Skip to main content
Blueprint provides comprehensive testing capabilities for TON smart contracts using the TON Sandbox emulator and test utilities. This reference covers all available testing APIs, methods, and utilities.

Quick Navigation

Main Sections: Related Documentation:

Environment setup

Blueprint testing environment requires proper setup of the TON Sandbox and test utilities.

Installation

npm install --save-dev @ton/sandbox @ton/test-utils

Basic test structure

./tests/Sample.spec.ts
import { Blockchain, SandboxContract, TreasuryContract } from '@ton/sandbox';
import { Cell, toNano } from '@ton/core';
import { Sample } from '../wrappers/Sample';
import '@ton/test-utils';
import { compile } from '@ton/blueprint';

describe('Sample', () => {
    let code: Cell;

    beforeAll(async () => {
        code = await compile('Sample');
    });

    let blockchain: Blockchain;
    let deployer: SandboxContract<TreasuryContract>;
    let sample: SandboxContract<Sample>;

    beforeEach(async () => {
        blockchain = await Blockchain.create();

        sample = blockchain.openContract(Sample.createFromConfig({}, code));

        deployer = await blockchain.treasury('deployer');

        const deployResult = await sample.sendDeploy(deployer.getSender(), toNano('0.05'));

        expect(deployResult.transactions).toHaveTransaction({
            from: deployer.address,
            to: sample.address,
            deploy: true,
            success: true,
        });
    });

    it('should deploy', async () => {
        // the check is done inside beforeEach
        // blockchain and sample are ready to use
    });
});

Core Testing Classes

Blockchain

Main blockchain emulator class that provides isolated testing environment.
class Blockchain {
    static create(opts?: {
        executor?: IExecutor;
        config?: BlockchainConfig;
        storage?: BlockchainStorage;
        meta?: ContractsMeta;
        autoDeployLibs?: boolean;
    }): Promise<Blockchain>

    // Contract and states management
    treasury(seed: string, params?: TreasuryParams): Promise<SandboxContract<TreasuryContract>>
    createWallets(n: number, params?: TreasuryParams): Promise<SandboxContract<TreasuryContract>[]>
    openContract<T extends Contract>(contract: T): SandboxContract<T>
    provider(address: Address, init?: StateInit | null): ContractProvider
    sender(address: Address): Sender
    getContract(address: Address): Promise<SmartContract>
    setShardAccount(address: Address, account: ShardAccount): Promise<void>
    getTransactions(address: Address, opts?: { limit?: number; lt?: string | bigint; hash?: string | Buffer }): Promise<BlockchainTransaction[]>

    // Core messaging methods
    sendMessage(message: Message | Cell, params?: MessageParams): Promise<SendMessageResult>
    sendMessageIter(message: Message | Cell, params?: SendMessageIterParams): Promise<AsyncIterator<BlockchainTransaction> & AsyncIterable<BlockchainTransaction>>
    runGetMethod(address: Address, method: number | string, stack?: TupleItem[], params?: GetMethodParams): Promise<GetMethodResult>
    runTickTock(on: Address | Address[], which: TickOrTock, params?: MessageParams): Promise<SendMessageResult>

    // Snapshotting
    snapshot(): BlockchainSnapshot
    loadFrom(snapshot: BlockchainSnapshot): Promise<void>

    // Coverage
    enableCoverage(enable?: boolean): void
    coverage(contract: Contract): Coverage | undefined
    coverageForCell(code: Cell, address?: Address): Coverage | undefined

    // Debugging
    getDebuggerExecutor(): Promise<Executor>
    get debug(): boolean
    set debug(value: boolean)

    // Configuration methods
    setVerbosityForAddress(address: Address, verbosity: Partial<LogsVerbosity> | Verbosity | undefined): Promise<void>
    setConfig(config: BlockchainConfig): void
    randomize(): Promise<Buffer>

    // Configuration properties
    get now(): number | undefined
    set now(now: number | undefined)
    get lt(): bigint
    get config(): Cell
    get configBase64(): string
    get verbosity(): LogsVerbosity
    set verbosity(value: LogsVerbosity)
    get libs(): Cell | undefined
    set libs(value: Cell | undefined)
    get random(): Buffer | undefined
    set random(value: Buffer | undefined)
    get recordStorage(): boolean
    set recordStorage(v: boolean)
    get autoDeployLibraries(): boolean
    set autoDeployLibraries(value: boolean)
    get prevBlocks(): PrevBlocksInfo | undefined
    set prevBlocks(value: PrevBlocksInfo | undefined)
}

Blockchain.create()

static create(opts?: {
    executor?: IExecutor;
    config?: BlockchainConfig;
    storage?: BlockchainStorage;
    meta?: ContractsMeta;
    autoDeployLibs?: boolean;
}): Promise<Blockchain>
Creates a new blockchain instance for testing. Parameters:
  • opts — optional blockchain configuration
    • executor — custom contract executor (default: Executor)
    • config — blockchain configuration (Cell, 'default', or 'slim')
    • storage — contracts storage (default: LocalBlockchainStorage)
    • meta — optional contracts metadata provider
    • autoDeployLibs — automatically collect and deploy libraries
Returns: promise resolving to blockchain instance Usage example:
// Basic blockchain
const blockchain = await Blockchain.create();

// With slim config for faster execution
const blockchain = await Blockchain.create({ config: 'slim' });

// With remote storage
const blockchain = await Blockchain.create({
    storage: new RemoteBlockchainStorage(client)
});

// With auto-deploy libraries
const blockchain = await Blockchain.create({
    autoDeployLibs: true
});

treasury()

treasury(seed: string, params?: TreasuryParams): Promise<SandboxContract<TreasuryContract>>
Creates a treasury wallet contract. This wallet is used as alternative to wallet smart contract. Parameters:
  • seed — initial seed for treasury. If the same seed is used to create a treasury, then these treasuries will be identical
  • params — optional treasury parameters
    • workchain — the workchain ID of the treasury (default: 0)
    • predeploy — if set the treasury will be deployed on the moment of creation
    • balance — initial balance of the treasury (default: 1_000_000 TON if omitted)
    • resetBalanceIfZero — if set and treasury balance is zero on moment of calling method it reset balance to balance
Returns: promise resolving to treasury contract wrapper Usage example:
const deployer = await blockchain.treasury('deployer');
const user = await blockchain.treasury('user', { balance: toNano('100') });

