four-flap-meme-sdk 2.2.18 → 2.2.20
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/__tests__/subpath-exports.test.d.ts +1 -0
- package/dist/__tests__/subpath-exports.test.js +64 -0
- package/dist/abis/common.d.ts +85 -0
- package/dist/abis/common.js +240 -0
- package/dist/abis/contracts/TaxToken.json +969 -0
- package/dist/abis/contracts/TokenManager.json +836 -0
- package/dist/abis/contracts/TokenManager2.json +136 -0
- package/dist/abis/contracts/TokenManagerHelper3.json +993 -0
- package/dist/abis/contracts/index.d.ts +5 -0
- package/dist/abis/contracts/index.js +5 -0
- package/dist/abis/flap/index.d.ts +5 -0
- package/dist/abis/flap/index.js +5 -0
- package/dist/abis/flap/portal-eip7702.d.ts +4 -0
- package/dist/abis/flap/portal-eip7702.js +39 -0
- package/dist/abis/flap/portal-events.d.ts +6 -0
- package/dist/abis/flap/portal-events.js +17 -0
- package/dist/abis/flap/portal-merkle.d.ts +4 -0
- package/dist/abis/flap/portal-merkle.js +25 -0
- package/dist/abis/flap/portal.d.ts +6 -0
- package/dist/abis/flap/portal.js +37 -0
- package/dist/abis/flap/vault.d.ts +171 -0
- package/dist/abis/flap/vault.js +91 -0
- package/dist/abis/index.d.ts +8 -0
- package/dist/abis/index.js +11 -0
- package/dist/bundle-core/__tests__/config-helpers.test.d.ts +1 -0
- package/dist/bundle-core/__tests__/config-helpers.test.js +28 -0
- package/dist/bundle-core/__tests__/facade-parity.test.d.ts +1 -0
- package/dist/bundle-core/__tests__/facade-parity.test.js +33 -0
- package/dist/bundle-core/__tests__/sign-context-helpers.test.d.ts +1 -0
- package/dist/bundle-core/__tests__/sign-context-helpers.test.js +60 -0
- package/dist/bundle-core/__tests__/sign-fixture.test.d.ts +1 -0
- package/dist/bundle-core/__tests__/sign-fixture.test.js +220 -0
- package/dist/bundle-core/__tests__/sign-fixtures.d.ts +10 -0
- package/dist/bundle-core/__tests__/sign-fixtures.js +16 -0
- package/dist/bundle-core/config-helpers.d.ts +37 -0
- package/dist/bundle-core/config-helpers.js +58 -0
- package/dist/bundle-core/errors.d.ts +50 -0
- package/dist/bundle-core/errors.js +38 -0
- package/dist/bundle-core/four-meme/approve-tokenmanager.d.ts +7 -0
- package/dist/bundle-core/four-meme/approve-tokenmanager.js +99 -0
- package/dist/bundle-core/four-meme/core-helpers.d.ts +8 -0
- package/dist/bundle-core/four-meme/core-helpers.js +41 -0
- package/dist/bundle-core/four-meme/core.d.ts +4 -0
- package/dist/bundle-core/four-meme/core.js +515 -0
- package/dist/bundle-core/four-meme/pancake-proxy.d.ts +28 -0
- package/dist/bundle-core/four-meme/pancake-proxy.js +679 -0
- package/dist/bundle-core/four-meme/private.d.ts +27 -0
- package/dist/bundle-core/four-meme/private.js +465 -0
- package/dist/bundle-core/four-meme/sign-context-helpers.d.ts +2 -0
- package/dist/bundle-core/four-meme/sign-context-helpers.js +2 -0
- package/dist/bundle-core/four-meme/swap-buy-first.d.ts +8 -0
- package/dist/bundle-core/four-meme/swap-buy-first.js +456 -0
- package/dist/bundle-core/four-meme/swap-hop-helpers.d.ts +6 -0
- package/dist/bundle-core/four-meme/swap-hop-helpers.js +63 -0
- package/dist/bundle-core/four-meme/swap-internal.d.ts +3 -0
- package/dist/bundle-core/four-meme/swap-internal.js +18 -0
- package/dist/bundle-core/four-meme/swap-sign-helpers.d.ts +28 -0
- package/dist/bundle-core/four-meme/swap-sign-helpers.js +105 -0
- package/dist/bundle-core/four-meme/swap.d.ts +17 -0
- package/dist/bundle-core/four-meme/swap.js +505 -0
- package/dist/bundle-core/four-meme/types/buy-first.d.ts +50 -0
- package/dist/bundle-core/four-meme/types/buy-first.js +1 -0
- package/dist/bundle-core/four-meme/types/core-flow.d.ts +63 -0
- package/dist/bundle-core/four-meme/types/core-flow.js +1 -0
- package/dist/bundle-core/four-meme/types/index.d.ts +600 -0
- package/dist/bundle-core/four-meme/types/index.js +1 -0
- package/dist/bundle-core/four-meme/types/swap-internal.d.ts +19 -0
- package/dist/bundle-core/four-meme/types/swap-internal.js +1 -0
- package/dist/bundle-core/four-meme/types.d.ts +1 -0
- package/dist/bundle-core/four-meme/types.js +1 -0
- package/dist/bundle-core/four-meme/utils-disperse.d.ts +7 -0
- package/dist/bundle-core/four-meme/utils-disperse.js +396 -0
- package/dist/bundle-core/four-meme/utils-pairwise.d.ts +8 -0
- package/dist/bundle-core/four-meme/utils-pairwise.js +328 -0
- package/dist/bundle-core/four-meme/utils-sweep.d.ts +8 -0
- package/dist/bundle-core/four-meme/utils-sweep.js +744 -0
- package/dist/bundle-core/index.d.ts +8 -0
- package/dist/bundle-core/index.js +8 -0
- package/dist/bundle-core/internal.d.ts +16 -0
- package/dist/bundle-core/internal.js +160 -0
- package/dist/bundle-core/sign-context-helpers.d.ts +26 -0
- package/dist/bundle-core/sign-context-helpers.js +63 -0
- package/dist/bundle-core/submit.d.ts +293 -0
- package/dist/bundle-core/submit.js +731 -0
- package/dist/bundle-core/types/index.d.ts +8 -0
- package/dist/bundle-core/types/index.js +1 -0
- package/dist/bundle-core/types.d.ts +1 -0
- package/dist/bundle-core/types.js +1 -0
- package/dist/chains/bsc/four/approve-tokenmanager.d.ts +1 -26
- package/dist/chains/bsc/four/approve-tokenmanager.js +1 -113
- package/dist/chains/bsc/four/config.d.ts +5 -67
- package/dist/chains/bsc/four/config.js +2 -114
- package/dist/chains/bsc/four/core.d.ts +1 -4
- package/dist/chains/bsc/four/core.js +1 -592
- package/dist/chains/bsc/four/index.d.ts +6 -6
- package/dist/chains/bsc/four/index.js +6 -6
- package/dist/chains/bsc/four/internal.d.ts +2 -46
- package/dist/chains/bsc/four/internal.js +2 -239
- package/dist/chains/bsc/four/pancake-proxy.d.ts +1 -28
- package/dist/chains/bsc/four/pancake-proxy.js +1 -687
- package/dist/chains/bsc/four/private.d.ts +1 -27
- package/dist/chains/bsc/four/private.js +1 -477
- package/dist/chains/bsc/four/submit.d.ts +2 -315
- package/dist/chains/bsc/four/submit.js +2 -752
- package/dist/chains/bsc/four/swap-buy-first.d.ts +2 -55
- package/dist/chains/bsc/four/swap-buy-first.js +2 -507
- package/dist/chains/bsc/four/swap-internal.d.ts +1 -3
- package/dist/chains/bsc/four/swap-internal.js +1 -18
- package/dist/chains/bsc/four/swap.d.ts +2 -144
- package/dist/chains/bsc/four/swap.js +2 -766
- package/dist/chains/bsc/four/types.d.ts +1 -476
- package/dist/chains/bsc/four/utils-disperse.d.ts +1 -0
- package/dist/chains/bsc/four/utils-disperse.js +1 -0
- package/dist/chains/bsc/four/utils-pairwise.d.ts +1 -0
- package/dist/chains/bsc/four/utils-pairwise.js +1 -0
- package/dist/chains/bsc/four/utils-sweep.d.ts +1 -0
- package/dist/chains/bsc/four/utils-sweep.js +1 -0
- package/dist/chains/bsc/four/utils.d.ts +5 -18
- package/dist/chains/bsc/four/utils.js +5 -1552
- package/dist/chains/bsc/iro.d.ts +5 -0
- package/dist/chains/bsc/iro.js +4 -0
- package/dist/chains/bsc/pancake/bundle-buy-first-helpers.d.ts +155 -0
- package/dist/chains/bsc/pancake/bundle-buy-first-helpers.js +80 -0
- package/dist/chains/bsc/pancake/bundle-buy-first.d.ts +1 -91
- package/dist/chains/bsc/pancake/bundle-buy-first.js +98 -213
- package/dist/chains/bsc/pancake/bundle-swap-helpers.d.ts +241 -0
- package/dist/chains/bsc/pancake/bundle-swap-helpers.js +565 -0
- package/dist/chains/bsc/pancake/bundle-swap.d.ts +1 -79
- package/dist/chains/bsc/pancake/bundle-swap.js +114 -726
- package/dist/chains/bsc/pancake/index.d.ts +4 -2
- package/dist/chains/bsc/pancake/index.js +1 -3
- package/dist/chains/bsc/platforms/iro/factory.d.ts +2 -2
- package/dist/chains/bsc/platforms/iro/factory.js +3 -1
- package/dist/chains/bsc/platforms/iro/index.d.ts +5 -5
- package/dist/chains/bsc/platforms/iro/index.js +3 -3
- package/dist/chains/bsc/platforms/iro/pool.js +31 -10
- package/dist/chains/bsc/platforms/iro/token.js +4 -1
- package/dist/chains/eni/batch-router/bundle-approve.js +4 -3
- package/dist/chains/eni/batch-router/transfer.js +55 -25
- package/dist/chains/eni/batch-router/utils.js +32 -6
- package/dist/chains/eni/bundler/sign.js +5 -6
- package/dist/chains/eni/bundler/submit.js +1 -4
- package/dist/chains/eni/constants.js +1 -1
- package/dist/chains/eni/flat-aliases.d.ts +10 -0
- package/dist/chains/eni/flat-aliases.js +8 -0
- package/dist/chains/eni/index.d.ts +2 -1
- package/dist/chains/eni/index.js +1 -0
- package/dist/chains/eni/platforms/daoaas/create.js +2 -2
- package/dist/chains/eni/platforms/daoaas/index.d.ts +3 -3
- package/dist/chains/eni/platforms/daoaas/index.js +3 -3
- package/dist/chains/eni/platforms/daoaas/meta.js +9 -6
- package/dist/chains/eni/platforms/daoaas/portal-direct.js +28 -44
- package/dist/chains/eni/platforms/daoaas/portal.js +10 -6
- package/dist/chains/eni/platforms/dswap/liquidity.js +58 -26
- package/dist/chains/eni/platforms/fair-launch/index.d.ts +2 -2
- package/dist/chains/eni/platforms/fair-launch/index.js +1 -1
- package/dist/chains/eni/platforms/fair-launch/launcher.js +87 -46
- package/dist/chains/eni/platforms/fair-launch/pool.js +4 -1
- package/dist/chains/eni/platforms/fair-launch/presets.js +2 -2
- package/dist/chains/eni/platforms/iro/factory.d.ts +2 -2
- package/dist/chains/eni/platforms/iro/factory.js +3 -1
- package/dist/chains/eni/platforms/iro/index.d.ts +6 -6
- package/dist/chains/eni/platforms/iro/index.js +4 -4
- package/dist/chains/eni/platforms/iro/pool.js +90 -26
- package/dist/chains/eni/platforms/iro/token.js +107 -31
- package/dist/chains/eni/platforms/iro/whitelist.js +6 -18
- package/dist/chains/eni/submit.d.ts +43 -0
- package/dist/chains/eni/submit.js +287 -0
- package/dist/chains/index.d.ts +13 -0
- package/dist/chains/index.js +13 -0
- package/dist/chains/xlayer/constants.d.ts +5 -0
- package/dist/chains/xlayer/eip7702/bundle-approve.d.ts +2 -26
- package/dist/chains/xlayer/eip7702/bundle-approve.js +11 -21
- package/dist/chains/xlayer/eip7702/bundle-buy.d.ts +2 -6
- package/dist/chains/xlayer/eip7702/bundle-buy.js +13 -51
- package/dist/chains/xlayer/eip7702/bundle-create.js +104 -74
- package/dist/chains/xlayer/eip7702/bundle-sell.d.ts +2 -6
- package/dist/chains/xlayer/eip7702/bundle-sell.js +29 -111
- package/dist/chains/xlayer/eip7702/bundle-swap.d.ts +3 -65
- package/dist/chains/xlayer/eip7702/bundle-swap.js +51 -245
- package/dist/chains/xlayer/eip7702/constants.d.ts +11 -26
- package/dist/chains/xlayer/eip7702/constants.js +15 -68
- package/dist/chains/xlayer/eip7702/flat-aliases.d.ts +13 -0
- package/dist/chains/xlayer/eip7702/flat-aliases.js +10 -0
- package/dist/chains/xlayer/eip7702/index.d.ts +28 -46
- package/dist/chains/xlayer/eip7702/index.js +28 -81
- package/dist/chains/xlayer/eip7702/multi-hop-transfer-helpers.d.ts +79 -0
- package/dist/chains/xlayer/eip7702/multi-hop-transfer-helpers.js +1 -0
- package/dist/chains/xlayer/eip7702/multi-hop-transfer.d.ts +2 -203
- package/dist/chains/xlayer/eip7702/multi-hop-transfer.js +63 -307
- package/dist/chains/xlayer/eip7702/transfer-context-helpers.d.ts +26 -0
- package/dist/chains/xlayer/eip7702/transfer-context-helpers.js +58 -0
- package/dist/chains/xlayer/eip7702/types.d.ts +88 -0
- package/dist/chains/xlayer/eip7702/utils.d.ts +0 -3
- package/dist/chains/xlayer/eip7702/utils.js +23 -28
- package/dist/chains/xlayer/eip7702/volume-helpers.d.ts +148 -0
- package/dist/chains/xlayer/eip7702/volume-helpers.js +48 -0
- package/dist/chains/xlayer/eip7702/volume.d.ts +6 -184
- package/dist/chains/xlayer/eip7702/volume.js +89 -164
- package/dist/chains/xlayer/eoa/constants.d.ts +1 -1
- package/dist/chains/xlayer/eoa/constants.js +2 -16
- package/dist/chains/xlayer/eoa/dex-helpers.d.ts +1 -1
- package/dist/chains/xlayer/eoa/dex-helpers.js +7 -37
- package/dist/chains/xlayer/eoa/eoa-bundle-swap-helpers.d.ts +126 -0
- package/dist/chains/xlayer/eoa/eoa-bundle-swap-helpers.js +228 -0
- package/dist/chains/xlayer/eoa/eoa-bundle-swap.d.ts +1 -95
- package/dist/chains/xlayer/eoa/eoa-bundle-swap.js +66 -299
- package/dist/chains/xlayer/eoa/eoa-wash-volume.d.ts +1 -1
- package/dist/chains/xlayer/eoa/eoa-wash-volume.js +18 -23
- package/dist/chains/xlayer/eoa/index.d.ts +10 -6
- package/dist/chains/xlayer/eoa/index.js +8 -23
- package/dist/chains/xlayer/eoa/portal-ops.js +7 -2
- package/dist/chains/xlayer/eoa/router-manager.js +5 -4
- package/dist/chains/xlayer/eoa/types.d.ts +2 -2
- package/dist/chains/xlayer/eoa/types.js +1 -3
- package/dist/chains/xlayer/index.d.ts +3 -2
- package/dist/chains/xlayer/index.js +4 -7
- package/dist/contracts/helper3.d.ts +20 -5
- package/dist/contracts/helper3.js +56 -20
- package/dist/contracts/tm-bundle-helpers.d.ts +88 -0
- package/dist/contracts/tm-bundle-helpers.js +73 -0
- package/dist/contracts/tm-bundle-merkle/approve-tokenmanager.d.ts +1 -26
- package/dist/contracts/tm-bundle-merkle/approve-tokenmanager.js +1 -113
- package/dist/contracts/tm-bundle-merkle/config.d.ts +5 -67
- package/dist/contracts/tm-bundle-merkle/config.js +2 -114
- package/dist/contracts/tm-bundle-merkle/core.d.ts +1 -4
- package/dist/contracts/tm-bundle-merkle/core.js +1 -591
- package/dist/contracts/tm-bundle-merkle/index.d.ts +5 -5
- package/dist/contracts/tm-bundle-merkle/index.js +5 -5
- package/dist/contracts/tm-bundle-merkle/internal.d.ts +2 -46
- package/dist/contracts/tm-bundle-merkle/internal.js +2 -238
- package/dist/contracts/tm-bundle-merkle/pancake-proxy.d.ts +1 -28
- package/dist/contracts/tm-bundle-merkle/pancake-proxy.js +1 -686
- package/dist/contracts/tm-bundle-merkle/private.d.ts +1 -27
- package/dist/contracts/tm-bundle-merkle/private.js +1 -476
- package/dist/contracts/tm-bundle-merkle/submit.d.ts +3 -314
- package/dist/contracts/tm-bundle-merkle/submit.js +3 -928
- package/dist/contracts/tm-bundle-merkle/swap-buy-first.d.ts +2 -55
- package/dist/contracts/tm-bundle-merkle/swap-buy-first.js +2 -506
- package/dist/contracts/tm-bundle-merkle/swap-internal.d.ts +1 -3
- package/dist/contracts/tm-bundle-merkle/swap-internal.js +1 -18
- package/dist/contracts/tm-bundle-merkle/swap.d.ts +2 -144
- package/dist/contracts/tm-bundle-merkle/swap.js +2 -764
- package/dist/contracts/tm-bundle-merkle/types.d.ts +1 -476
- package/dist/contracts/tm-bundle-merkle/utils-disperse.d.ts +1 -0
- package/dist/contracts/tm-bundle-merkle/utils-disperse.js +1 -0
- package/dist/contracts/tm-bundle-merkle/utils-pairwise.d.ts +1 -0
- package/dist/contracts/tm-bundle-merkle/utils-pairwise.js +1 -0
- package/dist/contracts/tm-bundle-merkle/utils-sweep.d.ts +1 -0
- package/dist/contracts/tm-bundle-merkle/utils-sweep.js +1 -0
- package/dist/contracts/tm-bundle-merkle/utils.d.ts +6 -18
- package/dist/contracts/tm-bundle-merkle/utils.js +6 -1501
- package/dist/contracts/tm-bundle.d.ts +3 -51
- package/dist/contracts/tm-bundle.js +120 -187
- package/dist/contracts/tm.d.ts +10 -8
- package/dist/contracts/tm.js +39 -35
- package/dist/contracts/tm1.js +9 -4
- package/dist/contracts/tm2.js +10 -5
- package/dist/dex/direct-router-helpers.d.ts +269 -0
- package/dist/dex/direct-router-helpers.js +536 -0
- package/dist/dex/direct-router.d.ts +3 -125
- package/dist/dex/direct-router.js +244 -672
- package/dist/dex/types.d.ts +81 -0
- package/dist/dex/types.js +1 -0
- package/dist/exports/root-bundle-and-tooling.d.ts +27 -0
- package/dist/exports/root-bundle-and-tooling.js +30 -0
- package/dist/exports/root-eni-and-bsc-iro.d.ts +26 -0
- package/dist/exports/root-eni-and-bsc-iro.js +66 -0
- package/dist/exports/root-foundations.d.ts +35 -0
- package/dist/exports/root-foundations.js +70 -0
- package/dist/exports/root-swap-dex-and-xlayer.d.ts +30 -0
- package/dist/exports/root-swap-dex-and-xlayer.js +78 -0
- package/dist/flap/index.d.ts +11 -0
- package/dist/flap/index.js +9 -0
- package/dist/flows/create.d.ts +2 -1
- package/dist/flows/create.js +6 -6
- package/dist/flows/index.d.ts +9 -0
- package/dist/flows/index.js +9 -0
- package/dist/index.d.ts +20 -88
- package/dist/index.js +20 -218
- package/dist/merkle/index.d.ts +12 -0
- package/dist/merkle/index.js +11 -0
- package/dist/shared/abis/common.d.ts +2 -83
- package/dist/shared/abis/common.js +2 -254
- package/dist/shared/abis/index.d.ts +5 -6
- package/dist/shared/abis/index.js +5 -7
- package/dist/shared/clients/blockrazor.d.ts +4 -8
- package/dist/shared/clients/blockrazor.js +43 -35
- package/dist/shared/clients/club48.d.ts +2 -2
- package/dist/shared/clients/club48.js +36 -30
- package/dist/shared/clients/emitservice.js +2 -0
- package/dist/shared/clients/four.d.ts +21 -6
- package/dist/shared/clients/four.js +29 -24
- package/dist/shared/clients/index.d.ts +8 -0
- package/dist/shared/clients/index.js +8 -0
- package/dist/shared/clients/merkle.d.ts +4 -3
- package/dist/shared/clients/merkle.js +30 -47
- package/dist/shared/constants/addresses.d.ts +27 -1
- package/dist/shared/constants/addresses.js +39 -2
- package/dist/shared/constants/chains.d.ts +1 -1
- package/dist/shared/constants/chains.js +1 -1
- package/dist/shared/constants/gas.d.ts +1 -1
- package/dist/shared/constants/gas.js +2 -6
- package/dist/shared/constants/index.d.ts +4 -1
- package/dist/shared/constants/index.js +2 -1
- package/dist/shared/constants/quote.d.ts +30 -0
- package/dist/shared/constants/quote.js +37 -0
- package/dist/shared/flap/abi.js +1 -1
- package/dist/shared/flap/constants.d.ts +1 -2
- package/dist/shared/flap/constants.js +3 -4
- package/dist/shared/flap/curve.js +3 -0
- package/dist/shared/flap/errors.d.ts +1 -4
- package/dist/shared/flap/errors.js +20 -1
- package/dist/shared/flap/index.d.ts +4 -5
- package/dist/shared/flap/index.js +4 -5
- package/dist/shared/flap/launch-v6.d.ts +0 -5
- package/dist/shared/flap/launch-v6.js +2 -16
- package/dist/shared/flap/meta.d.ts +22 -18
- package/dist/shared/flap/meta.js +32 -24
- package/dist/shared/flap/permit.js +10 -3
- package/dist/shared/flap/pinata.d.ts +22 -6
- package/dist/shared/flap/pinata.js +21 -26
- package/dist/shared/flap/portal-bundle-merkle/config.d.ts +3 -72
- package/dist/shared/flap/portal-bundle-merkle/config.js +4 -124
- package/dist/shared/flap/portal-bundle-merkle/core-helpers.d.ts +32 -0
- package/dist/shared/flap/portal-bundle-merkle/core-helpers.js +83 -0
- package/dist/shared/flap/portal-bundle-merkle/core.d.ts +0 -4
- package/dist/shared/flap/portal-bundle-merkle/core.js +168 -175
- package/dist/shared/flap/portal-bundle-merkle/create-to-dex.d.ts +17 -4
- package/dist/shared/flap/portal-bundle-merkle/create-to-dex.js +96 -117
- package/dist/shared/flap/portal-bundle-merkle/curve-to-dex.js +104 -122
- package/dist/shared/flap/portal-bundle-merkle/index.d.ts +11 -7
- package/dist/shared/flap/portal-bundle-merkle/index.js +4 -7
- package/dist/shared/flap/portal-bundle-merkle/pancake-proxy.js +71 -68
- package/dist/shared/flap/portal-bundle-merkle/private.js +61 -114
- package/dist/shared/flap/portal-bundle-merkle/swap-batch.d.ts +8 -0
- package/dist/shared/flap/portal-bundle-merkle/swap-batch.js +227 -0
- package/dist/shared/flap/portal-bundle-merkle/swap-buy-first-helpers.d.ts +125 -0
- package/dist/shared/flap/portal-bundle-merkle/swap-buy-first-helpers.js +113 -0
- package/dist/shared/flap/portal-bundle-merkle/swap-buy-first.d.ts +1 -64
- package/dist/shared/flap/portal-bundle-merkle/swap-buy-first.js +69 -288
- package/dist/shared/flap/portal-bundle-merkle/swap-cross.d.ts +9 -0
- package/dist/shared/flap/portal-bundle-merkle/swap-cross.js +139 -0
- package/dist/shared/flap/portal-bundle-merkle/swap-helpers.d.ts +149 -0
- package/dist/shared/flap/portal-bundle-merkle/swap-helpers.js +259 -0
- package/dist/shared/flap/portal-bundle-merkle/swap-planning.d.ts +70 -0
- package/dist/shared/flap/portal-bundle-merkle/swap-planning.js +182 -0
- package/dist/shared/flap/portal-bundle-merkle/swap-quick-batch.d.ts +16 -0
- package/dist/shared/flap/portal-bundle-merkle/swap-quick-batch.js +327 -0
- package/dist/shared/flap/portal-bundle-merkle/swap-single.d.ts +2 -0
- package/dist/shared/flap/portal-bundle-merkle/swap-single.js +184 -0
- package/dist/shared/flap/portal-bundle-merkle/swap-types.d.ts +101 -0
- package/dist/shared/flap/portal-bundle-merkle/swap-types.js +1 -0
- package/dist/shared/flap/portal-bundle-merkle/swap.d.ts +6 -199
- package/dist/shared/flap/portal-bundle-merkle/swap.js +5 -1357
- package/dist/shared/flap/portal-bundle-merkle/types.d.ts +88 -12
- package/dist/shared/flap/portal-bundle-merkle/utils.d.ts +1 -80
- package/dist/shared/flap/portal-bundle-merkle/utils.js +145 -265
- package/dist/shared/flap/portal-bundle.js +83 -78
- package/dist/shared/flap/portal-create-token.d.ts +39 -21
- package/dist/shared/flap/portal-create-token.js +121 -124
- package/dist/shared/flap/portal.d.ts +1 -2
- package/dist/shared/flap/portal.js +36 -28
- package/dist/shared/flap/vanity.d.ts +6 -6
- package/dist/shared/flap/vanity.js +15 -21
- package/dist/shared/flap/vault.d.ts +25 -93
- package/dist/shared/flap/vault.js +77 -127
- package/dist/shared/foundation/amount/split-by-weight.d.ts +5 -0
- package/dist/shared/foundation/amount/split-by-weight.js +35 -0
- package/dist/shared/foundation/dex/v3-path.d.ts +6 -0
- package/dist/shared/foundation/dex/v3-path.js +35 -0
- package/dist/shared/foundation/erc20/decimals.d.ts +7 -0
- package/dist/shared/foundation/erc20/decimals.js +24 -0
- package/dist/shared/foundation/gas/bundle-gas.d.ts +49 -0
- package/dist/shared/foundation/gas/bundle-gas.js +93 -0
- package/dist/shared/foundation/gas/profit-hop.d.ts +20 -0
- package/dist/shared/foundation/gas/profit-hop.js +72 -0
- package/dist/shared/foundation/index.d.ts +15 -0
- package/dist/shared/foundation/index.js +14 -0
- package/dist/shared/foundation/nonce/nonce-manager.d.ts +19 -0
- package/dist/shared/foundation/nonce/nonce-manager.js +217 -0
- package/dist/shared/foundation/normalize-unknown.d.ts +9 -0
- package/dist/shared/foundation/normalize-unknown.js +29 -0
- package/dist/shared/foundation/sdk-logger.d.ts +13 -0
- package/dist/shared/foundation/sdk-logger.js +12 -0
- package/dist/shared/foundation/tx/build-request.d.ts +17 -0
- package/dist/shared/foundation/tx/build-request.js +25 -0
- package/dist/shared/foundation/tx/sign-batch.d.ts +5 -0
- package/dist/shared/foundation/tx/sign-batch.js +26 -0
- package/dist/shared/foundation/tx/wallet-sign-patch.d.ts +1 -0
- package/dist/shared/foundation/tx/wallet-sign-patch.js +18 -0
- package/dist/shared/foundation/types/airdrop-sweep.d.ts +79 -0
- package/dist/shared/foundation/types/airdrop-sweep.js +1 -0
- package/dist/shared/foundation/types/erc20.d.ts +65 -0
- package/dist/shared/foundation/types/erc20.js +1 -0
- package/dist/shared/foundation/types/holders-maker.d.ts +64 -0
- package/dist/shared/foundation/types/holders-maker.js +1 -0
- package/dist/shared/foundation/types/index.d.ts +7 -0
- package/dist/shared/foundation/types/index.js +1 -0
- package/dist/shared/foundation/types/lp-inspect.d.ts +102 -0
- package/dist/shared/foundation/types/lp-inspect.js +1 -0
- package/dist/shared/foundation/types/multicall.d.ts +5 -0
- package/dist/shared/foundation/types/multicall.js +1 -0
- package/dist/shared/foundation/types/private-sale.d.ts +35 -0
- package/dist/shared/foundation/types/private-sale.js +1 -0
- package/dist/shared/foundation/types/quote-helpers.d.ts +17 -0
- package/dist/shared/foundation/types/quote-helpers.js +1 -0
- package/dist/shared/foundation/wallet/generate.d.ts +5 -0
- package/dist/shared/foundation/wallet/generate.js +8 -0
- package/dist/shared/four/tax-token.d.ts +1 -1
- package/dist/shared/four/tax-token.js +31 -10
- package/dist/shared/index.d.ts +6 -0
- package/dist/shared/index.js +4 -0
- package/dist/types/errors.d.ts +27 -0
- package/dist/types/errors.js +34 -0
- package/dist/utils/airdrop-sweep.d.ts +4 -76
- package/dist/utils/airdrop-sweep.js +42 -55
- package/dist/utils/bundle-helpers.d.ts +9 -243
- package/dist/utils/bundle-helpers.js +10 -584
- package/dist/utils/constants.d.ts +5 -61
- package/dist/utils/constants.js +5 -80
- package/dist/utils/contract-factory.d.ts +2 -4
- package/dist/utils/contract-factory.js +25 -18
- package/dist/utils/erc20.d.ts +7 -89
- package/dist/utils/erc20.js +98 -129
- package/dist/utils/errors.d.ts +12 -1
- package/dist/utils/errors.js +60 -1
- package/dist/utils/holders-maker/addresses.d.ts +12 -0
- package/dist/utils/holders-maker/addresses.js +15 -0
- package/dist/utils/holders-maker/buy-tx.d.ts +44 -0
- package/dist/utils/holders-maker/buy-tx.js +278 -0
- package/dist/utils/holders-maker/constants.d.ts +6 -0
- package/dist/utils/holders-maker/constants.js +7 -0
- package/dist/utils/holders-maker/disperse.d.ts +18 -0
- package/dist/utils/holders-maker/disperse.js +90 -0
- package/dist/utils/holders-maker/routing.d.ts +4 -0
- package/dist/utils/holders-maker/routing.js +45 -0
- package/dist/utils/holders-maker/transfer-tx.d.ts +4 -0
- package/dist/utils/holders-maker/transfer-tx.js +67 -0
- package/dist/utils/holders-maker-helpers.d.ts +9 -0
- package/dist/utils/holders-maker-helpers.js +9 -0
- package/dist/utils/holders-maker.d.ts +2 -138
- package/dist/utils/holders-maker.js +50 -671
- package/dist/utils/hop-chains.d.ts +35 -0
- package/dist/utils/hop-chains.js +215 -0
- package/dist/utils/lp-inspect-helpers.d.ts +9 -0
- package/dist/utils/lp-inspect-helpers.js +109 -0
- package/dist/utils/lp-inspect.d.ts +2 -112
- package/dist/utils/lp-inspect.js +78 -293
- package/dist/utils/mpcExclusive.d.ts +2 -5
- package/dist/utils/mpcExclusive.js +4 -3
- package/dist/utils/private-sale.d.ts +2 -58
- package/dist/utils/private-sale.js +4 -15
- package/dist/utils/provider-factory.d.ts +4 -0
- package/dist/utils/provider-factory.js +10 -0
- package/dist/utils/quote-helpers.d.ts +4 -45
- package/dist/utils/quote-helpers.js +17 -74
- package/dist/utils/stealth-transfer.d.ts +2 -28
- package/dist/utils/stealth-transfer.js +39 -19
- package/dist/utils/swap-helpers.d.ts +2 -15
- package/dist/utils/swap-helpers.js +6 -11
- package/dist/utils/types/airdrop-sweep.d.ts +1 -0
- package/dist/utils/types/airdrop-sweep.js +1 -0
- package/dist/utils/types/contract-factory.d.ts +1 -0
- package/dist/utils/types/contract-factory.js +1 -0
- package/dist/utils/types/erc20.d.ts +1 -0
- package/dist/utils/types/erc20.js +1 -0
- package/dist/utils/types/errors.d.ts +1 -0
- package/dist/utils/types/errors.js +1 -0
- package/dist/utils/types/holders-maker.d.ts +1 -0
- package/dist/utils/types/holders-maker.js +1 -0
- package/dist/utils/types/hop-chains.d.ts +8 -0
- package/dist/utils/types/hop-chains.js +1 -0
- package/dist/utils/types/index.d.ts +13 -0
- package/dist/utils/types/index.js +1 -0
- package/dist/utils/types/lp-inspect.d.ts +1 -0
- package/dist/utils/types/lp-inspect.js +1 -0
- package/dist/utils/types/mpc-exclusive.d.ts +5 -0
- package/dist/utils/types/mpc-exclusive.js +1 -0
- package/dist/utils/types/private-sale.d.ts +1 -0
- package/dist/utils/types/private-sale.js +1 -0
- package/dist/utils/types/quote-helpers.d.ts +1 -0
- package/dist/utils/types/quote-helpers.js +1 -0
- package/dist/utils/types/stealth-transfer.d.ts +44 -0
- package/dist/utils/types/stealth-transfer.js +1 -0
- package/dist/utils/types/wallet.d.ts +25 -0
- package/dist/utils/types/wallet.js +1 -0
- package/dist/utils/wallet.d.ts +4 -25
- package/dist/utils/wallet.js +27 -22
- package/dist/vanity/index.d.ts +5 -0
- package/dist/vanity/index.js +5 -0
- package/package.json +100 -2
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { ethers, Wallet } from 'ethers';
|
|
1
|
+
import { ethers, Wallet, JsonRpcProvider } from 'ethers';
|
|
2
2
|
import { MerkleClient } from '../../clients/merkle.js';
|
|
3
3
|
import { getOptimizedGasPrice, buildProfitHopTransactions, PROFIT_HOP_COUNT } from '../../../utils/bundle-helpers.js';
|
|
4
4
|
import { FLAP_PORTAL_ADDRESSES } from '../constants.js';
|
|
5
|
-
import { ZERO_ADDRESS } from '../../../
|
|
5
|
+
import { ZERO_ADDRESS } from '../../../shared/constants/index.js';
|
|
6
6
|
import { GAS_LIMITS, CHAINS } from '../../constants/index.js';
|
|
7
|
-
import { CHAIN_ID_MAP, PORTAL_ABI, getTxType, getGasPriceConfig, shouldExtractProfit, calculateProfit, calculateBatchProfit, getProfitRecipient, getBribeAmount, BLOCKRAZOR_BUILDER_EOA } from './config.js';
|
|
7
|
+
import { CHAIN_ID_MAP, PORTAL_ABI, getTxType, getGasPriceConfig, shouldExtractProfit, calculateProfit, calculateBatchProfit, getProfitRecipient, getBribeAmount, BLOCKRAZOR_BUILDER_EOA, } from './config.js';
|
|
8
8
|
const DEFAULT_GAS_LIMIT = 800000;
|
|
9
9
|
/**
|
|
10
10
|
* 私有购买(单笔)(Merkle 版本)
|
|
@@ -16,8 +16,8 @@ export async function flapPrivateBuyMerkle(params) {
|
|
|
16
16
|
const portalAddr = FLAP_PORTAL_ADDRESSES[chain];
|
|
17
17
|
const originalAmountWei = ethers.parseEther(amountIn);
|
|
18
18
|
// ✅ 利润提取配置
|
|
19
|
-
const extractProfit = shouldExtractProfit(
|
|
20
|
-
const { actualAmountWei, profitWei } = splitBuyAmount(originalAmountWei, extractProfit
|
|
19
|
+
const extractProfit = shouldExtractProfit();
|
|
20
|
+
const { actualAmountWei, profitWei } = splitBuyAmount(originalAmountWei, extractProfit);
|
|
21
21
|
const minAmountOut = parseMinOutput(minOutputAmount);
|
|
22
22
|
const portal = new ethers.Contract(portalAddr, PORTAL_ABI, wallet);
|
|
23
23
|
// ✅ 并行获取 gasPrice、nonce 和构建未签名交易
|
|
@@ -31,7 +31,7 @@ export async function flapPrivateBuyMerkle(params) {
|
|
|
31
31
|
inputAmount: actualAmountWei,
|
|
32
32
|
minOutputAmount: minAmountOut,
|
|
33
33
|
permitData: '0x',
|
|
34
|
-
}, { value: actualAmountWei })
|
|
34
|
+
}, { value: actualAmountWei }),
|
|
35
35
|
]);
|
|
36
36
|
const gasLimit = resolveGasLimit(config.gasLimitMultiplier);
|
|
37
37
|
// ✅ 获取贿赂金额
|
|
@@ -55,7 +55,7 @@ export async function flapPrivateBuyMerkle(params) {
|
|
|
55
55
|
gasPrice,
|
|
56
56
|
gasLimit: GAS_LIMITS.BRIBE,
|
|
57
57
|
chainId,
|
|
58
|
-
type: txType
|
|
58
|
+
type: txType,
|
|
59
59
|
}));
|
|
60
60
|
}
|
|
61
61
|
// 买入交易
|
|
@@ -67,7 +67,7 @@ export async function flapPrivateBuyMerkle(params) {
|
|
|
67
67
|
gasPrice,
|
|
68
68
|
chainId,
|
|
69
69
|
type: txType,
|
|
70
|
-
value: actualAmountWei
|
|
70
|
+
value: actualAmountWei,
|
|
71
71
|
}));
|
|
72
72
|
// ✅ 并行签名完成后按顺序返回
|
|
73
73
|
const signedTxs = await Promise.all(signPromises);
|
|
@@ -83,7 +83,7 @@ export async function flapPrivateBuyMerkle(params) {
|
|
|
83
83
|
gasPrice,
|
|
84
84
|
chainId,
|
|
85
85
|
txType,
|
|
86
|
-
startNonce: profitNonce
|
|
86
|
+
startNonce: profitNonce,
|
|
87
87
|
});
|
|
88
88
|
signedTxs.push(...profitHopResult.signedTransactions);
|
|
89
89
|
profitHopWallets = profitHopResult.hopWallets; // ✅ 收集利润多跳钱包
|
|
@@ -112,7 +112,7 @@ export async function flapPrivateSellMerkle(params) {
|
|
|
112
112
|
inputAmount: amountWei,
|
|
113
113
|
minOutputAmount: 0n, // ✅ 已移除滑点保护
|
|
114
114
|
permitData: '0x',
|
|
115
|
-
})
|
|
115
|
+
}),
|
|
116
116
|
]);
|
|
117
117
|
const gasLimit = resolveGasLimit(config.gasLimitMultiplier);
|
|
118
118
|
const txType = getTxType(config);
|
|
@@ -120,10 +120,8 @@ export async function flapPrivateSellMerkle(params) {
|
|
|
120
120
|
const bribeAmount = getBribeAmount(config);
|
|
121
121
|
const needBribeTx = bribeAmount > 0n;
|
|
122
122
|
// ✅ 利润计算
|
|
123
|
-
const extractProfit = shouldExtractProfit(
|
|
124
|
-
const { profit: profitWei } = extractProfit && quotedOutput > 0n
|
|
125
|
-
? calculateProfit(quotedOutput, config)
|
|
126
|
-
: { profit: 0n };
|
|
123
|
+
const extractProfit = shouldExtractProfit();
|
|
124
|
+
const { profit: profitWei } = extractProfit && quotedOutput > 0n ? calculateProfit(quotedOutput) : { profit: 0n };
|
|
127
125
|
const needProfitTx = extractProfit && profitWei > 0n;
|
|
128
126
|
// ✅ 分配 nonces:贿赂 → 卖出 → 利润
|
|
129
127
|
let nonceIdx = 0;
|
|
@@ -141,7 +139,7 @@ export async function flapPrivateSellMerkle(params) {
|
|
|
141
139
|
gasPrice,
|
|
142
140
|
gasLimit: GAS_LIMITS.BRIBE,
|
|
143
141
|
chainId,
|
|
144
|
-
type: txType
|
|
142
|
+
type: txType,
|
|
145
143
|
}));
|
|
146
144
|
}
|
|
147
145
|
// 卖出交易
|
|
@@ -152,7 +150,7 @@ export async function flapPrivateSellMerkle(params) {
|
|
|
152
150
|
gasLimit,
|
|
153
151
|
gasPrice,
|
|
154
152
|
chainId,
|
|
155
|
-
type: txType
|
|
153
|
+
type: txType,
|
|
156
154
|
}));
|
|
157
155
|
// ✅ 并行签名完成后按顺序返回
|
|
158
156
|
const signedTxs = await Promise.all(signPromises);
|
|
@@ -168,7 +166,7 @@ export async function flapPrivateSellMerkle(params) {
|
|
|
168
166
|
gasPrice,
|
|
169
167
|
chainId,
|
|
170
168
|
txType,
|
|
171
|
-
startNonce: profitNonce
|
|
169
|
+
startNonce: profitNonce,
|
|
172
170
|
});
|
|
173
171
|
signedTxs.push(...profitHopResult.signedTransactions);
|
|
174
172
|
profitHopWallets = profitHopResult.hopWallets; // ✅ 收集利润多跳钱包
|
|
@@ -185,15 +183,15 @@ export async function flapBatchPrivateBuyMerkle(params) {
|
|
|
185
183
|
}
|
|
186
184
|
const { chainId, provider } = createMerkleContext(chain, config);
|
|
187
185
|
const portalAddr = FLAP_PORTAL_ADDRESSES[chain];
|
|
188
|
-
const wallets = privateKeys.map(k => new Wallet(k, provider));
|
|
189
|
-
const originalAmountsWei = amountsIn.map(a => ethers.parseEther(a));
|
|
186
|
+
const wallets = privateKeys.map((k) => new Wallet(k, provider));
|
|
187
|
+
const originalAmountsWei = amountsIn.map((a) => ethers.parseEther(a));
|
|
190
188
|
// ✅ 利润提取配置
|
|
191
|
-
const extractProfit = shouldExtractProfit(
|
|
192
|
-
const { totalProfit, remainingAmounts } = calculateBatchProfit(originalAmountsWei
|
|
189
|
+
const extractProfit = shouldExtractProfit();
|
|
190
|
+
const { totalProfit, remainingAmounts } = calculateBatchProfit(originalAmountsWei);
|
|
193
191
|
const actualAmountsWei = remainingAmounts;
|
|
194
192
|
const maxFundsIndex = findMaxIndex(originalAmountsWei);
|
|
195
193
|
const minOuts = resolveBatchMinOutputs(minOutputAmounts, wallets.length);
|
|
196
|
-
const portals = wallets.map(w => new ethers.Contract(portalAddr, PORTAL_ABI, w));
|
|
194
|
+
const portals = wallets.map((w) => new ethers.Contract(portalAddr, PORTAL_ABI, w));
|
|
197
195
|
// ✅ 获取贿赂金额
|
|
198
196
|
const bribeAmount = getBribeAmount(config);
|
|
199
197
|
const needBribeTx = bribeAmount > 0n;
|
|
@@ -202,14 +200,14 @@ export async function flapBatchPrivateBuyMerkle(params) {
|
|
|
202
200
|
const [gasPrice, initialNonces, unsignedList] = await Promise.all([
|
|
203
201
|
getOptimizedGasPrice(provider, getGasPriceConfig(config)),
|
|
204
202
|
// ✅ 使用 pending nonce,避免 xLayer 等链上“已有 pending 交易”导致 nonce too low
|
|
205
|
-
Promise.all(wallets.map(w => provider.getTransactionCount(w.address, 'pending'))),
|
|
203
|
+
Promise.all(wallets.map((w) => provider.getTransactionCount(w.address, 'pending'))),
|
|
206
204
|
Promise.all(portals.map((portal, i) => portal.swapExactInput.populateTransaction({
|
|
207
205
|
inputToken: ZERO_ADDRESS,
|
|
208
206
|
outputToken: tokenAddress,
|
|
209
207
|
inputAmount: actualAmountsWei[i],
|
|
210
208
|
minOutputAmount: minOuts[i],
|
|
211
209
|
permitData: '0x',
|
|
212
|
-
}, { value: actualAmountsWei[i] })))
|
|
210
|
+
}, { value: actualAmountsWei[i] }))),
|
|
213
211
|
]);
|
|
214
212
|
// ✅ 分配 nonces:贿赂(可选) → 买入 → 利润(可选)
|
|
215
213
|
let payerNonceOffset = 0;
|
|
@@ -224,9 +222,7 @@ export async function flapBatchPrivateBuyMerkle(params) {
|
|
|
224
222
|
}
|
|
225
223
|
return n;
|
|
226
224
|
});
|
|
227
|
-
const profitNonce = needProfitTx && maxFundsIndex >= 0
|
|
228
|
-
? initialNonces[maxFundsIndex] + payerNonceOffset + 1
|
|
229
|
-
: undefined;
|
|
225
|
+
const profitNonce = needProfitTx && maxFundsIndex >= 0 ? initialNonces[maxFundsIndex] + payerNonceOffset + 1 : undefined;
|
|
230
226
|
const gasLimit = resolveGasLimit(config.gasLimitMultiplier);
|
|
231
227
|
const gasLimits = new Array(wallets.length).fill(gasLimit);
|
|
232
228
|
const signedTxs = [];
|
|
@@ -239,7 +235,7 @@ export async function flapBatchPrivateBuyMerkle(params) {
|
|
|
239
235
|
gasPrice,
|
|
240
236
|
gasLimit: GAS_LIMITS.BRIBE,
|
|
241
237
|
chainId,
|
|
242
|
-
type: getTxType(config)
|
|
238
|
+
type: getTxType(config),
|
|
243
239
|
});
|
|
244
240
|
signedTxs.push(bribeTx);
|
|
245
241
|
}
|
|
@@ -252,7 +248,7 @@ export async function flapBatchPrivateBuyMerkle(params) {
|
|
|
252
248
|
gasPrice,
|
|
253
249
|
chainId,
|
|
254
250
|
config,
|
|
255
|
-
values: actualAmountsWei
|
|
251
|
+
values: actualAmountsWei,
|
|
256
252
|
});
|
|
257
253
|
signedTxs.push(...signedList);
|
|
258
254
|
// ✅ 利润多跳转账(强制 2 跳中转)
|
|
@@ -267,7 +263,7 @@ export async function flapBatchPrivateBuyMerkle(params) {
|
|
|
267
263
|
gasPrice,
|
|
268
264
|
chainId,
|
|
269
265
|
txType: getTxType(config),
|
|
270
|
-
startNonce: profitNonce
|
|
266
|
+
startNonce: profitNonce,
|
|
271
267
|
});
|
|
272
268
|
signedTxs.push(...profitHopResult.signedTransactions);
|
|
273
269
|
profitHopWallets = profitHopResult.hopWallets; // ✅ 收集利润多跳钱包
|
|
@@ -278,37 +274,39 @@ export async function flapBatchPrivateBuyMerkle(params) {
|
|
|
278
274
|
* 批量私有卖出(Merkle 版本)
|
|
279
275
|
*/
|
|
280
276
|
export async function flapBatchPrivateSellMerkle(params) {
|
|
281
|
-
const { chain, privateKeys, amounts, tokenAddress,
|
|
277
|
+
const { chain, privateKeys, amounts, tokenAddress, config } = params;
|
|
282
278
|
if (privateKeys.length !== amounts.length) {
|
|
283
279
|
throw new Error('privateKeys and amounts length mismatch');
|
|
284
280
|
}
|
|
285
281
|
const { chainId, provider } = createMerkleContext(chain, config);
|
|
286
282
|
const portalAddr = FLAP_PORTAL_ADDRESSES[chain];
|
|
287
|
-
const wallets = privateKeys.map(k => new Wallet(k, provider));
|
|
288
|
-
const amountsWei = amounts.map(a => ethers.parseUnits(a, 18));
|
|
283
|
+
const wallets = privateKeys.map((k) => new Wallet(k, provider));
|
|
284
|
+
const amountsWei = amounts.map((a) => ethers.parseUnits(a, 18));
|
|
289
285
|
const portal = new ethers.Contract(portalAddr, PORTAL_ABI, provider);
|
|
290
|
-
const portals = wallets.map(w => new ethers.Contract(portalAddr, PORTAL_ABI, w));
|
|
286
|
+
const portals = wallets.map((w) => new ethers.Contract(portalAddr, PORTAL_ABI, w));
|
|
291
287
|
// ✅ 并行获取 gasPrice、所有 nonces、所有报价和构建未签名交易
|
|
292
288
|
const [gasPrice, initialNonces, quotedOutputs, unsignedList] = await Promise.all([
|
|
293
289
|
getOptimizedGasPrice(provider, getGasPriceConfig(config)),
|
|
294
290
|
// ✅ 使用 pending nonce,避免 xLayer 等链上“已有 pending 交易”导致 nonce too low
|
|
295
|
-
Promise.all(wallets.map(w => provider.getTransactionCount(w.address, 'pending'))),
|
|
296
|
-
Promise.all(amountsWei.map(amount => portal.quoteExactInput
|
|
291
|
+
Promise.all(wallets.map((w) => provider.getTransactionCount(w.address, 'pending'))),
|
|
292
|
+
Promise.all(amountsWei.map((amount) => portal.quoteExactInput
|
|
293
|
+
.staticCall({
|
|
297
294
|
inputToken: tokenAddress,
|
|
298
295
|
outputToken: ZERO_ADDRESS,
|
|
299
|
-
inputAmount: amount
|
|
300
|
-
})
|
|
296
|
+
inputAmount: amount,
|
|
297
|
+
})
|
|
298
|
+
.catch(() => 0n))),
|
|
301
299
|
// ✅ 并行构建未签名交易(已移除滑点保护:minOuts 固定为 0)
|
|
302
300
|
Promise.all(portals.map((p, i) => p.swapExactInput.populateTransaction({
|
|
303
301
|
inputToken: tokenAddress,
|
|
304
302
|
outputToken: ZERO_ADDRESS,
|
|
305
303
|
inputAmount: amountsWei[i],
|
|
306
304
|
minOutputAmount: 0n,
|
|
307
|
-
permitData: '0x'
|
|
308
|
-
})))
|
|
305
|
+
permitData: '0x',
|
|
306
|
+
}))),
|
|
309
307
|
]);
|
|
310
|
-
const extractProfit = shouldExtractProfit(
|
|
311
|
-
const { totalProfit, maxRevenueIndex } = summarizeSellProfits(quotedOutputs, extractProfit
|
|
308
|
+
const extractProfit = shouldExtractProfit();
|
|
309
|
+
const { totalProfit, maxRevenueIndex } = summarizeSellProfits(quotedOutputs, extractProfit);
|
|
312
310
|
// ✅ 获取贿赂金额
|
|
313
311
|
const bribeAmount = getBribeAmount(config);
|
|
314
312
|
const needBribeTx = bribeAmount > 0n;
|
|
@@ -326,9 +324,7 @@ export async function flapBatchPrivateSellMerkle(params) {
|
|
|
326
324
|
}
|
|
327
325
|
return n;
|
|
328
326
|
});
|
|
329
|
-
const profitNonce = needProfitTx && maxRevenueIndex >= 0
|
|
330
|
-
? initialNonces[maxRevenueIndex] + payerNonceOffset + 1
|
|
331
|
-
: undefined;
|
|
327
|
+
const profitNonce = needProfitTx && maxRevenueIndex >= 0 ? initialNonces[maxRevenueIndex] + payerNonceOffset + 1 : undefined;
|
|
332
328
|
const gasLimit = resolveGasLimit(config.gasLimitMultiplier);
|
|
333
329
|
const gasLimits = new Array(wallets.length).fill(gasLimit);
|
|
334
330
|
const signedTxs = [];
|
|
@@ -341,7 +337,7 @@ export async function flapBatchPrivateSellMerkle(params) {
|
|
|
341
337
|
gasPrice,
|
|
342
338
|
gasLimit: GAS_LIMITS.BRIBE,
|
|
343
339
|
chainId,
|
|
344
|
-
type: getTxType(config)
|
|
340
|
+
type: getTxType(config),
|
|
345
341
|
});
|
|
346
342
|
signedTxs.push(bribeTx);
|
|
347
343
|
}
|
|
@@ -353,7 +349,7 @@ export async function flapBatchPrivateSellMerkle(params) {
|
|
|
353
349
|
gasLimits,
|
|
354
350
|
gasPrice,
|
|
355
351
|
chainId,
|
|
356
|
-
config
|
|
352
|
+
config,
|
|
357
353
|
});
|
|
358
354
|
signedTxs.push(...signedList);
|
|
359
355
|
// ✅ 利润多跳转账(强制 2 跳中转)
|
|
@@ -368,7 +364,7 @@ export async function flapBatchPrivateSellMerkle(params) {
|
|
|
368
364
|
gasPrice,
|
|
369
365
|
chainId,
|
|
370
366
|
txType: getTxType(config),
|
|
371
|
-
startNonce: profitNonce
|
|
367
|
+
startNonce: profitNonce,
|
|
372
368
|
});
|
|
373
369
|
signedTxs.push(...profitHopResult.signedTransactions);
|
|
374
370
|
profitHopWallets = profitHopResult.hopWallets; // ✅ 收集利润多跳钱包
|
|
@@ -385,28 +381,27 @@ function createMerkleContext(chain, config) {
|
|
|
385
381
|
if (!config.customRpcUrl) {
|
|
386
382
|
throw new Error(`Chain ${chain} (chainId: ${chainId}) does not support Merkle bundle service. Please provide customRpcUrl.`);
|
|
387
383
|
}
|
|
388
|
-
const { JsonRpcProvider } = require('ethers');
|
|
389
|
-
// ✅ 禁用 ENS: 避免 "network does not support ENS" 错误
|
|
390
384
|
return {
|
|
391
385
|
chainId,
|
|
392
|
-
|
|
386
|
+
// ✅ 禁用 ENS: 避免 "network does not support ENS" 错误
|
|
387
|
+
provider: new JsonRpcProvider(config.customRpcUrl, { chainId, name: chain.toLowerCase(), ensAddress: undefined }),
|
|
393
388
|
};
|
|
394
389
|
}
|
|
395
390
|
const merkle = new MerkleClient({
|
|
396
391
|
apiKey: config.apiKey,
|
|
397
392
|
chainId: chainId, // 类型断言为 Merkle 支持的 chainId
|
|
398
|
-
customRpcUrl: config.customRpcUrl
|
|
393
|
+
customRpcUrl: config.customRpcUrl,
|
|
399
394
|
});
|
|
400
395
|
return {
|
|
401
396
|
chainId,
|
|
402
|
-
provider: merkle.getProvider()
|
|
397
|
+
provider: merkle.getProvider(),
|
|
403
398
|
};
|
|
404
399
|
}
|
|
405
|
-
function splitBuyAmount(amount, extractProfit
|
|
400
|
+
function splitBuyAmount(amount, extractProfit) {
|
|
406
401
|
if (!extractProfit) {
|
|
407
402
|
return { actualAmountWei: amount, profitWei: 0n };
|
|
408
403
|
}
|
|
409
|
-
const { remaining, profit } = calculateProfit(amount
|
|
404
|
+
const { remaining, profit } = calculateProfit(amount);
|
|
410
405
|
return { actualAmountWei: remaining, profitWei: profit };
|
|
411
406
|
}
|
|
412
407
|
function parseMinOutput(value) {
|
|
@@ -419,83 +414,35 @@ function resolveGasLimit(multiplier, defaultGas = DEFAULT_GAS_LIMIT) {
|
|
|
419
414
|
const factor = multiplier ?? 1.0;
|
|
420
415
|
return BigInt(Math.ceil(defaultGas * factor));
|
|
421
416
|
}
|
|
422
|
-
/**
|
|
423
|
-
* 追加利润多跳转账交易(强制 2 跳中转)
|
|
424
|
-
*/
|
|
425
|
-
async function appendSingleProfitTransfer({ extractProfit, profitWei, wallet, baseNonce, provider, gasPrice, chainId, config, signedTxs }) {
|
|
426
|
-
if (!extractProfit || profitWei === 0n) {
|
|
427
|
-
return undefined;
|
|
428
|
-
}
|
|
429
|
-
const profitHopResult = await buildProfitHopTransactions({
|
|
430
|
-
provider,
|
|
431
|
-
payerWallet: wallet,
|
|
432
|
-
profitAmount: profitWei,
|
|
433
|
-
profitRecipient: getProfitRecipient(),
|
|
434
|
-
hopCount: PROFIT_HOP_COUNT,
|
|
435
|
-
gasPrice,
|
|
436
|
-
chainId,
|
|
437
|
-
txType: getTxType(config),
|
|
438
|
-
startNonce: baseNonce + 1
|
|
439
|
-
});
|
|
440
|
-
signedTxs.push(...profitHopResult.signedTransactions);
|
|
441
|
-
return profitHopResult.hopWallets; // ✅ 返回利润多跳钱包
|
|
442
|
-
}
|
|
443
417
|
async function resolveSingleSellOutputs(portal, tokenAddress, amountWei, minOutputAmount) {
|
|
444
418
|
if (minOutputAmount !== undefined) {
|
|
445
|
-
const minOut = typeof minOutputAmount === 'string'
|
|
446
|
-
? ethers.parseEther(minOutputAmount)
|
|
447
|
-
: minOutputAmount;
|
|
419
|
+
const minOut = typeof minOutputAmount === 'string' ? ethers.parseEther(minOutputAmount) : minOutputAmount;
|
|
448
420
|
return {
|
|
449
421
|
quotedOutput: minOut,
|
|
450
|
-
minOut
|
|
422
|
+
minOut,
|
|
451
423
|
};
|
|
452
424
|
}
|
|
453
425
|
try {
|
|
454
426
|
const quotedOutput = await portal.quoteExactInput.staticCall({
|
|
455
427
|
inputToken: tokenAddress,
|
|
456
428
|
outputToken: ZERO_ADDRESS,
|
|
457
|
-
inputAmount: amountWei
|
|
429
|
+
inputAmount: amountWei,
|
|
458
430
|
});
|
|
459
431
|
return {
|
|
460
432
|
quotedOutput,
|
|
461
|
-
minOut: 0n // ✅ 已移除滑点保护:minOut 固定为 0
|
|
433
|
+
minOut: 0n, // ✅ 已移除滑点保护:minOut 固定为 0
|
|
462
434
|
};
|
|
463
435
|
}
|
|
464
436
|
catch {
|
|
465
437
|
return {
|
|
466
438
|
quotedOutput: 0n,
|
|
467
|
-
minOut: 0n
|
|
439
|
+
minOut: 0n,
|
|
468
440
|
};
|
|
469
441
|
}
|
|
470
442
|
}
|
|
471
|
-
/**
|
|
472
|
-
* 追加卖出利润多跳转账交易(强制 2 跳中转)
|
|
473
|
-
*/
|
|
474
|
-
async function appendSingleSellProfitTransfer({ extractProfit, quotedOutput, wallet, baseNonce, provider, gasPrice, chainId, config, signedTxs }) {
|
|
475
|
-
if (!extractProfit || quotedOutput <= 0n) {
|
|
476
|
-
return undefined;
|
|
477
|
-
}
|
|
478
|
-
const { profit } = calculateProfit(quotedOutput, config);
|
|
479
|
-
if (profit === 0n) {
|
|
480
|
-
return undefined;
|
|
481
|
-
}
|
|
482
|
-
const profitHopResult = await buildProfitHopTransactions({
|
|
483
|
-
provider,
|
|
484
|
-
payerWallet: wallet,
|
|
485
|
-
profitAmount: profit,
|
|
486
|
-
profitRecipient: getProfitRecipient(),
|
|
487
|
-
hopCount: PROFIT_HOP_COUNT,
|
|
488
|
-
gasPrice,
|
|
489
|
-
chainId,
|
|
490
|
-
txType: getTxType(config),
|
|
491
|
-
startNonce: baseNonce + 1
|
|
492
|
-
});
|
|
493
|
-
signedTxs.push(...profitHopResult.signedTransactions);
|
|
494
|
-
return profitHopResult.hopWallets; // ✅ 返回利润多跳钱包
|
|
495
|
-
}
|
|
496
443
|
function resolveBatchMinOutputs(minOutputAmounts, walletCount) {
|
|
497
444
|
if (minOutputAmounts && minOutputAmounts.length === walletCount) {
|
|
498
|
-
return minOutputAmounts.map(m => typeof m === 'string' ? ethers.parseUnits(m, 18) : m);
|
|
445
|
+
return minOutputAmounts.map((m) => (typeof m === 'string' ? ethers.parseUnits(m, 18) : m));
|
|
499
446
|
}
|
|
500
447
|
return new Array(walletCount).fill(0n);
|
|
501
448
|
}
|
|
@@ -513,9 +460,9 @@ function findMaxIndex(values) {
|
|
|
513
460
|
}
|
|
514
461
|
return maxIndex;
|
|
515
462
|
}
|
|
516
|
-
async function signBatchTransactions({ unsignedList, wallets, nonces, gasLimits, gasPrice, chainId, config, values }) {
|
|
463
|
+
async function signBatchTransactions({ unsignedList, wallets, nonces, gasLimits, gasPrice, chainId, config, values, }) {
|
|
517
464
|
return await Promise.all(unsignedList.map((unsigned, i) => {
|
|
518
|
-
const value = values ? values[i] : unsigned.value;
|
|
465
|
+
const value = values ? values[i] : (unsigned.value ?? 0n);
|
|
519
466
|
return wallets[i].signTransaction({
|
|
520
467
|
...unsigned,
|
|
521
468
|
from: wallets[i].address,
|
|
@@ -524,11 +471,11 @@ async function signBatchTransactions({ unsignedList, wallets, nonces, gasLimits,
|
|
|
524
471
|
gasPrice,
|
|
525
472
|
chainId,
|
|
526
473
|
type: getTxType(config),
|
|
527
|
-
value
|
|
474
|
+
value,
|
|
528
475
|
});
|
|
529
476
|
}));
|
|
530
477
|
}
|
|
531
|
-
function summarizeSellProfits(quotedOutputs, extractProfit
|
|
478
|
+
function summarizeSellProfits(quotedOutputs, extractProfit) {
|
|
532
479
|
let totalProfit = 0n;
|
|
533
480
|
let maxRevenueIndex = -1;
|
|
534
481
|
let maxRevenue = 0n;
|
|
@@ -536,7 +483,7 @@ function summarizeSellProfits(quotedOutputs, extractProfit, config) {
|
|
|
536
483
|
for (let i = 0; i < quotedOutputs.length; i++) {
|
|
537
484
|
const quoted = quotedOutputs[i];
|
|
538
485
|
if (quoted > 0n) {
|
|
539
|
-
const { profit } = calculateProfit(quoted
|
|
486
|
+
const { profit } = calculateProfit(quoted);
|
|
540
487
|
totalProfit += profit;
|
|
541
488
|
if (quoted > maxRevenue) {
|
|
542
489
|
maxRevenue = quoted;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { FlapBatchSwapSignParams, FlapBatchSwapResult } from './swap-types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Flap 内盘批量换手(一卖多买)
|
|
4
|
+
*
|
|
5
|
+
* 功能:主钱包一次卖出 → 多个子钱包同时买入 → 在同一个区块中完成
|
|
6
|
+
* 限制:最多 24 个买方(服务器限制 25 笔交易,包含 1 笔利润交易)
|
|
7
|
+
*/
|
|
8
|
+
export declare function flapBatchSwapMerkle(params: FlapBatchSwapSignParams): Promise<FlapBatchSwapResult>;
|
|
@@ -0,0 +1,227 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* swap-batch - 一卖多买批量换手
|
|
3
|
+
*/
|
|
4
|
+
import { ethers, Contract, Wallet } from 'ethers';
|
|
5
|
+
import { calculateSellAmount } from '../../../utils/swap-helpers.js';
|
|
6
|
+
import { NonceManager, getOptimizedGasPrice } from '../../../utils/bundle-helpers.js';
|
|
7
|
+
import { ZERO_ADDRESS } from '../../../shared/constants/index.js';
|
|
8
|
+
import { getGasPriceConfig, getTxType, getBribeAmount, BLOCKRAZOR_BUILDER_EOA, PORTAL_ABI, } from './config.js';
|
|
9
|
+
import { buildTransactionRequest } from '../../foundation/tx/build-request.js';
|
|
10
|
+
import { BRIBE_GAS_LIMIT, ERC20_BALANCE_OF_ABI, getGasLimit, getTokenToNativeQuote, } from './swap-helpers.js';
|
|
11
|
+
import { buildApprovalTransaction, buildProfitTransaction, calculateProfitAmount, createChainContext, quoteSellOutput, } from './swap-planning.js';
|
|
12
|
+
/**
|
|
13
|
+
* Flap 内盘批量换手(一卖多买)
|
|
14
|
+
*
|
|
15
|
+
* 功能:主钱包一次卖出 → 多个子钱包同时买入 → 在同一个区块中完成
|
|
16
|
+
* 限制:最多 24 个买方(服务器限制 25 笔交易,包含 1 笔利润交易)
|
|
17
|
+
*/
|
|
18
|
+
export async function flapBatchSwapMerkle(params) {
|
|
19
|
+
const { chain, sellerPrivateKey, sellAmount, sellPercentage, buyerPrivateKeys, tokenAddress, config, quoteToken, quoteTokenDecimals = 18, startNonces, // ✅ 可选:前端预获取的 nonces
|
|
20
|
+
} = params;
|
|
21
|
+
// ✅ 校验买方数量(最多 24 个)
|
|
22
|
+
const MAX_BUYERS = 24;
|
|
23
|
+
if (buyerPrivateKeys.length === 0) {
|
|
24
|
+
throw new Error('至少需要一个买方钱包');
|
|
25
|
+
}
|
|
26
|
+
if (buyerPrivateKeys.length > MAX_BUYERS) {
|
|
27
|
+
throw new Error(`买方钱包数量超过限制: ${buyerPrivateKeys.length} > ${MAX_BUYERS}`);
|
|
28
|
+
}
|
|
29
|
+
const chainContext = createChainContext(chain, config);
|
|
30
|
+
const seller = new Wallet(sellerPrivateKey, chainContext.provider);
|
|
31
|
+
const buyers = buyerPrivateKeys.map((pk) => new Wallet(pk, chainContext.provider));
|
|
32
|
+
const nonceManager = new NonceManager(chainContext.provider);
|
|
33
|
+
const finalGasLimit = getGasLimit(config);
|
|
34
|
+
const txType = getTxType(config);
|
|
35
|
+
// ✅ 判断是否使用原生代币
|
|
36
|
+
const useNativeToken = !quoteToken || quoteToken === ZERO_ADDRESS;
|
|
37
|
+
const outputToken = useNativeToken ? ZERO_ADDRESS : quoteToken;
|
|
38
|
+
// ✅ 并行获取:卖出数量、gasPrice
|
|
39
|
+
const [sellAmountResult, gasPrice] = await Promise.all([
|
|
40
|
+
calculateSellAmount(chainContext.provider, tokenAddress, seller.address, sellAmount, sellPercentage),
|
|
41
|
+
getOptimizedGasPrice(chainContext.provider, getGasPriceConfig(config)),
|
|
42
|
+
]);
|
|
43
|
+
const { amount: sellAmountWei, decimals } = sellAmountResult;
|
|
44
|
+
const priorityFee = gasPrice / 10n === 0n ? 1n : gasPrice / 10n;
|
|
45
|
+
// ✅ 并行获取:授权、报价(已移除滑点保护)
|
|
46
|
+
const [approvalTx, quote] = await Promise.all([
|
|
47
|
+
config.skipApprovalCheck
|
|
48
|
+
? Promise.resolve(null)
|
|
49
|
+
: buildApprovalTransaction({
|
|
50
|
+
tokenAddress,
|
|
51
|
+
seller,
|
|
52
|
+
provider: chainContext.provider,
|
|
53
|
+
decimals,
|
|
54
|
+
portalAddress: chainContext.portalAddress,
|
|
55
|
+
chainId: chainContext.chainId,
|
|
56
|
+
config,
|
|
57
|
+
}),
|
|
58
|
+
quoteSellOutput({
|
|
59
|
+
portalAddress: chainContext.portalAddress,
|
|
60
|
+
tokenAddress,
|
|
61
|
+
sellAmountWei,
|
|
62
|
+
provider: chainContext.provider,
|
|
63
|
+
skipQuoteOnError: config.skipQuoteOnError,
|
|
64
|
+
outputToken,
|
|
65
|
+
}),
|
|
66
|
+
]);
|
|
67
|
+
// ✅ 计算每个买方的买入金额(按比例分配,已移除滑点保护)
|
|
68
|
+
const totalBuyAmount = quote.quotedNative;
|
|
69
|
+
let buyAmountsWei;
|
|
70
|
+
if (params.buyerRatios && params.buyerRatios.length === buyers.length) {
|
|
71
|
+
// 按比例分配
|
|
72
|
+
buyAmountsWei = params.buyerRatios.map((ratio) => {
|
|
73
|
+
const amount = (totalBuyAmount * BigInt(Math.round(ratio * 10000))) / 10000n;
|
|
74
|
+
return amount;
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
else {
|
|
78
|
+
// 平均分配
|
|
79
|
+
const amountPerBuyer = totalBuyAmount / BigInt(buyers.length);
|
|
80
|
+
buyAmountsWei = buyers.map(() => amountPerBuyer);
|
|
81
|
+
}
|
|
82
|
+
// ✅ 并行验证所有买方余额
|
|
83
|
+
const reserveGas = ethers.parseEther((config.reserveGasETH || 0.0005).toString());
|
|
84
|
+
const erc20Contract = useNativeToken ? null : new Contract(quoteToken, ERC20_BALANCE_OF_ABI, chainContext.provider);
|
|
85
|
+
await Promise.all(buyers.map(async (buyer, i) => {
|
|
86
|
+
const buyAmount = buyAmountsWei[i];
|
|
87
|
+
if (useNativeToken) {
|
|
88
|
+
const buyerBalance = await buyer.provider.getBalance(buyer.address);
|
|
89
|
+
const required = buyAmount + reserveGas;
|
|
90
|
+
if (buyerBalance < required) {
|
|
91
|
+
throw new Error(`买方 ${i + 1} 余额不足: 需要 ${ethers.formatEther(required)} ${chainContext.nativeToken}, 实际 ${ethers.formatEther(buyerBalance)}`);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
else {
|
|
95
|
+
const buyerBalance = await erc20Contract.balanceOf(buyer.address);
|
|
96
|
+
if (buyerBalance < buyAmount) {
|
|
97
|
+
throw new Error(`买方 ${i + 1} 代币余额不足: 需要 ${ethers.formatUnits(buyAmount, quoteTokenDecimals)}, 实际 ${ethers.formatUnits(buyerBalance, quoteTokenDecimals)}`);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
}));
|
|
101
|
+
// ✅ 计算利润(根据 userType 动态调整)
|
|
102
|
+
const tokenProfitAmount = calculateProfitAmount(quote.quotedNative, config.userType);
|
|
103
|
+
let nativeProfitAmount = tokenProfitAmount;
|
|
104
|
+
if (!useNativeToken && tokenProfitAmount > 0n) {
|
|
105
|
+
nativeProfitAmount = await getTokenToNativeQuote(chainContext.provider, quoteToken, tokenProfitAmount, chainContext.chainId);
|
|
106
|
+
}
|
|
107
|
+
// ✅ 并行构建所有买入交易
|
|
108
|
+
const portalSeller = new Contract(chainContext.portalAddress, PORTAL_ABI, seller);
|
|
109
|
+
const [sellUnsigned, ...buyUnsignedList] = await Promise.all([
|
|
110
|
+
// 卖出交易
|
|
111
|
+
portalSeller.swapExactInput.populateTransaction({
|
|
112
|
+
inputToken: tokenAddress,
|
|
113
|
+
outputToken,
|
|
114
|
+
inputAmount: sellAmountWei,
|
|
115
|
+
minOutputAmount: 0,
|
|
116
|
+
permitData: '0x',
|
|
117
|
+
}),
|
|
118
|
+
// 所有买入交易
|
|
119
|
+
...buyers.map((buyer, i) => {
|
|
120
|
+
const portalBuyer = new Contract(chainContext.portalAddress, PORTAL_ABI, buyer);
|
|
121
|
+
const buyAmount = buyAmountsWei[i];
|
|
122
|
+
return portalBuyer.swapExactInput.populateTransaction({
|
|
123
|
+
inputToken: outputToken,
|
|
124
|
+
outputToken: tokenAddress,
|
|
125
|
+
inputAmount: buyAmount,
|
|
126
|
+
minOutputAmount: 0,
|
|
127
|
+
permitData: '0x',
|
|
128
|
+
}, useNativeToken ? { value: buyAmount } : {});
|
|
129
|
+
}),
|
|
130
|
+
]);
|
|
131
|
+
// ✅ 并行获取所有 nonce(如果前端传入了 startNonces,直接使用)
|
|
132
|
+
const allWallets = [seller, ...buyers];
|
|
133
|
+
let sellNonce;
|
|
134
|
+
let buyerNonces;
|
|
135
|
+
if (startNonces && startNonces.length >= allWallets.length) {
|
|
136
|
+
sellNonce = startNonces[0];
|
|
137
|
+
buyerNonces = startNonces.slice(1);
|
|
138
|
+
}
|
|
139
|
+
else {
|
|
140
|
+
sellNonce = await nonceManager.getNextNonce(seller);
|
|
141
|
+
buyerNonces = await Promise.all(buyers.map((buyer) => nonceManager.getNextNonce(buyer)));
|
|
142
|
+
}
|
|
143
|
+
// ✅ 贿赂交易和利润交易都由卖方发送(保持一致)
|
|
144
|
+
const bribeAmount = getBribeAmount(config);
|
|
145
|
+
let bribeTx = null;
|
|
146
|
+
let bribeNonceOffset = 0;
|
|
147
|
+
if (bribeAmount > 0n) {
|
|
148
|
+
const bribeNonce = sellNonce; // 使用卖方的第一个 nonce
|
|
149
|
+
bribeTx = await seller.signTransaction({
|
|
150
|
+
to: BLOCKRAZOR_BUILDER_EOA,
|
|
151
|
+
value: bribeAmount,
|
|
152
|
+
nonce: bribeNonce,
|
|
153
|
+
gasPrice,
|
|
154
|
+
gasLimit: BRIBE_GAS_LIMIT,
|
|
155
|
+
chainId: chainContext.chainId,
|
|
156
|
+
type: txType,
|
|
157
|
+
});
|
|
158
|
+
bribeNonceOffset = 1; // 卖出交易的 nonce 需要 +1
|
|
159
|
+
}
|
|
160
|
+
nonceManager.clearTemp();
|
|
161
|
+
// 利润多跳交易 nonce 计算
|
|
162
|
+
const profitNonce = nativeProfitAmount > 0n ? sellNonce + bribeNonceOffset + 1 : undefined;
|
|
163
|
+
// ✅ 并行签名所有交易
|
|
164
|
+
const sellTx = buildTransactionRequest(sellUnsigned, {
|
|
165
|
+
from: seller.address,
|
|
166
|
+
nonce: sellNonce + bribeNonceOffset, // ✅ 考虑贿赂交易的 nonce 偏移
|
|
167
|
+
gasLimit: finalGasLimit,
|
|
168
|
+
gasPrice,
|
|
169
|
+
priorityFee,
|
|
170
|
+
chainId: chainContext.chainId,
|
|
171
|
+
txType,
|
|
172
|
+
value: 0n,
|
|
173
|
+
});
|
|
174
|
+
const [signedSell, ...signedBuys] = await Promise.all([
|
|
175
|
+
seller.signTransaction(sellTx),
|
|
176
|
+
...buyers.map((buyer, i) => {
|
|
177
|
+
const buyTx = buildTransactionRequest(buyUnsignedList[i], {
|
|
178
|
+
from: buyer.address,
|
|
179
|
+
nonce: buyerNonces[i],
|
|
180
|
+
gasLimit: finalGasLimit,
|
|
181
|
+
gasPrice,
|
|
182
|
+
priorityFee,
|
|
183
|
+
chainId: chainContext.chainId,
|
|
184
|
+
txType,
|
|
185
|
+
value: useNativeToken ? buyAmountsWei[i] : 0n,
|
|
186
|
+
});
|
|
187
|
+
return buyer.signTransaction(buyTx);
|
|
188
|
+
}),
|
|
189
|
+
]);
|
|
190
|
+
// ✅ 按顺序组装交易数组:贿赂 → 授权 → 卖出 → 买入
|
|
191
|
+
const signedTransactions = [];
|
|
192
|
+
if (bribeTx)
|
|
193
|
+
signedTransactions.push(bribeTx);
|
|
194
|
+
if (approvalTx)
|
|
195
|
+
signedTransactions.push(approvalTx);
|
|
196
|
+
signedTransactions.push(signedSell);
|
|
197
|
+
signedTransactions.push(...signedBuys);
|
|
198
|
+
// ✅ 利润多跳转账(强制 2 跳中转)
|
|
199
|
+
let profitHopWallets;
|
|
200
|
+
if (profitNonce !== undefined && nativeProfitAmount > 0n) {
|
|
201
|
+
const profitResult = await buildProfitTransaction({
|
|
202
|
+
provider: chainContext.provider,
|
|
203
|
+
seller,
|
|
204
|
+
profitAmount: nativeProfitAmount,
|
|
205
|
+
profitNonce,
|
|
206
|
+
gasPrice,
|
|
207
|
+
chainId: chainContext.chainId,
|
|
208
|
+
txType,
|
|
209
|
+
});
|
|
210
|
+
if (profitResult) {
|
|
211
|
+
signedTransactions.push(...profitResult.signedTransactions);
|
|
212
|
+
profitHopWallets = profitResult.hopWallets; // ✅ 收集利润多跳钱包
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
return {
|
|
216
|
+
signedTransactions,
|
|
217
|
+
profitHopWallets, // ✅ 导出利润多跳钱包
|
|
218
|
+
metadata: {
|
|
219
|
+
sellerAddress: seller.address,
|
|
220
|
+
buyerAddresses: buyers.map((b) => b.address),
|
|
221
|
+
sellAmount: ethers.formatUnits(sellAmountWei, decimals),
|
|
222
|
+
buyAmounts: buyAmountsWei.map((amt) => useNativeToken ? ethers.formatEther(amt) : ethers.formatUnits(amt, quoteTokenDecimals)),
|
|
223
|
+
hasApproval: !!approvalTx,
|
|
224
|
+
profitAmount: nativeProfitAmount > 0n ? ethers.formatEther(nativeProfitAmount) : undefined,
|
|
225
|
+
},
|
|
226
|
+
};
|
|
227
|
+
}
|