@luxfi/dex 1.2.1 → 1.3.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.
Files changed (62) hide show
  1. package/dist/client/clob.d.ts +52 -0
  2. package/dist/client/clob.d.ts.map +1 -0
  3. package/dist/client/clob.js +196 -0
  4. package/dist/client/index.d.ts +7 -0
  5. package/dist/client/index.d.ts.map +1 -0
  6. package/dist/client/index.js +6 -0
  7. package/dist/client/types.d.ts +126 -0
  8. package/dist/client/types.d.ts.map +1 -0
  9. package/dist/client/types.js +5 -0
  10. package/dist/hooks/index.d.ts +7 -0
  11. package/dist/hooks/index.d.ts.map +1 -0
  12. package/dist/hooks/index.js +6 -0
  13. package/dist/hooks/use-quote.d.ts +18 -0
  14. package/dist/hooks/use-quote.d.ts.map +1 -0
  15. package/dist/hooks/use-quote.js +65 -0
  16. package/dist/hooks/use-swap.d.ts +17 -0
  17. package/dist/hooks/use-swap.d.ts.map +1 -0
  18. package/dist/hooks/use-swap.js +75 -0
  19. package/dist/index.d.ts +33 -115
  20. package/dist/index.d.ts.map +1 -1
  21. package/dist/index.js +41 -225
  22. package/dist/precompile/abis.d.ts +400 -0
  23. package/dist/precompile/abis.d.ts.map +1 -0
  24. package/dist/precompile/abis.js +287 -0
  25. package/dist/precompile/addresses.d.ts +65 -0
  26. package/dist/precompile/addresses.d.ts.map +1 -0
  27. package/dist/precompile/addresses.js +52 -0
  28. package/dist/precompile/index.d.ts +8 -0
  29. package/dist/precompile/index.d.ts.map +1 -0
  30. package/dist/precompile/index.js +7 -0
  31. package/dist/precompile/types.d.ts +76 -0
  32. package/dist/precompile/types.d.ts.map +1 -0
  33. package/dist/precompile/types.js +17 -0
  34. package/dist/router/index.d.ts +7 -0
  35. package/dist/router/index.d.ts.map +1 -0
  36. package/dist/router/index.js +6 -0
  37. package/dist/router/router.d.ts +58 -0
  38. package/dist/router/router.d.ts.map +1 -0
  39. package/dist/router/router.js +272 -0
  40. package/dist/router/types.d.ts +76 -0
  41. package/dist/router/types.d.ts.map +1 -0
  42. package/dist/router/types.js +1 -0
  43. package/package.json +55 -29
  44. package/src/client/clob.ts +256 -0
  45. package/src/client/index.ts +6 -0
  46. package/src/client/types.ts +148 -0
  47. package/src/hooks/index.ts +6 -0
  48. package/src/hooks/use-quote.ts +92 -0
  49. package/src/hooks/use-swap.ts +103 -0
  50. package/src/index.ts +76 -309
  51. package/src/precompile/abis.ts +291 -0
  52. package/src/precompile/addresses.ts +72 -0
  53. package/src/precompile/index.ts +7 -0
  54. package/src/precompile/types.ts +96 -0
  55. package/src/router/index.ts +6 -0
  56. package/src/router/router.ts +338 -0
  57. package/src/router/types.ts +87 -0
  58. package/dist/marketData.d.ts +0 -152
  59. package/dist/marketData.d.ts.map +0 -1
  60. package/dist/marketData.js +0 -253
  61. package/src/marketData.ts +0 -351
  62. package/tsconfig.json +0 -19
