@dynamic-labs-wallet/node 0.0.0-pr384.2 → 0.0.0-pr534.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.
Files changed (58) hide show
  1. package/index.cjs.js +530 -90
  2. package/index.esm.js +527 -94
  3. package/internal/core/bip340.cjs +1 -0
  4. package/internal/core/bip340.d.ts +1 -1
  5. package/internal/core/common.cjs +1 -0
  6. package/internal/core/common.d.ts +1 -0
  7. package/internal/core/ecdsa.cjs +1 -0
  8. package/internal/core/ecdsa.d.ts +1 -1
  9. package/internal/core/ed25519.cjs +1 -0
  10. package/internal/core/ed25519_exportable.cjs +1 -0
  11. package/internal/core/ed25519_exportable.d.ts +0 -1
  12. package/internal/core/index.cjs +1 -0
  13. package/internal/core/native.d.ts +2 -2
  14. package/internal/core/sr25519.cjs +1 -0
  15. package/internal/core/types.cjs +1 -0
  16. package/internal/node/index.cjs +1 -0
  17. package/internal/node/index.d.ts +1 -1
  18. package/internal/node/native/libmpc_executor_linux_arm64_nodejs.node +0 -0
  19. package/internal/node/native/libmpc_executor_linux_x86_64_nodejs.node +0 -0
  20. package/internal/node/native/libmpc_executor_macos_arm64_nodejs.node +0 -0
  21. package/internal/node/native/libmpc_executor_macos_x86_64_nodejs.node +0 -0
  22. package/internal/node/native.cjs +1 -0
  23. package/internal/node/native.d.ts +1 -1
  24. package/package.json +6 -4
  25. package/src/client.d.ts +56 -17
  26. package/src/client.d.ts.map +1 -1
  27. package/src/core/createCore.d.ts +25 -0
  28. package/src/core/createCore.d.ts.map +1 -0
  29. package/src/core/types.d.ts +7 -0
  30. package/src/core/types.d.ts.map +1 -0
  31. package/src/delegatedClient/createDelegatedClient.d.ts +23 -0
  32. package/src/delegatedClient/createDelegatedClient.d.ts.map +1 -0
  33. package/src/delegatedClient/index.d.ts +7 -0
  34. package/src/delegatedClient/index.d.ts.map +1 -0
  35. package/src/delegatedClient/modules/decryptWebhookData.d.ts +18 -0
  36. package/src/delegatedClient/modules/decryptWebhookData.d.ts.map +1 -0
  37. package/src/delegatedClient/modules/revokeDelegation.d.ts +3 -0
  38. package/src/delegatedClient/modules/revokeDelegation.d.ts.map +1 -0
  39. package/src/delegatedClient/modules/sign.d.ts +31 -0
  40. package/src/delegatedClient/modules/sign.d.ts.map +1 -0
  41. package/src/index.d.ts +4 -1
  42. package/src/index.d.ts.map +1 -1
  43. package/src/types.d.ts +3 -0
  44. package/src/types.d.ts.map +1 -1
  45. package/src/utils.d.ts.map +1 -1
  46. package/internal/core/bip340.js +0 -1
  47. package/internal/core/common.js +0 -1
  48. package/internal/core/ecdsa.js +0 -1
  49. package/internal/core/ed25519.js +0 -1
  50. package/internal/core/ed25519_exportable.js +0 -1
  51. package/internal/core/index.js +0 -1
  52. package/internal/core/package.json +0 -17
  53. package/internal/core/sr25519.js +0 -1
  54. package/internal/core/types.js +0 -1
  55. package/internal/node/index.js +0 -1
  56. package/internal/node/native.js +0 -1
  57. package/internal/node/package.json +0 -17
  58. /package/internal/core/{native.js → native.cjs} +0 -0
package/index.cjs.js CHANGED
@@ -4,8 +4,9 @@ var core$1 = require('#internal/core');
4
4
  var core = require('@dynamic-labs-wallet/core');
5
5
  var node = require('#internal/node');
6
6
  var uuid = require('uuid');
7
- var logger$1 = require('@dynamic-labs/logger');
8
7
  var crypto = require('crypto');
8
+ var logger$1 = require('@dynamic-labs/logger');
9
+ require('node:crypto');
9
10
 
10
11
  // Removed duplicate exports - these are already exported from #internal/core
11
12
  const getMPCSignatureScheme = ({ signingAlgorithm, baseRelayUrl = core.MPC_RELAY_PROD_API_URL })=>{
@@ -68,7 +69,8 @@ const getExternalServerKeyShareBackupInfo = (params)=>{
68
69
  [core.BackupLocation.GOOGLE_DRIVE]: [],
69
70
  [core.BackupLocation.ICLOUD]: [],
70
71
  [core.BackupLocation.USER]: [],
71
- [core.BackupLocation.EXTERNAL]: []
72
+ [core.BackupLocation.EXTERNAL]: [],
73
+ [core.BackupLocation.DELEGATED]: []
72
74
  };
73
75
  if (!(params == null ? void 0 : (_params_walletProperties = params.walletProperties) == null ? void 0 : _params_walletProperties.keyShares)) {
74
76
  return {
@@ -80,7 +82,8 @@ const getExternalServerKeyShareBackupInfo = (params)=>{
80
82
  if (backups[keyShare.backupLocation]) {
81
83
  backups[keyShare.backupLocation].push({
82
84
  location: keyShare.backupLocation,
83
- keyShareId: keyShare.id
85
+ keyShareId: keyShare.id,
86
+ passwordEncrypted: keyShare.passwordEncrypted
84
87
  });
85
88
  }
86
89
  });
@@ -239,7 +242,7 @@ const getKey = async ({ password, salt, encryptionConfig })=>{
239
242
  cipher: bytesToBase64(new Uint8Array(encryptedData)),
240
243
  version
241
244
  };
242
- } catch (error) {
245
+ } catch (e) {
243
246
  throw new Error('Error encrypting data');
244
247
  }
245
248
  };
