|
| 1 | +# TON Blockchain Client |
| 2 | + |
| 3 | +TON (The Open Network) support in the framework utilizes MyLocalTon Docker Compose environment to provide a local TON blockchain for testing purposes. |
| 4 | + |
| 5 | +## Configuration |
| 6 | + |
| 7 | +```toml |
| 8 | +[blockchain_a] |
| 9 | + type = "ton" |
| 10 | + image = "ghcr.io/neodix42/mylocalton-docker:latest" |
| 11 | +``` |
| 12 | + |
| 13 | +## Default Ports |
| 14 | + |
| 15 | +The TON implementation exposes several services: |
| 16 | + |
| 17 | +- TON Lite Server: Port 40004 |
| 18 | +- TON HTTP API: Port 8081 |
| 19 | +- TON Simple HTTP Server: Port 8000 |
| 20 | +- TON Explorer: Port 8080 |
| 21 | + |
| 22 | +> **Note**: By default, only the lite client service is exposed externally. Other services may need additional configuration to be accessible outside the Docker network. |
| 23 | +
|
| 24 | +## Validator Configuration |
| 25 | + |
| 26 | +By default, the MyLocalTon environment starts with only one validator enabled. If multiple validators are needed (up to 6 are supported), the Docker Compose file must be provided with modified version with corresponding service definition in toml file before starting the environment. |
| 27 | + |
| 28 | +## Usage |
| 29 | + |
| 30 | +```go |
| 31 | +package examples |
| 32 | + |
| 33 | +import ( |
| 34 | + "strings" |
| 35 | + "testing" |
| 36 | + |
| 37 | + "github.com/stretchr/testify/require" |
| 38 | + "github.com/xssnick/tonutils-go/liteclient" |
| 39 | + "github.com/xssnick/tonutils-go/ton" |
| 40 | + "github.com/xssnick/tonutils-go/ton/wallet" |
| 41 | + |
| 42 | + "github.com/smartcontractkit/chainlink-testing-framework/framework" |
| 43 | + "github.com/smartcontractkit/chainlink-testing-framework/framework/components/blockchain" |
| 44 | +) |
| 45 | + |
| 46 | +type CfgTon struct { |
| 47 | + BlockchainA *blockchain.Input `toml:"blockchain_a" validate:"required"` |
| 48 | +} |
| 49 | + |
| 50 | +func TestTonSmoke(t *testing.T) { |
| 51 | + in, err := framework.Load[CfgTon](t) |
| 52 | + require.NoError(t, err) |
| 53 | + |
| 54 | + bc, err := blockchain.NewBlockchainNetwork(in.BlockchainA) |
| 55 | + require.NoError(t, err) |
| 56 | + |
| 57 | + var client ton.APIClientWrapped |
| 58 | + |
| 59 | + t.Run("setup:connect", func(t *testing.T) { |
| 60 | + // Create a connection pool |
| 61 | + connectionPool := liteclient.NewConnectionPool() |
| 62 | + |
| 63 | + // Get the network configuration from the global config URL |
| 64 | + cfg, cferr := liteclient.GetConfigFromUrl(t.Context(), fmt.Sprintf("http://%s/localhost.global.config.json", bc.Nodes[0].ExternalHTTPUrl)) |
| 65 | + require.NoError(t, cferr, "Failed to get config from URL") |
| 66 | + |
| 67 | + // Add connections from the config |
| 68 | + caerr := connectionPool.AddConnectionsFromConfig(t.Context(), cfg) |
| 69 | + require.NoError(t, caerr, "Failed to add connections from config") |
| 70 | + |
| 71 | + // Create an API client with retry functionality |
| 72 | + client = ton.NewAPIClient(connectionPool).WithRetry() |
| 73 | + |
| 74 | + t.Run("setup:faucet", func(t *testing.T) { |
| 75 | + // Create a wallet from the pre-funded high-load wallet seed |
| 76 | + rawHlWallet, err := wallet.FromSeed(client, strings.Fields(blockchain.DefaultTonHlWalletMnemonic), wallet.HighloadV2Verified) |
| 77 | + require.NoError(t, err, "failed to create highload wallet") |
| 78 | + |
| 79 | + // Create a workchain -1 (masterchain) wallet |
| 80 | + mcFunderWallet, err := wallet.FromPrivateKeyWithOptions(client, rawHlWallet.PrivateKey(), wallet.HighloadV2Verified, wallet.WithWorkchain(-1)) |
| 81 | + require.NoError(t, err, "failed to create highload wallet") |
| 82 | + |
| 83 | + // Get subwallet with ID 42 |
| 84 | + funder, err := mcFunderWallet.GetSubwallet(uint32(42)) |
| 85 | + require.NoError(t, err, "failed to get highload subwallet") |
| 86 | + |
| 87 | + // Verify the funder address matches the expected default |
| 88 | + require.Equal(t, funder.Address().StringRaw(), blockchain.DefaultTonHlWalletAddress, "funder address mismatch") |
| 89 | + |
| 90 | + // Check the funder balance |
| 91 | + master, err := client.GetMasterchainInfo(t.Context()) |
| 92 | + require.NoError(t, err, "failed to get masterchain info for funder balance check") |
| 93 | + funderBalance, err := funder.GetBalance(t.Context(), master) |
| 94 | + require.NoError(t, err, "failed to get funder balance") |
| 95 | + require.Equal(t, funderBalance.Nano().String(), "1000000000000000", "funder balance mismatch") |
| 96 | + }) |
| 97 | + }) |
| 98 | +} |
| 99 | +``` |
| 100 | + |
| 101 | +## Test Private Keys |
| 102 | + |
| 103 | +The framework includes a pre-funded high-load wallet for testing purposes. This wallet type can send up to 254 messages per 1 external message, making it efficient for test scenarios. |
| 104 | + |
| 105 | +Default High-Load Wallet: |
| 106 | +``` |
| 107 | +Address: -1:5ee77ced0b7ae6ef88ab3f4350d8872c64667ffbe76073455215d3cdfab3294b |
| 108 | +Mnemonic: twenty unfair stay entry during please water april fabric morning length lumber style tomorrow melody similar forum width ride render void rather custom coin |
| 109 | +``` |
| 110 | + |
| 111 | +## Available Pre-funded Wallets |
| 112 | + |
| 113 | +MyLocalTon Docker environment comes with several pre-funded wallets that can be used for testing: |
| 114 | + |
| 115 | +1. Genesis Wallet (V3R2, WalletId: 42) |
| 116 | +2. Validator Wallets (1-5) (V3R2, WalletId: 42) |
| 117 | +3. Faucet Wallet (V3R2, WalletId: 42, Balance: 1 million TON) |
| 118 | +4. Faucet Highload Wallet (Highload V2, QueryId: 0, Balance: 1 million TON) |
| 119 | +5. Basechain Faucet Wallet (V3R2, WalletId: 42, Balance: 1 million TON) |
| 120 | +6. Basechain Faucet Highload Wallet (Highload V2, QueryId: 0, Balance: 1 million TON) |
| 121 | + |
| 122 | +For the complete list of addresses and mnemonics, refer to the [MyLocalTon Docker documentation](https://github.com/neodix42/mylocalton-docker). |
0 commit comments