
Tonweb
- 3 installs
- 4 repo stars
- Updated February 25, 2026
- hairyf/blockchain-skills
Build TON JavaScript apps with the TonWeb SDK: wallets, BOC, HttpProvider, NFTs, jettons, and TON DNS.
About
Reference for TonWeb, the JavaScript SDK for TON covering wallets, BOC handling, HttpProvider, NFTs, jettons, and DNS. A developer uses it when integrating TON functionality into a JavaScript application.
- Covers wallets, BOC, and HttpProvider
- Includes NFT, jetton, and TON DNS support
Tonweb by the numbers
- 3 all-time installs (skills.sh)
- Ranked #390 of 479 Web3 & Blockchain skills by installs in the Skillselion catalog
- Data as of Jul 13, 2026 (Skillselion catalog sync)
npx skills add https://github.com/hairyf/blockchain-skills --skill tonwebAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 3 |
|---|---|
| repo stars | ★ 4 |
| Last updated | February 25, 2026 |
| Repository | hairyf/blockchain-skills ↗ |
What it does
Build TON JavaScript apps with the TonWeb SDK: wallets, BOC, HttpProvider, NFTs, jettons, and TON DNS.
Files
Based on tonweb v0.0.66, generated 2026-02-25.
TonWeb is the JavaScript API for the TON blockchain: wallet contracts, BOC/Cell, TonCenter HttpProvider, NFT/Jetton, DNS, payments, block subscription.
Core References
| Topic | Description | Reference |
|---|---|---|
| Overview | Installation, provider, root API | core-overview |
| TonWeb instance | Root class, getTransactions, getBalance, sendBoc, call | core-tonweb-instance |
| Address and utils | Address, toNano/fromNano, bytes/hex/base64, BN, nacl | core-address-utils |
| BOC | Cell, BitString, fromBoc/oneFromBoc | core-boc |
| Slice | Parsing BOC: beginParse, loadBit, loadUint, loadAddress, loadRef | core-slice |
| Contract base | deploy, methods, getQuery/send/estimateFee, createStateInit | core-contract |
| HttpProvider | getAddressInfo, getWalletInfo, sendBoc, call/call2 | core-http-provider |
| HttpProviderUtils | parseResponse, parseObject — parse get-method stack to BN/Cell | core-http-provider-utils |
| Transfer URL | parseTransferUrl, formatTransferUrl (ton://transfer/...) | core-transfer-url |
| Workchain | WorkchainId Master/Basic, wc for addresses and contracts | core-workchain |
| Utils extra | AdnlAddress, StorageBagId; keyPairFromSeed, newKeyPair, newSeed | core-utils-extra |
| Estimate fee | estimateFee on methods, getEstimateFee(boc) on provider | core-estimate-fee |
Features
| Topic | Description | Reference |
|---|---|---|
| Wallet | create, deploy, transfer, seqno, V2/V3/V4 | features-wallet |
| Highload wallet | HighloadWalletContractV3, HighloadQueryId | features-highload-wallet |
| Lockup wallet | liquid/locked/restricted balances | features-lockup-wallet |
| Lockup vesting | VestingWalletV1: vesting schedule, getLockedAmount, getVestingData | features-lockup-vesting |
| NFT | NftCollection, NftItem, NftMarketplace, NftSale | features-nft |
| Jetton | JettonMinter, JettonWallet, transfer, burn | features-jetton |
| NFT content & royalty | NftUtils: offchain URI cell, parseOffchainUriCell, getRoyaltyParams | features-nft-content-royalty |
| DNS | resolve, getWalletAddress, getSiteAddress | features-dns |
| Ledger | AppTon, getPublicKey, getAddress, sign, transfer; TransportWebUSB/HID/BLE | features-ledger |
| Payments | PaymentChannel, createChannel | features-payments |
| Block subscription | BlockSubscription, InMemoryBlockStorage | features-block-subscription |
| Subscription contract | Recurring payments: pay, getSubscriptionData | features-subscription |
| Wallet parsing | parseTransferQuery, parseTransferBody (V3/V4 transfer BOC) | features-wallet-parsing |
Best practices
| Topic | Description | Reference |
|---|---|---|
| Custom contract | Extend Contract, createDataCell, message builders | best-practices-custom-contract |
| Error handling | exit_code, parseResponse throws, provider/send errors | best-practices-error-handling |
Generation Info
- Source: sources/tonweb
- Git SHA: 76dfd0701714c0a316aee503c2962840acaf74ef
- Generated: 2026-02-25
Custom Contract Best Practices
TON has no ABI; custom contracts are implemented by extending TonWeb.Contract and composing cells with the provided static helpers.
Override createDataCell
Contract state is stored in the data cell. Override createDataCell() to return a Cell that matches your contract’s data layout.
class MyContract extends Contract {
createDataCell() {
const cell = new Cell();
cell.bits.writeAddress(this.options.ownerAddress);
cell.bits.writeUint(this.options.counter, 64);
return cell;
}
}Address is derived from code + data via createStateInit(); keep options and data layout in sync for deploy and restore.
Deploy flow
Base class handles stateInit and deploy. You only need:
options.code— Cell (or Uint8Array from hex).options.wc— workchain (default 0).createDataCell()— initial state.
Optional: override createSigningMessage() for external messages if your contract expects a specific signing layout.
const deploy = contract.deploy(secretKey);
await deploy.estimateFee();
await deploy.send();Composing messages
Use Contract static methods so layout matches TVM:
- StateInit:
Contract.createStateInit(code, data, library, splitDepth, ticktock). - Internal message:
Contract.createInternalMessageHeader(dest, gramValue, ihrDisabled, bounce, ...)thenContract.createCommonMsgInfo(header, stateInit, body). - External message:
Contract.createExternalMessageHeader(dest, src, importFee)then commonMsgInfo with body/signature.
Put method op + params in a Cell as body; attach stateInit only for deploy or init.
Methods object
Attach callable methods to this.methods so they return objects with getQuery(), send(), estimateFee(), and for get-methods call(). Use Contract.createMethod(provider, queryPromise) for the standard shape, or build the promise from your message cell and sign/send logic.
Key points
- Keep code and data layout in sync with FunC/spec; wrong layout = wrong address or broken contract.
- Use
createInternalMessageHeader/createExternalMessageHeader+createCommonMsgInfoso serialization matches TON message format. - For get-methods use
provider.call(address, methodName, stackParams); stack format is array of['num', n],['cell', cell],['slice', slice].
<!-- Source references:
- https://github.com/toncenter/tonweb/blob/master/src/contract/README.md
- https://github.com/toncenter/tonweb/blob/master/src/contract/index.js
-->
Error Handling
Reliable agents check get-method results and provider responses before using data.
get-method exit code
When calling provider.call() or provider.call2() (runSmcMethod), the result includes exit_code. Non-zero means the TVM run failed (e.g. assertion, out of gas).
const result = await tonweb.provider.call(address, 'get_some_data');
if (result.exit_code !== 0) {
throw new Error('Get method failed: ' + result.exit_code);
}
const data = result.stack; // then parse stackHttpProviderUtils.parseResponse
HttpProviderUtils.parseResponse(result) throws if exit_code !== 0 and attaches the raw result to the error:
try {
const parsed = HttpProviderUtils.parseResponse(result);
// use parsed (BN, Cell, or array)
} catch (err) {
if (err.result) {
console.error('exit_code', err.result.exit_code, err.result);
}
throw err;
}Use this when you want a single place to enforce success and parse the stack.
sendBoc / send failures
sendBoc(bytes) and contract method .send() return whatever the HTTP API returns. Check for HTTP errors and message them; the node may return 200 with a JSON error for invalid BOC or send failure. Handle network errors and timeouts (retry or surface to user).
Key points
- Always check
exit_codewhen reading get-method results, or useparseResponsewhich throws on non-zero. - When parsing stack manually, handle missing or unexpected types to avoid runtime errors from malformed data.
<!-- Source references:
- sources/tonweb/src/providers/HttpProviderUtils.js (parseResponse exit_code check)
-->
Address and Utils
Utilities for addresses, amounts, and byte/hex/base64 handling. Access via TonWeb.utils or TonWeb.Address.
Address class
const Address = TonWeb.utils.Address;
const addr = new Address('EQDjVXa_oltdBP64Nc__p397xLCvGm2IcZ1ba7anSW0NAkeP');
// or raw: new Address('0:abc...') workchain:hash
addr.wc; // workchain (0 or -1)
addr.hashPart; // Uint8Array (32 bytes)
addr.isUserFriendly;
addr.isUrlSafe;
addr.isBounceable;
addr.isTestOnly;
// Format for display / links
addr.toString(true, true, false); // non-bounceable, url-safe (e.g. for receiving)
addr.toString(true, true, true); // bounceable (e.g. for contract dest)
Address.isValid(anyForm); // static: true if string/Address is validConstructor accepts: user-friendly base64 string, raw string "wc:hex", or another Address instance.
Amount helpers
TonWeb.utils.toNano('0.01'); // BN in nanograms (0.01 TON)
TonWeb.utils.toNano(0.01);
TonWeb.utils.fromNano(amount); // BN or string -> string TONBytes and encoding
TonWeb.utils.bytesToHex(bytes);
TonWeb.utils.hexToBytes(hexString);
TonWeb.utils.bytesToBase64(bytes);
TonWeb.utils.base64ToBytes(base64);
TonWeb.utils.stringToBytes(s, size?);
TonWeb.utils.concatBytes(a, b);
TonWeb.utils.crc32c(bytes);
TonWeb.utils.crc16(data); // ArrayLike<number> -> Uint8Array (2 bytes)Crypto / bignum
- TonWeb.utils.BN —
bn.jsfor big integers. - TonWeb.utils.nacl —
tweetnaclfor key pairs:nacl.sign.keyPair(),nacl.sign.keyPair.fromSecretKey(secretKey).
Key points
- Use non-bounceable addresses for user wallets (receiving); bounceable for contracts to allow bounce on error.
- All on-chain and API amounts are in nanograms; convert with
toNano/fromNano. - Address validation:
Address.isValid(str)before constructing.
<!-- Source references:
- https://github.com/toncenter/tonweb/blob/master/src/utils/README.md
- sources/tonweb/src/utils/README.md
- sources/tonweb/src/utils/Address.js
- sources/tonweb/src/utils/Utils.js
-->
BOC: Cell and BitString
TON messages and state are serialized as BOC. TonWeb provides Cell and BitString for building and parsing them.
BitString
const { Cell, BitString } = TonWeb.boc;
const bits = new BitString(1023);
bits.length; // max bits
bits.cursor; // current write position
bits.getFreeBits();
bits.getUsedBits();
bits.get(n); // read bit at n
bits.on(n); bits.off(n); bits.toggle(n);
// Writing (advances cursor)
bits.writeBit(b);
bits.writeBitArray([0,1,1]);
bits.writeUint(num, bitLength);
bits.writeInt(num, bitLength);
bits.writeBytes(uint8Array);
bits.writeString(s);
bits.writeGrams(amount); // nanograms (BN or number)
bits.writeAddress(Address | null);
bits.writeBitString(anotherBitString);
bits.clone();
bits.toHex();Cell
const cell = new Cell();
cell.bits; // BitString(1023)
cell.refs; // Array<Cell> (max 4)
cell.writeCell(anotherCell); // append another cell's bits and refs into this one
cell.hash(); // Promise<Uint8Array>
cell.print(); // Fift-like string for debugging
cell.toBoc(has_idx?, hash_crc32?, has_cache_bits?, flags?); // Promise<Uint8Array>Default toBoc(false) matches Fift 2 boc+>B.
BOC (de)serialization
const bytes = await cell.toBoc(false);
const cells = TonWeb.boc.Cell.fromBoc(bytes); // Cell[] (all roots)
const one = TonWeb.boc.Cell.oneFromBoc(bytes); // single root cell, throws if !== 1Example: build a simple message cell
const Cell = TonWeb.boc.Cell;
const cell = new Cell();
cell.bits.writeUint(0, 32); // op
cell.bits.writeAddress(senderAddress);
cell.bits.writeGrams(TonWeb.utils.toNano(1));
const bocBytes = await cell.toBoc();Key points
- Each cell has up to 1023 bits and 4 refs; use multiple cells for larger payloads.
- Use
writeGramsfor nanotons; usewriteAddress(null)for addr_none. - For get-method stack params: pass
Cellobjects as['cell', cell]or['slice', slice]; Slice is fromTonWeb.boc.Slice.
<!-- Source references:
- https://github.com/toncenter/tonweb/blob/master/src/boc/README.md
- sources/tonweb/src/boc/README.md
- sources/tonweb/src/boc/Cell.js
- sources/tonweb/src/boc/BitString.js
-->
Contract Base Class
TonWeb.Contract is the base for all contract wrappers. It handles address derivation, deploy, and method invocation (get-methods and external messages).
Constructor and address
const { Contract } = TonWeb;
const contract = new Contract(provider, {
code: codeCell, // Cell or Uint8Array
address?: Address|string, // if known
wc?: number // workchain, default 0 or from address
});
const address = await contract.getAddress(); // computed from stateInit if no address setDeploy
const deployMethod = contract.deploy(secretKey);
const queryCell = await deployMethod.getQuery();
const fee = await deployMethod.estimateFee();
await deployMethod.send();Methods (external messages)
contract.methods.myMethod(params); // you define on subclass
const method = contract.methods.transfer({ ... });
const query = await method.getQuery(); // Cell
const fee = await method.estimateFee();
await method.send();Get-methods
const getMethod = contract.methods.seqno();
const result = await getMethod.call(); // raw API resultUse provider.call2(address, method, params) for parsed stack (see HttpProvider).
Static helpers for building messages
Use these when implementing custom contracts:
- Contract.createStateInit(code, data, library?, splitDepth?, ticktock?) — returns StateInit Cell. Library/splitDepth/ticktock not implemented.
- Contract.createInternalMessageHeader(dest, gramValue, ihrDisabled?, bounce?, bounced?, src?, currencyCollection?, ...) — internal message header Cell.
- Contract.createExternalMessageHeader(dest, src?, importFee?) — external message header Cell.
- Contract.createCommonMsgInfo(header, stateInit?, body?) — full message: header + optional stateInit + optional body.
- Contract.createOutMsg(address, amount, payload, stateInit?) — convenience: internal message with optional stateInit.
payloadcan be string (prefixed with 32-bit 0), Uint8Array, or Cell.
Key points
- Override createDataCell() to set contract data for address/deploy; override createSigningMessage in deploy flow if needed.
- No ABI in TON; you compose message bodies manually (op + params in Cell/BitString).
- estimateFee and send use the provider (e.g. TonCenter); deploy uses init_code/init_data in estimate.
<!-- Source references:
- https://github.com/toncenter/tonweb/blob/master/src/contract/README.md
- sources/tonweb/src/contract/README.md
- sources/tonweb/src/contract/index.js
-->
Estimate Fee
Before sending a BOC you can get an estimated fee so the user can confirm or the app can attach enough value.
Usage
Build the external message (e.g. via deploy.getQuery() or transfer.getQuery()), serialize to BOC, then call the provider’s fee estimation. Contract helpers do this for you via .estimateFee().
Contract method: estimateFee()
On any deploy or contract method (e.g. transfer, pay):
const transfer = wallet.methods.transfer({ ... });
const fee = await transfer.estimateFee();
// fee: { gas_fee, forward_fee, ... } (shape depends on API)Use this when you want to show “Network fee: X TON” before calling .send().
Low-level: getEstimateFee(query)
provider.getEstimateFee(query) takes a query object as in TonCenter API: the same structure you would send with sendBoc (e.g. { boc: base64 }). Returns the node’s fee estimate.
Use when you have a raw BOC and want to estimate without going through a contract method.
Key points
- Estimation uses current chain state; actual fee can differ slightly. Use for UX, not exact accounting.
- If the message would fail (e.g. insufficient balance), the API may still return a fee or an error; handle both.
<!-- Source references:
- sources/tonweb/src/providers/index.js (getEstimateFee)
- sources/tonweb/src/contract (Contract.createMethod, estimateFee)
-->
HttpProviderUtils: Parsing get-method Results
When you call provider.call() or provider.call2() (runSmcMethod), the node returns a stack of typed values. HttpProviderUtils converts these into JS types (BN, Cell, nested tuples).
parseResponse(result)
Takes the raw runSmcMethod result. If exit_code !== 0, throws an error with err.result. Otherwise maps the result.stack array through parseResponseStack and returns a single value if stack length is 1, else the array.
const HttpProviderUtils = require('tonweb').providers?.HttpProviderUtils || require('tonweb/src/providers/HttpProviderUtils').default;
const result = await provider.call(address, 'get_balance');
const parsed = HttpProviderUtils.parseResponse(result); // BN or array of parsed stack entriesparseResponseStack(pair) / parseObject(x)
- Stack entry shape:
[type, value](e.g.['num', '0x1234'],['cell', { bytes: base64 }],['tuple', { elements: [...] }]). - num → BN (hex).
- cell → Cell via
Cell.oneFromBoc(base64ToBytes(value.bytes)). - list / tuple → recursively parsed array via
parseObject.
Use when you need Cell or BN from get-method results instead of raw stack.
makeArg / makeArgs
Convert JS args to the format expected by runSmcMethod stack: makeArg(BN|Number) → ['num', value]. makeArgs([...]) maps over an array. For cell/slice params the provider typically accepts ['cell', cell] or ['slice', slice]; build those separately.
Key points
- Always check
exit_codeor useparseResponsewhich throws on non-zero exit. - For
call2(runSmcMethod with typed parsing), the HTTP provider may already return parsed tuples; HttpProviderUtils is for low-level or custom parsing ofcallresults.
<!-- Source references:
- sources/tonweb/src/providers/HttpProviderUtils.js
- sources/tonweb/src/providers/index.js
-->
HttpProvider
TonWeb.HttpProvider talks to a TonCenter-compatible JSON-RPC API. Used by default when you new TonWeb().
Constructor
const provider = new TonWeb.HttpProvider(
'https://toncenter.com/api/v2/jsonRPC',
{ apiKey: 'YOUR_MAINNET_KEY' }
);
// Testnet:
// 'https://testnet.toncenter.com/api/v2/jsonRPC', { apiKey: 'YOUR_TESTNET_KEY' }Account and wallet
- getAddressInfo(address) — balance, code, data, last_transaction_id.
- getExtendedAddressInfo(address) — parsed state for known contract types (fewer wallet types).
- getWalletInfo(address) — recommended for wallets: simple, standard, v3.
Transactions and balance
- getTransactions(address, limit?, lt?, hash?, to_lt?, archival?) — tx list.
hashin hex; use withltfor pagination. - getBalance(address) — balance in nanograms (string).
Sending and get-methods
- sendBoc(base64) — send serialized BOC (base64 string).
- call(address, method, params?) — run get-method; returns raw API result (stack in API format).
- call2(address, method, params?) — same but returns parsed stack (e.g. BN, Cell, Slice) via HttpProviderUtils.
Block/config (low-level)
- getConfigParam(configParamId) — returns config cell (e.g. for DNS root).
- getMasterchainInfo(), getBlockShards(seqno), getBlockTransactions(...), getBlockHeader(...), getMasterchainBlockHeader(seqno).
Key points
- Set apiKey to avoid strict rate limits on TonCenter.
- Addresses passed as string (user-friendly or raw).
- For parsed get-method results use call2; for raw stack use call.
<!-- Source references:
- sources/tonweb/src/providers/README.md
- sources/tonweb/src/providers/index.js
- sources/tonweb/src/index.js
-->
TonWeb Overview
TonWeb is the JavaScript SDK for The Open Network (TON). It provides wallet contracts, BOC/Cell serialization, HTTP provider for TonCenter API, and helpers for addresses and amounts.
Installation
// npm or yarn
const TonWeb = require('tonweb');
// or ESM
import TonWeb from 'tonweb';
const tonweb = new TonWeb();Browser: <script src="tonweb.js"></script> then new window.TonWeb().
Provider (API endpoint)
By default uses mainnet TonCenter. Pass a custom HttpProvider for another endpoint or API key:
const TonWeb = require('tonweb');
// Mainnet with API key (higher rate limit)
const tonweb = new TonWeb(new TonWeb.HttpProvider('https://toncenter.com/api/v2/jsonRPC', { apiKey: 'YOUR_MAINNET_KEY' }));
// Testnet
const tonweb = new TonWeb(new TonWeb.HttpProvider('https://testnet.toncenter.com/api/v2/jsonRPC', { apiKey: 'YOUR_TESTNET_KEY' }));Without an API key, TonCenter applies request rate limits.
Root API surface
tonweb.version— SDK version string.tonweb.utils— Address,toNano/fromNano, hex/bytes/base64, BN, nacl.tonweb.Address— same astonweb.utils.Address.tonweb.boc— Cell and BitString (BOC serialization).tonweb.Contract— abstract contract base.tonweb.wallet— wallet factory and versions.tonweb.getTransactions(address, limit?, lt?, txhash?, to_lt?)— transaction history.tonweb.getBalance(address)— balance in nanograms (Promise<string>).tonweb.sendBoc(bytes: Uint8Array)— send serialized BOC (external message).tonweb.call(address, method, params?)— invoke contract get-method.
Typical flow
const tonweb = new TonWeb();
const wallet = tonweb.wallet.create({ publicKey });
const address = await wallet.getAddress();
const seqno = await wallet.methods.seqno().call();
await wallet.deploy(secretKey).send();
await wallet.methods.transfer({
secretKey,
toAddress: 'EQDjVXa_...',
amount: TonWeb.utils.toNano(0.01),
seqno,
payload: 'Hello',
sendMode: 3,
}).send();
const history = await tonweb.getTransactions(address);
const balance = await tonweb.getBalance(address);Key points
- All amounts in TON are in nanograms; use
TonWeb.utils.toNano(amount)andfromNanofor display. - Addresses can be user-friendly (base64) or raw; use
Addressfor parsing andtoString(...)for formatting. - For custom BOC messages, build
Cells and send withtonweb.sendBoc(cell.toBoc()).
<!-- Source references:
- https://github.com/toncenter/tonweb
- https://github.com/toncenter/tonweb/blob/master/src/README.md
- https://github.com/toncenter/tonweb/blob/master/README.md
-->
Slice: Parsing BOC Data
A Slice is a read-only view over a TVM cell used to parse data from Cells (e.g. message bodies, get-method results). Create it from a Cell with cell.beginParse().
Creating a Slice
const TonWeb = require('tonweb');
const cell = TonWeb.boc.Cell.oneFromBoc(bytes);
const slice = cell.beginParse();Reading primitives
- loadBit() — read one bit, advance cursor.
- loadBits(bitLength) — read
bitLengthbits, returnUint8Array. - loadUint(bitLength) — unsigned integer, returns
BN. - loadInt(bitLength) — signed integer, returns
BN. - loadVarUint(bitLength) — variable-length uint (length prefix then data).
- loadCoins() — VarUint 16 (nanotons), returns
BN. - loadAddress() — TON address; returns
Addressornullfor addr_none. - loadRef() — load next child cell as Slice; advances ref cursor. Throws if no refs left.
Cursor and remaining
- readCursor — current bit position.
- getFreeBits() — bits left in this slice (does not include refs).
Example: parse transfer body
const slice = TonWeb.boc.Cell.oneFromBoc(bodyBoc).beginParse();
const op = slice.loadUint(32);
const queryId = slice.loadUint(64);
const dest = slice.loadAddress();
const amount = slice.loadCoins();
// ... then load refs if needed: const payload = slice.loadRef();Key points
- Use Slice when you need to read existing BOC (e.g. parsing wallet transfer body, parsing runSmcMethod cell results). Use BitString/Cell when building messages.
- Ref order matters:
loadRef()returns refs in the order they were stored. - For get-method params you can pass a Slice as
['slice', slice]to the provider.
<!-- Source references:
- sources/tonweb/src/boc/Slice.js
- sources/tonweb/src/contract/wallet/WalletQueryParser (parseTransferBody uses beginParse)
-->
TonWeb Instance
TonWeb is the root class for the TON JavaScript SDK. Construct it with an optional HTTP provider; default is TonCenter mainnet.
Usage
const TonWeb = require('tonweb');
// Default: mainnet TonCenter (rate-limited without API key)
const tonweb = new TonWeb();
// With custom provider (e.g. testnet + API key)
const tonweb = new TonWeb(
new TonWeb.HttpProvider('https://testnet.toncenter.com/api/v2/jsonRPC', { apiKey: 'YOUR_KEY' })
);Main methods (delegate to provider)
- getTransactions(address, limit?, lt?, txhash?, to_lt?) — transaction history for an address.
addressisAddressor string; returns array of tx objects. - getBalance(address) — returns balance in nanograms (Promise<string>).
- sendBoc(bytes) — send serialized BOC (Uint8Array); use for external messages.
- call(address, method, params?) — run get-method on contract.
methodis name or method id;paramsis stack array e.g.[['num', 3], ['cell', cell], ['slice', slice]].
Attached helpers
- tonweb.utils — Address, toNano/fromNano, bytes/hex/base64, BN, nacl.
- tonweb.boc — Cell, BitString, BOC (de)serialization.
- tonweb.wallet — wallet factory (
tonweb.wallet.create(...)). - tonweb.dns — DNS resolver (
tonweb.dns.resolve,getWalletAddress,getSiteAddress). - tonweb.provider — raw HttpProvider (getAddressInfo, getWalletInfo, getExtendedAddressInfo, etc.).
Key points
- All amounts from API are in nanograms; use
TonWeb.utils.toNano('0.01')for 0.01 TON. - For high rate limits use TonCenter with
apiKeyin HttpProvider options. - Static exports:
TonWeb.version,TonWeb.utils,TonWeb.Address,TonWeb.boc,TonWeb.HttpProvider,TonWeb.Contract,TonWeb.Wallets,TonWeb.token.nft,TonWeb.token.jetton,TonWeb.dns,TonWeb.HighloadWallets,TonWeb.payments,TonWeb.BlockSubscription,TonWeb.InMemoryBlockStorage,TonWeb.ledger.
<!-- Source references:
- https://github.com/toncenter/tonweb
- sources/tonweb/README.md
- sources/tonweb/src/index.js
- sources/tonweb/src/README.md
-->
Transfer URL (Deep Links)
TonWeb can parse and format TON transfer URLs used for wallet deep links (e.g. "Send TON" links in apps).
Parsing a transfer URL
const { parseTransferUrl } = TonWeb.utils;
const parsed = parseTransferUrl('ton://transfer/EQ...?amount=0.01&text=Hello');
// parsed: { address: string, amount?: string, text?: string }Throws if the URL format is invalid.
Formatting a transfer URL
const { formatTransferUrl } = TonWeb.utils;
const url = formatTransferUrl('EQ...', '0.01', 'Hello');
// url: ton://transfer/EQ...?amount=0.01&text=HelloParameters: address, optional amount, optional text.
Key points
- Use for building "Send TON" links in dApps or for handling incoming transfer intents from wallets.
- Amount is typically in TON (string); convert to nanograms with
TonWeb.utils.toNano(amount)when sending.
<!-- Source references:
- sources/tonweb/dist/types/utils/transfer-url.d.ts
-->
Extra Utils: Address-like Types and Key Helpers
TonWeb exposes additional utils for ADNL/storage identifiers and key generation.
AdnlAddress
32-byte ADNL address (hex or Uint8Array). Used in TON for overlay/node addressing.
const AdnlAddress = TonWeb.utils.AdnlAddress;
const addr = new AdnlAddress(hexString); // 64 hex chars
// or: new AdnlAddress(uint8Array32)
addr.toHex(); // 64-char hex
AdnlAddress.isValid(x); // staticStorageBagId
32-byte storage bag identifier (hex or Uint8Array).
const StorageBagId = TonWeb.utils.StorageBagId;
const id = new StorageBagId(hexString); // 64 hex chars
id.toHex();
StorageBagId.isValid(x);Key generation helpers
- newKeyPair() — new random nacl signing key pair:
{ publicKey, secretKey }(Uint8Array). - newSeed() — new 32-byte seed (first 32 bytes of a new key pair’s secretKey).
- keyPairFromSeed(seed) — deterministic key pair from 32-byte
Uint8Arrayseed.
const { newKeyPair, newSeed, keyPairFromSeed } = TonWeb.utils;
const keyPair = newKeyPair();
const seed = newSeed();
const sameKeyPair = keyPairFromSeed(seed);Use keyPairFromSeed when you need a deterministic key from a seed (e.g. from mnemonic-derived bytes).
Key points
- AdnlAddress and StorageBagId are not TON payment addresses; use
Addressfor accounts and contracts. - For wallet creation use
nacl.sign.keyPair()orTonWeb.utils.newKeyPair(); usekeyPairFromSeedwhen you have a seed.
<!-- Source references:
- sources/tonweb/src/utils/AdnlAddress.js
- sources/tonweb/src/utils/StorageBagId.js
- sources/tonweb/src/utils/Utils.js (keyPairFromSeed, newKeyPair, newSeed)
- sources/tonweb/src/utils/index.js
-->
Workchain
TON has two main workchains: Masterchain (-1) and Basechain (0). TonWeb exposes this via a Workchain type and WorkchainId enum in TypeScript; in JS use numeric wc (e.g. 0 or -1).
Usage
- Wallet / contract workchain: When creating a wallet or contract, pass
wc: 0(default) orwc: -1for masterchain. - Address:
Addresshas awcproperty (number). User wallets are almost always workchain 0. - Lockup wallet: For validator/elector whitelist you may use workchain -1.
const wallet = tonweb.wallet.create({ publicKey, wc: 0 });
const address = await wallet.getAddress();
address.wc; // 0Key points
- Basechain (0) is where user accounts and most contracts live; masterchain (-1) holds validators and system contracts.
- Ledger AppTon
getAddressreturns basechain address (0:+ hex). Use workchain when building state init or sending to masterchain contracts.
<!-- Source references:
- sources/tonweb/dist/types/utils/workchain.d.ts
- sources/tonweb/src/contract/lockup/README.md (workchain: -1 for masterchain)
-->
Block Subscription
Process new masterchain and shardchain blocks in order (or shards out of order). Useful for indexers and watchers.
Setup
const { BlockSubscription, InMemoryBlockStorage } = TonWeb;
const storage = new InMemoryBlockStorage();
const subscription = new BlockSubscription(
tonweb.provider,
storage,
async (blockHeader, blockShards) => {
// blockHeader: workchain, shardId, seqno, end_lt, ...
// blockShards: for mc blocks, list of shard blocks
await processBlock(blockHeader, blockShards);
},
{
startMcBlockNumber: undefined, // from latest if omitted
mcInterval: 10 * 1000,
shardsInterval: 1000,
}
);
await subscription.start();Storage
InMemoryBlockStorage keeps processed block numbers in memory. For persistence, implement the same interface: getLastMasterchainBlockNumber(), insertBlocks(mcSeqno, shardBlocks) (and any other methods the subscription calls).
Behavior
- Masterchain: blocks processed in chronological order;
workchain === -1,shardId === '-9223372036854775808'. - Shardchain: blocks can be processed out of order.
- If
onBlockthrows, the block is not marked processed and subscription continues. subscription.stop()stops polling.
Key points
- Use custom provider (e.g. with API key) to avoid rate limits when polling.
- Start from
startMcBlockNumberfor replay; omit to start from current. - Storage must be consistent with the callback: only mark blocks processed after successful handling if you implement custom storage.
<!-- Source references:
- https://github.com/toncenter/tonweb/blob/master/src/providers/blockSubscription/BlockSubscription.js
- https://github.com/toncenter/tonweb/blob/master/src/providers/blockSubscription/InMemoryBlockStorage.js
- https://github.com/toncenter/tonweb/blob/master/src/index.js
-->
TON DNS
Resolve human-readable .ton domains to addresses and other records. Use tonweb.dns (Dns instance) or static helpers on TonWeb.dns.
Resolve
const rootAddress = await tonweb.dns.getRootDnsAddress();
// Resolve any category (returns Cell | Address | AdnlAddress | StorageBagId | null)
const result = await tonweb.dns.resolve('sub.alice.ton', category, oneStep);
// Convenience
const walletAddress = await tonweb.dns.getWalletAddress('alice.ton');
const siteRecord = await tonweb.dns.getSiteAddress('sub.alice.ton'); // AdnlAddress or StorageBagIdCategories
Dns.DNS_CATEGORY_WALLET— smart contract address (wallet).Dns.DNS_CATEGORY_SITE— site (ADNL or storage bag).Dns.DNS_CATEGORY_NEXT_RESOLVER— next resolver contract.Dns.DNS_CATEGORY_STORAGE— storage bag id.
Pass category as second argument to resolve(); omit or use null for “all”. Use oneStep: true for non-recursive resolution.
Creating and parsing records
Static helpers for building and parsing DNS record cells:
TonWeb.dns.createSmartContractAddressRecord(address);
TonWeb.dns.createAdnlAddressRecord(adnlAddress);
TonWeb.dns.createStorageBagIdRecord(storageBagId);
TonWeb.dns.createNextResolverRecord(address);
TonWeb.dns.parseSmartContractAddressRecord(cell);
TonWeb.dns.parseAdnlAddressRecord(cell);
TonWeb.dns.parseStorageBagIdRecord(cell);
TonWeb.dns.parseSiteRecord(cell);
TonWeb.dns.parseNextResolverRecord(cell);DnsCollection and DnsItem
For managing DNS collections and items (e.g. subdomains as NFT-like items):
const { DnsCollection, DnsItem } = TonWeb.dns;
// Use with provider and options (address, code, etc.) for deploy and methodsKey points
- Root DNS address comes from config param 4; TonWeb reads it via provider.
- Wallet UX: use
getWalletAddress(domain)to show “Send to domain” and then send to the returned Address. - Site resolution returns ADNL or storage bag; use parse helpers for the type you need.
<!-- Source references:
- https://github.com/toncenter/tonweb/blob/master/src/contract/dns/Dns.js
- https://github.com/toncenter/tonweb/blob/master/src/contract/dns/DnsUtils.js
- https://github.com/toncenter/tonweb/blob/master/src/contract/dns/index.js
-->
Highload Wallet
Highload wallet (V3) supports many pending transfers in one contract using a query_id scheme. Use when you need to send a large number of transfers without waiting for each tx to confirm.
Contract and query ID
const { HighloadWalletContractV3, HighloadQueryId } = TonWeb.HighloadWallets;
const wallet = new HighloadWalletContractV3(tonweb.provider, {
publicKey: keyPair.publicKey,
wc: 0,
});
const address = await wallet.getAddress();Each transfer must use a unique subwallet query id. Use HighloadQueryId to generate and track them:
const queryId = new HighloadQueryId();
queryId.getQueryId(); // unique for this subwallet slotDeploy and transfer
Same deploy pattern as standard wallet:
const deploy = wallet.deploy(keyPair.secretKey);
await deploy.send();Transfers use the highload-specific method with query ids so many can be in flight without conflicting.
Key points
- Highload V3 is for batch/s high throughput; each outgoing message uses a distinct query id from the subwallet.
- Use
TonWeb.HighloadWallets.HighloadQueryIdto generate valid query ids and avoid reuse. - See wallet contract source and tests for exact method signatures and transfer payload format.
<!-- Source references:
- https://github.com/toncenter/tonweb/blob/master/src/contract/highloadWallet/index.js
- https://github.com/toncenter/tonweb/blob/master/src/contract/highloadWallet/HighloadWalletContractV3.js
- https://github.com/toncenter/tonweb/blob/master/src/contract/highloadWallet/HighloadQueryId.js
-->
JETTON (Fungible Tokens)
JETTON is the TON standard for fungible tokens. TonWeb provides JettonMinter (token root) and JettonWallet (user balance).
JettonMinter
Root contract: supply, admin, metadata.
const { JettonMinter } = TonWeb.token.jetton; // or TonWeb.token.ft
const minter = new JettonMinter(tonweb.provider, {
adminAddress: adminAddress,
jettonContentUri: 'https://...',
jettonWalletCodeHex: '...', // optional, has default
});
const minterAddress = await minter.getAddress();Mint (admin only): createMintBody({ jettonAmount, destination, amount, queryId }). Admin: createChangeAdminBody({ newAdminAddress }), createEditContentBody({ jettonContentUri }).
JettonWallet
User’s token wallet; create by address (e.g. from get-method get_wallet_address).
const { JettonWallet } = TonWeb.token.jetton;
const jettonWallet = new JettonWallet(tonweb.provider, { address: walletAddress });
const data = await jettonWallet.getData();
// data: { balance, ownerAddress, jettonMinterAddress, jettonWalletCode }Transfer and burn:
const transferBody = await jettonWallet.createTransferBody({
jettonAmount: amount,
toAddress: recipientAddress,
responseAddress: myAddress,
forwardAmount: TonWeb.utils.toNano(0),
forwardPayload: undefined,
});
const burnBody = await jettonWallet.createBurnBody({
jettonAmount: amount,
responseAddress: myAddress,
});Send as internal message to the JettonWallet contract with enough TON for fees.
Key points
- Balance and amounts are in token base units (minter-defined decimals).
- Transfers go to the recipient’s JettonWallet (compute address from minter + owner if needed).
- Mint is only from minter contract; transfer/burn from user’s JettonWallet.
<!-- Source references:
- https://github.com/toncenter/tonweb/blob/master/src/contract/token/ft/JettonMinter.js
- https://github.com/toncenter/tonweb/blob/master/src/contract/token/ft/JettonWallet.js
- https://github.com/toncenter/tonweb/blob/master/src/contract/token/ft/index.js
-->
Ledger Hardware Wallet
TonWeb integrates Ledger TON app via @ledgerhq/hw-transport-* and exposes TonWeb.ledger with transports and AppTon for get address, sign, and transfer.
Setup
const TonWeb = require('tonweb');
const { TransportWebUSB, TransportWebHID, BluetoothTransport, AppTon } = TonWeb.ledger;
const transport = await TransportWebUSB.create();
const ton = new TonWeb();
const app = new AppTon(transport, ton);Use TransportWebHID.create() or BluetoothTransport.create() for HID or BLE.
AppTon API
- getAppConfiguration() —
{ version }(e.g. "1.2.3"). - getPublicKey(accountNumber, isDisplay) —
{ publicKey: Uint8Array }.accountNumberis index; setisDisplayto show on device. - getAddress(accountNumber, isDisplay, addressFormat) — returns Wallet V3R1 address:
{ address: Address }.addressFormatis a sum of: ADDRESS_FORMAT_HEX(0)ADDRESS_FORMAT_USER_FRIENDLY(1)ADDRESS_FORMAT_URL_SAFE(2)ADDRESS_FORMAT_BOUNCEABLE(4)ADDRESS_FORMAT_TEST_ONLY(8)- sign(accountNumber, buffer) — sign arbitrary bytes:
{ signature: Buffer }. - transfer(accountNumber, wallet, toAddress, amount, seqno, addressFormat) — build and sign a wallet transfer. Uses same semantics as
WalletContract.createTransferMessage. Ifseqno === 0, produces deploy + transfer. Returns a method object (e.g..send()).
Example: get address and send
const { address } = await app.getAddress(0, true, app.ADDRESS_FORMAT_USER_FRIENDLY + app.ADDRESS_FORMAT_BOUNCEABLE);
const wallet = ton.wallet.create({ address });
const seqno = await wallet.methods.seqno().call();
const method = await app.transfer(0, wallet, 'EQ...', TonWeb.utils.toNano('0.01'), seqno, 0);
await method.send();Key points
- Ledger app returns Wallet V3R1 address; use
tonweb.wallet.create({ address })to get a wallet interface. - For transfer, pass the same
walletinstance and currentseqno; the device signs the transfer message. - Close transport when done:
transport.close().
<!-- Source references:
- sources/tonweb/src/ledger/AppTon.js
- sources/tonweb/src/index.js (TonWeb.ledger)
-->
Vesting Wallet (VestingWalletV1)
TonWeb includes a vesting wallet contract: coins unlock over time (vesting schedule). Access via tonweb.lockupWallet.VestingWalletV1 or tonweb.lockupWallet.all['vesting-1'].
Creating
const VestingWalletV1 = tonweb.lockupWallet.all['vesting-1'];
const vesting = new VestingWalletV1(provider, {
wc: 0,
publicKey,
walletId: 0x10C + 0, // WALLET_ID_BASE + wc
vestingStartTime: startUnix,
vestingTotalDuration: 86400 * 365, // seconds
unlockPeriod: 86400 * 30,
cliffDuration: 86400 * 90,
vestingTotalAmount: TonWeb.utils.toNano('1000'),
vestingSenderAddress: senderAddress,
ownerAddress: ownerAddress,
});Deploy with vesting.deploy(secretKey) then only the vesting sender can fund it; the owner can transfer when unlocked.
Get-methods
- getPublicKey() — owner public key.
- getWalletId() — subwallet id.
- getLockedAmount(time) — locked amount at given unix time (param:
[['num', time]]). - getVestingData() — full vesting config: vestingStartTime, vestingTotalDuration, unlockPeriod, cliffDuration, vestingTotalAmount, vestingSenderAddress, ownerAddress, whitelistCell.
- getWhitelist() — list of whitelisted destination addresses (for restricted transfers).
Sending (owner)
Use createInternalTransfer(params) to build an internal message body for transfer: { address, amount, payload?, sendMode?, queryId? }. Send from the wallet via standard transfer with this body (op 0xa7733acd). Whitelist can restrict destinations.
Whitelist
- createAddWhitelistBody({ addresses, queryId? }) — body to add addresses to the whitelist (op
0x7258a69b). Send from an authorized account.
Key points
- Different from LockupWalletV1 (liquid/locked/restricted with timelock and funder). VestingWalletV1 is time-based unlock with optional whitelist.
- vestingTotalDuration must be divisible by unlockPeriod; cliffDuration by unlockPeriod. Total amount is unlocked in steps over vestingTotalDuration.
<!-- Source references:
- sources/tonweb/src/contract/lockup/VestingWalletV1.js
- sources/tonweb/src/contract/lockup/index.js
-->
Lockup and Vesting Wallets
Lockup-capable wallets track three balance types: liquid (spendable), locked (spendable after timelock), and restricted (spendable after timelock or to whitelisted addresses). Used for vesting and compliance.
Balance categories
- Liquid — spendable anytime.
- Locked — spendable only after per-pool timelock.
- Restricted — like locked but can bypass timelock if destination is whitelisted.
Only a designated funder (authenticated via config_public_key) can add locked/restricted coins with timelocks; arbitrary sends add to liquid.
Deploy parameters
const LockupWallets = TonWeb.LockupWallets;
// LockupWalletV1, VestingWalletV1
{
wallet_type: 'lockup-0.1',
workchain: 0, // -1 for masterchain (e.g. validators)
config_pubkey: base64EncodedFunderPubkey,
allowed_destinations: base64EncodedBocOfWhitelistAddresses
}Whitelist is set at deploy and cannot be changed. Restore = same deploy parameters.
Usage
Instantiate with the same options as standard wallets (provider + options). Contract get-methods return liquid/locked/restricted; liquid is derived using current node time (e.g. TonCenter server time).
When spending more than liquid (minus fee), the tx can fail if timelock or destination rules are not met; fee may still be charged. UI should warn.
Key points
- Show three balances in UI: liquid, locked, restricted (sum = total).
- Receiving: normal address; only liquid is topped up by regular transfers. Locked/restricted funding is done by specialized tooling with funder key.
- Verify contract hash and funder key when accepting locked/restricted funds.
<!-- Source references:
- https://github.com/toncenter/tonweb/blob/master/src/contract/lockup/README.md
- https://github.com/toncenter/tonweb/blob/master/src/contract/lockup/LockupWalletV1.js
- https://github.com/toncenter/tonweb/blob/master/src/contract/lockup/VestingWalletV1.js
-->
NFT Content and Royalty Utils
TonWeb’s NFT helpers use NftUtils for offchain metadata (URI) and royalty params. Handy when building or reading NFT collections/items.
Offchain URI (metadata link)
- createOffchainUriCell(uri) — build a BOC cell for offchain content: 8-bit prefix
0x01+ UTF-8 encoded URI. Use as NFT content cell. - parseOffchainUriCell(cell) — read URI from such a cell (follows refs for chunked data). Throws if not offchain prefix.
const NftUtils = require('tonweb').contract.token.nft.NftUtils;
// or from NftCollection/NftItem if re-exported
const cell = NftUtils.createOffchainUriCell('https://example.com/meta/1.json');
const uri = NftUtils.parseOffchainUriCell(cell);Royalty params
Call collection get-method royalty_params and parse to a usable object:
const params = await NftUtils.getRoyaltyParams(provider, collectionAddress);
// { royalty, royaltyFactor, royaltyBase, royaltyAddress }
// royalty = royaltyFactor / royaltyBase (e.g. 0.05 for 5%)Use when displaying or enforcing royalty in marketplaces.
parseAddress(cell)
Parse an Address from a cell whose first bits encode workchain (8 bits) and hash (256 bits). Used internally by get-method result parsing (e.g. royalty_address). Exported for custom parsing.
Constants
NftUtils.OFFCHAIN_CONTENT_PREFIX(0x01),ONCHAIN_CONTENT_PREFIX(0x00)NftUtils.SNAKE_DATA_PREFIX,CHUNK_DATA_PREFIXfor on-chain content layout
Key points
- Offchain content is the common “metadata URL” pattern; onchain content uses different prefixes and layout.
- getRoyaltyParams expects the collection contract to implement
royalty_params; not all collections do.
<!-- Source references:
- sources/tonweb/src/contract/token/nft/NftUtils.js
- sources/tonweb/src/contract/token/nft/index.js
-->
NFT (Token Standard)
TonWeb includes NFT contracts compatible with the TON token standard: NftCollection, NftItem, NftMarketplace, NftSale.
NftCollection
Create and deploy a collection; mint items by index.
const { NftCollection } = TonWeb.token.nft;
const collection = new NftCollection(tonweb.provider, {
ownerAddress: ownerAddress,
collectionContentUri: 'https://...',
nftItemContentBaseUri: 'https://.../',
nftItemCodeHex: '...', // optional, has default
royalty: 0.05, // 5%, must be <= 1
royaltyAddress: ownerAddress,
});
const collectionAddress = await collection.getAddress();Mint body (send as message to collection):
const body = collection.createMintBody({
itemIndex: 0,
amount: TonWeb.utils.toNano('0.05'),
itemOwnerAddress: buyerAddress,
itemContentUri: 'https://.../0.json',
queryId: 0,
});Get-methods: getCollectionData, getNftItemAddressByIndex, getNftItemContent, getRoyaltyParams.
NftItem
Wrap an existing NFT item by address. Use for transfer, get content, or listing.
const { NftItem } = TonWeb.token.nft;
const item = new NftItem(tonweb.provider, { address: itemAddress });
const addr = await item.getAddress();
// Use contract methods for transfer, get data, etc.NftMarketplace and NftSale
NftMarketplace and NftSale model marketplace and sale contracts. Instantiate with provider and options (address/code); use their methods to build sale listings and purchase messages.
Key points
- Collections use offchain content URIs; content layout follows TON NFT metadata conventions.
- Royalty is 0–1 (e.g. 0.05 = 5%); stored with royalty base 1000.
- Mint is a message to the collection contract with correct op and payload from
createMintBody.
<!-- Source references:
- https://github.com/toncenter/tonweb/blob/master/src/contract/token/nft/NftCollection.js
- https://github.com/toncenter/tonweb/blob/master/src/contract/token/nft/NftItem.js
- https://github.com/toncenter/tonweb/blob/master/src/contract/token/nft/index.js
-->
Payment Channels
Off-chain payment channels between two parties; settle on-chain. Use tonweb.payments.createChannel() or PaymentChannel with a provider.
Create channel
const channel = tonweb.payments.createChannel({
isA: true,
channelId: new BN('...'),
myKeyPair: nacl.sign.keyPair(),
hisPublicKey: otherPartyPublicKey,
initBalanceA: TonWeb.utils.toNano(10),
initBalanceB: TonWeb.utils.toNano(5),
addressA: myWalletAddress,
addressB: otherWalletAddress,
closingConfig: {
quarantineDuration: 0,
misbehaviorFine: 0,
conditionalCloseDuration: 0,
},
excessFee: TonWeb.utils.toNano(0),
});Options include isA (which side), key pairs, initial balances, addresses, closing parameters, and excess fee.
Channel operations
PaymentChannel implements: init (top-up), cooperative commit/close, uncooperative close (challenge, settle conditionals, finish). Use the channel’s methods to build messages for:
- Init / top-up balance
- Cooperative commit (new state)
- Cooperative close (final balance split)
- Start uncooperative close, challenge quarantined state, settle conditionals, finish close
Build and send the appropriate message cells (signed as per contract) for each step.
Key points
- Both parties sign state updates; contract stores signed semi-channel state.
- Use
PaymentChannelfromtonweb.payments.PaymentChannelortonweb.payments.createChannel(); same provider/options pattern as other contracts. - Closing config (quarantine, fines, conditional duration) is set at deploy and affects dispute flow.
<!-- Source references:
- https://github.com/toncenter/tonweb/blob/master/src/contract/payments/index.js
- https://github.com/toncenter/tonweb/blob/master/src/contract/payments/PaymentChannel.js
- https://github.com/toncenter/tonweb/blob/master/src/contract/payments/PaymentUtils.js
-->
Subscription Contract
TonWeb includes a subscription contract for recurring payments: a user (wallet) pays a beneficiary periodically. Use TonWeb.SubscriptionContract.
Creating a subscription contract
const { SubscriptionContract } = TonWeb;
const subscription = new SubscriptionContract(provider, {
wc: 0,
wallet: walletAddress, // payer
beneficiary: beneficiaryAddress,
amount: TonWeb.utils.toNano('1'), // per period
period: 86400, // seconds (e.g. 1 day)
timeout: 3600, // max delay for one payment
startAt: Math.floor(Date.now() / 1000),
subscriptionId: 1,
address: undefined // optional if deploying new
});Methods
- methods.pay() — create external message for the wallet to pay this period. Returns a method (e.g.
.getQuery(),.send()). - getSubscriptionData() — call get-method
get_subscription_data; returns: wallet,beneficiary(address strings)amount(BN),period,startAt,timeout,lastPayment,lastRequest,failedAttempts,subscriptionId(numbers where applicable).
Destroying a subscription
The contract supports a "self-destruct" body (op 0x64737472): from wallet or beneficiary. Use createSelfDestructBody() for the payload; sending is contract-specific.
Key points
- The wallet (payer) must send TON to the subscription contract with the correct body (e.g. from
createBody()op0x706c7567) to trigger a payment to the beneficiary. - Use
getSubscriptionData()to show status (last payment, failed attempts) in UI. - Contract code is embedded in TonWeb; no need to pass
codeunless customizing.
<!-- Source references:
- sources/tonweb/src/contract/subscription/index.js
- sources/tonweb/src/index.js (TonWeb.SubscriptionContract)
-->
Parsing Wallet Transfer BOC
To interpret an external message or message body as a wallet transfer (e.g. for history or backend processing), use the static parsers on the wallet contract classes.
parseTransferQuery(cell)
Parses a full external message Cell (BOC) into transfer fields. Use when you have the raw message (e.g. from getTransactions or a queue).
const WalletV3 = tonweb.wallet.all.v3R1; // or v4R1, v4R2
const cell = TonWeb.boc.Cell.oneFromBoc(TonWeb.utils.base64ToBytes(boc));
const parsed = WalletV3.parseTransferQuery(cell);
// parsed: { fromAddress, toAddress, value, bounce, seqno, expireAt, payload }Throws if the cell is not a valid V3-style external transfer message (header, stateInit, body).
parseTransferBody(slice)
Parses only the signed body (after header/stateInit). Use when you already have the body cell (e.g. from an internal message).
const bodyCell = TonWeb.boc.Cell.oneFromBoc(bodyBoc);
const slice = bodyCell.beginParse();
const parsed = WalletV3.parseTransferBody(slice);
// parsed: { toAddress, value, bounce, seqno, expireAt, payload }Which wallet class
- WalletV3ContractR1, WalletV3ContractR2 — same parser (V3 transfer format).
- WalletV4ContractR1, WalletV4ContractR2 — same parser (V3-style body).
const tonweb = new TonWeb();
tonweb.wallet.all.v3R1.parseTransferQuery(cell);
tonweb.wallet.all.v4R1.parseTransferBody(slice);Key points
- Use
parseTransferQueryfor full external BOC; useparseTransferBodywhen you only have the body (e.g. from internal message body). - Parsers expect V3 transfer layout (walletId, expireAt, seqno, sendMode 3, order with dest, value, payload). Invalid layout throws.
<!-- Source references:
- sources/tonweb/src/contract/wallet/WalletQueryParser.js
- sources/tonweb/src/contract/wallet/WalletContractV3.js
- sources/tonweb/src/contract/wallet/WalletContractV4.js
- sources/tonweb/src/contract/wallet/WalletContractV4R2.js
-->
Wallet Contracts
TonWeb provides wrappers for TON wallet smart contracts (from the TON repo). Default is V3 R1.
Create wallet interface
By public key (before deploy) or by address (existing wallet):
const nacl = TonWeb.utils.nacl;
const keyPair = nacl.sign.keyPair();
let wallet = tonweb.wallet.create({ publicKey: keyPair.publicKey, wc: 0 });
// or by address only
wallet = tonweb.wallet.create({ address: 'EQDjVXa_oltdBP64Nc__p397xLCvGm2IcZ1ba7anSW0NAkeP' });
const address = await wallet.getAddress();
const seqno = await wallet.methods.seqno().call();Deploy
const deploy = wallet.deploy(keyPair.secretKey);
await deploy.estimateFee();
await deploy.send();
const deployQuery = await deploy.getQuery(); // CellTransfer TON
const transfer = wallet.methods.transfer({
secretKey: keyPair.secretKey,
toAddress: 'EQDjVXa_oltdBP64Nc__p397xLCvGm2IcZ1ba7anSW0NAkeP',
amount: TonWeb.utils.toNano('0.01'),
seqno: seqno,
payload: 'Hello', // optional string or Cell
sendMode: 3,
});
await transfer.estimateFee();
await transfer.send();
const transferQuery = await transfer.getQuery();Wallet versions
No single standard; TonWeb supports multiple versions. Default is v3R1.
tonweb.wallet.all;
// simpleR1, simpleR2, simpleR3, v2R1, v2R2, v3R1, v3R2, v4R1, v4R2
const simpleWallet = new tonweb.wallet.all.SimpleWalletContractR1(tonweb.provider, { publicKey });
const v4Wallet = new tonweb.wallet.all.WalletV4ContractR1(tonweb.provider, { publicKey });Create non-default version by using the class directly with the same create() options (e.g. { publicKey, wc: 0 }).
Key points
- Always use current
seqnofor transfers; callwallet.methods.seqno().call()before each batch. - Amounts in nanograms: use
TonWeb.utils.toNano('0.01'). sendMode: 3is commonly used (pay fees separately, ignore errors). Adjust for bounce/attach behavior.
<!-- Source references:
- https://github.com/toncenter/tonweb/blob/master/src/contract/wallet/README.md
- https://github.com/toncenter/tonweb/blob/master/src/contract/wallet/index.js
-->