-
-
Notifications
You must be signed in to change notification settings - Fork 13
Expand file tree
/
Copy pathaccount.ts
More file actions
105 lines (99 loc) · 3.32 KB
/
Copy pathaccount.ts
File metadata and controls
105 lines (99 loc) · 3.32 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
import type { KeyringAccount, KeyringAccountType } from '@metamask/keyring-api';
import {
BtcAccountType,
BtcP2pkhAccountStruct,
BtcP2shAccountStruct,
BtcP2wpkhAccountStruct,
BtcP2trAccountStruct,
EthAccountType,
EthEoaAccountStruct,
EthErc4337AccountStruct,
AnyAccountType,
KeyringAccountStruct,
SolAccountType,
SolDataAccountStruct,
TrxAccountType,
TrxEoaAccountStruct,
} from '@metamask/keyring-api';
import { assert, omit, type Infer } from '@metamask/superstruct';
import { isAccountV1, transformAccountV1 } from './migrations';
/**
* A `KeyringAccount` with some optional fields which can be used to keep
* the retro-compatility with older version of keyring accounts/events.
*/
export const KeyringAccountV1Struct = omit(KeyringAccountStruct, ['scopes']);
export type KeyringAccountV1 = Infer<typeof KeyringAccountV1Struct>;
/**
* Assert that an account-like object matches its actual account type.
*
* @param account - The account-like object.
* @returns The account as normal `KeyringAccount`.
*/
export function assertKeyringAccount<
Account extends { type: KeyringAccountType },
>(account: Account): KeyringAccount {
// TODO: We should use a `selectiveUnion` for this and probably use it to define
// the `KeyringAccount`. This would also required to have a "generic `KeyringAccount`"
// definition.
switch (account.type) {
case BtcAccountType.P2pkh: {
assert(account, BtcP2pkhAccountStruct);
return account;
}
case BtcAccountType.P2sh: {
assert(account, BtcP2shAccountStruct);
return account;
}
case BtcAccountType.P2wpkh: {
assert(account, BtcP2wpkhAccountStruct);
return account;
}
case BtcAccountType.P2tr: {
assert(account, BtcP2trAccountStruct);
return account;
}
case SolAccountType.DataAccount: {
assert(account, SolDataAccountStruct);
return account;
}
case EthAccountType.Erc4337: {
assert(account, EthErc4337AccountStruct);
return account;
}
case EthAccountType.Eoa: {
assert(account, EthEoaAccountStruct);
return account;
}
case TrxAccountType.Eoa: {
assert(account, TrxEoaAccountStruct);
return account;
}
case AnyAccountType.Account: {
assert(account, KeyringAccountStruct);
return account;
}
default: {
// For now, we cannot much more than this (this should also, never happen)!
// NOTE: We could use a "generic `KeyringAccount` type" here though.
throw new Error(`Unknown account type: '${account.type}'`);
}
}
}
/**
* Transform any versionned account to a `KeyringAccount`.
*
* @param accountToTransform - The account to transform.
* @returns A valid transformed `KeyringAccount`.
*/
export function transformAccount(
// eslint-disable-next-line @typescript-eslint/no-redundant-type-constituents
accountToTransform: KeyringAccountV1 | KeyringAccount,
): KeyringAccount {
// To keep the retro-compatibility with older keyring-api versions, we identify the account's
// version and transform it to the latest `KeyringAccount` representation.
const account = isAccountV1(accountToTransform)
? transformAccountV1(accountToTransform)
: accountToTransform;
// We still assert that the converted account is valid according to their account's type.
return assertKeyringAccount(account);
}