xssnick / tonutils-go

TON SDK Library in pure Golang for interacting with The Open Network ecosystem using native protocols, such as ADNL, RLDP and etc.
Apache License 2.0
500 stars 101 forks source link

send jetton failed #221

Closed lokichoggio closed 1 month ago

lokichoggio commented 1 month ago

code


func main() {
    client := liteclient.NewConnectionPool()

    // connect to testnet lite server
    err := client.AddConnectionsFromConfigUrl(context.Background(), "https://ton.org/global.config.json")
    if err != nil {
        panic(err)
    }

    ctx := client.StickyContext(context.Background())

    // initialize ton api lite connection wrapper
    api := ton.NewAPIClient(client)

    // seed words of account, you can generate them with any wallet or using wallet.NewSeed() method
    words := strings.Split("...", " ")

    w, err := wallet.FromSeed(api, words, wallet.V3R2)
    if err != nil {
        log.Fatalln("FromSeed err:", err.Error())
        return
    }

    token := jetton.NewJettonMasterClient(api, address.MustParseAddr("..."))

    // find our jetton wallet
    tokenWallet, err := token.GetJettonWallet(ctx, w.WalletAddress())
    if err != nil {
        log.Fatal(err)
    }

    tokenBalance, err := tokenWallet.GetBalance(ctx)
    if err != nil {
        log.Fatal(err)
    }
    log.Println("our jetton balance:", tokenBalance.String())

    amountTokens := tlb.MustFromDecimal("0.1", 9)

    //comment, err := wallet.CreateCommentCell("Hello from tonutils-go!")
    //if err != nil {
    //  log.Fatal(err)
    //}

    // address of receiver's wallet (not token wallet, just usual)
    to := address.MustParseAddr("....")
    transferPayload, err := tokenWallet.BuildTransferPayloadV2(to, to, amountTokens, tlb.ZeroCoins, nil, nil)
    if err != nil {
        log.Fatal(err)
    }

    // your TON balance must be > 0.05 to send
    //msg := wallet.SimpleMessage(tokenWallet.Address(), tlb.MustFromTON("0.05"), transferPayload)
    msg := wallet.SimpleMessage(tokenWallet.Address(), tlb.ZeroCoins, transferPayload)

    log.Println("sending transaction...")
    tx, _, err := w.SendWaitTransaction(ctx, msg)
    if err != nil {
        panic(err)
    }
    log.Println("transaction confirmed, hash:", base64.StdEncoding.EncodeToString(tx.Hash))
}

ERROR(from https://tonviewer.com/): Transaction error Unable to complete the operation. I don't understand. Do we need to send Ton when sending jetton. and why your TON balance must be > 0.05 to send?

xssnick commented 1 month ago

Hi, yes, sending jetton requires some ton to pay gas fees

lokichoggio commented 1 month ago
tokenWallet.BuildTransferPayloadV2(to, to, amountTokens, tlb.ZeroCoins, nil, nil)

tokenWallet.BuildTransferPayloadV2(to, to, amountTokens, tlb.ZeroCoins, nil, nil) the second param to can be w.WalletAddress(), mean excess gas back to from address. is it right?

lokichoggio commented 1 month ago

another question, how can i get tx detail by tx hash, and determine whether the transaction is actually successful

xssnick commented 1 month ago

Second parameter of BuildTransferPayloadV2 is response destination, yes, excess gas will be returned to it.

another question, how can i get tx detail by tx hash, and determine whether the transaction is actually successful

Just hash is not enough, you need to know the block and lt to get it using GetTransaction method. Or you can ListTransactions of account and find it. To know is it successful you can check exit codes of compute phase or state change, but it depends on contract.