@stacks/transactions

Construct, decode, and broadcast transactions for the Stacks blockchain.

The @stacks/transactions package provides comprehensive functionality for creating, signing, and broadcasting transactions on the Stacks blockchain, including STX transfers, contract deployments, and contract calls.

Installation

Terminal
$
npm install @stacks/transactions

Transaction functions

makeSTXTokenTransfer

makeSTXTokenTransfer creates a signed STX token transfer transaction.

Signature

function makeSTXTokenTransfer(options: SignedTokenTransferOptions): Promise<StacksTransaction>

Parameters

NameTypeRequiredDescription
recipientstringYesRecipient STX address
amountbigintYesAmount to transfer in microSTX
senderKeystringYesSender's private key
networkStacksNetwork | stringYesNetwork configuration
memostringNoOptional memo field
feebigintNoTransaction fee in microSTX
noncebigintNoAccount nonce
anchorModeAnchorModeNoBlock anchoring mode

Examples

Basic transfer

import { makeSTXTokenTransfer, broadcastTransaction } from '@stacks/transactions';
const transaction = await makeSTXTokenTransfer({
recipient: 'SP3FGQ8Z7JY9BWYZ5WM53E0M9NK7WHJF0691NZ159',
amount: 1000000n, // 1 STX in microSTX
senderKey: 'b244296d5907de9864c0b0d51f98a13c52890be0404e83f273144cd5b9960eed01',
network: 'mainnet'
});
const response = await broadcastTransaction({ transaction, network: 'mainnet' });
console.log(response.txid);

Transfer with memo

const transaction = await makeSTXTokenTransfer({
recipient: 'SP3FGQ8Z7JY9BWYZ5WM53E0M9NK7WHJF0691NZ159',
amount: 2500000n,
memo: 'Payment for services',
senderKey: privateKey,
network: 'testnet'
});

makeUnsignedSTXTokenTransfer

makeUnsignedSTXTokenTransfer creates an unsigned STX token transfer transaction.

Signature

function makeUnsignedSTXTokenTransfer(options: UnsignedTokenTransferOptions): Promise<StacksTransaction>

Parameters

NameTypeRequiredDescription
recipientstringYesRecipient STX address
amountbigintYesAmount to transfer in microSTX
publicKeystringYesSender's public key
networkStacksNetwork | stringYesNetwork configuration
memostringNoOptional memo field
feebigintNoTransaction fee in microSTX
noncebigintNoAccount nonce

Example

import { makeUnsignedSTXTokenTransfer } from '@stacks/transactions';
const unsignedTx = await makeUnsignedSTXTokenTransfer({
recipient: 'SP3FGQ8Z7JY9BWYZ5WM53E0M9NK7WHJF0691NZ159',
amount: 1000000n,
publicKey: publicKeyString,
network: 'mainnet'
});

makeContractDeploy

makeContractDeploy creates a signed smart contract deployment transaction.

Signature

function makeContractDeploy(options: SignedContractDeployOptions): Promise<StacksTransaction>

Parameters

NameTypeRequiredDescription
contractNamestringYesName for the contract
codeBodystringYesClarity contract source code
senderKeystringYesDeployer's private key
networkStacksNetwork | stringYesNetwork configuration
clarityVersionClarityVersionNoClarity version (defaults to latest)
feebigintNoTransaction fee in microSTX
noncebigintNoAccount nonce

Examples

Deploy a contract

import { makeContractDeploy, broadcastTransaction } from '@stacks/transactions';
import { readFileSync } from 'fs';
const codeBody = readFileSync('./contract.clar', 'utf-8');
const transaction = await makeContractDeploy({
contractName: 'my-contract',
codeBody,
senderKey: privateKey,
network: 'testnet'
});
const response = await broadcastTransaction({ transaction, network: 'testnet' });

Deploy with Clarity version

const transaction = await makeContractDeploy({
contractName: 'clarity-v3-contract',
codeBody: contractCode,
clarityVersion: 3,
senderKey: privateKey,
network: 'mainnet'
});

makeContractCall

makeContractCall creates a signed contract function call transaction.

Signature

function makeContractCall(options: SignedContractCallOptions): Promise<StacksTransaction>

Parameters

NameTypeRequiredDescription
contractAddressstringYesContract address
contractNamestringYesContract name
functionNamestringYesFunction to call
functionArgsClarityValue[]YesFunction arguments
senderKeystringYesCaller's private key
networkStacksNetwork | stringYesNetwork configuration
postConditionsPostCondition[]NoPost conditions
validateWithAbiboolean | ClarityAbiNoValidate arguments against ABI
feebigintNoTransaction fee in microSTX
noncebigintNoAccount nonce

Examples

Basic contract call

