diff --git a/01-wallet/index.md b/01-wallet/index.md index 1063441..c7d9deb 100644 --- a/01-wallet/index.md +++ b/01-wallet/index.md @@ -131,7 +131,7 @@ library:npmton Next, we're going to install a JavaScript package named [ton](https://www.npmjs.com/package/ton) that will allow us to make TON API calls and manipulate TON objects. Install the package by opening terminal in the project directory and running: ```console -npm install ton ton-crypto ton-core +npm install @ton/ton @ton/crypto @ton/core ``` --- @@ -159,7 +159,7 @@ Create the file `step7.ts` with the following content: network:testnet library:npmton --- ```ts -import { mnemonicToWalletKey } from "ton-crypto"; +import { mnemonicToWalletKey } from "@ton/crypto"; import { WalletContractV4 } from "ton"; async function main() { @@ -184,7 +184,7 @@ main(); network:mainnet library:npmton --- ```ts -import { mnemonicToWalletKey } from "ton-crypto"; +import { mnemonicToWalletKey } from "@ton/crypto"; import { WalletContractV4 } from "ton"; async function main() { @@ -302,7 +302,7 @@ network:testnet library:npmton --- ```ts import { getHttpEndpoint } from "@orbs-network/ton-access"; -import { mnemonicToWalletKey } from "ton-crypto"; +import { mnemonicToWalletKey } from "@ton/crypto"; import { WalletContractV4, TonClient, fromNano } from "ton"; async function main() { @@ -335,7 +335,7 @@ network:mainnet library:npmton --- ```ts import { getHttpEndpoint } from "@orbs-network/ton-access"; -import { mnemonicToWalletKey } from "ton-crypto"; +import { mnemonicToWalletKey } from "@ton/crypto"; import { WalletContractV4, TonClient, fromNano } from "ton"; async function main() { @@ -458,7 +458,7 @@ network:testnet library:npmton --- ```ts import { getHttpEndpoint } from "@orbs-network/ton-access"; -import { mnemonicToWalletKey } from "ton-crypto"; +import { mnemonicToWalletKey } from "@ton/crypto"; import { TonClient, WalletContractV4, internal } from "ton"; async function main() { @@ -516,7 +516,7 @@ network:mainnet library:npmton --- ```ts import { getHttpEndpoint } from "@orbs-network/ton-access"; -import { mnemonicToWalletKey } from "ton-crypto"; +import { mnemonicToWalletKey } from "@ton/crypto"; import { TonClient, WalletContractV4, internal } from "ton"; async function main() { diff --git a/02-contract/index.md b/02-contract/index.md index a6b3c26..b032a0e 100644 --- a/02-contract/index.md +++ b/02-contract/index.md @@ -54,7 +54,7 @@ This will install the package [func-js](https://github.com/ton-community/func-js And finally, run in terminal: ```console -npm install ton ton-crypto ton-core +npm install @ton/ton @ton/crypto @ton/core ``` This will install a library that you should be familiar with - [ton](https://www.npmjs.com/package/ton). We'll use it to deploy our contract and interact with it. @@ -175,7 +175,7 @@ The recommended way to interact with contracts is to create a small TypeScript c Use the following code in `counter.ts` to create the initial data cell for deployment: ```ts -import { Contract, ContractProvider, Sender, Address, Cell, contractAddress, beginCell } from "ton-core"; +import { Contract, ContractProvider, Sender, Address, Cell, contractAddress, beginCell } from "@ton/core"; export default class Counter implements Contract { @@ -192,7 +192,7 @@ export default class Counter implements Contract { } ``` -Notice a few interesting things about this TypeScript code. First, it depends on the package [ton-core](https://www.npmjs.com/package/ton-core) instead of [ton](https://www.npmjs.com/package/ton), which contains a small subset of base types and is therefore slower to change - an important feature when building a stable interface for our contract. Second, the code that creates the data cell mimics the FunC API and is almost identical to our `save_data()` FunC function. Third, we can see the derivation of the contract address from the code cell and data cell using the function `contractAddress`. +Notice a few interesting things about this TypeScript code. First, it depends on the package [@ton/core](https://www.npmjs.com/package/@ton/core) instead of [ton](https://www.npmjs.com/package/ton), which contains a small subset of base types and is therefore slower to change - an important feature when building a stable interface for our contract. Second, the code that creates the data cell mimics the FunC API and is almost identical to our `save_data()` FunC function. Third, we can see the derivation of the contract address from the code cell and data cell using the function `contractAddress`. The actual deployment involves sending the first message that will cause our contract to be deployed. We can piggyback any message that is directed towards our contract. This can even be the increment message with op #1, but we will do something simpler. We will just send some TON coins to our contract (an empty message) and piggyback that. Let's make this part of our interface. Add the function `sendDeploy()` to `counter.ts` - this function will send the deployment message: @@ -235,7 +235,7 @@ network:testnet ```ts import * as fs from "fs"; import { getHttpEndpoint } from "@orbs-network/ton-access"; -import { mnemonicToWalletKey } from "ton-crypto"; +import { mnemonicToWalletKey } from "@ton/crypto"; import { TonClient, Cell, WalletContractV4 } from "ton"; import Counter from "./counter"; // this is the interface class from step 7 @@ -297,7 +297,7 @@ network:mainnet ```ts import * as fs from "fs"; import { getHttpEndpoint } from "@orbs-network/ton-access"; -import { mnemonicToWalletKey } from "ton-crypto"; +import { mnemonicToWalletKey } from "@ton/crypto"; import { TonClient, Cell, WalletContractV4 } from "ton"; import Counter from "./counter"; // this is the interface class from step 7 @@ -518,7 +518,7 @@ network:testnet --- ```ts import { getHttpEndpoint } from "@orbs-network/ton-access"; -import { mnemonicToWalletKey } from "ton-crypto"; +import { mnemonicToWalletKey } from "@ton/crypto"; import { TonClient, WalletContractV4, Address } from "ton"; import Counter from "./counter"; // this is the interface class we just implemented @@ -572,7 +572,7 @@ network:mainnet --- ```ts import { getHttpEndpoint } from "@orbs-network/ton-access"; -import { mnemonicToWalletKey } from "ton-crypto"; +import { mnemonicToWalletKey } from "@ton/crypto"; import { TonClient, WalletContractV4, Address } from "ton"; import Counter from "./counter"; // this is the interface class we just implemented diff --git a/03-client/index.md b/03-client/index.md index 41fcc66..aeb68ee 100644 --- a/03-client/index.md +++ b/03-client/index.md @@ -38,7 +38,7 @@ npm install We will need to install a few more packages that will allow us to interact with TON Blockchain. We've seen these packages in action in the previous tutorial. Run the following in terminal: ```console -npm install ton ton-core ton-crypto +npm install @ton/ton @ton/core @ton/crypto npm install @orbs-network/ton-access ``` @@ -209,7 +209,7 @@ import { useEffect, useState } from 'react'; import Counter from '../contracts/counter'; import { useTonClient } from './useTonClient'; import { useAsyncInitialize } from './useAsyncInitialize'; -import { Address, OpenedContract } from 'ton-core'; +import { Address, OpenedContract } from '@ton/core'; export function useCounterContract() { const client = useTonClient(); @@ -292,7 +292,7 @@ Create the file `src/hooks/useTonConnect.ts` with the following content: ```ts import { useTonConnectUI } from '@tonconnect/ui-react'; -import { Sender, SenderArguments } from 'ton-core'; +import { Sender, SenderArguments } from '@ton/core'; export function useTonConnect(): { sender: Sender; connected: boolean } { const [tonConnectUI] = useTonConnectUI(); @@ -327,7 +327,7 @@ import Counter from '../contracts/counter'; import { useTonClient } from './useTonClient'; import { useAsyncInitialize } from './useAsyncInitialize'; import { useTonConnect } from './useTonConnect'; -import { Address, OpenedContract } from 'ton-core'; +import { Address, OpenedContract } from '@ton/core'; export function useCounterContract() { const client = useTonClient(); diff --git a/docs/01-wallet/index.html b/docs/01-wallet/index.html index 37a5188..e3dd9cf 100644 --- a/docs/01-wallet/index.html +++ b/docs/01-wallet/index.html @@ -172,13 +172,13 @@

Step 6: Set up your local machine f
npm install ts-node
 

Next, we're going to install a JavaScript package named ton that will allow us to make TON API calls and manipulate TON objects. Install the package by opening terminal in the project directory and running:

-
npm install ton ton-crypto ton-core
+
npm install @ton/ton @ton/crypto @ton/core
 

Step 7: Get the wallet address programmatically

The first thing we'll do is calculate the address of our wallet in code and see that it matches what we saw in the explorer. This action is completely offline since the wallet address is derived from the version of the wallet and the private key used to create it.

Let's assume that your secret 24 word mnemonic is unfold sugar water ... - this is the phrase we backed up in step 2.

Create the file step7.ts with the following content:

-
import { mnemonicToWalletKey } from "ton-crypto";
+
import { mnemonicToWalletKey } from "@ton/crypto";
 import { WalletContractV4 } from "ton";
 
 async function main() {
@@ -209,7 +209,7 @@ 

Step 8: Read wallet state from the cha

Create the file step8.ts with the following content:

import { getHttpEndpoint } from "@orbs-network/ton-access";
-import { mnemonicToWalletKey } from "ton-crypto";
+import { mnemonicToWalletKey } from "@ton/crypto";
 import { WalletContractV4, TonClient, fromNano } from "ton";
 
 async function main() {
@@ -246,7 +246,7 @@ 

Step 9: Send transfer transactio

Create a new file step9.ts with this content:

import { getHttpEndpoint } from "@orbs-network/ton-access";
-import { mnemonicToWalletKey } from "ton-crypto";
+import { mnemonicToWalletKey } from "@ton/crypto";
 import { TonClient, WalletContractV4, internal } from "ton";
 
 async function main() {
@@ -562,13 +562,13 @@ 

Step 6: Set up your local machine f
npm install ts-node
 

Next, we're going to install a JavaScript package named ton that will allow us to make TON API calls and manipulate TON objects. Install the package by opening terminal in the project directory and running:

-
npm install ton ton-crypto ton-core
+
npm install @ton/ton @ton/crypto @ton/core
 

Step 7: Get the wallet address programmatically

The first thing we'll do is calculate the address of our wallet in code and see that it matches what we saw in the explorer. This action is completely offline since the wallet address is derived from the version of the wallet and the private key used to create it.

Let's assume that your secret 24 word mnemonic is unfold sugar water ... - this is the phrase we backed up in step 2.

Create the file step7.ts with the following content:

-
import { mnemonicToWalletKey } from "ton-crypto";
+
import { mnemonicToWalletKey } from "@ton/crypto";
 import { WalletContractV4 } from "ton";
 
 async function main() {
@@ -599,7 +599,7 @@ 

Step 8: Read wallet state from the cha

Create the file step8.ts with the following content:

import { getHttpEndpoint } from "@orbs-network/ton-access";
-import { mnemonicToWalletKey } from "ton-crypto";
+import { mnemonicToWalletKey } from "@ton/crypto";
 import { WalletContractV4, TonClient, fromNano } from "ton";
 
 async function main() {
@@ -636,7 +636,7 @@ 

Step 9: Send transfer transactio

Create a new file step9.ts with this content:

import { getHttpEndpoint } from "@orbs-network/ton-access";
-import { mnemonicToWalletKey } from "ton-crypto";
+import { mnemonicToWalletKey } from "@ton/crypto";
 import { TonClient, WalletContractV4, internal } from "ton";
 
 async function main() {
diff --git a/docs/01-wallet/mainnet-npmton.html b/docs/01-wallet/mainnet-npmton.html
index a3a49f4..f337874 100644
--- a/docs/01-wallet/mainnet-npmton.html
+++ b/docs/01-wallet/mainnet-npmton.html
@@ -49,13 +49,13 @@ 

Step 6: Set up your local machine f
npm install ts-node
 

Next, we're going to install a JavaScript package named ton that will allow us to make TON API calls and manipulate TON objects. Install the package by opening terminal in the project directory and running:

-
npm install ton ton-crypto ton-core
+
npm install @ton/ton @ton/crypto @ton/core
 

Step 7: Get the wallet address programmatically

The first thing we'll do is calculate the address of our wallet in code and see that it matches what we saw in the explorer. This action is completely offline since the wallet address is derived from the version of the wallet and the private key used to create it.

Let's assume that your secret 24 word mnemonic is unfold sugar water ... - this is the phrase we backed up in step 2.

Create the file step7.ts with the following content:

-
import { mnemonicToWalletKey } from "ton-crypto";
+
import { mnemonicToWalletKey } from "@ton/crypto";
 import { WalletContractV4 } from "ton";
 
 async function main() {
@@ -86,7 +86,7 @@ 

Step 8: Read wallet state from the cha

Create the file step8.ts with the following content:

import { getHttpEndpoint } from "@orbs-network/ton-access";
-import { mnemonicToWalletKey } from "ton-crypto";
+import { mnemonicToWalletKey } from "@ton/crypto";
 import { WalletContractV4, TonClient, fromNano } from "ton";
 
 async function main() {
@@ -123,7 +123,7 @@ 

Step 9: Send transfer transactio

Create a new file step9.ts with this content:

import { getHttpEndpoint } from "@orbs-network/ton-access";
-import { mnemonicToWalletKey } from "ton-crypto";
+import { mnemonicToWalletKey } from "@ton/crypto";
 import { TonClient, WalletContractV4, internal } from "ton";
 
 async function main() {
diff --git a/docs/01-wallet/mainnet-npmton.md b/docs/01-wallet/mainnet-npmton.md
index d8e9c82..15d4b67 100644
--- a/docs/01-wallet/mainnet-npmton.md
+++ b/docs/01-wallet/mainnet-npmton.md
@@ -102,7 +102,7 @@ npm install ts-node
 Next, we're going to install a JavaScript package named [ton](https://www.npmjs.com/package/ton) that will allow us to make TON API calls and manipulate TON objects. Install the package by opening terminal in the project directory and running:
 
 ```console
-npm install ton ton-crypto ton-core
+npm install @ton/ton @ton/crypto @ton/core
 ```
 
 ## Step 7: Get the wallet address programmatically
@@ -114,7 +114,7 @@ Let's assume that your secret 24 word mnemonic is `unfold sugar water ...` - thi
 Create the file `step7.ts` with the following content:
 
 ```ts
-import { mnemonicToWalletKey } from "ton-crypto";
+import { mnemonicToWalletKey } from "@ton/crypto";
 import { WalletContractV4 } from "ton";
 
 async function main() {
@@ -159,7 +159,7 @@ Create the file `step8.ts` with the following content:
 
 ```ts
 import { getHttpEndpoint } from "@orbs-network/ton-access";
-import { mnemonicToWalletKey } from "ton-crypto";
+import { mnemonicToWalletKey } from "@ton/crypto";
 import { WalletContractV4, TonClient, fromNano } from "ton";
 
 async function main() {
@@ -207,7 +207,7 @@ Create a new file `step9.ts` with this content:
 
 ```ts
 import { getHttpEndpoint } from "@orbs-network/ton-access";
-import { mnemonicToWalletKey } from "ton-crypto";
+import { mnemonicToWalletKey } from "@ton/crypto";
 import { TonClient, WalletContractV4, internal } from "ton";
 
 async function main() {
diff --git a/docs/01-wallet/testnet-npmton.html b/docs/01-wallet/testnet-npmton.html
index c716b88..4022181 100644
--- a/docs/01-wallet/testnet-npmton.html
+++ b/docs/01-wallet/testnet-npmton.html
@@ -51,13 +51,13 @@ 

Step 6: Set up your local machine f
npm install ts-node
 

Next, we're going to install a JavaScript package named ton that will allow us to make TON API calls and manipulate TON objects. Install the package by opening terminal in the project directory and running:

-
npm install ton ton-crypto ton-core
+
npm install @ton/ton @ton/crypto @ton/core
 

Step 7: Get the wallet address programmatically

The first thing we'll do is calculate the address of our wallet in code and see that it matches what we saw in the explorer. This action is completely offline since the wallet address is derived from the version of the wallet and the private key used to create it.

Let's assume that your secret 24 word mnemonic is unfold sugar water ... - this is the phrase we backed up in step 2.

Create the file step7.ts with the following content:

-
import { mnemonicToWalletKey } from "ton-crypto";
+
import { mnemonicToWalletKey } from "@ton/crypto";
 import { WalletContractV4 } from "ton";
 
 async function main() {
@@ -88,7 +88,7 @@ 

Step 8: Read wallet state from the cha

Create the file step8.ts with the following content:

import { getHttpEndpoint } from "@orbs-network/ton-access";
-import { mnemonicToWalletKey } from "ton-crypto";
+import { mnemonicToWalletKey } from "@ton/crypto";
 import { WalletContractV4, TonClient, fromNano } from "ton";
 
 async function main() {
@@ -125,7 +125,7 @@ 

Step 9: Send transfer transactio

Create a new file step9.ts with this content:

import { getHttpEndpoint } from "@orbs-network/ton-access";
-import { mnemonicToWalletKey } from "ton-crypto";
+import { mnemonicToWalletKey } from "@ton/crypto";
 import { TonClient, WalletContractV4, internal } from "ton";
 
 async function main() {
diff --git a/docs/01-wallet/testnet-npmton.md b/docs/01-wallet/testnet-npmton.md
index ad24aa2..1cfb424 100644
--- a/docs/01-wallet/testnet-npmton.md
+++ b/docs/01-wallet/testnet-npmton.md
@@ -106,7 +106,7 @@ npm install ts-node
 Next, we're going to install a JavaScript package named [ton](https://www.npmjs.com/package/ton) that will allow us to make TON API calls and manipulate TON objects. Install the package by opening terminal in the project directory and running:
 
 ```console
-npm install ton ton-crypto ton-core
+npm install @ton/ton @ton/crypto @ton/core
 ```
 
 ## Step 7: Get the wallet address programmatically
@@ -118,7 +118,7 @@ Let's assume that your secret 24 word mnemonic is `unfold sugar water ...` - thi
 Create the file `step7.ts` with the following content:
 
 ```ts
-import { mnemonicToWalletKey } from "ton-crypto";
+import { mnemonicToWalletKey } from "@ton/crypto";
 import { WalletContractV4 } from "ton";
 
 async function main() {
@@ -163,7 +163,7 @@ Create the file `step8.ts` with the following content:
 
 ```ts
 import { getHttpEndpoint } from "@orbs-network/ton-access";
-import { mnemonicToWalletKey } from "ton-crypto";
+import { mnemonicToWalletKey } from "@ton/crypto";
 import { WalletContractV4, TonClient, fromNano } from "ton";
 
 async function main() {
@@ -211,7 +211,7 @@ Create a new file `step9.ts` with this content:
 
 ```ts
 import { getHttpEndpoint } from "@orbs-network/ton-access";
-import { mnemonicToWalletKey } from "ton-crypto";
+import { mnemonicToWalletKey } from "@ton/crypto";
 import { TonClient, WalletContractV4, internal } from "ton";
 
 async function main() {
diff --git a/docs/02-contract/index.html b/docs/02-contract/index.html
index d1c953f..15314b1 100644
--- a/docs/02-contract/index.html
+++ b/docs/02-contract/index.html
@@ -112,7 +112,7 @@ 

TON H

A smart contract is simply a computer program running on TON Blockchain - or more exactly its TVM (TON Virtual Machine). The contract is made of code (compiled TVM instructions) and data (persistent state) that are stored in some address on TON Blockchain.

-

In the world of blockchain, code is law, meaning that instead of lawyers and papers, computer instructions define in absolute terms the rules of interaction between the different users of the contract. Before enagaging with any smart contract as a user, you're expected to review its code and thus understand its terms of agreement. Accordingly, we'll make an effort to make our contract as easy to read as possible, so its users could understand what they're getting into.

+

In the world of blockchain, code is law, meaning that instead of lawyers and papers, computer instructions define in absolute terms the rules of interaction between the different users of the contract. Before engaging with any smart contract as a user, you're expected to review its code and thus understand its terms of agreement. Accordingly, we'll make an effort to make our contract as easy to read as possible, so its users could understand what they're getting into.

Dapps - decentralized applications

Smart contracts are a key part of decentralized apps - a special type of application invented in the blockchain era, that does not depend on any single entity to run it. Unlike the app Uber, for example, which depends on the company Uber Inc to run it - a decentralized Uber would allow riders and drivers to interact directly (order, pay for and fulfill rides) without any intermediary like Uber Inc. Dapps are also unstoppable - if we don't depend on anyone specific to run them, nobody can take them down.

Dapps on TON Blockchain are usually made of 2 main projects:

@@ -141,7 +141,7 @@

Step 3: Set up the project

In previous iterations of this tutorial we used to deal with binaries executables of the func and fift compilers, but those were platform specific (different binaries for Mac, Windows and Linux). Relying on func-js will make life easier since it's cross-platform. In general, using executable binaries in the TON ecosystem is obsolete.

And finally, run in terminal:

-
npm install ton ton-crypto ton-core
+
npm install @ton/ton @ton/crypto @ton/core
 

This will install a library that you should be familiar with - ton. We'll use it to deploy our contract and interact with it.

Step 4: Structuring our smart contract

@@ -212,7 +212,7 @@

Init arguments

Interface class

The recommended way to interact with contracts is to create a small TypeScript class that will implement the interaction interface with the contract. We would normally give it the same name, so create the file counter.ts and place it next to the FunC source counter.fc.

Use the following code in counter.ts to create the initial data cell for deployment:

-
import { Contract, ContractProvider, Sender, Address, Cell, contractAddress, beginCell } from "ton-core";
+
import { Contract, ContractProvider, Sender, Address, Cell, contractAddress, beginCell } from "@ton/core";
 
 export default class Counter implements Contract {
 
@@ -228,7 +228,7 @@ 

Interface class

constructor(readonly address: Address, readonly init?: { code: Cell, data: Cell }) {} }
-

Notice a few interesting things about this TypeScript code. First, it depends on the package ton-core instead of ton, which contains a small subset of base types and is therefore slower to change - an important feature when building a stable interface for our contract. Second, the code that creates the data cell mimics the FunC API and is almost identical to our save_data() FunC function. Third, we can see the derivation of the contract address from the code cell and data cell using the function contractAddress.

+

Notice a few interesting things about this TypeScript code. First, it depends on the package @ton/core instead of ton, which contains a small subset of base types and is therefore slower to change - an important feature when building a stable interface for our contract. Second, the code that creates the data cell mimics the FunC API and is almost identical to our save_data() FunC function. Third, we can see the derivation of the contract address from the code cell and data cell using the function contractAddress.

The actual deployment involves sending the first message that will cause our contract to be deployed. We can piggyback any message that is directed towards our contract. This can even be the increment message with op #1, but we will do something simpler. We will just send some TON coins to our contract (an empty message) and piggyback that. Let's make this part of our interface. Add the function sendDeploy() to counter.ts - this function will send the deployment message:

// export default class Counter implements Contract {
 
@@ -253,7 +253,7 @@ 

Step 8: Deploy the contract on-chain

Create a new script deploy.ts that will use the interface class we just wrote:

import * as fs from "fs";
 import { getHttpEndpoint } from "@orbs-network/ton-access";
-import { mnemonicToWalletKey } from "ton-crypto";
+import { mnemonicToWalletKey } from "@ton/crypto";
 import { TonClient, Cell, WalletContractV4 } from "ton";
 import Counter from "./counter"; // this is the interface class from step 7
 
@@ -383,7 +383,7 @@ 

Interface class

Executing the send

The messages can be sent from any TON wallet, not necessarily the deployer wallet. Create a new script step10.ts and use your wallet to fund the send:

import { getHttpEndpoint } from "@orbs-network/ton-access";
-import { mnemonicToWalletKey } from "ton-crypto";
+import { mnemonicToWalletKey } from "@ton/crypto";
 import { TonClient, WalletContractV4, Address } from "ton";
 import Counter from "./counter"; // this is the interface class we just implemented
 
@@ -454,7 +454,7 @@ 

TON H

A smart contract is simply a computer program running on TON Blockchain - or more exactly its TVM (TON Virtual Machine). The contract is made of code (compiled TVM instructions) and data (persistent state) that are stored in some address on TON Blockchain.

-

In the world of blockchain, code is law, meaning that instead of lawyers and papers, computer instructions define in absolute terms the rules of interaction between the different users of the contract. Before enagaging with any smart contract as a user, you're expected to review its code and thus understand its terms of agreement. Accordingly, we'll make an effort to make our contract as easy to read as possible, so its users could understand what they're getting into.

+

In the world of blockchain, code is law, meaning that instead of lawyers and papers, computer instructions define in absolute terms the rules of interaction between the different users of the contract. Before engaging with any smart contract as a user, you're expected to review its code and thus understand its terms of agreement. Accordingly, we'll make an effort to make our contract as easy to read as possible, so its users could understand what they're getting into.

Dapps - decentralized applications

Smart contracts are a key part of decentralized apps - a special type of application invented in the blockchain era, that does not depend on any single entity to run it. Unlike the app Uber, for example, which depends on the company Uber Inc to run it - a decentralized Uber would allow riders and drivers to interact directly (order, pay for and fulfill rides) without any intermediary like Uber Inc. Dapps are also unstoppable - if we don't depend on anyone specific to run them, nobody can take them down.

Dapps on TON Blockchain are usually made of 2 main projects:

@@ -483,7 +483,7 @@

Step 3: Set up the project

In previous iterations of this tutorial we used to deal with binaries executables of the func and fift compilers, but those were platform specific (different binaries for Mac, Windows and Linux). Relying on func-js will make life easier since it's cross-platform. In general, using executable binaries in the TON ecosystem is obsolete.

And finally, run in terminal:

-
npm install ton ton-crypto ton-core
+
npm install @ton/ton @ton/crypto @ton/core
 

This will install a library that you should be familiar with - ton. We'll use it to deploy our contract and interact with it.

Step 4: Structuring our smart contract

@@ -554,7 +554,7 @@

Init arguments

Interface class

The recommended way to interact with contracts is to create a small TypeScript class that will implement the interaction interface with the contract. We would normally give it the same name, so create the file counter.ts and place it next to the FunC source counter.fc.

Use the following code in counter.ts to create the initial data cell for deployment:

-
import { Contract, ContractProvider, Sender, Address, Cell, contractAddress, beginCell } from "ton-core";
+
import { Contract, ContractProvider, Sender, Address, Cell, contractAddress, beginCell } from "@ton/core";
 
 export default class Counter implements Contract {
 
@@ -570,7 +570,7 @@ 

Interface class

constructor(readonly address: Address, readonly init?: { code: Cell, data: Cell }) {} }
-

Notice a few interesting things about this TypeScript code. First, it depends on the package ton-core instead of ton, which contains a small subset of base types and is therefore slower to change - an important feature when building a stable interface for our contract. Second, the code that creates the data cell mimics the FunC API and is almost identical to our save_data() FunC function. Third, we can see the derivation of the contract address from the code cell and data cell using the function contractAddress.

+

Notice a few interesting things about this TypeScript code. First, it depends on the package @ton/core instead of ton, which contains a small subset of base types and is therefore slower to change - an important feature when building a stable interface for our contract. Second, the code that creates the data cell mimics the FunC API and is almost identical to our save_data() FunC function. Third, we can see the derivation of the contract address from the code cell and data cell using the function contractAddress.

The actual deployment involves sending the first message that will cause our contract to be deployed. We can piggyback any message that is directed towards our contract. This can even be the increment message with op #1, but we will do something simpler. We will just send some TON coins to our contract (an empty message) and piggyback that. Let's make this part of our interface. Add the function sendDeploy() to counter.ts - this function will send the deployment message:

// export default class Counter implements Contract {
 
@@ -595,7 +595,7 @@ 

Step 8: Deploy the contract on-chain

Create a new script deploy.ts that will use the interface class we just wrote:

import * as fs from "fs";
 import { getHttpEndpoint } from "@orbs-network/ton-access";
-import { mnemonicToWalletKey } from "ton-crypto";
+import { mnemonicToWalletKey } from "@ton/crypto";
 import { TonClient, Cell, WalletContractV4 } from "ton";
 import Counter from "./counter"; // this is the interface class from step 7
 
@@ -725,7 +725,7 @@ 

Interface class

Executing the send

The messages can be sent from any TON wallet, not necessarily the deployer wallet. Create a new script step10.ts and use your wallet to fund the send:

import { getHttpEndpoint } from "@orbs-network/ton-access";
-import { mnemonicToWalletKey } from "ton-crypto";
+import { mnemonicToWalletKey } from "@ton/crypto";
 import { TonClient, WalletContractV4, Address } from "ton";
 import Counter from "./counter"; // this is the interface class we just implemented
 
diff --git a/docs/02-contract/mainnet-npmton.html b/docs/02-contract/mainnet-npmton.html
index b713772..3164da5 100644
--- a/docs/02-contract/mainnet-npmton.html
+++ b/docs/02-contract/mainnet-npmton.html
@@ -1,6 +1,6 @@
 

TON Hello World part 2: Step by step guide for writing your first smart contract

A smart contract is simply a computer program running on TON Blockchain - or more exactly its TVM (TON Virtual Machine). The contract is made of code (compiled TVM instructions) and data (persistent state) that are stored in some address on TON Blockchain.

-

In the world of blockchain, code is law, meaning that instead of lawyers and papers, computer instructions define in absolute terms the rules of interaction between the different users of the contract. Before enagaging with any smart contract as a user, you're expected to review its code and thus understand its terms of agreement. Accordingly, we'll make an effort to make our contract as easy to read as possible, so its users could understand what they're getting into.

+

In the world of blockchain, code is law, meaning that instead of lawyers and papers, computer instructions define in absolute terms the rules of interaction between the different users of the contract. Before engaging with any smart contract as a user, you're expected to review its code and thus understand its terms of agreement. Accordingly, we'll make an effort to make our contract as easy to read as possible, so its users could understand what they're getting into.

Dapps - decentralized applications

Smart contracts are a key part of decentralized apps - a special type of application invented in the blockchain era, that does not depend on any single entity to run it. Unlike the app Uber, for example, which depends on the company Uber Inc to run it - a decentralized Uber would allow riders and drivers to interact directly (order, pay for and fulfill rides) without any intermediary like Uber Inc. Dapps are also unstoppable - if we don't depend on anyone specific to run them, nobody can take them down.

Dapps on TON Blockchain are usually made of 2 main projects:

@@ -29,7 +29,7 @@

Step 3: Set up the project

In previous iterations of this tutorial we used to deal with binaries executables of the func and fift compilers, but those were platform specific (different binaries for Mac, Windows and Linux). Relying on func-js will make life easier since it's cross-platform. In general, using executable binaries in the TON ecosystem is obsolete.

And finally, run in terminal:

-
npm install ton ton-crypto ton-core
+
npm install @ton/ton @ton/crypto @ton/core
 

This will install a library that you should be familiar with - ton. We'll use it to deploy our contract and interact with it.

Step 4: Structuring our smart contract

@@ -100,7 +100,7 @@

Init arguments

Interface class

The recommended way to interact with contracts is to create a small TypeScript class that will implement the interaction interface with the contract. We would normally give it the same name, so create the file counter.ts and place it next to the FunC source counter.fc.

Use the following code in counter.ts to create the initial data cell for deployment:

-
import { Contract, ContractProvider, Sender, Address, Cell, contractAddress, beginCell } from "ton-core";
+
import { Contract, ContractProvider, Sender, Address, Cell, contractAddress, beginCell } from "@ton/core";
 
 export default class Counter implements Contract {
 
@@ -116,7 +116,7 @@ 

Interface class

constructor(readonly address: Address, readonly init?: { code: Cell, data: Cell }) {} }
-

Notice a few interesting things about this TypeScript code. First, it depends on the package ton-core instead of ton, which contains a small subset of base types and is therefore slower to change - an important feature when building a stable interface for our contract. Second, the code that creates the data cell mimics the FunC API and is almost identical to our save_data() FunC function. Third, we can see the derivation of the contract address from the code cell and data cell using the function contractAddress.

+

Notice a few interesting things about this TypeScript code. First, it depends on the package @ton/core instead of ton, which contains a small subset of base types and is therefore slower to change - an important feature when building a stable interface for our contract. Second, the code that creates the data cell mimics the FunC API and is almost identical to our save_data() FunC function. Third, we can see the derivation of the contract address from the code cell and data cell using the function contractAddress.

The actual deployment involves sending the first message that will cause our contract to be deployed. We can piggyback any message that is directed towards our contract. This can even be the increment message with op #1, but we will do something simpler. We will just send some TON coins to our contract (an empty message) and piggyback that. Let's make this part of our interface. Add the function sendDeploy() to counter.ts - this function will send the deployment message:

// export default class Counter implements Contract {
 
@@ -141,7 +141,7 @@ 

Step 8: Deploy the contract on-chain

Create a new script deploy.ts that will use the interface class we just wrote:

import * as fs from "fs";
 import { getHttpEndpoint } from "@orbs-network/ton-access";
-import { mnemonicToWalletKey } from "ton-crypto";
+import { mnemonicToWalletKey } from "@ton/crypto";
 import { TonClient, Cell, WalletContractV4 } from "ton";
 import Counter from "./counter"; // this is the interface class from step 7
 
@@ -271,7 +271,7 @@ 

Interface class

Executing the send

The messages can be sent from any TON wallet, not necessarily the deployer wallet. Create a new script step10.ts and use your wallet to fund the send:

import { getHttpEndpoint } from "@orbs-network/ton-access";
-import { mnemonicToWalletKey } from "ton-crypto";
+import { mnemonicToWalletKey } from "@ton/crypto";
 import { TonClient, WalletContractV4, Address } from "ton";
 import Counter from "./counter"; // this is the interface class we just implemented
 
diff --git a/docs/02-contract/mainnet-npmton.md b/docs/02-contract/mainnet-npmton.md
index c4aff97..326c79c 100644
--- a/docs/02-contract/mainnet-npmton.md
+++ b/docs/02-contract/mainnet-npmton.md
@@ -3,7 +3,7 @@
 
 A smart contract is simply a computer program running on TON Blockchain - or more exactly its [TVM](https://ton-blockchain.github.io/docs/tvm.pdf) (TON Virtual Machine). The contract is made of code (compiled TVM instructions) and data (persistent state) that are stored in some address on TON Blockchain.
 
-In the world of blockchain, *code is law*, meaning that instead of lawyers and papers, computer instructions define in absolute terms the rules of interaction between the different users of the contract. Before enagaging with any smart contract as a user, you're expected to review its code and thus understand its terms of agreement. Accordingly, we'll make an effort to make our contract as easy to read as possible, so its users could understand what they're getting into.
+In the world of blockchain, *code is law*, meaning that instead of lawyers and papers, computer instructions define in absolute terms the rules of interaction between the different users of the contract. Before engaging with any smart contract as a user, you're expected to review its code and thus understand its terms of agreement. Accordingly, we'll make an effort to make our contract as easy to read as possible, so its users could understand what they're getting into.
 
 ## Dapps - decentralized applications
 
@@ -54,7 +54,7 @@ This will install the package [func-js](https://github.com/ton-community/func-js
 And finally, run in terminal:
 
 ```console
-npm install ton ton-crypto ton-core
+npm install @ton/ton @ton/crypto @ton/core
 ```
 
 This will install a library that you should be familiar with - [ton](https://www.npmjs.com/package/ton). We'll use it to deploy our contract and interact with it.
@@ -175,7 +175,7 @@ The recommended way to interact with contracts is to create a small TypeScript c
 Use the following code in `counter.ts` to create the initial data cell for deployment:
 
 ```ts
-import { Contract, ContractProvider, Sender, Address, Cell, contractAddress, beginCell } from "ton-core";
+import { Contract, ContractProvider, Sender, Address, Cell, contractAddress, beginCell } from "@ton/core";
 
 export default class Counter implements Contract {
 
@@ -192,7 +192,7 @@ export default class Counter implements Contract {
 }
 ```
 
-Notice a few interesting things about this TypeScript code. First, it depends on the package [ton-core](https://www.npmjs.com/package/ton-core) instead of [ton](https://www.npmjs.com/package/ton), which contains a small subset of base types and is therefore slower to change - an important feature when building a stable interface for our contract. Second, the code that creates the data cell mimics the FunC API and is almost identical to our `save_data()` FunC function. Third, we can see the derivation of the contract address from the code cell and data cell using the function `contractAddress`.
+Notice a few interesting things about this TypeScript code. First, it depends on the package [@ton/core](https://www.npmjs.com/package/@ton/core) instead of [ton](https://www.npmjs.com/package/ton), which contains a small subset of base types and is therefore slower to change - an important feature when building a stable interface for our contract. Second, the code that creates the data cell mimics the FunC API and is almost identical to our `save_data()` FunC function. Third, we can see the derivation of the contract address from the code cell and data cell using the function `contractAddress`.
 
 The actual deployment involves sending the first message that will cause our contract to be deployed. We can piggyback any message that is directed towards our contract. This can even be the increment message with op #1, but we will do something simpler. We will just send some TON coins to our contract (an empty message) and piggyback that. Let's make this part of our interface. Add the function `sendDeploy()` to `counter.ts` - this function will send the deployment message:
 
@@ -232,7 +232,7 @@ Create a new script `deploy.ts` that will use the interface class we just wrote:
 ```ts
 import * as fs from "fs";
 import { getHttpEndpoint } from "@orbs-network/ton-access";
-import { mnemonicToWalletKey } from "ton-crypto";
+import { mnemonicToWalletKey } from "@ton/crypto";
 import { TonClient, Cell, WalletContractV4 } from "ton";
 import Counter from "./counter"; // this is the interface class from step 7
 
@@ -401,7 +401,7 @@ The messages can be sent from any TON wallet, not necessarily the deployer walle
 
 ```ts
 import { getHttpEndpoint } from "@orbs-network/ton-access";
-import { mnemonicToWalletKey } from "ton-crypto";
+import { mnemonicToWalletKey } from "@ton/crypto";
 import { TonClient, WalletContractV4, Address } from "ton";
 import Counter from "./counter"; // this is the interface class we just implemented
 
diff --git a/docs/02-contract/testnet-npmton.html b/docs/02-contract/testnet-npmton.html
index 24a6042..852310f 100644
--- a/docs/02-contract/testnet-npmton.html
+++ b/docs/02-contract/testnet-npmton.html
@@ -1,6 +1,6 @@
 

TON Hello World part 2: Step by step guide for writing your first smart contract

A smart contract is simply a computer program running on TON Blockchain - or more exactly its TVM (TON Virtual Machine). The contract is made of code (compiled TVM instructions) and data (persistent state) that are stored in some address on TON Blockchain.

-

In the world of blockchain, code is law, meaning that instead of lawyers and papers, computer instructions define in absolute terms the rules of interaction between the different users of the contract. Before enagaging with any smart contract as a user, you're expected to review its code and thus understand its terms of agreement. Accordingly, we'll make an effort to make our contract as easy to read as possible, so its users could understand what they're getting into.

+

In the world of blockchain, code is law, meaning that instead of lawyers and papers, computer instructions define in absolute terms the rules of interaction between the different users of the contract. Before engaging with any smart contract as a user, you're expected to review its code and thus understand its terms of agreement. Accordingly, we'll make an effort to make our contract as easy to read as possible, so its users could understand what they're getting into.

Dapps - decentralized applications

Smart contracts are a key part of decentralized apps - a special type of application invented in the blockchain era, that does not depend on any single entity to run it. Unlike the app Uber, for example, which depends on the company Uber Inc to run it - a decentralized Uber would allow riders and drivers to interact directly (order, pay for and fulfill rides) without any intermediary like Uber Inc. Dapps are also unstoppable - if we don't depend on anyone specific to run them, nobody can take them down.

Dapps on TON Blockchain are usually made of 2 main projects:

@@ -29,7 +29,7 @@

Step 3: Set up the project

In previous iterations of this tutorial we used to deal with binaries executables of the func and fift compilers, but those were platform specific (different binaries for Mac, Windows and Linux). Relying on func-js will make life easier since it's cross-platform. In general, using executable binaries in the TON ecosystem is obsolete.

And finally, run in terminal:

-
npm install ton ton-crypto ton-core
+
npm install @ton/ton @ton/crypto @ton/core
 

This will install a library that you should be familiar with - ton. We'll use it to deploy our contract and interact with it.

Step 4: Structuring our smart contract

@@ -100,7 +100,7 @@

Init arguments

Interface class

The recommended way to interact with contracts is to create a small TypeScript class that will implement the interaction interface with the contract. We would normally give it the same name, so create the file counter.ts and place it next to the FunC source counter.fc.

Use the following code in counter.ts to create the initial data cell for deployment:

-
import { Contract, ContractProvider, Sender, Address, Cell, contractAddress, beginCell } from "ton-core";
+
import { Contract, ContractProvider, Sender, Address, Cell, contractAddress, beginCell } from "@ton/core";
 
 export default class Counter implements Contract {
 
@@ -116,7 +116,7 @@ 

Interface class

constructor(readonly address: Address, readonly init?: { code: Cell, data: Cell }) {} }
-

Notice a few interesting things about this TypeScript code. First, it depends on the package ton-core instead of ton, which contains a small subset of base types and is therefore slower to change - an important feature when building a stable interface for our contract. Second, the code that creates the data cell mimics the FunC API and is almost identical to our save_data() FunC function. Third, we can see the derivation of the contract address from the code cell and data cell using the function contractAddress.

+

Notice a few interesting things about this TypeScript code. First, it depends on the package @ton/core instead of ton, which contains a small subset of base types and is therefore slower to change - an important feature when building a stable interface for our contract. Second, the code that creates the data cell mimics the FunC API and is almost identical to our save_data() FunC function. Third, we can see the derivation of the contract address from the code cell and data cell using the function contractAddress.

The actual deployment involves sending the first message that will cause our contract to be deployed. We can piggyback any message that is directed towards our contract. This can even be the increment message with op #1, but we will do something simpler. We will just send some TON coins to our contract (an empty message) and piggyback that. Let's make this part of our interface. Add the function sendDeploy() to counter.ts - this function will send the deployment message:

// export default class Counter implements Contract {
 
@@ -141,7 +141,7 @@ 

Step 8: Deploy the contract on-chain

Create a new script deploy.ts that will use the interface class we just wrote:

import * as fs from "fs";
 import { getHttpEndpoint } from "@orbs-network/ton-access";
-import { mnemonicToWalletKey } from "ton-crypto";
+import { mnemonicToWalletKey } from "@ton/crypto";
 import { TonClient, Cell, WalletContractV4 } from "ton";
 import Counter from "./counter"; // this is the interface class from step 7
 
@@ -271,7 +271,7 @@ 

Interface class

Executing the send

The messages can be sent from any TON wallet, not necessarily the deployer wallet. Create a new script step10.ts and use your wallet to fund the send:

import { getHttpEndpoint } from "@orbs-network/ton-access";
-import { mnemonicToWalletKey } from "ton-crypto";
+import { mnemonicToWalletKey } from "@ton/crypto";
 import { TonClient, WalletContractV4, Address } from "ton";
 import Counter from "./counter"; // this is the interface class we just implemented
 
diff --git a/docs/02-contract/testnet-npmton.md b/docs/02-contract/testnet-npmton.md
index c5f1d0b..112bce4 100644
--- a/docs/02-contract/testnet-npmton.md
+++ b/docs/02-contract/testnet-npmton.md
@@ -3,7 +3,7 @@
 
 A smart contract is simply a computer program running on TON Blockchain - or more exactly its [TVM](https://ton-blockchain.github.io/docs/tvm.pdf) (TON Virtual Machine). The contract is made of code (compiled TVM instructions) and data (persistent state) that are stored in some address on TON Blockchain.
 
-In the world of blockchain, *code is law*, meaning that instead of lawyers and papers, computer instructions define in absolute terms the rules of interaction between the different users of the contract. Before enagaging with any smart contract as a user, you're expected to review its code and thus understand its terms of agreement. Accordingly, we'll make an effort to make our contract as easy to read as possible, so its users could understand what they're getting into.
+In the world of blockchain, *code is law*, meaning that instead of lawyers and papers, computer instructions define in absolute terms the rules of interaction between the different users of the contract. Before engaging with any smart contract as a user, you're expected to review its code and thus understand its terms of agreement. Accordingly, we'll make an effort to make our contract as easy to read as possible, so its users could understand what they're getting into.
 
 ## Dapps - decentralized applications
 
@@ -54,7 +54,7 @@ This will install the package [func-js](https://github.com/ton-community/func-js
 And finally, run in terminal:
 
 ```console
-npm install ton ton-crypto ton-core
+npm install @ton/ton @ton/crypto @ton/core
 ```
 
 This will install a library that you should be familiar with - [ton](https://www.npmjs.com/package/ton). We'll use it to deploy our contract and interact with it.
@@ -175,7 +175,7 @@ The recommended way to interact with contracts is to create a small TypeScript c
 Use the following code in `counter.ts` to create the initial data cell for deployment:
 
 ```ts
-import { Contract, ContractProvider, Sender, Address, Cell, contractAddress, beginCell } from "ton-core";
+import { Contract, ContractProvider, Sender, Address, Cell, contractAddress, beginCell } from "@ton/core";
 
 export default class Counter implements Contract {
 
@@ -192,7 +192,7 @@ export default class Counter implements Contract {
 }
 ```
 
-Notice a few interesting things about this TypeScript code. First, it depends on the package [ton-core](https://www.npmjs.com/package/ton-core) instead of [ton](https://www.npmjs.com/package/ton), which contains a small subset of base types and is therefore slower to change - an important feature when building a stable interface for our contract. Second, the code that creates the data cell mimics the FunC API and is almost identical to our `save_data()` FunC function. Third, we can see the derivation of the contract address from the code cell and data cell using the function `contractAddress`.
+Notice a few interesting things about this TypeScript code. First, it depends on the package [@ton/core](https://www.npmjs.com/package/@ton/core) instead of [ton](https://www.npmjs.com/package/ton), which contains a small subset of base types and is therefore slower to change - an important feature when building a stable interface for our contract. Second, the code that creates the data cell mimics the FunC API and is almost identical to our `save_data()` FunC function. Third, we can see the derivation of the contract address from the code cell and data cell using the function `contractAddress`.
 
 The actual deployment involves sending the first message that will cause our contract to be deployed. We can piggyback any message that is directed towards our contract. This can even be the increment message with op #1, but we will do something simpler. We will just send some TON coins to our contract (an empty message) and piggyback that. Let's make this part of our interface. Add the function `sendDeploy()` to `counter.ts` - this function will send the deployment message:
 
@@ -232,7 +232,7 @@ Create a new script `deploy.ts` that will use the interface class we just wrote:
 ```ts
 import * as fs from "fs";
 import { getHttpEndpoint } from "@orbs-network/ton-access";
-import { mnemonicToWalletKey } from "ton-crypto";
+import { mnemonicToWalletKey } from "@ton/crypto";
 import { TonClient, Cell, WalletContractV4 } from "ton";
 import Counter from "./counter"; // this is the interface class from step 7
 
@@ -401,7 +401,7 @@ The messages can be sent from any TON wallet, not necessarily the deployer walle
 
 ```ts
 import { getHttpEndpoint } from "@orbs-network/ton-access";
-import { mnemonicToWalletKey } from "ton-crypto";
+import { mnemonicToWalletKey } from "@ton/crypto";
 import { TonClient, WalletContractV4, Address } from "ton";
 import Counter from "./counter"; // this is the interface class we just implemented
 
diff --git a/docs/03-client/index.html b/docs/03-client/index.html
index 86dce98..ab69b4d 100644
--- a/docs/03-client/index.html
+++ b/docs/03-client/index.html
@@ -131,7 +131,7 @@ 

Step 3: Set up the project

npm install

We will need to install a few more packages that will allow us to interact with TON Blockchain. We've seen these packages in action in the previous tutorial. Run the following in terminal:

-
npm install ton ton-core ton-crypto
+
npm install @ton/ton @ton/core @ton/crypto
 npm install @orbs-network/ton-access
 

Last but not least, we will need to overcome ton library's reliance on Nodejs Buffer that isn't available in the browser. We can do that by installing a polyfill. Run the following in terminal:

@@ -233,7 +233,7 @@

Step 6: Read the counter value fro import Counter from '../contracts/counter'; import { useTonClient } from './useTonClient'; import { useAsyncInitialize } from './useAsyncInitialize'; -import { Address, OpenedContract } from 'ton-core'; +import { Address, OpenedContract } from '@ton/core'; export function useCounterContract() { const client = useTonClient(); @@ -299,10 +299,10 @@

Step 6: Read the counter value fro

If you have network connectivity issues and get errors like backend nodes unhealthy or timeouts, please join the Telegram support chat for TON access to get assistance.

Step 7: Increment the counter on-chain

The last interaction was read-only, let's change the contract state by sending a transaction. The main action our counter contract supports is increment. Let's add a button to the main screen that sends this transaction. As you recall, sending a transaction on-chain costs gas, so we would expect the wallet to approve this action with the user and show how much TON coin will be spent.

-

Before starting, we're going a add another hook that will generate a sender object from the TON Connect interface. This sender represents the connected wallet and will allow us to send transactions on their behalf. While we're at it, we'll also expose the wallet connection state so we can alter the UI accordingly.

+

Before starting, we're going to add another hook that will generate a sender object from the TON Connect interface. This sender represents the connected wallet and will allow us to send transactions on their behalf. While we're at it, we'll also expose the wallet connection state so we can alter the UI accordingly.

Create the file src/hooks/useTonConnect.ts with the following content:

import { useTonConnectUI } from '@tonconnect/ui-react';
-import { Sender, SenderArguments } from 'ton-core';
+import { Sender, SenderArguments } from '@ton/core';
 
 export function useTonConnect(): { sender: Sender; connected: boolean } {
   const [tonConnectUI] = useTonConnectUI();
@@ -333,7 +333,7 @@ 

Step 7: Increment the counter on-chain< import { useTonClient } from './useTonClient'; import { useAsyncInitialize } from './useAsyncInitialize'; import { useTonConnect } from './useTonConnect'; -import { Address, OpenedContract } from 'ton-core'; +import { Address, OpenedContract } from '@ton/core'; export function useCounterContract() { const client = useTonClient(); @@ -416,7 +416,7 @@

Step 7: Increment the counter on-chain<

Then refresh the web browser viewing the URL shown on-screen. You should see a new "Increment" link on the bottom of the screen. I'm assuming that you're still on desktop, make a note of the counter value and click the link.

Since your mobile Tonkeeper wallet is connected, this action should reach the Tonkeeper mobile app and cause it to display a confirmation dialog. Notice that this dialog shows the gas cost of the transaction. Approve the transaction on the mobile app. Since the app and wallet are connected, your approval should reach the app and cause it to display an indication that the transaction was sent. As you recall, new transactions must wait until they're included in a block, so this should take 5-10 seconds.

-

If everything is working, the counter value on screen should refresh automatically and you should a value that his higher by one.

+

If everything is working, the counter value on screen should refresh automatically and you should see a value that is higher by one.

Step 8: Style the app

Functionally our app is working, but we can definitely improve what it looks like. Giving a polished user experience is particularly important on TON Blockchain. We are aiming to reach mass adoption and the next billion users. We won't succeed unless our apps look as polished as the ones these users are already using.

Replace src/index.css with the following content:

@@ -592,7 +592,7 @@

Step 3: Set up the project

npm install

We will need to install a few more packages that will allow us to interact with TON Blockchain. We've seen these packages in action in the previous tutorial. Run the following in terminal:

-
npm install ton ton-core ton-crypto
+
npm install @ton/ton @ton/core @ton/crypto
 npm install @orbs-network/ton-access
 

Last but not least, we will need to overcome ton library's reliance on Nodejs Buffer that isn't available in the browser. We can do that by installing a polyfill. Run the following in terminal:

@@ -694,7 +694,7 @@

Step 6: Read the counter value fro import Counter from '../contracts/counter'; import { useTonClient } from './useTonClient'; import { useAsyncInitialize } from './useAsyncInitialize'; -import { Address, OpenedContract } from 'ton-core'; +import { Address, OpenedContract } from '@ton/core'; export function useCounterContract() { const client = useTonClient(); @@ -760,10 +760,10 @@

Step 6: Read the counter value fro

If you have network connectivity issues and get errors like backend nodes unhealthy or timeouts, please join the Telegram support chat for TON access to get assistance.

Step 7: Increment the counter on-chain

The last interaction was read-only, let's change the contract state by sending a transaction. The main action our counter contract supports is increment. Let's add a button to the main screen that sends this transaction. As you recall, sending a transaction on-chain costs gas, so we would expect the wallet to approve this action with the user and show how much TON coin will be spent.

-

Before starting, we're going a add another hook that will generate a sender object from the TON Connect interface. This sender represents the connected wallet and will allow us to send transactions on their behalf. While we're at it, we'll also expose the wallet connection state so we can alter the UI accordingly.

+

Before starting, we're going to add another hook that will generate a sender object from the TON Connect interface. This sender represents the connected wallet and will allow us to send transactions on their behalf. While we're at it, we'll also expose the wallet connection state so we can alter the UI accordingly.

Create the file src/hooks/useTonConnect.ts with the following content:

import { useTonConnectUI } from '@tonconnect/ui-react';
-import { Sender, SenderArguments } from 'ton-core';
+import { Sender, SenderArguments } from '@ton/core';
 
 export function useTonConnect(): { sender: Sender; connected: boolean } {
   const [tonConnectUI] = useTonConnectUI();
@@ -794,7 +794,7 @@ 

Step 7: Increment the counter on-chain< import { useTonClient } from './useTonClient'; import { useAsyncInitialize } from './useAsyncInitialize'; import { useTonConnect } from './useTonConnect'; -import { Address, OpenedContract } from 'ton-core'; +import { Address, OpenedContract } from '@ton/core'; export function useCounterContract() { const client = useTonClient(); @@ -877,7 +877,7 @@

Step 7: Increment the counter on-chain<

Then refresh the web browser viewing the URL shown on-screen. You should see a new "Increment" link on the bottom of the screen. I'm assuming that you're still on desktop, make a note of the counter value and click the link.

Since your mobile Tonkeeper wallet is connected, this action should reach the Tonkeeper mobile app and cause it to display a confirmation dialog. Notice that this dialog shows the gas cost of the transaction. Approve the transaction on the mobile app. Since the app and wallet are connected, your approval should reach the app and cause it to display an indication that the transaction was sent. As you recall, new transactions must wait until they're included in a block, so this should take 5-10 seconds.

-

If everything is working, the counter value on screen should refresh automatically and you should a value that his higher by one.

+

If everything is working, the counter value on screen should refresh automatically and you should see a value that is higher by one.

Step 8: Style the app

Functionally our app is working, but we can definitely improve what it looks like. Giving a polished user experience is particularly important on TON Blockchain. We are aiming to reach mass adoption and the next billion users. We won't succeed unless our apps look as polished as the ones these users are already using.

Replace src/index.css with the following content:

diff --git a/docs/03-client/mainnet-npmton.html b/docs/03-client/mainnet-npmton.html index 20d74b3..c908b43 100644 --- a/docs/03-client/mainnet-npmton.html +++ b/docs/03-client/mainnet-npmton.html @@ -19,7 +19,7 @@

Step 3: Set up the project

npm install

We will need to install a few more packages that will allow us to interact with TON Blockchain. We've seen these packages in action in the previous tutorial. Run the following in terminal:

-
npm install ton ton-core ton-crypto
+
npm install @ton/ton @ton/core @ton/crypto
 npm install @orbs-network/ton-access
 

Last but not least, we will need to overcome ton library's reliance on Nodejs Buffer that isn't available in the browser. We can do that by installing a polyfill. Run the following in terminal:

@@ -121,7 +121,7 @@

Step 6: Read the counter value fro import Counter from '../contracts/counter'; import { useTonClient } from './useTonClient'; import { useAsyncInitialize } from './useAsyncInitialize'; -import { Address, OpenedContract } from 'ton-core'; +import { Address, OpenedContract } from '@ton/core'; export function useCounterContract() { const client = useTonClient(); @@ -187,10 +187,10 @@

Step 6: Read the counter value fro

If you have network connectivity issues and get errors like backend nodes unhealthy or timeouts, please join the Telegram support chat for TON access to get assistance.

Step 7: Increment the counter on-chain

The last interaction was read-only, let's change the contract state by sending a transaction. The main action our counter contract supports is increment. Let's add a button to the main screen that sends this transaction. As you recall, sending a transaction on-chain costs gas, so we would expect the wallet to approve this action with the user and show how much TON coin will be spent.

-

Before starting, we're going a add another hook that will generate a sender object from the TON Connect interface. This sender represents the connected wallet and will allow us to send transactions on their behalf. While we're at it, we'll also expose the wallet connection state so we can alter the UI accordingly.

+

Before starting, we're going to add another hook that will generate a sender object from the TON Connect interface. This sender represents the connected wallet and will allow us to send transactions on their behalf. While we're at it, we'll also expose the wallet connection state so we can alter the UI accordingly.

Create the file src/hooks/useTonConnect.ts with the following content:

import { useTonConnectUI } from '@tonconnect/ui-react';
-import { Sender, SenderArguments } from 'ton-core';
+import { Sender, SenderArguments } from '@ton/core';
 
 export function useTonConnect(): { sender: Sender; connected: boolean } {
   const [tonConnectUI] = useTonConnectUI();
@@ -221,7 +221,7 @@ 

Step 7: Increment the counter on-chain< import { useTonClient } from './useTonClient'; import { useAsyncInitialize } from './useAsyncInitialize'; import { useTonConnect } from './useTonConnect'; -import { Address, OpenedContract } from 'ton-core'; +import { Address, OpenedContract } from '@ton/core'; export function useCounterContract() { const client = useTonClient(); @@ -304,7 +304,7 @@

Step 7: Increment the counter on-chain<

Then refresh the web browser viewing the URL shown on-screen. You should see a new "Increment" link on the bottom of the screen. I'm assuming that you're still on desktop, make a note of the counter value and click the link.

Since your mobile Tonkeeper wallet is connected, this action should reach the Tonkeeper mobile app and cause it to display a confirmation dialog. Notice that this dialog shows the gas cost of the transaction. Approve the transaction on the mobile app. Since the app and wallet are connected, your approval should reach the app and cause it to display an indication that the transaction was sent. As you recall, new transactions must wait until they're included in a block, so this should take 5-10 seconds.

-

If everything is working, the counter value on screen should refresh automatically and you should a value that his higher by one.

+

If everything is working, the counter value on screen should refresh automatically and you should see a value that is higher by one.

Step 8: Style the app

Functionally our app is working, but we can definitely improve what it looks like. Giving a polished user experience is particularly important on TON Blockchain. We are aiming to reach mass adoption and the next billion users. We won't succeed unless our apps look as polished as the ones these users are already using.

Replace src/index.css with the following content:

diff --git a/docs/03-client/mainnet-npmton.md b/docs/03-client/mainnet-npmton.md index 309356a..d31bb97 100644 --- a/docs/03-client/mainnet-npmton.md +++ b/docs/03-client/mainnet-npmton.md @@ -38,7 +38,7 @@ npm install We will need to install a few more packages that will allow us to interact with TON Blockchain. We've seen these packages in action in the previous tutorial. Run the following in terminal: ```console -npm install ton ton-core ton-crypto +npm install @ton/ton @ton/core @ton/crypto npm install @orbs-network/ton-access ``` @@ -184,7 +184,7 @@ import { useEffect, useState } from 'react'; import Counter from '../contracts/counter'; import { useTonClient } from './useTonClient'; import { useAsyncInitialize } from './useAsyncInitialize'; -import { Address, OpenedContract } from 'ton-core'; +import { Address, OpenedContract } from '@ton/core'; export function useCounterContract() { const client = useTonClient(); @@ -261,13 +261,13 @@ If you have network connectivity issues and get errors like backend nodes unheal The last interaction was read-only, let's change the contract state by sending a transaction. The main action our counter contract supports is *increment*. Let's add a button to the main screen that sends this transaction. As you recall, sending a transaction on-chain costs gas, so we would expect the wallet to approve this action with the user and show how much TON coin will be spent. -Before starting, we're going a add another hook that will generate a `sender` object from the TON Connect interface. This sender represents the connected wallet and will allow us to send transactions on their behalf. While we're at it, we'll also expose the wallet connection state so we can alter the UI accordingly. +Before starting, we're going to add another hook that will generate a `sender` object from the TON Connect interface. This sender represents the connected wallet and will allow us to send transactions on their behalf. While we're at it, we'll also expose the wallet connection state so we can alter the UI accordingly. Create the file `src/hooks/useTonConnect.ts` with the following content: ```ts import { useTonConnectUI } from '@tonconnect/ui-react'; -import { Sender, SenderArguments } from 'ton-core'; +import { Sender, SenderArguments } from '@ton/core'; export function useTonConnect(): { sender: Sender; connected: boolean } { const [tonConnectUI] = useTonConnectUI(); @@ -302,7 +302,7 @@ import Counter from '../contracts/counter'; import { useTonClient } from './useTonClient'; import { useAsyncInitialize } from './useAsyncInitialize'; import { useTonConnect } from './useTonConnect'; -import { Address, OpenedContract } from 'ton-core'; +import { Address, OpenedContract } from '@ton/core'; export function useCounterContract() { const client = useTonClient(); @@ -394,7 +394,7 @@ Then refresh the web browser viewing the URL shown on-screen. You should see a n Since your mobile Tonkeeper wallet is connected, this action should reach the Tonkeeper mobile app and cause it to display a confirmation dialog. Notice that this dialog shows the gas cost of the transaction. Approve the transaction on the mobile app. Since the app and wallet are connected, your approval should reach the app and cause it to display an indication that the transaction was sent. As you recall, new transactions must wait until they're included in a block, so this should take 5-10 seconds. -If everything is working, the counter value on screen should refresh automatically and you should a value that his higher by one. +If everything is working, the counter value on screen should refresh automatically and you should see a value that is higher by one. ## Step 8: Style the app diff --git a/docs/03-client/testnet-npmton.html b/docs/03-client/testnet-npmton.html index edcfbb3..9107082 100644 --- a/docs/03-client/testnet-npmton.html +++ b/docs/03-client/testnet-npmton.html @@ -19,7 +19,7 @@

Step 3: Set up the project

npm install

We will need to install a few more packages that will allow us to interact with TON Blockchain. We've seen these packages in action in the previous tutorial. Run the following in terminal:

-
npm install ton ton-core ton-crypto
+
npm install @ton/ton @ton/core @ton/crypto
 npm install @orbs-network/ton-access
 

Last but not least, we will need to overcome ton library's reliance on Nodejs Buffer that isn't available in the browser. We can do that by installing a polyfill. Run the following in terminal:

@@ -121,7 +121,7 @@

Step 6: Read the counter value fro import Counter from '../contracts/counter'; import { useTonClient } from './useTonClient'; import { useAsyncInitialize } from './useAsyncInitialize'; -import { Address, OpenedContract } from 'ton-core'; +import { Address, OpenedContract } from '@ton/core'; export function useCounterContract() { const client = useTonClient(); @@ -187,10 +187,10 @@

Step 6: Read the counter value fro

If you have network connectivity issues and get errors like backend nodes unhealthy or timeouts, please join the Telegram support chat for TON access to get assistance.

Step 7: Increment the counter on-chain

The last interaction was read-only, let's change the contract state by sending a transaction. The main action our counter contract supports is increment. Let's add a button to the main screen that sends this transaction. As you recall, sending a transaction on-chain costs gas, so we would expect the wallet to approve this action with the user and show how much TON coin will be spent.

-

Before starting, we're going a add another hook that will generate a sender object from the TON Connect interface. This sender represents the connected wallet and will allow us to send transactions on their behalf. While we're at it, we'll also expose the wallet connection state so we can alter the UI accordingly.

+

Before starting, we're going to add another hook that will generate a sender object from the TON Connect interface. This sender represents the connected wallet and will allow us to send transactions on their behalf. While we're at it, we'll also expose the wallet connection state so we can alter the UI accordingly.

Create the file src/hooks/useTonConnect.ts with the following content:

import { useTonConnectUI } from '@tonconnect/ui-react';
-import { Sender, SenderArguments } from 'ton-core';
+import { Sender, SenderArguments } from '@ton/core';
 
 export function useTonConnect(): { sender: Sender; connected: boolean } {
   const [tonConnectUI] = useTonConnectUI();
@@ -221,7 +221,7 @@ 

Step 7: Increment the counter on-chain< import { useTonClient } from './useTonClient'; import { useAsyncInitialize } from './useAsyncInitialize'; import { useTonConnect } from './useTonConnect'; -import { Address, OpenedContract } from 'ton-core'; +import { Address, OpenedContract } from '@ton/core'; export function useCounterContract() { const client = useTonClient(); @@ -304,7 +304,7 @@

Step 7: Increment the counter on-chain<

Then refresh the web browser viewing the URL shown on-screen. You should see a new "Increment" link on the bottom of the screen. I'm assuming that you're still on desktop, make a note of the counter value and click the link.

Since your mobile Tonkeeper wallet is connected, this action should reach the Tonkeeper mobile app and cause it to display a confirmation dialog. Notice that this dialog shows the gas cost of the transaction. Approve the transaction on the mobile app. Since the app and wallet are connected, your approval should reach the app and cause it to display an indication that the transaction was sent. As you recall, new transactions must wait until they're included in a block, so this should take 5-10 seconds.

-

If everything is working, the counter value on screen should refresh automatically and you should a value that his higher by one.

+

If everything is working, the counter value on screen should refresh automatically and you should see a value that is higher by one.

Step 8: Style the app

Functionally our app is working, but we can definitely improve what it looks like. Giving a polished user experience is particularly important on TON Blockchain. We are aiming to reach mass adoption and the next billion users. We won't succeed unless our apps look as polished as the ones these users are already using.

Replace src/index.css with the following content:

diff --git a/docs/03-client/testnet-npmton.md b/docs/03-client/testnet-npmton.md index 7cfe361..ad0d327 100644 --- a/docs/03-client/testnet-npmton.md +++ b/docs/03-client/testnet-npmton.md @@ -38,7 +38,7 @@ npm install We will need to install a few more packages that will allow us to interact with TON Blockchain. We've seen these packages in action in the previous tutorial. Run the following in terminal: ```console -npm install ton ton-core ton-crypto +npm install @ton/ton @ton/core @ton/crypto npm install @orbs-network/ton-access ``` @@ -184,7 +184,7 @@ import { useEffect, useState } from 'react'; import Counter from '../contracts/counter'; import { useTonClient } from './useTonClient'; import { useAsyncInitialize } from './useAsyncInitialize'; -import { Address, OpenedContract } from 'ton-core'; +import { Address, OpenedContract } from '@ton/core'; export function useCounterContract() { const client = useTonClient(); @@ -261,13 +261,13 @@ If you have network connectivity issues and get errors like backend nodes unheal The last interaction was read-only, let's change the contract state by sending a transaction. The main action our counter contract supports is *increment*. Let's add a button to the main screen that sends this transaction. As you recall, sending a transaction on-chain costs gas, so we would expect the wallet to approve this action with the user and show how much TON coin will be spent. -Before starting, we're going a add another hook that will generate a `sender` object from the TON Connect interface. This sender represents the connected wallet and will allow us to send transactions on their behalf. While we're at it, we'll also expose the wallet connection state so we can alter the UI accordingly. +Before starting, we're going to add another hook that will generate a `sender` object from the TON Connect interface. This sender represents the connected wallet and will allow us to send transactions on their behalf. While we're at it, we'll also expose the wallet connection state so we can alter the UI accordingly. Create the file `src/hooks/useTonConnect.ts` with the following content: ```ts import { useTonConnectUI } from '@tonconnect/ui-react'; -import { Sender, SenderArguments } from 'ton-core'; +import { Sender, SenderArguments } from '@ton/core'; export function useTonConnect(): { sender: Sender; connected: boolean } { const [tonConnectUI] = useTonConnectUI(); @@ -302,7 +302,7 @@ import Counter from '../contracts/counter'; import { useTonClient } from './useTonClient'; import { useAsyncInitialize } from './useAsyncInitialize'; import { useTonConnect } from './useTonConnect'; -import { Address, OpenedContract } from 'ton-core'; +import { Address, OpenedContract } from '@ton/core'; export function useCounterContract() { const client = useTonClient(); @@ -394,7 +394,7 @@ Then refresh the web browser viewing the URL shown on-screen. You should see a n Since your mobile Tonkeeper wallet is connected, this action should reach the Tonkeeper mobile app and cause it to display a confirmation dialog. Notice that this dialog shows the gas cost of the transaction. Approve the transaction on the mobile app. Since the app and wallet are connected, your approval should reach the app and cause it to display an indication that the transaction was sent. As you recall, new transactions must wait until they're included in a block, so this should take 5-10 seconds. -If everything is working, the counter value on screen should refresh automatically and you should a value that his higher by one. +If everything is working, the counter value on screen should refresh automatically and you should see a value that is higher by one. ## Step 8: Style the app diff --git a/docs/04-testing/index.html b/docs/04-testing/index.html index b78dc51..af8fd84 100644 --- a/docs/04-testing/index.html +++ b/docs/04-testing/index.html @@ -78,7 +78,7 @@

TON H -

Testing is a big part of smart contract development. Smart contracts often deal with money and we don't want any of our users losing money because the smart contract had a bug. This is why it's normally expected from smart contract devleopers to share an automated test suite next to their FunC implementation. Every user that wants to be convinced that the contract is working as expected is welcome to execute the test suite and see for themselves.

+

Testing is a big part of smart contract development. Smart contracts often deal with money and we don't want any of our users losing money because the smart contract had a bug. This is why it's normally expected from smart contract developers to share an automated test suite next to their FunC implementation. Every user that wants to be convinced that the contract is working as expected is welcome to execute the test suite and see for themselves.

A thorough test suite is also a good signal to your users that you've taken your role as a contract developer seriously. I would personally be very hesitant to deposit a substantial amount of money in any contract that has no tests. Since code is law, any bug in the contract code is also part of the agreement, so a user wouldn't really have anyone to blame for money lost, but themselves.

Personally, I don't view testing as an afterthought taking place only when your code is complete. If done correctly, tests can be a powerful aid to the development process itself from the beginning, that will allow you to write better code faster.

Oh so many ways to test

@@ -280,6 +280,7 @@

Step 5: Debug by dumping variables

We can see that the debug messages are printed when the test is running. When we send some TON coin explicitly to the contract (7.123 coins), we can see that the first debug print indeed shows the expected value of msg_value. Since the TVM doesn't support floating points, the number is represented internally as a large integer (with 9 decimals, meaning multiplied by 10^9). On the second test, when we send the increment op, we can see both debug prints showing. This is because this message also includes a small amount of coins for gas.

If you would like to see even more verbose log output from running your contracts, you can increase the verbosity of the blockchain object after creating it in beforeEach:

blockchain.verbosity = {
+  print: true,
   blockchainLogs: true,
   vmLogs: "vm_logs_full",
   debugLogs: true,
diff --git a/docs/04-testing/npmton.html b/docs/04-testing/npmton.html
index a214675..e0d2248 100644
--- a/docs/04-testing/npmton.html
+++ b/docs/04-testing/npmton.html
@@ -1,5 +1,5 @@
 

TON Hello World part 4: Step by step guide for testing your first smart contract

-

Testing is a big part of smart contract development. Smart contracts often deal with money and we don't want any of our users losing money because the smart contract had a bug. This is why it's normally expected from smart contract devleopers to share an automated test suite next to their FunC implementation. Every user that wants to be convinced that the contract is working as expected is welcome to execute the test suite and see for themselves.

+

Testing is a big part of smart contract development. Smart contracts often deal with money and we don't want any of our users losing money because the smart contract had a bug. This is why it's normally expected from smart contract developers to share an automated test suite next to their FunC implementation. Every user that wants to be convinced that the contract is working as expected is welcome to execute the test suite and see for themselves.

A thorough test suite is also a good signal to your users that you've taken your role as a contract developer seriously. I would personally be very hesitant to deposit a substantial amount of money in any contract that has no tests. Since code is law, any bug in the contract code is also part of the agreement, so a user wouldn't really have anyone to blame for money lost, but themselves.

Personally, I don't view testing as an afterthought taking place only when your code is complete. If done correctly, tests can be a powerful aid to the development process itself from the beginning, that will allow you to write better code faster.

Oh so many ways to test

@@ -201,6 +201,7 @@

Step 5: Debug by dumping variables

We can see that the debug messages are printed when the test is running. When we send some TON coin explicitly to the contract (7.123 coins), we can see that the first debug print indeed shows the expected value of msg_value. Since the TVM doesn't support floating points, the number is represented internally as a large integer (with 9 decimals, meaning multiplied by 10^9). On the second test, when we send the increment op, we can see both debug prints showing. This is because this message also includes a small amount of coins for gas.

If you would like to see even more verbose log output from running your contracts, you can increase the verbosity of the blockchain object after creating it in beforeEach:

blockchain.verbosity = {
+  print: true,
   blockchainLogs: true,
   vmLogs: "vm_logs_full",
   debugLogs: true,
diff --git a/docs/04-testing/npmton.md b/docs/04-testing/npmton.md
index 89850bd..f7256dc 100644
--- a/docs/04-testing/npmton.md
+++ b/docs/04-testing/npmton.md
@@ -1,7 +1,7 @@
 
 # TON Hello World part 4: Step by step guide for testing your first smart contract
 
-Testing is a big part of smart contract development. Smart contracts often deal with money and we don't want any of our users losing money because the smart contract had a bug. This is why it's normally expected from smart contract devleopers to share an automated test suite next to their FunC implementation. Every user that wants to be convinced that the contract is working as expected is welcome to execute the test suite and see for themselves.
+Testing is a big part of smart contract development. Smart contracts often deal with money and we don't want any of our users losing money because the smart contract had a bug. This is why it's normally expected from smart contract developers to share an automated test suite next to their FunC implementation. Every user that wants to be convinced that the contract is working as expected is welcome to execute the test suite and see for themselves.
 
 A thorough test suite is also a good signal to your users that you've taken your role as a contract developer seriously. I would personally be very hesitant to deposit a substantial amount of money in any contract that has no tests. Since *code is law*, any bug in the contract code is also part of the agreement, so a user wouldn't really have anyone to blame for money lost, but themselves.
 
@@ -300,6 +300,7 @@ If you would like to see even more verbose log output from running your contract
 
 ```ts
 blockchain.verbosity = {
+  print: true,
   blockchainLogs: true,
   vmLogs: "vm_logs_full",
   debugLogs: true,