Giter Site home page Giter Site logo

xssnick / tonutils-go Goto Github PK

View Code? Open in Web Editor NEW
460.0 15.0 94.0 7.37 MB

TON SDK Library in pure Golang for interacting with The Open Network ecosystem using native protocols, such as ADNL, RLDP and etc.

License: Apache License 2.0

Go 100.00%
ton blockchain golang golang-library telegram toncoin sdk sdk-go

tonutils-go's Issues

Just want build a boc

I use this code. and want to build a boc .

        `transfer, err := w.BuildTransfer(addr, tlb.MustFromTON("0.003"), bounce, "Hello from tonutils-go!")
            if err != nil {
                log.Fatalln("Transfer err:", err.Error())
                return
            }
            
            ext, err := w.BuildExternalMessageForMany(context.Background(), []*wallet.Message{transfer})
            
            req, err := tlb.ToCell(ext)
            
            println(base64.URLEncoding.EncodeToString(req.ToBOCWithFlags(false)))`

then I want to use api to send my message,
image

always incorrectly.

Can you help me, dear friend😂

Transactions in a block in the past

Hey Nick, I'm new to Ton Blockchain. Can I ask have you implemented a method to get all transactions of an exact block yet? With go-ethereum it looks like : block, err := client.BlockByNumber(context.Background(), big.NewInt(3000000)).
Hope I will get your answer soon :) thank you very much for this library.

parse Tact map

How to parse the map in Tact using Golang when I call get method
ts script:
async getMap(provider: ContractProvider) {
let builder = new TupleBuilder();
let source = (await provider.get('map', builder.build())).stack;
let result = Dictionary.loadDirect(Dictionary.Keys.BigInt(257), Dictionary.Values.BigInt(257), source.readCellOpt());
return result;
}

how to parse jetton transaction to get jetton token amount and comment?

when transfer jetton, i noticed the jetton amount and comment has been included in transferPayload then included into message body, my purpose is to parse tx from ListTransactions, this sdk is not supported to get jetton amount and comment, so i try to parse message body to find out ,i can get the message body by 'body:=tx.IO.In.AsInternal().Body', but how to parse the body to readable text?

How to use `tlb` struct tag to load string snake?

I've looked at the docs in the loader.go, but still haven't figured out how to load the string snake; for now I'm stuck with the *cell.Cell:

var comment struct {
    _     tlb.Magic  `tlb:"#00000000"`
    Value *cell.Cell `tlb:"."`
}
_ = tlb.LoadFromCell(&comment, msgs[1].AsInternal().Body.BeginParse(), false)

// load string snake
cStr, err := comment.Value.BeginParse().LoadStringSnake()

I'm wondering if there are other ways to directly deserialize structs, such as tlb: "snake"?

How do we get user wallet from this backend ?

func getWallet(api *ton.APIClient) *wallet.Wallet {
	words := strings.Split("birth pattern then forest walnut then phrase walnut fan pumpkin pattern then cluster blossom verify then forest velvet pond fiction pattern collect then then", " ")
	w, err := wallet.FromSeed(api, words, wallet.V3)
	if err != nil {
		panic(err)
	}
	return w
}

any correct flow for this ?
How do I get user wallet without user insert this seed

send jetton failed

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?

ListTransactions() always fail with -400 error

I'm trying to load history transaction of an wallet, but always get this error:

send err: lite server error, code -400: cannot load block (0,8000000000000000,40278934):ED46C7BCB4EF18DD435C2F17A55DE395B4F8E49E3AF6BCCF856E4050DF317D5D:51BC46484CF32A99E74B8A5FD54A589EE3FC68E452CFA5C5538FB5C38E757261 with specified transaction: not in db

Anyone know how to fix it? Does that mean all lite servers are down?

Thanks.

I just use the example code to test this feature:
https://github.com/xssnick/tonutils-go/blob/master/example/account-state/main.go

SendManyWaitTransaction error

failed to send message: lite server error, code 0: cannot apply external message to current state : External message was not accepted
Cannot run message on account: inbound external message rejected by transaction xxx:
exitcode=33, steps=23, gas_used=0
VM Log (truncated):
...te NOW
execute LEQ
execute THROWIF 36
execute PUSH c4
execute CTOS
execute LDU 32
execute LDU 32
execute LDU 256
execute LDDICT
execute ENDS
execute XCPU s4,s3
execute EQUAL
execute THROWIFNOT 33
default exception handler, terminating vm with exit code 33

