Stacks.js Integration
Use Stacks.js to interact with your Clarinet devnet from JavaScript applications.
What you'll learn
Configure Stacks.js for a local devnet connection
Make STX transfers between devnet accounts
Call smart contract functions from JavaScript
Deploy contracts programmatically
Quickstart
1
2
Configure for devnet
Create a network helper:
import { StacksDevnet } from '@stacks/network';
export const devnet = new StacksDevnet({
url: 'http://localhost:3999'
});
export const accounts = {
deployer: {
address: 'ST1PQHQKV0RJXZFY1DGX8MNSNYVE3VGZJSRTPGZGM',
key: 'cb3df38053d132895220b9ce471f6b676db5b9bf0b4adefb55f2118ece2478df01'
},
wallet1: {
address: 'ST1SJ3DTE5DN7X54YDH5D64R3BCB6A2AG2ZQ8YPD5',
key: '7287ba251d44a4d3fd9276c88ce34c5c52a038955511cccaf77e61068649c17801'
}
};3
Test STX transfers
Send a transfer between devnet accounts:
import { makeSTXTokenTransfer, broadcastTransaction, AnchorMode } from '@stacks/transactions';
import { devnet, accounts } from './devnet-config';
async function transferSTX() {
const tx = await makeSTXTokenTransfer({
amount: 1_000_000n,
recipient: accounts.wallet1.address,
senderKey: accounts.deployer.key,
network: devnet,
anchorMode: AnchorMode.Any,
});
const result = await broadcastTransaction(tx, devnet);
console.log('Transaction ID:', result.txid);
}
transferSTX().catch(console.error);Run the transfer with ts-node stx-transfer.ts.
4
Call smart contracts
Interact with contracts deployed on devnet:
import { makeContractCall, broadcastTransaction, AnchorMode } from '@stacks/transactions';
import { devnet, accounts } from './devnet-config';
async function callContract() {
const tx = await makeContractCall({
contractAddress: accounts.deployer.address,
contractName: 'counter',
functionName: 'increment',
functionArgs: [],
senderKey: accounts.wallet1.key,
network: devnet,
anchorMode: AnchorMode.Any,
});
await broadcastTransaction(tx, devnet);
}
async function readCount() {
const response = await fetch(
`${devnet.coreApiUrl}/v2/contracts/call-read/${accounts.deployer.address}/counter/get-count`,
{
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
sender: accounts.wallet1.address,
arguments: []
})
}
);
const data = await response.json();
console.log(data);
}
callContract().catch(console.error);
readCount().catch(console.error);5
Deploy contracts programmatically
Deploy a contract from your application code:
import { makeContractDeploy, broadcastTransaction, AnchorMode } from '@stacks/transactions';
import { devnet, accounts } from './devnet-config';
import counterContract from './contracts/counter.clar?raw';
async function deployCounter() {
const tx = await makeContractDeploy({
contractName: 'counter',
codeBody: counterContract,
senderKey: accounts.deployer.key,
network: devnet,
anchorMode: AnchorMode.Any,
});
return broadcastTransaction(tx, devnet);
}
deployCounter().catch(console.error);Common patterns
Watching for transaction confirmation
Monitor when transactions are confirmed on devnet:
async function waitForTransaction(txid: string) {
let attempts = 0;
const maxAttempts = 10;
while (attempts < maxAttempts) {
const response = await fetch(
`${devnet.coreApiUrl}/extended/v1/tx/${txid}`
);
const tx = await response.json();
if (tx.tx_status === 'success') {
console.log('Transaction confirmed!');
return tx;
}
if (tx.tx_status === 'abort_by_response') {
throw new Error(`Transaction failed: ${tx.tx_result.repr}`);
}
// Wait for next block
await new Promise(resolve => setTimeout(resolve, 5000));
attempts++;
}
throw new Error('Transaction timeout');
}Post conditions for safety
Add post conditions to ensure contract calls behave as expected:
import { Pc } from '@stacks/transactions';
const postConditions = [
// Ensure sender's balance decreases by exactly the amount
Pc.principal(accounts.wallet1.address)
.willSendEq(1000000n)
.ustx(),
// Ensure recipient receives the amount
Pc.principal(accounts.deployer.address)
.willReceiveEq(1000000n)
.ustx()
];
const tx = await makeSTXTokenTransfer({
amount: 1000000n,
recipient: accounts.deployer.address,
senderKey: accounts.wallet1.key,
network: devnet,
postConditions,
anchorMode: AnchorMode.Any,
});Was this helpful?
