@defisaver/positions-sdk 2.1.127-dev → 2.1.127-uniswap-dev

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.
@@ -2,4 +2,5 @@ import * as aaveV3Claim from './aaveV3';
2
2
  import * as compV3Claim from './compV3';
3
3
  import * as kingV3Claim from './king';
4
4
  import * as sparkClaim from './spark';
5
- export { aaveV3Claim, compV3Claim, kingV3Claim, sparkClaim, };
5
+ import * as uniswapClaim from './uniswap';
6
+ export { aaveV3Claim, compV3Claim, kingV3Claim, sparkClaim, uniswapClaim, };
@@ -33,7 +33,7 @@ var __importStar = (this && this.__importStar) || (function () {
33
33
  };
34
34
  })();
35
35
  Object.defineProperty(exports, "__esModule", { value: true });
36
- exports.sparkClaim = exports.kingV3Claim = exports.compV3Claim = exports.aaveV3Claim = void 0;
36
+ exports.uniswapClaim = exports.sparkClaim = exports.kingV3Claim = exports.compV3Claim = exports.aaveV3Claim = void 0;
37
37
  const aaveV3Claim = __importStar(require("./aaveV3"));
38
38
  exports.aaveV3Claim = aaveV3Claim;
39
39
  const compV3Claim = __importStar(require("./compV3"));
@@ -42,3 +42,5 @@ const kingV3Claim = __importStar(require("./king"));
42
42
  exports.kingV3Claim = kingV3Claim;
43
43
  const sparkClaim = __importStar(require("./spark"));
44
44
  exports.sparkClaim = sparkClaim;
45
+ const uniswapClaim = __importStar(require("./uniswap"));
46
+ exports.uniswapClaim = uniswapClaim;
@@ -0,0 +1,4 @@
1
+ import { Client } from 'viem';
2
+ import { EthAddress, NetworkNumber } from '../types';
3
+ export declare const fetchUniswapRewardsData: (walletAddress: EthAddress) => Promise<any>;
4
+ export declare const getUniswapRewards: (provider: Client, network: NetworkNumber, walletAddresses: EthAddress[]) => Promise<Record<string, any[]>>;
@@ -0,0 +1,70 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ var __importDefault = (this && this.__importDefault) || function (mod) {
12
+ return (mod && mod.__esModule) ? mod : { "default": mod };
13
+ };
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ exports.getUniswapRewards = exports.fetchUniswapRewardsData = void 0;
16
+ const decimal_js_1 = __importDefault(require("decimal.js"));
17
+ const tokens_1 = require("@defisaver/tokens");
18
+ const contracts_1 = require("../contracts");
19
+ const claiming_1 = require("../types/claiming");
20
+ const EMPTY_DATA = (walletAddress) => ({
21
+ address: walletAddress, index: 0, amount: '0x0', proof: [],
22
+ });
23
+ const fetchUniswapRewardsData = (walletAddress) => __awaiter(void 0, void 0, void 0, function* () {
24
+ try {
25
+ const res = yield fetch(`https://uniswap-merkl-drop.defisaver.com/claims/${walletAddress}`, { signal: AbortSignal.timeout(5000) });
26
+ if (!res.ok)
27
+ throw new Error(yield res.text());
28
+ const data = yield res.json();
29
+ if (data.error)
30
+ return EMPTY_DATA(walletAddress);
31
+ return data;
32
+ }
33
+ catch (err) {
34
+ console.error('External API Error: Error fetching Uniswap rewards:', err);
35
+ return EMPTY_DATA(walletAddress);
36
+ }
37
+ });
38
+ exports.fetchUniswapRewardsData = fetchUniswapRewardsData;
39
+ const getUniswapRewards = (provider, network, walletAddresses) => __awaiter(void 0, void 0, void 0, function* () {
40
+ // Fetch all API data in parallel (these are external API calls, can't be batched with multicall)
41
+ const apiDataPromises = walletAddresses.map(address => (0, exports.fetchUniswapRewardsData)(address));
42
+ const apiDataArray = yield Promise.all(apiDataPromises);
43
+ // Batch all contract calls using multicall
44
+ const contract = (0, contracts_1.UniswapTokenDistributorViem)(provider, network);
45
+ const cumulativePromises = apiDataArray.map(data => (data.index ? contract.read.isClaimed([data.index]) : Promise.resolve(false)));
46
+ const cumulativeResults = yield Promise.all(cumulativePromises);
47
+ // Process results
48
+ const results = {};
49
+ for (let i = 0; i < walletAddresses.length; i++) {
50
+ const walletAddress = walletAddresses[i];
51
+ const data = apiDataArray[i];
52
+ const cumulative = cumulativeResults[i];
53
+ const amountToClaim = new decimal_js_1.default(data.amount);
54
+ if (amountToClaim.lessThanOrEqualTo('0')) {
55
+ results[walletAddress.toLowerCase()] = [];
56
+ }
57
+ else {
58
+ results[walletAddress.toLowerCase()] = [{
59
+ amount: (0, tokens_1.assetAmountInEth)(amountToClaim.toString(), 'UNI'),
60
+ walletAddress,
61
+ claimType: claiming_1.ClaimType.UNI_REWARDS,
62
+ index: data.index,
63
+ proof: data.proof,
64
+ isClaimed: cumulative,
65
+ }];
66
+ }
67
+ }
68
+ return results;
69
+ });
70
+ exports.getUniswapRewards = getUniswapRewards;
@@ -99091,3 +99091,25 @@ export declare const AaveV4View: {
99091
99091
  };
99092
99092
  };
99093
99093
  };
99094
+ export declare const UniswapTokenDistributor: {
99095
+ readonly abi: readonly [{
99096
+ readonly inputs: readonly [{
99097
+ readonly internalType: "uint256";
99098
+ readonly name: "index";
99099
+ readonly type: "uint256";
99100
+ }];
99101
+ readonly name: "isClaimed";
99102
+ readonly outputs: readonly [{
99103
+ readonly internalType: "bool";
99104
+ readonly name: "";
99105
+ readonly type: "bool";
99106
+ }];
99107
+ readonly stateMutability: "view";
99108
+ readonly type: "function";
99109
+ }];
99110
+ readonly networks: {
99111
+ readonly "1": {
99112
+ readonly address: "0x090D4613473dEE047c3f2706764f49E0821D256e";
99113
+ };
99114
+ };
99115
+ };
@@ -3,6 +3,7 @@
3
3
  Object.defineProperty(exports, "__esModule", { value: true });