Add new real world usage examples

More examples = easier to understand.

The task is to add more real world examples, DEX Swap (dedust for example), NFT put on sale, DNS auction, NFT sale buy and etc. For the contract message serialization please use struct with tlb tags, for the cleaner cell building (example).

If you want to add an example, leave a comment here with a small description about what you are going to add, i'll approve it with (👍) and you can start. This task can be done by many developers (each one can add own example).

When you are done, just make PR to master branch, and leave a comment here.

Optimize raptorq/discmath package and cover with tests

RaptorQ package (used for forward error correction encoding) is used by RLDP protocol, which is one of the building blocks of TON communication, it is used by such components as Storage, Proxy, Nodes. Current implementation is not so efficient as it could be, for example maps usage can be replaced to arrays/slices.

The task is to optimize raptorq+discmath packages, cover them with unit tests and add benchmarks. Please don't use CGO or external libraries.

You could start from benchmarks to understand current behaviour and speed. Usage example can be found in rldp package.

If you want to take the task, leave a comment here (time estimation will be a plus). When you are done, just make PR to dev-v19 branch, and leave a comment here.

Balance

It didnt work my version wallet is v5r1 and when i want to use that with beta || final it give err i tried with v4r2 it runed but it return 0 but i had 5 ton on test net

jetton comment cannot be parsed

  1. Send jetton tranfer transaction with comment
    comment, _ := wallet.CreateCommentCell("hello world!")
    transferPayload, _ := tokenWallet.BuildTransferPayloadV2(to, w.Address(), amountTokens, tlb.MustFromTON("0.1"), comment, nil)
  2. However, the refs field of transferPayload is empty and does not contain a comment cell. When I get tx.IO.In.AsInternal().Body.RefsNum() through api.SubscribeOnTransactions, it is 0, so I can't get the comment.
  3. I modified the flag of the ForwardPayload field of the jetton.TransferPayload structure from tlb:"either . ^" to tlb:"either ^ ." or tlb:"maybe ^", the refs field of transferPayload obtained through tokenWallet.BuildTransferPayloadV2 is not 0. When I get tx.IO.In.AsInternal().Body.RefsNum() through api.SubscribeOnTransactions, it is not 0, so I can get the comment.
    So why does this happen? What is the correct way to use it? Thank you.

Question about BuildTransferPayload

Hi all, I have a question about jetton message.
If I have a cell that contains lots of additional payload, when I use BuildTransferPayloadV2, cell will be parsed and every data will be appended to the msg_body.

