@sodax/wallet-sdk-react 1.5.6-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.
Files changed (211) hide show
  1. package/README.md +103 -145
  2. package/ai-exported/AGENTS.md +122 -0
  3. package/ai-exported/integration/README.md +102 -0
  4. package/ai-exported/integration/ai-rules.md +136 -0
  5. package/ai-exported/integration/architecture.md +181 -0
  6. package/ai-exported/integration/examples/01-minimal-evm.tsx +75 -0
  7. package/ai-exported/integration/examples/02-multi-chain-modal.tsx +169 -0
  8. package/ai-exported/integration/examples/03-nextjs-app-router.tsx +99 -0
  9. package/ai-exported/integration/examples/04-walletconnect-setup.tsx +89 -0
  10. package/ai-exported/integration/examples/README.md +29 -0
  11. package/ai-exported/integration/recipes/batch-operations.md +223 -0
  12. package/ai-exported/integration/recipes/bridge-to-sdk.md +164 -0
  13. package/ai-exported/integration/recipes/chain-detection.md +254 -0
  14. package/ai-exported/integration/recipes/connect-button.md +156 -0
  15. package/ai-exported/integration/recipes/multi-chain-modal.md +199 -0
  16. package/ai-exported/integration/recipes/setup.md +158 -0
  17. package/ai-exported/integration/recipes/sign-message.md +137 -0
  18. package/ai-exported/integration/recipes/sub-path-imports.md +95 -0
  19. package/ai-exported/integration/recipes/switch-chain.md +141 -0
  20. package/ai-exported/integration/recipes/walletconnect-setup.md +139 -0
  21. package/ai-exported/integration/reference/api-surface.md +175 -0
  22. package/ai-exported/integration/reference/chain-support.md +78 -0
  23. package/ai-exported/integration/reference/connectors.md +74 -0
  24. package/ai-exported/integration/reference/hooks.md +204 -0
  25. package/ai-exported/integration/reference/wallet-brands.md +106 -0
  26. package/ai-exported/migration/README.md +49 -0
  27. package/ai-exported/migration/ai-rules.md +144 -0
  28. package/ai-exported/migration/breaking-changes.md +305 -0
  29. package/ai-exported/migration/checklist.md +159 -0
  30. package/ai-exported/migration/recipes/connect-button.md +166 -0
  31. package/ai-exported/migration/recipes/multi-chain-modal.md +244 -0
  32. package/ai-exported/migration/recipes/ssr-setup.md +162 -0
  33. package/ai-exported/migration/recipes/walletconnect-migration.md +168 -0
  34. package/ai-exported/migration/reference/components.md +73 -0
  35. package/ai-exported/migration/reference/config.md +307 -0
  36. package/ai-exported/migration/reference/hooks.md +278 -0
  37. package/ai-exported/migration/reference/imports.md +157 -0
  38. package/dist/XConnector-B9YQTVJ4.d.ts +146 -0
  39. package/dist/chunk-2BOUGCJ7.mjs +150 -0
  40. package/dist/chunk-2BOUGCJ7.mjs.map +1 -0
  41. package/dist/chunk-66BAUK56.mjs +202 -0
  42. package/dist/chunk-66BAUK56.mjs.map +1 -0
  43. package/dist/chunk-7ULB6DW4.mjs +102 -0
  44. package/dist/chunk-7ULB6DW4.mjs.map +1 -0
  45. package/dist/chunk-BKJB527E.mjs +125 -0
  46. package/dist/chunk-BKJB527E.mjs.map +1 -0
  47. package/dist/chunk-BXJLBR4G.mjs +88 -0
  48. package/dist/chunk-BXJLBR4G.mjs.map +1 -0
  49. package/dist/chunk-E5IAZ7E6.mjs +186 -0
  50. package/dist/chunk-E5IAZ7E6.mjs.map +1 -0
  51. package/dist/chunk-MAQ47Q52.mjs +33 -0
  52. package/dist/chunk-MAQ47Q52.mjs.map +1 -0
  53. package/dist/chunk-MXZVF5HR.mjs +34 -0
  54. package/dist/chunk-MXZVF5HR.mjs.map +1 -0
  55. package/dist/chunk-N5A2TMF6.mjs +33 -0
  56. package/dist/chunk-N5A2TMF6.mjs.map +1 -0
  57. package/dist/chunk-NY7U7OJW.mjs +64 -0
  58. package/dist/chunk-NY7U7OJW.mjs.map +1 -0
  59. package/dist/chunk-PJLEJVAU.mjs +140 -0
  60. package/dist/chunk-PJLEJVAU.mjs.map +1 -0
  61. package/dist/chunk-PLCA4ZDJ.mjs +1585 -0
  62. package/dist/chunk-PLCA4ZDJ.mjs.map +1 -0
  63. package/dist/chunk-TZMKDXFA.mjs +3 -0
  64. package/dist/chunk-TZMKDXFA.mjs.map +1 -0
  65. package/dist/chunk-X2MHIWXO.mjs +100 -0
  66. package/dist/chunk-X2MHIWXO.mjs.map +1 -0
  67. package/dist/chunk-XZ7CHO2S.mjs +41 -0
  68. package/dist/chunk-XZ7CHO2S.mjs.map +1 -0
  69. package/dist/config-OlnzyEUE.d.ts +146 -0
  70. package/dist/index.cjs +2784 -1594
  71. package/dist/index.cjs.map +1 -1
  72. package/dist/index.d.ts +768 -1498
  73. package/dist/index.mjs +463 -2004
  74. package/dist/index.mjs.map +1 -1
  75. package/dist/xchains/bitcoin/index.cjs +1927 -0
  76. package/dist/xchains/bitcoin/index.cjs.map +1 -0
  77. package/dist/xchains/bitcoin/index.d.ts +125 -0
  78. package/dist/xchains/bitcoin/index.mjs +16 -0
  79. package/dist/xchains/bitcoin/index.mjs.map +1 -0
  80. package/dist/xchains/evm/index.cjs +316 -0
  81. package/dist/xchains/evm/index.cjs.map +1 -0
  82. package/dist/xchains/evm/index.d.ts +39 -0
  83. package/dist/xchains/evm/index.mjs +5 -0
  84. package/dist/xchains/evm/index.mjs.map +1 -0
  85. package/dist/xchains/icon/index.cjs +311 -0
  86. package/dist/xchains/icon/index.cjs.map +1 -0
  87. package/dist/xchains/icon/index.d.ts +37 -0
  88. package/dist/xchains/icon/index.mjs +7 -0
  89. package/dist/xchains/icon/index.mjs.map +1 -0
  90. package/dist/xchains/injective/index.cjs +223 -0
  91. package/dist/xchains/injective/index.cjs.map +1 -0
  92. package/dist/xchains/injective/index.d.ts +35 -0
  93. package/dist/xchains/injective/index.mjs +5 -0
  94. package/dist/xchains/injective/index.mjs.map +1 -0
  95. package/dist/xchains/near/index.cjs +190 -0
  96. package/dist/xchains/near/index.cjs.map +1 -0
  97. package/dist/xchains/near/index.d.ts +34 -0
  98. package/dist/xchains/near/index.mjs +6 -0
  99. package/dist/xchains/near/index.mjs.map +1 -0
  100. package/dist/xchains/solana/index.cjs +186 -0
  101. package/dist/xchains/solana/index.cjs.map +1 -0
  102. package/dist/xchains/solana/index.d.ts +26 -0
  103. package/dist/xchains/solana/index.mjs +7 -0
  104. package/dist/xchains/solana/index.mjs.map +1 -0
  105. package/dist/xchains/stacks/index.cjs +240 -0
  106. package/dist/xchains/stacks/index.cjs.map +1 -0
  107. package/dist/xchains/stacks/index.d.ts +36 -0
  108. package/dist/xchains/stacks/index.mjs +5 -0
  109. package/dist/xchains/stacks/index.mjs.map +1 -0
  110. package/dist/xchains/stellar/index.cjs +322 -0
  111. package/dist/xchains/stellar/index.cjs.map +1 -0
  112. package/dist/xchains/stellar/index.d.ts +44 -0
  113. package/dist/xchains/stellar/index.mjs +6 -0
  114. package/dist/xchains/stellar/index.mjs.map +1 -0
  115. package/dist/xchains/sui/index.cjs +248 -0
  116. package/dist/xchains/sui/index.cjs.map +1 -0
  117. package/dist/xchains/sui/index.d.ts +37 -0
  118. package/dist/xchains/sui/index.mjs +7 -0
  119. package/dist/xchains/sui/index.mjs.map +1 -0
  120. package/docs/ADDING_A_NEW_CHAIN.md +440 -0
  121. package/docs/ARCHITECTURE.md +291 -0
  122. package/docs/BATCH_OPERATIONS.md +267 -0
  123. package/docs/CHAIN_DETECTION.md +216 -0
  124. package/docs/CONFIGURE_PROVIDER.md +360 -0
  125. package/docs/CONNECTORS.md +247 -0
  126. package/docs/CONNECT_FLOW.md +276 -0
  127. package/docs/EVM_SWITCH_CHAIN.md +161 -0
  128. package/docs/SIGN_MESSAGE.md +213 -0
  129. package/docs/SUB_PATH_EXPORTS.md +246 -0
  130. package/docs/WALLETCONNECT.md +154 -0
  131. package/docs/WALLET_MODAL.md +331 -0
  132. package/docs/WALLET_PROVIDER_BRIDGE.md +226 -0
  133. package/package.json +34 -9
  134. package/skills/SKILLS.md +84 -0
  135. package/skills/bridge-to-sdk.md +148 -0
  136. package/skills/connect-button.md +116 -0
  137. package/skills/evm-only-walletconnect.md +111 -0
  138. package/skills/multi-chain-modal.md +178 -0
  139. package/skills/setup.md +107 -0
  140. package/dist/index.d.cts +0 -1579
  141. package/src/Hydrate.ts +0 -65
  142. package/src/SodaxWalletProvider.tsx +0 -97
  143. package/src/actions/getXChainType.ts +0 -8
  144. package/src/actions/getXService.ts +0 -33
  145. package/src/actions/index.ts +0 -2
  146. package/src/assets/wallets/hana.svg +0 -6
  147. package/src/assets/wallets/havah.svg +0 -76
  148. package/src/assets/wallets/keplr.svg +0 -30
  149. package/src/assets/wallets/metamask.svg +0 -60
  150. package/src/assets/wallets/phantom.svg +0 -4
  151. package/src/assets/wallets/sui.svg +0 -20
  152. package/src/core/XConnector.ts +0 -54
  153. package/src/core/XService.ts +0 -85
  154. package/src/core/index.ts +0 -2
  155. package/src/hooks/index.ts +0 -11
  156. package/src/hooks/useEthereumChainId.ts +0 -44
  157. package/src/hooks/useEvmSwitchChain.ts +0 -91
  158. package/src/hooks/useWalletProvider.ts +0 -206
  159. package/src/hooks/useXAccount.ts +0 -51
  160. package/src/hooks/useXAccounts.ts +0 -56
  161. package/src/hooks/useXBalances.ts +0 -65
  162. package/src/hooks/useXConnect.ts +0 -118
  163. package/src/hooks/useXConnection.ts +0 -72
  164. package/src/hooks/useXConnectors.ts +0 -72
  165. package/src/hooks/useXDisconnect.ts +0 -73
  166. package/src/hooks/useXService.ts +0 -8
  167. package/src/hooks/useXSignMessage.ts +0 -82
  168. package/src/index.ts +0 -19
  169. package/src/types/index.ts +0 -22
  170. package/src/useXWagmiStore.ts +0 -116
  171. package/src/utils/index.ts +0 -21
  172. package/src/xchains/bitcoin/BitcoinXConnector.ts +0 -34
  173. package/src/xchains/bitcoin/BitcoinXService.ts +0 -40
  174. package/src/xchains/bitcoin/OKXXConnector.ts +0 -117
  175. package/src/xchains/bitcoin/UnisatXConnector.ts +0 -117
  176. package/src/xchains/bitcoin/XverseXConnector.ts +0 -232
  177. package/src/xchains/bitcoin/index.ts +0 -7
  178. package/src/xchains/bitcoin/useBitcoinXConnectors.ts +0 -14
  179. package/src/xchains/evm/EvmXConnector.ts +0 -27
  180. package/src/xchains/evm/EvmXService.ts +0 -211
  181. package/src/xchains/evm/index.ts +0 -3
  182. package/src/xchains/icon/IconHanaXConnector.ts +0 -39
  183. package/src/xchains/icon/IconXService.ts +0 -117
  184. package/src/xchains/icon/actions.ts +0 -28
  185. package/src/xchains/icon/iconex/index.tsx +0 -46
  186. package/src/xchains/icon/index.ts +0 -2
  187. package/src/xchains/injective/InjectiveXConnector.ts +0 -60
  188. package/src/xchains/injective/InjectiveXService.ts +0 -62
  189. package/src/xchains/injective/actions.ts +0 -32
  190. package/src/xchains/injective/index.ts +0 -2
  191. package/src/xchains/near/NearXConnector.ts +0 -42
  192. package/src/xchains/near/NearXService.ts +0 -46
  193. package/src/xchains/near/useNearXConnectors.ts +0 -23
  194. package/src/xchains/solana/SolanaXConnector.ts +0 -26
  195. package/src/xchains/solana/SolanaXService.ts +0 -46
  196. package/src/xchains/solana/index.ts +0 -2
  197. package/src/xchains/stacks/StacksXConnector.ts +0 -63
  198. package/src/xchains/stacks/StacksXService.ts +0 -59
  199. package/src/xchains/stacks/constants.ts +0 -42
  200. package/src/xchains/stacks/index.ts +0 -4
  201. package/src/xchains/stacks/useStacksXConnectors.ts +0 -7
  202. package/src/xchains/stellar/CustomSorobanServer.ts +0 -93
  203. package/src/xchains/stellar/StellarWalletsKitXConnector.ts +0 -53
  204. package/src/xchains/stellar/StellarXService.ts +0 -93
  205. package/src/xchains/stellar/actions.ts +0 -24
  206. package/src/xchains/stellar/index.tsx +0 -2
  207. package/src/xchains/stellar/useStellarXConnectors.ts +0 -21
  208. package/src/xchains/stellar/utils.ts +0 -49
  209. package/src/xchains/sui/SuiXConnector.ts +0 -28
  210. package/src/xchains/sui/SuiXService.ts +0 -66
  211. package/src/xchains/sui/index.ts +0 -2
