Skip to content
Open

0.5.1 #234

Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
106f3ef
refactor: implement {data, error} response pattern
mois-ilya Nov 10, 2025
842fc56
feat: add schema patching system for OpenAPI client generation
mois-ilya Nov 10, 2025
3358e7c
feat: enhance HttpClient with API key management and custom fetch sup…
mois-ilya Nov 10, 2025
c7c718e
feat: implement centralized error handling for parsing errors in TonA…
mois-ilya Nov 11, 2025
df0c0d9
refactor: enhance error handling in TonAPI SDK
mois-ilya Nov 11, 2025
bdc7c8e
refactor: update TonApi client initialization and method usage
mois-ilya Nov 11, 2025
b54376d
feat: update API schema and enhance client functionality
mois-ilya Nov 11, 2025
dc86a60
chore: bump version to 0.5.0-alpha.0 in package.json and update clien…
mois-ilya Nov 11, 2025
58044f8
refactor: enhance TonApi client structure and error handling
mois-ilya Nov 13, 2025
abecfca
chore: bump version to 0.5.0-alpha.1
mois-ilya Nov 13, 2025
0a0a6b5
refactor: update examples to use TonApiClient instance
mois-ilya Nov 13, 2025
5abc4c6
chore: bump version to 0.5.0-alpha.2 in package.json and client packa…
mois-ilya Nov 13, 2025
7f3fe05
refactor: update address format to maybe-address in API schema and cl…
mois-ilya Nov 13, 2025
bb6cccc
chore: bump version to 0.5.0-alpha.3 in package.json and client packa…
mois-ilya Nov 13, 2025
d7f704c
feat: add typed error handling and address string support
mois-ilya Nov 14, 2025
9b28f2a
feat: add client-side validation and fix typed error handling
mois-ilya Nov 14, 2025
0de0bc7
chore: bump version to 0.5.0-alpha.6 in package.json and client packa…
mois-ilya Nov 14, 2025
f07dd34
feat: enhance API schema and client functionality
mois-ilya Nov 18, 2025
12feed0
fix: update JettonTransferPayload schema to use cell format for custo…
mois-ilya Nov 18, 2025
3c1a8c8
test: improve coverage with parsing tests and fix mock fetch
mois-ilya Dec 4, 2025
8b0d704
chore: bump version to 0.5.0-alpha.7
mois-ilya Dec 4, 2025
83f12af
chore(client): fix type for extra field and improve descriptions
mois-ilya Dec 10, 2025
6477ffb
chore: bump version to 0.5.0-alpha.8
mois-ilya Dec 10, 2025
fef0e20
fix(client): correct BlockchainConfig code_hash type from Address to …
mois-ilya Dec 22, 2025
363037e
chore: bump version to 0.5.0-alpha.9
mois-ilya Dec 22, 2025
3bbf469
fix(client): add stack trace to parsing error console output
mois-ilya Dec 22, 2025
f508238
chore: bump version to 0.5.1 and update API schema
rAndom1zeeeR Jun 19, 2026
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