@@ -283,6 +286,16 @@ const getKey = async ({ password, salt, encryptionConfig })=>{
283
286
  const DEFAULT_LOG_LEVEL = 'INFO';
284
287
 
285
288
  class DynamicWalletClient {
289
+ async initializeForwardMPCClient() {
290
+ try {
291
+ await this.apiClient.forwardMPCClient.ensureWsConnection();
292
+ } catch (error) {
293
+ this.logger.error('Error connecting to ForwardMPC enclave websocket. Environment: ' + this.environmentId, {
294
+ error,
295
+ environmentId: this.environmentId
296
+ });
297
+ }
298
+ }
286
299
  ensureApiClientAuthenticated() {
287
300
  if (!this.isApiClientAuthenticated) {
288
301
  throw new Error('Client must be authenticated before making API calls. Call authenticateApiToken first.');
@@ -306,7 +319,7 @@ class DynamicWalletClient {
306
319
  });
307
320
  this.isApiClientAuthenticated = true;
308
321
  }
309
- async dynamicServerInitializeKeyGen({ chainName, externalServerKeygenIds, thresholdSignatureScheme, dynamicRequestId, onError, onCeremonyComplete }) {
322
+ async dynamicServerInitializeKeyGen({ chainName, externalServerKeygenIds, thresholdSignatureScheme, dynamicRequestId, skipLock, onError, onCeremonyComplete }) {
310
323
  this.ensureApiClientAuthenticated();
311
324
  try {
312
325
  const data = await this.apiClient.createWalletAccount({
@@ -314,6 +327,7 @@ class DynamicWalletClient {
314
327
  clientKeygenIds: externalServerKeygenIds,
315
328
  thresholdSignatureScheme,
316
329
  dynamicRequestId,
330
+ skipLock,
317
331
  onError,
318
332
  onCeremonyComplete
319
333
  });
@@ -400,7 +414,7 @@ class DynamicWalletClient {
400
414
  throw new Error('Error deriving public key in externalServerKeyGen');
401
415
  }
402
416
  }
403
- async keyGen({ chainName, thresholdSignatureScheme, onError, onCeremonyComplete }) {
417
+ async keyGen({ chainName, thresholdSignatureScheme, skipLock, onError, onCeremonyComplete }) {
404
418
  const dynamicRequestId = uuid.v4();
405
419
  try {
406
420
  const externalServerInitKeygenResults = await this.externalServerInitializeKeyGen({
@@ -413,6 +427,7 @@ class DynamicWalletClient {
413
427
  externalServerKeygenIds,
414
428
  dynamicRequestId,
415
429
  thresholdSignatureScheme,
430
+ skipLock,
416
431
  onCeremonyComplete
417
432
  });
418
433
  const { rawPublicKey, externalServerKeyGenResults } = await this.externalServerKeyGen({
@@ -480,7 +495,7 @@ class DynamicWalletClient {
480
495
  externalServerKeyShares: externalServerKeygenResults
481
496
  };
482
497
  }
483
- async dynamicServerSign({ walletId, message, isFormatted }) {
498
+ async dynamicServerSign({ walletId, message, isFormatted, context, onError }) {
484
499
  const dynamicRequestId = uuid.v4();
485
500
  this.ensureApiClientAuthenticated();
486
501
  // Create the room and sign the message
@@ -491,7 +506,10 @@ class DynamicWalletClient {
491
506
  walletId,
492
507
  message,
493
508
  isFormatted,
494
- dynamicRequestId
509
+ dynamicRequestId,
510
+ context: context ? JSON.parse(JSON.stringify(context, (_key, value)=>typeof value === 'bigint' ? value.toString() : value)) : undefined,
511
+ onError,
512
+ forwardMPCClientEnabled: this.forwardMPCEnabled
495
513
  });
496
514
  return data;
497
515
  }
@@ -509,38 +527,102 @@ class DynamicWalletClient {
509
527
  throw error;
510
528
  }
511
529
  }
512
- async sign({ accountAddress, externalServerKeyShares, message, chainName, password = undefined, isFormatted = false }) {
513
- await this.verifyPassword({
514
- accountAddress,
515
- password,
516
- walletOperation: core.WalletOperation.SIGN_MESSAGE
517
- });
518
- const wallet = await this.getWallet({
519
- accountAddress,
520
- walletOperation: core.WalletOperation.SIGN_MESSAGE,
521
- password
522
- });
523
- externalServerKeyShares = externalServerKeyShares != null ? externalServerKeyShares : wallet.externalServerKeyShares;
524
- if (!externalServerKeyShares) {
525
- throw new Error('External server key shares are required to sign a message');
530
+ async forwardMPCClientSign({ chainName, message, roomId, keyShare, derivationPath, formattedMessage, dynamicRequestId, isFormatted }) {
531
+ try {
532
+ if (!this.apiClient.forwardMPCClient.connected) {
533
+ await this.initializeForwardMPCClient();
534
+ }
535
+ const messageForForwardMPC = core.serializeMessageForForwardMPC({
536
+ message,
537
+ isFormatted,
538
+ chainName
539
+ });
540
+ this.logger.info('Forward MPC enabled, signing message with forward MPC');
541
+ const environment = core.getEnvironmentFromUrl(this.baseApiUrl);
542
+ const defaultRelayUrl = core.MPC_RELAY_URL_MAP[environment];
543
+ const signature = await this.apiClient.forwardMPCClient.signMessage({
544
+ keyshare: keyShare,
545
+ message: chainName === 'SVM' ? formattedMessage : messageForForwardMPC,
546
+ relayDomain: this.baseMPCRelayApiUrl || defaultRelayUrl,
547
+ signingAlgo: chainName === 'EVM' ? 'ECDSA' : 'ED25519',
548
+ hashAlgo: chainName === 'EVM' && !isFormatted ? 'keccak256' : undefined,
549
+ derivationPath: derivationPath,
550
+ roomUuid: roomId
551
+ });
552
+ const signatureBytes = signature.data.signature;
553
+ if (!(signatureBytes instanceof Uint8Array)) {
554
+ throw new TypeError(`Invalid signature format: expected Uint8Array, got ${typeof signatureBytes}`);
555
+ }
556
+ // Convert to EcdsaSignature
557
+ if (chainName === 'EVM') {
558
+ const ecdsaSignature = node.EcdsaSignature.fromBuffer(signatureBytes);
559
+ return ecdsaSignature;
560
+ } else {
561
+ return signatureBytes;
562
+ }
563
+ } catch (error) {
564
+ this.logger.error('Error signing message with forward MPC client', {
565
+ error,
566
+ environmentId: this.environmentId,
567
+ dynamicRequestId
568
+ });
569
+ throw error;
570
+ }
571
+ }
572
+ async sign({ accountAddress, externalServerKeyShares, message, chainName, password = undefined, isFormatted = false, context, onError }) {
573
+ try {
574
+ await this.verifyPassword({
575
+ accountAddress,
576
+ password,
577
+ walletOperation: core.WalletOperation.SIGN_MESSAGE
578
+ });
579
+ const wallet = await this.getWallet({
580
+ accountAddress,
581
+ walletOperation: core.WalletOperation.SIGN_MESSAGE,
582
+ password
583
+ });
584
+ externalServerKeyShares = externalServerKeyShares != null ? externalServerKeyShares : wallet.externalServerKeyShares;
585
+ if (!externalServerKeyShares) {
586
+ throw new Error('External server key shares are required to sign a message');
587
+ }
588
+ // Perform the dynamic server sign
589
+ const data = await this.dynamicServerSign({
590
+ walletId: wallet.walletId,
591
+ message,
592
+ isFormatted,
593
+ context,
594
+ onError
595
+ });
596
+ const derivationPath = wallet.derivationPath && wallet.derivationPath != '' ? new Uint32Array(Object.values(JSON.parse(wallet.derivationPath))) : undefined;
597
+ // Perform the external server sign and return the signature
598
+ if (this.forwardMPCEnabled) {
599
+ const formattedMessage = isFormatted ? new node.MessageHash(message) : formatMessage(chainName, message);
600
+ const signature = await this.forwardMPCClientSign({
601
+ chainName,
602
+ message,
603
+ roomId: data.roomId,
604
+ keyShare: externalServerKeyShares[0],
605
+ derivationPath,
606
+ formattedMessage,
607
+ dynamicRequestId: uuid.v4(),
608
+ isFormatted
609
+ });
610
+ return signature;
611
+ } else {
612
+ const signature = await this.externalServerSign({
613
+ chainName,
614
+ message,
615
+ roomId: data.roomId,
616
+ keyShare: externalServerKeyShares[0],
617
+ derivationPath,
618
+ isFormatted
619
+ });
620
+ return signature;
621
+ }
622
+ } catch (error) {
623
+ this.logger.error('Error in sign', error);
624
+ throw error;
526
625
  }
527
- // Perform the dynamic server sign
528
- const data = await this.dynamicServerSign({
529
- walletId: wallet.walletId,
530
- message,
531
- isFormatted
532
- });
533
- const derivationPath = wallet.derivationPath && wallet.derivationPath != '' ? new Uint32Array(Object.values(JSON.parse(wallet.derivationPath))) : undefined;
534
- // Perform the external server sign and return the signature
535
- const signature = await this.externalServerSign({
536
- chainName,
537
- message,
538
- roomId: data.roomId,
539
- keyShare: externalServerKeyShares[0],
540
- derivationPath,
541
- isFormatted
542
- });
543
- return signature;
544
626
  }
545
627
  async refreshWalletAccountShares({ accountAddress, chainName, password = undefined, externalServerKeyShares, backUpToClientShareService = false }) {
546
628
  this.ensureApiClientAuthenticated();
@@ -818,19 +900,21 @@ class DynamicWalletClient {
818
900
  if (!this.walletMap[accountAddress] || !this.walletMap[accountAddress].walletId) {
819
901
  throw new Error(`WalletId not found for accountAddress: ${accountAddress}`);
820
902
  }
903
+ const passwordEncryptedFlag = Boolean(password) && password !== this.environmentId;
821
904
  const locations = [];
822
905
  if (backUpToClientShareService) {
823
906
  const data = await this.apiClient.storeEncryptedBackupByWallet({
824
907
  walletId: this.walletMap[accountAddress].walletId,
825
908
  encryptedKeyShares: encryptedKeyShares,
826
- passwordEncrypted: Boolean(password) && password !== this.environmentId,
909
+ passwordEncrypted: passwordEncryptedFlag,
827
910
  encryptionVersion: ENCRYPTION_VERSION_CURRENT,
828
911
  requiresSignedSessionId: false,
829
912
  dynamicRequestId
830
913
  });
831
914
  locations.push({
832
915
  location: core.BackupLocation.DYNAMIC,
833
- externalKeyShareId: data.keyShareIds[0]
916
+ externalKeyShareId: data.keyShareIds[0],
917
+ passwordEncrypted: passwordEncryptedFlag
834
918
  });
835
919
  } else {
836
920
  locations.push({
@@ -849,7 +933,7 @@ class DynamicWalletClient {
849
933
  id: ks.keyShareId,
850
934
  backupLocation: ks.location,
851
935
  externalKeyShareId: ks.externalKeyShareId,
852
- passwordEncrypted: Boolean(password) && password !== this.environmentId
936
+ passwordEncrypted: passwordEncryptedFlag
853
937
  })),
854
938
  thresholdSignatureScheme: this.walletMap[accountAddress].thresholdSignatureScheme
855
939
  }
@@ -881,12 +965,25 @@ class DynamicWalletClient {
881
965
  });
882
966
  }
883
967
  async getExternalServerKeyShares({ accountAddress, password }) {
968
+ var _wallet_externalServerKeySharesBackupInfo_backups, _wallet_externalServerKeySharesBackupInfo;
884
969
  const wallet = await this.getWallet({
885
970
  accountAddress,
886
971
  password,
887
972
  walletOperation: core.WalletOperation.REACH_THRESHOLD
888
973
  });
889
- return wallet.externalServerKeyShares;
974
+ // Check if the wallet has a dynamic backup and derive password encryption status from the first dynamic share
975
+ const dynamicBackups = (wallet == null ? void 0 : (_wallet_externalServerKeySharesBackupInfo = wallet.externalServerKeySharesBackupInfo) == null ? void 0 : (_wallet_externalServerKeySharesBackupInfo_backups = _wallet_externalServerKeySharesBackupInfo.backups) == null ? void 0 : _wallet_externalServerKeySharesBackupInfo_backups.dynamic) || [];
976
+ const passwordEncrypted = dynamicBackups.length > 0 ? Boolean(dynamicBackups[0].passwordEncrypted) : false;
977
+ if (passwordEncrypted && !password) {
978
+ throw new Error('Password is required for decryption but not provided. This backup was encrypted with a password.');
979
+ }
980
+ // recover the shares
981
+ const recoveredShares = await this.recoverEncryptedBackupByWallet({
982
+ accountAddress,
983
+ password,
984
+ walletOperation: core.WalletOperation.REACH_THRESHOLD
985
+ });
986
+ return recoveredShares;
890
987
  }
891
988
  async updatePassword({ accountAddress, existingPassword, newPassword, backUpToClientShareService }) {
892
989
  await this.getWallet({
@@ -928,10 +1025,14 @@ class DynamicWalletClient {
928
1025
  if (shareCount !== undefined) {
929
1026
  requiredShareCount = shareCount;
930
1027
  }
931
- const dynamicShares = backups[core.BackupLocation.DYNAMIC].slice(0, requiredShareCount);
1028
+ const dynamicShares = (backups[core.BackupLocation.DYNAMIC] || []).slice(0, requiredShareCount);
1029
+ const externalShares = (backups[core.BackupLocation.EXTERNAL] || []).slice(0, requiredShareCount);
1030
+ // If we have DYNAMIC shares, use those; otherwise use EXTERNAL shares
1031
+ const sharesToUse = dynamicShares.length > 0 ? dynamicShares : externalShares;
1032
+ const backupLocation = dynamicShares.length > 0 ? core.BackupLocation.DYNAMIC : core.BackupLocation.EXTERNAL;
932
1033
  return {
933
1034
  shares: {
934
- [core.BackupLocation.DYNAMIC]: dynamicShares.map((ks)=>{
1035
+ [backupLocation]: sharesToUse.map((ks)=>{
935
1036
  var _ks_externalKeyShareId, _ref;
936
1037
  return (_ref = (_ks_externalKeyShareId = ks.externalKeyShareId) != null ? _ks_externalKeyShareId : ks.keyShareId) != null ? _ref : '';
937
1038
  })
@@ -939,9 +1040,42 @@ class DynamicWalletClient {
939
1040
  requiredShareCount
940
1041
  };
941
1042
  }
1043
+ /**
1044
+ * Attempts to recover key shares from backup if they are not provided.
1045
+ * The recovered shares will be stored in the wallet map for use in signing operations.
1046
+ * @param accountAddress - The account address to recover shares for
1047
+ * @param password - The password to decrypt the shares
1048
+ * @param walletOperation - The wallet operation being performed
1049
+ * @param externalServerKeyShares - The provided key shares (if any)
1050
+ * @param errorMessage - The error message to throw if recovery fails
1051
+ * @throws Error if recovery is needed but fails
1052
+ */ async ensureKeySharesRecovered({ accountAddress, password, walletOperation, externalServerKeyShares, errorMessage }) {
1053
+ if (!externalServerKeyShares || externalServerKeyShares.length === 0) {
1054
+ // attempt to recover dynamic keyshares if no key shares are provided
1055
+ // the shares will be used for signing in the node SDK if successful
1056
+ const recoveredShares = await this.recoverEncryptedBackupByWallet({
1057
+ accountAddress,
1058
+ password,
1059
+ walletOperation,
1060
+ storeRecoveredShares: true
1061
+ });
1062
+ // If recovery returned empty and no shares were provided, throw error
1063
+ if (!recoveredShares || recoveredShares.length === 0) {
1064
+ throw new Error(errorMessage);
1065
+ }
1066
+ }
1067
+ }
942
1068
  async recoverEncryptedBackupByWallet({ accountAddress, password, walletOperation, shareCount = undefined, storeRecoveredShares = true }) {
1069
+ var _wallet_externalServerKeySharesBackupInfo;
943
1070
  this.ensureApiClientAuthenticated();
944
- const wallet = this.walletMap[accountAddress];
1071
+ let wallet = this.walletMap[accountAddress];
1072
+ if (!wallet) {
1073
+ const fetchedWallet = await this.getWalletByAddress(accountAddress);
1074
+ if (!fetchedWallet) {
1075
+ throw new Error(`Wallet not found for address 1: ${accountAddress}`);
1076
+ }
1077
+ wallet = fetchedWallet;
1078
+ }
945
1079
  this.logger.debug(`recoverEncryptedBackupByWallet wallet: ${walletOperation}`, wallet);
946
1080
  const { shares } = this.recoverStrategy({
947
1081
  externalServerKeySharesBackupInfo: wallet.externalServerKeySharesBackupInfo,
@@ -949,13 +1083,30 @@ class DynamicWalletClient {
949
1083
  walletOperation,
950
1084
  shareCount
951
1085
  });
952
- const { dynamic: dynamicKeyShareIds } = shares;
953
- const data = await this.apiClient.recoverEncryptedBackupByWallet({
954
- walletId: wallet.walletId,
955
- keyShareIds: dynamicKeyShareIds,
956
- requiresSignedSessionId: false
957
- });
1086
+ // Get the key share IDs from whichever backup location has shares
1087
+ const dynamicKeyShareIds = shares[core.BackupLocation.DYNAMIC] || [];
1088
+ const externalKeyShareIds = shares[core.BackupLocation.EXTERNAL] || [];
1089
+ // Only attempt recovery if we have DYNAMIC shares (the API doesn't support EXTERNAL shares)
1090
+ let data;
1091
+ if (dynamicKeyShareIds.length > 0) {
1092
+ data = await this.apiClient.recoverEncryptedBackupByWallet({
1093
+ walletId: wallet.walletId,
1094
+ keyShareIds: dynamicKeyShareIds,
1095
+ requiresSignedSessionId: false
1096
+ });
1097
+ } else if (externalKeyShareIds.length > 0) {
1098
+ this.logger.debug('Skipping recovery - only EXTERNAL shares available (backUpToClientShareService: false)');
1099
+ return []; // Return empty array since we can't recover EXTERNAL shares via API
1100
+ } else {
1101
+ this.logger.debug('No shares available for recovery');
1102
+ return []; // Return empty array if no shares are available
1103
+ }
958
1104
  const dynamicKeyShares = data.keyShares.filter((keyShare)=>keyShare.encryptedAccountCredential !== null && keyShare.backupLocation === core.BackupLocation.DYNAMIC);
1105
+ var _wallet_externalServerKeySharesBackupInfo_passwordEncrypted;
1106
+ const isPasswordEncrypted = (_wallet_externalServerKeySharesBackupInfo_passwordEncrypted = (_wallet_externalServerKeySharesBackupInfo = wallet.externalServerKeySharesBackupInfo) == null ? void 0 : _wallet_externalServerKeySharesBackupInfo.passwordEncrypted) != null ? _wallet_externalServerKeySharesBackupInfo_passwordEncrypted : false;
1107
+ if (isPasswordEncrypted && !password) {
1108
+ throw new Error('Password is required for decryption but not provided. This backup was encrypted with a password.');
1109
+ }
959
1110
  const decryptedKeyShares = await Promise.all(dynamicKeyShares.map((keyShare)=>this.decryptKeyShare({
960
1111
  keyShare: keyShare.encryptedAccountCredential,
961
1112
  password: password != null ? password : this.environmentId
@@ -985,6 +1136,7 @@ class DynamicWalletClient {
985
1136
  * @param walletOperation - The wallet operation that determines required fields
986
1137
  * @returns boolean indicating if wallet needs to be re-fetched and restored from server
987
1138
  */ async checkWalletFields({ accountAddress, walletOperation = core.WalletOperation.REACH_THRESHOLD, shareCount }) {
1139
+ var _existingWallet_externalServerKeyShares;
988
1140
  let keyshareCheck = false;
989
1141
  let walletCheck = false;
990
1142
  let thresholdSignatureSchemeCheck = false;
@@ -1004,7 +1156,7 @@ class DynamicWalletClient {
1004
1156
  }
1005
1157
  // check if wallet already exists with sufficient keyshares
1006
1158
  if (existingWallet) {
1007
- var _existingWallet_externalServerKeyShares;
1159
+ var _existingWallet_externalServerKeyShares1;
1008
1160
  const { shares } = this.recoverStrategy({
1009
1161
  externalServerKeySharesBackupInfo: existingWallet.externalServerKeySharesBackupInfo || {
1010
1162
  backups: getExternalServerKeyShareBackupInfo()
@@ -1014,11 +1166,35 @@ class DynamicWalletClient {
1014
1166
  shareCount
1015
1167
  });
1016
1168
  const { dynamic: requiredDynamicKeyShareIds = [] } = shares;
1017
- if (requiredDynamicKeyShareIds.length <= (((_existingWallet_externalServerKeyShares = existingWallet.externalServerKeyShares) == null ? void 0 : _existingWallet_externalServerKeyShares.length) || 0)) {
1169
+ const { external: requiredExternalKeyShareIds = [] } = shares;
1170
+ // Check if we have enough shares from any backup location
1171
+ const totalRequiredShares = requiredDynamicKeyShareIds.length + requiredExternalKeyShareIds.length;
1172
+ // Check if we have the required shares either loaded OR available in backup
1173
+ const hasLoadedShares = totalRequiredShares <= (((_existingWallet_externalServerKeyShares1 = existingWallet.externalServerKeyShares) == null ? void 0 : _existingWallet_externalServerKeyShares1.length) || 0);
1174
+ // Check if backup contains the specific required share IDs
1175
+ const hasBackupShares = existingWallet.externalServerKeySharesBackupInfo && (()=>{
1176
+ const backupShares = existingWallet.externalServerKeySharesBackupInfo.backups.dynamic;
1177
+ const allRequiredIds = [
1178
+ ...requiredDynamicKeyShareIds,
1179
+ ...requiredExternalKeyShareIds
1180
+ ];
1181
+ return allRequiredIds.every((requiredId)=>backupShares.some((backupShare)=>backupShare.externalKeyShareId === requiredId || backupShare.keyShareId === requiredId));
1182
+ })();
1183
+ if (hasLoadedShares || hasBackupShares) {
1018
1184
  keyshareCheck = true;
1019
1185
  }
1020
1186
  }
1021
- return walletCheck && thresholdSignatureSchemeCheck && keyshareCheck && derivationPathCheck;
1187
+ const result = walletCheck && thresholdSignatureSchemeCheck && keyshareCheck && derivationPathCheck;
1188
+ this.logger.debug('Wallet checks:', {
1189
+ walletCheck,
1190
+ thresholdSignatureSchemeCheck,
1191
+ keyshareCheck,
1192
+ derivationPathCheck,
1193
+ existingWallet: !!existingWallet,
1194
+ keySharesLength: existingWallet == null ? void 0 : (_existingWallet_externalServerKeyShares = existingWallet.externalServerKeyShares) == null ? void 0 : _existingWallet_externalServerKeyShares.length,
1195
+ result
1196
+ });
1197
+ return result;
1022
1198
  }
1023
1199
  /**
1024
1200
  * verifyPassword attempts to recover and decrypt a single client key share using the provided password.
@@ -1044,8 +1220,10 @@ class DynamicWalletClient {
1044
1220
  accountAddress
1045
1221
  });
1046
1222
  const { dynamic: dynamicKeyShareIds = [] } = backups;
1047
- if (!dynamicKeyShareIds || dynamicKeyShareIds.length === 0) {
1048
- throw new Error('No dynamic key shares found');
1223
+ const { external: externalKeyShareIds = [] } = backups;
1224
+ // Check if we have any shares available (DYNAMIC or EXTERNAL)
1225
+ if (dynamicKeyShareIds.length === 0 && externalKeyShareIds.length === 0) {
1226
+ throw new Error('No key shares found');
1049
1227
  }
1050
1228
  try {
1051
1229
  await this.recoverEncryptedBackupByWallet({
@@ -1090,34 +1268,44 @@ class DynamicWalletClient {
1090
1268
  if (walletOperation === core.WalletOperation.REACH_ALL_PARTIES || walletOperation === core.WalletOperation.REFRESH || walletOperation === core.WalletOperation.RESHARE) {
1091
1269
  return true;
1092
1270
  }
1093
- const { requiredShareCount } = this.recoverStrategy({
1271
+ const { shares, requiredShareCount } = this.recoverStrategy({
1094
1272
  externalServerKeySharesBackupInfo,
1095
1273
  thresholdSignatureScheme: this.walletMap[accountAddress].thresholdSignatureScheme,
1096
1274
  walletOperation
1097
1275
  });
1098
- if (externalServerKeyShares.length >= requiredShareCount) {
1276
+ const dynamicKeyShareIds = shares[core.BackupLocation.DYNAMIC] || [];
1277
+ const externalKeyShareIds = shares[core.BackupLocation.EXTERNAL] || [];
1278
+ // Check if we have enough shares from either location
1279
+ const totalAvailableShares = externalServerKeyShares.length + dynamicKeyShareIds.length + externalKeyShareIds.length;
1280
+ if (totalAvailableShares >= requiredShareCount) {
1099
1281
  return false;
1100
1282
  }
1101
1283
  return true;
1102
1284
  }
1103
1285
  async getWalletExternalServerKeyShareBackupInfo({ accountAddress }) {
1104
- var _this_walletMap_accountAddress_externalServerKeySharesBackupInfo_backups_BackupLocation_DYNAMIC, _this_walletMap_accountAddress_externalServerKeySharesBackupInfo_backups, _this_walletMap_accountAddress_externalServerKeySharesBackupInfo, _this_walletMap_accountAddress, _user_verifiedCredentials;
1286
+ var _wallet_externalServerKeySharesBackupInfo_backups_BackupLocation_DYNAMIC, _wallet_externalServerKeySharesBackupInfo_backups, _wallet_externalServerKeySharesBackupInfo, _user_verifiedCredentials;
1105
1287
  this.ensureApiClientAuthenticated();
1288
+ let wallet = this.walletMap[accountAddress];
1289
+ if (!wallet) {
1290
+ const fetchedWallet = await this.getWalletByAddress(accountAddress);
1291
+ if (!fetchedWallet) {
1292
+ throw new Error(`Wallet not found for address 2: ${accountAddress}`);
1293
+ }
1294
+ wallet = fetchedWallet;
1295
+ }
1106
1296
  // Return existing backup info if it exists
1107
- if (((_this_walletMap_accountAddress = this.walletMap[accountAddress]) == null ? void 0 : (_this_walletMap_accountAddress_externalServerKeySharesBackupInfo = _this_walletMap_accountAddress.externalServerKeySharesBackupInfo) == null ? void 0 : (_this_walletMap_accountAddress_externalServerKeySharesBackupInfo_backups = _this_walletMap_accountAddress_externalServerKeySharesBackupInfo.backups) == null ? void 0 : (_this_walletMap_accountAddress_externalServerKeySharesBackupInfo_backups_BackupLocation_DYNAMIC = _this_walletMap_accountAddress_externalServerKeySharesBackupInfo_backups[core.BackupLocation.DYNAMIC]) == null ? void 0 : _this_walletMap_accountAddress_externalServerKeySharesBackupInfo_backups_BackupLocation_DYNAMIC.length) > 0) {
1108
- return this.walletMap[accountAddress].externalServerKeySharesBackupInfo;
1297
+ if (((_wallet_externalServerKeySharesBackupInfo = wallet.externalServerKeySharesBackupInfo) == null ? void 0 : (_wallet_externalServerKeySharesBackupInfo_backups = _wallet_externalServerKeySharesBackupInfo.backups) == null ? void 0 : (_wallet_externalServerKeySharesBackupInfo_backups_BackupLocation_DYNAMIC = _wallet_externalServerKeySharesBackupInfo_backups[core.BackupLocation.DYNAMIC]) == null ? void 0 : _wallet_externalServerKeySharesBackupInfo_backups_BackupLocation_DYNAMIC.length) > 0) {
1298
+ return wallet.externalServerKeySharesBackupInfo;
1109
1299
  }
1110
1300
  // Get backup info from server
1111
1301
  const user = await this.apiClient.getUser(uuid.v4());
1112
- const wallet = (_user_verifiedCredentials = user.verifiedCredentials) == null ? void 0 : _user_verifiedCredentials.find((vc)=>vc.address.toLowerCase() === accountAddress.toLowerCase());
1302
+ const walletData = (_user_verifiedCredentials = user.verifiedCredentials) == null ? void 0 : _user_verifiedCredentials.find((vc)=>vc.address.toLowerCase() === accountAddress.toLowerCase());
1113
1303
  return getExternalServerKeyShareBackupInfo({
1114
- walletProperties: wallet == null ? void 0 : wallet.walletProperties
1304
+ walletProperties: walletData == null ? void 0 : walletData.walletProperties
1115
1305
  });
1116
1306
  }
1117
1307
  async getWallet({ accountAddress, walletOperation = core.WalletOperation.NO_OPERATION, shareCount = undefined, password = undefined }) {
1118
- const dynamicRequestId = uuid.v4();
1119
1308
  try {
1120
- var _user_verifiedCredentials;
1121
1309
  this.ensureApiClientAuthenticated();
1122
1310
  const existingWalletCheck = await this.checkWalletFields({
1123
1311
  accountAddress,
@@ -1128,22 +1316,13 @@ class DynamicWalletClient {
1128
1316
  this.logger.debug(`Wallet ${accountAddress} already exists`);
1129
1317
  return this.walletMap[accountAddress];
1130
1318
  }
1131
- //todo: Question - why don't we just call getWallets here? so then all are preloaded
1132
- // Fetch and restore wallet from server
1133
- const user = await this.apiClient.getUser(dynamicRequestId);
1134
- const wallet = (_user_verifiedCredentials = user.verifiedCredentials) == null ? void 0 : _user_verifiedCredentials.find((vc)=>vc.address.toLowerCase() === accountAddress.toLowerCase());
1319
+ const wallet = await this.getWalletByAddress(accountAddress);
1320
+ if (!wallet) {
1321
+ throw new Error(`Wallet not found for address 3: ${accountAddress}`);
1322
+ }
1135
1323
  this.logger.debug('Restoring wallet', wallet);
1136
- const walletProperties = wallet.walletProperties;
1137
- this.walletMap[accountAddress] = _extends({}, this.walletMap[accountAddress], {
1138
- walletId: wallet.id,
1139
- chainName: wallet.chainName,
1140
- accountAddress,
1141
- thresholdSignatureScheme: walletProperties.thresholdSignatureScheme,
1142
- derivationPath: walletProperties.derivationPath,
1143
- externalServerKeySharesBackupInfo: getExternalServerKeyShareBackupInfo({
1144
- walletProperties
1145
- })
1146
- });
1324
+ // The wallet is already processed, so we can use it directly
1325
+ this.walletMap[accountAddress] = wallet;
1147
1326
  if (walletOperation !== core.WalletOperation.NO_OPERATION && await this.requiresRestoreBackupSharesForOperation({
1148
1327
  accountAddress,
1149
1328
  walletOperation
@@ -1171,14 +1350,82 @@ class DynamicWalletClient {
1171
1350
  throw error;
1172
1351
  }
1173
1352
  }
1174
- async getWallets() {
1353
+ /**
1354
+ * Get a single wallet by address
1355
+ * First tries the efficient getWaasWalletByAddress endpoint, falls back to getUser() if not available
1356
+ */ async getWalletByAddress(accountAddress) {
1357
+ // Return cached wallet if available
1358
+ if (this.walletMap[accountAddress]) {
1359
+ return this.walletMap[accountAddress];
1360
+ }
1361
+ this.ensureApiClientAuthenticated();
1362
+ // Try getting single wallet by address first
1363
+ try {
1364
+ var _walletResponse_wallet;
1365
+ const walletResponse = await this.apiClient.getWaasWalletByAddress({
1366
+ walletAddress: accountAddress
1367
+ });
1368
+ const walletProperties = {
1369
+ walletId: walletResponse.wallet.walletId,
1370
+ chainName: walletResponse.wallet.chainName,
1371
+ accountAddress: walletResponse.wallet.accountAddress,
1372
+ externalServerKeyShares: [],
1373
+ derivationPath: walletResponse.wallet.derivationPath,
1374
+ thresholdSignatureScheme: walletResponse.wallet.thresholdSignatureScheme,
1375
+ externalServerKeySharesBackupInfo: getExternalServerKeyShareBackupInfo({
1376
+ walletProperties: {
1377
+ // @ts-expect-error TODO: update response to get key shares
1378
+ keyShares: ((_walletResponse_wallet = walletResponse.wallet) == null ? void 0 : _walletResponse_wallet.keyShares) || [],
1379
+ thresholdSignatureScheme: walletResponse.wallet.thresholdSignatureScheme,
1380
+ derivationPath: walletResponse.wallet.derivationPath
1381
+ }
1382
+ })
1383
+ };
1384
+ // Cache the wallet
1385
+ this.walletMap[accountAddress] = walletProperties;
1386
+ return walletProperties;
1387
+ } catch (error) {
1388
+ var _error_response;
1389
+ // If the new endpoint doesn't exist (404 or not implemented), fall back to getUser()
1390
+ if ((error == null ? void 0 : (_error_response = error.response) == null ? void 0 : _error_response.status) === 404 || (error == null ? void 0 : error.code) === 'ERR_BAD_REQUEST') {
1391
+ var _user_verifiedCredentials, _wallet_walletProperties, _wallet_walletProperties1;
1392
+ this.logger.debug('getWaasWalletByAddress endpoint not available, falling back to getUser()');
1393
+ // Fallback to getUser() approach
1394
+ const user = await this.apiClient.getUser(uuid.v4());
1395
+ const wallet = (_user_verifiedCredentials = user.verifiedCredentials) == null ? void 0 : _user_verifiedCredentials.find((vc)=>vc.walletName === 'dynamicwaas' && vc.address.toLowerCase() === accountAddress.toLowerCase());
1396
+ if (!wallet) {
1397
+ return null;
1398
+ }
1399
+ var _wallet_walletProperties_derivationPath;
1400
+ const walletProperties = {
1401
+ walletId: wallet.id,
1402
+ chainName: wallet.chain,
1403
+ accountAddress: wallet.address,
1404
+ externalServerKeyShares: [],
1405
+ derivationPath: (_wallet_walletProperties_derivationPath = (_wallet_walletProperties = wallet.walletProperties) == null ? void 0 : _wallet_walletProperties.derivationPath) != null ? _wallet_walletProperties_derivationPath : undefined,
1406
+ thresholdSignatureScheme: (_wallet_walletProperties1 = wallet.walletProperties) == null ? void 0 : _wallet_walletProperties1.thresholdSignatureScheme,
1407
+ externalServerKeySharesBackupInfo: getExternalServerKeyShareBackupInfo({
1408
+ walletProperties: wallet.walletProperties || {}
1409
+ })
1410
+ };
1411
+ // Cache the wallet
1412
+ this.walletMap[accountAddress] = walletProperties;
1413
+ return walletProperties;
1414
+ }
1415
+ throw error;
1416
+ }
1417
+ }
1418
+ /**
1419
+ * Get all wallets (kept for backward compatibility but now uses lazy loading)
1420
+ * @deprecated Consider using getWalletByAddress for better performance with large wallet counts
1421
+ */ async getWallets() {
1175
1422
  var _user_verifiedCredentials;
1176
1423
  this.ensureApiClientAuthenticated();
1177
1424
  const user = await this.apiClient.getUser(uuid.v4());
1178
1425
  const waasWallets = (_user_verifiedCredentials = user.verifiedCredentials) == null ? void 0 : _user_verifiedCredentials.filter((vc)=>vc.walletName === 'dynamicwaas');
1179
1426
  const wallets = waasWallets.map((vc)=>{
1180
- var _this_walletMap_vc_address, _this_walletMap_vc_address1, _vc_walletProperties;
1181
- var _this_walletMap_vc_address_derivationPath;
1427
+ var _this_walletMap_vc_address, _vc_walletProperties, _vc_walletProperties1;
1428
+ var _vc_walletProperties_derivationPath;
1182
1429
  return {
1183
1430
  walletId: vc.id,
1184
1431
  chainName: vc.chain,
@@ -1187,39 +1434,225 @@ class DynamicWalletClient {
1187
1434
  walletProperties: vc.walletProperties || {}
1188
1435
  }),
1189
1436
  externalServerKeyShares: ((_this_walletMap_vc_address = this.walletMap[vc.address]) == null ? void 0 : _this_walletMap_vc_address.externalServerKeyShares) || [],
1190
- derivationPath: (_this_walletMap_vc_address_derivationPath = (_this_walletMap_vc_address1 = this.walletMap[vc.address]) == null ? void 0 : _this_walletMap_vc_address1.derivationPath) != null ? _this_walletMap_vc_address_derivationPath : undefined,
1191
- thresholdSignatureScheme: (_vc_walletProperties = vc.walletProperties) == null ? void 0 : _vc_walletProperties.thresholdSignatureScheme
1437
+ derivationPath: (_vc_walletProperties_derivationPath = (_vc_walletProperties = vc.walletProperties) == null ? void 0 : _vc_walletProperties.derivationPath) != null ? _vc_walletProperties_derivationPath : undefined,
1438
+ thresholdSignatureScheme: (_vc_walletProperties1 = vc.walletProperties) == null ? void 0 : _vc_walletProperties1.thresholdSignatureScheme
1192
1439
  };
1193
1440
  });
1194
1441
  this.walletMap = wallets.reduce((acc, wallet)=>{
1195
- var _acc_accountAddress;
1196
- const accountAddress = wallet.accountAddress;
1197
1442
  acc[wallet.accountAddress] = {
1198
1443
  walletId: wallet.walletId,
1199
1444
  chainName: wallet.chainName,
1200
1445
  accountAddress: wallet.accountAddress,
1201
1446
  externalServerKeyShares: wallet.externalServerKeyShares || [],
1202
1447
  externalServerKeySharesBackupInfo: wallet.externalServerKeySharesBackupInfo,
1203
- derivationPath: ((_acc_accountAddress = acc[accountAddress]) == null ? void 0 : _acc_accountAddress.derivationPath) || undefined,
1448
+ derivationPath: wallet.derivationPath,
1204
1449
  thresholdSignatureScheme: wallet.thresholdSignatureScheme
1205
1450
  };
1206
1451
  return acc;
1207
1452
  }, {});
1208
1453
  return wallets;
1209
1454
  }
1210
- constructor({ environmentId, baseApiUrl, baseMPCRelayApiUrl, debug }){
1455
+ constructor({ environmentId, baseApiUrl, baseMPCRelayApiUrl, debug, forwardMPCClient, enableMPCAccelerator = false }){
1211
1456
  this.logger = logger;
1212
1457
  this.walletMap = {} // todo: store in session storage
1213
1458
  ;
1214
1459
  this.isApiClientAuthenticated = false;
1460
+ this.forwardMPCEnabled = false;
1215
1461
  this.environmentId = environmentId;
1216
1462
  this.baseMPCRelayApiUrl = baseMPCRelayApiUrl;
1217
1463
  this.baseApiUrl = baseApiUrl;
1218
1464
  this.debug = Boolean(debug);
1219
1465
  this.logger.setLogLevel(this.debug ? 'DEBUG' : DEFAULT_LOG_LEVEL);
1466
+ this.forwardMPCEnabled = enableMPCAccelerator || Boolean(forwardMPCClient);
1467
+ // Initialize API client with forwardMPCClient
1468
+ this.apiClient = new core.DynamicApiClient({
1469
+ environmentId,
1470
+ baseApiUrl,
1471
+ forwardMPCClient
1472
+ });
1473
+ if (this.forwardMPCEnabled) {
1474
+ this.logger.info('Initializing ForwardMPC enclave websocket in node client. Environment: ' + this.environmentId);
1475
+ this.initializeForwardMPCClient();
1476
+ }
1220
1477
  }
1221
1478
  }
1222
1479
 
1480
+ const createCore = ({ environmentId, baseApiUrl, baseMPCRelayApiUrl, debug = false })=>{
1481
+ const coreLogger = logger;
1482
+ coreLogger.setLogLevel(debug ? 'DEBUG' : DEFAULT_LOG_LEVEL);
1483
+ const createApiClient = (options = {})=>{
1484
+ return new core.DynamicApiClient(_extends({
1485
+ environmentId,
1486
+ baseApiUrl
1487
+ }, options));
1488
+ };
1489
+ return {
1490
+ environmentId,
1491
+ createApiClient,
1492
+ logger: coreLogger,
1493
+ baseMPCRelayApiUrl,
1494
+ baseApiUrl,
1495
+ debug
1496
+ };
1497
+ };
1498
+
1499
+ // Helper function to create API client for delegated operations
1500
+ const createDelegatedApiClient = (client, options = {})=>{
1501
+ return client.createApiClient(options);
1502
+ };
1503
+ // Helper function to create API client with wallet-specific headers
1504
+ const createDelegatedApiClientWithWalletKey = (client, walletApiKey)=>{
1505
+ const apiClient = client.createApiClient();
1506
+ // Add the wallet-specific API key header to all requests from this client
1507
+ apiClient.apiClient.defaults.headers['x-dyn-wallet-api-key'] = walletApiKey;
1508
+ return apiClient;
1509
+ };
1510
+ const createDelegatedWalletClient = ({ environmentId, baseApiUrl, baseMPCRelayApiUrl, apiKey, debug = false })=>{
1511
+ const core = createCore({
1512
+ environmentId,
1513
+ baseApiUrl,
1514
+ baseMPCRelayApiUrl,
1515
+ debug
1516
+ });
1517
+ // Store the API key for use in delegated operations
1518
+ core.apiKey = apiKey;
1519
+ const walletMap = {};
1520
+ const client = {
1521
+ get environmentId () {
1522
+ return core.environmentId;
1523
+ },
1524
+ get debug () {
1525
+ return core.debug;
1526
+ },
1527
+ get apiUrl () {
1528
+ var _core_baseApiUrl;
1529
+ return (_core_baseApiUrl = core.baseApiUrl) != null ? _core_baseApiUrl : 'https://app.dynamicauth.com';
1530
+ },
1531
+ get wallets () {
1532
+ return walletMap;
1533
+ },
1534
+ createApiClient: (options = {})=>{
1535
+ return core.createApiClient(_extends({
1536
+ authToken: apiKey
1537
+ }, options));
1538
+ },
1539
+ logger: core.logger,
1540
+ apiKey,
1541
+ baseMPCRelayApiUrl: core.baseMPCRelayApiUrl
1542
+ };
1543
+ return client;
1544
+ };
1545
+
1546
+ const dynamicDelegatedSign = async (client, { walletId, message, isFormatted, walletApiKey, onError, context })=>{
1547
+ const dynamicRequestId = uuid.v4();
1548
+ // Convert message to hex if it's a Uint8Array
1549
+ if (typeof message !== 'string') {
1550
+ message = '0x' + Buffer.from(message).toString('hex');
1551
+ }
1552
+ const apiClient = createDelegatedApiClientWithWalletKey(client, walletApiKey);
1553
+ const data = await apiClient.delegatedSignMessage({
1554
+ walletId,
1555
+ message,
1556
+ isFormatted,
1557
+ dynamicRequestId,
1558
+ onError,
1559
+ context: context ? JSON.parse(JSON.stringify(context, (_key, value)=>typeof value === 'bigint' ? value.toString() : value)) : undefined
1560
+ });
1561
+ return data;
1562
+ };
1563
+ const delegatedSign = async (client, { chainName, message, roomId, keyShare, derivationPath, isFormatted })=>{
1564
+ try {
1565
+ const mpcSigner = getMPCSigner({
1566
+ chainName,
1567
+ baseRelayUrl: client.baseMPCRelayApiUrl
1568
+ });
1569
+ const formattedMessage = isFormatted ? new node.MessageHash(message) : formatMessage(chainName, message);
1570
+ const signature = await mpcSigner.sign(roomId, keyShare, formattedMessage, derivationPath);
1571
+ return signature;
1572
+ } catch (error) {
1573
+ client.logger.error('Error in delegatedSign', error);
1574
+ throw error;
1575
+ }
1576
+ };
1577
+ const delegatedSignMessage = async (client, { walletId, walletApiKey, keyShare, message, chainName, isFormatted = false, onError, context })=>{
1578
+ // Validate required parameters
1579
+ if (!keyShare) {
1580
+ throw new Error('Delegated key share is required to sign a message');
1581
+ }
1582
+ const wallet = await getWallet(client, {
1583
+ walletId
1584
+ });
1585
+ // Perform the dynamic server sign
1586
+ const data = await dynamicDelegatedSign(client, {
1587
+ walletId,
1588
+ walletApiKey,
1589
+ message,
1590
+ isFormatted,
1591
+ onError,
1592
+ context
1593
+ });
1594
+ const derivationPath = wallet.derivationPath && wallet.derivationPath !== '' ? new Uint32Array(Object.values(JSON.parse(wallet.derivationPath))) : undefined;
1595
+ // Perform the external server sign and return the signature
1596
+ const signature = await delegatedSign(client, {
1597
+ chainName,
1598
+ message,
1599
+ roomId: data.roomId,
1600
+ keyShare,
1601
+ derivationPath,
1602
+ isFormatted
1603
+ });
1604
+ return signature;
1605
+ };
1606
+ // Helper function to get wallet (to be implemented in wallet module)
1607
+ const getWallet = async (client, { walletId })=>{
1608
+ const wallets = client.wallets;
1609
+ // Check if wallet is already cached
1610
+ if (wallets[walletId]) {
1611
+ return wallets[walletId];
1612
+ }
1613
+ // Fetch wallet from API
1614
+ const apiClient = createDelegatedApiClient(client);
1615
+ const { wallet } = await apiClient.getWaasWalletById({
1616
+ walletId
1617
+ });
1618
+ const waasWallet = {
1619
+ walletId,
1620
+ chainName: wallet.chainName,
1621
+ accountAddress: wallet.accountAddress,
1622
+ externalServerKeyShares: [],
1623
+ derivationPath: wallet.derivationPath,
1624
+ thresholdSignatureScheme: wallet.thresholdSignatureScheme,
1625
+ externalServerKeySharesBackupInfo: {
1626
+ passwordEncrypted: false,
1627
+ backups: {
1628
+ dynamic: [],
1629
+ googleDrive: [],
1630
+ iCloud: [],
1631
+ user: [],
1632
+ external: [],
1633
+ delegated: []
1634
+ }
1635
+ }
1636
+ };
1637
+ // Cache the wallet
1638
+ wallets[walletId] = waasWallet;
1639
+ return waasWallet;
1640
+ };
1641
+
1642
+ const revokeDelegation = async (client, walletId)=>{
1643
+ try {
1644
+ // TODO: Uncomment when API method is implemented
1645
+ // const apiClient = createDelegatedApiClient(client);
1646
+ // await apiClient.revokeDelegation({
1647
+ // walletId,
1648
+ // });
1649
+ client.logger.info(`Delegation revoked for wallet: ${walletId}`);
1650
+ } catch (error) {
1651
+ client.logger.error('Error revoking delegation', error);
1652
+ throw new Error('Failed to revoke delegation');
1653
+ }
1654
+ };
1655
+
1223
1656
  Object.defineProperty(exports, "SOLANA_RPC_URL", {
1224
1657
  enumerable: true,
1225
1658
  get: function () { return core.SOLANA_RPC_URL; }
@@ -1232,9 +1665,15 @@ Object.defineProperty(exports, "WalletOperation", {
1232
1665
  enumerable: true,
1233
1666
  get: function () { return core.WalletOperation; }
1234
1667
  });
1668
+ Object.defineProperty(exports, "getMPCChainConfig", {
1669
+ enumerable: true,
1670
+ get: function () { return core.getMPCChainConfig; }
1671
+ });
1235
1672
  exports.DynamicWalletClient = DynamicWalletClient;
1236
1673
  exports.base64ToBytes = base64ToBytes;
1237
1674
  exports.bytesToBase64 = bytesToBase64;
1675
+ exports.createDelegatedWalletClient = createDelegatedWalletClient;
1676
+ exports.delegatedSignMessage = delegatedSignMessage;
1238
1677
  exports.ensureBase64Padding = ensureBase64Padding;
1239
1678
  exports.formatEvmMessage = formatEvmMessage;
1240
1679
  exports.formatMessage = formatMessage;
@@ -1244,6 +1683,7 @@ exports.getMPCSigner = getMPCSigner;
1244
1683
  exports.isHexString = isHexString;
1245
1684
  exports.mergeUniqueKeyShares = mergeUniqueKeyShares;
1246
1685
  exports.retryPromise = retryPromise;
1686
+ exports.revokeDelegation = revokeDelegation;
1247
1687
  exports.stringToBytes = stringToBytes;
1248
1688
  Object.keys(core$1).forEach(function (k) {
1249
1689
  if (k !== 'default' && !Object.prototype.hasOwnProperty.call(exports, k)) Object.defineProperty(exports, k, {