@verified-network/verified-custody 0.2.0 → 0.2.1
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/README.md +437 -0
- package/package.json +5 -2
- package/babel.config.json +0 -12
- package/src/components/overlays.tsx +0 -61
- package/src/components/search.tsx +0 -381
- package/src/components/slider.tsx +0 -29
- package/src/components/success.tsx +0 -142
- package/src/customTypes.d.ts +0 -37
- package/src/index.ts +0 -17
- package/src/pages/addCosigners.tsx +0 -1014
- package/src/pages/contact.tsx +0 -280
- package/src/pages/createPin.tsx +0 -693
- package/src/pages/enterPin.tsx +0 -821
- package/src/pages/ftu.tsx +0 -244
- package/src/pages/index.tsx +0 -170
- package/src/pages/otp.tsx +0 -410
- package/src/services/contracts.ts +0 -817
- package/src/services/store.tsx +0 -65
- package/src/style.css +0 -2030
- package/src/utils/config.ts +0 -103
- package/src/utils/constants.ts +0 -1966
- package/src/utils/helpers.tsx +0 -334
- package/src/utils/types.ts +0 -85
- package/tsconfig.json +0 -16
- package/tsup.config.ts +0 -36
|
@@ -1,817 +0,0 @@
|
|
|
1
|
-
import { AbiCoder, decodeBytes32String, encodeBytes32String } from "ethers";
|
|
2
|
-
import { combine, split } from "shamir-secret-sharing";
|
|
3
|
-
import {
|
|
4
|
-
contractAddress,
|
|
5
|
-
Custody,
|
|
6
|
-
Provider,
|
|
7
|
-
VerifiedWallet,
|
|
8
|
-
} from "@verified-network/verified-sdk";
|
|
9
|
-
import { createSmartAccountClient } from "@biconomy/account";
|
|
10
|
-
import {
|
|
11
|
-
decryptString,
|
|
12
|
-
encryptString,
|
|
13
|
-
errorToast,
|
|
14
|
-
hashTheString,
|
|
15
|
-
} from "../utils/helpers";
|
|
16
|
-
import {
|
|
17
|
-
defaultChainId,
|
|
18
|
-
defaultVerifiedUrl,
|
|
19
|
-
newTransactionEventHash,
|
|
20
|
-
numberPositions,
|
|
21
|
-
} from "../utils/constants";
|
|
22
|
-
import { ChainConfig, PaymasterConfig } from "../utils/config";
|
|
23
|
-
import { VerifiedCustodyHelpers } from "../utils/types";
|
|
24
|
-
|
|
25
|
-
export const checkOrCreateVault = async (
|
|
26
|
-
vaultId: string,
|
|
27
|
-
hashedVaultId: string,
|
|
28
|
-
vaultPin: string,
|
|
29
|
-
hashedVaultPin: string,
|
|
30
|
-
otpChannel: string,
|
|
31
|
-
userPk: string,
|
|
32
|
-
userAddress: string,
|
|
33
|
-
vaultContract: any,
|
|
34
|
-
action?: string,
|
|
35
|
-
reqVaultData?: any,
|
|
36
|
-
txData?: any
|
|
37
|
-
) => {
|
|
38
|
-
try {
|
|
39
|
-
const vaultData = {
|
|
40
|
-
vaultId,
|
|
41
|
-
hashedVaultId,
|
|
42
|
-
vaultPin,
|
|
43
|
-
hashedVaultPin,
|
|
44
|
-
vaultContract,
|
|
45
|
-
};
|
|
46
|
-
return await vaultContract
|
|
47
|
-
.getCreator(hashedVaultId, hashedVaultPin)
|
|
48
|
-
.then(async (res: any) => {
|
|
49
|
-
if (res?.status === 0) {
|
|
50
|
-
try {
|
|
51
|
-
if (action === "invitation") {
|
|
52
|
-
return { isExisting: true, ...vaultData };
|
|
53
|
-
} else {
|
|
54
|
-
if (chrome?.storage?.local) {
|
|
55
|
-
const secretKey = encodeBytes32String(vaultPin);
|
|
56
|
-
|
|
57
|
-
const encryptedPk = encryptString(userPk, secretKey);
|
|
58
|
-
await chrome.storage.local.set({
|
|
59
|
-
myVault: JSON.stringify({
|
|
60
|
-
vaultId,
|
|
61
|
-
hashedVaultId: hashedVaultId,
|
|
62
|
-
pk: encryptedPk,
|
|
63
|
-
channel: otpChannel,
|
|
64
|
-
}),
|
|
65
|
-
});
|
|
66
|
-
}
|
|
67
|
-
if (chrome?.runtime?.sendMessage) {
|
|
68
|
-
chrome.runtime.sendMessage({
|
|
69
|
-
type:
|
|
70
|
-
action && action === "connect_wallet"
|
|
71
|
-
? "getPk"
|
|
72
|
-
: action && action !== "connect_wallet"
|
|
73
|
-
? action
|
|
74
|
-
: "getPk",
|
|
75
|
-
value: {
|
|
76
|
-
vaultData:
|
|
77
|
-
action && action === "signRecovery"
|
|
78
|
-
? reqVaultData
|
|
79
|
-
: action && action === "completeRecovery"
|
|
80
|
-
? reqVaultData
|
|
81
|
-
: { vaultId, hashedVaultId, hashedVaultPin },
|
|
82
|
-
txData: txData,
|
|
83
|
-
},
|
|
84
|
-
});
|
|
85
|
-
} else {
|
|
86
|
-
window.location.href = defaultVerifiedUrl;
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
return true;
|
|
90
|
-
} catch (err) {
|
|
91
|
-
if (process.env.REACT_APP_NODE_ENV !== "production") {
|
|
92
|
-
console.error("error handling existing vault: ", err);
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
errorToast(
|
|
96
|
-
"Oops something went wrong",
|
|
97
|
-
"Error fetching existing vault key(s). Try again later"
|
|
98
|
-
);
|
|
99
|
-
return false;
|
|
100
|
-
}
|
|
101
|
-
} else if (res?.reason?.toLowerCase() === "invalid pin") {
|
|
102
|
-
return null;
|
|
103
|
-
} else if (res?.reason?.toLowerCase() === "wallet not created") {
|
|
104
|
-
return await vaultContract
|
|
105
|
-
.createVault(hashedVaultId, hashedVaultPin)
|
|
106
|
-
.then(async (vultRes: any) => {
|
|
107
|
-
if (vultRes?.status === 0) {
|
|
108
|
-
return await vaultContract
|
|
109
|
-
.confirmParticipant(
|
|
110
|
-
hashedVaultId,
|
|
111
|
-
hashedVaultPin,
|
|
112
|
-
hashedVaultId,
|
|
113
|
-
hashedVaultPin,
|
|
114
|
-
true
|
|
115
|
-
)
|
|
116
|
-
.then(async (cfrmRes: any) => {
|
|
117
|
-
if (cfrmRes?.status === 0) {
|
|
118
|
-
try {
|
|
119
|
-
const secretKey = encodeBytes32String(vaultPin);
|
|
120
|
-
|
|
121
|
-
const encryptedPk = encryptString(userPk, secretKey);
|
|
122
|
-
|
|
123
|
-
if (chrome?.storage?.local) {
|
|
124
|
-
await chrome.storage.local.set({
|
|
125
|
-
myVault: JSON.stringify({
|
|
126
|
-
address: userAddress,
|
|
127
|
-
vaultId,
|
|
128
|
-
hashedVaultId: hashedVaultId,
|
|
129
|
-
pk: encryptedPk,
|
|
130
|
-
channel: otpChannel,
|
|
131
|
-
}),
|
|
132
|
-
});
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
return vaultData;
|
|
136
|
-
} catch (err) {
|
|
137
|
-
errorToast(
|
|
138
|
-
"Oops something went wrong",
|
|
139
|
-
"Error savingr new vault details. Try again later"
|
|
140
|
-
);
|
|
141
|
-
if (process.env.REACT_APP_NODE_ENV !== "production") {
|
|
142
|
-
console.error("save vault failed: ", err);
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
return false;
|
|
146
|
-
}
|
|
147
|
-
} else {
|
|
148
|
-
errorToast(
|
|
149
|
-
"Oops something went wrong",
|
|
150
|
-
"Error creating pin for new vault. Try again later"
|
|
151
|
-
);
|
|
152
|
-
|
|
153
|
-
if (process.env.REACT_APP_NODE_ENV !== "production") {
|
|
154
|
-
console.error("confirm pin vault failed: ", cfrmRes);
|
|
155
|
-
}
|
|
156
|
-
return false;
|
|
157
|
-
}
|
|
158
|
-
});
|
|
159
|
-
} else {
|
|
160
|
-
errorToast(
|
|
161
|
-
"Oops something went wrong",
|
|
162
|
-
"Error creating new vault. Try again later"
|
|
163
|
-
);
|
|
164
|
-
if (process.env.REACT_APP_NODE_ENV !== "production") {
|
|
165
|
-
console.error("create vault failed: ", vultRes);
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
return false;
|
|
169
|
-
}
|
|
170
|
-
});
|
|
171
|
-
}
|
|
172
|
-
});
|
|
173
|
-
} catch (err) {
|
|
174
|
-
if (process.env.REACT_APP_NODE_ENV !== "production") {
|
|
175
|
-
console.error("unexpected error: ", err);
|
|
176
|
-
}
|
|
177
|
-
errorToast(
|
|
178
|
-
"Oops something went wrong",
|
|
179
|
-
"Error while creating pin. Try again later"
|
|
180
|
-
);
|
|
181
|
-
return false;
|
|
182
|
-
}
|
|
183
|
-
};
|
|
184
|
-
|
|
185
|
-
export const validateVaultPin = async (
|
|
186
|
-
vaultId: string,
|
|
187
|
-
hashedVaultId: string,
|
|
188
|
-
vaultPin: string,
|
|
189
|
-
hashedVaultPin: string,
|
|
190
|
-
encryptedPk: any,
|
|
191
|
-
userAddress: string,
|
|
192
|
-
otpChannel: "sms" | "email",
|
|
193
|
-
newChainId?: number,
|
|
194
|
-
chainId?: number
|
|
195
|
-
) => {
|
|
196
|
-
try {
|
|
197
|
-
const secretKey = encodeBytes32String(vaultPin);
|
|
198
|
-
|
|
199
|
-
const userPk = decryptString(encryptedPk, secretKey);
|
|
200
|
-
|
|
201
|
-
if (userPk) {
|
|
202
|
-
const cntAddresses: any = contractAddress;
|
|
203
|
-
const sender = new VerifiedWallet(userPk);
|
|
204
|
-
const _chainId =
|
|
205
|
-
chainId &&
|
|
206
|
-
cntAddresses[chainId]?.Custody &&
|
|
207
|
-
ChainConfig[chainId]?.rpcUrls?.length > 0
|
|
208
|
-
? chainId
|
|
209
|
-
: defaultChainId;
|
|
210
|
-
const provider = ChainConfig[_chainId]?.rpcUrls[0];
|
|
211
|
-
const signer = sender.setProvider(new Provider(provider));
|
|
212
|
-
|
|
213
|
-
const vaultContract = new Custody(signer, cntAddresses[_chainId].Custody);
|
|
214
|
-
|
|
215
|
-
if (vaultContract) {
|
|
216
|
-
return await vaultContract
|
|
217
|
-
.getCreator(hashedVaultId, hashedVaultPin)
|
|
218
|
-
.then(async (res: any) => {
|
|
219
|
-
if (res?.status === 0) {
|
|
220
|
-
return {
|
|
221
|
-
address: userAddress,
|
|
222
|
-
vaultId,
|
|
223
|
-
hashedVaultId: hashedVaultId,
|
|
224
|
-
pk: userPk,
|
|
225
|
-
channel: otpChannel,
|
|
226
|
-
chainId: newChainId ? newChainId : _chainId,
|
|
227
|
-
};
|
|
228
|
-
} else {
|
|
229
|
-
if (process.env.REACT_APP_NODE_ENV !== "production") {
|
|
230
|
-
console.error("Invalid pin");
|
|
231
|
-
}
|
|
232
|
-
return null;
|
|
233
|
-
}
|
|
234
|
-
});
|
|
235
|
-
} else {
|
|
236
|
-
if (process.env.REACT_APP_NODE_ENV !== "production") {
|
|
237
|
-
console.error("error ggetting vault contract");
|
|
238
|
-
}
|
|
239
|
-
return null;
|
|
240
|
-
}
|
|
241
|
-
} else {
|
|
242
|
-
if (process.env.REACT_APP_NODE_ENV !== "production") {
|
|
243
|
-
console.error("error decrypting pk");
|
|
244
|
-
}
|
|
245
|
-
return null;
|
|
246
|
-
}
|
|
247
|
-
} catch (err) {
|
|
248
|
-
if (process.env.REACT_APP_NODE_ENV !== "production") {
|
|
249
|
-
console.error("unexpected error: ", err);
|
|
250
|
-
}
|
|
251
|
-
return null;
|
|
252
|
-
}
|
|
253
|
-
};
|
|
254
|
-
|
|
255
|
-
export const acceptOrRejectInvitation = async (
|
|
256
|
-
sendCreatorAcceptance: VerifiedCustodyHelpers["sendCreatorAcceptance"],
|
|
257
|
-
sendCreatorRejection: VerifiedCustodyHelpers["sendCreatorRejection"],
|
|
258
|
-
channel: "email" | "sms",
|
|
259
|
-
hashedCosignerId: string,
|
|
260
|
-
hashedCosignerPin: string,
|
|
261
|
-
hashedCreatorVaultId: string,
|
|
262
|
-
hashedCreatorVaultPin: string,
|
|
263
|
-
creatorVaultId: string,
|
|
264
|
-
coSignerVaultId: string,
|
|
265
|
-
accepted: boolean,
|
|
266
|
-
vaultContract?: any,
|
|
267
|
-
userPk?: string,
|
|
268
|
-
chainId?: number
|
|
269
|
-
) => {
|
|
270
|
-
let contract: any;
|
|
271
|
-
if (vaultContract) {
|
|
272
|
-
contract = vaultContract;
|
|
273
|
-
} else {
|
|
274
|
-
const cntAddresses: any = contractAddress;
|
|
275
|
-
const sender = new VerifiedWallet(userPk);
|
|
276
|
-
const _chainId =
|
|
277
|
-
chainId &&
|
|
278
|
-
cntAddresses[chainId]?.Custody &&
|
|
279
|
-
ChainConfig[chainId]?.rpcUrls?.length > 0
|
|
280
|
-
? chainId
|
|
281
|
-
: defaultChainId;
|
|
282
|
-
const provider = ChainConfig[_chainId]?.rpcUrls[0];
|
|
283
|
-
const signer = sender.setProvider(new Provider(provider));
|
|
284
|
-
|
|
285
|
-
contract = new Custody(signer, cntAddresses[_chainId].Custody);
|
|
286
|
-
}
|
|
287
|
-
if (contract) {
|
|
288
|
-
return await vaultContract
|
|
289
|
-
.confirmParticipant(
|
|
290
|
-
hashedCreatorVaultId,
|
|
291
|
-
hashedCosignerPin,
|
|
292
|
-
hashedCosignerId,
|
|
293
|
-
hashedCreatorVaultPin,
|
|
294
|
-
accepted
|
|
295
|
-
)
|
|
296
|
-
.then(async (res: any) => {
|
|
297
|
-
if (res?.status === 0) {
|
|
298
|
-
if (accepted) {
|
|
299
|
-
await sendCreatorAcceptance(
|
|
300
|
-
channel,
|
|
301
|
-
creatorVaultId,
|
|
302
|
-
coSignerVaultId
|
|
303
|
-
);
|
|
304
|
-
} else {
|
|
305
|
-
await sendCreatorRejection(
|
|
306
|
-
channel,
|
|
307
|
-
creatorVaultId,
|
|
308
|
-
coSignerVaultId
|
|
309
|
-
);
|
|
310
|
-
}
|
|
311
|
-
|
|
312
|
-
return true;
|
|
313
|
-
} else {
|
|
314
|
-
if (process.env.REACT_APP_NODE_ENV !== "production") {
|
|
315
|
-
console.error("Accept or reject invitation failed with");
|
|
316
|
-
}
|
|
317
|
-
return false;
|
|
318
|
-
}
|
|
319
|
-
})
|
|
320
|
-
.catch((err: any) => {
|
|
321
|
-
if (process.env.REACT_APP_NODE_ENV !== "production") {
|
|
322
|
-
console.error("Accept or reject invitation failed with error: ", err);
|
|
323
|
-
}
|
|
324
|
-
return false;
|
|
325
|
-
});
|
|
326
|
-
} else {
|
|
327
|
-
return false;
|
|
328
|
-
}
|
|
329
|
-
};
|
|
330
|
-
|
|
331
|
-
// const retryCompleteVault = async () => {
|
|
332
|
-
// failedParticipants = [...new Set(failedParticipants)]
|
|
333
|
-
// await Promise.all(
|
|
334
|
-
// failedParticipants.map(async (participant, idx) => {
|
|
335
|
-
// const retryAdd = await mainService.vault.addParticipant(
|
|
336
|
-
// vaultInfo.hashedVaultId,
|
|
337
|
-
// vaultInfo.hashedVaultPin,
|
|
338
|
-
// participant.hashedCosigner,
|
|
339
|
-
// participant.share
|
|
340
|
-
// )
|
|
341
|
-
|
|
342
|
-
// if (retryAdd.status) {
|
|
343
|
-
// // failedParticipants.push({
|
|
344
|
-
// // creatorVaultId: ,
|
|
345
|
-
// // fcmToken,
|
|
346
|
-
// // cosigner,
|
|
347
|
-
// // share: sharesArrayAsString[idx],
|
|
348
|
-
// // })
|
|
349
|
-
// } else {
|
|
350
|
-
// const filtered = failedParticipants.filter(
|
|
351
|
-
// (part) => part.cosigner !== participant.cosigner
|
|
352
|
-
// )
|
|
353
|
-
// failedParticipants = [...new Set(filtered)]
|
|
354
|
-
// await sendNotification({
|
|
355
|
-
// creator: vaultInfo.vaultId,
|
|
356
|
-
// hashedCreator: vaultInfo.hashedVaultId,
|
|
357
|
-
// idType: participant.idType,
|
|
358
|
-
// email: participant.cosigner,
|
|
359
|
-
// phoneNumber: participant.cosigner,
|
|
360
|
-
// })
|
|
361
|
-
// }
|
|
362
|
-
// })
|
|
363
|
-
// )
|
|
364
|
-
|
|
365
|
-
// if (failedParticipants.length > 0) {
|
|
366
|
-
// setIsRetry(true)
|
|
367
|
-
// setIsLoading(false)
|
|
368
|
-
// return
|
|
369
|
-
// }
|
|
370
|
-
|
|
371
|
-
// const addQuorum = await mainService.vault.defineQuorum(
|
|
372
|
-
// vaultInfo.hashedVaultId,
|
|
373
|
-
// vaultInfo.hashedVaultPin,
|
|
374
|
-
// threshold.toString() // coming from the slider
|
|
375
|
-
// )
|
|
376
|
-
|
|
377
|
-
// if (addQuorum.status) {
|
|
378
|
-
// return false
|
|
379
|
-
// }
|
|
380
|
-
// return true
|
|
381
|
-
// }
|
|
382
|
-
|
|
383
|
-
export const completeVaultCreation = async (
|
|
384
|
-
sendCoSignerInvitation: (
|
|
385
|
-
channel: "sms" | "email",
|
|
386
|
-
cosigerId: string,
|
|
387
|
-
cretorId: string,
|
|
388
|
-
hashedCretorPin: string
|
|
389
|
-
) => Promise<boolean>,
|
|
390
|
-
sendCreatorConfirmation: (
|
|
391
|
-
channel: "sms" | "email",
|
|
392
|
-
cretorId: string,
|
|
393
|
-
cosigersList: [],
|
|
394
|
-
requiredSigners: number
|
|
395
|
-
) => Promise<boolean>,
|
|
396
|
-
keyHolders: any,
|
|
397
|
-
coSigners: any,
|
|
398
|
-
otpChannel: "sms" | "email",
|
|
399
|
-
KeyThreshold: number,
|
|
400
|
-
vaultId: string,
|
|
401
|
-
hashedVaultId: string,
|
|
402
|
-
vaultPin: string,
|
|
403
|
-
hashedVaultPin: string,
|
|
404
|
-
vaultContract: any,
|
|
405
|
-
pk: string
|
|
406
|
-
) => {
|
|
407
|
-
const keyShardsCount = Number(keyHolders.length);
|
|
408
|
-
|
|
409
|
-
const privateKeySplits = await split(
|
|
410
|
-
Uint8Array.from(pk.split("").map((letter: string) => letter.charCodeAt(0))),
|
|
411
|
-
Number(keyShardsCount),
|
|
412
|
-
KeyThreshold
|
|
413
|
-
);
|
|
414
|
-
|
|
415
|
-
const sharesArrayAsString = privateKeySplits.map((share) => share.join(","));
|
|
416
|
-
|
|
417
|
-
let failedKeyHolders = [];
|
|
418
|
-
let succesfulKeyHolders = [];
|
|
419
|
-
|
|
420
|
-
for (let idx = 0; idx < keyHolders.length; idx++) {
|
|
421
|
-
const participant = keyHolders[idx];
|
|
422
|
-
await vaultContract
|
|
423
|
-
.addParticipant(
|
|
424
|
-
hashedVaultId,
|
|
425
|
-
hashedVaultPin,
|
|
426
|
-
hashTheString(participant.vaultId),
|
|
427
|
-
sharesArrayAsString[idx]
|
|
428
|
-
)
|
|
429
|
-
.then(async (res: any) => {
|
|
430
|
-
const keyHolder = {
|
|
431
|
-
creatorVaultId: vaultId,
|
|
432
|
-
vaultPin: vaultPin,
|
|
433
|
-
creatorHashedVaultId: hashedVaultId,
|
|
434
|
-
creatorHashedVaultPin: hashedVaultPin,
|
|
435
|
-
cosigner: participant.vaultId,
|
|
436
|
-
hashedCosigner: hashTheString(participant.vaultId),
|
|
437
|
-
cosignerVaultIdType:
|
|
438
|
-
participant.otpChannel === "sms" ? "PHONE" : "EMAIL",
|
|
439
|
-
cosignerVaultId: participant.vaultId,
|
|
440
|
-
share: sharesArrayAsString[idx],
|
|
441
|
-
...participant,
|
|
442
|
-
};
|
|
443
|
-
if (res?.status === 0) {
|
|
444
|
-
succesfulKeyHolders.push(keyHolder);
|
|
445
|
-
if (participant.vaultId !== vaultId) {
|
|
446
|
-
await sendCoSignerInvitation(
|
|
447
|
-
participant.otpChannel,
|
|
448
|
-
participant.vaultId,
|
|
449
|
-
vaultId,
|
|
450
|
-
hashedVaultPin
|
|
451
|
-
).then((res) => {
|
|
452
|
-
if (!res) {
|
|
453
|
-
if (process.env.REACT_APP_NODE_ENV !== "production") {
|
|
454
|
-
console.error("error while sending cosigner invite");
|
|
455
|
-
}
|
|
456
|
-
// errorToast("Oops somethin went wrong", "error while sending cosigner invite");
|
|
457
|
-
}
|
|
458
|
-
});
|
|
459
|
-
}
|
|
460
|
-
} else {
|
|
461
|
-
failedKeyHolders.push(keyHolder);
|
|
462
|
-
}
|
|
463
|
-
});
|
|
464
|
-
}
|
|
465
|
-
|
|
466
|
-
if (
|
|
467
|
-
failedKeyHolders?.length > 0 ||
|
|
468
|
-
succesfulKeyHolders?.length !== keyHolders?.length
|
|
469
|
-
) {
|
|
470
|
-
if (process.env.REACT_APP_NODE_ENV !== "production") {
|
|
471
|
-
console.error("error while adding co-signers");
|
|
472
|
-
}
|
|
473
|
-
errorToast("Oops somethin went wrong", "error while adding co-signers");
|
|
474
|
-
return false;
|
|
475
|
-
}
|
|
476
|
-
|
|
477
|
-
return await vaultContract
|
|
478
|
-
.defineQuorum(hashedVaultId, hashedVaultPin, KeyThreshold.toString())
|
|
479
|
-
.then(async (res: any) => {
|
|
480
|
-
if (res?.status === 0) {
|
|
481
|
-
const cosignersList = coSigners?.map((cng: any) => {
|
|
482
|
-
return {
|
|
483
|
-
name: cng?.name,
|
|
484
|
-
email: cng?.email,
|
|
485
|
-
phoneNumber: cng?.phoneNumber,
|
|
486
|
-
contactType: String(cng?.otpChannel)?.toUpperCase(),
|
|
487
|
-
position: `${numberPositions[Number(cng?.position)]} Co-Signer`,
|
|
488
|
-
};
|
|
489
|
-
});
|
|
490
|
-
await sendCreatorConfirmation(
|
|
491
|
-
otpChannel,
|
|
492
|
-
vaultId,
|
|
493
|
-
cosignersList,
|
|
494
|
-
Number(KeyThreshold)
|
|
495
|
-
).then((res) => {
|
|
496
|
-
if (!res) {
|
|
497
|
-
if (process.env.REACT_APP_NODE_ENV !== "production") {
|
|
498
|
-
console.error("error while sending creator's confirmation");
|
|
499
|
-
}
|
|
500
|
-
// errorToast("Oops somethin went wrong", "error while sending creator's confirmation");
|
|
501
|
-
}
|
|
502
|
-
});
|
|
503
|
-
|
|
504
|
-
return true;
|
|
505
|
-
} else {
|
|
506
|
-
if (process.env.REACT_APP_NODE_ENV !== "production") {
|
|
507
|
-
console.error("error while saving vault keys");
|
|
508
|
-
}
|
|
509
|
-
errorToast("Oops somethin went wrong", "error while saving vault keys");
|
|
510
|
-
return false;
|
|
511
|
-
}
|
|
512
|
-
});
|
|
513
|
-
};
|
|
514
|
-
|
|
515
|
-
export const initiateVaultRecovery = async (
|
|
516
|
-
sendCreatorInitiation: (
|
|
517
|
-
channel: "sms" | "email",
|
|
518
|
-
cretorId: string,
|
|
519
|
-
hashedCretorPin: string,
|
|
520
|
-
txId: number,
|
|
521
|
-
requiredSigners: number
|
|
522
|
-
) => Promise<boolean>,
|
|
523
|
-
hashedVaultId: string,
|
|
524
|
-
hashedVaultPin: string,
|
|
525
|
-
vaultId: string,
|
|
526
|
-
vaultPin: string,
|
|
527
|
-
encryptedPk: string,
|
|
528
|
-
vaultChannel: "sms" | "email",
|
|
529
|
-
chainId?: number
|
|
530
|
-
) => {
|
|
531
|
-
const secretKey = encodeBytes32String(vaultPin);
|
|
532
|
-
|
|
533
|
-
const userPk = decryptString(encryptedPk, secretKey);
|
|
534
|
-
|
|
535
|
-
if (userPk) {
|
|
536
|
-
const cntAddresses: any = contractAddress;
|
|
537
|
-
const sender = new VerifiedWallet(userPk);
|
|
538
|
-
const _chainId =
|
|
539
|
-
chainId &&
|
|
540
|
-
cntAddresses[chainId]?.Custody &&
|
|
541
|
-
ChainConfig[chainId]?.rpcUrls?.length > 0
|
|
542
|
-
? chainId
|
|
543
|
-
: defaultChainId;
|
|
544
|
-
const provider = ChainConfig[_chainId]?.rpcUrls[0];
|
|
545
|
-
const signer = sender.setProvider(new Provider(provider));
|
|
546
|
-
|
|
547
|
-
const vaultContract = new Custody(signer, cntAddresses[_chainId].Custody);
|
|
548
|
-
|
|
549
|
-
if (vaultContract) {
|
|
550
|
-
return await vaultContract
|
|
551
|
-
.promptSignatures(hashedVaultId, hashedVaultPin)
|
|
552
|
-
.then(async (res: any) => {
|
|
553
|
-
if (res?.status === 0 && res?.response?.result?.logs) {
|
|
554
|
-
const abiCoder = new AbiCoder();
|
|
555
|
-
const vaultLogs = res?.response?.result?.logs?.filter(
|
|
556
|
-
(log: any) =>
|
|
557
|
-
log?.address?.toLowerCase() ===
|
|
558
|
-
cntAddresses[_chainId].Custody?.toLowerCase() &&
|
|
559
|
-
log?.topics
|
|
560
|
-
?.map((tp: string) => tp?.toLowerCase())
|
|
561
|
-
?.includes(newTransactionEventHash?.toLowerCase())
|
|
562
|
-
);
|
|
563
|
-
const txData = vaultLogs[0]?.data;
|
|
564
|
-
const decodedTxData = abiCoder
|
|
565
|
-
.decode(["bytes32", "bytes32", "uint256"], txData)
|
|
566
|
-
?.map((val, idx) =>
|
|
567
|
-
idx < 2 ? decodeBytes32String(val) : Number(val)
|
|
568
|
-
)
|
|
569
|
-
.flat();
|
|
570
|
-
const txId = decodedTxData[decodedTxData?.length - 1];
|
|
571
|
-
await sendCreatorInitiation(
|
|
572
|
-
vaultChannel,
|
|
573
|
-
vaultId,
|
|
574
|
-
hashedVaultPin,
|
|
575
|
-
Number(txId),
|
|
576
|
-
Number(vaultLogs?.length)
|
|
577
|
-
);
|
|
578
|
-
return true;
|
|
579
|
-
} else {
|
|
580
|
-
return false;
|
|
581
|
-
}
|
|
582
|
-
})
|
|
583
|
-
.catch((err: any) => {
|
|
584
|
-
if (process.env.REACT_APP_NODE_ENV !== "production") {
|
|
585
|
-
console.error("error while initiating vault recovery", err);
|
|
586
|
-
}
|
|
587
|
-
return false;
|
|
588
|
-
});
|
|
589
|
-
}
|
|
590
|
-
}
|
|
591
|
-
};
|
|
592
|
-
|
|
593
|
-
export const signVaultRecovery = async (
|
|
594
|
-
sendCreatorSigned: (
|
|
595
|
-
channel: "sms" | "email",
|
|
596
|
-
cretorId: string,
|
|
597
|
-
coSignerId: string
|
|
598
|
-
) => Promise<boolean>,
|
|
599
|
-
sendCreatorCompleted: (
|
|
600
|
-
channel: "sms" | "email",
|
|
601
|
-
cretorId: string,
|
|
602
|
-
txId: number
|
|
603
|
-
) => Promise<boolean>,
|
|
604
|
-
hashedVaultId: string,
|
|
605
|
-
hashedVaultPin: string,
|
|
606
|
-
vaultId: string,
|
|
607
|
-
vaultPin: string,
|
|
608
|
-
encryptedPk: string,
|
|
609
|
-
reqVaultId: string,
|
|
610
|
-
hashedReqId: string,
|
|
611
|
-
hashedReqPin: string,
|
|
612
|
-
reqTxId: string,
|
|
613
|
-
chainId?: number
|
|
614
|
-
) => {
|
|
615
|
-
const secretKey = encodeBytes32String(vaultPin);
|
|
616
|
-
|
|
617
|
-
const userPk = decryptString(encryptedPk, secretKey);
|
|
618
|
-
|
|
619
|
-
if (userPk) {
|
|
620
|
-
const cntAddresses: any = contractAddress;
|
|
621
|
-
const sender = new VerifiedWallet(userPk);
|
|
622
|
-
const _chainId =
|
|
623
|
-
chainId &&
|
|
624
|
-
cntAddresses[chainId]?.Custody &&
|
|
625
|
-
ChainConfig[chainId]?.rpcUrls?.length > 0
|
|
626
|
-
? chainId
|
|
627
|
-
: defaultChainId;
|
|
628
|
-
const provider = ChainConfig[_chainId]?.rpcUrls[0];
|
|
629
|
-
const signer = sender.setProvider(new Provider(provider));
|
|
630
|
-
|
|
631
|
-
const vaultContract = new Custody(signer, cntAddresses[_chainId].Custody);
|
|
632
|
-
|
|
633
|
-
if (vaultContract) {
|
|
634
|
-
return await vaultContract
|
|
635
|
-
.signTransaction(
|
|
636
|
-
hashedReqId,
|
|
637
|
-
hashedVaultPin,
|
|
638
|
-
hashedVaultId,
|
|
639
|
-
reqTxId,
|
|
640
|
-
hashedReqPin
|
|
641
|
-
)
|
|
642
|
-
.then(async (res: any) => {
|
|
643
|
-
if (res?.status === 0) {
|
|
644
|
-
await sendCreatorSigned(
|
|
645
|
-
/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(reqVaultId) ? "email" : "sms",
|
|
646
|
-
reqVaultId,
|
|
647
|
-
vaultId
|
|
648
|
-
);
|
|
649
|
-
return await vaultContract
|
|
650
|
-
.checkQuorum(hashedReqId, hashedReqPin, hashedVaultId, reqTxId)
|
|
651
|
-
.then(async (qRes: any) => {
|
|
652
|
-
if (qRes?.status === 0 && qRes?.response?.result) {
|
|
653
|
-
if (qRes?.response?.result[0] === true) {
|
|
654
|
-
await sendCreatorCompleted(
|
|
655
|
-
/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(reqVaultId)
|
|
656
|
-
? "email"
|
|
657
|
-
: "sms",
|
|
658
|
-
reqVaultId,
|
|
659
|
-
Number(reqTxId)
|
|
660
|
-
);
|
|
661
|
-
}
|
|
662
|
-
return true;
|
|
663
|
-
} else {
|
|
664
|
-
return false;
|
|
665
|
-
}
|
|
666
|
-
});
|
|
667
|
-
} else {
|
|
668
|
-
return false;
|
|
669
|
-
}
|
|
670
|
-
})
|
|
671
|
-
.catch((err: any) => {
|
|
672
|
-
if (process.env.REACT_APP_NODE_ENV !== "production") {
|
|
673
|
-
console.error("error while signing vault recovery", err);
|
|
674
|
-
}
|
|
675
|
-
return false;
|
|
676
|
-
});
|
|
677
|
-
}
|
|
678
|
-
}
|
|
679
|
-
};
|
|
680
|
-
|
|
681
|
-
export const restoreVaultLogin = async (
|
|
682
|
-
hashedVaultId: string,
|
|
683
|
-
hashedVaultPin: string,
|
|
684
|
-
vaultId: string,
|
|
685
|
-
vaultPin: string,
|
|
686
|
-
encryptedPk: string,
|
|
687
|
-
reqTxId: string,
|
|
688
|
-
otpChannel: "sms" | "email",
|
|
689
|
-
chainId?: number
|
|
690
|
-
) => {
|
|
691
|
-
const secretKey = encodeBytes32String(vaultPin);
|
|
692
|
-
|
|
693
|
-
const userPk = decryptString(encryptedPk, secretKey);
|
|
694
|
-
|
|
695
|
-
if (userPk) {
|
|
696
|
-
const cntAddresses: any = contractAddress;
|
|
697
|
-
const sender = new VerifiedWallet(userPk);
|
|
698
|
-
const _chainId =
|
|
699
|
-
chainId &&
|
|
700
|
-
cntAddresses[chainId]?.Custody &&
|
|
701
|
-
ChainConfig[chainId]?.rpcUrls?.length > 0
|
|
702
|
-
? chainId
|
|
703
|
-
: defaultChainId;
|
|
704
|
-
const provider = ChainConfig[_chainId]?.rpcUrls[0];
|
|
705
|
-
const signer = sender.setProvider(new Provider(provider));
|
|
706
|
-
|
|
707
|
-
const vaultContract = new Custody(signer, cntAddresses[_chainId].Custody);
|
|
708
|
-
|
|
709
|
-
if (vaultContract) {
|
|
710
|
-
return await vaultContract
|
|
711
|
-
.checkQuorum(hashedVaultId, hashedVaultPin, hashedVaultId, reqTxId)
|
|
712
|
-
.then(async (qRes: any) => {
|
|
713
|
-
if (qRes?.status === 0 && qRes?.response?.result) {
|
|
714
|
-
if (qRes?.response?.result[0] === true) {
|
|
715
|
-
return await vaultContract
|
|
716
|
-
.signTransaction(
|
|
717
|
-
hashedVaultId,
|
|
718
|
-
hashedVaultPin,
|
|
719
|
-
hashedVaultId,
|
|
720
|
-
reqTxId,
|
|
721
|
-
hashedVaultPin
|
|
722
|
-
)
|
|
723
|
-
.then(async (res: any) => {
|
|
724
|
-
if (res?.status === 0) {
|
|
725
|
-
return await vaultContract
|
|
726
|
-
.getShards(hashedVaultId, hashedVaultPin, reqTxId)
|
|
727
|
-
.then(async (res: any) => {
|
|
728
|
-
if (res?.status === 0 && res?.response?.result) {
|
|
729
|
-
const recoveredShrads = res?.response?.result.filter(
|
|
730
|
-
(shrd: string) => shrd !== ""
|
|
731
|
-
);
|
|
732
|
-
if (recoveredShrads.length > 1) {
|
|
733
|
-
//at least 2 shrads?? since minimum signers are 2??
|
|
734
|
-
const shares = recoveredShrads.map(
|
|
735
|
-
(shrd: string) =>
|
|
736
|
-
new Uint8Array(shrd.split(",").map(Number))
|
|
737
|
-
);
|
|
738
|
-
|
|
739
|
-
const combinedShares = await combine(shares);
|
|
740
|
-
|
|
741
|
-
const pk = new TextDecoder().decode(combinedShares);
|
|
742
|
-
|
|
743
|
-
if (pk) {
|
|
744
|
-
const secretKey = encodeBytes32String(vaultPin);
|
|
745
|
-
|
|
746
|
-
const newEncryptedPk = encryptString(
|
|
747
|
-
pk,
|
|
748
|
-
secretKey
|
|
749
|
-
);
|
|
750
|
-
|
|
751
|
-
const newSender = new VerifiedWallet(pk);
|
|
752
|
-
|
|
753
|
-
const newSigner = newSender.setProvider(
|
|
754
|
-
new Provider(provider)
|
|
755
|
-
);
|
|
756
|
-
|
|
757
|
-
const smartAccount =
|
|
758
|
-
await createSmartAccountClient({
|
|
759
|
-
signer: newSigner,
|
|
760
|
-
bundlerUrl: `${PaymasterConfig.BUNDLER_URL_FIRST_SECTION}/${_chainId}/${PaymasterConfig[_chainId]["BUNDLER_API_KEY"]}`,
|
|
761
|
-
biconomyPaymasterApiKey:
|
|
762
|
-
PaymasterConfig[_chainId][
|
|
763
|
-
"PAYMASTER_API_KEY"
|
|
764
|
-
],
|
|
765
|
-
});
|
|
766
|
-
const newAddress =
|
|
767
|
-
await smartAccount.getAccountAddress();
|
|
768
|
-
if (chrome?.storage?.local) {
|
|
769
|
-
await chrome.storage.local.remove("myVault");
|
|
770
|
-
await chrome.storage.local.set({
|
|
771
|
-
myVault: JSON.stringify({
|
|
772
|
-
address: newAddress,
|
|
773
|
-
vaultId,
|
|
774
|
-
hashedVaultId: hashedVaultId,
|
|
775
|
-
pk: newEncryptedPk,
|
|
776
|
-
channel: otpChannel,
|
|
777
|
-
}),
|
|
778
|
-
});
|
|
779
|
-
}
|
|
780
|
-
return true;
|
|
781
|
-
}
|
|
782
|
-
} else {
|
|
783
|
-
return false;
|
|
784
|
-
}
|
|
785
|
-
} else {
|
|
786
|
-
return false;
|
|
787
|
-
}
|
|
788
|
-
})
|
|
789
|
-
.catch((err: any) => {
|
|
790
|
-
if (process.env.REACT_APP_NODE_ENV !== "production") {
|
|
791
|
-
console.error(
|
|
792
|
-
"error while restoring login access",
|
|
793
|
-
err
|
|
794
|
-
);
|
|
795
|
-
}
|
|
796
|
-
return false;
|
|
797
|
-
});
|
|
798
|
-
} else {
|
|
799
|
-
return false;
|
|
800
|
-
}
|
|
801
|
-
});
|
|
802
|
-
}
|
|
803
|
-
} else {
|
|
804
|
-
return false;
|
|
805
|
-
}
|
|
806
|
-
})
|
|
807
|
-
.catch((err: any) => {
|
|
808
|
-
if (process.env.REACT_APP_NODE_ENV !== "production") {
|
|
809
|
-
console.error("error while restoring login access", err);
|
|
810
|
-
}
|
|
811
|
-
return false;
|
|
812
|
-
});
|
|
813
|
-
} else {
|
|
814
|
-
return false;
|
|
815
|
-
}
|
|
816
|
-
}
|
|
817
|
-
};
|