@toruslabs/ethereum-controllers 8.17.1 → 9.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (76) hide show
  1. package/dist/lib.cjs/Account/AccountTrackerController.js +15 -7
  2. package/dist/lib.cjs/AccountAbstraction/AccountAbstractionController.js +22 -26
  3. package/dist/lib.cjs/Eip5792/walletGetCallsStatus.js +2 -2
  4. package/dist/lib.cjs/Eip5792/walletSendCalls.js +6 -7
  5. package/dist/lib.cjs/Eip7702/eip7702Utils.js +3 -3
  6. package/dist/lib.cjs/Gas/GasFeeController.js +2 -2
  7. package/dist/lib.cjs/Keyring/KeyringController.js +68 -41
  8. package/dist/lib.cjs/Message/utils.js +14 -16
  9. package/dist/lib.cjs/Network/NetworkController.js +7 -9
  10. package/dist/lib.cjs/Network/createEthereumMiddleware.js +373 -285
  11. package/dist/lib.cjs/Network/createJsonRpcClient.js +21 -21
  12. package/dist/lib.cjs/Nfts/NftHandler.js +54 -12
  13. package/dist/lib.cjs/Nfts/NftsController.js +1 -4
  14. package/dist/lib.cjs/Preferences/PreferencesController.js +2 -2
  15. package/dist/lib.cjs/Tokens/TokenHandler.js +39 -7
  16. package/dist/lib.cjs/Tokens/TokensController.js +15 -7
  17. package/dist/lib.cjs/Transaction/TransactionController.js +17 -20
  18. package/dist/lib.cjs/Transaction/TransactionGasUtil.js +11 -12
  19. package/dist/lib.cjs/Transaction/TransactionUtils.js +44 -39
  20. package/dist/lib.cjs/index.js +9 -0
  21. package/dist/lib.cjs/types/Account/AccountTrackerController.d.ts +1 -1
  22. package/dist/lib.cjs/types/AccountAbstraction/AccountAbstractionController.d.ts +4 -6
  23. package/dist/lib.cjs/types/Eip5792/walletSendCalls.d.ts +1 -1
  24. package/dist/lib.cjs/types/Eip7702/walletUpgradeAccount.d.ts +1 -1
  25. package/dist/lib.cjs/types/Keyring/KeyringController.d.ts +4 -4
  26. package/dist/lib.cjs/types/Network/NetworkController.d.ts +1 -1
  27. package/dist/lib.cjs/types/Network/createEthereumMiddleware.d.ts +28 -90
  28. package/dist/lib.cjs/types/Network/createJsonRpcClient.d.ts +4 -4
  29. package/dist/lib.cjs/types/Network/index.d.ts +5 -0
  30. package/dist/lib.cjs/types/Network/interfaces.d.ts +58 -0
  31. package/dist/lib.cjs/types/Nfts/NftHandler.d.ts +4 -3
  32. package/dist/lib.cjs/types/Nfts/NftsController.d.ts +0 -1
  33. package/dist/lib.cjs/types/Tokens/TokenHandler.d.ts +4 -3
  34. package/dist/lib.cjs/types/Tokens/TokensController.d.ts +1 -1
  35. package/dist/lib.cjs/types/Transaction/TransactionUtils.d.ts +11 -3
  36. package/dist/lib.cjs/types/index.d.ts +1 -3
  37. package/dist/lib.cjs/types/utils/abis.d.ts +544 -99
  38. package/dist/lib.cjs/types/utils/eip5792Types.d.ts +1 -1
  39. package/dist/lib.cjs/types/utils/eip7702Types.d.ts +1 -1
  40. package/dist/lib.cjs/types/utils/interfaces.d.ts +207 -4
  41. package/dist/lib.cjs/types/utils/transaction.d.ts +1 -1
  42. package/dist/lib.cjs/types/utils/viem.d.ts +8 -0
  43. package/dist/lib.cjs/utils/abis.js +12 -0
  44. package/dist/lib.cjs/utils/conversionUtils.js +3 -4
  45. package/dist/lib.cjs/utils/helpers.js +8 -7
  46. package/dist/lib.cjs/utils/transaction.js +7 -11
  47. package/dist/lib.cjs/utils/viem.js +214 -0
  48. package/dist/lib.esm/Account/AccountTrackerController.js +15 -7
  49. package/dist/lib.esm/AccountAbstraction/AccountAbstractionController.js +24 -28
  50. package/dist/lib.esm/Eip5792/walletGetCallsStatus.js +2 -2
  51. package/dist/lib.esm/Eip5792/walletSendCalls.js +6 -7
  52. package/dist/lib.esm/Eip7702/eip7702Utils.js +3 -3
  53. package/dist/lib.esm/Gas/GasFeeController.js +2 -2
  54. package/dist/lib.esm/Keyring/KeyringController.js +68 -42
  55. package/dist/lib.esm/Message/utils.js +14 -16
  56. package/dist/lib.esm/Network/NetworkController.js +8 -10
  57. package/dist/lib.esm/Network/createEthereumMiddleware.js +387 -290
  58. package/dist/lib.esm/Network/createJsonRpcClient.js +22 -22
  59. package/dist/lib.esm/Nfts/NftHandler.js +54 -12
  60. package/dist/lib.esm/Nfts/NftsController.js +1 -4
  61. package/dist/lib.esm/Preferences/PreferencesController.js +2 -2
  62. package/dist/lib.esm/Tokens/TokenHandler.js +39 -7
  63. package/dist/lib.esm/Tokens/TokensController.js +15 -7
  64. package/dist/lib.esm/Transaction/TransactionController.js +18 -21
  65. package/dist/lib.esm/Transaction/TransactionGasUtil.js +11 -12
  66. package/dist/lib.esm/Transaction/TransactionUtils.js +44 -40
  67. package/dist/lib.esm/index.js +4 -3
  68. package/dist/lib.esm/utils/abis.js +12 -0
  69. package/dist/lib.esm/utils/conversionUtils.js +3 -4
  70. package/dist/lib.esm/utils/helpers.js +8 -7
  71. package/dist/lib.esm/utils/interfaces.js +64 -0
  72. package/dist/lib.esm/utils/transaction.js +7 -11
  73. package/dist/lib.esm/utils/viem.js +214 -0
  74. package/package.json +14 -19
  75. package/dist/ethereumControllers.umd.min.js +0 -2
  76. package/dist/ethereumControllers.umd.min.js.LICENSE.txt +0 -50
