Skip to content

Commit

Permalink
SendWaitTransaction add return block
Browse files Browse the repository at this point in the history
  • Loading branch information
xssnick committed Apr 23, 2023
1 parent 25c24e3 commit 056f425
Show file tree
Hide file tree
Showing 4 changed files with 38 additions and 29 deletions.
15 changes: 12 additions & 3 deletions example/send-to-contract/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ func main() {
if balance.NanoTON().Uint64() >= 3000000 {
// create transaction body cell, depends on what contract needs, just random example here
body := cell.BeginCell().
MustStoreUInt(0x123abc55, 32). // op code
MustStoreUInt(0x123abc55, 32). // op code
MustStoreUInt(rand.Uint64(), 64). // query id
// payload:
MustStoreAddr(address.MustParseAddr("EQAbMQzuuGiCne0R7QEj9nrXsjM7gNjeVmrlBZouyC-SCLlO")).
Expand All @@ -65,7 +65,7 @@ func main() {

log.Println("sending transaction and waiting for confirmation...")

tx, err := w.SendWaitTransaction(context.Background(), &wallet.Message{
tx, block, err := w.SendWaitTransaction(context.Background(), &wallet.Message{
Mode: 1, // pay fees separately (from balance, not from amount)
InternalMessage: &tlb.InternalMessage{
Bounce: true, // return amount in case of processing error
Expand All @@ -79,7 +79,16 @@ func main() {
return
}

log.Println("transaction sent, hash:", base64.StdEncoding.EncodeToString(tx.Hash))
log.Println("transaction sent, confirmed at block, hash:", base64.StdEncoding.EncodeToString(tx.Hash))

balance, err = w.GetBalance(context.Background(), block)
if err != nil {
log.Fatalln("GetBalance err:", err.Error())
return
}

log.Println("balance left:", balance.TON())

return
}

Expand Down
4 changes: 2 additions & 2 deletions ton/jetton/integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -117,12 +117,12 @@ func TestJettonMasterClient_Transfer(t *testing.T) {

msg = wallet.SimpleMessage(tokenWallet.Address(), tlb.MustFromTON("0.05"), burnPayload)

err = w.Send(ctx, msg, true)
_, block, err := w.SendWaitTransaction(ctx, msg)
if err != nil {
panic(err)
}

b2, err := tokenWallet.GetBalance(ctx)
b2, err := tokenWallet.GetBalanceAtBlock(ctx, block)
if err != nil {
t.Fatal(err)
}
Expand Down
8 changes: 4 additions & 4 deletions ton/nft/integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -103,17 +103,17 @@ func Test_NftMintTransfer(t *testing.T) {
fmt.Println("Transferring NFT...")
transfer := wallet.SimpleMessage(nftAddr, tlb.MustFromTON("0.065"), transferData)

err = w.Send(context.Background(), transfer, true)
_, block, err = w.SendWaitTransaction(context.Background(), transfer)
if err != nil {
t.Fatal("Send err:", err.Error())
}

newData, err := nft.GetNFTData(ctx)
newData, err := nft.GetNFTDataAtBlock(ctx, block)
if err != nil {
t.Fatal("GetNFTData err:", err.Error())
}

fullContent, err := collection.GetNFTContent(ctx, collectionData.NextItemIndex, newData.Content)
fullContent, err := collection.GetNFTContentAtBlock(ctx, collectionData.NextItemIndex, newData.Content, block)
if err != nil {
t.Fatal("GetNFTData err:", err.Error())
}
Expand All @@ -122,7 +122,7 @@ func Test_NftMintTransfer(t *testing.T) {
t.Fatal("full content incorrect", fullContent.(*ContentOffchain).URI)
}

roy, err := collection.RoyaltyParams(ctx)
roy, err := collection.RoyaltyParamsAtBlock(ctx, block)
if err != nil {
t.Fatal("RoyaltyParams err:", err.Error())
}
Expand Down
40 changes: 20 additions & 20 deletions ton/wallet/wallet.go
Original file line number Diff line number Diff line change
Expand Up @@ -258,65 +258,65 @@ func (w *Wallet) Send(ctx context.Context, message *Message, waitConfirmation ..
}

func (w *Wallet) SendMany(ctx context.Context, messages []*Message, waitConfirmation ...bool) error {
_, _, err := w.sendMany(ctx, messages, waitConfirmation...)
_, _, _, err := w.sendMany(ctx, messages, waitConfirmation...)
return err
}

// SendManyGetInMsgHash returns hash of external incoming message payload.
func (w *Wallet) SendManyGetInMsgHash(ctx context.Context, messages []*Message, waitConfirmation ...bool) ([]byte, error) {
_, inMsgHash, err := w.sendMany(ctx, messages, waitConfirmation...)
_, _, inMsgHash, err := w.sendMany(ctx, messages, waitConfirmation...)
return inMsgHash, err
}

// SendManyWaitTxHash always waits for tx block confirmation and returns found tx hash in block.
func (w *Wallet) SendManyWaitTxHash(ctx context.Context, messages []*Message) ([]byte, error) {
tx, _, err := w.sendMany(ctx, messages, true)
tx, _, _, err := w.sendMany(ctx, messages, true)
return tx.Hash, err
}

// SendManyWaitTransaction always waits for tx block confirmation and returns found tx.
func (w *Wallet) SendManyWaitTransaction(ctx context.Context, messages []*Message) (*tlb.Transaction, error) {
tx, _, err := w.sendMany(ctx, messages, true)
return tx, err
func (w *Wallet) SendManyWaitTransaction(ctx context.Context, messages []*Message) (*tlb.Transaction, *ton.BlockIDExt, error) {
tx, block, _, err := w.sendMany(ctx, messages, true)
return tx, block, err
}

// SendWaitTransaction always waits for tx block confirmation and returns found tx.
func (w *Wallet) SendWaitTransaction(ctx context.Context, message *Message) (*tlb.Transaction, error) {
func (w *Wallet) SendWaitTransaction(ctx context.Context, message *Message) (*tlb.Transaction, *ton.BlockIDExt, error) {
return w.SendManyWaitTransaction(ctx, []*Message{message})
}

func (w *Wallet) sendMany(ctx context.Context, messages []*Message, waitConfirmation ...bool) (tx *tlb.Transaction, inMsgHash []byte, err error) {
block, err := w.api.CurrentMasterchainInfo(ctx)
func (w *Wallet) sendMany(ctx context.Context, messages []*Message, waitConfirmation ...bool) (tx *tlb.Transaction, block *ton.BlockIDExt, inMsgHash []byte, err error) {
block, err = w.api.CurrentMasterchainInfo(ctx)
if err != nil {
return nil, nil, fmt.Errorf("failed to get block: %w", err)
return nil, nil, nil, fmt.Errorf("failed to get block: %w", err)
}

acc, err := w.api.WaitForBlock(block.SeqNo).GetAccount(ctx, block, w.addr)
if err != nil {
return nil, nil, fmt.Errorf("failed to get account state: %w", err)
return nil, nil, nil, fmt.Errorf("failed to get account state: %w", err)
}

ext, err := w.BuildMessageForMany(ctx, messages)
if err != nil {
return nil, nil, err
return nil, nil, nil, err
}
inMsgHash = ext.Body.Hash()

if err = w.api.SendExternalMessage(ctx, ext); err != nil {
return nil, nil, fmt.Errorf("failed to send message: %w", err)
return nil, nil, nil, fmt.Errorf("failed to send message: %w", err)
}

if len(waitConfirmation) > 0 && waitConfirmation[0] {
tx, err = w.waitConfirmation(ctx, block, acc, ext)
tx, block, err = w.waitConfirmation(ctx, block, acc, ext)
if err != nil {
return nil, nil, err
return nil, nil, nil, err
}
}

return tx, inMsgHash, nil
return tx, block, inMsgHash, nil
}

func (w *Wallet) waitConfirmation(ctx context.Context, block *ton.BlockIDExt, acc *tlb.Account, ext *tlb.ExternalMessage) (*tlb.Transaction, error) {
func (w *Wallet) waitConfirmation(ctx context.Context, block *ton.BlockIDExt, acc *tlb.Account, ext *tlb.ExternalMessage) (*tlb.Transaction, *ton.BlockIDExt, error) {
if _, hasDeadline := ctx.Deadline(); !hasDeadline {
// fallback timeout to not stuck forever with background context
var cancel context.CancelFunc
Expand Down Expand Up @@ -354,7 +354,7 @@ func (w *Wallet) waitConfirmation(ctx context.Context, block *ton.BlockIDExt, ac
// to prevent this we will scan till we reach last seen offset.
for time.Now().Before(till) {
// we try to get last 5 transactions, and check if we have our new there.
txList, err := w.api.ListTransactions(ctx, w.addr, 5, lastLt, lastHash)
txList, err := w.api.WaitForBlock(block.SeqNo).ListTransactions(ctx, w.addr, 5, lastLt, lastHash)
if err != nil {
continue
}
Expand Down Expand Up @@ -391,7 +391,7 @@ func (w *Wallet) waitConfirmation(ctx context.Context, block *ton.BlockIDExt, ac
continue
}

return transaction, nil
return transaction, block, nil
}
}

Expand All @@ -402,7 +402,7 @@ func (w *Wallet) waitConfirmation(ctx context.Context, block *ton.BlockIDExt, ac
acc = accNew
}

return nil, ErrTxWasNotConfirmed
return nil, nil, ErrTxWasNotConfirmed
}

// TransferNoBounce - can be used to transfer TON to not yet initialized contract/wallet
Expand Down

0 comments on commit 056f425

Please sign in to comment.