Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactoring #17

Merged
merged 33 commits into from
Apr 8, 2024
Merged
Show file tree
Hide file tree
Changes from 31 commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
6c3c27e
fix: gas estimations and redundat calls
code-z2 Jan 16, 2024
d091a5c
sunset all goerli chains
code-z2 Feb 22, 2024
2e511bc
add global gas settings.
code-z2 Feb 22, 2024
5acac5f
remove address and initdata field in constructor
code-z2 Feb 22, 2024
f4fa0da
deprecate tbd issues
code-z2 Feb 22, 2024
ad157be
paymaster support
code-z2 Feb 24, 2024
6c8b22a
add support for entrypoint v0.7 in parallel
code-z2 Feb 27, 2024
1296689
feat: add web3 signers
code-z2 Mar 23, 2024
01c0005
feat: complete rewrite
code-z2 Mar 24, 2024
527b2a5
feat: segregate factories in factory
code-z2 Mar 25, 2024
5e5fdc6
returned the useroperationresponse.wait()
code-z2 Mar 25, 2024
3db203a
feat: add safe account creation
code-z2 Mar 26, 2024
a4f5f9d
feat: abi chunks
code-z2 Mar 26, 2024
e1f9dd6
v1.0.0: safe smart accounts
code-z2 Mar 29, 2024
63bc9b1
feat: redocument the sdk
code-z2 Mar 30, 2024
dc9573f
feat: merge example demo with sdk
code-z2 Mar 30, 2024
e562beb
feat: update example to be p256 compatible
code-z2 Mar 30, 2024
c657ea5
fix:late initialization field
maxiggle Mar 30, 2024
5ae4086
fix: ui fix
maxiggle Mar 30, 2024
a0af84e
fix: create account errors
code-z2 Mar 30, 2024
421c525
fix: broken copy button and address holder
maxiggle Mar 31, 2024
d4ddbaa
fix: predicted safe deployment data
code-z2 Mar 31, 2024
ea7351b
fixes
maxiggle Apr 1, 2024
c08d89f
ui: added mintnft button, fixed typography, recfator code
maxiggle Apr 2, 2024
5d9a1a4
feat: fix safe final sig encoding
code-z2 Apr 2, 2024
61fbab0
Merge branch 'refactoring' of https://github.com/vaariance/variance-d…
code-z2 Apr 2, 2024
686de74
feat: safe accounts working
code-z2 Apr 4, 2024
bb76e89
safe batch transactions
code-z2 Apr 5, 2024
d333e67
ui fix
maxiggle Apr 5, 2024
e2e3e11
feat: fully support v07 useroperations with pimlico
code-z2 Apr 7, 2024
fcf9051
bump SDK version
code-z2 Apr 7, 2024
dd64959
Merge branch 'main' into refactoring
code-z2 Apr 8, 2024
9513740
update readme
code-z2 Apr 8, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
63 changes: 63 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -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
Expand Down
180 changes: 85 additions & 95 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,166 +7,156 @@ 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.

- passkeys
- hd wallet
- simple credential (privatekey)
Additionally, you can specify a different Entrypoint address. By default, the entrypoin v0.6 is used.

> 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.
```dart
final EntryPointAddress entrypointAddress = EntryPointAddress.v07;
chain.entrypoint = entrypointAddress;
```

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("<user name>", 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>('paymaster').context = {'key': 'value'};
```

await pkp
.withSecureStorage(FlutterSecureStorage())
.saveCredential(CredentialType.passkeypair);
### Signers

// load a credential from the device
final ss = SecureStorageMiddleware(secureStorage: FlutterSecureStorage());
final hdInstance =
await HDWalletSigner.loadFromSecureStorage(storageMiddleware: ss);
print("pkp: ${hdInstance?.exportMnemonic()}");
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.

// NOTE: interactions with securestorage can be authenticated when using `SecureStorageMiddleware`
> You have to use the correct signer for the type of account you want to create.

final ss = SecureStorageMiddleware(secureStorage: FlutterSecureStorage(), authMiddleware: AuthenticationMiddleware());
// then used with `SecureStorageMiddleware` in the following way
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

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
### Smart Wallet Factory

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}");
```

#### To create a P256 Smart Account (Secure Enclave/Keystore)

// create a simple account based on hd
final SmartWallet simpleSmartAccount =
await walletClient.createSimpleAccount(salt);
print("simple account address: ${simpleSmartAccount.address}");
```dart
final Smartwallet wallet = await smartWalletFactory.createP256Account(keypair, salt);
print("p256 wallet address: ${wallet.address.hex}");
```

// create a simple account based on pkp
final SmartWallet simplePkpAccount =
await walletClient.createSimplePasskeyAccount(pkp, salt);
print("simple pkp account address: ${simplePkpAccount.address}");
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}");
```

Additionally, you can pass in multisig `owners` and the `threshold` to the `createSafeAccount` method.

```dart
final Smartwallet wallet = await smartWalletFactory
.createSafeAccount(salt, [...extraOwners], threshold);
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

Expand Down
43 changes: 43 additions & 0 deletions example/.gitignore
Original file line number Diff line number Diff line change
@@ -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
30 changes: 30 additions & 0 deletions example/.metadata
Original file line number Diff line number Diff line change
@@ -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'
Loading
Loading