import { makeContractCall, broadcastTransaction, Cl } from '@stacks/transactions';
const transaction = await makeContractCall({
contractAddress: 'SP2C2YFP12AJZB4MABJBAJ55XECVS7E4PMMZ89YZR',
contractName: 'hello-world',
functionName: 'say-hi',
functionArgs: [Cl.stringUtf8('Hello!')],
senderKey: privateKey,
network: 'testnet'
});
const response = await broadcastTransaction({ transaction, network: 'testnet' });

Call with post conditions

import { makeContractCall, Cl, Pc } from '@stacks/transactions';
const postCondition = Pc.principal('SP2ZD731ANQZT6J4K3F5N8A40ZXWXC1XFXHVVQFKE')
.willSendLte(1000000n)
.ustx();
const transaction = await makeContractCall({
contractAddress: 'SP2C2YFP12AJZB4MABJBAJ55XECVS7E4PMMZ89YZR',
contractName: 'token-contract',
functionName: 'transfer',
functionArgs: [
Cl.principal('SP3FGQ8Z7JY9BWYZ5WM53E0M9NK7WHJF0691NZ159'),
Cl.uint(100n)
],
postConditions: [postCondition],
validateWithAbi: true,
senderKey: privateKey,
network: 'mainnet'
});

sponsorTransaction

sponsorTransaction adds a sponsor signature to a transaction, enabling sponsored transactions.

Signature

function sponsorTransaction(options: SponsorTransactionOptions): Promise<StacksTransaction>

Parameters

NameTypeRequiredDescription
transactionStacksTransactionYesTransaction to sponsor
sponsorPrivateKeystringYesSponsor's private key
feebigintYesFee to be paid by sponsor
sponsorNoncebigintNoSponsor account nonce

Example

import { sponsorTransaction, deserializeTransaction, broadcastTransaction } from '@stacks/transactions';
// Deserialize the transaction from the origin
const deserializedTx = deserializeTransaction(serializedTx);
// Sponsor the transaction
const sponsoredTx = await sponsorTransaction({
transaction: deserializedTx,
sponsorPrivateKey: sponsorKey,
fee: 1000n,
sponsorNonce: 0
});
const response = await broadcastTransaction({ transaction: sponsoredTx, network: 'testnet' });

fetchCallReadOnlyFunction

fetchCallReadOnlyFunction calls a read-only contract function without creating a transaction.

Signature

function fetchCallReadOnlyFunction(options: CallReadOnlyFunctionOptions): Promise<ClarityValue>

Parameters

NameTypeRequiredDescription
contractAddressstringYesContract address
contractNamestringYesContract name
functionNamestringYesFunction to call
functionArgsClarityValue[]YesFunction arguments
networkStacksNetworkYesNetwork configuration
senderAddressstringYesAddress of the caller

Example

import { fetchCallReadOnlyFunction, Cl } from '@stacks/transactions';
import { STACKS_MAINNET } from '@stacks/network';
const result = await fetchCallReadOnlyFunction({
contractAddress: 'SP2C2YFP12AJZB4MABJBAJ55XECVS7E4PMMZ89YZR',
contractName: 'data-store',
functionName: 'get-value',
functionArgs: [Cl.stringUtf8('key')],
network: STACKS_MAINNET,
senderAddress: 'SP3FGQ8Z7JY9BWYZ5WM53E0M9NK7WHJF0691NZ159'
});
console.log(result);

broadcastTransaction

broadcastTransaction broadcasts a signed transaction to the network.

Signature

function broadcastTransaction(options: BroadcastTransactionOptions): Promise<TxBroadcastResult>

Parameters

NameTypeRequiredDescription
transactionStacksTransactionYesSigned transaction to broadcast
networkStacksNetwork | stringYesNetwork to broadcast to

Example

import { broadcastTransaction } from '@stacks/transactions';
const result = await broadcastTransaction({
transaction: signedTx,
network: 'mainnet'
});
if (result.error) {
console.error('Broadcast failed:', result.reason);
} else {
console.log('Transaction ID:', result.txid);
}

Clarity value construction

Primitive values

import { Cl } from '@stacks/transactions';
// Boolean values
const isTrue = Cl.bool(true);
const isFalse = Cl.bool(false);
// Integer values (signed 128-bit)
const positiveInt = Cl.int(42n);
const negativeInt = Cl.int(-100n);
// Unsigned integer values (unsigned 128-bit)
const unsignedInt = Cl.uint(100n);
// Buffer values
const buffer = Cl.bufferFromUtf8('hello world');
const hexBuffer = Cl.bufferFromHex('0x1234');
// String values
const asciiStr = Cl.stringAscii('Hello ASCII');
const utf8Str = Cl.stringUtf8('Hello UTF-8! 👋');

Complex values

