diff --git a/wallet/models_test.go b/wallet/models_test.go new file mode 100644 index 00000000..910063be --- /dev/null +++ b/wallet/models_test.go @@ -0,0 +1,15 @@ +package wallet + +import ( + "testing" +) + +func TestVersion_ToString(t *testing.T) { + for ver := range codes { + ver.ToString() + + } + if got := tt.v.ToString(); got != tt.want { + t.Errorf("ToString() = %v, want %v", got, tt.want) + } +} diff --git a/wallet/wallet.go b/wallet/wallet.go index abffd153..d2960e72 100644 --- a/wallet/wallet.go +++ b/wallet/wallet.go @@ -109,7 +109,7 @@ func newWallet(key ed25519.PublicKey, version Version, options Options) (wallet, case V4R1, V4R2: return newWalletV4(version, key, options), nil case V5Beta: - return newWalletV5(version, key, options), nil + return NewWalletV5Beta(version, key, options), nil case HighLoadV2R2: return newWalletHighloadV2(version, key, options), nil default: @@ -258,7 +258,7 @@ func (w *Wallet) SendV2(ctx context.Context, waitingConfirmation time.Duration, if err != nil { return ton.Bits256{}, fmt.Errorf("get account state failed: %v", err) } - params, err := w.intWallet.nextMessageParams(state) + params, err := w.intWallet.NextMessageParams(state) if err != nil { return ton.Bits256{}, err } diff --git a/wallet/wallet_highload_v2.go b/wallet/wallet_highload_v2.go index 3c68f790..a62b1b1c 100644 --- a/wallet/wallet_highload_v2.go +++ b/wallet/wallet_highload_v2.go @@ -71,14 +71,14 @@ func (w *walletHighloadV2) createSignedMsgBodyCell(privateKey ed25519.PrivateKey return signBodyCell(*bodyCell, privateKey) } -func (w *walletHighloadV2) nextMessageParams(state tlb.ShardAccount) (nextMsgParams, error) { +func (w *walletHighloadV2) NextMessageParams(state tlb.ShardAccount) (NextMsgParams, error) { initRequired := state.Account.Status() == tlb.AccountUninit || state.Account.Status() == tlb.AccountNone if !initRequired { - return nextMsgParams{}, nil + return NextMsgParams{}, nil } stateInit, err := w.generateStateInit() if err != nil { - return nextMsgParams{}, err + return NextMsgParams{}, err } - return nextMsgParams{Init: stateInit}, nil + return NextMsgParams{Init: stateInit}, nil } diff --git a/wallet/wallet_v1v2.go b/wallet/wallet_v1v2.go index 7f3de39d..a2d9843e 100644 --- a/wallet/wallet_v1v2.go +++ b/wallet/wallet_v1v2.go @@ -54,6 +54,6 @@ func (w *walletV1V2) createSignedMsgBodyCell(privateKey ed25519.PrivateKey, inte panic("implement me") } -func (w *walletV1V2) nextMessageParams(state tlb.ShardAccount) (nextMsgParams, error) { +func (w *walletV1V2) NextMessageParams(state tlb.ShardAccount) (NextMsgParams, error) { panic("implement me") } diff --git a/wallet/wallet_v3.go b/wallet/wallet_v3.go index e744888c..4f3ad842 100644 --- a/wallet/wallet_v3.go +++ b/wallet/wallet_v3.go @@ -69,20 +69,20 @@ func (w *walletV3) createSignedMsgBodyCell(privateKey ed25519.PrivateKey, intern return signBodyCell(*bodyCell, privateKey) } -func (w *walletV3) nextMessageParams(state tlb.ShardAccount) (nextMsgParams, error) { +func (w *walletV3) NextMessageParams(state tlb.ShardAccount) (NextMsgParams, error) { if state.Account.Status() == tlb.AccountActive { var data DataV3 cell := boc.Cell(state.Account.Account.Storage.State.AccountActive.StateInit.Data.Value.Value) if err := tlb.Unmarshal(&cell, &data); err != nil { - return nextMsgParams{}, err + return NextMsgParams{}, err } - return nextMsgParams{ + return NextMsgParams{ Seqno: data.Seqno, }, nil } init, err := w.generateStateInit() if err != nil { - return nextMsgParams{}, err + return NextMsgParams{}, err } - return nextMsgParams{Init: init}, nil + return NextMsgParams{Init: init}, nil } diff --git a/wallet/wallet_v4.go b/wallet/wallet_v4.go index 52e98790..6a8a6b1e 100644 --- a/wallet/wallet_v4.go +++ b/wallet/wallet_v4.go @@ -72,20 +72,20 @@ func (w *walletV4) createSignedMsgBodyCell(privateKey ed25519.PrivateKey, intern return signBodyCell(*bodyCell, privateKey) } -func (w *walletV4) nextMessageParams(state tlb.ShardAccount) (nextMsgParams, error) { +func (w *walletV4) NextMessageParams(state tlb.ShardAccount) (NextMsgParams, error) { if state.Account.Status() == tlb.AccountActive { var data DataV4 cell := boc.Cell(state.Account.Account.Storage.State.AccountActive.StateInit.Data.Value.Value) if err := tlb.Unmarshal(&cell, &data); err != nil { - return nextMsgParams{}, err + return NextMsgParams{}, err } - return nextMsgParams{ + return NextMsgParams{ Seqno: data.Seqno, }, nil } init, err := w.generateStateInit() if err != nil { - return nextMsgParams{}, err + return NextMsgParams{}, err } - return nextMsgParams{Init: init}, nil + return NextMsgParams{Init: init}, nil } diff --git a/wallet/wallet_v5.go b/wallet/wallet_v5.go index 1fedc63a..7d1adee4 100644 --- a/wallet/wallet_v5.go +++ b/wallet/wallet_v5.go @@ -23,7 +23,7 @@ type DataV5 struct { Extensions tlb.HashmapE[tlb.Bits256, tlb.Uint8] } -type walletV5 struct { +type walletV5Beta struct { version Version publicKey ed25519.PublicKey workchain int @@ -45,14 +45,14 @@ type MessageConfigV5 struct { MsgType V5MsgType } -var _ wallet = &walletV5{} +var _ wallet = &walletV5Beta{} -func newWalletV5(version Version, publicKey ed25519.PublicKey, opts Options) *walletV5 { +func NewWalletV5Beta(version Version, publicKey ed25519.PublicKey, opts Options) *walletV5Beta { workchain := defaultOr(opts.Workchain, 0) subWalletID := defaultOr(opts.SubWalletID, 0) networkGlobalID := defaultOr[int32](opts.NetworkGlobalID, MainnetGlobalID) - return &walletV5{ + return &walletV5Beta{ version: version, publicKey: publicKey, workchain: workchain, @@ -61,7 +61,7 @@ func newWalletV5(version Version, publicKey ed25519.PublicKey, opts Options) *wa } } -func (w *walletV5) generateAddress() (ton.AccountID, error) { +func (w *walletV5Beta) generateAddress() (ton.AccountID, error) { stateInit, err := w.generateStateInit() if err != nil { return ton.AccountID{}, fmt.Errorf("can not generate state init: %v", err) @@ -69,7 +69,7 @@ func (w *walletV5) generateAddress() (ton.AccountID, error) { return generateAddress(w.workchain, *stateInit) } -func (w *walletV5) generateStateInit() (*tlb.StateInit, error) { +func (w *walletV5Beta) generateStateInit() (*tlb.StateInit, error) { data := DataV5{ Seqno: 0, WalletID: WalletV5ID{ @@ -82,26 +82,26 @@ func (w *walletV5) generateStateInit() (*tlb.StateInit, error) { return generateStateInit(w.version, data) } -func (w *walletV5) maxMessageNumber() int { +func (w *walletV5Beta) maxMessageNumber() int { return 254 } -func (w *walletV5) nextMessageParams(state tlb.ShardAccount) (nextMsgParams, error) { +func (w *walletV5Beta) NextMessageParams(state tlb.ShardAccount) (NextMsgParams, error) { if state.Account.Status() == tlb.AccountActive { var data DataV5 cell := boc.Cell(state.Account.Account.Storage.State.AccountActive.StateInit.Data.Value.Value) if err := tlb.Unmarshal(&cell, &data); err != nil { - return nextMsgParams{}, err + return NextMsgParams{}, err } - return nextMsgParams{ + return NextMsgParams{ Seqno: uint32(data.Seqno), }, nil } init, err := w.generateStateInit() if err != nil { - return nextMsgParams{}, err + return NextMsgParams{}, err } - return nextMsgParams{Init: init}, nil + return NextMsgParams{Init: init}, nil } @@ -113,7 +113,43 @@ type extSignedMessage struct { Actions SendMessageList `tlb:"^"` } -func (w *walletV5) createSignedMsgBodyCell(privateKey ed25519.PrivateKey, internalMessages []RawMessage, msgConfig MessageConfig) (*boc.Cell, error) { +func (w *walletV5Beta) CreateMsgBodyWithoutSignature(internalMessages []RawMessage, msgConfig MessageConfig) (*boc.Cell, error) { + actions := SendMessageList{ + Actions: make([]SendMessageAction, 0, len(internalMessages)), + } + for _, msg := range internalMessages { + actions.Actions = append(actions.Actions, SendMessageAction{ + Msg: msg.Message, + Mode: msg.Mode, + }) + } + msg := extSignedMessage{ + WalletId: WalletV5ID{ + NetworkGlobalID: w.networkGlobalID, + Workchain: uint8(w.workchain), + SubWalletID: w.subWalletID, + }, + ValidUntil: uint32(msgConfig.ValidUntil.Unix()), + Seqno: msgConfig.Seqno, + Op: false, + Actions: actions, + } + bodyCell := boc.NewCell() + if err := bodyCell.WriteUint(uint64(msgConfig.V5MsgType), 32); err != nil { + return nil, err + } + if err := tlb.Marshal(bodyCell, msg); err != nil { + return nil, err + } + bytes := [64]byte{} + if err := bodyCell.WriteBytes(bytes[:]); err != nil { + return nil, err + } + return bodyCell, nil + +} + +func (w *walletV5Beta) createSignedMsgBodyCell(privateKey ed25519.PrivateKey, internalMessages []RawMessage, msgConfig MessageConfig) (*boc.Cell, error) { actions := SendMessageList{ Actions: make([]SendMessageAction, 0, len(internalMessages)), } diff --git a/wallet/wallets_common.go b/wallet/wallets_common.go index 715c598e..8f7a2de2 100644 --- a/wallet/wallets_common.go +++ b/wallet/wallets_common.go @@ -9,7 +9,7 @@ import ( "github.com/tonkeeper/tongo/ton" ) -type nextMsgParams struct { +type NextMsgParams struct { Seqno uint32 Init *tlb.StateInit } @@ -19,7 +19,7 @@ type wallet interface { generateStateInit() (*tlb.StateInit, error) maxMessageNumber() int createSignedMsgBodyCell(privateKey ed25519.PrivateKey, internalMessages []RawMessage, msgConfig MessageConfig) (*boc.Cell, error) - nextMessageParams(state tlb.ShardAccount) (nextMsgParams, error) + NextMessageParams(state tlb.ShardAccount) (NextMsgParams, error) } func defaultOr[T any](value *T, defaultValue T) T {