// Same seed creates identical treasury
const wallet1 = await blockchain.treasury('same-seed');
const wallet2 = await blockchain.treasury('same-seed');
// wallet1.address equals wallet2.address

createWallets()

createWallets(n: number, params?: TreasuryParams): Promise<SandboxContract<TreasuryContract>[]>
Bulk variant of treasury() method. Parameters:
  • n — number of wallets to create
  • params — params for treasury creation
Returns: array of opened treasury contracts Usage example:
const [wallet1, wallet2, wallet3] = await blockchain.createWallets(3);

openContract()

openContract<T extends Contract>(contract: T): SandboxContract<T>
Wraps a contract for testing with additional methods and state tracking. Parameters:
  • contract — contract instance to wrap
Returns: SandboxContract wrapper with testing capabilities Usage example:
const myContract = blockchain.openContract(MyContract.createFromConfig(config, code));

provider()

provider(address: Address, init?: StateInit | null): ContractProvider
Creates new ContractProvider for contract address. Parameters:
  • address — address to create contract provider for
  • init — initial state of contract
Returns: ContractProvider instance Usage example:
const contractProvider = blockchain.provider(address, init);

sender()

sender(address: Address): Sender
Creates Sender for address. Note, that this sender pushes internal messages to Blockchain directly. No value is deducted from sender address, all the values are set to defaults. Use for test purposes only. Parameters:
  • address — address to create sender for
Returns: Sender instance Usage example:
const sender = blockchain.sender(address);
await contract.send(sender, ...);

getContract()

getContract(address: Address): Promise<SmartContract>
Retrieves SmartContract from BlockchainStorage. Parameters:
  • address — address of contract to get
Returns: promise resolving to SmartContract instance

setShardAccount()

setShardAccount(address: Address, account: ShardAccount): Promise<void>
Sets the account state directly for a contract address. Parameters:
  • address — contract Address
  • accountShardAccount state to set

getTransactions()

getTransactions(address: Address, opts?: {
    limit?: number;
    lt?: string | bigint;
    hash?: string | Buffer;
}): Promise<BlockchainTransaction[]>
Retrieves transactions for the specified address. Transactions are ordered from newest to oldest. Parameters:
  • address — the Address to retrieve transactions for
  • opts — options to fetch transactions
    • lt — logical time of the transaction to start from (must be used with hash)
    • hash — hash of the transaction to start from (must be used with lt)
    • limit — maximum number of transactions to return
Returns: promise resolving to array of transactions involving the given address Usage example:
const transactions = await blockchain.getTransactions(Address.parse('...'), {
    lt: '1234567890',
    hash: 'abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890',
    limit: 10
});

sendMessage()

sendMessage(message: Message | Cell, params?: MessageParams): Promise<SendMessageResult>
Emulates the result of sending a message to this Blockchain. Emulates the whole chain of transactions before returning the result. Each transaction increases lt by 1000000. Parameters:
  • message — message to send (Message object or Cell for external messages)
  • params — optional MessageParams
    • now — override blockchain time for this message
    • randomSeed — random seed for deterministic execution
    • ignoreChksig — whether CHKSIG instructions are set to always succeed. Default: false
Returns: promise resolving to SendMessageResult containing transactions, events, and externals Usage example:
const result = await blockchain.sendMessage(internal({
    from: sender.address,
    to: contract.address,
    value: toNano('1'),
    body: beginCell().storeUint(0, 32).endCell(),
}));

// Check transactions
expect(result.transactions).toHaveTransaction({
    from: sender.address,
    to: contract.address,
    success: true
});

sendMessageIter()

sendMessageIter(message: Message | Cell, params?: SendMessageIterParams): Promise<AsyncIterator<BlockchainTransaction> & AsyncIterable<BlockchainTransaction>>
Starts emulating the result of sending a message to this Blockchain. Each iterator call emulates one transaction, so the whole chain is not emulated immediately, unlike in sendMessage. Parameters:
  • message — message to send (Message or Cell)
  • params — optional parameters
    • allowParallel — when true, allows many consequential executions of this method (default: false)
    • other MessageParams (now, randomSeed, ignoreChksig)
Returns: promise resolving to async iterator of BlockchainTransaction Usage example:
const message = internal({
    from: sender.address,
    to: address,
    value: toNano('1'),
    body: beginCell().storeUint(0, 32).endCell(),
});

for await (const tx of await blockchain.sendMessageIter(message, { randomSeed: crypto.randomBytes(32) })) {
    // process transaction
    console.log(tx);
}

runGetMethod()

runGetMethod(address: Address, method: number | string, stack?: TupleItem[], params?: GetMethodParams): Promise<GetMethodResult>
Runs get method on contract. Parameters:
  • address — contract Address
  • method — method ID (number) or method name (string) to run
  • stack — method parameters as TupleItem array
  • params — optional GetMethodParams
    • now — override blockchain time for this call
    • randomSeed — random seed for deterministic execution
    • gasLimit — overrides TVM emulator gas_limit, defaults to 10_000_000
Returns: promise resolving to GetMethodResult with stackReader and other execution details Usage example:
const { stackReader } = await blockchain.runGetMethod(address, 'get_now', [], {
    now: 2,
});
const now = stackReader.readNumber();

// With method ID
const result = await blockchain.runGetMethod(address, 123, []);

runTickTock()

runTickTock(on: Address | Address[], which: TickOrTock, params?: MessageParams): Promise<SendMessageResult>
Runs tick or tock transaction. Parameters:
  • onAddress or Address array to run tick-tock
  • which — type of transaction ('tick' or 'tock')
  • paramsMessageParams (now, randomSeed, ignoreChksig)
Returns: promise resolving to SendMessageResult Usage example:
let res = await blockchain.runTickTock(address, 'tock');

snapshot()

snapshot(): BlockchainSnapshot
Saves snapshot of current blockchain. Returns: BlockchainSnapshot object Usage example:
const snapshot = blockchain.snapshot();
// some operations
await blockchain.loadFrom(snapshot); // restores blockchain state

loadFrom()

loadFrom(snapshot: BlockchainSnapshot): Promise<void>
Restores blockchain state from snapshot. Parameters: Usage example:
const snapshot = blockchain.snapshot();
// ... perform operations
await blockchain.loadFrom(snapshot);

enableCoverage()

enableCoverage(enable?: boolean): void
Enable coverage collection. Parameters:
  • enable — if false, disable coverage collection (default: true)
