@volr/react 0.1.89 → 0.1.91
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 +237 -7
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +140 -2
- package/dist/index.d.ts +140 -2
- package/dist/index.js +232 -9
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.cjs
CHANGED
|
@@ -9781,7 +9781,9 @@ async function restorePasskey(params) {
|
|
|
9781
9781
|
userId,
|
|
9782
9782
|
blobUrl,
|
|
9783
9783
|
prfInput,
|
|
9784
|
-
credentialId: providedCredentialId
|
|
9784
|
+
credentialId: providedCredentialId,
|
|
9785
|
+
rpId = typeof window !== "undefined" ? window.location.hostname : "localhost",
|
|
9786
|
+
rpName = "Volr"
|
|
9785
9787
|
} = params;
|
|
9786
9788
|
const credentialId = providedCredentialId || prfInput.credentialId || safeStorage.getItem(STORAGE_KEYS.credentialId);
|
|
9787
9789
|
if (!credentialId) {
|
|
@@ -9810,7 +9812,7 @@ async function restorePasskey(params) {
|
|
|
9810
9812
|
`volr/master-seed/v1|${userId}|${keyStorageType}|${version5}`
|
|
9811
9813
|
);
|
|
9812
9814
|
const passkeyAdapter = createPasskeyAdapter({
|
|
9813
|
-
rpId
|
|
9815
|
+
rpId});
|
|
9814
9816
|
const provider = sdkCore.createPasskeyProvider(passkeyAdapter, {
|
|
9815
9817
|
prfInput: {
|
|
9816
9818
|
...prfInput,
|
|
@@ -19203,9 +19205,7 @@ async function enrollPasskey(params) {
|
|
|
19203
19205
|
crypto.getRandomValues(challenge2);
|
|
19204
19206
|
const userHandle = new TextEncoder().encode(userId);
|
|
19205
19207
|
const tempCredentialId = "temp-" + Date.now();
|
|
19206
|
-
const origin = typeof window !== "undefined" ? window.location.origin : "https://localhost";
|
|
19207
19208
|
const tempPrfInput = {
|
|
19208
|
-
origin,
|
|
19209
19209
|
projectId,
|
|
19210
19210
|
credentialId: tempCredentialId
|
|
19211
19211
|
};
|
|
@@ -19248,7 +19248,6 @@ async function enrollPasskey(params) {
|
|
|
19248
19248
|
const prfOutputBuffer = extensionResults.prf.results.first;
|
|
19249
19249
|
const prfOutput = new Uint8Array(prfOutputBuffer);
|
|
19250
19250
|
const prfInput = {
|
|
19251
|
-
origin,
|
|
19252
19251
|
projectId,
|
|
19253
19252
|
credentialId
|
|
19254
19253
|
};
|
|
@@ -19284,7 +19283,6 @@ async function enrollPasskey(params) {
|
|
|
19284
19283
|
apiKey,
|
|
19285
19284
|
accessToken,
|
|
19286
19285
|
blob
|
|
19287
|
-
// Don't pass axiosInstance - let uploadBlob create its own
|
|
19288
19286
|
});
|
|
19289
19287
|
if (!blobUrl) {
|
|
19290
19288
|
throw new Error("Failed to upload blob: missing key");
|
|
@@ -19297,7 +19295,6 @@ async function enrollPasskey(params) {
|
|
|
19297
19295
|
credentialId,
|
|
19298
19296
|
blobUrl,
|
|
19299
19297
|
prfInput: {
|
|
19300
|
-
origin,
|
|
19301
19298
|
projectId,
|
|
19302
19299
|
credentialId
|
|
19303
19300
|
},
|
|
@@ -19971,6 +19968,232 @@ async function checkPrfExtensionAvailable() {
|
|
|
19971
19968
|
const { prfSupported } = checkPrfSupport();
|
|
19972
19969
|
return prfSupported;
|
|
19973
19970
|
}
|
|
19971
|
+
async function requestMigration(params) {
|
|
19972
|
+
const { client, targetOrigin } = params;
|
|
19973
|
+
const response = await client.post("/wallet/migration/request", { targetOrigin });
|
|
19974
|
+
return {
|
|
19975
|
+
migrationToken: response.migrationToken,
|
|
19976
|
+
targetOrigin: response.targetOrigin,
|
|
19977
|
+
expiresAt: response.expiresAt
|
|
19978
|
+
};
|
|
19979
|
+
}
|
|
19980
|
+
function openMigrationPopup(targetOrigin, migrationToken, migrationPath = "/wallet/migrate") {
|
|
19981
|
+
const url = new URL(migrationPath, targetOrigin);
|
|
19982
|
+
url.searchParams.set("migration_token", migrationToken);
|
|
19983
|
+
const width = 500;
|
|
19984
|
+
const height = 600;
|
|
19985
|
+
const left = window.screenX + (window.outerWidth - width) / 2;
|
|
19986
|
+
const top = window.screenY + (window.outerHeight - height) / 2;
|
|
19987
|
+
return window.open(
|
|
19988
|
+
url.toString(),
|
|
19989
|
+
"volr_migration",
|
|
19990
|
+
`width=${width},height=${height},left=${left},top=${top},popup=1`
|
|
19991
|
+
);
|
|
19992
|
+
}
|
|
19993
|
+
function sendSeedToPopup(masterSeed, userId, projectId, targetOrigin, popup) {
|
|
19994
|
+
const response = {
|
|
19995
|
+
type: "VOLR_MIGRATION_SEED_RESPONSE",
|
|
19996
|
+
masterSeed: Array.from(masterSeed),
|
|
19997
|
+
userId,
|
|
19998
|
+
projectId
|
|
19999
|
+
};
|
|
20000
|
+
popup.postMessage(response, targetOrigin);
|
|
20001
|
+
}
|
|
20002
|
+
function listenForSeedRequests(allowedOrigins, getMasterSeed, getUserInfo) {
|
|
20003
|
+
const handleMessage = async (event) => {
|
|
20004
|
+
if (!allowedOrigins.includes(event.origin)) {
|
|
20005
|
+
return;
|
|
20006
|
+
}
|
|
20007
|
+
const data = event.data;
|
|
20008
|
+
if (data?.type !== "VOLR_MIGRATION_SEED_REQUEST") {
|
|
20009
|
+
return;
|
|
20010
|
+
}
|
|
20011
|
+
try {
|
|
20012
|
+
const masterSeed = await getMasterSeed();
|
|
20013
|
+
const { userId, projectId } = getUserInfo();
|
|
20014
|
+
const response = {
|
|
20015
|
+
type: "VOLR_MIGRATION_SEED_RESPONSE",
|
|
20016
|
+
masterSeed: Array.from(masterSeed),
|
|
20017
|
+
userId,
|
|
20018
|
+
projectId
|
|
20019
|
+
};
|
|
20020
|
+
event.source?.postMessage(response, { targetOrigin: event.origin });
|
|
20021
|
+
} catch (error) {
|
|
20022
|
+
const errorResponse = {
|
|
20023
|
+
type: "VOLR_MIGRATION_ERROR",
|
|
20024
|
+
code: "SEED_RETRIEVAL_FAILED",
|
|
20025
|
+
message: error instanceof Error ? error.message : "Failed to retrieve master seed"
|
|
20026
|
+
};
|
|
20027
|
+
event.source?.postMessage(errorResponse, { targetOrigin: event.origin });
|
|
20028
|
+
}
|
|
20029
|
+
};
|
|
20030
|
+
window.addEventListener("message", handleMessage);
|
|
20031
|
+
return () => {
|
|
20032
|
+
window.removeEventListener("message", handleMessage);
|
|
20033
|
+
};
|
|
20034
|
+
}
|
|
20035
|
+
function requestSeedFromOpener(sourceOrigin, migrationToken, timeout = 6e4) {
|
|
20036
|
+
return new Promise((resolve, reject) => {
|
|
20037
|
+
if (!window.opener) {
|
|
20038
|
+
reject(new Error("No opener window found. This page must be opened as a popup."));
|
|
20039
|
+
return;
|
|
20040
|
+
}
|
|
20041
|
+
const timeoutId = setTimeout(() => {
|
|
20042
|
+
window.removeEventListener("message", handleMessage);
|
|
20043
|
+
reject(new Error("Seed request timed out"));
|
|
20044
|
+
}, timeout);
|
|
20045
|
+
const handleMessage = (event) => {
|
|
20046
|
+
if (event.origin !== sourceOrigin) {
|
|
20047
|
+
return;
|
|
20048
|
+
}
|
|
20049
|
+
const data = event.data;
|
|
20050
|
+
if (data?.type === "VOLR_MIGRATION_SEED_RESPONSE") {
|
|
20051
|
+
clearTimeout(timeoutId);
|
|
20052
|
+
window.removeEventListener("message", handleMessage);
|
|
20053
|
+
resolve({
|
|
20054
|
+
masterSeed: new Uint8Array(data.masterSeed),
|
|
20055
|
+
userId: data.userId,
|
|
20056
|
+
projectId: data.projectId
|
|
20057
|
+
});
|
|
20058
|
+
} else if (data?.type === "VOLR_MIGRATION_ERROR") {
|
|
20059
|
+
clearTimeout(timeoutId);
|
|
20060
|
+
window.removeEventListener("message", handleMessage);
|
|
20061
|
+
reject(new Error(`${data.code}: ${data.message}`));
|
|
20062
|
+
}
|
|
20063
|
+
};
|
|
20064
|
+
window.addEventListener("message", handleMessage);
|
|
20065
|
+
const request = {
|
|
20066
|
+
type: "VOLR_MIGRATION_SEED_REQUEST",
|
|
20067
|
+
migrationToken
|
|
20068
|
+
};
|
|
20069
|
+
window.opener.postMessage(request, sourceOrigin);
|
|
20070
|
+
});
|
|
20071
|
+
}
|
|
20072
|
+
function detectPlatform3() {
|
|
20073
|
+
if (typeof navigator === "undefined") return "Unknown";
|
|
20074
|
+
const ua = navigator.userAgent;
|
|
20075
|
+
const platform = navigator.platform || "";
|
|
20076
|
+
if (/iPhone|iPad|iPod/.test(ua) || platform === "MacIntel" && navigator.maxTouchPoints > 1) {
|
|
20077
|
+
return "iOS";
|
|
20078
|
+
}
|
|
20079
|
+
if (/Android/.test(ua)) return "Android";
|
|
20080
|
+
if (/Mac/.test(platform)) return "macOS";
|
|
20081
|
+
if (/Win/.test(platform)) return "Windows";
|
|
20082
|
+
if (/CrOS/.test(ua)) return "ChromeOS";
|
|
20083
|
+
if (/Linux/.test(platform)) return "Linux";
|
|
20084
|
+
return "Unknown";
|
|
20085
|
+
}
|
|
20086
|
+
async function completeMigration(params) {
|
|
20087
|
+
const {
|
|
20088
|
+
client,
|
|
20089
|
+
baseUrl,
|
|
20090
|
+
apiKey,
|
|
20091
|
+
userId,
|
|
20092
|
+
projectId,
|
|
20093
|
+
migrationToken,
|
|
20094
|
+
masterSeed,
|
|
20095
|
+
rpId = typeof window !== "undefined" ? window.location.hostname : "localhost",
|
|
20096
|
+
rpName = "Volr",
|
|
20097
|
+
userEmail
|
|
20098
|
+
} = params;
|
|
20099
|
+
if (!navigator.credentials || !navigator.credentials.create) {
|
|
20100
|
+
throw new Error("WebAuthn API is not supported");
|
|
20101
|
+
}
|
|
20102
|
+
const challenge2 = new Uint8Array(32);
|
|
20103
|
+
crypto.getRandomValues(challenge2);
|
|
20104
|
+
const userHandle = new TextEncoder().encode(userId);
|
|
20105
|
+
const displayName = userEmail || `Volr Wallet (${userId.substring(0, 8)}...)`;
|
|
20106
|
+
const tempCredentialId = "temp-" + Date.now();
|
|
20107
|
+
const tempPrfInput = {
|
|
20108
|
+
projectId,
|
|
20109
|
+
credentialId: tempCredentialId
|
|
20110
|
+
};
|
|
20111
|
+
const prfSalt = sdkCore.deriveWrapKey(tempPrfInput);
|
|
20112
|
+
const publicKeyCredentialCreationOptions = {
|
|
20113
|
+
challenge: challenge2,
|
|
20114
|
+
rp: {
|
|
20115
|
+
name: rpName,
|
|
20116
|
+
id: rpId
|
|
20117
|
+
},
|
|
20118
|
+
user: {
|
|
20119
|
+
id: userHandle,
|
|
20120
|
+
name: displayName,
|
|
20121
|
+
displayName
|
|
20122
|
+
},
|
|
20123
|
+
pubKeyCredParams: PUBKEY_CRED_PARAMS,
|
|
20124
|
+
authenticatorSelection: AUTHENTICATOR_SELECTION,
|
|
20125
|
+
timeout: WEBAUTHN_TIMEOUT,
|
|
20126
|
+
attestation: ATTESTATION,
|
|
20127
|
+
extensions: {
|
|
20128
|
+
prf: {
|
|
20129
|
+
eval: {
|
|
20130
|
+
first: prfSalt.buffer
|
|
20131
|
+
}
|
|
20132
|
+
}
|
|
20133
|
+
}
|
|
20134
|
+
};
|
|
20135
|
+
const credential = await navigator.credentials.create({
|
|
20136
|
+
publicKey: publicKeyCredentialCreationOptions
|
|
20137
|
+
});
|
|
20138
|
+
if (!credential || !("response" in credential)) {
|
|
20139
|
+
throw new Error("Failed to create passkey credential");
|
|
20140
|
+
}
|
|
20141
|
+
const credentialId = Array.from(new Uint8Array(credential.rawId)).map((b) => b.toString(16).padStart(2, "0")).join("");
|
|
20142
|
+
const extensionResults = credential.getClientExtensionResults();
|
|
20143
|
+
if (!extensionResults.prf?.results?.first) {
|
|
20144
|
+
throw new Error("PRF extension not supported or PRF output missing");
|
|
20145
|
+
}
|
|
20146
|
+
const prfOutputBuffer = extensionResults.prf.results.first;
|
|
20147
|
+
const prfOutput = new Uint8Array(prfOutputBuffer);
|
|
20148
|
+
const wrapKey = prfOutput;
|
|
20149
|
+
const keyStorageType = "passkey";
|
|
20150
|
+
const version5 = "v1";
|
|
20151
|
+
const aadBytes = new TextEncoder().encode(
|
|
20152
|
+
`volr/master-seed/v1|${userId}|${keyStorageType}|${version5}`
|
|
20153
|
+
);
|
|
20154
|
+
const encryptedBlob = await sdkCore.sealMasterSeed(masterSeed, wrapKey, aadBytes);
|
|
20155
|
+
const blob = new Blob(
|
|
20156
|
+
[
|
|
20157
|
+
encryptedBlob.cipher,
|
|
20158
|
+
encryptedBlob.nonce
|
|
20159
|
+
],
|
|
20160
|
+
{ type: "application/octet-stream" }
|
|
20161
|
+
);
|
|
20162
|
+
const accessToken = client.getAccessToken();
|
|
20163
|
+
if (!accessToken) {
|
|
20164
|
+
throw new Error("Access token is required");
|
|
20165
|
+
}
|
|
20166
|
+
const { key: blobUrl } = await sdkCore.uploadBlob({
|
|
20167
|
+
baseUrl,
|
|
20168
|
+
apiKey,
|
|
20169
|
+
accessToken,
|
|
20170
|
+
blob
|
|
20171
|
+
});
|
|
20172
|
+
if (!blobUrl) {
|
|
20173
|
+
throw new Error("Failed to upload blob");
|
|
20174
|
+
}
|
|
20175
|
+
const platform = detectPlatform3();
|
|
20176
|
+
await client.post("/wallet/migration/complete", {
|
|
20177
|
+
migrationToken,
|
|
20178
|
+
credentialId,
|
|
20179
|
+
blobUrl,
|
|
20180
|
+
prfInput: {
|
|
20181
|
+
projectId,
|
|
20182
|
+
credentialId
|
|
20183
|
+
},
|
|
20184
|
+
rpId,
|
|
20185
|
+
platform
|
|
20186
|
+
});
|
|
20187
|
+
return {
|
|
20188
|
+
credentialId,
|
|
20189
|
+
blobUrl,
|
|
20190
|
+
rpId
|
|
20191
|
+
};
|
|
20192
|
+
}
|
|
20193
|
+
async function getUserCredentials(client) {
|
|
20194
|
+
const response = await client.get("/wallet/credentials");
|
|
20195
|
+
return response.credentials;
|
|
20196
|
+
}
|
|
19974
20197
|
/*! Bundled license information:
|
|
19975
20198
|
|
|
19976
20199
|
@noble/hashes/esm/utils.js:
|
|
@@ -20026,6 +20249,7 @@ exports.checkPrfExtensionAvailable = checkPrfExtensionAvailable;
|
|
|
20026
20249
|
exports.checkPrfSupport = checkPrfSupport;
|
|
20027
20250
|
exports.compareERC20Balances = compareERC20Balances;
|
|
20028
20251
|
exports.compareWalletStates = compareWalletStates;
|
|
20252
|
+
exports.completeMigration = completeMigration;
|
|
20029
20253
|
exports.createGetNetworkInfo = createGetNetworkInfo;
|
|
20030
20254
|
exports.createPasskeyAdapter = createPasskeyAdapter;
|
|
20031
20255
|
exports.debugTransactionFailure = debugTransactionFailure;
|
|
@@ -20033,11 +20257,17 @@ exports.defaultIdempotencyKey = defaultIdempotencyKey;
|
|
|
20033
20257
|
exports.diagnoseTransactionFailure = diagnoseTransactionFailure;
|
|
20034
20258
|
exports.getERC20Balance = getERC20Balance;
|
|
20035
20259
|
exports.getPasskeyAuthGuidance = getPasskeyAuthGuidance;
|
|
20260
|
+
exports.getUserCredentials = getUserCredentials;
|
|
20036
20261
|
exports.getWalletState = getWalletState;
|
|
20037
20262
|
exports.isEIP7702Delegated = isEIP7702Delegated;
|
|
20038
20263
|
exports.isUserCancelledError = isUserCancelledError;
|
|
20264
|
+
exports.listenForSeedRequests = listenForSeedRequests;
|
|
20039
20265
|
exports.normalizeHex = normalizeHex;
|
|
20040
20266
|
exports.normalizeHexArray = normalizeHexArray;
|
|
20267
|
+
exports.openMigrationPopup = openMigrationPopup;
|
|
20268
|
+
exports.requestMigration = requestMigration;
|
|
20269
|
+
exports.requestSeedFromOpener = requestSeedFromOpener;
|
|
20270
|
+
exports.sendSeedToPopup = sendSeedToPopup;
|
|
20041
20271
|
exports.uploadBlobViaPresign = uploadBlobViaPresign;
|
|
20042
20272
|
exports.useDepositListener = useDepositListener;
|
|
20043
20273
|
exports.useInternalAuth = useInternalAuth;
|