@dynamic-labs-wallet/browser 0.0.228 → 0.0.230

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
@@ -33,8 +33,8 @@ const getMPCSignatureScheme = ({ signingAlgorithm, baseRelayUrl = core.MPC_RELAY
33
33
  throw new Error(`Unsupported signing algorithm: ${signingAlgorithm}`);
34
34
  }
35
35
  };
36
- const getMPCSigner = ({ chainName, baseRelayUrl })=>{
37
- const chainConfig = core.getMPCChainConfig(chainName);
36
+ const getMPCSigner = ({ chainName, baseRelayUrl, bitcoinConfig })=>{
37
+ const chainConfig = core.getMPCChainConfig(chainName, bitcoinConfig);
38
38
  const signatureScheme = getMPCSignatureScheme({
39
39
  signingAlgorithm: chainConfig.signingAlgorithm,
40
40
  baseRelayUrl
@@ -467,7 +467,28 @@ const ROOM_EXPIRATION_TIME = 1000 * 60 * 10; // 10 minutes
467
467
  const ROOM_CACHE_COUNT = 5;
468
468
  const WALLET_BUSY_LOCK_TIMEOUT_MS = 20000; // 20 seconds
469
469
 
470
+ // eslint-disable-next-line @nx/enforce-module-boundaries
470
471
  const isBrowser = ()=>typeof window !== 'undefined';
472
+ /**
473
+ * Helper function to extract pubkey from potentially nested structure
474
+ * Handles cases where pubkey is stored as {pubkey: {0: 33, 1: 209, ...}} in localStorage
475
+ */ const extractPubkey = (pubkey)=>{
476
+ var _pubkey_pubkey;
477
+ // Handle nested pubkey structure (e.g., {pubkey: {0: 33, 1: 209, ...}})
478
+ const actualPubkey = (_pubkey_pubkey = pubkey == null ? void 0 : pubkey.pubkey) != null ? _pubkey_pubkey : pubkey;
479
+ if (actualPubkey instanceof Uint8Array) {
480
+ return actualPubkey;
481
+ }
482
+ // Convert object with numeric keys to Uint8Array
483
+ if (typeof actualPubkey === 'object' && actualPubkey !== null) {
484
+ const keys = Object.keys(actualPubkey).map(Number).filter((k)=>!Number.isNaN(k)).sort((a, b)=>a - b);
485
+ if (keys.length > 0) {
486
+ const result = new Uint8Array(keys.map((k)=>actualPubkey[k]));
487
+ return result;
488
+ }
489
+ }
490
+ return actualPubkey;
491
+ };
471
492
  const getClientKeyShareExportFileName = ({ thresholdSignatureScheme, accountAddress, isGoogleDrive = false })=>{
472
493
  const suffix = isGoogleDrive ? '-google-drive' : '';
473
494
  return `${CLIENT_KEYSHARE_EXPORT_FILENAME_PREFIX}-${thresholdSignatureScheme}-${accountAddress}${suffix}.json`;
@@ -580,6 +601,17 @@ const formatSolanaMessage = (message)=>{
580
601
  return message;
581
602
  }
582
603
  };
604
+ const formatTonMessage = (message)=>{
605
+ if (typeof message === 'string') {
606
+ if (!isHexString(message)) {
607
+ return Buffer.from(message).toString('hex');
608
+ } else {
609
+ return new Uint8Array(Buffer.from(message, 'hex'));
610
+ }
611
+ } else {
612
+ return message;
613
+ }
614
+ };
583
615
  const formatMessage = (chainName, message)=>{
584
616
  switch(chainName){
585
617
  case 'EVM':
@@ -588,6 +620,8 @@ const formatMessage = (chainName, message)=>{
588
620
  return formatSolanaMessage(message);
589
621
  case 'SUI':
590
622
  return message;
623
+ case 'TON':
624
+ return formatTonMessage(message);
591
625
  default:
592
626
  throw new Error('Unsupported chain name');
593
627
  }
@@ -825,21 +859,21 @@ class WalletBusyError extends Error {
825
859
  }
826
860
  }
827
861
  const createDelegationWithGoogleDriveDistribution = ({ existingShares, delegatedShare })=>({
828
- dynamicBackendShares: existingShares,
862
+ clientShares: existingShares,
829
863
  googleDriveShares: existingShares,
830
864
  delegatedShare
831
865
  });
832
866
  const createDelegationOnlyDistribution = ({ existingShares, delegatedShare })=>({
833
- dynamicBackendShares: existingShares,
867
+ clientShares: existingShares,
834
868
  googleDriveShares: [],
835
869
  delegatedShare
836
870
  });
837
871
  const createGoogleDriveOnlyDistribution = ({ allShares })=>({
838
- dynamicBackendShares: allShares.slice(0, -1),
872
+ clientShares: allShares.slice(0, -1),
839
873
  googleDriveShares: allShares.slice(-1)
840
874
  });
841
875
  const createDynamicOnlyDistribution = ({ allShares })=>({
842
- dynamicBackendShares: allShares,
876
+ clientShares: allShares,
843
877
  googleDriveShares: []
844
878
  });
845
879
  const hasGoogleDriveBackup = (backupInfo)=>{
@@ -857,10 +891,11 @@ const hasDelegatedBackup = (backupInfo)=>{
857
891
  * Client's shares go to both Dynamic and Google Drive.
858
892
  * delegatedShare is undefined - we don't re-publish, but preserve the location.
859
893
  */ const createAddGoogleDriveToExistingDelegationDistribution = ({ clientShares })=>({
860
- dynamicBackendShares: clientShares,
894
+ clientShares: clientShares,
861
895
  googleDriveShares: clientShares
862
896
  });
863
897
 
898
+ // eslint-disable-next-line @nx/enforce-module-boundaries
864
899
  class DynamicWalletClient {
865
900
  async initializeForwardMPCClient() {
866
901
  try {
@@ -1031,47 +1066,53 @@ class DynamicWalletClient {
1031
1066
  };
1032
1067
  }
1033
1068
  }
1034
- async serverInitializeKeyGen({ chainName, clientKeygenIds, dynamicRequestId, thresholdSignatureScheme, onError, onCeremonyComplete }) {
1069
+ async serverInitializeKeyGen({ chainName, clientKeygenIds, dynamicRequestId, thresholdSignatureScheme, bitcoinConfig, onError, onCeremonyComplete }) {
1035
1070
  // Initialize keygen, create room, and create the wallet account on the server
1036
1071
  const data = await this.apiClient.createWalletAccount({
1037
1072
  chainName,
1038
1073
  clientKeygenIds,
1039
1074
  dynamicRequestId,
1040
1075
  thresholdSignatureScheme,
1076
+ bitcoinConfig,
1041
1077
  onError,
1042
1078
  onCeremonyComplete
1043
1079
  });
1044
1080
  this.logger.debug(`[DynamicWaasWalletClient] Initialized client key generation with IDs: ${clientKeygenIds.join(', ')} for chain: ${chainName} using scheme: ${thresholdSignatureScheme}`);
1045
1081
  return data;
1046
1082
  }
1047
- async clientInitializeKeyGen({ chainName, thresholdSignatureScheme }) {
1083
+ async clientInitializeKeyGen({ chainName, thresholdSignatureScheme, bitcoinConfig }) {
1048
1084
  // Get the mpc signer
1049
1085
  const mpcSigner = getMPCSigner({
1050
1086
  chainName,
1051
- baseRelayUrl: this.baseMPCRelayApiUrl
1087
+ baseRelayUrl: this.baseMPCRelayApiUrl,
1088
+ bitcoinConfig
1052
1089
  });
1053
1090
  const clientThreshold = core.getClientThreshold(thresholdSignatureScheme);
1054
1091
  const keygenInitResults = await Promise.all(Array(clientThreshold).fill(null).map(()=>mpcSigner.initKeygen()));
1055
1092
  return keygenInitResults;
1056
1093
  }
1057
- async derivePublicKey({ chainName, keyShare, derivationPath }) {
1094
+ async derivePublicKey({ chainName, keyShare, derivationPath, bitcoinConfig }) {
1058
1095
  const mpcSigner = getMPCSigner({
1059
1096
  chainName,
1060
- baseRelayUrl: this.baseMPCRelayApiUrl
1097
+ baseRelayUrl: this.baseMPCRelayApiUrl,
1098
+ bitcoinConfig
1061
1099
  });
1062
1100
  let publicKey;
1063
1101
  if (mpcSigner instanceof web.Ecdsa) {
1064
1102
  publicKey = await mpcSigner.derivePubkey(keyShare, derivationPath);
1065
1103
  } else if (mpcSigner instanceof web.ExportableEd25519) {
1066
1104
  publicKey = await mpcSigner.getPubkey(keyShare);
1105
+ } else if (mpcSigner instanceof web.BIP340) {
1106
+ publicKey = await mpcSigner.deriveTweakPubkey(keyShare, derivationPath);
1067
1107
  }
1068
1108
  return publicKey;
1069
1109
  }
1070
- async clientKeyGen({ chainName, roomId, serverKeygenIds, clientKeygenInitResults, thresholdSignatureScheme }) {
1110
+ async clientKeyGen({ chainName, roomId, serverKeygenIds, clientKeygenInitResults, thresholdSignatureScheme, bitcoinConfig }) {
1071
1111
  // Get the chain config and the mpc signer
1072
1112
  const mpcSigner = getMPCSigner({
1073
1113
  chainName,
1074
- baseRelayUrl: this.baseMPCRelayApiUrl
1114
+ baseRelayUrl: this.baseMPCRelayApiUrl,
1115
+ bitcoinConfig
1075
1116
  });
1076
1117
  // Get the MPC config for the threshold signature scheme
1077
1118
  const mpcConfig = core.MPC_CONFIG[thresholdSignatureScheme];
@@ -1094,24 +1135,26 @@ class DynamicWalletClient {
1094
1135
  }));
1095
1136
  // only need one client keygen result to derive the public key
1096
1137
  const [clientKeygenResult] = clientKeygenResults;
1097
- const chainConfig = core.getMPCChainConfig(chainName);
1138
+ const chainConfig = core.getMPCChainConfig(chainName, bitcoinConfig);
1098
1139
  const derivationPath = new Uint32Array(chainConfig.derivationPath);
1099
1140
  const rawPublicKey = await this.derivePublicKey({
1100
1141
  chainName,
1101
1142
  keyShare: clientKeygenResult,
1102
- derivationPath
1143
+ derivationPath,
1144
+ bitcoinConfig
1103
1145
  });
1104
1146
  return {
1105
1147
  rawPublicKey,
1106
1148
  clientKeygenResults
1107
1149
  };
1108
1150
  }
1109
- async keyGen({ chainName, thresholdSignatureScheme, onError, onCeremonyComplete, traceContext }) {
1151
+ async keyGen({ chainName, thresholdSignatureScheme, bitcoinConfig, onError, onCeremonyComplete, traceContext }) {
1110
1152
  const dynamicRequestId = uuid.v4();
1111
1153
  try {
1112
1154
  const clientKeygenInitResults = await this.clientInitializeKeyGen({
1113
1155
  chainName,
1114
- thresholdSignatureScheme
1156
+ thresholdSignatureScheme,
1157
+ bitcoinConfig
1115
1158
  });
1116
1159
  const clientKeygenIds = clientKeygenInitResults.map((result)=>result.keygenId);
1117
1160
  this.instrument('[DynamicWaasWalletClient] Initialized client key generation', _extends({
@@ -1125,6 +1168,7 @@ class DynamicWalletClient {
1125
1168
  clientKeygenIds,
1126
1169
  dynamicRequestId,
1127
1170
  thresholdSignatureScheme,
1171
+ bitcoinConfig,
1128
1172
  onCeremonyComplete
1129
1173
  });
1130
1174
  this.instrument('[DynamicWaasWalletClient] Server key generation initialized', _extends({
@@ -1140,7 +1184,8 @@ class DynamicWalletClient {
1140
1184
  roomId,
1141
1185
  serverKeygenIds,
1142
1186
  clientKeygenInitResults,
1143
- thresholdSignatureScheme
1187
+ thresholdSignatureScheme,
1188
+ bitcoinConfig
1144
1189
  });
1145
1190
  this.instrument('[DynamicWaasWalletClient] Client key generation completed', _extends({
1146
1191
  roomId,
@@ -1256,7 +1301,7 @@ class DynamicWalletClient {
1256
1301
  throw error;
1257
1302
  }
1258
1303
  }
1259
- async serverSign({ walletId, message, isFormatted, mfaToken, roomId, context, onError, dynamicRequestId, traceContext }) {
1304
+ async serverSign({ walletId, message, isFormatted, mfaToken, roomId, context, onError, dynamicRequestId, traceContext, bitcoinConfig }) {
1260
1305
  // Create the room and sign the message
1261
1306
  if (typeof message !== 'string') {
1262
1307
  message = `0x${Buffer.from(message).toString('hex')}`;
@@ -1271,7 +1316,8 @@ class DynamicWalletClient {
1271
1316
  context: context ? JSON.parse(JSON.stringify(context, (_key, value)=>typeof value === 'bigint' ? value.toString() : value)) : undefined,
1272
1317
  onError,
1273
1318
  forwardMPCClientEnabled: this.forwardMPCEnabled,
1274
- traceContext
1319
+ traceContext,
1320
+ bitcoinConfig
1275
1321
  });
1276
1322
  return data;
1277
1323
  }
@@ -1319,11 +1365,12 @@ class DynamicWalletClient {
1319
1365
  throw error;
1320
1366
  }
1321
1367
  }
1322
- async clientSign({ chainName, message, roomId, keyShare, derivationPath, isFormatted, dynamicRequestId, traceContext }) {
1368
+ async clientSign({ chainName, message, roomId, keyShare, derivationPath, isFormatted, dynamicRequestId, traceContext, bitcoinConfig }) {
1323
1369
  try {
1324
1370
  const mpcSigner = getMPCSigner({
1325
1371
  chainName,
1326
- baseRelayUrl: this.baseMPCRelayApiUrl
1372
+ baseRelayUrl: this.baseMPCRelayApiUrl,
1373
+ bitcoinConfig
1327
1374
  });
1328
1375
  const formattedMessage = isFormatted ? new web.MessageHash(message) : formatMessage(chainName, message);
1329
1376
  this.logger.debug('[DynamicWaasWalletClient] Starting client sign', _extends({
@@ -1346,7 +1393,13 @@ class DynamicWalletClient {
1346
1393
  traceContext
1347
1394
  });
1348
1395
  }
1349
- const signature = await mpcSigner.sign(roomId, keyShare, formattedMessage, derivationPath);
1396
+ // Unwrap MessageHash for BIP340 as it expects Uint8Array or hex string
1397
+ let messageToSign = formattedMessage;
1398
+ if (mpcSigner instanceof web.BIP340 && formattedMessage instanceof web.MessageHash) {
1399
+ messageToSign = formattedMessage.bytes;
1400
+ }
1401
+ const tweak = bitcoinConfig == null ? void 0 : bitcoinConfig.tweak;
1402
+ const signature = await mpcSigner.sign(roomId, keyShare, messageToSign, derivationPath, tweak);
1350
1403
  return signature;
1351
1404
  } catch (error) {
1352
1405
  logError({
@@ -1364,7 +1417,7 @@ class DynamicWalletClient {
1364
1417
  }
1365
1418
  }
1366
1419
  //todo: need to modify with imported flag
1367
- async sign({ accountAddress, message, chainName, password = undefined, isFormatted = false, signedSessionId, mfaToken, context, onError, traceContext }) {
1420
+ async sign({ accountAddress, message, chainName, password = undefined, isFormatted = false, signedSessionId, mfaToken, context, onError, traceContext, bitcoinConfig }) {
1368
1421
  const dynamicRequestId = uuid.v4();
1369
1422
  try {
1370
1423
  await this.waitForWalletNotBusy(accountAddress);
@@ -1395,7 +1448,7 @@ class DynamicWalletClient {
1395
1448
  }, this.getTraceContext(traceContext)));
1396
1449
  }
1397
1450
  }
1398
- // Perform the server sign - always call, but only await if roomId is not provided
1451
+ // Perform the server sign
1399
1452
  const serverSignPromise = this.serverSign({
1400
1453
  walletId: wallet.walletId,
1401
1454
  message,
@@ -1405,7 +1458,8 @@ class DynamicWalletClient {
1405
1458
  context,
1406
1459
  onError,
1407
1460
  dynamicRequestId,
1408
- traceContext
1461
+ traceContext,
1462
+ bitcoinConfig
1409
1463
  });
1410
1464
  // Only await if roomId is not provided
1411
1465
  roomId = roomId != null ? roomId : (await serverSignPromise).roomId;
@@ -1431,7 +1485,8 @@ class DynamicWalletClient {
1431
1485
  derivationPath,
1432
1486
  isFormatted,
1433
1487
  dynamicRequestId,
1434
- traceContext
1488
+ traceContext,
1489
+ bitcoinConfig
1435
1490
  });
1436
1491
  this.instrument('[DynamicWaasWalletClient] Client sign completed', _extends({
1437
1492
  accountAddress,
@@ -1525,13 +1580,38 @@ class DynamicWalletClient {
1525
1580
  throw error;
1526
1581
  }
1527
1582
  }
1528
- async getExportId({ chainName, clientKeyShare }) {
1583
+ async getExportId({ chainName, clientKeyShare, bitcoinConfig }) {
1529
1584
  const mpcSigner = getMPCSigner({
1530
1585
  chainName,
1531
- baseRelayUrl: this.baseMPCRelayApiUrl
1586
+ baseRelayUrl: this.baseMPCRelayApiUrl,
1587
+ bitcoinConfig
1532
1588
  });
1533
- const exportId = await mpcSigner.exportID(clientKeyShare);
1534
- return exportId;
1589
+ try {
1590
+ // For BIP340, try passing the secretShare as a string directly
1591
+ // The exportID accepts either BIP340KeygenResult or string (secretShare)
1592
+ let exportId;
1593
+ if (mpcSigner instanceof web.BIP340) {
1594
+ const secretShareString = clientKeyShare.secretShare;
1595
+ exportId = await mpcSigner.exportID(secretShareString);
1596
+ } else {
1597
+ exportId = await mpcSigner.exportID(clientKeyShare);
1598
+ }
1599
+ this.logger.debug('[DynamicWaasWalletClient] getExportId succeeded', {
1600
+ chainName,
1601
+ exportId
1602
+ });
1603
+ return exportId;
1604
+ } catch (error) {
1605
+ var _clientKeyShare_secretShare;
1606
+ this.logger.error('[DynamicWaasWalletClient] Error in getExportId', {
1607
+ chainName,
1608
+ error,
1609
+ errorMessage: error instanceof Error ? error.message : String(error),
1610
+ clientKeyShareType: clientKeyShare.constructor.name,
1611
+ secretSharePrefix: (_clientKeyShare_secretShare = clientKeyShare.secretShare) == null ? void 0 : _clientKeyShare_secretShare.substring(0, 100)
1612
+ });
1613
+ throw error;
1614
+ }
1535
1615
  }
1536
1616
  /**
1537
1617
  * Helper function to create client shares required to complete a reshare ceremony.
@@ -1656,21 +1736,6 @@ class DynamicWalletClient {
1656
1736
  Promise.all(existingResharePromises),
1657
1737
  Promise.all(newResharePromises)
1658
1738
  ]);
1659
- const clientKeysharesToLocalStorage = delegateToProjectEnvironment ? [
1660
- ...existingReshareResults
1661
- ] : [
1662
- ...existingReshareResults,
1663
- ...newReshareResults
1664
- ];
1665
- this.walletMap[accountAddress] = _extends({}, this.walletMap[accountAddress], {
1666
- thresholdSignatureScheme: newThresholdSignatureScheme
1667
- });
1668
- // store client key shares to localStorage
1669
- await this.setClientKeySharesToLocalStorage({
1670
- accountAddress,
1671
- clientKeyShares: clientKeysharesToLocalStorage,
1672
- overwriteOrMerge: 'overwrite'
1673
- });
1674
1739
  const allClientShares = [
1675
1740
  ...existingReshareResults,
1676
1741
  ...newReshareResults
@@ -1702,6 +1767,14 @@ class DynamicWalletClient {
1702
1767
  allShares: allClientShares
1703
1768
  });
1704
1769
  }
1770
+ this.walletMap[accountAddress] = _extends({}, this.walletMap[accountAddress], {
1771
+ thresholdSignatureScheme: newThresholdSignatureScheme
1772
+ });
1773
+ await this.setClientKeySharesToLocalStorage({
1774
+ accountAddress,
1775
+ clientKeyShares: distribution.clientShares,
1776
+ overwriteOrMerge: 'overwrite'
1777
+ });
1705
1778
  await this.backupSharesWithDistribution({
1706
1779
  accountAddress,
1707
1780
  password,
@@ -1797,7 +1870,16 @@ class DynamicWalletClient {
1797
1870
  operationName: 'revokeDelegation'
1798
1871
  });
1799
1872
  }
1800
- async exportKey({ accountAddress, chainName, password = undefined, signedSessionId, mfaToken, traceContext }) {
1873
+ createKeygenResult(mpcSigner, extractedPubkey, secretShare) {
1874
+ if (mpcSigner instanceof web.Ecdsa) {
1875
+ return new web.EcdsaKeygenResult(extractedPubkey, secretShare);
1876
+ }
1877
+ if (mpcSigner instanceof web.ExportableEd25519) {
1878
+ return new web.ExportableEd25519KeygenResult(extractedPubkey, secretShare);
1879
+ }
1880
+ return new web.BIP340KeygenResult(extractedPubkey, secretShare);
1881
+ }
1882
+ async exportKey({ accountAddress, chainName, bitcoinConfig, password = undefined, signedSessionId, mfaToken, traceContext }) {
1801
1883
  const dynamicRequestId = uuid.v4();
1802
1884
  try {
1803
1885
  const wallet = await this.getWallet({
@@ -1808,18 +1890,19 @@ class DynamicWalletClient {
1808
1890
  });
1809
1891
  const mpcSigner = getMPCSigner({
1810
1892
  chainName,
1811
- baseRelayUrl: this.baseMPCRelayApiUrl
1812
- });
1813
- const clientKeyShares = await this.getClientKeySharesFromLocalStorage({
1814
- accountAddress
1893
+ baseRelayUrl: this.baseMPCRelayApiUrl,
1894
+ bitcoinConfig
1815
1895
  });
1896
+ const reconstructedKeyShare = await this.getReconstructedKeyShare(accountAddress, mpcSigner);
1816
1897
  const exportId = await this.getExportId({
1817
1898
  chainName,
1818
- clientKeyShare: clientKeyShares[0]
1899
+ clientKeyShare: reconstructedKeyShare,
1900
+ bitcoinConfig
1819
1901
  });
1820
1902
  const data = await this.apiClient.exportKey({
1821
1903
  walletId: wallet.walletId,
1822
1904
  exportId,
1905
+ bitcoinConfig,
1823
1906
  dynamicRequestId,
1824
1907
  mfaToken
1825
1908
  });
@@ -1830,10 +1913,7 @@ class DynamicWalletClient {
1830
1913
  exportId,
1831
1914
  roomId: data.roomId
1832
1915
  }, this.getTraceContext(traceContext)));
1833
- const keyExportRaw = await mpcSigner.exportFullPrivateKey(data.roomId, clientKeyShares[0], exportId);
1834
- if (!keyExportRaw) {
1835
- throw new Error('Error exporting private key');
1836
- }
1916
+ const keyExportRaw = await this.performMPCExport(mpcSigner, reconstructedKeyShare, data.roomId, exportId, accountAddress, chainName);
1837
1917
  this.logger.debug('[DynamicWaasWalletClient] Completed export of private key', _extends({
1838
1918
  accountAddress,
1839
1919
  chainName,
@@ -1841,15 +1921,7 @@ class DynamicWalletClient {
1841
1921
  exportId,
1842
1922
  roomId: data.roomId
1843
1923
  }, this.getTraceContext(traceContext)));
1844
- const derivationPath = wallet.derivationPath && wallet.derivationPath != '' ? new Uint32Array(Object.values(JSON.parse(wallet.derivationPath))) : undefined;
1845
- let derivedPrivateKey;
1846
- if (mpcSigner instanceof web.Ecdsa) {
1847
- derivedPrivateKey = await mpcSigner.derivePrivateKeyFromXpriv(keyExportRaw, derivationPath);
1848
- } else if (mpcSigner instanceof web.ExportableEd25519) {
1849
- derivedPrivateKey = keyExportRaw;
1850
- } else if (mpcSigner instanceof web.BIP340) {
1851
- derivedPrivateKey = await mpcSigner.derivePrivateKeyFromXpriv(keyExportRaw, derivationPath);
1852
- }
1924
+ const derivedPrivateKey = await this.derivePrivateKeyFromExport(mpcSigner, keyExportRaw, wallet);
1853
1925
  return {
1854
1926
  derivedPrivateKey
1855
1927
  };
@@ -1866,6 +1938,63 @@ class DynamicWalletClient {
1866
1938
  throw error;
1867
1939
  }
1868
1940
  }
1941
+ async getReconstructedKeyShare(accountAddress, mpcSigner) {
1942
+ const clientKeyShares = await this.getClientKeySharesFromLocalStorage({
1943
+ accountAddress
1944
+ });
1945
+ if (!clientKeyShares || clientKeyShares.length === 0) {
1946
+ throw new Error('No client key shares found for account');
1947
+ }
1948
+ // Reconstruct the keygen result from the stored clientKeyShare
1949
+ // This is necessary because localStorage stores plain objects, not class instances
1950
+ const clientKeyShare = clientKeyShares[0];
1951
+ const extractedPubkey = extractPubkey(clientKeyShare.pubkey);
1952
+ return this.createKeygenResult(mpcSigner, extractedPubkey, clientKeyShare.secretShare);
1953
+ }
1954
+ async performMPCExport(mpcSigner, reconstructedKeyShare, roomId, exportId, accountAddress, chainName) {
1955
+ try {
1956
+ // For BIP340, try passing the secretShare as a string directly if the keygenResult doesn't work
1957
+ // The exportFullPrivateKey accepts either BIP340KeygenResult or string (secretShare)
1958
+ const secretShareString = reconstructedKeyShare.secretShare;
1959
+ const keygenResultToPass = mpcSigner instanceof web.BIP340 ? secretShareString || reconstructedKeyShare : reconstructedKeyShare;
1960
+ const keyExportRaw = await mpcSigner.exportFullPrivateKey(roomId, keygenResultToPass, exportId);
1961
+ if (!keyExportRaw) {
1962
+ throw new Error('Error exporting private key');
1963
+ }
1964
+ return keyExportRaw;
1965
+ } catch (exportError) {
1966
+ var _reconstructedKeyShare_secretShare, _reconstructedKeyShare_secretShare1;
1967
+ this.logger.error('[DynamicWaasWalletClient] Error in exportFullPrivateKey', {
1968
+ accountAddress,
1969
+ chainName,
1970
+ error: exportError,
1971
+ errorMessage: exportError instanceof Error ? exportError.message : String(exportError),
1972
+ errorStack: exportError instanceof Error ? exportError.stack : undefined,
1973
+ reconstructedKeyShareType: reconstructedKeyShare.constructor.name,
1974
+ reconstructedKeyShare: {
1975
+ pubkeyType: reconstructedKeyShare.pubkey instanceof Uint8Array ? 'Uint8Array' : typeof reconstructedKeyShare.pubkey,
1976
+ pubkeyLength: reconstructedKeyShare.pubkey instanceof Uint8Array ? reconstructedKeyShare.pubkey.length : 'N/A',
1977
+ secretShareType: typeof reconstructedKeyShare.secretShare,
1978
+ secretShareLength: (_reconstructedKeyShare_secretShare = reconstructedKeyShare.secretShare) == null ? void 0 : _reconstructedKeyShare_secretShare.length,
1979
+ secretSharePrefix: (_reconstructedKeyShare_secretShare1 = reconstructedKeyShare.secretShare) == null ? void 0 : _reconstructedKeyShare_secretShare1.substring(0, 100)
1980
+ },
1981
+ roomId: roomId,
1982
+ exportId
1983
+ });
1984
+ throw exportError;
1985
+ }
1986
+ }
1987
+ async derivePrivateKeyFromExport(mpcSigner, keyExportRaw, wallet) {
1988
+ const derivationPath = wallet.derivationPath && wallet.derivationPath != '' ? new Uint32Array(Object.values(JSON.parse(wallet.derivationPath))) : undefined;
1989
+ if (mpcSigner instanceof web.Ecdsa) {
1990
+ return mpcSigner.derivePrivateKeyFromXpriv(keyExportRaw, derivationPath);
1991
+ } else if (mpcSigner instanceof web.ExportableEd25519) {
1992
+ return keyExportRaw;
1993
+ } else if (mpcSigner instanceof web.BIP340) {
1994
+ return mpcSigner.derivePrivateKeyFromXpriv(keyExportRaw, derivationPath);
1995
+ }
1996
+ return undefined;
1997
+ }
1869
1998
  async offlineExportKey({ chainName, keyShares, derivationPath }) {
1870
1999
  try {
1871
2000
  if (!keyShares || keyShares.length < 2) {
@@ -1876,7 +2005,7 @@ class DynamicWalletClient {
1876
2005
  baseRelayUrl: this.baseMPCRelayApiUrl
1877
2006
  });
1878
2007
  const walletKeyShares = keyShares.map((keyShare)=>{
1879
- return mpcSigner instanceof web.Ecdsa ? new web.EcdsaKeygenResult(keyShare.pubkey, keyShare.secretShare) : mpcSigner instanceof web.ExportableEd25519 ? new web.ExportableEd25519KeygenResult(keyShare.pubkey, keyShare.secretShare) : new web.BIP340KeygenResult(keyShare.pubkey, keyShare.secretShare);
2008
+ return this.createKeygenResult(mpcSigner, extractPubkey(keyShare.pubkey), keyShare.secretShare);
1880
2009
  });
1881
2010
  const keyExportRaw = await mpcSigner.offlineExportFullPrivateKey(walletKeyShares);
1882
2011
  if (!keyExportRaw) {
@@ -1978,8 +2107,8 @@ class DynamicWalletClient {
1978
2107
  throw error;
1979
2108
  }
1980
2109
  const locations = [];
1981
- if (distribution.dynamicBackendShares.length > 0) {
1982
- const encryptedDynamicShares = await Promise.all(distribution.dynamicBackendShares.map((keyShare)=>this.encryptKeyShare({
2110
+ if (distribution.clientShares.length > 0) {
2111
+ const encryptedDynamicShares = await Promise.all(distribution.clientShares.map((keyShare)=>this.encryptKeyShare({
1983
2112
  keyShare,
1984
2113
  password
1985
2114
  })));
@@ -2139,6 +2268,7 @@ class DynamicWalletClient {
2139
2268
  preserveDelegatedLocation = true;
2140
2269
  } else if (shouldBackupToGoogleDrive && keySharesToBackup.length >= 2) {
2141
2270
  // Google Drive only (no delegation): Split shares between Dynamic (N-1) and Google Drive (1).
2271
+ // The last share (new share) goes to Google Drive.
2142
2272
  distribution = createGoogleDriveOnlyDistribution({
2143
2273
  allShares: keySharesToBackup
2144
2274
  });
@@ -2727,7 +2857,8 @@ class DynamicWalletClient {
2727
2857
  derivationPath: walletProperties.derivationPath,
2728
2858
  clientKeySharesBackupInfo: getClientKeyShareBackupInfo({
2729
2859
  walletProperties
2730
- })
2860
+ }),
2861
+ addressType: walletProperties.addressType
2731
2862
  });
2732
2863
  if (walletOperation !== core.WalletOperation.NO_OPERATION && await this.requiresRestoreBackupSharesForOperation({
2733
2864
  accountAddress,
@@ -2781,7 +2912,7 @@ class DynamicWalletClient {
2781
2912
  this.userId = user.id;
2782
2913
  const waasWallets = (_user_verifiedCredentials = user.verifiedCredentials) == null ? void 0 : _user_verifiedCredentials.filter((vc)=>vc.walletName === 'dynamicwaas');
2783
2914
  const wallets = waasWallets.map((vc)=>{
2784
- var _this_walletMap_vc_address, _vc_walletProperties;
2915
+ var _this_walletMap_vc_address, _vc_walletProperties, _vc_walletProperties1;
2785
2916
  var _this_walletMap_vc_address_derivationPath;
2786
2917
  return {
2787
2918
  walletId: vc.id,
@@ -2791,7 +2922,8 @@ class DynamicWalletClient {
2791
2922
  walletProperties: vc.walletProperties || {}
2792
2923
  }),
2793
2924
  derivationPath: (_this_walletMap_vc_address_derivationPath = (_this_walletMap_vc_address = this.walletMap[vc.address]) == null ? void 0 : _this_walletMap_vc_address.derivationPath) != null ? _this_walletMap_vc_address_derivationPath : undefined,
2794
- thresholdSignatureScheme: (_vc_walletProperties = vc.walletProperties) == null ? void 0 : _vc_walletProperties.thresholdSignatureScheme
2925
+ thresholdSignatureScheme: (_vc_walletProperties = vc.walletProperties) == null ? void 0 : _vc_walletProperties.thresholdSignatureScheme,
2926
+ addressType: (_vc_walletProperties1 = vc.walletProperties) == null ? void 0 : _vc_walletProperties1.addressType
2795
2927
  };
2796
2928
  });
2797
2929
  this.walletMap = wallets.reduce((acc, wallet)=>{
@@ -2803,7 +2935,8 @@ class DynamicWalletClient {
2803
2935
  accountAddress: wallet.accountAddress,
2804
2936
  clientKeySharesBackupInfo: wallet.clientKeySharesBackupInfo,
2805
2937
  derivationPath: ((_acc_accountAddress = acc[accountAddress]) == null ? void 0 : _acc_accountAddress.derivationPath) || undefined,
2806
- thresholdSignatureScheme: wallet.thresholdSignatureScheme
2938
+ thresholdSignatureScheme: wallet.thresholdSignatureScheme,
2939
+ addressType: wallet.addressType
2807
2940
  };
2808
2941
  return acc;
2809
2942
  }, {});
@@ -3076,6 +3209,7 @@ exports.createDelegationWithGoogleDriveDistribution = createDelegationWithGoogle
3076
3209
  exports.createDynamicOnlyDistribution = createDynamicOnlyDistribution;
3077
3210
  exports.createGoogleDriveOnlyDistribution = createGoogleDriveOnlyDistribution;
3078
3211
  exports.downloadStringAsFile = downloadStringAsFile;
3212
+ exports.extractPubkey = extractPubkey;
3079
3213
  exports.formatEvmMessage = formatEvmMessage;
3080
3214
  exports.formatMessage = formatMessage;
3081
3215
  exports.getClientKeyShareBackupInfo = getClientKeyShareBackupInfo;