Blueprint
A development environment for TON blockchain for writing, testing, and deploying smart contracts.
Table of Contents
Quick start 🚀
Run the command in terminal to create a new project and follow the on-screen instructions:
npm create ton@latest
Overview
Blueprint is an all-in-one development environment designed to enhance the process of creating, testing, and deploying smart contracts on TON blockchain using Tolk, FunC, and Tact languages.
Core features
- Create a development environment from template -
npm create ton@latest
- Streamlined workflow for building, testing and deploying smart contracts
- Dead simple deployment to mainnet/testnet using your favorite wallet (eg. Tonkeeper)
- Blazing fast testing of multiple smart contracts in an isolated blockchain running in-process
Tech stack
Requirements
- Node.js with a recent version like v18. Version can be verified with
node -v
- IDE with TON support:
Features overview
Project creation
- Run and follow the on-screen instructions:
npm create ton@latest or npx create-ton@latest
- From the project directory run
npm/yarn install to install dependencies
Directory structure
contracts/ - Source code for all smart contracts and their imports
wrappers/ - TypeScript interface classes for all contracts except Tact.
- Tact-generated wrappers are located according to the build path defined in
tact.config.json
- Each wrapper implements
Contract interface from @ton/core
- Includes message [de]serialization primitives, getter wrappers and compilation functions
- Used by the test suite and client code to interact with the contracts from TypeScript
compilables/ - Compilations scripts for contracts
tests/ - TypeScript test suite for all contracts (relying on Sandbox for in-process tests)
scripts/ - Deployment scripts to mainnet/testnet and other scripts interacting with live contracts
build/ - Compilation artifacts created here after running a build command
Building contracts
- You need a compilation script in
compilables/<CONTRACT>.compile.ts - example
- Run interactive:
npx blueprint build or yarn blueprint build
- Non-interactive:
npx/yarn blueprint build <CONTRACT> OR build all contracts yarn blueprint build --all
- Example:
yarn blueprint build counter
- Build results are generated in
build/<CONTRACT>.compiled.json
- Tact generated files are located in
build/<CONTRACT> directory
- Fift output is located in
build/<CONTRACT>/<CONTRACT>.fif
Running the test suites
- Run in terminal:
npx blueprint test or yarn blueprint test
- Alternative method:
npm test or yarn test
- You can specify test file to run:
npm/yarn test <CONTRACT>
- Example:
yarn test counter
Learn more about writing tests from the Sandbox's documentation - here.
Running scripts
- Custom scripts should be located in
scripts folder
- Script file must have exported function
run
export async function run(provider: NetworkProvider, args: string[]) {
}
- Script can be run using
npx/yarn blueprint run <SCRIPT> [arg1, arg2, ...] command
Deploying contracts
- You need a deployment script in
scripts/deploy<CONTRACT>.ts - example
- Run interactive:
npx blueprint run or yarn blueprint run
- Non-interactive:
npx/yarn blueprint run deploy<CONTRACT> --<NETWORK> --<DEPLOY_METHOD>
- Example:
yarn blueprint run deployCounter --mainnet --tonconnect
Using Mnemonic Provider
To run scripts using a wallet by mnemonic authentication, you need to configure your environment and use the Mnemonic option when running scripts.
Start by adding the following environment variables to your .env file:
WALLET_MNEMONIC: Your wallet's mnemonic phrase (space-separated words).
WALLET_VERSION: The wallet contract version to use. Supported versions: v1r1, v1r2, v1r3, v2r1, v2r2, v3r1, v3r2, v4r1, v4r2 (or v4), v5r1.
Optional variables:
WALLET_ID: The wallet ID (can be used with versions below v5r1).
SUBWALLET_NUMBER: The subwallet number used to build the wallet ID (can be used with v5r1 wallets).
Once your environment is set up, you can use the mnemonic wallet for deployment with the appropriate configuration.
Updating Tolk version
Tolk version can be updated to the latest using npm update/yarn upgrade @ton/tolk-js command
Updating FunC version
FunC version can be updated to a specific version using npx/yarn blueprint set func command, or to the latest using npm update/yarn upgrade @ton-community/func-js command
Updating Tact version
Tact version can be updated to the latest using npm update/yarn upgrade @tact-lang/compiler command
Help and additional commands
Run in terminal: npx blueprint help or yarn blueprint help
Contract development
Before developing, make sure that your current working directory is located in the root of the project created using npm create ton@latest
Creating contracts
- Run interactive:
npx blueprint create or yarn blueprint create
- Non-interactive:
npx/yarn blueprint create <CONTRACT> --type <TYPE> (type can be tolk-empty, func-empty, tact-empty, tolk-counter, func-counter, tact-counter)
- Example:
yarn blueprint create MyNewContract --type tolk-empty
Renaming contracts
- Run interactive:
npx blueprint rename or yarn blueprint rename
- Non-interactive:
npx/yarn blueprint rename <OLD_NAME> <NEW_NAME>
- Example:
yarn blueprint rename OldContract NewContract
Writing contract code
Tolk
- Implement the contract in
contracts/<CONTRACT>.tolk; if you wish, split into multiple files
- Implement wrapper TypeScript class in
wrappers/<CONTRACT>.ts to encode messages and decode getters
FunC
- Implement the standalone FunC root contract in
contracts/<CONTRACT>.fc
- Implement shared FunC imports (if breaking code to multiple files) in
contracts/imports/*.fc
- Implement wrapper TypeScript class in
wrappers/<CONTRACT>.ts to encode messages and decode getters
Tact
- Implement the contract in
contracts/<CONTRACT>.tact
- Wrappers will be automatically generated in
build/<CONTRACT>/tact_<CONTRACT>.ts
Testing contracts
- Implement TypeScript tests in
tests/<CONTRACT>.spec.ts
- Rely on the wrapper TypeScript class from
wrappers/<CONTRACT>.ts to interact with the contract
Collecting coverage
To collect coverage run blueprint test --coverage. Coverage will appear in coverage directory.
Learn more about writing tests from the Sandbox's documentation - here.
Publishing Wrapper Code
- Authenticate with npm
Run
npm adduser to log in to your npm account.
📝 Note: You can learn more about advanced authentication in the official npm docs:
npmrc – Auth-Related Configuration
-
Update the package version
Edit the version field in your package.json to reflect the new release (e.g., 1.0.1 → 1.0.2).
-
Build the package
Run the following command to generate and bundle your contract wrappers:
blueprint pack
- Publish to npm
Push the package to the public npm registry:
npm publish --access public
Benchmark contracts
- Run
npx blueprint snapshot [--label=<comment>|-l <comment>] to collect metrics of contracts and save snapshot
- Run
npx blueprint test --gas-report|-g to compare current metrics and saved snapshot
Learn more about collect metric from the Sandbox's documentation - here.
Configuration
A config may be created in order to control some of blueprint's features. If a config is needed, create a blueprint.config.ts file in the root of your project with something like this:
import { Config } from '@ton/blueprint';
export const config: Config = {
};
It is important that the config is exported, is named config, and is not default exported.
Config's features are explained below.
Plugins
Blueprint has a plugin system to allow the community to develop their own additions for the ecosystem without the need to change blueprint's code.
In order to use plugins, add a plugins array to your config:
import { Config } from '@ton/blueprint';
import { ScaffoldPlugin } from 'blueprint-scaffold';
export const config: Config = {
plugins: [new ScaffoldPlugin()],
};
(This example shows how to add the scaffold plugin)
Here are some of the plugins developed by the community:
- scaffold - allows developers to quickly create a simple dapp automatically using the wrappers' code
- misti - simplifies workflow with the Misti static analyzer
Custom network
A custom network may be specified by using the --custom flags, which you can read about by running blueprint help run, but it can be tiresome to use these at all times. Instead, to specify a custom network to always be used (unless --custom flags are present), add a network object to your config:
import { Config } from '@ton/blueprint';
export const config: Config = {
network: {
endpoint: 'https://toncenter.com/api/v2/jsonRPC',
type: 'mainnet',
version: 'v2',
key: 'YOUR_API_KEY',
},
};
The above config parameters are equivalent to the arguments in the following command:
npx blueprint run --custom https://toncenter.com/api/v2/jsonRPC --custom-version v2 --custom-type mainnet --custom-key YOUR_API_KEY
Properties of the network object have the same semantics as the --custom flags with respective names (see blueprint help run).
Liteclient Support
Lite client is supported through the following configuration:
import { Config } from '@ton/blueprint';
export const config: Config = {
network: {
endpoint: 'https://ton.org/testnet-global.config.json',
version: 'liteclient',
type: 'testnet',
}
};
You can also provide these parameters via CLI:
npx blueprint run \
--custom https://ton.org/testnet-global.config.json \
--custom-version liteclient \
--custom-type testnet
Contract Verification Using Custom Network
You can also use custom network to verify contracts, like so:
npx blueprint verify --custom https://toncenter.com/api/v2/jsonRPC --custom-version v2 --custom-type mainnet --custom-key YOUR_API_KEY --compiler-version 0.4.4-newops.1
(or similarly using the config), however custom type MUST be specified as either mainnet or testnet when verifying.
Request timeout
You can optionally configure how long HTTP requests should wait before timing out using the requestTimout field. This can be especially useful when working with unstable or slow networks.
import { Config } from '@ton/blueprint';
export const config: Config = {
requestTimeout: 10000,
};
Recursive wrappers
You can configure whether the wrappers or compilables directories should be searched recursively for contracts configs by setting the recursiveWrappers field.
import { Config } from '@ton/blueprint';
export const config: Config = {
recursiveWrappers: true,
};
By default, this is set to false.
TonConnect manifest URL
If you're using a TonConnect provider, you can override the default manifest URL by specifying the manifestUrl field.
import { Config } from '@ton/blueprint';
export const config: Config = {
manifestUrl: 'https://yourdomain.com/custom-manifest.json',
};
By default, the manifest URL is set to:
https://raw.githubusercontent.com/ton-org/blueprint/main/tonconnect/manifest.json
Contributors
Special thanks to @qdevstudio for their logo for blueprint.
License
MIT
Donations
TON - EQAQR1d1Q4NaE5EefwUMdrr1QvXg-8mDB0XI2-fwDBD0nYxC