From 3c1049c73972fd2d24d5500dba372304a532b934 Mon Sep 17 00:00:00 2001 From: Bigcedar Date: Tue, 18 Feb 2025 14:14:49 +0100 Subject: [PATCH 01/11] docs(documentation): Add API documentation links to package docs - Add pub.dev API links for: - avnu_provider - starknet - starknet_provider - secure_store - wallet_kit --- packages/avnu_provider/README.md | 8 ++++++++ packages/secure_store/README.md | 2 ++ packages/starknet/README.md | 2 ++ packages/starknet_provider/README.md | 2 ++ packages/wallet_kit/README.md | 2 ++ 5 files changed, 16 insertions(+) diff --git a/packages/avnu_provider/README.md b/packages/avnu_provider/README.md index cbf16dcb..c6f5c779 100644 --- a/packages/avnu_provider/README.md +++ b/packages/avnu_provider/README.md @@ -2,3 +2,11 @@ AVNU Paymaster i a Dart package that provides a way to interact with the [AVNU paymaster service](https://doc.avnu.fi/avnu-paymaster/overview). + + + + + + +📚 [API Documentation](https://pub.dev/documentation/avnu_provider/latest/) + diff --git a/packages/secure_store/README.md b/packages/secure_store/README.md index 73419597..bcf6c872 100644 --- a/packages/secure_store/README.md +++ b/packages/secure_store/README.md @@ -1,5 +1,7 @@ # secure_store +📚 [API Documentation](https://pub.dev/documentation/secure_store/latest/) + The secure store is a Flutter allowing to securely store secret on a device, either using a password, or using biometrics. | | PasswordStore | BiometricsStore | diff --git a/packages/starknet/README.md b/packages/starknet/README.md index b1cd46d3..86bc5899 100644 --- a/packages/starknet/README.md +++ b/packages/starknet/README.md @@ -2,6 +2,8 @@ The goal of this SDK is to be able to interact with StarkNet smart contracts in a type-safe way. +📚 [API Documentation](https://pub.dev/documentation/starknet/latest/) + You can also call the JSON-RPC endpoint exposed by the StarkNet full nodes (see the [specs](https://github.com/starkware-libs/starknet-specs)). 📚 [docs](https://pub.dev/packages/starknet) diff --git a/packages/starknet_provider/README.md b/packages/starknet_provider/README.md index d2bfc0ef..e2d0af66 100644 --- a/packages/starknet_provider/README.md +++ b/packages/starknet_provider/README.md @@ -1,5 +1,7 @@ # Starknet provider +📚 [API Documentation](https://pub.dev/documentation/starknet_provider/latest/) + Starknet provider for Dart and Flutter applications ### Transaction support diff --git a/packages/wallet_kit/README.md b/packages/wallet_kit/README.md index eb99d5d9..d99bab55 100644 --- a/packages/wallet_kit/README.md +++ b/packages/wallet_kit/README.md @@ -1,5 +1,7 @@ # secure_store +📚 [API Documentation](https://pub.dev/documentation/wallet_kit/latest/) + A package to ease the use of [starknet](https://pub.dev/packages/starknet) in your Flutter app. ## Dart setup From 3c435f0211b16f0ea600814c4f9ce8aa5b9db52b Mon Sep 17 00:00:00 2001 From: Bigcedar Date: Wed, 19 Feb 2025 17:36:09 +0100 Subject: [PATCH 02/11] docs(packages): Move API links from READMEs to documentation pages - Remove API documentation links from package READMEs: - avnu_provider - starknet - starknet_provider - secure_store - wallet_kit - Add API documentation links to corresponding docs pages: - docs/packages/avnu_provider.mdx - docs/packages/starknet.mdx - docs/packages/starknet-provider.mdx - docs/packages/secure-store.mdx - docs/packages/wallet-kit.mdx --- docs/packages/avnu_provider.mdx | 2 +- docs/packages/secure-store.mdx | 2 +- docs/packages/starknet-provider.mdx | 2 +- docs/packages/starknet.mdx | 1 + docs/packages/wallet-kit.mdx | 1 + packages/avnu_provider/README.md | 2 +- packages/secure_store/README.md | 3 --- packages/starknet/README.md | 2 -- packages/starknet_provider/README.md | 2 -- packages/wallet_kit/README.md | 3 --- 10 files changed, 6 insertions(+), 14 deletions(-) diff --git a/docs/packages/avnu_provider.mdx b/docs/packages/avnu_provider.mdx index 074b11f9..74cf11df 100644 --- a/docs/packages/avnu_provider.mdx +++ b/docs/packages/avnu_provider.mdx @@ -8,7 +8,7 @@ - [IV. How to run tests](#iv-how-to-run-tests) AVNU Paymaster Provider is a Dart package that provides a way to interact with the AVNU paymaster service. - +📚 [API Documentation](https://pub.dev/documentation/avnu_provider/latest/) ## I. Introduction With this provider you (as sponsor) will be able to pay your users' gas fees and you (as a user) will be able to execute gasless transactions sponsored by the sponsor. The user simply signs typed data containing the calls they want to execute. The gas fees in ETH will be paid by Avnu relayers to execute the transaction. The process is as follows: diff --git a/docs/packages/secure-store.mdx b/docs/packages/secure-store.mdx index 12970d32..86855fb6 100644 --- a/docs/packages/secure-store.mdx +++ b/docs/packages/secure-store.mdx @@ -1,7 +1,7 @@ # Secure Store The secure store is a Flutter allowing to securely store secret on a device, either using a password, or using biometrics. - +📚 [API Documentation](https://pub.dev/documentation/secure_store/latest/) | | PasswordStore | BiometricsStore | | ------- | ------------- | --------------- | | IOS | ✅ | ✅ | diff --git a/docs/packages/starknet-provider.mdx b/docs/packages/starknet-provider.mdx index 41805ab6..d65de57c 100644 --- a/docs/packages/starknet-provider.mdx +++ b/docs/packages/starknet-provider.mdx @@ -1,5 +1,5 @@ # Call read-only method - +📚 [API Documentation](https://pub.dev/documentation/starknet_provider/latest/) ```dart import 'package:starknet/starknet.dart'; diff --git a/docs/packages/starknet.mdx b/docs/packages/starknet.mdx index f83f6daf..f3f26485 100644 --- a/docs/packages/starknet.mdx +++ b/docs/packages/starknet.mdx @@ -1 +1,2 @@ # Starknet Package +📚 [API Documentation](https://pub.dev/documentation/starknet_provider/latest/) \ No newline at end of file diff --git a/docs/packages/wallet-kit.mdx b/docs/packages/wallet-kit.mdx index 623238e6..cded8b5f 100644 --- a/docs/packages/wallet-kit.mdx +++ b/docs/packages/wallet-kit.mdx @@ -1 +1,2 @@ # Wallet Kit Package +📚 [API Documentation](https://pub.dev/documentation/wallet_kit/latest/) \ No newline at end of file diff --git a/packages/avnu_provider/README.md b/packages/avnu_provider/README.md index c6f5c779..2e86697b 100644 --- a/packages/avnu_provider/README.md +++ b/packages/avnu_provider/README.md @@ -8,5 +8,5 @@ AVNU Paymaster i a Dart package that provides a way to interact with the [AVNU p -📚 [API Documentation](https://pub.dev/documentation/avnu_provider/latest/) + diff --git a/packages/secure_store/README.md b/packages/secure_store/README.md index bcf6c872..f565152c 100644 --- a/packages/secure_store/README.md +++ b/packages/secure_store/README.md @@ -1,7 +1,4 @@ # secure_store - -📚 [API Documentation](https://pub.dev/documentation/secure_store/latest/) - The secure store is a Flutter allowing to securely store secret on a device, either using a password, or using biometrics. | | PasswordStore | BiometricsStore | diff --git a/packages/starknet/README.md b/packages/starknet/README.md index 86bc5899..b1cd46d3 100644 --- a/packages/starknet/README.md +++ b/packages/starknet/README.md @@ -2,8 +2,6 @@ The goal of this SDK is to be able to interact with StarkNet smart contracts in a type-safe way. -📚 [API Documentation](https://pub.dev/documentation/starknet/latest/) - You can also call the JSON-RPC endpoint exposed by the StarkNet full nodes (see the [specs](https://github.com/starkware-libs/starknet-specs)). 📚 [docs](https://pub.dev/packages/starknet) diff --git a/packages/starknet_provider/README.md b/packages/starknet_provider/README.md index e2d0af66..d2bfc0ef 100644 --- a/packages/starknet_provider/README.md +++ b/packages/starknet_provider/README.md @@ -1,7 +1,5 @@ # Starknet provider -📚 [API Documentation](https://pub.dev/documentation/starknet_provider/latest/) - Starknet provider for Dart and Flutter applications ### Transaction support diff --git a/packages/wallet_kit/README.md b/packages/wallet_kit/README.md index d99bab55..3e5b0863 100644 --- a/packages/wallet_kit/README.md +++ b/packages/wallet_kit/README.md @@ -1,7 +1,4 @@ # secure_store - -📚 [API Documentation](https://pub.dev/documentation/wallet_kit/latest/) - A package to ease the use of [starknet](https://pub.dev/packages/starknet) in your Flutter app. ## Dart setup From 800b8b813896cec039aac252d1d1999b2a57ef98 Mon Sep 17 00:00:00 2001 From: Bigcedar Date: Wed, 19 Feb 2025 17:45:30 +0100 Subject: [PATCH 03/11] Resolve merge conflict in starknet-provider docs --- docs/packages/starknet-provider.mdx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/packages/starknet-provider.mdx b/docs/packages/starknet-provider.mdx index d65de57c..c79ecc5c 100644 --- a/docs/packages/starknet-provider.mdx +++ b/docs/packages/starknet-provider.mdx @@ -1,5 +1,6 @@ -# Call read-only method +# Starknet Provider Documentation 📚 [API Documentation](https://pub.dev/documentation/starknet_provider/latest/) + ```dart import 'package:starknet/starknet.dart'; From cc1d21e43e839a346088f0b07717ac4c814cf113 Mon Sep 17 00:00:00 2001 From: Bigcedar Date: Wed, 19 Feb 2025 18:00:12 +0100 Subject: [PATCH 04/11] Resolve merge conflict in starknet-provider docs --- docs/packages/starknet-provider.mdx | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/docs/packages/starknet-provider.mdx b/docs/packages/starknet-provider.mdx index c79ecc5c..d65de57c 100644 --- a/docs/packages/starknet-provider.mdx +++ b/docs/packages/starknet-provider.mdx @@ -1,6 +1,5 @@ -# Starknet Provider Documentation +# Call read-only method 📚 [API Documentation](https://pub.dev/documentation/starknet_provider/latest/) - ```dart import 'package:starknet/starknet.dart'; From c752f54bcd6f49f37944e59a8496a7558aa04959 Mon Sep 17 00:00:00 2001 From: Bigcedar Date: Thu, 20 Feb 2025 17:26:34 +0100 Subject: [PATCH 05/11] docs: Address PR review comments --- docs/packages/avnu_provider.mdx | 1 + docs/packages/secure-store.mdx | 1 + docs/packages/starknet.mdx | 2 +- 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/docs/packages/avnu_provider.mdx b/docs/packages/avnu_provider.mdx index 74cf11df..c788e87f 100644 --- a/docs/packages/avnu_provider.mdx +++ b/docs/packages/avnu_provider.mdx @@ -8,6 +8,7 @@ - [IV. How to run tests](#iv-how-to-run-tests) AVNU Paymaster Provider is a Dart package that provides a way to interact with the AVNU paymaster service. + 📚 [API Documentation](https://pub.dev/documentation/avnu_provider/latest/) ## I. Introduction diff --git a/docs/packages/secure-store.mdx b/docs/packages/secure-store.mdx index 86855fb6..0f0d3bbd 100644 --- a/docs/packages/secure-store.mdx +++ b/docs/packages/secure-store.mdx @@ -1,6 +1,7 @@ # Secure Store The secure store is a Flutter allowing to securely store secret on a device, either using a password, or using biometrics. + 📚 [API Documentation](https://pub.dev/documentation/secure_store/latest/) | | PasswordStore | BiometricsStore | | ------- | ------------- | --------------- | diff --git a/docs/packages/starknet.mdx b/docs/packages/starknet.mdx index f3f26485..c1ac1834 100644 --- a/docs/packages/starknet.mdx +++ b/docs/packages/starknet.mdx @@ -1,2 +1,2 @@ # Starknet Package -📚 [API Documentation](https://pub.dev/documentation/starknet_provider/latest/) \ No newline at end of file +📚 [API Documentation](https://pub.dev/documentation/starknet/latest/) \ No newline at end of file From ea7bd81e7d5064560b0989056da15dc0bcae6e89 Mon Sep 17 00:00:00 2001 From: Bigcedar Date: Fri, 21 Feb 2025 09:09:40 +0100 Subject: [PATCH 06/11] docs: Update starknet-provider documentation formatting --- docs/packages/starknet-provider.mdx | 98 ++++++++++++++++++++--------- 1 file changed, 67 insertions(+), 31 deletions(-) diff --git a/docs/packages/starknet-provider.mdx b/docs/packages/starknet-provider.mdx index d65de57c..d2b53780 100644 --- a/docs/packages/starknet-provider.mdx +++ b/docs/packages/starknet-provider.mdx @@ -1,34 +1,70 @@ # Call read-only method 📚 [API Documentation](https://pub.dev/documentation/starknet_provider/latest/) -```dart -import 'package:starknet/starknet.dart'; - -void main() async { - final provider = JsonRpcProvider.infuraGoerliTestnet; - final accountAddress = Felt.fromHexString( - '0x046a1aa85bb0e68cd29fadbc81791208ddebee17886f075935e5b72f4aa898aa'); - final ethContractAddress = Felt.fromHexString( - '0x049d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7'); - final ethDecimals = 18; - - final response = await provider.call( - request: FunctionCall( - contractAddress: ethContractAddress, - entryPointSelector: getSelectorByName('balanceOf'), - calldata: [accountAddress], - ), - blockId: BlockId.blockTag("latest"), - ); - - response.when( - error: (error) { - throw Exception(error); - }, - result: (result) { - final ethBalance = Uint256.fromFeltList(result).toBigInt() / - BigInt.from(10).pow(ethDecimals); - print("ETH balance: ${ethBalance}"); // ETH balance: 8.142616847371661 - }, - ); -} +======= +# Starknet Provider + +A Dart package for interacting with Starknet node using JSON-RPC, following the [Starknet JSON-RPC specification](https://github.com/starkware-libs/starknet-specs.git). + +[Package documentation](https://pub.dev/documentation/starknet_provider/latest/) + +## Transaction support + +| Feature | State | Version | +| -------------- | ------------------ | ------- | +| invoke | ✅ | 0, 1, 3 | +| declare | ✅ | 1, 2, 3 | +| deploy_account | ✅ | 1, 3 | + +## Supported JSON RPC methods + +### Version: 0.7.1 + +### Read methods + +Name of methods have been extracted from [starknet-specs](https://github.com/starkware-libs/starknet-specs.git) with the following command: +```bash +jq .methods[].name ../starknet-specs/api/starknet_api_openrpc.json ``` +| Name | Implemented | +| ------------------------------------------ | ------------ | +| starknet_specVersion | ❌ | +| starknet_getBlockWithTxHashes | ✅ | +| starknet_getBlockWithTxs | ✅ | +| starknet_getBlockWithReceipts | ❌ | +| starknet_getStateUpdate | ✅ | +| starknet_getStorageAt | ✅ | +| starknet_getTransactionStatus | ❌ | +| starknet_getTransactionByHash | ✅ | +| starknet_getTransactionByBlockIdAndIndex | ✅ | +| starknet_getTransactionReceipt | ✅ | +| starknet_getClass | ✅ | +| starknet_getClassHashAt | ✅ | +| starknet_getClassAt | ✅ | +| starknet_getBlockTransactionCount | ✅ | +| starknet_call | ✅ | +| starknet_estimateFee | ✅ | +| starknet_estimateMessageFee | ❌ | +| starknet_blockNumber | ✅ | +| starknet_blockHashAndNumber | ✅ | +| starknet_chainId | ✅ | +| starknet_syncing | ✅ | +| starknet_getEvents | ✅ | +| starknet_getNonce | ✅ | + +### Write methods + +Name of methods have been extracted from [starknet-specs](https://github.com/starkware-libs/starknet-specs.git) with the following command: +```bash +jq .methods[].name ../starknet-specs/api/starknet_write_api.json +``` + +| Name | Implemented | +|--------------------------------------------|--------------| +| starknet_addInvokeTransaction | ✅ | +| starknet_addDeclareTransaction | ✅ | +| starknet_addDeployAccountTransaction | ✅ | + + +## Usage +### Call read-only method + From 5a382764bb6a5d312104a7a226c218f04246adbf Mon Sep 17 00:00:00 2001 From: Bigcedar Date: Mon, 24 Feb 2025 21:13:12 +0100 Subject: [PATCH 07/11] chore: fixed PR comment conflict --- docs/packages/starknet-provider.mdx | 138 ++++++++++++++-------------- 1 file changed, 68 insertions(+), 70 deletions(-) diff --git a/docs/packages/starknet-provider.mdx b/docs/packages/starknet-provider.mdx index d2b53780..d4c9d643 100644 --- a/docs/packages/starknet-provider.mdx +++ b/docs/packages/starknet-provider.mdx @@ -1,70 +1,68 @@ -# Call read-only method -📚 [API Documentation](https://pub.dev/documentation/starknet_provider/latest/) -======= -# Starknet Provider - -A Dart package for interacting with Starknet node using JSON-RPC, following the [Starknet JSON-RPC specification](https://github.com/starkware-libs/starknet-specs.git). - -[Package documentation](https://pub.dev/documentation/starknet_provider/latest/) - -## Transaction support - -| Feature | State | Version | -| -------------- | ------------------ | ------- | -| invoke | ✅ | 0, 1, 3 | -| declare | ✅ | 1, 2, 3 | -| deploy_account | ✅ | 1, 3 | - -## Supported JSON RPC methods - -### Version: 0.7.1 - -### Read methods - -Name of methods have been extracted from [starknet-specs](https://github.com/starkware-libs/starknet-specs.git) with the following command: -```bash -jq .methods[].name ../starknet-specs/api/starknet_api_openrpc.json -``` -| Name | Implemented | -| ------------------------------------------ | ------------ | -| starknet_specVersion | ❌ | -| starknet_getBlockWithTxHashes | ✅ | -| starknet_getBlockWithTxs | ✅ | -| starknet_getBlockWithReceipts | ❌ | -| starknet_getStateUpdate | ✅ | -| starknet_getStorageAt | ✅ | -| starknet_getTransactionStatus | ❌ | -| starknet_getTransactionByHash | ✅ | -| starknet_getTransactionByBlockIdAndIndex | ✅ | -| starknet_getTransactionReceipt | ✅ | -| starknet_getClass | ✅ | -| starknet_getClassHashAt | ✅ | -| starknet_getClassAt | ✅ | -| starknet_getBlockTransactionCount | ✅ | -| starknet_call | ✅ | -| starknet_estimateFee | ✅ | -| starknet_estimateMessageFee | ❌ | -| starknet_blockNumber | ✅ | -| starknet_blockHashAndNumber | ✅ | -| starknet_chainId | ✅ | -| starknet_syncing | ✅ | -| starknet_getEvents | ✅ | -| starknet_getNonce | ✅ | - -### Write methods - -Name of methods have been extracted from [starknet-specs](https://github.com/starkware-libs/starknet-specs.git) with the following command: -```bash -jq .methods[].name ../starknet-specs/api/starknet_write_api.json -``` - -| Name | Implemented | -|--------------------------------------------|--------------| -| starknet_addInvokeTransaction | ✅ | -| starknet_addDeclareTransaction | ✅ | -| starknet_addDeployAccountTransaction | ✅ | - - -## Usage -### Call read-only method - +# Call read-only method +📚 [API Documentation](https://pub.dev/documentation/starknet_provider/latest/) +# Starknet Provider +A Dart package for interacting with Starknet node using JSON-RPC, following the [Starknet JSON-RPC specification](https://github.com/starkware-libs/starknet-specs.git). + +[Package documentation](https://pub.dev/documentation/starknet_provider/latest/) + +## Transaction support + +| Feature | State | Version | +| -------------- | ------------------ | ------- | +| invoke | ✅ | 0, 1, 3 | +| declare | ✅ | 1, 2, 3 | +| deploy_account | ✅ | 1, 3 | + +## Supported JSON RPC methods + +### Version: 0.7.1 + +### Read methods + +Name of methods have been extracted from [starknet-specs](https://github.com/starkware-libs/starknet-specs.git) with the following command: +```bash +jq .methods[].name ../starknet-specs/api/starknet_api_openrpc.json +``` +| Name | Implemented | +| ------------------------------------------ | ------------ | +| starknet_specVersion | ❌ | +| starknet_getBlockWithTxHashes | ✅ | +| starknet_getBlockWithTxs | ✅ | +| starknet_getBlockWithReceipts | ❌ | +| starknet_getStateUpdate | ✅ | +| starknet_getStorageAt | ✅ | +| starknet_getTransactionStatus | ❌ | +| starknet_getTransactionByHash | ✅ | +| starknet_getTransactionByBlockIdAndIndex | ✅ | +| starknet_getTransactionReceipt | ✅ | +| starknet_getClass | ✅ | +| starknet_getClassHashAt | ✅ | +| starknet_getClassAt | ✅ | +| starknet_getBlockTransactionCount | ✅ | +| starknet_call | ✅ | +| starknet_estimateFee | ✅ | +| starknet_estimateMessageFee | ❌ | +| starknet_blockNumber | ✅ | +| starknet_blockHashAndNumber | ✅ | +| starknet_chainId | ✅ | +| starknet_syncing | ✅ | +| starknet_getEvents | ✅ | +| starknet_getNonce | ✅ | + +### Write methods + +Name of methods have been extracted from [starknet-specs](https://github.com/starkware-libs/starknet-specs.git) with the following command: +```bash +jq .methods[].name ../starknet-specs/api/starknet_write_api.json +``` + +| Name | Implemented | +|--------------------------------------------|--------------| +| starknet_addInvokeTransaction | ✅ | +| starknet_addDeclareTransaction | ✅ | +| starknet_addDeployAccountTransaction | ✅ | + + +## Usage +### Call read-only method + From 12aea46621a0c513bf858d805501e66279a853c9 Mon Sep 17 00:00:00 2001 From: Bigcedar Date: Fri, 28 Feb 2025 11:01:04 +0100 Subject: [PATCH 08/11] fix: PR conflicts --- docs/packages/starknet-provider.mdx | 79 ++++++----- packages/avnu_provider/README.md | 15 +- packages/secure_store/README.md | 207 ++++++++++++++-------------- 3 files changed, 146 insertions(+), 155 deletions(-) diff --git a/docs/packages/starknet-provider.mdx b/docs/packages/starknet-provider.mdx index d4c9d643..2de3bdec 100644 --- a/docs/packages/starknet-provider.mdx +++ b/docs/packages/starknet-provider.mdx @@ -1,17 +1,16 @@ -# Call read-only method -📚 [API Documentation](https://pub.dev/documentation/starknet_provider/latest/) # Starknet Provider + A Dart package for interacting with Starknet node using JSON-RPC, following the [Starknet JSON-RPC specification](https://github.com/starkware-libs/starknet-specs.git). [Package documentation](https://pub.dev/documentation/starknet_provider/latest/) ## Transaction support -| Feature | State | Version | -| -------------- | ------------------ | ------- | -| invoke | ✅ | 0, 1, 3 | -| declare | ✅ | 1, 2, 3 | -| deploy_account | ✅ | 1, 3 | +| Feature | State | Version | +| -------------- | ----- | ------- | +| invoke | ✅ | 0, 1, 3 | +| declare | ✅ | 1, 2, 3 | +| deploy_account | ✅ | 1, 3 | ## Supported JSON RPC methods @@ -20,49 +19,49 @@ A Dart package for interacting with Starknet node using JSON-RPC, following the ### Read methods Name of methods have been extracted from [starknet-specs](https://github.com/starkware-libs/starknet-specs.git) with the following command: + ```bash jq .methods[].name ../starknet-specs/api/starknet_api_openrpc.json ``` -| Name | Implemented | -| ------------------------------------------ | ------------ | -| starknet_specVersion | ❌ | -| starknet_getBlockWithTxHashes | ✅ | -| starknet_getBlockWithTxs | ✅ | -| starknet_getBlockWithReceipts | ❌ | -| starknet_getStateUpdate | ✅ | -| starknet_getStorageAt | ✅ | -| starknet_getTransactionStatus | ❌ | -| starknet_getTransactionByHash | ✅ | -| starknet_getTransactionByBlockIdAndIndex | ✅ | -| starknet_getTransactionReceipt | ✅ | -| starknet_getClass | ✅ | -| starknet_getClassHashAt | ✅ | -| starknet_getClassAt | ✅ | -| starknet_getBlockTransactionCount | ✅ | -| starknet_call | ✅ | -| starknet_estimateFee | ✅ | -| starknet_estimateMessageFee | ❌ | -| starknet_blockNumber | ✅ | -| starknet_blockHashAndNumber | ✅ | -| starknet_chainId | ✅ | -| starknet_syncing | ✅ | -| starknet_getEvents | ✅ | -| starknet_getNonce | ✅ | + +| Name | Implemented | +| ---------------------------------------- | ----------- | +| starknet_specVersion | ❌ | +| starknet_getBlockWithTxHashes | ✅ | +| starknet_getBlockWithTxs | ✅ | +| starknet_getBlockWithReceipts | ❌ | +| starknet_getStateUpdate | ✅ | +| starknet_getStorageAt | ✅ | +| starknet_getTransactionStatus | ❌ | +| starknet_getTransactionByHash | ✅ | +| starknet_getTransactionByBlockIdAndIndex | ✅ | +| starknet_getTransactionReceipt | ✅ | +| starknet_getClass | ✅ | +| starknet_getClassHashAt | ✅ | +| starknet_getClassAt | ✅ | +| starknet_getBlockTransactionCount | ✅ | +| starknet_call | ✅ | +| starknet_estimateFee | ✅ | +| starknet_estimateMessageFee | ❌ | +| starknet_blockNumber | ✅ | +| starknet_blockHashAndNumber | ✅ | +| starknet_chainId | ✅ | +| starknet_syncing | ✅ | +| starknet_getEvents | ✅ | +| starknet_getNonce | ✅ | ### Write methods Name of methods have been extracted from [starknet-specs](https://github.com/starkware-libs/starknet-specs.git) with the following command: + ```bash jq .methods[].name ../starknet-specs/api/starknet_write_api.json ``` -| Name | Implemented | -|--------------------------------------------|--------------| -| starknet_addInvokeTransaction | ✅ | -| starknet_addDeclareTransaction | ✅ | -| starknet_addDeployAccountTransaction | ✅ | - +| Name | Implemented | +| ------------------------------------ | ----------- | +| starknet_addInvokeTransaction | ✅ | +| starknet_addDeclareTransaction | ✅ | +| starknet_addDeployAccountTransaction | ✅ | -## Usage ### Call read-only method - diff --git a/packages/avnu_provider/README.md b/packages/avnu_provider/README.md index 2e86697b..33507c44 100644 --- a/packages/avnu_provider/README.md +++ b/packages/avnu_provider/README.md @@ -1,12 +1,3 @@ -## AVNU Paymaster - -AVNU Paymaster i a Dart package that provides a way to interact with the [AVNU paymaster service](https://doc.avnu.fi/avnu-paymaster/overview). - - - - - - - - - +## AVNU Paymaster + +AVNU Paymaster i a Dart package that provides a way to interact with the [AVNU paymaster service](https://doc.avnu.fi/avnu-paymaster/overview). diff --git a/packages/secure_store/README.md b/packages/secure_store/README.md index f565152c..7c08374a 100644 --- a/packages/secure_store/README.md +++ b/packages/secure_store/README.md @@ -1,103 +1,104 @@ -# secure_store -The secure store is a Flutter allowing to securely store secret on a device, either using a password, or using biometrics. - -| | PasswordStore | BiometricsStore | -| ------- | ------------- | --------------- | -| IOS | ✅ | ✅ | -| Android | ✅ | ✅ | -| Web | ✅ | ❌ | -| Mac | ✅ | ✅ | -| Windows | ✅ | ❌ | -| Linux | ✅ | ❌ | - -## Usage - -### Biometrics Store - -```dart -await BiometricStore().storeSecret( - secret: "Simplicity is the ultimate sophistication", - key: "biometrics-store:secret", -); - -final secret = await BiometricStore().getSecret( - key: "biometrics-store:secret", -); - -await BiometricStore().deleteSecret( - key: "biometrics-store:secret", -); -``` - -### Password Store - -First you need to initialize the password store since it's using Hive under the hood. - -```dart -// In main.dart -void main() { - PasswordStore.init(); - runApp(const MyApp()); -} -``` - -Then you can use password store very easily: - -```dart -await PasswordStore().storeSecret( - secret: "Simplicity is the ultimate sophistication", - key: "password-store:secret", - options: const PasswordStoreOptions(password: "1234"), -); - -final secret = await PasswordStore().getSecret( - key: "password-store:secret", - options: const PasswordStoreOptions(password: "1234"), -); -``` - -## Platform Setup - -### IOS - -Add `NSFaceIDUsageDescription` permission in `Info.plist`: - -```plist -NSFaceIDUsageDescription -Use Touch ID or Face ID to process transactions. -``` - -### Android - -Edit your `android/app/build.gradle`: - -```gradle -android { - defaultConfig { - minSdkVersion 23 - } -} -``` - -Change your `MainActivity` to extend `FlutterFragmentActivity` instead of `FlutterActivity`: - -```kt -package com.example.example - -import io.flutter.embedding.android.FlutterActivity - -class MainActivity: FlutterFragmentActivity() { -} -``` - -### Mac - -You need to add the Keychain Sharing capability in the Xcode project [following this guide](https://developer.apple.com/documentation/xcode/configuring-keychain-sharing). - -NOTE: you only need to add the capability, it's not needed to add any Keychain Groups. - -## Security Overview - -Some platforms and devices might be more secure than others. On iOS & MacOS, this plugin uses the [Secure Enclave](https://support.apple.com/fr-ca/guide/security/sec59b0b31ff/web) to protect the private key (if the device do not have a biometric component or not enabled, a password will be asked to encrypt data as a fallback method). On Android, the plugin biometric_storage is used. When biometric authentication is available, it is used to protect the private key. On other platforms and when the above is not available, the private key is encrypted using a password and stored in shared preferences. - -Here's an in-depth [architecture overview](https://focustree.notion.site/Seed-phrase-storage-cfafbd43f8b04b738dd66804459455fa?pvs=25). +# secure_store + +The secure store is a Flutter allowing to securely store secret on a device, either using a password, or using biometrics. + +| | PasswordStore | BiometricsStore | +| ------- | ------------- | --------------- | +| IOS | ✅ | ✅ | +| Android | ✅ | ✅ | +| Web | ✅ | ❌ | +| Mac | ✅ | ✅ | +| Windows | ✅ | ❌ | +| Linux | ✅ | ❌ | + +## Usage + +### Biometrics Store + +```dart +await BiometricStore().storeSecret( + secret: "Simplicity is the ultimate sophistication", + key: "biometrics-store:secret", +); + +final secret = await BiometricStore().getSecret( + key: "biometrics-store:secret", +); + +await BiometricStore().deleteSecret( + key: "biometrics-store:secret", +); +``` + +### Password Store + +First you need to initialize the password store since it's using Hive under the hood. + +```dart +// In main.dart +void main() { + PasswordStore.init(); + runApp(const MyApp()); +} +``` + +Then you can use password store very easily: + +```dart +await PasswordStore().storeSecret( + secret: "Simplicity is the ultimate sophistication", + key: "password-store:secret", + options: const PasswordStoreOptions(password: "1234"), +); + +final secret = await PasswordStore().getSecret( + key: "password-store:secret", + options: const PasswordStoreOptions(password: "1234"), +); +``` + +## Platform Setup + +### IOS + +Add `NSFaceIDUsageDescription` permission in `Info.plist`: + +```plist +NSFaceIDUsageDescription +Use Touch ID or Face ID to process transactions. +``` + +### Android + +Edit your `android/app/build.gradle`: + +```gradle +android { + defaultConfig { + minSdkVersion 23 + } +} +``` + +Change your `MainActivity` to extend `FlutterFragmentActivity` instead of `FlutterActivity`: + +```kt +package com.example.example + +import io.flutter.embedding.android.FlutterActivity + +class MainActivity: FlutterFragmentActivity() { +} +``` + +### Mac + +You need to add the Keychain Sharing capability in the Xcode project [following this guide](https://developer.apple.com/documentation/xcode/configuring-keychain-sharing). + +NOTE: you only need to add the capability, it's not needed to add any Keychain Groups. + +## Security Overview + +Some platforms and devices might be more secure than others. On iOS & MacOS, this plugin uses the [Secure Enclave](https://support.apple.com/fr-ca/guide/security/sec59b0b31ff/web) to protect the private key (if the device do not have a biometric component or not enabled, a password will be asked to encrypt data as a fallback method). On Android, the plugin biometric_storage is used. When biometric authentication is available, it is used to protect the private key. On other platforms and when the above is not available, the private key is encrypted using a password and stored in shared preferences. + +Here's an in-depth [architecture overview](https://focustree.notion.site/Seed-phrase-storage-cfafbd43f8b04b738dd66804459455fa?pvs=25). From 35330042553901b70f5fce8e47af8f5fe1c88693 Mon Sep 17 00:00:00 2001 From: Bigcedar Date: Fri, 28 Feb 2025 12:57:19 +0100 Subject: [PATCH 09/11] chores: fixed PR --- packages/secure_store/README.md | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/packages/secure_store/README.md b/packages/secure_store/README.md index 7c08374a..171ba427 100644 --- a/packages/secure_store/README.md +++ b/packages/secure_store/README.md @@ -80,16 +80,10 @@ android { } ``` -Change your `MainActivity` to extend `FlutterFragmentActivity` instead of `FlutterActivity`: +import io.flutter.embedding.android.FlutterFragmentActivity -```kt -package com.example.example - -import io.flutter.embedding.android.FlutterActivity - -class MainActivity: FlutterFragmentActivity() { +class MainActivity: FlutterFragmentActivity() { } -``` ### Mac From a694a50019ca9cec956911bd864267cb176143de Mon Sep 17 00:00:00 2001 From: Bigcedar Date: Sun, 2 Mar 2025 07:55:28 +0100 Subject: [PATCH 10/11] revert changes to original encoding --- docs/packages/starknet-provider.mdx | 1 - packages/wallet_kit/README.md | 929 ++++++++++++++-------------- 2 files changed, 465 insertions(+), 465 deletions(-) diff --git a/docs/packages/starknet-provider.mdx b/docs/packages/starknet-provider.mdx index 2de3bdec..18bbf9d5 100644 --- a/docs/packages/starknet-provider.mdx +++ b/docs/packages/starknet-provider.mdx @@ -1,7 +1,6 @@ # Starknet Provider A Dart package for interacting with Starknet node using JSON-RPC, following the [Starknet JSON-RPC specification](https://github.com/starkware-libs/starknet-specs.git). - [Package documentation](https://pub.dev/documentation/starknet_provider/latest/) ## Transaction support diff --git a/packages/wallet_kit/README.md b/packages/wallet_kit/README.md index 3e5b0863..db52a32d 100644 --- a/packages/wallet_kit/README.md +++ b/packages/wallet_kit/README.md @@ -1,464 +1,465 @@ -# secure_store -A package to ease the use of [starknet](https://pub.dev/packages/starknet) in your Flutter app. - -## Dart setup - -Add the following to your `pubspec.yaml`: - -```yaml -dependencies: - secure_store: [version] -``` - -Then, run `flutter pub get`. - -You need to call `init()` method of the `secure_store` plugin before using it. - -A good place to do this in your `main.dart`: - -```dart -Future main() async { - await Securestore.init(); - runApp(const StarknetDemoApp()); -} -``` - -## Platform setup - -### iOS - -You need to add some permissions in the `info.plist` - -- FaceID (used to store/retrieve sensitive informations like Starknet private key for.) - -```plist -NSFaceIDUsageDescription -Use Touch ID or Face ID to process transactions. -``` - -- Camera (used to scan account address QRCode) - -```plist -NSCameraUsageDescription -This app needs camera access to scan QR codes -``` - -### MacOS - -Like iOS, you need to add some permissions - -- Keychain Sharing - -You need to add the `Keychain Sharing` capability in the Xcode project [following this guide](https://developer.apple.com/documentation/xcode/configuring-keychain-sharing). - -**NOTE: you only need to add the capability, it's not needed to add any `Keychain Groups`.** - -- Camera - -You need to enable `Camera` permission into App Sandbox [following this guide](https://developer.apple.com/documentation/xcode/configuring-the-macos-app-sandbox/). - -### Android - -This plugin requires minSdkVersion 23 (Android 6.0) or higher. -Edit you `android/app/build.gradle`: - -```groovy -android { - defaultConfig { - minSdkVersion 23 - } -} -``` - -Your `MainActivity` must extend `FlutterFragmentActivity`. - -Example: - -```kotlin -package com.example.myapp - -import io.flutter.embedding.android.FlutterFragmentActivity - -class MainActivity : FlutterFragmentActivity() { } -``` - -The theme of the main activity must use `Theme.AppCompat` or there will be crashes on Android < 29. -Edit your manifest at `android/app/src/main/AndroidManifest.xml`: - -```xml - - - - @drawable/launch_background - - true - false - true - @null - -``` - -You might edit the night variant as well at `android/app/src/main/res/values-night/styles.xml`. - -### Windows - -_TBD_ - -### Linux - -_TBD_ - -### Web - -_TBD_ - -## Usage - -Some platforms and devices might be more secure than others. -On iOS & MacOS, this plugin uses the [Secure Enclave](https://support.apple.com/fr-ca/guide/security/sec59b0b31ff/web) to protect the private key (if the device do not have a biometric component or not enabled, a password will be asked to encrypt data as a fallback method). -On Android, the plugin [biometric_storage](https://pub.dev/packages/biometric_storage) is used. When biometric authentication is available, it is used to protect the private key. -On other platforms and when the above is not available, the private key is encrypted using a password and stored in [shared preferences](https://pub.dev/packages/shared_preferences). - -For above reasons, either a `BiometricStore` or a `PasswordStore` is returned when calling `SecureStore.get()`. -For convenience, the `when` method is provided to handle both cases: - -```dart -// store might be either a `BiometricStore` or a `PasswordStore` -final store = await SecureStore.get(); - -// Use `when` to handle both cases -await store.when( - biometric: (biometric) async { - // Use the biometric store - }, - password: (password) async { - // Use the password store - }, -); -``` - -### Setting up your password - -While `BiometricStore` uses your already registered biometric authentication, `PasswordStore` requires you to provide an initial password that will be used to encrypt and decrypt your secrets. -You can do it with the following code: - -```dart -final password = await createPassword(context); -if (password != null) { - await PasswordStore().initiatePassword(password); - if (mounted) Navigator.pop(context); -} -``` - -`createPassword()` is a function that returns a `Future` that will be used as the password. -In a real app, it could be a dialog that asks the user to create their password. - -`secure_store` includes several methods to enter a password: - -- `PasscodeInputView.showPattern()` to draw a pattern -- `PasscodeInputView.showPin()` to enter a pin -- `PasscodeInputView.showPassword()` to type a textual password -- `PasscodeInputView.showCustom()` to use anything you want to type your password while reusing the same logic as the other methods. - See below examples, and find more in the example project. - -
-Pattern input prompt example -Draw a pattern as your password. - -```dart -final result = await PasscodeInputView.showPattern( - context, - actionConfig: const PasscodeActionConfig.create( - createTitle: "Draw your pattern", - confirmTitle: "Confirm your pattern", - ), -) -``` - -
- -
-Emoji input prompt example -Enter emoji as your password, like "👍🎨🚚👀" for instance. - -```dart -final password = await PasscodeInputView.showCustom( - context, - actionConfig: const PasscodeActionConfig.create( - createTitle: "Type your emoji password", - confirmTitle: "Confirm your emoji password", - ), - onWrongRepeatInput: (input) { - showSnackBar( - "Wrong input: $input", - success: false, - ); - }, - passcodeConfig: const PasscodeConfig( - backgroundColor: Colors.lightBlueAccent, - cancelButtonConfig: PasscodeCancelButtonConfig( - child: Text( - "❌ Mission aborted", - style: TextStyle(color: Colors.white), - ), - ), - ), - inputBuilder: ( - OnInputValidated onInputValidated, - bool isConfirming, - ) { - return EmojiInput( - onInputValidated: onInputValidated, - nextTitle: isConfirming ? "Confirm" : "Next", - ); - }, -) -``` - -
- -### Storing the private key - -Use `BiomericStore.storePrivateKey` or `PasswordStore.storePrivateKey` to store the private key: - -```dart -final store = await SecureStore.get(); -await store.when( - biometric: (biometric) => biometric.storePrivateKey( - id: "uuid1", - privateKey: _privateKey, - ), - password: (password) => password.storePrivateKey( - id: "uuid1", - password: _password, - privateKey: _privateKey, - ), -); -``` - -Each private key is identified by an `id` (a `String`). -When using the `PasswordStore`, the password is used to encrypt the private key using AES 256 GCM. -The password is hashed using SHA 256. -The IV for AES is generated randomly, but you can also provide your own if needed. It must be 16 bytes long. - -### Retrieving the private key - -Similarly, you can retrieve the key using `BiomericStore.getPrivateKey` or `PasswordStore.getPrivateKey`: - -```dart -final store = await SecureStore.get(); -await store.when( - biometric: (biometric) => biometric.getPrivateKey(id: "uuid1"), - password: (password) => password.getPrivateKey( - id: "uuid1", - password: _password, - ), -); -``` - -## List exchange rates for a currency - -```dart -import 'package:secure_store/secure_store.dart'; - -void main() async { - final starknet = await Securestore.get(); - final exchangeRates = await starknet.getExchangeRates( - currency: "USD", - ); - print(exchangeRates); -} -``` - -## Running on Devnet - -Place yourself at the root of the monorepo project. -If you are in `secure_store`, this would be `../..`. -Call this to start the devnet: - -``` -poetry install -poetry run devnet start -``` - -Declare OpenZeppelin contract - -``` - -``` - -You are ready to create OpenZeppelin contracts, however you may need extra configuration if you want to run the example app. - -### Run the Flutter example on the devnet - -You need to define a NODE_URI dart environment variable like below: - -``` ---dart-define=NODE_URI=http://YOUR_HOST_IP:5050/rpc -``` - -For example with 192.168.1.15 as your host IP: - -``` -flutter run --dart-define=NODE_URI=http://192.168.1.15:5050/rpc -``` - -On Android Studio, you can add `--dart-define=NODE_URI=http://YOUR_HOST_IP:5050/rpc` to your run configuration in the "Additional run args" field. -On VS Code, you can also edit your `launch.json` to add `--dart-define=NODE_URI=http://YOUR_HOST_IP:5050/rpc` to your run configuration: - -```json -{ - "version": "0.2.0", - "configurations": [ - { - "name": "Example (Testnet)", - "request": "launch", - "type": "dart", - "program": "example/lib/main.dart" - }, - { - "name": "Example (Devnet)", - "request": "launch", - "type": "dart", - "program": "example/lib/main.dart", - "args": ["--dart-define=NODE_URI=http://192.168.1.15:5050/rpc"] - } - ] -} -``` - -### Send ETH to an address - -If your address is `0x7e678b687c94c9de17caeb4c39b86b2a4cb84312c4f93abbf42fb169377b845` for example, call from the monorepo root: - -``` -dart run ./packages/starknet/tool/send_eth.dart 0x7e678b687c94c9de17caeb4c39b86b2a4cb84312c4f93abbf42fb169377b845 -``` - -## Get ETH balance - -To display ETH balance of an account, you just need to call the `balance` property of a `PublicAccount` object. - -Example: - -```dart -// [...] select a wallet using wallet list for exemple. -final ethBalance = await selectedAccount.balance; -print('$ethBalance ETH'); // 0.045 ETH -``` - -## Get fiat equivalent to ETH balance - -```dart -final ethBalance = await selectedAccount.balance; -final ethExchangeRate = await ExchangeRates.get(from: 'ETH', to: 'USD'); // Change 'USD' to fiat currency you want -final fiatEquivalent = ethBalance * ethExchangeRate; -print('$fiatEquivalent \$'); // 43.34 $ -``` - -## Display formatted balance - -By default ETH balance was not rounded / truncated, if you want to display it properly on the UI, you can use following utils: - -First you need to import the plugin. - -```dart -import 'package:secure_store/secure_store.dart'; -``` - -- `truncateBalance()` this method wil truncate **without** round the value. - -Example: - -```dart -final ethBalance = 0.546365463; -String formatted = ethBalance.truncateBalance(precision: 4); -print(formatted) // 0.5463 -``` - -- `format()` this method will round value to 2 digits. - -Example: - -```dart -final ethBalance = 0.546365463; -String formatted = ethBalance.format(); -print(formatted) // 0.55 -``` - -## Display minified account address - -An address can be very long and it's pretty ugly. - -You can use the following snippet to display an address & keep first & last segment visible. - -```dart -final address = '0x53656356453665465364653664536426748692'; -final formatted = address.truncateMiddle(truncateLength: 20); -print(formatted) // 0x53656356...426748692 -``` - -## Show wallets list - -I you want to display the wallets list, you just have to call this code: - -```dart -StarknetWalletList.showModal( - context, - PasscodeInputView.showPinCode(context), -); -``` - -- `context` is used to display modal bottom sheet over your app. -- `passwordPrompt` is a method called when a password unlock is required to unlock sensitive data (you can set the pass code method you want). - -## Show transaction modal - -You can send ETH to a specific address. - -```dart -StarknetTransaction.showModal( - context, - args: transactionArguments, -); -``` - -- `context` is used to display modal bottom sheet over your app. -- `transactionArguments` handle the current selected `PublicAccount`. - -## Show account address QRCode - -You can display at anytime account QRCode address. - -```dart -StarknetReceive.showQRCodeModal( - context, - address: '0x0000', -); -``` - -- `context` is used to display modal bottom sheet over your app. -- `address` the account address to receive ETH. - -## Show wallet create/restore modal - -When called, the user can choose to create or restore a wallet. - -```dart -StarknetWallet.showInitializationModal( - context, - passwordPrompt: unlockWithPassword, -); -``` - -- `context` is used to display modal bottom sheet over your app. -- `passwordPrompt` is a method called when a password unlock is required to unlock sensitive data (you can set the pass code method you want). +# secure_store + +A package to ease the use of [starknet](https://pub.dev/packages/starknet) in your Flutter app. + +## Dart setup + +Add the following to your `pubspec.yaml`: + +```yaml +dependencies: + secure_store: [version] +``` + +Then, run `flutter pub get`. + +You need to call `init()` method of the `secure_store` plugin before using it. + +A good place to do this in your `main.dart`: + +```dart +Future main() async { + await Securestore.init(); + runApp(const StarknetDemoApp()); +} +``` + +## Platform setup + +### iOS + +You need to add some permissions in the `info.plist` + +- FaceID (used to store/retrieve sensitive informations like Starknet private key for.) + +```plist +NSFaceIDUsageDescription +Use Touch ID or Face ID to process transactions. +``` + +- Camera (used to scan account address QRCode) + +```plist +NSCameraUsageDescription +This app needs camera access to scan QR codes +``` + +### MacOS + +Like iOS, you need to add some permissions + +- Keychain Sharing + +You need to add the `Keychain Sharing` capability in the Xcode project [following this guide](https://developer.apple.com/documentation/xcode/configuring-keychain-sharing). + +**NOTE: you only need to add the capability, it's not needed to add any `Keychain Groups`.** + +- Camera + +You need to enable `Camera` permission into App Sandbox [following this guide](https://developer.apple.com/documentation/xcode/configuring-the-macos-app-sandbox/). + +### Android + +This plugin requires minSdkVersion 23 (Android 6.0) or higher. +Edit you `android/app/build.gradle`: + +```groovy +android { + defaultConfig { + minSdkVersion 23 + } +} +``` + +Your `MainActivity` must extend `FlutterFragmentActivity`. + +Example: + +```kotlin +package com.example.myapp + +import io.flutter.embedding.android.FlutterFragmentActivity + +class MainActivity : FlutterFragmentActivity() { } +``` + +The theme of the main activity must use `Theme.AppCompat` or there will be crashes on Android < 29. +Edit your manifest at `android/app/src/main/AndroidManifest.xml`: + +```xml + + + + @drawable/launch_background + + true + false + true + @null + +``` + +You might edit the night variant as well at `android/app/src/main/res/values-night/styles.xml`. + +### Windows + +_TBD_ + +### Linux + +_TBD_ + +### Web + +_TBD_ + +## Usage + +Some platforms and devices might be more secure than others. +On iOS & MacOS, this plugin uses the [Secure Enclave](https://support.apple.com/fr-ca/guide/security/sec59b0b31ff/web) to protect the private key (if the device do not have a biometric component or not enabled, a password will be asked to encrypt data as a fallback method). +On Android, the plugin [biometric_storage](https://pub.dev/packages/biometric_storage) is used. When biometric authentication is available, it is used to protect the private key. +On other platforms and when the above is not available, the private key is encrypted using a password and stored in [shared preferences](https://pub.dev/packages/shared_preferences). + +For above reasons, either a `BiometricStore` or a `PasswordStore` is returned when calling `SecureStore.get()`. +For convenience, the `when` method is provided to handle both cases: + +```dart +// store might be either a `BiometricStore` or a `PasswordStore` +final store = await SecureStore.get(); + +// Use `when` to handle both cases +await store.when( + biometric: (biometric) async { + // Use the biometric store + }, + password: (password) async { + // Use the password store + }, +); +``` + +### Setting up your password + +While `BiometricStore` uses your already registered biometric authentication, `PasswordStore` requires you to provide an initial password that will be used to encrypt and decrypt your secrets. +You can do it with the following code: + +```dart +final password = await createPassword(context); +if (password != null) { + await PasswordStore().initiatePassword(password); + if (mounted) Navigator.pop(context); +} +``` + +`createPassword()` is a function that returns a `Future` that will be used as the password. +In a real app, it could be a dialog that asks the user to create their password. + +`secure_store` includes several methods to enter a password: + +- `PasscodeInputView.showPattern()` to draw a pattern +- `PasscodeInputView.showPin()` to enter a pin +- `PasscodeInputView.showPassword()` to type a textual password +- `PasscodeInputView.showCustom()` to use anything you want to type your password while reusing the same logic as the other methods. + See below examples, and find more in the example project. + +
+Pattern input prompt example +Draw a pattern as your password. + +```dart +final result = await PasscodeInputView.showPattern( + context, + actionConfig: const PasscodeActionConfig.create( + createTitle: "Draw your pattern", + confirmTitle: "Confirm your pattern", + ), +) +``` + +
+ +
+Emoji input prompt example +Enter emoji as your password, like "👍🎨🚚👀" for instance. + +```dart +final password = await PasscodeInputView.showCustom( + context, + actionConfig: const PasscodeActionConfig.create( + createTitle: "Type your emoji password", + confirmTitle: "Confirm your emoji password", + ), + onWrongRepeatInput: (input) { + showSnackBar( + "Wrong input: $input", + success: false, + ); + }, + passcodeConfig: const PasscodeConfig( + backgroundColor: Colors.lightBlueAccent, + cancelButtonConfig: PasscodeCancelButtonConfig( + child: Text( + "❌ Mission aborted", + style: TextStyle(color: Colors.white), + ), + ), + ), + inputBuilder: ( + OnInputValidated onInputValidated, + bool isConfirming, + ) { + return EmojiInput( + onInputValidated: onInputValidated, + nextTitle: isConfirming ? "Confirm" : "Next", + ); + }, +) +``` + +
+ +### Storing the private key + +Use `BiomericStore.storePrivateKey` or `PasswordStore.storePrivateKey` to store the private key: + +```dart +final store = await SecureStore.get(); +await store.when( + biometric: (biometric) => biometric.storePrivateKey( + id: "uuid1", + privateKey: _privateKey, + ), + password: (password) => password.storePrivateKey( + id: "uuid1", + password: _password, + privateKey: _privateKey, + ), +); +``` + +Each private key is identified by an `id` (a `String`). +When using the `PasswordStore`, the password is used to encrypt the private key using AES 256 GCM. +The password is hashed using SHA 256. +The IV for AES is generated randomly, but you can also provide your own if needed. It must be 16 bytes long. + +### Retrieving the private key + +Similarly, you can retrieve the key using `BiomericStore.getPrivateKey` or `PasswordStore.getPrivateKey`: + +```dart +final store = await SecureStore.get(); +await store.when( + biometric: (biometric) => biometric.getPrivateKey(id: "uuid1"), + password: (password) => password.getPrivateKey( + id: "uuid1", + password: _password, + ), +); +``` + +## List exchange rates for a currency + +```dart +import 'package:secure_store/secure_store.dart'; + +void main() async { + final starknet = await Securestore.get(); + final exchangeRates = await starknet.getExchangeRates( + currency: "USD", + ); + print(exchangeRates); +} +``` + +## Running on Devnet + +Place yourself at the root of the monorepo project. +If you are in `secure_store`, this would be `../..`. +Call this to start the devnet: + +``` +poetry install +poetry run devnet start +``` + +Declare OpenZeppelin contract + +``` + +``` + +You are ready to create OpenZeppelin contracts, however you may need extra configuration if you want to run the example app. + +### Run the Flutter example on the devnet + +You need to define a NODE_URI dart environment variable like below: + +``` +--dart-define=NODE_URI=http://YOUR_HOST_IP:5050/rpc +``` + +For example with 192.168.1.15 as your host IP: + +``` +flutter run --dart-define=NODE_URI=http://192.168.1.15:5050/rpc +``` + +On Android Studio, you can add `--dart-define=NODE_URI=http://YOUR_HOST_IP:5050/rpc` to your run configuration in the "Additional run args" field. +On VS Code, you can also edit your `launch.json` to add `--dart-define=NODE_URI=http://YOUR_HOST_IP:5050/rpc` to your run configuration: + +```json +{ + "version": "0.2.0", + "configurations": [ + { + "name": "Example (Testnet)", + "request": "launch", + "type": "dart", + "program": "example/lib/main.dart" + }, + { + "name": "Example (Devnet)", + "request": "launch", + "type": "dart", + "program": "example/lib/main.dart", + "args": ["--dart-define=NODE_URI=http://192.168.1.15:5050/rpc"] + } + ] +} +``` + +### Send ETH to an address + +If your address is `0x7e678b687c94c9de17caeb4c39b86b2a4cb84312c4f93abbf42fb169377b845` for example, call from the monorepo root: + +``` +dart run ./packages/starknet/tool/send_eth.dart 0x7e678b687c94c9de17caeb4c39b86b2a4cb84312c4f93abbf42fb169377b845 +``` + +## Get ETH balance + +To display ETH balance of an account, you just need to call the `balance` property of a `PublicAccount` object. + +Example: + +```dart +// [...] select a wallet using wallet list for exemple. +final ethBalance = await selectedAccount.balance; +print('$ethBalance ETH'); // 0.045 ETH +``` + +## Get fiat equivalent to ETH balance + +```dart +final ethBalance = await selectedAccount.balance; +final ethExchangeRate = await ExchangeRates.get(from: 'ETH', to: 'USD'); // Change 'USD' to fiat currency you want +final fiatEquivalent = ethBalance * ethExchangeRate; +print('$fiatEquivalent \$'); // 43.34 $ +``` + +## Display formatted balance + +By default ETH balance was not rounded / truncated, if you want to display it properly on the UI, you can use following utils: + +First you need to import the plugin. + +```dart +import 'package:secure_store/secure_store.dart'; +``` + +- `truncateBalance()` this method wil truncate **without** round the value. + +Example: + +```dart +final ethBalance = 0.546365463; +String formatted = ethBalance.truncateBalance(precision: 4); +print(formatted) // 0.5463 +``` + +- `format()` this method will round value to 2 digits. + +Example: + +```dart +final ethBalance = 0.546365463; +String formatted = ethBalance.format(); +print(formatted) // 0.55 +``` + +## Display minified account address + +An address can be very long and it's pretty ugly. + +You can use the following snippet to display an address & keep first & last segment visible. + +```dart +final address = '0x53656356453665465364653664536426748692'; +final formatted = address.truncateMiddle(truncateLength: 20); +print(formatted) // 0x53656356...426748692 +``` + +## Show wallets list + +I you want to display the wallets list, you just have to call this code: + +```dart +StarknetWalletList.showModal( + context, + PasscodeInputView.showPinCode(context), +); +``` + +- `context` is used to display modal bottom sheet over your app. +- `passwordPrompt` is a method called when a password unlock is required to unlock sensitive data (you can set the pass code method you want). + +## Show transaction modal + +You can send ETH to a specific address. + +```dart +StarknetTransaction.showModal( + context, + args: transactionArguments, +); +``` + +- `context` is used to display modal bottom sheet over your app. +- `transactionArguments` handle the current selected `PublicAccount`. + +## Show account address QRCode + +You can display at anytime account QRCode address. + +```dart +StarknetReceive.showQRCodeModal( + context, + address: '0x0000', +); +``` + +- `context` is used to display modal bottom sheet over your app. +- `address` the account address to receive ETH. + +## Show wallet create/restore modal + +When called, the user can choose to create or restore a wallet. + +```dart +StarknetWallet.showInitializationModal( + context, + passwordPrompt: unlockWithPassword, +); +``` + +- `context` is used to display modal bottom sheet over your app. +- `passwordPrompt` is a method called when a password unlock is required to unlock sensitive data (you can set the pass code method you want). From 60c8b05ec67122982b15a17e6be6ebcc7d8cc730 Mon Sep 17 00:00:00 2001 From: Patrice Tisserand Date: Mon, 3 Mar 2025 15:34:03 +0100 Subject: [PATCH 11/11] restore original encoding --- docs/packages/starknet-provider.mdx | 132 ++-- packages/avnu_provider/README.md | 7 +- packages/secure_store/README.md | 202 +++--- packages/wallet_kit/README.md | 930 ++++++++++++++-------------- 4 files changed, 639 insertions(+), 632 deletions(-) diff --git a/docs/packages/starknet-provider.mdx b/docs/packages/starknet-provider.mdx index 18bbf9d5..e5980ccf 100644 --- a/docs/packages/starknet-provider.mdx +++ b/docs/packages/starknet-provider.mdx @@ -1,66 +1,66 @@ -# Starknet Provider - -A Dart package for interacting with Starknet node using JSON-RPC, following the [Starknet JSON-RPC specification](https://github.com/starkware-libs/starknet-specs.git). -[Package documentation](https://pub.dev/documentation/starknet_provider/latest/) - -## Transaction support - -| Feature | State | Version | -| -------------- | ----- | ------- | -| invoke | ✅ | 0, 1, 3 | -| declare | ✅ | 1, 2, 3 | -| deploy_account | ✅ | 1, 3 | - -## Supported JSON RPC methods - -### Version: 0.7.1 - -### Read methods - -Name of methods have been extracted from [starknet-specs](https://github.com/starkware-libs/starknet-specs.git) with the following command: - -```bash -jq .methods[].name ../starknet-specs/api/starknet_api_openrpc.json -``` - -| Name | Implemented | -| ---------------------------------------- | ----------- | -| starknet_specVersion | ❌ | -| starknet_getBlockWithTxHashes | ✅ | -| starknet_getBlockWithTxs | ✅ | -| starknet_getBlockWithReceipts | ❌ | -| starknet_getStateUpdate | ✅ | -| starknet_getStorageAt | ✅ | -| starknet_getTransactionStatus | ❌ | -| starknet_getTransactionByHash | ✅ | -| starknet_getTransactionByBlockIdAndIndex | ✅ | -| starknet_getTransactionReceipt | ✅ | -| starknet_getClass | ✅ | -| starknet_getClassHashAt | ✅ | -| starknet_getClassAt | ✅ | -| starknet_getBlockTransactionCount | ✅ | -| starknet_call | ✅ | -| starknet_estimateFee | ✅ | -| starknet_estimateMessageFee | ❌ | -| starknet_blockNumber | ✅ | -| starknet_blockHashAndNumber | ✅ | -| starknet_chainId | ✅ | -| starknet_syncing | ✅ | -| starknet_getEvents | ✅ | -| starknet_getNonce | ✅ | - -### Write methods - -Name of methods have been extracted from [starknet-specs](https://github.com/starkware-libs/starknet-specs.git) with the following command: - -```bash -jq .methods[].name ../starknet-specs/api/starknet_write_api.json -``` - -| Name | Implemented | -| ------------------------------------ | ----------- | -| starknet_addInvokeTransaction | ✅ | -| starknet_addDeclareTransaction | ✅ | -| starknet_addDeployAccountTransaction | ✅ | - -### Call read-only method +# Starknet Provider + +A Dart package for interacting with Starknet node using JSON-RPC, following the [Starknet JSON-RPC specification](https://github.com/starkware-libs/starknet-specs.git). +[Package documentation](https://pub.dev/documentation/starknet_provider/latest/) + +## Transaction support + +| Feature | State | Version | +| -------------- | ----- | ------- | +| invoke | ✅ | 0, 1, 3 | +| declare | ✅ | 1, 2, 3 | +| deploy_account | ✅ | 1, 3 | + +## Supported JSON RPC methods + +### Version: 0.7.1 + +### Read methods + +Name of methods have been extracted from [starknet-specs](https://github.com/starkware-libs/starknet-specs.git) with the following command: + +```bash +jq .methods[].name ../starknet-specs/api/starknet_api_openrpc.json +``` + +| Name | Implemented | +| ---------------------------------------- | ----------- | +| starknet_specVersion | ❌ | +| starknet_getBlockWithTxHashes | ✅ | +| starknet_getBlockWithTxs | ✅ | +| starknet_getBlockWithReceipts | ❌ | +| starknet_getStateUpdate | ✅ | +| starknet_getStorageAt | ✅ | +| starknet_getTransactionStatus | ❌ | +| starknet_getTransactionByHash | ✅ | +| starknet_getTransactionByBlockIdAndIndex | ✅ | +| starknet_getTransactionReceipt | ✅ | +| starknet_getClass | ✅ | +| starknet_getClassHashAt | ✅ | +| starknet_getClassAt | ✅ | +| starknet_getBlockTransactionCount | ✅ | +| starknet_call | ✅ | +| starknet_estimateFee | ✅ | +| starknet_estimateMessageFee | ❌ | +| starknet_blockNumber | ✅ | +| starknet_blockHashAndNumber | ✅ | +| starknet_chainId | ✅ | +| starknet_syncing | ✅ | +| starknet_getEvents | ✅ | +| starknet_getNonce | ✅ | + +### Write methods + +Name of methods have been extracted from [starknet-specs](https://github.com/starkware-libs/starknet-specs.git) with the following command: + +```bash +jq .methods[].name ../starknet-specs/api/starknet_write_api.json +``` + +| Name | Implemented | +| ------------------------------------ | ----------- | +| starknet_addInvokeTransaction | ✅ | +| starknet_addDeclareTransaction | ✅ | +| starknet_addDeployAccountTransaction | ✅ | + +### Call read-only method diff --git a/packages/avnu_provider/README.md b/packages/avnu_provider/README.md index 33507c44..cbf16dcb 100644 --- a/packages/avnu_provider/README.md +++ b/packages/avnu_provider/README.md @@ -1,3 +1,4 @@ -## AVNU Paymaster - -AVNU Paymaster i a Dart package that provides a way to interact with the [AVNU paymaster service](https://doc.avnu.fi/avnu-paymaster/overview). +## AVNU Paymaster + +AVNU Paymaster i a Dart package that provides a way to interact with the [AVNU paymaster service](https://doc.avnu.fi/avnu-paymaster/overview). + diff --git a/packages/secure_store/README.md b/packages/secure_store/README.md index 171ba427..fb2f5d4f 100644 --- a/packages/secure_store/README.md +++ b/packages/secure_store/README.md @@ -1,98 +1,104 @@ -# secure_store - -The secure store is a Flutter allowing to securely store secret on a device, either using a password, or using biometrics. - -| | PasswordStore | BiometricsStore | -| ------- | ------------- | --------------- | -| IOS | ✅ | ✅ | -| Android | ✅ | ✅ | -| Web | ✅ | ❌ | -| Mac | ✅ | ✅ | -| Windows | ✅ | ❌ | -| Linux | ✅ | ❌ | - -## Usage - -### Biometrics Store - -```dart -await BiometricStore().storeSecret( - secret: "Simplicity is the ultimate sophistication", - key: "biometrics-store:secret", -); - -final secret = await BiometricStore().getSecret( - key: "biometrics-store:secret", -); - -await BiometricStore().deleteSecret( - key: "biometrics-store:secret", -); -``` - -### Password Store - -First you need to initialize the password store since it's using Hive under the hood. - -```dart -// In main.dart -void main() { - PasswordStore.init(); - runApp(const MyApp()); -} -``` - -Then you can use password store very easily: - -```dart -await PasswordStore().storeSecret( - secret: "Simplicity is the ultimate sophistication", - key: "password-store:secret", - options: const PasswordStoreOptions(password: "1234"), -); - -final secret = await PasswordStore().getSecret( - key: "password-store:secret", - options: const PasswordStoreOptions(password: "1234"), -); -``` - -## Platform Setup - -### IOS - -Add `NSFaceIDUsageDescription` permission in `Info.plist`: - -```plist -NSFaceIDUsageDescription -Use Touch ID or Face ID to process transactions. -``` - -### Android - -Edit your `android/app/build.gradle`: - -```gradle -android { - defaultConfig { - minSdkVersion 23 - } -} -``` - -import io.flutter.embedding.android.FlutterFragmentActivity - -class MainActivity: FlutterFragmentActivity() { -} - -### Mac - -You need to add the Keychain Sharing capability in the Xcode project [following this guide](https://developer.apple.com/documentation/xcode/configuring-keychain-sharing). - -NOTE: you only need to add the capability, it's not needed to add any Keychain Groups. - -## Security Overview - -Some platforms and devices might be more secure than others. On iOS & MacOS, this plugin uses the [Secure Enclave](https://support.apple.com/fr-ca/guide/security/sec59b0b31ff/web) to protect the private key (if the device do not have a biometric component or not enabled, a password will be asked to encrypt data as a fallback method). On Android, the plugin biometric_storage is used. When biometric authentication is available, it is used to protect the private key. On other platforms and when the above is not available, the private key is encrypted using a password and stored in shared preferences. - -Here's an in-depth [architecture overview](https://focustree.notion.site/Seed-phrase-storage-cfafbd43f8b04b738dd66804459455fa?pvs=25). +# secure_store + +The secure store is a Flutter allowing to securely store secret on a device, either using a password, or using biometrics. + +| | PasswordStore | BiometricsStore | +| ------- | ------------- | --------------- | +| IOS | ✅ | ✅ | +| Android | ✅ | ✅ | +| Web | ✅ | ❌ | +| Mac | ✅ | ✅ | +| Windows | ✅ | ❌ | +| Linux | ✅ | ❌ | + +## Usage + +### Biometrics Store + +```dart +await BiometricStore().storeSecret( + secret: "Simplicity is the ultimate sophistication", + key: "biometrics-store:secret", +); + +final secret = await BiometricStore().getSecret( + key: "biometrics-store:secret", +); + +await BiometricStore().deleteSecret( + key: "biometrics-store:secret", +); +``` + +### Password Store + +First you need to initialize the password store since it's using Hive under the hood. + +```dart +// In main.dart +void main() { + PasswordStore.init(); + runApp(const MyApp()); +} +``` + +Then you can use password store very easily: + +```dart +await PasswordStore().storeSecret( + secret: "Simplicity is the ultimate sophistication", + key: "password-store:secret", + options: const PasswordStoreOptions(password: "1234"), +); + +final secret = await PasswordStore().getSecret( + key: "password-store:secret", + options: const PasswordStoreOptions(password: "1234"), +); +``` + +## Platform Setup + +### IOS + +Add `NSFaceIDUsageDescription` permission in `Info.plist`: + +```plist +NSFaceIDUsageDescription +Use Touch ID or Face ID to process transactions. +``` + +### Android + +Edit your `android/app/build.gradle`: + +```gradle +android { + defaultConfig { + minSdkVersion 23 + } +} +``` + +Change your `MainActivity` to extend `FlutterFragmentActivity` instead of `FlutterActivity`: + +```kt +package com.example.example + +import io.flutter.embedding.android.FlutterFragmentActivity + +class MainActivity: FlutterFragmentActivity() { +} +``` + +### Mac + +You need to add the Keychain Sharing capability in the Xcode project [following this guide](https://developer.apple.com/documentation/xcode/configuring-keychain-sharing). + +NOTE: you only need to add the capability, it's not needed to add any Keychain Groups. + +## Security Overview + +Some platforms and devices might be more secure than others. On iOS & MacOS, this plugin uses the [Secure Enclave](https://support.apple.com/fr-ca/guide/security/sec59b0b31ff/web) to protect the private key (if the device do not have a biometric component or not enabled, a password will be asked to encrypt data as a fallback method). On Android, the plugin biometric_storage is used. When biometric authentication is available, it is used to protect the private key. On other platforms and when the above is not available, the private key is encrypted using a password and stored in shared preferences. + +Here's an in-depth [architecture overview](https://focustree.notion.site/Seed-phrase-storage-cfafbd43f8b04b738dd66804459455fa?pvs=25). diff --git a/packages/wallet_kit/README.md b/packages/wallet_kit/README.md index db52a32d..eb99d5d9 100644 --- a/packages/wallet_kit/README.md +++ b/packages/wallet_kit/README.md @@ -1,465 +1,465 @@ -# secure_store - -A package to ease the use of [starknet](https://pub.dev/packages/starknet) in your Flutter app. - -## Dart setup - -Add the following to your `pubspec.yaml`: - -```yaml -dependencies: - secure_store: [version] -``` - -Then, run `flutter pub get`. - -You need to call `init()` method of the `secure_store` plugin before using it. - -A good place to do this in your `main.dart`: - -```dart -Future main() async { - await Securestore.init(); - runApp(const StarknetDemoApp()); -} -``` - -## Platform setup - -### iOS - -You need to add some permissions in the `info.plist` - -- FaceID (used to store/retrieve sensitive informations like Starknet private key for.) - -```plist -NSFaceIDUsageDescription -Use Touch ID or Face ID to process transactions. -``` - -- Camera (used to scan account address QRCode) - -```plist -NSCameraUsageDescription -This app needs camera access to scan QR codes -``` - -### MacOS - -Like iOS, you need to add some permissions - -- Keychain Sharing - -You need to add the `Keychain Sharing` capability in the Xcode project [following this guide](https://developer.apple.com/documentation/xcode/configuring-keychain-sharing). - -**NOTE: you only need to add the capability, it's not needed to add any `Keychain Groups`.** - -- Camera - -You need to enable `Camera` permission into App Sandbox [following this guide](https://developer.apple.com/documentation/xcode/configuring-the-macos-app-sandbox/). - -### Android - -This plugin requires minSdkVersion 23 (Android 6.0) or higher. -Edit you `android/app/build.gradle`: - -```groovy -android { - defaultConfig { - minSdkVersion 23 - } -} -``` - -Your `MainActivity` must extend `FlutterFragmentActivity`. - -Example: - -```kotlin -package com.example.myapp - -import io.flutter.embedding.android.FlutterFragmentActivity - -class MainActivity : FlutterFragmentActivity() { } -``` - -The theme of the main activity must use `Theme.AppCompat` or there will be crashes on Android < 29. -Edit your manifest at `android/app/src/main/AndroidManifest.xml`: - -```xml - - - - @drawable/launch_background - - true - false - true - @null - -``` - -You might edit the night variant as well at `android/app/src/main/res/values-night/styles.xml`. - -### Windows - -_TBD_ - -### Linux - -_TBD_ - -### Web - -_TBD_ - -## Usage - -Some platforms and devices might be more secure than others. -On iOS & MacOS, this plugin uses the [Secure Enclave](https://support.apple.com/fr-ca/guide/security/sec59b0b31ff/web) to protect the private key (if the device do not have a biometric component or not enabled, a password will be asked to encrypt data as a fallback method). -On Android, the plugin [biometric_storage](https://pub.dev/packages/biometric_storage) is used. When biometric authentication is available, it is used to protect the private key. -On other platforms and when the above is not available, the private key is encrypted using a password and stored in [shared preferences](https://pub.dev/packages/shared_preferences). - -For above reasons, either a `BiometricStore` or a `PasswordStore` is returned when calling `SecureStore.get()`. -For convenience, the `when` method is provided to handle both cases: - -```dart -// store might be either a `BiometricStore` or a `PasswordStore` -final store = await SecureStore.get(); - -// Use `when` to handle both cases -await store.when( - biometric: (biometric) async { - // Use the biometric store - }, - password: (password) async { - // Use the password store - }, -); -``` - -### Setting up your password - -While `BiometricStore` uses your already registered biometric authentication, `PasswordStore` requires you to provide an initial password that will be used to encrypt and decrypt your secrets. -You can do it with the following code: - -```dart -final password = await createPassword(context); -if (password != null) { - await PasswordStore().initiatePassword(password); - if (mounted) Navigator.pop(context); -} -``` - -`createPassword()` is a function that returns a `Future` that will be used as the password. -In a real app, it could be a dialog that asks the user to create their password. - -`secure_store` includes several methods to enter a password: - -- `PasscodeInputView.showPattern()` to draw a pattern -- `PasscodeInputView.showPin()` to enter a pin -- `PasscodeInputView.showPassword()` to type a textual password -- `PasscodeInputView.showCustom()` to use anything you want to type your password while reusing the same logic as the other methods. - See below examples, and find more in the example project. - -
-Pattern input prompt example -Draw a pattern as your password. - -```dart -final result = await PasscodeInputView.showPattern( - context, - actionConfig: const PasscodeActionConfig.create( - createTitle: "Draw your pattern", - confirmTitle: "Confirm your pattern", - ), -) -``` - -
- -
-Emoji input prompt example -Enter emoji as your password, like "👍🎨🚚👀" for instance. - -```dart -final password = await PasscodeInputView.showCustom( - context, - actionConfig: const PasscodeActionConfig.create( - createTitle: "Type your emoji password", - confirmTitle: "Confirm your emoji password", - ), - onWrongRepeatInput: (input) { - showSnackBar( - "Wrong input: $input", - success: false, - ); - }, - passcodeConfig: const PasscodeConfig( - backgroundColor: Colors.lightBlueAccent, - cancelButtonConfig: PasscodeCancelButtonConfig( - child: Text( - "❌ Mission aborted", - style: TextStyle(color: Colors.white), - ), - ), - ), - inputBuilder: ( - OnInputValidated onInputValidated, - bool isConfirming, - ) { - return EmojiInput( - onInputValidated: onInputValidated, - nextTitle: isConfirming ? "Confirm" : "Next", - ); - }, -) -``` - -
- -### Storing the private key - -Use `BiomericStore.storePrivateKey` or `PasswordStore.storePrivateKey` to store the private key: - -```dart -final store = await SecureStore.get(); -await store.when( - biometric: (biometric) => biometric.storePrivateKey( - id: "uuid1", - privateKey: _privateKey, - ), - password: (password) => password.storePrivateKey( - id: "uuid1", - password: _password, - privateKey: _privateKey, - ), -); -``` - -Each private key is identified by an `id` (a `String`). -When using the `PasswordStore`, the password is used to encrypt the private key using AES 256 GCM. -The password is hashed using SHA 256. -The IV for AES is generated randomly, but you can also provide your own if needed. It must be 16 bytes long. - -### Retrieving the private key - -Similarly, you can retrieve the key using `BiomericStore.getPrivateKey` or `PasswordStore.getPrivateKey`: - -```dart -final store = await SecureStore.get(); -await store.when( - biometric: (biometric) => biometric.getPrivateKey(id: "uuid1"), - password: (password) => password.getPrivateKey( - id: "uuid1", - password: _password, - ), -); -``` - -## List exchange rates for a currency - -```dart -import 'package:secure_store/secure_store.dart'; - -void main() async { - final starknet = await Securestore.get(); - final exchangeRates = await starknet.getExchangeRates( - currency: "USD", - ); - print(exchangeRates); -} -``` - -## Running on Devnet - -Place yourself at the root of the monorepo project. -If you are in `secure_store`, this would be `../..`. -Call this to start the devnet: - -``` -poetry install -poetry run devnet start -``` - -Declare OpenZeppelin contract - -``` - -``` - -You are ready to create OpenZeppelin contracts, however you may need extra configuration if you want to run the example app. - -### Run the Flutter example on the devnet - -You need to define a NODE_URI dart environment variable like below: - -``` ---dart-define=NODE_URI=http://YOUR_HOST_IP:5050/rpc -``` - -For example with 192.168.1.15 as your host IP: - -``` -flutter run --dart-define=NODE_URI=http://192.168.1.15:5050/rpc -``` - -On Android Studio, you can add `--dart-define=NODE_URI=http://YOUR_HOST_IP:5050/rpc` to your run configuration in the "Additional run args" field. -On VS Code, you can also edit your `launch.json` to add `--dart-define=NODE_URI=http://YOUR_HOST_IP:5050/rpc` to your run configuration: - -```json -{ - "version": "0.2.0", - "configurations": [ - { - "name": "Example (Testnet)", - "request": "launch", - "type": "dart", - "program": "example/lib/main.dart" - }, - { - "name": "Example (Devnet)", - "request": "launch", - "type": "dart", - "program": "example/lib/main.dart", - "args": ["--dart-define=NODE_URI=http://192.168.1.15:5050/rpc"] - } - ] -} -``` - -### Send ETH to an address - -If your address is `0x7e678b687c94c9de17caeb4c39b86b2a4cb84312c4f93abbf42fb169377b845` for example, call from the monorepo root: - -``` -dart run ./packages/starknet/tool/send_eth.dart 0x7e678b687c94c9de17caeb4c39b86b2a4cb84312c4f93abbf42fb169377b845 -``` - -## Get ETH balance - -To display ETH balance of an account, you just need to call the `balance` property of a `PublicAccount` object. - -Example: - -```dart -// [...] select a wallet using wallet list for exemple. -final ethBalance = await selectedAccount.balance; -print('$ethBalance ETH'); // 0.045 ETH -``` - -## Get fiat equivalent to ETH balance - -```dart -final ethBalance = await selectedAccount.balance; -final ethExchangeRate = await ExchangeRates.get(from: 'ETH', to: 'USD'); // Change 'USD' to fiat currency you want -final fiatEquivalent = ethBalance * ethExchangeRate; -print('$fiatEquivalent \$'); // 43.34 $ -``` - -## Display formatted balance - -By default ETH balance was not rounded / truncated, if you want to display it properly on the UI, you can use following utils: - -First you need to import the plugin. - -```dart -import 'package:secure_store/secure_store.dart'; -``` - -- `truncateBalance()` this method wil truncate **without** round the value. - -Example: - -```dart -final ethBalance = 0.546365463; -String formatted = ethBalance.truncateBalance(precision: 4); -print(formatted) // 0.5463 -``` - -- `format()` this method will round value to 2 digits. - -Example: - -```dart -final ethBalance = 0.546365463; -String formatted = ethBalance.format(); -print(formatted) // 0.55 -``` - -## Display minified account address - -An address can be very long and it's pretty ugly. - -You can use the following snippet to display an address & keep first & last segment visible. - -```dart -final address = '0x53656356453665465364653664536426748692'; -final formatted = address.truncateMiddle(truncateLength: 20); -print(formatted) // 0x53656356...426748692 -``` - -## Show wallets list - -I you want to display the wallets list, you just have to call this code: - -```dart -StarknetWalletList.showModal( - context, - PasscodeInputView.showPinCode(context), -); -``` - -- `context` is used to display modal bottom sheet over your app. -- `passwordPrompt` is a method called when a password unlock is required to unlock sensitive data (you can set the pass code method you want). - -## Show transaction modal - -You can send ETH to a specific address. - -```dart -StarknetTransaction.showModal( - context, - args: transactionArguments, -); -``` - -- `context` is used to display modal bottom sheet over your app. -- `transactionArguments` handle the current selected `PublicAccount`. - -## Show account address QRCode - -You can display at anytime account QRCode address. - -```dart -StarknetReceive.showQRCodeModal( - context, - address: '0x0000', -); -``` - -- `context` is used to display modal bottom sheet over your app. -- `address` the account address to receive ETH. - -## Show wallet create/restore modal - -When called, the user can choose to create or restore a wallet. - -```dart -StarknetWallet.showInitializationModal( - context, - passwordPrompt: unlockWithPassword, -); -``` - -- `context` is used to display modal bottom sheet over your app. -- `passwordPrompt` is a method called when a password unlock is required to unlock sensitive data (you can set the pass code method you want). +# secure_store + +A package to ease the use of [starknet](https://pub.dev/packages/starknet) in your Flutter app. + +## Dart setup + +Add the following to your `pubspec.yaml`: + +```yaml +dependencies: + secure_store: [version] +``` + +Then, run `flutter pub get`. + +You need to call `init()` method of the `secure_store` plugin before using it. + +A good place to do this in your `main.dart`: + +```dart +Future main() async { + await Securestore.init(); + runApp(const StarknetDemoApp()); +} +``` + +## Platform setup + +### iOS + +You need to add some permissions in the `info.plist` + +- FaceID (used to store/retrieve sensitive informations like Starknet private key for.) + +```plist +NSFaceIDUsageDescription +Use Touch ID or Face ID to process transactions. +``` + +- Camera (used to scan account address QRCode) + +```plist +NSCameraUsageDescription +This app needs camera access to scan QR codes +``` + +### MacOS + +Like iOS, you need to add some permissions + +- Keychain Sharing + +You need to add the `Keychain Sharing` capability in the Xcode project [following this guide](https://developer.apple.com/documentation/xcode/configuring-keychain-sharing). + +**NOTE: you only need to add the capability, it's not needed to add any `Keychain Groups`.** + +- Camera + +You need to enable `Camera` permission into App Sandbox [following this guide](https://developer.apple.com/documentation/xcode/configuring-the-macos-app-sandbox/). + +### Android + +This plugin requires minSdkVersion 23 (Android 6.0) or higher. +Edit you `android/app/build.gradle`: + +```groovy +android { + defaultConfig { + minSdkVersion 23 + } +} +``` + +Your `MainActivity` must extend `FlutterFragmentActivity`. + +Example: + +```kotlin +package com.example.myapp + +import io.flutter.embedding.android.FlutterFragmentActivity + +class MainActivity : FlutterFragmentActivity() { } +``` + +The theme of the main activity must use `Theme.AppCompat` or there will be crashes on Android < 29. +Edit your manifest at `android/app/src/main/AndroidManifest.xml`: + +```xml + + + + @drawable/launch_background + + true + false + true + @null + +``` + +You might edit the night variant as well at `android/app/src/main/res/values-night/styles.xml`. + +### Windows + +_TBD_ + +### Linux + +_TBD_ + +### Web + +_TBD_ + +## Usage + +Some platforms and devices might be more secure than others. +On iOS & MacOS, this plugin uses the [Secure Enclave](https://support.apple.com/fr-ca/guide/security/sec59b0b31ff/web) to protect the private key (if the device do not have a biometric component or not enabled, a password will be asked to encrypt data as a fallback method). +On Android, the plugin [biometric_storage](https://pub.dev/packages/biometric_storage) is used. When biometric authentication is available, it is used to protect the private key. +On other platforms and when the above is not available, the private key is encrypted using a password and stored in [shared preferences](https://pub.dev/packages/shared_preferences). + +For above reasons, either a `BiometricStore` or a `PasswordStore` is returned when calling `SecureStore.get()`. +For convenience, the `when` method is provided to handle both cases: + +```dart +// store might be either a `BiometricStore` or a `PasswordStore` +final store = await SecureStore.get(); + +// Use `when` to handle both cases +await store.when( + biometric: (biometric) async { + // Use the biometric store + }, + password: (password) async { + // Use the password store + }, +); +``` + +### Setting up your password + +While `BiometricStore` uses your already registered biometric authentication, `PasswordStore` requires you to provide an initial password that will be used to encrypt and decrypt your secrets. +You can do it with the following code: + +```dart +final password = await createPassword(context); +if (password != null) { + await PasswordStore().initiatePassword(password); + if (mounted) Navigator.pop(context); +} +``` + +`createPassword()` is a function that returns a `Future` that will be used as the password. +In a real app, it could be a dialog that asks the user to create their password. + +`secure_store` includes several methods to enter a password: + +- `PasscodeInputView.showPattern()` to draw a pattern +- `PasscodeInputView.showPin()` to enter a pin +- `PasscodeInputView.showPassword()` to type a textual password +- `PasscodeInputView.showCustom()` to use anything you want to type your password while reusing the same logic as the other methods. + See below examples, and find more in the example project. + +
+Pattern input prompt example +Draw a pattern as your password. + +```dart +final result = await PasscodeInputView.showPattern( + context, + actionConfig: const PasscodeActionConfig.create( + createTitle: "Draw your pattern", + confirmTitle: "Confirm your pattern", + ), +) +``` + +
+ +
+Emoji input prompt example +Enter emoji as your password, like "👍🎨🚚👀" for instance. + +```dart +final password = await PasscodeInputView.showCustom( + context, + actionConfig: const PasscodeActionConfig.create( + createTitle: "Type your emoji password", + confirmTitle: "Confirm your emoji password", + ), + onWrongRepeatInput: (input) { + showSnackBar( + "Wrong input: $input", + success: false, + ); + }, + passcodeConfig: const PasscodeConfig( + backgroundColor: Colors.lightBlueAccent, + cancelButtonConfig: PasscodeCancelButtonConfig( + child: Text( + "❌ Mission aborted", + style: TextStyle(color: Colors.white), + ), + ), + ), + inputBuilder: ( + OnInputValidated onInputValidated, + bool isConfirming, + ) { + return EmojiInput( + onInputValidated: onInputValidated, + nextTitle: isConfirming ? "Confirm" : "Next", + ); + }, +) +``` + +
+ +### Storing the private key + +Use `BiomericStore.storePrivateKey` or `PasswordStore.storePrivateKey` to store the private key: + +```dart +final store = await SecureStore.get(); +await store.when( + biometric: (biometric) => biometric.storePrivateKey( + id: "uuid1", + privateKey: _privateKey, + ), + password: (password) => password.storePrivateKey( + id: "uuid1", + password: _password, + privateKey: _privateKey, + ), +); +``` + +Each private key is identified by an `id` (a `String`). +When using the `PasswordStore`, the password is used to encrypt the private key using AES 256 GCM. +The password is hashed using SHA 256. +The IV for AES is generated randomly, but you can also provide your own if needed. It must be 16 bytes long. + +### Retrieving the private key + +Similarly, you can retrieve the key using `BiomericStore.getPrivateKey` or `PasswordStore.getPrivateKey`: + +```dart +final store = await SecureStore.get(); +await store.when( + biometric: (biometric) => biometric.getPrivateKey(id: "uuid1"), + password: (password) => password.getPrivateKey( + id: "uuid1", + password: _password, + ), +); +``` + +## List exchange rates for a currency + +```dart +import 'package:secure_store/secure_store.dart'; + +void main() async { + final starknet = await Securestore.get(); + final exchangeRates = await starknet.getExchangeRates( + currency: "USD", + ); + print(exchangeRates); +} +``` + +## Running on Devnet + +Place yourself at the root of the monorepo project. +If you are in `secure_store`, this would be `../..`. +Call this to start the devnet: + +``` +poetry install +poetry run devnet start +``` + +Declare OpenZeppelin contract + +``` + +``` + +You are ready to create OpenZeppelin contracts, however you may need extra configuration if you want to run the example app. + +### Run the Flutter example on the devnet + +You need to define a NODE_URI dart environment variable like below: + +``` +--dart-define=NODE_URI=http://YOUR_HOST_IP:5050/rpc +``` + +For example with 192.168.1.15 as your host IP: + +``` +flutter run --dart-define=NODE_URI=http://192.168.1.15:5050/rpc +``` + +On Android Studio, you can add `--dart-define=NODE_URI=http://YOUR_HOST_IP:5050/rpc` to your run configuration in the "Additional run args" field. +On VS Code, you can also edit your `launch.json` to add `--dart-define=NODE_URI=http://YOUR_HOST_IP:5050/rpc` to your run configuration: + +```json +{ + "version": "0.2.0", + "configurations": [ + { + "name": "Example (Testnet)", + "request": "launch", + "type": "dart", + "program": "example/lib/main.dart" + }, + { + "name": "Example (Devnet)", + "request": "launch", + "type": "dart", + "program": "example/lib/main.dart", + "args": ["--dart-define=NODE_URI=http://192.168.1.15:5050/rpc"] + } + ] +} +``` + +### Send ETH to an address + +If your address is `0x7e678b687c94c9de17caeb4c39b86b2a4cb84312c4f93abbf42fb169377b845` for example, call from the monorepo root: + +``` +dart run ./packages/starknet/tool/send_eth.dart 0x7e678b687c94c9de17caeb4c39b86b2a4cb84312c4f93abbf42fb169377b845 +``` + +## Get ETH balance + +To display ETH balance of an account, you just need to call the `balance` property of a `PublicAccount` object. + +Example: + +```dart +// [...] select a wallet using wallet list for exemple. +final ethBalance = await selectedAccount.balance; +print('$ethBalance ETH'); // 0.045 ETH +``` + +## Get fiat equivalent to ETH balance + +```dart +final ethBalance = await selectedAccount.balance; +final ethExchangeRate = await ExchangeRates.get(from: 'ETH', to: 'USD'); // Change 'USD' to fiat currency you want +final fiatEquivalent = ethBalance * ethExchangeRate; +print('$fiatEquivalent \$'); // 43.34 $ +``` + +## Display formatted balance + +By default ETH balance was not rounded / truncated, if you want to display it properly on the UI, you can use following utils: + +First you need to import the plugin. + +```dart +import 'package:secure_store/secure_store.dart'; +``` + +- `truncateBalance()` this method wil truncate **without** round the value. + +Example: + +```dart +final ethBalance = 0.546365463; +String formatted = ethBalance.truncateBalance(precision: 4); +print(formatted) // 0.5463 +``` + +- `format()` this method will round value to 2 digits. + +Example: + +```dart +final ethBalance = 0.546365463; +String formatted = ethBalance.format(); +print(formatted) // 0.55 +``` + +## Display minified account address + +An address can be very long and it's pretty ugly. + +You can use the following snippet to display an address & keep first & last segment visible. + +```dart +final address = '0x53656356453665465364653664536426748692'; +final formatted = address.truncateMiddle(truncateLength: 20); +print(formatted) // 0x53656356...426748692 +``` + +## Show wallets list + +I you want to display the wallets list, you just have to call this code: + +```dart +StarknetWalletList.showModal( + context, + PasscodeInputView.showPinCode(context), +); +``` + +- `context` is used to display modal bottom sheet over your app. +- `passwordPrompt` is a method called when a password unlock is required to unlock sensitive data (you can set the pass code method you want). + +## Show transaction modal + +You can send ETH to a specific address. + +```dart +StarknetTransaction.showModal( + context, + args: transactionArguments, +); +``` + +- `context` is used to display modal bottom sheet over your app. +- `transactionArguments` handle the current selected `PublicAccount`. + +## Show account address QRCode + +You can display at anytime account QRCode address. + +```dart +StarknetReceive.showQRCodeModal( + context, + address: '0x0000', +); +``` + +- `context` is used to display modal bottom sheet over your app. +- `address` the account address to receive ETH. + +## Show wallet create/restore modal + +When called, the user can choose to create or restore a wallet. + +```dart +StarknetWallet.showInitializationModal( + context, + passwordPrompt: unlockWithPassword, +); +``` + +- `context` is used to display modal bottom sheet over your app. +- `passwordPrompt` is a method called when a password unlock is required to unlock sensitive data (you can set the pass code method you want).