starknet_flutter

Creator: coderz1093

Last updated:

0 purchases

TODO
Add to Cart

Description:

starknet flutter

starknet_flutter #
A package to ease the use of starknet in your Flutter app.
Dart setup #
Add the following to your pubspec.yaml:
dependencies:
starknet_flutter: [version]
copied to clipboard
Then, run flutter pub get.
You need to call init() method of the starknet_flutter plugin before using it.
A good place to do this in your main.dart:
Future<void> main() async {
await StarknetFlutter.init();
runApp(const StarknetDemoApp());
}
copied to clipboard
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.)

<key>NSFaceIDUsageDescription</key>
<string>Use Touch ID or Face ID to process transactions.</string>
copied to clipboard

Camera (used to scan account address QRCode)

<key>NSCameraUsageDescription</key>
<string>This app needs camera access to scan QR codes</string>
copied to clipboard
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.
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.
Android #
This plugin requires minSdkVersion 23 (Android 6.0) or higher.
Edit you android/app/build.gradle:
android {
defaultConfig {
minSdkVersion 23
}
}
copied to clipboard
Your MainActivity must extend FlutterFragmentActivity.
Example:
package com.example.myapp

import io.flutter.embedding.android.FlutterFragmentActivity

class MainActivity : FlutterFragmentActivity() { }
copied to clipboard
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:

<activity android:name=".MainActivity" android:launchMode="singleTop"
android:theme="@style/LaunchTheme"
copied to clipboard
Then, change the theme set in android/app/src/main/res/values/styles.xml:

<style name="LaunchTheme" parent="Theme.AppCompat.NoActionBar">
<!-- Show a splash screen on the activity. Automatically removed when
Flutter draws its first frame -->
<item name="android:windowBackground">@drawable/launch_background</item>

<item name="android:windowNoTitle">true</item>
<item name="android:windowActionBar">false</item>
<item name="android:windowFullscreen">true</item>
<item name="android:windowContentOverlay">@null</item>
</style>
copied to clipboard
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 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.
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:
// 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
},
);
copied to clipboard
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:
final password = await createPassword(context);
if (password != null) {
await PasswordStore().initiatePassword(password);
if (mounted) Navigator.pop(context);
}
copied to clipboard
createPassword() is a function that returns a Future<String?> that will be used as the password.
In a real app, it could be a dialog that asks the user to create their password.
starknet_flutter 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.
final result = await PasscodeInputView.showPattern(
context,
actionConfig: const PasscodeActionConfig.create(
createTitle: "Draw your pattern",
confirmTitle: "Confirm your pattern",
),
)
copied to clipboard


Emoji input prompt example
Enter emoji as your password, like "👍🎨🚚👀" for instance.
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",
);
},
)
copied to clipboard

Storing the private key #
Use BiomericStore.storePrivateKey or PasswordStore.storePrivateKey to store the private key:
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,
),
);
copied to clipboard
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:
final store = await SecureStore.get();
await store.when(
biometric: (biometric) => biometric.getPrivateKey(id: "uuid1"),
password: (password) => password.getPrivateKey(
id: "uuid1",
password: _password,
),
);
copied to clipboard
List exchange rates for a currency #
import 'package:starknet_flutter/starknet_flutter.dart';

void main() async {
final starknet = await StarknetFlutter.get();
final exchangeRates = await starknet.getExchangeRates(
currency: "USD",
);
print(exchangeRates);
}
copied to clipboard
Running on Devnet #
Place yourself at the root of the monorepo project.
If you are in starknet_flutter, this would be ../...
Call this to start the devnet:
poetry install
poetry run devnet start
copied to clipboard
Declare OpenZeppelin contract
copied to clipboard
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
copied to clipboard
For example with 192.168.1.15 as your host IP:
flutter run --dart-define=NODE_URI=http://192.168.1.15:5050/rpc
copied to clipboard
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:
{
"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"
]
}
]
}

copied to clipboard
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
copied to clipboard
Get ETH balance #
To display ETH balance of an account, you just need to call the balance property of a PublicAccount object.
Example:
// [...] select a wallet using wallet list for exemple.
final ethBalance = await selectedAccount.balance;
print('$ethBalance ETH'); // 0.045 ETH
copied to clipboard
Get fiat equivalent to ETH balance #
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 $
copied to clipboard
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.
import 'package:starknet_flutter/starknet_flutter.dart';
copied to clipboard

truncateBalance() this method wil truncate without round the value.

Example:
final ethBalance = 0.546365463;
String formatted = ethBalance.truncateBalance(precision: 4);
print(formatted) // 0.5463
copied to clipboard

format() this method will round value to 2 digits.

Example:
final ethBalance = 0.546365463;
String formatted = ethBalance.format();
print(formatted) // 0.55
copied to clipboard
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.
final address = '0x53656356453665465364653664536426748692';
final formatted = address.truncateMiddle(truncateLength: 20);
print(formatted) // 0x53656356...426748692
copied to clipboard
Show wallets list #
I you want to display the wallets list, you just have to call this code:
StarknetWalletList.showModal(
context,
PasscodeInputView.showPinCode(context),
);
copied to clipboard

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.
StarknetTransaction.showModal(
context,
args: transactionArguments,
);
copied to clipboard

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.
StarknetReceive.showQRCodeModal(
context,
address: '0x0000',
);
copied to clipboard

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.
StarknetWallet.showInitializationModal(
context,
passwordPrompt: unlockWithPassword,
);
copied to clipboard

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).

License

For personal and professional use. You cannot resell or redistribute these repositories in their original state.

Files In This Product:

Customer Reviews

There are no reviews.