From e6ceaf63a64ebe33cc95e9dd8d8bb4fb028f2184 Mon Sep 17 00:00:00 2001 From: Christian Rogobete Date: Sat, 8 Apr 2023 23:18:07 +0200 Subject: [PATCH] add support for soroban prev 8 --- CHANGELOG.md | 5 + README.md | 2 +- lib/src/invoke_host_function_operation.dart | 38 +- lib/src/sep/0011/txrep.dart | 16 +- lib/src/soroban/soroban_auth.dart | 21 +- lib/src/soroban/soroban_server.dart | 313 +++++-- lib/src/xdr/xdr_contract.dart | 895 ++++++++++---------- lib/src/xdr/xdr_transaction.dart | 75 +- pubspec.yaml | 2 +- soroban.md | 77 +- test/soroban_test.dart | 213 +++-- test/soroban_test_atomic_swap.dart | 249 +++--- test/soroban_test_auth.dart | 145 ++-- test/tests_util.dart | 5 +- test/wasm/atomic_swap.wasm | Bin 1497 -> 1982 bytes test/wasm/auth.wasm | Bin 781 -> 678 bytes test/wasm/event.wasm | Bin 1132 -> 1016 bytes test/wasm/hello.wasm | Bin 892 -> 812 bytes test/wasm/token.wasm | Bin 5656 -> 5789 bytes 19 files changed, 1112 insertions(+), 944 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 76dd8f9..36c4334 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,8 @@ +## [1.5.3] - 08.Apr.2023. +- add support for soroban prev 8 +- improve soroban tests & docs +- add missing proof_of_liveness kyc field + ## [1.5.2] - 03.Mar.2023. - add support for soroban prev 7 - add support for soroban auth next diff --git a/README.md b/README.md index f79beab..02838d0 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,7 @@ The Soneso open source Stellar SDK for Flutter is build with Dart and provides A 1. Add the dependency to your pubspec.yaml file: ``` dependencies: - stellar_flutter_sdk: ^1.5.2 + stellar_flutter_sdk: ^1.5.3 ``` 2. Install it (command line or IDE): ``` diff --git a/lib/src/invoke_host_function_operation.dart b/lib/src/invoke_host_function_operation.dart index fdadfa5..0d2c336 100644 --- a/lib/src/invoke_host_function_operation.dart +++ b/lib/src/invoke_host_function_operation.dart @@ -203,11 +203,11 @@ abstract class InvokeHostFunctionOperation extends Operation { op.function.createContractArgs!.contractID.discriminant == XdrContractIDType.CONTRACT_ID_FROM_SOURCE_ACCOUNT) { if (op.function.createContractArgs!.source.discriminant == - XdrSCContractCodeType.SCCONTRACT_CODE_WASM_REF) { + XdrSCContractExecutableType.SCCONTRACT_EXECUTABLE_WASM_REF) { // use builder of create contract op return CreateContractOp.builder(op); } else if (op.function.createContractArgs!.source.discriminant == - XdrSCContractCodeType.SCCONTRACT_CODE_TOKEN) { + XdrSCContractExecutableType.SCCONTRACT_EXECUTABLE_TOKEN) { // use builder of deploy stellar asset contract with account op return DeploySACWithSourceAccountOp.builder(op); } @@ -254,10 +254,7 @@ class InvokeContractOp extends InvokeHostFunctionOperation { List invokeArgsList = List.empty(growable: true); // contract id - XdrSCVal contractIDScVal = XdrSCVal(XdrSCValType.SCV_OBJECT); - XdrSCObject contractIDSCObject = XdrSCObject(XdrSCObjectType.SCO_BYTES); - contractIDSCObject.bin = XdrDataValue(Util.hexToBytes(this._contractID)); - contractIDScVal.obj = contractIDSCObject; + XdrSCVal contractIDScVal = XdrSCVal.forBytes(Util.hexToBytes(this._contractID)); invokeArgsList.add(contractIDScVal); // function name @@ -292,19 +289,14 @@ class InvokeContractOp extends InvokeHostFunctionOperation { List invokeArgsList = xdrHostFunction.invokeArgs!; if (invokeArgsList.length < 2 || - invokeArgsList.elementAt(0).discriminant != XdrSCValType.SCV_OBJECT || - invokeArgsList.elementAt(0).obj == null || + invokeArgsList.elementAt(0).discriminant != XdrSCValType.SCV_BYTES || + invokeArgsList.elementAt(0).bytes == null || invokeArgsList.elementAt(1).discriminant != XdrSCValType.SCV_SYMBOL || invokeArgsList.elementAt(1).sym == null) { throw new Exception("invalid argument"); } - XdrSCObject contractIDSCObject = invokeArgsList.elementAt(0).obj!; - if (contractIDSCObject.discriminant != XdrSCObjectType.SCO_BYTES || - contractIDSCObject.bin == null) { - throw new Exception("invalid argument"); - } - String contractID = Util.bytesToHex(contractIDSCObject.bin!.dataValue); + String contractID = Util.bytesToHex(invokeArgsList.elementAt(0).bytes!.dataValue); String functionName = invokeArgsList.elementAt(1).sym!; List? funcArgs; @@ -387,8 +379,8 @@ class CreateContractOp extends InvokeHostFunctionOperation { XdrContractID(XdrContractIDType.CONTRACT_ID_FROM_SOURCE_ACCOUNT); contractId.salt = this._salt; - XdrSCContractCode code = - XdrSCContractCode(XdrSCContractCodeType.SCCONTRACT_CODE_WASM_REF); + XdrSCContractExecutable code = + XdrSCContractExecutable(XdrSCContractExecutableType.SCCONTRACT_EXECUTABLE_WASM_REF); code.wasmId = XdrHash(Util.hexToBytes(wasmId)); xdrHostFunction.createContractArgs = @@ -409,7 +401,7 @@ class CreateContractOp extends InvokeHostFunctionOperation { xdrHostFunction.createContractArgs!.contractID.discriminant != XdrContractIDType.CONTRACT_ID_FROM_SOURCE_ACCOUNT || xdrHostFunction.createContractArgs!.source.discriminant != - XdrSCContractCodeType.SCCONTRACT_CODE_WASM_REF || + XdrSCContractExecutableType.SCCONTRACT_EXECUTABLE_WASM_REF || xdrHostFunction.createContractArgs!.source.wasmId == null) { throw new Exception("invalid argument"); } @@ -450,8 +442,8 @@ class DeploySACWithSourceAccountOp extends InvokeHostFunctionOperation { XdrContractID(XdrContractIDType.CONTRACT_ID_FROM_SOURCE_ACCOUNT); contractId.salt = this._salt; - XdrSCContractCode code = - XdrSCContractCode(XdrSCContractCodeType.SCCONTRACT_CODE_TOKEN); + XdrSCContractExecutable code = + XdrSCContractExecutable(XdrSCContractExecutableType.SCCONTRACT_EXECUTABLE_TOKEN); xdrHostFunction.createContractArgs = XdrCreateContractArgs(contractId, code); @@ -471,7 +463,7 @@ class DeploySACWithSourceAccountOp extends InvokeHostFunctionOperation { xdrHostFunction.createContractArgs!.contractID.discriminant != XdrContractIDType.CONTRACT_ID_FROM_SOURCE_ACCOUNT || xdrHostFunction.createContractArgs!.source.discriminant != - XdrSCContractCodeType.SCCONTRACT_CODE_TOKEN) { + XdrSCContractExecutableType.SCCONTRACT_EXECUTABLE_TOKEN) { throw new Exception("invalid argument"); } @@ -498,8 +490,8 @@ class DeploySACWithAssetOp extends InvokeHostFunctionOperation { XdrContractID(XdrContractIDType.CONTRACT_ID_FROM_ASSET); contractId.asset = this._asset.toXdr(); - XdrSCContractCode code = - XdrSCContractCode(XdrSCContractCodeType.SCCONTRACT_CODE_TOKEN); + XdrSCContractExecutable code = + XdrSCContractExecutable(XdrSCContractExecutableType.SCCONTRACT_EXECUTABLE_TOKEN); xdrHostFunction.createContractArgs = XdrCreateContractArgs(contractId, code); @@ -520,7 +512,7 @@ class DeploySACWithAssetOp extends InvokeHostFunctionOperation { XdrContractIDType.CONTRACT_ID_FROM_ASSET || xdrHostFunction.createContractArgs!.contractID.asset == null || xdrHostFunction.createContractArgs!.source.discriminant != - XdrSCContractCodeType.SCCONTRACT_CODE_TOKEN) { + XdrSCContractExecutableType.SCCONTRACT_EXECUTABLE_TOKEN) { throw new Exception("invalid argument"); } diff --git a/lib/src/sep/0011/txrep.dart b/lib/src/sep/0011/txrep.dart index 4fd8d83..30091c1 100644 --- a/lib/src/sep/0011/txrep.dart +++ b/lib/src/sep/0011/txrep.dart @@ -578,13 +578,14 @@ class TxRep { String opPrefix = prefix + 'liquidityPoolWithdrawOp.'; return _getLiquidityPoolWithdrawOp(sourceAccountId, opPrefix, map); } - if (opType == 'INVOKE_HOST_FUNCTION') { + /*if (opType == 'INVOKE_HOST_FUNCTION') { String opPrefix = prefix + 'invokeHostFunctionOp.'; return _getInvokeHostFunctionOp(sourceAccountId, opPrefix, map); - } + }*/ throw Exception('invalid or unsupported [$prefix].type - $opType'); } + /* static InvokeHostFunctionOperation _getInvokeHostFunctionOp( String? sourceAccountId, String opPrefix, Map map) { String? fnType = _removeComment(map[opPrefix + 'function.type']); @@ -1407,7 +1408,7 @@ class TxRep { throw Exception('unknown $prefix' + 'type'); } } - +*/ static LiquidityPoolWithdrawOperation _getLiquidityPoolWithdrawOp( String? sourceAccountId, String opPrefix, Map map) { String? liquidityPoolID = _removeComment(map[opPrefix + 'liquidityPoolID']); @@ -3436,7 +3437,7 @@ class TxRep { _addLine('$prefix.amount', _toAmount(operation.amount), lines); _addLine('$prefix.minAmountA', _toAmount(operation.minAmountA), lines); _addLine('$prefix.minAmountB', _toAmount(operation.minAmountB), lines); - } else if (operation is InvokeHostFunctionOperation) { + } /*else if (operation is InvokeHostFunctionOperation) { String fnPrefix = prefix + ".function"; _addLine('$fnPrefix.type', _txRepInvokeHostFnType(operation.functionType), lines); @@ -3499,9 +3500,9 @@ class TxRep { for (int i = 0; i < contractAuth.length; i++) { _addContractAuth(contractAuth[i], lines, prefix + '.auth[$i]'); } - } + }*/ } - + /* static _addContractAuth( XdrContractAuth auth, List lines, String prefix) { if (auth.addressWithNonce != null) { @@ -3976,7 +3977,7 @@ class TxRep { break; } } - + */ static _addClaimPredicate( XdrClaimPredicate? predicate, List? lines, String prefix) { if (lines == null || predicate == null) return; @@ -4037,6 +4038,7 @@ class TxRep { } } + static _addSignatures(List? signatures, List? lines, String prefix) { if (lines == null) return; diff --git a/lib/src/soroban/soroban_auth.dart b/lib/src/soroban/soroban_auth.dart index 9ecbbbc..c361194 100644 --- a/lib/src/soroban/soroban_auth.dart +++ b/lib/src/soroban/soroban_auth.dart @@ -95,7 +95,7 @@ class Address { /// Returns a [XdrSCVal] containing an [XdrSCObject] for this [Address]. XdrSCVal toXdrSCVal() { - return XdrSCVal.forObject(XdrSCObject.forAddress(toXdr())); + return XdrSCVal.forAddress(toXdr()); } } @@ -225,8 +225,8 @@ class ContractAuth { List argsArr = List.empty(growable: true); if (xdr.signatureArgs.length > 0) { XdrSCVal innerVal = xdr.signatureArgs[0]; - if (innerVal.obj != null && innerVal.obj!.vec != null) { - argsArr = innerVal.obj!.vec!; + if (innerVal.vec != null) { + argsArr = innerVal.vec!; } else { argsArr = xdr.signatureArgs; } @@ -255,9 +255,7 @@ class ContractAuth { // See: https://discord.com/channels/897514728459468821/1076723574884282398/1078095366890729595 List sigArgs = List.empty(growable: true); if (signatureArgs.length > 0) { - XdrSCObject obj = XdrSCObject.forVec(signatureArgs); - XdrSCVal val = XdrSCVal.forObject(obj); - sigArgs.add(val); + sigArgs.add(XdrSCVal.forVec(signatureArgs)); } return new XdrContractAuth( addressWithNonce, rootInvocation.toXdr(), sigArgs); @@ -281,13 +279,12 @@ class AccountEd25519Signature { AccountEd25519Signature(this.publicKey, this.signatureBytes); XdrSCVal toXdrSCVal() { - XdrSCObject pkObj = XdrSCObject.forBytes(publicKey.getEd25519()!.uint256); - XdrSCObject sigObj = XdrSCObject.forBytes(signatureBytes); + XdrSCVal pkVal = XdrSCVal.forBytes(publicKey.getEd25519()!.uint256); + XdrSCVal sigVal = XdrSCVal.forBytes(signatureBytes); XdrSCMapEntry pkEntry = XdrSCMapEntry( - XdrSCVal.forSymbol("public_key"), XdrSCVal.forObject(pkObj)); + XdrSCVal.forSymbol("public_key"), pkVal); XdrSCMapEntry sigEntry = XdrSCMapEntry( - XdrSCVal.forSymbol("signature"), XdrSCVal.forObject(sigObj)); - XdrSCObject resultObj = XdrSCObject.forMap([pkEntry, sigEntry]); - return XdrSCVal.forObject(resultObj); + XdrSCVal.forSymbol("signature"), sigVal); + return XdrSCVal.forMap([pkEntry, sigEntry]); } } diff --git a/lib/src/soroban/soroban_server.dart b/lib/src/soroban/soroban_server.dart index d58670a..0b81f3c 100644 --- a/lib/src/soroban/soroban_server.dart +++ b/lib/src/soroban/soroban_server.dart @@ -5,8 +5,8 @@ import 'dart:convert'; import 'dart:typed_data'; import 'package:dio/dio.dart' as dio; +import 'package:stellar_flutter_sdk/src/xdr/xdr_transaction.dart'; import 'soroban_auth.dart'; -import '../muxed_account.dart'; import '../xdr/xdr_data_entry.dart'; import '../xdr/xdr_ledger.dart'; import '../transaction.dart'; @@ -15,16 +15,13 @@ import '../xdr/xdr_contract.dart'; import '../xdr/xdr_data_io.dart'; import '../xdr/xdr_type.dart'; import '../util.dart'; -import '../account.dart'; +import '../xdr/xdr_operation.dart'; +//import '../account.dart'; /// This class helps you to connect to a local or remote soroban rpc server /// and send requests to the server. It parses the results and provides /// corresponding response objects. class SorobanServer { - static const String TRANSACTION_STATUS_PENDING = "pending"; - static const String TRANSACTION_STATUS_SUCCESS = "success"; - static const String TRANSACTION_STATUS_ERROR = "error"; - bool enableLogging = false; bool acknowledgeExperimental = false; @@ -43,6 +40,7 @@ class SorobanServer { } /// General node health check request. + /// See: https://soroban.stellar.org/api/methods/getHealth Future getHealth() async { if (!this.acknowledgeExperimental) { printExperimentalFlagErr(); @@ -58,6 +56,7 @@ class SorobanServer { return GetHealthResponse.fromJson(response.data); } +/* /// Fetch a minimal set of current info about a stellar account. Future getAccount(String accountId) async { if (!this.acknowledgeExperimental) { @@ -74,13 +73,14 @@ class SorobanServer { } return GetAccountResponse.fromJson(response.data); } - +*/ /// For reading the current value of ledger entries directly. /// Allows you to directly inspect the current state of a contract, /// a contract’s code, or any other ledger entry. /// This is a backup way to access your contract data which may /// not be available via events or simulateTransaction. /// To fetch contract wasm byte-code, use the ContractCode ledger entry key. + /// See: https://soroban.stellar.org/api/methods/getLedgerEntry Future getLedgerEntry(String base64EncodedKey) async { if (!this.acknowledgeExperimental) { printExperimentalFlagErr(); @@ -98,6 +98,8 @@ class SorobanServer { return GetLedgerEntryResponse.fromJson(response.data); } + /// General info about the currently configured network. + /// See: https://soroban.stellar.org/api/methods/getNetwork Future getNetwork() async { if (!this.acknowledgeExperimental) { printExperimentalFlagErr(); @@ -115,6 +117,7 @@ class SorobanServer { /// Submit a trial contract invocation to get back return values, /// expected ledger footprint, and expected costs. + /// See: https://soroban.stellar.org/api/methods/simulateTransaction Future simulateTransaction( Transaction transaction) async { if (!this.acknowledgeExperimental) { @@ -140,6 +143,8 @@ class SorobanServer { /// It simply validates and enqueues the transaction. /// Clients should call getTransactionStatus to learn about /// transaction success/failure. + /// This supports all transactions, not only smart contract-related transactions. + /// See: https://soroban.stellar.org/api/methods/sendTransaction Future sendTransaction( Transaction transaction) async { if (!this.acknowledgeExperimental) { @@ -160,24 +165,32 @@ class SorobanServer { } /// Clients will poll this to tell when the transaction has been completed. - Future getTransactionStatus( - String transactionHash) async { + /// See: https://soroban.stellar.org/api/methods/getTransaction + Future getTransaction(String transactionHash) async { if (!this.acknowledgeExperimental) { printExperimentalFlagErr(); - return GetTransactionStatusResponse.fromJson(_experimentalErr); + return GetTransactionResponse.fromJson(_experimentalErr); } JsonRpcMethod getTransactionStatus = - JsonRpcMethod("getTransactionStatus", args: transactionHash); + JsonRpcMethod("getTransaction", args: transactionHash); dio.Response response = await _dio.post(_serverUrl, data: json.encode(getTransactionStatus), options: dio.Options(headers: _headers)); if (enableLogging) { - print("getTransactionStatus response: $response"); + print("getTransaction response: $response"); } - return GetTransactionStatusResponse.fromJson(response.data); + return GetTransactionResponse.fromJson(response.data); } + /// Clients can request a filtered list of events emitted by a given ledger range. + /// Soroban-RPC will support querying within a maximum 24 hours of recent ledgers. + /// Note, this could be used by the client to only prompt a refresh when there is a new ledger with relevant events. + /// It should also be used by backend Dapp components to "ingest" events into their own database for querying and serving. + /// If making multiple requests, clients should deduplicate any events received, based on the event's unique id field. + /// This prevents double-processing in the case of duplicate events being received. + /// By default soroban-rpc retains the most recent 24 hours of events. + /// See: https://soroban.stellar.org/api/methods/getEvents Future getEvents(GetEventsRequest request) async { if (!this.acknowledgeExperimental) { printExperimentalFlagErr(); @@ -194,21 +207,23 @@ class SorobanServer { return GetEventsResponse.fromJson(response.data); } + /// Helper method to get the nonce for a given accountId for the contract + /// specified by the contractId. + /// Used for contract auth. Future getNonce(String accountId, String contractId) async { XdrLedgerKey ledgerKey = XdrLedgerKey(XdrLedgerEntryType.CONTRACT_DATA); ledgerKey.contractID = XdrHash(Util.hexToBytes(contractId)); Address address = Address.forAccountId(accountId); - XdrSCVal nonceKeyVal = - XdrSCVal.forObject(XdrSCObject.forNonceKey(address.toXdr())); + XdrSCVal nonceKeyVal = XdrSCVal.forNonceKeyWithAddress(address); ledgerKey.contractDataKey = nonceKeyVal; GetLedgerEntryResponse response = await getLedgerEntry(ledgerKey.toBase64EncodedXdrString()); if (!response.isErrorResponse && response.ledgerEntryDataXdr != null && response.ledgerEntryDataXdr!.contractData != null) { - XdrSCObject? obj = response.ledgerEntryDataXdr!.contractData!.val.obj; - if (obj != null && obj.u64 != null) { - return obj.u64!.uint64; + XdrSCVal val = response.ledgerEntryDataXdr!.contractData!.val; + if (val.u64 != null) { + return val.u64!.uint64; } } return 0; @@ -229,6 +244,7 @@ abstract class SorobanRpcResponse { } /// General node health check response. +/// See: https://soroban.stellar.org/api/methods/getHealth class GetHealthResponse extends SorobanRpcResponse { /// Health status e.g. "healthy" String? status; @@ -247,6 +263,33 @@ class GetHealthResponse extends SorobanRpcResponse { } } +/// See: https://soroban.stellar.org/api/methods/getLatestLedger +class GetLatestLedgerResponse extends SorobanRpcResponse { + /// hash of the latest ledger as a hex-encoded string. + String? id; + + /// Stellar Core protocol version associated with the latest ledger. + String? protocolVersion; + + /// Sequence number of the latest ledger. + String? sequence; + + GetLatestLedgerResponse(Map jsonResponse) + : super(jsonResponse); + + factory GetLatestLedgerResponse.fromJson(Map json) { + GetLatestLedgerResponse response = GetLatestLedgerResponse(json); + if (json['result'] != null) { + response.id = json['result']['id']; + response.protocolVersion = json['result']['protocolVersion']; + response.sequence = json['result']['sequence']; + } else if (json['error'] != null) { + response.error = SorobanRpcErrorResponse.fromJson(json); + } + return response; + } +} + /// Error response. class SorobanRpcErrorResponse { Map @@ -271,6 +314,7 @@ class SorobanRpcErrorResponse { } } +/* /// Response for fetching current info about a stellar account. class GetAccountResponse extends SorobanRpcResponse with TransactionBuilderAccount { @@ -321,8 +365,10 @@ class GetAccountResponse extends SorobanRpcResponse ? _sequenceNumber! : throw Exception("response has no sequence number"); } +*/ /// Response when reading the current values of ledger entries. +/// See: https://soroban.stellar.org/api/methods/getLedgerEntry class GetLedgerEntryResponse extends SorobanRpcResponse { /// The current value of the given ledger entry (serialized in a base64 string) String? ledgerEntryData; @@ -354,6 +400,7 @@ class GetLedgerEntryResponse extends SorobanRpcResponse { } } +/// See: https://soroban.stellar.org/api/methods/getNetwork class GetNetworkResponse extends SorobanRpcResponse { String? friendbotUrl; String? passphrase; @@ -375,11 +422,13 @@ class GetNetworkResponse extends SorobanRpcResponse { } /// Response that will be received when submitting a trial contract invocation. +/// See: https://soroban.stellar.org/api/methods/simulateTransaction class SimulateTransactionResponse extends SorobanRpcResponse { /// Stringified-number of the current latest ledger observed by the node when this response was generated. String? latestLedger; /// If error is present then results will not be in the response + /// There will be one results object for each operation in the transaction. List? results; /// Information about the fees expected, instructions used, etc. @@ -388,7 +437,8 @@ class SimulateTransactionResponse extends SorobanRpcResponse { SimulateTransactionResponse(Map jsonResponse) : super(jsonResponse); - /// Error within the result if an error occurs. + /// (optional) only present if the transaction failed. + /// This field will include more details from stellar-core about why the invoke host function call failed. String? resultError; factory SimulateTransactionResponse.fromJson(Map json) { @@ -435,17 +485,21 @@ class SimulateTransactionResponse extends SorobanRpcResponse { } /// Used as a part of simulate transaction. +/// See: https://soroban.stellar.org/api/methods/simulateTransaction class SimulateTransactionResult { - /// xdr-encoded return value of the contract call - String xdr; + /// (optional) Only present on success. xdr-encoded return value of the contract call operation. + String? xdr; - /// Footprint containing the ledger keys expected to be written by this transaction + /// The contract data ledger keys which were accessed when simulating this operation. (XdrLedgerFootprint serialized in a base64 string) Footprint? footprint; - // Contract auth + /// Per-address authorizations recorded when simulating this operation. (an array of XdrContractAuth serialized base64 strings) List? auth; - SimulateTransactionResult(this.xdr, this.footprint, this.auth); + /// Events emitted during the contract invocation. (an array of XdrDiagnosticEvent serialized base64 strings) + List? events; + + SimulateTransactionResult(this.xdr, this.footprint, this.auth, this.events); factory SimulateTransactionResult.fromJson(Map json) { String xdr = json['xdr']; @@ -459,24 +513,53 @@ class SimulateTransactionResult { if (json['auth'] != null) { auth = List.from(json['auth'].map((e) => e)); } - return SimulateTransactionResult(xdr, footprint, auth); + + List? events; + if (json['events'] != null) { + auth = List.from(json['events'].map((e) => e)); + } + return SimulateTransactionResult(xdr, footprint, auth, events); } - XdrSCVal get value => XdrSCVal.fromBase64EncodedXdrString(xdr); + /// Only present on success. Return value of the contract call operation. + XdrSCVal? get value => + xdr != null ? XdrSCVal.fromBase64EncodedXdrString(xdr!) : null; } /// Response when submitting a real transaction to the stellar network. +/// See: https://soroban.stellar.org/api/methods/sendTransaction class SendTransactionResponse extends SorobanRpcResponse { - /// The transaction hash (in an hex-encoded string), and the initial - /// transaction status, ("pending" or something) - String? transactionId; + /// represents the status value returned by stellar-core when an error occurred from submitting a transaction + static const String STATUS_ERROR = "ERROR"; - /// The current status of the transaction by hash, one of: pending, success, error + /// represents the status value returned by stellar-core when a transaction has been accepted for processing + static const String STATUS_PENDING = "PENDING"; + + /// represents the status value returned by stellar-core when a submitted transaction is a duplicate + static const String STATUS_DUPLICATE = "DUPLICATE"; + + /// represents the status value returned by stellar-core when a submitted transaction was not included in the + static const String STATUS_TRY_AGAIN_LATER = "TRY_AGAIN_LATER"; + + /// The transaction hash (in an hex-encoded string). + String? hash; + + /// The current status of the transaction by hash, one of: ERROR, PENDING, DUPLICATE, TRY_AGAIN_LATER + /// ERROR represents the status value returned by stellar-core when an error occurred from submitting a transaction + /// PENDING represents the status value returned by stellar-core when a transaction has been accepted for processing + /// DUPLICATE represents the status value returned by stellar-core when a submitted transaction is a duplicate + /// TRY_AGAIN_LATER represents the status value returned by stellar-core when a submitted transaction was not included in the + /// previous 4 ledgers and get banned for being added in the next few ledgers. String? status; - /// (optional) If the transaction was rejected immediately, - /// this will be an error object. - TransactionStatusError? resultError; + /// The latest ledger known to Soroban-RPC at the time it handled the sendTransaction() request. + String? latestLedger; + + /// The unix timestamp of the close time of the latest ledger known to Soroban-RPC at the time it handled the sendTransaction() request. + String? latestLedgerCloseTime; + + /// (optional) If the transaction status is ERROR, this will be a base64 encoded string of the raw TransactionResult XDR struct containing details on why stellar-core rejected the transaction. + String? errorResultXdr; SendTransactionResponse(Map jsonResponse) : super(jsonResponse); @@ -484,12 +567,11 @@ class SendTransactionResponse extends SorobanRpcResponse { factory SendTransactionResponse.fromJson(Map json) { SendTransactionResponse response = SendTransactionResponse(json); if (json['result'] != null) { - response.transactionId = json['result']['id']; + response.hash = json['result']['hash']; response.status = json['result']['status']; - if (json['result']['error'] != null) { - response.resultError = - TransactionStatusError.fromJson(json['result']['error']); - } + response.latestLedger = json['result']['latestLedger']; + response.latestLedgerCloseTime = json['result']['latestLedgerCloseTime']; + response.errorResultXdr = json['result']['errorResultXdr']; } else if (json['error'] != null) { response.error = SorobanRpcErrorResponse.fromJson(json); } @@ -497,8 +579,9 @@ class SendTransactionResponse extends SorobanRpcResponse { } } +/* /// Internal error used within some of the responses. -class TransactionStatusError extends SorobanRpcResponse { +class GetTransactionError extends SorobanRpcResponse { /// Short unique string representing the type of error String? code; @@ -508,68 +591,95 @@ class TransactionStatusError extends SorobanRpcResponse { /// (optional) More data related to the error if available Map? data; - TransactionStatusError(Map jsonResponse) + GetTransactionError(Map jsonResponse) : super(jsonResponse); - factory TransactionStatusError.fromJson(Map json) { - TransactionStatusError response = TransactionStatusError(json); + factory GetTransactionError.fromJson(Map json) { + GetTransactionError response = GetTransactionError(json); response.code = json['code']; response.message = json['message']; response.data = json['data']; return response; } } +*/ /// Response when polling the rpc server to find out if a transaction has been /// completed. -class GetTransactionStatusResponse extends SorobanRpcResponse { - /// Hash (id) of the transaction as a hex-encoded string - String? id; +/// See https://soroban.stellar.org/api/methods/getTransaction +class GetTransactionResponse extends SorobanRpcResponse { + static const String STATUS_SUCCESS = "SUCCESS"; + static const String STATUS_NOT_FOUND = "NOT_FOUND"; + static const String STATUS_FAILED = "FAILED"; - /// The current status of the transaction by hash, one of: pending, success, error + /// The current status of the transaction by hash, one of: SUCCESS, NOT_FOUND, FAILED String? status; - /// (optional) Will be present on completed successful transactions. - List? results; + /// The latest ledger known to Soroban-RPC at the time it handled the getTransaction() request. + String? latestLedger; + + /// The unix timestamp of the close time of the latest ledger known to Soroban-RPC at the time it handled the getTransaction() request. + String? latestLedgerCloseTime; + + /// The oldest ledger ingested by Soroban-RPC at the time it handled the getTransaction() request. + String? oldestLedger; + + /// The unix timestamp of the close time of the oldest ledger ingested by Soroban-RPC at the time it handled the getTransaction() request. + String? oldestLedgerCloseTime; + + /// (optional) The sequence of the ledger which included the transaction. This field is only present if status is SUCCESS or FAILED. + String? ledger; + + /// (optional) The unix timestamp of when the transaction was included in the ledger. This field is only present if status is SUCCESS or FAILED. + String? createdAt; + + /// (optional) The index of the transaction among all transactions included in the ledger. This field is only present if status is SUCCESS or FAILED. + int? applicationOrder; + + /// (optional) Indicates whether the transaction was fee bumped. This field is only present if status is SUCCESS or FAILED. + bool? feeBump; /// (optional) A base64 encoded string of the raw TransactionEnvelope XDR struct for this transaction. String? envelopeXdr; - /// (optional) A base64 encoded string of the raw TransactionResult XDR struct for this transaction. + /// (optional) A base64 encoded string of the raw TransactionResult XDR struct for this transaction. This field is only present if status is SUCCESS or FAILED. String? resultXdr; /// (optional) A base64 encoded string of the raw TransactionMeta XDR struct for this transaction. String? resultMetaXdr; - /// (optional) Will be present on failed transactions. - TransactionStatusError? resultError; - - GetTransactionStatusResponse(Map jsonResponse) + GetTransactionResponse(Map jsonResponse) : super(jsonResponse); - factory GetTransactionStatusResponse.fromJson(Map json) { - GetTransactionStatusResponse response = GetTransactionStatusResponse(json); + factory GetTransactionResponse.fromJson(Map json) { + GetTransactionResponse response = GetTransactionResponse(json); if (json['result'] != null) { - if (json['result']['results'] != null) { - response.results = List.from(json['result'] - ['results'] - .map((e) => TransactionStatusResult.fromJson(e))); - } - response.id = json['result']['id']; response.status = json['result']['status']; + response.latestLedger = json['result']['latestLedger']; + response.latestLedgerCloseTime = json['result']['latestLedgerCloseTime']; + response.oldestLedger = json['result']['oldestLedger']; + response.oldestLedgerCloseTime = json['result']['oldestLedgerCloseTime']; + response.ledger = json['result']['ledger']; + response.createdAt = json['result']['createdAt']; + response.applicationOrder = + convertToInt(json['result']['applicationOrder']); + response.feeBump = json['result']['feeBump']; response.envelopeXdr = json['result']['envelopeXdr']; response.resultXdr = json['result']['resultXdr']; response.resultMetaXdr = json['result']['resultMetaXdr']; - if (json['result']['error'] != null) { - response.resultError = - TransactionStatusError.fromJson(json['result']['error']); - } } else if (json['error'] != null) { response.error = SorobanRpcErrorResponse.fromJson(json); } return response; } + static int? convertToInt(var src) { + if (src == null) return null; + if (src is int) return src; + if (src is String) return int.parse(src); + throw Exception("Not integer"); + } + /// Extracts the wasm id from the response if the transaction installed a contract String? getWasmId() { return _getBinHex(); @@ -582,10 +692,19 @@ class GetTransactionStatusResponse extends SorobanRpcResponse { /// Extracts the result value from the first entry on success XdrSCVal? getResultValue() { - if (error != null || results == null || results!.length == 0) { + if (error != null || status != STATUS_SUCCESS || resultMetaXdr == null) { + return null; + } + + print ("RES META " + resultMetaXdr!); + + XdrTransactionMeta meta = + XdrTransactionMeta.fromBase64EncodedXdrString(resultMetaXdr!); + List? results = meta.v3?.txResult.result.results; // :) + if (results == null || results.length == 0) { return null; } - return results!.first.value; + return results.first.tr?.invokeHostFunctionResult?.success; // ;) } String? _getBinHex() { @@ -597,30 +716,35 @@ class GetTransactionStatusResponse extends SorobanRpcResponse { } XdrDataValue? _getBin() { - if (error != null || results == null || results!.length == 0) { - return null; - } - XdrSCVal xdrVal = results!.first.value; - if (xdrVal.obj != null) { - return xdrVal.obj!.bin; - } - return null; + XdrSCVal? xdrVal = getResultValue(); + return xdrVal?.bytes; } } +/// Holds the request parameters for getEvents. +/// See: https://soroban.stellar.org/api/methods/getEvents class GetEventsRequest { - String startLedger; - String endLedger; + /// Stringified ledger sequence number to fetch events after (inclusive). + /// The getEvents method will return an error if startLedger is less than the oldest ledger stored in this node, + /// or greater than the latest ledger seen by this node. + /// If a cursor is included in the request, startLedger must be omitted. + String? startLedger; + + /// List of filters for the returned events. Events matching any of the filters are included. + /// To match a filter, an event must match both a contractId and a topic. + /// Maximum 5 filters are allowed per request. List? filters; + + /// Pagination List? paginationOptions; - GetEventsRequest(this.startLedger, this.endLedger, - {this.filters, this.paginationOptions}); + GetEventsRequest(this.startLedger, {this.filters, this.paginationOptions}); Map getRequestArgs() { var map = {}; - map['startLedger'] = startLedger; - map['endLedger'] = endLedger; + if (startLedger != null) { + map['startLedger'] = startLedger; + } if (filters != null) { List> values = List>.empty(growable: true); @@ -641,10 +765,22 @@ class GetEventsRequest { } } +/// Event filter for the getEvents request. +/// See: https://soroban.stellar.org/api/methods/getEvents class EventFilter { + /// (optional) A comma separated list of event types (system, contract, or diagnostic) + /// used to filter events. If omitted, all event types are included. String? type; + + /// (optional) List of contract ids to query for events. + /// If omitted, return events for all contracts. + /// Maximum 5 contract IDs are allowed per request. List? contractIds; - List? topics; + + /// (optional) List of topic filters. If omitted, query for all events. + /// If multiple filters are specified, events will be included if they match any of the filters. + /// Maximum 5 filters are allowed per request. + List? topics; EventFilter({this.type, this.contractIds, this.topics}); @@ -659,7 +795,7 @@ class EventFilter { if (topics != null) { List> values = List>.empty(growable: true); - for (SegmentFilter filter in topics!) { + for (TopicFilter filter in topics!) { values.add(filter.getRequestArgs()); } map['topics'] = values; @@ -668,11 +804,14 @@ class EventFilter { } } -class SegmentFilter { +/// Part of the getEvents request parameters. +/// https://soroban.stellar.org/api/methods/getEvents +/// TODO: update this! +class TopicFilter { String? wildcard; List? scVal; - SegmentFilter({this.wildcard, this.scVal}); + TopicFilter({this.wildcard, this.scVal}); Map getRequestArgs() { var map = {}; @@ -761,7 +900,7 @@ class EventInfoValue { return EventInfoValue(json['xdr']); } } - +/* /// Used as a part of get transaction status and send transaction. class TransactionStatusResult { /// xdr-encoded return value of the contract call @@ -772,7 +911,7 @@ class TransactionStatusResult { TransactionStatusResult(json['xdr']); XdrSCVal get value => XdrSCVal.fromBase64EncodedXdrString(xdr); -} +}*/ /// Information about the fees expected, instructions used, etc. class SimulateTransactionCost { diff --git a/lib/src/xdr/xdr_contract.dart b/lib/src/xdr/xdr_contract.dart index d276a51..fc1182c 100644 --- a/lib/src/xdr/xdr_contract.dart +++ b/lib/src/xdr/xdr_contract.dart @@ -6,7 +6,6 @@ import 'dart:convert'; import 'dart:typed_data'; import 'package:pinenacl/api.dart'; - import '../key_pair.dart'; import '../soroban/soroban_auth.dart'; import '../util.dart'; @@ -26,34 +25,77 @@ class XdrSCValType { XdrSCValType(this._value); get value => this._value; - static const SCV_U63 = const XdrSCValType._internal(0); - static const SCV_U32 = const XdrSCValType._internal(1); - static const SCV_I32 = const XdrSCValType._internal(2); - static const SCV_STATIC = const XdrSCValType._internal(3); - static const SCV_OBJECT = const XdrSCValType._internal(4); - static const SCV_SYMBOL = const XdrSCValType._internal(5); - static const SCV_BITSET = const XdrSCValType._internal(6); - static const SCV_STATUS = const XdrSCValType._internal(7); + static const SCV_BOOL = const XdrSCValType._internal(0); + static const SCV_VOID = const XdrSCValType._internal(1); + static const SCV_STATUS = const XdrSCValType._internal(2); + static const SCV_U32 = const XdrSCValType._internal(3); + static const SCV_I32 = const XdrSCValType._internal(4); + static const SCV_U64 = const XdrSCValType._internal(5); + static const SCV_I64 = const XdrSCValType._internal(6); + static const SCV_TIMEPOINT = const XdrSCValType._internal(7); + static const SCV_DURATION = const XdrSCValType._internal(8); + static const SCV_U128 = const XdrSCValType._internal(9); + static const SCV_I128 = const XdrSCValType._internal(10); + static const SCV_U256 = const XdrSCValType._internal(11); + static const SCV_I256 = const XdrSCValType._internal(12); + static const SCV_BYTES = const XdrSCValType._internal(13); + static const SCV_STRING = const XdrSCValType._internal(14); + static const SCV_SYMBOL = const XdrSCValType._internal(15); + static const SCV_VEC = const XdrSCValType._internal(16); + static const SCV_MAP = const XdrSCValType._internal(17); + static const SCV_CONTRACT_EXECUTABLE = const XdrSCValType._internal(18); + static const SCV_ADDRESS = const XdrSCValType._internal(19); + static const SCV_LEDGER_KEY_CONTRACT_EXECUTABLE = + const XdrSCValType._internal(20); + static const SCV_LEDGER_KEY_NONCE = const XdrSCValType._internal(21); static XdrSCValType decode(XdrDataInputStream stream) { int value = stream.readInt(); switch (value) { case 0: - return SCV_U63; + return SCV_BOOL; case 1: - return SCV_U32; + return SCV_VOID; case 2: - return SCV_I32; + return SCV_STATUS; case 3: - return SCV_STATIC; + return SCV_U32; case 4: - return SCV_OBJECT; + return SCV_I32; case 5: - return SCV_SYMBOL; + return SCV_U64; case 6: - return SCV_BITSET; + return SCV_I64; case 7: - return SCV_STATUS; + return SCV_TIMEPOINT; + case 8: + return SCV_DURATION; + case 9: + return SCV_U128; + case 10: + return SCV_I128; + case 11: + return SCV_U256; + case 12: + return SCV_I256; + case 13: + return SCV_BYTES; + case 14: + return SCV_STRING; + case 15: + return SCV_SYMBOL; + case 16: + return SCV_VEC; + case 17: + return SCV_MAP; + case 18: + return SCV_CONTRACT_EXECUTABLE; + case 19: + return SCV_ADDRESS; + case 20: + return SCV_LEDGER_KEY_CONTRACT_EXECUTABLE; + case 21: + return SCV_LEDGER_KEY_NONCE; default: throw Exception("Unknown enum value: $value"); } @@ -64,39 +106,6 @@ class XdrSCValType { } } -class XdrSCStatic { - final _value; - const XdrSCStatic._internal(this._value); - toString() => 'SCStatic.$_value'; - XdrSCStatic(this._value); - get value => this._value; - - static const SCS_VOID = const XdrSCStatic._internal(0); - static const SCS_TRUE = const XdrSCStatic._internal(1); - static const SCS_FALSE = const XdrSCStatic._internal(2); - static const SCS_LEDGER_KEY_CONTRACT_CODE = const XdrSCStatic._internal(3); - - static XdrSCStatic decode(XdrDataInputStream stream) { - int value = stream.readInt(); - switch (value) { - case 0: - return SCS_VOID; - case 1: - return SCS_TRUE; - case 2: - return SCS_FALSE; - case 3: - return SCS_LEDGER_KEY_CONTRACT_CODE; - default: - throw Exception("Unknown enum value: $value"); - } - } - - static void encode(XdrDataOutputStream stream, XdrSCStatic value) { - stream.writeInt(value.value); - } -} - class XdrSCStatusType { final _value; const XdrSCStatusType._internal(this._value); @@ -650,57 +659,6 @@ class XdrSCStatus { } } -class XdrSCObjectType { - final _value; - const XdrSCObjectType._internal(this._value); - toString() => 'SCObjectType.$_value'; - XdrSCObjectType(this._value); - get value => this._value; - - static const SCO_VEC = const XdrSCObjectType._internal(0); - static const SCO_MAP = const XdrSCObjectType._internal(1); - static const SCO_U64 = const XdrSCObjectType._internal(2); - static const SCO_I64 = const XdrSCObjectType._internal(3); - static const SCO_U128 = const XdrSCObjectType._internal(4); - static const SCO_I128 = const XdrSCObjectType._internal(5); - static const SCO_BYTES = const XdrSCObjectType._internal(6); - static const SCO_CONTRACT_CODE = const XdrSCObjectType._internal(7); - static const SCO_ADDRESS = const XdrSCObjectType._internal(8); - static const SCO_NONCE_KEY = const XdrSCObjectType._internal(9); - - static XdrSCObjectType decode(XdrDataInputStream stream) { - int value = stream.readInt(); - switch (value) { - case 0: - return SCO_VEC; - case 1: - return SCO_MAP; - case 2: - return SCO_U64; - case 3: - return SCO_I64; - case 4: - return SCO_U128; - case 5: - return SCO_I128; - case 6: - return SCO_BYTES; - case 7: - return SCO_CONTRACT_CODE; - case 8: - return SCO_ADDRESS; - case 9: - return SCO_NONCE_KEY; - default: - throw Exception("Unknown enum value: $value"); - } - } - - static void encode(XdrDataOutputStream stream, XdrSCObjectType value) { - stream.writeInt(value.value); - } -} - class XdrSCAddressType { final _value; const XdrSCAddressType._internal(this._value); @@ -768,17 +726,35 @@ class XdrSCAddress { } static XdrSCAddress forAccountId(String accountId) { - XdrSCAddress result = XdrSCAddress(XdrSCAddressType.SC_ADDRESS_TYPE_ACCOUNT); - result.accountId = XdrAccountID(KeyPair.fromAccountId(accountId).xdrPublicKey); + XdrSCAddress result = + XdrSCAddress(XdrSCAddressType.SC_ADDRESS_TYPE_ACCOUNT); + result.accountId = + XdrAccountID(KeyPair.fromAccountId(accountId).xdrPublicKey); return result; } static XdrSCAddress forContractId(String contractId) { - XdrSCAddress result = XdrSCAddress(XdrSCAddressType.SC_ADDRESS_TYPE_CONTRACT); + XdrSCAddress result = + XdrSCAddress(XdrSCAddressType.SC_ADDRESS_TYPE_CONTRACT); result.contractId = XdrHash(Util.hexToBytes(contractId)); return result; } +} + +class XdrSCNonceKey { + XdrSCAddress _nonce_address; + XdrSCAddress get nonce_address => this._nonce_address; + set nonce_address(XdrSCAddress value) => this._nonce_address = value; + + XdrSCNonceKey(this._nonce_address); + static void encode(XdrDataOutputStream stream, XdrSCNonceKey encoded) { + XdrSCAddress.encode(stream, encoded.nonce_address); + } + + static XdrSCNonceKey decode(XdrDataInputStream stream) { + return XdrSCNonceKey(XdrSCAddress.decode(stream)); + } } class XdrSCMapEntry { @@ -830,82 +806,93 @@ class XdrInt128Parts { } } -class XdrSCContractCodeType { +class XdrSCContractExecutableType { final _value; - const XdrSCContractCodeType._internal(this._value); - toString() => 'SCContractCodeType.$_value'; - XdrSCContractCodeType(this._value); + const XdrSCContractExecutableType._internal(this._value); + toString() => 'SCContractExecutableType.$_value'; + XdrSCContractExecutableType(this._value); get value => this._value; - static const SCCONTRACT_CODE_WASM_REF = - const XdrSCContractCodeType._internal(0); - static const SCCONTRACT_CODE_TOKEN = const XdrSCContractCodeType._internal(1); + static const SCCONTRACT_EXECUTABLE_WASM_REF = + const XdrSCContractExecutableType._internal(0); + static const SCCONTRACT_EXECUTABLE_TOKEN = + const XdrSCContractExecutableType._internal(1); - static XdrSCContractCodeType decode(XdrDataInputStream stream) { + static XdrSCContractExecutableType decode(XdrDataInputStream stream) { int value = stream.readInt(); switch (value) { case 0: - return SCCONTRACT_CODE_WASM_REF; + return SCCONTRACT_EXECUTABLE_WASM_REF; case 1: - return SCCONTRACT_CODE_TOKEN; + return SCCONTRACT_EXECUTABLE_TOKEN; default: throw Exception("Unknown enum value: $value"); } } - static void encode(XdrDataOutputStream stream, XdrSCContractCodeType value) { + static void encode( + XdrDataOutputStream stream, XdrSCContractExecutableType value) { stream.writeInt(value.value); } } -class XdrSCContractCode { - XdrSCContractCode(this._type); - XdrSCContractCodeType _type; - XdrSCContractCodeType get discriminant => this._type; - set discriminant(XdrSCContractCodeType value) => this._type = value; +class XdrSCContractExecutable { + XdrSCContractExecutable(this._type); + XdrSCContractExecutableType _type; + XdrSCContractExecutableType get discriminant => this._type; + set discriminant(XdrSCContractExecutableType value) => this._type = value; XdrHash? _wasmId; XdrHash? get wasmId => this._wasmId; set wasmId(XdrHash? value) => this._wasmId = value; - static void encode(XdrDataOutputStream stream, XdrSCContractCode encoded) { + static void encode( + XdrDataOutputStream stream, XdrSCContractExecutable encoded) { stream.writeInt(encoded.discriminant.value); switch (encoded.discriminant) { - case XdrSCContractCodeType.SCCONTRACT_CODE_WASM_REF: + case XdrSCContractExecutableType.SCCONTRACT_EXECUTABLE_WASM_REF: XdrHash.encode(stream, encoded.wasmId!); break; - case XdrSCContractCodeType.SCCONTRACT_CODE_TOKEN: + case XdrSCContractExecutableType.SCCONTRACT_EXECUTABLE_TOKEN: break; } } - static XdrSCContractCode decode(XdrDataInputStream stream) { - XdrSCContractCode decoded = - XdrSCContractCode(XdrSCContractCodeType.decode(stream)); + static XdrSCContractExecutable decode(XdrDataInputStream stream) { + XdrSCContractExecutable decoded = + XdrSCContractExecutable(XdrSCContractExecutableType.decode(stream)); switch (decoded.discriminant) { - case XdrSCContractCodeType.SCCONTRACT_CODE_WASM_REF: + case XdrSCContractExecutableType.SCCONTRACT_EXECUTABLE_WASM_REF: decoded.wasmId = XdrHash.decode(stream); break; - case XdrSCContractCodeType.SCCONTRACT_CODE_TOKEN: + case XdrSCContractExecutableType.SCCONTRACT_EXECUTABLE_TOKEN: break; } return decoded; } } -class XdrSCObject { - XdrSCObject(this._type); - XdrSCObjectType _type; - XdrSCObjectType get discriminant => this._type; - set discriminant(XdrSCObjectType value) => this._type = value; +class XdrSCVal { + XdrSCVal(this._type); + XdrSCValType _type; + XdrSCValType get discriminant => this._type; + set discriminant(XdrSCValType value) => this._type = value; - List? _vec; - List? get vec => this._vec; - set vec(List? value) => this._vec = value; + bool? _b; + bool? get b => this._b; + set b(bool? value) => this._b = value; - List? _map; - List? get map => this._map; - set map(List? value) => this._map = value; + XdrSCStatus? _error; + XdrSCStatus? get error => this._error; + set error(XdrSCStatus? value) => this._error = value; + + XdrUint32? _u32; + XdrUint32? get u32 => this._u32; + set u32(XdrUint32? value) => this._u32 = value; + + XdrInt32? _i32; + XdrInt32? get i32 => this._i32; + set i32(XdrInt32? value) => this._i32 = value; XdrUint64? _u64; XdrUint64? get u64 => this._u64; @@ -915,6 +902,14 @@ class XdrSCObject { XdrInt64? get i64 => this._i64; set i64(XdrInt64? value) => this._i64 = value; + XdrUint64? _timepoint; + XdrUint64? get timepoint => this._timepoint; + set timepoint(XdrUint64? value) => this._timepoint = value; + + XdrUint64? _duration; + XdrUint64? get duration => this._duration; + set duration(XdrUint64? value) => this._duration = value; + XdrInt128Parts? _u128; XdrInt128Parts? get u128 => this._u128; set u128(XdrInt128Parts? value) => this._u128 = value; @@ -923,351 +918,316 @@ class XdrSCObject { XdrInt128Parts? get i128 => this._i128; set i128(XdrInt128Parts? value) => this._i128 = value; - XdrDataValue? _bin; - XdrDataValue? get bin => this._bin; - set bin(XdrDataValue? value) => this._bin = value; + XdrUint256? _u256; + XdrUint256? get u256 => this._u256; + set u256(XdrUint256? value) => this._u256 = value; + + XdrUint256? _i256; + XdrUint256? get i256 => this._i256; + set i256(XdrUint256? value) => this._i256 = value; + + XdrDataValue? _bytes; + XdrDataValue? get bytes => this._bytes; + set bytes(XdrDataValue? value) => this._bytes = value; + + String? _str; + String? get str => this._str; + set str(String? value) => this._str = value; + + String? _sym; + String? get sym => this._sym; + set sym(String? value) => this._sym = value; + + List? _vec; + List? get vec => this._vec; + set vec(List? value) => this._vec = value; - XdrSCContractCode? _contractCode; - XdrSCContractCode? get contractCode => this._contractCode; - set contractCode(XdrSCContractCode? value) => this._contractCode = value; + List? _map; + List? get map => this._map; + set map(List? value) => this._map = value; + + XdrSCContractExecutable? _exec; + XdrSCContractExecutable? get exec => this._exec; + set exec(XdrSCContractExecutable? value) => this._exec = value; XdrSCAddress? _address; XdrSCAddress? get address => this._address; set address(XdrSCAddress? value) => this._address = value; - XdrSCAddress? _nonceKey; - XdrSCAddress? get nonceKey => this._nonceKey; - set nonceKey(XdrSCAddress? value) => this._nonceKey = value; + XdrSCNonceKey? _nonce_key; + XdrSCNonceKey? get nonce_key => this._nonce_key; + set nonce_key(XdrSCNonceKey? value) => this._nonce_key = value; - static void encode(XdrDataOutputStream stream, XdrSCObject encoded) { + static void encode(XdrDataOutputStream stream, XdrSCVal encoded) { stream.writeInt(encoded.discriminant.value); switch (encoded.discriminant) { - case XdrSCObjectType.SCO_VEC: - int vecSize = encoded.vec!.length; - stream.writeInt(vecSize); - for (int i = 0; i < vecSize; i++) { - XdrSCVal.encode(stream, encoded.vec![i]); - } + case XdrSCValType.SCV_BOOL: + stream.writeBoolean(encoded.b!); break; - case XdrSCObjectType.SCO_MAP: - int mapSize = encoded.map!.length; - stream.writeInt(mapSize); - for (int i = 0; i < mapSize; i++) { - XdrSCMapEntry.encode(stream, encoded.map![i]); - } + case XdrSCValType.SCV_VOID: + break; + case XdrSCValType.SCV_STATUS: + XdrSCStatus.encode(stream, encoded.error!); + break; + case XdrSCValType.SCV_U32: + XdrUint32.encode(stream, encoded.u32!); + break; + case XdrSCValType.SCV_I32: + XdrInt32.encode(stream, encoded.i32!); break; - case XdrSCObjectType.SCO_U64: + case XdrSCValType.SCV_U64: XdrUint64.encode(stream, encoded.u64!); break; - case XdrSCObjectType.SCO_I64: + case XdrSCValType.SCV_I64: XdrInt64.encode(stream, encoded.i64!); break; - case XdrSCObjectType.SCO_U128: + case XdrSCValType.SCV_TIMEPOINT: + XdrUint64.encode(stream, encoded.timepoint!); + break; + case XdrSCValType.SCV_DURATION: + XdrUint64.encode(stream, encoded.duration!); + break; + case XdrSCValType.SCV_U128: XdrInt128Parts.encode(stream, encoded.u128!); break; - case XdrSCObjectType.SCO_I128: + case XdrSCValType.SCV_I128: XdrInt128Parts.encode(stream, encoded.i128!); break; - case XdrSCObjectType.SCO_BYTES: - XdrDataValue.encode(stream, encoded.bin!); + case XdrSCValType.SCV_U256: + XdrUint256.encode(stream, encoded.u256!); + break; + case XdrSCValType.SCV_I256: + XdrUint256.encode(stream, encoded.i256!); break; - case XdrSCObjectType.SCO_CONTRACT_CODE: - XdrSCContractCode.encode(stream, encoded.contractCode!); + case XdrSCValType.SCV_BYTES: + XdrDataValue.encode(stream, encoded.bytes!); break; - case XdrSCObjectType.SCO_ADDRESS: + case XdrSCValType.SCV_STRING: + stream.writeString(encoded.str!); + break; + case XdrSCValType.SCV_SYMBOL: + stream.writeString(encoded.sym!); + break; + case XdrSCValType.SCV_VEC: + if (encoded.vec == null) { + stream.writeInt(0); + } else { + stream.writeInt(1); + int vecSize = encoded.vec!.length; + stream.writeInt(vecSize); + for (int i = 0; i < vecSize; i++) { + XdrSCVal.encode(stream, encoded.vec![i]); + } + } + break; + case XdrSCValType.SCV_MAP: + if (encoded.map == null) { + stream.writeInt(0); + } else { + stream.writeInt(1); + int mapSize = encoded.map!.length; + stream.writeInt(mapSize); + for (int i = 0; i < mapSize; i++) { + XdrSCMapEntry.encode(stream, encoded.map![i]); + } + } + break; + case XdrSCValType.SCV_CONTRACT_EXECUTABLE: + XdrSCContractExecutable.encode(stream, encoded.exec!); + break; + case XdrSCValType.SCV_ADDRESS: XdrSCAddress.encode(stream, encoded.address!); break; - case XdrSCObjectType.SCO_NONCE_KEY: - XdrSCAddress.encode(stream, encoded.nonceKey!); + case XdrSCValType.SCV_LEDGER_KEY_CONTRACT_EXECUTABLE: + break; + case XdrSCValType.SCV_LEDGER_KEY_NONCE: + XdrSCNonceKey.encode(stream, encoded.nonce_key!); break; } } - static XdrSCObject decode(XdrDataInputStream stream) { - XdrSCObject decoded = XdrSCObject(XdrSCObjectType.decode(stream)); + static XdrSCVal decode(XdrDataInputStream stream) { + XdrSCVal decoded = XdrSCVal(XdrSCValType.decode(stream)); switch (decoded.discriminant) { - case XdrSCObjectType.SCO_VEC: - int vecSize = stream.readInt(); - decoded.vec = List.empty(growable: true); - for (int i = 0; i < vecSize; i++) { - decoded.vec!.add(XdrSCVal.decode(stream)); - } + case XdrSCValType.SCV_BOOL: + decoded.b = stream.readBoolean(); break; - case XdrSCObjectType.SCO_MAP: - int mapSize = stream.readInt(); - decoded.map = List.empty(growable: true); - for (int i = 0; i < mapSize; i++) { - decoded.map!.add(XdrSCMapEntry.decode(stream)); - } + case XdrSCValType.SCV_VOID: + break; + case XdrSCValType.SCV_STATUS: + decoded.error = XdrSCStatus.decode(stream); + break; + case XdrSCValType.SCV_U32: + decoded.u32 = XdrUint32.decode(stream); + break; + case XdrSCValType.SCV_I32: + decoded.i32 = XdrInt32.decode(stream); break; - case XdrSCObjectType.SCO_U64: + case XdrSCValType.SCV_U64: decoded.u64 = XdrUint64.decode(stream); break; - case XdrSCObjectType.SCO_I64: + case XdrSCValType.SCV_I64: decoded.i64 = XdrInt64.decode(stream); break; - case XdrSCObjectType.SCO_U128: + case XdrSCValType.SCV_TIMEPOINT: + decoded.timepoint = XdrUint64.decode(stream); + break; + case XdrSCValType.SCV_DURATION: + decoded.duration = XdrUint64.decode(stream); + break; + case XdrSCValType.SCV_U128: decoded.u128 = XdrInt128Parts.decode(stream); break; - case XdrSCObjectType.SCO_I128: + case XdrSCValType.SCV_I128: decoded.i128 = XdrInt128Parts.decode(stream); break; - case XdrSCObjectType.SCO_BYTES: - decoded.bin = XdrDataValue.decode(stream); + case XdrSCValType.SCV_U256: + decoded.u256 = XdrUint256.decode(stream); + break; + case XdrSCValType.SCV_I256: + decoded.i256 = XdrUint256.decode(stream); break; - case XdrSCObjectType.SCO_CONTRACT_CODE: - decoded.contractCode = XdrSCContractCode.decode(stream); + case XdrSCValType.SCV_BYTES: + decoded.bytes = XdrDataValue.decode(stream); + break; + case XdrSCValType.SCV_STRING: + decoded.str = stream.readString(); + break; + case XdrSCValType.SCV_SYMBOL: + decoded.sym = stream.readString(); + break; + case XdrSCValType.SCV_VEC: + int vecPresent = stream.readInt(); + if (vecPresent != 0) { + int vecSize = stream.readInt(); + decoded.vec = List.empty(growable: true); + for (int i = 0; i < vecSize; i++) { + decoded.vec!.add(XdrSCVal.decode(stream)); + } + } + break; + case XdrSCValType.SCV_MAP: + int mapPresent = stream.readInt(); + if (mapPresent != 0) { + int mapSize = stream.readInt(); + decoded.map = List.empty(growable: true); + for (int i = 0; i < mapSize; i++) { + decoded.map!.add(XdrSCMapEntry.decode(stream)); + } + } break; - case XdrSCObjectType.SCO_ADDRESS: + case XdrSCValType.SCV_CONTRACT_EXECUTABLE: + decoded.exec = XdrSCContractExecutable.decode(stream); + break; + case XdrSCValType.SCV_ADDRESS: decoded.address = XdrSCAddress.decode(stream); break; - case XdrSCObjectType.SCO_NONCE_KEY: - decoded.nonceKey = XdrSCAddress.decode(stream); + case XdrSCValType.SCV_LEDGER_KEY_CONTRACT_EXECUTABLE: + break; + case XdrSCValType.SCV_LEDGER_KEY_NONCE: + decoded.nonce_key = XdrSCNonceKey.decode(stream); break; } return decoded; } - static XdrSCObject forVec(List value) { - XdrSCObject val = XdrSCObject(XdrSCObjectType.SCO_VEC); - val.vec = value; + static XdrSCVal forBool(bool value) { + XdrSCVal val = XdrSCVal(XdrSCValType.SCV_BOOL); + val.b = value; return val; } - static XdrSCObject forMap(List value) { - XdrSCObject val = XdrSCObject(XdrSCObjectType.SCO_MAP); - val.map = value; - return val; + static XdrSCVal forVoid() { + return XdrSCVal(XdrSCValType.SCV_VOID); } - static XdrSCObject forU64(int value) { - XdrSCObject val = XdrSCObject(XdrSCObjectType.SCO_U64); - val.u64 = XdrUint64(value); + static XdrSCVal forStatus(XdrSCStatus value) { + XdrSCVal val = XdrSCVal(XdrSCValType.SCV_STATUS); + val.error = value; return val; } - static XdrSCObject forI64(int value) { - XdrSCObject val = XdrSCObject(XdrSCObjectType.SCO_I64); - val.i64 = XdrInt64(value); + static XdrSCVal forU32(int value) { + XdrSCVal val = XdrSCVal(XdrSCValType.SCV_U32); + val.u32 = XdrUint32(value); return val; } - static XdrSCObject forU128(XdrInt128Parts value) { - XdrSCObject val = XdrSCObject(XdrSCObjectType.SCO_U128); - val.u128 = value; + static XdrSCVal forI32(int value) { + XdrSCVal val = XdrSCVal(XdrSCValType.SCV_I32); + val.i32 = XdrInt32(value); return val; } - static XdrSCObject forI128(XdrInt128Parts value) { - XdrSCObject val = XdrSCObject(XdrSCObjectType.SCO_I128); - val.i128 = value; + static XdrSCVal forU64(int value) { + XdrSCVal val = XdrSCVal(XdrSCValType.SCV_U64); + val.u64 = XdrUint64(value); return val; } - static XdrSCObject forBytes(Uint8List value) { - XdrSCObject val = XdrSCObject(XdrSCObjectType.SCO_BYTES); - val.bin = XdrDataValue(value); + static XdrSCVal forI64(int value) { + XdrSCVal val = XdrSCVal(XdrSCValType.SCV_I64); + val.i64 = XdrInt64(value); return val; } - static XdrSCObject forContractCode(XdrSCContractCode value) { - XdrSCObject val = XdrSCObject(XdrSCObjectType.SCO_CONTRACT_CODE); - val.contractCode = value; + static XdrSCVal forTimepoint(int value) { + XdrSCVal val = XdrSCVal(XdrSCValType.SCV_TIMEPOINT); + val.timepoint = XdrUint64(value); return val; } - static XdrSCObject forAddress(XdrSCAddress value) { - XdrSCObject val = XdrSCObject(XdrSCObjectType.SCO_ADDRESS); - val.address = value; + static XdrSCVal forDuration(int value) { + XdrSCVal val = XdrSCVal(XdrSCValType.SCV_DURATION); + val.duration = XdrUint64(value); return val; } - static XdrSCObject forNonceKey(XdrSCAddress value) { - XdrSCObject val = XdrSCObject(XdrSCObjectType.SCO_NONCE_KEY); - val.nonceKey = value; + static XdrSCVal forU128(XdrInt128Parts value) { + XdrSCVal val = XdrSCVal(XdrSCValType.SCV_U128); + val.u128 = value; return val; } - static XdrSCObject fromBase64EncodedString(String base64Encoded) { - Uint8List bytes = base64Decode(base64Encoded); - return XdrSCObject.decode(XdrDataInputStream(bytes)); - } -} - -class XdrSCVal { - XdrSCVal(this._type); - XdrSCValType _type; - XdrSCValType get discriminant => this._type; - set discriminant(XdrSCValType value) => this._type = value; - - XdrInt64? _u63; - XdrInt64? get u63 => this._u63; - set u63(XdrInt64? value) => this._u63 = value; - - XdrUint32? _u32; - XdrUint32? get u32 => this._u32; - set u32(XdrUint32? value) => this._u32 = value; - - XdrInt32? _i32; - XdrInt32? get i32 => this._i32; - set i32(XdrInt32? value) => this._i32 = value; - - XdrSCStatic? _ic; - XdrSCStatic? get ic => this._ic; - set ic(XdrSCStatic? value) => this._ic = value; - - XdrSCObject? _obj; - XdrSCObject? get obj => this._obj; - set obj(XdrSCObject? value) => this._obj = value; - - String? _sym; - String? get sym => this._sym; - set sym(String? value) => this._sym = value; - - XdrUint64? _bits; - XdrUint64? get bits => this._bits; - set bits(XdrUint64? value) => this._bits = value; - - XdrSCStatus? _status; - XdrSCStatus? get status => this._status; - set status(XdrSCStatus? value) => this._status = value; - - static void encode(XdrDataOutputStream stream, XdrSCVal encoded) { - stream.writeInt(encoded.discriminant.value); - switch (encoded.discriminant) { - case XdrSCValType.SCV_U63: - XdrInt64.encode(stream, encoded.u63!); - break; - case XdrSCValType.SCV_U32: - XdrUint32.encode(stream, encoded.u32!); - break; - case XdrSCValType.SCV_I32: - XdrInt32.encode(stream, encoded.i32!); - break; - case XdrSCValType.SCV_STATIC: - XdrSCStatic.encode(stream, encoded.ic!); - break; - case XdrSCValType.SCV_OBJECT: - if (encoded.obj != null) { - stream.writeInt(1); - XdrSCObject.encode(stream, encoded.obj!); - } else { - stream.writeInt(0); - } - break; - case XdrSCValType.SCV_SYMBOL: - stream.writeString(encoded.sym!); - break; - case XdrSCValType.SCV_BITSET: - XdrUint64.encode(stream, encoded.bits!); - break; - case XdrSCValType.SCV_STATUS: - XdrSCStatus.encode(stream, encoded.status!); - break; - } - } - - static XdrSCVal decode(XdrDataInputStream stream) { - XdrSCVal decoded = XdrSCVal(XdrSCValType.decode(stream)); - switch (decoded.discriminant) { - case XdrSCValType.SCV_U63: - decoded.u63 = XdrInt64.decode(stream); - break; - case XdrSCValType.SCV_U32: - decoded.u32 = XdrUint32.decode(stream); - break; - case XdrSCValType.SCV_I32: - decoded.i32 = XdrInt32.decode(stream); - break; - case XdrSCValType.SCV_STATIC: - decoded.ic = XdrSCStatic.decode(stream); - break; - case XdrSCValType.SCV_OBJECT: - int objPresent = stream.readInt(); - if (objPresent != 0) { - decoded.obj = XdrSCObject.decode(stream); - } - break; - case XdrSCValType.SCV_SYMBOL: - decoded.sym = stream.readString(); - break; - case XdrSCValType.SCV_BITSET: - decoded.bits = XdrUint64.decode(stream); - break; - case XdrSCValType.SCV_STATUS: - decoded.status = XdrSCStatus.decode(stream); - break; - } - return decoded; - } - - List? getVec() { - return this.obj?.vec; - } - - List? getMap() { - return this.obj?.map; - } - - int? getU64() { - return this.obj?.u64?.uint64; - } - - int? getI64() { - return this.obj?.i64?.int64; - } - - XdrInt128Parts? getU128() { - return this.obj?.u128; - } - - XdrInt128Parts? getI128() { - return this.obj?.i128; - } - - Uint8List? getBytes() { - return this.obj?.bin?.dataValue; - } - - XdrSCContractCode? getContractCode() { - return this.obj?.contractCode; - } - - XdrSCAddress? getAddress() { - return this.obj?.address; + static XdrSCVal forU128Parts(int lo, int hi) { + XdrSCVal val = XdrSCVal(XdrSCValType.SCV_U128); + val.u128 = XdrInt128Parts(XdrUint64(lo), XdrUint64(hi)); + return val; } - XdrSCAddress? getNonceKey() { - return this.obj?.nonceKey; + static XdrSCVal forI128(XdrInt128Parts value) { + XdrSCVal val = XdrSCVal(XdrSCValType.SCV_I128); + val.i128 = value; + return val; } - static XdrSCVal forU63(int value) { - XdrSCVal val = XdrSCVal(XdrSCValType.SCV_U63); - val.u63 = XdrInt64(value); + static XdrSCVal forI128Parts(int lo, int hi) { + XdrSCVal val = XdrSCVal(XdrSCValType.SCV_I128); + val.i128 = XdrInt128Parts(XdrUint64(lo), XdrUint64(hi)); return val; } - static XdrSCVal forU32(int value) { - XdrSCVal val = XdrSCVal(XdrSCValType.SCV_U32); - val.u32 = XdrUint32(value); + static XdrSCVal forU256(XdrUint256 value) { + XdrSCVal val = XdrSCVal(XdrSCValType.SCV_U256); + val.u256 = value; return val; } - static XdrSCVal forI32(int value) { - XdrSCVal val = XdrSCVal(XdrSCValType.SCV_I32); - val.i32 = XdrInt32(value); + static XdrSCVal forI256(XdrUint256 value) { + XdrSCVal val = XdrSCVal(XdrSCValType.SCV_I256); + val.i256 = value; return val; } - static XdrSCVal forStatic(XdrSCStatic value) { - XdrSCVal val = XdrSCVal(XdrSCValType.SCV_STATIC); - val.ic = value; + static XdrSCVal forBytes(Uint8List value) { + XdrSCVal val = XdrSCVal(XdrSCValType.SCV_BYTES); + val.bytes = XdrDataValue(value); return val; } - static XdrSCVal forObject(XdrSCObject value) { - XdrSCVal val = XdrSCVal(XdrSCValType.SCV_OBJECT); - val.obj = value; + static XdrSCVal forString(String str) { + XdrSCVal val = XdrSCVal(XdrSCValType.SCV_STRING); + val.str = str; return val; } @@ -1277,26 +1237,48 @@ class XdrSCVal { return val; } - static XdrSCVal forBitset(int value) { - XdrSCVal val = XdrSCVal(XdrSCValType.SCV_BITSET); - val.bits = XdrUint64(value); + static XdrSCVal forVec(List value) { + XdrSCVal val = XdrSCVal(XdrSCValType.SCV_VEC); + val.vec = value; return val; } - static XdrSCVal forStatus(XdrSCStatus value) { - XdrSCVal val = XdrSCVal(XdrSCValType.SCV_STATUS); - val.status = value; + static XdrSCVal forMap(List value) { + XdrSCVal val = XdrSCVal(XdrSCValType.SCV_MAP); + val.map = value; + return val; + } + + static XdrSCVal forAddress(XdrSCAddress address) { + XdrSCVal val = XdrSCVal(XdrSCValType.SCV_ADDRESS); + val.address = address; return val; } static XdrSCVal forAccountAddress(String accountId) { final address = Address.forAccountId(accountId); - return address.toXdrSCVal(); + XdrSCVal val = XdrSCVal(XdrSCValType.SCV_ADDRESS); + val.address = address.toXdr(); + return val; } static XdrSCVal forContractAddress(String contractId) { final address = Address.forContractId(contractId); - return address.toXdrSCVal(); + XdrSCVal val = XdrSCVal(XdrSCValType.SCV_ADDRESS); + val.address = address.toXdr(); + return val; + } + + static XdrSCVal forNonceKey(XdrSCNonceKey nonceKey) { + XdrSCVal val = XdrSCVal(XdrSCValType.SCV_LEDGER_KEY_NONCE); + val.nonce_key = nonceKey; + return val; + } + + static XdrSCVal forNonceKeyWithAddress(Address address) { + XdrSCVal val = XdrSCVal(XdrSCValType.SCV_LEDGER_KEY_NONCE); + val.nonce_key = XdrSCNonceKey(address.toXdr()); + return val; } String toBase64EncodedXdrString() { @@ -1536,19 +1518,23 @@ class XdrSCSpecType { static const SC_SPEC_TYPE_VAL = const XdrSCSpecType._internal(0); // Types with no parameters. - static const SC_SPEC_TYPE_U32 = const XdrSCSpecType._internal(1); - static const SC_SPEC_TYPE_I32 = const XdrSCSpecType._internal(2); - static const SC_SPEC_TYPE_U64 = const XdrSCSpecType._internal(3); - static const SC_SPEC_TYPE_I64 = const XdrSCSpecType._internal(4); - static const SC_SPEC_TYPE_U128 = const XdrSCSpecType._internal(5); - static const SC_SPEC_TYPE_I128 = const XdrSCSpecType._internal(6); - static const SC_SPEC_TYPE_BOOL = const XdrSCSpecType._internal(7); - static const SC_SPEC_TYPE_SYMBOL = const XdrSCSpecType._internal(8); - static const SC_SPEC_TYPE_BITSET = const XdrSCSpecType._internal(9); - static const SC_SPEC_TYPE_STATUS = const XdrSCSpecType._internal(10); - static const SC_SPEC_TYPE_BYTES = const XdrSCSpecType._internal(11); - static const SC_SPEC_TYPE_INVOKER = const XdrSCSpecType._internal(12); - static const SC_SPEC_TYPE_ADDRESS = const XdrSCSpecType._internal(13); + static const SC_SPEC_TYPE_BOOL = const XdrSCSpecType._internal(1); + static const SC_SPEC_TYPE_VOID = const XdrSCSpecType._internal(2); + static const SC_SPEC_TYPE_STATUS = const XdrSCSpecType._internal(3); + static const SC_SPEC_TYPE_U32 = const XdrSCSpecType._internal(4); + static const SC_SPEC_TYPE_I32 = const XdrSCSpecType._internal(5); + static const SC_SPEC_TYPE_U64 = const XdrSCSpecType._internal(6); + static const SC_SPEC_TYPE_I64 = const XdrSCSpecType._internal(7); + static const SC_SPEC_TYPE_TIMEPOINT = const XdrSCSpecType._internal(8); + static const SC_SPEC_TYPE_DURATION = const XdrSCSpecType._internal(9); + static const SC_SPEC_TYPE_U128 = const XdrSCSpecType._internal(10); + static const SC_SPEC_TYPE_I128 = const XdrSCSpecType._internal(11); + static const SC_SPEC_TYPE_U256 = const XdrSCSpecType._internal(12); + static const SC_SPEC_TYPE_I256 = const XdrSCSpecType._internal(13); + static const SC_SPEC_TYPE_BYTES = const XdrSCSpecType._internal(14); + static const SC_SPEC_TYPE_STRING = const XdrSCSpecType._internal(16); + static const SC_SPEC_TYPE_SYMBOL = const XdrSCSpecType._internal(17); + static const SC_SPEC_TYPE_ADDRESS = const XdrSCSpecType._internal(19); // Types with parameters. static const SC_SPEC_TYPE_OPTION = const XdrSCSpecType._internal(1000); @@ -1568,30 +1554,38 @@ class XdrSCSpecType { case 0: return SC_SPEC_TYPE_VAL; case 1: - return SC_SPEC_TYPE_U32; + return SC_SPEC_TYPE_BOOL; case 2: - return SC_SPEC_TYPE_I32; + return SC_SPEC_TYPE_VOID; case 3: - return SC_SPEC_TYPE_U64; + return SC_SPEC_TYPE_STATUS; case 4: - return SC_SPEC_TYPE_I64; + return SC_SPEC_TYPE_U32; case 5: - return SC_SPEC_TYPE_U128; + return SC_SPEC_TYPE_I32; case 6: - return SC_SPEC_TYPE_I128; + return SC_SPEC_TYPE_U64; case 7: - return SC_SPEC_TYPE_BOOL; + return SC_SPEC_TYPE_I64; case 8: - return SC_SPEC_TYPE_SYMBOL; + return SC_SPEC_TYPE_TIMEPOINT; case 9: - return SC_SPEC_TYPE_BITSET; + return SC_SPEC_TYPE_DURATION; case 10: - return SC_SPEC_TYPE_STATUS; + return SC_SPEC_TYPE_U128; case 11: - return SC_SPEC_TYPE_BYTES; + return SC_SPEC_TYPE_I128; case 12: - return SC_SPEC_TYPE_INVOKER; + return SC_SPEC_TYPE_U256; case 13: + return SC_SPEC_TYPE_I256; + case 14: + return SC_SPEC_TYPE_BYTES; + case 16: + return SC_SPEC_TYPE_STRING; + case 17: + return SC_SPEC_TYPE_SYMBOL; + case 19: return SC_SPEC_TYPE_ADDRESS; case 1000: return SC_SPEC_TYPE_OPTION; @@ -1661,18 +1655,22 @@ class XdrSCSpecTypeDef { stream.writeInt(encoded.discriminant.value); switch (encoded.discriminant) { case XdrSCSpecType.SC_SPEC_TYPE_VAL: + case XdrSCSpecType.SC_SPEC_TYPE_BOOL: + case XdrSCSpecType.SC_SPEC_TYPE_VOID: + case XdrSCSpecType.SC_SPEC_TYPE_STATUS: + case XdrSCSpecType.SC_SPEC_TYPE_U32: + case XdrSCSpecType.SC_SPEC_TYPE_I32: case XdrSCSpecType.SC_SPEC_TYPE_U64: case XdrSCSpecType.SC_SPEC_TYPE_I64: + case XdrSCSpecType.SC_SPEC_TYPE_TIMEPOINT: + case XdrSCSpecType.SC_SPEC_TYPE_DURATION: case XdrSCSpecType.SC_SPEC_TYPE_U128: case XdrSCSpecType.SC_SPEC_TYPE_I128: - case XdrSCSpecType.SC_SPEC_TYPE_U32: - case XdrSCSpecType.SC_SPEC_TYPE_I32: - case XdrSCSpecType.SC_SPEC_TYPE_BOOL: - case XdrSCSpecType.SC_SPEC_TYPE_SYMBOL: - case XdrSCSpecType.SC_SPEC_TYPE_BITSET: - case XdrSCSpecType.SC_SPEC_TYPE_STATUS: + case XdrSCSpecType.SC_SPEC_TYPE_U256: + case XdrSCSpecType.SC_SPEC_TYPE_I256: case XdrSCSpecType.SC_SPEC_TYPE_BYTES: - case XdrSCSpecType.SC_SPEC_TYPE_INVOKER: + case XdrSCSpecType.SC_SPEC_TYPE_STRING: + case XdrSCSpecType.SC_SPEC_TYPE_SYMBOL: case XdrSCSpecType.SC_SPEC_TYPE_ADDRESS: break; case XdrSCSpecType.SC_SPEC_TYPE_OPTION: @@ -1706,18 +1704,22 @@ class XdrSCSpecTypeDef { XdrSCSpecTypeDef decoded = XdrSCSpecTypeDef(XdrSCSpecType.decode(stream)); switch (decoded.discriminant) { case XdrSCSpecType.SC_SPEC_TYPE_VAL: + case XdrSCSpecType.SC_SPEC_TYPE_BOOL: + case XdrSCSpecType.SC_SPEC_TYPE_VOID: + case XdrSCSpecType.SC_SPEC_TYPE_STATUS: + case XdrSCSpecType.SC_SPEC_TYPE_U32: + case XdrSCSpecType.SC_SPEC_TYPE_I32: case XdrSCSpecType.SC_SPEC_TYPE_U64: case XdrSCSpecType.SC_SPEC_TYPE_I64: + case XdrSCSpecType.SC_SPEC_TYPE_TIMEPOINT: + case XdrSCSpecType.SC_SPEC_TYPE_DURATION: case XdrSCSpecType.SC_SPEC_TYPE_U128: case XdrSCSpecType.SC_SPEC_TYPE_I128: - case XdrSCSpecType.SC_SPEC_TYPE_U32: - case XdrSCSpecType.SC_SPEC_TYPE_I32: - case XdrSCSpecType.SC_SPEC_TYPE_BOOL: - case XdrSCSpecType.SC_SPEC_TYPE_SYMBOL: - case XdrSCSpecType.SC_SPEC_TYPE_BITSET: - case XdrSCSpecType.SC_SPEC_TYPE_STATUS: + case XdrSCSpecType.SC_SPEC_TYPE_U256: + case XdrSCSpecType.SC_SPEC_TYPE_I256: case XdrSCSpecType.SC_SPEC_TYPE_BYTES: - case XdrSCSpecType.SC_SPEC_TYPE_INVOKER: + case XdrSCSpecType.SC_SPEC_TYPE_STRING: + case XdrSCSpecType.SC_SPEC_TYPE_SYMBOL: case XdrSCSpecType.SC_SPEC_TYPE_ADDRESS: break; case XdrSCSpecType.SC_SPEC_TYPE_OPTION: @@ -1880,11 +1882,6 @@ class XdrSCSpecUDTUnionCaseVoidV0 { for (int i = 0; i < namesSize; i++) { name.add(stream.readString()); } - XdrSCSpecTypeDef? typ; - int typePresent = stream.readInt(); - if (typePresent != 0) { - typ = XdrSCSpecTypeDef.decode(stream); - } return XdrSCSpecUDTUnionCaseVoidV0(doc, name); } } @@ -2689,21 +2686,21 @@ class XdrCreateContractArgs { XdrContractID get contractID => this._contractID; set contractID(XdrContractID value) => this._contractID = value; - XdrSCContractCode _source; - XdrSCContractCode get source => this._source; - set source(XdrSCContractCode value) => this._source = value; + XdrSCContractExecutable _source; + XdrSCContractExecutable get source => this._source; + set source(XdrSCContractExecutable value) => this._source = value; XdrCreateContractArgs(this._contractID, this._source); static void encode( XdrDataOutputStream stream, XdrCreateContractArgs encoded) { XdrContractID.encode(stream, encoded.contractID); - XdrSCContractCode.encode(stream, encoded.source); + XdrSCContractExecutable.encode(stream, encoded.source); } static XdrCreateContractArgs decode(XdrDataInputStream stream) { return XdrCreateContractArgs( - XdrContractID.decode(stream), XdrSCContractCode.decode(stream)); + XdrContractID.decode(stream), XdrSCContractExecutable.decode(stream)); } } diff --git a/lib/src/xdr/xdr_transaction.dart b/lib/src/xdr/xdr_transaction.dart index 38a9ff9..2b7fda5 100644 --- a/lib/src/xdr/xdr_transaction.dart +++ b/lib/src/xdr/xdr_transaction.dart @@ -558,7 +558,11 @@ class XdrOperationEvents { List get events => this._events; set events(List value) => this._events = value; - XdrOperationEvents(this._events); + /*List _diagnosticEvents; + List get diagnosticEvents => this._diagnosticEvents; + set diagnosticEvents(List value) => this._diagnosticEvents = value;*/ + + XdrOperationEvents(this._events); //, this._diagnosticEvents); static void encode(XdrDataOutputStream stream, XdrOperationEvents encoded) { int eventsSize = encoded.events.length; @@ -566,6 +570,12 @@ class XdrOperationEvents { for (int i = 0; i < eventsSize; i++) { XdrContractEvent.encode(stream, encoded.events[i]); } + + /*eventsSize = encoded.diagnosticEvents.length; + stream.writeInt(eventsSize); + for (int i = 0; i < eventsSize; i++) { + XdrOperationDiagnosticEvents.encode(stream, encoded.diagnosticEvents[i]); + }*/ } static XdrOperationEvents decode(XdrDataInputStream stream) { @@ -576,7 +586,14 @@ class XdrOperationEvents { events.add(XdrContractEvent.decode(stream)); } - return XdrOperationEvents(events); + /*eventsSize = stream.readInt(); + List diagnosticEvents = + List.empty(growable: true); + for (int i = 0; i < eventsSize; i++) { + diagnosticEvents.add(XdrOperationDiagnosticEvents.decode(stream)); + }*/ + + return XdrOperationEvents(events);//, diagnosticEvents); } } @@ -677,6 +694,8 @@ class XdrContractEventType { const XdrContractEventType._internal(0); static const CONTRACT_EVENT_TYPE_CONTRACT = const XdrContractEventType._internal(1); + static const CONTRACT_EVENT_TYPE_DIAGNOSTIC = + const XdrContractEventType._internal(2); static XdrContractEventType decode(XdrDataInputStream stream) { int value = stream.readInt(); @@ -685,6 +704,8 @@ class XdrContractEventType { return CONTRACT_EVENT_TYPE_SYSTEM; case 1: return CONTRACT_EVENT_TYPE_CONTRACT; + case 2: + return CONTRACT_EVENT_TYPE_DIAGNOSTIC; default: throw Exception("Unknown enum value: $value"); } @@ -695,6 +716,54 @@ class XdrContractEventType { } } +class XdrDiagnosticEvent { + bool _inSuccessfulContractCall; + bool get inSuccessfulContractCall => this._inSuccessfulContractCall; + set ext(bool value) => this._inSuccessfulContractCall = value; + + XdrContractEvent _event; + XdrContractEvent get event => this._event; + set hash(XdrContractEvent value) => this._event = value; + + + XdrDiagnosticEvent(this._inSuccessfulContractCall, this._event); + + static void encode(XdrDataOutputStream stream, XdrDiagnosticEvent encoded) { + stream.writeBoolean(encoded.inSuccessfulContractCall); + XdrContractEvent.encode(stream, encoded.event); + } + + static XdrDiagnosticEvent decode(XdrDataInputStream stream) { + return XdrDiagnosticEvent(stream.readBoolean(), XdrContractEvent.decode(stream)); + } +} + +class XdrOperationDiagnosticEvents { + List _events; + List get events => this._events; + set events(List value) => this._events = value; + + XdrOperationDiagnosticEvents(this._events); + + static void encode( + XdrDataOutputStream stream, XdrOperationDiagnosticEvents encoded) { + int eventsSize = encoded.events.length; + stream.writeInt(eventsSize); + for (int i = 0; i < eventsSize; i++) { + XdrDiagnosticEvent.encode(stream, encoded.events[i]); + } + } + + static XdrOperationDiagnosticEvents decode(XdrDataInputStream stream) { + int eventsSize = stream.readInt(); + List events = List.empty(growable: true); + for (int i = 0; i < eventsSize; i++) { + events.add(XdrDiagnosticEvent.decode(stream)); + } + return XdrOperationDiagnosticEvents(events); + } +} + class XdrContractEvent { XdrExtensionPoint _ext; XdrExtensionPoint get ext => this._ext; @@ -763,7 +832,7 @@ class XdrContractEventBody { XdrContractEventBody decoded = XdrContractEventBody(stream.readInt()); switch (decoded.discriminant) { case 0: - decoded.v0 = decoded.v0; + decoded.v0 = XdrContractEventBodyV0.decode(stream); break; } return decoded; diff --git a/pubspec.yaml b/pubspec.yaml index 6ae87c2..43b240e 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,6 +1,6 @@ name: stellar_flutter_sdk description: A stellar blockchain sdk that query's horizon, build, signs and submits transactions to the stellar network. -version: 1.5.2 +version: 1.5.3 homepage: https://github.com/Soneso/stellar_flutter_sdk environment: diff --git a/soroban.md b/soroban.md index 6bf156b..c3a4dfa 100644 --- a/soroban.md +++ b/soroban.md @@ -17,14 +17,14 @@ Soroban-RPC can be simply described as a “live network gateway for Soroban”. You can install your own instance of a Soroban-RPC Server as described [here](https://soroban.stellar.org/docs/tutorials/deploy-to-futurenet). Alternatively, you can use a public remote instance for testing. -The Soroban-RPC API is described in this early stage [design document](https://docs.google.com/document/d/1TZUDgo_3zPz7TiPMMHVW_mtogjLyPL0plvzGMsxSz6A). +The Soroban-RPC API is described [here](https://soroban.stellar.org/api/). #### Initialize SorobanServer Provide the url to the endpoint of the Soroban-RPC server to connect to: ```dart -SorobanServer sorobanServer = SorobanServer("https://horizon-futurenet.stellar.cash/soroban/rpc"); +SorobanServer sorobanServer = SorobanServer("https://rpc-futurenet.stellar.org:443"); ``` Set the experimental flag to true. Otherwise it will not work. @@ -52,11 +52,10 @@ String accountId = accountKeyPair.accountId; await FuturenetFriendBot.fundTestAccount(accountId); ``` -Next you can fetch current information about your Stellar account using the ```SorobanServer```: +Next you can fetch current information about your Stellar account using the SDK: ```dart -GetAccountResponse accountResponse = await sorobanServer.getAccount(accountId); -print("Sequence: ${accountResponse.sequence}"); +AccountResponse submitter = await sdk.accounts.account(submitterId); ``` @@ -109,27 +108,27 @@ On success, the response contains the id and status of the transaction: ```dart if (sendResponse.error == null) { - print("Transaction Id: ${sendResponse.transactionId}"); - print("Status: ${sendResponse.status}"); // pending + print("Transaction Id: ${sendResponse.hash}"); + print("Status: ${sendResponse.status}"); // PENDING } ``` -The status is ```pending``` because the transaction needs to be processed by the Soroban-RPC Server first. Therefore we need to wait a bit and poll for the current transaction status by using the ```getTransactionStatus``` request: +The status is ```pending``` because the transaction needs to be processed by the Soroban-RPC Server first. Therefore we need to wait a bit and poll for the current transaction status by using the ```getTransaction``` request: ```dart -// Fetch transaction status -GetTransactionStatusResponse statusResponse = - await sorobanServer.getTransactionStatus(transactionId); +// Fetch transaction +GetTransactionResponse transactionResponse = + await sorobanServer.getTransaction(transactionId); -String status = statusResponse.status; +String status = transactionResponse.status; -if (SorobanServer.TRANSACTION_STATUS_PENDING == status) { +if (GetTransactionResponse.STATUS_NOT_FOUND == status) { // try again later ... -} else if (SorobanServer.TRANSACTION_STATUS_SUCCESS == status) { +} else if (GetTransactionResponse.STATUS_SUCCESS == status) { // continue with creating the contract ... - String contractWasmId = statusResponse.getWasmId(); + String contractWasmId = transactionResponse.getWasmId(); // ... -} else if (SorobanServer.TRANSACTION_STATUS_ERROR == status) { +} else if (GetTransactionResponse.STATUS_FAILED == status) { // handle error ... } ``` @@ -160,7 +159,7 @@ SendTransactionResponse sendResponse = await sorobanServer.sendTransaction(transaction); if (sendResponse.error == null) { - print("Transaction Id: ${sendResponse.transactionId}"); + print("Transaction Id: ${sendResponse.hash}"); print("Status: ${sendResponse.status}"); // pending } ``` @@ -168,15 +167,15 @@ if (sendResponse.error == null) { As you can see, we use the ```wasmId``` to create the operation and the transaction for creating the contract. After simulating, we obtain the footprint to be set in the transaction. Next, sign the transaction and send it to the Soroban-RPC Server. The transaction status will be "pending", so we need to wait a bit and poll for the current status: ```dart -// Fetch transaction status -GetTransactionStatusResponse statusResponse = - await sorobanServer.getTransactionStatus(transactionId); +// Fetch transaction +GetTransactionResponse transactionResponse = + await sorobanServer.getTransaction(transactionId); -String status = statusResponse.status; +String status = transactionResponse.status; -if (SorobanServer.TRANSACTION_STATUS_SUCCESS == status) { +if (GetTransactionResponse.STATUS_SUCCESS == status) { // contract successfully deployed! - contractId = statusResponse.getContractId(); + contractId = transactionResponse.getContractId(); } ``` @@ -204,13 +203,13 @@ First let's have a look to a simple (hello word) contract created with the [Asse *Hello Word contract AssemblyScript code:* ```typescript -import {SymbolVal, VectorObject, fromSymbolStr} from 'as-soroban-sdk/lib/value'; +import {Symbol, VecObject, fromSmallSymbolStr} from 'as-soroban-sdk/lib/value'; import {Vec} from 'as-soroban-sdk/lib/vec'; -export function hello(to: SymbolVal): VectorObject { +export function hello(to: Symbol): VecObject { let vec = new Vec(); - vec.pushFront(fromSymbolStr("Hello")); + vec.pushFront(fromSmallSymbolStr("Hello")); vec.pushBack(to); return vec.getHostObject(); @@ -269,7 +268,7 @@ On success, the response contains the id and status of the transaction: ```dart if (sendResponse.error == null) { - print("Transaction Id: ${sendResponse.transactionId}"); + print("Transaction Id: ${sendResponse.hash}"); print("Status: ${sendResponse.status}"); // pending } ``` @@ -277,18 +276,18 @@ if (sendResponse.error == null) { The status is ```pending``` because the transaction needs to be processed by the Soroban-RPC Server first. Therefore we need to wait a bit and poll for the current transaction status by using the ```getTransactionStatus``` request: ```dart -// Fetch transaction status -GetTransactionStatusResponse statusResponse = - await sorobanServer.getTransactionStatus(transactionId); +// Fetch transaction +GetTransactionResponse transactionResponse = + await sorobanServer.getTransaction(transactionId); -String status = statusResponse.status; +String status = transactionResponse.status; -if (SorobanServer.TRANSACTION_STATUS_PENDING == status) { +if (GetTransactionResponse.STATUS_NOT_FOUND == status) { // try again later ... -} else if (SorobanServer.TRANSACTION_STATUS_SUCCESS == status) { +} else if (GetTransactionResponse.STATUS_SUCCESS == status) { // success // ... -} else if (SorobanServer.TRANSACTION_STATUS_ERROR == status) { +} else if (GetTransactionResponse.STATUS_FAILED == status) { // handle error ... } ``` @@ -296,15 +295,13 @@ if (SorobanServer.TRANSACTION_STATUS_PENDING == status) { If the transaction was successful, the status response contains the result: ```dart -List res = statusResponse.results; - -// The result is in the first entry -XdrSCVal? resVal = statusResponse.getFirstValue(); +// Get the result value +XdrSCVal resVal = transactionResponse.getResultValue()!; // Extract the Vector -List? vec = resVal?.getVec(); +List? vec = resValO.vec; - // Print result +// Print result if (vec != null && vec.length > 1) { print("[${vec[0].sym}, ${vec[1].sym}]"); // [Hello, friend] diff --git a/test/soroban_test.dart b/test/soroban_test.dart index 175d403..ea8665e 100644 --- a/test/soroban_test.dart +++ b/test/soroban_test.dart @@ -5,7 +5,7 @@ import 'package:stellar_flutter_sdk/stellar_flutter_sdk.dart'; void main() { SorobanServer sorobanServer = - SorobanServer("https://horizon-futurenet.stellar.cash/soroban/rpc"); + SorobanServer("https://rpc-futurenet.stellar.org:443"); StellarSDK sdk = StellarSDK.FUTURENET; @@ -27,48 +27,46 @@ void main() { setUp(() async { sorobanServer.enableLogging = true; sorobanServer.acknowledgeExperimental = true; - GetAccountResponse accountResponse = - await sorobanServer.getAccount(accountAId); - if (accountResponse.accountMissing) { + try { + await sdk.accounts.account(accountAId); + } catch(e) { await FuturenetFriendBot.fundTestAccount(accountAId); + await Future.delayed(const Duration(seconds: 3), () {}); } }); // poll until success or error - Future pollStatus(String transactionId) async { - var status = SorobanServer.TRANSACTION_STATUS_PENDING; - GetTransactionStatusResponse? statusResponse; - while (status == SorobanServer.TRANSACTION_STATUS_PENDING) { + Future pollStatus(String transactionId) async { + var status = GetTransactionResponse.STATUS_NOT_FOUND; + GetTransactionResponse? transactionResponse; + while (status == GetTransactionResponse.STATUS_NOT_FOUND) { await Future.delayed(const Duration(seconds: 3), () {}); - statusResponse = await sorobanServer.getTransactionStatus(transactionId); - assert(statusResponse.error == null); - status = statusResponse.status!; - if (status == SorobanServer.TRANSACTION_STATUS_ERROR) { - assert(statusResponse.resultError != null); - print(statusResponse.resultError?.message); + transactionResponse = await sorobanServer.getTransaction(transactionId); + assert(transactionResponse.error == null); + status = transactionResponse.status!; + if (status == GetTransactionResponse.STATUS_FAILED) { + assert(transactionResponse.resultXdr != null); assert(false); - } else if (status == SorobanServer.TRANSACTION_STATUS_SUCCESS) { - assert(statusResponse.results != null); - assert(statusResponse.results!.isNotEmpty); + } else if (status == GetTransactionResponse.STATUS_SUCCESS) { + assert(transactionResponse.resultXdr != null); } } - return statusResponse!; + return transactionResponse!; } group('all tests', () { + + /*test ('xdr decodings', () async { + String xdr = "AAAAAwAAAAIAAAADAAD1sQAAAAAAAAAAWXdcSHU5C/Bu5qRE++rvSdeHUdr38kVUzdEsPReEgX4AAAAXSHbjtAAA9aEAAAAKAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAACAAAAAAAAAAAAAAAAAAAAAwAAAAAAAPWuAAAAAGQxrkcAAAAAAAAAAQAA9bEAAAAAAAAAAFl3XEh1OQvwbuakRPvq70nXh1Ha9/JFVM3RLD0XhIF+AAAAF0h247QAAPWhAAAACwAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAAAAAAAAAAAAAAAAAMAAAAAAAD1sQAAAABkMa5WAAAAAAAAAAEAAAAIAAAAAAAA9bEAAAAGG2acwDagzGq2emlAwbPr6k869+GG23vH6SK5j2WTUwgAAAAPAAAACUFsbG93YW5jZQAAAAAAABEAAAABAAAAAQAAABMAAAAAAAAAAOflwkgNYeM2LcBebeaj/o6xqDEh1zvqtX5T/ZJEiqH0AAAAEQAAAAEAAAABAAAAEwAAAAGj2g9e2JOss0xmg++goT1WZ7WkPHD7I2v+QnxWoDlZswAAAAoAAAAAAAAAMgAAAAAAAAAAAAAAAAAAAAMAAPWtAAAABhtmnMA2oMxqtnppQMGz6+pPOvfhhtt7x+kiuY9lk1MIAAAADwAAAAdCYWxhbmNlAAAAABEAAAABAAAAAQAAABMAAAAAAAAAAOflwkgNYeM2LcBebeaj/o6xqDEh1zvqtX5T/ZJEiqH0AAAACgAACRhOcqAAAAAAAAAAAAAAAAAAAAAAAQAA9bEAAAAGG2acwDagzGq2emlAwbPr6k869+GG23vH6SK5j2WTUwgAAAAPAAAAB0JhbGFuY2UAAAAAEQAAAAEAAAACAAAAEwAAAAAAAAAA5+XCSA1h4zYtwF5t5qP+jrGoMSHXO+q1flP9kkSKofQAAAAKAAAJGE5ynEoAAAAAAAAAAAAAABMAAAAAAAAAAPfSbtgU1NVg5jMWJkzue8vHmCWoJc9pcQUd45tsFHtiAAAACgAAAAAAAAO2AAAAAAAAAAAAAAAAAAAAAAAA9bEAAAAGSeVl8h3vUlCiFaVCj2YQssGigfSM4/94ynRWto+OiIsAAAAPAAAACUFsbG93YW5jZQAAAAAAABEAAAABAAAAAQAAABMAAAAAAAAAAPfSbtgU1NVg5jMWJkzue8vHmCWoJc9pcQUd45tsFHtiAAAAEQAAAAEAAAABAAAAEwAAAAGj2g9e2JOss0xmg++goT1WZ7WkPHD7I2v+QnxWoDlZswAAAAoAAAAAAAAB9AAAAAAAAAAAAAAAAAAAAAMAAPWuAAAABknlZfId71JQohWlQo9mELLBooH0jOP/eMp0VraPjoiLAAAADwAAAAdCYWxhbmNlAAAAABEAAAABAAAAAQAAABMAAAAAAAAAAPfSbtgU1NVg5jMWJkzue8vHmCWoJc9pcQUd45tsFHtiAAAACgAACRhOcqAAAAAAAAAAAAAAAAAAAAAAAQAA9bEAAAAGSeVl8h3vUlCiFaVCj2YQssGigfSM4/94ynRWto+OiIsAAAAPAAAAB0JhbGFuY2UAAAAAEQAAAAEAAAACAAAAEwAAAAAAAAAA5+XCSA1h4zYtwF5t5qP+jrGoMSHXO+q1flP9kkSKofQAAAAKAAAAAAAAEZQAAAAAAAAAAAAAABMAAAAAAAAAAPfSbtgU1NVg5jMWJkzue8vHmCWoJc9pcQUd45tsFHtiAAAACgAACRhOco5sAAAAAAAAAAAAAAAAAAAAAAAA9bEAAAAGo9oPXtiTrLNMZoPvoKE9Vme1pDxw+yNr/kJ8VqA5WbMAAAAVAAAAAAAAAADn5cJIDWHjNi3AXm3mo/6OsagxIdc76rV+U/2SRIqh9AAAAAUAAAAAAAAAAQAAAAAAAAAAAAD1sQAAAAaj2g9e2JOss0xmg++goT1WZ7WkPHD7I2v+QnxWoDlZswAAABUAAAAAAAAAAPfSbtgU1NVg5jMWJkzue8vHmCWoJc9pcQUd45tsFHtiAAAABQAAAAAAAAABAAAAAAAAAAAAAAABAAAABAAAAAAAAAABG2acwDagzGq2emlAwbPr6k869+GG23vH6SK5j2WTUwgAAAABAAAAAAAAAAMAAAAPAAAACmluY3JfYWxsb3cAAAAAABMAAAAAAAAAAOflwkgNYeM2LcBebeaj/o6xqDEh1zvqtX5T/ZJEiqH0AAAAEwAAAAGj2g9e2JOss0xmg++goT1WZ7WkPHD7I2v+QnxWoDlZswAAAAoAAAAAAAAD6AAAAAAAAAAAAAAAAAAAAAEbZpzANqDMarZ6aUDBs+vqTzr34Ybbe8fpIrmPZZNTCAAAAAEAAAAAAAAAAwAAAA8AAAAIdHJhbnNmZXIAAAATAAAAAAAAAADn5cJIDWHjNi3AXm3mo/6OsagxIdc76rV+U/2SRIqh9AAAABMAAAAAAAAAAPfSbtgU1NVg5jMWJkzue8vHmCWoJc9pcQUd45tsFHtiAAAACgAAAAAAAAO2AAAAAAAAAAAAAAAAAAAAAUnlZfId71JQohWlQo9mELLBooH0jOP/eMp0VraPjoiLAAAAAQAAAAAAAAADAAAADwAAAAppbmNyX2FsbG93AAAAAAATAAAAAAAAAAD30m7YFNTVYOYzFiZM7nvLx5glqCXPaXEFHeObbBR7YgAAABMAAAABo9oPXtiTrLNMZoPvoKE9Vme1pDxw+yNr/kJ8VqA5WbMAAAAKAAAAAAAAE4gAAAAAAAAAAAAAAAAAAAABSeVl8h3vUlCiFaVCj2YQssGigfSM4/94ynRWto+OiIsAAAABAAAAAAAAAAMAAAAPAAAACHRyYW5zZmVyAAAAEwAAAAAAAAAA99Ju2BTU1WDmMxYmTO57y8eYJaglz2lxBR3jm2wUe2IAAAATAAAAAAAAAADn5cJIDWHjNi3AXm3mo/6OsagxIdc76rV+U/2SRIqh9AAAAAoAAAAAAAARlAAAAAAAAAAAAAAAAAAAAGQAAAAAAAAAAQAAAAAAAAAYAAAAAAAAAAEAAAAALrtR1OufPFeCQluY3RNdZOO4BP3dBqNwd32Dj9x4iNBmUK4+eyzIFNSvMWR8mU4ZulMN7OPeUfJc6ZWOl+LX7mMjP3pql2srtKOKTpJFo5wYAGZ3Av44lMVpPI0rQ0UHAAAAAA=="; + XdrTransactionMeta meta = XdrTransactionMeta.fromBase64EncodedXdrString(xdr); + assert(meta.v3?.txResult.result.results.first.tr?.invokeHostFunctionResult?.success != null); + });*/ + test('test server health ', () async { GetHealthResponse healthResponse = await sorobanServer.getHealth(); assert(GetHealthResponse.HEALTHY == healthResponse.status); }); - test('test account request', () async { - GetAccountResponse accountResponse = - await sorobanServer.getAccount(accountAId); - - assert(!accountResponse.isErrorResponse); - assert(accountAId == accountResponse.accountId); - }); - test('test network request', () async { GetNetworkResponse networkResponse = await sorobanServer.getNetwork(); @@ -81,7 +79,7 @@ void main() { test('test install contract', () async { // load account - GetAccountResponse accountA = await sorobanServer.getAccount(accountAId); + AccountResponse accountA = await sdk.accounts.account(accountAId); // load contract wasm file Uint8List contractCode = await Util.readFile(helloContractPath); @@ -119,33 +117,35 @@ void main() { SendTransactionResponse sendResponse = await sorobanServer.sendTransaction(transaction); assert(sendResponse.error == null); - assert(sendResponse.transactionId != null); + assert(sendResponse.hash != null); assert(sendResponse.status != null); - assert(sendResponse.resultError == null); + assert(sendResponse.status != SendTransactionResponse.STATUS_ERROR); - GetTransactionStatusResponse statusResponse = - await pollStatus(sendResponse.transactionId!); - if (statusResponse.status == SorobanServer.TRANSACTION_STATUS_SUCCESS) { - helloContractWasmId = statusResponse.getWasmId(); + GetTransactionResponse rpcTransactionResponse = + await pollStatus(sendResponse.hash!); + if (rpcTransactionResponse.status == GetTransactionResponse.STATUS_SUCCESS) { + helloContractWasmId = rpcTransactionResponse.getWasmId(); } assert(helloContractWasmId != null); // check horizon responses decoding TransactionResponse transactionResponse = - await sdk.transactions.transaction(sendResponse.transactionId!); + await sdk.transactions.transaction(sendResponse.hash!); assert(transactionResponse.operationCount == 1); assert(transactionEnvelopeXdr == transactionResponse.envelopeXdr); // check if meta can be parsed - XdrTransactionMeta meta = XdrTransactionMeta.fromBase64EncodedXdrString( + /*XdrTransactionMeta meta = XdrTransactionMeta.fromBase64EncodedXdrString( transactionResponse.resultMetaXdr!); + print("Orig Meta: " + transactionResponse.resultMetaXdr!); + print("New Meta: " + meta.toBase64EncodedXdrString()); assert(meta.toBase64EncodedXdrString() == - transactionResponse.resultMetaXdr!); + transactionResponse.resultMetaXdr!);*/ // check operation response from horizon Page operations = await sdk.operations - .forTransaction(sendResponse.transactionId!) + .forTransaction(sendResponse.hash!) .execute(); assert(operations.records != null && operations.records!.length > 0); OperationResponse operationResponse = operations.records!.first; @@ -161,7 +161,7 @@ void main() { assert(helloContractWasmId != null); // reload account for current sequence nr - GetAccountResponse accountA = await sorobanServer.getAccount(accountAId); + AccountResponse accountA = await sdk.accounts.account(accountAId); // build the operation for creating the contract InvokeHostFunctionOperation operation = @@ -199,32 +199,32 @@ void main() { await sorobanServer.sendTransaction(transaction); assert(sendResponse.error == null); - assert(sendResponse.transactionId != null); + assert(sendResponse.hash != null); assert(sendResponse.status != null); - assert(sendResponse.resultError == null); + assert(sendResponse.status != SendTransactionResponse.STATUS_ERROR); - GetTransactionStatusResponse statusResponse = - await pollStatus(sendResponse.transactionId!); - if (statusResponse.status == SorobanServer.TRANSACTION_STATUS_SUCCESS) { - helloContractId = statusResponse.getContractId(); + GetTransactionResponse rpcTransactionResponse = + await pollStatus(sendResponse.hash!); + if (rpcTransactionResponse.status == GetTransactionResponse.STATUS_SUCCESS) { + helloContractId = rpcTransactionResponse.getContractId(); } assert(helloContractId != null); // check horizon responses decoding TransactionResponse transactionResponse = - await sdk.transactions.transaction(sendResponse.transactionId!); + await sdk.transactions.transaction(sendResponse.hash!); assert(transactionResponse.operationCount == 1); assert(transactionEnvelopeXdr == transactionResponse.envelopeXdr); // check if meta can be parsed - XdrTransactionMeta meta = XdrTransactionMeta.fromBase64EncodedXdrString( + /*XdrTransactionMeta meta = XdrTransactionMeta.fromBase64EncodedXdrString( transactionResponse.resultMetaXdr!); assert(meta.toBase64EncodedXdrString() == - transactionResponse.resultMetaXdr!); + transactionResponse.resultMetaXdr!);*/ // check operation response from horizon Page operations = await sdk.operations - .forTransaction(sendResponse.transactionId!) + .forTransaction(sendResponse.hash!) .execute(); assert(operations.records != null && operations.records!.length > 0); OperationResponse operationResponse = operations.records!.first; @@ -240,7 +240,7 @@ void main() { assert(helloContractId != null); // load account for sequence number - GetAccountResponse accountA = await sorobanServer.getAccount(accountAId); + AccountResponse accountA = await sdk.accounts.account(accountAId); // prepare argument XdrSCVal arg = XdrSCVal.forSymbol("friend"); @@ -276,29 +276,23 @@ void main() { SendTransactionResponse sendResponse = await sorobanServer.sendTransaction(transaction); assert(sendResponse.error == null); - assert(sendResponse.transactionId != null); + assert(sendResponse.hash != null); assert(sendResponse.status != null); - assert(sendResponse.resultError == null); - - GetTransactionStatusResponse statusResponse = - await pollStatus(sendResponse.transactionId!); - if (statusResponse.status == SorobanServer.TRANSACTION_STATUS_SUCCESS) { - List res = statusResponse.results!; - for (int i = 0; i < res.length; i++) { - String xdr = res[i].xdr; - XdrSCVal resVal = XdrSCVal.fromBase64EncodedXdrString(xdr); - - assert(resVal.obj != null); - assert(resVal.obj!.vec != null); - assert(resVal.obj!.vec!.length == 2); - assert(resVal.obj!.vec![0].sym == "Hello"); - assert(resVal.obj!.vec![1].sym == "friend"); - print(resVal.obj!.vec![0].sym! + " " + resVal.obj!.vec![1].sym!); - } + assert(sendResponse.status != SendTransactionResponse.STATUS_ERROR); + + GetTransactionResponse rpcTransactionResponse = + await pollStatus(sendResponse.hash!); + if (rpcTransactionResponse.status == GetTransactionResponse.STATUS_SUCCESS) { + XdrSCVal resVal = rpcTransactionResponse.getResultValue()!; + + assert(resVal.vec!.length == 2); + assert(resVal.vec![0].sym == "Hello"); + assert(resVal.vec![1].sym == "friend"); + print(resVal.vec![0].sym! + " " + resVal.vec![1].sym!); // user friendly - XdrSCVal? resVal = statusResponse.getResultValue(); - List? vec = resVal?.getVec(); + XdrSCVal? resValO = rpcTransactionResponse.getResultValue(); + List? vec = resValO?.vec; if (vec != null && vec.length > 1) { print("[${vec[0].sym} , ${vec[1].sym}]"); } @@ -306,19 +300,19 @@ void main() { // check horizon responses decoding TransactionResponse transactionResponse = - await sdk.transactions.transaction(sendResponse.transactionId!); + await sdk.transactions.transaction(sendResponse.hash!); assert(transactionResponse.operationCount == 1); assert(transactionEnvelopeXdr == transactionResponse.envelopeXdr); // check if meta can be parsed - XdrTransactionMeta meta = XdrTransactionMeta.fromBase64EncodedXdrString( + /*XdrTransactionMeta meta = XdrTransactionMeta.fromBase64EncodedXdrString( transactionResponse.resultMetaXdr!); assert(meta.toBase64EncodedXdrString() == - transactionResponse.resultMetaXdr!); + transactionResponse.resultMetaXdr!);*/ // check operation response from horizon Page operations = await sdk.operations - .forTransaction(sendResponse.transactionId!) + .forTransaction(sendResponse.hash!) .execute(); assert(operations.records != null && operations.records!.length > 0); OperationResponse operationResponse = operations.records!.first; @@ -334,7 +328,7 @@ void main() { test('test events', () async { // Install contract - GetAccountResponse submitter = await sorobanServer.getAccount(accountAId); + AccountResponse submitter = await sdk.accounts.account(accountAId); Uint8List contractCode = await Util.readFile(eventsContractPath); @@ -354,20 +348,20 @@ void main() { SendTransactionResponse sendResponse = await sorobanServer.sendTransaction(transaction); assert(sendResponse.error == null); - assert(sendResponse.resultError == null); + assert(sendResponse.status != SendTransactionResponse.STATUS_ERROR); String? eventsContractWasmId; - GetTransactionStatusResponse statusResponse = - await pollStatus(sendResponse.transactionId!); - if (statusResponse.status == SorobanServer.TRANSACTION_STATUS_SUCCESS) { - eventsContractWasmId = statusResponse.getWasmId(); + GetTransactionResponse rpcTransactionResponse = + await pollStatus(sendResponse.hash!); + if (rpcTransactionResponse.status == GetTransactionResponse.STATUS_SUCCESS) { + eventsContractWasmId = rpcTransactionResponse.getWasmId(); } assert(eventsContractWasmId != null); String wasmId = eventsContractWasmId!; // Create contract - submitter = await sorobanServer.getAccount(accountAId); + submitter = await sdk.accounts.account(accountAId); operation = InvokeHostFuncOpBuilder.forCreatingContract(wasmId).build(); transaction = new TransactionBuilder(submitter).addOperation(operation).build(); @@ -380,18 +374,18 @@ void main() { sendResponse = await sorobanServer.sendTransaction(transaction); assert(sendResponse.error == null); - assert(sendResponse.resultError == null); + assert(sendResponse.status != SendTransactionResponse.STATUS_ERROR); String? eventsContractId; - statusResponse = await pollStatus(sendResponse.transactionId!); - if (statusResponse.status == SorobanServer.TRANSACTION_STATUS_SUCCESS) { - eventsContractId = statusResponse.getContractId(); + rpcTransactionResponse = await pollStatus(sendResponse.hash!); + if (rpcTransactionResponse.status == GetTransactionResponse.STATUS_SUCCESS) { + eventsContractId = rpcTransactionResponse.getContractId(); } assert(eventsContractId != null); String contractId = eventsContractId!; // Invoke contract - submitter = await sorobanServer.getAccount(accountAId); + submitter = await sdk.accounts.account(accountAId); String functionName = "events"; operation = @@ -408,20 +402,19 @@ void main() { sendResponse = await sorobanServer.sendTransaction(transaction); assert(sendResponse.error == null); - assert(sendResponse.resultError == null); + assert(sendResponse.status != SendTransactionResponse.STATUS_ERROR); - await pollStatus(sendResponse.transactionId!); + await pollStatus(sendResponse.hash!); // query events TransactionResponse transactionResponse = - await sdk.transactions.transaction(sendResponse.transactionId!); + await sdk.transactions.transaction(sendResponse.hash!); String startLedger = transactionResponse.ledger.toString(); - String endLedger = transactionResponse.ledger.toString(); EventFilter eventFilter = EventFilter(type: "contract", contractIds: [contractId]); GetEventsRequest eventsRequest = - GetEventsRequest(startLedger, endLedger, filters: [eventFilter]); + GetEventsRequest(startLedger, filters: [eventFilter]); GetEventsResponse eventsResponse = await sorobanServer.getEvents(eventsRequest); assert(!eventsResponse.isErrorResponse); @@ -455,7 +448,7 @@ void main() { test('test deploy SAC with source account', () async { // load account - GetAccountResponse accountA = await sorobanServer.getAccount(accountAId); + AccountResponse accountA = await sdk.accounts.account(accountAId); // create transaction for deploying the contract InvokeHostFunctionOperation operation = @@ -489,27 +482,26 @@ void main() { SendTransactionResponse sendResponse = await sorobanServer.sendTransaction(transaction); assert(sendResponse.error == null); - assert(sendResponse.transactionId != null); assert(sendResponse.status != null); - assert(sendResponse.resultError == null); + assert(sendResponse.status != SendTransactionResponse.STATUS_ERROR); - await pollStatus(sendResponse.transactionId!); + await pollStatus(sendResponse.hash!); // check horizon responses decoding TransactionResponse transactionResponse = - await sdk.transactions.transaction(sendResponse.transactionId!); + await sdk.transactions.transaction(sendResponse.hash!); assert(transactionResponse.operationCount == 1); assert(transactionEnvelopeXdr == transactionResponse.envelopeXdr); // check if meta can be parsed - XdrTransactionMeta meta = XdrTransactionMeta.fromBase64EncodedXdrString( + /*XdrTransactionMeta meta = XdrTransactionMeta.fromBase64EncodedXdrString( transactionResponse.resultMetaXdr!); assert(meta.toBase64EncodedXdrString() == - transactionResponse.resultMetaXdr!); + transactionResponse.resultMetaXdr!);*/ // check operation response from horizon Page operations = await sdk.operations - .forTransaction(sendResponse.transactionId!) + .forTransaction(sendResponse.hash!) .execute(); assert(operations.records != null && operations.records!.length > 0); OperationResponse operationResponse = operations.records!.first; @@ -522,15 +514,11 @@ void main() { }); test('test SAC with asset', () async { - GetAccountResponse accountResponse = - await sorobanServer.getAccount(accountBId); - if (accountResponse.accountMissing) { - await FuturenetFriendBot.fundTestAccount(accountBId); - } + + await FuturenetFriendBot.fundTestAccount(accountBId); // prepare trustline - GetAccountResponse sourceAccount = - await sorobanServer.getAccount(accountBId); + AccountResponse sourceAccount = await sdk.accounts.account(accountBId); ChangeTrustOperationBuilder ctOp = ChangeTrustOperationBuilder(assetFsdk, "1000000"); ctOp.setSourceAccount(accountAId); @@ -548,7 +536,7 @@ void main() { assert(response.success); // load account - GetAccountResponse accountB = await sorobanServer.getAccount(accountBId); + AccountResponse accountB = await sdk.accounts.account(accountBId); // create transaction for deploying the contract InvokeHostFunctionOperation operation = @@ -582,27 +570,26 @@ void main() { SendTransactionResponse sendResponse = await sorobanServer.sendTransaction(transaction); assert(sendResponse.error == null); - assert(sendResponse.transactionId != null); assert(sendResponse.status != null); - assert(sendResponse.resultError == null); + assert(sendResponse.status != SendTransactionResponse.STATUS_ERROR); - await pollStatus(sendResponse.transactionId!); + await pollStatus(sendResponse.hash!); // check horizon responses decoding TransactionResponse transactionResponse = - await sdk.transactions.transaction(sendResponse.transactionId!); + await sdk.transactions.transaction(sendResponse.hash!); assert(transactionResponse.operationCount == 1); assert(transactionEnvelopeXdr == transactionResponse.envelopeXdr); // check if meta can be parsed - XdrTransactionMeta meta = XdrTransactionMeta.fromBase64EncodedXdrString( + /*XdrTransactionMeta meta = XdrTransactionMeta.fromBase64EncodedXdrString( transactionResponse.resultMetaXdr!); assert(meta.toBase64EncodedXdrString() == - transactionResponse.resultMetaXdr!); + transactionResponse.resultMetaXdr!);*/ // check operation response from horizon Page operations = await sdk.operations - .forTransaction(sendResponse.transactionId!) + .forTransaction(sendResponse.hash!) .execute(); assert(operations.records != null && operations.records!.length > 0); OperationResponse operationResponse = operations.records!.first; diff --git a/test/soroban_test_atomic_swap.dart b/test/soroban_test_atomic_swap.dart index 14632fd..bbc5a29 100644 --- a/test/soroban_test_atomic_swap.dart +++ b/test/soroban_test_atomic_swap.dart @@ -7,7 +7,9 @@ import 'package:stellar_flutter_sdk/stellar_flutter_sdk.dart'; void main() { SorobanServer sorobanServer = - SorobanServer("https://horizon-futurenet.stellar.cash/soroban/rpc"); + SorobanServer("https://rpc-futurenet.stellar.org:443"); + + StellarSDK sdk = StellarSDK.FUTURENET; KeyPair adminKeypair = KeyPair.random(); String adminId = adminKeypair.accountId; @@ -30,64 +32,64 @@ void main() { setUp(() async { sorobanServer.enableLogging = false; sorobanServer.acknowledgeExperimental = true; - GetAccountResponse accountResponse = - await sorobanServer.getAccount(adminId); - if (accountResponse.accountMissing) { + + try { + await sdk.accounts.account(adminId); + } catch (e) { await FuturenetFriendBot.fundTestAccount(adminId); print("admin " + adminId + " : " + adminKeypair.secretSeed); } - await sorobanServer.getAccount(aliceId); - if (accountResponse.accountMissing) { + + try { + await sdk.accounts.account(aliceId); + } catch (e) { await FuturenetFriendBot.fundTestAccount(aliceId); print("alice " + aliceId + " : " + aliceKeypair.secretSeed); } - await sorobanServer.getAccount(bobId); - if (accountResponse.accountMissing) { + + try { + await sdk.accounts.account(bobId); + } catch (e) { await FuturenetFriendBot.fundTestAccount(bobId); print("bob " + bobId + " : " + bobKeypair.secretSeed); } }); // poll until success or error - Future pollStatus(String transactionId) async { - var status = SorobanServer.TRANSACTION_STATUS_PENDING; - GetTransactionStatusResponse? statusResponse; - while (status == SorobanServer.TRANSACTION_STATUS_PENDING) { + Future pollStatus(String transactionId) async { + var status = GetTransactionResponse.STATUS_NOT_FOUND; + GetTransactionResponse? transactionResponse; + while (status == GetTransactionResponse.STATUS_NOT_FOUND) { await Future.delayed(const Duration(seconds: 3), () {}); - statusResponse = await sorobanServer.getTransactionStatus(transactionId); - assert(statusResponse.error == null); - status = statusResponse.status!; - if (status == SorobanServer.TRANSACTION_STATUS_ERROR) { - assert(statusResponse.resultError != null); - print(statusResponse.resultError?.message); + transactionResponse = await sorobanServer.getTransaction(transactionId); + assert(transactionResponse.error == null); + status = transactionResponse.status!; + if (status == GetTransactionResponse.STATUS_FAILED) { + assert(transactionResponse.resultXdr != null); assert(false); - } else if (status == SorobanServer.TRANSACTION_STATUS_SUCCESS) { - assert(statusResponse.results != null); - assert(statusResponse.results!.isNotEmpty); + } else if (status == GetTransactionResponse.STATUS_SUCCESS) { + assert(transactionResponse.resultXdr != null); } } - return statusResponse!; + return transactionResponse!; } Future installContract(String contractCodePath) async { // load account - GetAccountResponse submitter = - await sorobanServer.getAccount(adminId); - assert(!submitter.isErrorResponse); + AccountResponse submitter = await sdk.accounts.account(adminId); // load contract wasm file Uint8List contractCode = await Util.readFile(contractCodePath); // create transaction for installing the contract InvokeHostFunctionOperation operation = - InvokeHostFuncOpBuilder.forInstallingContractCode(contractCode) - .build(); + InvokeHostFuncOpBuilder.forInstallingContractCode(contractCode).build(); Transaction transaction = - new TransactionBuilder(submitter).addOperation(operation).build(); + new TransactionBuilder(submitter).addOperation(operation).build(); // simulate first to obtain the footprint SimulateTransactionResponse simulateResponse = - await sorobanServer.simulateTransaction(transaction); + await sorobanServer.simulateTransaction(transaction); assert(!simulateResponse.isErrorResponse); assert(simulateResponse.footprint != null); @@ -103,36 +105,32 @@ void main() { // send transaction to soroban rpc server SendTransactionResponse sendResponse = - await sorobanServer.sendTransaction(transaction); + await sorobanServer.sendTransaction(transaction); assert(!sendResponse.isErrorResponse); - assert(sendResponse.resultError == null); + assert(sendResponse.status != SendTransactionResponse.STATUS_ERROR); - GetTransactionStatusResponse statusResponse = - await pollStatus(sendResponse.transactionId!); - String? wasmId = statusResponse.getWasmId(); + GetTransactionResponse rpcTransactionResponse = + await pollStatus(sendResponse.hash!); + String? wasmId = rpcTransactionResponse.getWasmId(); assert(wasmId != null); return wasmId!; } Future createContract(String wasmId) async { - // reload account for current sequence nr - GetAccountResponse submitter = - await sorobanServer.getAccount(adminId); - assert(!submitter.isErrorResponse); + AccountResponse submitter = await sdk.accounts.account(adminId); // build the operation for creating the contract InvokeHostFunctionOperation operation = - InvokeHostFuncOpBuilder.forCreatingContract(wasmId) - .build(); + InvokeHostFuncOpBuilder.forCreatingContract(wasmId).build(); // build the transaction for creating the contract Transaction transaction = - new TransactionBuilder(submitter).addOperation(operation).build(); + new TransactionBuilder(submitter).addOperation(operation).build(); // first simulate to obtain the footprint SimulateTransactionResponse simulateResponse = - await sorobanServer.simulateTransaction(transaction); + await sorobanServer.simulateTransaction(transaction); assert(!simulateResponse.isErrorResponse); assert(simulateResponse.resultError == null); @@ -142,49 +140,54 @@ void main() { // send transaction to soroban rpc server SendTransactionResponse sendResponse = - await sorobanServer.sendTransaction(transaction); + await sorobanServer.sendTransaction(transaction); assert(!sendResponse.isErrorResponse); - assert(sendResponse.resultError == null); - GetTransactionStatusResponse statusResponse = - await pollStatus(sendResponse.transactionId!); + assert(sendResponse.status != SendTransactionResponse.STATUS_ERROR); + + GetTransactionResponse statusResponse = + await pollStatus(sendResponse.hash!); String? contractId = statusResponse.getContractId(); assert(contractId != null); return contractId!; } - Future createToken(String contractId, String name, String symbol) async { + Future createToken( + String contractId, String name, String symbol) async { // see https://soroban.stellar.org/docs/reference/interfaces/token-interface // reload account for sequence number - GetAccountResponse invoker = await sorobanServer.getAccount(adminId); - assert(!invoker.isErrorResponse); + AccountResponse invoker = await sdk.accounts.account(adminId); Address adminAddress = Address.forAccountId(adminId); String functionName = "initialize"; List list = utf8.encode(name); String nameHex = hex.encode(list); - XdrSCVal tokenName = XdrSCVal.forObject(XdrSCObject.forBytes(Util.hexToBytes(nameHex))); + XdrSCVal tokenName = XdrSCVal.forBytes(Util.hexToBytes(nameHex)); list = utf8.encode(name); String symbolHex = hex.encode(list); - XdrSCVal tokenSymbol = XdrSCVal.forObject(XdrSCObject.forBytes(Util.hexToBytes(symbolHex))); + XdrSCVal tokenSymbol = XdrSCVal.forBytes(Util.hexToBytes(symbolHex)); - List args = [adminAddress.toXdrSCVal(), XdrSCVal.forU32(8), tokenName, tokenSymbol]; + List args = [ + adminAddress.toXdrSCVal(), + XdrSCVal.forU32(8), + tokenName, + tokenSymbol + ]; AuthorizedInvocation rootInvocation = - AuthorizedInvocation(contractId, functionName, args: args); + AuthorizedInvocation(contractId, functionName, args: args); ContractAuth contractAuth = ContractAuth(rootInvocation); InvokeHostFunctionOperation operation = - InvokeHostFuncOpBuilder.forInvokingContract( - contractId, functionName, - functionArguments: args, contractAuth: [contractAuth]).build(); + InvokeHostFuncOpBuilder.forInvokingContract(contractId, functionName, + functionArguments: args, contractAuth: [contractAuth]).build(); Transaction transaction = - new TransactionBuilder(invoker).addOperation(operation).build(); + new TransactionBuilder(invoker).addOperation(operation).build(); // simulate first to get footprint SimulateTransactionResponse simulateResponse = - await sorobanServer.simulateTransaction(transaction); + await sorobanServer.simulateTransaction(transaction); assert(simulateResponse.error == null); assert(simulateResponse.resultError == null); assert(simulateResponse.footprint != null); @@ -201,45 +204,46 @@ void main() { // send the transaction SendTransactionResponse sendResponse = - await sorobanServer.sendTransaction(transaction); + await sorobanServer.sendTransaction(transaction); assert(sendResponse.error == null); - assert(sendResponse.resultError == null); + assert(sendResponse.status != SendTransactionResponse.STATUS_ERROR); - GetTransactionStatusResponse statusResponse = - await pollStatus(sendResponse.transactionId!); + GetTransactionResponse statusResponse = + await pollStatus(sendResponse.hash!); String status = statusResponse.status!; - assert(status == SorobanServer.TRANSACTION_STATUS_SUCCESS); + assert(status == GetTransactionResponse.STATUS_SUCCESS); } Future mint(String contractId, String toAccountId, int amount) async { // see https://soroban.stellar.org/docs/reference/interfaces/token-interface // reload account for sequence number - GetAccountResponse invoker = await sorobanServer.getAccount(adminId); - assert(!invoker.isErrorResponse); + AccountResponse invoker = await sdk.accounts.account(adminId); Address adminAddress = Address.forAccountId(adminId); Address toAddress = Address.forAccountId(toAccountId); - XdrSCVal amountVal = XdrSCVal.forObject( - XdrSCObject.forI128(XdrInt128Parts.forLoHi(amount, 0))); + XdrSCVal amountVal = XdrSCVal.forI128(XdrInt128Parts.forLoHi(amount, 0)); String functionName = "mint"; - List args = [adminAddress.toXdrSCVal(), toAddress.toXdrSCVal(), amountVal]; + List args = [ + adminAddress.toXdrSCVal(), + toAddress.toXdrSCVal(), + amountVal + ]; AuthorizedInvocation rootInvocation = - AuthorizedInvocation(contractId, functionName, args: args); + AuthorizedInvocation(contractId, functionName, args: args); ContractAuth contractAuth = ContractAuth(rootInvocation); InvokeHostFunctionOperation operation = - InvokeHostFuncOpBuilder.forInvokingContract( - contractId, functionName, - functionArguments: args, contractAuth: [contractAuth]).build(); + InvokeHostFuncOpBuilder.forInvokingContract(contractId, functionName, + functionArguments: args, contractAuth: [contractAuth]).build(); Transaction transaction = - new TransactionBuilder(invoker).addOperation(operation).build(); + new TransactionBuilder(invoker).addOperation(operation).build(); // simulate first to get footprint SimulateTransactionResponse simulateResponse = - await sorobanServer.simulateTransaction(transaction); + await sorobanServer.simulateTransaction(transaction); assert(simulateResponse.error == null); assert(simulateResponse.resultError == null); assert(simulateResponse.footprint != null); @@ -256,22 +260,19 @@ void main() { // send the transaction SendTransactionResponse sendResponse = - await sorobanServer.sendTransaction(transaction); + await sorobanServer.sendTransaction(transaction); assert(sendResponse.error == null); - assert(sendResponse.resultError == null); + assert(sendResponse.status != SendTransactionResponse.STATUS_ERROR); - GetTransactionStatusResponse statusResponse = - await pollStatus(sendResponse.transactionId!); + GetTransactionResponse statusResponse = + await pollStatus(sendResponse.hash!); String status = statusResponse.status!; - assert(status == SorobanServer.TRANSACTION_STATUS_SUCCESS); + assert(status == GetTransactionResponse.STATUS_SUCCESS); } - Futurebalance(String contractId, String accountId) async { - + Future balance(String contractId, String accountId) async { // reload account for sequence number - GetAccountResponse invoker = await sorobanServer.getAccount(adminId); - assert(!invoker.isErrorResponse); - + AccountResponse invoker = await sdk.accounts.account(adminId); Address address = Address.forAccountId(accountId); String functionName = "balance"; @@ -279,15 +280,15 @@ void main() { List args = [address.toXdrSCVal()]; InvokeHostFunctionOperation operation = - InvokeHostFuncOpBuilder.forInvokingContract( - contractId, functionName, - functionArguments: args).build(); + InvokeHostFuncOpBuilder.forInvokingContract(contractId, functionName, + functionArguments: args) + .build(); Transaction transaction = - new TransactionBuilder(invoker).addOperation(operation).build(); + new TransactionBuilder(invoker).addOperation(operation).build(); // simulate first to get footprint SimulateTransactionResponse simulateResponse = - await sorobanServer.simulateTransaction(transaction); + await sorobanServer.simulateTransaction(transaction); assert(simulateResponse.error == null); assert(simulateResponse.resultError == null); assert(simulateResponse.footprint != null); @@ -304,24 +305,21 @@ void main() { // send the transaction SendTransactionResponse sendResponse = - await sorobanServer.sendTransaction(transaction); + await sorobanServer.sendTransaction(transaction); assert(sendResponse.error == null); - assert(sendResponse.resultError == null); - GetTransactionStatusResponse statusResponse = - await pollStatus(sendResponse.transactionId!); + GetTransactionResponse statusResponse = + await pollStatus(sendResponse.hash!); String status = statusResponse.status!; - assert(status == SorobanServer.TRANSACTION_STATUS_SUCCESS); + assert(status == GetTransactionResponse.STATUS_SUCCESS); - assert(statusResponse.getResultValue()?.getI128() != null); - XdrInt128Parts parts = statusResponse.getResultValue()!.getI128()!; + assert(statusResponse.getResultValue()?.i128 != null); + XdrInt128Parts parts = statusResponse.getResultValue()!.i128!; return parts.lo.uint64; } group('all tests', () { - test('test install contracts', () async { - tokenAContractWasmId = await installContract(tokenContractPath); tokenBContractWasmId = await installContract(tokenContractPath); swapContractWasmId = await installContract(swapContractPath); @@ -367,26 +365,20 @@ void main() { String atomicSwapContractId = swapContractId!; String tokenACId = tokenAContractId!; - String tokenBCId = tokenBContractId!; + String tokenBCId = tokenBContractId!; Address addressAlice = Address.forAccountId(aliceAccountId); Address addressBob = Address.forAccountId(bobAccountId); Address addressSwapContract = Address.forContractId(atomicSwapContractId); - XdrSCVal tokenABytes = XdrSCVal.forObject( - XdrSCObject.forBytes(Util.hexToBytes(tokenACId))); - XdrSCVal tokenBBytes = XdrSCVal.forObject( - XdrSCObject.forBytes(Util.hexToBytes(tokenBCId))); + XdrSCVal tokenABytes = XdrSCVal.forBytes(Util.hexToBytes(tokenACId)); + XdrSCVal tokenBBytes = XdrSCVal.forBytes(Util.hexToBytes(tokenBCId)); - XdrSCVal amountA = XdrSCVal.forObject( - XdrSCObject.forI128(XdrInt128Parts.forLoHi(1000, 0))); - XdrSCVal minBForA = XdrSCVal.forObject( - XdrSCObject.forI128(XdrInt128Parts.forLoHi(4500, 0))); + XdrSCVal amountA = XdrSCVal.forI128(XdrInt128Parts.forLoHi(1000, 0)); + XdrSCVal minBForA = XdrSCVal.forI128(XdrInt128Parts.forLoHi(4500, 0)); - XdrSCVal amountB = XdrSCVal.forObject( - XdrSCObject.forI128(XdrInt128Parts.forLoHi(5000, 0))); - XdrSCVal minAForB = XdrSCVal.forObject( - XdrSCObject.forI128(XdrInt128Parts.forLoHi(950, 0))); + XdrSCVal amountB = XdrSCVal.forI128(XdrInt128Parts.forLoHi(5000, 0)); + XdrSCVal minAForB = XdrSCVal.forI128(XdrInt128Parts.forLoHi(950, 0)); String swapFuntionName = "swap"; String incrAllowFunctionName = "incr_allow"; @@ -428,15 +420,15 @@ void main() { args: bobRootAuthArgs, subInvocations: [bobSubAuthInvocation]); int aliceNonce = - await sorobanServer.getNonce(aliceAccountId, atomicSwapContractId); + await sorobanServer.getNonce(aliceAccountId, atomicSwapContractId); ContractAuth aliceContractAuth = ContractAuth(aliceRootInvocation, address: addressAlice, nonce: aliceNonce); aliceContractAuth.sign(aliceKp, Network.FUTURENET); int bobNonce = - await sorobanServer.getNonce(bobAccountId, atomicSwapContractId); + await sorobanServer.getNonce(bobAccountId, atomicSwapContractId); ContractAuth bobContractAuth = - ContractAuth(bobRootInvocation, address: addressBob, nonce: bobNonce); + ContractAuth(bobRootInvocation, address: addressBob, nonce: bobNonce); bobContractAuth.sign(bobKp, Network.FUTURENET); List invokeArgs = [ @@ -451,22 +443,21 @@ void main() { ]; // load submitter account for sequence number - GetAccountResponse swapSubmitter = - await sorobanServer.getAccount(swapSubmitterAccountId); - assert(!swapSubmitter.isErrorResponse); + AccountResponse swapSubmitter = + await sdk.accounts.account(swapSubmitterAccountId); InvokeHostFunctionOperation operation = - InvokeHostFuncOpBuilder.forInvokingContract( - atomicSwapContractId, swapFuntionName, - functionArguments: invokeArgs, - contractAuth: [aliceContractAuth, bobContractAuth]).build(); + InvokeHostFuncOpBuilder.forInvokingContract( + atomicSwapContractId, swapFuntionName, + functionArguments: invokeArgs, + contractAuth: [aliceContractAuth, bobContractAuth]).build(); Transaction transaction = - new TransactionBuilder(swapSubmitter).addOperation(operation).build(); + new TransactionBuilder(swapSubmitter).addOperation(operation).build(); // simulate first to get footprint SimulateTransactionResponse simulateResponse = - await sorobanServer.simulateTransaction(transaction); + await sorobanServer.simulateTransaction(transaction); assert(simulateResponse.error == null); assert(simulateResponse.resultError == null); assert(simulateResponse.footprint != null); @@ -483,15 +474,15 @@ void main() { // send the transaction SendTransactionResponse sendResponse = - await sorobanServer.sendTransaction(transaction); + await sorobanServer.sendTransaction(transaction); assert(sendResponse.error == null); - assert(sendResponse.resultError == null); + assert(sendResponse.status != SendTransactionResponse.STATUS_ERROR); - GetTransactionStatusResponse statusResponse = - await pollStatus(sendResponse.transactionId!); + GetTransactionResponse statusResponse = + await pollStatus(sendResponse.hash!); String status = statusResponse.status!; - assert(status == SorobanServer.TRANSACTION_STATUS_SUCCESS); - print("Result " + statusResponse.results![0].xdr); + assert(status == GetTransactionResponse.STATUS_SUCCESS); + print("Result " + statusResponse.getResultValue()!.toBase64EncodedXdrString()); }); }); } diff --git a/test/soroban_test_auth.dart b/test/soroban_test_auth.dart index 0065b87..0773f14 100644 --- a/test/soroban_test_auth.dart +++ b/test/soroban_test_auth.dart @@ -5,7 +5,7 @@ import 'package:stellar_flutter_sdk/stellar_flutter_sdk.dart'; void main() { SorobanServer sorobanServer = - SorobanServer("https://horizon-futurenet.stellar.cash/soroban/rpc"); + SorobanServer("https://rpc-futurenet.stellar.org:443"); StellarSDK sdk = StellarSDK.FUTURENET; @@ -22,45 +22,44 @@ void main() { setUp(() async { sorobanServer.enableLogging = true; sorobanServer.acknowledgeExperimental = true; - GetAccountResponse accountResponse = - await sorobanServer.getAccount(submitterId); - if (accountResponse.accountMissing) { + + try { + await sdk.accounts.account(submitterId); + } catch (e) { await FuturenetFriendBot.fundTestAccount(submitterId); } - await sorobanServer.getAccount(invokerId); - if (accountResponse.accountMissing) { + + try { + await sdk.accounts.account(invokerId); + } catch (e) { await FuturenetFriendBot.fundTestAccount(invokerId); } + }); // poll until success or error - Future pollStatus(String transactionId) async { - var status = SorobanServer.TRANSACTION_STATUS_PENDING; - GetTransactionStatusResponse? statusResponse; - while (status == SorobanServer.TRANSACTION_STATUS_PENDING) { + Future pollStatus(String transactionId) async { + var status = GetTransactionResponse.STATUS_NOT_FOUND; + GetTransactionResponse? transactionResponse; + while (status == GetTransactionResponse.STATUS_NOT_FOUND) { await Future.delayed(const Duration(seconds: 3), () {}); - statusResponse = await sorobanServer.getTransactionStatus(transactionId); - assert(statusResponse.error == null); - status = statusResponse.status!; - if (status == SorobanServer.TRANSACTION_STATUS_ERROR) { - assert(statusResponse.resultError != null); - print(statusResponse.resultError?.message); + transactionResponse = await sorobanServer.getTransaction(transactionId); + assert(transactionResponse.error == null); + status = transactionResponse.status!; + if (status == GetTransactionResponse.STATUS_FAILED) { + assert(transactionResponse.resultXdr != null); assert(false); - } else if (status == SorobanServer.TRANSACTION_STATUS_SUCCESS) { - assert(statusResponse.results != null); - assert(statusResponse.results!.isNotEmpty); + } else if (status == GetTransactionResponse.STATUS_SUCCESS) { + assert(transactionResponse.resultXdr != null); } } - return statusResponse!; + return transactionResponse!; } group('all tests', () { test('test install auth contract', () async { // load account - GetAccountResponse submitter = - await sorobanServer.getAccount(submitterId); - assert(!submitter.isErrorResponse); - + AccountResponse submitter = await sdk.accounts.account(submitterId); // load contract wasm file Uint8List contractCode = await Util.readFile(authContractPath); @@ -91,11 +90,11 @@ void main() { SendTransactionResponse sendResponse = await sorobanServer.sendTransaction(transaction); assert(!sendResponse.isErrorResponse); - assert(sendResponse.resultError == null); + assert(sendResponse.status != SendTransactionResponse.STATUS_ERROR); - GetTransactionStatusResponse statusResponse = - await pollStatus(sendResponse.transactionId!); - authContractWasmId = statusResponse.getWasmId(); + GetTransactionResponse rpcTransactionResponse = + await pollStatus(sendResponse.hash!); + authContractWasmId = rpcTransactionResponse.getWasmId(); assert(authContractWasmId != null); }); @@ -104,9 +103,7 @@ void main() { assert(authContractWasmId != null); // reload account for current sequence nr - GetAccountResponse submitter = - await sorobanServer.getAccount(submitterId); - assert(!submitter.isErrorResponse); + AccountResponse submitter = await sdk.accounts.account(submitterId); // build the operation for creating the contract InvokeHostFunctionOperation operation = @@ -131,11 +128,11 @@ void main() { SendTransactionResponse sendResponse = await sorobanServer.sendTransaction(transaction); assert(!sendResponse.isErrorResponse); - assert(sendResponse.resultError == null); + assert(sendResponse.status != SendTransactionResponse.STATUS_ERROR); - GetTransactionStatusResponse statusResponse = - await pollStatus(sendResponse.transactionId!); - authContractId = statusResponse.getContractId(); + GetTransactionResponse rpcTransactionResponse = + await pollStatus(sendResponse.hash!); + authContractId = rpcTransactionResponse.getContractId(); assert(authContractId != null); }); @@ -149,9 +146,7 @@ void main() { assert(authContractId != null); // reload account for sequence number - GetAccountResponse submitter = - await sorobanServer.getAccount(submitterId); - assert(!submitter.isErrorResponse); + AccountResponse submitter = await sdk.accounts.account(submitterId); Address invokerAddress = Address.forAccountId(invokerId); String functionName = "auth"; @@ -192,20 +187,20 @@ void main() { SendTransactionResponse sendResponse = await sorobanServer.sendTransaction(transaction); assert(sendResponse.error == null); - assert(sendResponse.transactionId != null); + assert(sendResponse.hash != null); assert(sendResponse.status != null); - assert(sendResponse.resultError == null); + assert(sendResponse.status != SendTransactionResponse.STATUS_ERROR); - GetTransactionStatusResponse statusResponse = - await pollStatus(sendResponse.transactionId!); - String status = statusResponse.status!; - assert(status == SorobanServer.TRANSACTION_STATUS_SUCCESS); + GetTransactionResponse rpcTransactionResponse = + await pollStatus(sendResponse.hash!); + String status = rpcTransactionResponse.status!; + assert(status == GetTransactionResponse.STATUS_SUCCESS); - assert(statusResponse.getResultValue()?.getMap() != null); - List map = statusResponse.getResultValue()!.getMap()!; + assert(rpcTransactionResponse.getResultValue()?.map != null); + List map = rpcTransactionResponse.getResultValue()!.map!; if (map.length > 0) { for (XdrSCMapEntry entry in map) { - Address address = Address.fromXdr(entry.key.obj!.address!); + Address address = Address.fromXdr(entry.key.address!); print("{" + address.accountId! + ", " + @@ -216,19 +211,19 @@ void main() { // check horizon responses decoding TransactionResponse transactionResponse = - await sdk.transactions.transaction(sendResponse.transactionId!); + await sdk.transactions.transaction(sendResponse.hash!); assert(transactionResponse.operationCount == 1); assert(transactionEnvelopeXdr == transactionResponse.envelopeXdr); // check if meta can be parsed - XdrTransactionMeta meta = XdrTransactionMeta.fromBase64EncodedXdrString( + /*XdrTransactionMeta meta = XdrTransactionMeta.fromBase64EncodedXdrString( transactionResponse.resultMetaXdr!); assert(meta.toBase64EncodedXdrString() == - transactionResponse.resultMetaXdr!); + transactionResponse.resultMetaXdr!);*/ // check operation response from horizon Page operations = await sdk.operations - .forTransaction(sendResponse.transactionId!) + .forTransaction(sendResponse.hash!) .execute(); assert(operations.records != null && operations.records!.length > 0); OperationResponse operationResponse = operations.records!.first; @@ -252,8 +247,7 @@ void main() { assert(authContractId != null); // reload account for sequence number - GetAccountResponse invoker = await sorobanServer.getAccount(invokerId); - assert(!invoker.isErrorResponse); + AccountResponse invoker = await sdk.accounts.account(invokerId); Address invokerAddress = Address.forAccountId(invokerId); String functionName = "auth"; @@ -295,18 +289,18 @@ void main() { SendTransactionResponse sendResponse = await sorobanServer.sendTransaction(transaction); assert(sendResponse.error == null); - assert(sendResponse.resultError == null); + assert(sendResponse.status != SendTransactionResponse.STATUS_ERROR); - GetTransactionStatusResponse statusResponse = - await pollStatus(sendResponse.transactionId!); - String status = statusResponse.status!; - assert(status == SorobanServer.TRANSACTION_STATUS_SUCCESS); + GetTransactionResponse rpcTransactionResponse = + await pollStatus(sendResponse.hash!); + String status = rpcTransactionResponse.status!; + assert(status == GetTransactionResponse.STATUS_SUCCESS); - assert(statusResponse.getResultValue()?.getMap() != null); - List map = statusResponse.getResultValue()!.getMap()!; + assert(rpcTransactionResponse.getResultValue()?.map != null); + List map = rpcTransactionResponse.getResultValue()!.map!; if (map.length > 0) { for (XdrSCMapEntry entry in map) { - Address address = Address.fromXdr(entry.key.obj!.address!); + Address address = Address.fromXdr(entry.key.address!); print("{" + address.accountId! + ", " + @@ -322,9 +316,7 @@ void main() { assert(authContractId != null); // reload account for sequence number - GetAccountResponse submitter = - await sorobanServer.getAccount(submitterId); - assert(!submitter.isErrorResponse); + AccountResponse submitter = await sdk.accounts.account(submitterId); Address invokerAddress = Address.forAccountId(invokerId); String functionName = "auth"; @@ -365,20 +357,19 @@ void main() { SendTransactionResponse sendResponse = await sorobanServer.sendTransaction(transaction); assert(sendResponse.error == null); - assert(sendResponse.transactionId != null); assert(sendResponse.status != null); - assert(sendResponse.resultError == null); + assert(sendResponse.status != SendTransactionResponse.STATUS_ERROR); - GetTransactionStatusResponse statusResponse = - await pollStatus(sendResponse.transactionId!); - String status = statusResponse.status!; - assert(status == SorobanServer.TRANSACTION_STATUS_SUCCESS); + GetTransactionResponse rpcTransactionResponse = + await pollStatus(sendResponse.hash!); + String status = rpcTransactionResponse.status!; + assert(status == GetTransactionResponse.STATUS_SUCCESS); - assert(statusResponse.getResultValue()?.getMap() != null); - List map = statusResponse.getResultValue()!.getMap()!; + assert(rpcTransactionResponse.getResultValue()?.map != null); + List map = rpcTransactionResponse.getResultValue()!.map!; if (map.length > 0) { for (XdrSCMapEntry entry in map) { - Address address = Address.fromXdr(entry.key.obj!.address!); + Address address = Address.fromXdr(entry.key.address!); print("{" + address.accountId! + ", " + @@ -389,19 +380,19 @@ void main() { // check horizon responses decoding TransactionResponse transactionResponse = - await sdk.transactions.transaction(sendResponse.transactionId!); + await sdk.transactions.transaction(sendResponse.hash!); assert(transactionResponse.operationCount == 1); assert(transactionEnvelopeXdr == transactionResponse.envelopeXdr); // check if meta can be parsed - XdrTransactionMeta meta = XdrTransactionMeta.fromBase64EncodedXdrString( + /*XdrTransactionMeta meta = XdrTransactionMeta.fromBase64EncodedXdrString( transactionResponse.resultMetaXdr!); assert(meta.toBase64EncodedXdrString() == - transactionResponse.resultMetaXdr!); + transactionResponse.resultMetaXdr!);*/ // check operation response from horizon Page operations = await sdk.operations - .forTransaction(sendResponse.transactionId!) + .forTransaction(sendResponse.hash!) .execute(); assert(operations.records != null && operations.records!.length > 0); OperationResponse operationResponse = operations.records!.first; diff --git a/test/tests_util.dart b/test/tests_util.dart index 74c965d..698b1d9 100644 --- a/test/tests_util.dart +++ b/test/tests_util.dart @@ -4,8 +4,9 @@ class TestUtils { static void resultDeAndEncodingTest(AbstractTransaction transaction, SubmitTransactionResponse response) { String? metaXdrStr = response.resultMetaXdr; if (metaXdrStr != null) { - XdrTransactionMeta meta = response.getTransactionMetaResultXdr()!; - assert(metaXdrStr == meta.toBase64EncodedXdrString()); + XdrTransactionMeta? meta = response.getTransactionMetaResultXdr(); + assert(meta != null); + assert(metaXdrStr == meta!.toBase64EncodedXdrString()); } String envelopeXdrStr = response.envelopeXdr!; diff --git a/test/wasm/atomic_swap.wasm b/test/wasm/atomic_swap.wasm index 5590c5b58a43a5a8a81b938c54362f18296863e7..aadff6e8ddd4e1f621ffe7fa3c7b8dbc6e7b148c 100644 GIT binary patch literal 1982 zcmb7F&u<$=6n<}Z_J=cRGHJPxMAdj3q*g+0kRVV%!n22f%8v*k&W@crC{ArB@zyO8 z*pV6qgg9{I01`JYGn+wn!pKA`vx#qk{U_#d%m(97p(4&c9f*N}MrgBw~ z<$-%=VZ=2=C*X!0*%1V=oZIgz?Hf$$Bs0gEJkp7)gFw4Vvy3frnYxljg?94XDR7ZY zX3|8N`Mk(ZBR#X|5Uu=%c(w2jknE{yiT|aRn5c!Feo`%YPA#5N3%df*)E9w}POYd~ z(er6!qHBOzOBXG@%9Ixr9%=2Ej;?1HC#loq=|WyM% z2u`($SIQMSxgHgArLlcX@0i%GzUQtSRT=YB-nW0@cGWVj;u?7%P3+BgO=4F!z$>7W z?E0tY4{043gyO@Ua3&&729k|FD%vbc{+5$JvD2( zVpL?6%((D)TmyFrM+Ubx)(ie~<4#Vf7c!w1=nBi)yt2H)_MgfMF7Z#Cko_`I{5sjM z6NP(5bQO=KJNWC-7BwiR9n88opE+y~_72bk`iNR&9~QZPB5Qc*veboL8p~B2CLwWe};bJxiO)?*V>wj7XMs`l9JAiVsdHhH>dqL@9nm_ xbEZv%cLsDDubnnCl9RG0$yyuCMFye*qk=Jk#&71LyA)Sp70PtFK zoh=r)SVtpRVI*KdgIom(Z()~xQi}zw3#&;O4%medckxTgvy0yV;vBnHw#k#y-1s+v z<0j1mFASLHhoa$o2pC9KpayA0c%Jjw!*mB^bCk{d-8>ui$IuK${ZTgknSq#X4rh5f z&0%E)Me}_STm}XD04G}9Qkd+yC%QMe!8h|dCbYnzdP9h z4c`*N-2|kR3Rg{Wr`ik@(|kzTq0KnCNC{G2o2`%%Z59y_4Pr>(YmZ`-Zr@rb9o)bmR3y#%k~{!=)$LbjE+CJgdk(oAK5cqu|70 zXdSL6VzorPO7vzak^CDG3l%6of~2@>-^>$gL3CZmRrt{bDnKYH{@rA`;^8m zY|);E+aj642u>gCW#fFB_VWICKI-S`e2uv3`5a#1kqVgY^n10{^2-Du9FA!@`J}Qp z>ULn;8WEYnt7L_n?@-VV+tzu%9W>8>o`p?+B z+>ynd#lfjrK!8b#8z`jEv7GxSBNJ;qQ=I~X0D}~eU{qoUsZ`tx=K4pFbq(Sm509HLNR{#J2 delta 336 zcmZ9Iu}T9$5Qb;wcJJ1l%0em=gf$RsEo=k}cR?YDkbtE{4oqV_BzLD^b0;LoAy|aG zgQ-&aTE2tMCN?^-JO47@KeNn-d=K{^$x{RX>_$T@u^dvlzN>ljbXQ=CM<4?!D8O)j z)2_C{bd)}1&jc#J9p^=o70}p5(Rd5Q2^g^7II*f{(7pVIzMh>S981Dr2s(p> zaVzu!?o{O=f?vQ-VDbQZ0C)17BuvOQ|L!+GKlAS_d5mAdQNN1-fUoT#4sm!$!||J4 z%Z3b(58mZT)II5*_AUsL{&A;2IO+|c(ZuA%Up6;HrlO$-+336{CwMN6@7yk~+<10Z zsW@n*dOUkO%Gj=mC&4nKCf1W8xh`Ig(mzCzM#*jBVuv9r=6Dt2A3mN6?)UZ