Usage example:
blockchain.enableCoverage();
// ... execute contract methods
const coverage = blockchain.coverage(contract);

coverage()

coverage(contract: Contract): Coverage | undefined
Returns coverage analysis for the specified contract. Coverage is collected at the TVM assembly instruction level from all executed transactions and get method calls. Parameters:
  • contract — contract to analyze coverage for
Returns: Coverage object with detailed coverage data or undefined Throws: Error if the contract has no code or if verbose VM logs are not enabled Usage example:
blockchain.enableCoverage();
await contract.send(sender, { value: toNano('1') }, 'increment');

const coverage = blockchain.coverage(contract);
const summary = coverage?.summary();
console.log(`Coverage: ${summary?.coveragePercentage?.toFixed(2)}%`);

const htmlReport = coverage?.report("html");
await fs.writeFile("coverage.html", htmlReport);

coverageForCell()

coverageForCell(code: Cell, address?: Address): Coverage | undefined
Returns coverage analysis for the specified code cell. This method allows analyzing coverage for code cells directly, with optional address filtering. Parameters:
  • code — Cell containing contract code to analyze
  • address — optional contract address to filter transactions by
Returns: Coverage object with detailed coverage data Usage example:
blockchain.enableCoverage();
const coverage = blockchain.coverageForCell(codeCell, contractAddress);
const allCoverage = blockchain.coverageForCell(codeCell); // Without address filtering

getDebuggerExecutor()

getDebuggerExecutor(): Promise<Executor>
Gets the debugger executor instance for debugging purposes. Returns: promise resolving to Executor instance for debugging Usage example:
const debugExecutor = await blockchain.getDebuggerExecutor();
// Use debugExecutor for debugging operations

debug

get debug(): boolean
set debug(value: boolean)
Gets or sets debug mode for the blockchain.

setVerbosityForAddress()

setVerbosityForAddress(address: Address, verbosity: Partial<LogsVerbosity> | Verbosity | undefined): Promise<void>
Updates logs verbosity level for address. Parameters:
  • address — contract Address
  • verbosityLogsVerbosity configuration or undefined to reset
Usage example:
await blockchain.setVerbosityForAddress(contract.address, {
    blockchainLogs: true,
    vmLogs: 'vm_logs_full'
});

setConfig()

setConfig(config: BlockchainConfig): void
Updates blockchain config. Parameters:
  • config — custom config in Cell format, or predefined 'default' | 'slim'
Usage example:
blockchain.setConfig('slim'); // Use slim config for faster execution
blockchain.setConfig(customConfigCell); // Use custom config

randomize()

randomize(): Promise<Buffer>
Generates and sets a new random seed using secure random bytes. Returns: promise resolving to the generated random seed Buffer Usage example:
const newSeed = await blockchain.randomize();

now

get now(): number | undefined
set now(now: number | undefined)
Gets or sets the current time in the blockchain (UNIX timestamp). Usage example:
// Get current time
const currentTime = blockchain.now;

// Set blockchain time
blockchain.now = Math.floor(Date.now() / 1000);

// Clear time (use system time)
blockchain.now = undefined;

lt

get lt(): bigint
Gets the current logical time in the blockchain. Returns: current logical time as bigint

config

get config(): Cell
Gets the configuration used in the blockchain. Returns: configuration as Cell

configBase64

get configBase64(): string
Gets the configuration used in the blockchain in base64 format. Returns: configuration as base64 string

verbosity

get verbosity(): LogsVerbosity
set verbosity(value: LogsVerbosity)
Gets or sets the logs verbosity level. Usage example:
// Get current verbosity
const currentVerbosity = blockchain.verbosity;

// Set verbosity
blockchain.verbosity = {
    print: true,
    blockchainLogs: true,
    vmLogs: 'vm_logs_full',
    debugLogs: true
};

libs

get libs(): Cell | undefined
set libs(value: Cell | undefined)
Gets or sets the global blockchain libraries. Usage example:
// Get current libs
const currentLibs = blockchain.libs;

// Set libraries
const libsDict = Dictionary.empty(Dictionary.Keys.Buffer(32), Dictionary.Values.Cell());
libsDict.set(libCell.hash(), libCell);
blockchain.libs = beginCell().storeDictDirect(libsDict).endCell();

random

get random(): Buffer | undefined
set random(value: Buffer | undefined)
Gets or sets the random seed. Usage example:
// Get current random seed
const currentSeed = blockchain.random;

// Set random seed
blockchain.random = crypto.randomBytes(32);

recordStorage

get recordStorage(): boolean
set recordStorage(v: boolean)
If set to true, BlockchainTransaction will have oldStorage and newStorage fields. Note that enabling this flag will disable a certain optimization, which will slow down contract emulation.

autoDeployLibraries

get autoDeployLibraries(): boolean
set autoDeployLibraries(value: boolean)
Gets or sets whether libraries should be automatically deployed.

prevBlocks

get prevBlocks(): PrevBlocksInfo | undefined
set prevBlocks(value: PrevBlocksInfo | undefined)
Gets or sets the PrevBlocksInfo for the blockchain.

Treasury

Test treasury wallet for sending transactions and managing test funds. Treasury is created by blockchain.treasury() and provides a convenient wallet interface for testing.
class TreasuryContract implements Contract {
    static readonly code: Cell;
    static create(workchain: number, subwalletId: bigint): TreasuryContract;
    readonly address: Address;
    readonly init: StateInit;
    readonly subwalletId: bigint;
    constructor(workchain: number, subwalletId: bigint);
    sendMessages(provider: ContractProvider, messages: MessageRelaxed[], sendMode?: SendMode): Promise<void>;
    send(provider: ContractProvider, args: SenderArguments): Promise<void>;
    getSender(provider: ContractProvider): Treasury;
    getBalance(provider: ContractProvider): Promise<bigint>;
    createTransfer(args: {
        messages: MessageRelaxed[];
        sendMode?: SendMode;
    }): Cell;
}

type Treasury = SandboxContract<TreasuryContract>

code

static readonly code: Cell
Static property containing the compiled treasury contract code. Returns: Cell with treasury contract bytecode

create()

static create(workchain: number, subwalletId: bigint): TreasuryContract
Creates a new treasury contract instance. Parameters:
  • workchain — workchain ID (typically 0)
  • subwalletId — unique subwallet identifier
