@oydual31/more-vaults-sdk 0.2.1 → 0.2.2
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/dist/react/index.cjs +146 -81
- package/dist/react/index.cjs.map +1 -1
- package/dist/react/index.d.cts +6 -6
- package/dist/react/index.d.ts +6 -6
- package/dist/react/index.js +146 -81
- package/dist/react/index.js.map +1 -1
- package/dist/{spokeRoutes-BFI1m_zk.d.cts → spokeRoutes-CK5NSOOF.d.cts} +26 -1
- package/dist/{spokeRoutes-BFI1m_zk.d.ts → spokeRoutes-CK5NSOOF.d.ts} +26 -1
- package/dist/viem/index.cjs +139 -87
- package/dist/viem/index.cjs.map +1 -1
- package/dist/viem/index.d.cts +1 -1
- package/dist/viem/index.d.ts +1 -1
- package/dist/viem/index.js +139 -88
- package/dist/viem/index.js.map +1 -1
- package/package.json +1 -1
- package/src/react/useVaultTopology.ts +14 -9
- package/src/viem/index.ts +1 -0
- package/src/viem/topology.ts +85 -1
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@ import { usePublicClient, useChainId } from 'wagmi'
|
|
|
2
2
|
import { useQuery } from '@tanstack/react-query'
|
|
3
3
|
import { asSdkClient } from '../viem/wagmiCompat.js'
|
|
4
4
|
import {
|
|
5
|
-
|
|
5
|
+
discoverVaultTopology,
|
|
6
6
|
isOnHubChain,
|
|
7
7
|
getAllVaultChainIds,
|
|
8
8
|
OMNI_FACTORY_ADDRESS,
|
|
@@ -28,14 +28,14 @@ interface UseVaultTopologyReturn {
|
|
|
28
28
|
}
|
|
29
29
|
|
|
30
30
|
/**
|
|
31
|
-
* Resolve the cross-chain topology of a vault
|
|
31
|
+
* Resolve the cross-chain topology of a vault with automatic multi-chain discovery.
|
|
32
32
|
*
|
|
33
|
-
*
|
|
34
|
-
*
|
|
35
|
-
*
|
|
36
|
-
* Since MoreVaults uses CREATE3, the vault address is the same on all chains.
|
|
33
|
+
* Uses `discoverVaultTopology` internally: if the wallet's current chain doesn't
|
|
34
|
+
* know the vault, it iterates all supported chains via public RPCs until the hub
|
|
35
|
+
* is found. Works even without a connected wallet.
|
|
37
36
|
*
|
|
38
37
|
* @example
|
|
38
|
+
* // Works regardless of which chain the wallet is on (or if disconnected)
|
|
39
39
|
* const { topology, needsNetworkSwitch, allChainIds } = useVaultTopology('0xVAULT')
|
|
40
40
|
*
|
|
41
41
|
* if (needsNetworkSwitch) {
|
|
@@ -50,9 +50,14 @@ export function useVaultTopology(
|
|
|
50
50
|
const publicClient = usePublicClient()
|
|
51
51
|
|
|
52
52
|
const { data: topology, isLoading } = useQuery<VaultTopology>({
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
53
|
+
// Key does NOT include currentChainId — topology is chain-independent
|
|
54
|
+
queryKey: ['vaultTopology', vault, factoryAddress],
|
|
55
|
+
queryFn: () => discoverVaultTopology(
|
|
56
|
+
vault!,
|
|
57
|
+
publicClient ? asSdkClient(publicClient) : null,
|
|
58
|
+
factoryAddress,
|
|
59
|
+
),
|
|
60
|
+
enabled: !!vault,
|
|
56
61
|
staleTime: 5 * 60 * 1000, // topology rarely changes — 5 min cache
|
|
57
62
|
})
|
|
58
63
|
|
package/src/viem/index.ts
CHANGED
package/src/viem/topology.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { type Address, type PublicClient, getAddress } from 'viem'
|
|
2
|
-
import { EID_TO_CHAIN_ID, CHAIN_ID_TO_EID } from './chains'
|
|
2
|
+
import { EID_TO_CHAIN_ID, CHAIN_ID_TO_EID, CHAIN_IDS } from './chains'
|
|
3
|
+
import { createChainClient } from './spokeRoutes'
|
|
3
4
|
|
|
4
5
|
// MoreVaults OMNI factory — same address on every supported chain (CREATE3)
|
|
5
6
|
export const OMNI_FACTORY_ADDRESS: Address = '0x7bDB8B17604b03125eFAED33cA0c55FBf856BB0C'
|
|
@@ -170,6 +171,89 @@ export async function getFullVaultTopology(
|
|
|
170
171
|
return topo
|
|
171
172
|
}
|
|
172
173
|
|
|
174
|
+
/** All mainnet chain IDs where the OMNI_FACTORY is deployed */
|
|
175
|
+
const DISCOVERY_CHAIN_IDS = Object.values(CHAIN_IDS).filter(
|
|
176
|
+
id => id !== 545, // exclude testnet
|
|
177
|
+
) as number[]
|
|
178
|
+
|
|
179
|
+
/**
|
|
180
|
+
* Discover a vault's topology across all supported chains.
|
|
181
|
+
*
|
|
182
|
+
* Unlike `getVaultTopology` (which queries a single chain), this function
|
|
183
|
+
* automatically iterates all supported chains when the initial query returns
|
|
184
|
+
* `role: "local"`. This handles the case where the caller doesn't know which
|
|
185
|
+
* chain the vault is deployed on, or when no wallet is connected.
|
|
186
|
+
*
|
|
187
|
+
* If a `publicClient` is provided, it's tried first. If that returns "local",
|
|
188
|
+
* every other supported chain is probed via `createChainClient` (public RPCs).
|
|
189
|
+
* If no `publicClient` is provided, all chains are probed.
|
|
190
|
+
*
|
|
191
|
+
* Once a hub is found, `getFullVaultTopology` is called to get the complete
|
|
192
|
+
* spoke list.
|
|
193
|
+
*
|
|
194
|
+
* @param vault Vault address (same on all chains via CREATE3)
|
|
195
|
+
* @param publicClient Optional — client for the "preferred" chain to try first
|
|
196
|
+
* @param factoryAddress MoreVaults factory (defaults to OMNI_FACTORY_ADDRESS)
|
|
197
|
+
*
|
|
198
|
+
* @example
|
|
199
|
+
* // No wallet connected — discovers that 0x8f74... is hub on Base
|
|
200
|
+
* const topo = await discoverVaultTopology('0x8f740...')
|
|
201
|
+
* // { role: 'hub', hubChainId: 8453, spokeChainIds: [1, 42161] }
|
|
202
|
+
*/
|
|
203
|
+
export async function discoverVaultTopology(
|
|
204
|
+
vault: Address,
|
|
205
|
+
publicClient?: PublicClient | null,
|
|
206
|
+
factoryAddress: Address = OMNI_FACTORY_ADDRESS,
|
|
207
|
+
): Promise<VaultTopology> {
|
|
208
|
+
const v = getAddress(vault)
|
|
209
|
+
|
|
210
|
+
// 1. Try the provided client first (fast path — avoids extra RPC calls)
|
|
211
|
+
let triedChainId: number | undefined
|
|
212
|
+
if (publicClient) {
|
|
213
|
+
try {
|
|
214
|
+
const topo = await getVaultTopology(publicClient, v, factoryAddress)
|
|
215
|
+
if (topo.role !== 'local') {
|
|
216
|
+
// Found hub or spoke — if spoke, resolve full topology from hub
|
|
217
|
+
if (topo.role === 'spoke') {
|
|
218
|
+
const hubClient = createChainClient(topo.hubChainId)
|
|
219
|
+
if (hubClient) {
|
|
220
|
+
try {
|
|
221
|
+
return await getFullVaultTopology(hubClient, v, factoryAddress)
|
|
222
|
+
} catch { /* fall through to return partial */ }
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
return topo
|
|
226
|
+
}
|
|
227
|
+
triedChainId = publicClient.chain?.id
|
|
228
|
+
} catch { /* client failed — continue with discovery */ }
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
// 2. Iterate all supported chains
|
|
232
|
+
for (const chainId of DISCOVERY_CHAIN_IDS) {
|
|
233
|
+
if (chainId === triedChainId) continue
|
|
234
|
+
const client = createChainClient(chainId)
|
|
235
|
+
if (!client) continue
|
|
236
|
+
|
|
237
|
+
try {
|
|
238
|
+
const topo = await getVaultTopology(client, v, factoryAddress)
|
|
239
|
+
if (topo.role === 'hub') return topo
|
|
240
|
+
if (topo.role === 'spoke') {
|
|
241
|
+
// Found spoke — get full topology from hub
|
|
242
|
+
const hubClient = createChainClient(topo.hubChainId)
|
|
243
|
+
if (hubClient) {
|
|
244
|
+
try {
|
|
245
|
+
return await getFullVaultTopology(hubClient, v, factoryAddress)
|
|
246
|
+
} catch { return topo }
|
|
247
|
+
}
|
|
248
|
+
return topo
|
|
249
|
+
}
|
|
250
|
+
} catch { /* this chain doesn't have the factory or vault — skip */ }
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
// 3. Not found on any chain — return local with chainId 0
|
|
254
|
+
return { role: 'local', hubChainId: 0, spokeChainIds: [] }
|
|
255
|
+
}
|
|
256
|
+
|
|
173
257
|
/**
|
|
174
258
|
* Check if a wallet is connected to the hub chain for a given vault.
|
|
175
259
|
* Useful for showing a "Switch to Base" prompt before deposit.
|