@metamask-previews/multichain-account-service 0.6.0-preview-55f2e41 → 0.6.0-preview-cab2ca5
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.
- package/CHANGELOG.md +7 -0
- package/dist/MultichainAccountGroup.cjs.map +1 -1
- package/dist/MultichainAccountGroup.d.cts +2 -2
- package/dist/MultichainAccountGroup.d.cts.map +1 -1
- package/dist/MultichainAccountGroup.d.mts +2 -2
- package/dist/MultichainAccountGroup.d.mts.map +1 -1
- package/dist/MultichainAccountGroup.mjs.map +1 -1
- package/dist/MultichainAccountService.cjs.map +1 -1
- package/dist/MultichainAccountService.d.cts +3 -2
- package/dist/MultichainAccountService.d.cts.map +1 -1
- package/dist/MultichainAccountService.d.mts +3 -2
- package/dist/MultichainAccountService.d.mts.map +1 -1
- package/dist/MultichainAccountService.mjs.map +1 -1
- package/dist/MultichainAccountWallet.cjs +66 -0
- package/dist/MultichainAccountWallet.cjs.map +1 -1
- package/dist/MultichainAccountWallet.d.cts +14 -2
- package/dist/MultichainAccountWallet.d.cts.map +1 -1
- package/dist/MultichainAccountWallet.d.mts +14 -2
- package/dist/MultichainAccountWallet.d.mts.map +1 -1
- package/dist/MultichainAccountWallet.mjs +66 -0
- package/dist/MultichainAccountWallet.mjs.map +1 -1
- package/dist/providers/AccountProviderWrapper.cjs +3 -0
- package/dist/providers/AccountProviderWrapper.cjs.map +1 -1
- package/dist/providers/AccountProviderWrapper.d.cts +1 -0
- package/dist/providers/AccountProviderWrapper.d.cts.map +1 -1
- package/dist/providers/AccountProviderWrapper.d.mts +1 -0
- package/dist/providers/AccountProviderWrapper.d.mts.map +1 -1
- package/dist/providers/AccountProviderWrapper.mjs +3 -0
- package/dist/providers/AccountProviderWrapper.mjs.map +1 -1
- package/dist/providers/BaseBip44AccountProvider.cjs.map +1 -1
- package/dist/providers/BaseBip44AccountProvider.d.cts +5 -1
- package/dist/providers/BaseBip44AccountProvider.d.cts.map +1 -1
- package/dist/providers/BaseBip44AccountProvider.d.mts +5 -1
- package/dist/providers/BaseBip44AccountProvider.d.mts.map +1 -1
- package/dist/providers/BaseBip44AccountProvider.mjs.map +1 -1
- package/dist/providers/EvmAccountProvider.cjs +87 -15
- package/dist/providers/EvmAccountProvider.cjs.map +1 -1
- package/dist/providers/EvmAccountProvider.d.cts +21 -52
- package/dist/providers/EvmAccountProvider.d.cts.map +1 -1
- package/dist/providers/EvmAccountProvider.d.mts +21 -52
- package/dist/providers/EvmAccountProvider.d.mts.map +1 -1
- package/dist/providers/EvmAccountProvider.mjs +88 -16
- package/dist/providers/EvmAccountProvider.mjs.map +1 -1
- package/dist/providers/SolAccountProvider.cjs +62 -21
- package/dist/providers/SolAccountProvider.cjs.map +1 -1
- package/dist/providers/SolAccountProvider.d.cts +3 -1
- package/dist/providers/SolAccountProvider.d.cts.map +1 -1
- package/dist/providers/SolAccountProvider.d.mts +3 -1
- package/dist/providers/SolAccountProvider.d.mts.map +1 -1
- package/dist/providers/SolAccountProvider.mjs +61 -20
- package/dist/providers/SolAccountProvider.mjs.map +1 -1
- package/dist/tests/accounts.cjs +11 -6
- package/dist/tests/accounts.cjs.map +1 -1
- package/dist/tests/accounts.d.cts +4 -1
- package/dist/tests/accounts.d.cts.map +1 -1
- package/dist/tests/accounts.d.mts +4 -1
- package/dist/tests/accounts.d.mts.map +1 -1
- package/dist/tests/accounts.mjs +6 -1
- package/dist/tests/accounts.mjs.map +1 -1
- package/dist/tests/messenger.cjs +2 -0
- package/dist/tests/messenger.cjs.map +1 -1
- package/dist/tests/messenger.d.cts.map +1 -1
- package/dist/tests/messenger.d.mts.map +1 -1
- package/dist/tests/messenger.mjs +2 -0
- package/dist/tests/messenger.mjs.map +1 -1
- package/dist/tests/providers.cjs +1 -0
- package/dist/tests/providers.cjs.map +1 -1
- package/dist/tests/providers.d.cts +1 -0
- package/dist/tests/providers.d.cts.map +1 -1
- package/dist/tests/providers.d.mts +1 -0
- package/dist/tests/providers.d.mts.map +1 -1
- package/dist/tests/providers.mjs +1 -0
- package/dist/tests/providers.mjs.map +1 -1
- package/dist/types.cjs.map +1 -1
- package/dist/types.d.cts +2 -1
- package/dist/types.d.cts.map +1 -1
- package/dist/types.d.mts +2 -1
- package/dist/types.d.mts.map +1 -1
- package/dist/types.mjs.map +1 -1
- package/package.json +3 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BaseBip44AccountProvider.mjs","sourceRoot":"","sources":["../../src/providers/BaseBip44AccountProvider.ts"],"names":[],"mappings":";;;;;;AAAA,OAAO,EACL,cAAc,EAGf,8BAA8B;AAS/B;;;;;GAKG;AACH,MAAM,UAAU,oBAAoB,CAClC,OAAuB;IAEvB,IAAI,CAAC,cAAc,CAAC,OAAO,CAAC,EAAE;QAC5B,MAAM,IAAI,KAAK,CAAC,0CAA0C,CAAC,CAAC;KAC7D;AACH,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,sBAAsB,CACpC,QAA0B;IAE1B,QAAQ,CAAC,OAAO,CAAC,oBAAoB,CAAC,CAAC;AACzC,CAAC;
|
|
1
|
+
{"version":3,"file":"BaseBip44AccountProvider.mjs","sourceRoot":"","sources":["../../src/providers/BaseBip44AccountProvider.ts"],"names":[],"mappings":";;;;;;AAAA,OAAO,EACL,cAAc,EAGf,8BAA8B;AAS/B;;;;;GAKG;AACH,MAAM,UAAU,oBAAoB,CAClC,OAAuB;IAEvB,IAAI,CAAC,cAAc,CAAC,OAAO,CAAC,EAAE;QAC5B,MAAM,IAAI,KAAK,CAAC,0CAA0C,CAAC,CAAC;KAC7D;AACH,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,sBAAsB,CACpC,QAA0B;IAE1B,QAAQ,CAAC,OAAO,CAAC,oBAAoB,CAAC,CAAC;AACzC,CAAC;AAQD,MAAM,OAAgB,wBAAwB;IAG5C,YAAY,SAA4C;;QACtD,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;IAC7B,CAAC;IA2BD,WAAW;QACT,OAAO,uBAAA,IAAI,kFAAa,MAAjB,IAAI,CAAe,CAAC;IAC7B,CAAC;IAED,UAAU,CACR,EAAsC;QAEtC,wDAAwD;QACxD,MAAM,CAAC,KAAK,CAAC,GAAG,uBAAA,IAAI,kFAAa,MAAjB,IAAI,EAAc,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC;QAElE,IAAI,CAAC,KAAK,EAAE;YACV,MAAM,IAAI,KAAK,CAAC,2BAA2B,EAAE,EAAE,CAAC,CAAC;SAClD;QAED,OAAO,KAAK,CAAC;IACf,CAAC;IAES,KAAK,CAAC,WAAW,CACzB,QAAyB,EACzB,SAM6B;QAE7B,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,IAAI,CACtC,+BAA+B,EAC/B,QAAQ,EACR,CAAC,EAAE,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,CACxB,SAAS,CAAC;YACR,OAAO,EAAE,OAA0B;YACnC,QAAQ;SACT,CAAC,CACL,CAAC;QAEF,OAAO,MAAwB,CAAC;IAClC,CAAC;CAmBF;4IA/EG,SAA+C,GAAG,EAAE,CAAC,IAAI;IAEzD,MAAM,QAAQ,GAAmC,EAAE,CAAC;IAEpD,KAAK,MAAM,OAAO,IAAI,IAAI,CAAC,SAAS,CAAC,IAAI;IACvC,2EAA2E;IAC3E,yEAAyE;IACzE,kDAAkD;IAClD,2CAA2C,CAC5C,EAAE;QACD,IACE,cAAc,CAAC,OAAO,CAAC;YACvB,IAAI,CAAC,mBAAmB,CAAC,OAAO,CAAC;YACjC,MAAM,CAAC,OAAO,CAAC,EACf;YACA,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;SACxB;KACF;IAED,OAAO,QAAQ,CAAC;AAClB,CAAC","sourcesContent":["import {\n isBip44Account,\n type AccountProvider,\n type Bip44Account,\n} from '@metamask/account-api';\nimport type { EntropySourceId, KeyringAccount } from '@metamask/keyring-api';\nimport type {\n KeyringMetadata,\n KeyringSelector,\n} from '@metamask/keyring-controller';\n\nimport type { MultichainAccountServiceMessenger } from '../types';\n\n/**\n * Asserts a keyring account is BIP-44 compatible.\n *\n * @param account - Keyring account to check.\n * @throws If the keyring account is not compatible.\n */\nexport function assertIsBip44Account(\n account: KeyringAccount,\n): asserts account is Bip44Account<KeyringAccount> {\n if (!isBip44Account(account)) {\n throw new Error('Created account is not BIP-44 compatible');\n }\n}\n\n/**\n * Asserts that a list of keyring accounts are all BIP-44 compatible.\n *\n * @param accounts - Keyring accounts to check.\n * @throws If any of the keyring account is not compatible.\n */\nexport function assertAreBip44Accounts(\n accounts: KeyringAccount[],\n): asserts accounts is Bip44Account<KeyringAccount>[] {\n accounts.forEach(assertIsBip44Account);\n}\n\nexport type NamedAccountProvider<\n Account extends Bip44Account<KeyringAccount> = Bip44Account<KeyringAccount>,\n> = AccountProvider<Account> & {\n getName(): string;\n};\n\nexport abstract class BaseBip44AccountProvider implements NamedAccountProvider {\n protected readonly messenger: MultichainAccountServiceMessenger;\n\n constructor(messenger: MultichainAccountServiceMessenger) {\n this.messenger = messenger;\n }\n\n abstract getName(): string;\n\n #getAccounts(\n filter: (account: KeyringAccount) => boolean = () => true,\n ): Bip44Account<KeyringAccount>[] {\n const accounts: Bip44Account<KeyringAccount>[] = [];\n\n for (const account of this.messenger.call(\n // NOTE: Even though the name is misleading, this only fetches all internal\n // accounts, including EVM and non-EVM. We might wanna change this action\n // name once we fully support multichain accounts.\n 'AccountsController:listMultichainAccounts',\n )) {\n if (\n isBip44Account(account) &&\n this.isAccountCompatible(account) &&\n filter(account)\n ) {\n accounts.push(account);\n }\n }\n\n return accounts;\n }\n\n getAccounts(): Bip44Account<KeyringAccount>[] {\n return this.#getAccounts();\n }\n\n getAccount(\n id: Bip44Account<KeyringAccount>['id'],\n ): Bip44Account<KeyringAccount> {\n // TODO: Maybe just use a proper find for faster lookup?\n const [found] = this.#getAccounts((account) => account.id === id);\n\n if (!found) {\n throw new Error(`Unable to find account: ${id}`);\n }\n\n return found;\n }\n\n protected async withKeyring<SelectedKeyring, CallbackResult = void>(\n selector: KeyringSelector,\n operation: ({\n keyring,\n metadata,\n }: {\n keyring: SelectedKeyring;\n metadata: KeyringMetadata;\n }) => Promise<CallbackResult>,\n ): Promise<CallbackResult> {\n const result = await this.messenger.call(\n 'KeyringController:withKeyring',\n selector,\n ({ keyring, metadata }) =>\n operation({\n keyring: keyring as SelectedKeyring,\n metadata,\n }),\n );\n\n return result as CallbackResult;\n }\n\n abstract isAccountCompatible(account: Bip44Account<KeyringAccount>): boolean;\n\n abstract createAccounts({\n entropySource,\n groupIndex,\n }: {\n entropySource: EntropySourceId;\n groupIndex: number;\n }): Promise<Bip44Account<KeyringAccount>[]>;\n\n abstract discoverAndCreateAccounts({\n entropySource,\n groupIndex,\n }: {\n entropySource: EntropySourceId;\n groupIndex: number;\n }): Promise<Bip44Account<KeyringAccount>[]>;\n}\n"]}
|
|
@@ -1,9 +1,16 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
|
|
3
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
|
|
4
|
+
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
|
|
5
|
+
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
6
|
+
};
|
|
7
|
+
var _EvmAccountProvider_instances, _EvmAccountProvider_createAccount;
|
|
2
8
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
9
|
exports.EvmAccountProvider = void 0;
|
|
4
10
|
const keyring_api_1 = require("@metamask/keyring-api");
|
|
5
11
|
const keyring_controller_1 = require("@metamask/keyring-controller");
|
|
6
12
|
const BaseBip44AccountProvider_1 = require("./BaseBip44AccountProvider.cjs");
|
|
13
|
+
const ETH_MAINNET_CHAIN_ID = '0x1';
|
|
7
14
|
/**
|
|
8
15
|
* Asserts an internal account exists.
|
|
9
16
|
*
|
|
@@ -16,24 +23,32 @@ function assertInternalAccountExists(account) {
|
|
|
16
23
|
}
|
|
17
24
|
}
|
|
18
25
|
class EvmAccountProvider extends BaseBip44AccountProvider_1.BaseBip44AccountProvider {
|
|
26
|
+
constructor() {
|
|
27
|
+
super(...arguments);
|
|
28
|
+
_EvmAccountProvider_instances.add(this);
|
|
29
|
+
}
|
|
19
30
|
isAccountCompatible(account) {
|
|
20
31
|
return (account.type === keyring_api_1.EthAccountType.Eoa &&
|
|
21
32
|
account.metadata.keyring.type === keyring_controller_1.KeyringTypes.hd);
|
|
22
33
|
}
|
|
34
|
+
getName() {
|
|
35
|
+
return 'EVM';
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Get the EVM provider.
|
|
39
|
+
*
|
|
40
|
+
* @returns The EVM provider.
|
|
41
|
+
*/
|
|
42
|
+
getEvmProvider() {
|
|
43
|
+
const networkClientId = this.messenger.call('NetworkController:findNetworkClientIdByChainId', ETH_MAINNET_CHAIN_ID);
|
|
44
|
+
const { provider } = this.messenger.call('NetworkController:getNetworkClientById', networkClientId);
|
|
45
|
+
return provider;
|
|
46
|
+
}
|
|
23
47
|
async createAccounts({ entropySource, groupIndex, }) {
|
|
24
|
-
const [address] = await this
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
return [accounts[groupIndex]];
|
|
29
|
-
}
|
|
30
|
-
// For now, we don't allow for gap, so if we need to create a new
|
|
31
|
-
// account, this has to be the next one.
|
|
32
|
-
if (groupIndex !== accounts.length) {
|
|
33
|
-
throw new Error('Trying to create too many accounts');
|
|
34
|
-
}
|
|
35
|
-
// Create next account (and returns their addresses).
|
|
36
|
-
return await keyring.addAccounts(1);
|
|
48
|
+
const [address] = await __classPrivateFieldGet(this, _EvmAccountProvider_instances, "m", _EvmAccountProvider_createAccount).call(this, {
|
|
49
|
+
entropySource,
|
|
50
|
+
groupIndex,
|
|
51
|
+
throwOnGap: true,
|
|
37
52
|
});
|
|
38
53
|
const account = this.messenger.call('AccountsController:getAccountByAddress', address);
|
|
39
54
|
// We MUST have the associated internal account.
|
|
@@ -42,9 +57,66 @@ class EvmAccountProvider extends BaseBip44AccountProvider_1.BaseBip44AccountProv
|
|
|
42
57
|
(0, BaseBip44AccountProvider_1.assertAreBip44Accounts)(accountsArray);
|
|
43
58
|
return accountsArray;
|
|
44
59
|
}
|
|
45
|
-
|
|
46
|
-
|
|
60
|
+
/**
|
|
61
|
+
* Discover and create accounts for the EVM provider.
|
|
62
|
+
*
|
|
63
|
+
* @param opts - The options for the discovery and creation of accounts.
|
|
64
|
+
* @param opts.entropySource - The entropy source to use for the discovery and creation of accounts.
|
|
65
|
+
* @param opts.groupIndex - The index of the group to create the accounts for.
|
|
66
|
+
* @returns The accounts for the EVM provider.
|
|
67
|
+
*/
|
|
68
|
+
async discoverAndCreateAccounts(opts) {
|
|
69
|
+
const provider = this.getEvmProvider();
|
|
70
|
+
const { entropySource, groupIndex } = opts;
|
|
71
|
+
const [address, didCreate] = await __classPrivateFieldGet(this, _EvmAccountProvider_instances, "m", _EvmAccountProvider_createAccount).call(this, {
|
|
72
|
+
entropySource,
|
|
73
|
+
groupIndex,
|
|
74
|
+
});
|
|
75
|
+
// We don't want to remove the account if it's the first one.
|
|
76
|
+
const shouldCleanup = didCreate && groupIndex !== 0;
|
|
77
|
+
try {
|
|
78
|
+
const countHex = (await provider.request({
|
|
79
|
+
method: 'eth_getTransactionCount',
|
|
80
|
+
params: [address, 'latest'],
|
|
81
|
+
}));
|
|
82
|
+
const count = parseInt(countHex, 16);
|
|
83
|
+
if (count === 0 && shouldCleanup) {
|
|
84
|
+
await this.withKeyring({ id: entropySource }, async ({ keyring }) => {
|
|
85
|
+
keyring.removeAccount?.(address);
|
|
86
|
+
});
|
|
87
|
+
return [];
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
catch (error) {
|
|
91
|
+
// If the RPC request fails and we just created this account for discovery,
|
|
92
|
+
// remove it to avoid leaving a dangling account.
|
|
93
|
+
if (shouldCleanup) {
|
|
94
|
+
await this.withKeyring({ id: entropySource }, async ({ keyring }) => {
|
|
95
|
+
keyring.removeAccount?.(address);
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
throw error;
|
|
99
|
+
}
|
|
100
|
+
const account = this.messenger.call('AccountsController:getAccountByAddress', address);
|
|
101
|
+
assertInternalAccountExists(account);
|
|
102
|
+
(0, BaseBip44AccountProvider_1.assertIsBip44Account)(account);
|
|
103
|
+
return [account];
|
|
47
104
|
}
|
|
48
105
|
}
|
|
49
106
|
exports.EvmAccountProvider = EvmAccountProvider;
|
|
107
|
+
_EvmAccountProvider_instances = new WeakSet(), _EvmAccountProvider_createAccount = async function _EvmAccountProvider_createAccount({ entropySource, groupIndex, throwOnGap = false, }) {
|
|
108
|
+
const result = await this.withKeyring({ id: entropySource }, async ({ keyring }) => {
|
|
109
|
+
const existing = await keyring.getAccounts();
|
|
110
|
+
if (groupIndex < existing.length) {
|
|
111
|
+
return [existing[groupIndex], false];
|
|
112
|
+
}
|
|
113
|
+
// If the throwOnGap flag is set, we throw an error to prevent index gaps.
|
|
114
|
+
if (throwOnGap && groupIndex !== existing.length) {
|
|
115
|
+
throw new Error('Trying to create too many accounts');
|
|
116
|
+
}
|
|
117
|
+
const [added] = await keyring.addAccounts(1);
|
|
118
|
+
return [added, true];
|
|
119
|
+
});
|
|
120
|
+
return result;
|
|
121
|
+
};
|
|
50
122
|
//# sourceMappingURL=EvmAccountProvider.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"EvmAccountProvider.cjs","sourceRoot":"","sources":["../../src/providers/EvmAccountProvider.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"EvmAccountProvider.cjs","sourceRoot":"","sources":["../../src/providers/EvmAccountProvider.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Bip44Account } from '@metamask/account-api';\nimport type { EntropySourceId, KeyringAccount } from '@metamask/keyring-api';\nimport { EthAccountType } from '@metamask/keyring-api';\nimport { KeyringTypes } from '@metamask/keyring-controller';\nimport type {\n EthKeyring,\n InternalAccount,\n} from '@metamask/keyring-internal-api';\nimport type { Provider } from '@metamask/network-controller';\nimport type { Hex } from '@metamask/utils';\n\nimport {\n assertAreBip44Accounts,\n assertIsBip44Account,\n BaseBip44AccountProvider,\n} from './BaseBip44AccountProvider';\n\nconst ETH_MAINNET_CHAIN_ID = '0x1';\n\n/**\n * Asserts an internal account exists.\n *\n * @param account - The internal account to check.\n * @throws An error if the internal account does not exist.\n */\nfunction assertInternalAccountExists(\n account: InternalAccount | undefined,\n): asserts account is InternalAccount {\n if (!account) {\n throw new Error('Internal account does not exist');\n }\n}\n\nexport class EvmAccountProvider extends BaseBip44AccountProvider {\n isAccountCompatible(account: Bip44Account<InternalAccount>): boolean {\n return (\n account.type === EthAccountType.Eoa &&\n account.metadata.keyring.type === (KeyringTypes.hd as string)\n );\n }\n\n getName(): string {\n return 'EVM';\n }\n\n /**\n * Get the EVM provider.\n *\n * @returns The EVM provider.\n */\n getEvmProvider(): Provider {\n const networkClientId = this.messenger.call(\n 'NetworkController:findNetworkClientIdByChainId',\n ETH_MAINNET_CHAIN_ID,\n );\n const { provider } = this.messenger.call(\n 'NetworkController:getNetworkClientById',\n networkClientId,\n );\n return provider;\n }\n\n async #createAccount({\n entropySource,\n groupIndex,\n throwOnGap = false,\n }: {\n entropySource: EntropySourceId;\n groupIndex: number;\n throwOnGap?: boolean;\n }): Promise<[Hex, boolean]> {\n const result = await this.withKeyring<EthKeyring, [Hex, boolean]>(\n { id: entropySource },\n async ({ keyring }) => {\n const existing = await keyring.getAccounts();\n if (groupIndex < existing.length) {\n return [existing[groupIndex], false];\n }\n\n // If the throwOnGap flag is set, we throw an error to prevent index gaps.\n if (throwOnGap && groupIndex !== existing.length) {\n throw new Error('Trying to create too many accounts');\n }\n\n const [added] = await keyring.addAccounts(1);\n return [added, true];\n },\n );\n\n return result;\n }\n\n async createAccounts({\n entropySource,\n groupIndex,\n }: {\n entropySource: EntropySourceId;\n groupIndex: number;\n }): Promise<Bip44Account<KeyringAccount>[]> {\n const [address] = await this.#createAccount({\n entropySource,\n groupIndex,\n throwOnGap: true,\n });\n\n const account = this.messenger.call(\n 'AccountsController:getAccountByAddress',\n address,\n );\n\n // We MUST have the associated internal account.\n assertInternalAccountExists(account);\n\n const accountsArray = [account];\n assertAreBip44Accounts(accountsArray);\n\n return accountsArray;\n }\n\n /**\n * Discover and create accounts for the EVM provider.\n *\n * @param opts - The options for the discovery and creation of accounts.\n * @param opts.entropySource - The entropy source to use for the discovery and creation of accounts.\n * @param opts.groupIndex - The index of the group to create the accounts for.\n * @returns The accounts for the EVM provider.\n */\n async discoverAndCreateAccounts(opts: {\n entropySource: EntropySourceId;\n groupIndex: number;\n }): Promise<Bip44Account<KeyringAccount>[]> {\n const provider = this.getEvmProvider();\n const { entropySource, groupIndex } = opts;\n\n const [address, didCreate] = await this.#createAccount({\n entropySource,\n groupIndex,\n });\n\n // We don't want to remove the account if it's the first one.\n const shouldCleanup = didCreate && groupIndex !== 0;\n try {\n const countHex = (await provider.request({\n method: 'eth_getTransactionCount',\n params: [address, 'latest'],\n })) as Hex;\n const count = parseInt(countHex, 16);\n\n if (count === 0 && shouldCleanup) {\n await this.withKeyring<EthKeyring>(\n { id: entropySource },\n async ({ keyring }) => {\n keyring.removeAccount?.(address);\n },\n );\n return [];\n }\n } catch (error) {\n // If the RPC request fails and we just created this account for discovery,\n // remove it to avoid leaving a dangling account.\n if (shouldCleanup) {\n await this.withKeyring<EthKeyring>(\n { id: entropySource },\n async ({ keyring }) => {\n keyring.removeAccount?.(address);\n },\n );\n }\n throw error;\n }\n\n const account = this.messenger.call(\n 'AccountsController:getAccountByAddress',\n address,\n );\n assertInternalAccountExists(account);\n assertIsBip44Account(account);\n return [account];\n }\n}\n"]}
|
|
@@ -1,64 +1,33 @@
|
|
|
1
1
|
import type { Bip44Account } from "@metamask/account-api";
|
|
2
|
-
import type { EntropySourceId } from "@metamask/keyring-api";
|
|
2
|
+
import type { EntropySourceId, KeyringAccount } from "@metamask/keyring-api";
|
|
3
3
|
import type { InternalAccount } from "@metamask/keyring-internal-api";
|
|
4
|
+
import type { Provider } from "@metamask/network-controller";
|
|
4
5
|
import { BaseBip44AccountProvider } from "./BaseBip44AccountProvider.cjs";
|
|
5
6
|
export declare class EvmAccountProvider extends BaseBip44AccountProvider {
|
|
7
|
+
#private;
|
|
6
8
|
isAccountCompatible(account: Bip44Account<InternalAccount>): boolean;
|
|
9
|
+
getName(): string;
|
|
10
|
+
/**
|
|
11
|
+
* Get the EVM provider.
|
|
12
|
+
*
|
|
13
|
+
* @returns The EVM provider.
|
|
14
|
+
*/
|
|
15
|
+
getEvmProvider(): Provider;
|
|
7
16
|
createAccounts({ entropySource, groupIndex, }: {
|
|
8
17
|
entropySource: EntropySourceId;
|
|
9
18
|
groupIndex: number;
|
|
10
|
-
}): Promise<
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
type: "private-key";
|
|
21
|
-
} | undefined;
|
|
22
|
-
exportable?: boolean | undefined;
|
|
23
|
-
};
|
|
24
|
-
metadata: {
|
|
25
|
-
name: string;
|
|
26
|
-
importTime: number;
|
|
27
|
-
keyring: {
|
|
28
|
-
type: string;
|
|
29
|
-
};
|
|
30
|
-
nameLastUpdatedAt?: number | undefined;
|
|
31
|
-
snap?: {
|
|
32
|
-
name: string;
|
|
33
|
-
id: string;
|
|
34
|
-
enabled: boolean;
|
|
35
|
-
} | undefined;
|
|
36
|
-
lastSelected?: number | undefined;
|
|
37
|
-
};
|
|
38
|
-
address: string;
|
|
39
|
-
scopes: `${string}:${string}`[];
|
|
40
|
-
methods: string[];
|
|
41
|
-
}[] & Bip44Account<{
|
|
42
|
-
type: "eip155:eoa" | "eip155:erc4337" | "bip122:p2pkh" | "bip122:p2sh" | "bip122:p2wpkh" | "bip122:p2tr" | "solana:data-account" | "tron:eoa" | "any:account";
|
|
43
|
-
id: string;
|
|
44
|
-
options: Record<string, import("@metamask/utils").Json> & {
|
|
45
|
-
entropy?: {
|
|
46
|
-
type: "mnemonic";
|
|
47
|
-
id: string;
|
|
48
|
-
derivationPath: string;
|
|
49
|
-
groupIndex: number;
|
|
50
|
-
} | {
|
|
51
|
-
type: "private-key";
|
|
52
|
-
} | undefined;
|
|
53
|
-
exportable?: boolean | undefined;
|
|
54
|
-
};
|
|
55
|
-
address: string;
|
|
56
|
-
scopes: `${string}:${string}`[];
|
|
57
|
-
methods: string[];
|
|
58
|
-
}>[]>;
|
|
59
|
-
discoverAndCreateAccounts(_: {
|
|
19
|
+
}): Promise<Bip44Account<KeyringAccount>[]>;
|
|
20
|
+
/**
|
|
21
|
+
* Discover and create accounts for the EVM provider.
|
|
22
|
+
*
|
|
23
|
+
* @param opts - The options for the discovery and creation of accounts.
|
|
24
|
+
* @param opts.entropySource - The entropy source to use for the discovery and creation of accounts.
|
|
25
|
+
* @param opts.groupIndex - The index of the group to create the accounts for.
|
|
26
|
+
* @returns The accounts for the EVM provider.
|
|
27
|
+
*/
|
|
28
|
+
discoverAndCreateAccounts(opts: {
|
|
60
29
|
entropySource: EntropySourceId;
|
|
61
30
|
groupIndex: number;
|
|
62
|
-
}): Promise<
|
|
31
|
+
}): Promise<Bip44Account<KeyringAccount>[]>;
|
|
63
32
|
}
|
|
64
33
|
//# sourceMappingURL=EvmAccountProvider.d.cts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"EvmAccountProvider.d.cts","sourceRoot":"","sources":["../../src/providers/EvmAccountProvider.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,8BAA8B;AAC1D,OAAO,KAAK,EAAE,eAAe,EAAE,8BAA8B;
|
|
1
|
+
{"version":3,"file":"EvmAccountProvider.d.cts","sourceRoot":"","sources":["../../src/providers/EvmAccountProvider.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,8BAA8B;AAC1D,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,8BAA8B;AAG7E,OAAO,KAAK,EAEV,eAAe,EAChB,uCAAuC;AACxC,OAAO,KAAK,EAAE,QAAQ,EAAE,qCAAqC;AAG7D,OAAO,EAGL,wBAAwB,EACzB,uCAAmC;AAkBpC,qBAAa,kBAAmB,SAAQ,wBAAwB;;IAC9D,mBAAmB,CAAC,OAAO,EAAE,YAAY,CAAC,eAAe,CAAC,GAAG,OAAO;IAOpE,OAAO,IAAI,MAAM;IAIjB;;;;OAIG;IACH,cAAc,IAAI,QAAQ;IA0CpB,cAAc,CAAC,EACnB,aAAa,EACb,UAAU,GACX,EAAE;QACD,aAAa,EAAE,eAAe,CAAC;QAC/B,UAAU,EAAE,MAAM,CAAC;KACpB,GAAG,OAAO,CAAC,YAAY,CAAC,cAAc,CAAC,EAAE,CAAC;IAqB3C;;;;;;;OAOG;IACG,yBAAyB,CAAC,IAAI,EAAE;QACpC,aAAa,EAAE,eAAe,CAAC;QAC/B,UAAU,EAAE,MAAM,CAAC;KACpB,GAAG,OAAO,CAAC,YAAY,CAAC,cAAc,CAAC,EAAE,CAAC;CAiD5C"}
|
|
@@ -1,64 +1,33 @@
|
|
|
1
1
|
import type { Bip44Account } from "@metamask/account-api";
|
|
2
|
-
import type { EntropySourceId } from "@metamask/keyring-api";
|
|
2
|
+
import type { EntropySourceId, KeyringAccount } from "@metamask/keyring-api";
|
|
3
3
|
import type { InternalAccount } from "@metamask/keyring-internal-api";
|
|
4
|
+
import type { Provider } from "@metamask/network-controller";
|
|
4
5
|
import { BaseBip44AccountProvider } from "./BaseBip44AccountProvider.mjs";
|
|
5
6
|
export declare class EvmAccountProvider extends BaseBip44AccountProvider {
|
|
7
|
+
#private;
|
|
6
8
|
isAccountCompatible(account: Bip44Account<InternalAccount>): boolean;
|
|
9
|
+
getName(): string;
|
|
10
|
+
/**
|
|
11
|
+
* Get the EVM provider.
|
|
12
|
+
*
|
|
13
|
+
* @returns The EVM provider.
|
|
14
|
+
*/
|
|
15
|
+
getEvmProvider(): Provider;
|
|
7
16
|
createAccounts({ entropySource, groupIndex, }: {
|
|
8
17
|
entropySource: EntropySourceId;
|
|
9
18
|
groupIndex: number;
|
|
10
|
-
}): Promise<
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
type: "private-key";
|
|
21
|
-
} | undefined;
|
|
22
|
-
exportable?: boolean | undefined;
|
|
23
|
-
};
|
|
24
|
-
metadata: {
|
|
25
|
-
name: string;
|
|
26
|
-
importTime: number;
|
|
27
|
-
keyring: {
|
|
28
|
-
type: string;
|
|
29
|
-
};
|
|
30
|
-
nameLastUpdatedAt?: number | undefined;
|
|
31
|
-
snap?: {
|
|
32
|
-
name: string;
|
|
33
|
-
id: string;
|
|
34
|
-
enabled: boolean;
|
|
35
|
-
} | undefined;
|
|
36
|
-
lastSelected?: number | undefined;
|
|
37
|
-
};
|
|
38
|
-
address: string;
|
|
39
|
-
scopes: `${string}:${string}`[];
|
|
40
|
-
methods: string[];
|
|
41
|
-
}[] & Bip44Account<{
|
|
42
|
-
type: "eip155:eoa" | "eip155:erc4337" | "bip122:p2pkh" | "bip122:p2sh" | "bip122:p2wpkh" | "bip122:p2tr" | "solana:data-account" | "tron:eoa" | "any:account";
|
|
43
|
-
id: string;
|
|
44
|
-
options: Record<string, import("@metamask/utils").Json> & {
|
|
45
|
-
entropy?: {
|
|
46
|
-
type: "mnemonic";
|
|
47
|
-
id: string;
|
|
48
|
-
derivationPath: string;
|
|
49
|
-
groupIndex: number;
|
|
50
|
-
} | {
|
|
51
|
-
type: "private-key";
|
|
52
|
-
} | undefined;
|
|
53
|
-
exportable?: boolean | undefined;
|
|
54
|
-
};
|
|
55
|
-
address: string;
|
|
56
|
-
scopes: `${string}:${string}`[];
|
|
57
|
-
methods: string[];
|
|
58
|
-
}>[]>;
|
|
59
|
-
discoverAndCreateAccounts(_: {
|
|
19
|
+
}): Promise<Bip44Account<KeyringAccount>[]>;
|
|
20
|
+
/**
|
|
21
|
+
* Discover and create accounts for the EVM provider.
|
|
22
|
+
*
|
|
23
|
+
* @param opts - The options for the discovery and creation of accounts.
|
|
24
|
+
* @param opts.entropySource - The entropy source to use for the discovery and creation of accounts.
|
|
25
|
+
* @param opts.groupIndex - The index of the group to create the accounts for.
|
|
26
|
+
* @returns The accounts for the EVM provider.
|
|
27
|
+
*/
|
|
28
|
+
discoverAndCreateAccounts(opts: {
|
|
60
29
|
entropySource: EntropySourceId;
|
|
61
30
|
groupIndex: number;
|
|
62
|
-
}): Promise<
|
|
31
|
+
}): Promise<Bip44Account<KeyringAccount>[]>;
|
|
63
32
|
}
|
|
64
33
|
//# sourceMappingURL=EvmAccountProvider.d.mts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"EvmAccountProvider.d.mts","sourceRoot":"","sources":["../../src/providers/EvmAccountProvider.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,8BAA8B;AAC1D,OAAO,KAAK,EAAE,eAAe,EAAE,8BAA8B;
|
|
1
|
+
{"version":3,"file":"EvmAccountProvider.d.mts","sourceRoot":"","sources":["../../src/providers/EvmAccountProvider.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,8BAA8B;AAC1D,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,8BAA8B;AAG7E,OAAO,KAAK,EAEV,eAAe,EAChB,uCAAuC;AACxC,OAAO,KAAK,EAAE,QAAQ,EAAE,qCAAqC;AAG7D,OAAO,EAGL,wBAAwB,EACzB,uCAAmC;AAkBpC,qBAAa,kBAAmB,SAAQ,wBAAwB;;IAC9D,mBAAmB,CAAC,OAAO,EAAE,YAAY,CAAC,eAAe,CAAC,GAAG,OAAO;IAOpE,OAAO,IAAI,MAAM;IAIjB;;;;OAIG;IACH,cAAc,IAAI,QAAQ;IA0CpB,cAAc,CAAC,EACnB,aAAa,EACb,UAAU,GACX,EAAE;QACD,aAAa,EAAE,eAAe,CAAC;QAC/B,UAAU,EAAE,MAAM,CAAC;KACpB,GAAG,OAAO,CAAC,YAAY,CAAC,cAAc,CAAC,EAAE,CAAC;IAqB3C;;;;;;;OAOG;IACG,yBAAyB,CAAC,IAAI,EAAE;QACpC,aAAa,EAAE,eAAe,CAAC;QAC/B,UAAU,EAAE,MAAM,CAAC;KACpB,GAAG,OAAO,CAAC,YAAY,CAAC,cAAc,CAAC,EAAE,CAAC;CAiD5C"}
|
|
@@ -1,6 +1,13 @@
|
|
|
1
|
+
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
|
|
2
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
|
|
3
|
+
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
|
|
4
|
+
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
5
|
+
};
|
|
6
|
+
var _EvmAccountProvider_instances, _EvmAccountProvider_createAccount;
|
|
1
7
|
import { EthAccountType } from "@metamask/keyring-api";
|
|
2
8
|
import { KeyringTypes } from "@metamask/keyring-controller";
|
|
3
|
-
import { assertAreBip44Accounts, BaseBip44AccountProvider } from "./BaseBip44AccountProvider.mjs";
|
|
9
|
+
import { assertAreBip44Accounts, assertIsBip44Account, BaseBip44AccountProvider } from "./BaseBip44AccountProvider.mjs";
|
|
10
|
+
const ETH_MAINNET_CHAIN_ID = '0x1';
|
|
4
11
|
/**
|
|
5
12
|
* Asserts an internal account exists.
|
|
6
13
|
*
|
|
@@ -13,24 +20,32 @@ function assertInternalAccountExists(account) {
|
|
|
13
20
|
}
|
|
14
21
|
}
|
|
15
22
|
export class EvmAccountProvider extends BaseBip44AccountProvider {
|
|
23
|
+
constructor() {
|
|
24
|
+
super(...arguments);
|
|
25
|
+
_EvmAccountProvider_instances.add(this);
|
|
26
|
+
}
|
|
16
27
|
isAccountCompatible(account) {
|
|
17
28
|
return (account.type === EthAccountType.Eoa &&
|
|
18
29
|
account.metadata.keyring.type === KeyringTypes.hd);
|
|
19
30
|
}
|
|
31
|
+
getName() {
|
|
32
|
+
return 'EVM';
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Get the EVM provider.
|
|
36
|
+
*
|
|
37
|
+
* @returns The EVM provider.
|
|
38
|
+
*/
|
|
39
|
+
getEvmProvider() {
|
|
40
|
+
const networkClientId = this.messenger.call('NetworkController:findNetworkClientIdByChainId', ETH_MAINNET_CHAIN_ID);
|
|
41
|
+
const { provider } = this.messenger.call('NetworkController:getNetworkClientById', networkClientId);
|
|
42
|
+
return provider;
|
|
43
|
+
}
|
|
20
44
|
async createAccounts({ entropySource, groupIndex, }) {
|
|
21
|
-
const [address] = await this
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
return [accounts[groupIndex]];
|
|
26
|
-
}
|
|
27
|
-
// For now, we don't allow for gap, so if we need to create a new
|
|
28
|
-
// account, this has to be the next one.
|
|
29
|
-
if (groupIndex !== accounts.length) {
|
|
30
|
-
throw new Error('Trying to create too many accounts');
|
|
31
|
-
}
|
|
32
|
-
// Create next account (and returns their addresses).
|
|
33
|
-
return await keyring.addAccounts(1);
|
|
45
|
+
const [address] = await __classPrivateFieldGet(this, _EvmAccountProvider_instances, "m", _EvmAccountProvider_createAccount).call(this, {
|
|
46
|
+
entropySource,
|
|
47
|
+
groupIndex,
|
|
48
|
+
throwOnGap: true,
|
|
34
49
|
});
|
|
35
50
|
const account = this.messenger.call('AccountsController:getAccountByAddress', address);
|
|
36
51
|
// We MUST have the associated internal account.
|
|
@@ -39,8 +54,65 @@ export class EvmAccountProvider extends BaseBip44AccountProvider {
|
|
|
39
54
|
assertAreBip44Accounts(accountsArray);
|
|
40
55
|
return accountsArray;
|
|
41
56
|
}
|
|
42
|
-
|
|
43
|
-
|
|
57
|
+
/**
|
|
58
|
+
* Discover and create accounts for the EVM provider.
|
|
59
|
+
*
|
|
60
|
+
* @param opts - The options for the discovery and creation of accounts.
|
|
61
|
+
* @param opts.entropySource - The entropy source to use for the discovery and creation of accounts.
|
|
62
|
+
* @param opts.groupIndex - The index of the group to create the accounts for.
|
|
63
|
+
* @returns The accounts for the EVM provider.
|
|
64
|
+
*/
|
|
65
|
+
async discoverAndCreateAccounts(opts) {
|
|
66
|
+
const provider = this.getEvmProvider();
|
|
67
|
+
const { entropySource, groupIndex } = opts;
|
|
68
|
+
const [address, didCreate] = await __classPrivateFieldGet(this, _EvmAccountProvider_instances, "m", _EvmAccountProvider_createAccount).call(this, {
|
|
69
|
+
entropySource,
|
|
70
|
+
groupIndex,
|
|
71
|
+
});
|
|
72
|
+
// We don't want to remove the account if it's the first one.
|
|
73
|
+
const shouldCleanup = didCreate && groupIndex !== 0;
|
|
74
|
+
try {
|
|
75
|
+
const countHex = (await provider.request({
|
|
76
|
+
method: 'eth_getTransactionCount',
|
|
77
|
+
params: [address, 'latest'],
|
|
78
|
+
}));
|
|
79
|
+
const count = parseInt(countHex, 16);
|
|
80
|
+
if (count === 0 && shouldCleanup) {
|
|
81
|
+
await this.withKeyring({ id: entropySource }, async ({ keyring }) => {
|
|
82
|
+
keyring.removeAccount?.(address);
|
|
83
|
+
});
|
|
84
|
+
return [];
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
catch (error) {
|
|
88
|
+
// If the RPC request fails and we just created this account for discovery,
|
|
89
|
+
// remove it to avoid leaving a dangling account.
|
|
90
|
+
if (shouldCleanup) {
|
|
91
|
+
await this.withKeyring({ id: entropySource }, async ({ keyring }) => {
|
|
92
|
+
keyring.removeAccount?.(address);
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
throw error;
|
|
96
|
+
}
|
|
97
|
+
const account = this.messenger.call('AccountsController:getAccountByAddress', address);
|
|
98
|
+
assertInternalAccountExists(account);
|
|
99
|
+
assertIsBip44Account(account);
|
|
100
|
+
return [account];
|
|
44
101
|
}
|
|
45
102
|
}
|
|
103
|
+
_EvmAccountProvider_instances = new WeakSet(), _EvmAccountProvider_createAccount = async function _EvmAccountProvider_createAccount({ entropySource, groupIndex, throwOnGap = false, }) {
|
|
104
|
+
const result = await this.withKeyring({ id: entropySource }, async ({ keyring }) => {
|
|
105
|
+
const existing = await keyring.getAccounts();
|
|
106
|
+
if (groupIndex < existing.length) {
|
|
107
|
+
return [existing[groupIndex], false];
|
|
108
|
+
}
|
|
109
|
+
// If the throwOnGap flag is set, we throw an error to prevent index gaps.
|
|
110
|
+
if (throwOnGap && groupIndex !== existing.length) {
|
|
111
|
+
throw new Error('Trying to create too many accounts');
|
|
112
|
+
}
|
|
113
|
+
const [added] = await keyring.addAccounts(1);
|
|
114
|
+
return [added, true];
|
|
115
|
+
});
|
|
116
|
+
return result;
|
|
117
|
+
};
|
|
46
118
|
//# sourceMappingURL=EvmAccountProvider.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"EvmAccountProvider.mjs","sourceRoot":"","sources":["../../src/providers/EvmAccountProvider.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,cAAc,EAAE,8BAA8B;AACvD,OAAO,EAAE,YAAY,EAAE,qCAAqC;
|
|
1
|
+
{"version":3,"file":"EvmAccountProvider.mjs","sourceRoot":"","sources":["../../src/providers/EvmAccountProvider.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Bip44Account } from '@metamask/account-api';\nimport type { EntropySourceId, KeyringAccount } from '@metamask/keyring-api';\nimport { EthAccountType } from '@metamask/keyring-api';\nimport { KeyringTypes } from '@metamask/keyring-controller';\nimport type {\n EthKeyring,\n InternalAccount,\n} from '@metamask/keyring-internal-api';\nimport type { Provider } from '@metamask/network-controller';\nimport type { Hex } from '@metamask/utils';\n\nimport {\n assertAreBip44Accounts,\n assertIsBip44Account,\n BaseBip44AccountProvider,\n} from './BaseBip44AccountProvider';\n\nconst ETH_MAINNET_CHAIN_ID = '0x1';\n\n/**\n * Asserts an internal account exists.\n *\n * @param account - The internal account to check.\n * @throws An error if the internal account does not exist.\n */\nfunction assertInternalAccountExists(\n account: InternalAccount | undefined,\n): asserts account is InternalAccount {\n if (!account) {\n throw new Error('Internal account does not exist');\n }\n}\n\nexport class EvmAccountProvider extends BaseBip44AccountProvider {\n isAccountCompatible(account: Bip44Account<InternalAccount>): boolean {\n return (\n account.type === EthAccountType.Eoa &&\n account.metadata.keyring.type === (KeyringTypes.hd as string)\n );\n }\n\n getName(): string {\n return 'EVM';\n }\n\n /**\n * Get the EVM provider.\n *\n * @returns The EVM provider.\n */\n getEvmProvider(): Provider {\n const networkClientId = this.messenger.call(\n 'NetworkController:findNetworkClientIdByChainId',\n ETH_MAINNET_CHAIN_ID,\n );\n const { provider } = this.messenger.call(\n 'NetworkController:getNetworkClientById',\n networkClientId,\n );\n return provider;\n }\n\n async #createAccount({\n entropySource,\n groupIndex,\n throwOnGap = false,\n }: {\n entropySource: EntropySourceId;\n groupIndex: number;\n throwOnGap?: boolean;\n }): Promise<[Hex, boolean]> {\n const result = await this.withKeyring<EthKeyring, [Hex, boolean]>(\n { id: entropySource },\n async ({ keyring }) => {\n const existing = await keyring.getAccounts();\n if (groupIndex < existing.length) {\n return [existing[groupIndex], false];\n }\n\n // If the throwOnGap flag is set, we throw an error to prevent index gaps.\n if (throwOnGap && groupIndex !== existing.length) {\n throw new Error('Trying to create too many accounts');\n }\n\n const [added] = await keyring.addAccounts(1);\n return [added, true];\n },\n );\n\n return result;\n }\n\n async createAccounts({\n entropySource,\n groupIndex,\n }: {\n entropySource: EntropySourceId;\n groupIndex: number;\n }): Promise<Bip44Account<KeyringAccount>[]> {\n const [address] = await this.#createAccount({\n entropySource,\n groupIndex,\n throwOnGap: true,\n });\n\n const account = this.messenger.call(\n 'AccountsController:getAccountByAddress',\n address,\n );\n\n // We MUST have the associated internal account.\n assertInternalAccountExists(account);\n\n const accountsArray = [account];\n assertAreBip44Accounts(accountsArray);\n\n return accountsArray;\n }\n\n /**\n * Discover and create accounts for the EVM provider.\n *\n * @param opts - The options for the discovery and creation of accounts.\n * @param opts.entropySource - The entropy source to use for the discovery and creation of accounts.\n * @param opts.groupIndex - The index of the group to create the accounts for.\n * @returns The accounts for the EVM provider.\n */\n async discoverAndCreateAccounts(opts: {\n entropySource: EntropySourceId;\n groupIndex: number;\n }): Promise<Bip44Account<KeyringAccount>[]> {\n const provider = this.getEvmProvider();\n const { entropySource, groupIndex } = opts;\n\n const [address, didCreate] = await this.#createAccount({\n entropySource,\n groupIndex,\n });\n\n // We don't want to remove the account if it's the first one.\n const shouldCleanup = didCreate && groupIndex !== 0;\n try {\n const countHex = (await provider.request({\n method: 'eth_getTransactionCount',\n params: [address, 'latest'],\n })) as Hex;\n const count = parseInt(countHex, 16);\n\n if (count === 0 && shouldCleanup) {\n await this.withKeyring<EthKeyring>(\n { id: entropySource },\n async ({ keyring }) => {\n keyring.removeAccount?.(address);\n },\n );\n return [];\n }\n } catch (error) {\n // If the RPC request fails and we just created this account for discovery,\n // remove it to avoid leaving a dangling account.\n if (shouldCleanup) {\n await this.withKeyring<EthKeyring>(\n { id: entropySource },\n async ({ keyring }) => {\n keyring.removeAccount?.(address);\n },\n );\n }\n throw error;\n }\n\n const account = this.messenger.call(\n 'AccountsController:getAccountByAddress',\n address,\n );\n assertInternalAccountExists(account);\n assertIsBip44Account(account);\n return [account];\n }\n}\n"]}
|