@guveno/wallet-sdk 1.0.0

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.
Files changed (100) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +211 -0
  3. package/dist/api/client.d.ts +48 -0
  4. package/dist/api/client.d.ts.map +1 -0
  5. package/dist/api/client.js +563 -0
  6. package/dist/api/client.js.map +1 -0
  7. package/dist/api/types.d.ts +237 -0
  8. package/dist/api/types.d.ts.map +1 -0
  9. package/dist/api/types.js +9 -0
  10. package/dist/api/types.js.map +1 -0
  11. package/dist/chains.d.ts +25 -0
  12. package/dist/chains.d.ts.map +1 -0
  13. package/dist/chains.js +67 -0
  14. package/dist/chains.js.map +1 -0
  15. package/dist/constants.d.ts +17 -0
  16. package/dist/constants.d.ts.map +1 -0
  17. package/dist/constants.js +19 -0
  18. package/dist/constants.js.map +1 -0
  19. package/dist/crypto/sealed-box.d.ts +8 -0
  20. package/dist/crypto/sealed-box.d.ts.map +1 -0
  21. package/dist/crypto/sealed-box.js +66 -0
  22. package/dist/crypto/sealed-box.js.map +1 -0
  23. package/dist/derivation.d.ts +26 -0
  24. package/dist/derivation.d.ts.map +1 -0
  25. package/dist/derivation.js +121 -0
  26. package/dist/derivation.js.map +1 -0
  27. package/dist/errors.d.ts +81 -0
  28. package/dist/errors.d.ts.map +1 -0
  29. package/dist/errors.js +95 -0
  30. package/dist/errors.js.map +1 -0
  31. package/dist/hot-wallet.d.ts +57 -0
  32. package/dist/hot-wallet.d.ts.map +1 -0
  33. package/dist/hot-wallet.js +139 -0
  34. package/dist/hot-wallet.js.map +1 -0
  35. package/dist/index.d.ts +29 -0
  36. package/dist/index.d.ts.map +1 -0
  37. package/dist/index.js +21 -0
  38. package/dist/index.js.map +1 -0
  39. package/dist/keyprovider/file-provider.d.ts +19 -0
  40. package/dist/keyprovider/file-provider.d.ts.map +1 -0
  41. package/dist/keyprovider/file-provider.js +48 -0
  42. package/dist/keyprovider/file-provider.js.map +1 -0
  43. package/dist/keyprovider/index.d.ts +13 -0
  44. package/dist/keyprovider/index.d.ts.map +1 -0
  45. package/dist/keyprovider/index.js +3 -0
  46. package/dist/keyprovider/index.js.map +1 -0
  47. package/dist/keyprovider/kms-provider.d.ts +26 -0
  48. package/dist/keyprovider/kms-provider.d.ts.map +1 -0
  49. package/dist/keyprovider/kms-provider.js +32 -0
  50. package/dist/keyprovider/kms-provider.js.map +1 -0
  51. package/dist/manager.d.ts +28 -0
  52. package/dist/manager.d.ts.map +1 -0
  53. package/dist/manager.js +499 -0
  54. package/dist/manager.js.map +1 -0
  55. package/dist/mnemonic.d.ts +13 -0
  56. package/dist/mnemonic.d.ts.map +1 -0
  57. package/dist/mnemonic.js +44 -0
  58. package/dist/mnemonic.js.map +1 -0
  59. package/dist/session/file-store.d.ts +10 -0
  60. package/dist/session/file-store.d.ts.map +1 -0
  61. package/dist/session/file-store.js +88 -0
  62. package/dist/session/file-store.js.map +1 -0
  63. package/dist/signing/sign-bitcoin.d.ts +14 -0
  64. package/dist/signing/sign-bitcoin.d.ts.map +1 -0
  65. package/dist/signing/sign-bitcoin.js +133 -0
  66. package/dist/signing/sign-bitcoin.js.map +1 -0
  67. package/dist/signing/sign-ethereum.d.ts +13 -0
  68. package/dist/signing/sign-ethereum.d.ts.map +1 -0
  69. package/dist/signing/sign-ethereum.js +49 -0
  70. package/dist/signing/sign-ethereum.js.map +1 -0
  71. package/dist/signing/sign-polkadot.d.ts +9 -0
  72. package/dist/signing/sign-polkadot.d.ts.map +1 -0
  73. package/dist/signing/sign-polkadot.js +79 -0
  74. package/dist/signing/sign-polkadot.js.map +1 -0
  75. package/dist/signing/sign-withdrawal.d.ts +21 -0
  76. package/dist/signing/sign-withdrawal.d.ts.map +1 -0
  77. package/dist/signing/sign-withdrawal.js +35 -0
  78. package/dist/signing/sign-withdrawal.js.map +1 -0
  79. package/dist/signing/sign-xrp.d.ts +7 -0
  80. package/dist/signing/sign-xrp.d.ts.map +1 -0
  81. package/dist/signing/sign-xrp.js +27 -0
  82. package/dist/signing/sign-xrp.js.map +1 -0
  83. package/dist/signing/types.d.ts +84 -0
  84. package/dist/signing/types.d.ts.map +1 -0
  85. package/dist/signing/types.js +15 -0
  86. package/dist/signing/types.js.map +1 -0
  87. package/dist/storage/crypto.d.ts +7 -0
  88. package/dist/storage/crypto.d.ts.map +1 -0
  89. package/dist/storage/crypto.js +80 -0
  90. package/dist/storage/crypto.js.map +1 -0
  91. package/dist/storage/file-store.d.ts +21 -0
  92. package/dist/storage/file-store.d.ts.map +1 -0
  93. package/dist/storage/file-store.js +219 -0
  94. package/dist/storage/file-store.js.map +1 -0
  95. package/dist/types.d.ts +187 -0
  96. package/dist/types.d.ts.map +1 -0
  97. package/dist/types.js +2 -0
  98. package/dist/types.js.map +1 -0
  99. package/docs/security.md +119 -0
  100. package/package.json +76 -0
