@weblock-wallet/sdk 0.1.70 → 0.1.71
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/dist/index.cjs +256 -84
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +256 -84
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -104111,8 +104111,14 @@ var STORAGE_KEYS = {
|
|
|
104111
104111
|
walletAddress: (orgHost) => `${orgHost}:walletAddress`,
|
|
104112
104112
|
share2: (orgHost) => `${orgHost}:share2`,
|
|
104113
104113
|
encryptedShare2: (orgHost) => `${orgHost}:encryptedShare2`,
|
|
104114
|
-
|
|
104115
|
-
|
|
104114
|
+
// User-scoped keys to prevent cross-account mixing on the same device.
|
|
104115
|
+
deviceId: (orgHost, firebaseId) => `${orgHost}:${firebaseId}:deviceId`,
|
|
104116
|
+
encryptedShare2Device: (orgHost, firebaseId) => `${orgHost}:${firebaseId}:encryptedShare2_device`,
|
|
104117
|
+
deviceSecret: (orgHost, firebaseId) => `${orgHost}:${firebaseId}:deviceSecret`,
|
|
104118
|
+
// Legacy keys (kept for migration / cleanup)
|
|
104119
|
+
encryptedShare2DeviceLegacy: (orgHost) => `${orgHost}:encryptedShare2_device`,
|
|
104120
|
+
deviceSecretLegacy: (orgHost) => `${orgHost}:deviceSecret`,
|
|
104121
|
+
deviceIdLegacy: (orgHost) => `${orgHost}:deviceId`,
|
|
104116
104122
|
firebaseId: (orgHost) => `${orgHost}:firebaseId`,
|
|
104117
104123
|
accessToken: (orgHost) => `${orgHost}:accessToken`,
|
|
104118
104124
|
isNewUser: (orgHost) => `${orgHost}:isNewUser`
|
|
@@ -104144,28 +104150,76 @@ var WalletService = class {
|
|
|
104144
104150
|
isSixDigitPin(pin) {
|
|
104145
104151
|
return /^[0-9]{6}$/.test(pin);
|
|
104146
104152
|
}
|
|
104153
|
+
normalizeAddr(v5) {
|
|
104154
|
+
const s5 = String(v5 ?? "").trim();
|
|
104155
|
+
return s5 ? s5.toLowerCase() : "";
|
|
104156
|
+
}
|
|
104157
|
+
addressesMismatch(a5, b4) {
|
|
104158
|
+
return !!a5 && !!b4 && a5.toLowerCase() !== b4.toLowerCase();
|
|
104159
|
+
}
|
|
104160
|
+
/**
|
|
104161
|
+
* deviceId: stable identifier for the current device/browser profile.
|
|
104162
|
+
* Used to store/fetch server-side device recovery backup.
|
|
104163
|
+
*/
|
|
104164
|
+
async getOrCreateDeviceId(firebaseId) {
|
|
104165
|
+
const scopedKey = STORAGE_KEYS.deviceId(this.orgHost, firebaseId);
|
|
104166
|
+
const existing = await LocalForage.get(scopedKey);
|
|
104167
|
+
if (existing) return existing;
|
|
104168
|
+
const legacy = await LocalForage.get(
|
|
104169
|
+
STORAGE_KEYS.deviceIdLegacy(this.orgHost)
|
|
104170
|
+
);
|
|
104171
|
+
if (legacy) {
|
|
104172
|
+
await LocalForage.save(scopedKey, legacy);
|
|
104173
|
+
return legacy;
|
|
104174
|
+
}
|
|
104175
|
+
const id = randomBytes(16).toString("hex");
|
|
104176
|
+
await LocalForage.save(scopedKey, id);
|
|
104177
|
+
return id;
|
|
104178
|
+
}
|
|
104147
104179
|
/**
|
|
104148
|
-
* deviceSecret:
|
|
104149
|
-
*
|
|
104180
|
+
* deviceSecret: device recovery secret. In the original SDK this was local-only.
|
|
104181
|
+
* To enable PIN reset after local storage wipe, we back it up to the server
|
|
104182
|
+
* (server should encrypt-at-rest; transport is TLS).
|
|
104150
104183
|
*/
|
|
104151
|
-
async getOrCreateDeviceSecret() {
|
|
104152
|
-
const
|
|
104153
|
-
const existing = await LocalForage.get(
|
|
104184
|
+
async getOrCreateDeviceSecret(firebaseId) {
|
|
104185
|
+
const scopedKey = STORAGE_KEYS.deviceSecret(this.orgHost, firebaseId);
|
|
104186
|
+
const existing = await LocalForage.get(scopedKey);
|
|
104154
104187
|
if (existing) return existing;
|
|
104188
|
+
const legacy = await LocalForage.get(
|
|
104189
|
+
STORAGE_KEYS.deviceSecretLegacy(this.orgHost)
|
|
104190
|
+
);
|
|
104191
|
+
if (legacy) {
|
|
104192
|
+
await LocalForage.save(scopedKey, legacy);
|
|
104193
|
+
return legacy;
|
|
104194
|
+
}
|
|
104155
104195
|
const secret = randomBytes(32).toString("hex");
|
|
104156
|
-
await LocalForage.save(
|
|
104196
|
+
await LocalForage.save(scopedKey, secret);
|
|
104157
104197
|
return secret;
|
|
104158
104198
|
}
|
|
104159
104199
|
/**
|
|
104160
|
-
* PATCH APPLIED:
|
|
104161
104200
|
* Always overwrite encryptedShare2_device when we have a fresh share2.
|
|
104162
|
-
*
|
|
104201
|
+
* Also upsert to server so that PIN reset can work after local storage wipe.
|
|
104202
|
+
*
|
|
104203
|
+
* Note: Server backup is best-effort; we do not fail the main flow if backup fails.
|
|
104163
104204
|
*/
|
|
104164
104205
|
async ensureDeviceEncryptedShare2(share2Plain, firebaseId) {
|
|
104165
|
-
const
|
|
104166
|
-
const deviceSecret = await this.getOrCreateDeviceSecret();
|
|
104206
|
+
const deviceId = await this.getOrCreateDeviceId(firebaseId);
|
|
104207
|
+
const deviceSecret = await this.getOrCreateDeviceSecret(firebaseId);
|
|
104208
|
+
const encryptedKey = STORAGE_KEYS.encryptedShare2Device(
|
|
104209
|
+
this.orgHost,
|
|
104210
|
+
firebaseId
|
|
104211
|
+
);
|
|
104167
104212
|
const encrypted = Crypto.encryptShare(share2Plain, deviceSecret, firebaseId);
|
|
104168
104213
|
await LocalForage.save(encryptedKey, encrypted);
|
|
104214
|
+
try {
|
|
104215
|
+
await this.walletClient.upsertDeviceRecovery({
|
|
104216
|
+
deviceId,
|
|
104217
|
+
encryptedShare2Device: encrypted,
|
|
104218
|
+
deviceSecret
|
|
104219
|
+
});
|
|
104220
|
+
} catch (e7) {
|
|
104221
|
+
console.warn("[WalletService] device recovery backup upsert failed", e7);
|
|
104222
|
+
}
|
|
104169
104223
|
}
|
|
104170
104224
|
async getAddress() {
|
|
104171
104225
|
try {
|
|
@@ -104254,69 +104308,106 @@ var WalletService = class {
|
|
|
104254
104308
|
);
|
|
104255
104309
|
}
|
|
104256
104310
|
}
|
|
104257
|
-
// client/src/core/services/wallet.ts
|
|
104258
|
-
// Full version of retrieveWallet() with the address-mismatch guard added.
|
|
104259
|
-
// Assumes existing imports/types in this file:
|
|
104260
|
-
// - SDKError, SDKErrorCode
|
|
104261
|
-
// - LocalForage
|
|
104262
|
-
// - STORAGE_KEYS
|
|
104263
|
-
// - Crypto (encryptShare/decryptShare)
|
|
104264
|
-
// - Secrets (combine)
|
|
104265
|
-
// - Wallet (ethers Wallet or equivalent)
|
|
104266
|
-
// - this.walletClient.getWallet()
|
|
104267
|
-
// - this.orgHost, this.walletAddress
|
|
104268
|
-
// - this.isSixDigitPin(password)
|
|
104269
104311
|
async retrieveWallet(password) {
|
|
104270
104312
|
try {
|
|
104313
|
+
const accessToken = await LocalForage.get(
|
|
104314
|
+
STORAGE_KEYS.accessToken(this.orgHost)
|
|
104315
|
+
);
|
|
104316
|
+
if (!accessToken) {
|
|
104317
|
+
throw new SDKError("Access token not found", "AUTH_REQUIRED" /* AUTH_REQUIRED */);
|
|
104318
|
+
}
|
|
104271
104319
|
const firebaseId = await LocalForage.get(
|
|
104272
104320
|
STORAGE_KEYS.firebaseId(this.orgHost)
|
|
104273
104321
|
);
|
|
104274
104322
|
if (!firebaseId) {
|
|
104275
104323
|
throw new SDKError("Not logged in", "AUTH_REQUIRED" /* AUTH_REQUIRED */);
|
|
104276
104324
|
}
|
|
104277
|
-
if (!
|
|
104325
|
+
if (!this.isSixDigitPin(password)) {
|
|
104278
104326
|
throw new SDKError(
|
|
104279
104327
|
"PIN must be a 6-digit number",
|
|
104280
104328
|
"INVALID_PARAMS" /* INVALID_PARAMS */
|
|
104281
104329
|
);
|
|
104282
104330
|
}
|
|
104331
|
+
const decryptShareOrThrow = (encryptedShare) => {
|
|
104332
|
+
try {
|
|
104333
|
+
return Crypto.decryptShare(encryptedShare, password, firebaseId);
|
|
104334
|
+
} catch (e7) {
|
|
104335
|
+
if (this.isInvalidPasswordError(e7)) {
|
|
104336
|
+
throw new SDKError(
|
|
104337
|
+
"Incorrect PIN code",
|
|
104338
|
+
"INVALID_PASSWORD" /* INVALID_PASSWORD */,
|
|
104339
|
+
e7
|
|
104340
|
+
);
|
|
104341
|
+
}
|
|
104342
|
+
throw e7;
|
|
104343
|
+
}
|
|
104344
|
+
};
|
|
104283
104345
|
const walletInfo = await this.walletClient.getWallet();
|
|
104284
|
-
const
|
|
104285
|
-
|
|
104286
|
-
|
|
104287
|
-
throw new SDKError(
|
|
104288
|
-
"Wallet is not initialized on the server",
|
|
104289
|
-
"WALLET_NOT_FOUND" /* WALLET_NOT_FOUND */
|
|
104290
|
-
);
|
|
104291
|
-
}
|
|
104292
|
-
const encryptedShare2 = await LocalForage.get(
|
|
104293
|
-
STORAGE_KEYS.encryptedShare2(this.orgHost)
|
|
104346
|
+
const serverAddr = this.normalizeAddr(walletInfo?.address);
|
|
104347
|
+
let share2 = await LocalForage.get(
|
|
104348
|
+
STORAGE_KEYS.share2(this.orgHost)
|
|
104294
104349
|
);
|
|
104295
|
-
if (!
|
|
104296
|
-
|
|
104297
|
-
|
|
104298
|
-
"RECOVERY_NOT_AVAILABLE" /* RECOVERY_NOT_AVAILABLE */
|
|
104299
|
-
);
|
|
104300
|
-
}
|
|
104301
|
-
let share2;
|
|
104302
|
-
try {
|
|
104303
|
-
share2 = Crypto.decryptShare(encryptedShare2, password, firebaseId);
|
|
104304
|
-
} catch (e7) {
|
|
104305
|
-
throw new SDKError(
|
|
104306
|
-
"Invalid PIN or corrupted local recovery material",
|
|
104307
|
-
"INVALID_PIN" /* INVALID_PIN */,
|
|
104308
|
-
e7
|
|
104350
|
+
if (!share2) {
|
|
104351
|
+
const encryptedShare2 = await LocalForage.get(
|
|
104352
|
+
STORAGE_KEYS.encryptedShare2(this.orgHost)
|
|
104309
104353
|
);
|
|
104354
|
+
if (encryptedShare2) {
|
|
104355
|
+
share2 = decryptShareOrThrow(encryptedShare2);
|
|
104356
|
+
await LocalForage.save(STORAGE_KEYS.share2(this.orgHost), share2);
|
|
104357
|
+
} else {
|
|
104358
|
+
const share3 = decryptShareOrThrow(
|
|
104359
|
+
walletInfo.encryptedShare3
|
|
104360
|
+
);
|
|
104361
|
+
const privateKey2 = await Secrets.combine([
|
|
104362
|
+
walletInfo.share1,
|
|
104363
|
+
share3
|
|
104364
|
+
]);
|
|
104365
|
+
const wallet2 = new Wallet(privateKey2);
|
|
104366
|
+
const derivedAddr2 = this.normalizeAddr(wallet2.address);
|
|
104367
|
+
if (this.addressesMismatch(serverAddr, derivedAddr2)) {
|
|
104368
|
+
throw new SDKError(
|
|
104369
|
+
`Recovered wallet address mismatch. server=${serverAddr} derived=${derivedAddr2}`,
|
|
104370
|
+
"WALLET_RECOVERY_FAILED" /* WALLET_RECOVERY_FAILED */
|
|
104371
|
+
);
|
|
104372
|
+
}
|
|
104373
|
+
const newShares = await Secrets.split(wallet2.privateKey, 3, 2);
|
|
104374
|
+
const [newShare1, newShare2, newShare3] = newShares;
|
|
104375
|
+
await this.walletClient.updateWalletKey({
|
|
104376
|
+
share1: newShare1,
|
|
104377
|
+
encryptedShare3: Crypto.encryptShare(
|
|
104378
|
+
newShare3,
|
|
104379
|
+
password,
|
|
104380
|
+
firebaseId
|
|
104381
|
+
)
|
|
104382
|
+
});
|
|
104383
|
+
await LocalForage.save(STORAGE_KEYS.share2(this.orgHost), newShare2);
|
|
104384
|
+
await LocalForage.save(
|
|
104385
|
+
STORAGE_KEYS.encryptedShare2(this.orgHost),
|
|
104386
|
+
Crypto.encryptShare(newShare2, password, firebaseId)
|
|
104387
|
+
);
|
|
104388
|
+
await this.ensureDeviceEncryptedShare2(newShare2, firebaseId);
|
|
104389
|
+
this.walletAddress = wallet2.address;
|
|
104390
|
+
await LocalForage.save(
|
|
104391
|
+
STORAGE_KEYS.walletAddress(this.orgHost),
|
|
104392
|
+
wallet2.address
|
|
104393
|
+
);
|
|
104394
|
+
await LocalForage.delete(STORAGE_KEYS.share2(this.orgHost));
|
|
104395
|
+
return wallet2.address;
|
|
104396
|
+
}
|
|
104310
104397
|
}
|
|
104311
|
-
const privateKey = await Secrets.combine([
|
|
104398
|
+
const privateKey = await Secrets.combine([
|
|
104399
|
+
walletInfo.share1,
|
|
104400
|
+
share2
|
|
104401
|
+
]);
|
|
104312
104402
|
const wallet = new Wallet(privateKey);
|
|
104313
|
-
const derivedAddr = wallet.address
|
|
104314
|
-
if (serverAddr
|
|
104403
|
+
const derivedAddr = this.normalizeAddr(wallet.address);
|
|
104404
|
+
if (this.addressesMismatch(serverAddr, derivedAddr)) {
|
|
104315
104405
|
throw new SDKError(
|
|
104316
104406
|
`Recovered wallet address mismatch. server=${serverAddr} derived=${derivedAddr}`,
|
|
104317
104407
|
"WALLET_RECOVERY_FAILED" /* WALLET_RECOVERY_FAILED */
|
|
104318
104408
|
);
|
|
104319
104409
|
}
|
|
104410
|
+
await this.ensureDeviceEncryptedShare2(share2, firebaseId);
|
|
104320
104411
|
this.walletAddress = wallet.address;
|
|
104321
104412
|
await LocalForage.save(
|
|
104322
104413
|
STORAGE_KEYS.walletAddress(this.orgHost),
|
|
@@ -104325,6 +104416,8 @@ var WalletService = class {
|
|
|
104325
104416
|
await LocalForage.delete(STORAGE_KEYS.share2(this.orgHost));
|
|
104326
104417
|
return wallet.address;
|
|
104327
104418
|
} catch (error) {
|
|
104419
|
+
this.walletAddress = null;
|
|
104420
|
+
await LocalForage.delete(STORAGE_KEYS.share2(this.orgHost));
|
|
104328
104421
|
if (error instanceof SDKError) throw error;
|
|
104329
104422
|
throw new SDKError(
|
|
104330
104423
|
"Failed to retrieve wallet",
|
|
@@ -104334,7 +104427,8 @@ var WalletService = class {
|
|
|
104334
104427
|
}
|
|
104335
104428
|
}
|
|
104336
104429
|
/**
|
|
104337
|
-
* PIN reset (same private key/address) using
|
|
104430
|
+
* PIN reset (same private key/address) using device recovery material.
|
|
104431
|
+
* If local recovery material is missing, it attempts to restore it from server backup.
|
|
104338
104432
|
*/
|
|
104339
104433
|
async resetPin(newPassword) {
|
|
104340
104434
|
try {
|
|
@@ -104356,42 +104450,71 @@ var WalletService = class {
|
|
|
104356
104450
|
"INVALID_PARAMS" /* INVALID_PARAMS */
|
|
104357
104451
|
);
|
|
104358
104452
|
}
|
|
104359
|
-
|
|
104360
|
-
STORAGE_KEYS.encryptedShare2Device(this.orgHost)
|
|
104453
|
+
let encryptedDevice = await LocalForage.get(
|
|
104454
|
+
STORAGE_KEYS.encryptedShare2Device(this.orgHost, firebaseId)
|
|
104361
104455
|
);
|
|
104362
|
-
|
|
104363
|
-
STORAGE_KEYS.deviceSecret(this.orgHost)
|
|
104456
|
+
let deviceSecret = await LocalForage.get(
|
|
104457
|
+
STORAGE_KEYS.deviceSecret(this.orgHost, firebaseId)
|
|
104364
104458
|
);
|
|
104365
104459
|
if (!encryptedDevice || !deviceSecret) {
|
|
104366
|
-
|
|
104367
|
-
|
|
104368
|
-
|
|
104460
|
+
let backup;
|
|
104461
|
+
try {
|
|
104462
|
+
backup = await this.walletClient.getDeviceRecovery(void 0);
|
|
104463
|
+
} catch (e7) {
|
|
104464
|
+
throw new SDKError(
|
|
104465
|
+
"PIN reset is not available on this device",
|
|
104466
|
+
"RECOVERY_NOT_AVAILABLE" /* RECOVERY_NOT_AVAILABLE */,
|
|
104467
|
+
e7
|
|
104468
|
+
);
|
|
104469
|
+
}
|
|
104470
|
+
if (!backup?.found || !backup?.encryptedShare2Device || !backup?.deviceSecret) {
|
|
104471
|
+
throw new SDKError(
|
|
104472
|
+
"PIN reset is not available. No device recovery backup found for this user.",
|
|
104473
|
+
"RECOVERY_NOT_AVAILABLE" /* RECOVERY_NOT_AVAILABLE */
|
|
104474
|
+
);
|
|
104475
|
+
}
|
|
104476
|
+
encryptedDevice = backup.encryptedShare2Device;
|
|
104477
|
+
deviceSecret = backup.deviceSecret;
|
|
104478
|
+
await LocalForage.save(
|
|
104479
|
+
STORAGE_KEYS.encryptedShare2Device(this.orgHost, firebaseId),
|
|
104480
|
+
encryptedDevice
|
|
104481
|
+
);
|
|
104482
|
+
await LocalForage.save(
|
|
104483
|
+
STORAGE_KEYS.deviceSecret(this.orgHost, firebaseId),
|
|
104484
|
+
deviceSecret
|
|
104369
104485
|
);
|
|
104486
|
+
if (backup?.deviceId) {
|
|
104487
|
+
await LocalForage.save(
|
|
104488
|
+
STORAGE_KEYS.deviceId(this.orgHost, firebaseId),
|
|
104489
|
+
backup.deviceId
|
|
104490
|
+
);
|
|
104491
|
+
}
|
|
104370
104492
|
}
|
|
104371
104493
|
let share2;
|
|
104372
104494
|
try {
|
|
104373
|
-
share2 = Crypto.decryptShare(
|
|
104495
|
+
share2 = Crypto.decryptShare(
|
|
104496
|
+
encryptedDevice,
|
|
104497
|
+
deviceSecret,
|
|
104498
|
+
firebaseId
|
|
104499
|
+
);
|
|
104374
104500
|
} catch (e7) {
|
|
104375
104501
|
throw new SDKError(
|
|
104376
|
-
"PIN reset is not available
|
|
104502
|
+
"PIN reset is not available. Recovery material cannot be decrypted.",
|
|
104377
104503
|
"RECOVERY_NOT_AVAILABLE" /* RECOVERY_NOT_AVAILABLE */,
|
|
104378
104504
|
e7
|
|
104379
104505
|
);
|
|
104380
104506
|
}
|
|
104381
104507
|
const walletInfo = await this.walletClient.getWallet();
|
|
104508
|
+
const serverAddr = this.normalizeAddr(walletInfo?.address);
|
|
104382
104509
|
const privateKey = await Secrets.combine([
|
|
104383
104510
|
walletInfo.share1,
|
|
104384
104511
|
share2
|
|
104385
104512
|
]);
|
|
104386
104513
|
const wallet = new Wallet(privateKey);
|
|
104387
|
-
const
|
|
104388
|
-
|
|
104389
|
-
const cachedAddr = await LocalForage.get(
|
|
104390
|
-
STORAGE_KEYS.walletAddress(this.orgHost)
|
|
104391
|
-
) ?? null;
|
|
104392
|
-
if (serverAddr && derivedAddr !== serverAddr) {
|
|
104514
|
+
const derivedAddr = this.normalizeAddr(wallet.address);
|
|
104515
|
+
if (this.addressesMismatch(serverAddr, derivedAddr)) {
|
|
104393
104516
|
throw new SDKError(
|
|
104394
|
-
`Device recovery
|
|
104517
|
+
`Device recovery does not match server wallet. server=${serverAddr} derived=${derivedAddr}`,
|
|
104395
104518
|
"RECOVERY_NOT_AVAILABLE" /* RECOVERY_NOT_AVAILABLE */
|
|
104396
104519
|
);
|
|
104397
104520
|
}
|
|
@@ -104431,8 +104554,23 @@ var WalletService = class {
|
|
|
104431
104554
|
await LocalForage.delete(STORAGE_KEYS.walletAddress(this.orgHost));
|
|
104432
104555
|
await LocalForage.delete(STORAGE_KEYS.share2(this.orgHost));
|
|
104433
104556
|
await LocalForage.delete(STORAGE_KEYS.encryptedShare2(this.orgHost));
|
|
104434
|
-
await LocalForage.
|
|
104435
|
-
|
|
104557
|
+
const firebaseId = await LocalForage.get(
|
|
104558
|
+
STORAGE_KEYS.firebaseId(this.orgHost)
|
|
104559
|
+
);
|
|
104560
|
+
if (firebaseId) {
|
|
104561
|
+
await LocalForage.delete(
|
|
104562
|
+
STORAGE_KEYS.encryptedShare2Device(this.orgHost, firebaseId)
|
|
104563
|
+
);
|
|
104564
|
+
await LocalForage.delete(
|
|
104565
|
+
STORAGE_KEYS.deviceSecret(this.orgHost, firebaseId)
|
|
104566
|
+
);
|
|
104567
|
+
await LocalForage.delete(STORAGE_KEYS.deviceId(this.orgHost, firebaseId));
|
|
104568
|
+
}
|
|
104569
|
+
await LocalForage.delete(
|
|
104570
|
+
STORAGE_KEYS.encryptedShare2DeviceLegacy(this.orgHost)
|
|
104571
|
+
);
|
|
104572
|
+
await LocalForage.delete(STORAGE_KEYS.deviceSecretLegacy(this.orgHost));
|
|
104573
|
+
await LocalForage.delete(STORAGE_KEYS.deviceIdLegacy(this.orgHost));
|
|
104436
104574
|
}
|
|
104437
104575
|
async getBalance(address, chainId) {
|
|
104438
104576
|
const response = await this.rpcClient.sendRpc({
|
|
@@ -104569,7 +104707,7 @@ var WalletService = class {
|
|
|
104569
104707
|
}
|
|
104570
104708
|
}
|
|
104571
104709
|
/**
|
|
104572
|
-
*
|
|
104710
|
+
* Critical safety:
|
|
104573
104711
|
* - Never overwrite cached walletAddress with derived signer address.
|
|
104574
104712
|
* - If server/cached address != derived address => throw WALLET_RECOVERY_FAILED.
|
|
104575
104713
|
*/
|
|
@@ -104597,19 +104735,21 @@ var WalletService = class {
|
|
|
104597
104735
|
const firebaseId = await LocalForage.get(
|
|
104598
104736
|
STORAGE_KEYS.firebaseId(this.orgHost)
|
|
104599
104737
|
);
|
|
104600
|
-
|
|
104601
|
-
|
|
104602
|
-
|
|
104603
|
-
const deviceSecret = await LocalForage.get(
|
|
104604
|
-
STORAGE_KEYS.deviceSecret(this.orgHost)
|
|
104605
|
-
);
|
|
104606
|
-
if (firebaseId && encryptedDevice && deviceSecret) {
|
|
104607
|
-
share2 = Crypto.decryptShare(
|
|
104608
|
-
encryptedDevice,
|
|
104609
|
-
deviceSecret,
|
|
104610
|
-
firebaseId
|
|
104738
|
+
if (firebaseId) {
|
|
104739
|
+
const encryptedDevice = await LocalForage.get(
|
|
104740
|
+
STORAGE_KEYS.encryptedShare2Device(this.orgHost, firebaseId)
|
|
104611
104741
|
);
|
|
104612
|
-
await LocalForage.
|
|
104742
|
+
const deviceSecret = await LocalForage.get(
|
|
104743
|
+
STORAGE_KEYS.deviceSecret(this.orgHost, firebaseId)
|
|
104744
|
+
);
|
|
104745
|
+
if (encryptedDevice && deviceSecret) {
|
|
104746
|
+
share2 = Crypto.decryptShare(
|
|
104747
|
+
encryptedDevice,
|
|
104748
|
+
deviceSecret,
|
|
104749
|
+
firebaseId
|
|
104750
|
+
);
|
|
104751
|
+
await LocalForage.save(STORAGE_KEYS.share2(this.orgHost), share2);
|
|
104752
|
+
}
|
|
104613
104753
|
}
|
|
104614
104754
|
} catch {
|
|
104615
104755
|
}
|
|
@@ -105202,6 +105342,38 @@ var WalletClient = class {
|
|
|
105202
105342
|
needsAccessToken: true
|
|
105203
105343
|
});
|
|
105204
105344
|
}
|
|
105345
|
+
async getDeviceShare2Backup() {
|
|
105346
|
+
try {
|
|
105347
|
+
return await this.client.get(
|
|
105348
|
+
"/api/v1/wallet/device-share2",
|
|
105349
|
+
{ needsAccessToken: true }
|
|
105350
|
+
);
|
|
105351
|
+
} catch (e7) {
|
|
105352
|
+
if (e7?.details?.status === 404 || String(e7?.message || "").includes("404"))
|
|
105353
|
+
return null;
|
|
105354
|
+
throw e7;
|
|
105355
|
+
}
|
|
105356
|
+
}
|
|
105357
|
+
async upsertDeviceShare2Backup(body) {
|
|
105358
|
+
await this.client.put("/api/v1/wallet/device-share2", body, {
|
|
105359
|
+
needsAccessToken: true
|
|
105360
|
+
});
|
|
105361
|
+
}
|
|
105362
|
+
async upsertDeviceRecovery(req) {
|
|
105363
|
+
await this.client.put(`${this.baseUrl}/device-recovery`, req, {
|
|
105364
|
+
needsAccessToken: true
|
|
105365
|
+
});
|
|
105366
|
+
}
|
|
105367
|
+
/**
|
|
105368
|
+
* If deviceId is omitted, server returns latest.
|
|
105369
|
+
* Returns { found:false } if no backup exists.
|
|
105370
|
+
*/
|
|
105371
|
+
async getDeviceRecovery(deviceId) {
|
|
105372
|
+
const qs = deviceId ? `?deviceId=${encodeURIComponent(deviceId)}` : "";
|
|
105373
|
+
return this.client.get(`${this.baseUrl}/device-recovery${qs}`, {
|
|
105374
|
+
needsAccessToken: true
|
|
105375
|
+
});
|
|
105376
|
+
}
|
|
105205
105377
|
};
|
|
105206
105378
|
|
|
105207
105379
|
// src/clients/api/rpcs.ts
|