Returns: new TreasuryContract instance

address

readonly address: Address
The address of the treasury contract. Returns: Address of the treasury

init

readonly init: StateInit
The initial state of the treasury contract. Returns: StateInit for contract deployment

subwalletId

readonly subwalletId: bigint
Unique subwallet identifier generated from the treasury seed using SHA-256. Returns: bigint subwallet ID

sendMessages()

sendMessages(provider: ContractProvider, messages: MessageRelaxed[], sendMode?: SendMode): Promise<void>
Sends multiple messages via the treasury contract. Parameters:
  • providerContractProvider
  • messages — array of MessageRelaxed to send
  • sendMode — optional SendMode (default: pay gas fees separately)

send()

send(provider: ContractProvider, args: SenderArguments): Promise<void>
Sends a single message via the treasury contract. Parameters:
  • providerContractProvider
  • argsSenderArguments including value, body, and send mode

getSender()

getSender(): Sender
Returns a sender interface for this treasury that automatically handles sending transactions. Returns: Sender object for transaction signing Usage example:
const deployer = await blockchain.treasury('deployer');
const sender = deployer.getSender();

// Sender automatically handles seqno and signing
await contract.sendDeploy(sender, toNano('0.05'));

getBalance()

getBalance(provider: ContractProvider): Promise<bigint>
Returns the current TON balance of the treasury. Parameters:
  • providerContractProvider
Returns: promise resolving to balance in nanoTON Usage example:
const treasury = await blockchain.treasury('user');
const balance = await treasury.getBalance();
console.log(`Treasury balance: ${balance} nanoTON`);

createTransfer()

createTransfer(args: {
    messages: MessageRelaxed[];
    sendMode?: SendMode;
}): Cell
Creates a transfer message cell for sending multiple messages via the treasury. Parameters:
  • args — transfer arguments
    • messages — array of MessageRelaxed to include in transfer
    • sendMode — optional SendMode (default: pay gas fees separately)
Returns: Cell containing the transfer message body

Treasury usage

Treasury contracts are pre-funded wallets that work like regular wallet contracts: Usage example:
// Create treasury with default 1M TON balance
const treasury = await blockchain.treasury('user');

// Create treasury with custom balance
const richTreasury = await blockchain.treasury('rich', { 
    balance: toNano(10_000_000n)
});

// Use treasury sender for transactions
await contract.sendMessage(treasury.getSender(), toNano('1'), messageBody);

// Treasury handles all operations automatically

RemoteBlockchainStorage

Storage implementation that fetches contract states from a real TON network.
class RemoteBlockchainStorage implements BlockchainStorage {
    constructor(client: TonClient4Wrapper, blockSeqno?: number)
}
Parameters:
  • client — wrapped TON client for network access
  • blockSeqno — optional block number to fetch state from
Usage example:
import { TonClient4 } from '@ton/ton';
import { RemoteBlockchainStorage, wrapTonClient4ForRemote } from '@ton/sandbox';

const blockchain = await Blockchain.create({
    storage: new RemoteBlockchainStorage(
        wrapTonClient4ForRemote(
            new TonClient4({
                endpoint: 'https://mainnet-v4.tonhubapi.com'
            })
        )
    )
});

Type Definitions

SandboxContract

Enhanced contract wrapper that transforms contract methods for sandbox testing. SandboxContract automatically wraps get methods and send methods to work with the sandbox environment.
export type SandboxContract<F> = {
    [P in keyof F]: P extends `${'get' | 'is'}${string}`
        ? F[P] extends (x: infer CP, ...args: infer P) => infer R
            ? ExtendsContractProvider<CP> extends true
                ? (...args: P) => R
                : never
            : never
        : P extends `send${string}`
            ? F[P] extends (x: infer CP, ...args: infer P) => infer R
                ? ExtendsContractProvider<CP> extends true
                    ? (...args: P) => Promise<SendMessageResult & {
                        result: R extends Promise<infer PR> ? PR : R;
                    }>
                    : never
                : never
            : F[P];
};
Key transformations:
  • Get methods (get*) — Remove the ContractProvider parameter, return the same result
  • Send methods (send*) — Remove ContractProvider parameter, return Promise<SendMessageResult & { result: R }>
  • Other properties — Remain unchanged
Usage example:
// Open a contract in sandbox
const myContract = blockchain.openContract(MyContract.createFromConfig(config, code));

// Deploy the contract - returns SendMessageResult
const deployResult = await myContract.sendDeploy(deployer.getSender(), toNano('0.05'));
expect(deployResult.transactions).toHaveTransaction({
    from: deployer.address,
    to: myContract.address,
    success: true
});

// Send methods return SendMessageResult with transaction info
const incrementResult = await myContract.sendIncrement(user.getSender(), toNano('0.1'));
expect(incrementResult.transactions).toHaveTransaction({
    from: user.address,
    to: myContract.address,
    success: true
});

// Get methods work the same as production
const counter = await myContract.getCounter();
expect(counter).toBe(1n);

SendMessageResult

Result of sending a message to the blockchain emulator.
export type SendMessageResult = {
    transactions: BlockchainTransaction[];
    events: Event[];
    externals: ExternalOut[];
};
Properties:
  • transactions — array of BlockchainTransaction objects that resulted from the message
  • events — array of Event objects emitted during execution
  • externals — array of ExternalOut messages generated during execution

BlockchainTransaction

Enhanced transaction type with additional sandbox-specific properties.
export type BlockchainTransaction = SmartContractTransaction & {
    events: Event[];
    parent?: BlockchainTransaction;
    children: BlockchainTransaction[];
    externals: ExternalOut[];
    mode?: number;
};
Properties:
  • eventsEvent objects emitted during transaction execution
  • parent — parent BlockchainTransaction that triggered this one
  • children — child BlockchainTransaction objects triggered by this transaction
  • externalsExternalOut messages generated during execution
  • mode — transaction execution mode

MessageParams

Optional parameters for message sending operations.
export type MessageParams = Partial<{
    now: number;
    randomSeed: Buffer;
    ignoreChksig: boolean;
}>;
Properties:
  • now — override blockchain time for this message (UNIX timestamp)
  • randomSeed — random seed for deterministic execution
  • ignoreChksig — whether CHKSIG instructions are set to always succeed

GetMethodParams

