Skip to content

Commit

Permalink
Wallet v5 support for generate address
Browse files Browse the repository at this point in the history
  • Loading branch information
aleksej-paschenko committed May 3, 2024
1 parent 1dab703 commit 32392d8
Show file tree
Hide file tree
Showing 4 changed files with 78 additions and 13 deletions.
9 changes: 7 additions & 2 deletions tonconnect/proof_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,11 @@ func TestCreateSignedProof(t *testing.T) {
version: wallet.V4R1,
secret: "another-random-secret",
},
{
name: "v5r1",
version: wallet.V5R1,
secret: "random-secret",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
Expand All @@ -47,11 +52,11 @@ func TestCreateSignedProof(t *testing.T) {
t.Fatalf("SeedToPrivateKey() failed: %v", err)
}
publicKey := privateKey.Public().(ed25519.PublicKey)
stateInit, err := wallet.GenerateStateInit(publicKey, tt.version, 0, nil)
stateInit, err := wallet.GenerateStateInit(publicKey, tt.version, 0, nil, nil)
if err != nil {
t.Fatalf("GenerateStateInit() failed: %v", err)
}
accountID, err := wallet.GenerateWalletAddress(publicKey, tt.version, 0, nil)
accountID, err := wallet.GenerateWalletAddress(publicKey, tt.version, 0, nil, nil)
if err != nil {
t.Fatalf("GenerateWalletAddress() failed: %v", err)
}
Expand Down
14 changes: 7 additions & 7 deletions wallet/models.go
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,13 @@ type DataV3 struct {
PublicKey tlb.Bits256
}

type DataV4 struct {
Seqno uint32
SubWalletId uint32
PublicKey tlb.Bits256
PluginDict tlb.HashmapE[tlb.Bits264, tlb.Any] // TODO: find type and check size
}

type WalletV5ID struct {
NetworkGlobalID uint32
Workchain uint8
Expand All @@ -190,13 +197,6 @@ type DataV5 struct {
PluginDict tlb.HashmapE[tlb.Bits264, tlb.Uint8] // TODO: find type and check size
}

type DataV4 struct {
Seqno uint32
SubWalletId uint32
PublicKey tlb.Bits256
PluginDict tlb.HashmapE[tlb.Bits264, tlb.Any] // TODO: find type and check size
}

// DataHighloadV4 represents data of a highload-wallet contract.
type DataHighloadV4 struct {
SubWalletId uint32
Expand Down
28 changes: 25 additions & 3 deletions wallet/wallet.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ func DefaultWalletFromSeed(seed string, blockchain blockchain) (Wallet, error) {
// (https://github.com/toncenter/tonweb/blob/master/src/contract/wallet/WalletSources.md)
func New(key ed25519.PrivateKey, ver Version, workchain int, subWalletId *int, blockchain blockchain) (Wallet, error) {
publicKey := key.Public().(ed25519.PublicKey)
address, err := GenerateWalletAddress(publicKey, ver, workchain, subWalletId)
address, err := GenerateWalletAddress(publicKey, ver, workchain, subWalletId, nil)
if err != nil {
return Wallet{}, err
}
Expand Down Expand Up @@ -56,8 +56,9 @@ func GenerateWalletAddress(
ver Version,
workchain int,
subWalletId *int,
networkGlobalID *int,
) (ton.AccountID, error) {
state, err := GenerateStateInit(key, ver, workchain, subWalletId)
state, err := GenerateStateInit(key, ver, workchain, subWalletId, networkGlobalID)
if err != nil {
return ton.AccountID{}, fmt.Errorf("can not generate wallet state: %v", err)
}
Expand All @@ -83,6 +84,7 @@ func GenerateStateInit(
ver Version,
workchain int,
subWalletId *int,
networkGlobalID *int,
) (tlb.StateInit, error) {
var (
err error
Expand Down Expand Up @@ -112,6 +114,26 @@ func GenerateStateInit(
PublicKey: publicKey,
}
err = tlb.Marshal(dataCell, data)
case V5R1:
if subWalletId == nil {
id := 0
subWalletId = &id
}
if networkGlobalID == nil {
id := -239 // -3 for testnet
networkGlobalID = &id
}
data := DataV5{
Seqno: 0,
WalletID: WalletV5ID{
NetworkGlobalID: uint32(*networkGlobalID),
Workchain: uint8(workchain),
WalletVersion: 0,
SubWalletID: uint32(*subWalletId),
},
PublicKey: publicKey,
}
err = tlb.Marshal(dataCell, data)
case HighLoadV2R2:
if subWalletId == nil {
id := DefaultSubWallet + workchain
Expand Down Expand Up @@ -260,7 +282,7 @@ func (w *Wallet) RawSend(
func (w *Wallet) getInit() (tlb.StateInit, error) {
publicKey := w.key.Public().(ed25519.PublicKey)
id := int(w.subWalletId)
return GenerateStateInit(publicKey, w.ver, int(w.address.Workchain), &id)
return GenerateStateInit(publicKey, w.ver, int(w.address.Workchain), &id, nil)
}

func checkMessagesLimit(msgQty int, ver Version) error { // TODO: maybe return bool
Expand Down
40 changes: 39 additions & 1 deletion wallet/wallet_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"encoding/hex"
"fmt"
"log"
"reflect"
"testing"

"github.com/tonkeeper/tongo/boc"
Expand Down Expand Up @@ -55,7 +56,7 @@ func TestGenerateWalletAddress(t *testing.T) {
for ver, data := range testData {
key, _ := hex.DecodeString(data.PublicKey)
publicKey := ed25519.PublicKey(key)
address, err := GenerateWalletAddress(publicKey, ver, 0, nil)
address, err := GenerateWalletAddress(publicKey, ver, 0, nil, nil)
if err != nil {
t.Fatalf("address generation failed: %v", err)
}
Expand Down Expand Up @@ -169,3 +170,40 @@ func TestDeserializeMessage(t *testing.T) {
panic(err)
}
}
func pointer[T any](t T) *T {
return &t
}

func TestGenerateWalletAddress1(t *testing.T) {
tests := []struct {
name string
key ed25519.PublicKey
ver Version
workchain int
subWalletId *int
networkGlobalID *int
want ton.AccountID
wantErr bool
}{
{
name: "V5R1",
ver: V5R1,
workchain: 0,
networkGlobalID: pointer(-3),
key: mustPubkeyFromHex("cfa50eeb1c3293c92bd33d5aa672c1717accd8a21b96033debb6d30b5bb230df"),
want: ton.MustParseAccountID("EQCsa9xhVJCw2BRL07dhxwkOoAjNHRPLN2iPggZG_ZauRYt-"),
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got, err := GenerateWalletAddress(tt.key, tt.ver, tt.workchain, tt.subWalletId, tt.networkGlobalID)
if (err != nil) != tt.wantErr {
t.Errorf("GenerateWalletAddress() error = %v, wantErr %v", err, tt.wantErr)
return
}
if !reflect.DeepEqual(got, tt.want) {
t.Errorf("GenerateWalletAddress() got = %v, want %v", got, tt.want)
}
})
}
}

0 comments on commit 32392d8

Please sign in to comment.