@sodax/wallet-sdk-react 1.5.7-beta → 2.0.0-rc.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 +103 -145
- package/ai-exported/AGENTS.md +122 -0
- package/ai-exported/integration/README.md +102 -0
- package/ai-exported/integration/ai-rules.md +136 -0
- package/ai-exported/integration/architecture.md +181 -0
- package/ai-exported/integration/examples/01-minimal-evm.tsx +75 -0
- package/ai-exported/integration/examples/02-multi-chain-modal.tsx +169 -0
- package/ai-exported/integration/examples/03-nextjs-app-router.tsx +99 -0
- package/ai-exported/integration/examples/04-walletconnect-setup.tsx +89 -0
- package/ai-exported/integration/examples/README.md +29 -0
- package/ai-exported/integration/recipes/batch-operations.md +223 -0
- package/ai-exported/integration/recipes/bridge-to-sdk.md +164 -0
- package/ai-exported/integration/recipes/chain-detection.md +254 -0
- package/ai-exported/integration/recipes/connect-button.md +156 -0
- package/ai-exported/integration/recipes/multi-chain-modal.md +199 -0
- package/ai-exported/integration/recipes/setup.md +158 -0
- package/ai-exported/integration/recipes/sign-message.md +137 -0
- package/ai-exported/integration/recipes/sub-path-imports.md +95 -0
- package/ai-exported/integration/recipes/switch-chain.md +141 -0
- package/ai-exported/integration/recipes/walletconnect-setup.md +139 -0
- package/ai-exported/integration/reference/api-surface.md +175 -0
- package/ai-exported/integration/reference/chain-support.md +78 -0
- package/ai-exported/integration/reference/connectors.md +74 -0
- package/ai-exported/integration/reference/hooks.md +204 -0
- package/ai-exported/integration/reference/wallet-brands.md +106 -0
- package/ai-exported/migration/README.md +49 -0
- package/ai-exported/migration/ai-rules.md +144 -0
- package/ai-exported/migration/breaking-changes.md +305 -0
- package/ai-exported/migration/checklist.md +159 -0
- package/ai-exported/migration/recipes/connect-button.md +166 -0
- package/ai-exported/migration/recipes/multi-chain-modal.md +244 -0
- package/ai-exported/migration/recipes/ssr-setup.md +162 -0
- package/ai-exported/migration/recipes/walletconnect-migration.md +168 -0
- package/ai-exported/migration/reference/components.md +73 -0
- package/ai-exported/migration/reference/config.md +307 -0
- package/ai-exported/migration/reference/hooks.md +278 -0
- package/ai-exported/migration/reference/imports.md +157 -0
- package/dist/XConnector-B9YQTVJ4.d.ts +146 -0
- package/dist/chunk-2BOUGCJ7.mjs +150 -0
- package/dist/chunk-2BOUGCJ7.mjs.map +1 -0
- package/dist/chunk-66BAUK56.mjs +202 -0
- package/dist/chunk-66BAUK56.mjs.map +1 -0
- package/dist/chunk-7ULB6DW4.mjs +102 -0
- package/dist/chunk-7ULB6DW4.mjs.map +1 -0
- package/dist/chunk-BKJB527E.mjs +125 -0
- package/dist/chunk-BKJB527E.mjs.map +1 -0
- package/dist/chunk-BXJLBR4G.mjs +88 -0
- package/dist/chunk-BXJLBR4G.mjs.map +1 -0
- package/dist/chunk-E5IAZ7E6.mjs +186 -0
- package/dist/chunk-E5IAZ7E6.mjs.map +1 -0
- package/dist/chunk-MAQ47Q52.mjs +33 -0
- package/dist/chunk-MAQ47Q52.mjs.map +1 -0
- package/dist/chunk-MXZVF5HR.mjs +34 -0
- package/dist/chunk-MXZVF5HR.mjs.map +1 -0
- package/dist/chunk-N5A2TMF6.mjs +33 -0
- package/dist/chunk-N5A2TMF6.mjs.map +1 -0
- package/dist/chunk-NY7U7OJW.mjs +64 -0
- package/dist/chunk-NY7U7OJW.mjs.map +1 -0
- package/dist/chunk-PJLEJVAU.mjs +140 -0
- package/dist/chunk-PJLEJVAU.mjs.map +1 -0
- package/dist/chunk-PLCA4ZDJ.mjs +1585 -0
- package/dist/chunk-PLCA4ZDJ.mjs.map +1 -0
- package/dist/chunk-TZMKDXFA.mjs +3 -0
- package/dist/chunk-TZMKDXFA.mjs.map +1 -0
- package/dist/chunk-X2MHIWXO.mjs +100 -0
- package/dist/chunk-X2MHIWXO.mjs.map +1 -0
- package/dist/chunk-XZ7CHO2S.mjs +41 -0
- package/dist/chunk-XZ7CHO2S.mjs.map +1 -0
- package/dist/config-OlnzyEUE.d.ts +146 -0
- package/dist/index.cjs +2784 -1594
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +768 -1498
- package/dist/index.mjs +463 -2004
- package/dist/index.mjs.map +1 -1
- package/dist/xchains/bitcoin/index.cjs +1927 -0
- package/dist/xchains/bitcoin/index.cjs.map +1 -0
- package/dist/xchains/bitcoin/index.d.ts +125 -0
- package/dist/xchains/bitcoin/index.mjs +16 -0
- package/dist/xchains/bitcoin/index.mjs.map +1 -0
- package/dist/xchains/evm/index.cjs +316 -0
- package/dist/xchains/evm/index.cjs.map +1 -0
- package/dist/xchains/evm/index.d.ts +39 -0
- package/dist/xchains/evm/index.mjs +5 -0
- package/dist/xchains/evm/index.mjs.map +1 -0
- package/dist/xchains/icon/index.cjs +311 -0
- package/dist/xchains/icon/index.cjs.map +1 -0
- package/dist/xchains/icon/index.d.ts +37 -0
- package/dist/xchains/icon/index.mjs +7 -0
- package/dist/xchains/icon/index.mjs.map +1 -0
- package/dist/xchains/injective/index.cjs +223 -0
- package/dist/xchains/injective/index.cjs.map +1 -0
- package/dist/xchains/injective/index.d.ts +35 -0
- package/dist/xchains/injective/index.mjs +5 -0
- package/dist/xchains/injective/index.mjs.map +1 -0
- package/dist/xchains/near/index.cjs +190 -0
- package/dist/xchains/near/index.cjs.map +1 -0
- package/dist/xchains/near/index.d.ts +34 -0
- package/dist/xchains/near/index.mjs +6 -0
- package/dist/xchains/near/index.mjs.map +1 -0
- package/dist/xchains/solana/index.cjs +186 -0
- package/dist/xchains/solana/index.cjs.map +1 -0
- package/dist/xchains/solana/index.d.ts +26 -0
- package/dist/xchains/solana/index.mjs +7 -0
- package/dist/xchains/solana/index.mjs.map +1 -0
- package/dist/xchains/stacks/index.cjs +240 -0
- package/dist/xchains/stacks/index.cjs.map +1 -0
- package/dist/xchains/stacks/index.d.ts +36 -0
- package/dist/xchains/stacks/index.mjs +5 -0
- package/dist/xchains/stacks/index.mjs.map +1 -0
- package/dist/xchains/stellar/index.cjs +322 -0
- package/dist/xchains/stellar/index.cjs.map +1 -0
- package/dist/xchains/stellar/index.d.ts +44 -0
- package/dist/xchains/stellar/index.mjs +6 -0
- package/dist/xchains/stellar/index.mjs.map +1 -0
- package/dist/xchains/sui/index.cjs +248 -0
- package/dist/xchains/sui/index.cjs.map +1 -0
- package/dist/xchains/sui/index.d.ts +37 -0
- package/dist/xchains/sui/index.mjs +7 -0
- package/dist/xchains/sui/index.mjs.map +1 -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 +246 -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 +34 -9
- package/skills/SKILLS.md +84 -0
- package/skills/bridge-to-sdk.md +148 -0
- package/skills/connect-button.md +116 -0
- package/skills/evm-only-walletconnect.md +111 -0
- package/skills/multi-chain-modal.md +178 -0
- package/skills/setup.md +107 -0
- package/dist/index.d.cts +0 -1579
- 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
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
# Skill: EVM-only WalletConnect
|
|
2
|
+
|
|
3
|
+
Enable WalletConnect protocol on the EVM slot for partners using enterprise custody (Fireblocks, Ledger Live, mobile-only wallets). Default EVM discovery (EIP-6963) only finds browser-extension wallets — WalletConnect lets users pair via QR/deep-link.
|
|
4
|
+
|
|
5
|
+
**Depends on:** [setup.md](https://github.com/icon-project/sodax-sdks/blob/main/packages/wallet-sdk-react/skills/setup.md)
|
|
6
|
+
|
|
7
|
+
## When to use
|
|
8
|
+
|
|
9
|
+
| Scenario | Need WalletConnect? |
|
|
10
|
+
|----------|---------------------|
|
|
11
|
+
| MetaMask / Hana / Rabby browser extension | ❌ — EIP-6963 covers them |
|
|
12
|
+
| Fireblocks workspace | ✅ |
|
|
13
|
+
| Ledger Live | ✅ |
|
|
14
|
+
| MetaMask Mobile / Trust / Rainbow (paired via QR) | ✅ |
|
|
15
|
+
| Coinbase Smart Wallet | ✅ (fallback path) |
|
|
16
|
+
|
|
17
|
+
If your dApp only targets desktop browser-extension wallets, omit `walletConnect` entirely.
|
|
18
|
+
|
|
19
|
+
## 1. Get a WalletConnect Cloud project id
|
|
20
|
+
|
|
21
|
+
Sign up at [https://cloud.walletconnect.com](https://cloud.walletconnect.com) and copy your project id. Add it to `.env`:
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
NEXT_PUBLIC_WC_PROJECT_ID=your-project-id
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
## 2. Add `walletConnect` to the `EVM` slot
|
|
28
|
+
|
|
29
|
+
```typescript
|
|
30
|
+
import { type SodaxWalletConfig } from '@sodax/wallet-sdk-react';
|
|
31
|
+
import { ChainKeys } from '@sodax/types';
|
|
32
|
+
|
|
33
|
+
const walletConfig: SodaxWalletConfig = {
|
|
34
|
+
EVM: {
|
|
35
|
+
ssr: true,
|
|
36
|
+
chains: {
|
|
37
|
+
[ChainKeys.SONIC_MAINNET]: { rpcUrl: 'https://rpc.soniclabs.com' },
|
|
38
|
+
[ChainKeys.ARBITRUM_MAINNET]: { rpcUrl: 'https://arb1.arbitrum.io/rpc' },
|
|
39
|
+
},
|
|
40
|
+
walletConnect: {
|
|
41
|
+
projectId: process.env.NEXT_PUBLIC_WC_PROJECT_ID!,
|
|
42
|
+
// showQrModal: true is the default — wagmi/WalletConnect own the QR display
|
|
43
|
+
},
|
|
44
|
+
},
|
|
45
|
+
};
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
A WalletConnect connector now surfaces alongside EIP-6963 wallets. `useXConnectors({ xChainType: 'EVM' })` returns it with `id === 'walletConnect'`. **No UI changes required** — the existing connect-button or modal already handles it.
|
|
49
|
+
|
|
50
|
+
## 3. Restrict the QR modal — Fireblocks-only
|
|
51
|
+
|
|
52
|
+
To show **only** Fireblocks (no Trust / Rainbow / etc. clutter), filter the WalletConnect Explorer list:
|
|
53
|
+
|
|
54
|
+
```typescript
|
|
55
|
+
const walletConfig: SodaxWalletConfig = {
|
|
56
|
+
EVM: {
|
|
57
|
+
walletConnect: {
|
|
58
|
+
projectId: process.env.NEXT_PUBLIC_WC_PROJECT_ID!,
|
|
59
|
+
qrModalOptions: {
|
|
60
|
+
explorerRecommendedWalletIds: [
|
|
61
|
+
'225affb176778569276e484e1b92637ad061b01e13a048b35a9d280c3b58970f', // Fireblocks
|
|
62
|
+
],
|
|
63
|
+
explorerExcludedWalletIds: 'ALL', // hide everything except recommended
|
|
64
|
+
},
|
|
65
|
+
},
|
|
66
|
+
},
|
|
67
|
+
};
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
Find wallet IDs at the [WalletConnect Explorer](https://walletconnect.com/explorer) — they're the long hex strings in URLs, not the human names.
|
|
71
|
+
|
|
72
|
+
## 4. Hide the Sodax modal during WalletConnect QR
|
|
73
|
+
|
|
74
|
+
When the user picks the WalletConnect connector, wagmi opens its own QR modal — two dialogs would stack. Detect WC by connector id and render `null`:
|
|
75
|
+
|
|
76
|
+
```typescript
|
|
77
|
+
import { useWalletModal } from '@sodax/wallet-sdk-react';
|
|
78
|
+
|
|
79
|
+
const modal = useWalletModal();
|
|
80
|
+
|
|
81
|
+
if (
|
|
82
|
+
modal.state.kind === 'connecting' &&
|
|
83
|
+
modal.state.connector.id === 'walletConnect'
|
|
84
|
+
) {
|
|
85
|
+
return null; // wagmi's QR modal owns the screen
|
|
86
|
+
}
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
The `useWalletModal` state machine handles the `connecting → success | error` transition normally — only the rendering is conditionally blanked.
|
|
90
|
+
|
|
91
|
+
## Missing `projectId` — silent skip
|
|
92
|
+
|
|
93
|
+
Setting `walletConnect: {}` without a `projectId` (or with an empty string) **silently skips** the WalletConnect connector and logs a warning:
|
|
94
|
+
|
|
95
|
+
```
|
|
96
|
+
[wallet-sdk-react] walletConnect.projectId is required — WalletConnect connector skipped.
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
EIP-6963 wallets continue to work normally — the dApp degrades gracefully. This intentionally avoids forcing local-dev environments to plumb the env var.
|
|
100
|
+
|
|
101
|
+
## EVM-only
|
|
102
|
+
|
|
103
|
+
The `walletConnect` field only exists on the `EVM` slot. Solana, Bitcoin, etc. use their own native wallet adapters and don't share the WalletConnect protocol layer. Don't attempt `SOLANA: { walletConnect: ... }` — TypeScript will reject it.
|
|
104
|
+
|
|
105
|
+
## Reference docs
|
|
106
|
+
|
|
107
|
+
- [WalletConnect](https://github.com/icon-project/sodax-sdks/blob/main/packages/wallet-sdk-react/docs/WALLETCONNECT.md) — full integration reference
|
|
108
|
+
- [Configure SodaxWalletProvider](https://github.com/icon-project/sodax-sdks/blob/main/packages/wallet-sdk-react/docs/CONFIGURE_PROVIDER.md#walletconnect-evm-only) — per-chain config
|
|
109
|
+
- [Wallet Modal QR caveat](https://github.com/icon-project/sodax-sdks/blob/main/packages/wallet-sdk-react/docs/WALLET_MODAL.md#walletconnect-qr-modal-caveat) — modal stacking handling
|
|
110
|
+
- [wagmi `WalletConnectParameters`](https://wagmi.sh/core/api/connectors/walletConnect) — full options reference
|
|
111
|
+
- [WalletConnect Cloud](https://cloud.walletconnect.com) — get a `projectId`
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
# Skill: Multi-chain Modal
|
|
2
|
+
|
|
3
|
+
Headless wallet-connect modal that walks the user through `chainSelect → walletSelect → connecting → success | error`. Pair with `useChainGroups` for the chain picker and `useXConnectors` for the wallet picker. Render-agnostic — works with any dialog/drawer/inline UI.
|
|
4
|
+
|
|
5
|
+
**Depends on:** [setup.md](https://github.com/icon-project/sodax-sdks/blob/main/packages/wallet-sdk-react/skills/setup.md)
|
|
6
|
+
|
|
7
|
+
## Hooks
|
|
8
|
+
|
|
9
|
+
| Hook | Purpose |
|
|
10
|
+
|------|---------|
|
|
11
|
+
| `useWalletModal({ onConnected? })` | State machine + actions (`open`, `close`, `back`, `selectChain`, `selectWallet`, `retry`) |
|
|
12
|
+
| `useChainGroups({ order? })` | One row per enabled chain family (EVM collapses to one row) |
|
|
13
|
+
| `useXConnectors({ xChainType })` | Wallet list for the chosen chain family |
|
|
14
|
+
| `useXAccount({ xChainType })` | Read the connected account when needed |
|
|
15
|
+
|
|
16
|
+
## Render switch
|
|
17
|
+
|
|
18
|
+
```tsx
|
|
19
|
+
import {
|
|
20
|
+
useWalletModal,
|
|
21
|
+
useChainGroups,
|
|
22
|
+
useXConnectors,
|
|
23
|
+
type IXConnector,
|
|
24
|
+
} from '@sodax/wallet-sdk-react';
|
|
25
|
+
|
|
26
|
+
export function WalletModalRoot() {
|
|
27
|
+
const modal = useWalletModal({
|
|
28
|
+
onConnected: async (chainType, account) => {
|
|
29
|
+
// app side-effects (e.g. registration, ToS check)
|
|
30
|
+
console.log('connected', chainType, account.address);
|
|
31
|
+
},
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
switch (modal.state.kind) {
|
|
35
|
+
case 'closed':
|
|
36
|
+
return <button onClick={modal.open}>Connect Wallet</button>;
|
|
37
|
+
|
|
38
|
+
case 'chainSelect':
|
|
39
|
+
return <ChainPicker onPick={modal.selectChain} onClose={modal.close} />;
|
|
40
|
+
|
|
41
|
+
case 'walletSelect':
|
|
42
|
+
return (
|
|
43
|
+
<WalletPicker
|
|
44
|
+
chainType={modal.state.chainType}
|
|
45
|
+
onPick={modal.selectWallet}
|
|
46
|
+
onBack={modal.back}
|
|
47
|
+
onClose={modal.close}
|
|
48
|
+
/>
|
|
49
|
+
);
|
|
50
|
+
|
|
51
|
+
case 'connecting':
|
|
52
|
+
// Hide modal while wagmi's QR modal is up for WalletConnect
|
|
53
|
+
if (modal.state.connector.id === 'walletConnect') return null;
|
|
54
|
+
return (
|
|
55
|
+
<Dialog onClose={modal.close}>
|
|
56
|
+
<p>Approve in {modal.state.connector.name}…</p>
|
|
57
|
+
<button onClick={modal.back}>Cancel</button>
|
|
58
|
+
</Dialog>
|
|
59
|
+
);
|
|
60
|
+
|
|
61
|
+
case 'success':
|
|
62
|
+
// onConnected fired; close after a beat
|
|
63
|
+
setTimeout(modal.close, 0);
|
|
64
|
+
return null;
|
|
65
|
+
|
|
66
|
+
case 'error':
|
|
67
|
+
return (
|
|
68
|
+
<Dialog onClose={modal.close}>
|
|
69
|
+
<p>{modal.state.error.message}</p>
|
|
70
|
+
{!modal.state.connector.isInstalled && modal.state.connector.installUrl && (
|
|
71
|
+
<a href={modal.state.connector.installUrl}>Install {modal.state.connector.name}</a>
|
|
72
|
+
)}
|
|
73
|
+
<button onClick={modal.retry}>Retry</button>
|
|
74
|
+
<button onClick={modal.back}>Pick another wallet</button>
|
|
75
|
+
</Dialog>
|
|
76
|
+
);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
Render `<WalletModalRoot />` once at the app root — any other component can dispatch `useWalletModal().open()` to show it.
|
|
82
|
+
|
|
83
|
+
## Chain picker (driven by `useChainGroups`)
|
|
84
|
+
|
|
85
|
+
```tsx
|
|
86
|
+
import { useChainGroups } from '@sodax/wallet-sdk-react';
|
|
87
|
+
import type { ChainType } from '@sodax/types';
|
|
88
|
+
|
|
89
|
+
function ChainPicker({ onPick, onClose }: { onPick: (c: ChainType) => void; onClose: () => void }) {
|
|
90
|
+
const groups = useChainGroups({ order: ['EVM', 'SOLANA', 'BITCOIN', 'ICON'] });
|
|
91
|
+
|
|
92
|
+
return (
|
|
93
|
+
<Dialog onClose={onClose}>
|
|
94
|
+
<h2>Select a chain</h2>
|
|
95
|
+
{groups.map((group) => (
|
|
96
|
+
<button key={group.chainType} onClick={() => onPick(group.chainType)}>
|
|
97
|
+
{group.iconUrl && <img src={group.iconUrl} alt="" width={24} height={24} />}
|
|
98
|
+
<span>{group.displayName}</span>
|
|
99
|
+
{group.isConnected && <span>Connected</span>}
|
|
100
|
+
</button>
|
|
101
|
+
))}
|
|
102
|
+
</Dialog>
|
|
103
|
+
);
|
|
104
|
+
}
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
EVM collapses to a single group covering every configured EVM network — this matches reality (wagmi maintains one connection across all EVM chains).
|
|
108
|
+
|
|
109
|
+
## Wallet picker (driven by `useXConnectors`)
|
|
110
|
+
|
|
111
|
+
```tsx
|
|
112
|
+
import { useXConnectors, sortConnectors, type IXConnector } from '@sodax/wallet-sdk-react';
|
|
113
|
+
import type { ChainType } from '@sodax/types';
|
|
114
|
+
|
|
115
|
+
function WalletPicker({
|
|
116
|
+
chainType,
|
|
117
|
+
onPick,
|
|
118
|
+
onBack,
|
|
119
|
+
onClose,
|
|
120
|
+
}: {
|
|
121
|
+
chainType: ChainType;
|
|
122
|
+
onPick: (c: IXConnector) => void;
|
|
123
|
+
onBack: () => void;
|
|
124
|
+
onClose: () => void;
|
|
125
|
+
}) {
|
|
126
|
+
const connectors = sortConnectors(useXConnectors({ xChainType: chainType }), {
|
|
127
|
+
preferred: ['hana', 'metamask', 'phantom'],
|
|
128
|
+
});
|
|
129
|
+
|
|
130
|
+
return (
|
|
131
|
+
<Dialog onClose={onClose}>
|
|
132
|
+
<button onClick={onBack}>← Back</button>
|
|
133
|
+
<h2>Select a wallet</h2>
|
|
134
|
+
{connectors.map((connector) => (
|
|
135
|
+
<button key={connector.id} onClick={() => onPick(connector)}>
|
|
136
|
+
{connector.icon && <img src={connector.icon} alt="" />}
|
|
137
|
+
{connector.name}
|
|
138
|
+
{!connector.isInstalled && ' (not installed)'}
|
|
139
|
+
</button>
|
|
140
|
+
))}
|
|
141
|
+
</Dialog>
|
|
142
|
+
);
|
|
143
|
+
}
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
## Concurrency rules
|
|
147
|
+
|
|
148
|
+
- **Same connector double-click** → returns the same in-flight promise (no double popup).
|
|
149
|
+
- **Different connector mid-attempt** → starts a new attempt; previous one's late resolution is dropped.
|
|
150
|
+
- **`back()` / `close()` mid-attempt** → cancellation guard inside the modal layer; the wallet may still approve in the background but `success`/`error` won't fire. To roll back, call `useXDisconnect({ xChainType })` from the same handler.
|
|
151
|
+
|
|
152
|
+
## `onConnected` is non-fatal
|
|
153
|
+
|
|
154
|
+
Throwing inside `onConnected` is logged but **does not** downgrade `success` → `error`. The connection is already persisted; the user is genuinely connected.
|
|
155
|
+
|
|
156
|
+
## Non-modal alternative — `useConnectionFlow`
|
|
157
|
+
|
|
158
|
+
For a single-button flow without the multi-step modal:
|
|
159
|
+
|
|
160
|
+
```tsx
|
|
161
|
+
import { useConnectionFlow } from '@sodax/wallet-sdk-react';
|
|
162
|
+
|
|
163
|
+
const { status, error, connect, retry, activeConnector } = useConnectionFlow();
|
|
164
|
+
|
|
165
|
+
return (
|
|
166
|
+
<button onClick={() => connect(connector)} disabled={status === 'connecting'}>
|
|
167
|
+
{status === 'connecting' ? 'Waiting…' : 'Connect'}
|
|
168
|
+
</button>
|
|
169
|
+
);
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
`connect()` and `retry()` never throw — errors flow into `error` state.
|
|
173
|
+
|
|
174
|
+
## Reference docs
|
|
175
|
+
|
|
176
|
+
- [Wallet Modal](https://github.com/icon-project/sodax-sdks/blob/main/packages/wallet-sdk-react/docs/WALLET_MODAL.md) — full state machine + cancellation semantics
|
|
177
|
+
- [Chain Detection](https://github.com/icon-project/sodax-sdks/blob/main/packages/wallet-sdk-react/docs/CHAIN_DETECTION.md) — `useChainGroups` + ordering
|
|
178
|
+
- [Connect Flow](https://github.com/icon-project/sodax-sdks/blob/main/packages/wallet-sdk-react/docs/CONNECT_FLOW.md) — underlying `useXConnect` lifecycle
|
package/skills/setup.md
ADDED
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
# Skill: Setup
|
|
2
|
+
|
|
3
|
+
Install and wire `@sodax/wallet-sdk-react` into a React project.
|
|
4
|
+
|
|
5
|
+
**Depends on:** None
|
|
6
|
+
|
|
7
|
+
## Install
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
pnpm add @sodax/wallet-sdk-react @tanstack/react-query
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
Peer dependencies:
|
|
14
|
+
|
|
15
|
+
```json
|
|
16
|
+
{
|
|
17
|
+
"react": ">=19",
|
|
18
|
+
"@tanstack/react-query": "5.x"
|
|
19
|
+
}
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
## Wire `SodaxWalletProvider`
|
|
23
|
+
|
|
24
|
+
Top-level keys on `SodaxWalletConfig` are chain-type slots — **omit a slot to skip mounting that adapter**, pass `{}` to mount with SDK defaults. `<QueryClientProvider>` must wrap `<SodaxWalletProvider>`.
|
|
25
|
+
|
|
26
|
+
```tsx
|
|
27
|
+
// providers.tsx
|
|
28
|
+
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
|
|
29
|
+
import { SodaxWalletProvider, type SodaxWalletConfig } from '@sodax/wallet-sdk-react';
|
|
30
|
+
import { ChainKeys } from '@sodax/types';
|
|
31
|
+
|
|
32
|
+
const queryClient = new QueryClient();
|
|
33
|
+
|
|
34
|
+
const walletConfig: SodaxWalletConfig = {
|
|
35
|
+
EVM: {
|
|
36
|
+
ssr: true, // Next.js — keep true for SSR-safe hydration
|
|
37
|
+
chains: {
|
|
38
|
+
[ChainKeys.SONIC_MAINNET]: { rpcUrl: 'https://rpc.soniclabs.com' },
|
|
39
|
+
[ChainKeys.ETHEREUM_MAINNET]: { rpcUrl: 'https://ethereum-rpc.publicnode.com' },
|
|
40
|
+
[ChainKeys.BSC_MAINNET]: { rpcUrl: 'https://bsc-dataseed.binance.org' },
|
|
41
|
+
},
|
|
42
|
+
},
|
|
43
|
+
ICON: {
|
|
44
|
+
chains: { [ChainKeys.ICON_MAINNET]: { rpcUrl: 'https://ctz.solidwallet.io/api/v3' } },
|
|
45
|
+
},
|
|
46
|
+
// BITCOIN: {}, // mount with SDK defaults
|
|
47
|
+
// SOLANA: { chains: { [ChainKeys.SOLANA_MAINNET]: { rpcUrl: '...' } } },
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
export function Providers({ children }: { children: React.ReactNode }) {
|
|
51
|
+
return (
|
|
52
|
+
<QueryClientProvider client={queryClient}>
|
|
53
|
+
<SodaxWalletProvider config={walletConfig}>{children}</SodaxWalletProvider>
|
|
54
|
+
</QueryClientProvider>
|
|
55
|
+
);
|
|
56
|
+
}
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
Use `Providers` at the app root (e.g. `app/layout.tsx` for Next.js, `main.tsx` for Vite).
|
|
60
|
+
|
|
61
|
+
## Chain-type slots
|
|
62
|
+
|
|
63
|
+
| Slot | Mounts | When to include |
|
|
64
|
+
|------|--------|-----------------|
|
|
65
|
+
| `EVM` | wagmi (12 EVM chains) | Sonic, Ethereum, Arbitrum, Base, BSC, etc. |
|
|
66
|
+
| `SOLANA` | `@solana/wallet-adapter-react` | Solana support |
|
|
67
|
+
| `SUI` | `@mysten/dapp-kit` | Sui support |
|
|
68
|
+
| `BITCOIN` | (no React adapter) | Bitcoin support |
|
|
69
|
+
| `STELLAR` | (no React adapter) | Stellar support |
|
|
70
|
+
| `ICON` | (no React adapter) | ICON support |
|
|
71
|
+
| `INJECTIVE` | (no React adapter) | Injective support |
|
|
72
|
+
| `NEAR` | (no React adapter) | NEAR support |
|
|
73
|
+
| `STACKS` | (no React adapter) | Stacks support |
|
|
74
|
+
|
|
75
|
+
## Config is captured once on mount
|
|
76
|
+
|
|
77
|
+
`SodaxWalletProvider` freezes the `config` prop on first render. Subsequent re-renders with a new reference have **no effect**. To swap config at runtime, remount with a new `key`:
|
|
78
|
+
|
|
79
|
+
```tsx
|
|
80
|
+
<SodaxWalletProvider key={configVersion} config={walletConfig}>
|
|
81
|
+
{children}
|
|
82
|
+
</SodaxWalletProvider>
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
## Pair with `@sodax/dapp-kit` (optional)
|
|
86
|
+
|
|
87
|
+
If you also use `@sodax/dapp-kit` for SDK feature hooks, mount `SodaxProvider` outermost:
|
|
88
|
+
|
|
89
|
+
```tsx
|
|
90
|
+
<SodaxProvider config={sodaxConfig}>
|
|
91
|
+
<QueryClientProvider client={queryClient}>
|
|
92
|
+
<SodaxWalletProvider config={walletConfig}>{children}</SodaxWalletProvider>
|
|
93
|
+
</QueryClientProvider>
|
|
94
|
+
</SodaxProvider>
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
See [`packages/dapp-kit/skills/setup.md`](https://github.com/icon-project/sodax-sdks/blob/main/packages/dapp-kit/skills/setup.md) for the dapp-kit side.
|
|
98
|
+
|
|
99
|
+
## Next steps
|
|
100
|
+
|
|
101
|
+
- [`connect-button.md`](https://github.com/icon-project/sodax-sdks/blob/main/packages/wallet-sdk-react/skills/connect-button.md) — single-chain connect/disconnect button
|
|
102
|
+
- [`multi-chain-modal.md`](https://github.com/icon-project/sodax-sdks/blob/main/packages/wallet-sdk-react/skills/multi-chain-modal.md) — multi-chain headless wallet modal
|
|
103
|
+
- [`bridge-to-sdk.md`](https://github.com/icon-project/sodax-sdks/blob/main/packages/wallet-sdk-react/skills/bridge-to-sdk.md) — pass `walletProvider` to `@sodax/sdk` calls
|
|
104
|
+
|
|
105
|
+
## Reference docs
|
|
106
|
+
|
|
107
|
+
- [Configure SodaxWalletProvider](https://github.com/icon-project/sodax-sdks/blob/main/packages/wallet-sdk-react/docs/CONFIGURE_PROVIDER.md) — full config reference, breaking changes from v1, per-chain `defaults`
|