@volr/react 0.1.112 → 0.1.113
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 +162 -19
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +162 -19
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.cjs
CHANGED
|
@@ -19425,6 +19425,11 @@ function useDepositListener(input) {
|
|
|
19425
19425
|
}, [getRpcUrl, input.chainId, input.address, JSON.stringify(input.asset)]);
|
|
19426
19426
|
return status;
|
|
19427
19427
|
}
|
|
19428
|
+
function debugLog(step, data) {
|
|
19429
|
+
{
|
|
19430
|
+
console.log(`[PasskeyEnrollment] ${step}`, data !== void 0 ? data : "");
|
|
19431
|
+
}
|
|
19432
|
+
}
|
|
19428
19433
|
function blobToBase64(blob) {
|
|
19429
19434
|
return new Promise((resolve, reject) => {
|
|
19430
19435
|
const reader = new FileReader();
|
|
@@ -19472,6 +19477,14 @@ function buildDisplayName(userEmail, userEvmAddress, userId) {
|
|
|
19472
19477
|
return userId || "Volr Wallet";
|
|
19473
19478
|
}
|
|
19474
19479
|
async function enrollPasskey(params) {
|
|
19480
|
+
debugLog("Starting enrollment with params:", {
|
|
19481
|
+
userId: params.userId,
|
|
19482
|
+
projectId: params.projectId,
|
|
19483
|
+
rpId: params.rpId,
|
|
19484
|
+
rpName: params.rpName,
|
|
19485
|
+
userEmail: params.userEmail,
|
|
19486
|
+
userEvmAddress: params.userEvmAddress
|
|
19487
|
+
});
|
|
19475
19488
|
const {
|
|
19476
19489
|
client,
|
|
19477
19490
|
baseUrl,
|
|
@@ -19483,6 +19496,7 @@ async function enrollPasskey(params) {
|
|
|
19483
19496
|
rpId = typeof window !== "undefined" ? window.location.hostname : "localhost",
|
|
19484
19497
|
rpName
|
|
19485
19498
|
} = params;
|
|
19499
|
+
debugLog("Step 0: Validating parameters");
|
|
19486
19500
|
if (!userId) {
|
|
19487
19501
|
throw new Error("userId is required");
|
|
19488
19502
|
}
|
|
@@ -19498,19 +19512,27 @@ async function enrollPasskey(params) {
|
|
|
19498
19512
|
if (!apiKey) {
|
|
19499
19513
|
throw new Error("apiKey is required");
|
|
19500
19514
|
}
|
|
19515
|
+
debugLog("Step 0: Parameters validated", { rpId, rpName });
|
|
19516
|
+
debugLog("Step 1: Checking WebAuthn support");
|
|
19501
19517
|
if (!navigator.credentials || !navigator.credentials.create) {
|
|
19502
19518
|
throw new Error("WebAuthn API is not supported");
|
|
19503
19519
|
}
|
|
19520
|
+
debugLog("Step 1: WebAuthn API is supported");
|
|
19504
19521
|
const challenge2 = new Uint8Array(32);
|
|
19505
19522
|
crypto.getRandomValues(challenge2);
|
|
19523
|
+
debugLog("Step 1: Challenge generated", { challengeLength: challenge2.length });
|
|
19506
19524
|
const userHandle = new TextEncoder().encode(userId);
|
|
19525
|
+
debugLog("Step 1: User handle created", { userHandleLength: userHandle.length });
|
|
19507
19526
|
const tempCredentialId = "temp-" + Date.now();
|
|
19508
19527
|
const tempPrfInput = {
|
|
19509
19528
|
projectId,
|
|
19510
19529
|
credentialId: tempCredentialId
|
|
19511
19530
|
};
|
|
19531
|
+
debugLog("Step 1: Temp PRF input created", tempPrfInput);
|
|
19512
19532
|
const prfSalt = sdkCore.deriveWrapKey(tempPrfInput);
|
|
19533
|
+
debugLog("Step 1: PRF salt derived", { prfSaltLength: prfSalt.length });
|
|
19513
19534
|
const displayName = buildDisplayName(userEmail, userEvmAddress, userId);
|
|
19535
|
+
debugLog("Step 1: Display name built", { displayName });
|
|
19514
19536
|
const publicKeyCredentialCreationOptions = {
|
|
19515
19537
|
challenge: challenge2,
|
|
19516
19538
|
rp: {
|
|
@@ -19534,37 +19556,105 @@ async function enrollPasskey(params) {
|
|
|
19534
19556
|
}
|
|
19535
19557
|
}
|
|
19536
19558
|
};
|
|
19537
|
-
|
|
19538
|
-
|
|
19559
|
+
debugLog("Step 1: WebAuthn options prepared", {
|
|
19560
|
+
rpId: publicKeyCredentialCreationOptions.rp.id,
|
|
19561
|
+
rpName: publicKeyCredentialCreationOptions.rp.name,
|
|
19562
|
+
timeout: publicKeyCredentialCreationOptions.timeout,
|
|
19563
|
+
attestation: publicKeyCredentialCreationOptions.attestation,
|
|
19564
|
+
authenticatorSelection: publicKeyCredentialCreationOptions.authenticatorSelection,
|
|
19565
|
+
pubKeyCredParams: publicKeyCredentialCreationOptions.pubKeyCredParams
|
|
19539
19566
|
});
|
|
19567
|
+
debugLog("Step 1: Calling navigator.credentials.create()...");
|
|
19568
|
+
let credential;
|
|
19569
|
+
try {
|
|
19570
|
+
credential = await navigator.credentials.create({
|
|
19571
|
+
publicKey: publicKeyCredentialCreationOptions
|
|
19572
|
+
});
|
|
19573
|
+
debugLog("Step 1: Credential creation completed", {
|
|
19574
|
+
hasCredential: !!credential,
|
|
19575
|
+
credentialId: credential ? Array.from(new Uint8Array(credential.rawId)).slice(0, 8).join(",") + "..." : null
|
|
19576
|
+
});
|
|
19577
|
+
} catch (err) {
|
|
19578
|
+
debugLog("Step 1: Credential creation FAILED", {
|
|
19579
|
+
error: err,
|
|
19580
|
+
errorMessage: err instanceof Error ? err.message : String(err),
|
|
19581
|
+
errorName: err instanceof Error ? err.name : "Unknown"
|
|
19582
|
+
});
|
|
19583
|
+
throw err;
|
|
19584
|
+
}
|
|
19540
19585
|
if (!credential || !("response" in credential)) {
|
|
19586
|
+
debugLog("Step 1: Invalid credential response", { credential });
|
|
19541
19587
|
throw new Error("Failed to create passkey credential");
|
|
19542
19588
|
}
|
|
19543
19589
|
const credentialId = Array.from(new Uint8Array(credential.rawId)).map((b) => b.toString(16).padStart(2, "0")).join("");
|
|
19590
|
+
debugLog("Step 2: Credential ID extracted", { credentialIdLength: credentialId.length, credentialIdPrefix: credentialId.slice(0, 16) });
|
|
19591
|
+
debugLog("Step 2: Extracting PRF output");
|
|
19544
19592
|
const extensionResults = credential.getClientExtensionResults();
|
|
19593
|
+
debugLog("Step 2: Extension results", {
|
|
19594
|
+
hasExtensionResults: !!extensionResults,
|
|
19595
|
+
hasPrf: !!extensionResults.prf,
|
|
19596
|
+
hasPrfResults: !!(extensionResults.prf && extensionResults.prf.results),
|
|
19597
|
+
hasPrfFirst: !!(extensionResults.prf && extensionResults.prf.results && extensionResults.prf.results.first),
|
|
19598
|
+
allKeys: Object.keys(extensionResults)
|
|
19599
|
+
});
|
|
19545
19600
|
if (!extensionResults.prf || !extensionResults.prf.results || !extensionResults.prf.results.first) {
|
|
19601
|
+
debugLog("Step 2: PRF extension not supported or missing", extensionResults);
|
|
19546
19602
|
throw new Error("PRF extension not supported or PRF output missing. Please use a browser that supports WebAuthn PRF extension.");
|
|
19547
19603
|
}
|
|
19548
19604
|
const prfOutputBuffer = extensionResults.prf.results.first;
|
|
19549
19605
|
const prfOutput = new Uint8Array(prfOutputBuffer);
|
|
19606
|
+
debugLog("Step 2: PRF output extracted", { prfOutputLength: prfOutput.length });
|
|
19550
19607
|
const prfInput = {
|
|
19551
19608
|
projectId,
|
|
19552
19609
|
credentialId
|
|
19553
19610
|
};
|
|
19611
|
+
debugLog("Step 3: PRF input built", prfInput);
|
|
19554
19612
|
const wrapKey = prfOutput;
|
|
19613
|
+
debugLog("Step 4: Wrap key created from PRF output", { wrapKeyLength: wrapKey.length });
|
|
19614
|
+
debugLog("Step 4: Generating master key...");
|
|
19555
19615
|
const masterKeyProvider = sdkCore.createMasterKeyProvider();
|
|
19556
|
-
|
|
19616
|
+
let masterKeyHandle;
|
|
19617
|
+
try {
|
|
19618
|
+
masterKeyHandle = await masterKeyProvider.generate();
|
|
19619
|
+
debugLog("Step 4: Master key generated", {
|
|
19620
|
+
hasEntropy: !!masterKeyHandle.entropy,
|
|
19621
|
+
entropyLength: masterKeyHandle.entropy?.length,
|
|
19622
|
+
hasSeed: !!masterKeyHandle.seed,
|
|
19623
|
+
seedLength: masterKeyHandle.seed?.length
|
|
19624
|
+
});
|
|
19625
|
+
} catch (err) {
|
|
19626
|
+
debugLog("Step 4: Master key generation FAILED", {
|
|
19627
|
+
error: err,
|
|
19628
|
+
errorMessage: err instanceof Error ? err.message : String(err)
|
|
19629
|
+
});
|
|
19630
|
+
throw err;
|
|
19631
|
+
}
|
|
19557
19632
|
try {
|
|
19558
19633
|
const keyStorageType = "passkey";
|
|
19559
19634
|
const version5 = "v1";
|
|
19560
19635
|
const aadBytes = new TextEncoder().encode(
|
|
19561
19636
|
`volr/master-seed/v1|${userId}|${keyStorageType}|${version5}`
|
|
19562
19637
|
);
|
|
19563
|
-
|
|
19564
|
-
|
|
19565
|
-
|
|
19566
|
-
|
|
19567
|
-
|
|
19638
|
+
debugLog("Step 4: AAD built", { aadLength: aadBytes.length });
|
|
19639
|
+
debugLog("Step 4: Encrypting entropy...");
|
|
19640
|
+
let encryptedBlob;
|
|
19641
|
+
try {
|
|
19642
|
+
encryptedBlob = await sdkCore.sealMasterSeed(
|
|
19643
|
+
masterKeyHandle.entropy,
|
|
19644
|
+
wrapKey,
|
|
19645
|
+
aadBytes
|
|
19646
|
+
);
|
|
19647
|
+
debugLog("Step 4: Entropy encrypted", {
|
|
19648
|
+
cipherLength: encryptedBlob.cipher.length,
|
|
19649
|
+
nonceLength: encryptedBlob.nonce.length
|
|
19650
|
+
});
|
|
19651
|
+
} catch (err) {
|
|
19652
|
+
debugLog("Step 4: Encryption FAILED", {
|
|
19653
|
+
error: err,
|
|
19654
|
+
errorMessage: err instanceof Error ? err.message : String(err)
|
|
19655
|
+
});
|
|
19656
|
+
throw err;
|
|
19657
|
+
}
|
|
19568
19658
|
const blob = new Blob(
|
|
19569
19659
|
[
|
|
19570
19660
|
encryptedBlob.cipher,
|
|
@@ -19574,28 +19664,80 @@ async function enrollPasskey(params) {
|
|
|
19574
19664
|
type: "application/octet-stream"
|
|
19575
19665
|
}
|
|
19576
19666
|
);
|
|
19667
|
+
debugLog("Step 5: Blob prepared", { blobSize: blob.size });
|
|
19668
|
+
debugLog("Step 6: Converting blob to base64...");
|
|
19577
19669
|
const blobB64 = await blobToBase64(blob);
|
|
19578
|
-
|
|
19579
|
-
|
|
19580
|
-
|
|
19670
|
+
debugLog("Step 6: Blob converted", { blobB64Length: blobB64.length });
|
|
19671
|
+
debugLog("Step 6: Uploading blob...");
|
|
19672
|
+
let uploadResponse;
|
|
19673
|
+
try {
|
|
19674
|
+
uploadResponse = await client.post("/blob/upload", {
|
|
19675
|
+
blobB64
|
|
19676
|
+
});
|
|
19677
|
+
debugLog("Step 6: Upload response", uploadResponse);
|
|
19678
|
+
} catch (err) {
|
|
19679
|
+
debugLog("Step 6: Blob upload FAILED", {
|
|
19680
|
+
error: err,
|
|
19681
|
+
errorMessage: err instanceof Error ? err.message : String(err)
|
|
19682
|
+
});
|
|
19683
|
+
throw err;
|
|
19684
|
+
}
|
|
19581
19685
|
const blobUrl = uploadResponse?.key;
|
|
19582
19686
|
if (!blobUrl) {
|
|
19687
|
+
debugLog("Step 6: Missing blob URL in response", uploadResponse);
|
|
19583
19688
|
throw new Error("Failed to upload blob: missing key");
|
|
19584
19689
|
}
|
|
19585
|
-
|
|
19690
|
+
debugLog("Step 6: Blob uploaded", { blobUrl });
|
|
19691
|
+
debugLog("Step 7: Deriving address from seed...");
|
|
19692
|
+
let keypair;
|
|
19693
|
+
try {
|
|
19694
|
+
keypair = sdkCore.deriveEvmKey({ masterSeed: masterKeyHandle.seed });
|
|
19695
|
+
debugLog("Step 7: Keypair derived", { address: keypair.address });
|
|
19696
|
+
} catch (err) {
|
|
19697
|
+
debugLog("Step 7: Key derivation FAILED", {
|
|
19698
|
+
error: err,
|
|
19699
|
+
errorMessage: err instanceof Error ? err.message : String(err)
|
|
19700
|
+
});
|
|
19701
|
+
throw err;
|
|
19702
|
+
}
|
|
19586
19703
|
const address = keypair.address;
|
|
19587
19704
|
const platform = detectPlatform();
|
|
19588
|
-
|
|
19705
|
+
debugLog("Step 8: Registering provider...", {
|
|
19589
19706
|
keyStorageType: "passkey",
|
|
19590
19707
|
credentialId,
|
|
19591
19708
|
blobUrl,
|
|
19592
|
-
prfInput: {
|
|
19593
|
-
projectId,
|
|
19594
|
-
credentialId
|
|
19595
|
-
},
|
|
19596
19709
|
address,
|
|
19597
19710
|
platform
|
|
19598
|
-
|
|
19711
|
+
});
|
|
19712
|
+
let registerResponse;
|
|
19713
|
+
try {
|
|
19714
|
+
registerResponse = await client.post("/wallet/provider/register", {
|
|
19715
|
+
keyStorageType: "passkey",
|
|
19716
|
+
credentialId,
|
|
19717
|
+
blobUrl,
|
|
19718
|
+
prfInput: {
|
|
19719
|
+
projectId,
|
|
19720
|
+
credentialId
|
|
19721
|
+
},
|
|
19722
|
+
address,
|
|
19723
|
+
platform
|
|
19724
|
+
// For UX hints when authenticating on different devices
|
|
19725
|
+
});
|
|
19726
|
+
debugLog("Step 8: Provider registered", {
|
|
19727
|
+
providerId: registerResponse?.id,
|
|
19728
|
+
hasUser: !!registerResponse?.user
|
|
19729
|
+
});
|
|
19730
|
+
} catch (err) {
|
|
19731
|
+
debugLog("Step 8: Provider registration FAILED", {
|
|
19732
|
+
error: err,
|
|
19733
|
+
errorMessage: err instanceof Error ? err.message : String(err)
|
|
19734
|
+
});
|
|
19735
|
+
throw err;
|
|
19736
|
+
}
|
|
19737
|
+
debugLog("Enrollment completed successfully!", {
|
|
19738
|
+
credentialId,
|
|
19739
|
+
blobUrl,
|
|
19740
|
+
address
|
|
19599
19741
|
});
|
|
19600
19742
|
return {
|
|
19601
19743
|
credentialId,
|
|
@@ -19610,7 +19752,8 @@ async function enrollPasskey(params) {
|
|
|
19610
19752
|
user: registerResponse.user
|
|
19611
19753
|
};
|
|
19612
19754
|
} finally {
|
|
19613
|
-
|
|
19755
|
+
debugLog("Cleanup: Destroying master key handle");
|
|
19756
|
+
masterKeyHandle.destroy();
|
|
19614
19757
|
}
|
|
19615
19758
|
}
|
|
19616
19759
|
function usePasskeyEnrollment() {
|