Skip to content

Commit e5da6b4

Browse files
Wallet v5 support for generate address
1 parent 831d00c commit e5da6b4

File tree

3 files changed

+77
-4
lines changed

3 files changed

+77
-4
lines changed

wallet/models.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,19 @@ type DataV4 struct {
182182
PublicKey tlb.Bits256
183183
PluginDict tlb.HashmapE[tlb.Bits264, tlb.Any] // TODO: find type and check size
184184
}
185+
type WalletV5ID struct {
186+
NetworkGlobalID uint32
187+
Workchain uint8
188+
WalletVersion uint8
189+
SubWalletID uint32
190+
}
191+
192+
type DataV5 struct {
193+
Seqno tlb.Uint33
194+
WalletID WalletV5ID
195+
PublicKey tlb.Bits256
196+
PluginDict tlb.HashmapE[tlb.Bits264, tlb.Uint8] // TODO: find type and check size
197+
}
185198

186199
// DataHighloadV4 represents data of a highload-wallet contract.
187200
type DataHighloadV4 struct {

wallet/wallet.go

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ func DefaultWalletFromSeed(seed string, blockchain blockchain) (Wallet, error) {
2828
// (https://github.com/toncenter/tonweb/blob/master/src/contract/wallet/WalletSources.md)
2929
func New(key ed25519.PrivateKey, ver Version, workchain int, subWalletId *int, blockchain blockchain) (Wallet, error) {
3030
publicKey := key.Public().(ed25519.PublicKey)
31-
address, err := GenerateWalletAddress(publicKey, ver, workchain, subWalletId)
31+
address, err := GenerateWalletAddress(publicKey, ver, workchain, subWalletId, nil)
3232
if err != nil {
3333
return Wallet{}, err
3434
}
@@ -56,8 +56,9 @@ func GenerateWalletAddress(
5656
ver Version,
5757
workchain int,
5858
subWalletId *int,
59+
networkGlobalID *int,
5960
) (ton.AccountID, error) {
60-
state, err := GenerateStateInit(key, ver, workchain, subWalletId)
61+
state, err := GenerateStateInit(key, ver, workchain, subWalletId, networkGlobalID)
6162
if err != nil {
6263
return ton.AccountID{}, fmt.Errorf("can not generate wallet state: %v", err)
6364
}
@@ -83,6 +84,7 @@ func GenerateStateInit(
8384
ver Version,
8485
workchain int,
8586
subWalletId *int,
87+
networkGlobalID *int,
8688
) (tlb.StateInit, error) {
8789
var (
8890
err error
@@ -112,6 +114,26 @@ func GenerateStateInit(
112114
PublicKey: publicKey,
113115
}
114116
err = tlb.Marshal(dataCell, data)
117+
case V5R1:
118+
if subWalletId == nil {
119+
id := 0
120+
subWalletId = &id
121+
}
122+
if networkGlobalID == nil {
123+
id := -239 // -3 for testnet
124+
networkGlobalID = &id
125+
}
126+
data := DataV5{
127+
Seqno: 0,
128+
WalletID: WalletV5ID{
129+
NetworkGlobalID: uint32(*networkGlobalID),
130+
Workchain: uint8(workchain),
131+
WalletVersion: 0,
132+
SubWalletID: uint32(*subWalletId),
133+
},
134+
PublicKey: publicKey,
135+
}
136+
err = tlb.Marshal(dataCell, data)
115137
case HighLoadV2R2:
116138
if subWalletId == nil {
117139
id := DefaultSubWallet + workchain
@@ -260,7 +282,7 @@ func (w *Wallet) RawSend(
260282
func (w *Wallet) getInit() (tlb.StateInit, error) {
261283
publicKey := w.key.Public().(ed25519.PublicKey)
262284
id := int(w.subWalletId)
263-
return GenerateStateInit(publicKey, w.ver, int(w.address.Workchain), &id)
285+
return GenerateStateInit(publicKey, w.ver, int(w.address.Workchain), &id, nil)
264286
}
265287

266288
func checkMessagesLimit(msgQty int, ver Version) error { // TODO: maybe return bool

wallet/wallet_test.go

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import (
77
"encoding/hex"
88
"fmt"
99
"log"
10+
"reflect"
1011
"testing"
1112

1213
"github.com/tonkeeper/tongo/boc"
@@ -55,7 +56,7 @@ func TestGenerateWalletAddress(t *testing.T) {
5556
for ver, data := range testData {
5657
key, _ := hex.DecodeString(data.PublicKey)
5758
publicKey := ed25519.PublicKey(key)
58-
address, err := GenerateWalletAddress(publicKey, ver, 0, nil)
59+
address, err := GenerateWalletAddress(publicKey, ver, 0, nil, nil)
5960
if err != nil {
6061
t.Fatalf("address generation failed: %v", err)
6162
}
@@ -169,3 +170,40 @@ func TestDeserializeMessage(t *testing.T) {
169170
panic(err)
170171
}
171172
}
173+
func pointer[T any](t T) *T {
174+
return &t
175+
}
176+
177+
func TestGenerateWalletAddress1(t *testing.T) {
178+
tests := []struct {
179+
name string
180+
key ed25519.PublicKey
181+
ver Version
182+
workchain int
183+
subWalletId *int
184+
networkGlobalID *int
185+
want ton.AccountID
186+
wantErr bool
187+
}{
188+
{
189+
name: "V5R1",
190+
ver: V5R1,
191+
workchain: 0,
192+
networkGlobalID: pointer(-3),
193+
key: mustPubkeyFromHex("cfa50eeb1c3293c92bd33d5aa672c1717accd8a21b96033debb6d30b5bb230df"),
194+
want: ton.MustParseAccountID("EQCsa9xhVJCw2BRL07dhxwkOoAjNHRPLN2iPggZG_ZauRYt-"),
195+
},
196+
}
197+
for _, tt := range tests {
198+
t.Run(tt.name, func(t *testing.T) {
199+
got, err := GenerateWalletAddress(tt.key, tt.ver, tt.workchain, tt.subWalletId, tt.networkGlobalID)
200+
if (err != nil) != tt.wantErr {
201+
t.Errorf("GenerateWalletAddress() error = %v, wantErr %v", err, tt.wantErr)
202+
return
203+
}
204+
if !reflect.DeepEqual(got, tt.want) {
205+
t.Errorf("GenerateWalletAddress() got = %v, want %v", got, tt.want)
206+
}
207+
})
208+
}
209+
}

0 commit comments

Comments
 (0)