Usage examples
Learn the most common patterns for interacting with the Stacks blockchain using Stacks.js.
Working with local accounts
When building automated systems or testing, you'll often need to work with accounts directly using private keys rather than connecting to a wallet.
import {randomPrivateKey,privateKeyToAddress,getAddressFromPublicKey,TransactionVersion} from '@stacks/transactions';// Generate a new random accountconst privateKey = randomPrivateKey();const address = privateKeyToAddress(privateKey, TransactionVersion.Mainnet);console.log('New address:', address);// Example: SP2J6ZY48GV1EZ5V2V5RB9MP66SW86PYKKNRV9EJ7// Import an existing private keyconst existingKey = 'b244296d5907de9864c0b0d51f98a13c52890be0404e83f273144cd5b9960eed01';const existingAddress = privateKeyToAddress(existingKey, TransactionVersion.Testnet);console.log('Testnet address:', existingAddress);// Example: ST2J6ZY48GV1EZ5V2V5RB9MP66SW86PYKKNRV9EJ7
Generate multiple accounts
import { generateWallet, generateSecretKey } from '@stacks/wallet-sdk';const secretKey = generateSecretKey();const wallet = await generateWallet({secretKey,password: 'my-secure-password'});// Access first 5 accountsfor (let i = 0; i < 5; i++) {const account = wallet.accounts[i];console.log(`Account ${i}: ${account.stxAddress}`);}
Read-only calls
Read-only calls let you query contract state without creating a transaction. These calls are free and return immediately.
import { callReadOnlyFunction, cvToValue, principalCV } from '@stacks/transactions';import { StacksMainnet } from '@stacks/network';const network = new StacksMainnet();// Check STX balance in a contractconst balanceResponse = await callReadOnlyFunction({network,contractAddress: 'SP3K8BC0PPEVCV7NZ6QSRWPQ2JE9E5B6N3PA0KBR9',contractName: 'alex-vault',functionName: 'get-balance',functionArgs: [principalCV('SP2J6ZY48GV1EZ5V2V5RB9MP66SW86PYKKNRV9EJ7')],senderAddress: 'SP2J6ZY48GV1EZ5V2V5RB9MP66SW86PYKKNRV9EJ7'});const balance = cvToValue(balanceResponse);console.log('Balance:', balance);
Parse complex return types
import {callReadOnlyFunction,cvToValue,standardPrincipalCV,uintCV} from '@stacks/transactions';// Call a function that returns a tupleconst response = await callReadOnlyFunction({network,contractAddress: 'SP3K8BC0PPEVCV7NZ6QSRWPQ2JE9E5B6N3PA0KBR9',contractName: 'token-contract',functionName: 'get-token-info',functionArgs: [],senderAddress: 'SP2J6ZY48GV1EZ5V2V5RB9MP66SW86PYKKNRV9EJ7'});const info = cvToValue(response);console.log('Token name:', info.name);console.log('Total supply:', info['total-supply']);console.log('Decimals:', info.decimals);
Broadcast transactions
Broadcasting transactions requires building, signing, and sending transactions to the network.
import {makeContractCall,broadcastTransaction,AnchorMode,PostConditionMode,uintCV,standardPrincipalCV} from '@stacks/transactions';import { StacksTestnet } from '@stacks/network';const network = new StacksTestnet();const privateKey = 'your-private-key-here';// Call a contract functionconst transaction = await makeContractCall({network,anchorMode: AnchorMode.Any,contractAddress: 'ST1PQHQKV0RJXZFY1DGX8MNSNYVE3VGZJSRTPGZGM',contractName: 'counter',functionName: 'increment',functionArgs: [uintCV(1)],senderKey: privateKey,postConditionMode: PostConditionMode.Deny,postConditions: []});const broadcastResponse = await broadcastTransaction(transaction, network);console.log('Transaction ID:', broadcastResponse.txid);
Monitor transaction status
import { StacksTestnet } from '@stacks/network';import { fetch } from 'cross-fetch';async function waitForTransaction(txId: string, network: StacksTestnet) {const url = `${network.coreApiUrl}/extended/v1/tx/${txId}`;let pending = true;while (pending) {const response = await fetch(url);const txInfo = await response.json();if (txInfo.tx_status === 'success') {console.log('Transaction confirmed!');return txInfo;} else if (txInfo.tx_status === 'abort_by_response') {throw new Error('Transaction failed');}// Wait 10 seconds before checking againawait new Promise(resolve => setTimeout(resolve, 10000));}}
STX token transfers
Sending STX tokens is one of the most common operations. Here's how to create and broadcast STX transfers.
import {makeSTXTokenTransfer,broadcastTransaction,AnchorMode} from '@stacks/transactions';import { StacksMainnet } from '@stacks/network';const network = new StacksMainnet();const privateKey = 'your-private-key-here';// Send 0.5 STX to another addressconst transaction = await makeSTXTokenTransfer({network,anchorMode: AnchorMode.Any,recipient: 'SP3FGQ8Z7JY9BWYZ5WM53E0M9NK7WHJF0691NZ159',amount: 500000n, // 0.5 STX in microSTX (1 STX = 1,000,000 microSTX)memo: 'Payment for coffee',senderKey: privateKey});const broadcastResponse = await broadcastTransaction(transaction, network);console.log('Transfer sent:', broadcastResponse.txid);
Batch STX transfers
import { makeSTXTokenTransfer, estimateTransactionFee } from '@stacks/transactions';// Create multiple transfers efficientlyconst recipients = [{ address: 'SP2J6ZY48GV1EZ5V2V5RB9MP66SW86PYKKNRV9EJ7', amount: 1000000n },{ address: 'SP3FGQ8Z7JY9BWYZ5WM53E0M9NK7WHJF0691NZ159', amount: 2000000n },{ address: 'SP1GPBP8NBRXDRJBFQBV7KMAZX1Z7W2RFWJEH0V8V', amount: 3000000n }];for (const recipient of recipients) {const transaction = await makeSTXTokenTransfer({network,anchorMode: AnchorMode.Any,recipient: recipient.address,amount: recipient.amount,senderKey: privateKey});// Estimate fee before broadcastingconst fee = await estimateTransactionFee(transaction, network);console.log(`Sending ${recipient.amount} microSTX with fee: ${fee}`);await broadcastTransaction(transaction, network);}
Deploy contracts
Deploy your Clarity smart contracts to the blockchain programmatically.
import {makeContractDeploy,broadcastTransaction,AnchorMode} from '@stacks/transactions';import { StacksTestnet } from '@stacks/network';import { readFileSync } from 'fs';const network = new StacksTestnet();const privateKey = 'your-private-key-here';// Read contract from fileconst contractCode = readFileSync('./contracts/my-token.clar', 'utf-8');const transaction = await makeContractDeploy({network,anchorMode: AnchorMode.Any,contractName: 'my-token-v1',codeBody: contractCode,senderKey: privateKey,});const broadcastResponse = await broadcastTransaction(transaction, network);console.log('Contract deployed:', broadcastResponse.txid);console.log('Contract ID:', `${privateKeyToAddress(privateKey)}.my-token-v1`);
Deploy with post-conditions
import {makeContractDeploy,makeStandardSTXPostCondition,FungibleConditionCode} from '@stacks/transactions';// Ensure deployment costs less than 1 STXconst postCondition = makeStandardSTXPostCondition(privateKeyToAddress(privateKey),FungibleConditionCode.LessEqual,1000000n // 1 STX max);const transaction = await makeContractDeploy({network,anchorMode: AnchorMode.Any,contractName: 'my-contract',codeBody: contractCode,senderKey: privateKey,postConditions: [postCondition]});