4
4
  exports.LiquityView = exports.crvUSDFactory = exports.crvUSDView = exports.crvUSDsfrxETHAmm = exports.crvUSDtBTCAmm = exports.crvUSDWBTCAmm = exports.crvUSDETHAmm = exports.crvUSDwstETHAmm = exports.crvUSDsfrxETHController = exports.crvUSDtBTCController = exports.crvUSDWBTCController = exports.crvUSDETHController = exports.crvUSDwstETHController = exports.SparkProtocolDataProvider = exports.SparkPoolAddressesProvider = exports.SparkLendingPool = exports.SparkIncentiveDataProvider = exports.SparkView = exports.Pot = exports.IAToken = exports.IVariableDebtToken = exports.Comptroller = exports.CompoundLoanInfo = exports.AaveLendingPoolV2 = exports.AaveProtocolDataProvider = exports.LendingPoolAddressesProvider = exports.AaveLoanInfoV2 = exports.wstETH = exports.CompV3BulkerL2 = exports.CompV3BulkerMainnetETH = exports.CompV3BulkerMainnetUSDC = exports.CompV3View = exports.cWstETHv3 = exports.cUSDSv3 = exports.cUSDTv3 = exports.cETHv3 = exports.cUSDbCv3 = exports.cUSDCev3 = exports.cUSDCv3 = exports.AaveUiIncentiveDataProviderV3 = exports.AaveV3EtherfiProtocolDataProvider = exports.AaveV3LidoProtocolDataProvider = exports.AaveV3ProtocolDataProvider = exports.AaveV3EtherfiLendingPool = exports.AaveV3LidoLendingPool = exports.AaveV3LendingPool = exports.AaveV3EtherfiPoolAddressesProvider = exports.AaveV3LidoPoolAddressesProvider = exports.AaveV3PoolAddressesProvider = exports.AaveV3View = void 0;
5
5
  exports.AaveV4View = exports.YearnV3Vault = exports.SkySavings = exports.SparkSavingsVault = exports.MakerDsr = exports.YearnView = exports.YearnVault = exports.MorphoVault = exports.StkAAVE = exports.LiquityV2sBoldVault = exports.LiquityV2ActivePool = exports.AaveRewardsController = exports.SparkRewardsController = exports.SparkAirdrop = exports.UUPS = exports.LiquityStabilityPool = exports.LiquityLQTYStaking = exports.AaveUmbrellaView = exports.Erc4626 = exports.Erc20 = exports.AaveIncentivesController = exports.McdCdpManager = exports.McdGetCdps = exports.FluidView = exports.LiquityV2StabilityPool = exports.EulerV2View = exports.LiquityV2TroveNFT = exports.LiquityV2CollSurplusPool = exports.LiquityV2View = exports.LiquityV2LegacyView = exports.LlamaLendControllerAbi = exports.LlamaLendView = exports.DFSFeedRegistry = exports.FeedRegistry = exports.MorphoBlueView = exports.WeETHPriceFeed = exports.WstETHPriceFeed = exports.USDCPriceFeed = exports.BTCPriceFeed = exports.ETHPriceFeed = exports.COMPPriceFeed = exports.McdDog = exports.McdJug = exports.McdVat = exports.McdSpotter = exports.McdView = exports.LiquityActivePool = exports.PriceFeed = exports.TroveManager = exports.CollSurplusPool = void 0;
