@metamask-previews/multichain-account-controller 0.0.0-preview-dccbb1e2 → 0.0.0-preview-3c8bcc82
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/dist/MultichainAccountController.cjs +8 -6
- package/dist/MultichainAccountController.cjs.map +1 -1
- package/dist/MultichainAccountController.d.cts +5 -4
- package/dist/MultichainAccountController.d.cts.map +1 -1
- package/dist/MultichainAccountController.d.mts +5 -4
- package/dist/MultichainAccountController.d.mts.map +1 -1
- package/dist/MultichainAccountController.mjs +8 -6
- package/dist/MultichainAccountController.mjs.map +1 -1
- package/dist/providers/EvmAccountProvider.cjs +13 -17
- package/dist/providers/EvmAccountProvider.cjs.map +1 -1
- package/dist/providers/EvmAccountProvider.d.cts +6 -47
- package/dist/providers/EvmAccountProvider.d.cts.map +1 -1
- package/dist/providers/EvmAccountProvider.d.mts +6 -47
- package/dist/providers/EvmAccountProvider.d.mts.map +1 -1
- package/dist/providers/EvmAccountProvider.mjs +13 -17
- package/dist/providers/EvmAccountProvider.mjs.map +1 -1
- package/dist/providers/SolAccountProvider.cjs +15 -39
- package/dist/providers/SolAccountProvider.cjs.map +1 -1
- package/dist/providers/SolAccountProvider.d.cts +6 -48
- package/dist/providers/SolAccountProvider.d.cts.map +1 -1
- package/dist/providers/SolAccountProvider.d.mts +6 -48
- package/dist/providers/SolAccountProvider.d.mts.map +1 -1
- package/dist/providers/SolAccountProvider.mjs +15 -39
- package/dist/providers/SolAccountProvider.mjs.map +1 -1
- package/dist/types.cjs.map +1 -1
- package/dist/types.d.cts +2 -2
- package/dist/types.d.cts.map +1 -1
- package/dist/types.d.mts +2 -2
- package/dist/types.d.mts.map +1 -1
- package/dist/types.mjs.map +1 -1
- package/package.json +1 -1
@@ -13,6 +13,7 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
|
|
13
13
|
var _MultichainAccountController_instances, _MultichainAccountController_messenger, _MultichainAccountController_providers, _MultichainAccountController_wallets, _MultichainAccountController_getWallet;
|
14
14
|
Object.defineProperty(exports, "__esModule", { value: true });
|
15
15
|
exports.MultichainAccountController = void 0;
|
16
|
+
const keyring_controller_1 = require("@metamask/keyring-controller");
|
16
17
|
const multichain_account_api_1 = require("@metamask/multichain-account-api");
|
17
18
|
const EvmAccountProvider_1 = require("./providers/EvmAccountProvider.cjs");
|
18
19
|
const SolAccountProvider_1 = require("./providers/SolAccountProvider.cjs");
|
@@ -42,10 +43,11 @@ class MultichainAccountController {
|
|
42
43
|
}
|
43
44
|
init() {
|
44
45
|
// Gather all entropy sources first.
|
45
|
-
const
|
46
|
-
|
47
|
-
|
48
|
-
|
46
|
+
const { keyrings } = __classPrivateFieldGet(this, _MultichainAccountController_messenger, "f").call('KeyringController:getState');
|
47
|
+
const entropySources = [];
|
48
|
+
for (const keyring of keyrings) {
|
49
|
+
if (keyring.type === keyring_controller_1.KeyringTypes.hd) {
|
50
|
+
entropySources.push(keyring.metadata.id);
|
49
51
|
}
|
50
52
|
}
|
51
53
|
for (const entropySource of entropySources) {
|
@@ -59,14 +61,14 @@ class MultichainAccountController {
|
|
59
61
|
}
|
60
62
|
}
|
61
63
|
getMultichainAccount({ entropySource, groupIndex, }) {
|
62
|
-
const multichainAccount = __classPrivateFieldGet(this, _MultichainAccountController_instances, "m", _MultichainAccountController_getWallet).call(this, entropySource).
|
64
|
+
const multichainAccount = __classPrivateFieldGet(this, _MultichainAccountController_instances, "m", _MultichainAccountController_getWallet).call(this, entropySource).getMultichainAccount(groupIndex);
|
63
65
|
if (!multichainAccount) {
|
64
66
|
throw new Error(`No multichain account for index: ${groupIndex}`);
|
65
67
|
}
|
66
68
|
return multichainAccount;
|
67
69
|
}
|
68
70
|
getMultichainAccounts({ entropySource, }) {
|
69
|
-
return __classPrivateFieldGet(this, _MultichainAccountController_instances, "m", _MultichainAccountController_getWallet).call(this, entropySource).
|
71
|
+
return __classPrivateFieldGet(this, _MultichainAccountController_instances, "m", _MultichainAccountController_getWallet).call(this, entropySource).getMultichainAccounts();
|
70
72
|
}
|
71
73
|
async createNextMultichainAccount({ entropySource, }) {
|
72
74
|
return await __classPrivateFieldGet(this, _MultichainAccountController_instances, "m", _MultichainAccountController_getWallet).call(this, entropySource).createNextMultichainAccount();
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"MultichainAccountController.cjs","sourceRoot":"","sources":["../src/MultichainAccountController.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;
|
1
|
+
{"version":3,"file":"MultichainAccountController.cjs","sourceRoot":"","sources":["../src/MultichainAccountController.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;AACA,qEAA4D;AAM5D,6EAK0C;AAE1C,2EAAoE;AACpE,2EAAoE;AAUpE;;GAEG;AACH,MAAa,2BAA2B;IAUtC;;;;;;OAMG;IACH,YAAY,EAAE,SAAS,EAAsC;;QAhBpD,yDAAiD;QAEjD,yDAA+C;QAE/C,uDAGP;QAUA,uBAAA,IAAI,0CAAc,SAAS,MAAA,CAAC;QAC5B,uBAAA,IAAI,wCAAY,IAAI,GAAG,EAAE,MAAA,CAAC;QAC1B,mFAAmF;QACnF,uBAAA,IAAI,0CAAc;YAChB,IAAI,uCAAkB,CAAC,uBAAA,IAAI,8CAAW,CAAC;YACvC,IAAI,uCAAkB,CAAC,uBAAA,IAAI,8CAAW,CAAC;SACxC,MAAA,CAAC;IACJ,CAAC;IAED,IAAI;QACF,oCAAoC;QACpC,MAAM,EAAE,QAAQ,EAAE,GAAG,uBAAA,IAAI,8CAAW,CAAC,IAAI,CAAC,4BAA4B,CAAC,CAAC;QAExE,MAAM,cAAc,GAAG,EAAE,CAAC;QAC1B,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE;YAC9B,IAAI,OAAO,CAAC,IAAI,KAAK,iCAAY,CAAC,EAAE,EAAE;gBACpC,cAAc,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;aAC1C;SACF;QAED,KAAK,MAAM,aAAa,IAAI,cAAc,EAAE;YAC1C,gFAAgF;YAChF,oDAAoD;YACpD,MAAM,MAAM,GAAG,IAAI,uDAA8B,CAAC;gBAChD,aAAa;gBACb,SAAS,EAAE,uBAAA,IAAI,8CAAW;aAC3B,CAAC,CAAC;YAEH,uBAAA,IAAI,4CAAS,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,EAAE,MAAM,CAAC,CAAC;SACtC;IACH,CAAC;IAkBD,oBAAoB,CAAC,EACnB,aAAa,EACb,UAAU,GAIX;QACC,MAAM,iBAAiB,GACrB,uBAAA,IAAI,sFAAW,MAAf,IAAI,EAAY,aAAa,CAAC,CAAC,oBAAoB,CAAC,UAAU,CAAC,CAAC;QAElE,IAAI,CAAC,iBAAiB,EAAE;YACtB,MAAM,IAAI,KAAK,CAAC,oCAAoC,UAAU,EAAE,CAAC,CAAC;SACnE;QAED,OAAO,iBAAiB,CAAC;IAC3B,CAAC;IAED,qBAAqB,CAAC,EACpB,aAAa,GAGd;QACC,OAAO,uBAAA,IAAI,sFAAW,MAAf,IAAI,EAAY,aAAa,CAAC,CAAC,qBAAqB,EAAE,CAAC;IAChE,CAAC;IAED,KAAK,CAAC,2BAA2B,CAAC,EAChC,aAAa,GAGd;QACC,OAAO,MAAM,uBAAA,IAAI,sFAAW,MAAf,IAAI,EAAY,aAAa,CAAC,CAAC,2BAA2B,EAAE,CAAC;IAC5E,CAAC;IAED,KAAK,CAAC,mCAAmC,CAAC,EACxC,aAAa,GAGd;QACC,OAAO,MAAM,uBAAA,IAAI,sFAAW,MAAf,IAAI,EACf,aAAa,CACd,CAAC,mCAAmC,EAAE,CAAC;IAC1C,CAAC;CACF;AA5GD,kEA4GC;uTAzDG,aAA8B;IAE9B,MAAM,MAAM,GAAG,uBAAA,IAAI,4CAAS,CAAC,GAAG,CAC9B,IAAA,oDAA2B,EAAC,aAAa,CAAC,CAC3C,CAAC;IAEF,IAAI,CAAC,MAAM,EAAE;QACX,MAAM,IAAI,KAAK,CACb,yDAAyD,CAC1D,CAAC;KACH;IAED,OAAO,MAAM,CAAC;AAChB,CAAC","sourcesContent":["import type { EntropySourceId } from '@metamask/keyring-api';\nimport { KeyringTypes } from '@metamask/keyring-controller';\nimport type { InternalAccount } from '@metamask/keyring-internal-api';\nimport type {\n AccountProvider,\n MultichainAccountWalletId,\n} from '@metamask/multichain-account-api';\nimport {\n MultichainAccountWalletAdapter,\n toMultichainAccountWalletId,\n type MultichainAccount,\n type MultichainAccountWallet,\n} from '@metamask/multichain-account-api';\n\nimport { EvmAccountProvider } from './providers/EvmAccountProvider';\nimport { SolAccountProvider } from './providers/SolAccountProvider';\nimport type { MultichainAccountControllerMessenger } from './types';\n\n/**\n * The options that {@link MultichainAccountController} takes.\n */\ntype MultichainAccountControllerOptions = {\n messenger: MultichainAccountControllerMessenger;\n};\n\n/**\n * Stateless controller to expose multichain accounts capabilities.\n */\nexport class MultichainAccountController {\n readonly #messenger: MultichainAccountControllerMessenger;\n\n readonly #providers: AccountProvider<InternalAccount>[];\n\n readonly #wallets: Map<\n MultichainAccountWalletId,\n MultichainAccountWallet<InternalAccount>\n >;\n\n /**\n * Constructs a new MultichainAccountController.\n *\n * @param options - The options.\n * @param options.messenger - The messenger suited to this\n * MultichainAccountController.\n */\n constructor({ messenger }: MultichainAccountControllerOptions) {\n this.#messenger = messenger;\n this.#wallets = new Map();\n // TODO: Rely on keyring capabilities once the keyring API is used by all keyrings.\n this.#providers = [\n new EvmAccountProvider(this.#messenger),\n new SolAccountProvider(this.#messenger),\n ];\n }\n\n init(): void {\n // Gather all entropy sources first.\n const { keyrings } = this.#messenger.call('KeyringController:getState');\n\n const entropySources = [];\n for (const keyring of keyrings) {\n if (keyring.type === KeyringTypes.hd) {\n entropySources.push(keyring.metadata.id);\n }\n }\n\n for (const entropySource of entropySources) {\n // This will automatically create all multichain accounts for that wallet (based\n // on the accounts owned by each account providers).\n const wallet = new MultichainAccountWalletAdapter({\n entropySource,\n providers: this.#providers,\n });\n\n this.#wallets.set(wallet.id, wallet);\n }\n }\n\n #getWallet(\n entropySource: EntropySourceId,\n ): MultichainAccountWallet<InternalAccount> {\n const wallet = this.#wallets.get(\n toMultichainAccountWalletId(entropySource),\n );\n\n if (!wallet) {\n throw new Error(\n 'Unknown wallet, not wallet matching this entropy source',\n );\n }\n\n return wallet;\n }\n\n getMultichainAccount({\n entropySource,\n groupIndex,\n }: {\n entropySource: EntropySourceId;\n groupIndex: number;\n }): MultichainAccount<InternalAccount> {\n const multichainAccount =\n this.#getWallet(entropySource).getMultichainAccount(groupIndex);\n\n if (!multichainAccount) {\n throw new Error(`No multichain account for index: ${groupIndex}`);\n }\n\n return multichainAccount;\n }\n\n getMultichainAccounts({\n entropySource,\n }: {\n entropySource: EntropySourceId;\n }): MultichainAccount<InternalAccount>[] {\n return this.#getWallet(entropySource).getMultichainAccounts();\n }\n\n async createNextMultichainAccount({\n entropySource,\n }: {\n entropySource: EntropySourceId;\n }): Promise<MultichainAccount<InternalAccount>> {\n return await this.#getWallet(entropySource).createNextMultichainAccount();\n }\n\n async discoverAndCreateMultichainAccounts({\n entropySource,\n }: {\n entropySource: EntropySourceId;\n }): Promise<MultichainAccount<InternalAccount>[]> {\n return await this.#getWallet(\n entropySource,\n ).discoverAndCreateMultichainAccounts();\n }\n}\n"]}
|
@@ -1,4 +1,5 @@
|
|
1
1
|
import type { EntropySourceId } from "@metamask/keyring-api";
|
2
|
+
import type { InternalAccount } from "@metamask/keyring-internal-api";
|
2
3
|
import { type MultichainAccount } from "@metamask/multichain-account-api";
|
3
4
|
import type { MultichainAccountControllerMessenger } from "./types.cjs";
|
4
5
|
/**
|
@@ -24,16 +25,16 @@ export declare class MultichainAccountController {
|
|
24
25
|
getMultichainAccount({ entropySource, groupIndex, }: {
|
25
26
|
entropySource: EntropySourceId;
|
26
27
|
groupIndex: number;
|
27
|
-
}): MultichainAccount
|
28
|
+
}): MultichainAccount<InternalAccount>;
|
28
29
|
getMultichainAccounts({ entropySource, }: {
|
29
30
|
entropySource: EntropySourceId;
|
30
|
-
}): MultichainAccount[];
|
31
|
+
}): MultichainAccount<InternalAccount>[];
|
31
32
|
createNextMultichainAccount({ entropySource, }: {
|
32
33
|
entropySource: EntropySourceId;
|
33
|
-
}): Promise<MultichainAccount
|
34
|
+
}): Promise<MultichainAccount<InternalAccount>>;
|
34
35
|
discoverAndCreateMultichainAccounts({ entropySource, }: {
|
35
36
|
entropySource: EntropySourceId;
|
36
|
-
}): Promise<MultichainAccount[]>;
|
37
|
+
}): Promise<MultichainAccount<InternalAccount>[]>;
|
37
38
|
}
|
38
39
|
export {};
|
39
40
|
//# sourceMappingURL=MultichainAccountController.d.cts.map
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"MultichainAccountController.d.cts","sourceRoot":"","sources":["../src/MultichainAccountController.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,8BAA8B;
|
1
|
+
{"version":3,"file":"MultichainAccountController.d.cts","sourceRoot":"","sources":["../src/MultichainAccountController.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,8BAA8B;AAE7D,OAAO,KAAK,EAAE,eAAe,EAAE,uCAAuC;AAKtE,OAAO,EAGL,KAAK,iBAAiB,EAEvB,yCAAyC;AAI1C,OAAO,KAAK,EAAE,oCAAoC,EAAE,oBAAgB;AAEpE;;GAEG;AACH,KAAK,kCAAkC,GAAG;IACxC,SAAS,EAAE,oCAAoC,CAAC;CACjD,CAAC;AAEF;;GAEG;AACH,qBAAa,2BAA2B;;IAUtC;;;;;;OAMG;gBACS,EAAE,SAAS,EAAE,EAAE,kCAAkC;IAU7D,IAAI,IAAI,IAAI;IAuCZ,oBAAoB,CAAC,EACnB,aAAa,EACb,UAAU,GACX,EAAE;QACD,aAAa,EAAE,eAAe,CAAC;QAC/B,UAAU,EAAE,MAAM,CAAC;KACpB,GAAG,iBAAiB,CAAC,eAAe,CAAC;IAWtC,qBAAqB,CAAC,EACpB,aAAa,GACd,EAAE;QACD,aAAa,EAAE,eAAe,CAAC;KAChC,GAAG,iBAAiB,CAAC,eAAe,CAAC,EAAE;IAIlC,2BAA2B,CAAC,EAChC,aAAa,GACd,EAAE;QACD,aAAa,EAAE,eAAe,CAAC;KAChC,GAAG,OAAO,CAAC,iBAAiB,CAAC,eAAe,CAAC,CAAC;IAIzC,mCAAmC,CAAC,EACxC,aAAa,GACd,EAAE;QACD,aAAa,EAAE,eAAe,CAAC;KAChC,GAAG,OAAO,CAAC,iBAAiB,CAAC,eAAe,CAAC,EAAE,CAAC;CAKlD"}
|
@@ -1,4 +1,5 @@
|
|
1
1
|
import type { EntropySourceId } from "@metamask/keyring-api";
|
2
|
+
import type { InternalAccount } from "@metamask/keyring-internal-api";
|
2
3
|
import { type MultichainAccount } from "@metamask/multichain-account-api";
|
3
4
|
import type { MultichainAccountControllerMessenger } from "./types.mjs";
|
4
5
|
/**
|
@@ -24,16 +25,16 @@ export declare class MultichainAccountController {
|
|
24
25
|
getMultichainAccount({ entropySource, groupIndex, }: {
|
25
26
|
entropySource: EntropySourceId;
|
26
27
|
groupIndex: number;
|
27
|
-
}): MultichainAccount
|
28
|
+
}): MultichainAccount<InternalAccount>;
|
28
29
|
getMultichainAccounts({ entropySource, }: {
|
29
30
|
entropySource: EntropySourceId;
|
30
|
-
}): MultichainAccount[];
|
31
|
+
}): MultichainAccount<InternalAccount>[];
|
31
32
|
createNextMultichainAccount({ entropySource, }: {
|
32
33
|
entropySource: EntropySourceId;
|
33
|
-
}): Promise<MultichainAccount
|
34
|
+
}): Promise<MultichainAccount<InternalAccount>>;
|
34
35
|
discoverAndCreateMultichainAccounts({ entropySource, }: {
|
35
36
|
entropySource: EntropySourceId;
|
36
|
-
}): Promise<MultichainAccount[]>;
|
37
|
+
}): Promise<MultichainAccount<InternalAccount>[]>;
|
37
38
|
}
|
38
39
|
export {};
|
39
40
|
//# sourceMappingURL=MultichainAccountController.d.mts.map
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"MultichainAccountController.d.mts","sourceRoot":"","sources":["../src/MultichainAccountController.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,8BAA8B;
|
1
|
+
{"version":3,"file":"MultichainAccountController.d.mts","sourceRoot":"","sources":["../src/MultichainAccountController.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,8BAA8B;AAE7D,OAAO,KAAK,EAAE,eAAe,EAAE,uCAAuC;AAKtE,OAAO,EAGL,KAAK,iBAAiB,EAEvB,yCAAyC;AAI1C,OAAO,KAAK,EAAE,oCAAoC,EAAE,oBAAgB;AAEpE;;GAEG;AACH,KAAK,kCAAkC,GAAG;IACxC,SAAS,EAAE,oCAAoC,CAAC;CACjD,CAAC;AAEF;;GAEG;AACH,qBAAa,2BAA2B;;IAUtC;;;;;;OAMG;gBACS,EAAE,SAAS,EAAE,EAAE,kCAAkC;IAU7D,IAAI,IAAI,IAAI;IAuCZ,oBAAoB,CAAC,EACnB,aAAa,EACb,UAAU,GACX,EAAE;QACD,aAAa,EAAE,eAAe,CAAC;QAC/B,UAAU,EAAE,MAAM,CAAC;KACpB,GAAG,iBAAiB,CAAC,eAAe,CAAC;IAWtC,qBAAqB,CAAC,EACpB,aAAa,GACd,EAAE;QACD,aAAa,EAAE,eAAe,CAAC;KAChC,GAAG,iBAAiB,CAAC,eAAe,CAAC,EAAE;IAIlC,2BAA2B,CAAC,EAChC,aAAa,GACd,EAAE;QACD,aAAa,EAAE,eAAe,CAAC;KAChC,GAAG,OAAO,CAAC,iBAAiB,CAAC,eAAe,CAAC,CAAC;IAIzC,mCAAmC,CAAC,EACxC,aAAa,GACd,EAAE;QACD,aAAa,EAAE,eAAe,CAAC;KAChC,GAAG,OAAO,CAAC,iBAAiB,CAAC,eAAe,CAAC,EAAE,CAAC;CAKlD"}
|
@@ -10,6 +10,7 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
|
|
10
10
|
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
11
11
|
};
|
12
12
|
var _MultichainAccountController_instances, _MultichainAccountController_messenger, _MultichainAccountController_providers, _MultichainAccountController_wallets, _MultichainAccountController_getWallet;
|
13
|
+
import { KeyringTypes } from "@metamask/keyring-controller";
|
13
14
|
import { MultichainAccountWalletAdapter, toMultichainAccountWalletId } from "@metamask/multichain-account-api";
|
14
15
|
import { EvmAccountProvider } from "./providers/EvmAccountProvider.mjs";
|
15
16
|
import { SolAccountProvider } from "./providers/SolAccountProvider.mjs";
|
@@ -39,10 +40,11 @@ export class MultichainAccountController {
|
|
39
40
|
}
|
40
41
|
init() {
|
41
42
|
// Gather all entropy sources first.
|
42
|
-
const
|
43
|
-
|
44
|
-
|
45
|
-
|
43
|
+
const { keyrings } = __classPrivateFieldGet(this, _MultichainAccountController_messenger, "f").call('KeyringController:getState');
|
44
|
+
const entropySources = [];
|
45
|
+
for (const keyring of keyrings) {
|
46
|
+
if (keyring.type === KeyringTypes.hd) {
|
47
|
+
entropySources.push(keyring.metadata.id);
|
46
48
|
}
|
47
49
|
}
|
48
50
|
for (const entropySource of entropySources) {
|
@@ -56,14 +58,14 @@ export class MultichainAccountController {
|
|
56
58
|
}
|
57
59
|
}
|
58
60
|
getMultichainAccount({ entropySource, groupIndex, }) {
|
59
|
-
const multichainAccount = __classPrivateFieldGet(this, _MultichainAccountController_instances, "m", _MultichainAccountController_getWallet).call(this, entropySource).
|
61
|
+
const multichainAccount = __classPrivateFieldGet(this, _MultichainAccountController_instances, "m", _MultichainAccountController_getWallet).call(this, entropySource).getMultichainAccount(groupIndex);
|
60
62
|
if (!multichainAccount) {
|
61
63
|
throw new Error(`No multichain account for index: ${groupIndex}`);
|
62
64
|
}
|
63
65
|
return multichainAccount;
|
64
66
|
}
|
65
67
|
getMultichainAccounts({ entropySource, }) {
|
66
|
-
return __classPrivateFieldGet(this, _MultichainAccountController_instances, "m", _MultichainAccountController_getWallet).call(this, entropySource).
|
68
|
+
return __classPrivateFieldGet(this, _MultichainAccountController_instances, "m", _MultichainAccountController_getWallet).call(this, entropySource).getMultichainAccounts();
|
67
69
|
}
|
68
70
|
async createNextMultichainAccount({ entropySource, }) {
|
69
71
|
return await __classPrivateFieldGet(this, _MultichainAccountController_instances, "m", _MultichainAccountController_getWallet).call(this, entropySource).createNextMultichainAccount();
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"MultichainAccountController.mjs","sourceRoot":"","sources":["../src/MultichainAccountController.ts"],"names":[],"mappings":";;;;;;;;;;;;
|
1
|
+
{"version":3,"file":"MultichainAccountController.mjs","sourceRoot":"","sources":["../src/MultichainAccountController.ts"],"names":[],"mappings":";;;;;;;;;;;;AACA,OAAO,EAAE,YAAY,EAAE,qCAAqC;AAM5D,OAAO,EACL,8BAA8B,EAC9B,2BAA2B,EAG5B,yCAAyC;AAE1C,OAAO,EAAE,kBAAkB,EAAE,2CAAuC;AACpE,OAAO,EAAE,kBAAkB,EAAE,2CAAuC;AAUpE;;GAEG;AACH,MAAM,OAAO,2BAA2B;IAUtC;;;;;;OAMG;IACH,YAAY,EAAE,SAAS,EAAsC;;QAhBpD,yDAAiD;QAEjD,yDAA+C;QAE/C,uDAGP;QAUA,uBAAA,IAAI,0CAAc,SAAS,MAAA,CAAC;QAC5B,uBAAA,IAAI,wCAAY,IAAI,GAAG,EAAE,MAAA,CAAC;QAC1B,mFAAmF;QACnF,uBAAA,IAAI,0CAAc;YAChB,IAAI,kBAAkB,CAAC,uBAAA,IAAI,8CAAW,CAAC;YACvC,IAAI,kBAAkB,CAAC,uBAAA,IAAI,8CAAW,CAAC;SACxC,MAAA,CAAC;IACJ,CAAC;IAED,IAAI;QACF,oCAAoC;QACpC,MAAM,EAAE,QAAQ,EAAE,GAAG,uBAAA,IAAI,8CAAW,CAAC,IAAI,CAAC,4BAA4B,CAAC,CAAC;QAExE,MAAM,cAAc,GAAG,EAAE,CAAC;QAC1B,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE;YAC9B,IAAI,OAAO,CAAC,IAAI,KAAK,YAAY,CAAC,EAAE,EAAE;gBACpC,cAAc,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;aAC1C;SACF;QAED,KAAK,MAAM,aAAa,IAAI,cAAc,EAAE;YAC1C,gFAAgF;YAChF,oDAAoD;YACpD,MAAM,MAAM,GAAG,IAAI,8BAA8B,CAAC;gBAChD,aAAa;gBACb,SAAS,EAAE,uBAAA,IAAI,8CAAW;aAC3B,CAAC,CAAC;YAEH,uBAAA,IAAI,4CAAS,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,EAAE,MAAM,CAAC,CAAC;SACtC;IACH,CAAC;IAkBD,oBAAoB,CAAC,EACnB,aAAa,EACb,UAAU,GAIX;QACC,MAAM,iBAAiB,GACrB,uBAAA,IAAI,sFAAW,MAAf,IAAI,EAAY,aAAa,CAAC,CAAC,oBAAoB,CAAC,UAAU,CAAC,CAAC;QAElE,IAAI,CAAC,iBAAiB,EAAE;YACtB,MAAM,IAAI,KAAK,CAAC,oCAAoC,UAAU,EAAE,CAAC,CAAC;SACnE;QAED,OAAO,iBAAiB,CAAC;IAC3B,CAAC;IAED,qBAAqB,CAAC,EACpB,aAAa,GAGd;QACC,OAAO,uBAAA,IAAI,sFAAW,MAAf,IAAI,EAAY,aAAa,CAAC,CAAC,qBAAqB,EAAE,CAAC;IAChE,CAAC;IAED,KAAK,CAAC,2BAA2B,CAAC,EAChC,aAAa,GAGd;QACC,OAAO,MAAM,uBAAA,IAAI,sFAAW,MAAf,IAAI,EAAY,aAAa,CAAC,CAAC,2BAA2B,EAAE,CAAC;IAC5E,CAAC;IAED,KAAK,CAAC,mCAAmC,CAAC,EACxC,aAAa,GAGd;QACC,OAAO,MAAM,uBAAA,IAAI,sFAAW,MAAf,IAAI,EACf,aAAa,CACd,CAAC,mCAAmC,EAAE,CAAC;IAC1C,CAAC;CACF;uTAzDG,aAA8B;IAE9B,MAAM,MAAM,GAAG,uBAAA,IAAI,4CAAS,CAAC,GAAG,CAC9B,2BAA2B,CAAC,aAAa,CAAC,CAC3C,CAAC;IAEF,IAAI,CAAC,MAAM,EAAE;QACX,MAAM,IAAI,KAAK,CACb,yDAAyD,CAC1D,CAAC;KACH;IAED,OAAO,MAAM,CAAC;AAChB,CAAC","sourcesContent":["import type { EntropySourceId } from '@metamask/keyring-api';\nimport { KeyringTypes } from '@metamask/keyring-controller';\nimport type { InternalAccount } from '@metamask/keyring-internal-api';\nimport type {\n AccountProvider,\n MultichainAccountWalletId,\n} from '@metamask/multichain-account-api';\nimport {\n MultichainAccountWalletAdapter,\n toMultichainAccountWalletId,\n type MultichainAccount,\n type MultichainAccountWallet,\n} from '@metamask/multichain-account-api';\n\nimport { EvmAccountProvider } from './providers/EvmAccountProvider';\nimport { SolAccountProvider } from './providers/SolAccountProvider';\nimport type { MultichainAccountControllerMessenger } from './types';\n\n/**\n * The options that {@link MultichainAccountController} takes.\n */\ntype MultichainAccountControllerOptions = {\n messenger: MultichainAccountControllerMessenger;\n};\n\n/**\n * Stateless controller to expose multichain accounts capabilities.\n */\nexport class MultichainAccountController {\n readonly #messenger: MultichainAccountControllerMessenger;\n\n readonly #providers: AccountProvider<InternalAccount>[];\n\n readonly #wallets: Map<\n MultichainAccountWalletId,\n MultichainAccountWallet<InternalAccount>\n >;\n\n /**\n * Constructs a new MultichainAccountController.\n *\n * @param options - The options.\n * @param options.messenger - The messenger suited to this\n * MultichainAccountController.\n */\n constructor({ messenger }: MultichainAccountControllerOptions) {\n this.#messenger = messenger;\n this.#wallets = new Map();\n // TODO: Rely on keyring capabilities once the keyring API is used by all keyrings.\n this.#providers = [\n new EvmAccountProvider(this.#messenger),\n new SolAccountProvider(this.#messenger),\n ];\n }\n\n init(): void {\n // Gather all entropy sources first.\n const { keyrings } = this.#messenger.call('KeyringController:getState');\n\n const entropySources = [];\n for (const keyring of keyrings) {\n if (keyring.type === KeyringTypes.hd) {\n entropySources.push(keyring.metadata.id);\n }\n }\n\n for (const entropySource of entropySources) {\n // This will automatically create all multichain accounts for that wallet (based\n // on the accounts owned by each account providers).\n const wallet = new MultichainAccountWalletAdapter({\n entropySource,\n providers: this.#providers,\n });\n\n this.#wallets.set(wallet.id, wallet);\n }\n }\n\n #getWallet(\n entropySource: EntropySourceId,\n ): MultichainAccountWallet<InternalAccount> {\n const wallet = this.#wallets.get(\n toMultichainAccountWalletId(entropySource),\n );\n\n if (!wallet) {\n throw new Error(\n 'Unknown wallet, not wallet matching this entropy source',\n );\n }\n\n return wallet;\n }\n\n getMultichainAccount({\n entropySource,\n groupIndex,\n }: {\n entropySource: EntropySourceId;\n groupIndex: number;\n }): MultichainAccount<InternalAccount> {\n const multichainAccount =\n this.#getWallet(entropySource).getMultichainAccount(groupIndex);\n\n if (!multichainAccount) {\n throw new Error(`No multichain account for index: ${groupIndex}`);\n }\n\n return multichainAccount;\n }\n\n getMultichainAccounts({\n entropySource,\n }: {\n entropySource: EntropySourceId;\n }): MultichainAccount<InternalAccount>[] {\n return this.#getWallet(entropySource).getMultichainAccounts();\n }\n\n async createNextMultichainAccount({\n entropySource,\n }: {\n entropySource: EntropySourceId;\n }): Promise<MultichainAccount<InternalAccount>> {\n return await this.#getWallet(entropySource).createNextMultichainAccount();\n }\n\n async discoverAndCreateMultichainAccounts({\n entropySource,\n }: {\n entropySource: EntropySourceId;\n }): Promise<MultichainAccount<InternalAccount>[]> {\n return await this.#getWallet(\n entropySource,\n ).discoverAndCreateMultichainAccounts();\n }\n}\n"]}
|
@@ -41,18 +41,13 @@ class EvmAccountProvider {
|
|
41
41
|
if (groupIndex !== accounts.length) {
|
42
42
|
throw new Error('Trying to create too many accounts');
|
43
43
|
}
|
44
|
-
// Create
|
45
|
-
|
46
|
-
// in `addAccounts`, so:
|
47
|
-
// - 1 means, 1 account -> index 0
|
48
|
-
// - 2 means, 2 accounts -> index 0 and 1
|
49
|
-
// - etc...
|
50
|
-
return await keyring.addAccounts(groupIndex + 1);
|
44
|
+
// Create next account (and returns their addresses).
|
45
|
+
return await keyring.addAccounts(1);
|
51
46
|
});
|
52
47
|
const account = __classPrivateFieldGet(this, _EvmAccountProvider_messenger, "f").call('AccountsController:getAccountByAddress', address);
|
53
48
|
// We MUST have the associated internal account.
|
54
49
|
assertInternalAccountExists(account);
|
55
|
-
return [account];
|
50
|
+
return [account.id];
|
56
51
|
}
|
57
52
|
async discoverAndCreateAccounts({ entropySource, groupIndex, }) {
|
58
53
|
// TODO: Move account discovery here (for EVM).
|
@@ -62,17 +57,18 @@ class EvmAccountProvider {
|
|
62
57
|
return [];
|
63
58
|
}
|
64
59
|
getAccounts({ entropySource, groupIndex, }) {
|
65
|
-
return __classPrivateFieldGet(this, _EvmAccountProvider_instances, "m", _EvmAccountProvider_getAccounts).call(this
|
60
|
+
return __classPrivateFieldGet(this, _EvmAccountProvider_instances, "m", _EvmAccountProvider_getAccounts).call(this, (account) => {
|
66
61
|
return (account.options.entropySource === entropySource &&
|
67
62
|
account.options.index === groupIndex);
|
68
|
-
});
|
63
|
+
}).map((account) => account.id);
|
69
64
|
}
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
65
|
+
getAccount(id) {
|
66
|
+
// TODO: Maybe just use a proper find for faster lookup?
|
67
|
+
const [found] = __classPrivateFieldGet(this, _EvmAccountProvider_instances, "m", _EvmAccountProvider_getAccounts).call(this, (account) => account.id === id);
|
68
|
+
if (!found) {
|
69
|
+
throw new Error(`Unable to find EVM account: ${id}`);
|
74
70
|
}
|
75
|
-
return
|
71
|
+
return found;
|
76
72
|
}
|
77
73
|
}
|
78
74
|
exports.EvmAccountProvider = EvmAccountProvider;
|
@@ -82,7 +78,7 @@ _EvmAccountProvider_messenger = new WeakMap(), _EvmAccountProvider_instances = n
|
|
82
78
|
metadata,
|
83
79
|
}));
|
84
80
|
return result;
|
85
|
-
}, _EvmAccountProvider_getAccounts = function _EvmAccountProvider_getAccounts() {
|
81
|
+
}, _EvmAccountProvider_getAccounts = function _EvmAccountProvider_getAccounts(filter = () => true) {
|
86
82
|
return __classPrivateFieldGet(this, _EvmAccountProvider_messenger, "f")
|
87
83
|
.call('AccountsController:listMultichainAccounts')
|
88
84
|
.filter((account) => {
|
@@ -101,7 +97,7 @@ _EvmAccountProvider_messenger = new WeakMap(), _EvmAccountProvider_instances = n
|
|
101
97
|
console.warn("! Found an HD account with no index: account won't be associated to its wallet.");
|
102
98
|
return false;
|
103
99
|
}
|
104
|
-
return
|
100
|
+
return filter(account);
|
105
101
|
}); // Safe, we did check for options fields during filtering.
|
106
102
|
};
|
107
103
|
//# 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":";;;;;;;;;;;;;;;AACA,uDAA6E;AAC7E,qEAIsC;AAStC,yEAAyE;AACzE,MAAM,eAAe,GAAG,CAAC,CAAC;AAS1B,+CAA+C;AAC/C,SAAS,2BAA2B,CAClC,OAAoC;IAEpC,IAAI,CAAC,OAAO,EAAE;QACZ,MAAM,IAAI,KAAK,CAAC,iCAAiC,CAAC,CAAC;KACpD;AACH,CAAC;AAED,MAAa,kBAAkB;IAG7B,YAAY,SAA+C;;QAFlD,gDAAiD;QAGxD,uBAAA,IAAI,iCAAc,SAAS,MAAA,CAAC;IAC9B,CAAC;IA4BD,KAAK,CAAC,cAAc,CAAC,EACnB,aAAa,EACb,UAAU,GAIX;QACC,MAAM,CAAC,OAAO,CAAC,GAAG,MAAM,uBAAA,IAAI,sEAAa,MAAjB,IAAI,EAC1B,EAAE,EAAE,EAAE,aAAa,EAAE,EACrB,KAAK,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE;YACpB,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC,WAAW,EAAE,CAAC;YAC7C,IAAI,UAAU,GAAG,QAAQ,CAAC,MAAM,EAAE;gBAChC,oEAAoE;gBACpE,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC,CAAC;aAC/B;YAED,iEAAiE;YACjE,wCAAwC;YACxC,IAAI,UAAU,KAAK,QAAQ,CAAC,MAAM,EAAE;gBAClC,MAAM,IAAI,KAAK,CAAC,oCAAoC,CAAC,CAAC;aACvD;YAED,qDAAqD;YACrD,OAAO,MAAM,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;QACtC,CAAC,CACF,CAAC;QAEF,MAAM,OAAO,GAAG,uBAAA,IAAI,qCAAW,CAAC,IAAI,CAClC,wCAAwC,EACxC,OAAO,CACR,CAAC;QAEF,gDAAgD;QAChD,2BAA2B,CAAC,OAAO,CAAC,CAAC;QAErC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;IACtB,CAAC;IAED,KAAK,CAAC,yBAAyB,CAAC,EAC9B,aAAa,EACb,UAAU,GAIX;QACC,+CAA+C;QAE/C,IAAI,UAAU,GAAG,eAAe,EAAE;YAChC,OAAO,MAAM,IAAI,CAAC,cAAc,CAAC,EAAE,aAAa,EAAE,UAAU,EAAE,CAAC,CAAC;SACjE;QACD,OAAO,EAAE,CAAC;IACZ,CAAC;IAoCD,WAAW,CAAC,EACV,aAAa,EACb,UAAU,GAIX;QACC,OAAO,uBAAA,IAAI,sEAAa,MAAjB,IAAI,EAAc,CAAC,OAAO,EAAE,EAAE;YACnC,OAAO,CACL,OAAO,CAAC,OAAO,CAAC,aAAa,KAAK,aAAa;gBAC/C,OAAO,CAAC,OAAO,CAAC,KAAK,KAAK,UAAU,CACrC,CAAC;QACJ,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;IAClC,CAAC;IAED,UAAU,CAAC,EAAa;QACtB,wDAAwD;QACxD,MAAM,CAAC,KAAK,CAAC,GAAG,uBAAA,IAAI,sEAAa,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,+BAA+B,EAAE,EAAE,CAAC,CAAC;SACtD;QAED,OAAO,KAAK,CAAC;IACf,CAAC;CACF;AAjJD,gDAiJC;gIA1IC,KAAK,0CAIH,QAAyB,EACzB,SAM6B;IAE7B,MAAM,MAAM,GAAG,MAAM,uBAAA,IAAI,qCAAW,CAAC,IAAI,CACvC,+BAA+B,EAC/B,QAAQ,EACR,CAAC,EAAE,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,CACxB,SAAS,CAAC;QACR,OAAO,EAAE,OAA0B;QACnC,QAAQ;KACT,CAAC,CACL,CAAC;IAEF,OAAO,MAAwB,CAAC;AAClC,CAAC,6EAwDC,SAAgD,GAAG,EAAE,CAAC,IAAI;IAE1D,OAAO,uBAAA,IAAI,qCAAW;SACnB,IAAI,CAAC,2CAA2C,CAAC;SACjD,MAAM,CAAC,CAAC,OAAO,EAAE,EAAE;QAClB,0DAA0D;QAC1D,IACE,OAAO,CAAC,IAAI,KAAK,4BAAc,CAAC,GAAG;YACnC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,KAAM,iCAAY,CAAC,EAAa,EAC7D;YACA,OAAO,KAAK,CAAC;SACd;QAED,iHAAiH;QACjH,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,aAAa,EAAE;YAClC,OAAO,CAAC,IAAI,CACV,0FAA0F,CAC3F,CAAC;YACF,OAAO,KAAK,CAAC;SACd;QAED,2DAA2D;QAC3D,IAAI,OAAO,CAAC,OAAO,CAAC,KAAK,KAAK,SAAS,EAAE;YACvC,OAAO,CAAC,IAAI,CACV,iFAAiF,CAClF,CAAC;YACF,OAAO,KAAK,CAAC;SACd;QAED,OAAO,MAAM,CAAC,OAAO,CAAC,CAAC;IACzB,CAAC,CAAyB,CAAC,CAAC,0DAA0D;AAC1F,CAAC","sourcesContent":["import type { AccountId } from '@metamask/accounts-controller';\nimport { EthAccountType, type EntropySourceId } from '@metamask/keyring-api';\nimport {\n KeyringTypes,\n type KeyringMetadata,\n type KeyringSelector,\n} from '@metamask/keyring-controller';\nimport type {\n EthKeyring,\n InternalAccount,\n} from '@metamask/keyring-internal-api';\nimport type { AccountProvider } from '@metamask/multichain-account-api';\n\nimport type { MultichainAccountControllerMessenger } from '../types';\n\n// Max index used by discovery (until we move the proper discovery here).\nconst MAX_GROUP_INDEX = 1;\n\ntype EoaInternalAccount = InternalAccount & {\n options: {\n index: number;\n entropySource: EntropySourceId;\n };\n};\n\n// eslint-disable-next-line jsdoc/require-jsdoc\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 implements AccountProvider<InternalAccount> {\n readonly #messenger: MultichainAccountControllerMessenger;\n\n constructor(messenger: MultichainAccountControllerMessenger) {\n this.#messenger = messenger;\n }\n\n async #withKeyring<\n SelectedKeyring extends EthKeyring = EthKeyring,\n CallbackResult = void,\n >(\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 async createAccounts({\n entropySource,\n groupIndex,\n }: {\n entropySource: EntropySourceId;\n groupIndex: number;\n }) {\n const [address] = await this.#withKeyring(\n { id: entropySource },\n async ({ keyring }) => {\n const accounts = await keyring.getAccounts();\n if (groupIndex < accounts.length) {\n // Nothing new to create, we just re-use the existing accounts here,\n return [accounts[groupIndex]];\n }\n\n // For now, we don't allow for gap, so if we need to create a new\n // account, this has to be the next one.\n if (groupIndex !== accounts.length) {\n throw new Error('Trying to create too many accounts');\n }\n\n // Create next account (and returns their addresses).\n return await keyring.addAccounts(1);\n },\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 return [account.id];\n }\n\n async discoverAndCreateAccounts({\n entropySource,\n groupIndex,\n }: {\n entropySource: EntropySourceId;\n groupIndex: number;\n }) {\n // TODO: Move account discovery here (for EVM).\n\n if (groupIndex < MAX_GROUP_INDEX) {\n return await this.createAccounts({ entropySource, groupIndex });\n }\n return [];\n }\n\n #getAccounts(\n filter: (account: InternalAccount) => boolean = () => true,\n ): EoaInternalAccount[] {\n return this.#messenger\n .call('AccountsController:listMultichainAccounts')\n .filter((account) => {\n // We only check for EOA accounts for multichain accounts.\n if (\n account.type !== EthAccountType.Eoa ||\n account.metadata.keyring.type !== (KeyringTypes.hd as string)\n ) {\n return false;\n }\n\n // TODO: Maybe use superstruct to validate the structure of HD account since they are not strongly-typed for now?\n if (!account.options.entropySource) {\n console.warn(\n \"! Found an HD account with no entropy source: account won't be associated to its wallet.\",\n );\n return false;\n }\n\n // TODO: We need to add this index for native accounts too!\n if (account.options.index === undefined) {\n console.warn(\n \"! Found an HD account with no index: account won't be associated to its wallet.\",\n );\n return false;\n }\n\n return filter(account);\n }) as EoaInternalAccount[]; // Safe, we did check for options fields during filtering.\n }\n\n getAccounts({\n entropySource,\n groupIndex,\n }: {\n entropySource: EntropySourceId;\n groupIndex: number;\n }): AccountId[] {\n return this.#getAccounts((account) => {\n return (\n account.options.entropySource === entropySource &&\n account.options.index === groupIndex\n );\n }).map((account) => account.id);\n }\n\n getAccount(id: AccountId): InternalAccount {\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 EVM account: ${id}`);\n }\n\n return found;\n }\n}\n"]}
|
@@ -1,64 +1,23 @@
|
|
1
|
+
import type { AccountId } from "@metamask/accounts-controller";
|
1
2
|
import { type EntropySourceId } from "@metamask/keyring-api";
|
2
3
|
import type { InternalAccount } from "@metamask/keyring-internal-api";
|
3
4
|
import type { AccountProvider } from "@metamask/multichain-account-api";
|
4
5
|
import type { MultichainAccountControllerMessenger } from "../types.cjs";
|
5
|
-
export declare class EvmAccountProvider implements AccountProvider {
|
6
|
+
export declare class EvmAccountProvider implements AccountProvider<InternalAccount> {
|
6
7
|
#private;
|
7
8
|
constructor(messenger: MultichainAccountControllerMessenger);
|
8
9
|
createAccounts({ entropySource, groupIndex, }: {
|
9
10
|
entropySource: EntropySourceId;
|
10
11
|
groupIndex: number;
|
11
|
-
}): Promise<
|
12
|
-
type: "eip155:eoa" | "eip155:erc4337" | "bip122:p2pkh" | "bip122:p2sh" | "bip122:p2wpkh" | "bip122:p2tr" | "solana:data-account";
|
13
|
-
id: string;
|
14
|
-
options: Record<string, import("@metamask/utils").Json>;
|
15
|
-
metadata: {
|
16
|
-
name: string;
|
17
|
-
importTime: number;
|
18
|
-
keyring: {
|
19
|
-
type: string;
|
20
|
-
};
|
21
|
-
nameLastUpdatedAt?: number | undefined;
|
22
|
-
snap?: {
|
23
|
-
name: string;
|
24
|
-
id: string;
|
25
|
-
enabled: boolean;
|
26
|
-
} | undefined;
|
27
|
-
lastSelected?: number | undefined;
|
28
|
-
};
|
29
|
-
address: string;
|
30
|
-
scopes: `${string}:${string}`[];
|
31
|
-
methods: string[];
|
32
|
-
}[]>;
|
12
|
+
}): Promise<string[]>;
|
33
13
|
discoverAndCreateAccounts({ entropySource, groupIndex, }: {
|
34
14
|
entropySource: EntropySourceId;
|
35
15
|
groupIndex: number;
|
36
|
-
}): Promise<
|
37
|
-
type: "eip155:eoa" | "eip155:erc4337" | "bip122:p2pkh" | "bip122:p2sh" | "bip122:p2wpkh" | "bip122:p2tr" | "solana:data-account";
|
38
|
-
id: string;
|
39
|
-
options: Record<string, import("@metamask/utils").Json>;
|
40
|
-
metadata: {
|
41
|
-
name: string;
|
42
|
-
importTime: number;
|
43
|
-
keyring: {
|
44
|
-
type: string;
|
45
|
-
};
|
46
|
-
nameLastUpdatedAt?: number | undefined;
|
47
|
-
snap?: {
|
48
|
-
name: string;
|
49
|
-
id: string;
|
50
|
-
enabled: boolean;
|
51
|
-
} | undefined;
|
52
|
-
lastSelected?: number | undefined;
|
53
|
-
};
|
54
|
-
address: string;
|
55
|
-
scopes: `${string}:${string}`[];
|
56
|
-
methods: string[];
|
57
|
-
}[]>;
|
16
|
+
}): Promise<string[]>;
|
58
17
|
getAccounts({ entropySource, groupIndex, }: {
|
59
18
|
entropySource: EntropySourceId;
|
60
19
|
groupIndex: number;
|
61
|
-
}):
|
62
|
-
|
20
|
+
}): AccountId[];
|
21
|
+
getAccount(id: AccountId): InternalAccount;
|
63
22
|
}
|
64
23
|
//# sourceMappingURL=EvmAccountProvider.d.cts.map
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"EvmAccountProvider.d.cts","sourceRoot":"","sources":["../../src/providers/EvmAccountProvider.ts"],"names":[],"mappings":"AAAA,OAAO,EAAkB,KAAK,eAAe,EAAE,8BAA8B;AAM7E,OAAO,KAAK,EAEV,eAAe,EAChB,uCAAuC;AACxC,OAAO,KAAK,EAAE,eAAe,EAAE,yCAAyC;AAExE,OAAO,KAAK,EAAE,oCAAoC,EAAE,qBAAiB;AAqBrE,qBAAa,kBAAmB,YAAW,eAAe;;
|
1
|
+
{"version":3,"file":"EvmAccountProvider.d.cts","sourceRoot":"","sources":["../../src/providers/EvmAccountProvider.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,sCAAsC;AAC/D,OAAO,EAAkB,KAAK,eAAe,EAAE,8BAA8B;AAM7E,OAAO,KAAK,EAEV,eAAe,EAChB,uCAAuC;AACxC,OAAO,KAAK,EAAE,eAAe,EAAE,yCAAyC;AAExE,OAAO,KAAK,EAAE,oCAAoC,EAAE,qBAAiB;AAqBrE,qBAAa,kBAAmB,YAAW,eAAe,CAAC,eAAe,CAAC;;gBAG7D,SAAS,EAAE,oCAAoC;IA8BrD,cAAc,CAAC,EACnB,aAAa,EACb,UAAU,GACX,EAAE;QACD,aAAa,EAAE,eAAe,CAAC;QAC/B,UAAU,EAAE,MAAM,CAAC;KACpB;IAgCK,yBAAyB,CAAC,EAC9B,aAAa,EACb,UAAU,GACX,EAAE;QACD,aAAa,EAAE,eAAe,CAAC;QAC/B,UAAU,EAAE,MAAM,CAAC;KACpB;IA2CD,WAAW,CAAC,EACV,aAAa,EACb,UAAU,GACX,EAAE;QACD,aAAa,EAAE,eAAe,CAAC;QAC/B,UAAU,EAAE,MAAM,CAAC;KACpB,GAAG,SAAS,EAAE;IASf,UAAU,CAAC,EAAE,EAAE,SAAS,GAAG,eAAe;CAU3C"}
|
@@ -1,64 +1,23 @@
|
|
1
|
+
import type { AccountId } from "@metamask/accounts-controller";
|
1
2
|
import { type EntropySourceId } from "@metamask/keyring-api";
|
2
3
|
import type { InternalAccount } from "@metamask/keyring-internal-api";
|
3
4
|
import type { AccountProvider } from "@metamask/multichain-account-api";
|
4
5
|
import type { MultichainAccountControllerMessenger } from "../types.mjs";
|
5
|
-
export declare class EvmAccountProvider implements AccountProvider {
|
6
|
+
export declare class EvmAccountProvider implements AccountProvider<InternalAccount> {
|
6
7
|
#private;
|
7
8
|
constructor(messenger: MultichainAccountControllerMessenger);
|
8
9
|
createAccounts({ entropySource, groupIndex, }: {
|
9
10
|
entropySource: EntropySourceId;
|
10
11
|
groupIndex: number;
|
11
|
-
}): Promise<
|
12
|
-
type: "eip155:eoa" | "eip155:erc4337" | "bip122:p2pkh" | "bip122:p2sh" | "bip122:p2wpkh" | "bip122:p2tr" | "solana:data-account";
|
13
|
-
id: string;
|
14
|
-
options: Record<string, import("@metamask/utils").Json>;
|
15
|
-
metadata: {
|
16
|
-
name: string;
|
17
|
-
importTime: number;
|
18
|
-
keyring: {
|
19
|
-
type: string;
|
20
|
-
};
|
21
|
-
nameLastUpdatedAt?: number | undefined;
|
22
|
-
snap?: {
|
23
|
-
name: string;
|
24
|
-
id: string;
|
25
|
-
enabled: boolean;
|
26
|
-
} | undefined;
|
27
|
-
lastSelected?: number | undefined;
|
28
|
-
};
|
29
|
-
address: string;
|
30
|
-
scopes: `${string}:${string}`[];
|
31
|
-
methods: string[];
|
32
|
-
}[]>;
|
12
|
+
}): Promise<string[]>;
|
33
13
|
discoverAndCreateAccounts({ entropySource, groupIndex, }: {
|
34
14
|
entropySource: EntropySourceId;
|
35
15
|
groupIndex: number;
|
36
|
-
}): Promise<
|
37
|
-
type: "eip155:eoa" | "eip155:erc4337" | "bip122:p2pkh" | "bip122:p2sh" | "bip122:p2wpkh" | "bip122:p2tr" | "solana:data-account";
|
38
|
-
id: string;
|
39
|
-
options: Record<string, import("@metamask/utils").Json>;
|
40
|
-
metadata: {
|
41
|
-
name: string;
|
42
|
-
importTime: number;
|
43
|
-
keyring: {
|
44
|
-
type: string;
|
45
|
-
};
|
46
|
-
nameLastUpdatedAt?: number | undefined;
|
47
|
-
snap?: {
|
48
|
-
name: string;
|
49
|
-
id: string;
|
50
|
-
enabled: boolean;
|
51
|
-
} | undefined;
|
52
|
-
lastSelected?: number | undefined;
|
53
|
-
};
|
54
|
-
address: string;
|
55
|
-
scopes: `${string}:${string}`[];
|
56
|
-
methods: string[];
|
57
|
-
}[]>;
|
16
|
+
}): Promise<string[]>;
|
58
17
|
getAccounts({ entropySource, groupIndex, }: {
|
59
18
|
entropySource: EntropySourceId;
|
60
19
|
groupIndex: number;
|
61
|
-
}):
|
62
|
-
|
20
|
+
}): AccountId[];
|
21
|
+
getAccount(id: AccountId): InternalAccount;
|
63
22
|
}
|
64
23
|
//# sourceMappingURL=EvmAccountProvider.d.mts.map
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"EvmAccountProvider.d.mts","sourceRoot":"","sources":["../../src/providers/EvmAccountProvider.ts"],"names":[],"mappings":"AAAA,OAAO,EAAkB,KAAK,eAAe,EAAE,8BAA8B;AAM7E,OAAO,KAAK,EAEV,eAAe,EAChB,uCAAuC;AACxC,OAAO,KAAK,EAAE,eAAe,EAAE,yCAAyC;AAExE,OAAO,KAAK,EAAE,oCAAoC,EAAE,qBAAiB;AAqBrE,qBAAa,kBAAmB,YAAW,eAAe;;
|
1
|
+
{"version":3,"file":"EvmAccountProvider.d.mts","sourceRoot":"","sources":["../../src/providers/EvmAccountProvider.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,sCAAsC;AAC/D,OAAO,EAAkB,KAAK,eAAe,EAAE,8BAA8B;AAM7E,OAAO,KAAK,EAEV,eAAe,EAChB,uCAAuC;AACxC,OAAO,KAAK,EAAE,eAAe,EAAE,yCAAyC;AAExE,OAAO,KAAK,EAAE,oCAAoC,EAAE,qBAAiB;AAqBrE,qBAAa,kBAAmB,YAAW,eAAe,CAAC,eAAe,CAAC;;gBAG7D,SAAS,EAAE,oCAAoC;IA8BrD,cAAc,CAAC,EACnB,aAAa,EACb,UAAU,GACX,EAAE;QACD,aAAa,EAAE,eAAe,CAAC;QAC/B,UAAU,EAAE,MAAM,CAAC;KACpB;IAgCK,yBAAyB,CAAC,EAC9B,aAAa,EACb,UAAU,GACX,EAAE;QACD,aAAa,EAAE,eAAe,CAAC;QAC/B,UAAU,EAAE,MAAM,CAAC;KACpB;IA2CD,WAAW,CAAC,EACV,aAAa,EACb,UAAU,GACX,EAAE;QACD,aAAa,EAAE,eAAe,CAAC;QAC/B,UAAU,EAAE,MAAM,CAAC;KACpB,GAAG,SAAS,EAAE;IASf,UAAU,CAAC,EAAE,EAAE,SAAS,GAAG,eAAe;CAU3C"}
|
@@ -38,18 +38,13 @@ export class EvmAccountProvider {
|
|
38
38
|
if (groupIndex !== accounts.length) {
|
39
39
|
throw new Error('Trying to create too many accounts');
|
40
40
|
}
|
41
|
-
// Create
|
42
|
-
|
43
|
-
// in `addAccounts`, so:
|
44
|
-
// - 1 means, 1 account -> index 0
|
45
|
-
// - 2 means, 2 accounts -> index 0 and 1
|
46
|
-
// - etc...
|
47
|
-
return await keyring.addAccounts(groupIndex + 1);
|
41
|
+
// Create next account (and returns their addresses).
|
42
|
+
return await keyring.addAccounts(1);
|
48
43
|
});
|
49
44
|
const account = __classPrivateFieldGet(this, _EvmAccountProvider_messenger, "f").call('AccountsController:getAccountByAddress', address);
|
50
45
|
// We MUST have the associated internal account.
|
51
46
|
assertInternalAccountExists(account);
|
52
|
-
return [account];
|
47
|
+
return [account.id];
|
53
48
|
}
|
54
49
|
async discoverAndCreateAccounts({ entropySource, groupIndex, }) {
|
55
50
|
// TODO: Move account discovery here (for EVM).
|
@@ -59,17 +54,18 @@ export class EvmAccountProvider {
|
|
59
54
|
return [];
|
60
55
|
}
|
61
56
|
getAccounts({ entropySource, groupIndex, }) {
|
62
|
-
return __classPrivateFieldGet(this, _EvmAccountProvider_instances, "m", _EvmAccountProvider_getAccounts).call(this
|
57
|
+
return __classPrivateFieldGet(this, _EvmAccountProvider_instances, "m", _EvmAccountProvider_getAccounts).call(this, (account) => {
|
63
58
|
return (account.options.entropySource === entropySource &&
|
64
59
|
account.options.index === groupIndex);
|
65
|
-
});
|
60
|
+
}).map((account) => account.id);
|
66
61
|
}
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
62
|
+
getAccount(id) {
|
63
|
+
// TODO: Maybe just use a proper find for faster lookup?
|
64
|
+
const [found] = __classPrivateFieldGet(this, _EvmAccountProvider_instances, "m", _EvmAccountProvider_getAccounts).call(this, (account) => account.id === id);
|
65
|
+
if (!found) {
|
66
|
+
throw new Error(`Unable to find EVM account: ${id}`);
|
71
67
|
}
|
72
|
-
return
|
68
|
+
return found;
|
73
69
|
}
|
74
70
|
}
|
75
71
|
_EvmAccountProvider_messenger = new WeakMap(), _EvmAccountProvider_instances = new WeakSet(), _EvmAccountProvider_withKeyring = async function _EvmAccountProvider_withKeyring(selector, operation) {
|
@@ -78,7 +74,7 @@ _EvmAccountProvider_messenger = new WeakMap(), _EvmAccountProvider_instances = n
|
|
78
74
|
metadata,
|
79
75
|
}));
|
80
76
|
return result;
|
81
|
-
}, _EvmAccountProvider_getAccounts = function _EvmAccountProvider_getAccounts() {
|
77
|
+
}, _EvmAccountProvider_getAccounts = function _EvmAccountProvider_getAccounts(filter = () => true) {
|
82
78
|
return __classPrivateFieldGet(this, _EvmAccountProvider_messenger, "f")
|
83
79
|
.call('AccountsController:listMultichainAccounts')
|
84
80
|
.filter((account) => {
|
@@ -97,7 +93,7 @@ _EvmAccountProvider_messenger = new WeakMap(), _EvmAccountProvider_instances = n
|
|
97
93
|
console.warn("! Found an HD account with no index: account won't be associated to its wallet.");
|
98
94
|
return false;
|
99
95
|
}
|
100
|
-
return
|
96
|
+
return filter(account);
|
101
97
|
}); // Safe, we did check for options fields during filtering.
|
102
98
|
};
|
103
99
|
//# sourceMappingURL=EvmAccountProvider.mjs.map
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"EvmAccountProvider.mjs","sourceRoot":"","sources":["../../src/providers/EvmAccountProvider.ts"],"names":[],"mappings":";;;;;;;;;;;;
|
1
|
+
{"version":3,"file":"EvmAccountProvider.mjs","sourceRoot":"","sources":["../../src/providers/EvmAccountProvider.ts"],"names":[],"mappings":";;;;;;;;;;;;AACA,OAAO,EAAE,cAAc,EAAwB,8BAA8B;AAC7E,OAAO,EACL,YAAY,EAGb,qCAAqC;AAStC,yEAAyE;AACzE,MAAM,eAAe,GAAG,CAAC,CAAC;AAS1B,+CAA+C;AAC/C,SAAS,2BAA2B,CAClC,OAAoC;IAEpC,IAAI,CAAC,OAAO,EAAE;QACZ,MAAM,IAAI,KAAK,CAAC,iCAAiC,CAAC,CAAC;KACpD;AACH,CAAC;AAED,MAAM,OAAO,kBAAkB;IAG7B,YAAY,SAA+C;;QAFlD,gDAAiD;QAGxD,uBAAA,IAAI,iCAAc,SAAS,MAAA,CAAC;IAC9B,CAAC;IA4BD,KAAK,CAAC,cAAc,CAAC,EACnB,aAAa,EACb,UAAU,GAIX;QACC,MAAM,CAAC,OAAO,CAAC,GAAG,MAAM,uBAAA,IAAI,sEAAa,MAAjB,IAAI,EAC1B,EAAE,EAAE,EAAE,aAAa,EAAE,EACrB,KAAK,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE;YACpB,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC,WAAW,EAAE,CAAC;YAC7C,IAAI,UAAU,GAAG,QAAQ,CAAC,MAAM,EAAE;gBAChC,oEAAoE;gBACpE,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC,CAAC;aAC/B;YAED,iEAAiE;YACjE,wCAAwC;YACxC,IAAI,UAAU,KAAK,QAAQ,CAAC,MAAM,EAAE;gBAClC,MAAM,IAAI,KAAK,CAAC,oCAAoC,CAAC,CAAC;aACvD;YAED,qDAAqD;YACrD,OAAO,MAAM,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;QACtC,CAAC,CACF,CAAC;QAEF,MAAM,OAAO,GAAG,uBAAA,IAAI,qCAAW,CAAC,IAAI,CAClC,wCAAwC,EACxC,OAAO,CACR,CAAC;QAEF,gDAAgD;QAChD,2BAA2B,CAAC,OAAO,CAAC,CAAC;QAErC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;IACtB,CAAC;IAED,KAAK,CAAC,yBAAyB,CAAC,EAC9B,aAAa,EACb,UAAU,GAIX;QACC,+CAA+C;QAE/C,IAAI,UAAU,GAAG,eAAe,EAAE;YAChC,OAAO,MAAM,IAAI,CAAC,cAAc,CAAC,EAAE,aAAa,EAAE,UAAU,EAAE,CAAC,CAAC;SACjE;QACD,OAAO,EAAE,CAAC;IACZ,CAAC;IAoCD,WAAW,CAAC,EACV,aAAa,EACb,UAAU,GAIX;QACC,OAAO,uBAAA,IAAI,sEAAa,MAAjB,IAAI,EAAc,CAAC,OAAO,EAAE,EAAE;YACnC,OAAO,CACL,OAAO,CAAC,OAAO,CAAC,aAAa,KAAK,aAAa;gBAC/C,OAAO,CAAC,OAAO,CAAC,KAAK,KAAK,UAAU,CACrC,CAAC;QACJ,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;IAClC,CAAC;IAED,UAAU,CAAC,EAAa;QACtB,wDAAwD;QACxD,MAAM,CAAC,KAAK,CAAC,GAAG,uBAAA,IAAI,sEAAa,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,+BAA+B,EAAE,EAAE,CAAC,CAAC;SACtD;QAED,OAAO,KAAK,CAAC;IACf,CAAC;CACF;gIA1IC,KAAK,0CAIH,QAAyB,EACzB,SAM6B;IAE7B,MAAM,MAAM,GAAG,MAAM,uBAAA,IAAI,qCAAW,CAAC,IAAI,CACvC,+BAA+B,EAC/B,QAAQ,EACR,CAAC,EAAE,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,CACxB,SAAS,CAAC;QACR,OAAO,EAAE,OAA0B;QACnC,QAAQ;KACT,CAAC,CACL,CAAC;IAEF,OAAO,MAAwB,CAAC;AAClC,CAAC,6EAwDC,SAAgD,GAAG,EAAE,CAAC,IAAI;IAE1D,OAAO,uBAAA,IAAI,qCAAW;SACnB,IAAI,CAAC,2CAA2C,CAAC;SACjD,MAAM,CAAC,CAAC,OAAO,EAAE,EAAE;QAClB,0DAA0D;QAC1D,IACE,OAAO,CAAC,IAAI,KAAK,cAAc,CAAC,GAAG;YACnC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,KAAM,YAAY,CAAC,EAAa,EAC7D;YACA,OAAO,KAAK,CAAC;SACd;QAED,iHAAiH;QACjH,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,aAAa,EAAE;YAClC,OAAO,CAAC,IAAI,CACV,0FAA0F,CAC3F,CAAC;YACF,OAAO,KAAK,CAAC;SACd;QAED,2DAA2D;QAC3D,IAAI,OAAO,CAAC,OAAO,CAAC,KAAK,KAAK,SAAS,EAAE;YACvC,OAAO,CAAC,IAAI,CACV,iFAAiF,CAClF,CAAC;YACF,OAAO,KAAK,CAAC;SACd;QAED,OAAO,MAAM,CAAC,OAAO,CAAC,CAAC;IACzB,CAAC,CAAyB,CAAC,CAAC,0DAA0D;AAC1F,CAAC","sourcesContent":["import type { AccountId } from '@metamask/accounts-controller';\nimport { EthAccountType, type EntropySourceId } from '@metamask/keyring-api';\nimport {\n KeyringTypes,\n type KeyringMetadata,\n type KeyringSelector,\n} from '@metamask/keyring-controller';\nimport type {\n EthKeyring,\n InternalAccount,\n} from '@metamask/keyring-internal-api';\nimport type { AccountProvider } from '@metamask/multichain-account-api';\n\nimport type { MultichainAccountControllerMessenger } from '../types';\n\n// Max index used by discovery (until we move the proper discovery here).\nconst MAX_GROUP_INDEX = 1;\n\ntype EoaInternalAccount = InternalAccount & {\n options: {\n index: number;\n entropySource: EntropySourceId;\n };\n};\n\n// eslint-disable-next-line jsdoc/require-jsdoc\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 implements AccountProvider<InternalAccount> {\n readonly #messenger: MultichainAccountControllerMessenger;\n\n constructor(messenger: MultichainAccountControllerMessenger) {\n this.#messenger = messenger;\n }\n\n async #withKeyring<\n SelectedKeyring extends EthKeyring = EthKeyring,\n CallbackResult = void,\n >(\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 async createAccounts({\n entropySource,\n groupIndex,\n }: {\n entropySource: EntropySourceId;\n groupIndex: number;\n }) {\n const [address] = await this.#withKeyring(\n { id: entropySource },\n async ({ keyring }) => {\n const accounts = await keyring.getAccounts();\n if (groupIndex < accounts.length) {\n // Nothing new to create, we just re-use the existing accounts here,\n return [accounts[groupIndex]];\n }\n\n // For now, we don't allow for gap, so if we need to create a new\n // account, this has to be the next one.\n if (groupIndex !== accounts.length) {\n throw new Error('Trying to create too many accounts');\n }\n\n // Create next account (and returns their addresses).\n return await keyring.addAccounts(1);\n },\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 return [account.id];\n }\n\n async discoverAndCreateAccounts({\n entropySource,\n groupIndex,\n }: {\n entropySource: EntropySourceId;\n groupIndex: number;\n }) {\n // TODO: Move account discovery here (for EVM).\n\n if (groupIndex < MAX_GROUP_INDEX) {\n return await this.createAccounts({ entropySource, groupIndex });\n }\n return [];\n }\n\n #getAccounts(\n filter: (account: InternalAccount) => boolean = () => true,\n ): EoaInternalAccount[] {\n return this.#messenger\n .call('AccountsController:listMultichainAccounts')\n .filter((account) => {\n // We only check for EOA accounts for multichain accounts.\n if (\n account.type !== EthAccountType.Eoa ||\n account.metadata.keyring.type !== (KeyringTypes.hd as string)\n ) {\n return false;\n }\n\n // TODO: Maybe use superstruct to validate the structure of HD account since they are not strongly-typed for now?\n if (!account.options.entropySource) {\n console.warn(\n \"! Found an HD account with no entropy source: account won't be associated to its wallet.\",\n );\n return false;\n }\n\n // TODO: We need to add this index for native accounts too!\n if (account.options.index === undefined) {\n console.warn(\n \"! Found an HD account with no index: account won't be associated to its wallet.\",\n );\n return false;\n }\n\n return filter(account);\n }) as EoaInternalAccount[]; // Safe, we did check for options fields during filtering.\n }\n\n getAccounts({\n entropySource,\n groupIndex,\n }: {\n entropySource: EntropySourceId;\n groupIndex: number;\n }): AccountId[] {\n return this.#getAccounts((account) => {\n return (\n account.options.entropySource === entropySource &&\n account.options.index === groupIndex\n );\n }).map((account) => account.id);\n }\n\n getAccount(id: AccountId): InternalAccount {\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 EVM account: ${id}`);\n }\n\n return found;\n }\n}\n"]}
|
@@ -17,12 +17,6 @@ const keyring_api_1 = require("@metamask/keyring-api");
|
|
17
17
|
const keyring_controller_1 = require("@metamask/keyring-controller");
|
18
18
|
const keyring_snap_client_1 = require("@metamask/keyring-snap-client");
|
19
19
|
const snaps_utils_1 = require("@metamask/snaps-utils");
|
20
|
-
// eslint-disable-next-line jsdoc/require-jsdoc
|
21
|
-
function assertInternalAccountExists(account) {
|
22
|
-
if (!account) {
|
23
|
-
throw new Error('Internal account does not exist');
|
24
|
-
}
|
25
|
-
}
|
26
20
|
const SOLANA_SNAP_ID = 'npm:@metamask/solana-wallet-snap';
|
27
21
|
class SolAccountProvider {
|
28
22
|
constructor(messenger) {
|
@@ -34,28 +28,31 @@ class SolAccountProvider {
|
|
34
28
|
__classPrivateFieldSet(this, _SolAccountProvider_client, __classPrivateFieldGet(this, _SolAccountProvider_instances, "m", _SolAccountProvider_getKeyringClientFromSnapId).call(this, SOLANA_SNAP_ID), "f");
|
35
29
|
}
|
36
30
|
async createAccounts({ entropySource, groupIndex, }) {
|
37
|
-
const
|
31
|
+
const id = await __classPrivateFieldGet(this, _SolAccountProvider_instances, "m", _SolAccountProvider_createAccount).call(this, {
|
38
32
|
entropySource,
|
39
33
|
derivationPath: `m/44'/501'/${groupIndex}'/0'`,
|
40
34
|
});
|
41
|
-
return [
|
35
|
+
return [id];
|
42
36
|
}
|
43
37
|
async discoverAndCreateAccounts({ entropySource, groupIndex, }) {
|
44
38
|
const discoveredAccounts = await __classPrivateFieldGet(this, _SolAccountProvider_client, "f").discoverAccounts([keyring_api_1.SolScope.Mainnet, keyring_api_1.SolScope.Testnet], entropySource, groupIndex);
|
45
39
|
return await Promise.all(discoveredAccounts.map(async ({ derivationPath }) => await __classPrivateFieldGet(this, _SolAccountProvider_instances, "m", _SolAccountProvider_createAccount).call(this, { entropySource, derivationPath })));
|
46
40
|
}
|
47
41
|
getAccounts({ entropySource, groupIndex, }) {
|
48
|
-
return __classPrivateFieldGet(this, _SolAccountProvider_instances, "m", _SolAccountProvider_getAccounts).call(this)
|
42
|
+
return __classPrivateFieldGet(this, _SolAccountProvider_instances, "m", _SolAccountProvider_getAccounts).call(this)
|
43
|
+
.filter((account) => {
|
49
44
|
return (account.options.entropySource === entropySource &&
|
50
45
|
account.options.index === groupIndex);
|
51
|
-
})
|
46
|
+
})
|
47
|
+
.map((account) => account.id);
|
52
48
|
}
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
49
|
+
getAccount(id) {
|
50
|
+
// TODO: Maybe just use a proper find for faster lookup?
|
51
|
+
const [found] = __classPrivateFieldGet(this, _SolAccountProvider_instances, "m", _SolAccountProvider_getAccounts).call(this, (account) => account.id === id);
|
52
|
+
if (!found) {
|
53
|
+
throw new Error(`Unable to find Solana account: ${id}`);
|
57
54
|
}
|
58
|
-
return
|
55
|
+
return found;
|
59
56
|
}
|
60
57
|
}
|
61
58
|
exports.SolAccountProvider = SolAccountProvider;
|
@@ -90,29 +87,8 @@ _SolAccountProvider_messenger = new WeakMap(), _SolAccountProvider_client = new
|
|
90
87
|
displayConfirmation: false,
|
91
88
|
setSelectedAccount: false,
|
92
89
|
});
|
93
|
-
|
94
|
-
|
95
|
-
// right away. For now we just re-create a fake `InternalAccount` and
|
96
|
-
// we might have to rely solely on `account.id`.
|
97
|
-
// Actually get the associated `InternalAccount`.
|
98
|
-
// const account = this.#messenger.call(
|
99
|
-
// 'AccountsController:getAccount',
|
100
|
-
// keyringAccount.id,
|
101
|
-
// );
|
102
|
-
const account = {
|
103
|
-
...keyringAccount,
|
104
|
-
metadata: {
|
105
|
-
name: `Solana account -- ${keyringAccount.options.index}`,
|
106
|
-
importTime: 0,
|
107
|
-
keyring: {
|
108
|
-
type: keyring_controller_1.KeyringTypes.snap,
|
109
|
-
},
|
110
|
-
},
|
111
|
-
};
|
112
|
-
// We MUST have the associated internal account.
|
113
|
-
assertInternalAccountExists(account);
|
114
|
-
return account;
|
115
|
-
}, _SolAccountProvider_getAccounts = function _SolAccountProvider_getAccounts() {
|
90
|
+
return keyringAccount.id;
|
91
|
+
}, _SolAccountProvider_getAccounts = function _SolAccountProvider_getAccounts(filter = () => true) {
|
116
92
|
return __classPrivateFieldGet(this, _SolAccountProvider_messenger, "f")
|
117
93
|
.call('AccountsController:listMultichainAccounts')
|
118
94
|
.filter((account) => {
|
@@ -131,7 +107,7 @@ _SolAccountProvider_messenger = new WeakMap(), _SolAccountProvider_client = new
|
|
131
107
|
console.warn("! Found a Solana account with no index: account won't be associated to its wallet.");
|
132
108
|
return false;
|
133
109
|
}
|
134
|
-
return
|
110
|
+
return filter(account);
|
135
111
|
}); // Safe, we did check for options fields during filtering.
|
136
112
|
};
|
137
113
|
//# sourceMappingURL=SolAccountProvider.cjs.map
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"SolAccountProvider.cjs","sourceRoot":"","sources":["../../src/providers/SolAccountProvider.ts"],"names":[],"mappings":"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","sourcesContent":["import type { SnapKeyring } from '@metamask/eth-snap-keyring';\nimport {\n SolAccountType,\n SolScope,\n type EntropySourceId,\n} from '@metamask/keyring-api';\nimport type {\n KeyringMetadata,\n KeyringSelector,\n} from '@metamask/keyring-controller';\nimport { KeyringTypes } from '@metamask/keyring-controller';\nimport type {\n EthKeyring,\n InternalAccount,\n} from '@metamask/keyring-internal-api';\nimport { KeyringClient } from '@metamask/keyring-snap-client';\nimport type { AccountProvider } from '@metamask/multichain-account-api';\nimport type { SnapId } from '@metamask/snaps-sdk';\nimport { HandlerType } from '@metamask/snaps-utils';\nimport type { Json, JsonRpcRequest } from '@metamask/utils';\n\nimport type { MultichainAccountControllerMessenger } from '../types';\n\ntype SolInternalAccount = InternalAccount & {\n options: {\n index: number;\n entropySource: EntropySourceId;\n };\n};\n\n// eslint-disable-next-line jsdoc/require-jsdoc\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\nconst SOLANA_SNAP_ID = 'npm:@metamask/solana-wallet-snap' as SnapId;\nexport class SolAccountProvider implements AccountProvider {\n readonly #messenger: MultichainAccountControllerMessenger;\n\n readonly #client: KeyringClient;\n\n constructor(messenger: MultichainAccountControllerMessenger) {\n this.#messenger = messenger;\n\n // TODO: Change this once we introduce 1 Snap keyring per Snaps.\n this.#client = this.#getKeyringClientFromSnapId(SOLANA_SNAP_ID);\n }\n\n 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 #getKeyringClientFromSnapId(snapId: string): KeyringClient {\n return new KeyringClient({\n send: async (request: JsonRpcRequest) => {\n const response = await this.#messenger.call(\n 'SnapController:handleRequest',\n {\n snapId: snapId as SnapId,\n origin: 'metamask',\n handler: HandlerType.OnKeyringRequest,\n request,\n },\n );\n return response as Promise<Json>;\n },\n });\n }\n\n async #createAccount(opts: {\n entropySource: EntropySourceId;\n derivationPath: `m/${string}`;\n }) {\n // NOTE: We're not supposed to make the keyring instance escape `withKeyring` but\n // we have to use the `SnapKeyring` instance to be able to create Solana account\n // without triggering UI confirmation.\n // Also, creating account that way won't invalidate the snap keyring state. The\n // account will get created and persisted properly with the Snap account creation\n // flow \"asynchronously\" (with `notify:accountCreated`).\n const createAccount = await this.#withKeyring<\n SnapKeyring,\n SnapKeyring['createAccount']\n >({ type: KeyringTypes.snap }, async ({ keyring }) =>\n keyring.createAccount.bind(keyring),\n );\n\n const keyringAccount = await createAccount(SOLANA_SNAP_ID, opts, {\n displayAccountNameSuggestion: false,\n displayConfirmation: false,\n setSelectedAccount: false,\n });\n\n // FIXME: This part of the flow is truly async, so when the `KeyringClient`\n // returns the `KeyringAccount`, its `InternalAccount` won't be \"ready\"\n // right away. For now we just re-create a fake `InternalAccount` and\n // we might have to rely solely on `account.id`.\n\n // Actually get the associated `InternalAccount`.\n // const account = this.#messenger.call(\n // 'AccountsController:getAccount',\n // keyringAccount.id,\n // );\n\n const account: InternalAccount = {\n ...keyringAccount,\n metadata: {\n name: `Solana account -- ${keyringAccount.options.index}`,\n importTime: 0,\n keyring: {\n type: KeyringTypes.snap,\n },\n },\n };\n\n // We MUST have the associated internal account.\n assertInternalAccountExists(account);\n\n return account;\n }\n\n async createAccounts({\n entropySource,\n groupIndex,\n }: {\n entropySource: EntropySourceId;\n groupIndex: number;\n }) {\n const account = await this.#createAccount({\n entropySource,\n derivationPath: `m/44'/501'/${groupIndex}'/0'`,\n });\n\n return [account];\n }\n\n async discoverAndCreateAccounts({\n entropySource,\n groupIndex,\n }: {\n entropySource: EntropySourceId;\n groupIndex: number;\n }) {\n const discoveredAccounts = await this.#client.discoverAccounts(\n [SolScope.Mainnet, SolScope.Testnet],\n entropySource,\n groupIndex,\n );\n\n return await Promise.all(\n discoveredAccounts.map(\n async ({ derivationPath }) =>\n await this.#createAccount({ entropySource, derivationPath }),\n ),\n );\n }\n\n #getAccounts(): SolInternalAccount[] {\n return this.#messenger\n .call('AccountsController:listMultichainAccounts')\n .filter((account) => {\n // We only check for EOA accounts for multichain accounts.\n if (\n account.type !== SolAccountType.DataAccount ||\n account.metadata.keyring.type !== (KeyringTypes.snap as string)\n ) {\n return false;\n }\n\n // TODO: Maybe use superstruct to validate the structure of HD account since they are not strongly-typed for now?\n if (!account.options.entropySource) {\n console.warn(\n \"! Found a Solana account with no entropy source: account won't be associated to its wallet.\",\n );\n return false;\n }\n\n // TODO: We need to add this index for native accounts too!\n if (account.options.index === undefined) {\n console.warn(\n \"! Found a Solana account with no index: account won't be associated to its wallet.\",\n );\n return false;\n }\n\n return true;\n }) as SolInternalAccount[]; // Safe, we did check for options fields during filtering.\n }\n\n getAccounts({\n entropySource,\n groupIndex,\n }: {\n entropySource: EntropySourceId;\n groupIndex: number;\n }): InternalAccount[] {\n return this.#getAccounts().filter((account) => {\n return (\n account.options.entropySource === entropySource &&\n account.options.index === groupIndex\n );\n });\n }\n\n getEntropySources(): EntropySourceId[] {\n const entropySources = new Set<EntropySourceId>();\n\n for (const account of this.#getAccounts()) {\n entropySources.add(account.options.entropySource);\n }\n\n return Array.from(entropySources);\n }\n}\n"]}
|
1
|
+
{"version":3,"file":"SolAccountProvider.cjs","sourceRoot":"","sources":["../../src/providers/SolAccountProvider.ts"],"names":[],"mappings":"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","sourcesContent":["import type { AccountId } from '@metamask/accounts-controller';\nimport type { SnapKeyring } from '@metamask/eth-snap-keyring';\nimport {\n SolAccountType,\n SolScope,\n type EntropySourceId,\n} from '@metamask/keyring-api';\nimport type {\n KeyringMetadata,\n KeyringSelector,\n} from '@metamask/keyring-controller';\nimport { KeyringTypes } from '@metamask/keyring-controller';\nimport type { InternalAccount } from '@metamask/keyring-internal-api';\nimport { KeyringClient } from '@metamask/keyring-snap-client';\nimport type { AccountProvider } from '@metamask/multichain-account-api';\nimport type { SnapId } from '@metamask/snaps-sdk';\nimport { HandlerType } from '@metamask/snaps-utils';\nimport type { Json, JsonRpcRequest } from '@metamask/utils';\n\nimport type { MultichainAccountControllerMessenger } from '../types';\n\ntype SolInternalAccount = InternalAccount & {\n options: {\n index: number;\n entropySource: EntropySourceId;\n };\n};\n\nconst SOLANA_SNAP_ID = 'npm:@metamask/solana-wallet-snap' as SnapId;\n\nexport class SolAccountProvider implements AccountProvider<InternalAccount> {\n readonly #messenger: MultichainAccountControllerMessenger;\n\n readonly #client: KeyringClient;\n\n constructor(messenger: MultichainAccountControllerMessenger) {\n this.#messenger = messenger;\n\n // TODO: Change this once we introduce 1 Snap keyring per Snaps.\n this.#client = this.#getKeyringClientFromSnapId(SOLANA_SNAP_ID);\n }\n\n 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 #getKeyringClientFromSnapId(snapId: string): KeyringClient {\n return new KeyringClient({\n send: async (request: JsonRpcRequest) => {\n const response = await this.#messenger.call(\n 'SnapController:handleRequest',\n {\n snapId: snapId as SnapId,\n origin: 'metamask',\n handler: HandlerType.OnKeyringRequest,\n request,\n },\n );\n return response as Promise<Json>;\n },\n });\n }\n\n async #createAccount(opts: {\n entropySource: EntropySourceId;\n derivationPath: `m/${string}`;\n }) {\n // NOTE: We're not supposed to make the keyring instance escape `withKeyring` but\n // we have to use the `SnapKeyring` instance to be able to create Solana account\n // without triggering UI confirmation.\n // Also, creating account that way won't invalidate the snap keyring state. The\n // account will get created and persisted properly with the Snap account creation\n // flow \"asynchronously\" (with `notify:accountCreated`).\n const createAccount = await this.#withKeyring<\n SnapKeyring,\n SnapKeyring['createAccount']\n >({ type: KeyringTypes.snap }, async ({ keyring }) =>\n keyring.createAccount.bind(keyring),\n );\n\n const keyringAccount = await createAccount(SOLANA_SNAP_ID, opts, {\n displayAccountNameSuggestion: false,\n displayConfirmation: false,\n setSelectedAccount: false,\n });\n\n return keyringAccount.id;\n }\n\n async createAccounts({\n entropySource,\n groupIndex,\n }: {\n entropySource: EntropySourceId;\n groupIndex: number;\n }) {\n const id = await this.#createAccount({\n entropySource,\n derivationPath: `m/44'/501'/${groupIndex}'/0'`,\n });\n\n return [id];\n }\n\n async discoverAndCreateAccounts({\n entropySource,\n groupIndex,\n }: {\n entropySource: EntropySourceId;\n groupIndex: number;\n }) {\n const discoveredAccounts = await this.#client.discoverAccounts(\n [SolScope.Mainnet, SolScope.Testnet],\n entropySource,\n groupIndex,\n );\n\n return await Promise.all(\n discoveredAccounts.map(\n async ({ derivationPath }) =>\n await this.#createAccount({ entropySource, derivationPath }),\n ),\n );\n }\n\n #getAccounts(\n filter: (account: InternalAccount) => boolean = () => true,\n ): SolInternalAccount[] {\n return this.#messenger\n .call('AccountsController:listMultichainAccounts')\n .filter((account) => {\n // We only check for EOA accounts for multichain accounts.\n if (\n account.type !== SolAccountType.DataAccount ||\n account.metadata.keyring.type !== (KeyringTypes.snap as string)\n ) {\n return false;\n }\n\n // TODO: Maybe use superstruct to validate the structure of HD account since they are not strongly-typed for now?\n if (!account.options.entropySource) {\n console.warn(\n \"! Found a Solana account with no entropy source: account won't be associated to its wallet.\",\n );\n return false;\n }\n\n // TODO: We need to add this index for native accounts too!\n if (account.options.index === undefined) {\n console.warn(\n \"! Found a Solana account with no index: account won't be associated to its wallet.\",\n );\n return false;\n }\n\n return filter(account);\n }) as SolInternalAccount[]; // Safe, we did check for options fields during filtering.\n }\n\n getAccounts({\n entropySource,\n groupIndex,\n }: {\n entropySource: EntropySourceId;\n groupIndex: number;\n }): AccountId[] {\n return this.#getAccounts()\n .filter((account) => {\n return (\n account.options.entropySource === entropySource &&\n account.options.index === groupIndex\n );\n })\n .map((account) => account.id);\n }\n\n getAccount(id: AccountId): InternalAccount {\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 Solana account: ${id}`);\n }\n\n return found;\n }\n}\n"]}
|
@@ -1,65 +1,23 @@
|
|
1
|
+
import type { AccountId } from "@metamask/accounts-controller";
|
1
2
|
import { type EntropySourceId } from "@metamask/keyring-api";
|
2
3
|
import type { InternalAccount } from "@metamask/keyring-internal-api";
|
3
4
|
import type { AccountProvider } from "@metamask/multichain-account-api";
|
4
|
-
import type { Json } from "@metamask/utils";
|
5
5
|
import type { MultichainAccountControllerMessenger } from "../types.cjs";
|
6
|
-
export declare class SolAccountProvider implements AccountProvider {
|
6
|
+
export declare class SolAccountProvider implements AccountProvider<InternalAccount> {
|
7
7
|
#private;
|
8
8
|
constructor(messenger: MultichainAccountControllerMessenger);
|
9
9
|
createAccounts({ entropySource, groupIndex, }: {
|
10
10
|
entropySource: EntropySourceId;
|
11
11
|
groupIndex: number;
|
12
|
-
}): Promise<
|
13
|
-
type: "eip155:eoa" | "eip155:erc4337" | "bip122:p2pkh" | "bip122:p2sh" | "bip122:p2wpkh" | "bip122:p2tr" | "solana:data-account";
|
14
|
-
id: string;
|
15
|
-
options: Record<string, Json>;
|
16
|
-
metadata: {
|
17
|
-
name: string;
|
18
|
-
importTime: number;
|
19
|
-
keyring: {
|
20
|
-
type: string;
|
21
|
-
};
|
22
|
-
nameLastUpdatedAt?: number | undefined;
|
23
|
-
snap?: {
|
24
|
-
name: string;
|
25
|
-
id: string;
|
26
|
-
enabled: boolean;
|
27
|
-
} | undefined;
|
28
|
-
lastSelected?: number | undefined;
|
29
|
-
};
|
30
|
-
address: string;
|
31
|
-
scopes: `${string}:${string}`[];
|
32
|
-
methods: string[];
|
33
|
-
}[]>;
|
12
|
+
}): Promise<string[]>;
|
34
13
|
discoverAndCreateAccounts({ entropySource, groupIndex, }: {
|
35
14
|
entropySource: EntropySourceId;
|
36
15
|
groupIndex: number;
|
37
|
-
}): Promise<
|
38
|
-
type: "eip155:eoa" | "eip155:erc4337" | "bip122:p2pkh" | "bip122:p2sh" | "bip122:p2wpkh" | "bip122:p2tr" | "solana:data-account";
|
39
|
-
id: string;
|
40
|
-
options: Record<string, Json>;
|
41
|
-
metadata: {
|
42
|
-
name: string;
|
43
|
-
importTime: number;
|
44
|
-
keyring: {
|
45
|
-
type: string;
|
46
|
-
};
|
47
|
-
nameLastUpdatedAt?: number | undefined;
|
48
|
-
snap?: {
|
49
|
-
name: string;
|
50
|
-
id: string;
|
51
|
-
enabled: boolean;
|
52
|
-
} | undefined;
|
53
|
-
lastSelected?: number | undefined;
|
54
|
-
};
|
55
|
-
address: string;
|
56
|
-
scopes: `${string}:${string}`[];
|
57
|
-
methods: string[];
|
58
|
-
}[]>;
|
16
|
+
}): Promise<string[]>;
|
59
17
|
getAccounts({ entropySource, groupIndex, }: {
|
60
18
|
entropySource: EntropySourceId;
|
61
19
|
groupIndex: number;
|
62
|
-
}):
|
63
|
-
|
20
|
+
}): AccountId[];
|
21
|
+
getAccount(id: AccountId): InternalAccount;
|
64
22
|
}
|
65
23
|
//# sourceMappingURL=SolAccountProvider.d.cts.map
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"SolAccountProvider.d.cts","sourceRoot":"","sources":["../../src/providers/SolAccountProvider.ts"],"names":[],"mappings":"
|
1
|
+
{"version":3,"file":"SolAccountProvider.d.cts","sourceRoot":"","sources":["../../src/providers/SolAccountProvider.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,sCAAsC;AAE/D,OAAO,EAGL,KAAK,eAAe,EACrB,8BAA8B;AAM/B,OAAO,KAAK,EAAE,eAAe,EAAE,uCAAuC;AAEtE,OAAO,KAAK,EAAE,eAAe,EAAE,yCAAyC;AAKxE,OAAO,KAAK,EAAE,oCAAoC,EAAE,qBAAiB;AAWrE,qBAAa,kBAAmB,YAAW,eAAe,CAAC,eAAe,CAAC;;gBAK7D,SAAS,EAAE,oCAAoC;IAyErD,cAAc,CAAC,EACnB,aAAa,EACb,UAAU,GACX,EAAE;QACD,aAAa,EAAE,eAAe,CAAC;QAC/B,UAAU,EAAE,MAAM,CAAC;KACpB;IASK,yBAAyB,CAAC,EAC9B,aAAa,EACb,UAAU,GACX,EAAE;QACD,aAAa,EAAE,eAAe,CAAC;QAC/B,UAAU,EAAE,MAAM,CAAC;KACpB;IAiDD,WAAW,CAAC,EACV,aAAa,EACb,UAAU,GACX,EAAE;QACD,aAAa,EAAE,eAAe,CAAC;QAC/B,UAAU,EAAE,MAAM,CAAC;KACpB,GAAG,SAAS,EAAE;IAWf,UAAU,CAAC,EAAE,EAAE,SAAS,GAAG,eAAe;CAU3C"}
|
@@ -1,65 +1,23 @@
|
|
1
|
+
import type { AccountId } from "@metamask/accounts-controller";
|
1
2
|
import { type EntropySourceId } from "@metamask/keyring-api";
|
2
3
|
import type { InternalAccount } from "@metamask/keyring-internal-api";
|
3
4
|
import type { AccountProvider } from "@metamask/multichain-account-api";
|
4
|
-
import type { Json } from "@metamask/utils";
|
5
5
|
import type { MultichainAccountControllerMessenger } from "../types.mjs";
|
6
|
-
export declare class SolAccountProvider implements AccountProvider {
|
6
|
+
export declare class SolAccountProvider implements AccountProvider<InternalAccount> {
|
7
7
|
#private;
|
8
8
|
constructor(messenger: MultichainAccountControllerMessenger);
|
9
9
|
createAccounts({ entropySource, groupIndex, }: {
|
10
10
|
entropySource: EntropySourceId;
|
11
11
|
groupIndex: number;
|
12
|
-
}): Promise<
|
13
|
-
type: "eip155:eoa" | "eip155:erc4337" | "bip122:p2pkh" | "bip122:p2sh" | "bip122:p2wpkh" | "bip122:p2tr" | "solana:data-account";
|
14
|
-
id: string;
|
15
|
-
options: Record<string, Json>;
|
16
|
-
metadata: {
|
17
|
-
name: string;
|
18
|
-
importTime: number;
|
19
|
-
keyring: {
|
20
|
-
type: string;
|
21
|
-
};
|
22
|
-
nameLastUpdatedAt?: number | undefined;
|
23
|
-
snap?: {
|
24
|
-
name: string;
|
25
|
-
id: string;
|
26
|
-
enabled: boolean;
|
27
|
-
} | undefined;
|
28
|
-
lastSelected?: number | undefined;
|
29
|
-
};
|
30
|
-
address: string;
|
31
|
-
scopes: `${string}:${string}`[];
|
32
|
-
methods: string[];
|
33
|
-
}[]>;
|
12
|
+
}): Promise<string[]>;
|
34
13
|
discoverAndCreateAccounts({ entropySource, groupIndex, }: {
|
35
14
|
entropySource: EntropySourceId;
|
36
15
|
groupIndex: number;
|
37
|
-
}): Promise<
|
38
|
-
type: "eip155:eoa" | "eip155:erc4337" | "bip122:p2pkh" | "bip122:p2sh" | "bip122:p2wpkh" | "bip122:p2tr" | "solana:data-account";
|
39
|
-
id: string;
|
40
|
-
options: Record<string, Json>;
|
41
|
-
metadata: {
|
42
|
-
name: string;
|
43
|
-
importTime: number;
|
44
|
-
keyring: {
|
45
|
-
type: string;
|
46
|
-
};
|
47
|
-
nameLastUpdatedAt?: number | undefined;
|
48
|
-
snap?: {
|
49
|
-
name: string;
|
50
|
-
id: string;
|
51
|
-
enabled: boolean;
|
52
|
-
} | undefined;
|
53
|
-
lastSelected?: number | undefined;
|
54
|
-
};
|
55
|
-
address: string;
|
56
|
-
scopes: `${string}:${string}`[];
|
57
|
-
methods: string[];
|
58
|
-
}[]>;
|
16
|
+
}): Promise<string[]>;
|
59
17
|
getAccounts({ entropySource, groupIndex, }: {
|
60
18
|
entropySource: EntropySourceId;
|
61
19
|
groupIndex: number;
|
62
|
-
}):
|
63
|
-
|
20
|
+
}): AccountId[];
|
21
|
+
getAccount(id: AccountId): InternalAccount;
|
64
22
|
}
|
65
23
|
//# sourceMappingURL=SolAccountProvider.d.mts.map
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"SolAccountProvider.d.mts","sourceRoot":"","sources":["../../src/providers/SolAccountProvider.ts"],"names":[],"mappings":"
|
1
|
+
{"version":3,"file":"SolAccountProvider.d.mts","sourceRoot":"","sources":["../../src/providers/SolAccountProvider.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,sCAAsC;AAE/D,OAAO,EAGL,KAAK,eAAe,EACrB,8BAA8B;AAM/B,OAAO,KAAK,EAAE,eAAe,EAAE,uCAAuC;AAEtE,OAAO,KAAK,EAAE,eAAe,EAAE,yCAAyC;AAKxE,OAAO,KAAK,EAAE,oCAAoC,EAAE,qBAAiB;AAWrE,qBAAa,kBAAmB,YAAW,eAAe,CAAC,eAAe,CAAC;;gBAK7D,SAAS,EAAE,oCAAoC;IAyErD,cAAc,CAAC,EACnB,aAAa,EACb,UAAU,GACX,EAAE;QACD,aAAa,EAAE,eAAe,CAAC;QAC/B,UAAU,EAAE,MAAM,CAAC;KACpB;IASK,yBAAyB,CAAC,EAC9B,aAAa,EACb,UAAU,GACX,EAAE;QACD,aAAa,EAAE,eAAe,CAAC;QAC/B,UAAU,EAAE,MAAM,CAAC;KACpB;IAiDD,WAAW,CAAC,EACV,aAAa,EACb,UAAU,GACX,EAAE;QACD,aAAa,EAAE,eAAe,CAAC;QAC/B,UAAU,EAAE,MAAM,CAAC;KACpB,GAAG,SAAS,EAAE;IAWf,UAAU,CAAC,EAAE,EAAE,SAAS,GAAG,eAAe;CAU3C"}
|
@@ -14,12 +14,6 @@ import { SolAccountType, SolScope } from "@metamask/keyring-api";
|
|
14
14
|
import { KeyringTypes } from "@metamask/keyring-controller";
|
15
15
|
import { KeyringClient } from "@metamask/keyring-snap-client";
|
16
16
|
import { HandlerType } from "@metamask/snaps-utils";
|
17
|
-
// eslint-disable-next-line jsdoc/require-jsdoc
|
18
|
-
function assertInternalAccountExists(account) {
|
19
|
-
if (!account) {
|
20
|
-
throw new Error('Internal account does not exist');
|
21
|
-
}
|
22
|
-
}
|
23
17
|
const SOLANA_SNAP_ID = 'npm:@metamask/solana-wallet-snap';
|
24
18
|
export class SolAccountProvider {
|
25
19
|
constructor(messenger) {
|
@@ -31,28 +25,31 @@ export class SolAccountProvider {
|
|
31
25
|
__classPrivateFieldSet(this, _SolAccountProvider_client, __classPrivateFieldGet(this, _SolAccountProvider_instances, "m", _SolAccountProvider_getKeyringClientFromSnapId).call(this, SOLANA_SNAP_ID), "f");
|
32
26
|
}
|
33
27
|
async createAccounts({ entropySource, groupIndex, }) {
|
34
|
-
const
|
28
|
+
const id = await __classPrivateFieldGet(this, _SolAccountProvider_instances, "m", _SolAccountProvider_createAccount).call(this, {
|
35
29
|
entropySource,
|
36
30
|
derivationPath: `m/44'/501'/${groupIndex}'/0'`,
|
37
31
|
});
|
38
|
-
return [
|
32
|
+
return [id];
|
39
33
|
}
|
40
34
|
async discoverAndCreateAccounts({ entropySource, groupIndex, }) {
|
41
35
|
const discoveredAccounts = await __classPrivateFieldGet(this, _SolAccountProvider_client, "f").discoverAccounts([SolScope.Mainnet, SolScope.Testnet], entropySource, groupIndex);
|
42
36
|
return await Promise.all(discoveredAccounts.map(async ({ derivationPath }) => await __classPrivateFieldGet(this, _SolAccountProvider_instances, "m", _SolAccountProvider_createAccount).call(this, { entropySource, derivationPath })));
|
43
37
|
}
|
44
38
|
getAccounts({ entropySource, groupIndex, }) {
|
45
|
-
return __classPrivateFieldGet(this, _SolAccountProvider_instances, "m", _SolAccountProvider_getAccounts).call(this)
|
39
|
+
return __classPrivateFieldGet(this, _SolAccountProvider_instances, "m", _SolAccountProvider_getAccounts).call(this)
|
40
|
+
.filter((account) => {
|
46
41
|
return (account.options.entropySource === entropySource &&
|
47
42
|
account.options.index === groupIndex);
|
48
|
-
})
|
43
|
+
})
|
44
|
+
.map((account) => account.id);
|
49
45
|
}
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
46
|
+
getAccount(id) {
|
47
|
+
// TODO: Maybe just use a proper find for faster lookup?
|
48
|
+
const [found] = __classPrivateFieldGet(this, _SolAccountProvider_instances, "m", _SolAccountProvider_getAccounts).call(this, (account) => account.id === id);
|
49
|
+
if (!found) {
|
50
|
+
throw new Error(`Unable to find Solana account: ${id}`);
|
54
51
|
}
|
55
|
-
return
|
52
|
+
return found;
|
56
53
|
}
|
57
54
|
}
|
58
55
|
_SolAccountProvider_messenger = new WeakMap(), _SolAccountProvider_client = new WeakMap(), _SolAccountProvider_instances = new WeakSet(), _SolAccountProvider_withKeyring = async function _SolAccountProvider_withKeyring(selector, operation) {
|
@@ -86,29 +83,8 @@ _SolAccountProvider_messenger = new WeakMap(), _SolAccountProvider_client = new
|
|
86
83
|
displayConfirmation: false,
|
87
84
|
setSelectedAccount: false,
|
88
85
|
});
|
89
|
-
|
90
|
-
|
91
|
-
// right away. For now we just re-create a fake `InternalAccount` and
|
92
|
-
// we might have to rely solely on `account.id`.
|
93
|
-
// Actually get the associated `InternalAccount`.
|
94
|
-
// const account = this.#messenger.call(
|
95
|
-
// 'AccountsController:getAccount',
|
96
|
-
// keyringAccount.id,
|
97
|
-
// );
|
98
|
-
const account = {
|
99
|
-
...keyringAccount,
|
100
|
-
metadata: {
|
101
|
-
name: `Solana account -- ${keyringAccount.options.index}`,
|
102
|
-
importTime: 0,
|
103
|
-
keyring: {
|
104
|
-
type: KeyringTypes.snap,
|
105
|
-
},
|
106
|
-
},
|
107
|
-
};
|
108
|
-
// We MUST have the associated internal account.
|
109
|
-
assertInternalAccountExists(account);
|
110
|
-
return account;
|
111
|
-
}, _SolAccountProvider_getAccounts = function _SolAccountProvider_getAccounts() {
|
86
|
+
return keyringAccount.id;
|
87
|
+
}, _SolAccountProvider_getAccounts = function _SolAccountProvider_getAccounts(filter = () => true) {
|
112
88
|
return __classPrivateFieldGet(this, _SolAccountProvider_messenger, "f")
|
113
89
|
.call('AccountsController:listMultichainAccounts')
|
114
90
|
.filter((account) => {
|
@@ -127,7 +103,7 @@ _SolAccountProvider_messenger = new WeakMap(), _SolAccountProvider_client = new
|
|
127
103
|
console.warn("! Found a Solana account with no index: account won't be associated to its wallet.");
|
128
104
|
return false;
|
129
105
|
}
|
130
|
-
return
|
106
|
+
return filter(account);
|
131
107
|
}); // Safe, we did check for options fields during filtering.
|
132
108
|
};
|
133
109
|
//# sourceMappingURL=SolAccountProvider.mjs.map
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"SolAccountProvider.mjs","sourceRoot":"","sources":["../../src/providers/SolAccountProvider.ts"],"names":[],"mappings":"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","sourcesContent":["import type { SnapKeyring } from '@metamask/eth-snap-keyring';\nimport {\n SolAccountType,\n SolScope,\n type EntropySourceId,\n} from '@metamask/keyring-api';\nimport type {\n KeyringMetadata,\n KeyringSelector,\n} from '@metamask/keyring-controller';\nimport { KeyringTypes } from '@metamask/keyring-controller';\nimport type {\n EthKeyring,\n InternalAccount,\n} from '@metamask/keyring-internal-api';\nimport { KeyringClient } from '@metamask/keyring-snap-client';\nimport type { AccountProvider } from '@metamask/multichain-account-api';\nimport type { SnapId } from '@metamask/snaps-sdk';\nimport { HandlerType } from '@metamask/snaps-utils';\nimport type { Json, JsonRpcRequest } from '@metamask/utils';\n\nimport type { MultichainAccountControllerMessenger } from '../types';\n\ntype SolInternalAccount = InternalAccount & {\n options: {\n index: number;\n entropySource: EntropySourceId;\n };\n};\n\n// eslint-disable-next-line jsdoc/require-jsdoc\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\nconst SOLANA_SNAP_ID = 'npm:@metamask/solana-wallet-snap' as SnapId;\nexport class SolAccountProvider implements AccountProvider {\n readonly #messenger: MultichainAccountControllerMessenger;\n\n readonly #client: KeyringClient;\n\n constructor(messenger: MultichainAccountControllerMessenger) {\n this.#messenger = messenger;\n\n // TODO: Change this once we introduce 1 Snap keyring per Snaps.\n this.#client = this.#getKeyringClientFromSnapId(SOLANA_SNAP_ID);\n }\n\n 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 #getKeyringClientFromSnapId(snapId: string): KeyringClient {\n return new KeyringClient({\n send: async (request: JsonRpcRequest) => {\n const response = await this.#messenger.call(\n 'SnapController:handleRequest',\n {\n snapId: snapId as SnapId,\n origin: 'metamask',\n handler: HandlerType.OnKeyringRequest,\n request,\n },\n );\n return response as Promise<Json>;\n },\n });\n }\n\n async #createAccount(opts: {\n entropySource: EntropySourceId;\n derivationPath: `m/${string}`;\n }) {\n // NOTE: We're not supposed to make the keyring instance escape `withKeyring` but\n // we have to use the `SnapKeyring` instance to be able to create Solana account\n // without triggering UI confirmation.\n // Also, creating account that way won't invalidate the snap keyring state. The\n // account will get created and persisted properly with the Snap account creation\n // flow \"asynchronously\" (with `notify:accountCreated`).\n const createAccount = await this.#withKeyring<\n SnapKeyring,\n SnapKeyring['createAccount']\n >({ type: KeyringTypes.snap }, async ({ keyring }) =>\n keyring.createAccount.bind(keyring),\n );\n\n const keyringAccount = await createAccount(SOLANA_SNAP_ID, opts, {\n displayAccountNameSuggestion: false,\n displayConfirmation: false,\n setSelectedAccount: false,\n });\n\n // FIXME: This part of the flow is truly async, so when the `KeyringClient`\n // returns the `KeyringAccount`, its `InternalAccount` won't be \"ready\"\n // right away. For now we just re-create a fake `InternalAccount` and\n // we might have to rely solely on `account.id`.\n\n // Actually get the associated `InternalAccount`.\n // const account = this.#messenger.call(\n // 'AccountsController:getAccount',\n // keyringAccount.id,\n // );\n\n const account: InternalAccount = {\n ...keyringAccount,\n metadata: {\n name: `Solana account -- ${keyringAccount.options.index}`,\n importTime: 0,\n keyring: {\n type: KeyringTypes.snap,\n },\n },\n };\n\n // We MUST have the associated internal account.\n assertInternalAccountExists(account);\n\n return account;\n }\n\n async createAccounts({\n entropySource,\n groupIndex,\n }: {\n entropySource: EntropySourceId;\n groupIndex: number;\n }) {\n const account = await this.#createAccount({\n entropySource,\n derivationPath: `m/44'/501'/${groupIndex}'/0'`,\n });\n\n return [account];\n }\n\n async discoverAndCreateAccounts({\n entropySource,\n groupIndex,\n }: {\n entropySource: EntropySourceId;\n groupIndex: number;\n }) {\n const discoveredAccounts = await this.#client.discoverAccounts(\n [SolScope.Mainnet, SolScope.Testnet],\n entropySource,\n groupIndex,\n );\n\n return await Promise.all(\n discoveredAccounts.map(\n async ({ derivationPath }) =>\n await this.#createAccount({ entropySource, derivationPath }),\n ),\n );\n }\n\n #getAccounts(): SolInternalAccount[] {\n return this.#messenger\n .call('AccountsController:listMultichainAccounts')\n .filter((account) => {\n // We only check for EOA accounts for multichain accounts.\n if (\n account.type !== SolAccountType.DataAccount ||\n account.metadata.keyring.type !== (KeyringTypes.snap as string)\n ) {\n return false;\n }\n\n // TODO: Maybe use superstruct to validate the structure of HD account since they are not strongly-typed for now?\n if (!account.options.entropySource) {\n console.warn(\n \"! Found a Solana account with no entropy source: account won't be associated to its wallet.\",\n );\n return false;\n }\n\n // TODO: We need to add this index for native accounts too!\n if (account.options.index === undefined) {\n console.warn(\n \"! Found a Solana account with no index: account won't be associated to its wallet.\",\n );\n return false;\n }\n\n return true;\n }) as SolInternalAccount[]; // Safe, we did check for options fields during filtering.\n }\n\n getAccounts({\n entropySource,\n groupIndex,\n }: {\n entropySource: EntropySourceId;\n groupIndex: number;\n }): InternalAccount[] {\n return this.#getAccounts().filter((account) => {\n return (\n account.options.entropySource === entropySource &&\n account.options.index === groupIndex\n );\n });\n }\n\n getEntropySources(): EntropySourceId[] {\n const entropySources = new Set<EntropySourceId>();\n\n for (const account of this.#getAccounts()) {\n entropySources.add(account.options.entropySource);\n }\n\n return Array.from(entropySources);\n }\n}\n"]}
|
1
|
+
{"version":3,"file":"SolAccountProvider.mjs","sourceRoot":"","sources":["../../src/providers/SolAccountProvider.ts"],"names":[],"mappings":"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","sourcesContent":["import type { AccountId } from '@metamask/accounts-controller';\nimport type { SnapKeyring } from '@metamask/eth-snap-keyring';\nimport {\n SolAccountType,\n SolScope,\n type EntropySourceId,\n} from '@metamask/keyring-api';\nimport type {\n KeyringMetadata,\n KeyringSelector,\n} from '@metamask/keyring-controller';\nimport { KeyringTypes } from '@metamask/keyring-controller';\nimport type { InternalAccount } from '@metamask/keyring-internal-api';\nimport { KeyringClient } from '@metamask/keyring-snap-client';\nimport type { AccountProvider } from '@metamask/multichain-account-api';\nimport type { SnapId } from '@metamask/snaps-sdk';\nimport { HandlerType } from '@metamask/snaps-utils';\nimport type { Json, JsonRpcRequest } from '@metamask/utils';\n\nimport type { MultichainAccountControllerMessenger } from '../types';\n\ntype SolInternalAccount = InternalAccount & {\n options: {\n index: number;\n entropySource: EntropySourceId;\n };\n};\n\nconst SOLANA_SNAP_ID = 'npm:@metamask/solana-wallet-snap' as SnapId;\n\nexport class SolAccountProvider implements AccountProvider<InternalAccount> {\n readonly #messenger: MultichainAccountControllerMessenger;\n\n readonly #client: KeyringClient;\n\n constructor(messenger: MultichainAccountControllerMessenger) {\n this.#messenger = messenger;\n\n // TODO: Change this once we introduce 1 Snap keyring per Snaps.\n this.#client = this.#getKeyringClientFromSnapId(SOLANA_SNAP_ID);\n }\n\n 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 #getKeyringClientFromSnapId(snapId: string): KeyringClient {\n return new KeyringClient({\n send: async (request: JsonRpcRequest) => {\n const response = await this.#messenger.call(\n 'SnapController:handleRequest',\n {\n snapId: snapId as SnapId,\n origin: 'metamask',\n handler: HandlerType.OnKeyringRequest,\n request,\n },\n );\n return response as Promise<Json>;\n },\n });\n }\n\n async #createAccount(opts: {\n entropySource: EntropySourceId;\n derivationPath: `m/${string}`;\n }) {\n // NOTE: We're not supposed to make the keyring instance escape `withKeyring` but\n // we have to use the `SnapKeyring` instance to be able to create Solana account\n // without triggering UI confirmation.\n // Also, creating account that way won't invalidate the snap keyring state. The\n // account will get created and persisted properly with the Snap account creation\n // flow \"asynchronously\" (with `notify:accountCreated`).\n const createAccount = await this.#withKeyring<\n SnapKeyring,\n SnapKeyring['createAccount']\n >({ type: KeyringTypes.snap }, async ({ keyring }) =>\n keyring.createAccount.bind(keyring),\n );\n\n const keyringAccount = await createAccount(SOLANA_SNAP_ID, opts, {\n displayAccountNameSuggestion: false,\n displayConfirmation: false,\n setSelectedAccount: false,\n });\n\n return keyringAccount.id;\n }\n\n async createAccounts({\n entropySource,\n groupIndex,\n }: {\n entropySource: EntropySourceId;\n groupIndex: number;\n }) {\n const id = await this.#createAccount({\n entropySource,\n derivationPath: `m/44'/501'/${groupIndex}'/0'`,\n });\n\n return [id];\n }\n\n async discoverAndCreateAccounts({\n entropySource,\n groupIndex,\n }: {\n entropySource: EntropySourceId;\n groupIndex: number;\n }) {\n const discoveredAccounts = await this.#client.discoverAccounts(\n [SolScope.Mainnet, SolScope.Testnet],\n entropySource,\n groupIndex,\n );\n\n return await Promise.all(\n discoveredAccounts.map(\n async ({ derivationPath }) =>\n await this.#createAccount({ entropySource, derivationPath }),\n ),\n );\n }\n\n #getAccounts(\n filter: (account: InternalAccount) => boolean = () => true,\n ): SolInternalAccount[] {\n return this.#messenger\n .call('AccountsController:listMultichainAccounts')\n .filter((account) => {\n // We only check for EOA accounts for multichain accounts.\n if (\n account.type !== SolAccountType.DataAccount ||\n account.metadata.keyring.type !== (KeyringTypes.snap as string)\n ) {\n return false;\n }\n\n // TODO: Maybe use superstruct to validate the structure of HD account since they are not strongly-typed for now?\n if (!account.options.entropySource) {\n console.warn(\n \"! Found a Solana account with no entropy source: account won't be associated to its wallet.\",\n );\n return false;\n }\n\n // TODO: We need to add this index for native accounts too!\n if (account.options.index === undefined) {\n console.warn(\n \"! Found a Solana account with no index: account won't be associated to its wallet.\",\n );\n return false;\n }\n\n return filter(account);\n }) as SolInternalAccount[]; // Safe, we did check for options fields during filtering.\n }\n\n getAccounts({\n entropySource,\n groupIndex,\n }: {\n entropySource: EntropySourceId;\n groupIndex: number;\n }): AccountId[] {\n return this.#getAccounts()\n .filter((account) => {\n return (\n account.options.entropySource === entropySource &&\n account.options.index === groupIndex\n );\n })\n .map((account) => account.id);\n }\n\n getAccount(id: AccountId): InternalAccount {\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 Solana account: ${id}`);\n }\n\n return found;\n }\n}\n"]}
|
package/dist/types.cjs.map
CHANGED
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"types.cjs","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"","sourcesContent":["import type {\n AccountsControllerGetAccountAction,\n AccountsControllerGetAccountByAddressAction,\n AccountsControllerListMultichainAccountsAction,\n} from '@metamask/accounts-controller';\nimport type { RestrictedMessenger } from '@metamask/base-controller';\nimport type {
|
1
|
+
{"version":3,"file":"types.cjs","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"","sourcesContent":["import type {\n AccountsControllerGetAccountAction,\n AccountsControllerGetAccountByAddressAction,\n AccountsControllerListMultichainAccountsAction,\n} from '@metamask/accounts-controller';\nimport type { RestrictedMessenger } from '@metamask/base-controller';\nimport type {\n KeyringControllerGetStateAction,\n KeyringControllerWithKeyringAction,\n} from '@metamask/keyring-controller';\nimport type { HandleSnapRequest as SnapControllerHandleSnapRequestAction } from '@metamask/snaps-controllers';\n\n/**\n * All actions that {@link MultichainAccountController} registers so that other\n * modules can call them.\n */\nexport type MultichainAccountControllerActions = never;\n/**\n * All events that {@link MultichainAccountController} publishes so that other modules\n * can subscribe to them.\n */\nexport type MultichainAccountControllerEvents = never;\n\n/**\n * All actions registered by other modules that {@link MultichainAccountController}\n * calls.\n */\nexport type AllowedActions =\n | AccountsControllerListMultichainAccountsAction\n | AccountsControllerGetAccountAction\n | AccountsControllerGetAccountByAddressAction\n | SnapControllerHandleSnapRequestAction\n | KeyringControllerWithKeyringAction\n | KeyringControllerGetStateAction;\n\n/**\n * All events published by other modules that {@link MultichainAccountController}\n * subscribes to.\n */\nexport type AllowedEvents = never;\n\n/**\n * The messenger restricted to actions and events that\n * {@link MultichainAccountController} needs to access.\n */\nexport type MultichainAccountControllerMessenger = RestrictedMessenger<\n 'MultichainAccountController',\n MultichainAccountControllerActions | AllowedActions,\n MultichainAccountControllerEvents | AllowedEvents,\n AllowedActions['type'],\n AllowedEvents['type']\n>;\n"]}
|
package/dist/types.d.cts
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
import type { AccountsControllerGetAccountAction, AccountsControllerGetAccountByAddressAction, AccountsControllerListMultichainAccountsAction } from "@metamask/accounts-controller";
|
2
2
|
import type { RestrictedMessenger } from "@metamask/base-controller";
|
3
|
-
import type { KeyringControllerWithKeyringAction } from "@metamask/keyring-controller";
|
3
|
+
import type { KeyringControllerGetStateAction, KeyringControllerWithKeyringAction } from "@metamask/keyring-controller";
|
4
4
|
import type { HandleSnapRequest as SnapControllerHandleSnapRequestAction } from "@metamask/snaps-controllers";
|
5
5
|
/**
|
6
6
|
* All actions that {@link MultichainAccountController} registers so that other
|
@@ -16,7 +16,7 @@ export type MultichainAccountControllerEvents = never;
|
|
16
16
|
* All actions registered by other modules that {@link MultichainAccountController}
|
17
17
|
* calls.
|
18
18
|
*/
|
19
|
-
export type AllowedActions = AccountsControllerListMultichainAccountsAction | AccountsControllerGetAccountAction | AccountsControllerGetAccountByAddressAction | SnapControllerHandleSnapRequestAction | KeyringControllerWithKeyringAction;
|
19
|
+
export type AllowedActions = AccountsControllerListMultichainAccountsAction | AccountsControllerGetAccountAction | AccountsControllerGetAccountByAddressAction | SnapControllerHandleSnapRequestAction | KeyringControllerWithKeyringAction | KeyringControllerGetStateAction;
|
20
20
|
/**
|
21
21
|
* All events published by other modules that {@link MultichainAccountController}
|
22
22
|
* subscribes to.
|
package/dist/types.d.cts.map
CHANGED
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"types.d.cts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,kCAAkC,EAClC,2CAA2C,EAC3C,8CAA8C,EAC/C,sCAAsC;AACvC,OAAO,KAAK,EAAE,mBAAmB,EAAE,kCAAkC;AACrE,OAAO,KAAK,
|
1
|
+
{"version":3,"file":"types.d.cts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,kCAAkC,EAClC,2CAA2C,EAC3C,8CAA8C,EAC/C,sCAAsC;AACvC,OAAO,KAAK,EAAE,mBAAmB,EAAE,kCAAkC;AACrE,OAAO,KAAK,EACV,+BAA+B,EAC/B,kCAAkC,EACnC,qCAAqC;AACtC,OAAO,KAAK,EAAE,iBAAiB,IAAI,qCAAqC,EAAE,oCAAoC;AAE9G;;;GAGG;AACH,MAAM,MAAM,kCAAkC,GAAG,KAAK,CAAC;AACvD;;;GAGG;AACH,MAAM,MAAM,iCAAiC,GAAG,KAAK,CAAC;AAEtD;;;GAGG;AACH,MAAM,MAAM,cAAc,GACtB,8CAA8C,GAC9C,kCAAkC,GAClC,2CAA2C,GAC3C,qCAAqC,GACrC,kCAAkC,GAClC,+BAA+B,CAAC;AAEpC;;;GAGG;AACH,MAAM,MAAM,aAAa,GAAG,KAAK,CAAC;AAElC;;;GAGG;AACH,MAAM,MAAM,oCAAoC,GAAG,mBAAmB,CACpE,6BAA6B,EAC7B,kCAAkC,GAAG,cAAc,EACnD,iCAAiC,GAAG,aAAa,EACjD,cAAc,CAAC,MAAM,CAAC,EACtB,aAAa,CAAC,MAAM,CAAC,CACtB,CAAC"}
|
package/dist/types.d.mts
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
import type { AccountsControllerGetAccountAction, AccountsControllerGetAccountByAddressAction, AccountsControllerListMultichainAccountsAction } from "@metamask/accounts-controller";
|
2
2
|
import type { RestrictedMessenger } from "@metamask/base-controller";
|
3
|
-
import type { KeyringControllerWithKeyringAction } from "@metamask/keyring-controller";
|
3
|
+
import type { KeyringControllerGetStateAction, KeyringControllerWithKeyringAction } from "@metamask/keyring-controller";
|
4
4
|
import type { HandleSnapRequest as SnapControllerHandleSnapRequestAction } from "@metamask/snaps-controllers";
|
5
5
|
/**
|
6
6
|
* All actions that {@link MultichainAccountController} registers so that other
|
@@ -16,7 +16,7 @@ export type MultichainAccountControllerEvents = never;
|
|
16
16
|
* All actions registered by other modules that {@link MultichainAccountController}
|
17
17
|
* calls.
|
18
18
|
*/
|
19
|
-
export type AllowedActions = AccountsControllerListMultichainAccountsAction | AccountsControllerGetAccountAction | AccountsControllerGetAccountByAddressAction | SnapControllerHandleSnapRequestAction | KeyringControllerWithKeyringAction;
|
19
|
+
export type AllowedActions = AccountsControllerListMultichainAccountsAction | AccountsControllerGetAccountAction | AccountsControllerGetAccountByAddressAction | SnapControllerHandleSnapRequestAction | KeyringControllerWithKeyringAction | KeyringControllerGetStateAction;
|
20
20
|
/**
|
21
21
|
* All events published by other modules that {@link MultichainAccountController}
|
22
22
|
* subscribes to.
|
package/dist/types.d.mts.map
CHANGED
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"types.d.mts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,kCAAkC,EAClC,2CAA2C,EAC3C,8CAA8C,EAC/C,sCAAsC;AACvC,OAAO,KAAK,EAAE,mBAAmB,EAAE,kCAAkC;AACrE,OAAO,KAAK,
|
1
|
+
{"version":3,"file":"types.d.mts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,kCAAkC,EAClC,2CAA2C,EAC3C,8CAA8C,EAC/C,sCAAsC;AACvC,OAAO,KAAK,EAAE,mBAAmB,EAAE,kCAAkC;AACrE,OAAO,KAAK,EACV,+BAA+B,EAC/B,kCAAkC,EACnC,qCAAqC;AACtC,OAAO,KAAK,EAAE,iBAAiB,IAAI,qCAAqC,EAAE,oCAAoC;AAE9G;;;GAGG;AACH,MAAM,MAAM,kCAAkC,GAAG,KAAK,CAAC;AACvD;;;GAGG;AACH,MAAM,MAAM,iCAAiC,GAAG,KAAK,CAAC;AAEtD;;;GAGG;AACH,MAAM,MAAM,cAAc,GACtB,8CAA8C,GAC9C,kCAAkC,GAClC,2CAA2C,GAC3C,qCAAqC,GACrC,kCAAkC,GAClC,+BAA+B,CAAC;AAEpC;;;GAGG;AACH,MAAM,MAAM,aAAa,GAAG,KAAK,CAAC;AAElC;;;GAGG;AACH,MAAM,MAAM,oCAAoC,GAAG,mBAAmB,CACpE,6BAA6B,EAC7B,kCAAkC,GAAG,cAAc,EACnD,iCAAiC,GAAG,aAAa,EACjD,cAAc,CAAC,MAAM,CAAC,EACtB,aAAa,CAAC,MAAM,CAAC,CACtB,CAAC"}
|
package/dist/types.mjs.map
CHANGED
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"types.mjs","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"","sourcesContent":["import type {\n AccountsControllerGetAccountAction,\n AccountsControllerGetAccountByAddressAction,\n AccountsControllerListMultichainAccountsAction,\n} from '@metamask/accounts-controller';\nimport type { RestrictedMessenger } from '@metamask/base-controller';\nimport type {
|
1
|
+
{"version":3,"file":"types.mjs","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"","sourcesContent":["import type {\n AccountsControllerGetAccountAction,\n AccountsControllerGetAccountByAddressAction,\n AccountsControllerListMultichainAccountsAction,\n} from '@metamask/accounts-controller';\nimport type { RestrictedMessenger } from '@metamask/base-controller';\nimport type {\n KeyringControllerGetStateAction,\n KeyringControllerWithKeyringAction,\n} from '@metamask/keyring-controller';\nimport type { HandleSnapRequest as SnapControllerHandleSnapRequestAction } from '@metamask/snaps-controllers';\n\n/**\n * All actions that {@link MultichainAccountController} registers so that other\n * modules can call them.\n */\nexport type MultichainAccountControllerActions = never;\n/**\n * All events that {@link MultichainAccountController} publishes so that other modules\n * can subscribe to them.\n */\nexport type MultichainAccountControllerEvents = never;\n\n/**\n * All actions registered by other modules that {@link MultichainAccountController}\n * calls.\n */\nexport type AllowedActions =\n | AccountsControllerListMultichainAccountsAction\n | AccountsControllerGetAccountAction\n | AccountsControllerGetAccountByAddressAction\n | SnapControllerHandleSnapRequestAction\n | KeyringControllerWithKeyringAction\n | KeyringControllerGetStateAction;\n\n/**\n * All events published by other modules that {@link MultichainAccountController}\n * subscribes to.\n */\nexport type AllowedEvents = never;\n\n/**\n * The messenger restricted to actions and events that\n * {@link MultichainAccountController} needs to access.\n */\nexport type MultichainAccountControllerMessenger = RestrictedMessenger<\n 'MultichainAccountController',\n MultichainAccountControllerActions | AllowedActions,\n MultichainAccountControllerEvents | AllowedEvents,\n AllowedActions['type'],\n AllowedEvents['type']\n>;\n"]}
|