Examples

End-to-end example scripts for easy implementation.

Example 1

Below is a complete example flow for buying runes with RBF protection, including waiting for user input for signed PSBTs:

import { SatsTerminal } from 'satsterminal-sdk';
import readlineSync from 'readline-sync';

// Configuration
const CONFIG = {
  apiKey: 'your_api_key_here',
  baseURL: 'https://api.satsterminal.com/v1',
  timeout: 30000 // 30 seconds timeout
};

// Trade Parameters
const TRADE_PARAMS = {
  runeName: 'LOBO•THE•WOLF•PUP',
  address: 'bc1p...',
  publicKey: '...',
  paymentAddress: '3Pc...',
  paymentPublicKey: '...',
  btcAmount: 0.0001,
  rbfProtection: true,
  marketplaces: ["MagicEden"],
  fill: true
};

// Initialize the SDK
const satsTerminal = new SatsTerminal(CONFIG);

// Function to get user input for signed PSBT
const getSignedPSBT = () => {
  console.log('\nPlease sign the PSBT and enter the signed PSBT base64 string:');
  return readlineSync.question('Signed PSBT: ');
};

// Function to get user input for signed RBF PSBT
const getSignedRbfPSBT = () => {
  console.log('\nPlease sign the RBF protection PSBT and enter the signed RBF PSBT base64 string:');
  return readlineSync.question('Signed RBF PSBT: ');
};

// Main execution
(async () => {
  try {
    // 1. Get a quote for the trade
    console.log('\n1. Fetching quote...');
    const quote = await satsTerminal.fetchQuote({
      btcAmount: TRADE_PARAMS.btcAmount,
      runeName: TRADE_PARAMS.runeName,
      address: TRADE_PARAMS.address,
      marketplaces: TRADE_PARAMS.marketplaces,
      rbfProtection: TRADE_PARAMS.rbfProtection,
      fill: TRADE_PARAMS.fill
    });
  
    console.log('Best marketplace:', quote.bestMarketplace);
    console.log('Quote:', quote.selectedOrders);

    // 2. Create a PSBT
    console.log('\n2. Creating PSBT...');
    const psbtResponse = await satsTerminal.getPSBT({
      orders: quote.selectedOrders,
      address: TRADE_PARAMS.address,
      publicKey: TRADE_PARAMS.publicKey,
      paymentAddress: TRADE_PARAMS.paymentAddress,
      paymentPublicKey: TRADE_PARAMS.paymentPublicKey,
      utxos: [], 
      feeRate: 5, 
      runeName: TRADE_PARAMS.runeName,
      sell: false,
      slippage: 9,
      rbfProtection: TRADE_PARAMS.rbfProtection
    });
  
    console.log('PSBT created:', psbtResponse);
  
    // Wait for user to input the signed PSBT
    const signedPsbtBase64 = getSignedPSBT();
  
    // Get signed RBF PSBT if RBF protection is enabled
    let signedRbfPsbtBase64 = null;
    if (TRADE_PARAMS.rbfProtection && psbtResponse.rbfProtected.base64) {
      console.log('\nRBF Protection PSBT:', psbtResponse.rbfProtected.base64);
      signedRbfPsbtBase64 = getSignedRbfPSBT();
    }

    // 3. Confirm the PSBT after signing
    console.log('\n3. Confirming PSBT...');
    const confirmation = await satsTerminal.confirmPSBT({
      orders: quote.selectedOrders,
      address: TRADE_PARAMS.address,
      publicKey: TRADE_PARAMS.publicKey,
      paymentAddress: TRADE_PARAMS.paymentAddress,
      paymentPublicKey: TRADE_PARAMS.paymentPublicKey,
      signedRbfPsbtBase64: signedRbfPsbtBase64,
      swapId: psbtResponse.swapId,
      runeName: TRADE_PARAMS.runeName,
      rbfProtection: TRADE_PARAMS.rbfProtection,
      signedPsbtBase64: signedPsbtBase64
    });
  
    console.log('Confirmation:', confirmation);

  } catch (error) {
    console.error('Error:', error.message);
  
    // Provide more helpful information for network errors
    if (error.code === 'ECONNREFUSED') {
      console.error('Connection refused. Make sure the API server is running and accessible.');
    } else if (error.code === 'ECONNRESET' || error.message.includes('socket hang up')) {
      console.error('Connection was reset or timed out. This could be due to:');
      console.error('- Network connectivity issues');
      console.error('- Server overload or maintenance');
      console.error('- Invalid API key or authentication');
      console.error('- Request timeout (the operation might take longer than expected)');
    }
  
    if (process.env.NODE_ENV === 'development') {
      console.error('Full error:', error);
    }
  }
})();

Example 2 (MagicEden Sell)

Last updated