// Principal values
const standardPrincipal = Cl.principal('SP3FGQ8Z7JY9BWYZ5WM53E0M9NK7WHJF0691NZ159');
const contractPrincipal = Cl.contractPrincipal('SP3FGQ8Z7JY9BWYZ5WM53E0M9NK7WHJF0691NZ159', 'my-contract');
// Optional values
const none = Cl.none();
const some = Cl.some(Cl.uint(42n));
// Response values
const okResponse = Cl.ok(Cl.stringUtf8('Success'));
const errResponse = Cl.error(Cl.uint(404n));
// Tuple values
const tuple = Cl.tuple({
name: Cl.stringUtf8('Alice'),
age: Cl.uint(30n),
active: Cl.bool(true)
});
// List values
const list = Cl.list([Cl.uint(1n), Cl.uint(2n), Cl.uint(3n)]);

Post conditions

STX post conditions

import { Pc } from '@stacks/transactions';
// Standard principal STX post condition
const stxPostCondition = Pc.principal('SP3FGQ8Z7JY9BWYZ5WM53E0M9NK7WHJF0691NZ159')
.willSendGte(1000000n)
.ustx();
// Contract principal STX post condition
const contractStxCondition = Pc.principal('SP3FGQ8Z7JY9BWYZ5WM53E0M9NK7WHJF0691NZ159.my-contract')
.willSendEq(500000n)
.ustx();

Fungible token post conditions

// Standard principal fungible token post condition
const ftPostCondition = Pc.principal('SP3FGQ8Z7JY9BWYZ5WM53E0M9NK7WHJF0691NZ159')
.willSendLte(100n)
.ft('SP2C2YFP12AJZB4MABJBAJ55XECVS7E4PMMZ89YZR.token-contract', 'my-token');
// Contract principal fungible token post condition
const contractFtCondition = Pc.principal('SP3FGQ8Z7JY9BWYZ5WM53E0M9NK7WHJF0691NZ159.vault')
.willNotSend()
.ft('SP2C2YFP12AJZB4MABJBAJ55XECVS7E4PMMZ89YZR.token-contract', 'my-token');

Non-fungible token post conditions

// Standard principal NFT post condition
const nftPostCondition = Pc.principal('SP3FGQ8Z7JY9BWYZ5WM53E0M9NK7WHJF0691NZ159')
.willSend()
.nft('SP2C2YFP12AJZB4MABJBAJ55XECVS7E4PMMZ89YZR.nft-contract', 'my-nft', Cl.uint(1n));
// Contract principal NFT post condition
const contractNftCondition = Pc.principal('SP3FGQ8Z7JY9BWYZ5WM53E0M9NK7WHJF0691NZ159.marketplace')
.willNotSend()
.nft('SP2C2YFP12AJZB4MABJBAJ55XECVS7E4PMMZ89YZR.nft-contract', 'my-nft', Cl.uint(1n));

Multi-signature transactions

Multi-signature transactions require multiple signatures before broadcasting.

import {
makeUnsignedSTXTokenTransfer,
createStacksPrivateKey,
deserializeTransaction,
pubKeyfromPrivKey,
publicKeyToString,
TransactionSigner,
BytesReader
} from '@stacks/transactions';
// Create unsigned multi-sig transaction
const transaction = await makeUnsignedSTXTokenTransfer({
recipient: 'SP3FGQ8Z7JY9BWYZ5WM53E0M9NK7WHJF0691NZ159',
amount: 1000000n,
fee: 200n,
numSignatures: 2, // Require 2 of 3 signatures
publicKeys: [publicKey1, publicKey2, publicKey3],
network: 'mainnet'
});
// Sign with multiple parties
const deserializedTx = deserializeTransaction(transaction.serialize());
const signer = new TransactionSigner(deserializedTx);
// Add required signatures
signer.signOrigin(privateKey1);
signer.signOrigin(privateKey2);
// Append public key of non-signing party
signer.appendOrigin(publicKey3);
// Broadcast the multi-sig transaction
const signedTx = deserializedTx;
const response = await broadcastTransaction({ transaction: signedTx, network: 'mainnet' });

Key generation utilities

randomPrivateKey

randomPrivateKey generates a new random private key.

import { randomPrivateKey } from '@stacks/transactions';
const privateKey = randomPrivateKey();
console.log(privateKey); // Random 32-byte hex string with optional compression flag

privateKeyToPublicKey

privateKeyToPublicKey derives a public key from a private key.

import { privateKeyToPublicKey } from '@stacks/transactions';
const privateKey = 'b244296d5907de9864c0b0d51f98a13c52890be0404e83f273144cd5b9960eed01';
const publicKey = privateKeyToPublicKey(privateKey);
console.log(publicKey); // Compressed public key

Utility functions

deserializeTransaction

deserializeTransaction converts a serialized transaction back to a transaction object.

import { deserializeTransaction } from '@stacks/transactions';
const serializedTx = '0x00000000...'; // Hex string
const transaction = deserializeTransaction(serializedTx);

cvToJSON

cvToJSON converts Clarity values to JSON format for easier manipulation.

import { cvToJSON, hexToCV } from '@stacks/transactions';
const clarityValue = hexToCV('0x0100000000000000000000000000000001');
const json = cvToJSON(clarityValue);
console.log(json); // { type: 'uint', value: '1' }