Optional parameters for get method execution.
export type GetMethodParams = Partial<{
    now: number;
    randomSeed: Buffer;
    gasLimit: bigint;
}>;
Properties:
  • now — override blockchain time for this call (UNIX timestamp)
  • randomSeed — random seed for deterministic execution
  • gasLimit — override TVM emulator gas limit (default: 10,000,000)

GetMethodResult

Result of executing a get method on a contract.
export type GetMethodResult = {
    stack: TupleItem[];
    stackReader: TupleReader;
    exitCode: number;
    gasUsed: bigint;
    blockchainLogs: string;
    vmLogs: string;
    debugLogs: string;
};
Properties:
  • stack — raw TupleItem array returned by the method
  • stackReader — convenient TupleReader for parsing stack items
  • exitCode — TVM exit code (0 for success, see ExitCodes)
  • gasUsed — amount of gas consumed during execution
  • blockchainLogs — blockchain-level execution logs
  • vmLogs — TVM execution logs
  • debugLogs — debug-level execution logs

Verbosity

Verbosity levels for TVM execution logging.
export type Verbosity = 'none' | 'vm_logs' | 'vm_logs_location' | 'vm_logs_gas' | 'vm_logs_full' | 'vm_logs_verbose';
Values:
  • 'none' — no VM logs
  • 'vm_logs' — basic VM execution logs
  • 'vm_logs_location' — VM logs with code location information
  • 'vm_logs_gas' — VM logs with gas consumption details
  • 'vm_logs_full' — comprehensive VM logs
  • 'vm_logs_verbose' — maximum verbosity VM logs

LogsVerbosity

Configuration for different types of logging output.
export type LogsVerbosity = {
    print: boolean;
    blockchainLogs: boolean;
    vmLogs: Verbosity;
    debugLogs: boolean;
};
Properties:
  • print — enable console output
  • blockchainLogs — enable blockchain-level logs
  • vmLogs — TVM execution Verbosity level
  • debugLogs — enable debug-level logs

SmartContractTransaction

Enhanced transaction type with execution logs and storage information.
export type SmartContractTransaction = Transaction & {
    blockchainLogs: string;
    vmLogs: string;
    debugLogs: string;
    oldStorage?: Cell;
    newStorage?: Cell;
    outActions?: OutAction[];
};
Properties:
  • blockchainLogs — blockchain execution logs
  • vmLogs — TVM execution logs
  • debugLogs — debug execution logs
  • oldStorage — contract storage before transaction (if recordStorage enabled)
  • newStorage — contract storage after transaction (if recordStorage enabled)
  • outActions — output actions generated during execution

BlockchainSnapshot

Snapshot of blockchain state for persistence and restoration.
export type BlockchainSnapshot = {
    contracts: SmartContractSnapshot[];
    networkConfig: string;
    lt: bigint;
    time?: number;
    verbosity: LogsVerbosity;
    libs?: Cell;
    nextCreateWalletIndex: number;
    prevBlocksInfo?: PrevBlocksInfo;
    randomSeed?: Buffer;
    autoDeployLibs: boolean;
    transactions: BlockchainTransaction[];
};
Properties:
  • contracts — snapshots of all contract states
  • networkConfig — blockchain configuration
  • lt — current logical time
  • time — current blockchain time
  • verbosity — logging configuration
  • libs — shared libraries
  • nextCreateWalletIndex — next treasury wallet index
  • prevBlocksInfo — previous blocks information
  • randomSeed — random seed for execution
  • autoDeployLibs — auto-deploy libraries flag
  • transactions — transaction history

GetMethodResultSuccess

Successful get method execution result from remote API.
export type GetMethodResultSuccess = {
    success: true;
    stack: string;
    gas_used: string;
    vm_exit_code: number;
    vm_log: string;
    missing_library: string | null;
};
Properties:
  • success — always true for successful results
  • stack — serialized result stack
  • gas_used — gas consumption as string
  • vm_exit_code — TVM exit code
  • vm_log — TVM execution log
  • missing_library — missing library hash if any

GetMethodResultError

Failed get method execution result from remote API.
export type GetMethodResultError = {
    success: false;
    error: string;
};
Properties:
  • success — always false for error results
  • error — error description

Event Types

Blockchain events emitted during transaction execution.
export type EventAccountCreated = {
    type: 'account_created';
    account: Address;
};

export type EventAccountDestroyed = {
    type: 'account_destroyed';
    account: Address;
};

export type EventMessageSent = {
    type: 'message_sent';
    from: Address;
    to: Address;
    value: bigint;
    body: Cell;
    bounced: boolean;
};

export type Event = EventAccountCreated | EventAccountDestroyed | EventMessageSent;
Event Types:
  • EventAccountCreated — account was created during execution
  • EventAccountDestroyed — account was destroyed during execution
  • EventMessageSent — message was sent during execution

BlockId

Identifier for a blockchain block.
export type BlockId = {
    workchain: number;
    shard: bigint;
    seqno: number;
    rootHash: Buffer;
    fileHash: Buffer;
};
Properties:
  • workchain — workchain number
  • shard — shard identifier
  • seqno — sequence number
  • rootHash — block root hash
  • fileHash — block file hash

PrevBlocksInfo

Information about previous blocks in the blockchain.
export type PrevBlocksInfo = {
    lastMcBlocks: BlockId[];
    prevKeyBlock: BlockId;
    lastMcBlocks100?: BlockId[];
};
Properties:
  • lastMcBlocks — last masterchain blocks
  • prevKeyBlock — previous key block
  • lastMcBlocks100 — last 100 masterchain blocks (optional)

SerializableSnapshot

JSON-serializable format for blockchain snapshots.
export type SerializableSnapshot = {
    contracts: {
        address: string;
        account: string;
        lastTxTime: number;
        verbosity?: Partial<LogsVerbosity>;
    }[];
    networkConfig: string;
    lt: string;
    time?: number;
    verbosity: LogsVerbosity;
    libs?: string;
    nextCreateWalletIndex: number;
    prevBlocksInfo?: {
        lastMcBlocks: SerializableBlockId[];
        prevKeyBlock: SerializableBlockId;
        lastMcBlocks100?: SerializableBlockId[];
    };
    randomSeed?: string;
    autoDeployLibs: boolean;
    transactions: {
        transaction: string;
        blockchainLogs: string;
        vmLogs: string;
        debugLogs: string;
        oldStorage?: string;
        newStorage?: string;
        outActions?: string;
        externals: string[];
        mode?: number;
        parentHash?: string;
        childrenHashes: string[];
    }[];
};

