@dynamic-labs-wallet/core 0.0.41 → 0.0.43
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/index.cjs.js +197 -30
- package/index.esm.js +197 -30
- package/package.json +1 -1
- package/src/api/api.d.ts +23 -16
- package/src/api/api.d.ts.map +1 -1
- package/src/eventStream/utils.d.ts +48 -0
- package/src/eventStream/utils.d.ts.map +1 -0
- package/src/types.d.ts +18 -0
- package/src/types.d.ts.map +1 -1
package/index.cjs.js
CHANGED
|
@@ -268,39 +268,200 @@ class BaseClient {
|
|
|
268
268
|
}
|
|
269
269
|
}
|
|
270
270
|
|
|
271
|
+
/**
|
|
272
|
+
* Creates a promise that resolves when a specific event is received from an event stream.
|
|
273
|
+
* Adds a timeout to prevent hanging and races the two promises.
|
|
274
|
+
*
|
|
275
|
+
* @template T The expected type of the response data
|
|
276
|
+
* @param apiClient The axios instance to use for API calls
|
|
277
|
+
* @param options The configuration options
|
|
278
|
+
* @returns A promise that resolves with the event data or rejects on timeout
|
|
279
|
+
*/ const createEventStreamPromise = ({ apiClient, endpoint, body, successEventType, timeoutMs = 30000, timeoutMessage, onError })=>{
|
|
280
|
+
// Create a promise that will resolve when the success event is received
|
|
281
|
+
const eventPromise = new Promise((resolve, reject)=>{
|
|
282
|
+
apiClient.post(endpoint, body, {
|
|
283
|
+
responseType: 'stream',
|
|
284
|
+
headers: {
|
|
285
|
+
Accept: 'text/event-stream',
|
|
286
|
+
'Cache-Control': 'no-cache',
|
|
287
|
+
Connection: 'keep-alive'
|
|
288
|
+
},
|
|
289
|
+
adapter: 'fetch'
|
|
290
|
+
}).then(createSuccessErrorEventStreamHandler({
|
|
291
|
+
onError,
|
|
292
|
+
reject,
|
|
293
|
+
resolve,
|
|
294
|
+
successEventType
|
|
295
|
+
})).catch(reject);
|
|
296
|
+
});
|
|
297
|
+
// Add a timeout to prevent hanging
|
|
298
|
+
const timeoutPromise = new Promise((_, reject)=>{
|
|
299
|
+
setTimeout(()=>reject(new Error(timeoutMessage)), timeoutMs);
|
|
300
|
+
});
|
|
301
|
+
// Return the event data as soon as it's available
|
|
302
|
+
return Promise.race([
|
|
303
|
+
eventPromise,
|
|
304
|
+
timeoutPromise
|
|
305
|
+
]);
|
|
306
|
+
};
|
|
307
|
+
/**
|
|
308
|
+
* Creates a handler function for processing server-sent events (SSE) streams.
|
|
309
|
+
* This utility manages asynchronous event-based communication with the server,
|
|
310
|
+
* particularly for long-running operations like wallet creation or key generation.
|
|
311
|
+
*
|
|
312
|
+
* @template T - The expected type of the successful response data
|
|
313
|
+
* @param {function} resolve - Promise resolution function to call when the success event is received
|
|
314
|
+
* @param {function} reject - Promise rejection function to call when an error occurs
|
|
315
|
+
* @param {string} successEventType - The event type string that indicates a successful operation
|
|
316
|
+
* @param {function} [onError] - Optional callback for error handling, allowing custom error processing
|
|
317
|
+
* @returns {function} A response handler function that processes the event stream
|
|
318
|
+
*/ const createSuccessErrorEventStreamHandler = ({ resolve, reject, successEventType, onError })=>{
|
|
319
|
+
return (response)=>{
|
|
320
|
+
const reader = response.data.getReader();
|
|
321
|
+
const decoder = new TextDecoder();
|
|
322
|
+
let buffer = '';
|
|
323
|
+
const processStream = async ()=>{
|
|
324
|
+
try {
|
|
325
|
+
const { value, done } = await reader.read();
|
|
326
|
+
if (done) return;
|
|
327
|
+
buffer += decoder.decode(value, {
|
|
328
|
+
stream: true
|
|
329
|
+
});
|
|
330
|
+
const events = parseEventStream(buffer);
|
|
331
|
+
for (const event of events){
|
|
332
|
+
if (event.type === successEventType) {
|
|
333
|
+
resolve(event.data);
|
|
334
|
+
}
|
|
335
|
+
if (event.type === 'error') {
|
|
336
|
+
reject(createErrorFromEventData(event.data));
|
|
337
|
+
onError == null ? void 0 : onError(createErrorFromEventData(event.data));
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
processStream();
|
|
341
|
+
} catch (err) {
|
|
342
|
+
reject(err instanceof Error ? err : new Error(String(err)));
|
|
343
|
+
}
|
|
344
|
+
};
|
|
345
|
+
processStream();
|
|
346
|
+
};
|
|
347
|
+
};
|
|
348
|
+
/**
|
|
349
|
+
* Creates an error object from event stream error data.
|
|
350
|
+
*
|
|
351
|
+
* @param data - The error data received from the event stream
|
|
352
|
+
* @returns A standardized Error object with properties from the error data
|
|
353
|
+
*/ const createErrorFromEventData = (data)=>{
|
|
354
|
+
const error = new Error(typeof data === 'object' && data !== null && 'error' in data ? String(data.error) : 'Unknown error');
|
|
355
|
+
if (typeof data === 'object' && data !== null) {
|
|
356
|
+
Object.assign(error, data);
|
|
357
|
+
}
|
|
358
|
+
return error;
|
|
359
|
+
};
|
|
360
|
+
/**
|
|
361
|
+
* Parses a Server-Sent Events (SSE) stream into structured event objects.
|
|
362
|
+
*
|
|
363
|
+
* @param input - Raw string data from an event stream
|
|
364
|
+
* @returns Array of parsed events with type and data properties
|
|
365
|
+
*/ const parseEventStream = (input)=>{
|
|
366
|
+
const lines = input.split('\n');
|
|
367
|
+
const events = [];
|
|
368
|
+
let currentEvent = {};
|
|
369
|
+
let inEvent = false;
|
|
370
|
+
for (const line of lines){
|
|
371
|
+
// Empty line marks the end of an event
|
|
372
|
+
if (line === '') {
|
|
373
|
+
if (currentEvent.type && currentEvent.data) {
|
|
374
|
+
events.push({
|
|
375
|
+
type: currentEvent.type,
|
|
376
|
+
data: JSON.parse(currentEvent.data)
|
|
377
|
+
});
|
|
378
|
+
currentEvent = {};
|
|
379
|
+
inEvent = false;
|
|
380
|
+
}
|
|
381
|
+
continue;
|
|
382
|
+
}
|
|
383
|
+
// Process event fields
|
|
384
|
+
if (line.startsWith('event:')) {
|
|
385
|
+
currentEvent.type = line.substring(6).trim();
|
|
386
|
+
inEvent = true;
|
|
387
|
+
} else if (line.startsWith('data:')) {
|
|
388
|
+
currentEvent.data = line.substring(5).trim();
|
|
389
|
+
inEvent = true;
|
|
390
|
+
} else if (inEvent && currentEvent.data) {
|
|
391
|
+
currentEvent.data += line;
|
|
392
|
+
}
|
|
393
|
+
}
|
|
394
|
+
return events;
|
|
395
|
+
};
|
|
396
|
+
|
|
397
|
+
var SuccessEventType = /*#__PURE__*/ function(SuccessEventType) {
|
|
398
|
+
SuccessEventType["KeygenComplete"] = "keygen_complete";
|
|
399
|
+
SuccessEventType["RoomCreated"] = "room_created";
|
|
400
|
+
return SuccessEventType;
|
|
401
|
+
}({});
|
|
402
|
+
|
|
271
403
|
class DynamicApiClient extends BaseClient {
|
|
272
|
-
async createWalletAccount({ chainName, clientKeygenIds, thresholdSignatureScheme }) {
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
404
|
+
async createWalletAccount({ chainName, clientKeygenIds, thresholdSignatureScheme, onError }) {
|
|
405
|
+
return createEventStreamPromise({
|
|
406
|
+
apiClient: this.apiClient,
|
|
407
|
+
endpoint: `/api/v0/sdk/${this.environmentId}/waas/create`,
|
|
408
|
+
body: {
|
|
409
|
+
chain: chainName,
|
|
410
|
+
clientKeygenIds,
|
|
411
|
+
thresholdSignatureScheme
|
|
412
|
+
},
|
|
413
|
+
successEventType: SuccessEventType.KeygenComplete,
|
|
414
|
+
timeoutMessage: 'Wallet creation timed out',
|
|
415
|
+
onError
|
|
278
416
|
});
|
|
279
|
-
return data;
|
|
280
417
|
}
|
|
281
|
-
async signMessage({ walletId, message }) {
|
|
282
|
-
|
|
283
|
-
|
|
418
|
+
async signMessage({ walletId, message, onError }) {
|
|
419
|
+
return createEventStreamPromise({
|
|
420
|
+
apiClient: this.apiClient,
|
|
421
|
+
endpoint: `/api/v0/sdk/${this.environmentId}/waas/${walletId}/signMessage`,
|
|
422
|
+
body: {
|
|
423
|
+
message
|
|
424
|
+
},
|
|
425
|
+
successEventType: SuccessEventType.RoomCreated,
|
|
426
|
+
timeoutMessage: 'Message signing timed out',
|
|
427
|
+
onError
|
|
284
428
|
});
|
|
285
|
-
return data;
|
|
286
429
|
}
|
|
287
|
-
async refreshWalletAccountShares({ walletId }) {
|
|
288
|
-
|
|
289
|
-
|
|
430
|
+
async refreshWalletAccountShares({ walletId, onError }) {
|
|
431
|
+
return createEventStreamPromise({
|
|
432
|
+
apiClient: this.apiClient,
|
|
433
|
+
endpoint: `/api/v0/sdk/${this.environmentId}/waas/${walletId}/refresh`,
|
|
434
|
+
body: undefined,
|
|
435
|
+
successEventType: SuccessEventType.RoomCreated,
|
|
436
|
+
timeoutMessage: 'Refresh timed out',
|
|
437
|
+
onError
|
|
438
|
+
});
|
|
290
439
|
}
|
|
291
|
-
async reshare({ walletId, clientKeygenIds, oldThresholdSignatureScheme, newThresholdSignatureScheme }) {
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
440
|
+
async reshare({ walletId, clientKeygenIds, oldThresholdSignatureScheme, newThresholdSignatureScheme, onError }) {
|
|
441
|
+
return createEventStreamPromise({
|
|
442
|
+
apiClient: this.apiClient,
|
|
443
|
+
endpoint: `/api/v0/sdk/${this.environmentId}/waas/${walletId}/reshare`,
|
|
444
|
+
body: {
|
|
445
|
+
clientKeygenIds,
|
|
446
|
+
oldThresholdSignatureScheme,
|
|
447
|
+
newThresholdSignatureScheme
|
|
448
|
+
},
|
|
449
|
+
successEventType: SuccessEventType.RoomCreated,
|
|
450
|
+
timeoutMessage: 'Reshare timed out',
|
|
451
|
+
onError
|
|
296
452
|
});
|
|
297
|
-
return data;
|
|
298
453
|
}
|
|
299
|
-
async exportKey({ walletId, exportId }) {
|
|
300
|
-
|
|
301
|
-
|
|
454
|
+
async exportKey({ walletId, exportId, onError }) {
|
|
455
|
+
return createEventStreamPromise({
|
|
456
|
+
apiClient: this.apiClient,
|
|
457
|
+
endpoint: `/api/v0/sdk/${this.environmentId}/waas/${walletId}/privateKey/export`,
|
|
458
|
+
body: {
|
|
459
|
+
exportId
|
|
460
|
+
},
|
|
461
|
+
successEventType: SuccessEventType.RoomCreated,
|
|
462
|
+
timeoutMessage: 'Key export timed out',
|
|
463
|
+
onError
|
|
302
464
|
});
|
|
303
|
-
return data;
|
|
304
465
|
}
|
|
305
466
|
async storeEncryptedBackupByWallet({ walletId, encryptedKeyShares, passwordEncrypted }) {
|
|
306
467
|
const { data } = await this.clientRelayApiClient.post(`/api/v0/sdk/${this.environmentId}/waas/${walletId}/keyShares/backup`, {
|
|
@@ -326,13 +487,19 @@ class DynamicApiClient extends BaseClient {
|
|
|
326
487
|
return data.accessToken;
|
|
327
488
|
}
|
|
328
489
|
// TODO: return array instead considering cases where server has multiple parties
|
|
329
|
-
async importPrivateKey({ chainName, clientKeygenIds, thresholdSignatureScheme }) {
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
490
|
+
async importPrivateKey({ chainName, clientKeygenIds, thresholdSignatureScheme, onError }) {
|
|
491
|
+
return createEventStreamPromise({
|
|
492
|
+
apiClient: this.apiClient,
|
|
493
|
+
endpoint: `/api/v0/sdk/${this.environmentId}/waas/privateKey/import`,
|
|
494
|
+
body: {
|
|
495
|
+
chain: chainName,
|
|
496
|
+
clientKeygenIds,
|
|
497
|
+
thresholdSignatureScheme
|
|
498
|
+
},
|
|
499
|
+
successEventType: SuccessEventType.KeygenComplete,
|
|
500
|
+
timeoutMessage: 'Key import timed out',
|
|
501
|
+
onError
|
|
334
502
|
});
|
|
335
|
-
return data;
|
|
336
503
|
}
|
|
337
504
|
// TODO: consider removing the retry logics if we switch to server-sent events
|
|
338
505
|
async getUser() {
|
package/index.esm.js
CHANGED
|
@@ -266,39 +266,200 @@ class BaseClient {
|
|
|
266
266
|
}
|
|
267
267
|
}
|
|
268
268
|
|
|
269
|
+
/**
|
|
270
|
+
* Creates a promise that resolves when a specific event is received from an event stream.
|
|
271
|
+
* Adds a timeout to prevent hanging and races the two promises.
|
|
272
|
+
*
|
|
273
|
+
* @template T The expected type of the response data
|
|
274
|
+
* @param apiClient The axios instance to use for API calls
|
|
275
|
+
* @param options The configuration options
|
|
276
|
+
* @returns A promise that resolves with the event data or rejects on timeout
|
|
277
|
+
*/ const createEventStreamPromise = ({ apiClient, endpoint, body, successEventType, timeoutMs = 30000, timeoutMessage, onError })=>{
|
|
278
|
+
// Create a promise that will resolve when the success event is received
|
|
279
|
+
const eventPromise = new Promise((resolve, reject)=>{
|
|
280
|
+
apiClient.post(endpoint, body, {
|
|
281
|
+
responseType: 'stream',
|
|
282
|
+
headers: {
|
|
283
|
+
Accept: 'text/event-stream',
|
|
284
|
+
'Cache-Control': 'no-cache',
|
|
285
|
+
Connection: 'keep-alive'
|
|
286
|
+
},
|
|
287
|
+
adapter: 'fetch'
|
|
288
|
+
}).then(createSuccessErrorEventStreamHandler({
|
|
289
|
+
onError,
|
|
290
|
+
reject,
|
|
291
|
+
resolve,
|
|
292
|
+
successEventType
|
|
293
|
+
})).catch(reject);
|
|
294
|
+
});
|
|
295
|
+
// Add a timeout to prevent hanging
|
|
296
|
+
const timeoutPromise = new Promise((_, reject)=>{
|
|
297
|
+
setTimeout(()=>reject(new Error(timeoutMessage)), timeoutMs);
|
|
298
|
+
});
|
|
299
|
+
// Return the event data as soon as it's available
|
|
300
|
+
return Promise.race([
|
|
301
|
+
eventPromise,
|
|
302
|
+
timeoutPromise
|
|
303
|
+
]);
|
|
304
|
+
};
|
|
305
|
+
/**
|
|
306
|
+
* Creates a handler function for processing server-sent events (SSE) streams.
|
|
307
|
+
* This utility manages asynchronous event-based communication with the server,
|
|
308
|
+
* particularly for long-running operations like wallet creation or key generation.
|
|
309
|
+
*
|
|
310
|
+
* @template T - The expected type of the successful response data
|
|
311
|
+
* @param {function} resolve - Promise resolution function to call when the success event is received
|
|
312
|
+
* @param {function} reject - Promise rejection function to call when an error occurs
|
|
313
|
+
* @param {string} successEventType - The event type string that indicates a successful operation
|
|
314
|
+
* @param {function} [onError] - Optional callback for error handling, allowing custom error processing
|
|
315
|
+
* @returns {function} A response handler function that processes the event stream
|
|
316
|
+
*/ const createSuccessErrorEventStreamHandler = ({ resolve, reject, successEventType, onError })=>{
|
|
317
|
+
return (response)=>{
|
|
318
|
+
const reader = response.data.getReader();
|
|
319
|
+
const decoder = new TextDecoder();
|
|
320
|
+
let buffer = '';
|
|
321
|
+
const processStream = async ()=>{
|
|
322
|
+
try {
|
|
323
|
+
const { value, done } = await reader.read();
|
|
324
|
+
if (done) return;
|
|
325
|
+
buffer += decoder.decode(value, {
|
|
326
|
+
stream: true
|
|
327
|
+
});
|
|
328
|
+
const events = parseEventStream(buffer);
|
|
329
|
+
for (const event of events){
|
|
330
|
+
if (event.type === successEventType) {
|
|
331
|
+
resolve(event.data);
|
|
332
|
+
}
|
|
333
|
+
if (event.type === 'error') {
|
|
334
|
+
reject(createErrorFromEventData(event.data));
|
|
335
|
+
onError == null ? void 0 : onError(createErrorFromEventData(event.data));
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
processStream();
|
|
339
|
+
} catch (err) {
|
|
340
|
+
reject(err instanceof Error ? err : new Error(String(err)));
|
|
341
|
+
}
|
|
342
|
+
};
|
|
343
|
+
processStream();
|
|
344
|
+
};
|
|
345
|
+
};
|
|
346
|
+
/**
|
|
347
|
+
* Creates an error object from event stream error data.
|
|
348
|
+
*
|
|
349
|
+
* @param data - The error data received from the event stream
|
|
350
|
+
* @returns A standardized Error object with properties from the error data
|
|
351
|
+
*/ const createErrorFromEventData = (data)=>{
|
|
352
|
+
const error = new Error(typeof data === 'object' && data !== null && 'error' in data ? String(data.error) : 'Unknown error');
|
|
353
|
+
if (typeof data === 'object' && data !== null) {
|
|
354
|
+
Object.assign(error, data);
|
|
355
|
+
}
|
|
356
|
+
return error;
|
|
357
|
+
};
|
|
358
|
+
/**
|
|
359
|
+
* Parses a Server-Sent Events (SSE) stream into structured event objects.
|
|
360
|
+
*
|
|
361
|
+
* @param input - Raw string data from an event stream
|
|
362
|
+
* @returns Array of parsed events with type and data properties
|
|
363
|
+
*/ const parseEventStream = (input)=>{
|
|
364
|
+
const lines = input.split('\n');
|
|
365
|
+
const events = [];
|
|
366
|
+
let currentEvent = {};
|
|
367
|
+
let inEvent = false;
|
|
368
|
+
for (const line of lines){
|
|
369
|
+
// Empty line marks the end of an event
|
|
370
|
+
if (line === '') {
|
|
371
|
+
if (currentEvent.type && currentEvent.data) {
|
|
372
|
+
events.push({
|
|
373
|
+
type: currentEvent.type,
|
|
374
|
+
data: JSON.parse(currentEvent.data)
|
|
375
|
+
});
|
|
376
|
+
currentEvent = {};
|
|
377
|
+
inEvent = false;
|
|
378
|
+
}
|
|
379
|
+
continue;
|
|
380
|
+
}
|
|
381
|
+
// Process event fields
|
|
382
|
+
if (line.startsWith('event:')) {
|
|
383
|
+
currentEvent.type = line.substring(6).trim();
|
|
384
|
+
inEvent = true;
|
|
385
|
+
} else if (line.startsWith('data:')) {
|
|
386
|
+
currentEvent.data = line.substring(5).trim();
|
|
387
|
+
inEvent = true;
|
|
388
|
+
} else if (inEvent && currentEvent.data) {
|
|
389
|
+
currentEvent.data += line;
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
return events;
|
|
393
|
+
};
|
|
394
|
+
|
|
395
|
+
var SuccessEventType = /*#__PURE__*/ function(SuccessEventType) {
|
|
396
|
+
SuccessEventType["KeygenComplete"] = "keygen_complete";
|
|
397
|
+
SuccessEventType["RoomCreated"] = "room_created";
|
|
398
|
+
return SuccessEventType;
|
|
399
|
+
}({});
|
|
400
|
+
|
|
269
401
|
class DynamicApiClient extends BaseClient {
|
|
270
|
-
async createWalletAccount({ chainName, clientKeygenIds, thresholdSignatureScheme }) {
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
402
|
+
async createWalletAccount({ chainName, clientKeygenIds, thresholdSignatureScheme, onError }) {
|
|
403
|
+
return createEventStreamPromise({
|
|
404
|
+
apiClient: this.apiClient,
|
|
405
|
+
endpoint: `/api/v0/sdk/${this.environmentId}/waas/create`,
|
|
406
|
+
body: {
|
|
407
|
+
chain: chainName,
|
|
408
|
+
clientKeygenIds,
|
|
409
|
+
thresholdSignatureScheme
|
|
410
|
+
},
|
|
411
|
+
successEventType: SuccessEventType.KeygenComplete,
|
|
412
|
+
timeoutMessage: 'Wallet creation timed out',
|
|
413
|
+
onError
|
|
276
414
|
});
|
|
277
|
-
return data;
|
|
278
415
|
}
|
|
279
|
-
async signMessage({ walletId, message }) {
|
|
280
|
-
|
|
281
|
-
|
|
416
|
+
async signMessage({ walletId, message, onError }) {
|
|
417
|
+
return createEventStreamPromise({
|
|
418
|
+
apiClient: this.apiClient,
|
|
419
|
+
endpoint: `/api/v0/sdk/${this.environmentId}/waas/${walletId}/signMessage`,
|
|
420
|
+
body: {
|
|
421
|
+
message
|
|
422
|
+
},
|
|
423
|
+
successEventType: SuccessEventType.RoomCreated,
|
|
424
|
+
timeoutMessage: 'Message signing timed out',
|
|
425
|
+
onError
|
|
282
426
|
});
|
|
283
|
-
return data;
|
|
284
427
|
}
|
|
285
|
-
async refreshWalletAccountShares({ walletId }) {
|
|
286
|
-
|
|
287
|
-
|
|
428
|
+
async refreshWalletAccountShares({ walletId, onError }) {
|
|
429
|
+
return createEventStreamPromise({
|
|
430
|
+
apiClient: this.apiClient,
|
|
431
|
+
endpoint: `/api/v0/sdk/${this.environmentId}/waas/${walletId}/refresh`,
|
|
432
|
+
body: undefined,
|
|
433
|
+
successEventType: SuccessEventType.RoomCreated,
|
|
434
|
+
timeoutMessage: 'Refresh timed out',
|
|
435
|
+
onError
|
|
436
|
+
});
|
|
288
437
|
}
|
|
289
|
-
async reshare({ walletId, clientKeygenIds, oldThresholdSignatureScheme, newThresholdSignatureScheme }) {
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
438
|
+
async reshare({ walletId, clientKeygenIds, oldThresholdSignatureScheme, newThresholdSignatureScheme, onError }) {
|
|
439
|
+
return createEventStreamPromise({
|
|
440
|
+
apiClient: this.apiClient,
|
|
441
|
+
endpoint: `/api/v0/sdk/${this.environmentId}/waas/${walletId}/reshare`,
|
|
442
|
+
body: {
|
|
443
|
+
clientKeygenIds,
|
|
444
|
+
oldThresholdSignatureScheme,
|
|
445
|
+
newThresholdSignatureScheme
|
|
446
|
+
},
|
|
447
|
+
successEventType: SuccessEventType.RoomCreated,
|
|
448
|
+
timeoutMessage: 'Reshare timed out',
|
|
449
|
+
onError
|
|
294
450
|
});
|
|
295
|
-
return data;
|
|
296
451
|
}
|
|
297
|
-
async exportKey({ walletId, exportId }) {
|
|
298
|
-
|
|
299
|
-
|
|
452
|
+
async exportKey({ walletId, exportId, onError }) {
|
|
453
|
+
return createEventStreamPromise({
|
|
454
|
+
apiClient: this.apiClient,
|
|
455
|
+
endpoint: `/api/v0/sdk/${this.environmentId}/waas/${walletId}/privateKey/export`,
|
|
456
|
+
body: {
|
|
457
|
+
exportId
|
|
458
|
+
},
|
|
459
|
+
successEventType: SuccessEventType.RoomCreated,
|
|
460
|
+
timeoutMessage: 'Key export timed out',
|
|
461
|
+
onError
|
|
300
462
|
});
|
|
301
|
-
return data;
|
|
302
463
|
}
|
|
303
464
|
async storeEncryptedBackupByWallet({ walletId, encryptedKeyShares, passwordEncrypted }) {
|
|
304
465
|
const { data } = await this.clientRelayApiClient.post(`/api/v0/sdk/${this.environmentId}/waas/${walletId}/keyShares/backup`, {
|
|
@@ -324,13 +485,19 @@ class DynamicApiClient extends BaseClient {
|
|
|
324
485
|
return data.accessToken;
|
|
325
486
|
}
|
|
326
487
|
// TODO: return array instead considering cases where server has multiple parties
|
|
327
|
-
async importPrivateKey({ chainName, clientKeygenIds, thresholdSignatureScheme }) {
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
488
|
+
async importPrivateKey({ chainName, clientKeygenIds, thresholdSignatureScheme, onError }) {
|
|
489
|
+
return createEventStreamPromise({
|
|
490
|
+
apiClient: this.apiClient,
|
|
491
|
+
endpoint: `/api/v0/sdk/${this.environmentId}/waas/privateKey/import`,
|
|
492
|
+
body: {
|
|
493
|
+
chain: chainName,
|
|
494
|
+
clientKeygenIds,
|
|
495
|
+
thresholdSignatureScheme
|
|
496
|
+
},
|
|
497
|
+
successEventType: SuccessEventType.KeygenComplete,
|
|
498
|
+
timeoutMessage: 'Key import timed out',
|
|
499
|
+
onError
|
|
332
500
|
});
|
|
333
|
-
return data;
|
|
334
501
|
}
|
|
335
502
|
// TODO: consider removing the retry logics if we switch to server-sent events
|
|
336
503
|
async getUser() {
|
package/package.json
CHANGED
package/src/api/api.d.ts
CHANGED
|
@@ -1,33 +1,42 @@
|
|
|
1
|
-
import { ThresholdSignatureScheme } from '../mpc/constants';
|
|
1
|
+
import type { ThresholdSignatureScheme } from '../mpc/constants';
|
|
2
2
|
import { BaseClient } from './client';
|
|
3
|
+
import { type KeygenCompleteResponse, type OpenRoomResponse, type ReshareResponse } from '../types';
|
|
3
4
|
export declare class DynamicApiClient extends BaseClient {
|
|
4
5
|
constructor({ environmentId, authToken, baseApiUrl, }: {
|
|
5
6
|
environmentId: string;
|
|
6
7
|
authToken: string;
|
|
7
8
|
baseApiUrl?: string;
|
|
8
9
|
});
|
|
9
|
-
createWalletAccount({ chainName, clientKeygenIds, thresholdSignatureScheme, }: {
|
|
10
|
+
createWalletAccount({ chainName, clientKeygenIds, thresholdSignatureScheme, onError, }: {
|
|
10
11
|
chainName: string;
|
|
11
12
|
clientKeygenIds: string[];
|
|
12
13
|
thresholdSignatureScheme: ThresholdSignatureScheme;
|
|
13
|
-
|
|
14
|
-
|
|
14
|
+
onError?: (error: Error) => void;
|
|
15
|
+
}): Promise<KeygenCompleteResponse>;
|
|
16
|
+
signMessage({ walletId, message, onError, }: {
|
|
15
17
|
walletId: string;
|
|
16
18
|
message: string;
|
|
17
|
-
|
|
18
|
-
|
|
19
|
+
onError?: (error: Error) => void;
|
|
20
|
+
}): Promise<OpenRoomResponse>;
|
|
21
|
+
refreshWalletAccountShares({ walletId, onError }: {
|
|
19
22
|
walletId: string;
|
|
20
|
-
|
|
21
|
-
|
|
23
|
+
onError?: (error: Error) => void;
|
|
24
|
+
}): Promise<{
|
|
25
|
+
roomId: string;
|
|
26
|
+
serverKeygenIds: string[];
|
|
27
|
+
}>;
|
|
28
|
+
reshare({ walletId, clientKeygenIds, oldThresholdSignatureScheme, newThresholdSignatureScheme, onError, }: {
|
|
22
29
|
walletId: string;
|
|
23
30
|
clientKeygenIds: string[];
|
|
24
31
|
oldThresholdSignatureScheme: ThresholdSignatureScheme;
|
|
25
32
|
newThresholdSignatureScheme: ThresholdSignatureScheme;
|
|
26
|
-
|
|
27
|
-
|
|
33
|
+
onError?: (error: Error) => void;
|
|
34
|
+
}): Promise<ReshareResponse>;
|
|
35
|
+
exportKey({ walletId, exportId, onError, }: {
|
|
28
36
|
walletId: string;
|
|
29
37
|
exportId: string;
|
|
30
|
-
|
|
38
|
+
onError?: (error: Error) => void;
|
|
39
|
+
}): Promise<OpenRoomResponse>;
|
|
31
40
|
storeEncryptedBackupByWallet({ walletId, encryptedKeyShares, passwordEncrypted, }: {
|
|
32
41
|
walletId: string;
|
|
33
42
|
encryptedKeyShares: string[];
|
|
@@ -43,14 +52,12 @@ export declare class DynamicApiClient extends BaseClient {
|
|
|
43
52
|
getAccessToken({ oauthAccountId }: {
|
|
44
53
|
oauthAccountId: string;
|
|
45
54
|
}): Promise<any>;
|
|
46
|
-
importPrivateKey({ chainName, clientKeygenIds, thresholdSignatureScheme, }: {
|
|
55
|
+
importPrivateKey({ chainName, clientKeygenIds, thresholdSignatureScheme, onError, }: {
|
|
47
56
|
chainName: string;
|
|
48
57
|
clientKeygenIds: string[];
|
|
49
58
|
thresholdSignatureScheme: ThresholdSignatureScheme;
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
serverKeygenIds: string[];
|
|
53
|
-
}>;
|
|
59
|
+
onError?: (error: Error) => void;
|
|
60
|
+
}): Promise<KeygenCompleteResponse>;
|
|
54
61
|
getUser(): Promise<any>;
|
|
55
62
|
refreshUser(): Promise<any>;
|
|
56
63
|
}
|
package/src/api/api.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../../src/api/api.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,wBAAwB,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../../src/api/api.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import type { AxiosInstance } from 'axios';
|
|
2
|
+
import type { SuccessEventType } from '../types';
|
|
3
|
+
/**
|
|
4
|
+
* Creates a promise that resolves when a specific event is received from an event stream.
|
|
5
|
+
* Adds a timeout to prevent hanging and races the two promises.
|
|
6
|
+
*
|
|
7
|
+
* @template T The expected type of the response data
|
|
8
|
+
* @param apiClient The axios instance to use for API calls
|
|
9
|
+
* @param options The configuration options
|
|
10
|
+
* @returns A promise that resolves with the event data or rejects on timeout
|
|
11
|
+
*/
|
|
12
|
+
export declare const createEventStreamPromise: <T>({ apiClient, endpoint, body, successEventType, timeoutMs, timeoutMessage, onError, }: {
|
|
13
|
+
apiClient: AxiosInstance;
|
|
14
|
+
endpoint: string;
|
|
15
|
+
body: Record<string, unknown> | undefined;
|
|
16
|
+
successEventType: SuccessEventType;
|
|
17
|
+
timeoutMs?: number;
|
|
18
|
+
timeoutMessage: string;
|
|
19
|
+
onError?: (error: Error) => void;
|
|
20
|
+
}) => Promise<T>;
|
|
21
|
+
/**
|
|
22
|
+
* Creates a handler function for processing server-sent events (SSE) streams.
|
|
23
|
+
* This utility manages asynchronous event-based communication with the server,
|
|
24
|
+
* particularly for long-running operations like wallet creation or key generation.
|
|
25
|
+
*
|
|
26
|
+
* @template T - The expected type of the successful response data
|
|
27
|
+
* @param {function} resolve - Promise resolution function to call when the success event is received
|
|
28
|
+
* @param {function} reject - Promise rejection function to call when an error occurs
|
|
29
|
+
* @param {string} successEventType - The event type string that indicates a successful operation
|
|
30
|
+
* @param {function} [onError] - Optional callback for error handling, allowing custom error processing
|
|
31
|
+
* @returns {function} A response handler function that processes the event stream
|
|
32
|
+
*/
|
|
33
|
+
export declare const createSuccessErrorEventStreamHandler: <T>({ resolve, reject, successEventType, onError, }: {
|
|
34
|
+
resolve: (data: T) => void;
|
|
35
|
+
reject: (error: Error) => void;
|
|
36
|
+
successEventType: string;
|
|
37
|
+
onError?: (error: Error) => void;
|
|
38
|
+
}) => (response: {
|
|
39
|
+
data: {
|
|
40
|
+
getReader: () => {
|
|
41
|
+
read: () => Promise<{
|
|
42
|
+
value: Uint8Array;
|
|
43
|
+
done: boolean;
|
|
44
|
+
}>;
|
|
45
|
+
};
|
|
46
|
+
};
|
|
47
|
+
}) => void;
|
|
48
|
+
//# sourceMappingURL=utils.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/eventStream/utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,OAAO,CAAC;AAC3C,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;AACjD;;;;;;;;GAQG;AACH,eAAO,MAAM,wBAAwB,GAAI,CAAC,wFAQvC;IACD,SAAS,EAAE,aAAa,CAAC;IACzB,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,CAAC;IAC1C,gBAAgB,EAAE,gBAAgB,CAAC;IACnC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,cAAc,EAAE,MAAM,CAAC;IACvB,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;CAClC,KAAG,OAAO,CAAC,CAAC,CA+BZ,CAAC;AAEF;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,oCAAoC,GAAI,CAAC,mDAKnD;IACD,OAAO,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,IAAI,CAAC;IAC3B,MAAM,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;IAC/B,gBAAgB,EAAE,MAAM,CAAC;IACzB,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;CAClC,gBACmB;IAChB,IAAI,EAAE;QACJ,SAAS,EAAE,MAAM;YACf,IAAI,EAAE,MAAM,OAAO,CAAC;gBAAE,KAAK,EAAE,UAAU,CAAC;gBAAC,IAAI,EAAE,OAAO,CAAA;aAAE,CAAC,CAAC;SAC3D,CAAC;KACH,CAAC;CACH,SAgCF,CAAC"}
|
package/src/types.d.ts
CHANGED
|
@@ -6,4 +6,22 @@ export type KeygenResult = {
|
|
|
6
6
|
pubkey: string;
|
|
7
7
|
secretShare: string;
|
|
8
8
|
};
|
|
9
|
+
export type KeygenCompleteResponse = {
|
|
10
|
+
walletId: string;
|
|
11
|
+
roomId: string;
|
|
12
|
+
serverKeygenIds: string[];
|
|
13
|
+
};
|
|
14
|
+
export type OpenRoomResponse = {
|
|
15
|
+
roomId: string;
|
|
16
|
+
serverKeygenIds: string[];
|
|
17
|
+
};
|
|
18
|
+
export type ReshareResponse = {
|
|
19
|
+
roomId: string;
|
|
20
|
+
serverKeygenIds: string[];
|
|
21
|
+
newServerKeygenIds: string[];
|
|
22
|
+
};
|
|
23
|
+
export declare enum SuccessEventType {
|
|
24
|
+
KeygenComplete = "keygen_complete",
|
|
25
|
+
RoomCreated = "room_created"
|
|
26
|
+
}
|
|
9
27
|
//# sourceMappingURL=types.d.ts.map
|
package/src/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../packages/src/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,gBAAgB,GAAG;IAC7B,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;CACtB,CAAC;AAEF,MAAM,MAAM,YAAY,GAAG;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;CACrB,CAAC"}
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../packages/src/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,gBAAgB,GAAG;IAC7B,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;CACtB,CAAC;AAEF,MAAM,MAAM,YAAY,GAAG;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;CACrB,CAAC;AAEF,MAAM,MAAM,sBAAsB,GAAG;IACnC,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,eAAe,EAAE,MAAM,EAAE,CAAC;CAC3B,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG;IAC7B,MAAM,EAAE,MAAM,CAAC;IACf,eAAe,EAAE,MAAM,EAAE,CAAC;CAC3B,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG;IAC5B,MAAM,EAAE,MAAM,CAAC;IACf,eAAe,EAAE,MAAM,EAAE,CAAC;IAC1B,kBAAkB,EAAE,MAAM,EAAE,CAAC;CAC9B,CAAC;AAEF,oBAAY,gBAAgB;IAC1B,cAAc,oBAAoB;IAClC,WAAW,iBAAiB;CAC7B"}
|