@luxfi/exchange 0.1.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 (154) hide show
  1. package/dist/bridge/__tests__/use-private-teleport.test.d.ts +2 -0
  2. package/dist/bridge/__tests__/use-private-teleport.test.d.ts.map +1 -0
  3. package/dist/bridge/__tests__/use-private-teleport.test.js +272 -0
  4. package/dist/bridge/cross-chain-store.d.ts +57 -0
  5. package/dist/bridge/cross-chain-store.d.ts.map +1 -0
  6. package/dist/bridge/cross-chain-store.js +158 -0
  7. package/dist/bridge/index.d.ts +78 -0
  8. package/dist/bridge/index.d.ts.map +1 -0
  9. package/dist/bridge/index.js +79 -0
  10. package/dist/bridge/private-teleport-types.d.ts +634 -0
  11. package/dist/bridge/private-teleport-types.d.ts.map +1 -0
  12. package/dist/bridge/private-teleport-types.js +308 -0
  13. package/dist/bridge/types.d.ts +84 -0
  14. package/dist/bridge/types.d.ts.map +1 -0
  15. package/dist/bridge/types.js +37 -0
  16. package/dist/bridge/use-cross-chain-mint.d.ts +34 -0
  17. package/dist/bridge/use-cross-chain-mint.d.ts.map +1 -0
  18. package/dist/bridge/use-cross-chain-mint.js +228 -0
  19. package/dist/bridge/use-private-teleport.d.ts +69 -0
  20. package/dist/bridge/use-private-teleport.d.ts.map +1 -0
  21. package/dist/bridge/use-private-teleport.js +666 -0
  22. package/dist/chains/index.d.ts +6 -0
  23. package/dist/chains/index.d.ts.map +1 -0
  24. package/dist/chains/index.js +6 -0
  25. package/dist/chains/lux.d.ts +508 -0
  26. package/dist/chains/lux.d.ts.map +1 -0
  27. package/dist/chains/lux.js +131 -0
  28. package/dist/contracts/abis/dex-swap-router.d.ts +137 -0
  29. package/dist/contracts/abis/dex-swap-router.d.ts.map +1 -0
  30. package/dist/contracts/abis/dex-swap-router.js +95 -0
  31. package/dist/contracts/abis/erc20.d.ts +136 -0
  32. package/dist/contracts/abis/erc20.d.ts.map +1 -0
  33. package/dist/contracts/abis/erc20.js +96 -0
  34. package/dist/contracts/abis/index.d.ts +15 -0
  35. package/dist/contracts/abis/index.d.ts.map +1 -0
  36. package/dist/contracts/abis/index.js +15 -0
  37. package/dist/contracts/abis/nft-position-manager.d.ts +235 -0
  38. package/dist/contracts/abis/nft-position-manager.d.ts.map +1 -0
  39. package/dist/contracts/abis/nft-position-manager.js +146 -0
  40. package/dist/contracts/abis/pool-manager.d.ts +315 -0
  41. package/dist/contracts/abis/pool-manager.d.ts.map +1 -0
  42. package/dist/contracts/abis/pool-manager.js +191 -0
  43. package/dist/contracts/abis/quoter-v2.d.ts +103 -0
  44. package/dist/contracts/abis/quoter-v2.d.ts.map +1 -0
  45. package/dist/contracts/abis/quoter-v2.js +68 -0
  46. package/dist/contracts/abis/swap-router.d.ts +119 -0
  47. package/dist/contracts/abis/swap-router.d.ts.map +1 -0
  48. package/dist/contracts/abis/swap-router.js +75 -0
  49. package/dist/contracts/abis/uniswap-v2-factory.d.ts +75 -0
  50. package/dist/contracts/abis/uniswap-v2-factory.d.ts.map +1 -0
  51. package/dist/contracts/abis/uniswap-v2-factory.js +49 -0
  52. package/dist/contracts/abis/uniswap-v2-pair.d.ts +119 -0
  53. package/dist/contracts/abis/uniswap-v2-pair.d.ts.map +1 -0
  54. package/dist/contracts/abis/uniswap-v2-pair.js +85 -0
  55. package/dist/contracts/abis/uniswap-v2-router.d.ts +249 -0
  56. package/dist/contracts/abis/uniswap-v2-router.d.ts.map +1 -0
  57. package/dist/contracts/abis/uniswap-v2-router.js +146 -0
  58. package/dist/contracts/abis/uniswap-v3-factory.d.ts +77 -0
  59. package/dist/contracts/abis/uniswap-v3-factory.d.ts.map +1 -0
  60. package/dist/contracts/abis/uniswap-v3-factory.js +45 -0
  61. package/dist/contracts/abis/uniswap-v3-pool.d.ts +128 -0
  62. package/dist/contracts/abis/uniswap-v3-pool.d.ts.map +1 -0
  63. package/dist/contracts/abis/uniswap-v3-pool.js +81 -0
  64. package/dist/contracts/addresses.d.ts +141 -0
  65. package/dist/contracts/addresses.d.ts.map +1 -0
  66. package/dist/contracts/addresses.js +108 -0
  67. package/dist/contracts/index.d.ts +6 -0
  68. package/dist/contracts/index.d.ts.map +1 -0
  69. package/dist/contracts/index.js +5 -0
  70. package/dist/dex/balance-delta.d.ts +27 -0
  71. package/dist/dex/balance-delta.d.ts.map +1 -0
  72. package/dist/dex/balance-delta.js +45 -0
  73. package/dist/dex/index.d.ts +7 -0
  74. package/dist/dex/index.d.ts.map +1 -0
  75. package/dist/dex/index.js +6 -0
  76. package/dist/dex/pool-key.d.ts +19 -0
  77. package/dist/dex/pool-key.d.ts.map +1 -0
  78. package/dist/dex/pool-key.js +44 -0
  79. package/dist/dex/types.d.ts +71 -0
  80. package/dist/dex/types.d.ts.map +1 -0
  81. package/dist/dex/types.js +28 -0
  82. package/dist/hooks/index.d.ts +10 -0
  83. package/dist/hooks/index.d.ts.map +1 -0
  84. package/dist/hooks/index.js +9 -0
  85. package/dist/hooks/use-pools.d.ts +24 -0
  86. package/dist/hooks/use-pools.d.ts.map +1 -0
  87. package/dist/hooks/use-pools.js +85 -0
  88. package/dist/hooks/use-positions.d.ts +17 -0
  89. package/dist/hooks/use-positions.d.ts.map +1 -0
  90. package/dist/hooks/use-positions.js +65 -0
  91. package/dist/hooks/use-swap-quote.d.ts +19 -0
  92. package/dist/hooks/use-swap-quote.d.ts.map +1 -0
  93. package/dist/hooks/use-swap-quote.js +54 -0
  94. package/dist/hooks/use-swap.d.ts +22 -0
  95. package/dist/hooks/use-swap.d.ts.map +1 -0
  96. package/dist/hooks/use-swap.js +46 -0
  97. package/dist/hooks/use-token-allowance.d.ts +27 -0
  98. package/dist/hooks/use-token-allowance.d.ts.map +1 -0
  99. package/dist/hooks/use-token-allowance.js +59 -0
  100. package/dist/hooks/use-token-balance.d.ts +17 -0
  101. package/dist/hooks/use-token-balance.d.ts.map +1 -0
  102. package/dist/hooks/use-token-balance.js +58 -0
  103. package/dist/index.d.ts +17 -0
  104. package/dist/index.d.ts.map +1 -0
  105. package/dist/index.js +24 -0
  106. package/dist/stores/index.d.ts +7 -0
  107. package/dist/stores/index.d.ts.map +1 -0
  108. package/dist/stores/index.js +6 -0
  109. package/dist/stores/settings-store.d.ts +25 -0
  110. package/dist/stores/settings-store.d.ts.map +1 -0
  111. package/dist/stores/settings-store.js +16 -0
  112. package/dist/stores/swap-store.d.ts +38 -0
  113. package/dist/stores/swap-store.d.ts.map +1 -0
  114. package/dist/stores/swap-store.js +58 -0
  115. package/dist/stores/token-store.d.ts +21 -0
  116. package/dist/stores/token-store.d.ts.map +1 -0
  117. package/dist/stores/token-store.js +32 -0
  118. package/dist/tokens/index.d.ts +65 -0
  119. package/dist/tokens/index.d.ts.map +1 -0
  120. package/dist/tokens/index.js +185 -0
  121. package/package.json +78 -0
  122. package/src/chains/index.ts +21 -0
  123. package/src/chains/lux.ts +141 -0
  124. package/src/contracts/abis/dex-swap-router.ts +98 -0
  125. package/src/contracts/abis/erc20.ts +96 -0
  126. package/src/contracts/abis/index.ts +17 -0
  127. package/src/contracts/abis/nft-position-manager.ts +146 -0
  128. package/src/contracts/abis/pool-manager.ts +198 -0
  129. package/src/contracts/abis/quoter-v2.ts +68 -0
  130. package/src/contracts/abis/swap-router.ts +75 -0
  131. package/src/contracts/abis/uniswap-v2-factory.ts +49 -0
  132. package/src/contracts/abis/uniswap-v2-pair.ts +85 -0
  133. package/src/contracts/abis/uniswap-v2-router.ts +146 -0
  134. package/src/contracts/abis/uniswap-v3-factory.ts +45 -0
  135. package/src/contracts/abis/uniswap-v3-pool.ts +81 -0
  136. package/src/contracts/addresses.ts +128 -0
  137. package/src/contracts/index.ts +14 -0
  138. package/src/dex/balance-delta.ts +52 -0
  139. package/src/dex/index.ts +7 -0
  140. package/src/dex/pool-key.ts +62 -0
  141. package/src/dex/types.ts +87 -0
  142. package/src/hooks/index.ts +10 -0
  143. package/src/hooks/use-pools.ts +116 -0
  144. package/src/hooks/use-positions.ts +90 -0
  145. package/src/hooks/use-swap-quote.ts +81 -0
  146. package/src/hooks/use-swap.ts +64 -0
  147. package/src/hooks/use-token-allowance.ts +74 -0
  148. package/src/hooks/use-token-balance.ts +71 -0
  149. package/src/index.ts +31 -0
  150. package/src/stores/index.ts +7 -0
  151. package/src/stores/settings-store.ts +54 -0
  152. package/src/stores/swap-store.ts +112 -0
  153. package/src/stores/token-store.ts +62 -0
  154. package/src/tokens/index.ts +220 -0
