@cookill/wallet-adapter 3.2.1 → 3.2.2

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
@@ -1,61 +1,41 @@
1
- # @cookill/wallet-adapter
1
+ # @cookill/wallet-adapter v3.2.1
2
2
 
3
- Wallet adapter for **Sheep Wallet** the browser extension wallet for the Rialo blockchain.
3
+ Official wallet adapter for **Sheep Wallet** on Rialo blockchain.
4
+
5
+ ## 🚀 What's New in v3.2.1
6
+
7
+ - **Anti-freeze connect flow**: connect path remains timeout-protected
8
+ - **Luxury Minimal WalletModal**: rebranded Sheep Wallet modal with clearer connect state
9
+ - **ConnectButton behavior fix**: disconnected click now opens modal consistently
10
+ - **Safer developer guidance**: docs clarified to avoid misleading integration assumptions
4
11
 
5
12
  ## Installation
6
13
 
7
14
  ```bash
8
15
  npm install @cookill/wallet-adapter
16
+ # or
17
+ pnpm add @cookill/wallet-adapter
18
+ # or
19
+ yarn add @cookill/wallet-adapter
9
20
  ```
10
21
 
11
22
  ## Quick Start (React)
12
23
 
13
24
  ```tsx
14
- import { WalletProvider, ConnectButton } from '@cookill/wallet-adapter/react';
25
+ import { WalletProvider, ConnectButton, WalletErrorBoundary } from '@cookill/wallet-adapter/react';
15
26
 
16
27
  function App() {
17
28
  return (
18
- <WalletProvider network="devnet" autoConnect>
19
- <ConnectButton />
20
- <YourDApp />
21
- </WalletProvider>
29
+ <WalletErrorBoundary>
30
+ <WalletProvider network="devnet" autoConnect>
31
+ <ConnectButton />
32
+ <YourDApp />
33
+ </WalletProvider>
34
+ </WalletErrorBoundary>
22
35
  );
23
36
  }
24
37
  ```
25
38
 
26
- `WalletProvider` renders a built-in connect modal automatically. On desktop it opens as a centered dialog; on mobile it slides up as a bottom sheet with swipe-to-dismiss.
27
-
28
- ## Built-in Modal
29
-
30
- The built-in modal is rendered inside `WalletProvider` and includes:
31
-
32
- - **Extension tab** — detects Sheep Wallet, shows install link if not found, triggers `window.rialo.connect()` on click
33
- - **Scan to Connect tab** — generates a `rialo-wc://` QR code for cross-device pairing
34
- - **Responsive layout** — centered dialog on desktop, slide-up sheet on mobile
35
- - **Auto-close** — closes automatically after successful connection
36
-
37
- Control it programmatically:
38
-
39
- ```tsx
40
- const { openModal, closeModal } = useWallet();
41
-
42
- // Open the built-in modal
43
- openModal();
44
- ```
45
-
46
- Or use `ConnectButton` which handles everything:
47
-
48
- ```tsx
49
- <ConnectButton
50
- connectLabel="Connect Wallet"
51
- disconnectLabel="Disconnect"
52
- showAddress={true}
53
- showBalance={false}
54
- />
55
- ```
56
-
57
- > When the extension is installed, `ConnectButton` calls `connect()` directly without opening the modal. When not installed, it opens the modal with a download link.
58
-
59
39
  ## React Hooks
60
40
 
61
41
  ### useWallet
