
Ton Blueprint
- 4 installs
- 4 repo stars
- Updated February 25, 2026
- hairyf/blockchain-master
Use the TON Blueprint dev environment - project layout, build/test/run, NetworkProvider, wrappers, and deploy via TonConnect or mnemonic.
About
Blueprint is a TON development environment to create projects, build Tolk/FunC/Tact contracts, test with Sandbox, and run deploy scripts. A developer uses it to scaffold, test, and deploy TON contracts.
- Fixed layout: contracts, wrappers, compilables, tests, scripts, build
- Sandbox testing and deploy via TonConnect, deeplink, or mnemonic
Ton Blueprint by the numbers
- 4 all-time installs (skills.sh)
- Ranked #347 of 479 Web3 & Blockchain skills by installs in the Skillselion catalog
- Data as of Jul 13, 2026 (Skillselion catalog sync)
npx skills add https://github.com/hairyf/blockchain-master --skill ton-blueprintAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 4 |
|---|---|
| repo stars | ★ 4 |
| Last updated | February 25, 2026 |
| Repository | hairyf/blockchain-master ↗ |
What it does
Use the TON Blueprint dev environment - project layout, build/test/run, NetworkProvider, wrappers, and deploy via TonConnect or mnemonic.
Files
Skill is based on Blueprint (ton-org/blueprint), generated at 2026-02-25.
Blueprint is a development environment for the TON blockchain: create projects with npm create ton@latest, then build (Tolk/FunC/Tact), test (Sandbox), and run scripts (deploy via TonConnect, deeplink, or mnemonic). Projects use a fixed layout: contracts/, wrappers/, compilables/, tests/, scripts/, build/.
Core References
| Topic | Description | Reference |
|---|---|---|
| Project structure | Directory layout, contracts/wrappers/compilables/tests/scripts/build | core-project-structure |
| CLI commands | build, test, run, create, rename, help, pack, snapshot, verify, set, convert | core-commands |
| NetworkProvider | sender, open, waitForDeploy, waitForLastTransaction, api, config | core-network-provider |
| Config | blueprint.config.ts, plugins, network, requestTimeout, recursiveWrappers, manifestUrl | core-config |
| UIProvider | write, prompt, input, choose, setActionPrompt, inputAddress for scripts | core-ui-provider |
| Networks and explorers | Network, Explorer, CustomNetwork, NetworkVersion for run/verify/config | core-networks-explorers |
Features
Scripts and compilation
| Topic | Description | Reference |
|---|---|---|
| Scripts | run(provider, args), deploy pattern, blueprint run | features-scripts |
| Compilation | compile(), CompilerConfig, compilables, build output, hooks | features-compilation |
| Build API | buildOne, buildAll, buildAllTact, artifact output | features-build-api |
| Wrappers | Contract, createFromConfig, createFromAddress, sendDeploy | features-wrappers |
| Plugins | Plugin, PluginRunner, custom CLI commands | features-plugins |
| Verify | Verify deployed contract on verifier.ton.org, flags, compiler version | features-verify |
| Pack | Publish-ready wrapper package, package.ts, dist, npm publish | features-pack |
| Create and rename | Create contract from template, rename across wrappers/scripts/tests | features-create-rename |
Best practices
| Topic | Description | Reference |
|---|---|---|
| Deploy | Deploy flow, TonConnect/deeplink/mnemonic, env vars, verify | best-practices-deploy |
| Testing | Sandbox tests, compile(), coverage, gas report/snapshot | best-practices-testing |
Generation Info
- Source:
sources/ton-blueprint - Git SHA:
3fec080855a271fe6bb6cf6530c63f37fd761c99 - Generated: 2026-02-25
Deploy Practices
Recommended deploy flow
1. Compile: code = await compile('ContractName'). 2. Build contract instance: Contract.createFromConfig(config, code) (or Tact equivalent). 3. Open with provider: provider.open(contract). 4. Send deploy: contract.sendDeploy(provider.sender(), toNano('0.05')) (or contract-specific method). 5. Wait: await provider.waitForDeploy(contract.address). 6. Use opened contract for getters or further messages.
Avoid the deprecated provider.deploy(contract, value, body, waitAttempts).
Wallet / send options
When running scripts, choose how to sign and send:
- TonConnect (
--tonconnect): TON Connect–compatible wallet (e.g. Tonkeeper). Not for custom network. - Deeplink (
--deeplink): Generateton://link or QR for signing. - Mnemonic (
--mnemonic): Use env vars so no interactive wallet.
Mnemonic env vars
For --mnemonic (or choosing “Mnemonic” interactively), set in .env:
- Required:
WALLET_MNEMONIC(space-separated words),WALLET_VERSION(e.g.v4r1,v5r1). - Optional:
WALLET_ID,SUBWALLET_NUMBER(for v5r1),WALLET_VERSIONone of:v1r1,v1r2,v1r3,v2r1,v2r2,v3r1,v3r2,v4r1,v4r2,v5r1.
Example non-interactive: yarn blueprint run deployCounter --testnet --mnemonic.
Custom network and verify
Use blueprint.config.ts network or CLI --custom, --custom-type, --custom-version, --custom-key for custom RPC. For contract verification, custom type must be mainnet or testnet. Example: blueprint verify ... --custom <endpoint> --custom-type mainnet --custom-key <key> --compiler-version 0.4.4-newops.1.
<!-- Source references:
- https://github.com/ton-org/blueprint/blob/main/README.md (Deploying contracts, Using Mnemonic Provider, Custom network, Contract Verification)
-->
Testing
Tests are in tests/*.spec.ts, use @ton/sandbox (in-process blockchain) and contract wrappers. Run with yarn test or yarn blueprint test; optionally yarn test <CONTRACT>.
Test layout
import { Blockchain, SandboxContract, TreasuryContract } from '@ton/sandbox';
import { Cell, toNano } from '@ton/core';
import { MyContract } from '../wrappers/MyContract';
import '@ton/test-utils';
import { compile } from '@ton/blueprint';
describe('MyContract', () => {
let code: Cell;
beforeAll(async () => {
code = await compile('MyContract');
});
let blockchain: Blockchain;
let deployer: SandboxContract<TreasuryContract>;
let contract: SandboxContract<MyContract>;
beforeEach(async () => {
blockchain = await Blockchain.create();
contract = blockchain.openContract(MyContract.createFromConfig({}, code));
deployer = await blockchain.treasury('deployer');
const result = await contract.sendDeploy(deployer.getSender(), toNano('0.05'));
expect(result.transactions).toHaveTransaction({
from: deployer.address,
to: contract.address,
deploy: true,
success: true,
});
});
it('should do something', async () => {
// use contract.get*(), contract.send*(), expect(...)
});
});Patterns
- Use
compile('ContractName')once inbeforeAll. - Create
Blockchainandblockchain.treasury('deployer')inbeforeEach. - Open contract with
blockchain.openContract(Contract.createFromConfig(config, code)). - Assert deploy with
toHaveTransaction({ deploy: true, success: true })from@ton/test-utils. - Use wrapper getters and send methods for behavior tests.
Coverage and gas
- Coverage:
blueprint test --coverage; output incoverage/. - Gas report:
blueprint test --gas-report(or-g) compares to last snapshot. - Snapshot:
blueprint snapshot [--label=<comment>]saves current gas metrics for later comparison.
<!-- Source references:
- https://github.com/ton-org/blueprint/blob/main/README.md (Testing contracts, Benchmark contracts)
- https://github.com/ton-org/sandbox (writing tests, benchmark)
- sources/ton-blueprint/src/templates (spec.ts.template)
-->
CLI Commands
Invoke with npx blueprint <command> or yarn blueprint <command>. Commands can be interactive or accept args/flags.
Command list
| Command | Description | Example |
|---|---|---|
create | Create a new contract from template (Tolk/FunC/Tact, empty or counter) | blueprint create MyContract --type func-empty |
build | Build contract(s) using .compile.ts; Tact output in build/<name>/ | blueprint build Counter or blueprint build --all |
test | Run Jest test suite (Sandbox); --coverage, --gas-report/-g, --ui | blueprint test or blueprint test --gas-report |
run | Run a script from scripts/ (e.g. deploy); needs network and wallet choice | blueprint run deployCounter --testnet --tonconnect |
help | Show help; pass command name for command-specific help | blueprint help run |
set | Set config values (e.g. func for @ton-community/func-js version) | blueprint set func |
verify | Verify deployed contract on verifier.ton.org | blueprint verify [Contract] --mainnet --compiler-version 0.4.4-newops.1 |
convert | Convert legacy bash build script to Blueprint compile wrapper | blueprint convert [path] |
rename | Rename contract (PascalCase) across wrappers, scripts, tests, contracts | blueprint rename OldName NewName |
pack | Build and prepare publish-ready package of wrappers | blueprint pack or blueprint pack --no-warn |
snapshot | Collect gas usage and cell sizes, write snapshot (for test --gas-report) | blueprint snapshot or blueprint snapshot -l "comment" |
Run flags
For blueprint run:
- Network:
--mainnet,--testnet,--tetra, or--custom <endpoint>with optional--custom-type,--custom-version,--custom-key,--custom-domain,--custom-network-id. - Wallet:
--tonconnect,--deeplink,--mnemonic. - Explorer:
--tonscan,--tonviewer,--toncx,--dton(default: tonscan in code, README says tonviewer).
Script args go after flags: blueprint run deployCounter --testnet --tonconnect arg1 arg2.
Verify flags
--mainnet/--testnet— network (custom requires--custom-typemainnet/testnet).--verifier— verifier ID (default: verifier.ton.org).--list-verifiers— list available verifiers.--compiler-version— exact compiler version string (e.g.0.4.4-newops.1); does not change local compiler.--custom,--custom-version,--custom-key,--custom-type— custom API for verify.
Plugin commands
Plugins registered in blueprint.config.ts add extra commands; their help is merged into blueprint help.
<!-- Source references:
- https://github.com/ton-org/blueprint/blob/main/README.md (Features overview, Help and additional commands)
- sources/ton-blueprint/src/cli/cli.ts
- sources/ton-blueprint/src/cli/constants.ts
- sources/ton-blueprint/src/cli/help.ts
-->
Configuration
Create blueprint.config.ts in the project root. Export a named config (not default) of type Config from @ton/blueprint.
import { Config } from '@ton/blueprint';
export const config: Config = {
// optional fields
};Options
| Field | Type | Description |
|---|---|---|
plugins | Plugin[] | Plugins that add runners (e.g. scaffold, misti). |
network | `'mainnet' \ | 'testnet' \ |
domain | number | Used with mnemonic/custom network. |
networkId | number | Used with mnemonic/custom network. |
separateCompilables | boolean | If true, compilables live in compilables/ instead of wrappers/. Default false. |
requestTimeout | number | HTTP timeout in ms (e.g. 10000). |
recursiveWrappers | boolean | Search wrappers/compilables recursively. Default false. |
manifestUrl | string | Override TonConnect manifest URL. |
Custom network
export const config: Config = {
network: {
endpoint: 'https://toncenter.com/api/v2/jsonRPC',
type: 'mainnet',
version: 'v2',
key: 'YOUR_API_KEY',
},
};Same effect as: blueprint run --custom <endpoint> --custom-type mainnet --custom-version v2 --custom-key <key>.
Liteclient
export const config: Config = {
network: {
endpoint: 'https://ton.org/testnet-global.config.json', // mainnet: global.config.json
version: 'liteclient',
type: 'testnet',
},
};Plugins
import { Config } from '@ton/blueprint';
import { ScaffoldPlugin } from 'blueprint-scaffold';
export const config: Config = {
plugins: [new ScaffoldPlugin()],
};Plugins implement Plugin: runners(): PluginRunner[] (name, runner, help).
<!-- Source references:
- https://github.com/ton-org/blueprint/blob/main/README.md (Configuration, Plugins, Custom network, Liteclient)
- sources/ton-blueprint/src/config/Config.ts
-->
NetworkProvider
Scripts and deploy flows receive a NetworkProvider from @ton/blueprint. Use it to send transactions, open contracts, and wait for deployment or transaction confirmation.
Getting a provider in scripts
Scripts export run(provider: NetworkProvider, args?: string[]). The CLI passes the provider when you run blueprint run <SCRIPT>.
import { NetworkProvider } from '@ton/blueprint';
export async function run(provider: NetworkProvider, args: string[]) {
const sender = provider.sender();
const address = /* ... */;
await provider.open(MyContract.createFromAddress(address)).send(sender, { value: toNano('0.05') });
await provider.waitForLastTransaction();
}Key methods
| Method | Use |
|---|---|
provider.network() | `'mainnet' \ |
provider.sender() | SenderWithSendResult for sending messages (deploy, internal messages) |
provider.open(contract) | OpenedContract<T> for getters and send() |
provider.provider(address, init?) | Low-level ContractProvider for an address |
provider.api() | Underlying client (TonClient, TonClient4, ContractAdapter, or LiteClient) |
provider.isContractDeployed(address) | Whether contract is active |
provider.waitForDeploy(address, attempts?, sleepMs?) | Poll until contract is deployed |
provider.waitForLastTransaction(attempts?, sleepMs?) | Wait for last sent message to be applied (uses sender().lastSendResult) |
provider.getContractState(address) | Contract state (balance, etc.) |
provider.getConfig(address?) | Blockchain config from config contract |
provider.ui() | UI for prompts/logging |
provider.explorer() | Explorer type for links |
Deploy pattern
import { toNano } from '@ton/core';
import { compile, NetworkProvider } from '@ton/blueprint';
import { MyContract } from '../wrappers/MyContract';
export async function run(provider: NetworkProvider) {
const code = await compile('MyContract');
const contract = provider.open(MyContract.createFromConfig({ /* config */ }, code));
await contract.sendDeploy(provider.sender(), toNano('0.05'));
await provider.waitForDeploy(contract.address);
// use contract...
}- Prefer the contract’s
sendDeploy(or equivalent) pluswaitForDeploy; avoid the deprecatedprovider.deploy().
<!-- Source references:
- https://github.com/ton-org/blueprint (README, NetworkProvider interface in src/network/NetworkProvider.ts)
-->
Project Structure
Blueprint projects follow a fixed layout. Use this when creating or navigating a TON project created with npm create ton@latest.
Directory layout
| Directory | Purpose |
|---|---|
contracts/ | Smart contract source (.tolk, .fc, .tact) and shared imports (e.g. contracts/imports/*.fc) |
wrappers/ | TypeScript wrapper classes implementing Contract from @ton/core; message encode/decode and compilation entrypoints. Tact puts generated wrappers under build/<CONTRACT>/ per tact.config.json |
compilables/ | Optional; compilation scripts *.compile.ts when separateCompilables: true. Otherwise compilables live in wrappers/ |
tests/ | Test files *.spec.ts using Sandbox and wrappers |
scripts/ | Deployment and other runnable scripts; must export run(provider, args?) |
build/ | Build output: build/<CONTRACT>.compiled.json, Tact artifacts in build/<CONTRACT>/, Fift in build/<CONTRACT>/*.fif |
Conventions
- One contract name maps to:
contracts/<Name>.(tolk|fc|tact), a wrapper (or Tact-generated wrapper), and optionallycompilables/<Name>.compile.ts(or insidewrappers/). - Wrappers implement
Contractand usually exposecreateFromAddress,createFromConfig, andsendDeploy(or equivalent). - Scripts are run with
npx blueprint run <SCRIPT> [args...]; the script file must exportrun(provider: NetworkProvider, args?: string[]).
<!-- Source references:
- https://github.com/ton-org/blueprint/blob/main/README.md (Directory structure, Building contracts)
-->
UIProvider
Scripts and CLI runners receive a UIProvider (e.g. InquirerUIProvider) for user interaction. Use it to write messages, prompt for input, or show status instead of hard-coding console.log or readline.
Interface
| Method | Purpose |
|---|---|
write(message: string) | Output a line to the user (console/UI). |
prompt(message: string): Promise<boolean> | Yes/no confirmation. |
input(message: string): Promise<string> | Free-text input. |
inputAddress(message: string, fallback?: Address): Promise<Address> | Prompt for TON address with optional fallback. |
choose<T>(message, choices: T[], display: (v: T) => string): Promise<T> | Pick one option from a list. |
setActionPrompt(message: string) | Set a persistent status line (e.g. "Awaiting deployment..."). |
clearActionPrompt() | Clear the status line. |
Usage in scripts
Scripts receive NetworkProvider; get UI via provider.ui():
export async function run(provider: NetworkProvider, args: string[]) {
const ui = provider.ui();
ui.write('Deploying contract...');
ui.setActionPrompt('Waiting for confirmation...');
// ... send deploy, wait
ui.clearActionPrompt();
const ok = await ui.prompt('Open in explorer?');
if (ok) { /* ... */ }
}Usage in runners
CLI runners receive (args, ui, runnerContext); use ui for all prompts and output so behavior stays consistent across interactive and non-interactive use.
<!-- Source references:
- sources/ton-blueprint/src/ui/UIProvider.ts
- sources/ton-blueprint/src/network/createNetworkProvider.ts (provider.ui())
-->
Build API
Blueprint exports buildOne, buildAll, and buildAllTact for building contracts from code (e.g. in plugins or custom scripts). The CLI blueprint build uses these internally.
Functions
import { buildOne, buildAll, buildAllTact } from '@ton/blueprint';
import type { UIProvider } from '@ton/blueprint';
// Build a single contract
await buildOne('Counter', ui);
// Build all discovered contracts (wrappers/compilables + Tact projects)
await buildAll(ui);
// Build only Tact contracts (legacy .compile.ts Tact + tact.config.json projects)
await buildAllTact(ui);- buildOne(contract: string, ui?: UIProvider) — Compiles one contract, writes artifact to
build/<contract>.compiled.json, and for FunC/Tolk writes Fift tobuild/<contract>/<contract>.fif. For Tact, writes generated files fromresult.fsto disk. Optionaluifor progress messages and action prompt. - buildAll(ui?) — Resolves all contracts via
findContracts()(compilables + Tact config) and runsbuildOnefor each. - buildAllTact(ui?) — Builds only Tact contracts: those with
lang === 'tact'in compilables plus projects from roottact.config.json.
Artifact format
build/<Contract>.compiled.json contains:
- hash — code cell hash (hex).
- hashBase64 — same hash in base64.
- hex — full BOC of the code cell (hex).
- libraryHash, libraryBoc — present only when compiler config has
buildLibrary: true.
Tact also writes generated files (wrappers, etc.) under paths from the compiler result; FunC/Tolk write <Contract>.fif into build/<Contract>/.
When to use
- buildAll — Before
pack, or when you need every contract built (e.g. CI). - buildOne — After creating a single new contract (e.g.
createrunner builds the new Tact contract once). - buildAllTact — When only Tact contracts need rebuilding.
<!-- Source references:
- sources/ton-blueprint/src/build.ts
- sources/ton-blueprint/src/index.ts (exports)
- sources/ton-blueprint/src/paths.ts (BUILD_DIR)
-->
Compilation
Blueprint compiles Tolk, FunC, and Tact contracts. Use compile() in tests/scripts or the blueprint build CLI.
Programmatic compile
import { compile, getCompilerConfigForContract, CompilerConfig, CompileOpts } from '@ton/blueprint';
// Compile by contract name (resolves .compile.ts or tact.config.json)
const code: Cell = await compile('MyContract');
// With options: hooks user data, debug info, build as library cell
const code2 = await compile('MyContract', {
hookUserData: { env: 'test' },
debugInfo: true,
buildLibrary: true,
});Contract name must match a compilable: either compilables/<Name>.compile.ts (or under wrappers/ when separateCompilables is false) or a Tact contract with tact.config.json.
Compiler config resolution
- Tact: If
getTactConfigForContract(name)finds a Tact config, that is used; Tact puts generated wrappers inbuild/<name>/. - FunC/Tolk: Otherwise config is loaded from
extractCompilableConfig(path)for<name>.compile.tsin the compilables directory.
import { getCompilerConfigForContract, getCompilablesDirectory } from '@ton/blueprint';
const config = await getCompilerConfigForContract('Counter');
const dir = await getCompilablesDirectory(); // 'compilables' or 'wrappers' per configCompilerConfig and hooks
Config can be CompilableConfig (FunC/Tolk/Tact legacy) or TactCompilerConfig. Common options:
- preCompileHook(params: HookParams): Promise<void> — runs before compile;
params.userDatafromCompileOpts.hookUserData. - postCompileHook(code: Cell, params: HookParams): Promise<void> — runs after compile.
- buildLibrary?: boolean — output as library cell (see docs.ton.org library-cells).
Compilable-specific: lang ('func' | 'tolk' | 'tact'), targets, sources, entrypoint, optimizationLevel, etc., depending on language.
Build output
- FunC/Tolk: Build writes artifacts (e.g. to
build/);doCompilereturnsFuncCompileResult/TolkCompileResultwithcode,version,snapshot, etc. - Tact: Generated files in
build/<Contract>/; result includesfs(virtual files) and.pkg. - Library cell: Use
buildLibrary: truein config orCompileOptsto get a library cell vialibraryCellFromCode(code).
Exports
compile(name, opts?)— returnsPromise<Cell>(compiled code).doCompile(name, opts?)— returns full result (TactCompileResult | FuncCompileResult | TolkCompileResult).getCompilerConfigForContract(name)— returnsPromise<CompilerConfig>.getCompilablesDirectory()— returns'compilables'or'wrappers'perconfig.separateCompilables.libraryCellFromCode(code: Cell)— packs code hash into library cell.- Types:
CompileOpts,HookParams,CompilerConfig,CompilableConfig,TactCompileResult,FuncCompileResult,TolkCompileResult.
<!-- Source references:
- https://github.com/ton-org/blueprint/blob/main/README.md (Building contracts)
- sources/ton-blueprint/src/compile/compile.ts
- sources/ton-blueprint/src/compile/CompilerConfig.ts
- sources/ton-blueprint/src/index.ts
-->
Pack (publish wrappers)
The blueprint pack command builds all contracts and produces a publish-ready npm package containing wrappers and compiled code. Use it before npm publish when shipping contract interfaces to consumers.
Usage
blueprint pack
blueprint pack --no-warn # skip confirmation about modifying filesWithout --no-warn, the command prompts to confirm because it will modify tsconfig.json, package.json, and remove dist/.
What pack does
1. Build all contracts — runs buildAll(ui) (same as blueprint build --all). 2. Generate `package.ts` — entry point that imports each contract wrapper and exports ContractNameCode (Cell from build/<Contract>.compiled.json). 3. Update `tsconfig.json` — sets outDir: 'dist', declaration: true, esModuleInterop: true, adds package.ts to include. 4. Remove `dist/` and run tsc to compile the package. 5. Update `package.json` — sets main: 'dist/package.js', files: ['dist/**/*'].
Result: a dist/ tree ready for publishing; consumers get wrappers and compiled code cells.
Wrapper path resolution
- FunC/Tolk: wrapper path is
./wrappers/<Contract>. - Tact: wrapper path is
./<output>/<Contract>_<Contract>(from Tact config, typicallybuild/<Contract>/).
All contracts returned by findContracts() (from compilables/wrappers and Tact config) are included. Each must have a build/<Contract>.compiled.json artifact after build.
When to use
- Before
npm publish --access publicwhen publishing a library of TON contract wrappers. - Ensure
tsconfig.json,package.json, and important source files are committed before running; use--no-warnin CI once confident.
<!-- Source references:
- https://github.com/ton-org/blueprint/blob/main/README.md (Publishing Wrapper Code)
- sources/ton-blueprint/src/cli/pack.ts
- sources/ton-blueprint/src/paths.ts
-->
Plugins
Blueprint supports plugins that add new CLI commands (runners) and help text. Plugins are configured in blueprint.config.ts and run in the same process as built-in commands.
Config
import { Config } from '@ton/blueprint';
import { ScaffoldPlugin } from 'blueprint-scaffold';
export const config: Config = {
plugins: [new ScaffoldPlugin()],
};Only named export config is used; do not default-export.
Plugin interface
import type { Plugin, PluginRunner, Runner, RunnerContext, Args } from '@ton/blueprint';
interface Plugin {
runners(): PluginRunner[];
}
interface PluginRunner {
name: string; // command name, e.g. 'scaffold'
runner: Runner;
help: string; // shown in blueprint help <name>
}
type Runner = (
args: Args,
ui: UIProvider,
context: RunnerContext
) => Promise<void>;
interface RunnerContext {
config?: Config;
}Plugin commands are merged with built-in ones; duplicate names override (plugin wins). Help for plugin commands is registered so blueprint help <name> shows runner.help.
Implementing a plugin
1. Implement Plugin: return an array of { name, runner, help }. 2. In runner, use args (parsed with argSpec), ui for output/prompts, and context.config for blueprint config. 3. Add the plugin instance to config.plugins in blueprint.config.ts.
Example (pseudo):
import { Plugin, PluginRunner, Args, RunnerContext } from '@ton/blueprint';
import type { UIProvider } from '@ton/blueprint';
class MyPlugin implements Plugin {
runners(): PluginRunner[] {
return [{
name: 'mycommand',
help: 'Usage: blueprint mycommand [options]\nDoes something useful.',
runner: this.run.bind(this),
}];
}
private async run(args: Args, ui: UIProvider, context: RunnerContext) {
ui.write('Running mycommand');
// context.config?.plugins, context.config?.network, etc.
}
}Community plugins
- blueprint-scaffold — generate a simple dapp from wrappers.
- blueprint-misti — integrate Misti static analyzer.
<!-- Source references:
- https://github.com/ton-org/blueprint/blob/main/README.md (Plugins)
- sources/ton-blueprint/src/config/Plugin.ts
- sources/ton-blueprint/src/cli/Runner.ts
- sources/ton-blueprint/src/cli/cli.ts (loading plugins, effectiveRunners)
-->
Scripts
Scripts live in scripts/ and are executed with npx blueprint run <SCRIPT> [args...]. Each script must export a run function.
Signature
export async function run(provider: NetworkProvider, args: string[]): Promise<void>provider: sameNetworkProviderused for deploy (sender, open, waitForDeploy, etc.).args: CLI arguments after the script name (e.g.blueprint run myScript a b→args = ['a', 'b']).
Shorter form when you don’t need args:
export async function run(provider: NetworkProvider): Promise<void>Deploy script pattern
Typical deploy script: compile contract, open with config, send deploy, wait for deploy.
import { toNano } from '@ton/core';
import { compile, NetworkProvider } from '@ton/blueprint';
import { Counter } from '../wrappers/Counter';
export async function run(provider: NetworkProvider) {
const counter = provider.open(
Counter.createFromConfig(
{ id: Math.floor(Math.random() * 10000), counter: 0 },
await compile('Counter')
)
);
await counter.sendDeploy(provider.sender(), toNano('0.05'));
await provider.waitForDeploy(counter.address);
console.log('ID', await counter.getID());
}Script with arguments
import { NetworkProvider, sleep } from '@ton/blueprint';
export async function run(provider: NetworkProvider, args: string[]) {
const contractAddress = args[0];
if (!contractAddress) {
provider.ui().write('Usage: blueprint run increment <address>');
return;
}
// ... open contract, send message, optionally waitForLastTransaction()
await provider.waitForLastTransaction();
}Run: yarn blueprint run increment EQ... --testnet --tonconnect.
<!-- Source references:
- https://github.com/ton-org/blueprint/blob/main/README.md (Running scripts, Deploying contracts)
- sources/ton-blueprint/src/templates (deploy and increment script templates)
-->
Contract verification
Blueprint can verify a deployed contract on verifier.ton.org so the source is publicly linked to the on-chain code.
Usage
blueprint verify [ContractName] --mainnet
blueprint verify MyContract --testnet --compiler-version 0.4.4-newops.1
blueprint verify --list-verifiersIf contract name is omitted, an interactive contract selection is shown.
Flags
| Flag | Description |
|---|---|
--mainnet / --testnet | Network. Custom network not allowed for verify. |
--verifier | Verifier ID (default: verifier.ton.org). |
--list-verifiers | List available verifiers for the selected network(s). |
--compiler-version | Exact compiler version string (e.g. 0.4.4-newops.1). Does not change the local compiler; used for the verifier payload. |
--custom, --custom-version, --custom-key, --custom-type | Use custom API; --custom-type must be mainnet or testnet. |
Flow (agent-oriented)
1. Resolve contract (arg or interactive). 2. Create network provider (no custom network type; mainnet/testnet/tetra allowed). 3. Compile locally with doCompile(selectedContract, { buildLibrary: false }). 4. Get deployed address: prompt user, or lookup by code hash via dton.io GraphQL. 5. Build source payload (Func/Tact/Tolk) and send to verifier backend /source. 6. Collect signatures until verifier quorum; send verification message to verifier registry contract. 7. Output success URL: https://verifier.ton.org/<address>?testnet=true if testnet.
Verifier config is fetched from: https://raw.githubusercontent.com/ton-community/contract-verifier-config/main/config.json. Verifier registry addresses: mainnet EQD-BJSVUJviud_Qv7Ymfd3qzXdrmV525e3YDzWQoHIAiInL, testnet EQCsdKYwUaXkgJkz2l0ol6qT_WxeRbE_wBCwnEybmR0u5TO8.
Custom network and config
When using a custom API for verify, specify --custom-type mainnet or --custom-type testnet; custom type is required. You can use blueprint.config.ts network so that --custom etc. are implied.
<!-- Source references:
- https://github.com/ton-org/blueprint/blob/main/README.md (Contract Verification Using Custom Network)
- sources/ton-blueprint/src/cli/verify.ts
- sources/ton-blueprint/src/cli/constants.ts (helpMessages.verify)
-->
Wrappers
Wrappers are TypeScript classes that implement Contract from @ton/core. They provide address/init, message encoding, getters, and a standard deploy helper. Tact generates its own wrappers under build/<CONTRACT>/.
Contract interface (from @ton/core)
address: Addressinit?: { code: Cell; data: Cell }- Used with
provider.open(contract)andcontract.sendDeploy(via, value)(or custom send methods).
Manual wrapper pattern (FunC/Tolk)
import { Address, beginCell, Cell, Contract, contractAddress, ContractProvider, Sender, SendMode } from '@ton/core';
export type CounterConfig = { id: number; counter: number };
export function counterConfigToCell(config: CounterConfig): Cell {
return beginCell().storeUint(config.id, 32).storeUint(config.counter, 32).endCell();
}
export class Counter implements Contract {
constructor(readonly address: Address, readonly init?: { code: Cell; data: Cell }) {}
static createFromAddress(address: Address) {
return new Counter(address);
}
static createFromConfig(config: CounterConfig, code: Cell, workchain = 0) {
const data = counterConfigToCell(config);
const init = { code, data };
return new Counter(contractAddress(workchain, init), init);
}
async sendDeploy(provider: ContractProvider, via: Sender, value: bigint) {
await provider.internal(via, {
value,
sendMode: SendMode.PAY_GAS_SEPARATELY,
body: beginCell().endCell(),
});
}
async getID(provider: ContractProvider) {
const { stack } = await provider.get('get_id', []);
return stack.readBigNumber();
}
}Usage in tests and scripts
- Tests:
blockchain.openContract(Contract.createFromConfig(config, code))thensendDeploy(deployer.getSender(), toNano('0.05')). - Scripts:
provider.open(Contract.createFromConfig(config, await compile('Contract')))thencontract.sendDeploy(provider.sender(), toNano('0.05'))andprovider.waitForDeploy(contract.address).
Tact-generated wrappers follow the same Contract pattern; import from build/<CONTRACT>/tact_<Contract>.ts (or path set in tact.config.json).
<!-- Source references:
- https://github.com/ton-org/blueprint/blob/main/README.md (Directory structure, wrappers)
- sources/ton-blueprint/src/templates (wrapper and deploy templates)
-->