Skip to main content

Overview

Dynamic’s Node SDK provides comprehensive support for TON blockchain operations, including wallet creation, transaction signing, message signing, and key management. The SDK implements Multi-Party Computation (MPC) for enhanced security.

Key Features

  • MPC Wallet Creation: Create secure TON wallets with threshold signature schemes
  • Transaction Signing: Sign TON transactions (BOC format) without exposing private keys
  • Message Signing: Sign messages using Ed25519, returned as base64 strings
  • Key Import/Export: Import existing private keys and export wallet data
  • Multiple Security Models: Choose between different threshold signature schemes

Available Threshold Signature Schemes

  • TWO_OF_TWO: Maximum security - requires both server and Dynamic infrastructure
  • TWO_OF_THREE: Balanced security and availability - requires 2 out of 3 shares
  • THREE_OF_FIVE: High availability - requires 3 out of 5 shares

Quick Start

import { DynamicTonWalletClient } from '@dynamic-labs-wallet/node-ton';
import { ThresholdSignatureScheme } from '@dynamic-labs-wallet/node';

const client = new DynamicTonWalletClient({
  environmentId: process.env.DYNAMIC_ENVIRONMENT_ID!,
});

await client.authenticateApiToken(process.env.DYNAMIC_AUTH_TOKEN!);

// Create a new wallet
const wallet = await client.createWalletAccount({
  thresholdSignatureScheme: ThresholdSignatureScheme.TWO_OF_TWO,
  backUpToClientShareService: true,
});

console.log('Wallet created:', wallet.accountAddress);

Core Functions

Wallet Management

  • createWalletAccount() - Create new TON wallet
  • importPrivateKey() - Import existing private key
  • getWallet() - Get specific wallet details
  • getTonWallets() - Get all TON wallets
  • deriveTonAddress() - Derive TON address from a public key (synchronous)

Signing Operations

  • signMessage() - Sign messages (Ed25519, base64 output)
  • signTransaction() - Sign TON transactions (BOC format)

Key Management

  • exportKey() - Export wallet key data
  • offlineExportPrivateKey() - Export private key from key shares offline
  • encryptKeyShare() - Encrypt key shares
  • decryptKeyShare() - Decrypt key shares

Backup and Recovery

  • storeEncryptedBackupByWallet() - Store encrypted backup
  • recoverEncryptedBackupByWallet() - Recover encrypted backup
  • refreshWalletAccountShares() - Refresh wallet shares

Guides

Prerequisites

Before using the TON SDK, ensure you have:
  1. Dynamic Project Setup: Set up your Dynamic project
  2. Environment Configuration: Configure your environment ID and auth token
  3. TON Chain Enabled: Enable TON chain in your Dynamic dashboard
  4. Dependencies Installed: Install required packages

Installation

bun add @dynamic-labs-wallet/node-ton @ton/ton @ton/crypto @dynamic-labs-wallet/node

Environment Variables

DYNAMIC_AUTH_TOKEN=your_auth_token_here
DYNAMIC_ENVIRONMENT_ID=your_environment_id_here

TON-Specific Concepts

Address Format

TON addresses are user-friendly strings (e.g., EQD...), derived from the wallet contract. The SDK uses WalletContractV5R1 by default. You can also derive an address from a public key using deriveTonAddress().

Native Unit

TON uses nanotons as its smallest unit: 1 TON = 1,000,000,000 nanotons.

Transaction Format

TON transactions use BOC (Bag of Cells) serialization. The signTransaction() method accepts a Cell object built with @ton/ton helpers and returns a signed BOC.

Jettons

TON’s fungible token standard is called Jettons. Transferring Jettons requires interacting with Jetton wallet contracts on-chain.

Security Considerations

  • MPC Architecture: Private keys are never stored in plain text
  • Threshold Signing: Multiple parties must collaborate to sign transactions
  • Key Share Backup: Use backUpToClientShareService: true for secure storage
  • Password Protection: Implement strong passwords for additional security layers

Network Support

The SDK currently supports TON Mainnet (workchain 0).

Error Handling

Always implement proper error handling:
try {
  const result = await tonClient.someFunction(params);
  console.log('Operation successful:', result);
} catch (error) {
  console.error('Operation failed:', error instanceof Error ? error.message : String(error));
}

Next Steps