@metamask-previews/account-api 0.1.0-6199101 → 0.1.0-e86c8ec
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/api/group.cjs.map +1 -1
- package/dist/api/group.d.cts +4 -5
- package/dist/api/group.d.cts.map +1 -1
- package/dist/api/group.d.mts +4 -5
- package/dist/api/group.d.mts.map +1 -1
- package/dist/api/group.mjs.map +1 -1
- package/dist/api/index.cjs.map +1 -1
- package/dist/api/index.d.cts +2 -0
- package/dist/api/index.d.cts.map +1 -1
- package/dist/api/index.d.mts +2 -0
- package/dist/api/index.d.mts.map +1 -1
- package/dist/api/index.mjs.map +1 -1
- package/dist/api/multichain/account.cjs +99 -48
- package/dist/api/multichain/account.cjs.map +1 -1
- package/dist/api/multichain/account.d.cts +46 -62
- package/dist/api/multichain/account.d.cts.map +1 -1
- package/dist/api/multichain/account.d.mts +46 -62
- package/dist/api/multichain/account.d.mts.map +1 -1
- package/dist/api/multichain/account.mjs +95 -45
- package/dist/api/multichain/account.mjs.map +1 -1
- package/dist/api/multichain/index.cjs.map +1 -1
- package/dist/api/multichain/index.d.cts +0 -1
- package/dist/api/multichain/index.d.cts.map +1 -1
- package/dist/api/multichain/index.d.mts +0 -1
- package/dist/api/multichain/index.d.mts.map +1 -1
- package/dist/api/multichain/index.mjs.map +1 -1
- package/dist/api/multichain/wallet.cjs +104 -38
- package/dist/api/multichain/wallet.cjs.map +1 -1
- package/dist/api/multichain/wallet.d.cts +48 -23
- package/dist/api/multichain/wallet.d.cts.map +1 -1
- package/dist/api/multichain/wallet.d.mts +48 -23
- package/dist/api/multichain/wallet.d.mts.map +1 -1
- package/dist/api/multichain/wallet.mjs +103 -37
- package/dist/api/multichain/wallet.mjs.map +1 -1
- package/dist/api/provider.cjs.map +1 -0
- package/dist/api/provider.d.cts +13 -0
- package/dist/api/provider.d.cts.map +1 -0
- package/dist/api/provider.d.mts +13 -0
- package/dist/api/provider.d.mts.map +1 -0
- package/dist/api/provider.mjs.map +1 -0
- package/dist/api/selector.cjs +3 -0
- package/dist/api/selector.cjs.map +1 -0
- package/dist/api/selector.d.cts +27 -0
- package/dist/api/selector.d.cts.map +1 -0
- package/dist/api/selector.d.mts +27 -0
- package/dist/api/selector.d.mts.map +1 -0
- package/dist/api/selector.mjs +2 -0
- package/dist/api/selector.mjs.map +1 -0
- package/dist/api/wallet.cjs.map +1 -1
- package/dist/api/wallet.d.cts +1 -0
- package/dist/api/wallet.d.cts.map +1 -1
- package/dist/api/wallet.d.mts +1 -0
- package/dist/api/wallet.d.mts.map +1 -1
- package/dist/api/wallet.mjs.map +1 -1
- package/package.json +1 -1
- package/dist/api/multichain/provider.cjs.map +0 -1
- package/dist/api/multichain/provider.d.cts +0 -29
- package/dist/api/multichain/provider.d.cts.map +0 -1
- package/dist/api/multichain/provider.d.mts +0 -29
- package/dist/api/multichain/provider.d.mts.map +0 -1
- package/dist/api/multichain/provider.mjs.map +0 -1
- /package/dist/api/{multichain/provider.cjs → provider.cjs} +0 -0
- /package/dist/api/{multichain/provider.mjs → provider.mjs} +0 -0
|
@@ -1,97 +1,74 @@
|
|
|
1
|
-
import type
|
|
2
|
-
import type { MultichainAccountProvider } from "./provider.mjs";
|
|
1
|
+
import { type KeyringAccount } from "@metamask/keyring-api";
|
|
3
2
|
import type { MultichainAccountWallet, MultichainAccountWalletId } from "./wallet.mjs";
|
|
4
|
-
import type { AccountGroup
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
*/
|
|
8
|
-
export type MultichainAccountSelector<Account extends KeyringAccount> = {
|
|
9
|
-
/**
|
|
10
|
-
* Query by account ID.
|
|
11
|
-
*/
|
|
12
|
-
id?: Account['id'];
|
|
13
|
-
/**
|
|
14
|
-
* Query by account address.
|
|
15
|
-
*/
|
|
16
|
-
address?: Account['address'];
|
|
17
|
-
/**
|
|
18
|
-
* Query by account type.
|
|
19
|
-
*/
|
|
20
|
-
type?: Account['type'];
|
|
21
|
-
/**
|
|
22
|
-
* Query by account methods.
|
|
23
|
-
*/
|
|
24
|
-
methods?: Account['methods'];
|
|
25
|
-
/**
|
|
26
|
-
* Query by account scopes.
|
|
27
|
-
*/
|
|
28
|
-
scopes?: Account['scopes'];
|
|
29
|
-
};
|
|
3
|
+
import type { AccountGroup } from "../group.mjs";
|
|
4
|
+
import type { AccountProvider } from "../provider.mjs";
|
|
5
|
+
import type { AccountSelector } from "../selector.mjs";
|
|
30
6
|
/**
|
|
31
7
|
* Multichain account ID.
|
|
32
8
|
*/
|
|
33
9
|
export type MultichainAccountId = `${MultichainAccountWalletId}/${number}`;
|
|
34
10
|
/**
|
|
35
|
-
* A multichain account that holds multiple
|
|
11
|
+
* A multichain account that holds multiple accounts.
|
|
36
12
|
*/
|
|
37
|
-
export
|
|
13
|
+
export declare class MultichainAccount<Account extends KeyringAccount> implements AccountGroup<Account> {
|
|
14
|
+
#private;
|
|
15
|
+
constructor({ groupIndex, wallet, providers, }: {
|
|
16
|
+
groupIndex: number;
|
|
17
|
+
wallet: MultichainAccountWallet<Account>;
|
|
18
|
+
providers: AccountProvider<Account>[];
|
|
19
|
+
});
|
|
38
20
|
/**
|
|
39
|
-
*
|
|
21
|
+
* Gets the multichain account ID.
|
|
22
|
+
*
|
|
23
|
+
* @returns The multichain account ID.
|
|
40
24
|
*/
|
|
41
25
|
get id(): MultichainAccountId;
|
|
42
26
|
/**
|
|
43
|
-
*
|
|
27
|
+
* Gets the multichain account's wallet reference (parent).
|
|
28
|
+
*
|
|
29
|
+
* @returns The multichain account's wallet.
|
|
44
30
|
*/
|
|
45
31
|
get wallet(): MultichainAccountWallet<Account>;
|
|
46
32
|
/**
|
|
47
|
-
*
|
|
33
|
+
* Gets the multichain account group index.
|
|
34
|
+
*
|
|
35
|
+
* @returns The multichain account group index.
|
|
48
36
|
*/
|
|
49
37
|
get index(): number;
|
|
50
38
|
/**
|
|
51
|
-
*
|
|
39
|
+
* Checks if there's any underlying accounts for this multichain accounts.
|
|
52
40
|
*
|
|
53
|
-
* @
|
|
54
|
-
|
|
41
|
+
* @returns True if there's any underlying accounts, false otherwise.
|
|
42
|
+
*/
|
|
43
|
+
hasAccounts(): boolean;
|
|
44
|
+
/**
|
|
45
|
+
* Gets the accounts for this multichain account.
|
|
46
|
+
*
|
|
47
|
+
* @returns The accounts.
|
|
55
48
|
*/
|
|
56
49
|
getAccounts(): Account[];
|
|
57
50
|
/**
|
|
58
|
-
* Gets the
|
|
51
|
+
* Gets the account for a given account ID.
|
|
59
52
|
*
|
|
60
53
|
* @param id - Account ID.
|
|
61
|
-
* @returns The
|
|
54
|
+
* @returns The account or undefined if not found.
|
|
62
55
|
*/
|
|
63
56
|
getAccount(id: Account['id']): Account | undefined;
|
|
64
57
|
/**
|
|
65
|
-
* Query
|
|
58
|
+
* Query an account matching the selector.
|
|
66
59
|
*
|
|
67
60
|
* @param selector - Query selector.
|
|
68
|
-
* @returns The
|
|
61
|
+
* @returns The account matching the selector or undefined if not matching.
|
|
69
62
|
* @throws If multiple accounts match the selector.
|
|
70
63
|
*/
|
|
71
|
-
get(selector:
|
|
64
|
+
get(selector: AccountSelector<Account>): Account | undefined;
|
|
72
65
|
/**
|
|
73
|
-
* Query
|
|
66
|
+
* Query accounts matching the selector.
|
|
74
67
|
*
|
|
75
68
|
* @param selector - Query selector.
|
|
76
|
-
* @returns The
|
|
69
|
+
* @returns The accounts matching the selector.
|
|
77
70
|
*/
|
|
78
|
-
select(selector:
|
|
79
|
-
};
|
|
80
|
-
export declare class MultichainAccountAdapter<Account extends KeyringAccount> implements MultichainAccount<Account> {
|
|
81
|
-
#private;
|
|
82
|
-
constructor({ groupIndex, wallet, providers, }: {
|
|
83
|
-
groupIndex: number;
|
|
84
|
-
wallet: MultichainAccountWallet<Account>;
|
|
85
|
-
providers: MultichainAccountProvider<Account>[];
|
|
86
|
-
});
|
|
87
|
-
get id(): MultichainAccountId;
|
|
88
|
-
get wallet(): MultichainAccountWallet<Account>;
|
|
89
|
-
get index(): number;
|
|
90
|
-
hasAccounts(): boolean;
|
|
91
|
-
getAccounts(): Account[];
|
|
92
|
-
getAccount(id: Account['id']): Account | undefined;
|
|
93
|
-
get(selector: MultichainAccountSelector<Account>): Account | undefined;
|
|
94
|
-
select(selector: MultichainAccountSelector<Account>): Account[];
|
|
71
|
+
select(selector: AccountSelector<Account>): Account[];
|
|
95
72
|
}
|
|
96
73
|
/**
|
|
97
74
|
* Gets the multichain account ID from its multichain account wallet ID and its index.
|
|
@@ -101,11 +78,18 @@ export declare class MultichainAccountAdapter<Account extends KeyringAccount> im
|
|
|
101
78
|
* @returns The multichain account ID.
|
|
102
79
|
*/
|
|
103
80
|
export declare function toMultichainAccountId(walletId: MultichainAccountWalletId, groupIndex: number): MultichainAccountId;
|
|
81
|
+
/**
|
|
82
|
+
* Checks if the given value is {@link MultichainAccountId}.
|
|
83
|
+
*
|
|
84
|
+
* @param value - The value to check.
|
|
85
|
+
* @returns Whether the value is a {@link MultichainAccountId}.
|
|
86
|
+
*/
|
|
87
|
+
export declare function isMultichainAccountId(value: string): value is MultichainAccountId;
|
|
104
88
|
/**
|
|
105
89
|
* Gets the multichain account index from an account group ID.
|
|
106
90
|
*
|
|
107
|
-
* @param
|
|
91
|
+
* @param id - Multichain account ID.
|
|
108
92
|
* @returns The multichain account index if extractable, undefined otherwise.
|
|
109
93
|
*/
|
|
110
|
-
export declare function
|
|
94
|
+
export declare function getGroupIndexFromMultichainAccountId(id: MultichainAccountId): number;
|
|
111
95
|
//# sourceMappingURL=account.d.mts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"account.d.mts","sourceRoot":"","sources":["../../../src/api/multichain/account.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"account.d.mts","sourceRoot":"","sources":["../../../src/api/multichain/account.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,cAAc,EACpB,8BAA8B;AAG/B,OAAO,KAAK,EACV,uBAAuB,EACvB,yBAAyB,EAC1B,qBAAiB;AAClB,OAAO,KAAK,EAAE,YAAY,EAAE,qBAAiB;AAC7C,OAAO,KAAK,EAAE,eAAe,EAAE,wBAAoB;AACnD,OAAO,KAAK,EAAE,eAAe,EAAE,wBAAoB;AAQnD;;GAEG;AACH,MAAM,MAAM,mBAAmB,GAAG,GAAG,yBAAyB,IAAI,MAAM,EAAE,CAAC;AAE3E;;GAEG;AACH,qBAAa,iBAAiB,CAAC,OAAO,SAAS,cAAc,CAC3D,YAAW,YAAY,CAAC,OAAO,CAAC;;gBAUpB,EACV,UAAU,EACV,MAAM,EACN,SAAS,GACV,EAAE;QACD,UAAU,EAAE,MAAM,CAAC;QACnB,MAAM,EAAE,uBAAuB,CAAC,OAAO,CAAC,CAAC;QACzC,SAAS,EAAE,eAAe,CAAC,OAAO,CAAC,EAAE,CAAC;KACvC;IAOD;;;;OAIG;IACH,IAAI,EAAE,IAAI,mBAAmB,CAE5B;IAED;;;;OAIG;IACH,IAAI,MAAM,IAAI,uBAAuB,CAAC,OAAO,CAAC,CAE7C;IAED;;;;OAIG;IACH,IAAI,KAAK,IAAI,MAAM,CAElB;IAED;;;;OAIG;IACH,WAAW,IAAI,OAAO;IAItB;;;;OAIG;IACH,WAAW,IAAI,OAAO,EAAE;IAuBxB;;;;;OAKG;IACH,UAAU,CAAC,EAAE,EAAE,OAAO,CAAC,IAAI,CAAC,GAAG,OAAO,GAAG,SAAS;IAMlD;;;;;;OAMG;IACH,GAAG,CAAC,QAAQ,EAAE,eAAe,CAAC,OAAO,CAAC,GAAG,OAAO,GAAG,SAAS;IAgB5D;;;;;OAKG;IACH,MAAM,CAAC,QAAQ,EAAE,eAAe,CAAC,OAAO,CAAC,GAAG,OAAO,EAAE;CA8BtD;AAED;;;;;;GAMG;AACH,wBAAgB,qBAAqB,CACnC,QAAQ,EAAE,yBAAyB,EACnC,UAAU,EAAE,MAAM,GACjB,mBAAmB,CAErB;AAED;;;;;GAKG;AACH,wBAAgB,qBAAqB,CACnC,KAAK,EAAE,MAAM,GACZ,KAAK,IAAI,mBAAmB,CAE9B;AAED;;;;;GAKG;AACH,wBAAgB,oCAAoC,CAClD,EAAE,EAAE,mBAAmB,GACtB,MAAM,CASR"}
|
|
@@ -9,60 +9,96 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
|
|
|
9
9
|
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
|
|
10
10
|
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
11
11
|
};
|
|
12
|
-
var
|
|
12
|
+
var _MultichainAccount_id, _MultichainAccount_wallet, _MultichainAccount_index, _MultichainAccount_providers;
|
|
13
|
+
import { KeyringAccountEntropyTypeOption } from "@metamask/keyring-api";
|
|
13
14
|
import { isScopeEqualToAny } from "@metamask/keyring-utils";
|
|
14
15
|
import { AccountWalletCategory } from "../wallet.mjs";
|
|
15
|
-
const
|
|
16
|
-
|
|
16
|
+
const MULTICHAIN_ACCOUNT_ID_REGEX = new RegExp(`^${AccountWalletCategory.Entropy}:.*/(?<groupIndex>\\d+)$`, 'u');
|
|
17
|
+
/**
|
|
18
|
+
* A multichain account that holds multiple accounts.
|
|
19
|
+
*/
|
|
20
|
+
export class MultichainAccount {
|
|
17
21
|
constructor({ groupIndex, wallet, providers, }) {
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
__classPrivateFieldSet(this,
|
|
25
|
-
__classPrivateFieldSet(this,
|
|
26
|
-
__classPrivateFieldSet(this, _MultichainAccountAdapter_wallet, wallet, "f");
|
|
27
|
-
__classPrivateFieldSet(this, _MultichainAccountAdapter_providers, providers, "f");
|
|
28
|
-
__classPrivateFieldSet(this, _MultichainAccountAdapter_accounts, new Map(), "f");
|
|
29
|
-
__classPrivateFieldSet(this, _MultichainAccountAdapter_providersByAccountId, new Map(), "f");
|
|
30
|
-
for (const provider of __classPrivateFieldGet(this, _MultichainAccountAdapter_providers, "f")) {
|
|
31
|
-
const accounts = provider.getAccounts({
|
|
32
|
-
entropySource: __classPrivateFieldGet(this, _MultichainAccountAdapter_wallet, "f").entropySource,
|
|
33
|
-
groupIndex: __classPrivateFieldGet(this, _MultichainAccountAdapter_index, "f"),
|
|
34
|
-
});
|
|
35
|
-
__classPrivateFieldGet(this, _MultichainAccountAdapter_accounts, "f").set(provider, accounts);
|
|
36
|
-
for (const id of accounts) {
|
|
37
|
-
__classPrivateFieldGet(this, _MultichainAccountAdapter_providersByAccountId, "f").set(id, provider);
|
|
38
|
-
}
|
|
39
|
-
}
|
|
22
|
+
_MultichainAccount_id.set(this, void 0);
|
|
23
|
+
_MultichainAccount_wallet.set(this, void 0);
|
|
24
|
+
_MultichainAccount_index.set(this, void 0);
|
|
25
|
+
_MultichainAccount_providers.set(this, void 0);
|
|
26
|
+
__classPrivateFieldSet(this, _MultichainAccount_id, toMultichainAccountId(wallet.id, groupIndex), "f");
|
|
27
|
+
__classPrivateFieldSet(this, _MultichainAccount_index, groupIndex, "f");
|
|
28
|
+
__classPrivateFieldSet(this, _MultichainAccount_wallet, wallet, "f");
|
|
29
|
+
__classPrivateFieldSet(this, _MultichainAccount_providers, providers, "f");
|
|
40
30
|
}
|
|
31
|
+
/**
|
|
32
|
+
* Gets the multichain account ID.
|
|
33
|
+
*
|
|
34
|
+
* @returns The multichain account ID.
|
|
35
|
+
*/
|
|
41
36
|
get id() {
|
|
42
|
-
return __classPrivateFieldGet(this,
|
|
37
|
+
return __classPrivateFieldGet(this, _MultichainAccount_id, "f");
|
|
43
38
|
}
|
|
39
|
+
/**
|
|
40
|
+
* Gets the multichain account's wallet reference (parent).
|
|
41
|
+
*
|
|
42
|
+
* @returns The multichain account's wallet.
|
|
43
|
+
*/
|
|
44
44
|
get wallet() {
|
|
45
|
-
return __classPrivateFieldGet(this,
|
|
45
|
+
return __classPrivateFieldGet(this, _MultichainAccount_wallet, "f");
|
|
46
46
|
}
|
|
47
|
+
/**
|
|
48
|
+
* Gets the multichain account group index.
|
|
49
|
+
*
|
|
50
|
+
* @returns The multichain account group index.
|
|
51
|
+
*/
|
|
47
52
|
get index() {
|
|
48
|
-
return __classPrivateFieldGet(this,
|
|
53
|
+
return __classPrivateFieldGet(this, _MultichainAccount_index, "f");
|
|
49
54
|
}
|
|
55
|
+
/**
|
|
56
|
+
* Checks if there's any underlying accounts for this multichain accounts.
|
|
57
|
+
*
|
|
58
|
+
* @returns True if there's any underlying accounts, false otherwise.
|
|
59
|
+
*/
|
|
50
60
|
hasAccounts() {
|
|
51
|
-
|
|
52
|
-
// be empty.
|
|
53
|
-
return __classPrivateFieldGet(this, _MultichainAccountAdapter_providersByAccountId, "f").size > 0;
|
|
61
|
+
return this.getAccounts().length > 0;
|
|
54
62
|
}
|
|
63
|
+
/**
|
|
64
|
+
* Gets the accounts for this multichain account.
|
|
65
|
+
*
|
|
66
|
+
* @returns The accounts.
|
|
67
|
+
*/
|
|
55
68
|
getAccounts() {
|
|
56
69
|
let allAccounts = [];
|
|
57
|
-
for (const
|
|
58
|
-
allAccounts = allAccounts.concat(
|
|
70
|
+
for (const provider of __classPrivateFieldGet(this, _MultichainAccount_providers, "f")) {
|
|
71
|
+
allAccounts = allAccounts.concat(provider.getAccounts().filter(
|
|
72
|
+
// NOTE: For now we always query the providers to get the latest
|
|
73
|
+
// account list. If this becomes too "heavy" in terms of computation
|
|
74
|
+
// we might wanna consider adding a state to that object and store
|
|
75
|
+
// the list of account IDs here.
|
|
76
|
+
(account) => account.options.entropy &&
|
|
77
|
+
account.options.entropy.type ===
|
|
78
|
+
KeyringAccountEntropyTypeOption.Mnemonic &&
|
|
79
|
+
account.options.entropy.id === this.wallet.entropySource &&
|
|
80
|
+
account.options.entropy.groupIndex === this.index));
|
|
59
81
|
}
|
|
60
82
|
return allAccounts;
|
|
61
83
|
}
|
|
84
|
+
/**
|
|
85
|
+
* Gets the account for a given account ID.
|
|
86
|
+
*
|
|
87
|
+
* @param id - Account ID.
|
|
88
|
+
* @returns The account or undefined if not found.
|
|
89
|
+
*/
|
|
62
90
|
getAccount(id) {
|
|
63
|
-
|
|
64
|
-
|
|
91
|
+
// NOTE: Same remark here. We could keep a state to make this operation
|
|
92
|
+
// faster.
|
|
93
|
+
return this.getAccounts().find((account) => account.id === id);
|
|
65
94
|
}
|
|
95
|
+
/**
|
|
96
|
+
* Query an account matching the selector.
|
|
97
|
+
*
|
|
98
|
+
* @param selector - Query selector.
|
|
99
|
+
* @returns The account matching the selector or undefined if not matching.
|
|
100
|
+
* @throws If multiple accounts match the selector.
|
|
101
|
+
*/
|
|
66
102
|
get(selector) {
|
|
67
103
|
const accounts = this.select(selector);
|
|
68
104
|
if (accounts.length > 1) {
|
|
@@ -73,6 +109,12 @@ export class MultichainAccountAdapter {
|
|
|
73
109
|
}
|
|
74
110
|
return accounts[0]; // This is safe, see checks above.
|
|
75
111
|
}
|
|
112
|
+
/**
|
|
113
|
+
* Query accounts matching the selector.
|
|
114
|
+
*
|
|
115
|
+
* @param selector - Query selector.
|
|
116
|
+
* @returns The accounts matching the selector.
|
|
117
|
+
*/
|
|
76
118
|
select(selector) {
|
|
77
119
|
return this.getAccounts().filter((account) => {
|
|
78
120
|
let selected = true;
|
|
@@ -99,7 +141,7 @@ export class MultichainAccountAdapter {
|
|
|
99
141
|
});
|
|
100
142
|
}
|
|
101
143
|
}
|
|
102
|
-
|
|
144
|
+
_MultichainAccount_id = new WeakMap(), _MultichainAccount_wallet = new WeakMap(), _MultichainAccount_index = new WeakMap(), _MultichainAccount_providers = new WeakMap();
|
|
103
145
|
/**
|
|
104
146
|
* Gets the multichain account ID from its multichain account wallet ID and its index.
|
|
105
147
|
*
|
|
@@ -110,20 +152,28 @@ _MultichainAccountAdapter_id = new WeakMap(), _MultichainAccountAdapter_wallet =
|
|
|
110
152
|
export function toMultichainAccountId(walletId, groupIndex) {
|
|
111
153
|
return `${walletId}/${groupIndex}`;
|
|
112
154
|
}
|
|
155
|
+
/**
|
|
156
|
+
* Checks if the given value is {@link MultichainAccountId}.
|
|
157
|
+
*
|
|
158
|
+
* @param value - The value to check.
|
|
159
|
+
* @returns Whether the value is a {@link MultichainAccountId}.
|
|
160
|
+
*/
|
|
161
|
+
export function isMultichainAccountId(value) {
|
|
162
|
+
return MULTICHAIN_ACCOUNT_ID_REGEX.test(value);
|
|
163
|
+
}
|
|
113
164
|
/**
|
|
114
165
|
* Gets the multichain account index from an account group ID.
|
|
115
166
|
*
|
|
116
|
-
* @param
|
|
167
|
+
* @param id - Multichain account ID.
|
|
117
168
|
* @returns The multichain account index if extractable, undefined otherwise.
|
|
118
169
|
*/
|
|
119
|
-
export function
|
|
120
|
-
const matched =
|
|
121
|
-
if (matched) {
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
170
|
+
export function getGroupIndexFromMultichainAccountId(id) {
|
|
171
|
+
const matched = id.match(MULTICHAIN_ACCOUNT_ID_REGEX);
|
|
172
|
+
if (matched?.groups?.groupIndex === undefined) {
|
|
173
|
+
// Unable to extract group index, even though, type wise, this should not
|
|
174
|
+
// be possible!
|
|
175
|
+
throw new Error('Unable to extract group index');
|
|
125
176
|
}
|
|
126
|
-
|
|
127
|
-
return undefined;
|
|
177
|
+
return Number(matched.groups.groupIndex);
|
|
128
178
|
}
|
|
129
179
|
//# sourceMappingURL=account.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"account.mjs","sourceRoot":"","sources":["../../../src/api/multichain/account.ts"],"names":[],"mappings":";;;;;;;;;;;;AACA,OAAO,EAAE,iBAAiB,EAAE,gCAAgC;AAQ5D,OAAO,EAAE,qBAAqB,EAAE,sBAAkB;AAElD,MAAM,oCAAoC,GAAG,IAAI,MAAM,CACrD,IAAI,qBAAqB,CAAC,OAAO,0BAA0B,EAC3D,GAAG,CACJ,CAAC;AA2FF,MAAM,OAAO,wBAAwB;IAkBnC,YAAY,EACV,UAAU,EACV,MAAM,EACN,SAAS,GAKV;QAvBQ,+CAAyB;QAEzB,mDAA0C;QAE1C,kDAAe;QAEf,sDAAiD;QAEjD,iEAGP;QAEO,qDAAoE;QAW3E,uBAAA,IAAI,gCAAO,qBAAqB,CAAC,MAAM,CAAC,EAAE,EAAE,UAAU,CAAC,MAAA,CAAC;QACxD,uBAAA,IAAI,mCAAU,UAAU,MAAA,CAAC;QACzB,uBAAA,IAAI,oCAAW,MAAM,MAAA,CAAC;QACtB,uBAAA,IAAI,uCAAc,SAAS,MAAA,CAAC;QAC5B,uBAAA,IAAI,sCAAa,IAAI,GAAG,EAAE,MAAA,CAAC;QAC3B,uBAAA,IAAI,kDAAyB,IAAI,GAAG,EAAE,MAAA,CAAC;QAEvC,KAAK,MAAM,QAAQ,IAAI,uBAAA,IAAI,2CAAW,EAAE,CAAC;YACvC,MAAM,QAAQ,GAAG,QAAQ,CAAC,WAAW,CAAC;gBACpC,aAAa,EAAE,uBAAA,IAAI,wCAAQ,CAAC,aAAa;gBACzC,UAAU,EAAE,uBAAA,IAAI,uCAAO;aACxB,CAAC,CAAC;YAEH,uBAAA,IAAI,0CAAU,CAAC,GAAG,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;YACvC,KAAK,MAAM,EAAE,IAAI,QAAQ,EAAE,CAAC;gBAC1B,uBAAA,IAAI,sDAAsB,CAAC,GAAG,CAAC,EAAE,EAAE,QAAQ,CAAC,CAAC;YAC/C,CAAC;QACH,CAAC;IACH,CAAC;IAED,IAAI,EAAE;QACJ,OAAO,uBAAA,IAAI,oCAAI,CAAC;IAClB,CAAC;IAED,IAAI,MAAM;QACR,OAAO,uBAAA,IAAI,wCAAQ,CAAC;IACtB,CAAC;IAED,IAAI,KAAK;QACP,OAAO,uBAAA,IAAI,uCAAO,CAAC;IACrB,CAAC;IAED,WAAW;QACT,sEAAsE;QACtE,YAAY;QACZ,OAAO,uBAAA,IAAI,sDAAsB,CAAC,IAAI,GAAG,CAAC,CAAC;IAC7C,CAAC;IAED,WAAW;QACT,IAAI,WAAW,GAAc,EAAE,CAAC;QAEhC,KAAK,MAAM,CAAC,QAAQ,EAAE,QAAQ,CAAC,IAAI,uBAAA,IAAI,0CAAU,CAAC,OAAO,EAAE,EAAE,CAAC;YAC5D,WAAW,GAAG,WAAW,CAAC,MAAM,CAC9B,QAAQ,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,QAAQ,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC,CAC9C,CAAC;QACJ,CAAC;QAED,OAAO,WAAW,CAAC;IACrB,CAAC;IAED,UAAU,CAAC,EAAiB;QAC1B,MAAM,QAAQ,GAAG,uBAAA,IAAI,sDAAsB,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAEpD,OAAO,QAAQ,EAAE,UAAU,CAAC,EAAE,CAAC,CAAC;IAClC,CAAC;IAED,GAAG,CAAC,QAA4C;QAC9C,MAAM,QAAQ,GAAG,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;QAEvC,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACxB,MAAM,IAAI,KAAK,CACb,iDAAiD,QAAQ,CAAC,MAAM,EAAE,CACnE,CAAC;QACJ,CAAC;QAED,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC1B,OAAO,SAAS,CAAC;QACnB,CAAC;QAED,OAAO,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,kCAAkC;IACxD,CAAC;IAED,MAAM,CAAC,QAA4C;QACjD,OAAO,IAAI,CAAC,WAAW,EAAE,CAAC,MAAM,CAAC,CAAC,OAAO,EAAE,EAAE;YAC3C,IAAI,QAAQ,GAAG,IAAI,CAAC;YAEpB,IAAI,QAAQ,CAAC,EAAE,EAAE,CAAC;gBAChB,QAAQ,KAAR,QAAQ,GAAK,OAAO,CAAC,EAAE,KAAK,QAAQ,CAAC,EAAE,EAAC;YAC1C,CAAC;YACD,IAAI,QAAQ,CAAC,OAAO,EAAE,CAAC;gBACrB,QAAQ,KAAR,QAAQ,GAAK,OAAO,CAAC,OAAO,KAAK,QAAQ,CAAC,OAAO,EAAC;YACpD,CAAC;YACD,IAAI,QAAQ,CAAC,IAAI,EAAE,CAAC;gBAClB,QAAQ,KAAR,QAAQ,GAAK,OAAO,CAAC,IAAI,KAAK,QAAQ,CAAC,IAAI,EAAC;YAC9C,CAAC;YACD,IAAI,QAAQ,CAAC,OAAO,KAAK,SAAS,EAAE,CAAC;gBACnC,QAAQ,KAAR,QAAQ,GAAK,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,CAC5C,OAAO,CAAC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,CACjC,EAAC;YACJ,CAAC;YACD,IAAI,QAAQ,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;gBAClC,QAAQ,KAAR,QAAQ,GAAK,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE;oBAC1C,OAAO;oBACL,mDAAmD;oBACnD,iBAAiB,CAAC,KAAK,EAAE,OAAO,CAAC,MAAM,CAAC,CACzC,CAAC;gBACJ,CAAC,CAAC,EAAC;YACL,CAAC;YAED,OAAO,QAAQ,CAAC;QAClB,CAAC,CAAC,CAAC;IACL,CAAC;CACF;;AAED;;;;;;GAMG;AACH,MAAM,UAAU,qBAAqB,CACnC,QAAmC,EACnC,UAAkB;IAElB,OAAO,GAAG,QAAQ,IAAI,UAAU,EAAE,CAAC;AACrC,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,+BAA+B,CAC7C,OAAuB;IAEvB,MAAM,OAAO,GAAG,OAAO,CAAC,KAAK,CAAC,oCAAoC,CAAC,CAAC;IACpE,IAAI,OAAO,EAAE,CAAC;QACZ,IAAI,OAAO,CAAC,MAAM,EAAE,UAAU,KAAK,SAAS,EAAE,CAAC;YAC7C,OAAO,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;QAC3C,CAAC;IACH,CAAC;IAED,iCAAiC;IACjC,OAAO,SAAS,CAAC;AACnB,CAAC","sourcesContent":["import type { KeyringAccount } from '@metamask/keyring-api';\nimport { isScopeEqualToAny } from '@metamask/keyring-utils';\n\nimport type { MultichainAccountProvider } from './provider';\nimport type {\n MultichainAccountWallet,\n MultichainAccountWalletId,\n} from './wallet';\nimport type { AccountGroup, AccountGroupId } from '../group';\nimport { AccountWalletCategory } from '../wallet';\n\nconst MULTICHAIN_ACCOUNT_GROUP_INDEX_REGEX = new RegExp(\n `^${AccountWalletCategory.Entropy}:.*/(?<groupIndex>\\\\d+)$`,\n 'u',\n);\n\n/**\n * Selector to query a specific \"blockchain\" account based on some criteria.\n */\nexport type MultichainAccountSelector<Account extends KeyringAccount> = {\n /**\n * Query by account ID.\n */\n id?: Account['id'];\n\n /**\n * Query by account address.\n */\n address?: Account['address'];\n\n /**\n * Query by account type.\n */\n type?: Account['type'];\n\n /**\n * Query by account methods.\n */\n methods?: Account['methods'];\n\n /**\n * Query by account scopes.\n */\n scopes?: Account['scopes'];\n};\n\n/**\n * Multichain account ID.\n */\nexport type MultichainAccountId = `${MultichainAccountWalletId}/${number}`; // Use number for the account group index.\n\n/**\n * A multichain account that holds multiple \"blockchain\" accounts.\n */\nexport type MultichainAccount<Account extends KeyringAccount> =\n AccountGroup<Account> & {\n /**\n * Multichain account ID.\n */\n get id(): MultichainAccountId;\n\n /**\n * Multichain account's wallet reference (parent).\n */\n get wallet(): MultichainAccountWallet<Account>;\n\n /**\n * Multichain account group index.\n */\n get index(): number;\n\n /**\n * Gets the \"blockchain\" accounts for this multichain account.\n *\n * @param id - Account ID.\n * @returns The \"blockchain\" accounts.\n */\n getAccounts(): Account[];\n\n /**\n * Gets the \"blockchain\" account for a given account ID.\n *\n * @param id - Account ID.\n * @returns The \"blockchain\" account or undefined if not found.\n */\n getAccount(id: Account['id']): Account | undefined;\n\n /**\n * Query a \"blockchain\" account matching the selector.\n *\n * @param selector - Query selector.\n * @returns The \"blockchain\" account matching the selector or undefined if not matching.\n * @throws If multiple accounts match the selector.\n */\n get(selector: MultichainAccountSelector<Account>): Account | undefined;\n\n /**\n * Query \"blockchain\" accounts matching the selector.\n *\n * @param selector - Query selector.\n * @returns The \"blockchain\" accounts matching the selector.\n */\n select(selector: MultichainAccountSelector<Account>): Account[];\n };\n\nexport class MultichainAccountAdapter<Account extends KeyringAccount>\n implements MultichainAccount<Account>\n{\n readonly #id: MultichainAccountId;\n\n readonly #wallet: MultichainAccountWallet<Account>;\n\n readonly #index: number;\n\n readonly #providers: MultichainAccountProvider<Account>[];\n\n readonly #providersByAccountId: Map<\n Account['id'],\n MultichainAccountProvider<Account>\n >;\n\n readonly #accounts: Map<MultichainAccountProvider<Account>, Account['id'][]>;\n\n constructor({\n groupIndex,\n wallet,\n providers,\n }: {\n groupIndex: number;\n wallet: MultichainAccountWallet<Account>;\n providers: MultichainAccountProvider<Account>[];\n }) {\n this.#id = toMultichainAccountId(wallet.id, groupIndex);\n this.#index = groupIndex;\n this.#wallet = wallet;\n this.#providers = providers;\n this.#accounts = new Map();\n this.#providersByAccountId = new Map();\n\n for (const provider of this.#providers) {\n const accounts = provider.getAccounts({\n entropySource: this.#wallet.entropySource,\n groupIndex: this.#index,\n });\n\n this.#accounts.set(provider, accounts);\n for (const id of accounts) {\n this.#providersByAccountId.set(id, provider);\n }\n }\n }\n\n get id(): MultichainAccountId {\n return this.#id;\n }\n\n get wallet(): MultichainAccountWallet<Account> {\n return this.#wallet;\n }\n\n get index(): number {\n return this.#index;\n }\n\n hasAccounts(): boolean {\n // Use this map, cause if there's no accounts, then this map will also\n // be empty.\n return this.#providersByAccountId.size > 0;\n }\n\n getAccounts(): Account[] {\n let allAccounts: Account[] = [];\n\n for (const [provider, accounts] of this.#accounts.entries()) {\n allAccounts = allAccounts.concat(\n accounts.map((id) => provider.getAccount(id)),\n );\n }\n\n return allAccounts;\n }\n\n getAccount(id: Account['id']): Account | undefined {\n const provider = this.#providersByAccountId.get(id);\n\n return provider?.getAccount(id);\n }\n\n get(selector: MultichainAccountSelector<Account>): Account | undefined {\n const accounts = this.select(selector);\n\n if (accounts.length > 1) {\n throw new Error(\n `Too many account candidates, expected 1, got: ${accounts.length}`,\n );\n }\n\n if (accounts.length === 0) {\n return undefined;\n }\n\n return accounts[0]; // This is safe, see checks above.\n }\n\n select(selector: MultichainAccountSelector<Account>): Account[] {\n return this.getAccounts().filter((account) => {\n let selected = true;\n\n if (selector.id) {\n selected &&= account.id === selector.id;\n }\n if (selector.address) {\n selected &&= account.address === selector.address;\n }\n if (selector.type) {\n selected &&= account.type === selector.type;\n }\n if (selector.methods !== undefined) {\n selected &&= selector.methods.some((method) =>\n account.methods.includes(method),\n );\n }\n if (selector.scopes !== undefined) {\n selected &&= selector.scopes.some((scope) => {\n return (\n // This will cover specific EVM EOA scopes as well.\n isScopeEqualToAny(scope, account.scopes)\n );\n });\n }\n\n return selected;\n });\n }\n}\n\n/**\n * Gets the multichain account ID from its multichain account wallet ID and its index.\n *\n * @param walletId - Multichain account wallet ID.\n * @param groupIndex - Index of that multichain account.\n * @returns The multichain account ID.\n */\nexport function toMultichainAccountId(\n walletId: MultichainAccountWalletId,\n groupIndex: number,\n): MultichainAccountId {\n return `${walletId}/${groupIndex}`;\n}\n\n/**\n * Gets the multichain account index from an account group ID.\n *\n * @param groupId - Account group ID.\n * @returns The multichain account index if extractable, undefined otherwise.\n */\nexport function getGroupIndexFromAccountGroupId(\n groupId: AccountGroupId,\n): number | undefined {\n const matched = groupId.match(MULTICHAIN_ACCOUNT_GROUP_INDEX_REGEX);\n if (matched) {\n if (matched.groups?.groupIndex !== undefined) {\n return Number(matched.groups.groupIndex);\n }\n }\n\n // Unable to extract group index.\n return undefined;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"account.mjs","sourceRoot":"","sources":["../../../src/api/multichain/account.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n KeyringAccountEntropyTypeOption,\n type KeyringAccount,\n} from '@metamask/keyring-api';\nimport { isScopeEqualToAny } from '@metamask/keyring-utils';\n\nimport type {\n MultichainAccountWallet,\n MultichainAccountWalletId,\n} from './wallet';\nimport type { AccountGroup } from '../group';\nimport type { AccountProvider } from '../provider';\nimport type { AccountSelector } from '../selector';\nimport { AccountWalletCategory } from '../wallet';\n\nconst MULTICHAIN_ACCOUNT_ID_REGEX = new RegExp(\n `^${AccountWalletCategory.Entropy}:.*/(?<groupIndex>\\\\d+)$`,\n 'u',\n);\n\n/**\n * Multichain account ID.\n */\nexport type MultichainAccountId = `${MultichainAccountWalletId}/${number}`; // Use number for the account group index.\n\n/**\n * A multichain account that holds multiple accounts.\n */\nexport class MultichainAccount<Account extends KeyringAccount>\n implements AccountGroup<Account>\n{\n readonly #id: MultichainAccountId;\n\n readonly #wallet: MultichainAccountWallet<Account>;\n\n readonly #index: number;\n\n readonly #providers: AccountProvider<Account>[];\n\n constructor({\n groupIndex,\n wallet,\n providers,\n }: {\n groupIndex: number;\n wallet: MultichainAccountWallet<Account>;\n providers: AccountProvider<Account>[];\n }) {\n this.#id = toMultichainAccountId(wallet.id, groupIndex);\n this.#index = groupIndex;\n this.#wallet = wallet;\n this.#providers = providers;\n }\n\n /**\n * Gets the multichain account ID.\n *\n * @returns The multichain account ID.\n */\n get id(): MultichainAccountId {\n return this.#id;\n }\n\n /**\n * Gets the multichain account's wallet reference (parent).\n *\n * @returns The multichain account's wallet.\n */\n get wallet(): MultichainAccountWallet<Account> {\n return this.#wallet;\n }\n\n /**\n * Gets the multichain account group index.\n *\n * @returns The multichain account group index.\n */\n get index(): number {\n return this.#index;\n }\n\n /**\n * Checks if there's any underlying accounts for this multichain accounts.\n *\n * @returns True if there's any underlying accounts, false otherwise.\n */\n hasAccounts(): boolean {\n return this.getAccounts().length > 0;\n }\n\n /**\n * Gets the accounts for this multichain account.\n *\n * @returns The accounts.\n */\n getAccounts(): Account[] {\n let allAccounts: Account[] = [];\n\n for (const provider of this.#providers) {\n allAccounts = allAccounts.concat(\n provider.getAccounts().filter(\n // NOTE: For now we always query the providers to get the latest\n // account list. If this becomes too \"heavy\" in terms of computation\n // we might wanna consider adding a state to that object and store\n // the list of account IDs here.\n (account) =>\n account.options.entropy &&\n account.options.entropy.type ===\n KeyringAccountEntropyTypeOption.Mnemonic &&\n account.options.entropy.id === this.wallet.entropySource &&\n account.options.entropy.groupIndex === this.index,\n ),\n );\n }\n\n return allAccounts;\n }\n\n /**\n * Gets the account for a given account ID.\n *\n * @param id - Account ID.\n * @returns The account or undefined if not found.\n */\n getAccount(id: Account['id']): Account | undefined {\n // NOTE: Same remark here. We could keep a state to make this operation\n // faster.\n return this.getAccounts().find((account) => account.id === id);\n }\n\n /**\n * Query an account matching the selector.\n *\n * @param selector - Query selector.\n * @returns The account matching the selector or undefined if not matching.\n * @throws If multiple accounts match the selector.\n */\n get(selector: AccountSelector<Account>): Account | undefined {\n const accounts = this.select(selector);\n\n if (accounts.length > 1) {\n throw new Error(\n `Too many account candidates, expected 1, got: ${accounts.length}`,\n );\n }\n\n if (accounts.length === 0) {\n return undefined;\n }\n\n return accounts[0]; // This is safe, see checks above.\n }\n\n /**\n * Query accounts matching the selector.\n *\n * @param selector - Query selector.\n * @returns The accounts matching the selector.\n */\n select(selector: AccountSelector<Account>): Account[] {\n return this.getAccounts().filter((account) => {\n let selected = true;\n\n if (selector.id) {\n selected &&= account.id === selector.id;\n }\n if (selector.address) {\n selected &&= account.address === selector.address;\n }\n if (selector.type) {\n selected &&= account.type === selector.type;\n }\n if (selector.methods !== undefined) {\n selected &&= selector.methods.some((method) =>\n account.methods.includes(method),\n );\n }\n if (selector.scopes !== undefined) {\n selected &&= selector.scopes.some((scope) => {\n return (\n // This will cover specific EVM EOA scopes as well.\n isScopeEqualToAny(scope, account.scopes)\n );\n });\n }\n\n return selected;\n });\n }\n}\n\n/**\n * Gets the multichain account ID from its multichain account wallet ID and its index.\n *\n * @param walletId - Multichain account wallet ID.\n * @param groupIndex - Index of that multichain account.\n * @returns The multichain account ID.\n */\nexport function toMultichainAccountId(\n walletId: MultichainAccountWalletId,\n groupIndex: number,\n): MultichainAccountId {\n return `${walletId}/${groupIndex}`;\n}\n\n/**\n * Checks if the given value is {@link MultichainAccountId}.\n *\n * @param value - The value to check.\n * @returns Whether the value is a {@link MultichainAccountId}.\n */\nexport function isMultichainAccountId(\n value: string,\n): value is MultichainAccountId {\n return MULTICHAIN_ACCOUNT_ID_REGEX.test(value);\n}\n\n/**\n * Gets the multichain account index from an account group ID.\n *\n * @param id - Multichain account ID.\n * @returns The multichain account index if extractable, undefined otherwise.\n */\nexport function getGroupIndexFromMultichainAccountId(\n id: MultichainAccountId,\n): number {\n const matched = id.match(MULTICHAIN_ACCOUNT_ID_REGEX);\n if (matched?.groups?.groupIndex === undefined) {\n // Unable to extract group index, even though, type wise, this should not\n // be possible!\n throw new Error('Unable to extract group index');\n }\n\n return Number(matched.groups.groupIndex);\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs","sourceRoot":"","sources":["../../../src/api/multichain/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,gDAA0B;AAC1B,+CAAyB","sourcesContent":["export * from './account';\nexport * from './wallet';\
|
|
1
|
+
{"version":3,"file":"index.cjs","sourceRoot":"","sources":["../../../src/api/multichain/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,gDAA0B;AAC1B,+CAAyB","sourcesContent":["export * from './account';\nexport * from './wallet';\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.cts","sourceRoot":"","sources":["../../../src/api/multichain/index.ts"],"names":[],"mappings":"AAAA,8BAA0B;AAC1B,6BAAyB
|
|
1
|
+
{"version":3,"file":"index.d.cts","sourceRoot":"","sources":["../../../src/api/multichain/index.ts"],"names":[],"mappings":"AAAA,8BAA0B;AAC1B,6BAAyB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.mts","sourceRoot":"","sources":["../../../src/api/multichain/index.ts"],"names":[],"mappings":"AAAA,8BAA0B;AAC1B,6BAAyB
|
|
1
|
+
{"version":3,"file":"index.d.mts","sourceRoot":"","sources":["../../../src/api/multichain/index.ts"],"names":[],"mappings":"AAAA,8BAA0B;AAC1B,6BAAyB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","sourceRoot":"","sources":["../../../src/api/multichain/index.ts"],"names":[],"mappings":"AAAA,8BAA0B;AAC1B,6BAAyB","sourcesContent":["export * from './account';\nexport * from './wallet';\
|
|
1
|
+
{"version":3,"file":"index.mjs","sourceRoot":"","sources":["../../../src/api/multichain/index.ts"],"names":[],"mappings":"AAAA,8BAA0B;AAC1B,6BAAyB","sourcesContent":["export * from './account';\nexport * from './wallet';\n"]}
|
|
@@ -10,76 +10,142 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
|
|
|
10
10
|
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
|
|
11
11
|
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
12
12
|
};
|
|
13
|
-
var
|
|
13
|
+
var _MultichainAccountWallet_id, _MultichainAccountWallet_providers, _MultichainAccountWallet_entropySource, _MultichainAccountWallet_accounts;
|
|
14
14
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
-
exports.
|
|
15
|
+
exports.MultichainAccountWallet = void 0;
|
|
16
16
|
exports.toMultichainAccountWalletId = toMultichainAccountWalletId;
|
|
17
|
+
const keyring_api_1 = require("@metamask/keyring-api");
|
|
17
18
|
const account_1 = require("./account.cjs");
|
|
18
19
|
const group_1 = require("../group.cjs");
|
|
19
20
|
const wallet_1 = require("../wallet.cjs");
|
|
20
|
-
|
|
21
|
+
/**
|
|
22
|
+
* A multichain account wallet that holds multiple multichain accounts (one multichain account per
|
|
23
|
+
* group index).
|
|
24
|
+
*/
|
|
25
|
+
class MultichainAccountWallet {
|
|
21
26
|
constructor({ providers, entropySource, }) {
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
__classPrivateFieldSet(this,
|
|
27
|
-
__classPrivateFieldSet(this,
|
|
28
|
-
__classPrivateFieldSet(this,
|
|
29
|
-
__classPrivateFieldSet(this,
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
//
|
|
33
|
-
|
|
34
|
-
//
|
|
35
|
-
//
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
27
|
+
_MultichainAccountWallet_id.set(this, void 0);
|
|
28
|
+
_MultichainAccountWallet_providers.set(this, void 0);
|
|
29
|
+
_MultichainAccountWallet_entropySource.set(this, void 0);
|
|
30
|
+
_MultichainAccountWallet_accounts.set(this, void 0);
|
|
31
|
+
__classPrivateFieldSet(this, _MultichainAccountWallet_id, toMultichainAccountWalletId(entropySource), "f");
|
|
32
|
+
__classPrivateFieldSet(this, _MultichainAccountWallet_providers, providers, "f");
|
|
33
|
+
__classPrivateFieldSet(this, _MultichainAccountWallet_entropySource, entropySource, "f");
|
|
34
|
+
__classPrivateFieldSet(this, _MultichainAccountWallet_accounts, new Map(), "f");
|
|
35
|
+
// NOTE: This will traverse all accounts to compute the max index. We could try
|
|
36
|
+
// to minimize the number of filtering we're doing on each providers if this
|
|
37
|
+
// becomes too costly.
|
|
38
|
+
const maxGroupIndex = MultichainAccountWallet.getHighestGroupIndexFrom(providers, entropySource);
|
|
39
|
+
// NOTE: We could have some gap for now, until we fully implement the
|
|
40
|
+
// gap/alignment mechanisms to backfill all "missing accounts".
|
|
41
|
+
for (let groupIndex = 0; groupIndex <= maxGroupIndex; groupIndex++) {
|
|
42
|
+
// Use "lower or equal", since we need to "include" the max index (which
|
|
43
|
+
// can also be 0)
|
|
44
|
+
const multichainAccount = new account_1.MultichainAccount({
|
|
39
45
|
groupIndex,
|
|
40
46
|
wallet: this,
|
|
41
|
-
providers: __classPrivateFieldGet(this,
|
|
47
|
+
providers: __classPrivateFieldGet(this, _MultichainAccountWallet_providers, "f"),
|
|
42
48
|
});
|
|
43
49
|
// We only add multichain account that has underlying accounts.
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
50
|
+
if (multichainAccount.hasAccounts()) {
|
|
51
|
+
__classPrivateFieldGet(this, _MultichainAccountWallet_accounts, "f").set(groupIndex, multichainAccount);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Gets the highest group index from multiple account providers for a given
|
|
57
|
+
* entropy source.
|
|
58
|
+
*
|
|
59
|
+
* @param providers - Account providers.
|
|
60
|
+
* @param entropySource - Entropy source to filter on.
|
|
61
|
+
* @returns The highest group index for a given entropy source.
|
|
62
|
+
*/
|
|
63
|
+
static getHighestGroupIndexFrom(providers, entropySource) {
|
|
64
|
+
let max = -1;
|
|
65
|
+
for (const provider of providers) {
|
|
66
|
+
for (const account of provider.getAccounts()) {
|
|
67
|
+
if (account.options.entropy &&
|
|
68
|
+
account.options.entropy.type ===
|
|
69
|
+
keyring_api_1.KeyringAccountEntropyTypeOption.Mnemonic &&
|
|
70
|
+
account.options.entropy.id === entropySource) {
|
|
71
|
+
max = Math.max(max, account.options.entropy.groupIndex);
|
|
72
|
+
}
|
|
47
73
|
}
|
|
48
|
-
|
|
49
|
-
|
|
74
|
+
}
|
|
75
|
+
return max;
|
|
50
76
|
}
|
|
77
|
+
/**
|
|
78
|
+
* Gets the multichain account wallet ID.
|
|
79
|
+
*
|
|
80
|
+
* @returns The multichain account wallet ID.
|
|
81
|
+
*/
|
|
51
82
|
get id() {
|
|
52
|
-
return __classPrivateFieldGet(this,
|
|
83
|
+
return __classPrivateFieldGet(this, _MultichainAccountWallet_id, "f");
|
|
53
84
|
}
|
|
85
|
+
/**
|
|
86
|
+
* Gets the multichain account wallet category, which is always {@link AccountWalletCategory.Entropy}.
|
|
87
|
+
*
|
|
88
|
+
* @returns The multichain account wallet category.
|
|
89
|
+
*/
|
|
54
90
|
get category() {
|
|
55
91
|
return wallet_1.AccountWalletCategory.Entropy;
|
|
56
92
|
}
|
|
93
|
+
/**
|
|
94
|
+
* Gets the multichain account wallet entropy source.
|
|
95
|
+
*
|
|
96
|
+
* @returns The multichain account wallet entropy source.
|
|
97
|
+
*/
|
|
57
98
|
get entropySource() {
|
|
58
|
-
return __classPrivateFieldGet(this,
|
|
99
|
+
return __classPrivateFieldGet(this, _MultichainAccountWallet_entropySource, "f");
|
|
59
100
|
}
|
|
60
|
-
|
|
101
|
+
/**
|
|
102
|
+
* Gets multichain account for a given ID.
|
|
103
|
+
* The default group ID will default to the multichain account with index 0.
|
|
104
|
+
*
|
|
105
|
+
* @param id - Account group ID.
|
|
106
|
+
* @returns Account group.
|
|
107
|
+
*/
|
|
108
|
+
getAccountGroup(id) {
|
|
61
109
|
// We consider the "default case" to be mapped to index 0.
|
|
62
|
-
if (
|
|
63
|
-
return __classPrivateFieldGet(this,
|
|
110
|
+
if (id === (0, group_1.toDefaultAccountGroupId)(this.id)) {
|
|
111
|
+
return __classPrivateFieldGet(this, _MultichainAccountWallet_accounts, "f").get(0);
|
|
64
112
|
}
|
|
65
|
-
|
|
66
|
-
|
|
113
|
+
// If it is not a valid ID, we cannot extract the group index
|
|
114
|
+
// from it, so we fail fast.
|
|
115
|
+
if (!(0, account_1.isMultichainAccountId)(id)) {
|
|
67
116
|
return undefined;
|
|
68
117
|
}
|
|
69
|
-
|
|
118
|
+
const groupIndex = (0, account_1.getGroupIndexFromMultichainAccountId)(id);
|
|
119
|
+
return __classPrivateFieldGet(this, _MultichainAccountWallet_accounts, "f").get(groupIndex);
|
|
70
120
|
}
|
|
121
|
+
/**
|
|
122
|
+
* Gets all multichain accounts. Similar to {@link MultichainAccountWallet.getMultichainAccounts}.
|
|
123
|
+
*
|
|
124
|
+
* @returns The multichain accounts.
|
|
125
|
+
*/
|
|
71
126
|
getAccountGroups() {
|
|
72
127
|
return this.getMultichainAccounts();
|
|
73
128
|
}
|
|
129
|
+
/**
|
|
130
|
+
* Gets multichain account for a given index.
|
|
131
|
+
*
|
|
132
|
+
* @param groupIndex - Multichain account index.
|
|
133
|
+
* @returns The multichain account associated with the given index.
|
|
134
|
+
*/
|
|
74
135
|
getMultichainAccount(groupIndex) {
|
|
75
|
-
return __classPrivateFieldGet(this,
|
|
136
|
+
return __classPrivateFieldGet(this, _MultichainAccountWallet_accounts, "f").get(groupIndex);
|
|
76
137
|
}
|
|
138
|
+
/**
|
|
139
|
+
* Gets all multichain accounts.
|
|
140
|
+
*
|
|
141
|
+
* @returns The multichain accounts.
|
|
142
|
+
*/
|
|
77
143
|
getMultichainAccounts() {
|
|
78
|
-
return Array.from(__classPrivateFieldGet(this,
|
|
144
|
+
return Array.from(__classPrivateFieldGet(this, _MultichainAccountWallet_accounts, "f").values()); // TODO: Prevent copy here.
|
|
79
145
|
}
|
|
80
146
|
}
|
|
81
|
-
exports.
|
|
82
|
-
|
|
147
|
+
exports.MultichainAccountWallet = MultichainAccountWallet;
|
|
148
|
+
_MultichainAccountWallet_id = new WeakMap(), _MultichainAccountWallet_providers = new WeakMap(), _MultichainAccountWallet_entropySource = new WeakMap(), _MultichainAccountWallet_accounts = new WeakMap();
|
|
83
149
|
/**
|
|
84
150
|
* Gets the multichain account wallet ID from its entropy source.
|
|
85
151
|
*
|