@@ -0,0 +1,237 @@
1
+ import type { SupportedChain, SupportedNetwork, WalletRecordAddressExport } from '../types.js';
2
+ import type { BitcoinOutput, SigningPayload } from '../signing/types.js';
3
+ export type ApiCompanyRole = 'owner' | 'admin' | 'tech' | 'manager' | 'signer' | 'viewer';
4
+ export type ApiWalletType = 'single_key' | 'mpc_threshold';
5
+ export type ApiRecordStatus = 'active' | 'archived';
6
+ /**
7
+ * Chains the Guveno product API can custody and return. Equivalent to
8
+ * {@link SupportedChain} — every chain the API custodies (Ethereum, Bitcoin, XRP,
9
+ * Polkadot) the SDK can also derive addresses and sign transactions for locally.
10
+ */
11
+ export type ApiChain = SupportedChain;
12
+ /** Networks the product API can return. Equivalent to {@link SupportedNetwork} (includes Polkadot's Paseo testnet). */
13
+ export type ApiNetwork = SupportedNetwork;
14
+ export interface ApiCompanyMembership {
15
+ id: number;
16
+ name: string;
17
+ role: ApiCompanyRole;
18
+ }
19
+ export interface ApiUserEncryptionKey {
20
+ id: string;
21
+ publicKey: string;
22
+ encryptedPrivateKeyJson: Record<string, unknown>;
23
+ createdAt: string;
24
+ updatedAt: string;
25
+ }
26
+ export interface ApiUser {
27
+ id: number;
28
+ email: string;
29
+ company: ApiCompanyMembership | null;
30
+ encryptionKey: ApiUserEncryptionKey | null;
31
+ createdAt: string;
32
+ updatedAt: string;
33
+ }
34
+ export interface ApiAuthResponse {
35
+ accessToken: string;
36
+ tokenType: 'Bearer';
37
+ expiresIn: string;
38
+ user: ApiUser;
39
+ }
40
+ export interface ApiSession extends ApiAuthResponse {
41
+ baseUrl: string;
42
+ authenticatedAt: string;
43
+ }
44
+ export interface ApiSignupResponse {
45
+ email: string;
46
+ verificationRequired: true;
47
+ }
48
+ export interface ApiVerifyEmailInput {
49
+ email: string;
50
+ code: string;
51
+ }
52
+ export interface ApiKeySummary {
53
+ id: string;
54
+ fingerprint: string;
55
+ createdAt: string;
56
+ updatedAt: string;
57
+ }
58
+ export interface ApiKeyAccess {
59
+ id: string;
60
+ keyId: string;
61
+ userId: number;
62
+ createdAt: string;
63
+ updatedAt: string;
64
+ }
65
+ /**
66
+ * A key grant including the encrypted custody secret. Returned only by
67
+ * {@link GuvenoApiClient.getWalletKeySecret} (`GET /wallets/:id/secret`), which
68
+ * requires an interactive user session and audits each access.
69
+ */
70
+ export interface ApiWalletKeySecret extends ApiKeyAccess {
71
+ encryptedSecretJson: Record<string, unknown>;
72
+ }
73
+ export interface ApiWalletSummary {
74
+ id: number;
75
+ keyId: string | null;
76
+ name: string;
77
+ chain: ApiChain;
78
+ network: ApiNetwork;
79
+ type: ApiWalletType;
80
+ threshold: number | null;
81
+ status: ApiRecordStatus;
82
+ archivedAt: string | null;
83
+ addressCount: number;
84
+ createdAt: string;
85
+ updatedAt: string;
86
+ }
87
+ export interface ApiWalletDetail extends ApiWalletSummary {
88
+ key: ApiKeySummary | null;
89
+ keyAccess: ApiKeyAccess | null;
90
+ }
91
+ export interface ApiWalletAddress {
92
+ id: number;
93
+ walletId: number;
94
+ chain: ApiChain;
95
+ network: ApiNetwork;
96
+ address: string;
97
+ derivationPath: string;
98
+ accountIndex: number;
99
+ label: string | null;
100
+ status: ApiRecordStatus;
101
+ archivedAt: string | null;
102
+ createdAt: string;
103
+ updatedAt: string;
104
+ }
105
+ export interface ApiPageInfo {
106
+ nextCursor: string | null;
107
+ hasNextPage: boolean;
108
+ }
109
+ export interface ApiClientOptions {
110
+ baseUrl?: string;
111
+ accessToken?: string;
112
+ /**
113
+ * A `gv_live_...` API key, used as the bearer token for headless/automated
114
+ * callers (e.g. an exchange hot wallet). Equivalent to passing it as
115
+ * `accessToken`; `accessToken` wins if both are set.
116
+ */
117
+ apiKey?: string;
118
+ fetchImpl?: typeof fetch;
119
+ }
120
+ export interface ApiEmailPasswordInput {
121
+ email: string;
122
+ password: string;
123
+ }
124
+ export interface CreateApiWalletInput {
125
+ name: string;
126
+ chain: SupportedChain;
127
+ network: SupportedNetwork;
128
+ type?: ApiWalletType;
129
+ threshold?: number | null;
130
+ keyFingerprint: string;
131
+ encryptedSecretJson: Record<string, unknown>;
132
+ addresses: WalletRecordAddressExport[];
133
+ }
134
+ export interface UpdateApiWalletInput {
135
+ name?: string;
136
+ addresses?: WalletRecordAddressExport[];
137
+ }
138
+ export interface ListApiWalletOptions {
139
+ limit?: number;
140
+ cursor?: string;
141
+ chain?: ApiChain;
142
+ network?: ApiNetwork;
143
+ }
144
+ export interface ListApiAddressOptions {
145
+ limit?: number;
146
+ cursor?: string;
147
+ }
148
+ export interface ApiSessionStore {
149
+ read(): Promise<ApiSession | null>;
150
+ write(session: ApiSession): Promise<void>;
151
+ clear(): Promise<void>;
152
+ }
153
+ export type ApiWebhookType = 'slack' | 'telegram' | 'api';
154
+ export type ApiWebhookEventType = 'deposit.detected' | 'deposit.confirmed' | 'deposit.rejected' | 'withdrawal.broadcast' | 'withdrawal.confirmed' | 'withdrawal.rejected';
155
+ export declare const WEBHOOK_EVENT_TYPES: ApiWebhookEventType[];
156
+ export interface ApiWebhook {
157
+ id: number;
158
+ type: ApiWebhookType;
159
+ events: string[];
160
+ enabled: boolean;
161
+ config: Record<string, unknown>;
162
+ createdAt: string;
163
+ updatedAt: string;
164
+ }
165
+ /** Returned only once, at creation time. `signingSecret` is never exposed again. */
166
+ export interface ApiWebhookWithSecret extends ApiWebhook {
167
+ signingSecret: string;
168
+ }
169
+ export interface CreateApiWebhookInput {
170
+ type: ApiWebhookType;
171
+ config: Record<string, unknown>;
172
+ events: string[];
173
+ enabled?: boolean;
174
+ }
175
+ export type ApiWebhookDeliveryStatus = 'pending' | 'delivered' | 'failed';
176
+ export interface ApiWebhookDelivery {
177
+ id: number;
178
+ webhookId: number;
179
+ eventId: string;
180
+ eventType: string | null;
181
+ status: ApiWebhookDeliveryStatus;
182
+ attempts: number;
183
+ responseCode: number | null;
184
+ lastError: string | null;
185
+ nextAttemptAt: string;
186
+ createdAt: string;
187
+ updatedAt: string;
188
+ }
189
+ export interface ListApiWebhookDeliveryOptions {
190
+ limit?: number;
191
+ }
192
+ export type ApiWithdrawalStatus = 'prepared' | 'broadcast' | 'confirmed' | 'rejected';
193
+ export interface ApiWithdrawal {
194
+ id: number;
195
+ addressId: number;
196
+ assetId: number;
197
+ network: string;
198
+ toAddress: string | null;
199
+ outputs: BitcoinOutput[] | null;
200
+ destinationTag: number | null;
201
+ amount: string;
202
+ status: ApiWithdrawalStatus;
203
+ rejectionReason: string | null;
204
+ txHash: string | null;
205
+ expiresAt: string;
206
+ createdAt: string;
207
+ updatedAt: string;
208
+ }
209
+ export interface PrepareWithdrawalInput {
210
+ addressId: number;
211
+ assetId: number;
212
+ toAddress?: string;
213
+ amount?: string;
214
+ outputs?: BitcoinOutput[];
215
+ destinationTag?: number;
216
+ /** Replay-safe key; sent in the body. Falls back to a generated UUID in the hot wallet. */
217
+ idempotencyKey?: string;
218
+ }
219
+ export interface PrepareWithdrawalResult {
220
+ withdrawal: ApiWithdrawal;
221
+ signingPayload: SigningPayload;
222
+ }
223
+ export interface BroadcastWithdrawalInput {
224
+ withdrawalId: number;
225
+ signedRawTx: string;
226
+ idempotencyKey?: string;
227
+ }
228
+ export interface ListApiWithdrawalOptions {
229
+ walletId?: number;
230
+ addressId?: number;
231
+ chain?: ApiChain;
232
+ network?: ApiNetwork;
233
+ status?: ApiWithdrawalStatus;
234
+ limit?: number;
235
+ cursor?: string;
236
+ }
237
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/api/types.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ export const WEBHOOK_EVENT_TYPES = [
2
+ 'deposit.detected',
3
+ 'deposit.confirmed',
4
+ 'deposit.rejected',
5
+ 'withdrawal.broadcast',
6
+ 'withdrawal.confirmed',
7
+ 'withdrawal.rejected'
8
+ ];
9
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/api/types.ts"],"names":[],"mappings":"AA6LA,MAAM,CAAC,MAAM,mBAAmB,GAA0B;IACxD,kBAAkB;IAClB,mBAAmB;IACnB,kBAAkB;IAClB,sBAAsB;IACtB,sBAAsB;IACtB,qBAAqB;CACtB,CAAC"}
@@ -0,0 +1,25 @@
1
+ import type { SupportedChain, SupportedNetwork } from './types.js';
2
+ export declare const SUPPORTED_CHAINS: readonly ["ethereum", "bitcoin", "xrp", "polkadot"];
3
+ export declare const SUPPORTED_NETWORKS: readonly ["mainnet", "sepolia", "testnet", "paseo"];
4
+ export declare const DEFAULT_CHAIN: SupportedChain;
5
+ export declare const DEFAULT_NETWORK: SupportedNetwork;
6
+ export interface ChainDefinition {
7
+ id: SupportedChain;
8
+ displayName: string;
9
+ derivationPathPrefix: string;
10
+ testnetDerivationPathPrefix?: string;
11
+ addressStyle: string;
12
+ }
13
+ export declare const CHAIN_DEFINITIONS: Record<SupportedChain, ChainDefinition>;
14
+ /**
15
+ * SS58 address prefix per network. The 32-byte public key is the real account
16
+ * identity (the server matches on it), so the prefix only changes the rendered
17
+ * string: 0 for Polkadot mainnet, 42 for the Paseo testnet (generic Substrate).
18
+ */
19
+ export declare const POLKADOT_SS58_FORMAT: Partial<Record<SupportedNetwork, number>>;
20
+ export declare function isSupportedChain(value: string): value is SupportedChain;
21
+ export declare function assertSupportedChain(value: string | undefined): SupportedChain;
22
+ export declare function getChainDefinition(chain: SupportedChain): ChainDefinition;
23
+ export declare function isSupportedNetwork(value: string): value is SupportedNetwork;
24
+ export declare function assertSupportedNetwork(value: string | undefined): SupportedNetwork;
25
+ //# sourceMappingURL=chains.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chains.d.ts","sourceRoot":"","sources":["../src/chains.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAEnE,eAAO,MAAM,gBAAgB,qDAAsD,CAAC;AACpF,eAAO,MAAM,kBAAkB,qDAAsD,CAAC;AACtF,eAAO,MAAM,aAAa,EAAE,cAA2B,CAAC;AACxD,eAAO,MAAM,eAAe,EAAE,gBAA4B,CAAC;AAE3D,MAAM,WAAW,eAAe;IAC9B,EAAE,EAAE,cAAc,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,oBAAoB,EAAE,MAAM,CAAC;IAC7B,2BAA2B,CAAC,EAAE,MAAM,CAAC;IACrC,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,eAAO,MAAM,iBAAiB,EAAE,MAAM,CAAC,cAAc,EAAE,eAAe,CA4BrE,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,oBAAoB,EAAE,OAAO,CAAC,MAAM,CAAC,gBAAgB,EAAE,MAAM,CAAC,CAG1E,CAAC;AAEF,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG,KAAK,IAAI,cAAc,CAEvE;AAED,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,cAAc,CAU9E;AAED,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,cAAc,GAAG,eAAe,CAEzE;AAED,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,MAAM,GAAG,KAAK,IAAI,gBAAgB,CAE3E;AAED,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,gBAAgB,CAQlF"}
package/dist/chains.js ADDED
@@ -0,0 +1,67 @@
1
+ import { ValidationError } from './errors.js';
2
+ export const SUPPORTED_CHAINS = ['ethereum', 'bitcoin', 'xrp', 'polkadot'];
3
+ export const SUPPORTED_NETWORKS = ['mainnet', 'sepolia', 'testnet', 'paseo'];
4
+ export const DEFAULT_CHAIN = 'ethereum';
5
+ export const DEFAULT_NETWORK = 'mainnet';
6
+ export const CHAIN_DEFINITIONS = {
7
+ ethereum: {
8
+ id: 'ethereum',
9
+ displayName: 'Ethereum',
10
+ derivationPathPrefix: "m/44'/60'/0'/0",
11
+ addressStyle: 'hex'
12
+ },
13
+ bitcoin: {
14
+ id: 'bitcoin',
15
+ displayName: 'Bitcoin',
16
+ derivationPathPrefix: "m/84'/0'/0'/0",
17
+ testnetDerivationPathPrefix: "m/84'/1'/0'/0",
18
+ addressStyle: 'bech32'
19
+ },
20
+ xrp: {
21
+ id: 'xrp',
22
+ displayName: 'XRP',
23
+ derivationPathPrefix: "m/44'/144'/0'/0",
24
+ addressStyle: 'classic'
25
+ },
26
+ polkadot: {
27
+ id: 'polkadot',
28
+ displayName: 'Polkadot',
29
+ // Substrate sr25519 accounts use junction-style soft/hard derivation rather
30
+ // than a BIP44 path; buildDerivationPath emits `//<index>` (a hard junction).
31
+ derivationPathPrefix: '//',
32
+ addressStyle: 'ss58'
33
+ }
34
+ };
35
+ /**
36
+ * SS58 address prefix per network. The 32-byte public key is the real account
37
+ * identity (the server matches on it), so the prefix only changes the rendered
38
+ * string: 0 for Polkadot mainnet, 42 for the Paseo testnet (generic Substrate).
39
+ */
40
+ export const POLKADOT_SS58_FORMAT = {
41
+ mainnet: 0,
42
+ paseo: 42
43
+ };
44
+ export function isSupportedChain(value) {
45
+ return SUPPORTED_CHAINS.includes(value);
46
+ }
47
+ export function assertSupportedChain(value) {
48
+ const normalized = value?.trim().toLowerCase() ?? DEFAULT_CHAIN;
49
+ if (!isSupportedChain(normalized)) {
50
+ throw new ValidationError(`Unsupported chain "${value}". Supported chains are: ${SUPPORTED_CHAINS.join(', ')}.`);
51
+ }
52
+ return normalized;
53
+ }
54
+ export function getChainDefinition(chain) {
55
+ return CHAIN_DEFINITIONS[chain];
56
+ }
57
+ export function isSupportedNetwork(value) {
58
+ return SUPPORTED_NETWORKS.includes(value);
59
+ }
60
+ export function assertSupportedNetwork(value) {
61
+ const normalized = value?.trim().toLowerCase() ?? DEFAULT_NETWORK;
62
+ if (!isSupportedNetwork(normalized)) {
63
+ throw new ValidationError(`Unsupported network "${value}". Supported networks are: ${SUPPORTED_NETWORKS.join(', ')}.`);
64
+ }
65
+ return normalized;
66
+ }
67
+ //# sourceMappingURL=chains.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chains.js","sourceRoot":"","sources":["../src/chains.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAG9C,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,UAAU,EAAE,SAAS,EAAE,KAAK,EAAE,UAAU,CAAU,CAAC;AACpF,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,SAAS,EAAE,SAAS,EAAE,SAAS,EAAE,OAAO,CAAU,CAAC;AACtF,MAAM,CAAC,MAAM,aAAa,GAAmB,UAAU,CAAC;AACxD,MAAM,CAAC,MAAM,eAAe,GAAqB,SAAS,CAAC;AAU3D,MAAM,CAAC,MAAM,iBAAiB,GAA4C;IACxE,QAAQ,EAAE;QACR,EAAE,EAAE,UAAU;QACd,WAAW,EAAE,UAAU;QACvB,oBAAoB,EAAE,gBAAgB;QACtC,YAAY,EAAE,KAAK;KACpB;IACD,OAAO,EAAE;QACP,EAAE,EAAE,SAAS;QACb,WAAW,EAAE,SAAS;QACtB,oBAAoB,EAAE,eAAe;QACrC,2BAA2B,EAAE,eAAe;QAC5C,YAAY,EAAE,QAAQ;KACvB;IACD,GAAG,EAAE;QACH,EAAE,EAAE,KAAK;QACT,WAAW,EAAE,KAAK;QAClB,oBAAoB,EAAE,iBAAiB;QACvC,YAAY,EAAE,SAAS;KACxB;IACD,QAAQ,EAAE;QACR,EAAE,EAAE,UAAU;QACd,WAAW,EAAE,UAAU;QACvB,4EAA4E;QAC5E,8EAA8E;QAC9E,oBAAoB,EAAE,IAAI;QAC1B,YAAY,EAAE,MAAM;KACrB;CACF,CAAC;AAEF;;;;GAIG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAA8C;IAC7E,OAAO,EAAE,CAAC;IACV,KAAK,EAAE,EAAE;CACV,CAAC;AAEF,MAAM,UAAU,gBAAgB,CAAC,KAAa;IAC5C,OAAO,gBAAgB,CAAC,QAAQ,CAAC,KAAuB,CAAC,CAAC;AAC5D,CAAC;AAED,MAAM,UAAU,oBAAoB,CAAC,KAAyB;IAC5D,MAAM,UAAU,GAAG,KAAK,EAAE,IAAI,EAAE,CAAC,WAAW,EAAE,IAAI,aAAa,CAAC;IAEhE,IAAI,CAAC,gBAAgB,CAAC,UAAU,CAAC,EAAE,CAAC;QAClC,MAAM,IAAI,eAAe,CACvB,sBAAsB,KAAK,4BAA4B,gBAAgB,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CACtF,CAAC;IACJ,CAAC;IAED,OAAO,UAAU,CAAC;AACpB,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,KAAqB;IACtD,OAAO,iBAAiB,CAAC,KAAK,CAAC,CAAC;AAClC,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,KAAa;IAC9C,OAAO,kBAAkB,CAAC,QAAQ,CAAC,KAAyB,CAAC,CAAC;AAChE,CAAC;AAED,MAAM,UAAU,sBAAsB,CAAC,KAAyB;IAC9D,MAAM,UAAU,GAAG,KAAK,EAAE,IAAI,EAAE,CAAC,WAAW,EAAE,IAAI,eAAe,CAAC;IAClE,IAAI,CAAC,kBAAkB,CAAC,UAAU,CAAC,EAAE,CAAC;QACpC,MAAM,IAAI,eAAe,CACvB,wBAAwB,KAAK,8BAA8B,kBAAkB,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAC5F,CAAC;IACJ,CAAC;IACD,OAAO,UAAU,CAAC;AACpB,CAAC"}
@@ -0,0 +1,17 @@
1
+ export declare const STORAGE_SCHEMA_VERSION = 3;
2
+ export declare const DEFAULT_STORAGE_ENV_VAR = "GUVENO_WALLET_HOME";
3
+ export declare const DEFAULT_STORAGE_DIR: string;
4
+ export declare const DEFAULT_API_BASE_URL_ENV_VAR = "GUVENO_API_BASE_URL";
5
+ export declare const DEFAULT_API_BASE_URL = "http://localhost:3000/api/v1";
6
+ export declare const STORAGE_LOCK_TIMEOUT_MS = 5000;
7
+ export declare const STORAGE_LOCK_RETRY_MS = 50;
8
+ export declare const ENCRYPTION_ALGORITHM = "aes-256-gcm";
9
+ export declare const ENCRYPTION_KDF = "scrypt";
10
+ export declare const SCRYPT_PARAMS: {
11
+ readonly cost: 16384;
12
+ readonly blockSize: 8;
13
+ readonly parallelization: 1;
14
+ readonly keyLength: 32;
15
+ };
16
+ export declare const SUPPORTED_MNEMONIC_WORD_COUNTS: readonly [12, 24];
17
+ //# sourceMappingURL=constants.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,sBAAsB,IAAI,CAAC;AACxC,eAAO,MAAM,uBAAuB,uBAAuB,CAAC;AAC5D,eAAO,MAAM,mBAAmB,QAAkC,CAAC;AACnE,eAAO,MAAM,4BAA4B,wBAAwB,CAAC;AAClE,eAAO,MAAM,oBAAoB,iCAAiC,CAAC;AACnE,eAAO,MAAM,uBAAuB,OAAQ,CAAC;AAC7C,eAAO,MAAM,qBAAqB,KAAK,CAAC;AACxC,eAAO,MAAM,oBAAoB,gBAAgB,CAAC;AAClD,eAAO,MAAM,cAAc,WAAW,CAAC;AACvC,eAAO,MAAM,aAAa;;;;;CAKhB,CAAC;AACX,eAAO,MAAM,8BAA8B,mBAAoB,CAAC"}
@@ -0,0 +1,19 @@
1
+ import { homedir } from 'node:os';
2
+ import path from 'node:path';
3
+ export const STORAGE_SCHEMA_VERSION = 3;
4
+ export const DEFAULT_STORAGE_ENV_VAR = 'GUVENO_WALLET_HOME';
5
+ export const DEFAULT_STORAGE_DIR = path.join(homedir(), '.guveno');
6
+ export const DEFAULT_API_BASE_URL_ENV_VAR = 'GUVENO_API_BASE_URL';
7
+ export const DEFAULT_API_BASE_URL = 'http://localhost:3000/api/v1';
8
+ export const STORAGE_LOCK_TIMEOUT_MS = 5_000;
9
+ export const STORAGE_LOCK_RETRY_MS = 50;
10
+ export const ENCRYPTION_ALGORITHM = 'aes-256-gcm';
11
+ export const ENCRYPTION_KDF = 'scrypt';
12
+ export const SCRYPT_PARAMS = {
13
+ cost: 16_384,
14
+ blockSize: 8,
15
+ parallelization: 1,
16
+ keyLength: 32
17
+ };
18
+ export const SUPPORTED_MNEMONIC_WORD_COUNTS = [12, 24];
19
+ //# sourceMappingURL=constants.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"constants.js","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B,MAAM,CAAC,MAAM,sBAAsB,GAAG,CAAC,CAAC;AACxC,MAAM,CAAC,MAAM,uBAAuB,GAAG,oBAAoB,CAAC;AAC5D,MAAM,CAAC,MAAM,mBAAmB,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,EAAE,SAAS,CAAC,CAAC;AACnE,MAAM,CAAC,MAAM,4BAA4B,GAAG,qBAAqB,CAAC;AAClE,MAAM,CAAC,MAAM,oBAAoB,GAAG,8BAA8B,CAAC;AACnE,MAAM,CAAC,MAAM,uBAAuB,GAAG,KAAK,CAAC;AAC7C,MAAM,CAAC,MAAM,qBAAqB,GAAG,EAAE,CAAC;AACxC,MAAM,CAAC,MAAM,oBAAoB,GAAG,aAAa,CAAC;AAClD,MAAM,CAAC,MAAM,cAAc,GAAG,QAAQ,CAAC;AACvC,MAAM,CAAC,MAAM,aAAa,GAAG;IAC3B,IAAI,EAAE,MAAM;IACZ,SAAS,EAAE,CAAC;IACZ,eAAe,EAAE,CAAC;IAClB,SAAS,EAAE,EAAE;CACL,CAAC;AACX,MAAM,CAAC,MAAM,8BAA8B,GAAG,CAAC,EAAE,EAAE,EAAE,CAAU,CAAC"}
@@ -0,0 +1,8 @@
1
+ export interface SealedSecretJson {
2
+ version: number;
3
+ type: 'x25519-sealed-box';
4
+ recipientPublicKey: string;
5
+ ciphertext: string;
6
+ }
7
+ export declare function sealSecret(mnemonic: string, recipientPublicKeyBase64: string): SealedSecretJson;
8
+ //# sourceMappingURL=sealed-box.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sealed-box.d.ts","sourceRoot":"","sources":["../../src/crypto/sealed-box.ts"],"names":[],"mappings":"AAUA,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,mBAAmB,CAAC;IAC1B,kBAAkB,EAAE,MAAM,CAAC;IAC3B,UAAU,EAAE,MAAM,CAAC;CACpB;AAiED,wBAAgB,UAAU,CAAC,QAAQ,EAAE,MAAM,EAAE,wBAAwB,EAAE,MAAM,GAAG,gBAAgB,CAmB/F"}
@@ -0,0 +1,66 @@
1
+ import { createCipheriv, createPublicKey, diffieHellman, generateKeyPairSync, hkdfSync, randomBytes } from 'node:crypto';
2
+ function toBase64Url(raw) {
3
+ return raw.toString('base64url');
4
+ }
5
+ function fromBase64Url(value) {
6
+ return Buffer.from(value, 'base64url');
7
+ }
8
+ function toBase64(raw) {
9
+ return Buffer.from(raw).toString('base64');
10
+ }
11
+ function fromBase64(value) {
12
+ return Buffer.from(value, 'base64');
13
+ }
14
+ function createRawPublicKey(rawPublicKey) {
15
+ return createPublicKey({
16
+ format: 'jwk',
17
+ key: {
18
+ kty: 'OKP',
19
+ crv: 'X25519',
20
+ x: toBase64Url(rawPublicKey)
21
+ }
22
+ });
23
+ }
24
+ function exportRawPublicKey(publicKey) {
25
+ const jwk = publicKey.export({ format: 'jwk' });
26
+ if (typeof jwk.x !== 'string') {
27
+ throw new Error('Unable to export generated X25519 public key.');
28
+ }
29
+ return fromBase64Url(jwk.x);
30
+ }
31
+ function deriveSharedAesKey(privateKey, publicKey) {
32
+ const shared = diffieHellman({ privateKey, publicKey });
33
+ return Buffer.from(hkdfSync('sha256', shared, Buffer.alloc(0), Buffer.from('guveno-sealed-box'), 32));
34
+ }
35
+ function encryptPayload(aesKey, payload) {
36
+ const iv = randomBytes(12);
37
+ const cipher = createCipheriv('aes-256-gcm', aesKey, iv);
38
+ const ciphertext = Buffer.concat([cipher.update(payload), cipher.final()]);
39
+ const tag = cipher.getAuthTag();
40
+ return {
41
+ ephemeralPublicKey: '',
42
+ iv: toBase64(iv),
43
+ tag: toBase64(tag),
44
+ ciphertext: toBase64(ciphertext)
45
+ };
46
+ }
47
+ export function sealSecret(mnemonic, recipientPublicKeyBase64) {
48
+ const recipientPublicKey = createRawPublicKey(fromBase64(recipientPublicKeyBase64));
49
+ const { privateKey: ephemeralPrivateKey, publicKey: ephemeralPublicKey } = generateKeyPairSync('x25519');
50
+ const aesKey = deriveSharedAesKey(ephemeralPrivateKey, recipientPublicKey);
51
+ try {
52
+ const payload = Buffer.from(JSON.stringify({ mnemonic }), 'utf8');
53
+ const sealedPayload = encryptPayload(aesKey, payload);
54
+ sealedPayload.ephemeralPublicKey = toBase64(exportRawPublicKey(ephemeralPublicKey));
55
+ return {
56
+ version: 1,
57
+ type: 'x25519-sealed-box',
58
+ recipientPublicKey: recipientPublicKeyBase64,
59
+ ciphertext: toBase64(Buffer.from(JSON.stringify(sealedPayload), 'utf8'))
60
+ };
61
+ }
62
+ finally {
63
+ aesKey.fill(0);
64
+ }
65
+ }
66
+ //# sourceMappingURL=sealed-box.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sealed-box.js","sourceRoot":"","sources":["../../src/crypto/sealed-box.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,cAAc,EACd,eAAe,EACf,aAAa,EACb,mBAAmB,EACnB,QAAQ,EACR,WAAW,EAEZ,MAAM,aAAa,CAAC;AAgBrB,SAAS,WAAW,CAAC,GAAW;IAC9B,OAAO,GAAG,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC;AACnC,CAAC;AAED,SAAS,aAAa,CAAC,KAAa;IAClC,OAAO,MAAM,CAAC,IAAI,CAAC,KAAK,EAAE,WAAW,CAAC,CAAC;AACzC,CAAC;AAED,SAAS,QAAQ,CAAC,GAAwB;IACxC,OAAO,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;AAC7C,CAAC;AAED,SAAS,UAAU,CAAC,KAAa;IAC/B,OAAO,MAAM,CAAC,IAAI,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;AACtC,CAAC;AAED,SAAS,kBAAkB,CAAC,YAAoB;IAC9C,OAAO,eAAe,CAAC;QACrB,MAAM,EAAE,KAAK;QACb,GAAG,EAAE;YACH,GAAG,EAAE,KAAK;YACV,GAAG,EAAE,QAAQ;YACb,CAAC,EAAE,WAAW,CAAC,YAAY,CAAC;SAC7B;KACF,CAAC,CAAC;AACL,CAAC;AAED,SAAS,kBAAkB,CAAC,SAAoB;IAC9C,MAAM,GAAG,GAAG,SAAS,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,CAAmB,CAAC;IAElE,IAAI,OAAO,GAAG,CAAC,CAAC,KAAK,QAAQ,EAAE,CAAC;QAC9B,MAAM,IAAI,KAAK,CAAC,+CAA+C,CAAC,CAAC;IACnE,CAAC;IAED,OAAO,aAAa,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;AAC9B,CAAC;AAED,SAAS,kBAAkB,CAAC,UAAqB,EAAE,SAAoB;IACrE,MAAM,MAAM,GAAG,aAAa,CAAC,EAAE,UAAU,EAAE,SAAS,EAAE,CAAC,CAAC;IACxD,OAAO,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,IAAI,CAAC,mBAAmB,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;AACxG,CAAC;AAED,SAAS,cAAc,CAAC,MAAc,EAAE,OAAe;IACrD,MAAM,EAAE,GAAG,WAAW,CAAC,EAAE,CAAC,CAAC;IAC3B,MAAM,MAAM,GAAG,cAAc,CAAC,aAAa,EAAE,MAAM,EAAE,EAAE,CAAC,CAAC;IACzD,MAAM,UAAU,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;IAC3E,MAAM,GAAG,GAAG,MAAM,CAAC,UAAU,EAAE,CAAC;IAEhC,OAAO;QACL,kBAAkB,EAAE,EAAE;QACtB,EAAE,EAAE,QAAQ,CAAC,EAAE,CAAC;QAChB,GAAG,EAAE,QAAQ,CAAC,GAAG,CAAC;QAClB,UAAU,EAAE,QAAQ,CAAC,UAAU,CAAC;KACjC,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,QAAgB,EAAE,wBAAgC;IAC3E,MAAM,kBAAkB,GAAG,kBAAkB,CAAC,UAAU,CAAC,wBAAwB,CAAC,CAAC,CAAC;IACpF,MAAM,EAAE,UAAU,EAAE,mBAAmB,EAAE,SAAS,EAAE,kBAAkB,EAAE,GAAG,mBAAmB,CAAC,QAAQ,CAAC,CAAC;IACzG,MAAM,MAAM,GAAG,kBAAkB,CAAC,mBAAmB,EAAE,kBAAkB,CAAC,CAAC;IAE3E,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,MAAM,CAAC,CAAC;QAClE,MAAM,aAAa,GAAG,cAAc,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QACtD,aAAa,CAAC,kBAAkB,GAAG,QAAQ,CAAC,kBAAkB,CAAC,kBAAkB,CAAC,CAAC,CAAC;QAEpF,OAAO;YACL,OAAO,EAAE,CAAC;YACV,IAAI,EAAE,mBAAmB;YACzB,kBAAkB,EAAE,wBAAwB;YAC5C,UAAU,EAAE,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC,CAAC;SACzE,CAAC;IACJ,CAAC;YAAS,CAAC;QACT,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACjB,CAAC;AACH,CAAC"}
@@ -0,0 +1,26 @@
1
+ import type { SupportedChain, SupportedNetwork } from './types.js';
2
+ export interface DerivationOptions {
3
+ chain?: SupportedChain;
4
+ network?: SupportedNetwork;
5
+ prefix?: string;
6
+ }
7
+ export interface DerivedAddressResult {
8
+ chain: SupportedChain;
9
+ network: SupportedNetwork;
10
+ address: string;
11
+ derivationPath: string;
12
+ index: number;
13
+ }
14
+ export declare function buildDerivationPath(index: number, options?: DerivationOptions): string;
15
+ export declare function deriveEthereumAddress(mnemonic: string, index: number, network?: SupportedNetwork, prefix?: string): DerivedAddressResult;
16
+ export declare function deriveBitcoinAddress(mnemonic: string, index: number, network?: SupportedNetwork, prefix?: string): DerivedAddressResult;
17
+ export declare function deriveXrpAddress(mnemonic: string, index: number, network?: SupportedNetwork, prefix?: string): DerivedAddressResult;
18
+ /**
19
+ * Derives a Polkadot (sr25519) account from a mnemonic. Unlike the secp256k1/ed25519
20
+ * chains this is async: schnorrkel signing initializes a WASM module that must be
21
+ * ready first. The account uses the substrate hard junction `//<index>`, so the same
22
+ * mnemonic recovers identical accounts in Polkadot-JS / Talisman.
23
+ */
24
+ export declare function derivePolkadotAddress(mnemonic: string, index: number, network?: SupportedNetwork): Promise<DerivedAddressResult>;
25
+ export declare function deriveAddress(mnemonic: string, index: number, options?: DerivationOptions): Promise<DerivedAddressResult>;
26
+ //# sourceMappingURL=derivation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"derivation.d.ts","sourceRoot":"","sources":["../src/derivation.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAMnE,MAAM,WAAW,iBAAiB;IAChC,KAAK,CAAC,EAAE,cAAc,CAAC;IACvB,OAAO,CAAC,EAAE,gBAAgB,CAAC;IAC3B,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,oBAAoB;IACnC,KAAK,EAAE,cAAc,CAAC;IACtB,OAAO,EAAE,gBAAgB,CAAC;IAC1B,OAAO,EAAE,MAAM,CAAC;IAChB,cAAc,EAAE,MAAM,CAAC;IACvB,KAAK,EAAE,MAAM,CAAC;CACf;AAED,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,GAAE,iBAAsB,GAAG,MAAM,CAsB1F;AAED,wBAAgB,qBAAqB,CACnC,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,MAAM,EACb,OAAO,GAAE,gBAAkC,EAC3C,MAAM,SAAsD,GAC3D,oBAAoB,CAetB;AAED,wBAAgB,oBAAoB,CAClC,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,MAAM,EACb,OAAO,GAAE,gBAAkC,EAC3C,MAAM,SAAqD,GAC1D,oBAAoB,CA0BtB;AAED,wBAAgB,gBAAgB,CAC9B,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,MAAM,EACb,OAAO,GAAE,gBAAkC,EAC3C,MAAM,SAAiD,GACtD,oBAAoB,CAiBtB;AAED;;;;;GAKG;AACH,wBAAsB,qBAAqB,CACzC,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,MAAM,EACb,OAAO,GAAE,gBAAkC,GAC1C,OAAO,CAAC,oBAAoB,CAAC,CAc/B;AAED,wBAAsB,aAAa,CACjC,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,MAAM,EACb,OAAO,GAAE,iBAAsB,GAC9B,OAAO,CAAC,oBAAoB,CAAC,CAa/B"}
@@ -0,0 +1,121 @@
1
+ import { Keyring } from '@polkadot/keyring';
2
+ import { cryptoWaitReady } from '@polkadot/util-crypto';
3
+ import { mnemonicToSeedSync } from '@scure/bip39';
4
+ import { BIP32Factory } from 'bip32';
5
+ import { initEccLib, networks, payments } from 'bitcoinjs-lib';
6
+ import { HDNodeWallet } from 'ethers';
7
+ import * as ecc from 'tiny-secp256k1';
8
+ import { Wallet as XrplWallet } from 'xrpl';
9
+ import { DEFAULT_CHAIN, DEFAULT_NETWORK, getChainDefinition, POLKADOT_SS58_FORMAT } from './chains.js';
10
+ import { ValidationError } from './errors.js';
11
+ initEccLib(ecc);
12
+ const bip32 = BIP32Factory(ecc);
13
+ export function buildDerivationPath(index, options = {}) {
14
+ if (!Number.isInteger(index) || index < 0) {
15
+ throw new ValidationError('Account index must be a non-negative integer.');
16
+ }
17
+ const chain = options.chain ?? DEFAULT_CHAIN;
18
+ const network = options.network ?? DEFAULT_NETWORK;
19
+ // Polkadot/Substrate use junction-style derivation, not BIP44: a hard junction
20
+ // `//<index>` appended to the mnemonic (e.g. `//0`), so don't `/`-join a prefix.
21
+ if (chain === 'polkadot') {
22
+ return `//${index}`;
23
+ }
24
+ const definition = getChainDefinition(chain);
25
+ const prefix = options.prefix ??
26
+ (chain === 'bitcoin' && network === 'testnet'
27
+ ? definition.testnetDerivationPathPrefix ?? definition.derivationPathPrefix
28
+ : definition.derivationPathPrefix);
29
+ return `${prefix}/${index}`;
30
+ }
31
+ export function deriveEthereumAddress(mnemonic, index, network = DEFAULT_NETWORK, prefix = getChainDefinition('ethereum').derivationPathPrefix) {
32
+ const derivationPath = buildDerivationPath(index, {
33
+ chain: 'ethereum',
34
+ network,
35
+ prefix
36
+ });
37
+ const wallet = HDNodeWallet.fromPhrase(mnemonic, undefined, derivationPath);
38
+ return {
39
+ chain: 'ethereum',
40
+ network,
41
+ address: wallet.address,
42
+ derivationPath,
43
+ index
44
+ };
45
+ }
46
+ export function deriveBitcoinAddress(mnemonic, index, network = DEFAULT_NETWORK, prefix = getChainDefinition('bitcoin').derivationPathPrefix) {
47
+ const derivationPath = buildDerivationPath(index, {
48
+ chain: 'bitcoin',
49
+ network,
50
+ prefix
51
+ });
52
+ const seed = mnemonicToSeedSync(mnemonic);
53
+ const btcNetwork = network === 'testnet' ? networks.testnet : networks.bitcoin;
54
+ const root = bip32.fromSeed(Buffer.from(seed), btcNetwork);
55
+ const child = root.derivePath(derivationPath);
56
+ const payment = payments.p2wpkh({
57
+ pubkey: Buffer.from(child.publicKey),
58
+ network: btcNetwork
59
+ });
60
+ if (payment.address == null) {
61
+ throw new ValidationError('Unable to derive a Bitcoin address from the supplied mnemonic.');
62
+ }
63
+ return {
64
+ chain: 'bitcoin',
65
+ network,
66
+ address: payment.address,
67
+ derivationPath,
68
+ index
69
+ };
70
+ }
71
+ export function deriveXrpAddress(mnemonic, index, network = DEFAULT_NETWORK, prefix = getChainDefinition('xrp').derivationPathPrefix) {
72
+ const derivationPath = buildDerivationPath(index, {
73
+ chain: 'xrp',
74
+ network,
75
+ prefix
76
+ });
77
+ const wallet = XrplWallet.fromMnemonic(mnemonic, {
78
+ derivationPath
79
+ });
80
+ return {
81
+ chain: 'xrp',
82
+ network,
83
+ address: wallet.classicAddress,
84
+ derivationPath,
85
+ index
86
+ };
87
+ }
88
+ /**
89
+ * Derives a Polkadot (sr25519) account from a mnemonic. Unlike the secp256k1/ed25519
90
+ * chains this is async: schnorrkel signing initializes a WASM module that must be
91
+ * ready first. The account uses the substrate hard junction `//<index>`, so the same
92
+ * mnemonic recovers identical accounts in Polkadot-JS / Talisman.
93
+ */
94
+ export async function derivePolkadotAddress(mnemonic, index, network = DEFAULT_NETWORK) {
95
+ const derivationPath = buildDerivationPath(index, { chain: 'polkadot', network });
96
+ await cryptoWaitReady();
97
+ const ss58Format = POLKADOT_SS58_FORMAT[network] ?? 0;
98
+ const keyring = new Keyring({ type: 'sr25519', ss58Format });
99
+ const pair = keyring.createFromUri(`${mnemonic}${derivationPath}`);
100
+ return {
101
+ chain: 'polkadot',
102
+ network,
103
+ address: pair.address,
104
+ derivationPath,
105
+ index
106
+ };
107
+ }
108
+ export async function deriveAddress(mnemonic, index, options = {}) {
109
+ const chain = options.chain ?? DEFAULT_CHAIN;
110
+ switch (chain) {
111
+ case 'ethereum':
112
+ return deriveEthereumAddress(mnemonic, index, options.network, options.prefix);
113
+ case 'bitcoin':
114
+ return deriveBitcoinAddress(mnemonic, index, options.network, options.prefix);
115
+ case 'xrp':
116
+ return deriveXrpAddress(mnemonic, index, options.network, options.prefix);
117
+ case 'polkadot':
118
+ return derivePolkadotAddress(mnemonic, index, options.network);
119
+ }
120
+ }
121
+ //# sourceMappingURL=derivation.js.map