@merkl/api 0.10.129 → 0.10.131
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/database/api/.generated/default.js +1 -0
- package/dist/database/api/.generated/edge.js +609 -0
- package/dist/database/api/.generated/index-browser.js +586 -0
- package/dist/database/api/.generated/index.js +638 -0
- package/dist/database/api/.generated/runtime/edge-esm.js +31 -0
- package/dist/database/api/.generated/runtime/edge.js +31 -0
- package/dist/database/api/.generated/runtime/index-browser.js +13 -0
- package/dist/database/api/.generated/runtime/library.js +143 -0
- package/dist/database/api/.generated/runtime/react-native.js +80 -0
- package/dist/database/api/.generated/runtime/wasm.js +32 -0
- package/dist/database/api/.generated/wasm.js +586 -0
- package/dist/database/api/seeder/resources/protocol.js +341 -0
- package/dist/database/engine/.generated/default.js +1 -0
- package/dist/database/engine/.generated/edge.js +438 -0
- package/dist/database/engine/.generated/index-browser.js +415 -0
- package/dist/database/engine/.generated/index.js +467 -0
- package/dist/database/engine/.generated/runtime/edge-esm.js +31 -0
- package/dist/database/engine/.generated/runtime/edge.js +31 -0
- package/dist/database/engine/.generated/runtime/index-browser.js +13 -0
- package/dist/database/engine/.generated/runtime/library.js +143 -0
- package/dist/database/engine/.generated/runtime/react-native.js +80 -0
- package/dist/database/engine/.generated/runtime/wasm.js +32 -0
- package/dist/database/engine/.generated/wasm.js +415 -0
- package/dist/src/backgroundJobs/index.js +44 -0
- package/dist/src/backgroundJobs/jobs/campaignsCacheUpdater.js +160 -0
- package/dist/src/backgroundJobs/jobs/health.js +15 -0
- package/dist/src/backgroundJobs/jobs/opportunityUpdater.js +63 -0
- package/dist/src/backgroundJobs/jobs/priceUpdater.js +16 -0
- package/dist/src/backgroundJobs/jobs/sync.js +33 -0
- package/dist/src/cache/declaration.js +146 -0
- package/dist/src/cache/index.js +152 -0
- package/dist/src/cache/redis.js +49 -0
- package/dist/src/constants.js +119 -0
- package/dist/src/entities/campaign.js +134 -0
- package/dist/src/entities/opportunity.js +549 -0
- package/dist/src/errors/BadRequest.error.js +7 -0
- package/dist/src/errors/Conflict.error.js +7 -0
- package/dist/src/errors/HttpError.js +11 -0
- package/dist/src/errors/NotFound.error.js +7 -0
- package/dist/src/errors/Opportunity.error.js +11 -0
- package/dist/src/errors/Unauthorized.error.js +7 -0
- package/dist/src/errors/index.js +5 -0
- package/dist/src/guards/BackOffice.guard.js +10 -0
- package/dist/src/guards/Engine.guard.js +10 -0
- package/dist/src/guards/TokenAuth.guard.js +10 -0
- package/dist/src/hooks/checkQueryAddressValidity.js +7 -0
- package/dist/src/hooks/checkQueryChainIdValidity.js +7 -0
- package/dist/src/index.js +79 -0
- package/dist/src/internal/controllers/endingCampaigns.js +41 -0
- package/dist/src/internal/controllers/unclaimed.js +36 -0
- package/dist/src/internal/index.js +30 -0
- package/dist/src/libs/campaigns/campaignTypes/AjnaDynamicData.js +111 -0
- package/dist/src/libs/campaigns/campaignTypes/BadgerDynamicData.js +93 -0
- package/dist/src/libs/campaigns/campaignTypes/CLAMMDynamicData.js +942 -0
- package/dist/src/libs/campaigns/campaignTypes/CompoundDynamicData.js +90 -0
- package/dist/src/libs/campaigns/campaignTypes/DolomiteDynamicData.js +60 -0
- package/dist/src/libs/campaigns/campaignTypes/ERC20DynamicData.js +162 -0
- package/dist/src/libs/campaigns/campaignTypes/ERC20DynamicDataRefacto.js +159 -0
- package/dist/src/libs/campaigns/campaignTypes/ERC20SubTypes/helpers/eulerVaultNames.js +13 -0
- package/dist/src/libs/campaigns/campaignTypes/ERC20SubTypes/helpers/factoryFinder.js +29 -0
- package/dist/src/libs/campaigns/campaignTypes/ERC20SubTypes/helpers/getBlacklistedSupply.js +22 -0
- package/dist/src/libs/campaigns/campaignTypes/ERC20SubTypes/helpers/metamorphoTvl.js +35 -0
- package/dist/src/libs/campaigns/campaignTypes/ERC20SubTypes/helpers/spliceTVL.js +21 -0
- package/dist/src/libs/campaigns/campaignTypes/ERC20SubTypes/helpers/tokenType.js +106 -0
- package/dist/src/libs/campaigns/campaignTypes/ERC20SubTypes/processor/AaveProcessor.js +26 -0
- package/dist/src/libs/campaigns/campaignTypes/ERC20SubTypes/processor/AssetProcessor.js +47 -0
- package/dist/src/libs/campaigns/campaignTypes/ERC20SubTypes/processor/AuraProcessor.js +103 -0
- package/dist/src/libs/campaigns/campaignTypes/ERC20SubTypes/processor/BalancerGaugeProcessor.js +83 -0
- package/dist/src/libs/campaigns/campaignTypes/ERC20SubTypes/processor/BalancerPoolProcessor.js +99 -0
- package/dist/src/libs/campaigns/campaignTypes/ERC20SubTypes/processor/BeefyProcessor.js +51 -0
- package/dist/src/libs/campaigns/campaignTypes/ERC20SubTypes/processor/CompoundProcessor.js +36 -0
- package/dist/src/libs/campaigns/campaignTypes/ERC20SubTypes/processor/EnzymeProcessor.js +51 -0
- package/dist/src/libs/campaigns/campaignTypes/ERC20SubTypes/processor/EulerBorrowProcessor.js +46 -0
- package/dist/src/libs/campaigns/campaignTypes/ERC20SubTypes/processor/EulerLendProcessor.js +47 -0
- package/dist/src/libs/campaigns/campaignTypes/ERC20SubTypes/processor/FluidProcessor.js +36 -0
- package/dist/src/libs/campaigns/campaignTypes/ERC20SubTypes/processor/FraxProcessor.js +41 -0
- package/dist/src/libs/campaigns/campaignTypes/ERC20SubTypes/processor/GearboxProcessor.js +44 -0
- package/dist/src/libs/campaigns/campaignTypes/ERC20SubTypes/processor/GenericProcessor.js +239 -0
- package/dist/src/libs/campaigns/campaignTypes/ERC20SubTypes/processor/MetamorphoProcessor.js +43 -0
- package/dist/src/libs/campaigns/campaignTypes/ERC20SubTypes/processor/PendleProcessor.js +31 -0
- package/dist/src/libs/campaigns/campaignTypes/ERC20SubTypes/processor/RadiantProcessor.js +58 -0
- package/dist/src/libs/campaigns/campaignTypes/ERC20SubTypes/processor/RfxProcessor.js +64 -0
- package/dist/src/libs/campaigns/campaignTypes/ERC20SubTypes/processor/SpliceProcessor.js +35 -0
- package/dist/src/libs/campaigns/campaignTypes/ERC20SubTypes/processor/SturdySiloProcessor.js +37 -0
- package/dist/src/libs/campaigns/campaignTypes/ERC20SubTypes/processor/TemplateProcessor.js +40 -0
- package/dist/src/libs/campaigns/campaignTypes/ERC20SubTypes/processor/TorosProcessor.js +33 -0
- package/dist/src/libs/campaigns/campaignTypes/ERC20SubTypes/processor/UniswapProcessor.js +48 -0
- package/dist/src/libs/campaigns/campaignTypes/ERC20SubTypes/processor/WoofiProcessor.js +40 -0
- package/dist/src/libs/campaigns/campaignTypes/ERC20SubTypes/processor/curveProcessor.js +68 -0
- package/dist/src/libs/campaigns/campaignTypes/ERC20SubTypes/processor/processorMapping.js +77 -0
- package/dist/src/libs/campaigns/campaignTypes/ERC20SubTypes/subtypesPrices.js +583 -0
- package/dist/src/libs/campaigns/campaignTypes/ERC20SubTypes/subtypesPricesRefactoFinal.js +24 -0
- package/dist/src/libs/campaigns/campaignTypes/ERC20SubTypes/subtypesRound1.js +1209 -0
- package/dist/src/libs/campaigns/campaignTypes/ERC20SubTypes/subtypesRound1RefactoFinal.js +194 -0
- package/dist/src/libs/campaigns/campaignTypes/ERC20SubTypes/subtypesRound2.js +645 -0
- package/dist/src/libs/campaigns/campaignTypes/ERC20SubTypes/subtypesRound2RefactoFinal.js +22 -0
- package/dist/src/libs/campaigns/campaignTypes/ERC20SubTypes/subtypesRound3.js +392 -0
- package/dist/src/libs/campaigns/campaignTypes/ERC20SubTypes/subtypesRound3RefactoFinal.js +22 -0
- package/dist/src/libs/campaigns/campaignTypes/ERC20SubTypes/subtypesRound4.js +323 -0
- package/dist/src/libs/campaigns/campaignTypes/ERC20SubTypes/subtypesRound4RefactoFinal.js +22 -0
- package/dist/src/libs/campaigns/campaignTypes/ERC20_SNAPSHOTDynamicData.js +38 -0
- package/dist/src/libs/campaigns/campaignTypes/EulerDynamicData.js +165 -0
- package/dist/src/libs/campaigns/campaignTypes/JSON_AIRDROPDynamicData.js +19 -0
- package/dist/src/libs/campaigns/campaignTypes/MORPHODynamicData.js +120 -0
- package/dist/src/libs/campaigns/campaignTypes/RadiantDynamicData.js +112 -0
- package/dist/src/libs/campaigns/campaignTypes/SILODynamicData.js +113 -0
- package/dist/src/libs/campaigns/campaignsDynamicData.js +83 -0
- package/dist/src/libs/campaigns/campaignsDynamicDataRefacto.js +78 -0
- package/dist/src/libs/campaigns/getCampaigns.js +18 -0
- package/dist/src/libs/campaigns/utils/fetchA51Strategies.js +44 -0
- package/dist/src/libs/campaigns/utils/fetchClamInfo.js +27 -0
- package/dist/src/libs/campaigns/utils/fetchLogs.js +91 -0
- package/dist/src/libs/campaigns/utils/getCompV2ForksVaults.js +122 -0
- package/dist/src/libs/campaigns/utils/getContractCreationBlock.js +44 -0
- package/dist/src/libs/campaigns/utils/getDolomiteMarkets.js +50 -0
- package/dist/src/libs/campaigns/utils/getEulerV2Vaults.js +87 -0
- package/dist/src/libs/campaigns/utils/getLastEligibilityRatio.js +56 -0
- package/dist/src/libs/computeFee.js +34 -0
- package/dist/src/libs/custom/twtParticipants.js +54 -0
- package/dist/src/libs/deprecated-merklv3/index.js +184 -0
- package/dist/src/libs/getTokensList.js +37 -0
- package/dist/src/libs/merklChainData.js +129 -0
- package/dist/src/libs/parse/marketsWithCache.js +8 -0
- package/dist/src/libs/positions/ajna/index.js +107 -0
- package/dist/src/libs/positions/badger/index.js +79 -0
- package/dist/src/libs/positions/clamm/index.js +419 -0
- package/dist/src/libs/positions/clamm/thegraph/fetchAlmPositions.js +35 -0
- package/dist/src/libs/positions/clamm/thegraph/fetchAmmPositions.js +35 -0
- package/dist/src/libs/positions/clamm/thegraph/fetchFarmedPositions.js +44 -0
- package/dist/src/libs/positions/clamm/thegraph/index.js +162 -0
- package/dist/src/libs/positions/compound/index.js +93 -0
- package/dist/src/libs/positions/dolomite/index.js +49 -0
- package/dist/src/libs/positions/erc20/index.js +55 -0
- package/dist/src/libs/positions/euler/index.js +57 -0
- package/dist/src/libs/positions/index.js +48 -0
- package/dist/src/libs/positions/morpho/index.js +177 -0
- package/dist/src/libs/positions/prepareFetch.js +339 -0
- package/dist/src/libs/positions/silo/index.js +67 -0
- package/dist/src/libs/positions/types.js +1 -0
- package/dist/src/libs/reports/campaignReport.js +37 -0
- package/dist/src/libs/reports/mainParameterRewards.js +48 -0
- package/dist/src/libs/rewards/userRewards.js +154 -0
- package/dist/src/libs/staticCampaigns.js +10 -0
- package/dist/src/libs/tokens/balances.js +126 -0
- package/dist/src/libs/tokens/tokenInfo.js +22 -0
- package/dist/src/modules/v4/accounting/accounting.controller.js +66 -0
- package/dist/src/modules/v4/accounting/accounting.model.js +32 -0
- package/dist/src/modules/v4/accounting/accounting.repository.js +100 -0
- package/dist/src/modules/v4/accounting/accounting.service.js +78 -0
- package/dist/src/modules/v4/accounting/index.js +3 -0
- package/dist/src/modules/v4/apr/apr.controller.js +1 -0
- package/dist/src/modules/v4/apr/apr.model.js +1 -0
- package/dist/src/modules/v4/apr/apr.repository.js +1 -0
- package/dist/src/modules/v4/apr/apr.service.js +40 -0
- package/dist/src/modules/v4/apr/index.js +2 -0
- package/dist/src/modules/v4/blacklist/blacklist.controller.js +45 -0
- package/dist/src/modules/v4/blacklist/blacklist.model.js +13 -0
- package/dist/src/modules/v4/blacklist/blacklist.repository.js +56 -0
- package/dist/src/modules/v4/blacklist/blacklist.service.js +24 -0
- package/dist/src/modules/v4/blacklist/index.js +3 -0
- package/dist/src/modules/v4/cache/cache.model.js +14 -0
- package/dist/src/modules/v4/cache/cache.repository.js +10 -0
- package/dist/src/modules/v4/cache/cache.service.js +44 -0
- package/dist/src/modules/v4/cache/index.js +1 -0
- package/dist/src/modules/v4/campaign/campaign.controller.js +56 -0
- package/dist/src/modules/v4/campaign/campaign.model.js +54 -0
- package/dist/src/modules/v4/campaign/campaign.repository.js +346 -0
- package/dist/src/modules/v4/campaign/campaign.service.js +203 -0
- package/dist/src/modules/v4/campaign/index.js +3 -0
- package/dist/src/modules/v4/chain/chain.controller.js +40 -0
- package/dist/src/modules/v4/chain/chain.model.js +17 -0
- package/dist/src/modules/v4/chain/chain.repository.js +64 -0
- package/dist/src/modules/v4/chain/chain.service.js +42 -0
- package/dist/src/modules/v4/chain/index.js +3 -0
- package/dist/src/modules/v4/dynamicData/dynamicData.controller.js +19 -0
- package/dist/src/modules/v4/dynamicData/dynamicData.model.js +6 -0
- package/dist/src/modules/v4/dynamicData/dynamicData.repository.js +1 -0
- package/dist/src/modules/v4/dynamicData/dynamicData.service.js +49 -0
- package/dist/src/modules/v4/dynamicData/index.js +3 -0
- package/dist/src/modules/v4/enso/enso.model.js +108 -0
- package/dist/src/modules/v4/enso/enso.service.js +46 -0
- package/dist/src/modules/v4/explorer/explorer.model.js +2 -0
- package/dist/src/modules/v4/explorer/explorer.repository.js +23 -0
- package/dist/src/modules/v4/explorer/explorer.service.js +24 -0
- package/dist/src/modules/v4/explorer/index.js +1 -0
- package/dist/src/modules/v4/index.js +4 -0
- package/dist/src/modules/v4/merklRoot/index.js +3 -0
- package/dist/src/modules/v4/merklRoot/merklRoot.controller.js +19 -0
- package/dist/src/modules/v4/merklRoot/merklRoot.model.js +6 -0
- package/dist/src/modules/v4/merklRoot/merklRoot.repository.js +31 -0
- package/dist/src/modules/v4/merklRoot/merklRoot.service.js +38 -0
- package/dist/src/modules/v4/opportunity/index.js +3 -0
- package/dist/src/modules/v4/opportunity/opportunity.controller.js +69 -0
- package/dist/src/modules/v4/opportunity/opportunity.model.js +36 -0
- package/dist/src/modules/v4/opportunity/opportunity.repository.d.ts +14 -0
- package/dist/src/modules/v4/opportunity/opportunity.repository.js +217 -0
- package/dist/src/modules/v4/opportunity/opportunity.service.d.ts +0 -15
- package/dist/src/modules/v4/opportunity/opportunity.service.js +180 -0
- package/dist/src/modules/v4/opportunity/subservices/getAjnaMetadata.service.js +50 -0
- package/dist/src/modules/v4/opportunity/subservices/getBadgerMetadata.service.js +23 -0
- package/dist/src/modules/v4/opportunity/subservices/getClammMetadata.service.js +33 -0
- package/dist/src/modules/v4/opportunity/subservices/getCompoundMetadata.service.js +18 -0
- package/dist/src/modules/v4/opportunity/subservices/getDolomiteMetadata.service.js +15 -0
- package/dist/src/modules/v4/opportunity/subservices/getErc20Metadata.service.js +63 -0
- package/dist/src/modules/v4/opportunity/subservices/getErc20SnapshotMetadata.service.js +8 -0
- package/dist/src/modules/v4/opportunity/subservices/getEulerMetadata.service.js +30 -0
- package/dist/src/modules/v4/opportunity/subservices/getJsonAirDropMetadata.service.js +36 -0
- package/dist/src/modules/v4/opportunity/subservices/getMorphoMetadata.service.js +19 -0
- package/dist/src/modules/v4/opportunity/subservices/getRadiantMetadata.service.js +9 -0
- package/dist/src/modules/v4/opportunity/subservices/getSiloMetadata.service.js +13 -0
- package/dist/src/modules/v4/opportunity/transform-id.pipe.js +6 -0
- package/dist/src/modules/v4/opportunity/validate-id.pipe.js +12 -0
- package/dist/src/modules/v4/participate/participate.controller.js +66 -0
- package/dist/src/modules/v4/participate/participate.model.js +24 -0
- package/dist/src/modules/v4/participate/participate.service.js +33 -0
- package/dist/src/modules/v4/price/index.js +3 -0
- package/dist/src/modules/v4/price/price.controller.js +62 -0
- package/dist/src/modules/v4/price/price.model.js +12 -0
- package/dist/src/modules/v4/price/price.repository.js +18 -0
- package/dist/src/modules/v4/price/price.service.js +44 -0
- package/dist/src/modules/v4/prisma/index.js +1 -0
- package/dist/src/modules/v4/protocol/index.js +3 -0
- package/dist/src/modules/v4/protocol/protocol.controller.js +23 -0
- package/dist/src/modules/v4/protocol/protocol.model.js +68 -0
- package/dist/src/modules/v4/protocol/protocol.repository.js +37 -0
- package/dist/src/modules/v4/protocol/protocol.service.js +77 -0
- package/dist/src/modules/v4/reward/index.js +3 -0
- package/dist/src/modules/v4/reward/reward.controller.js +52 -0
- package/dist/src/modules/v4/reward/reward.model.js +104 -0
- package/dist/src/modules/v4/reward/reward.repository.js +237 -0
- package/dist/src/modules/v4/reward/reward.service.js +283 -0
- package/dist/src/modules/v4/reward/rewardConvertor.service.js +136 -0
- package/dist/src/modules/v4/router.js +57 -0
- package/dist/src/modules/v4/status/index.js +3 -0
- package/dist/src/modules/v4/status/status.controller.js +48 -0
- package/dist/src/modules/v4/status/status.model.js +24 -0
- package/dist/src/modules/v4/status/status.repository.js +88 -0
- package/dist/src/modules/v4/status/status.service.js +60 -0
- package/dist/src/modules/v4/token/index.js +3 -0
- package/dist/src/modules/v4/token/token.controller.js +32 -0
- package/dist/src/modules/v4/token/token.model.js +23 -0
- package/dist/src/modules/v4/token/token.repository.js +128 -0
- package/dist/src/modules/v4/token/token.service.js +268 -0
- package/dist/src/modules/v4/tvl/index.js +2 -0
- package/dist/src/modules/v4/tvl/tvl.controller.js +1 -0
- package/dist/src/modules/v4/tvl/tvl.model.js +1 -0
- package/dist/src/modules/v4/tvl/tvl.repository.js +1 -0
- package/dist/src/modules/v4/tvl/tvl.service.js +49 -0
- package/dist/src/modules/v4/uniswapV4/index.js +4 -0
- package/dist/src/modules/v4/uniswapV4/uniswapV4.controller.js +11 -0
- package/dist/src/modules/v4/uniswapV4/uniswapV4.model.js +17 -0
- package/dist/src/modules/v4/uniswapV4/uniswapV4.repository.js +2 -0
- package/dist/src/modules/v4/uniswapV4/uniswapV4.service.js +73 -0
- package/dist/src/modules/v4/user/index.js +3 -0
- package/dist/src/modules/v4/user/user.controller.js +69 -0
- package/dist/src/modules/v4/user/user.model.js +18 -0
- package/dist/src/modules/v4/user/user.repository.js +38 -0
- package/dist/src/modules/v4/user/user.service.js +50 -0
- package/dist/src/plugins/error-handling.plugin.js +28 -0
- package/dist/src/plugins/logger.plugin.js +22 -0
- package/dist/src/routes/v1/allowances.js +115 -0
- package/dist/src/routes/v1/balances.js +25 -0
- package/dist/src/routes/v1/prices.js +11 -0
- package/dist/src/routes/v1/tokens.js +17 -0
- package/dist/src/routes/v2/merkl.js +13 -0
- package/dist/src/routes/v3/ERC20Campaigns.js +63 -0
- package/dist/src/routes/v3/app.js +18 -0
- package/dist/src/routes/v3/blacklist.js +18 -0
- package/dist/src/routes/v3/campaign/delay.js +78 -0
- package/dist/src/routes/v3/campaignClaims.js +24 -0
- package/dist/src/routes/v3/campaignReport.js +22 -0
- package/dist/src/routes/v3/campaignUnclaimed.js +28 -0
- package/dist/src/routes/v3/campaigns.js +101 -0
- package/dist/src/routes/v3/campaignsForMainParameter.js +19 -0
- package/dist/src/routes/v3/campaignsInfo.js +54 -0
- package/dist/src/routes/v3/campaignsRewardsReport.js +47 -0
- package/dist/src/routes/v3/claims.js +45 -0
- package/dist/src/routes/v3/compoundV2.js +9 -0
- package/dist/src/routes/v3/createCampaign.js +66 -0
- package/dist/src/routes/v3/dolomite.js +9 -0
- package/dist/src/routes/v3/euler.js +9 -0
- package/dist/src/routes/v3/exports/campaigns.js +28 -0
- package/dist/src/routes/v3/fetch.js +27 -0
- package/dist/src/routes/v3/health.js +13 -0
- package/dist/src/routes/v3/lostyield.js +98 -0
- package/dist/src/routes/v3/merkl.js +119 -0
- package/dist/src/routes/v3/morphoMarkets.js +27 -0
- package/dist/src/routes/v3/morphoVaults.js +22 -0
- package/dist/src/routes/v3/multiChainPositions.js +69 -0
- package/dist/src/routes/v3/opportunity.js +63 -0
- package/dist/src/routes/v3/overview.js +73 -0
- package/dist/src/routes/v3/parse.js +23 -0
- package/dist/src/routes/v3/payload.js +40 -0
- package/dist/src/routes/v3/poolInfo.js +88 -0
- package/dist/src/routes/v3/positions.js +62 -0
- package/dist/src/routes/v3/radiant.js +26 -0
- package/dist/src/routes/v3/recipients.js +20 -0
- package/dist/src/routes/v3/rewards.js +33 -0
- package/dist/src/routes/v3/rewardsReport.js +51 -0
- package/dist/src/routes/v3/rootForTimestamp.js +47 -0
- package/dist/src/routes/v3/silo.js +20 -0
- package/dist/src/routes/v3/token.js +24 -0
- package/dist/src/routes/v3/tokenUnclaimed.js +24 -0
- package/dist/src/routes/v3/twt/participants.js +11 -0
- package/dist/src/routes/v3/updates.js +47 -0
- package/dist/src/routes/v3/userRewards.js +59 -0
- package/dist/src/types/index.js +6 -0
- package/dist/src/types/parameters/Action.js +11 -0
- package/dist/src/types/parameters/Chain.js +13 -0
- package/dist/src/types/parameters/ChainCampaignId.js +13 -0
- package/dist/src/types/parameters/MainParameter.js +19 -0
- package/dist/src/types/parameters/OpportunityId.js +14 -0
- package/dist/src/types/parameters/Timestamp.js +16 -0
- package/dist/src/types/parameters/Type.js +15 -0
- package/dist/src/types/parameters/index.js +17 -0
- package/dist/src/types/returnTypes.js +1 -0
- package/dist/src/types/utils.js +1 -0
- package/dist/src/utils/addString.js +6 -0
- package/dist/src/utils/bigintToString.js +20 -0
- package/dist/src/utils/crypto.js +4 -0
- package/dist/src/utils/decodeCalls.js +170 -0
- package/dist/src/utils/encodeCalls.js +240 -0
- package/dist/src/utils/error.js +90 -0
- package/dist/src/utils/execute.js +41 -0
- package/dist/src/utils/generateCardName.js +89 -0
- package/dist/src/utils/generic.js +117 -0
- package/dist/src/utils/hashArray.js +4 -0
- package/dist/src/utils/lastBlockBefore.js +78 -0
- package/dist/src/utils/logger.js +52 -0
- package/dist/src/utils/pricer.js +180 -0
- package/dist/src/utils/prices/chainlinkRead.js +8 -0
- package/dist/src/utils/prices/curveVirtualPrice.js +7 -0
- package/dist/src/utils/prices/getDQUICK.js +8 -0
- package/dist/src/utils/prices/priceFetcherFactory.js +29 -0
- package/dist/src/utils/prices/priceService.js +328 -0
- package/dist/src/utils/prices/services/coinGeckoService.js +53 -0
- package/dist/src/utils/prices/services/defillamaService.js +53 -0
- package/dist/src/utils/prices/services/dexScreenerService.js +62 -0
- package/dist/src/utils/prices/services/erc4626Service.js +30 -0
- package/dist/src/utils/prices/services/getERC4626.js +11 -0
- package/dist/src/utils/prices/services/indexCoopService.js +55 -0
- package/dist/src/utils/prices/services/priceFetcher.js +1 -0
- package/dist/src/utils/prices/uniV2Price.js +40 -0
- package/dist/src/utils/prisma.js +12 -0
- package/dist/src/utils/providers.js +30 -0
- package/dist/src/utils/queries/activeCampaigns.js +22 -0
- package/dist/src/utils/queries/allCampaigns.js +51 -0
- package/dist/src/utils/queries/campaignsForMainParameter.js +23 -0
- package/dist/src/utils/queries/claimsOverTime.js +111 -0
- package/dist/src/utils/queries/endingCampaigns.js +21 -0
- package/dist/src/utils/queries/futureCampaigns.js +19 -0
- package/dist/src/utils/queries/mainParameterCampaigns.js +11 -0
- package/dist/src/utils/queries/rewardsAmount.js +106 -0
- package/dist/src/utils/queries/unclaimed.js +81 -0
- package/dist/src/utils/rateLimit.js +13 -0
- package/dist/src/utils/stryke.js +4 -0
- package/dist/src/utils/throw.js +27 -0
- package/dist/src/utils/validation.js +20 -0
- package/dist/tsconfig.package.tsbuildinfo +1 -1
- package/package.json +2 -2
- package/dist/package.json +0 -91
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import { HttpError } from "../errors";
|
|
2
|
+
import { NETWORK_LABELS } from "@sdk";
|
|
3
|
+
import { ValidationError } from "elysia";
|
|
4
|
+
export class InvalidParameter extends Error {
|
|
5
|
+
message;
|
|
6
|
+
constructor(message) {
|
|
7
|
+
super(message);
|
|
8
|
+
this.message = message;
|
|
9
|
+
this.name = "INVALID_PARAMETER";
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
export class UnsupportedNetwork extends Error {
|
|
13
|
+
chainId;
|
|
14
|
+
constructor(chainId) {
|
|
15
|
+
super(`API for Merkl products by Angle Labs does not support (yet) network ${chainId}`);
|
|
16
|
+
this.chainId = chainId;
|
|
17
|
+
this.name = "UNSUPPORTED_NETWORK";
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
export class OpportunityNotFound extends Error {
|
|
21
|
+
mainParameter;
|
|
22
|
+
chainId;
|
|
23
|
+
constructor(mainParameter, chainId) {
|
|
24
|
+
super(`No campaigns found for mainParameter ${mainParameter} on chain ${NETWORK_LABELS[chainId]}`);
|
|
25
|
+
this.mainParameter = mainParameter;
|
|
26
|
+
this.chainId = chainId;
|
|
27
|
+
this.name = "OPPORTUNITY_NOT_FOUND";
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
export class MerkleRootNotFound extends Error {
|
|
31
|
+
chainId;
|
|
32
|
+
constructor(chainId) {
|
|
33
|
+
super(`No Merkl root found for network ${NETWORK_LABELS[chainId]} (${chainId})`);
|
|
34
|
+
this.chainId = chainId;
|
|
35
|
+
this.name = "MERKLE_ROOT_NOT_FOUND";
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
export class InvalidCacheCall extends Error {
|
|
39
|
+
message;
|
|
40
|
+
constructor(message) {
|
|
41
|
+
super(message);
|
|
42
|
+
this.message = message;
|
|
43
|
+
this.name = "INVALID_CACHE_CALL";
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
export const errorHandler = (canLog = true) => {
|
|
47
|
+
return (app) => app
|
|
48
|
+
.error({
|
|
49
|
+
InvalidParameter,
|
|
50
|
+
UnsupportedNetwork,
|
|
51
|
+
OpportunityNotFound,
|
|
52
|
+
MerkleRootNotFound,
|
|
53
|
+
ValidationError,
|
|
54
|
+
InvalidCacheCall,
|
|
55
|
+
HttpError,
|
|
56
|
+
})
|
|
57
|
+
.onError(({ error, path, query, code, set, ...all }) => {
|
|
58
|
+
const response = (status, log = true, overrides) => {
|
|
59
|
+
if (canLog && log)
|
|
60
|
+
console.error(`[${path}](${JSON.stringify(query) ?? ""}): ${error.message} : ${error.stack}`);
|
|
61
|
+
return new Response(JSON.stringify(Object.assign({
|
|
62
|
+
error: error.name !== "Error" ? error.name : code,
|
|
63
|
+
message: error.message,
|
|
64
|
+
}, overrides ?? {})), {
|
|
65
|
+
status,
|
|
66
|
+
});
|
|
67
|
+
};
|
|
68
|
+
switch (code) {
|
|
69
|
+
case "InvalidParameter":
|
|
70
|
+
case "InvalidCacheCall":
|
|
71
|
+
return response(400, false);
|
|
72
|
+
case "NOT_FOUND":
|
|
73
|
+
return response(404, false, { message: `${path} does not exist` });
|
|
74
|
+
case "UnsupportedNetwork":
|
|
75
|
+
case "OpportunityNotFound":
|
|
76
|
+
case "MerkleRootNotFound":
|
|
77
|
+
return response(404, false);
|
|
78
|
+
case "VALIDATION": {
|
|
79
|
+
const errorObj = JSON.parse(error.message);
|
|
80
|
+
const property = (errorObj.property ?? "").replaceAll("/", "");
|
|
81
|
+
return response(400, false, {
|
|
82
|
+
message: errorObj.summary,
|
|
83
|
+
found: (property === "" ? errorObj.found : errorObj.found?.[property]) ?? "undefined",
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
default:
|
|
87
|
+
return response(500);
|
|
88
|
+
}
|
|
89
|
+
});
|
|
90
|
+
};
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { batchMulticallCall, multicallContractCall } from "./generic";
|
|
2
|
+
import { log } from "./logger";
|
|
3
|
+
import { archiveMulticalls, multicalls } from "./providers";
|
|
4
|
+
/**
|
|
5
|
+
* Functions
|
|
6
|
+
*/
|
|
7
|
+
export async function executeSimple(chainId, componentCall) {
|
|
8
|
+
const c = await componentCall;
|
|
9
|
+
if (c.cached === true)
|
|
10
|
+
return c.result;
|
|
11
|
+
return (await execute(chainId, [c.call]))[0];
|
|
12
|
+
}
|
|
13
|
+
const execute = async (chainId, callList, shouldRetry, blockNumber) => {
|
|
14
|
+
const calls = [];
|
|
15
|
+
for (const subCall of callList) {
|
|
16
|
+
calls.push(...subCall.callData);
|
|
17
|
+
}
|
|
18
|
+
try {
|
|
19
|
+
let result;
|
|
20
|
+
if (calls.length > 0) {
|
|
21
|
+
result = await batchMulticallCall(multicallContractCall, !!blockNumber ? archiveMulticalls[chainId] : multicalls[chainId], { blockNumber: blockNumber, data: calls }, shouldRetry);
|
|
22
|
+
}
|
|
23
|
+
else {
|
|
24
|
+
result = [];
|
|
25
|
+
}
|
|
26
|
+
let startIndex = 0;
|
|
27
|
+
const promises = [];
|
|
28
|
+
for (const subCall of callList) {
|
|
29
|
+
promises.push(subCall.reducer(result.slice(startIndex, startIndex + subCall.callData.length)));
|
|
30
|
+
startIndex += subCall.callData.length;
|
|
31
|
+
}
|
|
32
|
+
return await Promise.all(promises);
|
|
33
|
+
}
|
|
34
|
+
catch (e) {
|
|
35
|
+
for (const subCall of callList) {
|
|
36
|
+
log.error("execute", e);
|
|
37
|
+
subCall.handler();
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
return [];
|
|
41
|
+
};
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { tokenType } from "../libs/campaigns/campaignTypes/ERC20SubTypes/helpers/tokenType";
|
|
2
|
+
export function generateCardName(type, typeInfo, campaign, symbols = [""]) {
|
|
3
|
+
switch (type) {
|
|
4
|
+
case tokenType.uniswapv2:
|
|
5
|
+
case tokenType.poolside:
|
|
6
|
+
case tokenType.velodrome:
|
|
7
|
+
case tokenType.aerodrome:
|
|
8
|
+
case tokenType.dragonswap:
|
|
9
|
+
case tokenType.akron:
|
|
10
|
+
case tokenType.koi:
|
|
11
|
+
case tokenType.baseswap:
|
|
12
|
+
case tokenType.fenix:
|
|
13
|
+
case tokenType.zkswap:
|
|
14
|
+
case tokenType.ra:
|
|
15
|
+
case tokenType.syncswap:
|
|
16
|
+
return `${typeInfo.protocol} ${typeInfo.symbolToken0}/${typeInfo.symbolToken1}`;
|
|
17
|
+
case tokenType.pendle:
|
|
18
|
+
return `Provide ${typeInfo.symbolUnderlyingToken} on ${typeInfo.protocol}`;
|
|
19
|
+
case tokenType.balancerGauge:
|
|
20
|
+
return `${typeInfo.protocol} ${symbols.join("/")}`;
|
|
21
|
+
case tokenType.balancerPool: {
|
|
22
|
+
let cardName = `${typeInfo.protocol} ${symbols.join("/")}`;
|
|
23
|
+
if (typeInfo.vault === "0xFB43069f6d0473B85686a85F4Ce4Fc1FD8F00875") {
|
|
24
|
+
cardName = `Jellyverse Pool ${symbols.join("/")}`;
|
|
25
|
+
}
|
|
26
|
+
return cardName;
|
|
27
|
+
}
|
|
28
|
+
case tokenType.aura:
|
|
29
|
+
return `${typeInfo.protocol} ${symbols.join("/")}`;
|
|
30
|
+
case tokenType.gearbox:
|
|
31
|
+
return `${typeInfo.protocol} ${typeInfo.symbolUnderlyingToken} Deposit`;
|
|
32
|
+
case tokenType.compound:
|
|
33
|
+
return `Lend ${typeInfo.symbolBaseToken} on ${typeInfo.protocol}`;
|
|
34
|
+
case tokenType.radiant_lend: {
|
|
35
|
+
let cardToken = typeInfo.symbolUnderlyingToken;
|
|
36
|
+
if (campaign.campaignParameters.symbolTargetToken.startsWith("r")) {
|
|
37
|
+
cardToken = campaign.campaignParameters.symbolTargetToken.substring(1);
|
|
38
|
+
}
|
|
39
|
+
return `Lend ${cardToken} on ${typeInfo.protocol}`;
|
|
40
|
+
}
|
|
41
|
+
case tokenType.rfx:
|
|
42
|
+
return `Supply ${typeInfo.symbolShortToken}/${typeInfo.symbolLongToken} on ${typeInfo.protocol}`;
|
|
43
|
+
case tokenType.radiant_borrow:
|
|
44
|
+
case tokenType.aave_borrowing:
|
|
45
|
+
case tokenType.yei_borrowing:
|
|
46
|
+
case tokenType.ironclad_borrowing:
|
|
47
|
+
case tokenType.zerolend_borrowing:
|
|
48
|
+
case tokenType.euler_borrow:
|
|
49
|
+
return `Borrow ${typeInfo.symbolUnderlyingToken} on ${typeInfo.protocol}`;
|
|
50
|
+
case tokenType.ionic:
|
|
51
|
+
case tokenType.layerbank:
|
|
52
|
+
case tokenType.moonwell:
|
|
53
|
+
case tokenType.splice:
|
|
54
|
+
case tokenType.aave_lending:
|
|
55
|
+
case tokenType.yei_lending:
|
|
56
|
+
case tokenType.ironclad_lending:
|
|
57
|
+
case tokenType.zerolend_lending:
|
|
58
|
+
case tokenType.fraxlend:
|
|
59
|
+
case tokenType.euler_lend:
|
|
60
|
+
return `Supply ${typeInfo.symbolUnderlyingToken} on ${typeInfo.protocol}`;
|
|
61
|
+
case tokenType.metamorpho:
|
|
62
|
+
return `Supply to ${typeInfo.name} on ${typeInfo.protocol}`;
|
|
63
|
+
case tokenType.sturdy_aggregator:
|
|
64
|
+
return `Supply ${typeInfo.symbolUnderlyingToken} on ${typeInfo.protocol} ${typeInfo.name}`;
|
|
65
|
+
case tokenType.sturdy_silo:
|
|
66
|
+
return `Supply ${typeInfo.symbolUnderlyingToken} on ${typeInfo.protocol} ${typeInfo.symbolCollateral} Silo`;
|
|
67
|
+
case tokenType.curve:
|
|
68
|
+
case tokenType.curve_2:
|
|
69
|
+
return `${typeInfo.protocol} ${Object.values(typeInfo.poolTokens).join("/")}`;
|
|
70
|
+
case tokenType.fluid:
|
|
71
|
+
return `Lend ${typeInfo.symbolUnderlyingToken} on ${typeInfo.protocol}`;
|
|
72
|
+
case tokenType.enzyme:
|
|
73
|
+
return `Supply to the ${typeInfo.name} on ${typeInfo.protocol}`;
|
|
74
|
+
case tokenType.filament:
|
|
75
|
+
return `Earn Yield on ${typeInfo.symbolUnderlyingToken} on ${typeInfo.protocol}`;
|
|
76
|
+
case tokenType.silostaking:
|
|
77
|
+
return `Stake ${typeInfo.symbolUnderlyingToken} on ${typeInfo.protocol}`;
|
|
78
|
+
case tokenType.beefy:
|
|
79
|
+
return `${typeInfo.protocol} ${typeInfo.symbolToken0}/${typeInfo.symbolToken1}`;
|
|
80
|
+
case tokenType.toros:
|
|
81
|
+
return `${typeInfo.name} (${campaign.campaignParameters.symbolTargetToken}) on ${typeInfo.protocol}`;
|
|
82
|
+
case tokenType.ironcladStaking:
|
|
83
|
+
return `Stake ${campaign.campaignParameters.symbolTargetToken} on ${typeInfo.protocol}`;
|
|
84
|
+
case tokenType.woofi:
|
|
85
|
+
return `Supercharge ${typeInfo.symbolUnderlying} on ${typeInfo.protocol}`;
|
|
86
|
+
default:
|
|
87
|
+
return `Hold ${typeInfo.name} (${campaign.campaignParameters.symbolTargetToken})`;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import { withRetry } from "@sdk";
|
|
2
|
+
import { constants, BigNumber } from "ethers";
|
|
3
|
+
import { MAX_NUM_SUBCALLS } from "../constants";
|
|
4
|
+
import { log } from "./logger";
|
|
5
|
+
import { multicalls } from "./providers";
|
|
6
|
+
export async function multicallContractCall(contract, args) {
|
|
7
|
+
let result;
|
|
8
|
+
try {
|
|
9
|
+
// TO SIMULATE - USE CAUTIOUSLY AS IT USES CREDITS
|
|
10
|
+
// console.log(
|
|
11
|
+
// await callTenderly(
|
|
12
|
+
// {
|
|
13
|
+
// chainId: (await contract.provider.getNetwork()).chainId.toString(),
|
|
14
|
+
// data: contract.interface.encodeFunctionData('aggregate', [args.data]),
|
|
15
|
+
// from: !!args.from ? args.from : constants.AddressZero,
|
|
16
|
+
// saveSimulation: true,
|
|
17
|
+
// to: contract.address,
|
|
18
|
+
// value: '0',
|
|
19
|
+
// },
|
|
20
|
+
// undefined,
|
|
21
|
+
// true
|
|
22
|
+
// )
|
|
23
|
+
// );
|
|
24
|
+
result = await contract.provider.call({
|
|
25
|
+
data: contract.interface.encodeFunctionData("aggregate3", [
|
|
26
|
+
args.data.map(c => {
|
|
27
|
+
return {
|
|
28
|
+
allowFailure: !!c.allowFailure,
|
|
29
|
+
callData: c.callData,
|
|
30
|
+
target: c.target,
|
|
31
|
+
};
|
|
32
|
+
}),
|
|
33
|
+
]),
|
|
34
|
+
from: !!args.from ? args.from : constants.AddressZero,
|
|
35
|
+
to: contract.address,
|
|
36
|
+
}, !!args.blockNumber ? args.blockNumber : undefined);
|
|
37
|
+
}
|
|
38
|
+
catch (e) {
|
|
39
|
+
log.error("multicallContractCall failed", e);
|
|
40
|
+
throw new Error("❌ failed to decode multicall data");
|
|
41
|
+
}
|
|
42
|
+
return contract.interface.decodeFunctionResult("aggregate3", result)[0].map((r) => r?.returnData);
|
|
43
|
+
}
|
|
44
|
+
export async function batchMulticallCall(func, contract, args, shouldRetry = true) {
|
|
45
|
+
let callsLeft = args.data.length;
|
|
46
|
+
let lowerIdx = 0;
|
|
47
|
+
let upperIdx = Math.min(args.data.length, MAX_NUM_SUBCALLS);
|
|
48
|
+
const multicallBatch = [];
|
|
49
|
+
while (callsLeft !== 0) {
|
|
50
|
+
multicallBatch.push(shouldRetry
|
|
51
|
+
? withRetry(func, [
|
|
52
|
+
// TODO: fix typing
|
|
53
|
+
contract,
|
|
54
|
+
{
|
|
55
|
+
blockNumber: args.blockNumber,
|
|
56
|
+
data: args.data.slice(lowerIdx, upperIdx),
|
|
57
|
+
},
|
|
58
|
+
])
|
|
59
|
+
: func(contract, args));
|
|
60
|
+
callsLeft -= upperIdx - lowerIdx;
|
|
61
|
+
lowerIdx = upperIdx;
|
|
62
|
+
upperIdx = Math.min(args.data.length, upperIdx + MAX_NUM_SUBCALLS);
|
|
63
|
+
}
|
|
64
|
+
/** Executing batched multicall */
|
|
65
|
+
const results = await Promise.allSettled(multicallBatch);
|
|
66
|
+
let fetchedData = [];
|
|
67
|
+
for (let k = 0; k < results.length; k++) {
|
|
68
|
+
const res = results[k];
|
|
69
|
+
if (res.status === "fulfilled") {
|
|
70
|
+
fetchedData = fetchedData.concat(res.value);
|
|
71
|
+
}
|
|
72
|
+
else {
|
|
73
|
+
log.error(`batchMulticallCall failed to ${args.data[k].target}, data: ${args.data[k].callData}`, res);
|
|
74
|
+
fetchedData.concat("0x");
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
return fetchedData;
|
|
78
|
+
}
|
|
79
|
+
export async function archiveContractMethodCall(contract, args) {
|
|
80
|
+
return contract.interface.decodeFunctionResult("aggregate3", !!args.blockNumber
|
|
81
|
+
? await contract.provider.call({
|
|
82
|
+
data: contract.interface.encodeFunctionData("aggregate3", [args.calls]),
|
|
83
|
+
to: contract.address,
|
|
84
|
+
}, BigNumber.from(args.blockNumber).toNumber())
|
|
85
|
+
: await contract.provider.call({
|
|
86
|
+
data: contract.interface.encodeFunctionData("aggregate3", [args.calls]),
|
|
87
|
+
to: contract.address,
|
|
88
|
+
}))[0];
|
|
89
|
+
}
|
|
90
|
+
export async function batchMulticallCallWithRetry(chainId, args) {
|
|
91
|
+
let fetchedData = [];
|
|
92
|
+
let remainingCalls = args.calls.length;
|
|
93
|
+
let lowerIdx = 0;
|
|
94
|
+
let upperIdx = Math.min(args.calls.length, MAX_NUM_SUBCALLS);
|
|
95
|
+
const multicallBatch = [];
|
|
96
|
+
while (remainingCalls !== 0) {
|
|
97
|
+
multicallBatch.push(await withRetry(archiveContractMethodCall, [
|
|
98
|
+
multicalls[chainId],
|
|
99
|
+
{
|
|
100
|
+
blockNumber: args.blockNumber,
|
|
101
|
+
calls: args.calls.slice(lowerIdx, upperIdx),
|
|
102
|
+
},
|
|
103
|
+
]));
|
|
104
|
+
remainingCalls -= upperIdx - lowerIdx;
|
|
105
|
+
lowerIdx = upperIdx;
|
|
106
|
+
upperIdx = Math.min(args.calls.length, upperIdx + MAX_NUM_SUBCALLS);
|
|
107
|
+
}
|
|
108
|
+
/** Executing batched multicall */
|
|
109
|
+
const results = await Promise.allSettled(multicallBatch);
|
|
110
|
+
for (let k = 0; k < results.length; k++) {
|
|
111
|
+
const res = results[k];
|
|
112
|
+
if (res.status === "fulfilled") {
|
|
113
|
+
fetchedData = fetchedData.concat(res.value);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
return fetchedData;
|
|
117
|
+
}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { Redis } from "../cache";
|
|
2
|
+
import { hashArray } from "./hashArray";
|
|
3
|
+
import { BigNumber } from "ethers";
|
|
4
|
+
import moment from "moment";
|
|
5
|
+
import { log } from "./logger";
|
|
6
|
+
import { providers } from "./providers";
|
|
7
|
+
/**
|
|
8
|
+
* Fetches the timestamp of a block with up to RETRIES retries in case of failure
|
|
9
|
+
*/
|
|
10
|
+
const RETRIES = 10;
|
|
11
|
+
export const getBlockTimestamp = async (provider, blockNumber) => {
|
|
12
|
+
let res = null;
|
|
13
|
+
let trial = 0;
|
|
14
|
+
while (res === null && trial < RETRIES) {
|
|
15
|
+
try {
|
|
16
|
+
res = await provider.send("eth_getBlockByNumber", [`0x${blockNumber.toString(16)}`, false]);
|
|
17
|
+
}
|
|
18
|
+
catch { }
|
|
19
|
+
trial++;
|
|
20
|
+
}
|
|
21
|
+
if (trial > 1) {
|
|
22
|
+
console.log(`${trial - 1} calls failed fetching blocktimestamp for block ${blockNumber}.`);
|
|
23
|
+
}
|
|
24
|
+
return BigNumber.from(res?.timestamp).toNumber();
|
|
25
|
+
};
|
|
26
|
+
/**
|
|
27
|
+
* Binary search to search the last block before a given timestamp
|
|
28
|
+
*/
|
|
29
|
+
const getLastBlockBefore = async (timestamp, chainId) => {
|
|
30
|
+
if (moment().unix() < timestamp) {
|
|
31
|
+
log.error("getLastBlockBefore", `Timestamp ${timestamp} is in the future`);
|
|
32
|
+
return 0;
|
|
33
|
+
}
|
|
34
|
+
const provider = providers[chainId];
|
|
35
|
+
const current = await provider.getBlockNumber();
|
|
36
|
+
let upper = current;
|
|
37
|
+
let lower = 0;
|
|
38
|
+
let step = Math.floor((upper - lower) / 2);
|
|
39
|
+
let fixUpper = false;
|
|
40
|
+
let fixLower = false;
|
|
41
|
+
while (upper - lower > 1) {
|
|
42
|
+
// Reduce step size of interval has been found
|
|
43
|
+
if (upper - lower < 2 * step) {
|
|
44
|
+
step = Math.floor(step / 2);
|
|
45
|
+
fixUpper = false;
|
|
46
|
+
fixLower = false;
|
|
47
|
+
}
|
|
48
|
+
// Check reduction of upper bound
|
|
49
|
+
if (!fixUpper) {
|
|
50
|
+
const auxUpper = upper - step;
|
|
51
|
+
const auxUpperTimestamp = await getBlockTimestamp(provider, auxUpper);
|
|
52
|
+
if (auxUpperTimestamp > timestamp) {
|
|
53
|
+
upper = auxUpper;
|
|
54
|
+
}
|
|
55
|
+
else {
|
|
56
|
+
fixUpper = true;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
// Check reduction of lower bound
|
|
60
|
+
if (!fixLower) {
|
|
61
|
+
const auxLower = lower + step;
|
|
62
|
+
const auxLowerTimestamp = await getBlockTimestamp(provider, auxLower);
|
|
63
|
+
if (auxLowerTimestamp <= timestamp) {
|
|
64
|
+
lower = auxLower;
|
|
65
|
+
}
|
|
66
|
+
else {
|
|
67
|
+
// auxLower timestamp >= timestamp
|
|
68
|
+
// We want to return the last block with a timestamp <= timestamp
|
|
69
|
+
fixLower = true;
|
|
70
|
+
if (auxLowerTimestamp === timestamp) {
|
|
71
|
+
return auxLower;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
return lower;
|
|
77
|
+
};
|
|
78
|
+
export const getLastBlockBeforeWithCache = async (timestamp, chainId) => await Redis.getOrSet(`LastBlockBefore_${hashArray([timestamp, chainId])}`, getLastBlockBefore, timestamp, chainId);
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { createPinoLogger } from "@bogeychan/elysia-logger";
|
|
2
|
+
export const logger = createPinoLogger({
|
|
3
|
+
base: undefined,
|
|
4
|
+
formatters: {
|
|
5
|
+
level(level) {
|
|
6
|
+
return { level };
|
|
7
|
+
},
|
|
8
|
+
},
|
|
9
|
+
level: process.env.LOG_LEVEL || "info",
|
|
10
|
+
name: process.env.APP_NAME || "api",
|
|
11
|
+
transport: process.env.ENV !== "local"
|
|
12
|
+
? undefined
|
|
13
|
+
: {
|
|
14
|
+
options: {
|
|
15
|
+
colorize: true,
|
|
16
|
+
ignore: "time,name,hostname,pid,baseUrl,fullUrl,requestId,chain",
|
|
17
|
+
messageFormat: "\u001b[35m{baseUrl}\u001b[39m \u001b[33m{chain}\u001b[39m {msg}",
|
|
18
|
+
},
|
|
19
|
+
target: "pino-pretty",
|
|
20
|
+
},
|
|
21
|
+
});
|
|
22
|
+
const logConstructor = (type, message, errorMessage, onlyDev, service, url) => {
|
|
23
|
+
if (onlyDev && process.env.ENV !== "local")
|
|
24
|
+
return;
|
|
25
|
+
if (type === "error") {
|
|
26
|
+
if (!!service && !!url) {
|
|
27
|
+
logger.child({ service, url }).error(errorMessage, message);
|
|
28
|
+
}
|
|
29
|
+
else if (!!service) {
|
|
30
|
+
logger.child({ service }).error(errorMessage, message);
|
|
31
|
+
}
|
|
32
|
+
else {
|
|
33
|
+
logger.error(errorMessage, message);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
else if (type === "warn") {
|
|
37
|
+
logger.warn(message);
|
|
38
|
+
}
|
|
39
|
+
else if (type === "debug") {
|
|
40
|
+
logger.debug(message);
|
|
41
|
+
}
|
|
42
|
+
else {
|
|
43
|
+
logger.info(message);
|
|
44
|
+
}
|
|
45
|
+
};
|
|
46
|
+
export const log = {
|
|
47
|
+
debug: (message) => logConstructor("debug", message),
|
|
48
|
+
error: (message, errorMessage, service, url) => logConstructor("error", message, errorMessage, false, service, url),
|
|
49
|
+
info: (message) => logConstructor("info", message),
|
|
50
|
+
local: (message) => logConstructor("info", message, undefined, true),
|
|
51
|
+
warn: (message) => logConstructor("warn", message),
|
|
52
|
+
};
|
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
import { Redis } from "../cache";
|
|
2
|
+
import { ChainId, NETWORK_LABELS } from "@sdk";
|
|
3
|
+
import axios from "axios";
|
|
4
|
+
import { log } from "./logger";
|
|
5
|
+
import PriceService from "./prices/priceService";
|
|
6
|
+
const defiLamaChains = {
|
|
7
|
+
[ChainId.MAINNET]: "ethereum",
|
|
8
|
+
[ChainId.POLYGON]: "polygon",
|
|
9
|
+
[ChainId.FANTOM]: "fantom",
|
|
10
|
+
[ChainId.AVALANCHE]: "avax",
|
|
11
|
+
[ChainId.BSC]: "bsc",
|
|
12
|
+
[ChainId.OPTIMISM]: "optimism",
|
|
13
|
+
[ChainId.ARBITRUM]: "arbitrum",
|
|
14
|
+
[ChainId.BASE]: "base",
|
|
15
|
+
[ChainId.GNOSIS]: "gnosis",
|
|
16
|
+
};
|
|
17
|
+
export var PRICING_METHODS;
|
|
18
|
+
(function (PRICING_METHODS) {
|
|
19
|
+
PRICING_METHODS[PRICING_METHODS["defillama"] = 0] = "defillama";
|
|
20
|
+
PRICING_METHODS[PRICING_METHODS["quickswap"] = 1] = "quickswap";
|
|
21
|
+
PRICING_METHODS[PRICING_METHODS["abandonned"] = -1] = "abandonned";
|
|
22
|
+
})(PRICING_METHODS || (PRICING_METHODS = {}));
|
|
23
|
+
export class Pricer {
|
|
24
|
+
prices;
|
|
25
|
+
extraPricesData;
|
|
26
|
+
constructor(prices, extraPricesData) {
|
|
27
|
+
this.prices = prices;
|
|
28
|
+
this.extraPricesData = extraPricesData;
|
|
29
|
+
}
|
|
30
|
+
static async load() {
|
|
31
|
+
const { prices, extraPricesData } = await Redis.get("Prices");
|
|
32
|
+
const pricer = new Pricer(prices ?? {}, extraPricesData ?? []);
|
|
33
|
+
if (!prices) {
|
|
34
|
+
log.error("Pricer", "prices not found in cache when instanciating class");
|
|
35
|
+
await pricer.update();
|
|
36
|
+
}
|
|
37
|
+
return pricer;
|
|
38
|
+
}
|
|
39
|
+
getArray() {
|
|
40
|
+
return Object.keys(this.prices)
|
|
41
|
+
.filter(t => this.prices[t] >= 0)
|
|
42
|
+
.map(t => {
|
|
43
|
+
return {
|
|
44
|
+
rate: this.prices[t],
|
|
45
|
+
token: t,
|
|
46
|
+
};
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
/** Tries to fetch a given price sequentially using a given method */
|
|
50
|
+
async fetchPerMethod(x, method) {
|
|
51
|
+
switch (method) {
|
|
52
|
+
case PRICING_METHODS.abandonned:
|
|
53
|
+
return 0;
|
|
54
|
+
case PRICING_METHODS.defillama: {
|
|
55
|
+
let defillamaId;
|
|
56
|
+
if (!!x.chainId && !!x.address) {
|
|
57
|
+
defillamaId = `${defiLamaChains[x.chainId] ?? NETWORK_LABELS[x.chainId].toLowerCase()}:${x.address}`;
|
|
58
|
+
}
|
|
59
|
+
else {
|
|
60
|
+
defillamaId = `coingecko:${x.symbol}`;
|
|
61
|
+
}
|
|
62
|
+
const defillamaUrl = `https://coins.llama.fi/prices/current/${defillamaId}`;
|
|
63
|
+
try {
|
|
64
|
+
return (await axios.get(defillamaUrl, { timeout: 1000 })).data.coins[defillamaId].price;
|
|
65
|
+
}
|
|
66
|
+
catch { }
|
|
67
|
+
break;
|
|
68
|
+
}
|
|
69
|
+
case PRICING_METHODS.quickswap:
|
|
70
|
+
if (!!x.chainId && !!x.address) {
|
|
71
|
+
const quickswapUrl = `https://leaderboard.quickswap.exchange/utils/token-prices/v3?chainId=${x.chainId}&addresses=${x.address}`;
|
|
72
|
+
try {
|
|
73
|
+
return (await axios.get(quickswapUrl, { timeout: 1000 })).data?.[0].price;
|
|
74
|
+
}
|
|
75
|
+
catch { }
|
|
76
|
+
}
|
|
77
|
+
break;
|
|
78
|
+
}
|
|
79
|
+
return 0;
|
|
80
|
+
}
|
|
81
|
+
/** Tries to fetch a given price sequentially using all available methods */
|
|
82
|
+
async fetch(x) {
|
|
83
|
+
if (!!x.symbol && x.symbol?.toLowerCase().includes("test"))
|
|
84
|
+
return { method: PRICING_METHODS.abandonned, price: 0 };
|
|
85
|
+
for (const method of Object.values(PRICING_METHODS)) {
|
|
86
|
+
if (method === Number.parseInt(method.toString())) {
|
|
87
|
+
const price = await this.fetchPerMethod(x, method);
|
|
88
|
+
if (!!price)
|
|
89
|
+
return { method, price };
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
return { method: PRICING_METHODS.abandonned, price: 0 };
|
|
93
|
+
}
|
|
94
|
+
/** Returns the price if possible, otherwise tries to fetch it */
|
|
95
|
+
async get(x) {
|
|
96
|
+
if (x.symbol === "test")
|
|
97
|
+
return 0; // FIXME
|
|
98
|
+
// Normalize address
|
|
99
|
+
x.address = x?.address?.toLowerCase();
|
|
100
|
+
if (!!x.address && !!this.prices[x.address]) {
|
|
101
|
+
if (this.prices[x.address] !== -1)
|
|
102
|
+
return this.prices[x.address];
|
|
103
|
+
}
|
|
104
|
+
if (!!x.symbol && !!this.prices[x.symbol]) {
|
|
105
|
+
if (this.prices[x.symbol] === -1)
|
|
106
|
+
return undefined;
|
|
107
|
+
return this.prices[x.symbol];
|
|
108
|
+
}
|
|
109
|
+
if (!!x.symbol && x.symbol.toLowerCase().startsWith("w")) {
|
|
110
|
+
const symbol = x.symbol.slice(1);
|
|
111
|
+
if (!!this.prices[symbol]) {
|
|
112
|
+
if (this.prices[symbol] === -1)
|
|
113
|
+
return undefined;
|
|
114
|
+
return this.prices[symbol];
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
if (!!x.symbol && x.symbol.toLowerCase().startsWith("r")) {
|
|
118
|
+
const symbol = x.symbol.slice(1);
|
|
119
|
+
if (!!this.prices[symbol]) {
|
|
120
|
+
if (this.prices[symbol] === -1)
|
|
121
|
+
return undefined;
|
|
122
|
+
return this.prices[symbol];
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
if (!!x.symbol && x.symbol.toLowerCase().startsWith("r") && x.symbol.toLowerCase().endsWith("n")) {
|
|
126
|
+
const symbol = x.symbol.slice(1, -1);
|
|
127
|
+
if (!!this.prices[symbol]) {
|
|
128
|
+
if (this.prices[symbol] === -1)
|
|
129
|
+
return undefined;
|
|
130
|
+
return this.prices[symbol];
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
if (!!x.symbol && x.symbol.toLowerCase().startsWith("variableDebt")) {
|
|
134
|
+
const symbol = x.symbol.slice(12);
|
|
135
|
+
if (!!this.prices[symbol]) {
|
|
136
|
+
if (this.prices[symbol] === -1)
|
|
137
|
+
return undefined;
|
|
138
|
+
return this.prices[symbol];
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
if (!!x.symbol && x.symbol.toLowerCase().startsWith("variableDebt") && x.symbol.toLowerCase().endsWith("n")) {
|
|
142
|
+
const symbol = x.symbol.slice(12, -1);
|
|
143
|
+
if (!!this.prices[symbol]) {
|
|
144
|
+
if (this.prices[symbol] === -1)
|
|
145
|
+
return undefined;
|
|
146
|
+
return this.prices[symbol];
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
/** Saves the current price data in the cache */
|
|
151
|
+
async save() {
|
|
152
|
+
await Redis.safeSet("Prices", {
|
|
153
|
+
extraPricesData: this.extraPricesData,
|
|
154
|
+
prices: this.prices,
|
|
155
|
+
});
|
|
156
|
+
}
|
|
157
|
+
/** Recomputes all prices and saves them in the cache */
|
|
158
|
+
async update() {
|
|
159
|
+
// Update prices
|
|
160
|
+
this.prices = await PriceService.instance.fetchPrices();
|
|
161
|
+
// Update extra prices
|
|
162
|
+
this.extraPricesData = this.extraPricesData.filter(x => !!x.symbol && this.prices[x.symbol] === undefined && !!x.address && this.prices[x.address] === undefined);
|
|
163
|
+
for (const x of this.extraPricesData) {
|
|
164
|
+
try {
|
|
165
|
+
const price = await this.fetchPerMethod({ address: x.address, chainId: x.chainId, symbol: x.symbol }, x.method);
|
|
166
|
+
if (!!price) {
|
|
167
|
+
log.info(`price for ${x.symbol} - ${x.address} on ${NETWORK_LABELS[x.chainId ?? 1]}: ${price} added to cache`);
|
|
168
|
+
if (!!x.address && this.prices[x.address] === undefined)
|
|
169
|
+
this.prices[x.address] = price;
|
|
170
|
+
if (!!x.symbol && this.prices[x.symbol] === undefined)
|
|
171
|
+
this.prices[x.symbol] = price;
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
catch (e) {
|
|
175
|
+
log.error("pricer update", e);
|
|
176
|
+
}
|
|
177
|
+
} // Update extraPricesData
|
|
178
|
+
await this.save();
|
|
179
|
+
}
|
|
180
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { BN2Number } from "@sdk";
|
|
2
|
+
import { Contract, utils } from "ethers";
|
|
3
|
+
import { providers } from "../providers";
|
|
4
|
+
export async function getChainlinkLatestPrice(chainId, oracle) {
|
|
5
|
+
const abi = new utils.Interface(["function latestAnswer() external view returns(int256)"]);
|
|
6
|
+
const contract = new Contract(oracle, abi, providers[chainId]);
|
|
7
|
+
return BN2Number(await contract.latestAnswer(), 8);
|
|
8
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { BN2Number } from "@sdk";
|
|
2
|
+
import { Contract } from "ethers";
|
|
3
|
+
import { providers } from "../providers";
|
|
4
|
+
export async function getVirtualPrice(chainId, pool) {
|
|
5
|
+
const contract = new Contract(pool, ["function get_virtual_price() external view returns(uint256)"], providers[chainId]);
|
|
6
|
+
return BN2Number(await contract.get_virtual_price());
|
|
7
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { BN2Number } from "@sdk";
|
|
2
|
+
import { Contract, utils } from "ethers";
|
|
3
|
+
import { providers } from "../providers";
|
|
4
|
+
export async function getDQUICKPrice(chainId, contractAddress, assetDecimals = 18, vaultDecimals = 18) {
|
|
5
|
+
const contract = new Contract(contractAddress, ["function dQUICKForQUICK(uint256) external view returns(uint256)"], providers[chainId]);
|
|
6
|
+
const assetAmount = await contract.dQUICKForQUICK(utils.parseUnits("1", vaultDecimals));
|
|
7
|
+
return BN2Number(assetAmount, assetDecimals);
|
|
8
|
+
}
|