From c2cfa8e3d01ddf5d53764801a56ce9cc71b21ef7 Mon Sep 17 00:00:00 2001 From: Michael Vlasov Date: Mon, 21 Dec 2020 20:51:23 +0500 Subject: [PATCH 01/19] update versions and CHANGELOG.md --- ton_client/src/abi/errors.rs | 24 +- ton_client/src/boc/errors.rs | 10 +- ton_client/src/client/errors.rs | 68 +- ton_client/src/crypto/errors.rs | 40 +- ton_client/src/debot/errors.rs | 10 +- ton_client/src/debot/mod.rs | 30 +- ton_client/src/json_interface/modules.rs | 12 + ton_client/src/net/errors.rs | 23 +- ton_client/src/processing/errors.rs | 29 +- ton_client/src/tvm/errors.rs | 31 +- tools/api.json | 858 ++++++++++++++++++++++- 11 files changed, 982 insertions(+), 153 deletions(-) diff --git a/ton_client/src/abi/errors.rs b/ton_client/src/abi/errors.rs index 4ba7fc0bc..7584ff6f0 100644 --- a/ton_client/src/abi/errors.rs +++ b/ton_client/src/abi/errors.rs @@ -1,19 +1,19 @@ use crate::error::ClientError; use std::fmt::Display; -const ABI: isize = ClientError::ABI; // 200 +#[derive(ApiType)] pub enum ErrorCode { - RequiredAddressMissingForEncodeMessage = ABI + 1, - RequiredCallSetMissingForEncodeMessage = ABI + 2, - InvalidJson = ABI + 3, - InvalidMessage = ABI + 4, - EncodeDeployMessageFailed = ABI + 5, - EncodeRunMessageFailed = ABI + 6, - AttachSignatureFailed = ABI + 7, - InvalidTvcImage = ABI + 8, - RequiredPublicKeyMissingForFunctionHeader = ABI + 9, - InvalidSigner = ABI + 10, - InvalidAbi = ABI + 11, + RequiredAddressMissingForEncodeMessage = 301, + RequiredCallSetMissingForEncodeMessage = 302, + InvalidJson = 303, + InvalidMessage = 304, + EncodeDeployMessageFailed = 305, + EncodeRunMessageFailed = 306, + AttachSignatureFailed = 307, + InvalidTvcImage = 308, + RequiredPublicKeyMissingForFunctionHeader = 309, + InvalidSigner = 310, + InvalidAbi = 311, } pub struct Error; diff --git a/ton_client/src/boc/errors.rs b/ton_client/src/boc/errors.rs index 026025199..fabf43147 100644 --- a/ton_client/src/boc/errors.rs +++ b/ton_client/src/boc/errors.rs @@ -13,13 +13,13 @@ use crate::error::ClientError; use std::fmt::Display; -const BOC: isize = ClientError::BOC; // 200 +#[derive(ApiType)] pub enum ErrorCode { - InvalidBoc = BOC + 1, - SerializationError = BOC + 2, - InappropriateBlock = BOC + 3, - MissingSourceBoc = BOC + 4, + InvalidBoc = 201, + SerializationError = 202, + InappropriateBlock = 203, + MissingSourceBoc = 204, } pub struct Error; diff --git a/ton_client/src/client/errors.rs b/ton_client/src/client/errors.rs index 4a8d22844..09b929ad6 100644 --- a/ton_client/src/client/errors.rs +++ b/ton_client/src/client/errors.rs @@ -1,41 +1,41 @@ use crate::error::ClientError; use std::fmt::{Debug, Display}; -const CLIENT: isize = ClientError::CLIENT; // 0 +#[derive(ApiType)] pub enum ErrorCode { - NotImplemented = CLIENT + 1, - InvalidHex = CLIENT + 2, - InvalidBase64 = CLIENT + 3, - InvalidAddress = CLIENT + 4, - CallbackParamsCantBeConvertedToJson = CLIENT + 5, - WebsocketConnectError = CLIENT + 6, - WebsocketReceiveError = CLIENT + 7, - WebsocketSendError = CLIENT + 8, - HttpClientCreateError = CLIENT + 9, - HttpRequestCreateError = CLIENT + 10, - HttpRequestSendError = CLIENT + 11, - HttpRequestParseError = CLIENT + 12, - CallbackNotRegistered = CLIENT + 13, - NetModuleNotInit = CLIENT + 14, - InvalidConfig = CLIENT + 15, - CannotCreateRuntime = CLIENT + 16, - InvalidContextHandle = CLIENT + 17, - CannotSerializeResult = CLIENT + 18, - CannotSerializeError = CLIENT + 19, - CannotConvertJsValueToJson = CLIENT + 20, - CannotReceiveSpawnedResult = CLIENT + 21, - SetTimerError = CLIENT + 22, - InvalidParams = CLIENT + 23, - ContractsAddressConversionFailed = CLIENT + 24, - UnknownFunction = CLIENT + 25, - AppRequestError = CLIENT + 26, - NoSuchRequest = CLIENT + 27, - CanNotSendRequestResult = CLIENT + 28, - CanNotReceiveRequestResult = CLIENT + 29, - CanNotParseRequestResult = CLIENT + 30, - UnexpectedCallbackResponse = CLIENT + 31, - CanNotParseNumber = CLIENT + 32, - InternalError = CLIENT + 33, + NotImplemented = 1, + InvalidHex = 2, + InvalidBase64 = 3, + InvalidAddress = 4, + CallbackParamsCantBeConvertedToJson = 5, + WebsocketConnectError = 6, + WebsocketReceiveError = 7, + WebsocketSendError = 8, + HttpClientCreateError = 9, + HttpRequestCreateError = 10, + HttpRequestSendError = 11, + HttpRequestParseError = 12, + CallbackNotRegistered = 13, + NetModuleNotInit = 14, + InvalidConfig = 15, + CannotCreateRuntime = 16, + InvalidContextHandle = 17, + CannotSerializeResult = 18, + CannotSerializeError = 19, + CannotConvertJsValueToJson = 20, + CannotReceiveSpawnedResult = 21, + SetTimerError = 22, + InvalidParams = 23, + ContractsAddressConversionFailed = 24, + UnknownFunction = 25, + AppRequestError = 26, + NoSuchRequest = 27, + CanNotSendRequestResult = 28, + CanNotReceiveRequestResult = 29, + CanNotParseRequestResult = 30, + UnexpectedCallbackResponse = 31, + CanNotParseNumber = 32, + InternalError = 33, } pub struct Error; diff --git a/ton_client/src/crypto/errors.rs b/ton_client/src/crypto/errors.rs index c6fea23d6..a6699f6d4 100644 --- a/ton_client/src/crypto/errors.rs +++ b/ton_client/src/crypto/errors.rs @@ -1,27 +1,27 @@ use crate::error::ClientError; use std::fmt::Display; -const CRYPTO: isize = ClientError::CRYPTO; // 100 +#[derive(ApiType)] pub enum ErrorCode { - InvalidPublicKey = CRYPTO + 0, - InvalidSecretKey = CRYPTO + 1, - InvalidKey = CRYPTO + 2, - InvalidFactorizeChallenge = CRYPTO + 6, - InvalidBigInt = CRYPTO + 7, - ScryptFailed = CRYPTO + 8, - InvalidKeySize = CRYPTO + 9, - NaclSecretBoxFailed = CRYPTO + 10, - NaclBoxFailed = CRYPTO + 11, - NaclSignFailed = CRYPTO + 12, - Bip39InvalidEntropy = CRYPTO + 13, - Bip39InvalidPhrase = CRYPTO + 14, - Bip32InvalidKey = CRYPTO + 15, - Bip32InvalidDerivePath = CRYPTO + 16, - Bip39InvalidDictionary = CRYPTO + 17, - Bip39InvalidWordCount = CRYPTO + 18, - MnemonicGenerationFailed = CRYPTO + 19, - MnemonicFromEntropyFailed = CRYPTO + 20, - SigningBoxNotRegistered = CRYPTO + 21, + InvalidPublicKey = 100, + InvalidSecretKey = 101, + InvalidKey = 102, + InvalidFactorizeChallenge = 106, + InvalidBigInt = 107, + ScryptFailed = 108, + InvalidKeySize = 109, + NaclSecretBoxFailed = 110, + NaclBoxFailed = 111, + NaclSignFailed = 112, + Bip39InvalidEntropy = 113, + Bip39InvalidPhrase = 114, + Bip32InvalidKey = 115, + Bip32InvalidDerivePath = 116, + Bip39InvalidDictionary = 117, + Bip39InvalidWordCount = 118, + MnemonicGenerationFailed = 119, + MnemonicFromEntropyFailed = 120, + SigningBoxNotRegistered = 121, } pub struct Error; diff --git a/ton_client/src/debot/errors.rs b/ton_client/src/debot/errors.rs index 6169187f5..10fdaf13c 100644 --- a/ton_client/src/debot/errors.rs +++ b/ton_client/src/debot/errors.rs @@ -13,13 +13,13 @@ use crate::error::ClientError; use std::fmt::Display; -const DEBOT: isize = ClientError::DEBOT; // 800 +#[derive(ApiType)] pub enum ErrorCode { - DebotStartFailed = DEBOT + 1, - DebotFetchFailed, - DebotExecutionFailed, - DebotInvalidHandle, + DebotStartFailed = 801, + DebotFetchFailed = 802, + DebotExecutionFailed = 803, + DebotInvalidHandle = 804, } pub struct Error; diff --git a/ton_client/src/debot/mod.rs b/ton_client/src/debot/mod.rs index b34f00665..f750ea1bc 100644 --- a/ton_client/src/debot/mod.rs +++ b/ton_client/src/debot/mod.rs @@ -25,7 +25,7 @@ pub use action::DAction; pub use browser::BrowserCallbacks; pub use context::{DContext, STATE_EXIT, STATE_ZERO}; pub use dengine::DEngine; -pub use errors::Error; +pub use errors::{Error, ErrorCode}; use crate::error::ClientResult; use crate::ClientContext; @@ -42,12 +42,12 @@ pub struct DebotAction { /// A short action description. Should be used by Debot Browser as name of /// menu item. pub description: String, - /// Depends on action type. Can be a debot function name or a print string + /// Depends on action type. Can be a debot function name or a print string /// (for Print Action). pub name: String, /// Action type. pub action_type: u8, - /// ID of debot context to switch after action execution. + /// ID of debot context to switch after action execution. pub to: u8, /// Action attributes. In the form of "param=value,flag". /// attribute example: instant, args, fargs, sign. @@ -85,7 +85,7 @@ impl Into for DebotAction { /// [UNSTABLE](UNSTABLE.md) Parameters to start debot. #[derive(Serialize, Deserialize, Default, ApiType)] pub struct ParamsOfStart { - /// Debot smart contract address + /// Debot smart contract address address: String, } @@ -97,20 +97,20 @@ pub struct RegisteredDebot { } /// [UNSTABLE](UNSTABLE.md) Starts an instance of debot. -/// +/// /// Downloads debot smart contract from blockchain and switches it to /// context zero. /// Returns a debot handle which can be used later in `execute` function. /// This function must be used by Debot Browser to start a dialog with debot. /// While the function is executing, several Browser Callbacks can be called, /// since the debot tries to display all actions from the context 0 to the user. -/// +/// /// # Remarks /// `start` is equivalent to `fetch` + switch to context 0. -/// +/// /// When the debot starts SDK registers `BrowserCallbacks` AppObject. -/// Therefore when `debote.remove` is called the debot is being deleted and the callback is called -/// with `finish`=`true` which indicates that it will never be used again. +/// Therefore when `debote.remove` is called the debot is being deleted and the callback is called +/// with `finish`=`true` which indicates that it will never be used again. pub async fn start( context: Arc, params: ParamsOfStart, @@ -143,10 +143,10 @@ pub struct ParamsOfFetch { } /// [UNSTABLE](UNSTABLE.md) Fetches debot from blockchain. -/// -/// Downloads debot smart contract (code and data) from blockchain and creates +/// +/// Downloads debot smart contract (code and data) from blockchain and creates /// an instance of Debot Engine for it. -/// +/// /// # Remarks /// It does not switch debot to context 0. Browser Callbacks are not called. pub async fn fetch( @@ -183,10 +183,10 @@ pub struct ParamsOfExecute { } /// [UNSTABLE](UNSTABLE.md) Executes debot action. -/// +/// /// Calls debot engine referenced by debot handle to execute input action. /// Calls Debot Browser Callbacks if needed. -/// +/// /// # Remarks /// Chain of actions can be executed if input action generates a list of subactions. #[api_function] @@ -204,7 +204,7 @@ pub async fn execute( } /// [UNSTABLE](UNSTABLE.md) Destroys debot handle. -/// +/// /// Removes handle from Client Context and drops debot engine referenced by that handle. #[api_function] pub fn remove( diff --git a/ton_client/src/json_interface/modules.rs b/ton_client/src/json_interface/modules.rs index c746c1e78..43041c8ab 100644 --- a/ton_client/src/json_interface/modules.rs +++ b/ton_client/src/json_interface/modules.rs @@ -22,6 +22,7 @@ pub(crate) struct ClientModule; fn register_client(handlers: &mut RuntimeHandlers) { let mut module = ModuleReg::new::(handlers); + module.register_type::(); module.register_type::(); module.register_type::(); module.register_type::(); @@ -52,6 +53,7 @@ pub(crate) struct CryptoModule; fn register_crypto(handlers: &mut RuntimeHandlers) { let mut module = ModuleReg::new::(handlers); + module.register_type::(); module.register_type::(); // Math @@ -221,6 +223,7 @@ pub(crate) struct AbiModule; fn register_abi(handlers: &mut RuntimeHandlers) { let mut module = ModuleReg::new::(handlers); + module.register_type::(); module.register_type::(); module.register_type::(); module.register_type::(); @@ -275,6 +278,7 @@ pub(crate) struct BocModule; fn register_boc(handlers: &mut RuntimeHandlers) { let mut module = ModuleReg::new::(handlers); + module.register_type::(); module.register_sync_fn( crate::boc::parse_message, crate::boc::parse::parse_message_api, @@ -308,6 +312,8 @@ pub(crate) struct NetModule; fn register_net(handlers: &mut RuntimeHandlers) { let mut module = ModuleReg::new::(handlers); + module.register_type::(); + module.register_type::(); module.register_type::(); @@ -347,6 +353,8 @@ pub struct ProcessingModule; fn register_processing(handlers: &mut RuntimeHandlers) { let mut module = ModuleReg::new::(handlers); + module.register_type::(); + module.register_type::(); module.register_type::(); module.register_type::(); @@ -372,6 +380,8 @@ pub struct TvmModule; fn register_tvm(handlers: &mut RuntimeHandlers) { let mut module = ModuleReg::new::(handlers); + module.register_type::(); + module.register_type::(); module.register_type::(); module.register_type::(); @@ -406,6 +416,8 @@ pub struct DebotModule; fn register_debot(handlers: &mut RuntimeHandlers) { let mut module = ModuleReg::new::(handlers); + module.register_type::(); + module.register_type::(); module.register_type::(); module.register_type::(); diff --git a/ton_client/src/net/errors.rs b/ton_client/src/net/errors.rs index 16f76106c..2d542f5ad 100644 --- a/ton_client/src/net/errors.rs +++ b/ton_client/src/net/errors.rs @@ -2,19 +2,18 @@ use crate::error::ClientError; use serde_json::Value; use std::fmt::Display; -const NET: isize = ClientError::NET; // 600 - +#[derive(ApiType)] pub enum ErrorCode { - QueryFailed = NET + 1, - SubscribeFailed = NET + 2, - WaitForFailed = NET + 3, - GetSubscriptionResultFailed = NET + 4, - InvalidServerResponse = NET + 5, - ClockOutOfSync = NET + 6, - WaitForTimeout = NET + 7, - GraphqlError = NET + 8, - NetworkModuleSuspended = NET + 9, - WebsocketDisconnected = NET + 10, + QueryFailed = 601, + SubscribeFailed = 602, + WaitForFailed = 603, + GetSubscriptionResultFailed = 604, + InvalidServerResponse = 605, + ClockOutOfSync = 606, + WaitForTimeout = 607, + GraphqlError = 608, + NetworkModuleSuspended = 609, + WebsocketDisconnected = 610, } pub struct Error; diff --git a/ton_client/src/processing/errors.rs b/ton_client/src/processing/errors.rs index 6108aa17b..697f4242a 100644 --- a/ton_client/src/processing/errors.rs +++ b/ton_client/src/processing/errors.rs @@ -16,22 +16,21 @@ use crate::error::ClientError; use chrono::TimeZone; use serde_json::Value; -const PROCESSING: isize = ClientError::PROCESSING; // 500 - +#[derive(ApiType)] pub enum ErrorCode { - MessageAlreadyExpired = PROCESSING + 1, - MessageHasNotDestinationAddress = PROCESSING + 2, - CanNotBuildMessageCell = PROCESSING + 3, - FetchBlockFailed = PROCESSING + 4, - SendMessageFailed = PROCESSING + 5, - InvalidMessageBoc = PROCESSING + 6, - MessageExpired = PROCESSING + 7, - TransactionWaitTimeout = PROCESSING + 8, - InvalidBlockReceived = PROCESSING + 9, - CanNotCheckBlockShard = PROCESSING + 10, - BlockNotFound = PROCESSING + 11, - InvalidData = PROCESSING + 12, - ExternalSignerMustNotBeUsed = PROCESSING + 13, + MessageAlreadyExpired = 501, + MessageHasNotDestinationAddress = 502, + CanNotBuildMessageCell = 503, + FetchBlockFailed = 504, + SendMessageFailed = 505, + InvalidMessageBoc = 506, + MessageExpired = 507, + TransactionWaitTimeout = 508, + InvalidBlockReceived = 509, + CanNotCheckBlockShard = 510, + BlockNotFound = 511, + InvalidData = 512, + ExternalSignerMustNotBeUsed = 513, } pub struct Error; diff --git a/ton_client/src/tvm/errors.rs b/ton_client/src/tvm/errors.rs index 5cc69c6fe..d7c12621f 100644 --- a/ton_client/src/tvm/errors.rs +++ b/ton_client/src/tvm/errors.rs @@ -17,23 +17,22 @@ use std::fmt::Display; use ton_block::{AccStatusChange, ComputeSkipReason, MsgAddressInt}; use ton_types::ExceptionCode; -const TVM: isize = ClientError::TVM; // 400 - +#[derive(ApiType)] pub enum ErrorCode { - CanNotReadTransaction = TVM + 1, - CanNotReadBlockchainConfig = TVM + 2, - TransactionAborted = TVM + 3, - InternalError = TVM + 4, - ActionPhaseFailed = TVM + 5, - AccountCodeMissing = TVM + 6, - LowBalance = TVM + 7, - AccountFrozenOrDeleted = TVM + 8, - AccountMissing = TVM + 9, - UnknownExecutionError = TVM + 10, - InvalidInputStack = TVM + 11, - InvalidAccountBoc = TVM + 12, - InvalidMessageType = TVM + 13, - ContractExecutionError = TVM + 14, + CanNotReadTransaction = 401, + CanNotReadBlockchainConfig = 402, + TransactionAborted = 403, + InternalError = 404, + ActionPhaseFailed = 405, + AccountCodeMissing = 406, + LowBalance = 407, + AccountFrozenOrDeleted = 408, + AccountMissing = 409, + UnknownExecutionError = 410, + InvalidInputStack = 411, + InvalidAccountBoc = 412, + InvalidMessageType = 413, + ContractExecutionError = 414, } pub struct Error; diff --git a/tools/api.json b/tools/api.json index 22fc75f0a..67677b070 100644 --- a/tools/api.json +++ b/tools/api.json @@ -6,6 +6,245 @@ "summary": "Provides information about library.", "description": null, "types": [ + { + "name": "ErrorCode", + "type": "EnumOfConsts", + "enum_consts": [ + { + "name": "NotImplemented", + "type": "Number", + "value": "1", + "summary": null, + "description": null + }, + { + "name": "InvalidHex", + "type": "Number", + "value": "2", + "summary": null, + "description": null + }, + { + "name": "InvalidBase64", + "type": "Number", + "value": "3", + "summary": null, + "description": null + }, + { + "name": "InvalidAddress", + "type": "Number", + "value": "4", + "summary": null, + "description": null + }, + { + "name": "CallbackParamsCantBeConvertedToJson", + "type": "Number", + "value": "5", + "summary": null, + "description": null + }, + { + "name": "WebsocketConnectError", + "type": "Number", + "value": "6", + "summary": null, + "description": null + }, + { + "name": "WebsocketReceiveError", + "type": "Number", + "value": "7", + "summary": null, + "description": null + }, + { + "name": "WebsocketSendError", + "type": "Number", + "value": "8", + "summary": null, + "description": null + }, + { + "name": "HttpClientCreateError", + "type": "Number", + "value": "9", + "summary": null, + "description": null + }, + { + "name": "HttpRequestCreateError", + "type": "Number", + "value": "10", + "summary": null, + "description": null + }, + { + "name": "HttpRequestSendError", + "type": "Number", + "value": "11", + "summary": null, + "description": null + }, + { + "name": "HttpRequestParseError", + "type": "Number", + "value": "12", + "summary": null, + "description": null + }, + { + "name": "CallbackNotRegistered", + "type": "Number", + "value": "13", + "summary": null, + "description": null + }, + { + "name": "NetModuleNotInit", + "type": "Number", + "value": "14", + "summary": null, + "description": null + }, + { + "name": "InvalidConfig", + "type": "Number", + "value": "15", + "summary": null, + "description": null + }, + { + "name": "CannotCreateRuntime", + "type": "Number", + "value": "16", + "summary": null, + "description": null + }, + { + "name": "InvalidContextHandle", + "type": "Number", + "value": "17", + "summary": null, + "description": null + }, + { + "name": "CannotSerializeResult", + "type": "Number", + "value": "18", + "summary": null, + "description": null + }, + { + "name": "CannotSerializeError", + "type": "Number", + "value": "19", + "summary": null, + "description": null + }, + { + "name": "CannotConvertJsValueToJson", + "type": "Number", + "value": "20", + "summary": null, + "description": null + }, + { + "name": "CannotReceiveSpawnedResult", + "type": "Number", + "value": "21", + "summary": null, + "description": null + }, + { + "name": "SetTimerError", + "type": "Number", + "value": "22", + "summary": null, + "description": null + }, + { + "name": "InvalidParams", + "type": "Number", + "value": "23", + "summary": null, + "description": null + }, + { + "name": "ContractsAddressConversionFailed", + "type": "Number", + "value": "24", + "summary": null, + "description": null + }, + { + "name": "UnknownFunction", + "type": "Number", + "value": "25", + "summary": null, + "description": null + }, + { + "name": "AppRequestError", + "type": "Number", + "value": "26", + "summary": null, + "description": null + }, + { + "name": "NoSuchRequest", + "type": "Number", + "value": "27", + "summary": null, + "description": null + }, + { + "name": "CanNotSendRequestResult", + "type": "Number", + "value": "28", + "summary": null, + "description": null + }, + { + "name": "CanNotReceiveRequestResult", + "type": "Number", + "value": "29", + "summary": null, + "description": null + }, + { + "name": "CanNotParseRequestResult", + "type": "Number", + "value": "30", + "summary": null, + "description": null + }, + { + "name": "UnexpectedCallbackResponse", + "type": "Number", + "value": "31", + "summary": null, + "description": null + }, + { + "name": "CanNotParseNumber", + "type": "Number", + "value": "32", + "summary": null, + "description": null + }, + { + "name": "InternalError", + "type": "Number", + "value": "33", + "summary": null, + "description": null + } + ], + "summary": null, + "description": null + }, { "name": "ClientError", "type": "Struct", @@ -528,6 +767,147 @@ "summary": "Crypto functions.", "description": null, "types": [ + { + "name": "ErrorCode", + "type": "EnumOfConsts", + "enum_consts": [ + { + "name": "InvalidPublicKey", + "type": "Number", + "value": "100", + "summary": null, + "description": null + }, + { + "name": "InvalidSecretKey", + "type": "Number", + "value": "101", + "summary": null, + "description": null + }, + { + "name": "InvalidKey", + "type": "Number", + "value": "102", + "summary": null, + "description": null + }, + { + "name": "InvalidFactorizeChallenge", + "type": "Number", + "value": "106", + "summary": null, + "description": null + }, + { + "name": "InvalidBigInt", + "type": "Number", + "value": "107", + "summary": null, + "description": null + }, + { + "name": "ScryptFailed", + "type": "Number", + "value": "108", + "summary": null, + "description": null + }, + { + "name": "InvalidKeySize", + "type": "Number", + "value": "109", + "summary": null, + "description": null + }, + { + "name": "NaclSecretBoxFailed", + "type": "Number", + "value": "110", + "summary": null, + "description": null + }, + { + "name": "NaclBoxFailed", + "type": "Number", + "value": "111", + "summary": null, + "description": null + }, + { + "name": "NaclSignFailed", + "type": "Number", + "value": "112", + "summary": null, + "description": null + }, + { + "name": "Bip39InvalidEntropy", + "type": "Number", + "value": "113", + "summary": null, + "description": null + }, + { + "name": "Bip39InvalidPhrase", + "type": "Number", + "value": "114", + "summary": null, + "description": null + }, + { + "name": "Bip32InvalidKey", + "type": "Number", + "value": "115", + "summary": null, + "description": null + }, + { + "name": "Bip32InvalidDerivePath", + "type": "Number", + "value": "116", + "summary": null, + "description": null + }, + { + "name": "Bip39InvalidDictionary", + "type": "Number", + "value": "117", + "summary": null, + "description": null + }, + { + "name": "Bip39InvalidWordCount", + "type": "Number", + "value": "118", + "summary": null, + "description": null + }, + { + "name": "MnemonicGenerationFailed", + "type": "Number", + "value": "119", + "summary": null, + "description": null + }, + { + "name": "MnemonicFromEntropyFailed", + "type": "Number", + "value": "120", + "summary": null, + "description": null + }, + { + "name": "SigningBoxNotRegistered", + "type": "Number", + "value": "121", + "summary": null, + "description": null + } + ], + "summary": null, + "description": null + }, { "name": "SigningBoxHandle", "type": "Number", @@ -3121,6 +3501,91 @@ "summary": "Provides message encoding and decoding according to the ABI specification.", "description": null, "types": [ + { + "name": "ErrorCode", + "type": "EnumOfConsts", + "enum_consts": [ + { + "name": "RequiredAddressMissingForEncodeMessage", + "type": "Number", + "value": "301", + "summary": null, + "description": null + }, + { + "name": "RequiredCallSetMissingForEncodeMessage", + "type": "Number", + "value": "302", + "summary": null, + "description": null + }, + { + "name": "InvalidJson", + "type": "Number", + "value": "303", + "summary": null, + "description": null + }, + { + "name": "InvalidMessage", + "type": "Number", + "value": "304", + "summary": null, + "description": null + }, + { + "name": "EncodeDeployMessageFailed", + "type": "Number", + "value": "305", + "summary": null, + "description": null + }, + { + "name": "EncodeRunMessageFailed", + "type": "Number", + "value": "306", + "summary": null, + "description": null + }, + { + "name": "AttachSignatureFailed", + "type": "Number", + "value": "307", + "summary": null, + "description": null + }, + { + "name": "InvalidTvcImage", + "type": "Number", + "value": "308", + "summary": null, + "description": null + }, + { + "name": "RequiredPublicKeyMissingForFunctionHeader", + "type": "Number", + "value": "309", + "summary": null, + "description": null + }, + { + "name": "InvalidSigner", + "type": "Number", + "value": "310", + "summary": null, + "description": null + }, + { + "name": "InvalidAbi", + "type": "Number", + "value": "311", + "summary": null, + "description": null + } + ], + "summary": null, + "description": null + }, { "name": "Abi", "type": "EnumOfTypes", @@ -4457,25 +4922,61 @@ "description": null } ], - "result": { - "type": "Generic", - "generic_name": "ClientResult", - "generic_args": [ - { - "type": "Ref", - "ref_name": "abi.ResultOfEncodeAccount" - } - ] - }, - "errors": null - } - ] - }, - { - "name": "boc", - "summary": "BOC manipulation module.", - "description": null, - "types": [ + "result": { + "type": "Generic", + "generic_name": "ClientResult", + "generic_args": [ + { + "type": "Ref", + "ref_name": "abi.ResultOfEncodeAccount" + } + ] + }, + "errors": null + } + ] + }, + { + "name": "boc", + "summary": "BOC manipulation module.", + "description": null, + "types": [ + { + "name": "ErrorCode", + "type": "EnumOfConsts", + "enum_consts": [ + { + "name": "InvalidBoc", + "type": "Number", + "value": "201", + "summary": null, + "description": null + }, + { + "name": "SerializationError", + "type": "Number", + "value": "202", + "summary": null, + "description": null + }, + { + "name": "InappropriateBlock", + "type": "Number", + "value": "203", + "summary": null, + "description": null + }, + { + "name": "MissingSourceBoc", + "type": "Number", + "value": "204", + "summary": null, + "description": null + } + ], + "summary": null, + "description": null + }, { "name": "ParamsOfParse", "type": "Struct", @@ -4930,6 +5431,105 @@ "summary": "Message processing module.", "description": "This module incorporates functions related to complex message\nprocessing scenarios.", "types": [ + { + "name": "ErrorCode", + "type": "EnumOfConsts", + "enum_consts": [ + { + "name": "MessageAlreadyExpired", + "type": "Number", + "value": "501", + "summary": null, + "description": null + }, + { + "name": "MessageHasNotDestinationAddress", + "type": "Number", + "value": "502", + "summary": null, + "description": null + }, + { + "name": "CanNotBuildMessageCell", + "type": "Number", + "value": "503", + "summary": null, + "description": null + }, + { + "name": "FetchBlockFailed", + "type": "Number", + "value": "504", + "summary": null, + "description": null + }, + { + "name": "SendMessageFailed", + "type": "Number", + "value": "505", + "summary": null, + "description": null + }, + { + "name": "InvalidMessageBoc", + "type": "Number", + "value": "506", + "summary": null, + "description": null + }, + { + "name": "MessageExpired", + "type": "Number", + "value": "507", + "summary": null, + "description": null + }, + { + "name": "TransactionWaitTimeout", + "type": "Number", + "value": "508", + "summary": null, + "description": null + }, + { + "name": "InvalidBlockReceived", + "type": "Number", + "value": "509", + "summary": null, + "description": null + }, + { + "name": "CanNotCheckBlockShard", + "type": "Number", + "value": "510", + "summary": null, + "description": null + }, + { + "name": "BlockNotFound", + "type": "Number", + "value": "511", + "summary": null, + "description": null + }, + { + "name": "InvalidData", + "type": "Number", + "value": "512", + "summary": null, + "description": null + }, + { + "name": "ExternalSignerMustNotBeUsed", + "type": "Number", + "value": "513", + "summary": null, + "description": null + } + ], + "summary": null, + "description": null + }, { "name": "ProcessingEvent", "type": "EnumOfTypes", @@ -5596,6 +6196,112 @@ "summary": null, "description": null, "types": [ + { + "name": "ErrorCode", + "type": "EnumOfConsts", + "enum_consts": [ + { + "name": "CanNotReadTransaction", + "type": "Number", + "value": "401", + "summary": null, + "description": null + }, + { + "name": "CanNotReadBlockchainConfig", + "type": "Number", + "value": "402", + "summary": null, + "description": null + }, + { + "name": "TransactionAborted", + "type": "Number", + "value": "403", + "summary": null, + "description": null + }, + { + "name": "InternalError", + "type": "Number", + "value": "404", + "summary": null, + "description": null + }, + { + "name": "ActionPhaseFailed", + "type": "Number", + "value": "405", + "summary": null, + "description": null + }, + { + "name": "AccountCodeMissing", + "type": "Number", + "value": "406", + "summary": null, + "description": null + }, + { + "name": "LowBalance", + "type": "Number", + "value": "407", + "summary": null, + "description": null + }, + { + "name": "AccountFrozenOrDeleted", + "type": "Number", + "value": "408", + "summary": null, + "description": null + }, + { + "name": "AccountMissing", + "type": "Number", + "value": "409", + "summary": null, + "description": null + }, + { + "name": "UnknownExecutionError", + "type": "Number", + "value": "410", + "summary": null, + "description": null + }, + { + "name": "InvalidInputStack", + "type": "Number", + "value": "411", + "summary": null, + "description": null + }, + { + "name": "InvalidAccountBoc", + "type": "Number", + "value": "412", + "summary": null, + "description": null + }, + { + "name": "InvalidMessageType", + "type": "Number", + "value": "413", + "summary": null, + "description": null + }, + { + "name": "ContractExecutionError", + "type": "Number", + "value": "414", + "summary": null, + "description": null + } + ], + "summary": null, + "description": null + }, { "name": "ExecutionOptions", "type": "Struct", @@ -6095,6 +6801,84 @@ "summary": "Network access.", "description": null, "types": [ + { + "name": "ErrorCode", + "type": "EnumOfConsts", + "enum_consts": [ + { + "name": "QueryFailed", + "type": "Number", + "value": "601", + "summary": null, + "description": null + }, + { + "name": "SubscribeFailed", + "type": "Number", + "value": "602", + "summary": null, + "description": null + }, + { + "name": "WaitForFailed", + "type": "Number", + "value": "603", + "summary": null, + "description": null + }, + { + "name": "GetSubscriptionResultFailed", + "type": "Number", + "value": "604", + "summary": null, + "description": null + }, + { + "name": "InvalidServerResponse", + "type": "Number", + "value": "605", + "summary": null, + "description": null + }, + { + "name": "ClockOutOfSync", + "type": "Number", + "value": "606", + "summary": null, + "description": null + }, + { + "name": "WaitForTimeout", + "type": "Number", + "value": "607", + "summary": null, + "description": null + }, + { + "name": "GraphqlError", + "type": "Number", + "value": "608", + "summary": null, + "description": null + }, + { + "name": "NetworkModuleSuspended", + "type": "Number", + "value": "609", + "summary": null, + "description": null + }, + { + "name": "WebsocketDisconnected", + "type": "Number", + "value": "610", + "summary": null, + "description": null + } + ], + "summary": null, + "description": null + }, { "name": "OrderBy", "type": "Struct", @@ -6686,6 +7470,42 @@ "summary": "[UNSTABLE](UNSTABLE.md) Module for working with debot.", "description": null, "types": [ + { + "name": "ErrorCode", + "type": "EnumOfConsts", + "enum_consts": [ + { + "name": "DebotStartFailed", + "type": "Number", + "value": "801", + "summary": null, + "description": null + }, + { + "name": "DebotFetchFailed", + "type": "Number", + "value": "802", + "summary": null, + "description": null + }, + { + "name": "DebotExecutionFailed", + "type": "Number", + "value": "803", + "summary": null, + "description": null + }, + { + "name": "DebotInvalidHandle", + "type": "Number", + "value": "804", + "summary": null, + "description": null + } + ], + "summary": null, + "description": null + }, { "name": "DebotHandle", "type": "Number", From 42b537153e0edb5cc68181e0f15be261672658e8 Mon Sep 17 00:00:00 2001 From: Michael Vlasov Date: Tue, 22 Dec 2020 12:51:03 +0500 Subject: [PATCH 02/19] FIX: move `fuse` out of the loop. --- CHANGELOG.md | 1 + docs/mod_abi.md | 21 ++++++++++++ docs/mod_boc.md | 62 ++++++++++++++++++++++++++++++++++ docs/mod_client.md | 43 ++++++++++++++++++++++++ docs/mod_crypto.md | 49 +++++++++++++++++++++++++-- docs/mod_debot.md | 21 ++++++++++++ docs/mod_net.md | 68 +++++++++++++++++++++++++++++++++++++ docs/mod_processing.md | 23 +++++++++++++ docs/mod_tvm.md | 76 ++++++++++++++++++++++++++++++++++++++---- docs/modules.md | 16 +++++---- 10 files changed, 365 insertions(+), 15 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index dbbdf1e8a..fdbadda6d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ All notable changes to this project will be documented in this file. - `tonclient-core-version` http header. - `net.find_last_shard_block` function returning account shard last block ID. - `boc.get_code_from_tvc` function extracting contract code from TVC image. +- `ErrorCode` type in each module spec in `api.json`. - **Debot Module:** - Add new variant `ParamsOfAppDebotBrowser::SwitchCompleted` to notify browser when all context actions are shown. - Added new 3 engine routines for crypto operations and 1 routine for querying account state (balance, state type, code, data) that can be used in debots. diff --git a/docs/mod_abi.md b/docs/mod_abi.md index d0d0e6985..f584305df 100644 --- a/docs/mod_abi.md +++ b/docs/mod_abi.md @@ -17,6 +17,8 @@ null [encode_account](#encode_account) – Creates account state BOC ## Types +[ErrorCode](#ErrorCode) + [Abi](#Abi) [AbiHandle](#AbiHandle) @@ -346,6 +348,25 @@ function encode_account( # Types +## ErrorCode +```ts +type ErrorCode = 301 | 302 | 303 | 304 | 305 | 306 | 307 | 308 | 309 | 310 | 311; +``` +One of the following value: + +- `301` +- `302` +- `303` +- `304` +- `305` +- `306` +- `307` +- `308` +- `309` +- `310` +- `311` + + ## Abi ```ts type Abi = { diff --git a/docs/mod_boc.md b/docs/mod_boc.md index f3c063e7e..8c9a23e74 100644 --- a/docs/mod_boc.md +++ b/docs/mod_boc.md @@ -16,7 +16,11 @@ null [get_boc_hash](#get_boc_hash) – Calculates BOC root hash +[get_code_from_tvc](#get_code_from_tvc) – Extracts code from TVC contract image + ## Types +[ErrorCode](#ErrorCode) + [ParamsOfParse](#ParamsOfParse) [ResultOfParse](#ResultOfParse) @@ -31,6 +35,10 @@ null [ResultOfGetBocHash](#ResultOfGetBocHash) +[ParamsOfGetCodeFromTvc](#ParamsOfGetCodeFromTvc) + +[ResultOfGetCodeFromTvc](#ResultOfGetCodeFromTvc) + # Functions ## parse_message @@ -213,7 +221,43 @@ function get_boc_hash( - `hash`: _string_ – BOC root hash encoded with hex +## get_code_from_tvc + +Extracts code from TVC contract image + +```ts +type ParamsOfGetCodeFromTvc = { + tvc: string +}; + +type ResultOfGetCodeFromTvc = { + code: string +}; + +function get_code_from_tvc( + params: ParamsOfGetCodeFromTvc, +): Promise; +``` +### Parameters +- `tvc`: _string_ – Contract TVC image encoded as base64 +### Result + +- `code`: _string_ – Contract code encoded as base64 + + # Types +## ErrorCode +```ts +type ErrorCode = 201 | 202 | 203 | 204; +``` +One of the following value: + +- `201` +- `202` +- `203` +- `204` + + ## ParamsOfParse ```ts type ParamsOfParse = { @@ -281,3 +325,21 @@ type ResultOfGetBocHash = { - `hash`: _string_ – BOC root hash encoded with hex +## ParamsOfGetCodeFromTvc +```ts +type ParamsOfGetCodeFromTvc = { + tvc: string +}; +``` +- `tvc`: _string_ – Contract TVC image encoded as base64 + + +## ResultOfGetCodeFromTvc +```ts +type ResultOfGetCodeFromTvc = { + code: string +}; +``` +- `code`: _string_ – Contract code encoded as base64 + + diff --git a/docs/mod_client.md b/docs/mod_client.md index 9d63b475a..1f83ad70c 100644 --- a/docs/mod_client.md +++ b/docs/mod_client.md @@ -11,6 +11,8 @@ null [resolve_app_request](#resolve_app_request) – Resolves application request processing result ## Types +[ErrorCode](#ErrorCode) + [ClientError](#ClientError) [ClientConfig](#ClientConfig) @@ -109,6 +111,47 @@ function resolve_app_request( # Types +## ErrorCode +```ts +type ErrorCode = 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33; +``` +One of the following value: + +- `1` +- `2` +- `3` +- `4` +- `5` +- `6` +- `7` +- `8` +- `9` +- `10` +- `11` +- `12` +- `13` +- `14` +- `15` +- `16` +- `17` +- `18` +- `19` +- `20` +- `21` +- `22` +- `23` +- `24` +- `25` +- `26` +- `27` +- `28` +- `29` +- `30` +- `31` +- `32` +- `33` + + ## ClientError ```ts type ClientError = { diff --git a/docs/mod_crypto.md b/docs/mod_crypto.md index 90b0242e7..58360a47b 100644 --- a/docs/mod_crypto.md +++ b/docs/mod_crypto.md @@ -28,11 +28,11 @@ null [nacl_sign](#nacl_sign) – Signs data using the signer's secret key. -[nacl_sign_open](#nacl_sign_open) +[nacl_sign_open](#nacl_sign_open) – Verifies the signature and returns the unsigned message -[nacl_sign_detached](#nacl_sign_detached) +[nacl_sign_detached](#nacl_sign_detached) – Signs the message using the secret key and returns a signature. -[nacl_box_keypair](#nacl_box_keypair) +[nacl_box_keypair](#nacl_box_keypair) – Generates a random NaCl key pair [nacl_box_keypair_from_secret_key](#nacl_box_keypair_from_secret_key) – Generates key pair from a secret key @@ -77,6 +77,8 @@ null [remove_signing_box](#remove_signing_box) – Removes signing box from SDK. ## Types +[ErrorCode](#ErrorCode) + [SigningBoxHandle](#SigningBoxHandle) [ParamsOfFactorize](#ParamsOfFactorize) @@ -550,6 +552,13 @@ function nacl_sign( ## nacl_sign_open +Verifies the signature and returns the unsigned message + +Verifies the signature in `signed` using the signer's public key `public` +and returns the message `unsigned`. + +If the signature fails verification, crypto_sign_open raises an exception. + ```ts type ParamsOfNaclSignOpen = { signed: string, @@ -575,6 +584,11 @@ function nacl_sign_open( ## nacl_sign_detached +Signs the message using the secret key and returns a signature. + +Signs the message `unsigned` using the secret key `secret` +and returns a signature `signature`. + ```ts type ParamsOfNaclSign = { unsigned: string, @@ -599,6 +613,8 @@ function nacl_sign_detached( ## nacl_box_keypair +Generates a random NaCl key pair + ```ts type KeyPair = { public: string, @@ -1179,6 +1195,33 @@ function remove_signing_box( # Types +## ErrorCode +```ts +type ErrorCode = 100 | 101 | 102 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121; +``` +One of the following value: + +- `100` +- `101` +- `102` +- `106` +- `107` +- `108` +- `109` +- `110` +- `111` +- `112` +- `113` +- `114` +- `115` +- `116` +- `117` +- `118` +- `119` +- `120` +- `121` + + ## SigningBoxHandle ```ts type SigningBoxHandle = number; diff --git a/docs/mod_debot.md b/docs/mod_debot.md index 30f203fba..155ef1796 100644 --- a/docs/mod_debot.md +++ b/docs/mod_debot.md @@ -11,6 +11,8 @@ null [remove](#remove) – [UNSTABLE](UNSTABLE.md) Destroys debot handle. ## Types +[ErrorCode](#ErrorCode) + [DebotHandle](#DebotHandle) – [UNSTABLE](UNSTABLE.md) Handle of registered in SDK debot [DebotAction](#DebotAction) – [UNSTABLE](UNSTABLE.md) Describes a debot action in a Debot Context. @@ -144,6 +146,18 @@ function remove( # Types +## ErrorCode +```ts +type ErrorCode = 801 | 802 | 803 | 804; +``` +One of the following value: + +- `801` +- `802` +- `803` +- `804` + + ## DebotHandle [UNSTABLE](UNSTABLE.md) Handle of registered in SDK debot @@ -211,6 +225,8 @@ type ParamsOfAppDebotBrowser = { } | { type: 'Switch' context_id: number +} | { + type: 'SwitchCompleted' } | { type: 'ShowAction' action: DebotAction @@ -241,6 +257,11 @@ Switch debot to another context (menu). - `context_id`: _number_ – Debot context ID to which debot is switched. +When _type_ is _'SwitchCompleted'_ + +Notify browser that all context actions are shown. + + When _type_ is _'ShowAction'_ Show action to the user. Called after `switch` for each action in context. diff --git a/docs/mod_net.md b/docs/mod_net.md index 69b719d62..9e7448623 100644 --- a/docs/mod_net.md +++ b/docs/mod_net.md @@ -16,7 +16,11 @@ null [resume](#resume) – Resumes network module to enable network activity +[find_last_shard_block](#find_last_shard_block) – Returns ID of the last block in a specified account shard + ## Types +[ErrorCode](#ErrorCode) + [OrderBy](#OrderBy) [SortDirection](#SortDirection) @@ -37,6 +41,10 @@ null [ParamsOfSubscribeCollection](#ParamsOfSubscribeCollection) +[ParamsOfFindLastShardBlock](#ParamsOfFindLastShardBlock) + +[ResultOfFindLastShardBlock](#ResultOfFindLastShardBlock) + # Functions ## query @@ -217,7 +225,49 @@ function resume(): Promise; +## find_last_shard_block + +Returns ID of the last block in a specified account shard + +```ts +type ParamsOfFindLastShardBlock = { + address: string +}; + +type ResultOfFindLastShardBlock = { + block_id: string +}; + +function find_last_shard_block( + params: ParamsOfFindLastShardBlock, +): Promise; +``` +### Parameters +- `address`: _string_ – Account address +### Result + +- `block_id`: _string_ – Account shard last block ID + + # Types +## ErrorCode +```ts +type ErrorCode = 601 | 602 | 603 | 604 | 605 | 606 | 607 | 608 | 609 | 610; +``` +One of the following value: + +- `601` +- `602` +- `603` +- `604` +- `605` +- `606` +- `607` +- `608` +- `609` +- `610` + + ## OrderBy ```ts type OrderBy = { @@ -333,3 +383,21 @@ type ParamsOfSubscribeCollection = { - `result`: _string_ – Projection (result) string +## ParamsOfFindLastShardBlock +```ts +type ParamsOfFindLastShardBlock = { + address: string +}; +``` +- `address`: _string_ – Account address + + +## ResultOfFindLastShardBlock +```ts +type ResultOfFindLastShardBlock = { + block_id: string +}; +``` +- `block_id`: _string_ – Account shard last block ID + + diff --git a/docs/mod_processing.md b/docs/mod_processing.md index db00f64e9..fc1bda84e 100644 --- a/docs/mod_processing.md +++ b/docs/mod_processing.md @@ -10,6 +10,8 @@ processing scenarios. [process_message](#process_message) – Creates message, sends it to the network and monitors its processing. ## Types +[ErrorCode](#ErrorCode) + [ProcessingEvent](#ProcessingEvent) [ResultOfProcessMessage](#ResultOfProcessMessage) @@ -183,6 +185,27 @@ function process_message( # Types +## ErrorCode +```ts +type ErrorCode = 501 | 502 | 503 | 504 | 505 | 506 | 507 | 508 | 509 | 510 | 511 | 512 | 513; +``` +One of the following value: + +- `501` +- `502` +- `503` +- `504` +- `505` +- `506` +- `507` +- `508` +- `509` +- `510` +- `511` +- `512` +- `513` + + ## ProcessingEvent ```ts type ProcessingEvent = { diff --git a/docs/mod_tvm.md b/docs/mod_tvm.md index eaafc9aa4..95133a252 100644 --- a/docs/mod_tvm.md +++ b/docs/mod_tvm.md @@ -2,13 +2,15 @@ null ## Functions -[run_executor](#run_executor) +[run_executor](#run_executor) – Emulates all the phases of contract execution locally -[run_tvm](#run_tvm) +[run_tvm](#run_tvm) – Executes get methods of ABI-compatible contracts -[run_get](#run_get) – Executes getmethod and returns data from TVM stack +[run_get](#run_get) – Executes a getmethod of FIFT contract ## Types +[ErrorCode](#ErrorCode) + [ExecutionOptions](#ExecutionOptions) [AccountForExecutor](#AccountForExecutor) @@ -31,6 +33,28 @@ null # Functions ## run_executor +Emulates all the phases of contract execution locally + +Performs all the phases of contract execution on Transaction Executor - +the same component that is used on Validator Nodes. + +Can be used for contract debug, to find out the reason of message unsuccessful +delivery - as Validators just throw away failed transactions, here you can catch it. + +Another use case is to estimate fees for message execution. Set `AccountForExecutor::Account.unlimited_balance` +to `true` so that emulation will not depend on the actual balance. + +One more use case - you can procude the sequence of operations, +thus emulating the multiple contract calls locally. +And so on. + +To get the account boc (bag of cells) - use `net.query` method to download it from graphql api +(field `boc` of `account`) or generate it with `abi.encode_account method`. +To get the message boc - use `abi.encode_message` or prepare it any other way, for instance, with Fift script. + +If you need this emulation to be as precise as possible then specify `ParamsOfRunExecutor` parameter. +If you need to see the aborted transaction as a result, not as an error, set `skip_transaction_check` to `true`. + ```ts type ParamsOfRunExecutor = { message: string, @@ -73,6 +97,21 @@ function run_executor( ## run_tvm +Executes get methods of ABI-compatible contracts + +Performs only a part of compute phase of transaction execution +that is used to run get-methods of ABI-compatible contracts. + +If you try to run get methods with `run_executor` you will get an error, because it checks ACCEPT and exits +if there is none, which is actually true for get methods. + + To get the account boc (bag of cells) - use `net.query` method to download it from graphql api +(field `boc` of `account`) or generate it with `abi.encode_account method`. +To get the message boc - use `abi.encode_message` or prepare it any other way, for instance, with Fift script. + +Attention! Updated account state is produces as well, but only +`account_state.storage.state.data` part of the boc is updated. + ```ts type ParamsOfRunTvm = { message: string, @@ -104,12 +143,15 @@ function run_tvm(
Encoded as `base64` - `decoded`?: _[DecodedOutput](mod_processing.md#DecodedOutput)_ – Optional decoded message bodies according to the optional `abi` parameter. - `account`: _string_ – Updated account state BOC. -
Encoded as `base64`.Attention! Only data in account state is updated. +
Encoded as `base64`.Attention! Only `account_state.storage.state.data` part of the boc is updated. ## run_get -Executes getmethod and returns data from TVM stack +Executes a getmethod of FIFT contract + +Executes a getmethod of FIFT contract that fulfills the smc-guidelines https://test.ton.org/smc-guidelines.txt +and returns the result data from TVM's stack ```ts type ParamsOfRunGet = { @@ -138,6 +180,28 @@ function run_get( # Types +## ErrorCode +```ts +type ErrorCode = 401 | 402 | 403 | 404 | 405 | 406 | 407 | 408 | 409 | 410 | 411 | 412 | 413 | 414; +``` +One of the following value: + +- `401` +- `402` +- `403` +- `404` +- `405` +- `406` +- `407` +- `408` +- `409` +- `410` +- `411` +- `412` +- `413` +- `414` + + ## ExecutionOptions ```ts type ExecutionOptions = { @@ -274,7 +338,7 @@ type ResultOfRunTvm = {
Encoded as `base64` - `decoded`?: _[DecodedOutput](mod_processing.md#DecodedOutput)_ – Optional decoded message bodies according to the optional `abi` parameter. - `account`: _string_ – Updated account state BOC. -
Encoded as `base64`.Attention! Only data in account state is updated. +
Encoded as `base64`.Attention! Only `account_state.storage.state.data` part of the boc is updated. ## ParamsOfRunGet diff --git a/docs/modules.md b/docs/modules.md index 73f404b46..026f77b7e 100644 --- a/docs/modules.md +++ b/docs/modules.md @@ -37,11 +37,11 @@ [nacl_sign](mod_crypto.md#nacl_sign) – Signs data using the signer's secret key. -[nacl_sign_open](mod_crypto.md#nacl_sign_open) +[nacl_sign_open](mod_crypto.md#nacl_sign_open) – Verifies the signature and returns the unsigned message -[nacl_sign_detached](mod_crypto.md#nacl_sign_detached) +[nacl_sign_detached](mod_crypto.md#nacl_sign_detached) – Signs the message using the secret key and returns a signature. -[nacl_box_keypair](mod_crypto.md#nacl_box_keypair) +[nacl_box_keypair](mod_crypto.md#nacl_box_keypair) – Generates a random NaCl key pair [nacl_box_keypair_from_secret_key](mod_crypto.md#nacl_box_keypair_from_secret_key) – Generates key pair from a secret key @@ -117,6 +117,8 @@ [get_boc_hash](mod_boc.md#get_boc_hash) – Calculates BOC root hash +[get_code_from_tvc](mod_boc.md#get_code_from_tvc) – Extracts code from TVC contract image + ## [processing](mod_processing.md) – Message processing module. [send_message](mod_processing.md#send_message) – Sends message to the network @@ -131,11 +133,11 @@ ## [tvm](mod_tvm.md) -[run_executor](mod_tvm.md#run_executor) +[run_executor](mod_tvm.md#run_executor) – Emulates all the phases of contract execution locally -[run_tvm](mod_tvm.md#run_tvm) +[run_tvm](mod_tvm.md#run_tvm) – Executes get methods of ABI-compatible contracts -[run_get](mod_tvm.md#run_get) – Executes getmethod and returns data from TVM stack +[run_get](mod_tvm.md#run_get) – Executes a getmethod of FIFT contract ## [net](mod_net.md) – Network access. @@ -153,6 +155,8 @@ [resume](mod_net.md#resume) – Resumes network module to enable network activity +[find_last_shard_block](mod_net.md#find_last_shard_block) – Returns ID of the last block in a specified account shard + ## [debot](mod_debot.md) – [UNSTABLE](UNSTABLE.md) Module for working with debot. [start](mod_debot.md#start) – [UNSTABLE](UNSTABLE.md) Starts an instance of debot. From 8b140812d016c2d96916e82fbe02f712e05fc2ca Mon Sep 17 00:00:00 2001 From: Michael Vlasov Date: Tue, 22 Dec 2020 12:53:20 +0500 Subject: [PATCH 03/19] FIX: warnings in build_info. --- ton_client/build.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ton_client/build.rs b/ton_client/build.rs index daf317cfa..15001b412 100644 --- a/ton_client/build.rs +++ b/ton_client/build.rs @@ -102,7 +102,8 @@ fn main() -> Result<(), String> { /* FIXME: failed with `the lock file Cargo.lock needs to be updated but --locked was passed to prevent this. If you want to try to generate the lock file without accessing the network, use the --offline flag.` - if std::env::var("NO_BUILD_INFO").is_err() { + */ + if false { let build_info = BuildInfo::load()?; let build_info_json = serde_json::to_string_pretty(&build_info).unwrap(); std::fs::write( @@ -111,6 +112,5 @@ fn main() -> Result<(), String> { ) .map_err(|err| format!("{}", err))?; } - */ Ok(()) } From 7f8390f53b4472ec63d45ffec20a1bef1202a75d Mon Sep 17 00:00:00 2001 From: Michael Vlasov Date: Tue, 22 Dec 2020 13:18:09 +0500 Subject: [PATCH 04/19] FIX: error code names. --- docs/mod_abi.md | 6 ++-- docs/mod_boc.md | 6 ++-- docs/mod_crypto.md | 6 ++-- docs/mod_debot.md | 6 ++-- docs/mod_net.md | 6 ++-- docs/mod_processing.md | 6 ++-- docs/mod_tvm.md | 6 ++-- ton_client/src/json_interface/modules.rs | 14 ++++---- ton_client/src/json_interface/registrar.rs | 39 ++++++++++++++++------ tools/api.json | 14 ++++---- 10 files changed, 63 insertions(+), 46 deletions(-) diff --git a/docs/mod_abi.md b/docs/mod_abi.md index f584305df..09574edb3 100644 --- a/docs/mod_abi.md +++ b/docs/mod_abi.md @@ -17,7 +17,7 @@ null [encode_account](#encode_account) – Creates account state BOC ## Types -[ErrorCode](#ErrorCode) +[AbiErrorCode](#AbiErrorCode) [Abi](#Abi) @@ -348,9 +348,9 @@ function encode_account( # Types -## ErrorCode +## AbiErrorCode ```ts -type ErrorCode = 301 | 302 | 303 | 304 | 305 | 306 | 307 | 308 | 309 | 310 | 311; +type AbiErrorCode = 301 | 302 | 303 | 304 | 305 | 306 | 307 | 308 | 309 | 310 | 311; ``` One of the following value: diff --git a/docs/mod_boc.md b/docs/mod_boc.md index 8c9a23e74..d745f5138 100644 --- a/docs/mod_boc.md +++ b/docs/mod_boc.md @@ -19,7 +19,7 @@ null [get_code_from_tvc](#get_code_from_tvc) – Extracts code from TVC contract image ## Types -[ErrorCode](#ErrorCode) +[BocErrorCode](#BocErrorCode) [ParamsOfParse](#ParamsOfParse) @@ -246,9 +246,9 @@ function get_code_from_tvc( # Types -## ErrorCode +## BocErrorCode ```ts -type ErrorCode = 201 | 202 | 203 | 204; +type BocErrorCode = 201 | 202 | 203 | 204; ``` One of the following value: diff --git a/docs/mod_crypto.md b/docs/mod_crypto.md index 58360a47b..bdf233d5c 100644 --- a/docs/mod_crypto.md +++ b/docs/mod_crypto.md @@ -77,7 +77,7 @@ null [remove_signing_box](#remove_signing_box) – Removes signing box from SDK. ## Types -[ErrorCode](#ErrorCode) +[CryptoErrorCode](#CryptoErrorCode) [SigningBoxHandle](#SigningBoxHandle) @@ -1195,9 +1195,9 @@ function remove_signing_box( # Types -## ErrorCode +## CryptoErrorCode ```ts -type ErrorCode = 100 | 101 | 102 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121; +type CryptoErrorCode = 100 | 101 | 102 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121; ``` One of the following value: diff --git a/docs/mod_debot.md b/docs/mod_debot.md index 155ef1796..7d01a38d8 100644 --- a/docs/mod_debot.md +++ b/docs/mod_debot.md @@ -11,7 +11,7 @@ null [remove](#remove) – [UNSTABLE](UNSTABLE.md) Destroys debot handle. ## Types -[ErrorCode](#ErrorCode) +[DebotErrorCode](#DebotErrorCode) [DebotHandle](#DebotHandle) – [UNSTABLE](UNSTABLE.md) Handle of registered in SDK debot @@ -146,9 +146,9 @@ function remove( # Types -## ErrorCode +## DebotErrorCode ```ts -type ErrorCode = 801 | 802 | 803 | 804; +type DebotErrorCode = 801 | 802 | 803 | 804; ``` One of the following value: diff --git a/docs/mod_net.md b/docs/mod_net.md index 9e7448623..f9709bef0 100644 --- a/docs/mod_net.md +++ b/docs/mod_net.md @@ -19,7 +19,7 @@ null [find_last_shard_block](#find_last_shard_block) – Returns ID of the last block in a specified account shard ## Types -[ErrorCode](#ErrorCode) +[NetErrorCode](#NetErrorCode) [OrderBy](#OrderBy) @@ -250,9 +250,9 @@ function find_last_shard_block( # Types -## ErrorCode +## NetErrorCode ```ts -type ErrorCode = 601 | 602 | 603 | 604 | 605 | 606 | 607 | 608 | 609 | 610; +type NetErrorCode = 601 | 602 | 603 | 604 | 605 | 606 | 607 | 608 | 609 | 610; ``` One of the following value: diff --git a/docs/mod_processing.md b/docs/mod_processing.md index fc1bda84e..b373c64ae 100644 --- a/docs/mod_processing.md +++ b/docs/mod_processing.md @@ -10,7 +10,7 @@ processing scenarios. [process_message](#process_message) – Creates message, sends it to the network and monitors its processing. ## Types -[ErrorCode](#ErrorCode) +[ProcessingErrorCode](#ProcessingErrorCode) [ProcessingEvent](#ProcessingEvent) @@ -185,9 +185,9 @@ function process_message( # Types -## ErrorCode +## ProcessingErrorCode ```ts -type ErrorCode = 501 | 502 | 503 | 504 | 505 | 506 | 507 | 508 | 509 | 510 | 511 | 512 | 513; +type ProcessingErrorCode = 501 | 502 | 503 | 504 | 505 | 506 | 507 | 508 | 509 | 510 | 511 | 512 | 513; ``` One of the following value: diff --git a/docs/mod_tvm.md b/docs/mod_tvm.md index 95133a252..93f301308 100644 --- a/docs/mod_tvm.md +++ b/docs/mod_tvm.md @@ -9,7 +9,7 @@ null [run_get](#run_get) – Executes a getmethod of FIFT contract ## Types -[ErrorCode](#ErrorCode) +[TvmErrorCode](#TvmErrorCode) [ExecutionOptions](#ExecutionOptions) @@ -180,9 +180,9 @@ function run_get( # Types -## ErrorCode +## TvmErrorCode ```ts -type ErrorCode = 401 | 402 | 403 | 404 | 405 | 406 | 407 | 408 | 409 | 410 | 411 | 412 | 413 | 414; +type TvmErrorCode = 401 | 402 | 403 | 404 | 405 | 406 | 407 | 408 | 409 | 410 | 411 | 412 | 413 | 414; ``` One of the following value: diff --git a/ton_client/src/json_interface/modules.rs b/ton_client/src/json_interface/modules.rs index 43041c8ab..bb282ddd1 100644 --- a/ton_client/src/json_interface/modules.rs +++ b/ton_client/src/json_interface/modules.rs @@ -53,7 +53,7 @@ pub(crate) struct CryptoModule; fn register_crypto(handlers: &mut RuntimeHandlers) { let mut module = ModuleReg::new::(handlers); - module.register_type::(); + module.register_error_code::(); module.register_type::(); // Math @@ -223,7 +223,7 @@ pub(crate) struct AbiModule; fn register_abi(handlers: &mut RuntimeHandlers) { let mut module = ModuleReg::new::(handlers); - module.register_type::(); + module.register_error_code::(); module.register_type::(); module.register_type::(); module.register_type::(); @@ -278,7 +278,7 @@ pub(crate) struct BocModule; fn register_boc(handlers: &mut RuntimeHandlers) { let mut module = ModuleReg::new::(handlers); - module.register_type::(); + module.register_error_code::(); module.register_sync_fn( crate::boc::parse_message, crate::boc::parse::parse_message_api, @@ -312,7 +312,7 @@ pub(crate) struct NetModule; fn register_net(handlers: &mut RuntimeHandlers) { let mut module = ModuleReg::new::(handlers); - module.register_type::(); + module.register_error_code::(); module.register_type::(); module.register_type::(); @@ -353,7 +353,7 @@ pub struct ProcessingModule; fn register_processing(handlers: &mut RuntimeHandlers) { let mut module = ModuleReg::new::(handlers); - module.register_type::(); + module.register_error_code::(); module.register_type::(); module.register_type::(); @@ -380,7 +380,7 @@ pub struct TvmModule; fn register_tvm(handlers: &mut RuntimeHandlers) { let mut module = ModuleReg::new::(handlers); - module.register_type::(); + module.register_error_code::(); module.register_type::(); module.register_type::(); @@ -416,7 +416,7 @@ pub struct DebotModule; fn register_debot(handlers: &mut RuntimeHandlers) { let mut module = ModuleReg::new::(handlers); - module.register_type::(); + module.register_error_code::(); module.register_type::(); module.register_type::(); diff --git a/ton_client/src/json_interface/registrar.rs b/ton_client/src/json_interface/registrar.rs index 57c66385a..b17a8a21a 100644 --- a/ton_client/src/json_interface/registrar.rs +++ b/ton_client/src/json_interface/registrar.rs @@ -13,8 +13,8 @@ */ use super::handlers::{ - CallHandler, CallNoArgsHandler, SpawnHandler, SpawnHandlerCallback, SpawnHandlerAppObject, - SpawnHandlerAppObjectNoArgs, SpawnNoArgsHandler, + CallHandler, CallNoArgsHandler, SpawnHandler, SpawnHandlerAppObject, + SpawnHandlerAppObjectNoArgs, SpawnHandlerCallback, SpawnNoArgsHandler, }; use super::request::Request; use super::runtime::RuntimeHandlers; @@ -43,6 +43,17 @@ impl<'h> ModuleReg<'h> { self.handlers.add_module(self.module); } + pub fn register_error_code(&mut self) { + let mut ty = T::api(); + ty.name = format!( + "{}{}{}", + self.module.name[0..1].to_uppercase(), + self.module.name[1..].to_lowercase(), + ty.name + ); + self.module.types.push(ty); + } + pub fn register_type(&mut self) { let ty = T::api(); if let api_info::Type::None = ty.value { @@ -68,7 +79,7 @@ impl<'h> ModuleReg<'h> { ) where P: ApiType + Send + DeserializeOwned + 'static, R: ApiType + Send + Serialize + 'static, - F: Send + Future> + 'static, + F: Send + Future> + 'static, { self.register_type::

(); self.register_type::(); @@ -79,7 +90,7 @@ impl<'h> ModuleReg<'h> { self.handlers .register_async(name.clone(), Box::new(SpawnHandler::new(handler))); #[cfg(not(feature = "wasm"))] - self.handlers.register_sync( + self.handlers.register_sync( name, Box::new(CallHandler::new(move |context, params| { context.clone().env.block_on(handler(context, params)) @@ -93,7 +104,7 @@ impl<'h> ModuleReg<'h> { api: fn() -> api_info::Function, ) where R: ApiType + Send + Serialize + 'static, - F: Send + Future> + 'static, + F: Send + Future> + 'static, { self.register_type::(); let function = api(); @@ -118,7 +129,7 @@ impl<'h> ModuleReg<'h> { ) where P: ApiType + Send + DeserializeOwned + 'static, R: ApiType + Send + Serialize + 'static, - F: Send + Future> + 'static, + F: Send + Future> + 'static, { self.register_type::

(); self.register_type::(); @@ -132,14 +143,18 @@ impl<'h> ModuleReg<'h> { #[allow(dead_code)] pub fn register_async_fn_with_app_object( &mut self, - handler: fn(context: std::sync::Arc, params: P, app_object: AppObject) -> F, + handler: fn( + context: std::sync::Arc, + params: P, + app_object: AppObject, + ) -> F, api: fn() -> api_info::Function, ) where P: ApiType + Send + DeserializeOwned + 'static, R: ApiType + Send + Serialize + 'static, AP: ApiType + Send + Serialize + 'static, AR: ApiType + Send + DeserializeOwned + 'static, - F: Send + Future> + 'static, + F: Send + Future> + 'static, { self.register_type::

(); self.register_type::(); @@ -160,7 +175,7 @@ impl<'h> ModuleReg<'h> { R: ApiType + Send + Serialize + 'static, AP: ApiType + Send + Serialize + 'static, AR: ApiType + Send + DeserializeOwned + 'static, - F: Send + Future> + 'static, + F: Send + Future> + 'static, { self.register_type::(); self.register_type::(); @@ -168,8 +183,10 @@ impl<'h> ModuleReg<'h> { let function = api(); let name = format!("{}.{}", self.module.name, function.name); self.module.functions.push(function); - self.handlers - .register_async(name.clone(), Box::new(SpawnHandlerAppObjectNoArgs::new(handler))); + self.handlers.register_async( + name.clone(), + Box::new(SpawnHandlerAppObjectNoArgs::new(handler)), + ); } pub fn register_sync_fn( diff --git a/tools/api.json b/tools/api.json index 67677b070..9f817a1ba 100644 --- a/tools/api.json +++ b/tools/api.json @@ -768,7 +768,7 @@ "description": null, "types": [ { - "name": "ErrorCode", + "name": "CryptoErrorCode", "type": "EnumOfConsts", "enum_consts": [ { @@ -3502,7 +3502,7 @@ "description": null, "types": [ { - "name": "ErrorCode", + "name": "AbiErrorCode", "type": "EnumOfConsts", "enum_consts": [ { @@ -4942,7 +4942,7 @@ "description": null, "types": [ { - "name": "ErrorCode", + "name": "BocErrorCode", "type": "EnumOfConsts", "enum_consts": [ { @@ -5432,7 +5432,7 @@ "description": "This module incorporates functions related to complex message\nprocessing scenarios.", "types": [ { - "name": "ErrorCode", + "name": "ProcessingErrorCode", "type": "EnumOfConsts", "enum_consts": [ { @@ -6197,7 +6197,7 @@ "description": null, "types": [ { - "name": "ErrorCode", + "name": "TvmErrorCode", "type": "EnumOfConsts", "enum_consts": [ { @@ -6802,7 +6802,7 @@ "description": null, "types": [ { - "name": "ErrorCode", + "name": "NetErrorCode", "type": "EnumOfConsts", "enum_consts": [ { @@ -7471,7 +7471,7 @@ "description": null, "types": [ { - "name": "ErrorCode", + "name": "DebotErrorCode", "type": "EnumOfConsts", "enum_consts": [ { From 38680c36464b8feb06173e8c957e3b615eac0155 Mon Sep 17 00:00:00 2001 From: Alexey Vavilin Date: Tue, 22 Dec 2020 12:18:57 +0300 Subject: [PATCH 05/19] Version 1.5.0 --- ton_client/Cargo.toml | 2 +- ton_sdk/Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/ton_client/Cargo.toml b/ton_client/Cargo.toml index e35ad799c..03fb7509e 100644 --- a/ton_client/Cargo.toml +++ b/ton_client/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "ton_client" -version = "1.4.0" +version = "1.5.0" authors = ["Michael Vlasov"] edition = "2018" license = "Apache-2.0" diff --git a/ton_sdk/Cargo.toml b/ton_sdk/Cargo.toml index a91fed038..9af9d22db 100644 --- a/ton_sdk/Cargo.toml +++ b/ton_sdk/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "ton_sdk" -version = "1.4.0" +version = "1.5.0" edition = "2018" license = "Apache-2.0" From d37b955538147eaef404244d39d4c2ea2d343e1c Mon Sep 17 00:00:00 2001 From: Michael Vlasov Date: Tue, 22 Dec 2020 15:07:22 +0500 Subject: [PATCH 06/19] NEW: `enum` type in TS code for the enum of consts. --- docs/mod_abi.md | 133 ++++++---- docs/mod_boc.md | 65 ++--- docs/mod_client.md | 138 ++++++---- docs/mod_crypto.md | 320 ++++++++++++----------- docs/mod_debot.md | 43 +-- docs/mod_net.md | 86 +++--- docs/mod_processing.md | 68 +++-- docs/mod_tvm.md | 75 +++--- docs/mod_utils.md | 10 +- ton_client/src/json_interface/modules.rs | 2 +- tools/api.json | 2 +- tools/api.ts | 2 +- tools/docs.ts | 12 +- tools/ts-code.ts | 25 +- 14 files changed, 551 insertions(+), 430 deletions(-) diff --git a/docs/mod_abi.md b/docs/mod_abi.md index 09574edb3..398c9d0ca 100644 --- a/docs/mod_abi.md +++ b/docs/mod_abi.md @@ -88,12 +88,12 @@ type ParamsOfEncodeMessageBody = { is_internal: boolean, signer: Signer, processing_try_index?: number -}; +} type ResultOfEncodeMessageBody = { body: string, data_to_sign?: string -}; +} function encode_message_body( params: ParamsOfEncodeMessageBody, @@ -122,11 +122,11 @@ type ParamsOfAttachSignatureToMessageBody = { public_key: string, message: string, signature: string -}; +} type ResultOfAttachSignatureToMessageBody = { body: string -}; +} function attach_signature_to_message_body( params: ParamsOfAttachSignatureToMessageBody, @@ -180,14 +180,14 @@ type ParamsOfEncodeMessage = { call_set?: CallSet, signer: Signer, processing_try_index?: number -}; +} type ResultOfEncodeMessage = { message: string, data_to_sign?: string, address: string, message_id: string -}; +} function encode_message( params: ParamsOfEncodeMessage, @@ -223,12 +223,12 @@ type ParamsOfAttachSignature = { public_key: string, message: string, signature: string -}; +} type ResultOfAttachSignature = { message: string, message_id: string -}; +} function attach_signature( params: ParamsOfAttachSignature, @@ -253,14 +253,14 @@ Decodes message body using provided message BOC and ABI. type ParamsOfDecodeMessage = { abi: Abi, message: string -}; +} type DecodedMessageBody = { body_type: MessageBodyType, name: string, value?: any, header?: FunctionHeader -}; +} function decode_message( params: ParamsOfDecodeMessage, @@ -286,14 +286,14 @@ type ParamsOfDecodeMessageBody = { abi: Abi, body: string, is_internal: boolean -}; +} type DecodedMessageBody = { body_type: MessageBodyType, name: string, value?: any, header?: FunctionHeader -}; +} function decode_message_body( params: ParamsOfDecodeMessageBody, @@ -325,12 +325,12 @@ type ParamsOfEncodeAccount = { balance?: bigint, last_trans_lt?: bigint, last_paid?: number -}; +} type ResultOfEncodeAccount = { account: string, id: string -}; +} function encode_account( params: ParamsOfEncodeAccount, @@ -350,21 +350,33 @@ function encode_account( # Types ## AbiErrorCode ```ts -type AbiErrorCode = 301 | 302 | 303 | 304 | 305 | 306 | 307 | 308 | 309 | 310 | 311; +enum AbiErrorCode { + RequiredAddressMissingForEncodeMessage = 301, + RequiredCallSetMissingForEncodeMessage = 302, + InvalidJson = 303, + InvalidMessage = 304, + EncodeDeployMessageFailed = 305, + EncodeRunMessageFailed = 306, + AttachSignatureFailed = 307, + InvalidTvcImage = 308, + RequiredPublicKeyMissingForFunctionHeader = 309, + InvalidSigner = 310, + InvalidAbi = 311 +} ``` One of the following value: -- `301` -- `302` -- `303` -- `304` -- `305` -- `306` -- `307` -- `308` -- `309` -- `310` -- `311` +- `RequiredAddressMissingForEncodeMessage = 301` +- `RequiredCallSetMissingForEncodeMessage = 302` +- `InvalidJson = 303` +- `InvalidMessage = 304` +- `EncodeDeployMessageFailed = 305` +- `EncodeRunMessageFailed = 306` +- `AttachSignatureFailed = 307` +- `InvalidTvcImage = 308` +- `RequiredPublicKeyMissingForFunctionHeader = 309` +- `InvalidSigner = 310` +- `InvalidAbi = 311` ## Abi @@ -381,7 +393,7 @@ type Abi = { } | { type: 'Serialized' value: AbiContract -}; +} ``` Depends on value of the `type` field. @@ -408,7 +420,7 @@ When _type_ is _'Serialized'_ ## AbiHandle ```ts -type AbiHandle = number; +type AbiHandle = number ``` @@ -426,7 +438,7 @@ type FunctionHeader = { expire?: number, time?: bigint, pubkey?: string -}; +} ``` - `expire`?: _number_ – Message expiration time in seconds. If not specified - calculated automatically from message_expiration_timeout(), try_index and message_expiration_timeout_grow_factor() (if ABI includes `expire` header). - `time`?: _bigint_ – Message creation time in milliseconds. @@ -441,7 +453,7 @@ type CallSet = { function_name: string, header?: FunctionHeader, input?: any -}; +} ``` - `function_name`: _string_ – Function name that is being called. - `header`?: _[FunctionHeader](mod_abi.md#FunctionHeader)_ – Function header. @@ -455,7 +467,7 @@ type DeploySet = { tvc: string, workchain_id?: number, initial_data?: any -}; +} ``` - `tvc`: _string_ – Content of TVC file encoded in `base64`. - `workchain_id`?: _number_ – Target workchain for destination address. @@ -476,7 +488,7 @@ type Signer = { } | { type: 'SigningBox' handle: SigningBoxHandle -}; +} ``` Depends on value of the `type` field. @@ -511,15 +523,20 @@ Signing Box interface is provided for signing, allows Dapps to sign messages usi ## MessageBodyType ```ts -type MessageBodyType = 'Input' | 'Output' | 'InternalOutput' | 'Event'; +enum MessageBodyType { + Input = "Input", + Output = "Output", + InternalOutput = "InternalOutput", + Event = "Event" +} ``` One of the following value: -- `Input` – Message contains the input of the ABI function. -- `Output` – Message contains the output of the ABI function. -- `InternalOutput` – Message contains the input of the imported ABI function. +- `Input = "Input"` – Message contains the input of the ABI function. +- `Output = "Output"` – Message contains the output of the ABI function. +- `InternalOutput = "InternalOutput"` – Message contains the input of the imported ABI function.
Occurs when contract sends an internal message to other
contract. -- `Event` – Message contains the input of the ABI event. +- `Event = "Event"` – Message contains the input of the ABI event. ## StateInitSource @@ -537,7 +554,7 @@ type StateInitSource = { tvc: string, public_key?: string, init_params?: StateInitParams -}; +} ``` Depends on value of the `type` field. @@ -577,7 +594,7 @@ Encoded in `base64`. type StateInitParams = { abi: Abi, value: any -}; +} ``` - `abi`: _[Abi](mod_abi.md#Abi)_ - `value`: _any_ @@ -591,7 +608,7 @@ type MessageSource = { abi?: Abi } | ({ type: 'EncodingParams' -} & ParamsOfEncodeMessage); +} & ParamsOfEncodeMessage) ``` Depends on value of the `type` field. @@ -621,7 +638,7 @@ type AbiParam = { name: string, type: string, components?: AbiParam[] -}; +} ``` - `name`: _string_ - `type`: _string_ @@ -634,7 +651,7 @@ type AbiEvent = { name: string, inputs: AbiParam[], id?: string | null -}; +} ``` - `name`: _string_ - `inputs`: _[AbiParam](mod_abi.md#AbiParam)[]_ @@ -648,7 +665,7 @@ type AbiData = { name: string, type: string, components?: AbiParam[] -}; +} ``` - `key`: _bigint_ - `name`: _string_ @@ -663,7 +680,7 @@ type AbiFunction = { inputs: AbiParam[], outputs: AbiParam[], id?: string | null -}; +} ``` - `name`: _string_ - `inputs`: _[AbiParam](mod_abi.md#AbiParam)[]_ @@ -680,7 +697,7 @@ type AbiContract = { functions?: AbiFunction[], events?: AbiEvent[], data?: AbiData[] -}; +} ``` - `ABI version`?: _number_ - `abi_version`?: _number_ @@ -698,7 +715,7 @@ type ParamsOfEncodeMessageBody = { is_internal: boolean, signer: Signer, processing_try_index?: number -}; +} ``` - `abi`: _[Abi](mod_abi.md#Abi)_ – Contract ABI. - `call_set`: _[CallSet](mod_abi.md#CallSet)_ – Function call parameters. @@ -714,7 +731,7 @@ type ParamsOfEncodeMessageBody = { type ResultOfEncodeMessageBody = { body: string, data_to_sign?: string -}; +} ``` - `body`: _string_ – Message body BOC encoded with `base64`. - `data_to_sign`?: _string_ – Optional data to sign. @@ -728,7 +745,7 @@ type ParamsOfAttachSignatureToMessageBody = { public_key: string, message: string, signature: string -}; +} ``` - `abi`: _[Abi](mod_abi.md#Abi)_ – Contract ABI - `public_key`: _string_ – Public key. @@ -743,7 +760,7 @@ type ParamsOfAttachSignatureToMessageBody = { ```ts type ResultOfAttachSignatureToMessageBody = { body: string -}; +} ``` - `body`: _string_ @@ -757,7 +774,7 @@ type ParamsOfEncodeMessage = { call_set?: CallSet, signer: Signer, processing_try_index?: number -}; +} ``` - `abi`: _[Abi](mod_abi.md#Abi)_ – Contract ABI. - `address`?: _string_ – Target address the message will be sent to. @@ -778,7 +795,7 @@ type ResultOfEncodeMessage = { data_to_sign?: string, address: string, message_id: string -}; +} ``` - `message`: _string_ – Message BOC encoded with `base64`. - `data_to_sign`?: _string_ – Optional data to be signed encoded in `base64`. @@ -794,7 +811,7 @@ type ParamsOfAttachSignature = { public_key: string, message: string, signature: string -}; +} ``` - `abi`: _[Abi](mod_abi.md#Abi)_ – Contract ABI - `public_key`: _string_ – Public key encoded in `hex`. @@ -807,7 +824,7 @@ type ParamsOfAttachSignature = { type ResultOfAttachSignature = { message: string, message_id: string -}; +} ``` - `message`: _string_ – Signed message BOC - `message_id`: _string_ – Message ID @@ -818,7 +835,7 @@ type ResultOfAttachSignature = { type ParamsOfDecodeMessage = { abi: Abi, message: string -}; +} ``` - `abi`: _[Abi](mod_abi.md#Abi)_ – contract ABI - `message`: _string_ – Message BOC @@ -831,7 +848,7 @@ type DecodedMessageBody = { name: string, value?: any, header?: FunctionHeader -}; +} ``` - `body_type`: _[MessageBodyType](mod_abi.md#MessageBodyType)_ – Type of the message body content. - `name`: _string_ – Function or event name. @@ -845,7 +862,7 @@ type ParamsOfDecodeMessageBody = { abi: Abi, body: string, is_internal: boolean -}; +} ``` - `abi`: _[Abi](mod_abi.md#Abi)_ – Contract ABI used to decode. - `body`: _string_ – Message body BOC encoded in `base64`. @@ -859,7 +876,7 @@ type ParamsOfEncodeAccount = { balance?: bigint, last_trans_lt?: bigint, last_paid?: number -}; +} ``` - `state_init`: _[StateInitSource](mod_abi.md#StateInitSource)_ – Source of the account state init. - `balance`?: _bigint_ – Initial balance. @@ -872,7 +889,7 @@ type ParamsOfEncodeAccount = { type ResultOfEncodeAccount = { account: string, id: string -}; +} ``` - `account`: _string_ – Account BOC encoded in `base64`. - `id`: _string_ – Account ID encoded in `hex`. diff --git a/docs/mod_boc.md b/docs/mod_boc.md index d745f5138..8ed399cda 100644 --- a/docs/mod_boc.md +++ b/docs/mod_boc.md @@ -50,11 +50,11 @@ JSON structure is compatible with GraphQL API message object ```ts type ParamsOfParse = { boc: string -}; +} type ResultOfParse = { parsed: any -}; +} function parse_message( params: ParamsOfParse, @@ -76,11 +76,11 @@ JSON structure is compatible with GraphQL API transaction object ```ts type ParamsOfParse = { boc: string -}; +} type ResultOfParse = { parsed: any -}; +} function parse_transaction( params: ParamsOfParse, @@ -102,11 +102,11 @@ JSON structure is compatible with GraphQL API account object ```ts type ParamsOfParse = { boc: string -}; +} type ResultOfParse = { parsed: any -}; +} function parse_account( params: ParamsOfParse, @@ -128,11 +128,11 @@ JSON structure is compatible with GraphQL API block object ```ts type ParamsOfParse = { boc: string -}; +} type ResultOfParse = { parsed: any -}; +} function parse_block( params: ParamsOfParse, @@ -156,11 +156,11 @@ type ParamsOfParseShardstate = { boc: string, id: string, workchain_id: number -}; +} type ResultOfParse = { parsed: any -}; +} function parse_shardstate( params: ParamsOfParseShardstate, @@ -180,11 +180,11 @@ function parse_shardstate( ```ts type ParamsOfGetBlockchainConfig = { block_boc: string -}; +} type ResultOfGetBlockchainConfig = { config_boc: string -}; +} function get_blockchain_config( params: ParamsOfGetBlockchainConfig, @@ -204,11 +204,11 @@ Calculates BOC root hash ```ts type ParamsOfGetBocHash = { boc: string -}; +} type ResultOfGetBocHash = { hash: string -}; +} function get_boc_hash( params: ParamsOfGetBocHash, @@ -228,11 +228,11 @@ Extracts code from TVC contract image ```ts type ParamsOfGetCodeFromTvc = { tvc: string -}; +} type ResultOfGetCodeFromTvc = { code: string -}; +} function get_code_from_tvc( params: ParamsOfGetCodeFromTvc, @@ -248,21 +248,26 @@ function get_code_from_tvc( # Types ## BocErrorCode ```ts -type BocErrorCode = 201 | 202 | 203 | 204; +enum BocErrorCode { + InvalidBoc = 201, + SerializationError = 202, + InappropriateBlock = 203, + MissingSourceBoc = 204 +} ``` One of the following value: -- `201` -- `202` -- `203` -- `204` +- `InvalidBoc = 201` +- `SerializationError = 202` +- `InappropriateBlock = 203` +- `MissingSourceBoc = 204` ## ParamsOfParse ```ts type ParamsOfParse = { boc: string -}; +} ``` - `boc`: _string_ – BOC encoded as base64 @@ -271,7 +276,7 @@ type ParamsOfParse = { ```ts type ResultOfParse = { parsed: any -}; +} ``` - `parsed`: _any_ – JSON containing parsed BOC @@ -282,7 +287,7 @@ type ParamsOfParseShardstate = { boc: string, id: string, workchain_id: number -}; +} ``` - `boc`: _string_ – BOC encoded as base64 - `id`: _string_ – Shardstate identificator @@ -293,7 +298,7 @@ type ParamsOfParseShardstate = { ```ts type ParamsOfGetBlockchainConfig = { block_boc: string -}; +} ``` - `block_boc`: _string_ – Key block BOC encoded as base64 @@ -302,7 +307,7 @@ type ParamsOfGetBlockchainConfig = { ```ts type ResultOfGetBlockchainConfig = { config_boc: string -}; +} ``` - `config_boc`: _string_ – Blockchain config BOC encoded as base64 @@ -311,7 +316,7 @@ type ResultOfGetBlockchainConfig = { ```ts type ParamsOfGetBocHash = { boc: string -}; +} ``` - `boc`: _string_ – BOC encoded as base64 @@ -320,7 +325,7 @@ type ParamsOfGetBocHash = { ```ts type ResultOfGetBocHash = { hash: string -}; +} ``` - `hash`: _string_ – BOC root hash encoded with hex @@ -329,7 +334,7 @@ type ResultOfGetBocHash = { ```ts type ParamsOfGetCodeFromTvc = { tvc: string -}; +} ``` - `tvc`: _string_ – Contract TVC image encoded as base64 @@ -338,7 +343,7 @@ type ParamsOfGetCodeFromTvc = { ```ts type ResultOfGetCodeFromTvc = { code: string -}; +} ``` - `code`: _string_ – Contract code encoded as base64 diff --git a/docs/mod_client.md b/docs/mod_client.md index 1f83ad70c..6d4e34250 100644 --- a/docs/mod_client.md +++ b/docs/mod_client.md @@ -11,7 +11,7 @@ null [resolve_app_request](#resolve_app_request) – Resolves application request processing result ## Types -[ErrorCode](#ErrorCode) +[ClientErrorCode](#ClientErrorCode) [ClientError](#ClientError) @@ -46,7 +46,7 @@ Returns Core Library API reference ```ts type ResultOfGetApiReference = { api: any -}; +} function get_api_reference(): Promise; ``` @@ -62,7 +62,7 @@ Returns Core Library version ```ts type ResultOfVersion = { version: string -}; +} function version(): Promise; ``` @@ -79,7 +79,7 @@ Returns detailed information about this build. type ResultOfBuildInfo = { build_number: number, dependencies: BuildInfoDependency[] -}; +} function build_info(): Promise; ``` @@ -97,7 +97,7 @@ Resolves application request processing result type ParamsOfResolveAppRequest = { app_request_id: number, result: AppRequestResult -}; +} function resolve_app_request( params: ParamsOfResolveAppRequest, @@ -111,45 +111,79 @@ function resolve_app_request( # Types -## ErrorCode +## ClientErrorCode ```ts -type ErrorCode = 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33; +enum ClientErrorCode { + NotImplemented = 1, + InvalidHex = 2, + InvalidBase64 = 3, + InvalidAddress = 4, + CallbackParamsCantBeConvertedToJson = 5, + WebsocketConnectError = 6, + WebsocketReceiveError = 7, + WebsocketSendError = 8, + HttpClientCreateError = 9, + HttpRequestCreateError = 10, + HttpRequestSendError = 11, + HttpRequestParseError = 12, + CallbackNotRegistered = 13, + NetModuleNotInit = 14, + InvalidConfig = 15, + CannotCreateRuntime = 16, + InvalidContextHandle = 17, + CannotSerializeResult = 18, + CannotSerializeError = 19, + CannotConvertJsValueToJson = 20, + CannotReceiveSpawnedResult = 21, + SetTimerError = 22, + InvalidParams = 23, + ContractsAddressConversionFailed = 24, + UnknownFunction = 25, + AppRequestError = 26, + NoSuchRequest = 27, + CanNotSendRequestResult = 28, + CanNotReceiveRequestResult = 29, + CanNotParseRequestResult = 30, + UnexpectedCallbackResponse = 31, + CanNotParseNumber = 32, + InternalError = 33 +} ``` One of the following value: -- `1` -- `2` -- `3` -- `4` -- `5` -- `6` -- `7` -- `8` -- `9` -- `10` -- `11` -- `12` -- `13` -- `14` -- `15` -- `16` -- `17` -- `18` -- `19` -- `20` -- `21` -- `22` -- `23` -- `24` -- `25` -- `26` -- `27` -- `28` -- `29` -- `30` -- `31` -- `32` -- `33` +- `NotImplemented = 1` +- `InvalidHex = 2` +- `InvalidBase64 = 3` +- `InvalidAddress = 4` +- `CallbackParamsCantBeConvertedToJson = 5` +- `WebsocketConnectError = 6` +- `WebsocketReceiveError = 7` +- `WebsocketSendError = 8` +- `HttpClientCreateError = 9` +- `HttpRequestCreateError = 10` +- `HttpRequestSendError = 11` +- `HttpRequestParseError = 12` +- `CallbackNotRegistered = 13` +- `NetModuleNotInit = 14` +- `InvalidConfig = 15` +- `CannotCreateRuntime = 16` +- `InvalidContextHandle = 17` +- `CannotSerializeResult = 18` +- `CannotSerializeError = 19` +- `CannotConvertJsValueToJson = 20` +- `CannotReceiveSpawnedResult = 21` +- `SetTimerError = 22` +- `InvalidParams = 23` +- `ContractsAddressConversionFailed = 24` +- `UnknownFunction = 25` +- `AppRequestError = 26` +- `NoSuchRequest = 27` +- `CanNotSendRequestResult = 28` +- `CanNotReceiveRequestResult = 29` +- `CanNotParseRequestResult = 30` +- `UnexpectedCallbackResponse = 31` +- `CanNotParseNumber = 32` +- `InternalError = 33` ## ClientError @@ -158,7 +192,7 @@ type ClientError = { code: number, message: string, data: any -}; +} ``` - `code`: _number_ - `message`: _string_ @@ -171,7 +205,7 @@ type ClientConfig = { network?: NetworkConfig, crypto?: CryptoConfig, abi?: AbiConfig -}; +} ``` - `network`?: _[NetworkConfig](mod_client.md#NetworkConfig)_ - `crypto`?: _[CryptoConfig](mod_client.md#CryptoConfig)_ @@ -188,7 +222,7 @@ type NetworkConfig = { wait_for_timeout?: number, out_of_sync_threshold?: number, access_key?: string -}; +} ``` - `server_address`: _string_ - `network_retries_count`?: _number_ @@ -205,7 +239,7 @@ type CryptoConfig = { mnemonic_dictionary?: number, mnemonic_word_count?: number, hdkey_derivation_path?: string -}; +} ``` - `mnemonic_dictionary`?: _number_ - `mnemonic_word_count`?: _number_ @@ -218,7 +252,7 @@ type AbiConfig = { workchain?: number, message_expiration_timeout?: number, message_expiration_timeout_grow_factor?: number -}; +} ``` - `workchain`?: _number_ - `message_expiration_timeout`?: _number_ @@ -230,7 +264,7 @@ type AbiConfig = { type BuildInfoDependency = { name: string, git_commit: string -}; +} ``` - `name`: _string_ – Dependency name.
Usually it is a crate name. @@ -242,7 +276,7 @@ type BuildInfoDependency = { type ParamsOfAppRequest = { app_request_id: number, request_data: any -}; +} ``` - `app_request_id`: _number_ – Request ID.
Should be used in `resolve_app_request` call @@ -257,7 +291,7 @@ type AppRequestResult = { } | { type: 'Ok' result: any -}; +} ``` Depends on value of the `type` field. @@ -280,7 +314,7 @@ Request processed successfully ```ts type ResultOfGetApiReference = { api: any -}; +} ``` - `api`: _API_ @@ -289,7 +323,7 @@ type ResultOfGetApiReference = { ```ts type ResultOfVersion = { version: string -}; +} ``` - `version`: _string_ – Core Library version @@ -299,7 +333,7 @@ type ResultOfVersion = { type ResultOfBuildInfo = { build_number: number, dependencies: BuildInfoDependency[] -}; +} ``` - `build_number`: _number_ – Build number assigned to this build by the CI. - `dependencies`: _[BuildInfoDependency](mod_client.md#BuildInfoDependency)[]_ – Fingerprint of the most important dependencies. @@ -310,7 +344,7 @@ type ResultOfBuildInfo = { type ParamsOfResolveAppRequest = { app_request_id: number, result: AppRequestResult -}; +} ``` - `app_request_id`: _number_ – Request ID received from SDK - `result`: _[AppRequestResult](mod_client.md#AppRequestResult)_ – Result of request processing diff --git a/docs/mod_crypto.md b/docs/mod_crypto.md index bdf233d5c..fede7c46a 100644 --- a/docs/mod_crypto.md +++ b/docs/mod_crypto.md @@ -208,11 +208,11 @@ Performs prime factorization – decomposition of a composite number into a prod ```ts type ParamsOfFactorize = { composite: string -}; +} type ResultOfFactorize = { factors: string[] -}; +} function factorize( params: ParamsOfFactorize, @@ -234,11 +234,11 @@ type ParamsOfModularPower = { base: string, exponent: string, modulus: string -}; +} type ResultOfModularPower = { modular_power: string -}; +} function modular_power( params: ParamsOfModularPower, @@ -260,11 +260,11 @@ Calculates CRC16 using TON algorithm. ```ts type ParamsOfTonCrc16 = { data: string -}; +} type ResultOfTonCrc16 = { crc: number -}; +} function ton_crc16( params: ParamsOfTonCrc16, @@ -285,11 +285,11 @@ Generates random byte array of the specified length and returns it in `base64` f ```ts type ParamsOfGenerateRandomBytes = { length: number -}; +} type ResultOfGenerateRandomBytes = { bytes: string -}; +} function generate_random_bytes( params: ParamsOfGenerateRandomBytes, @@ -309,11 +309,11 @@ Converts public key to ton safe_format ```ts type ParamsOfConvertPublicKeyToTonSafeFormat = { public_key: string -}; +} type ResultOfConvertPublicKeyToTonSafeFormat = { ton_public_key: string -}; +} function convert_public_key_to_ton_safe_format( params: ParamsOfConvertPublicKeyToTonSafeFormat, @@ -334,7 +334,7 @@ Generates random ed25519 key pair. type KeyPair = { public: string, secret: string -}; +} function generate_random_sign_keys(): Promise; ``` @@ -352,12 +352,12 @@ Signs a data using the provided keys. type ParamsOfSign = { unsigned: string, keys: KeyPair -}; +} type ResultOfSign = { signed: string, signature: string -}; +} function sign( params: ParamsOfSign, @@ -380,11 +380,11 @@ Verifies signed data using the provided public key. Raises error if verification type ParamsOfVerifySignature = { signed: string, public: string -}; +} type ResultOfVerifySignature = { unsigned: string -}; +} function verify_signature( params: ParamsOfVerifySignature, @@ -405,11 +405,11 @@ Calculates SHA256 hash of the specified data. ```ts type ParamsOfHash = { data: string -}; +} type ResultOfHash = { hash: string -}; +} function sha256( params: ParamsOfHash, @@ -431,11 +431,11 @@ Calculates SHA512 hash of the specified data. ```ts type ParamsOfHash = { data: string -}; +} type ResultOfHash = { hash: string -}; +} function sha512( params: ParamsOfHash, @@ -475,11 +475,11 @@ type ParamsOfScrypt = { r: number, p: number, dk_len: number -}; +} type ResultOfScrypt = { key: string -}; +} function scrypt( params: ParamsOfScrypt, @@ -505,12 +505,12 @@ Generates a key pair for signing from the secret key ```ts type ParamsOfNaclSignKeyPairFromSecret = { secret: string -}; +} type KeyPair = { public: string, secret: string -}; +} function nacl_sign_keypair_from_secret_key( params: ParamsOfNaclSignKeyPairFromSecret, @@ -532,11 +532,11 @@ Signs data using the signer's secret key. type ParamsOfNaclSign = { unsigned: string, secret: string -}; +} type ResultOfNaclSign = { signed: string -}; +} function nacl_sign( params: ParamsOfNaclSign, @@ -563,11 +563,11 @@ If the signature fails verification, crypto_sign_open raises an exception. type ParamsOfNaclSignOpen = { signed: string, public: string -}; +} type ResultOfNaclSignOpen = { unsigned: string -}; +} function nacl_sign_open( params: ParamsOfNaclSignOpen, @@ -593,11 +593,11 @@ and returns a signature `signature`. type ParamsOfNaclSign = { unsigned: string, secret: string -}; +} type ResultOfNaclSignDetached = { signature: string -}; +} function nacl_sign_detached( params: ParamsOfNaclSign, @@ -619,7 +619,7 @@ Generates a random NaCl key pair type KeyPair = { public: string, secret: string -}; +} function nacl_box_keypair(): Promise; ``` @@ -636,12 +636,12 @@ Generates key pair from a secret key ```ts type ParamsOfNaclBoxKeyPairFromSecret = { secret: string -}; +} type KeyPair = { public: string, secret: string -}; +} function nacl_box_keypair_from_secret_key( params: ParamsOfNaclBoxKeyPairFromSecret, @@ -668,11 +668,11 @@ type ParamsOfNaclBox = { nonce: string, their_public: string, secret: string -}; +} type ResultOfNaclBox = { encrypted: string -}; +} function nacl_box( params: ParamsOfNaclBox, @@ -698,11 +698,11 @@ type ParamsOfNaclBoxOpen = { nonce: string, their_public: string, secret: string -}; +} type ResultOfNaclBoxOpen = { decrypted: string -}; +} function nacl_box_open( params: ParamsOfNaclBoxOpen, @@ -728,11 +728,11 @@ type ParamsOfNaclSecretBox = { decrypted: string, nonce: string, key: string -}; +} type ResultOfNaclBox = { encrypted: string -}; +} function nacl_secret_box( params: ParamsOfNaclSecretBox, @@ -757,11 +757,11 @@ type ParamsOfNaclSecretBoxOpen = { encrypted: string, nonce: string, key: string -}; +} type ResultOfNaclBoxOpen = { decrypted: string -}; +} function nacl_secret_box_open( params: ParamsOfNaclSecretBoxOpen, @@ -784,11 +784,11 @@ Prints the list of words from the specified dictionary ```ts type ParamsOfMnemonicWords = { dictionary?: number -}; +} type ResultOfMnemonicWords = { words: string -}; +} function mnemonic_words( params: ParamsOfMnemonicWords, @@ -809,11 +809,11 @@ Generates a random mnemonic from the specified dictionary and word count type ParamsOfMnemonicFromRandom = { dictionary?: number, word_count?: number -}; +} type ResultOfMnemonicFromRandom = { phrase: string -}; +} function mnemonic_from_random( params: ParamsOfMnemonicFromRandom, @@ -836,11 +836,11 @@ type ParamsOfMnemonicFromEntropy = { entropy: string, dictionary?: number, word_count?: number -}; +} type ResultOfMnemonicFromEntropy = { phrase: string -}; +} function mnemonic_from_entropy( params: ParamsOfMnemonicFromEntropy, @@ -865,11 +865,11 @@ type ParamsOfMnemonicVerify = { phrase: string, dictionary?: number, word_count?: number -}; +} type ResultOfMnemonicVerify = { valid: boolean -}; +} function mnemonic_verify( params: ParamsOfMnemonicVerify, @@ -894,12 +894,12 @@ type ParamsOfMnemonicDeriveSignKeys = { path?: string, dictionary?: number, word_count?: number -}; +} type KeyPair = { public: string, secret: string -}; +} function mnemonic_derive_sign_keys( params: ParamsOfMnemonicDeriveSignKeys, @@ -925,11 +925,11 @@ type ParamsOfHDKeyXPrvFromMnemonic = { phrase: string, dictionary?: number, word_count?: number -}; +} type ResultOfHDKeyXPrvFromMnemonic = { xprv: string -}; +} function hdkey_xprv_from_mnemonic( params: ParamsOfHDKeyXPrvFromMnemonic, @@ -953,11 +953,11 @@ type ParamsOfHDKeyDeriveFromXPrv = { xprv: string, child_index: number, hardened: boolean -}; +} type ResultOfHDKeyDeriveFromXPrv = { xprv: string -}; +} function hdkey_derive_from_xprv( params: ParamsOfHDKeyDeriveFromXPrv, @@ -980,11 +980,11 @@ Derives the extended private key from the specified key and path type ParamsOfHDKeyDeriveFromXPrvPath = { xprv: string, path: string -}; +} type ResultOfHDKeyDeriveFromXPrvPath = { xprv: string -}; +} function hdkey_derive_from_xprv_path( params: ParamsOfHDKeyDeriveFromXPrvPath, @@ -1005,11 +1005,11 @@ Extracts the private key from the serialized extended private key ```ts type ParamsOfHDKeySecretFromXPrv = { xprv: string -}; +} type ResultOfHDKeySecretFromXPrv = { secret: string -}; +} function hdkey_secret_from_xprv( params: ParamsOfHDKeySecretFromXPrv, @@ -1029,11 +1029,11 @@ Extracts the public key from the serialized extended private key ```ts type ParamsOfHDKeyPublicFromXPrv = { xprv: string -}; +} type ResultOfHDKeyPublicFromXPrv = { public: string -}; +} function hdkey_public_from_xprv( params: ParamsOfHDKeyPublicFromXPrv, @@ -1055,11 +1055,11 @@ type ParamsOfChaCha20 = { data: string, key: string, nonce: string -}; +} type ResultOfChaCha20 = { data: string -}; +} function chacha20( params: ParamsOfChaCha20, @@ -1085,7 +1085,7 @@ Register an application implemented signing box. ```ts type RegisteredSigningBox = { handle: SigningBoxHandle -}; +} function register_signing_box( obj: AppSigningBox, @@ -1104,11 +1104,11 @@ Creates a default signing box implementation. type KeyPair = { public: string, secret: string -}; +} type RegisteredSigningBox = { handle: SigningBoxHandle -}; +} function get_signing_box( params: KeyPair, @@ -1129,11 +1129,11 @@ Returns public key of signing key pair. ```ts type RegisteredSigningBox = { handle: SigningBoxHandle -}; +} type ResultOfSigningBoxGetPublicKey = { pubkey: string -}; +} function signing_box_get_public_key( params: RegisteredSigningBox, @@ -1155,11 +1155,11 @@ Returns signed user data. type ParamsOfSigningBoxSign = { signing_box: SigningBoxHandle, unsigned: string -}; +} type ResultOfSigningBoxSign = { signature: string -}; +} function signing_box_sign( params: ParamsOfSigningBoxSign, @@ -1182,7 +1182,7 @@ Removes signing box from SDK. ```ts type RegisteredSigningBox = { handle: SigningBoxHandle -}; +} function remove_signing_box( params: RegisteredSigningBox, @@ -1197,34 +1197,54 @@ function remove_signing_box( # Types ## CryptoErrorCode ```ts -type CryptoErrorCode = 100 | 101 | 102 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121; +enum CryptoErrorCode { + InvalidPublicKey = 100, + InvalidSecretKey = 101, + InvalidKey = 102, + InvalidFactorizeChallenge = 106, + InvalidBigInt = 107, + ScryptFailed = 108, + InvalidKeySize = 109, + NaclSecretBoxFailed = 110, + NaclBoxFailed = 111, + NaclSignFailed = 112, + Bip39InvalidEntropy = 113, + Bip39InvalidPhrase = 114, + Bip32InvalidKey = 115, + Bip32InvalidDerivePath = 116, + Bip39InvalidDictionary = 117, + Bip39InvalidWordCount = 118, + MnemonicGenerationFailed = 119, + MnemonicFromEntropyFailed = 120, + SigningBoxNotRegistered = 121 +} ``` One of the following value: -- `100` -- `101` -- `102` -- `106` -- `107` -- `108` -- `109` -- `110` -- `111` -- `112` -- `113` -- `114` -- `115` -- `116` -- `117` -- `118` -- `119` -- `120` -- `121` +- `InvalidPublicKey = 100` +- `InvalidSecretKey = 101` +- `InvalidKey = 102` +- `InvalidFactorizeChallenge = 106` +- `InvalidBigInt = 107` +- `ScryptFailed = 108` +- `InvalidKeySize = 109` +- `NaclSecretBoxFailed = 110` +- `NaclBoxFailed = 111` +- `NaclSignFailed = 112` +- `Bip39InvalidEntropy = 113` +- `Bip39InvalidPhrase = 114` +- `Bip32InvalidKey = 115` +- `Bip32InvalidDerivePath = 116` +- `Bip39InvalidDictionary = 117` +- `Bip39InvalidWordCount = 118` +- `MnemonicGenerationFailed = 119` +- `MnemonicFromEntropyFailed = 120` +- `SigningBoxNotRegistered = 121` ## SigningBoxHandle ```ts -type SigningBoxHandle = number; +type SigningBoxHandle = number ``` @@ -1232,7 +1252,7 @@ type SigningBoxHandle = number; ```ts type ParamsOfFactorize = { composite: string -}; +} ``` - `composite`: _string_ – Hexadecimal representation of u64 composite number. @@ -1241,7 +1261,7 @@ type ParamsOfFactorize = { ```ts type ResultOfFactorize = { factors: string[] -}; +} ``` - `factors`: _string[]_ – Two factors of composite or empty if composite can't be factorized. @@ -1252,7 +1272,7 @@ type ParamsOfModularPower = { base: string, exponent: string, modulus: string -}; +} ``` - `base`: _string_ – `base` argument of calculation. - `exponent`: _string_ – `exponent` argument of calculation. @@ -1263,7 +1283,7 @@ type ParamsOfModularPower = { ```ts type ResultOfModularPower = { modular_power: string -}; +} ``` - `modular_power`: _string_ – Result of modular exponentiation @@ -1272,7 +1292,7 @@ type ResultOfModularPower = { ```ts type ParamsOfTonCrc16 = { data: string -}; +} ``` - `data`: _string_ – Input data for CRC calculation.
Encoded with `base64`. @@ -1282,7 +1302,7 @@ type ParamsOfTonCrc16 = { ```ts type ResultOfTonCrc16 = { crc: number -}; +} ``` - `crc`: _number_ – Calculated CRC for input data. @@ -1291,7 +1311,7 @@ type ResultOfTonCrc16 = { ```ts type ParamsOfGenerateRandomBytes = { length: number -}; +} ``` - `length`: _number_ – Size of random byte array. @@ -1300,7 +1320,7 @@ type ParamsOfGenerateRandomBytes = { ```ts type ResultOfGenerateRandomBytes = { bytes: string -}; +} ``` - `bytes`: _string_ – Generated bytes encoded in `base64`. @@ -1309,7 +1329,7 @@ type ResultOfGenerateRandomBytes = { ```ts type ParamsOfConvertPublicKeyToTonSafeFormat = { public_key: string -}; +} ``` - `public_key`: _string_ – Public key - 64 symbols hex string @@ -1318,7 +1338,7 @@ type ParamsOfConvertPublicKeyToTonSafeFormat = { ```ts type ResultOfConvertPublicKeyToTonSafeFormat = { ton_public_key: string -}; +} ``` - `ton_public_key`: _string_ – Public key represented in TON safe format. @@ -1328,7 +1348,7 @@ type ResultOfConvertPublicKeyToTonSafeFormat = { type KeyPair = { public: string, secret: string -}; +} ``` - `public`: _string_ – Public key - 64 symbols hex string - `secret`: _string_ – Private key - u64 symbols hex string @@ -1339,7 +1359,7 @@ type KeyPair = { type ParamsOfSign = { unsigned: string, keys: KeyPair -}; +} ``` - `unsigned`: _string_ – Data that must be signed encoded in `base64`. - `keys`: _[KeyPair](mod_crypto.md#KeyPair)_ – Sign keys. @@ -1350,7 +1370,7 @@ type ParamsOfSign = { type ResultOfSign = { signed: string, signature: string -}; +} ``` - `signed`: _string_ – Signed data combined with signature encoded in `base64`. - `signature`: _string_ – Signature encoded in `hex`. @@ -1361,7 +1381,7 @@ type ResultOfSign = { type ParamsOfVerifySignature = { signed: string, public: string -}; +} ``` - `signed`: _string_ – Signed data that must be verified encoded in `base64`. - `public`: _string_ – Signer's public key - 64 symbols hex string @@ -1371,7 +1391,7 @@ type ParamsOfVerifySignature = { ```ts type ResultOfVerifySignature = { unsigned: string -}; +} ``` - `unsigned`: _string_ – Unsigned data encoded in `base64`. @@ -1380,7 +1400,7 @@ type ResultOfVerifySignature = { ```ts type ParamsOfHash = { data: string -}; +} ``` - `data`: _string_ – Input data for hash calculation.
Encoded with `base64`. @@ -1390,7 +1410,7 @@ type ParamsOfHash = { ```ts type ResultOfHash = { hash: string -}; +} ``` - `hash`: _string_ – Hash of input `data`.
Encoded with 'hex'. @@ -1405,7 +1425,7 @@ type ParamsOfScrypt = { r: number, p: number, dk_len: number -}; +} ``` - `password`: _string_ – The password bytes to be hashed. Must be encoded with `base64`. - `salt`: _string_ – Salt bytes that modify the hash to protect against Rainbow table attacks. Must be encoded with `base64`. @@ -1419,7 +1439,7 @@ type ParamsOfScrypt = { ```ts type ResultOfScrypt = { key: string -}; +} ``` - `key`: _string_ – Derived key.
Encoded with `hex`. @@ -1429,7 +1449,7 @@ type ResultOfScrypt = { ```ts type ParamsOfNaclSignKeyPairFromSecret = { secret: string -}; +} ``` - `secret`: _string_ – Secret key - unprefixed 0-padded to 64 symbols hex string @@ -1439,7 +1459,7 @@ type ParamsOfNaclSignKeyPairFromSecret = { type ParamsOfNaclSign = { unsigned: string, secret: string -}; +} ``` - `unsigned`: _string_ – Data that must be signed encoded in `base64`. - `secret`: _string_ – Signer's secret key - unprefixed 0-padded to 64 symbols hex string @@ -1449,7 +1469,7 @@ type ParamsOfNaclSign = { ```ts type ResultOfNaclSign = { signed: string -}; +} ``` - `signed`: _string_ – Signed data, encoded in `base64`. @@ -1459,7 +1479,7 @@ type ResultOfNaclSign = { type ParamsOfNaclSignOpen = { signed: string, public: string -}; +} ``` - `signed`: _string_ – Signed data that must be unsigned.
Encoded with `base64`. @@ -1470,7 +1490,7 @@ type ParamsOfNaclSignOpen = { ```ts type ResultOfNaclSignOpen = { unsigned: string -}; +} ``` - `unsigned`: _string_ – Unsigned data, encoded in `base64`. @@ -1479,7 +1499,7 @@ type ResultOfNaclSignOpen = { ```ts type ResultOfNaclSignDetached = { signature: string -}; +} ``` - `signature`: _string_ – Signature encoded in `hex`. @@ -1488,7 +1508,7 @@ type ResultOfNaclSignDetached = { ```ts type ParamsOfNaclBoxKeyPairFromSecret = { secret: string -}; +} ``` - `secret`: _string_ – Secret key - unprefixed 0-padded to 64 symbols hex string @@ -1500,7 +1520,7 @@ type ParamsOfNaclBox = { nonce: string, their_public: string, secret: string -}; +} ``` - `decrypted`: _string_ – Data that must be encrypted encoded in `base64`. - `nonce`: _string_ – Nonce, encoded in `hex` @@ -1512,7 +1532,7 @@ type ParamsOfNaclBox = { ```ts type ResultOfNaclBox = { encrypted: string -}; +} ``` - `encrypted`: _string_ – Encrypted data encoded in `base64`. @@ -1524,7 +1544,7 @@ type ParamsOfNaclBoxOpen = { nonce: string, their_public: string, secret: string -}; +} ``` - `encrypted`: _string_ – Data that must be decrypted.
Encoded with `base64`. @@ -1537,7 +1557,7 @@ type ParamsOfNaclBoxOpen = { ```ts type ResultOfNaclBoxOpen = { decrypted: string -}; +} ``` - `decrypted`: _string_ – Decrypted data encoded in `base64`. @@ -1548,7 +1568,7 @@ type ParamsOfNaclSecretBox = { decrypted: string, nonce: string, key: string -}; +} ``` - `decrypted`: _string_ – Data that must be encrypted.
Encoded with `base64`. @@ -1562,7 +1582,7 @@ type ParamsOfNaclSecretBoxOpen = { encrypted: string, nonce: string, key: string -}; +} ``` - `encrypted`: _string_ – Data that must be decrypted.
Encoded with `base64`. @@ -1574,7 +1594,7 @@ type ParamsOfNaclSecretBoxOpen = { ```ts type ParamsOfMnemonicWords = { dictionary?: number -}; +} ``` - `dictionary`?: _number_ – Dictionary identifier @@ -1583,7 +1603,7 @@ type ParamsOfMnemonicWords = { ```ts type ResultOfMnemonicWords = { words: string -}; +} ``` - `words`: _string_ – The list of mnemonic words @@ -1593,7 +1613,7 @@ type ResultOfMnemonicWords = { type ParamsOfMnemonicFromRandom = { dictionary?: number, word_count?: number -}; +} ``` - `dictionary`?: _number_ – Dictionary identifier - `word_count`?: _number_ – Mnemonic word count @@ -1603,7 +1623,7 @@ type ParamsOfMnemonicFromRandom = { ```ts type ResultOfMnemonicFromRandom = { phrase: string -}; +} ``` - `phrase`: _string_ – String of mnemonic words @@ -1614,7 +1634,7 @@ type ParamsOfMnemonicFromEntropy = { entropy: string, dictionary?: number, word_count?: number -}; +} ``` - `entropy`: _string_ – Entropy bytes.
Hex encoded. @@ -1626,7 +1646,7 @@ type ParamsOfMnemonicFromEntropy = { ```ts type ResultOfMnemonicFromEntropy = { phrase: string -}; +} ``` - `phrase`: _string_ – Phrase @@ -1637,7 +1657,7 @@ type ParamsOfMnemonicVerify = { phrase: string, dictionary?: number, word_count?: number -}; +} ``` - `phrase`: _string_ – Phrase - `dictionary`?: _number_ – Dictionary identifier @@ -1648,7 +1668,7 @@ type ParamsOfMnemonicVerify = { ```ts type ResultOfMnemonicVerify = { valid: boolean -}; +} ``` - `valid`: _boolean_ – Flag indicating if the mnemonic is valid or not @@ -1660,7 +1680,7 @@ type ParamsOfMnemonicDeriveSignKeys = { path?: string, dictionary?: number, word_count?: number -}; +} ``` - `phrase`: _string_ – Phrase - `path`?: _string_ – Derivation path, for instance "m/44'/396'/0'/0/0" @@ -1674,7 +1694,7 @@ type ParamsOfHDKeyXPrvFromMnemonic = { phrase: string, dictionary?: number, word_count?: number -}; +} ``` - `phrase`: _string_ – String with seed phrase - `dictionary`?: _number_ – Dictionary identifier @@ -1685,7 +1705,7 @@ type ParamsOfHDKeyXPrvFromMnemonic = { ```ts type ResultOfHDKeyXPrvFromMnemonic = { xprv: string -}; +} ``` - `xprv`: _string_ – Serialized extended master private key @@ -1696,7 +1716,7 @@ type ParamsOfHDKeyDeriveFromXPrv = { xprv: string, child_index: number, hardened: boolean -}; +} ``` - `xprv`: _string_ – Serialized extended private key - `child_index`: _number_ – Child index (see BIP-0032) @@ -1707,7 +1727,7 @@ type ParamsOfHDKeyDeriveFromXPrv = { ```ts type ResultOfHDKeyDeriveFromXPrv = { xprv: string -}; +} ``` - `xprv`: _string_ – Serialized extended private key @@ -1717,7 +1737,7 @@ type ResultOfHDKeyDeriveFromXPrv = { type ParamsOfHDKeyDeriveFromXPrvPath = { xprv: string, path: string -}; +} ``` - `xprv`: _string_ – Serialized extended private key - `path`: _string_ – Derivation path, for instance "m/44'/396'/0'/0/0" @@ -1727,7 +1747,7 @@ type ParamsOfHDKeyDeriveFromXPrvPath = { ```ts type ResultOfHDKeyDeriveFromXPrvPath = { xprv: string -}; +} ``` - `xprv`: _string_ – Derived serialized extended private key @@ -1736,7 +1756,7 @@ type ResultOfHDKeyDeriveFromXPrvPath = { ```ts type ParamsOfHDKeySecretFromXPrv = { xprv: string -}; +} ``` - `xprv`: _string_ – Serialized extended private key @@ -1745,7 +1765,7 @@ type ParamsOfHDKeySecretFromXPrv = { ```ts type ResultOfHDKeySecretFromXPrv = { secret: string -}; +} ``` - `secret`: _string_ – Private key - 64 symbols hex string @@ -1754,7 +1774,7 @@ type ResultOfHDKeySecretFromXPrv = { ```ts type ParamsOfHDKeyPublicFromXPrv = { xprv: string -}; +} ``` - `xprv`: _string_ – Serialized extended private key @@ -1763,7 +1783,7 @@ type ParamsOfHDKeyPublicFromXPrv = { ```ts type ResultOfHDKeyPublicFromXPrv = { public: string -}; +} ``` - `public`: _string_ – Public key - 64 symbols hex string @@ -1774,7 +1794,7 @@ type ParamsOfChaCha20 = { data: string, key: string, nonce: string -}; +} ``` - `data`: _string_ – Source data to be encrypted or decrypted.
Must be encoded with `base64`. @@ -1788,7 +1808,7 @@ type ParamsOfChaCha20 = { ```ts type ResultOfChaCha20 = { data: string -}; +} ``` - `data`: _string_ – Encrypted/decrypted data.
Encoded with `base64`. @@ -1798,7 +1818,7 @@ type ResultOfChaCha20 = { ```ts type RegisteredSigningBox = { handle: SigningBoxHandle -}; +} ``` - `handle`: _[SigningBoxHandle](mod_crypto.md#SigningBoxHandle)_ – Handle of the signing box. @@ -1812,7 +1832,7 @@ type ParamsOfAppSigningBox = { } | { type: 'Sign' unsigned: string -}; +} ``` Depends on value of the `type` field. @@ -1839,7 +1859,7 @@ type ResultOfAppSigningBox = { } | { type: 'Sign' signature: string -}; +} ``` Depends on value of the `type` field. @@ -1862,7 +1882,7 @@ Result of signing data ```ts type ResultOfSigningBoxGetPublicKey = { pubkey: string -}; +} ``` - `pubkey`: _string_ – Public key of signing box.
Encoded with hex @@ -1873,7 +1893,7 @@ type ResultOfSigningBoxGetPublicKey = { type ParamsOfSigningBoxSign = { signing_box: SigningBoxHandle, unsigned: string -}; +} ``` - `signing_box`: _[SigningBoxHandle](mod_crypto.md#SigningBoxHandle)_ – Signing Box handle. - `unsigned`: _string_ – Unsigned user data. @@ -1884,7 +1904,7 @@ type ParamsOfSigningBoxSign = { ```ts type ResultOfSigningBoxSign = { signature: string -}; +} ``` - `signature`: _string_ – Data signature.
Encoded with `base64`. diff --git a/docs/mod_debot.md b/docs/mod_debot.md index 7d01a38d8..9f7bc7cee 100644 --- a/docs/mod_debot.md +++ b/docs/mod_debot.md @@ -48,11 +48,11 @@ since the debot tries to display all actions from the context 0 to the user. ```ts type ParamsOfStart = { address: string -}; +} type RegisteredDebot = { debot_handle: DebotHandle -}; +} function start( params: ParamsOfStart, @@ -79,11 +79,11 @@ It does not switch debot to context 0. Browser Callbacks are not called. ```ts type ParamsOfFetch = { address: string -}; +} type RegisteredDebot = { debot_handle: DebotHandle -}; +} function fetch( params: ParamsOfFetch, @@ -111,7 +111,7 @@ Chain of actions can be executed if input action generates a list of subactions. type ParamsOfExecute = { debot_handle: DebotHandle, action: DebotAction -}; +} function execute( params: ParamsOfExecute, @@ -133,7 +133,7 @@ Removes handle from Client Context and drops debot engine referenced by that han ```ts type RegisteredDebot = { debot_handle: DebotHandle -}; +} function remove( params: RegisteredDebot, @@ -148,21 +148,26 @@ function remove( # Types ## DebotErrorCode ```ts -type DebotErrorCode = 801 | 802 | 803 | 804; +enum DebotErrorCode { + DebotStartFailed = 801, + DebotFetchFailed = 802, + DebotExecutionFailed = 803, + DebotInvalidHandle = 804 +} ``` One of the following value: -- `801` -- `802` -- `803` -- `804` +- `DebotStartFailed = 801` +- `DebotFetchFailed = 802` +- `DebotExecutionFailed = 803` +- `DebotInvalidHandle = 804` ## DebotHandle [UNSTABLE](UNSTABLE.md) Handle of registered in SDK debot ```ts -type DebotHandle = number; +type DebotHandle = number ``` @@ -177,7 +182,7 @@ type DebotAction = { to: number, attributes: string, misc: string -}; +} ``` - `description`: _string_ – A short action description.
Should be used by Debot Browser as name ofmenu item. @@ -197,7 +202,7 @@ type DebotAction = { ```ts type ParamsOfStart = { address: string -}; +} ``` - `address`: _string_ – Debot smart contract address @@ -208,7 +213,7 @@ type ParamsOfStart = { ```ts type RegisteredDebot = { debot_handle: DebotHandle -}; +} ``` - `debot_handle`: _[DebotHandle](mod_debot.md#DebotHandle)_ – Debot handle which references an instance of debot engine. @@ -239,7 +244,7 @@ type ParamsOfAppDebotBrowser = { type: 'InvokeDebot' debot_addr: string, action: DebotAction -}; +} ``` Depends on value of the `type` field. @@ -304,7 +309,7 @@ type ResultOfAppDebotBrowser = { signing_box: SigningBoxHandle } | { type: 'InvokeDebot' -}; +} ``` Depends on value of the `type` field. @@ -335,7 +340,7 @@ Result of debot invoking. ```ts type ParamsOfFetch = { address: string -}; +} ``` - `address`: _string_ – Debot smart contract address @@ -347,7 +352,7 @@ type ParamsOfFetch = { type ParamsOfExecute = { debot_handle: DebotHandle, action: DebotAction -}; +} ``` - `debot_handle`: _[DebotHandle](mod_debot.md#DebotHandle)_ – Debot handle which references an instance of debot engine. - `action`: _[DebotAction](mod_debot.md#DebotAction)_ – Debot Action that must be executed. diff --git a/docs/mod_net.md b/docs/mod_net.md index f9709bef0..1321dfd10 100644 --- a/docs/mod_net.md +++ b/docs/mod_net.md @@ -55,11 +55,11 @@ Performs DAppServer GraphQL query. type ParamsOfQuery = { query: string, variables?: any -}; +} type ResultOfQuery = { result: any -}; +} function query( params: ParamsOfQuery, @@ -89,11 +89,11 @@ type ParamsOfQueryCollection = { result: string, order?: OrderBy[], limit?: number -}; +} type ResultOfQueryCollection = { result: any[] -}; +} function query_collection( params: ParamsOfQueryCollection, @@ -127,11 +127,11 @@ type ParamsOfWaitForCollection = { filter?: any, result: string, timeout?: number -}; +} type ResultOfWaitForCollection = { result: any -}; +} function wait_for_collection( params: ParamsOfWaitForCollection, @@ -156,7 +156,7 @@ Cancels a subscription specified by its handle. ```ts type ResultOfSubscribeCollection = { handle: number -}; +} function unsubscribe( params: ResultOfSubscribeCollection, @@ -182,11 +182,11 @@ type ParamsOfSubscribeCollection = { collection: string, filter?: any, result: string -}; +} type ResultOfSubscribeCollection = { handle: number -}; +} function subscribe_collection( params: ParamsOfSubscribeCollection, @@ -232,11 +232,11 @@ Returns ID of the last block in a specified account shard ```ts type ParamsOfFindLastShardBlock = { address: string -}; +} type ResultOfFindLastShardBlock = { block_id: string -}; +} function find_last_shard_block( params: ParamsOfFindLastShardBlock, @@ -252,20 +252,31 @@ function find_last_shard_block( # Types ## NetErrorCode ```ts -type NetErrorCode = 601 | 602 | 603 | 604 | 605 | 606 | 607 | 608 | 609 | 610; +enum NetErrorCode { + QueryFailed = 601, + SubscribeFailed = 602, + WaitForFailed = 603, + GetSubscriptionResultFailed = 604, + InvalidServerResponse = 605, + ClockOutOfSync = 606, + WaitForTimeout = 607, + GraphqlError = 608, + NetworkModuleSuspended = 609, + WebsocketDisconnected = 610 +} ``` One of the following value: -- `601` -- `602` -- `603` -- `604` -- `605` -- `606` -- `607` -- `608` -- `609` -- `610` +- `QueryFailed = 601` +- `SubscribeFailed = 602` +- `WaitForFailed = 603` +- `GetSubscriptionResultFailed = 604` +- `InvalidServerResponse = 605` +- `ClockOutOfSync = 606` +- `WaitForTimeout = 607` +- `GraphqlError = 608` +- `NetworkModuleSuspended = 609` +- `WebsocketDisconnected = 610` ## OrderBy @@ -273,7 +284,7 @@ One of the following value: type OrderBy = { path: string, direction: SortDirection -}; +} ``` - `path`: _string_ - `direction`: _[SortDirection](mod_net.md#SortDirection)_ @@ -281,12 +292,15 @@ type OrderBy = { ## SortDirection ```ts -type SortDirection = 'ASC' | 'DESC'; +enum SortDirection { + ASC = "ASC", + DESC = "DESC" +} ``` One of the following value: -- `ASC` -- `DESC` +- `ASC = "ASC"` +- `DESC = "DESC"` ## ParamsOfQuery @@ -294,7 +308,7 @@ One of the following value: type ParamsOfQuery = { query: string, variables?: any -}; +} ``` - `query`: _string_ – GraphQL query text. - `variables`?: _any_ – Variables used in query. @@ -305,7 +319,7 @@ type ParamsOfQuery = { ```ts type ResultOfQuery = { result: any -}; +} ``` - `result`: _any_ – Result provided by DAppServer. @@ -318,7 +332,7 @@ type ParamsOfQueryCollection = { result: string, order?: OrderBy[], limit?: number -}; +} ``` - `collection`: _string_ – Collection name (accounts, blocks, transactions, messages, block_signatures) - `filter`?: _any_ – Collection filter @@ -331,7 +345,7 @@ type ParamsOfQueryCollection = { ```ts type ResultOfQueryCollection = { result: any[] -}; +} ``` - `result`: _any[]_ – Objects that match the provided criteria @@ -343,7 +357,7 @@ type ParamsOfWaitForCollection = { filter?: any, result: string, timeout?: number -}; +} ``` - `collection`: _string_ – Collection name (accounts, blocks, transactions, messages, block_signatures) - `filter`?: _any_ – Collection filter @@ -355,7 +369,7 @@ type ParamsOfWaitForCollection = { ```ts type ResultOfWaitForCollection = { result: any -}; +} ``` - `result`: _any_ – First found object that matches the provided criteria @@ -364,7 +378,7 @@ type ResultOfWaitForCollection = { ```ts type ResultOfSubscribeCollection = { handle: number -}; +} ``` - `handle`: _number_ – Subscription handle.
Must be closed with `unsubscribe` @@ -376,7 +390,7 @@ type ParamsOfSubscribeCollection = { collection: string, filter?: any, result: string -}; +} ``` - `collection`: _string_ – Collection name (accounts, blocks, transactions, messages, block_signatures) - `filter`?: _any_ – Collection filter @@ -387,7 +401,7 @@ type ParamsOfSubscribeCollection = { ```ts type ParamsOfFindLastShardBlock = { address: string -}; +} ``` - `address`: _string_ – Account address @@ -396,7 +410,7 @@ type ParamsOfFindLastShardBlock = { ```ts type ResultOfFindLastShardBlock = { block_id: string -}; +} ``` - `block_id`: _string_ – Account shard last block ID diff --git a/docs/mod_processing.md b/docs/mod_processing.md index b373c64ae..6972560a5 100644 --- a/docs/mod_processing.md +++ b/docs/mod_processing.md @@ -40,11 +40,11 @@ type ParamsOfSendMessage = { message: string, abi?: Abi, send_events: boolean -}; +} type ResultOfSendMessage = { shard_block_id: string -}; +} function send_message( params: ParamsOfSendMessage, @@ -97,14 +97,14 @@ type ParamsOfWaitForTransaction = { message: string, shard_block_id: string, send_events: boolean -}; +} type ResultOfProcessMessage = { transaction: any, out_messages: string[], decoded?: DecodedOutput, fees: TransactionFees -}; +} function wait_for_transaction( params: ParamsOfWaitForTransaction, @@ -157,14 +157,14 @@ then, if no transaction is found within the network timeout (see config paramete type ParamsOfProcessMessage = { message_encode_params: ParamsOfEncodeMessage, send_events: boolean -}; +} type ResultOfProcessMessage = { transaction: any, out_messages: string[], decoded?: DecodedOutput, fees: TransactionFees -}; +} function process_message( params: ParamsOfProcessMessage, @@ -187,23 +187,37 @@ function process_message( # Types ## ProcessingErrorCode ```ts -type ProcessingErrorCode = 501 | 502 | 503 | 504 | 505 | 506 | 507 | 508 | 509 | 510 | 511 | 512 | 513; +enum ProcessingErrorCode { + MessageAlreadyExpired = 501, + MessageHasNotDestinationAddress = 502, + CanNotBuildMessageCell = 503, + FetchBlockFailed = 504, + SendMessageFailed = 505, + InvalidMessageBoc = 506, + MessageExpired = 507, + TransactionWaitTimeout = 508, + InvalidBlockReceived = 509, + CanNotCheckBlockShard = 510, + BlockNotFound = 511, + InvalidData = 512, + ExternalSignerMustNotBeUsed = 513 +} ``` One of the following value: -- `501` -- `502` -- `503` -- `504` -- `505` -- `506` -- `507` -- `508` -- `509` -- `510` -- `511` -- `512` -- `513` +- `MessageAlreadyExpired = 501` +- `MessageHasNotDestinationAddress = 502` +- `CanNotBuildMessageCell = 503` +- `FetchBlockFailed = 504` +- `SendMessageFailed = 505` +- `InvalidMessageBoc = 506` +- `MessageExpired = 507` +- `TransactionWaitTimeout = 508` +- `InvalidBlockReceived = 509` +- `CanNotCheckBlockShard = 510` +- `BlockNotFound = 511` +- `InvalidData = 512` +- `ExternalSignerMustNotBeUsed = 513` ## ProcessingEvent @@ -245,7 +259,7 @@ type ProcessingEvent = { message_id: string, message: string, error: ClientError -}; +} ``` Depends on value of the `type` field. @@ -343,7 +357,7 @@ type ResultOfProcessMessage = { out_messages: string[], decoded?: DecodedOutput, fees: TransactionFees -}; +} ``` - `transaction`: _any_ – Parsed transaction.
In addition to the regular transaction fields there is a
`boc` field encoded with `base64` which contains source
transaction BOC. @@ -358,7 +372,7 @@ type ResultOfProcessMessage = { type DecodedOutput = { out_messages: DecodedMessageBody | null[], output?: any -}; +} ``` - `out_messages`: _[DecodedMessageBody](mod_abi.md#DecodedMessageBody)?[]_ – Decoded bodies of the out messages.
If the message can't be decoded, then `None` will be stored in
the appropriate position. @@ -371,7 +385,7 @@ type ParamsOfSendMessage = { message: string, abi?: Abi, send_events: boolean -}; +} ``` - `message`: _string_ – Message BOC. - `abi`?: _[Abi](mod_abi.md#Abi)_ – Optional message ABI. @@ -383,7 +397,7 @@ type ParamsOfSendMessage = { ```ts type ResultOfSendMessage = { shard_block_id: string -}; +} ``` - `shard_block_id`: _string_ – The last generated shard block of the message destination account before the message was sent.
This block id must be used as a parameter of the
`wait_for_transaction`. @@ -396,7 +410,7 @@ type ParamsOfWaitForTransaction = { message: string, shard_block_id: string, send_events: boolean -}; +} ``` - `abi`?: _[Abi](mod_abi.md#Abi)_ – Optional ABI for decoding the transaction result.
If it is specified, then the output messages' bodies will be
decoded according to this ABI.

The `abi_decoded` result field will be filled out. @@ -412,7 +426,7 @@ type ParamsOfWaitForTransaction = { type ParamsOfProcessMessage = { message_encode_params: ParamsOfEncodeMessage, send_events: boolean -}; +} ``` - `message_encode_params`: _[ParamsOfEncodeMessage](mod_abi.md#ParamsOfEncodeMessage)_ – Message encode parameters. - `send_events`: _boolean_ – Flag for requesting events sending diff --git a/docs/mod_tvm.md b/docs/mod_tvm.md index 93f301308..46fc977ae 100644 --- a/docs/mod_tvm.md +++ b/docs/mod_tvm.md @@ -62,7 +62,7 @@ type ParamsOfRunExecutor = { execution_options?: ExecutionOptions, abi?: Abi, skip_transaction_check?: boolean -}; +} type ResultOfRunExecutor = { transaction: any, @@ -70,7 +70,7 @@ type ResultOfRunExecutor = { decoded?: DecodedOutput, account: string, fees: TransactionFees -}; +} function run_executor( params: ParamsOfRunExecutor, @@ -118,13 +118,13 @@ type ParamsOfRunTvm = { account: string, execution_options?: ExecutionOptions, abi?: Abi -}; +} type ResultOfRunTvm = { out_messages: string[], decoded?: DecodedOutput, account: string -}; +} function run_tvm( params: ParamsOfRunTvm, @@ -159,11 +159,11 @@ type ParamsOfRunGet = { function_name: string, input?: any, execution_options?: ExecutionOptions -}; +} type ResultOfRunGet = { output: any -}; +} function run_get( params: ParamsOfRunGet, @@ -182,24 +182,39 @@ function run_get( # Types ## TvmErrorCode ```ts -type TvmErrorCode = 401 | 402 | 403 | 404 | 405 | 406 | 407 | 408 | 409 | 410 | 411 | 412 | 413 | 414; +enum TvmErrorCode { + CanNotReadTransaction = 401, + CanNotReadBlockchainConfig = 402, + TransactionAborted = 403, + InternalError = 404, + ActionPhaseFailed = 405, + AccountCodeMissing = 406, + LowBalance = 407, + AccountFrozenOrDeleted = 408, + AccountMissing = 409, + UnknownExecutionError = 410, + InvalidInputStack = 411, + InvalidAccountBoc = 412, + InvalidMessageType = 413, + ContractExecutionError = 414 +} ``` One of the following value: -- `401` -- `402` -- `403` -- `404` -- `405` -- `406` -- `407` -- `408` -- `409` -- `410` -- `411` -- `412` -- `413` -- `414` +- `CanNotReadTransaction = 401` +- `CanNotReadBlockchainConfig = 402` +- `TransactionAborted = 403` +- `InternalError = 404` +- `ActionPhaseFailed = 405` +- `AccountCodeMissing = 406` +- `LowBalance = 407` +- `AccountFrozenOrDeleted = 408` +- `AccountMissing = 409` +- `UnknownExecutionError = 410` +- `InvalidInputStack = 411` +- `InvalidAccountBoc = 412` +- `InvalidMessageType = 413` +- `ContractExecutionError = 414` ## ExecutionOptions @@ -209,7 +224,7 @@ type ExecutionOptions = { block_time?: number, block_lt?: bigint, transaction_lt?: bigint -}; +} ``` - `blockchain_config`?: _string_ – boc with config - `block_time`?: _number_ – time that is used as transaction time @@ -227,7 +242,7 @@ type AccountForExecutor = { type: 'Account' boc: string, unlimited_balance?: boolean -}; +} ``` Depends on value of the `type` field. @@ -261,7 +276,7 @@ type TransactionFees = { out_msgs_fwd_fee: bigint, total_account_fees: bigint, total_output: bigint -}; +} ``` - `in_msg_fwd_fee`: _bigint_ - `storage_fee`: _bigint_ @@ -279,7 +294,7 @@ type ParamsOfRunExecutor = { execution_options?: ExecutionOptions, abi?: Abi, skip_transaction_check?: boolean -}; +} ``` - `message`: _string_ – Input message BOC.
Must be encoded as base64. @@ -297,7 +312,7 @@ type ResultOfRunExecutor = { decoded?: DecodedOutput, account: string, fees: TransactionFees -}; +} ``` - `transaction`: _any_ – Parsed transaction.
In addition to the regular transaction fields there is a
`boc` field encoded with `base64` which contains source
transaction BOC. @@ -316,7 +331,7 @@ type ParamsOfRunTvm = { account: string, execution_options?: ExecutionOptions, abi?: Abi -}; +} ``` - `message`: _string_ – Input message BOC.
Must be encoded as base64. @@ -332,7 +347,7 @@ type ResultOfRunTvm = { out_messages: string[], decoded?: DecodedOutput, account: string -}; +} ``` - `out_messages`: _string[]_ – List of output messages' BOCs.
Encoded as `base64` @@ -348,7 +363,7 @@ type ParamsOfRunGet = { function_name: string, input?: any, execution_options?: ExecutionOptions -}; +} ``` - `account`: _string_ – Account BOC in `base64` - `function_name`: _string_ – Function name @@ -360,7 +375,7 @@ type ParamsOfRunGet = { ```ts type ResultOfRunGet = { output: any -}; +} ``` - `output`: _any_ – Values returned by getmethod on stack diff --git a/docs/mod_utils.md b/docs/mod_utils.md index bc8410d1d..acb10d972 100644 --- a/docs/mod_utils.md +++ b/docs/mod_utils.md @@ -21,11 +21,11 @@ Converts address from any TON format to any TON format type ParamsOfConvertAddress = { address: string, output_format: AddressStringFormat -}; +} type ResultOfConvertAddress = { address: string -}; +} function convert_address( params: ParamsOfConvertAddress, @@ -51,7 +51,7 @@ type AddressStringFormat = { url: boolean, test: boolean, bounce: boolean -}; +} ``` Depends on value of the `type` field. @@ -74,7 +74,7 @@ When _type_ is _'Base64'_ type ParamsOfConvertAddress = { address: string, output_format: AddressStringFormat -}; +} ``` - `address`: _string_ – Account address in any TON format. - `output_format`: _[AddressStringFormat](mod_utils.md#AddressStringFormat)_ – Specify the format to convert to. @@ -84,7 +84,7 @@ type ParamsOfConvertAddress = { ```ts type ResultOfConvertAddress = { address: string -}; +} ``` - `address`: _string_ – Address in the specified format diff --git a/ton_client/src/json_interface/modules.rs b/ton_client/src/json_interface/modules.rs index bb282ddd1..b7e44ad25 100644 --- a/ton_client/src/json_interface/modules.rs +++ b/ton_client/src/json_interface/modules.rs @@ -22,7 +22,7 @@ pub(crate) struct ClientModule; fn register_client(handlers: &mut RuntimeHandlers) { let mut module = ModuleReg::new::(handlers); - module.register_type::(); + module.register_error_code::(); module.register_type::(); module.register_type::(); module.register_type::(); diff --git a/tools/api.json b/tools/api.json index 9f817a1ba..068c92987 100644 --- a/tools/api.json +++ b/tools/api.json @@ -7,7 +7,7 @@ "description": null, "types": [ { - "name": "ErrorCode", + "name": "ClientErrorCode", "type": "EnumOfConsts", "enum_consts": [ { diff --git a/tools/api.ts b/tools/api.ts index 5c950f556..b9c3fe7c0 100644 --- a/tools/api.ts +++ b/tools/api.ts @@ -314,7 +314,7 @@ export abstract class Code { abstract typeVariant(variant: ApiField, indent: string, includeDoc?: boolean): string; - abstract constVariant(variant: ApiConst, includeDoc?: boolean): string; + abstract constVariant(variant: ApiConst, indent: string, includeDoc?: boolean): string; abstract type(type: ApiType, indent: string, includeDoc?: boolean): string; diff --git a/tools/docs.ts b/tools/docs.ts index 34411e936..90036b9eb 100644 --- a/tools/docs.ts +++ b/tools/docs.ts @@ -1,6 +1,5 @@ import { ApiConst, - ApiConstValueIs, ApiEnumOfConsts, ApiEnumOfTypes, ApiField, @@ -134,16 +133,7 @@ export class Docs extends Code { } constVariant(variant: ApiConst): string { - let md = "- \`"; - switch (variant.type) { - case ApiConstValueIs.None: - md += variant.name; - break; - default: - md += variant.value; - break; - } - md += `\`${summaryOf(variant)}\n`; + let md = `- \`${this.code.constVariant(variant, "", false)}\`${summaryOf(variant)}\n`; md += descriptionOf(variant); return md; } diff --git a/tools/ts-code.ts b/tools/ts-code.ts index e8205da9e..c6defbf13 100644 --- a/tools/ts-code.ts +++ b/tools/ts-code.ts @@ -193,19 +193,24 @@ export class ${Code.upperFirst(module.name)}Module { } } - constVariant(variant: ApiConst, _includeDoc?: boolean): string { + constVariant(variant: ApiConst, indent: string, _includeDoc?: boolean): string { + let value = ""; switch (variant.type) { case ApiConstValueIs.String: - return `'${variant.value}'`; + value = `"${variant.value}"`; + break; case ApiConstValueIs.None: - return `'${variant.name}'`; + value = `"${variant.name}"`; + break; case ApiConstValueIs.Bool: - return variant.value; + value = variant.value; + break; case ApiConstValueIs.Number: - return variant.value; - default: - return ""; + value = variant.value; + break; } + return `${indent}${variant.name} = ${value}`; + } type(type: ApiType, indent: string, includeDoc?: boolean): string { @@ -227,7 +232,8 @@ export class ${Code.upperFirst(module.name)}Module { case ApiTypeIs.Array: return `${this.type(type.array_item, indent)}[]`; case ApiTypeIs.EnumOfConsts: - return type.enum_consts.map(c => this.constVariant(c, includeDoc)).join(" | "); + const variants = type.enum_consts.map(c => this.constVariant(c, `${indent} `, includeDoc)); + return `{\n${variants.join(",\n")}\n${indent}}`; case ApiTypeIs.BigInt: return "bigint"; case ApiTypeIs.Any: @@ -244,7 +250,8 @@ export class ${Code.upperFirst(module.name)}Module { } typeDef(type: ApiField, includeDoc?: boolean): string { - return `type ${type.name} = ${this.type(type, "", includeDoc)};\n`; + const decl = type.type === ApiTypeIs.EnumOfConsts ? `enum ${type.name}` : `type ${type.name} =`; + return `${decl} ${this.type(type, "", includeDoc)}\n`; } paramsDecls(paramsInfo: ApiFunctionInfo): string[] { From 79eafe0cdf3decc8f5062de9eef6cc44df106975 Mon Sep 17 00:00:00 2001 From: Michael Vlasov Date: Tue, 22 Dec 2020 21:23:31 +0500 Subject: [PATCH 07/19] FIX: send `GQL_TERMINATE_CONNECTION` and close websocket on leaving ws loop. --- CHANGELOG.md | 5 ++++ ton_client/Cargo.toml | 2 +- ton_client/src/client/wasm_client_env.rs | 3 ++ ton_client/src/net/gql.rs | 38 +++++++++++++----------- ton_client/src/net/websocket_link.rs | 2 ++ ton_sdk/Cargo.toml | 2 +- toncli/Cargo.toml | 2 +- 7 files changed, 33 insertions(+), 21 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index dbbdf1e8a..232591092 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,11 @@ # Release Notes All notable changes to this project will be documented in this file. +## 1.4.1 Dec 23, 2020 + +### Fixed +- send `GQL_TERMINATE_CONNECTION` and close websocket on leaving ws loop. + ## 1.4.0 Dec 18, 2020 ### New diff --git a/ton_client/Cargo.toml b/ton_client/Cargo.toml index e35ad799c..9978fc8f3 100644 --- a/ton_client/Cargo.toml +++ b/ton_client/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "ton_client" -version = "1.4.0" +version = "1.4.1" authors = ["Michael Vlasov"] edition = "2018" license = "Apache-2.0" diff --git a/ton_client/src/client/wasm_client_env.rs b/ton_client/src/client/wasm_client_env.rs index 237eeccce..2b612d331 100644 --- a/ton_client/src/client/wasm_client_env.rs +++ b/ton_client/src/client/wasm_client_env.rs @@ -177,6 +177,9 @@ impl ClientEnv { wasm_bindgen_futures::spawn_local(async move { log::trace!("Start websocket sending loop"); while let Some((string, sender)) = send_stream.next().await { + if string.is_empty() { + break; + } log::trace!("Websocket send: {}", string); let result = ws .send_with_str(&string) diff --git a/ton_client/src/net/gql.rs b/ton_client/src/net/gql.rs index 421d42bde..aaf114953 100644 --- a/ton_client/src/net/gql.rs +++ b/ton_client/src/net/gql.rs @@ -20,7 +20,7 @@ const GQL_CONNECTION_INIT: &str = "connection_init"; const GQL_CONNECTION_ACK: &str = "connection_ack"; const GQL_CONNECTION_ERROR: &str = "connection_error"; const GQL_CONNECTION_KEEP_ALIVE: &str = "ka"; -// const GQL_CONNECTION_TERMINATE: &str = "connection_terminate"; +const GQL_CONNECTION_TERMINATE: &str = "connection_terminate"; const GQL_START: &str = "start"; const GQL_DATA: &str = "data"; const GQL_ERROR: &str = "error"; @@ -50,7 +50,7 @@ pub(crate) enum GraphQLMessageFromClient { ConnectionInit { connection_params: Value, }, - // ConnectionTerminate, + ConnectionTerminate, Start { id: String, query: String, @@ -69,9 +69,9 @@ impl GraphQLMessageFromClient { "type": GQL_CONNECTION_INIT, "payload": connection_params.clone(), }), - // GraphQLMessageFromClient::ConnectionTerminate => json!({ - // "type": GQL_CONNECTION_TERMINATE, - // }), + GraphQLMessageFromClient::ConnectionTerminate => json!({ + "type": GQL_CONNECTION_TERMINATE, + }), GraphQLMessageFromClient::Start { id, query, @@ -97,7 +97,8 @@ impl GraphQLMessageFromClient { "type": GQL_STOP, "id": id, }), - }.to_string() + } + .to_string() } } @@ -124,7 +125,8 @@ pub(crate) enum GraphQLMessageFromServer { impl GraphQLMessageFromServer { pub fn parse(message: &str) -> ClientResult { - let value = serde_json::from_str::(message).map_err(|_| Error::invalid_server_response(message))?; + let value = serde_json::from_str::(message) + .map_err(|_| Error::invalid_server_response(message))?; Ok(match value["type"].as_str().unwrap_or("") { GQL_CONNECTION_ERROR => GraphQLMessageFromServer::ConnectionError { error: value["payload"].clone(), @@ -173,11 +175,14 @@ impl GraphQLOperation { limit: Option, timeout: Option, ) -> Self { - let mut scheme_type: Vec = table.split_terminator("_").map(|word| { - let mut word = word.to_owned(); - word[..1].make_ascii_uppercase(); - word - }).collect(); + let mut scheme_type: Vec = table + .split_terminator("_") + .map(|word| { + let mut word = word.to_owned(); + word[..1].make_ascii_uppercase(); + word + }) + .collect(); scheme_type[0] = scheme_type[0].trim_end_matches("s").to_owned(); let scheme_type: String = scheme_type.join("") + "Filter"; @@ -208,11 +213,7 @@ impl GraphQLOperation { } } - pub fn subscription( - table: &str, - filter: &Value, - fields: &str, - ) -> Self { + pub fn subscription(table: &str, filter: &Value, fields: &str) -> Self { let mut scheme_type = (&table[0..table.len() - 1]).to_owned() + "Filter"; scheme_type[..1].make_ascii_uppercase(); @@ -232,7 +233,8 @@ impl GraphQLOperation { } pub fn post_requests(requests: &[PostRequest]) -> Self { - let query = "mutation postRequests($requests:[Request]){postRequests(requests:$requests)}".to_owned(); + let query = "mutation postRequests($requests:[Request]){postRequests(requests:$requests)}" + .to_owned(); let variables = Some(json!({ "requests": serde_json::json!(requests) })); Self { query, diff --git a/ton_client/src/net/websocket_link.rs b/ton_client/src/net/websocket_link.rs index 7ede44cbf..77b06b2c3 100644 --- a/ton_client/src/net/websocket_link.rs +++ b/ton_client/src/net/websocket_link.rs @@ -194,6 +194,8 @@ impl LinkHandler { phase = self.handle_ws_action(action, &mut ws_sender, phase).await } } + let _ = ws_sender.send(GraphQLMessageFromClient::ConnectionTerminate.get_message()).await; + let _ = ws_sender.send(String::new()).await; phase } diff --git a/ton_sdk/Cargo.toml b/ton_sdk/Cargo.toml index a91fed038..3ffca8f19 100644 --- a/ton_sdk/Cargo.toml +++ b/ton_sdk/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "ton_sdk" -version = "1.4.0" +version = "1.4.1" edition = "2018" license = "Apache-2.0" diff --git a/toncli/Cargo.toml b/toncli/Cargo.toml index e5dd1e2fa..4d9b09471 100644 --- a/toncli/Cargo.toml +++ b/toncli/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "toncli" -version = "1.4.0" +version = "1.4.1" description = "TON CLient Command Line Tool" authors = ["TON DEV SOLUTIONS LTD "] repository = "https://github.com/tonlabs/TON-SDK" From 60ba505ec63be9c315a1216c25a03480a22f9107 Mon Sep 17 00:00:00 2001 From: Alexey Vavilin Date: Wed, 23 Dec 2020 17:09:23 +0300 Subject: [PATCH 08/19] Multiple endpoints in config. Some refactor --- ton_client/src/client/client.rs | 8 +- ton_client/src/client/tests.rs | 2 - ton_client/src/debot/dengine.rs | 2 +- ton_client/src/error.rs | 2 +- ton_client/src/json_interface/modules.rs | 8 +- ton_client/src/net/mod.rs | 343 ++--------------------- ton_client/src/net/queries.rs | 142 ++++++++++ ton_client/src/net/server_link.rs | 52 +++- ton_client/src/net/subscriptions.rs | 123 ++++++++ ton_client/src/net/types.rs | 106 +++++++ ton_client/src/net/websocket_link.rs | 42 ++- ton_client/src/tests/common.rs | 2 +- ton_client/src/tests/mod.rs | 2 +- 13 files changed, 474 insertions(+), 360 deletions(-) create mode 100644 ton_client/src/net/queries.rs create mode 100644 ton_client/src/net/subscriptions.rs create mode 100644 ton_client/src/net/types.rs diff --git a/ton_client/src/client/client.rs b/ton_client/src/client/client.rs index 5308f9d8f..a550b4da7 100644 --- a/ton_client/src/client/client.rs +++ b/ton_client/src/client/client.rs @@ -26,7 +26,7 @@ use crate::crypto::boxes::SigningBox; use crate::debot::DEngine; use crate::json_interface::request::Request; use crate::json_interface::interop::ResponseType; -use crate::net::{NetworkConfig, ServerLink, SubscriptionAction}; +use crate::net::{NetworkConfig, ServerLink, subscriptions::SubscriptionAction}; #[cfg(not(feature = "wasm"))] use super::std_client_env::ClientEnv; @@ -66,7 +66,9 @@ impl ClientContext { pub fn new(config: ClientConfig) -> ClientResult { let env = Arc::new(ClientEnv::new()?); - let server_link = if !config.network.server_address.is_empty() { + let server_link = if config.network.server_address.is_some() + || config.network.endpoints.is_some() + { if config.network.out_of_sync_threshold > config.abi.message_expiration_timeout / 2 { return Err(Error::invalid_config(format!( r#"`out_of_sync_threshold` can not be more then `message_expiration_timeout / 2`. @@ -75,7 +77,7 @@ Note that default values are used if parameters are omitted in config"#, config.network.out_of_sync_threshold, config.abi.message_expiration_timeout ))); } - Some(ServerLink::new(config.network.clone(), env.clone())) + Some(ServerLink::new(config.network.clone(), env.clone())?) } else { None }; diff --git a/ton_client/src/client/tests.rs b/ton_client/src/client/tests.rs index 25cf219ad..06a47bc51 100644 --- a/ton_client/src/client/tests.rs +++ b/ton_client/src/client/tests.rs @@ -14,7 +14,6 @@ fn test_config_fields() { "message_expiration_timeout": null }, "network": { - "server_address": "mandatory", "network_retries_count": 100 } } @@ -26,7 +25,6 @@ fn test_config_fields() { default_mnemonic_word_count() ); assert_eq!(config.network.network_retries_count, 100); - assert_eq!(config.network.server_address, "mandatory"); } #[test] diff --git a/ton_client/src/debot/dengine.rs b/ton_client/src/debot/dengine.rs index 76eb6d50a..64c06b526 100644 --- a/ton_client/src/debot/dengine.rs +++ b/ton_client/src/debot/dengine.rs @@ -28,7 +28,7 @@ fn create_client(url: &str) -> Result { abi: AbiConfig::default(), crypto: CryptoConfig::default(), network: NetworkConfig { - server_address: url.to_owned(), + server_address: Some(url.to_owned()), ..Default::default() }, }; diff --git a/ton_client/src/error.rs b/ton_client/src/error.rs index 60d46cb43..4d5305115 100644 --- a/ton_client/src/error.rs +++ b/ton_client/src/error.rs @@ -55,7 +55,7 @@ impl ClientError { } pub(crate) fn add_network_url(mut self, client: &crate::net::ServerLink) -> ClientError { - self.data["config_server"] = client.config_server().into(); + self.data["config_servers"] = client.config_servers().into(); if let Some(url) = client.query_url() { self.data["query_url"] = url.into(); diff --git a/ton_client/src/json_interface/modules.rs b/ton_client/src/json_interface/modules.rs index c746c1e78..ceeb3495f 100644 --- a/ton_client/src/json_interface/modules.rs +++ b/ton_client/src/json_interface/modules.rs @@ -313,17 +313,17 @@ fn register_net(handlers: &mut RuntimeHandlers) { module.register_async_fn( crate::net::query, - crate::net::query_api, + crate::net::queries::query_api, ); module.register_async_fn( crate::net::query_collection, - crate::net::query_collection_api, + crate::net::queries::query_collection_api, ); module.register_async_fn( crate::net::wait_for_collection, - crate::net::wait_for_collection_api, + crate::net::queries::wait_for_collection_api, ); - module.register_async_fn(crate::net::unsubscribe, crate::net::unsubscribe_api); + module.register_async_fn(crate::net::unsubscribe, crate::net::subscriptions::unsubscribe_api); module.register_async_fn_with_callback( super::net::subscribe_collection, super::net::subscribe_collection_api, diff --git a/ton_client/src/net/mod.rs b/ton_client/src/net/mod.rs index 1dd8aeb77..fc2288456 100644 --- a/ton_client/src/net/mod.rs +++ b/ton_client/src/net/mod.rs @@ -13,343 +13,38 @@ use crate::client::ClientContext; use crate::error::ClientResult; -use futures::{Future, FutureExt, StreamExt}; -use rand::RngCore; -use tokio::sync::mpsc::{channel, Sender}; mod errors; - -pub use errors::{Error, ErrorCode}; - mod gql; +pub(crate) mod queries; mod websocket_link; mod server_link; mod server_info; +pub(crate) mod subscriptions; +mod types; +pub use errors::{Error, ErrorCode}; pub use gql::{OrderBy, SortDirection}; +pub use queries::{ + query, query_collection, wait_for_collection, + ParamsOfQuery, ParamsOfQueryCollection, ParamsOfWaitForCollection, ResultOfQuery, + ResultOfQueryCollection, ResultOfWaitForCollection, +}; +pub use subscriptions::{ + subscribe_collection, unsubscribe, + ParamsOfSubscribeCollection, ResultOfSubscribeCollection, ResultOfSubscription, + SubscriptionResponseType +}; +pub use types::{ + NetworkConfig, + MESSAGES_TABLE_NAME, CONTRACTS_TABLE_NAME, BLOCKS_TABLE_NAME, TRANSACTIONS_TABLE_NAME +}; + pub(crate) use server_link::{ServerLink, MAX_TIMEOUT}; -use serde::{Deserialize, Deserializer}; -use serde_json::Value; #[cfg(test)] mod tests; -pub const MESSAGES_TABLE_NAME: &str = "messages"; -pub const CONTRACTS_TABLE_NAME: &str = "accounts"; -pub const BLOCKS_TABLE_NAME: &str = "blocks"; -pub const TRANSACTIONS_TABLE_NAME: &str = "transactions"; - -pub fn default_network_retries_count() -> i8 { - 5 -} - -pub fn default_message_retries_count() -> i8 { - 5 -} - -pub fn default_message_processing_timeout() -> u32 { - 40000 -} - -pub fn default_wait_for_timeout() -> u32 { - 40000 -} - -pub fn default_out_of_sync_threshold() -> u32 { - 15000 -} - -fn deserialize_network_retries_count<'de, D: Deserializer<'de>>( - deserializer: D, -) -> Result { - Ok(Option::deserialize(deserializer)?.unwrap_or(default_network_retries_count())) -} - -fn deserialize_message_retries_count<'de, D: Deserializer<'de>>( - deserializer: D, -) -> Result { - Ok(Option::deserialize(deserializer)?.unwrap_or(default_message_retries_count())) -} - -fn deserialize_message_processing_timeout<'de, D: Deserializer<'de>>( - deserializer: D, -) -> Result { - Ok(Option::deserialize(deserializer)?.unwrap_or(default_message_processing_timeout())) -} - -fn deserialize_wait_for_timeout<'de, D: Deserializer<'de>>( - deserializer: D, -) -> Result { - Ok(Option::deserialize(deserializer)?.unwrap_or(default_wait_for_timeout())) -} - -fn deserialize_out_of_sync_threshold<'de, D: Deserializer<'de>>( - deserializer: D, -) -> Result { - Ok(Option::deserialize(deserializer)?.unwrap_or(default_out_of_sync_threshold())) -} - -#[derive(Serialize, Deserialize, Debug, Clone, ApiType)] -pub struct NetworkConfig { - pub server_address: String, - #[serde(default = "default_network_retries_count", - deserialize_with = "deserialize_network_retries_count")] - pub network_retries_count: i8, - #[serde(default = "default_message_retries_count", - deserialize_with = "deserialize_message_retries_count")] - pub message_retries_count: i8, - #[serde(default = "default_message_processing_timeout", - deserialize_with = "deserialize_message_processing_timeout")] - pub message_processing_timeout: u32, - #[serde(default = "default_wait_for_timeout", - deserialize_with = "deserialize_wait_for_timeout")] - pub wait_for_timeout: u32, - #[serde(default = "default_out_of_sync_threshold", - deserialize_with = "deserialize_out_of_sync_threshold")] - pub out_of_sync_threshold: u32, - pub access_key: Option, -} - -impl Default for NetworkConfig { - fn default() -> Self { - Self { - server_address: String::new(), - network_retries_count: default_network_retries_count(), - message_retries_count: default_message_retries_count(), - message_processing_timeout: default_message_processing_timeout(), - wait_for_timeout: default_wait_for_timeout(), - out_of_sync_threshold: default_out_of_sync_threshold(), - access_key: None, - } - } -} - -#[derive(Serialize, Deserialize, ApiType, Clone)] -pub struct ParamsOfQuery { - /// GraphQL query text. - pub query: String, - /// Variables used in query. Must be a map with named values that - /// can be used in query. - pub variables: Option, -} - -#[derive(Serialize, Deserialize, ApiType, Clone)] -pub struct ResultOfQuery { - /// Result provided by DAppServer. - pub result: Value, -} - -#[derive(Serialize, Deserialize, ApiType, Clone)] -pub struct ParamsOfQueryCollection { - /// Collection name (accounts, blocks, transactions, messages, block_signatures) - pub collection: String, - /// Collection filter - pub filter: Option, - /// Projection (result) string - pub result: String, - /// Sorting order - pub order: Option>, - /// Number of documents to return - pub limit: Option, -} - -#[derive(Serialize, Deserialize, ApiType, Clone)] -pub struct ResultOfQueryCollection { - /// Objects that match the provided criteria - pub result: Vec, -} - -#[derive(Serialize, Deserialize, ApiType, Clone, Default)] -pub struct ParamsOfWaitForCollection { - /// Collection name (accounts, blocks, transactions, messages, block_signatures) - pub collection: String, - /// Collection filter - pub filter: Option, - /// Projection (result) string - pub result: String, - /// Query timeout - pub timeout: Option, -} - -#[derive(Serialize, Deserialize, ApiType, Clone)] -pub struct ResultOfWaitForCollection { - /// First found object that matches the provided criteria - pub result: serde_json::Value, -} - -#[derive(Serialize, Deserialize, Clone, num_derive::FromPrimitive)] -pub enum SubscriptionResponseType { - Ok = 100, - Error = 101, -} - -#[derive(Serialize, Deserialize, ApiType, Clone)] -pub struct ParamsOfSubscribeCollection { - /// Collection name (accounts, blocks, transactions, messages, block_signatures) - pub collection: String, - /// Collection filter - pub filter: Option, - /// Projection (result) string - pub result: String, -} - -#[derive(Serialize, Deserialize, ApiType, Clone)] -pub struct ResultOfSubscribeCollection { - /// Subscription handle. Must be closed with `unsubscribe` - pub handle: u32, -} - -#[derive(Serialize, Deserialize, ApiType, Clone, Debug)] -pub struct ResultOfSubscription { - /// First appeared object that matches the provided criteria - pub result: serde_json::Value, -} - -#[derive(PartialEq, Debug)] -pub(crate) enum SubscriptionAction { - Finish, -} - -async fn add_subscription_handle(context: &ClientContext, handle: u32, sender: Sender) { - context.net.subscriptions.lock().await.insert(handle, sender); -} - -async fn extract_subscription_handle(context: &ClientContext, handle: &u32) -> Option> { - context.net.subscriptions.lock().await.remove(handle) -} - -/// Performs DAppServer GraphQL query. -#[api_function] -pub async fn query( - context: std::sync::Arc, - params: ParamsOfQuery, -) -> ClientResult { - let client = context.get_server_link()?; - let result = client.query( - ¶ms.query, - params.variables, - None, - ).await.map_err(|err| Error::queries_query_failed(err).add_network_url(client))?; - - let result = serde_json::from_value(result).map_err(|err| { - Error::queries_query_failed(format!("Can not parse result: {}", err)).add_network_url(client) - })?; - - Ok(ResultOfQuery { result }) -} - -/// Queries collection data -/// -/// Queries data that satisfies the `filter` conditions, -/// limits the number of returned records and orders them. -/// The projection fields are limited to `result` fields -#[api_function] -pub async fn query_collection( - context: std::sync::Arc, - params: ParamsOfQueryCollection, -) -> ClientResult { - let client = context.get_server_link()?; - let result = client.query_collection( - ¶ms.collection, - ¶ms.filter.unwrap_or(json!({})), - ¶ms.result, - params.order, - params.limit, - None, - ).await.map_err(|err| Error::queries_query_failed(err).add_network_url(client))?; - - let result = serde_json::from_value(result).map_err(|err| { - Error::queries_query_failed(format!("Can not parse result: {}", err)).add_network_url(client) - })?; - - Ok(ResultOfQueryCollection { result }) -} - -/// Returns an object that fulfills the conditions or waits for its appearance -/// -/// Triggers only once. -/// If object that satisfies the `filter` conditions -/// already exists - returns it immediately. -/// If not - waits for insert/update of data within the specified `timeout`, -/// and returns it. -/// The projection fields are limited to `result` fields -#[api_function] -pub async fn wait_for_collection( - context: std::sync::Arc, - params: ParamsOfWaitForCollection, -) -> ClientResult { - let client = context.get_server_link()?; - let result = client.wait_for( - ¶ms.collection, - ¶ms.filter.unwrap_or(json!({})), - ¶ms.result, - params.timeout, - ).await.map_err(|err| Error::queries_wait_for_failed(err).add_network_url(client))?; - - Ok(ResultOfWaitForCollection { result }) -} - -async fn create_subscription( - context: std::sync::Arc, params: &ParamsOfSubscribeCollection, -) -> ClientResult { - let client = context.get_server_link()?; - client.subscribe( - ¶ms.collection, - params.filter.as_ref().unwrap_or(&json!({})), - ¶ms.result, - ).await.map_err(|err| Error::queries_subscribe_failed(err).add_network_url(client)) -} - -pub async fn subscribe_collection + Send>( - context: std::sync::Arc, - params: ParamsOfSubscribeCollection, - callback: impl Fn(ClientResult) -> F + Send + Sync + 'static, -) -> ClientResult { - let handle = rand::thread_rng().next_u32(); - - let mut subscription = Some(create_subscription(context.clone(), ¶ms).await?); - - let (sender, mut receiver) = channel(1); - add_subscription_handle(&context, handle, sender).await; - - // spawn thread which reads subscription stream and calls callback with data - context.clone().env.spawn(Box::pin(async move { - let subscription = subscription.take().unwrap(); - let mut data_stream = subscription.data_stream.fuse(); - let wait_action = receiver.recv().fuse(); - futures::pin_mut!(wait_action); - loop { - futures::select!( - // waiting next subscription data - data = data_stream.select_next_some() => { - callback(data.map(|data| ResultOfSubscription { result: data })).await - }, - // waiting for some action with subscription (the only action is Finish) - _action = wait_action => { - break; - } - ); - } - subscription.unsubscribe.await; - })); - - Ok(ResultOfSubscribeCollection { handle }) -} - -/// Cancels a subscription -/// -/// Cancels a subscription specified by its handle. -#[api_function] -pub async fn unsubscribe( - context: std::sync::Arc, - params: ResultOfSubscribeCollection, -) -> ClientResult<()> { - if let Some(mut sender) = extract_subscription_handle(&context, ¶ms.handle).await { - let _ = sender.send(SubscriptionAction::Finish).await; - } - Ok(()) -} - /// Suspends network module to stop any network activity #[api_function] pub async fn suspend( diff --git a/ton_client/src/net/queries.rs b/ton_client/src/net/queries.rs new file mode 100644 index 000000000..22809e545 --- /dev/null +++ b/ton_client/src/net/queries.rs @@ -0,0 +1,142 @@ +/* +* Copyright 2018-2020 TON DEV SOLUTIONS LTD. +* +* Licensed under the SOFTWARE EVALUATION License (the "License"); you may not use +* this file except in compliance with the License. +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific TON DEV software governing permissions and +* limitations under the License. +*/ + +use crate::client::ClientContext; +use crate::error::ClientResult; +use super::{Error, OrderBy}; +use serde_json::Value; + +#[derive(Serialize, Deserialize, ApiType, Clone)] +pub struct ParamsOfQuery { + /// GraphQL query text. + pub query: String, + /// Variables used in query. Must be a map with named values that + /// can be used in query. + pub variables: Option, +} + +#[derive(Serialize, Deserialize, ApiType, Clone)] +pub struct ResultOfQuery { + /// Result provided by DAppServer. + pub result: Value, +} + +#[derive(Serialize, Deserialize, ApiType, Clone)] +pub struct ParamsOfQueryCollection { + /// Collection name (accounts, blocks, transactions, messages, block_signatures) + pub collection: String, + /// Collection filter + pub filter: Option, + /// Projection (result) string + pub result: String, + /// Sorting order + pub order: Option>, + /// Number of documents to return + pub limit: Option, +} + +#[derive(Serialize, Deserialize, ApiType, Clone)] +pub struct ResultOfQueryCollection { + /// Objects that match the provided criteria + pub result: Vec, +} + +#[derive(Serialize, Deserialize, ApiType, Clone, Default)] +pub struct ParamsOfWaitForCollection { + /// Collection name (accounts, blocks, transactions, messages, block_signatures) + pub collection: String, + /// Collection filter + pub filter: Option, + /// Projection (result) string + pub result: String, + /// Query timeout + pub timeout: Option, +} + +#[derive(Serialize, Deserialize, ApiType, Clone)] +pub struct ResultOfWaitForCollection { + /// First found object that matches the provided criteria + pub result: serde_json::Value, +} + + +/// Performs DAppServer GraphQL query. +#[api_function] +pub async fn query( + context: std::sync::Arc, + params: ParamsOfQuery, +) -> ClientResult { + let client = context.get_server_link()?; + let result = client.query( + ¶ms.query, + params.variables, + None, + ).await.map_err(|err| Error::queries_query_failed(err).add_network_url(client))?; + + let result = serde_json::from_value(result).map_err(|err| { + Error::queries_query_failed(format!("Can not parse result: {}", err)).add_network_url(client) + })?; + + Ok(ResultOfQuery { result }) +} + +/// Queries collection data +/// +/// Queries data that satisfies the `filter` conditions, +/// limits the number of returned records and orders them. +/// The projection fields are limited to `result` fields +#[api_function] +pub async fn query_collection( + context: std::sync::Arc, + params: ParamsOfQueryCollection, +) -> ClientResult { + let client = context.get_server_link()?; + let result = client.query_collection( + ¶ms.collection, + ¶ms.filter.unwrap_or(json!({})), + ¶ms.result, + params.order, + params.limit, + None, + ).await.map_err(|err| Error::queries_query_failed(err).add_network_url(client))?; + + let result = serde_json::from_value(result).map_err(|err| { + Error::queries_query_failed(format!("Can not parse result: {}", err)).add_network_url(client) + })?; + + Ok(ResultOfQueryCollection { result }) +} + +/// Returns an object that fulfills the conditions or waits for its appearance +/// +/// Triggers only once. +/// If object that satisfies the `filter` conditions +/// already exists - returns it immediately. +/// If not - waits for insert/update of data within the specified `timeout`, +/// and returns it. +/// The projection fields are limited to `result` fields +#[api_function] +pub async fn wait_for_collection( + context: std::sync::Arc, + params: ParamsOfWaitForCollection, +) -> ClientResult { + let client = context.get_server_link()?; + let result = client.wait_for( + ¶ms.collection, + ¶ms.filter.unwrap_or(json!({})), + ¶ms.result, + params.timeout, + ).await.map_err(|err| Error::queries_wait_for_failed(err).add_network_url(client))?; + + Ok(ResultOfWaitForCollection { result }) +} diff --git a/ton_client/src/net/server_link.rs b/ton_client/src/net/server_link.rs index 9652abb73..5d943d449 100644 --- a/ton_client/src/net/server_link.rs +++ b/ton_client/src/net/server_link.rs @@ -17,6 +17,7 @@ use crate::net::gql::{GraphQLOperation, GraphQLOperationEvent, OrderBy, PostRequ use crate::net::server_info::ServerInfo; use crate::net::websocket_link::WebsocketLink; use crate::net::{Error, NetworkConfig}; +use super::websocket_link::WsConfig; use futures::{Future, Stream, StreamExt}; use serde_json::Value; use std::collections::HashMap; @@ -33,6 +34,7 @@ pub(crate) struct Subscription { pub(crate) struct ServerLink { config: NetworkConfig, + endpoints: Vec, client_env: Arc, suspended: AtomicBool, server_info: tokio::sync::RwLock>, @@ -42,15 +44,23 @@ pub(crate) struct ServerLink { } impl ServerLink { - pub fn new(config: NetworkConfig, client_env: Arc) -> Self { - ServerLink { + pub fn new(config: NetworkConfig, client_env: Arc) -> ClientResult { + let endpoints = config.endpoints.clone() + .or(config.server_address.clone().map(|address| vec![address])) + .ok_or(crate::client::Error::net_module_not_init())?; + if endpoints.len() == 0 { + return Err(crate::client::Error::net_module_not_init()); + } + + Ok(ServerLink { config: config.clone(), + endpoints, client_env: client_env.clone(), suspended: AtomicBool::new(false), query_url: std::sync::RwLock::new(None), server_info: tokio::sync::RwLock::new(None), - websocket_link: WebsocketLink::new(config, client_env.clone()), - } + websocket_link: WebsocketLink::new(client_env.clone()), + }) } async fn query_by_url(&self, address: &str, query: &str) -> ClientResult { @@ -96,11 +106,27 @@ impl ServerLink { } async fn init(&self, config: &NetworkConfig) -> ClientResult { - let queries_server = ServerInfo::expand_address(&config.server_address); - let server_info = ServerInfo::fetch(self.client_env.clone(), &queries_server).await?; + let mut futures = vec![]; + for address in &self.endpoints { + let queries_server = ServerInfo::expand_address(&address); + futures.push(Box::pin(async move { + ServerInfo::fetch(self.client_env.clone(), &queries_server).await + })); + } + + let mut server_info = Err(crate::client::Error::net_module_not_init()); + while futures.len() != 0 { + let (result, _, remain_futures) = futures::future::select_all(futures).await; + futures = remain_futures; + server_info = result; + if server_info.is_ok() { + break; + } + } + let server_info = server_info?; if server_info.server_version.supports_time { - self.check_time_delta(&queries_server, config).await?; + self.check_time_delta(&server_info.query_url, config).await?; } Ok(server_info) @@ -121,6 +147,12 @@ impl ServerLink { } let inited_data = self.init(&self.config).await?; + + self.websocket_link.set_config(WsConfig { + url: inited_data.subscription_url.clone(), + access_key: self.config.access_key.clone() + }).await; + *self.query_url.write().unwrap() = Some(inited_data.query_url.clone()); *data = Some(inited_data); @@ -131,8 +163,8 @@ impl ServerLink { &self.config } - pub fn config_server(&self) -> &str { - &self.config.server_address + pub fn config_servers(&self) -> &[String] { + &self.endpoints } pub fn query_url(&self) -> Option { @@ -146,6 +178,8 @@ impl ServerLink { filter: &Value, fields: &str, ) -> ClientResult { + self.ensure_info().await?; + let event_receiver = self .websocket_link .start_operation(GraphQLOperation::subscription(table, filter, fields)) diff --git a/ton_client/src/net/subscriptions.rs b/ton_client/src/net/subscriptions.rs new file mode 100644 index 000000000..a94b05568 --- /dev/null +++ b/ton_client/src/net/subscriptions.rs @@ -0,0 +1,123 @@ +/* +* Copyright 2018-2020 TON DEV SOLUTIONS LTD. +* +* Licensed under the SOFTWARE EVALUATION License (the "License"); you may not use +* this file except in compliance with the License. +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific TON DEV software governing permissions and +* limitations under the License. +*/ + +use crate::client::ClientContext; +use crate::error::ClientResult; +use super::Error; +use futures::{Future, FutureExt, StreamExt}; +use rand::RngCore; +use tokio::sync::mpsc::{channel, Sender}; + + +#[derive(Serialize, Deserialize, Clone, num_derive::FromPrimitive)] +pub enum SubscriptionResponseType { + Ok = 100, + Error = 101, +} + +#[derive(Serialize, Deserialize, ApiType, Clone)] +pub struct ParamsOfSubscribeCollection { + /// Collection name (accounts, blocks, transactions, messages, block_signatures) + pub collection: String, + /// Collection filter + pub filter: Option, + /// Projection (result) string + pub result: String, +} + +#[derive(Serialize, Deserialize, ApiType, Clone)] +pub struct ResultOfSubscribeCollection { + /// Subscription handle. Must be closed with `unsubscribe` + pub handle: u32, +} + +#[derive(Serialize, Deserialize, ApiType, Clone, Debug)] +pub struct ResultOfSubscription { + /// First appeared object that matches the provided criteria + pub result: serde_json::Value, +} + +#[derive(PartialEq, Debug)] +pub(crate) enum SubscriptionAction { + Finish, +} + +async fn add_subscription_handle(context: &ClientContext, handle: u32, sender: Sender) { + context.net.subscriptions.lock().await.insert(handle, sender); +} + +async fn extract_subscription_handle(context: &ClientContext, handle: &u32) -> Option> { + context.net.subscriptions.lock().await.remove(handle) +} + + +async fn create_subscription( + context: std::sync::Arc, params: &ParamsOfSubscribeCollection, +) -> ClientResult { + let client = context.get_server_link()?; + client.subscribe( + ¶ms.collection, + params.filter.as_ref().unwrap_or(&json!({})), + ¶ms.result, + ).await.map_err(|err| Error::queries_subscribe_failed(err).add_network_url(client)) +} + +pub async fn subscribe_collection + Send>( + context: std::sync::Arc, + params: ParamsOfSubscribeCollection, + callback: impl Fn(ClientResult) -> F + Send + Sync + 'static, +) -> ClientResult { + let handle = rand::thread_rng().next_u32(); + + let mut subscription = Some(create_subscription(context.clone(), ¶ms).await?); + + let (sender, mut receiver) = channel(1); + add_subscription_handle(&context, handle, sender).await; + + // spawn thread which reads subscription stream and calls callback with data + context.clone().env.spawn(Box::pin(async move { + let subscription = subscription.take().unwrap(); + let mut data_stream = subscription.data_stream.fuse(); + let wait_action = receiver.recv().fuse(); + futures::pin_mut!(wait_action); + loop { + futures::select!( + // waiting next subscription data + data = data_stream.select_next_some() => { + callback(data.map(|data| ResultOfSubscription { result: data })).await + }, + // waiting for some action with subscription (the only action is Finish) + _action = wait_action => { + break; + } + ); + } + subscription.unsubscribe.await; + })); + + Ok(ResultOfSubscribeCollection { handle }) +} + +/// Cancels a subscription +/// +/// Cancels a subscription specified by its handle. +#[api_function] +pub async fn unsubscribe( + context: std::sync::Arc, + params: ResultOfSubscribeCollection, +) -> ClientResult<()> { + if let Some(mut sender) = extract_subscription_handle(&context, ¶ms.handle).await { + let _ = sender.send(SubscriptionAction::Finish).await; + } + Ok(()) +} diff --git a/ton_client/src/net/types.rs b/ton_client/src/net/types.rs new file mode 100644 index 000000000..5d23fcc85 --- /dev/null +++ b/ton_client/src/net/types.rs @@ -0,0 +1,106 @@ +/* +* Copyright 2018-2020 TON DEV SOLUTIONS LTD. +* +* Licensed under the SOFTWARE EVALUATION License (the "License"); you may not use +* this file except in compliance with the License. +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific TON DEV software governing permissions and +* limitations under the License. +*/ + +use serde::{Deserialize, Deserializer}; + +pub const MESSAGES_TABLE_NAME: &str = "messages"; +pub const CONTRACTS_TABLE_NAME: &str = "accounts"; +pub const BLOCKS_TABLE_NAME: &str = "blocks"; +pub const TRANSACTIONS_TABLE_NAME: &str = "transactions"; + +pub fn default_network_retries_count() -> i8 { + 5 +} + +pub fn default_message_retries_count() -> i8 { + 5 +} + +pub fn default_message_processing_timeout() -> u32 { + 40000 +} + +pub fn default_wait_for_timeout() -> u32 { + 40000 +} + +pub fn default_out_of_sync_threshold() -> u32 { + 15000 +} + +fn deserialize_network_retries_count<'de, D: Deserializer<'de>>( + deserializer: D, +) -> Result { + Ok(Option::deserialize(deserializer)?.unwrap_or(default_network_retries_count())) +} + +fn deserialize_message_retries_count<'de, D: Deserializer<'de>>( + deserializer: D, +) -> Result { + Ok(Option::deserialize(deserializer)?.unwrap_or(default_message_retries_count())) +} + +fn deserialize_message_processing_timeout<'de, D: Deserializer<'de>>( + deserializer: D, +) -> Result { + Ok(Option::deserialize(deserializer)?.unwrap_or(default_message_processing_timeout())) +} + +fn deserialize_wait_for_timeout<'de, D: Deserializer<'de>>( + deserializer: D, +) -> Result { + Ok(Option::deserialize(deserializer)?.unwrap_or(default_wait_for_timeout())) +} + +fn deserialize_out_of_sync_threshold<'de, D: Deserializer<'de>>( + deserializer: D, +) -> Result { + Ok(Option::deserialize(deserializer)?.unwrap_or(default_out_of_sync_threshold())) +} + +#[derive(Serialize, Deserialize, Debug, Clone, ApiType)] +pub struct NetworkConfig { + pub server_address: Option, + pub endpoints: Option>, + #[serde(default = "default_network_retries_count", + deserialize_with = "deserialize_network_retries_count")] + pub network_retries_count: i8, + #[serde(default = "default_message_retries_count", + deserialize_with = "deserialize_message_retries_count")] + pub message_retries_count: i8, + #[serde(default = "default_message_processing_timeout", + deserialize_with = "deserialize_message_processing_timeout")] + pub message_processing_timeout: u32, + #[serde(default = "default_wait_for_timeout", + deserialize_with = "deserialize_wait_for_timeout")] + pub wait_for_timeout: u32, + #[serde(default = "default_out_of_sync_threshold", + deserialize_with = "deserialize_out_of_sync_threshold")] + pub out_of_sync_threshold: u32, + pub access_key: Option, +} + +impl Default for NetworkConfig { + fn default() -> Self { + Self { + server_address: None, + endpoints: None, + network_retries_count: default_network_retries_count(), + message_retries_count: default_message_retries_count(), + message_processing_timeout: default_message_processing_timeout(), + wait_for_timeout: default_wait_for_timeout(), + out_of_sync_threshold: default_out_of_sync_threshold(), + access_key: None, + } + } +} diff --git a/ton_client/src/net/websocket_link.rs b/ton_client/src/net/websocket_link.rs index 7ede44cbf..a64d290e1 100644 --- a/ton_client/src/net/websocket_link.rs +++ b/ton_client/src/net/websocket_link.rs @@ -18,7 +18,7 @@ use crate::net::gql::{ GraphQLMessageFromClient, GraphQLMessageFromServer, GraphQLOperation, GraphQLOperationEvent, }; use crate::net::server_info::ServerInfo; -use crate::net::{Error, NetworkConfig}; +use crate::net::Error; use futures::stream::{Fuse, FusedStream}; use futures::Sink; use futures::{SinkExt, StreamExt}; @@ -29,6 +29,12 @@ use tokio::sync::mpsc::{channel, Receiver, Sender}; type WSSender = Pin + Send>>; +#[derive(Clone, Debug)] +pub(crate) struct WsConfig { + pub url: String, + pub access_key: Option, +} + #[derive(Debug)] enum HandlerAction { StartOperation(GraphQLOperation, Sender), @@ -38,6 +44,8 @@ enum HandlerAction { Resume, CheckKeepAlivePassed, + + SetConfig(WsConfig), } impl HandlerAction { @@ -56,9 +64,9 @@ pub(crate) struct WebsocketLink { } impl WebsocketLink { - pub fn new(config: NetworkConfig, client_env: Arc) -> Self { + pub fn new(client_env: Arc) -> Self { Self { - handler_action_sender: LinkHandler::run(config, client_env), + handler_action_sender: LinkHandler::run(client_env), } } @@ -85,6 +93,10 @@ impl WebsocketLink { self.send_action_to_handler(HandlerAction::Resume).await; } + pub async fn set_config(&self, config: WsConfig) { + self.send_action_to_handler(HandlerAction::SetConfig(config)).await; + } + async fn send_action_to_handler(&self, action: HandlerAction) { action.send(&mut self.handler_action_sender.clone()).await } @@ -117,7 +129,7 @@ enum Phase { } pub(crate) struct LinkHandler { - config: NetworkConfig, + config: Option, client_env: Arc, action_receiver: Fuse>, internal_action_sender: Sender, @@ -132,12 +144,12 @@ async fn ws_send(ws: &mut WSSender, message: GraphQLMessageFromClient) { } impl LinkHandler { - fn run(config: NetworkConfig, client_env: Arc) -> Sender { + fn run(client_env: Arc) -> Sender { let (action_sender, action_receiver) = channel(1); let (internal_action_sender, internal_action_receiver) = channel(1); client_env.clone().spawn(Box::pin(async move { LinkHandler { - config, + config: None, client_env, action_receiver: action_receiver.fuse(), internal_action_sender, @@ -210,17 +222,18 @@ impl LinkHandler { HandlerAction::Suspend => Phase::Idle, HandlerAction::Resume => Phase::Connecting, HandlerAction::CheckKeepAlivePassed => Phase::Idle, + HandlerAction::SetConfig(config) => { + self.config = Some(config); + Phase::Idle + } } } async fn connect(&mut self) -> ClientResult { self.keep_alive = KeepAlive::WaitFirst; - let server_info = ServerInfo::fetch( - self.client_env.clone(), - &ServerInfo::expand_address(&self.config.server_address), - ) - .await?; - let address = server_info.subscription_url; + let config = self.config + .clone() + .ok_or(crate::client::Error::invalid_config("No websocket config".to_owned()))?; let mut headers = HashMap::new(); headers.insert("Sec-WebSocket-Protocol".into(), "graphql-ws".into()); for (name, value) in ServerInfo::http_headers() { @@ -228,11 +241,11 @@ impl LinkHandler { } let mut ws = self .client_env - .websocket_connect(&address, Some(headers)) + .websocket_connect(&config.url, Some(headers)) .await; if let Ok(ref mut ws) = ws { let mut connection_params = json!({}); - if let Some(access_key) = &self.config.access_key { + if let Some(access_key) = &config.access_key { connection_params["accessKey"] = access_key.as_str().into(); } let init_message = GraphQLMessageFromClient::ConnectionInit { connection_params }; @@ -282,6 +295,7 @@ impl LinkHandler { self.start_keep_alive_timer(timeout); } }, + HandlerAction::SetConfig(config) => self.config = Some(config), } next_phase } diff --git a/ton_client/src/tests/common.rs b/ton_client/src/tests/common.rs index 4a15a5194..d1ee1ca65 100644 --- a/ton_client/src/tests/common.rs +++ b/ton_client/src/tests/common.rs @@ -85,7 +85,7 @@ fn test_deferred_init() { fn test_clock_sync() { let client = TestClient::new_with_config(json!({ "network": { - "server_address": TestClient::network_address(), + "endpoints": [TestClient::network_address()], "out_of_sync_threshold": 0, } })); diff --git a/ton_client/src/tests/mod.rs b/ton_client/src/tests/mod.rs index 810918a47..d1a269b4c 100644 --- a/ton_client/src/tests/mod.rs +++ b/ton_client/src/tests/mod.rs @@ -545,7 +545,7 @@ impl TestClient { let wait_for = self.wrap_async( crate::net::wait_for_collection, NetModule::api(), - crate::net::wait_for_collection_api(), + crate::net::queries::wait_for_collection_api(), ); let result = wait_for .call(ParamsOfWaitForCollection { From f7b196fb2dee761afac2d81422eaf0c7c6f4de53 Mon Sep 17 00:00:00 2001 From: Alexey Vavilin Date: Wed, 23 Dec 2020 19:47:18 +0300 Subject: [PATCH 09/19] fetch/set endpoints --- ton_client/src/error.rs | 33 +++++++++++------ ton_client/src/json_interface/modules.rs | 2 ++ ton_client/src/net/errors.rs | 16 +++++++++ ton_client/src/net/mod.rs | 36 +++++++++++++++++++ ton_client/src/net/queries.rs | 32 ++++++++++++----- ton_client/src/net/server_info.rs | 2 ++ ton_client/src/net/server_link.rs | 45 +++++++++++++++++++----- ton_client/src/net/subscriptions.rs | 8 +++-- ton_client/src/net/tests.rs | 22 ++++++++++++ 9 files changed, 167 insertions(+), 29 deletions(-) diff --git a/ton_client/src/error.rs b/ton_client/src/error.rs index 4d5305115..1d0f80b91 100644 --- a/ton_client/src/error.rs +++ b/ton_client/src/error.rs @@ -11,6 +11,29 @@ pub struct ClientError { pub type ClientResult = Result; +#[async_trait::async_trait] +pub(crate) trait AddNetworkUrl { + async fn add_network_url(self, client: &crate::net::ServerLink) -> Self; +} + +#[async_trait::async_trait] +impl AddNetworkUrl for ClientResult { + async fn add_network_url(self, client: &crate::net::ServerLink) -> Self { + match self { + Err(mut err) => { + err.data["config_servers"] = client.config_servers().await.into(); + + if let Some(url) = client.query_url().await { + err.data["query_url"] = url.into(); + } + + Err(err) + }, + _ => self + } + } +} + impl Display for ClientError { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { if f.alternate() { @@ -54,16 +77,6 @@ impl ClientError { } } - pub(crate) fn add_network_url(mut self, client: &crate::net::ServerLink) -> ClientError { - self.data["config_servers"] = client.config_servers().into(); - - if let Some(url) = client.query_url() { - self.data["query_url"] = url.into(); - } - - self - } - pub fn add_function(mut self, function: Option<&str>) -> ClientError { if let Some(function) = function { self.data["function_name"] = function.into(); diff --git a/ton_client/src/json_interface/modules.rs b/ton_client/src/json_interface/modules.rs index ceeb3495f..3a8c3145e 100644 --- a/ton_client/src/json_interface/modules.rs +++ b/ton_client/src/json_interface/modules.rs @@ -334,6 +334,8 @@ fn register_net(handlers: &mut RuntimeHandlers) { crate::net::find_last_shard_block, crate::net::find_last_shard_block_api, ); + module.register_async_fn_no_args(crate::net::fetch_endpoints, crate::net::fetch_endpoints_api); + module.register_async_fn(crate::net::set_endpoints, crate::net::set_endpoints_api); module.register(); } diff --git a/ton_client/src/net/errors.rs b/ton_client/src/net/errors.rs index 16f76106c..264e86e00 100644 --- a/ton_client/src/net/errors.rs +++ b/ton_client/src/net/errors.rs @@ -15,6 +15,8 @@ pub enum ErrorCode { GraphqlError = NET + 8, NetworkModuleSuspended = NET + 9, WebsocketDisconnected = NET + 10, + NotSupported = NET + 11, + NoEndpointsProvided = NET + 12, } pub struct Error; @@ -113,4 +115,18 @@ impl Error { "Can not use network module since it is suspended".to_owned(), ) } + + pub fn not_suppported(request: &str) -> ClientError { + error( + ErrorCode::NotSupported, + format!("Server does not support the following request: {}", request), + ) + } + + pub fn no_endpoints_provided() -> ClientError { + error( + ErrorCode::NoEndpointsProvided, + "No endpoints provided".to_owned(), + ) + } } diff --git a/ton_client/src/net/mod.rs b/ton_client/src/net/mod.rs index fc2288456..6c4b4abf2 100644 --- a/ton_client/src/net/mod.rs +++ b/ton_client/src/net/mod.rs @@ -90,3 +90,39 @@ pub async fn find_last_shard_block( block_id: block_id.to_string() }) } + +#[derive(Serialize, Deserialize, ApiType, Clone)] +pub struct EndpointsSet { + /// List of endpoints provided by server + pub endpoints: Vec, +} + +/// Requests the list of alternative endpoints from server +#[api_function] +pub async fn fetch_endpoints( + context: std::sync::Arc, +) -> ClientResult { + let client = context.get_server_link()?; + + Ok(EndpointsSet { + endpoints: client.fetch_endpoints().await? + }) +} + +/// Sets the list of endpoints to use on reinit +#[api_function] +pub async fn set_endpoints( + context: std::sync::Arc, + params: EndpointsSet +) -> ClientResult<()> { + if params.endpoints.len() == 0 { + return Err(Error::no_endpoints_provided()); + } + + context + .get_server_link()? + .set_endpoints(params.endpoints) + .await; + + Ok(()) +} diff --git a/ton_client/src/net/queries.rs b/ton_client/src/net/queries.rs index 22809e545..4f3ffe9f4 100644 --- a/ton_client/src/net/queries.rs +++ b/ton_client/src/net/queries.rs @@ -12,7 +12,7 @@ */ use crate::client::ClientContext; -use crate::error::ClientResult; +use crate::error::{AddNetworkUrl, ClientResult}; use super::{Error, OrderBy}; use serde_json::Value; @@ -81,11 +81,17 @@ pub async fn query( ¶ms.query, params.variables, None, - ).await.map_err(|err| Error::queries_query_failed(err).add_network_url(client))?; + ) + .await + .map_err(|err| Error::queries_query_failed(err)) + .add_network_url(client) + .await?; let result = serde_json::from_value(result).map_err(|err| { - Error::queries_query_failed(format!("Can not parse result: {}", err)).add_network_url(client) - })?; + Error::queries_query_failed(format!("Can not parse result: {}", err)) + }) + .add_network_url(client) + .await?; Ok(ResultOfQuery { result }) } @@ -108,11 +114,17 @@ pub async fn query_collection( params.order, params.limit, None, - ).await.map_err(|err| Error::queries_query_failed(err).add_network_url(client))?; + ) + .await + .map_err(|err| Error::queries_query_failed(err)) + .add_network_url(client) + .await?; let result = serde_json::from_value(result).map_err(|err| { - Error::queries_query_failed(format!("Can not parse result: {}", err)).add_network_url(client) - })?; + Error::queries_query_failed(format!("Can not parse result: {}", err)) + }) + .add_network_url(client) + .await?; Ok(ResultOfQueryCollection { result }) } @@ -136,7 +148,11 @@ pub async fn wait_for_collection( ¶ms.filter.unwrap_or(json!({})), ¶ms.result, params.timeout, - ).await.map_err(|err| Error::queries_wait_for_failed(err).add_network_url(client))?; + ) + .await + .map_err(|err| Error::queries_wait_for_failed(err)) + .add_network_url(client) + .await?; Ok(ResultOfWaitForCollection { result }) } diff --git a/ton_client/src/net/server_info.rs b/ton_client/src/net/server_info.rs index 3fb95bf99..a8a9500a9 100644 --- a/ton_client/src/net/server_info.rs +++ b/ton_client/src/net/server_info.rs @@ -20,6 +20,7 @@ use std::sync::Arc; pub(crate) struct ServerVersion { pub version: u64, pub supports_time: bool, + pub supports_endpoints: bool, } impl ServerVersion { @@ -33,6 +34,7 @@ impl ServerVersion { Ok(ServerVersion { version, supports_time: version >= 26003, + supports_endpoints: version >= 30000, }) } } diff --git a/ton_client/src/net/server_link.rs b/ton_client/src/net/server_link.rs index 5d943d449..3f33aae22 100644 --- a/ton_client/src/net/server_link.rs +++ b/ton_client/src/net/server_link.rs @@ -12,7 +12,7 @@ */ use crate::client::{ClientEnv, FetchMethod}; -use crate::error::{ClientError, ClientResult}; +use crate::error::{AddNetworkUrl, ClientError, ClientResult}; use crate::net::gql::{GraphQLOperation, GraphQLOperationEvent, OrderBy, PostRequest}; use crate::net::server_info::ServerInfo; use crate::net::websocket_link::WebsocketLink; @@ -34,7 +34,7 @@ pub(crate) struct Subscription { pub(crate) struct ServerLink { config: NetworkConfig, - endpoints: Vec, + endpoints: tokio::sync::RwLock>, client_env: Arc, suspended: AtomicBool, server_info: tokio::sync::RwLock>, @@ -54,7 +54,7 @@ impl ServerLink { Ok(ServerLink { config: config.clone(), - endpoints, + endpoints: tokio::sync::RwLock::new(endpoints), client_env: client_env.clone(), suspended: AtomicBool::new(false), query_url: std::sync::RwLock::new(None), @@ -107,7 +107,7 @@ impl ServerLink { async fn init(&self, config: &NetworkConfig) -> ClientResult { let mut futures = vec![]; - for address in &self.endpoints { + for address in self.endpoints.read().await.iter() { let queries_server = ServerInfo::expand_address(&address); futures.push(Box::pin(async move { ServerInfo::fetch(self.client_env.clone(), &queries_server).await @@ -163,12 +163,12 @@ impl ServerLink { &self.config } - pub fn config_servers(&self) -> &[String] { - &self.endpoints + pub async fn config_servers(&self) -> Vec { + self.endpoints.read().await.clone() } - pub fn query_url(&self) -> Option { - self.query_url.read().unwrap().clone() + pub async fn query_url(&self) -> Option { + self.server_info.read().await.as_ref().map(|info| info.query_url.clone()) } // Returns Stream with updates database fields by provided filter @@ -179,7 +179,7 @@ impl ServerLink { fields: &str, ) -> ClientResult { self.ensure_info().await?; - + let event_receiver = self .websocket_link .start_operation(GraphQLOperation::subscription(table, filter, fields)) @@ -389,4 +389,31 @@ impl ServerLink { self.suspended.store(false, Ordering::Relaxed); self.websocket_link.resume().await; } + + pub async fn fetch_endpoints(&self) -> ClientResult> { + self.ensure_info().await?; + let client_lock = self.server_info.read().await; + + if !client_lock.as_ref().unwrap().server_version.supports_endpoints { + return Err(Error::not_suppported("endpoints")); + } + + let result = self.query_by_url( + &client_lock.as_ref().unwrap().query_url, + "%7Binfo%7Bendpoints%7D%7D" + ) + .await + .add_network_url(&self) + .await?; + + serde_json::from_value(result["data"]["info"]["endpoints"].clone()) + .map_err(|_| Error::invalid_server_response(format!( + "Can not parse endpoints from response: {}", + result + ))) + } + + pub async fn set_endpoints(&self, endpoints: Vec) { + *self.endpoints.write().await = endpoints; + } } diff --git a/ton_client/src/net/subscriptions.rs b/ton_client/src/net/subscriptions.rs index a94b05568..810654ce1 100644 --- a/ton_client/src/net/subscriptions.rs +++ b/ton_client/src/net/subscriptions.rs @@ -12,7 +12,7 @@ */ use crate::client::ClientContext; -use crate::error::ClientResult; +use crate::error::{AddNetworkUrl, ClientResult}; use super::Error; use futures::{Future, FutureExt, StreamExt}; use rand::RngCore; @@ -69,7 +69,11 @@ async fn create_subscription( ¶ms.collection, params.filter.as_ref().unwrap_or(&json!({})), ¶ms.result, - ).await.map_err(|err| Error::queries_subscribe_failed(err).add_network_url(client)) + ) + .await + .map_err(|err| Error::queries_subscribe_failed(err)) + .add_network_url(client) + .await } pub async fn subscribe_collection + Send>( diff --git a/ton_client/src/net/tests.rs b/ton_client/src/net/tests.rs index 6d6646bf6..76cdad818 100644 --- a/ton_client/src/net/tests.rs +++ b/ton_client/src/net/tests.rs @@ -352,3 +352,25 @@ async fn find_last_shard_block() { println!("{}", block.block_id); } + +#[tokio::test(core_threads = 2)] +async fn test_endpoints() { + return; + let client = TestClient::new(); + + let endpoints: EndpointsSet = client + .request_async( + "net.fetch_endpoints", + (), + ) + .await + .unwrap(); + + let _: () = client + .request_async( + "net.set_endpoints", + endpoints, + ) + .await + .unwrap(); +} From 1d7a253760cde26b8068380400efece70fe8d3ad Mon Sep 17 00:00:00 2001 From: Michael Vlasov Date: Thu, 24 Dec 2020 13:28:16 +0500 Subject: [PATCH 10/19] FIX: regen api FIX: update CHANGELOG.md --- CHANGELOG.md | 3 +++ tools/api.json | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 86c7d1993..cae5b76be 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,9 @@ All notable changes to this project will be documented in this file. ## 1.4.1 Dec 23, 2020 +### New +- `ErrorCode` types in every module in `api.json`. + ### Fixed - send `GQL_TERMINATE_CONNECTION` and close websocket on leaving ws loop. diff --git a/tools/api.json b/tools/api.json index 068c92987..12b8f6a60 100644 --- a/tools/api.json +++ b/tools/api.json @@ -1,5 +1,5 @@ { - "version": "1.4.0", + "version": "1.4.1", "modules": [ { "name": "client", From e7a58b0f97e398ee575f9d6c4cd6cdb48c3bcba0 Mon Sep 17 00:00:00 2001 From: Michael Vlasov Date: Thu, 24 Dec 2020 15:57:23 +0500 Subject: [PATCH 11/19] NEW: `reconnect_timeout` parameter in `NetworkConfig`. --- CHANGELOG.md | 4 +- docs/mod_client.md | 8 +- docs/mod_net.md | 56 +++++++++++- docs/modules.md | 4 + ton_client/src/net/errors.rs | 24 ++--- ton_client/src/net/server_link.rs | 55 ++++++++---- ton_client/src/net/tests.rs | 40 +++++---- ton_client/src/net/types.rs | 14 +++ ton_client/src/net/websocket_link.rs | 44 +++++++-- tools/api.json | 129 ++++++++++++++++++++++++++- 10 files changed, 319 insertions(+), 59 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index cae5b76be..561c861f8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,10 +1,10 @@ # Release Notes All notable changes to this project will be documented in this file. -## 1.4.1 Dec 23, 2020 +## 1.5.0 Dec 25, 2020 ### New -- `ErrorCode` types in every module in `api.json`. +- `reconnect_timeout` parameter in `NetworkConfig`. ### Fixed - send `GQL_TERMINATE_CONNECTION` and close websocket on leaving ws loop. diff --git a/docs/mod_client.md b/docs/mod_client.md index 6d4e34250..0b777bb4e 100644 --- a/docs/mod_client.md +++ b/docs/mod_client.md @@ -215,21 +215,25 @@ type ClientConfig = { ## NetworkConfig ```ts type NetworkConfig = { - server_address: string, + server_address?: string, + endpoints?: string[], network_retries_count?: number, message_retries_count?: number, message_processing_timeout?: number, wait_for_timeout?: number, out_of_sync_threshold?: number, + reconnect_timeout?: number, access_key?: string } ``` -- `server_address`: _string_ +- `server_address`?: _string_ +- `endpoints`?: _string[]_ - `network_retries_count`?: _number_ - `message_retries_count`?: _number_ - `message_processing_timeout`?: _number_ - `wait_for_timeout`?: _number_ - `out_of_sync_threshold`?: _number_ +- `reconnect_timeout`?: _number_ - `access_key`?: _string_ diff --git a/docs/mod_net.md b/docs/mod_net.md index 1321dfd10..f3ce891b8 100644 --- a/docs/mod_net.md +++ b/docs/mod_net.md @@ -18,6 +18,10 @@ null [find_last_shard_block](#find_last_shard_block) – Returns ID of the last block in a specified account shard +[fetch_endpoints](#fetch_endpoints) – Requests the list of alternative endpoints from server + +[set_endpoints](#set_endpoints) – Sets the list of endpoints to use on reinit + ## Types [NetErrorCode](#NetErrorCode) @@ -45,6 +49,8 @@ null [ResultOfFindLastShardBlock](#ResultOfFindLastShardBlock) +[EndpointsSet](#EndpointsSet) + # Functions ## query @@ -249,6 +255,41 @@ function find_last_shard_block( - `block_id`: _string_ – Account shard last block ID +## fetch_endpoints + +Requests the list of alternative endpoints from server + +```ts +type EndpointsSet = { + endpoints: string[] +} + +function fetch_endpoints(): Promise; +``` +### Result + +- `endpoints`: _string[]_ – List of endpoints provided by server + + +## set_endpoints + +Sets the list of endpoints to use on reinit + +```ts +type EndpointsSet = { + endpoints: string[] +} + +function set_endpoints( + params: EndpointsSet, +): Promise; +``` +### Parameters +- `endpoints`: _string[]_ – List of endpoints provided by server +### Result + + + # Types ## NetErrorCode ```ts @@ -262,7 +303,9 @@ enum NetErrorCode { WaitForTimeout = 607, GraphqlError = 608, NetworkModuleSuspended = 609, - WebsocketDisconnected = 610 + WebsocketDisconnected = 610, + NotSupported = 611, + NoEndpointsProvided = 612 } ``` One of the following value: @@ -277,6 +320,8 @@ One of the following value: - `GraphqlError = 608` - `NetworkModuleSuspended = 609` - `WebsocketDisconnected = 610` +- `NotSupported = 611` +- `NoEndpointsProvided = 612` ## OrderBy @@ -415,3 +460,12 @@ type ResultOfFindLastShardBlock = { - `block_id`: _string_ – Account shard last block ID +## EndpointsSet +```ts +type EndpointsSet = { + endpoints: string[] +} +``` +- `endpoints`: _string[]_ – List of endpoints provided by server + + diff --git a/docs/modules.md b/docs/modules.md index 026f77b7e..5f3a684dd 100644 --- a/docs/modules.md +++ b/docs/modules.md @@ -157,6 +157,10 @@ [find_last_shard_block](mod_net.md#find_last_shard_block) – Returns ID of the last block in a specified account shard +[fetch_endpoints](mod_net.md#fetch_endpoints) – Requests the list of alternative endpoints from server + +[set_endpoints](mod_net.md#set_endpoints) – Sets the list of endpoints to use on reinit + ## [debot](mod_debot.md) – [UNSTABLE](UNSTABLE.md) Module for working with debot. [start](mod_debot.md#start) – [UNSTABLE](UNSTABLE.md) Starts an instance of debot. diff --git a/ton_client/src/net/errors.rs b/ton_client/src/net/errors.rs index 224d8431d..0f3e7e3d1 100644 --- a/ton_client/src/net/errors.rs +++ b/ton_client/src/net/errors.rs @@ -4,18 +4,18 @@ use std::fmt::Display; #[derive(ApiType)] pub enum ErrorCode { - QueryFailed = NET + 1, - SubscribeFailed = NET + 2, - WaitForFailed = NET + 3, - GetSubscriptionResultFailed = NET + 4, - InvalidServerResponse = NET + 5, - ClockOutOfSync = NET + 6, - WaitForTimeout = NET + 7, - GraphqlError = NET + 8, - NetworkModuleSuspended = NET + 9, - WebsocketDisconnected = NET + 10, - NotSupported = NET + 11, - NoEndpointsProvided = NET + 12, + QueryFailed = 601, + SubscribeFailed = 602, + WaitForFailed = 603, + GetSubscriptionResultFailed = 604, + InvalidServerResponse = 605, + ClockOutOfSync = 606, + WaitForTimeout = 607, + GraphqlError = 608, + NetworkModuleSuspended = 609, + WebsocketDisconnected = 610, + NotSupported = 611, + NoEndpointsProvided = 612, } pub struct Error; diff --git a/ton_client/src/net/server_link.rs b/ton_client/src/net/server_link.rs index 3f33aae22..f5873b378 100644 --- a/ton_client/src/net/server_link.rs +++ b/ton_client/src/net/server_link.rs @@ -11,13 +11,13 @@ * limitations under the License. */ +use super::websocket_link::WsConfig; use crate::client::{ClientEnv, FetchMethod}; use crate::error::{AddNetworkUrl, ClientError, ClientResult}; use crate::net::gql::{GraphQLOperation, GraphQLOperationEvent, OrderBy, PostRequest}; use crate::net::server_info::ServerInfo; use crate::net::websocket_link::WebsocketLink; use crate::net::{Error, NetworkConfig}; -use super::websocket_link::WsConfig; use futures::{Future, Stream, StreamExt}; use serde_json::Value; use std::collections::HashMap; @@ -45,7 +45,9 @@ pub(crate) struct ServerLink { impl ServerLink { pub fn new(config: NetworkConfig, client_env: Arc) -> ClientResult { - let endpoints = config.endpoints.clone() + let endpoints = config + .endpoints + .clone() .or(config.server_address.clone().map(|address| vec![address])) .ok_or(crate::client::Error::net_module_not_init())?; if endpoints.len() == 0 { @@ -109,11 +111,11 @@ impl ServerLink { let mut futures = vec![]; for address in self.endpoints.read().await.iter() { let queries_server = ServerInfo::expand_address(&address); - futures.push(Box::pin(async move { + futures.push(Box::pin(async move { ServerInfo::fetch(self.client_env.clone(), &queries_server).await })); } - + let mut server_info = Err(crate::client::Error::net_module_not_init()); while futures.len() != 0 { let (result, _, remain_futures) = futures::future::select_all(futures).await; @@ -126,7 +128,8 @@ impl ServerLink { let server_info = server_info?; if server_info.server_version.supports_time { - self.check_time_delta(&server_info.query_url, config).await?; + self.check_time_delta(&server_info.query_url, config) + .await?; } Ok(server_info) @@ -148,10 +151,13 @@ impl ServerLink { let inited_data = self.init(&self.config).await?; - self.websocket_link.set_config(WsConfig { - url: inited_data.subscription_url.clone(), - access_key: self.config.access_key.clone() - }).await; + self.websocket_link + .set_config(WsConfig { + url: inited_data.subscription_url.clone(), + access_key: self.config.access_key.clone(), + reconnect_timeout: self.config.reconnect_timeout, + }) + .await; *self.query_url.write().unwrap() = Some(inited_data.query_url.clone()); *data = Some(inited_data); @@ -168,7 +174,11 @@ impl ServerLink { } pub async fn query_url(&self) -> Option { - self.server_info.read().await.as_ref().map(|info| info.query_url.clone()) + self.server_info + .read() + .await + .as_ref() + .map(|info| info.query_url.clone()) } // Returns Stream with updates database fields by provided filter @@ -394,23 +404,30 @@ impl ServerLink { self.ensure_info().await?; let client_lock = self.server_info.read().await; - if !client_lock.as_ref().unwrap().server_version.supports_endpoints { + if !client_lock + .as_ref() + .unwrap() + .server_version + .supports_endpoints + { return Err(Error::not_suppported("endpoints")); } - let result = self.query_by_url( - &client_lock.as_ref().unwrap().query_url, - "%7Binfo%7Bendpoints%7D%7D" - ) + let result = self + .query_by_url( + &client_lock.as_ref().unwrap().query_url, + "%7Binfo%7Bendpoints%7D%7D", + ) .await .add_network_url(&self) .await?; - - serde_json::from_value(result["data"]["info"]["endpoints"].clone()) - .map_err(|_| Error::invalid_server_response(format!( + + serde_json::from_value(result["data"]["info"]["endpoints"].clone()).map_err(|_| { + Error::invalid_server_response(format!( "Can not parse endpoints from response: {}", result - ))) + )) + }) } pub async fn set_endpoints(&self, endpoints: Vec) { diff --git a/ton_client/src/net/tests.rs b/ton_client/src/net/tests.rs index 76cdad818..d29853117 100644 --- a/ton_client/src/net/tests.rs +++ b/ton_client/src/net/tests.rs @@ -155,12 +155,19 @@ async fn subscribe_for_transactions_with_addresses() { SubscriptionResponseType::Error => { Err(serde_json::from_value::(result).unwrap()) } - } - .unwrap(); - assert_eq!(result.result["account_addr"], address1); + }; + let address1 = address1.clone(); let transactions_copy = transactions_copy1.clone(); async move { - transactions_copy.lock().await.push(result.result); + match result { + Ok(result) => { + assert_eq!(result.result["account_addr"], address1); + transactions_copy.lock().await.push(result.result); + } + Err(err) => { + println!(">>> {}", err); + } + } } }; @@ -185,12 +192,19 @@ async fn subscribe_for_transactions_with_addresses() { SubscriptionResponseType::Error => { Err(serde_json::from_value::(result).unwrap()) } - } - .unwrap(); - assert_eq!(result.result["account_addr"], address2); + }; let transactions_copy = transactions_copy2.clone(); + let address2 = address2.clone(); async move { - transactions_copy.lock().await.push(result.result); + match result { + Ok(result) => { + assert_eq!(result.result["account_addr"], address2); + transactions_copy.lock().await.push(result.result); + } + Err(err) => { + println!(">>> {}", err); + } + } } }; @@ -359,18 +373,12 @@ async fn test_endpoints() { let client = TestClient::new(); let endpoints: EndpointsSet = client - .request_async( - "net.fetch_endpoints", - (), - ) + .request_async("net.fetch_endpoints", ()) .await .unwrap(); let _: () = client - .request_async( - "net.set_endpoints", - endpoints, - ) + .request_async("net.set_endpoints", endpoints) .await .unwrap(); } diff --git a/ton_client/src/net/types.rs b/ton_client/src/net/types.rs index 5d23fcc85..41a8e2643 100644 --- a/ton_client/src/net/types.rs +++ b/ton_client/src/net/types.rs @@ -38,6 +38,10 @@ pub fn default_out_of_sync_threshold() -> u32 { 15000 } +pub fn default_reconnect_timeout() -> u32 { + 1000 +} + fn deserialize_network_retries_count<'de, D: Deserializer<'de>>( deserializer: D, ) -> Result { @@ -68,6 +72,12 @@ fn deserialize_out_of_sync_threshold<'de, D: Deserializer<'de>>( Ok(Option::deserialize(deserializer)?.unwrap_or(default_out_of_sync_threshold())) } +fn deserialize_reconnect_timeout<'de, D: Deserializer<'de>>( + deserializer: D, +) -> Result { + Ok(Option::deserialize(deserializer)?.unwrap_or(default_reconnect_timeout())) +} + #[derive(Serialize, Deserialize, Debug, Clone, ApiType)] pub struct NetworkConfig { pub server_address: Option, @@ -87,6 +97,9 @@ pub struct NetworkConfig { #[serde(default = "default_out_of_sync_threshold", deserialize_with = "deserialize_out_of_sync_threshold")] pub out_of_sync_threshold: u32, + #[serde(default = "default_reconnect_timeout", + deserialize_with = "deserialize_reconnect_timeout")] + pub reconnect_timeout: u32, pub access_key: Option, } @@ -100,6 +113,7 @@ impl Default for NetworkConfig { message_processing_timeout: default_message_processing_timeout(), wait_for_timeout: default_wait_for_timeout(), out_of_sync_threshold: default_out_of_sync_threshold(), + reconnect_timeout: default_reconnect_timeout(), access_key: None, } } diff --git a/ton_client/src/net/websocket_link.rs b/ton_client/src/net/websocket_link.rs index ed06b7bc2..ca2b75f38 100644 --- a/ton_client/src/net/websocket_link.rs +++ b/ton_client/src/net/websocket_link.rs @@ -33,6 +33,7 @@ type WSSender = Pin + Send>>; pub(crate) struct WsConfig { pub url: String, pub access_key: Option, + pub reconnect_timeout: u32, } #[derive(Debug)] @@ -44,6 +45,7 @@ enum HandlerAction { Resume, CheckKeepAlivePassed, + Reconnect, SetConfig(WsConfig), } @@ -94,7 +96,8 @@ impl WebsocketLink { } pub async fn set_config(&self, config: WsConfig) { - self.send_action_to_handler(HandlerAction::SetConfig(config)).await; + self.send_action_to_handler(HandlerAction::SetConfig(config)) + .await; } async fn send_action_to_handler(&self, action: HandlerAction) { @@ -185,6 +188,7 @@ impl LinkHandler { Ok(w) => w, Err(err) => { self.send_error_to_running_operations(err).await; + self.start_reconnect_timer(); return Phase::Idle; } }; @@ -206,8 +210,10 @@ impl LinkHandler { phase = self.handle_ws_action(action, &mut ws_sender, phase).await } } - let _ = ws_sender.send(GraphQLMessageFromClient::ConnectionTerminate.get_message()).await; - let _ = ws_sender.send(String::new()).await; + let _ = ws_sender + .send(GraphQLMessageFromClient::ConnectionTerminate.get_message()) + .await; + let _ = ws_sender.send(String::new()); phase } @@ -224,6 +230,7 @@ impl LinkHandler { HandlerAction::Suspend => Phase::Idle, HandlerAction::Resume => Phase::Connecting, HandlerAction::CheckKeepAlivePassed => Phase::Idle, + HandlerAction::Reconnect => Phase::Connecting, HandlerAction::SetConfig(config) => { self.config = Some(config); Phase::Idle @@ -233,9 +240,12 @@ impl LinkHandler { async fn connect(&mut self) -> ClientResult { self.keep_alive = KeepAlive::WaitFirst; - let config = self.config + let config = self + .config .clone() - .ok_or(crate::client::Error::invalid_config("No websocket config".to_owned()))?; + .ok_or(crate::client::Error::invalid_config( + "No websocket config".to_owned(), + ))?; let mut headers = HashMap::new(); headers.insert("Sec-WebSocket-Protocol".into(), "graphql-ws".into()); for (name, value) in ServerInfo::http_headers() { @@ -291,12 +301,17 @@ impl LinkHandler { "keep alive message wasn't received", )) .await; + let _ = self + .internal_action_sender + .send(HandlerAction::Reconnect) + .await; next_phase = Phase::Idle; } KeepAlive::Passed { timeout } => { self.start_keep_alive_timer(timeout); } }, + HandlerAction::Reconnect => {} HandlerAction::SetConfig(config) => self.config = Some(config), } next_phase @@ -320,6 +335,10 @@ impl LinkHandler { Err(err) => { self.send_error_to_running_operations(Error::websocket_disconnected(err)) .await; + let _ = self + .internal_action_sender + .send(HandlerAction::Reconnect) + .await; return Phase::Idle; } }; @@ -348,6 +367,10 @@ impl LinkHandler { &vec![error], )) .await; + let _ = self + .internal_action_sender + .send(HandlerAction::Reconnect) + .await; next_phase = Phase::Idle; } GraphQLMessageFromServer::Data { id, data, errors } => { @@ -384,6 +407,17 @@ impl LinkHandler { })); } + fn start_reconnect_timer(&mut self) { + let mut sender = self.internal_action_sender.clone(); + let env = self.client_env.clone(); + if let Some(timeout) = self.config.as_ref().map(|x| x.reconnect_timeout) { + env.clone().spawn(Box::pin(async move { + let _ = env.set_timer(timeout as u64).await; + let _ = sender.send(HandlerAction::Reconnect).await; + })); + } + } + async fn notify_with_remove( &mut self, remove: bool, diff --git a/tools/api.json b/tools/api.json index 12b8f6a60..5305fa029 100644 --- a/tools/api.json +++ b/tools/api.json @@ -1,5 +1,5 @@ { - "version": "1.4.1", + "version": "1.5.0", "modules": [ { "name": "client", @@ -318,7 +318,22 @@ "struct_fields": [ { "name": "server_address", - "type": "String", + "type": "Optional", + "optional_inner": { + "type": "String" + }, + "summary": null, + "description": null + }, + { + "name": "endpoints", + "type": "Optional", + "optional_inner": { + "type": "Array", + "array_item": { + "type": "String" + } + }, "summary": null, "description": null }, @@ -377,6 +392,17 @@ "summary": null, "description": null }, + { + "name": "reconnect_timeout", + "type": "Optional", + "optional_inner": { + "type": "Number", + "number_type": "UInt", + "number_size": 32 + }, + "summary": null, + "description": null + }, { "name": "access_key", "type": "Optional", @@ -6874,6 +6900,20 @@ "value": "610", "summary": null, "description": null + }, + { + "name": "NotSupported", + "type": "Number", + "value": "611", + "summary": null, + "description": null + }, + { + "name": "NoEndpointsProvided", + "type": "Number", + "value": "612", + "summary": null, + "description": null } ], "summary": null, @@ -7160,6 +7200,23 @@ ], "summary": null, "description": null + }, + { + "name": "EndpointsSet", + "type": "Struct", + "struct_fields": [ + { + "name": "endpoints", + "type": "Array", + "array_item": { + "type": "String" + }, + "summary": "List of endpoints provided by server", + "description": null + } + ], + "summary": null, + "description": null } ], "functions": [ @@ -7462,6 +7519,74 @@ ] }, "errors": null + }, + { + "name": "fetch_endpoints", + "summary": "Requests the list of alternative endpoints from server", + "description": null, + "params": [ + { + "name": "context", + "type": "Generic", + "generic_name": "Arc", + "generic_args": [ + { + "type": "Ref", + "ref_name": "ClientContext" + } + ], + "summary": null, + "description": null + } + ], + "result": { + "type": "Generic", + "generic_name": "ClientResult", + "generic_args": [ + { + "type": "Ref", + "ref_name": "net.EndpointsSet" + } + ] + }, + "errors": null + }, + { + "name": "set_endpoints", + "summary": "Sets the list of endpoints to use on reinit", + "description": null, + "params": [ + { + "name": "context", + "type": "Generic", + "generic_name": "Arc", + "generic_args": [ + { + "type": "Ref", + "ref_name": "ClientContext" + } + ], + "summary": null, + "description": null + }, + { + "name": "params", + "type": "Ref", + "ref_name": "net.EndpointsSet", + "summary": null, + "description": null + } + ], + "result": { + "type": "Generic", + "generic_name": "ClientResult", + "generic_args": [ + { + "type": "None" + } + ] + }, + "errors": null } ] }, From 9f6dd2abf0937d87c85ca4664fd89a0027e94ba7 Mon Sep 17 00:00:00 2001 From: Michael Vlasov Date: Thu, 24 Dec 2020 16:04:06 +0500 Subject: [PATCH 12/19] regen --- docs/mod_client.md | 6 ++- docs/mod_net.md | 56 ++++++++++++++++++++- docs/modules.md | 4 ++ tools/api.json | 118 ++++++++++++++++++++++++++++++++++++++++++++- 4 files changed, 179 insertions(+), 5 deletions(-) diff --git a/docs/mod_client.md b/docs/mod_client.md index 6d4e34250..b3711d390 100644 --- a/docs/mod_client.md +++ b/docs/mod_client.md @@ -215,7 +215,8 @@ type ClientConfig = { ## NetworkConfig ```ts type NetworkConfig = { - server_address: string, + server_address?: string, + endpoints?: string[], network_retries_count?: number, message_retries_count?: number, message_processing_timeout?: number, @@ -224,7 +225,8 @@ type NetworkConfig = { access_key?: string } ``` -- `server_address`: _string_ +- `server_address`?: _string_ +- `endpoints`?: _string[]_ - `network_retries_count`?: _number_ - `message_retries_count`?: _number_ - `message_processing_timeout`?: _number_ diff --git a/docs/mod_net.md b/docs/mod_net.md index 1321dfd10..f3ce891b8 100644 --- a/docs/mod_net.md +++ b/docs/mod_net.md @@ -18,6 +18,10 @@ null [find_last_shard_block](#find_last_shard_block) – Returns ID of the last block in a specified account shard +[fetch_endpoints](#fetch_endpoints) – Requests the list of alternative endpoints from server + +[set_endpoints](#set_endpoints) – Sets the list of endpoints to use on reinit + ## Types [NetErrorCode](#NetErrorCode) @@ -45,6 +49,8 @@ null [ResultOfFindLastShardBlock](#ResultOfFindLastShardBlock) +[EndpointsSet](#EndpointsSet) + # Functions ## query @@ -249,6 +255,41 @@ function find_last_shard_block( - `block_id`: _string_ – Account shard last block ID +## fetch_endpoints + +Requests the list of alternative endpoints from server + +```ts +type EndpointsSet = { + endpoints: string[] +} + +function fetch_endpoints(): Promise; +``` +### Result + +- `endpoints`: _string[]_ – List of endpoints provided by server + + +## set_endpoints + +Sets the list of endpoints to use on reinit + +```ts +type EndpointsSet = { + endpoints: string[] +} + +function set_endpoints( + params: EndpointsSet, +): Promise; +``` +### Parameters +- `endpoints`: _string[]_ – List of endpoints provided by server +### Result + + + # Types ## NetErrorCode ```ts @@ -262,7 +303,9 @@ enum NetErrorCode { WaitForTimeout = 607, GraphqlError = 608, NetworkModuleSuspended = 609, - WebsocketDisconnected = 610 + WebsocketDisconnected = 610, + NotSupported = 611, + NoEndpointsProvided = 612 } ``` One of the following value: @@ -277,6 +320,8 @@ One of the following value: - `GraphqlError = 608` - `NetworkModuleSuspended = 609` - `WebsocketDisconnected = 610` +- `NotSupported = 611` +- `NoEndpointsProvided = 612` ## OrderBy @@ -415,3 +460,12 @@ type ResultOfFindLastShardBlock = { - `block_id`: _string_ – Account shard last block ID +## EndpointsSet +```ts +type EndpointsSet = { + endpoints: string[] +} +``` +- `endpoints`: _string[]_ – List of endpoints provided by server + + diff --git a/docs/modules.md b/docs/modules.md index 026f77b7e..5f3a684dd 100644 --- a/docs/modules.md +++ b/docs/modules.md @@ -157,6 +157,10 @@ [find_last_shard_block](mod_net.md#find_last_shard_block) – Returns ID of the last block in a specified account shard +[fetch_endpoints](mod_net.md#fetch_endpoints) – Requests the list of alternative endpoints from server + +[set_endpoints](mod_net.md#set_endpoints) – Sets the list of endpoints to use on reinit + ## [debot](mod_debot.md) – [UNSTABLE](UNSTABLE.md) Module for working with debot. [start](mod_debot.md#start) – [UNSTABLE](UNSTABLE.md) Starts an instance of debot. diff --git a/tools/api.json b/tools/api.json index 12b8f6a60..bb9855209 100644 --- a/tools/api.json +++ b/tools/api.json @@ -1,5 +1,5 @@ { - "version": "1.4.1", + "version": "1.5.0", "modules": [ { "name": "client", @@ -318,7 +318,22 @@ "struct_fields": [ { "name": "server_address", - "type": "String", + "type": "Optional", + "optional_inner": { + "type": "String" + }, + "summary": null, + "description": null + }, + { + "name": "endpoints", + "type": "Optional", + "optional_inner": { + "type": "Array", + "array_item": { + "type": "String" + } + }, "summary": null, "description": null }, @@ -6874,6 +6889,20 @@ "value": "610", "summary": null, "description": null + }, + { + "name": "NotSupported", + "type": "Number", + "value": "611", + "summary": null, + "description": null + }, + { + "name": "NoEndpointsProvided", + "type": "Number", + "value": "612", + "summary": null, + "description": null } ], "summary": null, @@ -7160,6 +7189,23 @@ ], "summary": null, "description": null + }, + { + "name": "EndpointsSet", + "type": "Struct", + "struct_fields": [ + { + "name": "endpoints", + "type": "Array", + "array_item": { + "type": "String" + }, + "summary": "List of endpoints provided by server", + "description": null + } + ], + "summary": null, + "description": null } ], "functions": [ @@ -7462,6 +7508,74 @@ ] }, "errors": null + }, + { + "name": "fetch_endpoints", + "summary": "Requests the list of alternative endpoints from server", + "description": null, + "params": [ + { + "name": "context", + "type": "Generic", + "generic_name": "Arc", + "generic_args": [ + { + "type": "Ref", + "ref_name": "ClientContext" + } + ], + "summary": null, + "description": null + } + ], + "result": { + "type": "Generic", + "generic_name": "ClientResult", + "generic_args": [ + { + "type": "Ref", + "ref_name": "net.EndpointsSet" + } + ] + }, + "errors": null + }, + { + "name": "set_endpoints", + "summary": "Sets the list of endpoints to use on reinit", + "description": null, + "params": [ + { + "name": "context", + "type": "Generic", + "generic_name": "Arc", + "generic_args": [ + { + "type": "Ref", + "ref_name": "ClientContext" + } + ], + "summary": null, + "description": null + }, + { + "name": "params", + "type": "Ref", + "ref_name": "net.EndpointsSet", + "summary": null, + "description": null + } + ], + "result": { + "type": "Generic", + "generic_name": "ClientResult", + "generic_args": [ + { + "type": "None" + } + ] + }, + "errors": null } ] }, From db896be59510bdee725fc110951b4577496a039c Mon Sep 17 00:00:00 2001 From: elasticLove1 Date: Thu, 24 Dec 2020 15:51:44 +0300 Subject: [PATCH 13/19] Config docs --- ton_client/src/abi/mod.rs | 7 ++++++ ton_client/src/crypto/mod.rs | 9 +++++++ ton_client/src/json_interface/processing.rs | 6 +---- ton_client/src/net/types.rs | 27 +++++++++++++++++++++ 4 files changed, 44 insertions(+), 5 deletions(-) diff --git a/ton_client/src/abi/mod.rs b/ton_client/src/abi/mod.rs index f9c634404..9238586e2 100644 --- a/ton_client/src/abi/mod.rs +++ b/ton_client/src/abi/mod.rs @@ -74,16 +74,23 @@ fn deserialize_message_expiration_timeout_grow_factor<'de, D: Deserializer<'de>> #[derive(Deserialize, Debug, Clone, ApiType)] pub struct AbiConfig { + /// Workchain id that is used by default in DeploySet #[serde( default = "default_workchain", deserialize_with = "deserialize_workchain" )] pub workchain: i32, + + /// Message lifetime for contracts which ABI includes "expire" header. + /// The default value is 40 sec. #[serde( default = "default_message_expiration_timeout", deserialize_with = "deserialize_message_expiration_timeout" )] pub message_expiration_timeout: u32, + + /// Factor that increases the expiration timeout for each retry + /// The default value is 1.5 #[serde( default = "default_message_expiration_timeout_grow_factor", deserialize_with = "deserialize_message_expiration_timeout_grow_factor" diff --git a/ton_client/src/crypto/mod.rs b/ton_client/src/crypto/mod.rs index 291fea3ed..9ec8aa37b 100644 --- a/ton_client/src/crypto/mod.rs +++ b/ton_client/src/crypto/mod.rs @@ -105,17 +105,26 @@ fn deserialize_hdkey_derivation_path<'de, D: Deserializer<'de>>( } #[derive(Deserialize, Debug, Clone, ApiType)] +/// Crypto config. pub struct CryptoConfig { + /// Mnemonic dictionary that will be used by default in crypto funcions. + /// If not specified, 1 dictionary will be used. #[serde( default = "default_mnemonic_dictionary", deserialize_with = "deserialize_mnemonic_dictionary" )] pub mnemonic_dictionary: u8, + + /// Mnemonic word count that will be used by default in crypto functions. + /// If not specified the default value will be 12. #[serde( default = "default_mnemonic_word_count", deserialize_with = "deserialize_mnemonic_word_count" )] pub mnemonic_word_count: u8, + + /// Derivation path that will be used by default in crypto functions. + /// If not specified `m/44'/396'/0'/0/0` will be used. #[serde( default = "default_hdkey_derivation_path", deserialize_with = "deserialize_hdkey_derivation_path" diff --git a/ton_client/src/json_interface/processing.rs b/ton_client/src/json_interface/processing.rs index ec6a23adc..7e8867348 100644 --- a/ton_client/src/json_interface/processing.rs +++ b/ton_client/src/json_interface/processing.rs @@ -34,11 +34,7 @@ use std::sync::Arc; /// The intermediate events, such as `WillFetchFirstBlock`, `WillSend`, `DidSend`, /// `WillFetchNextBlock`, etc - are switched on/off by `send_events` flag /// and logged into the supplied callback function. -/// The retry configuration parameters are defined in config: -/// -/// pub const DEFAULT_EXPIRATION_RETRIES_LIMIT: i8 = 3; - max number of retries -/// pub const DEFAULT_EXPIRATION_TIMEOUT: u32 = 40000; - message expiration timeout in ms. -/// pub const DEFAULT_....expiration_timeout_grow_factor... = 1.5 - factor that increases the expiration timeout for each retry +/// The retry configuration parameters are defined in client's `NetworkConfig`. /// /// If contract's ABI does not include "expire" header /// then, if no transaction is found within the network timeout (see config parameter ), exits with error. diff --git a/ton_client/src/net/types.rs b/ton_client/src/net/types.rs index 41a8e2643..782d769dd 100644 --- a/ton_client/src/net/types.rs +++ b/ton_client/src/net/types.rs @@ -80,23 +80,50 @@ fn deserialize_reconnect_timeout<'de, D: Deserializer<'de>>( #[derive(Serialize, Deserialize, Debug, Clone, ApiType)] pub struct NetworkConfig { + /// DApp Server public address. + /// For instance, for `net.ton.dev/graphql` GraphQL endpoint the server address will be net.ton.dev pub server_address: Option, + + /// List of DApp Server addresses. Any correct URL format can be specified, including IP addresses pub endpoints: Option>, + + /// The number of automatic network retries that SDK performs in case of connection problems + /// The default value is 5. #[serde(default = "default_network_retries_count", deserialize_with = "deserialize_network_retries_count")] pub network_retries_count: i8, + + /// The number of automatic message processing retries that SDK performs + /// in case of `Message Expired (507)` error - but only for those messages which + /// local emulation was successfull or failed with replay protection error. + /// The default value is 5. #[serde(default = "default_message_retries_count", deserialize_with = "deserialize_message_retries_count")] pub message_retries_count: i8, + + /// Timeout that is used to process message delivery for the contracts + /// which ABI does not include "expire" header. + /// If the message is not delivered within the speficied timeout + /// the appropriate error occurs. #[serde(default = "default_message_processing_timeout", deserialize_with = "deserialize_message_processing_timeout")] pub message_processing_timeout: u32, + + /// Maximum timeout that is used for query response. + /// The default value is 40 sec. #[serde(default = "default_wait_for_timeout", deserialize_with = "deserialize_wait_for_timeout")] pub wait_for_timeout: u32, + + /// Maximum time difference between server and client. If client's device time is out of sink and difference is more than + /// the threshhold then error will occur. Also the error will occur if the specified threshhold is more than + /// `message_processing_timeout/2`. + /// The default value is 15 sec. #[serde(default = "default_out_of_sync_threshold", deserialize_with = "deserialize_out_of_sync_threshold")] pub out_of_sync_threshold: u32, + + /// Timeout between reconnect attempts #[serde(default = "default_reconnect_timeout", deserialize_with = "deserialize_reconnect_timeout")] pub reconnect_timeout: u32, From 81a4c43db52e52adf225cbef478e6587536a2c62 Mon Sep 17 00:00:00 2001 From: elasticLove1 Date: Thu, 24 Dec 2020 17:18:04 +0300 Subject: [PATCH 14/19] Update types.rs --- ton_client/src/net/types.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ton_client/src/net/types.rs b/ton_client/src/net/types.rs index 782d769dd..be5c29127 100644 --- a/ton_client/src/net/types.rs +++ b/ton_client/src/net/types.rs @@ -127,6 +127,8 @@ pub struct NetworkConfig { #[serde(default = "default_reconnect_timeout", deserialize_with = "deserialize_reconnect_timeout")] pub reconnect_timeout: u32, + + /// Access key to GraphQL API. At the moment is not used in production pub access_key: Option, } From d124e7c2fa50ffbd81f320c08fc714bad038a8b5 Mon Sep 17 00:00:00 2001 From: Alexey Vavilin Date: Thu, 24 Dec 2020 18:13:41 +0300 Subject: [PATCH 15/19] Test endpoints --- ton_client/src/net/server_info.rs | 2 +- ton_client/src/net/tests.rs | 7 ++++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/ton_client/src/net/server_info.rs b/ton_client/src/net/server_info.rs index a8a9500a9..b53600987 100644 --- a/ton_client/src/net/server_info.rs +++ b/ton_client/src/net/server_info.rs @@ -57,7 +57,7 @@ impl ServerInfo { format!("https://{}", base_url) }; - format!("{}/graphql", base_url) + format!("{}/graphql", base_url.trim_end_matches("/")) } pub async fn fetch(client_env: Arc, address: &str) -> ClientResult { diff --git a/ton_client/src/net/tests.rs b/ton_client/src/net/tests.rs index d29853117..ece663147 100644 --- a/ton_client/src/net/tests.rs +++ b/ton_client/src/net/tests.rs @@ -370,7 +370,12 @@ async fn find_last_shard_block() { #[tokio::test(core_threads = 2)] async fn test_endpoints() { return; - let client = TestClient::new(); + + let client = TestClient::new_with_config(json!({ + "network": { + "endpoints": ["cinet.tonlabs.io", "cinet2.tonlabs.io/"], + } + })); let endpoints: EndpointsSet = client .request_async("net.fetch_endpoints", ()) From 6cf45d19a00199167b020f0f8aa29d315abe90da Mon Sep 17 00:00:00 2001 From: Alexey Vavilin Date: Thu, 24 Dec 2020 18:19:24 +0300 Subject: [PATCH 16/19] Update CHANGELOG.md --- CHANGELOG.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 561c861f8..eee4d9089 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,11 @@ All notable changes to this project will be documented in this file. ### New - `reconnect_timeout` parameter in `NetworkConfig`. +- `endpoints` parameter in `NetworkConfig`. It contains the list of available server addresses to connect. +SDK will use one them with the least connect time. `server_address` parameter is still supported but +`endpoints` is prevailing. +- `net.fetch_endpoints` function to receieve available endpoints from server. +- `net.set_endpoints` function to set endpoints list for using on next reconnect. ### Fixed - send `GQL_TERMINATE_CONNECTION` and close websocket on leaving ws loop. From f8164138ab983b40fc58d1a95550f163de0df7af Mon Sep 17 00:00:00 2001 From: Alexey Vavilin Date: Thu, 24 Dec 2020 19:08:38 +0300 Subject: [PATCH 17/19] Update CHANGELOG.md --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index eee4d9089..512cd6afb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ SDK will use one them with the least connect time. `server_address` parameter is `endpoints` is prevailing. - `net.fetch_endpoints` function to receieve available endpoints from server. - `net.set_endpoints` function to set endpoints list for using on next reconnect. +- `ErrorCode` type in each module spec in `api.json`. ### Fixed - send `GQL_TERMINATE_CONNECTION` and close websocket on leaving ws loop. @@ -22,7 +23,6 @@ SDK will use one them with the least connect time. `server_address` parameter is - `tonclient-core-version` http header. - `net.find_last_shard_block` function returning account shard last block ID. - `boc.get_code_from_tvc` function extracting contract code from TVC image. -- `ErrorCode` type in each module spec in `api.json`. - **Debot Module:** - Add new variant `ParamsOfAppDebotBrowser::SwitchCompleted` to notify browser when all context actions are shown. - Added new 3 engine routines for crypto operations and 1 routine for querying account state (balance, state type, code, data) that can be used in debots. From a7cdf1c5e2fa3516e0a5d5ff34b9dc00c34eb939 Mon Sep 17 00:00:00 2001 From: elasticLove1 Date: Thu, 24 Dec 2020 22:50:11 +0300 Subject: [PATCH 18/19] Update processing.rs --- ton_client/src/json_interface/processing.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ton_client/src/json_interface/processing.rs b/ton_client/src/json_interface/processing.rs index 7e8867348..694f226ca 100644 --- a/ton_client/src/json_interface/processing.rs +++ b/ton_client/src/json_interface/processing.rs @@ -34,7 +34,8 @@ use std::sync::Arc; /// The intermediate events, such as `WillFetchFirstBlock`, `WillSend`, `DidSend`, /// `WillFetchNextBlock`, etc - are switched on/off by `send_events` flag /// and logged into the supplied callback function. -/// The retry configuration parameters are defined in client's `NetworkConfig`. +/// +/// The retry configuration parameters are defined in the client's `NetworkConfig` and `AbiConfig`. /// /// If contract's ABI does not include "expire" header /// then, if no transaction is found within the network timeout (see config parameter ), exits with error. From f66acd7fe3a3f92c55bbd8d7b23a514393836afc Mon Sep 17 00:00:00 2001 From: Sergei Voronezhskii Date: Thu, 24 Dec 2020 23:42:12 +0300 Subject: [PATCH 19/19] Regenerate docs/ update versions --- api/derive/Cargo.toml | 2 +- api/info/Cargo.toml | 2 +- api/test/Cargo.toml | 2 +- docs/mod_abi.md | 8 ++++---- docs/mod_client.md | 39 ++++++++++++++++++++++----------------- docs/mod_net.md | 9 +++------ docs/mod_processing.md | 6 +----- toncli/Cargo.toml | 2 +- tools/api.json | 40 ++++++++++++++++++++-------------------- 9 files changed, 54 insertions(+), 56 deletions(-) diff --git a/api/derive/Cargo.toml b/api/derive/Cargo.toml index 9c79850aa..cddb0c454 100644 --- a/api/derive/Cargo.toml +++ b/api/derive/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "api_derive" -version = "1.4.0" +version = "1.5.0" authors = ["Michael Vlasov "] edition = "2018" diff --git a/api/info/Cargo.toml b/api/info/Cargo.toml index 44f5c9559..ebe4c4370 100644 --- a/api/info/Cargo.toml +++ b/api/info/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "api_info" -version = "1.4.0" +version = "1.5.0" authors = ["Michael Vlasov "] edition = "2018" diff --git a/api/test/Cargo.toml b/api/test/Cargo.toml index bac591b76..a9b74a556 100644 --- a/api/test/Cargo.toml +++ b/api/test/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "api_test" -version = "1.3.0" +version = "1.5.0" authors = ["Michael Vlasov "] edition = "2018" diff --git a/docs/mod_abi.md b/docs/mod_abi.md index 398c9d0ca..32135cb93 100644 --- a/docs/mod_abi.md +++ b/docs/mod_abi.md @@ -532,11 +532,11 @@ enum MessageBodyType { ``` One of the following value: -- `Input = "Input"` – Message contains the input of the ABI function. -- `Output = "Output"` – Message contains the output of the ABI function. -- `InternalOutput = "InternalOutput"` – Message contains the input of the imported ABI function. +- `Input` – Message contains the input of the ABI function. +- `Output` – Message contains the output of the ABI function. +- `InternalOutput` – Message contains the input of the imported ABI function.
Occurs when contract sends an internal message to other
contract. -- `Event = "Event"` – Message contains the input of the ABI event. +- `Event` – Message contains the input of the ABI event. ## StateInitSource diff --git a/docs/mod_client.md b/docs/mod_client.md index 0b777bb4e..c6211c3c5 100644 --- a/docs/mod_client.md +++ b/docs/mod_client.md @@ -19,7 +19,7 @@ null [NetworkConfig](#NetworkConfig) -[CryptoConfig](#CryptoConfig) +[CryptoConfig](#CryptoConfig) – Crypto config. [AbiConfig](#AbiConfig) @@ -226,18 +226,23 @@ type NetworkConfig = { access_key?: string } ``` -- `server_address`?: _string_ -- `endpoints`?: _string[]_ -- `network_retries_count`?: _number_ -- `message_retries_count`?: _number_ -- `message_processing_timeout`?: _number_ -- `wait_for_timeout`?: _number_ -- `out_of_sync_threshold`?: _number_ -- `reconnect_timeout`?: _number_ -- `access_key`?: _string_ +- `server_address`?: _string_ – DApp Server public address. For instance, for `net.ton.dev/graphql` GraphQL endpoint the server address will be net.ton.dev +- `endpoints`?: _string[]_ – List of DApp Server addresses. +
Any correct URL format can be specified, including IP addresses +- `network_retries_count`?: _number_ – The number of automatic network retries that SDK performs in case of connection problems The default value is 5. +- `message_retries_count`?: _number_ – The number of automatic message processing retries that SDK performs in case of `Message Expired (507)` error - but only for those messages which local emulation was successfull or failed with replay protection error. The default value is 5. +- `message_processing_timeout`?: _number_ – Timeout that is used to process message delivery for the contracts which ABI does not include "expire" header. If the message is not delivered within the speficied timeout the appropriate error occurs. +- `wait_for_timeout`?: _number_ – Maximum timeout that is used for query response. The default value is 40 sec. +- `out_of_sync_threshold`?: _number_ – Maximum time difference between server and client. +
If client's device time is out of sink and difference is more thanthe threshhold then error will occur. Also the error will occur if the specified threshhold is more than
`message_processing_timeout/2`.
The default value is 15 sec. +- `reconnect_timeout`?: _number_ – Timeout between reconnect attempts +- `access_key`?: _string_ – Access key to GraphQL API. +
At the moment is not used in production ## CryptoConfig +Crypto config. + ```ts type CryptoConfig = { mnemonic_dictionary?: number, @@ -245,9 +250,9 @@ type CryptoConfig = { hdkey_derivation_path?: string } ``` -- `mnemonic_dictionary`?: _number_ -- `mnemonic_word_count`?: _number_ -- `hdkey_derivation_path`?: _string_ +- `mnemonic_dictionary`?: _number_ – Mnemonic dictionary that will be used by default in crypto funcions. If not specified, 1 dictionary will be used. +- `mnemonic_word_count`?: _number_ – Mnemonic word count that will be used by default in crypto functions. If not specified the default value will be 12. +- `hdkey_derivation_path`?: _string_ – Derivation path that will be used by default in crypto functions. If not specified `m/44'/396'/0'/0/0` will be used. ## AbiConfig @@ -256,11 +261,11 @@ type AbiConfig = { workchain?: number, message_expiration_timeout?: number, message_expiration_timeout_grow_factor?: number -} +}; ``` -- `workchain`?: _number_ -- `message_expiration_timeout`?: _number_ -- `message_expiration_timeout_grow_factor`?: _number_ +- `workchain`?: _number_ – Workchain id that is used by default in DeploySet +- `message_expiration_timeout`?: _number_ – Message lifetime for contracts which ABI includes "expire" header. The default value is 40 sec. +- `message_expiration_timeout_grow_factor`?: _number_ – Factor that increases the expiration timeout for each retry The default value is 1.5 ## BuildInfoDependency diff --git a/docs/mod_net.md b/docs/mod_net.md index f3ce891b8..924f25fc5 100644 --- a/docs/mod_net.md +++ b/docs/mod_net.md @@ -337,15 +337,12 @@ type OrderBy = { ## SortDirection ```ts -enum SortDirection { - ASC = "ASC", - DESC = "DESC" -} +type SortDirection = 'ASC' | 'DESC'; ``` One of the following value: -- `ASC = "ASC"` -- `DESC = "DESC"` +- `ASC` +- `DESC` ## ParamsOfQuery diff --git a/docs/mod_processing.md b/docs/mod_processing.md index 6972560a5..e5101a8f0 100644 --- a/docs/mod_processing.md +++ b/docs/mod_processing.md @@ -144,11 +144,7 @@ timeout: SDK recreates the message, sends it and processes it again. The intermediate events, such as `WillFetchFirstBlock`, `WillSend`, `DidSend`, `WillFetchNextBlock`, etc - are switched on/off by `send_events` flag and logged into the supplied callback function. -The retry configuration parameters are defined in config: - -pub const DEFAULT_EXPIRATION_RETRIES_LIMIT: i8 = 3; - max number of retries -pub const DEFAULT_EXPIRATION_TIMEOUT: u32 = 40000; - message expiration timeout in ms. -pub const DEFAULT_....expiration_timeout_grow_factor... = 1.5 - factor that increases the expiration timeout for each retry +The retry configuration parameters are defined in client's `NetworkConfig`. If contract's ABI does not include "expire" header then, if no transaction is found within the network timeout (see config parameter ), exits with error. diff --git a/toncli/Cargo.toml b/toncli/Cargo.toml index 4d9b09471..9a39e9d16 100644 --- a/toncli/Cargo.toml +++ b/toncli/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "toncli" -version = "1.4.1" +version = "1.5.0" description = "TON CLient Command Line Tool" authors = ["TON DEV SOLUTIONS LTD "] repository = "https://github.com/tonlabs/TON-SDK" diff --git a/tools/api.json b/tools/api.json index 5305fa029..5eb1333eb 100644 --- a/tools/api.json +++ b/tools/api.json @@ -322,7 +322,7 @@ "optional_inner": { "type": "String" }, - "summary": null, + "summary": "DApp Server public address. For instance, for `net.ton.dev/graphql` GraphQL endpoint the server address will be net.ton.dev", "description": null }, { @@ -334,8 +334,8 @@ "type": "String" } }, - "summary": null, - "description": null + "summary": "List of DApp Server addresses.", + "description": "Any correct URL format can be specified, including IP addresses" }, { "name": "network_retries_count", @@ -345,7 +345,7 @@ "number_type": "Int", "number_size": 8 }, - "summary": null, + "summary": "The number of automatic network retries that SDK performs in case of connection problems The default value is 5.", "description": null }, { @@ -356,7 +356,7 @@ "number_type": "Int", "number_size": 8 }, - "summary": null, + "summary": "The number of automatic message processing retries that SDK performs in case of `Message Expired (507)` error - but only for those messages which local emulation was successfull or failed with replay protection error. The default value is 5.", "description": null }, { @@ -367,7 +367,7 @@ "number_type": "UInt", "number_size": 32 }, - "summary": null, + "summary": "Timeout that is used to process message delivery for the contracts which ABI does not include \"expire\" header. If the message is not delivered within the speficied timeout the appropriate error occurs.", "description": null }, { @@ -378,7 +378,7 @@ "number_type": "UInt", "number_size": 32 }, - "summary": null, + "summary": "Maximum timeout that is used for query response. The default value is 40 sec.", "description": null }, { @@ -389,8 +389,8 @@ "number_type": "UInt", "number_size": 32 }, - "summary": null, - "description": null + "summary": "Maximum time difference between server and client.", + "description": "If client's device time is out of sink and difference is more thanthe threshhold then error will occur. Also the error will occur if the specified threshhold is more than\n`message_processing_timeout/2`.\nThe default value is 15 sec." }, { "name": "reconnect_timeout", @@ -400,7 +400,7 @@ "number_type": "UInt", "number_size": 32 }, - "summary": null, + "summary": "Timeout between reconnect attempts", "description": null }, { @@ -409,8 +409,8 @@ "optional_inner": { "type": "String" }, - "summary": null, - "description": null + "summary": "Access key to GraphQL API.", + "description": "At the moment is not used in production" } ], "summary": null, @@ -428,7 +428,7 @@ "number_type": "UInt", "number_size": 8 }, - "summary": null, + "summary": "Mnemonic dictionary that will be used by default in crypto funcions. If not specified, 1 dictionary will be used.", "description": null }, { @@ -439,7 +439,7 @@ "number_type": "UInt", "number_size": 8 }, - "summary": null, + "summary": "Mnemonic word count that will be used by default in crypto functions. If not specified the default value will be 12.", "description": null }, { @@ -448,11 +448,11 @@ "optional_inner": { "type": "String" }, - "summary": null, + "summary": "Derivation path that will be used by default in crypto functions. If not specified `m/44'/396'/0'/0/0` will be used.", "description": null } ], - "summary": null, + "summary": "Crypto config.", "description": null }, { @@ -467,7 +467,7 @@ "number_type": "Int", "number_size": 32 }, - "summary": null, + "summary": "Workchain id that is used by default in DeploySet", "description": null }, { @@ -478,7 +478,7 @@ "number_type": "UInt", "number_size": 32 }, - "summary": null, + "summary": "Message lifetime for contracts which ABI includes \"expire\" header. The default value is 40 sec.", "description": null }, { @@ -489,7 +489,7 @@ "number_type": "Float", "number_size": 32 }, - "summary": null, + "summary": "Factor that increases the expiration timeout for each retry The default value is 1.5", "description": null } ], @@ -6037,7 +6037,7 @@ { "name": "process_message", "summary": "Creates message, sends it to the network and monitors its processing.", - "description": "Creates ABI-compatible message,\nsends it to the network and monitors for the result transaction.\nDecodes the output messages' bodies.\n\nIf contract's ABI includes \"expire\" header, then\nSDK implements retries in case of unsuccessful message delivery within the expiration\ntimeout: SDK recreates the message, sends it and processes it again.\n\nThe intermediate events, such as `WillFetchFirstBlock`, `WillSend`, `DidSend`,\n`WillFetchNextBlock`, etc - are switched on/off by `send_events` flag\nand logged into the supplied callback function.\nThe retry configuration parameters are defined in config:\n\npub const DEFAULT_EXPIRATION_RETRIES_LIMIT: i8 = 3; - max number of retries\npub const DEFAULT_EXPIRATION_TIMEOUT: u32 = 40000; - message expiration timeout in ms.\npub const DEFAULT_....expiration_timeout_grow_factor... = 1.5 - factor that increases the expiration timeout for each retry\n\nIf contract's ABI does not include \"expire\" header\nthen, if no transaction is found within the network timeout (see config parameter ), exits with error.", + "description": "Creates ABI-compatible message,\nsends it to the network and monitors for the result transaction.\nDecodes the output messages' bodies.\n\nIf contract's ABI includes \"expire\" header, then\nSDK implements retries in case of unsuccessful message delivery within the expiration\ntimeout: SDK recreates the message, sends it and processes it again.\n\nThe intermediate events, such as `WillFetchFirstBlock`, `WillSend`, `DidSend`,\n`WillFetchNextBlock`, etc - are switched on/off by `send_events` flag\nand logged into the supplied callback function.\nThe retry configuration parameters are defined in client's `NetworkConfig`.\n\nIf contract's ABI does not include \"expire\" header\nthen, if no transaction is found within the network timeout (see config parameter ), exits with error.", "params": [ { "name": "context",