Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
8c775dd
refactor: improve TonApiError ergonomics and fix parsing errors
claude Nov 10, 2025
a5b6121
feat: add schema patching system for OpenAPI client generation
mois-ilya Nov 10, 2025
71ffa60
feat: enhance HttpClient with API key management and custom fetch sup…
mois-ilya Nov 10, 2025
a70370f
feat: implement centralized error handling for parsing errors in TonA…
mois-ilya Nov 11, 2025
e4cd6ed
refactor: enhance error handling in TonAPI SDK
mois-ilya Nov 11, 2025
a051ad1
refactor: update TonApi client initialization and method usage
mois-ilya Nov 11, 2025
7a49ec7
feat: update API schema and enhance client functionality
mois-ilya Nov 11, 2025
3513d9f
chore: bump version to 0.5.0-alpha.0 in package.json and update clien…
mois-ilya Nov 11, 2025
c0b7b6d
tmp
mois-ilya Nov 11, 2025
9c5b1f9
refactor: enhance TonApi client structure and error handling
mois-ilya Nov 13, 2025
b7b50f9
chore: bump version to 0.5.0-alpha.1
mois-ilya Nov 13, 2025
c886e95
refactor: update examples to use TonApiClient instance
mois-ilya Nov 13, 2025
998aac3
chore: bump version to 0.5.0-alpha.2 in package.json and client packa…
mois-ilya Nov 13, 2025
80d907a
refactor: update address format to maybe-address in API schema and cl…
mois-ilya Nov 13, 2025
c0cf9a6
chore: bump version to 0.5.0-alpha.3 in package.json and client packa…
mois-ilya Nov 13, 2025
74ae3ae
feat: add typed error handling and address string support
mois-ilya Nov 14, 2025
cc831d2
feat: add client-side validation and fix typed error handling
mois-ilya Nov 14, 2025
e89aeaf
chore: bump version to 0.5.0-alpha.6 in package.json and client packa…
mois-ilya Nov 14, 2025
20e78b6
feat: enhance API schema and client functionality
mois-ilya Nov 18, 2025
fe4762d
fix: update JettonTransferPayload schema to use cell format for custo…
mois-ilya Nov 18, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 25 additions & 6 deletions examples/emulate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,19 +11,38 @@ import {
import { mnemonicNew, mnemonicToPrivateKey } from '@ton/crypto';
import { TonApiClient } from '@ton-api/client';

// Create TonApiClient instance
// if you need to send lots of requests in parallel, make sure you use a tonapi token.
const ta = new TonApiClient({
const tonApiClient = new TonApiClient({
baseUrl: 'https://tonapi.io',
apiKey: 'YOUR_API_KEY'
// apiKey: 'YOUR_API_KEY'
});

// Sender's wallet address
const senderAddress = Address.parse('UQAQxxpzxmEVU0Lu8U0zNTxBzXIWPvo263TIN1OQM9YvxsnV');
const recipientAddress = Address.parse('UQDNzlh0XSZdb5_Qrlx5QjyZHVAO74v5oMeVVrtF_5Vt1rIt');

// Get wallet's seqno and public key
const { seqno } = await ta.wallet.getAccountSeqno(senderAddress);
const { publicKey: publicKeyHex } = await ta.accounts.getAccountPublicKey(senderAddress);
const seqno = await tonApiClient
.getAccountSeqno(senderAddress)
.then(seqnoData => seqnoData.seqno)
.catch((error: unknown) => {
console.error(
'Error getting account seqno:',
error instanceof Error ? error.message : String(error)
);
process.exit(1);
});

const publicKeyHex = await tonApiClient
.getAccountPublicKey(senderAddress)
.then(publicKeyData => publicKeyData.publicKey)
.catch((error: unknown) => {
console.error(
'Error getting account public key:',
error instanceof Error ? error.message : String(error)
);
process.exit(1);
});

// Emulate transaction from wallet_v4 address
const wallet = WalletContractV4.create({
Expand Down Expand Up @@ -73,7 +92,7 @@ const bocExternalMessage = beginCell()
.endCell();

// Emulate transaction
const emulateTrace = await ta.emulation.emulateMessageToTrace(
const emulateTrace = await tonApiClient.emulateMessageToTrace(
{ boc: bocExternalMessage },
{ ignore_signature_check: true } // Ignore signature for execute message from other account
);
Expand Down
63 changes: 43 additions & 20 deletions examples/gasless.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,17 @@ import {
storeMessageRelaxed
} from '@ton/ton';

import { TonApiClient } from '@ton-api/client';
import { TonApiClient, TonApiHttpError } from '@ton-api/client';
import { ContractAdapter } from '@ton-api/ton-adapter';

// Create TonApiClient instance
// if you need to send lots of requests in parallel, make sure you use a tonapi token.
const ta = new TonApiClient({
const tonApiClient = new TonApiClient({
baseUrl: 'https://tonapi.io',
apiKey: 'YOUR_API_KEY'
// apiKey: 'YOUR_API_KEY'
});

const provider = new ContractAdapter(ta);
const provider = new ContractAdapter(tonApiClient);

const OP_CODES = {
TK_RELAYER_FEE: 0x878da6e3,
Expand All @@ -47,13 +48,15 @@ const contract = provider.open(wallet);

console.log('Wallet address:', wallet.address.toString());

const jettonWalletAddressResult = await ta.blockchain.execGetMethodForBlockchainAccount(
usdtMaster,
'get_wallet_address',
{
const jettonWalletAddressResult = await tonApiClient
.execGetMethodForBlockchainAccount(usdtMaster, 'get_wallet_address', {
args: [wallet.address.toRawString()]
}
);
})
.catch((getWalletError: unknown) => {
console.error('Error getting jetton wallet:',
getWalletError instanceof Error ? getWalletError.message : String(getWalletError));
process.exit(1);
});

const jettonWallet = Address.parse(jettonWalletAddressResult.decoded.jetton_wallet_address);

Expand Down Expand Up @@ -90,11 +93,17 @@ const messageToEstimate = beginCell()
// we send a single message containing a transfer from our wallet to a desired destination.
// as a result of estimation, TonAPI returns a list of messages that we need to sign.
// the first message is a fee transfer to the relay address, the second message is our original transfer.
const params = await ta.gasless.gaslessEstimate(usdtMaster, {
walletAddress: wallet.address,
walletPublicKey: keyPair.publicKey.toString('hex'),
messages: [{ boc: messageToEstimate }]
}); //.catch(error => console.error(error));
const params = await tonApiClient
.gaslessEstimate(usdtMaster, {
walletAddress: wallet.address,
walletPublicKey: keyPair.publicKey.toString('hex'),
messages: [{ boc: messageToEstimate }]
})
.catch((estimateError: unknown) => {
console.error('Error estimating gasless transfer:',
estimateError instanceof Error ? estimateError.message : String(estimateError));
process.exit(1);
});

console.log('Estimated transfer:', params);

Expand Down Expand Up @@ -129,19 +138,33 @@ const extMessage = beginCell()
.endCell();

// Send a gasless transfer
ta.gasless
const sendResult = await tonApiClient
.gaslessSend({
walletPublicKey: keyPair.publicKey.toString('hex'),
boc: extMessage
})
.then(() => console.log('A gasless transfer sent!'))
.catch(error => console.error(error.message));
.catch((sendError: unknown) => {
if (sendError instanceof TonApiHttpError) {
console.error('Error sending gasless transfer:', sendError.message, 'Status:', sendError.status);
} else {
console.error('Error sending gasless transfer:', sendError instanceof Error ? sendError.message : String(sendError));
}
return null;
});

if (sendResult) {
console.log('A gasless transfer sent!');
}

async function printConfigAndReturnRelayAddress(): Promise<Address> {
const cfg = await ta.gasless.gaslessConfig();
const cfg = await tonApiClient.gaslessConfig().catch((error: unknown) => {
console.error('Error getting gasless config:',
error instanceof Error ? error.message : String(error));
process.exit(1);
});

console.log('Available jettons for gasless transfer');
console.log(cfg.gasJettons.map(gasJetton => gasJetton.masterId));
console.log(cfg.gasJettons.map((gasJetton: any) => gasJetton.masterId));

console.log(`Relay address to send fees to: ${cfg.relayAddress}`);
return cfg.relayAddress;
Expand Down
15 changes: 9 additions & 6 deletions examples/send-jetton.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,14 @@ import { mnemonicToPrivateKey } from '@ton/crypto';
import { TonApiClient } from '@ton-api/client';
import { ContractAdapter } from '@ton-api/ton-adapter';

// Initialize TonApi client
const ta = new TonApiClient({
// Create TonApiClient instance
const tonApiClient = new TonApiClient({
baseUrl: 'https://tonapi.io',
apiKey: 'YOUR_API_KEY', // Optional, improves request limits and access
// apiKey: 'YOUR_API_KEY', // Optional, improves request limits and access
});

// Create an adapter for interacting with contracts
const adapter = new ContractAdapter(ta);
const adapter = new ContractAdapter(tonApiClient);

// Base gas fee required for the jetton transfer
const BASE_JETTON_SEND_AMOUNT = toNano(0.05);
Expand All @@ -32,11 +32,14 @@ const wallet = WalletContractV5R1.create({ workchain: 0, publicKey: keyPair.publ
const contract = adapter.open(wallet); // Open the wallet contract using the adapter

// Get the sender's jetton wallet address from the jetton master contract
const jettonWalletAddressResult = await ta.blockchain.execGetMethodForBlockchainAccount(
const jettonWalletAddressResult = await tonApiClient.execGetMethodForBlockchainAccount(
jettonMaster,
'get_wallet_address',
{ args: [wallet.address.toRawString()] }
);
).catch((error) => {
console.error('Error getting jetton wallet address:', error.message);
process.exit(1);
});

const jettonWallet = Address.parse(jettonWalletAddressResult.decoded.jetton_wallet_address); // Extract the jetton wallet address

Expand Down
8 changes: 4 additions & 4 deletions examples/send-ton.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,14 @@ import { mnemonicToPrivateKey } from '@ton/crypto';
import { TonApiClient } from '@ton-api/client';
import { ContractAdapter } from '@ton-api/ton-adapter';

// Initialize TonApi client
const ta = new TonApiClient({
// Create TonApiClient instance
const tonApiClient = new TonApiClient({
baseUrl: 'https://tonapi.io',
apiKey: 'YOUR_API_KEY', // Optional, improves limits and access
// apiKey: 'YOUR_API_KEY', // Optional, improves limits and access
});

// Create an adapter for interacting with contracts
const adapter = new ContractAdapter(ta);
const adapter = new ContractAdapter(tonApiClient);

// Convert mnemonic phrase to a private key
const mnemonics = 'word1 word2 ...'.split(' '); // Replace with your mnemonic phrase
Expand Down
25 changes: 16 additions & 9 deletions examples/track-transaction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,12 +35,12 @@ function normalizeHash(message: Message, normalizeExternal: boolean): Buffer {
// 1) Using normalizeHash with a manually-created external message
// ----------------------------------------------------------

// Step 1: Initialize the TonAPI client
const ta = new TonApiClient({
// Step 1: Create TonApiClient instance
const tonApiClient = new TonApiClient({
baseUrl: 'https://tonapi.io'
// apiKey: 'YOUR_API_KEY', // Optional, improves request limits and access
});
const adapter = new ContractAdapter(ta);
const adapter = new ContractAdapter(tonApiClient);

// Step 2: Define the wallet and recipient addresses
const destination = Address.parse('EQCKWpx7cNMpvmcN5ObM5lLUZHZRFKqYA4xmw9jOry0ZsF9M');
Expand Down Expand Up @@ -83,9 +83,13 @@ console.log('Manual Message Hash:', manualExtMessageHash.toString('hex'));
await delay(10000);

// Step 8: Retrieve the resulting transaction using the normalized external hash
const manualTransaction = await ta.blockchain.getBlockchainTransactionByMessageHash(
manualExtMessageHash.toString('hex')
);
// You can retry this step if the transaction is not found, until
const manualTransaction = await tonApiClient
.getBlockchainTransactionByMessageHash(manualExtMessageHash.toString('hex'))
.catch((error) => {
console.error('Error fetching transaction:', error.message);
return null;
});
console.log('Manual Transaction Details:', manualTransaction);

// ----------------------------------------------------------
Expand All @@ -106,7 +110,10 @@ const bocExtMessageHash = normalizeHash(bocMessage, true);
console.log('BOC Message Hash:', bocExtMessageHash.toString('hex'));

// Step 3: Retrieve the transaction using that hash
const bocTransaction = await ta.blockchain.getBlockchainTransactionByMessageHash(
bocExtMessageHash.toString('hex')
);
const bocTransaction = await tonApiClient
.getBlockchainTransactionByMessageHash(bocExtMessageHash.toString('hex'))
.catch((error) => {
console.error('Error fetching transaction:', error.message);
return null;
});
console.log('BOC Transaction Details:', bocTransaction);
Loading