@cookill/wallet-adapter 3.0.0 → 3.1.1
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 +160 -214
- package/dist/index.cjs +197 -4
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +223 -3
- package/dist/index.d.ts +223 -3
- package/dist/index.js +197 -4
- package/dist/index.js.map +1 -1
- package/dist/react.cjs +197 -4
- package/dist/react.cjs.map +1 -1
- package/dist/react.js +197 -4
- package/dist/react.js.map +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -1,41 +1,32 @@
|
|
|
1
|
-
# @cookill/wallet-adapter
|
|
1
|
+
# @cookill/wallet-adapter
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Wallet adapter for **Sheep Wallet** — the browser extension wallet for the Rialo blockchain.
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
- **Anti-freeze architecture**: All provider calls wrapped with timeouts
|
|
8
|
-
- **Clean separation**: Core (vanilla JS) vs React layer
|
|
9
|
-
- **Silent auto-connect**: Uses `checkSession()` instead of `connect()` for session restoration
|
|
10
|
-
- **No more hangs**: 20-second timeout on connection, 30-second on operations
|
|
5
|
+
Provides a drop-in React provider, responsive connect modal, and vanilla JS class so dApp developers can integrate Sheep Wallet without writing custom UI.
|
|
11
6
|
|
|
12
7
|
## Installation
|
|
13
8
|
|
|
14
9
|
```bash
|
|
15
10
|
npm install @cookill/wallet-adapter
|
|
16
|
-
# or
|
|
17
|
-
pnpm add @cookill/wallet-adapter
|
|
18
|
-
# or
|
|
19
|
-
yarn add @cookill/wallet-adapter
|
|
20
11
|
```
|
|
21
12
|
|
|
22
13
|
## Quick Start (React)
|
|
23
14
|
|
|
24
15
|
```tsx
|
|
25
|
-
import { WalletProvider, ConnectButton
|
|
16
|
+
import { WalletProvider, ConnectButton } from '@cookill/wallet-adapter/react';
|
|
26
17
|
|
|
27
18
|
function App() {
|
|
28
19
|
return (
|
|
29
|
-
<
|
|
30
|
-
<
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
</WalletProvider>
|
|
34
|
-
</WalletErrorBoundary>
|
|
20
|
+
<WalletProvider network="devnet" autoConnect>
|
|
21
|
+
<ConnectButton />
|
|
22
|
+
<YourDApp />
|
|
23
|
+
</WalletProvider>
|
|
35
24
|
);
|
|
36
25
|
}
|
|
37
26
|
```
|
|
38
27
|
|
|
28
|
+
`WalletProvider` renders a built-in connect modal automatically. On desktop the modal opens centered; on mobile it slides up from the bottom as a sheet. No custom modal code needed.
|
|
29
|
+
|
|
39
30
|
## React Hooks
|
|
40
31
|
|
|
41
32
|
### useWallet
|
|
@@ -45,65 +36,64 @@ import { useWallet } from '@cookill/wallet-adapter/react';
|
|
|
45
36
|
|
|
46
37
|
function MyComponent() {
|
|
47
38
|
const {
|
|
48
|
-
//
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
isInstalled, // boolean
|
|
55
|
-
|
|
39
|
+
connected, // boolean — is wallet connected
|
|
40
|
+
connecting, // boolean — connection in progress
|
|
41
|
+
activeAccount, // WalletAccount | null — first connected account
|
|
42
|
+
chainId, // string — e.g. "rialo:devnet"
|
|
43
|
+
isInstalled, // boolean — extension detected in browser
|
|
44
|
+
|
|
56
45
|
// Actions
|
|
57
|
-
connect,
|
|
58
|
-
disconnect,
|
|
59
|
-
switchNetwork,
|
|
60
|
-
refreshBalance,
|
|
61
|
-
|
|
62
|
-
// Transactions
|
|
63
|
-
signMessage,
|
|
64
|
-
signTransaction,
|
|
65
|
-
sendTransaction,
|
|
66
|
-
signAndSendTransaction,
|
|
67
|
-
|
|
68
|
-
// Modal
|
|
69
|
-
openModal,
|
|
70
|
-
closeModal,
|
|
46
|
+
connect, // () => Promise<WalletAccount[]>
|
|
47
|
+
disconnect, // () => Promise<void>
|
|
48
|
+
switchNetwork, // (network) => Promise<void>
|
|
49
|
+
refreshBalance, // () => Promise<void>
|
|
50
|
+
|
|
51
|
+
// Signing & Transactions
|
|
52
|
+
signMessage, // (msg: string) => Promise<SignedMessage>
|
|
53
|
+
signTransaction, // (tx) => Promise<string>
|
|
54
|
+
sendTransaction, // (tx) => Promise<TransactionResult>
|
|
55
|
+
signAndSendTransaction, // (tx) => Promise<TransactionResult>
|
|
56
|
+
|
|
57
|
+
// Modal control
|
|
58
|
+
openModal, // () => void — open the connect modal
|
|
59
|
+
closeModal, // () => void — close it
|
|
71
60
|
} = 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
61
|
}
|
|
83
62
|
```
|
|
84
63
|
|
|
85
|
-
###
|
|
64
|
+
### Focused Hooks
|
|
86
65
|
|
|
87
66
|
```tsx
|
|
88
|
-
// Connection
|
|
89
67
|
const { connect, connecting, isInstalled, error } = useConnectWallet();
|
|
90
68
|
const { disconnect, connected } = useDisconnectWallet();
|
|
91
69
|
const connected = useIsConnected();
|
|
92
|
-
|
|
93
|
-
// Account
|
|
94
70
|
const account = useActiveAccount();
|
|
95
71
|
const accounts = useAccounts();
|
|
96
|
-
|
|
97
|
-
// Balance
|
|
98
72
|
const { balance, refresh } = useBalance();
|
|
99
|
-
|
|
100
|
-
// Network
|
|
101
73
|
const { network, chainId } = useNetwork();
|
|
102
|
-
const { switchNetwork
|
|
74
|
+
const { switchNetwork } = useSwitchNetwork();
|
|
75
|
+
const { sendTransaction, signAndSendTransaction } = useSendTransaction();
|
|
76
|
+
const { signMessage } = useSignMessage();
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
## Connect Modal
|
|
80
|
+
|
|
81
|
+
The modal is rendered automatically by `WalletProvider`. It has two tabs:
|
|
82
|
+
|
|
83
|
+
1. **Extension** — Detects the installed Sheep Wallet extension and connects directly. If the extension is not installed, a download link is shown.
|
|
84
|
+
2. **Scan to Connect** — Generates a QR code that a mobile Sheep Wallet can scan to pair cross-device. Also supports the reverse flow (wallet shows QR, dApp scans).
|
|
85
|
+
|
|
86
|
+
On mobile viewports the modal slides up from the bottom as a sheet and can be dismissed by swiping down. On desktop it opens as a centered dialog.
|
|
103
87
|
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
88
|
+
When the user clicks **Connect** and the extension is installed, the extension popup opens automatically — no manual action required.
|
|
89
|
+
|
|
90
|
+
### Controlling the Modal
|
|
91
|
+
|
|
92
|
+
```tsx
|
|
93
|
+
const { openModal, closeModal } = useWallet();
|
|
94
|
+
|
|
95
|
+
// Or use the built-in button
|
|
96
|
+
<ConnectButton />
|
|
107
97
|
```
|
|
108
98
|
|
|
109
99
|
## Vanilla JavaScript
|
|
@@ -111,203 +101,159 @@ const { sendTransaction, signAndSendTransaction, connected } = useSendTransactio
|
|
|
111
101
|
```typescript
|
|
112
102
|
import { SheepWallet, isInstalled, formatBalance } from '@cookill/wallet-adapter';
|
|
113
103
|
|
|
114
|
-
// Check if installed
|
|
115
|
-
if (!isInstalled()) {
|
|
116
|
-
console.log('Please install Sheep Wallet');
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
// Create wallet instance
|
|
120
104
|
const wallet = new SheepWallet();
|
|
121
105
|
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
const accounts = await wallet.connect();
|
|
125
|
-
console.log('Connected:', accounts[0].address);
|
|
126
|
-
} catch (error) {
|
|
127
|
-
console.error('Connection failed:', error.message);
|
|
106
|
+
if (!wallet.isInstalled) {
|
|
107
|
+
console.log('Extension not found');
|
|
128
108
|
}
|
|
129
109
|
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
console.log('Balance:', formatBalance(balance), 'RLO');
|
|
110
|
+
const accounts = await wallet.connect();
|
|
111
|
+
console.log('Address:', accounts[0].address);
|
|
133
112
|
|
|
134
|
-
|
|
135
|
-
|
|
113
|
+
const balance = await wallet.getBalance();
|
|
114
|
+
console.log('Balance:', formatBalance(balance));
|
|
136
115
|
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
to: 'RecipientAddress...',
|
|
116
|
+
await wallet.signAndSendTransaction({
|
|
117
|
+
to: 'RecipientAddress',
|
|
140
118
|
value: '1000000000', // 1 RLO in kelvins
|
|
141
119
|
});
|
|
142
|
-
console.log('TX Hash:', tx.hash);
|
|
143
|
-
|
|
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);
|
|
148
|
-
}
|
|
149
|
-
```
|
|
150
120
|
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
```typescript
|
|
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
|
-
}
|
|
121
|
+
await wallet.disconnect();
|
|
163
122
|
```
|
|
164
123
|
|
|
165
|
-
##
|
|
166
|
-
|
|
167
|
-
### ConnectButton
|
|
124
|
+
## ConnectButton
|
|
168
125
|
|
|
169
126
|
```tsx
|
|
170
127
|
<ConnectButton
|
|
171
|
-
connectLabel="Connect Wallet"
|
|
172
|
-
disconnectLabel="Disconnect"
|
|
173
|
-
showAddress={true}
|
|
174
|
-
showBalance={false}
|
|
175
|
-
className="my-button"
|
|
176
|
-
style={{ backgroundColor: '#6EB9A8' }}
|
|
128
|
+
connectLabel="Connect Wallet" // label when disconnected
|
|
129
|
+
disconnectLabel="Disconnect" // dropdown label when connected
|
|
130
|
+
showAddress={true} // show truncated address when connected
|
|
131
|
+
showBalance={false} // show RLO balance next to address
|
|
177
132
|
/>
|
|
178
133
|
```
|
|
179
134
|
|
|
180
|
-
|
|
135
|
+
## WalletProvider Props
|
|
181
136
|
|
|
182
137
|
```tsx
|
|
183
138
|
<WalletProvider
|
|
184
|
-
network="devnet"
|
|
185
|
-
autoConnect={true}
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
onError={(error) => console.error(error)}
|
|
139
|
+
network="devnet" // default network
|
|
140
|
+
autoConnect={true} // silently restore previous session on load
|
|
141
|
+
onConnect={(accounts) => {}}
|
|
142
|
+
onDisconnect={() => {}}
|
|
143
|
+
onNetworkChange={(net) => {}}
|
|
144
|
+
onError={(error) => {}}
|
|
191
145
|
>
|
|
192
146
|
{children}
|
|
193
147
|
</WalletProvider>
|
|
194
148
|
```
|
|
195
149
|
|
|
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" />
|
|
223
|
-
|
|
224
|
-
<ConnectionStatus status="connecting" />
|
|
225
|
-
<ConnectionStatus status="approving" message="Check your wallet" />
|
|
226
|
-
<ConnectionStatus status="error" onRetry={() => connect()} />
|
|
227
|
-
```
|
|
228
|
-
|
|
229
150
|
## Networks
|
|
230
151
|
|
|
231
|
-
| Network | Chain ID | RPC URL
|
|
232
|
-
|
|
233
|
-
| Mainnet | rialo:mainnet | https://mainnet.rialo.io:4101
|
|
234
|
-
| Testnet | rialo:testnet | https://testnet.rialo.io:4101
|
|
235
|
-
| Devnet | rialo:devnet | https://devnet.rialo.io:4101
|
|
152
|
+
| Network | Chain ID | RPC URL | Symbol |
|
|
153
|
+
|----------|-----------------|--------------------------------|--------|
|
|
154
|
+
| Mainnet | rialo:mainnet | https://mainnet.rialo.io:4101 | RLO |
|
|
155
|
+
| Testnet | rialo:testnet | https://testnet.rialo.io:4101 | tRLO |
|
|
156
|
+
| Devnet | rialo:devnet | https://devnet.rialo.io:4101 | dRLO |
|
|
236
157
|
| Localnet | rialo:localnet | http://localhost:4101 | lRLO |
|
|
237
158
|
|
|
238
|
-
##
|
|
159
|
+
## Provider Interface (window.rialo)
|
|
239
160
|
|
|
240
|
-
|
|
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
|
-
```
|
|
254
|
-
|
|
255
|
-
## TypeScript
|
|
161
|
+
When the Sheep Wallet extension is installed, it injects `window.rialo` with this interface:
|
|
256
162
|
|
|
257
163
|
```typescript
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
164
|
+
interface RialoProvider {
|
|
165
|
+
isRialo: boolean;
|
|
166
|
+
isSheepWallet: boolean;
|
|
167
|
+
version: string;
|
|
168
|
+
|
|
169
|
+
// Connection
|
|
170
|
+
connect(): Promise<WalletAccount[]>;
|
|
171
|
+
disconnect(): Promise<void>;
|
|
172
|
+
isConnected(): Promise<boolean>;
|
|
173
|
+
getAccounts(): Promise<WalletAccount[]>;
|
|
174
|
+
|
|
175
|
+
// Transactions
|
|
176
|
+
signTransaction(tx: TransactionRequest): Promise<{ signature: string }>;
|
|
177
|
+
sendTransaction(tx: TransactionRequest): Promise<TransactionResult>;
|
|
178
|
+
signAndSendTransaction(tx: TransactionRequest): Promise<TransactionResult>;
|
|
179
|
+
|
|
180
|
+
// Message Signing
|
|
181
|
+
signMessage(message: string | Uint8Array): Promise<SignedMessage>;
|
|
182
|
+
|
|
183
|
+
// Network
|
|
184
|
+
getNetwork(): Promise<RialoNetwork>;
|
|
185
|
+
switchNetwork(network: RialoNetwork): Promise<void>;
|
|
186
|
+
getBalance(address?: string): Promise<BalanceResult>;
|
|
187
|
+
|
|
188
|
+
// Events
|
|
189
|
+
on(event: WalletEvent, callback: Function): () => void;
|
|
190
|
+
|
|
191
|
+
// State (synchronous getters)
|
|
192
|
+
readonly connected: boolean;
|
|
193
|
+
readonly accounts: WalletAccount[];
|
|
194
|
+
readonly address: string | null;
|
|
195
|
+
readonly network: RialoNetwork;
|
|
196
|
+
readonly chainId: string;
|
|
197
|
+
}
|
|
270
198
|
```
|
|
271
199
|
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
### Connection hangs / freezes
|
|
200
|
+
### Supported Events
|
|
275
201
|
|
|
276
|
-
|
|
202
|
+
| Event | Payload |
|
|
203
|
+
|-------------------|-----------------------------------|
|
|
204
|
+
| `connect` | `{ accounts: WalletAccount[] }` |
|
|
205
|
+
| `disconnect` | — |
|
|
206
|
+
| `accountsChanged` | `WalletAccount[]` |
|
|
207
|
+
| `networkChanged` | `{ network, chainId }` |
|
|
277
208
|
|
|
278
|
-
|
|
279
|
-
2. Check if popup was blocked by browser
|
|
280
|
-
3. Try refreshing the page
|
|
209
|
+
## Key Types
|
|
281
210
|
|
|
282
|
-
|
|
211
|
+
```typescript
|
|
212
|
+
interface WalletAccount {
|
|
213
|
+
address: string;
|
|
214
|
+
publicKey: string;
|
|
215
|
+
}
|
|
283
216
|
|
|
284
|
-
|
|
285
|
-
|
|
217
|
+
interface TransactionRequest {
|
|
218
|
+
to: string;
|
|
219
|
+
value: string; // amount in kelvins (1 RLO = 1_000_000_000 kelvins)
|
|
220
|
+
data?: string;
|
|
221
|
+
memo?: string;
|
|
222
|
+
}
|
|
286
223
|
|
|
287
|
-
|
|
224
|
+
interface TransactionResult {
|
|
225
|
+
hash: string;
|
|
226
|
+
signature?: string;
|
|
227
|
+
status: 'pending' | 'confirmed' | 'failed';
|
|
228
|
+
}
|
|
288
229
|
|
|
289
|
-
|
|
230
|
+
interface SignedMessage {
|
|
231
|
+
signature: string;
|
|
232
|
+
message: string;
|
|
233
|
+
address: string;
|
|
234
|
+
}
|
|
290
235
|
|
|
291
|
-
|
|
292
|
-
// Make sure you're inside WalletProvider
|
|
293
|
-
const { openModal } = useWallet();
|
|
294
|
-
openModal(); // This should work
|
|
236
|
+
type RialoNetwork = 'mainnet' | 'testnet' | 'devnet' | 'localnet';
|
|
295
237
|
```
|
|
296
238
|
|
|
297
|
-
##
|
|
239
|
+
## Utilities
|
|
298
240
|
|
|
299
|
-
```
|
|
300
|
-
|
|
301
|
-
|
|
241
|
+
```typescript
|
|
242
|
+
import {
|
|
243
|
+
formatAddress, // (address, chars?) => "5YNm...VWr8"
|
|
244
|
+
formatBalance, // (kelvins, decimals?) => "1.0000"
|
|
245
|
+
parseBalance, // (rlo) => bigint (kelvins)
|
|
246
|
+
isValidAddress, // (address) => boolean
|
|
247
|
+
isInstalled, // () => boolean
|
|
248
|
+
NETWORKS, // Record<RialoNetwork, NetworkConfig>
|
|
249
|
+
} from '@cookill/wallet-adapter';
|
|
250
|
+
```
|
|
302
251
|
|
|
303
|
-
|
|
304
|
-
const { connect, connected } = useWallet();
|
|
252
|
+
## Architecture Notes
|
|
305
253
|
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
// - New SheepWallet class for vanilla JS (replaces RialoWallet)
|
|
310
|
-
```
|
|
254
|
+
- All provider calls are wrapped with a 20-second timeout to prevent dApp freezes if the extension stops responding.
|
|
255
|
+
- `autoConnect` uses a silent `checkSession()` that never triggers a user-facing approval popup — it only restores an existing session.
|
|
256
|
+
- The connect modal is rendered inside `WalletProvider` so you never need to manage modal state yourself.
|
|
311
257
|
|
|
312
258
|
## License
|
|
313
259
|
|