@oydual31/more-vaults-sdk 0.4.2 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +94 -0
- package/dist/{spokeRoutes-B8Lnk-t4.d.cts → curatorBridge-CNs59kT9.d.cts} +222 -1
- package/dist/{spokeRoutes-B8Lnk-t4.d.ts → curatorBridge-CNs59kT9.d.ts} +222 -1
- package/dist/ethers/index.cjs +328 -3
- package/dist/ethers/index.cjs.map +1 -1
- package/dist/ethers/index.d.cts +279 -1
- package/dist/ethers/index.d.ts +279 -1
- package/dist/ethers/index.js +318 -5
- package/dist/ethers/index.js.map +1 -1
- package/dist/react/index.cjs +375 -0
- package/dist/react/index.cjs.map +1 -1
- package/dist/react/index.d.cts +266 -2
- package/dist/react/index.d.ts +266 -2
- package/dist/react/index.js +372 -2
- package/dist/react/index.js.map +1 -1
- package/dist/viem/index.cjs +377 -0
- package/dist/viem/index.cjs.map +1 -1
- package/dist/viem/index.d.cts +261 -3
- package/dist/viem/index.d.ts +261 -3
- package/dist/viem/index.js +367 -2
- package/dist/viem/index.js.map +1 -1
- package/package.json +1 -1
- package/src/ethers/abis.ts +24 -0
- package/src/ethers/curatorBridge.ts +235 -0
- package/src/ethers/curatorSubVaults.ts +443 -0
- package/src/ethers/index.ts +26 -0
- package/src/ethers/types.ts +99 -0
- package/src/react/index.ts +14 -0
- package/src/react/useCuratorBridgeQuote.ts +43 -0
- package/src/react/useERC7540RequestStatus.ts +43 -0
- package/src/react/useExecuteBridge.ts +50 -0
- package/src/react/useSubVaultPositions.ts +35 -0
- package/src/react/useVaultPortfolio.ts +35 -0
- package/src/viem/abis.ts +24 -0
- package/src/viem/curatorBridge.ts +288 -0
- package/src/viem/curatorSubVaults.ts +514 -0
- package/src/viem/index.ts +23 -0
- package/src/viem/types.ts +100 -0
package/package.json
CHANGED
package/src/ethers/abis.ts
CHANGED
|
@@ -177,3 +177,27 @@ export const REGISTRY_ABI = [
|
|
|
177
177
|
"function isBridgeAllowed(address bridge) view returns (bool)",
|
|
178
178
|
"function getAllowedFacets() view returns (address[])",
|
|
179
179
|
] as const;
|
|
180
|
+
|
|
181
|
+
/**
|
|
182
|
+
* Sub-vault ABI — reads for ERC4626/ERC7540 sub-vaults and ConfigurationFacet extensions.
|
|
183
|
+
* Used by curator sub-vault portfolio helpers (Phase 5).
|
|
184
|
+
*/
|
|
185
|
+
export const SUB_VAULT_ABI = [
|
|
186
|
+
// ConfigurationFacet reads — called on the MoreVaults diamond proxy
|
|
187
|
+
"function tokensHeld(bytes32 id) view returns (address[])",
|
|
188
|
+
"function lockedTokensAmountOfAsset(address asset) view returns (uint256)",
|
|
189
|
+
|
|
190
|
+
// ERC4626 standard reads — called on the sub-vault contract
|
|
191
|
+
"function convertToAssets(uint256 shares) view returns (uint256)",
|
|
192
|
+
"function convertToShares(uint256 assets) view returns (uint256)",
|
|
193
|
+
"function previewDeposit(uint256 assets) view returns (uint256)",
|
|
194
|
+
"function previewRedeem(uint256 shares) view returns (uint256)",
|
|
195
|
+
"function maxDeposit(address receiver) view returns (uint256)",
|
|
196
|
+
"function maxRedeem(address owner) view returns (uint256)",
|
|
197
|
+
|
|
198
|
+
// ERC7540 async reads — called on the sub-vault contract
|
|
199
|
+
"function pendingDepositRequest(uint256 requestId, address controller) view returns (uint256)",
|
|
200
|
+
"function claimableDepositRequest(uint256 requestId, address controller) view returns (uint256)",
|
|
201
|
+
"function pendingRedeemRequest(uint256 requestId, address controller) view returns (uint256)",
|
|
202
|
+
"function claimableRedeemRequest(uint256 requestId, address controller) view returns (uint256)",
|
|
203
|
+
] as const;
|
|
@@ -0,0 +1,235 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Curator BridgeFacet helpers for the MoreVaults ethers.js v6 SDK.
|
|
3
|
+
*
|
|
4
|
+
* Provides typed helpers to quote and execute cross-chain asset bridging
|
|
5
|
+
* via BridgeFacet.executeBridging on any MoreVaults diamond.
|
|
6
|
+
*
|
|
7
|
+
* Key flows:
|
|
8
|
+
* 1. `quoteCuratorBridgeFee` — read-only fee estimation via LzAdapter
|
|
9
|
+
* 2. `executeCuratorBridge` — send bridging transaction (curator only)
|
|
10
|
+
* 3. `encodeBridgeParams` — encode the 5-field bridgeSpecificParams bytes
|
|
11
|
+
* 4. `findBridgeRoute` — resolve OFT route for a token on given chains
|
|
12
|
+
*
|
|
13
|
+
* @module curatorBridge
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
import { AbiCoder, Contract, getAddress } from "ethers";
|
|
17
|
+
import type { Provider, Signer, ContractTransactionReceipt } from "ethers";
|
|
18
|
+
import { BRIDGE_FACET_ABI, LZ_ADAPTER_ABI } from "./abis";
|
|
19
|
+
import { OFT_ROUTES } from "./chains";
|
|
20
|
+
import { getCuratorVaultStatus } from "./curatorStatus";
|
|
21
|
+
|
|
22
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
23
|
+
// Types
|
|
24
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Parameters for a curator bridge operation.
|
|
28
|
+
*/
|
|
29
|
+
export interface CuratorBridgeParams {
|
|
30
|
+
/** OFT contract address on the source chain (from OFT_ROUTES[symbol][chainId].oft) */
|
|
31
|
+
oftToken: string;
|
|
32
|
+
/** LayerZero endpoint ID of the destination chain */
|
|
33
|
+
dstEid: number;
|
|
34
|
+
/** Amount to bridge (in token's native units) */
|
|
35
|
+
amount: bigint;
|
|
36
|
+
/** Vault address on the destination chain (hub or spoke) */
|
|
37
|
+
dstVault: string;
|
|
38
|
+
/** Address where excess LayerZero gas refunds are sent (usually the curator wallet) */
|
|
39
|
+
refundAddress: string;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
43
|
+
// Encoding helpers
|
|
44
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Encode the 5-field bridgeSpecificParams for use in `executeBridging`.
|
|
48
|
+
*
|
|
49
|
+
* Encodes: (oftToken, dstEid, amount, dstVault, refundAddress)
|
|
50
|
+
* Types: (address, uint32, uint256, address, address)
|
|
51
|
+
*
|
|
52
|
+
* @param params Full bridge parameters including refundAddress
|
|
53
|
+
* @returns ABI-encoded hex string
|
|
54
|
+
*/
|
|
55
|
+
export function encodeBridgeParams(params: CuratorBridgeParams): string {
|
|
56
|
+
const coder = AbiCoder.defaultAbiCoder();
|
|
57
|
+
return coder.encode(
|
|
58
|
+
["address", "uint32", "uint256", "address", "address"],
|
|
59
|
+
[
|
|
60
|
+
getAddress(params.oftToken),
|
|
61
|
+
params.dstEid,
|
|
62
|
+
params.amount,
|
|
63
|
+
getAddress(params.dstVault),
|
|
64
|
+
getAddress(params.refundAddress),
|
|
65
|
+
]
|
|
66
|
+
);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Encode the 4-field bridgeSpecificParams for `quoteBridgeFee`.
|
|
71
|
+
* Does NOT include refundAddress — quoting only needs routing parameters.
|
|
72
|
+
*
|
|
73
|
+
* @internal
|
|
74
|
+
*/
|
|
75
|
+
function encodeBridgeParamsForQuote(
|
|
76
|
+
params: Omit<CuratorBridgeParams, "refundAddress">
|
|
77
|
+
): string {
|
|
78
|
+
const coder = AbiCoder.defaultAbiCoder();
|
|
79
|
+
return coder.encode(
|
|
80
|
+
["address", "uint32", "uint256", "address"],
|
|
81
|
+
[
|
|
82
|
+
getAddress(params.oftToken),
|
|
83
|
+
params.dstEid,
|
|
84
|
+
params.amount,
|
|
85
|
+
getAddress(params.dstVault),
|
|
86
|
+
]
|
|
87
|
+
);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
91
|
+
// Route resolver
|
|
92
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* Find the OFT bridge route for a given token address on the source chain.
|
|
96
|
+
*
|
|
97
|
+
* Searches OFT_ROUTES for an asset whose `token` or `oft` field matches
|
|
98
|
+
* the provided address on the given source chainId.
|
|
99
|
+
*
|
|
100
|
+
* @param srcChainId EVM chain ID of the source chain
|
|
101
|
+
* @param dstChainId EVM chain ID of the destination chain
|
|
102
|
+
* @param tokenAddress ERC-20 token address on the source chain
|
|
103
|
+
* @returns Route info or null if no matching route exists
|
|
104
|
+
*/
|
|
105
|
+
export function findBridgeRoute(
|
|
106
|
+
srcChainId: number,
|
|
107
|
+
dstChainId: number,
|
|
108
|
+
tokenAddress: string
|
|
109
|
+
): { oftSrc: string; oftDst: string; symbol: string } | null {
|
|
110
|
+
const normalizedToken = getAddress(tokenAddress);
|
|
111
|
+
|
|
112
|
+
for (const [symbol, chains] of Object.entries(OFT_ROUTES)) {
|
|
113
|
+
const srcEntry = (
|
|
114
|
+
chains as Record<number, { oft: string; token: string }>
|
|
115
|
+
)[srcChainId];
|
|
116
|
+
const dstEntry = (
|
|
117
|
+
chains as Record<number, { oft: string; token: string }>
|
|
118
|
+
)[dstChainId];
|
|
119
|
+
|
|
120
|
+
if (!srcEntry || !dstEntry) continue;
|
|
121
|
+
|
|
122
|
+
const srcToken = getAddress(srcEntry.token);
|
|
123
|
+
const srcOft = getAddress(srcEntry.oft);
|
|
124
|
+
|
|
125
|
+
if (srcToken === normalizedToken || srcOft === normalizedToken) {
|
|
126
|
+
return {
|
|
127
|
+
oftSrc: srcOft,
|
|
128
|
+
oftDst: getAddress(dstEntry.oft),
|
|
129
|
+
symbol,
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
return null;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
138
|
+
// Read operations
|
|
139
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
140
|
+
|
|
141
|
+
/**
|
|
142
|
+
* Quote the native fee required to bridge assets via the vault's LzAdapter.
|
|
143
|
+
*
|
|
144
|
+
* Calls `lzAdapter.quoteBridgeFee(bridgeSpecificParams)` using a 4-field
|
|
145
|
+
* encoding (no refundAddress). The returned fee must be sent as `value`
|
|
146
|
+
* when calling `executeBridging`.
|
|
147
|
+
*
|
|
148
|
+
* @param provider Read-only provider (must be on the vault's chain)
|
|
149
|
+
* @param vault Hub vault address (diamond proxy)
|
|
150
|
+
* @param params Bridge parameters (refundAddress is included but not encoded for quote)
|
|
151
|
+
* @returns Native fee in wei
|
|
152
|
+
*
|
|
153
|
+
* @example
|
|
154
|
+
* ```typescript
|
|
155
|
+
* const fee = await quoteCuratorBridgeFee(provider, VAULT, {
|
|
156
|
+
* oftToken: '0x27a16dc786820B16E5c9028b75B99F6f604b5d26',
|
|
157
|
+
* dstEid: 30101,
|
|
158
|
+
* amount: 1_000_000n,
|
|
159
|
+
* dstVault: '0xSpokeVault...',
|
|
160
|
+
* refundAddress: '0xCurator...',
|
|
161
|
+
* })
|
|
162
|
+
* ```
|
|
163
|
+
*/
|
|
164
|
+
export async function quoteCuratorBridgeFee(
|
|
165
|
+
provider: Provider,
|
|
166
|
+
vault: string,
|
|
167
|
+
params: CuratorBridgeParams
|
|
168
|
+
): Promise<bigint> {
|
|
169
|
+
const status = await getCuratorVaultStatus(provider, vault);
|
|
170
|
+
const lzAdapter = status.lzAdapter;
|
|
171
|
+
|
|
172
|
+
const bridgeSpecificParams = encodeBridgeParamsForQuote(params);
|
|
173
|
+
|
|
174
|
+
const adapterContract = new Contract(lzAdapter, LZ_ADAPTER_ABI, provider);
|
|
175
|
+
const nativeFee = (await adapterContract.quoteBridgeFee.staticCall(
|
|
176
|
+
bridgeSpecificParams
|
|
177
|
+
)) as bigint;
|
|
178
|
+
|
|
179
|
+
return nativeFee;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
183
|
+
// Write operations
|
|
184
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
185
|
+
|
|
186
|
+
/**
|
|
187
|
+
* Execute a curator bridge operation via `BridgeFacet.executeBridging`.
|
|
188
|
+
*
|
|
189
|
+
* This is a direct curator call (NOT via multicall). The vault pauses during
|
|
190
|
+
* bridging for security. The `token` parameter is the underlying ERC-20,
|
|
191
|
+
* NOT the OFT address.
|
|
192
|
+
*
|
|
193
|
+
* Steps:
|
|
194
|
+
* 1. Get lzAdapter from `getCuratorVaultStatus`
|
|
195
|
+
* 2. Quote the native bridge fee
|
|
196
|
+
* 3. Encode 5-field bridgeSpecificParams
|
|
197
|
+
* 4. Call `vault.executeBridging(adapter, token, amount, bridgeSpecificParams)` with fee as value
|
|
198
|
+
*
|
|
199
|
+
* @param signer Signer with curator account attached
|
|
200
|
+
* @param vault Hub vault address (diamond proxy)
|
|
201
|
+
* @param token Underlying ERC-20 token address (NOT the OFT address)
|
|
202
|
+
* @param params Full bridge parameters including refundAddress
|
|
203
|
+
* @returns Transaction receipt
|
|
204
|
+
* @throws If caller is not curator, vault is paused, or bridge fails
|
|
205
|
+
*/
|
|
206
|
+
export async function executeCuratorBridge(
|
|
207
|
+
signer: Signer,
|
|
208
|
+
vault: string,
|
|
209
|
+
token: string,
|
|
210
|
+
params: CuratorBridgeParams
|
|
211
|
+
): Promise<ContractTransactionReceipt> {
|
|
212
|
+
const provider = signer.provider!;
|
|
213
|
+
|
|
214
|
+
// Step 1: Get lzAdapter address from vault status
|
|
215
|
+
const status = await getCuratorVaultStatus(provider, vault);
|
|
216
|
+
const lzAdapter = status.lzAdapter;
|
|
217
|
+
|
|
218
|
+
// Step 2: Quote the bridge fee
|
|
219
|
+
const fee = await quoteCuratorBridgeFee(provider, vault, params);
|
|
220
|
+
|
|
221
|
+
// Step 3: Encode full 5-field bridgeSpecificParams
|
|
222
|
+
const bridgeSpecificParams = encodeBridgeParams(params);
|
|
223
|
+
|
|
224
|
+
// Step 4: Execute bridging
|
|
225
|
+
const vaultContract = new Contract(vault, BRIDGE_FACET_ABI, signer);
|
|
226
|
+
const tx = await vaultContract.executeBridging(
|
|
227
|
+
getAddress(lzAdapter),
|
|
228
|
+
getAddress(token),
|
|
229
|
+
params.amount,
|
|
230
|
+
bridgeSpecificParams,
|
|
231
|
+
{ value: fee }
|
|
232
|
+
);
|
|
233
|
+
|
|
234
|
+
return tx.wait() as Promise<ContractTransactionReceipt>;
|
|
235
|
+
}
|