diff --git a/README.md b/README.md index f6f2743..5f412e0 100644 --- a/README.md +++ b/README.md @@ -3,12 +3,12 @@ **Community links:** [![Chat on Telegram](https://img.shields.io/badge/chat-on%20telegram-9cf.svg)](https://t.me/RADIANCE_TON_SDK) -[![SDK version](https://img.shields.io/badge/TON%20SDK%20version-1.38.0-green)](https://github.com/tonlabs/ever-sdk/tree/1.38.0) +[![SDK version](https://img.shields.io/badge/TON%20SDK%20version-1.41.0-green)](https://github.com/tonlabs/ever-sdk/tree/1.41.0) **Everscale scala client** is a simple scala binding to the [ever-sdk](https://github.com/tonlabs/ever-sdk). Features: -* All methods of the ever-sdk v 1.38.0 +* All methods of the ever-sdk v 1.41.0 * Interaction with the ever-sdk through synchronous an asynchronous calls * The every method contains inline-doc * The automatic download of the ever-sdk library for the current environment diff --git a/build.sbt b/build.sbt index 08e260b..aab00b5 100644 --- a/build.sbt +++ b/build.sbt @@ -26,7 +26,7 @@ val root = project in file(".") lazy val `everscale-client-scala` = project .settings( scalaVersion := "2.13.4", - version := "1.38.0", + version := "1.41.0", libraryDependencies ++= Seq( "io.circe" %% "circe-core" % circeVersion, "io.circe" %% "circe-derivation" % circeDerivationVersion, diff --git a/ever-sdk b/ever-sdk index c3906ea..9db08d9 160000 --- a/ever-sdk +++ b/ever-sdk @@ -1 +1 @@ -Subproject commit c3906ea236ef3624d0349f90d4ce44ee840453bb +Subproject commit 9db08d992acc221abc93cec9f011095d4642ce44 diff --git a/everscale-client-scala/src/main/scala/com/radiance/jvm/abi/AbiModule.scala b/everscale-client-scala/src/main/scala/com/radiance/jvm/abi/AbiModule.scala index d33b161..601215d 100644 --- a/everscale-client-scala/src/main/scala/com/radiance/jvm/abi/AbiModule.scala +++ b/everscale-client-scala/src/main/scala/com/radiance/jvm/abi/AbiModule.scala @@ -150,26 +150,34 @@ class AbiModule(ctx: Context) { /** * Decodes message body using provided message BOC and ABI. + * * @param abi * abi * @param message * message * @param allow_partial * allow_partial + * @param function_name + * function_name + * @param data_layout + * data_layout */ def decodeMessage( abi: AbiADT.Abi, message: String, - allow_partial: Option[Boolean] + allow_partial: Option[Boolean], + function_name: Option[String], + data_layout: Option[DataLayoutEnum.DataLayout] ): Future[Either[Throwable, DecodedMessageBody]] = { ctx.execAsync[ParamsOfDecodeMessage, DecodedMessageBody]( "abi.decode_message", - ParamsOfDecodeMessage(abi, message, allow_partial) + ParamsOfDecodeMessage(abi, message, allow_partial, function_name, data_layout) ) } /** * Decodes message body using provided body BOC and ABI. + * * @param abi * abi * @param body @@ -178,16 +186,22 @@ class AbiModule(ctx: Context) { * is_internal * @param allow_partial * allow_partial + * @param function_name + * function_name + * @param data_layout + * data_layout */ def decodeMessageBody( abi: AbiADT.Abi, body: String, is_internal: Boolean, - allow_partial: Option[Boolean] + allow_partial: Option[Boolean], + function_name: Option[String], + data_layout: Option[DataLayoutEnum.DataLayout] ): Future[Either[Throwable, DecodedMessageBody]] = { ctx.execAsync[ParamsOfDecodeMessageBody, DecodedMessageBody]( "abi.decode_message_body", - ParamsOfDecodeMessageBody(abi, body, is_internal, allow_partial) + ParamsOfDecodeMessageBody(abi, body, is_internal, allow_partial, function_name, data_layout) ) } @@ -363,6 +377,8 @@ class AbiModule(ctx: Context) { * parameter with default value here> * * Default value is 0. + * @param signature_id + * signature_id */ def encodeMessage( abi: AbiADT.Abi, @@ -370,18 +386,12 @@ class AbiModule(ctx: Context) { deploy_set: Option[DeploySet], call_set: Option[CallSet], signer: SignerADT.Signer, - processing_try_index: Option[Long] + processing_try_index: Option[Long], + signature_id: Option[Int] ): Future[Either[Throwable, ResultOfEncodeMessage]] = { ctx.execAsync[ParamsOfEncodeMessage, ResultOfEncodeMessage]( "abi.encode_message", - ParamsOfEncodeMessage( - abi, - address, - deploy_set, - call_set, - signer, - processing_try_index - ) + ParamsOfEncodeMessage(abi, address, deploy_set, call_set, signer, processing_try_index, signature_id) ) } @@ -408,6 +418,8 @@ class AbiModule(ctx: Context) { * @param address * Since ABI version 2.3 destination address of external inbound message is used in message body signature * calculation. Should be provided when signed external inbound message body is created. Otherwise can be omitted. + * @param signature_id + * signature_id */ def encodeMessageBody( abi: AbiADT.Abi, @@ -415,18 +427,33 @@ class AbiModule(ctx: Context) { is_internal: Boolean, signer: SignerADT.Signer, processing_try_index: Option[Long], - address: Option[String] + address: Option[String], + signature_id: Option[Int] ): Future[Either[Throwable, ResultOfEncodeMessageBody]] = { ctx.execAsync[ParamsOfEncodeMessageBody, ResultOfEncodeMessageBody]( "abi.encode_message_body", - ParamsOfEncodeMessageBody( - abi, - call_set, - is_internal, - signer, - processing_try_index, - address - ) + ParamsOfEncodeMessageBody(abi, call_set, is_internal, signer, processing_try_index, address, signature_id) + ) + } + + /** + * Extracts signature from message body and calculates hash to verify the signature + * + * @param abi + * abi + * @param message + * message + * @param signature_id + * signature_id + */ + def getSignatureData( + abi: AbiADT.Abi, + message: String, + signature_id: Option[Int] + ): Future[Either[Throwable, ResultOfGetSignatureData]] = { + ctx.execAsync[ParamsOfGetSignatureData, ResultOfGetSignatureData]( + "abi.get_signature_data", + ParamsOfGetSignatureData(abi, message, signature_id) ) } diff --git a/everscale-client-scala/src/main/scala/com/radiance/jvm/abi/Types.scala b/everscale-client-scala/src/main/scala/com/radiance/jvm/abi/Types.scala index ec27f9c..a9a72dd 100644 --- a/everscale-client-scala/src/main/scala/com/radiance/jvm/abi/Types.scala +++ b/everscale-client-scala/src/main/scala/com/radiance/jvm/abi/Types.scala @@ -152,6 +152,23 @@ object CallSet { implicit val encoder: Encoder[CallSet] = deriveEncoder[CallSet] } +object DataLayoutEnum { + sealed trait DataLayout + + /** + * Decode message body as function input parameters. + */ + case object Input extends DataLayout + + /** + * Decode message body as function output. + */ + case object Output extends DataLayout + + implicit val codec: Codec[DataLayout] = + extras.semiauto.deriveEnumerationCodec[DataLayout] +} + case class DecodedMessageBody( body_type: MessageBodyTypeEnum.MessageBodyType, name: String, @@ -296,7 +313,13 @@ object ParamsOfDecodeInitialData { deriveEncoder[ParamsOfDecodeInitialData] } -case class ParamsOfDecodeMessage(abi: AbiADT.Abi, message: String, allow_partial: Option[Boolean]) +case class ParamsOfDecodeMessage( + abi: AbiADT.Abi, + message: String, + allow_partial: Option[Boolean], + function_name: Option[String], + data_layout: Option[DataLayoutEnum.DataLayout] +) object ParamsOfDecodeMessage { implicit val encoder: Encoder[ParamsOfDecodeMessage] = @@ -307,7 +330,9 @@ case class ParamsOfDecodeMessageBody( abi: AbiADT.Abi, body: String, is_internal: Boolean, - allow_partial: Option[Boolean] + allow_partial: Option[Boolean], + function_name: Option[String], + data_layout: Option[DataLayoutEnum.DataLayout] ) object ParamsOfDecodeMessageBody { @@ -362,7 +387,8 @@ case class ParamsOfEncodeMessage( deploy_set: Option[DeploySet], call_set: Option[CallSet], signer: SignerADT.Signer, - processing_try_index: Option[Long] + processing_try_index: Option[Long], + signature_id: Option[Int] ) object ParamsOfEncodeMessage { @@ -376,7 +402,8 @@ case class ParamsOfEncodeMessageBody( is_internal: Boolean, signer: SignerADT.Signer, processing_try_index: Option[Long], - address: Option[String] + address: Option[String], + signature_id: Option[Int] ) object ParamsOfEncodeMessageBody { @@ -384,6 +411,13 @@ object ParamsOfEncodeMessageBody { deriveEncoder[ParamsOfEncodeMessageBody] } +case class ParamsOfGetSignatureData(abi: AbiADT.Abi, message: String, signature_id: Option[Int]) + +object ParamsOfGetSignatureData { + implicit val encoder: Encoder[ParamsOfGetSignatureData] = + deriveEncoder[ParamsOfGetSignatureData] +} + case class ParamsOfUpdateInitialData( abi: Option[AbiADT.Abi], data: String, @@ -493,6 +527,13 @@ object ResultOfEncodeMessageBody { deriveDecoder[ResultOfEncodeMessageBody] } +case class ResultOfGetSignatureData(signature: String, unsigned: String) + +object ResultOfGetSignatureData { + implicit val decoder: Decoder[ResultOfGetSignatureData] = + deriveDecoder[ResultOfGetSignatureData] +} + case class ResultOfUpdateInitialData(data: String) object ResultOfUpdateInitialData { diff --git a/everscale-client-scala/src/main/scala/com/radiance/jvm/client/Types.scala b/everscale-client-scala/src/main/scala/com/radiance/jvm/client/Types.scala index 86c5bb7..921726f 100644 --- a/everscale-client-scala/src/main/scala/com/radiance/jvm/client/Types.scala +++ b/everscale-client-scala/src/main/scala/com/radiance/jvm/client/Types.scala @@ -1,6 +1,7 @@ package com.radiance.jvm.client import com.radiance.jvm._ +import com.radiance.jvm.crypto._ import io.circe._ import io.circe.derivation._ import io.circe.generic.extras @@ -28,6 +29,12 @@ object AppRequestResultADT { extras.semiauto.deriveConfiguredEncoder[AppRequestResult] } +case class BindingConfig(library: Option[String], version: Option[String]) + +object BindingConfig { + implicit val codec: Codec[BindingConfig] = deriveCodec[BindingConfig] +} + case class BocConfig(cache_max_size: Option[Long]) object BocConfig { @@ -42,6 +49,7 @@ object BuildInfoDependency { } case class ClientConfig( + binding: Option[BindingConfig], network: Option[NetworkConfig], crypto: Option[CryptoConfig] = None, abi: Option[AbiConfig] = None, @@ -134,6 +142,10 @@ object ClientErrorCodeEnum { val code: String = "17" } + case object InvalidData extends ClientErrorCode { + override val code: String = "36" + } + case object InvalidHandle extends ClientErrorCode { override val code: String = "34" } @@ -209,10 +221,9 @@ object ClientErrorCodeEnum { } case class CryptoConfig( - mnemonic_dictionary: Option[Long], + mnemonic_dictionary: Option[MnemonicDictionaryEnum.MnemonicDictionary], mnemonic_word_count: Option[Long], - hdkey_derivation_path: Option[String], - hdkey_compliant: Option[Boolean] + hdkey_derivation_path: Option[String] ) object CryptoConfig { @@ -236,6 +247,7 @@ case class NetworkConfig( queries_protocol: Option[NetworkQueriesProtocolEnum.NetworkQueriesProtocol] = None, first_remp_status_timeout: Option[Long] = None, next_remp_status_timeout: Option[Long] = None, + signature_id: Option[Int] = None, access_key: Option[String] = None ) @@ -256,7 +268,8 @@ object NetworkQueriesProtocolEnum { case object HTTP extends NetworkQueriesProtocol /** - * All GraphQL queries will be served using single web socket connection. + * All GraphQL queries will be served using single web socket connection. SDK is tested to reliably handle 5000 + * parallel network requests (sending and processing messages, quering and awaiting blockchain data) */ case object WS extends NetworkQueriesProtocol diff --git a/everscale-client-scala/src/main/scala/com/radiance/jvm/crypto/CryptoModule.scala b/everscale-client-scala/src/main/scala/com/radiance/jvm/crypto/CryptoModule.scala index 87ab023..a94eccc 100644 --- a/everscale-client-scala/src/main/scala/com/radiance/jvm/crypto/CryptoModule.scala +++ b/everscale-client-scala/src/main/scala/com/radiance/jvm/crypto/CryptoModule.scala @@ -336,7 +336,7 @@ class CryptoModule(private val ctx: Context) { */ def hdkeyXprvFromMnemonic( phrase: String, - dictionary: Option[Long], + dictionary: Option[MnemonicDictionaryEnum.MnemonicDictionary], word_count: Option[Long] ): Either[Throwable, ResultOfHDKeyXPrvFromMnemonic] = ctx.execSync[ParamsOfHDKeyXPrvFromMnemonic, ResultOfHDKeyXPrvFromMnemonic]( @@ -359,7 +359,7 @@ class CryptoModule(private val ctx: Context) { def mnemonicDeriveSignKeys( phrase: String, path: Option[String], - dictionary: Option[Long], + dictionary: Option[MnemonicDictionaryEnum.MnemonicDictionary], word_count: Option[Long] ): Either[Throwable, KeyPair] = ctx.execSync[ParamsOfMnemonicDeriveSignKeys, KeyPair]( @@ -378,7 +378,7 @@ class CryptoModule(private val ctx: Context) { */ def mnemonicFromEntropy( entropy: String, - dictionary: Option[Long], + dictionary: Option[MnemonicDictionaryEnum.MnemonicDictionary], word_count: Option[Long] ): Either[Throwable, ResultOfMnemonicFromEntropy] = ctx.execSync[ParamsOfMnemonicFromEntropy, ResultOfMnemonicFromEntropy]( @@ -392,7 +392,7 @@ class CryptoModule(private val ctx: Context) { * Mnemonic word count */ def mnemonicFromRandom( - dictionary: Option[Long], + dictionary: Option[MnemonicDictionaryEnum.MnemonicDictionary], word_count: Option[Long] ): Either[Throwable, ResultOfMnemonicFromRandom] = ctx.execSync[ParamsOfMnemonicFromRandom, ResultOfMnemonicFromRandom]( @@ -412,7 +412,7 @@ class CryptoModule(private val ctx: Context) { */ def mnemonicVerify( phrase: String, - dictionary: Option[Long], + dictionary: Option[MnemonicDictionaryEnum.MnemonicDictionary], word_count: Option[Long] ): Either[Throwable, ResultOfMnemonicVerify] = ctx.execSync[ParamsOfMnemonicVerify, ResultOfMnemonicVerify]( @@ -426,7 +426,7 @@ class CryptoModule(private val ctx: Context) { * Dictionary identifier */ def mnemonicWords( - dictionary: Option[Long] + dictionary: Option[MnemonicDictionaryEnum.MnemonicDictionary] ): Either[Throwable, ResultOfMnemonicWords] = ctx .execSync[ParamsOfMnemonicWords, ResultOfMnemonicWords]( diff --git a/everscale-client-scala/src/main/scala/com/radiance/jvm/crypto/Types.scala b/everscale-client-scala/src/main/scala/com/radiance/jvm/crypto/Types.scala index 7ee4273..621bf7b 100644 --- a/everscale-client-scala/src/main/scala/com/radiance/jvm/crypto/Types.scala +++ b/everscale-client-scala/src/main/scala/com/radiance/jvm/crypto/Types.scala @@ -75,12 +75,17 @@ object CryptoBoxSecretADT { /** * Crypto Box Secret. */ - case class PredefinedSeedPhrase(phrase: String, dictionary: Long, wordcount: Long) extends CryptoBoxSecret + case class PredefinedSeedPhrase( + phrase: String, + dictionary: MnemonicDictionaryEnum.MnemonicDictionary, + wordcount: Long + ) extends CryptoBoxSecret /** * Crypto Box Secret. */ - case class RandomSeedPhrase(dictionary: Long, wordcount: Long) extends CryptoBoxSecret + case class RandomSeedPhrase(dictionary: MnemonicDictionaryEnum.MnemonicDictionary, wordcount: Long) + extends CryptoBoxSecret import com.radiance.jvm.DiscriminatorConfig._ implicit val encoder: Encoder[CryptoBoxSecret] = @@ -265,6 +270,78 @@ object KeyPair { implicit val codec: Codec[KeyPair] = deriveCodec[KeyPair] } +object MnemonicDictionaryEnum { + sealed trait MnemonicDictionary { + val code: String + } + + /** + * Chinese simplified BIP-39 dictionary + */ + case object ChineseSimplified extends MnemonicDictionary { + override val code: String = "2" + } + + /** + * Chinese traditional BIP-39 dictionary + */ + case object ChineseTraditional extends MnemonicDictionary { + override val code: String = "3" + } + + /** + * English BIP-39 dictionary + */ + case object English extends MnemonicDictionary { + override val code: String = "1" + } + + /** + * French BIP-39 dictionary + */ + case object French extends MnemonicDictionary { + override val code: String = "4" + } + + /** + * Italian BIP-39 dictionary + */ + case object Italian extends MnemonicDictionary { + override val code: String = "5" + } + + /** + * Japanese BIP-39 dictionary + */ + case object Japanese extends MnemonicDictionary { + override val code: String = "6" + } + + /** + * Korean BIP-39 dictionary + */ + case object Korean extends MnemonicDictionary { + override val code: String = "7" + } + + /** + * Spanish BIP-39 dictionary + */ + case object Spanish extends MnemonicDictionary { + override val code: String = "8" + } + + /** + * TON compatible dictionary + */ + case object Ton extends MnemonicDictionary { + override val code: String = "0" + } + + implicit val codec: Codec[MnemonicDictionary] = + extras.semiauto.deriveEnumerationCodec[MnemonicDictionary] +} + case class NaclBoxParamsCB(their_public: String, nonce: String) object NaclBoxParamsCB { @@ -485,7 +562,7 @@ object ParamsOfHDKeySecretFromXPrv { case class ParamsOfHDKeyXPrvFromMnemonic( phrase: String, - dictionary: Option[Long], + dictionary: Option[MnemonicDictionaryEnum.MnemonicDictionary], word_count: Option[Long] ) @@ -497,7 +574,7 @@ object ParamsOfHDKeyXPrvFromMnemonic { case class ParamsOfMnemonicDeriveSignKeys( phrase: String, path: Option[String], - dictionary: Option[Long], + dictionary: Option[MnemonicDictionaryEnum.MnemonicDictionary], word_count: Option[Long] ) @@ -508,7 +585,7 @@ object ParamsOfMnemonicDeriveSignKeys { case class ParamsOfMnemonicFromEntropy( entropy: String, - dictionary: Option[Long], + dictionary: Option[MnemonicDictionaryEnum.MnemonicDictionary], word_count: Option[Long] ) @@ -518,7 +595,7 @@ object ParamsOfMnemonicFromEntropy { } case class ParamsOfMnemonicFromRandom( - dictionary: Option[Long], + dictionary: Option[MnemonicDictionaryEnum.MnemonicDictionary], word_count: Option[Long] ) @@ -529,7 +606,7 @@ object ParamsOfMnemonicFromRandom { case class ParamsOfMnemonicVerify( phrase: String, - dictionary: Option[Long], + dictionary: Option[MnemonicDictionaryEnum.MnemonicDictionary], word_count: Option[Long] ) @@ -538,7 +615,7 @@ object ParamsOfMnemonicVerify { deriveEncoder[ParamsOfMnemonicVerify] } -case class ParamsOfMnemonicWords(dictionary: Option[Long]) +case class ParamsOfMnemonicWords(dictionary: Option[MnemonicDictionaryEnum.MnemonicDictionary]) object ParamsOfMnemonicWords { implicit val encoder: Encoder[ParamsOfMnemonicWords] = @@ -808,7 +885,11 @@ object ResultOfGetCryptoBoxInfo { deriveDecoder[ResultOfGetCryptoBoxInfo] } -case class ResultOfGetCryptoBoxSeedPhrase(phrase: String, dictionary: Long, wordcount: Long) +case class ResultOfGetCryptoBoxSeedPhrase( + phrase: String, + dictionary: MnemonicDictionaryEnum.MnemonicDictionary, + wordcount: Long +) object ResultOfGetCryptoBoxSeedPhrase { implicit val decoder: Decoder[ResultOfGetCryptoBoxSeedPhrase] = diff --git a/everscale-client-scala/src/main/scala/com/radiance/jvm/net/NetModule.scala b/everscale-client-scala/src/main/scala/com/radiance/jvm/net/NetModule.scala index 10cf901..c4d9187 100644 --- a/everscale-client-scala/src/main/scala/com/radiance/jvm/net/NetModule.scala +++ b/everscale-client-scala/src/main/scala/com/radiance/jvm/net/NetModule.scala @@ -212,6 +212,13 @@ class NetModule(private val ctx: Context) { ctx.execAsync[Unit, ResultOfGetEndpoints]("net.fetch_endpoints", ()) } + /** + * Returns signature ID for configured network if it should be used in messages signature + */ + def getSignatureId(): Future[Either[Throwable, ResultOfGetSignatureId]] = { + ctx.execAsync[Unit, ResultOfGetSignatureId]("net.get_signature_id", ()) + } + /** * Returns next available items. In addition to available items this function returns the `has_more` flag indicating * that the iterator isn't reach the end of the iterated range yet. @@ -327,7 +334,7 @@ class NetModule(private val ctx: Context) { * * Function reads transactions layer by layer, by pages of 20 transactions. * - * The retrieval prosess goes like this: Let's assume we have an infinite chain of transactions and each transaction + * The retrieval process goes like this: Let's assume we have an infinite chain of transactions and each transaction * generates 5 messages. * 1. Retrieve 1st message (input parameter) and corresponding transaction - put it into result. It is the first * level of the tree of transactions - its root. Retrieve 5 out message ids from the transaction for next steps. @@ -344,6 +351,7 @@ class NetModule(private val ctx: Context) { * To summarize, it is guaranteed that each message in `result.messages` has the corresponding transaction in the * `result.transactions`. But there is no guarantee that all messages from transactions `out_msgs` are presented in * `result.messages`. So the application has to continue retrieval for missing messages if it requires. + * * @param in_msg * in_msg * @param abi_registry @@ -351,19 +359,25 @@ class NetModule(private val ctx: Context) { * @param timeout * If some of the following messages and transactions are missing yet The maximum waiting time is regulated by this * option. + * + * Default value is 60000 (1 min). If `timeout` is set to 0 then function will wait infinitely until the whole + * transaction tree is executed + * @param transaction_max_count + * If transaction tree contains more transaction then this parameter then only first `transaction_max_count` + * transaction are awaited and returned. + * + * Default value is 50. If `transaction_max_count` is set to 0 then no limitation on transaction count is used and all + * transaction are returned. */ def queryTransactionTree( in_msg: String, abi_registry: Option[List[AbiADT.Abi]], - timeout: Option[Long] + timeout: Option[Long], + transaction_max_count: Option[Long] ): Future[Either[Throwable, ResultOfQueryTransactionTree]] = { ctx.execAsync[ParamsOfQueryTransactionTree, ResultOfQueryTransactionTree]( "net.query_transaction_tree", - ParamsOfQueryTransactionTree( - in_msg, - abi_registry, - timeout - ) + ParamsOfQueryTransactionTree(in_msg, abi_registry, timeout, transaction_max_count) ) } @@ -389,9 +403,10 @@ class NetModule(private val ctx: Context) { } /** - * Resumes block iterator. The iterator stays exactly at the same position where the `resume_state` was catched. + * Resumes block iterator. The iterator stays exactly at the same position where the `resume_state` was caught. * * Application should call the `remove_iterator` when iterator is no longer required. + * * @param resume_state * Same as value returned from `iterator_next`. */ @@ -449,7 +464,7 @@ class NetModule(private val ctx: Context) { * * ### Important Notes on Subscriptions * - * Unfortunately sometimes the connection with the network brakes down. In this situation the library attempts to + * Unfortunately sometimes the connection with the network breaks down. In this situation the library attempts to * reconnect to the network. This reconnection sequence can take significant time. All of this time the client is * disconnected from the network. * @@ -469,6 +484,7 @@ class NetModule(private val ctx: Context) { * query for this object and handle actual data as a regular data from the subscription. * - If application monitors sequence of some objects (for example transactions of the specific account): * application must refresh all cached (or visible to user) lists where this sequences presents. + * * @param subscription * subscription * @param variables diff --git a/everscale-client-scala/src/main/scala/com/radiance/jvm/net/Types.scala b/everscale-client-scala/src/main/scala/com/radiance/jvm/net/Types.scala index 7f376a4..dab927d 100644 --- a/everscale-client-scala/src/main/scala/com/radiance/jvm/net/Types.scala +++ b/everscale-client-scala/src/main/scala/com/radiance/jvm/net/Types.scala @@ -77,6 +77,9 @@ object NetErrorCode { case object GetSubscriptionResultFailed extends NetErrorCode { override val code: String = "604" } + case object GraphqlConnectionError extends NetErrorCode { + override val code: String = "617" + } case object GraphqlError extends NetErrorCode { override val code: String = "608" } @@ -101,6 +104,9 @@ object NetErrorCode { case object QueryFailed extends NetErrorCode { override val code: String = "601" } + case object QueryTransactionTreeTimeout extends NetErrorCode { + override val code: String = "616" + } case object SubscribeFailed extends NetErrorCode { override val code: String = "602" } @@ -228,9 +234,9 @@ object ParamsOfQueryOperationADT { case class ParamsOfQueryTransactionTree( in_msg: String, abi_registry: Option[List[AbiADT.Abi]], - timeout: Option[Long] + timeout: Option[Long], + transaction_max_count: Option[Long] ) - object ParamsOfQueryTransactionTree { implicit val encoder: Encoder[ParamsOfQueryTransactionTree] = deriveEncoder[ParamsOfQueryTransactionTree] } @@ -310,6 +316,13 @@ object ResultOfGetEndpoints { deriveDecoder[ResultOfGetEndpoints] } +case class ResultOfGetSignatureId(signature_id: Option[Int]) + +object ResultOfGetSignatureId { + implicit val decoder: Decoder[ResultOfGetSignatureId] = + deriveDecoder[ResultOfGetSignatureId] +} + case class ResultOfIteratorNext(items: List[Value], has_more: Boolean, resume_state: Option[Value]) object ResultOfIteratorNext { diff --git a/everscale-client-scala/src/main/scala/com/radiance/jvm/processing/Types.scala b/everscale-client-scala/src/main/scala/com/radiance/jvm/processing/Types.scala index c700142..d14be70 100644 --- a/everscale-client-scala/src/main/scala/com/radiance/jvm/processing/Types.scala +++ b/everscale-client-scala/src/main/scala/com/radiance/jvm/processing/Types.scala @@ -105,27 +105,51 @@ object ProcessingErrorCodeEnum { object ProcessingEventADT { sealed trait ProcessingEvent - case class DidSend(shard_block_id: String, message_id: String, message: String) extends ProcessingEvent - case class FetchFirstBlockFailed(error: ClientError) extends ProcessingEvent - case class FetchNextBlockFailed(shard_block_id: String, message_id: String, message: String, error: ClientError) + + case class DidSend(shard_block_id: String, message_id: String, message_dst: String, message: String) + extends ProcessingEvent + + case class FetchFirstBlockFailed(error: ClientError, message_id: String, message_dst: String) extends ProcessingEvent + + case class FetchNextBlockFailed( + shard_block_id: String, + message_id: String, + message_dst: String, + message: String, + error: ClientError + ) extends ProcessingEvent + + case class MessageExpired(message_id: String, message_dst: String, message: String, error: ClientError) extends ProcessingEvent - case class MessageExpired(message_id: String, message: String, error: ClientError) extends ProcessingEvent - case class RempError(error: ClientError) extends ProcessingEvent - case class RempIncludedIntoAcceptedBlock(message_id: String, timestamp: BigInt, json: Value) extends ProcessingEvent - case class RempIncludedIntoBlock(message_id: String, timestamp: BigInt, json: Value) extends ProcessingEvent - case class RempOther(message_id: String, timestamp: BigInt, json: Value) extends ProcessingEvent - case class RempSentToValidators(message_id: String, timestamp: BigInt, json: Value) extends ProcessingEvent - case class SendFailed(shard_block_id: String, message_id: String, message: String, error: ClientError) + + case class RempError(message_id: String, message_dst: String, error: ClientError) extends ProcessingEvent + + case class RempIncludedIntoAcceptedBlock(message_id: String, message_dst: String, timestamp: BigInt, json: Value) + extends ProcessingEvent + + case class RempIncludedIntoBlock(message_id: String, message_dst: String, timestamp: BigInt, json: Value) extends ProcessingEvent - /** - * Notifies the application that the account's current shard block will be fetched from the network. This step is - * performed before the message sending so that sdk knows starting from which block it will search for the - * transaction. Fetched block will be used later in waiting phase. - */ - case object WillFetchFirstBlock extends ProcessingEvent - case class WillFetchNextBlock(shard_block_id: String, message_id: String, message: String) extends ProcessingEvent - case class WillSend(shard_block_id: String, message_id: String, message: String) extends ProcessingEvent + case class RempOther(message_id: String, message_dst: String, timestamp: BigInt, json: Value) extends ProcessingEvent + + case class RempSentToValidators(message_id: String, message_dst: String, timestamp: BigInt, json: Value) + extends ProcessingEvent + + case class SendFailed( + shard_block_id: String, + message_id: String, + message_dst: String, + message: String, + error: ClientError + ) extends ProcessingEvent + + case class WillFetchFirstBlock(message_id: String, message_dst: String) extends ProcessingEvent + + case class WillFetchNextBlock(shard_block_id: String, message_id: String, message_dst: String, message: String) + extends ProcessingEvent + + case class WillSend(shard_block_id: String, message_id: String, message_dst: String, message: String) + extends ProcessingEvent } case class ResultOfProcessMessage( diff --git a/everscale-client-scala/src/main/scala/com/radiance/jvm/tvm/TvmModule.scala b/everscale-client-scala/src/main/scala/com/radiance/jvm/tvm/TvmModule.scala index fd769ec..16f08d4 100644 --- a/everscale-client-scala/src/main/scala/com/radiance/jvm/tvm/TvmModule.scala +++ b/everscale-client-scala/src/main/scala/com/radiance/jvm/tvm/TvmModule.scala @@ -13,7 +13,7 @@ class TvmModule(private val ctx: Context) { * Executor - the same component that is used on Validator Nodes. * * Can be used for contract debugging, to find out the reason why a message was not delivered successfully. Validators - * throw away the failed external inbound messages (if they failed bedore `ACCEPT`) in the real network. This is why + * throw away the failed external inbound messages (if they failed before `ACCEPT`) in the real network. This is why * these messages are impossible to debug in the real network. With the help of run_executor you can do that. In fact, * `process_message` function performs local check with `run_executor` if there was no transaction as a result of * processing and returns the error, if there is one. @@ -36,6 +36,7 @@ class TvmModule(private val ctx: Context) { * `execution_options` parameter. * * If you need to see the aborted transaction as a result, not as an error, set `skip_transaction_check` to `true`. + * * @param message * Must be encoded as base64. * @param account diff --git a/everscale-client-scala/src/main/scala/com/radiance/jvm/tvm/Types.scala b/everscale-client-scala/src/main/scala/com/radiance/jvm/tvm/Types.scala index d4fab83..c90c08e 100644 --- a/everscale-client-scala/src/main/scala/com/radiance/jvm/tvm/Types.scala +++ b/everscale-client-scala/src/main/scala/com/radiance/jvm/tvm/Types.scala @@ -29,7 +29,8 @@ case class ExecutionOptions( block_time: Option[Long], block_lt: Option[BigInt], transaction_lt: Option[BigInt], - chksig_always_succeed: Option[Boolean] + chksig_always_succeed: Option[Boolean], + signature_id: Option[Int] ) object ExecutionOptions { diff --git a/everscale-client-scala/src/main/scala/com/radiance/samples/Configuration.scala b/everscale-client-scala/src/main/scala/com/radiance/samples/Configuration.scala index e74ebb4..2b37ca9 100644 --- a/everscale-client-scala/src/main/scala/com/radiance/samples/Configuration.scala +++ b/everscale-client-scala/src/main/scala/com/radiance/samples/Configuration.scala @@ -1,5 +1,7 @@ package com.radiance.samples +import com.radiance.jvm.crypto.MnemonicDictionaryEnum + object Configuration { object Sample1 { @@ -26,14 +28,14 @@ object Configuration { NetworkQueriesProtocolEnum.HTTP.some: Option[NetworkQueriesProtocolEnum.NetworkQueriesProtocol], first_remp_status_timeout = 60000L.some: Option[Long], next_remp_status_timeout = 60000L.some: Option[Long], + signature_id = None, access_key = "access_key".some: Option[String] ) val cryptoConfig: CryptoConfig = CryptoConfig( - 1L.some, // mnemonic_dictionary: Option[Long] - 12L.some, // mnemonic_word_count: Option[Long] - "m/44'/396'/0'/0/0".some, // hdkey_derivation_path: Option[String] - true.some // hdkey_compliant: Option[Boolean] + mnemonic_dictionary = MnemonicDictionaryEnum.Ton.some, + mnemonic_word_count = 12L.some, + hdkey_derivation_path = "m/44'/396'/0'/0/0".some ) val abiConfig: AbiConfig = AbiConfig( @@ -43,9 +45,13 @@ object Configuration { ) val clientConfig: ClientConfig = ClientConfig( - networkConfig.some, - cryptoConfig.some, - abiConfig.some + binding = None, + network = networkConfig.some, + crypto = cryptoConfig.some, + abi = abiConfig.some, + boc = None, + proofs = None, + local_storage_path = None ) implicit val ec: ExecutionContext = ExecutionContext.global val ctx: Context = Context(clientConfig) @@ -58,6 +64,7 @@ object Configuration { import scala.concurrent.ExecutionContext val clientConfig: ClientConfig = ClientConfig( + None, NetworkConfig("net.ton.dev".some).some ) implicit val ec: ExecutionContext = ExecutionContext.global diff --git a/everscale-client-scala/src/main/scala/com/radiance/samples/ContractDeploy.scala b/everscale-client-scala/src/main/scala/com/radiance/samples/ContractDeploy.scala index 3a40790..408ee9d 100644 --- a/everscale-client-scala/src/main/scala/com/radiance/samples/ContractDeploy.scala +++ b/everscale-client-scala/src/main/scala/com/radiance/samples/ContractDeploy.scala @@ -53,6 +53,7 @@ object ContractDeploy { None, CallSet("sendGrams", None, inputMsg.some).some, SignerADT.None, + None, None ), send_events = true, @@ -70,7 +71,7 @@ object ContractDeploy { (for { encoded <- EitherT( abiModule - .encodeMessage(a, None, deploySet.some, callSet.some, signer, None) + .encodeMessage(a, None, deploySet.some, callSet.some, signer, None, None) ) _ <- EitherT(getGrams(encoded.address)) _ <- EitherT( @@ -81,6 +82,7 @@ object ContractDeploy { deploySet.some, callSet.some, signer, + None, None ), send_events = true, diff --git a/everscale-client-scala/src/test/scala/com/radiance/jvm/AbiModuleTest.scala b/everscale-client-scala/src/test/scala/com/radiance/jvm/AbiModuleTest.scala index c711572..346bc1b 100644 --- a/everscale-client-scala/src/test/scala/com/radiance/jvm/AbiModuleTest.scala +++ b/everscale-client-scala/src/test/scala/com/radiance/jvm/AbiModuleTest.scala @@ -48,6 +48,7 @@ class AbiModuleTest extends AnyFlatSpec with TestBase { deploySet.some, deployCallSet.some, SignerADT.External(keys.public), + None, None ) .get @@ -59,6 +60,7 @@ class AbiModuleTest extends AnyFlatSpec with TestBase { None, runCallSet.some, SignerADT.External(keys.public), + None, None ) .get @@ -82,6 +84,7 @@ class AbiModuleTest extends AnyFlatSpec with TestBase { None, runCallSet.some, SignerADT.Keys(keys), + None, None ) .get @@ -94,6 +97,7 @@ class AbiModuleTest extends AnyFlatSpec with TestBase { None, runCallSet.some, SignerADT.None, + None, None ) .get diff --git a/everscale-client-scala/src/test/scala/com/radiance/jvm/CryptoModuleTest.scala b/everscale-client-scala/src/test/scala/com/radiance/jvm/CryptoModuleTest.scala index 1bc7828..2e14762 100644 --- a/everscale-client-scala/src/test/scala/com/radiance/jvm/CryptoModuleTest.scala +++ b/everscale-client-scala/src/test/scala/com/radiance/jvm/CryptoModuleTest.scala @@ -1,6 +1,6 @@ package com.radiance.jvm -import com.radiance.jvm.crypto.{CryptoModule, KeyPair} +import com.radiance.jvm.crypto.{CryptoModule, KeyPair, MnemonicDictionaryEnum} import org.scalatest.flatspec.AnyFlatSpec import cats.implicits._ import com.radiance.jvm.Utils._ @@ -109,7 +109,7 @@ class CryptoModuleTest extends AnyFlatSpec with TestBase { } it should "show the correct behavior of mnemonic words" in { - val words = cryptoModule.mnemonicWords(1L.some).get.words + val words = cryptoModule.mnemonicWords(MnemonicDictionaryEnum.Ton.some).get.words logger.info(s"Word: '$words'") val xPrivate: String = cryptoModule diff --git a/everscale-client-scala/src/test/scala/com/radiance/jvm/NetModuleTest.scala b/everscale-client-scala/src/test/scala/com/radiance/jvm/NetModuleTest.scala index 6415fad..3bd3214 100644 --- a/everscale-client-scala/src/test/scala/com/radiance/jvm/NetModuleTest.scala +++ b/everscale-client-scala/src/test/scala/com/radiance/jvm/NetModuleTest.scala @@ -15,6 +15,7 @@ class NetModuleTest extends AnyFlatSpec with TestBase { private val logger = Logger[NetModuleTest] override protected val config = ClientConfig( + None, NetworkConfig("http://net.ton.dev/graphql".some).some ) diff --git a/everscale-client-scala/src/test/scala/com/radiance/jvm/ProcessingModuleTest.scala b/everscale-client-scala/src/test/scala/com/radiance/jvm/ProcessingModuleTest.scala index ac9c8b1..2dc0b03 100644 --- a/everscale-client-scala/src/test/scala/com/radiance/jvm/ProcessingModuleTest.scala +++ b/everscale-client-scala/src/test/scala/com/radiance/jvm/ProcessingModuleTest.scala @@ -31,6 +31,7 @@ class ProcessingModuleTest extends AnyFlatSpec with TestBase { FunctionHeader(None, None, keys.public.some).some ).some, SignerADT.Keys(keys), + None, None ) .get diff --git a/everscale-client-scala/src/test/scala/com/radiance/jvm/TestBase.scala b/everscale-client-scala/src/test/scala/com/radiance/jvm/TestBase.scala index cf4b106..ba2d2ef 100644 --- a/everscale-client-scala/src/test/scala/com/radiance/jvm/TestBase.scala +++ b/everscale-client-scala/src/test/scala/com/radiance/jvm/TestBase.scala @@ -47,6 +47,7 @@ trait TestBase extends BeforeAndAfter with TestUtils { this: AnyFlatSpec => protected var debotModule: DebotModule = _ protected val config = ClientConfig( + None, NetworkConfig(host.some).some ) @@ -78,7 +79,7 @@ trait TestBase extends BeforeAndAfter with TestUtils { this: AnyFlatSpec => (for { encoded <- EitherT( abiModule - .encodeMessage(a, None, deploySet.some, callSet.some, signer, None) + .encodeMessage(a, None, deploySet.some, callSet.some, signer, None, None) ) _ <- EitherT(getGramsFromGiver(encoded.address)) _ <- EitherT( @@ -89,6 +90,7 @@ trait TestBase extends BeforeAndAfter with TestUtils { this: AnyFlatSpec => deploySet.some, callSet.some, signer, + None, None ), false, @@ -116,6 +118,7 @@ trait TestBase extends BeforeAndAfter with TestUtils { this: AnyFlatSpec => inputMsg.some ).some, SignerADT.None, + None, None ), false, diff --git a/everscale-client-scala/src/test/scala/com/radiance/jvm/TvmModuleTest.scala b/everscale-client-scala/src/test/scala/com/radiance/jvm/TvmModuleTest.scala index 3f81ab1..e7602cb 100644 --- a/everscale-client-scala/src/test/scala/com/radiance/jvm/TvmModuleTest.scala +++ b/everscale-client-scala/src/test/scala/com/radiance/jvm/TvmModuleTest.scala @@ -251,6 +251,7 @@ class TvmModuleTest extends AnyFlatSpec with TestBase { ).some ).some, signer, + None, None ) ) @@ -267,6 +268,7 @@ class TvmModuleTest extends AnyFlatSpec with TestBase { fromFields(Seq("subscriptionId" -> fromString(subscriptionId))).some ).some, signer, + None, None ) ) diff --git a/everscale-client-scala/src/test/scala/com/radiance/jvm/temp/Mod.scala b/everscale-client-scala/src/test/scala/com/radiance/jvm/temp/Mod.scala index e89068b..44ebf95 100644 --- a/everscale-client-scala/src/test/scala/com/radiance/jvm/temp/Mod.scala +++ b/everscale-client-scala/src/test/scala/com/radiance/jvm/temp/Mod.scala @@ -24,6 +24,7 @@ object Mod { private val host = "http://localhost:80" private val config = ClientConfig( + None, NetworkConfig(host.some).some ) private implicit val ec: ExecutionContext = ExecutionContext.global diff --git a/everscale-client-scala/src/test/scala/com/radiance/jvm/temp/abi/AbiModuleTest.scala b/everscale-client-scala/src/test/scala/com/radiance/jvm/temp/abi/AbiModuleTest.scala index 265379b..6ca1d9e 100644 --- a/everscale-client-scala/src/test/scala/com/radiance/jvm/temp/abi/AbiModuleTest.scala +++ b/everscale-client-scala/src/test/scala/com/radiance/jvm/temp/abi/AbiModuleTest.scala @@ -48,6 +48,7 @@ class AbiModuleTest extends AnyFlatSpec with TestUtils { None ).some, signing, + None, None ) @@ -65,6 +66,7 @@ class AbiModuleTest extends AnyFlatSpec with TestUtils { fromFields(Seq("id" -> fromString("0"))).some ).some, signing, + None, None ) @@ -74,6 +76,7 @@ class AbiModuleTest extends AnyFlatSpec with TestUtils { false, run_params.signer, run_params.processing_try_index, + None, None ) @@ -244,6 +247,8 @@ class AbiModuleTest extends AnyFlatSpec with TestUtils { ParamsOfDecodeMessage( events_abi, message, + None, + None, None ) ) @@ -260,6 +265,8 @@ class AbiModuleTest extends AnyFlatSpec with TestUtils { events_abi, body, is_internal = parsed.parsed.hcursor.get[String]("msg_type_name").get == "Internal", + None, + None, None ) ) @@ -302,6 +309,8 @@ class AbiModuleTest extends AnyFlatSpec with TestUtils { body = "te6ccgEBAgEAlgAB4a3f2/jCeWWvgMoAXOakv3VSD56sQrDPT76n1cbrSvpZ0BCs0KEUy2Duvo3zPExePONW3TYy0MCA1i+FFRXcSIXTHxAj/Hd67jWQF7peccWoU/dbMCBJBB6YdPCVZcJlJkAAAF0ZyXLg19VzGQVviwSgAQBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=", is_internal = false, + None, + None, None ) ) diff --git a/everscale-codegen/src/main/resources/api.json b/everscale-codegen/src/main/resources/api.json index 3077bd7..e510763 100644 --- a/everscale-codegen/src/main/resources/api.json +++ b/everscale-codegen/src/main/resources/api.json @@ -1,5 +1,5 @@ { - "version": "1.38.0", + "version": "1.41.0", "modules": [ { "name": "client", @@ -254,6 +254,13 @@ "value": "35", "summary": null, "description": null + }, + { + "name": "InvalidData", + "type": "Number", + "value": "36", + "summary": null, + "description": null } ], "summary": null, @@ -292,6 +299,16 @@ "name": "ClientConfig", "type": "Struct", "struct_fields": [ + { + "name": "binding", + "type": "Optional", + "optional_inner": { + "type": "Ref", + "ref_name": "client.BindingConfig" + }, + "summary": null, + "description": null + }, { "name": "network", "type": "Optional", @@ -477,7 +494,7 @@ "number_size": 32 }, "summary": "Frequency of sync latency detection.", - "description": "Library periodically checks the current endpoint for blockchain data syncronization latency.\nIf the latency (time-lag) is less then `NetworkConfig.max_latency`\nthen library selects another endpoint.\n\nMust be specified in milliseconds. Default is 60000 (1 min)." + "description": "Library periodically checks the current endpoint for blockchain data synchronization latency.\nIf the latency (time-lag) is less then `NetworkConfig.max_latency`\nthen library selects another endpoint.\n\nMust be specified in milliseconds. Default is 60000 (1 min)." }, { "name": "max_latency", @@ -487,7 +504,7 @@ "number_type": "UInt", "number_size": 32 }, - "summary": "Maximum value for the endpoint's blockchain data syncronization latency (time-lag). Library periodically checks the current endpoint for blockchain data synchronization latency. If the latency (time-lag) is less then `NetworkConfig.max_latency` then library selects another endpoint.", + "summary": "Maximum value for the endpoint's blockchain data synchronization latency (time-lag). Library periodically checks the current endpoint for blockchain data synchronization latency. If the latency (time-lag) is less then `NetworkConfig.max_latency` then library selects another endpoint.", "description": "Must be specified in milliseconds. Default is 60000 (1 min)." }, { @@ -520,7 +537,7 @@ "number_size": 32 }, "summary": "UNSTABLE.", - "description": "First REMP status awaiting timeout. If no status recieved during the timeout than fallback transaction scenario is activated.\n\nMust be specified in milliseconds. Default is 1000 (1 sec)." + "description": "First REMP status awaiting timeout. If no status received during the timeout than fallback transaction scenario is activated.\n\nMust be specified in milliseconds. Default is 1000 (1 sec)." }, { "name": "next_remp_status_timeout", @@ -531,7 +548,18 @@ "number_size": 32 }, "summary": "UNSTABLE.", - "description": "Subsequent REMP status awaiting timeout. If no status recieved during the timeout than fallback transaction scenario is activated.\n\nMust be specified in milliseconds. Default is 5000 (5 sec)." + "description": "Subsequent REMP status awaiting timeout. If no status received during the timeout than fallback transaction scenario is activated.\n\nMust be specified in milliseconds. Default is 5000 (5 sec)." + }, + { + "name": "signature_id", + "type": "Optional", + "optional_inner": { + "type": "Number", + "number_type": "Int", + "number_size": 32 + }, + "summary": "Network signature ID which is used by VM in signature verifying instructions if capability `CapSignatureWithId` is enabled in blockchain configuration parameters.", + "description": "This parameter should be set to `global_id` field from any blockchain block if network can\nnot be reachable at the moment of message encoding and the message is aimed to be sent into\nnetwork with `CapSignatureWithId` enabled. Otherwise signature ID is detected automatically\ninside message encoding functions" }, { "name": "access_key", @@ -546,6 +574,32 @@ "summary": null, "description": null }, + { + "name": "BindingConfig", + "type": "Struct", + "struct_fields": [ + { + "name": "library", + "type": "Optional", + "optional_inner": { + "type": "String" + }, + "summary": null, + "description": null + }, + { + "name": "version", + "type": "Optional", + "optional_inner": { + "type": "String" + }, + "summary": null, + "description": null + } + ], + "summary": null, + "description": null + }, { "name": "NetworkQueriesProtocol", "type": "EnumOfConsts", @@ -559,7 +613,7 @@ { "name": "WS", "type": "None", - "summary": "All GraphQL queries will be served using single web socket connection.", + "summary": "All GraphQL queries will be served using single web socket connection. SDK is tested to reliably handle 5000 parallel network requests (sending and processing messages, quering and awaiting blockchain data)", "description": null } ], @@ -574,11 +628,10 @@ "name": "mnemonic_dictionary", "type": "Optional", "optional_inner": { - "type": "Number", - "number_type": "UInt", - "number_size": 8 + "type": "Ref", + "ref_name": "crypto.MnemonicDictionary" }, - "summary": "Mnemonic dictionary that will be used by default in crypto functions. If not specified, 1 dictionary will be used.", + "summary": "Mnemonic dictionary that will be used by default in crypto functions. If not specified, `English` dictionary will be used.", "description": null }, { @@ -1540,9 +1593,8 @@ "struct_fields": [ { "name": "dictionary", - "type": "Number", - "number_type": "UInt", - "number_size": 8, + "type": "Ref", + "ref_name": "crypto.MnemonicDictionary", "summary": null, "description": null }, @@ -1570,9 +1622,8 @@ }, { "name": "dictionary", - "type": "Number", - "number_type": "UInt", - "number_size": 8, + "type": "Ref", + "ref_name": "crypto.MnemonicDictionary", "summary": null, "description": null }, @@ -1715,6 +1766,77 @@ "summary": null, "description": null }, + { + "name": "MnemonicDictionary", + "type": "EnumOfConsts", + "enum_consts": [ + { + "name": "Ton", + "type": "Number", + "value": "0", + "summary": "TON compatible dictionary", + "description": null + }, + { + "name": "English", + "type": "Number", + "value": "1", + "summary": "English BIP-39 dictionary", + "description": null + }, + { + "name": "ChineseSimplified", + "type": "Number", + "value": "2", + "summary": "Chinese simplified BIP-39 dictionary", + "description": null + }, + { + "name": "ChineseTraditional", + "type": "Number", + "value": "3", + "summary": "Chinese traditional BIP-39 dictionary", + "description": null + }, + { + "name": "French", + "type": "Number", + "value": "4", + "summary": "French BIP-39 dictionary", + "description": null + }, + { + "name": "Italian", + "type": "Number", + "value": "5", + "summary": "Italian BIP-39 dictionary", + "description": null + }, + { + "name": "Japanese", + "type": "Number", + "value": "6", + "summary": "Japanese BIP-39 dictionary", + "description": null + }, + { + "name": "Korean", + "type": "Number", + "value": "7", + "summary": "Korean BIP-39 dictionary", + "description": null + }, + { + "name": "Spanish", + "type": "Number", + "value": "8", + "summary": "Spanish BIP-39 dictionary", + "description": null + } + ], + "summary": null, + "description": null + }, { "name": "ParamsOfFactorize", "type": "Struct", @@ -2365,9 +2487,8 @@ "name": "dictionary", "type": "Optional", "optional_inner": { - "type": "Number", - "number_type": "UInt", - "number_size": 8 + "type": "Ref", + "ref_name": "crypto.MnemonicDictionary" }, "summary": "Dictionary identifier", "description": null @@ -2398,9 +2519,8 @@ "name": "dictionary", "type": "Optional", "optional_inner": { - "type": "Number", - "number_type": "UInt", - "number_size": 8 + "type": "Ref", + "ref_name": "crypto.MnemonicDictionary" }, "summary": "Dictionary identifier", "description": null @@ -2448,9 +2568,8 @@ "name": "dictionary", "type": "Optional", "optional_inner": { - "type": "Number", - "number_type": "UInt", - "number_size": 8 + "type": "Ref", + "ref_name": "crypto.MnemonicDictionary" }, "summary": "Dictionary identifier", "description": null @@ -2498,9 +2617,8 @@ "name": "dictionary", "type": "Optional", "optional_inner": { - "type": "Number", - "number_type": "UInt", - "number_size": 8 + "type": "Ref", + "ref_name": "crypto.MnemonicDictionary" }, "summary": "Dictionary identifier", "description": null @@ -2557,9 +2675,8 @@ "name": "dictionary", "type": "Optional", "optional_inner": { - "type": "Number", - "number_type": "UInt", - "number_size": 8 + "type": "Ref", + "ref_name": "crypto.MnemonicDictionary" }, "summary": "Dictionary identifier", "description": null @@ -2593,9 +2710,8 @@ "name": "dictionary", "type": "Optional", "optional_inner": { - "type": "Number", - "number_type": "UInt", - "number_size": 8 + "type": "Ref", + "ref_name": "crypto.MnemonicDictionary" }, "summary": "Dictionary identifier", "description": null @@ -2913,9 +3029,8 @@ }, { "name": "dictionary", - "type": "Number", - "number_type": "UInt", - "number_size": 8, + "type": "Ref", + "ref_name": "crypto.MnemonicDictionary", "summary": null, "description": null }, @@ -6133,6 +6248,26 @@ "summary": null, "description": null }, + { + "name": "DataLayout", + "type": "EnumOfConsts", + "enum_consts": [ + { + "name": "Input", + "type": "None", + "summary": "Decode message body as function input parameters.", + "description": null + }, + { + "name": "Output", + "type": "None", + "summary": "Decode message body as function output.", + "description": null + } + ], + "summary": null, + "description": null + }, { "name": "ParamsOfEncodeMessageBody", "type": "Struct", @@ -6183,6 +6318,17 @@ }, "summary": "Destination address of the message", "description": "Since ABI version 2.3 destination address of external inbound message is used in message\nbody signature calculation. Should be provided when signed external inbound message body is\ncreated. Otherwise can be omitted." + }, + { + "name": "signature_id", + "type": "Optional", + "optional_inner": { + "type": "Number", + "number_type": "Int", + "number_size": 32 + }, + "summary": "Signature ID to be used in data to sign preparing when CapSignatureWithId capability is enabled", + "description": null } ], "summary": null, @@ -6315,6 +6461,17 @@ }, "summary": "Processing try index.", "description": "Used in message processing with retries (if contract's ABI includes \"expire\" header).\n\nEncoder uses the provided try index to calculate message\nexpiration time. The 1st message expiration time is specified in\nClient config.\n\nExpiration timeouts will grow with every retry.\nRetry grow factor is set in Client config:\n<.....add config parameter with default value here>\n\nDefault value is 0." + }, + { + "name": "signature_id", + "type": "Optional", + "optional_inner": { + "type": "Number", + "number_type": "Int", + "number_size": 32 + }, + "summary": "Signature ID to be used in data to sign preparing when CapSignatureWithId capability is enabled", + "description": null } ], "summary": null, @@ -6539,6 +6696,25 @@ }, "summary": "Flag allowing partial BOC decoding when ABI doesn't describe the full body BOC. Controls decoder behaviour when after decoding all described in ABI params there are some data left in BOC: `true` - return decoded values `false` - return error of incomplete BOC deserialization (default)", "description": null + }, + { + "name": "function_name", + "type": "Optional", + "optional_inner": { + "type": "String" + }, + "summary": "Function name or function id if is known in advance", + "description": null + }, + { + "name": "data_layout", + "type": "Optional", + "optional_inner": { + "type": "Ref", + "ref_name": "abi.DataLayout" + }, + "summary": null, + "description": null } ], "summary": null, @@ -6616,6 +6792,25 @@ }, "summary": "Flag allowing partial BOC decoding when ABI doesn't describe the full body BOC. Controls decoder behaviour when after decoding all described in ABI params there are some data left in BOC: `true` - return decoded values `false` - return error of incomplete BOC deserialization (default)", "description": null + }, + { + "name": "function_name", + "type": "Optional", + "optional_inner": { + "type": "String" + }, + "summary": "Function name or function id if is known in advance", + "description": null + }, + { + "name": "data_layout", + "type": "Optional", + "optional_inner": { + "type": "Ref", + "ref_name": "abi.DataLayout" + }, + "summary": null, + "description": null } ], "summary": null, @@ -7068,6 +7263,58 @@ ], "summary": null, "description": null + }, + { + "name": "ParamsOfGetSignatureData", + "type": "Struct", + "struct_fields": [ + { + "name": "abi", + "type": "Ref", + "ref_name": "abi.Abi", + "summary": "Contract ABI used to decode.", + "description": null + }, + { + "name": "message", + "type": "String", + "summary": "Message BOC encoded in `base64`.", + "description": null + }, + { + "name": "signature_id", + "type": "Optional", + "optional_inner": { + "type": "Number", + "number_type": "Int", + "number_size": 32 + }, + "summary": "Signature ID to be used in unsigned data preparing when CapSignatureWithId capability is enabled", + "description": null + } + ], + "summary": null, + "description": null + }, + { + "name": "ResultOfGetSignatureData", + "type": "Struct", + "struct_fields": [ + { + "name": "signature", + "type": "String", + "summary": "Signature from the message in `hex`.", + "description": null + }, + { + "name": "unsigned", + "type": "String", + "summary": "Data to verify the signature in `base64`.", + "description": null + } + ], + "summary": null, + "description": null } ], "functions": [ @@ -7640,6 +7887,44 @@ ] }, "errors": null + }, + { + "name": "get_signature_data", + "summary": "Extracts signature from message body and calculates hash to verify the signature", + "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": "abi.ParamsOfGetSignatureData", + "summary": null, + "description": null + } + ], + "result": { + "type": "Generic", + "generic_name": "ClientResult", + "generic_args": [ + { + "type": "Ref", + "ref_name": "abi.ResultOfGetSignatureData" + } + ] + }, + "errors": null } ] }, @@ -7776,7 +8061,7 @@ { "name": "id", "type": "String", - "summary": "Shardstate identificator", + "summary": "Shardstate identifier", "description": null }, { @@ -9396,7 +9681,20 @@ { "name": "WillFetchFirstBlock", "type": "Struct", - "struct_fields": [], + "struct_fields": [ + { + "name": "message_id", + "type": "String", + "summary": null, + "description": null + }, + { + "name": "message_dst", + "type": "String", + "summary": null, + "description": null + } + ], "summary": "Notifies the application that the account's current shard block will be fetched from the network. This step is performed before the message sending so that sdk knows starting from which block it will search for the transaction.", "description": "Fetched block will be used later in waiting phase." }, @@ -9410,6 +9708,18 @@ "ref_name": "client.ClientError", "summary": null, "description": null + }, + { + "name": "message_id", + "type": "String", + "summary": null, + "description": null + }, + { + "name": "message_dst", + "type": "String", + "summary": null, + "description": null } ], "summary": "Notifies the app that the client has failed to fetch the account's current shard block.", @@ -9431,6 +9741,12 @@ "summary": null, "description": null }, + { + "name": "message_dst", + "type": "String", + "summary": null, + "description": null + }, { "name": "message", "type": "String", @@ -9457,6 +9773,12 @@ "summary": null, "description": null }, + { + "name": "message_dst", + "type": "String", + "summary": null, + "description": null + }, { "name": "message", "type": "String", @@ -9464,8 +9786,8 @@ "description": null } ], - "summary": "Notifies the app that the message was sent to the network, i.e `processing.send_message` was successfuly executed. Now, the message is in the blockchain. If Application exits at this phase, Developer needs to proceed with processing after the application is restored with `wait_for_transaction` function, passing shard_block_id and message from this event.", - "description": "Do not forget to specify abi of your contract as well, it is crucial for proccessing. See `processing.wait_for_transaction` documentation." + "summary": "Notifies the app that the message was sent to the network, i.e `processing.send_message` was successfully executed. Now, the message is in the blockchain. If Application exits at this phase, Developer needs to proceed with processing after the application is restored with `wait_for_transaction` function, passing shard_block_id and message from this event.", + "description": "Do not forget to specify abi of your contract as well, it is crucial for processing. See `processing.wait_for_transaction` documentation." }, { "name": "SendFailed", @@ -9483,6 +9805,12 @@ "summary": null, "description": null }, + { + "name": "message_dst", + "type": "String", + "summary": null, + "description": null + }, { "name": "message", "type": "String", @@ -9498,7 +9826,7 @@ } ], "summary": "Notifies the app that the sending operation was failed with network error.", - "description": "Nevertheless the processing will be continued at the waiting\nphase because the message possibly has been delivered to the\nnode.\nIf Application exits at this phase, Developer needs to proceed with processing\nafter the application is restored with `wait_for_transaction` function, passing\nshard_block_id and message from this event. Do not forget to specify abi of your contract\nas well, it is crucial for proccessing. See `processing.wait_for_transaction` documentation." + "description": "Nevertheless the processing will be continued at the waiting\nphase because the message possibly has been delivered to the\nnode.\nIf Application exits at this phase, Developer needs to proceed with processing\nafter the application is restored with `wait_for_transaction` function, passing\nshard_block_id and message from this event. Do not forget to specify abi of your contract\nas well, it is crucial for processing. See `processing.wait_for_transaction` documentation." }, { "name": "WillFetchNextBlock", @@ -9516,6 +9844,12 @@ "summary": null, "description": null }, + { + "name": "message_dst", + "type": "String", + "summary": null, + "description": null + }, { "name": "message", "type": "String", @@ -9524,7 +9858,7 @@ } ], "summary": "Notifies the app that the next shard block will be fetched from the network.", - "description": "Event can occurs more than one time due to block walking\nprocedure.\nIf Application exits at this phase, Developer needs to proceed with processing\nafter the application is restored with `wait_for_transaction` function, passing\nshard_block_id and message from this event. Do not forget to specify abi of your contract\nas well, it is crucial for proccessing. See `processing.wait_for_transaction` documentation." + "description": "Event can occurs more than one time due to block walking\nprocedure.\nIf Application exits at this phase, Developer needs to proceed with processing\nafter the application is restored with `wait_for_transaction` function, passing\nshard_block_id and message from this event. Do not forget to specify abi of your contract\nas well, it is crucial for processing. See `processing.wait_for_transaction` documentation." }, { "name": "FetchNextBlockFailed", @@ -9542,6 +9876,12 @@ "summary": null, "description": null }, + { + "name": "message_dst", + "type": "String", + "summary": null, + "description": null + }, { "name": "message", "type": "String", @@ -9569,6 +9909,12 @@ "summary": null, "description": null }, + { + "name": "message_dst", + "type": "String", + "summary": null, + "description": null + }, { "name": "message", "type": "String", @@ -9584,7 +9930,7 @@ } ], "summary": "Notifies the app that the message was not executed within expire timeout on-chain and will never be because it is already expired. The expiration timeout can be configured with `AbiConfig` parameters.", - "description": "This event occurs only for the contracts which ABI includes \"expire\" header.\n\nIf Application specifies `NetworkConfig.message_retries_count` > 0, then `process_message`\nwill perform retries: will create a new message and send it again and repeat it untill it reaches\nthe maximum retries count or receives a successful result. All the processing\nevents will be repeated." + "description": "This event occurs only for the contracts which ABI includes \"expire\" header.\n\nIf Application specifies `NetworkConfig.message_retries_count` > 0, then `process_message`\nwill perform retries: will create a new message and send it again and repeat it until it reaches\nthe maximum retries count or receives a successful result. All the processing\nevents will be repeated." }, { "name": "RempSentToValidators", @@ -9596,6 +9942,12 @@ "summary": null, "description": null }, + { + "name": "message_dst", + "type": "String", + "summary": null, + "description": null + }, { "name": "timestamp", "type": "BigInt", @@ -9625,6 +9977,12 @@ "summary": null, "description": null }, + { + "name": "message_dst", + "type": "String", + "summary": null, + "description": null + }, { "name": "timestamp", "type": "BigInt", @@ -9654,6 +10012,12 @@ "summary": null, "description": null }, + { + "name": "message_dst", + "type": "String", + "summary": null, + "description": null + }, { "name": "timestamp", "type": "BigInt", @@ -9670,7 +10034,7 @@ "description": null } ], - "summary": "Notifies the app that the block candicate with the message has been accepted by the thread's validators", + "summary": "Notifies the app that the block candidate with the message has been accepted by the thread's validators", "description": null }, { @@ -9683,6 +10047,12 @@ "summary": null, "description": null }, + { + "name": "message_dst", + "type": "String", + "summary": null, + "description": null + }, { "name": "timestamp", "type": "BigInt", @@ -9706,6 +10076,18 @@ "name": "RempError", "type": "Struct", "struct_fields": [ + { + "name": "message_id", + "type": "String", + "summary": null, + "description": null + }, + { + "name": "message_dst", + "type": "String", + "summary": null, + "description": null + }, { "name": "error", "type": "Ref", @@ -9714,7 +10096,7 @@ "description": null } ], - "summary": "Notifies the app about any problem that has occured in REMP processing - in this case library switches to the fallback transaction awaiting scenario (sequential block reading).", + "summary": "Notifies the app about any problem that has occurred in REMP processing - in this case library switches to the fallback transaction awaiting scenario (sequential block reading).", "description": null } ], @@ -10677,6 +11059,17 @@ }, "summary": "Overrides standard TVM behaviour. If set to `true` then CHKSIG always will return `true`.", "description": null + }, + { + "name": "signature_id", + "type": "Optional", + "optional_inner": { + "type": "Number", + "number_type": "Int", + "number_size": 32 + }, + "summary": "Signature ID to be used in signature verifying instructions when CapSignatureWithId capability is enabled", + "description": null } ], "summary": null, @@ -11084,7 +11477,7 @@ { "name": "run_executor", "summary": "Emulates all the phases of contract execution locally", - "description": "Performs all the phases of contract execution on Transaction Executor -\nthe same component that is used on Validator Nodes.\n\nCan be used for contract debugging, to find out the reason why a message was not delivered successfully.\nValidators throw away the failed external inbound messages (if they failed bedore `ACCEPT`) in the real network.\nThis is why these messages are impossible to debug in the real network.\nWith the help of run_executor you can do that. In fact, `process_message` function\nperforms local check with `run_executor` if there was no transaction as a result of processing\nand returns the error, if there is one.\n\nAnother use case to use `run_executor` is to estimate fees for message execution.\nSet `AccountForExecutor::Account.unlimited_balance`\nto `true` so that emulation will not depend on the actual balance.\nThis may be needed to calculate deploy fees for an account that does not exist yet.\nJSON with fees is in `fees` field of the result.\n\nOne more use case - you can produce the sequence of operations,\nthus emulating the sequential contract calls locally.\nAnd so on.\n\nTransaction executor requires account BOC (bag of cells) as a parameter.\nTo get the account BOC - use `net.query` method to download it from GraphQL API\n(field `boc` of `account`) or generate it with `abi.encode_account` method.\n\nAlso it requires message BOC. To get the message BOC - use `abi.encode_message` or `abi.encode_internal_message`.\n\nIf you need this emulation to be as precise as possible (for instance - emulate transaction\nwith particular lt in particular block or use particular blockchain config,\ndownloaded from a particular key block - then specify `execution_options` parameter.\n\nIf you need to see the aborted transaction as a result, not as an error, set `skip_transaction_check` to `true`.", + "description": "Performs all the phases of contract execution on Transaction Executor -\nthe same component that is used on Validator Nodes.\n\nCan be used for contract debugging, to find out the reason why a message was not delivered successfully.\nValidators throw away the failed external inbound messages (if they failed before `ACCEPT`) in the real network.\nThis is why these messages are impossible to debug in the real network.\nWith the help of run_executor you can do that. In fact, `process_message` function\nperforms local check with `run_executor` if there was no transaction as a result of processing\nand returns the error, if there is one.\n\nAnother use case to use `run_executor` is to estimate fees for message execution.\nSet `AccountForExecutor::Account.unlimited_balance`\nto `true` so that emulation will not depend on the actual balance.\nThis may be needed to calculate deploy fees for an account that does not exist yet.\nJSON with fees is in `fees` field of the result.\n\nOne more use case - you can produce the sequence of operations,\nthus emulating the sequential contract calls locally.\nAnd so on.\n\nTransaction executor requires account BOC (bag of cells) as a parameter.\nTo get the account BOC - use `net.query` method to download it from GraphQL API\n(field `boc` of `account`) or generate it with `abi.encode_account` method.\n\nAlso it requires message BOC. To get the message BOC - use `abi.encode_message` or `abi.encode_internal_message`.\n\nIf you need this emulation to be as precise as possible (for instance - emulate transaction\nwith particular lt in particular block or use particular blockchain config,\ndownloaded from a particular key block - then specify `execution_options` parameter.\n\nIf you need to see the aborted transaction as a result, not as an error, set `skip_transaction_check` to `true`.", "params": [ { "name": "context", @@ -11310,6 +11703,20 @@ "value": "615", "summary": null, "description": null + }, + { + "name": "QueryTransactionTreeTimeout", + "type": "Number", + "value": "616", + "summary": null, + "description": null + }, + { + "name": "GraphqlConnectionError", + "type": "Number", + "value": "617", + "summary": null, + "description": null } ], "summary": null, @@ -12049,7 +12456,18 @@ "number_size": 32 }, "summary": "Timeout used to limit waiting time for the missing messages and transaction.", - "description": "If some of the following messages and transactions are missing yet\nThe maximum waiting time is regulated by this option.\n\nDefault value is 60000 (1 min)." + "description": "If some of the following messages and transactions are missing yet\nThe maximum waiting time is regulated by this option.\n\nDefault value is 60000 (1 min). If `timeout` is set to 0 then function will wait infinitely\nuntil the whole transaction tree is executed" + }, + { + "name": "transaction_max_count", + "type": "Optional", + "optional_inner": { + "type": "Number", + "number_type": "UInt", + "number_size": 32 + }, + "summary": "Maximum transaction count to wait.", + "description": "If transaction tree contains more transaction then this parameter then only first `transaction_max_count` transaction are awaited and returned.\n\nDefault value is 50. If `transaction_max_count` is set to 0 then no limitation on\ntransaction count is used and all transaction are returned." } ], "summary": null, @@ -12333,6 +12751,25 @@ ], "summary": null, "description": null + }, + { + "name": "ResultOfGetSignatureId", + "type": "Struct", + "struct_fields": [ + { + "name": "signature_id", + "type": "Optional", + "optional_inner": { + "type": "Number", + "number_type": "Int", + "number_size": 32 + }, + "summary": "Signature ID for configured network if it should be used in messages signature", + "description": null + } + ], + "summary": null, + "description": null } ], "functions": [ @@ -12617,7 +13054,7 @@ { "name": "subscribe", "summary": "Creates a subscription", - "description": "The subscription is a persistent communication channel between\nclient and Everscale Network.\n\n### Important Notes on Subscriptions\n\nUnfortunately sometimes the connection with the network breakes down.\nIn this situation the library attempts to reconnect to the network.\nThis reconnection sequence can take significant time.\nAll of this time the client is disconnected from the network.\n\nBad news is that all changes that happened while\nthe client was disconnected are lost.\n\nGood news is that the client report errors to the callback when\nit loses and resumes connection.\n\nSo, if the lost changes are important to the application then\nthe application must handle these error reports.\n\nLibrary reports errors with `responseType` == 101\nand the error object passed via `params`.\n\nWhen the library has successfully reconnected\nthe application receives callback with\n`responseType` == 101 and `params.code` == 614 (NetworkModuleResumed).\n\nApplication can use several ways to handle this situation:\n- If application monitors changes for the single\nobject (for example specific account): application\ncan perform a query for this object and handle actual data as a\nregular data from the subscription.\n- If application monitors sequence of some objects\n(for example transactions of the specific account): application must\nrefresh all cached (or visible to user) lists where this sequences presents.", + "description": "The subscription is a persistent communication channel between\nclient and Everscale Network.\n\n### Important Notes on Subscriptions\n\nUnfortunately sometimes the connection with the network breaks down.\nIn this situation the library attempts to reconnect to the network.\nThis reconnection sequence can take significant time.\nAll of this time the client is disconnected from the network.\n\nBad news is that all changes that happened while\nthe client was disconnected are lost.\n\nGood news is that the client report errors to the callback when\nit loses and resumes connection.\n\nSo, if the lost changes are important to the application then\nthe application must handle these error reports.\n\nLibrary reports errors with `responseType` == 101\nand the error object passed via `params`.\n\nWhen the library has successfully reconnected\nthe application receives callback with\n`responseType` == 101 and `params.code` == 614 (NetworkModuleResumed).\n\nApplication can use several ways to handle this situation:\n- If application monitors changes for the single\nobject (for example specific account): application\ncan perform a query for this object and handle actual data as a\nregular data from the subscription.\n- If application monitors sequence of some objects\n(for example transactions of the specific account): application must\nrefresh all cached (or visible to user) lists where this sequences presents.", "params": [ { "name": "context", @@ -12903,7 +13340,7 @@ { "name": "query_transaction_tree", "summary": "Returns a tree of transactions triggered by a specific message.", - "description": "Performs recursive retrieval of a transactions tree produced by a specific message:\nin_msg -> dst_transaction -> out_messages -> dst_transaction -> ...\nIf the chain of transactions execution is in progress while the function is running,\nit will wait for the next transactions to appear until the full tree or more than 50 transactions\nare received.\n\nAll the retrieved messages and transactions are included\ninto `result.messages` and `result.transactions` respectively.\n\nFunction reads transactions layer by layer, by pages of 20 transactions.\n\nThe retrieval prosess goes like this:\nLet's assume we have an infinite chain of transactions and each transaction generates 5 messages.\n1. Retrieve 1st message (input parameter) and corresponding transaction - put it into result.\nIt is the first level of the tree of transactions - its root.\nRetrieve 5 out message ids from the transaction for next steps.\n2. Retrieve 5 messages and corresponding transactions on the 2nd layer. Put them into result.\nRetrieve 5*5 out message ids from these transactions for next steps\n3. Retrieve 20 (size of the page) messages and transactions (3rd layer) and 20*5=100 message ids (4th layer).\n4. Retrieve the last 5 messages and 5 transactions on the 3rd layer + 15 messages and transactions (of 100) from the 4th layer\n+ 25 message ids of the 4th layer + 75 message ids of the 5th layer.\n5. Retrieve 20 more messages and 20 more transactions of the 4th layer + 100 more message ids of the 5th layer.\n6. Now we have 1+5+20+20+20 = 66 transactions, which is more than 50. Function exits with the tree of\n1m->1t->5m->5t->25m->25t->35m->35t. If we see any message ids in the last transactions out_msgs, which don't have\ncorresponding messages in the function result, it means that the full tree was not received and we need to continue iteration.\n\nTo summarize, it is guaranteed that each message in `result.messages` has the corresponding transaction\nin the `result.transactions`.\nBut there is no guarantee that all messages from transactions `out_msgs` are\npresented in `result.messages`.\nSo the application has to continue retrieval for missing messages if it requires.", + "description": "Performs recursive retrieval of a transactions tree produced by a specific message:\nin_msg -> dst_transaction -> out_messages -> dst_transaction -> ...\nIf the chain of transactions execution is in progress while the function is running,\nit will wait for the next transactions to appear until the full tree or more than 50 transactions\nare received.\n\nAll the retrieved messages and transactions are included\ninto `result.messages` and `result.transactions` respectively.\n\nFunction reads transactions layer by layer, by pages of 20 transactions.\n\nThe retrieval process goes like this:\nLet's assume we have an infinite chain of transactions and each transaction generates 5 messages.\n1. Retrieve 1st message (input parameter) and corresponding transaction - put it into result.\nIt is the first level of the tree of transactions - its root.\nRetrieve 5 out message ids from the transaction for next steps.\n2. Retrieve 5 messages and corresponding transactions on the 2nd layer. Put them into result.\nRetrieve 5*5 out message ids from these transactions for next steps\n3. Retrieve 20 (size of the page) messages and transactions (3rd layer) and 20*5=100 message ids (4th layer).\n4. Retrieve the last 5 messages and 5 transactions on the 3rd layer + 15 messages and transactions (of 100) from the 4th layer\n+ 25 message ids of the 4th layer + 75 message ids of the 5th layer.\n5. Retrieve 20 more messages and 20 more transactions of the 4th layer + 100 more message ids of the 5th layer.\n6. Now we have 1+5+20+20+20 = 66 transactions, which is more than 50. Function exits with the tree of\n1m->1t->5m->5t->25m->25t->35m->35t. If we see any message ids in the last transactions out_msgs, which don't have\ncorresponding messages in the function result, it means that the full tree was not received and we need to continue iteration.\n\nTo summarize, it is guaranteed that each message in `result.messages` has the corresponding transaction\nin the `result.transactions`.\nBut there is no guarantee that all messages from transactions `out_msgs` are\npresented in `result.messages`.\nSo the application has to continue retrieval for missing messages if it requires.", "params": [ { "name": "context", @@ -12979,7 +13416,7 @@ { "name": "resume_block_iterator", "summary": "Resumes block iterator.", - "description": "The iterator stays exactly at the same position where the `resume_state` was catched.\n\nApplication should call the `remove_iterator` when iterator is no longer required.", + "description": "The iterator stays exactly at the same position where the `resume_state` was caught.\n\nApplication should call the `remove_iterator` when iterator is no longer required.", "params": [ { "name": "context", @@ -13164,6 +13601,37 @@ ] }, "errors": null + }, + { + "name": "get_signature_id", + "summary": "Returns signature ID for configured network if it should be used in messages signature", + "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.ResultOfGetSignatureId" + } + ] + }, + "errors": null } ] }, diff --git a/everscale-codegen/src/main/resources/prototypes.txt b/everscale-codegen/src/main/resources/prototypes.txt index b81fd3a..68ef19b 100644 --- a/everscale-codegen/src/main/resources/prototypes.txt +++ b/everscale-codegen/src/main/resources/prototypes.txt @@ -5,9 +5,10 @@ package client { case class Error(text: String) extends AppRequestResult case class Ok(result: Value) extends AppRequestResult } + case class BindingConfig(library: Option[String], version: Option[String]) case class BocConfig(cache_max_size: Option[Long]) case class BuildInfoDependency(name: String, git_commit: String) - case class ClientConfig(network: Option[NetworkConfig], crypto: Option[CryptoConfig], abi: Option[AbiConfig], boc: Option[BocConfig], proofs: Option[ProofsConfig], local_storage_path: Option[String]) + case class ClientConfig(binding: Option[BindingConfig], network: Option[NetworkConfig], crypto: Option[CryptoConfig], abi: Option[AbiConfig], boc: Option[BocConfig], proofs: Option[ProofsConfig], local_storage_path: Option[String]) case class ClientError(code: Long, message: String, data: Value) object ClientErrorCodeEnum { sealed trait ClientErrorCode { @@ -79,6 +80,9 @@ package client { case object InvalidContextHandle extends ClientErrorCode { override val code: String = "17" } + case object InvalidData extends ClientErrorCode { + override val code: String = "36" + } case object InvalidHandle extends ClientErrorCode { override val code: String = "34" } @@ -120,14 +124,14 @@ package client { } } /** Crypto config. */ - case class CryptoConfig(mnemonic_dictionary: Option[Long], mnemonic_word_count: Option[Long], hdkey_derivation_path: Option[String]) - case class NetworkConfig(server_address: Option[String], endpoints: Option[List[String]], network_retries_count: Option[Int], max_reconnect_timeout: Option[Long], reconnect_timeout: Option[Long], message_retries_count: Option[Int], message_processing_timeout: Option[Long], wait_for_timeout: Option[Long], out_of_sync_threshold: Option[Long], sending_endpoint_count: Option[Long], latency_detection_interval: Option[Long], max_latency: Option[Long], query_timeout: Option[Long], queries_protocol: Option[NetworkQueriesProtocol], first_remp_status_timeout: Option[Long], next_remp_status_timeout: Option[Long], access_key: Option[String]) + case class CryptoConfig(mnemonic_dictionary: Option[MnemonicDictionary], mnemonic_word_count: Option[Long], hdkey_derivation_path: Option[String]) + case class NetworkConfig(server_address: Option[String], endpoints: Option[List[String]], network_retries_count: Option[Int], max_reconnect_timeout: Option[Long], reconnect_timeout: Option[Long], message_retries_count: Option[Int], message_processing_timeout: Option[Long], wait_for_timeout: Option[Long], out_of_sync_threshold: Option[Long], sending_endpoint_count: Option[Long], latency_detection_interval: Option[Long], max_latency: Option[Long], query_timeout: Option[Long], queries_protocol: Option[NetworkQueriesProtocol], first_remp_status_timeout: Option[Long], next_remp_status_timeout: Option[Long], signature_id: Option[Int], access_key: Option[String]) object NetworkQueriesProtocolEnum { /** Network protocol used to perform GraphQL queries. */ sealed trait NetworkQueriesProtocol /** Each GraphQL query uses separate HTTP request. */ case object HTTP extends NetworkQueriesProtocol - /** All GraphQL queries will be served using single web socket connection. */ + /** All GraphQL queries will be served using single web socket connection. SDK is tested to reliably handle 5000 parallel network requests (sending and processing messages, quering and awaiting blockchain data) */ case object WS extends NetworkQueriesProtocol } case class ParamsOfAppRequest(app_request_id: Long, request_data: Value) @@ -179,9 +183,9 @@ package crypto { /** Crypto Box Secret. */ case class EncryptedSecret(encrypted_secret: String) extends CryptoBoxSecret /** Crypto Box Secret. */ - case class PredefinedSeedPhrase(phrase: String, dictionary: Long, wordcount: Long) extends CryptoBoxSecret + case class PredefinedSeedPhrase(phrase: String, dictionary: MnemonicDictionary, wordcount: Long) extends CryptoBoxSecret /** Crypto Box Secret. */ - case class RandomSeedPhrase(dictionary: Long, wordcount: Long) extends CryptoBoxSecret + case class RandomSeedPhrase(dictionary: MnemonicDictionary, wordcount: Long) extends CryptoBoxSecret } object CryptoErrorCodeEnum { sealed trait CryptoErrorCode { @@ -295,6 +299,47 @@ package crypto { /** Encryption box information. */ case class EncryptionBoxInfo(hdpath: Option[String], algorithm: Option[String], options: Option[Value], public: Option[Value]) case class KeyPair(public: String, secret: String) + object MnemonicDictionaryEnum { + sealed trait MnemonicDictionary { + val code: String + } + /** Chinese simplified BIP-39 dictionary */ + case object ChineseSimplified extends MnemonicDictionary { + override val code: String = "2" + } + /** Chinese traditional BIP-39 dictionary */ + case object ChineseTraditional extends MnemonicDictionary { + override val code: String = "3" + } + /** English BIP-39 dictionary */ + case object English extends MnemonicDictionary { + override val code: String = "1" + } + /** French BIP-39 dictionary */ + case object French extends MnemonicDictionary { + override val code: String = "4" + } + /** Italian BIP-39 dictionary */ + case object Italian extends MnemonicDictionary { + override val code: String = "5" + } + /** Japanese BIP-39 dictionary */ + case object Japanese extends MnemonicDictionary { + override val code: String = "6" + } + /** Korean BIP-39 dictionary */ + case object Korean extends MnemonicDictionary { + override val code: String = "7" + } + /** Spanish BIP-39 dictionary */ + case object Spanish extends MnemonicDictionary { + override val code: String = "8" + } + /** TON compatible dictionary */ + case object Ton extends MnemonicDictionary { + override val code: String = "0" + } + } case class NaclBoxParamsCB(their_public: String, nonce: String) case class NaclBoxParamsEB(their_public: String, secret: String, nonce: String) case class NaclSecretBoxParamsCB(nonce: String) @@ -358,13 +403,13 @@ package crypto { case class ParamsOfHDKeyDeriveFromXPrvPath(xprv: String, path: String) case class ParamsOfHDKeyPublicFromXPrv(xprv: String) case class ParamsOfHDKeySecretFromXPrv(xprv: String) - case class ParamsOfHDKeyXPrvFromMnemonic(phrase: String, dictionary: Option[Long], word_count: Option[Long]) + case class ParamsOfHDKeyXPrvFromMnemonic(phrase: String, dictionary: Option[MnemonicDictionary], word_count: Option[Long]) case class ParamsOfHash(data: String) - case class ParamsOfMnemonicDeriveSignKeys(phrase: String, path: Option[String], dictionary: Option[Long], word_count: Option[Long]) - case class ParamsOfMnemonicFromEntropy(entropy: String, dictionary: Option[Long], word_count: Option[Long]) - case class ParamsOfMnemonicFromRandom(dictionary: Option[Long], word_count: Option[Long]) - case class ParamsOfMnemonicVerify(phrase: String, dictionary: Option[Long], word_count: Option[Long]) - case class ParamsOfMnemonicWords(dictionary: Option[Long]) + case class ParamsOfMnemonicDeriveSignKeys(phrase: String, path: Option[String], dictionary: Option[MnemonicDictionary], word_count: Option[Long]) + case class ParamsOfMnemonicFromEntropy(entropy: String, dictionary: Option[MnemonicDictionary], word_count: Option[Long]) + case class ParamsOfMnemonicFromRandom(dictionary: Option[MnemonicDictionary], word_count: Option[Long]) + case class ParamsOfMnemonicVerify(phrase: String, dictionary: Option[MnemonicDictionary], word_count: Option[Long]) + case class ParamsOfMnemonicWords(dictionary: Option[MnemonicDictionary]) case class ParamsOfModularPower(base: String, exponent: String, modulus: String) case class ParamsOfNaclBox(decrypted: String, nonce: String, their_public: String, secret: String) case class ParamsOfNaclBoxKeyPairFromSecret(secret: String) @@ -413,7 +458,7 @@ package crypto { case class ResultOfFactorize(factors: List[String]) case class ResultOfGenerateRandomBytes(bytes: String) case class ResultOfGetCryptoBoxInfo(encrypted_secret: String) - case class ResultOfGetCryptoBoxSeedPhrase(phrase: String, dictionary: Long, wordcount: Long) + case class ResultOfGetCryptoBoxSeedPhrase(phrase: String, dictionary: MnemonicDictionary, wordcount: Long) case class ResultOfHDKeyDeriveFromXPrv(xprv: String) case class ResultOfHDKeyDeriveFromXPrvPath(xprv: String) case class ResultOfHDKeyPublicFromXPrv(public: String) @@ -580,7 +625,7 @@ package crypto { * @param dictionary dictionary * @param word_count word_count */ - def hdkeyXprvFromMnemonic(phrase: String, dictionary: Option[Long], word_count: Option[Long]): Future[Either[Throwable, ResultOfHDKeyXPrvFromMnemonic]] + def hdkeyXprvFromMnemonic(phrase: String, dictionary: Option[MnemonicDictionary], word_count: Option[Long]): Future[Either[Throwable, ResultOfHDKeyXPrvFromMnemonic]] /** * Derives a key pair for signing from the seed phrase * Validates the seed phrase, generates master key and then derives @@ -590,20 +635,20 @@ package crypto { * @param dictionary dictionary * @param word_count word_count */ - def mnemonicDeriveSignKeys(phrase: String, path: Option[String], dictionary: Option[Long], word_count: Option[Long]): Future[Either[Throwable, KeyPair]] + def mnemonicDeriveSignKeys(phrase: String, path: Option[String], dictionary: Option[MnemonicDictionary], word_count: Option[Long]): Future[Either[Throwable, KeyPair]] /** * Generates mnemonic from pre-generated entropy * @param entropy Hex encoded. * @param dictionary dictionary * @param word_count word_count */ - def mnemonicFromEntropy(entropy: String, dictionary: Option[Long], word_count: Option[Long]): Future[Either[Throwable, ResultOfMnemonicFromEntropy]] + def mnemonicFromEntropy(entropy: String, dictionary: Option[MnemonicDictionary], word_count: Option[Long]): Future[Either[Throwable, ResultOfMnemonicFromEntropy]] /** * Generates a random mnemonic from the specified dictionary and word count * @param dictionary dictionary * @param word_count word_count */ - def mnemonicFromRandom(dictionary: Option[Long], word_count: Option[Long]): Future[Either[Throwable, ResultOfMnemonicFromRandom]] + def mnemonicFromRandom(dictionary: Option[MnemonicDictionary], word_count: Option[Long]): Future[Either[Throwable, ResultOfMnemonicFromRandom]] /** * Validates a mnemonic phrase * The phrase supplied will be checked for word length and validated according to the checksum @@ -612,12 +657,12 @@ package crypto { * @param dictionary dictionary * @param word_count word_count */ - def mnemonicVerify(phrase: String, dictionary: Option[Long], word_count: Option[Long]): Future[Either[Throwable, ResultOfMnemonicVerify]] + def mnemonicVerify(phrase: String, dictionary: Option[MnemonicDictionary], word_count: Option[Long]): Future[Either[Throwable, ResultOfMnemonicVerify]] /** * Prints the list of words from the specified dictionary * @param dictionary dictionary */ - def mnemonicWords(dictionary: Option[Long]): Future[Either[Throwable, ResultOfMnemonicWords]] + def mnemonicWords(dictionary: Option[MnemonicDictionary]): Future[Either[Throwable, ResultOfMnemonicWords]] /** * Modular exponentiation * Performs modular exponentiation for big integers (`base`^`exponent` mod `modulus`). @@ -859,6 +904,13 @@ package abi { case class AbiHandle(value: BigInt) extends AnyVal case class AbiParam(name: String, `type`: String, components: Option[List[AbiParam]]) case class CallSet(function_name: String, header: Option[FunctionHeader], input: Option[Value]) + object DataLayoutEnum { + sealed trait DataLayout + /** Decode message body as function input parameters. */ + case object Input extends DataLayout + /** Decode message body as function output. */ + case object Output extends DataLayout + } case class DecodedMessageBody(body_type: MessageBodyType, name: String, value: Option[Value], header: Option[FunctionHeader]) case class DeploySet(tvc: String, workchain_id: Option[Int], initial_data: Option[Value], initial_pubkey: Option[String]) /** @@ -897,13 +949,14 @@ package abi { case class ParamsOfDecodeAccountData(abi: Abi, data: String, allow_partial: Option[Boolean]) case class ParamsOfDecodeBoc(params: List[AbiParam], boc: String, allow_partial: Boolean) case class ParamsOfDecodeInitialData(abi: Option[Abi], data: String, allow_partial: Option[Boolean]) - case class ParamsOfDecodeMessage(abi: Abi, message: String, allow_partial: Option[Boolean]) - case class ParamsOfDecodeMessageBody(abi: Abi, body: String, is_internal: Boolean, allow_partial: Option[Boolean]) + case class ParamsOfDecodeMessage(abi: Abi, message: String, allow_partial: Option[Boolean], function_name: Option[String], data_layout: Option[DataLayout]) + case class ParamsOfDecodeMessageBody(abi: Abi, body: String, is_internal: Boolean, allow_partial: Option[Boolean], function_name: Option[String], data_layout: Option[DataLayout]) case class ParamsOfEncodeAccount(state_init: StateInitSource, balance: Option[BigInt], last_trans_lt: Option[BigInt], last_paid: Option[Long], boc_cache: Option[BocCacheType]) case class ParamsOfEncodeInitialData(abi: Option[Abi], initial_data: Option[Value], initial_pubkey: Option[String], boc_cache: Option[BocCacheType]) case class ParamsOfEncodeInternalMessage(abi: Option[Abi], address: Option[String], src_address: Option[String], deploy_set: Option[DeploySet], call_set: Option[CallSet], value: String, bounce: Option[Boolean], enable_ihr: Option[Boolean]) - case class ParamsOfEncodeMessage(abi: Abi, address: Option[String], deploy_set: Option[DeploySet], call_set: Option[CallSet], signer: Signer, processing_try_index: Option[Long]) - case class ParamsOfEncodeMessageBody(abi: Abi, call_set: CallSet, is_internal: Boolean, signer: Signer, processing_try_index: Option[Long], address: Option[String]) + case class ParamsOfEncodeMessage(abi: Abi, address: Option[String], deploy_set: Option[DeploySet], call_set: Option[CallSet], signer: Signer, processing_try_index: Option[Long], signature_id: Option[Int]) + case class ParamsOfEncodeMessageBody(abi: Abi, call_set: CallSet, is_internal: Boolean, signer: Signer, processing_try_index: Option[Long], address: Option[String], signature_id: Option[Int]) + case class ParamsOfGetSignatureData(abi: Abi, message: String, signature_id: Option[Int]) case class ParamsOfUpdateInitialData(abi: Option[Abi], data: String, initial_data: Option[Value], initial_pubkey: Option[String], boc_cache: Option[BocCacheType]) case class ResultOfAbiEncodeBoc(boc: String) case class ResultOfAttachSignature(message: String, message_id: String) @@ -917,6 +970,7 @@ package abi { case class ResultOfEncodeInternalMessage(message: String, address: String, message_id: String) case class ResultOfEncodeMessage(message: String, data_to_sign: Option[String], address: String, message_id: String) case class ResultOfEncodeMessageBody(body: String, data_to_sign: Option[String]) + case class ResultOfGetSignatureData(signature: String, unsigned: String) case class ResultOfUpdateInitialData(data: String) object SignerADT { sealed trait Signer @@ -1002,16 +1056,20 @@ package abi { * @param abi abi * @param message message * @param allow_partial allow_partial + * @param function_name function_name + * @param data_layout data_layout */ - def decodeMessage(abi: Abi, message: String, allow_partial: Option[Boolean]): Future[Either[Throwable, DecodedMessageBody]] + def decodeMessage(abi: Abi, message: String, allow_partial: Option[Boolean], function_name: Option[String], data_layout: Option[DataLayout]): Future[Either[Throwable, DecodedMessageBody]] /** * Decodes message body using provided body BOC and ABI. * @param abi abi * @param body body * @param is_internal is_internal * @param allow_partial allow_partial + * @param function_name function_name + * @param data_layout data_layout */ - def decodeMessageBody(abi: Abi, body: String, is_internal: Boolean, allow_partial: Option[Boolean]): Future[Either[Throwable, DecodedMessageBody]] + def decodeMessageBody(abi: Abi, body: String, is_internal: Boolean, allow_partial: Option[Boolean], function_name: Option[String], data_layout: Option[DataLayout]): Future[Either[Throwable, DecodedMessageBody]] /** * Creates account state BOC * Creates account state provided with one of these sets of data : @@ -1120,8 +1178,9 @@ package abi { * <.....add config parameter with default value here> * * Default value is 0. + * @param signature_id signature_id */ - def encodeMessage(abi: Abi, address: Option[String], deploy_set: Option[DeploySet], call_set: Option[CallSet], signer: Signer, processing_try_index: Option[Long]): Future[Either[Throwable, ResultOfEncodeMessage]] + def encodeMessage(abi: Abi, address: Option[String], deploy_set: Option[DeploySet], call_set: Option[CallSet], signer: Signer, processing_try_index: Option[Long], signature_id: Option[Int]): Future[Either[Throwable, ResultOfEncodeMessage]] /** * Encodes message body according to ABI function call. * @param abi abi @@ -1141,8 +1200,16 @@ package abi { * @param address Since ABI version 2.3 destination address of external inbound message is used in message * body signature calculation. Should be provided when signed external inbound message body is * created. Otherwise can be omitted. + * @param signature_id signature_id */ - def encodeMessageBody(abi: Abi, call_set: CallSet, is_internal: Boolean, signer: Signer, processing_try_index: Option[Long], address: Option[String]): Future[Either[Throwable, ResultOfEncodeMessageBody]] + def encodeMessageBody(abi: Abi, call_set: CallSet, is_internal: Boolean, signer: Signer, processing_try_index: Option[Long], address: Option[String], signature_id: Option[Int]): Future[Either[Throwable, ResultOfEncodeMessageBody]] + /** + * Extracts signature from message body and calculates hash to verify the signature + * @param abi abi + * @param message message + * @param signature_id signature_id + */ + def getSignatureData(abi: Abi, message: String, signature_id: Option[Int]): Future[Either[Throwable, ResultOfGetSignatureData]] /** * Updates initial account data with initial values for the contract's static variables and owner's public key. This operation is applicable only for initial account data (before deploy). If the contract is already deployed, its data doesn't contain this data section any more. * @param abi abi @@ -1417,23 +1484,19 @@ package processing { } object ProcessingEventADT { sealed trait ProcessingEvent - case class DidSend(shard_block_id: String, message_id: String, message: String) extends ProcessingEvent - case class FetchFirstBlockFailed(error: ClientError) extends ProcessingEvent - case class FetchNextBlockFailed(shard_block_id: String, message_id: String, message: String, error: ClientError) extends ProcessingEvent - case class MessageExpired(message_id: String, message: String, error: ClientError) extends ProcessingEvent - case class RempError(error: ClientError) extends ProcessingEvent - case class RempIncludedIntoAcceptedBlock(message_id: String, timestamp: BigInt, json: Value) extends ProcessingEvent - case class RempIncludedIntoBlock(message_id: String, timestamp: BigInt, json: Value) extends ProcessingEvent - case class RempOther(message_id: String, timestamp: BigInt, json: Value) extends ProcessingEvent - case class RempSentToValidators(message_id: String, timestamp: BigInt, json: Value) extends ProcessingEvent - case class SendFailed(shard_block_id: String, message_id: String, message: String, error: ClientError) extends ProcessingEvent - /** - * Notifies the application that the account's current shard block will be fetched from the network. This step is performed before the message sending so that sdk knows starting from which block it will search for the transaction. - * Fetched block will be used later in waiting phase. - */ - case object WillFetchFirstBlock extends ProcessingEvent - case class WillFetchNextBlock(shard_block_id: String, message_id: String, message: String) extends ProcessingEvent - case class WillSend(shard_block_id: String, message_id: String, message: String) extends ProcessingEvent + case class DidSend(shard_block_id: String, message_id: String, message_dst: String, message: String) extends ProcessingEvent + case class FetchFirstBlockFailed(error: ClientError, message_id: String, message_dst: String) extends ProcessingEvent + case class FetchNextBlockFailed(shard_block_id: String, message_id: String, message_dst: String, message: String, error: ClientError) extends ProcessingEvent + case class MessageExpired(message_id: String, message_dst: String, message: String, error: ClientError) extends ProcessingEvent + case class RempError(message_id: String, message_dst: String, error: ClientError) extends ProcessingEvent + case class RempIncludedIntoAcceptedBlock(message_id: String, message_dst: String, timestamp: BigInt, json: Value) extends ProcessingEvent + case class RempIncludedIntoBlock(message_id: String, message_dst: String, timestamp: BigInt, json: Value) extends ProcessingEvent + case class RempOther(message_id: String, message_dst: String, timestamp: BigInt, json: Value) extends ProcessingEvent + case class RempSentToValidators(message_id: String, message_dst: String, timestamp: BigInt, json: Value) extends ProcessingEvent + case class SendFailed(shard_block_id: String, message_id: String, message_dst: String, message: String, error: ClientError) extends ProcessingEvent + case class WillFetchFirstBlock(message_id: String, message_dst: String) extends ProcessingEvent + case class WillFetchNextBlock(shard_block_id: String, message_id: String, message_dst: String, message: String) extends ProcessingEvent + case class WillSend(shard_block_id: String, message_id: String, message_dst: String, message: String) extends ProcessingEvent } case class ResultOfProcessMessage(transaction: Value, out_messages: List[String], decoded: Option[DecodedOutput], fees: TransactionFees) case class ResultOfSendMessage(shard_block_id: String, sending_endpoints: List[String]) @@ -1591,7 +1654,7 @@ package tvm { /** Emulate uninitialized account to run deploy message */ case object Uninit extends AccountForExecutor } - case class ExecutionOptions(blockchain_config: Option[String], block_time: Option[Long], block_lt: Option[BigInt], transaction_lt: Option[BigInt], chksig_always_succeed: Option[Boolean]) + case class ExecutionOptions(blockchain_config: Option[String], block_time: Option[Long], block_lt: Option[BigInt], transaction_lt: Option[BigInt], chksig_always_succeed: Option[Boolean], signature_id: Option[Int]) case class ParamsOfRunExecutor(message: String, account: AccountForExecutor, execution_options: Option[ExecutionOptions], abi: Option[Abi], skip_transaction_check: Option[Boolean], boc_cache: Option[BocCacheType], return_updated_account: Option[Boolean]) case class ParamsOfRunGet(account: String, function_name: String, input: Option[Value], execution_options: Option[ExecutionOptions], tuple_list_as_array: Option[Boolean]) case class ParamsOfRunTvm(message: String, account: String, execution_options: Option[ExecutionOptions], abi: Option[Abi], boc_cache: Option[BocCacheType], return_updated_account: Option[Boolean]) @@ -1654,7 +1717,7 @@ package tvm { * the same component that is used on Validator Nodes. * * Can be used for contract debugging, to find out the reason why a message was not delivered successfully. - * Validators throw away the failed external inbound messages (if they failed bedore `ACCEPT`) in the real network. + * Validators throw away the failed external inbound messages (if they failed before `ACCEPT`) in the real network. * This is why these messages are impossible to debug in the real network. * With the help of run_executor you can do that. In fact, `process_message` function * performs local check with `run_executor` if there was no transaction as a result of processing @@ -1753,6 +1816,9 @@ package net { case object GetSubscriptionResultFailed extends NetErrorCode { override val code: String = "604" } + case object GraphqlConnectionError extends NetErrorCode { + override val code: String = "617" + } case object GraphqlError extends NetErrorCode { override val code: String = "608" } @@ -1777,6 +1843,9 @@ package net { case object QueryFailed extends NetErrorCode { override val code: String = "601" } + case object QueryTransactionTreeTimeout extends NetErrorCode { + override val code: String = "616" + } case object SubscribeFailed extends NetErrorCode { override val code: String = "602" } @@ -1810,7 +1879,7 @@ package net { case class QueryCounterparties(value: ParamsOfQueryCounterparties) extends ParamsOfQueryOperation case class WaitForCollection(value: ParamsOfWaitForCollection) extends ParamsOfQueryOperation } - case class ParamsOfQueryTransactionTree(in_msg: String, abi_registry: Option[List[Abi]], timeout: Option[Long]) + case class ParamsOfQueryTransactionTree(in_msg: String, abi_registry: Option[List[Abi]], timeout: Option[Long], transaction_max_count: Option[Long]) case class ParamsOfResumeBlockIterator(resume_state: Value) case class ParamsOfResumeTransactionIterator(resume_state: Value, accounts_filter: Option[List[String]]) case class ParamsOfSubscribe(subscription: String, variables: Option[Value]) @@ -1821,6 +1890,7 @@ package net { case class ResultOfBatchQuery(results: List[Value]) case class ResultOfFindLastShardBlock(block_id: String) case class ResultOfGetEndpoints(query: String, endpoints: List[String]) + case class ResultOfGetSignatureId(signature_id: Option[Int]) case class ResultOfIteratorNext(items: List[Value], has_more: Boolean, resume_state: Option[Value]) case class ResultOfQuery(result: Value) case class ResultOfQueryCollection(result: List[Value]) @@ -2013,6 +2083,8 @@ package net { def findLastShardBlock(address: String): Future[Either[Throwable, ResultOfFindLastShardBlock]] /** Requests the list of alternative endpoints from server */ def getEndpoints(): Future[Either[Throwable, ResultOfGetEndpoints]] + /** Returns signature ID for configured network if it should be used in messages signature */ + def getSignatureId(): Future[Either[Throwable, ResultOfGetSignatureId]] /** * Returns next available items. * In addition to available items this function returns the `has_more` flag @@ -2076,7 +2148,7 @@ package net { * * Function reads transactions layer by layer, by pages of 20 transactions. * - * The retrieval prosess goes like this: + * The retrieval process goes like this: * Let's assume we have an infinite chain of transactions and each transaction generates 5 messages. * 1. Retrieve 1st message (input parameter) and corresponding transaction - put it into result. * It is the first level of the tree of transactions - its root. @@ -2101,9 +2173,14 @@ package net { * @param timeout If some of the following messages and transactions are missing yet * The maximum waiting time is regulated by this option. * - * Default value is 60000 (1 min). + * Default value is 60000 (1 min). If `timeout` is set to 0 then function will wait infinitely + * until the whole transaction tree is executed + * @param transaction_max_count If transaction tree contains more transaction then this parameter then only first `transaction_max_count` transaction are awaited and returned. + * + * Default value is 50. If `transaction_max_count` is set to 0 then no limitation on + * transaction count is used and all transaction are returned. */ - def queryTransactionTree(in_msg: String, abi_registry: Option[List[Abi]], timeout: Option[Long]): Future[Either[Throwable, ResultOfQueryTransactionTree]] + def queryTransactionTree(in_msg: String, abi_registry: Option[List[Abi]], timeout: Option[Long], transaction_max_count: Option[Long]): Future[Either[Throwable, ResultOfQueryTransactionTree]] /** * Removes an iterator * Frees all resources allocated in library to serve iterator. @@ -2118,7 +2195,7 @@ package net { def resume(): Future[Either[Throwable, Unit]] /** * Resumes block iterator. - * The iterator stays exactly at the same position where the `resume_state` was catched. + * The iterator stays exactly at the same position where the `resume_state` was caught. * * Application should call the `remove_iterator` when iterator is no longer required. * @param resume_state Same as value returned from `iterator_next`. @@ -2156,7 +2233,7 @@ package net { * * ### Important Notes on Subscriptions * - * Unfortunately sometimes the connection with the network breakes down. + * Unfortunately sometimes the connection with the network breaks down. * In this situation the library attempts to reconnect to the network. * This reconnection sequence can take significant time. * All of this time the client is disconnected from the network.