6
+ exports.UniswapTokenDistributor = void 0;
6
7
  exports.AaveV3View = {
7
8
  "abi": [{ "inputs": [], "name": "AAVE_REFERRAL_CODE", "outputs": [{ "internalType": "uint16", "name": "", "type": "uint16" }], "stateMutability": "view", "type": "function" }, { "inputs": [{ "internalType": "address", "name": "_umbrella", "type": "address" }, { "internalType": "address", "name": "_user", "type": "address" }], "name": "getAdditionalUmbrellaStakingData", "outputs": [{ "components": [{ "internalType": "address", "name": "stkToken", "type": "address" }, { "internalType": "uint256", "name": "totalShares", "type": "uint256" }, { "internalType": "address", "name": "stkUnderlyingToken", "type": "address" }, { "internalType": "address", "name": "aToken", "type": "address" }, { "internalType": "uint256", "name": "cooldownPeriod", "type": "uint256" }, { "internalType": "uint256", "name": "unstakeWindow", "type": "uint256" }, { "internalType": "uint256", "name": "stkTokenToWaTokenRate", "type": "uint256" }, { "internalType": "uint256", "name": "waTokenToATokenRate", "type": "uint256" }, { "internalType": "uint256[]", "name": "rewardsEmissionRates", "type": "uint256[]" }, { "internalType": "uint256", "name": "userCooldownAmount", "type": "uint256" }, { "internalType": "uint256", "name": "userEndOfCooldown", "type": "uint256" }, { "internalType": "uint256", "name": "userWithdrawalWindow", "type": "uint256" }], "internalType": "struct AaveV3View.UmbrellaStkData[]", "name": "retVal", "type": "tuple[]" }], "stateMutability": "view", "type": "function" }, { "inputs": [{ "internalType": "address", "name": "_market", "type": "address" }], "name": "getAllEmodes", "outputs": [{ "components": [{ "internalType": "uint16", "name": "ltv", "type": "uint16" }, { "internalType": "uint16", "name": "liquidationThreshold", "type": "uint16" }, { "internalType": "uint16", "name": "liquidationBonus", "type": "uint16" }, { "internalType": "uint128", "name": "collateralBitmap", "type": "uint128" }, { "internalType": "bool", "name": "isolated", "type": "bool" }, { "internalType": "string", "name": "label", "type": "string" }, { "internalType": "uint128", "name": "borrowableBitmap", "type": "uint128" }, { "internalType": "uint128", "name": "ltvzeroBitmap", "type": "uint128" }], "internalType": "struct DataTypes.EModeCategoryNew[]", "name": "emodesData", "type": "tuple[]" }], "stateMutability": "view", "type": "function" }, { "inputs": [{ "internalType": "address", "name": "_market", "type": "address" }, { "components": [{ "internalType": "address", "name": "reserveAddress", "type": "address" }, { "internalType": "uint256", "name": "liquidityAdded", "type": "uint256" }, { "internalType": "uint256", "name": "liquidityTaken", "type": "uint256" }, { "internalType": "bool", "name": "isDebtAsset", "type": "bool" }], "internalType": "struct AaveV3View.LiquidityChangeParams[]", "name": "_reserveParams", "type": "tuple[]" }], "name": "getApyAfterValuesEstimation", "outputs": [{ "components": [{ "internalType": "address", "name": "reserveAddress", "type": "address" }, { "internalType": "uint256", "name": "supplyRate", "type": "uint256" }, { "internalType": "uint256", "name": "variableBorrowRate", "type": "uint256" }], "internalType": "struct AaveV3View.EstimatedRates[]", "name": "", "type": "tuple[]" }], "stateMutability": "view", "type": "function" }, { "inputs": [{ "internalType": "address", "name": "_market", "type": "address" }, { "internalType": "address", "name": "_tokenAddr", "type": "address" }], "name": "getAssetPrice", "outputs": [{ "internalType": "uint256", "name": "price", "type": "uint256" }], "stateMutability": "view", "type": "function" }, { "inputs": [{ "internalType": "address", "name": "_market", "type": "address" }, { "internalType": "address[]", "name": "_tokens", "type": "address[]" }], "name": "getCollFactors", "outputs": [{ "internalType": "uint256[]", "name": "collFactors", "type": "uint256[]" }], "stateMutability": "view", "type": "function" }, { "inputs": [{ "internalType": "uint256", "name": "emodeCategory", "type": "uint256" }, { "internalType": "contract IPoolV3", "name": "lendingPool", "type": "address" }], "name": "getEModeCollateralFactor", "outputs": [{ "internalType": "uint16", "name": "", "type": "uint16" }], "stateMutability": "view", "type": "function" }, { "inputs": [{ "internalType": "address", "name": "_asset", "type": "address" }, { "internalType": "address", "name": "_eoa", "type": "address" }, { "internalType": "address", "name": "_proxy", "type": "address" }, { "internalType": "address", "name": "_market", "type": "address" }], "name": "getEOAApprovalsAndBalances", "outputs": [{ "components": [{ "internalType": "address", "name": "asset", "type": "address" }, { "internalType": "address", "name": "aToken", "type": "address" }, { "internalType": "address", "name": "variableDebtToken", "type": "address" }, { "internalType": "uint256", "name": "assetApproval", "type": "uint256" }, { "internalType": "uint256", "name": "aTokenApproval", "type": "uint256" }, { "internalType": "uint256", "name": "variableDebtDelegation", "type": "uint256" }, { "internalType": "uint256", "name": "borrowedVariableAmount", "type": "uint256" }, { "internalType": "uint256", "name": "eoaBalance", "type": "uint256" }, { "internalType": "uint256", "name": "aTokenBalance", "type": "uint256" }], "internalType": "struct AaveV3View.EOAApprovalData", "name": "approvalData", "type": "tuple" }], "stateMutability": "view", "type": "function" }, { "inputs": [{ "internalType": "address", "name": "_eoa", "type": "address" }, { "internalType": "address", "name": "_proxy", "type": "address" }, { "internalType": "address", "name": "_market", "type": "address" }], "name": "getEOAApprovalsAndBalancesForAllTokens", "outputs": [{ "components": [{ "internalType": "address", "name": "asset", "type": "address" }, { "internalType": "address", "name": "aToken", "type": "address" }, { "internalType": "address", "name": "variableDebtToken", "type": "address" }, { "internalType": "uint256", "name": "assetApproval", "type": "uint256" }, { "internalType": "uint256", "name": "aTokenApproval", "type": "uint256" }, { "internalType": "uint256", "name": "variableDebtDelegation", "type": "uint256" }, { "internalType": "uint256", "name": "borrowedVariableAmount", "type": "uint256" }, { "internalType": "uint256", "name": "eoaBalance", "type": "uint256" }, { "internalType": "uint256", "name": "aTokenBalance", "type": "uint256" }], "internalType": "struct AaveV3View.EOAApprovalData[]", "name": "approvalData", "type": "tuple[]" }], "stateMutability": "view", "type": "function" }, { "inputs": [{ "internalType": "contract IPoolV3", "name": "_lendingPool", "type": "address" }, { "internalType": "uint8", "name": "_id", "type": "uint8" }], "name": "getEmodeData", "outputs": [{ "components": [{ "internalType": "uint16", "name": "ltv", "type": "uint16" }, { "internalType": "uint16", "name": "liquidationThreshold", "type": "uint16" }, { "internalType": "uint16", "name": "liquidationBonus", "type": "uint16" }, { "internalType": "uint128", "name": "collateralBitmap", "type": "uint128" }, { "internalType": "bool", "name": "isolated", "type": "bool" }, { "internalType": "string", "name": "label", "type": "string" }, { "internalType": "uint128", "name": "borrowableBitmap", "type": "uint128" }, { "internalType": "uint128", "name": "ltvzeroBitmap", "type": "uint128" }], "internalType": "struct DataTypes.EModeCategoryNew", "name": "emodeData", "type": "tuple" }], "stateMutability": "view", "type": "function" }, { "inputs": [{ "internalType": "address", "name": "_market", "type": "address" }, { "internalType": "address[]", "name": "_tokenAddresses", "type": "address[]" }], "name": "getFullTokensInfo", "outputs": [{ "components": [{ "internalType": "address", "name": "aTokenAddress", "type": "address" }, { "internalType": "address", "name": "underlyingTokenAddress", "type": "address" }, { "internalType": "uint16", "name": "assetId", "type": "uint16" }, { "internalType": "uint256", "name": "supplyRate", "type": "uint256" }, { "internalType": "uint256", "name": "borrowRateVariable", "type": "uint256" }, { "internalType": "uint256", "name": "borrowRateStable", "type": "uint256" }, { "internalType": "uint256", "name": "totalSupply", "type": "uint256" }, { "internalType": "uint256", "name": "availableLiquidity", "type": "uint256" }, { "internalType": "uint256", "name": "totalBorrow", "type": "uint256" }, { "internalType": "uint256", "name": "totalBorrowVar", "type": "uint256" }, { "internalType": "uint256", "name": "totalBorrowStab", "type": "uint256" }, { "internalType": "uint256", "name": "collateralFactor", "type": "uint256" }, { "internalType": "uint256", "name": "liquidationRatio", "type": "uint256" }, { "internalType": "uint256", "name": "price", "type": "uint256" }, { "internalType": "uint256", "name": "supplyCap", "type": "uint256" }, { "internalType": "uint256", "name": "borrowCap", "type": "uint256" }, { "internalType": "uint256", "name": "emodeCategory", "type": "uint256" }, { "internalType": "uint256", "name": "debtCeilingForIsolationMode", "type": "uint256" }, { "internalType": "uint256", "name": "isolationModeTotalDebt", "type": "uint256" }, { "internalType": "bool", "name": "usageAsCollateralEnabled", "type": "bool" }, { "internalType": "bool", "name": "borrowingEnabled", "type": "bool" }, { "internalType": "bool", "name": "stableBorrowRateEnabled", "type": "bool" }, { "internalType": "bool", "name": "isolationModeBorrowingEnabled", "type": "bool" }, { "internalType": "bool", "name": "isSiloedForBorrowing", "type": "bool" }, { "internalType": "uint256", "name": "eModeCollateralFactor", "type": "uint256" }, { "internalType": "bool", "name": "isFlashLoanEnabled", "type": "bool" }, { "internalType": "uint16", "name": "ltv", "type": "uint16" }, { "internalType": "uint16", "name": "liquidationThreshold", "type": "uint16" }, { "internalType": "uint16", "name": "liquidationBonus", "type": "uint16" }, { "internalType": "address", "name": "priceSource", "type": "address" }, { "internalType": "string", "name": "label", "type": "string" }, { "internalType": "bool", "name": "isActive", "type": "bool" }, { "internalType": "bool", "name": "isPaused", "type": "bool" }, { "internalType": "bool", "name": "isFrozen", "type": "bool" }, { "internalType": "address", "name": "debtTokenAddress", "type": "address" }], "internalType": "struct AaveV3View.TokenInfoFull[]", "name": "tokens", "type": "tuple[]" }], "stateMutability": "view", "type": "function" }, { "inputs": [{ "internalType": "address", "name": "_market", "type": "address" }, { "internalType": "address", "name": "_user", "type": "address" }], "name": "getHealthFactor", "outputs": [{ "internalType": "uint256", "name": "healthFactor", "type": "uint256" }], "stateMutability": "view", "type": "function" }, { "inputs": [{ "internalType": "address", "name": "_market", "type": "address" }, { "internalType": "address", "name": "_user", "type": "address" }], "name": "getLoanData", "outputs": [{ "components": [{ "internalType": "address", "name": "user", "type": "address" }, { "internalType": "uint128", "name": "ratio", "type": "uint128" }, { "internalType": "uint256", "name": "eMode", "type": "uint256" }, { "internalType": "address[]", "name": "collAddr", "type": "address[]" }, { "internalType": "bool[]", "name": "enabledAsColl", "type": "bool[]" }, { "internalType": "address[]", "name": "borrowAddr", "type": "address[]" }, { "internalType": "uint256[]", "name": "collAmounts", "type": "uint256[]" }, { "internalType": "uint256[]", "name": "borrowStableAmounts", "type": "uint256[]" }, { "internalType": "uint256[]", "name": "borrowVariableAmounts", "type": "uint256[]" }, { "internalType": "uint16", "name": "ltv", "type": "uint16" }, { "internalType": "uint16", "name": "liquidationThreshold", "type": "uint16" }, { "internalType": "uint16", "name": "liquidationBonus", "type": "uint16" }, { "internalType": "address", "name": "priceSource", "type": "address" }, { "internalType": "string", "name": "label", "type": "string" }], "internalType": "struct AaveV3View.LoanData", "name": "data", "type": "tuple" }], "stateMutability": "view", "type": "function" }, { "inputs": [{ "internalType": "address", "name": "_market", "type": "address" }, { "internalType": "address[]", "name": "_users", "type": "address[]" }], "name": "getLoanDataArr", "outputs": [{ "components": [{ "internalType": "address", "name": "user", "type": "address" }, { "internalType": "uint128", "name": "ratio", "type": "uint128" }, { "internalType": "uint256", "name": "eMode", "type": "uint256" }, { "internalType": "address[]", "name": "collAddr", "type": "address[]" }, { "internalType": "bool[]", "name": "enabledAsColl", "type": "bool[]" }, { "internalType": "address[]", "name": "borrowAddr", "type": "address[]" }, { "internalType": "uint256[]", "name": "collAmounts", "type": "uint256[]" }, { "internalType": "uint256[]", "name": "borrowStableAmounts", "type": "uint256[]" }, { "internalType": "uint256[]", "name": "borrowVariableAmounts", "type": "uint256[]" }, { "internalType": "uint16", "name": "ltv", "type": "uint16" }, { "internalType": "uint16", "name": "liquidationThreshold", "type": "uint16" }, { "internalType": "uint16", "name": "liquidationBonus", "type": "uint16" }, { "internalType": "address", "name": "priceSource", "type": "address" }, { "internalType": "string", "name": "label", "type": "string" }], "internalType": "struct AaveV3View.LoanData[]", "name": "loans", "type": "tuple[]" }], "stateMutability": "view", "type": "function" }, { "inputs": [{ "internalType": "address", "name": "_market", "type": "address" }, { "internalType": "address[]", "name": "_tokens", "type": "address[]" }], "name": "getPrices", "outputs": [{ "internalType": "uint256[]", "name": "prices", "type": "uint256[]" }], "stateMutability": "view", "type": "function" }, { "inputs": [{ "internalType": "address", "name": "_market", "type": "address" }, { "internalType": "address", "name": "_user", "type": "address" }], "name": "getRatio", "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], "stateMutability": "view", "type": "function" }, { "inputs": [{ "internalType": "address", "name": "_market", "type": "address" }, { "internalType": "address[]", "name": "_users", "type": "address[]" }], "name": "getRatios", "outputs": [{ "internalType": "uint256[]", "name": "ratios", "type": "uint256[]" }], "stateMutability": "view", "type": "function" }, { "inputs": [{ "internalType": "address", "name": "_market", "type": "address" }, { "internalType": "address", "name": "_user", "type": "address" }], "name": "getSafetyRatio", "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], "stateMutability": "view", "type": "function" }, { "inputs": [{ "internalType": "address", "name": "_market", "type": "address" }, { "internalType": "address", "name": "_user", "type": "address" }, { "internalType": "address[]", "name": "_tokens", "type": "address[]" }], "name": "getTokenBalances", "outputs": [{ "components": [{ "internalType": "address", "name": "token", "type": "address" }, { "internalType": "uint256", "name": "balance", "type": "uint256" }, { "internalType": "uint256", "name": "borrowsStable", "type": "uint256" }, { "internalType": "uint256", "name": "borrowsVariable", "type": "uint256" }, { "internalType": "uint256", "name": "stableBorrowRate", "type": "uint256" }, { "internalType": "bool", "name": "enabledAsCollateral", "type": "bool" }], "internalType": "struct AaveV3View.UserToken[]", "name": "userTokens", "type": "tuple[]" }], "stateMutability": "view", "type": "function" }, { "inputs": [{ "internalType": "address", "name": "_market", "type": "address" }, { "internalType": "address", "name": "_tokenAddr", "type": "address" }], "name": "getTokenInfoFull", "outputs": [{ "components": [{ "internalType": "address", "name": "aTokenAddress", "type": "address" }, { "internalType": "address", "name": "underlyingTokenAddress", "type": "address" }, { "internalType": "uint16", "name": "assetId", "type": "uint16" }, { "internalType": "uint256", "name": "supplyRate", "type": "uint256" }, { "internalType": "uint256", "name": "borrowRateVariable", "type": "uint256" }, { "internalType": "uint256", "name": "borrowRateStable", "type": "uint256" }, { "internalType": "uint256", "name": "totalSupply", "type": "uint256" }, { "internalType": "uint256", "name": "availableLiquidity", "type": "uint256" }, { "internalType": "uint256", "name": "totalBorrow", "type": "uint256" }, { "internalType": "uint256", "name": "totalBorrowVar", "type": "uint256" }, { "internalType": "uint256", "name": "totalBorrowStab", "type": "uint256" }, { "internalType": "uint256", "name": "collateralFactor", "type": "uint256" }, { "internalType": "uint256", "name": "liquidationRatio", "type": "uint256" }, { "internalType": "uint256", "name": "price", "type": "uint256" }, { "internalType": "uint256", "name": "supplyCap", "type": "uint256" }, { "internalType": "uint256", "name": "borrowCap", "type": "uint256" }, { "internalType": "uint256", "name": "emodeCategory", "type": "uint256" }, { "internalType": "uint256", "name": "debtCeilingForIsolationMode", "type": "uint256" }, { "internalType": "uint256", "name": "isolationModeTotalDebt", "type": "uint256" }, { "internalType": "bool", "name": "usageAsCollateralEnabled", "type": "bool" }, { "internalType": "bool", "name": "borrowingEnabled", "type": "bool" }, { "internalType": "bool", "name": "stableBorrowRateEnabled", "type": "bool" }, { "internalType": "bool", "name": "isolationModeBorrowingEnabled", "type": "bool" }, { "internalType": "bool", "name": "isSiloedForBorrowing", "type": "bool" }, { "internalType": "uint256", "name": "eModeCollateralFactor", "type": "uint256" }, { "internalType": "bool", "name": "isFlashLoanEnabled", "type": "bool" }, { "internalType": "uint16", "name": "ltv", "type": "uint16" }, { "internalType": "uint16", "name": "liquidationThreshold", "type": "uint16" }, { "internalType": "uint16", "name": "liquidationBonus", "type": "uint16" }, { "internalType": "address", "name": "priceSource", "type": "address" }, { "internalType": "string", "name": "label", "type": "string" }, { "internalType": "bool", "name": "isActive", "type": "bool" }, { "internalType": "bool", "name": "isPaused", "type": "bool" }, { "internalType": "bool", "name": "isFrozen", "type": "bool" }, { "internalType": "address", "name": "debtTokenAddress", "type": "address" }], "internalType": "struct AaveV3View.TokenInfoFull", "name": "_tokenInfo", "type": "tuple" }], "stateMutability": "view", "type": "function" }, { "inputs": [{ "internalType": "address", "name": "_market", "type": "address" }, { "internalType": "address[]", "name": "_tokenAddresses", "type": "address[]" }], "name": "getTokensInfo", "outputs": [{ "components": [{ "internalType": "address", "name": "aTokenAddress", "type": "address" }, { "internalType": "address", "name": "underlyingTokenAddress", "type": "address" }, { "internalType": "uint256", "name": "collateralFactor", "type": "uint256" }, { "internalType": "uint256", "name": "price", "type": "uint256" }], "internalType": "struct AaveV3View.TokenInfo[]", "name": "tokens", "type": "tuple[]" }], "stateMutability": "view", "type": "function" }, { "inputs": [{ "internalType": "address", "name": "", "type": "address" }], "name": "isBorrowAllowed", "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], "stateMutability": "pure", "type": "function" }],
8
9
  "networks": {
@@ -1353,3 +1354,11 @@ exports.AaveV4View = {
1353
1354
  }
1354
1355
  }
1355
1356
  };
1357
+ exports.UniswapTokenDistributor = {
1358
+ "abi": [{ "inputs": [{ "internalType": "uint256", "name": "index", "type": "uint256" }], "name": "isClaimed", "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], "stateMutability": "view", "type": "function" }],
1359
+ "networks": {
1360
+ "1": {
1361
+ "address": "0x090D4613473dEE047c3f2706764f49E0821D256e",
1362
+ }
1363
+ }
1364
+ };
@@ -618242,3 +618242,38 @@ export declare const AaveV4ViewContractViem: (client: Client, network: NetworkNu
618242
618242
  readonly type: "function";
618243
618243
  }];
618244
618244
  };
618245
+ export declare const UniswapTokenDistributorViem: (client: Client, network: NetworkNumber, block?: Blockish) => {
618246
+ read: {
618247
+ isClaimed: (args: readonly [bigint], options?: import("viem").Prettify<import("viem").UnionOmit<import("viem").ReadContractParameters<readonly [{
618248
+ readonly inputs: readonly [{
618249
+ readonly internalType: "uint256";
618250
+ readonly name: "index";
618251
+ readonly type: "uint256";
618252
+ }];
618253
+ readonly name: "isClaimed";
618254
+ readonly outputs: readonly [{
618255
+ readonly internalType: "bool";
618256
+ readonly name: "";
618257
+ readonly type: "bool";
618258
+ }];
618259
+ readonly stateMutability: "view";
618260
+ readonly type: "function";
618261
+ }], "isClaimed", readonly [bigint]>, "address" | "args" | "abi" | "functionName">> | undefined) => Promise<boolean>;
618262
+ };
618263
+ address: `0x${string}`;
618264
+ abi: readonly [{
618265
+ readonly inputs: readonly [{
618266
+ readonly internalType: "uint256";
618267
+ readonly name: "index";
618268
+ readonly type: "uint256";
618269
+ }];
618270
+ readonly name: "isClaimed";
618271
+ readonly outputs: readonly [{
618272
+ readonly internalType: "bool";
618273
+ readonly name: "";
618274
+ readonly type: "bool";
618275
+ }];
618276
+ readonly stateMutability: "view";
618277
+ readonly type: "function";
618278
+ }];
618279
+ };
package/cjs/contracts.js CHANGED
@@ -34,7 +34,7 @@ var __importStar = (this && this.__importStar) || (function () {
34
34
  })();
35
35
  Object.defineProperty(exports, "__esModule", { value: true });
36
36
  exports.SparkRewardsControllerViem = exports.UUPSViem = exports.LiquityStabilityPoolViem = exports.LiquityLQTYStakingViem = exports.AaveUmbrellaViewViem = exports.AaveIncentivesControllerViem = exports.FluidViewContractViem = exports.LiquityV2LegacyViewContractViem = exports.LiquityV2ViewContractViem = exports.LiquityActivePoolContractViem = exports.LiquityPriceFeedContractViem = exports.LiquityTroveManagerContractViem = exports.LiquityCollSurplusPoolContractViem = exports.LiquityViewContractViem = exports.BTCPriceFeedContractViem = exports.WeETHPriceFeedContractViem = exports.ComptrollerContractViem = exports.CompoundLoanInfoContractViem = exports.McdJugContractViem = exports.McdDogContractViem = exports.McdSpotterContractViem = exports.McdVatContractViem = exports.McdViewContractViem = exports.McdGetCdpsContractViem = exports.LlamaLendViewContractViem = exports.CrvUSDFactoryContractViem = exports.CrvUSDViewContractViem = exports.EulerV2ViewContractViem = exports.SparkIncentiveDataProviderContractViem = exports.SparkViewContractViem = exports.CompV3ViewContractViem = exports.WstETHPriceFeedContractViem = exports.USDCPriceFeedContractViem = exports.ETHPriceFeedContractViem = exports.COMPPriceFeedContractViem = exports.DFSFeedRegistryContractViem = exports.FeedRegistryContractViem = exports.AaveIncentiveDataProviderV3ContractViem = exports.AaveV3ViewContractViem = exports.AaveLoanInfoV2ContractViem = exports.MorphoBlueViewContractViem = exports.getYearnV3VaultContractViem = exports.getErc4626ContractViem = exports.getErc20ContractViem = exports.getSparkSavingsVaultContractViem = exports.getYearnVaultContractViem = exports.getMorphoVaultContractViem = exports.createViemContractFromConfigFunc = exports.getConfigContractAbi = exports.getConfigContractAddress = void 0;
37
- exports.AaveV4ViewContractViem = exports.SkySavingsContractView = exports.MakerDsrContractViem = exports.YearnViewContractViem = exports.StkAAVEViem = exports.LiquityV2sBoldVaultViem = exports.AaveRewardsControllerViem = void 0;
37
+ exports.UniswapTokenDistributorViem = exports.AaveV4ViewContractViem = exports.SkySavingsContractView = exports.MakerDsrContractViem = exports.YearnViewContractViem = exports.StkAAVEViem = exports.LiquityV2sBoldVaultViem = exports.AaveRewardsControllerViem = void 0;
38
38
  const viem_1 = require("viem");
39
39
  const configRaw = __importStar(require("./config/contracts"));
40
40
  // @ts-ignore
@@ -187,3 +187,4 @@ exports.YearnViewContractViem = (0, exports.createViemContractFromConfigFunc)('Y
187
187
  exports.MakerDsrContractViem = (0, exports.createViemContractFromConfigFunc)('MakerDsr');
188
188
  exports.SkySavingsContractView = (0, exports.createViemContractFromConfigFunc)('SkySavings');
189
189
  exports.AaveV4ViewContractViem = (0, exports.createViemContractFromConfigFunc)('AaveV4View');
190
+ exports.UniswapTokenDistributorViem = (0, exports.createViemContractFromConfigFunc)('UniswapTokenDistributor');
@@ -54,6 +54,7 @@ const spark_2 = require("../claiming/spark");
54
54
  const king_1 = require("../claiming/king");
55
55
  const ethena_1 = require("../claiming/ethena");
56
56
  const aaveV4_1 = require("../aaveV4");
57
+ const uniswap_1 = require("../claiming/uniswap");
57
58
  function getPortfolioData(provider_1, network_1, defaultProvider_1, addresses_1) {
58
59
  return __awaiter(this, arguments, void 0, function* (provider, network, defaultProvider, addresses, isSim = false) {
59
60
  const isMainnet = network === common_1.NetworkNumber.Eth;
@@ -309,6 +310,34 @@ function getPortfolioData(provider_1, network_1, defaultProvider_1, addresses_1)
309
310
  }
310
311
  }
311
312
  }))(),
