Skip to content

Commit 8c7ff08

Browse files
committed
add passkey supprot
1 parent 7021028 commit 8c7ff08

26 files changed

+347
-545
lines changed

CHANGELOG.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,14 @@
1+
## 0.1.4
2+
3+
* add surpport for web3_signers v0.1+
4+
* add create safe account with passkeys method in accounts factory
5+
* modify getSafeSignature to support hybrid signatures (private key + passkey)
6+
* update default singleton to safeL2
7+
* refactor safe inititializer
8+
* fix issue that causes create2salt to result in a different safe address
9+
* fetch the smart account balance from the entrypoint
10+
* fix issue where empty amounts array throws a light account ArrayLengthMismatch() error during batch transactions
11+
112
## 0.1.3
213

314
* replace Simple account with Alchemy light account

example/android/build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
buildscript {
2-
ext.kotlin_version = '1.7.10'
2+
ext.kotlin_version = '2.0.20'
33
repositories {
44
google()
55
mavenCentral()

example/devtools_options.yaml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
description: This file stores settings for Dart & Flutter DevTools.
2+
documentation: https://docs.flutter.dev/tools/devtools/extensions#configure-extension-enablement-states
3+
extensions:
Lines changed: 36 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,10 @@
1-
import 'dart:convert';
21
import 'dart:developer';
3-
import 'dart:io';
42
import 'dart:math' as math;
53
import 'package:flutter/foundation.dart';
64
import 'package:web3_signers/web3_signers.dart';
75
import 'package:variance_dart/variance_dart.dart';
86
import 'package:web3dart/credentials.dart';
97
import 'package:web3dart/web3dart.dart' as w3d;
10-
import 'package:web3dart/crypto.dart' as w3d;
118

129
class WalletProvider extends ChangeNotifier {
1310
final Chain _chain;
@@ -23,67 +20,56 @@ class WalletProvider extends ChangeNotifier {
2320
final EthereumAddress erc20 =
2421
EthereumAddress.fromHex("0xAEaF19097D8a8da728438D6B57edd9Bc5DAc4795");
2522
final EthereumAddress deployer =
26-
EthereumAddress.fromHex("0x218F6Bbc32Ef28F547A67c70AbCF8c2ea3b468BA");
23+
EthereumAddress.fromHex("0xf5bb7f874d8e3f41821175c0aa9910d30d10e193");
24+
25+
final salt = Uint256.zero;
26+
static const rpc =
27+
"https://api.pimlico.io/v2/84532/rpc?apikey=pim_NuuL4a9tBdyfoogF5LtP5A";
2728

2829
WalletProvider()
29-
: _chain = Chain(
30-
chainId: 31337,
31-
explorer: "https://sepolia.etherscan.io/",
32-
entrypoint: EntryPointAddress(
33-
0.6,
34-
EthereumAddress.fromHex(
35-
"0x5165c9e79213e2208947589c6e1dcc80ee8d3d00")))
36-
..accountFactory = EthereumAddress.fromHex(
37-
"0x0ce83Bf5d20c539E77e1E607B8349E26c6b20133") // v07 p256 factory address
38-
..jsonRpcUrl = "http://127.0.0.1:8545"
39-
..bundlerUrl = "http://localhost:3000/rpc";
40-
// ..paymasterUrl =
41-
// "https://api.pimlico.io/v2/11155111/rpc?apikey=875f3458-a37c-4187-8ac5-d08bbfa0d501";
42-
43-
// "0x402A266e92993EbF04a5B3fd6F0e2b21bFC83070" v06 p256 factory address
30+
: _chain = Chains.getChain(Network.baseTestnet)
31+
..accountFactory = Constants.lightAccountFactoryAddressv07
32+
..bundlerUrl = rpc
33+
..paymasterUrl = rpc;
34+
4435
Future<void> registerWithPassKey(String name,
4536
{bool? requiresUserVerification}) async {
46-
final pkpSigner =
47-
PassKeySigner("webauthn.io", "webauthn", "https://webauthn.io");
48-
final hwdSigner = HardwareSigner.withTag(name);
37+
_chain.accountFactory = Constants.safeProxyFactoryAddress;
4938

50-
final salt = Uint256.zero;
51-
Uint256.fromHex(
52-
hexlify(w3d.keccak256(Uint8List.fromList(utf8.encode(name)))));
39+
final options = PassKeysOptions(
40+
name: "variance",
41+
namespace: "variance.space",
42+
origin: "https://variance.space",
43+
userVerification: "required",
44+
requireResidentKey: true,
45+
sharedWebauthnSigner: EthereumAddress.fromHex(
46+
"0xfD90FAd33ee8b58f32c00aceEad1358e4AFC23f9"));
47+
final pkpSigner = PassKeySigner(options: options);
5348

5449
try {
55-
// uses passkeys on android, secure enclave on iOS
56-
if (Platform.isAndroid) {
57-
final SmartWalletFactory walletFactory =
58-
SmartWalletFactory(_chain, pkpSigner);
59-
final keypair = await pkpSigner.register(name, name);
60-
_wallet =
61-
await walletFactory.createP256Account<PassKeyPair>(keypair, salt);
62-
} else if (Platform.isIOS) {
63-
final SmartWalletFactory walletFactory =
64-
SmartWalletFactory(_chain, hwdSigner);
65-
final keypair = await hwdSigner.generateKeyPair();
66-
_wallet = await walletFactory.createP256Account<P256Credential>(
67-
keypair, salt);
68-
}
50+
final SmartWalletFactory walletFactory =
51+
SmartWalletFactory(_chain, pkpSigner);
52+
final keypair = await pkpSigner.register(
53+
"${DateTime.timestamp().millisecondsSinceEpoch}@variance.space",
54+
name);
55+
_wallet = await walletFactory.createSafeAccountWithPasskey(
56+
keypair, salt, options.sharedWebauthnSigner);
6957

7058
log("wallet created ${_wallet?.address.hex} ");
7159
} catch (e) {
7260
_errorMessage = e.toString();
7361
notifyListeners();
7462
log("something happened: $e");
63+
rethrow;
7564
}
7665
}
7766

7867
Future<void> createEOAWallet() async {
79-
_chain.accountFactory = Constants.lightAccountFactoryAddressv06;
80-
81-
final signer = EOAWallet.createWallet();
68+
final signer = EOAWallet.createWallet(
69+
WordLength.word_12, const SignatureOptions(prefix: [0]));
8270
log("signer: ${signer.getAddress()}");
8371

8472
final SmartWalletFactory walletFactory = SmartWalletFactory(_chain, signer);
85-
final salt = Uint256.fromHex(hexlify(w3d
86-
.keccak256(EthereumAddress.fromHex(signer.getAddress()).addressBytes)));
8773

8874
try {
8975
_wallet = await walletFactory.createAlchemyLightAccount(salt);
@@ -99,17 +85,13 @@ class WalletProvider extends ChangeNotifier {
9985
final random = math.Random.secure();
10086
final privateKey = EthPrivateKey.createRandom(random);
10187

102-
final signer = PrivateKeySigner.create(privateKey, "123456", random);
88+
final signer = PrivateKeySigner.create(privateKey, "123456", random,
89+
options: const SignatureOptions(prefix: [0]));
10390
log("signer: ${signer.getAddress()}");
10491
log("pk: ${hexlify(privateKey.privateKey)}");
10592

10693
final SmartWalletFactory walletFactory = SmartWalletFactory(_chain, signer);
10794

108-
final salt = Uint256.fromHex(hexlify(w3d
109-
.keccak256(EthereumAddress.fromHex(signer.getAddress()).addressBytes)));
110-
111-
log("pk salt: ${salt.toHex()}");
112-
11395
try {
11496
_wallet = await walletFactory.createAlchemyLightAccount(salt);
11597
log("pk wallet created ${_wallet?.address.hex} ");
@@ -128,11 +110,6 @@ class WalletProvider extends ChangeNotifier {
128110

129111
final SmartWalletFactory walletFactory = SmartWalletFactory(_chain, signer);
130112

131-
final salt = Uint256.fromHex(hexlify(w3d
132-
.keccak256(EthereumAddress.fromHex(signer.getAddress()).addressBytes)));
133-
134-
log("salt: ${salt.toHex()}");
135-
136113
try {
137114
_wallet = await walletFactory.createSafeAccount(salt);
138115
log("safe created ${_wallet?.address.hex} ");
@@ -180,30 +157,16 @@ class WalletProvider extends ChangeNotifier {
180157

181158
Future<void> sendTransaction(String recipient, String amount) async {
182159
if (_wallet != null) {
183-
final response = await transferToken(
184-
EthereumAddress.fromHex(recipient),
185-
w3d.EtherAmount.fromBigInt(
186-
w3d.EtherUnit.wei, BigInt.from(20 * math.pow(10, 6))));
187-
188-
// final etherAmount = w3d.EtherAmount.fromBigInt(w3d.EtherUnit.wei,
189-
// BigInt.from(double.parse(amount) * math.pow(10, 18)));
160+
final etherAmount = w3d.EtherAmount.fromBigInt(w3d.EtherUnit.wei,
161+
BigInt.from(double.parse(amount) * math.pow(10, 18)));
190162

191-
// final response =
192-
// await _wallet?.send(EthereumAddress.fromHex(recipient), etherAmount);
163+
final response =
164+
await _wallet?.send(EthereumAddress.fromHex(recipient), etherAmount);
193165
final receipt = await response?.wait();
194166

195167
log("Transaction receipt Hash: ${receipt?.userOpHash}");
196168
} else {
197169
log("No wallet available to send transaction");
198170
}
199171
}
200-
201-
Future<UserOperationResponse?> transferToken(
202-
EthereumAddress recipient, w3d.EtherAmount amount) async {
203-
final erc20 =
204-
EthereumAddress.fromHex("0xDc64a140Aa3E981100a9becA4E685f962f0cF6C9");
205-
206-
return await _wallet?.sendTransaction(
207-
erc20, Contract.encodeERC20TransferCall(erc20, recipient, amount));
208-
}
209172
}

example/lib/screens/create_account.dart

Lines changed: 42 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -134,8 +134,48 @@ class _CreateAccountScreenState extends State<CreateAccountScreen> {
134134
}
135135
},
136136
icon: const Icon(Icons.key),
137-
label: const Text('Create Safe Smart Account')),
138-
)
137+
label: const Text(
138+
'Create Alchemy Light Account with private key')),
139+
),
140+
18.verticalSpace,
141+
Container(
142+
margin: const EdgeInsets.only(left: 135),
143+
child: Text('OR', style: TextStyle(fontSize: 18.sp))),
144+
24.verticalSpace,
145+
Container(
146+
margin: const EdgeInsets.only(left: 30),
147+
child: TextButton.icon(
148+
onPressed: () {
149+
try {
150+
context.read<WalletProvider>().createEOAWallet();
151+
Navigator.pushNamed(context, '/home');
152+
} catch (e) {
153+
'Something went wrong: $e';
154+
}
155+
},
156+
icon: const Icon(Icons.key),
157+
label: const Text(
158+
'Create Alchemy Light Account with seed phrase')),
159+
),
160+
18.verticalSpace,
161+
Container(
162+
margin: const EdgeInsets.only(left: 135),
163+
child: Text('OR', style: TextStyle(fontSize: 18.sp))),
164+
24.verticalSpace,
165+
Container(
166+
margin: const EdgeInsets.only(left: 30),
167+
child: TextButton.icon(
168+
onPressed: () {
169+
try {
170+
context.read<WalletProvider>().createSafeWallet();
171+
Navigator.pushNamed(context, '/home');
172+
} catch (e) {
173+
'Something went wrong: $e';
174+
}
175+
},
176+
icon: const Icon(Icons.key),
177+
label: const Text('Create default Safe Account')),
178+
),
139179
],
140180
),
141181
);

example/lib/screens/home/home_screen.dart

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
import 'dart:developer';
2-
import 'package:flutter/cupertino.dart';
32
import 'package:flutter/material.dart';
43
import 'package:flutter/services.dart';
5-
import 'package:flutter/widgets.dart';
64
import 'package:flutter_screenutil/flutter_screenutil.dart';
75
import 'package:provider/provider.dart';
86
import 'package:variancedemo/providers/wallet_provider.dart';
@@ -167,9 +165,6 @@ class NFT extends StatelessWidget {
167165

168166
@override
169167
Widget build(BuildContext context) {
170-
final wallet = context.select(
171-
(WalletProvider provider) => provider.wallet,
172-
);
173168
return Column(
174169
crossAxisAlignment: CrossAxisAlignment.stretch,
175170
children: <Widget>[

example/pubspec.lock

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -300,18 +300,18 @@ packages:
300300
dependency: transitive
301301
description:
302302
name: leak_tracker
303-
sha256: "7f0df31977cb2c0b88585095d168e689669a2cc9b97c309665e3386f3e9d341a"
303+
sha256: "3f87a60e8c63aecc975dda1ceedbc8f24de75f09e4856ea27daf8958f2f0ce05"
304304
url: "https://pub.dev"
305305
source: hosted
306-
version: "10.0.4"
306+
version: "10.0.5"
307307
leak_tracker_flutter_testing:
308308
dependency: transitive
309309
description:
310310
name: leak_tracker_flutter_testing
311-
sha256: "06e98f569d004c1315b991ded39924b21af84cf14cc94791b8aea337d25b57f8"
311+
sha256: "932549fb305594d82d7183ecd9fa93463e9914e1b67cacc34bc40906594a1806"
312312
url: "https://pub.dev"
313313
source: hosted
314-
version: "3.0.3"
314+
version: "3.0.5"
315315
leak_tracker_testing:
316316
dependency: transitive
317317
description:
@@ -340,18 +340,18 @@ packages:
340340
dependency: transitive
341341
description:
342342
name: material_color_utilities
343-
sha256: "0e0a020085b65b6083975e499759762399b4475f766c21668c4ecca34ea74e5a"
343+
sha256: f7142bb1154231d7ea5f96bc7bde4bda2a0945d2806bb11670e30b850d56bdec
344344
url: "https://pub.dev"
345345
source: hosted
346-
version: "0.8.0"
346+
version: "0.11.1"
347347
meta:
348348
dependency: transitive
349349
description:
350350
name: meta
351-
sha256: "7687075e408b093f36e6bbf6c91878cc0d4cd10f409506f7bc996f68220b9136"
351+
sha256: bdb68674043280c3428e9ec998512fb681678676b3c54e773629ffe74419f8c7
352352
url: "https://pub.dev"
353353
source: hosted
354-
version: "1.12.0"
354+
version: "1.15.0"
355355
nested:
356356
dependency: transitive
357357
description:
@@ -641,10 +641,10 @@ packages:
641641
dependency: transitive
642642
description:
643643
name: test_api
644-
sha256: "9955ae474176f7ac8ee4e989dadfb411a58c30415bcfb648fa04b2b8a03afa7f"
644+
sha256: "5b8a98dafc4d5c4c9c72d8b31ab2b23fc13422348d2997120294d3bac86b4ddb"
645645
url: "https://pub.dev"
646646
source: hosted
647-
version: "0.7.0"
647+
version: "0.7.2"
648648
typed_data:
649649
dependency: transitive
650650
description:
@@ -683,7 +683,7 @@ packages:
683683
path: ".."
684684
relative: true
685685
source: path
686-
version: "0.1.3"
686+
version: "0.1.4"
687687
vector_math:
688688
dependency: transitive
689689
description:
@@ -696,10 +696,10 @@ packages:
696696
dependency: transitive
697697
description:
698698
name: vm_service
699-
sha256: "3923c89304b715fb1eb6423f017651664a03bf5f4b29983627c4da791f74a4ec"
699+
sha256: "5c5f338a667b4c644744b661f309fb8080bb94b18a7e91ef1dbd343bed00ed6d"
700700
url: "https://pub.dev"
701701
source: hosted
702-
version: "14.2.1"
702+
version: "14.2.5"
703703
wallet:
704704
dependency: transitive
705705
description:
@@ -720,10 +720,10 @@ packages:
720720
dependency: "direct main"
721721
description:
722722
name: web3_signers
723-
sha256: "455acf0207ef6edc5937a73edd57ce94f028b41856c07193be23e282d542d625"
723+
sha256: cb07808a4add7119f07c5c696db242a78df0c6c45a414ff8f1333b747b811b21
724724
url: "https://pub.dev"
725725
source: hosted
726-
version: "0.0.14-alpha-01"
726+
version: "0.1.6"
727727
web3dart:
728728
dependency: "direct main"
729729
description:
@@ -757,5 +757,5 @@ packages:
757757
source: hosted
758758
version: "3.1.2"
759759
sdks:
760-
dart: ">=3.4.0 <4.0.0"
761-
flutter: ">=3.22.0"
760+
dart: ">=3.5.0 <4.0.0"
761+
flutter: ">=3.24.3"

example/pubspec.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,13 @@ dependencies:
1717
google_fonts: 6.1.0
1818
flutter_screenutil: ^5.9.0
1919
qr_flutter: ^4.1.0
20-
web3dart: ^2.7.2
20+
web3dart: ^2.7.3
2121
shared_preferences: ^2.2.2
2222
path_provider: ^2.1.1
2323
fluttertoast: ^8.2.4
2424
variance_dart:
2525
path: ../
26-
web3_signers: ^0.0.14-alpha-01
26+
web3_signers: ^0.1.6
2727

2828
dev_dependencies:
2929
flutter_test:

0 commit comments

Comments
 (0)