package/src/index.ts CHANGED
@@ -1,309 +1,76 @@
1
- import axios, { AxiosInstance } from 'axios';
2
- import WebSocket from 'ws';
3
- import {
4
- MarketDataClient,
5
- LiquidationMonitor,
6
- MarketDataSource,
7
- LiquidationInfo,
8
- SettlementBatch,
9
- MarginInfo,
10
- MarketDataProviders
11
- } from './marketData';
12
-
13
- // Types
14
- export enum OrderType {
15
- LIMIT = 0,
16
- MARKET = 1,
17
- STOP = 2,
18
- STOP_LIMIT = 3,
19
- ICEBERG = 4,
20
- PEG = 5
21
- }
22
-
23
- export enum OrderSide {
24
- BUY = 0,
25
- SELL = 1
26
- }
27
-
28
- export enum OrderStatus {
29
- OPEN = 'open',
30
- PARTIAL = 'partial',
31
- FILLED = 'filled',
32
- CANCELLED = 'cancelled',
33
- REJECTED = 'rejected'
34
- }
35
-
36
- export enum TimeInForce {
37
- GTC = 'GTC',
38
- IOC = 'IOC',
39
- FOK = 'FOK',
40
- DAY = 'DAY'
41
- }
42
-
43
- export interface Order {
44
- orderId?: number;
45
- symbol: string;
46
- type: OrderType;
47
- side: OrderSide;
48
- price: number;
49
- size: number;
50
- userID?: string;
51
- clientID?: string;
52
- timeInForce?: TimeInForce;
53
- postOnly?: boolean;
54
- reduceOnly?: boolean;
55
- status?: OrderStatus;
56
- filled?: number;
57
- remaining?: number;
58
- timestamp?: number;
59
- }
60
-
61
- export interface Trade {
62
- tradeId: number;
63
- symbol: string;
64
- price: number;
65
- size: number;
66
- side: OrderSide;
67
- buyOrderId: number;
68
- sellOrderId: number;
69
- buyerId: string;
70
- sellerId: string;
71
- timestamp: number;
72
- }
73
-
74
- export interface OrderBookLevel {
75
- price: number;
76
- size: number;
77
- count?: number;
78
- }
79
-
80
- export interface OrderBook {
81
- symbol: string;
82
- bids: OrderBookLevel[];
83
- asks: OrderBookLevel[];
84
- timestamp: number;
85
- }
86
-
87
- export interface NodeInfo {
88
- version: string;
89
- network: string;
90
- orderCount: number;
91
- tradeCount: number;
92
- timestamp: number;
93
- }
94
-
95
- export interface LXDexConfig {
96
- jsonRpcUrl?: string;
97
- wsUrl?: string;
98
- grpcUrl?: string;
99
- apiKey?: string;
100
- }
101
-
102
- // JSON-RPC Client
103
- class JSONRPCClient {
104
- private axios: AxiosInstance;
105
- private idCounter = 1;
106
-
107
- constructor(baseURL: string) {
108
- this.axios = axios.create({
109
- baseURL,
110
- headers: {
111
- 'Content-Type': 'application/json'
112
- }
113
- });
114
- }
115
-
116
- async call(method: string, params: any = {}): Promise<any> {
117
- const response = await this.axios.post('/rpc', {
118
- jsonrpc: '2.0',
119
- method,
120
- params,
121
- id: this.idCounter++
122
- });
123
-
124
- if (response.data.error) {
125
- throw new Error(response.data.error.message);
126
- }
127
-
128
- return response.data.result;
129
- }
130
- }
131
-
132
- // Main SDK Client
133
- export class LXDexClient {
134
- private jsonRpc: JSONRPCClient;
135
- private ws: WebSocket | null = null;
136
- private wsCallbacks: Map<string, Function[]> = new Map();
137
- private config: LXDexConfig;
138
- public marketData: MarketDataClient;
139
- public liquidationMonitor: LiquidationMonitor;
140
-
141
- constructor(config: LXDexConfig = {}) {
142
- this.config = {
143
- jsonRpcUrl: config.jsonRpcUrl || 'http://localhost:8080',
144
- wsUrl: config.wsUrl || 'ws://localhost:8081',
145
- ...config
146
- };
147
-
148
- this.jsonRpc = new JSONRPCClient(this.config.jsonRpcUrl!);
149
-
150
- // Initialize sub-clients
151
- this.marketData = new MarketDataClient(this.jsonRpc);
152
- this.liquidationMonitor = new LiquidationMonitor(null);
153
- }
154
-
155
- // Connection Management
156
- async connect(): Promise<void> {
157
- if (this.ws) return;
158
-
159
- return new Promise((resolve, reject) => {
160
- this.ws = new WebSocket(this.config.wsUrl!);
161
-
162
- this.ws.on('open', () => {
163
- console.log('WebSocket connected');
164
- // Set WebSocket for liquidation monitor
165
- this.liquidationMonitor.setWebSocket(this.ws!);
166
- resolve();
167
- });
168
-
169
- this.ws.on('message', (data: string) => {
170
- try {
171
- const msg = JSON.parse(data);
172
- this.handleWebSocketMessage(msg);
173
- } catch (err) {
174
- console.error('Failed to parse WebSocket message:', err);
175
- }
176
- });
177
-
178
- this.ws.on('error', (err) => {
179
- console.error('WebSocket error:', err);
180
- reject(err);
181
- });
182
-
183
- this.ws.on('close', () => {
184
- console.log('WebSocket disconnected');
185
- this.ws = null;
186
- });
187
- });
188
- }
189
-
190
- disconnect(): void {
191
- if (this.ws) {
192
- this.ws.close();
193
- this.ws = null;
194
- }
195
- }
196
-
197
- // Order Management
198
- async placeOrder(order: Partial<Order>): Promise<{ orderId: number; status: string }> {
199
- return this.jsonRpc.call('lx_placeOrder', order);
200
- }
201
-
202
- async cancelOrder(orderId: number): Promise<{ success: boolean; message: string }> {
203
- return this.jsonRpc.call('lx_cancelOrder', { orderId });
204
- }
205
-
206
- async getOrder(orderId: number): Promise<Order> {
207
- return this.jsonRpc.call('lx_getOrder', { orderId });
208
- }
209
-
210
- // Market Data
211
- async getOrderBook(symbol: string = 'BTC-USD', depth: number = 10): Promise<OrderBook> {
212
- return this.jsonRpc.call('lx_getOrderBook', { symbol, depth });
213
- }
214
-
215
- async getBestBid(symbol: string = 'BTC-USD'): Promise<number> {
216
- const result = await this.jsonRpc.call('lx_getBestBid', { symbol });
217
- return result.price;
218
- }
219
-
220
- async getBestAsk(symbol: string = 'BTC-USD'): Promise<number> {
221
- const result = await this.jsonRpc.call('lx_getBestAsk', { symbol });
222
- return result.price;
223
- }
224
-
225
- async getTrades(symbol: string = 'BTC-USD', limit: number = 100): Promise<Trade[]> {
226
- return this.jsonRpc.call('lx_getTrades', { symbol, limit });
227
- }
228
-
229
- // Node Information
230
- async getInfo(): Promise<NodeInfo> {
231
- return this.jsonRpc.call('lx_getInfo');
232
- }
233
-
234
- async ping(): Promise<string> {
235
- return this.jsonRpc.call('lx_ping');
236
- }
237
-
238
- // WebSocket Subscriptions
239
- subscribe(channel: string, callback: Function): void {
240
- if (!this.wsCallbacks.has(channel)) {
241
- this.wsCallbacks.set(channel, []);
242
- }
243
- this.wsCallbacks.get(channel)!.push(callback);
244
-
245
- // Send subscription message
246
- if (this.ws && this.ws.readyState === WebSocket.OPEN) {
247
- this.ws.send(JSON.stringify({
248
- type: 'subscribe',
249
- channel
250
- }));
251
- }
252
- }
253
-
254
- unsubscribe(channel: string, callback?: Function): void {
255
- if (callback) {
256
- const callbacks = this.wsCallbacks.get(channel);
257
- if (callbacks) {
258
- const index = callbacks.indexOf(callback);
259
- if (index > -1) {
260
- callbacks.splice(index, 1);
261
- }
262
- }
263
- } else {
264
- this.wsCallbacks.delete(channel);
265
- }
266
-
267
- // Send unsubscribe message
268
- if (this.ws && this.ws.readyState === WebSocket.OPEN) {
269
- this.ws.send(JSON.stringify({
270
- type: 'unsubscribe',
271
- channel
272
- }));
273
- }
274
- }
275
-
276
- subscribeOrderBook(symbol: string, callback: (book: OrderBook) => void): void {
277
- this.subscribe(`orderbook:${symbol}`, callback);
278
- }
279
-
280
- subscribeTrades(symbol: string, callback: (trade: Trade) => void): void {
281
- this.subscribe(`trades:${symbol}`, callback);
282
- }
283
-
284
- // Private methods
285
- private handleWebSocketMessage(msg: any): void {
286
- const { channel, data } = msg;
287
- const callbacks = this.wsCallbacks.get(channel);
288
- if (callbacks) {
289
- callbacks.forEach(cb => cb(data));
290
- }
291
- }
292
-
293
- // Utility methods
294
- static formatPrice(price: number, decimals: number = 2): string {
295
- return price.toFixed(decimals);
296
- }
297
-
298
- static formatSize(size: number, decimals: number = 8): string {
299
- return size.toFixed(decimals);
300
- }
301
-
302
- static calculateTotal(price: number, size: number): number {
303
- return price * size;
304
- }
305
- }
306
-
307
- // Export everything
308
- export default LXDexClient;
309
- export * from './marketData';
1
+ /**
2
+ * @luxfi/dex
3
+ *
4
+ * DEX Integration Package
5
+ *
6
+ * Provides routing between:
7
+ * - CLOB (Central Limit Order Book) via ~/work/lux/dex
8
+ * - AMM Precompiles (0x0400-0x0403) for native swaps
9
+ *
10
+ * Architecture:
11
+ * ```
12
+ * ┌────────────────────────────────────────┐
13
+ * │ Omnichain Router │
14
+ * │ Best execution between CLOB & AMM │
15
+ * └─────────────────┬──────────────────────┘
16
+ * │
17
+ * ┌─────────────┴─────────────┐
18
+ * │ │
19
+ * ▼ ▼
20
+ * ┌─────────┐ ┌───────────────┐
21
+ * │ CLOB │ │ AMM Precompile│
22
+ * │ Client │ │ (0x0400) │
23
+ * │ │ │ │
24
+ * │ • Limit │ │ • Swap │
25
+ * │ • HFT │ │ • Liquidity │
26
+ * │ • Perps │ │ • Flash │
27
+ * └─────────┘ └───────────────┘
28
+ * ```
29
+ */
30
+
31
+ // Precompile types and ABIs (AMM)
32
+ export {
33
+ // Types
34
+ type Currency,
35
+ type PoolKey,
36
+ type BalanceDelta,
37
+ type SwapParams,
38
+ type ModifyLiquidityParams,
39
+ type PoolState,
40
+ type Position as AMMPosition,
41
+ NATIVE_LUX,
42
+ sortCurrencies,
43
+ createPoolKey,
44
+ // ABIs
45
+ POOL_MANAGER_ABI,
46
+ SWAP_ROUTER_ABI,
47
+ HOOKS_REGISTRY_ABI,
48
+ FLASH_LOAN_ABI,
49
+ // Addresses
50
+ DEX_PRECOMPILES,
51
+ type DexPrecompile,
52
+ } from './precompile'
53
+
54
+ // CLOB client (exports Position as CLOBPosition to avoid conflict)
55
+ export {
56
+ type OrderSide,
57
+ type OrderType,
58
+ type OrderStatus,
59
+ type TimeInForce,
60
+ type OrderRequest,
61
+ type Order,
62
+ type OrderBookEntry,
63
+ type OrderBook,
64
+ type Trade,
65
+ type Position as CLOBPosition,
66
+ type Balance,
67
+ type ICLOBClient,
68
+ CLOBClient,
69
+ createCLOBClient,
70
+ } from './client'
71
+
72
+ // Omnichain router
73
+ export * from './router'
74
+
75
+ // React hooks
76
+ export * from './hooks'
@@ -0,0 +1,291 @@
1
+ /**
2
+ * DEX Precompile ABIs
3
+ * Native Go implementation at 0x0400-0x0403
4
+ */
5
+
6
+ /**
7
+ * PoolManager ABI (0x0400)
8
+ * Singleton contract managing all pools
9
+ */
10
+ export const POOL_MANAGER_ABI = [
11
+ // Initialize a new pool
12
+ {
13
+ type: 'function',
14
+ name: 'initialize',
15
+ inputs: [
16
+ {
17
+ name: 'key',
18
+ type: 'tuple',
19
+ components: [
20
+ { name: 'currency0', type: 'address' },
21
+ { name: 'currency1', type: 'address' },
22
+ { name: 'fee', type: 'uint24' },
23
+ { name: 'tickSpacing', type: 'int24' },
24
+ { name: 'hooks', type: 'address' },
25
+ ],
26
+ },
27
+ { name: 'sqrtPriceX96', type: 'uint160' },
28
+ ],
29
+ outputs: [{ name: 'tick', type: 'int24' }],
30
+ stateMutability: 'nonpayable',
31
+ },
32
+ // Execute a swap
33
+ {
34
+ type: 'function',
35
+ name: 'swap',
36
+ inputs: [
37
+ {
38
+ name: 'key',
39
+ type: 'tuple',
40
+ components: [
41
+ { name: 'currency0', type: 'address' },
42
+ { name: 'currency1', type: 'address' },
43
+ { name: 'fee', type: 'uint24' },
44
+ { name: 'tickSpacing', type: 'int24' },
45
+ { name: 'hooks', type: 'address' },
46
+ ],
47
+ },
48
+ {
49
+ name: 'params',
50
+ type: 'tuple',
51
+ components: [
52
+ { name: 'zeroForOne', type: 'bool' },
53
+ { name: 'amountSpecified', type: 'int256' },
54
+ { name: 'sqrtPriceLimitX96', type: 'uint160' },
55
+ ],
56
+ },
57
+ { name: 'hookData', type: 'bytes' },
58
+ ],
59
+ outputs: [{ name: 'delta', type: 'int256' }],
60
+ stateMutability: 'nonpayable',
61
+ },
62
+ // Modify liquidity
63
+ {
64
+ type: 'function',
65
+ name: 'modifyLiquidity',
66
+ inputs: [
67
+ {
68
+ name: 'key',
69
+ type: 'tuple',
70
+ components: [
71
+ { name: 'currency0', type: 'address' },
72
+ { name: 'currency1', type: 'address' },
73
+ { name: 'fee', type: 'uint24' },
74
+ { name: 'tickSpacing', type: 'int24' },
75
+ { name: 'hooks', type: 'address' },
76
+ ],
77
+ },
78
+ {
79
+ name: 'params',
80
+ type: 'tuple',
81
+ components: [
82
+ { name: 'tickLower', type: 'int24' },
83
+ { name: 'tickUpper', type: 'int24' },
84
+ { name: 'liquidityDelta', type: 'int256' },
85
+ { name: 'salt', type: 'bytes32' },
86
+ ],
87
+ },
88
+ { name: 'hookData', type: 'bytes' },
89
+ ],
90
+ outputs: [
91
+ { name: 'callerDelta', type: 'int256' },
92
+ { name: 'feesAccrued', type: 'int256' },
93
+ ],
94
+ stateMutability: 'nonpayable',
95
+ },
96
+ // Settle outstanding balance
97
+ {
98
+ type: 'function',
99
+ name: 'settle',
100
+ inputs: [{ name: 'currency', type: 'address' }],
101
+ outputs: [{ name: 'amount', type: 'uint256' }],
102
+ stateMutability: 'payable',
103
+ },
104
+ // Take tokens from pool
105
+ {
106
+ type: 'function',
107
+ name: 'take',
108
+ inputs: [
109
+ { name: 'currency', type: 'address' },
110
+ { name: 'to', type: 'address' },
111
+ { name: 'amount', type: 'uint256' },
112
+ ],
113
+ outputs: [],
114
+ stateMutability: 'nonpayable',
115
+ },
116
+ // Get pool state
117
+ {
118
+ type: 'function',
119
+ name: 'getSlot0',
120
+ inputs: [
121
+ {
122
+ name: 'key',
123
+ type: 'tuple',
124
+ components: [
125
+ { name: 'currency0', type: 'address' },
126
+ { name: 'currency1', type: 'address' },
127
+ { name: 'fee', type: 'uint24' },
128
+ { name: 'tickSpacing', type: 'int24' },
129
+ { name: 'hooks', type: 'address' },
130
+ ],
131
+ },
132
+ ],
133
+ outputs: [
134
+ { name: 'sqrtPriceX96', type: 'uint160' },
135
+ { name: 'tick', type: 'int24' },
136
+ { name: 'protocolFee', type: 'uint24' },
137
+ { name: 'lpFee', type: 'uint24' },
138
+ ],
139
+ stateMutability: 'view',
140
+ },
141
+ // Get liquidity
142
+ {
143
+ type: 'function',
144
+ name: 'getLiquidity',
145
+ inputs: [
146
+ {
147
+ name: 'key',
148
+ type: 'tuple',
149
+ components: [
150
+ { name: 'currency0', type: 'address' },
151
+ { name: 'currency1', type: 'address' },
152
+ { name: 'fee', type: 'uint24' },
153
+ { name: 'tickSpacing', type: 'int24' },
154
+ { name: 'hooks', type: 'address' },
155
+ ],
156
+ },
157
+ ],
158
+ outputs: [{ name: 'liquidity', type: 'uint128' }],
159
+ stateMutability: 'view',
160
+ },
161
+ ] as const
162
+
163
+ /**
164
+ * SwapRouter ABI (0x0401)
165
+ * Optimized swap routing
166
+ */
167
+ export const SWAP_ROUTER_ABI = [
168
+ // Single swap (exact input)
169
+ {
170
+ type: 'function',
171
+ name: 'exactInputSingle',
172
+ inputs: [
173
+ {
174
+ name: 'params',
175
+ type: 'tuple',
176
+ components: [
177
+ {
178
+ name: 'poolKey',
179
+ type: 'tuple',
180
+ components: [
181
+ { name: 'currency0', type: 'address' },
182
+ { name: 'currency1', type: 'address' },
183
+ { name: 'fee', type: 'uint24' },
184
+ { name: 'tickSpacing', type: 'int24' },
185
+ { name: 'hooks', type: 'address' },
186
+ ],
187
+ },
188
+ { name: 'zeroForOne', type: 'bool' },
189
+ { name: 'amountIn', type: 'uint256' },
190
+ { name: 'amountOutMinimum', type: 'uint256' },
191
+ { name: 'sqrtPriceLimitX96', type: 'uint160' },
192
+ { name: 'hookData', type: 'bytes' },
193
+ ],
194
+ },
195
+ ],
196
+ outputs: [{ name: 'amountOut', type: 'uint256' }],
197
+ stateMutability: 'payable',
198
+ },
199
+ // Single swap (exact output)
200
+ {
201
+ type: 'function',
202
+ name: 'exactOutputSingle',
203
+ inputs: [
204
+ {
205
+ name: 'params',
206
+ type: 'tuple',
207
+ components: [
208
+ {
209
+ name: 'poolKey',
210
+ type: 'tuple',
211
+ components: [
212
+ { name: 'currency0', type: 'address' },
213
+ { name: 'currency1', type: 'address' },
214
+ { name: 'fee', type: 'uint24' },
215
+ { name: 'tickSpacing', type: 'int24' },
216
+ { name: 'hooks', type: 'address' },
217
+ ],
218
+ },
219
+ { name: 'zeroForOne', type: 'bool' },
220
+ { name: 'amountOut', type: 'uint256' },
221
+ { name: 'amountInMaximum', type: 'uint256' },
222
+ { name: 'sqrtPriceLimitX96', type: 'uint160' },
223
+ { name: 'hookData', type: 'bytes' },
224
+ ],
225
+ },
226
+ ],
227
+ outputs: [{ name: 'amountIn', type: 'uint256' }],
228
+ stateMutability: 'payable',
229
+ },
230
+ // Multi-hop swap
231
+ {
232
+ type: 'function',
233
+ name: 'exactInput',
234
+ inputs: [
235
+ {
236
+ name: 'params',
237
+ type: 'tuple',
238
+ components: [
239
+ { name: 'path', type: 'bytes' },
240
+ { name: 'amountIn', type: 'uint256' },
241
+ { name: 'amountOutMinimum', type: 'uint256' },
242
+ ],
243
+ },
244
+ ],
245
+ outputs: [{ name: 'amountOut', type: 'uint256' }],
246
+ stateMutability: 'payable',
247
+ },
248
+ ] as const
249
+
250
+ /**
251
+ * HooksRegistry ABI (0x0402)
252
+ * Registry for hook contracts
253
+ */
254
+ export const HOOKS_REGISTRY_ABI = [
255
+ {
256
+ type: 'function',
257
+ name: 'registerHook',
258
+ inputs: [
259
+ { name: 'hook', type: 'address' },
260
+ { name: 'permissions', type: 'uint256' },
261
+ ],
262
+ outputs: [],
263
+ stateMutability: 'nonpayable',
264
+ },
265
+ {
266
+ type: 'function',
267
+ name: 'getHookPermissions',
268
+ inputs: [{ name: 'hook', type: 'address' }],
269
+ outputs: [{ name: 'permissions', type: 'uint256' }],
270
+ stateMutability: 'view',
271
+ },
272
+ ] as const
273
+
274
+ /**
275
+ * FlashLoan ABI (0x0403)
276
+ * Flash loan facility
277
+ */
278
+ export const FLASH_LOAN_ABI = [
279
+ {
280
+ type: 'function',
281
+ name: 'flash',
282
+ inputs: [
283
+ { name: 'recipient', type: 'address' },
284
+ { name: 'currency', type: 'address' },
285
+ { name: 'amount', type: 'uint256' },
286
+ { name: 'data', type: 'bytes' },
287
+ ],
288
+ outputs: [],
289
+ stateMutability: 'nonpayable',
290
+ },
291
+ ] as const