313
+ // Batch UNI rewards
314
+ (() => __awaiter(this, void 0, void 0, function* () {
315
+ try {
316
+ if (!isMainnet) {
317
+ for (const address of addresses) {
318
+ rewardsData[address.toLowerCase()].uniswap = { error: '', data: [] };
319
+ }
320
+ return;
321
+ }
322
+ const uniswapRewards = yield (0, uniswap_1.getUniswapRewards)(client, network, addresses);
323
+ for (const address of addresses) {
324
+ const lowerAddress = address.toLowerCase();
325
+ rewardsData[lowerAddress].uniswap = {
326
+ error: '',
327
+ data: uniswapRewards[lowerAddress] || [],
328
+ };
329
+ }
330
+ }
331
+ catch (error) {
332
+ console.error('Error fetching Uniswap rewards data in batch:', error);
333
+ for (const address of addresses) {
334
+ rewardsData[address.toLowerCase()].uniswap = {
335
+ error: 'Error fetching Uniswap rewards data in batch',
336
+ data: null,
337
+ };
338
+ }
339
+ }
340
+ }))(),
312
341
  ...sparkMarkets.map((market) => addresses.map((address) => __awaiter(this, void 0, void 0, function* () {
313
342
  try {
314
343
  if (!isMainnet) {
@@ -14,6 +14,8 @@ export declare enum ClaimType {
14
14
  SPARK_AIRDROP = "SPARK_AIRDROP",
15
15
  /** Spark Airdrop */
16
16
  SPARK_WST_ETH_REWARDS = "SPARK_WST_ETH_REWARDS",// TODO: This will be removed once we fully refactor spark rewards
17
+ /** UNI Airdrop */
18
+ UNI_REWARDS = "UNI_REWARDS",
17
19
  ETHENA_AIRDROP = "ETHENA_AIRDROP"
18
20
  }
19
21
  type _ClaimableTokenPartial = {
@@ -17,6 +17,8 @@ var ClaimType;
17
17
  ClaimType["SPARK_AIRDROP"] = "SPARK_AIRDROP";
18
18
  /** Spark Airdrop */
19
19
  ClaimType["SPARK_WST_ETH_REWARDS"] = "SPARK_WST_ETH_REWARDS";
20
+ /** UNI Airdrop */
21
+ ClaimType["UNI_REWARDS"] = "UNI_REWARDS";
20
22
  ClaimType["ETHENA_AIRDROP"] = "ETHENA_AIRDROP";
21
23
  })(ClaimType || (exports.ClaimType = ClaimType = {}));
22
24
  var SparkAirdropType;
@@ -2,4 +2,5 @@ import * as aaveV3Claim from './aaveV3';
2
2
  import * as compV3Claim from './compV3';
3
3
  import * as kingV3Claim from './king';
4
4
  import * as sparkClaim from './spark';
5
- export { aaveV3Claim, compV3Claim, kingV3Claim, sparkClaim, };
5
+ import * as uniswapClaim from './uniswap';
6
+ export { aaveV3Claim, compV3Claim, kingV3Claim, sparkClaim, uniswapClaim, };
@@ -2,4 +2,5 @@ import * as aaveV3Claim from './aaveV3';
2
2
  import * as compV3Claim from './compV3';
3
3
  import * as kingV3Claim from './king';
4
4
  import * as sparkClaim from './spark';
5
- export { aaveV3Claim, compV3Claim, kingV3Claim, sparkClaim, };
5
+ import * as uniswapClaim from './uniswap';
6
+ export { aaveV3Claim, compV3Claim, kingV3Claim, sparkClaim, uniswapClaim, };
@@ -0,0 +1,4 @@
1
+ import { Client } from 'viem';
2
+ import { EthAddress, NetworkNumber } from '../types';
3
+ export declare const fetchUniswapRewardsData: (walletAddress: EthAddress) => Promise<any>;
4
+ export declare const getUniswapRewards: (provider: Client, network: NetworkNumber, walletAddresses: EthAddress[]) => Promise<Record<string, any[]>>;
@@ -0,0 +1,62 @@
1
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
+ return new (P || (P = Promise))(function (resolve, reject) {
4
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
8
+ });
9
+ };
10
+ import Dec from 'decimal.js';
11
+ import { assetAmountInEth } from '@defisaver/tokens';
12
+ import { UniswapTokenDistributorViem } from '../contracts';
13
+ import { ClaimType } from '../types/claiming';
14
+ const EMPTY_DATA = (walletAddress) => ({
15
+ address: walletAddress, index: 0, amount: '0x0', proof: [],
16
+ });
17
+ export const fetchUniswapRewardsData = (walletAddress) => __awaiter(void 0, void 0, void 0, function* () {
18
+ try {
19
+ const res = yield fetch(`https://uniswap-merkl-drop.defisaver.com/claims/${walletAddress}`, { signal: AbortSignal.timeout(5000) });
20
+ if (!res.ok)
21
+ throw new Error(yield res.text());
22
+ const data = yield res.json();
23
+ if (data.error)
24
+ return EMPTY_DATA(walletAddress);
25
+ return data;
26
+ }
27
+ catch (err) {
28
+ console.error('External API Error: Error fetching Uniswap rewards:', err);
29
+ return EMPTY_DATA(walletAddress);
30
+ }
31
+ });
32
+ export const getUniswapRewards = (provider, network, walletAddresses) => __awaiter(void 0, void 0, void 0, function* () {
33
+ // Fetch all API data in parallel (these are external API calls, can't be batched with multicall)
34
+ const apiDataPromises = walletAddresses.map(address => fetchUniswapRewardsData(address));
35
+ const apiDataArray = yield Promise.all(apiDataPromises);
36
+ // Batch all contract calls using multicall
37
+ const contract = UniswapTokenDistributorViem(provider, network);
38
+ const cumulativePromises = apiDataArray.map(data => (data.index ? contract.read.isClaimed([data.index]) : Promise.resolve(false)));
39
+ const cumulativeResults = yield Promise.all(cumulativePromises);
40
+ // Process results
41
+ const results = {};
42
+ for (let i = 0; i < walletAddresses.length; i++) {
43
+ const walletAddress = walletAddresses[i];
44
+ const data = apiDataArray[i];
45
+ const cumulative = cumulativeResults[i];
46
+ const amountToClaim = new Dec(data.amount);
47
+ if (amountToClaim.lessThanOrEqualTo('0')) {
48
+ results[walletAddress.toLowerCase()] = [];
49
+ }
50
+ else {
51
+ results[walletAddress.toLowerCase()] = [{
52
+ amount: assetAmountInEth(amountToClaim.toString(), 'UNI'),
53
+ walletAddress,
54
+ claimType: ClaimType.UNI_REWARDS,
55
+ index: data.index,
56
+ proof: data.proof,
57
+ isClaimed: cumulative,
58
+ }];
59
+ }
60
+ }
61
+ return results;
62
+ });
@@ -99091,3 +99091,25 @@ export declare const AaveV4View: {
99091
99091
  };
99092
99092
  };
99093
99093
  };
99094
+ export declare const UniswapTokenDistributor: {
99095
+ readonly abi: readonly [{
99096
+ readonly inputs: readonly [{
99097
+ readonly internalType: "uint256";
99098
+ readonly name: "index";
99099
+ readonly type: "uint256";
99100
+ }];
99101
+ readonly name: "isClaimed";
99102
+ readonly outputs: readonly [{
99103
+ readonly internalType: "bool";
99104
+ readonly name: "";
99105
+ readonly type: "bool";
99106
+ }];
99107
+ readonly stateMutability: "view";
99108
+ readonly type: "function";
99109
+ }];
99110
+ readonly networks: {
99111
+ readonly "1": {
99112
+ readonly address: "0x090D4613473dEE047c3f2706764f49E0821D256e";
99113
+ };
99114
+ };
99115
+ };
@@ -1349,3 +1349,11 @@ export const AaveV4View = {
1349
1349
  }
1350
1350
  }
1351
1351
  };
