diff --git a/.github/workflows/tonlib-linux.yml b/.github/workflows/tonlib-linux.yml index aab76b1..e727bde 100644 --- a/.github/workflows/tonlib-linux.yml +++ b/.github/workflows/tonlib-linux.yml @@ -17,7 +17,7 @@ jobs: - name: Fetch TON repo run: | cd .. - git clone --recursive https://github.com/ton-blockchain/ton + git clone --recursive https://github.com/newton-blockchain/ton - name: Build tonlibjson run: | @@ -26,6 +26,7 @@ jobs: cd build cmake ../ton -DCMAKE_BUILD_TYPE=Release cmake --build . --target tonlibjson + make tonlibjson_static - name: Copy built lib run: | diff --git a/.github/workflows/tonlib-macos.yml b/.github/workflows/tonlib-macos.yml index 3f42e45..a2475e5 100644 --- a/.github/workflows/tonlib-macos.yml +++ b/.github/workflows/tonlib-macos.yml @@ -17,7 +17,7 @@ jobs: - name: Fetch TON repo run: | cd .. - git clone --recursive https://github.com/ton-blockchain/ton + git clone --recursive https://github.com/newton-blockchain/ton - name: Build tonlibjson run: | @@ -26,6 +26,7 @@ jobs: cd build cmake ../ton -DOPENSSL_ROOT_DIR=$(brew --prefix)/opt/openssl -DCMAKE_BUILD_TYPE=Release cmake --build . --target tonlibjson + make tonlibjson_static - name: Copy built lib run: | diff --git a/.gitignore b/.gitignore index f73b40b..77af0b2 100644 --- a/.gitignore +++ b/.gitignore @@ -12,5 +12,15 @@ .idea ./vendor +# tonlib-c files +lib/linux* +lib/linux + +lib/linux/*.so +lib/linux/*.a + +tlgenerator + # auto generated files -test.keys/* \ No newline at end of file +test.keys/* +test.keys.testnet/* diff --git a/client.go b/client.go index 6331fb1..0338ac9 100644 --- a/client.go +++ b/client.go @@ -166,7 +166,6 @@ func (client *Client) executeSynchronously(data interface{}) (*TONResult, error) func (client *Client) Destroy() { C.tonlib_client_json_destroy(client.client) - C.free(client.client) } //sync node`s blocks to current diff --git a/cmd/tlgenerator/tlStructGenerator.go b/cmd/tlgenerator/tlStructGenerator.go index c98aba1..d6e639f 100644 --- a/cmd/tlgenerator/tlStructGenerator.go +++ b/cmd/tlgenerator/tlStructGenerator.go @@ -382,7 +382,7 @@ func generateStructsFromTnEntities( } } - illStr := `fmt.Errorf("error! code: %d msg: %s", result.Data["code"], result.Data["message"])` + illStr := `fmt.Errorf("error! code: %v msg: %s", result.Data["code"], result.Data["message"])` if strings.Contains(paramsStr, returnTypeCamel) { returnTypeCamel = returnTypeCamel + "Dummy" } diff --git a/example/send_gram.go b/example/send_gram.go index 87efa07..a60e52e 100644 --- a/example/send_gram.go +++ b/example/send_gram.go @@ -43,7 +43,7 @@ func main() { base64.StdEncoding.EncodeToString(loc), tonlib.TONPrivateKey{ pKey.PublicKey, - base64.StdEncoding.EncodeToString((*pKey.Secret)[:]), + base64.StdEncoding.EncodeToString([]byte(pKey.Secret)), }, } diff --git a/go.mod b/go.mod index 4ad7c88..8ffb503 100644 --- a/go.mod +++ b/go.mod @@ -4,8 +4,5 @@ go 1.13 require ( github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a - github.com/dvsekhvalnov/jose2go v0.0.0-20180829124132-7f401d37b68a // indirect - github.com/joho/godotenv v1.3.0 // indirect - github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24 // indirect github.com/spf13/cobra v0.0.5 ) diff --git a/go.sum b/go.sum index ddff373..7bb9446 100644 --- a/go.sum +++ b/go.sum @@ -7,22 +7,16 @@ github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8Nz github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/dvsekhvalnov/jose2go v0.0.0-20180829124132-7f401d37b68a h1:mq+R6XEM6lJX5VlLyZIrUSP8tSuJp82xTK89hvBwJbU= -github.com/dvsekhvalnov/jose2go v0.0.0-20180829124132-7f401d37b68a/go.mod h1:7BvyPhdbLxMXIYTFPLsyJRFMsKmOZnQmzh6Gb+uquuM= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= -github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg= github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= -github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24/go.mod h1:M+9NzErvs504Cn4c5DxATwIqPbtswREoFCre64PpcG4= -github.com/shopspring/decimal v0.0.0-20190905144223-a36b5d85f337 h1:Da9XEUfFxgyDOqUfwgoTDcWzmnlOnCGi6i4iPS+8Fbw= -github.com/shopspring/decimal v0.0.0-20190905144223-a36b5d85f337/go.mod h1:M+9NzErvs504Cn4c5DxATwIqPbtswREoFCre64PpcG4= github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= github.com/spf13/cobra v0.0.5 h1:f0B+LkLX6DtmRH1isoNA9VTtNUK9K8xYd28JNNfOv/s= diff --git a/lib/darwin/libtonlib.a b/lib/darwin/libtonlib.a deleted file mode 100644 index 07f542b..0000000 Binary files a/lib/darwin/libtonlib.a and /dev/null differ diff --git a/lib/darwin/libtonlibjson.0.5.dylib b/lib/darwin/libtonlibjson.0.5.dylib deleted file mode 100644 index ad1cf8c..0000000 Binary files a/lib/darwin/libtonlibjson.0.5.dylib and /dev/null differ diff --git a/lib/darwin/libtonlibjson.dylib b/lib/darwin/libtonlibjson.dylib deleted file mode 100644 index ad1cf8c..0000000 Binary files a/lib/darwin/libtonlibjson.dylib and /dev/null differ diff --git a/lib/darwin/libtonlibjson_private.a b/lib/darwin/libtonlibjson_private.a deleted file mode 100644 index df57b16..0000000 Binary files a/lib/darwin/libtonlibjson_private.a and /dev/null differ diff --git a/lib/darwin/libtonlibjson_static.a b/lib/darwin/libtonlibjson_static.a deleted file mode 100644 index db1eb44..0000000 Binary files a/lib/darwin/libtonlibjson_static.a and /dev/null differ diff --git a/lib/lib.go b/lib/lib.go index e7aae82..16fe1f4 100644 --- a/lib/lib.go +++ b/lib/lib.go @@ -2,5 +2,4 @@ package linux import ( _ "github.com/mercuryoio/tonlib-go/lib/darwin" - _ "github.com/mercuryoio/tonlib-go/lib/linux" ) diff --git a/lib/linux/libtonlib.a b/lib/linux/libtonlib.a deleted file mode 100644 index 736504d..0000000 Binary files a/lib/linux/libtonlib.a and /dev/null differ diff --git a/lib/linux/libtonlibjson.so b/lib/linux/libtonlibjson.so deleted file mode 100755 index 83674f1..0000000 Binary files a/lib/linux/libtonlibjson.so and /dev/null differ diff --git a/lib/linux/libtonlibjson.so.0.5 b/lib/linux/libtonlibjson.so.0.5 deleted file mode 100755 index 83674f1..0000000 Binary files a/lib/linux/libtonlibjson.so.0.5 and /dev/null differ diff --git a/lib/linux/libtonlibjson_private.a b/lib/linux/libtonlibjson_private.a deleted file mode 100644 index c68c006..0000000 Binary files a/lib/linux/libtonlibjson_private.a and /dev/null differ diff --git a/lib/linux/libtonlibjson_static.a b/lib/linux/libtonlibjson_static.a deleted file mode 100644 index f599a3e..0000000 Binary files a/lib/linux/libtonlibjson_static.a and /dev/null differ diff --git a/tonlib.mainnet.json.example b/tonlib.mainnet.json.example new file mode 100644 index 0000000..edc395c --- /dev/null +++ b/tonlib.mainnet.json.example @@ -0,0 +1,223 @@ +{ + "config": { + "config": { + "@type": "config.global", + "dht": { + "@type": "dht.config.global", + "k": 6, + "a": 3, + "static_nodes": { + "@type": "dht.nodes", + "nodes": [ + { + "@type": "dht.node", + "id": { + "@type": "pub.ed25519", + "key": "znOAvy1ECxyzeKishi4PdSO2edaVx78wynVyNKLBmQ8=" + }, + "addr_list": { + "@type": "adnl.addressList", + "addrs": [ + { + "@type": "adnl.address.udp", + "ip": -1068377703, + "port": 6302 + } + ], + "version": 0, + "reinit_date": 0, + "priority": 0, + "expire_at": 0 + }, + "version": -1, + "signature": "KLH17nNKmOk3carKwbsUcVBc4JZpdAUdUOMxe8FSyqnkOw/lolnltbylJcC+lvPpIV5ySI/Qx8UZdNRV/4HzCA==" + }, + { + "@type": "dht.node", + "id": { + "@type": "pub.ed25519", + "key": "Qjhv9rmeqXm0a+nYYhCJG1AH7C2TM6DAmyIM3FgO0Eo=" + }, + "addr_list": { + "@type": "adnl.addressList", + "addrs": [ + { + "@type": "adnl.address.udp", + "ip": -1057912003, + "port": 6302 + } + ], + "version": 0, + "reinit_date": 0, + "priority": 0, + "expire_at": 0 + }, + "version": -1, + "signature": "2Gw5eIsZR+SdbWCU139DCuBI8Rv8T9iUioxDkgV6/IjcCHf6hNz8WCyUsKd5l5P1NBs/kdaxUBIybINDpYXoCw==" + }, + { + "@type": "dht.node", + "id": { + "@type": "pub.ed25519", + "key": "2YsTRIu3aRYzZe8eoR8PK2N2ydHJyKllwKcLPk676d4=" + }, + "addr_list": { + "@type": "adnl.addressList", + "addrs": [ + { + "@type": "adnl.address.udp", + "ip": -1057911744, + "port": 6302 + } + ], + "version": 0, + "reinit_date": 0, + "priority": 0, + "expire_at": 0 + }, + "version": -1, + "signature": "9/TJsaj0wELvRKXVIrBdyZWjgLKhfSvl7v0Oqq/9p9MsU/t9iRuGcpAzHqQF4bQAWrN8j9ARwMumRata7dH8Bg==" + }, + { + "@type": "dht.node", + "id": { + "@type": "pub.ed25519", + "key": "SHrXmMEEUBGa51TWZwHSA+2RF4Vyavw51jgtnAz1ypU=" + }, + "addr_list": { + "@type": "adnl.addressList", + "addrs": [ + { + "@type": "adnl.address.udp", + "ip": -1057911148, + "port": 6302 + } + ], + "version": 0, + "reinit_date": 0, + "priority": 0, + "expire_at": 0 + }, + "version": -1, + "signature": "R4ku8+tvjKSLIGe18zWHBHDv1maQHD5tGbAUOgbldGpBvfqH+/b76XkJjJzDsjnCO/bpxwUZfcI1sM1h6vFJCQ==" + }, + { + "@type": "dht.node", + "id": { + "@type": "pub.ed25519", + "key": "G+Lr6UtSWUcyYHTUutwbxrIG9GGZan3h96j8qQPLIXQ=" + }, + "addr_list": { + "@type": "adnl.addressList", + "addrs": [ + { + "@type": "adnl.address.udp", + "ip": -960017601, + "port": 6302 + } + ], + "version": 0, + "reinit_date": 0, + "priority": 0, + "expire_at": 0 + }, + "version": -1, + "signature": "fWU9hSNLvmaSCQOBW9M4Lja5pIWcqOzU1g9vtSywdgtASj9oQpwAslvr2sjNh9E2Np1c26NW8Sc5gUKf8YY7BA==" + } + ] + } + }, + "liteservers": [ + { + "ip": 1137658550, + "port": "4924", + "id": { + "@type": "pub.ed25519", + "key": "peJTw/arlRfssgTuf9BMypJzqOi7SXEqSPSWiEw2U1M=" + } + }, + { + "ip": 1560268637, + "port": "6199", + "id": { + "@type": "pub.ed25519", + "key": "NSyVw0XhPhW4Yg5a3NhS1dkCc6ZY7Hex40tJ6EiBMAI=" + } + }, + { + "ip": 84478511, + "port": "19949", + "id": { + "@type": "pub.ed25519", + "key": "n4VDnSCUuSpjnCyUk9e3QOOd6o0ItSWYbTnW3Wnn8wk=" + } + }, + { + "ip": 84478479, + "port": "48014", + "id": { + "@type": "pub.ed25519", + "key": "3XO67K/qi+gu3T9v8G2hx1yNmWZhccL3O7SoosFo8G0=" + } + }, + { + "ip": -2018135749, + "port": "53312", + "id": { + "@type": "pub.ed25519", + "key": "aF91CuUHuuOv9rm2W5+O/4h38M3sRm40DtSdRxQhmtQ=" + } + }, + { + "ip": -2018145068, + "port": "13206", + "id": { + "@type": "pub.ed25519", + "key": "K0t3+IWLOXHYMvMcrGZDPs+pn58a17LFbnXoQkKc2xw=" + } + }, + { + "ip": -2018145059, + "port": "46995", + "id": { + "@type": "pub.ed25519", + "key": "wQE0MVhXNWUXpWiW5Bk8cAirIh5NNG3cZM1/fSVKIts=" + } + } + ], + "validator": { + "@type": "validator.config.global", + "zero_state": { + "workchain": -1, + "shard": -9223372036854775808, + "seqno": 0, + "root_hash": "F6OpKZKqvqeFp6CQmFomXNMfMj2EnaUSOXN+Mh+wVWk=", + "file_hash": "XplPz01CXAps5qeSWUtxcyBfdAo5zVb1N979KLSKD24=" + }, + "init_block" : { + "root_hash": "irEt9whDfgaYwD+8AzBlYzrMZHhrkhSVp3PU1s4DOz4=", + "seqno": 10171687, + "file_hash": "lay/bUKUUFDJXU9S6gx9GACQFl+uK+zX8SqHWS9oLZc=", + "workchain": -1, + "shard": -9223372036854775808 + }, + "hardforks": [ + { + "file_hash": "t/9VBPODF7Zdh4nsnA49dprO69nQNMqYL+zk5bCjV/8=", + "seqno": 8536841, + "root_hash": "08Kpc9XxrMKC6BF/FeNHPS3MEL1/Vi/fQU/C9ELUrkc=", + "workchain": -1, + "shard": -9223372036854775808 + } + ] + } + }, + "blockchain_name": "mainnet", + "use_callbacks_for_network": false, + "ignore_cache": false + }, + "keystore_type": { + "@type": "keyStoreTypeDirectory", + "directory": "./main.keys" + } +} diff --git a/utils.go b/utils.go index 460559e..b2cb172 100644 --- a/utils.go +++ b/utils.go @@ -18,11 +18,13 @@ type TonlibListenserverConfig struct { ID map[string]string `json:"id"` } type ValidatorConfig struct { - Type string `json:"@type"` - ZeroState ZeroState `json:"zero_state"` + Type string `json:"@type"` + ZeroState InitBlock `json:"zero_state"` + InitBlock InitBlock `json:"init_block,omitempty"` + Hardforks []InitBlock `json:"hardforks,omitempty"` } -type ZeroState struct { +type InitBlock struct { Workchain int `json:"workchain"` Shard int64 `json:"shard"` Seqno int `json:"seqno"` diff --git a/v2/client.go b/v2/client.go index 22cc592..5dbc560 100644 --- a/v2/client.go +++ b/v2/client.go @@ -9,16 +9,21 @@ package v2 import "C" import ( "encoding/json" + "errors" "fmt" "math/rand" + "regexp" + "strconv" "sync" + "sync/atomic" "time" "unsafe" ) const ( - DEFAULT_TIMEOUT = 4.5 - DefaultRetries = 10 + NodeTimeoutSeconds = 4.5 + WaitTimeout = 60 * time.Second + ForceUnlockSyncTimeout = 10 * time.Second ) type InputKey struct { @@ -27,6 +32,7 @@ type InputKey struct { Key TONPrivateKey `json:"key"` } type TONPrivateKey struct { + Type string `json:"@type"` PublicKey string `json:"public_key"` Secret string `json:"secret"` } @@ -47,6 +53,24 @@ type KeyStoreType struct { // TONResponse alias for use in TONResult type TONResponse map[string]interface{} +func (o TONResponse) getType() (string, bool) { + t, ok := o["@type"].(string) + if !ok { + t = "" + } + + return t, ok +} + +func (o TONResponse) getExtra() (string, bool) { + extra, ok := o["@extra"].(string) + if !ok { + extra = "" + } + + return extra, ok +} + // TONResult is used to unmarshal received json strings into type TONResult struct { Data TONResponse @@ -55,6 +79,24 @@ type TONResult struct { // Client is the Telegram TdLib client type Client struct { + syncInProgress bool + + extraToRespChan map[string]chan *TONResult + + respMapMu *sync.RWMutex + receiveMu *sync.Mutex + syncMu *sync.RWMutex + syncUtilsMu *sync.Mutex + + uniqClientID string + + uniqExtra *uint64 + + filterLogRe *regexp.Regexp + + stopChan chan struct{} + syncChan chan *TONResult + client unsafe.Pointer config Config timeout int64 @@ -68,12 +110,41 @@ type TonInitRequest struct { Options Options `json:"options"` } -// NewClient Creates a new instance of TONLib. -func NewClient(tonCnf *TonInitRequest, config Config, timeout int64, clientLogging bool, tonLogging int32) (*Client, error) { +func NewClient(tonCnf *TonInitRequest, config Config, timeout int64, + clientLogging bool, tonLogging int32) (*Client, error) { + uniqClientID := strconv.FormatUint(rand.Uint64(), 10) + + return NewClientWithUniqID(tonCnf, config, timeout, clientLogging, tonLogging, uniqClientID) +} + +// NewClientWithUniqID Creates a new instance of TONLib. +// @uniqClientID - is not important for executing. Using just for logging for identify client +func NewClientWithUniqID(tonCnf *TonInitRequest, config Config, timeout int64, + clientLogging bool, tonLogging int32, uniqClientID string) (*Client, error) { rand.Seed(time.Now().UnixNano()) + cli := C.tonlib_client_json_create() + + extra := uint64(0) + client := Client{ - client: C.tonlib_client_json_create(), + syncInProgress: false, + extraToRespChan: make(map[string]chan *TONResult), + respMapMu: &sync.RWMutex{}, + receiveMu: &sync.Mutex{}, + syncMu: &sync.RWMutex{}, + syncUtilsMu: &sync.Mutex{}, + + uniqClientID: uniqClientID, + + uniqExtra: &extra, + + filterLogRe: regexp.MustCompile(`"(local_password|mnemonic_password|secret|word_list)":("(\\"|[^"])*"|\[("(\\"|[^"])*"(,"(\\"|[^"])*")*)?\])`), + + stopChan: make(chan struct{}), + syncChan: make(chan *TONResult), + + client: cli, config: config, timeout: timeout, clientLogging: clientLogging, @@ -84,282 +155,414 @@ func NewClient(tonCnf *TonInitRequest, config Config, timeout int64, clientLoggi // disable ton logs if needed err := client.executeSetLogLevel(tonLogging) if err != nil { - return &client, err + return nil, errors.New( + client.formatLog("", fmt.Sprintf("error set log level. Error: %v", err))) } + go client.receiveWorker() + go client.syncWorker() + optionsInfo, err := client.Init(tonCnf.Options) if err != nil { - return &client, err + return nil, errors.New( + client.formatLog("", fmt.Sprintf("error init client. Error: %v", err))) } if optionsInfo.tonCommon.Type == "options.info" { return &client, nil } + + client.stopChan <- struct{}{} + close(client.stopChan) + close(client.syncChan) if optionsInfo.tonCommon.Type == "error" { - return &client, fmt.Errorf("Error ton client init. Message: %s. ", optionsInfo.tonCommon.Extra) + return nil, fmt.Errorf(client.formatLog(optionsInfo.Extra, "error client init")) } - return &client, fmt.Errorf("Error ton client init. ") + + return nil, fmt.Errorf(client.formatLog(optionsInfo.Extra, "error NewClient")) } -// disable ton client C lib`s logs -func (client *Client) executeSetLogLevel(logLevel int32) error { - data := struct { - Type string `json:"@type"` - NewVerbosityLevel int32 `json:"new_verbosity_level"` - }{ - Type: "setLogVerbosityLevel", - NewVerbosityLevel: logLevel, +func (client *Client) formatLog(extra, logStr string) string { + logStr = client.filterLogRe.ReplaceAllString(logStr, "\"$1\":\"hided\"") + + return fmt.Sprintf("clientID:%s, extra:%s, log:%s", client.uniqClientID, extra, logStr) +} + +func (client *Client) printLog(extra, logStr string) { + if client.clientLogging { + fmt.Println(client.formatLog(extra, logStr)) } +} + +func (client *Client) getNewExtra() string { + return strconv.FormatUint(atomic.AddUint64(client.uniqExtra, 1), 10) +} + +func (client *Client) sendAsync(extra string, data interface{}) error { req, err := json.Marshal(data) if err != nil { return err } + + client.printLog(extra, fmt.Sprintf("call: %s", string(req))) + cs := C.CString(string(req)) defer C.free(unsafe.Pointer(cs)) - if client.clientLogging { - fmt.Println("call execute setLogVerbosityLevel: ", string(req)) - } - C.tonlib_client_json_execute(client.client, cs) + // send may be async + C.tonlib_client_json_send(client.client, cs) + return nil } -/** -execute ton-lib asynchronously -*/ -func (client *Client) executeAsynchronously(data interface{}) (*TONResult, error) { - req, err := json.Marshal(data) +func (client *Client) execReceive() []byte { + // receive must be sync + result := C.tonlib_client_json_receive(client.client, NodeTimeoutSeconds) + + if result == nil { + return nil + } + + res := C.GoString(result) + resB := []byte(res) + + return resB +} + +func (client *Client) receiveOne() error { + // receive and sync must be syncrinious + client.receiveMu.Lock() + defer client.receiveMu.Unlock() + + resB := client.execReceive() + if resB == nil { + return nil + } + + var updateData TONResponse + err := json.Unmarshal(resB, &updateData) if err != nil { - return &TONResult{}, err + return err } - cs := C.CString(string(req)) - defer C.free(unsafe.Pointer(cs)) - if client.clientLogging { - fmt.Println("call", string(req)) + data := &TONResult{Data: updateData, Raw: resB} + + extra, extraOk := data.Data.getExtra() + + client.printLog(extra, fmt.Sprintf("fetch data: %s", string(resB))) + + respType, ok := data.Data.getType() + if !ok { + return errors.New( + client.formatLog(extra, + fmt.Sprintf("error. Resp does not contains type field. Resp: %s", string(data.Raw)))) } - C.tonlib_client_json_send(client.client, cs) - result := C.tonlib_client_json_receive(client.client, DEFAULT_TIMEOUT) - num := 0 - for result == nil { - if num >= DefaultRetries { - return &TONResult{}, fmt.Errorf("Client.executeAsynchronously: exided limit of retries to get json response from TON C`s lib. ") - } - time.Sleep(1 * time.Second) - result = C.tonlib_client_json_receive(client.client, DEFAULT_TIMEOUT) - num += 1 + needService := client.checkNeedService(extra, respType, data) + if needService { + return nil } - var updateData TONResponse - res := C.GoString(result) - resB := []byte(res) - err = json.Unmarshal(resB, &updateData) - if client.clientLogging { - fmt.Println("fetch data: ", string(resB)) + if !extraOk { + return errors.New( + client.formatLog(extra, + fmt.Sprintf("error. Resp does not contains extra field. Resp: %s", string(data.Raw)))) } - if st, ok := updateData["@type"]; ok && st == "updateSendLiteServerQuery" { - err = json.Unmarshal(resB, &updateData) - if err == nil { - _, err = client.OnLiteServerQueryResult(updateData["data"].([]byte), updateData["id"].(JSONInt64)) - } + + ch, err := client.getFromStore(extra) + if err != nil { + return err } - if st, ok := updateData["@type"]; ok && st == "updateSyncState" { - syncResp := struct { - Type string `json:"@type"` - SyncState SyncState `json:"sync_state"` - }{} - err = json.Unmarshal(resB, &syncResp) - if err != nil { - return &TONResult{}, err - } - if client.clientLogging { - fmt.Println("run sync", updateData) - } - res, err = client.Sync(syncResp.SyncState) - if err != nil { - return &TONResult{}, err - } - if res != "" { - updateData = TONResponse{} - resB := []byte(res) - err = json.Unmarshal(resB, &updateData) + + ch <- data + + return nil +} + +func (client *Client) checkNeedService(extra, respType string, data *TONResult) bool { + switch respType { + case "updateSendLiteServerQuery": + go func() { + _, err := client.onLiteServerQueryResult(data.Data["data"].([]byte), data.Data["id"].(JSONInt64)) if err != nil { - return &TONResult{}, err + client.printLog(extra, fmt.Sprintf("error OnLiteServerQueryResult. Error: %v", err)) } - return &TONResult{Data: updateData, Raw: resB}, err - } + }() + return true + + case "updateSyncState": + go func() { + client.syncChan <- data + }() + return true + + case "ton.blockIdExt": + return true + + default: + return false } - return &TONResult{Data: updateData, Raw: resB}, err } -/** -execute ton-lib synchronously -*/ -func (client *Client) executeSynchronously(data interface{}) (*TONResult, error) { - req, _ := json.Marshal(data) - cs := C.CString(string(req)) - defer C.free(unsafe.Pointer(cs)) - result := C.tonlib_client_json_execute(client.client, cs) - var updateData TONResponse - res := C.GoString(result) - resB := []byte(res) - err := json.Unmarshal(resB, &updateData) - return &TONResult{Data: updateData, Raw: resB}, err +func (client *Client) receiveWorker() { + for { + select { + case <-client.stopChan: + client.printLog("", "receiveWorker. Stop") + return + + default: + if err := client.receiveOne(); err != nil { + client.printLog("", fmt.Sprintf("error receiveOne. Error: %v", err)) + } + + break + } + } } -func (client *Client) Destroy() { - C.tonlib_client_json_destroy(client.client) - //C.free(client.client) +func (client *Client) timerSyncProgress(t *time.Timer) { + <-t.C + + client.syncUnlock() } -//sync node`s blocks to current -func (client *Client) Sync(syncState SyncState) (string, error) { - data := struct { - Type string `json:"@type"` - SyncState SyncState `json:"sync_state"` - }{ - Type: "sync", - SyncState: syncState, - } - req, err := json.Marshal(data) - if err != nil { - return "", err +func (client *Client) syncLock() { + client.syncUtilsMu.Lock() + defer client.syncUtilsMu.Unlock() + + if !client.syncInProgress { + client.syncInProgress = true + client.syncMu.Lock() + + client.printLog("", "sync lock") } - cs := C.CString(string(req)) - defer C.free(unsafe.Pointer(cs)) - if client.clientLogging { - fmt.Println("call (sync)", string(req)) +} + +func (client *Client) syncUnlock() { + client.syncUtilsMu.Lock() + defer client.syncUtilsMu.Unlock() + + if client.syncInProgress { + client.syncInProgress = false + client.syncMu.Unlock() + + client.printLog("", "sync unlock") } - C.tonlib_client_json_send(client.client, cs) +} + +func (client *Client) syncWorker() { for { - result := C.tonlib_client_json_receive(client.client, DEFAULT_TIMEOUT) - for result == nil { - if client.clientLogging { - fmt.Println("empty response. next attempt") - } - time.Sleep(1 * time.Second) - result = C.tonlib_client_json_receive(client.client, DEFAULT_TIMEOUT) + data, ok := <-client.syncChan + if !ok { + client.printLog("", "sync. stop sync worker") + return + } + + respType, _ := data.Data.getType() + if respType != "updateSyncState" { + client.printLog("", fmt.Sprintf("sync. received wrong type. Skip. Resp:%s", string(data.Raw))) + continue } + syncResp := struct { Type string `json:"@type"` SyncState SyncState `json:"sync_state"` }{} - res := C.GoString(result) - resB := []byte(res) - err = json.Unmarshal(resB, &syncResp) - if client.clientLogging { - fmt.Println("sync result #1: ", res) - } + + err := json.Unmarshal(data.Raw, &syncResp) if err != nil { - return "", err - } - if syncResp.Type == "error" { - return "", fmt.Errorf("Got an error response from ton: `%s` ", res) + client.syncUnlock() + + client.printLog("", + fmt.Sprintf("sync. Error unmarshal response. Skip. Resp:%s, Error:%v", string(data.Raw), err)) + + continue } + if syncResp.SyncState.Type == "syncStateDone" { - result := C.tonlib_client_json_receive(client.client, DEFAULT_TIMEOUT) - syncResp = struct { - Type string `json:"@type"` - SyncState SyncState `json:"sync_state"` - }{} - res = C.GoString(result) - resB := []byte(res) - err = json.Unmarshal(resB, &syncResp) - if client.clientLogging { - fmt.Println("sync result #2: ", string(resB)) - } - } - if syncResp.Type == "ok" { - // continue updating + client.syncUnlock() + + client.printLog("", "sync. Received syncStateDone. SyncInProgress=false") + continue } - if syncResp.Type == "ton.blockIdExt" { - // continue updating + + if client.syncInProgress { + client.printLog("", fmt.Sprintf("sync. Sync in progress. Resp: %s", string(data.Raw))) + continue } - if syncResp.Type == "updateSyncState" { - // continue updating - continue + + // for sync we must stop send and receive + extra := client.getNewExtra() + startSyncData := struct { + Type string `json:"@type"` + Extra string `json:"extra"` + SyncState SyncState `json:"sync_state"` + }{ + Type: "sync", + Extra: extra, + SyncState: syncResp.SyncState, } - return res, nil + client.syncLock() + t := time.NewTimer(ForceUnlockSyncTimeout) + go client.timerSyncProgress(t) + + client.printLog(extra, fmt.Sprintf("sync. Start sync. SyncInProgress=true. Req:%+v", startSyncData)) + + // resend start sync msg is ok. We will just receive one more ton.blockIdExt message + if err = client.sendAsync(extra, startSyncData); err != nil { + client.printLog(extra, + fmt.Sprintf("sync. Error send start sync. Req:%+v, Error:%v", startSyncData, err)) + } } } -// QueryEstimateFees -// sometimes it`s respond with "@type: ok" instead of "query.fees" -// @param id -// @param ignoreChksig -func (client *Client) QueryEstimateFees(id int64, ignoreChksig bool) (*QueryFees, error) { - callData := struct { - Type string `json:"@type"` - Id int64 `json:"id"` - IgnoreChksig bool `json:"ignore_chksig"` +// disable ton client C lib`s logs +func (client *Client) executeSetLogLevel(logLevel int32) error { + data := struct { + Type string `json:"@type"` + NewVerbosityLevel int32 `json:"new_verbosity_level"` }{ - Type: "query.estimateFees", - Id: id, - IgnoreChksig: ignoreChksig, + Type: "setLogVerbosityLevel", + NewVerbosityLevel: logLevel, } - - type Exit struct { - Exit bool - sync.Mutex + req, err := json.Marshal(data) + if err != nil { + return err } + cs := C.CString(string(req)) + defer C.free(unsafe.Pointer(cs)) - var queryFees QueryFees + client.printLog("", fmt.Sprintf("call execute setLogVerbosityLevel: %s", string(req))) - type Resp struct { - Fee *QueryFees - Error error + C.tonlib_client_json_execute(client.client, cs) + + return nil +} + +func (client *Client) putToStore(extra string, ch chan *TONResult) { + client.respMapMu.Lock() + defer client.respMapMu.Unlock() + + client.extraToRespChan[extra] = ch +} + +func (client *Client) getFromStore(extra string) (chan *TONResult, error) { + client.respMapMu.Lock() + defer client.respMapMu.Unlock() + + ch, ok := client.extraToRespChan[extra] + if !ok { + return nil, errors.New("extra not found in store") } - resultChan := make(chan Resp, 1) - ticker := time.NewTimer(time.Duration(client.timeout) * time.Second) - exit := &Exit{false, sync.Mutex{}} + return ch, nil +} - go func() { - for true { - result, err := client.executeAsynchronously(callData) - // if timeout reached - close chan and exit - exit.Lock() - if exit.Exit { - exit.Unlock() - close(resultChan) - return - } - exit.Unlock() +func (client *Client) deleteFromStore(extra string) { + client.respMapMu.Lock() + defer client.respMapMu.Unlock() - if err != nil { - resultChan <- Resp{nil, err} - return - } + delete(client.extraToRespChan, extra) +} - if result.Data["@type"].(string) == "error" { - resultChan <- Resp{nil, fmt.Errorf("error! code: %d msg: %s", result.Data["code"], result.Data["message"])} - return - } +func (client *Client) executeAsynchronously(extra string, data interface{}) (*TONResult, error) { + ch := make(chan *TONResult) + defer close(ch) - if result.Data["@type"].(string) == "query.fees" { - err = json.Unmarshal(result.Raw, &queryFees) - resultChan <- Resp{&queryFees, err} - return - } - } - }() + client.putToStore(extra, ch) + defer client.deleteFromStore(extra) + + client.syncMu.RLock() + client.syncMu.RUnlock() + + err := client.sendAsync(extra, data) + if err != nil { + return nil, errors.New(client.formatLog(extra, fmt.Sprintf("error sendAsync. Error: %v", err))) + } + + timeout := time.NewTimer(WaitTimeout) + defer timeout.Stop() select { - case _ = <-ticker.C: - // notify gorutine that performing requests to TON - exit.Lock() - exit.Exit = true - exit.Unlock() + case <-timeout.C: + return nil, errors.New(client.formatLog(extra, "timeout for wait response")) + case resp := <-ch: + extraResp, _ := resp.Data.getExtra() + if extraResp != extra { + return nil, errors.New(client.formatLog(extra, + fmt.Sprintf("req extra != resp extra. ReqExtra: %s, RespExtra: %s, Req:%+v, Resp:%+v", + extra, extraResp, data, resp.Data))) + } + + return resp, nil + } +} - ticker.Stop() - return nil, fmt.Errorf("timeout") - case result := <-resultChan: - ticker.Stop() - return result.Fee, result.Error +/** +execute ton-lib asynchronously +*/ +func (client *Client) onLiteServerQueryResult(bytes []byte, id JSONInt64) (*Ok, error) { + extra := client.getNewExtra() + result, err := client.executeAsynchronously(extra, + struct { + Type string `json:"@type"` + Extra string `json:"@extra"` + Bytes []byte `json:"bytes"` + Id JSONInt64 `json:"id"` + }{ + Type: "onLiteServerQueryResult", + Bytes: bytes, + Extra: extra, + Id: id, + }, + ) + + if result.Data["@type"].(string) == "error" { + return nil, fmt.Errorf("error! code: %d msg: %s", result.Data["code"], result.Data["message"]) + } + + var ok Ok + err = json.Unmarshal(result.Raw, &ok) + + return &ok, err +} + +/** +execute ton-lib synchronously +*/ +func (client *Client) executeSynchronously(data interface{}) (*TONResult, error) { + req, err := json.Marshal(data) + if err != nil { + return nil, err } + + cs := C.CString(string(req)) + defer C.free(unsafe.Pointer(cs)) + + client.printLog("", fmt.Sprintf("call sycroniously: %v", data)) + + result := C.tonlib_client_json_execute(client.client, cs) + + var updateData TONResponse + res := C.GoString(result) + resB := []byte(res) + + client.printLog("", fmt.Sprintf("fetch sycroniously: %s", string(resB))) + + err = json.Unmarshal(resB, &updateData) + + return &TONResult{Data: updateData, Raw: resB}, err +} + +func (client *Client) Destroy() { + client.printLog("", "destroy client") + client.stopChan <- struct{}{} + close(client.stopChan) + close(client.syncChan) + C.tonlib_client_json_destroy(client.client) } // for now - a few requests may works wrong, cause it some times get respose form previos reqest for a few times @@ -368,17 +571,28 @@ func (client *Client) UpdateTonConnection() error { if err != nil { return err } + client.syncMu.Lock() + // destroy old c.ient client.Destroy() // create new C client client.client = C.tonlib_client_json_create() + + client.syncMu.Unlock() + // set log level err = client.executeSetLogLevel(client.tonLogging) if err != nil { return err } + client.stopChan = make(chan struct{}) + client.syncChan = make(chan *TONResult) + + go client.receiveWorker() + go client.syncWorker() + // init client optionsInfo, err := client.Init(client.options) if err != nil { @@ -388,9 +602,14 @@ func (client *Client) UpdateTonConnection() error { return nil } if optionsInfo.tonCommon.Type == "error" { - return fmt.Errorf("Error ton client init. Message: %s. ", optionsInfo.tonCommon.Extra) + return fmt.Errorf( + client.formatLog(optionsInfo.Extra, + fmt.Sprintf("error update ton connection. Ton client init. Message: %+v", optionsInfo))) } - return fmt.Errorf("Unexpected client init response. %#v", optionsInfo) + + return fmt.Errorf( + client.formatLog(optionsInfo.Extra, + fmt.Sprintf("error update ton connection. Unexpected client init response. %+v", optionsInfo))) } // key struct cause it strings values no bytes @@ -431,3 +650,6 @@ type DnsEntryData string type Action interface{ MessageType() string } type DnsAction Action + +type PchanState interface{ MessageType() string } +type PchanAction interface{ MessageType() string } diff --git a/v2/client_test.go b/v2/client_test.go index 240f8cf..ee16b60 100644 --- a/v2/client_test.go +++ b/v2/client_test.go @@ -4,6 +4,7 @@ import ( "encoding/base64" "fmt" "io/ioutil" + "log" "testing" ) @@ -152,8 +153,9 @@ func TestClient_ExportKey(t *testing.T) { TONPrivateKey{ pKey.PublicKey, pKey.Secret, + "", }, - }, ) + }) if err != nil { t.Fatal("Ton export key error", err) } @@ -199,6 +201,7 @@ func TestClient_ExportPemKey(t *testing.T) { TONPrivateKey{ pKey.PublicKey, pKey.Secret, + "", }, }, loc) if err != nil { @@ -254,26 +257,40 @@ func TestClient_WalletGetAccountAddress(t *testing.T) { t.Fatal("TestClient_WalletGetAccountAddress Init client error. ", err) } defer cln.Destroy() + defer cln.Close() - // prepare data - loc := SecureBytes(TestPassword) - mem := SecureBytes(TestPassword) - seed := SecureBytes("") + //prepare data + testAddress := "EQDfYZhDfNJ0EePoT5ibfI9oG9bWIU6g872oX5h9rL5PHY9a" - // create new key - pKey, err := cln.CreateNewKey(loc, mem, seed) + //get address pair + addrUnpacked, err := cln.UnpackAccountAddress(testAddress) if err != nil { - t.Fatal("TestClient_WalletGetAccountAddress create key for init wallet error", err) + t.Fatal("Error unpack account address", err) } - fmt.Println(fmt.Sprintf("TestClient_WalletGetAccountAddress pKey: %#v", pKey)) - // get wallet adress info - addrr, err := cln.GetAccountAddress(NewWalletInitialAccountState(pKey.PublicKey), 0) + isBounceable := addrUnpacked.Bounceable + + addrPacked, err := cln.PackAccountAddress(*addrUnpacked) if err != nil { - t.Fatal("TestClient_WalletGetAccountAddress failed to WalletGetAccountAddress(): ", err) + t.Fatal("Error pack account address", err) + } + + addrUnpacked.Bounceable = !addrUnpacked.Bounceable + addrPackedInverse, err := cln.PackAccountAddress(*addrUnpacked) + if err != nil { + t.Fatal("Error pack account address", err) + } + var bounceAddr, unBounceAddr *AccountAddress + if isBounceable { + bounceAddr = addrPacked + unBounceAddr = addrPackedInverse + } else { + bounceAddr = addrPackedInverse + unBounceAddr = addrPacked } - fmt.Printf("TestClient_WalletGetAccountAddress: get account adress addr: %#v, err: %v. ", addrr, err) + fmt.Printf("TestClient_WalletGetAccountAddress: get account adress addr. " + + "Bounceable: %#v, Unbounceable, %#v, Err: %v. ", bounceAddr, unBounceAddr, err) } func TestClient_WalletGetAccountState(t *testing.T) { @@ -295,32 +312,14 @@ func TestClient_WalletGetAccountState(t *testing.T) { t.Fatal("TestClient_WalletGetAccountState Init client error. ", err) } defer cln.Destroy() + defer cln.Close() - // prepare data - loc := SecureBytes(TestPassword) - mem := SecureBytes(TestPassword) - seed := SecureBytes("") - - // create new key - pKey, err := cln.CreateNewKey(loc, mem, seed) - if err != nil { - t.Fatal("TestClient_WalletGetAccountState create key for init wallet error", err) - } - fmt.Println(fmt.Sprintf("TestClient_WalletGetAccountState pKey: %#v", pKey)) - - // get wallet adress info - addrr, err := cln.GetAccountAddress(NewWalletInitialAccountState(pKey.PublicKey), 0) + state, err := cln.GetAccountStateSimple(TestAccountAddress) if err != nil { - t.Fatal("TestClient_WalletGetAccountState failed to WalletGetAccountAddress(): ", err) + t.Fatal("TestClient_WalletGetAccountState Get account state simple error. ", err) } - // get wallet account state info - state, err := cln.GetAccountState(*addrr) - if err != nil { - t.Fatal("TestClient_WalletGetAccountState failed to WalletGetAccountState(): ", err) - } - - fmt.Printf("TestClient_WalletGetAccountState: get account stater: %#v, err: %v. ", state, err) + fmt.Printf("TestClient_WalletGetAccountState: get account state: %#v, err: %v. ", state, err) } func TestClient_RawGetTransactions(t *testing.T) { @@ -386,21 +385,32 @@ func TestClient_RawCreateAndSendMessage(t *testing.T) { t.Fatal("TestClient_RawCreateAndSendMessage Init client error. ", err) } defer cln.Destroy() + defer cln.Close() // prepare data - loc := SecureBytes(TestPassword) - mem := SecureBytes(TestPassword) - seed := SecureBytes("") + // generate new 24 words mnemo on tonwallet.me or https://github.com/cryptoboyio/ton-mnemonic + // mnemonicPass should be empty + var mnemonic []string + var mnemonicPass string - // create new key - pKey, err := cln.CreateNewKey(loc, mem, seed) + walletID := int64(698983191) + revision := 1 + workchainID := 0 + + wordList := make([]SecureString, 0, len(mnemonic)) + for _, word := range mnemonic { + wordList = append(wordList, SecureString(word)) + } + + exportedKey := NewExportedKey(wordList) + key, err := cln.ImportKey(*exportedKey, SecureBytes(mnemonicPass), SecureBytes(mnemonicPass)) if err != nil { - t.Fatal("TestClient_RawCreateAndSendMessage create key for init wallet error", err) + log.Fatalln("Import key error", err) } - fmt.Println(fmt.Sprintf("TestClient_RawCreateAndSendMessage pKey: %#v", pKey)) + sourceAccState := NewWalletV3InitialAccountState(key.PublicKey, JSONInt64(walletID)) // get wallet address info - addrr, err := cln.GetAccountAddress(NewWalletInitialAccountState(pKey.PublicKey), 0) + addrr, err := cln.GetAccountAddress(sourceAccState, int32(revision), int32(workchainID)) if err != nil { t.Fatal("TestClient_RawCreateAndSendMessage failed to WalletGetAccountAddress(): ", err) } @@ -423,3 +433,26 @@ func TestClient_RawCreateAndSendMessage(t *testing.T) { } fmt.Printf("TestClient_RawCreateAndSendMessage: create and send msg msgSentOk: %#v, err: %v. ", msgSentOk, err) } + +func TestGetType(t *testing.T) { + wantValue := "query.estimateFees" + + data := struct { + Type string `json:"@type"` + Id int64 `json:"id"` + IgnoreChksig bool `json:"ignore_chksig"` + }{ + Type: wantValue, + Id: 1, + IgnoreChksig: true, + } + + actualValue, err := getType(interface{}(data)) + if err != nil { + t.Errorf("Error getType. Data: %v. Error: %v", data, err) + } + + if wantValue != actualValue { + t.Errorf("Error getType. WantValue: %s, ActualValue: %s", wantValue, actualValue) + } +} diff --git a/v2/cmd/tlgenerator/main.go b/v2/cmd/tlgenerator/main.go index 265ce34..d991cad 100644 --- a/v2/cmd/tlgenerator/main.go +++ b/v2/cmd/tlgenerator/main.go @@ -3,11 +3,12 @@ package main import ( "bufio" "fmt" - "github.com/spf13/cobra" "log" "os" "os/exec" "os/signal" + + "github.com/spf13/cobra" ) var syncWithTlCmd = &cobra.Command{ @@ -44,7 +45,7 @@ func syncWtithTl(cmd *cobra.Command, args []string) { fmt.Printf("Parsed entities: %d, interfaces: %d, enums: %d. ", len(*entities), len(*interfaces), len(*enums)) // generate gp`s structs based on parsed entities - structsContent, methodsContetnt := generateStructsFromTnEntities("tonlib", entities, interfaces, enums) + structsContent, methodsContetnt := generateStructsFromTnEntities("v2", entities, interfaces, enums) structsFilePath := "./structs.go" methodsFilePath := "./methods.go" diff --git a/v2/cmd/tlgenerator/tlStructGenerator.go b/v2/cmd/tlgenerator/tlStructGenerator.go index 1ff6ce4..894b604 100644 --- a/v2/cmd/tlgenerator/tlStructGenerator.go +++ b/v2/cmd/tlgenerator/tlStructGenerator.go @@ -13,7 +13,7 @@ var StructNamesExcludedFromGenerator = []string{ } var SkipMethodNames = []string{ - "sync", "query.estimateFees", + "sync", } func generateStructsFromTnEntities( @@ -181,7 +181,7 @@ func generateStructsFromTnEntities( // sort params to enshure the same params order in each generation sort.Slice(itemInfo.Properties, func(i, j int) bool { - if (itemInfo.Properties[i].Name > itemInfo.Properties[j].Name){ + if itemInfo.Properties[i].Name > itemInfo.Properties[j].Name { return false } return true @@ -343,7 +343,7 @@ func generateStructsFromTnEntities( // sort params to enshure the same params order in each generation sort.Slice(itemInfo.Properties, func(i, j int) bool { - if (itemInfo.Properties[i].Name > itemInfo.Properties[j].Name){ + if itemInfo.Properties[i].Name > itemInfo.Properties[j].Name { return false } return true @@ -406,12 +406,15 @@ func generateStructsFromTnEntities( } methodsContent += fmt.Sprintf(` { - result, err := client.executeAsynchronously( + extra := client.getNewExtra() + result, err := client.executeAsynchronously(extra, struct { Type string `+"`json:\"@type\"`"+` + Extra string `+"`json:\"@extra\"`"+` %s }{ Type: "%s", + Extra: extra, %s }, ) @@ -436,12 +439,15 @@ func generateStructsFromTnEntities( } else { methodsContent += fmt.Sprintf(` { - result, err := client.executeAsynchronously( + extra := client.getNewExtra() + result, err := client.executeAsynchronously(extra, struct { Type string `+"`json:\"@type\"`"+` + Extra string `+"`json:\"@extra\"`"+` %s }{ Type: "%s", + Extra: extra, %s }, ) @@ -456,8 +462,8 @@ func generateStructsFromTnEntities( var %s %s err = json.Unmarshal(result.Raw, &%s) + return %s%s, err - } `, clientCallStructAttrs, itemInfo.Name, paramsStr, illStr, returnTypeCamel, diff --git a/v2/cmd/tlgenerator/utils.go b/v2/cmd/tlgenerator/utils.go index 6b4a4b0..e414ea8 100644 --- a/v2/cmd/tlgenerator/utils.go +++ b/v2/cmd/tlgenerator/utils.go @@ -2,8 +2,9 @@ package main import ( "fmt" - "github.com/asaskevich/govalidator" "strings" + + "github.com/asaskevich/govalidator" ) func checkIsInterface(input string, interfaces *[]InterfaceInfo) bool { @@ -104,7 +105,7 @@ func convertDataType(input string, changeBytesToString bool) (string, bool) { propType = strings.Replace(input, "int53", "int64", 1) } else if strings.Contains(input, "bytes") { - if changeBytesToString{ + if changeBytesToString { propType = strings.Replace(input, "bytes", "string", 1) } else { propType = strings.Replace(input, "bytes", "[]byte", 1) diff --git a/v2/cmd/tongo/createPrivateKey.go b/v2/cmd/tongo/createPrivateKey.go index 9c69c5b..75c3521 100644 --- a/v2/cmd/tongo/createPrivateKey.go +++ b/v2/cmd/tongo/createPrivateKey.go @@ -23,7 +23,7 @@ var createPKCmd = &cobra.Command{ } _, err := os.Stat(args[0]) if err != nil { - errors.New("please choose config path") + return errors.New("please choose config path") } return nil }, @@ -46,8 +46,8 @@ func createPK(cmd *cobra.Command, args []string) { mem := tonlib.SecureBytes(mnPass) seed := tonlib.SecureBytes("") - // create ne wkey - pKey, err := tonClient.CreateNewKey(loc, mem, seed, ) + // create new key + pKey, err := tonClient.CreateNewKey(loc, mem, seed) if err != nil { log.Fatal("failed to create new key with error: ", err) return @@ -55,7 +55,7 @@ func createPK(cmd *cobra.Command, args []string) { fmt.Printf("Got a result: publicKey :%v; secret: %s. Errors: %v. \n", pKey.PublicKey, pKey.Secret, err) // prepare key for transffering - addr, err := tonClient.GetAccountAddress(tonlib.NewWalletInitialAccountState(pKey.PublicKey), 0) + addr, err := tonClient.GetAccountAddress(tonlib.NewWalletV3InitialAccountState(pKey.PublicKey, walletID), 0, 0) if err != nil { log.Fatal("failed to get key address with error: ", err) return diff --git a/v2/cmd/tongo/estimateFee.go b/v2/cmd/tongo/estimateFee.go index bd0e333..92aa691 100644 --- a/v2/cmd/tongo/estimateFee.go +++ b/v2/cmd/tongo/estimateFee.go @@ -4,11 +4,12 @@ import ( "encoding/base64" "errors" "fmt" - tonlib "github.com/mercuryoio/tonlib-go/v2" - "github.com/spf13/cobra" "log" "os" "strconv" + + tonlib "github.com/mercuryoio/tonlib-go/v2" + "github.com/spf13/cobra" ) var estimateFeeCmd = &cobra.Command{ @@ -67,7 +68,8 @@ func estimateFee(cmd *cobra.Command, args []string) { } // get wallet adress info - addr, err := tonClient.GetAccountAddress(tonlib.NewWalletInitialAccountState(pKey.PublicKey), 0) + sourceAccState := tonlib.NewWalletV3InitialAccountState(pKey.PublicKey, walletID) + addr, err := tonClient.GetAccountAddress(sourceAccState, 0, 0) if err != nil { fmt.Println("get wallet address error: ", err) os.Exit(0) @@ -81,11 +83,13 @@ func estimateFee(cmd *cobra.Command, args []string) { tonlib.NewMsgDataText(message), tonlib.NewAccountAddress(destinationAddr), "", + -1, )}, ) queryInfo, err := tonClient.CreateQuery( msgAction, *addr, + sourceAccState, inputKey, 300, // If this timeout will be exceeded - all request are go as usual but grams wil not be sent ) diff --git a/v2/cmd/tongo/main.go b/v2/cmd/tongo/main.go index 338a3eb..f24727b 100644 --- a/v2/cmd/tongo/main.go +++ b/v2/cmd/tongo/main.go @@ -8,6 +8,8 @@ import ( "os/signal" ) +const walletID = 698983191 + var tonClient *tonlib.Client func init() { diff --git a/v2/cmd/tongo/sendGramm.go b/v2/cmd/tongo/sendGramm.go index 6d9cec0..bd09674 100644 --- a/v2/cmd/tongo/sendGramm.go +++ b/v2/cmd/tongo/sendGramm.go @@ -4,11 +4,12 @@ import ( "encoding/base64" "errors" "fmt" - tonlib "github.com/mercuryoio/tonlib-go/v2" - "github.com/spf13/cobra" "log" "os" "strconv" + + tonlib "github.com/mercuryoio/tonlib-go/v2" + "github.com/spf13/cobra" ) var sendGrammCmd = &cobra.Command{ @@ -68,7 +69,8 @@ func sendGramm(cmd *cobra.Command, args []string) { } // get wallet adress info - senderAddr, err := tonClient.GetAccountAddress(tonlib.NewWalletInitialAccountState(pKey.PublicKey), 0) + sourceAccState := tonlib.NewWalletV3InitialAccountState(pKey.PublicKey, walletID) + senderAddr, err := tonClient.GetAccountAddress(sourceAccState, 0, 0) if err != nil { fmt.Println("get wallet address error: ", err, senderAddr) os.Exit(0) @@ -82,11 +84,13 @@ func sendGramm(cmd *cobra.Command, args []string) { tonlib.NewMsgDataText(message), tonlib.NewAccountAddress(destinationAddr), "", + -1, )}, ) queryInfo, err := tonClient.CreateQuery( msgAction, *senderAddr, + sourceAccState, inputKey, 300, // time out of sending money not executing request ) diff --git a/v2/cmd/tongo/walletAddress.go b/v2/cmd/tongo/walletAddress.go index 22ed29e..3dfc804 100644 --- a/v2/cmd/tongo/walletAddress.go +++ b/v2/cmd/tongo/walletAddress.go @@ -38,7 +38,7 @@ func walletAddress(cmd *cobra.Command, args []string) { pKey := tonlib.TONPrivateKey{PublicKey: args[1], Secret: args[2]} - addr, err := tonClient.GetAccountAddress(tonlib.NewWalletInitialAccountState(pKey.PublicKey), 0) + addr, err := tonClient.GetAccountAddress(tonlib.NewWalletV3InitialAccountState(pKey.PublicKey, walletID), 0, 0) if err != nil { fmt.Println("get wallet address error: ", err) os.Exit(0) diff --git a/v2/cmd/tongo/walletState.go b/v2/cmd/tongo/walletState.go index f65d34b..8f26310 100644 --- a/v2/cmd/tongo/walletState.go +++ b/v2/cmd/tongo/walletState.go @@ -38,7 +38,7 @@ func walletState(cmd *cobra.Command, args []string) { pKey := tonlib.TONPrivateKey{PublicKey: args[1], Secret: args[2]} - addr, err := tonClient.GetAccountAddress(tonlib.NewWalletInitialAccountState(pKey.PublicKey), 0) + addr, err := tonClient.GetAccountAddress(tonlib.NewWalletV3InitialAccountState(pKey.PublicKey, walletID), 0, 0) if err != nil { fmt.Println("get wallet address error: ", err) os.Exit(0) diff --git a/v2/example/send_gram.go b/v2/example/send_gram.go index 1e81fe1..e05c2b9 100644 --- a/v2/example/send_gram.go +++ b/v2/example/send_gram.go @@ -3,71 +3,89 @@ package main import ( "encoding/base64" "fmt" - tonlib "github.com/mercuryoio/tonlib-go/v2" "log" + + "github.com/mercuryoio/tonlib-go/v2" ) func main() { // parse config - options, err := tonlib.ParseConfigFile("./tonlib.config.json.example") + options, err := v2.ParseConfigFile("./tonlib.config.json.example") if err != nil { log.Fatal("failed parse config error. ", err) } // make req - req := tonlib.TonInitRequest{ + req := v2.TonInitRequest{ "init", *options, } - cln, err := tonlib.NewClient(&req, tonlib.Config{}, 10, true, 9) + cln, err := v2.NewClient(&req, v2.Config{}, 10, true, 9) if err != nil { log.Fatalln("Init client error", err) } defer cln.Destroy() + defer cln.Close() - // create private key // prepare data - loc := tonlib.SecureBytes(TEST_PASSWORD) - mem := tonlib.SecureBytes(TEST_PASSWORD) - seed := tonlib.SecureBytes("") + // generate new 24 words mnemo on tonwallet.me or https://github.com/cryptoboyio/ton-mnemonic + // mnemonicPass should be empty + var mnemonic []string + var mnemonicPass string - // create new key - pKey, err := cln.CreateNewKey(&loc, &mem, &seed) - if err != nil { - log.Fatalln("Ton create key for send grams error", err) - } + walletID := int64(698983191) + revision := 1 + workchainID := 0 - // prepare input key - inputKey := tonlib.InputKey{ - "inputKeyRegular", - base64.StdEncoding.EncodeToString(loc), - tonlib.TONPrivateKey{ - pKey.PublicKey, - base64.StdEncoding.EncodeToString((*pKey.Secret)[:]), - }, + wordList := make([]v2.SecureString, 0, len(mnemonic)) + for _, word := range mnemonic { + wordList = append(wordList, v2.SecureString(word)) } - _, err = cln.WalletInit(&inputKey) + exportedKey := v2.NewExportedKey(wordList) + key, err := cln.ImportKey(*exportedKey, v2.SecureBytes(mnemonicPass), v2.SecureBytes(mnemonicPass)) if err != nil { - log.Fatalln("Ton init wallet for send gramms error", err) + log.Fatalln("Import key error", err) } - address, err := cln.WalletGetAccountAddress(tonlib.NewWalletInitialAccountState(pKey.PublicKey)) + + sourceAccState := v2.NewWalletV3InitialAccountState(key.PublicKey, v2.JSONInt64(walletID)) + accountAddr, err := cln.GetAccountAddress(sourceAccState, int32(revision), int32(workchainID)) if err != nil { - log.Fatalln("Ton get address for send grams error", err) + log.Fatalln("Get account address error", err) } - // send grams - sendResult, err := cln.GenericSendGrams( + msgAction := v2.NewActionMsg( true, - TEST_AMOUNT, - tonlib.NewAccountAddress(TEST_ADDRESS), - []byte(""), - &inputKey, - address, - 5, + []v2.MsgMessage{*v2.NewMsgMessage( + v2.JSONInt64(TEST_AMOUNT), + v2.NewMsgDataText(""), + v2.NewAccountAddress(TEST_ADDRESS), + "", + -1, + )}, + ) + + inputKey := v2.InputKey{ + Type: "inputKeyRegular", + LocalPassword: base64.StdEncoding.EncodeToString(v2.SecureBytes(mnemonicPass)), + Key: v2.TONPrivateKey{Type: "key", PublicKey: key.PublicKey, Secret: key.Secret}, + } + + queryInfo, err := cln.CreateQuery( + msgAction, + *accountAddr, + sourceAccState, + inputKey, + 90, // If this timeout will be exceeded - all request are go as usual but grams wil not be sent ) if err != nil { - log.Fatalln("Ton send grams error ", err) + log.Fatalln("Create query error", err) + } + + ok, err := cln.QuerySend(queryInfo.Id) + if err != nil { + log.Fatalln("Send query error", err) } - fmt.Println(fmt.Sprintf("Send grams with resp: %#v. ", sendResult)) + + fmt.Println(fmt.Sprintf("Send grams with queryInfo: %#v, queryResult: %#v", queryInfo, ok)) } diff --git a/v2/go.mod b/v2/go.mod index ec38251..58ed159 100644 --- a/v2/go.mod +++ b/v2/go.mod @@ -4,8 +4,5 @@ go 1.13 require ( github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a - github.com/dvsekhvalnov/jose2go v0.0.0-20180829124132-7f401d37b68a // indirect - github.com/joho/godotenv v1.3.0 // indirect - github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24 // indirect github.com/spf13/cobra v0.0.5 ) diff --git a/v2/go.sum b/v2/go.sum index 609f3a9..1cb8a68 100644 --- a/v2/go.sum +++ b/v2/go.sum @@ -7,7 +7,6 @@ github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8Nz github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/dvsekhvalnov/jose2go v0.0.0-20180829124132-7f401d37b68a h1:mq+R6XEM6lJX5VlLyZIrUSP8tSuJp82xTK89hvBwJbU= github.com/dvsekhvalnov/jose2go v0.0.0-20180829124132-7f401d37b68a/go.mod h1:7BvyPhdbLxMXIYTFPLsyJRFMsKmOZnQmzh6Gb+uquuM= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= @@ -23,8 +22,6 @@ github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/9 github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24/go.mod h1:M+9NzErvs504Cn4c5DxATwIqPbtswREoFCre64PpcG4= -github.com/shopspring/decimal v0.0.0-20190905144223-a36b5d85f337 h1:Da9XEUfFxgyDOqUfwgoTDcWzmnlOnCGi6i4iPS+8Fbw= -github.com/shopspring/decimal v0.0.0-20190905144223-a36b5d85f337/go.mod h1:M+9NzErvs504Cn4c5DxATwIqPbtswREoFCre64PpcG4= github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= github.com/spf13/cobra v0.0.5 h1:f0B+LkLX6DtmRH1isoNA9VTtNUK9K8xYd28JNNfOv/s= diff --git a/v2/lib/darwin/libtonlib.a b/v2/lib/darwin/libtonlib.a index c69aae1..fff4803 100644 Binary files a/v2/lib/darwin/libtonlib.a and b/v2/lib/darwin/libtonlib.a differ diff --git a/v2/lib/darwin/libtonlibjson.0.5.dylib b/v2/lib/darwin/libtonlibjson.0.5.dylib old mode 100644 new mode 100755 index f2e9761..24bda64 Binary files a/v2/lib/darwin/libtonlibjson.0.5.dylib and b/v2/lib/darwin/libtonlibjson.0.5.dylib differ diff --git a/v2/lib/darwin/libtonlibjson.dylib b/v2/lib/darwin/libtonlibjson.dylib old mode 100644 new mode 100755 index f2e9761..24bda64 Binary files a/v2/lib/darwin/libtonlibjson.dylib and b/v2/lib/darwin/libtonlibjson.dylib differ diff --git a/v2/lib/darwin/libtonlibjson_private.a b/v2/lib/darwin/libtonlibjson_private.a index ebc8c50..19293e8 100644 Binary files a/v2/lib/darwin/libtonlibjson_private.a and b/v2/lib/darwin/libtonlibjson_private.a differ diff --git a/v2/lib/darwin/libtonlibjson_static.a b/v2/lib/darwin/libtonlibjson_static.a index db1eb44..fe5be40 100644 Binary files a/v2/lib/darwin/libtonlibjson_static.a and b/v2/lib/darwin/libtonlibjson_static.a differ diff --git a/v2/lib/linux/libtonlib.a b/v2/lib/linux/libtonlib.a index 90a635f..a6cc5bb 100644 Binary files a/v2/lib/linux/libtonlib.a and b/v2/lib/linux/libtonlib.a differ diff --git a/v2/lib/linux/libtonlibjson.so b/v2/lib/linux/libtonlibjson.so index 956d2b0..e81ecf8 100755 Binary files a/v2/lib/linux/libtonlibjson.so and b/v2/lib/linux/libtonlibjson.so differ diff --git a/v2/lib/linux/libtonlibjson.so.0.5 b/v2/lib/linux/libtonlibjson.so.0.5 index 956d2b0..e81ecf8 100755 Binary files a/v2/lib/linux/libtonlibjson.so.0.5 and b/v2/lib/linux/libtonlibjson.so.0.5 differ diff --git a/v2/lib/linux/libtonlibjson_private.a b/v2/lib/linux/libtonlibjson_private.a index 2bb2983..7d57c13 100644 Binary files a/v2/lib/linux/libtonlibjson_private.a and b/v2/lib/linux/libtonlibjson_private.a differ diff --git a/v2/lib/linux/libtonlibjson_static.a b/v2/lib/linux/libtonlibjson_static.a index f599a3e..304f5a5 100644 Binary files a/v2/lib/linux/libtonlibjson_static.a and b/v2/lib/linux/libtonlibjson_static.a differ diff --git a/v2/methods.go b/v2/methods.go index 0027764..db0b0f4 100755 --- a/v2/methods.go +++ b/v2/methods.go @@ -8,12 +8,15 @@ import ( // Init // @param options func (client *Client) Init(options Options) (*OptionsInfo, error) { - result, err := client.executeAsynchronously( + extra := client.getNewExtra() + result, err := client.executeAsynchronously(extra, struct { Type string `json:"@type"` + Extra string `json:"@extra"` Options Options `json:"options"` }{ Type: "init", + Extra: extra, Options: options, }, ) @@ -28,17 +31,20 @@ func (client *Client) Init(options Options) (*OptionsInfo, error) { var optionsInfo OptionsInfo err = json.Unmarshal(result.Raw, &optionsInfo) - return &optionsInfo, err + return &optionsInfo, err } // Close func (client *Client) Close() (*Ok, error) { - result, err := client.executeAsynchronously( + extra := client.getNewExtra() + result, err := client.executeAsynchronously(extra, struct { - Type string `json:"@type"` + Type string `json:"@type"` + Extra string `json:"@extra"` }{ - Type: "close", + Type: "close", + Extra: extra, }, ) @@ -52,19 +58,22 @@ func (client *Client) Close() (*Ok, error) { var ok Ok err = json.Unmarshal(result.Raw, &ok) - return &ok, err + return &ok, err } // OptionsSetConfig // @param config func (client *Client) OptionsSetConfig(config Config) (*OptionsConfigInfo, error) { - result, err := client.executeAsynchronously( + extra := client.getNewExtra() + result, err := client.executeAsynchronously(extra, struct { Type string `json:"@type"` + Extra string `json:"@extra"` Config Config `json:"config"` }{ Type: "options.setConfig", + Extra: extra, Config: config, }, ) @@ -79,19 +88,22 @@ func (client *Client) OptionsSetConfig(config Config) (*OptionsConfigInfo, error var optionsConfigInfo OptionsConfigInfo err = json.Unmarshal(result.Raw, &optionsConfigInfo) - return &optionsConfigInfo, err + return &optionsConfigInfo, err } // OptionsValidateConfig // @param config func (client *Client) OptionsValidateConfig(config Config) (*OptionsConfigInfo, error) { - result, err := client.executeAsynchronously( + extra := client.getNewExtra() + result, err := client.executeAsynchronously(extra, struct { Type string `json:"@type"` + Extra string `json:"@extra"` Config Config `json:"config"` }{ Type: "options.validateConfig", + Extra: extra, Config: config, }, ) @@ -106,8 +118,8 @@ func (client *Client) OptionsValidateConfig(config Config) (*OptionsConfigInfo, var optionsConfigInfo OptionsConfigInfo err = json.Unmarshal(result.Raw, &optionsConfigInfo) - return &optionsConfigInfo, err + return &optionsConfigInfo, err } // CreateNewKey @@ -115,14 +127,17 @@ func (client *Client) OptionsValidateConfig(config Config) (*OptionsConfigInfo, // @param mnemonicPassword // @param randomExtraSeed func (client *Client) CreateNewKey(localPassword SecureBytes, mnemonicPassword SecureBytes, randomExtraSeed SecureBytes) (*Key, error) { - result, err := client.executeAsynchronously( + extra := client.getNewExtra() + result, err := client.executeAsynchronously(extra, struct { Type string `json:"@type"` + Extra string `json:"@extra"` LocalPassword SecureBytes `json:"local_password"` MnemonicPassword SecureBytes `json:"mnemonic_password"` RandomExtraSeed SecureBytes `json:"random_extra_seed"` }{ Type: "createNewKey", + Extra: extra, LocalPassword: localPassword, MnemonicPassword: mnemonicPassword, RandomExtraSeed: randomExtraSeed, @@ -139,20 +154,23 @@ func (client *Client) CreateNewKey(localPassword SecureBytes, mnemonicPassword S var key Key err = json.Unmarshal(result.Raw, &key) - return &key, err + return &key, err } // DeleteKey // @param key func (client *Client) DeleteKey(key Key) (*Ok, error) { - result, err := client.executeAsynchronously( + extra := client.getNewExtra() + result, err := client.executeAsynchronously(extra, struct { - Type string `json:"@type"` - Key Key `json:"key"` + Type string `json:"@type"` + Extra string `json:"@extra"` + Key Key `json:"key"` }{ - Type: "deleteKey", - Key: key, + Type: "deleteKey", + Extra: extra, + Key: key, }, ) @@ -166,17 +184,20 @@ func (client *Client) DeleteKey(key Key) (*Ok, error) { var ok Ok err = json.Unmarshal(result.Raw, &ok) - return &ok, err + return &ok, err } // DeleteAllKeys func (client *Client) DeleteAllKeys() (*Ok, error) { - result, err := client.executeAsynchronously( + extra := client.getNewExtra() + result, err := client.executeAsynchronously(extra, struct { - Type string `json:"@type"` + Type string `json:"@type"` + Extra string `json:"@extra"` }{ - Type: "deleteAllKeys", + Type: "deleteAllKeys", + Extra: extra, }, ) @@ -190,19 +211,22 @@ func (client *Client) DeleteAllKeys() (*Ok, error) { var ok Ok err = json.Unmarshal(result.Raw, &ok) - return &ok, err + return &ok, err } // ExportKey // @param inputKey func (client *Client) ExportKey(inputKey InputKey) (*ExportedKey, error) { - result, err := client.executeAsynchronously( + extra := client.getNewExtra() + result, err := client.executeAsynchronously(extra, struct { Type string `json:"@type"` + Extra string `json:"@extra"` InputKey InputKey `json:"input_key"` }{ Type: "exportKey", + Extra: extra, InputKey: inputKey, }, ) @@ -217,21 +241,24 @@ func (client *Client) ExportKey(inputKey InputKey) (*ExportedKey, error) { var exportedKey ExportedKey err = json.Unmarshal(result.Raw, &exportedKey) - return &exportedKey, err + return &exportedKey, err } // ExportPemKey // @param inputKey // @param keyPassword func (client *Client) ExportPemKey(inputKey InputKey, keyPassword SecureBytes) (*ExportedPemKey, error) { - result, err := client.executeAsynchronously( + extra := client.getNewExtra() + result, err := client.executeAsynchronously(extra, struct { Type string `json:"@type"` + Extra string `json:"@extra"` InputKey InputKey `json:"input_key"` KeyPassword SecureBytes `json:"key_password"` }{ Type: "exportPemKey", + Extra: extra, InputKey: inputKey, KeyPassword: keyPassword, }, @@ -247,21 +274,24 @@ func (client *Client) ExportPemKey(inputKey InputKey, keyPassword SecureBytes) ( var exportedPemKey ExportedPemKey err = json.Unmarshal(result.Raw, &exportedPemKey) - return &exportedPemKey, err + return &exportedPemKey, err } // ExportEncryptedKey // @param inputKey // @param keyPassword func (client *Client) ExportEncryptedKey(inputKey InputKey, keyPassword SecureBytes) (*ExportedEncryptedKey, error) { - result, err := client.executeAsynchronously( + extra := client.getNewExtra() + result, err := client.executeAsynchronously(extra, struct { Type string `json:"@type"` + Extra string `json:"@extra"` InputKey InputKey `json:"input_key"` KeyPassword SecureBytes `json:"key_password"` }{ Type: "exportEncryptedKey", + Extra: extra, InputKey: inputKey, KeyPassword: keyPassword, }, @@ -277,19 +307,22 @@ func (client *Client) ExportEncryptedKey(inputKey InputKey, keyPassword SecureBy var exportedEncryptedKey ExportedEncryptedKey err = json.Unmarshal(result.Raw, &exportedEncryptedKey) - return &exportedEncryptedKey, err + return &exportedEncryptedKey, err } // ExportUnencryptedKey // @param inputKey func (client *Client) ExportUnencryptedKey(inputKey InputKey) (*ExportedUnencryptedKey, error) { - result, err := client.executeAsynchronously( + extra := client.getNewExtra() + result, err := client.executeAsynchronously(extra, struct { Type string `json:"@type"` + Extra string `json:"@extra"` InputKey InputKey `json:"input_key"` }{ Type: "exportUnencryptedKey", + Extra: extra, InputKey: inputKey, }, ) @@ -304,8 +337,8 @@ func (client *Client) ExportUnencryptedKey(inputKey InputKey) (*ExportedUnencryp var exportedUnencryptedKey ExportedUnencryptedKey err = json.Unmarshal(result.Raw, &exportedUnencryptedKey) - return &exportedUnencryptedKey, err + return &exportedUnencryptedKey, err } // ImportKey @@ -313,14 +346,17 @@ func (client *Client) ExportUnencryptedKey(inputKey InputKey) (*ExportedUnencryp // @param localPassword // @param mnemonicPassword func (client *Client) ImportKey(exportedKey ExportedKey, localPassword SecureBytes, mnemonicPassword SecureBytes) (*Key, error) { - result, err := client.executeAsynchronously( + extra := client.getNewExtra() + result, err := client.executeAsynchronously(extra, struct { Type string `json:"@type"` + Extra string `json:"@extra"` ExportedKey ExportedKey `json:"exported_key"` LocalPassword SecureBytes `json:"local_password"` MnemonicPassword SecureBytes `json:"mnemonic_password"` }{ Type: "importKey", + Extra: extra, ExportedKey: exportedKey, LocalPassword: localPassword, MnemonicPassword: mnemonicPassword, @@ -337,8 +373,8 @@ func (client *Client) ImportKey(exportedKey ExportedKey, localPassword SecureByt var key Key err = json.Unmarshal(result.Raw, &key) - return &key, err + return &key, err } // ImportPemKey @@ -346,14 +382,17 @@ func (client *Client) ImportKey(exportedKey ExportedKey, localPassword SecureByt // @param keyPassword // @param localPassword func (client *Client) ImportPemKey(exportedKey ExportedPemKey, keyPassword SecureBytes, localPassword SecureBytes) (*Key, error) { - result, err := client.executeAsynchronously( + extra := client.getNewExtra() + result, err := client.executeAsynchronously(extra, struct { Type string `json:"@type"` + Extra string `json:"@extra"` ExportedKey ExportedPemKey `json:"exported_key"` KeyPassword SecureBytes `json:"key_password"` LocalPassword SecureBytes `json:"local_password"` }{ Type: "importPemKey", + Extra: extra, ExportedKey: exportedKey, KeyPassword: keyPassword, LocalPassword: localPassword, @@ -370,8 +409,8 @@ func (client *Client) ImportPemKey(exportedKey ExportedPemKey, keyPassword Secur var keyDummy Key err = json.Unmarshal(result.Raw, &keyDummy) - return &keyDummy, err + return &keyDummy, err } // ImportEncryptedKey @@ -379,14 +418,17 @@ func (client *Client) ImportPemKey(exportedKey ExportedPemKey, keyPassword Secur // @param keyPassword // @param localPassword func (client *Client) ImportEncryptedKey(exportedEncryptedKey ExportedEncryptedKey, keyPassword SecureBytes, localPassword SecureBytes) (*Key, error) { - result, err := client.executeAsynchronously( + extra := client.getNewExtra() + result, err := client.executeAsynchronously(extra, struct { Type string `json:"@type"` + Extra string `json:"@extra"` ExportedEncryptedKey ExportedEncryptedKey `json:"exported_encrypted_key"` KeyPassword SecureBytes `json:"key_password"` LocalPassword SecureBytes `json:"local_password"` }{ Type: "importEncryptedKey", + Extra: extra, ExportedEncryptedKey: exportedEncryptedKey, KeyPassword: keyPassword, LocalPassword: localPassword, @@ -403,21 +445,24 @@ func (client *Client) ImportEncryptedKey(exportedEncryptedKey ExportedEncryptedK var keyDummy Key err = json.Unmarshal(result.Raw, &keyDummy) - return &keyDummy, err + return &keyDummy, err } // ImportUnencryptedKey // @param exportedUnencryptedKey // @param localPassword func (client *Client) ImportUnencryptedKey(exportedUnencryptedKey ExportedUnencryptedKey, localPassword SecureBytes) (*Key, error) { - result, err := client.executeAsynchronously( + extra := client.getNewExtra() + result, err := client.executeAsynchronously(extra, struct { Type string `json:"@type"` + Extra string `json:"@extra"` ExportedUnencryptedKey ExportedUnencryptedKey `json:" exported_unencrypted_key"` LocalPassword SecureBytes `json:"local_password"` }{ Type: "importUnencryptedKey", + Extra: extra, ExportedUnencryptedKey: exportedUnencryptedKey, LocalPassword: localPassword, }, @@ -433,21 +478,24 @@ func (client *Client) ImportUnencryptedKey(exportedUnencryptedKey ExportedUnencr var key Key err = json.Unmarshal(result.Raw, &key) - return &key, err + return &key, err } // ChangeLocalPassword // @param inputKey // @param newLocalPassword func (client *Client) ChangeLocalPassword(inputKey InputKey, newLocalPassword SecureBytes) (*Key, error) { - result, err := client.executeAsynchronously( + extra := client.getNewExtra() + result, err := client.executeAsynchronously(extra, struct { Type string `json:"@type"` + Extra string `json:"@extra"` InputKey InputKey `json:"input_key"` NewLocalPassword SecureBytes `json:"new_local_password"` }{ Type: "changeLocalPassword", + Extra: extra, InputKey: inputKey, NewLocalPassword: newLocalPassword, }, @@ -463,21 +511,24 @@ func (client *Client) ChangeLocalPassword(inputKey InputKey, newLocalPassword Se var key Key err = json.Unmarshal(result.Raw, &key) - return &key, err + return &key, err } // Encrypt // @param decryptedData // @param secret func (client *Client) Encrypt(decryptedData SecureBytes, secret SecureBytes) (*Data, error) { - result, err := client.executeAsynchronously( + extra := client.getNewExtra() + result, err := client.executeAsynchronously(extra, struct { Type string `json:"@type"` + Extra string `json:"@extra"` DecryptedData SecureBytes `json:"decrypted_data"` Secret SecureBytes `json:"secret"` }{ Type: "encrypt", + Extra: extra, DecryptedData: decryptedData, Secret: secret, }, @@ -493,21 +544,24 @@ func (client *Client) Encrypt(decryptedData SecureBytes, secret SecureBytes) (*D var data Data err = json.Unmarshal(result.Raw, &data) - return &data, err + return &data, err } // Decrypt // @param encryptedData // @param secret func (client *Client) Decrypt(encryptedData SecureBytes, secret SecureBytes) (*Data, error) { - result, err := client.executeAsynchronously( + extra := client.getNewExtra() + result, err := client.executeAsynchronously(extra, struct { Type string `json:"@type"` + Extra string `json:"@extra"` EncryptedData SecureBytes `json:"encrypted_data"` Secret SecureBytes `json:"secret"` }{ Type: "decrypt", + Extra: extra, EncryptedData: encryptedData, Secret: secret, }, @@ -523,8 +577,8 @@ func (client *Client) Decrypt(encryptedData SecureBytes, secret SecureBytes) (*D var data Data err = json.Unmarshal(result.Raw, &data) - return &data, err + return &data, err } // Kdf @@ -532,14 +586,17 @@ func (client *Client) Decrypt(encryptedData SecureBytes, secret SecureBytes) (*D // @param password // @param salt func (client *Client) Kdf(iterations int32, password SecureBytes, salt SecureBytes) (*Data, error) { - result, err := client.executeAsynchronously( + extra := client.getNewExtra() + result, err := client.executeAsynchronously(extra, struct { Type string `json:"@type"` + Extra string `json:"@extra"` Iterations int32 `json:"iterations"` Password SecureBytes `json:"password"` Salt SecureBytes `json:"salt"` }{ Type: "kdf", + Extra: extra, Iterations: iterations, Password: password, Salt: salt, @@ -556,19 +613,22 @@ func (client *Client) Kdf(iterations int32, password SecureBytes, salt SecureByt var data Data err = json.Unmarshal(result.Raw, &data) - return &data, err + return &data, err } // UnpackAccountAddress // @param accountAddress func (client *Client) UnpackAccountAddress(accountAddress string) (*UnpackedAccountAddress, error) { - result, err := client.executeAsynchronously( + extra := client.getNewExtra() + result, err := client.executeAsynchronously(extra, struct { Type string `json:"@type"` + Extra string `json:"@extra"` AccountAddress string `json:"account_address"` }{ Type: "unpackAccountAddress", + Extra: extra, AccountAddress: accountAddress, }, ) @@ -583,19 +643,22 @@ func (client *Client) UnpackAccountAddress(accountAddress string) (*UnpackedAcco var unpackedAccountAddress UnpackedAccountAddress err = json.Unmarshal(result.Raw, &unpackedAccountAddress) - return &unpackedAccountAddress, err + return &unpackedAccountAddress, err } // PackAccountAddress // @param accountAddress func (client *Client) PackAccountAddress(accountAddress UnpackedAccountAddress) (*AccountAddress, error) { - result, err := client.executeAsynchronously( + extra := client.getNewExtra() + result, err := client.executeAsynchronously(extra, struct { Type string `json:"@type"` + Extra string `json:"@extra"` AccountAddress UnpackedAccountAddress `json:"account_address"` }{ Type: "packAccountAddress", + Extra: extra, AccountAddress: accountAddress, }, ) @@ -610,19 +673,22 @@ func (client *Client) PackAccountAddress(accountAddress UnpackedAccountAddress) var accountAddressDummy AccountAddress err = json.Unmarshal(result.Raw, &accountAddressDummy) - return &accountAddressDummy, err + return &accountAddressDummy, err } // GetBip39Hints // @param prefix func (client *Client) GetBip39Hints(prefix string) (*Bip39Hints, error) { - result, err := client.executeAsynchronously( + extra := client.getNewExtra() + result, err := client.executeAsynchronously(extra, struct { Type string `json:"@type"` + Extra string `json:"@extra"` Prefix string `json:"prefix"` }{ Type: "getBip39Hints", + Extra: extra, Prefix: prefix, }, ) @@ -637,19 +703,22 @@ func (client *Client) GetBip39Hints(prefix string) (*Bip39Hints, error) { var bip39Hints Bip39Hints err = json.Unmarshal(result.Raw, &bip39Hints) - return &bip39Hints, err + return &bip39Hints, err } // RawGetAccountState // @param accountAddress func (client *Client) RawGetAccountState(accountAddress AccountAddress) (*RawFullAccountState, error) { - result, err := client.executeAsynchronously( + extra := client.getNewExtra() + result, err := client.executeAsynchronously(extra, struct { Type string `json:"@type"` + Extra string `json:"@extra"` AccountAddress AccountAddress `json:"account_address"` }{ Type: "raw.getAccountState", + Extra: extra, AccountAddress: accountAddress, }, ) @@ -664,8 +733,8 @@ func (client *Client) RawGetAccountState(accountAddress AccountAddress) (*RawFul var rawFullAccountState RawFullAccountState err = json.Unmarshal(result.Raw, &rawFullAccountState) - return &rawFullAccountState, err + return &rawFullAccountState, err } // RawGetTransactions @@ -673,14 +742,17 @@ func (client *Client) RawGetAccountState(accountAddress AccountAddress) (*RawFul // @param fromTransactionId // @param privateKey func (client *Client) RawGetTransactions(accountAddress AccountAddress, fromTransactionId InternalTransactionId, privateKey InputKey) (*RawTransactions, error) { - result, err := client.executeAsynchronously( + extra := client.getNewExtra() + result, err := client.executeAsynchronously(extra, struct { Type string `json:"@type"` + Extra string `json:"@extra"` AccountAddress AccountAddress `json:"account_address"` FromTransactionId InternalTransactionId `json:"from_transaction_id"` PrivateKey InputKey `json:"private_key"` }{ Type: "raw.getTransactions", + Extra: extra, AccountAddress: accountAddress, FromTransactionId: fromTransactionId, PrivateKey: privateKey, @@ -697,20 +769,23 @@ func (client *Client) RawGetTransactions(accountAddress AccountAddress, fromTran var rawTransactions RawTransactions err = json.Unmarshal(result.Raw, &rawTransactions) - return &rawTransactions, err + return &rawTransactions, err } // RawSendMessage // @param body func (client *Client) RawSendMessage(body []byte) (*Ok, error) { - result, err := client.executeAsynchronously( + extra := client.getNewExtra() + result, err := client.executeAsynchronously(extra, struct { - Type string `json:"@type"` - Body []byte `json:"body"` + Type string `json:"@type"` + Extra string `json:"@extra"` + Body []byte `json:"body"` }{ - Type: "raw.sendMessage", - Body: body, + Type: "raw.sendMessage", + Extra: extra, + Body: body, }, ) @@ -724,8 +799,8 @@ func (client *Client) RawSendMessage(body []byte) (*Ok, error) { var Ok Ok err = json.Unmarshal(result.Raw, &Ok) - return &Ok, err + return &Ok, err } // RawCreateAndSendMessage @@ -733,14 +808,17 @@ func (client *Client) RawSendMessage(body []byte) (*Ok, error) { // @param destination // @param initialAccountState func (client *Client) RawCreateAndSendMessage(data []byte, destination AccountAddress, initialAccountState []byte) (*Ok, error) { - result, err := client.executeAsynchronously( + extra := client.getNewExtra() + result, err := client.executeAsynchronously(extra, struct { Type string `json:"@type"` + Extra string `json:"@extra"` Data []byte `json:"data"` Destination AccountAddress `json:"destination"` InitialAccountState []byte `json:"initial_account_state"` }{ Type: "raw.createAndSendMessage", + Extra: extra, Data: data, Destination: destination, InitialAccountState: initialAccountState, @@ -757,8 +835,8 @@ func (client *Client) RawCreateAndSendMessage(data []byte, destination AccountAd var ok Ok err = json.Unmarshal(result.Raw, &ok) - return &ok, err + return &ok, err } // RawCreateQuery @@ -767,15 +845,18 @@ func (client *Client) RawCreateAndSendMessage(data []byte, destination AccountAd // @param initCode // @param initData func (client *Client) RawCreateQuery(body []byte, destination AccountAddress, initCode []byte, initData []byte) (*QueryInfo, error) { - result, err := client.executeAsynchronously( + extra := client.getNewExtra() + result, err := client.executeAsynchronously(extra, struct { Type string `json:"@type"` + Extra string `json:"@extra"` Body []byte `json:"body"` Destination AccountAddress `json:"destination"` InitCode []byte `json:"init_code"` InitData []byte `json:"init_data"` }{ Type: "raw.createQuery", + Extra: extra, Body: body, Destination: destination, InitCode: initCode, @@ -793,23 +874,29 @@ func (client *Client) RawCreateQuery(body []byte, destination AccountAddress, in var queryInfo QueryInfo err = json.Unmarshal(result.Raw, &queryInfo) - return &queryInfo, err + return &queryInfo, err } // GetAccountAddress // @param initialAccountState // @param revision -func (client *Client) GetAccountAddress(initialAccountState InitialAccountState, revision int32) (*AccountAddress, error) { - result, err := client.executeAsynchronously( +// @param workchainId +func (client *Client) GetAccountAddress(initialAccountState InitialAccountState, revision int32, workchainId int32) (*AccountAddress, error) { + extra := client.getNewExtra() + result, err := client.executeAsynchronously(extra, struct { Type string `json:"@type"` + Extra string `json:"@extra"` InitialAccountState InitialAccountState `json:"initial_account_state"` Revision int32 `json:"revision"` + WorkchainId int32 `json:"workchain_id"` }{ Type: "getAccountAddress", + Extra: extra, InitialAccountState: initialAccountState, Revision: revision, + WorkchainId: workchainId, }, ) @@ -823,20 +910,26 @@ func (client *Client) GetAccountAddress(initialAccountState InitialAccountState, var accountAddress AccountAddress err = json.Unmarshal(result.Raw, &accountAddress) - return &accountAddress, err + return &accountAddress, err } // GuessAccountRevision // @param initialAccountState -func (client *Client) GuessAccountRevision(initialAccountState InitialAccountState) (*AccountRevisionList, error) { - result, err := client.executeAsynchronously( +// @param workchainId +func (client *Client) GuessAccountRevision(initialAccountState InitialAccountState, workchainId int32) (*AccountRevisionList, error) { + extra := client.getNewExtra() + result, err := client.executeAsynchronously(extra, struct { Type string `json:"@type"` + Extra string `json:"@extra"` InitialAccountState InitialAccountState `json:"initial_account_state"` + WorkchainId int32 `json:"workchain_id"` }{ Type: "guessAccountRevision", + Extra: extra, InitialAccountState: initialAccountState, + WorkchainId: workchainId, }, ) @@ -850,19 +943,55 @@ func (client *Client) GuessAccountRevision(initialAccountState InitialAccountSta var accountRevisionList AccountRevisionList err = json.Unmarshal(result.Raw, &accountRevisionList) + return &accountRevisionList, err +} +// GuessAccount +// @param publicKey +// @param rwalletInitPublicKey +func (client *Client) GuessAccount(publicKey string, rwalletInitPublicKey string) (*AccountRevisionList, error) { + extra := client.getNewExtra() + result, err := client.executeAsynchronously(extra, + struct { + Type string `json:"@type"` + Extra string `json:"@extra"` + PublicKey string `json:"public_key"` + RwalletInitPublicKey string `json:"rwallet_init_public_key"` + }{ + Type: "guessAccount", + Extra: extra, + PublicKey: publicKey, + RwalletInitPublicKey: rwalletInitPublicKey, + }, + ) + + if err != nil { + return nil, err + } + + if result.Data["@type"].(string) == "error" { + return nil, fmt.Errorf("error! code: %d msg: %s", result.Data["code"], result.Data["message"]) + } + + var accountRevisionList AccountRevisionList + err = json.Unmarshal(result.Raw, &accountRevisionList) + + return &accountRevisionList, err } // GetAccountState // @param accountAddress func (client *Client) GetAccountState(accountAddress AccountAddress) (*FullAccountState, error) { - result, err := client.executeAsynchronously( + extra := client.getNewExtra() + result, err := client.executeAsynchronously(extra, struct { Type string `json:"@type"` + Extra string `json:"@extra"` AccountAddress AccountAddress `json:"account_address"` }{ Type: "getAccountState", + Extra: extra, AccountAddress: accountAddress, }, ) @@ -877,29 +1006,35 @@ func (client *Client) GetAccountState(accountAddress AccountAddress) (*FullAccou var fullAccountState FullAccountState err = json.Unmarshal(result.Raw, &fullAccountState) - return &fullAccountState, err + return &fullAccountState, err } // CreateQuery // @param action // @param address +// @param initialAccountState // @param privateKey // @param timeout -func (client *Client) CreateQuery(action Action, address AccountAddress, privateKey InputKey, timeout int32) (*QueryInfo, error) { - result, err := client.executeAsynchronously( +func (client *Client) CreateQuery(action Action, address AccountAddress, initialAccountState InitialAccountState, privateKey InputKey, timeout int32) (*QueryInfo, error) { + extra := client.getNewExtra() + result, err := client.executeAsynchronously(extra, struct { - Type string `json:"@type"` - Action Action `json:"action"` - Address AccountAddress `json:"address"` - PrivateKey InputKey `json:"private_key"` - Timeout int32 `json:"timeout"` + Type string `json:"@type"` + Extra string `json:"@extra"` + Action Action `json:"action"` + Address AccountAddress `json:"address"` + InitialAccountState InitialAccountState `json:"initial_account_state"` + PrivateKey InputKey `json:"private_key"` + Timeout int32 `json:"timeout"` }{ - Type: "createQuery", - Action: action, - Address: address, - PrivateKey: privateKey, - Timeout: timeout, + Type: "createQuery", + Extra: extra, + Action: action, + Address: address, + InitialAccountState: initialAccountState, + PrivateKey: privateKey, + Timeout: timeout, }, ) @@ -913,21 +1048,24 @@ func (client *Client) CreateQuery(action Action, address AccountAddress, private var queryInfo QueryInfo err = json.Unmarshal(result.Raw, &queryInfo) - return &queryInfo, err + return &queryInfo, err } // MsgDecrypt // @param data // @param inputKey func (client *Client) MsgDecrypt(data MsgDataEncryptedArray, inputKey InputKey) (*MsgDataDecryptedArray, error) { - result, err := client.executeAsynchronously( + extra := client.getNewExtra() + result, err := client.executeAsynchronously(extra, struct { Type string `json:"@type"` + Extra string `json:"@extra"` Data MsgDataEncryptedArray `json:"data"` InputKey InputKey `json:"input_key"` }{ Type: "msg.decrypt", + Extra: extra, Data: data, InputKey: inputKey, }, @@ -943,21 +1081,24 @@ func (client *Client) MsgDecrypt(data MsgDataEncryptedArray, inputKey InputKey) var msgDataDecryptedArray MsgDataDecryptedArray err = json.Unmarshal(result.Raw, &msgDataDecryptedArray) - return &msgDataDecryptedArray, err + return &msgDataDecryptedArray, err } // MsgDecryptWithProof // @param data // @param proof func (client *Client) MsgDecryptWithProof(data MsgDataEncrypted, proof []byte) (*MsgData, error) { - result, err := client.executeAsynchronously( + extra := client.getNewExtra() + result, err := client.executeAsynchronously(extra, struct { Type string `json:"@type"` + Extra string `json:"@extra"` Data MsgDataEncrypted `json:"data"` Proof []byte `json:"proof"` }{ Type: "msg.decryptWithProof", + Extra: extra, Data: data, Proof: proof, }, @@ -973,20 +1114,23 @@ func (client *Client) MsgDecryptWithProof(data MsgDataEncrypted, proof []byte) ( var msgData MsgData err = json.Unmarshal(result.Raw, &msgData) - return &msgData, err + return &msgData, err } // QuerySend // @param id func (client *Client) QuerySend(id int64) (*Ok, error) { - result, err := client.executeAsynchronously( + extra := client.getNewExtra() + result, err := client.executeAsynchronously(extra, struct { - Type string `json:"@type"` - Id int64 `json:"id"` + Type string `json:"@type"` + Extra string `json:"@extra"` + Id int64 `json:"id"` }{ - Type: "query.send", - Id: id, + Type: "query.send", + Extra: extra, + Id: id, }, ) @@ -1000,20 +1144,23 @@ func (client *Client) QuerySend(id int64) (*Ok, error) { var ok Ok err = json.Unmarshal(result.Raw, &ok) - return &ok, err + return &ok, err } // QueryForget // @param id func (client *Client) QueryForget(id int64) (*Ok, error) { - result, err := client.executeAsynchronously( + extra := client.getNewExtra() + result, err := client.executeAsynchronously(extra, struct { - Type string `json:"@type"` - Id int64 `json:"id"` + Type string `json:"@type"` + Extra string `json:"@extra"` + Id int64 `json:"id"` }{ - Type: "query.forget", - Id: id, + Type: "query.forget", + Extra: extra, + Id: id, }, ) @@ -1027,20 +1174,56 @@ func (client *Client) QueryForget(id int64) (*Ok, error) { var ok Ok err = json.Unmarshal(result.Raw, &ok) + return &ok, err +} + +// QueryEstimateFees +// @param id +// @param ignoreChksig +func (client *Client) QueryEstimateFees(id int64, ignoreChksig bool) (*QueryFees, error) { + extra := client.getNewExtra() + result, err := client.executeAsynchronously(extra, + struct { + Type string `json:"@type"` + Extra string `json:"@extra"` + Id int64 `json:"id"` + IgnoreChksig bool `json:"ignore_chksig"` + }{ + Type: "query.estimateFees", + Extra: extra, + Id: id, + IgnoreChksig: ignoreChksig, + }, + ) + + if err != nil { + return nil, err + } + if result.Data["@type"].(string) == "error" { + return nil, fmt.Errorf("error! code: %d msg: %s", result.Data["code"], result.Data["message"]) + } + + var queryFees QueryFees + err = json.Unmarshal(result.Raw, &queryFees) + + return &queryFees, err } // QueryGetInfo // @param id func (client *Client) QueryGetInfo(id int64) (*QueryInfo, error) { - result, err := client.executeAsynchronously( + extra := client.getNewExtra() + result, err := client.executeAsynchronously(extra, struct { - Type string `json:"@type"` - Id int64 `json:"id"` + Type string `json:"@type"` + Extra string `json:"@extra"` + Id int64 `json:"id"` }{ - Type: "query.getInfo", - Id: id, + Type: "query.getInfo", + Extra: extra, + Id: id, }, ) @@ -1054,19 +1237,22 @@ func (client *Client) QueryGetInfo(id int64) (*QueryInfo, error) { var queryInfo QueryInfo err = json.Unmarshal(result.Raw, &queryInfo) - return &queryInfo, err + return &queryInfo, err } // SmcLoad // @param accountAddress func (client *Client) SmcLoad(accountAddress AccountAddress) (*SmcInfo, error) { - result, err := client.executeAsynchronously( + extra := client.getNewExtra() + result, err := client.executeAsynchronously(extra, struct { Type string `json:"@type"` + Extra string `json:"@extra"` AccountAddress AccountAddress `json:"account_address"` }{ Type: "smc.load", + Extra: extra, AccountAddress: accountAddress, }, ) @@ -1081,20 +1267,23 @@ func (client *Client) SmcLoad(accountAddress AccountAddress) (*SmcInfo, error) { var smcInfo SmcInfo err = json.Unmarshal(result.Raw, &smcInfo) - return &smcInfo, err + return &smcInfo, err } // SmcGetCode // @param id func (client *Client) SmcGetCode(id int64) (*TvmCell, error) { - result, err := client.executeAsynchronously( + extra := client.getNewExtra() + result, err := client.executeAsynchronously(extra, struct { - Type string `json:"@type"` - Id int64 `json:"id"` + Type string `json:"@type"` + Extra string `json:"@extra"` + Id int64 `json:"id"` }{ - Type: "smc.getCode", - Id: id, + Type: "smc.getCode", + Extra: extra, + Id: id, }, ) @@ -1108,20 +1297,23 @@ func (client *Client) SmcGetCode(id int64) (*TvmCell, error) { var tvmCell TvmCell err = json.Unmarshal(result.Raw, &tvmCell) - return &tvmCell, err + return &tvmCell, err } // SmcGetData // @param id func (client *Client) SmcGetData(id int64) (*TvmCell, error) { - result, err := client.executeAsynchronously( + extra := client.getNewExtra() + result, err := client.executeAsynchronously(extra, struct { - Type string `json:"@type"` - Id int64 `json:"id"` + Type string `json:"@type"` + Extra string `json:"@extra"` + Id int64 `json:"id"` }{ - Type: "smc.getData", - Id: id, + Type: "smc.getData", + Extra: extra, + Id: id, }, ) @@ -1135,20 +1327,23 @@ func (client *Client) SmcGetData(id int64) (*TvmCell, error) { var tvmCell TvmCell err = json.Unmarshal(result.Raw, &tvmCell) - return &tvmCell, err + return &tvmCell, err } // SmcGetState // @param id func (client *Client) SmcGetState(id int64) (*TvmCell, error) { - result, err := client.executeAsynchronously( + extra := client.getNewExtra() + result, err := client.executeAsynchronously(extra, struct { - Type string `json:"@type"` - Id int64 `json:"id"` + Type string `json:"@type"` + Extra string `json:"@extra"` + Id int64 `json:"id"` }{ - Type: "smc.getState", - Id: id, + Type: "smc.getState", + Extra: extra, + Id: id, }, ) @@ -1162,8 +1357,8 @@ func (client *Client) SmcGetState(id int64) (*TvmCell, error) { var tvmCell TvmCell err = json.Unmarshal(result.Raw, &tvmCell) - return &tvmCell, err + return &tvmCell, err } // SmcRunGetMethod @@ -1171,14 +1366,17 @@ func (client *Client) SmcGetState(id int64) (*TvmCell, error) { // @param method // @param stack func (client *Client) SmcRunGetMethod(id int64, method SmcMethodId, stack []TvmStackEntry) (*SmcRunResult, error) { - result, err := client.executeAsynchronously( + extra := client.getNewExtra() + result, err := client.executeAsynchronously(extra, struct { Type string `json:"@type"` + Extra string `json:"@extra"` Id int64 `json:"id"` Method SmcMethodId `json:"method"` Stack []TvmStackEntry `json:"stack"` }{ Type: "smc.runGetMethod", + Extra: extra, Id: id, Method: method, Stack: stack, @@ -1195,8 +1393,8 @@ func (client *Client) SmcRunGetMethod(id int64, method SmcMethodId, stack []TvmS var smcRunResult SmcRunResult err = json.Unmarshal(result.Raw, &smcRunResult) - return &smcRunResult, err + return &smcRunResult, err } // DnsResolve @@ -1205,15 +1403,18 @@ func (client *Client) SmcRunGetMethod(id int64, method SmcMethodId, stack []TvmS // @param name // @param ttl func (client *Client) DnsResolve(accountAddress AccountAddress, category int32, name string, ttl int32) (*DnsResolved, error) { - result, err := client.executeAsynchronously( + extra := client.getNewExtra() + result, err := client.executeAsynchronously(extra, struct { Type string `json:"@type"` + Extra string `json:"@extra"` AccountAddress AccountAddress `json:"account_address"` Category int32 `json:"category"` Name string `json:"name"` Ttl int32 `json:"ttl"` }{ Type: "dns.resolve", + Extra: extra, AccountAddress: accountAddress, Category: category, Name: name, @@ -1231,21 +1432,315 @@ func (client *Client) DnsResolve(accountAddress AccountAddress, category int32, var dnsResolved DnsResolved err = json.Unmarshal(result.Raw, &dnsResolved) + return &dnsResolved, err +} + +// PchanSignPromise +// @param inputKey +// @param promise +func (client *Client) PchanSignPromise(inputKey InputKey, promise PchanPromise) (*PchanPromise, error) { + extra := client.getNewExtra() + result, err := client.executeAsynchronously(extra, + struct { + Type string `json:"@type"` + Extra string `json:"@extra"` + InputKey InputKey `json:"input_key"` + Promise PchanPromise `json:"promise"` + }{ + Type: "pchan.signPromise", + Extra: extra, + InputKey: inputKey, + Promise: promise, + }, + ) + + if err != nil { + return nil, err + } + + if result.Data["@type"].(string) == "error" { + return nil, fmt.Errorf("error! code: %d msg: %s", result.Data["code"], result.Data["message"]) + } + + var pchanPromise PchanPromise + err = json.Unmarshal(result.Raw, &pchanPromise) + + return &pchanPromise, err +} + +// PchanValidatePromise +// @param promise +// @param publicKey +func (client *Client) PchanValidatePromise(promise PchanPromise, publicKey []byte) (*Ok, error) { + extra := client.getNewExtra() + result, err := client.executeAsynchronously(extra, + struct { + Type string `json:"@type"` + Extra string `json:"@extra"` + Promise PchanPromise `json:"promise"` + PublicKey []byte `json:"public_key"` + }{ + Type: "pchan.validatePromise", + Extra: extra, + Promise: promise, + PublicKey: publicKey, + }, + ) + + if err != nil { + return nil, err + } + + if result.Data["@type"].(string) == "error" { + return nil, fmt.Errorf("error! code: %d msg: %s", result.Data["code"], result.Data["message"]) + } + + var ok Ok + err = json.Unmarshal(result.Raw, &ok) + + return &ok, err +} + +// PchanPackPromise +// @param promise +func (client *Client) PchanPackPromise(promise PchanPromise) (*Data, error) { + extra := client.getNewExtra() + result, err := client.executeAsynchronously(extra, + struct { + Type string `json:"@type"` + Extra string `json:"@extra"` + Promise PchanPromise `json:"promise"` + }{ + Type: "pchan.packPromise", + Extra: extra, + Promise: promise, + }, + ) + + if err != nil { + return nil, err + } + + if result.Data["@type"].(string) == "error" { + return nil, fmt.Errorf("error! code: %d msg: %s", result.Data["code"], result.Data["message"]) + } + + var data Data + err = json.Unmarshal(result.Raw, &data) + + return &data, err +} + +// PchanUnpackPromise +// @param data +func (client *Client) PchanUnpackPromise(data SecureBytes) (*PchanPromise, error) { + extra := client.getNewExtra() + result, err := client.executeAsynchronously(extra, + struct { + Type string `json:"@type"` + Extra string `json:"@extra"` + Data SecureBytes `json:"data"` + }{ + Type: "pchan.unpackPromise", + Extra: extra, + Data: data, + }, + ) + + if err != nil { + return nil, err + } + + if result.Data["@type"].(string) == "error" { + return nil, fmt.Errorf("error! code: %d msg: %s", result.Data["code"], result.Data["message"]) + } + + var pchanPromise PchanPromise + err = json.Unmarshal(result.Raw, &pchanPromise) + + return &pchanPromise, err +} + +// BlocksGetMasterchainInfo +func (client *Client) BlocksGetMasterchainInfo() (*BlocksMasterchainInfo, error) { + extra := client.getNewExtra() + result, err := client.executeAsynchronously(extra, + struct { + Type string `json:"@type"` + Extra string `json:"@extra"` + }{ + Type: "blocks.getMasterchainInfo", + Extra: extra, + }, + ) + + if err != nil { + return nil, err + } + + if result.Data["@type"].(string) == "error" { + return nil, fmt.Errorf("error! code: %d msg: %s", result.Data["code"], result.Data["message"]) + } + + var blocksMasterchainInfo BlocksMasterchainInfo + err = json.Unmarshal(result.Raw, &blocksMasterchainInfo) + + return &blocksMasterchainInfo, err +} + +// BlocksGetShards +// @param id +func (client *Client) BlocksGetShards(id TonBlockIdExt) (*BlocksShards, error) { + extra := client.getNewExtra() + result, err := client.executeAsynchronously(extra, + struct { + Type string `json:"@type"` + Extra string `json:"@extra"` + Id TonBlockIdExt `json:"id"` + }{ + Type: "blocks.getShards", + Extra: extra, + Id: id, + }, + ) + + if err != nil { + return nil, err + } + + if result.Data["@type"].(string) == "error" { + return nil, fmt.Errorf("error! code: %d msg: %s", result.Data["code"], result.Data["message"]) + } + + var blocksShards BlocksShards + err = json.Unmarshal(result.Raw, &blocksShards) + + return &blocksShards, err +} + +// BlocksLookupBlock +// @param id +// @param lt +// @param mode +// @param utime +func (client *Client) BlocksLookupBlock(id TonBlockId, lt JSONInt64, mode int32, utime int32) (*TonBlockIdExt, error) { + extra := client.getNewExtra() + result, err := client.executeAsynchronously(extra, + struct { + Type string `json:"@type"` + Extra string `json:"@extra"` + Id TonBlockId `json:"id"` + Lt JSONInt64 `json:"lt"` + Mode int32 `json:"mode"` + Utime int32 `json:"utime"` + }{ + Type: "blocks.lookupBlock", + Extra: extra, + Id: id, + Lt: lt, + Mode: mode, + Utime: utime, + }, + ) + + if err != nil { + return nil, err + } + + if result.Data["@type"].(string) == "error" { + return nil, fmt.Errorf("error! code: %d msg: %s", result.Data["code"], result.Data["message"]) + } + var tonBlockIdExt TonBlockIdExt + err = json.Unmarshal(result.Raw, &tonBlockIdExt) + + return &tonBlockIdExt, err +} + +// BlocksGetTransactions +// @param after +// @param count +// @param id +// @param mode +func (client *Client) BlocksGetTransactions(after BlocksAccountTransactionId, count int32, id TonBlockIdExt, mode int32) (*BlocksTransactions, error) { + extra := client.getNewExtra() + result, err := client.executeAsynchronously(extra, + struct { + Type string `json:"@type"` + Extra string `json:"@extra"` + After BlocksAccountTransactionId `json:"after"` + Count int32 `json:"count"` + Id TonBlockIdExt `json:"id"` + Mode int32 `json:"mode"` + }{ + Type: "blocks.getTransactions", + Extra: extra, + After: after, + Count: count, + Id: id, + Mode: mode, + }, + ) + + if err != nil { + return nil, err + } + + if result.Data["@type"].(string) == "error" { + return nil, fmt.Errorf("error! code: %d msg: %s", result.Data["code"], result.Data["message"]) + } + + var blocksTransactions BlocksTransactions + err = json.Unmarshal(result.Raw, &blocksTransactions) + + return &blocksTransactions, err +} + +// BlocksGetBlockHeader +// @param id +func (client *Client) BlocksGetBlockHeader(id TonBlockIdExt) (*BlocksHeader, error) { + extra := client.getNewExtra() + result, err := client.executeAsynchronously(extra, + struct { + Type string `json:"@type"` + Extra string `json:"@extra"` + Id TonBlockIdExt `json:"id"` + }{ + Type: "blocks.getBlockHeader", + Extra: extra, + Id: id, + }, + ) + + if err != nil { + return nil, err + } + + if result.Data["@type"].(string) == "error" { + return nil, fmt.Errorf("error! code: %d msg: %s", result.Data["code"], result.Data["message"]) + } + + var blocksHeader BlocksHeader + err = json.Unmarshal(result.Raw, &blocksHeader) + + return &blocksHeader, err } // OnLiteServerQueryResult // @param bytes // @param id func (client *Client) OnLiteServerQueryResult(bytes []byte, id JSONInt64) (*Ok, error) { - result, err := client.executeAsynchronously( + extra := client.getNewExtra() + result, err := client.executeAsynchronously(extra, struct { Type string `json:"@type"` + Extra string `json:"@extra"` Bytes []byte `json:"bytes"` Id JSONInt64 `json:"id"` }{ Type: "onLiteServerQueryResult", + Extra: extra, Bytes: bytes, Id: id, }, @@ -1261,21 +1756,24 @@ func (client *Client) OnLiteServerQueryResult(bytes []byte, id JSONInt64) (*Ok, var ok Ok err = json.Unmarshal(result.Raw, &ok) - return &ok, err + return &ok, err } // OnLiteServerQueryError // @param error // @param id func (client *Client) OnLiteServerQueryError(error Error, id JSONInt64) (*Ok, error) { - result, err := client.executeAsynchronously( + extra := client.getNewExtra() + result, err := client.executeAsynchronously(extra, struct { Type string `json:"@type"` + Extra string `json:"@extra"` Error Error `json:"error"` Id JSONInt64 `json:"id"` }{ Type: "onLiteServerQueryError", + Extra: extra, Error: error, Id: id, }, @@ -1291,21 +1789,24 @@ func (client *Client) OnLiteServerQueryError(error Error, id JSONInt64) (*Ok, er var ok Ok err = json.Unmarshal(result.Raw, &ok) - return &ok, err + return &ok, err } // WithBlock // @param function // @param id func (client *Client) WithBlock(function Function, id TonBlockIdExt) (*Object, error) { - result, err := client.executeAsynchronously( + extra := client.getNewExtra() + result, err := client.executeAsynchronously(extra, struct { Type string `json:"@type"` + Extra string `json:"@extra"` Function Function `json:"function"` Id TonBlockIdExt `json:"id"` }{ Type: "withBlock", + Extra: extra, Function: function, Id: id, }, @@ -1321,20 +1822,23 @@ func (client *Client) WithBlock(function Function, id TonBlockIdExt) (*Object, e var object Object err = json.Unmarshal(result.Raw, &object) - return &object, err + return &object, err } // RunTests // @param dir func (client *Client) RunTests(dir string) (*Ok, error) { - result, err := client.executeAsynchronously( + extra := client.getNewExtra() + result, err := client.executeAsynchronously(extra, struct { - Type string `json:"@type"` - Dir string `json:"dir"` + Type string `json:"@type"` + Extra string `json:"@extra"` + Dir string `json:"dir"` }{ - Type: "runTests", - Dir: dir, + Type: "runTests", + Extra: extra, + Dir: dir, }, ) @@ -1348,17 +1852,20 @@ func (client *Client) RunTests(dir string) (*Ok, error) { var ok Ok err = json.Unmarshal(result.Raw, &ok) - return &ok, err + return &ok, err } // LiteServerGetInfo func (client *Client) LiteServerGetInfo() (*LiteServerInfo, error) { - result, err := client.executeAsynchronously( + extra := client.getNewExtra() + result, err := client.executeAsynchronously(extra, struct { - Type string `json:"@type"` + Type string `json:"@type"` + Extra string `json:"@extra"` }{ - Type: "liteServer.getInfo", + Type: "liteServer.getInfo", + Extra: extra, }, ) @@ -1372,19 +1879,22 @@ func (client *Client) LiteServerGetInfo() (*LiteServerInfo, error) { var liteServerInfo LiteServerInfo err = json.Unmarshal(result.Raw, &liteServerInfo) - return &liteServerInfo, err + return &liteServerInfo, err } // SetLogStream Sets new log stream for internal logging of tonlib. This is an offline method. Can be called before authorization. Can be called synchronously // @param logStream New log stream func (client *Client) SetLogStream(logStream LogStream) (*Ok, error) { - result, err := client.executeAsynchronously( + extra := client.getNewExtra() + result, err := client.executeAsynchronously(extra, struct { Type string `json:"@type"` + Extra string `json:"@extra"` LogStream LogStream `json:"log_stream"` }{ Type: "setLogStream", + Extra: extra, LogStream: logStream, }, ) @@ -1399,17 +1909,20 @@ func (client *Client) SetLogStream(logStream LogStream) (*Ok, error) { var ok Ok err = json.Unmarshal(result.Raw, &ok) - return &ok, err + return &ok, err } // GetLogStream Returns information about currently used log stream for internal logging of tonlib. This is an offline method. Can be called before authorization. Can be called synchronously func (client *Client) GetLogStream() (LogStream, error) { - result, err := client.executeAsynchronously( + extra := client.getNewExtra() + result, err := client.executeAsynchronously(extra, struct { - Type string `json:"@type"` + Type string `json:"@type"` + Extra string `json:"@extra"` }{ - Type: "getLogStream", + Type: "getLogStream", + Extra: extra, }, ) @@ -1446,12 +1959,15 @@ func (client *Client) GetLogStream() (LogStream, error) { // SetLogVerbosityLevel Sets the verbosity level of the internal logging of tonlib. This is an offline method. Can be called before authorization. Can be called synchronously // @param newVerbosityLevel New value of the verbosity level for logging. Value 0 corresponds to fatal errors, value 1 corresponds to errors, value 2 corresponds to warnings and debug warnings, value 3 corresponds to informational, value 4 corresponds to debug, value 5 corresponds to verbose debug, value greater than 5 and up to 1023 can be used to enable even more logging func (client *Client) SetLogVerbosityLevel(newVerbosityLevel int32) (*Ok, error) { - result, err := client.executeAsynchronously( + extra := client.getNewExtra() + result, err := client.executeAsynchronously(extra, struct { Type string `json:"@type"` + Extra string `json:"@extra"` NewVerbosityLevel int32 `json:"new_verbosity_level"` }{ Type: "setLogVerbosityLevel", + Extra: extra, NewVerbosityLevel: newVerbosityLevel, }, ) @@ -1466,17 +1982,20 @@ func (client *Client) SetLogVerbosityLevel(newVerbosityLevel int32) (*Ok, error) var ok Ok err = json.Unmarshal(result.Raw, &ok) - return &ok, err + return &ok, err } // GetLogVerbosityLevel Returns current verbosity level of the internal logging of tonlib. This is an offline method. Can be called before authorization. Can be called synchronously func (client *Client) GetLogVerbosityLevel() (*LogVerbosityLevel, error) { - result, err := client.executeAsynchronously( + extra := client.getNewExtra() + result, err := client.executeAsynchronously(extra, struct { - Type string `json:"@type"` + Type string `json:"@type"` + Extra string `json:"@extra"` }{ - Type: "getLogVerbosityLevel", + Type: "getLogVerbosityLevel", + Extra: extra, }, ) @@ -1490,17 +2009,20 @@ func (client *Client) GetLogVerbosityLevel() (*LogVerbosityLevel, error) { var logVerbosityLevel LogVerbosityLevel err = json.Unmarshal(result.Raw, &logVerbosityLevel) - return &logVerbosityLevel, err + return &logVerbosityLevel, err } // GetLogTags Returns list of available tonlib internal log tags, for example, ["actor", "binlog", "connections", "notifications", "proxy"]. This is an offline method. Can be called before authorization. Can be called synchronously func (client *Client) GetLogTags() (*LogTags, error) { - result, err := client.executeAsynchronously( + extra := client.getNewExtra() + result, err := client.executeAsynchronously(extra, struct { - Type string `json:"@type"` + Type string `json:"@type"` + Extra string `json:"@extra"` }{ - Type: "getLogTags", + Type: "getLogTags", + Extra: extra, }, ) @@ -1514,21 +2036,24 @@ func (client *Client) GetLogTags() (*LogTags, error) { var logTags LogTags err = json.Unmarshal(result.Raw, &logTags) - return &logTags, err + return &logTags, err } // SetLogTagVerbosityLevel Sets the verbosity level for a specified tonlib internal log tag. This is an offline method. Can be called before authorization. Can be called synchronously // @param newVerbosityLevel New verbosity level; 1-1024 // @param tag Logging tag to change verbosity level func (client *Client) SetLogTagVerbosityLevel(newVerbosityLevel int32, tag string) (*Ok, error) { - result, err := client.executeAsynchronously( + extra := client.getNewExtra() + result, err := client.executeAsynchronously(extra, struct { Type string `json:"@type"` + Extra string `json:"@extra"` NewVerbosityLevel int32 `json:"new_verbosity_level"` Tag string `json:"tag"` }{ Type: "setLogTagVerbosityLevel", + Extra: extra, NewVerbosityLevel: newVerbosityLevel, Tag: tag, }, @@ -1544,20 +2069,23 @@ func (client *Client) SetLogTagVerbosityLevel(newVerbosityLevel int32, tag strin var ok Ok err = json.Unmarshal(result.Raw, &ok) - return &ok, err + return &ok, err } // GetLogTagVerbosityLevel Returns current verbosity level for a specified tonlib internal log tag. This is an offline method. Can be called before authorization. Can be called synchronously // @param tag Logging tag to change verbosity level func (client *Client) GetLogTagVerbosityLevel(tag string) (*LogVerbosityLevel, error) { - result, err := client.executeAsynchronously( + extra := client.getNewExtra() + result, err := client.executeAsynchronously(extra, struct { - Type string `json:"@type"` - Tag string `json:"tag"` + Type string `json:"@type"` + Extra string `json:"@extra"` + Tag string `json:"tag"` }{ - Type: "getLogTagVerbosityLevel", - Tag: tag, + Type: "getLogTagVerbosityLevel", + Extra: extra, + Tag: tag, }, ) @@ -1571,36 +2099,6 @@ func (client *Client) GetLogTagVerbosityLevel(tag string) (*LogVerbosityLevel, e var logVerbosityLevel LogVerbosityLevel err = json.Unmarshal(result.Raw, &logVerbosityLevel) - return &logVerbosityLevel, err - -} - -// AddLogMessage Adds a message to tonlib internal log. This is an offline method. Can be called before authorization. Can be called synchronously -// @param text Text of a message to log -// @param verbosityLevel Minimum verbosity level needed for the message to be logged, 0-1023 -func (client *Client) AddLogMessage(text string, verbosityLevel int32) (*Ok, error) { - result, err := client.executeAsynchronously( - struct { - Type string `json:"@type"` - Text string `json:"text"` - VerbosityLevel int32 `json:"verbosity_level"` - }{ - Type: "addLogMessage", - Text: text, - VerbosityLevel: verbosityLevel, - }, - ) - - if err != nil { - return nil, err - } - - if result.Data["@type"].(string) == "error" { - return nil, fmt.Errorf("error! code: %d msg: %s", result.Data["code"], result.Data["message"]) - } - - var ok Ok - err = json.Unmarshal(result.Raw, &ok) - return &ok, err + return &logVerbosityLevel, err } diff --git a/v2/simple.go b/v2/simple.go index 76ad921..9781053 100644 --- a/v2/simple.go +++ b/v2/simple.go @@ -374,10 +374,6 @@ func (client *Client) GetAccountStateSimple(address string) (*FullAccountState, return client.GetAccountState(*accountAddress) } -func (client *Client) GetLastBlock() (string, error) { - return client.Sync(SyncState(SyncState{})) -} - func (client *Client) TonlibSendFile(bocFilePath string) error { if !fileExists(bocFilePath) { return fmt.Errorf("file does not exist") diff --git a/v2/structs.go b/v2/structs.go index e3cd511..0430e87 100755 --- a/v2/structs.go +++ b/v2/structs.go @@ -389,7 +389,8 @@ func NewOptions(config *Config, keystoreType *KeyStoreType) *Options { // OptionsConfigInfo type OptionsConfigInfo struct { tonCommon - DefaultWalletId JSONInt64 `json:"default_wallet_id"` // + DefaultRwalletInitPublicKey string `json:"default_rwallet_init_public_key"` // + DefaultWalletId JSONInt64 `json:"default_wallet_id"` // } // MessageType return the string telegram-type of OptionsConfigInfo @@ -399,11 +400,13 @@ func (optionsConfigInfo *OptionsConfigInfo) MessageType() string { // NewOptionsConfigInfo creates a new OptionsConfigInfo // +// @param defaultRwalletInitPublicKey // @param defaultWalletId -func NewOptionsConfigInfo(defaultWalletId JSONInt64) *OptionsConfigInfo { +func NewOptionsConfigInfo(defaultRwalletInitPublicKey string, defaultWalletId JSONInt64) *OptionsConfigInfo { optionsConfigInfoTemp := OptionsConfigInfo{ - tonCommon: tonCommon{Type: "options.configInfo"}, - DefaultWalletId: defaultWalletId, + tonCommon: tonCommon{Type: "options.configInfo"}, + DefaultRwalletInitPublicKey: defaultRwalletInitPublicKey, + DefaultWalletId: defaultWalletId, } return &optionsConfigInfoTemp @@ -639,29 +642,6 @@ func NewAccountAddress(accountAddress string) *AccountAddress { return &accountAddressTemp } -// AccountRevisionList -type AccountRevisionList struct { - tonCommon - Revisions []int32 `json:"revisions"` // -} - -// MessageType return the string telegram-type of AccountRevisionList -func (accountRevisionList *AccountRevisionList) MessageType() string { - return "accountRevisionList" -} - -// NewAccountRevisionList creates a new AccountRevisionList -// -// @param revisions -func NewAccountRevisionList(revisions []int32) *AccountRevisionList { - accountRevisionListTemp := AccountRevisionList{ - tonCommon: tonCommon{Type: "accountRevisionList"}, - Revisions: revisions, - } - - return &accountRevisionListTemp -} - // UnpackedAccountAddress type UnpackedAccountAddress struct { tonCommon @@ -833,7 +813,7 @@ type RawMessage struct { Destination *AccountAddress `json:"destination"` // FwdFee JSONInt64 `json:"fwd_fee"` // IhrFee JSONInt64 `json:"ihr_fee"` // - MsgData MsgData `json:"msg_data"` // + MsgData *MsgData `json:"msg_data"` // Source *AccountAddress `json:"source"` // Value JSONInt64 `json:"value"` // } @@ -853,7 +833,7 @@ func (rawMessage *RawMessage) MessageType() string { // @param msgData // @param source // @param value -func NewRawMessage(bodyHash string, createdLt JSONInt64, destination *AccountAddress, fwdFee JSONInt64, ihrFee JSONInt64, msgData MsgData, source *AccountAddress, value JSONInt64) *RawMessage { +func NewRawMessage(bodyHash string, createdLt JSONInt64, destination *AccountAddress, fwdFee JSONInt64, ihrFee JSONInt64, msgData *MsgData, source *AccountAddress, value JSONInt64) *RawMessage { rawMessageTemp := RawMessage{ tonCommon: tonCommon{Type: "raw.message"}, BodyHash: bodyHash, @@ -939,6 +919,47 @@ func NewRawTransactions(previousTransactionId *InternalTransactionId, transactio return &rawTransactionsTemp } +// PchanConfig +type PchanConfig struct { + tonCommon + AliceAddress *AccountAddress `json:"alice_address"` // + AlicePublicKey string `json:"alice_public_key"` // + BobAddress *AccountAddress `json:"bob_address"` // + BobPublicKey string `json:"bob_public_key"` // + ChannelId JSONInt64 `json:"channel_id"` // + CloseTimeout int32 `json:"close_timeout"` // + InitTimeout int32 `json:"init_timeout"` // +} + +// MessageType return the string telegram-type of PchanConfig +func (pchanConfig *PchanConfig) MessageType() string { + return "pchan.config" +} + +// NewPchanConfig creates a new PchanConfig +// +// @param aliceAddress +// @param alicePublicKey +// @param bobAddress +// @param bobPublicKey +// @param channelId +// @param closeTimeout +// @param initTimeout +func NewPchanConfig(aliceAddress *AccountAddress, alicePublicKey string, bobAddress *AccountAddress, bobPublicKey string, channelId JSONInt64, closeTimeout int32, initTimeout int32) *PchanConfig { + pchanConfigTemp := PchanConfig{ + tonCommon: tonCommon{Type: "pchan.config"}, + AliceAddress: aliceAddress, + AlicePublicKey: alicePublicKey, + BobAddress: bobAddress, + BobPublicKey: bobPublicKey, + ChannelId: channelId, + CloseTimeout: closeTimeout, + InitTimeout: initTimeout, + } + + return &pchanConfigTemp +} + // RawInitialAccountState type RawInitialAccountState struct { tonCommon @@ -965,72 +986,6 @@ func NewRawInitialAccountState(code string, data string) *RawInitialAccountState return &rawInitialAccountStateTemp } -// TestGiverInitialAccountState -type TestGiverInitialAccountState struct { - tonCommon -} - -// MessageType return the string telegram-type of TestGiverInitialAccountState -func (testGiverInitialAccountState *TestGiverInitialAccountState) MessageType() string { - return "testGiver.initialAccountState" -} - -// NewTestGiverInitialAccountState creates a new TestGiverInitialAccountState -// -func NewTestGiverInitialAccountState() *TestGiverInitialAccountState { - testGiverInitialAccountStateTemp := TestGiverInitialAccountState{ - tonCommon: tonCommon{Type: "testGiver.initialAccountState"}, - } - - return &testGiverInitialAccountStateTemp -} - -// TestWalletInitialAccountState -type TestWalletInitialAccountState struct { - tonCommon - PublicKey string `json:"public_key"` // -} - -// MessageType return the string telegram-type of TestWalletInitialAccountState -func (testWalletInitialAccountState *TestWalletInitialAccountState) MessageType() string { - return "testWallet.initialAccountState" -} - -// NewTestWalletInitialAccountState creates a new TestWalletInitialAccountState -// -// @param publicKey -func NewTestWalletInitialAccountState(publicKey string) *TestWalletInitialAccountState { - testWalletInitialAccountStateTemp := TestWalletInitialAccountState{ - tonCommon: tonCommon{Type: "testWallet.initialAccountState"}, - PublicKey: publicKey, - } - - return &testWalletInitialAccountStateTemp -} - -// WalletInitialAccountState -type WalletInitialAccountState struct { - tonCommon - PublicKey string `json:"public_key"` // -} - -// MessageType return the string telegram-type of WalletInitialAccountState -func (walletInitialAccountState *WalletInitialAccountState) MessageType() string { - return "wallet.initialAccountState" -} - -// NewWalletInitialAccountState creates a new WalletInitialAccountState -// -// @param publicKey -func NewWalletInitialAccountState(publicKey string) *WalletInitialAccountState { - walletInitialAccountStateTemp := WalletInitialAccountState{ - tonCommon: tonCommon{Type: "wallet.initialAccountState"}, - PublicKey: publicKey, - } - - return &walletInitialAccountStateTemp -} - // WalletV3InitialAccountState type WalletV3InitialAccountState struct { tonCommon @@ -1109,6 +1064,87 @@ func NewWalletHighloadV2InitialAccountState(publicKey string, walletId JSONInt64 return &walletHighloadV2InitialAccountStateTemp } +// RwalletLimit +type RwalletLimit struct { + tonCommon + Seconds int32 `json:"seconds"` // + Value JSONInt64 `json:"value"` // +} + +// MessageType return the string telegram-type of RwalletLimit +func (rwalletLimit *RwalletLimit) MessageType() string { + return "rwallet.limit" +} + +// NewRwalletLimit creates a new RwalletLimit +// +// @param seconds +// @param value +func NewRwalletLimit(seconds int32, value JSONInt64) *RwalletLimit { + rwalletLimitTemp := RwalletLimit{ + tonCommon: tonCommon{Type: "rwallet.limit"}, + Seconds: seconds, + Value: value, + } + + return &rwalletLimitTemp +} + +// RwalletConfig +type RwalletConfig struct { + tonCommon + Limits []RwalletLimit `json:"limits"` // + StartAt int64 `json:"start_at"` // +} + +// MessageType return the string telegram-type of RwalletConfig +func (rwalletConfig *RwalletConfig) MessageType() string { + return "rwallet.config" +} + +// NewRwalletConfig creates a new RwalletConfig +// +// @param limits +// @param startAt +func NewRwalletConfig(limits []RwalletLimit, startAt int64) *RwalletConfig { + rwalletConfigTemp := RwalletConfig{ + tonCommon: tonCommon{Type: "rwallet.config"}, + Limits: limits, + StartAt: startAt, + } + + return &rwalletConfigTemp +} + +// RwalletInitialAccountState +type RwalletInitialAccountState struct { + tonCommon + InitPublicKey string `json:"init_public_key"` // + PublicKey string `json:"public_key"` // + WalletId JSONInt64 `json:"wallet_id"` // +} + +// MessageType return the string telegram-type of RwalletInitialAccountState +func (rwalletInitialAccountState *RwalletInitialAccountState) MessageType() string { + return "rwallet.initialAccountState" +} + +// NewRwalletInitialAccountState creates a new RwalletInitialAccountState +// +// @param initPublicKey +// @param publicKey +// @param walletId +func NewRwalletInitialAccountState(initPublicKey string, publicKey string, walletId JSONInt64) *RwalletInitialAccountState { + rwalletInitialAccountStateTemp := RwalletInitialAccountState{ + tonCommon: tonCommon{Type: "rwallet.initialAccountState"}, + InitPublicKey: initPublicKey, + PublicKey: publicKey, + WalletId: walletId, + } + + return &rwalletInitialAccountStateTemp +} + // DnsInitialAccountState type DnsInitialAccountState struct { tonCommon @@ -1135,6 +1171,29 @@ func NewDnsInitialAccountState(publicKey string, walletId JSONInt64) *DnsInitial return &dnsInitialAccountStateTemp } +// PchanInitialAccountState +type PchanInitialAccountState struct { + tonCommon + Config *PchanConfig `json:"config"` // +} + +// MessageType return the string telegram-type of PchanInitialAccountState +func (pchanInitialAccountState *PchanInitialAccountState) MessageType() string { + return "pchan.initialAccountState" +} + +// NewPchanInitialAccountState creates a new PchanInitialAccountState +// +// @param config +func NewPchanInitialAccountState(config *PchanConfig) *PchanInitialAccountState { + pchanInitialAccountStateTemp := PchanInitialAccountState{ + tonCommon: tonCommon{Type: "pchan.initialAccountState"}, + Config: config, + } + + return &pchanInitialAccountStateTemp +} + // RawAccountState type RawAccountState struct { tonCommon @@ -1164,52 +1223,6 @@ func NewRawAccountState(code string, data string, frozenHash string) *RawAccount return &rawAccountStateTemp } -// TestWalletAccountState -type TestWalletAccountState struct { - tonCommon - Seqno int32 `json:"seqno"` // -} - -// MessageType return the string telegram-type of TestWalletAccountState -func (testWalletAccountState *TestWalletAccountState) MessageType() string { - return "testWallet.accountState" -} - -// NewTestWalletAccountState creates a new TestWalletAccountState -// -// @param seqno -func NewTestWalletAccountState(seqno int32) *TestWalletAccountState { - testWalletAccountStateTemp := TestWalletAccountState{ - tonCommon: tonCommon{Type: "testWallet.accountState"}, - Seqno: seqno, - } - - return &testWalletAccountStateTemp -} - -// WalletAccountState -type WalletAccountState struct { - tonCommon - Seqno int32 `json:"seqno"` // -} - -// MessageType return the string telegram-type of WalletAccountState -func (walletAccountState *WalletAccountState) MessageType() string { - return "wallet.accountState" -} - -// NewWalletAccountState creates a new WalletAccountState -// -// @param seqno -func NewWalletAccountState(seqno int32) *WalletAccountState { - walletAccountStateTemp := WalletAccountState{ - tonCommon: tonCommon{Type: "wallet.accountState"}, - Seqno: seqno, - } - - return &walletAccountStateTemp -} - // WalletV3AccountState type WalletV3AccountState struct { tonCommon @@ -1285,29 +1298,6 @@ func NewWalletHighloadV2AccountState(walletId JSONInt64) *WalletHighloadV2Accoun return &walletHighloadV2AccountStateTemp } -// TestGiverAccountState -type TestGiverAccountState struct { - tonCommon - Seqno int32 `json:"seqno"` // -} - -// MessageType return the string telegram-type of TestGiverAccountState -func (testGiverAccountState *TestGiverAccountState) MessageType() string { - return "testGiver.accountState" -} - -// NewTestGiverAccountState creates a new TestGiverAccountState -// -// @param seqno -func NewTestGiverAccountState(seqno int32) *TestGiverAccountState { - testGiverAccountStateTemp := TestGiverAccountState{ - tonCommon: tonCommon{Type: "testGiver.accountState"}, - Seqno: seqno, - } - - return &testGiverAccountStateTemp -} - // DnsAccountState type DnsAccountState struct { tonCommon @@ -1331,6 +1321,175 @@ func NewDnsAccountState(walletId JSONInt64) *DnsAccountState { return &dnsAccountStateTemp } +// RwalletAccountState +type RwalletAccountState struct { + tonCommon + Config *RwalletConfig `json:"config"` // + Seqno int32 `json:"seqno"` // + UnlockedBalance JSONInt64 `json:"unlocked_balance"` // + WalletId JSONInt64 `json:"wallet_id"` // +} + +// MessageType return the string telegram-type of RwalletAccountState +func (rwalletAccountState *RwalletAccountState) MessageType() string { + return "rwallet.accountState" +} + +// NewRwalletAccountState creates a new RwalletAccountState +// +// @param config +// @param seqno +// @param unlockedBalance +// @param walletId +func NewRwalletAccountState(config *RwalletConfig, seqno int32, unlockedBalance JSONInt64, walletId JSONInt64) *RwalletAccountState { + rwalletAccountStateTemp := RwalletAccountState{ + tonCommon: tonCommon{Type: "rwallet.accountState"}, + Config: config, + Seqno: seqno, + UnlockedBalance: unlockedBalance, + WalletId: walletId, + } + + return &rwalletAccountStateTemp +} + +// PchanStateInit +type PchanStateInit struct { + tonCommon + A JSONInt64 `json:"A"` // + B JSONInt64 `json:"B"` // + ExpireAt int64 `json:"expire_at"` // + MinA JSONInt64 `json:"min_A"` // + MinB JSONInt64 `json:"min_B"` // + SignedA bool `json:"signed_A"` // + SignedB bool `json:"signed_B"` // +} + +// MessageType return the string telegram-type of PchanStateInit +func (pchanStateInit *PchanStateInit) MessageType() string { + return "pchan.stateInit" +} + +// NewPchanStateInit creates a new PchanStateInit +// +// @param a +// @param b +// @param expireAt +// @param minA +// @param minB +// @param signedA +// @param signedB +func NewPchanStateInit(a JSONInt64, b JSONInt64, expireAt int64, minA JSONInt64, minB JSONInt64, signedA bool, signedB bool) *PchanStateInit { + pchanStateInitTemp := PchanStateInit{ + tonCommon: tonCommon{Type: "pchan.stateInit"}, + A: a, + B: b, + ExpireAt: expireAt, + MinA: minA, + MinB: minB, + SignedA: signedA, + SignedB: signedB, + } + + return &pchanStateInitTemp +} + +// PchanStateClose +type PchanStateClose struct { + tonCommon + A JSONInt64 `json:"A"` // + B JSONInt64 `json:"B"` // + ExpireAt int64 `json:"expire_at"` // + MinA JSONInt64 `json:"min_A"` // + MinB JSONInt64 `json:"min_B"` // + SignedA bool `json:"signed_A"` // + SignedB bool `json:"signed_B"` // +} + +// MessageType return the string telegram-type of PchanStateClose +func (pchanStateClose *PchanStateClose) MessageType() string { + return "pchan.stateClose" +} + +// NewPchanStateClose creates a new PchanStateClose +// +// @param a +// @param b +// @param expireAt +// @param minA +// @param minB +// @param signedA +// @param signedB +func NewPchanStateClose(a JSONInt64, b JSONInt64, expireAt int64, minA JSONInt64, minB JSONInt64, signedA bool, signedB bool) *PchanStateClose { + pchanStateCloseTemp := PchanStateClose{ + tonCommon: tonCommon{Type: "pchan.stateClose"}, + A: a, + B: b, + ExpireAt: expireAt, + MinA: minA, + MinB: minB, + SignedA: signedA, + SignedB: signedB, + } + + return &pchanStateCloseTemp +} + +// PchanStatePayout +type PchanStatePayout struct { + tonCommon + A JSONInt64 `json:"A"` // + B JSONInt64 `json:"B"` // +} + +// MessageType return the string telegram-type of PchanStatePayout +func (pchanStatePayout *PchanStatePayout) MessageType() string { + return "pchan.statePayout" +} + +// NewPchanStatePayout creates a new PchanStatePayout +// +// @param a +// @param b +func NewPchanStatePayout(a JSONInt64, b JSONInt64) *PchanStatePayout { + pchanStatePayoutTemp := PchanStatePayout{ + tonCommon: tonCommon{Type: "pchan.statePayout"}, + A: a, + B: b, + } + + return &pchanStatePayoutTemp +} + +// PchanAccountState +type PchanAccountState struct { + tonCommon + Config *PchanConfig `json:"config"` // + Description string `json:"description"` // + State *PchanState `json:"state"` // +} + +// MessageType return the string telegram-type of PchanAccountState +func (pchanAccountState *PchanAccountState) MessageType() string { + return "pchan.accountState" +} + +// NewPchanAccountState creates a new PchanAccountState +// +// @param config +// @param description +// @param state +func NewPchanAccountState(config *PchanConfig, description string, state *PchanState) *PchanAccountState { + pchanAccountStateTemp := PchanAccountState{ + tonCommon: tonCommon{Type: "pchan.accountState"}, + Config: config, + Description: description, + State: state, + } + + return &pchanAccountStateTemp +} + // UninitedAccountState type UninitedAccountState struct { tonCommon @@ -1358,9 +1517,11 @@ func NewUninitedAccountState(frozenHash string) *UninitedAccountState { type FullAccountState struct { tonCommon AccountState *AccountState `json:"account_state"` // + Address *AccountAddress `json:"address"` // Balance JSONInt64 `json:"balance"` // BlockId *TonBlockIdExt `json:"block_id"` // LastTransactionId *InternalTransactionId `json:"last_transaction_id"` // + Revision int32 `json:"revision"` // SyncUtime int64 `json:"sync_utime"` // } @@ -1372,23 +1533,73 @@ func (fullAccountState *FullAccountState) MessageType() string { // NewFullAccountState creates a new FullAccountState // // @param accountState +// @param address // @param balance // @param blockId // @param lastTransactionId +// @param revision // @param syncUtime -func NewFullAccountState(accountState *AccountState, balance JSONInt64, blockId *TonBlockIdExt, lastTransactionId *InternalTransactionId, syncUtime int64) *FullAccountState { +func NewFullAccountState(accountState *AccountState, address *AccountAddress, balance JSONInt64, blockId *TonBlockIdExt, lastTransactionId *InternalTransactionId, revision int32, syncUtime int64) *FullAccountState { fullAccountStateTemp := FullAccountState{ tonCommon: tonCommon{Type: "fullAccountState"}, AccountState: accountState, + Address: address, Balance: balance, BlockId: blockId, LastTransactionId: lastTransactionId, + Revision: revision, SyncUtime: syncUtime, } return &fullAccountStateTemp } +// AccountRevisionList +type AccountRevisionList struct { + tonCommon + Revisions []FullAccountState `json:"revisions"` // +} + +// MessageType return the string telegram-type of AccountRevisionList +func (accountRevisionList *AccountRevisionList) MessageType() string { + return "accountRevisionList" +} + +// NewAccountRevisionList creates a new AccountRevisionList +// +// @param revisions +func NewAccountRevisionList(revisions []FullAccountState) *AccountRevisionList { + accountRevisionListTemp := AccountRevisionList{ + tonCommon: tonCommon{Type: "accountRevisionList"}, + Revisions: revisions, + } + + return &accountRevisionListTemp +} + +// AccountList +type AccountList struct { + tonCommon + Accounts []FullAccountState `json:"accounts"` // +} + +// MessageType return the string telegram-type of AccountList +func (accountList *AccountList) MessageType() string { + return "accountList" +} + +// NewAccountList creates a new AccountList +// +// @param accounts +func NewAccountList(accounts []FullAccountState) *AccountList { + accountListTemp := AccountList{ + tonCommon: tonCommon{Type: "accountList"}, + Accounts: accounts, + } + + return &accountListTemp +} + // SyncStateDone type SyncStateDone struct { tonCommon @@ -1441,7 +1652,8 @@ func NewSyncStateInProgress(currentSeqno int32, fromSeqno int32, toSeqno int32) // MsgDataRaw type MsgDataRaw struct { tonCommon - Body string `json:"body"` // + Body string `json:"body"` // + InitState string `json:"init_state"` // } // MessageType return the string telegram-type of MsgDataRaw @@ -1452,10 +1664,12 @@ func (msgDataRaw *MsgDataRaw) MessageType() string { // NewMsgDataRaw creates a new MsgDataRaw // // @param body -func NewMsgDataRaw(body string) *MsgDataRaw { +// @param initState +func NewMsgDataRaw(body string, initState string) *MsgDataRaw { msgDataRawTemp := MsgDataRaw{ tonCommon: tonCommon{Type: "msg.dataRaw"}, Body: body, + InitState: initState, } return &msgDataRawTemp @@ -1533,7 +1747,7 @@ func NewMsgDataEncryptedText(text string) *MsgDataEncryptedText { // MsgDataEncrypted type MsgDataEncrypted struct { tonCommon - Data MsgData `json:"data"` // + Data *MsgData `json:"data"` // Source *AccountAddress `json:"source"` // } @@ -1546,7 +1760,7 @@ func (msgDataEncrypted *MsgDataEncrypted) MessageType() string { // // @param data // @param source -func NewMsgDataEncrypted(data MsgData, source *AccountAddress) *MsgDataEncrypted { +func NewMsgDataEncrypted(data *MsgData, source *AccountAddress) *MsgDataEncrypted { msgDataEncryptedTemp := MsgDataEncrypted{ tonCommon: tonCommon{Type: "msg.dataEncrypted"}, Data: data, @@ -1559,7 +1773,7 @@ func NewMsgDataEncrypted(data MsgData, source *AccountAddress) *MsgDataEncrypted // MsgDataDecrypted type MsgDataDecrypted struct { tonCommon - Data MsgData `json:"data"` // + Data *MsgData `json:"data"` // Proof string `json:"proof"` // } @@ -1572,7 +1786,7 @@ func (msgDataDecrypted *MsgDataDecrypted) MessageType() string { // // @param data // @param proof -func NewMsgDataDecrypted(data MsgData, proof string) *MsgDataDecrypted { +func NewMsgDataDecrypted(data *MsgData, proof string) *MsgDataDecrypted { msgDataDecryptedTemp := MsgDataDecrypted{ tonCommon: tonCommon{Type: "msg.dataDecrypted"}, Data: data, @@ -1632,9 +1846,10 @@ func NewMsgDataDecryptedArray(elements []MsgDataDecrypted) *MsgDataDecryptedArra type MsgMessage struct { tonCommon Amount JSONInt64 `json:"amount"` // - Data MsgData `json:"data"` // + Data MsgData `json:"data"` // Destination *AccountAddress `json:"destination"` // PublicKey string `json:"public_key"` // + SendMode int32 `json:"send_mode"` // } // MessageType return the string telegram-type of MsgMessage @@ -1648,13 +1863,15 @@ func (msgMessage *MsgMessage) MessageType() string { // @param data // @param destination // @param publicKey -func NewMsgMessage(amount JSONInt64, data MsgData, destination *AccountAddress, publicKey string) *MsgMessage { +// @param sendMode +func NewMsgMessage(amount JSONInt64, data MsgData, destination *AccountAddress, publicKey string, sendMode int32) *MsgMessage { msgMessageTemp := MsgMessage{ tonCommon: tonCommon{Type: "msg.message"}, Amount: amount, Data: data, Destination: destination, PublicKey: publicKey, + SendMode: sendMode, } return &msgMessageTemp @@ -1896,6 +2113,142 @@ func NewDnsResolved(entries []DnsEntry) *DnsResolved { return &dnsResolvedTemp } +// PchanPromise +type PchanPromise struct { + tonCommon + ChannelId JSONInt64 `json:"channel_id"` // + PromiseA JSONInt64 `json:"promise_A"` // + PromiseB JSONInt64 `json:"promise_B"` // + Signature string `json:"signature"` // +} + +// MessageType return the string telegram-type of PchanPromise +func (pchanPromise *PchanPromise) MessageType() string { + return "pchan.promise" +} + +// NewPchanPromise creates a new PchanPromise +// +// @param channelId +// @param promiseA +// @param promiseB +// @param signature +func NewPchanPromise(channelId JSONInt64, promiseA JSONInt64, promiseB JSONInt64, signature string) *PchanPromise { + pchanPromiseTemp := PchanPromise{ + tonCommon: tonCommon{Type: "pchan.promise"}, + ChannelId: channelId, + PromiseA: promiseA, + PromiseB: promiseB, + Signature: signature, + } + + return &pchanPromiseTemp +} + +// PchanActionInit +type PchanActionInit struct { + tonCommon + IncA JSONInt64 `json:"inc_A"` // + IncB JSONInt64 `json:"inc_B"` // + MinA JSONInt64 `json:"min_A"` // + MinB JSONInt64 `json:"min_B"` // +} + +// MessageType return the string telegram-type of PchanActionInit +func (pchanActionInit *PchanActionInit) MessageType() string { + return "pchan.actionInit" +} + +// NewPchanActionInit creates a new PchanActionInit +// +// @param incA +// @param incB +// @param minA +// @param minB +func NewPchanActionInit(incA JSONInt64, incB JSONInt64, minA JSONInt64, minB JSONInt64) *PchanActionInit { + pchanActionInitTemp := PchanActionInit{ + tonCommon: tonCommon{Type: "pchan.actionInit"}, + IncA: incA, + IncB: incB, + MinA: minA, + MinB: minB, + } + + return &pchanActionInitTemp +} + +// PchanActionClose +type PchanActionClose struct { + tonCommon + ExtraA JSONInt64 `json:"extra_A"` // + ExtraB JSONInt64 `json:"extra_B"` // + Promise *PchanPromise `json:"promise"` // +} + +// MessageType return the string telegram-type of PchanActionClose +func (pchanActionClose *PchanActionClose) MessageType() string { + return "pchan.actionClose" +} + +// NewPchanActionClose creates a new PchanActionClose +// +// @param extraA +// @param extraB +// @param promise +func NewPchanActionClose(extraA JSONInt64, extraB JSONInt64, promise *PchanPromise) *PchanActionClose { + pchanActionCloseTemp := PchanActionClose{ + tonCommon: tonCommon{Type: "pchan.actionClose"}, + ExtraA: extraA, + ExtraB: extraB, + Promise: promise, + } + + return &pchanActionCloseTemp +} + +// PchanActionTimeout +type PchanActionTimeout struct { + tonCommon +} + +// MessageType return the string telegram-type of PchanActionTimeout +func (pchanActionTimeout *PchanActionTimeout) MessageType() string { + return "pchan.actionTimeout" +} + +// NewPchanActionTimeout creates a new PchanActionTimeout +// +func NewPchanActionTimeout() *PchanActionTimeout { + pchanActionTimeoutTemp := PchanActionTimeout{ + tonCommon: tonCommon{Type: "pchan.actionTimeout"}, + } + + return &pchanActionTimeoutTemp +} + +// RwalletActionInit +type RwalletActionInit struct { + tonCommon + Config *RwalletConfig `json:"config"` // +} + +// MessageType return the string telegram-type of RwalletActionInit +func (rwalletActionInit *RwalletActionInit) MessageType() string { + return "rwallet.actionInit" +} + +// NewRwalletActionInit creates a new RwalletActionInit +// +// @param config +func NewRwalletActionInit(config *RwalletConfig) *RwalletActionInit { + rwalletActionInitTemp := RwalletActionInit{ + tonCommon: tonCommon{Type: "rwallet.actionInit"}, + Config: config, + } + + return &rwalletActionInitTemp +} + // ActionNoop type ActionNoop struct { tonCommon @@ -1965,6 +2318,52 @@ func NewActionDns(actions []DnsAction) *ActionDns { return &actionDnsTemp } +// ActionPchan +type ActionPchan struct { + tonCommon + Action *PchanAction `json:"action"` // +} + +// MessageType return the string telegram-type of ActionPchan +func (actionPchan *ActionPchan) MessageType() string { + return "actionPchan" +} + +// NewActionPchan creates a new ActionPchan +// +// @param action +func NewActionPchan(action *PchanAction) *ActionPchan { + actionPchanTemp := ActionPchan{ + tonCommon: tonCommon{Type: "actionPchan"}, + Action: action, + } + + return &actionPchanTemp +} + +// ActionRwallet +type ActionRwallet struct { + tonCommon + Action *RwalletActionInit `json:"action"` // +} + +// MessageType return the string telegram-type of ActionRwallet +func (actionRwallet *ActionRwallet) MessageType() string { + return "actionRwallet" +} + +// NewActionRwallet creates a new ActionRwallet +// +// @param action +func NewActionRwallet(action *RwalletActionInit) *ActionRwallet { + actionRwalletTemp := ActionRwallet{ + tonCommon: tonCommon{Type: "actionRwallet"}, + Action: action, + } + + return &actionRwalletTemp +} + // Fees type Fees struct { tonCommon @@ -2026,8 +2425,10 @@ func NewQueryFees(destinationFees []Fees, sourceFees *Fees) *QueryFees { // QueryInfo type QueryInfo struct { tonCommon + Body string `json:"body"` // BodyHash string `json:"body_hash"` // Id int64 `json:"id"` // + InitState string `json:"init_state"` // ValidUntil int64 `json:"valid_until"` // } @@ -2038,14 +2439,18 @@ func (queryInfo *QueryInfo) MessageType() string { // NewQueryInfo creates a new QueryInfo // +// @param body // @param bodyHash // @param id +// @param initState // @param validUntil -func NewQueryInfo(bodyHash string, id int64, validUntil int64) *QueryInfo { +func NewQueryInfo(body string, bodyHash string, id int64, initState string, validUntil int64) *QueryInfo { queryInfoTemp := QueryInfo{ tonCommon: tonCommon{Type: "query.info"}, + Body: body, BodyHash: bodyHash, Id: id, + InitState: initState, ValidUntil: validUntil, } @@ -2628,6 +3033,219 @@ func NewLiteServerInfo(capabilities JSONInt64, now int64, version int32) *LiteSe return &liteServerInfoTemp } +// BlocksMasterchainInfo +type BlocksMasterchainInfo struct { + tonCommon + Init *TonBlockIdExt `json:"init"` // + Last *TonBlockIdExt `json:"last"` // + StateRootHash string `json:"state_root_hash"` // +} + +// MessageType return the string telegram-type of BlocksMasterchainInfo +func (blocksMasterchainInfo *BlocksMasterchainInfo) MessageType() string { + return "blocks.masterchainInfo" +} + +// NewBlocksMasterchainInfo creates a new BlocksMasterchainInfo +// +// @param init +// @param last +// @param stateRootHash +func NewBlocksMasterchainInfo(init *TonBlockIdExt, last *TonBlockIdExt, stateRootHash string) *BlocksMasterchainInfo { + blocksMasterchainInfoTemp := BlocksMasterchainInfo{ + tonCommon: tonCommon{Type: "blocks.masterchainInfo"}, + Init: init, + Last: last, + StateRootHash: stateRootHash, + } + + return &blocksMasterchainInfoTemp +} + +// BlocksShards +type BlocksShards struct { + tonCommon + Shards []TonBlockIdExt `json:"shards"` // +} + +// MessageType return the string telegram-type of BlocksShards +func (blocksShards *BlocksShards) MessageType() string { + return "blocks.shards" +} + +// NewBlocksShards creates a new BlocksShards +// +// @param shards +func NewBlocksShards(shards []TonBlockIdExt) *BlocksShards { + blocksShardsTemp := BlocksShards{ + tonCommon: tonCommon{Type: "blocks.shards"}, + Shards: shards, + } + + return &blocksShardsTemp +} + +// BlocksAccountTransactionId +type BlocksAccountTransactionId struct { + tonCommon + Account string `json:"account"` // + Lt JSONInt64 `json:"lt"` // +} + +// MessageType return the string telegram-type of BlocksAccountTransactionId +func (blocksAccountTransactionId *BlocksAccountTransactionId) MessageType() string { + return "blocks.accountTransactionId" +} + +// NewBlocksAccountTransactionId creates a new BlocksAccountTransactionId +// +// @param account +// @param lt +func NewBlocksAccountTransactionId(account string, lt JSONInt64) *BlocksAccountTransactionId { + blocksAccountTransactionIdTemp := BlocksAccountTransactionId{ + tonCommon: tonCommon{Type: "blocks.accountTransactionId"}, + Account: account, + Lt: lt, + } + + return &blocksAccountTransactionIdTemp +} + +// BlocksShortTxId +type BlocksShortTxId struct { + tonCommon + Account string `json:"account"` // + Hash string `json:"hash"` // + Lt JSONInt64 `json:"lt"` // + Mode int32 `json:"mode"` // +} + +// MessageType return the string telegram-type of BlocksShortTxId +func (blocksShortTxId *BlocksShortTxId) MessageType() string { + return "blocks.shortTxId" +} + +// NewBlocksShortTxId creates a new BlocksShortTxId +// +// @param account +// @param hash +// @param lt +// @param mode +func NewBlocksShortTxId(account string, hash string, lt JSONInt64, mode int32) *BlocksShortTxId { + blocksShortTxIdTemp := BlocksShortTxId{ + tonCommon: tonCommon{Type: "blocks.shortTxId"}, + Account: account, + Hash: hash, + Lt: lt, + Mode: mode, + } + + return &blocksShortTxIdTemp +} + +// BlocksTransactions +type BlocksTransactions struct { + tonCommon + Id *TonBlockIdExt `json:"id"` // + Incomplete bool `json:"incomplete"` // + ReqCount int32 `json:"req_count"` // + Transactions []BlocksShortTxId `json:"transactions"` // +} + +// MessageType return the string telegram-type of BlocksTransactions +func (blocksTransactions *BlocksTransactions) MessageType() string { + return "blocks.transactions" +} + +// NewBlocksTransactions creates a new BlocksTransactions +// +// @param id +// @param incomplete +// @param reqCount +// @param transactions +func NewBlocksTransactions(id *TonBlockIdExt, incomplete bool, reqCount int32, transactions []BlocksShortTxId) *BlocksTransactions { + blocksTransactionsTemp := BlocksTransactions{ + tonCommon: tonCommon{Type: "blocks.transactions"}, + Id: id, + Incomplete: incomplete, + ReqCount: reqCount, + Transactions: transactions, + } + + return &blocksTransactionsTemp +} + +// BlocksHeader +type BlocksHeader struct { + tonCommon + AfterMerge bool `json:"after_merge"` // + AfterSplit bool `json:"after_split"` // + BeforeSplit bool `json:"before_split"` // + CatchainSeqno int32 `json:"catchain_seqno"` // + EndLt JSONInt64 `json:"end_lt"` // + GlobalId int32 `json:"global_id"` // + Id *TonBlockIdExt `json:"id"` // + IsKeyBlock bool `json:"is_key_block"` // + MinRefMcSeqno int32 `json:"min_ref_mc_seqno"` // + PrevBlocks []TonBlockIdExt `json:"prev_blocks"` // + PrevKeyBlockSeqno int32 `json:"prev_key_block_seqno"` // + StartLt JSONInt64 `json:"start_lt"` // + ValidatorListHashShort int32 `json:"validator_list_hash_short"` // + Version int32 `json:"version"` // + VertSeqno int32 `json:"vert_seqno"` // + WantMerge bool `json:"want_merge"` // + WantSplit bool `json:"want_split"` // +} + +// MessageType return the string telegram-type of BlocksHeader +func (blocksHeader *BlocksHeader) MessageType() string { + return "blocks.header" +} + +// NewBlocksHeader creates a new BlocksHeader +// +// @param afterMerge +// @param afterSplit +// @param beforeSplit +// @param catchainSeqno +// @param endLt +// @param globalId +// @param id +// @param isKeyBlock +// @param minRefMcSeqno +// @param prevBlocks +// @param prevKeyBlockSeqno +// @param startLt +// @param validatorListHashShort +// @param version +// @param vertSeqno +// @param wantMerge +// @param wantSplit +func NewBlocksHeader(afterMerge bool, afterSplit bool, beforeSplit bool, catchainSeqno int32, endLt JSONInt64, globalId int32, id *TonBlockIdExt, isKeyBlock bool, minRefMcSeqno int32, prevBlocks []TonBlockIdExt, prevKeyBlockSeqno int32, startLt JSONInt64, validatorListHashShort int32, version int32, vertSeqno int32, wantMerge bool, wantSplit bool) *BlocksHeader { + blocksHeaderTemp := BlocksHeader{ + tonCommon: tonCommon{Type: "blocks.header"}, + AfterMerge: afterMerge, + AfterSplit: afterSplit, + BeforeSplit: beforeSplit, + CatchainSeqno: catchainSeqno, + EndLt: endLt, + GlobalId: globalId, + Id: id, + IsKeyBlock: isKeyBlock, + MinRefMcSeqno: minRefMcSeqno, + PrevBlocks: prevBlocks, + PrevKeyBlockSeqno: prevKeyBlockSeqno, + StartLt: startLt, + ValidatorListHashShort: validatorListHashShort, + Version: version, + VertSeqno: vertSeqno, + WantMerge: wantMerge, + WantSplit: wantSplit, + } + + return &blocksHeaderTemp +} + func unmarshalLogStream(rawMsg *json.RawMessage) (LogStream, error) { if rawMsg == nil { diff --git a/v2/tl/tonlib_api.tl b/v2/tl/tonlib_api.tl new file mode 100644 index 0000000..338f671 --- /dev/null +++ b/v2/tl/tonlib_api.tl @@ -0,0 +1,330 @@ +double ? = Double; +string ? = String; + +int32 = Int32; +int53 = Int53; +int64 = Int64; +bytes = Bytes; +secureString = SecureString; +secureBytes = SecureBytes; + +object ? = Object; +function ? = Function; + +boolFalse = Bool; +boolTrue = Bool; + +vector {t:Type} # [ t ] = Vector t; + +error code:int32 message:string = Error; +ok = Ok; + +keyStoreTypeDirectory directory:string = KeyStoreType; +keyStoreTypeInMemory = KeyStoreType; + +config config:string blockchain_name:string use_callbacks_for_network:Bool ignore_cache:Bool = Config; + +options config:config keystore_type:KeyStoreType = Options; +options.configInfo default_wallet_id:int64 default_rwallet_init_public_key:string = options.ConfigInfo; +options.info config_info:options.configInfo = options.Info; + +key public_key:string secret:secureBytes = Key; +inputKeyRegular key:key local_password:secureBytes = InputKey; +inputKeyFake = InputKey; +exportedKey word_list:vector = ExportedKey; +exportedPemKey pem:secureString = ExportedPemKey; +exportedEncryptedKey data:secureBytes = ExportedEncryptedKey; +exportedUnencryptedKey data:secureBytes = ExportedUnencryptedKey; + +bip39Hints words:vector = Bip39Hints; + +adnlAddress adnl_address:string = AdnlAddress; + +accountAddress account_address:string = AccountAddress; + +unpackedAccountAddress workchain_id:int32 bounceable:Bool testnet:Bool addr:bytes = UnpackedAccountAddress; + +internal.transactionId lt:int64 hash:bytes = internal.TransactionId; + +ton.blockId workchain:int32 shard:int64 seqno:int32 = internal.BlockId; +ton.blockIdExt workchain:int32 shard:int64 seqno:int32 root_hash:bytes file_hash:bytes = ton.BlockIdExt; + +raw.fullAccountState balance:int64 code:bytes data:bytes last_transaction_id:internal.transactionId block_id:ton.blockIdExt frozen_hash:bytes sync_utime:int53 = raw.FullAccountState; +raw.message source:accountAddress destination:accountAddress value:int64 fwd_fee:int64 ihr_fee:int64 created_lt:int64 body_hash:bytes msg_data:msg.Data = raw.Message; +raw.transaction 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; +raw.transactions transactions:vector previous_transaction_id:internal.transactionId = raw.Transactions; + +pchan.config alice_public_key:string alice_address:accountAddress bob_public_key:string bob_address:accountAddress init_timeout:int32 close_timeout:int32 channel_id:int64 = pchan.Config; + +raw.initialAccountState code:bytes data:bytes = InitialAccountState; +wallet.v3.initialAccountState public_key:string wallet_id:int64 = InitialAccountState; +wallet.highload.v1.initialAccountState public_key:string wallet_id:int64 = InitialAccountState; +wallet.highload.v2.initialAccountState public_key:string wallet_id:int64 = InitialAccountState; + +rwallet.limit seconds:int32 value:int64 = rwallet.Limit; +rwallet.config start_at:int53 limits:vector = rwallet.Config; +rwallet.initialAccountState init_public_key:string public_key:string wallet_id:int64 = InitialAccountState; + +dns.initialAccountState public_key:string wallet_id:int64 = InitialAccountState; +pchan.initialAccountState config:pchan.config = InitialAccountState; + +raw.accountState code:bytes data:bytes frozen_hash:bytes = AccountState; +wallet.v3.accountState wallet_id:int64 seqno:int32 = AccountState; +wallet.highload.v1.accountState wallet_id:int64 seqno:int32 = AccountState; +wallet.highload.v2.accountState wallet_id:int64 = AccountState; +dns.accountState wallet_id:int64 = AccountState; +rwallet.accountState wallet_id:int64 seqno:int32 unlocked_balance:int64 config:rwallet.config = AccountState; + +pchan.stateInit signed_A:Bool signed_B:Bool min_A:int64 min_B:int64 expire_at:int53 A:int64 B:int64 = pchan.State; +pchan.stateClose signed_A:Bool signed_B:Bool min_A:int64 min_B:int64 expire_at:int53 A:int64 B:int64 = pchan.State; +pchan.statePayout A:int64 B:int64 = pchan.State; + +pchan.accountState config:pchan.config state:pchan.State description:string = AccountState; +uninited.accountState frozen_hash:bytes = AccountState; + +fullAccountState address:accountAddress balance:int64 last_transaction_id:internal.transactionId block_id:ton.blockIdExt sync_utime:int53 account_state:AccountState revision:int32 = FullAccountState; + +accountRevisionList revisions:vector = AccountRevisionList; +accountList accounts:vector = AccountList; + +syncStateDone = SyncState; +syncStateInProgress from_seqno:int32 to_seqno:int32 current_seqno:int32 = SyncState; + +// +// MSG +// + +msg.dataRaw body:bytes init_state:bytes = msg.Data; +msg.dataText text:bytes = msg.Data; +msg.dataDecryptedText text:bytes = msg.Data; +msg.dataEncryptedText text:bytes = msg.Data; + +msg.dataEncrypted source:accountAddress data:msg.Data = msg.DataEncrypted; +msg.dataDecrypted proof:bytes data:msg.Data = msg.DataDecrypted; + +msg.dataEncryptedArray elements:vector = msg.DataEncryptedArray; +msg.dataDecryptedArray elements:vector = msg.DataDecryptedArray; + +msg.message destination:accountAddress public_key:string amount:int64 data:msg.Data send_mode:int32 = msg.Message; + +// +// DNS +// + +dns.entryDataUnknown bytes:bytes = dns.EntryData; +dns.entryDataText text:string = dns.EntryData; +dns.entryDataNextResolver resolver:AccountAddress = dns.EntryData; +dns.entryDataSmcAddress smc_address:AccountAddress = dns.EntryData; +dns.entryDataAdnlAddress adnl_address:AdnlAddress = dns.EntryData; + +dns.entry name:string category:int32 entry:dns.EntryData = dns.Entry; + +dns.actionDeleteAll = dns.Action; +// use category = 0 to delete all entries +dns.actionDelete name:string category:int32 = dns.Action; +dns.actionSet entry:dns.entry = dns.Action; + +dns.resolved entries:vector = dns.Resolved; + + +// +// Payment channel +// +pchan.promise signature:bytes promise_A:int64 promise_B:int64 channel_id:int64 = pchan.Promise; + +pchan.actionInit inc_A:int64 inc_B:int64 min_A:int64 min_B:int64 = pchan.Action; +pchan.actionClose extra_A:int64 extra_B:int64 promise:pchan.promise = pchan.Action; +pchan.actionTimeout = pchan.Action; + +// +// Restricted wallet initialization +// +rwallet.actionInit config:rwallet.config = rwallet.Action; + +// +// Actions +// + +actionNoop = Action; +actionMsg messages:vector allow_send_to_uninited:Bool = Action; +actionDns actions:vector = Action; +actionPchan action:pchan.Action = Action; +actionRwallet action:rwallet.actionInit = Action; +//actionMultisig actions:vector = Action; + +fees in_fwd_fee:int53 storage_fee:int53 gas_fee:int53 fwd_fee:int53 = Fees; +query.fees source_fees:fees destination_fees:vector = query.Fees; +// query.emulationResult exit_code:int32 fees:fees = query.EmulationResult; +query.info id:int53 valid_until:int53 body_hash:bytes body:bytes init_state:bytes = query.Info; + +tvm.slice bytes:bytes = tvm.Slice; +tvm.cell bytes:bytes = tvm.Cell; +tvm.numberDecimal number:string = tvm.Number; +tvm.tuple elements:vector = tvm.Tuple; +tvm.list elements:vector = tvm.List; + +tvm.stackEntrySlice slice:tvm.slice = tvm.StackEntry; +tvm.stackEntryCell cell:tvm.cell = tvm.StackEntry; +tvm.stackEntryNumber number:tvm.Number = tvm.StackEntry; +tvm.stackEntryTuple tuple:tvm.Tuple = tvm.StackEntry; +tvm.stackEntryList list:tvm.List = tvm.StackEntry; +tvm.stackEntryUnsupported = tvm.StackEntry; + +smc.info id:int53 = smc.Info; + +smc.methodIdNumber number:int32 = smc.MethodId; +smc.methodIdName name:string = smc.MethodId; + +smc.runResult gas_used:int53 stack:vector exit_code:int32 = smc.RunResult; + +updateSendLiteServerQuery id:int64 data:bytes = Update; +updateSyncState sync_state:SyncState = Update; + +//@class LogStream @description Describes a stream to which tonlib internal log is written + +//@description The log is written to stderr or an OS specific log +logStreamDefault = LogStream; + +//@description The log is written to a file @path Path to the file to where the internal tonlib log will be written @max_file_size Maximum size of the file to where the internal tonlib log is written before the file will be auto-rotated +logStreamFile path:string max_file_size:int53 = LogStream; + +//@description The log is written nowhere +logStreamEmpty = LogStream; + + +//@description Contains a tonlib internal log verbosity level @verbosity_level Log verbosity level +logVerbosityLevel verbosity_level:int32 = LogVerbosityLevel; + +//@description Contains a list of available tonlib internal log tags @tags List of log tags +logTags tags:vector = LogTags; + +data bytes:secureBytes = Data; + +liteServer.info now:int53 version:int32 capabilities:int64 = liteServer.Info; + + +blocks.masterchainInfo last:ton.BlockIdExt state_root_hash:bytes init:ton.BlockIdExt = blocks.MasterchainInfo; +blocks.shards shards:vector = blocks.Shards; +blocks.accountTransactionId account:bytes lt:int64 = blocks.AccountTransactionId; +blocks.shortTxId mode:int32 account:bytes lt:int64 hash:bytes = liteServer.TransactionId; +blocks.transactions id:ton.blockIdExt req_count:int32 incomplete:Bool transactions:vector = blocks.Transactions; +blocks.header id:ton.blockIdExt global_id:int32 version:int32 after_merge:Bool after_split:Bool before_split:Bool want_merge:Bool want_split:Bool validator_list_hash_short:int32 catchain_seqno:int32 min_ref_mc_seqno:int32 is_key_block:Bool prev_key_block_seqno:int32 start_lt:int64 end_lt:int64 vert_seqno:int32 prev_blocks:vector = blocks.Header; +//blocks.shortData header:blocks.Header transactions:blocks.Header = blocks.BlockData; +---functions--- + +init options:options = options.Info; +close = Ok; + +options.setConfig config:config = options.ConfigInfo; +options.validateConfig config:config = options.ConfigInfo; + +createNewKey local_password:secureBytes mnemonic_password:secureBytes random_extra_seed:secureBytes = Key; +deleteKey key:key = Ok; +deleteAllKeys = Ok; +exportKey input_key:InputKey = ExportedKey; +exportPemKey input_key:InputKey key_password:secureBytes = ExportedPemKey; +exportEncryptedKey input_key:InputKey key_password:secureBytes = ExportedEncryptedKey; +exportUnencryptedKey input_key:InputKey = ExportedUnencryptedKey; +importKey local_password:secureBytes mnemonic_password:secureBytes exported_key:exportedKey = Key; +importPemKey local_password:secureBytes key_password:secureBytes exported_key:exportedPemKey = Key; +importEncryptedKey local_password:secureBytes key_password:secureBytes exported_encrypted_key:exportedEncryptedKey = Key; +importUnencryptedKey local_password:secureBytes exported_unencrypted_key:exportedUnencryptedKey = Key; +changeLocalPassword input_key:InputKey new_local_password:secureBytes = Key; + +encrypt decrypted_data:secureBytes secret:secureBytes = Data; +decrypt encrypted_data:secureBytes secret:secureBytes = Data; +kdf password:secureBytes salt:secureBytes iterations:int32 = Data; + +unpackAccountAddress account_address:string = UnpackedAccountAddress; +packAccountAddress account_address:unpackedAccountAddress = AccountAddress; +getBip39Hints prefix:string = Bip39Hints; + +//raw.init initial_account_state:raw.initialAccountState = Ok; +raw.getAccountState account_address:accountAddress = raw.FullAccountState; +raw.getTransactions private_key:InputKey account_address:accountAddress from_transaction_id:internal.transactionId = raw.Transactions; +raw.sendMessage body:bytes = Ok; +raw.createAndSendMessage destination:accountAddress initial_account_state:bytes data:bytes = Ok; +raw.createQuery destination:accountAddress init_code:bytes init_data:bytes body:bytes = query.Info; + +sync = ton.BlockIdExt; + +// revision = 0 -- use default revision +// revision = x (x > 0) -- use revision x +// revision = -1 -- use experimental (newest) revision. Only for debug purpose +// +// workchain_id = -1 or 0. -1 for masterchain, 0 for basechain +// NB: use wallet_id = default_wallet_id + workchain_id +getAccountAddress initial_account_state:InitialAccountState revision:int32 workchain_id:int32 = AccountAddress; +guessAccountRevision initial_account_state:InitialAccountState workchain_id:int32 = AccountRevisionList; + +guessAccount public_key:string rwallet_init_public_key:string = AccountRevisionList; + +getAccountState account_address:accountAddress = FullAccountState; +createQuery private_key:InputKey address:accountAddress timeout:int32 action:Action initial_account_state:InitialAccountState = query.Info; + +msg.decrypt input_key:InputKey data:msg.dataEncryptedArray = msg.DataDecryptedArray; +msg.decryptWithProof proof:bytes data:msg.dataEncrypted = msg.Data; + +query.send id:int53 = Ok; +query.forget id:int53 = Ok; +query.estimateFees id:int53 ignore_chksig:Bool = query.Fees; +// query.emulate id:int53 ignore_chksig:Bool = query.EmulationResult; +query.getInfo id:int53 = query.Info; + +smc.load account_address:accountAddress = smc.Info; +//smc.forget id:int53 = Ok; +smc.getCode id:int53 = tvm.Cell; +smc.getData id:int53 = tvm.Cell; +smc.getState id:int53 = tvm.Cell; +smc.runGetMethod id:int53 method:smc.MethodId stack:vector = smc.RunResult; + +dns.resolve account_address:accountAddress name:string category:int32 ttl:int32 = dns.Resolved; + +pchan.signPromise input_key:InputKey promise:pchan.promise = pchan.Promise; +pchan.validatePromise public_key:bytes promise:pchan.promise = Ok; + +pchan.packPromise promise:pchan.promise = Data; +pchan.unpackPromise data:secureBytes = pchan.Promise; + + +blocks.getMasterchainInfo = blocks.MasterchainInfo; +blocks.getShards id:ton.blockIdExt = blocks.Shards; +blocks.lookupBlock mode:int32 id:ton.blockId lt:int64 utime:int32 = ton.BlockIdExt; +blocks.getTransactions id:ton.blockIdExt mode:int32 count:int32 after:blocks.accountTransactionId = blocks.Transactions; +blocks.getBlockHeader id:ton.blockIdExt = blocks.Header; + +onLiteServerQueryResult id:int64 bytes:bytes = Ok; +onLiteServerQueryError id:int64 error:error = Ok; + +withBlock id:ton.blockIdExt function:Function = Object; + +runTests dir:string = Ok; + +liteServer.getInfo = liteServer.Info; + +//@description Sets new log stream for internal logging of tonlib. This is an offline method. Can be called before authorization. Can be called synchronously @log_stream New log stream +setLogStream log_stream:LogStream = Ok; + +//@description Returns information about currently used log stream for internal logging of tonlib. This is an offline method. Can be called before authorization. Can be called synchronously +getLogStream = LogStream; + +//@description Sets the verbosity level of the internal logging of tonlib. This is an offline method. Can be called before authorization. Can be called synchronously +//@new_verbosity_level New value of the verbosity level for logging. Value 0 corresponds to fatal errors, value 1 corresponds to errors, value 2 corresponds to warnings and debug warnings, value 3 corresponds to informational, value 4 corresponds to debug, value 5 corresponds to verbose debug, value greater than 5 and up to 1023 can be used to enable even more logging +setLogVerbosityLevel new_verbosity_level:int32 = Ok; + +//@description Returns current verbosity level of the internal logging of tonlib. This is an offline method. Can be called before authorization. Can be called synchronously +getLogVerbosityLevel = LogVerbosityLevel; + +//@description Returns list of available tonlib internal log tags, for example, ["actor", "binlog", "connections", "notifications", "proxy"]. This is an offline method. Can be called before authorization. Can be called synchronously +getLogTags = LogTags; + +//@description Sets the verbosity level for a specified tonlib internal log tag. This is an offline method. Can be called before authorization. Can be called synchronously +//@tag Logging tag to change verbosity level @new_verbosity_level New verbosity level; 1-1024 +setLogTagVerbosityLevel tag:string new_verbosity_level:int32 = Ok; + +//@description Returns current verbosity level for a specified tonlib internal log tag. This is an offline method. Can be called before authorization. Can be called synchronously @tag Logging tag to change verbosity level +getLogTagVerbosityLevel tag:string = LogVerbosityLevel; + +//@description Adds a message to tonlib internal log. This is an offline method. Can be called before authorization. Can be called synchronously +//@verbosity_level Minimum verbosity level needed for the message to be logged, 0-1023 @text Text of a message to log +addLogMessage verbosity_level:int32 text:string = Ok; \ No newline at end of file diff --git a/v2/tonlib.config.json.example b/v2/tonlib.config.json.example index 1d1b33e..d0cc4d1 100644 --- a/v2/tonlib.config.json.example +++ b/v2/tonlib.config.json.example @@ -1,14 +1,190 @@ { "config": { "config": { - "liteservers": [{ - "ip": 1137658550, - "port": "4924", - "id": { - "@type": "pub.ed25519", - "key": "peJTw/arlRfssgTuf9BMypJzqOi7SXEqSPSWiEw2U1M=" - } - }], + "@type": "config.global", + "dht": { + "@type": "dht.config.global", + "k": 6, + "a": 3, + "static_nodes": { + "@type": "dht.nodes", + "nodes": [ + { + "@type": "dht.node", + "id": { + "@type": "pub.ed25519", + "key": "znOAvy1ECxyzeKishi4PdSO2edaVx78wynVyNKLBmQ8=" + }, + "addr_list": { + "@type": "adnl.addressList", + "addrs": [ + { + "@type": "adnl.address.udp", + "ip": -1068377703, + "port": 6302 + } + ], + "version": 0, + "reinit_date": 0, + "priority": 0, + "expire_at": 0 + }, + "version": -1, + "signature": "KLH17nNKmOk3carKwbsUcVBc4JZpdAUdUOMxe8FSyqnkOw/lolnltbylJcC+lvPpIV5ySI/Qx8UZdNRV/4HzCA==" + }, + { + "@type": "dht.node", + "id": { + "@type": "pub.ed25519", + "key": "Qjhv9rmeqXm0a+nYYhCJG1AH7C2TM6DAmyIM3FgO0Eo=" + }, + "addr_list": { + "@type": "adnl.addressList", + "addrs": [ + { + "@type": "adnl.address.udp", + "ip": -1057912003, + "port": 6302 + } + ], + "version": 0, + "reinit_date": 0, + "priority": 0, + "expire_at": 0 + }, + "version": -1, + "signature": "2Gw5eIsZR+SdbWCU139DCuBI8Rv8T9iUioxDkgV6/IjcCHf6hNz8WCyUsKd5l5P1NBs/kdaxUBIybINDpYXoCw==" + }, + { + "@type": "dht.node", + "id": { + "@type": "pub.ed25519", + "key": "2YsTRIu3aRYzZe8eoR8PK2N2ydHJyKllwKcLPk676d4=" + }, + "addr_list": { + "@type": "adnl.addressList", + "addrs": [ + { + "@type": "adnl.address.udp", + "ip": -1057911744, + "port": 6302 + } + ], + "version": 0, + "reinit_date": 0, + "priority": 0, + "expire_at": 0 + }, + "version": -1, + "signature": "9/TJsaj0wELvRKXVIrBdyZWjgLKhfSvl7v0Oqq/9p9MsU/t9iRuGcpAzHqQF4bQAWrN8j9ARwMumRata7dH8Bg==" + }, + { + "@type": "dht.node", + "id": { + "@type": "pub.ed25519", + "key": "SHrXmMEEUBGa51TWZwHSA+2RF4Vyavw51jgtnAz1ypU=" + }, + "addr_list": { + "@type": "adnl.addressList", + "addrs": [ + { + "@type": "adnl.address.udp", + "ip": -1057911148, + "port": 6302 + } + ], + "version": 0, + "reinit_date": 0, + "priority": 0, + "expire_at": 0 + }, + "version": -1, + "signature": "R4ku8+tvjKSLIGe18zWHBHDv1maQHD5tGbAUOgbldGpBvfqH+/b76XkJjJzDsjnCO/bpxwUZfcI1sM1h6vFJCQ==" + }, + { + "@type": "dht.node", + "id": { + "@type": "pub.ed25519", + "key": "G+Lr6UtSWUcyYHTUutwbxrIG9GGZan3h96j8qQPLIXQ=" + }, + "addr_list": { + "@type": "adnl.addressList", + "addrs": [ + { + "@type": "adnl.address.udp", + "ip": -960017601, + "port": 6302 + } + ], + "version": 0, + "reinit_date": 0, + "priority": 0, + "expire_at": 0 + }, + "version": -1, + "signature": "fWU9hSNLvmaSCQOBW9M4Lja5pIWcqOzU1g9vtSywdgtASj9oQpwAslvr2sjNh9E2Np1c26NW8Sc5gUKf8YY7BA==" + } + ] + } + }, + "liteservers": [ + { + "ip": 1137658550, + "port": "4924", + "id": { + "@type": "pub.ed25519", + "key": "peJTw/arlRfssgTuf9BMypJzqOi7SXEqSPSWiEw2U1M=" + } + }, + { + "ip": 1560268637, + "port": "6199", + "id": { + "@type": "pub.ed25519", + "key": "NSyVw0XhPhW4Yg5a3NhS1dkCc6ZY7Hex40tJ6EiBMAI=" + } + }, + { + "ip": 84478511, + "port": "19949", + "id": { + "@type": "pub.ed25519", + "key": "n4VDnSCUuSpjnCyUk9e3QOOd6o0ItSWYbTnW3Wnn8wk=" + } + }, + { + "ip": 84478479, + "port": "48014", + "id": { + "@type": "pub.ed25519", + "key": "3XO67K/qi+gu3T9v8G2hx1yNmWZhccL3O7SoosFo8G0=" + } + }, + { + "ip": -2018135749, + "port": "53312", + "id": { + "@type": "pub.ed25519", + "key": "aF91CuUHuuOv9rm2W5+O/4h38M3sRm40DtSdRxQhmtQ=" + } + }, + { + "ip": -2018145068, + "port": "13206", + "id": { + "@type": "pub.ed25519", + "key": "K0t3+IWLOXHYMvMcrGZDPs+pn58a17LFbnXoQkKc2xw=" + } + }, + { + "ip": -2018145059, + "port": "46995", + "id": { + "@type": "pub.ed25519", + "key": "wQE0MVhXNWUXpWiW5Bk8cAirIh5NNG3cZM1/fSVKIts=" + } + } + ], "validator": { "@type": "validator.config.global", "zero_state": { @@ -17,12 +193,28 @@ "seqno": 0, "root_hash": "F6OpKZKqvqeFp6CQmFomXNMfMj2EnaUSOXN+Mh+wVWk=", "file_hash": "XplPz01CXAps5qeSWUtxcyBfdAo5zVb1N979KLSKD24=" - } + }, + "init_block" : { + "root_hash": "irEt9whDfgaYwD+8AzBlYzrMZHhrkhSVp3PU1s4DOz4=", + "seqno": 10171687, + "file_hash": "lay/bUKUUFDJXU9S6gx9GACQFl+uK+zX8SqHWS9oLZc=", + "workchain": -1, + "shard": -9223372036854775808 + }, + "hardforks": [ + { + "file_hash": "t/9VBPODF7Zdh4nsnA49dprO69nQNMqYL+zk5bCjV/8=", + "seqno": 8536841, + "root_hash": "08Kpc9XxrMKC6BF/FeNHPS3MEL1/Vi/fQU/C9ELUrkc=", + "workchain": -1, + "shard": -9223372036854775808 + } + ] } }, - "blockchain_name": "my-chain", + "blockchain_name": "TON Mainnet", "use_callbacks_for_network": false, - "ignore_cache": false + "ignore_cache": true }, "keystore_type": { "@type": "keyStoreTypeDirectory", diff --git a/v2/utils.go b/v2/utils.go index 75cf58d..00d4890 100644 --- a/v2/utils.go +++ b/v2/utils.go @@ -2,9 +2,22 @@ package v2 import ( "encoding/json" + "errors" "io/ioutil" "math/big" "os" + "reflect" +) + +var ( + ErrorReflectStringFieldIsNotStruct = errors.New("reflectStringField error. Value is not struct") + ErrorReflectStringFieldIsNotString = errors.New("reflectStringField error. Type field is not string") + ErrorReflectStringFieldIsNotValid = errors.New("reflectStringField error. Type field is not valid") +) + +const ( + extraFieldName = "Extra" + typeFiledName = "Type" ) type TonlibConfigServer struct { @@ -19,11 +32,13 @@ type TonlibListenserverConfig struct { ID map[string]string `json:"id"` } type ValidatorConfig struct { - Type string `json:"@type"` - ZeroState ZeroState `json:"zero_state"` + Type string `json:"@type"` + ZeroState InitBlock `json:"zero_state"` + InitBlock InitBlock `json:"init_block,omitempty"` + Hardforks []InitBlock `json:"hardforks,omitempty"` } -type ZeroState struct { +type InitBlock struct { Workchain int `json:"workchain"` Shard int64 `json:"shard"` Seqno int `json:"seqno"` @@ -90,3 +105,29 @@ func fileExists(filename string) bool { } return !info.IsDir() } + +func getType(data interface{}) (string, error) { + return reflectStringField(data, typeFiledName) +} + +func getExtra(data interface{}) (string, error) { + return reflectStringField(data, extraFieldName) +} + +func reflectStringField(data interface{}, fieldName string) (string, error) { + ps := reflect.ValueOf(data) + if ps.Kind() != reflect.Struct { + return "", ErrorReflectStringFieldIsNotStruct + } + + f := ps.FieldByName(fieldName) + if f.Kind() != reflect.String { + return "", ErrorReflectStringFieldIsNotString + } + + if !f.IsValid() { + return "", ErrorReflectStringFieldIsNotValid + } + + return f.String(), nil +}