-
Notifications
You must be signed in to change notification settings - Fork 128
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
add recovery to flutter wallet sdk (#288)
* add recovery to flutter wallet sdk * add stellar to flutter wallet sdk * update flutter wallet sdk version nr
- Loading branch information
1 parent
db612a1
commit 6a96e93
Showing
5 changed files
with
338 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
import { CodeExample } from "@site/src/components/CodeExample"; | ||
|
||
### Configuring the Client | ||
|
||
The Flutter Wallet SDK uses the standard Client from the [http package](https://pub.dev/packages/http) for all network requests (excluding Horizon, where the Flutter Stellar SDK's HTTP client is used). | ||
|
||
Optionally, you can set your own client from [http package](https://pub.dev/packages/http) to be used across the app. | ||
|
||
The client can be globally configured: | ||
|
||
<CodeExample> | ||
|
||
```dart | ||
import 'package:http/http.dart'; | ||
// ... | ||
// init and configure your HTTP client | ||
// var myClient = ... | ||
// set as default HTTP client | ||
var appConfig = ApplicationConfiguration(defaultClient: myClient); | ||
var walletCustomClient = Wallet(StellarConfiguration.testNet, applicationConfiguration: appConfig); | ||
``` | ||
|
||
</CodeExample> | ||
|
||
Some [test cases](https://github.com/Soneso/stellar_wallet_flutter_sdk/tree/main/test) of this SDK use for example the `MockClient`. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -28,6 +28,12 @@ const recoveryKp = wallet.stellar().account().createKeypair(); | |
val recoveryKp = wallet.stellar().account().createKeyPair() | ||
``` | ||
|
||
```dart | ||
var accountKp = wallet.stellar().account().createKeyPair(); | ||
var deviceKp = wallet.stellar().account().createKeyPair(); | ||
var recoveryKp = wallet.stellar().account().createKeyPair(); | ||
``` | ||
|
||
</CodeExample> | ||
|
||
The `accountKp` is the wallet's main account. The `deviceKp` we will be adding to the wallet as a signer so a device (eg. a mobile device a wallet is hosted on) can take control of the account. And the `recoveryKp` will be used to identify the key with the recovery servers. | ||
|
@@ -65,6 +71,15 @@ val servers = mapOf(first to firstServer, second to secondServer) | |
val recovery = wallet.recovery(servers) | ||
``` | ||
|
||
```dart | ||
var first = RecoveryServerKey("first"); | ||
var second = RecoveryServerKey("second"); | ||
var firstServer = RecoveryServer("https://recovery.example1.com", "https://auth.example1.com", "recovery.example1.com"); | ||
var secondServer = RecoveryServer("https://recovery.example2.com", "https://auth.example2.com", "recovery.example2.com"); | ||
var servers = {first:firstServer, second:secondServer}; | ||
var recovery = wallet.recovery(servers); | ||
``` | ||
|
||
</CodeExample> | ||
|
||
Next, we need to define SEP-30 identities. In this example we are going to create an identity for both servers. Registering an identity tells the recovery server what identities are allowed to access the account. | ||
|
@@ -107,6 +122,19 @@ const identity2 = { | |
) | ||
``` | ||
|
||
```dart | ||
var identity1 = [ | ||
RecoveryAccountIdentity(RecoveryRole.owner, [ | ||
RecoveryAccountAuthMethod(RecoveryType.stellarAddress, recoveryKp.address) | ||
]) | ||
]; | ||
var identity2 = [ | ||
RecoveryAccountIdentity(RecoveryRole.owner, | ||
[RecoveryAccountAuthMethod(RecoveryType.email, "[email protected]")]) | ||
]; | ||
``` | ||
|
||
</CodeExample> | ||
|
||
Here, stellar key and email are used as recovery methods. Other recovery servers may support phone as a recovery method as well. | ||
|
@@ -141,6 +169,18 @@ const recoverableWallet = await recovery.createRecoverableWallet(config); | |
) | ||
``` | ||
|
||
```dart | ||
var recoverableWallet = await recovery.createRecoverableWallet( | ||
RecoverableWalletConfig( | ||
accountKp, | ||
deviceKp, | ||
AccountThreshold(10, 10, 10), | ||
{first: identity1, second: identity2}, | ||
SignerWeight(10, 5) | ||
) | ||
); | ||
``` | ||
|
||
</CodeExample> | ||
|
||
With the given parameters, this function will create a transaction that will: | ||
|
@@ -166,6 +206,12 @@ await stellar.submitTransaction(recoverableWallet.transaction); | |
wallet.stellar().submitTransaction(tx) | ||
``` | ||
|
||
```dart | ||
var transaction = recoverableWallet.transaction; | ||
transaction.sign(accountKp.keyPair, flutter_sdk.Network.TESTNET); | ||
await wallet.stellar().submitTransaction(transaction); | ||
``` | ||
|
||
</CodeExample> | ||
|
||
## Get Account Info | ||
|
@@ -184,6 +230,11 @@ const authToken = await recovery | |
val auth1 = recovery.sep10Auth(first).authenticate(recoveryKp) | ||
``` | ||
|
||
```dart | ||
var sep10 = await recovery.sep10Auth(first); | ||
var authToken = await sep10.authenticate(recoveryKp); | ||
``` | ||
|
||
</CodeExample> | ||
|
||
Next, get account info using auth tokens: | ||
|
@@ -202,6 +253,10 @@ const accountResp = await recovery.getAccountInfo(accountKp, { | |
println("Recoverable info: $accountInfo") | ||
``` | ||
|
||
```dart | ||
var accountInfo = await recovery.getAccountInfo(accountKp, {first: authToken.jwt}); | ||
``` | ||
|
||
</CodeExample> | ||
|
||
Our second identity uses an email as an auth method. For that we can't use a [SEP-10] auth token for that server. Instead we need to use a token that ties the email to the user. For example, Firebase tokens are a good use case for this. To use this, the recovery signer server needs to be prepared to handle these kinds of tokens. | ||
|
@@ -228,6 +283,10 @@ const accountResp = await recovery.getAccountInfo(accountKp, { | |
println("Recoverable info: $accountInfo") | ||
``` | ||
|
||
```dart | ||
var accountInfo = await recovery.getAccountInfo(accountKp, {second: <other token string>}); | ||
``` | ||
|
||
</CodeExample> | ||
|
||
## Recover Wallet | ||
|
@@ -254,6 +313,14 @@ const firebaseToken = AuthToken.from(<firebase token string>) | |
val firebaseToken = AuthToken.from(<firebase token string>) | ||
``` | ||
|
||
```dart | ||
var sep10 = await recovery.sep10Auth(first); | ||
var authToken = await sep10.authenticate(recoveryKp); | ||
var auth1 = authToken.jwt; | ||
var auth2 = "..."; // get other token e.g. firebase token | ||
``` | ||
|
||
</CodeExample> | ||
|
||
We need to know the recovery signer addresses that will be used to sign the transaction. You can get them from either the recoverable wallet object we created earlier (`recoverableWallet.signers`), or via fetching account info from recovery servers. | ||
|
@@ -269,6 +336,10 @@ const recoverySignerAddress2 = recoverableWallet.signers[1]; | |
val recoverySigners = recoverableWallet.signers | ||
``` | ||
|
||
```dart | ||
var recoverySigners = recoverableWallet.signers; | ||
``` | ||
|
||
</CodeExample> | ||
|
||
Next, create a new device key and retrieve a signed transaction that replaces the device key: | ||
|
@@ -312,6 +383,16 @@ const recoverTxn = await recovery.replaceDeviceKey( | |
) | ||
``` | ||
|
||
```dart | ||
var newKey = wallet.stellar().account().createKeyPair(); | ||
var serverAuth = { | ||
first: RecoveryServerSigning(recoverySigners[0], auth1), | ||
second: RecoveryServerSigning(recoverySigners[1], auth2) | ||
}; | ||
var signedReplaceKeyTx = await recovery.replaceDeviceKey(accountKp, newKey, serverAuth); | ||
``` | ||
|
||
</CodeExample> | ||
|
||
Calling this function will create a transaction that locks the previous device key and replaces it with your new key (having the same weight as the old one). Both recovery signers will have signed the transaction. | ||
|
@@ -337,6 +418,10 @@ await stellar.submitTransaction(recoverTxn); | |
wallet.stellar().submitTransaction(signedReplaceKeyTransaction) | ||
``` | ||
|
||
```dart | ||
await wallet.stellar().submitTransaction(signedReplaceKeyTx); | ||
``` | ||
|
||
</CodeExample> | ||
|
||
[sep-30]: https://github.com/stellar/stellar-protocol/blob/master/ecosystem/sep-0030.md |
Oops, something went wrong.