1352
+ export const UniswapTokenDistributor = {
1353
+ "abi": [{ "inputs": [{ "internalType": "uint256", "name": "index", "type": "uint256" }], "name": "isClaimed", "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], "stateMutability": "view", "type": "function" }],
1354
+ "networks": {
1355
+ "1": {
1356
+ "address": "0x090D4613473dEE047c3f2706764f49E0821D256e",
1357
+ }
1358
+ }
1359
+ };
@@ -618242,3 +618242,38 @@ export declare const AaveV4ViewContractViem: (client: Client, network: NetworkNu
618242
618242
  readonly type: "function";
618243
618243
  }];
618244
618244
  };
618245
+ export declare const UniswapTokenDistributorViem: (client: Client, network: NetworkNumber, block?: Blockish) => {
618246
+ read: {
618247
+ isClaimed: (args: readonly [bigint], options?: import("viem").Prettify<import("viem").UnionOmit<import("viem").ReadContractParameters<readonly [{
618248
+ readonly inputs: readonly [{
618249
+ readonly internalType: "uint256";
618250
+ readonly name: "index";
618251
+ readonly type: "uint256";
618252
+ }];
618253
+ readonly name: "isClaimed";
618254
+ readonly outputs: readonly [{
618255
+ readonly internalType: "bool";
618256
+ readonly name: "";
618257
+ readonly type: "bool";
618258
+ }];
618259
+ readonly stateMutability: "view";
618260
+ readonly type: "function";
618261
+ }], "isClaimed", readonly [bigint]>, "address" | "args" | "abi" | "functionName">> | undefined) => Promise<boolean>;
618262
+ };
618263
+ address: `0x${string}`;
618264
+ abi: readonly [{
618265
+ readonly inputs: readonly [{
618266
+ readonly internalType: "uint256";
618267
+ readonly name: "index";
618268
+ readonly type: "uint256";
618269
+ }];
618270
+ readonly name: "isClaimed";
618271
+ readonly outputs: readonly [{
618272
+ readonly internalType: "bool";
618273
+ readonly name: "";
618274
+ readonly type: "bool";
618275
+ }];
618276
+ readonly stateMutability: "view";
618277
+ readonly type: "function";
618278
+ }];
618279
+ };
package/esm/contracts.js CHANGED
@@ -141,3 +141,4 @@ export const YearnViewContractViem = createViemContractFromConfigFunc('YearnView
141
141
  export const MakerDsrContractViem = createViemContractFromConfigFunc('MakerDsr');
142
142
  export const SkySavingsContractView = createViemContractFromConfigFunc('SkySavings');
143
143
  export const AaveV4ViewContractViem = createViemContractFromConfigFunc('AaveV4View');
144
+ export const UniswapTokenDistributorViem = createViemContractFromConfigFunc('UniswapTokenDistributor');
@@ -34,6 +34,7 @@ import { fetchSparkAirdropRewards, fetchSparkRewards } from '../claiming/spark';
34
34
  import { getKingRewards } from '../claiming/king';
35
35
  import { fetchEthenaAirdropRewards } from '../claiming/ethena';
36
36
  import { _getAaveV4AccountData, _getAaveV4SpokeData } from '../aaveV4';
37
+ import { getUniswapRewards } from '../claiming/uniswap';
37
38
  export function getPortfolioData(provider_1, network_1, defaultProvider_1, addresses_1) {
38
39
  return __awaiter(this, arguments, void 0, function* (provider, network, defaultProvider, addresses, isSim = false) {
39
40
  const isMainnet = network === NetworkNumber.Eth;
@@ -289,6 +290,34 @@ export function getPortfolioData(provider_1, network_1, defaultProvider_1, addre
289
290
  }
290
291
  }
291
292
  }))(),
