@canton-network/wallet-gateway-remote 1.4.0 → 1.6.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/dist/auth/jwt-auth-service.d.ts.map +1 -1
- package/dist/auth/jwt-auth-service.js +6 -5
- package/dist/auth/jwt-auth-service.test.d.ts +2 -0
- package/dist/auth/jwt-auth-service.test.d.ts.map +1 -0
- package/dist/auth/jwt-auth-service.test.js +259 -0
- package/dist/auth/jwt-unsafe-auth-service.test.d.ts +2 -0
- package/dist/auth/jwt-unsafe-auth-service.test.d.ts.map +1 -0
- package/dist/auth/jwt-unsafe-auth-service.test.js +120 -0
- package/dist/config/Config.d.ts +69 -4
- package/dist/config/Config.d.ts.map +1 -1
- package/dist/config/Config.js +6 -0
- package/dist/config/ConfigUtils.d.ts.map +1 -1
- package/dist/config/ConfigUtils.js +3 -0
- package/dist/dapp-api/controller.d.ts +5 -1
- package/dist/dapp-api/controller.d.ts.map +1 -1
- package/dist/dapp-api/controller.js +104 -30
- package/dist/dapp-api/controller.test.js +2 -2
- package/dist/dapp-api/server.d.ts +3 -2
- package/dist/dapp-api/server.d.ts.map +1 -1
- package/dist/dapp-api/server.js +2 -2
- package/dist/dapp-api/server.test.js +1 -6
- package/dist/example-config.d.ts +3 -0
- package/dist/example-config.d.ts.map +1 -1
- package/dist/example-config.js +3 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +10 -0
- package/dist/init.d.ts.map +1 -1
- package/dist/init.js +19 -7
- package/dist/ledger/transaction-service.d.ts +16 -11
- package/dist/ledger/transaction-service.d.ts.map +1 -1
- package/dist/ledger/transaction-service.js +135 -8
- package/dist/ledger/transaction-service.test.d.ts +2 -0
- package/dist/ledger/transaction-service.test.d.ts.map +1 -0
- package/dist/ledger/transaction-service.test.js +390 -0
- package/dist/ledger/wallet-allocation/signing-providers/fireblocks-wallet-allocator.d.ts +5 -2
- package/dist/ledger/wallet-allocation/signing-providers/fireblocks-wallet-allocator.d.ts.map +1 -1
- package/dist/ledger/wallet-allocation/signing-providers/fireblocks-wallet-allocator.js +7 -6
- package/dist/ledger/wallet-allocation/wallet-allocation-service.d.ts +11 -5
- package/dist/ledger/wallet-allocation/wallet-allocation-service.d.ts.map +1 -1
- package/dist/ledger/wallet-allocation/wallet-allocation-service.js +28 -14
- package/dist/ledger/wallet-allocation/wallet-allocation-service.test.js +550 -19
- package/dist/ledger/wallet-sync-service.js +3 -3
- package/dist/middleware/apiKeyAuth.d.ts +6 -0
- package/dist/middleware/apiKeyAuth.d.ts.map +1 -0
- package/dist/middleware/apiKeyAuth.js +90 -0
- package/dist/middleware/apiKeyAuth.test.d.ts +2 -0
- package/dist/middleware/apiKeyAuth.test.d.ts.map +1 -0
- package/dist/middleware/apiKeyAuth.test.js +126 -0
- package/dist/middleware/jsonRpcHandler.d.ts +11 -1
- package/dist/middleware/jsonRpcHandler.d.ts.map +1 -1
- package/dist/middleware/jsonRpcHandler.js +14 -15
- package/dist/middleware/jsonRpcHandler.test.d.ts +2 -0
- package/dist/middleware/jsonRpcHandler.test.d.ts.map +1 -0
- package/dist/middleware/jsonRpcHandler.test.js +254 -0
- package/dist/middleware/jwtAuth.d.ts.map +1 -1
- package/dist/middleware/jwtAuth.js +4 -0
- package/dist/middleware/jwtAuth.test.d.ts +2 -0
- package/dist/middleware/jwtAuth.test.d.ts.map +1 -0
- package/dist/middleware/jwtAuth.test.js +93 -0
- package/dist/middleware/rateLimit.test.js +12 -0
- package/dist/middleware/sessionHandler.js +1 -1
- package/dist/middleware/sessionHandler.test.d.ts +2 -0
- package/dist/middleware/sessionHandler.test.d.ts.map +1 -0
- package/dist/middleware/sessionHandler.test.js +121 -0
- package/dist/notification/NotificationService.test.d.ts +2 -0
- package/dist/notification/NotificationService.test.d.ts.map +1 -0
- package/dist/notification/NotificationService.test.js +110 -0
- package/dist/signing/service-account-session.d.ts +16 -0
- package/dist/signing/service-account-session.d.ts.map +1 -0
- package/dist/signing/service-account-session.js +25 -0
- package/dist/signing/service-account-session.test.d.ts +2 -0
- package/dist/signing/service-account-session.test.d.ts.map +1 -0
- package/dist/signing/service-account-session.test.js +89 -0
- package/dist/signing/signing-drivers.d.ts +7 -0
- package/dist/signing/signing-drivers.d.ts.map +1 -0
- package/dist/signing/signing-drivers.js +3 -0
- package/dist/signing/signing-worker.d.ts +83 -0
- package/dist/signing/signing-worker.d.ts.map +1 -0
- package/dist/signing/signing-worker.js +206 -0
- package/dist/signing/signing-worker.test.d.ts +2 -0
- package/dist/signing/signing-worker.test.d.ts.map +1 -0
- package/dist/signing/signing-worker.test.js +152 -0
- package/dist/user-api/controller.d.ts +6 -4
- package/dist/user-api/controller.d.ts.map +1 -1
- package/dist/user-api/controller.js +119 -95
- package/dist/user-api/controller.test.d.ts +2 -0
- package/dist/user-api/controller.test.d.ts.map +1 -0
- package/dist/user-api/controller.test.js +862 -0
- package/dist/user-api/rpc-gen/index.d.ts +12 -0
- package/dist/user-api/rpc-gen/index.d.ts.map +1 -1
- package/dist/user-api/rpc-gen/index.js +4 -0
- package/dist/user-api/rpc-gen/typings.d.ts +52 -3
- package/dist/user-api/rpc-gen/typings.d.ts.map +1 -1
- package/dist/utils.d.ts +17 -1
- package/dist/utils.d.ts.map +1 -1
- package/dist/utils.js +53 -2
- package/dist/utils.test.d.ts +2 -0
- package/dist/utils.test.d.ts.map +1 -0
- package/dist/utils.test.js +24 -0
- package/dist/web/frontend/404/index.html +2 -2
- package/dist/web/frontend/activities/index.html +3 -3
- package/dist/web/frontend/approve/index.html +4 -4
- package/dist/web/frontend/assets/{404-C7V2yl2z.js → 404-C4hCL2o8.js} +2 -2
- package/dist/web/frontend/assets/{activities-NY8oZAkH.js → activities-Bq7yMMQY.js} +2 -2
- package/dist/web/frontend/assets/addIdentityProvider-DRJWLhHF.js +28 -0
- package/dist/web/frontend/assets/addNetwork-CJUaKP1q.js +38 -0
- package/dist/web/frontend/assets/addParty-2ObTLGIL.js +45 -0
- package/dist/web/frontend/assets/approve-BuA5DGC2.js +21 -0
- package/dist/web/frontend/assets/callback-C5vJWFLq.js +1 -0
- package/dist/web/frontend/assets/{identityProviders-BZ9h_VOJ.js → identityProviders-78FbpzYL.js} +2 -2
- package/dist/web/frontend/assets/{index-B-HiKugW.js → index-BTH_md6b.js} +3 -3
- package/dist/web/frontend/assets/index-CFnOucPK.js +4737 -0
- package/dist/web/frontend/assets/{login-CqwMEG9J.js → login-Dyn1o6fW.js} +2 -2
- package/dist/web/frontend/assets/{networks-BJvRi47M.js → networks-_el10AWP.js} +2 -2
- package/dist/web/frontend/assets/reviewIdentityProvider-DodUZ2mY.js +43 -0
- package/dist/web/frontend/assets/reviewNetwork-BFMtmKEL.js +43 -0
- package/dist/web/frontend/assets/settings-BBmkIfYm.js +37 -0
- package/dist/web/frontend/assets/{state-qAsNw5qf.js → state-DkxLvywv.js} +1 -1
- package/dist/web/frontend/assets/{utils-BDkHxi8V.js → utils-DvJKIYxT.js} +1 -1
- package/dist/web/frontend/callback/index.html +2 -2
- package/dist/web/frontend/identity-providers/add/index.html +3 -3
- package/dist/web/frontend/identity-providers/index.html +3 -3
- package/dist/web/frontend/identity-providers/review/index.html +3 -3
- package/dist/web/frontend/index.html +1 -1
- package/dist/web/frontend/login/index.html +3 -3
- package/dist/web/frontend/networks/add/index.html +3 -3
- package/dist/web/frontend/networks/index.html +3 -3
- package/dist/web/frontend/networks/review/index.html +3 -3
- package/dist/web/frontend/parties/add/index.html +5 -5
- package/dist/web/frontend/parties/index.html +4 -4
- package/dist/web/frontend/settings/index.html +3 -3
- package/package.json +36 -32
- package/dist/web/frontend/assets/addIdentityProvider-38ghz3RT.js +0 -28
- package/dist/web/frontend/assets/addNetwork-BaDhbrZl.js +0 -38
- package/dist/web/frontend/assets/addParty-j3JWZX5a.js +0 -41
- package/dist/web/frontend/assets/approve-43nVzAAC.js +0 -21
- package/dist/web/frontend/assets/callback-BBMiCjHR.js +0 -1
- package/dist/web/frontend/assets/index-DoNqknyE.js +0 -4042
- package/dist/web/frontend/assets/reviewIdentityProvider-ySlQnw5R.js +0 -43
- package/dist/web/frontend/assets/reviewNetwork-DrVxeHd4.js +0 -43
- package/dist/web/frontend/assets/settings-BVNkaUyJ.js +0 -37
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
// Copyright (c) 2025-2026 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved.
|
|
2
2
|
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
import { LedgerClient } from '@canton-network/core-ledger-client';
|
|
3
4
|
import { SigningProvider, } from '@canton-network/core-signing-lib';
|
|
4
|
-
import { ledgerPrepareParams } from '../utils.js';
|
|
5
|
+
import { ledgerPrepareParams, logDynamically, } from '../utils.js';
|
|
6
|
+
import { AuthTokenProvider, } from '@canton-network/core-wallet-auth';
|
|
5
7
|
function handleSigningError(result) {
|
|
6
8
|
if ('error' in result) {
|
|
7
9
|
throw new Error(`Error from signing driver: ${result.error_description}`);
|
|
@@ -15,11 +17,116 @@ export class TransactionService {
|
|
|
15
17
|
this.signingDrivers = signingDrivers;
|
|
16
18
|
this.notifier = notifier;
|
|
17
19
|
}
|
|
20
|
+
async sign(authContext, wallet, signParams) {
|
|
21
|
+
const signingProvider = wallet.signingProviderId;
|
|
22
|
+
const driver = this.signingDrivers[signingProvider]?.controller(authContext.userId);
|
|
23
|
+
if (!driver) {
|
|
24
|
+
throw new Error(`No driver found for ${signingProvider}`);
|
|
25
|
+
}
|
|
26
|
+
switch (signingProvider) {
|
|
27
|
+
case SigningProvider.PARTICIPANT: {
|
|
28
|
+
return this.signWithParticipant(wallet);
|
|
29
|
+
}
|
|
30
|
+
case SigningProvider.WALLET_KERNEL: {
|
|
31
|
+
return this.signWithWalletKernel(authContext.userId, wallet, signParams);
|
|
32
|
+
}
|
|
33
|
+
case SigningProvider.BLOCKDAEMON: {
|
|
34
|
+
if (!authContext.email) {
|
|
35
|
+
throw new Error('Email is required for Blockdaemon wallet allocation');
|
|
36
|
+
}
|
|
37
|
+
return this.signWithBlockdaemon(authContext.email, wallet, signParams);
|
|
38
|
+
}
|
|
39
|
+
case SigningProvider.FIREBLOCKS: {
|
|
40
|
+
return this.signWithFireblocks(authContext.userId, wallet, signParams);
|
|
41
|
+
}
|
|
42
|
+
case SigningProvider.DFNS: {
|
|
43
|
+
return this.signWithDfns(authContext.userId, wallet, signParams);
|
|
44
|
+
}
|
|
45
|
+
default:
|
|
46
|
+
throw new Error(`Unsupported signing provider: ${wallet.signingProviderId}`);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
execute(userId, wallet, transaction, executeParams, ledgerClient, network) {
|
|
50
|
+
if (transaction.status === 'executed') {
|
|
51
|
+
throw new Error('Transaction is already executed.');
|
|
52
|
+
}
|
|
53
|
+
switch (wallet.signingProviderId) {
|
|
54
|
+
case SigningProvider.PARTICIPANT: {
|
|
55
|
+
try {
|
|
56
|
+
if (!executeParams) {
|
|
57
|
+
throw new Error('Execute params are required for participant signing');
|
|
58
|
+
}
|
|
59
|
+
if (!ledgerClient) {
|
|
60
|
+
throw new Error('Ledger client is required for participant signing');
|
|
61
|
+
}
|
|
62
|
+
if (!network) {
|
|
63
|
+
throw new Error('Network is required for participant signing');
|
|
64
|
+
}
|
|
65
|
+
return this.executeWithParticipant(userId, executeParams, transaction, ledgerClient, network);
|
|
66
|
+
}
|
|
67
|
+
catch (error) {
|
|
68
|
+
this.logger.error(error, 'Failed to submit transaction');
|
|
69
|
+
throw error;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
case SigningProvider.WALLET_KERNEL:
|
|
73
|
+
case SigningProvider.BLOCKDAEMON:
|
|
74
|
+
case SigningProvider.FIREBLOCKS: {
|
|
75
|
+
if (!executeParams) {
|
|
76
|
+
throw new Error('Execute params are required for external signing');
|
|
77
|
+
}
|
|
78
|
+
if (!ledgerClient) {
|
|
79
|
+
throw new Error('Ledger client is required for external signing');
|
|
80
|
+
}
|
|
81
|
+
return this.executeWithExternal(userId, executeParams, transaction, ledgerClient);
|
|
82
|
+
}
|
|
83
|
+
case SigningProvider.DFNS: {
|
|
84
|
+
return this.executeWithDfns(transaction);
|
|
85
|
+
}
|
|
86
|
+
default:
|
|
87
|
+
throw new Error(`Unsupported signing provider: ${wallet.signingProviderId}`);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
async signAndExecute(authContext, network, wallet, transaction) {
|
|
91
|
+
const signParams = {
|
|
92
|
+
transactionId: transaction.id,
|
|
93
|
+
partyId: wallet.partyId,
|
|
94
|
+
};
|
|
95
|
+
const signResult = await this.sign(authContext, wallet, signParams);
|
|
96
|
+
if (signResult.status === 'pending') {
|
|
97
|
+
return signResult;
|
|
98
|
+
}
|
|
99
|
+
if (signResult.status !== 'signed') {
|
|
100
|
+
throw new Error(`Service account signing failed with status: ${signResult.status}`);
|
|
101
|
+
}
|
|
102
|
+
if (!('signature' in signResult) ||
|
|
103
|
+
signResult.signature === undefined) {
|
|
104
|
+
throw new Error('Service account signing did not return a signature');
|
|
105
|
+
}
|
|
106
|
+
const ledgerClient = new LedgerClient({
|
|
107
|
+
baseUrl: new URL(network.ledgerApi.baseUrl),
|
|
108
|
+
logger: this.logger,
|
|
109
|
+
accessTokenProvider: AuthTokenProvider.fromToken(authContext.accessToken, this.logger),
|
|
110
|
+
});
|
|
111
|
+
const executeParams = {
|
|
112
|
+
transactionId: transaction.id,
|
|
113
|
+
partyId: wallet.partyId,
|
|
114
|
+
signature: signResult.signature,
|
|
115
|
+
signedBy: signResult.signedBy,
|
|
116
|
+
};
|
|
117
|
+
const userId = authContext.isApiKey
|
|
118
|
+
? authContext.ledgerUserId
|
|
119
|
+
: authContext.userId;
|
|
120
|
+
return this.execute(userId, wallet, transaction, executeParams, ledgerClient, network);
|
|
121
|
+
}
|
|
18
122
|
async loadPreparedTransactionForSigning(transactionId) {
|
|
19
123
|
const existingTx = await this.store.getTransaction(transactionId);
|
|
20
124
|
if (!existingTx) {
|
|
21
125
|
throw new Error(`Transaction not found with id: ${transactionId}`);
|
|
22
126
|
}
|
|
127
|
+
if (existingTx.status !== 'pending') {
|
|
128
|
+
throw new Error(`Cannot sign an already ${existingTx.status} transaction`);
|
|
129
|
+
}
|
|
23
130
|
return existingTx;
|
|
24
131
|
}
|
|
25
132
|
signWithParticipant(wallet) {
|
|
@@ -79,7 +186,7 @@ export class TransactionService {
|
|
|
79
186
|
const driver = signingProvider.controller(userId);
|
|
80
187
|
const tx = await this.loadPreparedTransactionForSigning(signParams.transactionId);
|
|
81
188
|
let signingResult;
|
|
82
|
-
if (tx
|
|
189
|
+
if (tx.externalTxId) {
|
|
83
190
|
signingResult = await driver
|
|
84
191
|
.getTransaction({
|
|
85
192
|
userId,
|
|
@@ -104,6 +211,10 @@ export class TransactionService {
|
|
|
104
211
|
.then(handleSigningError);
|
|
105
212
|
}
|
|
106
213
|
const now = new Date();
|
|
214
|
+
logDynamically(this.logger, 'Blockdaemon signing result', {
|
|
215
|
+
info: { transactionId: tx.id, status: signingResult.status },
|
|
216
|
+
debug: { signingResult, tx },
|
|
217
|
+
});
|
|
107
218
|
if (signingResult.status === 'signed') {
|
|
108
219
|
if (!signingResult.signature) {
|
|
109
220
|
throw new Error('No signature returned from signing driver');
|
|
@@ -164,7 +275,7 @@ export class TransactionService {
|
|
|
164
275
|
const driver = signingProvider.controller(userId);
|
|
165
276
|
const tx = await this.loadPreparedTransactionForSigning(signParams.transactionId);
|
|
166
277
|
let signingResult;
|
|
167
|
-
if (tx
|
|
278
|
+
if (tx.externalTxId) {
|
|
168
279
|
signingResult = await driver
|
|
169
280
|
.getTransaction({
|
|
170
281
|
userId,
|
|
@@ -185,6 +296,10 @@ export class TransactionService {
|
|
|
185
296
|
.then(handleSigningError);
|
|
186
297
|
}
|
|
187
298
|
const now = new Date();
|
|
299
|
+
logDynamically(this.logger, 'Fireblocks signing result', {
|
|
300
|
+
info: { transactionId: tx.id, status: signingResult.status },
|
|
301
|
+
debug: { signingResult, tx },
|
|
302
|
+
});
|
|
188
303
|
if (signingResult.status === 'signed') {
|
|
189
304
|
if (!signingResult.signature) {
|
|
190
305
|
throw new Error('No signature returned from signing driver');
|
|
@@ -273,6 +388,10 @@ export class TransactionService {
|
|
|
273
388
|
.then(handleSigningError);
|
|
274
389
|
}
|
|
275
390
|
const now = new Date();
|
|
391
|
+
logDynamically(this.logger, 'Dfns signing result', {
|
|
392
|
+
info: { transactionId: tx.id, status: signingResult.status },
|
|
393
|
+
debug: { signingResult, tx },
|
|
394
|
+
});
|
|
276
395
|
if (signingResult.status === 'signed') {
|
|
277
396
|
if (!signingResult.signature) {
|
|
278
397
|
throw new Error('No updateId returned from Dfns');
|
|
@@ -359,15 +478,19 @@ export class TransactionService {
|
|
|
359
478
|
const { partyId } = executeParams;
|
|
360
479
|
const { commandId } = transaction;
|
|
361
480
|
const synchronizerId = network.synchronizerId ?? (await ledgerClient.getSynchronizerId());
|
|
362
|
-
const prep = ledgerPrepareParams(userId, partyId, synchronizerId, transaction.payload);
|
|
363
|
-
const
|
|
481
|
+
const prep = ledgerPrepareParams(userId, [partyId], synchronizerId, transaction.payload);
|
|
482
|
+
const result = await ledgerClient.postWithRetry('/v2/commands/submit-and-wait', prep);
|
|
483
|
+
logDynamically(this.logger, 'Participant execution result', {
|
|
484
|
+
info: { transactionId: transaction.id },
|
|
485
|
+
debug: { result, transaction, executeParams, userId },
|
|
486
|
+
});
|
|
364
487
|
const executedTx = {
|
|
365
488
|
id: transaction.id,
|
|
366
489
|
commandId,
|
|
367
490
|
status: 'executed',
|
|
368
491
|
preparedTransaction: transaction.preparedTransaction,
|
|
369
492
|
preparedTransactionHash: transaction.preparedTransactionHash,
|
|
370
|
-
payload:
|
|
493
|
+
payload: result,
|
|
371
494
|
origin: transaction.origin ?? null,
|
|
372
495
|
...(transaction.createdAt && {
|
|
373
496
|
createdAt: transaction.createdAt,
|
|
@@ -377,10 +500,10 @@ export class TransactionService {
|
|
|
377
500
|
}),
|
|
378
501
|
};
|
|
379
502
|
await this.store.setTransactionStatus(transaction.id, 'executed', {
|
|
380
|
-
payload:
|
|
503
|
+
payload: result,
|
|
381
504
|
});
|
|
382
505
|
this.notifier.emit('txChanged', executedTx);
|
|
383
|
-
return
|
|
506
|
+
return result;
|
|
384
507
|
}
|
|
385
508
|
async executeWithExternal(userId, executeParams, transaction, ledgerClient) {
|
|
386
509
|
const { partyId, signature, signedBy } = executeParams;
|
|
@@ -409,6 +532,10 @@ export class TransactionService {
|
|
|
409
532
|
],
|
|
410
533
|
},
|
|
411
534
|
});
|
|
535
|
+
logDynamically(this.logger, 'Externally signed execution result', {
|
|
536
|
+
info: { transactionId: transaction.id },
|
|
537
|
+
debug: { result, transaction, executeParams, userId },
|
|
538
|
+
});
|
|
412
539
|
const executedTx = {
|
|
413
540
|
id: transaction.id,
|
|
414
541
|
commandId,
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"transaction-service.test.d.ts","sourceRoot":"","sources":["../../src/ledger/transaction-service.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,390 @@
|
|
|
1
|
+
// Copyright (c) 2025-2026 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved.
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
|
|
4
|
+
import { pino } from 'pino';
|
|
5
|
+
import { sink } from 'pino-test';
|
|
6
|
+
import { SigningProvider, } from '@canton-network/core-signing-lib';
|
|
7
|
+
import { TransactionService } from './transaction-service.js';
|
|
8
|
+
const authContext = {
|
|
9
|
+
userId: 'user-1',
|
|
10
|
+
accessToken: 'access-token-1',
|
|
11
|
+
};
|
|
12
|
+
const authContextWithEmail = {
|
|
13
|
+
...authContext,
|
|
14
|
+
email: 'user@example.com',
|
|
15
|
+
};
|
|
16
|
+
const wallet = {
|
|
17
|
+
primary: true,
|
|
18
|
+
partyId: 'party::namespace',
|
|
19
|
+
status: 'allocated',
|
|
20
|
+
hint: 'party',
|
|
21
|
+
signingProviderId: SigningProvider.WALLET_KERNEL,
|
|
22
|
+
publicKey: 'wallet-public-key',
|
|
23
|
+
namespace: 'namespace',
|
|
24
|
+
networkId: 'network1',
|
|
25
|
+
rights: [],
|
|
26
|
+
};
|
|
27
|
+
const pendingTransaction = {
|
|
28
|
+
id: 'tx-1',
|
|
29
|
+
commandId: 'cmd-1',
|
|
30
|
+
status: 'pending',
|
|
31
|
+
preparedTransaction: 'prepared-tx',
|
|
32
|
+
preparedTransactionHash: 'tx-hash',
|
|
33
|
+
origin: 'https://dapp.example',
|
|
34
|
+
createdAt: new Date('2026-01-01T00:00:00.000Z'),
|
|
35
|
+
};
|
|
36
|
+
const signParams = {
|
|
37
|
+
transactionId: pendingTransaction.id,
|
|
38
|
+
partyId: wallet.partyId,
|
|
39
|
+
};
|
|
40
|
+
const executeParams = {
|
|
41
|
+
transactionId: pendingTransaction.id,
|
|
42
|
+
partyId: wallet.partyId,
|
|
43
|
+
signature: 'signature',
|
|
44
|
+
signedBy: wallet.namespace,
|
|
45
|
+
};
|
|
46
|
+
const network = {
|
|
47
|
+
id: 'network1',
|
|
48
|
+
name: 'testnet',
|
|
49
|
+
synchronizerId: 'sync::fingerprint',
|
|
50
|
+
description: 'Test',
|
|
51
|
+
identityProviderId: 'idp1',
|
|
52
|
+
ledgerApi: { baseUrl: 'http://ledger.test' },
|
|
53
|
+
auth: {
|
|
54
|
+
method: 'authorization_code',
|
|
55
|
+
clientId: 'cid',
|
|
56
|
+
scope: 'scope',
|
|
57
|
+
audience: 'aud',
|
|
58
|
+
},
|
|
59
|
+
};
|
|
60
|
+
function walletWithProvider(signingProviderId) {
|
|
61
|
+
return { ...wallet, signingProviderId };
|
|
62
|
+
}
|
|
63
|
+
function createDriver(options) {
|
|
64
|
+
return {
|
|
65
|
+
controller: vi.fn().mockReturnValue({
|
|
66
|
+
signTransaction: options.signTransaction ??
|
|
67
|
+
vi.fn().mockResolvedValue({ signature: 'driver-signature' }),
|
|
68
|
+
getTransaction: options.getTransaction ?? vi.fn().mockResolvedValue({}),
|
|
69
|
+
}),
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
function createStore(transaction = pendingTransaction) {
|
|
73
|
+
return {
|
|
74
|
+
getTransaction: vi.fn().mockResolvedValue(transaction),
|
|
75
|
+
setTransactionSigned: vi.fn().mockResolvedValue(undefined),
|
|
76
|
+
setTransactionStatus: vi.fn().mockResolvedValue(undefined),
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
function createService(store, drivers, notifier, logger) {
|
|
80
|
+
return new TransactionService(store, logger, drivers, notifier);
|
|
81
|
+
}
|
|
82
|
+
describe('TransactionService', () => {
|
|
83
|
+
let logger;
|
|
84
|
+
let notifier;
|
|
85
|
+
let emit;
|
|
86
|
+
beforeEach(() => {
|
|
87
|
+
logger = pino({ level: 'silent' }, sink());
|
|
88
|
+
emit = vi.fn();
|
|
89
|
+
notifier = { emit };
|
|
90
|
+
});
|
|
91
|
+
afterEach(() => {
|
|
92
|
+
vi.clearAllMocks();
|
|
93
|
+
});
|
|
94
|
+
describe('sign', () => {
|
|
95
|
+
describe('participant', () => {
|
|
96
|
+
it('returns a signed result without calling external drivers', async () => {
|
|
97
|
+
const store = createStore();
|
|
98
|
+
const service = createService(store, {
|
|
99
|
+
[SigningProvider.PARTICIPANT]: createDriver({}),
|
|
100
|
+
}, notifier, logger);
|
|
101
|
+
const participantWallet = walletWithProvider(SigningProvider.PARTICIPANT);
|
|
102
|
+
const result = await service.sign(authContext, participantWallet, signParams);
|
|
103
|
+
expect(result).toEqual({
|
|
104
|
+
status: 'signed',
|
|
105
|
+
signature: 'none',
|
|
106
|
+
signedBy: wallet.namespace,
|
|
107
|
+
partyId: wallet.partyId,
|
|
108
|
+
});
|
|
109
|
+
expect(store.getTransaction).not.toHaveBeenCalled();
|
|
110
|
+
});
|
|
111
|
+
});
|
|
112
|
+
describe('wallet-kernel', () => {
|
|
113
|
+
it('signs the transaction and persists the signed state', async () => {
|
|
114
|
+
const signTransaction = vi
|
|
115
|
+
.fn()
|
|
116
|
+
.mockResolvedValue({ signature: 'kernel-signature' });
|
|
117
|
+
const store = createStore();
|
|
118
|
+
const service = createService(store, {
|
|
119
|
+
[SigningProvider.WALLET_KERNEL]: createDriver({
|
|
120
|
+
signTransaction,
|
|
121
|
+
}),
|
|
122
|
+
}, notifier, logger);
|
|
123
|
+
const result = await service.sign(authContext, wallet, signParams);
|
|
124
|
+
expect(signTransaction).toHaveBeenCalledWith({
|
|
125
|
+
tx: pendingTransaction.preparedTransaction,
|
|
126
|
+
txHash: pendingTransaction.preparedTransactionHash,
|
|
127
|
+
keyIdentifier: { publicKey: wallet.publicKey },
|
|
128
|
+
});
|
|
129
|
+
expect(store.setTransactionSigned).toHaveBeenCalledWith(pendingTransaction.id, expect.any(Date));
|
|
130
|
+
expect(emit).toHaveBeenCalledWith('txChanged', expect.objectContaining({
|
|
131
|
+
id: pendingTransaction.id,
|
|
132
|
+
status: 'signed',
|
|
133
|
+
}));
|
|
134
|
+
expect(result).toEqual({
|
|
135
|
+
status: 'signed',
|
|
136
|
+
signature: 'kernel-signature',
|
|
137
|
+
signedBy: wallet.namespace,
|
|
138
|
+
partyId: wallet.partyId,
|
|
139
|
+
});
|
|
140
|
+
});
|
|
141
|
+
it('throws when the wallet-kernel driver is missing', async () => {
|
|
142
|
+
const service = createService(createStore(), {}, notifier, logger);
|
|
143
|
+
await expect(service.sign(authContext, wallet, signParams)).rejects.toThrow('No driver found for wallet-kernel');
|
|
144
|
+
});
|
|
145
|
+
it('throws when the transaction does not exist', async () => {
|
|
146
|
+
const store = createStore();
|
|
147
|
+
store.getTransaction.mockResolvedValue(undefined);
|
|
148
|
+
const service = createService(store, {
|
|
149
|
+
[SigningProvider.WALLET_KERNEL]: createDriver({}),
|
|
150
|
+
}, notifier, logger);
|
|
151
|
+
await expect(service.sign(authContext, wallet, signParams)).rejects.toThrow('Transaction not found with id: tx-1');
|
|
152
|
+
});
|
|
153
|
+
it('throws when the driver returns an RPC error', async () => {
|
|
154
|
+
const signTransaction = vi.fn().mockResolvedValue({
|
|
155
|
+
error: 'access_denied',
|
|
156
|
+
error_description: 'Signing rejected',
|
|
157
|
+
});
|
|
158
|
+
const service = createService(createStore(), {
|
|
159
|
+
[SigningProvider.WALLET_KERNEL]: createDriver({
|
|
160
|
+
signTransaction,
|
|
161
|
+
}),
|
|
162
|
+
}, notifier, logger);
|
|
163
|
+
await expect(service.sign(authContext, wallet, signParams)).rejects.toThrow('Error from signing driver: Signing rejected');
|
|
164
|
+
});
|
|
165
|
+
});
|
|
166
|
+
describe('blockdaemon', () => {
|
|
167
|
+
const blockdaemonWallet = walletWithProvider(SigningProvider.BLOCKDAEMON);
|
|
168
|
+
it('throws when email is missing from auth context', async () => {
|
|
169
|
+
const service = createService(createStore(), {
|
|
170
|
+
[SigningProvider.BLOCKDAEMON]: createDriver({}),
|
|
171
|
+
}, notifier, logger);
|
|
172
|
+
await expect(service.sign(authContext, blockdaemonWallet, signParams)).rejects.toThrow('Email is required for Blockdaemon wallet allocation');
|
|
173
|
+
});
|
|
174
|
+
it('starts signing when there is no external transaction id yet', async () => {
|
|
175
|
+
const signTransaction = vi.fn().mockResolvedValue({
|
|
176
|
+
status: 'pending',
|
|
177
|
+
txId: 'external-tx-1',
|
|
178
|
+
});
|
|
179
|
+
const store = createStore();
|
|
180
|
+
const service = createService(store, {
|
|
181
|
+
[SigningProvider.BLOCKDAEMON]: createDriver({
|
|
182
|
+
signTransaction,
|
|
183
|
+
}),
|
|
184
|
+
}, notifier, logger);
|
|
185
|
+
const result = await service.sign(authContextWithEmail, blockdaemonWallet, signParams);
|
|
186
|
+
expect(signTransaction).toHaveBeenCalledWith(expect.objectContaining({
|
|
187
|
+
tx: pendingTransaction.preparedTransaction,
|
|
188
|
+
internalTxId: expect.any(String),
|
|
189
|
+
}));
|
|
190
|
+
expect(store.setTransactionStatus).toHaveBeenCalledWith(pendingTransaction.id, 'pending', { externalTxId: 'external-tx-1' });
|
|
191
|
+
expect(result).toEqual({
|
|
192
|
+
status: 'pending',
|
|
193
|
+
externalTxId: 'external-tx-1',
|
|
194
|
+
partyId: wallet.partyId,
|
|
195
|
+
});
|
|
196
|
+
});
|
|
197
|
+
it('fetches transaction when an external transaction id already exists', async () => {
|
|
198
|
+
const getTransaction = vi.fn().mockResolvedValue({
|
|
199
|
+
status: 'signed',
|
|
200
|
+
txId: 'external-tx-1',
|
|
201
|
+
signature: 'bd-signature',
|
|
202
|
+
});
|
|
203
|
+
const store = createStore({
|
|
204
|
+
...pendingTransaction,
|
|
205
|
+
externalTxId: 'external-tx-1',
|
|
206
|
+
});
|
|
207
|
+
const service = createService(store, {
|
|
208
|
+
[SigningProvider.BLOCKDAEMON]: createDriver({
|
|
209
|
+
getTransaction,
|
|
210
|
+
}),
|
|
211
|
+
}, notifier, logger);
|
|
212
|
+
const result = await service.sign(authContextWithEmail, blockdaemonWallet, signParams);
|
|
213
|
+
expect(getTransaction).toHaveBeenCalledWith({
|
|
214
|
+
userId: authContextWithEmail.email,
|
|
215
|
+
txId: 'external-tx-1',
|
|
216
|
+
});
|
|
217
|
+
expect(store.setTransactionSigned).toHaveBeenCalledWith(pendingTransaction.id, expect.any(Date), 'external-tx-1');
|
|
218
|
+
expect(result).toMatchObject({
|
|
219
|
+
status: 'signed',
|
|
220
|
+
signature: 'bd-signature',
|
|
221
|
+
externalTxId: 'external-tx-1',
|
|
222
|
+
});
|
|
223
|
+
});
|
|
224
|
+
});
|
|
225
|
+
describe('fireblocks', () => {
|
|
226
|
+
it('returns a base64 signature when signing completes', async () => {
|
|
227
|
+
const hexSignature = Buffer.from('fireblocks-signature').toString('hex');
|
|
228
|
+
const signTransaction = vi.fn().mockResolvedValue({
|
|
229
|
+
status: 'signed',
|
|
230
|
+
txId: 'fb-tx-1',
|
|
231
|
+
signature: hexSignature,
|
|
232
|
+
});
|
|
233
|
+
const store = createStore();
|
|
234
|
+
const service = createService(store, {
|
|
235
|
+
[SigningProvider.FIREBLOCKS]: createDriver({
|
|
236
|
+
signTransaction,
|
|
237
|
+
}),
|
|
238
|
+
}, notifier, logger);
|
|
239
|
+
const result = await service.sign(authContext, walletWithProvider(SigningProvider.FIREBLOCKS), signParams);
|
|
240
|
+
expect(signTransaction).toHaveBeenCalledWith(expect.objectContaining({
|
|
241
|
+
userId: authContext.userId,
|
|
242
|
+
txHash: Buffer.from(pendingTransaction.preparedTransactionHash, 'base64').toString('hex'),
|
|
243
|
+
}));
|
|
244
|
+
expect(result).toMatchObject({
|
|
245
|
+
status: 'signed',
|
|
246
|
+
signature: Buffer.from(hexSignature, 'hex').toString('base64'),
|
|
247
|
+
externalTxId: 'fb-tx-1',
|
|
248
|
+
});
|
|
249
|
+
});
|
|
250
|
+
});
|
|
251
|
+
describe('dfns', () => {
|
|
252
|
+
it('persists the update id as the signature when signing completes', async () => {
|
|
253
|
+
const signTransaction = vi.fn().mockResolvedValue({
|
|
254
|
+
status: 'signed',
|
|
255
|
+
txId: 'dfns-tx-1',
|
|
256
|
+
signature: 'update-id-123',
|
|
257
|
+
});
|
|
258
|
+
const store = createStore();
|
|
259
|
+
const service = createService(store, {
|
|
260
|
+
[SigningProvider.DFNS]: createDriver({
|
|
261
|
+
signTransaction,
|
|
262
|
+
}),
|
|
263
|
+
}, notifier, logger);
|
|
264
|
+
const result = await service.sign(authContext, walletWithProvider(SigningProvider.DFNS), signParams);
|
|
265
|
+
expect(result).toEqual({
|
|
266
|
+
status: 'signed',
|
|
267
|
+
signature: 'update-id-123',
|
|
268
|
+
signedBy: wallet.namespace,
|
|
269
|
+
partyId: wallet.partyId,
|
|
270
|
+
externalTxId: 'dfns-tx-1',
|
|
271
|
+
});
|
|
272
|
+
});
|
|
273
|
+
});
|
|
274
|
+
});
|
|
275
|
+
describe('execute', () => {
|
|
276
|
+
describe('dfns', () => {
|
|
277
|
+
it('marks the transaction executed using the external tx id', async () => {
|
|
278
|
+
const signedTransaction = {
|
|
279
|
+
...pendingTransaction,
|
|
280
|
+
status: 'signed',
|
|
281
|
+
externalTxId: 'dfns-update-id',
|
|
282
|
+
};
|
|
283
|
+
const store = createStore(signedTransaction);
|
|
284
|
+
const service = createService(store, {}, notifier, logger);
|
|
285
|
+
const result = await service.execute(authContext.userId, walletWithProvider(SigningProvider.DFNS), signedTransaction);
|
|
286
|
+
expect(store.setTransactionStatus).toHaveBeenCalledWith(signedTransaction.id, 'executed', { externalTxId: 'dfns-update-id' });
|
|
287
|
+
expect(emit).toHaveBeenCalledWith('txChanged', expect.objectContaining({ status: 'executed' }));
|
|
288
|
+
expect(result).toEqual({ updateId: 'dfns-update-id' });
|
|
289
|
+
});
|
|
290
|
+
it('throws when the transaction has no external tx id', async () => {
|
|
291
|
+
const service = createService(createStore(), {}, notifier, logger);
|
|
292
|
+
await expect(service.execute(authContext.userId, walletWithProvider(SigningProvider.DFNS), pendingTransaction)).rejects.toThrow('Cannot execute Dfns transaction without externalTxId from Dfns');
|
|
293
|
+
});
|
|
294
|
+
});
|
|
295
|
+
describe('participant', () => {
|
|
296
|
+
it('submits the prepared transaction to the ledger', async () => {
|
|
297
|
+
const participantWallet = walletWithProvider(SigningProvider.PARTICIPANT);
|
|
298
|
+
const transaction = {
|
|
299
|
+
...pendingTransaction,
|
|
300
|
+
payload: {
|
|
301
|
+
commandId: pendingTransaction.commandId,
|
|
302
|
+
commands: [],
|
|
303
|
+
},
|
|
304
|
+
};
|
|
305
|
+
const store = createStore(transaction);
|
|
306
|
+
const postWithRetry = vi
|
|
307
|
+
.fn()
|
|
308
|
+
.mockResolvedValue({ updateId: 'ledger-update-1' });
|
|
309
|
+
const ledgerClient = {
|
|
310
|
+
postWithRetry,
|
|
311
|
+
getSynchronizerId: vi.fn(),
|
|
312
|
+
};
|
|
313
|
+
const service = createService(store, {}, notifier, logger);
|
|
314
|
+
const result = await service.execute(authContext.userId, participantWallet, transaction, executeParams, ledgerClient, network);
|
|
315
|
+
expect(postWithRetry).toHaveBeenCalledWith('/v2/commands/submit-and-wait', expect.objectContaining({
|
|
316
|
+
commandId: pendingTransaction.commandId,
|
|
317
|
+
userId: authContext.userId,
|
|
318
|
+
synchronizerId: network.synchronizerId,
|
|
319
|
+
}));
|
|
320
|
+
expect(store.setTransactionStatus).toHaveBeenCalledWith(pendingTransaction.id, 'executed', { payload: { updateId: 'ledger-update-1' } });
|
|
321
|
+
expect(result).toEqual({ updateId: 'ledger-update-1' });
|
|
322
|
+
});
|
|
323
|
+
});
|
|
324
|
+
describe('external signing providers', () => {
|
|
325
|
+
it('executes the prepared transaction with the provided signature', async () => {
|
|
326
|
+
const signedTransaction = {
|
|
327
|
+
...pendingTransaction,
|
|
328
|
+
status: 'signed',
|
|
329
|
+
};
|
|
330
|
+
const store = createStore(signedTransaction);
|
|
331
|
+
const postWithRetry = vi
|
|
332
|
+
.fn()
|
|
333
|
+
.mockResolvedValue({ updateId: 'external-update-1' });
|
|
334
|
+
const ledgerClient = {
|
|
335
|
+
postWithRetry,
|
|
336
|
+
};
|
|
337
|
+
const service = createService(store, {}, notifier, logger);
|
|
338
|
+
const result = await service.execute(authContext.userId, wallet, signedTransaction, executeParams, ledgerClient, network);
|
|
339
|
+
expect(postWithRetry).toHaveBeenCalledWith('/v2/interactive-submission/executeAndWait', expect.objectContaining({
|
|
340
|
+
userId: authContext.userId,
|
|
341
|
+
preparedTransaction: pendingTransaction.preparedTransaction,
|
|
342
|
+
submissionId: pendingTransaction.commandId,
|
|
343
|
+
partySignatures: expect.objectContaining({
|
|
344
|
+
signatures: [
|
|
345
|
+
expect.objectContaining({
|
|
346
|
+
party: wallet.partyId,
|
|
347
|
+
}),
|
|
348
|
+
],
|
|
349
|
+
}),
|
|
350
|
+
}));
|
|
351
|
+
expect(store.setTransactionStatus).toHaveBeenCalledWith(pendingTransaction.id, 'executed', { payload: { updateId: 'external-update-1' } });
|
|
352
|
+
expect(result).toEqual({ updateId: 'external-update-1' });
|
|
353
|
+
});
|
|
354
|
+
});
|
|
355
|
+
});
|
|
356
|
+
describe('signAndExecute', () => {
|
|
357
|
+
const participantWallet = walletWithProvider(SigningProvider.PARTICIPANT);
|
|
358
|
+
it('signs and executes when signing completes synchronously', async () => {
|
|
359
|
+
const service = createService(createStore(), {}, notifier, logger);
|
|
360
|
+
const executeSpy = vi
|
|
361
|
+
.spyOn(service, 'execute')
|
|
362
|
+
.mockResolvedValue({ commandId: 'cmd-1' });
|
|
363
|
+
vi.spyOn(service, 'sign').mockResolvedValue({
|
|
364
|
+
status: 'signed',
|
|
365
|
+
signature: 'sig',
|
|
366
|
+
signedBy: 'namespace',
|
|
367
|
+
partyId: participantWallet.partyId,
|
|
368
|
+
});
|
|
369
|
+
const result = await service.signAndExecute(authContext, network, participantWallet, pendingTransaction);
|
|
370
|
+
expect(result).toEqual({ commandId: 'cmd-1' });
|
|
371
|
+
expect(executeSpy).toHaveBeenCalled();
|
|
372
|
+
});
|
|
373
|
+
it('returns pending sign result without executing', async () => {
|
|
374
|
+
const service = createService(createStore(), {}, notifier, logger);
|
|
375
|
+
const executeSpy = vi.spyOn(service, 'execute');
|
|
376
|
+
vi.spyOn(service, 'sign').mockResolvedValue({
|
|
377
|
+
status: 'pending',
|
|
378
|
+
externalTxId: 'ext-1',
|
|
379
|
+
partyId: participantWallet.partyId,
|
|
380
|
+
});
|
|
381
|
+
const result = await service.signAndExecute(authContext, network, participantWallet, pendingTransaction);
|
|
382
|
+
expect(result).toEqual({
|
|
383
|
+
status: 'pending',
|
|
384
|
+
externalTxId: 'ext-1',
|
|
385
|
+
partyId: participantWallet.partyId,
|
|
386
|
+
});
|
|
387
|
+
expect(executeSpy).not.toHaveBeenCalled();
|
|
388
|
+
});
|
|
389
|
+
});
|
|
390
|
+
});
|
|
@@ -3,7 +3,7 @@ import { Store, Wallet } from '@canton-network/core-wallet-store';
|
|
|
3
3
|
import { SigningDriverInterface } from '@canton-network/core-signing-lib';
|
|
4
4
|
import { Logger } from 'pino';
|
|
5
5
|
import { PartyAllocationService } from '../../party-allocation-service.js';
|
|
6
|
-
import { PartyHint, Primary } from '../../../user-api/rpc-gen/typings.js';
|
|
6
|
+
import { PartyHint, Primary, VaultName } from '../../../user-api/rpc-gen/typings.js';
|
|
7
7
|
import type { WalletAllocator } from '../wallet-allocation-service.js';
|
|
8
8
|
export declare class FireblocksWalletAllocator implements WalletAllocator {
|
|
9
9
|
private store;
|
|
@@ -11,7 +11,10 @@ export declare class FireblocksWalletAllocator implements WalletAllocator {
|
|
|
11
11
|
private partyAllocator;
|
|
12
12
|
private signingDriver;
|
|
13
13
|
constructor(store: Store, logger: Logger, partyAllocator: PartyAllocationService, signingDriver: SigningDriverInterface);
|
|
14
|
-
createWallet(userId: UserId, email: string | undefined, partyHint: PartyHint, primary
|
|
14
|
+
createWallet(userId: UserId, email: string | undefined, partyHint: PartyHint, primary: Primary | undefined, vaultName: VaultName): Promise<Wallet>;
|
|
15
15
|
allocateParty(userId: UserId, email: string | undefined, existingWallet: Wallet): Promise<void>;
|
|
16
|
+
getVaults(userId: UserId): Promise<{
|
|
17
|
+
vaults: string[];
|
|
18
|
+
}>;
|
|
16
19
|
}
|
|
17
20
|
//# sourceMappingURL=fireblocks-wallet-allocator.d.ts.map
|
package/dist/ledger/wallet-allocation/signing-providers/fireblocks-wallet-allocator.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fireblocks-wallet-allocator.d.ts","sourceRoot":"","sources":["../../../../src/ledger/wallet-allocation/signing-providers/fireblocks-wallet-allocator.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,MAAM,EAAE,MAAM,kCAAkC,CAAA;AACzD,OAAO,EAAE,KAAK,EAAgB,MAAM,EAAE,MAAM,mCAAmC,CAAA;AAC/E,OAAO,EAEH,sBAAsB,EAEzB,MAAM,kCAAkC,CAAA;AACzC,OAAO,EAAE,MAAM,EAAE,MAAM,MAAM,CAAA;AAC7B,OAAO,EAAE,sBAAsB,EAAE,MAAM,mCAAmC,CAAA;AAC1E,OAAO,
|
|
1
|
+
{"version":3,"file":"fireblocks-wallet-allocator.d.ts","sourceRoot":"","sources":["../../../../src/ledger/wallet-allocation/signing-providers/fireblocks-wallet-allocator.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,MAAM,EAAE,MAAM,kCAAkC,CAAA;AACzD,OAAO,EAAE,KAAK,EAAgB,MAAM,EAAE,MAAM,mCAAmC,CAAA;AAC/E,OAAO,EAEH,sBAAsB,EAEzB,MAAM,kCAAkC,CAAA;AACzC,OAAO,EAAE,MAAM,EAAE,MAAM,MAAM,CAAA;AAC7B,OAAO,EAAE,sBAAsB,EAAE,MAAM,mCAAmC,CAAA;AAC1E,OAAO,EACH,SAAS,EACT,OAAO,EACP,SAAS,EACZ,MAAM,sCAAsC,CAAA;AAC7C,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,iCAAiC,CAAA;AAYtE,qBAAa,yBAA0B,YAAW,eAAe;IAEzD,OAAO,CAAC,KAAK;IACb,OAAO,CAAC,MAAM;IACd,OAAO,CAAC,cAAc;IACtB,OAAO,CAAC,aAAa;gBAHb,KAAK,EAAE,KAAK,EACZ,MAAM,EAAE,MAAM,EACd,cAAc,EAAE,sBAAsB,EACtC,aAAa,EAAE,sBAAsB;IAG3C,YAAY,CACd,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,MAAM,GAAG,SAAS,EACzB,SAAS,EAAE,SAAS,EACpB,OAAO,EAAE,OAAO,YAAQ,EACxB,SAAS,EAAE,SAAS,GACrB,OAAO,CAAC,MAAM,CAAC;IA6FZ,aAAa,CACf,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,MAAM,GAAG,SAAS,EACzB,cAAc,EAAE,MAAM,GACvB,OAAO,CAAC,IAAI,CAAC;IAgEV,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,MAAM,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC;CAKjE"}
|