ExtraCurrency

Type for extra currencies in transactions.
export type ExtraCurrency = {
    [key: number]: bigint;
};
Properties:
  • [key: number] — currency ID mapped to amount in basic units

Utility functions

loadConfig()

Loads and parses blockchain configuration from Cell or base64 string.
export function loadConfig(configCellOrBase64: string | Cell): BlockchainConfig;
Parameters:
  • configCellOrBase64 — configuration as Cell or base64 string
Returns: parsed BlockchainConfig object

updateConfig()

Updates blockchain configuration with new parameters.
export function updateConfig(config: Cell, ...params: ConfigParam[]): Cell;
Parameters:
  • config — existing configuration Cell
  • ...paramsConfigParam array to update
Returns: updated configuration Cell

prettyLogTransaction()

Creates a formatted log string for a transaction.
export function prettyLogTransaction(tx: Transaction, mapFunc?: AddressMapFunc): string;
Parameters:
  • txTransaction to create log string for
  • mapFunc — optional AddressMapFunc to map addresses to human-readable strings
Returns: formatted transaction log string

prettyLogTransactions()

Logs multiple transactions to console using formatted output.
export function prettyLogTransactions(txs: Transaction[], mapFunc?: AddressMapFunc): void;
Parameters:
  • txsTransaction array to log
  • mapFunc — optional AddressMapFunc to map addresses to human-readable format
Example Output:
null  ➡️  EQBGhqLAZseEqRXz4ByFPTGV7SVMlI4hrbs-Sps_Xzx01x8G
      ➡️  0.05 💎 EQC2VluVfpj2FoHNMAiDMpcMzwvjLZxxTG8ecq477RE3NvVt

internal() (Utility Function)

Creates an internal message from parameters. This is a utility function used internally and in message builders.
export function internal(params: {
    from: Address;
    to: Address;
    value: bigint;
    body?: Cell;
    stateInit?: StateInit;
    bounce?: boolean;
    bounced?: boolean;
    ihrDisabled?: boolean;
    ihrFee?: bigint;
    forwardFee?: bigint;
    createdAt?: number;
    createdLt?: bigint;
    ec?: Dictionary<number, bigint> | [number, bigint][] | ExtraCurrency;
}): Message;
Parameters:
  • from — sender Address
  • to — recipient Address
  • value — message value in nanoTON
  • body — optional message body Cell
  • stateInit — optional StateInit for contract deployment
  • bounce — bounce flag (default: true for bounceable messages)
  • bounced — indicates if this is a bounced message (default: false)
  • ihrDisabled — disable Instant Hypercube Routing (default: true)
  • ihrFee — IHR fee amount
  • forwardFee — forward fee amount
  • createdAt — message creation timestamp
  • createdLt — logical time when message was created
  • ec — extra currencies Dictionary or ExtraCurrency
Returns: Message object for blockchain processing Usage examples:
// Simple internal message
const message = internal({
    from: sender.address,
    to: contract.address,
    value: toNano('1'),
    body: beginCell().storeUint(1, 32).endCell()
});

// Message with state init for deployment
const deployMessage = internal({
    from: deployer.address,
    to: contract.address,
    value: toNano('0.05'),
    stateInit: { code, data },
    body: beginCell().endCell()
});

// Non-bounceable message
const nonBounceMessage = internal({
    from: sender.address,
    to: wallet.address,
    value: toNano('0.1'),
    bounce: false
});

printTransactionFees()

Prints transaction fees in a formatted table to console.
export function printTransactionFees(transactions: Transaction[], mapFunc?: OpMapFunc): void;
Parameters:
  • transactions — list of Transaction to analyze and print fees for
  • mapFunc — optional OpMapFunc to map operation codes to human-readable format
Returns: void (outputs formatted table to console)

snapshotToSerializable()

export function snapshotToSerializable(snapshot: BlockchainSnapshot): SerializableSnapshot;
Parameters: Returns: SerializableSnapshot — JSON-serializable snapshot object

snapshotFromSerializable()

export function snapshotFromSerializable(serialized: SerializableSnapshot): BlockchainSnapshot;
Parameters: Returns: BlockchainSnapshot — restored blockchain snapshot Usage example:
import { snapshotToSerializable, snapshotFromSerializable } from '@ton/sandbox';
import fs from 'fs';

// Save snapshot to file
const snapshot = blockchain.snapshot();
const serializable = snapshotToSerializable(snapshot);
fs.writeFileSync('snapshot.json', JSON.stringify(serializable));

// Load snapshot from file
const loaded = JSON.parse(fs.readFileSync('snapshot.json', 'utf8'));
const restored = snapshotFromSerializable(loaded);
await blockchain.loadFrom(restored);

setGlobalVersion()

Sets global version in blockchain configuration.
export function setGlobalVersion(config: Cell, version: number, capabilites?: bigint): Cell;
Parameters:
  • config — blockchain configuration Cell
  • version — global version number to set
  • capabilites — optional capabilities flags
Returns: Cell — updated configuration Cell

fetchConfig()

Fetches blockchain configuration from TON network.
export async function fetchConfig(network: 'mainnet' | 'testnet', maxRetries?: number): Promise<Cell>;
Parameters:
  • network — network to fetch config from ('mainnet' or 'testnet')
  • maxRetries — maximum number of retry attempts (default: 5)
Returns: Promise<Cell> — blockchain configuration Cell

registerCompiledContract()

Registers compiled contract for debugging support.
export function registerCompiledContract(code: Cell, debugInfo: FuncDebugInfo, marks: Cell): Cell;
Parameters:
  • code — compiled contract code Cell
  • debugInfoFuncDebugInfo debug information
  • marks — debug marks Cell
Returns: Cell — the same code Cell (for chaining)

Test utilities and matchers

Comprehensive testing utilities for TON blockchain transactions and state. Import from @ton/test-utils to use these utilities and matchers.
import '@ton/test-utils';

FlatTransaction

