@volr/react 0.1.109 → 0.1.110

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
@@ -7883,7 +7883,7 @@ var init_BlockOverrides = __esm({
7883
7883
  });
7884
7884
 
7885
7885
  // ../node_modules/viem/_esm/constants/abis.js
7886
- var multicall3Abi, batchGatewayAbi, universalResolverErrors, universalResolverResolveAbi, universalResolverReverseAbi, textResolverAbi, addressResolverAbi, erc1271Abi, erc6492SignatureValidatorAbi;
7886
+ var multicall3Abi, batchGatewayAbi, universalResolverErrors, universalResolverResolveAbi, universalResolverReverseAbi, textResolverAbi, addressResolverAbi, erc1271Abi, erc6492SignatureValidatorAbi, erc20Abi;
7887
7887
  var init_abis = __esm({
7888
7888
  "../node_modules/viem/_esm/constants/abis.js"() {
7889
7889
  multicall3Abi = [
@@ -8220,6 +8220,194 @@ var init_abis = __esm({
8220
8220
  name: "isValidSig"
8221
8221
  }
8222
8222
  ];
8223
+ erc20Abi = [
8224
+ {
8225
+ type: "event",
8226
+ name: "Approval",
8227
+ inputs: [
8228
+ {
8229
+ indexed: true,
8230
+ name: "owner",
8231
+ type: "address"
8232
+ },
8233
+ {
8234
+ indexed: true,
8235
+ name: "spender",
8236
+ type: "address"
8237
+ },
8238
+ {
8239
+ indexed: false,
8240
+ name: "value",
8241
+ type: "uint256"
8242
+ }
8243
+ ]
8244
+ },
8245
+ {
8246
+ type: "event",
8247
+ name: "Transfer",
8248
+ inputs: [
8249
+ {
8250
+ indexed: true,
8251
+ name: "from",
8252
+ type: "address"
8253
+ },
8254
+ {
8255
+ indexed: true,
8256
+ name: "to",
8257
+ type: "address"
8258
+ },
8259
+ {
8260
+ indexed: false,
8261
+ name: "value",
8262
+ type: "uint256"
8263
+ }
8264
+ ]
8265
+ },
8266
+ {
8267
+ type: "function",
8268
+ name: "allowance",
8269
+ stateMutability: "view",
8270
+ inputs: [
8271
+ {
8272
+ name: "owner",
8273
+ type: "address"
8274
+ },
8275
+ {
8276
+ name: "spender",
8277
+ type: "address"
8278
+ }
8279
+ ],
8280
+ outputs: [
8281
+ {
8282
+ type: "uint256"
8283
+ }
8284
+ ]
8285
+ },
8286
+ {
8287
+ type: "function",
8288
+ name: "approve",
8289
+ stateMutability: "nonpayable",
8290
+ inputs: [
8291
+ {
8292
+ name: "spender",
8293
+ type: "address"
8294
+ },
8295
+ {
8296
+ name: "amount",
8297
+ type: "uint256"
8298
+ }
8299
+ ],
8300
+ outputs: [
8301
+ {
8302
+ type: "bool"
8303
+ }
8304
+ ]
8305
+ },
8306
+ {
8307
+ type: "function",
8308
+ name: "balanceOf",
8309
+ stateMutability: "view",
8310
+ inputs: [
8311
+ {
8312
+ name: "account",
8313
+ type: "address"
8314
+ }
8315
+ ],
8316
+ outputs: [
8317
+ {
8318
+ type: "uint256"
8319
+ }
8320
+ ]
8321
+ },
8322
+ {
8323
+ type: "function",
8324
+ name: "decimals",
8325
+ stateMutability: "view",
8326
+ inputs: [],
8327
+ outputs: [
8328
+ {
8329
+ type: "uint8"
8330
+ }
8331
+ ]
8332
+ },
8333
+ {
8334
+ type: "function",
8335
+ name: "name",
8336
+ stateMutability: "view",
8337
+ inputs: [],
8338
+ outputs: [
8339
+ {
8340
+ type: "string"
8341
+ }
8342
+ ]
8343
+ },
8344
+ {
8345
+ type: "function",
8346
+ name: "symbol",
8347
+ stateMutability: "view",
8348
+ inputs: [],
8349
+ outputs: [
8350
+ {
8351
+ type: "string"
8352
+ }
8353
+ ]
8354
+ },
8355
+ {
8356
+ type: "function",
8357
+ name: "totalSupply",
8358
+ stateMutability: "view",
8359
+ inputs: [],
8360
+ outputs: [
8361
+ {
8362
+ type: "uint256"
8363
+ }
8364
+ ]
8365
+ },
8366
+ {
8367
+ type: "function",
8368
+ name: "transfer",
8369
+ stateMutability: "nonpayable",
8370
+ inputs: [
8371
+ {
8372
+ name: "recipient",
8373
+ type: "address"
8374
+ },
8375
+ {
8376
+ name: "amount",
8377
+ type: "uint256"
8378
+ }
8379
+ ],
8380
+ outputs: [
8381
+ {
8382
+ type: "bool"
8383
+ }
8384
+ ]
8385
+ },
8386
+ {
8387
+ type: "function",
8388
+ name: "transferFrom",
8389
+ stateMutability: "nonpayable",
8390
+ inputs: [
8391
+ {
8392
+ name: "sender",
8393
+ type: "address"
8394
+ },
8395
+ {
8396
+ name: "recipient",
8397
+ type: "address"
8398
+ },
8399
+ {
8400
+ name: "amount",
8401
+ type: "uint256"
8402
+ }
8403
+ ],
8404
+ outputs: [
8405
+ {
8406
+ type: "bool"
8407
+ }
8408
+ ]
8409
+ }
8410
+ ];
8223
8411
  }
8224
8412
  });
8225
8413
 
@@ -16002,6 +16190,51 @@ var InvalidWrappedSignatureError = class extends BaseError3 {
16002
16190
  }
16003
16191
  };
