@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.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, signSession, getAuthNonce, signAuthorization, deriveWrapKey, createMasterKeyProvider, sealMasterSeed, uploadBlob, deriveEvmKey, ZERO_HASH, selectSigner, VolrError } from '@volr/sdk-core';
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: typeof window !== "undefined" ? window.location.hostname : "localhost"});
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 = "Volr"
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
- const projectId = user.id;
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: "Volr"
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