@dynamic-labs-wallet/browser 0.0.229 → 0.0.231
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 +192 -51
- package/index.esm.js +192 -52
- package/package.json +2 -2
- package/src/client.d.ts +27 -13
- package/src/client.d.ts.map +1 -1
- package/src/mpc/index.d.ts.map +1 -1
- package/src/mpc/mpc.d.ts +3 -1
- package/src/mpc/mpc.d.ts.map +1 -1
- package/src/mpc/types.d.ts +3 -2
- package/src/mpc/types.d.ts.map +1 -1
- package/src/types.d.ts +1 -0
- package/src/types.d.ts.map +1 -1
- package/src/utils.d.ts +6 -1
- package/src/utils.d.ts.map +1 -1
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
|
}
|
|
@@ -861,6 +895,7 @@ const hasDelegatedBackup = (backupInfo)=>{
|
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
1534
|
-
|
|
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.
|
|
@@ -1790,7 +1870,16 @@ class DynamicWalletClient {
|
|
|
1790
1870
|
operationName: 'revokeDelegation'
|
|
1791
1871
|
});
|
|
1792
1872
|
}
|
|
1793
|
-
|
|
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 }) {
|
|
1794
1883
|
const dynamicRequestId = uuid.v4();
|
|
1795
1884
|
try {
|
|
1796
1885
|
const wallet = await this.getWallet({
|
|
@@ -1801,18 +1890,19 @@ class DynamicWalletClient {
|
|
|
1801
1890
|
});
|
|
1802
1891
|
const mpcSigner = getMPCSigner({
|
|
1803
1892
|
chainName,
|
|
1804
|
-
baseRelayUrl: this.baseMPCRelayApiUrl
|
|
1805
|
-
|
|
1806
|
-
const clientKeyShares = await this.getClientKeySharesFromLocalStorage({
|
|
1807
|
-
accountAddress
|
|
1893
|
+
baseRelayUrl: this.baseMPCRelayApiUrl,
|
|
1894
|
+
bitcoinConfig
|
|
1808
1895
|
});
|
|
1896
|
+
const reconstructedKeyShare = await this.getReconstructedKeyShare(accountAddress, mpcSigner);
|
|
1809
1897
|
const exportId = await this.getExportId({
|
|
1810
1898
|
chainName,
|
|
1811
|
-
clientKeyShare:
|
|
1899
|
+
clientKeyShare: reconstructedKeyShare,
|
|
1900
|
+
bitcoinConfig
|
|
1812
1901
|
});
|
|
1813
1902
|
const data = await this.apiClient.exportKey({
|
|
1814
1903
|
walletId: wallet.walletId,
|
|
1815
1904
|
exportId,
|
|
1905
|
+
bitcoinConfig,
|
|
1816
1906
|
dynamicRequestId,
|
|
1817
1907
|
mfaToken
|
|
1818
1908
|
});
|
|
@@ -1823,10 +1913,7 @@ class DynamicWalletClient {
|
|
|
1823
1913
|
exportId,
|
|
1824
1914
|
roomId: data.roomId
|
|
1825
1915
|
}, this.getTraceContext(traceContext)));
|
|
1826
|
-
const keyExportRaw = await
|
|
1827
|
-
if (!keyExportRaw) {
|
|
1828
|
-
throw new Error('Error exporting private key');
|
|
1829
|
-
}
|
|
1916
|
+
const keyExportRaw = await this.performMPCExport(mpcSigner, reconstructedKeyShare, data.roomId, exportId, accountAddress, chainName);
|
|
1830
1917
|
this.logger.debug('[DynamicWaasWalletClient] Completed export of private key', _extends({
|
|
1831
1918
|
accountAddress,
|
|
1832
1919
|
chainName,
|
|
@@ -1834,15 +1921,7 @@ class DynamicWalletClient {
|
|
|
1834
1921
|
exportId,
|
|
1835
1922
|
roomId: data.roomId
|
|
1836
1923
|
}, this.getTraceContext(traceContext)));
|
|
1837
|
-
const
|
|
1838
|
-
let derivedPrivateKey;
|
|
1839
|
-
if (mpcSigner instanceof web.Ecdsa) {
|
|
1840
|
-
derivedPrivateKey = await mpcSigner.derivePrivateKeyFromXpriv(keyExportRaw, derivationPath);
|
|
1841
|
-
} else if (mpcSigner instanceof web.ExportableEd25519) {
|
|
1842
|
-
derivedPrivateKey = keyExportRaw;
|
|
1843
|
-
} else if (mpcSigner instanceof web.BIP340) {
|
|
1844
|
-
derivedPrivateKey = await mpcSigner.derivePrivateKeyFromXpriv(keyExportRaw, derivationPath);
|
|
1845
|
-
}
|
|
1924
|
+
const derivedPrivateKey = await this.derivePrivateKeyFromExport(mpcSigner, keyExportRaw, wallet);
|
|
1846
1925
|
return {
|
|
1847
1926
|
derivedPrivateKey
|
|
1848
1927
|
};
|
|
@@ -1859,6 +1938,63 @@ class DynamicWalletClient {
|
|
|
1859
1938
|
throw error;
|
|
1860
1939
|
}
|
|
1861
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
|
+
}
|
|
1862
1998
|
async offlineExportKey({ chainName, keyShares, derivationPath }) {
|
|
1863
1999
|
try {
|
|
1864
2000
|
if (!keyShares || keyShares.length < 2) {
|
|
@@ -1869,7 +2005,7 @@ class DynamicWalletClient {
|
|
|
1869
2005
|
baseRelayUrl: this.baseMPCRelayApiUrl
|
|
1870
2006
|
});
|
|
1871
2007
|
const walletKeyShares = keyShares.map((keyShare)=>{
|
|
1872
|
-
return
|
|
2008
|
+
return this.createKeygenResult(mpcSigner, extractPubkey(keyShare.pubkey), keyShare.secretShare);
|
|
1873
2009
|
});
|
|
1874
2010
|
const keyExportRaw = await mpcSigner.offlineExportFullPrivateKey(walletKeyShares);
|
|
1875
2011
|
if (!keyExportRaw) {
|
|
@@ -2132,6 +2268,7 @@ class DynamicWalletClient {
|
|
|
2132
2268
|
preserveDelegatedLocation = true;
|
|
2133
2269
|
} else if (shouldBackupToGoogleDrive && keySharesToBackup.length >= 2) {
|
|
2134
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.
|
|
2135
2272
|
distribution = createGoogleDriveOnlyDistribution({
|
|
2136
2273
|
allShares: keySharesToBackup
|
|
2137
2274
|
});
|
|
@@ -2720,7 +2857,8 @@ class DynamicWalletClient {
|
|
|
2720
2857
|
derivationPath: walletProperties.derivationPath,
|
|
2721
2858
|
clientKeySharesBackupInfo: getClientKeyShareBackupInfo({
|
|
2722
2859
|
walletProperties
|
|
2723
|
-
})
|
|
2860
|
+
}),
|
|
2861
|
+
addressType: walletProperties.addressType
|
|
2724
2862
|
});
|
|
2725
2863
|
if (walletOperation !== core.WalletOperation.NO_OPERATION && await this.requiresRestoreBackupSharesForOperation({
|
|
2726
2864
|
accountAddress,
|
|
@@ -2774,7 +2912,7 @@ class DynamicWalletClient {
|
|
|
2774
2912
|
this.userId = user.id;
|
|
2775
2913
|
const waasWallets = (_user_verifiedCredentials = user.verifiedCredentials) == null ? void 0 : _user_verifiedCredentials.filter((vc)=>vc.walletName === 'dynamicwaas');
|
|
2776
2914
|
const wallets = waasWallets.map((vc)=>{
|
|
2777
|
-
var _this_walletMap_vc_address, _vc_walletProperties;
|
|
2915
|
+
var _this_walletMap_vc_address, _vc_walletProperties, _vc_walletProperties1;
|
|
2778
2916
|
var _this_walletMap_vc_address_derivationPath;
|
|
2779
2917
|
return {
|
|
2780
2918
|
walletId: vc.id,
|
|
@@ -2784,7 +2922,8 @@ class DynamicWalletClient {
|
|
|
2784
2922
|
walletProperties: vc.walletProperties || {}
|
|
2785
2923
|
}),
|
|
2786
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,
|
|
2787
|
-
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
|
|
2788
2927
|
};
|
|
2789
2928
|
});
|
|
2790
2929
|
this.walletMap = wallets.reduce((acc, wallet)=>{
|
|
@@ -2796,7 +2935,8 @@ class DynamicWalletClient {
|
|
|
2796
2935
|
accountAddress: wallet.accountAddress,
|
|
2797
2936
|
clientKeySharesBackupInfo: wallet.clientKeySharesBackupInfo,
|
|
2798
2937
|
derivationPath: ((_acc_accountAddress = acc[accountAddress]) == null ? void 0 : _acc_accountAddress.derivationPath) || undefined,
|
|
2799
|
-
thresholdSignatureScheme: wallet.thresholdSignatureScheme
|
|
2938
|
+
thresholdSignatureScheme: wallet.thresholdSignatureScheme,
|
|
2939
|
+
addressType: wallet.addressType
|
|
2800
2940
|
};
|
|
2801
2941
|
return acc;
|
|
2802
2942
|
}, {});
|
|
@@ -3069,6 +3209,7 @@ exports.createDelegationWithGoogleDriveDistribution = createDelegationWithGoogle
|
|
|
3069
3209
|
exports.createDynamicOnlyDistribution = createDynamicOnlyDistribution;
|
|
3070
3210
|
exports.createGoogleDriveOnlyDistribution = createGoogleDriveOnlyDistribution;
|
|
3071
3211
|
exports.downloadStringAsFile = downloadStringAsFile;
|
|
3212
|
+
exports.extractPubkey = extractPubkey;
|
|
3072
3213
|
exports.formatEvmMessage = formatEvmMessage;
|
|
3073
3214
|
exports.formatMessage = formatMessage;
|
|
3074
3215
|
exports.getClientKeyShareBackupInfo = getClientKeyShareBackupInfo;
|