293
+ // Batch UNI rewards
294
+ (() => __awaiter(this, void 0, void 0, function* () {
295
+ try {
296
+ if (!isMainnet) {
297
+ for (const address of addresses) {
298
+ rewardsData[address.toLowerCase()].uniswap = { error: '', data: [] };
299
+ }
300
+ return;
301
+ }
302
+ const uniswapRewards = yield getUniswapRewards(client, network, addresses);
303
+ for (const address of addresses) {
304
+ const lowerAddress = address.toLowerCase();
305
+ rewardsData[lowerAddress].uniswap = {
306
+ error: '',
307
+ data: uniswapRewards[lowerAddress] || [],
308
+ };
309
+ }
310
+ }
311
+ catch (error) {
312
+ console.error('Error fetching Uniswap rewards data in batch:', error);
313
+ for (const address of addresses) {
314
+ rewardsData[address.toLowerCase()].uniswap = {
315
+ error: 'Error fetching Uniswap rewards data in batch',
316
+ data: null,
317
+ };
318
+ }
319
+ }
320
+ }))(),
292
321
  ...sparkMarkets.map((market) => addresses.map((address) => __awaiter(this, void 0, void 0, function* () {
293
322
  try {
294
323
  if (!isMainnet) {
@@ -14,6 +14,8 @@ export declare enum ClaimType {
14
14
  SPARK_AIRDROP = "SPARK_AIRDROP",
15
15
  /** Spark Airdrop */
16
16
  SPARK_WST_ETH_REWARDS = "SPARK_WST_ETH_REWARDS",// TODO: This will be removed once we fully refactor spark rewards
17
+ /** UNI Airdrop */
18
+ UNI_REWARDS = "UNI_REWARDS",
17
19
  ETHENA_AIRDROP = "ETHENA_AIRDROP"
18
20
  }
19
21
  type _ClaimableTokenPartial = {
@@ -14,6 +14,8 @@ export var ClaimType;
14
14
  ClaimType["SPARK_AIRDROP"] = "SPARK_AIRDROP";
15
15
  /** Spark Airdrop */
16
16
  ClaimType["SPARK_WST_ETH_REWARDS"] = "SPARK_WST_ETH_REWARDS";
17
+ /** UNI Airdrop */
18
+ ClaimType["UNI_REWARDS"] = "UNI_REWARDS";
17
19
  ClaimType["ETHENA_AIRDROP"] = "ETHENA_AIRDROP";
18
20
  })(ClaimType || (ClaimType = {}));
19
21
  export var SparkAirdropType;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@defisaver/positions-sdk",
3
- "version": "2.1.127-dev",
3
+ "version": "2.1.127-uniswap-dev",
4
4
  "description": "",
5
5
  "main": "./cjs/index.js",
6
6
  "module": "./esm/index.js",
@@ -2,10 +2,12 @@ import * as aaveV3Claim from './aaveV3';
2
2
  import * as compV3Claim from './compV3';
3
3
  import * as kingV3Claim from './king';
4
4
  import * as sparkClaim from './spark';
5
+ import * as uniswapClaim from './uniswap';
5
6
 
6
7
  export {
7
8
  aaveV3Claim,
8
9
  compV3Claim,
9
10
  kingV3Claim,
10
11
  sparkClaim,
12
+ uniswapClaim,
11
13
  };
@@ -0,0 +1,65 @@
1
+ import Dec from 'decimal.js';
2
+ import { Client } from 'viem';
3
+ import { assetAmountInEth } from '@defisaver/tokens';
4
+ import { EthAddress, NetworkNumber } from '../types';
5
+ import { UniswapTokenDistributorViem } from '../contracts';
6
+ import { ClaimType } from '../types/claiming';
7
+
8
+ const EMPTY_DATA = (walletAddress: EthAddress) => ({
9
+ address: walletAddress, index: 0, amount: '0x0', proof: [],
10
+ });
11
+
12
+ export const fetchUniswapRewardsData = async (walletAddress: EthAddress) => {
13
+ try {
14
+ const res = await fetch(`https://uniswap-merkl-drop.defisaver.com/claims/${walletAddress}`,
15
+ { signal: AbortSignal.timeout(5000) });
16
+
17
+ if (!res.ok) throw new Error(await res.text());
18
+
19
+ const data = await res.json();
20
+ if (data.error) return EMPTY_DATA(walletAddress);
21
+
22
+ return data;
23
+ } catch (err) {
24
+ console.error('External API Error: Error fetching Uniswap rewards:', err);
25
+ return EMPTY_DATA(walletAddress);
26
+ }
27
+ };
28
+
29
+ export const getUniswapRewards = async (provider: Client, network: NetworkNumber, walletAddresses: EthAddress[]) => {
30
+ // Fetch all API data in parallel (these are external API calls, can't be batched with multicall)
31
+ const apiDataPromises = walletAddresses.map(address => fetchUniswapRewardsData(address));
32
+ const apiDataArray = await Promise.all(apiDataPromises);
33
+
34
+ // Batch all contract calls using multicall
35
+ const contract = UniswapTokenDistributorViem(provider, network);
36
+ const cumulativePromises = apiDataArray.map(data => (data.index ? contract.read.isClaimed([data.index]) : Promise.resolve(false)),
37
+ );
38
+ const cumulativeResults = await Promise.all(cumulativePromises);
39
+
40
+ // Process results
41
+ const results: Record<string, any[]> = {};
42
+
43
+ for (let i = 0; i < walletAddresses.length; i++) {
44
+ const walletAddress = walletAddresses[i];
45
+ const data = apiDataArray[i];
46
+ const cumulative = cumulativeResults[i];
47
+
48
+ const amountToClaim = new Dec(data.amount);
49
+
50
+ if (amountToClaim.lessThanOrEqualTo('0')) {
51
+ results[walletAddress.toLowerCase() as EthAddress] = [];
52
+ } else {
53
+ results[walletAddress.toLowerCase() as EthAddress] = [{
54
+ amount: assetAmountInEth(amountToClaim.toString(), 'UNI'),
55
+ walletAddress,
56
+ claimType: ClaimType.UNI_REWARDS,
57
+ index: data.index,
58
+ proof: data.proof,
59
+ isClaimed: cumulative,
60
+ }];
61
+ }
62
+ }
63
+
64
+ return results;
65
+ };
@@ -1351,3 +1351,12 @@ export const AaveV4View = {
1351
1351
  }
1352
1352
  }
1353
1353
  } as const;
1354
+
1355
+ export const UniswapTokenDistributor = {
1356
+ "abi": [{"inputs":[{"internalType":"uint256","name":"index","type":"uint256"}],"name":"isClaimed","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"}],
1357
+ "networks": {
1358
+ "1": {
1359
+ "address": "0x090D4613473dEE047c3f2706764f49E0821D256e",
1360
+ }
1361
+ }
1362
+ } as const;
package/src/contracts.ts CHANGED
@@ -181,3 +181,5 @@ export const MakerDsrContractViem = createViemContractFromConfigFunc('MakerDsr')
181
181
  export const SkySavingsContractView = createViemContractFromConfigFunc('SkySavings');
182
182
 
183
183
  export const AaveV4ViewContractViem = createViemContractFromConfigFunc('AaveV4View');
184
+
185
+ export const UniswapTokenDistributorViem = createViemContractFromConfigFunc('UniswapTokenDistributor');
@@ -51,6 +51,7 @@ import { fetchSparkAirdropRewards, fetchSparkRewards } from '../claiming/spark';
51
51
  import { getKingRewards } from '../claiming/king';
52
52
  import { fetchEthenaAirdropRewards } from '../claiming/ethena';
53
53
  import { _getAaveV4AccountData, _getAaveV4SpokeData } from '../aaveV4';
54
+ import { getUniswapRewards } from '../claiming/uniswap';
54
55
 
55
56
  export async function getPortfolioData(provider: EthereumProvider, network: NetworkNumber, defaultProvider: EthereumProvider, addresses: EthAddress[], isSim = false): Promise<{
56
57
  positions: PortfolioPositionsData;
@@ -310,6 +311,33 @@ export async function getPortfolioData(provider: EthereumProvider, network: Netw
310
311
  }
311
312
  }
312
313
  })(),
314
+ // Batch UNI rewards
315
+ (async () => {
316
+ try {
317
+ if (!isMainnet) {
318
+ for (const address of addresses) {
319
+ rewardsData[address.toLowerCase()].uniswap = { error: '', data: [] };
320
+ }
321
+ return;
322
+ }
323
+ const uniswapRewards = await getUniswapRewards(client, network, addresses);
324
+ for (const address of addresses) {
325
+ const lowerAddress = address.toLowerCase() as EthAddress;
326
+ rewardsData[lowerAddress].uniswap = {
327
+ error: '',
328
+ data: uniswapRewards[lowerAddress] || [],
329
+ };
330
+ }
331
+ } catch (error) {
332
+ console.error('Error fetching Uniswap rewards data in batch:', error);
333
+ for (const address of addresses) {
334
+ rewardsData[address.toLowerCase() as EthAddress].uniswap = {
335
+ error: 'Error fetching Uniswap rewards data in batch',
336
+ data: null,
337
+ };
338
+ }
339
+ }
340
+ })(),
313
341
  ...sparkMarkets.map((market) => addresses.map(async address => {
314
342
  try {
315
343
  if (!isMainnet) {
@@ -15,6 +15,8 @@ export enum ClaimType {
15
15
  SPARK_AIRDROP = 'SPARK_AIRDROP',
16
16
  /** Spark Airdrop */
17
17
  SPARK_WST_ETH_REWARDS = 'SPARK_WST_ETH_REWARDS', // TODO: This will be removed once we fully refactor spark rewards
18
+ /** UNI Airdrop */
19
+ UNI_REWARDS = 'UNI_REWARDS',
18
20
 
19
21
  ETHENA_AIRDROP = 'ETHENA_AIRDROP',
20
22
  }