@@ -63,206 +43,272 @@ Or use `ConnectButton` which handles everything:
63
43
  ```tsx
64
44
  import { useWallet } from '@cookill/wallet-adapter/react';
65
45
 
66
- const {
67
- connected, // boolean
68
- connecting, // boolean
69
- activeAccount, // WalletAccount | null
70
- chainId, // string — e.g. "rialo:devnet"
71
- isInstalled, // boolean extension detected
72
-
73
- // Actions
74
- connect, // () => Promise<WalletAccount[]>
75
- disconnect, // () => Promise<void>
76
- switchNetwork, // (network) => Promise<void>
77
- refreshBalance, // () => Promise<void>
78
-
79
- // Signing & Transactions
80
- signMessage, // (msg: string) => Promise<SignedMessage>
81
- signTransaction, // (tx) => Promise<string>
82
- sendTransaction, // (tx) => Promise<TransactionResult>
83
- signAndSendTransaction, // (tx) => Promise<TransactionResult>
84
-
85
- // Modal control
86
- openModal, // () => void
87
- closeModal, // () => void
88
- } = useWallet();
46
+ function MyComponent() {
47
+ const {
48
+ // State
49
+ connected, // boolean
50
+ connecting, // boolean
51
+ activeAccount, // WalletAccount | null
52
+ state, // Full state object
53
+ chainId, // 'rialo:devnet' etc
54
+ isInstalled, // boolean
55
+
56
+ // Actions
57
+ connect, // () => Promise<WalletAccount[]>
58
+ disconnect, // () => Promise<void>
59
+ switchNetwork, // (network) => Promise<void>
60
+ refreshBalance, // () => Promise<void>
61
+
62
+ // Transactions
63
+ signMessage, // (message: string) => Promise<SignedMessage>
64
+ signTransaction, // (tx) => Promise<string>
65
+ sendTransaction, // (tx) => Promise<TransactionResult>
66
+ signAndSendTransaction, // (tx) => Promise<TransactionResult>
67
+
68
+ // Modal
69
+ openModal,
70
+ closeModal,
71
+ } = useWallet();
72
+
73
+ return (
74
+ <div>
75
+ {connected ? (
76
+ <p>Connected: {activeAccount?.address}</p>
77
+ ) : (
78
+ <button onClick={connect}>Connect</button>
79
+ )}
80
+ </div>
81
+ );
82
+ }
89
83
  ```
90
84
 
91
- ### Focused Hooks
85
+ ### Specialized Hooks
92
86
 
93
87
  ```tsx
88
+ // Connection
94
89
  const { connect, connecting, isInstalled, error } = useConnectWallet();
95
90
  const { disconnect, connected } = useDisconnectWallet();
96
91
  const connected = useIsConnected();
92
+
93
+ // Account
97
94
  const account = useActiveAccount();
98
95
  const accounts = useAccounts();
99
- const { balance, refresh } = useBalance();
100
- const { network, chainId } = useNetwork();
101
- const { switchNetwork } = useSwitchNetwork();
102
- const { sendTransaction, signAndSendTransaction, sendGaslessTransaction } = useSendTransaction();
103
- const { signMessage } = useSignMessage();
104
- ```
105
96
 
106
- ### REX (Confidential Transactions)
107
-
108
- ```tsx
109
- const { capabilities, supported, submitREXTransaction } = useREX();
110
- ```
97
+ // Balance
98
+ const { balance, refresh } = useBalance();
111
99
 
112
- ### SfS (Stake-for-Service / Gasless)
100
+ // Network
101
+ const { network, chainId } = useNetwork();
102
+ const { switchNetwork, network } = useSwitchNetwork();
113
103
 
114
- ```tsx
115
- const { positions, credits, hasCredits, createPosition, sendGasless, refresh } = useSfS();
104
+ // Transactions
105
+ const { signMessage, connected } = useSignMessage();
106
+ const { sendTransaction, signAndSendTransaction, connected } = useSendTransaction();
116
107
  ```
117
108
 
118
- ### Scan-to-Connect
109
+ ## Vanilla JavaScript
119
110
 
120
- ```tsx
121
- const { scanURI, status, generateQR, approveSession, rejectSession } = useScanConnect();
122
- ```
111
+ ```typescript
112
+ import { SheepWallet, isInstalled, formatBalance } from '@cookill/wallet-adapter';
123
113
 
124
- ## Custom Modal (Optional)
114
+ // Check if installed
115
+ if (!isInstalled()) {
116
+ console.log('Please install Sheep Wallet');
117
+ }
125
118
 
126
- If you need full control over the UI, build your own modal using the hooks:
119
+ // Create wallet instance
120
+ const wallet = new SheepWallet();
127
121
 
128
- ```tsx
129
- import { useConnectWallet, useScanConnect, isInstalled } from '@cookill/wallet-adapter/react';
122
+ // Connect (with built-in timeout)
123
+ try {
124
+ const accounts = await wallet.connect();
125
+ console.log('Connected:', accounts[0].address);
126
+ } catch (error) {
127
+ console.error('Connection failed:', error.message);
128
+ }
130
129
 