@@ -0,0 +1,440 @@
1
+ # Adding a New Chain
2
+
3
+ This document is the contributor workflow for onboarding a new chain family (e.g. Aptos, Cosmos, …) into `@sodax/wallet-sdk-react`. Most steps are mechanical because the central abstractions (`ChainMeta`, `chainRegistry`, sub-path exports) auto-derive downstream types — adding a chain is mostly **filling in entries**, not rewriting hooks.
4
+
5
+ Prerequisite: read [`ARCHITECTURE.md`](https://github.com/icon-project/sodax-sdks/blob/main/packages/wallet-sdk-react/docs/ARCHITECTURE.md) first, especially the [Provider-managed vs non-provider](https://github.com/icon-project/sodax-sdks/blob/main/packages/wallet-sdk-react/docs/ARCHITECTURE.md#provider-managed-vs-non-provider-chains) split — that decision drives the rest of this guide.
6
+
7
+ ## Table of contents
8
+
9
+ 1. [Decision tree — provider-managed or not?](#decision-tree--provider-managed-or-not)
10
+ 2. [Step 1 — types in `@sodax/types`](#step-1--types-in-sodaxtypes)
11
+ 3. [Step 2 — wallet provider in `@sodax/wallet-sdk-core`](#step-2--wallet-provider-in-sodaxwallet-sdk-core)
12
+ 4. [Step 3 — `XService` + `XConnector` in `xchains/<chain>/`](#step-3--xservice--xconnector-in-xchainschain)
13
+ 5. [Step 4 — `xchains/<chain>/index.ts` barrel for sub-path export](#step-4--xchainschainindexts-barrel-for-sub-path-export)
14
+ 6. [Step 5 — `ChainMeta` entry in `types/config.ts`](#step-5--chainmeta-entry-in-typesconfigts)
15
+ 7. [Step 6 — register in `chainRegistry`](#step-6--register-in-chainregistry)
16
+ 8. [Step 7 — provider-managed only — Provider/Hydrator/Actions trio](#step-7--provider-managed-only--providerhydratoractions-trio)
17
+ 9. [Step 8 — barrel surface (`src/index.ts`)](#step-8--barrel-surface-srcindexts)
18
+ 10. [Step 9 — tests](#step-9--tests)
19
+ 11. [Verification checklist](#verification-checklist)
20
+
21
+ ---
22
+
23
+ ## Decision tree — provider-managed or not?
24
+
25
+ Set `providerManaged: true` if **any** of these is true:
26
+
27
+ - The chain ships a React adapter library (wagmi, `@solana/wallet-adapter-react`, `@mysten/dapp-kit`, etc.) that you want to use.
28
+ - The wallet-side SDK requires a long-lived React context to register handlers and survive component re-renders.
29
+ - Wallet discovery is reactive (EIP-6963 announcements, dynamic adapter registration) and you want components to re-render automatically.
30
+
31
+ Set `providerManaged: false` if:
32
+
33
+ - You can probe `window.<wallet>` synchronously per-call.
34
+ - Connection lifecycle is short-lived (call `connect()`, get an account back, no React context needed).
35
+ - The native SDK is plain TS classes/functions with no React glue (e.g. `sats-connect`, `icon-sdk-js`).
36
+
37
+ **Mixing** — you can have a non-provider chain whose `discoverConnectors` is async (Stellar). That's still `providerManaged: false` because the connectors are static after discovery; the React adapter pattern isn't used.
38
+
39
+ ---
40
+
41
+ ## Step 1 — types in `@sodax/types`
42
+
43
+ Add the chain's identity and types to `packages/types/src/`:
44
+
45
+ 1. **Chain key** in [`packages/types/src/chains/chain-keys.ts`](https://github.com/icon-project/sodax-sdks/blob/main/packages/types/src/chains/chain-keys.ts):
46
+ ```typescript
47
+ export const ChainKeys = {
48
+ ...
49
+ APTOS_MAINNET: 'aptos',
50
+ };
51
+ ```
52
+ 2. **Chain type** in `ChainTypeArr`:
53
+ ```typescript
54
+ export const ChainTypeArr = [..., 'APTOS'] as const;
55
+ ```
56
+ 3. **Chain key type alias**:
57
+ ```typescript
58
+ export type AptosChainKey = typeof ChainKeys.APTOS_MAINNET;
59
+ ```
60
+ 4. **Chain info entry** in [`packages/types/src/chains/chains.ts`](https://github.com/icon-project/sodax-sdks/blob/main/packages/types/src/chains/chains.ts) (`baseChainInfo`):
61
+ ```typescript
62
+ [ChainKeys.APTOS_MAINNET]: { type: 'APTOS', chainId: '0x1' /* or numeric */, displayName: 'Aptos' }
63
+ ```
64
+ 5. **Wallet provider interface** in `packages/types/src/aptos.ts`:
65
+ ```typescript
66
+ export interface IAptosWalletProvider extends WalletAddressProvider {
67
+ readonly chainType: 'APTOS';
68
+ // chain-specific methods: signAndSubmitTransaction, signMessage, ...
69
+ }
70
+ ```
71
+ 6. **Add to root barrel** if you want it re-exported from `@sodax/types`, or leave as a sub-package export per [`packages/types/CLAUDE.md`](https://github.com/icon-project/sodax-sdks/blob/main/packages/types/CLAUDE.md).
72
+
73
+ The `ChainKey` and `ChainType` unions auto-derive — once these entries land, downstream code in `@sodax/sdk` and `@sodax/wallet-sdk-react` sees the new chain at the type level.
74
+
75
+ ---
76
+
77
+ ## Step 2 — wallet provider in `@sodax/wallet-sdk-core`
78
+
79
+ Add `packages/wallet-sdk-core/src/wallet-providers/aptos/`:
80
+
81
+ ```
82
+ aptos/
83
+ ├── AptosWalletProvider.ts
84
+ ├── AptosWalletProvider.test.ts
85
+ ├── types.ts # PrivateKey<chain>WalletConfig + BrowserExtension<chain>WalletConfig + AptosWalletDefaults
86
+ └── index.ts # Barrel re-export
87
+ ```
88
+
89
+ `AptosWalletProvider` extends `BaseWalletProvider<AptosWalletDefaults>` and implements `IAptosWalletProvider`. Discriminated config — pick a discriminant pattern:
90
+
91
+ - **Field presence** (no `type` field): `privateKey` field present vs. absent. Most chains use this.
92
+ - **Explicit `type`**: `'PRIVATE_KEY'` | `'BROWSER_EXTENSION'`. Use when both modes share fields that would clash without a discriminant (Bitcoin, Stellar).
93
+
94
+ See [`packages/wallet-sdk-core/CLAUDE.md`](https://github.com/icon-project/sodax-sdks/blob/main/packages/wallet-sdk-core/CLAUDE.md#config-variants-discriminants) for the canonical patterns.
95
+
96
+ Re-export from `packages/wallet-sdk-core/src/wallet-providers/index.ts`:
97
+
98
+ ```typescript
99
+ export * from './aptos/index.js';
100
+ ```
101
+
102
+ ---
103
+
104
+ ## Step 3 — `XService` + `XConnector` in `xchains/<chain>/`
105
+
106
+ Create `packages/wallet-sdk-react/src/xchains/aptos/`:
107
+
108
+ ```
109
+ aptos/
110
+ ├── AptosXService.ts
111
+ ├── AptosXConnector.ts
112
+ ├── AptosXConnector.test.ts
113
+ └── index.ts
114
+ ```
115
+
116
+ ### `AptosXService`
117
+
118
+ Singleton that owns the connector list and exposes balance reads. Extend the abstract `XService`:
119
+
120
+ ```typescript
121
+ import type { XToken } from '@sodax/types';
122
+ import { XService } from '@/core/index.js';
123
+
124
+ export class AptosXService extends XService {
125
+ private static instance: AptosXService | undefined;
126
+
127
+ static getInstance(rpcConfig?: { rpcUrl?: string }): AptosXService {
128
+ if (!AptosXService.instance) AptosXService.instance = new AptosXService(rpcConfig);
129
+ return AptosXService.instance;
130
+ }
131
+
132
+ // chain-specific state (RPC client, etc.)
133
+
134
+ async getBalance(address: string, xToken: XToken): Promise<bigint> {
135
+ // …
136
+ }
137
+ }
138
+ ```
139
+
140
+ ### `AptosXConnector`
141
+
142
+ Extend `XConnector`. The base class provides `id`, `icon`, `isInstalled = true` defaults; override `isInstalled` / `installUrl` for browser-extension-backed connectors:
143
+
144
+ ```typescript
145
+ import { XConnector } from '@/core/index.js';
146
+ import type { XAccount } from '@/types/index.js';
147
+
148
+ export class AptosWalletXConnector extends XConnector {
149
+ constructor() {
150
+ super('APTOS', 'Aptos Wallet', 'aptos.wallet');
151
+ }
152
+
153
+ override get isInstalled(): boolean {
154
+ return typeof window !== 'undefined' && 'aptos' in window;
155
+ }
156
+
157
+ override get installUrl(): string {
158
+ return 'https://chrome.google.com/webstore/detail/...';
159
+ }
160
+
161
+ async connect(): Promise<XAccount | undefined> {
162
+ const account = await window.aptos.connect();
163
+ return account ? { address: account.address, xChainType: 'APTOS', publicKey: account.publicKey } : undefined;
164
+ }
165
+
166
+ async disconnect(): Promise<void> {
167
+ await window.aptos.disconnect();
168
+ }
169
+ }
170
+ ```
171
+
172
+ For chains with multiple wallets (Bitcoin: Unisat / Xverse / OKX; Injective: MetaMask / Keplr / Leap), create one `XConnector` subclass per wallet and have an abstract intermediate base if shared logic exists (Bitcoin uses `BitcoinXConnector` abstract).
173
+
174
+ ---
175
+
176
+ ## Step 4 — `xchains/<chain>/index.ts` barrel for sub-path export
177
+
178
+ Create the barrel that powers `@sodax/wallet-sdk-react/xchains/aptos`:
179
+
180
+ ```typescript
181
+ // src/xchains/aptos/index.ts
182
+ export { AptosXService } from './AptosXService.js';
183
+ export { AptosWalletXConnector } from './AptosXConnector.js';
184
+ ```
185
+
186
+ `tsup.config.ts` already picks up `src/xchains/*/index.ts` via glob — **no config edit needed**. The sub-path export will resolve as `@sodax/wallet-sdk-react/xchains/aptos`.
187
+
188
+ See [`SUB_PATH_EXPORTS.md`](https://github.com/icon-project/sodax-sdks/blob/main/packages/wallet-sdk-react/docs/SUB_PATH_EXPORTS.md) for the export plumbing.
189
+
190
+ ---
191
+
192
+ ## Step 5 — `ChainMeta` entry in `types/config.ts`
193
+
194
+ [`ChainMeta`](https://github.com/icon-project/sodax-sdks/blob/main/packages/wallet-sdk-react/src/types/config.ts) is the **single source of truth** for per-chain-type metadata. `SodaxWalletConfig`, `ChainTypeConfig<T>`, `ChainEntry<K>`, `WalletDefaultsByKey<K>` all derive from it automatically.
195
+
196
+ Add **one entry**:
197
+
198
+ ```typescript
199
+ export type AptosChainEntry = SimpleChainEntry<AptosWalletDefaults>;
200
+
201
+ export type ChainMeta = {
202
+ EVM: { ... };
203
+ // ...
204
+ APTOS: {
205
+ keys: AptosChainKey; // from @sodax/types
206
+ entry: AptosChainEntry; // { rpcUrl?, defaults? } (or richer if chain has multi-field RPC)
207
+ defaults: AptosWalletDefaults;
208
+ adapter: {}; // {} for non-provider chains; AptosAdapterFields if provider-managed
209
+ };
210
+ };
211
+ ```
212
+
213
+ If the chain has multi-field RPC (Stellar's horizon + soroban, Bitcoin's RPC + Radfi), define a custom entry shape that extends `*RpcConfig` from `@sodax/types`:
214
+
215
+ ```typescript
216
+ export type AptosChainEntry = AptosRpcConfig & { defaults?: AptosWalletDefaults };
217
+ ```
218
+
219
+ If provider-managed, define `AptosAdapterFields` (one value per React provider — wagmi-config-level settings, not per-chain):
220
+
221
+ ```typescript
222
+ export type AptosAdapterFields = {
223
+ network?: 'mainnet' | 'testnet' | 'devnet';
224
+ autoConnect?: boolean;
225
+ };
226
+ ```
227
+
228
+ Add the per-chain-type alias for external typing convenience:
229
+
230
+ ```typescript
231
+ export type AptosTypeConfig = ChainTypeConfig<'APTOS'>;
232
+ ```
233
+
234
+ ---
235
+
236
+ ## Step 6 — register in `chainRegistry`
237
+
238
+ Add an entry to [`chainRegistry`](https://github.com/icon-project/sodax-sdks/blob/main/packages/wallet-sdk-react/src/chainRegistry.ts):
239
+
240
+ ### Non-provider chain
241
+
242
+ ```typescript
243
+ APTOS: defineChain({
244
+ createService: walletConfig =>
245
+ AptosXService.getInstance({ rpcUrl: getRpcUrl(walletConfig?.APTOS?.chains?.[ChainKeys.APTOS_MAINNET]) }),
246
+ displayName: 'Aptos',
247
+ defaultConnectors: () => [new AptosWalletXConnector()],
248
+ providerManaged: false,
249
+ // Optional — provide createActions if signMessage needs custom dispatch (Bitcoin's BIP-322/ECDSA)
250
+ createActions: (service, getStore) => ({
251
+ ...createDefaultActions('APTOS', service, getStore),
252
+ signMessage: async (message: string) => {
253
+ // chain-specific signing logic
254
+ },
255
+ }),
256
+ // Optional — provide createWalletProvider if the chain needs a wallet provider in `walletProviders` map
257
+ createWalletProvider: (service, getStore) => {
258
+ const connection = getStore().xConnections.APTOS;
259
+ if (!connection?.xConnectorId) return undefined;
260
+ const defaults = getEntryDefaults<typeof ChainKeys.APTOS_MAINNET>(
261
+ getStore().walletConfig?.APTOS?.chains?.[ChainKeys.APTOS_MAINNET],
262
+ );
263
+ return new AptosWalletProvider({ /* ... */, defaults });
264
+ },
265
+ // Optional — provide discoverConnectors if connectors require async detection
266
+ discoverConnectors: async (service, getStore) => {
267
+ const wallets = await detectInstalledAptosWallets();
268
+ const connectors = wallets.map(w => new AptosWalletXConnector(w));
269
+ service.setXConnectors(connectors);
270
+ getStore().setXConnectors('APTOS', connectors);
271
+ },
272
+ }),
273
+ ```
274
+
275
+ ### Provider-managed chain
276
+
277
+ ```typescript
278
+ APTOS: defineChain({
279
+ createService: () => AptosXService.getInstance(),
280
+ displayName: 'Aptos',
281
+ defaultConnectors: () => [], // ignored — connectors come from the React adapter
282
+ providerManaged: true,
283
+ // No createActions / createWalletProvider — the Hydrator handles both.
284
+ }),
285
+ ```
286
+
287
+ ---
288
+
289
+ ## Step 7 — provider-managed only — Provider/Hydrator/Actions trio
290
+
291
+ Skip this step for `providerManaged: false`.
292
+
293
+ Create `packages/wallet-sdk-react/src/providers/aptos/`:
294
+
295
+ ```
296
+ aptos/
297
+ ├── AptosProvider.tsx # Wraps native React adapter
298
+ ├── AptosHydrator.tsx # Sole writer of connection state + walletProviders
299
+ ├── AptosActions.tsx # Registers ChainActions (connect/disconnect/signMessage)
300
+ ├── AptosHydrator.test.tsx
301
+ └── index.ts
302
+ ```
303
+
304
+ ### `<AptosProvider>`
305
+
306
+ Wraps the chain's native React provider:
307
+
308
+ ```tsx
309
+ import { type ReactNode } from 'react';
310
+ import { AptosProvider as NativeProvider } from 'aptos-adapter-react';
311
+ import { AptosHydrator } from './AptosHydrator.js';
312
+ import { AptosActions } from './AptosActions.js';
313
+ import type { AptosTypeConfig } from '@/types/config.js';
314
+
315
+ type AptosProviderProps = {
316
+ children: ReactNode;
317
+ config: AptosTypeConfig;
318
+ };
319
+
320
+ export const AptosProvider = ({ children, config }: AptosProviderProps) => (
321
+ <NativeProvider network={config.network ?? 'mainnet'} autoConnect={config.autoConnect ?? true}>
322
+ <AptosHydrator />
323
+ <AptosActions />
324
+ {children}
325
+ </NativeProvider>
326
+ );
327
+ ```
328
+
329
+ ### `<AptosHydrator>`
330
+
331
+ Sole writer. Subscribes to native SDK hooks; writes through `setXConnection` / `setWalletProvider`. **Never** writes inside an event handler — only inside `useEffect` reactions to native state.
332
+
333
+ ```typescript
334
+ import { useAccount } from 'aptos-adapter-react';
335
+
336
+ export const AptosHydrator = () => {
337
+ const { address, status, connector } = useAccount();
338
+ const setXConnection = useXWalletStore(s => s.setXConnection);
339
+ const unsetXConnection = useXWalletStore(s => s.unsetXConnection);
340
+
341
+ useEffect(() => {
342
+ if (status === 'connected' && address) {
343
+ setXConnection('APTOS', { xAccount: { address, xChainType: 'APTOS' }, xConnectorId: connector.id });
344
+ } else if (status === 'disconnected') {
345
+ unsetXConnection('APTOS');
346
+ }
347
+ }, [address, status, connector]);
348
+
349
+ // ... build wallet provider similarly via useMemo + setWalletProvider
350
+
351
+ return null;
352
+ };
353
+ ```
354
+
355
+ ### `<AptosActions>`
356
+
357
+ Registers `ChainActions` using **refs** to native SDK functions, so the registered closures always call the latest function without re-registering:
358
+
359
+ ```typescript
360
+ const connectRef = useRef(connectAsync);
361
+ useEffect(() => { connectRef.current = connectAsync; }, [connectAsync]);
362
+
363
+ useEffect(() => {
364
+ registerChainActions('APTOS', {
365
+ connect: async (id) => connectRef.current({ connector: id }),
366
+ disconnect: async () => disconnectRef.current(),
367
+ // ...
368
+ });
369
+ }, []); // empty deps — register once
370
+
371
+ return null;
372
+ ```
373
+
374
+ ### Mount in `SodaxWalletProvider.tsx`
375
+
376
+ ```tsx
377
+ {frozen.APTOS && (
378
+ <AptosProvider config={frozen.APTOS}>
379
+ {content}
380
+ </AptosProvider>
381
+ )}
382
+ ```
383
+
384
+ ---
385
+
386
+ ## Step 8 — barrel surface (`src/index.ts`)
387
+
388
+ **Do NOT** add `export * from './xchains/aptos'` to the root `src/index.ts`. Concrete classes stay behind sub-path imports.
389
+
390
+ If consumers need a **type** from the barrel for type-only ergonomics, add an explicit `export type` line:
391
+
392
+ ```typescript
393
+ // src/index.ts
394
+ export type { AptosWalletAddressType } from './xchains/aptos/index.js';
395
+ ```
396
+
397
+ This keeps runtime classes off the barrel but lets consumers `import type { AptosWalletAddressType } from '@sodax/wallet-sdk-react'` without going through the deep import for a type-only reference.
398
+
399
+ See [`SUB_PATH_EXPORTS.md`](https://github.com/icon-project/sodax-sdks/blob/main/packages/wallet-sdk-react/docs/SUB_PATH_EXPORTS.md) for why concrete classes are deep-imported.
400
+
401
+ ---
402
+
403
+ ## Step 9 — tests
404
+
405
+ Required test surface per `vitest.config.ts`:
406
+
407
+ - `AptosXConnector.test.ts` — connector constructor, `connect/disconnect`, `isInstalled`/`installUrl` window probes
408
+ - `AptosXService.test.ts` (or co-located) — singleton behavior, balance reads
409
+ - `AptosWalletProvider.test.ts` (in wallet-sdk-core) — config variants, defaults merge, core method dispatch
410
+ - `AptosHydrator.test.tsx` (provider-managed only) — fake adapter state → assert store writes
411
+
412
+ Pattern reference: [`EvmHydrator.test.tsx`](https://github.com/icon-project/sodax-sdks/blob/main/packages/wallet-sdk-react/src/providers/evm/EvmHydrator.test.tsx).
413
+
414
+ ---
415
+
416
+ ## Verification checklist
417
+
418
+ Before opening a PR, walk through each item:
419
+
420
+ - [ ] `pnpm checkTs` passes — `SodaxWalletConfig.APTOS` is recognized; `useWalletProvider({ xChainType: 'APTOS' })` returns the right type.
421
+ - [ ] `pnpm test` passes for new files.
422
+ - [ ] `pnpm build:packages` produces `dist/xchains/aptos/index.{mjs,cjs,d.ts}`.
423
+ - [ ] `import { AptosXService } from '@sodax/wallet-sdk-react/xchains/aptos'` resolves in a consumer app.
424
+ - [ ] `import { AptosXService } from '@sodax/wallet-sdk-react'` is **not** available (intentional — concrete classes stay behind deep imports).
425
+ - [ ] Adding `APTOS: {}` to `SodaxWalletConfig` mounts the chain; omitting the slot skips it.
426
+ - [ ] `useEnabledChains()` includes `'APTOS'` only when the slot is present.
427
+ - [ ] Connect → disconnect cycle updates `xConnections.APTOS` correctly; `localStorage` persists.
428
+ - [ ] On reload, `cleanupDisabledConnections` removes `xConnections.APTOS` if the slot is later removed.
429
+ - [ ] Documentation: add an entry to the connector reference in [`CONNECTORS.md`](https://github.com/icon-project/sodax-sdks/blob/main/packages/wallet-sdk-react/docs/CONNECTORS.md) and the chain-type tables in [`CONFIGURE_PROVIDER.md`](https://github.com/icon-project/sodax-sdks/blob/main/packages/wallet-sdk-react/docs/CONFIGURE_PROVIDER.md).
430
+
431
+ ---
432
+
433
+ ## Related docs
434
+
435
+ - [Architecture](https://github.com/icon-project/sodax-sdks/blob/main/packages/wallet-sdk-react/docs/ARCHITECTURE.md) — store + registry + Hydrator pattern
436
+ - [Sub-path Exports](https://github.com/icon-project/sodax-sdks/blob/main/packages/wallet-sdk-react/docs/SUB_PATH_EXPORTS.md) — barrel vs deep-import boundary
437
+ - [Configure SodaxWalletProvider](https://github.com/icon-project/sodax-sdks/blob/main/packages/wallet-sdk-react/docs/CONFIGURE_PROVIDER.md) — config schema (auto-extends from `ChainMeta`)
438
+ - [Connectors](https://github.com/icon-project/sodax-sdks/blob/main/packages/wallet-sdk-react/docs/CONNECTORS.md) — IXConnector contract + sub-path map
439
+ - [`packages/wallet-sdk-core/CLAUDE.md`](https://github.com/icon-project/sodax-sdks/blob/main/packages/wallet-sdk-core/CLAUDE.md) — wallet provider class patterns
440
+ - [`packages/types/CLAUDE.md`](https://github.com/icon-project/sodax-sdks/blob/main/packages/types/CLAUDE.md) — interface conventions