Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
547fafb
feat(emulation): start creating models for emulation
heyllog Apr 24, 2026
7f09223
feat(emulation): move types to clients
heyllog Apr 27, 2026
a6b9d84
feat(emulation): move ApiClient to api/interfaces
heyllog Apr 27, 2026
4cdd5c4
feat(emulation): fetchEmulation returns new model
heyllog Apr 27, 2026
d6d3a0e
feat(emulation): delete dead code
heyllog Apr 27, 2026
7e072d0
feat(emulation): fetchEmulation added in tonapi
heyllog Apr 28, 2026
41b4b3d
feat(emulation): add nft actions mapping
heyllog Apr 28, 2026
d04fd19
Merge branch 'main' into feat/TON-858-tonapi-emulation
heyllog Apr 29, 2026
c6ee476
feat(emulation): more adjustments
heyllog Apr 30, 2026
e3651b5
feat(emulation): remove moneyflow from response
heyllog May 1, 2026
a64a12f
feat(emulation): remove unused old code
heyllog May 1, 2026
90280c2
feat(emulation): rework models
heyllog May 1, 2026
90845d2
feat(emulation): make opcode hex
heyllog May 1, 2026
d144286
feat(appkit): add status mapping
heyllog May 1, 2026
b966c6c
feat(emulation): replace null with undefined
heyllog May 4, 2026
260a70d
feat(emulation): update exports
heyllog May 4, 2026
9eb4764
feat(emulation): replace record with object
heyllog May 5, 2026
2d3bb09
feat(emulation): map bits and cells to number
heyllog May 5, 2026
2b60c6c
feat(emulation): map bits and cells to number in EmulationActionMessa…
heyllog May 5, 2026
c67bb0e
feat(emulation): add changeset and fix quality issues
heyllog May 8, 2026
938a7bb
fix: SwiftAPIClientAdapter type fix
TrueCarry May 8, 2026
f8cc768
fix: update return types in AndroidAPIClientAdapter to use undefined …
TrueCarry May 9, 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
7 changes: 7 additions & 0 deletions .changeset/tonapi-emulation-domain-models.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
'@ton/walletkit': patch
'@ton/appkit': patch
'@ton/mcp': patch
---

Added emulation support to the TonAPI client and introduced provider-agnostic emulation domain models under `api/models/emulation` (`EmulationResult`, `EmulationResponse`, `EmulationTransaction`, `EmulationMessage`, `EmulationAction`, `EmulationTraceNode`, `EmulationAddressBookEntry`). `ApiClient.fetchEmulation` now returns `EmulationResult` instead of the toncenter-specific `ToncenterEmulationResult`, so callers get the same shape regardless of backend. Reorganized toncenter raw types under `clients/toncenter/types/*` (NFTs, jettons, DNS, metadata, raw emulation), moved the `ApiClient` interface to `api/interfaces`, removed legacy emulation parsing utilities (`utils/toncenterEmulation`, message/jetton parser handlers), and migrated optional NFT and DNS results from `null` to `undefined` across walletkit, appkit, and mcp.
2 changes: 1 addition & 1 deletion packages/appkit/src/actions/nft/get-nft.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ export interface GetNftOptions {
network?: Network;
}

export type GetNftReturnType = NFT | null;
export type GetNftReturnType = NFT | undefined;

export const getNft = async (appKit: AppKit, options: GetNftOptions): Promise<GetNftReturnType> => {
const { address, network } = options;
Expand Down
2 changes: 1 addition & 1 deletion packages/appkit/src/queries/nft/get-nft.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ export const getNftQueryOptions = <selectData = GetNftData>(
};
};

export type GetNftQueryFnData = Compute<NFT | null>;
export type GetNftQueryFnData = Compute<NFT | undefined>;

export type GetNftData = GetNftQueryFnData;