if err := root.StoreBuilder(builder); err != nil {

It may caused cell overflow error. So Im confused why not use store_ref() to store cell? or maybe I have a wrong thinking?

Thanks for everyone's answer.

"Failed to parse payload: recursive reference of cells" on "cell.FromBOC" call

Hello. I get error Failed to parse payload: recursive reference of cells when deserializing stateinit from mytonwallet (ton connect).
Error occurs on the call cell.FromBOC.
I believe this is a bug, because I was able to successfully parse this stateinit using tongo library as shown in the example.

Tonutils version: v1.8.9

Example:

package main

import (
  "encoding/base64"
  "fmt"
  "log"

  "github.com/tonkeeper/tongo/tonconnect"
  "github.com/xssnick/tonutils-go/tvm/cell"
)

func main() {
  // address
  // UQBe7yULTjbWZszDK2d8LOePumy9ZtGzwQgrXXfqjR1yM2fy

  // stateInit from mytonwallet
  stateInit := "te6ccsECFgEAAwQAAAAABQAwAD0AQgDEAMsBAwE9AXYBewGAAa8BtAG/AcQByQHYAecCCAJ/AsYCATQCAQBRAAAAACmpoxf4lk0qBZddWkKNjjqmudjY6QDlccYne0gS9zCGDH3x2kABFP8A9KQT9LzyyAsDAgEgCQQE+PKDCNcYINMf0x/THwL4I7vyZO1E0NMf0x/T//QE0VFDuvKhUVG68qIF+QFUEGT5EPKj+AAkpMjLH1JAyx9SMMv/UhD0AMntVPgPAdMHIcAAn2xRkyDXSpbTB9QC+wDoMOAhwAHjACHAAuMAAcADkTDjDQOkyMsfEssfy/8IBwYFAAr0AMntVABsgQEI1xj6ANM/MFIkgQEI9Fnyp4IQZHN0cnB0gBjIywXLAlAFzxZQA/oCE8tqyx8Syz/Jc/sAAHCBAQjXGPoA0z/IVCBHgQEI9FHyp4IQbm90ZXB0gBjIywXLAlAGzxZQBPoCFMtqEssfyz/Jc/sAAgBu0gf6ANTUIvkABcjKBxXL/8nQd3SAGMjLBcsCIs8WUAX6AhTLaxLMzMlz+wDIQBSBAQj0UfKnAgIBSBMKAgEgDAsAWb0kK29qJoQICga5D6AhhHDUCAhHpJN9KZEM5pA+n/mDeBKAG3gQFImHFZ8xhAIBIA4NABG4yX7UTQ1wsfgCAVgSDwIBIBEQABmvHfaiaEAQa5DrhY/AABmtznaiaEAga5Drhf/AAD2ynftRNCBAUDXIfQEMALIygfL/8nQAYEBCPQKb6ExgAubQAdDTAyFxsJJfBOAi10nBIJJfBOAC0x8hghBwbHVnvSKCEGRzdHK9sJJfBeAD+kAwIPpEAcjKB8v/ydDtRNCBAUDXIfQEMFyBAQj0Cm+hMbOSXwfgBdM/yCWCEHBsdWe6kjgw4w0DghBkc3RyupJfBuMNFRQAilAEgQEI9Fkw7UTQgQFA1yDIAc8W9ADJ7VQBcrCOI4IQZHN0coMesXCAGFAFywVQA88WI/oCE8tqyx/LP8mAQPsAkl8D4gB4AfoA9AQw+CdvIjBQCqEhvvLgUIIQcGx1Z4MesXCAGFAEywUmzxZY+gIZ9ADLaRfLH1Jgyz8gyYBA+wAGdYbenA=="

  _, err := tonconnect.ParseStateInit(stateInit)
  if err != nil {
    log.Fatal(err) 
  }
    // ok
  fmt.Println("parsed 1")

  stateInitBytes, err := base64.StdEncoding.DecodeString(stateInit)
  if err != nil {
    log.Fatal(err)
  }

  _, err = cell.FromBOC(stateInitBytes)
  if err != nil {
    log.Fatal(err) // failed to parse payload: recursive reference of cells
  }
  fmt.Println("parsed 2")

}

findLastTransactionByHash does not work as expected

  1. Only first transaction in txList for out message checked:
		for i, transaction := range txList {
			if i == 0 {
				// get previous of the oldest tx, in case if we need to scan deeper
				lastLt, lastHash = txList[0].PrevTxLT, txList[0].PrevTxHash
			}

			if isOut {
				if transaction.IO.Out == nil {
					continue
				}

				list, err := transaction.IO.Out.ToSlice()
				if err != nil {
					return nil, fmt.Errorf("cannot list out messages: %w", err)
				}

				for _, m := range list {
					if bytes.Equal(m.Msg.Payload().Hash(), msgHash) {
						return transaction, nil
					}
				}
                  // TODO: continue required for other transactions check 
                 // TODO: return transaction, nil at the end of range txList { also should be fixed
...
  1. m.Msg.Payload().Hash() calculation seems wrong. It calculates hash different than what is displayed in ton explorer. Transaction hash remains correct.

api.SubscribeOnTransactions cannot monitor transactions with ton transfer 0

Hi,

  1. I sent a ton transfer transaction
    bounce := false
    transfer, _ := w.BuildTransfer(to, tlb.MustFromTON("0"), bounce, "test")
    tx, _, _ := w.SendWaitTransaction(ctx, transfer)
  2. When monitoring the to address to use the following code, I cannot receive tx, but I can see the transaction in explorer
    go api.SubscribeOnTransactions(context.Background(), treasuryAddress, lastProcessedLT, transactions)
    for tx := range transactions {}
  3. But when I modify the sent ton amount to not be 0, I can monitor the transaction, so how should I modify code to monitor the transaction with ton transfer of 0?
    Thank you!

Out message list can be nil in FindLastTransactionByOutMsgHash

Looks like transaction.IO.Out can be nil in FindLastTransactionByOutMsgHash and condition transaction.IO.Out == nil required:

			if isOut {
				list, err := transaction.IO.Out.ToSlice()
				if err != nil {
					return nil, fmt.Errorf("cannot list out messages: %w", err)
				}

				for _, m := range list {
					if bytes.Equal(m.Msg.Payload().Hash(), msgHash) {
						return transaction, nil
					}
				}
			} else {
...

Accessing validator-engine-console with ADNL client

I am trying to use ConnectionPool for accessing validator-engine-console with more or less the following code:

tl.Register(ValidatorStats{}, "engine.validator.getStats = engine.validator.Stats")
...
client := liteclient.NewConnectionPool()

// Read key files etc...

err = client.AddConnection(
	context.Background(),
	"NODE_IP:PORT",
	serverKeyPubB64,
	clinetKeyFull,
)
if err != nil {
	panic(err)
}
fmt.Println("Connected to server")

var resp tl.Serializable
err = client.QueryADNL(context.Background(), ValidatorStats{}, &resp)
if err != nil {
	panic(err)
}
...

What I am getting in response is engine.validator.ControlQueryError with Code:602 Message:forbidden.

Running validator-engine-console against the same host with the same keys works fine.

So my question is if it is possible to use the library to access validator-engine-console, or is it strictly specific to lite server? If so if you could point me to some resources to understand the specificity I would be very grateful (I am not proficient enough in c++ to figure it out quickly from Ton codebase).

Fix policy ProofCheckPolicyFast with multiple existing shards

Hey! Could you please check, current example is not work. Probably this happened because multiple shard became alive in mainnet. I found out that error appears in this switch case with zero value in ab variable. Could you please research it and maybe adding another case to this switch case would fix the problem? And then I switched mode to ProofCheckPolicyUnsafe, checks was skipped and everything works well. Is it safe to use ProofCheckPolicyUnsafe?

always get "Transfer err:failed to get account state: adnl request timeout, node 185.86.79.9:4701",why this happen?

here is my code

var messages []*wallet.Message
messages = append(messages, &wallet.Message{
    Mode: 1,
    InternalMessage: &tlb.InternalMessage{
    Bounce:  false,
    DstAddr: addr,
    Amount:  amount,
    Body:    comment,
  },
})
// send tx and wait for it
tx, block, err := w.SendManyWaitTransaction(context.Background(), messages)
if err != nil {
	global.LOG.Sugar().Error("Transfer err:", err.Error())
	return err
}

Issue sending JETTON USDT - "failed to run get_wallet_address method: contract exit code: -256 (contract is not initialized)"

Context

  • I am hoping to have a script that sends USDT to other users (New and Old wallets)
  • However, when I am trying to do that, I got this weird error

Logs

{"time":"2024-06-11T00:45:29.191189+08:00","level":"ERROR","msg":"error sending USDT","error":"failed to run get_wallet_address method: contract exit code: -256 (contract is not initialized)"}

Error Message

failed to run get_wallet_address method: contract exit code: -256 (contract is not initialized

Code

	seeds := strings.Split(mnemonic, " ")
	w, err := wallet.FromSeed(api, seeds, wallet.V4R2)
	if err != nil {
		return nil, err
	}

        destAddr, err := address.ParseAddr(to)
	if err != nil {
		return nil, err
	}

	token := jetton.NewJettonMasterClient(c.api, address.MustParseAddr(contract.ContractAddress))

	// find our jetton wallet
        // where the error happens and I am not sure why? 
        // it used to work :( 
	tokenWallet, err := token.GetJettonWallet(ctx, w.WalletAddress())
	if err != nil {
		return nil, err
	}

	tokenBalance, err := tokenWallet.GetBalance(ctx)
	if err != nil {
		return nil, err
	}

	amountTokens, err := tlb.FromDecimal(amount, 0)
	if err != nil {
		return nil, err
	}

	if tokenBalance.Int64() < amountTokens.Nano().Int64() {
		slog.Warn("token balance", "balance", tokenBalance.Int64(), "amount", amountTokens.Nano().Int64())
		return nil, ErrHotWalletInsufficientBalance
	}

	comment, err := wallet.CreateCommentCell(reqID)
	if err != nil {
		return nil, err
	}

	// address of receiver's wallet (not token wallet, just usual)
	transferPayload, err := tokenWallet.BuildTransferPayloadV2(destAddr, destAddr, amountTokens, tlb.ZeroCoins, comment, nil)
	if err != nil {
		return nil, err
	}

	msg := wallet.SimpleMessage(tokenWallet.Address(), amountTokens, transferPayload)

	tx, _, err := w.SendWaitTransaction(ctx, msg)
	if err != nil {
		return nil, err
	}

	return tx, nil

`Merkle proofs automatic validation` feature

Hi!

In readme file, Merkle proofs automatic validation is not checked.
But I see Merkle proofs are checked in the features.
How can I make sure that Merkle proofs work on my integration?

Beat Regards.

Support wallet V3R1

Hey there,
is it possible to add support for V3R1 wallets? now only V3R2 implemented

case V3:
data = cell.BeginCell().
MustStoreUInt(0, 32). // seqno
MustStoreUInt(uint64(subWallet), 32). // sub wallet
MustStoreSlice(pubKey, 256).
EndCell()
case V4R2:
data = cell.BeginCell().
MustStoreUInt(0, 32). // seqno
MustStoreUInt(uint64(subWallet), 32).
MustStoreSlice(pubKey, 256).
MustStoreDict(nil). // empty dict of plugins
EndCell()
case HighloadV2R2:
data = cell.BeginCell().
MustStoreUInt(uint64(subWallet), 32).
MustStoreUInt(0, 64). // last cleaned
MustStoreSlice(pubKey, 256).
MustStoreDict(nil). // old queries
EndCell()

return tx after Transfer

Hi! Thanks for your great library.

I have an issue about getting tx after calling func (w *Wallet) Transfer.
Right now I am passing context, address, amount and comment to Transfer, but the only return is error. How can I broadcast my transaction with amount, address and comment, and get the tx?

One solution is after transaction I can read the last transaction, but this does not work for me as the number of requests are high in a sec.

I checked the SendManyWaitTxHash and SendManyWaitTransaction but they only accept ctx and message.

mint jetton

Can you provide an example of a mint jetton?

jetton.GetJettonDataAtBlock doest works for jetton contracts

If you need to access Jetton contract data, such as the name, symbol, or decimals, you'll encounter an issue because the GetJettonDataAtBlock method currently only refers to the NFT package and parses NFT data.

content, err := nft.ContentFromCell(contentCell)
if err != nil {
return nil, fmt.Errorf("failed to load content from contentCell: %w", err)
}

So ContentOnchain in a ContentFromCell for jetton method must look like that:

ContentOnchain: &ContentOnchain{
	Address:     string(getOnchainVal(dict, "address")),
	Name:        string(getOnchainVal(dict, "name")),
	Symbol:      string(getOnchainVal(dict, "symbol")),
	Decimals:    string(getOnchainVal(dict, "decimals")),
	Image:       string(getOnchainVal(dict, "image")),
	Description: string(getOnchainVal(dict, "description")),
	attributes:  dict,
},

I plan to create a pull request later unless someone else addresses this first.

如何设置excess地址

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

	// find our jetton wallet
	tokenWallet, err := token.GetJettonWallet(context.Background(), wallet.WalletAddress())
	if err != nil {
		return nil, err
	}
	comment, err := pkgTonWallet.CreateCommentCell(memo)
	if err != nil {
		return nil, err
	}
	transferPayload, err := tokenWallet.BuildTransferPayloadV2(address.MustParseAddr(toStr), address.MustParseAddr(responseToStr), tlb.MustFromNano(value, tokenDecimal), tlb.MustFromTON("0.000000001"), comment, nil)
	if err != nil {
		return nil, err
	}
	unsignedTx = pkgTonWallet.SimpleMessage(tokenWallet.Address(), tlb.MustFromTON("0.05"), transferPayload)

`

构建交易,发现excess地址永远是jetton收款地址(to),如何将excess设置成发送方地址(from)?

Highload wallet V3 computes wrong wallet address

I use the function below to generate and deploy a highload V3 wallet. However, when I instantiate a wallet.Wallet instance from the seed or the private key the address returned by WalletAddress() is not correct.

When I run the code I see the following output

Jul 24 13:14:26.911072 INF seed #1: april crush assault siege goddess budget expire input adapt lecture head pipe number upset cereal govern casual flat where mobile student ask meadow timber
Jul 24 13:14:26.934423 INF public key #1: 0x348bf53efe8cfb20a710bca3d9a6f87c33c7068b4c23eeecf808115cf104f7bc
Jul 24 13:14:26.934449 INF contract address #1: EQC11CCgZZ68UIJOT1T4nlm02MPamCeTiZ9qXPvH616e6RYN
Jul 24 13:14:26.934463 INF initial wallet address   #1: UQDjnFy4oIJEan6lPOIV2FvNTKpToz3HkoLEt0tgWh0JZNIB
Jul 24 13:14:49.090290 INF addr: EQC11CCgZZ68UIJOT1T4nlm02MPamCeTiZ9qXPvH616e6RYN
...

I can also see the wallet contract on tonviewer and interact with it

image image

The problem is that the address displayed by tonviewer (UQC11CCgZZ68UIJOT1T4nlm02MPamCeTiZ9qXPvH616e6UvI) is different from the one returned by WalletAddress() and logged by the code below (UQDjnFy4oIJEan6lPOIV2FvNTKpToz3HkoLEt0tgWh0JZNIB).

I believe this is a bug since both the public key and the subwallet id match in the deployed contract.

func (c *Client) genHighloadWallet(ctx context.Context, fw *wallet.Wallet, wNum int, codeCell *cell.Cell) (*wallet.Wallet, error) {
	seed := wallet.NewSeed()
	err := writeStringToFile(strings.Join(seed, " "), fmt.Sprintf("init-ton-%d", wNum))
	if err != nil {
		err = fmt.Errorf("failed to write seed #%d to file: %v", wNum, err)
		logger.Error().Msg(err.Error())
		return nil, err
	}
	logger.Info().Msgf("seed #%d: %s", wNum, strings.Join(seed, " "))
	mac := hmac.New(sha512.New, []byte(strings.Join(seed, " ")))
	hash := mac.Sum(nil)
	k := pbkdf2.Key(hash, []byte("TON default seed"), 100000, 32, sha512.New) // In TON libraries "TON default seed" is used as salt when getting keys
	highloadPrivateKey := ed25519.NewKeyFromSeed(k)                           // get private key
	highloadPublicKey := highloadPrivateKey.Public().(ed25519.PublicKey)      // get public key from private key

	logger.Info().Msgf("public key #%d: %v", wNum, hexutil.Encode(highloadPublicKey))

	dataCell := cell.BeginCell().
		MustStoreSlice(highloadPublicKey, 256). // Public Key
		MustStoreUInt(defaultSubWalletId, 32).  // Subwallet ID
		MustStoreBoolBit(false).                // indicate that the dictionary is empty
		MustStoreBoolBit(false).                // indicate that the dictionary is empty
		MustStoreUInt(0, 64).                   // Last cleaned
		MustStoreUInt(65536, 22).               // timeout
		EndCell()

	stateInit := cell.BeginCell().
		MustStoreBoolBit(false). // No split_depth
		MustStoreBoolBit(false). // No special
		MustStoreBoolBit(true).  // We have code
		MustStoreRef(codeCell).
		MustStoreBoolBit(true). // We have data
		MustStoreRef(dataCell).
		MustStoreBoolBit(false). // No library
		EndCell()

	contractAddress := address.NewAddress(0, 0, stateInit.Hash()) // get the hash of stateInit to get the address of our smart contract in workchain with ID 0
	logger.Info().Msgf("contract address #%d: %v", wNum, contractAddress.String())

	nw, err := wallet.FromPrivateKey(c.api, highloadPrivateKey, wallet.ConfigHighloadV3{
		MessageTTL: 120,
		MessageBuilder: func(_ context.Context, _ uint32) (id uint32, createdAt int64, err error) {
			tm := time.Now().Unix() - 30
			return uint32(10000 + tm%(1<<23)), tm, nil
		},
	})
	if err != nil {
		err = fmt.Errorf("failed to initialize wallet #%d: %v", wNum, err)
		logger.Error().Msg(err.Error())
		return nil, err
	}

	logger.Info().Msgf("initial wallet address   #%d: %v", wNum, nw.WalletAddress())
	addr, tx, block, err := fw.DeployContractWaitTransaction(ctx, tlb.MustFromTON("0.005"), cell.BeginCell().EndCell(), codeCell, dataCell)
	if err != nil {
		err = fmt.Errorf("failed to deploy wallet contract #%d: %v", wNum, err)
		logger.Error().Msg(err.Error())
		return nil, err
	}
	logger.Info().Msgf("addr: %v", addr.String())
	logger.Info().Msgf("tx: %v", tx)
	logger.Info().Msgf("block: %v", block)

	return nw, nil
}

failed to check proof: should have 2 roots

Some litenodes were updated in testnet yesterday and now we get this error on GetBlockShardsInfo():
v.1.8.9

failed to check proof: should have 2 roots

v1.9.0 return timeout

Could you please take a look?

GetBalance Error

An error occurred when I tried to parse out the address through the mnemonic phrase and obtain the address balance.

I tried using the mainnet configuration file, and errors occurred with the specified node.

2024/01/31 22:11:19 GetBalance err: failed to get account state: lite server error, code 651: too big masterchain block seqno exit status 1

This is why?

Send jetton with comment failed

Hi, when i send jetton without comment, it will do success, but when i add comment as payloadForward, the Jetton Notify tx always failed.
Follow is my code

	commentCell, err := wallet.CreateCommentCell(comment)
	if err != nil {
		return
	}
	transferPayload, err := tokenWallet.BuildTransferPayloadV2(toAddr, wal.WalletAddress(), amount, minTon, commentCell, nil)
	if err != nil {
		return
	}
	msg := wallet.SimpleMessageAutoBounce(tokenWallet.Address(), jettonTxFee, transferPayload)
	tx, block, err := wal.SendWaitTransaction(c, msg)

The tx is https://tonviewer.com/transaction/1ff4e7ae87f9903114d4b41d1de900a07465742166ce827283aa158495651f6d.

You can see the OpCode of 0x7362d09c(Jetton Notify) failed

But when i call without commentCell, it will success like this one:

https://tonviewer.com/transaction/30775d9c4f9770901dd493e3704859884f54c1757ce98a156a290e7f2b0495f5.

Please help me, thanks.

How can we get all transaction fees?

Hi,
How can we get all transaction fees like it declared in tonlib_api.tl ?

raw.transaction address:accountAddress utime:int53 data:bytes transaction_id:internal.transactionId fee:int64 storage_fee:int64 other_fee:int64 in_msg:raw.message out_msgs:vector = raw.Transaction;

While using tonlib client we always can get fee:int64 storage_fee:int64 other_fee:int64, but tonutils lib provides only TotalFees or I didn't find...

Could you please clarify this moment for me?

User-friendly to Raw adress conversion/comparison

Hi! In a nutshell, i'm building an app that detect transactions from specific addresses set by user so i need to compare user-friendly addresses (that user send to app) with raw addresses from subscription channel:

senderUFAddr := "sender-user-friendly-address"

go api.SubscribeOnTransactions(context.Background(), receiverAddress, lastProcessedLT, transactions)

for tx := range transactions {
	if tx.IO.In == nil || tx.IO.In.Msg == nil {
		fmt.Println("not an in message")
		continue
	}

	internalMessage, ok := tx.IO.In.Msg.(*tlb.InternalMessage)
	if !ok {
		fmt.Println("not an internal message")
		continue
	}

	senderRawAddr := internalMessage.SrcAddr.String()

	lastProcessedLT = tx.LT
}

How can i do this comparison with tonutils or i have to implement it on my own?

too small slice for this size

client := liteclient.NewClient()

err := client.Connect(context.Background(),
	"67.207.74.182:4924",
	"peJTw/arlRfssgTuf9BMypJzqOi7SXEqSPSWiEw2U1M=")
if err != nil {
	panic(err)
}
api := ton.NewAPIClient(client)
block, err := api.GetBlockInfo(context.Background())
if err != nil {
	Log.Fatalln("get block err:", err.Error())
	return
}

_, err = api.RunGetMethod(context.Background(), block, address.MustParseAddr("EQCunKWfEsKkdhSXZAEWDpck8rSvcIjV_V_6CBA6UsI0XRBu"), "get_nft_data")
if err != nil {
	Log.Errorf("run get method err: %s", err.Error())
	return
}
panic: too small slice for this size
goroutine 1 [running]:
github.com/xssnick/tonutils-go/tvm/cell.(*Builder).MustStoreSlice(...)
        .../github.com/xssnick/[email protected]/tvm/cell/builder.go:134
github.com/xssnick/tonutils-go/ton.(*APIClient).RunGetMethod(0xc000119f40, {0x70aec8, 0xc000016050}, 0xc000194140, 0xc0001820a0, {0x6d1222, 0xc}, {0x0, 0x0, 0x0})
        .../github.com/xssnick/[email protected]/ton/api.go:253 +0x1745
main.main()
        .../test/lite-client.go:29 +0x205
> runmethod EQCunKWfEsKkdhSXZAEWDpck8rSvcIjV_V_6CBA6UsI0XRBu get_nft_data
[ 3][t 1][2022-04-29 00:52:24.707931189][lite-client.cpp:1324][!testnode]       requesting remote get-method execution for 0:AE9CA59F12C2A47614976401160E9724F2B4AF7088D5FD5FFA08103A52C2345D with respect to (-1,8000000000000000,20168059):A348D3D666FF09B2FAEC3F06419F7D9CA9F1B6CC4FF62D0E865C8040D05994CB:F14E06284BC7A8F525EC1BE4210A7D56EE9FECF58AB8466BB6F48D2FAB75D489 to run method get_nft_data with 0 parameters
[ 3][t 2][2022-04-29 00:52:24.767547252][lite-client.cpp:1998][!testnode]       got (partial) account state (637 bytes) with mode=31 for 0:AE9CA59F12C2A47614976401160E9724F2B4AF7088D5FD5FFA08103A52C2345D with respect to blocks (-1,8000000000000000,20168059):A348D3D666FF09B2FAEC3F06419F7D9CA9F1B6CC4FF62D0E865C8040D05994CB:F14E06284BC7A8F525EC1BE4210A7D56EE9FECF58AB8466BB6F48D2FAB75D489 and (0,8000000000000000,25326017):6FEB8CDE0C810A3CBC4FEEC5685103FD5FCEF48B7DDCEAF320668D153369796D:6DA394AC82E92EAD9F9770796F9260CB5B3C2CD2A91AEA2DEB075C5CC8AA6BF9
[ 3][t 2][2022-04-29 00:52:24.767826707][lite-client.cpp:2095][!testnode]       starting VM to run method `get_nft_data` (102351) of smart contract 0:AE9CA59F12C2A47614976401160E9724F2B4AF7088D5FD5FFA08103A52C2345D
arguments:  [ 102351 ]
result:  [ -1 0 CS{Cell{0295000000000000000080051eec1b065126304253957c14810c949f9902ec722d1aa47adb690497b32f7cd0027e457611181313ddf9812a3ef5d3b9dcf80c7f1bdb9ff8d57fc9e74a3ce93c46} bits: 64..331; refs: 0..0} CS{Cell{0295000000000000000080051eec1b065126304253957c14810c949f9902ec722d1aa47adb690497b32f7cd0027e457611181313ddf9812a3ef5d3b9dcf80c7f1bdb9ff8d57fc9e74a3ce93c46} bits: 331..598; refs: 0..0} C{62EDF0EE80EF8562B380870C568CB4965EBED8FFF0308548C263FB9FAD023020} ]
remote result (not to be trusted):  [ -1 0 CS{Cell{0295000000000000000080051eec1b065126304253957c14810c949f9902ec722d1aa47adb690497b32f7cd0027e457611181313ddf9812a3ef5d3b9dcf80c7f1bdb9ff8d57fc9e74a3ce93c46} bits: 64..331; refs: 0..0} CS{Cell{0295000000000000000080051eec1b065126304253957c14810c949f9902ec722d1aa47adb690497b32f7cd0027e457611181313ddf9812a3ef5d3b9dcf80c7f1bdb9ff8d57fc9e74a3ce93c46} bits: 331..598; refs: 0..0} C{62EDF0EE80EF8562B380870C568CB4965EBED8FFF0308548C263FB9FAD023020} ]
[ 3][t 2][2022-04-29 00:52:24.767973694][lite-client.cpp:1225][!testnode]       caching cell 62EDF0EE80EF8562B380870C568CB4965EBED8FFF0308548C263FB9FAD023020

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.