@onekeyfe/hardware-cli 1.1.25-alpha.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.
- package/.claude-plugin/plugin.json +14 -0
- package/dist/chains.d.ts +74 -0
- package/dist/chains.js +307 -0
- package/dist/cli.d.ts +1 -0
- package/dist/cli.js +824 -0
- package/dist/index.d.ts +96 -0
- package/dist/index.js +30 -0
- package/dist/sdk.d.ts +16 -0
- package/dist/sdk.js +187 -0
- package/evals/cases.json +564 -0
- package/evals/run-evals.sh +136 -0
- package/package.json +34 -0
- package/rollup.config.js +28 -0
- package/skills/device/SKILL.md +191 -0
- package/skills/firmware/SKILL.md +163 -0
- package/skills/security/SKILL.md +328 -0
- package/skills/signing/SKILL.md +478 -0
- package/src/chains.ts +387 -0
- package/src/cli.ts +855 -0
- package/src/index.ts +38 -0
- package/src/sdk.ts +198 -0
- package/tsconfig.json +18 -0
package/src/chains.ts
ADDED
|
@@ -0,0 +1,387 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Chain Resolver — maps chain identifiers to the correct SDK API calls.
|
|
3
|
+
* Handles derivation path defaults and chain-specific parameter transformations.
|
|
4
|
+
*
|
|
5
|
+
* Reference: developer-portal docs at
|
|
6
|
+
* content/en/hardware-sdk/chains/<chain>/<method>.mdx
|
|
7
|
+
* content/en/hardware-sdk/core-api-guide.mdx (HD path section)
|
|
8
|
+
*
|
|
9
|
+
* Type definitions: packages/core/src/types/api/*.ts
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
import type { CoreApi } from '@onekeyfe/hd-core';
|
|
13
|
+
|
|
14
|
+
// Default BIP44 derivation paths per chain
|
|
15
|
+
// Sources: developer-portal core-api-guide.mdx + chain-specific docs
|
|
16
|
+
const DEFAULT_PATHS: Record<string, string> = {
|
|
17
|
+
evm: "m/44'/60'/0'/0/0", // EIP-44 standard
|
|
18
|
+
btc: "m/84'/0'/0'/0/0", // Native SegWit (bech32). Also: m/44' (legacy), m/49' (nested segwit), m/86' (taproot)
|
|
19
|
+
sol: "m/44'/501'/0'/0'", // Fully hardened per Solana spec
|
|
20
|
+
tron: "m/44'/195'/0'/0/0",
|
|
21
|
+
cosmos: "m/44'/118'/0'/0/0",
|
|
22
|
+
cardano: "m/1852'/1815'/0'/0/0", // Shelley-era
|
|
23
|
+
polkadot: "m/44'/354'/0'/0'/0'",
|
|
24
|
+
aptos: "m/44'/637'/0'/0'/0'", // Fully hardened
|
|
25
|
+
sui: "m/44'/784'/0'/0'/0'", // Fully hardened
|
|
26
|
+
near: "m/44'/397'/0'", // Short path per NEAR spec
|
|
27
|
+
xrp: "m/44'/144'/0'/0/0",
|
|
28
|
+
stellar: "m/44'/148'/0'",
|
|
29
|
+
ton: "m/44'/607'/0'",
|
|
30
|
+
nostr: "m/44'/1237'/0'/0/0",
|
|
31
|
+
filecoin: "m/44'/461'/0'/0/0",
|
|
32
|
+
kaspa: "m/44'/111111'/0'/0/0",
|
|
33
|
+
algo: "m/44'/283'/0'/0/0",
|
|
34
|
+
conflux: "m/44'/503'/0'/0/0",
|
|
35
|
+
nervos: "m/44'/309'/0'/0/0",
|
|
36
|
+
alephium: "m/44'/1234'/0'/0/0",
|
|
37
|
+
neo: "m/44'/888'/0'/0/0",
|
|
38
|
+
starcoin: "m/44'/101010'/0'/0'/0'",
|
|
39
|
+
nem: "m/44'/43'/0'/0'/0'",
|
|
40
|
+
dnx: "m/44'/29538'/0'/0'/0'",
|
|
41
|
+
scdo: "m/44'/541'/0'/0/0",
|
|
42
|
+
benfen: "m/44'/728'/0'/0'/0'",
|
|
43
|
+
nexa: "m/44'/29223'/0'/0/0",
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
// Chain name aliases for fuzzy matching
|
|
47
|
+
const CHAIN_ALIASES: Record<string, string> = {
|
|
48
|
+
ethereum: 'evm',
|
|
49
|
+
eth: 'evm',
|
|
50
|
+
bitcoin: 'btc',
|
|
51
|
+
solana: 'sol',
|
|
52
|
+
dot: 'polkadot',
|
|
53
|
+
ada: 'cardano',
|
|
54
|
+
atom: 'cosmos',
|
|
55
|
+
apt: 'aptos',
|
|
56
|
+
ripple: 'xrp',
|
|
57
|
+
xlm: 'stellar',
|
|
58
|
+
fil: 'filecoin',
|
|
59
|
+
ckb: 'nervos',
|
|
60
|
+
alph: 'alephium',
|
|
61
|
+
cfx: 'conflux',
|
|
62
|
+
stc: 'starcoin',
|
|
63
|
+
xem: 'nem',
|
|
64
|
+
bfc: 'benfen',
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
function resolveChain(chain: string): string {
|
|
68
|
+
const normalized = chain.toLowerCase().trim();
|
|
69
|
+
return CHAIN_ALIASES[normalized] || normalized;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
function getDefaultPath(chain: string): string {
|
|
73
|
+
const resolved = resolveChain(chain);
|
|
74
|
+
const path = DEFAULT_PATHS[resolved];
|
|
75
|
+
if (!path) {
|
|
76
|
+
throw new Error(
|
|
77
|
+
`Unsupported chain: ${chain}. Supported: ${Object.keys(DEFAULT_PATHS).join(', ')}`
|
|
78
|
+
);
|
|
79
|
+
}
|
|
80
|
+
return path;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Common params passed to all SDK methods.
|
|
85
|
+
* Reference: packages/core/src/types/api/export.ts (CommonParams)
|
|
86
|
+
*/
|
|
87
|
+
export interface CommonCLIParams {
|
|
88
|
+
connectId?: string;
|
|
89
|
+
deviceId?: string;
|
|
90
|
+
passphraseState?: string;
|
|
91
|
+
useEmptyPassphrase?: boolean;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
export interface GetAddressParams extends CommonCLIParams {
|
|
95
|
+
chain: string;
|
|
96
|
+
path?: string;
|
|
97
|
+
showOnDevice?: boolean;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
export async function resolveGetAddress(sdk: CoreApi, params: GetAddressParams) {
|
|
101
|
+
const chain = resolveChain(params.chain);
|
|
102
|
+
const path = params.path || getDefaultPath(chain);
|
|
103
|
+
const showOnOneKey = params.showOnDevice ?? true;
|
|
104
|
+
const connectId = params.connectId || '';
|
|
105
|
+
const deviceId = params.deviceId || '';
|
|
106
|
+
|
|
107
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
108
|
+
const chainMethodMap: Record<string, () => Promise<any>> = {
|
|
109
|
+
evm: () => sdk.evmGetAddress(connectId, deviceId, { path, showOnOneKey }),
|
|
110
|
+
btc: () => sdk.btcGetAddress(connectId, deviceId, { path, showOnOneKey, coin: 'btc' }),
|
|
111
|
+
sol: () => sdk.solGetAddress(connectId, deviceId, { path, showOnOneKey }),
|
|
112
|
+
tron: () => sdk.tronGetAddress(connectId, deviceId, { path, showOnOneKey }),
|
|
113
|
+
cosmos: () => sdk.cosmosGetAddress(connectId, deviceId, { path, showOnOneKey }),
|
|
114
|
+
// Cardano requires networkId, protocolMagic, derivationType
|
|
115
|
+
cardano: () =>
|
|
116
|
+
sdk.cardanoGetAddress(connectId, deviceId, {
|
|
117
|
+
addressParameters: { path, addressType: 0 } as any,
|
|
118
|
+
networkId: 1, // mainnet
|
|
119
|
+
protocolMagic: 764824073, // mainnet magic
|
|
120
|
+
derivationType: 1, // Icarus
|
|
121
|
+
showOnOneKey,
|
|
122
|
+
}),
|
|
123
|
+
// Polkadot requires network param
|
|
124
|
+
polkadot: () =>
|
|
125
|
+
sdk.polkadotGetAddress(connectId, deviceId, {
|
|
126
|
+
path,
|
|
127
|
+
prefix: 0,
|
|
128
|
+
network: 'polkadot',
|
|
129
|
+
showOnOneKey,
|
|
130
|
+
}),
|
|
131
|
+
aptos: () => sdk.aptosGetAddress(connectId, deviceId, { path, showOnOneKey }),
|
|
132
|
+
sui: () => sdk.suiGetAddress(connectId, deviceId, { path, showOnOneKey }),
|
|
133
|
+
near: () => sdk.nearGetAddress(connectId, deviceId, { path, showOnOneKey }),
|
|
134
|
+
xrp: () => sdk.xrpGetAddress(connectId, deviceId, { path, showOnOneKey }),
|
|
135
|
+
stellar: () => sdk.stellarGetAddress(connectId, deviceId, { path, showOnOneKey }),
|
|
136
|
+
ton: () => sdk.tonGetAddress(connectId, deviceId, { path, showOnOneKey }),
|
|
137
|
+
filecoin: () => sdk.filecoinGetAddress(connectId, deviceId, { path, showOnOneKey }),
|
|
138
|
+
kaspa: () => sdk.kaspaGetAddress(connectId, deviceId, { path, showOnOneKey, prefix: 'kaspa' }),
|
|
139
|
+
algo: () => sdk.algoGetAddress(connectId, deviceId, { path, showOnOneKey }),
|
|
140
|
+
conflux: () => sdk.confluxGetAddress(connectId, deviceId, { path, showOnOneKey }),
|
|
141
|
+
nervos: () => sdk.nervosGetAddress(connectId, deviceId, { path, showOnOneKey, network: 'ckb' }),
|
|
142
|
+
alephium: () => sdk.alephiumGetAddress(connectId, deviceId, { path, showOnOneKey, group: 0 }),
|
|
143
|
+
neo: () => sdk.neoGetAddress(connectId, deviceId, { path, showOnOneKey }),
|
|
144
|
+
starcoin: () => sdk.starcoinGetAddress(connectId, deviceId, { path, showOnOneKey }),
|
|
145
|
+
nem: () => sdk.nemGetAddress(connectId, deviceId, { path, showOnOneKey, network: 104 }),
|
|
146
|
+
dnx: () => sdk.dnxGetAddress(connectId, deviceId, { path, showOnOneKey }),
|
|
147
|
+
scdo: () => sdk.scdoGetAddress(connectId, deviceId, { path, showOnOneKey }),
|
|
148
|
+
benfen: () => sdk.benfenGetAddress(connectId, deviceId, { path, showOnOneKey }),
|
|
149
|
+
nexa: () => sdk.nexaGetAddress(connectId, deviceId, { path, showOnOneKey, prefix: 'nexa' }),
|
|
150
|
+
};
|
|
151
|
+
|
|
152
|
+
const method = chainMethodMap[chain];
|
|
153
|
+
if (!method) {
|
|
154
|
+
throw new Error(`getAddress not supported for chain: ${chain}`);
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
const result = await method();
|
|
158
|
+
if (result == null) {
|
|
159
|
+
return { success: false, error: 'No response from device', chain, path };
|
|
160
|
+
}
|
|
161
|
+
return { ...(result as object), chain, path };
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
export interface GetPublicKeyParams extends CommonCLIParams {
|
|
165
|
+
chain: string;
|
|
166
|
+
path?: string;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
export async function resolveGetPublicKey(sdk: CoreApi, params: GetPublicKeyParams) {
|
|
170
|
+
const chain = resolveChain(params.chain);
|
|
171
|
+
const path = params.path || getDefaultPath(chain);
|
|
172
|
+
const connectId = params.connectId || '';
|
|
173
|
+
const deviceId = params.deviceId || '';
|
|
174
|
+
|
|
175
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
176
|
+
const chainMethodMap: Record<string, () => Promise<any>> = {
|
|
177
|
+
evm: () => sdk.evmGetPublicKey(connectId, deviceId, { path }),
|
|
178
|
+
btc: () => sdk.btcGetPublicKey(connectId, deviceId, { path, coin: 'btc' }),
|
|
179
|
+
aptos: () => sdk.aptosGetPublicKey(connectId, deviceId, { path }),
|
|
180
|
+
cosmos: () => sdk.cosmosGetPublicKey(connectId, deviceId, { path }),
|
|
181
|
+
sui: () => sdk.suiGetPublicKey(connectId, deviceId, { path }),
|
|
182
|
+
starcoin: () => sdk.starcoinGetPublicKey(connectId, deviceId, { path }),
|
|
183
|
+
nostr: () => sdk.nostrGetPublicKey(connectId, deviceId, { path }),
|
|
184
|
+
benfen: () => sdk.benfenGetPublicKey(connectId, deviceId, { path }),
|
|
185
|
+
cardano: () => sdk.cardanoGetPublicKey(connectId, deviceId, { path, derivationType: 1 }),
|
|
186
|
+
};
|
|
187
|
+
|
|
188
|
+
const method = chainMethodMap[chain];
|
|
189
|
+
if (!method) {
|
|
190
|
+
throw new Error(
|
|
191
|
+
`getPublicKey not supported for chain: ${chain}. Supported: ${Object.keys(
|
|
192
|
+
chainMethodMap
|
|
193
|
+
).join(', ')}`
|
|
194
|
+
);
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
const result = await method();
|
|
198
|
+
return { ...(result as object), chain, path };
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
export interface SignTransactionParams extends CommonCLIParams {
|
|
202
|
+
chain: string;
|
|
203
|
+
path?: string;
|
|
204
|
+
transaction: Record<string, unknown>;
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
export async function resolveSignTransaction(sdk: CoreApi, params: SignTransactionParams) {
|
|
208
|
+
const chain = resolveChain(params.chain);
|
|
209
|
+
const path = params.path || getDefaultPath(chain);
|
|
210
|
+
const connectId = params.connectId || '';
|
|
211
|
+
const deviceId = params.deviceId || '';
|
|
212
|
+
const tx = params.transaction;
|
|
213
|
+
|
|
214
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
215
|
+
const chainMethodMap: Record<string, () => Promise<any>> = {
|
|
216
|
+
// EVM: chainId is inside the transaction object, not top-level
|
|
217
|
+
evm: () => sdk.evmSignTransaction(connectId, deviceId, { path, transaction: tx as any }),
|
|
218
|
+
// BTC: requires inputs/outputs/refTxs/coin format
|
|
219
|
+
btc: () => sdk.btcSignTransaction(connectId, deviceId, { coin: 'btc', ...(tx as any) }),
|
|
220
|
+
sol: () => sdk.solSignTransaction(connectId, deviceId, { path, rawTx: tx.rawTx as string }),
|
|
221
|
+
tron: () => sdk.tronSignTransaction(connectId, deviceId, { path, transaction: tx as any }),
|
|
222
|
+
cosmos: () =>
|
|
223
|
+
sdk.cosmosSignTransaction(connectId, deviceId, { path, rawTx: tx.rawTx as string }),
|
|
224
|
+
aptos: () => sdk.aptosSignTransaction(connectId, deviceId, { path, rawTx: tx.rawTx as string }),
|
|
225
|
+
sui: () => sdk.suiSignTransaction(connectId, deviceId, { path, rawTx: tx.rawTx as string }),
|
|
226
|
+
near: () => sdk.nearSignTransaction(connectId, deviceId, { path, rawTx: tx.rawTx as string }),
|
|
227
|
+
// XRP: implementation reads path + transaction from payload despite type declaration
|
|
228
|
+
// eslint-disable-next-line @typescript-eslint/ban-types
|
|
229
|
+
xrp: () =>
|
|
230
|
+
(sdk.xrpSignTransaction as (...args: unknown[]) => Promise<unknown>)(connectId, deviceId, {
|
|
231
|
+
path,
|
|
232
|
+
transaction: tx,
|
|
233
|
+
}),
|
|
234
|
+
stellar: () =>
|
|
235
|
+
sdk.stellarSignTransaction(connectId, deviceId, {
|
|
236
|
+
path,
|
|
237
|
+
networkPassphrase: tx.networkPassphrase as string,
|
|
238
|
+
transaction: tx.transaction as any,
|
|
239
|
+
}),
|
|
240
|
+
// Polkadot: requires prefix param
|
|
241
|
+
polkadot: () =>
|
|
242
|
+
sdk.polkadotSignTransaction(connectId, deviceId, {
|
|
243
|
+
path,
|
|
244
|
+
rawTx: tx.rawTx as string,
|
|
245
|
+
network: (tx.network as string) || 'polkadot',
|
|
246
|
+
prefix: (tx.prefix as number) ?? 0,
|
|
247
|
+
}),
|
|
248
|
+
filecoin: () =>
|
|
249
|
+
sdk.filecoinSignTransaction(connectId, deviceId, { path, rawTx: tx.rawTx as string }),
|
|
250
|
+
kaspa: () => sdk.kaspaSignTransaction(connectId, deviceId, { ...(tx as any) }),
|
|
251
|
+
algo: () => sdk.algoSignTransaction(connectId, deviceId, { path, rawTx: tx.rawTx as string }),
|
|
252
|
+
conflux: () =>
|
|
253
|
+
sdk.confluxSignTransaction(connectId, deviceId, { path, transaction: tx as any }),
|
|
254
|
+
nervos: () => sdk.nervosSignTransaction(connectId, deviceId, { ...(tx as any) }),
|
|
255
|
+
alephium: () =>
|
|
256
|
+
sdk.alephiumSignTransaction(connectId, deviceId, { path, rawTx: tx.rawTx as string }),
|
|
257
|
+
neo: () => sdk.neoSignTransaction(connectId, deviceId, { path, ...(tx as any) }),
|
|
258
|
+
dnx: () => sdk.dnxSignTransaction(connectId, deviceId, { path, ...(tx as any) }),
|
|
259
|
+
// SCDO: flat params (nonce, gasPrice, gasLimit, to, value, data), not wrapped
|
|
260
|
+
scdo: () => sdk.scdoSignTransaction(connectId, deviceId, { path, ...(tx as any) }),
|
|
261
|
+
benfen: () =>
|
|
262
|
+
sdk.benfenSignTransaction(connectId, deviceId, { path, rawTx: tx.rawTx as string }),
|
|
263
|
+
nexa: () => sdk.nexaSignTransaction(connectId, deviceId, { ...(tx as any) }),
|
|
264
|
+
cardano: () => sdk.cardanoSignTransaction(connectId, deviceId, { ...(tx as any) }),
|
|
265
|
+
starcoin: () =>
|
|
266
|
+
sdk.starcoinSignTransaction(connectId, deviceId, { path, rawTx: tx.rawTx as string }),
|
|
267
|
+
};
|
|
268
|
+
|
|
269
|
+
const method = chainMethodMap[chain];
|
|
270
|
+
if (!method) {
|
|
271
|
+
throw new Error(`signTransaction not supported for chain: ${chain}`);
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
const result = await method();
|
|
275
|
+
return { ...(result as object), chain, path };
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
export interface SignMessageParams extends CommonCLIParams {
|
|
279
|
+
chain: string;
|
|
280
|
+
path?: string;
|
|
281
|
+
message: string;
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
export async function resolveSignMessage(sdk: CoreApi, params: SignMessageParams) {
|
|
285
|
+
const chain = resolveChain(params.chain);
|
|
286
|
+
const path = params.path || getDefaultPath(chain);
|
|
287
|
+
const connectId = params.connectId || '';
|
|
288
|
+
const deviceId = params.deviceId || '';
|
|
289
|
+
|
|
290
|
+
// Most chains use `messageHex` (hex-encoded). CLI accepts either:
|
|
291
|
+
// - Already hex-encoded string (starts with "0x" or matches /^[0-9a-fA-F]+$/)
|
|
292
|
+
// - Plain text string (auto-converted to hex)
|
|
293
|
+
const raw = params.message;
|
|
294
|
+
const isHex = /^(0x)?[0-9a-fA-F]+$/.test(raw);
|
|
295
|
+
const msg = isHex ? raw.replace(/^0x/, '') : Buffer.from(raw, 'utf8').toString('hex');
|
|
296
|
+
|
|
297
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
298
|
+
const chainMethodMap: Record<string, () => Promise<any>> = {
|
|
299
|
+
evm: () => sdk.evmSignMessage(connectId, deviceId, { path, messageHex: msg }),
|
|
300
|
+
// BTC: uses messageHex, not message
|
|
301
|
+
btc: () => sdk.btcSignMessage(connectId, deviceId, { path, messageHex: msg, coin: 'btc' }),
|
|
302
|
+
sol: () => sdk.solSignMessage(connectId, deviceId, { path, messageHex: msg }),
|
|
303
|
+
// Tron: uses messageHex
|
|
304
|
+
tron: () => sdk.tronSignMessage(connectId, deviceId, { path, messageHex: msg }),
|
|
305
|
+
aptos: () =>
|
|
306
|
+
sdk.aptosSignMessage(connectId, deviceId, { path, payload: { message: msg } as any }),
|
|
307
|
+
sui: () => sdk.suiSignMessage(connectId, deviceId, { path, messageHex: msg }),
|
|
308
|
+
// Conflux: uses messageHex
|
|
309
|
+
conflux: () => sdk.confluxSignMessage(connectId, deviceId, { path, messageHex: msg }),
|
|
310
|
+
// Starcoin: uses messageHex
|
|
311
|
+
starcoin: () => sdk.starcoinSignMessage(connectId, deviceId, { path, messageHex: msg }),
|
|
312
|
+
// TON: tonSignMessage is transfer-signing, pass JSON params
|
|
313
|
+
ton: () => {
|
|
314
|
+
const tonParams = JSON.parse(msg);
|
|
315
|
+
return sdk.tonSignMessage(connectId, deviceId, { path, ...tonParams });
|
|
316
|
+
},
|
|
317
|
+
// Nostr: event must be a NostrEvent object (kind, content, tags, created_at)
|
|
318
|
+
nostr: () => {
|
|
319
|
+
const event = JSON.parse(msg);
|
|
320
|
+
return sdk.nostrSignEvent(connectId, deviceId, { path, event });
|
|
321
|
+
},
|
|
322
|
+
// SCDO: uses messageHex
|
|
323
|
+
scdo: () => sdk.scdoSignMessage(connectId, deviceId, { path, messageHex: msg }),
|
|
324
|
+
// Alephium: requires messageType
|
|
325
|
+
alephium: () =>
|
|
326
|
+
sdk.alephiumSignMessage(connectId, deviceId, {
|
|
327
|
+
path,
|
|
328
|
+
messageHex: msg,
|
|
329
|
+
messageType: 'alephium',
|
|
330
|
+
}),
|
|
331
|
+
benfen: () => sdk.benfenSignMessage(connectId, deviceId, { path, messageHex: msg }),
|
|
332
|
+
// Cardano: uses `message` field, requires networkId
|
|
333
|
+
cardano: () =>
|
|
334
|
+
sdk.cardanoSignMessage(connectId, deviceId, {
|
|
335
|
+
path,
|
|
336
|
+
message: msg,
|
|
337
|
+
derivationType: 1,
|
|
338
|
+
networkId: 1,
|
|
339
|
+
}),
|
|
340
|
+
};
|
|
341
|
+
|
|
342
|
+
const method = chainMethodMap[chain];
|
|
343
|
+
if (!method) {
|
|
344
|
+
throw new Error(
|
|
345
|
+
`signMessage not supported for chain: ${chain}. Supported: ${Object.keys(chainMethodMap).join(
|
|
346
|
+
', '
|
|
347
|
+
)}`
|
|
348
|
+
);
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
const result = await method();
|
|
352
|
+
return { ...(result as object), chain, path };
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
export interface BatchGetAddressParams extends CommonCLIParams {
|
|
356
|
+
bundle: Array<{
|
|
357
|
+
chain: string;
|
|
358
|
+
path?: string;
|
|
359
|
+
showOnDevice?: boolean;
|
|
360
|
+
}>;
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
export async function resolveBatchGetAddress(sdk: CoreApi, params: BatchGetAddressParams) {
|
|
364
|
+
// #13 FIX: Collect per-item results with error handling for partial failures
|
|
365
|
+
const results: Array<Record<string, unknown>> = [];
|
|
366
|
+
for (const item of params.bundle) {
|
|
367
|
+
try {
|
|
368
|
+
const result = await resolveGetAddress(sdk, {
|
|
369
|
+
chain: item.chain,
|
|
370
|
+
path: item.path,
|
|
371
|
+
showOnDevice: item.showOnDevice ?? false,
|
|
372
|
+
connectId: params.connectId,
|
|
373
|
+
deviceId: params.deviceId,
|
|
374
|
+
});
|
|
375
|
+
results.push(result);
|
|
376
|
+
} catch (err) {
|
|
377
|
+
results.push({
|
|
378
|
+
chain: item.chain,
|
|
379
|
+
path: item.path,
|
|
380
|
+
success: false,
|
|
381
|
+
error: err instanceof Error ? err.message : String(err),
|
|
382
|
+
});
|
|
383
|
+
}
|
|
384
|
+
}
|
|
385
|
+
const allSuccess = results.every(r => r.success !== false);
|
|
386
|
+
return { success: allSuccess, addresses: results };
|
|
387
|
+
}
|