@volr/react 0.1.99 → 0.1.101

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/README.md CHANGED
@@ -29,28 +29,34 @@ function App() {
29
29
  }
30
30
 
31
31
  function YourApp() {
32
- const { evm, evmAddress, isLoggedIn, logout } = useVolr();
32
+ const { evm, isLoggedIn, logout } = useVolr();
33
33
 
34
34
  if (!isLoggedIn) {
35
35
  return <div>Please login</div>;
36
36
  }
37
37
 
38
- // Read contract
39
- const balance = await evm(8453).readContract({
38
+ // Get wallet address
39
+ const address = evm.address;
40
+
41
+ // Sign a message (chain-agnostic)
42
+ const signature = await evm.signMessage('Hello, World!');
43
+
44
+ // Read contract (chain-specific)
45
+ const balance = await evm.client(8453).readContract({
40
46
  address: '0x...',
41
47
  abi: erc20Abi,
42
48
  functionName: 'balanceOf',
43
- args: [evmAddress],
49
+ args: [address],
44
50
  });
45
51
 
46
- // Send transaction
47
- const result = await evm(8453).sendTransaction({
52
+ // Send transaction (chain-specific)
53
+ const result = await evm.client(8453).sendTransaction({
48
54
  to: '0x...',
49
55
  data: '0x...',
50
56
  });
51
57
 
52
- // Send batch
53
- const result = await evm(8453).sendBatch([
58
+ // Send batch (chain-specific)
59
+ const result = await evm.client(8453).sendBatch([
54
60
  {
55
61
  target: '0x...',
56
62
  abi: erc20Abi,
@@ -69,8 +75,8 @@ Main hook for wallet operations.
69
75
 
70
76
  ```tsx
71
77
  const {
72
- evm, // (chainId: number) => EvmClient
73
- evmAddress, // `0x${string}` | undefined
78
+ evm, // EvmNamespace (see below)
79
+ evmAddress, // `0x${string}` | undefined (deprecated, use evm.address)
74
80
  email, // string | undefined
75
81
  isLoggedIn, // boolean
76
82
  signerType, // 'passkey' | 'external_wallet' | 'mpc' | undefined
@@ -80,12 +86,26 @@ const {
80
86
  } = useVolr();
81
87
  ```
82
88
 
83
- ### EvmClient
89
+ ### EvmNamespace
84
90
 
85
- Returned by `evm(chainId)`.
91
+ The `evm` object provides chain-agnostic operations and a `client()` method for chain-specific operations.
86
92
 
87
93
  ```tsx
88
- const client = evm(8453);
94
+ // Chain-agnostic operations
95
+ evm.address // `0x${string}` | undefined
96
+ await evm.signMessage('Hello') // Sign message (EIP-191)
97
+ await evm.signTypedData({...}) // Sign typed data (EIP-712)
98
+
99
+ // Chain-specific operations
100
+ const client = evm.client(8453);
101
+ ```
102
+
103
+ ### EvmChainClient
104
+
105
+ Returned by `evm.client(chainId)` for chain-specific operations.
106
+
107
+ ```tsx
108
+ const client = evm.client(8453);
89
109
 
90
110
  // Read contract
91
111
  const balance = await client.readContract({
@@ -95,6 +115,9 @@ const balance = await client.readContract({
95
115
  args: [userAddress],
96
116
  });
97
117
 
118
+ // Get balance
119
+ const ethBalance = await client.getBalance('0x...');
120
+
98
121
  // Send single transaction
99
122
  const result = await client.sendTransaction({
100
123
  to: '0x...',
@@ -124,6 +147,32 @@ const result = await client.sendBatch([
124
147
  ]);
125
148
  ```
126
149
 
150
+ ### Message Signing
151
+
152
+ Sign messages and typed data without specifying a chain (uses the same private key).
153
+
154
+ ```tsx
155
+ // Sign a simple message
156
+ const signature = await evm.signMessage('Hello, World!');
157
+
158
+ // Sign raw bytes
159
+ const signature = await evm.signMessage(new Uint8Array([1, 2, 3]));
160
+
161
+ // Sign EIP-712 typed data
162
+ const signature = await evm.signTypedData({
163
+ domain: {
164
+ name: 'MyApp',
165
+ version: '1',
166
+ chainId: 1,
167
+ verifyingContract: '0x...',
168
+ },
169
+ types: {
170
+ Message: [{ name: 'content', type: 'string' }],
171
+ },
172
+ message: { content: 'Hello' },
173
+ });
174
+ ```
175
+
127
176
  ## Features
128
177
 
129
178
  - **Simple API**: `useVolr()` provides everything you need
package/dist/index.cjs CHANGED
@@ -18532,12 +18532,54 @@ function useVolr() {
18532
18532
  const { user, config, provider, setProvider, logout, isLoading, error } = useVolrContext();
18533
18533
  const { precheck } = usePrecheck();
18534
18534
  const { relay } = useRelay();
18535
- const { client } = useInternalAuth();
18535
+ const { client: apiClient } = useInternalAuth();
18536
18536
  const getRpcUrl = react.useCallback(
18537
- createGetRpcUrl({ client, rpcOverrides: config.rpcOverrides }),
18538
- [client, config.rpcOverrides]
18537
+ createGetRpcUrl({ client: apiClient, rpcOverrides: config.rpcOverrides }),
18538
+ [apiClient, config.rpcOverrides]
18539
+ );
18540
+ const signMessage = react.useCallback(
18541
+ async (message) => {
18542
+ if (!provider) {
18543
+ throw new Error(
18544
+ "No wallet provider available. Please log in with a Passkey or MPC wallet to sign messages."
18545
+ );
18546
+ }
18547
+ if (config.onSignRequest) {
18548
+ await config.onSignRequest({ type: "message", message });
18549
+ }
18550
+ await provider.ensureSession({ interactive: true });
18551
+ const messageHash = hashMessage(
18552
+ typeof message === "string" ? message : { raw: message }
18553
+ );
18554
+ const hashBytes = new Uint8Array(32);
18555
+ const hex = messageHash.slice(2);
18556
+ for (let i = 0; i < 32; i++) {
18557
+ hashBytes[i] = parseInt(hex.slice(i * 2, i * 2 + 2), 16);
18558
+ }
18559
+ const sig = await provider.signMessage(hashBytes);
18560
+ const v = sig.yParity + 27;
18561
+ const rHex = Array.from(sig.r).map((b) => b.toString(16).padStart(2, "0")).join("");
18562
+ const sHex = Array.from(sig.s).map((b) => b.toString(16).padStart(2, "0")).join("");
18563
+ const vHex = v.toString(16).padStart(2, "0");
18564
+ return `0x${rHex}${sHex}${vHex}`;
18565
+ },
18566
+ [provider, config.onSignRequest]
18567
+ );
18568
+ const signTypedData = react.useCallback(
18569
+ async (typedData) => {
18570
+ if (!provider) {
18571
+ throw new Error(
18572
+ "No wallet provider available. Please log in with a Passkey or MPC wallet to sign typed data."
18573
+ );
18574
+ }
18575
+ if (config.onSignRequest) {
18576
+ await config.onSignRequest({ type: "typedData", typedData });
18577
+ }
18578
+ return provider.signTypedData(typedData);
18579
+ },
18580
+ [provider, config.onSignRequest]
18539
18581
  );
18540
- const evm = react.useCallback(
18582
+ const createChainClient = react.useCallback(
18541
18583
  (chainId) => {
18542
18584
  if (chainId === 0) {
18543
18585
  throw new Error("chainId cannot be 0");
@@ -18556,12 +18598,12 @@ function useVolr() {
18556
18598
  };
18557
18599
  return {
18558
18600
  getBalance: async (address) => {
18559
- const { publicClient: client2 } = await ensureRpcClient();
18560
- return client2.getBalance({ address });
18601
+ const { publicClient: client } = await ensureRpcClient();
18602
+ return client.getBalance({ address });
18561
18603
  },
18562
18604
  readContract: async (args) => {
18563
- const { publicClient: client2 } = await ensureRpcClient();
18564
- return client2.readContract(args);
18605
+ const { publicClient: client } = await ensureRpcClient();
18606
+ return client.readContract(args);
18565
18607
  },
18566
18608
  sendTransaction: async (tx, opts = {}) => {
18567
18609
  const { publicClient: publicClient2, extendedRpcClient: rpcClient } = await ensureRpcClient();
@@ -18587,7 +18629,7 @@ function useVolr() {
18587
18629
  rpcClient,
18588
18630
  precheck,
18589
18631
  relay,
18590
- client,
18632
+ client: apiClient,
18591
18633
  user: user ?? null,
18592
18634
  provider: provider ?? null,
18593
18635
  setProvider
@@ -18621,50 +18663,30 @@ function useVolr() {
18621
18663
  rpcClient,
18622
18664
  precheck,
18623
18665
  relay,
18624
- client,
18666
+ client: apiClient,
18625
18667
  user: user ?? null,
18626
18668
  provider: provider ?? null,
18627
18669
  setProvider
18628
18670
  }
18629
18671
  });
18630
- }),
18631
- signMessage: async (message) => {
18632
- if (!provider) {
18633
- throw new Error(
18634
- "No wallet provider available. Please log in with a Passkey or MPC wallet to sign messages."
18635
- );
18636
- }
18637
- await provider.ensureSession({ interactive: true });
18638
- const messageHash = hashMessage(
18639
- typeof message === "string" ? message : { raw: message }
18640
- );
18641
- const hashBytes = new Uint8Array(32);
18642
- const hex = messageHash.slice(2);
18643
- for (let i = 0; i < 32; i++) {
18644
- hashBytes[i] = parseInt(hex.slice(i * 2, i * 2 + 2), 16);
18645
- }
18646
- const sig = await provider.signMessage(hashBytes);
18647
- const v = sig.yParity + 27;
18648
- const rHex = Array.from(sig.r).map((b) => b.toString(16).padStart(2, "0")).join("");
18649
- const sHex = Array.from(sig.s).map((b) => b.toString(16).padStart(2, "0")).join("");
18650
- const vHex = v.toString(16).padStart(2, "0");
18651
- return `0x${rHex}${sHex}${vHex}`;
18652
- },
18653
- signTypedData: async (typedData) => {
18654
- if (!provider) {
18655
- throw new Error(
18656
- "No wallet provider available. Please log in with a Passkey or MPC wallet to sign typed data."
18657
- );
18658
- }
18659
- return provider.signTypedData(typedData);
18660
- }
18672
+ })
18661
18673
  };
18662
18674
  },
18663
- [user, config, provider, precheck, relay, getRpcUrl, setProvider, client]
18675
+ [user, provider, precheck, relay, getRpcUrl, setProvider, apiClient]
18676
+ );
18677
+ const evm = react.useMemo(
18678
+ () => ({
18679
+ address: user?.evmAddress,
18680
+ signMessage,
18681
+ signTypedData,
18682
+ client: createChainClient
18683
+ }),
18684
+ [user?.evmAddress, signMessage, signTypedData, createChainClient]
18664
18685
  );
18665
18686
  return {
18666
18687
  evm,
18667
18688
  evmAddress: user?.evmAddress,
18689
+ // deprecated, kept for backward compatibility
18668
18690
  email: user?.email,
18669
18691
  isLoggedIn: user !== null,
18670
18692
  signerType: user?.signerType,
@@ -18688,19 +18710,6 @@ function toChecksumAddress(address) {
18688
18710
  }
18689
18711
  return checksummed;
18690
18712
  }
18691
- function detectWalletConnector() {
18692
- if (typeof window === "undefined" || !window.ethereum) {
18693
- return void 0;
18694
- }
18695
- const provider = window.ethereum;
18696
- if (provider.info?.rdns) return provider.info.rdns;
18697
- if (provider.isMetaMask) return "io.metamask";
18698
- if (provider.isCoinbaseWallet) return "com.coinbase.wallet";
18699
- if (provider.isRabby) return "io.rabby";
18700
- if (provider.isZerion) return "io.zerion";
18701
- if (provider.isBraveWallet) return "com.brave.wallet";
18702
- return "unknown";
18703
- }
18704
18713
  function useVolrLogin() {
18705
18714
  const { config, setUser } = useVolrContext();
18706
18715
  const { setAccessToken, setRefreshToken, client } = useInternalAuth();
@@ -18710,9 +18719,8 @@ function useVolrLogin() {
18710
18719
  projectId: u.projectId,
18711
18720
  projectName: u.projectName,
18712
18721
  email: u.email,
18713
- accountId: u.accountId ?? void 0,
18722
+ authWallet: u.authWallet ?? void 0,
18714
18723
  evmAddress: u.evmAddress,
18715
- authWalletAddress: u.authWalletAddress ?? void 0,
18716
18724
  keyStorageType: u.keyStorageType ?? void 0,
18717
18725
  signerType: u.signerType ?? void 0,
18718
18726
  walletConnector: u.walletConnector ?? void 0,
@@ -18834,11 +18842,11 @@ function useVolrLogin() {
18834
18842
  [client, setAccessToken, setRefreshToken, setUser, toVolrUser]
18835
18843
  );
18836
18844
  const signWithWallet = react.useCallback(
18837
- async (walletAddress) => {
18838
- if (typeof window === "undefined" || !window.ethereum) {
18845
+ async (walletAddress, options) => {
18846
+ const ethereum = options?.provider ?? (typeof window !== "undefined" ? window.ethereum : null);
18847
+ if (!ethereum) {
18839
18848
  throw new Error("No Ethereum wallet found. Please install MetaMask or another wallet.");
18840
18849
  }
18841
- const ethereum = window.ethereum;
18842
18850
  const chainIdHex = await ethereum.request({ method: "eth_chainId" });
18843
18851
  const chainId = parseInt(chainIdHex, 16);
18844
18852
  const nonce = await requestSiweNonce();
@@ -18861,7 +18869,7 @@ Issued At: ${issuedAt}`;
18861
18869
  method: "personal_sign",
18862
18870
  params: [message, walletAddress]
18863
18871
  });
18864
- const walletConnector = detectWalletConnector();
18872
+ const walletConnector = options?.walletConnector ?? ethereum.info?.rdns ?? "unknown";
18865
18873
  return verifySiweSignature(message, signature, { walletConnector, chainId });
18866
18874
  },
18867
18875
  [requestSiweNonce, verifySiweSignature]
@@ -18928,7 +18936,7 @@ function useVolrAuthCallback(options = {}) {
18928
18936
  projectId: u.projectId,
18929
18937
  projectName: u.projectName,
18930
18938
  email: u.email,
18931
- accountId: u.accountId ?? void 0,
18939
+ authWallet: u.authWallet ?? void 0,
18932
18940
  evmAddress: u.evmAddress,
18933
18941
  keyStorageType: u.keyStorageType ?? void 0,
18934
18942
  signerType: u.signerType ?? void 0,