Skip to content

Commit 9707d6e

Browse files
anchor handling improvements
1 parent 9a3c06e commit 9707d6e

26 files changed

+229
-136
lines changed

CHANGELOG.md

+4
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
## [1.6.2] - 24.Aug.2023.
2+
- anchor handling improvements
3+
- preparations for web support
4+
-
15
## [1.6.1] - 27.Jul.2023.
26
- xdr fixes: XdrSCNoceKey, data_io
37
- soroban contract source code loading

README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ The Soneso open source Stellar SDK for Flutter is build with Dart and provides A
1111
1. Add the dependency to your pubspec.yaml file:
1212
```
1313
dependencies:
14-
stellar_flutter_sdk: ^1.6.1
14+
stellar_flutter_sdk: ^1.6.2
1515
```
1616
2. Install it (command line or IDE):
1717
```

documentation/sdk_api_doc.zip

-5.55 MB
Binary file not shown.

lib/src/muxed_account.dart

-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
// found in the LICENSE file.
44

55
import 'key_pair.dart';
6-
import 'util.dart';
76
import 'xdr/xdr_type.dart';
87
import 'xdr/xdr_account.dart';
98
import 'xdr/xdr_data_io.dart';

lib/src/requests/liquidity_pools_request_builder.dart

-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ import '../responses/liquidity_pool_response.dart';
99
import 'dart:async';
1010
import '../responses/response.dart';
1111
import 'request_builder.dart';
12-
import '../util.dart';
1312

1413
class LiquidityPoolsRequestBuilder extends RequestBuilder {
1514
static const String RESERVES_PARAMETER_NAME = "reserves";

lib/src/responses/offer_response.dart

-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44

55
import 'response.dart';
66
import '../assets.dart';
7-
import '../key_pair.dart';
87

98
/// Represents an offer response received from the horizon server. Offers are statements about how much of an asset an account wants to buy or sell.
109
/// See: <a href="https://developers.stellar.org/api/resources/offers/" target="_blank">Offer documentation</a>

lib/src/responses/order_book_response.dart

-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
import 'response.dart';
66
import '../assets.dart';
77
import '../price.dart';
8-
import '../util.dart';
98

109
/// Represents an order book response received from the horizon server. An order book is a collections of offers for a specific pair of assets.
1110
/// See: <a href="https://developers.stellar.org/api/aggregations/order-books/" target="_blank">Order book documentation</a>

lib/src/sep/0001/stellar_toml.dart

+4
Original file line numberDiff line numberDiff line change
@@ -227,6 +227,7 @@ class StellarToml {
227227
currency.isAssetAnchored = item['is_asset_anchored'];
228228
currency.anchorAssetType = item['anchor_asset_type'];
229229
currency.anchorAsset = item['anchor_asset'];
230+
currency.attestationOfReserve = item['attestation_of_reserve'];
230231
currency.redemptionInstructions = item['redemption_instructions'];
231232

232233
var collateralAddresses = item['collateral_addresses'];
@@ -438,6 +439,9 @@ class Currency {
438439
/// If anchored token, code / symbol for asset that token is anchored to. E.g. USD, BTC, SBUX, Address of real-estate investment property.
439440
String? anchorAsset;
440441

442+
/// URL to attestation or other proof, evidence, or verification of reserves, such as third-party audits.
443+
String? attestationOfReserve;
444+
441445
/// If anchored token, these are instructions to redeem the underlying asset from tokens.
442446
String? redemptionInstructions;
443447

lib/src/sep/0009/standard_kyc_fields.dart

+2-1
Original file line numberDiff line numberDiff line change
@@ -280,7 +280,7 @@ class OrganizationKYCFields {
280280
/// Organization contact phone
281281
String? phone;
282282

283-
Map<String, String>? fields() {
283+
Map<String, String> fields() {
284284
final fields = <String, String>{};
285285
if (name != null) {
286286
fields['organization.name'] = name!;
@@ -324,6 +324,7 @@ class OrganizationKYCFields {
324324
if (phone != null) {
325325
fields['organization.phone'] = phone!;
326326
}
327+
return fields;
327328
}
328329

329330
Map<String, Uint8List> files() {

lib/src/sep/0010/webauth.dart

+81-23
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,11 @@ import '../../xdr/xdr_transaction.dart';
2121
import '../0001/stellar_toml.dart';
2222

2323
class WebAuth {
24-
String? _authEndpoint;
25-
String? _serverSigningKey;
26-
Network? _network;
27-
String? _serverHomeDomain;
28-
http.Client httpClient = new http.Client();
24+
String _authEndpoint;
25+
String _serverSigningKey;
26+
Network _network;
27+
String _serverHomeDomain;
28+
late http.Client httpClient;
2929
int gracePeriod = 60 * 5;
3030

3131
/// Constructor
@@ -34,7 +34,13 @@ class WebAuth {
3434
/// - Parameter serverSigningKey: The server public key, taken from stellar.toml.
3535
/// - Parameter serverHomeDomain: The server home domain of the server where the stellar.toml was loaded from
3636
WebAuth(this._authEndpoint, this._network, this._serverSigningKey,
37-
this._serverHomeDomain);
37+
this._serverHomeDomain, {http.Client? httpClient}) {
38+
if (httpClient != null) {
39+
this.httpClient = httpClient;
40+
} else {
41+
this.httpClient = http.Client();
42+
}
43+
}
3844

3945
/// Creates a WebAuth instance by loading the needed data from the stellar.toml file hosted on the given domain.
4046
/// e.g. fromDomain("soneso.com", Network.TESTNET)
@@ -51,14 +57,14 @@ class WebAuth {
5157
);
5258

5359
if (toml.generalInformation.webAuthEndpoint == null) {
54-
throw Exception("No WEB_AUTH_ENDPOINT found in stellar.toml");
60+
throw NoWebAuthEndpointFoundException(domain);
5561
}
5662
if (toml.generalInformation.signingKey == null) {
57-
throw Exception("No auth server SIGNING_KEY found in stellar.toml");
63+
throw NoWebAuthServerSigningKeyFoundException(domain);
5864
}
5965

60-
return new WebAuth(toml.generalInformation.webAuthEndpoint, network,
61-
toml.generalInformation.signingKey, domain);
66+
return new WebAuth(toml.generalInformation.webAuthEndpoint!, network,
67+
toml.generalInformation.signingKey!, domain, httpClient: httpClient);
6268
}
6369

6470
/// Get JWT token for wallet.
@@ -85,13 +91,12 @@ class WebAuth {
8591
clientDomainAccountId = clientDomainAccountKeyPair.accountId;
8692
} else if (clientDomainSigningDelegate != null) {
8793
if (clientDomain == null) {
88-
throw Exception(
89-
"The clientDomain is required if clientDomainSigningDelegate is provided");
94+
throw MissingClientDomainException();
9095
}
9196
final StellarToml clientToml =
9297
await StellarToml.fromDomain(clientDomain, httpClient: httpClient);
9398
if (clientToml.generalInformation.signingKey == null) {
94-
throw Exception("No client domain SIGNING_KEY found in stellar.toml");
99+
throw NoClientDomainSigningKeyFoundException(clientDomain);
95100
}
96101
clientDomainAccountId = clientToml.generalInformation.signingKey;
97102
}
@@ -128,7 +133,7 @@ class WebAuth {
128133

129134
String? transaction = challengeResponse.transaction;
130135
if (transaction == null) {
131-
throw Exception("Error parsing challenge response");
136+
throw MissingTransactionInChallengeResponseException();
132137
}
133138
return transaction;
134139
}
@@ -203,13 +208,13 @@ class WebAuth {
203208
}
204209
}
205210

206-
if (i == 0 && dataName != _serverHomeDomain! + " auth") {
211+
if (i == 0 && dataName != _serverHomeDomain + " auth") {
207212
throw ChallengeValidationErrorInvalidHomeDomain(
208213
"invalid home domain in operation $i");
209214
}
210215
final dataValue = op.body.manageDataOp!.dataValue!.dataValue;
211216
if (i > 0 && dataName == "web_auth_domain") {
212-
final uri = Uri.parse(_authEndpoint!);
217+
final uri = Uri.parse(_authEndpoint);
213218
if (uri.host != String.fromCharCodes(dataValue)) {
214219
throw ChallengeValidationErrorInvalidWebAuthDomain(
215220
"invalid web auth domain in operation $i");
@@ -240,9 +245,9 @@ class WebAuth {
240245
}
241246
final firstSignature = envelopeXdr.v1!.signatures[0];
242247
// validate signature
243-
final serverKeyPair = KeyPair.fromAccountId(_serverSigningKey!);
248+
final serverKeyPair = KeyPair.fromAccountId(_serverSigningKey);
244249
final transactionHash =
245-
AbstractTransaction.fromEnvelopeXdr(envelopeXdr).hash(_network!);
250+
AbstractTransaction.fromEnvelopeXdr(envelopeXdr).hash(_network);
246251
final valid = serverKeyPair.verify(
247252
transactionHash, firstSignature.signature!.signature!);
248253
if (!valid) {
@@ -260,7 +265,7 @@ class WebAuth {
260265
}
261266

262267
final txHash =
263-
AbstractTransaction.fromEnvelopeXdr(envelopeXdr).hash(_network!);
268+
AbstractTransaction.fromEnvelopeXdr(envelopeXdr).hash(_network);
264269

265270
List<XdrDecoratedSignature> signatures =
266271
List<XdrDecoratedSignature>.empty(growable: true);
@@ -276,7 +281,7 @@ class WebAuth {
276281
/// In case of success, it returns the jwt token obtained from the web auth server.
277282
Future<String> sendSignedChallengeTransaction(
278283
String base64EnvelopeXDR) async {
279-
Uri serverURI = Uri.parse(_authEndpoint!);
284+
Uri serverURI = Uri.parse(_authEndpoint);
280285

281286
Map<String, String> headers = {...RequestBuilder.headers};
282287
headers.putIfAbsent("Content-Type", () => "application/json");
@@ -314,11 +319,10 @@ class WebAuth {
314319
Future<ChallengeResponse> getChallengeResponse(String accountId,
315320
[int? memo, String? homeDomain, String? clientDomain]) async {
316321
if (memo != null && accountId.startsWith("M")) {
317-
throw new Exception(
318-
"memo cannot be used if accountId is a muxed account");
322+
throw NoMemoForMuxedAccountsException();
319323
}
320324

321-
Uri serverURI = Uri.parse(_authEndpoint!);
325+
Uri serverURI = Uri.parse(_authEndpoint);
322326
try {
323327
_ChallengeRequestBuilder requestBuilder =
324328
new _ChallengeRequestBuilder(httpClient, serverURI);
@@ -500,3 +504,57 @@ class SubmitCompletedChallengeErrorResponseException implements Exception {
500504

501505
String get error => _error;
502506
}
507+
508+
class NoWebAuthEndpointFoundException implements Exception {
509+
String domain;
510+
511+
NoWebAuthEndpointFoundException(this.domain);
512+
513+
String toString() {
514+
return "No WEB_AUTH_ENDPOINT found in stellar.toml for domain: $domain";
515+
}
516+
}
517+
518+
class NoWebAuthServerSigningKeyFoundException implements Exception {
519+
String domain;
520+
521+
NoWebAuthServerSigningKeyFoundException(this.domain);
522+
523+
String toString() {
524+
return "No auth server SIGNING_KEY found in stellar.toml for domain: $domain";
525+
}
526+
}
527+
528+
class NoClientDomainSigningKeyFoundException implements Exception {
529+
String domain;
530+
531+
NoClientDomainSigningKeyFoundException(this.domain);
532+
533+
String toString() {
534+
return "No client domain SIGNING_KEY found in stellar.toml for domain: $domain";
535+
}
536+
}
537+
538+
class MissingClientDomainException implements Exception {
539+
MissingClientDomainException();
540+
541+
String toString() {
542+
return "The clientDomain is required if clientDomainSigningDelegate is provided";
543+
}
544+
}
545+
546+
class MissingTransactionInChallengeResponseException implements Exception {
547+
MissingTransactionInChallengeResponseException();
548+
549+
String toString() {
550+
return "Missing transaction in challenge response";
551+
}
552+
}
553+
554+
class NoMemoForMuxedAccountsException implements Exception {
555+
NoMemoForMuxedAccountsException();
556+
557+
String toString() {
558+
return "Memo cannot be used if account is a muxed account";
559+
}
560+
}

0 commit comments

Comments
 (0)