16004
16192
 
16193
+ // ../node_modules/viem/_esm/errors/unit.js
16194
+ init_base();
16195
+ var InvalidDecimalNumberError = class extends BaseError2 {
16196
+ constructor({ value }) {
16197
+ super(`Number \`${value}\` is not a valid decimal number.`, {
16198
+ name: "InvalidDecimalNumberError"
16199
+ });
16200
+ }
16201
+ };
16202
+
16203
+ // ../node_modules/viem/_esm/utils/unit/parseUnits.js
16204
+ function parseUnits(value, decimals) {
16205
+ if (!/^(-?)([0-9]*)\.?([0-9]*)$/.test(value))
16206
+ throw new InvalidDecimalNumberError({ value });
16207
+ let [integer, fraction = "0"] = value.split(".");
16208
+ const negative = integer.startsWith("-");
16209
+ if (negative)
16210
+ integer = integer.slice(1);
16211
+ fraction = fraction.replace(/(0+)$/, "");
16212
+ if (decimals === 0) {
16213
+ if (Math.round(Number(`.${fraction}`)) === 1)
16214
+ integer = `${BigInt(integer) + 1n}`;
16215
+ fraction = "";
16216
+ } else if (fraction.length > decimals) {
16217
+ const [left, unit, right] = [
16218
+ fraction.slice(0, decimals - 1),
16219
+ fraction.slice(decimals - 1, decimals),
16220
+ fraction.slice(decimals)
16221
+ ];
16222
+ const rounded = Math.round(Number(`${unit}.${right}`));
16223
+ if (rounded > 9)
16224
+ fraction = `${BigInt(left) + BigInt(1)}0`.padStart(left.length + 1, "0");
16225
+ else
16226
+ fraction = `${left}${rounded}`;
16227
+ if (fraction.length > decimals) {
16228
+ fraction = fraction.slice(1);
16229
+ integer = `${BigInt(integer) + 1n}`;
16230
+ }
16231
+ fraction = fraction.slice(0, decimals);
16232
+ } else {
16233
+ fraction = fraction.padEnd(decimals, "0");
16234
+ }
16235
+ return BigInt(`${negative ? "-" : ""}${integer}${fraction}`);
16236
+ }
16237
+
16005
16238
  // ../node_modules/viem/_esm/utils/formatters/proof.js
