@0xio/sdk 2.7.0 → 2.8.0
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/CHANGELOG.md +92 -33
- package/README.md +105 -250
- package/dist/index.d.ts +279 -188
- package/dist/index.esm.js +524 -325
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +533 -324
- package/dist/index.js.map +1 -1
- package/dist/index.umd.js +533 -324
- package/dist/index.umd.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,356 +1,211 @@
|
|
|
1
1
|
# 0xio Wallet SDK
|
|
2
2
|
|
|
3
|
-
**Version
|
|
3
|
+
**Version 2.8.0**
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
The official TypeScript SDK for building dapps on the 0xio Wallet and the Octra Network. It works with the browser extension, inside the 0xio Desktop browser and inside the 0xio App, and picks the right transport on its own.
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
What changed in each release is in [CHANGELOG.md](CHANGELOG.md). The full API is in [DOCUMENTATION.md](DOCUMENTATION.md).
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
- **MessageChannel transport** (H-2 fix): Extension now uses a private `MessageChannel` port instead of `window.postMessage`, preventing page scripts from intercepting or injecting wallet messages. SDK validates a per-session nonce on every response.
|
|
11
|
-
- **Pluggable wallet adapters**: New `src/supports/` system — implement `WalletTransportAdapter` and drop a file in `supports/` to add any wallet without touching core SDK code. See `src/supports/template.ts` for the starting point.
|
|
12
|
-
- Fixed wildcard postMessage target leaking request payloads to any origin (HIGH)
|
|
13
|
-
- Removed `Math.random()` fallback for request IDs — throws if `crypto` unavailable (MEDIUM)
|
|
14
|
-
- Fixed `requestTimestamps` unbounded memory growth in idle tabs (LOW)
|
|
15
|
-
- Removed all `octraWalletReady` legacy event listeners and `createOctraWallet` alias (LOW)
|
|
16
|
-
- Extension fixes: balance/network events now delivered end-to-end; `accountChanged` on wallet switch; exact hostname tab matching; approval listener spoofing from content scripts blocked
|
|
17
|
-
- All 17 post-audit findings resolved. See `AUDIT_REMEDIATION.md` for full details.
|
|
18
|
-
|
|
19
|
-
## What's New in v2.6.0
|
|
20
|
-
|
|
21
|
-
- **`sendPrivateTransfer(to, amount)`**: Send encrypted (stealth) transfers — amount is hidden from everyone except sender and recipient. Uses PVAC-HFHE for ciphertext subtraction + zero-knowledge proofs. The node re-encrypts under the recipient's key.
|
|
22
|
-
- **`getPendingPrivateTransfers()`**: List incoming private transfers claimable by your wallet.
|
|
23
|
-
- **`claimPrivateTransfer(transferId)`**: Claim a pending private transfer into your encrypted balance.
|
|
24
|
-
- **Privacy-first DApps**: Build prediction markets, private payments, stealth bets — all amounts stay encrypted on-chain.
|
|
25
|
-
- Requires 0xio Wallet Extension v2.4.0+
|
|
26
|
-
|
|
27
|
-
## v2.5.0
|
|
28
|
-
|
|
29
|
-
- **`switchNetwork(networkId)`**: Switch the extension's network silently — no popup, no user action. DApps can detect network mismatch and offer one-click switch (like Rabby).
|
|
30
|
-
- **`getNetworkId()`**: Get the extension's current active network.
|
|
31
|
-
- **Network-aware DApps**: Detect if user is on mainnet vs devnet, show banner, switch with one click.
|
|
32
|
-
|
|
33
|
-
## v2.4.5
|
|
34
|
-
|
|
35
|
-
- **Correct network detection**: SDK reads active network from extension instead of hardcoding mainnet.
|
|
36
|
-
- **Full networkInfo in connect response**: Extension returns complete network config.
|
|
37
|
-
- **Live balance on reconnect**: Fresh balance from chain instead of stale cached zeros.
|
|
38
|
-
- **Transaction history**: Real on-chain transactions with pagination.
|
|
39
|
-
- **Event alignment**: `transactionConfirmed` event fires correctly.
|
|
40
|
-
|
|
41
|
-
## v2.4.4
|
|
42
|
-
|
|
43
|
-
- **Fix double popup on timeout**: Transaction/signing methods no longer retry, preventing duplicate approval popups.
|
|
44
|
-
- **120s timeout for interactive methods**: Users have 2 minutes to review and approve transactions.
|
|
45
|
-
|
|
46
|
-
## v2.4.2
|
|
47
|
-
|
|
48
|
-
- **Cross-origin iframe bridge**: Localhost origins now accepted as trusted parents for dev/testing DApp browser scenarios.
|
|
49
|
-
- **Parent origin capture**: `walletReady` signal carries `parentOrigin` for reliable cross-origin reply targeting.
|
|
50
|
-
- **postMessage fix**: Replies to parent frame use captured origin instead of `window.location.origin` (which fails cross-port).
|
|
51
|
-
|
|
52
|
-
## v2.4.1
|
|
53
|
-
|
|
54
|
-
- **No retry on user rejection**: Transactions, contract calls, and sign requests rejected by the user no longer trigger automatic retry. Prevents double confirmation popups.
|
|
55
|
-
- **Security hardening**: postMessage origin validation, removed iframe auto-trust, response ID binding.
|
|
56
|
-
- **Type fixes**: Replaced `NodeJS.Timeout` with `ReturnType<typeof setTimeout>` for browser compatibility.
|
|
57
|
-
|
|
58
|
-
## v2.4.0
|
|
59
|
-
|
|
60
|
-
- **Desktop/Mobile DApp Bridge**: SDK now supports running inside iframes (0xio Desktop) and WebViews (0xio App). Requests are relayed to the parent frame automatically.
|
|
61
|
-
- **Auto Frame Detection**: When `window.parent !== window`, the SDK assumes a wallet bridge is available and marks the wallet as detected.
|
|
62
|
-
- **Frame-Aware Messaging**: `postMessageToExtension()` posts to both `window` and `window.parent` when running inside a frame; `setupMessageListener()` accepts messages from `window.parent`.
|
|
63
|
-
- **walletReady via postMessage**: Extension detection now recognizes `walletReady` events from parent frames.
|
|
64
|
-
- **Fully backward compatible** — extension-based DApps work unchanged with no code changes needed.
|
|
65
|
-
|
|
66
|
-
## Installation
|
|
9
|
+
## Install
|
|
67
10
|
|
|
68
11
|
```bash
|
|
69
12
|
npm install @0xio/sdk
|
|
70
13
|
```
|
|
71
14
|
|
|
72
|
-
## Quick
|
|
15
|
+
## Quick start
|
|
73
16
|
|
|
74
17
|
```typescript
|
|
75
18
|
import { ZeroXIOWallet } from '@0xio/sdk';
|
|
76
19
|
|
|
77
|
-
// 1. Initialize
|
|
78
20
|
const wallet = new ZeroXIOWallet({
|
|
79
21
|
appName: 'My DApp',
|
|
80
|
-
requiredPermissions: ['
|
|
22
|
+
requiredPermissions: ['accounts', 'public_transactions'],
|
|
81
23
|
});
|
|
82
24
|
|
|
83
25
|
await wallet.initialize();
|
|
84
26
|
|
|
85
|
-
//
|
|
27
|
+
// Connect. The wallet shows an approval the first time.
|
|
86
28
|
const connection = await wallet.connect();
|
|
87
|
-
console.log(
|
|
88
|
-
console.log(
|
|
29
|
+
console.log(connection.address);
|
|
30
|
+
console.log(connection.publicKey); // base64 Ed25519 key
|
|
89
31
|
|
|
90
|
-
//
|
|
32
|
+
// Balance, in OCT.
|
|
91
33
|
const balance = await wallet.getBalance();
|
|
92
|
-
console.log(
|
|
34
|
+
console.log(balance.public, balance.private, balance.total);
|
|
93
35
|
|
|
94
|
-
//
|
|
36
|
+
// Sign a message. The wallet frames it (see Message signing below).
|
|
95
37
|
const signature = await wallet.signMessage('Hello, 0xio!');
|
|
96
|
-
console.log('Signature:', signature);
|
|
97
38
|
|
|
98
|
-
// 5.
|
|
39
|
+
// Send 10.5 OCT.
|
|
99
40
|
const result = await wallet.sendTransaction({
|
|
100
41
|
to: 'oct1recipient...',
|
|
101
|
-
|
|
102
|
-
message: 'Payment'
|
|
42
|
+
amountOct: '10.5',
|
|
43
|
+
message: 'Payment',
|
|
103
44
|
});
|
|
104
|
-
console.log(
|
|
45
|
+
console.log(result.hash);
|
|
105
46
|
```
|
|
106
47
|
|
|
107
|
-
##
|
|
48
|
+
## Amounts and units
|
|
108
49
|
|
|
109
|
-
|
|
50
|
+
The wallet counts in raw micro-OCT: one OCT is 1000000 units. Every raw field is passed to the wallet exactly as you give it, so existing integrations keep working. Where you would rather write OCT, use the OCT field and the SDK converts it with exact decimal arithmetic.
|
|
110
51
|
|
|
111
|
-
|
|
112
|
-
|
|
52
|
+
| Method | Raw field (sent as is) | OCT field (converted by the SDK) |
|
|
53
|
+
|--------|------------------------|----------------------------------|
|
|
54
|
+
| `sendTransaction`, `signTransaction` | `amount` | `amountOct` |
|
|
55
|
+
| `callContract` | `amount` | `amountOct` |
|
|
56
|
+
| `sendPrivateTransfer` | `amountRaw` | `amount` |
|
|
57
|
+
| `getBalance` | | returns OCT |
|
|
113
58
|
|
|
114
|
-
|
|
115
|
-
Connect to the user's wallet. Shows approval popup if first time.
|
|
59
|
+
Pass one field or the other, not both. A number that cannot be written in six decimals (such as `0.1 + 0.2`) is rejected; pass a string.
|
|
116
60
|
|
|
117
|
-
|
|
118
|
-
Disconnect from the wallet.
|
|
61
|
+
## Permissions
|
|
119
62
|
|
|
120
|
-
|
|
121
|
-
Check if currently connected.
|
|
63
|
+
Ask for what the dapp uses. The wallet enforces these names:
|
|
122
64
|
|
|
123
|
-
|
|
65
|
+
| Scope | Grants |
|
|
66
|
+
|-------|--------|
|
|
67
|
+
| `accounts` | address, balance, public key |
|
|
68
|
+
| `public_transactions` | sends and message signing |
|
|
69
|
+
| `contract_calls` | state-changing contract calls |
|
|
70
|
+
| `contract_views` | read-only contract calls |
|
|
71
|
+
| `private_balance_read` | private balance, decrypting values, pending transfers |
|
|
72
|
+
| `private_proofs` | encrypting values, zero and range proofs |
|
|
73
|
+
| `private_transfers` | sending private transfers |
|
|
74
|
+
| `private_claims` | claiming private transfers |
|
|
124
75
|
|
|
125
|
-
|
|
126
|
-
Get wallet balance (public + private).
|
|
76
|
+
The private scopes show a warning in the connection dialog. Older names such as `read_balance` or `stealth_claim` still work: the SDK translates them, and they come back in the granted list as aliases.
|
|
127
77
|
|
|
128
|
-
|
|
129
|
-
interface Balance {
|
|
130
|
-
public: number; // Visible on-chain balance
|
|
131
|
-
private: number; // Encrypted (FHE) balance
|
|
132
|
-
total: number; // public + private
|
|
133
|
-
currency: 'OCT';
|
|
134
|
-
}
|
|
135
|
-
```
|
|
78
|
+
## API map
|
|
136
79
|
|
|
137
|
-
|
|
80
|
+
Connection: `initialize()`, `connect(options?)`, `disconnect()`, `isConnected()`, `getConnectionStatus()`, `getAddress()`, `getPublicKey()`.
|
|
138
81
|
|
|
139
|
-
|
|
140
|
-
Send a transaction. Returns result with transaction finality status.
|
|
82
|
+
Balance and network: `getBalance(forceRefresh?)`, `getNetworkInfo()`, `getNetworkId()`, `switchNetwork(id)` (connected dapps only; no popup).
|
|
141
83
|
|
|
142
|
-
|
|
143
|
-
interface TransactionData {
|
|
144
|
-
to: string; // Recipient address (oct1...)
|
|
145
|
-
amount: number; // Amount in OCT
|
|
146
|
-
message?: string; // Optional memo
|
|
147
|
-
}
|
|
84
|
+
Transactions: `sendTransaction(data)`, `signTransaction(data)` then `submitTransaction(signedTx)`, `getTransactionHistory(page?, limit?)`.
|
|
148
85
|
|
|
149
|
-
|
|
150
|
-
txHash: string;
|
|
151
|
-
success: boolean;
|
|
152
|
-
finality?: 'pending' | 'confirmed' | 'rejected';
|
|
153
|
-
message?: string;
|
|
154
|
-
explorerUrl?: string;
|
|
155
|
-
}
|
|
156
|
-
```
|
|
86
|
+
Contracts: `callContract(data)` (signed, approval shown), `contractCallView(data)` (read-only, no approval), `getContractStorage(contract, key)`, `sendContractTransactionSequence(data)` (several calls under one approval; every step is listed in it).
|
|
157
87
|
|
|
158
|
-
|
|
88
|
+
Messages: `signMessage(message)`, `signAuthMessage(service, nonce)`, and the verifiers `verifyMessage`, `getSignedMessageBytes`, `buildAuthMessage`.
|
|
159
89
|
|
|
160
|
-
|
|
161
|
-
Execute a state-changing contract call. The extension signs and submits via `octra_submit`.
|
|
90
|
+
Private: `sendPrivateTransfer(data)`, `getPendingPrivateTransfers()`, `claimPrivateTransfer(id)` (approval shown), `getPrivateBalanceInfo()`, `registerPrivateViewKey({ address })`.
|
|
162
91
|
|
|
163
|
-
|
|
164
|
-
const result = await wallet.callContract({
|
|
165
|
-
contract: 'oct26Lia...', // Contract address
|
|
166
|
-
method: 'swap', // AML method name
|
|
167
|
-
params: [100, true, 90], // Method arguments (flat, not array-wrapped)
|
|
168
|
-
amount: '0', // Native OCT to send (optional, default '0')
|
|
169
|
-
ou: '10000', // Operational units (optional, default '10000')
|
|
170
|
-
});
|
|
171
|
-
console.log('TX Hash:', result.txHash);
|
|
172
|
-
```
|
|
92
|
+
Private primitives (2.8.0): `getPrivateCapabilities()`, `encryptValue()`, `decryptValue()`, `makeZeroProof()`, `makeRangeProof()`, `getPrivateBalance()`. Keys never leave the wallet; the dapp receives ciphertexts, proofs and hashes.
|
|
173
93
|
|
|
174
|
-
|
|
175
|
-
Read-only contract query. No signing, no approval popup, no wallet unlock required.
|
|
94
|
+
Passthrough: `request(method, params)` sends any wallet method; `rpcCall(method, params)` reaches the wallet's read-only node RPC allow-list, such as `octra_balance`.
|
|
176
95
|
|
|
177
|
-
|
|
178
|
-
const price = await wallet.contractCallView({
|
|
179
|
-
contract: 'oct26Lia...',
|
|
180
|
-
method: 'get_active_price',
|
|
181
|
-
params: [],
|
|
182
|
-
});
|
|
183
|
-
console.log('Price:', price);
|
|
184
|
-
```
|
|
96
|
+
`encryptBalance` and `decryptBalance` remain for other wallets; the 0xio extension answers `NOT_AVAILABLE`, and users encrypt from its Privacy screen.
|
|
185
97
|
|
|
186
|
-
|
|
187
|
-
Read contract storage by key.
|
|
98
|
+
## Message signing
|
|
188
99
|
|
|
189
|
-
|
|
190
|
-
const value = await wallet.getContractStorage('oct26Lia...', 'total_supply');
|
|
191
|
-
console.log('Total supply:', value);
|
|
192
|
-
```
|
|
100
|
+
The wallet never signs a raw message. It signs a framed payload, so a signed message can never be a transaction (a transaction is JSON and starts with `{`):
|
|
193
101
|
|
|
194
|
-
|
|
102
|
+
```
|
|
103
|
+
"Octra Signed Message:\n" + utf8ByteLength(message) + "\n" + message
|
|
104
|
+
```
|
|
195
105
|
|
|
196
|
-
|
|
197
|
-
Sign an arbitrary message with the wallet's private key. User will be prompted to approve.
|
|
106
|
+
The signature is an Ed25519 detached signature over the UTF-8 bytes of that string. Verify it with the SDK:
|
|
198
107
|
|
|
199
108
|
```typescript
|
|
200
|
-
|
|
201
|
-
const message = `Login to MyDApp\nTimestamp: ${Date.now()}`;
|
|
202
|
-
const signature = await wallet.signMessage(message);
|
|
109
|
+
import { verifyMessage } from '@0xio/sdk';
|
|
203
110
|
|
|
204
|
-
|
|
205
|
-
|
|
111
|
+
const publicKey = await wallet.getPublicKey();
|
|
112
|
+
const ok = await verifyMessage(message, signature, publicKey);
|
|
206
113
|
```
|
|
207
114
|
|
|
208
|
-
|
|
209
|
-
- Prove wallet ownership for API authentication
|
|
210
|
-
- Sign login challenges
|
|
211
|
-
- Authorize off-chain actions
|
|
212
|
-
- Create verifiable attestations
|
|
115
|
+
Or with any Ed25519 library, over the exact bytes from `getSignedMessageBytes(message)`. For `signAuthMessage(service, nonce)`, rebuild the signed string with `buildAuthMessage(service, nonce, origin)` first.
|
|
213
116
|
|
|
214
|
-
|
|
117
|
+
## Events
|
|
215
118
|
|
|
216
119
|
```typescript
|
|
217
120
|
wallet.on('connect', (event) => console.log('Connected:', event.data.address));
|
|
218
|
-
wallet.on('disconnect', (event) => console.log('Disconnected'));
|
|
219
|
-
wallet.on('
|
|
220
|
-
wallet.on('
|
|
121
|
+
wallet.on('disconnect', (event) => console.log('Disconnected:', event.data.reason));
|
|
122
|
+
wallet.on('accountChanged', (event) => console.log('Account:', event.data.newAddress));
|
|
123
|
+
wallet.on('balanceChanged', (event) => console.log('Balance:', event.data.newBalance.total));
|
|
221
124
|
wallet.on('networkChanged', (event) => console.log('Network:', event.data.newNetwork.name));
|
|
125
|
+
wallet.on('transactionConfirmed', (event) => console.log('Confirmed:', event.data.txHash));
|
|
126
|
+
wallet.on('transactionFailed', (event) => console.log('Failed:', event.data.error));
|
|
127
|
+
wallet.on('extensionLocked', () => console.log('Locked'));
|
|
222
128
|
```
|
|
223
129
|
|
|
224
|
-
##
|
|
130
|
+
## Errors
|
|
131
|
+
|
|
132
|
+
Every failure is a `ZeroXIOWalletError` with a `code`.
|
|
225
133
|
|
|
226
134
|
```typescript
|
|
227
135
|
import { ZeroXIOWalletError, ErrorCode } from '@0xio/sdk';
|
|
228
136
|
|
|
229
137
|
try {
|
|
230
|
-
|
|
138
|
+
await wallet.sendTransaction({ to: 'oct1...', amountOct: '10' });
|
|
231
139
|
} catch (error) {
|
|
232
140
|
if (error instanceof ZeroXIOWalletError) {
|
|
233
141
|
switch (error.code) {
|
|
234
|
-
case ErrorCode.
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
case ErrorCode.
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
case ErrorCode.INVALID_SIGNATURE:
|
|
241
|
-
console.log('Invalid transaction signature');
|
|
242
|
-
break;
|
|
243
|
-
case ErrorCode.DUPLICATE_TRANSACTION:
|
|
244
|
-
console.log('Transaction already submitted');
|
|
245
|
-
break;
|
|
246
|
-
case ErrorCode.SELF_TRANSFER:
|
|
247
|
-
console.log('Cannot send to yourself');
|
|
248
|
-
break;
|
|
249
|
-
case ErrorCode.NONCE_TOO_FAR:
|
|
250
|
-
console.log('Transaction nonce too far ahead');
|
|
251
|
-
break;
|
|
252
|
-
case ErrorCode.WALLET_LOCKED:
|
|
253
|
-
console.log('Please unlock your wallet');
|
|
254
|
-
break;
|
|
142
|
+
case ErrorCode.NOT_CONNECTED: // connect() first
|
|
143
|
+
case ErrorCode.WALLET_LOCKED: // the user has to unlock the wallet
|
|
144
|
+
case ErrorCode.USER_REJECTED: // the user declined the approval
|
|
145
|
+
case ErrorCode.INVALID_AMOUNT: // bad unit or precision
|
|
146
|
+
case ErrorCode.NONCE_TOO_FAR: // node rejected the transaction
|
|
147
|
+
console.log(error.code, error.message);
|
|
255
148
|
}
|
|
256
149
|
}
|
|
257
150
|
}
|
|
258
151
|
```
|
|
259
152
|
|
|
260
|
-
|
|
153
|
+
The wallet refuses anything that signs, submits or changes state until the page has connected, and opens its unlock screen at most once a minute for a page that is not connected.
|
|
261
154
|
|
|
262
|
-
|
|
155
|
+
## Networks
|
|
263
156
|
|
|
264
157
|
```typescript
|
|
265
|
-
import {
|
|
158
|
+
import { getNetworkConfig } from '@0xio/sdk';
|
|
266
159
|
|
|
267
|
-
// Get devnet config
|
|
268
160
|
const devnet = getNetworkConfig('devnet');
|
|
269
|
-
console.log(devnet.rpcUrl);
|
|
270
|
-
console.log(devnet.
|
|
271
|
-
console.log(devnet.isTestnet); // true
|
|
272
|
-
|
|
273
|
-
// Get mainnet config
|
|
274
|
-
const mainnet = getNetworkConfig('mainnet');
|
|
275
|
-
console.log(mainnet.rpcUrl); // http://46.101.86.250:8080
|
|
276
|
-
console.log(mainnet.supportsPrivacy); // true
|
|
277
|
-
```
|
|
278
|
-
|
|
279
|
-
| Network | Privacy (FHE) | Explorer |
|
|
280
|
-
|---------|:---:|---|
|
|
281
|
-
| Mainnet Alpha | Yes | [octrascan.io](https://octrascan.io) |
|
|
282
|
-
| Devnet | Yes | [devnet.octrascan.io](https://devnet.octrascan.io) |
|
|
283
|
-
|
|
284
|
-
### NetworkInfo Type
|
|
285
|
-
|
|
286
|
-
```typescript
|
|
287
|
-
interface NetworkInfo {
|
|
288
|
-
id: string;
|
|
289
|
-
name: string;
|
|
290
|
-
rpcUrl: string;
|
|
291
|
-
explorerUrl?: string; // Transaction explorer base URL
|
|
292
|
-
explorerAddressUrl?: string; // Address explorer base URL
|
|
293
|
-
indexerUrl?: string; // Indexer/API base URL
|
|
294
|
-
supportsPrivacy: boolean; // FHE encrypted balance support
|
|
295
|
-
color: string; // Brand color hex
|
|
296
|
-
isTestnet: boolean;
|
|
297
|
-
}
|
|
161
|
+
console.log(devnet.rpcUrl); // https://devnet.octrascan.io
|
|
162
|
+
console.log(devnet.isTestnet); // true
|
|
298
163
|
```
|
|
299
164
|
|
|
300
|
-
|
|
165
|
+
| Network | RPC | Explorer | Privacy |
|
|
166
|
+
|---------|-----|----------|---------|
|
|
167
|
+
| Mainnet | `https://octra.network` | [octrascan.io](https://octrascan.io) | yes |
|
|
168
|
+
| Devnet | `https://devnet.octrascan.io` | [devnet.octrascan.io](https://devnet.octrascan.io) | yes |
|
|
301
169
|
|
|
302
|
-
|
|
170
|
+
`connect()` returns the wallet's active network in `networkInfo`; the SDK never assumes one.
|
|
303
171
|
|
|
304
|
-
|
|
305
|
-
- **0xio App's built-in browser** — Your DApp is loaded in a WebView. The SDK communicates with the mobile wallet via the existing WebView bridge.
|
|
306
|
-
- **0xio Wallet Extension** — Standard browser extension communication (unchanged).
|
|
172
|
+
## Where it runs
|
|
307
173
|
|
|
308
|
-
|
|
174
|
+
- **Browser extension.** The page talks to the extension over a private message channel that page scripts cannot read or forge.
|
|
175
|
+
- **0xio Desktop.** The dapp runs in an iframe and the SDK relays requests to the desktop wallet. Set `trustedParentOrigins` in production; localhost is trusted by default for development.
|
|
176
|
+
- **0xio App.** The dapp runs in a WebView and the SDK uses the app's bridge.
|
|
309
177
|
|
|
310
|
-
|
|
178
|
+
No code changes are needed; the SDK detects the environment.
|
|
311
179
|
|
|
312
|
-
|
|
180
|
+
## Wallet adapters
|
|
313
181
|
|
|
314
|
-
|
|
182
|
+
Transport is pluggable, so another wallet can be supported without touching the core.
|
|
315
183
|
|
|
316
184
|
```typescript
|
|
317
|
-
import { detectWalletAdapter, ZeroXIOWallet } from '@0xio/sdk';
|
|
185
|
+
import { detectWalletAdapter, ZeroXIOWallet, OctraProviderAdapter } from '@0xio/sdk';
|
|
318
186
|
|
|
187
|
+
// Detect: the 0xio bridge first, then any RFC-O-1 provider on window.octra.
|
|
319
188
|
const adapter = detectWalletAdapter();
|
|
320
|
-
if (!adapter) throw new Error('No supported wallet found');
|
|
321
|
-
|
|
322
189
|
const wallet = new ZeroXIOWallet({ appName: 'My DApp', adapter });
|
|
323
|
-
```
|
|
324
190
|
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
```typescript
|
|
328
|
-
import { ZeroXIOWallet, ZeroXIOAdapter } from '@0xio/sdk';
|
|
329
|
-
|
|
330
|
-
const wallet = new ZeroXIOWallet({ appName: 'My DApp', adapter: ZeroXIOAdapter });
|
|
191
|
+
// Or choose one explicitly.
|
|
192
|
+
const rfc = new ZeroXIOWallet({ appName: 'My DApp', adapter: OctraProviderAdapter });
|
|
331
193
|
```
|
|
332
194
|
|
|
333
|
-
|
|
195
|
+
The 0xio bridge carries every SDK method. The RFC-O-1 provider carries what the RFC names, so `getBalance`, `getPublicKey`, `getTransactionHistory`, `getContractStorage`, `getPendingPrivateTransfers` and `rpcCall` have no equivalent there. The table in DOCUMENTATION.md lists coverage per method.
|
|
334
196
|
|
|
335
|
-
|
|
336
|
-
2. Fill in the four constants (`REQUEST_SOURCE`, `RESPONSE_SOURCE`, `WINDOW_KEY`, `READY_EVENT`) and the message-shape mapping
|
|
337
|
-
3. Register it in `src/supports/index.ts` `REGISTERED_ADAPTERS`
|
|
338
|
-
4. Export it from `src/index.ts` if you want it in the public API
|
|
197
|
+
To add a wallet, copy `src/supports/template.ts`, fill in its constants and message mapping, register it in `src/supports/index.ts`, and export it from `src/index.ts` if it belongs in the public API.
|
|
339
198
|
|
|
340
|
-
|
|
199
|
+
## Timeouts
|
|
341
200
|
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
- 0xio Wallet Extension v2.0.1 or higher (Mainnet Alpha)
|
|
345
|
-
- 0xio Wallet Extension v2.2.1 or higher (Devnet — required for contract calls and privacy features)
|
|
346
|
-
- 0xio Desktop v1.0+ (for iframe bridge support)
|
|
347
|
-
- 0xio App v1.0+ (for WebView bridge support)
|
|
348
|
-
- Modern browser (Chrome, Firefox, Edge, Brave)
|
|
201
|
+
Approvals wait up to three minutes. A private transfer waits up to ten, because the wallet builds proofs after the approval. Interactive methods are never retried, so a slow approval never produces a second popup.
|
|
349
202
|
|
|
350
|
-
##
|
|
203
|
+
## Requirements
|
|
351
204
|
|
|
352
|
-
|
|
205
|
+
- 0xio Wallet Extension 2.5.5 or newer for the 2.8.0 private primitives and framed message signing; 2.4.0 or newer for private transfers and claims
|
|
206
|
+
- 0xio Desktop 1.0 or newer for the iframe bridge, 0xio App 1.0 or newer for the WebView bridge
|
|
207
|
+
- A current Chromium-based browser (Chrome, Edge, Brave) or Firefox
|
|
353
208
|
|
|
354
209
|
## License
|
|
355
210
|
|
|
356
|
-
MIT License. Copyright 2026 0xio Labs.
|
|
211
|
+
MIT License. Copyright 2026 0xio Labs.
|