Skip to content

Commit ada4528

Browse files
authored
Refactor TON network to use testcontainers-go (#1833)
feat: TON network support
1 parent 3db6234 commit ada4528

File tree

14 files changed

+781
-262
lines changed

14 files changed

+781
-262
lines changed

.github/workflows/framework-golden-tests.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,10 @@ jobs:
4343
config: smoke_solana.toml
4444
count: 1
4545
timeout: 10m
46+
- name: TestTonSmoke
47+
config: smoke_ton.toml
48+
count: 1
49+
timeout: 10m
4650
- name: TestUpgrade
4751
config: upgrade.toml
4852
count: 1

book/src/SUMMARY.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@
4646
- [Sui](framework/components/blockchains/sui.md)
4747
- [TRON](framework/components/blockchains/tron.md)
4848
- [ZKSync](framework/components/blockchains/zksync.md)
49+
- [Ton](framework/components/blockchains/ton.md)
4950
- [Optimism Stack]()
5051
- [Arbitrum Stack]()
5152
- [Chainlink](framework/components/chainlink.md)
Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
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).

framework/.changeset/v0.8.2.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
- TON Network support with testcontainers

framework/components/blockchain/blockchain.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ const (
1818
TypeAptos = "aptos"
1919
TypeSui = "sui"
2020
TypeTron = "tron"
21+
TypeTon = "ton"
2122
)
2223

2324
// Blockchain node family
@@ -27,12 +28,13 @@ const (
2728
FamilyAptos = "aptos"
2829
FamilySui = "sui"
2930
FamilyTron = "tron"
31+
FamilyTon = "ton"
3032
)
3133

3234
// Input is a blockchain network configuration params
3335
type Input struct {
3436
// Common EVM fields
35-
Type string `toml:"type" validate:"required,oneof=anvil geth besu solana aptos tron sui" envconfig:"net_type"`
37+
Type string `toml:"type" validate:"required,oneof=anvil geth besu solana aptos tron sui ton" envconfig:"net_type"`
3638
Image string `toml:"image"`
3739
PullImage bool `toml:"pull_image"`
3840
Port string `toml:"port"`
@@ -99,6 +101,8 @@ func NewBlockchainNetwork(in *Input) (*Output, error) {
99101
out, err = newTron(in)
100102
case TypeAnvilZKSync:
101103
out, err = newAnvilZksync(in)
104+
case TypeTon:
105+
out, err = newTon(in)
102106
default:
103107
return nil, fmt.Errorf("blockchain type is not supported or empty, must be 'anvil' or 'geth'")
104108
}

0 commit comments

Comments
 (0)