131
- function MyConnectModal({ open, onClose }) {
132
- const { connect, connecting, error } = useConnectWallet();
133
- const { scanURI, status, generateQR } = useScanConnect();
130
+ // Get balance
131
+ const balance = await wallet.getBalance();
132
+ console.log('Balance:', formatBalance(balance), 'RLO');
134
133
 
135
- const handleConnect = async () => {
136
- try {
137
- const accounts = await connect();
138
- console.log('Connected:', accounts[0].address);
139
- onClose();
140
- } catch (err) {
141
- console.error('Connection failed:', err);
142
- }
143
- };
134
+ // Sign message
135
+ const signed = await wallet.signMessage('Hello!');
144
136
 
145
- if (!open) return null;
137
+ // Send transaction
138
+ const tx = await wallet.signAndSendTransaction({
139
+ to: 'RecipientAddress...',
140
+ value: '1000000000', // 1 RLO in kelvins
141
+ });
142
+ console.log('TX Hash:', tx.hash);
146
143
 
147
- return (
148
- <div className="modal-overlay" onClick={onClose}>
149
- <div className="modal-content" onClick={e => e.stopPropagation()}>
150
- <h2>Connect Wallet</h2>
151
-
152
- {isInstalled() ? (
153
- <button onClick={handleConnect} disabled={connecting}>
154
- {connecting ? 'Approve in extension...' : 'Connect Sheep Wallet'}
155
- </button>
156
- ) : (
157
- <a href="https://rialo.io/wallet" target="_blank">Install Sheep Wallet</a>
158
- )}
159
-
160
- {error && <p className="error">{error.message}</p>}
161
- </div>
162
- </div>
163
- );
144
+ // Silent session check (for auto-connect, never triggers approval)
145
+ const existingSession = await wallet.checkSession();
146
+ if (existingSession) {
147
+ console.log('Session restored:', existingSession[0].address);
164
148
  }
165
149
  ```
166
150
 
167
- Key points:
168
- - `connect()` calls `window.rialo.connect()` which triggers the extension's approval popup
169
- - The `connect()` call has a 20-second timeout to prevent dApp freezes
170
- - Use `isInstalled()` to check if the extension is present before connecting
171
-
172
- ## Vanilla JavaScript
151
+ ## Direct Provider Access
173
152
 
174
153
  ```typescript
175
- import { SheepWallet, isInstalled, formatBalance } from '@cookill/wallet-adapter';
154
+ // Access window.rialo directly
155
+ if (window.rialo) {
156
+ const accounts = await window.rialo.connect();
157
+ const balance = await window.rialo.getBalance();
158
+ const tx = await window.rialo.signAndSendTransaction({
159
+ to: 'RecipientAddress...',
160
+ value: '1000000000',
161
+ });
162
+ }
163
+ ```
176
164
 
177
- const wallet = new SheepWallet();
165
+ ## Components
178
166
 
179
- if (!wallet.isInstalled) {
180
- console.log('Extension not found');
181
- }
167
+ ### ConnectButton
182
168
 
183
- const accounts = await wallet.connect();
184
- const balance = await wallet.getBalance();
185
- console.log('Balance:', formatBalance(balance));
169
+ ```tsx
170
+ <ConnectButton
171
+ connectLabel="Connect Wallet"
172
+ disconnectLabel="Disconnect"
173
+ showAddress={true}
174
+ showBalance={false}
175
+ className="my-button"
176
+ style={{ backgroundColor: '#6EB9A8' }}
177
+ />
178
+ ```
186
179
 
187
- await wallet.signAndSendTransaction({
188
- to: 'RecipientAddress',
189
- value: '1000000000', // 1 RLO in kelvins
190
- });
180
+ ### WalletProvider
191
181
 
192
- await wallet.disconnect();
182
+ ```tsx
183
+ <WalletProvider
184
+ network="devnet" // 'mainnet' | 'testnet' | 'devnet' | 'localnet'
185
+ autoConnect={true} // Restore session silently on mount
186
+ wallets={[customWallet]} // Additional wallets to show
187
+ onConnect={(accounts) => console.log('Connected', accounts)}
188
+ onDisconnect={() => console.log('Disconnected')}
189
+ onNetworkChange={(network) => console.log('Network:', network)}
190
+ onError={(error) => console.error(error)}
191
+ >
192
+ {children}
193
+ </WalletProvider>
193
194
  ```
194
195
 
195
- ## WalletProvider Props
196
+ ### Error Boundary & Loading States
197
+
198
+ ```tsx
199
+ import {
200
+ WalletErrorBoundary,
201
+ ApprovalPending,
202
+ LoadingSpinner,
203
+ ConnectionStatus,
204
+ } from '@cookill/wallet-adapter/react';
205
+
206
+ // Error Boundary
207
+ <WalletErrorBoundary
208
+ fallback={<CustomError />}
209
+ onError={(error, info) => logError(error)}
210
+ >
211
+ <WalletProvider>...</WalletProvider>
212
+ </WalletErrorBoundary>
213
+
214
+ // Loading states
215
+ <ApprovalPending
216
+ title="Waiting for Approval"
217
+ message="Please approve in Sheep Wallet"
218
+ walletName="Sheep Wallet"
219
+ onCancel={() => disconnect()}
220
+ />
221
+
222
+ <LoadingSpinner size="md" color="#6EB9A8" />
196
223
 
197
- | Prop | Type | Default | Description |
198
- |------|------|---------|-------------|
199
- | `network` | `RialoNetwork` | `'devnet'` | Default network |
200
- | `autoConnect` | `boolean` | `true` | Silently restore previous session on load |
201
- | `scanConnectRelay` | `string` | `'wss://relay.rialo.io'` | Relay URL for scan-to-connect |
202
- | `onConnect` | `(accounts) => void` | — | Called after successful connection |
203
- | `onDisconnect` | `() => void` | — | Called after disconnect |
204
- | `onError` | `(error) => void` | — | Called on connection errors |
205
- | `onNetworkChange` | `(network) => void` | — | Called when network changes |
224
+ <ConnectionStatus status="connecting" />
225
+ <ConnectionStatus status="approving" message="Check your wallet" />
226
+ <ConnectionStatus status="error" onRetry={() => connect()} />
227
+ ```
206
228
 
207
229
  ## Networks
208
230
 
209
- | Network | Chain ID | RPC URL | Symbol |
210
- |----------|-----------------|--------------------------------|--------|
211
- | Mainnet | rialo:mainnet | https://mainnet.rialo.io:4101 | RLO |
212
- | Testnet | rialo:testnet | https://testnet.rialo.io:4101 | tRLO |
213
- | Devnet | rialo:devnet | https://devnet.rialo.io:4101 | dRLO |
231
+ | Network | Chain ID | RPC URL | Symbol |
232
+ |----------|-----------------|----------------------------------|--------|
233
+ | Mainnet | rialo:mainnet | https://mainnet.rialo.io:4101 | RLO |
234
+ | Testnet | rialo:testnet | https://testnet.rialo.io:4101 | tRLO |
235
+ | Devnet | rialo:devnet | https://devnet.rialo.io:4101 | dRLO |
214
236
  | Localnet | rialo:localnet | http://localhost:4101 | lRLO |
215
237
 
216
- ## Key Types
238
+ ## Utilities
217
239
 
218
240
  ```typescript
219
- interface WalletAccount {
220
- address: string;
221
- publicKey: string;
222
- }
241
+ import {
242
+ formatAddress, // (address, chars?) => "5YNm...VWr8"
243
+ formatBalance, // (kelvins, decimals?) => "1.0000"
244
+ parseBalance, // (rlo) => bigint (kelvins)
245
+ isValidAddress, // (address) => boolean
246
+ toChainId, // (network) => 'rialo:devnet'
247
+ fromChainId, // (chainId) => 'devnet'
248
+ isInstalled, // () => boolean
249
+ getProvider, // () => RialoProvider | undefined
250
+ waitForProvider, // (timeout?) => Promise<RialoProvider | undefined>
251
+ NETWORKS, // Network configurations
252
+ } from '@cookill/wallet-adapter';
253
+ ```
223
254
 
224
- interface TransactionRequest {
225
- to: string;
226
- value: string; // amount in kelvins (1 RLO = 1_000_000_000 kelvins)
227
- data?: string;
228
- memo?: string;
229
- gasless?: boolean; // set by sendGaslessTransaction
230
- }
255
+ ## TypeScript
231
256
 
232
- interface TransactionResult {
233
- hash: string;
234
- signature?: string;
235
- status: 'pending' | 'confirmed' | 'failed';
236
- }
257
+ ```typescript
258
+ import type {
259
+ WalletAccount,
260
+ TransactionRequest,
261
+ TransactionResult,
262
+ SignedMessage,
263
+ BalanceResult,
264
+ NetworkConfig,
265
+ WalletInfo,
266
+ RialoProvider,
267
+ RialoNetwork,
268
+ RialoChainId,
269
+ } from '@cookill/wallet-adapter';
270
+ ```
237
271
 
238
- interface SignedMessage {
239
- signature: string;
240
- message: string;
241
- address: string;
242
- }
272
+ ## Troubleshooting
273
+
274
+ ### Connection hangs / freezes
243
275
 
244
- type RialoNetwork = 'mainnet' | 'testnet' | 'devnet' | 'localnet';
276
+ v3.2.1 has built-in 20-second timeout. If connection still hangs:
277
+
278
+ 1. Make sure extension is installed and unlocked
279
+ 2. Check if popup was blocked by browser
280
+ 3. Try refreshing the page
281
+
282
+ ### Auto-connect not working
283
+
284
+ Auto-connect uses `checkSession()` which only restores **existing** sessions silently.
285
+ It won't trigger the approval popup. User must explicitly call `connect()` first time.
286
+
287
+ ### Modal connect flow
288
+
289
+ `ConnectButton` now always opens the modal when disconnected, then connection is initiated from the modal so extension approval flow stays consistent and never feels like a silent fail.
290
+
291
+ ```tsx
292
+ const { openModal } = useWallet();
293
+ openModal();
245
294
  ```
246
295
 
247
- ## Utilities
296
+ ## Migration from v3.0.x
248
297
 
249
- ```typescript
250
- import {
251
- formatAddress, // (address, chars?) => "5YNm...VWr8"
252
- formatBalance, // (kelvins, decimals?) => "1.0000"
253
- parseBalance, // (rlo) => bigint (kelvins)
254
- isValidAddress, // (address) => boolean
255
- isInstalled, // () => boolean checks window.rialo
256
- NETWORKS, // Record<RialoNetwork, NetworkConfig>
257
- } from '@cookill/wallet-adapter';
298
+ ```diff
299
+ import { WalletProvider, ConnectButton } from '@cookill/wallet-adapter/react';
300
+
301
+ const { connect, connected } = useWallet();
302
+
303
+ // v3.2.1 updates:
304
+ // - ConnectButton opens WalletModal when disconnected
305
+ // - WalletModal uses refreshed Sheep Wallet Luxury Minimal branding
306
+ // - connect() path remains timeout-guarded
258
307
  ```
259
308
 
260
- ## Architecture Notes
309
+ ### Important note about QR / scan-to-connect
261
310
 
262
- - All provider calls have a 20-second timeout to prevent dApp freezes
263
- - `autoConnect` uses `checkSession()` — never triggers a user-facing popup
264
- - The built-in modal uses a sibling DOM architecture (backdrop and content are separate elements) to prevent click events from interfering with tab switching or button interactions
265
- - `ConnectButton` bypasses the modal when the extension is installed
311
+ Core `@cookill/wallet-adapter/react` does **not** ship camera QR scanner UI. If your app needs QR scan/connect flow, implement custom modal UI at app layer and pass resulting URI to your own connect handler.
266
312
 
267
313
  ## License
268
314