Tolk wrappers
Learn how to generate Tolk wrappers and use them in tests and scripts
acton wrapper generates a typed Tolk wrapper from a contract's compiler ABI. The wrapper exposes methods to create, deploy, send messages to, and call get methods on the contract — the same API works in both tests and scripts.
Generate a Tolk wrapper
Run acton wrapper with the contract name from Acton.toml:
acton wrapper CounterThis writes a Counter.gen.tolk wrapper to wrappers/ by default. The acton wrapper does not require a prior acton build run.
Generate wrappers for every contract in Acton.toml at once:
acton wrapper --allWhen generating all wrappers, use --output-dir to choose a directory. --output is only for a single contract because it names one file.
Precompiled .boc contracts can also have wrappers when their contract section
points types to a Tolk interface file:
[contracts.Precompiled]
src = "contracts/Precompiled.boc"
types = "contracts/Precompiled.types.tolk"Acton reads deployable code from the BoC and reads the ABI from
Precompiled.types.tolk. A BoC contract without types is skipped by
acton wrapper --all, and acton wrapper Precompiled reports that types is
required. See Precompiled BoC contracts for
the build and wrapper workflow.
Pass --test to also emit a runnable test stub alongside the wrapper:
acton wrapper Counter --testThe stub is written to tests/Counter.test.tolk and contains a setupTest() helper with an example test case ready to extend.
Wrapper file structure
The generated file provides:
Counter.fromStorage(storage)— initializes contract state from a storage struct instance and calculates the deployment address.counter.deploy(from, config)— deploys the contract.counter.send{MessageName}(from, ...)— one method per internal incoming message type declared incontract { incomingMessages: ... }.counter.sendAny(from, body, config)— sends a custom internal body cell.counter.sendExternal{MessageName}(...)— one method per external incoming message type declared incontract { incomingExternal: ... }; these methods returnExternalSendResult.counter.sendAnyExternal(body)— sends a custom external-in body when the contract declares external incoming messages.counter.{getMethodName}()— one method per declared get method.
Fine tune wrapper generation with the contract { ... } header in the contract entrypoint file:
storage: ...enables the typedfromStorage()initializer; without it, the initializer falls back to an untyped form.incomingMessages: ...enables typedsend{MessageName}helpers; without it, only the genericsendAny()internal-message helper is generated.incomingExternal: ...enablessendExternal{MessageName}helpers andsendAnyExternal().
Use a wrapper in a Tolk test
Import the wrapper and any types it references, then create and deploy the contract:
import "@wrappers/Counter.gen"
import "@contracts/types"
import "@acton/emulation/testing"
import "@acton/testing/expect"
get fun `test increase`() {
val deployer = testing.treasury("deployer");
val contract = Counter.fromStorage({ id: 0, counter: 0 });
val deployResult = contract.deploy(deployer.address, { value: ton("0.05") });
expect(deployResult).toHaveSuccessfulDeploy({ to: contract.address });
val sendResult = contract.sendIncreaseCounter(deployer.address, 5);
expect(sendResult).toHaveTransaction({ success: true });
expect(contract.currentCounter()).toEqual(5);
}See the testing guides for more.
Use a wrapper in a Tolk script
Replace testing.treasury() with scripts.wallet():
import "@wrappers/Counter.gen"
import "@contracts/types"
// Replaces @acton/emulation/testing:
import "@acton/emulation/scripts"
fun main() {
val deployer = scripts.wallet("deployer");
val contract = Counter.fromStorage({ id: 0, counter: 0 });
val result = contract.deploy(deployer.address, { value: ton("0.05") });
result.waitForFirstTransaction();
println("Deployed to {}", contract.address);
}Run and test locally first, then broadcast to testnet with --net:
acton script scripts/deploy.tolk
acton script scripts/deploy.tolk --net testnetSee the scripting guides for more.
Regenerate after contract changes
Regenerate the wrapper whenever the contract's storage struct, accepted messages, or get-methods change:
acton wrapper CounterGenerate a TypeScript wrapper
Pass --ts to emit a TypeScript wrapper:
acton wrapper Counter --tsThis writes a Counter.gen.ts wrapper to wrappers-ts/ by default.
Node.js, npm, and npx must be available in the PATH.
See the dApps development guide for working with TypeScript wrappers.
Configure wrapper defaults
Set per-project defaults in Acton.toml:
[wrappers.tolk]
output-dir = "wrappers"
generate-test = true
test-output-dir = "tests"
[wrappers.typescript]
output-dir = "wrappers-ts"See the build reference for all available fields.
See also
Last updated on