### Start Local Starknet Devnet Source: https://starknetdart.dev/examples/starknet-counter Command to start a local Starknet development network instance with a specific seed and port. This command initializes the devnet, making it ready for contract deployment and interaction. ```Shell $ starknet-devnet --seed 0 --port 5050 ``` -------------------------------- ### Install Starkli CLI Source: https://starknetdart.dev/examples/starknet-counter Instructions to install Starkli version 0.3.5 using `asdf`. Starkli is a command-line interface for interacting with Starknet, useful for deploying and managing contracts. ```Shell asdf install starkli 0.3.5 asdf global starkli 0.3.5 ``` -------------------------------- ### Install Starknet Devnet Source: https://starknetdart.dev/examples/starknet-counter Instructions to install Starknet Devnet version 0.2.0 using `asdf`. Starknet Devnet is a local development network that simulates the Starknet blockchain, allowing for local testing and deployment. ```Shell asdf install starknet-devnet 0.2.0 asdf global starknet-devnet 0.2.0 ``` -------------------------------- ### Example Output of Running Starknet Devnet Source: https://starknetdart.dev/examples/starknet-counter Illustrative output showing the details of a running Starknet Devnet instance, including predeployed tokens, UDC, chain ID, and example account addresses with private/public keys. This output confirms the successful launch of the devnet and provides essential network information. ```Shell Predeployed FeeToken ETH Address: 0x49D36570D4E46F48E99674BD3FCC84644DDD6B96F7C741B1562B82F9E004DC7 STRK Address: 0x04718f5a0fc34cc1af16a1cdee98ffb20c31f5cd61d6ab07201858f4287c938d Class Hash: 0x046ded64ae2dead6448e247234bab192a9c483644395b66f2155f2614e5804b0 Predeployed UDC Address: 0x41A78E741E5AF2FEC34B695679BC6891742439F7AFB8484ECD7766661AD02BF Class Hash: 0x7B3E05F48F0C69E4A65CE5E076A66271A527AFF2C34CE1083EC6E1526997A69 Chain ID: SN_SEPOLIA (0x534e5f5345504f4c4941) | Account address | 0x64b48806902a367c8598f4f95c305e8c1a1acba5f082d294a43793113115691 | Private key | 0x71d7bb07b9a64f6f78ac4c816aff4da9 | Public key | 0x39d9e6ce352ad4530a0ef5d5a18fd3303c3606a7fa6ac5b620020ad681cc33b | Account address | 0x78662e7352d062084b0010068b99288486c2d8b914f6e2a55ce945f8792c8b1 | Private key | 0xe1406455b7d66b1690803be066cbe5e | Public key | 0x7a1bb2744a7dd29bffd44341dbd78008adb4bc11733601e7eddff322ada9cb ... ``` -------------------------------- ### Starkli Deploy Output Example Source: https://starknetdart.dev/examples/starknet-counter Example output after successfully deploying a Starknet contract, showing the deployed contract address. This address is needed to interact with the contract instance. ```Text WARNING: using private key in plain text is highly insecure, and you should... ... Contract deployed: 0x02b955c900b35047f94200a336ee815587dbe228371f8b3194b7c6eb2b70a056 ``` -------------------------------- ### Install Scarb for Starknet Development Source: https://starknetdart.dev/examples/starknet-counter Instructions to install Scarb version 2.8.4 using `asdf`. Scarb is a build toolchain for Cairo and Starknet, essential for compiling Starknet contracts. ```Shell asdf install scarb 2.8.4 asdf global scarb 2.8.4 ``` -------------------------------- ### Create Flutter Project Source: https://starknetdart.dev/examples/starknet-counter Commands to initialize a new Flutter project and navigate into its directory, setting up the environment for a new mobile application. ```Bash $ flutter create starknet_counter $ cd starknet_counter ``` -------------------------------- ### Start Starknet Devnet locally Source: https://starknetdart.dev/examples/starknet-cli This command executes the Starknet Devnet within the Poetry environment, starting a local Starknet development network for testing and deployment. ```shell poetry run starknet-devnet ``` -------------------------------- ### Scarb Build Output Example Source: https://starknetdart.dev/examples/starknet-counter Example output after successfully compiling a Cairo contract with Scarb, indicating the compilation status and time taken. ```Text Compiling contract v0.1.0 (/.../contract/Scarb.toml) Finished `dev` profile target(s) in 16 seconds ``` -------------------------------- ### Starkli Declare Output Example Source: https://starknetdart.dev/examples/starknet-counter Example output after successfully declaring a Starknet contract, showing transaction confirmation and the resulting class hash. This class hash is crucial for deploying instances of the contract. ```Text WARNING: using private key in plain text is highly insecure, and you should... ... Transaction 0x060516c3d8c89327d5fd993e7deee37c2d0ce694111073a4f96d5c2f7d331f81 confirmed Class hash declared: 0x037075473c665d582edbb379dfc87167076c6c714416190dcc3db27dc54eb84b ``` -------------------------------- ### Deploy Starknet Contract Source: https://starknetdart.dev/examples/starknet-counter Command to deploy a declared Starknet contract on the devnet using `starkli`. It requires a salt, RPC endpoint, account configuration, and the previously obtained class hash. ```Bash ~/contract$ starkli deploy --salt 0x42 --watch --rpc http://localhost:5050 --account devnet-acct.json 0x037075473c665d582edbb379dfc87167076c6c714416190dcc3db27dc54eb84b ``` -------------------------------- ### Initialize a New Starknet Project with Scarb Source: https://starknetdart.dev/examples/starknet-counter Commands to create a new directory for a Starknet contract and initialize a Scarb project within it. This sets up the basic project structure for Cairo development, including necessary configuration files. ```Shell mkdir contract cd contract ~/contract$ scarb init Created package. ``` -------------------------------- ### Complete Flutter App Initialization and Main Widget Source: https://starknetdart.dev/examples/mobile-wallet Presents the complete `main.dart` file, integrating all previous setup steps including environment loading, WalletKit/Hive initialization, UI configuration, and running the `WalletApp` widget within a `ProviderScope`. ```Dart import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter_dotenv/flutter_dotenv.dart'; import 'package:hive_flutter/hive_flutter.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:wallet_kit/wallet_kit.dart'; import './screens/home_screen.dart'; Future main() async { WidgetsFlutterBinding.ensureInitialized(); await dotenv.load(); WalletKit().init( accountClassHash: dotenv.env['ACCOUNT_CLASS_HASH'] as String, rpc: dotenv.env['RPC'] as String, ); await Hive.initFlutter(); SystemChrome.setEnabledSystemUIMode( SystemUiMode.edgeToEdge, ); SystemChrome.setPreferredOrientations([ DeviceOrientation.portraitUp, DeviceOrientation.portraitDown, ]); SystemChrome.setSystemUIOverlayStyle(const SystemUiOverlayStyle( statusBarColor: Colors.transparent, statusBarIconBrightness: Brightness.dark, systemNavigationBarColor: Colors.transparent, systemNavigationBarDividerColor: Colors.transparent, systemNavigationBarIconBrightness: Brightness.dark, )); runApp(const ProviderScope(child: WalletApp())); } class WalletApp extends HookConsumerWidget { const WalletApp({super.key}); @override Widget build(BuildContext context, WidgetRef ref) { return MaterialApp( title: 'Starknet Wallet', home: const Placeholder(), theme: walletThemeData, debugShowCheckedModeBanner: false, ); } } ``` -------------------------------- ### Implement Starknet Counter Contract in Cairo Source: https://starknetdart.dev/examples/starknet-counter Full Cairo code for the `Counter` contract, defining an interface (`ICounter`) with methods for incrementing, decrementing, increasing by a number, and getting the current count. It includes storage definition and a constructor to initialize the count. ```Cairo #[starknet::interface] trait ICounter { fn increment(ref self: TState); fn decrement(ref self: TState); fn increase_count_by(ref self: TState, number: u64); fn get_current_count(self: @TState) -> u64; } #[starknet::contract] mod Counter { #[storage] struct Storage { _count: u64, } #[constructor] fn constructor(ref self: ContractState) { self._count.write(1); } #[abi(embed_v0)] impl CounterImpl of super::ICounter { fn increment(ref self: ContractState,) { let current_count = self._count.read(); self._count.write(current_count + 1); } fn decrement(ref self: ContractState,) { let current_count = self._count.read(); self._count.write(current_count -1); } fn increase_count_by(ref self: ContractState, number: u64) { let current_count = self._count.read(); self._count.write(current_count + number); } fn get_current_count(self: @ContractState) -> u64 { self._count.read() } } } ``` -------------------------------- ### Export Starknet Private Key Source: https://starknetdart.dev/examples/starknet-counter Command to set the Starknet private key as an environment variable. This key is used by `starkli` for signing transactions. ```Bash ~/contract$ export STARKNET_PRIVATE_KEY="0x71d7bb07b9a64f6f78ac4c816aff4da9" ``` -------------------------------- ### Verify Scarb installation Source: https://starknetdart.dev/examples/starknet-cli This command checks the installed version of Scarb, ensuring that the contract build tool is correctly set up and accessible in the environment. ```shell scarb --version ``` -------------------------------- ### Start Starknet Devnet Source: https://starknetdart.dev/how-to-contribute Command to start the local Starknet development network in a dedicated terminal, providing a local blockchain environment for testing and development. ```Shell melos devnet:start ``` -------------------------------- ### Set Up Starknet Development Environment Source: https://starknetdart.dev/how-to-contribute Commands to load environment variables and set up the Starknet development environment. This step requires `asdf` and `cargo` to be installed beforehand for managing Rust toolchains and devnet dependencies. ```Shell source .env.devnet melos starknet:setup ``` -------------------------------- ### Configure Scarb.toml for Starknet Project Source: https://starknetdart.dev/examples/starknet-counter Configuration for the `Scarb.toml` file, specifying the package name and version. This file is crucial for Scarb to correctly build and manage the Cairo contract project. ```TOML [package] name = "contract" version = "0.1.0" ``` -------------------------------- ### Compile Cairo Contract with Scarb Source: https://starknetdart.dev/examples/starknet-counter Command to compile the Cairo contract using the Scarb build tool, preparing it for deployment on Starknet. ```Bash $ scarb build ``` -------------------------------- ### Initialize Flutter Widgets in main.dart Source: https://starknetdart.dev/examples/mobile-wallet Starts with a basic `main` function in 'main.dart' to ensure Flutter widgets are initialized before the app runs. ```Dart import 'package:flutter/material.dart'; Future main() async { WidgetsFlutterBinding.ensureInitialized(); } ``` -------------------------------- ### Start Devnet in Dump Mode Source: https://starknetdart.dev/how-to-contribute Command to start the Starknet devnet in a special dump mode, which allows for capturing the state of the devnet after contract deployments. ```Shell melos devnet:start:dump ``` -------------------------------- ### Create new Flutter project for NFT marketplace Source: https://starknetdart.dev/examples/nft-marketplace Initializes a new Flutter application named `nft_marketplace`. This command sets up the basic project structure, preparing it for mobile development. Run `flutter run` to verify the setup. ```Shell flutter create nft_marketplace ``` -------------------------------- ### Initialize Flutter Application Main Entry Point Source: https://starknetdart.dev/examples/starknet-counter This `main.dart` file serves as the entry point for the Flutter application. It initializes the `MyApp` widget, which sets up the basic material design theme and defines the `CounterPage` as the application's home screen. ```Dart import './ui/counter.dart'; import 'package:flutter/material.dart'; void main() { runApp(const MyApp()); } class MyApp extends StatelessWidget { const MyApp({super.key}); // This widget is the root of your application. @override Widget build(BuildContext context) { return MaterialApp( title: 'Flutter Startnet Counter', theme: ThemeData( colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple), useMaterial3: true, ), home: const CounterPage(title: 'Flutter Starknet'), ); } } ``` -------------------------------- ### Devnet Account Configuration JSON Source: https://starknetdart.dev/examples/starknet-counter JSON configuration for a devnet account, including version, variant (OpenZeppelin), public key, and deployment details like class hash and address. This file is used by starkli for account operations. ```JSON { "version": 1, "variant": { "type": "open_zeppelin", "version": 1, "public_key": "0x39d9e6ce352ad4530a0ef5d5a18fd3303c3606a7fa6ac5b620020ad681c cc33b", "legacy": false }, "deployment": { "status": "deployed", "class_hash": "0x61dac032f228abef9c6626f995015233097ae253a7f72d68552db02f297 1b8f", "address": "0x64b48806902a367c8598f4f95c305e8c1a1acba5f082d294a4379311311569 1" } } ``` -------------------------------- ### Scarb.toml Dependency Configuration Source: https://starknetdart.dev/examples/starknet-counter Defines project dependencies for a Starknet contract, specifying the required Starknet version and target type. ```TOML [dependencies] starknet = ">=2.2.0" [[target.starknet-contract]] ``` -------------------------------- ### Flutter pubspec.yaml with starknet_dart Dependency Source: https://starknetdart.dev/examples/starknet-counter Configuration file for a Flutter project, adding the `starknet_dart` package as a dependency. This enables Starknet interaction within the Flutter application. ```YAML name: starknet_counter description: A new Flutter project. # The following line prevents the package from being accidentally published to ``` -------------------------------- ### Flutter Counter App UI and State Management Source: https://starknetdart.dev/examples/starknet-counter This Dart code defines the user interface and state management logic for a Flutter counter application. It includes asynchronous functions to interact with a Starknet counter contract (increment, decrement, get, increment by amount) and updates the UI accordingly. The `build` method constructs the Scaffold, AppBar, and body with input fields, text display, and action buttons. ```Dart _increaseCount() async { await increaseCounter(); await _getCounter(); setState(() {}); } _increaseCountBy() async { await increaseCounterBy(amount.text.trim()); await _getCounter(); amount.clear(); setState(() {}); } _decreaseCount() async { await decreaseCounter(); await _getCounter(); setState(() {}); } _getCounter() async { int balcounter = await getCurrentCount(); setState(() { counter = balcounter; }); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( backgroundColor: Theme.of(context).colorScheme.inversePrimary, title: Text(widget.title), ), body: Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ const SizedBox( height: 20, ), Text("Counter is : $counter"), const SizedBox( height: 20, ), SizedBox( width: 500, child: TextField( controller: amount, decoration: const InputDecoration( border: OutlineInputBorder(), hintText: 'Enter your Amount', ), ), ), const SizedBox( height: 20, ), Wrap( alignment: WrapAlignment.center, spacing: 20, runSpacing: 10, children: [ ElevatedButton( onPressed: _increaseCount, child: const Text('increment')), ElevatedButton( onPressed: _increaseCountBy, child: const Text('incrementBy')), ElevatedButton( onPressed: (() => _getCounter()), child: const Text('get count')), ElevatedButton( onPressed: _decreaseCount, child: const Text('decrement')) ] ) ] ) ) ); } } ``` -------------------------------- ### Install Wallet Kit and its Flutter dependencies Source: https://starknetdart.dev/examples/nft-marketplace Adds `flutter_riverpod`, `hive_flutter`, and `wallet_kit` packages to the Flutter project. These dependencies are crucial for state management, local data storage, and integrating wallet functionalities. ```Shell flutter pub add flutter_riverpod hive_flutter wallet_kit ``` -------------------------------- ### Install and update Rust toolchain Source: https://starknetdart.dev/examples/starknet-cli This command sequence installs and updates the Rust toolchain to the stable version. Rust is required for compiling Starknet contracts using Scarb. ```shell rustup override set stable && rustup update ``` -------------------------------- ### Clone Ark protocol project repository Source: https://starknetdart.dev/examples/nft-marketplace Clones the Ark protocol's GitHub repository. This provides the necessary smart contracts and tools for integrating the NFT marketplace functionalities. Follow the README instructions for local setup. ```Shell git clone git@github.com:ArkProjectNFTs/ark-project.git ``` -------------------------------- ### Configure Flutter Project Dependencies and Publishing Source: https://starknetdart.dev/examples/starknet-counter This `pubspec.yaml` file defines the project's metadata, Dart SDK constraints, and essential dependencies for a Flutter application, including `starknet` and `starknet_provider`. It also sets `publish_to: "none"` to prevent accidental publishing. ```YAML publish_to: "none" # Remove this line if you wish to publish to pub.dev version: 1.0.0+1 environment: sdk: ">=3.0.0 <4.0.0" dependencies: flutter: sdk: flutter cupertino_icons: ^1.0.2 starknet: flutter_lints: ^2.0.0 build_runner: ^2.4.6 starknet_provider: dev_dependencies: flutter_test: sdk: flutter flutter: uses-material-design: true ``` -------------------------------- ### Define Cairo Module in src/lib.cairo Source: https://starknetdart.dev/examples/starknet-counter Content for `src/lib.cairo` to declare the `counter` module. This organizes the contract code within the Scarb project, ensuring proper module visibility and compilation. ```Cairo mod counter; ``` -------------------------------- ### Declare Starknet Contract Source: https://starknetdart.dev/examples/starknet-counter Command to declare a compiled Starknet contract on the devnet using `starkli`. It requires the RPC endpoint, account configuration, and the path to the contract class JSON. ```Bash ~/contract$ starkli declare --watch --rpc http://localhost:5050 --account devnet-acct.json target/dev/contract_Counter.contract_class.json ``` -------------------------------- ### Install Melos for Monorepo Management Source: https://starknetdart.dev/how-to-contribute Command to globally activate Melos, a powerful tool used for managing the `starknet.dart` monorepo, facilitating dependency management and script execution across multiple packages. ```Dart dart pub global activate melos ``` -------------------------------- ### Configure environment variables for Starknet devnet Source: https://starknetdart.dev/examples/mobile-wallet Example content for the .env file, setting the ACCOUNT_CLASS_HASH and RPC endpoint for connecting to a Starknet devnet instance. The ACCOUNT_CLASS_HASH must match the devnet's configuration. ```Dotenv ACCOUNT_CLASS_HASH="0x061dac032f228abef9c6626f995015233097ae253a7f72d68552db02f2971b8f" RPC="http://127.0.0.1:5050/rpc" ``` -------------------------------- ### Integrate HomeScreen into WalletApp Source: https://starknetdart.dev/examples/mobile-wallet Updates the `WalletApp` widget to display the newly created `HomeScreen` as its primary content, replacing the placeholder and completing the app's UI setup. ```Dart import './screens/home_screen.dart'; class WalletApp extends HookConsumerWidget { const WalletApp({super.key}); @override Widget build(BuildContext context, WidgetRef ref) { return MaterialApp( title: 'Starknet Wallet', home: const HomeScreen(), theme: walletThemeData, debugShowCheckedModeBanner: false, ); } } ``` -------------------------------- ### Execute Flutter Application Locally Source: https://starknetdart.dev/examples/starknet-counter This shell command is used to run the Flutter application on a connected device or emulator. It compiles the Dart code and launches the app, allowing for local testing and interaction. ```Shell ~/starknet_counter$ flutter run ``` -------------------------------- ### Flutter Run Device Selection Output Source: https://starknetdart.dev/examples/starknet-counter This snippet shows the expected command-line output when running a Flutter application, prompting the user to select a target device from a list of connected options (e.g., Linux desktop, Chrome web). The user needs to input a number corresponding to their desired device. ```Shell Connected devices: Linux (desktop) • linux • linux-x64 • Ubuntu 22.04.2 LTS 5.15.0-25-generic Chrome (web) • chrome • web-javascript • Google Chrome 119.0.6045.159 [1]: Linux (linux) [2]: Chrome (chrome) Please choose one (or "q" to quit): 1 ... ``` -------------------------------- ### Android Setup: Configure minSdkVersion in build.gradle (Gradle) Source: https://starknetdart.dev/packages/secure-store To ensure compatibility with the Secure Store plugin on Android, the minSdkVersion in the android/app/build.gradle file must be set to 23 or higher. ```Gradle android { defaultConfig { minSdkVersion 23 } } ``` -------------------------------- ### APIDOC: Get AVNU Gas Token Prices Source: https://starknetdart.dev/packages/avnu_provider Fetches the current prices for AVNU gas tokens. This function requires no arguments. ```APIDOC getGasTokenPrices() None. ``` -------------------------------- ### APIDOC: Get Sponsor Activity Source: https://starknetdart.dev/packages/avnu_provider Retrieves the sponsor activity for an account within a specified date range. The maximum difference between `startDate` and `endDate` is 7 days. ```APIDOC getSponsorActivity(String startDate, String endDate) startDate: The start date of the activity. endDate: The end date of the activity (max diff between startDate and endDate is 7 days). ``` -------------------------------- ### Allocate Rewards to Users (Dart) Source: https://starknetdart.dev/packages/avnu_provider Demonstrates how a sponsor can allocate free transactions to users within a specific campaign, enabling gasless transactions. This example allocates one free transaction in an 'Onboarding' campaign. ```Dart import 'package:avnu_provider/avnu_provider.dart'; // Initate avnu provider with a public key only in case you want to check for API signature (recommended). // Remember that if you have a compressed public key with the x coordinate like for example 0x030429c489.... , // then you must remove the 03 prefix and use the x coordinate only: 0x0429c489..... final apiKey = 'your_api_key'; final publicKey = BigInt.parse("0429c489be63b21c399353e03a9659cfc1650b24bae1e9ebdde0aef2b38deb44",radix: 16); final AvnuProvider avnuProvider = getAvnuProvider(publicKey: publicKey, apiKey: apiKey); ... ... final address = sepoliaAccount0.accountAddress.toHexString(); final campaign = 'Onboarding'; final protocol = 'AVNU'; final freeTx = 1; // set expiration date as utc + one hour in the future final expirationDate = DateTime.now().add(Duration(hours: 1)).toUtc().toIso8601String(); final whitelistedCalls = [ { 'contractAddress': '*', 'entrypoint': '*' } ]; final avnuSetAccountRewards = await avnuProvider.setAccountRewards(address, campaign, protocol, freeTx, expirationDate, whitelistedCalls); avnuSetAccountRewards.when( result: (date, address, sponsor, campaign, protocol, freeTx, remainingTx, expirationDate, whitelistedCalls) { print('Account rewards set successfully'); }, error: (error, revertError) { print('Error setting account rewards: $error'); } ); ``` -------------------------------- ### Password Store: Store and Get Secrets with Options (Dart) Source: https://starknetdart.dev/packages/secure-store Illustrates how to store and retrieve secrets using the PasswordStore with a specified password. The PasswordStoreOptions object is used to provide the password for encryption and decryption. ```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"), ); ``` -------------------------------- ### Avnu API: Build Typed Data Response Structure Source: https://starknetdart.dev/packages/avnu_provider Example of a successful API response from the Avnu `buildTypedData` endpoint, detailing the structure of the `types`, `primaryType`, `domain`, and `message` fields for a Starknet transaction. ```APIDOC {types: {StarknetDomain: [ {name: name, type: shortstring}, {name: version, type: shortstring}, {name: chainId, type: shortstring}, {name: revision, type: shortstring}], OutsideExecution: [ {name: Caller, type: ContractAddress}, {name: Nonce, type: felt}, {name: "Execute After", type: u128}, {name: "Execute Before", type: u128}, {name: Calls, type: "Call*"}], Call: {name: To, type: ContractAddress}, {name: Selector, type: selector}, {name: Calldata, type: "felt*"}]}, primaryType: OutsideExecution, domain: {name: "Account.execute_from_outside", version: 2, chainId: "0x534e5f5345504f4c4941", revision: 1}, message: { Caller: "0x75a180e18e56da1b1cae181c92a288f586f5fe22c18df21cf97886f1e4b316c", Nonce: "0x264286408869284018bf8a96ba21459e1230e19226bcb1a70332700f0503cb3", "Execute After": "0x1", "Execute Before": "0x194d200bc56", Calls: [{ To: "0x49d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7", Selector: "0x219209e083275171774dab1df80982e9df2096516f06319c5c6d71ae0a8480c", Calldata: ["0x498e484da80a8895c77dcad5362ae483758050f22a92af29a385459b0365bfe", "0xf", "0x0"] }] } } ``` -------------------------------- ### Override Flutter Package Dependencies from Git Source: https://starknetdart.dev/examples/starknet-counter The `pubspec_overrides.yaml` file is used to override specific package dependencies, directing them to local paths or Git repositories. In this case, `starknet` and `starknet_provider` are sourced directly from the `focustree/starknet.dart` GitHub repository for development purposes. ```YAML dependency_overrides: path: ^1.8.3 http: ^1.0.0 starknet: git: url: https://github.com/focustree/starknet.dart path: packages/starknet starknet_provider: git: url: https://github.com/focustree/starknet.dart path: packages/starknet_provider ``` -------------------------------- ### iOS Setup: Add NSFaceIDUsageDescription to Info.plist (XML) Source: https://starknetdart.dev/packages/secure-store For iOS applications using biometrics, the NSFaceIDUsageDescription key must be added to the Info.plist file. This provides a user-facing description for why Face ID or Touch ID is requested. ```XML NSFaceIDUsageDescription Use Touch ID or Face ID to process transactions. ``` -------------------------------- ### Define Flutter Counter Page UI Structure Source: https://starknetdart.dev/examples/starknet-counter This partial Dart file outlines the basic structure for the `CounterPage` UI in Flutter. It defines a `StatefulWidget` to manage the counter state and includes a `TextEditingController` for user input, preparing the groundwork for displaying and interacting with the counter value. ```Dart import '../services/counter_service.dart'; import 'package:flutter/material.dart'; class CounterPage extends StatefulWidget { const CounterPage({super.key, required this.title}); final String title; @override State createState() => _CounterPageState(); } class _CounterPageState extends State { int counter = 0; TextEditingController amount = TextEditingController(); ``` -------------------------------- ### Android Setup: Extend FlutterFragmentActivity in MainActivity (Java) Source: https://starknetdart.dev/packages/secure-store For Android, the MainActivity class needs to extend FlutterFragmentActivity instead of FlutterActivity to properly support the Secure Store plugin's functionalities, especially related to biometrics. ```Java package com.example.example import io.flutter.embedding.android.FlutterActivity class MainActivity: FlutterFragmentActivity() { } ``` -------------------------------- ### Implement Starknet Counter Smart Contract Interaction Service Source: https://starknetdart.dev/examples/starknet-counter This Dart file provides a service layer for interacting with a Starknet counter smart contract. It defines a `JsonRpcProvider` for node communication, sets up account details, and includes functions to `getCurrentCount`, `increaseCounter`, `increaseCounterBy`, and `decreaseCounter` by sending transactions to the contract. Remember to replace `contractAddress`, `secretAccountAddress`, and `secretAccountPrivateKey` with your actual deployed contract and account details. ```Dart import 'package:starknet/starknet.dart'; import 'package:starknet_provider/starknet_provider.dart'; final provider = JsonRpcProvider( nodeUri: Uri.parse( 'http://localhost:5050')); final contractAddress = '0x02b955c900b35047f94200a336ee815587dbe228371f8b3194b7c6eb2b70a056'; final secretAccountAddress = "0x64b48806902a367c8598f4f95c305e8c1a1acba5f082d294a43793113115691"; final secretAccountPrivateKey = "0x71d7bb07b9a64f6f78ac4c816aff4da9"; final signeraccount = getAccount( accountAddress: Felt.fromHexString(secretAccountAddress), privateKey: Felt.fromHexString(secretAccountPrivateKey), nodeUri: Uri.parse( 'http://localhost:5050'), ); Future getCurrentCount() async { final result = await provider.call( request: FunctionCall( contractAddress: Felt.fromHexString(contractAddress), entryPointSelector: getSelectorByName("get_current_count"), calldata: []), blockId: BlockId.latest, ); return result.when( result: (result) => result[0].toInt(), error: (error) => throw Exception("Failed to get counter value"), ); } Future increaseCounter() async { print('print increment'); final response = await signeraccount.execute(functionCalls: [ FunctionCall( contractAddress: Felt.fromHexString(contractAddress), entryPointSelector: getSelectorByName("increment"), calldata: [], ), ]); final txHash = response.when( result: (result) => result.transaction_hash, error: (err) => throw Exception("Failed to execute"), ); print('printing increment TX : $txHash'); await waitForAcceptance(transactionHash: txHash, provider: provider); } Future increaseCounterBy(String number) async { print('print increment by '); final response = await signeraccount.execute(functionCalls: [ FunctionCall( contractAddress: Felt.fromHexString(contractAddress), entryPointSelector: getSelectorByName("increase_count_by"), calldata: [Felt.fromIntString(number)], ), ]); final txHash = response.when( result: (result) => result.transaction_hash, error: (err) => throw Exception("Failed to execute"), ); print('printing incrementby amount TX : $txHash'); await waitForAcceptance(transactionHash: txHash, provider: provider); } Future decreaseCounter() async { print('decrementing.....'); final response = await signeraccount.execute(functionCalls: [ FunctionCall( contractAddress: Felt.fromHexString(contractAddress), entryPointSelector: getSelectorByName("decrement"), calldata: [], ), ]); final txHash = response.when( result: (result) => result.transaction_hash, error: (err) => throw Exception("Failed to execute"), ); print('printing decrement TX : $txHash'); await waitForAcceptance(transactionHash: txHash, provider: provider); } ``` -------------------------------- ### Subscribe and listen for new events with Starknet Dart Source: https://starknetdart.dev/packages/starknet-provider-wss This example demonstrates how to establish a WebSocket connection to a Starknet node, subscribe to new events, process a specific number of events (e.g., 5), and then unsubscribe and disconnect. It shows how to set up an `onEvents` handler to process incoming event data. ```Dart import 'package:starknet/starknet.dart'; final nodeUrl = 'wss://sepolia-pathfinder-rpc.spaceshard.io/rpc/v0_8'; final webSocketChannel = StarknetWebSocketChannel(nodeUrl: nodeUrl); await webSocketChannel.waitForConnection(); // Setup onEvents handler function. In this example, we will // process 5 events and print their transaction_hash. final eventCompleter = Completer(); int eventCount = 0; webSocketChannel.onEvents = (channel, response) { print("received event transaction_hash: ${response.result.transactionHash}"); eventCount++; if (eventCount == 5) { eventCompleter.complete(); } }; // Then we initiate the subscription sending the events // subscription message to the wss endpoint. final subId = await webSocketChannel.subscribeEvents(); subId.when( result: (subId) { // we can check if the subscription was successful expect(subId, isNotNull); }, error: (error) => fail('Should not return an error'), ); // At this point, we will start to receive and process all the events. // Wait for the subscription events completion // This is wait for eventCompleter.complete() to be called. await eventCompleter.future; // At this point, in the background we are still receiving and processing the events. // So, let's unsubscribe to stop receiving and processing the events. final status = await webSocketChannel.unsubscribeEvents(); status.when( // we can check if the unsubscription was successful result: (status) => expect(status, true), error: (error) => fail('Should not return an error'), ); // Disconnect from the web socket node await webSocketChannel.disconnect(); await webSocketChannel.waitForDisconnect(); ``` -------------------------------- ### Subscribe and Listen for Starknet Transaction Status (Dart) Source: https://starknetdart.dev/packages/starknet-provider-wss This example demonstrates how to establish a WebSocket connection to a Starknet node, subscribe to a transaction's status, and process status updates until the transaction is accepted on L2. It also shows how to unsubscribe from the status updates and disconnect from the WebSocket. ```Dart import 'package:starknet/starknet.dart'; final nodeUrl = 'wss://sepolia-pathfinder-rpc.spaceshard.io/rpc/v0_8'; final webSocketChannel = StarknetWebSocketChannel(nodeUrl: nodeUrl); await webSocketChannel.waitForConnection(); // Setup onTransactionStatus handler function. In this example, we will // process the transaction status until it is accepted on L2. final eventCompleter = Completer(); webSocketChannel.onTransactionStatus = (channel, response) { print("received transaction status: ${response.result.finalityStatus}"); if (response.result.finalityStatus == "ACCEPTED_ON_L2") { eventCompleter.complete(); } }; // Then we initiate the subscription sending the transaction status // subscription message to the wss endpoint. final transactionHash = Felt.fromHexString("0x194b07e7a536cbf2b94c74d558af8b9c689dbdd70a649a7ce1ca07375ae3cc9"); final subId = await webSocketChannel.subscribeTransactionStatus(transactionHash); subId.when( result: (subId) { // we can check if the subscription was successful expect(subId, isNotNull); }, error: (error) => fail('Should not return an error'), ); // At this point, we will start to receive and process all the transaction status events. // Wait for the subscription transaction status completion // This is wait for eventCompleter.complete() to be called. await eventCompleter.future; // At this point, in the background we are still receiving and processing the transaction status. // So, let's unsubscribe to stop receiving and processing the transaction status. final status = await webSocketChannel.unsubscribeTransactionStatus(); status.when( // we can check if the unsubscription was successful result: (status) => expect(status, true), error: (error) => fail('Should not return an error'), ); // Disconnect from the web socket node await webSocketChannel.disconnect(); await webSocketChannel.waitForDisconnect(); ``` -------------------------------- ### Subscribe and listen for pending transactions with Starknet Dart Source: https://starknetdart.dev/packages/starknet-provider-wss This example demonstrates how to establish a WebSocket connection to a Starknet node, subscribe to pending transactions, process a specific number of transactions (e.g., 5), and then unsubscribe and disconnect. It shows how to set up an `onPendingTransactions` handler to process incoming transaction data. ```Dart import 'package:starknet/starknet.dart'; final nodeUrl = 'wss://sepolia-pathfinder-rpc.spaceshard.io/rpc/v0_8'; final webSocketChannel = StarknetWebSocketChannel(nodeUrl: nodeUrl); await webSocketChannel.waitForConnection(); // Setup onPendingTransactions handler function. In this example, we will // process 5 pending transactions and print their transaction_hash. final eventCompleter = Completer(); int eventCount = 0; webSocketChannel.onPendingTransactions = (channel, response) { print("received pending transaction transaction_hash: ${response.result.transactionHash}"); eventCount++; if (eventCount == 5) { eventCompleter.complete(); } }; // Then we initiate the subscription sending the pending transactions // subscription message to the wss endpoint. final subId = await webSocketChannel.subscribePendingTransactions(); subId.when( result: (subId) { // we can check if the subscription was successful expect(subId, isNotNull); }, error: (error) => fail('Should not return an error'), ); // At this point, we will start to receive and process all the pending transactions. // Wait for the subscription pending transactions completion // This is wait for eventCompleter.complete() to be called. await eventCompleter.future; // At this point, in the background we are still receiving and processing the pending transactions. // So, let's unsubscribe to stop receiving and processing the pending transactions. final status = await webSocketChannel.unsubscribePendingTransactions(); status.when( // we can check if the unsubscription was successful result: (status) => expect(status, true), error: (error) => fail('Should not return an error'), ); // Disconnect from the web socket node await webSocketChannel.disconnect(); await webSocketChannel.waitForDisconnect(); ``` -------------------------------- ### Subscribe and Listen for New Block Heads in Dart Source: https://starknetdart.dev/packages/starknet-provider-wss This Dart example demonstrates how to subscribe to new block heads using `StarknetWebSocketChannel`, set up an `onNewHeads` handler to process incoming blocks, and then unsubscribe after a certain number of blocks are received. It includes connection, subscription, event handling, unsubscription, and disconnection logic. ```Dart import 'package:starknet/starknet.dart'; final nodeUrl = 'wss://sepolia-pathfinder-rpc.spaceshard.io/rpc/v0_8'; final webSocketChannel = StarknetWebSocketChannel(nodeUrl: nodeUrl); await webSocketChannel.waitForConnection(); // Setup onNewHeads handler function. In this example, we will // process every new block head and store it in a list. final eventCompleter = Completer(); final blocks = []; webSocketChannel.onNewHeads = (channel, response) { blocks.add(response); print("blocks.length: ${blocks.length}"); print("received block: ${response.result}"); if (blocks.length == 5) { eventCompleter.complete(); } }; // Then we initiate the subscription sending the new block heads // subscription message to the wss endpoint. final subId = await webSocketChannel.subscribeNewHeads(); subId.when( result: (subId) { // we can check if the subscription was successful expect(subId, isNotNull); }, error: (error) => fail('Should not return an error'), ); // At this point, we will start to receive and process all the new block heads. // Wait for the subscription events completion // This is wait for eventCompleter.complete() to be called. await eventCompleter.future; // At this point, in the background we are still receiving and processing the new block heads. // So, let's unsubscribe to stop receiving and processing the new block heads. final status = await webSocketChannel.unsubscribeNewHeads(); status.when( // we can check if the unsubscription was successful result: (status) => expect(status, true), error: (error) => fail('Should not return an error'), ); // Disconnect from the web socket node await webSocketChannel.disconnect(); await webSocketChannel.waitForDisconnect(); ``` -------------------------------- ### Send and Receive Regular RPC Messages to Starknet (Dart) Source: https://starknetdart.dev/packages/starknet-provider-wss This example illustrates how to send a standard RPC message, specifically querying the chain ID, to a Starknet WebSocket node and verify the response. It covers establishing a connection, sending a request, receiving a response, and disconnecting. ```Dart import 'package:starknet/starknet.dart'; final nodeUrl = 'wss://sepolia-pathfinder-rpc.spaceshard.io/rpc/v0_8'; final webSocketChannel = StarknetWebSocketChannel(nodeUrl: nodeUrl); await webSocketChannel.waitForConnection(); // Send a regular rpc message to the web socket node final response = await webSocketChannel.sendReceive('starknet_chainId'); // Check if the response is the expected chainId final snSepolia = '0x534e5f5345504f4c4941'; //SN_SEPOLIA expect(response['result'], snSepolia); // Disconnect from the web socket node await webSocketChannel.disconnect(); await webSocketChannel.waitForDisconnect(); ``` -------------------------------- ### Handle Reorganization WebSocket Response Source: https://starknetdart.dev/packages/starknet-provider-wss Documents the `onReorg` handler, which processes incoming blockchain reorganization responses from a Starknet WebSocket channel. This message can be received from subscribing to newHeads, Events, or TransactionStatus. It details the arguments `channel` (StarknetWebSocketChannel) and `response` (WssSubscriptionReorgResponse) and provides an example JSON structure for the response. ```APIDOC onReorg(StarknetWebSocketChannel, WssSubscriptionReorgResponse) channel: The channel to handle. response: The response to handle. ``` ```JSON { "subscription_id": "0x5", "result": { "old_head": { "blockHash": "0x0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef", "parentHash": "0xfedcba9876543210fedcba9876543210fedcba9876543210fedcba9876543210", "blockNumber": 123456 }, "new_head": { "blockHash": "0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", "parentHash": "0xbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", "blockNumber": 123456 } } } ``` -------------------------------- ### Handle New Block Heads (onNewHeads) API Source: https://starknetdart.dev/packages/starknet-provider-wss Documents the `onNewHeads` function, which processes new block head updates received via a Starknet WebSocket channel. It takes the channel and a `WssSubscriptionNewHeadResponse` object as arguments. An example JSON structure for `WssSubscriptionNewHeadResponse` is provided, detailing block information such as hash, number, timestamp, and gas prices. ```APIDOC `onNewHeads(StarknetWebSocketChannel, WssSubscriptionNewHeadResponse)` Arguments: * `channel`: The channel to handle. * `response`: The response to handle. ``` ```JSON { "subscription_id": "0x1", "result": { "blockHash": "0x12345...", "parentHash": "0xabcde...", "blockNumber": 123456, "newRoot": "0x67890...", "timestamp": 1678901234, "sequencerAddress": "0xfedcb...", "l1GasPrice": { "priceInFri": "0x123", "priceInWei": "0x456" }, "l2GasPrice": { "priceInFri": "0x789", "priceInWei": "0xabc" }, "l1DataGasPrice": { "priceInFri": "0xdef", "priceInWei": "0x123" }, "l1DaMode": "CALLDATA", "starknetVersion": "0.12.1" } } ``` -------------------------------- ### Clone Starknet.dart Repository Source: https://starknetdart.dev/how-to-contribute Instructions to clone the `starknet.dart` project repository from GitHub to your local machine. ```Shell git clone git@github.com:focustree/starknet.dart.git ```