Skip to content

Commit

Permalink
feat: fix hd wallet signatures
Browse files Browse the repository at this point in the history
  • Loading branch information
code-z2 committed Jan 7, 2024
1 parent ded6a5c commit 5298702
Show file tree
Hide file tree
Showing 4 changed files with 52 additions and 30 deletions.
33 changes: 15 additions & 18 deletions lib/src/4337/wallet.dart
Original file line number Diff line number Diff line change
Expand Up @@ -139,10 +139,10 @@ class SmartWallet with _PluginManager implements SmartWalletBase {
@override
Future<SmartWallet> createSimpleAccount(Uint256 salt, {int? index}) async {
EthereumAddress signer = EthereumAddress.fromHex(
plugin<MultiSignerInterface>('signer').getAddress());
plugin<MultiSignerInterface>('signer').getAddress(index: index ?? 0));
_initCalldata = _getInitCallData('createAccount', [signer, salt.value]);
await getSimpleAccountAddress(signer, salt)
.then((value) => {_walletAddress = value});
.then((addr) => {_walletAddress = addr});
return this;
}

Expand Down Expand Up @@ -170,25 +170,17 @@ class SmartWallet with _PluginManager implements SmartWalletBase {
@override
Future<EthereumAddress> getSimpleAccountAddress(
EthereumAddress signer, Uint256 salt) {
try {
return plugin<_AccountFactory>('factory').getAddress(signer, salt.value);
} catch (e) {
throw SmartWalletError("Simple acount creation error: $e");
}
return plugin<_AccountFactory>('factory').getAddress(signer, salt.value);
}

@override
Future<EthereumAddress> getSimplePassKeyAccountAddress(
PassKeyPair pkp, Uint256 salt) {
try {
return plugin<_AccountFactory>('factory').getPasskeyAccountAddress(
pkp.credentialHexBytes,
pkp.publicKey[0].value,
pkp.publicKey[1].value,
salt.value);
} catch (e) {
throw SmartWalletError("Passkey acount creation error: $e");
}
return plugin<_AccountFactory>('factory').getPasskeyAccountAddress(
pkp.credentialHexBytes,
pkp.publicKey[0].value,
pkp.publicKey[1].value,
salt.value);
}

@override
Expand Down Expand Up @@ -244,9 +236,14 @@ class SmartWallet with _PluginManager implements SmartWalletBase {
final opHash = userOp.hash(_chain);

Uint8List signature = await plugin<MultiSignerInterface>('signer')
.personalSign(opHash,
.personalSign(
opHash,
index: index,
id: id ?? plugin<PasskeyInterface>('signer').defaultId);
id: id ??
(plugin('signer') is PasskeyInterface
? plugin('signer').defaultId
: id));

userOp.signature = hexlify(signature);

await _validateUserOperation(userOp);
Expand Down
7 changes: 6 additions & 1 deletion lib/src/common/uint256.dart
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,12 @@ class Uint256 implements Uint256Base {
}

@override
double toUnit(int decimals) {
BigInt toUnit(int decimals) {
return _value * BigInt.from(pow(10, decimals));
}

@override
double fromUnit(int decimals) {
return _value / BigInt.from(pow(10, decimals));
}

Expand Down
25 changes: 22 additions & 3 deletions lib/src/interfaces/uint256_interface.dart
Original file line number Diff line number Diff line change
Expand Up @@ -62,10 +62,29 @@ abstract class Uint256Base {
@override
String toString();

/// Converts this Uint256 to a [double] giving the [decimals].
/// The `toUnit` method is used to convert a Uint256 value from its base unit to a specific
/// unit. It takes an `int` parameter `decimals` which represents the number of decimal places
/// to consider. The method returns a `BigInt` representing the converted value.
/// example:
///
/// Returns an [double]
double toUnit(int decimals);
/// ```dart
/// Uint256(BigInt.from(1)).toUnit(18);
///
/// // 1 * 10^18 = 1000000000000000000
/// ```
BigInt toUnit(int decimals);

/// The `fromUnit` method is used to convert a Uint256 value from a specific unit to its base
/// unit. It takes an `int` parameter `decimals` which represents the number of decimal places
/// to consider. The method returns a `double` representing the converted value.
/// example:
///
/// ```dart
/// Uint256(BigInt.from(1000000000000000000)).fromUnit(18);
///
/// // 1000000000000000000 / 10^18 = 1.0
/// ```
double fromUnit(int decimals);

/// Converts this Uint256 to an [EtherAmount] in wei.
///
Expand Down
17 changes: 9 additions & 8 deletions lib/src/signers/hd_wallet_signer.dart
Original file line number Diff line number Diff line change
@@ -1,21 +1,23 @@
part of 'package:variance_dart/variance.dart';

class HDWalletSigner with SecureStorageMixin implements HDInterface {
String? _mnemonic;
final String _mnemonic;

final String _seed;

late final EthereumAddress zerothAddress;

HDWalletSigner({required String seed}) : _seed = seed {
HDWalletSigner._internal({required String seed, required String mnemonic})
: _seed = seed,
_mnemonic = mnemonic {
assert(seed.isNotEmpty, "seed cannot be empty");
}

/// Generates a new account in the HD wallet and stores it as zeroth.
///
/// Returns the HD signer instance.
factory HDWalletSigner.createWallet() {
final mnemonic = bip39.generateMnemonic();
return HDWalletSigner.recoverAccount(mnemonic);
return HDWalletSigner.recoverAccount(bip39.generateMnemonic());
}

/// Recovers an account from a mnemonic phrase and stores it in the HD wallet as zeroth.
Expand All @@ -25,7 +27,7 @@ class HDWalletSigner with SecureStorageMixin implements HDInterface {
/// Returns the HD signer instance.
factory HDWalletSigner.recoverAccount(String mnemonic) {
final seed = bip39.mnemonicToSeedHex(mnemonic);
final signer = HDWalletSigner(seed: seed);
final signer = HDWalletSigner._internal(seed: seed, mnemonic: mnemonic);
signer.zerothAddress = signer._add(seed, 0);
return signer;
}
Expand All @@ -52,7 +54,7 @@ class HDWalletSigner with SecureStorageMixin implements HDInterface {
}

@override
String? exportMnemonic() {
String exportMnemonic() {
return _getMnemonic();
}

Expand Down Expand Up @@ -115,8 +117,7 @@ class HDWalletSigner with SecureStorageMixin implements HDInterface {
return _deriveHdKey(_seed, index);
}

String? _getMnemonic() {
require(_mnemonic != null, "exportMnemonic: Not a Valid Wallet");
String _getMnemonic() {
return _mnemonic;
}

Expand Down

0 comments on commit 5298702

Please sign in to comment.