@@ -2,8 +2,8 @@ import _objectSpread from '@babel/runtime/helpers/objectSpread2';
2
2
  import _defineProperty from '@babel/runtime/helpers/defineProperty';
3
3
  import { BaseController } from '@toruslabs/base-controllers';
4
4
  import { Mutex } from 'async-mutex';
5
- import { BrowserProvider, toQuantity, Contract } from 'ethers';
6
5
  import log from 'loglevel';
6
+ import { createPublicClient, custom, toHex } from 'viem';
7
7
  import { singleBalanceCheckerAbi } from '../utils/abis.js';
8
8
  import { SINGLE_CALL_BALANCES_ADDRESSES } from '../utils/contractAddresses.js';
9
9
 
@@ -32,7 +32,7 @@ class AccountTrackerController extends BaseController {
32
32
  _defineProperty(this, "provider", void 0);
33
33
  _defineProperty(this, "blockTracker", void 0);
34
34
  _defineProperty(this, "mutex", new Mutex());
35
- _defineProperty(this, "ethersProvider", void 0);
35
+ _defineProperty(this, "publicClient", void 0);
36
36
  _defineProperty(this, "getIdentities", void 0);
37
37
  _defineProperty(this, "getCurrentChainId", void 0);
38
38
  this.defaultState = {
@@ -41,7 +41,9 @@ class AccountTrackerController extends BaseController {
41
41
  this.initialize();
42
42
  this.provider = provider;
43
43
  this.blockTracker = blockTracker;
44
- this.ethersProvider = new BrowserProvider(this.provider, "any");
44
+ this.publicClient = createPublicClient({
45
+ transport: custom(this.provider)
46
+ });
45
47
  this.getIdentities = getIdentities;
46
48
  this.getCurrentChainId = getCurrentChainId;
47
49
  onPreferencesStateChange(() => {
@@ -127,21 +129,27 @@ class AccountTrackerController extends BaseController {
127
129
  } = this.state;
128
130
  if (!accounts[address]) return;
129
131
  accounts[address] = {
130
- balance: toQuantity(balance)
132
+ balance: toHex(BigInt(balance))
131
133
  };
132
134
  this.update({
133
135
  accounts
134
136
  });
135
137
  }
136
138
  async _updateAccountsViaBalanceChecker(addresses, deployedContractAddress) {
137
- const ethContract = new Contract(deployedContractAddress, singleBalanceCheckerAbi, this.ethersProvider);
138
139
  try {
139
- const result = await ethContract.balances(addresses, [ZERO_ADDRESS]);
140
+ const result = await this.publicClient.readContract({
141
+ address: deployedContractAddress,
142
+ abi: singleBalanceCheckerAbi,
143
+ functionName: "balances",
144
+ args: [addresses, [ZERO_ADDRESS]],
145
+ authorizationList: undefined // required when public client has no chain specified
146
+ });
140
147
  const {
141
148
  accounts
142
149
  } = this.state;
143
150
  addresses.forEach((address, index) => {
144
- const balance = toQuantity(result[index]);
151
+ var _result$index;
152
+ const balance = toHex((_result$index = result[index]) !== null && _result$index !== void 0 ? _result$index : 0n);
145
153
  if (!accounts[address]) return;
146
154
  accounts[address] = {
147
155
  balance
@@ -1,32 +1,28 @@
1
1
  import _objectSpread from '@babel/runtime/helpers/objectSpread2';
2
2
  import _defineProperty from '@babel/runtime/helpers/defineProperty';
3
- import { addHexPrefix } from '@ethereumjs/util';
4
3
  import { BaseController, TransactionStatus } from '@toruslabs/base-controllers';
5
- import { JRPCEngine, providerFromEngine } from '@web3auth/auth';
6
- import { isHexString } from 'ethers';
4
+ import { JRPCEngineV2, providerFromEngineV2 } from '@web3auth/auth';
7
5
  import log from 'loglevel';
8
- import { defineChain, createPublicClient, http, createWalletClient, custom, parseEther, toHex } from 'viem';
6
+ import { defineChain, createPublicClient, http, createWalletClient, custom, toHex, parseEther, isHex } from 'viem';
9
7
  import { createPaymasterClient, createBundlerClient } from 'viem/account-abstraction';
10
8
 
11
- const eoaInterceptorMiddleware = eoaAddress => (req, res, next, end) => {
12
- req.isAAProviderRequest = true;
13
- if (req.method === "eth_accounts" || req.method === "eth_requestAccounts") {
14
- res.result = [eoaAddress];
15
- end();
16
- return;
9
+ const eoaInterceptorMiddleware = eoaAddress => async ({
10
+ request,
11
+ next,
12
+ context
13
+ }) => {
14
+ context.set("isAAProviderRequest", true);
15
+ if (request.method === "eth_accounts" || request.method === "eth_requestAccounts") {
16
+ return [eoaAddress];
17
17
  }
18
- next();
18
+ return next();
19
19
  };
20
20
  function eoaProviderAsMiddleware(provider) {
21
- return async (req, res, _next, end) => {
22
- // send request to provider
23
- try {
24
- const providerRes = await provider.request(req);
25
- res.result = providerRes;
26
- return end();
27
- } catch (error) {
28
- return end(error);
29
- }
21
+ return async ({
22
+ request
23
+ }) => {
24
+ const result = await provider.request(request);
25
+ return result;
30
26
  };
31
27
  }
32
28
  class AccountAbstractionController extends BaseController {
@@ -93,10 +89,10 @@ class AccountAbstractionController extends BaseController {
93
89
  });
94
90
 
95
91
  // viem wallet client using json-rpc account from eoaProvider
96
- const aaEngine = new JRPCEngine();
97
- aaEngine.push(eoaInterceptorMiddleware(eoaAddress));
98
- aaEngine.push(eoaProviderAsMiddleware(eoaProvider));
99
- const provider = providerFromEngine(aaEngine);
92
+ const aaEngine = JRPCEngineV2.create({
93
+ middleware: [eoaInterceptorMiddleware(eoaAddress), eoaProviderAsMiddleware(eoaProvider)]
94
+ });
95
+ const provider = providerFromEngineV2(aaEngine);
100
96
  // need to hoist the account address https://viem.sh/docs/clients/wallet#optional-hoist-the-account
101
97
  const eoaWalletClient = createWalletClient({
102
98
  account: eoaAddress,
@@ -124,7 +120,7 @@ class AccountAbstractionController extends BaseController {
124
120
  });
125
121
  }
126
122
  async sendTransaction(id, tx, address) {
127
- var _txParams$chainId, _txReceipt$receipt, _txReceipt$nonce, _txReceipt$receipt2, _txReceipt$receipt3, _txReceipt$receipt4;
123
+ var _txParams$chainId, _txReceipt$receipt, _txReceipt$nonce, _txReceipt$receipt$ga, _txReceipt$receipt2, _txReceipt$receipt$ef, _txReceipt$receipt3, _txReceipt$receipt4;
128
124
  if (address.toLowerCase() !== this.smartAccount.address.toLowerCase()) {
129
125
  throw new Error("Invalid address");
130
126
  }
@@ -164,8 +160,8 @@ class AccountAbstractionController extends BaseController {
164
160
  receipt: {
165
161
  transactionHash: (_txReceipt$receipt = txReceipt.receipt) === null || _txReceipt$receipt === void 0 ? void 0 : _txReceipt$receipt.transactionHash,
166
162
  nonce: (_txReceipt$nonce = txReceipt.nonce) === null || _txReceipt$nonce === void 0 ? void 0 : _txReceipt$nonce.toString(),
167
- gasUsed: addHexPrefix((_txReceipt$receipt2 = txReceipt.receipt) === null || _txReceipt$receipt2 === void 0 || (_txReceipt$receipt2 = _txReceipt$receipt2.gasUsed) === null || _txReceipt$receipt2 === void 0 ? void 0 : _txReceipt$receipt2.toString(16)),
168
- effectiveGasPrice: addHexPrefix((_txReceipt$receipt3 = txReceipt.receipt) === null || _txReceipt$receipt3 === void 0 || (_txReceipt$receipt3 = _txReceipt$receipt3.effectiveGasPrice) === null || _txReceipt$receipt3 === void 0 ? void 0 : _txReceipt$receipt3.toString(16)),
163
+ gasUsed: toHex((_txReceipt$receipt$ga = (_txReceipt$receipt2 = txReceipt.receipt) === null || _txReceipt$receipt2 === void 0 ? void 0 : _txReceipt$receipt2.gasUsed) !== null && _txReceipt$receipt$ga !== void 0 ? _txReceipt$receipt$ga : 0n),
164
+ effectiveGasPrice: toHex((_txReceipt$receipt$ef = (_txReceipt$receipt3 = txReceipt.receipt) === null || _txReceipt$receipt3 === void 0 ? void 0 : _txReceipt$receipt3.effectiveGasPrice) !== null && _txReceipt$receipt$ef !== void 0 ? _txReceipt$receipt$ef : 0n),
169
165
  type: (_txReceipt$receipt4 = txReceipt.receipt) === null || _txReceipt$receipt4 === void 0 ? void 0 : _txReceipt$receipt4.type,
170
166
  reason: txReceipt.reason
171
167
  },
@@ -278,7 +274,7 @@ class AccountAbstractionController extends BaseController {
278
274
  throw new Error("Invalid address");
279
275
  }
280
276
  return (_this$smartAccount = this.smartAccount) === null || _this$smartAccount === void 0 ? void 0 : _this$smartAccount.signMessage({
281
- message: isHexString(message) ? {
277
+ message: isHex(message) ? {
282
278
  raw: message
283
279
  } : message
284
280
  });
@@ -1,5 +1,5 @@
1
- import { addHexPrefix } from '@ethereumjs/util';
2
1
  import { TransactionStatus } from '@toruslabs/base-controllers';
2
+ import { add0x } from '@toruslabs/metadata-helpers';
3
3
  import { rpcErrors, JsonRpcError } from '@web3auth/auth';
4
4
  import { GetCallsStatusCode, EIP_5792_METHODS, EIP5792ErrorCode } from '../utils/eip5792Types.js';
5
5
 
@@ -67,7 +67,7 @@ function walletGetCallsStatus(request, getTransactionByBatchId) {
67
67
  return {
68
68
  status: mapTransactionStatusToEip5792Status(batchTx.status),
69
69
  id: batchId,
70
- chainId: addHexPrefix(batchTx.chainId),
70
+ chainId: add0x(batchTx.chainId),
71
71
  atomic: true,
72
72
  receipts: batchTx.txReceipt ? [batchTx.txReceipt] : []
73
73
  };
@@ -1,7 +1,6 @@
1
- import { isValidAddress } from '@ethereumjs/util';
2
1
  import { rpcErrors } from '@web3auth/auth';
3
- import { isHexString } from 'ethers';
4
2
  import { v4, parse } from 'uuid';
3
+ import { isHex, isAddress } from 'viem';
5
4
  import { getIsEip7702UpgradeSupported } from '../Eip7702/eip7702Utils.js';
6
5
  import { EIP_5792_METHODS } from '../utils/eip5792Types.js';
7
6
 
@@ -23,20 +22,20 @@ function generateBatchId() {
23
22
  */
24
23
  function validateCall(call, index) {
25
24
  // Validate 'to' address
26
- if (!call.to || !isHexString(call.to) || !isValidAddress(call.to)) {
25
+ if (!call.to || !isHex(call.to) || !isAddress(call.to)) {
27
26
  throw rpcErrors.invalidParams(`Invalid 'to' address in call at index ${index}`);
28
27
  }
29
28
 
30
29
  // Validate 'value' if present
31
30
  if (call.value !== undefined) {
32
- if (!isHexString(call.value)) {
31
+ if (!isHex(call.value)) {
33
32
  throw rpcErrors.invalidParams(`Invalid 'value' in call at index ${index}: must be a valid non-negative hex string`);
34
33
  }
35
34
  }
36
35
 
37
36
  // Validate 'data' if present
38
37
  if (call.data !== undefined) {
39
- if (!isHexString(call.data)) {
38
+ if (!isHex(call.data)) {
40
39
  throw rpcErrors.invalidParams(`Invalid 'data' in call at index ${index}: must be a valid hex string`);
41
40
  }
42
41
  }
@@ -58,7 +57,7 @@ function validateSendCallsParams(sendCallsParams) {
58
57
  }
59
58
 
60
59
  // Validate chainId format
61
- if (!sendCallsParams.chainId || !isHexString(sendCallsParams.chainId)) {
60
+ if (!sendCallsParams.chainId || !isHex(sendCallsParams.chainId)) {
62
61
  throw rpcErrors.invalidParams("Invalid chainId: must be a valid hex string");
63
62
  }
64
63
 
@@ -66,7 +65,7 @@ function validateSendCallsParams(sendCallsParams) {
66
65
  if (!sendCallsParams.from) {
67
66
  throw rpcErrors.invalidParams("Missing 'from' address");
68
67
  }
69
- if (!isHexString(sendCallsParams.from) || !isValidAddress(sendCallsParams.from)) {
68
+ if (!isHex(sendCallsParams.from) || !isAddress(sendCallsParams.from)) {
70
69
  throw rpcErrors.invalidParams("Invalid 'from' address: must be a valid hex address");
71
70
  }
72
71
 
@@ -1,4 +1,4 @@
1
- import { addHexPrefix } from '@ethereumjs/util';
1
+ import { add0x } from '@toruslabs/metadata-helpers';
2
2
  import { zeroAddress, encodeAbiParameters, parseAbiParameters, encodeFunctionData } from 'viem';
3
3
  import { erc7821Abi } from '../utils/abis.js';
4
4
  import { SUPPORTED_NETWORKS } from '../utils/constants.js';
@@ -12,10 +12,10 @@ const MetaMask_EIP7702_Stateless_Delegator = "0x63c0c19a282a1B52b07dD5a65b58948A
12
12
  async function getDelegationAddress(walletAddress, chainId, getEthCode) {
13
13
  // query eth_getCode
14
14
  const code = await getEthCode(walletAddress, chainId);
15
- const normalizedCode = code ? addHexPrefix(code).toLowerCase() : "0x0";
15
+ const normalizedCode = code ? add0x(code).toLowerCase() : "0x0";
16
16
  const hasDelegation = normalizedCode.length === 48 && normalizedCode.startsWith(EIP_7702_PREFIX);
17
17
  if (hasDelegation) {
18
- const delegationAddress = addHexPrefix(normalizedCode.slice(EIP_7702_PREFIX.length));
18
+ const delegationAddress = add0x(normalizedCode.slice(EIP_7702_PREFIX.length));
19
19
  return delegationAddress;
20
20
  }
21
21
  return null;
@@ -1,6 +1,6 @@
1
1
  import _defineProperty from '@babel/runtime/helpers/defineProperty';
2
- import { isHexString, addHexPrefix } from '@ethereumjs/util';
3
2
  import { BaseController, PollingManager, cloneDeep } from '@toruslabs/base-controllers';
3
+ import { isHexString } from '@toruslabs/metadata-helpers';
4
4
  import log from 'loglevel';
5
5
  import { GAS_ESTIMATE_TYPES } from '../utils/constants.js';
6
6
  import { fetchGasEstimates, fetchEthGasPriceEstimate, fetchLegacyGasPriceEstimates, fetchGasEstimatesViaEthFeeHistory, calculateTimeEstimate } from './gasUtil.js';
@@ -119,7 +119,7 @@ class GasFeeController extends BaseController {
119
119
  const chainId = this.getNetworkIdentifier();
120
120
  if (chainId === "loading") return;
121
121
  let chainIdInt;
122
- if (typeof chainId === "string" && isHexString(addHexPrefix(chainId))) {
122
+ if (isHexString(chainId)) {
123
123
  chainIdInt = Number.parseInt(chainId, 16);
124
124
  }
125
125
  try {
@@ -1,8 +1,9 @@
1
- import { encode } from '@ethereumjs/rlp';
2
- import { addHexPrefix, bytesToHex, privateToPublic, toChecksumAddress, privateToAddress, stripHexPrefix, bigIntToBytes, isHexString } from '@ethereumjs/util';
1
+ import _objectSpread from '@babel/runtime/helpers/objectSpread2';
3
2
  import { BaseKeyringController, ecsignature, concatSig } from '@toruslabs/base-controllers';
4
- import { SigningKey, concat, keccak256, hashMessage, TypedDataEncoder } from 'ethers';
5
- import { toHex } from 'viem';
3
+ import { add0x, remove0x, hexToBytes } from '@toruslabs/metadata-helpers';
4
+ import { serializeTransaction, keccak256, parseSignature, toHex, isHex } from 'viem';
5
+ import { privateKeyToAccount } from 'viem/accounts';
6
+ import { prepareViemTx } from '../utils/viem.js';
6
7
 
7
8
  class KeyringController extends BaseKeyringController {
8
9
  constructor({
@@ -20,49 +21,55 @@ class KeyringController extends BaseKeyringController {
20
21
  }
21
22
  async signTransaction(tx, address) {
22
23
  const wallet = this._getWalletForAccount(address);
23
- const privKey = new SigningKey(addHexPrefix(wallet.privateKey));
24
+ const account = privateKeyToAccount(add0x(wallet.privateKey));
24
25
  const localTx = tx;
25
- localTx.signature = privKey.sign(localTx.unsignedHash);
26
- return localTx;
26
+ const txToSign = prepareViemTx(localTx);
27
+ // NOTE: don't use account.signTransaction directly because it only return signed serialized transaction
28
+ // we don't want to compute unsigned hash and signature again
29
+ const serializedUnsigned = serializeTransaction(txToSign);
30
+ const unsignedHash = keccak256(serializedUnsigned);
31
+ const rawSig = await account.sign({
32
+ hash: unsignedHash
33
+ });
34
+ const signature = parseSignature(rawSig);
35
+ const serialized = serializeTransaction(txToSign, signature);
36
+ return _objectSpread(_objectSpread({}, txToSign), {}, {
37
+ unsignedHash,
38
+ serialized,
39
+ signature
40
+ });
27
41
  }
28
42
  async signEip7702Authorization(authorization, address) {
29
43
  const wallet = this._getWalletForAccount(address);
30
- const privKey = new SigningKey(addHexPrefix(wallet.privateKey));
44
+ const account = privateKeyToAccount(add0x(wallet.privateKey));
31
45
 
32
46
  // Convert hex strings to proper types for RLP encoding
33
47
  // EIP-7702 authorization tuple: [chain_id_decimal, address, nonce_decimal]
34
48
  const chainIdDecimal = parseInt(authorization.chainId, 16);
35
49
  const nonceDecimal = parseInt(authorization.nonce, 16);
36
-
37
- // RLP encode the eip7702 authorization
38
- const encodedAuthorization = encode([chainIdDecimal, authorization.address, nonceDecimal]);
39
- // Prefixed with EIP7702 Domain Separator (0x05)
40
- const prefixedAuthorization = concat(["0x05", encodedAuthorization]);
41
- const authorizationHash = keccak256(prefixedAuthorization);
42
- const {
43
- r,
44
- s,
45
- v
46
- } = privKey.sign(authorizationHash);
47
- const signedAuthorization = {
50
+ const signedAuthorization = await account.signAuthorization({
51
+ contractAddress: authorization.address,
52
+ chainId: chainIdDecimal,
53
+ nonce: nonceDecimal
54
+ });
55
+ return {
48
56
  address: authorization.address,
49
57
  chainId: authorization.chainId,
50
58
  nonce: authorization.nonce,
51
- r: addHexPrefix(r),
52
- s: addHexPrefix(s),
53
- yParity: toHex(v - 27 === 0 ? 0 : 1)
59
+ r: signedAuthorization.r,
60
+ s: signedAuthorization.s,
61
+ yParity: toHex(signedAuthorization.yParity)
54
62
  };
55
- return signedAuthorization;
56
63
  }
57
64
  getAccounts() {
58
65
  return this.state.wallets.map(w => w.publicKey);
59
66
  }
60
- importAccount(accountPrivateKey) {
67
+ async importAccount(accountPrivateKey) {
61
68
  try {
62
- const hexPrivateKey = accountPrivateKey.padStart(64, "0");
63
- const bufferPrivKey = Buffer.from(hexPrivateKey, "hex");
64
- const publicKey = bytesToHex(privateToPublic(bufferPrivKey));
65
- const address = toChecksumAddress(bytesToHex(privateToAddress(bufferPrivKey)));
69
+ const hexPrivateKey = remove0x(accountPrivateKey).padStart(64, "0");
70
+ const account = privateKeyToAccount(add0x(hexPrivateKey));
71
+ const publicKey = account.publicKey;
72
+ const address = account.address;
66
73
  const existingWallet = this.state.wallets.find(w => w.address === address);
67
74
  if (existingWallet) return existingWallet.address;
68
75
  this.update({
@@ -90,37 +97,56 @@ class KeyringController extends BaseKeyringController {
90
97
  });
91
98
  }
92
99
  }
93
- getBufferPrivateKey(privateKey) {
94
- const stripped = stripHexPrefix(privateKey);
95
- return Buffer.from(stripped, "hex");
100
+ getPrivateKeyBytes(privateKey) {
101
+ return hexToBytes(privateKey);
96
102
  }
97
103
 
98
104
  // For eth_sign, we need to sign arbitrary data:
99
105
  async signMessage(data, address) {
106
+ if (typeof data !== "string") {
107
+ throw new Error("Torus Keyring - signMessage data must be type 'string'");
108
+ }
100
109
  const wallet = this._getWalletForAccount(address);
101
- const privKey = this.getBufferPrivateKey(wallet.privateKey);
102
- const messageSig = ecsignature(Buffer.from(stripHexPrefix(data), "hex"), privKey);
103
- const sig = concatSig(Buffer.from(bigIntToBytes(messageSig.v)), Buffer.from(messageSig.r), Buffer.from(messageSig.s));
110
+ const privKey = this.getPrivateKeyBytes(wallet.privateKey);
111
+ const payload = hexToBytes(data);
112
+ const messageSig = ecsignature(payload, privKey);
113
+ const sig = concatSig(messageSig.v, messageSig.r, messageSig.s);
104
114
  return sig;
105
115
  }
106
116
  async signPersonalMessage(data, address) {
107
117
  const wallet = this._getWalletForAccount(address);
108
- const privKey = new SigningKey(addHexPrefix(wallet.privateKey));
118
+ const account = privateKeyToAccount(add0x(wallet.privateKey));
109
119
  // we need to check if the data is hex or not
110
120
  // For historical reasons, you must submit the message to sign in hex-encoded UTF-8.
111
121
  // https://docs.metamask.io/wallet/how-to/sign-data/#use-personal_sign
112
- const message = isHexString(data) ? Buffer.from(stripHexPrefix(data), "hex") : Buffer.from(data);
113
- const signature = privKey.sign(hashMessage(message)).serialized;
114
- return signature;
122
+ const message = isHex(data) ? {
123
+ raw: data
124
+ } : data;
125
+ return account.signMessage({
126
+ message
127
+ });
115
128
  }
116
129
 
117
130
  // personal_signTypedData, signs data along with the schema
118
131
  async signTypedData(typedData, address) {
119
132
  const wallet = this._getWalletForAccount(address);
120
- const privKey = new SigningKey(addHexPrefix(wallet.privateKey));
133
+ const account = privateKeyToAccount(add0x(wallet.privateKey));
121
134
  delete typedData.types.EIP712Domain;
122
- const signature = privKey.sign(TypedDataEncoder.hash(typedData.domain, typedData.types, typedData.message)).serialized;
123
- return signature;
135
+ const primaryType = typedData.primaryType;
136
+ if (!primaryType) {
137
+ throw new Error("Torus Keyring - primaryType is required");
138
+ }
139
+ const rawSig = await account.signTypedData({
140
+ domain: _objectSpread(_objectSpread({}, typedData.domain), {}, {
141
+ chainId: typeof typedData.domain.chainId === "string" ? parseInt(typedData.domain.chainId, 16) : typedData.domain.chainId,
142
+ salt: typedData.domain.salt,
143
+ verifyingContract: typedData.domain.verifyingContract
144
+ }),
145
+ types: typedData.types,
146
+ primaryType,
147
+ message: typedData.message
148
+ });
149
+ return rawSig;
124
150
  }
125
151
  _getWalletForAccount(account) {
126
152
  const address = account.toLowerCase();
@@ -1,10 +1,9 @@
1
- import { stripHexPrefix, addHexPrefix, bytesToHex, isValidAddress } from '@ethereumjs/util';
2
1
  import { CHAIN_NAMESPACES } from '@toruslabs/base-controllers';
3
- import { isHexString, JsonRpcProvider, toQuantity } from 'ethers';
2
+ import { isHexString, add0x, bytesToHex, utf8ToBytes } from '@toruslabs/metadata-helpers';
3
+ import { isHex, createPublicClient, http, toHex, isAddress } from 'viem';
4
4
 
5
- const hexRe = /^[0-9A-Fa-f]+$/gu;
6
5
  function validateAddress(address, propertyName) {
7
- if (!address || typeof address !== "string" || !isValidAddress(address)) {
6
+ if (!address || typeof address !== "string" || !isAddress(address)) {
8
7
  throw new Error(`Invalid "${propertyName}" address: ${address} must be a valid string.`);
9
8
  }
10
9
  }
@@ -20,14 +19,13 @@ function validateSignMessageData(messageData) {
20
19
  }
21
20
  function normalizeMessageData(data) {
22
21
  try {
23
- const stripped = stripHexPrefix(data);
24
- if (stripped.match(hexRe)) {
25
- return addHexPrefix(stripped);
22
+ if (isHexString(data)) {
23
+ return add0x(data);
26
24
  }
27
25
  } catch {
28
26
  // do nothing
29
27
  }
30
- return bytesToHex(Buffer.from(data, "utf8"));
28
+ return add0x(bytesToHex(utf8ToBytes(data)));
31
29
  }
32
30
  async function validateTypedSignMessageDataV4(messageData, currentChainId) {
33
31
  validateAddress(messageData.from, "from");
@@ -72,7 +70,7 @@ async function validateAddChainData(data) {
72
70
  if (!chainId) {
73
71
  throw new Error("Invalid add chain params: please pass chainId in params");
74
72
  }
75
- if (!isHexString(chainId)) {
73
+ if (!isHex(chainId)) {
76
74
  throw new Error("Invalid add chain params: please pass a valid hex chainId in params, for: ex: 0x1");
77
75
  }
78
76
  if (!rpcUrls || rpcUrls.length === 0) throw new Error("params.rpcUrls not provided");
@@ -85,12 +83,12 @@ async function validateAddChainData(data) {
85
83
  if (!name) throw new Error("params.nativeCurrency.name not provided");
86
84
  if (!symbol) throw new Error("params.nativeCurrency.symbol not provided");
87
85
  if (decimals === undefined) throw new Error("params.nativeCurrency.decimals not provided");
88
- const _web3 = new JsonRpcProvider(rpcUrls[0], "any");
89
- const {
90
- chainId: networkChainID
91
- } = await _web3.getNetwork();
92
- if (Number.parseInt(networkChainID.toString()) !== Number.parseInt(chainId, 16)) {
93
- throw new Error(`Provided rpc url's chainId version is not matching with provided chainId, expected: ${toQuantity(networkChainID)}, received: ${chainId}`);
86
+ const client = createPublicClient({
87
+ transport: http(rpcUrls[0])
88
+ });
89
+ const networkChainID = await client.getChainId();
90
+ if (networkChainID !== Number.parseInt(chainId, 16)) {
91
+ throw new Error(`Provided rpc url's chainId version is not matching with provided chainId, expected: ${toHex(networkChainID)}, received: ${chainId}`);
94
92
  }
95
93
  }
96
94
  function validateSwitchChainData(data) {
@@ -100,7 +98,7 @@ function validateSwitchChainData(data) {
100
98
  if (!fullChainId) {
101
99
  throw new Error("Invalid switch chain params: please pass chainId in params");
102
100
  }
103
- if (!isHexString(fullChainId)) {
101
+ if (!isHex(fullChainId)) {
104
102
  const [namespace, chainId] = fullChainId.split(":");
105
103
  if (namespace !== CHAIN_NAMESPACES.SOLANA && namespace !== CHAIN_NAMESPACES.EIP155) {
106
104
  throw new Error("Invalid switch chain params: invalid namespace");
@@ -2,7 +2,7 @@ import _objectWithoutProperties from '@babel/runtime/helpers/objectWithoutProper
2
2
  import _objectSpread from '@babel/runtime/helpers/objectSpread2';
3
3
  import _defineProperty from '@babel/runtime/helpers/defineProperty';
4
4
  import { BaseController, createAnalyticsMiddleware, createSwappableProxy, createEventEmitterProxy } from '@toruslabs/base-controllers';
5
- import { JRPCEngine, providerFromEngine } from '@web3auth/auth';
5
+ import { JRPCEngineV2, providerFromEngineV2 } from '@web3auth/auth';
6
6
  import { Mutex } from 'async-mutex';
7
7
  import log from 'loglevel';
8
8
  import { SUPPORTED_NETWORKS, MAINNET_CHAIN_ID } from '../utils/constants.js';
@@ -151,15 +151,13 @@ class NetworkController extends BaseController {
151
151
  networkMiddleware,
152
152
  blockTracker
153
153
  }) {
154
- const ethereumMiddleware = createEthereumMiddleware(this.baseProviderHandlers, this.getProviderConfig(), this.analytics);
155
- const engine = new JRPCEngine();
156
- engine.push(createAnalyticsMiddleware({
157
- providerConfig: this.getProviderConfig(),
158
- analytics: this.analytics
159
- }));
160
- engine.push(ethereumMiddleware);
161
- engine.push(networkMiddleware);
162
- const provider = providerFromEngine(engine);
154
+ const engine = JRPCEngineV2.create({
155
+ middleware: [createAnalyticsMiddleware({
156
+ providerConfig: this.getProviderConfig(),
157
+ analytics: this.analytics
158
+ }), createEthereumMiddleware(this.baseProviderHandlers, this.getProviderConfig(), this.analytics), networkMiddleware]
159
+ });
160
+ const provider = providerFromEngineV2(engine);
163
161
  this.setProvider({
164
162
  provider,
165
163
  blockTracker