@sodax/wallet-sdk-react 1.5.7-beta → 2.0.0-rc.10
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 +107 -142
- package/dist/XConnector-12q0OVe5.d.ts +146 -0
- package/dist/chunk-7V7O3Q7Y.mjs +62 -0
- package/dist/chunk-C6M34IVL.mjs +86 -0
- package/dist/chunk-DQTYAMKF.mjs +1609 -0
- package/dist/chunk-FSOGMSJH.mjs +39 -0
- package/dist/chunk-IFXZQW4C.mjs +98 -0
- package/dist/chunk-JQ4H4GJ5.mjs +100 -0
- package/dist/chunk-LKSSME2J.mjs +31 -0
- package/dist/chunk-MWWVB7TD.mjs +123 -0
- package/dist/chunk-NAKCAL2M.mjs +32 -0
- package/dist/chunk-OPYSVPRW.mjs +144 -0
- package/dist/chunk-QMXBY3UI.mjs +1 -0
- package/dist/chunk-TACW7Z4D.mjs +31 -0
- package/dist/chunk-WPZOLGVB.mjs +148 -0
- package/dist/chunk-X7BHR7WS.mjs +200 -0
- package/dist/chunk-Z5GXDHGL.mjs +190 -0
- package/dist/config-DEsqgrG1.d.ts +151 -0
- package/dist/index.d.ts +768 -1498
- package/dist/index.mjs +453 -2005
- package/dist/xchains/bitcoin/index.d.ts +125 -0
- package/dist/xchains/bitcoin/index.mjs +14 -0
- package/dist/xchains/evm/index.d.ts +39 -0
- package/dist/xchains/evm/index.mjs +3 -0
- package/dist/xchains/icon/index.d.ts +37 -0
- package/dist/xchains/icon/index.mjs +5 -0
- package/dist/xchains/injective/index.d.ts +35 -0
- package/dist/xchains/injective/index.mjs +3 -0
- package/dist/xchains/near/index.d.ts +34 -0
- package/dist/xchains/near/index.mjs +4 -0
- package/dist/xchains/solana/index.d.ts +26 -0
- package/dist/xchains/solana/index.mjs +5 -0
- package/dist/xchains/stacks/index.d.ts +42 -0
- package/dist/xchains/stacks/index.mjs +3 -0
- package/dist/xchains/stellar/index.d.ts +44 -0
- package/dist/xchains/stellar/index.mjs +4 -0
- package/dist/xchains/sui/index.d.ts +37 -0
- package/dist/xchains/sui/index.mjs +5 -0
- package/docs/ADDING_A_NEW_CHAIN.md +440 -0
- package/docs/ARCHITECTURE.md +291 -0
- package/docs/BATCH_OPERATIONS.md +267 -0
- package/docs/CHAIN_DETECTION.md +216 -0
- package/docs/CONFIGURE_PROVIDER.md +360 -0
- package/docs/CONNECTORS.md +247 -0
- package/docs/CONNECT_FLOW.md +276 -0
- package/docs/EVM_SWITCH_CHAIN.md +161 -0
- package/docs/SIGN_MESSAGE.md +213 -0
- package/docs/SUB_PATH_EXPORTS.md +218 -0
- package/docs/WALLETCONNECT.md +154 -0
- package/docs/WALLET_MODAL.md +331 -0
- package/docs/WALLET_PROVIDER_BRIDGE.md +226 -0
- package/package.json +56 -22
- package/dist/index.cjs +0 -2147
- package/dist/index.cjs.map +0 -1
- package/dist/index.d.cts +0 -1579
- package/dist/index.mjs.map +0 -1
- package/src/Hydrate.ts +0 -65
- package/src/SodaxWalletProvider.tsx +0 -97
- package/src/actions/getXChainType.ts +0 -8
- package/src/actions/getXService.ts +0 -33
- package/src/actions/index.ts +0 -2
- package/src/assets/wallets/hana.svg +0 -6
- package/src/assets/wallets/havah.svg +0 -76
- package/src/assets/wallets/keplr.svg +0 -30
- package/src/assets/wallets/metamask.svg +0 -60
- package/src/assets/wallets/phantom.svg +0 -4
- package/src/assets/wallets/sui.svg +0 -20
- package/src/core/XConnector.ts +0 -54
- package/src/core/XService.ts +0 -85
- package/src/core/index.ts +0 -2
- package/src/hooks/index.ts +0 -11
- package/src/hooks/useEthereumChainId.ts +0 -44
- package/src/hooks/useEvmSwitchChain.ts +0 -91
- package/src/hooks/useWalletProvider.ts +0 -206
- package/src/hooks/useXAccount.ts +0 -51
- package/src/hooks/useXAccounts.ts +0 -56
- package/src/hooks/useXBalances.ts +0 -65
- package/src/hooks/useXConnect.ts +0 -118
- package/src/hooks/useXConnection.ts +0 -72
- package/src/hooks/useXConnectors.ts +0 -72
- package/src/hooks/useXDisconnect.ts +0 -73
- package/src/hooks/useXService.ts +0 -8
- package/src/hooks/useXSignMessage.ts +0 -82
- package/src/index.ts +0 -19
- package/src/types/index.ts +0 -22
- package/src/useXWagmiStore.ts +0 -116
- package/src/utils/index.ts +0 -21
- package/src/xchains/bitcoin/BitcoinXConnector.ts +0 -34
- package/src/xchains/bitcoin/BitcoinXService.ts +0 -40
- package/src/xchains/bitcoin/OKXXConnector.ts +0 -117
- package/src/xchains/bitcoin/UnisatXConnector.ts +0 -117
- package/src/xchains/bitcoin/XverseXConnector.ts +0 -232
- package/src/xchains/bitcoin/index.ts +0 -7
- package/src/xchains/bitcoin/useBitcoinXConnectors.ts +0 -14
- package/src/xchains/evm/EvmXConnector.ts +0 -27
- package/src/xchains/evm/EvmXService.ts +0 -211
- package/src/xchains/evm/index.ts +0 -3
- package/src/xchains/icon/IconHanaXConnector.ts +0 -39
- package/src/xchains/icon/IconXService.ts +0 -117
- package/src/xchains/icon/actions.ts +0 -28
- package/src/xchains/icon/iconex/index.tsx +0 -46
- package/src/xchains/icon/index.ts +0 -2
- package/src/xchains/injective/InjectiveXConnector.ts +0 -60
- package/src/xchains/injective/InjectiveXService.ts +0 -62
- package/src/xchains/injective/actions.ts +0 -32
- package/src/xchains/injective/index.ts +0 -2
- package/src/xchains/near/NearXConnector.ts +0 -42
- package/src/xchains/near/NearXService.ts +0 -46
- package/src/xchains/near/useNearXConnectors.ts +0 -23
- package/src/xchains/solana/SolanaXConnector.ts +0 -26
- package/src/xchains/solana/SolanaXService.ts +0 -46
- package/src/xchains/solana/index.ts +0 -2
- package/src/xchains/stacks/StacksXConnector.ts +0 -63
- package/src/xchains/stacks/StacksXService.ts +0 -59
- package/src/xchains/stacks/constants.ts +0 -42
- package/src/xchains/stacks/index.ts +0 -4
- package/src/xchains/stacks/useStacksXConnectors.ts +0 -7
- package/src/xchains/stellar/CustomSorobanServer.ts +0 -93
- package/src/xchains/stellar/StellarWalletsKitXConnector.ts +0 -53
- package/src/xchains/stellar/StellarXService.ts +0 -93
- package/src/xchains/stellar/actions.ts +0 -24
- package/src/xchains/stellar/index.tsx +0 -2
- package/src/xchains/stellar/useStellarXConnectors.ts +0 -21
- package/src/xchains/stellar/utils.ts +0 -49
- package/src/xchains/sui/SuiXConnector.ts +0 -28
- package/src/xchains/sui/SuiXService.ts +0 -66
- package/src/xchains/sui/index.ts +0 -2
package/README.md
CHANGED
|
@@ -1,80 +1,73 @@
|
|
|
1
1
|
# @sodax/wallet-sdk-react
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
React layer over [`@sodax/wallet-sdk-core`](https://github.com/icon-project/sodax-sdks/blob/main/packages/wallet-sdk-core/README.md) — wallet connection, signing, and account management for the SODAX cross-chain ecosystem. Hooks read from a single Zustand store; per-chain native SDKs (wagmi, `@solana/wallet-adapter`, `@mysten/dapp-kit`, …) are wrapped behind a uniform `IXService` / `IXConnector` interface.
|
|
4
4
|
|
|
5
5
|
## Features
|
|
6
|
-
- Seamless wallet connectivity for all supported wallets in the Sodax network
|
|
7
|
-
- EVM Wallets: All browser extensions that support [EIP-6963](https://eips.ethereum.org/EIPS/eip-6963) (Hana Wallet, MetaMask, Phantom, etc.) ✅
|
|
8
|
-
- Sui Wallets: All browser extension that @mysten/dapp-kit supports (Hana, Sui Wallet, Suiet, etc.) ✅
|
|
9
|
-
- Solana Wallets: ✅
|
|
10
|
-
- Stellar Wallets: ✅
|
|
11
|
-
- Injective Wallets: ✅
|
|
12
|
-
- ICON Wallets: ✅ (Hana Wallet and other ICON-compatible extensions)
|
|
13
|
-
|
|
14
|
-
- Address and connection state management
|
|
15
|
-
- EVM (Arbitrum, Avalanche, Base, BSC, Optimism, Polygon, Sonic, HyperEVM, LightLink, Ethereum, Redbelly, Kaia) ✅
|
|
16
|
-
- Sui ✅
|
|
17
|
-
- Solana ✅
|
|
18
|
-
- Stellar ✅
|
|
19
|
-
- Injective ✅
|
|
20
|
-
- ICON ✅
|
|
21
6
|
|
|
7
|
+
- **Unified wallet connectivity** for 9 chain families across 20 chains
|
|
8
|
+
- EVM (Sonic hub, Ethereum, Arbitrum, Base, BSC, Optimism, Polygon, Avalanche, HyperEVM, Lightlink, Redbelly, Kaia) — EIP-6963 + WalletConnect
|
|
9
|
+
- Solana, Sui, Stellar, ICON, Injective, Bitcoin, NEAR, Stacks
|
|
10
|
+
- **Single-store state** — `useXAccount`, `useXConnection`, `useXAccounts` all read the same Zustand slice; persisted to `localStorage`
|
|
11
|
+
- **Bridge to `@sodax/sdk`** — `useWalletProvider` returns a typed `IXxxWalletProvider` ready to plug into any SDK call
|
|
12
|
+
- **Headless wallet modal** — `useWalletModal` state machine (chainSelect → walletSelect → connecting → success | error), render-agnostic
|
|
13
|
+
- **Batch operations** — connect/disconnect every chain a wallet identifier covers, in sequence
|
|
14
|
+
- **WalletConnect** — opt-in for enterprise custody (Fireblocks, etc.) via `config.EVM.walletConnect`
|
|
22
15
|
|
|
23
16
|
## Installation
|
|
24
17
|
|
|
25
18
|
```bash
|
|
26
|
-
|
|
19
|
+
pnpm add @sodax/wallet-sdk-react
|
|
20
|
+
# or
|
|
27
21
|
npm install @sodax/wallet-sdk-react
|
|
28
|
-
|
|
29
|
-
# Using yarn
|
|
22
|
+
# or
|
|
30
23
|
yarn add @sodax/wallet-sdk-react
|
|
31
|
-
|
|
32
|
-
# Using pnpm
|
|
33
|
-
pnpm add @sodax/wallet-sdk-react
|
|
34
24
|
```
|
|
35
25
|
|
|
36
|
-
## Peer
|
|
37
|
-
|
|
38
|
-
This package requires the following peer dependencies:
|
|
26
|
+
## Peer dependencies
|
|
39
27
|
|
|
40
28
|
```json
|
|
41
29
|
{
|
|
42
30
|
"react": ">=19",
|
|
43
|
-
"@tanstack/react-query": "
|
|
31
|
+
"@tanstack/react-query": "5.x"
|
|
44
32
|
}
|
|
45
33
|
```
|
|
46
34
|
|
|
47
|
-
## Quick
|
|
35
|
+
## Quick start
|
|
48
36
|
|
|
49
|
-
```
|
|
50
|
-
import {
|
|
37
|
+
```tsx
|
|
38
|
+
import {
|
|
39
|
+
SodaxWalletProvider,
|
|
40
|
+
type SodaxWalletConfig,
|
|
41
|
+
useXAccount,
|
|
42
|
+
useXConnect,
|
|
43
|
+
useXConnectors,
|
|
44
|
+
} from '@sodax/wallet-sdk-react';
|
|
51
45
|
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
|
|
52
|
-
import
|
|
46
|
+
import { ChainKeys } from '@sodax/types';
|
|
53
47
|
|
|
54
|
-
// Create a QueryClient instance
|
|
55
48
|
const queryClient = new QueryClient();
|
|
56
49
|
|
|
57
|
-
const
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
50
|
+
const config: SodaxWalletConfig = {
|
|
51
|
+
EVM: {
|
|
52
|
+
ssr: true,
|
|
53
|
+
chains: {
|
|
54
|
+
[ChainKeys.SONIC_MAINNET]: { rpcUrl: 'https://rpc.soniclabs.com' },
|
|
55
|
+
[ChainKeys.ETHEREUM_MAINNET]: { rpcUrl: 'https://ethereum-rpc.publicnode.com' },
|
|
56
|
+
},
|
|
57
|
+
// Optional: add WalletConnect support (requires wc projectId)
|
|
58
|
+
// walletConnect: { projectId: '...' },
|
|
59
|
+
},
|
|
60
|
+
ICON: {
|
|
61
|
+
chains: {
|
|
62
|
+
[ChainKeys.ICON_MAINNET]: { rpcUrl: 'https://ctz.solidwallet.io/api/v3' },
|
|
63
|
+
},
|
|
64
|
+
},
|
|
72
65
|
};
|
|
73
66
|
|
|
74
67
|
function App() {
|
|
75
68
|
return (
|
|
76
69
|
<QueryClientProvider client={queryClient}>
|
|
77
|
-
<SodaxWalletProvider
|
|
70
|
+
<SodaxWalletProvider config={config}>
|
|
78
71
|
<WalletConnect />
|
|
79
72
|
</SodaxWalletProvider>
|
|
80
73
|
</QueryClientProvider>
|
|
@@ -82,132 +75,104 @@ function App() {
|
|
|
82
75
|
}
|
|
83
76
|
|
|
84
77
|
function WalletConnect() {
|
|
85
|
-
|
|
86
|
-
const connectors = useXConnectors('EVM');
|
|
87
|
-
|
|
88
|
-
// Get connect mutation
|
|
78
|
+
const connectors = useXConnectors({ xChainType: 'EVM' });
|
|
89
79
|
const { mutateAsync: connect } = useXConnect();
|
|
80
|
+
const account = useXAccount({ xChainType: 'EVM' });
|
|
90
81
|
|
|
91
|
-
|
|
92
|
-
|
|
82
|
+
if (account.address) {
|
|
83
|
+
return <p>Connected: {account.address}</p>;
|
|
84
|
+
}
|
|
93
85
|
|
|
94
86
|
return (
|
|
95
|
-
<div
|
|
96
|
-
{
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
)}
|
|
103
|
-
|
|
104
|
-
{/* Display available connectors */}
|
|
105
|
-
<div className="space-y-2">
|
|
106
|
-
{connectors.map((connector) => (
|
|
107
|
-
<button
|
|
108
|
-
key={connector.id}
|
|
109
|
-
onClick={() => connect(connector)}
|
|
110
|
-
className="flex items-center gap-2 p-2 border rounded-lg hover:bg-gray-50"
|
|
111
|
-
>
|
|
112
|
-
<img
|
|
113
|
-
src={connector.icon}
|
|
114
|
-
alt={connector.name}
|
|
115
|
-
width={24}
|
|
116
|
-
height={24}
|
|
117
|
-
className="rounded-md"
|
|
118
|
-
/>
|
|
119
|
-
<span>Connect {connector.name}</span>
|
|
120
|
-
</button>
|
|
121
|
-
))}
|
|
122
|
-
</div>
|
|
87
|
+
<div>
|
|
88
|
+
{connectors.map(connector => (
|
|
89
|
+
<button key={connector.id} onClick={() => connect(connector)}>
|
|
90
|
+
{connector.icon && <img src={connector.icon} alt="" width={20} height={20} />}
|
|
91
|
+
{connector.name}
|
|
92
|
+
</button>
|
|
93
|
+
))}
|
|
123
94
|
</div>
|
|
124
95
|
);
|
|
125
96
|
}
|
|
126
97
|
```
|
|
127
98
|
|
|
128
|
-
|
|
129
|
-
1. Setting up the required providers (`QueryClientProvider` and `SodaxWalletProvider`)
|
|
130
|
-
2. Using `useXConnectors` to get available wallet connectors
|
|
131
|
-
3. Using `useXConnect` to handle wallet connections
|
|
132
|
-
4. Using `useXAccount` to display the connected wallet address
|
|
133
|
-
5. A basic UI to display and connect to available wallets
|
|
134
|
-
|
|
99
|
+
## Documentation
|
|
135
100
|
|
|
136
|
-
|
|
101
|
+
The full guide lives in [`docs/`](docs/). Start with the topic that matches what you're building.
|
|
137
102
|
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
-
|
|
103
|
+
| Topic | What it covers |
|
|
104
|
+
|-------|----------------|
|
|
105
|
+
| [Configure SodaxWalletProvider](docs/CONFIGURE_PROVIDER.md) | `SodaxWalletConfig` shape, opt-in chain mounting, per-chain RPC + wallet defaults, breaking changes from v1 |
|
|
106
|
+
| [Connect Flow](docs/CONNECT_FLOW.md) | Discover connectors, connect, read account, disconnect; provider-managed vs non-provider chains; persisted reconnect |
|
|
107
|
+
| [Wallet Provider Bridge](docs/WALLET_PROVIDER_BRIDGE.md) | `useWalletProvider` → typed `IXxxWalletProvider` for `@sodax/sdk` calls; `useXService` / `useXServices` |
|
|
108
|
+
| [Wallet Modal](docs/WALLET_MODAL.md) | Headless state machine for multi-chain modal UIs; `useConnectionFlow` non-modal alternative |
|
|
109
|
+
| [WalletConnect](docs/WALLETCONNECT.md) | Enterprise custody integration (Fireblocks, Ledger); `qrModalOptions` filtering |
|
|
110
|
+
| [Batch Operations](docs/BATCH_OPERATIONS.md) | Sequential multi-chain connect/disconnect by wallet identifier |
|
|
111
|
+
| [Chain Detection](docs/CHAIN_DETECTION.md) | `useChainGroups`, `useConnectedChains`, `useIsWalletInstalled`, `useEnabledChains`; hydration status |
|
|
112
|
+
| [Sign Message](docs/SIGN_MESSAGE.md) | `useXSignMessage` cross-chain; Bitcoin BIP-322 vs ECDSA auto-detect |
|
|
113
|
+
| [EVM Switch Chain](docs/EVM_SWITCH_CHAIN.md) | Single wagmi connection across all configured EVM networks |
|
|
114
|
+
| [Connectors](docs/CONNECTORS.md) | `IXConnector` contract, deep-import concrete classes, custom connectors |
|
|
115
|
+
| [Architecture](docs/ARCHITECTURE.md) | Zustand store, Provider/Hydrator/Actions trio, persist hydration caveat |
|
|
116
|
+
| [Adding a New Chain](https://github.com/icon-project/sodax-sdks/blob/main/packages/wallet-sdk-react/docs/ADDING_A_NEW_CHAIN.md) | `ChainMeta` extension, chain registry, sub-path export wiring |
|
|
141
117
|
|
|
118
|
+
## AI agent docs
|
|
142
119
|
|
|
143
|
-
|
|
120
|
+
AI-readable docs for `@sodax/wallet-sdk-react` (and the other `@sodax/*` packages) are shipped via [`@sodax/skills`](https://github.com/icon-project/sodax-sdks/tree/main/packages/skills) — a separate npm package bundling Claude-Code SKILL.md files and a long-form knowledge tree.
|
|
144
121
|
|
|
145
|
-
|
|
122
|
+
**Recommended: [`skills` CLI](https://github.com/vercel-labs/skills)** — from your project root:
|
|
146
123
|
|
|
147
|
-
|
|
124
|
+
```bash
|
|
125
|
+
npx skills@latest add icon-project/sodax-sdks/packages/skills
|
|
126
|
+
```
|
|
148
127
|
|
|
149
|
-
|
|
128
|
+
**npm + `AGENTS.md` pointer** (fallback for web chats, or when you prefer a devDependency over the CLI):
|
|
150
129
|
|
|
151
|
-
|
|
152
|
-
-
|
|
153
|
-
|
|
154
|
-
- [`useXAccount`](https://github.com/icon-project/sodax-frontend/tree/main/packages/wallet-sdk-react/src/hooks/useXAccount.ts) - Get account information
|
|
155
|
-
- [`useXDisconnect`](https://github.com/icon-project/sodax-frontend/tree/main/packages/wallet-sdk-react/src/hooks/useXDisconnect.ts) - Disconnect from a wallet
|
|
130
|
+
```bash
|
|
131
|
+
pnpm add -D @sodax/skills
|
|
132
|
+
```
|
|
156
133
|
|
|
157
|
-
|
|
158
|
-
- [`useEvmSwitchChain`](https://github.com/icon-project/sodax-frontend/tree/main/packages/wallet-sdk-react/src/hooks/evm/useEvmSwitchChain.ts) - Switch between EVM chains
|
|
134
|
+
Then point your agent at `node_modules/@sodax/skills/AGENTS.md`. See [docs/ai-integration-guide.md](https://github.com/icon-project/sodax-sdks/blob/main/docs/ai-integration-guide.md) for all install modes and per-tool wiring.
|
|
159
135
|
|
|
160
|
-
|
|
161
|
-
- [`useXBalances`](https://github.com/icon-project/sodax-frontend/tree/main/packages/wallet-sdk-react/src/hooks/useXBalances.ts) - Fetch token balances
|
|
136
|
+
---
|
|
162
137
|
|
|
163
|
-
|
|
164
|
-
- [`useXService`](https://github.com/icon-project/sodax-frontend/tree/main/packages/wallet-sdk-react/src/hooks/useXService.ts) - Access chain-specific service
|
|
138
|
+
## Sub-path exports
|
|
165
139
|
|
|
166
|
-
|
|
140
|
+
Concrete connector / service classes are **not** exported from the package barrel — they live behind sub-path imports to prevent accidental coupling to internals:
|
|
167
141
|
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
- [`XConnector`](https://github.com/icon-project/sodax-frontend/tree/main/packages/wallet-sdk-react/src/types/index.ts) - Wallet connector type
|
|
172
|
-
- [`XToken`](https://github.com/icon-project/sodax-frontend/tree/main/packages/wallet-sdk-react/src/types/index.ts) - Cross-chain token type
|
|
142
|
+
```typescript
|
|
143
|
+
// ✅ Normal usage — barrel import
|
|
144
|
+
import { useXConnect, useXAccount, type IXConnector } from '@sodax/wallet-sdk-react';
|
|
173
145
|
|
|
174
|
-
|
|
146
|
+
// ✅ Advanced — concrete class via deep import
|
|
147
|
+
import { XverseXConnector } from '@sodax/wallet-sdk-react/xchains/bitcoin';
|
|
148
|
+
if (connector instanceof XverseXConnector) {
|
|
149
|
+
connector.setAddressPurpose('payment');
|
|
150
|
+
}
|
|
151
|
+
```
|
|
175
152
|
|
|
176
|
-
|
|
177
|
-
- [`XConnector`](https://github.com/icon-project/sodax-frontend/tree/main/packages/wallet-sdk-react/src/core/XConnector.ts) - Base class for wallet connectors
|
|
178
|
-
- [`EvmXConnector`](https://github.com/icon-project/sodax-frontend/tree/main/packages/wallet-sdk-react/src/xchains/evm/EvmXConnector.ts) - EVM wallet connector
|
|
179
|
-
- [`SolanaXConnector`](https://github.com/icon-project/sodax-frontend/tree/main/packages/wallet-sdk-react/src/xchains/solana/SolanaXConnector.ts) - Solana wallet connector
|
|
180
|
-
- [`SuiXConnector`](https://github.com/icon-project/sodax-frontend/tree/main/packages/wallet-sdk-react/src/xchains/sui/SuiXConnector.ts) - Sui wallet connector
|
|
181
|
-
- [`StellarXConnector`](https://github.com/icon-project/sodax-frontend/tree/main/packages/wallet-sdk-react/src/xchains/stellar/StellarWalletsKitXConnector.ts) - Stellar wallet connector
|
|
182
|
-
- [`InjectiveMetamaskXConnector`](https://github.com/icon-project/sodax-frontend/tree/main/packages/wallet-sdk-react/src/xchains/injective/InjectiveMetamaskXConnector.ts) - Injective MetaMask connector
|
|
183
|
-
- [`InjectiveKelprXConnector`](https://github.com/icon-project/sodax-frontend/tree/main/packages/wallet-sdk-react/src/xchains/injective/InjectiveKelprXConnector.ts) - Injective Keplr connector
|
|
184
|
-
- [`IconXConnector`](https://github.com/icon-project/sodax-frontend/tree/main/packages/wallet-sdk-react/src/xchains/icon/IconHanaXConnector.ts) - ICON wallet connector
|
|
153
|
+
See [Connectors](docs/CONNECTORS.md) for the full list of deep-import sub-paths.
|
|
185
154
|
|
|
186
|
-
##
|
|
155
|
+
## Requirements
|
|
187
156
|
|
|
188
|
-
|
|
157
|
+
- Node.js >= 20.12.0
|
|
158
|
+
- React >= 19
|
|
159
|
+
- TypeScript
|
|
189
160
|
|
|
190
161
|
## Development
|
|
191
162
|
|
|
192
163
|
```bash
|
|
193
|
-
# Install dependencies
|
|
194
|
-
pnpm
|
|
195
|
-
|
|
196
|
-
#
|
|
197
|
-
pnpm
|
|
198
|
-
|
|
199
|
-
#
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
# Run type checking
|
|
203
|
-
pnpm checkTs
|
|
164
|
+
pnpm install # Install dependencies
|
|
165
|
+
pnpm build # Build the package (ESM + CJS, multi-entry)
|
|
166
|
+
pnpm dev # Watch mode
|
|
167
|
+
pnpm checkTs # Type checking
|
|
168
|
+
pnpm test # Run tests
|
|
169
|
+
pnpm pretty # Format code
|
|
170
|
+
pnpm lint # Lint code
|
|
171
|
+
```
|
|
204
172
|
|
|
205
|
-
|
|
206
|
-
pnpm pretty
|
|
173
|
+
## Contributing
|
|
207
174
|
|
|
208
|
-
|
|
209
|
-
pnpm lint
|
|
210
|
-
```
|
|
175
|
+
Contributions welcome — see the repo [Contributing Guide](https://github.com/icon-project/sodax-sdks/blob/main/CONTRIBUTING.md). For onboarding a new chain family, follow [`docs/ADDING_A_NEW_CHAIN.md`](https://github.com/icon-project/sodax-sdks/blob/main/packages/wallet-sdk-react/docs/ADDING_A_NEW_CHAIN.md).
|
|
211
176
|
|
|
212
177
|
## License
|
|
213
178
|
|
|
@@ -215,5 +180,5 @@ pnpm lint
|
|
|
215
180
|
|
|
216
181
|
## Support
|
|
217
182
|
|
|
218
|
-
- [GitHub Issues](https://github.com/icon-project/sodax-
|
|
183
|
+
- [GitHub Issues](https://github.com/icon-project/sodax-sdks/issues)
|
|
219
184
|
- [Discord Community](https://discord.gg/sodax-formerly-icon-880651922682560582)
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
import { ChainType, IXServiceBase, XToken } from '@sodax/types';
|
|
2
|
+
|
|
3
|
+
type XAccount = {
|
|
4
|
+
address: string | undefined;
|
|
5
|
+
xChainType: ChainType | undefined;
|
|
6
|
+
publicKey?: string;
|
|
7
|
+
};
|
|
8
|
+
type XConnection = {
|
|
9
|
+
xAccount: XAccount;
|
|
10
|
+
xConnectorId: string;
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Public interface for chain service implementations.
|
|
15
|
+
*
|
|
16
|
+
* Consumer code should depend on this interface instead of the concrete XService class.
|
|
17
|
+
* Extends the shared `IXServiceBase` from `@sodax/types` with wallet-sdk-react
|
|
18
|
+
* specific connector methods.
|
|
19
|
+
*/
|
|
20
|
+
interface IXService extends IXServiceBase {
|
|
21
|
+
getXConnectors(): IXConnector[];
|
|
22
|
+
getXConnectorById(xConnectorId: string): IXConnector | undefined;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Public interface for wallet connector implementations.
|
|
26
|
+
*
|
|
27
|
+
* `isInstalled` reads `window.*` at getter-call time (render time); no extra
|
|
28
|
+
* subscription is installed. Components get fresh values through normal React
|
|
29
|
+
* render triggers (store updates, parent rerenders).
|
|
30
|
+
*/
|
|
31
|
+
interface IXConnector {
|
|
32
|
+
readonly xChainType: ChainType;
|
|
33
|
+
readonly name: string;
|
|
34
|
+
/** Unique identifier for the connector */
|
|
35
|
+
readonly _id: string;
|
|
36
|
+
/** Optional icon URL for the wallet provider */
|
|
37
|
+
readonly _icon?: string;
|
|
38
|
+
readonly id: string;
|
|
39
|
+
readonly icon: string | undefined;
|
|
40
|
+
/** True when the wallet extension backing this connector is installed. */
|
|
41
|
+
readonly isInstalled: boolean;
|
|
42
|
+
/** URL where users can install the wallet extension if missing. */
|
|
43
|
+
readonly installUrl: string | undefined;
|
|
44
|
+
connect(): Promise<XAccount | undefined>;
|
|
45
|
+
disconnect(): Promise<void>;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Abstract base class for blockchain service implementations.
|
|
50
|
+
*
|
|
51
|
+
* The XService class serves as a foundation for implementing blockchain-specific services
|
|
52
|
+
* in a multi-chain environment. It provides a standardized interface for:
|
|
53
|
+
* 1. Managing wallet connectors for different blockchain types
|
|
54
|
+
* 2. Querying token balances across different chains
|
|
55
|
+
*
|
|
56
|
+
* Each blockchain implementation (e.g., Solana, EVM chains) extends this class
|
|
57
|
+
* to provide chain-specific functionality while maintaining a consistent interface.
|
|
58
|
+
*
|
|
59
|
+
* @abstract
|
|
60
|
+
* @class XService
|
|
61
|
+
* @property {ChainType} xChainType - The blockchain type this service handles (e.g., 'SOLANA', 'EVM')
|
|
62
|
+
* @property {XConnector[]} xConnectors - Available wallet connectors for this chain
|
|
63
|
+
*
|
|
64
|
+
*/
|
|
65
|
+
declare abstract class XService implements IXServiceBase {
|
|
66
|
+
/** The blockchain type this service handles */
|
|
67
|
+
readonly xChainType: ChainType;
|
|
68
|
+
/** Available wallet connectors for this chain */
|
|
69
|
+
private xConnectors;
|
|
70
|
+
constructor(xChainType: ChainType);
|
|
71
|
+
/**
|
|
72
|
+
* Gets the balance of a specific token for an address
|
|
73
|
+
* @param address The wallet address to check
|
|
74
|
+
* @param xToken The token to get the balance for
|
|
75
|
+
* @returns Promise resolving to the token balance as a bigint
|
|
76
|
+
*/
|
|
77
|
+
getBalance(address: string | undefined, xToken: XToken): Promise<bigint>;
|
|
78
|
+
/**
|
|
79
|
+
* Gets balances for multiple tokens for an address
|
|
80
|
+
* @param address The wallet address to check
|
|
81
|
+
* @param xTokens Array of tokens to get balances for
|
|
82
|
+
* @returns Promise resolving to object mapping token addresses to balances
|
|
83
|
+
*/
|
|
84
|
+
getBalances(address: string | undefined, xTokens: readonly XToken[]): Promise<Record<string, bigint>>;
|
|
85
|
+
/**
|
|
86
|
+
* Gets all available connectors for this chain
|
|
87
|
+
*/
|
|
88
|
+
getXConnectors(): IXConnector[];
|
|
89
|
+
/**
|
|
90
|
+
* Sets the available connectors for this chain
|
|
91
|
+
*/
|
|
92
|
+
setXConnectors(xConnectors: IXConnector[]): void;
|
|
93
|
+
/**
|
|
94
|
+
* Gets a specific connector by its ID
|
|
95
|
+
* @param xConnectorId The connector ID to look up
|
|
96
|
+
* @returns The matching connector or undefined if not found
|
|
97
|
+
*/
|
|
98
|
+
getXConnectorById(xConnectorId: string): IXConnector | undefined;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* Base class for wallet provider connectors that handles connection management and wallet interactions
|
|
103
|
+
*
|
|
104
|
+
* @abstract
|
|
105
|
+
* @class XConnector
|
|
106
|
+
* @property {ChainType} xChainType - The blockchain type this connector supports
|
|
107
|
+
* @property {string} name - Display name of the wallet provider
|
|
108
|
+
* @property {string} _id - Unique identifier for the connector
|
|
109
|
+
* @property {string | undefined} _icon - Optional icon URL for the wallet provider
|
|
110
|
+
*/
|
|
111
|
+
declare abstract class XConnector implements IXConnector {
|
|
112
|
+
/** The blockchain type this connector supports */
|
|
113
|
+
readonly xChainType: ChainType;
|
|
114
|
+
/** Display name of the wallet provider */
|
|
115
|
+
readonly name: string;
|
|
116
|
+
/** Unique identifier for the connector */
|
|
117
|
+
readonly _id: string;
|
|
118
|
+
/** Optional icon URL for the wallet provider */
|
|
119
|
+
readonly _icon?: string;
|
|
120
|
+
constructor(xChainType: ChainType, name: string, id: string);
|
|
121
|
+
/**
|
|
122
|
+
* Connects to the wallet provider
|
|
123
|
+
* @returns Promise resolving to the connected account, or undefined if connection fails
|
|
124
|
+
*/
|
|
125
|
+
abstract connect(): Promise<XAccount | undefined>;
|
|
126
|
+
/**
|
|
127
|
+
* Disconnects from the wallet provider
|
|
128
|
+
*/
|
|
129
|
+
abstract disconnect(): Promise<void>;
|
|
130
|
+
/** Get the unique identifier for this connector */
|
|
131
|
+
get id(): string;
|
|
132
|
+
/** Get the optional icon URL for this wallet provider */
|
|
133
|
+
get icon(): string | undefined;
|
|
134
|
+
/**
|
|
135
|
+
* True when the wallet extension backing this connector is installed.
|
|
136
|
+
* Default: true (for provider-managed chains where connector presence already
|
|
137
|
+
* implies install — EVM via EIP-6963, Solana/Sui via adapter discovery).
|
|
138
|
+
* Subclasses backed by extension injection (Bitcoin, ICON, Stacks) override
|
|
139
|
+
* this with a window probe.
|
|
140
|
+
*/
|
|
141
|
+
get isInstalled(): boolean;
|
|
142
|
+
/** URL to install the wallet extension when missing. Subclasses override. */
|
|
143
|
+
get installUrl(): string | undefined;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
export { type IXConnector as I, type XAccount as X, type IXService as a, type XConnection as b, XConnector as c, XService as d };
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { getEvmChainKeyByChainId, baseChainInfo } from '@sodax/types';
|
|
2
|
+
|
|
3
|
+
// src/utils/walletRpcConfig.ts
|
|
4
|
+
function getEntryDefaults(entry) {
|
|
5
|
+
if (!entry || typeof entry === "string") return void 0;
|
|
6
|
+
return entry.defaults;
|
|
7
|
+
}
|
|
8
|
+
function getRpcUrl(entry) {
|
|
9
|
+
if (!entry || typeof entry === "string") return void 0;
|
|
10
|
+
return entry.rpcUrl;
|
|
11
|
+
}
|
|
12
|
+
function resolveEvmDefaults(activeChainId, evmChains) {
|
|
13
|
+
const key = getEvmChainKeyByChainId(activeChainId);
|
|
14
|
+
if (!key || !evmChains) return void 0;
|
|
15
|
+
return evmChains[key]?.defaults;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
// src/utils/sortConnectors.ts
|
|
19
|
+
function sortConnectors(connectors, options = {}) {
|
|
20
|
+
const { preferred = [] } = options;
|
|
21
|
+
const preferredIndex = new Map(preferred.map((id, i) => [id, i]));
|
|
22
|
+
return [...connectors].map((connector, originalIndex) => ({ connector, originalIndex })).sort((a, b) => {
|
|
23
|
+
const aPref = preferredIndex.get(a.connector.id);
|
|
24
|
+
const bPref = preferredIndex.get(b.connector.id);
|
|
25
|
+
if (aPref !== bPref) {
|
|
26
|
+
if (aPref === void 0) return 1;
|
|
27
|
+
if (bPref === void 0) return -1;
|
|
28
|
+
return aPref - bPref;
|
|
29
|
+
}
|
|
30
|
+
if (a.connector.isInstalled !== b.connector.isInstalled) {
|
|
31
|
+
return a.connector.isInstalled ? -1 : 1;
|
|
32
|
+
}
|
|
33
|
+
return a.originalIndex - b.originalIndex;
|
|
34
|
+
}).map(({ connector }) => connector);
|
|
35
|
+
}
|
|
36
|
+
var isNativeToken = (xToken) => {
|
|
37
|
+
const nativeAddresses = [
|
|
38
|
+
"cx0000000000000000000000000000000000000000",
|
|
39
|
+
"0x0000000000000000000000000000000000000000",
|
|
40
|
+
"inj",
|
|
41
|
+
"0x0000000000000000000000000000000000000000000000000000000000000002::sui::SUI",
|
|
42
|
+
"hx0000000000000000000000000000000000000000",
|
|
43
|
+
"11111111111111111111111111111111",
|
|
44
|
+
// solana
|
|
45
|
+
"CAS3J7GYLGXMF6TDJBBYYSE3HQ6BBSMLNUQ34T6TZMYMW2EVH34XOWMA",
|
|
46
|
+
// stellar
|
|
47
|
+
"ST000000000000000000002AMW42H.nativetoken",
|
|
48
|
+
// stacks
|
|
49
|
+
"0:0"
|
|
50
|
+
// bitcoin
|
|
51
|
+
];
|
|
52
|
+
return nativeAddresses.includes(xToken.address);
|
|
53
|
+
};
|
|
54
|
+
var getWagmiChainId = (xChainId) => {
|
|
55
|
+
const chainId = baseChainInfo[xChainId].chainId;
|
|
56
|
+
if (typeof chainId !== "number") {
|
|
57
|
+
throw new Error(`[wallet-sdk-react] getWagmiChainId: expected numeric chainId, got ${typeof chainId}`);
|
|
58
|
+
}
|
|
59
|
+
return chainId;
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
export { getEntryDefaults, getRpcUrl, getWagmiChainId, isNativeToken, resolveEvmDefaults, sortConnectors };
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import { NEAR_DEFAULT_RPC_URL } from './chunk-NAKCAL2M.mjs';
|
|
2
|
+
import { XService, XConnector } from './chunk-IFXZQW4C.mjs';
|
|
3
|
+
import { NearConnector } from '@hot-labs/near-connect';
|
|
4
|
+
import { JsonRpcProvider } from 'near-api-js';
|
|
5
|
+
|
|
6
|
+
var NearXService = class _NearXService extends XService {
|
|
7
|
+
static instance;
|
|
8
|
+
walletSelector;
|
|
9
|
+
rpcUrl;
|
|
10
|
+
/**
|
|
11
|
+
* @param rpcUrl - Used by `getBalance` via `JsonRpcProvider({ url: rpcUrl })`.
|
|
12
|
+
* Does NOT affect `walletSelector` — `@hot-labs/near-connect` only accepts
|
|
13
|
+
* the network preset name (`'mainnet'`/`'testnet'`) and fetches RPC internally.
|
|
14
|
+
* Custom RPC is therefore read-only for balance queries.
|
|
15
|
+
*/
|
|
16
|
+
constructor(rpcUrl = NEAR_DEFAULT_RPC_URL) {
|
|
17
|
+
super("NEAR");
|
|
18
|
+
this.rpcUrl = rpcUrl;
|
|
19
|
+
this.walletSelector = new NearConnector({
|
|
20
|
+
network: "mainnet",
|
|
21
|
+
logger: console,
|
|
22
|
+
autoConnect: true,
|
|
23
|
+
excludedWallets: ["okx-wallet"]
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* @param rpcUrl - Re-applied on every call (matches StacksXService semantics).
|
|
28
|
+
* `rpcUrl` only drives `getBalance` via a per-call `JsonRpcProvider`, so it's
|
|
29
|
+
* safe to update at runtime — no persistent chain client to rebuild.
|
|
30
|
+
*/
|
|
31
|
+
static getInstance(rpcUrl) {
|
|
32
|
+
if (!_NearXService.instance) {
|
|
33
|
+
_NearXService.instance = new _NearXService(rpcUrl);
|
|
34
|
+
} else if (rpcUrl) {
|
|
35
|
+
_NearXService.instance.rpcUrl = rpcUrl;
|
|
36
|
+
}
|
|
37
|
+
return _NearXService.instance;
|
|
38
|
+
}
|
|
39
|
+
async getBalance(address, xToken) {
|
|
40
|
+
const provider = new JsonRpcProvider({ url: this.rpcUrl });
|
|
41
|
+
if (xToken.symbol === "NEAR") {
|
|
42
|
+
const account = await provider.viewAccount({ accountId: address ?? "" });
|
|
43
|
+
return BigInt(account.amount);
|
|
44
|
+
}
|
|
45
|
+
const res = await provider.callFunction({
|
|
46
|
+
contractId: xToken.address,
|
|
47
|
+
method: "ft_balance_of",
|
|
48
|
+
args: { account_id: address }
|
|
49
|
+
});
|
|
50
|
+
return BigInt(res ?? 0);
|
|
51
|
+
}
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
// src/xchains/near/NearXConnector.ts
|
|
55
|
+
var NearXConnector = class extends XConnector {
|
|
56
|
+
_wallet;
|
|
57
|
+
constructor(wallet) {
|
|
58
|
+
super("NEAR", wallet.manifest.name, wallet.manifest.id);
|
|
59
|
+
this._wallet = wallet;
|
|
60
|
+
}
|
|
61
|
+
getXService() {
|
|
62
|
+
return NearXService.getInstance();
|
|
63
|
+
}
|
|
64
|
+
async connect() {
|
|
65
|
+
const walletSelector = this.getXService().walletSelector;
|
|
66
|
+
const wallet = await walletSelector.connect({ walletId: this._wallet.manifest.id });
|
|
67
|
+
const accounts = await wallet.getAccounts();
|
|
68
|
+
if (accounts.length === 0 || accounts[0] === void 0) {
|
|
69
|
+
console.warn(`[NearXConnector] connect: ${this._wallet.manifest.name} returned no accounts`);
|
|
70
|
+
return void 0;
|
|
71
|
+
}
|
|
72
|
+
return {
|
|
73
|
+
address: accounts[0].accountId,
|
|
74
|
+
xChainType: this.xChainType
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
async disconnect() {
|
|
78
|
+
const walletSelector = this.getXService().walletSelector;
|
|
79
|
+
await walletSelector.disconnect(this._wallet);
|
|
80
|
+
}
|
|
81
|
+
get icon() {
|
|
82
|
+
return this._wallet.manifest.icon;
|
|
83
|
+
}
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
export { NearXConnector, NearXService };
|