Skip to content

Commit bf9e0da

Browse files
committed
Fixing JSON-RPC serialization issues where Uint8Array gets converted to plain objects
1 parent bdd7d61 commit bf9e0da

3 files changed

Lines changed: 94 additions & 24 deletions

File tree

packages/core/src/cloud-wallet.ts

Lines changed: 28 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -283,7 +283,12 @@ interface DocumentQueue {
283283
export async function generateCloudWalletMasterKey(): Promise<{ mnemonic: string; masterKey: Uint8Array }> {
284284
const mnemonic = await utilCryptoService.mnemonicGenerate(MNEMONIC_WORD_COUNT);
285285

286-
const masterKey = await utilCryptoService.mnemonicToMiniSecret(mnemonic);
286+
const masterKeyResult = await utilCryptoService.mnemonicToMiniSecret(mnemonic);
287+
288+
// Ensure masterKey is a proper Uint8Array (JSON-RPC serialization converts it to a plain object)
289+
const masterKey = masterKeyResult instanceof Uint8Array
290+
? masterKeyResult
291+
: new Uint8Array(Object.values(masterKeyResult));
287292

288293
return {
289294
mnemonic,
@@ -292,35 +297,34 @@ export async function generateCloudWalletMasterKey(): Promise<{ mnemonic: string
292297
}
293298

294299
export async function recoverCloudWalletMasterKey(mnemonic: string): Promise<Uint8Array> {
295-
const masterKey = await utilCryptoService.mnemonicToMiniSecret(mnemonic);
300+
const masterKeyResult = await utilCryptoService.mnemonicToMiniSecret(mnemonic);
296301

297-
return masterKey;
302+
// Ensure masterKey is a proper Uint8Array (JSON-RPC serialization converts it to a plain object)
303+
return masterKeyResult instanceof Uint8Array
304+
? masterKeyResult
305+
: new Uint8Array(Object.values(masterKeyResult));
298306
}
299307

300308
export async function initializeCloudWallet({
301309
dataStore,
302310
edvUrl,
303311
authKey,
304312
masterKey,
313+
mnemonic,
305314
}: {
306315
dataStore?: DataStore;
307316
edvUrl: string;
308317
authKey: string;
309-
masterKey: Uint8Array;
318+
masterKey?: Uint8Array;
319+
mnemonic?: string;
310320
}) {
311-
const {
312-
hmacKey,
313-
agreementKey,
314-
verificationKey,
315-
} = await edvService.deriveKeys(masterKey);
316-
317-
await edvService.initialize({
318-
hmacKey,
319-
agreementKey,
320-
verificationKey,
321-
edvUrl,
322-
authKey
323-
});
321+
if (mnemonic) {
322+
await edvService.initializeFromMnemonic({ mnemonic, edvUrl, authKey });
323+
} else if (masterKey) {
324+
await edvService.initializeFromMasterKey({ masterKey, edvUrl, authKey });
325+
} else {
326+
throw new Error('Either masterKey or mnemonic is required');
327+
}
324328

325329
const documentQueues = new Map<string, DocumentQueue>();
326330
const activeOperations = new Set<Promise<any>>();
@@ -498,18 +502,24 @@ export async function initializeCloudWallet({
498502
}
499503

500504
async function pullDocuments() {
505+
logger.debug('Pulling documents from EDV');
501506
const allDocs = await edvService.find({});
502507

508+
logger.debug(`Documents found in EDV: ${allDocs.documents.length}`);
509+
503510
for (const doc of allDocs.documents) {
504511
const edvDoc = doc.content;
505512
const walletDoc = await dataStore.documents.getDocumentById(edvDoc.id);
506513

507514
if (!walletDoc) {
508-
const result = await dataStore.documents.addDocument(edvDoc, {
515+
logger.debug(`Document ${edvDoc.id} not found in data store, adding to data store`);
516+
await dataStore.documents.addDocument(edvDoc, {
509517
stopPropagation: true,
510518
});
511519
}
512520
}
521+
522+
return allDocs;
513523
}
514524

515525
async function clearEdvDocuments() {

packages/wasm/src/services/edv/service-rpc.js

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,20 @@ export class EDVServiceRpc extends RpcService {
1111
return this.call('initialize', params);
1212
}
1313

14+
initializeFromMnemonic(params: { mnemonic: string; edvUrl: string; authKey: string }) {
15+
return this.call('initializeFromMnemonic', params);
16+
}
17+
18+
initializeFromMasterKey(params: { masterKey: any; edvUrl: string; authKey: string }) {
19+
return this.call('initializeFromMasterKey', params);
20+
}
21+
1422
generateKeys() {
1523
return this.call('generateKeys');
1624
}
1725

18-
deriveKeys() {
19-
return this.call('deriveKeys');
26+
deriveKeys(masterKey) {
27+
return this.call('deriveKeys', masterKey);
2028
}
2129

2230
getController() {

packages/wasm/src/services/edv/service.ts

Lines changed: 56 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import {didService} from '@docknetwork/wallet-sdk-wasm/src/services/dids/service
1919
import {Ed25519Keypair} from '@docknetwork/credential-sdk/keypairs';
2020
import hkdf from 'futoin-hkdf';
2121
import crypto from '@docknetwork/universal-wallet/crypto';
22+
import {utilCryptoService} from '@docknetwork/wallet-sdk-wasm/src/services/util-crypto/service';
2223

2324
export const HKDF_LENGTH = 32;
2425
export const HKDF_HASH = 'SHA-256';
@@ -40,6 +41,8 @@ export class EDVService {
4041
EDVService.prototype.deriveKeys,
4142
EDVService.prototype.getController,
4243
EDVService.prototype.initialize,
44+
EDVService.prototype.initializeFromMnemonic,
45+
EDVService.prototype.initializeFromMasterKey,
4346
EDVService.prototype.find,
4447
EDVService.prototype.update,
4548
EDVService.prototype.insert,
@@ -138,6 +141,43 @@ export class EDVService {
138141
});
139142
}
140143

144+
async initializeFromMnemonic({
145+
mnemonic,
146+
edvUrl,
147+
authKey,
148+
}: {
149+
mnemonic: string;
150+
edvUrl: string;
151+
authKey: string;
152+
}) {
153+
const masterKey = await utilCryptoService.mnemonicToMiniSecret(mnemonic);
154+
return this.initializeFromMasterKey({ masterKey, edvUrl, authKey });
155+
}
156+
157+
async initializeFromMasterKey({
158+
masterKey,
159+
edvUrl,
160+
authKey,
161+
}: {
162+
masterKey: Uint8Array;
163+
edvUrl: string;
164+
authKey: string;
165+
}) {
166+
if (!(masterKey instanceof Uint8Array)) {
167+
masterKey = new Uint8Array(Object.values(masterKey));
168+
}
169+
170+
const { verificationKey, agreementKey, hmacKey } = await this.deriveKeys(masterKey);
171+
172+
return this.initialize({
173+
hmacKey,
174+
agreementKey,
175+
verificationKey,
176+
edvUrl,
177+
authKey,
178+
});
179+
}
180+
141181
/**
142182
* Generates new cryptographic keys for EDV operations
143183
* @returns {Promise<Object>} Generated keys
@@ -181,6 +221,10 @@ export class EDVService {
181221
* const keys = await edvService.deriveKeys(masterKey);
182222
*/
183223
async deriveKeys(masterKey: Uint8Array) {
224+
// Ensure masterKey is a proper Uint8Array (JSON-RPC serialization converts it to a plain object)
225+
if (!(masterKey instanceof Uint8Array)) {
226+
masterKey = new Uint8Array(Object.values(masterKey));
227+
}
184228
const {keyPair: pair} = new Ed25519Keypair(masterKey, 'seed');
185229

186230
const keyPair = await didService.deriveKeyDoc({ pair });
@@ -330,8 +374,12 @@ export class EDVService {
330374
encryptionKey: Buffer,
331375
iv: Buffer
332376
): Promise<Uint8Array> {
333-
const keyData = new Uint8Array(encryptionKey);
334-
const ivData = new Uint8Array(iv);
377+
// Ensure typed arrays survive JSON-RPC serialization
378+
if (!(masterKey instanceof Uint8Array)) {
379+
masterKey = new Uint8Array(Object.values(masterKey));
380+
}
381+
const keyData = new Uint8Array(Object.values(encryptionKey));
382+
const ivData = new Uint8Array(Object.values(iv));
335383

336384
const key = await crypto.subtle.importKey(
337385
'raw',
@@ -366,8 +414,12 @@ export class EDVService {
366414
iv: Buffer
367415
): Promise<Uint8Array> {
368416
try {
369-
const keyData = new Uint8Array(decryptionKey);
370-
const ivData = new Uint8Array(iv);
417+
// Ensure typed arrays survive JSON-RPC serialization
418+
if (!(encryptedKey instanceof Uint8Array)) {
419+
encryptedKey = new Uint8Array(Object.values(encryptedKey));
420+
}
421+
const keyData = new Uint8Array(Object.values(decryptionKey));
422+
const ivData = new Uint8Array(Object.values(iv));
371423

372424
const key = await crypto.subtle.importKey(
373425
'raw',

0 commit comments

Comments
 (0)