Skip to content

Commit

Permalink
add support for soroban prev. 11
Browse files Browse the repository at this point in the history
  • Loading branch information
christian-rogobete committed Sep 17, 2023
1 parent 9707d6e commit 83f3e37
Show file tree
Hide file tree
Showing 20 changed files with 570 additions and 636 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
## [1.6.3] - 17.Sep.2023.
- support for soroban prev 11

## [1.6.2] - 24.Aug.2023.
- anchor handling improvements
- preparations for web support
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.6.2
stellar_flutter_sdk: ^1.6.3
```
2. Install it (command line or IDE):
```
Expand All @@ -30,7 +30,7 @@ print("sequence number: ${account.sequenceNumber}");

### Manual

Add the SDK is a Flutter Dart plugin. Here is a step by step that we recommend:
The SDK is a Flutter Dart package. Here is a step by step that we recommend:

1. Clone this repo.
2. Open the project in your IDE (e.g. Android Studio).
Expand Down
Binary file modified documentation/sdk_api_doc.zip
Binary file not shown.
46 changes: 13 additions & 33 deletions lib/src/invoke_host_function_operation.dart
Original file line number Diff line number Diff line change
Expand Up @@ -30,26 +30,14 @@ abstract class HostFunction {
break;
case XdrHostFunctionType.HOST_FUNCTION_TYPE_INVOKE_CONTRACT:
if (xdr.invokeContract != null) {
List<XdrSCVal> invokeArgsList = xdr.invokeContract!;
if (invokeArgsList.length < 2 ||
invokeArgsList.elementAt(0).discriminant !=
XdrSCValType.SCV_ADDRESS ||
invokeArgsList.elementAt(0).address?.contractId == null ||
invokeArgsList.elementAt(1).discriminant !=
XdrSCValType.SCV_SYMBOL ||
invokeArgsList.elementAt(1).sym == null) {
XdrInvokeContractArgs invokeArgs = xdr.invokeContract!;
if (invokeArgs.contractAddress.contractId == null) {
throw UnimplementedError();
}
String contractID = Util.bytesToHex(
invokeArgsList.elementAt(0).address!.contractId!.hash);
String functionName = invokeArgsList.elementAt(1).sym!;
List<XdrSCVal>? funcArgs;
if (invokeArgsList.length > 2) {
funcArgs = List<XdrSCVal>.empty(growable: true);
for (int i = 2; i < invokeArgsList.length; i++) {
funcArgs.add(invokeArgsList[i]);
}
}
String contractID =
Util.bytesToHex(invokeArgs.contractAddress.contractId!.hash);
String functionName = invokeArgs.functionName;
List<XdrSCVal> funcArgs = invokeArgs.args;
return InvokeContractHostFunction(contractID, functionName,
arguments: funcArgs);
}
Expand Down Expand Up @@ -181,24 +169,16 @@ class InvokeContractHostFunction extends HostFunction {

@override
XdrHostFunction toXdr() {
List<XdrSCVal> invokeArgsList = List<XdrSCVal>.empty(growable: true);

// contract id
XdrSCVal contractIDScVal =
Address.forContractId(this._contractID).toXdrSCVal();
invokeArgsList.add(contractIDScVal);
List<XdrSCVal> fcArgs = List<XdrSCVal>.empty(growable: true);

// function name
XdrSCVal functionNameScVal = XdrSCVal(XdrSCValType.SCV_SYMBOL);
functionNameScVal.sym = this._functionName;
invokeArgsList.add(functionNameScVal);

// arguments for the function call
if (this.arguments != null) {
invokeArgsList.addAll(this.arguments!);
fcArgs.addAll(this.arguments!);
}

return XdrHostFunction.forInvokingContractWithArgs(invokeArgsList);
XdrInvokeContractArgs args = XdrInvokeContractArgs(
Address.forContractId(this._contractID).toXdr(),
this._functionName,
fcArgs);
return XdrHostFunction.forInvokingContractWithArgs(args);
}
}

Expand Down
72 changes: 18 additions & 54 deletions lib/src/soroban/soroban_auth.dart
Original file line number Diff line number Diff line change
Expand Up @@ -102,25 +102,19 @@ class SorobanAddressCredentials {
Address address;
int nonce;
int signatureExpirationLedger;
List<XdrSCVal> signatureArgs = List<XdrSCVal>.empty(growable: true);
XdrSCVal signature;

SorobanAddressCredentials(
this.address, this.nonce, this.signatureExpirationLedger,
{List<XdrSCVal>? signatureArgs}) {
if (signatureArgs != null) {
this.signatureArgs = signatureArgs;
}
}
this.address, this.nonce, this.signatureExpirationLedger, this.signature);

static SorobanAddressCredentials fromXdr(XdrSorobanAddressCredentials xdr) {
return SorobanAddressCredentials(Address.fromXdr(xdr.address),
xdr.nonce.int64, xdr.signatureExpirationLedger.uint32,
signatureArgs: xdr.signaturArgs);
xdr.nonce.int64, xdr.signatureExpirationLedger.uint32, xdr.signature);
}

XdrSorobanAddressCredentials toXdr() {
return new XdrSorobanAddressCredentials(address.toXdr(), XdrInt64(nonce),
XdrUint32(signatureExpirationLedger), signatureArgs);
XdrUint32(signatureExpirationLedger), signature);
}
}