Flattened transaction structure for easier testing and comparison.
export type FlatTransaction = {
    from?: Address;
    to?: Address;
    on?: Address;
    value?: bigint;
    ec?: [number, bigint][];
    body?: Cell;
    inMessageBounced?: boolean;
    inMessageBounceable?: boolean;
    op?: number;
    initData?: Cell;
    initCode?: Cell;
    deploy: boolean;
    lt: bigint;
    now: number;
    outMessagesCount: number;
    oldStatus: AccountStatus;
    endStatus: AccountStatus;
    totalFees?: bigint;
    aborted?: boolean;
    destroyed?: boolean;
    exitCode?: number;
    actionResultCode?: number;
    success?: boolean;
    mode?: number;
};
Properties:
  • from — sender address (if internal message)
  • to — recipient address
  • on — contract address being called
  • value — message value in nanoTON
  • ec — extra currencies as [currencyId, amount] pairs
  • body — message body cell
  • inMessageBounced — whether incoming message was bounced
  • inMessageBounceable — whether incoming message is bounceable
  • op — operation code extracted from message body
  • initData — contract initialization data
  • initCode — contract initialization code
  • deploy — whether this transaction deployed a contract
  • lt — logical time of transaction
  • now — timestamp of transaction
  • outMessagesCount — number of outbound messages
  • oldStatus — account status before transaction
  • endStatus — account status after transaction
  • totalFees — total fees paid for transaction
  • aborted — whether transaction was aborted
  • destroyed — whether account was destroyed
  • exitCode — TVM exit code
  • actionResultCode — action phase result code
  • success — whether transaction was successful
  • mode — transaction execution mode

FlatTransactionComparable

Pattern for matching transactions with optional fields and functions.
type WithFunctions<T> = {
    [K in keyof T]: T[K] | ((x: T[K]) => boolean);
};

export type FlatTransactionComparable = Partial<WithFunctions<FlatTransaction>>;
A partial FlatTransaction where each field can be either:
  • The exact value to match
  • A function that returns true if the value matches the criteria
Usage examples:
// Exact value matching
const exactMatch: FlatTransactionComparable = {
    from: deployer.address,
    to: contract.address,
    success: true,
    deploy: true
};

// Function-based matching
const conditionalMatch: FlatTransactionComparable = {
    value: (v) => v !== undefined && v >= toNano('0.1'), // At least 0.1 TON
    exitCode: (code) => code === 0 || code === undefined, // Success or no code
    totalFees: (fees) => fees !== undefined && fees < toNano('0.01') // Less than 0.01 TON fees
};

// Mixed matching
const mixedMatch: FlatTransactionComparable = {
    from: user.address, // Exact match
    success: true, // Exact match
    value: (v) => v >= toNano('1'), // Function match
    op: 0x12345678 // Exact match
};

PrettyTransaction

Human-readable transaction format for debugging and logging.
export type PrettyTransaction = Omit<FlatTransaction, 'from' | 'to' | 'on' | 'op' | 'failReason'> & {
    failReason?: FailReason;
    from?: string;
    to?: string;
    on?: string;
    op?: string;
};
Properties:
  • failReason — human-readable failure reason (if transaction failed)
  • from — readable sender address or name
  • to — readable recipient address or name
  • on — readable contract address or name
  • op — readable operation name or code

FailReason

Describes why a transaction failed with human-readable information.
export type FailReason = {
    message: string;
};
Properties:
  • message — human-readable failure description

ContractsMeta

Registry for contract metadata to enhance debugging and logging.
export class ContractsMeta {
    get(key: Address): ContractMeta | undefined;
    upsert(key: Address, value: Partial<ContractMeta>): void;
    clear(): void;
    delete(key: Address): void;
}

export type ContractMeta = {
    wrapperName?: string;
    abi?: ContractABI | null;
    treasurySeed?: string;
};
Methods:
  • get() — retrieve metadata for contract address
  • upsert() — add or update metadata for contract address
  • clear() — remove all metadata
  • delete() — remove metadata for specific address
Usage example:
import { contractsMeta } from '@ton/test-utils';

// Add contract metadata for better debugging
contractsMeta.upsert(contract.address, {
    wrapperName: 'MyContract',
    abi: contractAbi,
    treasurySeed: 'deployer'
});

// Pretty print transactions will now show readable names
const pretty = prettifyTransaction(transaction);
console.log(pretty.to); // "MyContract" instead of address

Jest/Chai matchers

Test utils provides custom Jest/Chai matchers for testing TON blockchain transactions and data structures. These matchers are automatically available when you import @ton/test-utils.

toHaveTransaction()

toHaveTransaction(cmp: FlatTransactionComparable): R
Asserts that a transaction array or result contains a transaction matching the specified pattern. Parameters: Usage examples:
// Check deployment transaction
expect(result.transactions).toHaveTransaction({
    from: deployer.address,
    to: contract.address,
    deploy: true,
    success: true
});

// Check specific operation with value
expect(result.transactions).toHaveTransaction({
    from: user.address,
    to: contract.address,
    value: toNano('1'),
    op: 0x12345678,
    success: true
});

// Use functions for complex matching
expect(result.transactions).toHaveTransaction({
    value: (v) => v >= toNano('0.1'),
    exitCode: (code) => code !== 0
});

toEqualCell()

toEqualCell(cell: Cell): R
Asserts that a Cell equals another Cell by comparing their hash and content. Parameters:
  • cell — Cell to compare against
Usage example:
const expectedCell = beginCell().storeUint(123, 32).endCell();
expect(actualCell).toEqualCell(expectedCell);

toEqualAddress()

toEqualAddress(address: Address): R
Asserts that an Address equals another Address. Parameters:
  • address — Address to compare against
Usage example:
expect(contract.address).toEqualAddress(Address.parse('EQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAM9c'));

toEqualSlice()

toEqualSlice(slice: Slice): R
Asserts that a Slice equals another Slice by comparing their underlying Cell data. Parameters:
  • slice — Slice to compare against
Usage example:
const expectedSlice = beginCell().storeUint(123, 32).endCell().beginParse();
expect(actualSlice).toEqualSlice(expectedSlice);

toThrowExitCode()

toThrowExitCode(exitCode: number): Promise<R>
Asserts that a function throws an error with a specific TVM exit code. Parameters:
  • exitCode — expected TVM exit code
Usage examples:
// Test that get method throws specific exit code
await expect(async () => {
    await blockchain.runGetMethod(contract.address, 'fail_method');
}).toThrowExitCode(11);

// Test that send method throws exit code
await expect(async () => {
    await contract.sendInvalidOperation(user.getSender(), toNano('0.1'));
}).toThrowExitCode(134); // Invalid argument

Transaction utilities

Utilities for finding, filtering, and working with transactions in tests.

