diff --git a/CHANGELOG.md b/CHANGELOG.md index 394ebdc..e05badc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,66 @@ +## 0.1.0 + +* Training wheel support for entrypoint v0.7.0 via pimlico bundler +* Fix issue with gas multiplier +* Added safe4337module abi for v0.7.0 +* Add support for custom paymaster address + +## 0.1.0-r3 + +* Add mutisend address to constants +* Add support for Safe account batch transactions + +## 0.1.0-r2 + +* Fix safe transaction encoding +* Remove _checkDeployment function in counterfactual creation +* Add getBlockInformation in JsonRPCProvider + +## 0.1.0-r1 + +* Mainnet Pre-release +* refactor sdk to use the factory method for creating smart-accounts +* add safe smart accounts via safe plugin +* reduce external dependencies to 3 +* implement custom errors and add logger for debugging +* update contract abis, adding more erc20/erc721 abi snippets +* fix paymaster plugin context incompatibility +* add utility for packing and unpacking uint256 values +* update chain configuration to surpport minimal modest chains +* update example to a real flutter example +* rename library name from variance to variance_dart for consistency +* update API refs and README to reflect new changes + +## 0.0.9 + +* Add support for entrypoint v0.7 in parrallel. + +## 0.0.8 + +* Add paymaster as a plugin +* Rename plugins.dart to mixins +* Improve gas and nonce calculation process. + +## 0.0.7 + +* Deprecate passing wallet address via constructor as fields will be made final +* Enable global gas settings and fee % multiplier +* Introduce userOp retry mechanism + +## 0.0.6 + +* Sunset all goerli chains + +## 0.0.5 + +* Added missing required blockParam to `eth_call` + +* Reduced default callgasLimit and verificationGasLimit to 250K and 750k respectively in `eth_estimateUserOperationGas` + +* Prevent redundant eth_call's in fetching nonce/deployment status + +* Reduced strict internal op callGasLimit validation from 21k gas 12k gas requirement + ## 0.0.4 * Added a Secure Storage Repository for saving credentials to encrypted android shared-preference and iOS keychain diff --git a/README.md b/README.md index 51352e4..da60629 100644 --- a/README.md +++ b/README.md @@ -7,166 +7,148 @@ Variance is a Dart SDK designed to simplify interaction with Ethereum-based bloc - **ABI Encoding/Decoding:** Easily encode and decode ABI data for Ethereum smart contract and Entrypoint interactions. - **Transaction Handling:** Simplify the process of creating and sending UserOperations. - **Token Operations:** Work with ERC20 and ERC721 tokens, including transfer and approval functionalities. -- **Secure Storage:** Securely store and manage sensitive data such as private keys and credentials. -- **Web3 Functionality:** Interact with Ethereum nodes and bundlers using web3 functions like `eth_call`, `eth_sendTransaction`, `eth_sendUserOperation`, etc. -- **PassKeyPair and HDWalletSigner:** Manage smart accounts signers using Passkeys or Seed Phrases. +- **Web3 Functionality:** Interact with Ethereum nodes and bundlers using abstracted methods over, `eth_sendTransaction`, and `eth_sendUserOperation`. +- **SecP256r1 Signatures:** Sign transactions with SecP256r1 signatures. ## Getting Started ### Installation -```yml -// Add this line to your pubspec.yaml file - -dependencies: - variance_dart: ^0.0.4 -``` - -Then run: +open your terminal and run the following command: ```sh -flutter pub get +flutter pub add variance_dart +flutter pub add web3_signers + +# optionally +flutter pub add web3dart ``` ### Usage ```dart // Import the package -import 'package:variance_dart/utils.dart'; -import 'package:variance_dart/variance.dart'; +import 'package:web3_signers/web3_signers.dart'; +import 'package:variance_dart/variance_dart.dart'; // optionally -import 'package:flutter_secure_storage/flutter_secure_storage.dart'; import 'package:web3dart/web3dart.dart'; ``` -configure your chains: there are 2 ways to get the chain configuration. either manually or using the already supported configurations. +### Chain Configuration ```dart -Chain chain; - -// manually const String rpcUrl = 'http://localhost:8545'; const String bundlerUrl = 'http://localhost:3000/rpc'; +const Uint256 salt = const Uint256.zero; -chain = Chain( - ethRpcUrl: rpcUrl, - bundlerUrl: bundlerUrl, - entrypoint: Constants.entrypoint, - accountFactory: Constants.accountFactory, - chainId: 1337, - explorer: ""); - -// using pre configured chain -chain = Chains.getChain(Network.localhost) - ..ethRpcUrl = rpcUrl +final Chain chain = Chains.getChain(Network.localhost) + ..jsonRpcUrl = rpcUrl ..bundlerUrl = bundlerUrl; ``` -In order to create a smart wallet client you need to set up a signer, which will sign useroperation hashes to be verified onchain. -there are 3 available signers: +> There are 8 available networks: ethereum, polygon, optimism, base, arbitrumOne, linea, opBnB and scroll. 3 available testnets: sepolia, mumbai and baseTestent. You can also develop on localHost. + +Additionally, you can specify a different Entrypoint address. By default, the entrypoin v0.6 is used. -- passkeys -- hd wallet -- simple credential (privatekey) +```dart +final EntryPointAddress entrypointAddress = EntryPointAddress.v07; +chain.entrypoint = entrypointAddress; +``` -> Variance SDK can be used to create both EOA and Smart Wallets. the `HD wallet signer` itself is a fully featured EOA wallet that can be used to build any EOA wallet like metamask. it can also be used as an account signer for a smart wallet. +Also if wish to use paymasters with your smart wallet you can do so by specifying the endpoint of the paymaster. By default the paymaster is set to null. This would add a paymaster Plugin to the smart wallet. ```dart -// create smart wallet signer based of seed phrase -final HDWalletSigner hd = HDWalletSigner.createWallet(); -print("mnemonic: ${hd.exportMnemonic()}"); - -// create a smart wallet signer based on passkeys -// this operation requires biometrics verification from the user -final PassKeyPair pkp = - await PassKeySigner("myapp.xyz", "myapp", "https://myapp.xyz") - .register("", true); -print("pkp: ${pkp.toJson()}"); +final String paymasterUrl = 'https://api.pimlico.io/v2/84532/rpc?apikey=...'; +chain.paymasterUrl = paymasterUrl; ``` -Optionally the credentials returned from the signer instances can be securely saved on device android encrypted shared preferences or ios keychain using the `SecureStorageMiddleware`. +If you have additional context for the paymaster, you will be able to add it to the smart wallet after creation or before initiating a transaction. ```dart -// save a signer credential to device -await hd - .withSecureStorage(FlutterSecureStorage()) - .saveCredential(CredentialType.hdwallet); +wallet.plugin('paymaster').context = {'key': 'value'}; +``` + +### Signers -await pkp - .withSecureStorage(FlutterSecureStorage()) - .saveCredential(CredentialType.passkeypair); +In order to create a smart wallet client you need to set up a signer, which will sign useroperation hashes to be verified onchain. Only signers available in the [web3signers](https://pub.dev/packages/web3_signers) package can be used. -// load a credential from the device -final ss = SecureStorageMiddleware(secureStorage: FlutterSecureStorage()); -final hdInstance = - await HDWalletSigner.loadFromSecureStorage(storageMiddleware: ss); -print("pkp: ${hdInstance?.exportMnemonic()}"); +> You have to use the correct signer for the type of account you want to create. -// NOTE: interactions with securestorage can be authenticated when using `SecureStorageMiddleware` +1. `PrivateKeys` - use with simple accounts and safe accounts only +2. `Passkey` - use with p256 smart accounts and safe Passkey accounts only +3. `EOA Wallet (Seed Phrases)` - use with simple smart accounts and safe accounts only +4. `HardWare Signers (Secure Enclave/Keystore)` - use with p256 smart accounts only -final ss = SecureStorageMiddleware(secureStorage: FlutterSecureStorage(), authMiddleware: AuthenticationMiddleware()); -// then used with `SecureStorageMiddleware` in the following way +### Smart Wallet Factory -ss.save("key", "value", options: SSAuthOperationOptions(requiresAuth: true, authReason: "reason")); -ss.read("key"); // default options are used i.e requiresAuth: false -ss.delete("key", options: SSAuthOperationOptions(requiresAuth: false)); // explicitly reject authentication +The smart wallet factory handles the creation of smart wallet instances. Make sure you have created a signer from the previous step. + +```dart +final SmartWalletFactory smartWalletFactory = SmartWalletFactory(chain, signer); ``` -Interacting with the smart wallet: +#### To Create a Simple Smart Account ```dart -// create a smart wallet client -final walletClient = SmartWallet( - chain: chain, - signer: hd, - bundler: BundlerProvider(chain, RPCProvider(chain.bundlerUrl!)), -); +final Smartwallet wallet = await smartWalletFactory.createSimpleAccount(salt); +print("simple wallet address: ${wallet.address.hex}"); +``` -// create a simple account based on hd -final SmartWallet simpleSmartAccount = - await walletClient.createSimpleAccount(salt); -print("simple account address: ${simpleSmartAccount.address}"); +#### To create a P256 Smart Account (Secure Enclave/Keystore) -// create a simple account based on pkp -final SmartWallet simplePkpAccount = - await walletClient.createSimplePasskeyAccount(pkp, salt); -print("simple pkp account address: ${simplePkpAccount.address}"); +```dart +final Smartwallet wallet = await smartWalletFactory.createP256Account(keypair, salt); +print("p256 wallet address: ${wallet.address.hex}"); +``` + +Your keypair must be either be the `PassKeyPair` or `P256Credential` return when registering with your secp256r1 signer. +Additionally, you can pass a recovery address to the `createP256Account` method. + +```dart +final Smartwallet wallet = await smartWalletFactory.createP256Account(keypair, salt, recoveryAddress); +print("p256 wallet address: ${wallet.address.hex}"); +``` + +#### To create a [Safe](https://safe.global) Smart Account + +```dart +final Smartwallet wallet = await smartWalletFactory + .createSafeAccount(salt); +print("safe wallet address: ${wallet.address.hex}"); +``` + +> Safe SecP256r1 signers can not be used with this SDK yet. + +### Interacting with the Smart Wallet +```dart // retrieve the balance of a smart wallet -final EtherAmount balance = await simpleSmartAccount.balance; +final EtherAmount balance = await wallet.balance; print("account balance: ${balance.getInWei}"); // retrive the account nonce -final Uint256 nonce = await simpleSmartAccount.nonce; +final Uint256 nonce = await wallet.nonce; print("account nonce: ${nonce.toInt()}"); // check if a smart wallet has been deployed -final bool deployed = await simpleSmartAccount.deployed; +final bool deployed = await wallet.deployed; print("account deployed: $deployed"); // get the init code of the smart wallet -final String initCode = simpleSmartAccount.initCode; +final String initCode = wallet.initCode; print("account init code: $initCode"); // perform a simple transaction (send ether to another account) // account must be prefunded with native token. paymaster is not yet implemented -await simpleSmartAccount.send( +await wallet.send( EthereumAddress.fromHex( "0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789"), // receive address - getConversion("0.7142"), // 0.7142 ether + EtherAmount.fromInt(EtherUnit.ether, 0.7142), // 0.7142 ether ); - - -// utility function to convert eth amount from string to wei -EtherAmount getConversion(String amount) { - final amtToDb = double.parse(amount); - return EtherAmount.fromBigInt( - EtherUnit.wei, BigInt.from(amtToDb * pow(10, 18))); -} ``` -For detailed usage and examples, refer to the [documentation](https://docs.variance.space). Additional refer to the [demo](https://github.com/vaariance/variancedemo) for use in a flutter app. +For detailed usage and examples, refer to the [documentation](https://docs.variance.space). Additional refer to the [example](./example/) for use in a flutter app. ## API Reference diff --git a/example/.gitignore b/example/.gitignore new file mode 100644 index 0000000..29a3a50 --- /dev/null +++ b/example/.gitignore @@ -0,0 +1,43 @@ +# Miscellaneous +*.class +*.log +*.pyc +*.swp +.DS_Store +.atom/ +.buildlog/ +.history +.svn/ +migrate_working_dir/ + +# IntelliJ related +*.iml +*.ipr +*.iws +.idea/ + +# The .vscode folder contains launch configuration and tasks you configure in +# VS Code which you may wish to be included in version control, so this line +# is commented out by default. +#.vscode/ + +# Flutter/Dart/Pub related +**/doc/api/ +**/ios/Flutter/.last_build_id +.dart_tool/ +.flutter-plugins +.flutter-plugins-dependencies +.pub-cache/ +.pub/ +/build/ + +# Symbolication related +app.*.symbols + +# Obfuscation related +app.*.map.json + +# Android Studio will place build artifacts here +/android/app/debug +/android/app/profile +/android/app/release diff --git a/example/.metadata b/example/.metadata new file mode 100644 index 0000000..7d0a304 --- /dev/null +++ b/example/.metadata @@ -0,0 +1,30 @@ +# This file tracks properties of this Flutter project. +# Used by Flutter tool to assess capabilities and perform upgrades etc. +# +# This file should be version controlled and should not be manually edited. + +version: + revision: "41456452f29d64e8deb623a3c927524bcf9f111b" + channel: "stable" + +project_type: app + +# Tracks metadata for the flutter migrate command +migration: + platforms: + - platform: root + create_revision: 41456452f29d64e8deb623a3c927524bcf9f111b + base_revision: 41456452f29d64e8deb623a3c927524bcf9f111b + - platform: android + create_revision: 41456452f29d64e8deb623a3c927524bcf9f111b + base_revision: 41456452f29d64e8deb623a3c927524bcf9f111b + + # User provided section + + # List of Local paths (relative to this file) that should be + # ignored by the migrate tool. + # + # Files that are not part of the templates will be ignored by default. + unmanaged_files: + - 'lib/main.dart' + - 'ios/Runner.xcodeproj/project.pbxproj' diff --git a/example/README.md b/example/README.md new file mode 100644 index 0000000..ae69948 --- /dev/null +++ b/example/README.md @@ -0,0 +1,16 @@ +# variancedemo + +A new Flutter project. + +## Getting Started + +This project is a starting point for a Flutter application. + +A few resources to get you started if this is your first Flutter project: + +- [Lab: Write your first Flutter app](https://docs.flutter.dev/get-started/codelab) +- [Cookbook: Useful Flutter samples](https://docs.flutter.dev/cookbook) + +For help getting started with Flutter development, view the +[online documentation](https://docs.flutter.dev/), which offers tutorials, +samples, guidance on mobile development, and a full API reference. diff --git a/example/analysis_options.yaml b/example/analysis_options.yaml new file mode 100644 index 0000000..0d29021 --- /dev/null +++ b/example/analysis_options.yaml @@ -0,0 +1,28 @@ +# This file configures the analyzer, which statically analyzes Dart code to +# check for errors, warnings, and lints. +# +# The issues identified by the analyzer are surfaced in the UI of Dart-enabled +# IDEs (https://dart.dev/tools#ides-and-editors). The analyzer can also be +# invoked from the command line by running `flutter analyze`. + +# The following line activates a set of recommended lints for Flutter apps, +# packages, and plugins designed to encourage good coding practices. +include: package:flutter_lints/flutter.yaml + +linter: + # The lint rules applied to this project can be customized in the + # section below to disable rules from the `package:flutter_lints/flutter.yaml` + # included above or to enable additional rules. A list of all available lints + # and their documentation is published at https://dart.dev/lints. + # + # Instead of disabling a lint rule for the entire project in the + # section below, it can also be suppressed for a single line of code + # or a specific dart file by using the `// ignore: name_of_lint` and + # `// ignore_for_file: name_of_lint` syntax on the line or in the file + # producing the lint. + rules: + # avoid_print: false # Uncomment to disable the `avoid_print` rule + # prefer_single_quotes: true # Uncomment to enable the `prefer_single_quotes` rule + +# Additional information about this file can be found at +# https://dart.dev/guides/language/analysis-options diff --git a/example/android/.gitignore b/example/android/.gitignore new file mode 100644 index 0000000..6f56801 --- /dev/null +++ b/example/android/.gitignore @@ -0,0 +1,13 @@ +gradle-wrapper.jar +/.gradle +/captures/ +/gradlew +/gradlew.bat +/local.properties +GeneratedPluginRegistrant.java + +# Remember to never publicly share your keystore. +# See https://flutter.dev/docs/deployment/android#reference-the-keystore-from-the-app +key.properties +**/*.keystore +**/*.jks diff --git a/example/android/app/build.gradle b/example/android/app/build.gradle new file mode 100644 index 0000000..35000b9 --- /dev/null +++ b/example/android/app/build.gradle @@ -0,0 +1,67 @@ +plugins { + id "com.android.application" + id "kotlin-android" + id "dev.flutter.flutter-gradle-plugin" +} + +def localProperties = new Properties() +def localPropertiesFile = rootProject.file('local.properties') +if (localPropertiesFile.exists()) { + localPropertiesFile.withReader('UTF-8') { reader -> + localProperties.load(reader) + } +} + +def flutterVersionCode = localProperties.getProperty('flutter.versionCode') +if (flutterVersionCode == null) { + flutterVersionCode = '1' +} + +def flutterVersionName = localProperties.getProperty('flutter.versionName') +if (flutterVersionName == null) { + flutterVersionName = '1.0' +} + +android { + namespace "com.example.variancedemo" + compileSdkVersion 34 + ndkVersion flutter.ndkVersion + + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } + + kotlinOptions { + jvmTarget = '1.8' + } + + sourceSets { + main.java.srcDirs += 'src/main/kotlin' + } + + defaultConfig { + // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). + applicationId "com.example.variancedemo" + // You can update the following values to match your application needs. + // For more information, see: https://docs.flutter.dev/deployment/android#reviewing-the-gradle-build-configuration. + minSdkVersion 28 + targetSdkVersion flutter.targetSdkVersion + versionCode flutterVersionCode.toInteger() + versionName flutterVersionName + } + + buildTypes { + release { + // TODO: Add your own signing config for the release build. + // Signing with the debug keys for now, so `flutter run --release` works. + signingConfig signingConfigs.debug + } + } +} + +flutter { + source '../..' +} + +dependencies {} diff --git a/example/android/app/src/debug/AndroidManifest.xml b/example/android/app/src/debug/AndroidManifest.xml new file mode 100644 index 0000000..399f698 --- /dev/null +++ b/example/android/app/src/debug/AndroidManifest.xml @@ -0,0 +1,7 @@ + + + + diff --git a/example/android/app/src/main/AndroidManifest.xml b/example/android/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..cde5a63 --- /dev/null +++ b/example/android/app/src/main/AndroidManifest.xml @@ -0,0 +1,43 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/example/android/app/src/main/kotlin/com/example/variancedemo/MainActivity.kt b/example/android/app/src/main/kotlin/com/example/variancedemo/MainActivity.kt new file mode 100644 index 0000000..ffd0113 --- /dev/null +++ b/example/android/app/src/main/kotlin/com/example/variancedemo/MainActivity.kt @@ -0,0 +1,5 @@ +package com.example.variancedemo + +import io.flutter.embedding.android.FlutterFragmentActivity + +class MainActivity : FlutterFragmentActivity() {} diff --git a/example/android/app/src/main/res/drawable-v21/launch_background.xml b/example/android/app/src/main/res/drawable-v21/launch_background.xml new file mode 100644 index 0000000..f74085f --- /dev/null +++ b/example/android/app/src/main/res/drawable-v21/launch_background.xml @@ -0,0 +1,12 @@ + + + + + + + + diff --git a/example/android/app/src/main/res/drawable/launch_background.xml b/example/android/app/src/main/res/drawable/launch_background.xml new file mode 100644 index 0000000..304732f --- /dev/null +++ b/example/android/app/src/main/res/drawable/launch_background.xml @@ -0,0 +1,12 @@ + + + + + + + + diff --git a/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png b/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png new file mode 100644 index 0000000..db77bb4 Binary files /dev/null and b/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png differ diff --git a/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png b/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png new file mode 100644 index 0000000..17987b7 Binary files /dev/null and b/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png differ diff --git a/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png new file mode 100644 index 0000000..09d4391 Binary files /dev/null and b/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png differ diff --git a/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png new file mode 100644 index 0000000..d5f1c8d Binary files /dev/null and b/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png differ diff --git a/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png new file mode 100644 index 0000000..4d6372e Binary files /dev/null and b/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png differ diff --git a/example/android/app/src/main/res/values-night/styles.xml b/example/android/app/src/main/res/values-night/styles.xml new file mode 100644 index 0000000..06952be --- /dev/null +++ b/example/android/app/src/main/res/values-night/styles.xml @@ -0,0 +1,18 @@ + + + + + + + diff --git a/example/android/app/src/main/res/values/styles.xml b/example/android/app/src/main/res/values/styles.xml new file mode 100644 index 0000000..cb1ef88 --- /dev/null +++ b/example/android/app/src/main/res/values/styles.xml @@ -0,0 +1,18 @@ + + + + + + + diff --git a/example/android/app/src/profile/AndroidManifest.xml b/example/android/app/src/profile/AndroidManifest.xml new file mode 100644 index 0000000..399f698 --- /dev/null +++ b/example/android/app/src/profile/AndroidManifest.xml @@ -0,0 +1,7 @@ + + + + diff --git a/example/android/build.gradle b/example/android/build.gradle new file mode 100644 index 0000000..e83fb5d --- /dev/null +++ b/example/android/build.gradle @@ -0,0 +1,30 @@ +buildscript { + ext.kotlin_version = '1.7.10' + repositories { + google() + mavenCentral() + } + + dependencies { + classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" + } +} + +allprojects { + repositories { + google() + mavenCentral() + } +} + +rootProject.buildDir = '../build' +subprojects { + project.buildDir = "${rootProject.buildDir}/${project.name}" +} +subprojects { + project.evaluationDependsOn(':app') +} + +tasks.register("clean", Delete) { + delete rootProject.buildDir +} diff --git a/example/android/gradle.properties b/example/android/gradle.properties new file mode 100644 index 0000000..598d13f --- /dev/null +++ b/example/android/gradle.properties @@ -0,0 +1,3 @@ +org.gradle.jvmargs=-Xmx4G +android.useAndroidX=true +android.enableJetifier=true diff --git a/example/android/gradle/wrapper/gradle-wrapper.properties b/example/android/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 0000000..3c472b9 --- /dev/null +++ b/example/android/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,5 @@ +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-7.5-all.zip diff --git a/example/android/settings.gradle b/example/android/settings.gradle new file mode 100644 index 0000000..7cd7128 --- /dev/null +++ b/example/android/settings.gradle @@ -0,0 +1,29 @@ +pluginManagement { + def flutterSdkPath = { + def properties = new Properties() + file("local.properties").withInputStream { properties.load(it) } + def flutterSdkPath = properties.getProperty("flutter.sdk") + assert flutterSdkPath != null, "flutter.sdk not set in local.properties" + return flutterSdkPath + } + settings.ext.flutterSdkPath = flutterSdkPath() + + includeBuild("${settings.ext.flutterSdkPath}/packages/flutter_tools/gradle") + + repositories { + google() + mavenCentral() + gradlePluginPortal() + } + + plugins { + id "dev.flutter.flutter-gradle-plugin" version "1.0.0" apply false + } +} + +plugins { + id "dev.flutter.flutter-plugin-loader" version "1.0.0" + id "com.android.application" version "7.3.0" apply false +} + +include ":app" diff --git a/example/assets/images/down-arrow.png b/example/assets/images/down-arrow.png new file mode 100644 index 0000000..3dfec09 Binary files /dev/null and b/example/assets/images/down-arrow.png differ diff --git a/example/assets/images/ethereum.png b/example/assets/images/ethereum.png new file mode 100644 index 0000000..04b534c Binary files /dev/null and b/example/assets/images/ethereum.png differ diff --git a/example/assets/images/variance_logo.png b/example/assets/images/variance_logo.png new file mode 100644 index 0000000..e66f8a7 Binary files /dev/null and b/example/assets/images/variance_logo.png differ diff --git a/example/ios/.gitignore b/example/ios/.gitignore new file mode 100644 index 0000000..7a7f987 --- /dev/null +++ b/example/ios/.gitignore @@ -0,0 +1,34 @@ +**/dgph +*.mode1v3 +*.mode2v3 +*.moved-aside +*.pbxuser +*.perspectivev3 +**/*sync/ +.sconsign.dblite +.tags* +**/.vagrant/ +**/DerivedData/ +Icon? +**/Pods/ +**/.symlinks/ +profile +xcuserdata +**/.generated/ +Flutter/App.framework +Flutter/Flutter.framework +Flutter/Flutter.podspec +Flutter/Generated.xcconfig +Flutter/ephemeral/ +Flutter/app.flx +Flutter/app.zip +Flutter/flutter_assets/ +Flutter/flutter_export_environment.sh +ServiceDefinitions.json +Runner/GeneratedPluginRegistrant.* + +# Exceptions to above rules. +!default.mode1v3 +!default.mode2v3 +!default.pbxuser +!default.perspectivev3 diff --git a/example/ios/Flutter/AppFrameworkInfo.plist b/example/ios/Flutter/AppFrameworkInfo.plist new file mode 100644 index 0000000..7c56964 --- /dev/null +++ b/example/ios/Flutter/AppFrameworkInfo.plist @@ -0,0 +1,26 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + App + CFBundleIdentifier + io.flutter.flutter.app + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + App + CFBundlePackageType + FMWK + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1.0 + MinimumOSVersion + 12.0 + + diff --git a/example/ios/Flutter/Debug.xcconfig b/example/ios/Flutter/Debug.xcconfig new file mode 100644 index 0000000..ec97fc6 --- /dev/null +++ b/example/ios/Flutter/Debug.xcconfig @@ -0,0 +1,2 @@ +#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig" +#include "Generated.xcconfig" diff --git a/example/ios/Flutter/Release.xcconfig b/example/ios/Flutter/Release.xcconfig new file mode 100644 index 0000000..c4855bf --- /dev/null +++ b/example/ios/Flutter/Release.xcconfig @@ -0,0 +1,2 @@ +#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" +#include "Generated.xcconfig" diff --git a/example/ios/Podfile b/example/ios/Podfile new file mode 100644 index 0000000..8e41300 --- /dev/null +++ b/example/ios/Podfile @@ -0,0 +1,44 @@ +# Uncomment this line to define a global platform for your project +platform :ios, '12.4' + +# CocoaPods analytics sends network stats synchronously affecting flutter build latency. +ENV['COCOAPODS_DISABLE_STATS'] = 'true' + +project 'Runner', { + 'Debug' => :debug, + 'Profile' => :release, + 'Release' => :release, +} + +def flutter_root + generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'Generated.xcconfig'), __FILE__) + unless File.exist?(generated_xcode_build_settings_path) + raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure flutter pub get is executed first" + end + + File.foreach(generated_xcode_build_settings_path) do |line| + matches = line.match(/FLUTTER_ROOT\=(.*)/) + return matches[1].strip if matches + end + raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Generated.xcconfig, then run flutter pub get" +end + +require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root) + +flutter_ios_podfile_setup + +target 'Runner' do + use_frameworks! + use_modular_headers! + + flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__)) + target 'RunnerTests' do + inherit! :search_paths + end +end + +post_install do |installer| + installer.pods_project.targets.each do |target| + flutter_additional_ios_build_settings(target) + end +end diff --git a/example/ios/Podfile.lock b/example/ios/Podfile.lock new file mode 100644 index 0000000..1388937 --- /dev/null +++ b/example/ios/Podfile.lock @@ -0,0 +1,67 @@ +PODS: + - Flutter (1.0.0) + - flutter_native_splash (0.0.1): + - Flutter + - fluttertoast (0.0.2): + - Flutter + - Toast + - passkeys_ios (0.0.1): + - Flutter + - path_provider_foundation (0.0.1): + - Flutter + - FlutterMacOS + - shared_preferences_foundation (0.0.1): + - Flutter + - FlutterMacOS + - Toast (4.1.0) + - ua_client_hints (1.2.2): + - Flutter + - web3_signers (0.0.1): + - Flutter + +DEPENDENCIES: + - Flutter (from `Flutter`) + - flutter_native_splash (from `.symlinks/plugins/flutter_native_splash/ios`) + - fluttertoast (from `.symlinks/plugins/fluttertoast/ios`) + - passkeys_ios (from `.symlinks/plugins/passkeys_ios/ios`) + - path_provider_foundation (from `.symlinks/plugins/path_provider_foundation/darwin`) + - shared_preferences_foundation (from `.symlinks/plugins/shared_preferences_foundation/darwin`) + - ua_client_hints (from `.symlinks/plugins/ua_client_hints/ios`) + - web3_signers (from `.symlinks/plugins/web3_signers/ios`) + +SPEC REPOS: + trunk: + - Toast + +EXTERNAL SOURCES: + Flutter: + :path: Flutter + flutter_native_splash: + :path: ".symlinks/plugins/flutter_native_splash/ios" + fluttertoast: + :path: ".symlinks/plugins/fluttertoast/ios" + passkeys_ios: + :path: ".symlinks/plugins/passkeys_ios/ios" + path_provider_foundation: + :path: ".symlinks/plugins/path_provider_foundation/darwin" + shared_preferences_foundation: + :path: ".symlinks/plugins/shared_preferences_foundation/darwin" + ua_client_hints: + :path: ".symlinks/plugins/ua_client_hints/ios" + web3_signers: + :path: ".symlinks/plugins/web3_signers/ios" + +SPEC CHECKSUMS: + Flutter: e0871f40cf51350855a761d2e70bf5af5b9b5de7 + flutter_native_splash: 52501b97d1c0a5f898d687f1646226c1f93c56ef + fluttertoast: 31b00dabfa7fb7bacd9e7dbee580d7a2ff4bf265 + passkeys_ios: fdae8c06e2178a9fcb9261a6cb21fb9a06a81d53 + path_provider_foundation: 3784922295ac71e43754bd15e0653ccfd36a147c + shared_preferences_foundation: b4c3b4cddf1c21f02770737f147a3f5da9d39695 + Toast: ec33c32b8688982cecc6348adeae667c1b9938da + ua_client_hints: 7f4e0f5d390685e8f7efd6eb363594f760108926 + web3_signers: 5f49d582ab0d1fe673b3220aa6ecf25bb3cbed6b + +PODFILE CHECKSUM: 8e101fac9760a9fc2bf6ef04178c5d9c7f894567 + +COCOAPODS: 1.14.2 diff --git a/example/ios/Runner.xcodeproj/project.pbxproj b/example/ios/Runner.xcodeproj/project.pbxproj new file mode 100644 index 0000000..64e1869 --- /dev/null +++ b/example/ios/Runner.xcodeproj/project.pbxproj @@ -0,0 +1,722 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 54; + objects = { + +/* Begin PBXBuildFile section */ + 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; + 331C808B294A63AB00263BE5 /* RunnerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 331C807B294A618700263BE5 /* RunnerTests.swift */; }; + 3825D4244B2E713B314728A6 /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 983CD1B4D4ED14A1962E9010 /* Pods_Runner.framework */; }; + 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; + 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; }; + 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; }; + 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; }; + 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; }; + EE7C4C7D0A3AA61623F2F769 /* Pods_RunnerTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4A74FAFB68A53B658D418631 /* Pods_RunnerTests.framework */; }; +/* End PBXBuildFile section */ + +/* Begin PBXContainerItemProxy section */ + 331C8085294A63A400263BE5 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 97C146E61CF9000F007C117D /* Project object */; + proxyType = 1; + remoteGlobalIDString = 97C146ED1CF9000F007C117D; + remoteInfo = Runner; + }; +/* End PBXContainerItemProxy section */ + +/* Begin PBXCopyFilesBuildPhase section */ + 9705A1C41CF9048500538489 /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXCopyFilesBuildPhase section */ + +/* Begin PBXFileReference section */ + 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; }; + 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; }; + 331C807B294A618700263BE5 /* RunnerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RunnerTests.swift; sourceTree = ""; }; + 331C8081294A63A400263BE5 /* RunnerTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = RunnerTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; }; + 430F0A4173282D78C8F28354 /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = ""; }; + 4A74FAFB68A53B658D418631 /* Pods_RunnerTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_RunnerTests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = ""; }; + 74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; + 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; }; + 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = ""; }; + 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = ""; }; + 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; + 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; + 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 983CD1B4D4ED14A1962E9010 /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 9F3DAD41ACBE62DCC647F3B8 /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = ""; }; + A7E83DBB1826CD9D3A064E3D /* Pods-RunnerTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.release.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.release.xcconfig"; sourceTree = ""; }; + AF0E938D37BDA368A07CB299 /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = ""; }; + CD2ADA656814A888BCA45D23 /* Pods-RunnerTests.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.profile.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.profile.xcconfig"; sourceTree = ""; }; + D405FD9596CCED7157430C74 /* Pods-RunnerTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.debug.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.debug.xcconfig"; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 97C146EB1CF9000F007C117D /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 3825D4244B2E713B314728A6 /* Pods_Runner.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + AC89F723EB996FDAE502A039 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + EE7C4C7D0A3AA61623F2F769 /* Pods_RunnerTests.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 331C8082294A63A400263BE5 /* RunnerTests */ = { + isa = PBXGroup; + children = ( + 331C807B294A618700263BE5 /* RunnerTests.swift */, + ); + path = RunnerTests; + sourceTree = ""; + }; + 7DCC2EFB852679CF0E6782C0 /* Frameworks */ = { + isa = PBXGroup; + children = ( + 983CD1B4D4ED14A1962E9010 /* Pods_Runner.framework */, + 4A74FAFB68A53B658D418631 /* Pods_RunnerTests.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; + 9740EEB11CF90186004384FC /* Flutter */ = { + isa = PBXGroup; + children = ( + 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */, + 9740EEB21CF90195004384FC /* Debug.xcconfig */, + 7AFA3C8E1D35360C0083082E /* Release.xcconfig */, + 9740EEB31CF90195004384FC /* Generated.xcconfig */, + ); + name = Flutter; + sourceTree = ""; + }; + 97C146E51CF9000F007C117D = { + isa = PBXGroup; + children = ( + 9740EEB11CF90186004384FC /* Flutter */, + 97C146F01CF9000F007C117D /* Runner */, + 97C146EF1CF9000F007C117D /* Products */, + 331C8082294A63A400263BE5 /* RunnerTests */, + E7114C3F32BD70DD1950BD59 /* Pods */, + 7DCC2EFB852679CF0E6782C0 /* Frameworks */, + ); + sourceTree = ""; + }; + 97C146EF1CF9000F007C117D /* Products */ = { + isa = PBXGroup; + children = ( + 97C146EE1CF9000F007C117D /* Runner.app */, + 331C8081294A63A400263BE5 /* RunnerTests.xctest */, + ); + name = Products; + sourceTree = ""; + }; + 97C146F01CF9000F007C117D /* Runner */ = { + isa = PBXGroup; + children = ( + 97C146FA1CF9000F007C117D /* Main.storyboard */, + 97C146FD1CF9000F007C117D /* Assets.xcassets */, + 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */, + 97C147021CF9000F007C117D /* Info.plist */, + 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */, + 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */, + 74858FAE1ED2DC5600515810 /* AppDelegate.swift */, + 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */, + ); + path = Runner; + sourceTree = ""; + }; + E7114C3F32BD70DD1950BD59 /* Pods */ = { + isa = PBXGroup; + children = ( + 9F3DAD41ACBE62DCC647F3B8 /* Pods-Runner.debug.xcconfig */, + 430F0A4173282D78C8F28354 /* Pods-Runner.release.xcconfig */, + AF0E938D37BDA368A07CB299 /* Pods-Runner.profile.xcconfig */, + D405FD9596CCED7157430C74 /* Pods-RunnerTests.debug.xcconfig */, + A7E83DBB1826CD9D3A064E3D /* Pods-RunnerTests.release.xcconfig */, + CD2ADA656814A888BCA45D23 /* Pods-RunnerTests.profile.xcconfig */, + ); + name = Pods; + path = Pods; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 331C8080294A63A400263BE5 /* RunnerTests */ = { + isa = PBXNativeTarget; + buildConfigurationList = 331C8087294A63A400263BE5 /* Build configuration list for PBXNativeTarget "RunnerTests" */; + buildPhases = ( + F3D0508EA3321B66D50657EC /* [CP] Check Pods Manifest.lock */, + 331C807D294A63A400263BE5 /* Sources */, + 331C807F294A63A400263BE5 /* Resources */, + AC89F723EB996FDAE502A039 /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + 331C8086294A63A400263BE5 /* PBXTargetDependency */, + ); + name = RunnerTests; + productName = RunnerTests; + productReference = 331C8081294A63A400263BE5 /* RunnerTests.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; + }; + 97C146ED1CF9000F007C117D /* Runner */ = { + isa = PBXNativeTarget; + buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */; + buildPhases = ( + 42325FF05B70CB02BFCCE667 /* [CP] Check Pods Manifest.lock */, + 9740EEB61CF901F6004384FC /* Run Script */, + 97C146EA1CF9000F007C117D /* Sources */, + 97C146EB1CF9000F007C117D /* Frameworks */, + 97C146EC1CF9000F007C117D /* Resources */, + 9705A1C41CF9048500538489 /* Embed Frameworks */, + 3B06AD1E1E4923F5004D2608 /* Thin Binary */, + 96EF6373ECA3887762113812 /* [CP] Embed Pods Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = Runner; + productName = Runner; + productReference = 97C146EE1CF9000F007C117D /* Runner.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 97C146E61CF9000F007C117D /* Project object */ = { + isa = PBXProject; + attributes = { + BuildIndependentTargetsInParallel = YES; + LastUpgradeCheck = 1430; + ORGANIZATIONNAME = ""; + TargetAttributes = { + 331C8080294A63A400263BE5 = { + CreatedOnToolsVersion = 14.0; + TestTargetID = 97C146ED1CF9000F007C117D; + }; + 97C146ED1CF9000F007C117D = { + CreatedOnToolsVersion = 7.3.1; + LastSwiftMigration = 1100; + }; + }; + }; + buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */; + compatibilityVersion = "Xcode 9.3"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 97C146E51CF9000F007C117D; + productRefGroup = 97C146EF1CF9000F007C117D /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 97C146ED1CF9000F007C117D /* Runner */, + 331C8080294A63A400263BE5 /* RunnerTests */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 331C807F294A63A400263BE5 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 97C146EC1CF9000F007C117D /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */, + 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */, + 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */, + 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXShellScriptBuildPhase section */ + 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = { + isa = PBXShellScriptBuildPhase; + alwaysOutOfDate = 1; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + "${TARGET_BUILD_DIR}/${INFOPLIST_PATH}", + ); + name = "Thin Binary"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin"; + }; + 42325FF05B70CB02BFCCE667 /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputFileListPaths = ( + ); + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + showEnvVarsInLog = 0; + }; + 96EF6373ECA3887762113812 /* [CP] Embed Pods Frameworks */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-input-files.xcfilelist", + ); + name = "[CP] Embed Pods Frameworks"; + outputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-output-files.xcfilelist", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n"; + showEnvVarsInLog = 0; + }; + 9740EEB61CF901F6004384FC /* Run Script */ = { + isa = PBXShellScriptBuildPhase; + alwaysOutOfDate = 1; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "Run Script"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build"; + }; + F3D0508EA3321B66D50657EC /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputFileListPaths = ( + ); + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-RunnerTests-checkManifestLockResult.txt", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + showEnvVarsInLog = 0; + }; +/* End PBXShellScriptBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 331C807D294A63A400263BE5 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 331C808B294A63AB00263BE5 /* RunnerTests.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 97C146EA1CF9000F007C117D /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */, + 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXTargetDependency section */ + 331C8086294A63A400263BE5 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 97C146ED1CF9000F007C117D /* Runner */; + targetProxy = 331C8085294A63A400263BE5 /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + +/* Begin PBXVariantGroup section */ + 97C146FA1CF9000F007C117D /* Main.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 97C146FB1CF9000F007C117D /* Base */, + ); + name = Main.storyboard; + sourceTree = ""; + }; + 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 97C147001CF9000F007C117D /* Base */, + ); + name = LaunchScreen.storyboard; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 249021D3217E4FDB00AE95B9 /* Profile */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + SUPPORTED_PLATFORMS = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + }; + name = Profile; + }; + 249021D4217E4FDB00AE95B9 /* Profile */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ENABLE_MODULES = YES; + CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + ENABLE_BITCODE = NO; + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.example.variancedemo; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; + SWIFT_VERSION = 5.0; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Profile; + }; + 331C8088294A63A400263BE5 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = D405FD9596CCED7157430C74 /* Pods-RunnerTests.debug.xcconfig */; + buildSettings = { + BUNDLE_LOADER = "$(TEST_HOST)"; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + GENERATE_INFOPLIST_FILE = YES; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = com.example.variancedemo.RunnerTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 5.0; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Runner.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Runner"; + }; + name = Debug; + }; + 331C8089294A63A400263BE5 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = A7E83DBB1826CD9D3A064E3D /* Pods-RunnerTests.release.xcconfig */; + buildSettings = { + BUNDLE_LOADER = "$(TEST_HOST)"; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + GENERATE_INFOPLIST_FILE = YES; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = com.example.variancedemo.RunnerTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Runner.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Runner"; + }; + name = Release; + }; + 331C808A294A63A400263BE5 /* Profile */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = CD2ADA656814A888BCA45D23 /* Pods-RunnerTests.profile.xcconfig */; + buildSettings = { + BUNDLE_LOADER = "$(TEST_HOST)"; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + GENERATE_INFOPLIST_FILE = YES; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = com.example.variancedemo.RunnerTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Runner.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Runner"; + }; + name = Profile; + }; + 97C147031CF9000F007C117D /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 97C147041CF9000F007C117D /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + SUPPORTED_PLATFORMS = iphoneos; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 97C147061CF9000F007C117D /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ENABLE_MODULES = YES; + CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + ENABLE_BITCODE = NO; + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.example.variancedemo; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 5.0; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Debug; + }; + 97C147071CF9000F007C117D /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ENABLE_MODULES = YES; + CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + ENABLE_BITCODE = NO; + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.example.variancedemo; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; + SWIFT_VERSION = 5.0; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 331C8087294A63A400263BE5 /* Build configuration list for PBXNativeTarget "RunnerTests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 331C8088294A63A400263BE5 /* Debug */, + 331C8089294A63A400263BE5 /* Release */, + 331C808A294A63A400263BE5 /* Profile */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 97C147031CF9000F007C117D /* Debug */, + 97C147041CF9000F007C117D /* Release */, + 249021D3217E4FDB00AE95B9 /* Profile */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 97C147061CF9000F007C117D /* Debug */, + 97C147071CF9000F007C117D /* Release */, + 249021D4217E4FDB00AE95B9 /* Profile */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 97C146E61CF9000F007C117D /* Project object */; +} diff --git a/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..919434a --- /dev/null +++ b/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 0000000..18d9810 --- /dev/null +++ b/example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings b/example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings new file mode 100644 index 0000000..f9b0d7c --- /dev/null +++ b/example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings @@ -0,0 +1,8 @@ + + + + + PreviewsEnabled + + + diff --git a/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme new file mode 100644 index 0000000..87131a0 --- /dev/null +++ b/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme @@ -0,0 +1,98 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/example/ios/Runner.xcworkspace/contents.xcworkspacedata b/example/ios/Runner.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..21a3cc1 --- /dev/null +++ b/example/ios/Runner.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,10 @@ + + + + + + + diff --git a/example/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/example/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 0000000..18d9810 --- /dev/null +++ b/example/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/example/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings b/example/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings new file mode 100644 index 0000000..f9b0d7c --- /dev/null +++ b/example/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings @@ -0,0 +1,8 @@ + + + + + PreviewsEnabled + + + diff --git a/example/ios/Runner/AppDelegate.swift b/example/ios/Runner/AppDelegate.swift new file mode 100644 index 0000000..70693e4 --- /dev/null +++ b/example/ios/Runner/AppDelegate.swift @@ -0,0 +1,13 @@ +import UIKit +import Flutter + +@UIApplicationMain +@objc class AppDelegate: FlutterAppDelegate { + override func application( + _ application: UIApplication, + didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? + ) -> Bool { + GeneratedPluginRegistrant.register(with: self) + return super.application(application, didFinishLaunchingWithOptions: launchOptions) + } +} diff --git a/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json b/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..d36b1fa --- /dev/null +++ b/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,122 @@ +{ + "images" : [ + { + "size" : "20x20", + "idiom" : "iphone", + "filename" : "Icon-App-20x20@2x.png", + "scale" : "2x" + }, + { + "size" : "20x20", + "idiom" : "iphone", + "filename" : "Icon-App-20x20@3x.png", + "scale" : "3x" + }, + { + "size" : "29x29", + "idiom" : "iphone", + "filename" : "Icon-App-29x29@1x.png", + "scale" : "1x" + }, + { + "size" : "29x29", + "idiom" : "iphone", + "filename" : "Icon-App-29x29@2x.png", + "scale" : "2x" + }, + { + "size" : "29x29", + "idiom" : "iphone", + "filename" : "Icon-App-29x29@3x.png", + "scale" : "3x" + }, + { + "size" : "40x40", + "idiom" : "iphone", + "filename" : "Icon-App-40x40@2x.png", + "scale" : "2x" + }, + { + "size" : "40x40", + "idiom" : "iphone", + "filename" : "Icon-App-40x40@3x.png", + "scale" : "3x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "Icon-App-60x60@2x.png", + "scale" : "2x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "Icon-App-60x60@3x.png", + "scale" : "3x" + }, + { + "size" : "20x20", + "idiom" : "ipad", + "filename" : "Icon-App-20x20@1x.png", + "scale" : "1x" + }, + { + "size" : "20x20", + "idiom" : "ipad", + "filename" : "Icon-App-20x20@2x.png", + "scale" : "2x" + }, + { + "size" : "29x29", + "idiom" : "ipad", + "filename" : "Icon-App-29x29@1x.png", + "scale" : "1x" + }, + { + "size" : "29x29", + "idiom" : "ipad", + "filename" : "Icon-App-29x29@2x.png", + "scale" : "2x" + }, + { + "size" : "40x40", + "idiom" : "ipad", + "filename" : "Icon-App-40x40@1x.png", + "scale" : "1x" + }, + { + "size" : "40x40", + "idiom" : "ipad", + "filename" : "Icon-App-40x40@2x.png", + "scale" : "2x" + }, + { + "size" : "76x76", + "idiom" : "ipad", + "filename" : "Icon-App-76x76@1x.png", + "scale" : "1x" + }, + { + "size" : "76x76", + "idiom" : "ipad", + "filename" : "Icon-App-76x76@2x.png", + "scale" : "2x" + }, + { + "size" : "83.5x83.5", + "idiom" : "ipad", + "filename" : "Icon-App-83.5x83.5@2x.png", + "scale" : "2x" + }, + { + "size" : "1024x1024", + "idiom" : "ios-marketing", + "filename" : "Icon-App-1024x1024@1x.png", + "scale" : "1x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} diff --git a/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png b/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png new file mode 100644 index 0000000..dc9ada4 Binary files /dev/null and b/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png differ diff --git a/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png b/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png new file mode 100644 index 0000000..7353c41 Binary files /dev/null and b/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png differ diff --git a/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png b/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png new file mode 100644 index 0000000..797d452 Binary files /dev/null and b/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png differ diff --git a/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png b/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png new file mode 100644 index 0000000..6ed2d93 Binary files /dev/null and b/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png differ diff --git a/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png b/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png new file mode 100644 index 0000000..4cd7b00 Binary files /dev/null and b/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png differ diff --git a/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png b/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png new file mode 100644 index 0000000..fe73094 Binary files /dev/null and b/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png differ diff --git a/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png b/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png new file mode 100644 index 0000000..321773c Binary files /dev/null and b/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png differ diff --git a/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png b/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png new file mode 100644 index 0000000..797d452 Binary files /dev/null and b/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png differ diff --git a/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png b/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png new file mode 100644 index 0000000..502f463 Binary files /dev/null and b/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png differ diff --git a/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png b/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png new file mode 100644 index 0000000..0ec3034 Binary files /dev/null and b/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png differ diff --git a/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png b/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png new file mode 100644 index 0000000..0ec3034 Binary files /dev/null and b/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png differ diff --git a/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png b/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png new file mode 100644 index 0000000..e9f5fea Binary files /dev/null and b/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png differ diff --git a/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png b/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png new file mode 100644 index 0000000..84ac32a Binary files /dev/null and b/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png differ diff --git a/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png b/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png new file mode 100644 index 0000000..8953cba Binary files /dev/null and b/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png differ diff --git a/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png b/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png new file mode 100644 index 0000000..0467bf1 Binary files /dev/null and b/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png differ diff --git a/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json b/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json new file mode 100644 index 0000000..0bedcf2 --- /dev/null +++ b/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "LaunchImage.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "LaunchImage@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "LaunchImage@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} diff --git a/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png b/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png new file mode 100644 index 0000000..9da19ea Binary files /dev/null and b/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png differ diff --git a/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png b/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png new file mode 100644 index 0000000..9da19ea Binary files /dev/null and b/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png differ diff --git a/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png b/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png new file mode 100644 index 0000000..9da19ea Binary files /dev/null and b/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png differ diff --git a/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md b/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md new file mode 100644 index 0000000..89c2725 --- /dev/null +++ b/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md @@ -0,0 +1,5 @@ +# Launch Screen Assets + +You can customize the launch screen with your own desired assets by replacing the image files in this directory. + +You can also do it by opening your Flutter project's Xcode project with `open ios/Runner.xcworkspace`, selecting `Runner/Assets.xcassets` in the Project Navigator and dropping in the desired images. \ No newline at end of file diff --git a/example/ios/Runner/Base.lproj/LaunchScreen.storyboard b/example/ios/Runner/Base.lproj/LaunchScreen.storyboard new file mode 100644 index 0000000..f2e259c --- /dev/null +++ b/example/ios/Runner/Base.lproj/LaunchScreen.storyboard @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/example/ios/Runner/Base.lproj/Main.storyboard b/example/ios/Runner/Base.lproj/Main.storyboard new file mode 100644 index 0000000..f3c2851 --- /dev/null +++ b/example/ios/Runner/Base.lproj/Main.storyboard @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/example/ios/Runner/Info.plist b/example/ios/Runner/Info.plist new file mode 100644 index 0000000..ec6255d --- /dev/null +++ b/example/ios/Runner/Info.plist @@ -0,0 +1,51 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleDisplayName + Variancedemo + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + variancedemo + CFBundlePackageType + APPL + CFBundleShortVersionString + $(FLUTTER_BUILD_NAME) + CFBundleSignature + ???? + CFBundleVersion + $(FLUTTER_BUILD_NUMBER) + LSRequiresIPhoneOS + + UILaunchStoryboardName + LaunchScreen + UIMainStoryboardFile + Main + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + CADisableMinimumFrameDurationOnPhone + + UIApplicationSupportsIndirectInputEvents + + NSFaceIDUsageDescription + Why is my app authenticating using face id? + + diff --git a/example/ios/Runner/Runner-Bridging-Header.h b/example/ios/Runner/Runner-Bridging-Header.h new file mode 100644 index 0000000..308a2a5 --- /dev/null +++ b/example/ios/Runner/Runner-Bridging-Header.h @@ -0,0 +1 @@ +#import "GeneratedPluginRegistrant.h" diff --git a/example/ios/RunnerTests/RunnerTests.swift b/example/ios/RunnerTests/RunnerTests.swift new file mode 100644 index 0000000..86a7c3b --- /dev/null +++ b/example/ios/RunnerTests/RunnerTests.swift @@ -0,0 +1,12 @@ +import Flutter +import UIKit +import XCTest + +class RunnerTests: XCTestCase { + + func testExample() { + // If you add code to the Runner application, consider adding tests here. + // See https://developer.apple.com/documentation/xctest for more information about using XCTest. + } + +} diff --git a/example/lib/main.dart b/example/lib/main.dart index c43724e..e203d25 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -1,103 +1,39 @@ -// ignore_for_file: public_member_api_docs - -import 'dart:math'; - -import 'package:flutter_secure_storage/flutter_secure_storage.dart'; -import 'package:variance_dart/utils.dart'; -import 'package:variance_dart/variance.dart'; -import 'package:web3dart/web3dart.dart'; - -const String rpcUrl = 'http://localhost:8545'; -const String bundlerUrl = 'http://localhost:3000/rpc'; - -Future main() async { - final Uint256 salt = Uint256.zero; - - // configure your chain - final Chain chain = Chain( - ethRpcUrl: rpcUrl, - bundlerUrl: bundlerUrl, - entrypoint: Constants.entrypoint, - accountFactory: Constants.accountFactory, - chainId: 1337, - explorer: ""); - - // create smart wallet signer based of seed phrase - final HDWalletSigner hd = HDWalletSigner.createWallet(); - print("mnemonic: ${hd.exportMnemonic()}"); - - // create a smart wallet signer based on passkeys - // this operation requires biometrics verification from the user - final PassKeyPair pkp = - await PassKeySigner("myapp.xyz", "myapp", "https://myapp.xyz") - .register("", true); - print("pkp: ${pkp.toJson()}"); - - // save a signer credential to device - await hd - .withSecureStorage(FlutterSecureStorage()) - .saveCredential(CredentialType.hdwallet); - - // load a credential from the device - final ss = SecureStorageMiddleware(secureStorage: FlutterSecureStorage()); - final hdInstance = - await HDWalletSigner.loadFromSecureStorage(storageMiddleware: ss); - print("pkp: ${hdInstance?.exportMnemonic()}"); - - // NOTE: interactions with securestorage can be authenticated when using `SecureStorageMiddleware` - // - // final ss = SecureStorageMiddleware(secureStorage: FlutterSecureStorage(), authMiddleware: AuthenticationMiddleware()); - // then used with `SecureStorageMiddleware` in the following way - // - // ss.save("key", "value", options: SSAuthOperationOptions(requiresAuth: true, authReason: "reason")) - // ss.read("key") // default options are used i.e requiresAuth: false - // ss.delete("key", options: SSAuthOperationOptions(requiresAuth: false)) // explicitly reject authentication - //; - - // create a smart wallet client - final walletClient = SmartWallet( - chain: chain, - signer: hd, - bundler: BundlerProvider(chain, RPCProvider(chain.bundlerUrl!)), - ); - - // create a simple account based on hd - final SmartWallet simpleSmartAccount = - await walletClient.createSimpleAccount(salt); - print("simple account address: ${simpleSmartAccount.address}"); - - // create a simple account based on pkp - final SmartWallet simplePkpAccount = - await walletClient.createSimplePasskeyAccount(pkp, salt); - print("simple pkp account address: ${simplePkpAccount.address}"); - - // retrieve the balance of a smart wallet - final EtherAmount balance = await simpleSmartAccount.balance; - print("account balance: ${balance.getInWei}"); - - // retrive the account nonce - final Uint256 nonce = await simpleSmartAccount.nonce; - print("account nonce: ${nonce.toInt()}"); - - // check if a smart wallet has been deployed - final bool deployed = await simpleSmartAccount.deployed; - print("account deployed: $deployed"); - - // get the init code of the smart wallet - final String initCode = simpleSmartAccount.initCode; - print("account init code: $initCode"); - - // perform a simple transaction (send ether to another account) - // account must be prefunded with native token. paymaster is not yet implemented - await simpleSmartAccount.send( - EthereumAddress.fromHex( - "0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789"), // receive address - getConversion("0.7142"), // 0.7142 ether - ); +import 'package:flutter/material.dart'; +import 'package:flutter_screenutil/flutter_screenutil.dart'; +import 'package:google_fonts/google_fonts.dart'; +import 'package:provider/provider.dart'; +import 'package:variancedemo/providers/wallet_provider.dart'; +import 'package:variancedemo/screens/create_account.dart'; +import 'package:variancedemo/screens/home/home_screen.dart'; + +final globalScaffoldMessengerKey = GlobalKey(); + +void main() { + WidgetsFlutterBinding.ensureInitialized(); + runApp(MultiProvider(providers: [ + ChangeNotifierProvider(create: (_) => WalletProvider()), + ], child: const MyApp())); } -EtherAmount getConversion(String amount) { - final amtToDb = double.parse(amount); - return EtherAmount.fromBigInt( - EtherUnit.wei, BigInt.from(amtToDb * pow(10, 18))); +class MyApp extends StatelessWidget { + const MyApp({super.key}); + + @override + Widget build(BuildContext context) { + return ScreenUtilInit( + designSize: const Size(375, 812), + child: MaterialApp( + title: 'Variance Dart', + routes: { + '/': (context) => const CreateAccountScreen(), + '/home': (context) => const WalletHome(), + }, + theme: ThemeData( + colorScheme: ColorScheme.fromSeed(seedColor: const Color(0xffE1FF01)), + textTheme: GoogleFonts.poppinsTextTheme(), + ), + debugShowCheckedModeBanner: false, + ), + ); + } } diff --git a/example/lib/providers/wallet_provider.dart b/example/lib/providers/wallet_provider.dart new file mode 100644 index 0000000..baf881a --- /dev/null +++ b/example/lib/providers/wallet_provider.dart @@ -0,0 +1,189 @@ +import 'dart:convert'; +import 'dart:developer'; +import 'dart:io'; +import 'dart:math' as math; +import 'package:flutter/foundation.dart'; +import 'package:web3_signers/web3_signers.dart'; +import 'package:variance_dart/variance_dart.dart'; +import 'package:web3dart/credentials.dart'; +import 'package:web3dart/web3dart.dart' as w3d; +import 'package:web3dart/crypto.dart' as w3d; + +class WalletProvider extends ChangeNotifier { + final Chain _chain; + + SmartWallet? _wallet; + SmartWallet? get wallet => _wallet; + + String _errorMessage = ""; + String get errorMessage => _errorMessage; + + final EthereumAddress nft = + EthereumAddress.fromHex("0x4B509a7e891Dc8fd45491811d67a8B9e7ef547B9"); + final EthereumAddress erc20 = + EthereumAddress.fromHex("0xAEaF19097D8a8da728438D6B57edd9Bc5DAc4795"); + final EthereumAddress deployer = + EthereumAddress.fromHex("0x218F6Bbc32Ef28F547A67c70AbCF8c2ea3b468BA"); + + WalletProvider() + : _chain = Chain( + chainId: 11155111, + explorer: "https://sepolia.etherscan.io/", + entrypoint: EntryPointAddress.v07) + ..accountFactory = EthereumAddress.fromHex( + "0xECA49857B32A12403F5a3A64ad291861EF4B63cb") // v07 p256 factory address + ..jsonRpcUrl = "https://rpc.ankr.com/eth_sepolia" + ..bundlerUrl = + "https://api.pimlico.io/v2/11155111/rpc?apikey=YOUR_API_KEY" + ..paymasterUrl = + "https://api.pimlico.io/v2/11155111/rpc?apikey=YOUR_API_KEY"; + + // "0x402A266e92993EbF04a5B3fd6F0e2b21bFC83070" v06 p256 factory address + Future registerWithPassKey(String name, + {bool? requiresUserVerification}) async { + final pkpSigner = + PassKeySigner("webauthn.io", "webauthn", "https://webauthn.io"); + final hwdSigner = HardwareSigner.withTag(name); + + final salt = Uint256.fromHex( + hexlify(w3d.keccak256(Uint8List.fromList(utf8.encode(name))))); + + try { + // uses passkeys on android, secure enclave on iOS + if (Platform.isAndroid) { + final SmartWalletFactory walletFactory = + SmartWalletFactory(_chain, pkpSigner); + final keypair = await pkpSigner.register(name, name); + _wallet = + await walletFactory.createP256Account(keypair, salt); + } else if (Platform.isIOS) { + final SmartWalletFactory walletFactory = + SmartWalletFactory(_chain, hwdSigner); + final keypair = await hwdSigner.generateKeyPair(); + _wallet = await walletFactory.createP256Account( + keypair, salt); + } + + log("wallet created ${_wallet?.address.hex} "); + } catch (e) { + _errorMessage = e.toString(); + notifyListeners(); + log("something happened: $e"); + } + } + + Future createEOAWallet() async { + _chain.accountFactory = Constants.simpleAccountFactoryAddressv06; + + final signer = EOAWallet.createWallet(); + log("signer: ${signer.getAddress()}"); + + final SmartWalletFactory walletFactory = SmartWalletFactory(_chain, signer); + final salt = Uint256.fromHex(hexlify(w3d + .keccak256(EthereumAddress.fromHex(signer.getAddress()).addressBytes))); + + try { + _wallet = await walletFactory.createSimpleAccount(salt); + log("wallet created ${_wallet?.address.hex} "); + } catch (e) { + _errorMessage = e.toString(); + notifyListeners(); + log("something happened: $e"); + } + } + + Future createPrivateKeyWallet() async { + _chain.accountFactory = Constants.simpleAccountFactoryAddressv06; + + final signer = PrivateKeySigner.createRandom("123456"); + log("signer: ${signer.getAddress()}"); + + final SmartWalletFactory walletFactory = SmartWalletFactory(_chain, signer); + + final salt = Uint256.fromHex(hexlify(w3d + .keccak256(EthereumAddress.fromHex(signer.getAddress()).addressBytes))); + + log("salt: ${salt.toHex()}"); + + try { + _wallet = await walletFactory.createSimpleAccount(salt); + log("wallet created ${_wallet?.address.hex} "); + } catch (e) { + _errorMessage = e.toString(); + notifyListeners(); + log("something happened: $e"); + } + } + + Future createSafeWallet() async { + _chain.accountFactory = Constants.safeProxyFactoryAddress; + + final signer = EOAWallet.createWallet(); + log("signer: ${signer.getAddress()}"); + + final SmartWalletFactory walletFactory = SmartWalletFactory(_chain, signer); + + final salt = Uint256.fromHex(hexlify(w3d + .keccak256(EthereumAddress.fromHex(signer.getAddress()).addressBytes))); + + log("salt: ${salt.toHex()}"); + + try { + _wallet = await walletFactory.createSafeAccount(salt); + log("safe created ${_wallet?.address.hex} "); + } catch (e) { + log("something happened: $e"); + } + } + + Future mintNFt() async { + // pimlico requires us to get the gasfees from their bundler. + // that cannot be built into the sdk so we modify the internal fees manually + if (_chain.entrypoint.version == 0.7) { + _wallet?.gasSettings = GasSettings( + gasMultiplierPercentage: 5, + userDefinedMaxFeePerGas: BigInt.parse("0x524e1909"), + userDefinedMaxPriorityFeePerGas: BigInt.parse("0x52412100")); + } + // mints nft + final tx1 = await _wallet?.sendTransaction( + nft, + Contract.encodeFunctionCall("safeMint", nft, + ContractAbis.get("ERC721_SafeMint"), [_wallet?.address])); + await tx1?.wait(); + + await sendBatchedTransaction(); + } + + Future sendBatchedTransaction() async { + final tx = await _wallet?.sendBatchedTransaction([ + erc20, + erc20 + ], [ + Contract.encodeFunctionCall( + "mint", erc20, ContractAbis.get("ERC20_Mint"), [ + _wallet?.address, + w3d.EtherAmount.fromInt(w3d.EtherUnit.ether, 20).getInWei + ]), + Contract.encodeERC20TransferCall( + erc20, deployer, w3d.EtherAmount.fromInt(w3d.EtherUnit.ether, 20)) + ]); + + await tx?.wait(); + } + + Future sendTransaction(String recipient, String amount) async { + if (_wallet != null) { + final etherAmount = w3d.EtherAmount.fromBigInt(w3d.EtherUnit.wei, + BigInt.from(double.parse(amount) * math.pow(10, 18))); + + final response = + await _wallet?.send(EthereumAddress.fromHex(recipient), etherAmount); + final receipt = await response?.wait(); + + log("Transaction receipt Hash: ${receipt?.userOpHash}"); + } else { + log("No wallet available to send transaction"); + } + } +} diff --git a/example/lib/screens/create_account.dart b/example/lib/screens/create_account.dart new file mode 100644 index 0000000..d74cab2 --- /dev/null +++ b/example/lib/screens/create_account.dart @@ -0,0 +1,145 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_screenutil/flutter_screenutil.dart'; +import 'package:fluttertoast/fluttertoast.dart'; +import 'package:provider/provider.dart'; +import 'package:variancedemo/main.dart'; +import 'package:variancedemo/providers/wallet_provider.dart'; + +class CreateAccountScreen extends StatefulWidget { + const CreateAccountScreen({super.key}); + + @override + State createState() => _CreateAccountScreenState(); +} + +class _CreateAccountScreenState extends State { + final TextEditingController controller = TextEditingController(); + final _formKey = GlobalKey(); + FToast? fToast; + + @override + void initState() { + super.initState(); + fToast = FToast(); + fToast?.init(context); + } + + @override + Widget build(BuildContext context) { + return SafeArea( + child: Scaffold( + body: Consumer( + builder: (context, value, child) { + return Padding( + padding: EdgeInsets.symmetric(horizontal: 16.sp), + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + const Text( + 'Create Account', + style: TextStyle(fontSize: 51, fontWeight: FontWeight.w500), + ), + const SizedBox(height: 50), + Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Expanded( + child: Container( + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(25)), + child: TextFormField( + key: _formKey, + autovalidateMode: AutovalidateMode.onUserInteraction, + validator: (value) { + if (value!.isEmpty) { + return 'Please enter a username'; + } + if (!RegExp(r'^[a-zA-Z]+$').hasMatch(value)) { + return 'Username must contain only alphabets with no spaces'; + } + return null; + }, + onChanged: (value) { + setState(() { + controller.text = value; + }); + }, + controller: controller, + maxLines: 1, + textAlign: TextAlign.center, + decoration: InputDecoration( + contentPadding: const EdgeInsets.all(8), + hintText: 'Choose a username', + hintStyle: TextStyle( + fontSize: 20.sp, + ), + border: const OutlineInputBorder( + borderRadius: BorderRadius.all( + Radius.circular(12), + ), + ), + fillColor: Colors.white, + filled: true), + ), + )), + const SizedBox( + width: 10, + ), + SizedBox( + height: 45.h, + child: TextButton( + key: globalScaffoldMessengerKey, + onPressed: () async { + await value.registerWithPassKey(controller.text, + requiresUserVerification: true); + // ignore: use_build_context_synchronously + if (value.errorMessage.isNotEmpty) { + fToast?.showToast( + gravity: ToastGravity.BOTTOM, + child: Text(value.errorMessage)); + } else { + Navigator.pushNamed(context, '/home'); + } + }, + style: TextButton.styleFrom( + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(12)), + backgroundColor: const Color(0xffE1FF01), + ), + child: const Text( + 'Continue', + style: TextStyle(fontSize: 14, color: Colors.black), + ), + ), + ) + ], + ), + 18.verticalSpace, + Container( + margin: const EdgeInsets.only(left: 135), + child: Text('OR', style: TextStyle(fontSize: 18.sp))), + 24.verticalSpace, + Container( + margin: const EdgeInsets.only(left: 30), + child: TextButton.icon( + onPressed: () { + try { + context.read().createSafeWallet(); + Navigator.pushNamed(context, '/home'); + } catch (e) { + 'Something went wrong: $e'; + } + }, + icon: const Icon(Icons.key), + label: const Text('Create Safe Smart Account')), + ) + ], + ), + ); + }, + ), + ), + ); + } +} diff --git a/example/lib/screens/home/home_screen.dart b/example/lib/screens/home/home_screen.dart new file mode 100644 index 0000000..e8b32c9 --- /dev/null +++ b/example/lib/screens/home/home_screen.dart @@ -0,0 +1,215 @@ +import 'dart:developer'; +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; +import 'package:flutter/widgets.dart'; +import 'package:flutter_screenutil/flutter_screenutil.dart'; +import 'package:provider/provider.dart'; +import 'package:variancedemo/providers/wallet_provider.dart'; +import 'package:variancedemo/screens/home/home_widgets.dart'; +import 'package:variancedemo/utils/widgets.dart'; +import 'package:variancedemo/variance_colors.dart'; + +class WalletHome extends StatefulWidget { + const WalletHome({super.key}); + + @override + State createState() => _WalletHomeState(); +} + +class _WalletHomeState extends State + with SingleTickerProviderStateMixin { + final _formKey = GlobalKey(); + late TabController _tabController; + TextEditingController amountController = TextEditingController(); + TextEditingController addressController = TextEditingController(); + + @override + void initState() { + _tabController = TabController(length: 3, vsync: this); + super.initState(); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor: VarianceColors.primary, + body: SafeArea( + child: Padding( + padding: EdgeInsets.symmetric(vertical: 19.h, horizontal: 16.w), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + const WalletBalance(), + 50.verticalSpace, + TabBar( + controller: _tabController, + tabs: [ + Tab( + child: Text('Send', + style: TextStyle( + fontSize: 20.sp, color: VarianceColors.secondary)), + ), + Tab( + child: Text('Receive', + style: TextStyle( + fontSize: 20.sp, color: VarianceColors.secondary)), + ), + Tab( + child: Text('NFT', + style: TextStyle( + fontSize: 20.sp, color: VarianceColors.secondary)), + ), + ], + ), + Expanded( + child: TabBarView(controller: _tabController, children: [ + Send( + addressController: addressController, + formKey: _formKey, + amountController: amountController), + const Receive(), + const NFT(), + ]), + ), + 60.verticalSpace, + ], + ), + ), + ), + ); + } +} + +class Send extends StatelessWidget { + const Send({ + super.key, + required this.addressController, + required GlobalKey formKey, + required this.amountController, + }) : _formKey = formKey; + + final TextEditingController addressController; + final GlobalKey _formKey; + final TextEditingController amountController; + + @override + Widget build(BuildContext context) { + return Column( + // mainAxisAlignment: MainAxisAlignment.center, + children: [ + 50.verticalSpace, + AddressBar( + hintText: 'Eth Address', + textEditingController: addressController, + ), + 18.verticalSpace, + TextFormField( + style: TextStyle( + fontSize: 51.sp, + fontWeight: FontWeight.w600, + color: VarianceColors.secondary), + key: _formKey, + validator: (value) { + if (value == null || value.isEmpty) { + return 'Please enter a value'; + } else if (int.parse(value) > 100) { + return 'Value should be less than or equal to 100'; + } + return null; + }, + onChanged: (value) { + if (value.isEmpty) { + return; + } + }, + textAlign: TextAlign.center, + controller: amountController, + keyboardType: TextInputType.number, + decoration: const InputDecoration( + focusColor: Colors.white, + fillColor: Colors.white, + border: InputBorder.none, + hintText: '0.0', + hintStyle: + TextStyle(fontSize: 51, color: VarianceColors.secondary), + ), + cursorColor: VarianceColors.secondary, + inputFormatters: [ + FilteringTextInputFormatter.allow( + RegExp(r'^\.?\d*(?().sendTransaction( + addressController.text, amountController.text); + }, + child: const Text('Send')), + ), + ], + ); + } +} + +class NFT extends StatelessWidget { + const NFT({super.key}); + + @override + Widget build(BuildContext context) { + final wallet = context.select( + (WalletProvider provider) => provider.wallet, + ); + return Column( + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + 50.verticalSpace, + Row( + children: [ + const CircleAvatar(), + 10.horizontalSpace, + const Text( + 'NFT', + style: TextStyle(color: VarianceColors.secondary), + ), + const Spacer(), + const Text( + '\$0.00', + style: TextStyle(color: VarianceColors.secondary), + ), + ], + ), + 10.verticalSpace, + Row(children: [ + const CircleAvatar(), + 10.horizontalSpace, + const Text( + 'NFT', + style: TextStyle(color: VarianceColors.secondary), + ), + const Spacer(), + const Text( + '\$0.00', + style: TextStyle(color: VarianceColors.secondary), + ), + ]), + const Spacer(), + ElevatedButton( + onPressed: () { + context.read().mintNFt(); + }, + child: const Text('Mint')), + ], + ); + } +} diff --git a/example/lib/screens/home/home_widgets.dart b/example/lib/screens/home/home_widgets.dart new file mode 100644 index 0000000..0e54fd8 --- /dev/null +++ b/example/lib/screens/home/home_widgets.dart @@ -0,0 +1,209 @@ +import 'dart:async'; + +import 'package:flutter/material.dart'; +import 'dart:ui' as ui; +import 'package:flutter/services.dart'; +import 'package:flutter/widgets.dart'; +import 'package:flutter_screenutil/flutter_screenutil.dart'; +import 'package:provider/provider.dart'; +import 'package:qr_flutter/qr_flutter.dart'; +import 'package:variancedemo/providers/wallet_provider.dart'; +import 'package:variancedemo/variance_colors.dart'; +import 'package:web3_signers/web3_signers.dart'; +import 'package:web3dart/web3dart.dart'; + +String address = ''; + +class WalletBalance extends StatefulWidget { + const WalletBalance({super.key}); + + @override + State createState() => _WalletBalanceState(); +} + +class _WalletBalanceState extends State { + Uint256 balance = Uint256.zero; + + @override + Widget build(BuildContext context) { + final wallet = context.select( + (WalletProvider provider) => provider.wallet, + ); + // final hdWallet = context.select( + // (WalletProvider provider) => provider.hdWalletSigner, + // ); + + address = wallet?.address.hex ?? ''; + + Future getBalance() async { + final ether = await wallet?.balance; + setState(() { + balance = Uint256.fromWei(ether ?? EtherAmount.zero()); + }); + } + //if the wallet is created with a passkey + + getBalance(); + return Consumer( + builder: (context, value, child) { + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + children: [ + Text( + 'Total Balance', + style: TextStyle( + color: VarianceColors.secondary, fontSize: 14.sp), + ), + 10.horizontalSpace, + const Image( + image: AssetImage( + 'assets/images/down-arrow.png', + ), + height: 10, + width: 10, + color: VarianceColors.secondary, + ), + const Spacer(), + Expanded( + child: Text( + address, + style: const TextStyle( + color: VarianceColors.secondary, + overflow: TextOverflow.ellipsis, + ), + ), + ) + ], + ), + 18.verticalSpace, + Text( + '${balance.fromUnit(18)} ETH', + style: TextStyle(color: Colors.white, fontSize: 24.sp), + ), + 18.verticalSpace, + ], + ); + }, + ); + } +} + +String message = address; +final FutureBuilder qrFutureBuilder = FutureBuilder( + future: _loadOverlayImage(), + builder: (BuildContext ctx, AsyncSnapshot snapshot) { + const double size = 280.0; + if (!snapshot.hasData) { + return const SizedBox(width: size, height: size); + } + return CustomPaint( + size: const Size.square(size), + painter: QrPainter( + data: message.toString(), + version: QrVersions.auto, + eyeStyle: const QrEyeStyle( + eyeShape: QrEyeShape.square, + color: Color(0xff000000), + ), + dataModuleStyle: const QrDataModuleStyle( + dataModuleShape: QrDataModuleShape.circle, + color: Color(0xff000000), + ), + // size: 320.0, + embeddedImage: snapshot.data, + embeddedImageStyle: const QrEmbeddedImageStyle( + size: Size.square(60), + ), + ), + ); + }, +); +Future _loadOverlayImage() async { + final Completer completer = Completer(); + final ByteData byteData = await rootBundle.load('assets/images/ethereum.png'); + ui.decodeImageFromList(byteData.buffer.asUint8List(), completer.complete); + return completer.future; +} + +class Receive extends StatelessWidget { + const Receive({super.key}); + + @override + Widget build(BuildContext context) { + return Container( + padding: const EdgeInsets.symmetric(horizontal: 10.0), + child: SizedBox( + height: MediaQuery.of(context).size.height * 0.89, + child: Column( + crossAxisAlignment: CrossAxisAlignment.stretch, + mainAxisAlignment: MainAxisAlignment.center, + children: [ + 50.verticalSpace, + Center( + child: Container( + padding: const EdgeInsets.all(10.0), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(10), + ), + child: qrFutureBuilder, // Replace with your content + ), + ), + const SizedBox(height: 50), + Container( + padding: const EdgeInsets.symmetric(horizontal: 10), + // margin: const EdgeInsets.symmetric(horizontal: 15), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(10), + border: Border.all(color: Colors.grey.shade400), + ), + child: Row( + // mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + SizedBox( + width: 200, + child: Text( + message, + style: TextStyle( + fontFamily: 'Inter', + overflow: TextOverflow.ellipsis, + color: const Color(0xff32353E).withOpacity(0.5), + ), + ), + ), + const SizedBox(height: 5), + Expanded( + child: TextButton( + onPressed: () { + Clipboard.setData(ClipboardData( + text: message, + )); + }, + style: TextButton.styleFrom( + backgroundColor: const Color(0xff32353E), + padding: const EdgeInsets.only(left: 30, right: 30), + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(10), + ), + ), + child: const Text( + 'copy', + style: TextStyle( + color: Colors.white, + fontFamily: 'Inter', + ), + ), + ), + ), + ], + ), + ), + ], + ), + ), + ); + } +} diff --git a/example/lib/utils/widgets.dart b/example/lib/utils/widgets.dart new file mode 100644 index 0000000..2431ee7 --- /dev/null +++ b/example/lib/utils/widgets.dart @@ -0,0 +1,76 @@ +import 'package:flutter/material.dart'; +import 'package:variancedemo/main.dart'; +import 'package:variancedemo/variance_colors.dart'; + +void showSnackbar(String message) { + var currentScaffoldMessenger = globalScaffoldMessengerKey.currentState; + currentScaffoldMessenger?.hideCurrentSnackBar(); + currentScaffoldMessenger?.showSnackBar(SnackBar(content: Text(message))); +} + +class AddressBar extends StatefulWidget { + final String hintText; + final TextEditingController? textEditingController; + final TextStyle? hintTextStyle; + + // Add an optional parameter for the initial value + final String initialValue; + + const AddressBar({ + required this.hintText, + this.hintTextStyle, + this.textEditingController, + this.initialValue = "0.0", // Provide a default initial value + Key? key, + }) : super(key: key); + + @override + State createState() => _AddressBarState(); +} + +class _AddressBarState extends State { + bool pwdVisibility = false; + final formKey = GlobalKey(); + late final TextEditingController textEditingController; + @override + void initState() { + super.initState(); + // Initialize the TextEditingController with the initial value + textEditingController = widget.textEditingController ?? + TextEditingController(text: widget.initialValue); + } + + @override + Widget build(BuildContext context) { + return TextFormField( + cursorColor: VarianceColors.primary, + controller: widget.textEditingController, + textAlign: TextAlign.center, + decoration: InputDecoration( + fillColor: VarianceColors.secondary, + filled: true, + hintText: widget.hintText, + hintStyle: widget.hintTextStyle, + enabledBorder: OutlineInputBorder( + borderSide: const BorderSide( + color: Colors.white, + width: 1, + ), + borderRadius: BorderRadius.circular(10), + ), + focusedBorder: OutlineInputBorder( + borderSide: const BorderSide( + color: Colors.white, + width: 1, + ), + borderRadius: BorderRadius.circular(10)), + ), + validator: (val) { + if (val!.isEmpty) { + return 'Required'; + } + return null; + }, + ); + } +} diff --git a/example/lib/variance_colors.dart b/example/lib/variance_colors.dart new file mode 100644 index 0000000..3a012d8 --- /dev/null +++ b/example/lib/variance_colors.dart @@ -0,0 +1,8 @@ +import 'package:flutter/material.dart'; + +/// +class VarianceColors { + static const Color primary = Color(0xff1B1D1F); + static const Color secondary = Color(0xffC0C1C1); + static const Color white = Color(0xffffffff); +} diff --git a/example/pubspec.lock b/example/pubspec.lock new file mode 100644 index 0000000..eedf18d --- /dev/null +++ b/example/pubspec.lock @@ -0,0 +1,761 @@ +# Generated by pub +# See https://dart.dev/tools/pub/glossary#lockfile +packages: + ansicolor: + dependency: transitive + description: + name: ansicolor + sha256: "8bf17a8ff6ea17499e40a2d2542c2f481cd7615760c6d34065cb22bfd22e6880" + url: "https://pub.dev" + source: hosted + version: "2.0.2" + archive: + dependency: transitive + description: + name: archive + sha256: "22600aa1e926be775fa5fe7e6894e7fb3df9efda8891c73f70fb3262399a432d" + url: "https://pub.dev" + source: hosted + version: "3.4.10" + args: + dependency: transitive + description: + name: args + sha256: eef6c46b622e0494a36c5a12d10d77fb4e855501a91c1b9ef9339326e58f0596 + url: "https://pub.dev" + source: hosted + version: "2.4.2" + asn1lib: + dependency: transitive + description: + name: asn1lib + sha256: c9c85fedbe2188b95133cbe960e16f5f448860f7133330e272edbbca5893ddc6 + url: "https://pub.dev" + source: hosted + version: "1.5.2" + async: + dependency: transitive + description: + name: async + sha256: "947bfcf187f74dbc5e146c9eb9c0f10c9f8b30743e341481c1e2ed3ecc18c20c" + url: "https://pub.dev" + source: hosted + version: "2.11.0" + blockchain_utils: + dependency: transitive + description: + name: blockchain_utils + sha256: "38ef5f4a22441ac4370aed9071dc71c460acffc37c79b344533f67d15f24c13c" + url: "https://pub.dev" + source: hosted + version: "2.1.1" + boolean_selector: + dependency: transitive + description: + name: boolean_selector + sha256: "6cfb5af12253eaf2b368f07bacc5a80d1301a071c73360d746b7f2e32d762c66" + url: "https://pub.dev" + source: hosted + version: "2.1.1" + characters: + dependency: transitive + description: + name: characters + sha256: "04a925763edad70e8443c99234dc3328f442e811f1d8fd1a72f1c8ad0f69a605" + url: "https://pub.dev" + source: hosted + version: "1.3.0" + checked_yaml: + dependency: transitive + description: + name: checked_yaml + sha256: feb6bed21949061731a7a75fc5d2aa727cf160b91af9a3e464c5e3a32e28b5ff + url: "https://pub.dev" + source: hosted + version: "2.0.3" + cli_util: + dependency: transitive + description: + name: cli_util + sha256: c05b7406fdabc7a49a3929d4af76bcaccbbffcbcdcf185b082e1ae07da323d19 + url: "https://pub.dev" + source: hosted + version: "0.4.1" + clock: + dependency: transitive + description: + name: clock + sha256: cb6d7f03e1de671e34607e909a7213e31d7752be4fb66a86d29fe1eb14bfb5cf + url: "https://pub.dev" + source: hosted + version: "1.1.1" + collection: + dependency: transitive + description: + name: collection + sha256: ee67cb0715911d28db6bf4af1026078bd6f0128b07a5f66fb2ed94ec6783c09a + url: "https://pub.dev" + source: hosted + version: "1.18.0" + convert: + dependency: transitive + description: + name: convert + sha256: "0f08b14755d163f6e2134cb58222dd25ea2a2ee8a195e53983d57c075324d592" + url: "https://pub.dev" + source: hosted + version: "3.1.1" + corbado_frontend_api_client: + dependency: transitive + description: + name: corbado_frontend_api_client + sha256: a6d65fc0da88f2e6a6e95251de0b67735556128c5d96c9b609e7b18010a6f6c1 + url: "https://pub.dev" + source: hosted + version: "1.1.0" + crypto: + dependency: transitive + description: + name: crypto + sha256: ff625774173754681d66daaf4a448684fb04b78f902da9cb3d308c19cc5e8bab + url: "https://pub.dev" + source: hosted + version: "3.0.3" + csslib: + dependency: transitive + description: + name: csslib + sha256: "706b5707578e0c1b4b7550f64078f0a0f19dec3f50a178ffae7006b0a9ca58fb" + url: "https://pub.dev" + source: hosted + version: "1.0.0" + cupertino_icons: + dependency: "direct main" + description: + name: cupertino_icons + sha256: d57953e10f9f8327ce64a508a355f0b1ec902193f66288e8cb5070e7c47eeb2d + url: "https://pub.dev" + source: hosted + version: "1.0.6" + eip1559: + dependency: transitive + description: + name: eip1559 + sha256: c2b81ac85f3e0e71aaf558201dd9a4600f051ece7ebacd0c5d70065c9b458004 + url: "https://pub.dev" + source: hosted + version: "0.6.2" + eip55: + dependency: transitive + description: + name: eip55 + sha256: "213a9b86add87a5216328e8494b0ab836e401210c4d55eb5e521bd39e39169e1" + url: "https://pub.dev" + source: hosted + version: "1.0.2" + fake_async: + dependency: transitive + description: + name: fake_async + sha256: "511392330127add0b769b75a987850d136345d9227c6b94c96a04cf4a391bf78" + url: "https://pub.dev" + source: hosted + version: "1.3.1" + ffi: + dependency: transitive + description: + name: ffi + sha256: "7bf0adc28a23d395f19f3f1eb21dd7cfd1dd9f8e1c50051c069122e6853bc878" + url: "https://pub.dev" + source: hosted + version: "2.1.0" + file: + dependency: transitive + description: + name: file + sha256: "5fc22d7c25582e38ad9a8515372cd9a93834027aacf1801cf01164dac0ffa08c" + url: "https://pub.dev" + source: hosted + version: "7.0.0" + fixnum: + dependency: transitive + description: + name: fixnum + sha256: "25517a4deb0c03aa0f32fd12db525856438902d9c16536311e76cdc57b31d7d1" + url: "https://pub.dev" + source: hosted + version: "1.1.0" + flutter: + dependency: "direct main" + description: flutter + source: sdk + version: "0.0.0" + flutter_launcher_icons: + dependency: "direct main" + description: + name: flutter_launcher_icons + sha256: "526faf84284b86a4cb36d20a5e45147747b7563d921373d4ee0559c54fcdbcea" + url: "https://pub.dev" + source: hosted + version: "0.13.1" + flutter_lints: + dependency: "direct dev" + description: + name: flutter_lints + sha256: a25a15ebbdfc33ab1cd26c63a6ee519df92338a9c10f122adda92938253bef04 + url: "https://pub.dev" + source: hosted + version: "2.0.3" + flutter_native_splash: + dependency: "direct main" + description: + name: flutter_native_splash + sha256: "558f10070f03ee71f850a78f7136ab239a67636a294a44a06b6b7345178edb1e" + url: "https://pub.dev" + source: hosted + version: "2.3.10" + flutter_screenutil: + dependency: "direct main" + description: + name: flutter_screenutil + sha256: "8cf100b8e4973dc570b6415a2090b0bfaa8756ad333db46939efc3e774ee100d" + url: "https://pub.dev" + source: hosted + version: "5.9.0" + flutter_test: + dependency: "direct dev" + description: flutter + source: sdk + version: "0.0.0" + flutter_web_plugins: + dependency: transitive + description: flutter + source: sdk + version: "0.0.0" + fluttertoast: + dependency: "direct main" + description: + name: fluttertoast + sha256: dfdde255317af381bfc1c486ed968d5a43a2ded9c931e87cbecd88767d6a71c1 + url: "https://pub.dev" + source: hosted + version: "8.2.4" + google_fonts: + dependency: "direct main" + description: + name: google_fonts + sha256: f0b8d115a13ecf827013ec9fc883390ccc0e87a96ed5347a3114cac177ef18e8 + url: "https://pub.dev" + source: hosted + version: "6.1.0" + html: + dependency: transitive + description: + name: html + sha256: "3a7812d5bcd2894edf53dfaf8cd640876cf6cef50a8f238745c8b8120ea74d3a" + url: "https://pub.dev" + source: hosted + version: "0.15.4" + http: + dependency: transitive + description: + name: http + sha256: a2bbf9d017fcced29139daa8ed2bba4ece450ab222871df93ca9eec6f80c34ba + url: "https://pub.dev" + source: hosted + version: "1.2.0" + http_parser: + dependency: transitive + description: + name: http_parser + sha256: "2aa08ce0341cc9b354a498388e30986515406668dbcc4f7c950c3e715496693b" + url: "https://pub.dev" + source: hosted + version: "4.0.2" + image: + dependency: transitive + description: + name: image + sha256: "4c68bfd5ae83e700b5204c1e74451e7bf3cf750e6843c6e158289cf56bda018e" + url: "https://pub.dev" + source: hosted + version: "4.1.7" + intl: + dependency: transitive + description: + name: intl + sha256: "3bc132a9dbce73a7e4a21a17d06e1878839ffbf975568bc875c60537824b0c4d" + url: "https://pub.dev" + source: hosted + version: "0.18.1" + js: + dependency: transitive + description: + name: js + sha256: f2c445dce49627136094980615a031419f7f3eb393237e4ecd97ac15dea343f3 + url: "https://pub.dev" + source: hosted + version: "0.6.7" + json_annotation: + dependency: transitive + description: + name: json_annotation + sha256: b10a7b2ff83d83c777edba3c6a0f97045ddadd56c944e1a23a3fdf43a1bf4467 + url: "https://pub.dev" + source: hosted + version: "4.8.1" + json_rpc_2: + dependency: transitive + description: + name: json_rpc_2 + sha256: "5e469bffa23899edacb7b22787780068d650b106a21c76db3c49218ab7ca447e" + url: "https://pub.dev" + source: hosted + version: "3.0.2" + lints: + dependency: transitive + description: + name: lints + sha256: "0a217c6c989d21039f1498c3ed9f3ed71b354e69873f13a8dfc3c9fe76f1b452" + url: "https://pub.dev" + source: hosted + version: "2.1.1" + matcher: + dependency: transitive + description: + name: matcher + sha256: "1803e76e6653768d64ed8ff2e1e67bea3ad4b923eb5c56a295c3e634bad5960e" + url: "https://pub.dev" + source: hosted + version: "0.12.16" + material_color_utilities: + dependency: transitive + description: + name: material_color_utilities + sha256: "9528f2f296073ff54cb9fee677df673ace1218163c3bc7628093e7eed5203d41" + url: "https://pub.dev" + source: hosted + version: "0.5.0" + meta: + dependency: transitive + description: + name: meta + sha256: a6e590c838b18133bb482a2745ad77c5bb7715fb0451209e1a7567d416678b8e + url: "https://pub.dev" + source: hosted + version: "1.10.0" + nested: + dependency: transitive + description: + name: nested + sha256: "03bac4c528c64c95c722ec99280375a6f2fc708eec17c7b3f07253b626cd2a20" + url: "https://pub.dev" + source: hosted + version: "1.0.0" + openapi_generator_annotations: + dependency: transitive + description: + name: openapi_generator_annotations + sha256: "46f1fb675029d78e19ce9143e70ce414d738b0f6c45c49c004b4b3afdb405a5c" + url: "https://pub.dev" + source: hosted + version: "4.13.1" + passkeys: + dependency: transitive + description: + name: passkeys + sha256: "59e50b21746aff90cbc56145174caa3b99523f449e42f7d8aa2199ec09c511cd" + url: "https://pub.dev" + source: hosted + version: "2.0.8" + passkeys_android: + dependency: transitive + description: + name: passkeys_android + sha256: "9dc0b84dad03329ff2f3be18bedecf1b8de9309c8e9cda6ef821dc88556a126d" + url: "https://pub.dev" + source: hosted + version: "2.0.4" + passkeys_ios: + dependency: transitive + description: + name: passkeys_ios + sha256: "411b10c3cd159c9601426d47b2dc5aa4dd1e34ef69deefaac01ff81712ea6064" + url: "https://pub.dev" + source: hosted + version: "2.0.3" + passkeys_platform_interface: + dependency: transitive + description: + name: passkeys_platform_interface + sha256: a1f1f5c637049f68350cf43323df9689be2e86fe5822a6e098362e7f6168351e + url: "https://pub.dev" + source: hosted + version: "2.0.1" + passkeys_web: + dependency: transitive + description: + name: passkeys_web + sha256: "1c7815020332b9be1af4df67686826a91b6dd29fea53be947d6082654abd6280" + url: "https://pub.dev" + source: hosted + version: "2.0.1" + path: + dependency: transitive + description: + name: path + sha256: "8829d8a55c13fc0e37127c29fedf290c102f4e40ae94ada574091fe0ff96c917" + url: "https://pub.dev" + source: hosted + version: "1.8.3" + path_provider: + dependency: "direct main" + description: + name: path_provider + sha256: b27217933eeeba8ff24845c34003b003b2b22151de3c908d0e679e8fe1aa078b + url: "https://pub.dev" + source: hosted + version: "2.1.2" + path_provider_android: + dependency: transitive + description: + name: path_provider_android + sha256: "477184d672607c0a3bf68fbbf601805f92ef79c82b64b4d6eb318cbca4c48668" + url: "https://pub.dev" + source: hosted + version: "2.2.2" + path_provider_foundation: + dependency: transitive + description: + name: path_provider_foundation + sha256: "5a7999be66e000916500be4f15a3633ebceb8302719b47b9cc49ce924125350f" + url: "https://pub.dev" + source: hosted + version: "2.3.2" + path_provider_linux: + dependency: transitive + description: + name: path_provider_linux + sha256: f7a1fe3a634fe7734c8d3f2766ad746ae2a2884abe22e241a8b301bf5cac3279 + url: "https://pub.dev" + source: hosted + version: "2.2.1" + path_provider_platform_interface: + dependency: transitive + description: + name: path_provider_platform_interface + sha256: "88f5779f72ba699763fa3a3b06aa4bf6de76c8e5de842cf6f29e2e06476c2334" + url: "https://pub.dev" + source: hosted + version: "2.1.2" + path_provider_windows: + dependency: transitive + description: + name: path_provider_windows + sha256: "8bc9f22eee8690981c22aa7fc602f5c85b497a6fb2ceb35ee5a5e5ed85ad8170" + url: "https://pub.dev" + source: hosted + version: "2.2.1" + petitparser: + dependency: transitive + description: + name: petitparser + sha256: c15605cd28af66339f8eb6fbe0e541bfe2d1b72d5825efc6598f3e0a31b9ad27 + url: "https://pub.dev" + source: hosted + version: "6.0.2" + platform: + dependency: transitive + description: + name: platform + sha256: "12220bb4b65720483f8fa9450b4332347737cf8213dd2840d8b2c823e47243ec" + url: "https://pub.dev" + source: hosted + version: "3.1.4" + plugin_platform_interface: + dependency: transitive + description: + name: plugin_platform_interface + sha256: "4820fbfdb9478b1ebae27888254d445073732dae3d6ea81f0b7e06d5dedc3f02" + url: "https://pub.dev" + source: hosted + version: "2.1.8" + pointycastle: + dependency: transitive + description: + name: pointycastle + sha256: "43ac87de6e10afabc85c445745a7b799e04de84cebaa4fd7bf55a5e1e9604d29" + url: "https://pub.dev" + source: hosted + version: "3.7.4" + provider: + dependency: "direct main" + description: + name: provider + sha256: c8a055ee5ce3fd98d6fc872478b03823ffdb448699c6ebdbbc71d59b596fd48c + url: "https://pub.dev" + source: hosted + version: "6.1.2" + qr: + dependency: transitive + description: + name: qr + sha256: "64957a3930367bf97cc211a5af99551d630f2f4625e38af10edd6b19131b64b3" + url: "https://pub.dev" + source: hosted + version: "3.0.1" + qr_flutter: + dependency: "direct main" + description: + name: qr_flutter + sha256: "5095f0fc6e3f71d08adef8feccc8cea4f12eec18a2e31c2e8d82cb6019f4b097" + url: "https://pub.dev" + source: hosted + version: "4.1.0" + sec: + dependency: transitive + description: + name: sec + sha256: "8bbd56df884502192a441b5f5d667265498f2f8728a282beccd9db79e215f379" + url: "https://pub.dev" + source: hosted + version: "1.1.0" + shared_preferences: + dependency: "direct main" + description: + name: shared_preferences + sha256: "81429e4481e1ccfb51ede496e916348668fd0921627779233bd24cc3ff6abd02" + url: "https://pub.dev" + source: hosted + version: "2.2.2" + shared_preferences_android: + dependency: transitive + description: + name: shared_preferences_android + sha256: "8568a389334b6e83415b6aae55378e158fbc2314e074983362d20c562780fb06" + url: "https://pub.dev" + source: hosted + version: "2.2.1" + shared_preferences_foundation: + dependency: transitive + description: + name: shared_preferences_foundation + sha256: "7708d83064f38060c7b39db12aefe449cb8cdc031d6062280087bc4cdb988f5c" + url: "https://pub.dev" + source: hosted + version: "2.3.5" + shared_preferences_linux: + dependency: transitive + description: + name: shared_preferences_linux + sha256: "9f2cbcf46d4270ea8be39fa156d86379077c8a5228d9dfdb1164ae0bb93f1faa" + url: "https://pub.dev" + source: hosted + version: "2.3.2" + shared_preferences_platform_interface: + dependency: transitive + description: + name: shared_preferences_platform_interface + sha256: "22e2ecac9419b4246d7c22bfbbda589e3acf5c0351137d87dd2939d984d37c3b" + url: "https://pub.dev" + source: hosted + version: "2.3.2" + shared_preferences_web: + dependency: transitive + description: + name: shared_preferences_web + sha256: "7b15ffb9387ea3e237bb7a66b8a23d2147663d391cafc5c8f37b2e7b4bde5d21" + url: "https://pub.dev" + source: hosted + version: "2.2.2" + shared_preferences_windows: + dependency: transitive + description: + name: shared_preferences_windows + sha256: "841ad54f3c8381c480d0c9b508b89a34036f512482c407e6df7a9c4aa2ef8f59" + url: "https://pub.dev" + source: hosted + version: "2.3.2" + sky_engine: + dependency: transitive + description: flutter + source: sdk + version: "0.0.99" + source_span: + dependency: transitive + description: + name: source_span + sha256: "53e943d4206a5e30df338fd4c6e7a077e02254531b138a15aec3bd143c1a8b3c" + url: "https://pub.dev" + source: hosted + version: "1.10.0" + sprintf: + dependency: transitive + description: + name: sprintf + sha256: "1fc9ffe69d4df602376b52949af107d8f5703b77cda567c4d7d86a0693120f23" + url: "https://pub.dev" + source: hosted + version: "7.0.0" + stack_trace: + dependency: transitive + description: + name: stack_trace + sha256: "73713990125a6d93122541237550ee3352a2d84baad52d375a4cad2eb9b7ce0b" + url: "https://pub.dev" + source: hosted + version: "1.11.1" + stream_channel: + dependency: "direct overridden" + description: + name: stream_channel + sha256: ba2aa5d8cc609d96bbb2899c28934f9e1af5cddbd60a827822ea467161eb54e7 + url: "https://pub.dev" + source: hosted + version: "2.1.2" + stream_transform: + dependency: transitive + description: + name: stream_transform + sha256: "14a00e794c7c11aa145a170587321aedce29769c08d7f58b1d141da75e3b1c6f" + url: "https://pub.dev" + source: hosted + version: "2.1.0" + string_scanner: + dependency: transitive + description: + name: string_scanner + sha256: "556692adab6cfa87322a115640c11f13cb77b3f076ddcc5d6ae3c20242bedcde" + url: "https://pub.dev" + source: hosted + version: "1.2.0" + term_glyph: + dependency: transitive + description: + name: term_glyph + sha256: a29248a84fbb7c79282b40b8c72a1209db169a2e0542bce341da992fe1bc7e84 + url: "https://pub.dev" + source: hosted + version: "1.2.1" + test_api: + dependency: transitive + description: + name: test_api + sha256: "5c2f730018264d276c20e4f1503fd1308dfbbae39ec8ee63c5236311ac06954b" + url: "https://pub.dev" + source: hosted + version: "0.6.1" + typed_data: + dependency: transitive + description: + name: typed_data + sha256: facc8d6582f16042dd49f2463ff1bd6e2c9ef9f3d5da3d9b087e244a7b564b3c + url: "https://pub.dev" + source: hosted + version: "1.3.2" + ua_client_hints: + dependency: transitive + description: + name: ua_client_hints + sha256: "8401d7bec261f61b3d3b61cd877653ddf840de2d9e07bd164f34588572aa0c8b" + url: "https://pub.dev" + source: hosted + version: "1.2.2" + universal_io: + dependency: transitive + description: + name: universal_io + sha256: "1722b2dcc462b4b2f3ee7d188dad008b6eb4c40bbd03a3de451d82c78bba9aad" + url: "https://pub.dev" + source: hosted + version: "2.2.2" + uuid: + dependency: transitive + description: + name: uuid + sha256: cd210a09f7c18cbe5a02511718e0334de6559871052c90a90c0cca46a4aa81c8 + url: "https://pub.dev" + source: hosted + version: "4.3.3" + variance_dart: + dependency: "direct main" + description: + path: ".." + relative: true + source: path + version: "0.1.0" + vector_math: + dependency: transitive + description: + name: vector_math + sha256: "80b3257d1492ce4d091729e3a67a60407d227c27241d6927be0130c98e741803" + url: "https://pub.dev" + source: hosted + version: "2.1.4" + wallet: + dependency: transitive + description: + name: wallet + sha256: "687fd89a16557649b26189e597792962f405797fc64113e8758eabc2c2605c32" + url: "https://pub.dev" + source: hosted + version: "0.0.13" + web: + dependency: transitive + description: + name: web + sha256: afe077240a270dcfd2aafe77602b4113645af95d0ad31128cc02bce5ac5d5152 + url: "https://pub.dev" + source: hosted + version: "0.3.0" + web3_signers: + dependency: "direct main" + description: + name: web3_signers + sha256: fd2a4ee394537f2140c08a395eadd8611aa713e04699c29b6aaba75e11264faf + url: "https://pub.dev" + source: hosted + version: "0.0.6" + web3dart: + dependency: "direct main" + description: + name: web3dart + sha256: "885e5e8f0cc3c87c09f160a7fce6279226ca41316806f7ece2001959c62ecced" + url: "https://pub.dev" + source: hosted + version: "2.7.3" + win32: + dependency: transitive + description: + name: win32 + sha256: "464f5674532865248444b4c3daca12bd9bf2d7c47f759ce2617986e7229494a8" + url: "https://pub.dev" + source: hosted + version: "5.2.0" + xdg_directories: + dependency: transitive + description: + name: xdg_directories + sha256: faea9dee56b520b55a566385b84f2e8de55e7496104adada9962e0bd11bcff1d + url: "https://pub.dev" + source: hosted + version: "1.0.4" + xml: + dependency: transitive + description: + name: xml + sha256: b015a8ad1c488f66851d762d3090a21c600e479dc75e68328c52774040cf9226 + url: "https://pub.dev" + source: hosted + version: "6.5.0" + yaml: + dependency: transitive + description: + name: yaml + sha256: "75769501ea3489fca56601ff33454fe45507ea3bfb014161abc3b43ae25989d5" + url: "https://pub.dev" + source: hosted + version: "3.1.2" +sdks: + dart: ">=3.2.6 <4.0.0" + flutter: ">=3.16.9" diff --git a/example/pubspec.yaml b/example/pubspec.yaml new file mode 100644 index 0000000..03b61bb --- /dev/null +++ b/example/pubspec.yaml @@ -0,0 +1,40 @@ +name: variancedemo +description: A new Flutter project. + +publish_to: "none" +version: 1.0.0+1 + +environment: + sdk: ">=3.1.5 <4.0.0" + +dependencies: + flutter: + sdk: flutter + cupertino_icons: ^1.0.2 + flutter_launcher_icons: ^0.13.1 + flutter_native_splash: ^2.3.7 + provider: ^6.1.1 + google_fonts: 6.1.0 + flutter_screenutil: ^5.9.0 + qr_flutter: ^4.1.0 + web3dart: ^2.7.2 + shared_preferences: ^2.2.2 + path_provider: ^2.1.1 + fluttertoast: ^8.2.4 + variance_dart: + path: ../ + web3_signers: ^0.0.6 + +dev_dependencies: + flutter_test: + sdk: flutter + + flutter_lints: ^2.0.0 + +flutter: + uses-material-design: true + assets: + - assets/images/ + +dependency_overrides: + stream_channel: ^2.1.2 diff --git a/example/pubspec.yml b/example/pubspec.yml deleted file mode 100644 index b1879ff..0000000 --- a/example/pubspec.yml +++ /dev/null @@ -1,16 +0,0 @@ -name: example -publish_to: none -version: 0.0.1 -homepage: https://variance.space -repository: https://github.com/vaariance/variance-dart - -environment: - sdk: ">=2.12.0 <4.0.0" - -dependencies: - variance_dart: - path: ../ - -dev_dependencies: - coverage: ^1.1.0 - lints: ^2.0.0 diff --git a/example/test/widget_test.dart b/example/test/widget_test.dart new file mode 100644 index 0000000..339fefa --- /dev/null +++ b/example/test/widget_test.dart @@ -0,0 +1,30 @@ +// This is a basic Flutter widget test. +// +// To perform an interaction with a widget in your test, use the WidgetTester +// utility in the flutter_test package. For example, you can send tap and scroll +// gestures. You can also use WidgetTester to find child widgets in the widget +// tree, read text, and verify that the values of widget properties are correct. + +import 'package:flutter/material.dart'; +import 'package:flutter_test/flutter_test.dart'; + +import 'package:variancedemo/main.dart'; + +void main() { + testWidgets('Counter increments smoke test', (WidgetTester tester) async { + // Build our app and trigger a frame. + await tester.pumpWidget(const MyApp()); + + // Verify that our counter starts at 0. + expect(find.text('0'), findsOneWidget); + expect(find.text('1'), findsNothing); + + // Tap the '+' icon and trigger a frame. + await tester.tap(find.byIcon(Icons.add)); + await tester.pump(); + + // Verify that our counter has incremented. + expect(find.text('0'), findsNothing); + expect(find.text('1'), findsOneWidget); + }); +} diff --git a/lib/interfaces.dart b/lib/interfaces.dart deleted file mode 100644 index b804c71..0000000 --- a/lib/interfaces.dart +++ /dev/null @@ -1,4 +0,0 @@ -library interfaces; - -export 'src/interfaces/interfaces.dart' - show MultiSignerInterface, HDInterface, PasskeyInterface; diff --git a/lib/src/4337/chains.dart b/lib/src/4337/chains.dart index d1d3649..4c26a7f 100644 --- a/lib/src/4337/chains.dart +++ b/lib/src/4337/chains.dart @@ -1,162 +1,291 @@ -part of '../../variance.dart'; +part of '../../variance_dart.dart'; +/// Represents an Ethereum-based blockchain chain. class Chain { + /// The unique identifier of the chain. final int chainId; + + /// The URL of the block explorer for this chain. final String explorer; - final EthereumAddress entrypoint; - final EthereumAddress accountFactory; - String? ethRpcUrl; + + /// The address of the EntryPoint contract on this chain. + final EntryPointAddress entrypoint; + + /// The address of the AccountFactory contract on this chain. + EthereumAddress? accountFactory; + + /// The URL of the JSON-RPC endpoint for this chain. + String? jsonRpcUrl; + + /// The URL of the bundler service for this chain. String? bundlerUrl; + /// The URL of the paymaster service for this chain. + /// + /// This is an optional parameter and can be left null if the paymaster URL + /// is not known or needed. + String? paymasterUrl; + + /// Creates a new instance of the [Chain] class. + /// + /// [chainId] is the unique identifier of the chain. + /// [explorer] is the URL of the block explorer for this chain. + /// [entrypoint] is the address of the EntryPoint contract on this chain. + /// [accountFactory] is the address of the AccountFactory contract on this + /// chain. + /// [jsonRpcUrl] is the URL of the JSON-RPC endpoint for this chain. + /// [bundlerUrl] is the URL of the bundler service for this chain. + /// [paymasterUrl] is the optional URL of the paymaster service for this + /// chain. + /// + /// Example: + /// + /// ```dart + /// final chain = Chain( + /// chainId: 1, + /// explorer: 'https://etherscan.io', + /// entrypoint: EntryPointAddress('0x...'), + /// accountFactory: EthereumAddress('0x...'), + /// jsonRpcUrl: 'https://mainnet.infura.io/v3/...', + /// bundlerUrl: 'https://bundler.example.com', + /// paymasterUrl: 'https://paymaster.example.com', + /// ); + /// ``` + Chain( {required this.chainId, required this.explorer, - this.ethRpcUrl, - this.bundlerUrl, required this.entrypoint, - required this.accountFactory}); - - /// asserts that [ethRpcUrl] and [bundlerUrl] is provided - Chain validate() { - require(isURL(ethRpcUrl), "Chain: please provide a valid eth rpc url"); - require(isURL(bundlerUrl), "Chain: please provide a valid bundler url"); - return this; - } + this.accountFactory, + this.jsonRpcUrl, + this.bundlerUrl, + this.paymasterUrl}); } //predefined Chains you can use class Chains { static Map chains = { - // Ethereum Mainnet - Network.mainnet: Chain( - chainId: 1, - explorer: "https://etherscan.io/", - ethRpcUrl: "https://rpc.ankr.com/eth", - entrypoint: Constants.entrypoint, - accountFactory: Constants.accountFactory), - // Optimism Mainnet + Network.ethereum: Chain( + chainId: 1, + explorer: "https://etherscan.io/", + jsonRpcUrl: "https://rpc.ankr.com/eth", + entrypoint: EntryPointAddress.v06, + ), + Network.polygon: Chain( + chainId: 137, + explorer: "https://polygonscan.com/", + jsonRpcUrl: "https://rpc.ankr.com/polygon", + entrypoint: EntryPointAddress.v06, + ), Network.optimism: Chain( - chainId: 10, - explorer: "https://explorer.optimism.io", - ethRpcUrl: "https://mainnet.optimism.io", - entrypoint: Constants.entrypoint, - accountFactory: Constants.accountFactory), - // Base Mainnet + chainId: 10, + explorer: "https://explorer.optimism.io", + jsonRpcUrl: "https://rpc.ankr.com/optimism", + entrypoint: EntryPointAddress.v06, + ), Network.base: Chain( - chainId: 8453, - explorer: "https://basescan.org", - ethRpcUrl: "https://mainnet.base.org", - entrypoint: Constants.entrypoint, - accountFactory: Constants.accountFactory), - // Arbitrum (one) Mainnet - Network.arbitrum: Chain( - chainId: 42161, - explorer: "https://arbiscan.io/", - ethRpcUrl: "https://arb1.arbitrum.io/rpc", - entrypoint: Constants.entrypoint, - accountFactory: Constants.accountFactory), - // Polygon Mainnet - Network.polygon: Chain( - chainId: 137, - explorer: "https://polygonscan.com/", - ethRpcUrl: "https://polygon-rpc.com/", - entrypoint: Constants.entrypoint, - accountFactory: Constants.accountFactory), - // Mantle Mainnet - Network.mantle: Chain( - chainId: 5000, - explorer: "https://explorer.mantle.xyz/", - ethRpcUrl: "https://rpc.mantle.xyz/", - entrypoint: Constants.entrypoint, - accountFactory: Constants.accountFactory), - // Sepolia Testnet + chainId: 8453, + explorer: "https://basescan.org", + jsonRpcUrl: "https://rpc.ankr.com/base", + entrypoint: EntryPointAddress.v06, + ), + Network.arbitrumOne: Chain( + chainId: 42161, + explorer: "https://arbiscan.io/", + jsonRpcUrl: "https://rpc.ankr.com/arbitrum", + entrypoint: EntryPointAddress.v06, + ), + Network.linea: Chain( + chainId: 59144, + explorer: "https://lineascan.build/", + jsonRpcUrl: "https://rpc.linea.build", + entrypoint: EntryPointAddress.v06), + Network.opBnB: Chain( + chainId: 204, + explorer: "http://opbnbscan.com/", + jsonRpcUrl: "https://opbnb-mainnet-rpc.bnbchain.org", + entrypoint: EntryPointAddress.v06, + ), + Network.scroll: Chain( + chainId: 534352, + explorer: "https://scrollscan.com/", + jsonRpcUrl: "https://rpc.ankr.com/scroll", + entrypoint: EntryPointAddress.v06, + ), Network.sepolia: Chain( - chainId: 11155111, - explorer: "https://sepolia.etherscan.io/", - ethRpcUrl: "https://rpc.sepolia.org", - entrypoint: Constants.entrypoint, - accountFactory: Constants.accountFactory), - // Optimism Goerli Testnet - Network.opGoerli: Chain( - chainId: 420, - explorer: "https://goerli-explorer.optimism.io", - ethRpcUrl: "https://goerli.optimism.io", - entrypoint: Constants.entrypoint, - accountFactory: Constants.accountFactory), - // Base Goerli testnet - Network.baseGoerli: Chain( - chainId: 84531, - explorer: "https://goerli.basescan.org", - ethRpcUrl: "https://goerli.base.org", - entrypoint: Constants.entrypoint, - accountFactory: Constants.accountFactory), - // Mumbai Testnet + chainId: 11155111, + explorer: "https://sepolia.etherscan.io/", + jsonRpcUrl: "https://rpc.ankr.com/eth_sepolia", + entrypoint: EntryPointAddress.v06, + ), Network.mumbai: Chain( - chainId: 80001, - explorer: "https://mumbai.polygonscan.com/", - ethRpcUrl: "https://rpc-mumbai.maticvigil.com/", - entrypoint: Constants.entrypoint, - accountFactory: Constants.accountFactory), - // Mantle Testnet - Network.mantleTestnet: Chain( - chainId: 50001, - explorer: "https://explorer.testnet.mantle.xyz/", - ethRpcUrl: "https://rpc.testnet.mantle.xyz/", - entrypoint: Constants.entrypoint, - accountFactory: Constants.accountFactory), - // Scroll Sepolia Testnet - Network.scrollSepolia: Chain( - chainId: 534351, - explorer: "https://sepolia-blockscout.scroll.io/", - ethRpcUrl: "https://sepolia-rpc.scroll.io/", - entrypoint: Constants.entrypoint, - accountFactory: Constants.accountFactory), - // Localhost + chainId: 80001, + explorer: "https://mumbai.polygonscan.com/", + jsonRpcUrl: "https://rpc.ankr.com/polygon_mumbai", + entrypoint: EntryPointAddress.v06, + ), + Network.baseTestnet: Chain( + chainId: 84532, + explorer: "https://sepolia.basescan.org/", + jsonRpcUrl: "https://rpc.ankr.com/base_sepolia", + entrypoint: EntryPointAddress.v06, + ), Network.localhost: Chain( - chainId: 1337, - explorer: "http://localhost:8545", - ethRpcUrl: "http://localhost:8545", - bundlerUrl: "http://localhost:3000/rpc", - entrypoint: Constants.entrypoint, - accountFactory: Constants.accountFactory) + chainId: 1337, + explorer: "http://localhost:8545", + jsonRpcUrl: "http://localhost:8545", + bundlerUrl: "http://localhost:3000/rpc", + entrypoint: EntryPointAddress.v06, + ) }; const Chains._(); + /// Returns the [Chain] instance for the given [Network]. + /// + /// [network] is the target network for which the [Chain] instance is required. + /// + /// This method retrieves the [Chain] instance from a predefined map of + /// networks and their corresponding chain configurations. + /// + /// Example: + /// + /// ```dart + /// final mainnetChain = Chain.getChain(Network.ethereum); + /// final sepoliaChain = Chain.getChain(Network.sepolia); + /// ``` static Chain getChain(Network network) { return chains[network]!; } } class Constants { - static EthereumAddress entrypoint = EthereumAddress.fromHex( - "0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789", - enforceEip55: true); + static EthereumAddress entrypointv06 = + EthereumAddress.fromHex("0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789"); + static EthereumAddress entrypointv07 = + EthereumAddress.fromHex("0x0000000071727De22E5E9d8BAf0edAc6f37da032"); static EthereumAddress zeroAddress = EthereumAddress.fromHex("0x0000000000000000000000000000000000000000"); - static EthereumAddress accountFactory = EthereumAddress.fromHex( - "0xCCaE5F64307D86346B83E55e7865f77906F9c7b4", - enforceEip55: true); + static final EthereumAddress simpleAccountFactoryAddressv06 = + EthereumAddress.fromHex("0x9406Cc6185a346906296840746125a0E44976454"); + static final EthereumAddress simpleAccountFactoryAddressv07 = + EthereumAddress.fromHex("0x91E60e0613810449d098b0b5Ec8b51A0FE8c8985"); + static final EthereumAddress safeProxyFactoryAddress = + EthereumAddress.fromHex("0x4e1DCf7AD4e460CfD30791CCC4F9c8a4f820ec67"); + static final EthereumAddress safe4337ModuleAddressv06 = + EthereumAddress.fromHex("0xa581c4A4DB7175302464fF3C06380BC3270b4037"); + static final EthereumAddress safe4337ModuleAddressv07 = + EthereumAddress.fromHex("0x75cf11467937ce3F2f357CE24ffc3DBF8fD5c226"); + static final EthereumAddress safeSingletonAddress = + EthereumAddress.fromHex("0x41675C099F32341bf84BFc5382aF534df5C7461a"); + static final EthereumAddress safeModuleSetupAddressv06 = + EthereumAddress.fromHex("0x8EcD4ec46D4D2a6B64fE960B3D64e8B94B2234eb"); + static final EthereumAddress safeModuleSetupAddressv07 = + EthereumAddress.fromHex("0x2dd68b007B46fBe91B9A7c3EDa5A7a1063cB5b47"); + static final EthereumAddress safeMultiSendaddress = + EthereumAddress.fromHex("0x38869bf66a61cF6bDB996A6aE40D5853Fd43B526"); + Constants._(); } enum Network { // mainnet - mainnet, + ethereum, + polygon, optimism, base, - arbitrum, - polygon, - mantle, + arbitrumOne, + linea, + opBnB, + scroll, // testnet sepolia, - opGoerli, - baseGoerli, mumbai, - mantleTestnet, - scrollSepolia, + baseTestnet, // localhost localhost } + +/// Represents the address of an EntryPoint contract on the Ethereum blockchain. +class EntryPointAddress { + /// Returns the EntryPoint address for version 0.6 of the EntryPoint contract. + static EntryPointAddress get v06 => EntryPointAddress( + 0.6, + Constants.entrypointv06, + ); + + /// Returns the EntryPoint address for version 0.7 of the EntryPoint contract. + static EntryPointAddress get v07 => EntryPointAddress( + 0.7, + Constants.entrypointv07, + ); + + /// The version of the EntryPoint contract. + final double version; + + /// The Ethereum address of the EntryPoint contract. + final EthereumAddress address; + + /// Creates a new instance of the [EntryPointAddress] class. + /// + /// [version] is the version of the EntryPoint contract. + /// [address] is the Ethereum address of the EntryPoint contract. + const EntryPointAddress(this.version, this.address); +} + +/// Represents the address of the Safe4337Module contract on the Ethereum blockchain. +class Safe4337ModuleAddress { + /// The address of the Safe4337Module contract for version 0.6. + static Safe4337ModuleAddress v06 = Safe4337ModuleAddress( + 0.6, + Constants.safe4337ModuleAddressv06, + Constants.safeModuleSetupAddressv06, + ); + + /// The address of the Safe4337Module contract for version 0.7. + static Safe4337ModuleAddress v07 = Safe4337ModuleAddress( + 0.7, + Constants.safe4337ModuleAddressv07, + Constants.safeModuleSetupAddressv07, + ); + + /// The version of the Safe4337Module contract. + final double version; + + /// The Ethereum address of the Safe4337Module contract. + final EthereumAddress address; + + /// The address of the SafeModuleSetup contract. + final EthereumAddress setup; + + /// Creates a new instance of the [Safe4337ModuleAddress] class. + /// + /// [version] is the version of the Safe4337Module contract. + /// [address] is the Ethereum address of the Safe4337Module contract. + /// [setup] is the address of the SafeModuleSetup contract. + const Safe4337ModuleAddress(this.version, this.address, this.setup); + + /// Creates a new instance of the [Safe4337ModuleAddress] class from a given version. + /// + /// [version] is the version of the Safe4337Module contract. + /// + /// If the provided version is not supported, an [Exception] will be thrown. + /// + /// Example: + /// + /// ```dart + /// final moduleAddress = Safe4337ModuleAddress.fromVersion(0.6); + /// ``` + factory Safe4337ModuleAddress.fromVersion(double version) { + switch (version) { + case 0.6: + return Safe4337ModuleAddress.v06; + case 0.7: + return Safe4337ModuleAddress.v07; + default: + throw Exception("Unsupported version: $version"); + } + } +} diff --git a/lib/src/4337/factory.dart b/lib/src/4337/factory.dart new file mode 100644 index 0000000..f17beff --- /dev/null +++ b/lib/src/4337/factory.dart @@ -0,0 +1,249 @@ +part of '../../variance_dart.dart'; + +/// A factory class for creating various types of Ethereum smart wallets. +/// {@inheritDoc SmartWalletFactoryBase} +class SmartWalletFactory implements SmartWalletFactoryBase { + final Chain _chain; + final MSI _signer; + + late final JsonRPCProvider _jsonRpc; + late final BundlerProvider _bundler; + late final Contract _contract; + + /// Creates a new instance of the [SmartWalletFactory] class. + /// + /// [_chain] is the Ethereum chain configuration. + /// [_signer] is the signer instance used for signing transactions. + /// + /// Throws an [InvalidFactoryAddress] exception if the provided chain does not + /// have a valid account factory address. + SmartWalletFactory(this._chain, this._signer) + : assert(_chain.accountFactory != null, + InvalidFactoryAddress(_chain.accountFactory)), + _jsonRpc = JsonRPCProvider(_chain), + _bundler = BundlerProvider(_chain) { + _contract = Contract(_jsonRpc.rpc); + } + + /// A getter for the P256AccountFactory contract instance. + _P256AccountFactory get _p256Accountfactory => _P256AccountFactory( + address: _chain.accountFactory!, + chainId: _chain.chainId, + rpc: _jsonRpc.rpc); + + /// A getter for the SafePlugin instance. + _SafePlugin get _safePlugin => _SafePlugin( + address: + Safe4337ModuleAddress.fromVersion(_chain.entrypoint.version).address, + chainId: _chain.chainId, + client: _safeProxyFactory.client); + + /// A getter for the SafeProxyFactory contract instance. + _SafeProxyFactory get _safeProxyFactory => _SafeProxyFactory( + address: _chain.accountFactory!, + chainId: _chain.chainId, + rpc: _jsonRpc.rpc); + + /// A getter for the SimpleAccountFactory contract instance. + _SimpleAccountFactory get _simpleAccountfactory => _SimpleAccountFactory( + address: _chain.accountFactory!, + chainId: _chain.chainId, + rpc: _jsonRpc.rpc); + + @override + Future createP256Account(T keyPair, Uint256 salt, + [EthereumAddress? recoveryAddress]) { + switch (keyPair.runtimeType) { + case const (PassKeyPair): + return _createPasskeyAccount( + keyPair as PassKeyPair, salt, recoveryAddress); + case const (P256Credential): + return _createSecureEnclaveAccount( + keyPair as P256Credential, salt, recoveryAddress); + default: + throw ArgumentError.value(keyPair, 'keyPair', + 'createP256Account: An instance of `PassKeyPair` or `P256Credential` is expected, but got: ${keyPair.runtimeType}'); + } + } + + @override + Future createSafeAccount(Uint256 salt) async { + final signer = EthereumAddress.fromHex(_signer.getAddress()); + + // Get the initializer data for the Safe account + final initializer = _safeProxyFactory.getInitializer([signer], 1, + Safe4337ModuleAddress.fromVersion(_chain.entrypoint.version)); + + // Get the proxy creation code for the Safe account + final creation = await _safeProxyFactory.proxyCreationCode(); + + // Predict the address of the Safe account + final address = + _safeProxyFactory.getPredictedSafe(initializer, salt, creation); + + // Encode the call data for the `createProxyWithNonce` function + // This function is used to create the Safe account with the given initializer data and salt + final initCallData = _safeProxyFactory.self + .function("createProxyWithNonce") + .encodeCall([Constants.safeSingletonAddress, initializer, salt.value]); + + // Generate the initialization code by combining the account factory address and the encoded call data + final initCode = _getInitCode(initCallData); + + // Create the SmartWallet instance for the Safe account + return _createAccount(_chain, address, initCode) + ..addPlugin<_SafePlugin>('safe', _safePlugin); + } + + @override + Future createSimpleAccount(Uint256 salt, [int? index]) async { + final signer = + EthereumAddress.fromHex(_signer.getAddress(index: index ?? 0)); + + // Get the predicted address of the simple account + final address = await _simpleAccountfactory.getAddress(signer, salt.value); + + // Encode the call data for the `createAccount` function + // This function is used to create the simple account with the given signer address and salt + final initCalldata = _simpleAccountfactory.self + .function('createAccount') + .encodeCall([signer, salt.value]); + + // Generate the initialization code by combining the account factory address and the encoded call data + final initCode = _getInitCode(initCalldata); + + // Create the SmartWallet instance for the simple account + return _createAccount(_chain, address, initCode); + } + + @override + Future createVendorAccount( + EthereumAddress address, + Uint8List initCode, + ) async { + return _createAccount(_chain, address, initCode); + } + + /// Creates a new [SmartWallet] instance with the provided chain, address, and initialization code. + /// + /// [chain] is the Ethereum chain configuration. + /// [address] is the Ethereum address of the account. + /// [initCalldata] is the initialization code for the account. + /// + /// The [SmartWallet] instance is created with various plugins added to it, including: + /// - [MSI] signer plugin + /// - [BundlerProviderBase] bundler plugin + /// - [JsonRPCProviderBase] JSON-RPC provider plugin + /// - [Contract] contract plugin + /// + /// Returns a [SmartWallet] instance representing the created account. + SmartWallet _createAccount( + Chain chain, EthereumAddress address, Uint8List initCalldata) { + final wallet = SmartWallet(chain, address, initCalldata) + ..addPlugin('signer', _signer) + ..addPlugin('bundler', _bundler) + ..addPlugin('jsonRpc', _jsonRpc) + ..addPlugin('contract', _contract); + + if (chain.paymasterUrl != null) { + wallet.addPlugin('paymaster', Paymaster(chain)); + } + + return wallet; + } + + /// Creates a new passkey account with the provided [PassKeyPair], salt, and optional recovery address. + /// + /// [pkp] is the [PassKeyPair] instance used to create the account. + /// [salt] is the salt value used in the account creation process. + /// [recoveryAddress] is an optional recovery address for the account. + /// + /// Returns a [Future] that resolves to a [SmartWallet] instance representing + /// the created passkey account. + /// + /// The process involves: + /// 1. Encoding the account creation data with the provided [PassKeyPair], [salt], and [recoveryAddress]. + /// - The encoded data includes the recovery address, credential hex, and public key components. + /// 2. Calling the `createP256Account` function on the `_p256AccountFactory` contract with the encoded data and [salt]. + /// - This function initiates the account creation process on the Ethereum blockchain. + /// 3. Getting the initialization code by combining the account factory address and the encoded call data. + /// - The initialization code is required to create the account on the client-side. + /// 4. Predicting the account address using the `_p256AccountFactory` contract's `getP256AccountAddress` function. + /// - This function predicts the address of the account based on the creation data and salt. + /// 5. Creating a new [SmartWallet] instance with the predicted address and initialization code. + Future _createPasskeyAccount(PassKeyPair pkp, Uint256 salt, + [EthereumAddress? recoveryAddress]) async { + final Uint8List creation = abi.encode([ + 'address', + 'bytes32', + 'uint256', + 'uint256' + ], [ + recoveryAddress ?? Constants.zeroAddress, + hexToBytes(pkp.credentialHex), + pkp.publicKey.item1.value, + pkp.publicKey.item2.value, + ]); + + final initCalldata = _p256Accountfactory.self + .function('createP256Account') + .encodeCall([salt.value, creation]); + final initCode = _getInitCode(initCalldata); + final address = + await _p256Accountfactory.getP256AccountAddress(salt.value, creation); + return _createAccount(_chain, address, initCode); + } + + /// Creates a new secure enclave account with the provided [P256Credential], salt, and optional recovery address. + /// + /// [p256] is the [P256Credential] instance used to create the account. + /// [salt] is the salt value used in the account creation process. + /// [recoveryAddress] is an optional recovery address for the account. + /// + /// Returns a [Future] that resolves to a [SmartWallet] instance representing + /// the created secure enclave account. + /// + /// The process is similar to [_createPasskeyAccount] but with a different encoding for the account creation data. + /// 1. Encoding the account creation data with the provided [P256Credential], [salt], and [recoveryAddress]. + /// - The encoded data includes the recovery address, an empty bytes32 value, and the public key components. + /// 2. Calling the `createP256Account` function on the `_p256AccountFactory` contract with the encoded data and [salt]. + /// 3. Getting the initialization code by combining the account factory address and the encoded call data. + /// 4. Predicting the account address using the `_p256AccountFactory` contract's `getP256AccountAddress` function. + /// 5. Creating a new [SmartWallet] instance with the predicted address and initialization code. + Future _createSecureEnclaveAccount( + P256Credential p256, Uint256 salt, + [EthereumAddress? recoveryAddress]) async { + final Uint8List creation = abi.encode([ + 'address', + 'bytes32', + 'uint256', + 'uint256' + ], [ + recoveryAddress ?? Constants.zeroAddress, + Uint8List(32), + p256.publicKey.item1.value, + p256.publicKey.item2.value, + ]); + + final initCalldata = _p256Accountfactory.self + .function('createP256Account') + .encodeCall([salt.value, creation]); + final initCode = _getInitCode(initCalldata); + final address = + await _p256Accountfactory.getP256AccountAddress(salt.value, creation); + return _createAccount(_chain, address, initCode); + } + + /// Returns the initialization code for the account by concatenating the account factory address with the provided initialization call data. + /// + /// [initCalldata] is the initialization call data for the account. + /// + /// The initialization code is required to create the account on the client-side. It is generated by combining the account factory address and the encoded call data for the account creation function. + /// + /// Returns a [Uint8List] containing the initialization code. + Uint8List _getInitCode(Uint8List initCalldata) { + List extended = _chain.accountFactory!.addressBytes.toList(); + extended.addAll(initCalldata); + return Uint8List.fromList(extended); + } +} diff --git a/lib/src/4337/paymaster.dart b/lib/src/4337/paymaster.dart index bbf17e6..38915db 100644 --- a/lib/src/4337/paymaster.dart +++ b/lib/src/4337/paymaster.dart @@ -1,5 +1,114 @@ -part of '../../variance.dart'; +part of '../../variance_dart.dart'; -abstract class PaymasterBase {} +/// Represents a Paymaster contract for sponsoring user operations. +class Paymaster implements PaymasterBase { + final RPCBase _rpc; + final Chain _chain; -class Paymaster {} + /// The address of the Paymaster contract. + /// + /// This is an optional parameter and can be left null if the paymaster address + /// is not known or needed. + EthereumAddress? _paymasterAddress; + + /// The context data for the Paymaster. + /// + /// This is an optional parameter and can be used to provide additional context + /// information to the Paymaster when sponsoring user operations. + Map? _context; + + /// Creates a new instance of the [Paymaster] class. + /// + /// [_chain] is the Ethereum chain configuration. + /// [_paymasterAddress] is an optional address of the Paymaster contract. + /// [_context] is an optional map containing the context data for the Paymaster. + /// + /// Throws an [InvalidPaymasterUrl] exception if the paymaster URL in the + /// provided chain configuration is not a valid URL. + Paymaster(this._chain, [this._paymasterAddress, this._context]) + : assert(_chain.paymasterUrl.isURL(), + InvalidPaymasterUrl(_chain.paymasterUrl)), + _rpc = RPCBase(_chain.paymasterUrl!); + + @override + set context(Map? context) { + _context = context; + } + + @override + set paymasterAddress(EthereumAddress? address) { + _paymasterAddress = address; + } + + @override + Future intercept(UserOperation op) async { + if (_paymasterAddress != null) { + op.paymasterAndData = Uint8List.fromList([ + ..._paymasterAddress!.addressBytes, + ...op.paymasterAndData.sublist(20) + ]); + } + final paymasterResponse = await sponsorUserOperation( + op.toMap(_chain.entrypoint.version), _chain.entrypoint, _context); + + // Create a new UserOperation with the updated Paymaster data and gas limits + return op.copyWith( + paymasterAndData: paymasterResponse.paymasterAndData, + preVerificationGas: paymasterResponse.preVerificationGas, + verificationGasLimit: paymasterResponse.verificationGasLimit, + callGasLimit: paymasterResponse.callGasLimit, + ); + } + + @override + Future sponsorUserOperation(Map userOp, + EntryPointAddress entrypoint, Map? context) async { + final request = [userOp, entrypoint.address.hex]; + if (context != null) { + request.add(context); + } + final response = await _rpc.send>( + 'pm_sponsorUserOperation', request); + + // Parse the response into a PaymasterResponse object + return PaymasterResponse.fromMap(response); + } +} + +class PaymasterResponse { + final Uint8List paymasterAndData; + final BigInt preVerificationGas; + final BigInt verificationGasLimit; + final BigInt callGasLimit; + + PaymasterResponse({ + required this.paymasterAndData, + required this.preVerificationGas, + required this.verificationGasLimit, + required this.callGasLimit, + }); + + factory PaymasterResponse.fromMap(Map map) { + final List accountGasLimits = map['accountGasLimits'] != null + ? unpackUints(map['accountGasLimits']) + : [ + BigInt.parse(map['verificationGasLimit']), + BigInt.parse(map['callGasLimit']) + ]; + + final paymasterAndData = map['paymasterAndData'] != null + ? hexToBytes(map['paymasterAndData']) + : Uint8List.fromList([ + ...EthereumAddress.fromHex(map['paymaster']).addressBytes, + ...packUints(BigInt.parse(map['paymasterVerificationGasLimit']), + BigInt.parse(map['paymasterPostOpGasLimit'])), + ...hexToBytes(map["paymasterData"]) + ]); + + return PaymasterResponse( + paymasterAndData: paymasterAndData, + preVerificationGas: BigInt.parse(map['preVerificationGas']), + verificationGasLimit: accountGasLimits[0], + callGasLimit: accountGasLimits[1]); + } +} diff --git a/lib/src/4337/providers.dart b/lib/src/4337/providers.dart index fa8e9bc..29b1153 100644 --- a/lib/src/4337/providers.dart +++ b/lib/src/4337/providers.dart @@ -1,155 +1,124 @@ -part of '../../variance.dart'; +part of '../../variance_dart.dart'; +/// A class that implements the `BundlerProviderBase` interface and provides methods +/// for interacting with a bundler for sending and tracking user operations on +/// an Ethereum-like blockchain. class BundlerProvider implements BundlerProviderBase { - /// Set of Ethereum RPC methods supported by the SmartWallet SDK. - static final Set methods = { - 'eth_chainId', - 'eth_sendUserOperation', - 'eth_estimateUserOperationGas', - 'eth_getUserOperationByHash', - 'eth_getUserOperationReceipt', - 'eth_supportedEntryPoints', - }; - - final int _chainId; - final String _bundlerUrl; - final RPCProviderBase _bundlerRpc; + /// The remote procedure call (RPC) client used to communicate with the bundler. + final RPCBase rpc; + /// A flag indicating whether the initialization process was successful. late final bool _initialized; - Entrypoint? entrypoint; - - BundlerProvider(Chain chain, RPCProviderBase bundlerRpc) - : _chainId = chain.chainId, - _bundlerUrl = chain.bundlerUrl!, - _bundlerRpc = bundlerRpc { - _initializeBundlerProvider(); + /// Creates a new instance of the BundlerProvider class. + /// + /// [chain] is an object representing the blockchain chain configuration. + /// + /// The constructor checks if the bundler URL is a valid URL and initializes + /// the RPC client with the bundler URL. It also sends an RPC request to + /// retrieve the chain ID and verifies that it matches the expected chain ID. + /// If the chain IDs don't match, the _initialized flag is set to false. + BundlerProvider(Chain chain) + : assert(chain.bundlerUrl.isURL(), InvalidBundlerUrl(chain.bundlerUrl)), + rpc = RPCBase(chain.bundlerUrl!) { + rpc + .send('eth_chainId') + .then(BigInt.parse) + .then((value) => value.toInt() == chain.chainId) + .then((value) => _initialized = value); } @override Future estimateUserOperationGas( - Map userOp, EthereumAddress entrypoint) async { - require(_initialized, "estimateUserOpGas: Wallet Provider not initialized"); - final opGas = await _bundlerRpc.send>( - 'eth_estimateUserOperationGas', [userOp, entrypoint.hex]); + Map userOp, EntryPointAddress entrypoint) async { + Logger.conditionalWarning( + !_initialized, "estimateUserOpGas may fail: chainId mismatch"); + final opGas = await rpc.send>( + 'eth_estimateUserOperationGas', [userOp, entrypoint.address.hex]); return UserOperationGas.fromMap(opGas); } @override Future getUserOperationByHash(String userOpHash) async { - require(_initialized, "getUserOpByHash: Wallet Provider not initialized"); - final opExtended = await _bundlerRpc + Logger.conditionalWarning( + !_initialized, "getUserOpByHash may fail: chainId mismatch"); + final opExtended = await rpc .send>('eth_getUserOperationByHash', [userOpHash]); return UserOperationByHash.fromMap(opExtended); } @override - Future getUserOpReceipt(String userOpHash) async { - require(_initialized, "getUserOpReceipt: Wallet Provider not initialized"); - final opReceipt = await _bundlerRpc.send>( + Future getUserOpReceipt(String userOpHash) async { + Logger.conditionalWarning( + !_initialized, "getUserOpReceipt may fail: chainId mismatch"); + final opReceipt = await rpc.send>( 'eth_getUserOperationReceipt', [userOpHash]); return UserOperationReceipt.fromMap(opReceipt); } - @override - void initializeWithEntrypoint(Entrypoint ep) { - entrypoint = ep; - } - @override Future sendUserOperation( - Map userOp, EthereumAddress entrypoint) async { - require(_initialized, "sendUserOp: Wallet Provider not initialized"); - final opHash = await _bundlerRpc - .send('eth_sendUserOperation', [userOp, entrypoint.hex]); - return UserOperationResponse(opHash, wait); + Map userOp, EntryPointAddress entrypoint) async { + Logger.conditionalWarning( + !_initialized, "sendUserOp may fail: chainId mismatch"); + final opHash = await rpc.send( + 'eth_sendUserOperation', [userOp, entrypoint.address.hex]); + return UserOperationResponse(opHash, getUserOpReceipt); } @override Future> supportedEntryPoints() async { final entrypointList = - await _bundlerRpc.send>('eth_supportedEntryPoints'); + await rpc.send>('eth_supportedEntryPoints'); return List.castFrom(entrypointList); } +} - @override - Future wait({int millisecond = 0}) async { - if (millisecond == 0) { - return null; - } - require(entrypoint != null, "Entrypoint required! use Wallet.init"); - final block = await entrypoint!.client.getBlockNumber(); - final end = DateTime.now().millisecondsSinceEpoch + millisecond; - - return await Isolate.run(() async { - while (DateTime.now().millisecondsSinceEpoch < end) { - final filterEvent = await entrypoint!.client - .events( - FilterOptions.events( - contract: entrypoint!.self, - event: entrypoint!.self.event('UserOperationEvent'), - fromBlock: BlockNum.exact(block - 100), - ), - ) - .take(1) - .first; - if (filterEvent.transactionHash != null) { - return filterEvent; - } - await Future.delayed(Duration(milliseconds: millisecond)); - } - return null; - }); - } - - Future _initializeBundlerProvider() async { - final chainId = await _bundlerRpc - .send('eth_chainId') - .then(BigInt.parse) - .then((value) => value.toInt()); - require(chainId == _chainId, - "bundler $_bundlerUrl is on chainId $chainId, but provider is on chainId $_chainId"); - _initialized = true; - } +/// A class that implements the JsonRPCProviderBase interface and provides methods +/// for interacting with an Ethereum-like blockchain via the JSON-RPC protocol. +class JsonRPCProvider implements JsonRPCProviderBase { + /// The remote procedure call (RPC) client used to communicate with the blockchain. + final RPCBase rpc; - /// Validates if the provided method is a supported RPC method. - /// - /// Parameters: - /// - `method`: The Ethereum RPC method to validate. + /// Creates a new instance of the JsonRPCProvider class. /// - /// Throws: - /// - A [Exception] if the method is not a valid supported method. + /// [chain] is an object representing the blockchain chain configuration. /// - /// Example: - /// ```dart - /// validateBundlerMethod('eth_sendUserOperation'); - /// ``` - static validateBundlerMethod(String method) { - require(methods.contains(method), - "validateMethod: method ::'$method':: is not a valid method"); - } -} - -class RPCProvider extends JsonRPC implements RPCProviderBase { - RPCProvider(String url) : super(url, http.Client()); + /// The constructor checks if the JSON-RPC URL is a valid URL and initializes + /// the RPC client with the JSON-RPC URL. + JsonRPCProvider(Chain chain) + : assert(chain.jsonRpcUrl.isURL(), InvalidJsonRpcUrl(chain.jsonRpcUrl)), + rpc = RPCBase(chain.jsonRpcUrl!); @override Future estimateGas(EthereumAddress to, String calldata) { - return _makeRPCCall('eth_estimateGas', [ + return rpc.send('eth_estimateGas', [ {'to': to.hex, 'data': calldata} ]).then(hexToInt); } @override Future getBlockNumber() { - return _makeRPCCall('eth_blockNumber') + return rpc + .send('eth_blockNumber') .then(hexToInt) .then((value) => value.toInt()); } + @override + Future getBlockInformation({ + String blockNumber = 'latest', + bool isContainFullObj = true, + }) { + return rpc.send>( + 'eth_getBlockByNumber', + [blockNumber, isContainFullObj], + ).then((json) => BlockInformation.fromJson(json)); + } + @override Future> getEip1559GasPrice() async { - final fee = await _makeRPCCall("eth_maxPriorityFeePerGas"); + final fee = await rpc.send("eth_maxPriorityFeePerGas"); final tip = Uint256.fromHex(fee); final mul = Uint256(BigInt.from(100 * 13)); final buffer = tip / mul; @@ -177,11 +146,27 @@ class RPCProvider extends JsonRPC implements RPCProviderBase { @override Future getLegacyGasPrice() async { - final data = await _makeRPCCall('eth_gasPrice'); + final data = await rpc.send('eth_gasPrice'); return EtherAmount.fromBigInt(EtherUnit.wei, hexToInt(data)); } +} - @override +class RPCBase extends JsonRPC { + RPCBase(String url) : super(url, http.Client()); + + /// Asynchronously sends an RPC call to the Ethereum node for the specified function and parameters. + /// + /// Parameters: + /// - `function`: The Ethereum RPC function to call. eg: `eth_getBalance` + /// - `params`: Optional parameters for the RPC call. + /// + /// Returns: + /// A [Future] that completes with the result of the RPC call. + /// + /// Example: + /// ```dart + /// var result = await send('eth_getBalance', ['0x9876543210abcdef9876543210abcdef98765432']); + /// ``` Future send(String function, [List? params]) { return _makeRPCCall(function, params); } diff --git a/lib/src/4337/safe.dart b/lib/src/4337/safe.dart new file mode 100644 index 0000000..064214e --- /dev/null +++ b/lib/src/4337/safe.dart @@ -0,0 +1,115 @@ +part of '../../variance_dart.dart'; + +/// A class that extends the Safe4337Module and implements the Safe4337ModuleBase interface. +/// It provides functionality related to Safe accounts and user operations on an Ethereum-like blockchain. +class _SafePlugin extends Safe4337Module implements Safe4337ModuleBase { + /// Creates a new instance of the _SafePlugin class. + /// + /// [address] is the address of the Safe 4337 module. + /// [chainId] is the ID of the blockchain chain. + /// [client] is the client used for interacting with the blockchain. + _SafePlugin({ + required super.address, + super.chainId, + required super.client, + }); + + /// Encodes the signature of a user operation with a validity period. + /// + /// [signature] is the signature of the user operation. + /// [blockInfo] is the current blockInformation including the timestamp and baseFee. + /// + /// Returns a HexString representing the encoded signature with a validity period. + String getSafeSignature(String signature, BlockInformation blockInfo) { + final timestamp = blockInfo.timestamp.millisecondsSinceEpoch ~/ 1000; + + String validAfter = (timestamp - 3600).toRadixString(16); + validAfter = '0' * (12 - validAfter.length) + validAfter; + + String validUntil = (timestamp + 3600).toRadixString(16); + validUntil = '0' * (12 - validUntil.length) + validUntil; + + int v = int.parse(signature.substring(130, 132), radix: 16); + + if (v >= 27 && v <= 30) { + v += 4; + } + + String modifiedV = v.toRadixString(16); + if (modifiedV.length == 1) { + modifiedV = '0$modifiedV'; + } + + return '0x$validAfter$validUntil${signature.substring(2, 130)}$modifiedV'; + } + + /// Computes the hash of a Safe UserOperation. + /// + /// [op] is an object representing the user operation details. + /// [blockInfo] is the current timestamp in seconds. + /// + /// Returns a Future that resolves to the hash of the user operation as a Uint8List. + Future getSafeOperationHash( + UserOperation op, BlockInformation blockInfo) async { + if (self.address == Safe4337ModuleAddress.v07.address) { + return getOperationHash$2([ + op.sender, + op.nonce, + op.initCode, + op.callData, + packUints(op.verificationGasLimit, op.callGasLimit), + op.preVerificationGas, + packUints(op.maxPriorityFeePerGas, op.maxFeePerGas), + op.paymasterAndData, + hexToBytes(getSafeSignature(op.signature, blockInfo)) + ]); + } + return getOperationHash([ + op.sender, + op.nonce, + op.initCode, + op.callData, + op.callGasLimit, + op.verificationGasLimit, + op.preVerificationGas, + op.maxFeePerGas, + op.maxPriorityFeePerGas, + op.paymasterAndData, + hexToBytes(getSafeSignature(op.signature, blockInfo)) + ]); + } + + Uint8List getSafeMultisendCallData(List recipients, + List? amounts, List? innerCalls) { + Uint8List packedCallData = Uint8List(0); + + for (int i = 0; i < recipients.length; i++) { + Uint8List operation = Uint8List.fromList([0]); + Uint8List to = recipients[i].addressBytes; + Uint8List value = amounts != null + ? padTo32Bytes(amounts[i].getInWei) + : padTo32Bytes(BigInt.zero); + Uint8List dataLength = innerCalls != null + ? padTo32Bytes(BigInt.from(innerCalls[i].length)) + : padTo32Bytes(BigInt.zero); + Uint8List data = + innerCalls != null ? innerCalls[i] : Uint8List.fromList([]); + Uint8List encodedCall = Uint8List.fromList( + [...operation, ...to, ...value, ...dataLength, ...data]); + packedCallData = Uint8List.fromList([...packedCallData, ...encodedCall]); + } + + return Contract.encodeFunctionCall( + "multiSend", + Constants.safeMultiSendaddress, + ContractAbis.get("multiSend"), + [packedCallData]); + } + + Uint8List padTo32Bytes(BigInt number) { + final bytes = intToBytes(number); + return bytes.length < 32 + ? Uint8List.fromList([...Uint8List(32 - bytes.length), ...bytes]) + : bytes; + } +} diff --git a/lib/src/4337/userop.dart b/lib/src/4337/userop.dart index 8c5a7c7..c650b8b 100644 --- a/lib/src/4337/userop.dart +++ b/lib/src/4337/userop.dart @@ -1,5 +1,6 @@ -part of '../../variance.dart'; +part of '../../variance_dart.dart'; +/// A class that implements the user operation struct defined in EIP4337. class UserOperation implements UserOperationBase { @override final EthereumAddress sender; @@ -115,84 +116,93 @@ class UserOperation implements UserOperationBase { paymasterAndData: Uint8List(0), ); - /// Creates a [UserOperation] by updating an existing operation using a map. - /// - /// Parameters: - /// - `map`: A map containing key-value pairs representing the user operation data. - /// - `opGas`: Optional parameter of type [UserOperationGas] for specifying gas-related information. - /// - `sender`: Optional Ethereum address of the sender. - /// - `nonce`: Optional nonce value. - /// - `initCode`: Optional initialization code. - /// - /// Returns: - /// A [UserOperation] instance created from the provided map. - /// - /// Example: - /// ```dart - /// var map = UserOperation.partial(callData: Uint8List(0xabcdef)).toMap(); - /// var updatedUserOperation = UserOperation.update( - /// map, - /// opGas: UserOperationGas(callGasLimit: BigInt.from(20000000), ...), - /// // Other parameters can be updated as needed. - /// ); - /// ``` - factory UserOperation.update( - Map map, { - UserOperationGas? opGas, + UserOperation copyWith({ EthereumAddress? sender, BigInt? nonce, - String? initCode, + Uint8List? initCode, + Uint8List? callData, + BigInt? callGasLimit, + BigInt? verificationGasLimit, + BigInt? preVerificationGas, + BigInt? maxFeePerGas, + BigInt? maxPriorityFeePerGas, + String? signature, + Uint8List? paymasterAndData, }) { - if (opGas != null) { - map['callGasLimit'] = '0x${opGas.callGasLimit.toRadixString(16)}'; - map['verificationGasLimit'] = - '0x${opGas.verificationGasLimit.toRadixString(16)}'; - map['preVerificationGas'] = - '0x${BigInt.from(opGas.preVerificationGas.toDouble() * 1.2).toRadixString(16)}'; - } - - if (sender != null) map['sender'] = sender.hex; - if (nonce != null) map['nonce'] = '0x${nonce.toRadixString(16)}'; - if (initCode != null) map['initCode'] = initCode; - - return UserOperation.fromMap(map); + return UserOperation( + sender: sender ?? this.sender, + nonce: nonce ?? this.nonce, + initCode: initCode ?? this.initCode, + callData: callData ?? this.callData, + callGasLimit: callGasLimit ?? this.callGasLimit, + verificationGasLimit: verificationGasLimit ?? this.verificationGasLimit, + preVerificationGas: preVerificationGas ?? this.preVerificationGas, + maxFeePerGas: maxFeePerGas ?? this.maxFeePerGas, + maxPriorityFeePerGas: maxPriorityFeePerGas ?? this.maxPriorityFeePerGas, + signature: signature ?? this.signature, + paymasterAndData: paymasterAndData ?? this.paymasterAndData, + ); } @override Uint8List hash(Chain chain) { - final encoded = keccak256(abi.encode([ - 'address', - 'uint256', - 'bytes32', - 'bytes32', - 'uint256', - 'uint256', - 'uint256', - 'uint256', - 'uint256', - 'bytes32', - ], [ - sender, - nonce, - keccak256(initCode), - keccak256(callData), - callGasLimit, - verificationGasLimit, - preVerificationGas, - maxFeePerGas, - maxPriorityFeePerGas, - keccak256(paymasterAndData), - ])); + Uint8List encoded; + if (chain.entrypoint.version == EntryPointAddress.v07.version) { + encoded = keccak256(abi.encode([ + 'address', + 'uint256', + 'bytes32', + 'bytes32', + 'bytes32', + 'uint256', + 'bytes32', + 'bytes32', + ], [ + sender, + nonce, + keccak256(initCode), + keccak256(callData), + packUints(verificationGasLimit, callGasLimit), + preVerificationGas, + packUints(maxPriorityFeePerGas, maxFeePerGas), + keccak256(paymasterAndData), + ])); + } else { + encoded = keccak256(abi.encode([ + 'address', + 'uint256', + 'bytes32', + 'bytes32', + 'uint256', + 'uint256', + 'uint256', + 'uint256', + 'uint256', + 'bytes32', + ], [ + sender, + nonce, + keccak256(initCode), + keccak256(callData), + callGasLimit, + verificationGasLimit, + preVerificationGas, + maxFeePerGas, + maxPriorityFeePerGas, + keccak256(paymasterAndData), + ])); + } return keccak256(abi.encode(['bytes32', 'address', 'uint256'], - [encoded, chain.entrypoint, BigInt.from(chain.chainId)])); + [encoded, chain.entrypoint.address, BigInt.from(chain.chainId)])); } + /// uses pimlico v07 useroperation standard, which requires only pimlico bundlers + /// this is a training wheel and will revert to which ever schema bundlers accept in concensus @override - Map toMap() { - return { + Map packUserOperation() { + Map op = { 'sender': sender.hexEip55, 'nonce': '0x${nonce.toRadixString(16)}', - 'initCode': hexlify(initCode), 'callData': hexlify(callData), 'callGasLimit': '0x${callGasLimit.toRadixString(16)}', 'verificationGasLimit': '0x${verificationGasLimit.toRadixString(16)}', @@ -200,14 +210,70 @@ class UserOperation implements UserOperationBase { 'maxFeePerGas': '0x${maxFeePerGas.toRadixString(16)}', 'maxPriorityFeePerGas': '0x${maxPriorityFeePerGas.toRadixString(16)}', 'signature': signature, - 'paymasterAndData': hexlify(paymasterAndData), }; + if (initCode.isNotEmpty) { + op['factory'] = hexlify(initCode.sublist(0, 20)); + op['factoryData'] = hexlify(initCode.sublist(20)); + } + if (paymasterAndData.isNotEmpty) { + op['paymaster'] = hexlify(paymasterAndData.sublist(0, 20)); + final upackedPaymasterGasFields = + unpackUints(hexlify(paymasterAndData.sublist(20, 52))); + op['paymasterVerificationGasLimit'] = + '0x${upackedPaymasterGasFields[0].toRadixString(16)}'; + op['paymasterPostOpGasLimit'] = + '0x${upackedPaymasterGasFields[1].toRadixString(16)}'; + op['paymasterData'] = hexlify(paymasterAndData.sublist(52)); + } + return op; } @override String toJson() { return jsonEncode(toMap()); } + + @override + Map toMap([double version = 0.6]) { + if (version == 0.7) return packUserOperation(); + return { + 'sender': sender.hexEip55, + 'nonce': '0x${nonce.toRadixString(16)}', + 'initCode': hexlify(initCode), + 'callData': hexlify(callData), + 'callGasLimit': '0x${callGasLimit.toRadixString(16)}', + 'verificationGasLimit': '0x${verificationGasLimit.toRadixString(16)}', + 'preVerificationGas': '0x${preVerificationGas.toRadixString(16)}', + 'maxFeePerGas': '0x${maxFeePerGas.toRadixString(16)}', + 'maxPriorityFeePerGas': '0x${maxPriorityFeePerGas.toRadixString(16)}', + 'paymasterAndData': hexlify(paymasterAndData), + 'signature': signature, + }; + } + + @override + UserOperation updateOpGas( + UserOperationGas? opGas, Map? feePerGas) { + return copyWith( + callGasLimit: opGas?.callGasLimit, + verificationGasLimit: opGas?.verificationGasLimit, + preVerificationGas: opGas?.preVerificationGas, + maxFeePerGas: (feePerGas?["maxFeePerGas"] as EtherAmount?)?.getInWei, + maxPriorityFeePerGas: + (feePerGas?["maxPriorityFeePerGas"] as EtherAmount?)?.getInWei, + ); + } + + @override + void validate(bool deployed, [String? initCode]) { + require( + deployed + ? hexlify(this.initCode).toLowerCase() == "0x" + : hexlify(this.initCode).toLowerCase() == initCode?.toLowerCase(), + "InitCode mismatch"); + require(callData.length >= 4, "Calldata too short"); + require(signature.length >= 64, "Signature too short"); + } } class UserOperationByHash { @@ -236,27 +302,34 @@ class UserOperationByHash { } class UserOperationGas { - final BigInt preVerificationGas; + final BigInt callGasLimit; final BigInt verificationGasLimit; + final BigInt preVerificationGas; BigInt? validAfter; BigInt? validUntil; - final BigInt callGasLimit; UserOperationGas({ - required this.preVerificationGas, + required this.callGasLimit, required this.verificationGasLimit, + required this.preVerificationGas, this.validAfter, this.validUntil, - required this.callGasLimit, }); factory UserOperationGas.fromMap(Map map) { + final List accountGasLimits = map['accountGasLimits'] != null + ? unpackUints(map['accountGasLimits']) + : [ + BigInt.parse(map['verificationGasLimit']), + BigInt.parse(map['callGasLimit']) + ]; + return UserOperationGas( + verificationGasLimit: accountGasLimits[0], + callGasLimit: accountGasLimits[1], preVerificationGas: BigInt.parse(map['preVerificationGas']), - verificationGasLimit: BigInt.parse(map['verificationGasLimit']), validAfter: map['validAfter'] != null ? BigInt.parse(map['validAfter']) : null, validUntil: map['validUntil'] != null ? BigInt.parse(map['validUntil']) : null, - callGasLimit: BigInt.parse(map['callGasLimit']), ); } } @@ -304,7 +377,43 @@ class UserOperationReceipt { class UserOperationResponse { final String userOpHash; - final Future Function({int millisecond}) wait; + final Future Function(String) _callback; - UserOperationResponse(this.userOpHash, this.wait); + UserOperationResponse(this.userOpHash, this._callback); + + Future wait( + [Duration timeout = const Duration(seconds: 15), + Duration pollInterval = const Duration(seconds: 2)]) async { + assert( + timeout.inSeconds > 0, + RangeError.value( + timeout.inSeconds, "timeout", "wait timeout must be >= 0 sec")); + assert( + pollInterval.inSeconds > 0, + RangeError.value(pollInterval.inSeconds, "pollInterval", + "pollInterval must be >= 0 sec")); + assert( + pollInterval < timeout, + RangeError.value( + timeout.inSeconds, "timeout", "timeout must be > pollInterval")); + + Duration count = Duration.zero; + + while (count < timeout) { + await Future.delayed(pollInterval); + + try { + final receipt = await _callback(userOpHash); + if (receipt != null) { + return receipt; + } + count += pollInterval; + } catch (e) { + count += pollInterval; + } + } + + throw TimeoutException( + "can't find useroperation with hash $userOpHash", timeout); + } } diff --git a/lib/src/4337/wallet.dart b/lib/src/4337/wallet.dart index 1dd8052..c3787b1 100644 --- a/lib/src/4337/wallet.dart +++ b/lib/src/4337/wallet.dart @@ -1,87 +1,59 @@ -part of '../../variance.dart'; - -class SmartWallet with _PluginManager implements SmartWalletBase { +part of '../../variance_dart.dart'; + +/// A class that represents a Smart Wallet on an Ethereum-like blockchain. +/// +/// The [SmartWallet] class implements the [SmartWalletBase] interface and provides +/// various methods for interacting with the wallet, such as sending transactions, +/// estimating gas, and retrieving balances. It uses various plugins for different +/// functionalities, such as contract interaction, gas estimation, and signing operations. +/// +/// The class utilizes the `_PluginManager` and `_GasSettings` mixins for managing plugins +/// and gas settings, respectively. +/// +/// Example usage: +/// +/// ```dart +/// // Create a new instance of the SmartWallet +/// final wallet = SmartWallet(chain, walletAddress, initCode); +/// +/// // Get the wallet balance +/// final balance = await wallet.balance; +/// +/// // Send a transaction +/// final recipient = EthereumAddress.fromHex('0x...'); +/// final amount = EtherAmount.fromUnitAndValue(EtherUnit.ether, 1); +/// final response = await wallet.send(recipient, amount); +/// ``` +class SmartWallet with _PluginManager, _GasSettings implements SmartWalletBase { + /// The blockchain chain configuration. final Chain _chain; - EthereumAddress? _walletAddress; - - Uint8List? _initCalldata; - - bool? _deployed; + /// The address of the Smart Wallet. + final EthereumAddress _walletAddress; - SmartWallet( - {required Chain chain, - required MultiSignerInterface signer, - required BundlerProviderBase bundler, - EthereumAddress? address}) - : _chain = chain.validate(), - _walletAddress = address { - final rpc = RPCProvider(chain.ethRpcUrl!); - final fact = _AccountFactory( - address: chain.accountFactory, chainId: chain.chainId, rpc: rpc); + /// The initialization code for deploying the Smart Wallet contract. + Uint8List _initCode; - addPlugin('signer', signer); - addPlugin('bundler', bundler); - addPlugin('ethRpc', rpc); - addPlugin('contract', Contract(rpc)); - addPlugin('factory', fact); - } - - /// Initializes a [SmartWallet] instance for a specific chain with the provided parameters. - /// - /// Parameters: - /// - `chain`: The blockchain [Chain] associated with the smart wallet. - /// - `signer`: The [MultiSignerInterface] responsible for signing transactions. - /// - `bundler`: The [BundlerProviderBase] that provides bundling services. - /// - `address`: Optional Ethereum address associated with the smart wallet. - /// - `initCallData`: Optional initialization calldata of the factory create method as a [Uint8List]. + /// Creates a new instance of the [SmartWallet] class. /// - /// Returns: - /// A fully initialized [SmartWallet] instance. - /// - /// Example: - /// ```dart - /// var smartWallet = SmartWallet.init( - /// chain: Chain.ethereum, - /// signer: myMultiSigner, - /// bundler: myBundler, - /// address: myWalletAddress, - /// initCallData: Uint8List.fromList([0x01, 0x02, 0x03]), - /// ); - /// ``` - /// additionally initializes the associated Entrypoint contract for `tx.wait(userOpHash)` calls - factory SmartWallet.init( - {required Chain chain, - required MultiSignerInterface signer, - required BundlerProviderBase bundler, - EthereumAddress? address, - Uint8List? initCallData}) { - final instance = SmartWallet( - chain: chain, signer: signer, bundler: bundler, address: address); - - instance - ..dangerouslySetInitCallData(initCallData) - ..plugin('bundler').initializeWithEntrypoint(Entrypoint( - address: chain.entrypoint, - client: instance.plugin('factory').client, - )); - - return instance; - } + /// [_chain] is an object representing the blockchain chain configuration. + /// [_walletAddress] is the address of the Smart Wallet. + /// [_initCode] is the initialization code for deploying the Smart Wallet contract. + SmartWallet(this._chain, this._walletAddress, this._initCode); @override - EthereumAddress? get address => _walletAddress; + EthereumAddress get address => _walletAddress; @override Future get balance => plugin("contract").getBalance(_walletAddress); @override - Future get deployed => + Future get isDeployed => plugin("contract").deployed(_walletAddress); @override - String get initCode => _initCode; + String get initCode => hexlify(_initCode); @override Future get initCodeGas => _initCodeGas; @@ -90,99 +62,41 @@ class SmartWallet with _PluginManager implements SmartWalletBase { Future get nonce => _getNonce(); @override - @Deprecated( - "pass the wallet address alongside the constructor if known beforehand") - set setWalletAddress(EthereumAddress address) => _walletAddress = address; + String? get toHex => _walletAddress.hexEip55; @override - String? get toHex => _walletAddress?.hexEip55; - - String get _initCode => _initCalldata != null - ? _chain.accountFactory.hexEip55 + hexlify(_initCalldata!).substring(2) - : "0x"; - - Uint8List get _initCodeBytes { - if (_initCalldata == null) return Uint8List(0); - List extended = _chain.accountFactory.addressBytes.toList(); - extended.addAll(_initCalldata!); - return Uint8List.fromList(extended); - } - - Future get _initCodeGas => plugin('ethRpc') - .estimateGas(_chain.entrypoint, _initCode); + String get dummySignature => plugin('signer').dummySignature; - @override - Future createSimpleAccount(Uint256 salt, {int? index}) async { - EthereumAddress signer = EthereumAddress.fromHex( - plugin('signer').getAddress(index: index ?? 0)); - _initCalldata = _getInitCallData('createAccount', [signer, salt.value]); - await getSimpleAccountAddress(signer, salt) - .then((addr) => {_walletAddress = addr}); - return this; - } - - @override - Future createSimplePasskeyAccount( - PassKeyPair pkp, Uint256 salt) async { - _initCalldata = _getInitCallData('createPasskeyAccount', [ - pkp.credentialHexBytes, - pkp.publicKey[0].value, - pkp.publicKey[1].value, - salt.value - ]); - - await getSimplePassKeyAccountAddress(pkp, salt) - .then((addr) => {_walletAddress = addr}); - return this; - } + /// Returns the estimated gas required for deploying the Smart Wallet contract. + /// + /// The gas estimation is performed by interacting with the 'jsonRpc' plugin + /// and estimating the gas for the initialization code. + Future get _initCodeGas => plugin('jsonRpc') + .estimateGas(_chain.entrypoint.address, initCode); @override - void dangerouslySetInitCallData(Uint8List? code) { - _initCalldata = code; + @Deprecated("Not recommended to modify the initcode") + void dangerouslySetInitCode(Uint8List code) { + _initCode = code; } - @override - Future getSimpleAccountAddress( - EthereumAddress signer, Uint256 salt) => - plugin<_AccountFactory>('factory').getAddress(signer, salt.value); - - @override - Future getSimplePassKeyAccountAddress( - PassKeyPair pkp, Uint256 salt) => - plugin<_AccountFactory>('factory').getPasskeyAccountAddress( - pkp.credentialHexBytes, - pkp.publicKey[0].value, - pkp.publicKey[1].value, - salt.value); - @override UserOperation buildUserOperation({ required Uint8List callData, BigInt? customNonce, - BigInt? callGasLimit, - BigInt? verificationGasLimit, - BigInt? preVerificationGas, - BigInt? maxFeePerGas, - BigInt? maxPriorityFeePerGas, }) => UserOperation.partial( - callData: callData, - initCode: _initCodeBytes, - sender: _walletAddress, - nonce: customNonce, - callGasLimit: callGasLimit, - verificationGasLimit: verificationGasLimit, - preVerificationGas: preVerificationGas, - maxFeePerGas: maxFeePerGas, - maxPriorityFeePerGas: maxPriorityFeePerGas, - ); + callData: callData, + initCode: _initCode, + sender: _walletAddress, + nonce: customNonce); @override Future send( EthereumAddress recipient, EtherAmount amount) => sendUserOperation(buildUserOperation( - callData: - Contract.execute(_walletAddress, to: recipient, amount: amount))); + callData: Contract.execute(_walletAddress, + to: recipient, amount: amount, isSafe: hasPlugin("safe")))); @override Future sendTransaction( @@ -190,119 +104,145 @@ class SmartWallet with _PluginManager implements SmartWalletBase { {EtherAmount? amount}) => sendUserOperation(buildUserOperation( callData: Contract.execute(_walletAddress, - to: to, amount: amount, innerCallData: encodedFunctionData))); + to: to, + amount: amount, + innerCallData: encodedFunctionData, + isSafe: hasPlugin("safe")))); @override Future sendBatchedTransaction( - List recipients, List calls, - {List? amounts}) => - sendUserOperation(buildUserOperation( + List recipients, List calls, + {List? amounts}) { + final isSafe = hasPlugin("safe"); + if (isSafe) { + final innerCall = plugin<_SafePlugin>('safe') + .getSafeMultisendCallData(recipients, amounts, calls); + return sendUserOperation(buildUserOperation( + callData: Contract.executeBatch( + walletAddress: _walletAddress, + recipients: [Constants.safeMultiSendaddress], + amounts: [], + innerCalls: [innerCall], + isSafe: true))); + } else { + return sendUserOperation(buildUserOperation( callData: Contract.executeBatch( walletAddress: _walletAddress, recipients: recipients, amounts: amounts, innerCalls: calls))); + } + } @override Future sendSignedUserOperation(UserOperation op) => plugin('bundler') - .sendUserOperation(op.toMap(), _chain.entrypoint); + .sendUserOperation( + op.toMap(_chain.entrypoint.version), _chain.entrypoint) + .catchError((e) => throw SendError(e.toString(), op)); @override - Future sendUserOperation(UserOperation op, - {String? id}) => - signUserOperation(op, id: id).then(sendSignedUserOperation); + Future sendUserOperation(UserOperation op) => + prepareUserOperation(op) + .then(signUserOperation) + .then(sendSignedUserOperation); @override - Future signUserOperation(UserOperation userOp, - {bool update = true, String? id, int? index}) async { - if (update) userOp = await _updateUserOperation(userOp); - - final opHash = userOp.hash(_chain); + Future prepareUserOperation(UserOperation op, + {bool update = true}) async { + // Update the user operation with the latest nonce and gas prices if needed + if (update) op = await _updateUserOperation(op); - Uint8List signature = await plugin('signer') - .personalSign( - opHash, - index: index, - id: id ?? - (plugin('signer') is PasskeyInterface - ? plugin('signer').defaultId - : id)); + // If the 'paymaster' plugin is enabled, intercept the user operation + if (hasPlugin('paymaster')) { + op = await plugin('paymaster').intercept(op); + } - userOp.signature = hexlify(signature); + // Validate the user operation + op.validate(op.nonce > BigInt.zero, initCode); - await _validateUserOperation(userOp); - return userOp; + return op; } - Uint8List _getInitCallData(String functionName, List params) => - plugin<_AccountFactory>('factory') - .self - .function(functionName) - .encodeCall(params); - - Future _getNonce() => plugin("contract") - .call(_chain.entrypoint, ContractAbis.get('getNonce'), "getNonce", - params: [_walletAddress, BigInt.zero]) - .then((value) => Uint256(value[0])) - .catchError((e) => throw SmartWalletError( - "Error getting nonce for address: $_walletAddress. ${e.toString()}")); - - Future _updateUserOperation(UserOperation op) async { - List responses = await Future.wait([ - plugin('ethRpc').getGasPrice(), - _getNonce(), - Future.microtask(() async => _deployed = await deployed) - ]); - - op = UserOperation.update(op.toMap(), - sender: _walletAddress, - nonce: responses[1].value, - initCode: responses[2] ? "0x" : null); - op.maxFeePerGas = - (responses[0] as Map)["maxFeePerGas"]!.getInWei; - op.maxPriorityFeePerGas = - (responses[0] as Map)["maxPriorityFeePerGas"]! - .getInWei; - op.signature = plugin('signer').dummySignature; - - return plugin('bundler') - .estimateUserOperationGas(op.toMap(), _chain.entrypoint) - .then((opGas) => UserOperation.update(op.toMap(), opGas: opGas)); - } + @override + Future signUserOperation(UserOperation op, + {int? index}) async { + final isSafe = hasPlugin('safe'); + final blockInfo = + await plugin('jsonRpc').getBlockInformation(); - Future _validateUserOperation(UserOperation op) async { - if (_walletAddress == null) { - throw SmartWalletError( - 'Wallet address must be set: Did you call create?', - ); - } + // Calculate the operation hash + final opHash = isSafe + ? await plugin<_SafePlugin>('safe').getSafeOperationHash(op, blockInfo) + : op.hash(_chain); - require(op.sender.hex == _walletAddress?.hex, - "Operation sender error. ${op.sender} provided."); - require( - (_deployed ?? (await deployed)) - ? hexlify(op.initCode).toLowerCase() == "0x" - : hexlify(op.initCode).toLowerCase() == initCode.toLowerCase(), - "Init code mismatch"); - require(op.callGasLimit >= BigInt.from(21000), - "Call gas limit too small expected value greater than 21000"); - require(op.verificationGasLimit >= BigInt.from(39000), - "Verification gas limit too small expected value greater than 39000"); - require(op.preVerificationGas >= BigInt.from(5000), - "Pre verification gas too small expected value greater than 5000"); - require(op.callData.length >= 4, "Call data too short, min is 4 bytes"); - require(op.signature.length >= 64, "Signature too short, min is 32 bytes"); - } -} + // Sign the operation hash using the 'signer' plugin + final signature = + await plugin('signer').personalSign(opHash, index: index); + final signatureHex = hexlify(signature); -class SmartWalletError extends Error { - final String message; + // Append the signature validity period if the 'safe' plugin is enabled + op.signature = isSafe + ? plugin<_SafePlugin>('safe').getSafeSignature(signatureHex, blockInfo) + : signatureHex; - SmartWalletError(this.message); - - @override - String toString() { - return message; + return op; } + + /// Returns the nonce for the Smart Wallet address. + /// + /// If the wallet is not deployed, returns 0. + /// Otherwise, retrieves the nonce by calling the 'getNonce' function on the entrypoint. + /// + /// If an error occurs during the nonce retrieval process, a [NonceError] exception is thrown. + Future _getNonce() => isDeployed.then((deployed) => !deployed + ? Future.value(Uint256.zero) + : plugin("contract") + .read(_chain.entrypoint.address, ContractAbis.get('getNonce'), + "getNonce", + params: [_walletAddress, BigInt.zero]) + .then((value) => Uint256(value[0])) + .catchError((e) => throw NonceError(e.toString(), _walletAddress))); + + /// Updates the user operation with the latest nonce and gas prices. + /// + /// [op] is the user operation to update. + /// + /// Returns a [Future] that resolves to the updated [UserOperation] object. + Future _updateUserOperation(UserOperation op) => + Future.wait([ + _getNonce(), + plugin('jsonRpc').getGasPrice() + ]).then((responses) { + op = op.copyWith( + nonce: op.nonce > BigInt.zero ? op.nonce : responses[0].value, + initCode: responses[0] > Uint256.zero ? Uint8List(0) : null, + signature: dummySignature); + + // require pimlico bundlers for entrypoint v07 + if (_chain.entrypoint.version == 0.7) { + final bundlerHost = Uri.parse(_chain.bundlerUrl!).host; + Logger.conditionalError(!bundlerHost.contains("pimlico"), + "Entrypoint v07 is relatively new. Currently, only compatible with pimlico bundler https://pimlico.io."); + } + + return _updateUserOperationGas(op, feePerGas: responses[1]); + }); + + /// Updates the gas information for the user operation. + /// + /// [op] is the user operation to update. + /// [feePerGas] is an optional map containing the gas prices. + /// + /// Returns a [Future] that resolves to the updated [UserOperation] object. + /// + /// If an error occurs during the gas estimation process, a [GasEstimationError] exception is thrown. + Future _updateUserOperationGas(UserOperation op, + {Map? feePerGas}) => + plugin('bundler') + .estimateUserOperationGas( + op.toMap(_chain.entrypoint.version), _chain.entrypoint) + .then((opGas) => op.updateOpGas(opGas, feePerGas)) + .then((op) => applyCustomGasSettings(op)) + .catchError((e) => throw GasEstimationError(e.toString(), op)); } diff --git a/lib/src/abis/abis.dart b/lib/src/abis/abis.dart index 2e8d394..6b08f08 100644 --- a/lib/src/abis/abis.dart +++ b/lib/src/abis/abis.dart @@ -1,5 +1,6 @@ -export 'accountFactory.g.dart'; +export 'simpleAccountFactory.g.dart'; +export 'p256AccountFactory.g.dart'; +export 'safeProxyFactory.g.dart'; +export 'safe4337Module.g.dart'; export 'contract_abis.dart'; export 'entrypoint.g.dart'; -export 'token.g.dart'; -export 'simplePasskeyAccount.g.dart'; diff --git a/lib/src/abis/accountFactory.abi.json b/lib/src/abis/accountFactory.abi.json deleted file mode 100644 index 37e104d..0000000 --- a/lib/src/abis/accountFactory.abi.json +++ /dev/null @@ -1,95 +0,0 @@ -[ - { - "inputs": [ - { - "internalType": "contract IEntryPoint", - "name": "_entryPoint", - "type": "address" - } - ], - "stateMutability": "nonpayable", - "type": "constructor" - }, - { - "inputs": [ - { "internalType": "address", "name": "owner", "type": "address" }, - { "internalType": "uint256", "name": "salt", "type": "uint256" } - ], - "name": "createAccount", - "outputs": [ - { - "internalType": "contract SimpleAccount", - "name": "ret", - "type": "address" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { "internalType": "bytes32", "name": "credentialHex", "type": "bytes32" }, - { "internalType": "uint256", "name": "x", "type": "uint256" }, - { "internalType": "uint256", "name": "y", "type": "uint256" }, - { "internalType": "uint256", "name": "salt", "type": "uint256" } - ], - "name": "createPasskeyAccount", - "outputs": [ - { - "internalType": "contract SimplePasskeyAccount", - "name": "ret", - "type": "address" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { "internalType": "address", "name": "owner", "type": "address" }, - { "internalType": "uint256", "name": "salt", "type": "uint256" } - ], - "name": "getAddress", - "outputs": [{ "internalType": "address", "name": "", "type": "address" }], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { "internalType": "bytes32", "name": "credentialHex", "type": "bytes32" }, - { "internalType": "uint256", "name": "x", "type": "uint256" }, - { "internalType": "uint256", "name": "y", "type": "uint256" }, - { "internalType": "uint256", "name": "salt", "type": "uint256" } - ], - "name": "getPasskeyAccountAddress", - "outputs": [{ "internalType": "address", "name": "", "type": "address" }], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "simpleAccount", - "outputs": [ - { - "internalType": "contract SimpleAccount", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "simplePasskeyAccount", - "outputs": [ - { - "internalType": "contract SimplePasskeyAccount", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - } -] diff --git a/lib/src/abis/accountFactory.g.dart b/lib/src/abis/accountFactory.g.dart deleted file mode 100644 index d076fda..0000000 --- a/lib/src/abis/accountFactory.g.dart +++ /dev/null @@ -1,154 +0,0 @@ -// Generated code, do not modify. Run `build_runner build` to re-generate! -// @dart=2.12 -// ignore_for_file: no_leading_underscores_for_library_prefixes -import 'package:web3dart/web3dart.dart' as _i1; -import 'dart:typed_data' as _i2; - -final _contractAbi = _i1.ContractAbi.fromJson( - '[{"inputs":[{"internalType":"contract IEntryPoint","name":"_entryPoint","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"salt","type":"uint256"}],"name":"createAccount","outputs":[{"internalType":"contract SimpleAccount","name":"ret","type":"address"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"credentialHex","type":"bytes32"},{"internalType":"uint256","name":"x","type":"uint256"},{"internalType":"uint256","name":"y","type":"uint256"},{"internalType":"uint256","name":"salt","type":"uint256"}],"name":"createPasskeyAccount","outputs":[{"internalType":"contract SimplePasskeyAccount","name":"ret","type":"address"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"salt","type":"uint256"}],"name":"getAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"credentialHex","type":"bytes32"},{"internalType":"uint256","name":"x","type":"uint256"},{"internalType":"uint256","name":"y","type":"uint256"},{"internalType":"uint256","name":"salt","type":"uint256"}],"name":"getPasskeyAccountAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"simpleAccount","outputs":[{"internalType":"contract SimpleAccount","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"simplePasskeyAccount","outputs":[{"internalType":"contract SimplePasskeyAccount","name":"","type":"address"}],"stateMutability":"view","type":"function"}]', - 'AccountFactory', -); - -class AccountFactory extends _i1.GeneratedContract { - AccountFactory({ - required _i1.EthereumAddress address, - required _i1.Web3Client client, - int? chainId, - }) : super( - _i1.DeployedContract( - _contractAbi, - address, - ), - client, - chainId, - ); - - /// The optional [transaction] parameter can be used to override parameters - /// like the gas price, nonce and max gas. The `data` and `to` fields will be - /// set by the contract. - Future createAccount( - _i1.EthereumAddress owner, - BigInt salt, { - required _i1.Credentials credentials, - _i1.Transaction? transaction, - }) async { - final function = self.abi.functions[1]; - assert(checkSignature(function, '5fbfb9cf')); - final params = [ - owner, - salt, - ]; - return write( - credentials, - transaction, - function, - params, - ); - } - - /// The optional [transaction] parameter can be used to override parameters - /// like the gas price, nonce and max gas. The `data` and `to` fields will be - /// set by the contract. - Future createPasskeyAccount( - _i2.Uint8List credentialHex, - BigInt x, - BigInt y, - BigInt salt, { - required _i1.Credentials credentials, - _i1.Transaction? transaction, - }) async { - final function = self.abi.functions[2]; - assert(checkSignature(function, 'e2bb0bd2')); - final params = [ - credentialHex, - x, - y, - salt, - ]; - return write( - credentials, - transaction, - function, - params, - ); - } - - /// The optional [atBlock] parameter can be used to view historical data. When - /// set, the function will be evaluated in the specified block. By default, the - /// latest on-chain block will be used. - Future<_i1.EthereumAddress> getAddress( - _i1.EthereumAddress owner, - BigInt salt, { - _i1.BlockNum? atBlock, - }) async { - final function = self.abi.functions[3]; - assert(checkSignature(function, '8cb84e18')); - final params = [ - owner, - salt, - ]; - final response = await read( - function, - params, - atBlock, - ); - return (response[0] as _i1.EthereumAddress); - } - - /// The optional [atBlock] parameter can be used to view historical data. When - /// set, the function will be evaluated in the specified block. By default, the - /// latest on-chain block will be used. - Future<_i1.EthereumAddress> getPasskeyAccountAddress( - _i2.Uint8List credentialHex, - BigInt x, - BigInt y, - BigInt salt, { - _i1.BlockNum? atBlock, - }) async { - final function = self.abi.functions[4]; - assert(checkSignature(function, 'c162e788')); - final params = [ - credentialHex, - x, - y, - salt, - ]; - final response = await read( - function, - params, - atBlock, - ); - return (response[0] as _i1.EthereumAddress); - } - - /// The optional [atBlock] parameter can be used to view historical data. When - /// set, the function will be evaluated in the specified block. By default, the - /// latest on-chain block will be used. - Future<_i1.EthereumAddress> simpleAccount({_i1.BlockNum? atBlock}) async { - final function = self.abi.functions[5]; - assert(checkSignature(function, '65e4731a')); - final params = []; - final response = await read( - function, - params, - atBlock, - ); - return (response[0] as _i1.EthereumAddress); - } - - /// The optional [atBlock] parameter can be used to view historical data. When - /// set, the function will be evaluated in the specified block. By default, the - /// latest on-chain block will be used. - Future<_i1.EthereumAddress> simplePasskeyAccount( - {_i1.BlockNum? atBlock}) async { - final function = self.abi.functions[6]; - assert(checkSignature(function, 'b2d46b17')); - final params = []; - final response = await read( - function, - params, - atBlock, - ); - return (response[0] as _i1.EthereumAddress); - } -} diff --git a/lib/src/abis/contract_abis.dart b/lib/src/abis/contract_abis.dart index 602054e..05f429d 100644 --- a/lib/src/abis/contract_abis.dart +++ b/lib/src/abis/contract_abis.dart @@ -1,28 +1,93 @@ import 'package:web3dart/web3dart.dart'; +/// Contract ABIs +/// Getters for contract ABIs for onchain operations class ContractAbis { - static ContractAbi get(String name, {ContractAbi? abi}) { + /// Get contract ABI + /// - `name`: name of the contract + /// + /// Returns ABI of the contract. + static ContractAbi get(String name) { String abi; switch (name) { - case 'ERC721': + case 'ERC20_BalanceOf': abi = - '[{"inputs":[{"internalType":"string","name":"name","type":"string"},{"internalType":"string","name":"symbol","type":"string"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"baseURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"burn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"string","name":"_tokenURI","type":"string"}],"name":"mint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"baseURI","type":"string"}],"name":"setBaseURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenOfOwnerByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"}]'; + '[{"constant":true,"inputs":[{"name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"}]'; break; - case 'ERC20': + case 'ERC20_Approve': abi = - '[{"constant":true,"inputs":[],"name":"name","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"spender","type":"address"},{"name":"value","type":"uint256"}],"name":"approve","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"totalSupply","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"from","type":"address"},{"name":"to","type":"address"},{"name":"value","type":"uint256"}],"name":"transferFrom","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"decimals","outputs":[{"name":"","type":"uint8"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"spender","type":"address"},{"name":"addedValue","type":"uint256"}],"name":"increaseAllowance","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"to","type":"address"},{"name":"value","type":"uint256"}],"name":"mint","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"symbol","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"account","type":"address"}],"name":"addMinter","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"renounceMinter","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"spender","type":"address"},{"name":"subtractedValue","type":"uint256"}],"name":"decreaseAllowance","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"to","type":"address"},{"name":"value","type":"uint256"}],"name":"transfer","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"account","type":"address"}],"name":"isMinter","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"owner","type":"address"},{"name":"spender","type":"address"}],"name":"allowance","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"inputs":[{"name":"name","type":"string"},{"name":"symbol","type":"string"},{"name":"decimals","type":"uint8"}],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"name":"account","type":"address"}],"name":"MinterAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"account","type":"address"}],"name":"MinterRemoved","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"from","type":"address"},{"indexed":true,"name":"to","type":"address"},{"indexed":false,"name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"owner","type":"address"},{"indexed":true,"name":"spender","type":"address"},{"indexed":false,"name":"value","type":"uint256"}],"name":"Approval","type":"event"}]'; + '[{"constant":false,"inputs":[{"name":"spender","type":"address"},{"name":"value","type":"uint256"}],"name":"approve","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"}]'; + break; + case 'ERC20_Allowance': + abi = + '[{"constant":true,"inputs":[{"name":"owner","type":"address"},{"name":"spender","type":"address"}],"name":"allowance","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"}]'; + break; + case 'ERC20_Transfer': + abi = + '[{"constant":false,"inputs":[{"name":"to","type":"address"},{"name":"value","type":"uint256"}],"name":"transfer","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"}]'; + break; + case 'ERC20_TransferFrom': + abi = + '[{"constant":false,"inputs":[{"name":"from","type":"address"},{"name":"to","type":"address"},{"name":"value","type":"uint256"}],"name":"transferFrom","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"}]'; + break; + case 'ERC20_Mint': + abi = + '[{"constant":false,"inputs":[{"name":"to","type":"address"},{"name":"value","type":"uint256"}],"name":"mint","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"}]'; + break; + case 'ERC721_BalanceOf': + abi = + '[{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"}]'; + break; + case 'ERC721_OwnerOf': + abi = + '[{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"}]'; + break; + case 'ERC721_Approve': + abi = + '[{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"}]'; + break; + case 'ERC721_SafeMint': + abi = + '[{"type":"function","name":"safeMint","inputs":[{"name":"to","type":"address","internalType":"address"}],"outputs":[],"stateMutability":"nonpayable"}]'; + break; + case 'ERC721_SafeTransferFrom': + abi = + '[{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"}]'; + break; + case 'ERC721_Burn': + abi = + '[{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"burn","outputs":[],"stateMutability":"nonpayable","type":"function"}]'; break; case 'getNonce': abi = '[{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"uint192","name":"key","type":"uint192"}],"name":"getNonce","outputs":[{"internalType":"uint256","name":"nonce","type":"uint256"}],"stateMutability":"view","type":"function" }]'; + break; case 'execute': abi = '[{"inputs":[{"internalType":"address","name":"dest","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"bytes","name":"func","type":"bytes"}],"name":"execute","outputs":[],"stateMutability":"nonpayable","type":"function"}]'; + break; + case 'executeUserOpWithErrorString': + abi = + '[{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"},{"internalType":"uint8","name":"operation","type":"uint8"}],"name":"executeUserOpWithErrorString","outputs":[],"stateMutability":"nonpayable","type":"function"}]'; + break; case 'executeBatch': abi = '[{"inputs":[{"internalType":"address[]","name":"dest","type":"address[]"},{"internalType":"uint256[]","name":"value","type":"uint256[]"},{"internalType":"bytes[]","name":"func","type":"bytes[]"}],"name":"executeBatch","outputs":[],"stateMutability":"nonpayable","type":"function"}]'; + break; + case 'enableModules': + abi = + '[{"type":"function","name":"enableModules","inputs":[{"name":"modules","type":"address[]","internalType":"address[]"}],"outputs":[],"stateMutability":"nonpayable"}]'; + break; + case 'setup': + abi = + '[{"type":"function","name":"setup","inputs":[{"name":"_owners","type":"address[]","internalType":"address[]"},{"name":"_threshold","type":"uint256","internalType":"uint256"},{"name":"to","type":"address","internalType":"address"},{"name":"data","type":"bytes","internalType":"bytes"},{"name":"fallbackHandler","type":"address","internalType":"address"},{"name":"paymentToken","type":"address","internalType":"address"},{"name":"payment","type":"uint256","internalType":"uint256"},{"name":"paymentReceiver","type":"address","internalType":"address payable"}],"outputs":[],"stateMutability":"nonpayable"}]'; + break; + case 'multiSend': + abi = + '[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"bytes","name":"transactions","type":"bytes"}],"name":"multiSend","outputs":[],"stateMutability":"payable","type":"function"}]'; + break; default: - throw 'ABI of $name is not available, but you can add it yourself'; + throw 'ABI of $name is not available by default. Please provide the ABI manually.'; } return ContractAbi.fromJson(abi, name); } diff --git a/lib/src/abis/nft.abi.json b/lib/src/abis/nft.abi.json deleted file mode 100644 index ccbf5ee..0000000 --- a/lib/src/abis/nft.abi.json +++ /dev/null @@ -1,270 +0,0 @@ -[ - { - "inputs": [ - { "internalType": "string", "name": "name", "type": "string" }, - { "internalType": "string", "name": "symbol", "type": "string" } - ], - "stateMutability": "nonpayable", - "type": "constructor" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "owner", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "approved", - "type": "address" - }, - { - "indexed": true, - "internalType": "uint256", - "name": "tokenId", - "type": "uint256" - } - ], - "name": "Approval", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "owner", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "operator", - "type": "address" - }, - { - "indexed": false, - "internalType": "bool", - "name": "approved", - "type": "bool" - } - ], - "name": "ApprovalForAll", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "from", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "indexed": true, - "internalType": "uint256", - "name": "tokenId", - "type": "uint256" - } - ], - "name": "Transfer", - "type": "event" - }, - { - "inputs": [ - { "internalType": "address", "name": "to", "type": "address" }, - { "internalType": "uint256", "name": "tokenId", "type": "uint256" } - ], - "name": "approve", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { "internalType": "address", "name": "owner", "type": "address" } - ], - "name": "balanceOf", - "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "baseURI", - "outputs": [{ "internalType": "string", "name": "", "type": "string" }], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { "internalType": "uint256", "name": "tokenId", "type": "uint256" } - ], - "name": "burn", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { "internalType": "uint256", "name": "tokenId", "type": "uint256" } - ], - "name": "getApproved", - "outputs": [{ "internalType": "address", "name": "", "type": "address" }], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { "internalType": "address", "name": "owner", "type": "address" }, - { "internalType": "address", "name": "operator", "type": "address" } - ], - "name": "isApprovedForAll", - "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { "internalType": "address", "name": "to", "type": "address" }, - { "internalType": "uint256", "name": "tokenId", "type": "uint256" }, - { "internalType": "string", "name": "_tokenURI", "type": "string" } - ], - "name": "mint", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "name", - "outputs": [{ "internalType": "string", "name": "", "type": "string" }], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { "internalType": "uint256", "name": "tokenId", "type": "uint256" } - ], - "name": "ownerOf", - "outputs": [{ "internalType": "address", "name": "", "type": "address" }], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { "internalType": "address", "name": "from", "type": "address" }, - { "internalType": "address", "name": "to", "type": "address" }, - { "internalType": "uint256", "name": "tokenId", "type": "uint256" } - ], - "name": "safeTransferFrom", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { "internalType": "address", "name": "from", "type": "address" }, - { "internalType": "address", "name": "to", "type": "address" }, - { "internalType": "uint256", "name": "tokenId", "type": "uint256" }, - { "internalType": "bytes", "name": "_data", "type": "bytes" } - ], - "name": "safeTransferFrom", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { "internalType": "address", "name": "operator", "type": "address" }, - { "internalType": "bool", "name": "approved", "type": "bool" } - ], - "name": "setApprovalForAll", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { "internalType": "string", "name": "baseURI", "type": "string" } - ], - "name": "setBaseURI", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { "internalType": "bytes4", "name": "interfaceId", "type": "bytes4" } - ], - "name": "supportsInterface", - "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "symbol", - "outputs": [{ "internalType": "string", "name": "", "type": "string" }], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { "internalType": "uint256", "name": "index", "type": "uint256" } - ], - "name": "tokenByIndex", - "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { "internalType": "address", "name": "owner", "type": "address" }, - { "internalType": "uint256", "name": "index", "type": "uint256" } - ], - "name": "tokenOfOwnerByIndex", - "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { "internalType": "uint256", "name": "tokenId", "type": "uint256" } - ], - "name": "tokenURI", - "outputs": [{ "internalType": "string", "name": "", "type": "string" }], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "totalSupply", - "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { "internalType": "address", "name": "from", "type": "address" }, - { "internalType": "address", "name": "to", "type": "address" }, - { "internalType": "uint256", "name": "tokenId", "type": "uint256" } - ], - "name": "transferFrom", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - } -] diff --git a/lib/src/abis/nft.g.dart b/lib/src/abis/nft.g.dart deleted file mode 100644 index e7aab7a..0000000 --- a/lib/src/abis/nft.g.dart +++ /dev/null @@ -1,546 +0,0 @@ -// Generated code, do not modify. Run `build_runner build` to re-generate! -// @dart=2.12 -// ignore_for_file: no_leading_underscores_for_library_prefixes -import 'package:web3dart/web3dart.dart' as _i1; -import 'dart:typed_data' as _i2; - -final _contractAbi = _i1.ContractAbi.fromJson( - '[{"inputs":[{"internalType":"string","name":"name","type":"string"},{"internalType":"string","name":"symbol","type":"string"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"baseURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"burn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"string","name":"_tokenURI","type":"string"}],"name":"mint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"baseURI","type":"string"}],"name":"setBaseURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenOfOwnerByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"}]', - 'Nft', -); - -class Nft extends _i1.GeneratedContract { - Nft({ - required _i1.EthereumAddress address, - required _i1.Web3Client client, - int? chainId, - }) : super( - _i1.DeployedContract( - _contractAbi, - address, - ), - client, - chainId, - ); - - /// The optional [transaction] parameter can be used to override parameters - /// like the gas price, nonce and max gas. The `data` and `to` fields will be - /// set by the contract. - Future approve( - _i1.EthereumAddress to, - BigInt tokenId, { - required _i1.Credentials credentials, - _i1.Transaction? transaction, - }) async { - final function = self.abi.functions[1]; - assert(checkSignature(function, '095ea7b3')); - final params = [ - to, - tokenId, - ]; - return write( - credentials, - transaction, - function, - params, - ); - } - - /// The optional [atBlock] parameter can be used to view historical data. When - /// set, the function will be evaluated in the specified block. By default, the - /// latest on-chain block will be used. - Future balanceOf( - _i1.EthereumAddress owner, { - _i1.BlockNum? atBlock, - }) async { - final function = self.abi.functions[2]; - assert(checkSignature(function, '70a08231')); - final params = [owner]; - final response = await read( - function, - params, - atBlock, - ); - return (response[0] as BigInt); - } - - /// The optional [atBlock] parameter can be used to view historical data. When - /// set, the function will be evaluated in the specified block. By default, the - /// latest on-chain block will be used. - Future baseURI({_i1.BlockNum? atBlock}) async { - final function = self.abi.functions[3]; - assert(checkSignature(function, '6c0360eb')); - final params = []; - final response = await read( - function, - params, - atBlock, - ); - return (response[0] as String); - } - - /// The optional [transaction] parameter can be used to override parameters - /// like the gas price, nonce and max gas. The `data` and `to` fields will be - /// set by the contract. - Future burn( - BigInt tokenId, { - required _i1.Credentials credentials, - _i1.Transaction? transaction, - }) async { - final function = self.abi.functions[4]; - assert(checkSignature(function, '42966c68')); - final params = [tokenId]; - return write( - credentials, - transaction, - function, - params, - ); - } - - /// The optional [atBlock] parameter can be used to view historical data. When - /// set, the function will be evaluated in the specified block. By default, the - /// latest on-chain block will be used. - Future<_i1.EthereumAddress> getApproved( - BigInt tokenId, { - _i1.BlockNum? atBlock, - }) async { - final function = self.abi.functions[5]; - assert(checkSignature(function, '081812fc')); - final params = [tokenId]; - final response = await read( - function, - params, - atBlock, - ); - return (response[0] as _i1.EthereumAddress); - } - - /// The optional [atBlock] parameter can be used to view historical data. When - /// set, the function will be evaluated in the specified block. By default, the - /// latest on-chain block will be used. - Future isApprovedForAll( - _i1.EthereumAddress owner, - _i1.EthereumAddress operator, { - _i1.BlockNum? atBlock, - }) async { - final function = self.abi.functions[6]; - assert(checkSignature(function, 'e985e9c5')); - final params = [ - owner, - operator, - ]; - final response = await read( - function, - params, - atBlock, - ); - return (response[0] as bool); - } - - /// The optional [transaction] parameter can be used to override parameters - /// like the gas price, nonce and max gas. The `data` and `to` fields will be - /// set by the contract. - Future mint( - _i1.EthereumAddress to, - BigInt tokenId, - String _tokenURI, { - required _i1.Credentials credentials, - _i1.Transaction? transaction, - }) async { - final function = self.abi.functions[7]; - assert(checkSignature(function, 'd3fc9864')); - final params = [ - to, - tokenId, - _tokenURI, - ]; - return write( - credentials, - transaction, - function, - params, - ); - } - - /// The optional [atBlock] parameter can be used to view historical data. When - /// set, the function will be evaluated in the specified block. By default, the - /// latest on-chain block will be used. - Future name({_i1.BlockNum? atBlock}) async { - final function = self.abi.functions[8]; - assert(checkSignature(function, '06fdde03')); - final params = []; - final response = await read( - function, - params, - atBlock, - ); - return (response[0] as String); - } - - /// The optional [atBlock] parameter can be used to view historical data. When - /// set, the function will be evaluated in the specified block. By default, the - /// latest on-chain block will be used. - Future<_i1.EthereumAddress> ownerOf( - BigInt tokenId, { - _i1.BlockNum? atBlock, - }) async { - final function = self.abi.functions[9]; - assert(checkSignature(function, '6352211e')); - final params = [tokenId]; - final response = await read( - function, - params, - atBlock, - ); - return (response[0] as _i1.EthereumAddress); - } - - /// The optional [transaction] parameter can be used to override parameters - /// like the gas price, nonce and max gas. The `data` and `to` fields will be - /// set by the contract. - Future safeTransferFrom( - _i1.EthereumAddress from, - _i1.EthereumAddress to, - BigInt tokenId, { - required _i1.Credentials credentials, - _i1.Transaction? transaction, - }) async { - final function = self.abi.functions[10]; - assert(checkSignature(function, '42842e0e')); - final params = [ - from, - to, - tokenId, - ]; - return write( - credentials, - transaction, - function, - params, - ); - } - - /// The optional [transaction] parameter can be used to override parameters - /// like the gas price, nonce and max gas. The `data` and `to` fields will be - /// set by the contract. - Future safeTransferFrom$2( - _i1.EthereumAddress from, - _i1.EthereumAddress to, - BigInt tokenId, - _i2.Uint8List _data, { - required _i1.Credentials credentials, - _i1.Transaction? transaction, - }) async { - final function = self.abi.functions[11]; - assert(checkSignature(function, 'b88d4fde')); - final params = [ - from, - to, - tokenId, - _data, - ]; - return write( - credentials, - transaction, - function, - params, - ); - } - - /// The optional [transaction] parameter can be used to override parameters - /// like the gas price, nonce and max gas. The `data` and `to` fields will be - /// set by the contract. - Future setApprovalForAll( - _i1.EthereumAddress operator, - bool approved, { - required _i1.Credentials credentials, - _i1.Transaction? transaction, - }) async { - final function = self.abi.functions[12]; - assert(checkSignature(function, 'a22cb465')); - final params = [ - operator, - approved, - ]; - return write( - credentials, - transaction, - function, - params, - ); - } - - /// The optional [transaction] parameter can be used to override parameters - /// like the gas price, nonce and max gas. The `data` and `to` fields will be - /// set by the contract. - Future setBaseURI( - String baseURI, { - required _i1.Credentials credentials, - _i1.Transaction? transaction, - }) async { - final function = self.abi.functions[13]; - assert(checkSignature(function, '55f804b3')); - final params = [baseURI]; - return write( - credentials, - transaction, - function, - params, - ); - } - - /// The optional [atBlock] parameter can be used to view historical data. When - /// set, the function will be evaluated in the specified block. By default, the - /// latest on-chain block will be used. - Future supportsInterface( - _i2.Uint8List interfaceId, { - _i1.BlockNum? atBlock, - }) async { - final function = self.abi.functions[14]; - assert(checkSignature(function, '01ffc9a7')); - final params = [interfaceId]; - final response = await read( - function, - params, - atBlock, - ); - return (response[0] as bool); - } - - /// The optional [atBlock] parameter can be used to view historical data. When - /// set, the function will be evaluated in the specified block. By default, the - /// latest on-chain block will be used. - Future symbol({_i1.BlockNum? atBlock}) async { - final function = self.abi.functions[15]; - assert(checkSignature(function, '95d89b41')); - final params = []; - final response = await read( - function, - params, - atBlock, - ); - return (response[0] as String); - } - - /// The optional [atBlock] parameter can be used to view historical data. When - /// set, the function will be evaluated in the specified block. By default, the - /// latest on-chain block will be used. - Future tokenByIndex( - BigInt index, { - _i1.BlockNum? atBlock, - }) async { - final function = self.abi.functions[16]; - assert(checkSignature(function, '4f6ccce7')); - final params = [index]; - final response = await read( - function, - params, - atBlock, - ); - return (response[0] as BigInt); - } - - /// The optional [atBlock] parameter can be used to view historical data. When - /// set, the function will be evaluated in the specified block. By default, the - /// latest on-chain block will be used. - Future tokenOfOwnerByIndex( - _i1.EthereumAddress owner, - BigInt index, { - _i1.BlockNum? atBlock, - }) async { - final function = self.abi.functions[17]; - assert(checkSignature(function, '2f745c59')); - final params = [ - owner, - index, - ]; - final response = await read( - function, - params, - atBlock, - ); - return (response[0] as BigInt); - } - - /// The optional [atBlock] parameter can be used to view historical data. When - /// set, the function will be evaluated in the specified block. By default, the - /// latest on-chain block will be used. - Future tokenURI( - BigInt tokenId, { - _i1.BlockNum? atBlock, - }) async { - final function = self.abi.functions[18]; - assert(checkSignature(function, 'c87b56dd')); - final params = [tokenId]; - final response = await read( - function, - params, - atBlock, - ); - return (response[0] as String); - } - - /// The optional [atBlock] parameter can be used to view historical data. When - /// set, the function will be evaluated in the specified block. By default, the - /// latest on-chain block will be used. - Future totalSupply({_i1.BlockNum? atBlock}) async { - final function = self.abi.functions[19]; - assert(checkSignature(function, '18160ddd')); - final params = []; - final response = await read( - function, - params, - atBlock, - ); - return (response[0] as BigInt); - } - - /// The optional [transaction] parameter can be used to override parameters - /// like the gas price, nonce and max gas. The `data` and `to` fields will be - /// set by the contract. - Future transferFrom( - _i1.EthereumAddress from, - _i1.EthereumAddress to, - BigInt tokenId, { - required _i1.Credentials credentials, - _i1.Transaction? transaction, - }) async { - final function = self.abi.functions[20]; - assert(checkSignature(function, '23b872dd')); - final params = [ - from, - to, - tokenId, - ]; - return write( - credentials, - transaction, - function, - params, - ); - } - - /// Returns a live stream of all Approval events emitted by this contract. - Stream approvalEvents({ - _i1.BlockNum? fromBlock, - _i1.BlockNum? toBlock, - }) { - final event = self.event('Approval'); - final filter = _i1.FilterOptions.events( - contract: self, - event: event, - fromBlock: fromBlock, - toBlock: toBlock, - ); - return client.events(filter).map((_i1.FilterEvent result) { - final decoded = event.decodeResults( - result.topics!, - result.data!, - ); - return Approval( - decoded, - result, - ); - }); - } - - /// Returns a live stream of all ApprovalForAll events emitted by this contract. - Stream approvalForAllEvents({ - _i1.BlockNum? fromBlock, - _i1.BlockNum? toBlock, - }) { - final event = self.event('ApprovalForAll'); - final filter = _i1.FilterOptions.events( - contract: self, - event: event, - fromBlock: fromBlock, - toBlock: toBlock, - ); - return client.events(filter).map((_i1.FilterEvent result) { - final decoded = event.decodeResults( - result.topics!, - result.data!, - ); - return ApprovalForAll( - decoded, - result, - ); - }); - } - - /// Returns a live stream of all Transfer events emitted by this contract. - Stream transferEvents({ - _i1.BlockNum? fromBlock, - _i1.BlockNum? toBlock, - }) { - final event = self.event('Transfer'); - final filter = _i1.FilterOptions.events( - contract: self, - event: event, - fromBlock: fromBlock, - toBlock: toBlock, - ); - return client.events(filter).map((_i1.FilterEvent result) { - final decoded = event.decodeResults( - result.topics!, - result.data!, - ); - return Transfer( - decoded, - result, - ); - }); - } -} - -class Approval { - Approval( - List response, - this.event, - ) : owner = (response[0] as _i1.EthereumAddress), - approved = (response[1] as _i1.EthereumAddress), - tokenId = (response[2] as BigInt); - - final _i1.EthereumAddress owner; - - final _i1.EthereumAddress approved; - - final BigInt tokenId; - - final _i1.FilterEvent event; -} - -class ApprovalForAll { - ApprovalForAll( - List response, - this.event, - ) : owner = (response[0] as _i1.EthereumAddress), - operator = (response[1] as _i1.EthereumAddress), - approved = (response[2] as bool); - - final _i1.EthereumAddress owner; - - final _i1.EthereumAddress operator; - - final bool approved; - - final _i1.FilterEvent event; -} - -class Transfer { - Transfer( - List response, - this.event, - ) : from = (response[0] as _i1.EthereumAddress), - to = (response[1] as _i1.EthereumAddress), - tokenId = (response[2] as BigInt); - - final _i1.EthereumAddress from; - - final _i1.EthereumAddress to; - - final BigInt tokenId; - - final _i1.FilterEvent event; -} diff --git a/lib/src/abis/p256AccountFactory.abi.json b/lib/src/abis/p256AccountFactory.abi.json new file mode 100644 index 0000000..17df5bc --- /dev/null +++ b/lib/src/abis/p256AccountFactory.abi.json @@ -0,0 +1,48 @@ +[ + { + "type": "constructor", + "inputs": [ + { + "name": "_entryPoint", + "type": "address", + "internalType": "contract IEntryPoint" + } + ], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "createP256Account", + "inputs": [ + { "name": "salt", "type": "uint256", "internalType": "uint256" }, + { "name": "creation", "type": "bytes", "internalType": "bytes" } + ], + "outputs": [ + { + "name": "ret", + "type": "address", + "internalType": "contract P256Account" + } + ], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "getP256AccountAddress", + "inputs": [ + { "name": "salt", "type": "uint256", "internalType": "uint256" }, + { "name": "creation", "type": "bytes", "internalType": "bytes" } + ], + "outputs": [{ "name": "", "type": "address", "internalType": "address" }], + "stateMutability": "view" + }, + { + "type": "function", + "name": "p256Account", + "inputs": [], + "outputs": [ + { "name": "", "type": "address", "internalType": "contract P256Account" } + ], + "stateMutability": "view" + } +] diff --git a/lib/src/abis/p256AccountFactory.g.dart b/lib/src/abis/p256AccountFactory.g.dart new file mode 100644 index 0000000..fa5031c --- /dev/null +++ b/lib/src/abis/p256AccountFactory.g.dart @@ -0,0 +1,85 @@ +// Generated code, do not modify. Run `build_runner build` to re-generate! +// @dart=2.12 +// ignore_for_file: no_leading_underscores_for_library_prefixes +import 'package:web3dart/web3dart.dart' as _i1; +import 'dart:typed_data' as _i2; + +final _contractAbi = _i1.ContractAbi.fromJson( + '[{"type":"constructor","inputs":[{"name":"_entryPoint","type":"address","internalType":"contract IEntryPoint"}],"stateMutability":"nonpayable"},{"type":"function","name":"createP256Account","inputs":[{"name":"salt","type":"uint256","internalType":"uint256"},{"name":"creation","type":"bytes","internalType":"bytes"}],"outputs":[{"name":"ret","type":"address","internalType":"contract P256Account"}],"stateMutability":"nonpayable"},{"type":"function","name":"getP256AccountAddress","inputs":[{"name":"salt","type":"uint256","internalType":"uint256"},{"name":"creation","type":"bytes","internalType":"bytes"}],"outputs":[{"name":"","type":"address","internalType":"address"}],"stateMutability":"view"},{"type":"function","name":"p256Account","inputs":[],"outputs":[{"name":"","type":"address","internalType":"contract P256Account"}],"stateMutability":"view"}]', + 'P256AccountFactory', +); + +class P256AccountFactory extends _i1.GeneratedContract { + P256AccountFactory({ + required _i1.EthereumAddress address, + required _i1.Web3Client client, + int? chainId, + }) : super( + _i1.DeployedContract( + _contractAbi, + address, + ), + client, + chainId, + ); + + /// The optional [transaction] parameter can be used to override parameters + /// like the gas price, nonce and max gas. The `data` and `to` fields will be + /// set by the contract. + Future createP256Account( + BigInt salt, + _i2.Uint8List creation, { + required _i1.Credentials credentials, + _i1.Transaction? transaction, + }) async { + final function = self.abi.functions[1]; + assert(checkSignature(function, '8bb4387f')); + final params = [ + salt, + creation, + ]; + return write( + credentials, + transaction, + function, + params, + ); + } + + /// The optional [atBlock] parameter can be used to view historical data. When + /// set, the function will be evaluated in the specified block. By default, the + /// latest on-chain block will be used. + Future<_i1.EthereumAddress> getP256AccountAddress( + BigInt salt, + _i2.Uint8List creation, { + _i1.BlockNum? atBlock, + }) async { + final function = self.abi.functions[2]; + assert(checkSignature(function, '28ef50f0')); + final params = [ + salt, + creation, + ]; + final response = await read( + function, + params, + atBlock, + ); + return (response[0] as _i1.EthereumAddress); + } + + /// The optional [atBlock] parameter can be used to view historical data. When + /// set, the function will be evaluated in the specified block. By default, the + /// latest on-chain block will be used. + Future<_i1.EthereumAddress> p256Account({_i1.BlockNum? atBlock}) async { + final function = self.abi.functions[3]; + assert(checkSignature(function, 'e8eb9e23')); + final params = []; + final response = await read( + function, + params, + atBlock, + ); + return (response[0] as _i1.EthereumAddress); + } +} diff --git a/lib/src/abis/safe4337Module.abi.json b/lib/src/abis/safe4337Module.abi.json new file mode 100644 index 0000000..41b0a5d --- /dev/null +++ b/lib/src/abis/safe4337Module.abi.json @@ -0,0 +1,137 @@ +[ + { + "inputs": [ + { "internalType": "address", "name": "entryPoint", "type": "address" } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [], + "name": "SUPPORTED_ENTRYPOINT", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "domainSeparator", + "outputs": [{ "internalType": "bytes32", "name": "", "type": "bytes32" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "to", "type": "address" }, + { "internalType": "uint256", "name": "value", "type": "uint256" }, + { "internalType": "bytes", "name": "data", "type": "bytes" }, + { "internalType": "uint8", "name": "operation", "type": "uint8" } + ], + "name": "executeUserOp", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "to", "type": "address" }, + { "internalType": "uint256", "name": "value", "type": "uint256" }, + { "internalType": "bytes", "name": "data", "type": "bytes" }, + { "internalType": "uint8", "name": "operation", "type": "uint8" } + ], + "name": "executeUserOpWithErrorString", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { "internalType": "address", "name": "sender", "type": "address" }, + { "internalType": "uint256", "name": "nonce", "type": "uint256" }, + { "internalType": "bytes", "name": "initCode", "type": "bytes" }, + { "internalType": "bytes", "name": "callData", "type": "bytes" }, + { + "internalType": "uint256", + "name": "callGasLimit", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "verificationGasLimit", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "preVerificationGas", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "maxFeePerGas", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "maxPriorityFeePerGas", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "paymasterAndData", + "type": "bytes" + }, + { "internalType": "bytes", "name": "signature", "type": "bytes" } + ], + "internalType": "struct UserOperation", + "name": "userOp", + "type": "tuple" + } + ], + "name": "getOperationHash", + "outputs": [ + { "internalType": "bytes32", "name": "operationHash", "type": "bytes32" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { "internalType": "address", "name": "sender", "type": "address" }, + { "internalType": "uint256", "name": "nonce", "type": "uint256" }, + { "internalType": "bytes", "name": "initCode", "type": "bytes" }, + { "internalType": "bytes", "name": "callData", "type": "bytes" }, + { + "internalType": "bytes32", + "name": "accountGasLimits", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "preVerificationGas", + "type": "uint256" + }, + { "internalType": "bytes32", "name": "gasFees", "type": "bytes32" }, + { + "internalType": "bytes", + "name": "paymasterAndData", + "type": "bytes" + }, + { "internalType": "bytes", "name": "signature", "type": "bytes" } + ], + "internalType": "struct PackedUserOperation", + "name": "userOp", + "type": "tuple" + } + ], + "name": "getOperationHash", + "outputs": [ + { "internalType": "bytes32", "name": "operationHash", "type": "bytes32" } + ], + "stateMutability": "view", + "type": "function" + } +] diff --git a/lib/src/abis/safe4337Module.g.dart b/lib/src/abis/safe4337Module.g.dart new file mode 100644 index 0000000..affc039 --- /dev/null +++ b/lib/src/abis/safe4337Module.g.dart @@ -0,0 +1,146 @@ +// Generated code, do not modify. Run `build_runner build` to re-generate! +// @dart=2.12 +// ignore_for_file: no_leading_underscores_for_library_prefixes +import 'package:web3dart/web3dart.dart' as _i1; +import 'dart:typed_data' as _i2; + +final _contractAbi = _i1.ContractAbi.fromJson( + '[{"inputs":[{"internalType":"address","name":"entryPoint","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"SUPPORTED_ENTRYPOINT","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"domainSeparator","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"},{"internalType":"uint8","name":"operation","type":"uint8"}],"name":"executeUserOp","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"},{"internalType":"uint8","name":"operation","type":"uint8"}],"name":"executeUserOpWithErrorString","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"uint256","name":"nonce","type":"uint256"},{"internalType":"bytes","name":"initCode","type":"bytes"},{"internalType":"bytes","name":"callData","type":"bytes"},{"internalType":"uint256","name":"callGasLimit","type":"uint256"},{"internalType":"uint256","name":"verificationGasLimit","type":"uint256"},{"internalType":"uint256","name":"preVerificationGas","type":"uint256"},{"internalType":"uint256","name":"maxFeePerGas","type":"uint256"},{"internalType":"uint256","name":"maxPriorityFeePerGas","type":"uint256"},{"internalType":"bytes","name":"paymasterAndData","type":"bytes"},{"internalType":"bytes","name":"signature","type":"bytes"}],"internalType":"struct UserOperation","name":"userOp","type":"tuple"}],"name":"getOperationHash","outputs":[{"internalType":"bytes32","name":"operationHash","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"uint256","name":"nonce","type":"uint256"},{"internalType":"bytes","name":"initCode","type":"bytes"},{"internalType":"bytes","name":"callData","type":"bytes"},{"internalType":"bytes32","name":"accountGasLimits","type":"bytes32"},{"internalType":"uint256","name":"preVerificationGas","type":"uint256"},{"internalType":"bytes32","name":"gasFees","type":"bytes32"},{"internalType":"bytes","name":"paymasterAndData","type":"bytes"},{"internalType":"bytes","name":"signature","type":"bytes"}],"internalType":"struct PackedUserOperation","name":"userOp","type":"tuple"}],"name":"getOperationHash","outputs":[{"internalType":"bytes32","name":"operationHash","type":"bytes32"}],"stateMutability":"view","type":"function"}]', + 'Safe4337Module', +); + +class Safe4337Module extends _i1.GeneratedContract { + Safe4337Module({ + required _i1.EthereumAddress address, + required _i1.Web3Client client, + int? chainId, + }) : super( + _i1.DeployedContract( + _contractAbi, + address, + ), + client, + chainId, + ); + + /// The optional [atBlock] parameter can be used to view historical data. When + /// set, the function will be evaluated in the specified block. By default, the + /// latest on-chain block will be used. + Future<_i1.EthereumAddress> SUPPORTED_ENTRYPOINT( + {_i1.BlockNum? atBlock}) async { + final function = self.abi.functions[1]; + assert(checkSignature(function, '137e051e')); + final params = []; + final response = await read( + function, + params, + atBlock, + ); + return (response[0] as _i1.EthereumAddress); + } + + /// The optional [atBlock] parameter can be used to view historical data. When + /// set, the function will be evaluated in the specified block. By default, the + /// latest on-chain block will be used. + Future<_i2.Uint8List> domainSeparator({_i1.BlockNum? atBlock}) async { + final function = self.abi.functions[2]; + assert(checkSignature(function, 'f698da25')); + final params = []; + final response = await read( + function, + params, + atBlock, + ); + return (response[0] as _i2.Uint8List); + } + + /// The optional [transaction] parameter can be used to override parameters + /// like the gas price, nonce and max gas. The `data` and `to` fields will be + /// set by the contract. + Future executeUserOp( + _i1.EthereumAddress to, + BigInt value, + _i2.Uint8List data, + BigInt operation, { + required _i1.Credentials credentials, + _i1.Transaction? transaction, + }) async { + final function = self.abi.functions[3]; + assert(checkSignature(function, '7bb37428')); + final params = [ + to, + value, + data, + operation, + ]; + return write( + credentials, + transaction, + function, + params, + ); + } + + /// The optional [transaction] parameter can be used to override parameters + /// like the gas price, nonce and max gas. The `data` and `to` fields will be + /// set by the contract. + Future executeUserOpWithErrorString( + _i1.EthereumAddress to, + BigInt value, + _i2.Uint8List data, + BigInt operation, { + required _i1.Credentials credentials, + _i1.Transaction? transaction, + }) async { + final function = self.abi.functions[4]; + assert(checkSignature(function, '541d63c8')); + final params = [ + to, + value, + data, + operation, + ]; + return write( + credentials, + transaction, + function, + params, + ); + } + + /// The optional [atBlock] parameter can be used to view historical data. When + /// set, the function will be evaluated in the specified block. By default, the + /// latest on-chain block will be used. + Future<_i2.Uint8List> getOperationHash( + dynamic userOp, { + _i1.BlockNum? atBlock, + }) async { + final function = self.abi.functions[5]; + assert(checkSignature(function, 'b25f3776')); + final params = [userOp]; + final response = await read( + function, + params, + atBlock, + ); + return (response[0] as _i2.Uint8List); + } + + /// The optional [atBlock] parameter can be used to view historical data. When + /// set, the function will be evaluated in the specified block. By default, the + /// latest on-chain block will be used. + Future<_i2.Uint8List> getOperationHash$2( + dynamic userOp, { + _i1.BlockNum? atBlock, + }) async { + final function = self.abi.functions[6]; + assert(checkSignature(function, 'bbe5dc4f')); + final params = [userOp]; + final response = await read( + function, + params, + atBlock, + ); + return (response[0] as _i2.Uint8List); + } +} diff --git a/lib/src/abis/safeProxyFactory.abi.json b/lib/src/abis/safeProxyFactory.abi.json new file mode 100644 index 0000000..d630760 --- /dev/null +++ b/lib/src/abis/safeProxyFactory.abi.json @@ -0,0 +1,91 @@ +[ + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "contract SafeProxy", + "name": "proxy", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "singleton", + "type": "address" + } + ], + "name": "ProxyCreation", + "type": "event" + }, + { + "inputs": [ + { "internalType": "address", "name": "_singleton", "type": "address" }, + { "internalType": "bytes", "name": "initializer", "type": "bytes" }, + { "internalType": "uint256", "name": "saltNonce", "type": "uint256" } + ], + "name": "createChainSpecificProxyWithNonce", + "outputs": [ + { + "internalType": "contract SafeProxy", + "name": "proxy", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_singleton", "type": "address" }, + { "internalType": "bytes", "name": "initializer", "type": "bytes" }, + { "internalType": "uint256", "name": "saltNonce", "type": "uint256" }, + { + "internalType": "contract IProxyCreationCallback", + "name": "callback", + "type": "address" + } + ], + "name": "createProxyWithCallback", + "outputs": [ + { + "internalType": "contract SafeProxy", + "name": "proxy", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_singleton", "type": "address" }, + { "internalType": "bytes", "name": "initializer", "type": "bytes" }, + { "internalType": "uint256", "name": "saltNonce", "type": "uint256" } + ], + "name": "createProxyWithNonce", + "outputs": [ + { + "internalType": "contract SafeProxy", + "name": "proxy", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "getChainId", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "proxyCreationCode", + "outputs": [{ "internalType": "bytes", "name": "", "type": "bytes" }], + "stateMutability": "pure", + "type": "function" + } +] diff --git a/lib/src/abis/safeProxyFactory.g.dart b/lib/src/abis/safeProxyFactory.g.dart new file mode 100644 index 0000000..7790cbd --- /dev/null +++ b/lib/src/abis/safeProxyFactory.g.dart @@ -0,0 +1,170 @@ +// Generated code, do not modify. Run `build_runner build` to re-generate! +// @dart=2.12 +// ignore_for_file: no_leading_underscores_for_library_prefixes +import 'package:web3dart/web3dart.dart' as _i1; +import 'dart:typed_data' as _i2; + +final _contractAbi = _i1.ContractAbi.fromJson( + '[{"anonymous":false,"inputs":[{"indexed":true,"internalType":"contract SafeProxy","name":"proxy","type":"address"},{"indexed":false,"internalType":"address","name":"singleton","type":"address"}],"name":"ProxyCreation","type":"event"},{"inputs":[{"internalType":"address","name":"_singleton","type":"address"},{"internalType":"bytes","name":"initializer","type":"bytes"},{"internalType":"uint256","name":"saltNonce","type":"uint256"}],"name":"createChainSpecificProxyWithNonce","outputs":[{"internalType":"contract SafeProxy","name":"proxy","type":"address"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_singleton","type":"address"},{"internalType":"bytes","name":"initializer","type":"bytes"},{"internalType":"uint256","name":"saltNonce","type":"uint256"},{"internalType":"contract IProxyCreationCallback","name":"callback","type":"address"}],"name":"createProxyWithCallback","outputs":[{"internalType":"contract SafeProxy","name":"proxy","type":"address"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_singleton","type":"address"},{"internalType":"bytes","name":"initializer","type":"bytes"},{"internalType":"uint256","name":"saltNonce","type":"uint256"}],"name":"createProxyWithNonce","outputs":[{"internalType":"contract SafeProxy","name":"proxy","type":"address"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"getChainId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"proxyCreationCode","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"pure","type":"function"}]', + 'SafeProxyFactory', +); + +class SafeProxyFactory extends _i1.GeneratedContract { + SafeProxyFactory({ + required _i1.EthereumAddress address, + required _i1.Web3Client client, + int? chainId, + }) : super( + _i1.DeployedContract( + _contractAbi, + address, + ), + client, + chainId, + ); + + /// The optional [transaction] parameter can be used to override parameters + /// like the gas price, nonce and max gas. The `data` and `to` fields will be + /// set by the contract. + Future createChainSpecificProxyWithNonce( + _i1.EthereumAddress _singleton, + _i2.Uint8List initializer, + BigInt saltNonce, { + required _i1.Credentials credentials, + _i1.Transaction? transaction, + }) async { + final function = self.abi.functions[0]; + assert(checkSignature(function, 'ec9e80bb')); + final params = [ + _singleton, + initializer, + saltNonce, + ]; + return write( + credentials, + transaction, + function, + params, + ); + } + + /// The optional [transaction] parameter can be used to override parameters + /// like the gas price, nonce and max gas. The `data` and `to` fields will be + /// set by the contract. + Future createProxyWithCallback( + _i1.EthereumAddress _singleton, + _i2.Uint8List initializer, + BigInt saltNonce, + _i1.EthereumAddress callback, { + required _i1.Credentials credentials, + _i1.Transaction? transaction, + }) async { + final function = self.abi.functions[1]; + assert(checkSignature(function, 'd18af54d')); + final params = [ + _singleton, + initializer, + saltNonce, + callback, + ]; + return write( + credentials, + transaction, + function, + params, + ); + } + + /// The optional [transaction] parameter can be used to override parameters + /// like the gas price, nonce and max gas. The `data` and `to` fields will be + /// set by the contract. + Future createProxyWithNonce( + _i1.EthereumAddress _singleton, + _i2.Uint8List initializer, + BigInt saltNonce, { + required _i1.Credentials credentials, + _i1.Transaction? transaction, + }) async { + final function = self.abi.functions[2]; + assert(checkSignature(function, '1688f0b9')); + final params = [ + _singleton, + initializer, + saltNonce, + ]; + return write( + credentials, + transaction, + function, + params, + ); + } + + /// The optional [atBlock] parameter can be used to view historical data. When + /// set, the function will be evaluated in the specified block. By default, the + /// latest on-chain block will be used. + Future getChainId({_i1.BlockNum? atBlock}) async { + final function = self.abi.functions[3]; + assert(checkSignature(function, '3408e470')); + final params = []; + final response = await read( + function, + params, + atBlock, + ); + return (response[0] as BigInt); + } + + /// The optional [atBlock] parameter can be used to view historical data. When + /// set, the function will be evaluated in the specified block. By default, the + /// latest on-chain block will be used. + Future<_i2.Uint8List> proxyCreationCode({_i1.BlockNum? atBlock}) async { + final function = self.abi.functions[4]; + assert(checkSignature(function, '53e5d935')); + final params = []; + final response = await read( + function, + params, + atBlock, + ); + return (response[0] as _i2.Uint8List); + } + + /// Returns a live stream of all ProxyCreation events emitted by this contract. + Stream proxyCreationEvents({ + _i1.BlockNum? fromBlock, + _i1.BlockNum? toBlock, + }) { + final event = self.event('ProxyCreation'); + final filter = _i1.FilterOptions.events( + contract: self, + event: event, + fromBlock: fromBlock, + toBlock: toBlock, + ); + return client.events(filter).map((_i1.FilterEvent result) { + final decoded = event.decodeResults( + result.topics!, + result.data!, + ); + return ProxyCreation( + decoded, + result, + ); + }); + } +} + +class ProxyCreation { + ProxyCreation( + List response, + this.event, + ) : proxy = (response[0] as _i1.EthereumAddress), + singleton = (response[1] as _i1.EthereumAddress); + + final _i1.EthereumAddress proxy; + + final _i1.EthereumAddress singleton; + + final _i1.FilterEvent event; +} diff --git a/lib/src/abis/simpleAccount.abi.json b/lib/src/abis/simpleAccount.abi.json deleted file mode 100644 index 2d6cc5f..0000000 --- a/lib/src/abis/simpleAccount.abi.json +++ /dev/null @@ -1,327 +0,0 @@ -[ - { - "inputs": [ - { - "internalType": "contract IEntryPoint", - "name": "anEntryPoint", - "type": "address" - } - ], - "stateMutability": "nonpayable", - "type": "constructor" - }, - { - "inputs": [ - { "internalType": "address", "name": "target", "type": "address" } - ], - "name": "AddressEmptyCode", - "type": "error" - }, - { "inputs": [], "name": "ECDSAInvalidSignature", "type": "error" }, - { - "inputs": [ - { "internalType": "uint256", "name": "length", "type": "uint256" } - ], - "name": "ECDSAInvalidSignatureLength", - "type": "error" - }, - { - "inputs": [{ "internalType": "bytes32", "name": "s", "type": "bytes32" }], - "name": "ECDSAInvalidSignatureS", - "type": "error" - }, - { - "inputs": [ - { "internalType": "address", "name": "implementation", "type": "address" } - ], - "name": "ERC1967InvalidImplementation", - "type": "error" - }, - { "inputs": [], "name": "ERC1967NonPayable", "type": "error" }, - { "inputs": [], "name": "FailedInnerCall", "type": "error" }, - { "inputs": [], "name": "InvalidInitialization", "type": "error" }, - { "inputs": [], "name": "NotInitializing", "type": "error" }, - { "inputs": [], "name": "UUPSUnauthorizedCallContext", "type": "error" }, - { - "inputs": [ - { "internalType": "bytes32", "name": "slot", "type": "bytes32" } - ], - "name": "UUPSUnsupportedProxiableUUID", - "type": "error" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "uint64", - "name": "version", - "type": "uint64" - } - ], - "name": "Initialized", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "contract IEntryPoint", - "name": "entryPoint", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "owner", - "type": "address" - } - ], - "name": "SimpleAccountInitialized", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "implementation", - "type": "address" - } - ], - "name": "Upgraded", - "type": "event" - }, - { - "inputs": [], - "name": "UPGRADE_INTERFACE_VERSION", - "outputs": [{ "internalType": "string", "name": "", "type": "string" }], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "addDeposit", - "outputs": [], - "stateMutability": "payable", - "type": "function" - }, - { - "inputs": [], - "name": "entryPoint", - "outputs": [ - { "internalType": "contract IEntryPoint", "name": "", "type": "address" } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { "internalType": "address", "name": "dest", "type": "address" }, - { "internalType": "uint256", "name": "value", "type": "uint256" }, - { "internalType": "bytes", "name": "func", "type": "bytes" } - ], - "name": "execute", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { "internalType": "address[]", "name": "dest", "type": "address[]" }, - { "internalType": "uint256[]", "name": "value", "type": "uint256[]" }, - { "internalType": "bytes[]", "name": "func", "type": "bytes[]" } - ], - "name": "executeBatch", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "getDeposit", - "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "getNonce", - "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { "internalType": "address", "name": "anOwner", "type": "address" } - ], - "name": "initialize", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { "internalType": "address", "name": "", "type": "address" }, - { "internalType": "address", "name": "", "type": "address" }, - { "internalType": "uint256[]", "name": "", "type": "uint256[]" }, - { "internalType": "uint256[]", "name": "", "type": "uint256[]" }, - { "internalType": "bytes", "name": "", "type": "bytes" } - ], - "name": "onERC1155BatchReceived", - "outputs": [{ "internalType": "bytes4", "name": "", "type": "bytes4" }], - "stateMutability": "pure", - "type": "function" - }, - { - "inputs": [ - { "internalType": "address", "name": "", "type": "address" }, - { "internalType": "address", "name": "", "type": "address" }, - { "internalType": "uint256", "name": "", "type": "uint256" }, - { "internalType": "uint256", "name": "", "type": "uint256" }, - { "internalType": "bytes", "name": "", "type": "bytes" } - ], - "name": "onERC1155Received", - "outputs": [{ "internalType": "bytes4", "name": "", "type": "bytes4" }], - "stateMutability": "pure", - "type": "function" - }, - { - "inputs": [ - { "internalType": "address", "name": "", "type": "address" }, - { "internalType": "address", "name": "", "type": "address" }, - { "internalType": "uint256", "name": "", "type": "uint256" }, - { "internalType": "bytes", "name": "", "type": "bytes" } - ], - "name": "onERC721Received", - "outputs": [{ "internalType": "bytes4", "name": "", "type": "bytes4" }], - "stateMutability": "pure", - "type": "function" - }, - { - "inputs": [], - "name": "owner", - "outputs": [{ "internalType": "address", "name": "", "type": "address" }], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "proxiableUUID", - "outputs": [{ "internalType": "bytes32", "name": "", "type": "bytes32" }], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { "internalType": "bytes4", "name": "interfaceId", "type": "bytes4" } - ], - "name": "supportsInterface", - "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { "internalType": "address", "name": "", "type": "address" }, - { "internalType": "address", "name": "", "type": "address" }, - { "internalType": "address", "name": "", "type": "address" }, - { "internalType": "uint256", "name": "", "type": "uint256" }, - { "internalType": "bytes", "name": "", "type": "bytes" }, - { "internalType": "bytes", "name": "", "type": "bytes" } - ], - "name": "tokensReceived", - "outputs": [], - "stateMutability": "pure", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "newImplementation", - "type": "address" - }, - { "internalType": "bytes", "name": "data", "type": "bytes" } - ], - "name": "upgradeToAndCall", - "outputs": [], - "stateMutability": "payable", - "type": "function" - }, - { - "inputs": [ - { - "components": [ - { "internalType": "address", "name": "sender", "type": "address" }, - { "internalType": "uint256", "name": "nonce", "type": "uint256" }, - { "internalType": "bytes", "name": "initCode", "type": "bytes" }, - { "internalType": "bytes", "name": "callData", "type": "bytes" }, - { - "internalType": "uint256", - "name": "callGasLimit", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "verificationGasLimit", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "preVerificationGas", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "maxFeePerGas", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "maxPriorityFeePerGas", - "type": "uint256" - }, - { - "internalType": "bytes", - "name": "paymasterAndData", - "type": "bytes" - }, - { "internalType": "bytes", "name": "signature", "type": "bytes" } - ], - "internalType": "struct UserOperation", - "name": "userOp", - "type": "tuple" - }, - { "internalType": "bytes32", "name": "userOpHash", "type": "bytes32" }, - { - "internalType": "uint256", - "name": "missingAccountFunds", - "type": "uint256" - } - ], - "name": "validateUserOp", - "outputs": [ - { "internalType": "uint256", "name": "validationData", "type": "uint256" } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address payable", - "name": "withdrawAddress", - "type": "address" - }, - { "internalType": "uint256", "name": "amount", "type": "uint256" } - ], - "name": "withdrawDepositTo", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { "stateMutability": "payable", "type": "receive" } -] diff --git a/lib/src/abis/simpleAccount.g.dart b/lib/src/abis/simpleAccount.g.dart deleted file mode 100644 index 05fab4b..0000000 --- a/lib/src/abis/simpleAccount.g.dart +++ /dev/null @@ -1,510 +0,0 @@ -// Generated code, do not modify. Run `build_runner build` to re-generate! -// @dart=2.12 -// ignore_for_file: no_leading_underscores_for_library_prefixes -import 'package:web3dart/web3dart.dart' as _i1; -import 'dart:typed_data' as _i2; - -final _contractAbi = _i1.ContractAbi.fromJson( - '[{"inputs":[{"internalType":"contract IEntryPoint","name":"anEntryPoint","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"address","name":"target","type":"address"}],"name":"AddressEmptyCode","type":"error"},{"inputs":[],"name":"ECDSAInvalidSignature","type":"error"},{"inputs":[{"internalType":"uint256","name":"length","type":"uint256"}],"name":"ECDSAInvalidSignatureLength","type":"error"},{"inputs":[{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"ECDSAInvalidSignatureS","type":"error"},{"inputs":[{"internalType":"address","name":"implementation","type":"address"}],"name":"ERC1967InvalidImplementation","type":"error"},{"inputs":[],"name":"ERC1967NonPayable","type":"error"},{"inputs":[],"name":"FailedInnerCall","type":"error"},{"inputs":[],"name":"InvalidInitialization","type":"error"},{"inputs":[],"name":"NotInitializing","type":"error"},{"inputs":[],"name":"UUPSUnauthorizedCallContext","type":"error"},{"inputs":[{"internalType":"bytes32","name":"slot","type":"bytes32"}],"name":"UUPSUnsupportedProxiableUUID","type":"error"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint64","name":"version","type":"uint64"}],"name":"Initialized","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"contract IEntryPoint","name":"entryPoint","type":"address"},{"indexed":true,"internalType":"address","name":"owner","type":"address"}],"name":"SimpleAccountInitialized","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"implementation","type":"address"}],"name":"Upgraded","type":"event"},{"inputs":[],"name":"UPGRADE_INTERFACE_VERSION","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"addDeposit","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"entryPoint","outputs":[{"internalType":"contract IEntryPoint","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"dest","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"bytes","name":"func","type":"bytes"}],"name":"execute","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"dest","type":"address[]"},{"internalType":"uint256[]","name":"value","type":"uint256[]"},{"internalType":"bytes[]","name":"func","type":"bytes[]"}],"name":"executeBatch","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"getDeposit","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getNonce","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"anOwner","type":"address"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256[]","name":"","type":"uint256[]"},{"internalType":"uint256[]","name":"","type":"uint256[]"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"onERC1155BatchReceived","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"onERC1155Received","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"onERC721Received","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"proxiableUUID","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"bytes","name":"","type":"bytes"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"tokensReceived","outputs":[],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"newImplementation","type":"address"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"upgradeToAndCall","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"uint256","name":"nonce","type":"uint256"},{"internalType":"bytes","name":"initCode","type":"bytes"},{"internalType":"bytes","name":"callData","type":"bytes"},{"internalType":"uint256","name":"callGasLimit","type":"uint256"},{"internalType":"uint256","name":"verificationGasLimit","type":"uint256"},{"internalType":"uint256","name":"preVerificationGas","type":"uint256"},{"internalType":"uint256","name":"maxFeePerGas","type":"uint256"},{"internalType":"uint256","name":"maxPriorityFeePerGas","type":"uint256"},{"internalType":"bytes","name":"paymasterAndData","type":"bytes"},{"internalType":"bytes","name":"signature","type":"bytes"}],"internalType":"struct UserOperation","name":"userOp","type":"tuple"},{"internalType":"bytes32","name":"userOpHash","type":"bytes32"},{"internalType":"uint256","name":"missingAccountFunds","type":"uint256"}],"name":"validateUserOp","outputs":[{"internalType":"uint256","name":"validationData","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address payable","name":"withdrawAddress","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"withdrawDepositTo","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]', - 'SimpleAccount', -); - -class SimpleAccount extends _i1.GeneratedContract { - SimpleAccount({ - required _i1.EthereumAddress address, - required _i1.Web3Client client, - int? chainId, - }) : super( - _i1.DeployedContract( - _contractAbi, - address, - ), - client, - chainId, - ); - - /// The optional [atBlock] parameter can be used to view historical data. When - /// set, the function will be evaluated in the specified block. By default, the - /// latest on-chain block will be used. - Future UPGRADE_INTERFACE_VERSION({_i1.BlockNum? atBlock}) async { - final function = self.abi.functions[1]; - assert(checkSignature(function, 'ad3cb1cc')); - final params = []; - final response = await read( - function, - params, - atBlock, - ); - return (response[0] as String); - } - - /// The optional [transaction] parameter can be used to override parameters - /// like the gas price, nonce and max gas. The `data` and `to` fields will be - /// set by the contract. - Future addDeposit({ - required _i1.Credentials credentials, - _i1.Transaction? transaction, - }) async { - final function = self.abi.functions[2]; - assert(checkSignature(function, '4a58db19')); - final params = []; - return write( - credentials, - transaction, - function, - params, - ); - } - - /// The optional [atBlock] parameter can be used to view historical data. When - /// set, the function will be evaluated in the specified block. By default, the - /// latest on-chain block will be used. - Future<_i1.EthereumAddress> entryPoint({_i1.BlockNum? atBlock}) async { - final function = self.abi.functions[3]; - assert(checkSignature(function, 'b0d691fe')); - final params = []; - final response = await read( - function, - params, - atBlock, - ); - return (response[0] as _i1.EthereumAddress); - } - - /// The optional [transaction] parameter can be used to override parameters - /// like the gas price, nonce and max gas. The `data` and `to` fields will be - /// set by the contract. - Future execute( - _i1.EthereumAddress dest, - BigInt value, - _i2.Uint8List func, { - required _i1.Credentials credentials, - _i1.Transaction? transaction, - }) async { - final function = self.abi.functions[4]; - assert(checkSignature(function, 'b61d27f6')); - final params = [ - dest, - value, - func, - ]; - return write( - credentials, - transaction, - function, - params, - ); - } - - /// The optional [transaction] parameter can be used to override parameters - /// like the gas price, nonce and max gas. The `data` and `to` fields will be - /// set by the contract. - Future executeBatch( - List<_i1.EthereumAddress> dest, - List value, - List<_i2.Uint8List> func, { - required _i1.Credentials credentials, - _i1.Transaction? transaction, - }) async { - final function = self.abi.functions[5]; - assert(checkSignature(function, '47e1da2a')); - final params = [ - dest, - value, - func, - ]; - return write( - credentials, - transaction, - function, - params, - ); - } - - /// The optional [atBlock] parameter can be used to view historical data. When - /// set, the function will be evaluated in the specified block. By default, the - /// latest on-chain block will be used. - Future getDeposit({_i1.BlockNum? atBlock}) async { - final function = self.abi.functions[6]; - assert(checkSignature(function, 'c399ec88')); - final params = []; - final response = await read( - function, - params, - atBlock, - ); - return (response[0] as BigInt); - } - - /// The optional [atBlock] parameter can be used to view historical data. When - /// set, the function will be evaluated in the specified block. By default, the - /// latest on-chain block will be used. - Future getNonce({_i1.BlockNum? atBlock}) async { - final function = self.abi.functions[7]; - assert(checkSignature(function, 'd087d288')); - final params = []; - final response = await read( - function, - params, - atBlock, - ); - return (response[0] as BigInt); - } - - /// The optional [transaction] parameter can be used to override parameters - /// like the gas price, nonce and max gas. The `data` and `to` fields will be - /// set by the contract. - Future initialize( - _i1.EthereumAddress anOwner, { - required _i1.Credentials credentials, - _i1.Transaction? transaction, - }) async { - final function = self.abi.functions[8]; - assert(checkSignature(function, 'c4d66de8')); - final params = [anOwner]; - return write( - credentials, - transaction, - function, - params, - ); - } - - /// The optional [atBlock] parameter can be used to view historical data. When - /// set, the function will be evaluated in the specified block. By default, the - /// latest on-chain block will be used. - Future<_i2.Uint8List> onERC1155BatchReceived( - _i1.EthereumAddress $param7, - _i1.EthereumAddress $param8, - List $param9, - List $param10, - _i2.Uint8List $param11, { - _i1.BlockNum? atBlock, - }) async { - final function = self.abi.functions[9]; - assert(checkSignature(function, 'bc197c81')); - final params = [ - $param7, - $param8, - $param9, - $param10, - $param11, - ]; - final response = await read( - function, - params, - atBlock, - ); - return (response[0] as _i2.Uint8List); - } - - /// The optional [atBlock] parameter can be used to view historical data. When - /// set, the function will be evaluated in the specified block. By default, the - /// latest on-chain block will be used. - Future<_i2.Uint8List> onERC1155Received( - _i1.EthereumAddress $param12, - _i1.EthereumAddress $param13, - BigInt $param14, - BigInt $param15, - _i2.Uint8List $param16, { - _i1.BlockNum? atBlock, - }) async { - final function = self.abi.functions[10]; - assert(checkSignature(function, 'f23a6e61')); - final params = [ - $param12, - $param13, - $param14, - $param15, - $param16, - ]; - final response = await read( - function, - params, - atBlock, - ); - return (response[0] as _i2.Uint8List); - } - - /// The optional [atBlock] parameter can be used to view historical data. When - /// set, the function will be evaluated in the specified block. By default, the - /// latest on-chain block will be used. - Future<_i2.Uint8List> onERC721Received( - _i1.EthereumAddress $param17, - _i1.EthereumAddress $param18, - BigInt $param19, - _i2.Uint8List $param20, { - _i1.BlockNum? atBlock, - }) async { - final function = self.abi.functions[11]; - assert(checkSignature(function, '150b7a02')); - final params = [ - $param17, - $param18, - $param19, - $param20, - ]; - final response = await read( - function, - params, - atBlock, - ); - return (response[0] as _i2.Uint8List); - } - - /// The optional [atBlock] parameter can be used to view historical data. When - /// set, the function will be evaluated in the specified block. By default, the - /// latest on-chain block will be used. - Future<_i1.EthereumAddress> owner({_i1.BlockNum? atBlock}) async { - final function = self.abi.functions[12]; - assert(checkSignature(function, '8da5cb5b')); - final params = []; - final response = await read( - function, - params, - atBlock, - ); - return (response[0] as _i1.EthereumAddress); - } - - /// The optional [atBlock] parameter can be used to view historical data. When - /// set, the function will be evaluated in the specified block. By default, the - /// latest on-chain block will be used. - Future<_i2.Uint8List> proxiableUUID({_i1.BlockNum? atBlock}) async { - final function = self.abi.functions[13]; - assert(checkSignature(function, '52d1902d')); - final params = []; - final response = await read( - function, - params, - atBlock, - ); - return (response[0] as _i2.Uint8List); - } - - /// The optional [atBlock] parameter can be used to view historical data. When - /// set, the function will be evaluated in the specified block. By default, the - /// latest on-chain block will be used. - Future supportsInterface( - _i2.Uint8List interfaceId, { - _i1.BlockNum? atBlock, - }) async { - final function = self.abi.functions[14]; - assert(checkSignature(function, '01ffc9a7')); - final params = [interfaceId]; - final response = await read( - function, - params, - atBlock, - ); - return (response[0] as bool); - } - - /// The optional [atBlock] parameter can be used to view historical data. When - /// set, the function will be evaluated in the specified block. By default, the - /// latest on-chain block will be used. - Future tokensReceived( - _i1.EthereumAddress $param22, - _i1.EthereumAddress $param23, - _i1.EthereumAddress $param24, - BigInt $param25, - _i2.Uint8List $param26, - _i2.Uint8List $param27, { - _i1.BlockNum? atBlock, - }) async { - final function = self.abi.functions[15]; - assert(checkSignature(function, '0023de29')); - final params = [ - $param22, - $param23, - $param24, - $param25, - $param26, - $param27, - ]; - final response = await read( - function, - params, - atBlock, - ); - } - - /// The optional [transaction] parameter can be used to override parameters - /// like the gas price, nonce and max gas. The `data` and `to` fields will be - /// set by the contract. - Future upgradeToAndCall( - _i1.EthereumAddress newImplementation, - _i2.Uint8List data, { - required _i1.Credentials credentials, - _i1.Transaction? transaction, - }) async { - final function = self.abi.functions[16]; - assert(checkSignature(function, '4f1ef286')); - final params = [ - newImplementation, - data, - ]; - return write( - credentials, - transaction, - function, - params, - ); - } - - /// The optional [transaction] parameter can be used to override parameters - /// like the gas price, nonce and max gas. The `data` and `to` fields will be - /// set by the contract. - Future validateUserOp( - dynamic userOp, - _i2.Uint8List userOpHash, - BigInt missingAccountFunds, { - required _i1.Credentials credentials, - _i1.Transaction? transaction, - }) async { - final function = self.abi.functions[17]; - assert(checkSignature(function, '3a871cdd')); - final params = [ - userOp, - userOpHash, - missingAccountFunds, - ]; - return write( - credentials, - transaction, - function, - params, - ); - } - - /// The optional [transaction] parameter can be used to override parameters - /// like the gas price, nonce and max gas. The `data` and `to` fields will be - /// set by the contract. - Future withdrawDepositTo( - _i1.EthereumAddress withdrawAddress, - BigInt amount, { - required _i1.Credentials credentials, - _i1.Transaction? transaction, - }) async { - final function = self.abi.functions[18]; - assert(checkSignature(function, '4d44560d')); - final params = [ - withdrawAddress, - amount, - ]; - return write( - credentials, - transaction, - function, - params, - ); - } - - /// Returns a live stream of all Initialized events emitted by this contract. - Stream initializedEvents({ - _i1.BlockNum? fromBlock, - _i1.BlockNum? toBlock, - }) { - final event = self.event('Initialized'); - final filter = _i1.FilterOptions.events( - contract: self, - event: event, - fromBlock: fromBlock, - toBlock: toBlock, - ); - return client.events(filter).map((_i1.FilterEvent result) { - final decoded = event.decodeResults( - result.topics!, - result.data!, - ); - return Initialized( - decoded, - result, - ); - }); - } - - /// Returns a live stream of all SimpleAccountInitialized events emitted by this contract. - Stream simpleAccountInitializedEvents({ - _i1.BlockNum? fromBlock, - _i1.BlockNum? toBlock, - }) { - final event = self.event('SimpleAccountInitialized'); - final filter = _i1.FilterOptions.events( - contract: self, - event: event, - fromBlock: fromBlock, - toBlock: toBlock, - ); - return client.events(filter).map((_i1.FilterEvent result) { - final decoded = event.decodeResults( - result.topics!, - result.data!, - ); - return SimpleAccountInitialized( - decoded, - result, - ); - }); - } - - /// Returns a live stream of all Upgraded events emitted by this contract. - Stream upgradedEvents({ - _i1.BlockNum? fromBlock, - _i1.BlockNum? toBlock, - }) { - final event = self.event('Upgraded'); - final filter = _i1.FilterOptions.events( - contract: self, - event: event, - fromBlock: fromBlock, - toBlock: toBlock, - ); - return client.events(filter).map((_i1.FilterEvent result) { - final decoded = event.decodeResults( - result.topics!, - result.data!, - ); - return Upgraded( - decoded, - result, - ); - }); - } -} - -class Initialized { - Initialized( - List response, - this.event, - ) : version = (response[0] as BigInt); - - final BigInt version; - - final _i1.FilterEvent event; -} - -class SimpleAccountInitialized { - SimpleAccountInitialized( - List response, - this.event, - ) : entryPoint = (response[0] as _i1.EthereumAddress), - owner = (response[1] as _i1.EthereumAddress); - - final _i1.EthereumAddress entryPoint; - - final _i1.EthereumAddress owner; - - final _i1.FilterEvent event; -} - -class Upgraded { - Upgraded( - List response, - this.event, - ) : implementation = (response[0] as _i1.EthereumAddress); - - final _i1.EthereumAddress implementation; - - final _i1.FilterEvent event; -} diff --git a/lib/src/abis/simpleAccountFactory.abi.json b/lib/src/abis/simpleAccountFactory.abi.json new file mode 100644 index 0000000..0e5bc9b --- /dev/null +++ b/lib/src/abis/simpleAccountFactory.abi.json @@ -0,0 +1,74 @@ +[ + { + "inputs": [ + { + "internalType": "contract IEntryPoint", + "name": "_entryPoint", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [], + "name": "accountImplementation", + "outputs": [ + { + "internalType": "contract SimpleAccount", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "uint256", + "name": "salt", + "type": "uint256" + } + ], + "name": "createAccount", + "outputs": [ + { + "internalType": "contract SimpleAccount", + "name": "ret", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "uint256", + "name": "salt", + "type": "uint256" + } + ], + "name": "getAddress", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + } +] diff --git a/lib/src/abis/simpleAccountFactory.g.dart b/lib/src/abis/simpleAccountFactory.g.dart new file mode 100644 index 0000000..b452414 --- /dev/null +++ b/lib/src/abis/simpleAccountFactory.g.dart @@ -0,0 +1,85 @@ +// Generated code, do not modify. Run `build_runner build` to re-generate! +// @dart=2.12 +// ignore_for_file: no_leading_underscores_for_library_prefixes +import 'package:web3dart/web3dart.dart' as _i1; + +final _contractAbi = _i1.ContractAbi.fromJson( + '[{"inputs":[{"internalType":"contract IEntryPoint","name":"_entryPoint","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"accountImplementation","outputs":[{"internalType":"contract SimpleAccount","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"salt","type":"uint256"}],"name":"createAccount","outputs":[{"internalType":"contract SimpleAccount","name":"ret","type":"address"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"salt","type":"uint256"}],"name":"getAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"}]', + 'SimpleAccountFactory', +); + +class SimpleAccountFactory extends _i1.GeneratedContract { + SimpleAccountFactory({ + required _i1.EthereumAddress address, + required _i1.Web3Client client, + int? chainId, + }) : super( + _i1.DeployedContract( + _contractAbi, + address, + ), + client, + chainId, + ); + + /// The optional [atBlock] parameter can be used to view historical data. When + /// set, the function will be evaluated in the specified block. By default, the + /// latest on-chain block will be used. + Future<_i1.EthereumAddress> accountImplementation( + {_i1.BlockNum? atBlock}) async { + final function = self.abi.functions[1]; + assert(checkSignature(function, '11464fbe')); + final params = []; + final response = await read( + function, + params, + atBlock, + ); + return (response[0] as _i1.EthereumAddress); + } + + /// The optional [transaction] parameter can be used to override parameters + /// like the gas price, nonce and max gas. The `data` and `to` fields will be + /// set by the contract. + Future createAccount( + _i1.EthereumAddress owner, + BigInt salt, { + required _i1.Credentials credentials, + _i1.Transaction? transaction, + }) async { + final function = self.abi.functions[2]; + assert(checkSignature(function, '5fbfb9cf')); + final params = [ + owner, + salt, + ]; + return write( + credentials, + transaction, + function, + params, + ); + } + + /// The optional [atBlock] parameter can be used to view historical data. When + /// set, the function will be evaluated in the specified block. By default, the + /// latest on-chain block will be used. + Future<_i1.EthereumAddress> getAddress( + _i1.EthereumAddress owner, + BigInt salt, { + _i1.BlockNum? atBlock, + }) async { + final function = self.abi.functions[3]; + assert(checkSignature(function, '8cb84e18')); + final params = [ + owner, + salt, + ]; + final response = await read( + function, + params, + atBlock, + ); + return (response[0] as _i1.EthereumAddress); + } +} diff --git a/lib/src/abis/simplePasskeyAccount.abi.json b/lib/src/abis/simplePasskeyAccount.abi.json deleted file mode 100644 index 15ffa4e..0000000 --- a/lib/src/abis/simplePasskeyAccount.abi.json +++ /dev/null @@ -1,334 +0,0 @@ -[ - { - "inputs": [ - { - "internalType": "contract IEntryPoint", - "name": "anEntryPoint", - "type": "address" - } - ], - "stateMutability": "nonpayable", - "type": "constructor" - }, - { - "inputs": [ - { "internalType": "address", "name": "target", "type": "address" } - ], - "name": "AddressEmptyCode", - "type": "error" - }, - { - "inputs": [ - { "internalType": "address", "name": "implementation", "type": "address" } - ], - "name": "ERC1967InvalidImplementation", - "type": "error" - }, - { "inputs": [], "name": "ERC1967NonPayable", "type": "error" }, - { "inputs": [], "name": "FailedInnerCall", "type": "error" }, - { "inputs": [], "name": "InvalidInitialization", "type": "error" }, - { "inputs": [], "name": "NotInitializing", "type": "error" }, - { "inputs": [], "name": "UUPSUnauthorizedCallContext", "type": "error" }, - { - "inputs": [ - { "internalType": "bytes32", "name": "slot", "type": "bytes32" } - ], - "name": "UUPSUnsupportedProxiableUUID", - "type": "error" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "uint64", - "name": "version", - "type": "uint64" - } - ], - "name": "Initialized", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "contract IEntryPoint", - "name": "entryPoint", - "type": "address" - }, - { - "indexed": true, - "internalType": "bytes32", - "name": "credentialHex", - "type": "bytes32" - } - ], - "name": "SimpleAccountInitialized", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "implementation", - "type": "address" - } - ], - "name": "Upgraded", - "type": "event" - }, - { - "inputs": [], - "name": "UPGRADE_INTERFACE_VERSION", - "outputs": [{ "internalType": "string", "name": "", "type": "string" }], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "addDeposit", - "outputs": [], - "stateMutability": "payable", - "type": "function" - }, - { - "inputs": [], - "name": "credentialHex", - "outputs": [{ "internalType": "bytes32", "name": "", "type": "bytes32" }], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "entryPoint", - "outputs": [ - { "internalType": "contract IEntryPoint", "name": "", "type": "address" } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { "internalType": "address", "name": "dest", "type": "address" }, - { "internalType": "uint256", "name": "value", "type": "uint256" }, - { "internalType": "bytes", "name": "func", "type": "bytes" } - ], - "name": "execute", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { "internalType": "address[]", "name": "dest", "type": "address[]" }, - { "internalType": "uint256[]", "name": "value", "type": "uint256[]" }, - { "internalType": "bytes[]", "name": "func", "type": "bytes[]" } - ], - "name": "executeBatch", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "getCredentialIdBase64", - "outputs": [{ "internalType": "string", "name": "", "type": "string" }], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "getDeposit", - "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "getNonce", - "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes32", - "name": "aCredentialHex", - "type": "bytes32" - }, - { "internalType": "uint256", "name": "x", "type": "uint256" }, - { "internalType": "uint256", "name": "y", "type": "uint256" } - ], - "name": "initialize", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { "internalType": "address", "name": "", "type": "address" }, - { "internalType": "address", "name": "", "type": "address" }, - { "internalType": "uint256[]", "name": "", "type": "uint256[]" }, - { "internalType": "uint256[]", "name": "", "type": "uint256[]" }, - { "internalType": "bytes", "name": "", "type": "bytes" } - ], - "name": "onERC1155BatchReceived", - "outputs": [{ "internalType": "bytes4", "name": "", "type": "bytes4" }], - "stateMutability": "pure", - "type": "function" - }, - { - "inputs": [ - { "internalType": "address", "name": "", "type": "address" }, - { "internalType": "address", "name": "", "type": "address" }, - { "internalType": "uint256", "name": "", "type": "uint256" }, - { "internalType": "uint256", "name": "", "type": "uint256" }, - { "internalType": "bytes", "name": "", "type": "bytes" } - ], - "name": "onERC1155Received", - "outputs": [{ "internalType": "bytes4", "name": "", "type": "bytes4" }], - "stateMutability": "pure", - "type": "function" - }, - { - "inputs": [ - { "internalType": "address", "name": "", "type": "address" }, - { "internalType": "address", "name": "", "type": "address" }, - { "internalType": "uint256", "name": "", "type": "uint256" }, - { "internalType": "bytes", "name": "", "type": "bytes" } - ], - "name": "onERC721Received", - "outputs": [{ "internalType": "bytes4", "name": "", "type": "bytes4" }], - "stateMutability": "pure", - "type": "function" - }, - { - "inputs": [], - "name": "proxiableUUID", - "outputs": [{ "internalType": "bytes32", "name": "", "type": "bytes32" }], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], - "name": "publicKey", - "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { "internalType": "bytes4", "name": "interfaceId", "type": "bytes4" } - ], - "name": "supportsInterface", - "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { "internalType": "address", "name": "", "type": "address" }, - { "internalType": "address", "name": "", "type": "address" }, - { "internalType": "address", "name": "", "type": "address" }, - { "internalType": "uint256", "name": "", "type": "uint256" }, - { "internalType": "bytes", "name": "", "type": "bytes" }, - { "internalType": "bytes", "name": "", "type": "bytes" } - ], - "name": "tokensReceived", - "outputs": [], - "stateMutability": "pure", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "newImplementation", - "type": "address" - }, - { "internalType": "bytes", "name": "data", "type": "bytes" } - ], - "name": "upgradeToAndCall", - "outputs": [], - "stateMutability": "payable", - "type": "function" - }, - { - "inputs": [ - { - "components": [ - { "internalType": "address", "name": "sender", "type": "address" }, - { "internalType": "uint256", "name": "nonce", "type": "uint256" }, - { "internalType": "bytes", "name": "initCode", "type": "bytes" }, - { "internalType": "bytes", "name": "callData", "type": "bytes" }, - { - "internalType": "uint256", - "name": "callGasLimit", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "verificationGasLimit", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "preVerificationGas", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "maxFeePerGas", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "maxPriorityFeePerGas", - "type": "uint256" - }, - { - "internalType": "bytes", - "name": "paymasterAndData", - "type": "bytes" - }, - { "internalType": "bytes", "name": "signature", "type": "bytes" } - ], - "internalType": "struct UserOperation", - "name": "userOp", - "type": "tuple" - }, - { "internalType": "bytes32", "name": "userOpHash", "type": "bytes32" }, - { - "internalType": "uint256", - "name": "missingAccountFunds", - "type": "uint256" - } - ], - "name": "validateUserOp", - "outputs": [ - { "internalType": "uint256", "name": "validationData", "type": "uint256" } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address payable", - "name": "withdrawAddress", - "type": "address" - }, - { "internalType": "uint256", "name": "amount", "type": "uint256" } - ], - "name": "withdrawDepositTo", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { "stateMutability": "payable", "type": "receive" } -] diff --git a/lib/src/abis/simplePasskeyAccount.g.dart b/lib/src/abis/simplePasskeyAccount.g.dart deleted file mode 100644 index dc42741..0000000 --- a/lib/src/abis/simplePasskeyAccount.g.dart +++ /dev/null @@ -1,549 +0,0 @@ -// Generated code, do not modify. Run `build_runner build` to re-generate! -// @dart=2.12 -// ignore_for_file: no_leading_underscores_for_library_prefixes -import 'package:web3dart/web3dart.dart' as _i1; -import 'dart:typed_data' as _i2; - -final _contractAbi = _i1.ContractAbi.fromJson( - '[{"inputs":[{"internalType":"contract IEntryPoint","name":"anEntryPoint","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"address","name":"target","type":"address"}],"name":"AddressEmptyCode","type":"error"},{"inputs":[{"internalType":"address","name":"implementation","type":"address"}],"name":"ERC1967InvalidImplementation","type":"error"},{"inputs":[],"name":"ERC1967NonPayable","type":"error"},{"inputs":[],"name":"FailedInnerCall","type":"error"},{"inputs":[],"name":"InvalidInitialization","type":"error"},{"inputs":[],"name":"NotInitializing","type":"error"},{"inputs":[],"name":"UUPSUnauthorizedCallContext","type":"error"},{"inputs":[{"internalType":"bytes32","name":"slot","type":"bytes32"}],"name":"UUPSUnsupportedProxiableUUID","type":"error"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint64","name":"version","type":"uint64"}],"name":"Initialized","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"contract IEntryPoint","name":"entryPoint","type":"address"},{"indexed":true,"internalType":"bytes32","name":"credentialHex","type":"bytes32"}],"name":"SimpleAccountInitialized","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"implementation","type":"address"}],"name":"Upgraded","type":"event"},{"inputs":[],"name":"UPGRADE_INTERFACE_VERSION","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"addDeposit","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"credentialHex","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"entryPoint","outputs":[{"internalType":"contract IEntryPoint","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"dest","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"bytes","name":"func","type":"bytes"}],"name":"execute","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"dest","type":"address[]"},{"internalType":"uint256[]","name":"value","type":"uint256[]"},{"internalType":"bytes[]","name":"func","type":"bytes[]"}],"name":"executeBatch","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"getCredentialIdBase64","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getDeposit","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getNonce","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"aCredentialHex","type":"bytes32"},{"internalType":"uint256","name":"x","type":"uint256"},{"internalType":"uint256","name":"y","type":"uint256"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256[]","name":"","type":"uint256[]"},{"internalType":"uint256[]","name":"","type":"uint256[]"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"onERC1155BatchReceived","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"onERC1155Received","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"onERC721Received","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"proxiableUUID","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"publicKey","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"bytes","name":"","type":"bytes"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"tokensReceived","outputs":[],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"newImplementation","type":"address"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"upgradeToAndCall","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"uint256","name":"nonce","type":"uint256"},{"internalType":"bytes","name":"initCode","type":"bytes"},{"internalType":"bytes","name":"callData","type":"bytes"},{"internalType":"uint256","name":"callGasLimit","type":"uint256"},{"internalType":"uint256","name":"verificationGasLimit","type":"uint256"},{"internalType":"uint256","name":"preVerificationGas","type":"uint256"},{"internalType":"uint256","name":"maxFeePerGas","type":"uint256"},{"internalType":"uint256","name":"maxPriorityFeePerGas","type":"uint256"},{"internalType":"bytes","name":"paymasterAndData","type":"bytes"},{"internalType":"bytes","name":"signature","type":"bytes"}],"internalType":"struct UserOperation","name":"userOp","type":"tuple"},{"internalType":"bytes32","name":"userOpHash","type":"bytes32"},{"internalType":"uint256","name":"missingAccountFunds","type":"uint256"}],"name":"validateUserOp","outputs":[{"internalType":"uint256","name":"validationData","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address payable","name":"withdrawAddress","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"withdrawDepositTo","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]', - 'SimplePasskeyAccount', -); - -class SimplePasskeyAccount extends _i1.GeneratedContract { - SimplePasskeyAccount({ - required _i1.EthereumAddress address, - required _i1.Web3Client client, - int? chainId, - }) : super( - _i1.DeployedContract( - _contractAbi, - address, - ), - client, - chainId, - ); - - /// The optional [atBlock] parameter can be used to view historical data. When - /// set, the function will be evaluated in the specified block. By default, the - /// latest on-chain block will be used. - Future UPGRADE_INTERFACE_VERSION({_i1.BlockNum? atBlock}) async { - final function = self.abi.functions[1]; - assert(checkSignature(function, 'ad3cb1cc')); - final params = []; - final response = await read( - function, - params, - atBlock, - ); - return (response[0] as String); - } - - /// The optional [transaction] parameter can be used to override parameters - /// like the gas price, nonce and max gas. The `data` and `to` fields will be - /// set by the contract. - Future addDeposit({ - required _i1.Credentials credentials, - _i1.Transaction? transaction, - }) async { - final function = self.abi.functions[2]; - assert(checkSignature(function, '4a58db19')); - final params = []; - return write( - credentials, - transaction, - function, - params, - ); - } - - /// The optional [atBlock] parameter can be used to view historical data. When - /// set, the function will be evaluated in the specified block. By default, the - /// latest on-chain block will be used. - Future<_i2.Uint8List> credentialHex({_i1.BlockNum? atBlock}) async { - final function = self.abi.functions[3]; - assert(checkSignature(function, 'f2de8bc6')); - final params = []; - final response = await read( - function, - params, - atBlock, - ); - return (response[0] as _i2.Uint8List); - } - - /// The optional [atBlock] parameter can be used to view historical data. When - /// set, the function will be evaluated in the specified block. By default, the - /// latest on-chain block will be used. - Future<_i1.EthereumAddress> entryPoint({_i1.BlockNum? atBlock}) async { - final function = self.abi.functions[4]; - assert(checkSignature(function, 'b0d691fe')); - final params = []; - final response = await read( - function, - params, - atBlock, - ); - return (response[0] as _i1.EthereumAddress); - } - - /// The optional [transaction] parameter can be used to override parameters - /// like the gas price, nonce and max gas. The `data` and `to` fields will be - /// set by the contract. - Future execute( - _i1.EthereumAddress dest, - BigInt value, - _i2.Uint8List func, { - required _i1.Credentials credentials, - _i1.Transaction? transaction, - }) async { - final function = self.abi.functions[5]; - assert(checkSignature(function, 'b61d27f6')); - final params = [ - dest, - value, - func, - ]; - return write( - credentials, - transaction, - function, - params, - ); - } - - /// The optional [transaction] parameter can be used to override parameters - /// like the gas price, nonce and max gas. The `data` and `to` fields will be - /// set by the contract. - Future executeBatch( - List<_i1.EthereumAddress> dest, - List value, - List<_i2.Uint8List> func, { - required _i1.Credentials credentials, - _i1.Transaction? transaction, - }) async { - final function = self.abi.functions[6]; - assert(checkSignature(function, '47e1da2a')); - final params = [ - dest, - value, - func, - ]; - return write( - credentials, - transaction, - function, - params, - ); - } - - /// The optional [atBlock] parameter can be used to view historical data. When - /// set, the function will be evaluated in the specified block. By default, the - /// latest on-chain block will be used. - Future getCredentialIdBase64({_i1.BlockNum? atBlock}) async { - final function = self.abi.functions[7]; - assert(checkSignature(function, '3a941022')); - final params = []; - final response = await read( - function, - params, - atBlock, - ); - return (response[0] as String); - } - - /// The optional [atBlock] parameter can be used to view historical data. When - /// set, the function will be evaluated in the specified block. By default, the - /// latest on-chain block will be used. - Future getDeposit({_i1.BlockNum? atBlock}) async { - final function = self.abi.functions[8]; - assert(checkSignature(function, 'c399ec88')); - final params = []; - final response = await read( - function, - params, - atBlock, - ); - return (response[0] as BigInt); - } - - /// The optional [atBlock] parameter can be used to view historical data. When - /// set, the function will be evaluated in the specified block. By default, the - /// latest on-chain block will be used. - Future getNonce({_i1.BlockNum? atBlock}) async { - final function = self.abi.functions[9]; - assert(checkSignature(function, 'd087d288')); - final params = []; - final response = await read( - function, - params, - atBlock, - ); - return (response[0] as BigInt); - } - - /// The optional [transaction] parameter can be used to override parameters - /// like the gas price, nonce and max gas. The `data` and `to` fields will be - /// set by the contract. - Future initialize( - _i2.Uint8List aCredentialHex, - BigInt x, - BigInt y, { - required _i1.Credentials credentials, - _i1.Transaction? transaction, - }) async { - final function = self.abi.functions[10]; - assert(checkSignature(function, 'f0fd7f64')); - final params = [ - aCredentialHex, - x, - y, - ]; - return write( - credentials, - transaction, - function, - params, - ); - } - - /// The optional [atBlock] parameter can be used to view historical data. When - /// set, the function will be evaluated in the specified block. By default, the - /// latest on-chain block will be used. - Future<_i2.Uint8List> onERC1155BatchReceived( - _i1.EthereumAddress $param9, - _i1.EthereumAddress $param10, - List $param11, - List $param12, - _i2.Uint8List $param13, { - _i1.BlockNum? atBlock, - }) async { - final function = self.abi.functions[11]; - assert(checkSignature(function, 'bc197c81')); - final params = [ - $param9, - $param10, - $param11, - $param12, - $param13, - ]; - final response = await read( - function, - params, - atBlock, - ); - return (response[0] as _i2.Uint8List); - } - - /// The optional [atBlock] parameter can be used to view historical data. When - /// set, the function will be evaluated in the specified block. By default, the - /// latest on-chain block will be used. - Future<_i2.Uint8List> onERC1155Received( - _i1.EthereumAddress $param14, - _i1.EthereumAddress $param15, - BigInt $param16, - BigInt $param17, - _i2.Uint8List $param18, { - _i1.BlockNum? atBlock, - }) async { - final function = self.abi.functions[12]; - assert(checkSignature(function, 'f23a6e61')); - final params = [ - $param14, - $param15, - $param16, - $param17, - $param18, - ]; - final response = await read( - function, - params, - atBlock, - ); - return (response[0] as _i2.Uint8List); - } - - /// The optional [atBlock] parameter can be used to view historical data. When - /// set, the function will be evaluated in the specified block. By default, the - /// latest on-chain block will be used. - Future<_i2.Uint8List> onERC721Received( - _i1.EthereumAddress $param19, - _i1.EthereumAddress $param20, - BigInt $param21, - _i2.Uint8List $param22, { - _i1.BlockNum? atBlock, - }) async { - final function = self.abi.functions[13]; - assert(checkSignature(function, '150b7a02')); - final params = [ - $param19, - $param20, - $param21, - $param22, - ]; - final response = await read( - function, - params, - atBlock, - ); - return (response[0] as _i2.Uint8List); - } - - /// The optional [atBlock] parameter can be used to view historical data. When - /// set, the function will be evaluated in the specified block. By default, the - /// latest on-chain block will be used. - Future<_i2.Uint8List> proxiableUUID({_i1.BlockNum? atBlock}) async { - final function = self.abi.functions[14]; - assert(checkSignature(function, '52d1902d')); - final params = []; - final response = await read( - function, - params, - atBlock, - ); - return (response[0] as _i2.Uint8List); - } - - /// The optional [atBlock] parameter can be used to view historical data. When - /// set, the function will be evaluated in the specified block. By default, the - /// latest on-chain block will be used. - Future publicKey( - BigInt $param23, { - _i1.BlockNum? atBlock, - }) async { - final function = self.abi.functions[15]; - assert(checkSignature(function, '8940aebe')); - final params = [$param23]; - final response = await read( - function, - params, - atBlock, - ); - return (response[0] as BigInt); - } - - /// The optional [atBlock] parameter can be used to view historical data. When - /// set, the function will be evaluated in the specified block. By default, the - /// latest on-chain block will be used. - Future supportsInterface( - _i2.Uint8List interfaceId, { - _i1.BlockNum? atBlock, - }) async { - final function = self.abi.functions[16]; - assert(checkSignature(function, '01ffc9a7')); - final params = [interfaceId]; - final response = await read( - function, - params, - atBlock, - ); - return (response[0] as bool); - } - - /// The optional [atBlock] parameter can be used to view historical data. When - /// set, the function will be evaluated in the specified block. By default, the - /// latest on-chain block will be used. - Future tokensReceived( - _i1.EthereumAddress $param25, - _i1.EthereumAddress $param26, - _i1.EthereumAddress $param27, - BigInt $param28, - _i2.Uint8List $param29, - _i2.Uint8List $param30, { - _i1.BlockNum? atBlock, - }) async { - final function = self.abi.functions[17]; - assert(checkSignature(function, '0023de29')); - final params = [ - $param25, - $param26, - $param27, - $param28, - $param29, - $param30, - ]; - final response = await read( - function, - params, - atBlock, - ); - } - - /// The optional [transaction] parameter can be used to override parameters - /// like the gas price, nonce and max gas. The `data` and `to` fields will be - /// set by the contract. - Future upgradeToAndCall( - _i1.EthereumAddress newImplementation, - _i2.Uint8List data, { - required _i1.Credentials credentials, - _i1.Transaction? transaction, - }) async { - final function = self.abi.functions[18]; - assert(checkSignature(function, '4f1ef286')); - final params = [ - newImplementation, - data, - ]; - return write( - credentials, - transaction, - function, - params, - ); - } - - /// The optional [transaction] parameter can be used to override parameters - /// like the gas price, nonce and max gas. The `data` and `to` fields will be - /// set by the contract. - Future validateUserOp( - dynamic userOp, - _i2.Uint8List userOpHash, - BigInt missingAccountFunds, { - required _i1.Credentials credentials, - _i1.Transaction? transaction, - }) async { - final function = self.abi.functions[19]; - assert(checkSignature(function, '3a871cdd')); - final params = [ - userOp, - userOpHash, - missingAccountFunds, - ]; - return write( - credentials, - transaction, - function, - params, - ); - } - - /// The optional [transaction] parameter can be used to override parameters - /// like the gas price, nonce and max gas. The `data` and `to` fields will be - /// set by the contract. - Future withdrawDepositTo( - _i1.EthereumAddress withdrawAddress, - BigInt amount, { - required _i1.Credentials credentials, - _i1.Transaction? transaction, - }) async { - final function = self.abi.functions[20]; - assert(checkSignature(function, '4d44560d')); - final params = [ - withdrawAddress, - amount, - ]; - return write( - credentials, - transaction, - function, - params, - ); - } - - /// Returns a live stream of all Initialized events emitted by this contract. - Stream initializedEvents({ - _i1.BlockNum? fromBlock, - _i1.BlockNum? toBlock, - }) { - final event = self.event('Initialized'); - final filter = _i1.FilterOptions.events( - contract: self, - event: event, - fromBlock: fromBlock, - toBlock: toBlock, - ); - return client.events(filter).map((_i1.FilterEvent result) { - final decoded = event.decodeResults( - result.topics!, - result.data!, - ); - return Initialized( - decoded, - result, - ); - }); - } - - /// Returns a live stream of all SimpleAccountInitialized events emitted by this contract. - Stream simpleAccountInitializedEvents({ - _i1.BlockNum? fromBlock, - _i1.BlockNum? toBlock, - }) { - final event = self.event('SimpleAccountInitialized'); - final filter = _i1.FilterOptions.events( - contract: self, - event: event, - fromBlock: fromBlock, - toBlock: toBlock, - ); - return client.events(filter).map((_i1.FilterEvent result) { - final decoded = event.decodeResults( - result.topics!, - result.data!, - ); - return SimpleAccountInitialized( - decoded, - result, - ); - }); - } - - /// Returns a live stream of all Upgraded events emitted by this contract. - Stream upgradedEvents({ - _i1.BlockNum? fromBlock, - _i1.BlockNum? toBlock, - }) { - final event = self.event('Upgraded'); - final filter = _i1.FilterOptions.events( - contract: self, - event: event, - fromBlock: fromBlock, - toBlock: toBlock, - ); - return client.events(filter).map((_i1.FilterEvent result) { - final decoded = event.decodeResults( - result.topics!, - result.data!, - ); - return Upgraded( - decoded, - result, - ); - }); - } -} - -class Initialized { - Initialized( - List response, - this.event, - ) : version = (response[0] as BigInt); - - final BigInt version; - - final _i1.FilterEvent event; -} - -class SimpleAccountInitialized { - SimpleAccountInitialized( - List response, - this.event, - ) : entryPoint = (response[0] as _i1.EthereumAddress), - credentialHex = (response[1] as _i2.Uint8List); - - final _i1.EthereumAddress entryPoint; - - final _i2.Uint8List credentialHex; - - final _i1.FilterEvent event; -} - -class Upgraded { - Upgraded( - List response, - this.event, - ) : implementation = (response[0] as _i1.EthereumAddress); - - final _i1.EthereumAddress implementation; - - final _i1.FilterEvent event; -} diff --git a/lib/src/abis/token.abi.json b/lib/src/abis/token.abi.json deleted file mode 100644 index 7f9f9a7..0000000 --- a/lib/src/abis/token.abi.json +++ /dev/null @@ -1,201 +0,0 @@ -[ - { - "constant": true, - "inputs": [], - "name": "name", - "outputs": [{ "name": "", "type": "string" }], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { "name": "spender", "type": "address" }, - { "name": "value", "type": "uint256" } - ], - "name": "approve", - "outputs": [{ "name": "", "type": "bool" }], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": true, - "inputs": [], - "name": "totalSupply", - "outputs": [{ "name": "", "type": "uint256" }], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { "name": "from", "type": "address" }, - { "name": "to", "type": "address" }, - { "name": "value", "type": "uint256" } - ], - "name": "transferFrom", - "outputs": [{ "name": "", "type": "bool" }], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": true, - "inputs": [], - "name": "decimals", - "outputs": [{ "name": "", "type": "uint8" }], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { "name": "spender", "type": "address" }, - { "name": "addedValue", "type": "uint256" } - ], - "name": "increaseAllowance", - "outputs": [{ "name": "", "type": "bool" }], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { "name": "to", "type": "address" }, - { "name": "value", "type": "uint256" } - ], - "name": "mint", - "outputs": [{ "name": "", "type": "bool" }], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": true, - "inputs": [{ "name": "owner", "type": "address" }], - "name": "balanceOf", - "outputs": [{ "name": "", "type": "uint256" }], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": true, - "inputs": [], - "name": "symbol", - "outputs": [{ "name": "", "type": "string" }], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": false, - "inputs": [{ "name": "account", "type": "address" }], - "name": "addMinter", - "outputs": [], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": false, - "inputs": [], - "name": "renounceMinter", - "outputs": [], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { "name": "spender", "type": "address" }, - { "name": "subtractedValue", "type": "uint256" } - ], - "name": "decreaseAllowance", - "outputs": [{ "name": "", "type": "bool" }], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { "name": "to", "type": "address" }, - { "name": "value", "type": "uint256" } - ], - "name": "transfer", - "outputs": [{ "name": "", "type": "bool" }], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": true, - "inputs": [{ "name": "account", "type": "address" }], - "name": "isMinter", - "outputs": [{ "name": "", "type": "bool" }], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": true, - "inputs": [ - { "name": "owner", "type": "address" }, - { "name": "spender", "type": "address" } - ], - "name": "allowance", - "outputs": [{ "name": "", "type": "uint256" }], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { "name": "name", "type": "string" }, - { "name": "symbol", "type": "string" }, - { "name": "decimals", "type": "uint8" } - ], - "payable": false, - "stateMutability": "nonpayable", - "type": "constructor" - }, - { - "anonymous": false, - "inputs": [{ "indexed": true, "name": "account", "type": "address" }], - "name": "MinterAdded", - "type": "event" - }, - { - "anonymous": false, - "inputs": [{ "indexed": true, "name": "account", "type": "address" }], - "name": "MinterRemoved", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { "indexed": true, "name": "from", "type": "address" }, - { "indexed": true, "name": "to", "type": "address" }, - { "indexed": false, "name": "value", "type": "uint256" } - ], - "name": "Transfer", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { "indexed": true, "name": "owner", "type": "address" }, - { "indexed": true, "name": "spender", "type": "address" }, - { "indexed": false, "name": "value", "type": "uint256" } - ], - "name": "Approval", - "type": "event" - } -] diff --git a/lib/src/abis/token.g.dart b/lib/src/abis/token.g.dart deleted file mode 100644 index ae78e35..0000000 --- a/lib/src/abis/token.g.dart +++ /dev/null @@ -1,471 +0,0 @@ -// Generated code, do not modify. Run `build_runner build` to re-generate! -// @dart=2.12 -// ignore_for_file: no_leading_underscores_for_library_prefixes -import 'package:web3dart/web3dart.dart' as _i1; - -final _contractAbi = _i1.ContractAbi.fromJson( - '[{"constant":true,"inputs":[],"name":"name","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"spender","type":"address"},{"name":"value","type":"uint256"}],"name":"approve","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"totalSupply","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"from","type":"address"},{"name":"to","type":"address"},{"name":"value","type":"uint256"}],"name":"transferFrom","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"decimals","outputs":[{"name":"","type":"uint8"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"spender","type":"address"},{"name":"addedValue","type":"uint256"}],"name":"increaseAllowance","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"to","type":"address"},{"name":"value","type":"uint256"}],"name":"mint","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"symbol","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"account","type":"address"}],"name":"addMinter","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"renounceMinter","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"spender","type":"address"},{"name":"subtractedValue","type":"uint256"}],"name":"decreaseAllowance","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"to","type":"address"},{"name":"value","type":"uint256"}],"name":"transfer","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"account","type":"address"}],"name":"isMinter","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"owner","type":"address"},{"name":"spender","type":"address"}],"name":"allowance","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"inputs":[{"name":"name","type":"string"},{"name":"symbol","type":"string"},{"name":"decimals","type":"uint8"}],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"name":"account","type":"address"}],"name":"MinterAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"account","type":"address"}],"name":"MinterRemoved","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"from","type":"address"},{"indexed":true,"name":"to","type":"address"},{"indexed":false,"name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"owner","type":"address"},{"indexed":true,"name":"spender","type":"address"},{"indexed":false,"name":"value","type":"uint256"}],"name":"Approval","type":"event"}]', - 'Token', -); - -class Token extends _i1.GeneratedContract { - Token({ - required _i1.EthereumAddress address, - required _i1.Web3Client client, - int? chainId, - }) : super( - _i1.DeployedContract( - _contractAbi, - address, - ), - client, - chainId, - ); - - /// The optional [atBlock] parameter can be used to view historical data. When - /// set, the function will be evaluated in the specified block. By default, the - /// latest on-chain block will be used. - Future name({_i1.BlockNum? atBlock}) async { - final function = self.abi.functions[0]; - assert(checkSignature(function, '06fdde03')); - final params = []; - final response = await read( - function, - params, - atBlock, - ); - return (response[0] as String); - } - - /// The optional [transaction] parameter can be used to override parameters - /// like the gas price, nonce and max gas. The `data` and `to` fields will be - /// set by the contract. - Future approve( - _i1.EthereumAddress spender, - BigInt value, { - required _i1.Credentials credentials, - _i1.Transaction? transaction, - }) async { - final function = self.abi.functions[1]; - assert(checkSignature(function, '095ea7b3')); - final params = [ - spender, - value, - ]; - return write( - credentials, - transaction, - function, - params, - ); - } - - /// The optional [atBlock] parameter can be used to view historical data. When - /// set, the function will be evaluated in the specified block. By default, the - /// latest on-chain block will be used. - Future totalSupply({_i1.BlockNum? atBlock}) async { - final function = self.abi.functions[2]; - assert(checkSignature(function, '18160ddd')); - final params = []; - final response = await read( - function, - params, - atBlock, - ); - return (response[0] as BigInt); - } - - /// The optional [transaction] parameter can be used to override parameters - /// like the gas price, nonce and max gas. The `data` and `to` fields will be - /// set by the contract. - Future transferFrom( - _i1.EthereumAddress from, - _i1.EthereumAddress to, - BigInt value, { - required _i1.Credentials credentials, - _i1.Transaction? transaction, - }) async { - final function = self.abi.functions[3]; - assert(checkSignature(function, '23b872dd')); - final params = [ - from, - to, - value, - ]; - return write( - credentials, - transaction, - function, - params, - ); - } - - /// The optional [atBlock] parameter can be used to view historical data. When - /// set, the function will be evaluated in the specified block. By default, the - /// latest on-chain block will be used. - Future decimals({_i1.BlockNum? atBlock}) async { - final function = self.abi.functions[4]; - assert(checkSignature(function, '313ce567')); - final params = []; - final response = await read( - function, - params, - atBlock, - ); - return (response[0] as BigInt); - } - - /// The optional [transaction] parameter can be used to override parameters - /// like the gas price, nonce and max gas. The `data` and `to` fields will be - /// set by the contract. - Future increaseAllowance( - _i1.EthereumAddress spender, - BigInt addedValue, { - required _i1.Credentials credentials, - _i1.Transaction? transaction, - }) async { - final function = self.abi.functions[5]; - assert(checkSignature(function, '39509351')); - final params = [ - spender, - addedValue, - ]; - return write( - credentials, - transaction, - function, - params, - ); - } - - /// The optional [transaction] parameter can be used to override parameters - /// like the gas price, nonce and max gas. The `data` and `to` fields will be - /// set by the contract. - Future mint( - _i1.EthereumAddress to, - BigInt value, { - required _i1.Credentials credentials, - _i1.Transaction? transaction, - }) async { - final function = self.abi.functions[6]; - assert(checkSignature(function, '40c10f19')); - final params = [ - to, - value, - ]; - return write( - credentials, - transaction, - function, - params, - ); - } - - /// The optional [atBlock] parameter can be used to view historical data. When - /// set, the function will be evaluated in the specified block. By default, the - /// latest on-chain block will be used. - Future balanceOf( - _i1.EthereumAddress owner, { - _i1.BlockNum? atBlock, - }) async { - final function = self.abi.functions[7]; - assert(checkSignature(function, '70a08231')); - final params = [owner]; - final response = await read( - function, - params, - atBlock, - ); - return (response[0] as BigInt); - } - - /// The optional [atBlock] parameter can be used to view historical data. When - /// set, the function will be evaluated in the specified block. By default, the - /// latest on-chain block will be used. - Future symbol({_i1.BlockNum? atBlock}) async { - final function = self.abi.functions[8]; - assert(checkSignature(function, '95d89b41')); - final params = []; - final response = await read( - function, - params, - atBlock, - ); - return (response[0] as String); - } - - /// The optional [transaction] parameter can be used to override parameters - /// like the gas price, nonce and max gas. The `data` and `to` fields will be - /// set by the contract. - Future addMinter( - _i1.EthereumAddress account, { - required _i1.Credentials credentials, - _i1.Transaction? transaction, - }) async { - final function = self.abi.functions[9]; - assert(checkSignature(function, '983b2d56')); - final params = [account]; - return write( - credentials, - transaction, - function, - params, - ); - } - - /// The optional [transaction] parameter can be used to override parameters - /// like the gas price, nonce and max gas. The `data` and `to` fields will be - /// set by the contract. - Future renounceMinter({ - required _i1.Credentials credentials, - _i1.Transaction? transaction, - }) async { - final function = self.abi.functions[10]; - assert(checkSignature(function, '98650275')); - final params = []; - return write( - credentials, - transaction, - function, - params, - ); - } - - /// The optional [transaction] parameter can be used to override parameters - /// like the gas price, nonce and max gas. The `data` and `to` fields will be - /// set by the contract. - Future decreaseAllowance( - _i1.EthereumAddress spender, - BigInt subtractedValue, { - required _i1.Credentials credentials, - _i1.Transaction? transaction, - }) async { - final function = self.abi.functions[11]; - assert(checkSignature(function, 'a457c2d7')); - final params = [ - spender, - subtractedValue, - ]; - return write( - credentials, - transaction, - function, - params, - ); - } - - /// The optional [transaction] parameter can be used to override parameters - /// like the gas price, nonce and max gas. The `data` and `to` fields will be - /// set by the contract. - Future transfer( - _i1.EthereumAddress to, - BigInt value, { - required _i1.Credentials credentials, - _i1.Transaction? transaction, - }) async { - final function = self.abi.functions[12]; - assert(checkSignature(function, 'a9059cbb')); - final params = [ - to, - value, - ]; - return write( - credentials, - transaction, - function, - params, - ); - } - - /// The optional [atBlock] parameter can be used to view historical data. When - /// set, the function will be evaluated in the specified block. By default, the - /// latest on-chain block will be used. - Future isMinter( - _i1.EthereumAddress account, { - _i1.BlockNum? atBlock, - }) async { - final function = self.abi.functions[13]; - assert(checkSignature(function, 'aa271e1a')); - final params = [account]; - final response = await read( - function, - params, - atBlock, - ); - return (response[0] as bool); - } - - /// The optional [atBlock] parameter can be used to view historical data. When - /// set, the function will be evaluated in the specified block. By default, the - /// latest on-chain block will be used. - Future allowance( - _i1.EthereumAddress owner, - _i1.EthereumAddress spender, { - _i1.BlockNum? atBlock, - }) async { - final function = self.abi.functions[14]; - assert(checkSignature(function, 'dd62ed3e')); - final params = [ - owner, - spender, - ]; - final response = await read( - function, - params, - atBlock, - ); - return (response[0] as BigInt); - } - - /// Returns a live stream of all MinterAdded events emitted by this contract. - Stream minterAddedEvents({ - _i1.BlockNum? fromBlock, - _i1.BlockNum? toBlock, - }) { - final event = self.event('MinterAdded'); - final filter = _i1.FilterOptions.events( - contract: self, - event: event, - fromBlock: fromBlock, - toBlock: toBlock, - ); - return client.events(filter).map((_i1.FilterEvent result) { - final decoded = event.decodeResults( - result.topics!, - result.data!, - ); - return MinterAdded( - decoded, - result, - ); - }); - } - - /// Returns a live stream of all MinterRemoved events emitted by this contract. - Stream minterRemovedEvents({ - _i1.BlockNum? fromBlock, - _i1.BlockNum? toBlock, - }) { - final event = self.event('MinterRemoved'); - final filter = _i1.FilterOptions.events( - contract: self, - event: event, - fromBlock: fromBlock, - toBlock: toBlock, - ); - return client.events(filter).map((_i1.FilterEvent result) { - final decoded = event.decodeResults( - result.topics!, - result.data!, - ); - return MinterRemoved( - decoded, - result, - ); - }); - } - - /// Returns a live stream of all Transfer events emitted by this contract. - Stream transferEvents({ - _i1.BlockNum? fromBlock, - _i1.BlockNum? toBlock, - }) { - final event = self.event('Transfer'); - final filter = _i1.FilterOptions.events( - contract: self, - event: event, - fromBlock: fromBlock, - toBlock: toBlock, - ); - return client.events(filter).map((_i1.FilterEvent result) { - final decoded = event.decodeResults( - result.topics!, - result.data!, - ); - return Transfer( - decoded, - result, - ); - }); - } - - /// Returns a live stream of all Approval events emitted by this contract. - Stream approvalEvents({ - _i1.BlockNum? fromBlock, - _i1.BlockNum? toBlock, - }) { - final event = self.event('Approval'); - final filter = _i1.FilterOptions.events( - contract: self, - event: event, - fromBlock: fromBlock, - toBlock: toBlock, - ); - return client.events(filter).map((_i1.FilterEvent result) { - final decoded = event.decodeResults( - result.topics!, - result.data!, - ); - return Approval( - decoded, - result, - ); - }); - } -} - -class MinterAdded { - MinterAdded( - List response, - this.event, - ) : account = (response[0] as _i1.EthereumAddress); - - final _i1.EthereumAddress account; - - final _i1.FilterEvent event; -} - -class MinterRemoved { - MinterRemoved( - List response, - this.event, - ) : account = (response[0] as _i1.EthereumAddress); - - final _i1.EthereumAddress account; - - final _i1.FilterEvent event; -} - -class Transfer { - Transfer( - List response, - this.event, - ) : from = (response[0] as _i1.EthereumAddress), - to = (response[1] as _i1.EthereumAddress), - value = (response[2] as BigInt); - - final _i1.EthereumAddress from; - - final _i1.EthereumAddress to; - - final BigInt value; - - final _i1.FilterEvent event; -} - -class Approval { - Approval( - List response, - this.event, - ) : owner = (response[0] as _i1.EthereumAddress), - spender = (response[1] as _i1.EthereumAddress), - value = (response[2] as BigInt); - - final _i1.EthereumAddress owner; - - final _i1.EthereumAddress spender; - - final BigInt value; - - final _i1.FilterEvent event; -} diff --git a/lib/src/common/abi_coder.dart b/lib/src/common/abi_coder.dart deleted file mode 100644 index 408da54..0000000 --- a/lib/src/common/abi_coder.dart +++ /dev/null @@ -1,59 +0,0 @@ -part of 'common.dart'; - -/// Abstract base class for handling Ethereum's Application Binary Interface (ABI). -/// -/// The ABI is a data encoding scheme used in Ethereum for ABI encoding -/// and interaction with contracts within Ethereum. -// ignore: camel_case_types -class abi { - abi._(); - - /// Decodes a list of ABI-encoded types and values. - /// - /// Parameters: - /// - `types`: A list of string types describing the ABI types to decode. - /// - `value`: A [Uint8List] containing the ABI-encoded data to be decoded. - /// - /// Returns: - /// A list of decoded values with the specified type. - /// - /// Example: - /// ```dart - /// var decodedValues = abi.decode(['uint256', 'string'], encodedData); - /// ``` - static List decode(List types, Uint8List value) { - List abiTypes = []; - for (String type in types) { - var abiType = parseAbiType(type); - abiTypes.add(abiType); - } - final parsedData = TupleType(abiTypes).decode(value.buffer, 0); - return parsedData.data; - } - - /// Encodes a list of types and values into ABI-encoded data. - /// - /// Parameters: - /// - `types`: A list of string types describing the ABI types. - /// - `values`: A list of dynamic values to be ABI-encoded. - /// - /// Returns: - /// A [Uint8List] containing the ABI-encoded types and values. - /// - /// Example: - /// ```dart - /// var encodedData = abi.encode(['uint256', 'string'], [BigInt.from(123), 'Hello']); - /// ``` - static Uint8List encode(List types, List values) { - List abiTypes = []; - LengthTrackingByteSink result = LengthTrackingByteSink(); - for (String type in types) { - var abiType = parseAbiType(type); - abiTypes.add(abiType); - } - TupleType(abiTypes).encode(values, result); - var resultBytes = result.asBytes(); - result.close(); - return resultBytes; - } -} diff --git a/lib/src/common/address.dart b/lib/src/common/address.dart deleted file mode 100644 index a6cb4fe..0000000 --- a/lib/src/common/address.dart +++ /dev/null @@ -1,71 +0,0 @@ -part of 'common.dart'; - -class Address extends EthereumAddress implements ENSResolverBase { - String? _ens; - - ChainBaseApiBase? client; - - Address(super.addressBytes, {bool ens = false, this.client}) { - _setEnsName(); - } - - factory Address.fromEthAddress(EthereumAddress ethAddress) { - return Address(ethAddress.addressBytes); - } - - @override - String? get ens => _ens; - - @override - Future? getEnsName() async { - return _ens ?? await _getEnsName(this); - } - - @override - Future? getEnsNameForAddress(EthereumAddress address) { - return _getEnsName(address); - } - - @override - Address withClient(ChainBaseApiBase client) { - return Address(addressBytes, client: client); - } - - Future? _getEnsName(EthereumAddress address) { - return client?.reverseENSAddress(address).then((value) => value.data?.name); - } - - Future _setEnsName() async { - _getEnsName(this)?.then((name) { - _ens = name; - }).catchError((err) { - _ens = null; - }); - } - - /// Creates an instance of Address from an ENS name. - /// - /// - [name]: The ENS name. - /// - /// Returns a [Future] that completes with an instance of Address. - static Future? fromEns(String name, {ChainBaseApiBase? client}) { - return client - ?.resolveENSName(name) - .then((value) => value.data?.address) - .then((address) => address == null - ? null - : Address(EthereumAddress.fromHex(address).addressBytes)); - } -} - -extension AddressExtension on EthereumAddress { - String avatarUrl() { - return 'https://effigy.im/a/$hex.svg'; - } - - String formattedAddress({int length = 6}) { - final prefix = hex.substring(0, 2 + length); - final suffix = hex.substring(hex.length - length); - return '$prefix...$suffix'; - } -} diff --git a/lib/src/common/common.dart b/lib/src/common/common.dart deleted file mode 100644 index 041793f..0000000 --- a/lib/src/common/common.dart +++ /dev/null @@ -1,17 +0,0 @@ -library common; - -import 'dart:math'; -import 'dart:typed_data'; - -import 'package:web3dart/crypto.dart'; -import 'package:web3dart/web3dart.dart'; - -import '../../utils.dart'; -import '../../variance.dart'; -import '../abis/abis.dart' show ContractAbis; -import '../interfaces/interfaces.dart'; - -part 'abi_coder.dart'; -part 'address.dart'; -part 'contract.dart'; -part 'uint256.dart'; diff --git a/lib/src/common/contract.dart b/lib/src/common/contract.dart index f4eec72..fda0bef 100644 --- a/lib/src/common/contract.dart +++ b/lib/src/common/contract.dart @@ -1,60 +1,14 @@ -part of 'common.dart'; +part of '../../variance_dart.dart'; -/// A wrapper for interacting with deployed Ethereum contracts through [RPCProvider]. +/// A wrapper for interacting with deployed Ethereum contracts through [JsonRPCProvider]. class Contract { - RPCProviderBase _provider; + /// The remote procedure call (RPC) client used to communicate with the bundler. + final RPCBase rpc; Contract( - this._provider, + this.rpc, ); - RPCProviderBase get provider => _provider; - - set setProvider(RPCProviderBase provider) { - _provider = provider; - } - - /// Asynchronously calls a function on a smart contract with the provided parameters. - /// - /// Parameters: - /// - `contractAddress`: The [EthereumAddress] of the smart contract. - /// - `abi`: The [ContractAbi] representing the smart contract's ABI. - /// - `methodName`: The name of the method to call on the smart contract. - /// - `params`: Optional parameters for the function call. - /// - `sender`: The [EthereumAddress] of the sender, if applicable. - /// - /// Returns: - /// A [Future] that completes with a list of dynamic values representing the result of the function call. - /// - /// Example: - /// ```dart - /// var result = await call( - /// EthereumAddress.fromHex('0x9876543210abcdef9876543210abcdef98765432'), - /// myErc20ContractAbi, - /// 'balanceOf', - /// params: [ EthereumAddress.fromHex('0x9876543210abcdef9876543210abcdef98765432')], - /// ); - /// ``` - /// This method uses the an Ethereum jsonRPC to `staticcall` a function on the specified smart contract. - /// **Note:** This method does not support contract calls with state changes. - Future> call( - EthereumAddress contractAddress, ContractAbi abi, String methodName, - {List? params, EthereumAddress? sender}) { - final function = getContractFunction(methodName, contractAddress, abi); - final calldata = { - 'to': contractAddress.hex, - 'data': params != null - ? bytesToHex(function.encodeCall(params), - include0x: true, padToEvenLength: true) - : "0x", - if (sender != null) 'from': sender.hex, - }; - return _provider.send('eth_call', [ - calldata, - BlockNum.current().toBlockParam() - ]).then((value) => function.decodeReturnValues(value)); - } - /// Asynchronously checks whether a smart contract is deployed at the specified address. /// /// Parameters: @@ -77,7 +31,7 @@ class Contract { if (address == null) { return Future.value(false); } - final isDeployed = _provider + final isDeployed = rpc .send('eth_getCode', [address.hex, atBlock.toBlockParam()]) .then(hexToBytes) .then((value) => value.isNotEmpty); @@ -106,12 +60,53 @@ class Contract { if (address == null) { return Future.value(EtherAmount.zero()); } - return _provider + return rpc .send('eth_getBalance', [address.hex, atBlock.toBlockParam()]) .then(BigInt.parse) .then((value) => EtherAmount.fromBigInt(EtherUnit.wei, value)); } + /// Asynchronously calls a function on a smart contract with the provided parameters. + /// + /// Parameters: + /// - `contractAddress`: The [EthereumAddress] of the smart contract. + /// - `abi`: The [ContractAbi] representing the smart contract's ABI. + /// - `methodName`: The name of the method to call on the smart contract. + /// - `params`: Optional parameters for the function call. + /// - `sender`: The [EthereumAddress] of the sender, if applicable. + /// + /// Returns: + /// A [Future] that completes with a list of dynamic values representing the result of the function call. + /// + /// Example: + /// ```dart + /// var result = await read( + /// EthereumAddress.fromHex('0x9876543210abcdef9876543210abcdef98765432'), + /// myErc20ContractAbi, + /// 'balanceOf', + /// params: [ EthereumAddress.fromHex('0x9876543210abcdef9876543210abcdef98765432')], + /// ); + /// ``` + /// This method uses the an Ethereum jsonRPC to `staticcall` a function on the specified smart contract. + /// **Note:** This method does not support contract calls with state changes. + Future> read( + EthereumAddress contractAddress, ContractAbi abi, String methodName, + {List? params, EthereumAddress? sender}) { + final function = getContractFunction(methodName, contractAddress, abi); + final calldata = { + 'to': contractAddress.hex, + 'data': params != null + ? bytesToHex(function.encodeCall(params), + include0x: true, padToEvenLength: true) + : "0x", + if (sender != null) 'from': sender.hex, + }; + return rpc.send('eth_call', [ + calldata, + BlockNum.current().toBlockParam() + ]).then((value) => function.decodeReturnValues(value)); + } + /// Encodes an ERC-20 token approval function call. /// /// Parameters: @@ -139,7 +134,7 @@ class Contract { return encodeFunctionCall( 'approve', address, - ContractAbis.get('ERC20'), + ContractAbis.get('ERC20_Approve'), [spender, amount.getInWei], ); } @@ -171,7 +166,7 @@ class Contract { return encodeFunctionCall( 'transfer', address, - ContractAbis.get('ERC20'), + ContractAbis.get('ERC20_Transfer'), [recipient, amount.getInWei], ); } @@ -198,7 +193,7 @@ class Contract { static Uint8List encodeERC721ApproveCall( EthereumAddress contractAddress, EthereumAddress to, BigInt tokenId) { return encodeFunctionCall("approve", contractAddress, - ContractAbis.get("ERC721"), [to.hex, tokenId]); + ContractAbis.get("ERC721_Approve"), [to.hex, tokenId]); } /// Encodes an ERC-721 token safe transfer function call. @@ -224,8 +219,11 @@ class Contract { /// This method uses the ERC-721 contract ABI to return a `calldata` for 'safeTransferFrom' function call. static Uint8List encodeERC721SafeTransferCall(EthereumAddress contractAddress, EthereumAddress from, EthereumAddress to, BigInt tokenId) { - return encodeFunctionCall("safeTransferFrom", contractAddress, - ContractAbis.get("ERC721"), [from.hex, to.hex, tokenId]); + return encodeFunctionCall( + "safeTransferFrom", + contractAddress, + ContractAbis.get("ERC721_SafeTransferFrom"), + [from.hex, to.hex, tokenId]); } /// Encodes a function call for a smart contract. @@ -262,6 +260,7 @@ class Contract { /// - `to`: The [EthereumAddress] of the target recipient for the operation. /// - `amount`: The [EtherAmount] representing the amount to transfer, if applicable. /// - `innerCallData`: The [Uint8List] containing inner call data, if applicable. + /// - `isSafe`: An optional flag indicating whether the operation is a GnosisSafeOperation or not. defaults to false. /// /// Returns: /// A [Uint8List] containing the ABI-encoded data for the 'execute' function call. @@ -276,25 +275,28 @@ class Contract { /// ); // transfer to 0x1234567890abcdef1234567890abcdef12345678 with 1000000000000000000 wei /// ``` /// This method uses the 'execute' function ABI to encode the smart wallet operation. - static Uint8List execute(EthereumAddress? walletAddress, + static Uint8List execute(EthereumAddress walletAddress, {required EthereumAddress to, EtherAmount? amount, - Uint8List? innerCallData}) { + Uint8List? innerCallData, + bool isSafe = false}) { final params = [ to, amount?.getInWei ?? EtherAmount.zero().getInWei, innerCallData ?? Uint8List.fromList([]) ]; - if (walletAddress == null) { - throw SmartWalletError( - "Invlaid Operation, SmartWallet Address is undefined! (contract.execute)"); + String method = 'execute'; + + if (isSafe) { + method = 'executeUserOpWithErrorString'; + params.add(BigInt.zero); } return encodeFunctionCall( - 'execute', + method, walletAddress, - ContractAbis.get('execute'), + ContractAbis.get(method), params, ); } @@ -306,6 +308,7 @@ class Contract { /// - `recipients`: A list of [EthereumAddress] instances representing the recipients for each operation. /// - `amounts`: Optional list of [EtherAmount] instances representing the amounts to transfer for each operation. /// - `innerCalls`: Optional list of [Uint8List] instances containing inner call data for each operation. + /// - `isSafe`: An optional flag indicating whether the operation is a GnosisSafeOperation or not. defaults to false. /// /// Returns: /// A [Uint8List] containing the ABI-encoded data for the 'executeBatch' function call. @@ -327,28 +330,37 @@ class Contract { /// ``` /// This method uses the 'executeBatch' function ABI to encode the smart wallet batch operation. static Uint8List executeBatch( - {required EthereumAddress? walletAddress, + {required EthereumAddress walletAddress, required List recipients, List? amounts, - List? innerCalls}) { - final params = [ + List? innerCalls, + bool isSafe = false}) { + List params = [ recipients, amounts?.map((e) => e.getInWei) ?? [], innerCalls ?? Uint8List.fromList([]), ]; + if (innerCalls == null || innerCalls.isEmpty) { require(amounts != null && amounts.isNotEmpty, "malformed batch request"); } - if (walletAddress == null) { - throw SmartWalletError( - "Invlaid Operation, SmartWallet Address is undefined! (contract.executeBatch)"); + String method = 'executeBatch'; + + if (isSafe) { + method = 'executeUserOpWithErrorString'; + params = [ + recipients[0], // multisend contract + EtherAmount.zero().getInWei, // 0 value to be passed + innerCalls?[0], // the encoded multisend calldata + BigInt.one // specifying delegate call operation + ]; } return encodeFunctionCall( - 'executeBatch', + method, walletAddress, - ContractAbis.get('executeBatch'), + ContractAbis.get(method), params, ); } diff --git a/lib/src/common/factories.dart b/lib/src/common/factories.dart new file mode 100644 index 0000000..ced8352 --- /dev/null +++ b/lib/src/common/factories.dart @@ -0,0 +1,116 @@ +part of '../../variance_dart.dart'; + +/// A class that extends [P256AccountFactory] and implements [P256AccountFactoryBase]. +/// It creates an instance of [P256AccountFactory] with a custom [RPCBase] client. +/// Used to create instances of [SmartWallet] for P256 accounts. +class _P256AccountFactory extends P256AccountFactory + implements P256AccountFactoryBase { + /// Creates a new instance of [_P256AccountFactory]. + /// + /// [address] is the address of the account factory. + /// [chainId] is the ID of the blockchain chain. + /// [rpc] is the [RPCBase] client used for communication with the blockchain. + _P256AccountFactory({ + required super.address, + super.chainId, + required RPCBase rpc, + }) : super(client: Web3Client.custom(rpc)); +} + +/// A class that extends [SafeProxyFactory] and implements [SafeProxyFactoryBase]. +/// It creates an instance of [SafeProxyFactory] with a custom [RPCBase] client. +/// Used to create instances of [SmartWallet] for Safe accounts. +/// Additionally, it provides methods for getting the initializer data and predicting the Safe address. +class _SafeProxyFactory extends SafeProxyFactory + implements SafeProxyFactoryBase { + /// Creates a new instance of [_SafeProxyFactory]. + /// + /// [address] is the address of the Safe proxy factory. + /// [chainId] is the ID of the blockchain chain. + /// [rpc] is the [RPCBase] client used for communication with the blockchain. + _SafeProxyFactory({ + required super.address, + super.chainId, + required RPCBase rpc, + }) : super(client: Web3Client.custom(rpc)); + + /// Generates the initializer data for deploying a new Safe contract. + /// + /// [owners] is an iterable of owner addresses for the Safe. + /// [threshold] is the required number of confirmations for executing transactions. + /// [module] is the address of the Safe module to enable. + /// + /// Returns a [Uint8List] containing the encoded initializer data. + Uint8List getInitializer(Iterable owners, int threshold, + Safe4337ModuleAddress module) { + return Contract.encodeFunctionCall( + "setup", Constants.safeSingletonAddress, ContractAbis.get("setup"), [ + owners.toList(), + BigInt.from(threshold), + module.setup, + Contract.encodeFunctionCall( + "enableModules", module.setup, ContractAbis.get("enableModules"), [ + [module.address] + ]), + module.address, + Constants.zeroAddress, + BigInt.zero, + Constants.zeroAddress, + ]); + } + + /// Predicts the address of the Safe Smart Account based on the initializer data, salt, and creation code. + /// + /// [initializer] is the initializer data for deploying the Safe contract. + /// [salt] is the salt value used for address calculation. + /// [creationCode] is the creation code for deploying the Safe contract. + /// + /// Returns the predicted [EthereumAddress] of the Safe contract. + + EthereumAddress getPredictedSafe( + Uint8List initializer, Uint256 salt, Uint8List creationCode) { + paddedAddressBytes(Uint8List addressBytes) { + return [...Uint8List(32 - addressBytes.length), ...addressBytes]; + } + + final deploymentData = Uint8List.fromList( + [ + ...creationCode, + ...paddedAddressBytes(Constants.safeSingletonAddress.addressBytes) + ], + ); + + final hash = keccak256( + Uint8List.fromList([ + 0xff, + ...self.address.addressBytes, + ...keccak256(Uint8List.fromList([ + ...keccak256(initializer), + ...intToBytes(salt.value), + ])), + ...keccak256(deploymentData), + ]), + ); + + final predictedAddress = + EthereumAddress(Uint8List.fromList(hash.skip(12).take(20).toList())); + return predictedAddress; + } +} + +/// A class that extends [SimpleAccountFactory] and implements [SimpleAccountFactoryBase]. +/// It creates an instance of [SimpleAccountFactory] with a custom [RPCBase] client. +/// Used to create instances of [SmartWallet] for simple accounts. +class _SimpleAccountFactory extends SimpleAccountFactory + implements SimpleAccountFactoryBase { + /// Creates a new instance of [_SimpleAccountFactory]. + /// + /// [address] is the address of the simple account factory. + /// [chainId] is the ID of the blockchain chain. + /// [rpc] is the [RPCBase] client used for communication with the blockchain. + _SimpleAccountFactory({ + required super.address, + super.chainId, + required RPCBase rpc, + }) : super(client: Web3Client.custom(rpc)); +} diff --git a/lib/src/common/factory.dart b/lib/src/common/factory.dart deleted file mode 100644 index bef8b9e..0000000 --- a/lib/src/common/factory.dart +++ /dev/null @@ -1,7 +0,0 @@ -part of 'package:variance_dart/variance.dart'; - -class _AccountFactory extends AccountFactory implements AccountFactoryBase { - _AccountFactory( - {required super.address, super.chainId, required RPCProviderBase rpc}) - : super(client: Web3Client.custom(rpc)); -} diff --git a/lib/src/common/logger.dart b/lib/src/common/logger.dart new file mode 100644 index 0000000..8659048 --- /dev/null +++ b/lib/src/common/logger.dart @@ -0,0 +1,98 @@ +import 'dart:developer'; + +/// A class that provides logging functionality with colored output for warnings and errors. +class Logger { + /// The ANSI escape code for red color. + static final _errorColor = '\x1B[31m'; + + /// The ANSI escape code for yellow color. + static final _warningColor = '\x1B[33m'; + + /// The ANSI escape code to reset the color. + static final _resetColor = '\x1B[0m'; + + /// Logs an error message if a condition is met. + /// + /// [condition] is the condition to check. + /// [message] is the error message to be logged if the condition is true. + /// [error] is an optional error object associated with the error message. + /// [stackTrace] is an optional stack trace associated with the error message. + static void conditionalError(bool condition, String message, + [Object? error, StackTrace? stackTrace]) { + if (condition) { + _logError('ERROR', _errorColor, message, error, stackTrace); + } + } + + /// Logs a warning message if a condition is met. + /// + /// [condition] is the condition to check. + /// [message] is the warning message to be logged if the condition is true. + static void conditionalWarning(bool condition, String message) { + if (condition) { + _logMessage('WARNING', _warningColor, message); + } + } + + /// Logs an error message. + /// + /// [message] is the error message to be logged. + /// [error] is an optional error object associated with the error message. + /// [stackTrace] is an optional stack trace associated with the error message. + static void error(String message, [Object? error, StackTrace? stackTrace]) { + _logError('ERROR', _errorColor, message, error, stackTrace); + } + + /// Logs a warning message. + /// + /// [message] is the warning message to be logged. + static void warning(String message) { + _logMessage('WARNING', _warningColor, message); + } + + /// Logs a message with the specified level, color, and timestamp. + /// + /// [level] is the log level (e.g., WARNING, ERROR). + /// [color] is the ANSI escape code for the color. + /// [message] is the message to be logged. + static void _log(String level, String color, String message) { + final now = DateTime.now(); + final formattedTime = '${now.year.toString().padLeft(4, '0')}-' + '${now.month.toString().padLeft(2, '0')}-' + '${now.day.toString().padLeft(2, '0')} ' + '${now.hour.toString().padLeft(2, '0')}:' + '${now.minute.toString().padLeft(2, '0')}:' + '${now.second.toString().padLeft(2, '0')}'; + + final logMessage = '$formattedTime [$color$level$_resetColor] $message'; + log(logMessage); + } + + /// Logs an error message with additional error and stack trace information. + /// + /// [level] is the log level (e.g., WARNING, ERROR). + /// [color] is the ANSI escape code for the color. + /// [message] is the error message to be logged. + /// [error] is an optional error object associated with the error message. + /// [stackTrace] is an optional stack trace associated with the error message. + static void _logError(String level, String color, String message, + [Object? error, StackTrace? stackTrace]) { + String errorMessage = message; + if (error != null) { + errorMessage += '\nError: $error'; + } + if (stackTrace != null) { + errorMessage += '\nStackTrace: $stackTrace'; + } + _log(level, color, errorMessage); + } + + /// Logs a message with the specified level and color. + /// + /// [level] is the log level (e.g., WARNING, ERROR). + /// [color] is the ANSI escape code for the color. + /// [message] is the message to be logged. + static void _logMessage(String level, String color, String message) { + _log(level, color, message); + } +} diff --git a/lib/src/common/mixins.dart b/lib/src/common/mixins.dart new file mode 100644 index 0000000..a7e833c --- /dev/null +++ b/lib/src/common/mixins.dart @@ -0,0 +1,129 @@ +part of '../../variance_dart.dart'; + +typedef Percent = double; + +/// A class that represents gas settings for Ethereum transactions. +class GasSettings { + /// The percentage by which the gas limits should be multiplied. + /// + /// This value should be between 0 and 100. + Percent gasMultiplierPercentage; + + /// The user-defined maximum fee per gas for the transaction. + BigInt? userDefinedMaxFeePerGas; + + /// The user-defined maximum priority fee per gas for the transaction. + BigInt? userDefinedMaxPriorityFeePerGas; + + /// Creates a new instance of the [GasSettings] class. + /// + /// [gasMultiplierPercentage] is the percentage by which the gas limits should be multiplied. + /// Defaults to 0. + /// + /// [userDefinedMaxFeePerGas] is the user-defined maximum fee per gas for the transaction. + /// + /// [userDefinedMaxPriorityFeePerGas] is the user-defined maximum priority fee per gas for the transaction. + /// + /// An assertion is made to ensure that [gasMultiplierPercentage] is between 0 and 100. + GasSettings({ + this.gasMultiplierPercentage = 0, + this.userDefinedMaxFeePerGas, + this.userDefinedMaxPriorityFeePerGas, + }) : assert(gasMultiplierPercentage >= 0, + RangeOutOfBounds("Wrong Gas multiplier percentage", 0, 100)); +} + +/// A mixin that provides methods for managing gas settings for user operations. +mixin _GasSettings { + /// The gas settings for user operations. + GasSettings _gasParams = GasSettings(); + + /// Sets the gas settings for user operations. + /// + /// [gasParams] is an instance of the [GasSettings] class containing the gas settings. + set gasSettings(GasSettings gasParams) => _gasParams = gasParams; + + /// Applies the gas settings to a user operation, by multiplying the gas limits by a certain percentage. + /// + /// [op] is the user operation to which the gas settings should be applied. + /// + /// Returns a new [UserOperation] object with the updated gas settings. + UserOperation applyCustomGasSettings(UserOperation op) { + final multiplier = _gasParams.gasMultiplierPercentage / 100 + 1; + + return op.copyWith( + callGasLimit: BigInt.from(op.callGasLimit.toDouble() * multiplier), + verificationGasLimit: + BigInt.from(op.verificationGasLimit.toDouble() * multiplier), + preVerificationGas: + BigInt.from(op.preVerificationGas.toDouble() * multiplier), + maxFeePerGas: _gasParams.userDefinedMaxFeePerGas, + maxPriorityFeePerGas: _gasParams.userDefinedMaxPriorityFeePerGas); + } +} + +/// Used to manage the plugins used in the [Smartwallet] instance +mixin _PluginManager { + final Map _plugins = {}; + + ///returns a list of all active plugins + List activePlugins() { + return _plugins.keys.toList(growable: false); + } + + /// Adds a plugin by name. + /// + /// Parameters: + /// - `name`: The name of the plugin to add. + /// - `module`: The instance of the plugin. + /// + /// Example: + /// ```dart + /// addPlugin('logger', Logger()); + /// ``` + void addPlugin(String name, T module) { + _plugins[name] = module; + } + + /// checks if a plugin exists + /// + /// Parameters: + /// - `name`: The name of the plugin to check + /// + /// Returns: + /// true if the plugin exists + bool hasPlugin(String name) { + return _plugins.containsKey(name); + } + + /// Gets a plugin by name. + /// + /// Parameters: + /// - `name`: Optional. The name of the plugin to retrieve. + /// + /// Returns: + /// The plugin with the specified name. + T plugin([String? name]) { + if (name == null) { + for (var plugin in _plugins.values) { + if (plugin is T) { + return plugin; + } + } + } + return _plugins[name] as T; + } + + /// Removes an unwanted plugin by name. + /// + /// Parameters: + /// - `name`: The name of the plugin to remove. + /// + /// Example: + /// ```dart + /// removePlugin('logger'); + /// ``` + void removePlugin(String name) { + _plugins.remove(name); + } +} diff --git a/lib/src/common/pack.dart b/lib/src/common/pack.dart new file mode 100644 index 0000000..cec7cab --- /dev/null +++ b/lib/src/common/pack.dart @@ -0,0 +1,38 @@ +part of '../../variance_dart.dart'; + +/// Packs two 128-bit unsigned integers into a 32-byte array. +/// +/// Parameters: +/// - [high128]: The high 128-bit unsigned integer. +/// - [low128]: The low 128-bit unsigned integer. +/// +/// Returns a Uint8List containing the packed bytes. +/// +/// Example: +/// ```dart +/// final high128 = BigInt.from(1); +/// final low128 = BigInt.from(2); +/// final packedBytes = packUints(high128, low128); +/// print(packedBytes); +/// ``` +Uint8List packUints(BigInt high128, BigInt low128) { + final packed = (high128 << 128) + low128; + return hexToBytes('0x${packed.toRadixString(16).padLeft(64, '0')}'); +} + +/// Unpacks two 128-bit unsigned integers from a 32-byte array. +/// +/// Parameters: +/// - [bytes]: The 32-byte array containing the packed bytes. +/// +/// Returns a list containing the unpacked high and low 128-bit unsigned integers. +/// +/// Example: +/// ```dart +/// final unpacked = unpackUints("0x...32byteshex"); +/// print(unpacked); +/// ``` +List unpackUints(Hex hex) { + final value = BigInt.parse(hex.substring(2), radix: 16); + return [value >> 128, value.toUnsigned(128)]; +} diff --git a/lib/src/common/plugins.dart b/lib/src/common/plugins.dart deleted file mode 100644 index c184bb7..0000000 --- a/lib/src/common/plugins.dart +++ /dev/null @@ -1,48 +0,0 @@ -part of 'package:variance_dart/variance.dart'; - -mixin _PluginManager { - final Map _plugins = {}; - - ///returns a list of all active plugins - List activePlugins() { - return _plugins.keys.toList(growable: false); - } - - /// Gets a plugin by name. - /// - /// Parameters: - /// - `name`: The name of the plugin to retrieve. - /// - /// Returns: - /// The plugin with the specified name. - T plugin(String name) { - return _plugins[name] as T; - } - - /// Removes an unwanted plugin by name. - /// - /// Parameters: - /// - `name`: The name of the plugin to remove. - /// - /// Example: - /// ```dart - /// removePlugin('logger'); - /// ``` - void removePlugin(String name) { - _plugins.remove(name); - } - - /// Adds a plugin by name. - /// - /// Parameters: - /// - `name`: The name of the plugin to add. - /// - `module`: The instance of the plugin. - /// - /// Example: - /// ```dart - /// addPlugin('logger', Logger()); - /// ``` - void addPlugin(String name, T module) { - _plugins[name] = module; - } -} diff --git a/lib/src/common/string.dart b/lib/src/common/string.dart new file mode 100644 index 0000000..62018df --- /dev/null +++ b/lib/src/common/string.dart @@ -0,0 +1,148 @@ +part of '../../variance_dart.dart'; + +RegExp _ipv4Maybe = RegExp(r'^(\d?\d?\d)\.(\d?\d?\d)\.(\d?\d?\d)\.(\d?\d?\d)$'); +RegExp _ipv6 = + RegExp(r'^::|^::1|^([a-fA-F0-9]{1,4}::?){1,7}([a-fA-F0-9]{1,4})$'); + +bool isFQDN(String str, Map options) { + final parts = str.split('.'); + if (options['require_tld'] as bool) { + var tld = parts.removeLast(); + if (parts.isEmpty || !RegExp(r'^[a-z]{2,}$').hasMatch(tld)) { + return false; + } + } + + for (final part in parts) { + if (options['allow_underscores'] as bool) { + if (part.contains('__')) { + return false; + } + } + if (!RegExp(r'^[a-z\\u00a1-\\uffff0-9-]+$').hasMatch(part)) { + return false; + } + if (part[0] == '-' || + part[part.length - 1] == '-' || + part.contains('---')) { + return false; + } + } + return true; +} + +bool isIP(String str, [Object? version]) { + assert(version == null || version is String || version is int); + version = version.toString(); + if (version == 'null') { + return isIP(str, 4) || isIP(str, 6); + } else if (version == '4') { + if (!_ipv4Maybe.hasMatch(str)) { + return false; + } + var parts = str.split('.'); + parts.sort((a, b) => int.parse(a) - int.parse(b)); + return int.parse(parts[3]) <= 255; + } + return version == '6' && _ipv6.hasMatch(str); +} + +String? _shift(List elements) { + if (elements.isEmpty) return null; + return elements.removeAt(0); +} + +extension StringExtension on String? { + bool isURL() { + var str = this; + if (str == null || + str.isEmpty || + str.length > 2083 || + str.indexOf('mailto:') == 0) { + return false; + } + + final Map options = { + 'protocols': ['http', 'https', 'ftp'], + 'require_tld': true, + 'require_protocol': false, + 'allow_underscores': false, + }; + + var split = str.split('://'); + if (split.length > 1) { + final protocol = _shift(split); + final protocols = options['protocols'] as List; + if (!protocols.contains(protocol)) { + return false; + } + } else if (options['require_protocol'] == true) { + return false; + } + str = split.join('://'); + + // check hash + split = str.split('#'); + str = _shift(split); + final hash = split.join('#'); + if (hash.isNotEmpty && RegExp(r'\s').hasMatch(hash)) { + return false; + } + + // check query params + split = str?.split('?') ?? []; + str = _shift(split); + final query = split.join('?'); + if (query != "" && RegExp(r'\s').hasMatch(query)) { + return false; + } + + // check path + split = str?.split('/') ?? []; + str = _shift(split); + final path = split.join('/'); + if (path != "" && RegExp(r'\s').hasMatch(path)) { + return false; + } + + // check auth type urls + split = str?.split('@') ?? []; + if (split.length > 1) { + final auth = _shift(split); + if (auth != null && auth.contains(':')) { + // final auth = auth.split(':'); + final parts = auth.split(':'); + final user = _shift(parts); + if (user == null || !RegExp(r'^\S+$').hasMatch(user)) { + return false; + } + final pass = parts.join(':'); + if (!RegExp(r'^\S*$').hasMatch(pass)) { + return false; + } + } + } + + // check hostname + final hostname = split.join('@'); + split = hostname.split(':'); + final host = _shift(split); + if (split.isNotEmpty) { + final portStr = split.join(':'); + final port = int.tryParse(portStr, radix: 10); + if (!RegExp(r'^[0-9]+$').hasMatch(portStr) || + port == null || + port <= 0 || + port > 65535) { + return false; + } + } + + if (host == null || + !isIP(host) && !isFQDN(host, options) && host != 'localhost') { + return false; + } + + return true; + } +} diff --git a/lib/src/common/uint256.dart b/lib/src/common/uint256.dart deleted file mode 100644 index 521582e..0000000 --- a/lib/src/common/uint256.dart +++ /dev/null @@ -1,114 +0,0 @@ -part of 'common.dart'; - -class Uint256 implements Uint256Base { - static Uint256 get zero => Uint256(BigInt.zero); - - final BigInt _value; - - const Uint256(this._value); - - /// Creates a [Uint256] instance from a hexadecimal string [hex]. - /// - /// Example: - /// ```dart - /// final value = Uint256.fromHex('0x1a'); // Creates Uint256 with value 26 - /// ``` - factory Uint256.fromHex(String hex) { - return Uint256(hexToInt(hex)); - } - - /// Creates a [Uint256] instance from an [EtherAmount] value [inWei]. - /// - /// Example: - /// ```dart - /// final amount = EtherAmount.inWei(BigInt.from(5)).getInWei; - /// final value = Uint256.fromWei(amount); // Creates Uint256 with value 5 - /// ``` - factory Uint256.fromWei(EtherAmount inWei) { - return Uint256(inWei.getInWei); - } - - /// Creates a [Uint256] instance from an integer value [value]. - /// - /// Example: - /// ```dart - /// final value = Uint256.fromInt(42); // Creates Uint256 with value 42 - /// ``` - factory Uint256.fromInt(int value) { - return Uint256(BigInt.from(value)); - } - - /// Creates a [Uint256] instance from a string representation of a number [value]. - /// - /// Example: - /// ```dart - /// final value = Uint256.fromString('123'); // Creates Uint256 with value 123 - /// ``` - factory Uint256.fromString(String value) { - return Uint256(BigInt.parse(value)); - } - - @override - BigInt get value => _value; - - @override - Uint256 operator *(Uint256 other) { - return Uint256(_value * other._value); - } - - @override - Uint256 operator +(Uint256 other) { - return Uint256(_value + other._value); - } - - @override - Uint256 operator -(Uint256 other) { - return Uint256(_value - other._value); - } - - @override - Uint256 operator /(Uint256 other) { - return Uint256(BigInt.from(_value / other._value)); - } - - @override - BigInt toEther() { - return toEtherAmount().getInEther; - } - - @override - EtherAmount toEtherAmount() { - return EtherAmount.fromBigInt(EtherUnit.wei, _value); - } - - @override - String toHex() { - final hexString = _value.toRadixString(16); - return '0x${hexString.padLeft(64, '0')}'; - } - - @override - int toInt() { - return _value.toInt(); - } - - @override - String toString() { - return toHex(); - } - - @override - BigInt toUnit(int decimals) { - return _value * BigInt.from(pow(10, decimals)); - } - - @override - double fromUnit(int decimals) { - return _value / BigInt.from(pow(10, decimals)); - } - - @override - BigInt toWei() { - return toEtherAmount().getInWei; - } -} diff --git a/lib/src/errors/wallet_errors.dart b/lib/src/errors/wallet_errors.dart new file mode 100644 index 0000000..cab5efc --- /dev/null +++ b/lib/src/errors/wallet_errors.dart @@ -0,0 +1,146 @@ +part of '../../variance_dart.dart'; + +class GasEstimationError extends Error { + final String message; + final UserOperation operation; + + GasEstimationError(this.message, this.operation); + + @override + String toString() { + return ''' + Error estimating user operation gas! Failed with error: $message + -------------------------------------------------- + User operation: ${operation.toJson()}. + '''; + } +} + +class InvalidBundlerMethod extends Error { + final String message = 'Invalid bundler method!'; + final String? method; + + InvalidBundlerMethod(this.method); + + @override + String toString() { + return ''' + $message + -------------------------------------------------- + method ::'$method':: is not supported by the bundler. + '''; + } +} + +class InvalidBundlerUrl extends Error { + final String message = 'Invalid bundler url!'; + final String? url; + + InvalidBundlerUrl(this.url); + + @override + String toString() { + return ''' + $message + -------------------------------------------------- + Provided bundler url: $url + '''; + } +} + +class InvalidFactoryAddress extends Error { + final EthereumAddress? address; + final String message = 'Invalid account factory address!'; + + InvalidFactoryAddress(this.address); + + @override + String toString() { + return ''' + $message + -------------------------------------------------- + Provided factory address: $address + '''; + } +} + +class InvalidJsonRpcUrl extends Error { + final String message = 'Invalid json rpc url!'; + final String? url; + + InvalidJsonRpcUrl(this.url); + + @override + String toString() { + return ''' + $message + -------------------------------------------------- + Provided json rpc url: $url + '''; + } +} + +class InvalidPaymasterUrl extends Error { + final String message = 'Invalid paymaster url!'; + final String? url; + + InvalidPaymasterUrl(this.url); + + @override + String toString() { + return ''' + $message + -------------------------------------------------- + Provided paymaster url: $url + '''; + } +} + +class NonceError extends Error { + final String message; + final EthereumAddress? address; + + NonceError(this.message, this.address); + + @override + String toString() { + return ''' + Error fetching user account nonce for address ${address?.hex}! + -------------------------------------------------- + Failed with error: $message + '''; + } +} + +class RangeOutOfBounds extends Error { + final String? message; + final int? start; + final int? end; + + RangeOutOfBounds(this.message, this.start, this.end); + + @override + String toString() { + return ''' + $message + -------------------------------------------------- + only start ::'$start':: and end ::'$end':: is permissible. + '''; + } +} + +class SendError extends Error { + final String message; + final UserOperation operation; + + SendError(this.message, this.operation); + + @override + String toString() { + return ''' + Error sending user operation! Failed with error: $message + -------------------------------------------------- + User operation: ${operation.toJson()}. + '''; + } +} diff --git a/lib/src/interfaces/account_factories.dart b/lib/src/interfaces/account_factories.dart new file mode 100644 index 0000000..9c68f6c --- /dev/null +++ b/lib/src/interfaces/account_factories.dart @@ -0,0 +1,35 @@ +part of 'interfaces.dart'; + +/// An abstract class representing the contract interface for an Ethereum Account Factory. +/// +/// This class defines the common interface for interacting with an Ethereum smart contract +/// responsible for creating and managing accounts. +abstract class SimpleAccountFactoryBase { + /// Retrieves the Ethereum address associated with a standard account. + Future getAddress( + EthereumAddress owner, + BigInt salt, { + BlockNum? atBlock, + }); +} + +abstract class P256AccountFactoryBase { + /// Retrieves the Ethereum address associated with a standard p256 account. + Future getP256AccountAddress( + BigInt salt, + Uint8List creation, { + BlockNum? atBlock, + }); +} + +abstract class SafeProxyFactoryBase { + Future proxyCreationCode({BlockNum? atBlock}); + + Future createProxyWithNonce( + EthereumAddress _singleton, + Uint8List initializer, + BigInt saltNonce, { + required Credentials credentials, + Transaction? transaction, + }); +} diff --git a/lib/src/interfaces/account_factory.dart b/lib/src/interfaces/account_factory.dart deleted file mode 100644 index 1e65397..0000000 --- a/lib/src/interfaces/account_factory.dart +++ /dev/null @@ -1,29 +0,0 @@ -part of 'interfaces.dart'; - -/// An abstract class representing the contract interface for an Ethereum Account Factory. -/// -/// This class defines the common interface for interacting with an Ethereum smart contract -/// responsible for creating and managing accounts. -abstract class AccountFactoryBase { - /// Retrieves the Ethereum address associated with a standard account. - Future getAddress( - EthereumAddress owner, - BigInt salt, { - BlockNum? atBlock, - }); - - /// Retrieves the Ethereum address associated with a passkey account. - Future getPasskeyAccountAddress( - Uint8List credentialHex, - BigInt x, - BigInt y, - BigInt salt, { - BlockNum? atBlock, - }); - - /// Retrieves the Ethereum address associated with the simpleAccount contract. - Future simpleAccount({BlockNum? atBlock}); - - /// Retrieves the Ethereum address associated with the simplePasskeyAccount contract. - Future simplePasskeyAccount({BlockNum? atBlock}); -} diff --git a/lib/src/interfaces/bundler_provider.dart b/lib/src/interfaces/bundler_provider.dart index c691401..fe336a3 100644 --- a/lib/src/interfaces/bundler_provider.dart +++ b/lib/src/interfaces/bundler_provider.dart @@ -5,11 +5,22 @@ part of 'interfaces.dart'; /// Implementations of this class are expected to provide functionality for interacting specifically /// with bundlers and provides methods for sending user operations to an entrypoint. abstract class BundlerProviderBase { + /// Set of Ethereum RPC methods supported by a 4337 bundler. + static final Set methods = { + 'eth_chainId', + 'eth_sendUserOperation', + 'eth_estimateUserOperationGas', + 'eth_getUserOperationByHash', + 'eth_getUserOperationReceipt', + 'eth_supportedEntryPoints', + 'pm_sponsorUserOperation' + }; + /// Asynchronously estimates the gas cost for a user operation using the provided data and entrypoint. /// /// Parameters: /// - `userOp`: A map containing the user operation data. - /// - `entrypoint`: The [EthereumAddress] representing the entrypoint for the operation. + /// - `entrypoint`: The [EntryPointAddress] representing the entrypoint for the operation. /// /// Returns: /// A [Future] that completes with a [UserOperationGas] instance representing the estimated gas values. @@ -23,7 +34,7 @@ abstract class BundlerProviderBase { /// ``` /// This method uses the bundled RPC to estimate the gas cost for the provided user operation data. Future estimateUserOperationGas( - Map userOp, EthereumAddress entrypoint); + Map userOp, EntryPointAddress entrypoint); /// Asynchronously retrieves information about a user operation using its hash. /// @@ -53,18 +64,13 @@ abstract class BundlerProviderBase { /// var userOpReceipt = await getUserOpReceipt('0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef'); /// ``` /// This method uses the bundled RPC to fetch the receipt of the specified user operation using its hash. - Future getUserOpReceipt(String userOpHash); - - /// Initializes the provider with an entrypoint. - /// - /// - [ep]: The entrypoint to initialize with. - void initializeWithEntrypoint(Entrypoint ep); + Future getUserOpReceipt(String userOpHash); /// Asynchronously sends a user operation to the bundler for execution. /// /// Parameters: /// - `userOp`: A map containing the user operation data. - /// - `entrypoint`: The [EthereumAddress] representing the entrypoint for the operation. + /// - `entrypoint`: The [EntryPointAddress] representing the entrypoint for the operation. /// /// Returns: /// A [Future] that completes with a [UserOperationResponse] containing information about the executed operation. @@ -78,7 +84,7 @@ abstract class BundlerProviderBase { /// ``` /// This method uses the bundled RPC to send the specified user operation for execution and returns the response. Future sendUserOperation( - Map userOp, EthereumAddress entrypoint); + Map userOp, EntryPointAddress entrypoint); /// Asynchronously retrieves a list of supported entrypoints from the bundler. /// @@ -91,20 +97,19 @@ abstract class BundlerProviderBase { /// ``` Future> supportedEntryPoints(); - /// Asynchronously waits for a FilterEvent within a specified time duration based on an event emmitted by entrypoint. - /// Used to wait for [UserOperation] to complete. + /// Validates if the provided method is a supported RPC method. /// /// Parameters: - /// - `millisecond`: The time duration, in milliseconds, to wait for a FilterEvent. Defaults to `0`. + /// - `method`: The Ethereum RPC method to validate. /// - /// Returns: - /// A [Future] that completes with a [FilterEvent] if one is found within the specified duration, otherwise, returns `null`. + /// Throws: + /// - A [Exception] if the method is not a valid supported method. /// /// Example: /// ```dart - /// var filterEvent = await wait(millisecond: 5000); + /// validateBundlerMethod('eth_sendUserOperation'); /// ``` - /// This method waits for a FilterEvent related to the 'UserOperationEvent' within the given time duration. - - Future wait({int millisecond}); + static validateBundlerMethod(String method) { + assert(methods.contains(method), InvalidBundlerMethod(method)); + } } diff --git a/lib/src/interfaces/ens_resolver.dart b/lib/src/interfaces/ens_resolver.dart deleted file mode 100644 index ac757e6..0000000 --- a/lib/src/interfaces/ens_resolver.dart +++ /dev/null @@ -1,24 +0,0 @@ -part of 'interfaces.dart'; - -/// Abstract base class for handling Ethereum Name Service (ENS) resolution. -/// -/// This class provides methods to interact with ENS, including resolving -/// ENS names to addresses and formatting addresses. -abstract class ENSResolverBase { - String? get ens; - - /// Gets the ENS name associated with the current address. - /// - /// Returns a [Future] that completes with the ENS name. - Future? getEnsName(); - - /// Converts an Ethereum address to its corresponding ENS name. - /// - /// - [address]: The Ethereum address to convert to an ENS name. - /// - /// Returns a [Future] that completes with the ENS name. - Future? getEnsNameForAddress(EthereumAddress address); - - /// Returns a new [ENSResolver] instance with the specified [client]. - ENSResolverBase withClient(ChainBaseApiBase client); -} diff --git a/lib/src/interfaces/hd_interface.dart b/lib/src/interfaces/hd_interface.dart deleted file mode 100644 index d8dedba..0000000 --- a/lib/src/interfaces/hd_interface.dart +++ /dev/null @@ -1,47 +0,0 @@ -part of 'interfaces.dart'; - -/// An interface for hierarchical deterministic (HD) wallets. -/// -/// This interface defines the basic contract for interacting with HD wallets, -/// allowing the creation of accounts, exporting mnemonic phrases, exporting -/// private keys, signing messages, and more. -abstract class HDInterface extends MultiSignerInterface { - /// Adds an Ethereum account derived from the HD wallet using the specified [index]. - /// - /// Parameters: - /// - [index]: The index used to derive the Ethereum account. - /// - /// Returns the Ethereum address associated with the specified index. - /// - /// Example: - /// ```dart - /// final walletSigner = HDWalletSigner.recoverAccount('mnemonic phrase'); - /// final newAccount = walletSigner.addAccount(1); - /// ``` - EthereumAddress addAccount(int index); - - /// Exports the mnemonic phrase associated with the HD wallet signer. - /// - /// Returns the mnemonic phrase. - /// - /// Example: - /// ```dart - /// final walletSigner = HDWalletSigner.recoverAccount('mnemonic phrase'); - /// final exportedMnemonic = walletSigner.exportMnemonic(); - /// ``` - String? exportMnemonic(); - - /// Exports the private key associated with the Ethereum account derived from the HD wallet using the specified [index]. - /// - /// Parameters: - /// - [index]: The index used to derive the Ethereum account. - /// - /// Returns the exported private key as a hexadecimal string. - /// - /// Example: - /// ```dart - /// final walletSigner = HDWalletSigner.recoverAccount('mnemonic phrase'); - /// final exportedPrivateKey = walletSigner.exportPrivateKey(1); - /// ``` - String exportPrivateKey(int index); -} diff --git a/lib/src/interfaces/interfaces.dart b/lib/src/interfaces/interfaces.dart index 2e4fb50..583bc8e 100644 --- a/lib/src/interfaces/interfaces.dart +++ b/lib/src/interfaces/interfaces.dart @@ -1,43 +1,26 @@ -library interfaces; - import 'dart:typed_data'; -import 'package:flutter_secure_storage/flutter_secure_storage.dart'; -import 'package:local_auth_android/local_auth_android.dart'; -import 'package:local_auth_ios/local_auth_ios.dart'; -import 'package:web3dart/crypto.dart'; -import 'package:web3dart/json_rpc.dart' show RpcService; +import 'package:web3_signers/web3_signers.dart' show PassKeyPair, Uint256; import 'package:web3dart/web3dart.dart'; -import '../../utils.dart' - show - SSAuthOperationOptions, - ChainBaseApiBase, - CredentialType, - SecureStorageMiddleware; -import '../../variance.dart' +import '../../variance_dart.dart' show Chain, - PassKeyPair, - PassKeySignature, - PassKeysOptions, - Uint256, + EntryPointAddress, + InvalidBundlerMethod, + PaymasterResponse, + SmartWallet, UserOperation, UserOperationByHash, UserOperationGas, UserOperationReceipt, UserOperationResponse; -import '../abis/abis.dart' show Entrypoint; -part 'account_factory.dart'; +part 'account_factories.dart'; part 'bundler_provider.dart'; -part 'ens_resolver.dart'; -part 'hd_interface.dart'; -part 'local_authentication.dart'; -part 'multi_signer_interface.dart'; -part 'passkey_interface.dart'; -part 'rpc_provider.dart'; -part 'secure_storage_repository.dart'; +part 'json_rpc_provider.dart'; +part 'paymaster.dart'; +part 'safe_module.dart'; part 'smart_wallet.dart'; -part 'uint256_interface.dart'; +part 'smart_wallet_factory.dart'; part 'user_operations.dart'; diff --git a/lib/src/interfaces/rpc_provider.dart b/lib/src/interfaces/json_rpc_provider.dart similarity index 80% rename from lib/src/interfaces/rpc_provider.dart rename to lib/src/interfaces/json_rpc_provider.dart index 3aff221..e7662f3 100644 --- a/lib/src/interfaces/rpc_provider.dart +++ b/lib/src/interfaces/json_rpc_provider.dart @@ -4,7 +4,7 @@ part of 'interfaces.dart'; /// /// Implementations of this class are expected to provide functionality for specifically interacting /// with bundlers only. -abstract class RPCProviderBase implements RpcService { +abstract class JsonRPCProviderBase { /// Asynchronously estimates the gas cost for a transaction to the specified address with the given calldata. /// /// Parameters: @@ -39,6 +39,26 @@ abstract class RPCProviderBase implements RpcService { /// This method uses an ethereum jsonRPC to fetch the current block number from the Ethereum node. Future getBlockNumber(); + /// Asynchronously retrieves information about the specified block. + /// If no block number is provided, it defaults to the latest block. + /// If `isContainFullObj` is set to `true`, the full block object will be returned. + /// + /// Parameters: + /// - `blockNumber`: The block number to retrieve information for. + /// - `isContainFullObj`: Whether to return the full block object. + /// + /// Returns: + /// A [Future] that completes with a [BlockInformation] object containing the block information. + /// + /// Example: + /// ```dart + /// var blockInfo = await getBlockInformation(); + /// ``` + Future getBlockInformation({ + String blockNumber = 'latest', + bool isContainFullObj = true, + }); + /// Asynchronously retrieves the EIP-1559 gas prices, including `maxFeePerGas` and `maxPriorityFeePerGas`. /// /// Returns: @@ -74,19 +94,4 @@ abstract class RPCProviderBase implements RpcService { /// ``` /// This method uses an ethereum jsonRPC to fetch the legacy gas price from the Ethereum node. Future getLegacyGasPrice(); - - /// Asynchronously sends an RPC call to the Ethereum node for the specified function and parameters. - /// - /// Parameters: - /// - `function`: The Ethereum RPC function to call. eg: `eth_getBalance` - /// - `params`: Optional parameters for the RPC call. - /// - /// Returns: - /// A [Future] that completes with the result of the RPC call. - /// - /// Example: - /// ```dart - /// var result = await send('eth_getBalance', ['0x9876543210abcdef9876543210abcdef98765432']); - /// ``` - Future send(String function, [List? params]); } diff --git a/lib/src/interfaces/local_authentication.dart b/lib/src/interfaces/local_authentication.dart deleted file mode 100644 index 5bd8a22..0000000 --- a/lib/src/interfaces/local_authentication.dart +++ /dev/null @@ -1,45 +0,0 @@ -part of 'interfaces.dart'; - -/// An abstract class representing authentication operations. -/// -/// Subclasses of this abstract class should provide concrete implementations -/// for authentication mechanisms on specific platforms. -abstract class Authentication { - /// Performs an authentication operation. - /// - /// The authentication operation may involve displaying a prompt to the user - /// for providing authentication credentials, such as a password, fingerprint, - /// or face recognition. - /// - /// The [localizedReason] parameter is a human-readable message describing - /// why authentication is required. The [androidAuthMessages] and [iosAuthMessages] - /// parameters allow providing custom strings for platform-specific authentication - /// scenarios. - /// - /// The [useErrorDialogs] parameter, when set to `true`, indicates that error - /// dialogs should be used to communicate authentication failures. The - /// [stickyAuth] parameter, when set to `true`, allows maintaining the - /// authentication state across app launches. - /// - /// Throws an exception if the authentication operation fails. - Future authenticate({ - required String localizedReason, - AndroidAuthMessages? androidAuthMessages, - IOSAuthMessages? iosAuthMessages, - bool useErrorDialogs = true, - bool stickyAuth = true, - }); - - /// Checks whether the device supports biometric authentication. - /// - /// This method determines whether the device has the necessary hardware and - /// configuration to perform biometric authentication, such as fingerprint or - /// face recognition. - /// - /// Returns `true` if biometric authentication is supported; otherwise, - /// returns `false`. - /// - /// Throws an exception if there is an error while determining biometric - /// authentication support. - Future canAuthenticateWithBiometrics(); -} diff --git a/lib/src/interfaces/multi_signer_interface.dart b/lib/src/interfaces/multi_signer_interface.dart deleted file mode 100644 index 8b0edce..0000000 --- a/lib/src/interfaces/multi_signer_interface.dart +++ /dev/null @@ -1,74 +0,0 @@ -part of 'interfaces.dart'; - -/// An interface for a multi-signer, allowing signing of data and returning the result. -/// -/// the multi-signer interface provides a uniform interface for accessing signer address and signing -/// messages in the Ethereum context. This allows for flexibility in creating different implementations -/// of multi-signers while adhering to a common interface. -/// interfaces include: [PrivateKeySigner], [PassKeySigner] and [HDWalletSigner] -abstract class MultiSignerInterface { - /// The dummy signature is a valid signature that can be used for testing purposes. - /// specifically, this will be used to simulate user operation on the entrypoint. - /// You must specify a dummy signature that matches your transaction signature standard. - String dummySignature = "0x"; - - /// Generates an Ethereum address from the key at the specified [index]. - /// - /// Parameters: - /// - [index]: The index to determine which key to use for address generation. Defaults to 0. - /// - [bytes]: Optional bytes for key generation. If not provided, it defaults to `null`. - /// - /// Example: - /// ```dart - /// final address = getAddress(); - /// ``` - String getAddress({int index = 0, bytes}); - - /// Signs the provided [hash] using the personal sign method. - /// - /// Parameters: - /// - [hash]: The hash to be signed. - /// - [index]: The optional index to specify which privatekey to use for signing (required for HD wallets). If not provided, it defaults to `null`. - /// - [id]: The optional identifier for the signing key. If not provided, it defaults to `null`. Required for passkey signers. - /// - /// Example: - /// ```dart - /// final hashToSign = Uint8List.fromList([0x01, 0x02, 0x03, 0x04]); - /// final signature = await personalSign(hashToSign, index: 0, id: 'credentialId'); // credentialId is only required for passkey signers - /// ``` - - Future personalSign(Uint8List hash, {int? index, String? id}); - - /// Signs the provided [hash] using elliptic curve (EC) signatures and returns the r and s values. - /// - /// Parameters: - /// - [hash]: The hash to be signed. - /// - [index]: The optional index to specify which key to use for signing. If not provided, it defaults to `null`. - /// - [id]: The optional identifier for the signing key. If not provided, it defaults to `null`. Required for passkey signers. - /// - /// Example: - /// ```dart - /// final hashToSign = Uint8List.fromList([0x01, 0x02, 0x03, 0x04]); - /// final signature = await signToEc(hashToSign, index: 0, id: 'credentialId'); - /// ``` - Future signToEc(Uint8List hash, {int? index, String? id}); -} - -mixin SecureStorageMixin { - /// Creates a `SecureStorageMiddleware` instance with the provided [FlutterSecureStorage]. - /// - /// Parameters: - /// - [secureStorage]: The FlutterSecureStorage instance to be used for secure storage. - /// - [authMiddleware]: Optional authentication middleware. Defaults to `null`. - /// - /// Example: - /// ```dart - /// final flutterSecureStorage = FlutterSecureStorage(); - /// final secureStorageMiddleware = this.withSecureStorage( - /// flutterSecureStorage, - /// authMiddleware: myAuthMiddleware, - /// ); - /// ``` - SecureStorageMiddleware withSecureStorage(FlutterSecureStorage secureStorage, - {Authentication? authMiddleware}); -} diff --git a/lib/src/interfaces/passkey_interface.dart b/lib/src/interfaces/passkey_interface.dart deleted file mode 100644 index 7f8d700..0000000 --- a/lib/src/interfaces/passkey_interface.dart +++ /dev/null @@ -1,101 +0,0 @@ -part of 'interfaces.dart'; - -abstract class PasskeyInterface extends MultiSignerInterface { - /// Gets the PassKeysOptions used by the PasskeyInterface. - PassKeysOptions get opts; - - /// Gets the default credential ID used by the Passkey. - String? get defaultId; - - /// Generates the client data hash for the given [PassKeysOptions] and optional challenge. - /// - /// Parameters: - /// - [options]: PassKeysOptions containing the authentication options. - /// - [challenge]: Optional challenge value. Defaults to a randomly generated challenge if not provided. - /// - /// Returns the Uint8List representation of the client data hash. - /// - /// Example: - /// ```dart - /// final passKeysOptions = PassKeysOptions(type: 'webauthn', origin: 'https://example.com'); - /// final clientDataHash = clientDataHash(passKeysOptions); - /// ``` - Uint8List clientDataHash(PassKeysOptions options, {String? challenge}); - - /// Generates the 32-byte client data hash for the given [PassKeysOptions] and optional challenge. - /// - /// Parameters: - /// - [options]: PassKeysOptions containing the authentication options. - /// - [challenge]: Optional challenge value. Defaults to a randomly generated challenge if not provided. - /// - /// Returns the Uint8List representation of the 32-byte client data hash. - /// - /// Example: - /// ```dart - /// final passKeysOptions = PassKeysOptions(type: 'webauthn', origin: 'https://example.com'); - /// final clientDataHash32 = clientDataHash32(passKeysOptions); - /// ``` - Uint8List clientDataHash32(PassKeysOptions options, {String? challenge}); - - /// Converts a List credentialId to a hex string representation with a length of 32 bytes. - /// - /// Parameters: - /// - [credentialId]: List of integers representing the credentialId. - /// - /// Returns the hex string representation of the credentialId padded to 32 bytes. - /// - /// Example: - /// ```dart - /// final credentialId = [1, 2, 3]; - /// final hexString = credentialIdToBytes32Hex(credentialId); - /// ``` - String credentialIdToBytes32Hex(List credentialId); - - /// Parses ASN1-encoded signature bytes and returns a List of two hex strings representing the `r` and `s` values. - /// - /// Parameters: - /// - [signatureBytes]: Uint8List containing the ASN1-encoded signature bytes. - /// - /// Returns a Future> containing hex strings for `r` and `s` values. - /// - /// Example: - /// ```dart - /// final signatureBytes = Uint8List.fromList([48, 68, 2, 32, ...]); - /// final signatureHexValues = await getMessagingSignature(signatureBytes); - /// ``` - Future> getMessagingSignature(Uint8List signatureBytes); - - /// Registers a new PassKeyPair. - /// - /// Parameters: - /// - [name]: The name associated with the PassKeyPair. - /// - [requiresUserVerification]: A boolean indicating whether user verification is required. - /// - /// Returns a Future representing the registered PassKeyPair. - /// - /// Example: - /// ```dart - /// final pkps = PassKeySigner("example", "example.com", "https://example.com"); - /// final passKeyPair = await pkps.register('geffy', true); - /// ``` - Future register(String name, bool requiresUserVerification); - - /// Signs a hash using the PassKeyPair associated with the given credentialId. - /// - /// Parameters: - /// - [hash]: The hash to be signed. - /// - [credentialId]: The credentialId associated with the PassKeyPair. - /// - /// Returns a Future representing the PassKeySignature of the signed hash. - /// - /// Example: - /// ```dart - /// final hash = Uint8List.fromList([/* your hash bytes here */]); - /// final credentialId = 'your_credential_id'; - /// - /// final pkps = PassKeySigner("example", "example.com", "https://example.com"); - /// final passKeySignature = await pkps.signToPasskeySignature(hash, credentialId); - /// ``` - Future signToPasskeySignature( - Uint8List hash, String credentialId); -} diff --git a/lib/src/interfaces/paymaster.dart b/lib/src/interfaces/paymaster.dart new file mode 100644 index 0000000..c2fffd3 --- /dev/null +++ b/lib/src/interfaces/paymaster.dart @@ -0,0 +1,38 @@ +part of 'interfaces.dart'; + +abstract class PaymasterBase { + /// Sets the context data for the Paymaster. + /// + /// [context] is a map containing the context data to be set. + set context(Map? context); + + /// Sets the address of the Paymaster. + /// + /// [address] is the address of the Paymaster. + set paymasterAddress(EthereumAddress? address); + + /// Intercepts a [UserOperation] and sponsors it with the Paymaster. + /// + /// [operation] is the [UserOperation] to be sponsored. + /// + /// Returns a [Future] that resolves to the sponsored [UserOperation]. + /// + /// This method calls the `sponsorUserOperation` method to get the Paymaster + /// response, and then creates a new [UserOperation] with the updated + /// Paymaster data and gas limits. + Future intercept(UserOperation operation); + + /// Sponsors a user operation with the Paymaster. + /// + /// [userOp] is a map containing the user operation data. + /// [entrypoint] is the address of the EntryPoint contract. + /// [context] is an optional map containing the context data for the Paymaster. + /// + /// Returns a [Future] that resolves to a [PaymasterResponse] containing the + /// Paymaster data and gas limits for the sponsored user operation. + /// + /// This method calls the `pm_sponsorUserOperation` RPC method on the Paymaster + /// contract to sponsor the user operation. + Future sponsorUserOperation(Map userOp, + EntryPointAddress entrypoint, Map? context); +} diff --git a/lib/src/interfaces/safe_module.dart b/lib/src/interfaces/safe_module.dart new file mode 100644 index 0000000..1556abc --- /dev/null +++ b/lib/src/interfaces/safe_module.dart @@ -0,0 +1,28 @@ +part of 'interfaces.dart'; + +abstract class Safe4337ModuleBase { + Future SUPPORTED_ENTRYPOINT({BlockNum? atBlock}); + + Future executeUserOpWithErrorString( + EthereumAddress to, + BigInt value, + Uint8List data, + BigInt operation, { + required Credentials credentials, + Transaction? transaction, + }); + + Future executeUserOp( + EthereumAddress to, + BigInt value, + Uint8List data, + BigInt operation, { + required Credentials credentials, + Transaction? transaction, + }); + + Future getOperationHash( + dynamic userOp, { + BlockNum? atBlock, + }); +} diff --git a/lib/src/interfaces/secure_storage_repository.dart b/lib/src/interfaces/secure_storage_repository.dart deleted file mode 100644 index ad7d881..0000000 --- a/lib/src/interfaces/secure_storage_repository.dart +++ /dev/null @@ -1,149 +0,0 @@ -part of 'interfaces.dart'; - -/// A repository for secure storage operations. -/// -/// This abstract class defines methods for saving, reading, updating, and -/// deleting key-value pairs in a secure storage medium. The storage operations -/// can optionally require authentication for additional security. -/// -/// Subclasses of this abstract class should provide concrete implementations -/// for these methods based on the specific secure storage mechanism they intend -/// to use. -abstract class SecureStorageRepository { - /// Saves a key-value pair to the secure storage. - /// - /// Parameters: - /// - [key]: The key under which to store the value. - /// - [value]: The value to be stored. - /// - [options]: Options for the secure storage operation, including authentication requirements. - /// - /// Throws a [SecureStorageAuthMiddlewareError] if authentication is required but no authentication middleware is provided. - /// - /// Example: - /// ```dart - /// final saveKey = 'myKey'; - /// final saveValue = 'myValue'; - /// final saveOptions = SSAuthOperationOptions( - /// requiresAuth: true, - /// authReason: 'Authenticate to save the key-value pair.', - /// ssNameSpace: 'myNamespace', - /// ); - /// await save(saveKey, saveValue, options: saveOptions); - /// print('Key-value pair saved successfully.'); - /// ``` - Future save(String key, String value, - {SSAuthOperationOptions? options}); - - /// Saves a credential to the secure storage for a specified [CredentialType]. - /// - /// Parameters: - /// - [type]: The type of credential to be saved. - /// - [options]: Options for the secure storage operation, including authentication requirements. - /// - /// Throws a [SecureStorageAuthMiddlewareError] if authentication is required but no authentication middleware is provided. - /// - /// Example: - /// ```dart - /// final saveCredentialType = CredentialType.exampleCredential; - /// final saveOptions = SSAuthOperationOptions( - /// requiresAuth: true, - /// authReason: 'Authenticate to save the credential.', - /// ssNameSpace: 'myNamespace', - /// ); - /// await saveCredential(saveCredentialType, options: saveOptions); - /// print('Credential saved successfully.'); - /// ``` - Future saveCredential(CredentialType type, - {SSAuthOperationOptions? options}); - - /// Reads a value from the secure storage. - /// - /// Parameters: - /// - [key]: The key for the value to be read. - /// - [options]: Options for the secure storage operation, including authentication requirements. - /// - /// Throws a [SecureStorageAuthMiddlewareError] if authentication is required but no authentication middleware is provided. - /// - /// Returns the value associated with the provided key, or `null` if the key is not found. - /// - /// Example: - /// ```dart - /// final keyToRead = 'exampleKey'; - /// final readOptions = SSAuthOperationOptions( - /// requiresAuth: true, - /// authReason: 'Authenticate to read the key.', - /// ssNameSpace: 'myNamespace', - /// ); - /// final storedValue = await read(keyToRead, options: readOptions); - /// print('Stored value: $storedValue'); - /// ``` - Future read(String key, {SSAuthOperationOptions? options}); - - /// Reads a credential from the secure storage. - /// - /// Parameters: - /// - [type]: The type of credential to be read. - /// - [options]: Options for the secure storage operation, including authentication requirements. - /// - /// Throws a [SecureStorageAuthMiddlewareError] if authentication is required but no authentication middleware is provided. - /// - /// Returns the credential associated with the provided type, or `null` if the credential is not found. - /// - /// Example: - /// ```dart - /// final credentialType = CredentialType.hdwallet; - /// final readOptions = SSAuthOperationOptions( - /// requiresAuth: true, - /// authReason: 'Authenticate to read the credential.', - /// ssNameSpace: 'myNamespace', - /// ); - /// final storedCredential = await readCredential(credentialType, options: readOptions); - /// print('Stored credential: $storedCredential'); - /// ``` - Future readCredential(CredentialType type, - {SSAuthOperationOptions? options}); - - /// Updates the value of an existing key in the secure storage. - /// - /// Parameters: - /// - [key]: The key for which to update the value. - /// - [value]: The new value to be stored. - /// - [options]: Options for the secure storage operation, including authentication requirements. - /// - /// Throws a [SecureStorageAuthMiddlewareError] if authentication is required but no authentication middleware is provided. - /// - /// Example: - /// ```dart - /// final updateKey = 'myKey'; - /// final updateValue = 'newValue'; - /// final updateOptions = SSAuthOperationOptions( - /// requiresAuth: true, - /// authReason: 'Authenticate to update the key value.', - /// ssNameSpace: 'myNamespace', - /// ); - /// await update(updateKey, updateValue, options: updateOptions); - /// print('Key updated successfully.'); - /// ``` - Future update(String key, String value, - {SSAuthOperationOptions? options}); - - /// Deletes a key from the secure storage. - /// - /// Parameters: - /// - [key]: The key to be deleted. - /// - [options]: Options for the secure storage operation, including authentication requirements. - /// - /// Throws a [SecureStorageAuthMiddlewareError] if authentication is required but no authentication middleware is provided. - /// - /// Example: - /// ```dart - /// final keyToDelete = 'exampleKey'; - /// final deleteOptions = SSAuthOperationOptions( - /// requiresAuth: true, - /// authReason: 'Authenticate to delete the key.', - /// ssNameSpace: 'myNamespace', - /// ); - /// await delete(keyToDelete, options: deleteOptions); - /// ``` - Future delete(String key, {SSAuthOperationOptions? options}); -} diff --git a/lib/src/interfaces/smart_wallet.dart b/lib/src/interfaces/smart_wallet.dart index cd96b91..ef816ba 100644 --- a/lib/src/interfaces/smart_wallet.dart +++ b/lib/src/interfaces/smart_wallet.dart @@ -7,40 +7,43 @@ part of 'interfaces.dart'; /// creating different implementations of Smart Wallets while adhering to a /// common interface. abstract class SmartWalletBase { - /// The Ethereum address associated with the Smart Wallet. + /// The Ethereum address of the Smart Wallet. EthereumAddress? get address; - /// Retrieves the balance of the Smart Wallet. + /// Returns the balance of the Smart Wallet. + /// + /// The balance is retrieved by interacting with the 'contract' plugin. Future get balance; - /// Checks if the Smart Wallet has been deployed on the blockchain. - Future get deployed; + /// Retrieves the dummy signature required for gas estimation from the Smart Wallet. + String get dummySignature; - /// Retrieves the init code of the Smart Wallet. + /// Returns the initialization code for deploying the Smart Wallet contract. String? get initCode; - /// Retrieves the gas required to deploy the Smart Wallet. + /// Returns the estimated gas required for deploying the Smart Wallet contract. + /// + /// The gas estimation is performed by interacting with the 'jsonRpc' plugin. Future get initCodeGas; - /// Retrieves the nonce of the Smart Wallet. + /// Checks if the Smart Wallet is deployed on the blockchain. + /// + /// The deployment status is checked by interacting with the 'contract' plugin. + Future get isDeployed; + + /// Returns the nonce for the Smart Wallet from the entrypoint. + /// + /// The nonce is retrieved by calling the `_getNonce` method. Future get nonce; - /// Converts the Smart Wallet address to its hexadecimal representation. + /// Returns the hexadecimal representation of the Smart Wallet address in EIP-55 format. String? get toHex; - /// Sets the smart wallet address for this account; - set setWalletAddress(EthereumAddress address); - /// Builds a [UserOperation] instance with the specified parameters. /// /// Parameters: /// - `callData` (required): The call data as a [Uint8List]. /// - `customNonce`: An optional custom nonce value. - /// - `callGasLimit`: An optional custom call gas limit as a [BigInt]. - /// - `verificationGasLimit`: An optional custom verification gas limit as a [BigInt]. - /// - `preVerificationGas`: An optional custom pre-verification gas as a [BigInt]. - /// - `maxFeePerGas`: An optional custom maximum fee per gas as a [BigInt]. - /// - `maxPriorityFeePerGas`: An optional custom maximum priority fee per gas as a [BigInt]. /// /// Returns: /// A [UserOperation] instance with the specified parameters. @@ -50,108 +53,42 @@ abstract class SmartWalletBase { /// var userOperation = buildUserOperation( /// callData: Uint8List(0xabcdef), /// customNonce: BigInt.from(42), - /// callGasLimit: BigInt.from(20000000), - /// // Other optional parameters can be provided as needed. /// ); /// ``` UserOperation buildUserOperation({ required Uint8List callData, BigInt? customNonce, - BigInt? callGasLimit, - BigInt? verificationGasLimit, - BigInt? preVerificationGas, - BigInt? maxFeePerGas, - BigInt? maxPriorityFeePerGas, }); - /// Sets the account initialization calldata for a [SmartWalletBase] in a potentially unsafe manner. + /// Sets the initialization code for deploying the Smart Wallet contract. + /// + /// This method is marked as `@Deprecated` and should not be used in production code. + /// It is recommended to set the initialization code during the construction of the [SmartWallet] instance. /// /// **Warning:** /// This method allows setting the initialization calldata directly, which may lead to unexpected behavior /// if used improperly. It is intended for advanced use cases where the caller is aware of the potential risks. /// /// Parameters: - /// - `code`: The initialization calldata as a [Uint8List]. Set to `null` to clear the existing data. + /// - `code`: The initialization calldata as a [Uint8List]. /// /// Example: /// ```dart /// dangerouslySetInitCallData(Uint8List.fromList([0x01, 0x02, 0x03])); /// ``` - void dangerouslySetInitCallData(Uint8List? code); - - /// Asynchronously creates a simple Ethereum smart account using the provided salt value. - /// Uses counterfactactual deployment to create the account and [deployed] should be used to check deployment status. - /// An `initCode` will be attached on the first transaction. - /// - /// Parameters: - /// - `salt`: A [Uint256] representing the salt value for account creation. - /// - `index`: Optional parameter specifying the index for selecting a signer. Defaults to `null`. - /// - /// Returns: - /// A [Future] that completes with the created [SmartWallet] instance. - /// - /// Example: - /// ```dart - /// var smartWallet = await createSimpleAccount(Uint256.zero, index: 1); - /// ``` - /// This method generates initialization calldata using the 'createAccount' method and the provided signer and salt. - /// It then retrieves the Ethereum address for the simple account and sets it to the wallet instance. - Future createSimpleAccount(Uint256 salt, {int? index}); - - /// Asynchronously creates a simple Ethereum smart account using a passkey pair and the provided salt value. - /// - /// Parameters: - /// - `pkp`: A [PassKeyPair] representing the passkey pair for account creation. - /// - `salt`: A [Uint256] representing the salt value for account creation. - /// - /// Returns: - /// A [Future] that completes with the created [SmartWallet] instance. - /// - /// Example: - /// ```dart - /// var smartWallet = await createSimplePasskeyAccount(myPassKeyPair, Uint256.zero); - /// ``` - /// This method generates initialization calldata using the 'createPasskeyAccount' method and the provided - /// passkey pair and salt. The passkey pair includes the credential and public key values. - Future createSimplePasskeyAccount(PassKeyPair pkp, Uint256 salt); - - /// Asynchronously retrieves the Ethereum address for a simple account created with the specified signer and salt. - /// - /// Parameters: - /// - `signer`: The [EthereumAddress] of the signer associated with the account. - /// - `salt`: A [Uint256] representing the salt value used in the account creation. - /// - /// Returns: - /// A [Future] that completes with the Ethereum address of the simple account. - /// - /// Example: - /// ```dart - /// var address = await getSimpleAccountAddress( - /// EthereumAddress.fromHex('0x1234567890abcdef1234567890abcdef12345678'), - /// Uint256.zero, - /// ); - /// ``` - Future getSimpleAccountAddress( - EthereumAddress signer, Uint256 salt); + @Deprecated("Not recommended to modify the initcode") + void dangerouslySetInitCode(Uint8List code); - /// Asynchronously retrieves the Ethereum address for a simple account created with the specified passkey pair and salt. - /// - /// Parameters: - /// - `pkp`: The [PassKeyPair] used for creating the account. - /// - `salt`: A [Uint256] representing the salt value used in the account creation. + /// Prepares a user operation by updating it with the latest nonce and gas prices, + /// intercepting it with a paymaster (if enabled), and validating it. /// - /// Returns: - /// A [Future] that completes with the Ethereum address of the simple account. + /// [op] is the user operation to prepare. + /// [update] is a flag indicating whether to update the user operation with the + /// latest nonce and gas prices. Defaults to `true`. /// - /// Example: - /// ```dart - /// var address = await getSimplePassKeyAccountAddress( - /// myPassKeyPair, - /// Uint256.zero, - /// ); - /// ``` - Future getSimplePassKeyAccountAddress( - PassKeyPair pkp, Uint256 salt); + /// Returns a [Future] that resolves to the prepared [UserOperation] object. + Future prepareUserOperation(UserOperation op, + {bool update = true}); /// Asynchronously transfers native Token (ETH) to the specified recipient with the given amount. /// @@ -269,7 +206,6 @@ abstract class SmartWalletBase { /// Parameters: /// - `userOp`: The [UserOperation] to be signed. /// - `update`: Optional parameter indicating whether to update the user operation before signing. Defaults to `true`. - /// - `id`: Optional identifier (credential Id) when using a passkey signer Defaults to `null`. /// - `index`: Optional index parameter for selecting a signer. Defaults to `null`. /// /// Returns: @@ -281,9 +217,5 @@ abstract class SmartWalletBase { /// var signedOperation = await signUserOperation(myUserOperation, index: 0); // signer 0 /// var signedOperation = await signUserOperation(myUserOperation, index: 1); // signer 1 /// ``` - Future signUserOperation( - UserOperation userOp, { - bool update = true, - String? id, - }); + Future signUserOperation(UserOperation op, {int? index}); } diff --git a/lib/src/interfaces/smart_wallet_factory.dart b/lib/src/interfaces/smart_wallet_factory.dart new file mode 100644 index 0000000..5004038 --- /dev/null +++ b/lib/src/interfaces/smart_wallet_factory.dart @@ -0,0 +1,47 @@ +part of 'interfaces.dart'; + +abstract class SmartWalletFactoryBase { + /// Creates a new P256 account using the provided key pair and salt. + /// + /// [keyPair] is the key pair used to create the account. It can be either a + /// [PassKeyPair] or a [P256Credential] instance. + /// [salt] is the salt value used in the account creation process. + /// [recoveryAddress] is an optional recovery address for the account. + /// + /// Returns a [Future] that resolves to a [SmartWallet] instance representing + /// the created account. + /// + /// Throws an [ArgumentError] if the provided [keyPair] is not a + /// [PassKeyPair] or [P256Credential] instance. + Future createP256Account(T keyPair, Uint256 salt, + [EthereumAddress? recoveryAddress]); + + /// Creates a new Safe account with the provided salt and optional owners and threshold. + /// + /// [salt] is the salt value used in the account creation process. + /// + /// Returns a [Future] that resolves to a [SmartWallet] instance representing + /// the created Safe account. + + Future createSafeAccount(Uint256 salt); + + /// Creates a new simple account with the provided salt and optional index. + /// + /// [salt] is the salt value used in the account creation process. + /// [index] is an optional index value for the signer address. + /// + /// Returns a [Future] that resolves to a [SmartWallet] instance representing + /// the created simple account. + Future createSimpleAccount(Uint256 salt, [int? index]); + + /// Creates a new vendor account with the provided address and initialization code. + /// + /// [address] is the Ethereum address of the vendor account. + /// [initCode] is the initialization code for the vendor account. + /// + /// Returns a [SmartWallet] instance representing the created vendor account. + Future createVendorAccount( + EthereumAddress address, + Uint8List initCode, + ); +} diff --git a/lib/src/interfaces/uint256_interface.dart b/lib/src/interfaces/uint256_interface.dart deleted file mode 100644 index 64a315e..0000000 --- a/lib/src/interfaces/uint256_interface.dart +++ /dev/null @@ -1,138 +0,0 @@ -part of 'interfaces.dart'; - -/// Abstract base class representing a 64-bit length big number, similar to Solidity. -/// -/// This interface defines methods and properties for working with 64-bit length big numbers, -/// with operations such as multiplication, addition, subtraction, division, and various conversions. -abstract class Uint256Base { - BigInt get value; - - Uint256Base operator *(covariant Uint256Base other); - - Uint256Base operator +(covariant Uint256Base other); - - Uint256Base operator -(covariant Uint256Base other); - - Uint256Base operator /(covariant Uint256Base other); - - /// Converts the value of this [Uint256] instance to a [BigInt] representing the equivalent amount in ether. - /// - /// Example 1: - /// ```dart - /// final value = Uint256(BigInt.from(5000000000)); - /// final etherValue = value.toEther(); // Converts the value to ether (0.000000000000000005) - /// ``` - - /// Example 2: - /// ```dart - /// final value = Uint256(BigInt.from(1000000000000000000)); - /// final etherValue = value.toEther(); // Converts the value to ether (1.0) - /// ``` - BigInt toEther(); - - /// Converts the value of this [Uint256] instance to an [EtherAmount] with the equivalent amount in wei. - /// - /// Example 1: - /// ```dart - /// final value = Uint256(BigInt.from(5000000000)); - /// final etherAmount = value.toEtherAmount(); // Converts the value to EtherAmount (5 wei) - /// ``` - - /// Example 2: - /// ```dart - /// final value = Uint256(BigInt.from(1000000000000000000)); - /// final etherAmount = value.toEtherAmount(); // Converts the value to EtherAmount (1 ether) - /// ``` - EtherAmount toEtherAmount(); - - /// Converts the value of this [Uint256] instance to a hexadecimal string with a length of 64 characters, padded with leading zeros. - /// - /// Example 1: - /// ```dart - /// final value = Uint256(BigInt.from(42)); - /// final hexString = value.toHex(); // Converts the value to hex (0x000000000000000000000000000000000000000000000000000000000000002a) - /// ``` - - /// Example 2: - /// ```dart - /// final value = Uint256(BigInt.from(255)); - /// final hexString = value.toHex(); // Converts the value to hex (0x00000000000000000000000000000000000000000000000000000000000000ff) - /// ``` - String toHex(); - - /// Converts the value of this [Uint256] instance to an integer. - /// - /// Example 1: - /// ```dart - /// final value = Uint256(BigInt.from(42)); - /// final intValue = value.toInt(); // Converts the value to an integer (42) - /// ``` - - /// Example 2: - /// ```dart - /// final value = Uint256(BigInt.from(123456789)); - /// final intValue = value.toInt(); // Converts the value to an integer (123456789) - /// ``` - int toInt(); - - /// Returns the hexadecimal representation of this [Uint256] instance as a string. - /// - /// Example 1: - /// ```dart - /// final value = Uint256(BigInt.from(42)); - /// final stringValue = value.toString(); // Converts the value to a string (0x000000000000000000000000000000000000000000000000000000000000002a) - /// ``` - - /// Example 2: - /// ```dart - /// final value = Uint256(BigInt.from(255)); - /// final stringValue = value.toString(); // Converts the value to a string (0x00000000000000000000000000000000000000000000000000000000000000ff) - /// ``` - @override - String toString(); - - /// Converts the value of this [Uint256] instance to a [BigInt] with a scale defined by [decimals]. - /// - /// Example 1: - /// ```dart - /// final value = Uint256(BigInt.from(42)); - /// final unitValue = value.toUnit(3); // Converts the value to a unit with 3 decimals (42000) - /// ``` - - /// Example 2: - /// ```dart - /// final value = Uint256(BigInt.from(123456789)); - /// final unitValue = value.toUnit(6); // Converts the value to a unit with 6 decimals (123456789000000) - /// ``` - BigInt toUnit(int decimals); - - /// Converts the value of this [Uint256] instance from a unit with [decimals] to a double. - /// - /// Example 1: - /// ```dart - /// final value = Uint256(BigInt.from(42000)); - /// final doubleValue = value.fromUnit(3); // Converts the value from a unit with 3 decimals to a double (42.0) - /// ``` - - /// Example 2: - /// ```dart - /// final value = Uint256(BigInt.from(123456789000000)); - /// final doubleValue = value.fromUnit(6); // Converts the value from a unit with 6 decimals to a double (123.456789) - /// ``` - double fromUnit(int decimals); - - /// Converts the value of this [Uint256] instance to a [BigInt] representing the equivalent amount in wei. - /// - /// Example 1: - /// ```dart - /// final value = Uint256(BigInt.from(5000000000)); - /// final weiValue = value.toWei(); // Converts the value to wei (5000000000) - /// ``` - - /// Example 2: - /// ```dart - /// final value = Uint256(BigInt.from(1000000000000000000)); - /// final weiValue = value.toWei(); // Converts the value to wei (1000000000000000000) - /// ``` - BigInt toWei(); -} diff --git a/lib/src/interfaces/user_operations.dart b/lib/src/interfaces/user_operations.dart index 10564d3..f205328 100644 --- a/lib/src/interfaces/user_operations.dart +++ b/lib/src/interfaces/user_operations.dart @@ -5,26 +5,37 @@ part of 'interfaces.dart'; /// Implementations of this class are expected to provide functionality for creating, /// updating, and hashing user operations. abstract class UserOperationBase { + /// Address of the smart wallet. EthereumAddress get sender; + /// Nonce of the Smart Account. BigInt get nonce; + /// Initialization code for the Smart Account. Uint8List get initCode; + /// Call data for execution in a user operation. Uint8List get callData; + /// Maximum amount of gas that can be used for executing a user operation calldata. BigInt get callGasLimit; + /// Maximum amount of gas that can be used for executing a user operation signature verification. BigInt get verificationGasLimit; + /// Gas for executing a user operation pre-verification. BigInt get preVerificationGas; + /// Maximum fee per gas for the contract call. BigInt get maxFeePerGas; + /// EIP1559 priority fee per gas for the contract call. BigInt get maxPriorityFeePerGas; + /// Signature of the user operation. String get signature; + /// Details of the paymaster and data for the gas sponsorship. Uint8List get paymasterAndData; /// Hashes the user operation for the given chain. @@ -34,6 +45,20 @@ abstract class UserOperationBase { /// Returns a [Uint8List] representing the hashed user operation. Uint8List hash(Chain chain); + /// Packs a [UserOperation] into a PackedUserOperation map for EntryPoint v0.7 and above. + /// + /// Parameters: + /// - [userOp]: The [UserOperation] to pack. + /// + /// Returns a [Map] containing the packed user operation. + /// + /// Example: + /// ```dart + /// final packedUserOp = op.packUserOperation(); + /// print(packedUserOp); + /// ``` + Map packUserOperation(); + /// Converts the user operation to a JSON-encoded string. String toJson(); @@ -41,4 +66,32 @@ abstract class UserOperationBase { /// /// Returns a [Map] representing the user operation. Map toMap(); + + /// Creates a [UserOperation] by updating an existing operation gas params. + /// + /// Parameters: + /// - `opGas`: Optional parameter of type [UserOperationGas] for specifying gas-related information. + /// - `feePerGas`: Optional parameter of type [Map] for specifying maxFeePerGas and maxPriorityFeePerGas. + /// + /// Returns: + /// A [UserOperation] instance created from the provided map. + /// + /// Example: + /// ```dart + /// var map = UserOperation.partial(callData: Uint8List(0xabcdef)).toMap(); + /// var updatedUserOperation = UserOperation.update( + /// map, + /// opGas: UserOperationGas(callGasLimit: BigInt.from(20000000), ...), + /// // Other parameters can be updated as needed. + /// ); + /// ``` + UserOperation updateOpGas( + UserOperationGas? opGas, Map? feePerGas); + + /// Validates the user operation fields for accuracy + /// + /// Parameters: + /// - `deployed`: Whether the user operation sender is deployed or not + /// - `initCode`: (optional) The initialization code of the user operation + void validate(bool deployed, [String? initCode]); } diff --git a/lib/src/signers/hd_wallet_signer.dart b/lib/src/signers/hd_wallet_signer.dart deleted file mode 100644 index 9bef3ca..0000000 --- a/lib/src/signers/hd_wallet_signer.dart +++ /dev/null @@ -1,158 +0,0 @@ -part of '../../variance.dart'; - -class HDWalletSigner with SecureStorageMixin implements HDInterface { - final String _mnemonic; - - final String _seed; - - late final EthereumAddress zerothAddress; - - @override - String dummySignature = - "0xfffffffffffffffffffffffffffffff0000000000000000000000000000000007aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa1c"; - - /// Creates a new HD wallet signer instance by generating a random mnemonic phrase. - /// - /// Example: - /// ```dart - /// final walletSigner = HDWalletSigner.createWallet(); - /// ``` - factory HDWalletSigner.createWallet() { - return HDWalletSigner.recoverAccount(bip39.generateMnemonic()); - } - - /// Recovers an HD wallet signer instance from a given mnemonic phrase. - /// - /// Parameters: - /// - [mnemonic]: The mnemonic phrase used for recovering the HD wallet signer. - /// - /// Example: - /// ```dart - /// final mnemonicPhrase = 'word1 word2 word3 ...'; // Replace with an actual mnemonic phrase - /// final recoveredSigner = HDWalletSigner.recoverAccount(mnemonicPhrase); - /// ``` - - factory HDWalletSigner.recoverAccount(String mnemonic) { - final seed = bip39.mnemonicToSeedHex(mnemonic); - final signer = HDWalletSigner._internal(seed: seed, mnemonic: mnemonic); - signer.zerothAddress = signer._add(seed, 0); - return signer; - } - - HDWalletSigner._internal({required String seed, required String mnemonic}) - : _seed = seed, - _mnemonic = mnemonic { - assert(seed.isNotEmpty, "seed cannot be empty"); - } - - @override - EthereumAddress addAccount(int index) { - return _add(_seed, index); - } - - @override - String exportMnemonic() { - return _getMnemonic(); - } - - @override - String exportPrivateKey(int index) { - final ethPrivateKey = _getPrivateKey(index); - Uint8List privKey = ethPrivateKey.privateKey; - bool rlz = shouldRemoveLeadingZero(privKey); - if (rlz) { - privKey = privKey.sublist(1); - } - return hexlify(privKey); - } - - @override - String getAddress({int index = 0, bytes}) { - return _getEthereumAddress(index: index).hex; - } - - @override - Future personalSign(Uint8List hash, - {int? index, String? id}) async { - final privKey = _getPrivateKey(index ?? 0); - return privKey.signPersonalMessageToUint8List(hash); - } - - @override - Future signToEc(Uint8List hash, - {int? index, String? id}) async { - final privKey = _getPrivateKey(index ?? 0); - return privKey.signToEcSignature(hash); - } - - @override - SecureStorageMiddleware withSecureStorage(FlutterSecureStorage secureStorage, - {Authentication? authMiddleware}) { - return SecureStorageMiddleware( - secureStorage: secureStorage, - authMiddleware: authMiddleware, - credential: _getMnemonic()); - } - - EthereumAddress _add(String seed, int index) { - final hdKey = _deriveHdKey(seed, index); - final privKey = _deriveEthPrivKey(hdKey.privateKeyHex()); - return privKey.address; - } - - EthPrivateKey _deriveEthPrivKey(String key) { - final ethPrivateKey = EthPrivateKey.fromHex(key); - return ethPrivateKey; - } - - bip44.ExtendedPrivateKey _deriveHdKey(String seed, int idx) { - final path = "m/44'/60'/0'/0/$idx"; - final chain = bip44.Chain.seed(seed); - final hdKey = chain.forPath(path) as bip44.ExtendedPrivateKey; - return hdKey; - } - - EthereumAddress _getEthereumAddress({int index = 0}) { - bip44.ExtendedPrivateKey hdKey = _getHdKey(index); - final privKey = _deriveEthPrivKey(hdKey.privateKeyHex()); - return privKey.address; - } - - bip44.ExtendedPrivateKey _getHdKey(int index) { - return _deriveHdKey(_seed, index); - } - - String _getMnemonic() { - return _mnemonic; - } - - EthPrivateKey _getPrivateKey(int index) { - final hdKey = _getHdKey(index); - final privateKey = _deriveEthPrivKey(hdKey.privateKeyHex()); - return privateKey; - } - - /// Loads an HD wallet signer instance from secure storage using the provided [SecureStorageRepository]. - /// - /// Parameters: - /// - [storageMiddleware]: The secure storage repository used to retrieve the HD wallet credentials. - /// - [options]: Optional authentication operation options. Defaults to `null`. - /// - /// Returns a `Future` that resolves to a `HDWalletSigner` instance if successfully loaded, or `null` otherwise. - /// - /// Example: - /// ```dart - /// final secureStorageRepo = SecureStorageRepository(); // Replace with an actual instance - /// final loadedSigner = await HDWalletSigner.loadFromSecureStorage( - /// storageMiddleware: secureStorageRepo, - /// ); - /// ``` - static Future loadFromSecureStorage( - {required SecureStorageRepository storageMiddleware, - SSAuthOperationOptions? options}) { - return storageMiddleware - .readCredential(CredentialType.hdwallet, options: options) - .then((value) => - value != null ? HDWalletSigner.recoverAccount(value) : null); - } -} diff --git a/lib/src/signers/passkey_signer.dart b/lib/src/signers/passkey_signer.dart deleted file mode 100644 index 103d25a..0000000 --- a/lib/src/signers/passkey_signer.dart +++ /dev/null @@ -1,420 +0,0 @@ -part of '../../variance.dart'; - -class AuthData { - final String credentialHex; - final String credentialId; - final List publicKey; - final String aaGUID; - AuthData(this.credentialHex, this.credentialId, this.publicKey, this.aaGUID); -} - -class PassKeyPair with SecureStorageMixin { - final Uint8List credentialHexBytes; - final String credentialId; - final List publicKey; - final String name; - final String aaGUID; - final DateTime registrationTime; - PassKeyPair(this.credentialHexBytes, this.credentialId, this.publicKey, - this.name, this.aaGUID, this.registrationTime); - - factory PassKeyPair.fromJson(String source) => - PassKeyPair.fromMap(json.decode(source) as Map); - - factory PassKeyPair.fromMap(Map map) { - return PassKeyPair( - Uint8List.fromList(map['credentialHexBytes']), - map['credentialId'], - List.from( - (map['publicKey'] as List).map( - (x) => Uint256.fromHex(x), - ), - ), - map['name'], - map['aaGUID'], - DateTime.fromMillisecondsSinceEpoch(map['registrationTime']), - ); - } - - String toJson() => json.encode(toMap()); - - Map toMap() { - return { - 'credentialHexBytes': credentialHexBytes.toList(), - 'credentialId': credentialId, - 'publicKey': publicKey.map((x) => x.toHex()).toList(), - 'name': name, - 'aaGUID': aaGUID, - 'registrationTime': registrationTime.millisecondsSinceEpoch, - }; - } - - @override - SecureStorageMiddleware withSecureStorage(FlutterSecureStorage secureStorage, - {Authentication? authMiddleware}) { - return SecureStorageMiddleware( - secureStorage: secureStorage, - authMiddleware: authMiddleware, - credential: toJson()); - } - - /// Loads a passkey pair from secure storage using the provided [SecureStorageRepository]. - /// - /// Parameters: - /// - [storageMiddleware]: The secure storage repository used to retrieve the passkey pair credentials. - /// - [options]: Optional authentication operation options. Defaults to `null`. - /// - /// Returns a `Future` that resolves to a `PassKeyPair` instance if successfully loaded, or `null` otherwise. - /// - /// Example: - /// ```dart - /// final secureStorageRepo = SecureStorageRepository(); // Replace with an actual instance - /// final loadedPassKeyPair = await PassKeyPair.loadFromSecureStorage( - /// storageMiddleware: secureStorageRepo, - /// ); - /// ``` - static Future loadFromSecureStorage( - {required SecureStorageRepository storageMiddleware, - SSAuthOperationOptions? options}) { - return storageMiddleware - .readCredential(CredentialType.passkeypair, options: options) - .then((value) => value != null ? PassKeyPair.fromJson(value) : null); - } -} - -class PassKeySignature { - final String credentialId; - final List rs; - final Uint8List authData; - final String clientDataPrefix; - final String clientDataSuffix; - PassKeySignature(this.credentialId, this.rs, this.authData, - this.clientDataPrefix, this.clientDataSuffix); - - /// Converts the `PassKeySignature` to a `Uint8List` using the specified ABI encoding. - /// - /// Returns the encoded Uint8List. - /// - /// Example: - /// ```dart - /// final Uint8List encodedSig = pkpSig.toUint8List(); - /// ``` - Uint8List toUint8List() { - return abi.encode([ - 'uint256', - 'uint256', - 'bytes', - 'string', - 'string' - ], [ - rs[0].value, - rs[1].value, - authData, - clientDataPrefix, - clientDataSuffix - ]); - } -} - -class PassKeySigner implements PasskeyInterface { - final _makeCredentialJson = '''{ - "authenticatorExtensions": "", - "clientDataHash": "", - "credTypesAndPubKeyAlgs": [ - ["public-key", -7] - ], - "excludeCredentials": [], - "requireResidentKey": true, - "requireUserPresence": true, - "requireUserVerification": false, - "rp": { - "name": "", - "id": "" - }, - "user": { - "name": "", - "displayName": "", - "id": "" - } - }'''; - - final _getAssertionJson = '''{ - "allowCredentialDescriptorList": [], - "authenticatorExtensions": "", - "clientDataHash": "", - "requireUserPresence": true, - "requireUserVerification": false, - "rpId": "" - }'''; - - final PassKeysOptions _opts; - - final Authenticator _auth; - - String? _defaultId; - - PassKeySigner(String namespace, String name, String origin, - {bool? crossOrigin}) - : _opts = PassKeysOptions( - namespace: namespace, - name: name, - origin: origin, - crossOrigin: crossOrigin ?? false, - ), - _auth = Authenticator(true, true); - - @override - String? get defaultId => _defaultId; - - @override - PassKeysOptions get opts => _opts; - - @override - String dummySignature = - "0xe017c9b829f0d550c9a0f1d791d460485b774c5e157d2eaabdf690cba2a62726b3e3a3c5022dc5301d272a752c05053941b1ca608bf6bc8ec7c71dfe15d5305900000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000000000025205f5f63c4a6cebdc67844b75186367e6d2e4f19b976ab0affefb4e981c22435050000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000247b2274797065223a22776562617574686e2e676574222c226368616c6c656e6765223a2200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001d222c226f726967696e223a226170692e776562617574686e2e696f227d000000"; - - @override - Uint8List clientDataHash(PassKeysOptions options, {String? challenge}) { - options.challenge = challenge ?? _randomChallenge(options); - final clientDataJson = jsonEncode({ - "type": options.type, - "challenge": options.challenge, - "origin": options.origin, - "crossOrigin": options.crossOrigin - }); - return Uint8List.fromList(utf8.encode(clientDataJson)); - } - - @override - Uint8List clientDataHash32(PassKeysOptions options, {String? challenge}) { - final dataBuffer = clientDataHash(options, challenge: challenge); - final hash = sha256Hash(dataBuffer); - return Uint8List.fromList(hash.bytes); - } - - @override - String credentialIdToBytes32Hex(List credentialId) { - require(credentialId.length <= 32, "exception: credentialId too long"); - while (credentialId.length < 32) { - credentialId.insert(0, 0); - } - return hexlify(credentialId); - } - - @override - String getAddress({int index = 0, bytes}) { - return credentialIdToBytes32Hex(bytes); - } - - @override - Future> getMessagingSignature(Uint8List signatureBytes) async { - ASN1Parser parser = ASN1Parser(signatureBytes); - ASN1Sequence parsedSignature = parser.nextObject() as ASN1Sequence; - ASN1Integer rValue = parsedSignature.elements[0] as ASN1Integer; - ASN1Integer sValue = parsedSignature.elements[1] as ASN1Integer; - Uint8List rBytes = rValue.valueBytes(); - Uint8List sBytes = sValue.valueBytes(); - - if (shouldRemoveLeadingZero(rBytes)) { - rBytes = rBytes.sublist(1); - } - if (shouldRemoveLeadingZero(sBytes)) { - sBytes = sBytes.sublist(1); - } - - final r = hexlify(rBytes); - final s = hexlify(sBytes); - return [r, s]; - } - - @override - Future personalSign(Uint8List hash, - {int? index, String? id}) async { - require(id != null, "credential id expected"); - final signature = await signToPasskeySignature(hash, id!); - return signature.toUint8List(); - } - - @override - Future register( - String name, bool requiresUserVerification) async { - final attestation = await _register(name, requiresUserVerification); - final authData = _decodeAttestation(attestation); - if (authData.publicKey.length != 2) { - throw "Invalid public key"; - } - _defaultId = authData.credentialId; - return PassKeyPair( - hexToBytes(authData.credentialHex), - authData.credentialId, - [ - Uint256.fromHex(authData.publicKey[0]), - Uint256.fromHex(authData.publicKey[1]), - ], - name, - authData.aaGUID, - DateTime.now(), - ); - } - - @override - Future signToEc(Uint8List hash, - {int? index, String? id}) async { - require(id != null, "credential id expected"); - final signature = await signToPasskeySignature(hash, id!); - return MsgSignature(signature.rs[0].value, signature.rs[1].value, 0); - } - - @override - Future signToPasskeySignature( - Uint8List hash, String credentialId) async { - final webAuthnOptions = _opts; - webAuthnOptions.type = "webauthn.get"; - - // Prepare hash - final hashBase64 = base64Url - .encode(hash) - .replaceAll(RegExp(r'=', multiLine: true, caseSensitive: false), ''); - - // Prepare challenge - final challenge32 = - clientDataHash32(webAuthnOptions, challenge: hashBase64); - - // Authenticate - final assertion = await _authenticate([credentialId], challenge32, true); - final sig = await getMessagingSignature(assertion.signature); - - // Prepare challenge for response - final challenge = clientDataHash(webAuthnOptions, challenge: hashBase64); - final clientDataJSON = utf8.decode(challenge); - int challengePos = clientDataJSON.indexOf(hashBase64); - String challengePrefix = clientDataJSON.substring(0, challengePos); - String challengeSuffix = - clientDataJSON.substring(challengePos + hashBase64.length); - - return PassKeySignature( - base64Url.encode(assertion.selectedCredentialId), - [ - Uint256.fromHex(sig[0]), - Uint256.fromHex(sig[1]), - ], - assertion.authenticatorData, - challengePrefix, - challengeSuffix, - ); - } - - Future _authenticate(List credentialIds, - Uint8List challenge, bool requiresUserVerification) async { - final entity = GetAssertionOptions.fromJson(jsonDecode(_getAssertionJson)); - entity.allowCredentialDescriptorList = credentialIds - .map((credentialId) => PublicKeyCredentialDescriptor( - type: PublicKeyCredentialType.publicKey, - id: base64Url.decode(credentialId))) - .toList(); - if (entity.allowCredentialDescriptorList!.isEmpty) { - throw AuthenticatorException('User not found'); - } - entity.clientDataHash = challenge; - entity.rpId = _opts.namespace; - entity.requireUserVerification = requiresUserVerification; - entity.requireUserPresence = !requiresUserVerification; - return await _auth.getAssertion(entity); - } - - AuthData _decode(dynamic authData) { - // Extract the length of the public key from the authentication data. - final l = (authData[53] << 8) + authData[54]; - - // Calculate the offset for the start of the public key data. - final publicKeyOffset = 55 + l; - - // Extract the public key data from the authentication data. - final pKey = authData.sublist(publicKeyOffset); - - // Extract the credential ID from the authentication data. - final List credentialId = authData.sublist(55, publicKeyOffset); - - // Extract and encode the aaGUID from the authentication data. - final aaGUID = base64Url.encode(authData.sublist(37, 53)); - - // Decode the CBOR-encoded public key and convert it to a map. - final decodedPubKey = cbor.decode(pKey).toObject() as Map; - - // Calculate the hash of the credential ID. - final credentialHex = credentialIdToBytes32Hex(credentialId); - - // Extract x and y coordinates from the decoded public key. - final x = hexlify(decodedPubKey[-2]); - final y = hexlify(decodedPubKey[-3]); - - return AuthData( - credentialHex, base64Url.encode(credentialId), [x, y], aaGUID); - } - - AuthData _decodeAttestation(Attestation attestation) { - final attestationAsCbor = attestation.asCBOR(); - final decodedAttestationAsCbor = - cbor.decode(attestationAsCbor).toObject() as Map; - final authData = decodedAttestationAsCbor["authData"]; - final decode = _decode(authData); - return decode; - } - - String _randomChallenge(PassKeysOptions options) { - final uuid = const Uuid() - .v5buffer(Uuid.NAMESPACE_URL, options.name, List.filled(32, 0)); - return base64Url.encode(uuid); - } - - Future _register( - String name, bool requiresUserVerification) async { - final options = _opts; - options.type = "webauthn.create"; - final hash = clientDataHash32(options); - final entity = - MakeCredentialOptions.fromJson(jsonDecode(_makeCredentialJson)); - entity.userEntity = UserEntity( - id: Uint8List.fromList(utf8.encode(name)), - displayName: name, - name: name, - ); - entity.clientDataHash = hash; - entity.rpEntity.id = options.namespace; - entity.rpEntity.name = options.name; - entity.requireUserVerification = requiresUserVerification; - entity.requireUserPresence = !requiresUserVerification; - return await _auth.makeCredential(entity); - } - - /// [credentialIdToBytes32Hex] converts a 32 byte credentialAddress hex to a base64 string - static String credentialHexToBase64(String credentialHex) { - // Remove the "0x" prefix if present. - if (credentialHex.startsWith("0x")) { - credentialHex = credentialHex.substring(2); - } - - List credentialId = hexToBytes(credentialHex); - - while (credentialId.isNotEmpty && credentialId[0] == 0) { - credentialId.removeAt(0); - } - return base64Url.encode(credentialId); - } -} - -class PassKeysOptions { - final String namespace; - final String name; - final String origin; - bool? crossOrigin; - String? challenge; - String? type; - PassKeysOptions( - {required this.namespace, - required this.name, - required this.origin, - this.crossOrigin, - this.challenge, - this.type}); -} diff --git a/lib/src/signers/private_key_signer.dart b/lib/src/signers/private_key_signer.dart deleted file mode 100644 index bd20676..0000000 --- a/lib/src/signers/private_key_signer.dart +++ /dev/null @@ -1,128 +0,0 @@ -part of '../../variance.dart'; - -class PrivateKeySigner with SecureStorageMixin implements MultiSignerInterface { - final Wallet _credential; - - @override - String dummySignature = - "0xfffffffffffffffffffffffffffffff0000000000000000000000000000000007aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa1c"; - - /// Creates a PrivateKeySigner instance using the provided EthPrivateKey. - /// - /// Parameters: - /// - [privateKey]: The EthPrivateKey used to create the PrivateKeySigner. - /// - [password]: The password for encrypting the private key. - /// - [random]: The Random instance for generating random values. - /// - [scryptN]: Scrypt parameter N (CPU/memory cost) for key derivation. Defaults to 8192. - /// - [p]: Scrypt parameter p (parallelization factor) for key derivation. Defaults to 1. - /// - /// Example: - /// ```dart - /// final ethPrivateKey = EthPrivateKey.fromHex('your_private_key_hex'); - /// final password = 'your_password'; - /// final random = Random.secure(); - /// final privateKeySigner = PrivateKeySigner.create(ethPrivateKey, password, random); - /// ``` - PrivateKeySigner.create( - EthPrivateKey privateKey, String password, Random random, - {int scryptN = 8192, int p = 1}) - : _credential = Wallet.createNew(privateKey, password, random, - scryptN: scryptN, p: p); - - /// Creates a PrivateKeySigner instance with a randomly generated EthPrivateKey. - /// - /// Parameters: - /// - [password]: The password for encrypting the private key. - /// - /// Example: - /// ```dart - /// final password = 'your_password'; - /// final privateKeySigner = PrivateKeySigner.createRandom(password); - /// ``` - factory PrivateKeySigner.createRandom(String password) { - final random = Random.secure(); - final privateKey = EthPrivateKey.createRandom(random); - final credential = Wallet.createNew(privateKey, password, random); - return PrivateKeySigner._internal(credential); - } - - /// Creates a PrivateKeySigner instance from JSON representation. - /// - /// Parameters: - /// - [source]: The JSON representation of the wallet. - /// - [password]: The password for decrypting the private key. - /// - /// Example: - /// ```dart - /// final sourceJson = '{"privateKey": "your_private_key_encrypted", ...}'; - /// final password = 'your_password'; - /// final privateKeySigner = PrivateKeySigner.fromJson(sourceJson, password); - /// ``` - factory PrivateKeySigner.fromJson(String source, String password) => - PrivateKeySigner._internal( - Wallet.fromJson(source, password), - ); - - PrivateKeySigner._internal(this._credential); - - /// Returns the Ethereum address associated with the PrivateKeySigner. - EthereumAddress get address => _credential.privateKey.address; - - /// Returns the public key associated with the PrivateKeySigner. - Uint8List get publicKey => _credential.privateKey.encodedPublicKey; - - @override - String getAddress({int index = 0, bytes}) { - return address.hex; - } - - @override - Future personalSign(Uint8List hash, - {int? index, String? id}) async { - return _credential.privateKey.signPersonalMessageToUint8List(hash); - } - - @override - Future signToEc(Uint8List hash, - {int? index, String? id}) async { - return _credential.privateKey.signToEcSignature(hash); - } - - String toJson() => _credential.toJson(); - - @override - SecureStorageMiddleware withSecureStorage(FlutterSecureStorage secureStorage, - {Authentication? authMiddleware}) { - return SecureStorageMiddleware( - secureStorage: secureStorage, - authMiddleware: authMiddleware, - credential: toJson()); - } - - /// Loads a PrivateKeySigner encrypted credentialJson from secure storage. - /// - /// Parameters: - /// - [storageMiddleware]: The repository for secure storage. - /// - [password]: The password for decrypting the private key. - /// - [options]: Additional options for the authentication operation. - /// - /// Example: - /// ```dart - /// final storageMiddleware = SecureStorageRepository(); // Initialize your storage middleware - /// final password = 'your_password'; - /// final privateKeySigner = await PrivateKeySigner.loadFromSecureStorage( - /// storageMiddleware: storageMiddleware, - /// password: password, - /// options: yourSSAuthOperationOptions, - /// ); - /// ``` - static Future loadFromSecureStorage( - {required SecureStorageRepository storageMiddleware, - required String password, - SSAuthOperationOptions? options}) { - return storageMiddleware - .readCredential(CredentialType.hdwallet, options: options) - .then((value) => - value != null ? PrivateKeySigner.fromJson(value, password) : null); - } -} diff --git a/lib/src/utils/chainbase_api.dart b/lib/src/utils/chainbase_api.dart deleted file mode 100644 index 8e6a88f..0000000 --- a/lib/src/utils/chainbase_api.dart +++ /dev/null @@ -1,416 +0,0 @@ -part of 'package:variance_dart/utils.dart'; - -class ChainBaseApi implements ChainBaseApiBase { - final RestClient _restClient; - final Chain _chain; - - ChainBaseApi({required RestClient restClient, required Chain chain}) - : _restClient = restClient, - _chain = chain; - - @override - Future getERC20TokenMarketPrice( - EthereumAddress tokenAddress) async { - return TokenPriceResponse.fromJson(await _restClient - .get>('/token/price', queryParameters: { - 'contract_address': tokenAddress.hex, - 'chain_id': _chain.chainId - })); - } - - @override - Future getNFTBalancesForAddress( - EthereumAddress address, { - EthereumAddress? tokenAddress, - int page = 1, - int pageSize = 20, - }) async { - return NFTBalancesResponse.fromJson(await _restClient - .get>('/account/nfts', queryParameters: { - 'address': address.hex, - 'chain_id': _chain.chainId, - if (tokenAddress != null) 'contract_address': tokenAddress.hex, - 'page': page, - 'limit': pageSize, - })); - } - - @override - Future getTokenBalancesForAddress( - EthereumAddress address, - {EthereumAddress? tokenAddress, - int page = 1, - int pageSize = 20}) async { - return TokenBalancesResponse.fromJson(await _restClient - .get>('/account/tokens', queryParameters: { - 'address': address.hex, - 'chain_id': _chain.chainId, - if (tokenAddress != null) 'contract_address': tokenAddress.hex, - 'page': page, - 'limit': pageSize, - })); - } - - @override - Future getTokenMetadata( - EthereumAddress tokenAddress, - ) async { - return TokenMetadataResponse.fromJson(await _restClient - .get>('/token/metadata', queryParameters: { - 'contract_address': tokenAddress.hex, - 'chain_id': _chain.chainId, - })); - } - - @override - Future getTokenTransfersForAddress( - EthereumAddress address, { - EthereumAddress? tokenAddress, - BlockNum? fromBlock, - BlockNum? toBlock, - DateTime? fromTime, - DateTime? toTime, - int page = 1, - int pageSize = 20, - }) async { - return TokenTransfersResponse.fromJson( - await _restClient - .get>('/token/transfers', queryParameters: { - 'address': address.hex, - 'chain_id': _chain.chainId, - if (tokenAddress != null) 'contract_address': tokenAddress.hex, - if (fromBlock != null) 'from_block': fromBlock.toBlockParam(), - if (toBlock != null) 'to_block': toBlock.toBlockParam(), - if (fromTime != null) - 'from_timestamp': fromTime.millisecondsSinceEpoch, - if (toTime != null) 'end_timestamp': toTime.millisecondsSinceEpoch, - 'page': page, - 'limit': pageSize, - }), - address.hex); - } - - @override - Future getTransactionsForAddress( - EthereumAddress address, { - EthereumAddress? tokenAddress, - BlockNum? fromBlock, - BlockNum? toBlock, - DateTime? fromTime, - DateTime? toTime, - int page = 1, - int pageSize = 20, - }) async { - return TransactionsResponse.fromJson(await _restClient - .get>('/account/txs', queryParameters: { - 'address': address.hex, - 'chain_id': _chain.chainId, - if (tokenAddress != null) 'contract_address': tokenAddress.hex, - if (fromBlock != null) 'from_block': fromBlock.toBlockParam(), - if (toBlock != null) 'to_block': toBlock.toBlockParam(), - if (fromTime != null) 'from_timestamp': fromTime.millisecondsSinceEpoch, - if (toTime != null) 'end_timestamp': toTime.millisecondsSinceEpoch, - 'page': page, - 'limit': pageSize, - })); - } - - @override - Future resolveENSName(String name, {BlockNum? toBlock}) async { - return ENSResponse.fromJson(await _restClient - .get>('/ens/records', queryParameters: { - 'domain': name, - 'chain_id': 1, - if (toBlock != null) 'to_block': toBlock.toBlockParam() - })); - } - - @override - Future reverseENSAddress(EthereumAddress address, - {BlockNum? toBlock}) async { - return ENSResponse.fromJson(await _restClient - .get>('/ens/reverse', queryParameters: { - 'address': address, - 'chain_id': 1, - if (toBlock != null) 'to_block': toBlock.toBlockParam() - })); - } -} - -/// An abstract class representing the base API for interacting with a blockchain. -/// -/// This class defines methods for retrieving various information related to -/// ERC-20 tokens, NFT balances, token balances, token transfers, transactions, -/// ENS name resolution, and reverse ENS address lookup. -abstract class ChainBaseApiBase { - /// Retrieves the market price of an ERC-20 token. - /// - /// Given the [tokenAddress], this method returns a [TokenPriceResponse] - /// containing information about the market price of the token. - Future getERC20TokenMarketPrice( - EthereumAddress tokenAddress); - - /// Retrieves NFT balances for a specific address. - /// - /// Given the [address], this method returns a [NFTBalancesResponse] with - /// information about NFT balances. Additional parameters like [tokenAddress], - /// [page], and [pageSize] can be specified for more targeted results. - Future getNFTBalancesForAddress( - EthereumAddress address, { - EthereumAddress? tokenAddress, - int page = 1, - int pageSize = 20, - }); - - /// Retrieves token balances for a specific address. - /// - /// Given the [address], this method returns a [TokenBalancesResponse] with - /// information about the token balances. Additional parameters like [tokenAddress], - /// [page], and [pageSize] can be specified for more targeted results. - Future getTokenBalancesForAddress( - EthereumAddress address, - {EthereumAddress? tokenAddress, - int page = 1, - int pageSize = 20}); - - /// Retrieves token metadata for a specific address. - /// - /// Given the [tokenAddress], this method returns a [TokenMetadataResponse] - /// with information about the token metadata. - Future getTokenMetadata( - EthereumAddress tokenAddress, - ); - - /// Retrieves token transfers for a specific address and token. - /// - /// Given the [address] and [tokenAddress], this method returns a - /// [TokenTransfersResponse] with information about token transfers. Additional - /// parameters like [fromBlock], [toBlock], [fromTime], [toTime], [page], and - /// [pageSize] can be specified for more targeted results. - Future getTokenTransfersForAddress( - EthereumAddress address, { - EthereumAddress? tokenAddress, - BlockNum? fromBlock, - BlockNum? toBlock, - DateTime? fromTime, - DateTime? toTime, - int page = 1, - int pageSize = 20, - }); - - /// Retrieves transactions for a specific address. - /// - /// Given the [address], this method returns a [TransactionsResponse] - /// containing information about transactions related to the address. Additional - /// parameters like [fromBlock], [toBlock], [fromTime], [toTime], [page], and - /// [pageSize] can be specified for more targeted results. - Future getTransactionsForAddress( - EthereumAddress address, { - EthereumAddress? tokenAddress, - BlockNum? fromBlock, - BlockNum? toBlock, - DateTime? fromTime, - DateTime? toTime, - int page = 1, - int pageSize = 20, - }); - - /// Resolves an ENS name to its corresponding Ethereum address. - /// - /// Given the [name], this method returns an [ENSResponse] containing - /// information about the Ethereum address associated with the ENS name. - Future resolveENSName(String name, {BlockNum? toBlock}); - - /// Performs a reverse ENS address lookup to obtain the associated ENS name. - /// - /// Given the [address], this method returns an [ENSResponse] with - /// information about the ENS name associated with the Ethereum address. - Future reverseENSAddress(EthereumAddress address, - {BlockNum? toBlock}); -} - -class ChainBaseResponse { - final int code; - final String message; - final int? nextPageNumber; - final int? count; - - ChainBaseResponse({ - required this.code, - required this.message, - this.nextPageNumber, - this.count, - }); -} - -class ENSResponse extends ChainBaseResponse { - final ENS? data; - ENSResponse({ - required super.code, - required super.message, - this.data, - super.nextPageNumber, - super.count, - }); - - factory ENSResponse.fromJson(Map json) { - return ENSResponse( - code: json['code'], - message: json['message'], - data: json['data'] != null - ? json['data'] is List - ? ENS.fromJson(json['data'][0]) - : ENS.fromJson(json['data']) - : null, - nextPageNumber: json['next_page'], - count: json['count'], - ); - } -} - -class NFTBalancesResponse extends ChainBaseResponse { - final List? data; - NFTBalancesResponse({ - required super.code, - required super.message, - this.data, - super.nextPageNumber, - super.count, - }); - - factory NFTBalancesResponse.fromJson(Map json) { - return NFTBalancesResponse( - code: json['code'], - message: json['message'], - data: json['data'] != null - ? List.from(json['data'].map((x) => NFT.fromJson(x))) - : null, - nextPageNumber: json['next_page'], - count: json['count'], - ); - } -} - -class TokenBalancesResponse extends ChainBaseResponse { - final List? data; - TokenBalancesResponse({ - required super.code, - required super.message, - this.data, - super.nextPageNumber, - super.count, - }); - - factory TokenBalancesResponse.fromJson(Map json) { - return TokenBalancesResponse( - code: json['code'], - message: json['message'], - data: json['data'] != null - ? List.from(json['data'].map((x) => Token.fromJson(x))) - : null, - nextPageNumber: json['next_page'], - count: json['count'], - ); - } -} - -class TokenMetadataResponse extends ChainBaseResponse { - final TokenMetadata? data; - - TokenMetadataResponse({ - required super.code, - required super.message, - this.data, - super.nextPageNumber, - super.count, - }); - - factory TokenMetadataResponse.fromJson(Map json) { - return TokenMetadataResponse( - code: json['code'], - message: json['message'], - data: json['data'] != null ? TokenMetadata.fromJson(json['data']) : null, - nextPageNumber: json['next_page'], - count: json['count'], - ); - } -} - -class TokenPriceResponse extends ChainBaseResponse { - final TokenPrice? data; - TokenPriceResponse({ - required super.code, - required super.message, - this.data, - super.nextPageNumber, - super.count, - }); - - factory TokenPriceResponse.fromJson(Map json) { - return TokenPriceResponse( - code: json['code'], - message: json['message'], - data: json['data'] != null ? TokenPrice.fromJson(json['data']) : null, - nextPageNumber: json['next_page'], - count: json['count'], - ); - } -} - -class TokenTransfersResponse extends ChainBaseResponse { - final List? data; - TokenTransfersResponse({ - required super.code, - required super.message, - this.data, - super.nextPageNumber, - super.count, - }); - - factory TokenTransfersResponse.fromJson( - Map json, String caller) { - Map getModifiedJson(Map json) { - if (json['from_address'].toLowerCase() == caller.toLowerCase()) { - json['direction'] = 'SEND'; - } else { - json['direction'] = 'RECEIVE'; - } - return json; - } - - return TokenTransfersResponse( - code: json['code'], - message: json['message'], - data: json['data'] != null - ? List.from(json['data'] - .map((x) => TokenTransfer.fromJson(getModifiedJson(x)))) - : null, - nextPageNumber: json['next_page'], - count: json['count'], - ); - } -} - -class TransactionsResponse extends ChainBaseResponse { - final List? data; - TransactionsResponse({ - required super.code, - required super.message, - this.data, - super.nextPageNumber, - super.count, - }); - - factory TransactionsResponse.fromJson(Map json) { - return TransactionsResponse( - code: json['code'], - message: json['message'], - data: json['data'] != null - ? List.from( - json['data'].map((x) => Transaction.fromJson(x))) - : null, - nextPageNumber: json['next_page'], - count: json['count'], - ); - } -} diff --git a/lib/src/utils/crypto.dart b/lib/src/utils/crypto.dart deleted file mode 100644 index cc9b559..0000000 --- a/lib/src/utils/crypto.dart +++ /dev/null @@ -1,147 +0,0 @@ -part of '../../utils.dart'; - -/// Converts a hex string to a 32bytes `Uint8List`. -/// -/// Parameters: -/// - [hexString]: The input hex string. -/// -/// Returns a Uint8List containing the converted bytes. -/// -/// Example: -/// ```dart -/// final hexString = '0x1a2b3c'; -/// final resultBytes = arrayify(hexString); -/// ``` -Uint8List arrayify(String hexString) { - hexString = hexString.replaceAll(RegExp(r'\s+'), ''); - List bytes = []; - for (int i = 0; i < hexString.length; i += 2) { - String byteHex = hexString.substring(i, i + 2); - int byteValue = int.parse(byteHex, radix: 16); - bytes.add(byteValue); - } - return Uint8List.fromList(bytes); -} - -/// Retrieves the X and Y components of an ECDSA public key from its bytes. -/// -/// Parameters: -/// - [publicKeyBytes]: The bytes of the ECDSA public key. -/// -/// Returns a Future containing a List of two strings representing the X and Y components of the public key. -/// -/// Example: -/// ```dart -/// final publicKeyBytes = Uint8List.fromList([4, 1, 2, 3]); // Replace with actual public key bytes -/// final components = await getPublicKeyFromBytes(publicKeyBytes); -/// print(components); // Output: ['01', '02'] -/// ``` -Future?> getPublicKeyFromBytes(Uint8List publicKeyBytes) async { - final pKey = - await EcdsaPublicKey.importSpkiKey(publicKeyBytes, EllipticCurve.p256); - final jwk = await pKey.exportJsonWebKey(); - if (jwk.containsKey('x') && jwk.containsKey('y')) { - final x = base64Url.normalize(jwk['x']); - final y = base64Url.normalize(jwk['y']); - - final decodedX = hexlify(base64Url.decode(x)); - final decodedY = hexlify(base64Url.decode(y)); - - return [decodedX, decodedY]; - } else { - throw "Invalid public key"; - } -} - -/// Converts a list of integers to a hexadecimal string. -/// -/// Parameters: -/// - [intArray]: The list of integers to be converted. -/// -/// Returns a string representing the hexadecimal value. -/// -/// Example: -/// ```dart -/// final intArray = [1, 15, 255]; -/// final hexString = hexlify(intArray); -/// print(hexString); // Output: '0x01ff' -/// ``` -String hexlify(List intArray) { - var ss = []; - for (int value in intArray) { - ss.add(value.toRadixString(16).padLeft(2, '0')); - } - return "0x${ss.join('')}"; -} - -/// Throws an exception if the specified requirement is not met. -/// -/// Parameters: -/// - [requirement]: The boolean requirement to be checked. -/// - [exception]: The exception message to be thrown if the requirement is not met. -/// -/// Throws an exception with the specified message if the requirement is not met. -/// -/// Example: -/// ```dart -/// final value = 42; -/// require(value > 0, "Value must be greater than 0"); -/// print("Value is valid: $value"); -/// ``` -require(bool requirement, String exception) { - if (!requirement) { - throw Exception(exception); - } -} - -/// Computes the SHA-256 hash of the specified input. -/// -/// Parameters: -/// - [input]: The list of integers representing the input data. -/// -/// Returns a [Digest] object representing the SHA-256 hash. -/// -/// Example: -/// ```dart -/// final data = utf8.encode("Hello, World!"); -/// final hash = sha256Hash(data); -/// print("SHA-256 Hash: ${hash.toString()}"); -/// ``` -Digest sha256Hash(List input) { - return sha256.convert(input); -} - -/// Checks whether the leading zero should be removed from the byte array. -/// -/// Parameters: -/// - [bytes]: The list of integers representing the byte array. -/// -/// Returns `true` if the leading zero should be removed, otherwise `false`. -/// -/// Example: -/// ```dart -/// final byteData = Uint8List.fromList([0x00, 0x01, 0x02, 0x03]); -/// final removeZero = shouldRemoveLeadingZero(byteData); -/// print("Remove Leading Zero: $removeZero"); -/// ``` -bool shouldRemoveLeadingZero(Uint8List bytes) { - return bytes[0] == 0x0 && (bytes[1] & (1 << 7)) != 0; -} - -/// Combines multiple lists of integers into a single list. -/// -/// Parameters: -/// - [buff]: List of lists of integers to be combined. -/// -/// Returns a new list containing all the integers from the input lists. -/// -/// Example: -/// ```dart -/// final list1 = [1, 2, 3]; -/// final list2 = [4, 5, 6]; -/// final combinedList = toBuffer([list1, list2]); -/// print("Combined List: $combinedList"); -/// ``` -List toBuffer(List> buff) { - return List.from(buff.expand((element) => element).toList()); -} diff --git a/lib/src/utils/dio_client.dart b/lib/src/utils/dio_client.dart deleted file mode 100644 index 3ff2c78..0000000 --- a/lib/src/utils/dio_client.dart +++ /dev/null @@ -1,90 +0,0 @@ -part of '../../utils.dart'; - -class DioClient implements RestClient { - final Dio _dio = Dio() - ..interceptors.add(DioCacheInterceptor( - options: CacheOptions( - store: MemCacheStore(maxSize: 10485760, maxEntrySize: 1048576), - policy: CachePolicy.request, - hitCacheOnErrorExcept: [401, 403], - maxStale: const Duration(days: 1), - ), - )); - - DioClient({BaseOptions? baseOptions}) { - _dio.options = baseOptions ?? - BaseOptions( - contentType: 'application/json', - connectTimeout: const Duration(seconds: 30), - receiveTimeout: const Duration(seconds: 30), - sendTimeout: const Duration(seconds: 60), - ); - } - - @override - Future get(String path, - {Object? body, - Map? queryParameters, - Options? options}) async { - try { - final response = await _dio.get( - path, - data: body, - queryParameters: queryParameters, - options: options, - ); - return response.data as T; - } on DioException catch (e) { - log("message: ${e.message}"); - rethrow; - } - } - - @override - Future post(String path, - {Object? body, - Map? queryParameters, - Options? options}) async { - try { - final response = await _dio.post(path, - data: body, queryParameters: queryParameters, options: options); - return response.data as T; - } on DioException catch (e) { - log("message: ${e.message}"); - rethrow; - } - } -} - -/// Rest client utility class using Dio for making HTTP requests over Rest Endpoints. -/// -/// The RestClient class provides methods to perform GET and POST requests with additional caching. -/// It utilizes the Dio library and includes error handling for DioException. -/// The RestClient class is mainly used by the ChainBaseApi class to make requests to the ChainBase API. -abstract class RestClient { - /// Performs a GET request to the provided API URL and returns the response. - /// - /// - [path]: The URL for the GET request. - /// - [body]: (optional) request body. - /// - [queryParameters]: (optional) The query parameters for the GET request. - /// - [options]: (optional) The options to be merged with the base options. - /// - /// Returns a [Future] that completes with the response data of type [T]. - /// - /// Throws a [DioException] if the request fails. - Future get(String path, - {Object? body, Map? queryParameters, Options? options}); - - /// Performs a POST request to the provided API URL with the given [body] and returns the response. - /// - /// - [path]: The URL for the POST request. - /// - [body]: (optional) The request body. - /// - [queryParameters]: (optional) The query parameters for the POST request. - /// - [options]: (optional) The options to be merged with the base options. - /// - /// Returns a [Future] that completes with the response data of type [T]. - /// - /// Throws a [DioException] if the request fails. - Future post(String path, - {Object? body, Map? queryParameters, Options? options}); -} diff --git a/lib/src/utils/local_authentication.dart b/lib/src/utils/local_authentication.dart deleted file mode 100644 index 211a396..0000000 --- a/lib/src/utils/local_authentication.dart +++ /dev/null @@ -1,83 +0,0 @@ -part of '../../utils.dart'; - -class AuthenticationError extends Error { - final String message; - - AuthenticationError(this.message); -} - -class AuthenticationMiddleware implements Authentication { - final LocalAuthentication _auth = LocalAuthentication(); - - @override - Future authenticate( - {required String localizedReason, - AndroidAuthMessages? androidAuthMessages, - IOSAuthMessages? iosAuthMessages, - bool useErrorDialogs = true, - bool stickyAuth = true}) async { - final bool canAuthenticate = await canAuthenticateWithBiometrics(); - - if (!canAuthenticate) { - throw AuthenticationError( - 'Unable to authenticate with biometrics: NO BIOMETRICS ENROLLED'); - } - - try { - final bool authenticated = await _auth.authenticate( - localizedReason: localizedReason, - options: AuthenticationOptions( - useErrorDialogs: useErrorDialogs, - stickyAuth: stickyAuth, - biometricOnly: true, - ), - authMessages: [ - androidAuthMessages ?? - const AndroidAuthMessages( - signInTitle: 'Authentication required!', - cancelButton: 'No thanks', - ), - iosAuthMessages ?? - const IOSAuthMessages( - cancelButton: 'No thanks', - ), - ]); - - if (!authenticated) { - throw AuthenticationError( - 'Unable to authenticate with biometrics: AUTHENTICATION FAILED'); - } - } on PlatformException catch (e) { - if (e.code == auth_error.notAvailable) { - throw AuthenticationError( - 'Unable to authenticate with biometrics: NOT AVAILABLE'); - } else if (e.code == auth_error.notEnrolled) { - throw AuthenticationError( - 'Unable to authenticate with biometrics: NOT ENROLLED'); - } else if (e.code == auth_error.lockedOut || - e.code == auth_error.permanentlyLockedOut) { - throw AuthenticationError( - 'Unable to authenticate with biometrics: LOCKED OUT'); - } else { - rethrow; - } - } - } - - @override - Future canAuthenticateWithBiometrics() async { - final bool canAuthenticateWithBiometrics = await _auth.canCheckBiometrics; - final bool canAuthenticate = - canAuthenticateWithBiometrics || await _auth.isDeviceSupported(); - - if (!canAuthenticate) { - throw AuthenticationError( - 'Unable to authenticate with biometrics: BIOMETRICS NOT SUPPORTED'); - } - - final List availableBiometrics = - await _auth.getAvailableBiometrics(); - - return availableBiometrics.isNotEmpty; - } -} diff --git a/lib/src/utils/models/ens.dart b/lib/src/utils/models/ens.dart deleted file mode 100644 index e36813c..0000000 --- a/lib/src/utils/models/ens.dart +++ /dev/null @@ -1,21 +0,0 @@ -import 'package:freezed_annotation/freezed_annotation.dart'; - -part 'ens.freezed.dart'; -part 'ens.g.dart'; - -@freezed -class ENS with _$ENS { - const factory ENS({ - required String name, - required String address, - required String registrant, - required String owner, - required String resolver, - @JsonKey(name: 'registrant_time') required DateTime registrantTime, - @JsonKey(name: 'expiration_time') required DateTime expirationTime, - @JsonKey(name: 'token_id') required String tokenId, - @JsonKey(name: 'text_records') required dynamic textRecords, - }) = _ENS; - - factory ENS.fromJson(Map json) => _$ENSFromJson(json); -} diff --git a/lib/src/utils/models/ens.freezed.dart b/lib/src/utils/models/ens.freezed.dart deleted file mode 100644 index b061334..0000000 --- a/lib/src/utils/models/ens.freezed.dart +++ /dev/null @@ -1,335 +0,0 @@ -// coverage:ignore-file -// GENERATED CODE - DO NOT MODIFY BY HAND -// ignore_for_file: type=lint -// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target, unnecessary_question_mark - -part of 'ens.dart'; - -// ************************************************************************** -// FreezedGenerator -// ************************************************************************** - -T _$identity(T value) => value; - -final _privateConstructorUsedError = UnsupportedError( - 'It seems like you constructed your class using `MyClass._()`. This constructor is only meant to be used by freezed and you are not supposed to need it nor use it.\nPlease check the documentation here for more information: https://github.com/rrousselGit/freezed#custom-getters-and-methods'); - -ENS _$ENSFromJson(Map json) { - return _ENS.fromJson(json); -} - -/// @nodoc -mixin _$ENS { - String get name => throw _privateConstructorUsedError; - String get address => throw _privateConstructorUsedError; - String get registrant => throw _privateConstructorUsedError; - String get owner => throw _privateConstructorUsedError; - String get resolver => throw _privateConstructorUsedError; - @JsonKey(name: 'registrant_time') - DateTime get registrantTime => throw _privateConstructorUsedError; - @JsonKey(name: 'expiration_time') - DateTime get expirationTime => throw _privateConstructorUsedError; - @JsonKey(name: 'token_id') - String get tokenId => throw _privateConstructorUsedError; - @JsonKey(name: 'text_records') - dynamic get textRecords => throw _privateConstructorUsedError; - - Map toJson() => throw _privateConstructorUsedError; - @JsonKey(ignore: true) - $ENSCopyWith get copyWith => throw _privateConstructorUsedError; -} - -/// @nodoc -abstract class $ENSCopyWith<$Res> { - factory $ENSCopyWith(ENS value, $Res Function(ENS) then) = - _$ENSCopyWithImpl<$Res, ENS>; - @useResult - $Res call( - {String name, - String address, - String registrant, - String owner, - String resolver, - @JsonKey(name: 'registrant_time') DateTime registrantTime, - @JsonKey(name: 'expiration_time') DateTime expirationTime, - @JsonKey(name: 'token_id') String tokenId, - @JsonKey(name: 'text_records') dynamic textRecords}); -} - -/// @nodoc -class _$ENSCopyWithImpl<$Res, $Val extends ENS> implements $ENSCopyWith<$Res> { - _$ENSCopyWithImpl(this._value, this._then); - - // ignore: unused_field - final $Val _value; - // ignore: unused_field - final $Res Function($Val) _then; - - @pragma('vm:prefer-inline') - @override - $Res call({ - Object? name = null, - Object? address = null, - Object? registrant = null, - Object? owner = null, - Object? resolver = null, - Object? registrantTime = null, - Object? expirationTime = null, - Object? tokenId = null, - Object? textRecords = freezed, - }) { - return _then(_value.copyWith( - name: null == name - ? _value.name - : name // ignore: cast_nullable_to_non_nullable - as String, - address: null == address - ? _value.address - : address // ignore: cast_nullable_to_non_nullable - as String, - registrant: null == registrant - ? _value.registrant - : registrant // ignore: cast_nullable_to_non_nullable - as String, - owner: null == owner - ? _value.owner - : owner // ignore: cast_nullable_to_non_nullable - as String, - resolver: null == resolver - ? _value.resolver - : resolver // ignore: cast_nullable_to_non_nullable - as String, - registrantTime: null == registrantTime - ? _value.registrantTime - : registrantTime // ignore: cast_nullable_to_non_nullable - as DateTime, - expirationTime: null == expirationTime - ? _value.expirationTime - : expirationTime // ignore: cast_nullable_to_non_nullable - as DateTime, - tokenId: null == tokenId - ? _value.tokenId - : tokenId // ignore: cast_nullable_to_non_nullable - as String, - textRecords: freezed == textRecords - ? _value.textRecords - : textRecords // ignore: cast_nullable_to_non_nullable - as dynamic, - ) as $Val); - } -} - -/// @nodoc -abstract class _$$ENSImplCopyWith<$Res> implements $ENSCopyWith<$Res> { - factory _$$ENSImplCopyWith(_$ENSImpl value, $Res Function(_$ENSImpl) then) = - __$$ENSImplCopyWithImpl<$Res>; - @override - @useResult - $Res call( - {String name, - String address, - String registrant, - String owner, - String resolver, - @JsonKey(name: 'registrant_time') DateTime registrantTime, - @JsonKey(name: 'expiration_time') DateTime expirationTime, - @JsonKey(name: 'token_id') String tokenId, - @JsonKey(name: 'text_records') dynamic textRecords}); -} - -/// @nodoc -class __$$ENSImplCopyWithImpl<$Res> extends _$ENSCopyWithImpl<$Res, _$ENSImpl> - implements _$$ENSImplCopyWith<$Res> { - __$$ENSImplCopyWithImpl(_$ENSImpl _value, $Res Function(_$ENSImpl) _then) - : super(_value, _then); - - @pragma('vm:prefer-inline') - @override - $Res call({ - Object? name = null, - Object? address = null, - Object? registrant = null, - Object? owner = null, - Object? resolver = null, - Object? registrantTime = null, - Object? expirationTime = null, - Object? tokenId = null, - Object? textRecords = freezed, - }) { - return _then(_$ENSImpl( - name: null == name - ? _value.name - : name // ignore: cast_nullable_to_non_nullable - as String, - address: null == address - ? _value.address - : address // ignore: cast_nullable_to_non_nullable - as String, - registrant: null == registrant - ? _value.registrant - : registrant // ignore: cast_nullable_to_non_nullable - as String, - owner: null == owner - ? _value.owner - : owner // ignore: cast_nullable_to_non_nullable - as String, - resolver: null == resolver - ? _value.resolver - : resolver // ignore: cast_nullable_to_non_nullable - as String, - registrantTime: null == registrantTime - ? _value.registrantTime - : registrantTime // ignore: cast_nullable_to_non_nullable - as DateTime, - expirationTime: null == expirationTime - ? _value.expirationTime - : expirationTime // ignore: cast_nullable_to_non_nullable - as DateTime, - tokenId: null == tokenId - ? _value.tokenId - : tokenId // ignore: cast_nullable_to_non_nullable - as String, - textRecords: freezed == textRecords - ? _value.textRecords - : textRecords // ignore: cast_nullable_to_non_nullable - as dynamic, - )); - } -} - -/// @nodoc -@JsonSerializable() -class _$ENSImpl implements _ENS { - const _$ENSImpl( - {required this.name, - required this.address, - required this.registrant, - required this.owner, - required this.resolver, - @JsonKey(name: 'registrant_time') required this.registrantTime, - @JsonKey(name: 'expiration_time') required this.expirationTime, - @JsonKey(name: 'token_id') required this.tokenId, - @JsonKey(name: 'text_records') required this.textRecords}); - - factory _$ENSImpl.fromJson(Map json) => - _$$ENSImplFromJson(json); - - @override - final String name; - @override - final String address; - @override - final String registrant; - @override - final String owner; - @override - final String resolver; - @override - @JsonKey(name: 'registrant_time') - final DateTime registrantTime; - @override - @JsonKey(name: 'expiration_time') - final DateTime expirationTime; - @override - @JsonKey(name: 'token_id') - final String tokenId; - @override - @JsonKey(name: 'text_records') - final dynamic textRecords; - - @override - String toString() { - return 'ENS(name: $name, address: $address, registrant: $registrant, owner: $owner, resolver: $resolver, registrantTime: $registrantTime, expirationTime: $expirationTime, tokenId: $tokenId, textRecords: $textRecords)'; - } - - @override - bool operator ==(Object other) { - return identical(this, other) || - (other.runtimeType == runtimeType && - other is _$ENSImpl && - (identical(other.name, name) || other.name == name) && - (identical(other.address, address) || other.address == address) && - (identical(other.registrant, registrant) || - other.registrant == registrant) && - (identical(other.owner, owner) || other.owner == owner) && - (identical(other.resolver, resolver) || - other.resolver == resolver) && - (identical(other.registrantTime, registrantTime) || - other.registrantTime == registrantTime) && - (identical(other.expirationTime, expirationTime) || - other.expirationTime == expirationTime) && - (identical(other.tokenId, tokenId) || other.tokenId == tokenId) && - const DeepCollectionEquality() - .equals(other.textRecords, textRecords)); - } - - @JsonKey(ignore: true) - @override - int get hashCode => Object.hash( - runtimeType, - name, - address, - registrant, - owner, - resolver, - registrantTime, - expirationTime, - tokenId, - const DeepCollectionEquality().hash(textRecords)); - - @JsonKey(ignore: true) - @override - @pragma('vm:prefer-inline') - _$$ENSImplCopyWith<_$ENSImpl> get copyWith => - __$$ENSImplCopyWithImpl<_$ENSImpl>(this, _$identity); - - @override - Map toJson() { - return _$$ENSImplToJson( - this, - ); - } -} - -abstract class _ENS implements ENS { - const factory _ENS( - {required final String name, - required final String address, - required final String registrant, - required final String owner, - required final String resolver, - @JsonKey(name: 'registrant_time') required final DateTime registrantTime, - @JsonKey(name: 'expiration_time') required final DateTime expirationTime, - @JsonKey(name: 'token_id') required final String tokenId, - @JsonKey(name: 'text_records') - required final dynamic textRecords}) = _$ENSImpl; - - factory _ENS.fromJson(Map json) = _$ENSImpl.fromJson; - - @override - String get name; - @override - String get address; - @override - String get registrant; - @override - String get owner; - @override - String get resolver; - @override - @JsonKey(name: 'registrant_time') - DateTime get registrantTime; - @override - @JsonKey(name: 'expiration_time') - DateTime get expirationTime; - @override - @JsonKey(name: 'token_id') - String get tokenId; - @override - @JsonKey(name: 'text_records') - dynamic get textRecords; - @override - @JsonKey(ignore: true) - _$$ENSImplCopyWith<_$ENSImpl> get copyWith => - throw _privateConstructorUsedError; -} diff --git a/lib/src/utils/models/ens.g.dart b/lib/src/utils/models/ens.g.dart deleted file mode 100644 index b027b84..0000000 --- a/lib/src/utils/models/ens.g.dart +++ /dev/null @@ -1,31 +0,0 @@ -// GENERATED CODE - DO NOT MODIFY BY HAND - -part of 'ens.dart'; - -// ************************************************************************** -// JsonSerializableGenerator -// ************************************************************************** - -_$ENSImpl _$$ENSImplFromJson(Map json) => _$ENSImpl( - name: json['name'] as String, - address: json['address'] as String, - registrant: json['registrant'] as String, - owner: json['owner'] as String, - resolver: json['resolver'] as String, - registrantTime: DateTime.parse(json['registrant_time'] as String), - expirationTime: DateTime.parse(json['expiration_time'] as String), - tokenId: json['token_id'] as String, - textRecords: json['text_records'], - ); - -Map _$$ENSImplToJson(_$ENSImpl instance) => { - 'name': instance.name, - 'address': instance.address, - 'registrant': instance.registrant, - 'owner': instance.owner, - 'resolver': instance.resolver, - 'registrant_time': instance.registrantTime.toIso8601String(), - 'expiration_time': instance.expirationTime.toIso8601String(), - 'token_id': instance.tokenId, - 'text_records': instance.textRecords, - }; diff --git a/lib/src/utils/models/metadata.dart b/lib/src/utils/models/metadata.dart deleted file mode 100644 index f07005d..0000000 --- a/lib/src/utils/models/metadata.dart +++ /dev/null @@ -1,26 +0,0 @@ -import 'package:freezed_annotation/freezed_annotation.dart'; -import 'package:variance_dart/utils.dart' - show BigIntConverter, TokenLogo, TokenUrl; -import 'package:variance_dart/variance.dart' show Uint256; - -part 'metadata.freezed.dart'; -part 'metadata.g.dart'; - -@freezed -class TokenMetadata with _$TokenMetadata { - const factory TokenMetadata({ - @JsonKey(name: 'contract_address') required String contractAddress, - required num decimals, - required String name, - required String symbol, - @BigIntConverter() - @JsonKey(name: 'total_supply') - required Uint256 totalSupply, - required List? logos, - required List? urls, - @JsonKey(name: 'current_usd_price') required num? currentUsdPrice, - }) = _TokenMetadata; - - factory TokenMetadata.fromJson(Map json) => - _$TokenMetadataFromJson(json); -} diff --git a/lib/src/utils/models/metadata.freezed.dart b/lib/src/utils/models/metadata.freezed.dart deleted file mode 100644 index 160e5c3..0000000 --- a/lib/src/utils/models/metadata.freezed.dart +++ /dev/null @@ -1,343 +0,0 @@ -// coverage:ignore-file -// GENERATED CODE - DO NOT MODIFY BY HAND -// ignore_for_file: type=lint -// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target, unnecessary_question_mark - -part of 'metadata.dart'; - -// ************************************************************************** -// FreezedGenerator -// ************************************************************************** - -T _$identity(T value) => value; - -final _privateConstructorUsedError = UnsupportedError( - 'It seems like you constructed your class using `MyClass._()`. This constructor is only meant to be used by freezed and you are not supposed to need it nor use it.\nPlease check the documentation here for more information: https://github.com/rrousselGit/freezed#custom-getters-and-methods'); - -TokenMetadata _$TokenMetadataFromJson(Map json) { - return _TokenMetadata.fromJson(json); -} - -/// @nodoc -mixin _$TokenMetadata { - @JsonKey(name: 'contract_address') - String get contractAddress => throw _privateConstructorUsedError; - num get decimals => throw _privateConstructorUsedError; - String get name => throw _privateConstructorUsedError; - String get symbol => throw _privateConstructorUsedError; - @BigIntConverter() - @JsonKey(name: 'total_supply') - Uint256 get totalSupply => throw _privateConstructorUsedError; - List? get logos => throw _privateConstructorUsedError; - List? get urls => throw _privateConstructorUsedError; - @JsonKey(name: 'current_usd_price') - num? get currentUsdPrice => throw _privateConstructorUsedError; - - Map toJson() => throw _privateConstructorUsedError; - @JsonKey(ignore: true) - $TokenMetadataCopyWith get copyWith => - throw _privateConstructorUsedError; -} - -/// @nodoc -abstract class $TokenMetadataCopyWith<$Res> { - factory $TokenMetadataCopyWith( - TokenMetadata value, $Res Function(TokenMetadata) then) = - _$TokenMetadataCopyWithImpl<$Res, TokenMetadata>; - @useResult - $Res call( - {@JsonKey(name: 'contract_address') String contractAddress, - num decimals, - String name, - String symbol, - @BigIntConverter() @JsonKey(name: 'total_supply') Uint256 totalSupply, - List? logos, - List? urls, - @JsonKey(name: 'current_usd_price') num? currentUsdPrice}); -} - -/// @nodoc -class _$TokenMetadataCopyWithImpl<$Res, $Val extends TokenMetadata> - implements $TokenMetadataCopyWith<$Res> { - _$TokenMetadataCopyWithImpl(this._value, this._then); - - // ignore: unused_field - final $Val _value; - // ignore: unused_field - final $Res Function($Val) _then; - - @pragma('vm:prefer-inline') - @override - $Res call({ - Object? contractAddress = null, - Object? decimals = null, - Object? name = null, - Object? symbol = null, - Object? totalSupply = null, - Object? logos = freezed, - Object? urls = freezed, - Object? currentUsdPrice = freezed, - }) { - return _then(_value.copyWith( - contractAddress: null == contractAddress - ? _value.contractAddress - : contractAddress // ignore: cast_nullable_to_non_nullable - as String, - decimals: null == decimals - ? _value.decimals - : decimals // ignore: cast_nullable_to_non_nullable - as num, - name: null == name - ? _value.name - : name // ignore: cast_nullable_to_non_nullable - as String, - symbol: null == symbol - ? _value.symbol - : symbol // ignore: cast_nullable_to_non_nullable - as String, - totalSupply: null == totalSupply - ? _value.totalSupply - : totalSupply // ignore: cast_nullable_to_non_nullable - as Uint256, - logos: freezed == logos - ? _value.logos - : logos // ignore: cast_nullable_to_non_nullable - as List?, - urls: freezed == urls - ? _value.urls - : urls // ignore: cast_nullable_to_non_nullable - as List?, - currentUsdPrice: freezed == currentUsdPrice - ? _value.currentUsdPrice - : currentUsdPrice // ignore: cast_nullable_to_non_nullable - as num?, - ) as $Val); - } -} - -/// @nodoc -abstract class _$$TokenMetadataImplCopyWith<$Res> - implements $TokenMetadataCopyWith<$Res> { - factory _$$TokenMetadataImplCopyWith( - _$TokenMetadataImpl value, $Res Function(_$TokenMetadataImpl) then) = - __$$TokenMetadataImplCopyWithImpl<$Res>; - @override - @useResult - $Res call( - {@JsonKey(name: 'contract_address') String contractAddress, - num decimals, - String name, - String symbol, - @BigIntConverter() @JsonKey(name: 'total_supply') Uint256 totalSupply, - List? logos, - List? urls, - @JsonKey(name: 'current_usd_price') num? currentUsdPrice}); -} - -/// @nodoc -class __$$TokenMetadataImplCopyWithImpl<$Res> - extends _$TokenMetadataCopyWithImpl<$Res, _$TokenMetadataImpl> - implements _$$TokenMetadataImplCopyWith<$Res> { - __$$TokenMetadataImplCopyWithImpl( - _$TokenMetadataImpl _value, $Res Function(_$TokenMetadataImpl) _then) - : super(_value, _then); - - @pragma('vm:prefer-inline') - @override - $Res call({ - Object? contractAddress = null, - Object? decimals = null, - Object? name = null, - Object? symbol = null, - Object? totalSupply = null, - Object? logos = freezed, - Object? urls = freezed, - Object? currentUsdPrice = freezed, - }) { - return _then(_$TokenMetadataImpl( - contractAddress: null == contractAddress - ? _value.contractAddress - : contractAddress // ignore: cast_nullable_to_non_nullable - as String, - decimals: null == decimals - ? _value.decimals - : decimals // ignore: cast_nullable_to_non_nullable - as num, - name: null == name - ? _value.name - : name // ignore: cast_nullable_to_non_nullable - as String, - symbol: null == symbol - ? _value.symbol - : symbol // ignore: cast_nullable_to_non_nullable - as String, - totalSupply: null == totalSupply - ? _value.totalSupply - : totalSupply // ignore: cast_nullable_to_non_nullable - as Uint256, - logos: freezed == logos - ? _value._logos - : logos // ignore: cast_nullable_to_non_nullable - as List?, - urls: freezed == urls - ? _value._urls - : urls // ignore: cast_nullable_to_non_nullable - as List?, - currentUsdPrice: freezed == currentUsdPrice - ? _value.currentUsdPrice - : currentUsdPrice // ignore: cast_nullable_to_non_nullable - as num?, - )); - } -} - -/// @nodoc -@JsonSerializable() -class _$TokenMetadataImpl implements _TokenMetadata { - const _$TokenMetadataImpl( - {@JsonKey(name: 'contract_address') required this.contractAddress, - required this.decimals, - required this.name, - required this.symbol, - @BigIntConverter() - @JsonKey(name: 'total_supply') - required this.totalSupply, - required final List? logos, - required final List? urls, - @JsonKey(name: 'current_usd_price') required this.currentUsdPrice}) - : _logos = logos, - _urls = urls; - - factory _$TokenMetadataImpl.fromJson(Map json) => - _$$TokenMetadataImplFromJson(json); - - @override - @JsonKey(name: 'contract_address') - final String contractAddress; - @override - final num decimals; - @override - final String name; - @override - final String symbol; - @override - @BigIntConverter() - @JsonKey(name: 'total_supply') - final Uint256 totalSupply; - final List? _logos; - @override - List? get logos { - final value = _logos; - if (value == null) return null; - if (_logos is EqualUnmodifiableListView) return _logos; - // ignore: implicit_dynamic_type - return EqualUnmodifiableListView(value); - } - - final List? _urls; - @override - List? get urls { - final value = _urls; - if (value == null) return null; - if (_urls is EqualUnmodifiableListView) return _urls; - // ignore: implicit_dynamic_type - return EqualUnmodifiableListView(value); - } - - @override - @JsonKey(name: 'current_usd_price') - final num? currentUsdPrice; - - @override - String toString() { - return 'TokenMetadata(contractAddress: $contractAddress, decimals: $decimals, name: $name, symbol: $symbol, totalSupply: $totalSupply, logos: $logos, urls: $urls, currentUsdPrice: $currentUsdPrice)'; - } - - @override - bool operator ==(Object other) { - return identical(this, other) || - (other.runtimeType == runtimeType && - other is _$TokenMetadataImpl && - (identical(other.contractAddress, contractAddress) || - other.contractAddress == contractAddress) && - (identical(other.decimals, decimals) || - other.decimals == decimals) && - (identical(other.name, name) || other.name == name) && - (identical(other.symbol, symbol) || other.symbol == symbol) && - (identical(other.totalSupply, totalSupply) || - other.totalSupply == totalSupply) && - const DeepCollectionEquality().equals(other._logos, _logos) && - const DeepCollectionEquality().equals(other._urls, _urls) && - (identical(other.currentUsdPrice, currentUsdPrice) || - other.currentUsdPrice == currentUsdPrice)); - } - - @JsonKey(ignore: true) - @override - int get hashCode => Object.hash( - runtimeType, - contractAddress, - decimals, - name, - symbol, - totalSupply, - const DeepCollectionEquality().hash(_logos), - const DeepCollectionEquality().hash(_urls), - currentUsdPrice); - - @JsonKey(ignore: true) - @override - @pragma('vm:prefer-inline') - _$$TokenMetadataImplCopyWith<_$TokenMetadataImpl> get copyWith => - __$$TokenMetadataImplCopyWithImpl<_$TokenMetadataImpl>(this, _$identity); - - @override - Map toJson() { - return _$$TokenMetadataImplToJson( - this, - ); - } -} - -abstract class _TokenMetadata implements TokenMetadata { - const factory _TokenMetadata( - {@JsonKey(name: 'contract_address') required final String contractAddress, - required final num decimals, - required final String name, - required final String symbol, - @BigIntConverter() - @JsonKey(name: 'total_supply') - required final Uint256 totalSupply, - required final List? logos, - required final List? urls, - @JsonKey(name: 'current_usd_price') - required final num? currentUsdPrice}) = _$TokenMetadataImpl; - - factory _TokenMetadata.fromJson(Map json) = - _$TokenMetadataImpl.fromJson; - - @override - @JsonKey(name: 'contract_address') - String get contractAddress; - @override - num get decimals; - @override - String get name; - @override - String get symbol; - @override - @BigIntConverter() - @JsonKey(name: 'total_supply') - Uint256 get totalSupply; - @override - List? get logos; - @override - List? get urls; - @override - @JsonKey(name: 'current_usd_price') - num? get currentUsdPrice; - @override - @JsonKey(ignore: true) - _$$TokenMetadataImplCopyWith<_$TokenMetadataImpl> get copyWith => - throw _privateConstructorUsedError; -} diff --git a/lib/src/utils/models/metadata.g.dart b/lib/src/utils/models/metadata.g.dart deleted file mode 100644 index d119b29..0000000 --- a/lib/src/utils/models/metadata.g.dart +++ /dev/null @@ -1,35 +0,0 @@ -// GENERATED CODE - DO NOT MODIFY BY HAND - -part of 'metadata.dart'; - -// ************************************************************************** -// JsonSerializableGenerator -// ************************************************************************** - -_$TokenMetadataImpl _$$TokenMetadataImplFromJson(Map json) => - _$TokenMetadataImpl( - contractAddress: json['contract_address'] as String, - decimals: json['decimals'] as num, - name: json['name'] as String, - symbol: json['symbol'] as String, - totalSupply: const BigIntConverter().fromJson(json['total_supply']), - logos: (json['logos'] as List?) - ?.map((e) => TokenLogo.fromJson(e as Map)) - .toList(), - urls: (json['urls'] as List?) - ?.map((e) => TokenUrl.fromJson(e as Map)) - .toList(), - currentUsdPrice: json['current_usd_price'] as num?, - ); - -Map _$$TokenMetadataImplToJson(_$TokenMetadataImpl instance) => - { - 'contract_address': instance.contractAddress, - 'decimals': instance.decimals, - 'name': instance.name, - 'symbol': instance.symbol, - 'total_supply': const BigIntConverter().toJson(instance.totalSupply), - 'logos': instance.logos, - 'urls': instance.urls, - 'current_usd_price': instance.currentUsdPrice, - }; diff --git a/lib/src/utils/models/nft.dart b/lib/src/utils/models/nft.dart deleted file mode 100644 index 377331a..0000000 --- a/lib/src/utils/models/nft.dart +++ /dev/null @@ -1,138 +0,0 @@ -import 'package:freezed_annotation/freezed_annotation.dart'; - -part 'nft.freezed.dart'; -part 'nft.g.dart'; - -@freezed -class NFT with _$NFT { - const factory NFT({ - @JsonKey(name: 'contract_address') required String contractAddress, - @JsonKey(name: 'erc_type') required String? ercType, - @JsonKey(name: 'floor_prices') required List? floorPrices, - @JsonKey(name: 'image_uri') required String? imageUri, - required NFTMetadata? metadata, - @JsonKey(name: 'mint_time') required DateTime mintTime, - @JsonKey(name: 'mint_transaction_hash') required String mintTransactionHash, - required String? name, - required String? owner, - @JsonKey(name: 'rarity_rank') required num? rarityRank, - @JsonKey(name: 'rarity_score') required num? rarityScore, - required String symbol, - @JsonKey(name: 'token_id') required String tokenId, - @JsonKey(name: 'token_uri') required String? tokenUri, - required num? total, - @JsonKey(name: 'total_string') required String? totalString, - required List? traits, - }) = _NFT; - - factory NFT.fromJson(Map json) => _$NFTFromJson(json); -} - -class NFTMetadata { - NFTMetadata({ - required this.attributes, - required this.backgroundImage, - required this.description, - required this.image, - required this.imageUrl, - required this.isNormalized, - required this.name, - required this.nameLength, - required this.segmentLength, - required this.url, - required this.version, - }); - - factory NFTMetadata.fromJson(Map json) => NFTMetadata( - attributes: json['attributes'] != null - ? List.from( - json['attributes'].map((x) => NFTAttributes.fromJson(x))) - : null, - backgroundImage: json['background_image'], - description: json['description'], - image: json['image'], - imageUrl: json['image_url'], - isNormalized: json['is_normalized'], - name: json['name'], - nameLength: json['name_length'], - segmentLength: json['segment_length'], - url: json['url'], - version: json['version'], - ); - - final List? attributes; - final String? backgroundImage; - final String? description; - final String? image; - final String? imageUrl; - final bool? isNormalized; - final String? name; - final num? nameLength; - final num? segmentLength; - final String? url; - final num? version; - - Map toJson() => { - 'attributes': attributes != null - ? attributes!.map((x) => x.toJson()).toList() - : null, - 'background_image': backgroundImage, - 'description': description, - 'image': image, - 'image_url': imageUrl, - 'is_normalized': isNormalized, - 'name': name, - 'name_length': nameLength, - 'segment_length': segmentLength, - 'url': url, - 'version': version, - }; -} - -class NFTAttributes { - NFTAttributes({ - required this.displayType, - required this.traitType, - required this.value, - }); - - factory NFTAttributes.fromJson(Map json) => NFTAttributes( - displayType: json['display_type'], - traitType: json['trait_type'], - value: json['value'], - ); - - final String? displayType; - final String? traitType; - final dynamic value; - - Map toJson() => { - 'display_type': displayType, - 'trait_type': traitType, - 'value': value, - }; -} - -class NFTFloorPrice { - NFTFloorPrice({ - required this.address, - required this.symbol, - required this.value, - }); - - factory NFTFloorPrice.fromJson(Map json) => NFTFloorPrice( - address: json['address'], - symbol: json['symbol'], - value: json['value'], - ); - - final String address; - final String symbol; - final String value; - - Map toJson() => { - 'address': address, - 'symbol': symbol, - 'value': value, - }; -} diff --git a/lib/src/utils/models/nft.freezed.dart b/lib/src/utils/models/nft.freezed.dart deleted file mode 100644 index 4163272..0000000 --- a/lib/src/utils/models/nft.freezed.dart +++ /dev/null @@ -1,548 +0,0 @@ -// coverage:ignore-file -// GENERATED CODE - DO NOT MODIFY BY HAND -// ignore_for_file: type=lint -// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target, unnecessary_question_mark - -part of 'nft.dart'; - -// ************************************************************************** -// FreezedGenerator -// ************************************************************************** - -T _$identity(T value) => value; - -final _privateConstructorUsedError = UnsupportedError( - 'It seems like you constructed your class using `MyClass._()`. This constructor is only meant to be used by freezed and you are not supposed to need it nor use it.\nPlease check the documentation here for more information: https://github.com/rrousselGit/freezed#custom-getters-and-methods'); - -NFT _$NFTFromJson(Map json) { - return _NFT.fromJson(json); -} - -/// @nodoc -mixin _$NFT { - @JsonKey(name: 'contract_address') - String get contractAddress => throw _privateConstructorUsedError; - @JsonKey(name: 'erc_type') - String? get ercType => throw _privateConstructorUsedError; - @JsonKey(name: 'floor_prices') - List? get floorPrices => throw _privateConstructorUsedError; - @JsonKey(name: 'image_uri') - String? get imageUri => throw _privateConstructorUsedError; - NFTMetadata? get metadata => throw _privateConstructorUsedError; - @JsonKey(name: 'mint_time') - DateTime get mintTime => throw _privateConstructorUsedError; - @JsonKey(name: 'mint_transaction_hash') - String get mintTransactionHash => throw _privateConstructorUsedError; - String? get name => throw _privateConstructorUsedError; - String? get owner => throw _privateConstructorUsedError; - @JsonKey(name: 'rarity_rank') - num? get rarityRank => throw _privateConstructorUsedError; - @JsonKey(name: 'rarity_score') - num? get rarityScore => throw _privateConstructorUsedError; - String get symbol => throw _privateConstructorUsedError; - @JsonKey(name: 'token_id') - String get tokenId => throw _privateConstructorUsedError; - @JsonKey(name: 'token_uri') - String? get tokenUri => throw _privateConstructorUsedError; - num? get total => throw _privateConstructorUsedError; - @JsonKey(name: 'total_string') - String? get totalString => throw _privateConstructorUsedError; - List? get traits => throw _privateConstructorUsedError; - - Map toJson() => throw _privateConstructorUsedError; - @JsonKey(ignore: true) - $NFTCopyWith get copyWith => throw _privateConstructorUsedError; -} - -/// @nodoc -abstract class $NFTCopyWith<$Res> { - factory $NFTCopyWith(NFT value, $Res Function(NFT) then) = - _$NFTCopyWithImpl<$Res, NFT>; - @useResult - $Res call( - {@JsonKey(name: 'contract_address') String contractAddress, - @JsonKey(name: 'erc_type') String? ercType, - @JsonKey(name: 'floor_prices') List? floorPrices, - @JsonKey(name: 'image_uri') String? imageUri, - NFTMetadata? metadata, - @JsonKey(name: 'mint_time') DateTime mintTime, - @JsonKey(name: 'mint_transaction_hash') String mintTransactionHash, - String? name, - String? owner, - @JsonKey(name: 'rarity_rank') num? rarityRank, - @JsonKey(name: 'rarity_score') num? rarityScore, - String symbol, - @JsonKey(name: 'token_id') String tokenId, - @JsonKey(name: 'token_uri') String? tokenUri, - num? total, - @JsonKey(name: 'total_string') String? totalString, - List? traits}); -} - -/// @nodoc -class _$NFTCopyWithImpl<$Res, $Val extends NFT> implements $NFTCopyWith<$Res> { - _$NFTCopyWithImpl(this._value, this._then); - - // ignore: unused_field - final $Val _value; - // ignore: unused_field - final $Res Function($Val) _then; - - @pragma('vm:prefer-inline') - @override - $Res call({ - Object? contractAddress = null, - Object? ercType = freezed, - Object? floorPrices = freezed, - Object? imageUri = freezed, - Object? metadata = freezed, - Object? mintTime = null, - Object? mintTransactionHash = null, - Object? name = freezed, - Object? owner = freezed, - Object? rarityRank = freezed, - Object? rarityScore = freezed, - Object? symbol = null, - Object? tokenId = null, - Object? tokenUri = freezed, - Object? total = freezed, - Object? totalString = freezed, - Object? traits = freezed, - }) { - return _then(_value.copyWith( - contractAddress: null == contractAddress - ? _value.contractAddress - : contractAddress // ignore: cast_nullable_to_non_nullable - as String, - ercType: freezed == ercType - ? _value.ercType - : ercType // ignore: cast_nullable_to_non_nullable - as String?, - floorPrices: freezed == floorPrices - ? _value.floorPrices - : floorPrices // ignore: cast_nullable_to_non_nullable - as List?, - imageUri: freezed == imageUri - ? _value.imageUri - : imageUri // ignore: cast_nullable_to_non_nullable - as String?, - metadata: freezed == metadata - ? _value.metadata - : metadata // ignore: cast_nullable_to_non_nullable - as NFTMetadata?, - mintTime: null == mintTime - ? _value.mintTime - : mintTime // ignore: cast_nullable_to_non_nullable - as DateTime, - mintTransactionHash: null == mintTransactionHash - ? _value.mintTransactionHash - : mintTransactionHash // ignore: cast_nullable_to_non_nullable - as String, - name: freezed == name - ? _value.name - : name // ignore: cast_nullable_to_non_nullable - as String?, - owner: freezed == owner - ? _value.owner - : owner // ignore: cast_nullable_to_non_nullable - as String?, - rarityRank: freezed == rarityRank - ? _value.rarityRank - : rarityRank // ignore: cast_nullable_to_non_nullable - as num?, - rarityScore: freezed == rarityScore - ? _value.rarityScore - : rarityScore // ignore: cast_nullable_to_non_nullable - as num?, - symbol: null == symbol - ? _value.symbol - : symbol // ignore: cast_nullable_to_non_nullable - as String, - tokenId: null == tokenId - ? _value.tokenId - : tokenId // ignore: cast_nullable_to_non_nullable - as String, - tokenUri: freezed == tokenUri - ? _value.tokenUri - : tokenUri // ignore: cast_nullable_to_non_nullable - as String?, - total: freezed == total - ? _value.total - : total // ignore: cast_nullable_to_non_nullable - as num?, - totalString: freezed == totalString - ? _value.totalString - : totalString // ignore: cast_nullable_to_non_nullable - as String?, - traits: freezed == traits - ? _value.traits - : traits // ignore: cast_nullable_to_non_nullable - as List?, - ) as $Val); - } -} - -/// @nodoc -abstract class _$$NFTImplCopyWith<$Res> implements $NFTCopyWith<$Res> { - factory _$$NFTImplCopyWith(_$NFTImpl value, $Res Function(_$NFTImpl) then) = - __$$NFTImplCopyWithImpl<$Res>; - @override - @useResult - $Res call( - {@JsonKey(name: 'contract_address') String contractAddress, - @JsonKey(name: 'erc_type') String? ercType, - @JsonKey(name: 'floor_prices') List? floorPrices, - @JsonKey(name: 'image_uri') String? imageUri, - NFTMetadata? metadata, - @JsonKey(name: 'mint_time') DateTime mintTime, - @JsonKey(name: 'mint_transaction_hash') String mintTransactionHash, - String? name, - String? owner, - @JsonKey(name: 'rarity_rank') num? rarityRank, - @JsonKey(name: 'rarity_score') num? rarityScore, - String symbol, - @JsonKey(name: 'token_id') String tokenId, - @JsonKey(name: 'token_uri') String? tokenUri, - num? total, - @JsonKey(name: 'total_string') String? totalString, - List? traits}); -} - -/// @nodoc -class __$$NFTImplCopyWithImpl<$Res> extends _$NFTCopyWithImpl<$Res, _$NFTImpl> - implements _$$NFTImplCopyWith<$Res> { - __$$NFTImplCopyWithImpl(_$NFTImpl _value, $Res Function(_$NFTImpl) _then) - : super(_value, _then); - - @pragma('vm:prefer-inline') - @override - $Res call({ - Object? contractAddress = null, - Object? ercType = freezed, - Object? floorPrices = freezed, - Object? imageUri = freezed, - Object? metadata = freezed, - Object? mintTime = null, - Object? mintTransactionHash = null, - Object? name = freezed, - Object? owner = freezed, - Object? rarityRank = freezed, - Object? rarityScore = freezed, - Object? symbol = null, - Object? tokenId = null, - Object? tokenUri = freezed, - Object? total = freezed, - Object? totalString = freezed, - Object? traits = freezed, - }) { - return _then(_$NFTImpl( - contractAddress: null == contractAddress - ? _value.contractAddress - : contractAddress // ignore: cast_nullable_to_non_nullable - as String, - ercType: freezed == ercType - ? _value.ercType - : ercType // ignore: cast_nullable_to_non_nullable - as String?, - floorPrices: freezed == floorPrices - ? _value._floorPrices - : floorPrices // ignore: cast_nullable_to_non_nullable - as List?, - imageUri: freezed == imageUri - ? _value.imageUri - : imageUri // ignore: cast_nullable_to_non_nullable - as String?, - metadata: freezed == metadata - ? _value.metadata - : metadata // ignore: cast_nullable_to_non_nullable - as NFTMetadata?, - mintTime: null == mintTime - ? _value.mintTime - : mintTime // ignore: cast_nullable_to_non_nullable - as DateTime, - mintTransactionHash: null == mintTransactionHash - ? _value.mintTransactionHash - : mintTransactionHash // ignore: cast_nullable_to_non_nullable - as String, - name: freezed == name - ? _value.name - : name // ignore: cast_nullable_to_non_nullable - as String?, - owner: freezed == owner - ? _value.owner - : owner // ignore: cast_nullable_to_non_nullable - as String?, - rarityRank: freezed == rarityRank - ? _value.rarityRank - : rarityRank // ignore: cast_nullable_to_non_nullable - as num?, - rarityScore: freezed == rarityScore - ? _value.rarityScore - : rarityScore // ignore: cast_nullable_to_non_nullable - as num?, - symbol: null == symbol - ? _value.symbol - : symbol // ignore: cast_nullable_to_non_nullable - as String, - tokenId: null == tokenId - ? _value.tokenId - : tokenId // ignore: cast_nullable_to_non_nullable - as String, - tokenUri: freezed == tokenUri - ? _value.tokenUri - : tokenUri // ignore: cast_nullable_to_non_nullable - as String?, - total: freezed == total - ? _value.total - : total // ignore: cast_nullable_to_non_nullable - as num?, - totalString: freezed == totalString - ? _value.totalString - : totalString // ignore: cast_nullable_to_non_nullable - as String?, - traits: freezed == traits - ? _value._traits - : traits // ignore: cast_nullable_to_non_nullable - as List?, - )); - } -} - -/// @nodoc -@JsonSerializable() -class _$NFTImpl implements _NFT { - const _$NFTImpl( - {@JsonKey(name: 'contract_address') required this.contractAddress, - @JsonKey(name: 'erc_type') required this.ercType, - @JsonKey(name: 'floor_prices') - required final List? floorPrices, - @JsonKey(name: 'image_uri') required this.imageUri, - required this.metadata, - @JsonKey(name: 'mint_time') required this.mintTime, - @JsonKey(name: 'mint_transaction_hash') required this.mintTransactionHash, - required this.name, - required this.owner, - @JsonKey(name: 'rarity_rank') required this.rarityRank, - @JsonKey(name: 'rarity_score') required this.rarityScore, - required this.symbol, - @JsonKey(name: 'token_id') required this.tokenId, - @JsonKey(name: 'token_uri') required this.tokenUri, - required this.total, - @JsonKey(name: 'total_string') required this.totalString, - required final List? traits}) - : _floorPrices = floorPrices, - _traits = traits; - - factory _$NFTImpl.fromJson(Map json) => - _$$NFTImplFromJson(json); - - @override - @JsonKey(name: 'contract_address') - final String contractAddress; - @override - @JsonKey(name: 'erc_type') - final String? ercType; - final List? _floorPrices; - @override - @JsonKey(name: 'floor_prices') - List? get floorPrices { - final value = _floorPrices; - if (value == null) return null; - if (_floorPrices is EqualUnmodifiableListView) return _floorPrices; - // ignore: implicit_dynamic_type - return EqualUnmodifiableListView(value); - } - - @override - @JsonKey(name: 'image_uri') - final String? imageUri; - @override - final NFTMetadata? metadata; - @override - @JsonKey(name: 'mint_time') - final DateTime mintTime; - @override - @JsonKey(name: 'mint_transaction_hash') - final String mintTransactionHash; - @override - final String? name; - @override - final String? owner; - @override - @JsonKey(name: 'rarity_rank') - final num? rarityRank; - @override - @JsonKey(name: 'rarity_score') - final num? rarityScore; - @override - final String symbol; - @override - @JsonKey(name: 'token_id') - final String tokenId; - @override - @JsonKey(name: 'token_uri') - final String? tokenUri; - @override - final num? total; - @override - @JsonKey(name: 'total_string') - final String? totalString; - final List? _traits; - @override - List? get traits { - final value = _traits; - if (value == null) return null; - if (_traits is EqualUnmodifiableListView) return _traits; - // ignore: implicit_dynamic_type - return EqualUnmodifiableListView(value); - } - - @override - String toString() { - return 'NFT(contractAddress: $contractAddress, ercType: $ercType, floorPrices: $floorPrices, imageUri: $imageUri, metadata: $metadata, mintTime: $mintTime, mintTransactionHash: $mintTransactionHash, name: $name, owner: $owner, rarityRank: $rarityRank, rarityScore: $rarityScore, symbol: $symbol, tokenId: $tokenId, tokenUri: $tokenUri, total: $total, totalString: $totalString, traits: $traits)'; - } - - @override - bool operator ==(Object other) { - return identical(this, other) || - (other.runtimeType == runtimeType && - other is _$NFTImpl && - (identical(other.contractAddress, contractAddress) || - other.contractAddress == contractAddress) && - (identical(other.ercType, ercType) || other.ercType == ercType) && - const DeepCollectionEquality() - .equals(other._floorPrices, _floorPrices) && - (identical(other.imageUri, imageUri) || - other.imageUri == imageUri) && - (identical(other.metadata, metadata) || - other.metadata == metadata) && - (identical(other.mintTime, mintTime) || - other.mintTime == mintTime) && - (identical(other.mintTransactionHash, mintTransactionHash) || - other.mintTransactionHash == mintTransactionHash) && - (identical(other.name, name) || other.name == name) && - (identical(other.owner, owner) || other.owner == owner) && - (identical(other.rarityRank, rarityRank) || - other.rarityRank == rarityRank) && - (identical(other.rarityScore, rarityScore) || - other.rarityScore == rarityScore) && - (identical(other.symbol, symbol) || other.symbol == symbol) && - (identical(other.tokenId, tokenId) || other.tokenId == tokenId) && - (identical(other.tokenUri, tokenUri) || - other.tokenUri == tokenUri) && - (identical(other.total, total) || other.total == total) && - (identical(other.totalString, totalString) || - other.totalString == totalString) && - const DeepCollectionEquality().equals(other._traits, _traits)); - } - - @JsonKey(ignore: true) - @override - int get hashCode => Object.hash( - runtimeType, - contractAddress, - ercType, - const DeepCollectionEquality().hash(_floorPrices), - imageUri, - metadata, - mintTime, - mintTransactionHash, - name, - owner, - rarityRank, - rarityScore, - symbol, - tokenId, - tokenUri, - total, - totalString, - const DeepCollectionEquality().hash(_traits)); - - @JsonKey(ignore: true) - @override - @pragma('vm:prefer-inline') - _$$NFTImplCopyWith<_$NFTImpl> get copyWith => - __$$NFTImplCopyWithImpl<_$NFTImpl>(this, _$identity); - - @override - Map toJson() { - return _$$NFTImplToJson( - this, - ); - } -} - -abstract class _NFT implements NFT { - const factory _NFT( - {@JsonKey(name: 'contract_address') required final String contractAddress, - @JsonKey(name: 'erc_type') required final String? ercType, - @JsonKey(name: 'floor_prices') - required final List? floorPrices, - @JsonKey(name: 'image_uri') required final String? imageUri, - required final NFTMetadata? metadata, - @JsonKey(name: 'mint_time') required final DateTime mintTime, - @JsonKey(name: 'mint_transaction_hash') - required final String mintTransactionHash, - required final String? name, - required final String? owner, - @JsonKey(name: 'rarity_rank') required final num? rarityRank, - @JsonKey(name: 'rarity_score') required final num? rarityScore, - required final String symbol, - @JsonKey(name: 'token_id') required final String tokenId, - @JsonKey(name: 'token_uri') required final String? tokenUri, - required final num? total, - @JsonKey(name: 'total_string') required final String? totalString, - required final List? traits}) = _$NFTImpl; - - factory _NFT.fromJson(Map json) = _$NFTImpl.fromJson; - - @override - @JsonKey(name: 'contract_address') - String get contractAddress; - @override - @JsonKey(name: 'erc_type') - String? get ercType; - @override - @JsonKey(name: 'floor_prices') - List? get floorPrices; - @override - @JsonKey(name: 'image_uri') - String? get imageUri; - @override - NFTMetadata? get metadata; - @override - @JsonKey(name: 'mint_time') - DateTime get mintTime; - @override - @JsonKey(name: 'mint_transaction_hash') - String get mintTransactionHash; - @override - String? get name; - @override - String? get owner; - @override - @JsonKey(name: 'rarity_rank') - num? get rarityRank; - @override - @JsonKey(name: 'rarity_score') - num? get rarityScore; - @override - String get symbol; - @override - @JsonKey(name: 'token_id') - String get tokenId; - @override - @JsonKey(name: 'token_uri') - String? get tokenUri; - @override - num? get total; - @override - @JsonKey(name: 'total_string') - String? get totalString; - @override - List? get traits; - @override - @JsonKey(ignore: true) - _$$NFTImplCopyWith<_$NFTImpl> get copyWith => - throw _privateConstructorUsedError; -} diff --git a/lib/src/utils/models/nft.g.dart b/lib/src/utils/models/nft.g.dart deleted file mode 100644 index 47d0a64..0000000 --- a/lib/src/utils/models/nft.g.dart +++ /dev/null @@ -1,53 +0,0 @@ -// GENERATED CODE - DO NOT MODIFY BY HAND - -part of 'nft.dart'; - -// ************************************************************************** -// JsonSerializableGenerator -// ************************************************************************** - -_$NFTImpl _$$NFTImplFromJson(Map json) => _$NFTImpl( - contractAddress: json['contract_address'] as String, - ercType: json['erc_type'] as String?, - floorPrices: (json['floor_prices'] as List?) - ?.map((e) => NFTFloorPrice.fromJson(e as Map)) - .toList(), - imageUri: json['image_uri'] as String?, - metadata: json['metadata'] == null - ? null - : NFTMetadata.fromJson(json['metadata'] as Map), - mintTime: DateTime.parse(json['mint_time'] as String), - mintTransactionHash: json['mint_transaction_hash'] as String, - name: json['name'] as String?, - owner: json['owner'] as String?, - rarityRank: json['rarity_rank'] as num?, - rarityScore: json['rarity_score'] as num?, - symbol: json['symbol'] as String, - tokenId: json['token_id'] as String, - tokenUri: json['token_uri'] as String?, - total: json['total'] as num?, - totalString: json['total_string'] as String?, - traits: (json['traits'] as List?) - ?.map((e) => NFTAttributes.fromJson(e as Map)) - .toList(), - ); - -Map _$$NFTImplToJson(_$NFTImpl instance) => { - 'contract_address': instance.contractAddress, - 'erc_type': instance.ercType, - 'floor_prices': instance.floorPrices, - 'image_uri': instance.imageUri, - 'metadata': instance.metadata, - 'mint_time': instance.mintTime.toIso8601String(), - 'mint_transaction_hash': instance.mintTransactionHash, - 'name': instance.name, - 'owner': instance.owner, - 'rarity_rank': instance.rarityRank, - 'rarity_score': instance.rarityScore, - 'symbol': instance.symbol, - 'token_id': instance.tokenId, - 'token_uri': instance.tokenUri, - 'total': instance.total, - 'total_string': instance.totalString, - 'traits': instance.traits, - }; diff --git a/lib/src/utils/models/price.dart b/lib/src/utils/models/price.dart deleted file mode 100644 index 957738b..0000000 --- a/lib/src/utils/models/price.dart +++ /dev/null @@ -1,17 +0,0 @@ -import 'package:freezed_annotation/freezed_annotation.dart'; - -part 'price.freezed.dart'; -part 'price.g.dart'; - -@freezed -class TokenPrice with _$TokenPrice { - const factory TokenPrice({ - required num? price, - required String? symbol, - required num? decimals, - @JsonKey(name: 'updated_at') required DateTime? updatedAt, - }) = _TokenPrice; - - factory TokenPrice.fromJson(Map json) => - _$TokenPriceFromJson(json); -} diff --git a/lib/src/utils/models/price.freezed.dart b/lib/src/utils/models/price.freezed.dart deleted file mode 100644 index a0a10d8..0000000 --- a/lib/src/utils/models/price.freezed.dart +++ /dev/null @@ -1,222 +0,0 @@ -// coverage:ignore-file -// GENERATED CODE - DO NOT MODIFY BY HAND -// ignore_for_file: type=lint -// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target, unnecessary_question_mark - -part of 'price.dart'; - -// ************************************************************************** -// FreezedGenerator -// ************************************************************************** - -T _$identity(T value) => value; - -final _privateConstructorUsedError = UnsupportedError( - 'It seems like you constructed your class using `MyClass._()`. This constructor is only meant to be used by freezed and you are not supposed to need it nor use it.\nPlease check the documentation here for more information: https://github.com/rrousselGit/freezed#custom-getters-and-methods'); - -TokenPrice _$TokenPriceFromJson(Map json) { - return _TokenPrice.fromJson(json); -} - -/// @nodoc -mixin _$TokenPrice { - num? get price => throw _privateConstructorUsedError; - String? get symbol => throw _privateConstructorUsedError; - num? get decimals => throw _privateConstructorUsedError; - @JsonKey(name: 'updated_at') - DateTime? get updatedAt => throw _privateConstructorUsedError; - - Map toJson() => throw _privateConstructorUsedError; - @JsonKey(ignore: true) - $TokenPriceCopyWith get copyWith => - throw _privateConstructorUsedError; -} - -/// @nodoc -abstract class $TokenPriceCopyWith<$Res> { - factory $TokenPriceCopyWith( - TokenPrice value, $Res Function(TokenPrice) then) = - _$TokenPriceCopyWithImpl<$Res, TokenPrice>; - @useResult - $Res call( - {num? price, - String? symbol, - num? decimals, - @JsonKey(name: 'updated_at') DateTime? updatedAt}); -} - -/// @nodoc -class _$TokenPriceCopyWithImpl<$Res, $Val extends TokenPrice> - implements $TokenPriceCopyWith<$Res> { - _$TokenPriceCopyWithImpl(this._value, this._then); - - // ignore: unused_field - final $Val _value; - // ignore: unused_field - final $Res Function($Val) _then; - - @pragma('vm:prefer-inline') - @override - $Res call({ - Object? price = freezed, - Object? symbol = freezed, - Object? decimals = freezed, - Object? updatedAt = freezed, - }) { - return _then(_value.copyWith( - price: freezed == price - ? _value.price - : price // ignore: cast_nullable_to_non_nullable - as num?, - symbol: freezed == symbol - ? _value.symbol - : symbol // ignore: cast_nullable_to_non_nullable - as String?, - decimals: freezed == decimals - ? _value.decimals - : decimals // ignore: cast_nullable_to_non_nullable - as num?, - updatedAt: freezed == updatedAt - ? _value.updatedAt - : updatedAt // ignore: cast_nullable_to_non_nullable - as DateTime?, - ) as $Val); - } -} - -/// @nodoc -abstract class _$$TokenPriceImplCopyWith<$Res> - implements $TokenPriceCopyWith<$Res> { - factory _$$TokenPriceImplCopyWith( - _$TokenPriceImpl value, $Res Function(_$TokenPriceImpl) then) = - __$$TokenPriceImplCopyWithImpl<$Res>; - @override - @useResult - $Res call( - {num? price, - String? symbol, - num? decimals, - @JsonKey(name: 'updated_at') DateTime? updatedAt}); -} - -/// @nodoc -class __$$TokenPriceImplCopyWithImpl<$Res> - extends _$TokenPriceCopyWithImpl<$Res, _$TokenPriceImpl> - implements _$$TokenPriceImplCopyWith<$Res> { - __$$TokenPriceImplCopyWithImpl( - _$TokenPriceImpl _value, $Res Function(_$TokenPriceImpl) _then) - : super(_value, _then); - - @pragma('vm:prefer-inline') - @override - $Res call({ - Object? price = freezed, - Object? symbol = freezed, - Object? decimals = freezed, - Object? updatedAt = freezed, - }) { - return _then(_$TokenPriceImpl( - price: freezed == price - ? _value.price - : price // ignore: cast_nullable_to_non_nullable - as num?, - symbol: freezed == symbol - ? _value.symbol - : symbol // ignore: cast_nullable_to_non_nullable - as String?, - decimals: freezed == decimals - ? _value.decimals - : decimals // ignore: cast_nullable_to_non_nullable - as num?, - updatedAt: freezed == updatedAt - ? _value.updatedAt - : updatedAt // ignore: cast_nullable_to_non_nullable - as DateTime?, - )); - } -} - -/// @nodoc -@JsonSerializable() -class _$TokenPriceImpl implements _TokenPrice { - const _$TokenPriceImpl( - {required this.price, - required this.symbol, - required this.decimals, - @JsonKey(name: 'updated_at') required this.updatedAt}); - - factory _$TokenPriceImpl.fromJson(Map json) => - _$$TokenPriceImplFromJson(json); - - @override - final num? price; - @override - final String? symbol; - @override - final num? decimals; - @override - @JsonKey(name: 'updated_at') - final DateTime? updatedAt; - - @override - String toString() { - return 'TokenPrice(price: $price, symbol: $symbol, decimals: $decimals, updatedAt: $updatedAt)'; - } - - @override - bool operator ==(Object other) { - return identical(this, other) || - (other.runtimeType == runtimeType && - other is _$TokenPriceImpl && - (identical(other.price, price) || other.price == price) && - (identical(other.symbol, symbol) || other.symbol == symbol) && - (identical(other.decimals, decimals) || - other.decimals == decimals) && - (identical(other.updatedAt, updatedAt) || - other.updatedAt == updatedAt)); - } - - @JsonKey(ignore: true) - @override - int get hashCode => - Object.hash(runtimeType, price, symbol, decimals, updatedAt); - - @JsonKey(ignore: true) - @override - @pragma('vm:prefer-inline') - _$$TokenPriceImplCopyWith<_$TokenPriceImpl> get copyWith => - __$$TokenPriceImplCopyWithImpl<_$TokenPriceImpl>(this, _$identity); - - @override - Map toJson() { - return _$$TokenPriceImplToJson( - this, - ); - } -} - -abstract class _TokenPrice implements TokenPrice { - const factory _TokenPrice( - {required final num? price, - required final String? symbol, - required final num? decimals, - @JsonKey(name: 'updated_at') required final DateTime? updatedAt}) = - _$TokenPriceImpl; - - factory _TokenPrice.fromJson(Map json) = - _$TokenPriceImpl.fromJson; - - @override - num? get price; - @override - String? get symbol; - @override - num? get decimals; - @override - @JsonKey(name: 'updated_at') - DateTime? get updatedAt; - @override - @JsonKey(ignore: true) - _$$TokenPriceImplCopyWith<_$TokenPriceImpl> get copyWith => - throw _privateConstructorUsedError; -} diff --git a/lib/src/utils/models/price.g.dart b/lib/src/utils/models/price.g.dart deleted file mode 100644 index f60bc83..0000000 --- a/lib/src/utils/models/price.g.dart +++ /dev/null @@ -1,25 +0,0 @@ -// GENERATED CODE - DO NOT MODIFY BY HAND - -part of 'price.dart'; - -// ************************************************************************** -// JsonSerializableGenerator -// ************************************************************************** - -_$TokenPriceImpl _$$TokenPriceImplFromJson(Map json) => - _$TokenPriceImpl( - price: json['price'] as num?, - symbol: json['symbol'] as String?, - decimals: json['decimals'] as num?, - updatedAt: json['updated_at'] == null - ? null - : DateTime.parse(json['updated_at'] as String), - ); - -Map _$$TokenPriceImplToJson(_$TokenPriceImpl instance) => - { - 'price': instance.price, - 'symbol': instance.symbol, - 'decimals': instance.decimals, - 'updated_at': instance.updatedAt?.toIso8601String(), - }; diff --git a/lib/src/utils/models/token.dart b/lib/src/utils/models/token.dart deleted file mode 100644 index caf72d0..0000000 --- a/lib/src/utils/models/token.dart +++ /dev/null @@ -1,98 +0,0 @@ -import 'package:freezed_annotation/freezed_annotation.dart'; -import 'package:variance_dart/variance.dart' show Uint256; - -part 'token.freezed.dart'; -part 'token.g.dart'; - -@freezed -class Token with _$Token { - const factory Token( - {@HexConverter() required Uint256 balance, - @JsonKey(name: 'contract_address') required String contractAddress, - @JsonKey(name: 'current_usd_price') required num? currentUsdPrice, - required num decimals, - required List? logos, - required String name, - required String symbol, - @BigIntConverter() - @JsonKey(name: 'total_supply') - required Uint256? totalSupply, - required List? urls}) = _Token; - - factory Token.fromJson(Map json) => _$TokenFromJson(json); -} - -class HexConverter implements JsonConverter { - const HexConverter(); - - @override - Uint256 fromJson(String json) { - return Uint256.fromHex(json); - } - - @override - String toJson(Uint256 balance) { - return balance.toHex(); - } -} - -class BigIntConverter implements JsonConverter { - const BigIntConverter(); - - @override - Uint256 fromJson(dynamic json) { - if (json is String) { - return Uint256(BigInt.parse(json)); - } - return Uint256(BigInt.from(json)); - } - - @override - BigInt toJson(Uint256 balance) { - return balance.value; - } -} - -class TokenUrl { - TokenUrl({ - required this.name, - required this.url, - }); - - factory TokenUrl.fromJson(Map json) => TokenUrl( - name: json['name'], - url: json['url'], - ); - - final String name; - final String url; - - Map toJson() => { - 'name': name, - 'url': url, - }; -} - -class TokenLogo { - TokenLogo({ - required this.height, - required this.uri, - required this.width, - }); - - factory TokenLogo.fromJson(Map json) => TokenLogo( - height: json['height'], - uri: json['uri'], - width: json['width'], - ); - - final num height; - final String uri; - final num width; - - Map toJson() => { - 'height': height, - 'uri': uri, - 'width': width, - }; -} diff --git a/lib/src/utils/models/token.freezed.dart b/lib/src/utils/models/token.freezed.dart deleted file mode 100644 index f3b0f4e..0000000 --- a/lib/src/utils/models/token.freezed.dart +++ /dev/null @@ -1,361 +0,0 @@ -// coverage:ignore-file -// GENERATED CODE - DO NOT MODIFY BY HAND -// ignore_for_file: type=lint -// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target, unnecessary_question_mark - -part of 'token.dart'; - -// ************************************************************************** -// FreezedGenerator -// ************************************************************************** - -T _$identity(T value) => value; - -final _privateConstructorUsedError = UnsupportedError( - 'It seems like you constructed your class using `MyClass._()`. This constructor is only meant to be used by freezed and you are not supposed to need it nor use it.\nPlease check the documentation here for more information: https://github.com/rrousselGit/freezed#custom-getters-and-methods'); - -Token _$TokenFromJson(Map json) { - return _Token.fromJson(json); -} - -/// @nodoc -mixin _$Token { - @HexConverter() - Uint256 get balance => throw _privateConstructorUsedError; - @JsonKey(name: 'contract_address') - String get contractAddress => throw _privateConstructorUsedError; - @JsonKey(name: 'current_usd_price') - num? get currentUsdPrice => throw _privateConstructorUsedError; - num get decimals => throw _privateConstructorUsedError; - List? get logos => throw _privateConstructorUsedError; - String get name => throw _privateConstructorUsedError; - String get symbol => throw _privateConstructorUsedError; - @BigIntConverter() - @JsonKey(name: 'total_supply') - Uint256? get totalSupply => throw _privateConstructorUsedError; - List? get urls => throw _privateConstructorUsedError; - - Map toJson() => throw _privateConstructorUsedError; - @JsonKey(ignore: true) - $TokenCopyWith get copyWith => throw _privateConstructorUsedError; -} - -/// @nodoc -abstract class $TokenCopyWith<$Res> { - factory $TokenCopyWith(Token value, $Res Function(Token) then) = - _$TokenCopyWithImpl<$Res, Token>; - @useResult - $Res call( - {@HexConverter() Uint256 balance, - @JsonKey(name: 'contract_address') String contractAddress, - @JsonKey(name: 'current_usd_price') num? currentUsdPrice, - num decimals, - List? logos, - String name, - String symbol, - @BigIntConverter() @JsonKey(name: 'total_supply') Uint256? totalSupply, - List? urls}); -} - -/// @nodoc -class _$TokenCopyWithImpl<$Res, $Val extends Token> - implements $TokenCopyWith<$Res> { - _$TokenCopyWithImpl(this._value, this._then); - - // ignore: unused_field - final $Val _value; - // ignore: unused_field - final $Res Function($Val) _then; - - @pragma('vm:prefer-inline') - @override - $Res call({ - Object? balance = null, - Object? contractAddress = null, - Object? currentUsdPrice = freezed, - Object? decimals = null, - Object? logos = freezed, - Object? name = null, - Object? symbol = null, - Object? totalSupply = freezed, - Object? urls = freezed, - }) { - return _then(_value.copyWith( - balance: null == balance - ? _value.balance - : balance // ignore: cast_nullable_to_non_nullable - as Uint256, - contractAddress: null == contractAddress - ? _value.contractAddress - : contractAddress // ignore: cast_nullable_to_non_nullable - as String, - currentUsdPrice: freezed == currentUsdPrice - ? _value.currentUsdPrice - : currentUsdPrice // ignore: cast_nullable_to_non_nullable - as num?, - decimals: null == decimals - ? _value.decimals - : decimals // ignore: cast_nullable_to_non_nullable - as num, - logos: freezed == logos - ? _value.logos - : logos // ignore: cast_nullable_to_non_nullable - as List?, - name: null == name - ? _value.name - : name // ignore: cast_nullable_to_non_nullable - as String, - symbol: null == symbol - ? _value.symbol - : symbol // ignore: cast_nullable_to_non_nullable - as String, - totalSupply: freezed == totalSupply - ? _value.totalSupply - : totalSupply // ignore: cast_nullable_to_non_nullable - as Uint256?, - urls: freezed == urls - ? _value.urls - : urls // ignore: cast_nullable_to_non_nullable - as List?, - ) as $Val); - } -} - -/// @nodoc -abstract class _$$TokenImplCopyWith<$Res> implements $TokenCopyWith<$Res> { - factory _$$TokenImplCopyWith( - _$TokenImpl value, $Res Function(_$TokenImpl) then) = - __$$TokenImplCopyWithImpl<$Res>; - @override - @useResult - $Res call( - {@HexConverter() Uint256 balance, - @JsonKey(name: 'contract_address') String contractAddress, - @JsonKey(name: 'current_usd_price') num? currentUsdPrice, - num decimals, - List? logos, - String name, - String symbol, - @BigIntConverter() @JsonKey(name: 'total_supply') Uint256? totalSupply, - List? urls}); -} - -/// @nodoc -class __$$TokenImplCopyWithImpl<$Res> - extends _$TokenCopyWithImpl<$Res, _$TokenImpl> - implements _$$TokenImplCopyWith<$Res> { - __$$TokenImplCopyWithImpl( - _$TokenImpl _value, $Res Function(_$TokenImpl) _then) - : super(_value, _then); - - @pragma('vm:prefer-inline') - @override - $Res call({ - Object? balance = null, - Object? contractAddress = null, - Object? currentUsdPrice = freezed, - Object? decimals = null, - Object? logos = freezed, - Object? name = null, - Object? symbol = null, - Object? totalSupply = freezed, - Object? urls = freezed, - }) { - return _then(_$TokenImpl( - balance: null == balance - ? _value.balance - : balance // ignore: cast_nullable_to_non_nullable - as Uint256, - contractAddress: null == contractAddress - ? _value.contractAddress - : contractAddress // ignore: cast_nullable_to_non_nullable - as String, - currentUsdPrice: freezed == currentUsdPrice - ? _value.currentUsdPrice - : currentUsdPrice // ignore: cast_nullable_to_non_nullable - as num?, - decimals: null == decimals - ? _value.decimals - : decimals // ignore: cast_nullable_to_non_nullable - as num, - logos: freezed == logos - ? _value._logos - : logos // ignore: cast_nullable_to_non_nullable - as List?, - name: null == name - ? _value.name - : name // ignore: cast_nullable_to_non_nullable - as String, - symbol: null == symbol - ? _value.symbol - : symbol // ignore: cast_nullable_to_non_nullable - as String, - totalSupply: freezed == totalSupply - ? _value.totalSupply - : totalSupply // ignore: cast_nullable_to_non_nullable - as Uint256?, - urls: freezed == urls - ? _value._urls - : urls // ignore: cast_nullable_to_non_nullable - as List?, - )); - } -} - -/// @nodoc -@JsonSerializable() -class _$TokenImpl implements _Token { - const _$TokenImpl( - {@HexConverter() required this.balance, - @JsonKey(name: 'contract_address') required this.contractAddress, - @JsonKey(name: 'current_usd_price') required this.currentUsdPrice, - required this.decimals, - required final List? logos, - required this.name, - required this.symbol, - @BigIntConverter() - @JsonKey(name: 'total_supply') - required this.totalSupply, - required final List? urls}) - : _logos = logos, - _urls = urls; - - factory _$TokenImpl.fromJson(Map json) => - _$$TokenImplFromJson(json); - - @override - @HexConverter() - final Uint256 balance; - @override - @JsonKey(name: 'contract_address') - final String contractAddress; - @override - @JsonKey(name: 'current_usd_price') - final num? currentUsdPrice; - @override - final num decimals; - final List? _logos; - @override - List? get logos { - final value = _logos; - if (value == null) return null; - if (_logos is EqualUnmodifiableListView) return _logos; - // ignore: implicit_dynamic_type - return EqualUnmodifiableListView(value); - } - - @override - final String name; - @override - final String symbol; - @override - @BigIntConverter() - @JsonKey(name: 'total_supply') - final Uint256? totalSupply; - final List? _urls; - @override - List? get urls { - final value = _urls; - if (value == null) return null; - if (_urls is EqualUnmodifiableListView) return _urls; - // ignore: implicit_dynamic_type - return EqualUnmodifiableListView(value); - } - - @override - String toString() { - return 'Token(balance: $balance, contractAddress: $contractAddress, currentUsdPrice: $currentUsdPrice, decimals: $decimals, logos: $logos, name: $name, symbol: $symbol, totalSupply: $totalSupply, urls: $urls)'; - } - - @override - bool operator ==(Object other) { - return identical(this, other) || - (other.runtimeType == runtimeType && - other is _$TokenImpl && - (identical(other.balance, balance) || other.balance == balance) && - (identical(other.contractAddress, contractAddress) || - other.contractAddress == contractAddress) && - (identical(other.currentUsdPrice, currentUsdPrice) || - other.currentUsdPrice == currentUsdPrice) && - (identical(other.decimals, decimals) || - other.decimals == decimals) && - const DeepCollectionEquality().equals(other._logos, _logos) && - (identical(other.name, name) || other.name == name) && - (identical(other.symbol, symbol) || other.symbol == symbol) && - (identical(other.totalSupply, totalSupply) || - other.totalSupply == totalSupply) && - const DeepCollectionEquality().equals(other._urls, _urls)); - } - - @JsonKey(ignore: true) - @override - int get hashCode => Object.hash( - runtimeType, - balance, - contractAddress, - currentUsdPrice, - decimals, - const DeepCollectionEquality().hash(_logos), - name, - symbol, - totalSupply, - const DeepCollectionEquality().hash(_urls)); - - @JsonKey(ignore: true) - @override - @pragma('vm:prefer-inline') - _$$TokenImplCopyWith<_$TokenImpl> get copyWith => - __$$TokenImplCopyWithImpl<_$TokenImpl>(this, _$identity); - - @override - Map toJson() { - return _$$TokenImplToJson( - this, - ); - } -} - -abstract class _Token implements Token { - const factory _Token( - {@HexConverter() required final Uint256 balance, - @JsonKey(name: 'contract_address') required final String contractAddress, - @JsonKey(name: 'current_usd_price') required final num? currentUsdPrice, - required final num decimals, - required final List? logos, - required final String name, - required final String symbol, - @BigIntConverter() - @JsonKey(name: 'total_supply') - required final Uint256? totalSupply, - required final List? urls}) = _$TokenImpl; - - factory _Token.fromJson(Map json) = _$TokenImpl.fromJson; - - @override - @HexConverter() - Uint256 get balance; - @override - @JsonKey(name: 'contract_address') - String get contractAddress; - @override - @JsonKey(name: 'current_usd_price') - num? get currentUsdPrice; - @override - num get decimals; - @override - List? get logos; - @override - String get name; - @override - String get symbol; - @override - @BigIntConverter() - @JsonKey(name: 'total_supply') - Uint256? get totalSupply; - @override - List? get urls; - @override - @JsonKey(ignore: true) - _$$TokenImplCopyWith<_$TokenImpl> get copyWith => - throw _privateConstructorUsedError; -} diff --git a/lib/src/utils/models/token.g.dart b/lib/src/utils/models/token.g.dart deleted file mode 100644 index f147d11..0000000 --- a/lib/src/utils/models/token.g.dart +++ /dev/null @@ -1,43 +0,0 @@ -// GENERATED CODE - DO NOT MODIFY BY HAND - -part of 'token.dart'; - -// ************************************************************************** -// JsonSerializableGenerator -// ************************************************************************** - -_$TokenImpl _$$TokenImplFromJson(Map json) => _$TokenImpl( - balance: const HexConverter().fromJson(json['balance'] as String), - contractAddress: json['contract_address'] as String, - currentUsdPrice: json['current_usd_price'] as num?, - decimals: json['decimals'] as num, - logos: (json['logos'] as List?) - ?.map((e) => TokenLogo.fromJson(e as Map)) - .toList(), - name: json['name'] as String, - symbol: json['symbol'] as String, - totalSupply: const BigIntConverter().fromJson(json['total_supply']), - urls: (json['urls'] as List?) - ?.map((e) => TokenUrl.fromJson(e as Map)) - .toList(), - ); - -Map _$$TokenImplToJson(_$TokenImpl instance) => - { - 'balance': const HexConverter().toJson(instance.balance), - 'contract_address': instance.contractAddress, - 'current_usd_price': instance.currentUsdPrice, - 'decimals': instance.decimals, - 'logos': instance.logos, - 'name': instance.name, - 'symbol': instance.symbol, - 'total_supply': _$JsonConverterToJson( - instance.totalSupply, const BigIntConverter().toJson), - 'urls': instance.urls, - }; - -Json? _$JsonConverterToJson( - Value? value, - Json? Function(Value value) toJson, -) => - value == null ? null : toJson(value); diff --git a/lib/src/utils/models/transaction.dart b/lib/src/utils/models/transaction.dart deleted file mode 100644 index 729bbb5..0000000 --- a/lib/src/utils/models/transaction.dart +++ /dev/null @@ -1,45 +0,0 @@ -import 'package:freezed_annotation/freezed_annotation.dart'; -import 'package:variance_dart/src/common/common.dart' show Uint256; -import 'package:variance_dart/utils.dart' show BigIntConverter; - -part 'transaction.freezed.dart'; -part 'transaction.g.dart'; - -@freezed -class Transaction with _$Transaction { - const factory Transaction({ - required num type, - required num status, - @JsonKey(name: 'block_number') required num blockNumber, - @JsonKey(name: 'block_timestamp') required DateTime blockTimestamp, - @JsonKey(name: 'transaction_hash') required String transactionHash, - @JsonKey(name: 'transaction_index') required num transactionIndex, - @JsonKey(name: 'from_address') required String fromAddress, - @JsonKey(name: 'to_address') required String toAddress, - @BigIntConverter() required Uint256 value, - required String? input, - required num nonce, - @JsonKey(name: 'contract_address') required String? contractAddress, - @BigIntConverter() required Uint256 gas, - @BigIntConverter() @JsonKey(name: 'gas_price') required Uint256 gasPrice, - @BigIntConverter() @JsonKey(name: 'gas_used') required Uint256 gasUsed, - @BigIntConverter() - @JsonKey(name: 'effective_gas_price') - required Uint256 effectiveGasPrice, - @BigIntConverter() - @JsonKey(name: 'cumulative_gas_used') - required Uint256 cumulativeGasUsed, - @BigIntConverter() - @JsonKey(name: 'max_fee_per_gas') - required Uint256? maxFeePerGas, - @BigIntConverter() - @JsonKey(name: 'max_priority_fee_per_gas') - required Uint256? maxPriorityFeePerGas, - @JsonKey(name: 'tx_fee') required num txFee, - @JsonKey(name: 'saving_fee') required num? savingFee, - @JsonKey(name: 'burnt_fee') required num? burntFee, - }) = _Transaction; - - factory Transaction.fromJson(Map json) => - _$TransactionFromJson(json); -} diff --git a/lib/src/utils/models/transaction.freezed.dart b/lib/src/utils/models/transaction.freezed.dart deleted file mode 100644 index 44702a7..0000000 --- a/lib/src/utils/models/transaction.freezed.dart +++ /dev/null @@ -1,722 +0,0 @@ -// coverage:ignore-file -// GENERATED CODE - DO NOT MODIFY BY HAND -// ignore_for_file: type=lint -// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target, unnecessary_question_mark - -part of 'transaction.dart'; - -// ************************************************************************** -// FreezedGenerator -// ************************************************************************** - -T _$identity(T value) => value; - -final _privateConstructorUsedError = UnsupportedError( - 'It seems like you constructed your class using `MyClass._()`. This constructor is only meant to be used by freezed and you are not supposed to need it nor use it.\nPlease check the documentation here for more information: https://github.com/rrousselGit/freezed#custom-getters-and-methods'); - -Transaction _$TransactionFromJson(Map json) { - return _Transaction.fromJson(json); -} - -/// @nodoc -mixin _$Transaction { - num get type => throw _privateConstructorUsedError; - num get status => throw _privateConstructorUsedError; - @JsonKey(name: 'block_number') - num get blockNumber => throw _privateConstructorUsedError; - @JsonKey(name: 'block_timestamp') - DateTime get blockTimestamp => throw _privateConstructorUsedError; - @JsonKey(name: 'transaction_hash') - String get transactionHash => throw _privateConstructorUsedError; - @JsonKey(name: 'transaction_index') - num get transactionIndex => throw _privateConstructorUsedError; - @JsonKey(name: 'from_address') - String get fromAddress => throw _privateConstructorUsedError; - @JsonKey(name: 'to_address') - String get toAddress => throw _privateConstructorUsedError; - @BigIntConverter() - Uint256 get value => throw _privateConstructorUsedError; - String? get input => throw _privateConstructorUsedError; - num get nonce => throw _privateConstructorUsedError; - @JsonKey(name: 'contract_address') - String? get contractAddress => throw _privateConstructorUsedError; - @BigIntConverter() - Uint256 get gas => throw _privateConstructorUsedError; - @BigIntConverter() - @JsonKey(name: 'gas_price') - Uint256 get gasPrice => throw _privateConstructorUsedError; - @BigIntConverter() - @JsonKey(name: 'gas_used') - Uint256 get gasUsed => throw _privateConstructorUsedError; - @BigIntConverter() - @JsonKey(name: 'effective_gas_price') - Uint256 get effectiveGasPrice => throw _privateConstructorUsedError; - @BigIntConverter() - @JsonKey(name: 'cumulative_gas_used') - Uint256 get cumulativeGasUsed => throw _privateConstructorUsedError; - @BigIntConverter() - @JsonKey(name: 'max_fee_per_gas') - Uint256? get maxFeePerGas => throw _privateConstructorUsedError; - @BigIntConverter() - @JsonKey(name: 'max_priority_fee_per_gas') - Uint256? get maxPriorityFeePerGas => throw _privateConstructorUsedError; - @JsonKey(name: 'tx_fee') - num get txFee => throw _privateConstructorUsedError; - @JsonKey(name: 'saving_fee') - num? get savingFee => throw _privateConstructorUsedError; - @JsonKey(name: 'burnt_fee') - num? get burntFee => throw _privateConstructorUsedError; - - Map toJson() => throw _privateConstructorUsedError; - @JsonKey(ignore: true) - $TransactionCopyWith get copyWith => - throw _privateConstructorUsedError; -} - -/// @nodoc -abstract class $TransactionCopyWith<$Res> { - factory $TransactionCopyWith( - Transaction value, $Res Function(Transaction) then) = - _$TransactionCopyWithImpl<$Res, Transaction>; - @useResult - $Res call( - {num type, - num status, - @JsonKey(name: 'block_number') num blockNumber, - @JsonKey(name: 'block_timestamp') DateTime blockTimestamp, - @JsonKey(name: 'transaction_hash') String transactionHash, - @JsonKey(name: 'transaction_index') num transactionIndex, - @JsonKey(name: 'from_address') String fromAddress, - @JsonKey(name: 'to_address') String toAddress, - @BigIntConverter() Uint256 value, - String? input, - num nonce, - @JsonKey(name: 'contract_address') String? contractAddress, - @BigIntConverter() Uint256 gas, - @BigIntConverter() @JsonKey(name: 'gas_price') Uint256 gasPrice, - @BigIntConverter() @JsonKey(name: 'gas_used') Uint256 gasUsed, - @BigIntConverter() - @JsonKey(name: 'effective_gas_price') - Uint256 effectiveGasPrice, - @BigIntConverter() - @JsonKey(name: 'cumulative_gas_used') - Uint256 cumulativeGasUsed, - @BigIntConverter() - @JsonKey(name: 'max_fee_per_gas') - Uint256? maxFeePerGas, - @BigIntConverter() - @JsonKey(name: 'max_priority_fee_per_gas') - Uint256? maxPriorityFeePerGas, - @JsonKey(name: 'tx_fee') num txFee, - @JsonKey(name: 'saving_fee') num? savingFee, - @JsonKey(name: 'burnt_fee') num? burntFee}); -} - -/// @nodoc -class _$TransactionCopyWithImpl<$Res, $Val extends Transaction> - implements $TransactionCopyWith<$Res> { - _$TransactionCopyWithImpl(this._value, this._then); - - // ignore: unused_field - final $Val _value; - // ignore: unused_field - final $Res Function($Val) _then; - - @pragma('vm:prefer-inline') - @override - $Res call({ - Object? type = null, - Object? status = null, - Object? blockNumber = null, - Object? blockTimestamp = null, - Object? transactionHash = null, - Object? transactionIndex = null, - Object? fromAddress = null, - Object? toAddress = null, - Object? value = null, - Object? input = freezed, - Object? nonce = null, - Object? contractAddress = freezed, - Object? gas = null, - Object? gasPrice = null, - Object? gasUsed = null, - Object? effectiveGasPrice = null, - Object? cumulativeGasUsed = null, - Object? maxFeePerGas = freezed, - Object? maxPriorityFeePerGas = freezed, - Object? txFee = null, - Object? savingFee = freezed, - Object? burntFee = freezed, - }) { - return _then(_value.copyWith( - type: null == type - ? _value.type - : type // ignore: cast_nullable_to_non_nullable - as num, - status: null == status - ? _value.status - : status // ignore: cast_nullable_to_non_nullable - as num, - blockNumber: null == blockNumber - ? _value.blockNumber - : blockNumber // ignore: cast_nullable_to_non_nullable - as num, - blockTimestamp: null == blockTimestamp - ? _value.blockTimestamp - : blockTimestamp // ignore: cast_nullable_to_non_nullable - as DateTime, - transactionHash: null == transactionHash - ? _value.transactionHash - : transactionHash // ignore: cast_nullable_to_non_nullable - as String, - transactionIndex: null == transactionIndex - ? _value.transactionIndex - : transactionIndex // ignore: cast_nullable_to_non_nullable - as num, - fromAddress: null == fromAddress - ? _value.fromAddress - : fromAddress // ignore: cast_nullable_to_non_nullable - as String, - toAddress: null == toAddress - ? _value.toAddress - : toAddress // ignore: cast_nullable_to_non_nullable - as String, - value: null == value - ? _value.value - : value // ignore: cast_nullable_to_non_nullable - as Uint256, - input: freezed == input - ? _value.input - : input // ignore: cast_nullable_to_non_nullable - as String?, - nonce: null == nonce - ? _value.nonce - : nonce // ignore: cast_nullable_to_non_nullable - as num, - contractAddress: freezed == contractAddress - ? _value.contractAddress - : contractAddress // ignore: cast_nullable_to_non_nullable - as String?, - gas: null == gas - ? _value.gas - : gas // ignore: cast_nullable_to_non_nullable - as Uint256, - gasPrice: null == gasPrice - ? _value.gasPrice - : gasPrice // ignore: cast_nullable_to_non_nullable - as Uint256, - gasUsed: null == gasUsed - ? _value.gasUsed - : gasUsed // ignore: cast_nullable_to_non_nullable - as Uint256, - effectiveGasPrice: null == effectiveGasPrice - ? _value.effectiveGasPrice - : effectiveGasPrice // ignore: cast_nullable_to_non_nullable - as Uint256, - cumulativeGasUsed: null == cumulativeGasUsed - ? _value.cumulativeGasUsed - : cumulativeGasUsed // ignore: cast_nullable_to_non_nullable - as Uint256, - maxFeePerGas: freezed == maxFeePerGas - ? _value.maxFeePerGas - : maxFeePerGas // ignore: cast_nullable_to_non_nullable - as Uint256?, - maxPriorityFeePerGas: freezed == maxPriorityFeePerGas - ? _value.maxPriorityFeePerGas - : maxPriorityFeePerGas // ignore: cast_nullable_to_non_nullable - as Uint256?, - txFee: null == txFee - ? _value.txFee - : txFee // ignore: cast_nullable_to_non_nullable - as num, - savingFee: freezed == savingFee - ? _value.savingFee - : savingFee // ignore: cast_nullable_to_non_nullable - as num?, - burntFee: freezed == burntFee - ? _value.burntFee - : burntFee // ignore: cast_nullable_to_non_nullable - as num?, - ) as $Val); - } -} - -/// @nodoc -abstract class _$$TransactionImplCopyWith<$Res> - implements $TransactionCopyWith<$Res> { - factory _$$TransactionImplCopyWith( - _$TransactionImpl value, $Res Function(_$TransactionImpl) then) = - __$$TransactionImplCopyWithImpl<$Res>; - @override - @useResult - $Res call( - {num type, - num status, - @JsonKey(name: 'block_number') num blockNumber, - @JsonKey(name: 'block_timestamp') DateTime blockTimestamp, - @JsonKey(name: 'transaction_hash') String transactionHash, - @JsonKey(name: 'transaction_index') num transactionIndex, - @JsonKey(name: 'from_address') String fromAddress, - @JsonKey(name: 'to_address') String toAddress, - @BigIntConverter() Uint256 value, - String? input, - num nonce, - @JsonKey(name: 'contract_address') String? contractAddress, - @BigIntConverter() Uint256 gas, - @BigIntConverter() @JsonKey(name: 'gas_price') Uint256 gasPrice, - @BigIntConverter() @JsonKey(name: 'gas_used') Uint256 gasUsed, - @BigIntConverter() - @JsonKey(name: 'effective_gas_price') - Uint256 effectiveGasPrice, - @BigIntConverter() - @JsonKey(name: 'cumulative_gas_used') - Uint256 cumulativeGasUsed, - @BigIntConverter() - @JsonKey(name: 'max_fee_per_gas') - Uint256? maxFeePerGas, - @BigIntConverter() - @JsonKey(name: 'max_priority_fee_per_gas') - Uint256? maxPriorityFeePerGas, - @JsonKey(name: 'tx_fee') num txFee, - @JsonKey(name: 'saving_fee') num? savingFee, - @JsonKey(name: 'burnt_fee') num? burntFee}); -} - -/// @nodoc -class __$$TransactionImplCopyWithImpl<$Res> - extends _$TransactionCopyWithImpl<$Res, _$TransactionImpl> - implements _$$TransactionImplCopyWith<$Res> { - __$$TransactionImplCopyWithImpl( - _$TransactionImpl _value, $Res Function(_$TransactionImpl) _then) - : super(_value, _then); - - @pragma('vm:prefer-inline') - @override - $Res call({ - Object? type = null, - Object? status = null, - Object? blockNumber = null, - Object? blockTimestamp = null, - Object? transactionHash = null, - Object? transactionIndex = null, - Object? fromAddress = null, - Object? toAddress = null, - Object? value = null, - Object? input = freezed, - Object? nonce = null, - Object? contractAddress = freezed, - Object? gas = null, - Object? gasPrice = null, - Object? gasUsed = null, - Object? effectiveGasPrice = null, - Object? cumulativeGasUsed = null, - Object? maxFeePerGas = freezed, - Object? maxPriorityFeePerGas = freezed, - Object? txFee = null, - Object? savingFee = freezed, - Object? burntFee = freezed, - }) { - return _then(_$TransactionImpl( - type: null == type - ? _value.type - : type // ignore: cast_nullable_to_non_nullable - as num, - status: null == status - ? _value.status - : status // ignore: cast_nullable_to_non_nullable - as num, - blockNumber: null == blockNumber - ? _value.blockNumber - : blockNumber // ignore: cast_nullable_to_non_nullable - as num, - blockTimestamp: null == blockTimestamp - ? _value.blockTimestamp - : blockTimestamp // ignore: cast_nullable_to_non_nullable - as DateTime, - transactionHash: null == transactionHash - ? _value.transactionHash - : transactionHash // ignore: cast_nullable_to_non_nullable - as String, - transactionIndex: null == transactionIndex - ? _value.transactionIndex - : transactionIndex // ignore: cast_nullable_to_non_nullable - as num, - fromAddress: null == fromAddress - ? _value.fromAddress - : fromAddress // ignore: cast_nullable_to_non_nullable - as String, - toAddress: null == toAddress - ? _value.toAddress - : toAddress // ignore: cast_nullable_to_non_nullable - as String, - value: null == value - ? _value.value - : value // ignore: cast_nullable_to_non_nullable - as Uint256, - input: freezed == input - ? _value.input - : input // ignore: cast_nullable_to_non_nullable - as String?, - nonce: null == nonce - ? _value.nonce - : nonce // ignore: cast_nullable_to_non_nullable - as num, - contractAddress: freezed == contractAddress - ? _value.contractAddress - : contractAddress // ignore: cast_nullable_to_non_nullable - as String?, - gas: null == gas - ? _value.gas - : gas // ignore: cast_nullable_to_non_nullable - as Uint256, - gasPrice: null == gasPrice - ? _value.gasPrice - : gasPrice // ignore: cast_nullable_to_non_nullable - as Uint256, - gasUsed: null == gasUsed - ? _value.gasUsed - : gasUsed // ignore: cast_nullable_to_non_nullable - as Uint256, - effectiveGasPrice: null == effectiveGasPrice - ? _value.effectiveGasPrice - : effectiveGasPrice // ignore: cast_nullable_to_non_nullable - as Uint256, - cumulativeGasUsed: null == cumulativeGasUsed - ? _value.cumulativeGasUsed - : cumulativeGasUsed // ignore: cast_nullable_to_non_nullable - as Uint256, - maxFeePerGas: freezed == maxFeePerGas - ? _value.maxFeePerGas - : maxFeePerGas // ignore: cast_nullable_to_non_nullable - as Uint256?, - maxPriorityFeePerGas: freezed == maxPriorityFeePerGas - ? _value.maxPriorityFeePerGas - : maxPriorityFeePerGas // ignore: cast_nullable_to_non_nullable - as Uint256?, - txFee: null == txFee - ? _value.txFee - : txFee // ignore: cast_nullable_to_non_nullable - as num, - savingFee: freezed == savingFee - ? _value.savingFee - : savingFee // ignore: cast_nullable_to_non_nullable - as num?, - burntFee: freezed == burntFee - ? _value.burntFee - : burntFee // ignore: cast_nullable_to_non_nullable - as num?, - )); - } -} - -/// @nodoc -@JsonSerializable() -class _$TransactionImpl implements _Transaction { - const _$TransactionImpl( - {required this.type, - required this.status, - @JsonKey(name: 'block_number') required this.blockNumber, - @JsonKey(name: 'block_timestamp') required this.blockTimestamp, - @JsonKey(name: 'transaction_hash') required this.transactionHash, - @JsonKey(name: 'transaction_index') required this.transactionIndex, - @JsonKey(name: 'from_address') required this.fromAddress, - @JsonKey(name: 'to_address') required this.toAddress, - @BigIntConverter() required this.value, - required this.input, - required this.nonce, - @JsonKey(name: 'contract_address') required this.contractAddress, - @BigIntConverter() required this.gas, - @BigIntConverter() @JsonKey(name: 'gas_price') required this.gasPrice, - @BigIntConverter() @JsonKey(name: 'gas_used') required this.gasUsed, - @BigIntConverter() - @JsonKey(name: 'effective_gas_price') - required this.effectiveGasPrice, - @BigIntConverter() - @JsonKey(name: 'cumulative_gas_used') - required this.cumulativeGasUsed, - @BigIntConverter() - @JsonKey(name: 'max_fee_per_gas') - required this.maxFeePerGas, - @BigIntConverter() - @JsonKey(name: 'max_priority_fee_per_gas') - required this.maxPriorityFeePerGas, - @JsonKey(name: 'tx_fee') required this.txFee, - @JsonKey(name: 'saving_fee') required this.savingFee, - @JsonKey(name: 'burnt_fee') required this.burntFee}); - - factory _$TransactionImpl.fromJson(Map json) => - _$$TransactionImplFromJson(json); - - @override - final num type; - @override - final num status; - @override - @JsonKey(name: 'block_number') - final num blockNumber; - @override - @JsonKey(name: 'block_timestamp') - final DateTime blockTimestamp; - @override - @JsonKey(name: 'transaction_hash') - final String transactionHash; - @override - @JsonKey(name: 'transaction_index') - final num transactionIndex; - @override - @JsonKey(name: 'from_address') - final String fromAddress; - @override - @JsonKey(name: 'to_address') - final String toAddress; - @override - @BigIntConverter() - final Uint256 value; - @override - final String? input; - @override - final num nonce; - @override - @JsonKey(name: 'contract_address') - final String? contractAddress; - @override - @BigIntConverter() - final Uint256 gas; - @override - @BigIntConverter() - @JsonKey(name: 'gas_price') - final Uint256 gasPrice; - @override - @BigIntConverter() - @JsonKey(name: 'gas_used') - final Uint256 gasUsed; - @override - @BigIntConverter() - @JsonKey(name: 'effective_gas_price') - final Uint256 effectiveGasPrice; - @override - @BigIntConverter() - @JsonKey(name: 'cumulative_gas_used') - final Uint256 cumulativeGasUsed; - @override - @BigIntConverter() - @JsonKey(name: 'max_fee_per_gas') - final Uint256? maxFeePerGas; - @override - @BigIntConverter() - @JsonKey(name: 'max_priority_fee_per_gas') - final Uint256? maxPriorityFeePerGas; - @override - @JsonKey(name: 'tx_fee') - final num txFee; - @override - @JsonKey(name: 'saving_fee') - final num? savingFee; - @override - @JsonKey(name: 'burnt_fee') - final num? burntFee; - - @override - String toString() { - return 'Transaction(type: $type, status: $status, blockNumber: $blockNumber, blockTimestamp: $blockTimestamp, transactionHash: $transactionHash, transactionIndex: $transactionIndex, fromAddress: $fromAddress, toAddress: $toAddress, value: $value, input: $input, nonce: $nonce, contractAddress: $contractAddress, gas: $gas, gasPrice: $gasPrice, gasUsed: $gasUsed, effectiveGasPrice: $effectiveGasPrice, cumulativeGasUsed: $cumulativeGasUsed, maxFeePerGas: $maxFeePerGas, maxPriorityFeePerGas: $maxPriorityFeePerGas, txFee: $txFee, savingFee: $savingFee, burntFee: $burntFee)'; - } - - @override - bool operator ==(Object other) { - return identical(this, other) || - (other.runtimeType == runtimeType && - other is _$TransactionImpl && - (identical(other.type, type) || other.type == type) && - (identical(other.status, status) || other.status == status) && - (identical(other.blockNumber, blockNumber) || - other.blockNumber == blockNumber) && - (identical(other.blockTimestamp, blockTimestamp) || - other.blockTimestamp == blockTimestamp) && - (identical(other.transactionHash, transactionHash) || - other.transactionHash == transactionHash) && - (identical(other.transactionIndex, transactionIndex) || - other.transactionIndex == transactionIndex) && - (identical(other.fromAddress, fromAddress) || - other.fromAddress == fromAddress) && - (identical(other.toAddress, toAddress) || - other.toAddress == toAddress) && - (identical(other.value, value) || other.value == value) && - (identical(other.input, input) || other.input == input) && - (identical(other.nonce, nonce) || other.nonce == nonce) && - (identical(other.contractAddress, contractAddress) || - other.contractAddress == contractAddress) && - (identical(other.gas, gas) || other.gas == gas) && - (identical(other.gasPrice, gasPrice) || - other.gasPrice == gasPrice) && - (identical(other.gasUsed, gasUsed) || other.gasUsed == gasUsed) && - (identical(other.effectiveGasPrice, effectiveGasPrice) || - other.effectiveGasPrice == effectiveGasPrice) && - (identical(other.cumulativeGasUsed, cumulativeGasUsed) || - other.cumulativeGasUsed == cumulativeGasUsed) && - (identical(other.maxFeePerGas, maxFeePerGas) || - other.maxFeePerGas == maxFeePerGas) && - (identical(other.maxPriorityFeePerGas, maxPriorityFeePerGas) || - other.maxPriorityFeePerGas == maxPriorityFeePerGas) && - (identical(other.txFee, txFee) || other.txFee == txFee) && - (identical(other.savingFee, savingFee) || - other.savingFee == savingFee) && - (identical(other.burntFee, burntFee) || - other.burntFee == burntFee)); - } - - @JsonKey(ignore: true) - @override - int get hashCode => Object.hashAll([ - runtimeType, - type, - status, - blockNumber, - blockTimestamp, - transactionHash, - transactionIndex, - fromAddress, - toAddress, - value, - input, - nonce, - contractAddress, - gas, - gasPrice, - gasUsed, - effectiveGasPrice, - cumulativeGasUsed, - maxFeePerGas, - maxPriorityFeePerGas, - txFee, - savingFee, - burntFee - ]); - - @JsonKey(ignore: true) - @override - @pragma('vm:prefer-inline') - _$$TransactionImplCopyWith<_$TransactionImpl> get copyWith => - __$$TransactionImplCopyWithImpl<_$TransactionImpl>(this, _$identity); - - @override - Map toJson() { - return _$$TransactionImplToJson( - this, - ); - } -} - -abstract class _Transaction implements Transaction { - const factory _Transaction( - {required final num type, - required final num status, - @JsonKey(name: 'block_number') required final num blockNumber, - @JsonKey(name: 'block_timestamp') required final DateTime blockTimestamp, - @JsonKey(name: 'transaction_hash') required final String transactionHash, - @JsonKey(name: 'transaction_index') required final num transactionIndex, - @JsonKey(name: 'from_address') required final String fromAddress, - @JsonKey(name: 'to_address') required final String toAddress, - @BigIntConverter() required final Uint256 value, - required final String? input, - required final num nonce, - @JsonKey(name: 'contract_address') required final String? contractAddress, - @BigIntConverter() required final Uint256 gas, - @BigIntConverter() - @JsonKey(name: 'gas_price') - required final Uint256 gasPrice, - @BigIntConverter() - @JsonKey(name: 'gas_used') - required final Uint256 gasUsed, - @BigIntConverter() - @JsonKey(name: 'effective_gas_price') - required final Uint256 effectiveGasPrice, - @BigIntConverter() - @JsonKey(name: 'cumulative_gas_used') - required final Uint256 cumulativeGasUsed, - @BigIntConverter() - @JsonKey(name: 'max_fee_per_gas') - required final Uint256? maxFeePerGas, - @BigIntConverter() - @JsonKey(name: 'max_priority_fee_per_gas') - required final Uint256? maxPriorityFeePerGas, - @JsonKey(name: 'tx_fee') required final num txFee, - @JsonKey(name: 'saving_fee') required final num? savingFee, - @JsonKey(name: 'burnt_fee') - required final num? burntFee}) = _$TransactionImpl; - - factory _Transaction.fromJson(Map json) = - _$TransactionImpl.fromJson; - - @override - num get type; - @override - num get status; - @override - @JsonKey(name: 'block_number') - num get blockNumber; - @override - @JsonKey(name: 'block_timestamp') - DateTime get blockTimestamp; - @override - @JsonKey(name: 'transaction_hash') - String get transactionHash; - @override - @JsonKey(name: 'transaction_index') - num get transactionIndex; - @override - @JsonKey(name: 'from_address') - String get fromAddress; - @override - @JsonKey(name: 'to_address') - String get toAddress; - @override - @BigIntConverter() - Uint256 get value; - @override - String? get input; - @override - num get nonce; - @override - @JsonKey(name: 'contract_address') - String? get contractAddress; - @override - @BigIntConverter() - Uint256 get gas; - @override - @BigIntConverter() - @JsonKey(name: 'gas_price') - Uint256 get gasPrice; - @override - @BigIntConverter() - @JsonKey(name: 'gas_used') - Uint256 get gasUsed; - @override - @BigIntConverter() - @JsonKey(name: 'effective_gas_price') - Uint256 get effectiveGasPrice; - @override - @BigIntConverter() - @JsonKey(name: 'cumulative_gas_used') - Uint256 get cumulativeGasUsed; - @override - @BigIntConverter() - @JsonKey(name: 'max_fee_per_gas') - Uint256? get maxFeePerGas; - @override - @BigIntConverter() - @JsonKey(name: 'max_priority_fee_per_gas') - Uint256? get maxPriorityFeePerGas; - @override - @JsonKey(name: 'tx_fee') - num get txFee; - @override - @JsonKey(name: 'saving_fee') - num? get savingFee; - @override - @JsonKey(name: 'burnt_fee') - num? get burntFee; - @override - @JsonKey(ignore: true) - _$$TransactionImplCopyWith<_$TransactionImpl> get copyWith => - throw _privateConstructorUsedError; -} diff --git a/lib/src/utils/models/transaction.g.dart b/lib/src/utils/models/transaction.g.dart deleted file mode 100644 index fd5449d..0000000 --- a/lib/src/utils/models/transaction.g.dart +++ /dev/null @@ -1,72 +0,0 @@ -// GENERATED CODE - DO NOT MODIFY BY HAND - -part of 'transaction.dart'; - -// ************************************************************************** -// JsonSerializableGenerator -// ************************************************************************** - -_$TransactionImpl _$$TransactionImplFromJson(Map json) => - _$TransactionImpl( - type: json['type'] as num, - status: json['status'] as num, - blockNumber: json['block_number'] as num, - blockTimestamp: DateTime.parse(json['block_timestamp'] as String), - transactionHash: json['transaction_hash'] as String, - transactionIndex: json['transaction_index'] as num, - fromAddress: json['from_address'] as String, - toAddress: json['to_address'] as String, - value: const BigIntConverter().fromJson(json['value']), - input: json['input'] as String?, - nonce: json['nonce'] as num, - contractAddress: json['contract_address'] as String?, - gas: const BigIntConverter().fromJson(json['gas']), - gasPrice: const BigIntConverter().fromJson(json['gas_price']), - gasUsed: const BigIntConverter().fromJson(json['gas_used']), - effectiveGasPrice: - const BigIntConverter().fromJson(json['effective_gas_price']), - cumulativeGasUsed: - const BigIntConverter().fromJson(json['cumulative_gas_used']), - maxFeePerGas: const BigIntConverter().fromJson(json['max_fee_per_gas']), - maxPriorityFeePerGas: - const BigIntConverter().fromJson(json['max_priority_fee_per_gas']), - txFee: json['tx_fee'] as num, - savingFee: json['saving_fee'] as num?, - burntFee: json['burnt_fee'] as num?, - ); - -Map _$$TransactionImplToJson(_$TransactionImpl instance) => - { - 'type': instance.type, - 'status': instance.status, - 'block_number': instance.blockNumber, - 'block_timestamp': instance.blockTimestamp.toIso8601String(), - 'transaction_hash': instance.transactionHash, - 'transaction_index': instance.transactionIndex, - 'from_address': instance.fromAddress, - 'to_address': instance.toAddress, - 'value': const BigIntConverter().toJson(instance.value), - 'input': instance.input, - 'nonce': instance.nonce, - 'contract_address': instance.contractAddress, - 'gas': const BigIntConverter().toJson(instance.gas), - 'gas_price': const BigIntConverter().toJson(instance.gasPrice), - 'gas_used': const BigIntConverter().toJson(instance.gasUsed), - 'effective_gas_price': - const BigIntConverter().toJson(instance.effectiveGasPrice), - 'cumulative_gas_used': - const BigIntConverter().toJson(instance.cumulativeGasUsed), - 'max_fee_per_gas': _$JsonConverterToJson( - instance.maxFeePerGas, const BigIntConverter().toJson), - 'max_priority_fee_per_gas': _$JsonConverterToJson( - instance.maxPriorityFeePerGas, const BigIntConverter().toJson), - 'tx_fee': instance.txFee, - 'saving_fee': instance.savingFee, - 'burnt_fee': instance.burntFee, - }; - -Json? _$JsonConverterToJson( - Value? value, - Json? Function(Value value) toJson, -) => - value == null ? null : toJson(value); diff --git a/lib/src/utils/models/transfer.dart b/lib/src/utils/models/transfer.dart deleted file mode 100644 index d10e36e..0000000 --- a/lib/src/utils/models/transfer.dart +++ /dev/null @@ -1,30 +0,0 @@ -import 'package:freezed_annotation/freezed_annotation.dart'; -import 'package:variance_dart/src/common/common.dart' show Uint256; -import 'package:variance_dart/utils.dart' show BigIntConverter; - -part 'transfer.freezed.dart'; -part 'transfer.g.dart'; - -@freezed -class TokenTransfer with _$TokenTransfer { - const factory TokenTransfer({ - required TxType direction, - @JsonKey(name: 'block_number') required num blockNumber, - @JsonKey(name: 'block_timestamp') required DateTime blockTimestamp, - @JsonKey(name: 'contract_address') required String contractAddress, - @JsonKey(name: 'from_address') required String fromAddress, - @JsonKey(name: 'log_index') required num logIndex, - @JsonKey(name: 'to_address') required String toAddress, - @JsonKey(name: 'transaction_hash') required String transactionHash, - @JsonKey(name: 'transaction_index') required num transactionIndex, - @JsonKey(name: 'tx_fee') required num txFee, - @JsonKey(name: 'tx_type') required num txType, - @BigIntConverter() required Uint256 value, - }) = _TokenTransfer; - - factory TokenTransfer.fromJson(Map json) => - _$TokenTransferFromJson(json); -} - -// ignore: constant_identifier_names -enum TxType { RECEIVE, SEND } diff --git a/lib/src/utils/models/transfer.freezed.dart b/lib/src/utils/models/transfer.freezed.dart deleted file mode 100644 index 841b010..0000000 --- a/lib/src/utils/models/transfer.freezed.dart +++ /dev/null @@ -1,430 +0,0 @@ -// coverage:ignore-file -// GENERATED CODE - DO NOT MODIFY BY HAND -// ignore_for_file: type=lint -// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target, unnecessary_question_mark - -part of 'transfer.dart'; - -// ************************************************************************** -// FreezedGenerator -// ************************************************************************** - -T _$identity(T value) => value; - -final _privateConstructorUsedError = UnsupportedError( - 'It seems like you constructed your class using `MyClass._()`. This constructor is only meant to be used by freezed and you are not supposed to need it nor use it.\nPlease check the documentation here for more information: https://github.com/rrousselGit/freezed#custom-getters-and-methods'); - -TokenTransfer _$TokenTransferFromJson(Map json) { - return _TokenTransfer.fromJson(json); -} - -/// @nodoc -mixin _$TokenTransfer { - TxType get direction => throw _privateConstructorUsedError; - @JsonKey(name: 'block_number') - num get blockNumber => throw _privateConstructorUsedError; - @JsonKey(name: 'block_timestamp') - DateTime get blockTimestamp => throw _privateConstructorUsedError; - @JsonKey(name: 'contract_address') - String get contractAddress => throw _privateConstructorUsedError; - @JsonKey(name: 'from_address') - String get fromAddress => throw _privateConstructorUsedError; - @JsonKey(name: 'log_index') - num get logIndex => throw _privateConstructorUsedError; - @JsonKey(name: 'to_address') - String get toAddress => throw _privateConstructorUsedError; - @JsonKey(name: 'transaction_hash') - String get transactionHash => throw _privateConstructorUsedError; - @JsonKey(name: 'transaction_index') - num get transactionIndex => throw _privateConstructorUsedError; - @JsonKey(name: 'tx_fee') - num get txFee => throw _privateConstructorUsedError; - @JsonKey(name: 'tx_type') - num get txType => throw _privateConstructorUsedError; - @BigIntConverter() - Uint256 get value => throw _privateConstructorUsedError; - - Map toJson() => throw _privateConstructorUsedError; - @JsonKey(ignore: true) - $TokenTransferCopyWith get copyWith => - throw _privateConstructorUsedError; -} - -/// @nodoc -abstract class $TokenTransferCopyWith<$Res> { - factory $TokenTransferCopyWith( - TokenTransfer value, $Res Function(TokenTransfer) then) = - _$TokenTransferCopyWithImpl<$Res, TokenTransfer>; - @useResult - $Res call( - {TxType direction, - @JsonKey(name: 'block_number') num blockNumber, - @JsonKey(name: 'block_timestamp') DateTime blockTimestamp, - @JsonKey(name: 'contract_address') String contractAddress, - @JsonKey(name: 'from_address') String fromAddress, - @JsonKey(name: 'log_index') num logIndex, - @JsonKey(name: 'to_address') String toAddress, - @JsonKey(name: 'transaction_hash') String transactionHash, - @JsonKey(name: 'transaction_index') num transactionIndex, - @JsonKey(name: 'tx_fee') num txFee, - @JsonKey(name: 'tx_type') num txType, - @BigIntConverter() Uint256 value}); -} - -/// @nodoc -class _$TokenTransferCopyWithImpl<$Res, $Val extends TokenTransfer> - implements $TokenTransferCopyWith<$Res> { - _$TokenTransferCopyWithImpl(this._value, this._then); - - // ignore: unused_field - final $Val _value; - // ignore: unused_field - final $Res Function($Val) _then; - - @pragma('vm:prefer-inline') - @override - $Res call({ - Object? direction = null, - Object? blockNumber = null, - Object? blockTimestamp = null, - Object? contractAddress = null, - Object? fromAddress = null, - Object? logIndex = null, - Object? toAddress = null, - Object? transactionHash = null, - Object? transactionIndex = null, - Object? txFee = null, - Object? txType = null, - Object? value = null, - }) { - return _then(_value.copyWith( - direction: null == direction - ? _value.direction - : direction // ignore: cast_nullable_to_non_nullable - as TxType, - blockNumber: null == blockNumber - ? _value.blockNumber - : blockNumber // ignore: cast_nullable_to_non_nullable - as num, - blockTimestamp: null == blockTimestamp - ? _value.blockTimestamp - : blockTimestamp // ignore: cast_nullable_to_non_nullable - as DateTime, - contractAddress: null == contractAddress - ? _value.contractAddress - : contractAddress // ignore: cast_nullable_to_non_nullable - as String, - fromAddress: null == fromAddress - ? _value.fromAddress - : fromAddress // ignore: cast_nullable_to_non_nullable - as String, - logIndex: null == logIndex - ? _value.logIndex - : logIndex // ignore: cast_nullable_to_non_nullable - as num, - toAddress: null == toAddress - ? _value.toAddress - : toAddress // ignore: cast_nullable_to_non_nullable - as String, - transactionHash: null == transactionHash - ? _value.transactionHash - : transactionHash // ignore: cast_nullable_to_non_nullable - as String, - transactionIndex: null == transactionIndex - ? _value.transactionIndex - : transactionIndex // ignore: cast_nullable_to_non_nullable - as num, - txFee: null == txFee - ? _value.txFee - : txFee // ignore: cast_nullable_to_non_nullable - as num, - txType: null == txType - ? _value.txType - : txType // ignore: cast_nullable_to_non_nullable - as num, - value: null == value - ? _value.value - : value // ignore: cast_nullable_to_non_nullable - as Uint256, - ) as $Val); - } -} - -/// @nodoc -abstract class _$$TokenTransferImplCopyWith<$Res> - implements $TokenTransferCopyWith<$Res> { - factory _$$TokenTransferImplCopyWith( - _$TokenTransferImpl value, $Res Function(_$TokenTransferImpl) then) = - __$$TokenTransferImplCopyWithImpl<$Res>; - @override - @useResult - $Res call( - {TxType direction, - @JsonKey(name: 'block_number') num blockNumber, - @JsonKey(name: 'block_timestamp') DateTime blockTimestamp, - @JsonKey(name: 'contract_address') String contractAddress, - @JsonKey(name: 'from_address') String fromAddress, - @JsonKey(name: 'log_index') num logIndex, - @JsonKey(name: 'to_address') String toAddress, - @JsonKey(name: 'transaction_hash') String transactionHash, - @JsonKey(name: 'transaction_index') num transactionIndex, - @JsonKey(name: 'tx_fee') num txFee, - @JsonKey(name: 'tx_type') num txType, - @BigIntConverter() Uint256 value}); -} - -/// @nodoc -class __$$TokenTransferImplCopyWithImpl<$Res> - extends _$TokenTransferCopyWithImpl<$Res, _$TokenTransferImpl> - implements _$$TokenTransferImplCopyWith<$Res> { - __$$TokenTransferImplCopyWithImpl( - _$TokenTransferImpl _value, $Res Function(_$TokenTransferImpl) _then) - : super(_value, _then); - - @pragma('vm:prefer-inline') - @override - $Res call({ - Object? direction = null, - Object? blockNumber = null, - Object? blockTimestamp = null, - Object? contractAddress = null, - Object? fromAddress = null, - Object? logIndex = null, - Object? toAddress = null, - Object? transactionHash = null, - Object? transactionIndex = null, - Object? txFee = null, - Object? txType = null, - Object? value = null, - }) { - return _then(_$TokenTransferImpl( - direction: null == direction - ? _value.direction - : direction // ignore: cast_nullable_to_non_nullable - as TxType, - blockNumber: null == blockNumber - ? _value.blockNumber - : blockNumber // ignore: cast_nullable_to_non_nullable - as num, - blockTimestamp: null == blockTimestamp - ? _value.blockTimestamp - : blockTimestamp // ignore: cast_nullable_to_non_nullable - as DateTime, - contractAddress: null == contractAddress - ? _value.contractAddress - : contractAddress // ignore: cast_nullable_to_non_nullable - as String, - fromAddress: null == fromAddress - ? _value.fromAddress - : fromAddress // ignore: cast_nullable_to_non_nullable - as String, - logIndex: null == logIndex - ? _value.logIndex - : logIndex // ignore: cast_nullable_to_non_nullable - as num, - toAddress: null == toAddress - ? _value.toAddress - : toAddress // ignore: cast_nullable_to_non_nullable - as String, - transactionHash: null == transactionHash - ? _value.transactionHash - : transactionHash // ignore: cast_nullable_to_non_nullable - as String, - transactionIndex: null == transactionIndex - ? _value.transactionIndex - : transactionIndex // ignore: cast_nullable_to_non_nullable - as num, - txFee: null == txFee - ? _value.txFee - : txFee // ignore: cast_nullable_to_non_nullable - as num, - txType: null == txType - ? _value.txType - : txType // ignore: cast_nullable_to_non_nullable - as num, - value: null == value - ? _value.value - : value // ignore: cast_nullable_to_non_nullable - as Uint256, - )); - } -} - -/// @nodoc -@JsonSerializable() -class _$TokenTransferImpl implements _TokenTransfer { - const _$TokenTransferImpl( - {required this.direction, - @JsonKey(name: 'block_number') required this.blockNumber, - @JsonKey(name: 'block_timestamp') required this.blockTimestamp, - @JsonKey(name: 'contract_address') required this.contractAddress, - @JsonKey(name: 'from_address') required this.fromAddress, - @JsonKey(name: 'log_index') required this.logIndex, - @JsonKey(name: 'to_address') required this.toAddress, - @JsonKey(name: 'transaction_hash') required this.transactionHash, - @JsonKey(name: 'transaction_index') required this.transactionIndex, - @JsonKey(name: 'tx_fee') required this.txFee, - @JsonKey(name: 'tx_type') required this.txType, - @BigIntConverter() required this.value}); - - factory _$TokenTransferImpl.fromJson(Map json) => - _$$TokenTransferImplFromJson(json); - - @override - final TxType direction; - @override - @JsonKey(name: 'block_number') - final num blockNumber; - @override - @JsonKey(name: 'block_timestamp') - final DateTime blockTimestamp; - @override - @JsonKey(name: 'contract_address') - final String contractAddress; - @override - @JsonKey(name: 'from_address') - final String fromAddress; - @override - @JsonKey(name: 'log_index') - final num logIndex; - @override - @JsonKey(name: 'to_address') - final String toAddress; - @override - @JsonKey(name: 'transaction_hash') - final String transactionHash; - @override - @JsonKey(name: 'transaction_index') - final num transactionIndex; - @override - @JsonKey(name: 'tx_fee') - final num txFee; - @override - @JsonKey(name: 'tx_type') - final num txType; - @override - @BigIntConverter() - final Uint256 value; - - @override - String toString() { - return 'TokenTransfer(direction: $direction, blockNumber: $blockNumber, blockTimestamp: $blockTimestamp, contractAddress: $contractAddress, fromAddress: $fromAddress, logIndex: $logIndex, toAddress: $toAddress, transactionHash: $transactionHash, transactionIndex: $transactionIndex, txFee: $txFee, txType: $txType, value: $value)'; - } - - @override - bool operator ==(Object other) { - return identical(this, other) || - (other.runtimeType == runtimeType && - other is _$TokenTransferImpl && - (identical(other.direction, direction) || - other.direction == direction) && - (identical(other.blockNumber, blockNumber) || - other.blockNumber == blockNumber) && - (identical(other.blockTimestamp, blockTimestamp) || - other.blockTimestamp == blockTimestamp) && - (identical(other.contractAddress, contractAddress) || - other.contractAddress == contractAddress) && - (identical(other.fromAddress, fromAddress) || - other.fromAddress == fromAddress) && - (identical(other.logIndex, logIndex) || - other.logIndex == logIndex) && - (identical(other.toAddress, toAddress) || - other.toAddress == toAddress) && - (identical(other.transactionHash, transactionHash) || - other.transactionHash == transactionHash) && - (identical(other.transactionIndex, transactionIndex) || - other.transactionIndex == transactionIndex) && - (identical(other.txFee, txFee) || other.txFee == txFee) && - (identical(other.txType, txType) || other.txType == txType) && - (identical(other.value, value) || other.value == value)); - } - - @JsonKey(ignore: true) - @override - int get hashCode => Object.hash( - runtimeType, - direction, - blockNumber, - blockTimestamp, - contractAddress, - fromAddress, - logIndex, - toAddress, - transactionHash, - transactionIndex, - txFee, - txType, - value); - - @JsonKey(ignore: true) - @override - @pragma('vm:prefer-inline') - _$$TokenTransferImplCopyWith<_$TokenTransferImpl> get copyWith => - __$$TokenTransferImplCopyWithImpl<_$TokenTransferImpl>(this, _$identity); - - @override - Map toJson() { - return _$$TokenTransferImplToJson( - this, - ); - } -} - -abstract class _TokenTransfer implements TokenTransfer { - const factory _TokenTransfer( - {required final TxType direction, - @JsonKey(name: 'block_number') required final num blockNumber, - @JsonKey(name: 'block_timestamp') required final DateTime blockTimestamp, - @JsonKey(name: 'contract_address') required final String contractAddress, - @JsonKey(name: 'from_address') required final String fromAddress, - @JsonKey(name: 'log_index') required final num logIndex, - @JsonKey(name: 'to_address') required final String toAddress, - @JsonKey(name: 'transaction_hash') required final String transactionHash, - @JsonKey(name: 'transaction_index') required final num transactionIndex, - @JsonKey(name: 'tx_fee') required final num txFee, - @JsonKey(name: 'tx_type') required final num txType, - @BigIntConverter() required final Uint256 value}) = _$TokenTransferImpl; - - factory _TokenTransfer.fromJson(Map json) = - _$TokenTransferImpl.fromJson; - - @override - TxType get direction; - @override - @JsonKey(name: 'block_number') - num get blockNumber; - @override - @JsonKey(name: 'block_timestamp') - DateTime get blockTimestamp; - @override - @JsonKey(name: 'contract_address') - String get contractAddress; - @override - @JsonKey(name: 'from_address') - String get fromAddress; - @override - @JsonKey(name: 'log_index') - num get logIndex; - @override - @JsonKey(name: 'to_address') - String get toAddress; - @override - @JsonKey(name: 'transaction_hash') - String get transactionHash; - @override - @JsonKey(name: 'transaction_index') - num get transactionIndex; - @override - @JsonKey(name: 'tx_fee') - num get txFee; - @override - @JsonKey(name: 'tx_type') - num get txType; - @override - @BigIntConverter() - Uint256 get value; - @override - @JsonKey(ignore: true) - _$$TokenTransferImplCopyWith<_$TokenTransferImpl> get copyWith => - throw _privateConstructorUsedError; -} diff --git a/lib/src/utils/models/transfer.g.dart b/lib/src/utils/models/transfer.g.dart deleted file mode 100644 index a843a76..0000000 --- a/lib/src/utils/models/transfer.g.dart +++ /dev/null @@ -1,44 +0,0 @@ -// GENERATED CODE - DO NOT MODIFY BY HAND - -part of 'transfer.dart'; - -// ************************************************************************** -// JsonSerializableGenerator -// ************************************************************************** - -_$TokenTransferImpl _$$TokenTransferImplFromJson(Map json) => - _$TokenTransferImpl( - direction: $enumDecode(_$TxTypeEnumMap, json['direction']), - blockNumber: json['block_number'] as num, - blockTimestamp: DateTime.parse(json['block_timestamp'] as String), - contractAddress: json['contract_address'] as String, - fromAddress: json['from_address'] as String, - logIndex: json['log_index'] as num, - toAddress: json['to_address'] as String, - transactionHash: json['transaction_hash'] as String, - transactionIndex: json['transaction_index'] as num, - txFee: json['tx_fee'] as num, - txType: json['tx_type'] as num, - value: const BigIntConverter().fromJson(json['value']), - ); - -Map _$$TokenTransferImplToJson(_$TokenTransferImpl instance) => - { - 'direction': _$TxTypeEnumMap[instance.direction]!, - 'block_number': instance.blockNumber, - 'block_timestamp': instance.blockTimestamp.toIso8601String(), - 'contract_address': instance.contractAddress, - 'from_address': instance.fromAddress, - 'log_index': instance.logIndex, - 'to_address': instance.toAddress, - 'transaction_hash': instance.transactionHash, - 'transaction_index': instance.transactionIndex, - 'tx_fee': instance.txFee, - 'tx_type': instance.txType, - 'value': const BigIntConverter().toJson(instance.value), - }; - -const _$TxTypeEnumMap = { - TxType.RECEIVE: 'RECEIVE', - TxType.SEND: 'SEND', -}; diff --git a/lib/src/utils/secure_storage_repository.dart b/lib/src/utils/secure_storage_repository.dart deleted file mode 100644 index 5886a53..0000000 --- a/lib/src/utils/secure_storage_repository.dart +++ /dev/null @@ -1,131 +0,0 @@ -part of '../../utils.dart'; - -enum CredentialType { hdwallet, privateKey, passkeypair } - -class SecureStorageAuthMiddlewareError extends Error { - final String message = - "requires auth, but Authentication middleware is not set"; - - SecureStorageAuthMiddlewareError(); - - @override - String toString() { - return 'SecureStorageAuthMiddlewareError: $message'; - } -} - -class SecureStorageMiddleware implements SecureStorageRepository { - final AndroidOptions androidOptions; - final IOSOptions iosOptions; - - final FlutterSecureStorage secureStorage; - final Authentication? authMiddleware; - - final String? _credential; - - SecureStorageMiddleware({ - required this.secureStorage, - this.authMiddleware, - String? credential, - }) : androidOptions = const AndroidOptions( - encryptedSharedPreferences: true, - ), - iosOptions = const IOSOptions( - accessibility: KeychainAccessibility.unlocked, - ), - _credential = credential; - - Future _authenticate({required SSAuthOperationOptions options}) async { - if (!options.requiresAuth) return; - if (authMiddleware == null) throw SecureStorageAuthMiddlewareError(); - - return await authMiddleware?.authenticate( - localizedReason: options.authReason, - ); - } - - @override - Future delete( - String key, { - SSAuthOperationOptions? options = const SSAuthOperationOptions(), - }) async { - await _authenticate(options: options!); - await secureStorage.delete( - key: "${options.ssNameSpace ?? "vaariance"}_$key", - ); - } - - @override - Future read( - String key, { - SSAuthOperationOptions? options = const SSAuthOperationOptions(), - }) async { - await _authenticate(options: options!); - return await secureStorage.read( - key: "${options.ssNameSpace ?? "vaariance"}_$key", - ); - } - - @override - Future readCredential( - CredentialType type, { - SSAuthOperationOptions? options = const SSAuthOperationOptions(), - }) async { - await _authenticate(options: options!); - return await secureStorage.read( - key: "${options.ssNameSpace ?? "vaariance"}_${type.name}", - ); - } - - @override - Future save( - String key, - String value, { - SSAuthOperationOptions? options = const SSAuthOperationOptions(), - }) async { - await _authenticate(options: options!); - await secureStorage.write( - key: "${options.ssNameSpace ?? "vaariance"}_$key", - value: value, - ); - } - - @override - Future saveCredential( - CredentialType type, { - SSAuthOperationOptions? options = const SSAuthOperationOptions(), - }) async { - await _authenticate(options: options!); - await secureStorage.write( - key: "${options.ssNameSpace ?? "vaariance"}_${type.name}", - value: _credential, - ); - } - - @override - Future update( - String key, - String value, { - SSAuthOperationOptions? options = const SSAuthOperationOptions(), - }) async { - await _authenticate(options: options!); - await secureStorage.write( - key: "${options.ssNameSpace ?? "vaariance"}_$key", - value: value, - ); - } -} - -class SSAuthOperationOptions { - final bool requiresAuth; - final String authReason; - // Namespace for uniquely addressing the secure storage keys. - // if provided the secure storage keys will be prefixed with this value, defaults to "vaariance" - // namespace ?? "vaariance" + "_" + identifier - final String? ssNameSpace; - - const SSAuthOperationOptions( - {bool? requiresAuth, String? authReason, this.ssNameSpace}) - : authReason = authReason ?? "unlock to access secure storage", - requiresAuth = requiresAuth ?? false; -} diff --git a/lib/utils.dart b/lib/utils.dart deleted file mode 100644 index 8e750ff..0000000 --- a/lib/utils.dart +++ /dev/null @@ -1,42 +0,0 @@ -library utils; - -import 'dart:convert'; -import 'dart:developer'; - -import 'package:crypto/crypto.dart'; -import 'package:dio/dio.dart'; -import 'package:dio_cache_interceptor/dio_cache_interceptor.dart'; -import 'package:flutter/services.dart'; -import 'package:flutter_secure_storage/flutter_secure_storage.dart'; -import 'package:local_auth/error_codes.dart' as auth_error; -import 'package:local_auth/local_auth.dart'; -import 'package:local_auth_android/local_auth_android.dart'; -import 'package:local_auth_ios/types/auth_messages_ios.dart'; -import 'package:web3dart/web3dart.dart' show BlockNum, EthereumAddress; -import 'package:webcrypto/webcrypto.dart'; - -import 'src/interfaces/interfaces.dart'; -import 'src/utils/models/ens.dart'; -import 'src/utils/models/metadata.dart'; -import 'src/utils/models/nft.dart'; -import 'src/utils/models/price.dart'; -import 'src/utils/models/token.dart'; -import 'src/utils/models/transaction.dart'; -import 'src/utils/models/transfer.dart'; -import 'variance.dart' show Chain; - -export 'package:dio/dio.dart' show BaseOptions; - -export 'src/utils/models/ens.dart'; -export 'src/utils/models/metadata.dart'; -export 'src/utils/models/nft.dart'; -export 'src/utils/models/price.dart'; -export 'src/utils/models/token.dart'; -export 'src/utils/models/transaction.dart'; -export 'src/utils/models/transfer.dart'; - -part 'src/utils/chainbase_api.dart'; -part 'src/utils/crypto.dart'; -part 'src/utils/dio_client.dart'; -part 'src/utils/local_authentication.dart'; -part 'src/utils/secure_storage_repository.dart'; diff --git a/lib/variance.dart b/lib/variance.dart deleted file mode 100644 index ad77e2c..0000000 --- a/lib/variance.dart +++ /dev/null @@ -1,40 +0,0 @@ -library variance; - -import 'dart:async'; -import 'dart:convert'; -import 'dart:isolate'; -import 'dart:math'; -import 'dart:typed_data'; - -import 'package:asn1lib/asn1lib.dart'; -import 'package:bip32_bip44/dart_bip32_bip44.dart' as bip44; -import "package:bip39/bip39.dart" as bip39; -import 'package:cbor/cbor.dart'; -import 'package:flutter/foundation.dart'; -import 'package:flutter_secure_storage/flutter_secure_storage.dart'; -import 'package:http/http.dart' as http; -import 'package:string_validator/string_validator.dart'; -import 'package:uuid/uuid.dart'; -import 'package:web3dart/crypto.dart'; -import 'package:web3dart/json_rpc.dart'; -import 'package:web3dart/web3dart.dart'; -import 'package:webauthn/webauthn.dart'; - -import 'src/interfaces/interfaces.dart'; -import 'src/abis/abis.dart'; -import 'src/common/common.dart'; -import 'utils.dart'; - -export 'src/abis/abis.dart' show Entrypoint; -export 'src/common/common.dart'; - -part 'src/4337/chains.dart'; -part 'src/4337/paymaster.dart'; -part 'src/4337/providers.dart'; -part 'src/4337/userop.dart'; -part 'src/4337/wallet.dart'; -part 'src/common/factory.dart'; -part 'src/common/plugins.dart'; -part 'src/signers/private_key_signer.dart'; -part 'src/signers/hd_wallet_signer.dart'; -part 'src/signers/passkey_signer.dart'; diff --git a/lib/variance_dart.dart b/lib/variance_dart.dart new file mode 100644 index 0000000..15ab5f8 --- /dev/null +++ b/lib/variance_dart.dart @@ -0,0 +1,31 @@ +library; + +import 'dart:async'; +import 'dart:convert'; +import 'dart:typed_data'; + +import 'package:http/http.dart' as http; +import 'package:web3_signers/web3_signers.dart'; +import 'package:web3dart/crypto.dart'; +import 'package:web3dart/json_rpc.dart'; +import 'package:web3dart/web3dart.dart'; + +import 'src/abis/abis.dart'; +import 'src/common/logger.dart'; +import 'src/interfaces/interfaces.dart'; + +export 'src/abis/abis.dart' show ContractAbis; + +part 'src/4337/chains.dart'; +part 'src/4337/factory.dart'; +part 'src/4337/paymaster.dart'; +part 'src/4337/providers.dart'; +part 'src/4337/safe.dart'; +part 'src/4337/userop.dart'; +part 'src/4337/wallet.dart'; +part 'src/common/contract.dart'; +part 'src/common/factories.dart'; +part 'src/common/mixins.dart'; +part 'src/common/pack.dart'; +part 'src/common/string.dart'; +part 'src/errors/wallet_errors.dart'; diff --git a/pubspec.lock b/pubspec.lock index 05d0ed0..07c8696 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -26,13 +26,13 @@ packages: source: hosted version: "2.4.2" asn1lib: - dependency: "direct main" + dependency: transitive description: name: asn1lib - sha256: "21afe4333076c02877d14f4a89df111e658a6d466cbfc802eb705eb91bd5adfd" + sha256: c9c85fedbe2188b95133cbe960e16f5f448860f7133330e272edbbca5893ddc6 url: "https://pub.dev" source: hosted - version: "1.5.0" + version: "1.5.2" async: dependency: transitive description: @@ -41,30 +41,14 @@ packages: url: "https://pub.dev" source: hosted version: "2.11.0" - base58check: + blockchain_utils: dependency: transitive description: - name: base58check - sha256: "6c300dfc33e598d2fe26319e13f6243fea81eaf8204cb4c6b69ef20a625319a5" - url: "https://pub.dev" - source: hosted - version: "2.0.0" - bip32_bip44: - dependency: "direct main" - description: - name: bip32_bip44 - sha256: "8e28e6bde00da1ed207f2c0a5361792375799196176742c0d36c71e89a5485d3" + name: blockchain_utils + sha256: "38ef5f4a22441ac4370aed9071dc71c460acffc37c79b344533f67d15f24c13c" url: "https://pub.dev" source: hosted - version: "1.0.0" - bip39: - dependency: "direct main" - description: - name: bip39 - sha256: de1ee27ebe7d96b84bb3a04a4132a0a3007dcdd5ad27dd14aa87a29d97c45edc - url: "https://pub.dev" - source: hosted - version: "1.0.6" + version: "2.1.1" boolean_selector: dependency: transitive description: @@ -109,18 +93,18 @@ packages: dependency: "direct dev" description: name: build_runner - sha256: "581bacf68f89ec8792f5e5a0b2c4decd1c948e97ce659dc783688c8a88fbec21" + sha256: "3ac61a79bfb6f6cc11f693591063a7f19a7af628dc52f141743edac5c16e8c22" url: "https://pub.dev" source: hosted - version: "2.4.8" + version: "2.4.9" build_runner_core: dependency: transitive description: name: build_runner_core - sha256: c9e32d21dd6626b5c163d48b037ce906bbe428bc23ab77bcd77bb21e593b6185 + sha256: "4ae8ffe5ac758da294ecf1802f2aff01558d8b1b00616aa7538ea9a8a5d50799" url: "https://pub.dev" source: hosted - version: "7.2.11" + version: "7.3.0" built_collection: dependency: transitive description: @@ -133,26 +117,10 @@ packages: dependency: transitive description: name: built_value - sha256: c9aabae0718ec394e5bc3c7272e6bb0dc0b32201a08fe185ec1d8401d3e39309 + sha256: c7913a9737ee4007efedaffc968c049fd0f3d0e49109e778edc10de9426005cb url: "https://pub.dev" source: hosted - version: "8.8.1" - byte_extensions: - dependency: transitive - description: - name: byte_extensions - sha256: d69db1bb5926638d937f2382fe7ad97772e61a4fb842a3143d1510224666385c - url: "https://pub.dev" - source: hosted - version: "0.0.3" - cbor: - dependency: "direct main" - description: - name: cbor - sha256: eccfcb3c16a46146517f6970d4d6df94bfd443e048d5825e85b9e23cc08d1132 - url: "https://pub.dev" - source: hosted - version: "6.1.1" + version: "8.9.2" characters: dependency: transitive description: @@ -189,10 +157,10 @@ packages: dependency: transitive description: name: collection - sha256: f092b211a4319e98e5ff58223576de6c2803db36221657b46c82574721240687 + sha256: ee67cb0715911d28db6bf4af1026078bd6f0128b07a5f66fb2ed94ec6783c09a url: "https://pub.dev" source: hosted - version: "1.17.2" + version: "1.18.0" convert: dependency: transitive description: @@ -201,46 +169,30 @@ packages: url: "https://pub.dev" source: hosted version: "3.1.1" - crypto: - dependency: "direct main" + corbado_frontend_api_client: + dependency: transitive description: - name: crypto - sha256: ff625774173754681d66daaf4a448684fb04b78f902da9cb3d308c19cc5e8bab + name: corbado_frontend_api_client + sha256: a6d65fc0da88f2e6a6e95251de0b67735556128c5d96c9b609e7b18010a6f6c1 url: "https://pub.dev" source: hosted - version: "3.0.3" - crypto_keys: + version: "1.1.0" + crypto: dependency: transitive description: - name: crypto_keys - sha256: acc19abf34623d990a0e8aec69463d74a824c31f137128f42e2810befc509ad0 + name: crypto + sha256: ff625774173754681d66daaf4a448684fb04b78f902da9cb3d308c19cc5e8bab url: "https://pub.dev" source: hosted - version: "0.3.0+1" + version: "3.0.3" dart_style: dependency: transitive description: name: dart_style - sha256: "40ae61a5d43feea6d24bd22c0537a6629db858963b99b4bc1c3db80676f32368" + sha256: "99e066ce75c89d6b29903d788a7bb9369cf754f7b24bf70bf4b6d6d6b26853b9" url: "https://pub.dev" source: hosted - version: "2.3.4" - dio: - dependency: "direct main" - description: - name: dio - sha256: "797e1e341c3dd2f69f2dad42564a6feff3bfb87187d05abb93b9609e6f1645c3" - url: "https://pub.dev" - source: hosted - version: "5.4.0" - dio_cache_interceptor: - dependency: "direct main" - description: - name: dio_cache_interceptor - sha256: fb7905c0d12075d8786a6b63bffd64ae062d053f682cfaf28d145a2686507308 - url: "https://pub.dev" - source: hosted - version: "3.5.0" + version: "2.3.6" eip1559: dependency: transitive description: @@ -257,22 +209,6 @@ packages: url: "https://pub.dev" source: hosted version: "1.0.2" - equatable: - dependency: transitive - description: - name: equatable - sha256: c2b87cb7756efdf69892005af546c56c0b5037f54d2a88269b4f347a505e3ca2 - url: "https://pub.dev" - source: hosted - version: "2.0.5" - ffi: - dependency: transitive - description: - name: ffi - sha256: "7bf0adc28a23d395f19f3f1eb21dd7cfd1dd9f8e1c50051c069122e6853bc878" - url: "https://pub.dev" - source: hosted - version: "2.1.0" file: dependency: transitive description: @@ -298,95 +234,23 @@ packages: dependency: "direct dev" description: name: flutter_lints - sha256: e2a421b7e59244faef694ba7b30562e489c2b489866e505074eb005cd7060db7 - url: "https://pub.dev" - source: hosted - version: "3.0.1" - flutter_plugin_android_lifecycle: - dependency: transitive - description: - name: flutter_plugin_android_lifecycle - sha256: b068ffc46f82a55844acfa4fdbb61fad72fa2aef0905548419d97f0f95c456da + sha256: "9e8c3858111da373efc5aa341de011d9bd23e2c5c5e0c62bccf32438e192d7b1" url: "https://pub.dev" source: hosted - version: "2.0.17" - flutter_secure_storage: - dependency: "direct main" - description: - name: flutter_secure_storage - sha256: ffdbb60130e4665d2af814a0267c481bcf522c41ae2e43caf69fa0146876d685 - url: "https://pub.dev" - source: hosted - version: "9.0.0" - flutter_secure_storage_linux: - dependency: transitive - description: - name: flutter_secure_storage_linux - sha256: "3d5032e314774ee0e1a7d0a9f5e2793486f0dff2dd9ef5a23f4e3fb2a0ae6a9e" - url: "https://pub.dev" - source: hosted - version: "1.2.0" - flutter_secure_storage_macos: - dependency: transitive - description: - name: flutter_secure_storage_macos - sha256: bd33935b4b628abd0b86c8ca20655c5b36275c3a3f5194769a7b3f37c905369c - url: "https://pub.dev" - source: hosted - version: "3.0.1" - flutter_secure_storage_platform_interface: - dependency: transitive - description: - name: flutter_secure_storage_platform_interface - sha256: "0d4d3a5dd4db28c96ae414d7ba3b8422fd735a8255642774803b2532c9a61d7e" - url: "https://pub.dev" - source: hosted - version: "1.0.2" - flutter_secure_storage_web: - dependency: transitive - description: - name: flutter_secure_storage_web - sha256: "30f84f102df9dcdaa2241866a958c2ec976902ebdaa8883fbfe525f1f2f3cf20" - url: "https://pub.dev" - source: hosted - version: "1.1.2" - flutter_secure_storage_windows: - dependency: transitive - description: - name: flutter_secure_storage_windows - sha256: "5809c66f9dd3b4b93b0a6e2e8561539405322ee767ac2f64d084e2ab5429d108" - url: "https://pub.dev" - source: hosted - version: "3.0.0" + version: "3.0.2" flutter_web_plugins: dependency: transitive description: flutter source: sdk version: "0.0.0" - freezed: - dependency: "direct dev" - description: - name: freezed - sha256: "6c5031daae12c7072b3a87eff98983076434b4889ef2a44384d0cae3f82372ba" - url: "https://pub.dev" - source: hosted - version: "2.4.6" - freezed_annotation: - dependency: "direct main" - description: - name: freezed_annotation - sha256: c3fd9336eb55a38cc1bbd79ab17573113a8deccd0ecbbf926cca3c62803b5c2d - url: "https://pub.dev" - source: hosted - version: "2.4.1" frontend_server_client: dependency: transitive description: name: frontend_server_client - sha256: "408e3ca148b31c20282ad6f37ebfa6f4bdc8fede5b74bc2f08d9d92b55db3612" + sha256: f64a0333a82f30b0cca061bc3d143813a486dc086b574bfb233b7c1372427694 url: "https://pub.dev" source: hosted - version: "3.2.0" + version: "4.0.0" glob: dependency: transitive description: @@ -403,22 +267,14 @@ packages: url: "https://pub.dev" source: hosted version: "2.3.1" - hex: - dependency: transitive - description: - name: hex - sha256: "4e7cd54e4b59ba026432a6be2dd9d96e4c5205725194997193bf871703b82c4a" - url: "https://pub.dev" - source: hosted - version: "0.2.0" http: dependency: "direct main" description: name: http - sha256: "759d1a329847dd0f39226c688d3e06a6b8679668e350e2891a6474f8b4bb8525" + sha256: a2bbf9d017fcced29139daa8ed2bba4ece450ab222871df93ca9eec6f80c34ba url: "https://pub.dev" source: hosted - version: "1.1.0" + version: "1.2.0" http_multi_server: dependency: transitive description: @@ -435,14 +291,6 @@ packages: url: "https://pub.dev" source: hosted version: "4.0.2" - ieee754: - dependency: transitive - description: - name: ieee754 - sha256: "7d87451c164a56c156180d34a4e93779372edd191d2c219206100b976203128c" - url: "https://pub.dev" - source: hosted - version: "1.0.3" intl: dependency: transitive description: @@ -468,7 +316,7 @@ packages: source: hosted version: "0.6.7" json_annotation: - dependency: "direct main" + dependency: transitive description: name: json_annotation sha256: b10a7b2ff83d83c777edba3c6a0f97045ddadd56c944e1a23a3fdf43a1bf4467 @@ -483,14 +331,6 @@ packages: url: "https://pub.dev" source: hosted version: "3.0.2" - json_serializable: - dependency: "direct dev" - description: - name: json_serializable - sha256: aa1f5a8912615733e0fdc7a02af03308933c93235bdc8d50d0b0c8a8ccb0b969 - url: "https://pub.dev" - source: hosted - version: "6.7.1" lints: dependency: transitive description: @@ -499,54 +339,6 @@ packages: url: "https://pub.dev" source: hosted version: "3.0.0" - local_auth: - dependency: "direct main" - description: - name: local_auth - sha256: "27679ed8e0d7daab2357db6bb7076359e083a56b295c0c59723845301da6aed9" - url: "https://pub.dev" - source: hosted - version: "2.1.8" - local_auth_android: - dependency: "direct main" - description: - name: local_auth_android - sha256: "54e9c35ce52c06333355ab0d0f41e4c06dbca354b23426765ba41dfb1de27598" - url: "https://pub.dev" - source: hosted - version: "1.0.36" - local_auth_ios: - dependency: "direct main" - description: - name: local_auth_ios - sha256: "8293faf72ef0ac4710f209edd03916c2d4c1eeab0483bdcf9b2e659c2f7d737b" - url: "https://pub.dev" - source: hosted - version: "1.1.5" - local_auth_platform_interface: - dependency: transitive - description: - name: local_auth_platform_interface - sha256: "1b842ff177a7068442eae093b64abe3592f816afd2a533c0ebcdbe40f9d2075a" - url: "https://pub.dev" - source: hosted - version: "1.0.10" - local_auth_windows: - dependency: transitive - description: - name: local_auth_windows - sha256: "505ba3367ca781efb1c50d3132e44a2446bccc4163427bc203b9b4d8994d97ea" - url: "https://pub.dev" - source: hosted - version: "1.0.10" - logger: - dependency: transitive - description: - name: logger - sha256: "6bbb9d6f7056729537a4309bda2e74e18e5d9f14302489cc1e93f33b3fe32cac" - url: "https://pub.dev" - source: hosted - version: "2.0.2+1" logging: dependency: transitive description: @@ -575,18 +367,18 @@ packages: dependency: transitive description: name: meta - sha256: "3c74dbf8763d36539f114c799d8a2d87343b5067e9d796ca22b5eb8437090ee3" + sha256: a6e590c838b18133bb482a2745ad77c5bb7715fb0451209e1a7567d416678b8e url: "https://pub.dev" source: hosted - version: "1.9.1" + version: "1.10.0" mime: dependency: transitive description: name: mime - sha256: e4ff8e8564c03f255408decd16e7899da1733852a9110a58fe6d1b817684a63e + sha256: "2e123074287cc9fd6c09de8336dae606d1ddb88d9ac47358826db698c176a1f2" url: "https://pub.dev" source: hosted - version: "1.0.4" + version: "1.0.5" mockito: dependency: "direct dev" description: @@ -595,78 +387,70 @@ packages: url: "https://pub.dev" source: hosted version: "5.4.4" - package_config: + openapi_generator_annotations: dependency: transitive description: - name: package_config - sha256: "1c5b77ccc91e4823a5af61ee74e6b972db1ef98c2ff5a18d3161c982a55448bd" + name: openapi_generator_annotations + sha256: "46f1fb675029d78e19ce9143e70ce414d738b0f6c45c49c004b4b3afdb405a5c" url: "https://pub.dev" source: hosted - version: "2.1.0" - path: - dependency: transitive - description: - name: path - sha256: "087ce49c3f0dc39180befefc60fdb4acd8f8620e5682fe2476afd0b3688bb4af" - url: "https://pub.dev" - source: hosted - version: "1.9.0" - path_provider: + version: "4.13.1" + package_config: dependency: transitive description: - name: path_provider - sha256: b27217933eeeba8ff24845c34003b003b2b22151de3c908d0e679e8fe1aa078b + name: package_config + sha256: "1c5b77ccc91e4823a5af61ee74e6b972db1ef98c2ff5a18d3161c982a55448bd" url: "https://pub.dev" source: hosted - version: "2.1.2" - path_provider_android: + version: "2.1.0" + passkeys: dependency: transitive description: - name: path_provider_android - sha256: "477184d672607c0a3bf68fbbf601805f92ef79c82b64b4d6eb318cbca4c48668" + name: passkeys + sha256: "59e50b21746aff90cbc56145174caa3b99523f449e42f7d8aa2199ec09c511cd" url: "https://pub.dev" source: hosted - version: "2.2.2" - path_provider_foundation: + version: "2.0.8" + passkeys_android: dependency: transitive description: - name: path_provider_foundation - sha256: "19314d595120f82aca0ba62787d58dde2cc6b5df7d2f0daf72489e38d1b57f2d" + name: passkeys_android + sha256: "9dc0b84dad03329ff2f3be18bedecf1b8de9309c8e9cda6ef821dc88556a126d" url: "https://pub.dev" source: hosted - version: "2.3.1" - path_provider_linux: + version: "2.0.4" + passkeys_ios: dependency: transitive description: - name: path_provider_linux - sha256: f7a1fe3a634fe7734c8d3f2766ad746ae2a2884abe22e241a8b301bf5cac3279 + name: passkeys_ios + sha256: "411b10c3cd159c9601426d47b2dc5aa4dd1e34ef69deefaac01ff81712ea6064" url: "https://pub.dev" source: hosted - version: "2.2.1" - path_provider_platform_interface: + version: "2.0.3" + passkeys_platform_interface: dependency: transitive description: - name: path_provider_platform_interface - sha256: "88f5779f72ba699763fa3a3b06aa4bf6de76c8e5de842cf6f29e2e06476c2334" + name: passkeys_platform_interface + sha256: a1f1f5c637049f68350cf43323df9689be2e86fe5822a6e098362e7f6168351e url: "https://pub.dev" source: hosted - version: "2.1.2" - path_provider_windows: + version: "2.0.1" + passkeys_web: dependency: transitive description: - name: path_provider_windows - sha256: "8bc9f22eee8690981c22aa7fc602f5c85b497a6fb2ceb35ee5a5e5ed85ad8170" + name: passkeys_web + sha256: "1c7815020332b9be1af4df67686826a91b6dd29fea53be947d6082654abd6280" url: "https://pub.dev" source: hosted - version: "2.2.1" - platform: + version: "2.0.1" + path: dependency: transitive description: - name: platform - sha256: "12220bb4b65720483f8fa9450b4332347737cf8213dd2840d8b2c823e47243ec" + name: path + sha256: "087ce49c3f0dc39180befefc60fdb4acd8f8620e5682fe2476afd0b3688bb4af" url: "https://pub.dev" source: hosted - version: "3.1.4" + version: "1.9.0" plugin_platform_interface: dependency: transitive description: @@ -679,10 +463,10 @@ packages: dependency: transitive description: name: pointycastle - sha256: "7c1e5f0d23c9016c5bbd8b1473d0d3fb3fc851b876046039509e18e0c7485f2c" + sha256: "43ac87de6e10afabc85c445745a7b799e04de84cebaa4fd7bf55a5e1e9604d29" url: "https://pub.dev" source: hosted - version: "3.7.3" + version: "3.7.4" pool: dependency: transitive description: @@ -691,14 +475,6 @@ packages: url: "https://pub.dev" source: hosted version: "1.5.1" - precis: - dependency: transitive - description: - name: precis - sha256: "3473e97e1a01d0f92afcdd9991549727447559edd185764a24fc54d48181bd29" - url: "https://pub.dev" - source: hosted - version: "0.0.3" pub_semver: dependency: transitive description: @@ -715,14 +491,6 @@ packages: url: "https://pub.dev" source: hosted version: "1.2.3" - quiver: - dependency: transitive - description: - name: quiver - sha256: b1c1ac5ce6688d77f65f3375a9abb9319b3cb32486bdc7a1e0fdf004d7ba4e47 - url: "https://pub.dev" - source: hosted - version: "3.2.1" sec: dependency: transitive description: @@ -760,14 +528,6 @@ packages: url: "https://pub.dev" source: hosted version: "1.5.0" - source_helper: - dependency: transitive - description: - name: source_helper - sha256: "6adebc0006c37dd63fe05bca0a929b99f06402fc95aa35bf36d67f5c06de01fd" - url: "https://pub.dev" - source: hosted - version: "1.3.4" source_span: dependency: transitive description: @@ -784,22 +544,6 @@ packages: url: "https://pub.dev" source: hosted version: "7.0.0" - sqflite: - dependency: transitive - description: - name: sqflite - sha256: "591f1602816e9c31377d5f008c2d9ef7b8aca8941c3f89cc5fd9d84da0c38a9a" - url: "https://pub.dev" - source: hosted - version: "2.3.0" - sqflite_common: - dependency: transitive - description: - name: sqflite_common - sha256: bb4738f15b23352822f4c42a531677e5c6f522e079461fd240ead29d8d8a54a6 - url: "https://pub.dev" - source: hosted - version: "2.5.0+2" stack_trace: dependency: transitive description: @@ -832,22 +576,6 @@ packages: url: "https://pub.dev" source: hosted version: "1.2.0" - string_validator: - dependency: "direct main" - description: - name: string_validator - sha256: "54d4f42cd6878ae72793a58a529d9a18ebfdfbfebd9793bbe55c9b28935e8543" - url: "https://pub.dev" - source: hosted - version: "1.0.2" - synchronized: - dependency: transitive - description: - name: synchronized - sha256: "539ef412b170d65ecdafd780f924e5be3f60032a1128df156adad6c5b373d558" - url: "https://pub.dev" - source: hosted - version: "3.1.0+1" term_glyph: dependency: transitive description: @@ -880,22 +608,22 @@ packages: url: "https://pub.dev" source: hosted version: "1.3.2" - unorm_dart: + ua_client_hints: dependency: transitive description: - name: unorm_dart - sha256: "5b35bff83fce4d76467641438f9e867dc9bcfdb8c1694854f230579d68cd8f4b" + name: ua_client_hints + sha256: "8401d7bec261f61b3d3b61cd877653ddf840de2d9e07bd164f34588572aa0c8b" url: "https://pub.dev" source: hosted - version: "0.2.0" + version: "1.2.2" uuid: - dependency: "direct main" + dependency: transitive description: name: uuid - sha256: "22c94e5ad1e75f9934b766b53c742572ee2677c56bc871d850a57dad0f82127f" + sha256: cd210a09f7c18cbe5a02511718e0334de6559871052c90a90c0cca46a4aa81c8 url: "https://pub.dev" source: hosted - version: "4.2.2" + version: "4.3.3" vector_math: dependency: transitive description: @@ -924,18 +652,26 @@ packages: dependency: transitive description: name: web - sha256: dc8ccd225a2005c1be616fe02951e2e342092edf968cf0844220383757ef8f10 + sha256: afe077240a270dcfd2aafe77602b4113645af95d0ad31128cc02bce5ac5d5152 url: "https://pub.dev" source: hosted - version: "0.1.4-beta" + version: "0.3.0" + web3_signers: + dependency: "direct main" + description: + name: web3_signers + sha256: fd2a4ee394537f2140c08a395eadd8611aa713e04699c29b6aaba75e11264faf + url: "https://pub.dev" + source: hosted + version: "0.0.6" web3dart: dependency: "direct main" description: name: web3dart - sha256: "31f93cf84b8c874d7ffb363959249d7e479115fe12cf46f30b037dcad6750b22" + sha256: "885e5e8f0cc3c87c09f160a7fce6279226ca41316806f7ece2001959c62ecced" url: "https://pub.dev" source: hosted - version: "2.7.2" + version: "2.7.3" web3dart_builders: dependency: "direct dev" description: @@ -952,38 +688,6 @@ packages: url: "https://pub.dev" source: hosted version: "2.4.0" - webauthn: - dependency: "direct main" - description: - name: webauthn - sha256: b4a9a58c73cbf501a28e6cc78dd9b48542bfbfdc6dbcb7677ef06114bc0cf6da - url: "https://pub.dev" - source: hosted - version: "0.2.3" - webcrypto: - dependency: "direct main" - description: - name: webcrypto - sha256: a3cc45ce5efa053435505a958d32785f7497a684a859e6910d805ddf094f903f - url: "https://pub.dev" - source: hosted - version: "0.5.3" - win32: - dependency: transitive - description: - name: win32 - sha256: b0f37db61ba2f2e9b7a78a1caece0052564d1bc70668156cf3a29d676fe4e574 - url: "https://pub.dev" - source: hosted - version: "5.1.1" - xdg_directories: - dependency: transitive - description: - name: xdg_directories - sha256: faea9dee56b520b55a566385b84f2e8de55e7496104adada9962e0bd11bcff1d - url: "https://pub.dev" - source: hosted - version: "1.0.4" yaml: dependency: transitive description: @@ -993,5 +697,5 @@ packages: source: hosted version: "3.1.2" sdks: - dart: ">=3.1.0 <4.0.0" - flutter: ">=3.13.0" + dart: ">=3.2.6 <4.0.0" + flutter: ">=3.16.9" diff --git a/pubspec.yaml b/pubspec.yaml index 9d97ea7..e584970 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,6 +1,6 @@ name: variance_dart description: An Account Abstraction (4337) Development kit, for quickly building mobile web3 apps and smart wallets. -version: 0.0.4 +version: 0.1.0 documentation: https://docs.variance.space homepage: https://variance.space repository: https://github.com/vaariance/variance-dart @@ -18,32 +18,14 @@ platforms: dependencies: flutter: sdk: flutter - webauthn: ^0.2.1 web3dart: ^2.7.2 - webcrypto: ^0.5.3 - asn1lib: ^1.5.0 - uuid: ^4.1.0 - crypto: ^3.0.3 - cbor: ^6.1.1 http: ^1.1.0 - bip39: ^1.0.6 - bip32_bip44: ^1.0.0 - dio: ^5.3.2 - dio_cache_interceptor: ^3.4.3 - freezed_annotation: ^2.4.1 - json_annotation: ^4.8.1 - local_auth: ^2.1.7 - local_auth_ios: ^1.1.5 - local_auth_android: ^1.0.36 - flutter_secure_storage: ^9.0.0 - string_validator: ^1.0.2 + web3_signers: ^0.0.6 dev_dependencies: web3dart_builders: ^0.0.7 build_runner: ^2.4.6 flutter_lints: ^3.0.0 - freezed: ^2.4.5 - json_serializable: ^6.7.1 mockito: ^5.4.2 topics: