@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.cjs CHANGED
@@ -7907,7 +7907,7 @@ var init_BlockOverrides = __esm({
7907
7907
  });
7908
7908
 
7909
7909
  // ../node_modules/viem/_esm/constants/abis.js
7910
- var multicall3Abi, batchGatewayAbi, universalResolverErrors, universalResolverResolveAbi, universalResolverReverseAbi, textResolverAbi, addressResolverAbi, erc1271Abi, erc6492SignatureValidatorAbi;
7910
+ var multicall3Abi, batchGatewayAbi, universalResolverErrors, universalResolverResolveAbi, universalResolverReverseAbi, textResolverAbi, addressResolverAbi, erc1271Abi, erc6492SignatureValidatorAbi, erc20Abi;
7911
7911
  var init_abis = __esm({
7912
7912
  "../node_modules/viem/_esm/constants/abis.js"() {
7913
7913
  multicall3Abi = [
@@ -8244,6 +8244,194 @@ var init_abis = __esm({
8244
8244
  name: "isValidSig"
8245
8245
  }
8246
8246
  ];
8247
+ erc20Abi = [
8248
+ {
8249
+ type: "event",
8250
+ name: "Approval",
8251
+ inputs: [
8252
+ {
8253
+ indexed: true,
8254
+ name: "owner",
8255
+ type: "address"
8256
+ },
8257
+ {
8258
+ indexed: true,
8259
+ name: "spender",
8260
+ type: "address"
8261
+ },
8262
+ {
8263
+ indexed: false,
8264
+ name: "value",
8265
+ type: "uint256"
8266
+ }
8267
+ ]
8268
+ },
8269
+ {
8270
+ type: "event",
8271
+ name: "Transfer",
8272
+ inputs: [
8273
+ {
8274
+ indexed: true,
8275
+ name: "from",
8276
+ type: "address"
8277
+ },
8278
+ {
8279
+ indexed: true,
8280
+ name: "to",
8281
+ type: "address"
8282
+ },
8283
+ {
8284
+ indexed: false,
8285
+ name: "value",
8286
+ type: "uint256"
8287
+ }
8288
+ ]
8289
+ },
8290
+ {
8291
+ type: "function",
8292
+ name: "allowance",
8293
+ stateMutability: "view",
8294
+ inputs: [
8295
+ {
8296
+ name: "owner",
8297
+ type: "address"
8298
+ },
8299
+ {
8300
+ name: "spender",
8301
+ type: "address"
8302
+ }
8303
+ ],
8304
+ outputs: [
8305
+ {
8306
+ type: "uint256"
8307
+ }
8308
+ ]
8309
+ },
8310
+ {
8311
+ type: "function",
8312
+ name: "approve",
8313
+ stateMutability: "nonpayable",
8314
+ inputs: [
8315
+ {
8316
+ name: "spender",
8317
+ type: "address"
8318
+ },
8319
+ {
8320
+ name: "amount",
8321
+ type: "uint256"
8322
+ }
8323
+ ],
8324
+ outputs: [
8325
+ {
8326
+ type: "bool"
8327
+ }
8328
+ ]
8329
+ },
8330
+ {
8331
+ type: "function",
8332
+ name: "balanceOf",
8333
+ stateMutability: "view",
8334
+ inputs: [
8335
+ {
8336
+ name: "account",
8337
+ type: "address"
8338
+ }
8339
+ ],
8340
+ outputs: [
8341
+ {
8342
+ type: "uint256"
8343
+ }
8344
+ ]
8345
+ },
8346
+ {
8347
+ type: "function",
8348
+ name: "decimals",
8349
+ stateMutability: "view",
8350
+ inputs: [],
8351
+ outputs: [
8352
+ {
8353
+ type: "uint8"
8354
+ }
8355
+ ]
8356
+ },
8357
+ {
8358
+ type: "function",
8359
+ name: "name",
8360
+ stateMutability: "view",
8361
+ inputs: [],
8362
+ outputs: [
8363
+ {
8364
+ type: "string"
8365
+ }
8366
+ ]
8367
+ },
8368
+ {
8369
+ type: "function",
8370
+ name: "symbol",
8371
+ stateMutability: "view",
8372
+ inputs: [],
8373
+ outputs: [
8374
+ {
8375
+ type: "string"
8376
+ }
8377
+ ]
8378
+ },
8379
+ {
8380
+ type: "function",
8381
+ name: "totalSupply",
8382
+ stateMutability: "view",
8383
+ inputs: [],
8384
+ outputs: [
8385
+ {
8386
+ type: "uint256"
8387
+ }
8388
+ ]
8389
+ },
8390
+ {
8391
+ type: "function",
8392
+ name: "transfer",
8393
+ stateMutability: "nonpayable",
8394
+ inputs: [
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
+ {
8411
+ type: "function",
8412
+ name: "transferFrom",
8413
+ stateMutability: "nonpayable",
8414
+ inputs: [
8415
+ {
8416
+ name: "sender",
8417
+ type: "address"
8418
+ },
8419
+ {
8420
+ name: "recipient",
8421
+ type: "address"
8422
+ },
8423
+ {
8424
+ name: "amount",
8425
+ type: "uint256"
8426
+ }
8427
+ ],
8428
+ outputs: [
8429
+ {
8430
+ type: "bool"
8431
+ }
8432
+ ]
8433
+ }
8434
+ ];
8247
8435
  }
8248
8436
  });
8249
8437
 
@@ -16026,6 +16214,51 @@ var InvalidWrappedSignatureError = class extends BaseError3 {
16026
16214
  }
16027
16215
  };
16028
16216
 
16217
+ // ../node_modules/viem/_esm/errors/unit.js
16218
+ init_base();
16219
+ var InvalidDecimalNumberError = class extends BaseError2 {
16220
+ constructor({ value }) {
16221
+ super(`Number \`${value}\` is not a valid decimal number.`, {
16222
+ name: "InvalidDecimalNumberError"
16223
+ });
16224
+ }
16225
+ };
16226
+
16227
+ // ../node_modules/viem/_esm/utils/unit/parseUnits.js
16228
+ function parseUnits(value, decimals) {
16229
+ if (!/^(-?)([0-9]*)\.?([0-9]*)$/.test(value))
16230
+ throw new InvalidDecimalNumberError({ value });
16231
+ let [integer, fraction = "0"] = value.split(".");
16232
+ const negative = integer.startsWith("-");
16233
+ if (negative)
16234
+ integer = integer.slice(1);
16235
+ fraction = fraction.replace(/(0+)$/, "");
16236
+ if (decimals === 0) {
16237
+ if (Math.round(Number(`.${fraction}`)) === 1)
16238
+ integer = `${BigInt(integer) + 1n}`;
16239
+ fraction = "";
16240
+ } else if (fraction.length > decimals) {
16241
+ const [left, unit, right] = [
16242
+ fraction.slice(0, decimals - 1),
16243
+ fraction.slice(decimals - 1, decimals),
16244
+ fraction.slice(decimals)
16245
+ ];
16246
+ const rounded = Math.round(Number(`${unit}.${right}`));
16247
+ if (rounded > 9)
16248
+ fraction = `${BigInt(left) + BigInt(1)}0`.padStart(left.length + 1, "0");
16249
+ else
16250
+ fraction = `${left}${rounded}`;
16251
+ if (fraction.length > decimals) {
16252
+ fraction = fraction.slice(1);
16253
+ integer = `${BigInt(integer) + 1n}`;
16254
+ }
16255
+ fraction = fraction.slice(0, decimals);
16256
+ } else {
16257
+ fraction = fraction.padEnd(decimals, "0");
16258
+ }
16259
+ return BigInt(`${negative ? "-" : ""}${integer}${fraction}`);
16260
+ }
16261
+
16029
16262
  // ../node_modules/viem/_esm/utils/formatters/proof.js
16030
16263
  function formatStorageProof(storageProof) {
16031
16264
  return storageProof.map((proof) => ({
@@ -18065,6 +18298,7 @@ function http(url, config = {}) {
18065
18298
  }
18066
18299
 
18067
18300
  // ../node_modules/viem/_esm/index.js
18301
+ init_abis();
18068
18302
  init_encodeFunctionData();
18069
18303
  init_getAddress();
18070
18304
  init_formatEther();
@@ -19734,6 +19968,216 @@ function useVolrPaymentApi() {
19734
19968
  isLoading
19735
19969
  };
19736
19970
  }
19971
+ function formatBalance(raw, decimals) {
19972
+ const divisor = 10n ** BigInt(decimals);
19973
+ const integerPart = raw / divisor;
19974
+ const fractionalPart = raw % divisor;
19975
+ const fractionalStr = fractionalPart.toString().padStart(decimals, "0");
19976
+ const trimmedFractional = fractionalStr.replace(/0+$/, "");
19977
+ const displayFractional = trimmedFractional.slice(0, 6) || "0";
19978
+ if (displayFractional === "0" && integerPart === 0n) {
19979
+ return "0";
19980
+ }
19981
+ return `${integerPart.toLocaleString()}.${displayFractional}`.replace(/\.$/, "");
19982
+ }
19983
+ function getNativeSymbol(chainId) {
19984
+ switch (chainId) {
19985
+ case 137:
19986
+ case 80002:
19987
+ return "POL";
19988
+ case 56:
19989
+ case 97:
19990
+ return "BNB";
19991
+ case 43114:
19992
+ case 43113:
19993
+ return "AVAX";
19994
+ default:
19995
+ return "ETH";
19996
+ }
19997
+ }
19998
+ function useUserBalances() {
19999
+ const { user, config } = useVolrContext();
20000
+ const { client } = useInternalAuth();
20001
+ const [brandingData, setBrandingData] = react.useState(null);
20002
+ const [balances, setBalances] = react.useState([]);
20003
+ const [isLoadingBranding, setIsLoadingBranding] = react.useState(true);
20004
+ const [error, setError] = react.useState(null);
20005
+ const getRpcUrl = react.useMemo(
20006
+ () => createGetRpcUrl({ client, rpcOverrides: config.rpcOverrides }),
20007
+ [client, config.rpcOverrides]
20008
+ );
20009
+ react.useEffect(() => {
20010
+ setIsLoadingBranding(true);
20011
+ setError(null);
20012
+ client.get("/auth/branding").then((response) => {
20013
+ setBrandingData(response);
20014
+ const initialBalances = response.depositAssets.map((asset) => {
20015
+ const isNative = asset.token === "native";
20016
+ const token = asset.token;
20017
+ const address = isNative ? "0x0000000000000000000000000000000000000000" : token.address;
20018
+ const id = `${asset.chainId}_${isNative ? "native" : address.toLowerCase()}`;
20019
+ return {
20020
+ id,
20021
+ chainId: asset.chainId,
20022
+ symbol: isNative ? getNativeSymbol(asset.chainId) : token.symbol,
20023
+ decimals: isNative ? 18 : token.decimals,
20024
+ address,
20025
+ iconUrl: isNative ? void 0 : token.iconUrl,
20026
+ isNative,
20027
+ balanceRaw: 0n,
20028
+ balance: "0",
20029
+ isLoading: true
20030
+ };
20031
+ });
20032
+ setBalances(initialBalances);
20033
+ }).catch((err) => {
20034
+ console.error("[useUserBalances] Failed to fetch branding:", err);
20035
+ setError(err instanceof Error ? err : new Error("Failed to fetch branding"));
20036
+ }).finally(() => {
20037
+ setIsLoadingBranding(false);
20038
+ });
20039
+ }, [client]);
20040
+ const fetchBalances = react.useCallback(async () => {
20041
+ if (!user?.evmAddress || !brandingData?.depositAssets.length) {
20042
+ return;
20043
+ }
20044
+ const userAddress = user.evmAddress;
20045
+ const balancePromises = brandingData.depositAssets.map(async (asset) => {
20046
+ const isNative = asset.token === "native";
20047
+ const token = asset.token;
20048
+ const address = isNative ? "0x0000000000000000000000000000000000000000" : token.address;
20049
+ const id = `${asset.chainId}_${isNative ? "native" : address.toLowerCase()}`;
20050
+ try {
20051
+ const rpcUrl = await getRpcUrl(asset.chainId);
20052
+ const publicClient = createPublicClient({
20053
+ transport: http(rpcUrl)
20054
+ });
20055
+ let balanceRaw;
20056
+ const decimals = isNative ? 18 : token.decimals;
20057
+ if (isNative) {
20058
+ balanceRaw = await publicClient.getBalance({ address: userAddress });
20059
+ } else {
20060
+ balanceRaw = await publicClient.readContract({
20061
+ address: token.address,
20062
+ abi: erc20Abi,
20063
+ functionName: "balanceOf",
20064
+ args: [userAddress]
20065
+ });
20066
+ }
20067
+ return {
20068
+ id,
20069
+ balanceRaw,
20070
+ balance: formatBalance(balanceRaw, decimals),
20071
+ isLoading: false,
20072
+ error: void 0
20073
+ };
20074
+ } catch (err) {
20075
+ console.error(`[useUserBalances] Failed to fetch balance for ${id}:`, err);
20076
+ return {
20077
+ id,
20078
+ balanceRaw: 0n,
20079
+ balance: "0",
20080
+ isLoading: false,
20081
+ error: "Failed to fetch balance"
20082
+ };
20083
+ }
20084
+ });
20085
+ const results = await Promise.all(balancePromises);
20086
+ setBalances(
20087
+ (prev) => prev.map((b) => {
20088
+ const result = results.find((r) => r.id === b.id);
20089
+ if (result) {
20090
+ return { ...b, ...result };
20091
+ }
20092
+ return b;
20093
+ })
20094
+ );
20095
+ }, [user?.evmAddress, brandingData?.depositAssets, getRpcUrl]);
20096
+ react.useEffect(() => {
20097
+ if (!isLoadingBranding && user?.evmAddress && brandingData) {
20098
+ fetchBalances();
20099
+ }
20100
+ }, [isLoadingBranding, user?.evmAddress, brandingData, fetchBalances]);
20101
+ const totalUsd = react.useMemo(() => {
20102
+ return balances.reduce((sum, b) => sum + (b.balanceUsd ?? 0), 0);
20103
+ }, [balances]);
20104
+ const isLoading = isLoadingBranding || balances.some((b) => b.isLoading);
20105
+ return {
20106
+ balances,
20107
+ totalUsd,
20108
+ isLoading,
20109
+ paymentEnabled: brandingData?.paymentEnabled ?? false,
20110
+ refresh: fetchBalances,
20111
+ error
20112
+ };
20113
+ }
20114
+ function isNativeToken(address) {
20115
+ const normalized = address.toLowerCase();
20116
+ return normalized === "native" || normalized === "0x0000000000000000000000000000000000000000" || normalized === "0x0";
20117
+ }
20118
+ function useWithdraw() {
20119
+ const { evm, isLoggedIn } = useVolr();
20120
+ const [isWithdrawing, setIsWithdrawing] = react.useState(false);
20121
+ const [result, setResult] = react.useState(null);
20122
+ const [error, setError] = react.useState(null);
20123
+ const withdraw = react.useCallback(
20124
+ async (params) => {
20125
+ if (!isLoggedIn) {
20126
+ throw new Error("User must be logged in to withdraw");
20127
+ }
20128
+ if (!evm.address) {
20129
+ throw new Error("Wallet address not available");
20130
+ }
20131
+ setIsWithdrawing(true);
20132
+ setError(null);
20133
+ setResult(null);
20134
+ try {
20135
+ const { chainId, tokenAddress, decimals, amount, to } = params;
20136
+ const client = evm.client(chainId);
20137
+ const amountRaw = parseUnits(amount, decimals);
20138
+ let txResult;
20139
+ if (isNativeToken(tokenAddress)) {
20140
+ txResult = await client.sendTransaction({
20141
+ to,
20142
+ data: "0x",
20143
+ value: amountRaw
20144
+ });
20145
+ } else {
20146
+ const data = encodeFunctionData({
20147
+ abi: erc20Abi,
20148
+ functionName: "transfer",
20149
+ args: [to, amountRaw]
20150
+ });
20151
+ txResult = await client.sendTransaction({
20152
+ to: tokenAddress,
20153
+ data
20154
+ });
20155
+ }
20156
+ setResult(txResult);
20157
+ return txResult;
20158
+ } catch (err) {
20159
+ const error2 = err instanceof Error ? err : new Error("Withdrawal failed");
20160
+ setError(error2);
20161
+ throw error2;
20162
+ } finally {
20163
+ setIsWithdrawing(false);
20164
+ }
20165
+ },
20166
+ [evm, isLoggedIn]
20167
+ );
20168
+ const reset = react.useCallback(() => {
20169
+ setIsWithdrawing(false);
20170
+ setResult(null);
20171
+ setError(null);
20172
+ }, []);
20173
+ return {
20174
+ withdraw,
20175
+ isWithdrawing,
20176
+ result,
20177
+ error,
20178
+ reset
20179
+ };
20180
+ }
19737
20181
 
19738
20182
  // src/utils/contract-analysis.ts
19739
20183
  var EIP7702_PREFIX = "0xef0100";
@@ -20331,6 +20775,101 @@ async function getUserCredentials(client) {
20331
20775
  const response = await client.get("/wallet/credentials");
20332
20776
  return response.credentials;
20333
20777
  }
20778
+ function useEIP6963() {
20779
+ const [providers, setProviders] = react.useState([]);
20780
+ const [hasLegacyProvider, setHasLegacyProvider] = react.useState(false);
20781
+ const [isDetecting, setIsDetecting] = react.useState(true);
20782
+ react.useEffect(() => {
20783
+ if (typeof window === "undefined") {
20784
+ setIsDetecting(false);
20785
+ return;
20786
+ }
20787
+ const handleAnnounceProvider = (event) => {
20788
+ const { detail } = event;
20789
+ setProviders((prev) => {
20790
+ if (prev.some((p) => p.info.uuid === detail.info.uuid)) {
20791
+ return prev;
20792
+ }
20793
+ return [...prev, detail];
20794
+ });
20795
+ };
20796
+ window.addEventListener("eip6963:announceProvider", handleAnnounceProvider);
20797
+ window.dispatchEvent(new Event("eip6963:requestProvider"));
20798
+ const hasLegacy = !!window.ethereum;
20799
+ setHasLegacyProvider(hasLegacy);
20800
+ const timeout = setTimeout(() => {
20801
+ setIsDetecting(false);
20802
+ }, 200);
20803
+ return () => {
20804
+ window.removeEventListener(
20805
+ "eip6963:announceProvider",
20806
+ handleAnnounceProvider
20807
+ );
20808
+ clearTimeout(timeout);
20809
+ };
20810
+ }, []);
20811
+ const getProvider = react.useCallback(() => {
20812
+ if (providers.length > 0) {
20813
+ return { provider: providers[0].provider, info: providers[0].info };
20814
+ }
20815
+ if (hasLegacyProvider && window.ethereum) {
20816
+ return { provider: window.ethereum, info: null };
20817
+ }
20818
+ return { provider: null, info: null };
20819
+ }, [providers, hasLegacyProvider]);
20820
+ const getWalletsForDisplay = react.useCallback(() => {
20821
+ const walletsToShow = [];
20822
+ providers.forEach((p) => {
20823
+ walletsToShow.push({
20824
+ id: p.info.uuid,
20825
+ name: p.info.name,
20826
+ icon: p.info.icon,
20827
+ provider: p.provider,
20828
+ rdns: p.info.rdns
20829
+ });
20830
+ });
20831
+ if (hasLegacyProvider && providers.length === 0) {
20832
+ const ethereum = window.ethereum;
20833
+ let name = "Wallet";
20834
+ if (ethereum?.isMetaMask) name = "MetaMask";
20835
+ else if (ethereum?.isCoinbaseWallet) name = "Coinbase Wallet";
20836
+ else if (ethereum?.isRabby) name = "Rabby";
20837
+ else if (ethereum?.isBraveWallet) name = "Brave Wallet";
20838
+ walletsToShow.push({
20839
+ id: "legacy",
20840
+ name,
20841
+ provider: ethereum,
20842
+ isLegacy: true
20843
+ });
20844
+ }
20845
+ return walletsToShow;
20846
+ }, [providers, hasLegacyProvider]);
20847
+ const { provider, info } = getProvider();
20848
+ const hasWallet = provider !== null;
20849
+ return {
20850
+ provider,
20851
+ providerInfo: info,
20852
+ hasWallet,
20853
+ isDetecting,
20854
+ allProviders: providers,
20855
+ hasLegacyProvider,
20856
+ getWalletsForDisplay
20857
+ };
20858
+ }
20859
+ function detectWalletConnector(provider, providerInfo) {
20860
+ if (providerInfo?.rdns) {
20861
+ return providerInfo.rdns;
20862
+ }
20863
+ if (!provider) return "unknown";
20864
+ if (provider.isMetaMask) return "io.metamask";
20865
+ if (provider.isCoinbaseWallet) return "com.coinbase.wallet";
20866
+ if (provider.isRabby) return "io.rabby";
20867
+ if (provider.isZerion) return "io.zerion";
20868
+ if (provider.isBraveWallet) return "com.brave.wallet";
20869
+ if (provider.isTrust) return "com.trustwallet";
20870
+ if (provider.isPhantom) return "app.phantom";
20871
+ return "unknown";
20872
+ }
20334
20873
  /*! Bundled license information:
20335
20874
 
20336
20875
  @noble/hashes/esm/utils.js:
@@ -20391,6 +20930,7 @@ exports.createGetNetworkInfo = createGetNetworkInfo;
20391
20930
  exports.createPasskeyAdapter = createPasskeyAdapter;
20392
20931
  exports.debugTransactionFailure = debugTransactionFailure;
20393
20932
  exports.defaultIdempotencyKey = defaultIdempotencyKey;
20933
+ exports.detectWalletConnector = detectWalletConnector;
20394
20934
  exports.diagnoseTransactionFailure = diagnoseTransactionFailure;
20395
20935
  exports.getERC20Balance = getERC20Balance;
20396
20936
  exports.getPasskeyAuthGuidance = getPasskeyAuthGuidance;
@@ -20407,13 +20947,16 @@ exports.requestSeedFromOpener = requestSeedFromOpener;
20407
20947
  exports.sendSeedToPopup = sendSeedToPopup;
20408
20948
  exports.uploadBlobViaPresign = uploadBlobViaPresign;
20409
20949
  exports.useDepositListener = useDepositListener;
20950
+ exports.useEIP6963 = useEIP6963;
20410
20951
  exports.useInternalAuth = useInternalAuth;
20411
20952
  exports.useMpcConnection = useMpcConnection;
20412
20953
  exports.usePasskeyEnrollment = usePasskeyEnrollment;
20954
+ exports.useUserBalances = useUserBalances;
20413
20955
  exports.useVolr = useVolr;
20414
20956
  exports.useVolrAuthCallback = useVolrAuthCallback;
20415
20957
  exports.useVolrContext = useVolrContext;
20416
20958
  exports.useVolrLogin = useVolrLogin;
20417
20959
  exports.useVolrPaymentApi = useVolrPaymentApi;
20960
+ exports.useWithdraw = useWithdraw;
20418
20961
  //# sourceMappingURL=index.cjs.map
20419
20962
  //# sourceMappingURL=index.cjs.map