findTransaction()

export function findTransaction<T extends Transaction>(txs: T | T[], match: FlatTransactionComparable): T | undefined;
Finds the first transaction matching the specified pattern. Parameters: Returns: matching transaction or undefined if not found Usage example:
import { findTransaction } from '@ton/test-utils';

const deployTx = findTransaction(result.transactions, {
    from: deployer.address,
    to: contract.address,
    deploy: true
});

if (deployTx) {
    console.log('Deploy transaction found:', deployTx.lt);
}

findTransactionRequired()

export function findTransactionRequired<T extends Transaction>(txs: T | T[], match: FlatTransactionComparable): T;
Finds the first transaction matching the specified pattern, throwing an error if not found. Parameters: Returns: matching transaction Throws: Error if no matching transaction is found Usage example:
import { findTransactionRequired } from '@ton/test-utils';

const deployTx = findTransactionRequired(result.transactions, {
    from: deployer.address,
    to: contract.address,
    deploy: true
});
// Guaranteed to have a transaction or throw
console.log('Deploy transaction LT:', deployTx.lt);

filterTransactions()

export function filterTransactions<T extends Transaction>(txs: T[], match: FlatTransactionComparable): T[];
Filters transactions array to only include transactions matching the specified pattern. Parameters: Returns: array of matching transactions Usage example:
import { filterTransactions } from '@ton/test-utils';

const successfulTxs = filterTransactions(result.transactions, {
    success: true
});

const userTxs = filterTransactions(result.transactions, {
    from: user.address
});

Async execution utilities

Utilities for working with transaction iterators and step-by-step execution.

executeTill()

export async function executeTill<T extends Transaction>(txs: AsyncIterator<T>, match: FlatTransactionComparable): Promise<T[]>;
Executes transactions from an async iterator until finding a transaction matching the pattern. Parameters: Returns: promise resolving to array of executed transactions up to and including the match Throws: Error if no matching transaction is found Usage example:
import { executeTill } from '@ton/test-utils';

const message = internal({
    from: sender.address,
    to: contract.address,
    value: toNano('1')
});

const txIter = await blockchain.sendMessageIter(message);
const executedTxs = await executeTill(txIter, {
    to: contract.address,
    success: true
});

console.log(`Executed ${executedTxs.length} transactions until success`);

executeFrom()

export async function executeFrom<T extends Transaction>(txs: AsyncIterator<T>): Promise<T[]>;
Executes all remaining transactions from an async iterator. Parameters:
  • txs — async iterator of transactions
Returns: promise resolving to array of all executed transactions Usage example:
import { executeFrom } from '@ton/test-utils';

const message = internal({
    from: sender.address,
    to: contract.address,
    value: toNano('1')
});

const txIter = await blockchain.sendMessageIter(message);
const allTxs = await executeFrom(txIter);

console.log(`Total executed transactions: ${allTxs.length}`);

Formatting and debugging utilities

Utilities for making transactions and debugging information more readable.

prettifyTransaction()

export function prettifyTransaction(transaction: Transaction): PrettyTransaction;
Converts a transaction to a human-readable format for debugging and logging. Parameters:
  • transaction — transaction to prettify
Returns: PrettyTransaction object with readable formatting Usage example:
import { prettifyTransaction } from '@ton/test-utils';

const pretty = prettifyTransaction(transaction);
console.log('Transaction details:', pretty);

contractsMeta

Global registry for contract metadata to enhance debugging and logging.
export const contractsMeta: ContractsMeta;
Usage example:
import { contractsMeta } from '@ton/test-utils';

// Add contract metadata for better debugging
contractsMeta.upsert(contract.address, {
    wrapperName: 'MyContract',
    abi: contractAbi,
    treasurySeed: 'deployer'
});

// Pretty print transactions will now show readable names
const pretty = prettifyTransaction(transaction);
console.log(pretty.to); // "MyContract" instead of address

Testing constants and utilities

ExitCodes

Comprehensive collection of TVM exit codes for error testing and analysis.
export const ExitCodes: {
    // Numeric codes
    Success: 0;
    ReservedSuccess: 1;
    StackUnderflow: 2;
    StackOverflow: 3;
    IntegerOverflow: 4;
    RangeCheckError: 5;
    InvalidOpcode: 6;
    TypeCheckError: 7;
    CellOverflow: 8;
    CellUnderflow: 9;
    DictionaryError: 10;
    UnknownError: 11;
    FatalError: 12;
    OutOfGas: 13;
    OutOfGasNegative: -14;
    VirtualizationError: 14;
    InvalidActionList: 32;
    ActionListTooLong: 33;
    InvalidOrUnsupportedAction: 34;
    InvalidOutboundSrcAddress: 35;
    InvalidOutboundDestAddress: 36;
    NotEnoughToncoin: 37;
    NotEnoughExtraCurrencies: 38;
    OutboundMessageTooLarge: 39;
    CannotProcessMessage: 40;
    NullLibraryReference: 41;
    LibraryChangeError: 42;
    LibraryLimitsExceeded: 43;
    AccountStateTooLarge: 50;
    NullReference: 128;
    InvalidSerializationPrefix: 129;
    InvalidIncomingMessage: 130;
    ConstraintsError: 131;
    AccessDenied: 132;
    ContractStopped: 133;
    InvalidArgument: 134;
    ContractCodeNotFound: 135;
    InvalidStandardAddress: 136;
    NotBasechainAddress: 138;
    UnrecognizedMessageOpcode: 65535;
    
    // String mappings (reverse lookup)
    "0": "Success";
    "1": "ReservedSuccess";
    // ... etc
};

randomAddress()

export function randomAddress(workchain?: number): Address;
Generates a random TON address for testing purposes. Parameters:
  • workchain — workchain ID (default: 0)
Returns: randomly generated Address Usage example:
import { randomAddress } from '@ton/test-utils';

const testAddress = randomAddress();
const masterchainAddress = randomAddress(-1);

// Use in tests
expect(contract.getOwner()).toEqualAddress(testAddress);

Network configuration

Custom network configuration

import { loadConfig, updateConfig } from '@ton/sandbox';

const oldConfig = loadConfig(blockchain.config);
const updatedConfig = updateConfig(oldConfig, {
    ...oldConfig[8],
    anon0: {
        ...oldConfig[8].anon0,
        version: 99,
    },
});
blockchain.setConfig(updatedConfig);
I