@canton-network/wallet-gateway-remote 1.4.0 → 1.5.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 +60 -4
- package/dist/config/Config.d.ts.map +1 -1
- package/dist/config/Config.js +1 -0
- package/dist/config/ConfigUtils.d.ts.map +1 -1
- package/dist/config/ConfigUtils.js +3 -0
- package/dist/dapp-api/controller.d.ts.map +1 -1
- package/dist/dapp-api/controller.js +54 -24
- 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 +3 -6
- package/dist/ledger/transaction-service.d.ts +14 -11
- package/dist/ledger/transaction-service.d.ts.map +1 -1
- package/dist/ledger/transaction-service.js +95 -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 +356 -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 +88 -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/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/user-api/controller.d.ts +6 -4
- package/dist/user-api/controller.d.ts.map +1 -1
- package/dist/user-api/controller.js +111 -94
- 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-MVLWUPwN.js +5 -0
- package/dist/web/frontend/assets/{activities-NY8oZAkH.js → activities-DaWkmGqA.js} +2 -2
- package/dist/web/frontend/assets/{addIdentityProvider-38ghz3RT.js → addIdentityProvider--rBb0ihb.js} +2 -2
- package/dist/web/frontend/assets/{addNetwork-BaDhbrZl.js → addNetwork-C6UDsRkU.js} +4 -4
- package/dist/web/frontend/assets/addParty-B3fFD1eM.js +45 -0
- package/dist/web/frontend/assets/approve-WbGL4E82.js +21 -0
- package/dist/web/frontend/assets/callback--tihEryB.js +1 -0
- package/dist/web/frontend/assets/{identityProviders-BZ9h_VOJ.js → identityProviders-Dra4qG6t.js} +2 -2
- package/dist/web/frontend/assets/{index-B-HiKugW.js → index-Bm76pXA_.js} +2 -2
- package/dist/web/frontend/assets/index-D1dC4Cl9.js +4477 -0
- package/dist/web/frontend/assets/{login-CqwMEG9J.js → login-BC8a-kD_.js} +2 -2
- package/dist/web/frontend/assets/{networks-BJvRi47M.js → networks-B3ztsogL.js} +2 -2
- package/dist/web/frontend/assets/{reviewIdentityProvider-ySlQnw5R.js → reviewIdentityProvider-Co420Dbk.js} +3 -3
- package/dist/web/frontend/assets/{reviewNetwork-DrVxeHd4.js → reviewNetwork-B-Sh8pCH.js} +3 -3
- package/dist/web/frontend/assets/{settings-BVNkaUyJ.js → settings-DvyUjqLl.js} +1 -1
- package/dist/web/frontend/assets/{state-qAsNw5qf.js → state-Bq65GwdF.js} +1 -1
- package/dist/web/frontend/assets/{utils-BDkHxi8V.js → utils-B2iziW8V.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/404-C7V2yl2z.js +0 -5
- 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
|
@@ -0,0 +1,356 @@
|
|
|
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
|
+
});
|
|
@@ -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"}
|
|
@@ -15,10 +15,10 @@ export class FireblocksWalletAllocator {
|
|
|
15
15
|
this.partyAllocator = partyAllocator;
|
|
16
16
|
this.signingDriver = signingDriver;
|
|
17
17
|
}
|
|
18
|
-
async createWallet(userId, email, partyHint, primary = false) {
|
|
18
|
+
async createWallet(userId, email, partyHint, primary = false, vaultName) {
|
|
19
19
|
const driver = this.signingDriver.controller(userId);
|
|
20
20
|
const keys = await driver.getKeys().then(handleSigningError);
|
|
21
|
-
const key = keys?.keys?.find((k) => k.name ===
|
|
21
|
+
const key = keys?.keys?.find((k) => k.name === vaultName);
|
|
22
22
|
if (!key)
|
|
23
23
|
throw new Error('Fireblocks key not found');
|
|
24
24
|
const formattedPublicKey = Buffer.from(key.publicKey, 'hex').toString('base64');
|
|
@@ -92,10 +92,6 @@ export class FireblocksWalletAllocator {
|
|
|
92
92
|
throw new Error('Existing wallet is missing field externalTxId or topologyTransactions');
|
|
93
93
|
}
|
|
94
94
|
const driver = this.signingDriver.controller(userId);
|
|
95
|
-
const keys = await driver.getKeys().then(handleSigningError);
|
|
96
|
-
const key = keys?.keys?.find((k) => k.name === 'Canton Party');
|
|
97
|
-
if (!key)
|
|
98
|
-
throw new Error('Fireblocks key not found');
|
|
99
95
|
const { signature, status } = await driver
|
|
100
96
|
.getTransaction({
|
|
101
97
|
userId,
|
|
@@ -138,4 +134,9 @@ export class FireblocksWalletAllocator {
|
|
|
138
134
|
}
|
|
139
135
|
return this.store.updateWallet(walletUpdate);
|
|
140
136
|
}
|
|
137
|
+
async getVaults(userId) {
|
|
138
|
+
const driver = this.signingDriver.controller(userId);
|
|
139
|
+
const keys = await driver.getKeys().then(handleSigningError);
|
|
140
|
+
return { vaults: keys?.keys?.map((key) => key.name) ?? [] };
|
|
141
|
+
}
|
|
141
142
|
}
|
|
@@ -1,12 +1,15 @@
|
|
|
1
|
-
import { UserId } from '@canton-network/core-wallet-auth';
|
|
1
|
+
import { AuthContext, UserId } from '@canton-network/core-wallet-auth';
|
|
2
2
|
import { Store, Wallet } from '@canton-network/core-wallet-store';
|
|
3
3
|
import { SigningDriverInterface, SigningProvider } 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
|
export interface WalletAllocator {
|
|
8
|
-
createWallet(userId: UserId, email: string | undefined, partyHint: PartyHint, primary: Primary): Promise<Wallet>;
|
|
8
|
+
createWallet(userId: UserId, email: string | undefined, partyHint: PartyHint, primary: Primary, vaultName?: VaultName | undefined): Promise<Wallet>;
|
|
9
9
|
allocateParty(userId: UserId, email: string | undefined, existingWallet: Wallet): Promise<void>;
|
|
10
|
+
getVaults?(userId: UserId): Promise<{
|
|
11
|
+
vaults: string[];
|
|
12
|
+
}>;
|
|
10
13
|
}
|
|
11
14
|
export declare class WalletAllocationService {
|
|
12
15
|
private readonly participantAllocator;
|
|
@@ -15,7 +18,10 @@ export declare class WalletAllocationService {
|
|
|
15
18
|
private readonly blockdaemonAllocator?;
|
|
16
19
|
private readonly dfnsAllocator?;
|
|
17
20
|
constructor(store: Store, logger: Logger, partyAllocator: PartyAllocationService, signingDrivers?: Partial<Record<SigningProvider, SigningDriverInterface>>);
|
|
18
|
-
createWallet(
|
|
19
|
-
allocateParty(
|
|
21
|
+
createWallet(authContext: AuthContext, partyHint: PartyHint, primary: Primary, signingProviderId: SigningProvider, vaultName?: VaultName | undefined): Promise<Wallet>;
|
|
22
|
+
allocateParty(authContext: AuthContext, existingWallet: Wallet, signingProviderId: SigningProvider): Promise<void>;
|
|
23
|
+
getVaults(authContext: AuthContext, signingProviderId: SigningProvider): Promise<{
|
|
24
|
+
vaults: string[];
|
|
25
|
+
}>;
|
|
20
26
|
}
|
|
21
27
|
//# sourceMappingURL=wallet-allocation-service.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"wallet-allocation-service.d.ts","sourceRoot":"","sources":["../../../src/ledger/wallet-allocation/wallet-allocation-service.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,MAAM,EAAE,MAAM,kCAAkC,CAAA;
|
|
1
|
+
{"version":3,"file":"wallet-allocation-service.d.ts","sourceRoot":"","sources":["../../../src/ledger/wallet-allocation/wallet-allocation-service.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,kCAAkC,CAAA;AACtE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,mCAAmC,CAAA;AACjE,OAAO,EACH,sBAAsB,EACtB,eAAe,EAClB,MAAM,kCAAkC,CAAA;AACzC,OAAO,EAAE,MAAM,EAAE,MAAM,MAAM,CAAA;AAC7B,OAAO,EAAE,sBAAsB,EAAE,MAAM,gCAAgC,CAAA;AACvE,OAAO,EACH,SAAS,EACT,OAAO,EACP,SAAS,EACZ,MAAM,mCAAmC,CAAA;AAO1C,MAAM,WAAW,eAAe;IAC5B,YAAY,CACR,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,MAAM,GAAG,SAAS,EACzB,SAAS,EAAE,SAAS,EACpB,OAAO,EAAE,OAAO,EAChB,SAAS,CAAC,EAAE,SAAS,GAAG,SAAS,GAClC,OAAO,CAAC,MAAM,CAAC,CAAA;IAClB,aAAa,CACT,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,MAAM,GAAG,SAAS,EACzB,cAAc,EAAE,MAAM,GACvB,OAAO,CAAC,IAAI,CAAC,CAAA;IAChB,SAAS,CAAC,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,MAAM,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC,CAAA;CAC5D;AAED,qBAAa,uBAAuB;IAChC,OAAO,CAAC,QAAQ,CAAC,oBAAoB,CAA4B;IACjE,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAC,CAAuB;IACxD,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAAC,CAA2B;IAChE,OAAO,CAAC,QAAQ,CAAC,oBAAoB,CAAC,CAA4B;IAClE,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAqB;gBAGhD,KAAK,EAAE,KAAK,EACZ,MAAM,EAAE,MAAM,EACd,cAAc,EAAE,sBAAsB,EACtC,cAAc,GAAE,OAAO,CACnB,MAAM,CAAC,eAAe,EAAE,sBAAsB,CAAC,CAC7C;IAiDG,YAAY,CACrB,WAAW,EAAE,WAAW,EACxB,SAAS,EAAE,SAAS,EACpB,OAAO,EAAE,OAAO,EAChB,iBAAiB,EAAE,eAAe,EAClC,SAAS,CAAC,EAAE,SAAS,GAAG,SAAS,GAClC,OAAO,CAAC,MAAM,CAAC;IAqEL,aAAa,CACtB,WAAW,EAAE,WAAW,EACxB,cAAc,EAAE,MAAM,EACtB,iBAAiB,EAAE,eAAe,GACnC,OAAO,CAAC,IAAI,CAAC;IA0DH,SAAS,CAClB,WAAW,EAAE,WAAW,EACxB,iBAAiB,EAAE,eAAe,GACnC,OAAO,CAAC;QAAE,MAAM,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC;CAanC"}
|
|
@@ -26,66 +26,80 @@ export class WalletAllocationService {
|
|
|
26
26
|
this.dfnsAllocator = new DfnsWalletAllocator(store, logger, partyAllocator, dfnsDriver);
|
|
27
27
|
}
|
|
28
28
|
}
|
|
29
|
-
async createWallet(
|
|
29
|
+
async createWallet(authContext, partyHint, primary, signingProviderId, vaultName) {
|
|
30
30
|
switch (signingProviderId) {
|
|
31
31
|
case SigningProvider.PARTICIPANT:
|
|
32
|
-
return this.participantAllocator.createWallet(userId, email, partyHint, primary);
|
|
32
|
+
return this.participantAllocator.createWallet(authContext.userId, authContext.email, partyHint, primary);
|
|
33
33
|
case SigningProvider.WALLET_KERNEL:
|
|
34
34
|
if (!this.kernelAllocator) {
|
|
35
35
|
throw new Error('Wallet Gateway signing driver not available');
|
|
36
36
|
}
|
|
37
|
-
return this.kernelAllocator.createWallet(userId, email, partyHint, primary);
|
|
37
|
+
return this.kernelAllocator.createWallet(authContext.userId, authContext.email, partyHint, primary);
|
|
38
38
|
case SigningProvider.FIREBLOCKS:
|
|
39
39
|
if (!this.fireblocksAllocator) {
|
|
40
40
|
throw new Error('Fireblocks signing driver not available');
|
|
41
41
|
}
|
|
42
|
-
|
|
42
|
+
if (!vaultName) {
|
|
43
|
+
throw new Error('vaultName is required for creating a wallet with Fireblocks');
|
|
44
|
+
}
|
|
45
|
+
return this.fireblocksAllocator.createWallet(authContext.userId, authContext.email, partyHint, primary, vaultName);
|
|
43
46
|
case SigningProvider.BLOCKDAEMON:
|
|
44
47
|
if (!this.blockdaemonAllocator) {
|
|
45
48
|
throw new Error('Blockdaemon signing driver not available');
|
|
46
49
|
}
|
|
47
|
-
if (!email) {
|
|
50
|
+
if (!authContext.email) {
|
|
48
51
|
throw new Error('Email is required for Blockdaemon wallet allocation');
|
|
49
52
|
}
|
|
50
|
-
return this.blockdaemonAllocator.createWallet(userId, email, partyHint, primary);
|
|
53
|
+
return this.blockdaemonAllocator.createWallet(authContext.userId, authContext.email, partyHint, primary);
|
|
51
54
|
case SigningProvider.DFNS:
|
|
52
55
|
if (!this.dfnsAllocator) {
|
|
53
56
|
throw new Error('Dfns signing driver not available');
|
|
54
57
|
}
|
|
55
|
-
return this.dfnsAllocator.createWallet(userId, email, partyHint, primary);
|
|
58
|
+
return this.dfnsAllocator.createWallet(authContext.userId, authContext.email, partyHint, primary);
|
|
56
59
|
default:
|
|
57
60
|
throw new Error(`Unsupported signing provider: ${signingProviderId}`);
|
|
58
61
|
}
|
|
59
62
|
}
|
|
60
|
-
async allocateParty(
|
|
63
|
+
async allocateParty(authContext, existingWallet, signingProviderId) {
|
|
61
64
|
switch (signingProviderId) {
|
|
62
65
|
case SigningProvider.PARTICIPANT:
|
|
63
|
-
return this.participantAllocator.allocateParty(userId, email, existingWallet);
|
|
66
|
+
return this.participantAllocator.allocateParty(authContext.userId, authContext.email, existingWallet);
|
|
64
67
|
case SigningProvider.WALLET_KERNEL:
|
|
65
68
|
if (!this.kernelAllocator) {
|
|
66
69
|
throw new Error('Wallet Gateway signing driver not available');
|
|
67
70
|
}
|
|
68
|
-
return this.kernelAllocator.allocateParty(userId, email, existingWallet);
|
|
71
|
+
return this.kernelAllocator.allocateParty(authContext.userId, authContext.email, existingWallet);
|
|
69
72
|
case SigningProvider.FIREBLOCKS:
|
|
70
73
|
if (!this.fireblocksAllocator) {
|
|
71
74
|
throw new Error('Fireblocks signing driver not available');
|
|
72
75
|
}
|
|
73
|
-
return this.fireblocksAllocator.allocateParty(userId, email, existingWallet);
|
|
76
|
+
return this.fireblocksAllocator.allocateParty(authContext.userId, authContext.email, existingWallet);
|
|
74
77
|
case SigningProvider.BLOCKDAEMON:
|
|
75
78
|
if (!this.blockdaemonAllocator) {
|
|
76
79
|
throw new Error('Blockdaemon signing driver not available');
|
|
77
80
|
}
|
|
78
|
-
if (!email) {
|
|
81
|
+
if (!authContext.email) {
|
|
79
82
|
throw new Error('Email is required for Blockdaemon wallet allocation');
|
|
80
83
|
}
|
|
81
|
-
return this.blockdaemonAllocator.allocateParty(userId, email, existingWallet);
|
|
84
|
+
return this.blockdaemonAllocator.allocateParty(authContext.userId, authContext.email, existingWallet);
|
|
82
85
|
case SigningProvider.DFNS:
|
|
83
86
|
if (!this.dfnsAllocator) {
|
|
84
87
|
throw new Error('Dfns signing driver not available');
|
|
85
88
|
}
|
|
86
|
-
return this.dfnsAllocator.allocateParty(userId, email, existingWallet);
|
|
89
|
+
return this.dfnsAllocator.allocateParty(authContext.userId, authContext.email, existingWallet);
|
|
87
90
|
default:
|
|
88
91
|
throw new Error(`Unsupported signing provider: ${signingProviderId}`);
|
|
89
92
|
}
|
|
90
93
|
}
|
|
94
|
+
async getVaults(authContext, signingProviderId) {
|
|
95
|
+
switch (signingProviderId) {
|
|
96
|
+
case SigningProvider.FIREBLOCKS:
|
|
97
|
+
if (!this.fireblocksAllocator) {
|
|
98
|
+
throw new Error('Fireblocks signing driver not available');
|
|
99
|
+
}
|
|
100
|
+
return this.fireblocksAllocator.getVaults(authContext.userId);
|
|
101
|
+
default:
|
|
102
|
+
throw new Error(`Signing provider ${signingProviderId} does not support listing vaults`);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
91
105
|
}
|