@dynamic-labs-wallet/core 0.0.0-pr384.2 → 0.0.0-pr526.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/index.esm.js CHANGED
@@ -1,9 +1,8 @@
1
1
  import { v4 } from 'uuid';
2
2
  import axios from 'axios';
3
+ import { ForwardMPCClient } from '@dynamic-labs-wallet/forward-mpc-client';
4
+ import createHttpError from 'http-errors';
3
5
 
4
- const DYNAMIC_AUTH_PROD_BASE_API_URL = 'https://app.dynamicauth.com';
5
- const DYNAMIC_AUTH_PREPROD_BASE_API_URL = 'https://app.dynamic-preprod.xyz';
6
- const DYNAMIC_AUTH_DEV_BASE_API_URL = 'http://localhost:4200';
7
6
  var ENVIRONMENT_ENUM = /*#__PURE__*/ function(ENVIRONMENT_ENUM) {
8
7
  ENVIRONMENT_ENUM["development"] = "development";
9
8
  ENVIRONMENT_ENUM["preprod"] = "preprod";
@@ -13,30 +12,40 @@ var ENVIRONMENT_ENUM = /*#__PURE__*/ function(ENVIRONMENT_ENUM) {
13
12
  const DynamicRequestIdHeader = 'x-dyn-request-id';
14
13
  const DynamicClientSessionSignature = 'x-dyn-client-session-signature';
15
14
  const DynamicMfaTokenHeader = 'x-mfa-auth-token';
16
- const DYNAMIC_CLIENT_RELAY_PROD_BASE_API_URL = 'https://waas-keyshares-relay.dynamicauth.com';
17
- const DYNAMIC_CLIENT_RELAY_PREPROD_BASE_API_URL = 'https://waas-keyshares-dynamic-preprod-xyz-app-32d15525a875.relay.evervault.app';
18
- const DYNAMIC_CLIENT_RELAY_DEV_BASE_API_URL = 'https://waas-keyshares-dynamic-preprod-xyz-app-32d15525a875.relay.evervault.app';
19
- const DYNAMIC_CLIENT_RELAY_PROD_REDCOAST_API_URL = 'https://app-dynamicauth-com-app-6e12fc400995.relay.evervault.app';
20
- const DYNAMIC_CLIENT_RELAY_PREPROD_REDCOAST_API_URL = 'https://app-dynamic-preprod-xyz-app-32d15525a875.relay.evervault.app';
21
- const DYNAMIC_CLIENT_RELAY_DEV_REDCOAST_API_URL = 'http://localhost:4200';
15
+ const DynamicForwardMPCHeader = 'x-forward-mpc-client';
16
+ const DynamicTraceIdHeader = 'x-dyn-trace-id';
17
+ const DynamicTraceElapsedTimeHeader = 'x-dyn-trace-elapsed-time';
18
+ /**
19
+ * Dynamic auth base API URL to redcoast API
20
+ * NOTE: For coookie auth, we should use the configured baseApiUrl
21
+ */ const DYNAMIC_AUTH_PROD_BASE_API_URL = 'https://app.dynamicauth.com';
22
+ const DYNAMIC_AUTH_PREPROD_BASE_API_URL = 'https://app.dynamic-preprod.xyz';
23
+ const DYNAMIC_AUTH_DEV_BASE_API_URL = 'http://localhost:4200';
22
24
  const DYNAMIC_AUTH_BASE_API_URL_MAP = {
23
25
  ["production"]: DYNAMIC_AUTH_PROD_BASE_API_URL,
24
26
  ["preprod"]: DYNAMIC_AUTH_PREPROD_BASE_API_URL,
25
27
  ["development"]: DYNAMIC_AUTH_DEV_BASE_API_URL
26
28
  };
27
- const DYNAMIC_CLIENT_USER_SHARE_RELAY_MAP = {
28
- ["production"]: DYNAMIC_CLIENT_RELAY_PROD_BASE_API_URL,
29
- ["preprod"]: DYNAMIC_CLIENT_RELAY_PREPROD_BASE_API_URL,
30
- ["development"]: DYNAMIC_CLIENT_RELAY_PREPROD_BASE_API_URL
31
- };
32
- const DYNAMIC_CLIENT_RELAY_REDCOAST_MAP = {
33
- ["production"]: DYNAMIC_CLIENT_RELAY_PROD_REDCOAST_API_URL,
34
- ["preprod"]: DYNAMIC_CLIENT_RELAY_PREPROD_REDCOAST_API_URL,
35
- ["development"]: DYNAMIC_CLIENT_RELAY_DEV_REDCOAST_API_URL
29
+ /**
30
+ * Evervault keyshare encryption relay
31
+ * Note: Not used for cookie auth, we use the configured baseKeyshareRelayApiUrl
32
+ */ const DYNAMIC_KEYSHARES_RELAY_PROD_BASE_API_URL = 'https://waas-keyshares-relay.dynamicauth.com';
33
+ const DYNAMIC_KEYSHARES_RELAY_PREPROD_BASE_API_URL = 'https://waas-keyshares-relay.dynamic-preprod.xyz';
34
+ const DYNAMIC_KEYSHARES_RELAY_MAP = {
35
+ ["production"]: DYNAMIC_KEYSHARES_RELAY_PROD_BASE_API_URL,
36
+ ["preprod"]: DYNAMIC_KEYSHARES_RELAY_PREPROD_BASE_API_URL,
37
+ ["development"]: DYNAMIC_KEYSHARES_RELAY_PREPROD_BASE_API_URL
36
38
  };
37
- const MPC_RELAY_PROD_API_URL = 'relay.dynamicauth.com';
39
+ /**
40
+ * Dymamic MPC relay where the MPC operations are performed (NOT keyshare relay in Evervault)
41
+ */ const MPC_RELAY_PROD_API_URL = 'relay.dynamicauth.com';
38
42
  const MPC_RELAY_PREPROD_API_URL = 'relay.dynamic-preprod.xyz';
39
43
  const MPC_RELAY_DEV_API_URL = 'http://localhost:4200';
44
+ const MPC_RELAY_URL_MAP = {
45
+ ["production"]: MPC_RELAY_PROD_API_URL,
46
+ ["preprod"]: MPC_RELAY_PREPROD_API_URL,
47
+ ["development"]: MPC_RELAY_DEV_API_URL
48
+ };
40
49
  const RELAY_APP_ID_HEADER = 'X-Evervault-App-Id';
41
50
  const PROD_RELAY_APP_ID = 'app_6e12fc400995';
42
51
  const PREPROD_RELAY_APP_ID = 'app_32d15525a875';
@@ -80,6 +89,7 @@ var BackupLocation = /*#__PURE__*/ function(BackupLocation) {
80
89
  BackupLocation["ICLOUD"] = "iCloud";
81
90
  BackupLocation["USER"] = "user";
82
91
  BackupLocation["EXTERNAL"] = "external";
92
+ BackupLocation["DELEGATED"] = "delegated";
83
93
  return BackupLocation;
84
94
  }({});
85
95
  const IFRAME_DOMAIN_MAP = {
@@ -101,7 +111,27 @@ const verifiedCredentialNameToChainEnum = {
101
111
  };
102
112
  const DELEGATED_SHARE_COUNT = 1;
103
113
  const FEATURE_FLAGS = {
104
- ENABLE_DELEGATED_KEY_SHARES_FLAG: 'enable-delegated-key-shares'
114
+ ENABLE_DELEGATED_KEY_SHARES_FLAG: 'enable-delegated-key-shares',
115
+ ENABLE_FORWARD_MPC_CLIENT_FLAG: 'enable-forward-mpc-client'
116
+ };
117
+ const DYNAMIC_FORWARD_MPC_PROD_ENCLAVE_URL = 'wss://forward-mpc-client-prod.app-bf095f298b04.enclave.evervault.com/ws';
118
+ const DYNAMIC_FORWARD_MPC_PREPROD_ENCLAVE_URL = 'wss://forward-mpc-client-preprod.app-560a39ebfe3b.enclave.evervault.com/ws';
119
+ const DYNAMIC_FORWARD_MPC_DEV_ENCLAVE_URL = 'ws://localhost:8008/ws';
120
+ const DYNAMIC_FORWARD_MPC_ENCLAVE_URL_MAP = {
121
+ ["production"]: DYNAMIC_FORWARD_MPC_PROD_ENCLAVE_URL,
122
+ ["preprod"]: DYNAMIC_FORWARD_MPC_PREPROD_ENCLAVE_URL,
123
+ ["development"]: DYNAMIC_FORWARD_MPC_DEV_ENCLAVE_URL
124
+ };
125
+ const DYNAMIC_FORWARD_MPC_ENCLAVE_ATTESTATION_CONFIG_MAP = {
126
+ ["production"]: {
127
+ expectedPcr8: '484fd412249304fe7659b2a9a4869504f0e4502d8abb4f88183e65416b4f62354e4eda60e80a5b2e9d730ab0d804f83e',
128
+ strictCertValidation: true
129
+ },
130
+ ["preprod"]: {
131
+ expectedPcr8: 'acc59ec98dbf7ecb43f9a6b9890866141868c079aa879e05e3675e1a10e187259a64951e72cc531541b02dbdcd780770',
132
+ strictCertValidation: true
133
+ },
134
+ ["development"]: undefined
105
135
  };
106
136
 
107
137
  var SigningAlgorithm = /*#__PURE__*/ function(SigningAlgorithm) {
@@ -443,7 +473,7 @@ const getDynamicServerThreshold = (thresholdSignatureScheme)=>{
443
473
  };
444
474
  const URL_PATTERNS = {
445
475
  [ENVIRONMENT_ENUM.development]: /^http:\/\/localhost:\d+$/,
446
- [ENVIRONMENT_ENUM.preprod]: /dynamic-preprod/,
476
+ [ENVIRONMENT_ENUM.preprod]: /-preprod/,
447
477
  [ENVIRONMENT_ENUM.production]: /^(?!.*dynamic-preprod)(?!http:\/\/localhost:\d+).*/
448
478
  };
449
479
  function getEnvironmentFromUrl(url) {
@@ -482,6 +512,9 @@ var SuccessEventType = /*#__PURE__*/ function(SuccessEventType) {
482
512
  return SuccessEventType;
483
513
  }({});
484
514
 
515
+ const getElapsedTime = (startTime)=>{
516
+ return startTime ? (Date.now() - startTime).toString() : undefined;
517
+ };
485
518
  /**
486
519
  * Creates a promise that resolves when a specific event is received from an event stream.
487
520
  * Adds a timeout to prevent hanging and races the two promises.
@@ -490,13 +523,16 @@ var SuccessEventType = /*#__PURE__*/ function(SuccessEventType) {
490
523
  * @param apiClient The axios instance to use for API calls
491
524
  * @param options The configuration options
492
525
  * @returns A promise that resolves with the event data or rejects on timeout
493
- */ const createEventStreamPromise = ({ apiClient, dynamicRequestId, endpoint, body, successEventType, timeoutMs = 30000, timeoutMessage, onError, onCeremonyComplete, mfaToken })=>{
526
+ */ const createEventStreamPromise = ({ apiClient, dynamicRequestId, endpoint, body, successEventType, timeoutMs = 30000, timeoutMessage, onError, onCeremonyComplete, mfaToken, forwardMPCClientEnabled, traceContext })=>{
494
527
  const headers = {
495
528
  Accept: 'text/event-stream',
496
529
  'Cache-Control': 'no-cache',
497
530
  Connection: 'keep-alive',
498
531
  [DynamicRequestIdHeader]: dynamicRequestId,
499
- [DynamicMfaTokenHeader]: mfaToken
532
+ [DynamicMfaTokenHeader]: mfaToken,
533
+ [DynamicForwardMPCHeader]: forwardMPCClientEnabled,
534
+ [DynamicTraceIdHeader]: traceContext == null ? void 0 : traceContext.traceId,
535
+ [DynamicTraceElapsedTimeHeader]: getElapsedTime(traceContext == null ? void 0 : traceContext.startTime)
500
536
  };
501
537
  // Create a promise that will resolve when the success event is received
502
538
  const eventPromise = new Promise((resolve, reject)=>{
@@ -636,8 +672,8 @@ class BaseClient {
636
672
  throw new Error('Failed to sync auth token, auth header is not set to the expected auth token after sync, there is likely a race condition, contact Dynamic devs to investigate');
637
673
  }
638
674
  }
639
- constructor({ environmentId, baseApiUrl, authToken, baseClientRelayApiUrl, authMode = AuthMode.HEADER, // Represents the version of the client SDK used by developer
640
- sdkVersion }){
675
+ constructor({ environmentId, baseApiUrl, authToken, baseClientKeysharesRelayApiUrl, authMode = AuthMode.HEADER, // Represents the version of the client SDK used by developer
676
+ sdkVersion, forwardMPCClient }){
641
677
  const headers = {};
642
678
  // Only set Authorization header if using header auth mode and token is provided
643
679
  if (authMode === AuthMode.HEADER && authToken) {
@@ -657,14 +693,28 @@ class BaseClient {
657
693
  withCredentials: true
658
694
  } : {});
659
695
  this.apiClient = axios.create(axiosConfig);
660
- this.clientRelayBaseApiUrl = baseClientRelayApiUrl != null ? baseClientRelayApiUrl : DYNAMIC_CLIENT_USER_SHARE_RELAY_MAP[environment];
696
+ this.clientKeysharesRelayBaseApiUrl = baseClientKeysharesRelayApiUrl != null ? baseClientKeysharesRelayApiUrl : DYNAMIC_KEYSHARES_RELAY_MAP[environment];
661
697
  this.clientRelayApiClient = axios.create({
662
- baseURL: this.clientRelayBaseApiUrl,
698
+ baseURL: this.clientKeysharesRelayBaseApiUrl,
663
699
  headers: _extends({}, headers, {
664
700
  [RELAY_API_KEY_HEADER]: DYNAMIC_CLIENT_RELAY_REDCOAST_API_KEY_MAP[environment],
665
701
  [RELAY_APP_ID_HEADER]: DYNAMIC_CLIENT_RELAY_REDCOAST_APP_ID_MAP[environment]
666
702
  })
667
703
  });
704
+ // Use provided ForwardMPCClient or create a new one
705
+ if (forwardMPCClient) {
706
+ this.forwardMPCClient = forwardMPCClient;
707
+ } else {
708
+ const forwardMPCEnclaveUrl = DYNAMIC_FORWARD_MPC_ENCLAVE_URL_MAP[environment];
709
+ const attestationConfig = DYNAMIC_FORWARD_MPC_ENCLAVE_ATTESTATION_CONFIG_MAP[environment];
710
+ this.forwardMPCClient = new ForwardMPCClient(forwardMPCEnclaveUrl != null ? forwardMPCEnclaveUrl : '', {
711
+ reconnectInterval: 5000,
712
+ reconnectAttempts: 5,
713
+ connectionTimeout: 10000,
714
+ heartbeatInterval: 30000,
715
+ attestationConfig
716
+ });
717
+ }
668
718
  }
669
719
  }
670
720
 
@@ -676,23 +726,26 @@ class DynamicApiClient extends BaseClient {
676
726
  }
677
727
  });
678
728
  }
679
- async createWalletAccount({ chainName, clientKeygenIds, dynamicRequestId, thresholdSignatureScheme, onError, onCeremonyComplete }) {
729
+ async createWalletAccount({ chainName, clientKeygenIds, dynamicRequestId, thresholdSignatureScheme, skipLock, onError, onCeremonyComplete, traceContext }) {
680
730
  return createEventStreamPromise({
681
731
  apiClient: this.apiClient,
682
732
  dynamicRequestId,
683
733
  endpoint: `/api/v0/sdk/${this.environmentId}/waas/create`,
684
- body: {
734
+ body: _extends({
685
735
  chain: chainName,
686
736
  clientKeygenIds,
687
737
  thresholdSignatureScheme
688
- },
738
+ }, skipLock ? {
739
+ skipLock
740
+ } : {}),
689
741
  successEventType: SuccessEventType.KeygenComplete,
690
742
  timeoutMessage: 'Wallet creation timed out',
691
743
  onError,
692
- onCeremonyComplete
744
+ onCeremonyComplete,
745
+ traceContext
693
746
  });
694
747
  }
695
- async signMessage({ dynamicRequestId, walletId, message, onError, isFormatted, mfaToken, context }) {
748
+ async signMessage({ dynamicRequestId, walletId, message, onError, isFormatted, mfaToken, roomId, context, forwardMPCClientEnabled, traceContext }) {
696
749
  return createEventStreamPromise({
697
750
  apiClient: this.apiClient,
698
751
  dynamicRequestId,
@@ -700,15 +753,18 @@ class DynamicApiClient extends BaseClient {
700
753
  body: {
701
754
  message,
702
755
  isFormatted,
703
- context
756
+ context,
757
+ roomId
704
758
  },
705
759
  successEventType: SuccessEventType.RoomCreated,
706
760
  timeoutMessage: 'Message signing timed out',
707
761
  onError,
708
- mfaToken
762
+ mfaToken,
763
+ forwardMPCClientEnabled,
764
+ traceContext
709
765
  });
710
766
  }
711
- async refreshWalletAccountShares({ dynamicRequestId, walletId, onError, mfaToken }) {
767
+ async refreshWalletAccountShares({ dynamicRequestId, walletId, onError, mfaToken, traceContext }) {
712
768
  return createEventStreamPromise({
713
769
  apiClient: this.apiClient,
714
770
  dynamicRequestId,
@@ -717,27 +773,30 @@ class DynamicApiClient extends BaseClient {
717
773
  successEventType: SuccessEventType.RoomCreated,
718
774
  timeoutMessage: 'Refresh timed out',
719
775
  onError,
720
- mfaToken
776
+ mfaToken,
777
+ traceContext
721
778
  });
722
779
  }
723
- async reshare({ walletId, dynamicRequestId, clientKeygenIds, oldThresholdSignatureScheme, newThresholdSignatureScheme, delegateToProjectEnvironment, mfaToken, onError }) {
780
+ async reshare({ walletId, dynamicRequestId, clientKeygenIds, oldThresholdSignatureScheme, newThresholdSignatureScheme, delegateToProjectEnvironment, revokeDelegation, mfaToken, onError, traceContext }) {
724
781
  return createEventStreamPromise({
725
782
  apiClient: this.apiClient,
726
783
  dynamicRequestId,
727
784
  endpoint: `/api/v0/sdk/${this.environmentId}/waas/${walletId}/reshare`,
728
785
  body: {
729
786
  clientKeygenIds,
730
- oldThresholdSignatureScheme,
787
+ delegateToProjectEnvironment,
731
788
  newThresholdSignatureScheme,
732
- delegateToProjectEnvironment
789
+ oldThresholdSignatureScheme,
790
+ revokeDelegation
733
791
  },
734
792
  successEventType: SuccessEventType.RoomCreated,
735
793
  timeoutMessage: 'Reshare timed out',
736
794
  onError,
737
- mfaToken
795
+ mfaToken,
796
+ traceContext
738
797
  });
739
798
  }
740
- async exportKey({ mfaToken, dynamicRequestId, walletId, exportId, onError }) {
799
+ async exportKey({ mfaToken, dynamicRequestId, walletId, exportId, onError, traceContext }) {
741
800
  return createEventStreamPromise({
742
801
  apiClient: this.apiClient,
743
802
  dynamicRequestId,
@@ -748,18 +807,45 @@ class DynamicApiClient extends BaseClient {
748
807
  successEventType: SuccessEventType.RoomCreated,
749
808
  timeoutMessage: 'Key export timed out',
750
809
  onError,
751
- mfaToken
810
+ mfaToken,
811
+ traceContext
752
812
  });
753
813
  }
754
- async storeEncryptedBackupByWallet({ walletId, encryptedKeyShares, passwordEncrypted, signedSessionId, encryptionVersion, requiresSignedSessionId = false, authMode = AuthMode.HEADER, dynamicRequestId }) {
814
+ async getDelegatedEncryptionKey({ environmentId, traceContext }) {
815
+ const { data } = await this.apiClient.get(`/api/v0/sdk/${environmentId}/waas/delegatedAccess/encryptionPublicKey`, {
816
+ headers: {
817
+ [DynamicRequestIdHeader]: v4().replace('-', ''),
818
+ [DynamicTraceIdHeader]: traceContext == null ? void 0 : traceContext.traceId,
819
+ [DynamicTraceElapsedTimeHeader]: getElapsedTime(traceContext == null ? void 0 : traceContext.startTime)
820
+ }
821
+ });
822
+ return data;
823
+ }
824
+ async publishDelegatedKeyShare({ walletId, encryptedKeyShare, signedSessionId, requiresSignedSessionId = false, dynamicRequestId, traceContext }) {
825
+ if (requiresSignedSessionId && !signedSessionId) {
826
+ throw new Error('Signed session ID is required');
827
+ }
828
+ const apiClient = this.apiClient;
829
+ const { data, status } = await apiClient.post(`/api/v0/sdk/${this.environmentId}/waas/${walletId}/delegatedAccess/delivery`, {
830
+ encryptedDelegatedShare: encryptedKeyShare
831
+ }, {
832
+ headers: {
833
+ [DynamicRequestIdHeader]: dynamicRequestId,
834
+ [DynamicClientSessionSignature]: signedSessionId,
835
+ [DynamicTraceIdHeader]: traceContext == null ? void 0 : traceContext.traceId,
836
+ [DynamicTraceElapsedTimeHeader]: getElapsedTime(traceContext == null ? void 0 : traceContext.startTime)
837
+ }
838
+ });
839
+ return {
840
+ data,
841
+ status
842
+ };
843
+ }
844
+ async storeEncryptedBackupByWallet({ walletId, encryptedKeyShares, passwordEncrypted, signedSessionId, encryptionVersion, requiresSignedSessionId = false, authMode = AuthMode.HEADER, dynamicRequestId, traceContext }) {
755
845
  if (requiresSignedSessionId && !signedSessionId) {
756
846
  throw new Error('Signed session ID is required');
757
847
  }
758
- // When using cookie-based authentication, use the main apiClient instead of clientRelayApiClient.
759
- // This ensures requests are sent to the same domain, allowing cookies to be included and maintaining session continuity.
760
- // For header-based auth, clientRelayApiClient is used as usual.
761
- const apiClient = authMode === AuthMode.COOKIE ? this.apiClient : this.clientRelayApiClient;
762
- const { data } = await apiClient.post(`/api/v0/sdk/${this.environmentId}/waas/${walletId}/keyShares/backup`, {
848
+ const { data } = await this.clientRelayApiClient.post(`/api/v0/sdk/${this.environmentId}/waas/${walletId}/keyShares/backup`, {
763
849
  // TODO: decide on whether to store encryptedAccountCredentials or encryptedKeyShares as backup
764
850
  encryptedAccountCredentials: encryptedKeyShares,
765
851
  passwordEncrypted,
@@ -767,11 +853,15 @@ class DynamicApiClient extends BaseClient {
767
853
  }, {
768
854
  headers: {
769
855
  [DynamicRequestIdHeader]: dynamicRequestId,
770
- [DynamicClientSessionSignature]: signedSessionId
771
- }
856
+ [DynamicClientSessionSignature]: signedSessionId,
857
+ [DynamicTraceIdHeader]: traceContext == null ? void 0 : traceContext.traceId,
858
+ [DynamicTraceElapsedTimeHeader]: getElapsedTime(traceContext == null ? void 0 : traceContext.startTime)
859
+ },
860
+ withCredentials: authMode === AuthMode.COOKIE ? true : undefined
772
861
  });
773
862
  return data;
774
863
  }
864
+ // TODO: is this still used? if not, remove it
775
865
  async markKeySharesAsBackedUpGoogleDrive({ walletId }) {
776
866
  const { data } = await this.clientRelayApiClient.post(`/api/v0/sdk/${this.environmentId}/waas/${walletId}/keyShares/backup/googleDrive`, {}, {
777
867
  headers: {
@@ -780,46 +870,49 @@ class DynamicApiClient extends BaseClient {
780
870
  });
781
871
  return data;
782
872
  }
783
- async markKeySharesAsBackedUp({ walletId, locations, dynamicRequestId }) {
873
+ async markKeySharesAsBackedUp({ walletId, locations, dynamicRequestId, traceContext }) {
784
874
  const { data } = await this.apiClient.post(`/api/v0/sdk/${this.environmentId}/waas/${walletId}/keyShares/backup/locations`, {
785
875
  locations
786
876
  }, {
787
877
  headers: {
788
- [DynamicRequestIdHeader]: dynamicRequestId
878
+ [DynamicRequestIdHeader]: dynamicRequestId,
879
+ [DynamicTraceIdHeader]: traceContext == null ? void 0 : traceContext.traceId,
880
+ [DynamicTraceElapsedTimeHeader]: getElapsedTime(traceContext == null ? void 0 : traceContext.startTime)
789
881
  }
790
882
  });
791
883
  return data;
792
884
  }
793
- async recoverEncryptedBackupByWallet({ walletId, keyShareIds, signedSessionId, mfaToken, requiresSignedSessionId = false, authMode = AuthMode.HEADER }) {
885
+ async recoverEncryptedBackupByWallet({ walletId, keyShareIds, signedSessionId, mfaToken, requiresSignedSessionId = false, authMode = AuthMode.HEADER, traceContext }) {
794
886
  if (requiresSignedSessionId && !signedSessionId) {
795
887
  throw new Error('Signed session ID is required');
796
888
  }
797
- // When using cookie-based authentication, use the main apiClient instead of clientRelayApiClient.
798
- // This ensures requests are sent to the same domain, allowing cookies to be included and maintaining session continuity.
799
- // For header-based auth, clientRelayApiClient is used as usual.
800
- const apiClient = authMode === AuthMode.COOKIE ? this.apiClient : this.clientRelayApiClient;
801
889
  // TODO: add signed messsage to body?
802
- const { data } = await apiClient.post(`/api/v0/sdk/${this.environmentId}/waas/${walletId}/keyShares/recover`, keyShareIds ? {
890
+ const { data } = await this.clientRelayApiClient.post(`/api/v0/sdk/${this.environmentId}/waas/${walletId}/keyShares/recover`, keyShareIds ? {
803
891
  keyShareIds
804
892
  } : undefined, {
805
893
  headers: {
806
894
  [DynamicRequestIdHeader]: v4().replace('-', ''),
807
895
  [DynamicClientSessionSignature]: signedSessionId,
808
- [DynamicMfaTokenHeader]: mfaToken
809
- }
896
+ [DynamicMfaTokenHeader]: mfaToken,
897
+ [DynamicTraceIdHeader]: traceContext == null ? void 0 : traceContext.traceId,
898
+ [DynamicTraceElapsedTimeHeader]: getElapsedTime(traceContext == null ? void 0 : traceContext.startTime)
899
+ },
900
+ withCredentials: authMode === AuthMode.COOKIE ? true : undefined
810
901
  });
811
902
  return data;
812
903
  }
813
- async getAccessToken({ oauthAccountId }) {
904
+ async getAccessToken({ oauthAccountId, traceContext }) {
814
905
  const { data } = await this.apiClient.get(`/api/v0/sdk/${this.environmentId}/oauthAccounts/${oauthAccountId}/accessToken`, {
815
906
  headers: {
816
- [DynamicRequestIdHeader]: v4().replace('-', '')
907
+ [DynamicRequestIdHeader]: v4().replace('-', ''),
908
+ [DynamicTraceIdHeader]: traceContext == null ? void 0 : traceContext.traceId,
909
+ [DynamicTraceElapsedTimeHeader]: getElapsedTime(traceContext == null ? void 0 : traceContext.startTime)
817
910
  }
818
911
  });
819
912
  return data.accessToken;
820
913
  }
821
914
  // TODO: return array instead considering cases where server has multiple parties
822
- async importPrivateKey({ chainName, dynamicRequestId, clientKeygenIds, thresholdSignatureScheme, onError, onCeremonyComplete }) {
915
+ async importPrivateKey({ chainName, dynamicRequestId, clientKeygenIds, thresholdSignatureScheme, onError, onCeremonyComplete, traceContext }) {
823
916
  return createEventStreamPromise({
824
917
  apiClient: this.apiClient,
825
918
  dynamicRequestId,
@@ -832,11 +925,12 @@ class DynamicApiClient extends BaseClient {
832
925
  successEventType: SuccessEventType.KeygenComplete,
833
926
  timeoutMessage: 'Key import timed out',
834
927
  onError,
835
- onCeremonyComplete
928
+ onCeremonyComplete,
929
+ traceContext
836
930
  });
837
931
  }
838
932
  // TODO: consider removing the retry logics if we switch to server-sent events
839
- async getUser(dynamicRequestId) {
933
+ async getUser(dynamicRequestId, traceContext) {
840
934
  let attempts = 0;
841
935
  const maxAttempts = 5;
842
936
  const retryInterval = 1000; // 1 second interval for each retry
@@ -844,7 +938,9 @@ class DynamicApiClient extends BaseClient {
844
938
  try {
845
939
  const { data } = await this.apiClient.get(`/api/v0/sdk/${this.environmentId}/users`, {
846
940
  headers: {
847
- [DynamicRequestIdHeader]: dynamicRequestId
941
+ [DynamicRequestIdHeader]: dynamicRequestId,
942
+ [DynamicTraceIdHeader]: traceContext == null ? void 0 : traceContext.traceId,
943
+ [DynamicTraceElapsedTimeHeader]: getElapsedTime(traceContext == null ? void 0 : traceContext.startTime)
848
944
  }
849
945
  });
850
946
  return data;
@@ -858,7 +954,7 @@ class DynamicApiClient extends BaseClient {
858
954
  }
859
955
  }
860
956
  // TODO: consider removing the retry logics if we switch to server-sent events
861
- async refreshUser() {
957
+ async refreshUser(traceContext) {
862
958
  let attempts = 0;
863
959
  const maxAttempts = 5;
864
960
  const retryInterval = 1000; // 1 second interval for each retry
@@ -866,7 +962,9 @@ class DynamicApiClient extends BaseClient {
866
962
  try {
867
963
  const { data } = await this.apiClient.post(`/api/v0/sdk/${this.environmentId}/refresh`, undefined, {
868
964
  headers: {
869
- [DynamicRequestIdHeader]: v4().replace('-', '')
965
+ [DynamicRequestIdHeader]: v4().replace('-', ''),
966
+ [DynamicTraceIdHeader]: traceContext == null ? void 0 : traceContext.traceId,
967
+ [DynamicTraceElapsedTimeHeader]: getElapsedTime(traceContext == null ? void 0 : traceContext.startTime)
870
968
  }
871
969
  });
872
970
  return data;
@@ -879,22 +977,92 @@ class DynamicApiClient extends BaseClient {
879
977
  }
880
978
  }
881
979
  }
882
- async getEnvironmentSettings() {
980
+ async getEnvironmentSettings(traceContext) {
883
981
  const { data } = await this.apiClient.get(`/api/v0/sdk/${this.environmentId}/settings`, {
884
982
  headers: {
885
- [DynamicRequestIdHeader]: v4().replace('-', '')
983
+ [DynamicRequestIdHeader]: v4().replace('-', ''),
984
+ [DynamicTraceIdHeader]: traceContext == null ? void 0 : traceContext.traceId,
985
+ [DynamicTraceElapsedTimeHeader]: getElapsedTime(traceContext == null ? void 0 : traceContext.startTime)
986
+ }
987
+ });
988
+ return data;
989
+ }
990
+ async getWaasWalletById({ walletId, traceContext }) {
991
+ const { data } = await this.apiClient.get(`/api/v0/environments/${this.environmentId}/waas/${walletId}`, {
992
+ headers: {
993
+ [DynamicRequestIdHeader]: v4().replace('-', ''),
994
+ [DynamicTraceIdHeader]: traceContext == null ? void 0 : traceContext.traceId,
995
+ [DynamicTraceElapsedTimeHeader]: getElapsedTime(traceContext == null ? void 0 : traceContext.startTime)
996
+ }
997
+ });
998
+ return data;
999
+ }
1000
+ /**
1001
+ * Fetch a single WaaS wallet by ID using the /sdk/{environmentId}/waas/{walletId} endpoint.
1002
+ * This endpoint returns user information with verified credentials filtered to only include the specified WaaS wallet.
1003
+ */ async getWaasWalletByAddress({ walletAddress, traceContext }) {
1004
+ const { data } = await this.apiClient.get(`/api/v0/sdk/${this.environmentId}/waas/byWalletAddress/${walletAddress}`, {
1005
+ headers: {
1006
+ [DynamicRequestIdHeader]: v4().replace('-', ''),
1007
+ [DynamicTraceIdHeader]: traceContext == null ? void 0 : traceContext.traceId,
1008
+ [DynamicTraceElapsedTimeHeader]: getElapsedTime(traceContext == null ? void 0 : traceContext.startTime)
1009
+ }
1010
+ });
1011
+ return data;
1012
+ }
1013
+ async delegatedSignMessage({ walletId, message, isFormatted, dynamicRequestId, onError, context, traceContext }) {
1014
+ return createEventStreamPromise({
1015
+ apiClient: this.apiClient,
1016
+ dynamicRequestId,
1017
+ endpoint: `/api/v0/environments/${this.environmentId}/waas/${walletId}/delegatedAccess/signMessage`,
1018
+ body: {
1019
+ message,
1020
+ isFormatted,
1021
+ context
1022
+ },
1023
+ successEventType: SuccessEventType.RoomCreated,
1024
+ timeoutMessage: 'Delegated sign message timed out',
1025
+ onError,
1026
+ traceContext
1027
+ });
1028
+ }
1029
+ async createRooms({ walletId, roomType, roomCount = 5, traceContext }) {
1030
+ const { data } = await this.apiClient.post(`/api/v0/sdk/${this.environmentId}/waas/${walletId}/createRooms`, {
1031
+ roomCount,
1032
+ roomType
1033
+ }, {
1034
+ headers: {
1035
+ [DynamicRequestIdHeader]: v4().replace('-', ''),
1036
+ [DynamicTraceIdHeader]: traceContext == null ? void 0 : traceContext.traceId,
1037
+ [DynamicTraceElapsedTimeHeader]: getElapsedTime(traceContext == null ? void 0 : traceContext.startTime)
1038
+ }
1039
+ });
1040
+ return data;
1041
+ }
1042
+ async createRoomsWithoutWalletId({ roomType, thresholdSignatureScheme, roomCount = 5, traceContext }) {
1043
+ const { data } = await this.apiClient.post(`/api/v0/sdk/${this.environmentId}/waas/createRooms`, {
1044
+ roomCount,
1045
+ roomType,
1046
+ thresholdSignatureScheme
1047
+ }, {
1048
+ headers: {
1049
+ [DynamicRequestIdHeader]: v4().replace('-', ''),
1050
+ [DynamicTraceIdHeader]: traceContext == null ? void 0 : traceContext.traceId,
1051
+ [DynamicTraceElapsedTimeHeader]: getElapsedTime(traceContext == null ? void 0 : traceContext.startTime)
886
1052
  }
887
1053
  });
888
1054
  return data;
889
1055
  }
890
1056
  constructor({ environmentId, authToken, baseApiUrl, authMode = AuthMode.HEADER, // Represents the version of the client SDK used by developer
891
- sdkVersion }){
1057
+ sdkVersion, forwardMPCClient, baseClientKeysharesRelayApiUrl }){
892
1058
  super({
893
1059
  environmentId,
894
1060
  authToken: authToken || '',
895
1061
  baseApiUrl,
896
1062
  authMode,
897
- sdkVersion
1063
+ sdkVersion,
1064
+ forwardMPCClient,
1065
+ baseClientKeysharesRelayApiUrl
898
1066
  });
899
1067
  }
900
1068
  }
@@ -964,4 +1132,46 @@ const SDK_NAMESPACE = {
964
1132
  return parsed ? parsed.namespace : null;
965
1133
  }
966
1134
 
967
- export { AuthMode, BITCOIN_DERIVATION_PATHS, BackupLocation, CreateRoomPartiesOptions, DELEGATED_SHARE_COUNT, DYNAMIC_AUTH_BASE_API_URL_MAP, DYNAMIC_AUTH_DEV_BASE_API_URL, DYNAMIC_AUTH_PREPROD_BASE_API_URL, DYNAMIC_AUTH_PROD_BASE_API_URL, DYNAMIC_CLIENT_RELAY_DEV_BASE_API_URL, DYNAMIC_CLIENT_RELAY_DEV_REDCOAST_API_URL, DYNAMIC_CLIENT_RELAY_PREPROD_BASE_API_URL, DYNAMIC_CLIENT_RELAY_PREPROD_REDCOAST_API_URL, DYNAMIC_CLIENT_RELAY_PROD_BASE_API_URL, DYNAMIC_CLIENT_RELAY_PROD_REDCOAST_API_URL, DYNAMIC_CLIENT_RELAY_REDCOAST_API_KEY_MAP, DYNAMIC_CLIENT_RELAY_REDCOAST_APP_ID_MAP, DYNAMIC_CLIENT_RELAY_REDCOAST_MAP, DYNAMIC_CLIENT_USER_SHARE_RELAY_MAP, DynamicApiClient, DynamicClientSessionSignature, DynamicMfaTokenHeader, DynamicRequestIdHeader, ENVIRONMENT_ENUM, FEATURE_FLAGS, IFRAME_DOMAIN_MAP, MPC_CHAIN_CONFIG, MPC_CONFIG, MPC_RELAY_DEV_API_URL, MPC_RELAY_PREPROD_API_URL, MPC_RELAY_PROD_API_URL, PREPROD_RELAY_API_KEY, PREPROD_RELAY_APP_ID, PROD_RELAY_API_KEY, PROD_RELAY_APP_ID, RELAY_API_KEY_HEADER, RELAY_APP_ID_HEADER, SDK_NAMESPACE, SOLANA_RPC_URL, SigningAlgorithm, SuccessEventType, ThresholdSignatureScheme, URL_PATTERNS, WalletOperation, chain, chainEnumToVerifiedCredentialName, formatNamespacedVersion, getClientThreshold, getDynamicServerThreshold, getEnvironmentFromUrl, getMPCChainConfig, getReshareConfig, getServerWalletReshareConfig, getTSSConfig, getVersionNamespace, getVersionWithoutNamespace, parseNamespacedVersion, verifiedCredentialNameToChainEnum };
1135
+ const serializeMessageForForwardMPC = ({ message, isFormatted = false, chainName })=>{
1136
+ let serializedMessage = message;
1137
+ if (isFormatted && chainName === 'EVM') {
1138
+ if (typeof message === 'string') {
1139
+ // Handle hex string (with or without 0x prefix)
1140
+ const cleanHex = message.startsWith('0x') ? message.slice(2) : message;
1141
+ serializedMessage = cleanHex;
1142
+ } else if (message instanceof Uint8Array) {
1143
+ serializedMessage = Buffer.from(message).toString('hex');
1144
+ } else if (message instanceof MessageHash) {
1145
+ serializedMessage = message.toHex();
1146
+ } else {
1147
+ throw new Error('Unsupported formatted message format');
1148
+ }
1149
+ }
1150
+ return serializedMessage;
1151
+ };
1152
+
1153
+ const handleAxiosError = (error, message, context, logger)=>{
1154
+ var _error_response, _error_response1, _error_response2;
1155
+ logger.error('[DynamicWaasWalletClient] Axios error: ', {
1156
+ message,
1157
+ error: (_error_response = error.response) == null ? void 0 : _error_response.data,
1158
+ status: (_error_response1 = error.response) == null ? void 0 : _error_response1.status,
1159
+ context
1160
+ });
1161
+ switch((_error_response2 = error.response) == null ? void 0 : _error_response2.status){
1162
+ case 400:
1163
+ throw createHttpError(400, 'Invalid request');
1164
+ case 401:
1165
+ throw createHttpError(401, 'Authorization header or cookie is required');
1166
+ case 403:
1167
+ throw createHttpError(403, 'Forbidden');
1168
+ case 422:
1169
+ throw createHttpError(422, 'Unprocessable content');
1170
+ case 500:
1171
+ throw createHttpError(500, 'Internal server error');
1172
+ default:
1173
+ throw createHttpError(500, 'Internal server error');
1174
+ }
1175
+ };
1176
+
1177
+ export { AuthMode, BITCOIN_DERIVATION_PATHS, BackupLocation, CreateRoomPartiesOptions, DELEGATED_SHARE_COUNT, DYNAMIC_AUTH_BASE_API_URL_MAP, DYNAMIC_AUTH_DEV_BASE_API_URL, DYNAMIC_AUTH_PREPROD_BASE_API_URL, DYNAMIC_AUTH_PROD_BASE_API_URL, DYNAMIC_CLIENT_RELAY_REDCOAST_API_KEY_MAP, DYNAMIC_CLIENT_RELAY_REDCOAST_APP_ID_MAP, DYNAMIC_FORWARD_MPC_DEV_ENCLAVE_URL, DYNAMIC_FORWARD_MPC_ENCLAVE_ATTESTATION_CONFIG_MAP, DYNAMIC_FORWARD_MPC_ENCLAVE_URL_MAP, DYNAMIC_FORWARD_MPC_PREPROD_ENCLAVE_URL, DYNAMIC_FORWARD_MPC_PROD_ENCLAVE_URL, DYNAMIC_KEYSHARES_RELAY_MAP, DYNAMIC_KEYSHARES_RELAY_PREPROD_BASE_API_URL, DYNAMIC_KEYSHARES_RELAY_PROD_BASE_API_URL, DynamicApiClient, DynamicClientSessionSignature, DynamicForwardMPCHeader, DynamicMfaTokenHeader, DynamicRequestIdHeader, DynamicTraceElapsedTimeHeader, DynamicTraceIdHeader, ENVIRONMENT_ENUM, FEATURE_FLAGS, IFRAME_DOMAIN_MAP, MPC_CHAIN_CONFIG, MPC_CONFIG, MPC_RELAY_DEV_API_URL, MPC_RELAY_PREPROD_API_URL, MPC_RELAY_PROD_API_URL, MPC_RELAY_URL_MAP, PREPROD_RELAY_API_KEY, PREPROD_RELAY_APP_ID, PROD_RELAY_API_KEY, PROD_RELAY_APP_ID, RELAY_API_KEY_HEADER, RELAY_APP_ID_HEADER, SDK_NAMESPACE, SOLANA_RPC_URL, SigningAlgorithm, SuccessEventType, ThresholdSignatureScheme, URL_PATTERNS, WalletOperation, chain, chainEnumToVerifiedCredentialName, formatNamespacedVersion, getClientThreshold, getDynamicServerThreshold, getEnvironmentFromUrl, getMPCChainConfig, getReshareConfig, getServerWalletReshareConfig, getTSSConfig, getVersionNamespace, getVersionWithoutNamespace, handleAxiosError, parseNamespacedVersion, serializeMessageForForwardMPC, verifiedCredentialNameToChainEnum };
package/package.json CHANGED
@@ -1,12 +1,15 @@
1
1
  {
2
2
  "name": "@dynamic-labs-wallet/core",
3
- "version": "0.0.0-pr384.2",
3
+ "version": "0.0.0-pr526.0",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "dependencies": {
7
- "axios": "1.9.0",
8
- "uuid": "11.1.0",
9
- "@dynamic-labs/sdk-api-core": "^0.0.764"
7
+ "@dynamic-labs-wallet/forward-mpc-client": "0.1.3",
8
+ "@dynamic-labs/logger": "^4.25.3",
9
+ "@dynamic-labs/sdk-api-core": "^0.0.828",
10
+ "axios": "1.13.2",
11
+ "http-errors": "2.0.0",
12
+ "uuid": "11.1.0"
10
13
  },
11
14
  "files": [
12
15
  "*",
@@ -31,5 +34,8 @@
31
34
  "require": "./index.cjs.js",
32
35
  "default": "./index.esm.js"
33
36
  }
37
+ },
38
+ "devDependencies": {
39
+ "@types/http-errors": "^2.0.0"
34
40
  }
35
41
  }