genius-intents 0.19.0 → 0.20.1-develop.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/CHANGELOG.md +54 -0
- package/dist/direct-pools/fourmeme/fourmeme-direct.service.js +16 -16
- package/dist/direct-pools/fourmeme/fourmeme-direct.service.js.map +1 -1
- package/dist/direct-pools/meteora/pool-info/meteora-damm-v1-pool-info.service.d.ts +1 -1
- package/dist/direct-pools/meteora/pool-info/meteora-damm-v1-pool-info.service.d.ts.map +1 -1
- package/dist/direct-pools/meteora/pool-info/meteora-damm-v1-pool-info.service.js +9 -2
- package/dist/direct-pools/meteora/pool-info/meteora-damm-v1-pool-info.service.js.map +1 -1
- package/dist/direct-pools/meteora/pool-info/meteora-damm-v2-pool-info.service.d.ts +1 -1
- package/dist/direct-pools/meteora/pool-info/meteora-damm-v2-pool-info.service.d.ts.map +1 -1
- package/dist/direct-pools/meteora/pool-info/meteora-damm-v2-pool-info.service.js +9 -2
- package/dist/direct-pools/meteora/pool-info/meteora-damm-v2-pool-info.service.js.map +1 -1
- package/dist/direct-pools/meteora/pool-info/meteora-dbc-pool-info.service.d.ts +1 -1
- package/dist/direct-pools/meteora/pool-info/meteora-dbc-pool-info.service.d.ts.map +1 -1
- package/dist/direct-pools/meteora/pool-info/meteora-dbc-pool-info.service.js +9 -2
- package/dist/direct-pools/meteora/pool-info/meteora-dbc-pool-info.service.js.map +1 -1
- package/dist/direct-pools/meteora/pool-info/meteora-dlmm-pool-info.service.d.ts +1 -1
- package/dist/direct-pools/meteora/pool-info/meteora-dlmm-pool-info.service.d.ts.map +1 -1
- package/dist/direct-pools/meteora/pool-info/meteora-dlmm-pool-info.service.js +9 -2
- package/dist/direct-pools/meteora/pool-info/meteora-dlmm-pool-info.service.js.map +1 -1
- package/dist/direct-pools/pump-fun/pool-info/pump-fun-pool-info.service.d.ts +1 -1
- package/dist/direct-pools/pump-fun/pool-info/pump-fun-pool-info.service.d.ts.map +1 -1
- package/dist/direct-pools/pump-fun/pool-info/pump-fun-pool-info.service.js +9 -2
- package/dist/direct-pools/pump-fun/pool-info/pump-fun-pool-info.service.js.map +1 -1
- package/dist/direct-pools/pump-fun/pool-info/pump-swap-amm-pool-info.service.d.ts +1 -1
- package/dist/direct-pools/pump-fun/pool-info/pump-swap-amm-pool-info.service.d.ts.map +1 -1
- package/dist/direct-pools/pump-fun/pool-info/pump-swap-amm-pool-info.service.js +9 -2
- package/dist/direct-pools/pump-fun/pool-info/pump-swap-amm-pool-info.service.js.map +1 -1
- package/dist/direct-pools/raydium/pool-info/raydium-amm-pool-info.service.d.ts +1 -1
- package/dist/direct-pools/raydium/pool-info/raydium-amm-pool-info.service.d.ts.map +1 -1
- package/dist/direct-pools/raydium/pool-info/raydium-amm-pool-info.service.js +9 -2
- package/dist/direct-pools/raydium/pool-info/raydium-amm-pool-info.service.js.map +1 -1
- package/dist/direct-pools/raydium/pool-info/raydium-clmm-pool-info.service.d.ts +1 -1
- package/dist/direct-pools/raydium/pool-info/raydium-clmm-pool-info.service.d.ts.map +1 -1
- package/dist/direct-pools/raydium/pool-info/raydium-clmm-pool-info.service.js +9 -2
- package/dist/direct-pools/raydium/pool-info/raydium-clmm-pool-info.service.js.map +1 -1
- package/dist/direct-pools/raydium/pool-info/raydium-cpmm-pool-info.service.d.ts +1 -1
- package/dist/direct-pools/raydium/pool-info/raydium-cpmm-pool-info.service.d.ts.map +1 -1
- package/dist/direct-pools/raydium/pool-info/raydium-cpmm-pool-info.service.js +9 -2
- package/dist/direct-pools/raydium/pool-info/raydium-cpmm-pool-info.service.js.map +1 -1
- package/dist/direct-pools/raydium/pool-info/raydium-launchlab-pool-info.service.d.ts +1 -1
- package/dist/direct-pools/raydium/pool-info/raydium-launchlab-pool-info.service.d.ts.map +1 -1
- package/dist/direct-pools/raydium/pool-info/raydium-launchlab-pool-info.service.js +9 -2
- package/dist/direct-pools/raydium/pool-info/raydium-launchlab-pool-info.service.js.map +1 -1
- package/dist/direct-pools/whirlpools/pool-info/whirlpools-pool-info.service.d.ts +1 -1
- package/dist/direct-pools/whirlpools/pool-info/whirlpools-pool-info.service.d.ts.map +1 -1
- package/dist/direct-pools/whirlpools/pool-info/whirlpools-pool-info.service.js +9 -2
- package/dist/direct-pools/whirlpools/pool-info/whirlpools-pool-info.service.js.map +1 -1
- package/dist/genius-intents.d.ts.map +1 -1
- package/dist/genius-intents.js +3 -0
- package/dist/genius-intents.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -1
- package/dist/index.js.map +1 -1
- package/dist/lib/dex/algebra/algebra-dex-deployments.d.ts +3 -0
- package/dist/lib/dex/algebra/algebra-dex-deployments.d.ts.map +1 -0
- package/dist/lib/dex/algebra/algebra-dex-deployments.js +34 -0
- package/dist/lib/dex/algebra/algebra-dex-deployments.js.map +1 -0
- package/dist/lib/dex/algebra/quickswap-quoter.abi.d.ts +3 -0
- package/dist/lib/dex/algebra/quickswap-quoter.abi.d.ts.map +1 -0
- package/dist/lib/dex/algebra/quickswap-quoter.abi.js +103 -0
- package/dist/lib/dex/algebra/quickswap-quoter.abi.js.map +1 -0
- package/dist/lib/dex/fourmeme/fourmeme-v3-helper.abi.d.ts +3 -0
- package/dist/lib/dex/fourmeme/fourmeme-v3-helper.abi.d.ts.map +1 -0
- package/dist/lib/dex/fourmeme/fourmeme-v3-helper.abi.js +61 -0
- package/dist/lib/dex/fourmeme/fourmeme-v3-helper.abi.js.map +1 -0
- package/dist/lib/dex/lfj/lfj-dex-deployments.d.ts +3 -0
- package/dist/lib/dex/lfj/lfj-dex-deployments.d.ts.map +1 -0
- package/dist/lib/dex/lfj/lfj-dex-deployments.js +21 -0
- package/dist/lib/dex/lfj/lfj-dex-deployments.js.map +1 -0
- package/dist/lib/dex/lfj/lfj-quoter.abi.d.ts +3 -0
- package/dist/lib/dex/lfj/lfj-quoter.abi.d.ts.map +1 -0
- package/dist/lib/dex/lfj/lfj-quoter.abi.js +135 -0
- package/dist/lib/dex/lfj/lfj-quoter.abi.js.map +1 -0
- package/dist/lib/dex/lfj/lfj-router.abi.d.ts +3 -0
- package/dist/lib/dex/lfj/lfj-router.abi.d.ts.map +1 -0
- package/dist/lib/dex/lfj/lfj-router.abi.js +587 -0
- package/dist/lib/dex/lfj/lfj-router.abi.js.map +1 -0
- package/dist/lib/dex/pair-discovery/adapters/algebra-dex-pair-discovery.adapter.d.ts +22 -0
- package/dist/lib/dex/pair-discovery/adapters/algebra-dex-pair-discovery.adapter.d.ts.map +1 -0
- package/dist/lib/dex/pair-discovery/adapters/algebra-dex-pair-discovery.adapter.js +225 -0
- package/dist/lib/dex/pair-discovery/adapters/algebra-dex-pair-discovery.adapter.js.map +1 -0
- package/dist/lib/dex/pair-discovery/adapters/fourmeme-dex-pair-discovery.adapter.d.ts +20 -0
- package/dist/lib/dex/pair-discovery/adapters/fourmeme-dex-pair-discovery.adapter.d.ts.map +1 -0
- package/dist/lib/dex/pair-discovery/adapters/fourmeme-dex-pair-discovery.adapter.js +272 -0
- package/dist/lib/dex/pair-discovery/adapters/fourmeme-dex-pair-discovery.adapter.js.map +1 -0
- package/dist/lib/dex/pair-discovery/adapters/lfj-v3-dex-pair-doscovery.adapter.d.ts +19 -0
- package/dist/lib/dex/pair-discovery/adapters/lfj-v3-dex-pair-doscovery.adapter.d.ts.map +1 -0
- package/dist/lib/dex/pair-discovery/adapters/lfj-v3-dex-pair-doscovery.adapter.js +130 -0
- package/dist/lib/dex/pair-discovery/adapters/lfj-v3-dex-pair-doscovery.adapter.js.map +1 -0
- package/dist/lib/dex/pair-discovery/adapters/v2-dex-pair-discovery.adapter.d.ts +29 -0
- package/dist/lib/dex/pair-discovery/adapters/v2-dex-pair-discovery.adapter.d.ts.map +1 -0
- package/dist/lib/dex/pair-discovery/adapters/v2-dex-pair-discovery.adapter.js +179 -0
- package/dist/lib/dex/pair-discovery/adapters/v2-dex-pair-discovery.adapter.js.map +1 -0
- package/dist/lib/dex/pair-discovery/adapters/v3-dex-pair-discovery.adapter.d.ts +29 -0
- package/dist/lib/dex/pair-discovery/adapters/v3-dex-pair-discovery.adapter.d.ts.map +1 -0
- package/dist/lib/dex/pair-discovery/adapters/v3-dex-pair-discovery.adapter.js +345 -0
- package/dist/lib/dex/pair-discovery/adapters/v3-dex-pair-discovery.adapter.js.map +1 -0
- package/dist/lib/dex/pair-discovery/adapters/ve33-dex-pair-discovery.adapter.d.ts +36 -0
- package/dist/lib/dex/pair-discovery/adapters/ve33-dex-pair-discovery.adapter.d.ts.map +1 -0
- package/dist/lib/dex/pair-discovery/adapters/ve33-dex-pair-discovery.adapter.js +275 -0
- package/dist/lib/dex/pair-discovery/adapters/ve33-dex-pair-discovery.adapter.js.map +1 -0
- package/dist/lib/dex/pair-discovery/index.d.ts +3 -0
- package/dist/lib/dex/pair-discovery/index.d.ts.map +1 -0
- package/dist/lib/dex/pair-discovery/index.js +21 -0
- package/dist/lib/dex/pair-discovery/index.js.map +1 -0
- package/dist/lib/dex/pair-discovery/pair-discovery.service.d.ts +16 -0
- package/dist/lib/dex/pair-discovery/pair-discovery.service.d.ts.map +1 -0
- package/dist/lib/dex/pair-discovery/pair-discovery.service.js +98 -0
- package/dist/lib/dex/pair-discovery/pair-discovery.service.js.map +1 -0
- package/dist/lib/dex/pair-discovery/pair-discovery.types.d.ts +191 -0
- package/dist/lib/dex/pair-discovery/pair-discovery.types.d.ts.map +1 -0
- package/dist/lib/dex/pair-discovery/pair-discovery.types.js +3 -0
- package/dist/lib/dex/pair-discovery/pair-discovery.types.js.map +1 -0
- package/dist/lib/dex/uniswapV2/v2-dex-deployments.d.ts +5 -0
- package/dist/lib/dex/uniswapV2/v2-dex-deployments.d.ts.map +1 -0
- package/dist/lib/dex/uniswapV2/v2-dex-deployments.js +166 -0
- package/dist/lib/dex/uniswapV2/v2-dex-deployments.js.map +1 -0
- package/dist/lib/dex/uniswapv3/{v3-offchain-quoter.service.d.ts → offchain-quoter/v3-offchain-quoter.service.d.ts} +1 -1
- package/dist/lib/dex/uniswapv3/offchain-quoter/v3-offchain-quoter.service.d.ts.map +1 -0
- package/dist/lib/dex/uniswapv3/{v3-offchain-quoter.service.js → offchain-quoter/v3-offchain-quoter.service.js} +3 -3
- package/dist/lib/dex/uniswapv3/offchain-quoter/v3-offchain-quoter.service.js.map +1 -0
- package/dist/lib/dex/uniswapv3/offchain-quoter/v3-offchain-quoter.types.d.ts +162 -0
- package/dist/lib/dex/uniswapv3/offchain-quoter/v3-offchain-quoter.types.d.ts.map +1 -0
- package/dist/lib/dex/uniswapv3/offchain-quoter/v3-offchain-quoter.types.js +3 -0
- package/dist/lib/dex/uniswapv3/offchain-quoter/v3-offchain-quoter.types.js.map +1 -0
- package/dist/lib/dex/uniswapv3/ramses-quoter.abi.d.ts +3 -0
- package/dist/lib/dex/uniswapv3/ramses-quoter.abi.d.ts.map +1 -0
- package/dist/lib/dex/uniswapv3/ramses-quoter.abi.js +114 -0
- package/dist/lib/dex/uniswapv3/ramses-quoter.abi.js.map +1 -0
- package/dist/lib/dex/uniswapv3/v3-dex-deployments.d.ts +32 -0
- package/dist/lib/dex/uniswapv3/v3-dex-deployments.d.ts.map +1 -0
- package/dist/lib/dex/uniswapv3/v3-dex-deployments.js +283 -0
- package/dist/lib/dex/uniswapv3/v3-dex-deployments.js.map +1 -0
- package/dist/lib/dex/ve33/pharaoh-swap-router.abi.d.ts +3 -0
- package/dist/lib/dex/ve33/pharaoh-swap-router.abi.d.ts.map +1 -0
- package/dist/lib/dex/ve33/pharaoh-swap-router.abi.js +239 -0
- package/dist/lib/dex/ve33/pharaoh-swap-router.abi.js.map +1 -0
- package/dist/lib/dex/ve33/ve33-dex-deployments.d.ts +4 -0
- package/dist/lib/dex/ve33/ve33-dex-deployments.d.ts.map +1 -0
- package/dist/lib/dex/ve33/ve33-dex-deployments.js +34 -0
- package/dist/lib/dex/ve33/ve33-dex-deployments.js.map +1 -0
- package/dist/protocols/algebra/algebra.service.d.ts +9 -7
- package/dist/protocols/algebra/algebra.service.d.ts.map +1 -1
- package/dist/protocols/algebra/algebra.service.js +84 -113
- package/dist/protocols/algebra/algebra.service.js.map +1 -1
- package/dist/protocols/algebra/algebra.types.d.ts +30 -16
- package/dist/protocols/algebra/algebra.types.d.ts.map +1 -1
- package/dist/protocols/algebra/algebra.types.js +1 -1
- package/dist/protocols/algebra/algebra.types.js.map +1 -1
- package/dist/protocols/four-meme/four-meme.service.d.ts.map +1 -1
- package/dist/protocols/four-meme/four-meme.service.js +54 -59
- package/dist/protocols/four-meme/four-meme.service.js.map +1 -1
- package/dist/protocols/four-meme/four-meme.types.d.ts +2 -5
- package/dist/protocols/four-meme/four-meme.types.d.ts.map +1 -1
- package/dist/protocols/genius-bridge/genius-bridge.service.d.ts +2 -1
- package/dist/protocols/genius-bridge/genius-bridge.service.d.ts.map +1 -1
- package/dist/protocols/genius-bridge/genius-bridge.service.js.map +1 -1
- package/dist/protocols/genius-bridge/index.d.ts +1 -1
- package/dist/protocols/genius-bridge/index.d.ts.map +1 -1
- package/dist/protocols/lfj/index.d.ts +3 -0
- package/dist/protocols/lfj/index.d.ts.map +1 -0
- package/dist/protocols/lfj/index.js +21 -0
- package/dist/protocols/lfj/index.js.map +1 -0
- package/dist/protocols/lfj/lfj.service.d.ts +45 -0
- package/dist/protocols/lfj/lfj.service.d.ts.map +1 -0
- package/dist/protocols/lfj/lfj.service.js +324 -0
- package/dist/protocols/lfj/lfj.service.js.map +1 -0
- package/dist/protocols/lfj/lfj.types.d.ts +134 -0
- package/dist/protocols/lfj/lfj.types.d.ts.map +1 -0
- package/dist/protocols/lfj/lfj.types.js +16 -0
- package/dist/protocols/lfj/lfj.types.js.map +1 -0
- package/dist/protocols/v2-dex/index.d.ts +1 -1
- package/dist/protocols/v2-dex/index.d.ts.map +1 -1
- package/dist/protocols/v2-dex/index.js +15 -0
- package/dist/protocols/v2-dex/index.js.map +1 -1
- package/dist/protocols/v2-dex/v2-dex.service.d.ts +9 -13
- package/dist/protocols/v2-dex/v2-dex.service.d.ts.map +1 -1
- package/dist/protocols/v2-dex/v2-dex.service.js +80 -496
- package/dist/protocols/v2-dex/v2-dex.service.js.map +1 -1
- package/dist/protocols/v2-dex/v2-dex.types.d.ts +29 -30
- package/dist/protocols/v2-dex/v2-dex.types.d.ts.map +1 -1
- package/dist/protocols/v2-dex/v2-dex.types.js.map +1 -1
- package/dist/protocols/v3-dex/adapters/slipstream.adapter.d.ts +42 -0
- package/dist/protocols/v3-dex/adapters/slipstream.adapter.d.ts.map +1 -0
- package/dist/protocols/v3-dex/adapters/slipstream.adapter.js +185 -0
- package/dist/protocols/v3-dex/adapters/slipstream.adapter.js.map +1 -0
- package/dist/protocols/v3-dex/adapters/uniswap-fork.adapter.d.ts +40 -0
- package/dist/protocols/v3-dex/adapters/uniswap-fork.adapter.d.ts.map +1 -0
- package/dist/protocols/v3-dex/adapters/uniswap-fork.adapter.js +237 -0
- package/dist/protocols/v3-dex/adapters/uniswap-fork.adapter.js.map +1 -0
- package/dist/protocols/v3-dex/adapters/uniswap.adapter.d.ts +39 -0
- package/dist/protocols/v3-dex/adapters/uniswap.adapter.d.ts.map +1 -0
- package/dist/protocols/v3-dex/adapters/uniswap.adapter.js +226 -0
- package/dist/protocols/v3-dex/adapters/uniswap.adapter.js.map +1 -0
- package/dist/protocols/v3-dex/index.d.ts +1 -1
- package/dist/protocols/v3-dex/index.d.ts.map +1 -1
- package/dist/protocols/v3-dex/index.js +15 -0
- package/dist/protocols/v3-dex/index.js.map +1 -1
- package/dist/protocols/v3-dex/v3-dex.service.d.ts +21 -120
- package/dist/protocols/v3-dex/v3-dex.service.d.ts.map +1 -1
- package/dist/protocols/v3-dex/v3-dex.service.js +383 -1364
- package/dist/protocols/v3-dex/v3-dex.service.js.map +1 -1
- package/dist/protocols/v3-dex/v3-dex.types.d.ts +144 -374
- package/dist/protocols/v3-dex/v3-dex.types.d.ts.map +1 -1
- package/dist/protocols/v3-dex/v3-dex.types.js +10 -1
- package/dist/protocols/v3-dex/v3-dex.types.js.map +1 -1
- package/dist/protocols/ve33/adapters/blackhole.adapter.d.ts +29 -0
- package/dist/protocols/ve33/adapters/blackhole.adapter.d.ts.map +1 -0
- package/dist/protocols/ve33/adapters/blackhole.adapter.js +59 -0
- package/dist/protocols/ve33/adapters/blackhole.adapter.js.map +1 -0
- package/dist/protocols/ve33/adapters/pharaoh.adapter.d.ts +34 -0
- package/dist/protocols/ve33/adapters/pharaoh.adapter.d.ts.map +1 -0
- package/dist/protocols/ve33/adapters/pharaoh.adapter.js +51 -0
- package/dist/protocols/ve33/adapters/pharaoh.adapter.js.map +1 -0
- package/dist/protocols/ve33/adapters/solidly.adapter.d.ts +42 -0
- package/dist/protocols/ve33/adapters/solidly.adapter.d.ts.map +1 -0
- package/dist/protocols/ve33/adapters/solidly.adapter.js +63 -0
- package/dist/protocols/ve33/adapters/solidly.adapter.js.map +1 -0
- package/dist/protocols/ve33/index.d.ts +1 -1
- package/dist/protocols/ve33/index.d.ts.map +1 -1
- package/dist/protocols/ve33/index.js +15 -0
- package/dist/protocols/ve33/index.js.map +1 -1
- package/dist/protocols/ve33/ve33.service.d.ts +8 -3
- package/dist/protocols/ve33/ve33.service.d.ts.map +1 -1
- package/dist/protocols/ve33/ve33.service.js +128 -125
- package/dist/protocols/ve33/ve33.service.js.map +1 -1
- package/dist/protocols/ve33/ve33.types.d.ts +19 -33
- package/dist/protocols/ve33/ve33.types.d.ts.map +1 -1
- package/dist/protocols/ve33/ve33.types.js +6 -1
- package/dist/protocols/ve33/ve33.types.js.map +1 -1
- package/dist/token-launches/jupiter/jupiter-studio-launch.constants.d.ts +40 -0
- package/dist/token-launches/jupiter/jupiter-studio-launch.constants.d.ts.map +1 -0
- package/dist/token-launches/jupiter/jupiter-studio-launch.constants.js +43 -0
- package/dist/token-launches/jupiter/jupiter-studio-launch.constants.js.map +1 -0
- package/dist/token-launches/jupiter/jupiter-studio-launch.service.d.ts +10 -0
- package/dist/token-launches/jupiter/jupiter-studio-launch.service.d.ts.map +1 -0
- package/dist/token-launches/jupiter/jupiter-studio-launch.service.js +56 -0
- package/dist/token-launches/jupiter/jupiter-studio-launch.service.js.map +1 -0
- package/dist/token-launches/jupiter/jupiter-studio-launch.types.d.ts +49 -0
- package/dist/token-launches/jupiter/jupiter-studio-launch.types.d.ts.map +1 -0
- package/dist/token-launches/jupiter/jupiter-studio-launch.types.js +3 -0
- package/dist/token-launches/jupiter/jupiter-studio-launch.types.js.map +1 -0
- package/dist/token-launches/jupiter/jupiter-studio-launch.utils.d.ts +9 -0
- package/dist/token-launches/jupiter/jupiter-studio-launch.utils.d.ts.map +1 -0
- package/dist/token-launches/jupiter/jupiter-studio-launch.utils.js +82 -0
- package/dist/token-launches/jupiter/jupiter-studio-launch.utils.js.map +1 -0
- package/dist/token-launches/meteora/meteora-launch.constants.d.ts +11 -0
- package/dist/token-launches/meteora/meteora-launch.constants.d.ts.map +1 -0
- package/dist/token-launches/meteora/meteora-launch.constants.js +15 -0
- package/dist/token-launches/meteora/meteora-launch.constants.js.map +1 -0
- package/dist/token-launches/meteora/meteora-launch.service.d.ts +13 -0
- package/dist/token-launches/meteora/meteora-launch.service.d.ts.map +1 -0
- package/dist/token-launches/meteora/meteora-launch.service.js +64 -0
- package/dist/token-launches/meteora/meteora-launch.service.js.map +1 -0
- package/dist/token-launches/meteora/meteora-launch.types.d.ts +18 -0
- package/dist/token-launches/meteora/meteora-launch.types.d.ts.map +1 -0
- package/dist/token-launches/meteora/meteora-launch.types.js +3 -0
- package/dist/token-launches/meteora/meteora-launch.types.js.map +1 -0
- package/dist/token-launches/meteora/meteora-launch.utils.d.ts +4 -0
- package/dist/token-launches/meteora/meteora-launch.utils.d.ts.map +1 -0
- package/dist/token-launches/meteora/meteora-launch.utils.js +54 -0
- package/dist/token-launches/meteora/meteora-launch.utils.js.map +1 -0
- package/dist/token-launches/pump-fun/pump-fun-launch.service.d.ts +13 -0
- package/dist/token-launches/pump-fun/pump-fun-launch.service.d.ts.map +1 -0
- package/dist/token-launches/pump-fun/pump-fun-launch.service.js +63 -0
- package/dist/token-launches/pump-fun/pump-fun-launch.service.js.map +1 -0
- package/dist/token-launches/pump-fun/pump-fun-launch.types.d.ts +12 -0
- package/dist/token-launches/pump-fun/pump-fun-launch.types.d.ts.map +1 -0
- package/dist/token-launches/pump-fun/pump-fun-launch.types.js +3 -0
- package/dist/token-launches/pump-fun/pump-fun-launch.types.js.map +1 -0
- package/dist/token-launches/raydium-launchlab/raydium-launch.constants.d.ts +13 -0
- package/dist/token-launches/raydium-launchlab/raydium-launch.constants.d.ts.map +1 -0
- package/dist/token-launches/raydium-launchlab/raydium-launch.constants.js +18 -0
- package/dist/token-launches/raydium-launchlab/raydium-launch.constants.js.map +1 -0
- package/dist/token-launches/raydium-launchlab/raydium-launch.service.d.ts +13 -0
- package/dist/token-launches/raydium-launchlab/raydium-launch.service.d.ts.map +1 -0
- package/dist/token-launches/raydium-launchlab/raydium-launch.service.js +102 -0
- package/dist/token-launches/raydium-launchlab/raydium-launch.service.js.map +1 -0
- package/dist/token-launches/raydium-launchlab/raydium-launch.types.d.ts +57 -0
- package/dist/token-launches/raydium-launchlab/raydium-launch.types.d.ts.map +1 -0
- package/dist/token-launches/raydium-launchlab/raydium-launch.types.js +3 -0
- package/dist/token-launches/raydium-launchlab/raydium-launch.types.js.map +1 -0
- package/dist/types/enums.d.ts +4 -2
- package/dist/types/enums.d.ts.map +1 -1
- package/dist/types/enums.js +2 -0
- package/dist/types/enums.js.map +1 -1
- package/dist/types/price-params.d.ts +8 -3
- package/dist/types/price-params.d.ts.map +1 -1
- package/dist/types/price-response.d.ts +4 -3
- package/dist/types/price-response.d.ts.map +1 -1
- package/dist/types/quote-response.d.ts +4 -3
- package/dist/types/quote-response.d.ts.map +1 -1
- package/dist/utils/chainId-to-chain.d.ts +4 -0
- package/dist/utils/chainId-to-chain.d.ts.map +1 -0
- package/dist/utils/chainId-to-chain.js +44 -0
- package/dist/utils/chainId-to-chain.js.map +1 -0
- package/dist/utils/norm-dex-token.d.ts +13 -0
- package/dist/utils/norm-dex-token.d.ts.map +1 -0
- package/dist/utils/norm-dex-token.js +19 -0
- package/dist/utils/norm-dex-token.js.map +1 -0
- package/dist/utils/pair-result.d.ts +3 -0
- package/dist/utils/pair-result.d.ts.map +1 -0
- package/dist/utils/pair-result.js +11 -0
- package/dist/utils/pair-result.js.map +1 -0
- package/dist/utils/sort-addresses.d.ts +2 -1
- package/dist/utils/sort-addresses.d.ts.map +1 -1
- package/dist/utils/sort-addresses.js +3 -1
- package/dist/utils/sort-addresses.js.map +1 -1
- package/dist/utils/to-pool-key.d.ts +4 -0
- package/dist/utils/to-pool-key.d.ts.map +1 -0
- package/dist/utils/to-pool-key.js +15 -0
- package/dist/utils/to-pool-key.js.map +1 -0
- package/dist/utils/transaction-builder.util.d.ts +3 -0
- package/dist/utils/transaction-builder.util.d.ts.map +1 -0
- package/dist/utils/transaction-builder.util.js +13 -0
- package/dist/utils/transaction-builder.util.js.map +1 -0
- package/package.json +2 -2
- package/dist/lib/dex/uniswapv3/v3-offchain-quoter.service.d.ts.map +0 -1
- package/dist/lib/dex/uniswapv3/v3-offchain-quoter.service.js.map +0 -1
|
@@ -2,745 +2,270 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.V3StyleDexService = void 0;
|
|
4
4
|
const viem_1 = require("viem");
|
|
5
|
-
const ethers_1 = require("ethers");
|
|
6
5
|
const v3_dex_types_1 = require("./v3-dex.types");
|
|
7
|
-
const
|
|
8
|
-
const pacakeswapV3_router_abi_1 = require("../../lib/dex/pancakeswap/pacakeswapV3-router.abi");
|
|
9
|
-
const v3_offchain_quoter_service_1 = require("../../lib/dex/uniswapv3/v3-offchain-quoter.service");
|
|
10
|
-
const slipstream_quoter_abi_1 = require("../../lib/dex/uniswapv3/slipstream-quoter.abi");
|
|
11
|
-
const slipstream_router_abi_1 = require("../../lib/dex/uniswapv3/slipstream-router.abi");
|
|
12
|
-
const uniswapV3_quoter_abi_1 = require("../../lib/dex/uniswapv3/uniswapV3-quoter.abi");
|
|
13
|
-
const uniswapV3_router_abi_1 = require("../../lib/dex/uniswapv3/uniswapV3-router.abi");
|
|
14
|
-
const uniswapV3_pool_abi_1 = require("../../lib/dex/uniswapv3/uniswapV3-pool.abi");
|
|
6
|
+
const v3_dex_deployments_1 = require("../../lib/dex/uniswapv3/v3-dex-deployments");
|
|
15
7
|
const enums_1 = require("../../types/enums");
|
|
8
|
+
const slipstream_adapter_1 = require("./adapters/slipstream.adapter");
|
|
9
|
+
const uniswap_fork_adapter_1 = require("./adapters/uniswap-fork.adapter");
|
|
16
10
|
const min_amount_out_1 = require("../../utils/min-amount-out");
|
|
17
11
|
const wrapped_native_1 = require("../../utils/wrapped-native");
|
|
12
|
+
const uniswap_adapter_1 = require("./adapters/uniswap.adapter");
|
|
13
|
+
const chainId_to_chain_1 = require("../../utils/chainId-to-chain");
|
|
18
14
|
const constants_1 = require("../../utils/constants");
|
|
15
|
+
const to_pool_key_1 = require("../../utils/to-pool-key");
|
|
19
16
|
const is_native_1 = require("../../utils/is-native");
|
|
20
|
-
const logger_1 = require("../../utils/logger");
|
|
21
17
|
const utils_1 = require("../../utils");
|
|
22
|
-
const
|
|
23
|
-
|
|
24
|
-
/**
|
|
25
|
-
*
|
|
26
|
-
*
|
|
27
|
-
* This service provides price discovery and swap quote functionality for supported chains and DEX deployments.
|
|
28
|
-
* It supports multicall-based quoting across multiple fee tiers and deployments, with fallback logic for different quoter contract versions.
|
|
29
|
-
*
|
|
30
|
-
* @remarks
|
|
31
|
-
* - Only single-chain swaps are supported.
|
|
32
|
-
* - Deployments and RPC clients are configured via the constructor.
|
|
33
|
-
* - Supports Uniswap V3, PancakeSwap V3, Slipstream, and SushiSwap V3 deployments on Avalanche, Arbitrum, BSC, Base, Ethereum, Optimism, HyperEVM, and Polygon.
|
|
34
|
-
*
|
|
35
|
-
* @example
|
|
36
|
-
* ```typescript
|
|
37
|
-
import { base, optimism } from 'viem/chains';
|
|
38
|
-
|
|
39
|
-
async function t() {
|
|
40
|
-
const rpcs = {
|
|
41
|
-
[ChainIdEnum.BASE]: '<url>',
|
|
42
|
-
[ChainIdEnum.OPTIMISM]: '<url>',
|
|
43
|
-
};
|
|
44
|
-
|
|
45
|
-
const solidlyChainConfigs = {
|
|
46
|
-
[ChainIdEnum.BASE]: base,
|
|
47
|
-
[ChainIdEnum.OPTIMISM]: optimism,
|
|
48
|
-
};
|
|
49
|
-
|
|
50
|
-
const s = new V3StyleDexService({ rpcs, uniV3ChainConfigs: solidlyChainConfigs });
|
|
51
|
-
const a = await s.fetchQuote({
|
|
52
|
-
from: '0x055698dead6666c0690B1419647556149005504D',
|
|
53
|
-
receiver: '0x055698dead6666c0690B1419647556149005504D',
|
|
54
|
-
tokenOut: ZERO_ADDRESS, // WETH
|
|
55
|
-
tokenIn: '0x940181a94A35A4569E4529A3CDfB74e38FD98631', // USDC
|
|
56
|
-
amountIn: '100000000000000000000', // s0.01 WETH
|
|
57
|
-
networkIn: ChainIdEnum.BASE,
|
|
58
|
-
networkOut: ChainIdEnum.BASE,
|
|
59
|
-
slippage: 10, // 1%
|
|
60
|
-
});
|
|
61
|
-
|
|
62
|
-
const c = await s.fetchQuote({
|
|
63
|
-
from: '0x055698dead6666c0690B1419647556149005504D',
|
|
64
|
-
receiver: '0x055698dead6666c0690B1419647556149005504D',
|
|
65
|
-
tokenIn: ZERO_ADDRESS, // WETH
|
|
66
|
-
tokenOut: '0x9560e827aF36c94D2Ac33a39bCE1Fe78631088Db', // USDC
|
|
67
|
-
amountIn: '100000000000000000', // 0.01 WETH
|
|
68
|
-
networkIn: ChainIdEnum.OPTIMISM,
|
|
69
|
-
networkOut: ChainIdEnum.OPTIMISM,
|
|
70
|
-
slippage: 10, // 1%
|
|
71
|
-
});
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
t();
|
|
75
|
-
* ```
|
|
76
|
-
*
|
|
77
|
-
* @implements IIntentProtocol
|
|
78
|
-
*/
|
|
18
|
+
const logger_1 = require("../../utils/logger");
|
|
19
|
+
let logger;
|
|
20
|
+
/** -----------------------------------------------------------------------
|
|
21
|
+
* V3StyleDexService
|
|
22
|
+
* --------------------------------------------------------------------- */
|
|
79
23
|
class V3StyleDexService {
|
|
80
24
|
constructor(config) {
|
|
81
|
-
/**
|
|
82
|
-
* The protocol that the service produces
|
|
83
|
-
*/
|
|
84
25
|
this.protocol = enums_1.ProtocolEnum.UNISWAP_V3;
|
|
85
|
-
/**
|
|
86
|
-
* Whether the service supports a single chain
|
|
87
|
-
*/
|
|
88
26
|
this.singleChain = true;
|
|
89
|
-
/**
|
|
90
|
-
* Whether the service supports multiple chains
|
|
91
|
-
*/
|
|
92
27
|
this.multiChain = false;
|
|
93
|
-
|
|
94
|
-
* The chains that the service supports
|
|
95
|
-
*/
|
|
96
|
-
this.chains = [
|
|
97
|
-
enums_1.ChainIdEnum.AVALANCHE,
|
|
98
|
-
enums_1.ChainIdEnum.ARBITRUM,
|
|
99
|
-
enums_1.ChainIdEnum.BSC,
|
|
100
|
-
enums_1.ChainIdEnum.BASE,
|
|
101
|
-
enums_1.ChainIdEnum.ETHEREUM,
|
|
102
|
-
enums_1.ChainIdEnum.OPTIMISM,
|
|
103
|
-
enums_1.ChainIdEnum.POLYGON,
|
|
104
|
-
enums_1.ChainIdEnum.HYPEREVM,
|
|
105
|
-
];
|
|
106
|
-
/**
|
|
107
|
-
* Public clients by chain
|
|
108
|
-
*/
|
|
28
|
+
this.chains = v3_dex_deployments_1.uniV3SupportedChains;
|
|
109
29
|
this._clients = {};
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
{
|
|
131
|
-
dex: v3_dex_types_1.UniswapV3StyleDexEnum.UNISWAP_V3,
|
|
132
|
-
quoter: '0xbe0F5544EC67e9B3b2D979aaA43f18Fd87E6257F',
|
|
133
|
-
router: '0xbb00FF08d01D300023C629E8fFfFcb65A5a578cE',
|
|
134
|
-
factory: '0x740b1c1de25031C31FF4fC9A62f554A55cdC1baD',
|
|
135
|
-
initHash: '0xe34f199b19b2b4f47f68442619d555527d244f78a3297ea89325f843f87b8b54',
|
|
136
|
-
},
|
|
137
|
-
{
|
|
138
|
-
dex: v3_dex_types_1.UniswapV3StyleDexEnum.PANGOLIN_V3,
|
|
139
|
-
quoter: '0xA86522CCc412dBC4FA10991900FE46De95983822',
|
|
140
|
-
factory: '0x1128F23D0bc0A8396E9FBC3c0c68f5EA228B8256',
|
|
141
|
-
router: '0x5485A0751a249225D3bA2f6f296551507e22547f',
|
|
142
|
-
initHash: '0x40231f6b438bce0797c9ada29b718a87ea0a5cea3fe9a771abdd76bd41a3e545',
|
|
143
|
-
},
|
|
144
|
-
{
|
|
145
|
-
dex: v3_dex_types_1.UniswapV3StyleDexEnum.PHARAOH_CLMM, // reuse existing UNISWAP_V3 branch/ABIs
|
|
146
|
-
router: '0x062c62cA66E50Cfe277A95564Fe5bB504db1Fab8', // SwapRouter (immutable & verified)
|
|
147
|
-
quoter: '0xAAAEA10b0e6FBe566FE27c3A023DC5D8cA6Bca3d', // QuoterV2
|
|
148
|
-
factory: '0xAAA32926fcE6bE95ea2c51cB4Fcb60836D320C42', // PharaohV2Factory (CL)
|
|
149
|
-
initHash: '0x1565b129f2d1790f12d45301b9b084335626f0c92410bc43130763b69971135d',
|
|
150
|
-
},
|
|
151
|
-
// {
|
|
152
|
-
// dex: UniswapV3StyleDexEnum.SUSHISWAP_V3,
|
|
153
|
-
// router: '0x81602ef321c46d73f5ba7f476947ae1a862957dc', // RouteProcessor9
|
|
154
|
-
// factory: '0x3e603c14af37ebdad31709c4f848fc6ad5bec715',
|
|
155
|
-
// },
|
|
156
|
-
],
|
|
157
|
-
[enums_1.ChainIdEnum.ARBITRUM]: [
|
|
158
|
-
{
|
|
159
|
-
dex: v3_dex_types_1.UniswapV3StyleDexEnum.UNISWAP_V3,
|
|
160
|
-
quoter: '0x61fFE014bA17989E743c5F6cB21bF9697530B21e',
|
|
161
|
-
router: '0x68b3465833fb72A70ecDF485E0e4C7bD8665Fc45',
|
|
162
|
-
factory: '0x1F98431c8aD98523631AE4a59f267346ea31F984',
|
|
163
|
-
initHash: '0xe34f199b19b2b4f47f68442619d555527d244f78a3297ea89325f843f87b8b54',
|
|
164
|
-
},
|
|
165
|
-
{
|
|
166
|
-
dex: v3_dex_types_1.UniswapV3StyleDexEnum.PANCAKESWAP_V3,
|
|
167
|
-
quoter: '0xB048Bbc1Ee6b733FFfCFb9e9CeF7375518e25997',
|
|
168
|
-
deployer: '0x41ff9AA7e16B8B1a8a8dc4f0eFacd93D02d071c9',
|
|
169
|
-
router: '0x1b81D678ffb9C0263b24A97847620C99d213eB14',
|
|
170
|
-
factory: '0x0BFbCF9fa4f9C56B0F40a671Ad40E0805A091865',
|
|
171
|
-
initHash: '0x6ce8eb472fa82df5469c6ab6d485f17c3ad13c8cd7af59b3d4a8026c5ce0f7e2',
|
|
172
|
-
},
|
|
173
|
-
// {
|
|
174
|
-
// dex: UniswapV3StyleDexEnum.SUSHISWAP_V3,
|
|
175
|
-
// router: '0x81602ef321c46d73f5ba7f476947ae1a862957dc', // RouteProcessor9
|
|
176
|
-
// factory: '0x1af415a1eba07a4986a52b6f2e7de7003d82231e',
|
|
177
|
-
// },
|
|
178
|
-
],
|
|
179
|
-
[enums_1.ChainIdEnum.BSC]: [
|
|
180
|
-
{
|
|
181
|
-
dex: v3_dex_types_1.UniswapV3StyleDexEnum.UNISWAP_V3,
|
|
182
|
-
quoter: '0x78D78E420Da98ad378D7799bE8f4AF69033EB077',
|
|
183
|
-
router: '0xB971eF87ede563556b2ED4b1C0b0019111Dd85d2',
|
|
184
|
-
factory: '0xdB1d10011AD0Ff90774D0C6Bb92e5C5c8b4461F7',
|
|
185
|
-
initHash: '0xe34f199b19b2b4f47f68442619d555527d244f78a3297ea89325f843f87b8b54',
|
|
186
|
-
},
|
|
187
|
-
{
|
|
188
|
-
dex: v3_dex_types_1.UniswapV3StyleDexEnum.PANCAKESWAP_V3,
|
|
189
|
-
quoter: '0xB048Bbc1Ee6b733FFfCFb9e9CeF7375518e25997',
|
|
190
|
-
deployer: '0x41ff9AA7e16B8B1a8a8dc4f0eFacd93D02d071c9',
|
|
191
|
-
router: '0x1b81D678ffb9C0263b24A97847620C99d213eB14',
|
|
192
|
-
factory: '0x0BFbCF9fa4f9C56B0F40a671Ad40E0805A091865',
|
|
193
|
-
initHash: '0x6ce8eb472fa82df5469c6ab6d485f17c3ad13c8cd7af59b3d4a8026c5ce0f7e2',
|
|
194
|
-
},
|
|
195
|
-
// {
|
|
196
|
-
// dex: UniswapV3StyleDexEnum.SUSHISWAP_V3,
|
|
197
|
-
// router: '0x81602ef321c46d73f5ba7f476947ae1a862957dc', // RouteProcessor9
|
|
198
|
-
// factory: '0x126555dd55a39328f69400d6ae4f782bd4c34abb',
|
|
199
|
-
// },
|
|
200
|
-
],
|
|
201
|
-
[enums_1.ChainIdEnum.BASE]: [
|
|
202
|
-
{
|
|
203
|
-
dex: v3_dex_types_1.UniswapV3StyleDexEnum.UNISWAP_V3,
|
|
204
|
-
quoter: '0x3d4e44Eb1374240CE5F1B871ab261CD16335B76a',
|
|
205
|
-
router: '0x2626664c2603336E57B271c5C0b26F421741e481',
|
|
206
|
-
factory: '0x33128a8fC17869897dcE68Ed026d694621f6FDfD',
|
|
207
|
-
initHash: '0xe34f199b19b2b4f47f68442619d555527d244f78a3297ea89325f843f87b8b54',
|
|
208
|
-
},
|
|
209
|
-
{
|
|
210
|
-
dex: v3_dex_types_1.UniswapV3StyleDexEnum.PANCAKESWAP_V3,
|
|
211
|
-
quoter: '0xB048Bbc1Ee6b733FFfCFb9e9CeF7375518e25997',
|
|
212
|
-
deployer: '0x41ff9AA7e16B8B1a8a8dc4f0eFacd93D02d071c9',
|
|
213
|
-
router: '0x1b81D678ffb9C0263b24A97847620C99d213eB14',
|
|
214
|
-
factory: '0x0BFbCF9fa4f9C56B0F40a671Ad40E0805A091865',
|
|
215
|
-
initHash: '0x6ce8eb472fa82df5469c6ab6d485f17c3ad13c8cd7af59b3d4a8026c5ce0f7e2',
|
|
216
|
-
},
|
|
217
|
-
{
|
|
218
|
-
dex: v3_dex_types_1.UniswapV3StyleDexEnum.AERODROME_CLMM,
|
|
219
|
-
quoter: '0x254cF9E1E6e233aa1AC962CB9B05b2cfeAaE15b0',
|
|
220
|
-
router: '0xBE6D8f0d05cC4be24d5167a3eF062215bE6D18a5',
|
|
221
|
-
factory: '0x5e7BB104d84c7CB9B682AaC2F3d509f5F406809A',
|
|
222
|
-
initHash: '0xffb9af9ea6d9e39da47392ecc7055277b9915b8bfc9f83f105821b7791a6ae30',
|
|
223
|
-
},
|
|
224
|
-
// {
|
|
225
|
-
// dex: UniswapV3StyleDexEnum.SUSHISWAP_V3,
|
|
226
|
-
// router: '0x81602ef321c46d73f5ba7f476947ae1a862957dc', // RouteProcessor9
|
|
227
|
-
// factory: '0xc35dadb65012ec5796536bd9864ed8773abc74c4',
|
|
228
|
-
// },
|
|
229
|
-
],
|
|
230
|
-
[enums_1.ChainIdEnum.ETHEREUM]: [
|
|
231
|
-
{
|
|
232
|
-
dex: v3_dex_types_1.UniswapV3StyleDexEnum.UNISWAP_V3,
|
|
233
|
-
quoter: '0x61fFE014bA17989E743c5F6cB21bF9697530B21e',
|
|
234
|
-
router: '0x68b3465833fb72A70ecDF485E0e4C7bD8665Fc45',
|
|
235
|
-
factory: '0x1F98431c8aD98523631AE4a59f267346ea31F984',
|
|
236
|
-
initHash: '0xe34f199b19b2b4f47f68442619d555527d244f78a3297ea89325f843f87b8b54',
|
|
237
|
-
},
|
|
238
|
-
{
|
|
239
|
-
dex: v3_dex_types_1.UniswapV3StyleDexEnum.PANCAKESWAP_V3,
|
|
240
|
-
quoter: '0xB048Bbc1Ee6b733FFfCFb9e9CeF7375518e25997',
|
|
241
|
-
deployer: '0x41ff9AA7e16B8B1a8a8dc4f0eFacd93D02d071c9',
|
|
242
|
-
router: '0x1b81D678ffb9C0263b24A97847620C99d213eB14',
|
|
243
|
-
factory: '0x0BFbCF9fa4f9C56B0F40a671Ad40E0805A091865',
|
|
244
|
-
initHash: '0x6ce8eb472fa82df5469c6ab6d485f17c3ad13c8cd7af59b3d4a8026c5ce0f7e2',
|
|
245
|
-
},
|
|
246
|
-
// {
|
|
247
|
-
// dex: UniswapV3StyleDexEnum.SUSHISWAP_V3,
|
|
248
|
-
// router: '0x81602ef321c46d73f5ba7f476947ae1a862957dc', // RouteProcessor9
|
|
249
|
-
// factory: '0xbaceb8ec6b9355dfc0269c18bac9d6e2bdc29c4f',
|
|
250
|
-
// },
|
|
251
|
-
],
|
|
252
|
-
[enums_1.ChainIdEnum.OPTIMISM]: [
|
|
253
|
-
{
|
|
254
|
-
dex: v3_dex_types_1.UniswapV3StyleDexEnum.UNISWAP_V3,
|
|
255
|
-
quoter: '0x61fFE014bA17989E743c5F6cB21bF9697530B21e',
|
|
256
|
-
router: '0x68b3465833fb72A70ecDF485E0e4C7bD8665Fc45',
|
|
257
|
-
factory: '0x1F98431c8aD98523631AE4a59f267346ea31F984',
|
|
258
|
-
initHash: '0xe34f199b19b2b4f47f68442619d555527d244f78a3297ea89325f843f87b8b54',
|
|
259
|
-
},
|
|
260
|
-
{
|
|
261
|
-
dex: v3_dex_types_1.UniswapV3StyleDexEnum.VELODROME_CLMM,
|
|
262
|
-
quoter: '0x89D8218ed5fF1e46d8dcd33fb0bbeE3be1621466',
|
|
263
|
-
router: '0x0792a633F0c19c351081CF4B211F68F79bCc9676',
|
|
264
|
-
factory: '0xCc0bDDB707055e04e497aB22a59c2aF4391cd12F',
|
|
265
|
-
initHash: '0x339492e30b7a68609e535da9b0773082bfe60230ca47639ee5566007d525f5a7',
|
|
266
|
-
},
|
|
267
|
-
// {
|
|
268
|
-
// dex: UniswapV3StyleDexEnum.SUSHISWAP_V3,
|
|
269
|
-
// router: '0x81602ef321c46d73f5ba7f476947ae1a862957dc', // RouteProcessor9
|
|
270
|
-
// factory: '0x9c6522117e2ed1fe5bdb72bb0ed5e3f2bde7dbe0',
|
|
271
|
-
// },
|
|
272
|
-
],
|
|
273
|
-
[enums_1.ChainIdEnum.POLYGON]: [
|
|
274
|
-
{
|
|
275
|
-
dex: v3_dex_types_1.UniswapV3StyleDexEnum.UNISWAP_V3,
|
|
276
|
-
quoter: '0x61fFE014bA17989E743c5F6cB21bF9697530B21e',
|
|
277
|
-
router: '0x68b3465833fb72A70ecDF485E0e4C7bD8665Fc45',
|
|
278
|
-
factory: '0x1F98431c8aD98523631AE4a59f267346ea31F984',
|
|
279
|
-
initHash: '0xe34f199b19b2b4f47f68442619d555527d244f78a3297ea89325f843f87b8b54',
|
|
280
|
-
},
|
|
281
|
-
// {
|
|
282
|
-
// dex: UniswapV3StyleDexEnum.SUSHISWAP_V3,
|
|
283
|
-
// router: '0x81602ef321c46d73f5ba7f476947ae1a862957dc', // RouteProcessor9
|
|
284
|
-
// factory: '0x917933899c6a5f8e37f31e19f92cdbff7e8ff0e2',
|
|
285
|
-
// },
|
|
286
|
-
],
|
|
287
|
-
[enums_1.ChainIdEnum.HYPEREVM]: [
|
|
288
|
-
{
|
|
289
|
-
dex: v3_dex_types_1.UniswapV3StyleDexEnum.HYPERSWAP_V3,
|
|
290
|
-
quoter: '0x03A918028f22D9E1473B7959C927AD7425A45C7C',
|
|
291
|
-
router: '0x6D99e7f6747AF2cDbB5164b6DD50e40D4fDe1e77',
|
|
292
|
-
factory: '0xB1c0fa0B789320044A6F623cFe5eBda9562602E3',
|
|
293
|
-
initHash: '0xe3572921be1688dba92df30c6781b8770499ff274d20ae9b325f4242634774fb',
|
|
294
|
-
},
|
|
295
|
-
],
|
|
296
|
-
};
|
|
297
|
-
if (config?.rpcs) {
|
|
298
|
-
for (const [chainIdStr, rpc] of Object.entries(config.rpcs)) {
|
|
299
|
-
const chainId = Number(chainIdStr);
|
|
300
|
-
if (!rpc || rpc === '') {
|
|
301
|
-
logger_1.logger.warn(`Skipping empty RPC for chainId ${chainId}`);
|
|
302
|
-
continue;
|
|
303
|
-
}
|
|
304
|
-
const expectedConfig = config.uniV3ChainConfigs[chainId];
|
|
305
|
-
if (!expectedConfig) {
|
|
306
|
-
logger_1.logger.warn(`No RPC URL found for chainId ${chainId}, skipping client creation`);
|
|
307
|
-
continue;
|
|
308
|
-
}
|
|
309
|
-
const chainConfig = config.uniV3ChainConfigs[chainId];
|
|
310
|
-
this._clients[chainId] = (0, viem_1.createPublicClient)({
|
|
311
|
-
chain: chainConfig,
|
|
312
|
-
transport: (0, viem_1.http)(rpc),
|
|
313
|
-
});
|
|
314
|
-
}
|
|
315
|
-
}
|
|
316
|
-
if (config?.uniV3ExtraDeployments) {
|
|
317
|
-
for (const [k, extras] of Object.entries(config.uniV3ExtraDeployments)) {
|
|
318
|
-
const chain = Number(k);
|
|
319
|
-
const base = this.deployments[chain] ?? [];
|
|
320
|
-
this.deployments[chain] = [...base, ...(extras ?? [])];
|
|
30
|
+
this._deployments = v3_dex_deployments_1.uniV3DexDeployments;
|
|
31
|
+
this._adapterCache = new Map();
|
|
32
|
+
if (!config) {
|
|
33
|
+
throw new Error('V3StyleDexService requires configuration');
|
|
34
|
+
}
|
|
35
|
+
if (config?.debug) {
|
|
36
|
+
logger_1.LoggerFactory.configure(logger_1.LoggerFactory.createConsoleLogger({ level: logger_1.LogLevelEnum.DEBUG }));
|
|
37
|
+
}
|
|
38
|
+
// Use custom logger if provided
|
|
39
|
+
else if (config?.logger) {
|
|
40
|
+
logger_1.LoggerFactory.configure(config.logger);
|
|
41
|
+
}
|
|
42
|
+
logger = logger_1.LoggerFactory.getLogger();
|
|
43
|
+
// Create clients where both chainConfig & rpc are provided
|
|
44
|
+
for (const [key, rpcUrl] of Object.entries(config.rpcs ?? {})) {
|
|
45
|
+
const chainId = Number(key);
|
|
46
|
+
const chainObj = chainId_to_chain_1.chainIdToChain[chainId];
|
|
47
|
+
if (!rpcUrl || !chainObj) {
|
|
48
|
+
logger.warn(`Skipping V3StyleDexService client creation for chainId ${chainId} - missing RPC or chain config`);
|
|
49
|
+
continue;
|
|
321
50
|
}
|
|
51
|
+
this._clients[chainId] = (0, viem_1.createPublicClient)({
|
|
52
|
+
chain: chainObj,
|
|
53
|
+
transport: (0, viem_1.http)(rpcUrl),
|
|
54
|
+
});
|
|
322
55
|
}
|
|
323
56
|
}
|
|
57
|
+
// --------------------------- Public API -----------------------------------
|
|
324
58
|
isCorrectConfig(_config) {
|
|
325
|
-
// V2StyleDexService has no required config fields, all are optional
|
|
326
59
|
return true;
|
|
327
60
|
}
|
|
61
|
+
/** -----------------------------------------------------------------------
|
|
62
|
+
* fetchPrice
|
|
63
|
+
* --------------------------------------------------------------------- */
|
|
328
64
|
async fetchPrice(params) {
|
|
329
|
-
const { networkIn, networkOut, tokenIn, tokenOut, amountIn, slippage
|
|
330
|
-
const pair = overrideParamsV3Dex?.pair;
|
|
331
|
-
const expectedAmountOutMin = overrideParamsV3Dex?.amountOutMin;
|
|
332
|
-
const dex = overrideParamsV3Dex?.dex;
|
|
65
|
+
const { networkIn, networkOut, tokenIn, tokenOut, amountIn, slippage } = params;
|
|
333
66
|
if (networkIn !== networkOut) {
|
|
334
|
-
throw (0, utils_1.sdkError)(enums_1.SdkErrorEnum.INVALID_PARAMS, 'V3StyleDexService
|
|
335
|
-
}
|
|
336
|
-
const amountInBI = BigInt(amountIn);
|
|
337
|
-
if (amountInBI <= 0n) {
|
|
338
|
-
throw (0, utils_1.sdkError)(enums_1.SdkErrorEnum.INVALID_PARAMS, 'amountIn must be greater than zero');
|
|
339
|
-
}
|
|
340
|
-
const deployments = this.deployments[networkIn] ?? [];
|
|
341
|
-
if (!deployments.length) {
|
|
342
|
-
throw (0, utils_1.sdkError)(enums_1.SdkErrorEnum.INVALID_PARAMS, `No V3-style deployments configured for network ${networkIn}`);
|
|
343
|
-
}
|
|
344
|
-
// Early exit if caller supplied a known pair & minOut (optimistic path)
|
|
345
|
-
if (pair && expectedAmountOutMin && dex) {
|
|
346
|
-
const router = deployments.find(d => d.dex === dex)?.router;
|
|
347
|
-
if (!router) {
|
|
348
|
-
throw (0, utils_1.sdkError)(enums_1.SdkErrorEnum.INVALID_PARAMS, `No router found for dex ${dex} on chainId ${networkIn}`);
|
|
349
|
-
}
|
|
350
|
-
const dexKey = (0, dex_deployment_key_1.dexDeploymentKey)({
|
|
351
|
-
dex: dex,
|
|
352
|
-
router: router,
|
|
353
|
-
network: networkIn,
|
|
354
|
-
});
|
|
355
|
-
const earlyResponse = {
|
|
356
|
-
dex: dexKey,
|
|
357
|
-
amountOut: expectedAmountOutMin,
|
|
358
|
-
quoterAddress: undefined,
|
|
359
|
-
feeTier: 3000,
|
|
360
|
-
sqrtPriceX96After: undefined,
|
|
361
|
-
initializedTicksCrossed: undefined,
|
|
362
|
-
gasEstimate: undefined,
|
|
363
|
-
method: 'ExpectedAmountOut',
|
|
364
|
-
path: pair,
|
|
365
|
-
notes: `Early return due to supplied pair and amountOutMin`,
|
|
366
|
-
};
|
|
367
|
-
return {
|
|
368
|
-
protocol: this.protocol,
|
|
369
|
-
networkIn,
|
|
370
|
-
networkOut,
|
|
371
|
-
tokenIn,
|
|
372
|
-
tokenOut,
|
|
373
|
-
amountIn,
|
|
374
|
-
amountOut: expectedAmountOutMin,
|
|
375
|
-
slippage,
|
|
376
|
-
protocolResponse: earlyResponse,
|
|
377
|
-
};
|
|
67
|
+
throw (0, utils_1.sdkError)(enums_1.SdkErrorEnum.INVALID_PARAMS, 'V3StyleDexService supports only single-chain swaps');
|
|
378
68
|
}
|
|
379
69
|
const client = this._clients[networkIn];
|
|
380
70
|
if (!client) {
|
|
381
71
|
throw (0, utils_1.sdkError)(enums_1.SdkErrorEnum.INVALID_PARAMS, `No RPC client configured for chainId ${networkIn}`);
|
|
382
72
|
}
|
|
383
|
-
|
|
73
|
+
let deployments = this._deployments[networkIn] ?? [];
|
|
74
|
+
/**
|
|
75
|
+
* If an override pair + amountOutMin + dex + feeTier is provided, use fast route
|
|
76
|
+
* logic, which does not rely on any on-chain quoting – assumes the caller has done
|
|
77
|
+
* their own due diligence to verify the pair exists and is valid.
|
|
78
|
+
*/
|
|
79
|
+
const overrides = params?.overrideParamsV3Dex;
|
|
80
|
+
const overridePairCandidate = overrides?.pairCandidate;
|
|
81
|
+
const overridePair = overridePairCandidate?.pair;
|
|
82
|
+
const overrideAmountOutMin = overridePairCandidate?.amountOutMin;
|
|
83
|
+
const overrideDex = overridePairCandidate?.dex;
|
|
84
|
+
const overrideFeeOrTick = overridePairCandidate?.feeOrTick;
|
|
85
|
+
const useFastRoute = overridePair && overrideAmountOutMin && overrideDex && overrideFeeOrTick;
|
|
86
|
+
if (useFastRoute) {
|
|
87
|
+
logger.info(`V3StyleDexService: Using fast route price fetch logic.`);
|
|
88
|
+
return this._buildFastRoutePriceResponse({
|
|
89
|
+
networkIn: networkIn,
|
|
90
|
+
networkOut: networkOut,
|
|
91
|
+
tokenIn: tokenIn,
|
|
92
|
+
tokenOut: tokenOut,
|
|
93
|
+
slippage: slippage ?? 0,
|
|
94
|
+
amountIn: amountIn,
|
|
95
|
+
overrideDex: overrideDex,
|
|
96
|
+
overrideAmountOutMin: overrideAmountOutMin,
|
|
97
|
+
overrideFeeOrTick: overrideFeeOrTick,
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
const deploymentsToExclude = overrides?.excludeDexes ?? [];
|
|
101
|
+
if (deploymentsToExclude) {
|
|
102
|
+
logger.info(`V3StyleDexService: Excluding deployments for dexes: ${deploymentsToExclude.join(', ')}`);
|
|
103
|
+
deployments = deployments.filter(d => !deploymentsToExclude?.includes(d.dex));
|
|
104
|
+
}
|
|
105
|
+
if (!deployments.length) {
|
|
106
|
+
throw (0, utils_1.sdkError)(enums_1.SdkErrorEnum.INVALID_PARAMS, `No CLMM deployments for chainId ${networkIn}`);
|
|
107
|
+
}
|
|
108
|
+
const amountInBI = BigInt(amountIn);
|
|
109
|
+
if (amountInBI <= 0n) {
|
|
110
|
+
throw (0, utils_1.sdkError)(enums_1.SdkErrorEnum.INVALID_PARAMS, 'amountIn must be greater than zero');
|
|
111
|
+
}
|
|
112
|
+
// Normalize for quoting (wrap native)
|
|
384
113
|
const nativeIn = (0, is_native_1.isNative)(tokenIn);
|
|
385
114
|
const nativeOut = (0, is_native_1.isNative)(tokenOut);
|
|
386
115
|
const wrapped = wrapped_native_1.wrappedNativeTokens[networkIn];
|
|
387
116
|
if ((nativeIn || nativeOut) && !wrapped) {
|
|
388
|
-
throw (0, utils_1.sdkError)(enums_1.SdkErrorEnum.INVALID_PARAMS, `Missing wrapped native token mapping for
|
|
117
|
+
throw (0, utils_1.sdkError)(enums_1.SdkErrorEnum.INVALID_PARAMS, `Missing wrapped native token mapping for ${networkIn}`);
|
|
389
118
|
}
|
|
390
|
-
const
|
|
391
|
-
const
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
const
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
119
|
+
const tokenInQ = (nativeIn ? wrapped : tokenIn);
|
|
120
|
+
const tokenOutQ = (nativeOut ? wrapped : tokenOut);
|
|
121
|
+
// Build all QuoterV2 calls (first pass)
|
|
122
|
+
const v2Specs = [];
|
|
123
|
+
for (const d of deployments) {
|
|
124
|
+
const adapter = this._getAdapter(d.dex);
|
|
125
|
+
const presets = adapter.presets(networkIn); // fee tiers or tick spacings
|
|
126
|
+
for (const p of presets) {
|
|
127
|
+
const poolKey = (0, to_pool_key_1.toPoolKey)(tokenInQ, tokenOutQ, p);
|
|
128
|
+
const task = {
|
|
129
|
+
deployment: d,
|
|
130
|
+
tokenIn: tokenInQ,
|
|
131
|
+
tokenOut: tokenOutQ,
|
|
132
|
+
amountIn: amountInBI,
|
|
133
|
+
poolKey,
|
|
134
|
+
nativeIn,
|
|
135
|
+
nativeOut,
|
|
136
|
+
};
|
|
137
|
+
try {
|
|
138
|
+
const spec = adapter.buildQuoterV2Call(task);
|
|
139
|
+
if (!spec)
|
|
140
|
+
continue;
|
|
141
|
+
v2Specs.push({ spec, adapter, meta: task, d, preset: p });
|
|
142
|
+
}
|
|
143
|
+
catch {
|
|
144
|
+
// Adapter may not support V2 (shouldn't happen here), skip
|
|
145
|
+
}
|
|
146
|
+
}
|
|
415
147
|
}
|
|
416
|
-
//
|
|
417
|
-
const orthodox = deployments.filter(d => !!d.quoter);
|
|
418
|
-
const quoterless = deployments.filter(d => !('quoter' in d) || !d.quoter);
|
|
148
|
+
// Execute V2 multicall
|
|
419
149
|
let best;
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
try {
|
|
427
|
-
const result = await client.readContract({
|
|
428
|
-
address: c.address,
|
|
429
|
-
abi: c.abi,
|
|
430
|
-
functionName: c.functionName,
|
|
431
|
-
args: c.args,
|
|
432
|
-
});
|
|
433
|
-
return { status: 'success', result };
|
|
434
|
-
}
|
|
435
|
-
catch (error) {
|
|
436
|
-
return { status: 'failure', error };
|
|
437
|
-
}
|
|
438
|
-
}));
|
|
439
|
-
}
|
|
440
|
-
return client.multicall({ allowFailure: true, contracts });
|
|
441
|
-
};
|
|
442
|
-
/** ---------------------------------------
|
|
443
|
-
* Round 1: QuoterV2-style calls
|
|
444
|
-
* - Uni/Pancake/Pangolin/etc: use fee (uint24)
|
|
445
|
-
* - Slipstream (Velodrome/Aerodrome): use tickSpacing (int24)
|
|
446
|
-
* ------------------------------------- */
|
|
447
|
-
// A) Uni-like group (fee tiers)
|
|
448
|
-
const v2ContractsUniLike = orthodox
|
|
449
|
-
.filter(d => !this._isSlipstreamDexString(d.dex))
|
|
450
|
-
.flatMap(d => {
|
|
451
|
-
const feeTiers = this._determineFeeTiersForDex(d.dex);
|
|
452
|
-
return feeTiers.map(fee => ({
|
|
453
|
-
address: d.quoter,
|
|
454
|
-
abi: uniswapV3_quoter_abi_1.uniswapV3QuoterAbi,
|
|
455
|
-
functionName: 'quoteExactInputSingle',
|
|
456
|
-
args: [
|
|
457
|
-
{
|
|
458
|
-
tokenIn: (0, viem_1.getAddress)(tokenInForQuote),
|
|
459
|
-
tokenOut: (0, viem_1.getAddress)(tokenOutForQuote),
|
|
460
|
-
amountIn: amountInBI,
|
|
461
|
-
fee,
|
|
462
|
-
sqrtPriceLimitX96: 0n,
|
|
463
|
-
},
|
|
464
|
-
],
|
|
465
|
-
}));
|
|
466
|
-
});
|
|
467
|
-
const v2MetasUniLike = orthodox
|
|
468
|
-
.filter(d => !this._isSlipstreamDexString(d.dex))
|
|
469
|
-
.flatMap(d => {
|
|
470
|
-
const feeTiers = this._determineFeeTiersForDex(d.dex);
|
|
471
|
-
return feeTiers.map(fee => ({
|
|
472
|
-
dex: (0, dex_deployment_key_1.dexDeploymentKey)({
|
|
473
|
-
dex: d.dex,
|
|
474
|
-
network: networkIn,
|
|
475
|
-
router: d.router,
|
|
476
|
-
}),
|
|
477
|
-
fee,
|
|
478
|
-
quoter: d.quoter,
|
|
479
|
-
method: 'QuoterV2.quoteExactInputSingle',
|
|
480
|
-
isSlip: false,
|
|
481
|
-
}));
|
|
482
|
-
});
|
|
483
|
-
// B) Slipstream group (tick spacing)
|
|
484
|
-
const v2ContractsSlip = orthodox
|
|
485
|
-
.filter(d => this._isSlipstreamDexString(d.dex))
|
|
486
|
-
.flatMap(d => {
|
|
487
|
-
const tss = this._determineTickSpacingsForDex(d.dex);
|
|
488
|
-
return tss.map(ts => ({
|
|
489
|
-
address: d.quoter,
|
|
490
|
-
abi: slipstream_quoter_abi_1.slipstreamQuoterAbi,
|
|
491
|
-
functionName: 'quoteExactInputSingle',
|
|
492
|
-
args: [
|
|
493
|
-
{
|
|
494
|
-
tokenIn: (0, viem_1.getAddress)(tokenInForQuote),
|
|
495
|
-
tokenOut: (0, viem_1.getAddress)(tokenOutForQuote),
|
|
496
|
-
amountIn: amountInBI,
|
|
497
|
-
tickSpacing: ts,
|
|
498
|
-
sqrtPriceLimitX96: 0n,
|
|
499
|
-
},
|
|
500
|
-
],
|
|
150
|
+
if (v2Specs.length) {
|
|
151
|
+
const calls = v2Specs.map(s => ({
|
|
152
|
+
address: s.spec.address,
|
|
153
|
+
abi: s.spec.abi,
|
|
154
|
+
functionName: s.spec.fn,
|
|
155
|
+
args: s.spec.args,
|
|
501
156
|
}));
|
|
502
|
-
|
|
503
|
-
const v2MetasSlip = orthodox
|
|
504
|
-
.filter(d => this._isSlipstreamDexString(d.dex))
|
|
505
|
-
.flatMap(d => this._determineTickSpacingsForDex(d.dex).map(ts => ({
|
|
506
|
-
dex: (0, dex_deployment_key_1.dexDeploymentKey)({
|
|
507
|
-
dex: d.dex,
|
|
508
|
-
network: networkIn,
|
|
509
|
-
router: d.router,
|
|
510
|
-
}),
|
|
511
|
-
fee: ts, // store tickSpacing in "fee" slot to reuse payload shape
|
|
512
|
-
quoter: d.quoter,
|
|
513
|
-
method: 'QuoterV2.quoteExactInputSingle',
|
|
514
|
-
isSlip: true,
|
|
515
|
-
})));
|
|
516
|
-
// Execute both groups
|
|
517
|
-
const [v2ResultsUniLike, v2ResultsSlip] = await Promise.all([
|
|
518
|
-
execBatch(v2ContractsUniLike),
|
|
519
|
-
execBatch(v2ContractsSlip),
|
|
520
|
-
]);
|
|
521
|
-
// Unified handling for success/revert-decode
|
|
522
|
-
const handleV2Group = (results, metas, abi) => {
|
|
157
|
+
const results = await this._execBatch(networkIn, calls);
|
|
523
158
|
for (let i = 0; i < results.length; i++) {
|
|
524
159
|
const res = results[i];
|
|
525
|
-
const
|
|
526
|
-
if (!
|
|
160
|
+
const s = v2Specs[i];
|
|
161
|
+
if (!s)
|
|
527
162
|
continue;
|
|
528
|
-
|
|
529
|
-
if (res.status === 'success' && Array.isArray(res.result)) {
|
|
530
|
-
const [amountOut, sqrtAfter, ticks, gas] = res.result;
|
|
531
|
-
const candidate = {
|
|
532
|
-
amountOut,
|
|
533
|
-
payload: {
|
|
534
|
-
dex: meta.dex,
|
|
535
|
-
quoterAddress: meta.quoter,
|
|
536
|
-
method: meta.method,
|
|
537
|
-
feeTier: meta.fee, // NOTE: tickSpacing for Slipstream
|
|
538
|
-
amountOut: amountOut.toString(),
|
|
539
|
-
gasEstimate: gas ? gas.toString() : undefined,
|
|
540
|
-
sqrtPriceX96After: sqrtAfter ? sqrtAfter.toString() : undefined,
|
|
541
|
-
initializedTicksCrossed: ticks,
|
|
542
|
-
notes: (meta.isSlip ? 'Slipstream tickSpacing; ' : '') +
|
|
543
|
-
(nativeIn || nativeOut
|
|
544
|
-
? `Quoted with wrapped native: in=${nativeIn ? 'wrapped' : 'erc20'}, out=${nativeOut ? 'wrapped' : 'erc20'}`
|
|
545
|
-
: ''),
|
|
546
|
-
},
|
|
547
|
-
};
|
|
548
|
-
if (!best || candidate.amountOut > best.amountOut)
|
|
549
|
-
best = candidate;
|
|
163
|
+
if (!res)
|
|
550
164
|
continue;
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
// @ts-ignore – Viem surfaces revert data in error.data
|
|
554
|
-
const data = res?.error?.data;
|
|
555
|
-
if (!data || data === '0x')
|
|
165
|
+
const decoded = s.adapter.decodeQuoterV2(res);
|
|
166
|
+
if (!decoded)
|
|
556
167
|
continue;
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
method:
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
gasEstimate: gas ? gas.toString() : undefined,
|
|
572
|
-
sqrtPriceX96After: sqrtAfter ? sqrtAfter.toString() : undefined,
|
|
573
|
-
initializedTicksCrossed: ticks,
|
|
574
|
-
notes: (meta.isSlip ? 'Slipstream tickSpacing; ' : '') +
|
|
575
|
-
(nativeIn || nativeOut
|
|
576
|
-
? `Quoted with wrapped native: in=${nativeIn ? 'wrapped' : 'erc20'}, out=${nativeOut ? 'wrapped' : 'erc20'}`
|
|
577
|
-
: ''),
|
|
578
|
-
},
|
|
579
|
-
};
|
|
580
|
-
if (!best || candidate.amountOut > (best.amountOut ?? 0n))
|
|
581
|
-
best = candidate;
|
|
582
|
-
}
|
|
583
|
-
catch {
|
|
584
|
-
/* ignore; continue */
|
|
168
|
+
if (decoded.amountOut > 0n) {
|
|
169
|
+
if (!best || decoded.amountOut > best.amountOut) {
|
|
170
|
+
best = {
|
|
171
|
+
adapter: s.adapter,
|
|
172
|
+
d: s.d,
|
|
173
|
+
p: s.preset,
|
|
174
|
+
amountOut: decoded.amountOut,
|
|
175
|
+
sqrt: decoded.sqrt,
|
|
176
|
+
ticks: decoded.ticks,
|
|
177
|
+
gas: decoded.gas,
|
|
178
|
+
meta: s.meta,
|
|
179
|
+
method: 'QuoterV2.quoteExactInputSingle',
|
|
180
|
+
};
|
|
181
|
+
}
|
|
585
182
|
}
|
|
586
183
|
}
|
|
587
|
-
}
|
|
588
|
-
|
|
589
|
-
handleV2Group(v2ResultsSlip, v2MetasSlip, slipstream_quoter_abi_1.slipstreamQuoterAbi);
|
|
590
|
-
/** ---------------------------------------
|
|
591
|
-
* Round 2: Legacy Quoter (tuple) fallback
|
|
592
|
-
* - Only for Uni-like deployments (Slipstream has no v1 tuple form)
|
|
593
|
-
* ------------------------------------- */
|
|
184
|
+
}
|
|
185
|
+
// If no V2 winner, try V1 where supported (Uniswap/V3Fork; NOT Slipstream)
|
|
594
186
|
if (!best) {
|
|
595
|
-
const
|
|
596
|
-
const
|
|
597
|
-
const
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
args: [
|
|
603
|
-
{
|
|
604
|
-
tokenIn: (0, viem_1.getAddress)(tokenInForQuote),
|
|
605
|
-
tokenOut: (0, viem_1.getAddress)(tokenOutForQuote),
|
|
606
|
-
fee,
|
|
607
|
-
amountIn: amountInBI,
|
|
608
|
-
sqrtPriceLimitX96: 0n,
|
|
609
|
-
},
|
|
610
|
-
],
|
|
611
|
-
}));
|
|
612
|
-
});
|
|
613
|
-
const v1Metas = orthodoxUniLike.flatMap(d => this._determineFeeTiersForDex(d.dex).map(fee => ({
|
|
614
|
-
dex: (0, dex_deployment_key_1.dexDeploymentKey)({
|
|
615
|
-
dex: d.dex,
|
|
616
|
-
network: networkIn,
|
|
617
|
-
router: d.router,
|
|
618
|
-
}),
|
|
619
|
-
fee,
|
|
620
|
-
quoter: d.quoter,
|
|
621
|
-
method: 'Quoter.quoteExactInputSingle',
|
|
622
|
-
})));
|
|
623
|
-
const v1Results = v1Contracts.length
|
|
624
|
-
? await client.multicall({
|
|
625
|
-
allowFailure: true,
|
|
626
|
-
contracts: v1Contracts,
|
|
627
|
-
...(networkIn === enums_1.ChainIdEnum.HYPEREVM && {
|
|
628
|
-
multicallAddress: '0xcA11bde05977b3631167028862bE2a173976CA11',
|
|
629
|
-
}),
|
|
630
|
-
})
|
|
631
|
-
: [];
|
|
632
|
-
for (let i = 0; i < v1Results.length; i++) {
|
|
633
|
-
const res = v1Results[i];
|
|
634
|
-
const meta = v1Metas[i];
|
|
635
|
-
if (!meta || !res)
|
|
636
|
-
continue;
|
|
637
|
-
if (res.status === 'success') {
|
|
638
|
-
const [amountOut] = res.result;
|
|
639
|
-
const candidate = {
|
|
640
|
-
amountOut,
|
|
641
|
-
payload: {
|
|
642
|
-
dex: meta.dex,
|
|
643
|
-
quoterAddress: meta.quoter,
|
|
644
|
-
method: meta.method,
|
|
645
|
-
feeTier: meta.fee,
|
|
646
|
-
amountOut: amountOut.toString(),
|
|
647
|
-
notes: nativeIn || nativeOut
|
|
648
|
-
? `Quoted with wrapped native: in=${nativeIn ? 'wrapped' : 'erc20'}, out=${nativeOut ? 'wrapped' : 'erc20'}`
|
|
649
|
-
: undefined,
|
|
650
|
-
},
|
|
651
|
-
};
|
|
652
|
-
if (!best || candidate.amountOut > best.amountOut)
|
|
653
|
-
best = candidate;
|
|
187
|
+
const v1Specs = [];
|
|
188
|
+
for (const d of deployments) {
|
|
189
|
+
const adapter = this._getAdapter(d.dex);
|
|
190
|
+
// Slipstream throws on V1 – guard out by capability or key
|
|
191
|
+
const skipV1 = adapter.caps?.usesTickSpacing ||
|
|
192
|
+
adapter.family === v3_dex_types_1.UniswapV3StyleDexFamilyEnum.SLIPSTREAM;
|
|
193
|
+
if (skipV1)
|
|
654
194
|
continue;
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
});
|
|
667
|
-
const candidate = {
|
|
668
|
-
amountOut,
|
|
669
|
-
payload: {
|
|
670
|
-
dex: meta.dex,
|
|
671
|
-
quoterAddress: meta.quoter,
|
|
672
|
-
method: meta.method,
|
|
673
|
-
feeTier: meta.fee,
|
|
674
|
-
amountOut: amountOut.toString(),
|
|
675
|
-
notes: nativeIn || nativeOut
|
|
676
|
-
? `Quoted with wrapped native: in=${nativeIn ? 'wrapped' : 'erc20'}, out=${nativeOut ? 'wrapped' : 'erc20'}`
|
|
677
|
-
: undefined,
|
|
678
|
-
},
|
|
195
|
+
const presets = adapter.presets(networkIn);
|
|
196
|
+
for (const p of presets) {
|
|
197
|
+
const poolKey = (0, to_pool_key_1.toPoolKey)(tokenInQ, tokenOutQ, p);
|
|
198
|
+
const task = {
|
|
199
|
+
deployment: d,
|
|
200
|
+
tokenIn: tokenInQ,
|
|
201
|
+
tokenOut: tokenOutQ,
|
|
202
|
+
amountIn: amountInBI,
|
|
203
|
+
poolKey,
|
|
204
|
+
nativeIn,
|
|
205
|
+
nativeOut,
|
|
679
206
|
};
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
207
|
+
try {
|
|
208
|
+
const spec = adapter.buildQuoterV1Call(task);
|
|
209
|
+
if (!spec)
|
|
210
|
+
continue;
|
|
211
|
+
v1Specs.push({ spec, adapter, meta: task, d, preset: p });
|
|
212
|
+
}
|
|
213
|
+
catch {
|
|
214
|
+
/* unsupported; skip */
|
|
215
|
+
}
|
|
685
216
|
}
|
|
686
217
|
}
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
const
|
|
695
|
-
for (
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
amountOut: res.best.amountOut,
|
|
715
|
-
payload: {
|
|
716
|
-
dex: dexKey,
|
|
717
|
-
quoterAddress: undefined,
|
|
718
|
-
method: 'OffchainQuoter.simulateExactInputSingle',
|
|
719
|
-
feeTier: res.best.fee,
|
|
720
|
-
amountOut: res.best.amountOut.toString(),
|
|
721
|
-
sqrtPriceX96After: res.best.sqrtPriceX96After
|
|
722
|
-
? res.best.sqrtPriceX96After.toString()
|
|
723
|
-
: undefined,
|
|
724
|
-
initializedTicksCrossed: res.best.initializedTicksCrossed,
|
|
725
|
-
notes: (nativeIn || nativeOut
|
|
726
|
-
? `Quoted with wrapped native: in=${nativeIn ? 'wrapped' : 'erc20'}, out=${nativeOut ? 'wrapped' : 'erc20'}; `
|
|
727
|
-
: '') + `Factory=${(0, viem_1.getAddress)(d.factory)}`,
|
|
728
|
-
},
|
|
218
|
+
if (v1Specs.length) {
|
|
219
|
+
const calls = v1Specs.map(s => ({
|
|
220
|
+
address: s.spec.address,
|
|
221
|
+
abi: s.spec.abi,
|
|
222
|
+
functionName: s.spec.fn,
|
|
223
|
+
args: s.spec.args,
|
|
224
|
+
}));
|
|
225
|
+
const results = await this._execBatch(networkIn, calls);
|
|
226
|
+
for (let i = 0; i < results.length; i++) {
|
|
227
|
+
const res = results[i];
|
|
228
|
+
const s = v1Specs[i];
|
|
229
|
+
if (!s)
|
|
230
|
+
continue;
|
|
231
|
+
if (!res)
|
|
232
|
+
continue;
|
|
233
|
+
const decoded = s.adapter.decodeQuoterV1(res);
|
|
234
|
+
if (!decoded)
|
|
235
|
+
continue;
|
|
236
|
+
if (decoded.amountOut > 0n) {
|
|
237
|
+
if (!best || decoded.amountOut > best.amountOut) {
|
|
238
|
+
best = {
|
|
239
|
+
adapter: s.adapter,
|
|
240
|
+
d: s.d,
|
|
241
|
+
p: s.preset,
|
|
242
|
+
amountOut: decoded.amountOut,
|
|
243
|
+
meta: s.meta,
|
|
244
|
+
method: 'Quoter.quoteExactInputSingle',
|
|
729
245
|
};
|
|
730
|
-
if (!best || candidate.amountOut > best.amountOut)
|
|
731
|
-
best = candidate;
|
|
732
246
|
}
|
|
733
247
|
}
|
|
734
|
-
catch {
|
|
735
|
-
// ignore this deployment; continue to next
|
|
736
|
-
}
|
|
737
248
|
}
|
|
738
249
|
}
|
|
739
250
|
}
|
|
740
251
|
if (!best) {
|
|
741
|
-
throw (0, utils_1.sdkError)(enums_1.SdkErrorEnum.QUOTE_NOT_FOUND,
|
|
742
|
-
}
|
|
743
|
-
|
|
252
|
+
throw (0, utils_1.sdkError)(enums_1.SdkErrorEnum.QUOTE_NOT_FOUND, 'No CLMM quote could be found');
|
|
253
|
+
}
|
|
254
|
+
const payload = {
|
|
255
|
+
dex: best.d.dex,
|
|
256
|
+
router: best.d.router,
|
|
257
|
+
quoter: best.d.quoter,
|
|
258
|
+
method: best.method,
|
|
259
|
+
feeOrTick: best.p,
|
|
260
|
+
amountOut: best.amountOut.toString(),
|
|
261
|
+
sqrtPriceX96After: best.sqrt ? best.sqrt.toString() : undefined,
|
|
262
|
+
initializedTicksCrossed: best?.ticks,
|
|
263
|
+
gasEstimate: best.gas ? best.gas.toString() : undefined,
|
|
264
|
+
notes: (nativeIn || nativeOut
|
|
265
|
+
? `Quoted with wrapped native (in=${nativeIn ? 'wrapped' : 'erc20'}, out=${nativeOut ? 'wrapped' : 'erc20'}). `
|
|
266
|
+
: '') + `Adapter=${best.adapter.constructor.name}`,
|
|
267
|
+
};
|
|
268
|
+
const priceResponse = {
|
|
744
269
|
protocol: this.protocol,
|
|
745
270
|
networkIn,
|
|
746
271
|
networkOut,
|
|
@@ -749,728 +274,222 @@ class V3StyleDexService {
|
|
|
749
274
|
amountIn,
|
|
750
275
|
amountOut: best.amountOut.toString(),
|
|
751
276
|
slippage,
|
|
752
|
-
protocolResponse:
|
|
277
|
+
protocolResponse: payload,
|
|
753
278
|
};
|
|
279
|
+
logger.info(`V3StyleDexService: Fetched price: ${amountIn} ${tokenIn} -> ${priceResponse.amountOut} ${tokenOut} on ${networkIn} via ${best.d.dex}`);
|
|
280
|
+
return priceResponse;
|
|
754
281
|
}
|
|
282
|
+
/** -----------------------------------------------------------------------
|
|
283
|
+
* fetchQuote
|
|
284
|
+
* --------------------------------------------------------------------- */
|
|
755
285
|
async fetchQuote(params) {
|
|
756
|
-
const { networkIn, networkOut, tokenIn, tokenOut, amountIn, slippage, from, receiver,
|
|
757
|
-
if (overrideParamsV3Dex &&
|
|
758
|
-
overrideParamsV3Dex.nativePrice &&
|
|
759
|
-
overrideParamsV3Dex.tokenInPrice &&
|
|
760
|
-
overrideParamsV3Dex.tokenInDecimals) {
|
|
761
|
-
await this._validateNativeLiquidity({
|
|
762
|
-
tokenIn,
|
|
763
|
-
networkIn: enums_1.ChainIdEnum.UNKNOWN,
|
|
764
|
-
dexes: this.deployments[networkIn]?.map(d => d.dex) ?? [],
|
|
765
|
-
nativePrice: overrideParamsV3Dex.nativePrice,
|
|
766
|
-
tokenInPrice: overrideParamsV3Dex.tokenInPrice,
|
|
767
|
-
tokenInDecimals: overrideParamsV3Dex.tokenInDecimals,
|
|
768
|
-
});
|
|
769
|
-
}
|
|
286
|
+
const { networkIn, networkOut, tokenIn, tokenOut, amountIn, slippage, from, receiver, priceResponse, } = params;
|
|
770
287
|
if (networkIn !== networkOut) {
|
|
771
|
-
throw (0, utils_1.sdkError)(enums_1.SdkErrorEnum.INVALID_PARAMS, 'V3StyleDexService
|
|
288
|
+
throw (0, utils_1.sdkError)(enums_1.SdkErrorEnum.INVALID_PARAMS, 'V3StyleDexService supports only single-chain swaps');
|
|
772
289
|
}
|
|
773
|
-
const
|
|
774
|
-
if (
|
|
775
|
-
throw (0, utils_1.sdkError)(enums_1.SdkErrorEnum.INVALID_PARAMS,
|
|
776
|
-
}
|
|
777
|
-
// Native normalization for execution paths
|
|
778
|
-
const expectNativeIn = (0, is_native_1.isNative)(tokenIn);
|
|
779
|
-
const expectNativeOut = (0, is_native_1.isNative)(tokenOut);
|
|
780
|
-
const wrapped = wrapped_native_1.wrappedNativeTokens[networkIn];
|
|
781
|
-
if ((expectNativeIn || expectNativeOut) && !wrapped) {
|
|
782
|
-
throw (0, utils_1.sdkError)(enums_1.SdkErrorEnum.INVALID_PARAMS, `Missing wrapped native token mapping for chainId ${networkIn}`);
|
|
290
|
+
const client = this._clients[networkIn];
|
|
291
|
+
if (!client) {
|
|
292
|
+
throw (0, utils_1.sdkError)(enums_1.SdkErrorEnum.INVALID_PARAMS, `No RPC client configured for chainId ${networkIn}`);
|
|
783
293
|
}
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
if (!params?.priceResponse) {
|
|
789
|
-
let priceRes;
|
|
790
|
-
try {
|
|
791
|
-
priceRes = await this.fetchPrice({
|
|
792
|
-
networkIn,
|
|
793
|
-
networkOut,
|
|
794
|
-
tokenIn,
|
|
795
|
-
tokenOut,
|
|
796
|
-
amountIn,
|
|
797
|
-
from,
|
|
798
|
-
slippage,
|
|
799
|
-
overrideParamsV3Dex,
|
|
800
|
-
});
|
|
801
|
-
}
|
|
802
|
-
catch (e) {
|
|
803
|
-
const errorMessage = e.message ?? e;
|
|
804
|
-
throw (0, utils_1.sdkError)(enums_1.SdkErrorEnum.QUOTE_NOT_FOUND, errorMessage);
|
|
805
|
-
}
|
|
806
|
-
v3Price = priceRes.protocolResponse;
|
|
294
|
+
let price = undefined;
|
|
295
|
+
if (priceResponse) {
|
|
296
|
+
logger.info(`V3StyleDexService: Using provided price response for quote fetch.`);
|
|
297
|
+
price = priceResponse;
|
|
807
298
|
}
|
|
808
299
|
else {
|
|
809
|
-
|
|
300
|
+
logger.info(`V3StyleDexService: Fetching price for quote.`);
|
|
301
|
+
price = await this.fetchPrice(params);
|
|
302
|
+
}
|
|
303
|
+
const overrides = params?.overrideParamsV3Dex;
|
|
304
|
+
const overridePairCandidate = overrides?.pairCandidate;
|
|
305
|
+
const overrideSqrtPriceX96After = overridePairCandidate?.sqrtPriceX96After;
|
|
306
|
+
const sqrtPriceX96After = overrideSqrtPriceX96After
|
|
307
|
+
? overrideSqrtPriceX96After
|
|
308
|
+
: price.protocolResponse && 'sqrtPriceX96After' in price.protocolResponse
|
|
309
|
+
? price.protocolResponse.sqrtPriceX96After
|
|
310
|
+
: undefined;
|
|
311
|
+
const pp = price.protocolResponse;
|
|
312
|
+
const deployments = this._deployments[networkIn] ?? [];
|
|
313
|
+
const deployment = deployments.find(d => d.dex === pp.dex && d.router.toLowerCase() === pp.router.toLowerCase()) ?? deployments.find(d => d.dex === pp.dex);
|
|
314
|
+
if (!deployment) {
|
|
315
|
+
throw (0, utils_1.sdkError)(enums_1.SdkErrorEnum.INVALID_PARAMS, `No deployment found for ${pp.dex} on ${networkIn}`);
|
|
810
316
|
}
|
|
811
|
-
|
|
812
|
-
|
|
317
|
+
const adapter = this._getAdapter(deployment.dex);
|
|
318
|
+
logger.info(`V3StyleDexService: Building quote for ${amountIn} ${tokenIn} -> ${price.amountOut} ${tokenOut} on ${networkIn} via ${deployment.dex}`);
|
|
319
|
+
// Native flags & recipient
|
|
320
|
+
const nativeIn = (0, is_native_1.isNative)(tokenIn);
|
|
321
|
+
const nativeOut = (0, is_native_1.isNative)(tokenOut);
|
|
322
|
+
const wrapped = wrapped_native_1.wrappedNativeTokens[networkIn];
|
|
323
|
+
if ((nativeIn || nativeOut) && !wrapped) {
|
|
324
|
+
throw (0, utils_1.sdkError)(enums_1.SdkErrorEnum.INVALID_PARAMS, `Missing wrapped native token mapping for ${networkIn}`);
|
|
813
325
|
}
|
|
814
|
-
|
|
815
|
-
const bestAmountOut = BigInt(v3Price.amountOut);
|
|
326
|
+
const recipient = (receiver || from);
|
|
816
327
|
const slippagePct = typeof slippage === 'number' ? slippage : Number(slippage || 0);
|
|
817
|
-
|
|
818
|
-
|
|
328
|
+
// Build the "pick" for the adapter
|
|
329
|
+
const poolKey = (0, to_pool_key_1.toPoolKey)(nativeIn ? wrapped : tokenIn, nativeOut ? wrapped : tokenOut, pp.feeOrTick);
|
|
330
|
+
const task = {
|
|
331
|
+
deployment,
|
|
332
|
+
tokenIn: poolKey.tokenA === tokenIn
|
|
333
|
+
? tokenIn
|
|
334
|
+
: nativeIn
|
|
335
|
+
? wrapped
|
|
336
|
+
: tokenIn,
|
|
337
|
+
tokenOut: poolKey.tokenB === tokenOut
|
|
338
|
+
? tokenOut
|
|
339
|
+
: nativeOut
|
|
340
|
+
? wrapped
|
|
341
|
+
: tokenOut,
|
|
342
|
+
amountIn: BigInt(amountIn),
|
|
343
|
+
poolKey,
|
|
344
|
+
nativeIn,
|
|
345
|
+
nativeOut,
|
|
346
|
+
};
|
|
347
|
+
const pick = {
|
|
348
|
+
task,
|
|
349
|
+
amountOut: BigInt(price.amountOut),
|
|
350
|
+
decoded: { feeOrTick: pp.feeOrTick, quoter: pp.quoter, method: pp.method },
|
|
351
|
+
};
|
|
352
|
+
// Adapter calldata
|
|
353
|
+
const calldataInput = {
|
|
354
|
+
pick,
|
|
819
355
|
slippage: slippagePct,
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
}
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
throw (0, utils_1.sdkError)(enums_1.SdkErrorEnum.INVALID_PARAMS, `No router found for selected deployment on network ${networkIn}`);
|
|
838
|
-
}
|
|
839
|
-
const deadline = BigInt(Math.floor(Date.now() / 1000) + 30 * 60); // 30 minutes
|
|
840
|
-
const recipientForFirstLeg = expectNativeOut
|
|
841
|
-
? (0, viem_1.getAddress)(chosenRouter)
|
|
842
|
-
: (0, viem_1.getAddress)(receiver || from);
|
|
843
|
-
const isSushiV3 = this._isDex(v3_dex_types_1.UniswapV3StyleDexEnum.SUSHISWAP_V3, v3Price);
|
|
844
|
-
const isPancakeV3 = this._isDex(v3_dex_types_1.UniswapV3StyleDexEnum.PANCAKESWAP_V3, v3Price);
|
|
845
|
-
const isPangolinV3 = this._isDex(v3_dex_types_1.UniswapV3StyleDexEnum.PANGOLIN_V3, v3Price);
|
|
846
|
-
const isPharaoh = this._isDex(v3_dex_types_1.UniswapV3StyleDexEnum.PHARAOH_CLMM, v3Price);
|
|
847
|
-
const isSlipstream = this._isDex(v3_dex_types_1.UniswapV3StyleDexEnum.VELODROME_CLMM, v3Price) ||
|
|
848
|
-
this._isDex(v3_dex_types_1.UniswapV3StyleDexEnum.AERODROME_CLMM, v3Price);
|
|
849
|
-
let data;
|
|
850
|
-
let methodForResponse;
|
|
851
|
-
let txValue = expectNativeIn ? amountInBI.toString() : '0';
|
|
852
|
-
if (isSushiV3) {
|
|
853
|
-
/**
|
|
854
|
-
* -------------------------
|
|
855
|
-
* Sushi Route Processor 9
|
|
856
|
-
* -------------------------
|
|
857
|
-
* Uses route bytes (off-chain). We set a sentinel here.
|
|
858
|
-
*/
|
|
859
|
-
const routeBytes = '0x';
|
|
860
|
-
const takeSurplus = false;
|
|
861
|
-
const referralCode = 0;
|
|
862
|
-
if (expectNativeIn) {
|
|
863
|
-
data = (0, viem_1.encodeFunctionData)({
|
|
864
|
-
abi: sushiswap_route_processor_9_abi_1.sushiswapRouteProcessor9Abi,
|
|
865
|
-
functionName: 'processRouteWithTransferValueInput',
|
|
866
|
-
args: [
|
|
867
|
-
(0, viem_1.getAddress)(chosenRouter), // transferValueTo (RP9)
|
|
868
|
-
amountInBI, // amountValueTransfer
|
|
869
|
-
(0, viem_1.getAddress)(tokenInExec),
|
|
870
|
-
amountInBI,
|
|
871
|
-
(0, viem_1.getAddress)(tokenOutExec),
|
|
872
|
-
amountOutMin,
|
|
873
|
-
(0, viem_1.getAddress)(receiver || from),
|
|
874
|
-
routeBytes,
|
|
875
|
-
takeSurplus,
|
|
876
|
-
referralCode,
|
|
877
|
-
],
|
|
878
|
-
});
|
|
879
|
-
methodForResponse = 'RouteProcessor9.processRouteWithTransferValueInput';
|
|
880
|
-
// txValue already equals amountIn for native-in
|
|
881
|
-
}
|
|
882
|
-
else {
|
|
883
|
-
data = (0, viem_1.encodeFunctionData)({
|
|
884
|
-
abi: sushiswap_route_processor_9_abi_1.sushiswapRouteProcessor9Abi,
|
|
885
|
-
functionName: 'processRoute',
|
|
886
|
-
args: [
|
|
887
|
-
(0, viem_1.getAddress)(tokenInExec),
|
|
888
|
-
amountInBI,
|
|
889
|
-
(0, viem_1.getAddress)(tokenOutExec),
|
|
890
|
-
amountOutMin,
|
|
891
|
-
(0, viem_1.getAddress)(receiver || from),
|
|
892
|
-
routeBytes,
|
|
893
|
-
takeSurplus,
|
|
894
|
-
referralCode,
|
|
895
|
-
],
|
|
896
|
-
});
|
|
897
|
-
methodForResponse = 'RouteProcessor9.processRoute';
|
|
898
|
-
txValue = '0';
|
|
899
|
-
}
|
|
900
|
-
}
|
|
901
|
-
else {
|
|
902
|
-
// Choose router ABI (Slipstream vs Uni-like)
|
|
903
|
-
const routerAbi = isSlipstream
|
|
904
|
-
? slipstream_router_abi_1.slipstreamRouterAbi
|
|
905
|
-
: isPancakeV3 || isPangolinV3 || isPharaoh
|
|
906
|
-
? pacakeswapV3_router_abi_1.pancakeswapV3RouterAbi
|
|
907
|
-
: uniswapV3_router_abi_1.uniswapV3RouterAbi;
|
|
908
|
-
// Build exactInputSingle calldata
|
|
909
|
-
let exactInputSingleCalldata;
|
|
910
|
-
if (isSlipstream) {
|
|
911
|
-
// Slipstream uses tickSpacing (int24) and includes deadline in the struct
|
|
912
|
-
const struct = {
|
|
913
|
-
tokenIn: (0, viem_1.getAddress)(tokenInExec),
|
|
914
|
-
tokenOut: (0, viem_1.getAddress)(tokenOutExec),
|
|
915
|
-
tickSpacing: Number(v3Price.feeTier ?? 60), // feeTier carries tickSpacing for Slipstream
|
|
916
|
-
recipient: recipientForFirstLeg,
|
|
917
|
-
deadline,
|
|
918
|
-
amountIn: amountInBI,
|
|
919
|
-
amountOutMinimum: amountOutMin,
|
|
920
|
-
sqrtPriceLimitX96: 0n,
|
|
921
|
-
};
|
|
922
|
-
exactInputSingleCalldata = (0, viem_1.encodeFunctionData)({
|
|
923
|
-
abi: routerAbi,
|
|
924
|
-
functionName: 'exactInputSingle',
|
|
925
|
-
args: [struct],
|
|
926
|
-
});
|
|
927
|
-
}
|
|
928
|
-
else {
|
|
929
|
-
// Uni/Pancake/Pangolin use fee (uint24)
|
|
930
|
-
const struct = isPancakeV3 || isPangolinV3 || isPharaoh
|
|
931
|
-
? {
|
|
932
|
-
tokenIn: (0, viem_1.getAddress)(tokenInExec),
|
|
933
|
-
tokenOut: (0, viem_1.getAddress)(tokenOutExec),
|
|
934
|
-
fee: (v3Price.feeTier ?? 3000),
|
|
935
|
-
recipient: recipientForFirstLeg,
|
|
936
|
-
deadline,
|
|
937
|
-
amountIn: amountInBI,
|
|
938
|
-
amountOutMinimum: amountOutMin,
|
|
939
|
-
sqrtPriceLimitX96: 0n,
|
|
940
|
-
}
|
|
941
|
-
: {
|
|
942
|
-
tokenIn: (0, viem_1.getAddress)(tokenInExec),
|
|
943
|
-
tokenOut: (0, viem_1.getAddress)(tokenOutExec),
|
|
944
|
-
fee: (v3Price.feeTier ?? 3000),
|
|
945
|
-
recipient: recipientForFirstLeg,
|
|
946
|
-
amountIn: amountInBI,
|
|
947
|
-
amountOutMinimum: amountOutMin,
|
|
948
|
-
sqrtPriceLimitX96: 0n,
|
|
949
|
-
};
|
|
950
|
-
exactInputSingleCalldata = (0, viem_1.encodeFunctionData)({
|
|
951
|
-
abi: routerAbi,
|
|
952
|
-
functionName: 'exactInputSingle',
|
|
953
|
-
args: [struct],
|
|
954
|
-
});
|
|
955
|
-
}
|
|
956
|
-
if (expectNativeOut) {
|
|
957
|
-
const unwrapCalldata = (0, viem_1.encodeFunctionData)({
|
|
958
|
-
abi: routerAbi,
|
|
959
|
-
functionName: 'unwrapWETH9',
|
|
960
|
-
args: [amountOutMin, (0, viem_1.getAddress)(receiver || from)],
|
|
961
|
-
});
|
|
962
|
-
data = (0, viem_1.encodeFunctionData)({
|
|
963
|
-
abi: routerAbi,
|
|
964
|
-
functionName: 'multicall',
|
|
965
|
-
args: [[exactInputSingleCalldata, unwrapCalldata]],
|
|
966
|
-
});
|
|
967
|
-
methodForResponse = 'SwapRouter.exactInputSingle';
|
|
968
|
-
}
|
|
969
|
-
else {
|
|
970
|
-
data = exactInputSingleCalldata;
|
|
971
|
-
methodForResponse = 'SwapRouter.exactInputSingle';
|
|
972
|
-
}
|
|
973
|
-
}
|
|
974
|
-
// ETH value handling:
|
|
975
|
-
const approval = expectNativeIn
|
|
976
|
-
? undefined
|
|
977
|
-
: {
|
|
978
|
-
token: (0, viem_1.getAddress)(tokenIn),
|
|
979
|
-
spender: chosenRouter,
|
|
980
|
-
amount: amountInBI.toString(),
|
|
981
|
-
};
|
|
356
|
+
recipient,
|
|
357
|
+
expectNativeIn: nativeIn,
|
|
358
|
+
expectNativeOut: nativeOut,
|
|
359
|
+
deadline: BigInt(Math.floor(Date.now() / 1000) + 1800), // +30 mins
|
|
360
|
+
sqrtPriceLimitX96: BigInt(sqrtPriceX96After || 0),
|
|
361
|
+
};
|
|
362
|
+
const cd = adapter.buildCalldata(calldataInput);
|
|
363
|
+
logger.info(`V3StyleDexService: Built calldata for quote: to=${cd.to} data=${cd.data} value=${cd.valueWei}`);
|
|
364
|
+
// Build approval if ERC-20 in
|
|
365
|
+
const approvalToken = nativeIn ? constants_1.ZERO_ADDRESS : tokenIn;
|
|
366
|
+
const approvalAmount = nativeIn ? BigInt(0) : BigInt(amountIn);
|
|
367
|
+
const approvalSpender = nativeIn ? constants_1.ZERO_ADDRESS : cd.to;
|
|
368
|
+
const approval = {
|
|
369
|
+
token: approvalToken,
|
|
370
|
+
spender: approvalSpender,
|
|
371
|
+
amount: approvalAmount.toString(),
|
|
372
|
+
};
|
|
982
373
|
const evmExecutionPayload = {
|
|
983
374
|
transactionData: {
|
|
984
|
-
to:
|
|
985
|
-
data,
|
|
986
|
-
value:
|
|
375
|
+
to: cd.to,
|
|
376
|
+
data: cd.data,
|
|
377
|
+
value: cd.valueWei ?? '0',
|
|
987
378
|
gasEstimate: '0',
|
|
988
379
|
gasLimit: '0',
|
|
989
380
|
},
|
|
990
|
-
|
|
381
|
+
approval,
|
|
991
382
|
};
|
|
992
|
-
|
|
993
|
-
const
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
}
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
routerAddress: chosenRouter,
|
|
1011
|
-
quoterAddress: v3Price.quoterAddress,
|
|
1012
|
-
feeTier: v3Price.feeTier, // tickSpacing for Slipstream
|
|
1013
|
-
method: methodForResponse,
|
|
1014
|
-
amountOut: bestAmountOut.toString(),
|
|
1015
|
-
amountOutMin: amountOutMin.toString(),
|
|
1016
|
-
calldata: data,
|
|
1017
|
-
value: txValue,
|
|
1018
|
-
gasEstimate: v3Price.gasEstimate,
|
|
1019
|
-
sqrtPriceX96After: v3Price.sqrtPriceX96After,
|
|
1020
|
-
initializedTicksCrossed: v3Price.initializedTicksCrossed,
|
|
1021
|
-
notes: (v3Price.method?.startsWith('OffchainQuoter') ? 'Off-chain pool simulation; ' : '') +
|
|
1022
|
-
(isSlipstream ? 'Slipstream tickSpacing; ' : '') +
|
|
1023
|
-
(isSushiV3
|
|
1024
|
-
? 'Sushi Route Processor 9 calldata (route bytes expected from off-chain pathfinder); '
|
|
1025
|
-
: '') +
|
|
1026
|
-
(expectNativeIn ? 'Native in; ' : '') +
|
|
1027
|
-
(expectNativeOut
|
|
1028
|
-
? isSushiV3
|
|
1029
|
-
? 'Native out handled inside route bytes.'
|
|
1030
|
-
: 'Native out via multicall(unwrapWETH9).'
|
|
1031
|
-
: 'ERC-20 out to recipient.'),
|
|
383
|
+
// For completeness, compute minOut here for protocol payload
|
|
384
|
+
const amountOutMin = (0, min_amount_out_1.calculateMinAmountOut)({
|
|
385
|
+
amountOut: price.amountOut,
|
|
386
|
+
slippage: slippagePct,
|
|
387
|
+
}).toString();
|
|
388
|
+
const qPayload = {
|
|
389
|
+
dex: deployment.dex,
|
|
390
|
+
router: cd.to,
|
|
391
|
+
quoter: deployment.quoter,
|
|
392
|
+
method: cd.methodName,
|
|
393
|
+
feeOrTick: pp.feeOrTick,
|
|
394
|
+
amountOut: price.amountOut,
|
|
395
|
+
amountOutMin,
|
|
396
|
+
calldata: cd.data,
|
|
397
|
+
value: cd.valueWei ?? '0',
|
|
398
|
+
notes: (nativeIn ? 'Native in; ' : '') +
|
|
399
|
+
(nativeOut ? 'Native out via unwrap; ' : '') +
|
|
400
|
+
`Adapter=${adapter.constructor.name}`,
|
|
1032
401
|
};
|
|
1033
|
-
|
|
402
|
+
const quoteResponse = {
|
|
1034
403
|
protocol: this.protocol,
|
|
1035
404
|
networkIn,
|
|
1036
405
|
networkOut,
|
|
1037
406
|
tokenIn,
|
|
1038
407
|
tokenOut,
|
|
1039
408
|
amountIn,
|
|
1040
|
-
amountOut:
|
|
1041
|
-
estimatedGas:
|
|
409
|
+
amountOut: price.amountOut,
|
|
410
|
+
estimatedGas: pp.gasEstimate,
|
|
1042
411
|
slippage,
|
|
1043
412
|
from,
|
|
1044
413
|
receiver,
|
|
1045
414
|
evmExecutionPayload,
|
|
1046
|
-
protocolResponse,
|
|
1047
|
-
};
|
|
1048
|
-
}
|
|
1049
|
-
_convertKeyToDexEnum(dexKey) {
|
|
1050
|
-
const parts = dexKey.split(':');
|
|
1051
|
-
if (parts.length !== 3) {
|
|
1052
|
-
throw (0, utils_1.sdkError)(enums_1.SdkErrorEnum.INVALID_PARAMS, `Invalid dex key format: ${dexKey}`);
|
|
1053
|
-
}
|
|
1054
|
-
const dexEnum = parts[0];
|
|
1055
|
-
if (![
|
|
1056
|
-
v3_dex_types_1.UniswapV3StyleDexEnum.UNISWAP_V3,
|
|
1057
|
-
v3_dex_types_1.UniswapV3StyleDexEnum.SUSHISWAP_V3,
|
|
1058
|
-
v3_dex_types_1.UniswapV3StyleDexEnum.PANCAKESWAP_V3,
|
|
1059
|
-
v3_dex_types_1.UniswapV3StyleDexEnum.PANGOLIN_V3,
|
|
1060
|
-
v3_dex_types_1.UniswapV3StyleDexEnum.HYPERSWAP_V3,
|
|
1061
|
-
v3_dex_types_1.UniswapV3StyleDexEnum.PHARAOH_CLMM,
|
|
1062
|
-
v3_dex_types_1.UniswapV3StyleDexEnum.AERODROME_CLMM,
|
|
1063
|
-
v3_dex_types_1.UniswapV3StyleDexEnum.VELODROME_CLMM,
|
|
1064
|
-
].includes(dexEnum)) {
|
|
1065
|
-
throw (0, utils_1.sdkError)(enums_1.SdkErrorEnum.INVALID_PARAMS, `Unknown dex enum in key: ${dexKey}`);
|
|
1066
|
-
}
|
|
1067
|
-
return dexEnum;
|
|
1068
|
-
}
|
|
1069
|
-
_determineFeeTiersForDex(dexString) {
|
|
1070
|
-
const dex = dexString === v3_dex_types_1.UniswapV3StyleDexEnum.PANCAKESWAP_V3
|
|
1071
|
-
? v3_dex_types_1.UniswapV3StyleDexEnum.PANCAKESWAP_V3
|
|
1072
|
-
: dexString === v3_dex_types_1.UniswapV3StyleDexEnum.PANGOLIN_V3
|
|
1073
|
-
? v3_dex_types_1.UniswapV3StyleDexEnum.PANGOLIN_V3
|
|
1074
|
-
: dexString === v3_dex_types_1.UniswapV3StyleDexEnum.SUSHISWAP_V3
|
|
1075
|
-
? v3_dex_types_1.UniswapV3StyleDexEnum.SUSHISWAP_V3
|
|
1076
|
-
: dexString === v3_dex_types_1.UniswapV3StyleDexEnum.HYPERSWAP_V3
|
|
1077
|
-
? v3_dex_types_1.UniswapV3StyleDexEnum.HYPERSWAP_V3
|
|
1078
|
-
: dexString === v3_dex_types_1.UniswapV3StyleDexEnum.PHARAOH_CLMM
|
|
1079
|
-
? v3_dex_types_1.UniswapV3StyleDexEnum.PHARAOH_CLMM
|
|
1080
|
-
: dexString === v3_dex_types_1.UniswapV3StyleDexEnum.AERODROME_CLMM
|
|
1081
|
-
? v3_dex_types_1.UniswapV3StyleDexEnum.AERODROME_CLMM
|
|
1082
|
-
: dexString === v3_dex_types_1.UniswapV3StyleDexEnum.VELODROME_CLMM
|
|
1083
|
-
? v3_dex_types_1.UniswapV3StyleDexEnum.VELODROME_CLMM
|
|
1084
|
-
: v3_dex_types_1.UniswapV3StyleDexEnum.UNISWAP_V3;
|
|
1085
|
-
switch (dex) {
|
|
1086
|
-
case v3_dex_types_1.UniswapV3StyleDexEnum.PANCAKESWAP_V3:
|
|
1087
|
-
return this.pancakeFeeTiers;
|
|
1088
|
-
case v3_dex_types_1.UniswapV3StyleDexEnum.PANGOLIN_V3:
|
|
1089
|
-
return this.pangolinFeeTiers;
|
|
1090
|
-
case v3_dex_types_1.UniswapV3StyleDexEnum.SUSHISWAP_V3:
|
|
1091
|
-
return this.uniFeeTiers;
|
|
1092
|
-
case v3_dex_types_1.UniswapV3StyleDexEnum.HYPERSWAP_V3:
|
|
1093
|
-
return this.hyperswapFeeTiers;
|
|
1094
|
-
case v3_dex_types_1.UniswapV3StyleDexEnum.PHARAOH_CLMM:
|
|
1095
|
-
return this.pharaohFeeTiers;
|
|
1096
|
-
case v3_dex_types_1.UniswapV3StyleDexEnum.AERODROME_CLMM:
|
|
1097
|
-
return this.aerodromeFeeTiers;
|
|
1098
|
-
case v3_dex_types_1.UniswapV3StyleDexEnum.VELODROME_CLMM:
|
|
1099
|
-
return this.velodromeFeeTiers;
|
|
1100
|
-
case v3_dex_types_1.UniswapV3StyleDexEnum.UNISWAP_V3:
|
|
1101
|
-
default:
|
|
1102
|
-
return this.uniFeeTiers;
|
|
1103
|
-
}
|
|
1104
|
-
}
|
|
1105
|
-
_isDex(expectedDex, v3Price) {
|
|
1106
|
-
return !!v3Price?.dex && v3Price.dex.startsWith(`${expectedDex}:`);
|
|
1107
|
-
}
|
|
1108
|
-
_create2Address(params) {
|
|
1109
|
-
const { dex, initHash, tokenA, tokenB, fee, deployer, factory } = params;
|
|
1110
|
-
const isSlip = dex === v3_dex_types_1.UniswapV3StyleDexEnum.AERODROME_CLMM || dex === v3_dex_types_1.UniswapV3StyleDexEnum.VELODROME_CLMM;
|
|
1111
|
-
// For Pancake V3 you already special-case deployer vs factory; Slipstream uses factory as deployer.
|
|
1112
|
-
const addressToUse = dex === v3_dex_types_1.UniswapV3StyleDexEnum.PANCAKESWAP_V3 ? deployer : factory;
|
|
1113
|
-
const a = (0, viem_1.getAddress)(tokenA);
|
|
1114
|
-
const b = (0, viem_1.getAddress)(tokenB);
|
|
1115
|
-
const [token0, token1] = (0, sort_addresses_1.sortAddresses)(a, b);
|
|
1116
|
-
// SLIPSTREAM: salt = keccak256(abi.encode(address,address,int24 tickSpacing))
|
|
1117
|
-
// UNI-LIKE: salt = keccak256(abi.encode(address,address,uint24 fee))
|
|
1118
|
-
const encoded = isSlip
|
|
1119
|
-
? (0, viem_1.encodeAbiParameters)([{ type: 'address' }, { type: 'address' }, { type: 'int24' }], [token0, token1, fee])
|
|
1120
|
-
: (0, viem_1.encodeAbiParameters)([{ type: 'address' }, { type: 'address' }, { type: 'uint24' }], [token0, token1, fee]);
|
|
1121
|
-
const salt = (0, ethers_1.keccak256)(encoded);
|
|
1122
|
-
const digest = (0, ethers_1.keccak256)((0, viem_1.concat)([
|
|
1123
|
-
(0, viem_1.hexToBytes)('0xff'),
|
|
1124
|
-
(0, viem_1.hexToBytes)(addressToUse),
|
|
1125
|
-
(0, viem_1.hexToBytes)(salt),
|
|
1126
|
-
(0, viem_1.hexToBytes)(initHash),
|
|
1127
|
-
]));
|
|
1128
|
-
return (0, viem_1.getAddress)(`0x${digest.slice(26)}`);
|
|
1129
|
-
}
|
|
1130
|
-
async _validateNativeLiquidity(params) {
|
|
1131
|
-
const { tokenIn, networkIn, dexes, nativePrice, tokenInPrice, tokenInDecimals } = params;
|
|
1132
|
-
// --- setup & guards
|
|
1133
|
-
const stable = constants_1.networkStablecoins[networkIn];
|
|
1134
|
-
if (!stable) {
|
|
1135
|
-
throw (0, utils_1.sdkError)(enums_1.SdkErrorEnum.INVALID_PARAMS, `No stablecoin mapping for chainId ${networkIn}`);
|
|
1136
|
-
}
|
|
1137
|
-
const usdcEntry = stable.usdc; // { address, decimals } | undefined
|
|
1138
|
-
const usdtEntry = stable.usdt;
|
|
1139
|
-
const wrappedNative = wrapped_native_1.wrappedNativeTokens[networkIn]; // string
|
|
1140
|
-
const tokenInAddr = (0, viem_1.getAddress)(tokenIn);
|
|
1141
|
-
const baseTokenAddrs = [wrappedNative, usdcEntry?.address, usdtEntry?.address]
|
|
1142
|
-
.filter((a) => !!a)
|
|
1143
|
-
.filter(a => !(0, is_native_1.isNative)(a))
|
|
1144
|
-
.map(a => (0, viem_1.getAddress)(a))
|
|
1145
|
-
.filter(a => a !== tokenInAddr);
|
|
1146
|
-
if (baseTokenAddrs.length === 0) {
|
|
1147
|
-
throw (0, utils_1.sdkError)(enums_1.SdkErrorEnum.INVALID_PARAMS, `No valid base tokens (WETH/USDC/USDT) for liquidity check on chainId ${networkIn}`);
|
|
1148
|
-
}
|
|
1149
|
-
const deployments = (this.deployments[networkIn] ?? []).filter(d => dexes.includes(d.dex));
|
|
1150
|
-
if (!deployments.length) {
|
|
1151
|
-
throw (0, utils_1.sdkError)(enums_1.SdkErrorEnum.INVALID_PARAMS, `No V3-style deployments configured for network ${networkIn} (requested: ${dexes.join(', ')})`);
|
|
1152
|
-
}
|
|
1153
|
-
const client = this._clients[networkIn];
|
|
1154
|
-
if (!client) {
|
|
1155
|
-
throw (0, utils_1.sdkError)(enums_1.SdkErrorEnum.INVALID_PARAMS, `No RPC client configured for chainId ${networkIn}`);
|
|
1156
|
-
}
|
|
1157
|
-
const feeTiers = this.uniFeeTiers; // e.g. [500, 3000, 10000]
|
|
1158
|
-
// --- helpers
|
|
1159
|
-
const isWrappedNative = (addr) => !!wrappedNative &&
|
|
1160
|
-
(0, viem_1.getAddress)(addr).toLowerCase() === (0, viem_1.getAddress)(wrappedNative).toLowerCase();
|
|
1161
|
-
const stableAddrLower = new Set([
|
|
1162
|
-
usdcEntry?.address ? (0, viem_1.getAddress)(usdcEntry.address).toLowerCase() : '',
|
|
1163
|
-
usdtEntry?.address ? (0, viem_1.getAddress)(usdtEntry.address).toLowerCase() : '',
|
|
1164
|
-
].filter(Boolean));
|
|
1165
|
-
const isStable = (addr) => stableAddrLower.has(addr.toLowerCase());
|
|
1166
|
-
const getBaseDecimals = (base) => {
|
|
1167
|
-
const lower = base.toLowerCase();
|
|
1168
|
-
if (usdcEntry && (0, viem_1.getAddress)(usdcEntry.address).toLowerCase() === lower)
|
|
1169
|
-
return usdcEntry.decimals;
|
|
1170
|
-
if (usdtEntry && (0, viem_1.getAddress)(usdtEntry.address).toLowerCase() === lower)
|
|
1171
|
-
return usdtEntry.decimals;
|
|
1172
|
-
if (isWrappedNative(base))
|
|
1173
|
-
return 18; // adjust per-chain if needed
|
|
1174
|
-
return 18; // fallback for any other ERC-20s you might allow as base later
|
|
415
|
+
protocolResponse: qPayload,
|
|
1175
416
|
};
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
// UniswapV3 pools always order tokens by address (token0 < token1) for the salt.
|
|
1179
|
-
// _create2Address MUST do this internally (or we do it here before calling).
|
|
1180
|
-
const candidatesMap = new Map(); // dedupe by pool address
|
|
1181
|
-
for (const d of deployments) {
|
|
1182
|
-
for (const base of baseTokenAddrs) {
|
|
1183
|
-
for (const fee of feeTiers) {
|
|
1184
|
-
// compute deterministic address
|
|
1185
|
-
const poolAddr = this._create2Address({
|
|
1186
|
-
dex: d.dex,
|
|
1187
|
-
factory: d.factory,
|
|
1188
|
-
deployer: d.deployer,
|
|
1189
|
-
initHash: d.initHash, // whatever your deployment holds
|
|
1190
|
-
tokenA: tokenInAddr,
|
|
1191
|
-
tokenB: base,
|
|
1192
|
-
fee,
|
|
1193
|
-
});
|
|
1194
|
-
const key = poolAddr.toLowerCase();
|
|
1195
|
-
if (!candidatesMap.has(key)) {
|
|
1196
|
-
candidatesMap.set(key, { pool: poolAddr, baseToken: base, dex: d.dex, fee });
|
|
1197
|
-
}
|
|
1198
|
-
}
|
|
1199
|
-
}
|
|
1200
|
-
}
|
|
1201
|
-
const candidates = [...candidatesMap.values()];
|
|
1202
|
-
if (!candidates.length) {
|
|
1203
|
-
throw (0, utils_1.sdkError)(enums_1.SdkErrorEnum.INVALID_PARAMS, `No candidate V3 pools could be constructed for chainId ${networkIn}`);
|
|
1204
|
-
}
|
|
1205
|
-
// --- 2) single multicall: balanceOf(tokenIn, pool) + balanceOf(base, pool) for each candidate
|
|
1206
|
-
const balanceCalls = candidates.flatMap(({ pool, baseToken }) => [
|
|
1207
|
-
{
|
|
1208
|
-
address: tokenInAddr,
|
|
1209
|
-
abi: viem_1.erc20Abi,
|
|
1210
|
-
functionName: 'balanceOf',
|
|
1211
|
-
args: [pool],
|
|
1212
|
-
},
|
|
1213
|
-
{
|
|
1214
|
-
address: baseToken,
|
|
1215
|
-
abi: viem_1.erc20Abi,
|
|
1216
|
-
functionName: 'balanceOf',
|
|
1217
|
-
args: [pool],
|
|
1218
|
-
},
|
|
1219
|
-
]);
|
|
1220
|
-
const balanceResults = await client.multicall({
|
|
1221
|
-
allowFailure: true,
|
|
1222
|
-
contracts: balanceCalls,
|
|
1223
|
-
...(networkIn === enums_1.ChainIdEnum.HYPEREVM && {
|
|
1224
|
-
multicallAddress: '0xcA11bde05977b3631167028862bE2a173976CA11',
|
|
1225
|
-
}),
|
|
1226
|
-
});
|
|
1227
|
-
const poolTVLs = [];
|
|
1228
|
-
for (let i = 0; i < candidates.length; i++) {
|
|
1229
|
-
const candidate = candidates[i];
|
|
1230
|
-
if (!candidate)
|
|
1231
|
-
continue; // should not happen
|
|
1232
|
-
const { pool, baseToken } = candidate;
|
|
1233
|
-
const tokenInBalRes = balanceResults[i * 2];
|
|
1234
|
-
const baseBalRes = balanceResults[i * 2 + 1];
|
|
1235
|
-
const tokenInRaw = tokenInBalRes?.status === 'success' && typeof tokenInBalRes.result === 'bigint'
|
|
1236
|
-
? tokenInBalRes.result
|
|
1237
|
-
: 0n;
|
|
1238
|
-
const baseRaw = baseBalRes?.status === 'success' && typeof baseBalRes.result === 'bigint'
|
|
1239
|
-
? baseBalRes.result
|
|
1240
|
-
: 0n;
|
|
1241
|
-
// quick skip if both zero to avoid NaN issues later
|
|
1242
|
-
if (tokenInRaw === 0n && baseRaw === 0n)
|
|
1243
|
-
continue;
|
|
1244
|
-
const baseDec = getBaseDecimals(baseToken);
|
|
1245
|
-
const tokenInAmt = Number(tokenInRaw) / 10 ** tokenInDecimals;
|
|
1246
|
-
const baseAmt = Number(baseRaw) / 10 ** baseDec;
|
|
1247
|
-
const usdValue = tokenInAmt * tokenInPrice + baseAmt * getBasePriceUSD(baseToken);
|
|
1248
|
-
poolTVLs.push({
|
|
1249
|
-
pool,
|
|
1250
|
-
baseToken,
|
|
1251
|
-
usdValue,
|
|
1252
|
-
baseIsNative: isWrappedNative(baseToken) ?? false,
|
|
1253
|
-
});
|
|
1254
|
-
}
|
|
1255
|
-
if (!poolTVLs.length) {
|
|
1256
|
-
throw (0, utils_1.sdkError)(enums_1.SdkErrorEnum.PRICE_NOT_FOUND, `No liquidity detected for ${tokenIn} on chainId ${networkIn} across requested dexes: ${dexes.join(', ')}`);
|
|
1257
|
-
}
|
|
1258
|
-
// --- 4) pick the most liquid and validate base
|
|
1259
|
-
poolTVLs.sort((a, b) => b.usdValue - a.usdValue);
|
|
1260
|
-
const top = poolTVLs[0];
|
|
1261
|
-
if (!top) {
|
|
1262
|
-
throw (0, utils_1.sdkError)(enums_1.SdkErrorEnum.PRICE_NOT_FOUND, `No liquidity detected for ${tokenIn} on chainId ${networkIn} across requested dexes: ${dexes.join(', ')}`);
|
|
1263
|
-
}
|
|
1264
|
-
if (isStable(top.baseToken)) {
|
|
1265
|
-
throw (0, utils_1.sdkError)(enums_1.SdkErrorEnum.PRICE_NOT_FOUND, `Most liquid pool for ${tokenIn} on chain ${networkIn} is against a stablecoin, not native.`);
|
|
1266
|
-
}
|
|
1267
|
-
if (!top.baseIsNative) {
|
|
1268
|
-
throw (0, utils_1.sdkError)(enums_1.SdkErrorEnum.PRICE_NOT_FOUND, `Most liquid pool for ${tokenIn} is not against the native token.`);
|
|
1269
|
-
}
|
|
1270
|
-
// success — top pool is native-based
|
|
1271
|
-
return;
|
|
1272
|
-
}
|
|
1273
|
-
/**
|
|
1274
|
-
* Read token0, token1, fee from a known pool via a single multicall,
|
|
1275
|
-
* then identify which configured deployment this pool belongs to by
|
|
1276
|
-
* recomputing CREATE2 for each deployment and comparing addresses.
|
|
1277
|
-
*/
|
|
1278
|
-
async _resolvePairDeploymentFast(network, pair) {
|
|
1279
|
-
const client = this._clients[network];
|
|
1280
|
-
if (!client) {
|
|
1281
|
-
throw (0, utils_1.sdkError)(enums_1.SdkErrorEnum.INVALID_PARAMS, `No RPC client configured for chainId ${network}`);
|
|
1282
|
-
}
|
|
1283
|
-
const [t0, t1, feeRes] = (await client.multicall({
|
|
1284
|
-
allowFailure: false,
|
|
1285
|
-
contracts: [
|
|
1286
|
-
{ address: pair, abi: uniswapV3_pool_abi_1.uniswapV3PoolAbi, functionName: 'token0' },
|
|
1287
|
-
{ address: pair, abi: uniswapV3_pool_abi_1.uniswapV3PoolAbi, functionName: 'token1' },
|
|
1288
|
-
{ address: pair, abi: uniswapV3_pool_abi_1.uniswapV3PoolAbi, functionName: 'fee' },
|
|
1289
|
-
],
|
|
1290
|
-
...(network === enums_1.ChainIdEnum.HYPEREVM && {
|
|
1291
|
-
multicallAddress: '0xcA11bde05977b3631167028862bE2a173976CA11',
|
|
1292
|
-
}),
|
|
1293
|
-
}));
|
|
1294
|
-
if (t0.status !== 'success' || t1.status !== 'success' || feeRes.status !== 'success') {
|
|
1295
|
-
throw (0, utils_1.sdkError)(enums_1.SdkErrorEnum.INVALID_PARAMS, `Failed to read pool data from pair address ${pair} on chain ${network}`);
|
|
1296
|
-
}
|
|
1297
|
-
const token0 = (0, viem_1.getAddress)(t0.result);
|
|
1298
|
-
const token1 = (0, viem_1.getAddress)(t1.result);
|
|
1299
|
-
const fee = Number(feeRes.result);
|
|
1300
|
-
const pairLower = pair.toLowerCase();
|
|
1301
|
-
const deployments = this.deployments[network] ?? [];
|
|
1302
|
-
for (const d of deployments) {
|
|
1303
|
-
const expected = this._create2Address({
|
|
1304
|
-
dex: d.dex,
|
|
1305
|
-
factory: d.factory,
|
|
1306
|
-
deployer: d.deployer,
|
|
1307
|
-
initHash: d.initHash,
|
|
1308
|
-
tokenA: token0,
|
|
1309
|
-
tokenB: token1,
|
|
1310
|
-
fee,
|
|
1311
|
-
});
|
|
1312
|
-
if (expected.toLowerCase() === pairLower) {
|
|
1313
|
-
return {
|
|
1314
|
-
token0,
|
|
1315
|
-
token1,
|
|
1316
|
-
fee,
|
|
1317
|
-
deployment: {
|
|
1318
|
-
dex: d.dex,
|
|
1319
|
-
router: d.router,
|
|
1320
|
-
quoter: d.quoter,
|
|
1321
|
-
factory: d.factory,
|
|
1322
|
-
deployer: d.deployer,
|
|
1323
|
-
initHash: d.initHash,
|
|
1324
|
-
},
|
|
1325
|
-
};
|
|
1326
|
-
}
|
|
1327
|
-
}
|
|
1328
|
-
throw (0, utils_1.sdkError)(enums_1.SdkErrorEnum.INVALID_PARAMS, `Pair ${pair} does not match any configured V3 deployments on chain ${network}`);
|
|
417
|
+
logger.info(`V3StyleDexService: Built quote response for ${amountIn} ${tokenIn} -> ${quoteResponse.amountOut} ${tokenOut} on ${networkIn} via ${deployment.dex}`);
|
|
418
|
+
return quoteResponse;
|
|
1329
419
|
}
|
|
1330
|
-
|
|
1331
|
-
|
|
1332
|
-
* - Validate the pair matches tokenIn/tokenOut (after native wrapping).
|
|
1333
|
-
* - Use the single matched deployment's quoter if present (V2 -> V1 fallback).
|
|
1334
|
-
* - Else, fallback to Offchain quoter limited to this one factory + fee.
|
|
1335
|
-
*/
|
|
1336
|
-
async _fetchKnownPairPrice(params) {
|
|
1337
|
-
const { network, tokenInForQuote, tokenOutForQuote, amountInBI, pair } = params;
|
|
420
|
+
// --------------------------- Internals -------------------------------------
|
|
421
|
+
async _execBatch(network, contracts) {
|
|
1338
422
|
const client = this._clients[network];
|
|
1339
423
|
if (!client) {
|
|
1340
424
|
throw (0, utils_1.sdkError)(enums_1.SdkErrorEnum.INVALID_PARAMS, `No RPC client configured for chainId ${network}`);
|
|
1341
425
|
}
|
|
1342
|
-
|
|
1343
|
-
|
|
1344
|
-
// Confirm the requested direction is (tokenIn, tokenOut) ∈ {(token0,token1),(token1,token0)}
|
|
1345
|
-
const inLower = (0, viem_1.getAddress)(tokenInForQuote).toLowerCase();
|
|
1346
|
-
const outLower = (0, viem_1.getAddress)(tokenOutForQuote).toLowerCase();
|
|
1347
|
-
const t0 = token0.toLowerCase();
|
|
1348
|
-
const t1 = token1.toLowerCase();
|
|
1349
|
-
const directionValid = (inLower === t0 && outLower === t1) || (inLower === t1 && outLower === t0);
|
|
1350
|
-
if (!directionValid) {
|
|
1351
|
-
throw (0, utils_1.sdkError)(enums_1.SdkErrorEnum.INVALID_PARAMS, `Supplied pair/token direction mismatch. Pair ${pair} tokens are ${token0}/${token1}; received ${tokenInForQuote}/${tokenOutForQuote}`);
|
|
1352
|
-
}
|
|
1353
|
-
// Build dex key for response routing
|
|
1354
|
-
const dexKey = (0, dex_deployment_key_1.dexDeploymentKey)({
|
|
1355
|
-
dex: deployment.dex,
|
|
1356
|
-
router: deployment.router,
|
|
1357
|
-
network,
|
|
1358
|
-
});
|
|
1359
|
-
// 2) Try on-chain quoter (struct signature first, then legacy)
|
|
1360
|
-
if (deployment?.quoter) {
|
|
1361
|
-
// V2 (struct)
|
|
1362
|
-
try {
|
|
1363
|
-
// V2 (struct) via static call
|
|
1364
|
-
const sim = await client.simulateContract({
|
|
1365
|
-
address: deployment.quoter,
|
|
1366
|
-
abi: uniswapV3_quoter_abi_1.uniswapV3QuoterAbi,
|
|
1367
|
-
functionName: 'quoteExactInputSingle',
|
|
1368
|
-
args: [
|
|
1369
|
-
{
|
|
1370
|
-
tokenIn: (0, viem_1.getAddress)(tokenInForQuote),
|
|
1371
|
-
tokenOut: (0, viem_1.getAddress)(tokenOutForQuote),
|
|
1372
|
-
amountIn: amountInBI,
|
|
1373
|
-
fee,
|
|
1374
|
-
sqrtPriceLimitX96: 0n,
|
|
1375
|
-
},
|
|
1376
|
-
],
|
|
1377
|
-
});
|
|
1378
|
-
const [amountOut, sqrtAfter, ticks, gas] = sim.result;
|
|
1379
|
-
return {
|
|
1380
|
-
amountOut,
|
|
1381
|
-
payload: {
|
|
1382
|
-
dex: dexKey,
|
|
1383
|
-
quoterAddress: deployment.quoter,
|
|
1384
|
-
method: 'QuoterV2.quoteExactInputSingle',
|
|
1385
|
-
feeTier: fee,
|
|
1386
|
-
amountOut: amountOut.toString(),
|
|
1387
|
-
gasEstimate: gas ? gas.toString() : undefined,
|
|
1388
|
-
sqrtPriceX96After: sqrtAfter ? sqrtAfter.toString() : undefined,
|
|
1389
|
-
initializedTicksCrossed: ticks,
|
|
1390
|
-
notes: `Known pair fast path (${pair}).`,
|
|
1391
|
-
},
|
|
1392
|
-
};
|
|
1393
|
-
}
|
|
1394
|
-
catch (eV2) {
|
|
1395
|
-
// Legacy V1 (tuple) via static call
|
|
426
|
+
if (network === enums_1.ChainIdEnum.HYPEREVM) {
|
|
427
|
+
return Promise.all(contracts.map(async (c) => {
|
|
1396
428
|
try {
|
|
1397
|
-
const
|
|
1398
|
-
|
|
1399
|
-
abi: uniswapV3_quoter_abi_1.uniswapV3QuoterAbi,
|
|
1400
|
-
functionName: 'quoteExactInputSingle',
|
|
1401
|
-
args: [
|
|
1402
|
-
{
|
|
1403
|
-
tokenIn: (0, viem_1.getAddress)(tokenInForQuote),
|
|
1404
|
-
tokenOut: (0, viem_1.getAddress)(tokenOutForQuote),
|
|
1405
|
-
fee,
|
|
1406
|
-
amountIn: amountInBI,
|
|
1407
|
-
sqrtPriceLimitX96: 0n,
|
|
1408
|
-
},
|
|
1409
|
-
],
|
|
1410
|
-
});
|
|
1411
|
-
const [amountOut] = simV1.result;
|
|
1412
|
-
return {
|
|
1413
|
-
amountOut,
|
|
1414
|
-
payload: {
|
|
1415
|
-
dex: dexKey,
|
|
1416
|
-
quoterAddress: deployment.quoter,
|
|
1417
|
-
method: 'Quoter.quoteExactInputSingle',
|
|
1418
|
-
feeTier: fee,
|
|
1419
|
-
amountOut: amountOut.toString(),
|
|
1420
|
-
notes: `Known pair fast path (${pair}).`,
|
|
1421
|
-
},
|
|
1422
|
-
};
|
|
429
|
+
const result = await client.readContract(c);
|
|
430
|
+
return { status: 'success', result };
|
|
1423
431
|
}
|
|
1424
|
-
catch (
|
|
1425
|
-
|
|
1426
|
-
// fall through to off-chain
|
|
432
|
+
catch (error) {
|
|
433
|
+
return { status: 'failure', error };
|
|
1427
434
|
}
|
|
1428
|
-
}
|
|
1429
|
-
}
|
|
1430
|
-
// 3) Off-chain fallback (constrained)
|
|
1431
|
-
if (deployment.factory) {
|
|
1432
|
-
const off = new v3_offchain_quoter_service_1.V3OffchainQuoter();
|
|
1433
|
-
const res = await off.fetchV3Quote({
|
|
1434
|
-
client,
|
|
1435
|
-
tokenIn: (0, viem_1.getAddress)(tokenInForQuote),
|
|
1436
|
-
tokenOut: (0, viem_1.getAddress)(tokenOutForQuote),
|
|
1437
|
-
amountIn: amountInBI,
|
|
1438
|
-
factory: (0, viem_1.getAddress)(deployment.factory),
|
|
1439
|
-
fees: [fee],
|
|
1440
|
-
});
|
|
1441
|
-
if (res?.best && res.best.ok && res.best.amountOut > 0n) {
|
|
1442
|
-
return {
|
|
1443
|
-
amountOut: res.best.amountOut,
|
|
1444
|
-
payload: {
|
|
1445
|
-
dex: dexKey,
|
|
1446
|
-
quoterAddress: undefined,
|
|
1447
|
-
method: 'OffchainQuoter.simulateExactInputSingle',
|
|
1448
|
-
feeTier: fee,
|
|
1449
|
-
amountOut: res.best.amountOut.toString(),
|
|
1450
|
-
sqrtPriceX96After: res.best.sqrtPriceX96After
|
|
1451
|
-
? res.best.sqrtPriceX96After.toString()
|
|
1452
|
-
: undefined,
|
|
1453
|
-
initializedTicksCrossed: res.best.initializedTicksCrossed,
|
|
1454
|
-
notes: `Known pair fast path (${pair}).`,
|
|
1455
|
-
},
|
|
1456
|
-
};
|
|
1457
|
-
}
|
|
435
|
+
}));
|
|
1458
436
|
}
|
|
1459
|
-
|
|
1460
|
-
}
|
|
1461
|
-
_isSlipstreamDexString(dexString) {
|
|
1462
|
-
return (dexString === v3_dex_types_1.UniswapV3StyleDexEnum.VELODROME_CLMM ||
|
|
1463
|
-
dexString === v3_dex_types_1.UniswapV3StyleDexEnum.AERODROME_CLMM);
|
|
437
|
+
return client.multicall({ allowFailure: true, contracts });
|
|
1464
438
|
}
|
|
1465
|
-
|
|
1466
|
-
|
|
439
|
+
_getAdapter(dex) {
|
|
440
|
+
const cached = this._adapterCache.get(dex);
|
|
441
|
+
if (cached)
|
|
442
|
+
return cached;
|
|
443
|
+
let adapter;
|
|
444
|
+
switch (dex) {
|
|
1467
445
|
case v3_dex_types_1.UniswapV3StyleDexEnum.AERODROME_CLMM:
|
|
1468
|
-
return this.aerodromeTickSpacings;
|
|
1469
446
|
case v3_dex_types_1.UniswapV3StyleDexEnum.VELODROME_CLMM:
|
|
1470
|
-
|
|
447
|
+
adapter = new slipstream_adapter_1.SlipstreamDexAdapter(dex);
|
|
448
|
+
break;
|
|
449
|
+
case v3_dex_types_1.UniswapV3StyleDexEnum.PANCAKESWAP_V3:
|
|
450
|
+
case v3_dex_types_1.UniswapV3StyleDexEnum.PANGOLIN_V3:
|
|
451
|
+
case v3_dex_types_1.UniswapV3StyleDexEnum.PHARAOH_CLMM:
|
|
452
|
+
case v3_dex_types_1.UniswapV3StyleDexEnum.RAMSES_CLMM:
|
|
453
|
+
adapter = new uniswap_fork_adapter_1.V3ForkDexAdapter(dex);
|
|
454
|
+
break;
|
|
455
|
+
case v3_dex_types_1.UniswapV3StyleDexEnum.UNISWAP_V3:
|
|
456
|
+
case v3_dex_types_1.UniswapV3StyleDexEnum.HYPERSWAP_V3:
|
|
457
|
+
adapter = new uniswap_adapter_1.UniswapV3DexAdapter(dex);
|
|
458
|
+
break;
|
|
1471
459
|
default:
|
|
1472
|
-
|
|
460
|
+
throw new Error(`Unsupported CLMM DEX enum: ${dex}`);
|
|
1473
461
|
}
|
|
462
|
+
this._adapterCache.set(dex, adapter);
|
|
463
|
+
return adapter;
|
|
464
|
+
}
|
|
465
|
+
_buildFastRoutePriceResponse(params) {
|
|
466
|
+
const { networkIn, networkOut, tokenIn, tokenOut, slippage, amountIn, overrideDex, overrideAmountOutMin, overrideFeeOrTick, } = params;
|
|
467
|
+
const deployment = this._deployments[networkIn]?.find(d => d.dex === overrideDex);
|
|
468
|
+
if (!deployment) {
|
|
469
|
+
throw (0, utils_1.sdkError)(enums_1.SdkErrorEnum.INVALID_PARAMS, `No CLMM deployment for DEX ${overrideDex} on chainId ${networkIn}`);
|
|
470
|
+
}
|
|
471
|
+
const router = deployment.router ?? constants_1.ZERO_ADDRESS;
|
|
472
|
+
const quoter = deployment.quoter ?? constants_1.ZERO_ADDRESS;
|
|
473
|
+
const rawPriceResponse = {
|
|
474
|
+
dex: overrideDex,
|
|
475
|
+
router,
|
|
476
|
+
quoter,
|
|
477
|
+
method: `ExpectedAmountOut`,
|
|
478
|
+
feeOrTick: overrideFeeOrTick,
|
|
479
|
+
amountOut: overrideAmountOutMin,
|
|
480
|
+
};
|
|
481
|
+
const priceResponse = {
|
|
482
|
+
protocol: this.protocol,
|
|
483
|
+
networkIn,
|
|
484
|
+
networkOut,
|
|
485
|
+
tokenIn,
|
|
486
|
+
tokenOut,
|
|
487
|
+
amountIn,
|
|
488
|
+
amountOut: overrideAmountOutMin,
|
|
489
|
+
protocolResponse: rawPriceResponse,
|
|
490
|
+
slippage,
|
|
491
|
+
};
|
|
492
|
+
return priceResponse;
|
|
1474
493
|
}
|
|
1475
494
|
}
|
|
1476
495
|
exports.V3StyleDexService = V3StyleDexService;
|