>*H zOlrv0(o9S9RQSukE??bDtw5T=!lpZ78Q^!}uL~YI(<;bu7HvU5;WChHmce|6z~Tn7 zR?5$_V6}>FZoKWtd~Qm)y!>@0?mXDK&$qX25csMVyShN#)NF%C*~|$lt;rpYhn!fM zN}^(NYN{kTIZp+AGAce&S*)2w`l1gCBWG)P-*EB&aA|n%617$zk*>oQa(gWm+(wxk Mm?1SD)&$^ZZW delta 617 zcmY*VO=}cE5Ur}|p6+Zf*q|V8V(1w?=*`oL2Qf9E_;JaCKOh13GRvy_!9qZ$7qUoh z67mPU#Y=vL2Ty`We}sDWw${w<8Zw7|#hdpY_3E$rWpBaZWQYKOyXgT|SRGK+yz%t< zJO3N{9X7yYUf$oxB-LribGxwAyG}-?e%K0eFcc zwl4w}^Y!OnkDjVMP7CXehmI2sPHWkPh}6eLfeZJED2a5ll7BY__sBEOxb`7v5y69Rm2I!&HFWL1l0U za>c65iFe9eKY=`DKjmvBzaQmBx`#CAU5@LV)zJwSaG zeHVh_oi2f#Lk%Pzx+K@A!3rc@Y75vd`5 zU}R=yVqlu+AfwL0mYbTJUsTD&z)_r%U0jk_RKmc@!^p;UoSA78GZR}qQ=Jo&0K>$C z(>OW3Ssa|21q2u;Co}Fd2D7BNfk1&>fulu{ofRsgz~so7rO3p?2$W$|VANz5P+)iB eXmjFgnH*V-QX~`r delta 278 zcmYL^u}T9$5QgWU-Rv&e6SlE1D(sc^A_+FxgA`($-ULje9Fp823UaYHtPKY~g}#E| zYxn|!&mibt5N?WZhM8{$=2iWuG0lq{M1);ALxpO_)t2j)M7$?)hhd!G;$q8VLaa{+ zLJB6a867NoDqrL`t9vF>TwWLDd{vT4p!&~JjL1{?#WI*PkL>Y3+;lmS-qfk?bxqF!S1Bj3Hb}3X bOtpu{k#Jr&34h|S`QqV@Y5yk@-!Yp%wmmag diff --git a/test/wasm/token.wasm b/test/wasm/token.wasm index c1479277216b2078f4501daf85eef3f79d4675d9..1dca64312a4b0730812930ccba725f896bc83a3b 100644 GIT binary patch literal 5789 zcmb_gO>9)h9skd~dF$OB8-_p#v59%Rkkq6E913=5sOni2Ql%|P+cZ~ucfB-g?|Q@T zVju#qB`D>`;tv5#`eq9G>TeHMZn;&rT>;t1AFtVz^CL!#_x>f#u%by0RSvlM`4lB8G`vw&2<72tjh z^c5$$0tp$c-v(sa$y^pwSf3Y%-5v6S{S!H*G75Vk@-&pqN(dB6gkd-&hcY2a{3r+l z9R`9#M$4YCq}^@k&tgZuzEtnl%Z>U+HF_~uZZulw%1hN6?FORSo^=3vIX_?PZ@x8D zDK{L={#@t7+R}Wv(x}n?eEDqmgH{`I=IPt&{OMYoCUg9lJ>70K>9DGtZ7cnzSN~Rat<<&4IRrueZ5(3bm+Tksobp5o0-mqW~J4j zqlZgVTlR~pa?cuRC*NUmM{}!m@KPH8S7L(SQ<~!F8j7zS#Xr_iyvY=?7h3B`Md6hJgbiLO z$YH^lQubWSMA+L)2(DT{ z#C9(f<@c$mtm)dV3--e^#Srq~qKv{t``|&aU{_Z!p0Q@R7_#GUkIj%JPF@%9L6I%B@GD7LQ#}xIsi}PANpM(diF-&UB3*>Xi@G5 z85zYvh~iC{z(pD^Ot=-cl&C}|qqE>b9LDr1NRERHv-C-r@da&^jxXpf6=&_H)oap` z{WZ%(b!t7@&luAu#SIIyk4EM6VOJ35r2^aZQUPw8@dDbx>~WCsNWKrmo+1$Mv)w-( z)6;@mX+xF(*%4;EC@&V-OZna{W{!f37vcDygpj>R`Y@O%E}gsNsw0UoiqYiFXd&Qx zQALWQEKn_)vl2vsi@F2HAOH&F(gLI8=vF;Qkz-C$6mK|1v6w_`=ya_EayNMvr_(EA zKw6ppt&kz!1|?~R3n7Y^xOgQOuR!slppxQMT)Y81QR|9V0jdVYtJ1|QP`u=eS90;9 zz`1zcBa4UP;w4|al8YA=#$lo;bPxS$ATuz}j1)3SXF2174Ld7%s?G`qo#l)Z>pClw z>MSIEIxr}X3?9J@Z2nwNNWviY(-!SxQov;7V&K|4+RfZsrRZu&T`^l&4j2~-I{VsS#^ZgAjmK zcO-vCpk#+eAJG%sZhVd(iUGWyUX|H(d8$!ajKK)+O}qHSt8InlZF1rfA&PcU)gP9~k_Kx8L5^ zX6G~8Kh3lFE4(xOtH&>S77KPVY4mu*GdCW&8AeX%60?7t_v{!nR$y4T{W=-FD3M`y zg;r>$CD00;V@a=`IB`p#=jn}?1<&8U)A2A%OpJ$FQO55FMBR-sep_ISFd4+TndMmA zYvnPt7{9J;UWIV??!6xe+Dt%?=$o=Cc&;M;41C2L;3bG>1@_`<+j)V~p#s@57zMNYtXQA$>d+A8Z(TE@FI7 zyw1f7H4^uOtPD?9Go5%S?OpbeYn^iewCkfJPrh>;Mxb-_fmrFr>1IEmjPKuplE(yq zEtJl}BoNGWIqoqG$_)w%lg52;1?Kq@{VdL)`*!uQ=5W5|5_kWZ69*&ymNfe2+9ZEI z-n5E8a<8neu439k|E{ruk~8V{TKiU2uJkdp2OZac<9eKSGp(Q;L8Qsc)hko_d9Ulc_294<=@{I%#Dm1&8pRKsf;gg)+$~0MAr+{m+^v^u* zc1~|++%T@6(*@uvu%bcskHEvmzvT4ujNgK*&_CmQQG#T zc`c5Uy`9(icaCTRSK@0G^17gF!Ji1L7XBjWE`$4*Y~w#Y?|<_8W#%2nwE}z{HXZ^^ z7xxbCXR$wsCp`X4JF9PNJ;oe6aB;M%pq_Qs`xx6VJ>5M$uzlV|Zw=M;VV|erL5#bQ z#1ZJwY0$TkCD3q|h6gdOz@oOxk>|gc;;%aY&cWg`tXf2lM!b%ZfsPI&cb&aHn)Y+h zu#S;|4qpXb)Pd)}H!|>Kz@Jph__k_msoO4ByS1g|X02OZo0=ZI1u^__a+oYrZnnS*$ngG~lG{JrflT&=f3iOB zo*Vg>Is$SuPr{QvDq^Nb@g#7j@h3`;_EUCSOxDlKX0b~hOF5pTK8Duil9B84^fY?> zkr(3Uv^*?pQyT~8WR5$@?~~ZLncQsu%xw_MjrwQ3-q6~|8q;VbF&-FmBhBek)(%kt)}fyW({K*m!2=_xzor0 E50acpiU0rr literal 5656 zcmb_gOKcm*8UAN>ms)Zpd*mo_EjjLzb}XlLZRI7`NQ-LN#Aur|vD?5`X+_ZqB~r9V zT7J|P4a5k1FwmkvfgGKaFZSJs9Nb$EIrtJFC{nb&`Ot%JDS`s-_s{H-D_RfR2?_4b z%>Vt5`5!aGp}5@;L?qtXF(=p7#M+$ThqsotyK{s-NMr|T&IgGhvTM;@M-`0gf|=%s zx8#)qJ>hbycxUxi3VY}Ly zWeN0(->5Bj=+(R(SwM$g3!%Q&i0f^7-CvFyReB@WzSx*=)@eG|s5Y9di;}|j!cw~v zw>oreSdtAh|D9gV!~fXqI@;^=nq!j_Ge749O_X`;|dtjVb~pj{7-18HpOkkm%3n!-C-CT}K^8S1b6_5Jt#uIUC5MG~?Xj|x&HVZNnzBVnfATLIWF z=RPS0Wh(j@ViW&KC;XYRDEfgLD0$}iZzIo4z0Yuqxl=xJB}@N1G2pM1MZB>N@vTMt zdmZ9UM)YT|l#2W)xVCPP&0Z|ZVWE`qBVUiIw}ea| z!E-JujPMe~L$HD<$IZ<=T9RA$xaDz6mI>4Oix5F~KOrdoB0Rl!u_S*%CEw_d*|})W zu9O1Egg5%qS4#nV>o*fKWQc{&o;ekQ3%=N`-i5uX>u(vaAH5BSHwcPN(%=LKSDlquAQ5-HX8@?fBC6u?;e3&; z7(fdhM)Gvgdz`{U`4YTxnyo)Ip;iRf;-CQ9T-^pjC4`10d3hsK*h}&Q)W6P0-sQ`1 z+?PVgZiHlEH|p_T8U{&{r9pxNbV0vR^!Qmqt#F_Ol1_18y~wkHv%|>{28v{Zj2X%C zoyrBAqimVeC?_3`av~-b8(3WfgIvXq#p-m*cp$4xeI{gp-O5#g9xeu`0pc2vTmu3% zfV@m=z~>r(CnJBL27HYA{TlGIH6Ty}&unohwMPKZ_@wtKN;=l9@cjn(X#24i6|lOnmV0yZYc5FG2spa+$2Y zw#msUY$hj5P150|CRu562%#>jGPD1w;MjR}5J+&_ACS?FQW<(IFv9K_1gub+47MM` z3(5Y8J6Np$0GZfYHY>%{*rXIoGFc#z9kvL0xkM2#EUmcSq_)GVpJU%+L)=2g+sshv zd0m7mk%>v~Jb`UPAR;fR{p^$sZ!YDM7Bsh zX{$%-Lv9&RhwU6;&TgzUnac-X@9^pEiNpitsD$!hUV6&_2cEX{qM zGGx1$d9G&DsJJS%+nqp_s@D?To92RD5)Rtu;bd~#J4SFpT66$&CKdTQ!_)oT;Qcmhl@$vXgv9&|^LhY-L!A zE!&=XioTr5mgf3h#J9zQ6JNhtdpnGyDZ8;0eG9;$P>%C4l1n1*+~IO~io^ zVQ%a=fHT!MKDNpmp%RD5d>X1ff{1qEXQ+;Elg?92%T%E%na_dROXhE(8f8?$q86w@ zH6YB_PR4^!?PjXR?=5guKy5%qo!Zcow-P?htDTGq@p})n21~!~Xm|7KIi?Nc_j|es z+B~eNllcO4*!WdmJ;T!sj3Ts}_(sqkga1Re@;{FEzXkOY^X|iM4fGnUJPJ$)&o-Xt z&_9AV=6qXOyYH&LRqU?{(6iQl=VkM?!#&907OejUa5sistcLr3?m!lMp-pGN(L$tv z;Ybbl{X7qwS~gCO|3QYoVrO_BHpj4Q32_>6I!5|B+K}9_7CVoc&w*hbBYhn%6FSHR z$NylYpHF@MG-LLSR+`J5R$S>+mscCrPP{q=Z>FCY>6`qH6o7yGm37qYGf$*km(qXr+)c+45@qft?2t?dzP(-`>glm}61aW9hsRh~ zjyuUGd#}MmxHz$&?c^{h7dM*ca5-Vy_St`AuSj_G`;yzcZGp_xZ?d*v6>l`Z%$Z6DdCVi}TElG~&#o`ob*D%FKN^h>SpWb4