-
-
Notifications
You must be signed in to change notification settings - Fork 13
Expand file tree
/
Copy pathv1.ts
More file actions
136 lines (128 loc) · 4.13 KB
/
Copy pathv1.ts
File metadata and controls
136 lines (128 loc) · 4.13 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
import {
BtcAccountType,
EthAccountType,
SolAccountType,
BtcScope,
EthScope,
SolScope,
TrxScope,
TrxAccountType,
} from '@metamask/keyring-api';
import type {
CaipChainId,
KeyringAccount,
KeyringAccountType,
} from '@metamask/keyring-api';
import { isBtcMainnetAddress } from '@metamask/keyring-utils';
import { is } from '@metamask/superstruct';
import {
assertKeyringAccount,
KeyringAccountV1Struct,
type KeyringAccountV1,
} from '../account';
/**
* Checks if an account is an `KeyringAccount` v1.
*
* @param account - A v1 account to check.
* @returns True if the account is v1, false otherwise.
*/
export function isAccountV1(
// eslint-disable-next-line @typescript-eslint/no-redundant-type-constituents
account: KeyringAccountV1 | KeyringAccount,
): boolean {
return is(account, KeyringAccountV1Struct);
}
/**
* Gets default scopes for a v1 account.
*
* @param accountV1 - A v1 account.
* @returns The list of scopes for that accounts.
*/
export function getScopesForAccountV1(
accountV1: KeyringAccountV1,
): CaipChainId[] {
switch (accountV1.type) {
case EthAccountType.Eoa: {
// EVM EOA account are compatible with any EVM networks, we use the
// 'eip155:0' scope as defined in the EVM CAIP-10 namespaces.
//
// See: https://namespaces.chainagnostic.org/eip155/caip10
return [EthScope.Eoa];
}
case EthAccountType.Erc4337: {
// EVM Erc4337 account
// NOTE: A Smart Contract account might not be compatible with every chain, in this case we just default
// to testnet since we cannot really "guess" it from here.
// Also, there's no official Snap as of today that uses this account type. So this case should never happen
// in production.
return [EthScope.Testnet];
}
case BtcAccountType.P2pkh:
case BtcAccountType.P2sh:
case BtcAccountType.P2wpkh:
case BtcAccountType.P2tr: {
// Bitcoin uses different accounts for testnet and mainnet
return [
isBtcMainnetAddress(accountV1.address)
? BtcScope.Mainnet
: BtcScope.Testnet,
];
}
case SolAccountType.DataAccount: {
// Solana account supports multiple chains.
return [SolScope.Mainnet, SolScope.Testnet, SolScope.Devnet];
}
case TrxAccountType.Eoa: {
// TRON account supports multiple chains.
return [TrxScope.Mainnet, TrxScope.Nile, TrxScope.Shasta];
}
default:
// We re-use EOA scopes if we don't know what to do for now.
return [EthScope.Eoa];
}
}
/**
* Transform an account v1. This account might have optional fields that are now required by
* the Keyring API. This function will automatically provides the missing fields with some
* default values.
*
* @param accountV1 - A v1 account to transform.
* @throws An error if the v1 account cannot be transformed.
* @returns A valid KeyringAccount.
*/
export function transformAccountV1(
accountV1: KeyringAccountV1,
): KeyringAccount {
const { type } = accountV1;
// EVM EOA account are compatible with any EVM networks, and we use CAIP-2
// namespaces when the scope relates to ALL chains (from that namespace).
// So we can automatically inject a valid `scopes` for this, but not for
// other kind of accounts.
if (type === EthAccountType.Eoa) {
return {
...accountV1,
scopes: getScopesForAccountV1(accountV1),
};
}
// For all other non-EVM and ERC4337 Snap accounts, the `scopes` is required, and
// each `*AccountStruct` should assert that automatically.
return assertKeyringAccount(accountV1 as { type: KeyringAccountType });
}
/**
* Migrate an account v1. This account might have optional fields that are now required by
* the Keyring API. This function will automatically provides the missing fields with some
* meaningful default values.
*
* @param accountV1 - The account to migrate.
* @returns A valid KeyringAccount.
*/
export function migrateAccountV1(accountV1: KeyringAccountV1): KeyringAccount {
if (!isAccountV1(accountV1)) {
// Nothing to do in this case.
return accountV1 as KeyringAccount;
}
return {
...accountV1,
scopes: getScopesForAccountV1(accountV1),
};
}