Expand All @@ -137,12 +131,10 @@ class SorobanCredentials {
return SorobanCredentials();
}

static SorobanCredentials forAddress(
Address address, int nonce, int signatureExpirationLedger,
{List<XdrSCVal>? signatureArgs}) {
static SorobanCredentials forAddress(Address address, int nonce,
int signatureExpirationLedger, XdrSCVal signature) {
SorobanAddressCredentials addressCredentials = SorobanAddressCredentials(
address, nonce, signatureExpirationLedger,
signatureArgs: signatureArgs);
address, nonce, signatureExpirationLedger, signature);
return SorobanCredentials(addressCredentials: addressCredentials);
}

Expand Down Expand Up @@ -172,37 +164,12 @@ class SorobanCredentials {
}
}

class SorobanAuthorizedContractFunction {
Address contractAddress;
String functionName;
List<XdrSCVal> args = List<XdrSCVal>.empty(growable: true);

SorobanAuthorizedContractFunction(this.contractAddress, this.functionName,
{List<XdrSCVal>? args}) {
if (args != null) {
this.args = args;
}
}

static SorobanAuthorizedContractFunction fromXdr(
XdrSorobanAuthorizedContractFunction xdr) {
return SorobanAuthorizedContractFunction(
Address.fromXdr(xdr.contractAddress), xdr.functionName,
args: xdr.args);
}

XdrSorobanAuthorizedContractFunction toXdr() {
return XdrSorobanAuthorizedContractFunction(
contractAddress.toXdr(), functionName, args);
}
}