@@ -0,0 +1,81 @@
1
+ /**
2
+ * UniswapV3Pool ABI (essential functions)
3
+ */
4
+ export const UNISWAP_V3_POOL_ABI = [
5
+ {
6
+ type: 'function',
7
+ name: 'token0',
8
+ inputs: [],
9
+ outputs: [{ type: 'address' }],
10
+ stateMutability: 'view',
11
+ },
12
+ {
13
+ type: 'function',
14
+ name: 'token1',
15
+ inputs: [],
16
+ outputs: [{ type: 'address' }],
17
+ stateMutability: 'view',
18
+ },
19
+ {
20
+ type: 'function',
21
+ name: 'fee',
22
+ inputs: [],
23
+ outputs: [{ type: 'uint24' }],
24
+ stateMutability: 'view',
25
+ },
26
+ {
27
+ type: 'function',
28
+ name: 'tickSpacing',
29
+ inputs: [],
30
+ outputs: [{ type: 'int24' }],
31
+ stateMutability: 'view',
32
+ },
33
+ {
34
+ type: 'function',
35
+ name: 'liquidity',
36
+ inputs: [],
37
+ outputs: [{ type: 'uint128' }],
38
+ stateMutability: 'view',
39
+ },
40
+ {
41
+ type: 'function',
42
+ name: 'slot0',
43
+ inputs: [],
44
+ outputs: [
45
+ { name: 'sqrtPriceX96', type: 'uint160' },
46
+ { name: 'tick', type: 'int24' },
47
+ { name: 'observationIndex', type: 'uint16' },
48
+ { name: 'observationCardinality', type: 'uint16' },
49
+ { name: 'observationCardinalityNext', type: 'uint16' },
50
+ { name: 'feeProtocol', type: 'uint8' },
51
+ { name: 'unlocked', type: 'bool' },
52
+ ],
53
+ stateMutability: 'view',
54
+ },
55
+ {
56
+ type: 'function',
57
+ name: 'positions',
58
+ inputs: [{ name: 'key', type: 'bytes32' }],
59
+ outputs: [
60
+ { name: 'liquidity', type: 'uint128' },
61
+ { name: 'feeGrowthInside0LastX128', type: 'uint256' },
62
+ { name: 'feeGrowthInside1LastX128', type: 'uint256' },
63
+ { name: 'tokensOwed0', type: 'uint128' },
64
+ { name: 'tokensOwed1', type: 'uint128' },
65
+ ],
66
+ stateMutability: 'view',
67
+ },
68
+ {
69
+ type: 'event',
70
+ name: 'Swap',
71
+ inputs: [
72
+ { name: 'sender', type: 'address', indexed: true },
73
+ { name: 'recipient', type: 'address', indexed: true },
74
+ { name: 'amount0', type: 'int256', indexed: false },
75
+ { name: 'amount1', type: 'int256', indexed: false },
76
+ { name: 'sqrtPriceX96', type: 'uint160', indexed: false },
77
+ { name: 'liquidity', type: 'uint128', indexed: false },
78
+ { name: 'tick', type: 'int24', indexed: false },
79
+ ],
80
+ },
81
+ ] as const
@@ -0,0 +1,128 @@
1
+ /**
2
+ * Contract Addresses for Lux Exchange
3
+ */
4
+ import type { Address } from 'viem'
5
+
6
+ /**
7
+ * Contract addresses for Lux Mainnet (96369)
8
+ */
9
+ export const LUX_MAINNET_CONTRACTS = {
10
+ // Core
11
+ WLUX: '0x55750d6CA62a041c06a8E28626b10Be6c688f471' as Address,
12
+ MULTICALL: '0xd25F88CBdAe3c2CCA3Bb75FC4E723b44C0Ea362F' as Address,
13
+
14
+ // Bridge tokens
15
+ LETH: '0xAA3AE95816a4A6FbC6b8Ed5a6C06f22A96A80C8C' as Address,
16
+ LBTC: '0x526903E35E7106D62ED3B5d77E14e51d024Aa1D3' as Address,
17
+ LUSD: '0x4B1BfA76eD63F1A0aD2E4f40b3F46C45E8F7A4E2' as Address,
18
+
19
+ // AMM V2 (QuantumSwap)
20
+ V2_FACTORY: '0xd9a95609DbB228A13568Bd9f9A285105E7596970' as Address,
21
+ V2_ROUTER: '0x1F6cbC7d3bc7D803ee76D80F0eEE25767431e674' as Address,
22
+
23
+ // AMM V3 (Concentrated Liquidity)
24
+ V3_FACTORY: '0xb732BD88F25EdD9C3456638671fB37685D4B4e3f' as Address,
25
+ V3_SWAP_ROUTER: '0xE8fb25086C8652c92f5AF90D730Bac7C63Fc9A58' as Address,
26
+ V3_SWAP_ROUTER_02: '0x939bC0Bca6F9B9c52E6e3AD8A3C590b5d9B9D10E' as Address,
27
+ V3_QUOTER: '0x12e2B76FaF4dDA5a173a4532916bb6Bfa3645275' as Address,
28
+ V3_QUOTER_V2: '0x15C729fdd833Ba675edd466Dfc63E1B737925A4c' as Address,
29
+ V3_TICK_LENS: '0x57A22965AdA0e52D785A9Aa155beF423D573b879' as Address,
30
+ V3_NFT_POSITION_MANAGER: '0x7a4C48B9dae0b7c396569b34042fcA604150Ee28' as Address,
31
+ V3_NFT_DESCRIPTOR: '0x53B1aAA5b6DDFD4eD00D0A7b5Ef333dc74B605b5' as Address,
32
+ } as const
33
+
34
+ /**
35
+ * Contract addresses for Lux Testnet (96368)
36
+ */
37
+ export const LUX_TESTNET_CONTRACTS = {
38
+ // Core
39
+ WLUX: '0x732740c5c895C9FCF619930ed4293fc858eb44c7' as Address,
40
+ WETH: '0xd9956542B51032d940ef076d70B69410667277A3' as Address,
41
+ MULTICALL: '0xd25F88CBdAe3c2CCA3Bb75FC4E723b44C0Ea362F' as Address,
42
+
43
+ // AMM V2
44
+ V2_FACTORY: '0x81C3669B139D92909AA67DbF74a241b10540d919' as Address,
45
+ V2_ROUTER: '0xDB6c703c80BFaE5F9a56482d3c8535f27E1136EB' as Address,
46
+
47
+ // AMM V3
48
+ V3_FACTORY: '0x80bBc7C4C7a59C899D1B37BC14539A22D5830a84' as Address,
49
+ V3_SWAP_ROUTER: '0xE8fb25086C8652c92f5AF90D730Bac7C63Fc9A58' as Address,
50
+ V3_SWAP_ROUTER_02: '0x939bC0Bca6F9B9c52E6e3AD8A3C590b5d9B9D10E' as Address,
51
+ V3_QUOTER: '0x12e2B76FaF4dDA5a173a4532916bb6Bfa3645275' as Address,
52
+ V3_QUOTER_V2: '0x15C729fdd833Ba675edd466Dfc63E1B737925A4c' as Address,
53
+ V3_TICK_LENS: '0x57A22965AdA0e52D785A9Aa155beF423D573b879' as Address,
54
+ V3_NFT_POSITION_MANAGER: '0x7a4C48B9dae0b7c396569b34042fcA604150Ee28' as Address,
55
+ V3_NFT_DESCRIPTOR: '0x53B1aAA5b6DDFD4eD00D0A7b5Ef333dc74B605b5' as Address,
56
+ } as const
57
+
58
+ /**
59
+ * DEX Precompile addresses (native AMM)
60
+ * These provide sub-microsecond execution
61
+ *
62
+ * Lux Precompile Address Standard:
63
+ * - Prefix format: 0xNNNN000000000000000000000000000000000000
64
+ * - Range 0x0400-0x04FF is reserved for DEX precompiles
65
+ *
66
+ * @see ~/work/lux/precompile/dex/module.go for implementation
67
+ */
68
+ export const DEX_PRECOMPILES = {
69
+ POOL_MANAGER: '0x0400000000000000000000000000000000000000' as Address,
70
+ SWAP_ROUTER: '0x0401000000000000000000000000000000000000' as Address,
71
+ HOOKS_REGISTRY: '0x0402000000000000000000000000000000000000' as Address,
72
+ FLASH_LOAN: '0x0403000000000000000000000000000000000000' as Address,
73
+ LENDING: '0x0410000000000000000000000000000000000000' as Address,
74
+ LIQUID: '0x0430000000000000000000000000000000000000' as Address,
75
+ TELEPORT: '0x0440000000000000000000000000000000000000' as Address,
76
+ } as const
77
+
78
+ /**
79
+ * Contract addresses for Lux Dev (1337)
80
+ */
81
+ export const LUX_DEV_CONTRACTS = {
82
+ // Core
83
+ WLUX: '0x610178dA211FEF7D417bC0e6FeD39F05609AD788' as Address,
84
+ MULTICALL: '0xd25F88CBdAe3c2CCA3Bb75FC4E723b44C0Ea362F' as Address,
85
+
86
+ // Bridged tokens (local dev)
87
+ ETH: '0x5FbDB2315678afecb367f032d93F642f64180aa3' as Address,
88
+ BTC: '0xe7f1725E7734CE288F8367e1Bb143E90bb3F0512' as Address,
89
+ USDC: '0x9fE46736679d2D9a65F0992F2272dE9f3c7fa6e0' as Address,
90
+ USDT: '0xCf7Ed3AccA5a467e9e704C703E8D87F634fB0Fc9' as Address,
91
+ DAI: '0xDc64a140Aa3E981100a9becA4E685f962f0cF6C9' as Address,
92
+ AI: '0x0B306BF915C4d645ff596e518fAf3F9669b97016' as Address,
93
+
94
+ // AMM V2
95
+ V2_FACTORY: '0x959922bE3CAee4b8Cd9a407cc3ac1C251C2007B1' as Address,
96
+ V2_ROUTER: '0x9A9f2CCfdE556A7E9Ff0848998Aa4a0CFD8863AE' as Address,
97
+
98
+ // AMM V3 (uses testnet addresses for dev)
99
+ V3_FACTORY: '0x80bBc7C4C7a59C899D1B37BC14539A22D5830a84' as Address,
100
+ V3_SWAP_ROUTER: '0xE8fb25086C8652c92f5AF90D730Bac7C63Fc9A58' as Address,
101
+ V3_SWAP_ROUTER_02: '0x939bC0Bca6F9B9c52E6e3AD8A3C590b5d9B9D10E' as Address,
102
+ V3_QUOTER: '0x12e2B76FaF4dDA5a173a4532916bb6Bfa3645275' as Address,
103
+ V3_QUOTER_V2: '0x15C729fdd833Ba675edd466Dfc63E1B737925A4c' as Address,
104
+ V3_TICK_LENS: '0x57A22965AdA0e52D785A9Aa155beF423D573b879' as Address,
105
+ V3_NFT_POSITION_MANAGER: '0x7a4C48B9dae0b7c396569b34042fcA604150Ee28' as Address,
106
+ V3_NFT_DESCRIPTOR: '0x53B1aAA5b6DDFD4eD00D0A7b5Ef333dc74B605b5' as Address,
107
+
108
+ // Staking
109
+ STAKED_LUX: '0xA51c1fc2f0D1a1b8494Ed1FE312d7C3a78Ed91C0' as Address,
110
+ } as const
111
+
112
+ /**
113
+ * Get contracts for a specific chain
114
+ */
115
+ export function getContracts(chainId: number) {
116
+ switch (chainId) {
117
+ case 96369:
118
+ return LUX_MAINNET_CONTRACTS
119
+ case 96368:
120
+ return LUX_TESTNET_CONTRACTS
121
+ case 1337:
122
+ return LUX_DEV_CONTRACTS
123
+ default:
124
+ return LUX_TESTNET_CONTRACTS
125
+ }
126
+ }
127
+
128
+ export type ContractAddresses = typeof LUX_MAINNET_CONTRACTS
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Contract exports
3
+ */
4
+
5
+ export {
6
+ LUX_MAINNET_CONTRACTS,
7
+ LUX_TESTNET_CONTRACTS,
8
+ LUX_DEV_CONTRACTS,
9
+ DEX_PRECOMPILES,
10
+ getContracts,
11
+ type ContractAddresses,
12
+ } from './addresses'
13
+
14
+ export * from './abis'
@@ -0,0 +1,52 @@
1
+ import type { BalanceDelta } from './types'
2
+
3
+ /**
4
+ * Create balance delta from packed int256 (Solidity representation)
5
+ * Upper 128 bits = amount0, Lower 128 bits = amount1
6
+ */
7
+ export function unpackBalanceDelta(packed: bigint): BalanceDelta {
8
+ const amount0 = packed >> 128n
9
+ const amount1 = BigInt.asIntN(128, packed)
10
+ return { amount0, amount1 }
11
+ }
12
+
13
+ /**
14
+ * Pack balance delta into int256
15
+ */
16
+ export function packBalanceDelta(delta: BalanceDelta): bigint {
17
+ return (delta.amount0 << 128n) | (delta.amount1 & ((1n << 128n) - 1n))
18
+ }
19
+
20
+ /**
21
+ * Add two balance deltas
22
+ */
23
+ export function addBalanceDeltas(a: BalanceDelta, b: BalanceDelta): BalanceDelta {
24
+ return {
25
+ amount0: a.amount0 + b.amount0,
26
+ amount1: a.amount1 + b.amount1,
27
+ }
28
+ }
29
+
30
+ /**
31
+ * Negate balance delta
32
+ */
33
+ export function negateBalanceDelta(delta: BalanceDelta): BalanceDelta {
34
+ return {
35
+ amount0: -delta.amount0,
36
+ amount1: -delta.amount1,
37
+ }
38
+ }
39
+
40
+ /**
41
+ * Check if balance delta is zero
42
+ */
43
+ export function isZeroDelta(delta: BalanceDelta): boolean {
44
+ return delta.amount0 === 0n && delta.amount1 === 0n
45
+ }
46
+
47
+ /**
48
+ * Get the amount for a specific currency (0 or 1)
49
+ */
50
+ export function getDeltaAmount(delta: BalanceDelta, currency: 0 | 1): bigint {
51
+ return currency === 0 ? delta.amount0 : delta.amount1
52
+ }
@@ -0,0 +1,7 @@
1
+ /**
2
+ * DEX Types and Utilities
3
+ */
4
+
5
+ export * from './types'
6
+ export * from './pool-key'
7
+ export * from './balance-delta'
@@ -0,0 +1,62 @@
1
+ import { keccak256, encodeAbiParameters, type Address } from 'viem'
2
+ import type { PoolKey, Currency } from './types'
3
+
4
+ /**
5
+ * Sort currencies to ensure currency0 < currency1
6
+ */
7
+ export function sortCurrencies(currencyA: Currency, currencyB: Currency): [Currency, Currency] {
8
+ const a = BigInt(currencyA)
9
+ const b = BigInt(currencyB)
10
+ return a < b ? [currencyA, currencyB] : [currencyB, currencyA]
11
+ }
12
+
13
+ /**
14
+ * Create a pool key from parameters
15
+ */
16
+ export function createPoolKey(
17
+ currencyA: Currency,
18
+ currencyB: Currency,
19
+ fee: number,
20
+ tickSpacing: number,
21
+ hooks: Address = '0x0000000000000000000000000000000000000000'
22
+ ): PoolKey {
23
+ const [currency0, currency1] = sortCurrencies(currencyA, currencyB)
24
+ return {
25
+ currency0,
26
+ currency1,
27
+ fee,
28
+ tickSpacing,
29
+ hooks,
30
+ }
31
+ }
32
+
33
+ /**
34
+ * Compute pool ID from pool key
35
+ */
36
+ export function computePoolId(key: PoolKey): `0x${string}` {
37
+ return keccak256(
38
+ encodeAbiParameters(
39
+ [
40
+ { type: 'address', name: 'currency0' },
41
+ { type: 'address', name: 'currency1' },
42
+ { type: 'uint24', name: 'fee' },
43
+ { type: 'int24', name: 'tickSpacing' },
44
+ { type: 'address', name: 'hooks' },
45
+ ],
46
+ [key.currency0, key.currency1, key.fee, key.tickSpacing, key.hooks]
47
+ )
48
+ )
49
+ }
50
+
51
+ /**
52
+ * Check if two pool keys are equal
53
+ */
54
+ export function poolKeysEqual(a: PoolKey, b: PoolKey): boolean {
55
+ return (
56
+ a.currency0.toLowerCase() === b.currency0.toLowerCase() &&
57
+ a.currency1.toLowerCase() === b.currency1.toLowerCase() &&
58
+ a.fee === b.fee &&
59
+ a.tickSpacing === b.tickSpacing &&
60
+ a.hooks.toLowerCase() === b.hooks.toLowerCase()
61
+ )
62
+ }
@@ -0,0 +1,87 @@
1
+ import type { Address } from 'viem'
2
+
3
+ /**
4
+ * Currency type - address(0) represents native token
5
+ */
6
+ export type Currency = Address
7
+
8
+ /**
9
+ * Pool key uniquely identifies a pool
10
+ */
11
+ export interface PoolKey {
12
+ currency0: Currency
13
+ currency1: Currency
14
+ fee: number // uint24 - fee in hundredths of a bip (e.g., 3000 = 0.30%)
15
+ tickSpacing: number // int24
16
+ hooks: Address // Hook contract address (address(0) = no hooks)
17
+ }
18
+
19
+ /**
20
+ * Balance delta represents changes in token balances
21
+ * Positive = user owes pool, Negative = pool owes user
22
+ */
23
+ export interface BalanceDelta {
24
+ amount0: bigint
25
+ amount1: bigint
26
+ }
27
+
28
+ /**
29
+ * Swap parameters
30
+ */
31
+ export interface SwapParams {
32
+ zeroForOne: boolean // Direction: true = token0 -> token1
33
+ amountSpecified: bigint // Positive = exact input, Negative = exact output
34
+ sqrtPriceLimitX96: bigint // Price limit (0 for no limit)
35
+ }
36
+
37
+ /**
38
+ * Modify liquidity parameters
39
+ */
40
+ export interface ModifyLiquidityParams {
41
+ tickLower: number
42
+ tickUpper: number
43
+ liquidityDelta: bigint
44
+ salt: `0x${string}`
45
+ }
46
+
47
+ /**
48
+ * Pool slot0 state
49
+ */
50
+ export interface Slot0 {
51
+ sqrtPriceX96: bigint
52
+ tick: number
53
+ protocolFee: number
54
+ lpFee: number
55
+ }
56
+
57
+ /**
58
+ * Fee tiers (in hundredths of a bip)
59
+ */
60
+ export const FEE_TIERS = {
61
+ LOWEST: 100, // 0.01%
62
+ LOW: 500, // 0.05%
63
+ MEDIUM: 3000, // 0.30%
64
+ HIGH: 10000, // 1.00%
65
+ } as const
66
+
67
+ /**
68
+ * Tick spacing for fee tiers
69
+ */
70
+ export const TICK_SPACINGS: Record<number, number> = {
71
+ 100: 1,
72
+ 500: 10,
73
+ 3000: 60,
74
+ 10000: 200,
75
+ }
76
+
77
+ /**
78
+ * Native currency constant
79
+ */
80
+ export const NATIVE_CURRENCY: Currency = '0x0000000000000000000000000000000000000000'
81
+
82
+ /**
83
+ * Check if currency is native
84
+ */
85
+ export function isNativeCurrency(currency: Currency): boolean {
86
+ return currency === NATIVE_CURRENCY
87
+ }
@@ -0,0 +1,10 @@
1
+ /**
2
+ * React hooks for DEX interactions
3
+ */
4
+
5
+ export * from './use-swap-quote'
6
+ export * from './use-swap'
7
+ export * from './use-pools'
8
+ export * from './use-positions'
9
+ export * from './use-token-balance'
10
+ export * from './use-token-allowance'
@@ -0,0 +1,116 @@
1
+ 'use client'
2
+
3
+ import { useQuery } from '@tanstack/react-query'
4
+ import { usePublicClient } from 'wagmi'
5
+ import { getContracts } from '../contracts'
6
+ import { UNISWAP_V3_FACTORY_ABI, UNISWAP_V3_POOL_ABI } from '../contracts/abis'
7
+ import type { Address } from 'viem'
8
+
9
+ export interface Pool {
10
+ address: Address
11
+ token0: Address
12
+ token1: Address
13
+ fee: number
14
+ tickSpacing: number
15
+ liquidity: bigint
16
+ sqrtPriceX96: bigint
17
+ tick: number
18
+ }
19
+
20
+ /**
21
+ * Hook to get pool information
22
+ */
23
+ export function usePool(
24
+ token0: Address | undefined,
25
+ token1: Address | undefined,
26
+ fee: number,
27
+ chainId: number
28
+ ) {
29
+ const publicClient = usePublicClient({ chainId })
30
+ const contracts = getContracts(chainId)
31
+
32
+ return useQuery({
33
+ queryKey: ['pool', token0, token1, fee, chainId],
34
+ queryFn: async (): Promise<Pool | null> => {
35
+ if (!token0 || !token1 || !publicClient) return null
36
+
37
+ try {
38
+ // Get pool address from factory
39
+ const poolAddress = await publicClient.readContract({
40
+ address: contracts.V3_FACTORY,
41
+ abi: UNISWAP_V3_FACTORY_ABI,
42
+ functionName: 'getPool',
43
+ args: [token0, token1, fee],
44
+ })
45
+
46
+ if (poolAddress === '0x0000000000000000000000000000000000000000') {
47
+ return null
48
+ }
49
+
50
+ // Get pool state
51
+ const [slot0, liquidity, tickSpacing] = await Promise.all([
52
+ publicClient.readContract({
53
+ address: poolAddress,
54
+ abi: UNISWAP_V3_POOL_ABI,
55
+ functionName: 'slot0',
56
+ }),
57
+ publicClient.readContract({
58
+ address: poolAddress,
59
+ abi: UNISWAP_V3_POOL_ABI,
60
+ functionName: 'liquidity',
61
+ }),
62
+ publicClient.readContract({
63
+ address: poolAddress,
64
+ abi: UNISWAP_V3_POOL_ABI,
65
+ functionName: 'tickSpacing',
66
+ }),
67
+ ])
68
+
69
+ return {
70
+ address: poolAddress,
71
+ token0,
72
+ token1,
73
+ fee,
74
+ tickSpacing,
75
+ liquidity,
76
+ sqrtPriceX96: slot0[0],
77
+ tick: slot0[1],
78
+ }
79
+ } catch (error) {
80
+ console.error('Failed to fetch pool:', error)
81
+ return null
82
+ }
83
+ },
84
+ enabled: !!token0 && !!token1 && !!publicClient,
85
+ staleTime: 30_000,
86
+ })
87
+ }
88
+
89
+ /**
90
+ * Hook to get all pools for a token pair
91
+ */
92
+ export function usePools(
93
+ token0: Address | undefined,
94
+ token1: Address | undefined,
95
+ chainId: number
96
+ ) {
97
+ const pool100 = usePool(token0, token1, 100, chainId)
98
+ const pool500 = usePool(token0, token1, 500, chainId)
99
+ const pool3000 = usePool(token0, token1, 3000, chainId)
100
+ const pool10000 = usePool(token0, token1, 10000, chainId)
101
+
102
+ const pools = [
103
+ pool100.data,
104
+ pool500.data,
105
+ pool3000.data,
106
+ pool10000.data,
107
+ ].filter((p): p is Pool => p !== null)
108
+
109
+ return {
110
+ pools,
111
+ isLoading: pool100.isLoading || pool500.isLoading || pool3000.isLoading || pool10000.isLoading,
112
+ bestPool: pools.length > 0 ? pools.reduce((best, pool) =>
113
+ pool.liquidity > best.liquidity ? pool : best
114
+ ) : null,
115
+ }
116
+ }
@@ -0,0 +1,90 @@
1
+ 'use client'
2
+
3
+ import { useQuery } from '@tanstack/react-query'
4
+ import { usePublicClient } from 'wagmi'
5
+ import { getContracts } from '../contracts'
6
+ import { NFT_POSITION_MANAGER_ABI } from '../contracts/abis'
7
+ import type { Address } from 'viem'
8
+
9
+ export interface Position {
10
+ tokenId: bigint
11
+ token0: Address
12
+ token1: Address
13
+ fee: number
14
+ tickLower: number
15
+ tickUpper: number
16
+ liquidity: bigint
17
+ tokensOwed0: bigint
18
+ tokensOwed1: bigint
19
+ }
20
+
21
+ /**
22
+ * Hook to get user's liquidity positions
23
+ */
24
+ export function usePositions(owner: Address | undefined, chainId: number) {
25
+ const publicClient = usePublicClient({ chainId })
26
+ const contracts = getContracts(chainId)
27
+
28
+ return useQuery({
29
+ queryKey: ['positions', owner, chainId],
30
+ queryFn: async (): Promise<Position[]> => {
31
+ if (!owner || !publicClient) return []
32
+
33
+ try {
34
+ // Get number of positions
35
+ const balance = await publicClient.readContract({
36
+ address: contracts.V3_NFT_POSITION_MANAGER,
37
+ abi: NFT_POSITION_MANAGER_ABI,
38
+ functionName: 'balanceOf',
39
+ args: [owner],
40
+ })
41
+
42
+ if (balance === 0n) return []
43
+
44
+ // Get all token IDs
45
+ const tokenIds = await Promise.all(
46
+ Array.from({ length: Number(balance) }, (_, i) =>
47
+ publicClient.readContract({
48
+ address: contracts.V3_NFT_POSITION_MANAGER,
49
+ abi: NFT_POSITION_MANAGER_ABI,
50
+ functionName: 'tokenOfOwnerByIndex',
51
+ args: [owner, BigInt(i)],
52
+ })
53
+ )
54
+ )
55
+
56
+ // Get position details for each token ID
57
+ const positions = await Promise.all(
58
+ tokenIds.map(async (tokenId) => {
59
+ const position = await publicClient.readContract({
60
+ address: contracts.V3_NFT_POSITION_MANAGER,
61
+ abi: NFT_POSITION_MANAGER_ABI,
62
+ functionName: 'positions',
63
+ args: [tokenId],
64
+ })
65
+
66
+ return {
67
+ tokenId,
68
+ token0: position[2],
69
+ token1: position[3],
70
+ fee: position[4],
71
+ tickLower: position[5],
72
+ tickUpper: position[6],
73
+ liquidity: position[7],
74
+ tokensOwed0: position[10],
75
+ tokensOwed1: position[11],
76
+ }
77
+ })
78
+ )
79
+
80
+ // Filter out closed positions (zero liquidity)
81
+ return positions.filter((p) => p.liquidity > 0n)
82
+ } catch (error) {
83
+ console.error('Failed to fetch positions:', error)
84
+ return []
85
+ }
86
+ },
87
+ enabled: !!owner && !!publicClient,
88
+ staleTime: 60_000,
89
+ })
90
+ }