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)
// Import the SDK
import { SatsTerminal } from 'satsterminal-sdk';
import readlineSync from 'readline-sync';
/**
* This example demonstrates how to use the SatsTerminal SDK to:
* 1. Get a quote for a rune sell
* 2. Create a PSBT
* 3. Wait for user to input signed PSBT
* 4. Confirm the signed PSBT
*/
// Configuration
const CONFIG = {
// Your API key for SatsTerminal
apiKey: 'your_api_key_here',
// Base URL for the API
baseURL: 'https://api.satsterminal.com/v1',
};
// Trade Parameters
const TRADE_PARAMS = {
// The rune you want to trade
runeName: 'DOG•GO•TO•THE•MOON',
address: 'bc1puxa2cwvfw47vaadt4lfxwgl4zln9epqtfsq3y7cl7vr5wvfayz6s22mmwp',
publicKey: 'dd4c950d7a5f86e92235687cffeee1bfb61b5c8a9e15b80751077c3d4315821c',
paymentAddress: '3PcP9J6C9ZNQpTRHrtqFBhP3LoBjSmMkZq',
paymentPublicKey: '02af6d71243386e3a24a23ebf47ea91dcf0d114b8ec29163ed9716e9b14a8fe3d8',
sellAmount: "10000",
sell: true,
marketplaces: ["MagicEden"]
};
// 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: ');
};
// Main execution block (sell)
(async () => {
try {
// 1. Get a quote for the trade
console.log('\n1. Fetching quote...');
console.log(TRADE_PARAMS);
const quote = await satsTerminal.fetchQuote({
btcAmount: TRADE_PARAMS.sellAmount,
runeName: TRADE_PARAMS.runeName,
address: TRADE_PARAMS.address,
marketplaces: TRADE_PARAMS.marketplaces,
sell: TRADE_PARAMS.sell,
});
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, // Use the selected orders from the quote
address: TRADE_PARAMS.address,
publicKey: TRADE_PARAMS.publicKey,
paymentAddress: TRADE_PARAMS.paymentAddress,
paymentPublicKey: TRADE_PARAMS.paymentPublicKey,
runeName: TRADE_PARAMS.runeName,
sell: TRADE_PARAMS.sell,
utxos: [],
feeRate: 5,
slippage: 9
});
console.log('PSBT created:', psbtResponse);
// Wait for user to input the signed PSBT
const signedPsbtBase64 = getSignedPSBT();
// 3. Confirm the PSBT after signing
console.log('\n3. Confirming PSBT...');
const confirmation = await satsTerminal.confirmPSBT({
orders: quote.selectedOrders, // Use the selected orders from the quote
address: TRADE_PARAMS.address,
publicKey: TRADE_PARAMS.publicKey,
paymentAddress: TRADE_PARAMS.paymentAddress,
paymentPublicKey: TRADE_PARAMS.paymentPublicKey,
signedRbfPsbtBase64: signedRbfPsbtBase64,
runeName: TRADE_PARAMS.runeName,
sell: TRADE_PARAMS.sell,
signedPsbtBase64: signedPsbtBase64,
swapId: psbtResponse.swapId // Use the swapId from the PSBT response
});
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);
}
}
})();
Last updated