class SorobanAuthorizedFunction {
SorobanAuthorizedContractFunction? contractFn;
XdrInvokeContractArgs? contractFn;
XdrCreateContractArgs? createContractHostFn;

SorobanAuthorizedFunction(
{SorobanAuthorizedContractFunction? contractFn,
{XdrInvokeContractArgs? contractFn,
XdrCreateContractArgs? createContractHostFn}) {
if (contractFn == null && createContractHostFn == null) {
throw ArgumentError("invalid arguments");
Expand All @@ -215,11 +182,9 @@ class SorobanAuthorizedFunction {
}

static SorobanAuthorizedFunction forContractFunction(
Address contractAddress, String functionName,
{List<XdrSCVal>? args}) {
SorobanAuthorizedContractFunction cfn = SorobanAuthorizedContractFunction(
contractAddress, functionName,
args: args);
Address contractAddress, String functionName, List<XdrSCVal> args) {
XdrInvokeContractArgs cfn =
XdrInvokeContractArgs(contractAddress.toXdr(), functionName, args);
return SorobanAuthorizedFunction(contractFn: cfn);
}

Expand All @@ -235,8 +200,7 @@ class SorobanAuthorizedFunction {
.SOROBAN_AUTHORIZED_FUNCTION_TYPE_CONTRACT_FN &&
xdr.contractFn != null) {
return SorobanAuthorizedFunction(
contractFn:
SorobanAuthorizedContractFunction.fromXdr(xdr.contractFn!));
contractFn:xdr.contractFn!);
} else {
return SorobanAuthorizedFunction(
createContractHostFn: xdr.createContractHostFn);
Expand All @@ -248,7 +212,7 @@ class SorobanAuthorizedFunction {
XdrSorobanAuthorizedFunction cfn = XdrSorobanAuthorizedFunction(
XdrSorobanAuthorizedFunctionType
.SOROBAN_AUTHORIZED_FUNCTION_TYPE_CONTRACT_FN);
cfn.contractFn = contractFn!.toXdr();
cfn.contractFn = contractFn!;
return cfn;
}
XdrSorobanAuthorizedFunction cfn = XdrSorobanAuthorizedFunction(
Expand Down Expand Up @@ -323,8 +287,7 @@ class SorobanAuthorizationEntry {
}

/// Signs the authorization entry.
///
/// The signature will be added to the [signatureArgs] of the soroban credentials
/// The signature will be set to the soroban credentials
void sign(KeyPair signer, Network network) {
XdrSorobanCredentials xdrCredentials = credentials.toXdr();
if (credentials.addressCredentials == null ||
Expand All @@ -349,7 +312,7 @@ class SorobanAuthorizationEntry {
Uint8List signatureBytes = signer.sign(payload);
AccountEd25519Signature signature =
AccountEd25519Signature(signer.xdrPublicKey, signatureBytes);
credentials.addressCredentials!.signatureArgs.add(signature.toXdrSCVal());
credentials.addressCredentials!.signature = signature.toXdrSCVal();
}
}

Expand All @@ -367,6 +330,7 @@ class AccountEd25519Signature {
XdrSCMapEntry(XdrSCVal.forSymbol("public_key"), pkVal);
XdrSCMapEntry sigEntry =
XdrSCMapEntry(XdrSCVal.forSymbol("signature"), sigVal);
return XdrSCVal.forMap([pkEntry, sigEntry]);
XdrSCVal map = XdrSCVal.forMap([pkEntry, sigEntry]);
return XdrSCVal.forVec([map]);
}
}
46 changes: 41 additions & 5 deletions lib/src/soroban/soroban_server.dart
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ class SorobanServer {
Future<XdrContractCodeEntry?> loadContractCodeForWasmId(String wasmId) async {
XdrLedgerKey ledgerKey = XdrLedgerKey(XdrLedgerEntryType.CONTRACT_CODE);
ledgerKey.contractCode = XdrLedgerKeyContractCode(
XdrHash(Util.hexToBytes(wasmId)), XdrContractEntryBodyType.DATA_ENTRY);
XdrHash(Util.hexToBytes(wasmId)));
GetLedgerEntryResponse ledgerEntryResponse =
await getLedgerEntry(ledgerKey.toBase64EncodedXdrString());
if (ledgerEntryResponse.ledgerEntryData != null) {
Expand All @@ -120,8 +120,7 @@ class SorobanServer {
ledgerKey.contractData = XdrLedgerKeyContractData(
Address.forContractId(contractId).toXdr(),
XdrSCVal.forLedgerKeyContractInstance(),
XdrContractDataDurability.PERSISTENT,
XdrContractEntryBodyType.DATA_ENTRY);
XdrContractDataDurability.PERSISTENT);

GetLedgerEntryResponse ledgerEntryResponse =
await getLedgerEntry(ledgerKey.toBase64EncodedXdrString());
Expand All @@ -131,10 +130,10 @@ class SorobanServer {
ledgerEntryResponse.ledgerEntryData!);
if (ledgerEntryData.contractData != null &&
ledgerEntryData
.contractData?.body.data?.val.instance?.executable.wasmHash !=
.contractData?.val.instance?.executable.wasmHash !=
null) {
String wasmId = Util.bytesToHex(ledgerEntryData
.contractData!.body.data!.val.instance!.executable.wasmHash!.hash);
.contractData!.val.instance!.executable.wasmHash!.hash);
return await (loadContractCodeForWasmId(wasmId));
}
}
Expand Down Expand Up @@ -391,6 +390,33 @@ class GetNetworkResponse extends SorobanRpcResponse {
}
}

/// It can only present on successful simulation (i.e. no error) of InvokeHostFunction operations.
/// If present, it indicates the simulation detected expired ledger entries which requires restoring
/// with the submission of a RestoreFootprint operation before submitting the InvokeHostFunction operation.
/// The minResourceFee and transactionData fields should be used to construct the transaction
/// containing the RestoreFootprint operation.
class RestorePreamble {

/// The recommended Soroban Transaction Data to use when submitting the RestoreFootprint operation.
XdrSorobanTransactionData transactionData;

/// Recommended minimum resource fee to add when submitting the RestoreFootprint operation. This fee is to be added on top of the Stellar network fee.
int minResourceFee;


RestorePreamble(this.transactionData, this.minResourceFee);

factory RestorePreamble.fromJson(Map<String, dynamic> json) {

XdrSorobanTransactionData transactionData = XdrSorobanTransactionData.fromBase64EncodedXdrString(
json['transactionData']);

int minResourceFee = convertInt(json['minResourceFee'])!;
return RestorePreamble(transactionData, minResourceFee);
}

}

/// Response that will be received when submitting a trial contract invocation.
/// See: https://soroban.stellar.org/api/methods/simulateTransaction
class SimulateTransactionResponse extends SorobanRpcResponse {
Expand All @@ -413,6 +439,12 @@ class SimulateTransactionResponse extends SorobanRpcResponse {
/// Array of the events emitted during the contract invocation(s). The events are ordered by their emission time. (an array of serialized base64 strings representing XdrDiagnosticEvent)
List<String>? events;

/// t can only present on successful simulation (i.e. no error) of InvokeHostFunction operations. If present, it indicates
/// the simulation detected expired ledger entries which requires restoring with the submission of a RestoreFootprint
/// operation before submitting the InvokeHostFunction operation. The restorePreamble.minResourceFee and restorePreamble.transactionData fields should
/// be used to construct the transaction containing the RestoreFootprint
RestorePreamble? restorePreamble;

SimulateTransactionResponse(Map<String, dynamic> jsonResponse)
: super(jsonResponse);

Expand Down Expand Up @@ -448,6 +480,10 @@ class SimulateTransactionResponse extends SorobanRpcResponse {
response.events = List<String>.from(json['events'].map((e) => e));
}

if (json['restorePreamble'] != null) {
response.restorePreamble = RestorePreamble.fromJson(json['restorePreamble']);
}

response.minResourceFee = convertInt(json['result']['minResourceFee']);
} else if (json['error'] != null) {
response.error = SorobanRpcErrorResponse.fromJson(json);
Expand Down
2 changes: 1 addition & 1 deletion lib/src/stellar_sdk.dart
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ import 'requests/liquidity_pools_request_builder.dart';

/// Main class of the flutter stellar sdk.
class StellarSDK {
static const versionNumber = "1.6.2";
static const versionNumber = "1.6.3";

static final StellarSDK PUBLIC = StellarSDK("https://horizon.stellar.org");
static final StellarSDK TESTNET = StellarSDK("https://horizon-testnet.stellar.org");
Expand Down
Loading

0 comments on commit 83f3e37

Please sign in to comment.