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 account
const privateKey = randomPrivateKey();
const address = privateKeyToAddress(privateKey, TransactionVersion.Mainnet);
console.log('New address:', address);
// Example: SP2J6ZY48GV1EZ5V2V5RB9MP66SW86PYKKNRV9EJ7
// Import an existing private key
const 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 accounts
for (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 contract
const 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 tuple
const 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 function
const 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 again
await 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 address
const 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 efficiently
const 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 broadcasting
const 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 file
const 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 STX
const 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]
});

Further reading