@dynamic-labs-wallet/core 0.0.0-preview.112
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.d.ts +1 -0
- package/index.cjs.js +715 -0
- package/index.esm.d.ts +1 -0
- package/index.esm.js +686 -0
- package/package.json +33 -0
- package/src/api/api.d.ts +69 -0
- package/src/api/api.d.ts.map +1 -0
- package/src/api/client.d.ts +15 -0
- package/src/api/client.d.ts.map +1 -0
- package/src/api/index.d.ts +2 -0
- package/src/api/index.d.ts.map +1 -0
- package/src/constants.d.ts +42 -0
- package/src/constants.d.ts.map +1 -0
- package/src/eventStream/utils.d.ts +50 -0
- package/src/eventStream/utils.d.ts.map +1 -0
- package/src/index.d.ts +5 -0
- package/src/index.d.ts.map +1 -0
- package/src/mpc/constants.d.ts +44 -0
- package/src/mpc/constants.d.ts.map +1 -0
- package/src/mpc/index.d.ts +3 -0
- package/src/mpc/index.d.ts.map +1 -0
- package/src/mpc/utils.d.ts +52 -0
- package/src/mpc/utils.d.ts.map +1 -0
- package/src/types.d.ts +72 -0
- package/src/types.d.ts.map +1 -0
package/index.esm.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./src/index";
|
package/index.esm.js
ADDED
|
@@ -0,0 +1,686 @@
|
|
|
1
|
+
import axios from 'axios';
|
|
2
|
+
|
|
3
|
+
const DYNAMIC_AUTH_PROD_BASE_API_URL = 'https://app.dynamicauth.com';
|
|
4
|
+
const DYNAMIC_AUTH_PREPROD_BASE_API_URL = 'https://app.dynamic-preprod.xyz';
|
|
5
|
+
const DYNAMIC_CLIENT_RELAY_PROD_BASE_API_URL = 'https://app-dynamicauth-com-app-6e12fc400995.relay.evervault.app';
|
|
6
|
+
const DYNAMIC_CLIENT_RELAY_PREPROD_BASE_API_URL = 'https://app-dynamic-preprod-xyz-app-32d15525a875.relay.evervault.app';
|
|
7
|
+
const MPC_RELAY_PROD_API_URL = 'relay.dynamicauth.com';
|
|
8
|
+
const MPC_RELAY_PREPROD_API_URL = 'relay.dynamic-preprod.xyz';
|
|
9
|
+
const SOLANA_RPC_URL = 'https://api.devnet.solana.com';
|
|
10
|
+
const chain = {
|
|
11
|
+
EVM: 'EVM',
|
|
12
|
+
SOL: 'SOL',
|
|
13
|
+
COSMOS: 'COSMOS',
|
|
14
|
+
BTC: 'BTC',
|
|
15
|
+
FLOW: 'FLOW',
|
|
16
|
+
SUI: 'SUI'
|
|
17
|
+
};
|
|
18
|
+
var WalletOperation = /*#__PURE__*/ function(WalletOperation) {
|
|
19
|
+
WalletOperation["REACH_THRESHOLD"] = "REACH_THRESHOLD";
|
|
20
|
+
WalletOperation["REACH_ALL_PARTIES"] = "REACH_ALL_PARTIES";
|
|
21
|
+
WalletOperation["SIGN_MESSAGE"] = "SIGN_MESSAGE";
|
|
22
|
+
WalletOperation["SIGN_TRANSACTION"] = "SIGN_TRANSACTION";
|
|
23
|
+
WalletOperation["REFRESH"] = "REFRESH";
|
|
24
|
+
WalletOperation["RESHARE"] = "RESHARE";
|
|
25
|
+
WalletOperation["EXPORT_PRIVATE_KEY"] = "EXPORT_PRIVATE_KEY";
|
|
26
|
+
WalletOperation["NO_OPERATION"] = "NO_OPERATION";
|
|
27
|
+
return WalletOperation;
|
|
28
|
+
}({});
|
|
29
|
+
var BackupLocation = /*#__PURE__*/ function(BackupLocation) {
|
|
30
|
+
BackupLocation["DYNAMIC"] = "dynamic";
|
|
31
|
+
BackupLocation["GOOGLE_DRIVE"] = "googleDrive";
|
|
32
|
+
BackupLocation["ICLOUD"] = "iCloud";
|
|
33
|
+
BackupLocation["USER"] = "user";
|
|
34
|
+
BackupLocation["EXTERNAL"] = "external";
|
|
35
|
+
return BackupLocation;
|
|
36
|
+
}({});
|
|
37
|
+
// TODO: replace with apiClient proxy and move this to apiClient when ready
|
|
38
|
+
const IFRAME_DOMAIN_PREPROD = 'https://waas.dynamic-preprod.xyz';
|
|
39
|
+
const IFRAME_DOMAIN_PROD = 'https://waas.dynamicauth.com';
|
|
40
|
+
const ChainEnumToVerifiedCredentialName = {
|
|
41
|
+
BTC: 'bip122',
|
|
42
|
+
EVM: 'eip155',
|
|
43
|
+
FLOW: 'flow',
|
|
44
|
+
SOL: 'solana'
|
|
45
|
+
};
|
|
46
|
+
const VerifiedCredentialNameToChainEnum = {
|
|
47
|
+
bip122: 'BTC',
|
|
48
|
+
eip155: 'EVM',
|
|
49
|
+
solana: 'SOL'
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
var SigningAlgorithm = /*#__PURE__*/ function(SigningAlgorithm) {
|
|
53
|
+
SigningAlgorithm["ECDSA"] = "ECDSA";
|
|
54
|
+
SigningAlgorithm["ED25519"] = "ED25519";
|
|
55
|
+
SigningAlgorithm["BIP340"] = "BIP340";
|
|
56
|
+
return SigningAlgorithm;
|
|
57
|
+
}({});
|
|
58
|
+
const BITCOIN_DERIVATION_PATHS = {
|
|
59
|
+
LEGACY: [
|
|
60
|
+
44,
|
|
61
|
+
0,
|
|
62
|
+
0,
|
|
63
|
+
0,
|
|
64
|
+
0
|
|
65
|
+
],
|
|
66
|
+
// m/49'/0'/0'/0/0 - SegWit (P2SH-P2WPKH)
|
|
67
|
+
NATIVE_SEGWIT: [
|
|
68
|
+
84,
|
|
69
|
+
0,
|
|
70
|
+
0,
|
|
71
|
+
0,
|
|
72
|
+
0
|
|
73
|
+
],
|
|
74
|
+
// m/44'/0'/0'/0/0 - Legacy (P2PKH)
|
|
75
|
+
SEGWIT: [
|
|
76
|
+
49,
|
|
77
|
+
0,
|
|
78
|
+
0,
|
|
79
|
+
0,
|
|
80
|
+
0
|
|
81
|
+
]
|
|
82
|
+
};
|
|
83
|
+
const MPC_CHAIN_CONFIG = {
|
|
84
|
+
EVM: {
|
|
85
|
+
// Uses secp256k1 ECDSA
|
|
86
|
+
derivationPath: [
|
|
87
|
+
44,
|
|
88
|
+
60,
|
|
89
|
+
0,
|
|
90
|
+
0,
|
|
91
|
+
0
|
|
92
|
+
],
|
|
93
|
+
signingAlgorithm: "ECDSA"
|
|
94
|
+
},
|
|
95
|
+
SOL: {
|
|
96
|
+
// Uses Ed25519
|
|
97
|
+
derivationPath: [
|
|
98
|
+
44,
|
|
99
|
+
501,
|
|
100
|
+
0,
|
|
101
|
+
0,
|
|
102
|
+
0
|
|
103
|
+
],
|
|
104
|
+
signingAlgorithm: "ED25519"
|
|
105
|
+
},
|
|
106
|
+
BTC: {
|
|
107
|
+
// Uses secp256k1 BIP340
|
|
108
|
+
derivationPath: BITCOIN_DERIVATION_PATHS.NATIVE_SEGWIT,
|
|
109
|
+
signingAlgorithm: "BIP340"
|
|
110
|
+
},
|
|
111
|
+
COSMOS: {
|
|
112
|
+
// Uses Ed25519
|
|
113
|
+
derivationPath: [
|
|
114
|
+
44,
|
|
115
|
+
118,
|
|
116
|
+
0,
|
|
117
|
+
0,
|
|
118
|
+
0
|
|
119
|
+
],
|
|
120
|
+
signingAlgorithm: "ED25519"
|
|
121
|
+
},
|
|
122
|
+
FLOW: {
|
|
123
|
+
// Uses Ed25519
|
|
124
|
+
derivationPath: [
|
|
125
|
+
44,
|
|
126
|
+
539,
|
|
127
|
+
0,
|
|
128
|
+
0,
|
|
129
|
+
0
|
|
130
|
+
],
|
|
131
|
+
signingAlgorithm: "ED25519"
|
|
132
|
+
}
|
|
133
|
+
};
|
|
134
|
+
var ThresholdSignatureScheme = /*#__PURE__*/ function(ThresholdSignatureScheme) {
|
|
135
|
+
ThresholdSignatureScheme["TWO_OF_TWO"] = "TWO_OF_TWO";
|
|
136
|
+
ThresholdSignatureScheme["TWO_OF_THREE"] = "TWO_OF_THREE";
|
|
137
|
+
ThresholdSignatureScheme["THREE_OF_FIVE"] = "THREE_OF_FIVE";
|
|
138
|
+
return ThresholdSignatureScheme;
|
|
139
|
+
}({});
|
|
140
|
+
const MPC_CONFIG = {
|
|
141
|
+
["TWO_OF_TWO"]: {
|
|
142
|
+
numberOfParties: 2,
|
|
143
|
+
threshold: 2,
|
|
144
|
+
clientThreshold: 1,
|
|
145
|
+
dynamicServerThreshold: 1
|
|
146
|
+
},
|
|
147
|
+
["TWO_OF_THREE"]: {
|
|
148
|
+
numberOfParties: 3,
|
|
149
|
+
threshold: 2,
|
|
150
|
+
clientThreshold: 2,
|
|
151
|
+
dynamicServerThreshold: 1
|
|
152
|
+
},
|
|
153
|
+
["THREE_OF_FIVE"]: {
|
|
154
|
+
numberOfParties: 5,
|
|
155
|
+
threshold: 3,
|
|
156
|
+
clientThreshold: 3,
|
|
157
|
+
dynamicServerThreshold: 2
|
|
158
|
+
}
|
|
159
|
+
};
|
|
160
|
+
var CreateRoomPartiesOptions = /*#__PURE__*/ function(CreateRoomPartiesOptions) {
|
|
161
|
+
CreateRoomPartiesOptions["THRESHOLD"] = "threshold";
|
|
162
|
+
CreateRoomPartiesOptions["FULL"] = "full";
|
|
163
|
+
return CreateRoomPartiesOptions;
|
|
164
|
+
}({});
|
|
165
|
+
|
|
166
|
+
const getMPCChainConfig = (chainName)=>{
|
|
167
|
+
const chainConfig = MPC_CHAIN_CONFIG[chainName];
|
|
168
|
+
if (!chainConfig) {
|
|
169
|
+
throw new Error(`Chain ${chainName} not supported`);
|
|
170
|
+
}
|
|
171
|
+
return chainConfig;
|
|
172
|
+
};
|
|
173
|
+
const getTSSConfig = (thresholdSignatureScheme)=>{
|
|
174
|
+
const { threshold, numberOfParties } = MPC_CONFIG[thresholdSignatureScheme];
|
|
175
|
+
return {
|
|
176
|
+
threshold,
|
|
177
|
+
numberOfParties
|
|
178
|
+
};
|
|
179
|
+
};
|
|
180
|
+
const getClientThreshold = (thresholdSignatureScheme)=>{
|
|
181
|
+
return MPC_CONFIG[thresholdSignatureScheme].clientThreshold;
|
|
182
|
+
};
|
|
183
|
+
const getDynamicServerThreshold = (thresholdSignatureScheme)=>{
|
|
184
|
+
return MPC_CONFIG[thresholdSignatureScheme].dynamicServerThreshold;
|
|
185
|
+
};
|
|
186
|
+
/**
|
|
187
|
+
* Helper function to get the reshare config for client and server shares
|
|
188
|
+
* @param {ThresholdSignatureScheme} oldThresholdSignatureScheme - The current threshold signature scheme
|
|
189
|
+
* @param {ThresholdSignatureScheme} newThresholdSignatureScheme - The target threshold signature scheme
|
|
190
|
+
* @returns {{
|
|
191
|
+
* existingClientShareCount: number,
|
|
192
|
+
* newClientShareCount: number,
|
|
193
|
+
* existingServerShareCount: number,
|
|
194
|
+
* newServerShareCount: number
|
|
195
|
+
* }} The number of existing and new client and server shares needed
|
|
196
|
+
*/ const getReshareConfig = ({ oldThresholdSignatureScheme, newThresholdSignatureScheme })=>{
|
|
197
|
+
switch(true){
|
|
198
|
+
// 2-of-2 -> 2-of-2:
|
|
199
|
+
// -- dynamic server shares: 1 existing, 0 new
|
|
200
|
+
// -- client shares: 1 existing, 0 new
|
|
201
|
+
case oldThresholdSignatureScheme === ThresholdSignatureScheme.TWO_OF_TWO && newThresholdSignatureScheme === ThresholdSignatureScheme.TWO_OF_TWO:
|
|
202
|
+
return {
|
|
203
|
+
existingClientShareCount: 1,
|
|
204
|
+
newClientShareCount: 0,
|
|
205
|
+
existingServerShareCount: 1,
|
|
206
|
+
newServerShareCount: 0
|
|
207
|
+
};
|
|
208
|
+
// 2-of-3 -> 2-of-3:
|
|
209
|
+
// -- dynamic server shares: 1 existing, 0 new
|
|
210
|
+
// -- client shares: 1 existing, 1 new
|
|
211
|
+
case oldThresholdSignatureScheme === ThresholdSignatureScheme.TWO_OF_THREE && newThresholdSignatureScheme === ThresholdSignatureScheme.TWO_OF_THREE:
|
|
212
|
+
return {
|
|
213
|
+
existingClientShareCount: 1,
|
|
214
|
+
newClientShareCount: 1,
|
|
215
|
+
existingServerShareCount: 1,
|
|
216
|
+
newServerShareCount: 0
|
|
217
|
+
};
|
|
218
|
+
// 3-of-5 -> 3-of-5:
|
|
219
|
+
// -- dynamic server shares: 2 existing, 0 new
|
|
220
|
+
// -- client shares: 1 existing, 2 new
|
|
221
|
+
case oldThresholdSignatureScheme === ThresholdSignatureScheme.THREE_OF_FIVE && newThresholdSignatureScheme === ThresholdSignatureScheme.THREE_OF_FIVE:
|
|
222
|
+
return {
|
|
223
|
+
existingClientShareCount: 1,
|
|
224
|
+
newClientShareCount: 2,
|
|
225
|
+
existingServerShareCount: 2,
|
|
226
|
+
newServerShareCount: 0
|
|
227
|
+
};
|
|
228
|
+
// 2-of-2 -> 2-of-3:
|
|
229
|
+
// -- dynamic server shares: 1 existing, 0 new
|
|
230
|
+
// -- client shares: 1 existing, 1 new
|
|
231
|
+
case oldThresholdSignatureScheme === ThresholdSignatureScheme.TWO_OF_TWO && newThresholdSignatureScheme === ThresholdSignatureScheme.TWO_OF_THREE:
|
|
232
|
+
return {
|
|
233
|
+
existingClientShareCount: 1,
|
|
234
|
+
newClientShareCount: 1,
|
|
235
|
+
existingServerShareCount: 1,
|
|
236
|
+
newServerShareCount: 0
|
|
237
|
+
};
|
|
238
|
+
// 2-of-2 -> 3-of-5:
|
|
239
|
+
// -- dynamic server shares: 1 existing, 1 new
|
|
240
|
+
// -- client shares: 1 existing, 2 new
|
|
241
|
+
case oldThresholdSignatureScheme === ThresholdSignatureScheme.TWO_OF_TWO && newThresholdSignatureScheme === ThresholdSignatureScheme.THREE_OF_FIVE:
|
|
242
|
+
return {
|
|
243
|
+
existingClientShareCount: 1,
|
|
244
|
+
newClientShareCount: 2,
|
|
245
|
+
existingServerShareCount: 1,
|
|
246
|
+
newServerShareCount: 1
|
|
247
|
+
};
|
|
248
|
+
// 2-of-3 -> 3-of-5:
|
|
249
|
+
// -- dynamic server shares: 1 existing, 1 new
|
|
250
|
+
// -- client shares: 1 existing, 2 new
|
|
251
|
+
case oldThresholdSignatureScheme === ThresholdSignatureScheme.TWO_OF_THREE && newThresholdSignatureScheme === ThresholdSignatureScheme.THREE_OF_FIVE:
|
|
252
|
+
return {
|
|
253
|
+
existingClientShareCount: 1,
|
|
254
|
+
newClientShareCount: 2,
|
|
255
|
+
existingServerShareCount: 1,
|
|
256
|
+
newServerShareCount: 1
|
|
257
|
+
};
|
|
258
|
+
// 2-of-3 -> 2-of-2:
|
|
259
|
+
// -- dynamic server shares: 1 existing, 0 new
|
|
260
|
+
// -- client shares: 1 existing, 0 new
|
|
261
|
+
case oldThresholdSignatureScheme === ThresholdSignatureScheme.TWO_OF_THREE && newThresholdSignatureScheme === ThresholdSignatureScheme.TWO_OF_TWO:
|
|
262
|
+
return {
|
|
263
|
+
existingClientShareCount: 1,
|
|
264
|
+
newClientShareCount: 0,
|
|
265
|
+
existingServerShareCount: 1,
|
|
266
|
+
newServerShareCount: 0
|
|
267
|
+
};
|
|
268
|
+
// 3-of-5 -> 2-of-3:
|
|
269
|
+
// -- dynamic server shares: 1 existing, 0 new
|
|
270
|
+
// -- client shares: 2 existing, 0 new
|
|
271
|
+
case oldThresholdSignatureScheme === ThresholdSignatureScheme.THREE_OF_FIVE && newThresholdSignatureScheme === ThresholdSignatureScheme.TWO_OF_THREE:
|
|
272
|
+
return {
|
|
273
|
+
existingClientShareCount: 2,
|
|
274
|
+
newClientShareCount: 0,
|
|
275
|
+
existingServerShareCount: 1,
|
|
276
|
+
newServerShareCount: 0
|
|
277
|
+
};
|
|
278
|
+
default:
|
|
279
|
+
throw new Error(`Unsupported reshare from ${oldThresholdSignatureScheme} to ${newThresholdSignatureScheme}`);
|
|
280
|
+
}
|
|
281
|
+
};
|
|
282
|
+
/**
|
|
283
|
+
* Helper function to get the reshare config for client and server shares
|
|
284
|
+
* @param {ThresholdSignatureScheme} oldThresholdSignatureScheme - The current threshold signature scheme
|
|
285
|
+
* @param {ThresholdSignatureScheme} newThresholdSignatureScheme - The target threshold signature scheme
|
|
286
|
+
* @returns {{
|
|
287
|
+
* existingServerShareCount: number,
|
|
288
|
+
* newServerhareCount: number,
|
|
289
|
+
* existingDynamicServerShareCount: number,
|
|
290
|
+
* newDynamicServerShareCount: number
|
|
291
|
+
* }} The number of existing and new client and server shares needed
|
|
292
|
+
*/ const getServerWalletReshareConfig = ({ oldThresholdSignatureScheme, newThresholdSignatureScheme })=>{
|
|
293
|
+
switch(true){
|
|
294
|
+
// 2-of-2 -> 2-of-2:
|
|
295
|
+
// -- dyanmic server shares: 1 existing, 0 new
|
|
296
|
+
// -- external server shares: 1 existing, 0 new
|
|
297
|
+
case oldThresholdSignatureScheme === ThresholdSignatureScheme.TWO_OF_TWO && newThresholdSignatureScheme === ThresholdSignatureScheme.TWO_OF_TWO:
|
|
298
|
+
return {
|
|
299
|
+
existingExternalServerShareCount: 1,
|
|
300
|
+
newExternalServerShareCount: 0,
|
|
301
|
+
existingDynamicServerShareCount: 1,
|
|
302
|
+
newDynamicServerShareCount: 0
|
|
303
|
+
};
|
|
304
|
+
// 2-of-3 -> 2-of-3:
|
|
305
|
+
// -- dyanmic server shares: 1 existing, 0 new
|
|
306
|
+
// -- external server shares: 1 existing, 1 new
|
|
307
|
+
case oldThresholdSignatureScheme === ThresholdSignatureScheme.TWO_OF_THREE && newThresholdSignatureScheme === ThresholdSignatureScheme.TWO_OF_THREE:
|
|
308
|
+
return {
|
|
309
|
+
existingExternalServerShareCount: 1,
|
|
310
|
+
newExternalServerShareCount: 1,
|
|
311
|
+
existingDynamicServerShareCount: 1,
|
|
312
|
+
newDynamicServerShareCount: 0
|
|
313
|
+
};
|
|
314
|
+
// 3-of-5 -> 3-of-5:
|
|
315
|
+
// -- dyanmic server shares: 2 existing, 0 new
|
|
316
|
+
// -- external server shares: 1 existing, 2 new
|
|
317
|
+
case oldThresholdSignatureScheme === ThresholdSignatureScheme.THREE_OF_FIVE && newThresholdSignatureScheme === ThresholdSignatureScheme.THREE_OF_FIVE:
|
|
318
|
+
return {
|
|
319
|
+
existingExternalServerShareCount: 1,
|
|
320
|
+
newExternalServerShareCount: 2,
|
|
321
|
+
existingDynamicServerShareCount: 2,
|
|
322
|
+
newDynamicServerShareCount: 0
|
|
323
|
+
};
|
|
324
|
+
// 2-of-2 -> 2-of-3:
|
|
325
|
+
// -- dyanmic server shares: 1 existing, 0 new
|
|
326
|
+
// -- external server shares: 1 existing, 1 new
|
|
327
|
+
case oldThresholdSignatureScheme === ThresholdSignatureScheme.TWO_OF_TWO && newThresholdSignatureScheme === ThresholdSignatureScheme.TWO_OF_THREE:
|
|
328
|
+
return {
|
|
329
|
+
existingExternalServerShareCount: 1,
|
|
330
|
+
newExternalServerShareCount: 1,
|
|
331
|
+
existingDynamicServerShareCount: 1,
|
|
332
|
+
newDynamicServerShareCount: 0
|
|
333
|
+
};
|
|
334
|
+
// 2-of-2 -> 3-of-5:
|
|
335
|
+
// -- dyanmic server shares: 1 existing, 1 new
|
|
336
|
+
// -- external server shares: 1 existing, 2 new
|
|
337
|
+
case oldThresholdSignatureScheme === ThresholdSignatureScheme.TWO_OF_TWO && newThresholdSignatureScheme === ThresholdSignatureScheme.THREE_OF_FIVE:
|
|
338
|
+
return {
|
|
339
|
+
existingExternalServerShareCount: 1,
|
|
340
|
+
newExternalServerShareCount: 2,
|
|
341
|
+
existingDynamicServerShareCount: 1,
|
|
342
|
+
newDynamicServerShareCount: 1
|
|
343
|
+
};
|
|
344
|
+
// 2-of-3 -> 3-of-5:
|
|
345
|
+
// -- dyanmic server shares: 1 existing, 1 new
|
|
346
|
+
// -- external server shares: 1 existing, 2 new
|
|
347
|
+
case oldThresholdSignatureScheme === ThresholdSignatureScheme.TWO_OF_THREE && newThresholdSignatureScheme === ThresholdSignatureScheme.THREE_OF_FIVE:
|
|
348
|
+
return {
|
|
349
|
+
existingExternalServerShareCount: 1,
|
|
350
|
+
newExternalServerShareCount: 2,
|
|
351
|
+
existingDynamicServerShareCount: 1,
|
|
352
|
+
newDynamicServerShareCount: 1
|
|
353
|
+
};
|
|
354
|
+
// 2-of-3 -> 2-of-2:
|
|
355
|
+
// -- dyanmic server shares: 1 existing, 0 new
|
|
356
|
+
// -- external server shares: 1 existing, 0 new
|
|
357
|
+
case oldThresholdSignatureScheme === ThresholdSignatureScheme.TWO_OF_THREE && newThresholdSignatureScheme === ThresholdSignatureScheme.TWO_OF_TWO:
|
|
358
|
+
return {
|
|
359
|
+
existingExternalServerShareCount: 1,
|
|
360
|
+
newExternalServerShareCount: 0,
|
|
361
|
+
existingDynamicServerShareCount: 1,
|
|
362
|
+
newDynamicServerShareCount: 0
|
|
363
|
+
};
|
|
364
|
+
// 3-of-5 -> 2-of-3:
|
|
365
|
+
// -- dyanmic server shares: 1 existing, 0 new
|
|
366
|
+
// -- external server shares: 2 existing, 0 new
|
|
367
|
+
case oldThresholdSignatureScheme === ThresholdSignatureScheme.THREE_OF_FIVE && newThresholdSignatureScheme === ThresholdSignatureScheme.TWO_OF_THREE:
|
|
368
|
+
return {
|
|
369
|
+
existingExternalServerShareCount: 2,
|
|
370
|
+
newExternalServerShareCount: 0,
|
|
371
|
+
existingDynamicServerShareCount: 1,
|
|
372
|
+
newDynamicServerShareCount: 0
|
|
373
|
+
};
|
|
374
|
+
default:
|
|
375
|
+
throw new Error(`Unsupported reshare from ${oldThresholdSignatureScheme} to ${newThresholdSignatureScheme}`);
|
|
376
|
+
}
|
|
377
|
+
};
|
|
378
|
+
|
|
379
|
+
class BaseClient {
|
|
380
|
+
constructor({ environmentId, baseApiUrl, authToken, baseClientRelayApiUrl }){
|
|
381
|
+
const headers = {};
|
|
382
|
+
headers['Authorization'] = authToken ? `Bearer ${authToken}` : undefined;
|
|
383
|
+
this.environmentId = environmentId;
|
|
384
|
+
const isProd = typeof baseApiUrl === 'undefined' || DYNAMIC_AUTH_PROD_BASE_API_URL === baseApiUrl;
|
|
385
|
+
this.baseApiUrl = isProd ? DYNAMIC_AUTH_PROD_BASE_API_URL : baseApiUrl || DYNAMIC_AUTH_PREPROD_BASE_API_URL;
|
|
386
|
+
this.apiClient = axios.create({
|
|
387
|
+
baseURL: this.baseApiUrl,
|
|
388
|
+
headers
|
|
389
|
+
});
|
|
390
|
+
this.clientRelayBaseApiUrl = isProd ? DYNAMIC_CLIENT_RELAY_PROD_BASE_API_URL : baseClientRelayApiUrl || DYNAMIC_CLIENT_RELAY_PREPROD_BASE_API_URL;
|
|
391
|
+
this.clientRelayApiClient = axios.create({
|
|
392
|
+
baseURL: this.clientRelayBaseApiUrl,
|
|
393
|
+
headers
|
|
394
|
+
});
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
var SuccessEventType = /*#__PURE__*/ function(SuccessEventType) {
|
|
399
|
+
SuccessEventType["KeygenComplete"] = "keygen_complete";
|
|
400
|
+
SuccessEventType["RoomCreated"] = "room_created";
|
|
401
|
+
SuccessEventType["CeremonyComplete"] = "ceremony_complete";
|
|
402
|
+
return SuccessEventType;
|
|
403
|
+
}({});
|
|
404
|
+
|
|
405
|
+
/**
|
|
406
|
+
* Creates a promise that resolves when a specific event is received from an event stream.
|
|
407
|
+
* Adds a timeout to prevent hanging and races the two promises.
|
|
408
|
+
*
|
|
409
|
+
* @template T The expected type of the response data
|
|
410
|
+
* @param apiClient The axios instance to use for API calls
|
|
411
|
+
* @param options The configuration options
|
|
412
|
+
* @returns A promise that resolves with the event data or rejects on timeout
|
|
413
|
+
*/ const createEventStreamPromise = ({ apiClient, endpoint, body, successEventType, timeoutMs = 30000, timeoutMessage, onError, onCeremonyComplete })=>{
|
|
414
|
+
// Create a promise that will resolve when the success event is received
|
|
415
|
+
const eventPromise = new Promise((resolve, reject)=>{
|
|
416
|
+
apiClient.post(endpoint, body, {
|
|
417
|
+
responseType: 'stream',
|
|
418
|
+
headers: {
|
|
419
|
+
Accept: 'text/event-stream',
|
|
420
|
+
'Cache-Control': 'no-cache',
|
|
421
|
+
Connection: 'keep-alive'
|
|
422
|
+
},
|
|
423
|
+
adapter: 'fetch'
|
|
424
|
+
}).then(createSuccessErrorEventStreamHandler({
|
|
425
|
+
onError,
|
|
426
|
+
reject,
|
|
427
|
+
resolve,
|
|
428
|
+
successEventType,
|
|
429
|
+
onCeremonyComplete
|
|
430
|
+
})).catch(reject);
|
|
431
|
+
});
|
|
432
|
+
// Add a timeout to prevent hanging
|
|
433
|
+
const timeoutPromise = new Promise((_, reject)=>{
|
|
434
|
+
setTimeout(()=>reject(new Error(timeoutMessage)), timeoutMs);
|
|
435
|
+
});
|
|
436
|
+
// Return the event data as soon as it's available
|
|
437
|
+
return Promise.race([
|
|
438
|
+
eventPromise,
|
|
439
|
+
timeoutPromise
|
|
440
|
+
]);
|
|
441
|
+
};
|
|
442
|
+
/**
|
|
443
|
+
* Creates a handler function for processing server-sent events (SSE) streams.
|
|
444
|
+
* This utility manages asynchronous event-based communication with the server,
|
|
445
|
+
* particularly for long-running operations like wallet creation or key generation.
|
|
446
|
+
*
|
|
447
|
+
* @template T - The expected type of the successful response data
|
|
448
|
+
* @param {function} resolve - Promise resolution function to call when the success event is received
|
|
449
|
+
* @param {function} reject - Promise rejection function to call when an error occurs
|
|
450
|
+
* @param {string} successEventType - The event type string that indicates a successful operation
|
|
451
|
+
* @param {function} [onError] - Optional callback for error handling, allowing custom error processing
|
|
452
|
+
* @returns {function} A response handler function that processes the event stream
|
|
453
|
+
*/ const createSuccessErrorEventStreamHandler = ({ resolve, reject, successEventType, onError, onCeremonyComplete })=>{
|
|
454
|
+
return (response)=>{
|
|
455
|
+
const reader = response.data.getReader();
|
|
456
|
+
const decoder = new TextDecoder();
|
|
457
|
+
let buffer = '';
|
|
458
|
+
const processStream = async ()=>{
|
|
459
|
+
try {
|
|
460
|
+
const { value, done } = await reader.read();
|
|
461
|
+
if (done) return;
|
|
462
|
+
buffer += decoder.decode(value, {
|
|
463
|
+
stream: true
|
|
464
|
+
});
|
|
465
|
+
const events = parseEventStream(buffer);
|
|
466
|
+
for (const event of events){
|
|
467
|
+
if (event.type === successEventType) {
|
|
468
|
+
resolve(event.data);
|
|
469
|
+
}
|
|
470
|
+
if (event.type === SuccessEventType.CeremonyComplete) {
|
|
471
|
+
const { accountAddress, walletId } = event.data;
|
|
472
|
+
onCeremonyComplete == null ? void 0 : onCeremonyComplete(accountAddress, walletId);
|
|
473
|
+
}
|
|
474
|
+
if (event.type === 'error') {
|
|
475
|
+
reject(createErrorFromEventData(event.data));
|
|
476
|
+
onError == null ? void 0 : onError(createErrorFromEventData(event.data));
|
|
477
|
+
}
|
|
478
|
+
}
|
|
479
|
+
processStream();
|
|
480
|
+
} catch (err) {
|
|
481
|
+
reject(err instanceof Error ? err : new Error(String(err)));
|
|
482
|
+
}
|
|
483
|
+
};
|
|
484
|
+
processStream();
|
|
485
|
+
};
|
|
486
|
+
};
|
|
487
|
+
/**
|
|
488
|
+
* Creates an error object from event stream error data.
|
|
489
|
+
*
|
|
490
|
+
* @param data - The error data received from the event stream
|
|
491
|
+
* @returns A standardized Error object with properties from the error data
|
|
492
|
+
*/ const createErrorFromEventData = (data)=>{
|
|
493
|
+
const error = new Error(typeof data === 'object' && data !== null && 'error' in data ? String(data.error) : 'Unknown error');
|
|
494
|
+
if (typeof data === 'object' && data !== null) {
|
|
495
|
+
Object.assign(error, data);
|
|
496
|
+
}
|
|
497
|
+
return error;
|
|
498
|
+
};
|
|
499
|
+
/**
|
|
500
|
+
* Parses a Server-Sent Events (SSE) stream into structured event objects.
|
|
501
|
+
*
|
|
502
|
+
* @param input - Raw string data from an event stream
|
|
503
|
+
* @returns Array of parsed events with type and data properties
|
|
504
|
+
*/ const parseEventStream = (input)=>{
|
|
505
|
+
const lines = input.split('\n');
|
|
506
|
+
const events = [];
|
|
507
|
+
let currentEvent = {};
|
|
508
|
+
let inEvent = false;
|
|
509
|
+
for (const line of lines){
|
|
510
|
+
// Empty line marks the end of an event
|
|
511
|
+
if (line === '') {
|
|
512
|
+
if (currentEvent.type && currentEvent.data) {
|
|
513
|
+
events.push({
|
|
514
|
+
type: currentEvent.type,
|
|
515
|
+
data: JSON.parse(currentEvent.data)
|
|
516
|
+
});
|
|
517
|
+
currentEvent = {};
|
|
518
|
+
inEvent = false;
|
|
519
|
+
}
|
|
520
|
+
continue;
|
|
521
|
+
}
|
|
522
|
+
// Process event fields
|
|
523
|
+
if (line.startsWith('event:')) {
|
|
524
|
+
currentEvent.type = line.substring(6).trim();
|
|
525
|
+
inEvent = true;
|
|
526
|
+
} else if (line.startsWith('data:')) {
|
|
527
|
+
currentEvent.data = line.substring(5).trim();
|
|
528
|
+
inEvent = true;
|
|
529
|
+
} else if (inEvent && currentEvent.data) {
|
|
530
|
+
currentEvent.data += line;
|
|
531
|
+
}
|
|
532
|
+
}
|
|
533
|
+
return events;
|
|
534
|
+
};
|
|
535
|
+
|
|
536
|
+
class DynamicApiClient extends BaseClient {
|
|
537
|
+
async authenticateApiToken({ environmentId }) {
|
|
538
|
+
return this.apiClient.post(`/api/v0/environments/${environmentId}/waas/authenticate`);
|
|
539
|
+
}
|
|
540
|
+
async createWalletAccount({ chainName, clientKeygenIds, thresholdSignatureScheme, onError, onCeremonyComplete }) {
|
|
541
|
+
return createEventStreamPromise({
|
|
542
|
+
apiClient: this.apiClient,
|
|
543
|
+
endpoint: `/api/v0/sdk/${this.environmentId}/waas/create`,
|
|
544
|
+
body: {
|
|
545
|
+
chain: chainName,
|
|
546
|
+
clientKeygenIds,
|
|
547
|
+
thresholdSignatureScheme
|
|
548
|
+
},
|
|
549
|
+
successEventType: SuccessEventType.KeygenComplete,
|
|
550
|
+
timeoutMessage: 'Wallet creation timed out',
|
|
551
|
+
onError,
|
|
552
|
+
onCeremonyComplete
|
|
553
|
+
});
|
|
554
|
+
}
|
|
555
|
+
async signMessage({ walletId, message, onError }) {
|
|
556
|
+
return createEventStreamPromise({
|
|
557
|
+
apiClient: this.apiClient,
|
|
558
|
+
endpoint: `/api/v0/sdk/${this.environmentId}/waas/${walletId}/signMessage`,
|
|
559
|
+
body: {
|
|
560
|
+
message
|
|
561
|
+
},
|
|
562
|
+
successEventType: SuccessEventType.RoomCreated,
|
|
563
|
+
timeoutMessage: 'Message signing timed out',
|
|
564
|
+
onError
|
|
565
|
+
});
|
|
566
|
+
}
|
|
567
|
+
async refreshWalletAccountShares({ walletId, onError }) {
|
|
568
|
+
return createEventStreamPromise({
|
|
569
|
+
apiClient: this.apiClient,
|
|
570
|
+
endpoint: `/api/v0/sdk/${this.environmentId}/waas/${walletId}/refresh`,
|
|
571
|
+
body: undefined,
|
|
572
|
+
successEventType: SuccessEventType.RoomCreated,
|
|
573
|
+
timeoutMessage: 'Refresh timed out',
|
|
574
|
+
onError
|
|
575
|
+
});
|
|
576
|
+
}
|
|
577
|
+
async reshare({ walletId, clientKeygenIds, oldThresholdSignatureScheme, newThresholdSignatureScheme, onError }) {
|
|
578
|
+
return createEventStreamPromise({
|
|
579
|
+
apiClient: this.apiClient,
|
|
580
|
+
endpoint: `/api/v0/sdk/${this.environmentId}/waas/${walletId}/reshare`,
|
|
581
|
+
body: {
|
|
582
|
+
clientKeygenIds,
|
|
583
|
+
oldThresholdSignatureScheme,
|
|
584
|
+
newThresholdSignatureScheme
|
|
585
|
+
},
|
|
586
|
+
successEventType: SuccessEventType.RoomCreated,
|
|
587
|
+
timeoutMessage: 'Reshare timed out',
|
|
588
|
+
onError
|
|
589
|
+
});
|
|
590
|
+
}
|
|
591
|
+
async exportKey({ walletId, exportId, onError }) {
|
|
592
|
+
return createEventStreamPromise({
|
|
593
|
+
apiClient: this.apiClient,
|
|
594
|
+
endpoint: `/api/v0/sdk/${this.environmentId}/waas/${walletId}/privateKey/export`,
|
|
595
|
+
body: {
|
|
596
|
+
exportId
|
|
597
|
+
},
|
|
598
|
+
successEventType: SuccessEventType.RoomCreated,
|
|
599
|
+
timeoutMessage: 'Key export timed out',
|
|
600
|
+
onError
|
|
601
|
+
});
|
|
602
|
+
}
|
|
603
|
+
async storeEncryptedBackupByWallet({ walletId, encryptedKeyShares, passwordEncrypted }) {
|
|
604
|
+
const { data } = await this.clientRelayApiClient.post(`/api/v0/sdk/${this.environmentId}/waas/${walletId}/keyShares/backup`, {
|
|
605
|
+
// TODO: decide on whether to store encryptedAccountCredentials or encryptedKeyShares as backup
|
|
606
|
+
encryptedAccountCredentials: encryptedKeyShares,
|
|
607
|
+
passwordEncrypted
|
|
608
|
+
});
|
|
609
|
+
return data;
|
|
610
|
+
}
|
|
611
|
+
async markKeySharesAsBackedUpGoogleDrive({ walletId }) {
|
|
612
|
+
const { data } = await this.clientRelayApiClient.post(`/api/v0/sdk/${this.environmentId}/waas/${walletId}/keyShares/backup/googleDrive`, {});
|
|
613
|
+
return data;
|
|
614
|
+
}
|
|
615
|
+
async recoverEncryptedBackupByWallet({ walletId, keyShareIds }) {
|
|
616
|
+
const { data } = await this.clientRelayApiClient.post(`/api/v0/sdk/${this.environmentId}/waas/${walletId}/keyShares/recover`, keyShareIds ? {
|
|
617
|
+
keyShareIds
|
|
618
|
+
} : undefined);
|
|
619
|
+
return data;
|
|
620
|
+
}
|
|
621
|
+
async getAccessToken({ oauthAccountId }) {
|
|
622
|
+
const { data } = await this.apiClient.get(`/api/v0/sdk/${this.environmentId}/oauthAccounts/${oauthAccountId}/accessToken`);
|
|
623
|
+
return data.accessToken;
|
|
624
|
+
}
|
|
625
|
+
// TODO: return array instead considering cases where server has multiple parties
|
|
626
|
+
async importPrivateKey({ chainName, clientKeygenIds, thresholdSignatureScheme, onError, onCeremonyComplete }) {
|
|
627
|
+
return createEventStreamPromise({
|
|
628
|
+
apiClient: this.apiClient,
|
|
629
|
+
endpoint: `/api/v0/sdk/${this.environmentId}/waas/privateKey/import`,
|
|
630
|
+
body: {
|
|
631
|
+
chain: chainName,
|
|
632
|
+
clientKeygenIds,
|
|
633
|
+
thresholdSignatureScheme
|
|
634
|
+
},
|
|
635
|
+
successEventType: SuccessEventType.KeygenComplete,
|
|
636
|
+
timeoutMessage: 'Key import timed out',
|
|
637
|
+
onError,
|
|
638
|
+
onCeremonyComplete
|
|
639
|
+
});
|
|
640
|
+
}
|
|
641
|
+
// TODO: consider removing the retry logics if we switch to server-sent events
|
|
642
|
+
async getUser() {
|
|
643
|
+
let attempts = 0;
|
|
644
|
+
const maxAttempts = 5;
|
|
645
|
+
const retryInterval = 1000; // 1 second interval for each retry
|
|
646
|
+
while(attempts < maxAttempts){
|
|
647
|
+
try {
|
|
648
|
+
const { data } = await this.apiClient.get(`/api/v0/sdk/${this.environmentId}/users`);
|
|
649
|
+
return data;
|
|
650
|
+
} catch (error) {
|
|
651
|
+
attempts++;
|
|
652
|
+
if (attempts === maxAttempts) {
|
|
653
|
+
throw error;
|
|
654
|
+
}
|
|
655
|
+
await new Promise((resolve)=>setTimeout(resolve, retryInterval));
|
|
656
|
+
}
|
|
657
|
+
}
|
|
658
|
+
}
|
|
659
|
+
// TODO: consider removing the retry logics if we switch to server-sent events
|
|
660
|
+
async refreshUser() {
|
|
661
|
+
let attempts = 0;
|
|
662
|
+
const maxAttempts = 5;
|
|
663
|
+
const retryInterval = 1000; // 1 second interval for each retry
|
|
664
|
+
while(attempts < maxAttempts){
|
|
665
|
+
try {
|
|
666
|
+
const { data } = await this.apiClient.post(`/api/v0/sdk/${this.environmentId}/refresh`, undefined);
|
|
667
|
+
return data;
|
|
668
|
+
} catch (error) {
|
|
669
|
+
attempts++;
|
|
670
|
+
if (attempts === maxAttempts) {
|
|
671
|
+
throw error;
|
|
672
|
+
}
|
|
673
|
+
await new Promise((resolve)=>setTimeout(resolve, retryInterval));
|
|
674
|
+
}
|
|
675
|
+
}
|
|
676
|
+
}
|
|
677
|
+
constructor({ environmentId, authToken, baseApiUrl }){
|
|
678
|
+
super({
|
|
679
|
+
environmentId,
|
|
680
|
+
authToken,
|
|
681
|
+
baseApiUrl
|
|
682
|
+
});
|
|
683
|
+
}
|
|
684
|
+
}
|
|
685
|
+
|
|
686
|
+
export { BITCOIN_DERIVATION_PATHS, BackupLocation, ChainEnumToVerifiedCredentialName, CreateRoomPartiesOptions, DYNAMIC_AUTH_PREPROD_BASE_API_URL, DYNAMIC_AUTH_PROD_BASE_API_URL, DYNAMIC_CLIENT_RELAY_PREPROD_BASE_API_URL, DYNAMIC_CLIENT_RELAY_PROD_BASE_API_URL, DynamicApiClient, IFRAME_DOMAIN_PREPROD, IFRAME_DOMAIN_PROD, MPC_CHAIN_CONFIG, MPC_CONFIG, MPC_RELAY_PREPROD_API_URL, MPC_RELAY_PROD_API_URL, SOLANA_RPC_URL, SigningAlgorithm, SuccessEventType, ThresholdSignatureScheme, VerifiedCredentialNameToChainEnum, WalletOperation, chain, getClientThreshold, getDynamicServerThreshold, getMPCChainConfig, getReshareConfig, getServerWalletReshareConfig, getTSSConfig };
|