From 3836bf02dde7f287913db933a862203f2f41a2a9 Mon Sep 17 00:00:00 2001 From: Christian Rogobete Date: Mon, 27 Nov 2023 18:52:06 +0100 Subject: [PATCH] update wallet docs for flutter (#262) --- .../wallet/component/dart/install.mdx | 13 ++ docs/building-apps/wallet/intro.mdx | 23 ++- docs/building-apps/wallet/sep10.mdx | 41 ++--- docs/building-apps/wallet/sep24.mdx | 170 +++++++++++------- 4 files changed, 157 insertions(+), 90 deletions(-) create mode 100644 docs/building-apps/wallet/component/dart/install.mdx diff --git a/docs/building-apps/wallet/component/dart/install.mdx b/docs/building-apps/wallet/component/dart/install.mdx new file mode 100644 index 000000000..44f98df16 --- /dev/null +++ b/docs/building-apps/wallet/component/dart/install.mdx @@ -0,0 +1,13 @@ +import { CodeExample } from "@site/src/components/CodeExample"; + + + +```dart +// pubspec.yaml +stellar_wallet_flutter_sdk: ^0.0.2 +stellar_flutter_sdk: ^1.6.9 +``` + + + +You can get the latest available version on the [project GitHub page](https://github.com/Soneso/stellar_wallet_flutter_sdk) diff --git a/docs/building-apps/wallet/intro.mdx b/docs/building-apps/wallet/intro.mdx index 9c07c7334..b0d4044c0 100644 --- a/docs/building-apps/wallet/intro.mdx +++ b/docs/building-apps/wallet/intro.mdx @@ -8,6 +8,7 @@ import { WalletCodeExample as CodeExample } from "@site/src/components/WalletCod import Header from "./component/header.mdx"; import KtInstall from "./component/kt/install.mdx"; import TsInstall from "./component/ts/install.mdx"; +import DartInstall from "./component/dart/install.mdx"; import KtHttpConfig from "./component/kt/httpConfig.mdx"; import KtConfigClient from "./component/kt/configClient.mdx"; import TsConfigClient from "./component/ts/configClient.mdx"; @@ -18,7 +19,11 @@ import TsConfigClient from "./component/ts/configClient.mdx"; First, you need to add the SDK dependency to your project. -} ts={} /> +} + ts={} + dart={} +/> ## Working with the SDK @@ -34,8 +39,8 @@ val wallet = Wallet(StellarConfiguration.Testnet) let wallet = walletSdk.Wallet.TestNet(); ``` -```flutter -final StellarSDK sdk = StellarSDK.TESTNET; +```dart +var wallet = Wallet(StellarConfiguration.testNet); ``` @@ -54,6 +59,10 @@ let wallet = new Wallet({ }); ``` +```dart +var wallet = Wallet(StellarConfiguration.publicNet); +``` + } /> @@ -102,6 +111,10 @@ val anchor = wallet.anchor("https://testanchor.stellar.org") let anchor = wallet.anchor({ homeDomain: "testanchor.stellar.org" }); ``` +```dart +var anchor = wallet.anchor("testanchor.stellar.org") +``` + And the most basic interaction of fetching a [SEP-1]: Stellar Info File: @@ -118,6 +131,10 @@ suspend fun anchorToml(): TomlInfo { let resp = await anchor.sep1(); ``` +```dart +var resp = await anchor.sep1(); +``` + The anchor class also supports [SEP-10]: Stellar Authentication and [SEP-24]: Hosted Deposit and Withdrawal features. diff --git a/docs/building-apps/wallet/sep10.mdx b/docs/building-apps/wallet/sep10.mdx index 4c698ed78..823604335 100644 --- a/docs/building-apps/wallet/sep10.mdx +++ b/docs/building-apps/wallet/sep10.mdx @@ -44,7 +44,7 @@ let anchor = wallet.anchor({ homeDomain: "https://testanchor.stellar.org" }); ``` ```dart -final webAuth = WebAuth.fromDomain("https://testanchor.stellar.org", Network.TESTNET); +final anchor = wallet.anchor("testanchor.stellar.org"); ``` @@ -69,9 +69,10 @@ const authToken = await sep10.authenticate({ accountKp: authKey }); ``` ```dart -KeyPair authKey = KeyPair.fromSecretSeed("my secret key"); -String accountId = authKey.accountId; -String jwtToken = await webAuth.jwtToken(accountId, [authKey]); +final authKey = SigningKeyPair.fromSecret("my secret key"); +final sep10 = await anchor.sep10(); + +final authToken = await sep10.authenticate(authKey); ``` @@ -140,25 +141,11 @@ const getAuthToken = async () => { ``` ```dart -// delegate client signing -String jwtToken = await webAuth.jwtToken( - userAccountId, - [userKeyPair], - clientDomain: "demo-wallet-server.stellar.org", - clientDomainSigningDelegate: (transaction) async { - // delegate client signing e.g.: - return myWalletSigner.signTransaction(transaction, clientKeyPair); - } -); - -// alternatively let the SDK also sign with the clientKeyPair -String jwtToken = await webAuth.jwtToken( - userAccountId, - [userKeyPair], - clientDomain: "demo-wallet-server.stellar.org", - clientDomainAccountKeyPair: clientKeyPair -); +final signer = DomainSigner("https://demo-wallet-server.stellar.org/sign"); +final sep10 = await anchor.sep10(); +final authToken = await sep10.authenticate(userKeyPair, + clientDomainSigner: signer, clientDomain: "demo-wallet-server.stellar.org"); ``` @@ -202,6 +189,16 @@ const demoWalletSigner: WalletSigner = { }; ``` +```dart +Map requestHeaders = { + "Authorization": "Bearer $token", + "Content-Type": "application/json" +}; + +var signer = DomainSigner("https://demo-wallet-server.stellar.org/sign", + requestHeaders: requestHeaders); +``` + [//]: # "TODO: update after WAL-882 is completed" diff --git a/docs/building-apps/wallet/sep24.mdx b/docs/building-apps/wallet/sep24.mdx index ff9d26b67..4a10cfc36 100644 --- a/docs/building-apps/wallet/sep24.mdx +++ b/docs/building-apps/wallet/sep24.mdx @@ -30,11 +30,7 @@ let sep24 = await anchor.sep24(); ``` ```dart -// By providing the domain hosting the stellar.toml file -final transferService = await TransferServerSEP24Service.fromDomain("place.domain.com"); - -// Or by providing the service url -final transferService = TransferServerSEP24Service("http://api.stellar-anchor.org/transfer"); +var sep24 = await anchor.sep24(); ``` @@ -56,7 +52,7 @@ const getAnchorServices = async (): Promise => { ``` ```dart -SEP24InfoResponse infoResponse = await transferService.info(); +final servicesInfo = await sep24.getServiceInfo(); ``` @@ -77,6 +73,10 @@ val asset = info.currencies.first { it.code == "USDC" }.assetId const asset = info.currencies.find(({ code }) => code === "USDC").assetId; ``` +```dart +var asset = info.currencies.firstWhere((it)=>it.code=='USDC').assetId; +``` + :::info @@ -103,11 +103,7 @@ let deposit = await anchor.sep24().deposit({ ``` ```dart -SEP24DepositRequest request = new SEP24DepositRequest(); -request.assetCode = "USDC"; -request.jwt = jwtToken; - -SEP24InteractiveResponse response = await transferService.deposit(request); +final deposit = sep24.deposit(asset, token) ``` @@ -129,8 +125,8 @@ let id = deposit.id; ``` ```dart -String url = response.url; -String id = response.id; +final url = deposit.url; +final id = deposit.id; ``` @@ -155,12 +151,9 @@ let id = withdrawal.id; ``` ```dart -SEP24WithdrawRequest request = new SEP24WithdrawRequest(); -request.assetCode = "USDC"; -request.type = "bank_account"; -request.jwt = jwtToken; - -SEP24InteractiveResponse response = await transferService.withdraw(request); +final withdrawal = sep24.withdraw(asset, token) +final url = withdrawal.url +final id = withdrawal.id ``` @@ -198,18 +191,8 @@ let deposit = await anchor.sep24().deposit({ ``` ```dart -SEP24DepositRequest request = new SEP24DepositRequest(); -request.assetCode = "USDC"; -request.jwt = jwtToken; - -StandardKYCFields kycFields = StandardKYCFields(); -kycFields.naturalPersonKYCFields = NaturalPersonKYCFields(); -kycFields.naturalPersonKYCFields!.emailAddress = "mail@example.com"; -kycFields.naturalPersonKYCFields!.photoIdFront = await Util.readFile(path); - -request.kycFields = kycFields; - -SEP24InteractiveResponse response = await transferService.deposit(request); +final deposit = await sep24.deposit(asset, token, + extraFields: {"email_address": "mail@example.com"}); ``` @@ -245,14 +228,9 @@ const depositDifferentAccount = async (): Promise => { ``` ```dart -SEP24DepositRequest request = new SEP24DepositRequest(); -request.assetCode = "USDC"; -request.account = "G..."; -request.memo = "my memo"; -request.memoType = "text"; -request.jwt = jwtToken; - -SEP24InteractiveResponse response = await transferService.deposit(request); +const recipientAccount = "G..."; +final deposit = await sep24.deposit(asset, token, destinationAccount: recipientAccount, + destinationMemo: "my memo", destinationMemoType: MemoType.text); ``` @@ -276,11 +254,8 @@ const withdrawal = await anchor.sep24().withdraw({ ``` ```dart -SEP24WithdrawRequest request = new SEP24WithdrawRequest(); -request.account = "G..."; -//... - -SEP24InteractiveResponse response = await transferService.withdraw(request); +const originAccount = "G..."; +final withdrawal = sep24.withdraw(asset, token, withdrawalAccount: originAccount); ``` @@ -315,6 +290,11 @@ let { stop, refresh } = watcher.watchOneTransaction({ }); ``` +```dart +final watcher = sep24.watcher(); +final result = watcher.watchOneTransaction(token, "transaction id"); +``` + Alternatively, we can track multiple transactions for the same asset. @@ -337,6 +317,11 @@ let { stop, refresh } = watcher.watchAllTransactions({ }); ``` +```dart +val watcher = sep24.watcher() +val result = watcher.watchAsset(token, asset) +``` + } /> @@ -359,21 +344,7 @@ const transaction = await anchor.sep24().getTransactionBy({ ``` ```dart -// single transaction -SEP24TransactionRequest request = SEP24TransactionRequest(); -request.stellarTransactionId = "transaction id"; -request.jwt = jwtToken; - -SEP24TransactionResponse response = await transferService.transaction(request); -SEP24Transaction transaction = response.transaction; - -// multiple transactions -SEP24TransactionsRequest request = SEP24TransactionsRequest(); -request.assetCode = "ETH"; -request.jwt = jwtToken; - -SEP24TransactionsResponse response = await transferService.transactions(request); -List transactions = response.transactions; +var transaction = await sep24.getTransaction("transaction id", token); ``` @@ -394,12 +365,7 @@ const transactions = await anchor.sep24().getTransactionsForAsset({ ``` ```dart -SEP24TransactionsRequest request = SEP24TransactionsRequest(); -request.assetCode = "ETH"; -request.jwt = jwtToken; - -SEP24TransactionsResponse response = await transferService.transactions(request); -List transactions = response.transactions; +var transactions = sep24.getTransactionsForAsset(asset, token); ``` @@ -423,6 +389,10 @@ let withdrawal = await anchor.sep24().withdraw({ }); ``` +```dart +final withdrawal = await sep24.withdraw(asset, token) +``` + Next, open an interactive url : @@ -439,6 +409,11 @@ let url = withdrawal.url; // open the url ``` +```dart +final url = withdrawal.url +// open the url +``` + After that we need to wait until the anchor is ready to receive funds. To do so, we will be waiting until transaction reaches `pending_user_transfer_start` status @@ -477,6 +452,20 @@ let { refresh, stop } = watcher.watchOneTransaction({ }); ``` +```dart +final withdrawalWatcher = sep24.watcher().watchOneTransaction(token, withdrawal.id) +withdrawalWatcher.controller.stream.listen( + (event) { + if (event is StatusChange && TransactionStatus.pendingUserTransferStart == event.status) { + // begin transfer + } + }, + onError: (error) { + // handle error + }, +); +``` + Next, sign and submit the Stellar transfer: @@ -506,6 +495,35 @@ keypair.sign(transfer); stellar.submitTransaction(transfer); ``` +```dart +final tx = event.transaction as WithdrawalTransaction; + +final paymentBuilder = flutter_sdk.PaymentOperationBuilder( + tx.withdrawAnchorAccount!, + flutter_sdk.Asset.createNonNativeAsset(asset.code, asset.issuer), + tx.amountIn!, +); + +final transactionBuilder = flutter_sdk.TransactionBuilder(sourceAccount) + ..addOperation(paymentBuilder.build()); + +flutter_sdk.Memo? memo; +if ("text" == tx.withdrawalMemoType) { + memo = flutter_sdk.MemoText(tx.withdrawalMemo!); +} else if ("hash" == tx.withdrawalMemoType) { + memo = flutter_sdk.MemoHash(base64Decode(tx.withdrawalMemo!)); +} // ... etc. + +if (memo != null) { + transactionBuilder.addMemo(memo); +} + +flutter_sdk.KeyPair kp = + flutter_sdk.KeyPair.fromSecretSeed(userKeyPair.secretKey); +final transaction = transactionBuilder.build()..sign(kp, network); +final paymentResult = await sdk.submitTransaction(transaction); +``` + Where `keypair` is the SEP-10 authenticated account. If you want to transfer funds from a different address, refer to [Changing Stellar Transfer Account](#changing-stellar-transfer-account) section. @@ -560,6 +578,28 @@ let { refresh, stop } = watcher.watchOneTransaction({ }); ``` +```dart +final watcher = sep24.watcher().watchOneTransaction(token, withdrawal.id) +watcher.controller.stream.listen( + (event) { + if (event is StatusChange && event.status.isTerminal()) { + if (TransactionStatus.completed != event.status) { + print("Transaction was not completed!"); + } else { + print("Success"); + } + } else if (event is ExceptionHandlerExit) { + print("Retries exhausted trying obtain transaction data, giving up."); + } else if (event is StreamControllerClosed) { + print("Transaction tracking finished"); + } + }, + onError: (error) { + // handle error + }, +); +``` + [sep-9]: https://github.com/stellar/stellar-protocol/blob/master/ecosystem/sep-000p.md