@dynamic-labs-wallet/core 0.0.41 → 0.0.42

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 CHANGED
@@ -268,15 +268,129 @@ class BaseClient {
268
268
  }
269
269
  }
270
270
 
271
+ /**
272
+ * Creates a handler function for processing server-sent events (SSE) streams.
273
+ * This utility manages asynchronous event-based communication with the server,
274
+ * particularly for long-running operations like wallet creation or key generation.
275
+ *
276
+ * @template T - The expected type of the successful response data
277
+ * @param {function} resolve - Promise resolution function to call when the success event is received
278
+ * @param {function} reject - Promise rejection function to call when an error occurs
279
+ * @param {string} successEventType - The event type string that indicates a successful operation
280
+ * @param {function} [onError] - Optional callback for error handling, allowing custom error processing
281
+ * @returns {function} A response handler function that processes the event stream
282
+ */ const createSuccessErrorEventStreamHandler = ({ resolve, reject, successEventType, onError })=>{
283
+ return (response)=>{
284
+ const reader = response.data.getReader();
285
+ const decoder = new TextDecoder();
286
+ let buffer = '';
287
+ const processStream = async ()=>{
288
+ try {
289
+ const { value, done } = await reader.read();
290
+ if (done) return;
291
+ buffer += decoder.decode(value, {
292
+ stream: true
293
+ });
294
+ const events = parseEventStream(buffer);
295
+ for (const event of events){
296
+ if (event.type === successEventType) {
297
+ resolve(event.data);
298
+ }
299
+ if (event.type === 'error') {
300
+ reject(createErrorFromEventData(event.data));
301
+ onError == null ? void 0 : onError(createErrorFromEventData(event.data));
302
+ }
303
+ }
304
+ // Continue reading if no conclusive event was found
305
+ processStream();
306
+ } catch (err) {
307
+ reject(err instanceof Error ? err : new Error(String(err)));
308
+ }
309
+ };
310
+ processStream();
311
+ };
312
+ };
313
+ /**
314
+ * Creates an error object from event stream error data.
315
+ *
316
+ * @param data - The error data received from the event stream
317
+ * @returns A standardized Error object with properties from the error data
318
+ */ const createErrorFromEventData = (data)=>{
319
+ const error = new Error(typeof data === 'object' && data !== null && 'error' in data ? String(data.error) : 'Unknown error');
320
+ if (typeof data === 'object' && data !== null) {
321
+ Object.assign(error, data);
322
+ }
323
+ return error;
324
+ };
325
+ /**
326
+ * Parses a Server-Sent Events (SSE) stream into structured event objects.
327
+ *
328
+ * @param input - Raw string data from an event stream
329
+ * @returns Array of parsed events with type and data properties
330
+ */ const parseEventStream = (input)=>{
331
+ const lines = input.split('\n');
332
+ const events = [];
333
+ let currentEvent = {};
334
+ let inEvent = false;
335
+ for (const line of lines){
336
+ // Empty line marks the end of an event
337
+ if (line === '') {
338
+ if (currentEvent.type && currentEvent.data) {
339
+ events.push({
340
+ type: currentEvent.type,
341
+ data: JSON.parse(currentEvent.data)
342
+ });
343
+ currentEvent = {};
344
+ inEvent = false;
345
+ }
346
+ continue;
347
+ }
348
+ // Process event fields
349
+ if (line.startsWith('event:')) {
350
+ currentEvent.type = line.substring(6).trim();
351
+ inEvent = true;
352
+ } else if (line.startsWith('data:')) {
353
+ currentEvent.data = line.substring(5).trim();
354
+ inEvent = true;
355
+ } else if (inEvent && currentEvent.data) {
356
+ currentEvent.data += line;
357
+ }
358
+ }
359
+ return events;
360
+ };
361
+
271
362
  class DynamicApiClient extends BaseClient {
272
- async createWalletAccount({ chainName, clientKeygenIds, thresholdSignatureScheme }) {
273
- // Initialize keygen, create room, and create the wallet account on the server
274
- const { data } = await this.apiClient.post(`/api/v0/sdk/${this.environmentId}/waas/create`, {
275
- chain: chainName,
276
- clientKeygenIds,
277
- thresholdSignatureScheme
363
+ async createWalletAccount({ chainName, clientKeygenIds, thresholdSignatureScheme, onError }) {
364
+ // Create a promise that will resolve when the keygen_complete event is received
365
+ const keygenCompletePromise = new Promise((resolve, reject)=>{
366
+ this.apiClient.post(`/api/v0/sdk/${this.environmentId}/waas/create`, {
367
+ chain: chainName,
368
+ clientKeygenIds,
369
+ thresholdSignatureScheme
370
+ }, {
371
+ responseType: 'stream',
372
+ headers: {
373
+ Accept: 'text/event-stream',
374
+ 'Cache-Control': 'no-cache',
375
+ Connection: 'keep-alive'
376
+ },
377
+ adapter: 'fetch'
378
+ }).then(createSuccessErrorEventStreamHandler({
379
+ onError,
380
+ reject,
381
+ resolve,
382
+ successEventType: 'keygen_complete'
383
+ })).catch(reject);
278
384
  });
279
- return data;
385
+ // Add a timeout to prevent hanging
386
+ const timeoutPromise = new Promise((_, reject)=>{
387
+ setTimeout(()=>reject(new Error('Wallet creation timed out')), 30000);
388
+ });
389
+ // Return the keygen complete data as soon as it's available
390
+ return Promise.race([
391
+ keygenCompletePromise,
392
+ timeoutPromise
393
+ ]);
280
394
  }
281
395
  async signMessage({ walletId, message }) {
282
396
  const { data } = await this.apiClient.post(`/api/v0/sdk/${this.environmentId}/waas/${walletId}/signMessage`, {
package/index.esm.js CHANGED
@@ -266,15 +266,129 @@ class BaseClient {
266
266
  }
267
267
  }
268
268
 
269
+ /**
270
+ * Creates a handler function for processing server-sent events (SSE) streams.
271
+ * This utility manages asynchronous event-based communication with the server,
272
+ * particularly for long-running operations like wallet creation or key generation.
273
+ *
274
+ * @template T - The expected type of the successful response data
275
+ * @param {function} resolve - Promise resolution function to call when the success event is received
276
+ * @param {function} reject - Promise rejection function to call when an error occurs
277
+ * @param {string} successEventType - The event type string that indicates a successful operation
278
+ * @param {function} [onError] - Optional callback for error handling, allowing custom error processing
279
+ * @returns {function} A response handler function that processes the event stream
280
+ */ const createSuccessErrorEventStreamHandler = ({ resolve, reject, successEventType, onError })=>{
281
+ return (response)=>{
282
+ const reader = response.data.getReader();
283
+ const decoder = new TextDecoder();
284
+ let buffer = '';
285
+ const processStream = async ()=>{
286
+ try {
287
+ const { value, done } = await reader.read();
288
+ if (done) return;
289
+ buffer += decoder.decode(value, {
290
+ stream: true
291
+ });
292
+ const events = parseEventStream(buffer);
293
+ for (const event of events){
294
+ if (event.type === successEventType) {
295
+ resolve(event.data);
296
+ }
297
+ if (event.type === 'error') {
298
+ reject(createErrorFromEventData(event.data));
299
+ onError == null ? void 0 : onError(createErrorFromEventData(event.data));
300
+ }
301
+ }
302
+ // Continue reading if no conclusive event was found
303
+ processStream();
304
+ } catch (err) {
305
+ reject(err instanceof Error ? err : new Error(String(err)));
306
+ }
307
+ };
308
+ processStream();
309
+ };
310
+ };
311
+ /**
312
+ * Creates an error object from event stream error data.
313
+ *
314
+ * @param data - The error data received from the event stream
315
+ * @returns A standardized Error object with properties from the error data
316
+ */ const createErrorFromEventData = (data)=>{
317
+ const error = new Error(typeof data === 'object' && data !== null && 'error' in data ? String(data.error) : 'Unknown error');
318
+ if (typeof data === 'object' && data !== null) {
319
+ Object.assign(error, data);
320
+ }
321
+ return error;
322
+ };
323
+ /**
324
+ * Parses a Server-Sent Events (SSE) stream into structured event objects.
325
+ *
326
+ * @param input - Raw string data from an event stream
327
+ * @returns Array of parsed events with type and data properties
328
+ */ const parseEventStream = (input)=>{
329
+ const lines = input.split('\n');
330
+ const events = [];
331
+ let currentEvent = {};
332
+ let inEvent = false;
333
+ for (const line of lines){
334
+ // Empty line marks the end of an event
335
+ if (line === '') {
336
+ if (currentEvent.type && currentEvent.data) {
337
+ events.push({
338
+ type: currentEvent.type,
339
+ data: JSON.parse(currentEvent.data)
340
+ });
341
+ currentEvent = {};
342
+ inEvent = false;
343
+ }
344
+ continue;
345
+ }
346
+ // Process event fields
347
+ if (line.startsWith('event:')) {
348
+ currentEvent.type = line.substring(6).trim();
349
+ inEvent = true;
350
+ } else if (line.startsWith('data:')) {
351
+ currentEvent.data = line.substring(5).trim();
352
+ inEvent = true;
353
+ } else if (inEvent && currentEvent.data) {
354
+ currentEvent.data += line;
355
+ }
356
+ }
357
+ return events;
358
+ };
359
+
269
360
  class DynamicApiClient extends BaseClient {
270
- async createWalletAccount({ chainName, clientKeygenIds, thresholdSignatureScheme }) {
271
- // Initialize keygen, create room, and create the wallet account on the server
272
- const { data } = await this.apiClient.post(`/api/v0/sdk/${this.environmentId}/waas/create`, {
273
- chain: chainName,
274
- clientKeygenIds,
275
- thresholdSignatureScheme
361
+ async createWalletAccount({ chainName, clientKeygenIds, thresholdSignatureScheme, onError }) {
362
+ // Create a promise that will resolve when the keygen_complete event is received
363
+ const keygenCompletePromise = new Promise((resolve, reject)=>{
364
+ this.apiClient.post(`/api/v0/sdk/${this.environmentId}/waas/create`, {
365
+ chain: chainName,
366
+ clientKeygenIds,
367
+ thresholdSignatureScheme
368
+ }, {
369
+ responseType: 'stream',
370
+ headers: {
371
+ Accept: 'text/event-stream',
372
+ 'Cache-Control': 'no-cache',
373
+ Connection: 'keep-alive'
374
+ },
375
+ adapter: 'fetch'
376
+ }).then(createSuccessErrorEventStreamHandler({
377
+ onError,
378
+ reject,
379
+ resolve,
380
+ successEventType: 'keygen_complete'
381
+ })).catch(reject);
276
382
  });
277
- return data;
383
+ // Add a timeout to prevent hanging
384
+ const timeoutPromise = new Promise((_, reject)=>{
385
+ setTimeout(()=>reject(new Error('Wallet creation timed out')), 30000);
386
+ });
387
+ // Return the keygen complete data as soon as it's available
388
+ return Promise.race([
389
+ keygenCompletePromise,
390
+ timeoutPromise
391
+ ]);
278
392
  }
279
393
  async signMessage({ walletId, message }) {
280
394
  const { data } = await this.apiClient.post(`/api/v0/sdk/${this.environmentId}/waas/${walletId}/signMessage`, {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dynamic-labs-wallet/core",
3
- "version": "0.0.41",
3
+ "version": "0.0.42",
4
4
  "license": "MIT",
5
5
  "dependencies": {
6
6
  "axios": "1.7.9"
package/src/api/api.d.ts CHANGED
@@ -1,16 +1,22 @@
1
- import { ThresholdSignatureScheme } from '../mpc/constants';
1
+ import type { ThresholdSignatureScheme } from '../mpc/constants';
2
2
  import { BaseClient } from './client';
3
+ type KeygenCompleteResponse = {
4
+ walletId: string;
5
+ roomId: string;
6
+ serverKeygenIds: string[];
7
+ };
3
8
  export declare class DynamicApiClient extends BaseClient {
4
9
  constructor({ environmentId, authToken, baseApiUrl, }: {
5
10
  environmentId: string;
6
11
  authToken: string;
7
12
  baseApiUrl?: string;
8
13
  });
9
- createWalletAccount({ chainName, clientKeygenIds, thresholdSignatureScheme, }: {
14
+ createWalletAccount({ chainName, clientKeygenIds, thresholdSignatureScheme, onError, }: {
10
15
  chainName: string;
11
16
  clientKeygenIds: string[];
12
17
  thresholdSignatureScheme: ThresholdSignatureScheme;
13
- }): Promise<any>;
18
+ onError?: (error: Error) => void;
19
+ }): Promise<KeygenCompleteResponse>;
14
20
  signMessage({ walletId, message, }: {
15
21
  walletId: string;
16
22
  message: string;
@@ -54,4 +60,5 @@ export declare class DynamicApiClient extends BaseClient {
54
60
  getUser(): Promise<any>;
55
61
  refreshUser(): Promise<any>;
56
62
  }
63
+ export {};
57
64
  //# sourceMappingURL=api.d.ts.map
@@ -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;AAC5D,OAAO,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAEtC,qBAAa,gBAAiB,SAAQ,UAAU;gBAClC,EACV,aAAa,EACb,SAAS,EACT,UAAU,GACX,EAAE;QACD,aAAa,EAAE,MAAM,CAAC;QACtB,SAAS,EAAE,MAAM,CAAC;QAClB,UAAU,CAAC,EAAE,MAAM,CAAC;KACrB;IAIK,mBAAmB,CAAC,EACxB,SAAS,EACT,eAAe,EACf,wBAAwB,GACzB,EAAE;QACD,SAAS,EAAE,MAAM,CAAC;QAClB,eAAe,EAAE,MAAM,EAAE,CAAC;QAC1B,wBAAwB,EAAE,wBAAwB,CAAC;KACpD;IAaK,WAAW,CAAC,EAChB,QAAQ,EACR,OAAO,GACR,EAAE;QACD,QAAQ,EAAE,MAAM,CAAC;QACjB,OAAO,EAAE,MAAM,CAAC;KACjB;IAUK,0BAA0B,CAAC,EAAE,QAAQ,EAAE,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAA;KAAE;IAO7D,OAAO,CAAC,EACZ,QAAQ,EACR,eAAe,EACf,2BAA2B,EAC3B,2BAA2B,GAC5B,EAAE;QACD,QAAQ,EAAE,MAAM,CAAC;QACjB,eAAe,EAAE,MAAM,EAAE,CAAC;QAC1B,2BAA2B,EAAE,wBAAwB,CAAC;QACtD,2BAA2B,EAAE,wBAAwB,CAAC;KACvD;IAYK,SAAS,CAAC,EACd,QAAQ,EACR,QAAQ,GACT,EAAE;QACD,QAAQ,EAAE,MAAM,CAAC;QACjB,QAAQ,EAAE,MAAM,CAAC;KAClB;IAUK,4BAA4B,CAAC,EACjC,QAAQ,EACR,kBAAkB,EAClB,iBAAiB,GAClB,EAAE;QACD,QAAQ,EAAE,MAAM,CAAC;QACjB,kBAAkB,EAAE,MAAM,EAAE,CAAC;QAC7B,iBAAiB,EAAE,OAAO,CAAC;KAC5B;IAYK,kCAAkC,CAAC,EAAE,QAAQ,EAAE,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAA;KAAE;IASrE,8BAA8B,CAAC,EACnC,QAAQ,EACR,WAAW,GACZ,EAAE;QACD,QAAQ,EAAE,MAAM,CAAC;QACjB,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;KACxB;IAQK,cAAc,CAAC,EAAE,cAAc,EAAE,EAAE;QAAE,cAAc,EAAE,MAAM,CAAA;KAAE;IAS7D,gBAAgB,CAAC,EACrB,SAAS,EACT,eAAe,EACf,wBAAwB,GACzB,EAAE;QACD,SAAS,EAAE,MAAM,CAAC;QAClB,eAAe,EAAE,MAAM,EAAE,CAAC;QAC1B,wBAAwB,EAAE,wBAAwB,CAAC;KACpD,GAAG,OAAO,CAAC;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,eAAe,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC;IAapD,OAAO,IAAI,OAAO,CAAC,GAAG,CAAC;IAsBvB,WAAW,IAAI,OAAO,CAAC,GAAG,CAAC;CAqBlC"}
1
+ {"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../../src/api/api.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,kBAAkB,CAAC;AACjE,OAAO,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAGtC,KAAK,sBAAsB,GAAG;IAC5B,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,eAAe,EAAE,MAAM,EAAE,CAAC;CAC3B,CAAC;AAEF,qBAAa,gBAAiB,SAAQ,UAAU;gBAClC,EACV,aAAa,EACb,SAAS,EACT,UAAU,GACX,EAAE;QACD,aAAa,EAAE,MAAM,CAAC;QACtB,SAAS,EAAE,MAAM,CAAC;QAClB,UAAU,CAAC,EAAE,MAAM,CAAC;KACrB;IAIK,mBAAmB,CAAC,EACxB,SAAS,EACT,eAAe,EACf,wBAAwB,EACxB,OAAO,GACR,EAAE;QACD,SAAS,EAAE,MAAM,CAAC;QAClB,eAAe,EAAE,MAAM,EAAE,CAAC;QAC1B,wBAAwB,EAAE,wBAAwB,CAAC;QACnD,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;KAClC;IA2CK,WAAW,CAAC,EAChB,QAAQ,EACR,OAAO,GACR,EAAE;QACD,QAAQ,EAAE,MAAM,CAAC;QACjB,OAAO,EAAE,MAAM,CAAC;KACjB;IAUK,0BAA0B,CAAC,EAAE,QAAQ,EAAE,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAA;KAAE;IAO7D,OAAO,CAAC,EACZ,QAAQ,EACR,eAAe,EACf,2BAA2B,EAC3B,2BAA2B,GAC5B,EAAE;QACD,QAAQ,EAAE,MAAM,CAAC;QACjB,eAAe,EAAE,MAAM,EAAE,CAAC;QAC1B,2BAA2B,EAAE,wBAAwB,CAAC;QACtD,2BAA2B,EAAE,wBAAwB,CAAC;KACvD;IAYK,SAAS,CAAC,EACd,QAAQ,EACR,QAAQ,GACT,EAAE;QACD,QAAQ,EAAE,MAAM,CAAC;QACjB,QAAQ,EAAE,MAAM,CAAC;KAClB;IAUK,4BAA4B,CAAC,EACjC,QAAQ,EACR,kBAAkB,EAClB,iBAAiB,GAClB,EAAE;QACD,QAAQ,EAAE,MAAM,CAAC;QACjB,kBAAkB,EAAE,MAAM,EAAE,CAAC;QAC7B,iBAAiB,EAAE,OAAO,CAAC;KAC5B;IAYK,kCAAkC,CAAC,EAAE,QAAQ,EAAE,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAA;KAAE;IASrE,8BAA8B,CAAC,EACnC,QAAQ,EACR,WAAW,GACZ,EAAE;QACD,QAAQ,EAAE,MAAM,CAAC;QACjB,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;KACxB;IAQK,cAAc,CAAC,EAAE,cAAc,EAAE,EAAE;QAAE,cAAc,EAAE,MAAM,CAAA;KAAE;IAS7D,gBAAgB,CAAC,EACrB,SAAS,EACT,eAAe,EACf,wBAAwB,GACzB,EAAE;QACD,SAAS,EAAE,MAAM,CAAC;QAClB,eAAe,EAAE,MAAM,EAAE,CAAC;QAC1B,wBAAwB,EAAE,wBAAwB,CAAC;KACpD,GAAG,OAAO,CAAC;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,eAAe,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC;IAapD,OAAO,IAAI,OAAO,CAAC,GAAG,CAAC;IAsBvB,WAAW,IAAI,OAAO,CAAC,GAAG,CAAC;CAqBlC"}
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Creates a handler function for processing server-sent events (SSE) streams.
3
+ * This utility manages asynchronous event-based communication with the server,
4
+ * particularly for long-running operations like wallet creation or key generation.
5
+ *
6
+ * @template T - The expected type of the successful response data
7
+ * @param {function} resolve - Promise resolution function to call when the success event is received
8
+ * @param {function} reject - Promise rejection function to call when an error occurs
9
+ * @param {string} successEventType - The event type string that indicates a successful operation
10
+ * @param {function} [onError] - Optional callback for error handling, allowing custom error processing
11
+ * @returns {function} A response handler function that processes the event stream
12
+ */
13
+ export declare const createSuccessErrorEventStreamHandler: <T>({ resolve, reject, successEventType, onError, }: {
14
+ resolve: (data: T) => void;
15
+ reject: (error: Error) => void;
16
+ successEventType: string;
17
+ onError?: (error: Error) => void;
18
+ }) => (response: {
19
+ data: {
20
+ getReader: () => {
21
+ read: () => Promise<{
22
+ value: Uint8Array;
23
+ done: boolean;
24
+ }>;
25
+ };
26
+ };
27
+ }) => void;
28
+ //# sourceMappingURL=utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/eventStream/utils.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;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,SAiCF,CAAC"}