@0xio/sdk 2.2.0 → 2.4.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 +52 -1
- package/README.md +59 -9
- package/dist/index.d.ts +43 -4
- package/dist/index.esm.js +133 -41
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +133 -40
- package/dist/index.js.map +1 -1
- package/dist/index.umd.js +134 -41
- package/dist/index.umd.js.map +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,57 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to the 0xio Wallet SDK will be documented in this file.
|
|
4
4
|
|
|
5
|
+
## [2.4.0] - 2026-03-24
|
|
6
|
+
|
|
7
|
+
### Added
|
|
8
|
+
- **Desktop/Mobile DApp Bridge**: SDK now supports running inside iframes (desktop browser) and WebViews (mobile browser). Requests are relayed to the parent frame automatically.
|
|
9
|
+
- **Parent Frame Detection**: `postMessageToExtension()` now posts to both `window` (extension content script) and `window.parent` (iframe bridge) when running inside a frame.
|
|
10
|
+
- **Frame-Aware Message Listener**: `setupMessageListener()` now accepts messages from `window.parent` in addition to same-window, enabling desktop/mobile wallet bridges to communicate with DApps.
|
|
11
|
+
- **walletReady via postMessage**: `startExtensionDetection()` now detects `walletReady` events sent via `postMessage` from parent frames, in addition to DOM events and global signals.
|
|
12
|
+
- **Auto Frame Detection**: When `window.parent !== window`, the SDK assumes a wallet bridge is available and marks the wallet as detected.
|
|
13
|
+
|
|
14
|
+
### Security
|
|
15
|
+
- Parent frame messages are only accepted from `window.parent`, not arbitrary origins
|
|
16
|
+
- Extension content script messages continue to use strict origin validation
|
|
17
|
+
|
|
18
|
+
### Compatibility
|
|
19
|
+
- Fully backward compatible — extension-based DApps work unchanged
|
|
20
|
+
- Desktop (0xio Desktop): DApps loaded in BrowserScreen iframe now auto-connect
|
|
21
|
+
- Mobile (0xio App): DApps loaded in WebView browser now auto-connect via existing bridge
|
|
22
|
+
- Mainnet Alpha: Extension v2.0.1+
|
|
23
|
+
- Devnet: Extension v2.2.1+
|
|
24
|
+
|
|
25
|
+
---
|
|
26
|
+
|
|
27
|
+
## [2.3.0] - 2026-03-10
|
|
28
|
+
|
|
29
|
+
### Added
|
|
30
|
+
- **Smart Contract Interaction**: New `callContract()` method for state-changing contract calls. The extension builds, signs, and submits via `octra_submit` — works on both mainnet and devnet.
|
|
31
|
+
- **Contract View Calls**: New `contractCallView()` method for read-only contract queries. No wallet unlock or approval popup required.
|
|
32
|
+
- **Contract Storage**: New `getContractStorage()` method to read contract storage by key directly from the chain.
|
|
33
|
+
- **New Types**: `ContractCallData`, `ContractViewCallData`, and `ContractParams` for type-safe contract interaction.
|
|
34
|
+
- **Devnet Version Constant**: New `MIN_EXTENSION_VERSION_DEVNET` export (`'2.2.1'`) for programmatic devnet compatibility checks.
|
|
35
|
+
|
|
36
|
+
### Improved
|
|
37
|
+
- **Type Safety**: Replaced `any` with `ContractParams` (`ReadonlyArray<string | number | boolean>`) in `ContractCallData.params` and `ContractViewCallData.params`.
|
|
38
|
+
- **Event Handler Typing**: Three internal event handlers (`handleAccountChanged`, `handleNetworkChanged`, `handleBalanceChanged`) now use properly typed parameters instead of `any`.
|
|
39
|
+
- **Error Consistency**: `getNetworkConfig()` now throws `ZeroXIOWalletError` with `ErrorCode.NETWORK_ERROR` instead of a generic `Error`.
|
|
40
|
+
- **UMD Global Name**: Fixed UMD build global from `OctraWalletSDK` to `ZeroXIOWalletSDK` to match SDK branding.
|
|
41
|
+
|
|
42
|
+
### Security
|
|
43
|
+
- **Fixed wildcard origin**: `simulateExtensionEvent` now uses `window.location.origin` instead of `'*'` wildcard, preventing cross-origin message injection.
|
|
44
|
+
- **signMessage length limit**: Added 10,000 character max to prevent memory exhaustion from oversized signing requests.
|
|
45
|
+
- **Narrowed dev detection**: Removed overly broad `hostname.includes('dev')` check that would enable debug mode on any domain containing "dev" (e.g., `developer.mozilla.org`). Dev mode now only activates on `localhost`, `127.0.0.1`, or when `NODE_ENV=development`.
|
|
46
|
+
|
|
47
|
+
### Fixed
|
|
48
|
+
- **Message validation**: Increased `isValidMessage()` limit from 280 to 100,000 characters. The 280-char limit was blocking contract call parameters which are serialized JSON and can be large.
|
|
49
|
+
|
|
50
|
+
### Compatibility
|
|
51
|
+
- **Mainnet Alpha**: Requires 0xio Wallet Extension v2.0.1 or higher
|
|
52
|
+
- **Devnet**: Requires 0xio Wallet Extension v2.2.1 or higher (contract calls, privacy features)
|
|
53
|
+
|
|
54
|
+
---
|
|
55
|
+
|
|
5
56
|
## [2.2.0] - 2026-03-08
|
|
6
57
|
|
|
7
58
|
### Added
|
|
@@ -18,7 +69,7 @@ All notable changes to the 0xio Wallet SDK will be documented in this file.
|
|
|
18
69
|
|
|
19
70
|
| Network | RPC | Explorer | Privacy | Testnet |
|
|
20
71
|
|---------|-----|----------|---------|---------|
|
|
21
|
-
| Mainnet
|
|
72
|
+
| Mainnet | `http://46.101.86.250:8080` | `https://lite.octrascan.io` | Yes | No |
|
|
22
73
|
| Devnet | `http://165.227.225.79:8080` | `https://devnet.octrascan.io` | Yes | Yes |
|
|
23
74
|
| Custom | User-defined | User-defined | No | No |
|
|
24
75
|
|
package/README.md
CHANGED
|
@@ -1,15 +1,16 @@
|
|
|
1
1
|
# 0xio Wallet SDK
|
|
2
2
|
|
|
3
|
-
**Version:** 2.
|
|
3
|
+
**Version:** 2.4.0
|
|
4
4
|
|
|
5
5
|
Official TypeScript SDK for integrating DApps with 0xio Wallet on Octra Network.
|
|
6
6
|
|
|
7
|
-
## What's New in v2.
|
|
7
|
+
## What's New in v2.4.0
|
|
8
8
|
|
|
9
|
-
- **
|
|
10
|
-
- **
|
|
11
|
-
- **
|
|
12
|
-
- **
|
|
9
|
+
- **Desktop/Mobile DApp Bridge**: SDK now supports running inside iframes (0xio Desktop) and WebViews (0xio App). Requests are relayed to the parent frame automatically.
|
|
10
|
+
- **Auto Frame Detection**: When `window.parent !== window`, the SDK assumes a wallet bridge is available and marks the wallet as detected.
|
|
11
|
+
- **Frame-Aware Messaging**: `postMessageToExtension()` posts to both `window` and `window.parent` when running inside a frame; `setupMessageListener()` accepts messages from `window.parent`.
|
|
12
|
+
- **walletReady via postMessage**: Extension detection now recognizes `walletReady` events from parent frames.
|
|
13
|
+
- **Fully backward compatible** — extension-based DApps work unchanged with no code changes needed.
|
|
13
14
|
|
|
14
15
|
## Installation
|
|
15
16
|
|
|
@@ -103,6 +104,42 @@ interface TransactionResult {
|
|
|
103
104
|
}
|
|
104
105
|
```
|
|
105
106
|
|
|
107
|
+
### Smart Contracts
|
|
108
|
+
|
|
109
|
+
#### `wallet.callContract(data: ContractCallData): Promise<TransactionResult>`
|
|
110
|
+
Execute a state-changing contract call. The extension signs and submits via `octra_submit`.
|
|
111
|
+
|
|
112
|
+
```typescript
|
|
113
|
+
const result = await wallet.callContract({
|
|
114
|
+
contract: 'oct26Lia...', // Contract address
|
|
115
|
+
method: 'swap', // AML method name
|
|
116
|
+
params: [100, true, 90], // Method arguments (flat, not array-wrapped)
|
|
117
|
+
amount: '0', // Native OCT to send (optional, default '0')
|
|
118
|
+
ou: '10000', // Operational units (optional, default '10000')
|
|
119
|
+
});
|
|
120
|
+
console.log('TX Hash:', result.txHash);
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
#### `wallet.contractCallView(data: ContractViewCallData): Promise<any>`
|
|
124
|
+
Read-only contract query. No signing, no approval popup, no wallet unlock required.
|
|
125
|
+
|
|
126
|
+
```typescript
|
|
127
|
+
const price = await wallet.contractCallView({
|
|
128
|
+
contract: 'oct26Lia...',
|
|
129
|
+
method: 'get_active_price',
|
|
130
|
+
params: [],
|
|
131
|
+
});
|
|
132
|
+
console.log('Price:', price);
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
#### `wallet.getContractStorage(contract: string, key: string): Promise<string | null>`
|
|
136
|
+
Read contract storage by key.
|
|
137
|
+
|
|
138
|
+
```typescript
|
|
139
|
+
const value = await wallet.getContractStorage('oct26Lia...', 'total_supply');
|
|
140
|
+
console.log('Total supply:', value);
|
|
141
|
+
```
|
|
142
|
+
|
|
106
143
|
### Message Signing
|
|
107
144
|
|
|
108
145
|
#### `wallet.signMessage(message: string): Promise<string>`
|
|
@@ -184,8 +221,8 @@ console.log(devnet.isTestnet); // true
|
|
|
184
221
|
|
|
185
222
|
// Get mainnet config
|
|
186
223
|
const mainnet = getNetworkConfig('mainnet');
|
|
187
|
-
console.log(mainnet.rpcUrl); //
|
|
188
|
-
console.log(mainnet.supportsPrivacy); //
|
|
224
|
+
console.log(mainnet.rpcUrl); // http://46.101.86.250:8080
|
|
225
|
+
console.log(mainnet.supportsPrivacy); // true
|
|
189
226
|
```
|
|
190
227
|
|
|
191
228
|
| Network | Privacy (FHE) | Explorer |
|
|
@@ -209,9 +246,22 @@ interface NetworkInfo {
|
|
|
209
246
|
}
|
|
210
247
|
```
|
|
211
248
|
|
|
249
|
+
## Desktop & Mobile Support
|
|
250
|
+
|
|
251
|
+
The SDK automatically detects when your DApp is running inside:
|
|
252
|
+
|
|
253
|
+
- **0xio Desktop's built-in browser** — Your DApp is loaded in an iframe. The SDK detects `window.parent !== window` and relays all requests to the desktop wallet via the iframe bridge.
|
|
254
|
+
- **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.
|
|
255
|
+
- **0xio Wallet Extension** — Standard browser extension communication (unchanged).
|
|
256
|
+
|
|
257
|
+
No code changes are needed for DApp developers. Just use the SDK as normal and it will auto-detect the environment and choose the correct transport.
|
|
258
|
+
|
|
212
259
|
## Requirements
|
|
213
260
|
|
|
214
|
-
- 0xio Wallet Extension v2.0.1 or higher
|
|
261
|
+
- 0xio Wallet Extension v2.0.1 or higher (Mainnet Alpha)
|
|
262
|
+
- 0xio Wallet Extension v2.2.1 or higher (Devnet — required for contract calls and privacy features)
|
|
263
|
+
- 0xio Desktop v1.0+ (for iframe bridge support)
|
|
264
|
+
- 0xio App v1.0+ (for WebView bridge support)
|
|
215
265
|
- Modern browser (Chrome, Firefox, Edge, Brave)
|
|
216
266
|
|
|
217
267
|
## Documentation
|
package/dist/index.d.ts
CHANGED
|
@@ -30,6 +30,30 @@ interface TransactionData {
|
|
|
30
30
|
readonly feeLevel?: 1 | 3;
|
|
31
31
|
readonly isPrivate?: boolean;
|
|
32
32
|
}
|
|
33
|
+
/** Flat array of AML-compatible primitive values for contract method arguments. */
|
|
34
|
+
type ContractParams = ReadonlyArray<string | number | boolean>;
|
|
35
|
+
interface ContractCallData {
|
|
36
|
+
/** Contract address (oct-prefixed, 47 chars) */
|
|
37
|
+
readonly contract: string;
|
|
38
|
+
/** Contract method name (e.g. 'swap', 'approve') */
|
|
39
|
+
readonly method: string;
|
|
40
|
+
/** Method arguments — flat primitives, NOT array-wrapped: `[amount, flag]` not `[[amount, flag]]` */
|
|
41
|
+
readonly params: ContractParams;
|
|
42
|
+
/** Native OCT to send with call (human-readable for sendTransaction, micro-units for callContract) */
|
|
43
|
+
readonly amount?: string | number;
|
|
44
|
+
/** Operation units / gas limit (default: 10000) */
|
|
45
|
+
readonly ou?: string | number;
|
|
46
|
+
}
|
|
47
|
+
interface ContractViewCallData {
|
|
48
|
+
/** Contract address (oct-prefixed, 47 chars) */
|
|
49
|
+
readonly contract: string;
|
|
50
|
+
/** Contract method name (e.g. 'balance_of', 'get_active_bin') */
|
|
51
|
+
readonly method: string;
|
|
52
|
+
/** Method arguments — flat primitives, NOT array-wrapped */
|
|
53
|
+
readonly params: ContractParams;
|
|
54
|
+
/** Caller address for view context (defaults to connected wallet) */
|
|
55
|
+
readonly caller?: string;
|
|
56
|
+
}
|
|
33
57
|
interface SignedTransaction {
|
|
34
58
|
readonly from: string;
|
|
35
59
|
readonly to_: string;
|
|
@@ -292,6 +316,20 @@ declare class ZeroXIOWallet extends EventEmitter {
|
|
|
292
316
|
* Send transaction
|
|
293
317
|
*/
|
|
294
318
|
sendTransaction(txData: TransactionData): Promise<TransactionResult>;
|
|
319
|
+
/**
|
|
320
|
+
* Call a smart contract method (state-changing).
|
|
321
|
+
* The extension builds, signs, and submits the transaction via octra_submit.
|
|
322
|
+
*/
|
|
323
|
+
callContract(callData: ContractCallData): Promise<TransactionResult>;
|
|
324
|
+
/**
|
|
325
|
+
* Read-only contract view call (no signing, no approval popup).
|
|
326
|
+
* Use this to query contract state without submitting a transaction.
|
|
327
|
+
*/
|
|
328
|
+
contractCallView(viewData: ContractViewCallData): Promise<any>;
|
|
329
|
+
/**
|
|
330
|
+
* Read contract storage by key.
|
|
331
|
+
*/
|
|
332
|
+
getContractStorage(contract: string, key: string): Promise<string | null>;
|
|
295
333
|
/**
|
|
296
334
|
* Get transaction history
|
|
297
335
|
*/
|
|
@@ -585,7 +623,7 @@ declare function createDefaultBalance(total?: number): Balance;
|
|
|
585
623
|
* SDK Configuration constants
|
|
586
624
|
*/
|
|
587
625
|
declare const SDK_CONFIG: {
|
|
588
|
-
readonly version: "2.
|
|
626
|
+
readonly version: "2.3.0";
|
|
589
627
|
readonly defaultNetworkId: "mainnet";
|
|
590
628
|
readonly communicationTimeout: 30000;
|
|
591
629
|
readonly retryAttempts: 3;
|
|
@@ -712,8 +750,9 @@ declare function createLogger(prefix: string, debug: boolean): {
|
|
|
712
750
|
groupEnd: () => void;
|
|
713
751
|
};
|
|
714
752
|
|
|
715
|
-
declare const SDK_VERSION = "2.
|
|
753
|
+
declare const SDK_VERSION = "2.3.0";
|
|
716
754
|
declare const MIN_EXTENSION_VERSION = "2.0.1";
|
|
755
|
+
declare const MIN_EXTENSION_VERSION_DEVNET = "2.2.1";
|
|
717
756
|
declare const SUPPORTED_EXTENSION_VERSIONS = "^2.0.1";
|
|
718
757
|
declare function createZeroXIOWallet(config: {
|
|
719
758
|
appName: string;
|
|
@@ -728,5 +767,5 @@ declare function checkSDKCompatibility(): {
|
|
|
728
767
|
recommendations: string[];
|
|
729
768
|
};
|
|
730
769
|
|
|
731
|
-
export { DEFAULT_NETWORK_ID, ErrorCode, EventEmitter, ExtensionCommunicator, MIN_EXTENSION_VERSION, NETWORKS, SDK_CONFIG, SDK_VERSION, SUPPORTED_EXTENSION_VERSIONS, ZeroXIOWallet, ZeroXIOWalletError, checkBrowserSupport, checkSDKCompatibility, createDefaultBalance, createErrorMessage, createLogger, createOctraWallet, createZeroXIOWallet, delay, formatAddress, formatOCT, formatTimestamp, formatTxHash, formatOCT as formatZeroXIO, fromMicroOCT, fromMicroOCT as fromMicroZeroXIO, generateMockData, getAllNetworks, getDefaultNetwork, getNetworkConfig, isBrowser, isErrorType, isValidAddress, isValidAmount, isValidFeeLevel, isValidMessage, isValidNetworkId, retry, toMicroOCT, toMicroOCT as toMicroZeroXIO, withTimeout };
|
|
732
|
-
export type { AccountChangedEvent, Balance, BalanceChangedEvent, ConnectEvent, ConnectOptions, ConnectionInfo, DisconnectEvent, ErrorEvent, ExtensionRequest, ExtensionResponse, NetworkChangedEvent, NetworkInfo, PendingPrivateTransfer, Permission, PrivateBalanceInfo, PrivateTransferData, SDKConfig, SignedTransaction, Transaction, TransactionConfirmedEvent, TransactionData, TransactionFinality, TransactionHistory, TransactionResult, WalletAddress, WalletEvent, WalletEventType };
|
|
770
|
+
export { DEFAULT_NETWORK_ID, ErrorCode, EventEmitter, ExtensionCommunicator, MIN_EXTENSION_VERSION, MIN_EXTENSION_VERSION_DEVNET, NETWORKS, SDK_CONFIG, SDK_VERSION, SUPPORTED_EXTENSION_VERSIONS, ZeroXIOWallet, ZeroXIOWalletError, checkBrowserSupport, checkSDKCompatibility, createDefaultBalance, createErrorMessage, createLogger, createOctraWallet, createZeroXIOWallet, delay, formatAddress, formatOCT, formatTimestamp, formatTxHash, formatOCT as formatZeroXIO, fromMicroOCT, fromMicroOCT as fromMicroZeroXIO, generateMockData, getAllNetworks, getDefaultNetwork, getNetworkConfig, isBrowser, isErrorType, isValidAddress, isValidAmount, isValidFeeLevel, isValidMessage, isValidNetworkId, retry, toMicroOCT, toMicroOCT as toMicroZeroXIO, withTimeout };
|
|
771
|
+
export type { AccountChangedEvent, Balance, BalanceChangedEvent, ConnectEvent, ConnectOptions, ConnectionInfo, ContractCallData, ContractParams, ContractViewCallData, DisconnectEvent, ErrorEvent, ExtensionRequest, ExtensionResponse, NetworkChangedEvent, NetworkInfo, PendingPrivateTransfer, Permission, PrivateBalanceInfo, PrivateTransferData, SDKConfig, SignedTransaction, Transaction, TransactionConfirmedEvent, TransactionData, TransactionFinality, TransactionHistory, TransactionResult, WalletAddress, WalletEvent, WalletEventType };
|
package/dist/index.esm.js
CHANGED
|
@@ -184,8 +184,8 @@ function isValidMessage(message) {
|
|
|
184
184
|
if (typeof message !== 'string') {
|
|
185
185
|
return false;
|
|
186
186
|
}
|
|
187
|
-
//
|
|
188
|
-
return message.length <=
|
|
187
|
+
// 100KB limit — contract call params can be large (serialized JSON)
|
|
188
|
+
return message.length <= 100000;
|
|
189
189
|
}
|
|
190
190
|
/**
|
|
191
191
|
* Validate fee level
|
|
@@ -394,12 +394,12 @@ function generateMockData() {
|
|
|
394
394
|
},
|
|
395
395
|
networkInfo: {
|
|
396
396
|
id: 'mainnet',
|
|
397
|
-
name: 'Octra Mainnet
|
|
398
|
-
rpcUrl: '
|
|
399
|
-
explorerUrl: 'https://octrascan.io/
|
|
400
|
-
explorerAddressUrl: 'https://octrascan.io/
|
|
401
|
-
indexerUrl: 'https://
|
|
402
|
-
supportsPrivacy:
|
|
397
|
+
name: 'Octra Mainnet',
|
|
398
|
+
rpcUrl: 'http://46.101.86.250:8080',
|
|
399
|
+
explorerUrl: 'https://lite.octrascan.io/tx.html?hash=',
|
|
400
|
+
explorerAddressUrl: 'https://lite.octrascan.io/address.html?addr=',
|
|
401
|
+
indexerUrl: 'https://lite.octrascan.io',
|
|
402
|
+
supportsPrivacy: true,
|
|
403
403
|
color: '#f59e0b',
|
|
404
404
|
isTestnet: false
|
|
405
405
|
}
|
|
@@ -411,41 +411,44 @@ function generateMockData() {
|
|
|
411
411
|
function createLogger(prefix, debug) {
|
|
412
412
|
const isDevelopment = typeof window !== 'undefined' && (window.location.hostname === 'localhost' ||
|
|
413
413
|
window.location.hostname === '127.0.0.1' ||
|
|
414
|
-
window.location.hostname.includes('dev') ||
|
|
415
414
|
window.__OCTRA_SDK_DEBUG__);
|
|
416
415
|
// Only enable logging in development mode AND when debug is explicitly enabled
|
|
417
416
|
const shouldLog = debug && isDevelopment;
|
|
417
|
+
const ts = () => {
|
|
418
|
+
const d = new Date();
|
|
419
|
+
return `${d.toTimeString().slice(0, 8)}.${String(d.getMilliseconds()).padStart(3, '0')}`;
|
|
420
|
+
};
|
|
418
421
|
return {
|
|
419
422
|
log: (...args) => {
|
|
420
423
|
if (shouldLog) {
|
|
421
|
-
console.log(`[${prefix}]`, ...args);
|
|
424
|
+
console.log(`[${ts()}][${prefix}]`, ...args);
|
|
422
425
|
}
|
|
423
426
|
},
|
|
424
427
|
warn: (...args) => {
|
|
425
428
|
if (shouldLog) {
|
|
426
|
-
console.warn(`[${prefix}]`, ...args);
|
|
429
|
+
console.warn(`[${ts()}][${prefix}]`, ...args);
|
|
427
430
|
}
|
|
428
431
|
},
|
|
429
432
|
error: (...args) => {
|
|
430
433
|
// Always show errors in development, even without debug flag
|
|
431
434
|
if (isDevelopment) {
|
|
432
|
-
console.error(`[${prefix}]`, ...args);
|
|
435
|
+
console.error(`[${ts()}][${prefix}]`, ...args);
|
|
433
436
|
}
|
|
434
437
|
},
|
|
435
438
|
debug: (...args) => {
|
|
436
439
|
if (shouldLog) {
|
|
437
|
-
console.debug(`[${prefix}]`, ...args);
|
|
440
|
+
console.debug(`[${ts()}][${prefix}]`, ...args);
|
|
438
441
|
}
|
|
439
442
|
},
|
|
440
443
|
table: (data) => {
|
|
441
444
|
if (shouldLog) {
|
|
442
|
-
console.log(`[${prefix}] Table data:`);
|
|
445
|
+
console.log(`[${ts()}][${prefix}] Table data:`);
|
|
443
446
|
console.table(data);
|
|
444
447
|
}
|
|
445
448
|
},
|
|
446
449
|
group: (label) => {
|
|
447
450
|
if (shouldLog) {
|
|
448
|
-
console.group(`[${prefix}] ${label}`);
|
|
451
|
+
console.group(`[${ts()}][${prefix}] ${label}`);
|
|
449
452
|
}
|
|
450
453
|
},
|
|
451
454
|
groupEnd: () => {
|
|
@@ -647,13 +650,14 @@ class ExtensionCommunicator extends EventEmitter {
|
|
|
647
650
|
}
|
|
648
651
|
const allowedOrigin = window.location.origin;
|
|
649
652
|
window.addEventListener('message', (event) => {
|
|
650
|
-
//
|
|
651
|
-
|
|
652
|
-
|
|
653
|
+
// Accept messages from same origin OR from parent frame (desktop/mobile bridge)
|
|
654
|
+
const isFromSameOrigin = event.origin === allowedOrigin;
|
|
655
|
+
const isFromParent = event.source === window.parent && window.parent !== window;
|
|
656
|
+
if (!isFromSameOrigin && !isFromParent) {
|
|
653
657
|
return;
|
|
654
658
|
}
|
|
655
|
-
//
|
|
656
|
-
if (event.source !== window) {
|
|
659
|
+
// Accept from same window or parent frame
|
|
660
|
+
if (event.source !== window && event.source !== window.parent) {
|
|
657
661
|
return;
|
|
658
662
|
}
|
|
659
663
|
// Check if it's a 0xio SDK response
|
|
@@ -725,12 +729,13 @@ class ExtensionCommunicator extends EventEmitter {
|
|
|
725
729
|
* Post message to extension via content script
|
|
726
730
|
*/
|
|
727
731
|
postMessageToExtension(request) {
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
window.postMessage(
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
732
|
+
const msg = { source: '0xio-sdk-request', request };
|
|
733
|
+
// Post to same window (extension content script picks it up)
|
|
734
|
+
window.postMessage(msg, window.location.origin);
|
|
735
|
+
// Also post to parent frame if in an iframe (desktop/mobile bridge picks it up)
|
|
736
|
+
if (window.parent !== window) {
|
|
737
|
+
window.parent.postMessage(msg, '*');
|
|
738
|
+
}
|
|
734
739
|
}
|
|
735
740
|
/**
|
|
736
741
|
* Check if we're in a context that can communicate with extension
|
|
@@ -825,6 +830,18 @@ class ExtensionCommunicator extends EventEmitter {
|
|
|
825
830
|
this.logger.log('Received octraWalletReady event');
|
|
826
831
|
this.isExtensionAvailableState = true;
|
|
827
832
|
});
|
|
833
|
+
// Listen for desktop/mobile bridge walletReady via postMessage
|
|
834
|
+
window.addEventListener('message', (event) => {
|
|
835
|
+
if (event.data?.source === '0xio-sdk-bridge' && event.data?.event?.type === 'walletReady') {
|
|
836
|
+
this.logger.log('Received walletReady via postMessage (desktop/mobile bridge)');
|
|
837
|
+
this.isExtensionAvailableState = true;
|
|
838
|
+
}
|
|
839
|
+
});
|
|
840
|
+
// Also detect if running inside a frame with a wallet bridge parent
|
|
841
|
+
if (window.parent !== window) {
|
|
842
|
+
this.logger.log('Running inside a frame — checking for parent wallet bridge');
|
|
843
|
+
this.isExtensionAvailableState = true;
|
|
844
|
+
}
|
|
828
845
|
// Initial check (in case extension was already injected)
|
|
829
846
|
this.checkExtensionAvailability();
|
|
830
847
|
// Set up periodic checks as fallback
|
|
@@ -984,12 +1001,12 @@ class ExtensionCommunicator extends EventEmitter {
|
|
|
984
1001
|
const NETWORKS = {
|
|
985
1002
|
'mainnet': {
|
|
986
1003
|
id: 'mainnet',
|
|
987
|
-
name: 'Octra Mainnet
|
|
988
|
-
rpcUrl: '
|
|
989
|
-
explorerUrl: 'https://octrascan.io/
|
|
990
|
-
explorerAddressUrl: 'https://octrascan.io/
|
|
991
|
-
indexerUrl: 'https://
|
|
992
|
-
supportsPrivacy:
|
|
1004
|
+
name: 'Octra Mainnet',
|
|
1005
|
+
rpcUrl: 'http://46.101.86.250:8080',
|
|
1006
|
+
explorerUrl: 'https://lite.octrascan.io/tx.html?hash=',
|
|
1007
|
+
explorerAddressUrl: 'https://lite.octrascan.io/address.html?addr=',
|
|
1008
|
+
indexerUrl: 'https://lite.octrascan.io',
|
|
1009
|
+
supportsPrivacy: true,
|
|
993
1010
|
color: '#f59e0b',
|
|
994
1011
|
isTestnet: false
|
|
995
1012
|
},
|
|
@@ -1023,7 +1040,7 @@ const DEFAULT_NETWORK_ID = 'mainnet';
|
|
|
1023
1040
|
function getNetworkConfig(networkId = DEFAULT_NETWORK_ID) {
|
|
1024
1041
|
const network = NETWORKS[networkId];
|
|
1025
1042
|
if (!network) {
|
|
1026
|
-
throw new
|
|
1043
|
+
throw new ZeroXIOWalletError(ErrorCode.NETWORK_ERROR, `Unknown network ID: ${networkId}`);
|
|
1027
1044
|
}
|
|
1028
1045
|
return network;
|
|
1029
1046
|
}
|
|
@@ -1052,7 +1069,7 @@ function createDefaultBalance(total = 0) {
|
|
|
1052
1069
|
* SDK Configuration constants
|
|
1053
1070
|
*/
|
|
1054
1071
|
const SDK_CONFIG = {
|
|
1055
|
-
version: '2.
|
|
1072
|
+
version: '2.3.0',
|
|
1056
1073
|
defaultNetworkId: DEFAULT_NETWORK_ID,
|
|
1057
1074
|
communicationTimeout: 30000, // 30 seconds
|
|
1058
1075
|
retryAttempts: 3,
|
|
@@ -1360,6 +1377,78 @@ class ZeroXIOWallet extends EventEmitter {
|
|
|
1360
1377
|
throw new ZeroXIOWalletError(ErrorCode.TRANSACTION_FAILED, 'Failed to send transaction', error);
|
|
1361
1378
|
}
|
|
1362
1379
|
}
|
|
1380
|
+
/**
|
|
1381
|
+
* Call a smart contract method (state-changing).
|
|
1382
|
+
* The extension builds, signs, and submits the transaction via octra_submit.
|
|
1383
|
+
*/
|
|
1384
|
+
async callContract(callData) {
|
|
1385
|
+
this.ensureConnected();
|
|
1386
|
+
try {
|
|
1387
|
+
this.logger.log('Calling contract:', callData);
|
|
1388
|
+
const result = await this.communicator.sendRequest('call_contract', {
|
|
1389
|
+
contract: callData.contract,
|
|
1390
|
+
method: callData.method,
|
|
1391
|
+
params: callData.params,
|
|
1392
|
+
amount: callData.amount != null ? String(callData.amount) : '0',
|
|
1393
|
+
ou: callData.ou != null ? String(callData.ou) : '10000',
|
|
1394
|
+
});
|
|
1395
|
+
this.logger.log('Contract call result:', result);
|
|
1396
|
+
return result;
|
|
1397
|
+
}
|
|
1398
|
+
catch (error) {
|
|
1399
|
+
this.logger.error('Contract call failed:', error);
|
|
1400
|
+
if (error instanceof ZeroXIOWalletError) {
|
|
1401
|
+
throw error;
|
|
1402
|
+
}
|
|
1403
|
+
throw new ZeroXIOWalletError(ErrorCode.TRANSACTION_FAILED, 'Failed to call contract', error);
|
|
1404
|
+
}
|
|
1405
|
+
}
|
|
1406
|
+
/**
|
|
1407
|
+
* Read-only contract view call (no signing, no approval popup).
|
|
1408
|
+
* Use this to query contract state without submitting a transaction.
|
|
1409
|
+
*/
|
|
1410
|
+
async contractCallView(viewData) {
|
|
1411
|
+
this.ensureInitialized();
|
|
1412
|
+
try {
|
|
1413
|
+
this.logger.log('Contract view call:', viewData);
|
|
1414
|
+
const result = await this.communicator.sendRequest('contract_call_view', {
|
|
1415
|
+
contract: viewData.contract,
|
|
1416
|
+
method: viewData.method,
|
|
1417
|
+
params: viewData.params,
|
|
1418
|
+
caller: viewData.caller || this.getAddress() || '',
|
|
1419
|
+
});
|
|
1420
|
+
this.logger.log('Contract view result:', result);
|
|
1421
|
+
return result;
|
|
1422
|
+
}
|
|
1423
|
+
catch (error) {
|
|
1424
|
+
this.logger.error('Contract view call failed:', error);
|
|
1425
|
+
if (error instanceof ZeroXIOWalletError) {
|
|
1426
|
+
throw error;
|
|
1427
|
+
}
|
|
1428
|
+
throw new ZeroXIOWalletError(ErrorCode.NETWORK_ERROR, 'Failed to call contract view', error);
|
|
1429
|
+
}
|
|
1430
|
+
}
|
|
1431
|
+
/**
|
|
1432
|
+
* Read contract storage by key.
|
|
1433
|
+
*/
|
|
1434
|
+
async getContractStorage(contract, key) {
|
|
1435
|
+
this.ensureInitialized();
|
|
1436
|
+
try {
|
|
1437
|
+
this.logger.log('Getting contract storage:', { contract, key });
|
|
1438
|
+
const result = await this.communicator.sendRequest('get_contract_storage', {
|
|
1439
|
+
contract,
|
|
1440
|
+
key,
|
|
1441
|
+
});
|
|
1442
|
+
return result;
|
|
1443
|
+
}
|
|
1444
|
+
catch (error) {
|
|
1445
|
+
this.logger.error('Get contract storage failed:', error);
|
|
1446
|
+
if (error instanceof ZeroXIOWalletError) {
|
|
1447
|
+
throw error;
|
|
1448
|
+
}
|
|
1449
|
+
throw new ZeroXIOWalletError(ErrorCode.NETWORK_ERROR, 'Failed to get contract storage', error);
|
|
1450
|
+
}
|
|
1451
|
+
}
|
|
1363
1452
|
/**
|
|
1364
1453
|
* Get transaction history
|
|
1365
1454
|
*/
|
|
@@ -1500,6 +1589,9 @@ class ZeroXIOWallet extends EventEmitter {
|
|
|
1500
1589
|
if (!message || typeof message !== 'string') {
|
|
1501
1590
|
throw new ZeroXIOWalletError(ErrorCode.SIGNATURE_FAILED, 'Message must be a non-empty string');
|
|
1502
1591
|
}
|
|
1592
|
+
if (message.length > 10000) {
|
|
1593
|
+
throw new ZeroXIOWalletError(ErrorCode.SIGNATURE_FAILED, 'Message too long (max 10,000 characters)');
|
|
1594
|
+
}
|
|
1503
1595
|
try {
|
|
1504
1596
|
this.logger.log('Requesting message signature for:', message.substring(0, 100) + (message.length > 100 ? '...' : ''));
|
|
1505
1597
|
const result = await this.communicator.sendRequest('signMessage', { message });
|
|
@@ -1564,7 +1656,7 @@ class ZeroXIOWallet extends EventEmitter {
|
|
|
1564
1656
|
const accountChangedEvent = {
|
|
1565
1657
|
previousAddress,
|
|
1566
1658
|
newAddress: data.address,
|
|
1567
|
-
balance: data.balance
|
|
1659
|
+
balance: data.balance ?? this.connectionInfo.balance
|
|
1568
1660
|
};
|
|
1569
1661
|
this.emit('accountChanged', accountChangedEvent);
|
|
1570
1662
|
this.logger.log('Account changed:', accountChangedEvent);
|
|
@@ -1678,8 +1770,9 @@ var wallet = /*#__PURE__*/Object.freeze({
|
|
|
1678
1770
|
*/
|
|
1679
1771
|
// Main exports
|
|
1680
1772
|
// Version information
|
|
1681
|
-
const SDK_VERSION = '2.
|
|
1682
|
-
const MIN_EXTENSION_VERSION = '2.0.1';
|
|
1773
|
+
const SDK_VERSION = '2.3.0';
|
|
1774
|
+
const MIN_EXTENSION_VERSION = '2.0.1'; // Mainnet Alpha
|
|
1775
|
+
const MIN_EXTENSION_VERSION_DEVNET = '2.2.1'; // Devnet (contract calls, privacy)
|
|
1683
1776
|
const SUPPORTED_EXTENSION_VERSIONS = '^2.0.1'; // Supports all versions >= 2.0.1
|
|
1684
1777
|
// Quick setup function for simple use cases
|
|
1685
1778
|
async function createZeroXIOWallet(config) {
|
|
@@ -1733,8 +1826,7 @@ if (typeof window !== 'undefined') {
|
|
|
1733
1826
|
window.__ZEROXIO_SDK_VERSION__ = SDK_VERSION;
|
|
1734
1827
|
// Development mode detection
|
|
1735
1828
|
const isDevelopment = window.location.hostname === 'localhost' ||
|
|
1736
|
-
window.location.hostname === '127.0.0.1'
|
|
1737
|
-
window.location.hostname.includes('dev');
|
|
1829
|
+
window.location.hostname === '127.0.0.1';
|
|
1738
1830
|
if (isDevelopment) {
|
|
1739
1831
|
// Set debug flag but don't automatically log
|
|
1740
1832
|
window.__OCTRA_SDK_DEBUG__ = true;
|
|
@@ -1762,7 +1854,7 @@ if (typeof window !== 'undefined') {
|
|
|
1762
1854
|
window.postMessage({
|
|
1763
1855
|
source: '0xio-sdk-bridge',
|
|
1764
1856
|
event: { type: eventType, data }
|
|
1765
|
-
},
|
|
1857
|
+
}, window.location.origin);
|
|
1766
1858
|
console.log('[0xio SDK] Simulated extension event:', eventType, data);
|
|
1767
1859
|
},
|
|
1768
1860
|
showWelcome: () => {
|
|
@@ -1779,5 +1871,5 @@ if (typeof window !== 'undefined') {
|
|
|
1779
1871
|
}
|
|
1780
1872
|
}
|
|
1781
1873
|
|
|
1782
|
-
export { DEFAULT_NETWORK_ID, ErrorCode, EventEmitter, ExtensionCommunicator, MIN_EXTENSION_VERSION, NETWORKS, SDK_CONFIG, SDK_VERSION, SUPPORTED_EXTENSION_VERSIONS, ZeroXIOWallet, ZeroXIOWalletError, checkBrowserSupport, checkSDKCompatibility, createDefaultBalance, createErrorMessage, createLogger, createOctraWallet, createZeroXIOWallet, delay, formatAddress, formatOCT, formatTimestamp, formatTxHash, formatOCT as formatZeroXIO, fromMicroOCT, fromMicroOCT as fromMicroZeroXIO, generateMockData, getAllNetworks, getDefaultNetwork, getNetworkConfig, isBrowser, isErrorType, isValidAddress, isValidAmount, isValidFeeLevel, isValidMessage, isValidNetworkId, retry, toMicroOCT, toMicroOCT as toMicroZeroXIO, withTimeout };
|
|
1874
|
+
export { DEFAULT_NETWORK_ID, ErrorCode, EventEmitter, ExtensionCommunicator, MIN_EXTENSION_VERSION, MIN_EXTENSION_VERSION_DEVNET, NETWORKS, SDK_CONFIG, SDK_VERSION, SUPPORTED_EXTENSION_VERSIONS, ZeroXIOWallet, ZeroXIOWalletError, checkBrowserSupport, checkSDKCompatibility, createDefaultBalance, createErrorMessage, createLogger, createOctraWallet, createZeroXIOWallet, delay, formatAddress, formatOCT, formatTimestamp, formatTxHash, formatOCT as formatZeroXIO, fromMicroOCT, fromMicroOCT as fromMicroZeroXIO, generateMockData, getAllNetworks, getDefaultNetwork, getNetworkConfig, isBrowser, isErrorType, isValidAddress, isValidAmount, isValidFeeLevel, isValidMessage, isValidNetworkId, retry, toMicroOCT, toMicroOCT as toMicroZeroXIO, withTimeout };
|
|
1783
1875
|
//# sourceMappingURL=index.esm.js.map
|