16006
16239
  function formatStorageProof(storageProof) {
16007
16240
  return storageProof.map((proof) => ({
@@ -18041,6 +18274,7 @@ function http(url, config = {}) {
18041
18274
  }
18042
18275
 
18043
18276
  // ../node_modules/viem/_esm/index.js
18277
+ init_abis();
18044
18278
  init_encodeFunctionData();
18045
18279
  init_getAddress();
18046
18280
  init_formatEther();
@@ -19710,6 +19944,216 @@ function useVolrPaymentApi() {
19710
19944
  isLoading
19711
19945
  };
19712
19946
  }
19947
+ function formatBalance(raw, decimals) {
19948
+ const divisor = 10n ** BigInt(decimals);
19949
+ const integerPart = raw / divisor;
19950
+ const fractionalPart = raw % divisor;
19951
+ const fractionalStr = fractionalPart.toString().padStart(decimals, "0");
19952
+ const trimmedFractional = fractionalStr.replace(/0+$/, "");
19953
+ const displayFractional = trimmedFractional.slice(0, 6) || "0";
19954
+ if (displayFractional === "0" && integerPart === 0n) {
19955
+ return "0";
19956
+ }
19957
+ return `${integerPart.toLocaleString()}.${displayFractional}`.replace(/\.$/, "");
19958
+ }
19959
+ function getNativeSymbol(chainId) {
19960
+ switch (chainId) {
19961
+ case 137:
19962
+ case 80002:
19963
+ return "POL";
19964
+ case 56:
19965
+ case 97:
19966
+ return "BNB";
19967
+ case 43114:
19968
+ case 43113:
19969
+ return "AVAX";
19970
+ default:
19971
+ return "ETH";
19972
+ }
19973
+ }
19974
+ function useUserBalances() {
19975
+ const { user, config } = useVolrContext();
19976
+ const { client } = useInternalAuth();
19977
+ const [brandingData, setBrandingData] = useState(null);
19978
+ const [balances, setBalances] = useState([]);
19979
+ const [isLoadingBranding, setIsLoadingBranding] = useState(true);
19980
+ const [error, setError] = useState(null);
19981
+ const getRpcUrl = useMemo(
19982
+ () => createGetRpcUrl({ client, rpcOverrides: config.rpcOverrides }),
19983
+ [client, config.rpcOverrides]
19984
+ );
19985
+ useEffect(() => {
19986
+ setIsLoadingBranding(true);
19987
+ setError(null);
19988
+ client.get("/auth/branding").then((response) => {
19989
+ setBrandingData(response);
19990
+ const initialBalances = response.depositAssets.map((asset) => {
19991
+ const isNative = asset.token === "native";
19992
+ const token = asset.token;
19993
+ const address = isNative ? "0x0000000000000000000000000000000000000000" : token.address;
19994
+ const id = `${asset.chainId}_${isNative ? "native" : address.toLowerCase()}`;
19995
+ return {
19996
+ id,
19997
+ chainId: asset.chainId,
19998
+ symbol: isNative ? getNativeSymbol(asset.chainId) : token.symbol,
19999
+ decimals: isNative ? 18 : token.decimals,
20000
+ address,
20001
+ iconUrl: isNative ? void 0 : token.iconUrl,
20002
+ isNative,
20003
+ balanceRaw: 0n,
20004
+ balance: "0",
20005
+ isLoading: true
20006
+ };
20007
+ });
20008
+ setBalances(initialBalances);
20009
+ }).catch((err) => {
20010
+ console.error("[useUserBalances] Failed to fetch branding:", err);
20011
+ setError(err instanceof Error ? err : new Error("Failed to fetch branding"));
20012
+ }).finally(() => {
20013
+ setIsLoadingBranding(false);
20014
+ });
20015
+ }, [client]);
20016
+ const fetchBalances = useCallback(async () => {
20017
+ if (!user?.evmAddress || !brandingData?.depositAssets.length) {
20018
+ return;
20019
+ }
20020
+ const userAddress = user.evmAddress;
20021
+ const balancePromises = brandingData.depositAssets.map(async (asset) => {
20022
+ const isNative = asset.token === "native";
20023
+ const token = asset.token;
20024
+ const address = isNative ? "0x0000000000000000000000000000000000000000" : token.address;
20025
+ const id = `${asset.chainId}_${isNative ? "native" : address.toLowerCase()}`;
20026
+ try {
20027
+ const rpcUrl = await getRpcUrl(asset.chainId);
20028
+ const publicClient = createPublicClient({
20029
+ transport: http(rpcUrl)
20030
+ });
20031
+ let balanceRaw;
20032
+ const decimals = isNative ? 18 : token.decimals;
20033
+ if (isNative) {
20034
+ balanceRaw = await publicClient.getBalance({ address: userAddress });
20035
+ } else {
20036
+ balanceRaw = await publicClient.readContract({
20037
+ address: token.address,
20038
+ abi: erc20Abi,
20039
+ functionName: "balanceOf",
20040
+ args: [userAddress]
20041
+ });
20042
+ }
20043
+ return {
20044
+ id,
20045
+ balanceRaw,
20046
+ balance: formatBalance(balanceRaw, decimals),
20047
+ isLoading: false,
20048
+ error: void 0
20049
+ };
20050
+ } catch (err) {
20051
+ console.error(`[useUserBalances] Failed to fetch balance for ${id}:`, err);
20052
+ return {
20053
+ id,
20054
+ balanceRaw: 0n,
20055
+ balance: "0",
20056
+ isLoading: false,
20057
+ error: "Failed to fetch balance"
20058
+ };
20059
+ }
20060
+ });
20061
+ const results = await Promise.all(balancePromises);
20062
+ setBalances(
20063
+ (prev) => prev.map((b) => {
20064
+ const result = results.find((r) => r.id === b.id);
20065
+ if (result) {
20066
+ return { ...b, ...result };
20067
+ }
20068
+ return b;
20069
+ })
20070
+ );
20071
+ }, [user?.evmAddress, brandingData?.depositAssets, getRpcUrl]);
20072
+ useEffect(() => {
20073
+ if (!isLoadingBranding && user?.evmAddress && brandingData) {
20074
+ fetchBalances();
20075
+ }
20076
+ }, [isLoadingBranding, user?.evmAddress, brandingData, fetchBalances]);
20077
+ const totalUsd = useMemo(() => {
20078
+ return balances.reduce((sum, b) => sum + (b.balanceUsd ?? 0), 0);
20079
+ }, [balances]);
20080
+ const isLoading = isLoadingBranding || balances.some((b) => b.isLoading);
20081
+ return {
20082
+ balances,
20083
+ totalUsd,
20084
+ isLoading,
20085
+ paymentEnabled: brandingData?.paymentEnabled ?? false,
20086
+ refresh: fetchBalances,
20087
+ error
20088
+ };
20089
+ }
20090
+ function isNativeToken(address) {
20091
+ const normalized = address.toLowerCase();
20092
+ return normalized === "native" || normalized === "0x0000000000000000000000000000000000000000" || normalized === "0x0";
20093
+ }
20094
+ function useWithdraw() {
20095
+ const { evm, isLoggedIn } = useVolr();
20096
+ const [isWithdrawing, setIsWithdrawing] = useState(false);
20097
+ const [result, setResult] = useState(null);
20098
+ const [error, setError] = useState(null);
20099
+ const withdraw = useCallback(
20100
+ async (params) => {
20101
+ if (!isLoggedIn) {
20102
+ throw new Error("User must be logged in to withdraw");
20103
+ }
20104
+ if (!evm.address) {
20105
+ throw new Error("Wallet address not available");
20106
+ }
20107
+ setIsWithdrawing(true);
20108
+ setError(null);
20109
+ setResult(null);
20110
+ try {
20111
+ const { chainId, tokenAddress, decimals, amount, to } = params;
20112
+ const client = evm.client(chainId);
20113
+ const amountRaw = parseUnits(amount, decimals);
20114
+ let txResult;
20115
+ if (isNativeToken(tokenAddress)) {
20116
+ txResult = await client.sendTransaction({
20117
+ to,
20118
+ data: "0x",
20119
+ value: amountRaw
20120
+ });
20121
+ } else {
20122
+ const data = encodeFunctionData({
20123
+ abi: erc20Abi,
20124
+ functionName: "transfer",
20125
+ args: [to, amountRaw]
20126
+ });
20127
+ txResult = await client.sendTransaction({
20128
+ to: tokenAddress,
20129
+ data
20130
+ });
20131
+ }
20132
+ setResult(txResult);
20133
+ return txResult;
20134
+ } catch (err) {
20135
+ const error2 = err instanceof Error ? err : new Error("Withdrawal failed");
20136
+ setError(error2);
20137
+ throw error2;
20138
+ } finally {
20139
+ setIsWithdrawing(false);
20140
+ }
20141
+ },
20142
+ [evm, isLoggedIn]
20143
+ );
20144
+ const reset = useCallback(() => {
20145
+ setIsWithdrawing(false);
20146
+ setResult(null);
20147
+ setError(null);
20148
+ }, []);
20149
+ return {
20150
+ withdraw,
20151
+ isWithdrawing,
20152
+ result,
20153
+ error,
20154
+ reset
20155
+ };
20156
+ }
19713
20157
 
19714
20158
  // src/utils/contract-analysis.ts
19715
20159
  var EIP7702_PREFIX = "0xef0100";
@@ -20307,6 +20751,101 @@ async function getUserCredentials(client) {
20307
20751
  const response = await client.get("/wallet/credentials");
20308
20752
  return response.credentials;
20309
20753
  }
20754
+ function useEIP6963() {
20755
+ const [providers, setProviders] = useState([]);
20756
+ const [hasLegacyProvider, setHasLegacyProvider] = useState(false);
20757
+ const [isDetecting, setIsDetecting] = useState(true);
20758
+ useEffect(() => {
20759
+ if (typeof window === "undefined") {
20760
+ setIsDetecting(false);
20761
+ return;
20762
+ }
20763
+ const handleAnnounceProvider = (event) => {
20764
+ const { detail } = event;
20765
+ setProviders((prev) => {
20766
+ if (prev.some((p) => p.info.uuid === detail.info.uuid)) {
20767
+ return prev;
20768
+ }
20769
+ return [...prev, detail];
20770
+ });
20771
+ };
20772
+ window.addEventListener("eip6963:announceProvider", handleAnnounceProvider);
20773
+ window.dispatchEvent(new Event("eip6963:requestProvider"));
20774
+ const hasLegacy = !!window.ethereum;
20775
+ setHasLegacyProvider(hasLegacy);
20776
+ const timeout = setTimeout(() => {
20777
+ setIsDetecting(false);
20778
+ }, 200);
20779
+ return () => {
20780
+ window.removeEventListener(
20781
+ "eip6963:announceProvider",
20782
+ handleAnnounceProvider
20783
+ );
20784
+ clearTimeout(timeout);
20785
+ };
20786
+ }, []);
20787
+ const getProvider = useCallback(() => {
20788
+ if (providers.length > 0) {
20789
+ return { provider: providers[0].provider, info: providers[0].info };
20790
+ }
20791
+ if (hasLegacyProvider && window.ethereum) {
20792
+ return { provider: window.ethereum, info: null };
20793
+ }
20794
+ return { provider: null, info: null };
20795
+ }, [providers, hasLegacyProvider]);
20796
+ const getWalletsForDisplay = useCallback(() => {
20797
+ const walletsToShow = [];
20798
+ providers.forEach((p) => {
20799
+ walletsToShow.push({
20800
+ id: p.info.uuid,
20801
+ name: p.info.name,
20802
+ icon: p.info.icon,
20803
+ provider: p.provider,
20804
+ rdns: p.info.rdns
20805
+ });
20806
+ });
20807
+ if (hasLegacyProvider && providers.length === 0) {
20808
+ const ethereum = window.ethereum;
20809
+ let name = "Wallet";
20810
+ if (ethereum?.isMetaMask) name = "MetaMask";
20811
+ else if (ethereum?.isCoinbaseWallet) name = "Coinbase Wallet";
20812
+ else if (ethereum?.isRabby) name = "Rabby";
20813
+ else if (ethereum?.isBraveWallet) name = "Brave Wallet";
20814
+ walletsToShow.push({
20815
+ id: "legacy",
20816
+ name,
20817
+ provider: ethereum,
20818
+ isLegacy: true
20819
+ });
20820
+ }
20821
+ return walletsToShow;
20822
+ }, [providers, hasLegacyProvider]);
20823
+ const { provider, info } = getProvider();
20824
+ const hasWallet = provider !== null;
20825
+ return {
20826
+ provider,
20827
+ providerInfo: info,
20828
+ hasWallet,
20829
+ isDetecting,
20830
+ allProviders: providers,
20831
+ hasLegacyProvider,
20832
+ getWalletsForDisplay
20833
+ };
20834
+ }
20835
+ function detectWalletConnector(provider, providerInfo) {
20836
+ if (providerInfo?.rdns) {
20837
+ return providerInfo.rdns;
20838
+ }
20839
+ if (!provider) return "unknown";
20840
+ if (provider.isMetaMask) return "io.metamask";
20841
+ if (provider.isCoinbaseWallet) return "com.coinbase.wallet";
20842
+ if (provider.isRabby) return "io.rabby";
20843
+ if (provider.isZerion) return "io.zerion";
20844
+ if (provider.isBraveWallet) return "com.brave.wallet";
20845
+ if (provider.isTrust) return "com.trustwallet";
20846
+ if (provider.isPhantom) return "app.phantom";
20847
+ return "unknown";
20848
+ }
20310
20849
  /*! Bundled license information:
20311
20850
 
20312
20851
  @noble/hashes/esm/utils.js:
@@ -20321,6 +20860,6 @@ async function getUserCredentials(client) {
20321
20860
  (*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) *)
20322
20861
  */
20323
20862
 
20324
- 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, useVolrPaymentApi };
20863
+ export { DEFAULT_EXPIRES_IN_SEC, DEFAULT_MODE, PasskeyNotFoundError, PrfNotSupportedError, UserCancelledError, VolrProvider, analyzeContractForEIP7702, buildCall, buildCalls, checkPrfExtensionAvailable, checkPrfSupport, compareERC20Balances, compareWalletStates, completeMigration, createGetNetworkInfo, createPasskeyAdapter, debugTransactionFailure, defaultIdempotencyKey, detectWalletConnector, diagnoseTransactionFailure, getERC20Balance, getPasskeyAuthGuidance, getUserCredentials, getWalletState, isEIP7702Delegated, isUserCancelledError, listenForSeedRequests, normalizeHex, normalizeHexArray, openMigrationPopup, requestMigration, requestSeedFromOpener, sendSeedToPopup, uploadBlobViaPresign, useDepositListener, useEIP6963, useInternalAuth, useMpcConnection, usePasskeyEnrollment, useUserBalances, useVolr, useVolrAuthCallback, useVolrContext, useVolrLogin, useVolrPaymentApi, useWithdraw };
20325
20864
  //# sourceMappingURL=index.js.map
20326
20865
  //# sourceMappingURL=index.js.map