@volr/react 0.1.90 → 0.1.92
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 +259 -11
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +144 -2
- package/dist/index.d.ts +144 -2
- package/dist/index.js +254 -13
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as nc from 'crypto';
|
|
2
2
|
import { createContext, useRef, useEffect, useMemo, useState, useCallback, useContext } from 'react';
|
|
3
|
-
import { createPasskeyProvider, createMpcProvider,
|
|
3
|
+
import { createPasskeyProvider, createMpcProvider, deriveWrapKey, sealMasterSeed, uploadBlob, signSession, getAuthNonce, signAuthorization, createMasterKeyProvider, deriveEvmKey, ZERO_HASH, selectSigner, VolrError } from '@volr/sdk-core';
|
|
4
4
|
export { createMasterKeyProvider, createMpcProvider, createPasskeyProvider, deriveEvmKey, deriveWrapKey, sealMasterSeed, uploadBlob } from '@volr/sdk-core';
|
|
5
5
|
import axios from 'axios';
|
|
6
6
|
import { jsx } from 'react/jsx-runtime';
|
|
@@ -9757,7 +9757,9 @@ async function restorePasskey(params) {
|
|
|
9757
9757
|
userId,
|
|
9758
9758
|
blobUrl,
|
|
9759
9759
|
prfInput,
|
|
9760
|
-
credentialId: providedCredentialId
|
|
9760
|
+
credentialId: providedCredentialId,
|
|
9761
|
+
rpId = typeof window !== "undefined" ? window.location.hostname : "localhost",
|
|
9762
|
+
rpName = "Volr"
|
|
9761
9763
|
} = params;
|
|
9762
9764
|
const credentialId = providedCredentialId || prfInput.credentialId || safeStorage.getItem(STORAGE_KEYS.credentialId);
|
|
9763
9765
|
if (!credentialId) {
|
|
@@ -9786,7 +9788,7 @@ async function restorePasskey(params) {
|
|
|
9786
9788
|
`volr/master-seed/v1|${userId}|${keyStorageType}|${version5}`
|
|
9787
9789
|
);
|
|
9788
9790
|
const passkeyAdapter = createPasskeyAdapter({
|
|
9789
|
-
rpId
|
|
9791
|
+
rpId});
|
|
9790
9792
|
const provider = createPasskeyProvider(passkeyAdapter, {
|
|
9791
9793
|
prfInput: {
|
|
9792
9794
|
...prfInput,
|
|
@@ -18677,6 +18679,8 @@ function useVolrLogin() {
|
|
|
18677
18679
|
const toVolrUser = useCallback((u) => {
|
|
18678
18680
|
return {
|
|
18679
18681
|
id: u.id,
|
|
18682
|
+
projectId: u.projectId,
|
|
18683
|
+
projectName: u.projectName,
|
|
18680
18684
|
email: u.email,
|
|
18681
18685
|
accountId: u.accountId ?? void 0,
|
|
18682
18686
|
evmAddress: u.evmAddress,
|
|
@@ -18892,6 +18896,8 @@ function useVolrAuthCallback(options = {}) {
|
|
|
18892
18896
|
const toVolrUser = useCallback((u) => {
|
|
18893
18897
|
return {
|
|
18894
18898
|
id: u.id,
|
|
18899
|
+
projectId: u.projectId,
|
|
18900
|
+
projectName: u.projectName,
|
|
18895
18901
|
email: u.email,
|
|
18896
18902
|
accountId: u.accountId ?? void 0,
|
|
18897
18903
|
evmAddress: u.evmAddress,
|
|
@@ -19158,7 +19164,7 @@ async function enrollPasskey(params) {
|
|
|
19158
19164
|
userEvmAddress,
|
|
19159
19165
|
projectId,
|
|
19160
19166
|
rpId = typeof window !== "undefined" ? window.location.hostname : "localhost",
|
|
19161
|
-
rpName
|
|
19167
|
+
rpName
|
|
19162
19168
|
} = params;
|
|
19163
19169
|
if (!userId) {
|
|
19164
19170
|
throw new Error("userId is required");
|
|
@@ -19166,6 +19172,9 @@ async function enrollPasskey(params) {
|
|
|
19166
19172
|
if (!projectId) {
|
|
19167
19173
|
throw new Error("projectId is required");
|
|
19168
19174
|
}
|
|
19175
|
+
if (!rpName) {
|
|
19176
|
+
throw new Error("rpName is required");
|
|
19177
|
+
}
|
|
19169
19178
|
if (!baseUrl) {
|
|
19170
19179
|
throw new Error("baseUrl is required");
|
|
19171
19180
|
}
|
|
@@ -19179,9 +19188,7 @@ async function enrollPasskey(params) {
|
|
|
19179
19188
|
crypto.getRandomValues(challenge2);
|
|
19180
19189
|
const userHandle = new TextEncoder().encode(userId);
|
|
19181
19190
|
const tempCredentialId = "temp-" + Date.now();
|
|
19182
|
-
const origin = typeof window !== "undefined" ? window.location.origin : "https://localhost";
|
|
19183
19191
|
const tempPrfInput = {
|
|
19184
|
-
origin,
|
|
19185
19192
|
projectId,
|
|
19186
19193
|
credentialId: tempCredentialId
|
|
19187
19194
|
};
|
|
@@ -19224,7 +19231,6 @@ async function enrollPasskey(params) {
|
|
|
19224
19231
|
const prfOutputBuffer = extensionResults.prf.results.first;
|
|
19225
19232
|
const prfOutput = new Uint8Array(prfOutputBuffer);
|
|
19226
19233
|
const prfInput = {
|
|
19227
|
-
origin,
|
|
19228
19234
|
projectId,
|
|
19229
19235
|
credentialId
|
|
19230
19236
|
};
|
|
@@ -19260,7 +19266,6 @@ async function enrollPasskey(params) {
|
|
|
19260
19266
|
apiKey,
|
|
19261
19267
|
accessToken,
|
|
19262
19268
|
blob
|
|
19263
|
-
// Don't pass axiosInstance - let uploadBlob create its own
|
|
19264
19269
|
});
|
|
19265
19270
|
if (!blobUrl) {
|
|
19266
19271
|
throw new Error("Failed to upload blob: missing key");
|
|
@@ -19273,7 +19278,6 @@ async function enrollPasskey(params) {
|
|
|
19273
19278
|
credentialId,
|
|
19274
19279
|
blobUrl,
|
|
19275
19280
|
prfInput: {
|
|
19276
|
-
origin,
|
|
19277
19281
|
projectId,
|
|
19278
19282
|
credentialId
|
|
19279
19283
|
},
|
|
@@ -19321,7 +19325,17 @@ function usePasskeyEnrollment() {
|
|
|
19321
19325
|
"Access token is required for passkey enrollment. Please login first."
|
|
19322
19326
|
);
|
|
19323
19327
|
}
|
|
19324
|
-
|
|
19328
|
+
if (!user.projectId) {
|
|
19329
|
+
throw new Error(
|
|
19330
|
+
"Project ID is required for passkey enrollment. User data may be incomplete."
|
|
19331
|
+
);
|
|
19332
|
+
}
|
|
19333
|
+
if (!user.projectName) {
|
|
19334
|
+
throw new Error(
|
|
19335
|
+
"Project name is required for passkey enrollment. User data may be incomplete."
|
|
19336
|
+
);
|
|
19337
|
+
}
|
|
19338
|
+
const projectId = user.projectId;
|
|
19325
19339
|
setStep("encrypting");
|
|
19326
19340
|
const result = await enrollPasskey({
|
|
19327
19341
|
client,
|
|
@@ -19330,7 +19344,8 @@ function usePasskeyEnrollment() {
|
|
|
19330
19344
|
userId: user.id,
|
|
19331
19345
|
userEmail: user.email ?? null,
|
|
19332
19346
|
userEvmAddress: user.evmAddress ?? null,
|
|
19333
|
-
projectId
|
|
19347
|
+
projectId,
|
|
19348
|
+
rpName: user.projectName
|
|
19334
19349
|
});
|
|
19335
19350
|
setStep("registering");
|
|
19336
19351
|
if (typeof window !== "undefined") {
|
|
@@ -19338,7 +19353,7 @@ function usePasskeyEnrollment() {
|
|
|
19338
19353
|
}
|
|
19339
19354
|
const passkeyAdapter = createPasskeyAdapter({
|
|
19340
19355
|
rpId: typeof window !== "undefined" ? window.location.hostname : "localhost",
|
|
19341
|
-
rpName:
|
|
19356
|
+
rpName: user.projectName
|
|
19342
19357
|
});
|
|
19343
19358
|
const provider = createPasskeyProvider(passkeyAdapter, {
|
|
19344
19359
|
prfInput: result.prfInput,
|
|
@@ -19947,6 +19962,232 @@ async function checkPrfExtensionAvailable() {
|
|
|
19947
19962
|
const { prfSupported } = checkPrfSupport();
|
|
19948
19963
|
return prfSupported;
|
|
19949
19964
|
}
|
|
19965
|
+
async function requestMigration(params) {
|
|
19966
|
+
const { client, targetOrigin } = params;
|
|
19967
|
+
const response = await client.post("/wallet/migration/request", { targetOrigin });
|
|
19968
|
+
return {
|
|
19969
|
+
migrationToken: response.migrationToken,
|
|
19970
|
+
targetOrigin: response.targetOrigin,
|
|
19971
|
+
expiresAt: response.expiresAt
|
|
19972
|
+
};
|
|
19973
|
+
}
|
|
19974
|
+
function openMigrationPopup(targetOrigin, migrationToken, migrationPath = "/wallet/migrate") {
|
|
19975
|
+
const url = new URL(migrationPath, targetOrigin);
|
|
19976
|
+
url.searchParams.set("migration_token", migrationToken);
|
|
19977
|
+
const width = 500;
|
|
19978
|
+
const height = 600;
|
|
19979
|
+
const left = window.screenX + (window.outerWidth - width) / 2;
|
|
19980
|
+
const top = window.screenY + (window.outerHeight - height) / 2;
|
|
19981
|
+
return window.open(
|
|
19982
|
+
url.toString(),
|
|
19983
|
+
"volr_migration",
|
|
19984
|
+
`width=${width},height=${height},left=${left},top=${top},popup=1`
|
|
19985
|
+
);
|
|
19986
|
+
}
|
|
19987
|
+
function sendSeedToPopup(masterSeed, userId, projectId, targetOrigin, popup) {
|
|
19988
|
+
const response = {
|
|
19989
|
+
type: "VOLR_MIGRATION_SEED_RESPONSE",
|
|
19990
|
+
masterSeed: Array.from(masterSeed),
|
|
19991
|
+
userId,
|
|
19992
|
+
projectId
|
|
19993
|
+
};
|
|
19994
|
+
popup.postMessage(response, targetOrigin);
|
|
19995
|
+
}
|
|
19996
|
+
function listenForSeedRequests(allowedOrigins, getMasterSeed, getUserInfo) {
|
|
19997
|
+
const handleMessage = async (event) => {
|
|
19998
|
+
if (!allowedOrigins.includes(event.origin)) {
|
|
19999
|
+
return;
|
|
20000
|
+
}
|
|
20001
|
+
const data = event.data;
|
|
20002
|
+
if (data?.type !== "VOLR_MIGRATION_SEED_REQUEST") {
|
|
20003
|
+
return;
|
|
20004
|
+
}
|
|
20005
|
+
try {
|
|
20006
|
+
const masterSeed = await getMasterSeed();
|
|
20007
|
+
const { userId, projectId } = getUserInfo();
|
|
20008
|
+
const response = {
|
|
20009
|
+
type: "VOLR_MIGRATION_SEED_RESPONSE",
|
|
20010
|
+
masterSeed: Array.from(masterSeed),
|
|
20011
|
+
userId,
|
|
20012
|
+
projectId
|
|
20013
|
+
};
|
|
20014
|
+
event.source?.postMessage(response, { targetOrigin: event.origin });
|
|
20015
|
+
} catch (error) {
|
|
20016
|
+
const errorResponse = {
|
|
20017
|
+
type: "VOLR_MIGRATION_ERROR",
|
|
20018
|
+
code: "SEED_RETRIEVAL_FAILED",
|
|
20019
|
+
message: error instanceof Error ? error.message : "Failed to retrieve master seed"
|
|
20020
|
+
};
|
|
20021
|
+
event.source?.postMessage(errorResponse, { targetOrigin: event.origin });
|
|
20022
|
+
}
|
|
20023
|
+
};
|
|
20024
|
+
window.addEventListener("message", handleMessage);
|
|
20025
|
+
return () => {
|
|
20026
|
+
window.removeEventListener("message", handleMessage);
|
|
20027
|
+
};
|
|
20028
|
+
}
|
|
20029
|
+
function requestSeedFromOpener(sourceOrigin, migrationToken, timeout = 6e4) {
|
|
20030
|
+
return new Promise((resolve, reject) => {
|
|
20031
|
+
if (!window.opener) {
|
|
20032
|
+
reject(new Error("No opener window found. This page must be opened as a popup."));
|
|
20033
|
+
return;
|
|
20034
|
+
}
|
|
20035
|
+
const timeoutId = setTimeout(() => {
|
|
20036
|
+
window.removeEventListener("message", handleMessage);
|
|
20037
|
+
reject(new Error("Seed request timed out"));
|
|
20038
|
+
}, timeout);
|
|
20039
|
+
const handleMessage = (event) => {
|
|
20040
|
+
if (event.origin !== sourceOrigin) {
|
|
20041
|
+
return;
|
|
20042
|
+
}
|
|
20043
|
+
const data = event.data;
|
|
20044
|
+
if (data?.type === "VOLR_MIGRATION_SEED_RESPONSE") {
|
|
20045
|
+
clearTimeout(timeoutId);
|
|
20046
|
+
window.removeEventListener("message", handleMessage);
|
|
20047
|
+
resolve({
|
|
20048
|
+
masterSeed: new Uint8Array(data.masterSeed),
|
|
20049
|
+
userId: data.userId,
|
|
20050
|
+
projectId: data.projectId
|
|
20051
|
+
});
|
|
20052
|
+
} else if (data?.type === "VOLR_MIGRATION_ERROR") {
|
|
20053
|
+
clearTimeout(timeoutId);
|
|
20054
|
+
window.removeEventListener("message", handleMessage);
|
|
20055
|
+
reject(new Error(`${data.code}: ${data.message}`));
|
|
20056
|
+
}
|
|
20057
|
+
};
|
|
20058
|
+
window.addEventListener("message", handleMessage);
|
|
20059
|
+
const request = {
|
|
20060
|
+
type: "VOLR_MIGRATION_SEED_REQUEST",
|
|
20061
|
+
migrationToken
|
|
20062
|
+
};
|
|
20063
|
+
window.opener.postMessage(request, sourceOrigin);
|
|
20064
|
+
});
|
|
20065
|
+
}
|
|
20066
|
+
function detectPlatform3() {
|
|
20067
|
+
if (typeof navigator === "undefined") return "Unknown";
|
|
20068
|
+
const ua = navigator.userAgent;
|
|
20069
|
+
const platform = navigator.platform || "";
|
|
20070
|
+
if (/iPhone|iPad|iPod/.test(ua) || platform === "MacIntel" && navigator.maxTouchPoints > 1) {
|
|
20071
|
+
return "iOS";
|
|
20072
|
+
}
|
|
20073
|
+
if (/Android/.test(ua)) return "Android";
|
|
20074
|
+
if (/Mac/.test(platform)) return "macOS";
|
|
20075
|
+
if (/Win/.test(platform)) return "Windows";
|
|
20076
|
+
if (/CrOS/.test(ua)) return "ChromeOS";
|
|
20077
|
+
if (/Linux/.test(platform)) return "Linux";
|
|
20078
|
+
return "Unknown";
|
|
20079
|
+
}
|
|
20080
|
+
async function completeMigration(params) {
|
|
20081
|
+
const {
|
|
20082
|
+
client,
|
|
20083
|
+
baseUrl,
|
|
20084
|
+
apiKey,
|
|
20085
|
+
userId,
|
|
20086
|
+
projectId,
|
|
20087
|
+
migrationToken,
|
|
20088
|
+
masterSeed,
|
|
20089
|
+
rpId = typeof window !== "undefined" ? window.location.hostname : "localhost",
|
|
20090
|
+
rpName = "Volr",
|
|
20091
|
+
userEmail
|
|
20092
|
+
} = params;
|
|
20093
|
+
if (!navigator.credentials || !navigator.credentials.create) {
|
|
20094
|
+
throw new Error("WebAuthn API is not supported");
|
|
20095
|
+
}
|
|
20096
|
+
const challenge2 = new Uint8Array(32);
|
|
20097
|
+
crypto.getRandomValues(challenge2);
|
|
20098
|
+
const userHandle = new TextEncoder().encode(userId);
|
|
20099
|
+
const displayName = userEmail || `Volr Wallet (${userId.substring(0, 8)}...)`;
|
|
20100
|
+
const tempCredentialId = "temp-" + Date.now();
|
|
20101
|
+
const tempPrfInput = {
|
|
20102
|
+
projectId,
|
|
20103
|
+
credentialId: tempCredentialId
|
|
20104
|
+
};
|
|
20105
|
+
const prfSalt = deriveWrapKey(tempPrfInput);
|
|
20106
|
+
const publicKeyCredentialCreationOptions = {
|
|
20107
|
+
challenge: challenge2,
|
|
20108
|
+
rp: {
|
|
20109
|
+
name: rpName,
|
|
20110
|
+
id: rpId
|
|
20111
|
+
},
|
|
20112
|
+
user: {
|
|
20113
|
+
id: userHandle,
|
|
20114
|
+
name: displayName,
|
|
20115
|
+
displayName
|
|
20116
|
+
},
|
|
20117
|
+
pubKeyCredParams: PUBKEY_CRED_PARAMS,
|
|
20118
|
+
authenticatorSelection: AUTHENTICATOR_SELECTION,
|
|
20119
|
+
timeout: WEBAUTHN_TIMEOUT,
|
|
20120
|
+
attestation: ATTESTATION,
|
|
20121
|
+
extensions: {
|
|
20122
|
+
prf: {
|
|
20123
|
+
eval: {
|
|
20124
|
+
first: prfSalt.buffer
|
|
20125
|
+
}
|
|
20126
|
+
}
|
|
20127
|
+
}
|
|
20128
|
+
};
|
|
20129
|
+
const credential = await navigator.credentials.create({
|
|
20130
|
+
publicKey: publicKeyCredentialCreationOptions
|
|
20131
|
+
});
|
|
20132
|
+
if (!credential || !("response" in credential)) {
|
|
20133
|
+
throw new Error("Failed to create passkey credential");
|
|
20134
|
+
}
|
|
20135
|
+
const credentialId = Array.from(new Uint8Array(credential.rawId)).map((b) => b.toString(16).padStart(2, "0")).join("");
|
|
20136
|
+
const extensionResults = credential.getClientExtensionResults();
|
|
20137
|
+
if (!extensionResults.prf?.results?.first) {
|
|
20138
|
+
throw new Error("PRF extension not supported or PRF output missing");
|
|
20139
|
+
}
|
|
20140
|
+
const prfOutputBuffer = extensionResults.prf.results.first;
|
|
20141
|
+
const prfOutput = new Uint8Array(prfOutputBuffer);
|
|
20142
|
+
const wrapKey = prfOutput;
|
|
20143
|
+
const keyStorageType = "passkey";
|
|
20144
|
+
const version5 = "v1";
|
|
20145
|
+
const aadBytes = new TextEncoder().encode(
|
|
20146
|
+
`volr/master-seed/v1|${userId}|${keyStorageType}|${version5}`
|
|
20147
|
+
);
|
|
20148
|
+
const encryptedBlob = await sealMasterSeed(masterSeed, wrapKey, aadBytes);
|
|
20149
|
+
const blob = new Blob(
|
|
20150
|
+
[
|
|
20151
|
+
encryptedBlob.cipher,
|
|
20152
|
+
encryptedBlob.nonce
|
|
20153
|
+
],
|
|
20154
|
+
{ type: "application/octet-stream" }
|
|
20155
|
+
);
|
|
20156
|
+
const accessToken = client.getAccessToken();
|
|
20157
|
+
if (!accessToken) {
|
|
20158
|
+
throw new Error("Access token is required");
|
|
20159
|
+
}
|
|
20160
|
+
const { key: blobUrl } = await uploadBlob({
|
|
20161
|
+
baseUrl,
|
|
20162
|
+
apiKey,
|
|
20163
|
+
accessToken,
|
|
20164
|
+
blob
|
|
20165
|
+
});
|
|
20166
|
+
if (!blobUrl) {
|
|
20167
|
+
throw new Error("Failed to upload blob");
|
|
20168
|
+
}
|
|
20169
|
+
const platform = detectPlatform3();
|
|
20170
|
+
await client.post("/wallet/migration/complete", {
|
|
20171
|
+
migrationToken,
|
|
20172
|
+
credentialId,
|
|
20173
|
+
blobUrl,
|
|
20174
|
+
prfInput: {
|
|
20175
|
+
projectId,
|
|
20176
|
+
credentialId
|
|
20177
|
+
},
|
|
20178
|
+
rpId,
|
|
20179
|
+
platform
|
|
20180
|
+
});
|
|
20181
|
+
return {
|
|
20182
|
+
credentialId,
|
|
20183
|
+
blobUrl,
|
|
20184
|
+
rpId
|
|
20185
|
+
};
|
|
20186
|
+
}
|
|
20187
|
+
async function getUserCredentials(client) {
|
|
20188
|
+
const response = await client.get("/wallet/credentials");
|
|
20189
|
+
return response.credentials;
|
|
20190
|
+
}
|
|
19950
20191
|
/*! Bundled license information:
|
|
19951
20192
|
|
|
19952
20193
|
@noble/hashes/esm/utils.js:
|
|
@@ -19961,6 +20202,6 @@ async function checkPrfExtensionAvailable() {
|
|
|
19961
20202
|
(*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) *)
|
|
19962
20203
|
*/
|
|
19963
20204
|
|
|
19964
|
-
export { DEFAULT_EXPIRES_IN_SEC, DEFAULT_MODE, PasskeyNotFoundError, PrfNotSupportedError, UserCancelledError, VolrProvider, analyzeContractForEIP7702, buildCall, buildCalls, checkPrfExtensionAvailable, checkPrfSupport, compareERC20Balances, compareWalletStates, createGetNetworkInfo, createPasskeyAdapter, debugTransactionFailure, defaultIdempotencyKey, diagnoseTransactionFailure, getERC20Balance, getPasskeyAuthGuidance, getWalletState, isEIP7702Delegated, isUserCancelledError, normalizeHex, normalizeHexArray, uploadBlobViaPresign, useDepositListener, useInternalAuth, useMpcConnection, usePasskeyEnrollment, useVolr, useVolrAuthCallback, useVolrContext, useVolrLogin };
|
|
20205
|
+
export { DEFAULT_EXPIRES_IN_SEC, DEFAULT_MODE, PasskeyNotFoundError, PrfNotSupportedError, UserCancelledError, VolrProvider, analyzeContractForEIP7702, buildCall, buildCalls, checkPrfExtensionAvailable, checkPrfSupport, compareERC20Balances, compareWalletStates, completeMigration, createGetNetworkInfo, createPasskeyAdapter, debugTransactionFailure, defaultIdempotencyKey, diagnoseTransactionFailure, getERC20Balance, getPasskeyAuthGuidance, getUserCredentials, getWalletState, isEIP7702Delegated, isUserCancelledError, listenForSeedRequests, normalizeHex, normalizeHexArray, openMigrationPopup, requestMigration, requestSeedFromOpener, sendSeedToPopup, uploadBlobViaPresign, useDepositListener, useInternalAuth, useMpcConnection, usePasskeyEnrollment, useVolr, useVolrAuthCallback, useVolrContext, useVolrLogin };
|
|
19965
20206
|
//# sourceMappingURL=index.js.map
|
|
19966
20207
|
//# sourceMappingURL=index.js.map
|