Expand Down
6 changes: 4 additions & 2 deletions packages/mcp/src/services/McpWalletService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1104,15 +1104,17 @@ export class McpWalletService {
*/
async resolveDns(domain: string): Promise<string | null> {
const client = this.wallet.getClient();
return client.resolveDnsWallet(domain);
const address = await client.resolveDnsWallet(domain);
return address ?? null;
}

/**
* Reverse resolve a wallet address to a TON DNS domain
*/
async backResolveDns(address: string): Promise<string | null> {
const client = this.wallet.getClient();
return client.backResolveDnsWallet(address);
const domain = await client.backResolveDnsWallet(address);
return domain ?? null;
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import type {
TransactionsResponse,
JettonsResponse,
FullAccountState,
ToncenterEmulationResult,
EmulationResult,
ToncenterResponseJettonMasters,
ToncenterTracesResponse,
TransactionsByAddressRequest,
Expand Down Expand Up @@ -139,7 +139,7 @@ export class AndroidAPIClientAdapter implements ApiClient {
throw new Error('nftItemsByOwner is not implemented yet');
}

async fetchEmulation(_messageBoc: Base64String, _ignoreSignature?: boolean): Promise<ToncenterEmulationResult> {
async fetchEmulation(_messageBoc: Base64String, _ignoreSignature?: boolean): Promise<EmulationResult> {
throw new Error('fetchEmulation is not implemented yet');
}

Expand Down Expand Up @@ -179,11 +179,11 @@ export class AndroidAPIClientAdapter implements ApiClient {
throw new Error('getPendingTrace is not implemented yet');
}

async resolveDnsWallet(_domain: string): Promise<string | null> {
async resolveDnsWallet(_domain: string): Promise<string | undefined> {
throw new Error('resolveDnsWallet is not implemented yet');
}

async backResolveDnsWallet(_address: UserFriendlyAddress): Promise<string | null> {
async backResolveDnsWallet(_address: UserFriendlyAddress): Promise<string | undefined> {
throw new Error('backResolveDnsWallet is not implemented yet');
}

Expand Down
8 changes: 4 additions & 4 deletions packages/walletkit-ios-bridge/src/SwiftAPIClientAdapter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import type {
TransactionsResponse,
JettonsResponse,
FullAccountState,
ToncenterEmulationResult,
EmulationResult,
ToncenterResponseJettonMasters,
ToncenterTracesResponse,
TransactionsByAddressRequest,
Expand Down Expand Up @@ -62,7 +62,7 @@ export class SwiftAPIClientAdapter implements ApiClient {
throw new Error('nftItemsByOwner is not implemented yet');
}

async fetchEmulation(_messageBoc: Base64String, _ignoreSignature?: boolean): Promise<ToncenterEmulationResult> {
async fetchEmulation(_messageBoc: Base64String, _ignoreSignature?: boolean): Promise<EmulationResult> {
throw new Error('fetchEmulation is not implemented yet');
}

Expand Down Expand Up @@ -94,11 +94,11 @@ export class SwiftAPIClientAdapter implements ApiClient {
throw new Error('getPendingTrace is not implemented yet');
}

async resolveDnsWallet(_domain: string): Promise<string | null> {
async resolveDnsWallet(_domain: string): Promise<string | undefined> {
throw new Error('resolveDnsWallet is not implemented yet');
}

async backResolveDnsWallet(_address: UserFriendlyAddress): Promise<string | null> {
async backResolveDnsWallet(_address: UserFriendlyAddress): Promise<string | undefined> {
throw new Error('backResolveDnsWallet is not implemented yet');
}

Expand Down
1 change: 1 addition & 0 deletions packages/walletkit/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@
"build:esm": "tsc -p tsconfig.esm.json",
"dev": "tsc -p tsconfig.esm.json --watch",
"test": "vitest run",

"test:coverage": "vitest run --coverage",
"test:mutation": "stryker run stryker.config.js",
"quality": "pnpm test:coverage",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@

import type { Address } from '@ton/core';

import type { ToncenterResponseJettonMasters, ToncenterTracesResponse } from './emulation';
import type { FullAccountState } from './api';
import type { Event } from './AccountEvent';
import type { ToncenterResponseJettonMasters, ToncenterTracesResponse } from '../../types/toncenter/emulation';
import type { FullAccountState } from '../../types/toncenter/api';
import type { Event } from '../../types/toncenter/AccountEvent';
import type {
Base64String,
UserNFTsRequest,
Expand All @@ -23,8 +23,8 @@ import type {
RawStackItem,
GetMethodResult,
MasterchainInfo,
} from '../../api/models';
import type { ToncenterEmulationResult } from '../../utils/toncenterEmulation';
} from '../models';
import type { EmulationResult } from '../models';

export interface LimitRequest {
limit?: number;
Expand Down Expand Up @@ -97,7 +97,7 @@ export interface GetEventsResponse {
export interface ApiClient {
nftItemsByAddress(request: NFTsRequest): Promise<NFTsResponse>;
nftItemsByOwner(request: UserNFTsRequest): Promise<NFTsResponse>;
fetchEmulation(messageBoc: Base64String, ignoreSignature?: boolean): Promise<ToncenterEmulationResult>;
fetchEmulation(messageBoc: Base64String, ignoreSignature?: boolean): Promise<EmulationResult>;
sendBoc(boc: Base64String): Promise<string>;
runGetMethod(
address: UserFriendlyAddress,
Expand All @@ -116,8 +116,8 @@ export interface ApiClient {
getTrace(request: GetTraceRequest): Promise<ToncenterTracesResponse>;
getPendingTrace(request: GetPendingTraceRequest): Promise<ToncenterTracesResponse>;

resolveDnsWallet(domain: string): Promise<string | null>;
backResolveDnsWallet(address: UserFriendlyAddress): Promise<string | null>;
resolveDnsWallet(domain: string): Promise<string | undefined>;
backResolveDnsWallet(address: UserFriendlyAddress): Promise<string | undefined>;

jettonsByAddress(request: GetJettonsByAddressRequest): Promise<ToncenterResponseJettonMasters>;
jettonsByOwnerAddress(request: GetJettonsByOwnerRequest): Promise<JettonsResponse>;
Expand Down
4 changes: 2 additions & 2 deletions packages/walletkit/src/api/interfaces/Wallet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
*
*/

import type { ApiClient } from '../../types/toncenter/ApiClient';
import type { ApiClient } from './ApiClient';
import type {
TokenAmount,
TONTransferRequest,
Expand Down Expand Up @@ -52,5 +52,5 @@ export interface WalletNftInterface {
createTransferNftTransaction(params: NFTTransferRequest): Promise<TransactionRequest>;
createTransferNftRawTransaction(params: NFTRawTransferRequest): Promise<TransactionRequest>;
getNfts(params: NFTsRequest): Promise<NFTsResponse>;
getNft(address: UserFriendlyAddress): Promise<NFT | null>;
getNft(address: UserFriendlyAddress): Promise<NFT | undefined>;
}
16 changes: 16 additions & 0 deletions packages/walletkit/src/api/interfaces/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,19 @@ export type { TONConnectSessionManager } from './TONConnectSessionManager';
// Streaming interfaces
export type { StreamingProvider, StreamingProviderFactory } from './StreamingProvider';
export type { StreamingAPI } from './StreamingAPI';

export type {
LimitRequest,
NftItemsRequest,
NftItemsByOwnerRequest,
TransactionsByAddressRequest,
GetTransactionByHashRequest,
GetPendingTransactionsRequest,
GetTraceRequest,
GetPendingTraceRequest,
GetJettonsByOwnerRequest,
GetJettonsByAddressRequest,
GetEventsRequest,
GetEventsResponse,
ApiClient,
} from './ApiClient';
93 changes: 93 additions & 0 deletions packages/walletkit/src/api/models/emulation/EmulationAction.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
/**
* Copyright (c) TonTech.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*/

import type { UserFriendlyAddress, LogicalTime, Hex } from '../core/Primitives';

/**
* High-level action extracted from an emulated transaction trace.
*/
export interface EmulationAction {
/**
* Trace identifier this action belongs to
*/
traceId?: string;

/**
* Hex-encoded unique identifier of the action
*/
actionId: Hex;

/**
* Logical time when the action started
*/
startLt: LogicalTime;

/**
* Logical time when the action ended
*/
endLt: LogicalTime;

/**
* Unix timestamp when the action started
* @format timestamp
*/
startUtime: number;

/**
* Unix timestamp when the action ended
* @format timestamp
*/
endUtime: number;

/**
* Logical time when the trace ended
*/
traceEndLt: LogicalTime;

/**
* Unix timestamp when the trace ended
* @format timestamp
*/
traceEndUtime: number;

/**
* Masterchain block sequence number when the trace ended
* @format int
*/
traceMcSeqnoEnd: number;

/**
* Hex-encoded hashes of transactions involved in this action
*/
transactions: Hex[];

/**
* Whether the action completed successfully
*/
isSuccess: boolean;

/**
* Action type identifier (e.g. "jetton_transfer", "ton_transfer", "jetton_swap")
*/
type: string;

/**
* Hex-encoded external message hash of the root trace
*/
traceExternalHash: Hex;

/**
* Addresses of accounts involved in this action
*/
accounts: UserFriendlyAddress[];

/**
* Action-specific detail fields keyed by name
*/
details: { [key: string]: unknown };
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
/**
* Copyright (c) TonTech.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*/

import type { UserFriendlyAddress } from '../core/Primitives';

/**
* Address book entry providing human-readable metadata for an on-chain address.
*/
export interface EmulationAddressBookEntry {
/**
* DNS domain name associated with the address, if any
*/
domain?: string;

/**
* User-friendly representation of the address
*/
userFriendly: UserFriendlyAddress;

/**
* List of known interfaces implemented by the contract
*/
interfaces: string[];
}
Loading
Loading