@gearbox-protocol/sdk 16.0.0-next.16 → 16.0.0-next.17

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.
@@ -4,5 +4,5 @@ const require_rewards_rewards_api = require("./rewards/api.js");
4
4
  const require_rewards_rewards_extra_apy = require("./rewards/extra-apy.js");
5
5
  require("./rewards/index.js");
6
6
  exports.PoolPointsAPI = require_rewards_rewards_extra_apy.PoolPointsAPI;
7
- exports.RewardAmountAPI = require_rewards_rewards_api.RewardAmountAPI;
8
7
  exports.getKeyForPoolPointsInfo = require_rewards_rewards_extra_apy.getKeyForPoolPointsInfo;
8
+ exports.getMerklRewards = require_rewards_rewards_api.getMerklRewards;
@@ -1,70 +1,80 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ const require_onchain_utils_AddressMap = require("../../onchain/utils/AddressMap.js");
2
3
  const require_onchain_utils_bigint_math = require("../../onchain/utils/bigint-math.js");
3
- const require_onchain_chain_chains = require("../../onchain/chain/chains.js");
4
4
  const require_onchain_utils_formatter = require("../../onchain/utils/formatter.js");
5
5
  require("../../onchain/index.js");
6
6
  require("../../common-utils/index.js");
7
7
  const require_rewards_rewards_merkl_api = require("./merkl-api.js");
8
8
  let viem = require("viem");
9
9
  //#region src/rewards/rewards/api.ts
10
- var RewardAmountAPI = class RewardAmountAPI {
11
- constructor() {}
12
- static async getLmRewardsMerkle({ pools, account, network, reportError, apiKey }) {
13
- const [merkleXYZLMResponse] = await Promise.allSettled([require_rewards_rewards_merkl_api.MerkleXYZApi.fetchWithFallback(require_rewards_rewards_merkl_api.MerkleXYZApi.getUserRewardsUrl({ params: {
14
- chainId: require_onchain_chain_chains.chains[network].id,
15
- user: (0, viem.getAddress)(account)
16
- } }), apiKey)]);
17
- const merkleXYZLm = RewardAmountAPI.extractFulfilled(merkleXYZLMResponse, reportError, "merkleXYZLm")?.data;
18
- const poolByItsToken = Object.values(pools).reduce((acc, p) => {
19
- p.stakedDieselToken.forEach((t) => {
20
- if (t) acc[t] = p.address;
21
- });
22
- p.stakedDieselToken_old.forEach((t) => {
23
- if (t) acc[t] = p.address;
24
- });
25
- acc[p.dieselToken] = p.address;
26
- return acc;
27
- }, {});
28
- const extraRewards = (merkleXYZLm || []).reduce((acc, chainRewards) => {
29
- chainRewards.rewards.forEach((reward) => {
30
- const rewardToken = reward.token.address.toLowerCase();
31
- reward.breakdowns.forEach((reason) => {
32
- const poolToken = ((reason.reason || "").split("_").find((part) => part.startsWith("0x")) || "").toLowerCase();
33
- const pool = poolByItsToken[poolToken];
34
- const total = require_onchain_utils_formatter.toBigInt(reason.amount || 0);
35
- const claimed = require_onchain_utils_formatter.toBigInt(reason.claimed || 0);
36
- const claimable = require_onchain_utils_bigint_math.BigIntMath.max(total - claimed, 0n);
37
- const key = [
38
- pool,
39
- poolToken,
40
- rewardToken
41
- ].join("_");
42
- if (pool && claimable > 0n) {
43
- const prevAmount = acc[key]?.amount || 0n;
44
- acc[key] = {
45
- pool,
46
- poolToken,
47
- rewardToken,
48
- rewardTokenSymbol: reward.token.symbol,
49
- rewardTokenDecimals: reward.token.decimals || 18,
50
- amount: prevAmount + claimable,
51
- type: "extraMerkle"
52
- };
53
- }
10
+ /**
11
+ * The wallet's claimable Merkl rewards on one chain.
12
+ *
13
+ * Never rejects on a transport failure: the fetch is settled rather than
14
+ * awaited, and a failure goes to `reportError` and yields an empty list. A
15
+ * caller that must tell "this chain is down" from "this chain has no rewards"
16
+ * has to watch that callback.
17
+ */
18
+ async function getMerklRewards({ sdk, account, reportError, apiKey }) {
19
+ const [merkleXYZLMResponse] = await Promise.allSettled([require_rewards_rewards_merkl_api.MerkleXYZApi.fetchWithFallback(require_rewards_rewards_merkl_api.MerkleXYZApi.getUserRewardsUrl({ params: {
20
+ chainId: sdk.chainId,
21
+ user: (0, viem.getAddress)(account)
22
+ } }), apiKey)]);
23
+ const merkleXYZLm = extractFulfilled(merkleXYZLMResponse, reportError, "merkleXYZLm")?.data;
24
+ const poolByItsToken = require_onchain_utils_AddressMap.AddressMap.fromMappedArray(sdk.marketRegister.pools.map(({ pool }) => pool.address), (address) => address);
25
+ const claimable = /* @__PURE__ */ new Map();
26
+ for (const chainRewards of merkleXYZLm || []) for (const reward of chainRewards.rewards) {
27
+ if (!(0, viem.isAddress)(reward.token.address, { strict: false })) continue;
28
+ const rewardTokenAddress = (0, viem.getAddress)(reward.token.address);
29
+ for (const reason of reward.breakdowns) {
30
+ const poolTokenAddress = (reason.reason || "").split("_").find((part) => part.startsWith("0x")) ?? "";
31
+ if (!(0, viem.isAddress)(poolTokenAddress, { strict: false })) continue;
32
+ const pool = poolByItsToken.get(poolTokenAddress);
33
+ if (!pool) continue;
34
+ const total = require_onchain_utils_formatter.toBigInt(reason.amount || 0);
35
+ const claimed = require_onchain_utils_formatter.toBigInt(reason.claimed || 0);
36
+ const amount = require_onchain_utils_bigint_math.BigIntMath.max(total - claimed, 0n);
37
+ if (amount === 0n) continue;
38
+ const key = `${pool}_${rewardTokenAddress}`;
39
+ const seen = claimable.get(key);
40
+ if (seen) {
41
+ claimable.set(key, {
42
+ ...seen,
43
+ amount: seen.amount + amount
54
44
  });
45
+ continue;
46
+ }
47
+ const poolToken = sdk.tokensMeta.getToken(pool);
48
+ if (!poolToken) continue;
49
+ claimable.set(key, {
50
+ chainId: sdk.chainId,
51
+ pool,
52
+ poolToken,
53
+ rewardToken: toRewardToken(sdk, rewardTokenAddress, reward.token),
54
+ amount
55
55
  });
56
- return acc;
57
- }, {});
58
- return Object.values(extraRewards);
59
- }
60
- static extractFulfilled(r, reportError, description) {
61
- if (r.status === "fulfilled") return r.value;
62
- else {
63
- if (reportError) reportError(r.reason, description);
64
- else console.error(r.reason);
65
- return;
66
56
  }
67
57
  }
68
- };
58
+ return [...claimable.values()];
59
+ }
60
+ /**
61
+ * A campaign's incentive token is not protocol collateral, so the registry
62
+ * usually has no entry for it — and Merkl always names it. The one place the
63
+ * two sources are reconciled.
64
+ */
65
+ function toRewardToken(sdk, address, merkl) {
66
+ return sdk.tokensMeta.getToken(address) ?? {
67
+ chainId: sdk.chainId,
68
+ address,
69
+ symbol: merkl.symbol,
70
+ name: merkl.symbol,
71
+ decimals: merkl.decimals || 18
72
+ };
73
+ }
74
+ function extractFulfilled(r, reportError, description) {
75
+ if (r.status === "fulfilled") return r.value;
76
+ if (reportError) reportError(r.reason, description);
77
+ else console.error(r.reason);
78
+ }
69
79
  //#endregion
70
- exports.RewardAmountAPI = RewardAmountAPI;
80
+ exports.getMerklRewards = getMerklRewards;
@@ -2,5 +2,5 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
2
  const require_rewards_rewards_api = require("./api.js");
3
3
  const require_rewards_rewards_extra_apy = require("./extra-apy.js");
4
4
  exports.PoolPointsAPI = require_rewards_rewards_extra_apy.PoolPointsAPI;
5
- exports.RewardAmountAPI = require_rewards_rewards_api.RewardAmountAPI;
6
5
  exports.getKeyForPoolPointsInfo = require_rewards_rewards_extra_apy.getKeyForPoolPointsInfo;
6
+ exports.getMerklRewards = require_rewards_rewards_api.getMerklRewards;
@@ -1,5 +1,5 @@
1
1
  import "./apy/index.js";
2
- import { RewardAmountAPI } from "./rewards/api.js";
2
+ import { getMerklRewards } from "./rewards/api.js";
3
3
  import { PoolPointsAPI, getKeyForPoolPointsInfo } from "./rewards/extra-apy.js";
4
4
  import "./rewards/index.js";
5
- export { PoolPointsAPI, RewardAmountAPI, getKeyForPoolPointsInfo };
5
+ export { PoolPointsAPI, getKeyForPoolPointsInfo, getMerklRewards };
@@ -1,69 +1,79 @@
1
+ import { AddressMap } from "../../onchain/utils/AddressMap.js";
1
2
  import { BigIntMath } from "../../onchain/utils/bigint-math.js";
2
- import { chains } from "../../onchain/chain/chains.js";
3
3
  import { toBigInt } from "../../onchain/utils/formatter.js";
4
4
  import "../../onchain/index.js";
5
5
  import "../../common-utils/index.js";
6
6
  import { MerkleXYZApi } from "./merkl-api.js";
7
- import { getAddress } from "viem";
7
+ import { getAddress, isAddress } from "viem";
8
8
  //#region src/rewards/rewards/api.ts
9
- var RewardAmountAPI = class RewardAmountAPI {
10
- constructor() {}
11
- static async getLmRewardsMerkle({ pools, account, network, reportError, apiKey }) {
12
- const [merkleXYZLMResponse] = await Promise.allSettled([MerkleXYZApi.fetchWithFallback(MerkleXYZApi.getUserRewardsUrl({ params: {
13
- chainId: chains[network].id,
14
- user: getAddress(account)
15
- } }), apiKey)]);
16
- const merkleXYZLm = RewardAmountAPI.extractFulfilled(merkleXYZLMResponse, reportError, "merkleXYZLm")?.data;
17
- const poolByItsToken = Object.values(pools).reduce((acc, p) => {
18
- p.stakedDieselToken.forEach((t) => {
19
- if (t) acc[t] = p.address;
20
- });
21
- p.stakedDieselToken_old.forEach((t) => {
22
- if (t) acc[t] = p.address;
23
- });
24
- acc[p.dieselToken] = p.address;
25
- return acc;
26
- }, {});
27
- const extraRewards = (merkleXYZLm || []).reduce((acc, chainRewards) => {
28
- chainRewards.rewards.forEach((reward) => {
29
- const rewardToken = reward.token.address.toLowerCase();
30
- reward.breakdowns.forEach((reason) => {
31
- const poolToken = ((reason.reason || "").split("_").find((part) => part.startsWith("0x")) || "").toLowerCase();
32
- const pool = poolByItsToken[poolToken];
33
- const total = toBigInt(reason.amount || 0);
34
- const claimed = toBigInt(reason.claimed || 0);
35
- const claimable = BigIntMath.max(total - claimed, 0n);
36
- const key = [
37
- pool,
38
- poolToken,
39
- rewardToken
40
- ].join("_");
41
- if (pool && claimable > 0n) {
42
- const prevAmount = acc[key]?.amount || 0n;
43
- acc[key] = {
44
- pool,
45
- poolToken,
46
- rewardToken,
47
- rewardTokenSymbol: reward.token.symbol,
48
- rewardTokenDecimals: reward.token.decimals || 18,
49
- amount: prevAmount + claimable,
50
- type: "extraMerkle"
51
- };
52
- }
9
+ /**
10
+ * The wallet's claimable Merkl rewards on one chain.
11
+ *
12
+ * Never rejects on a transport failure: the fetch is settled rather than
13
+ * awaited, and a failure goes to `reportError` and yields an empty list. A
14
+ * caller that must tell "this chain is down" from "this chain has no rewards"
15
+ * has to watch that callback.
16
+ */
17
+ async function getMerklRewards({ sdk, account, reportError, apiKey }) {
18
+ const [merkleXYZLMResponse] = await Promise.allSettled([MerkleXYZApi.fetchWithFallback(MerkleXYZApi.getUserRewardsUrl({ params: {
19
+ chainId: sdk.chainId,
20
+ user: getAddress(account)
21
+ } }), apiKey)]);
22
+ const merkleXYZLm = extractFulfilled(merkleXYZLMResponse, reportError, "merkleXYZLm")?.data;
23
+ const poolByItsToken = AddressMap.fromMappedArray(sdk.marketRegister.pools.map(({ pool }) => pool.address), (address) => address);
24
+ const claimable = /* @__PURE__ */ new Map();
25
+ for (const chainRewards of merkleXYZLm || []) for (const reward of chainRewards.rewards) {
26
+ if (!isAddress(reward.token.address, { strict: false })) continue;
27
+ const rewardTokenAddress = getAddress(reward.token.address);
28
+ for (const reason of reward.breakdowns) {
29
+ const poolTokenAddress = (reason.reason || "").split("_").find((part) => part.startsWith("0x")) ?? "";
30
+ if (!isAddress(poolTokenAddress, { strict: false })) continue;
31
+ const pool = poolByItsToken.get(poolTokenAddress);
32
+ if (!pool) continue;
33
+ const total = toBigInt(reason.amount || 0);
34
+ const claimed = toBigInt(reason.claimed || 0);
35
+ const amount = BigIntMath.max(total - claimed, 0n);
36
+ if (amount === 0n) continue;
37
+ const key = `${pool}_${rewardTokenAddress}`;
38
+ const seen = claimable.get(key);
39
+ if (seen) {
40
+ claimable.set(key, {
41
+ ...seen,
42
+ amount: seen.amount + amount
53
43
  });
44
+ continue;
45
+ }
46
+ const poolToken = sdk.tokensMeta.getToken(pool);
47
+ if (!poolToken) continue;
48
+ claimable.set(key, {
49
+ chainId: sdk.chainId,
50
+ pool,
51
+ poolToken,
52
+ rewardToken: toRewardToken(sdk, rewardTokenAddress, reward.token),
53
+ amount
54
54
  });
55
- return acc;
56
- }, {});
57
- return Object.values(extraRewards);
58
- }
59
- static extractFulfilled(r, reportError, description) {
60
- if (r.status === "fulfilled") return r.value;
61
- else {
62
- if (reportError) reportError(r.reason, description);
63
- else console.error(r.reason);
64
- return;
65
55
  }
66
56
  }
67
- };
57
+ return [...claimable.values()];
58
+ }
59
+ /**
60
+ * A campaign's incentive token is not protocol collateral, so the registry
61
+ * usually has no entry for it — and Merkl always names it. The one place the
62
+ * two sources are reconciled.
63
+ */
64
+ function toRewardToken(sdk, address, merkl) {
65
+ return sdk.tokensMeta.getToken(address) ?? {
66
+ chainId: sdk.chainId,
67
+ address,
68
+ symbol: merkl.symbol,
69
+ name: merkl.symbol,
70
+ decimals: merkl.decimals || 18
71
+ };
72
+ }
73
+ function extractFulfilled(r, reportError, description) {
74
+ if (r.status === "fulfilled") return r.value;
75
+ if (reportError) reportError(r.reason, description);
76
+ else console.error(r.reason);
77
+ }
68
78
  //#endregion
69
- export { RewardAmountAPI };
79
+ export { getMerklRewards };
@@ -1,3 +1,3 @@
1
- import { RewardAmountAPI } from "./api.js";
1
+ import { getMerklRewards } from "./api.js";
2
2
  import { PoolPointsAPI, getKeyForPoolPointsInfo } from "./extra-apy.js";
3
- export { PoolPointsAPI, RewardAmountAPI, getKeyForPoolPointsInfo };
3
+ export { PoolPointsAPI, getKeyForPoolPointsInfo, getMerklRewards };
@@ -1,7 +1,7 @@
1
1
  import { Apy, ApyDetails, DebtReward, ExternalApy, ExtraCollateralAPY, ExtraCollateralPointsInfo, FarmInfo, GearAPY, GearAPYDetails, PointsInfo, PointsReward, PoolExtraApy, PoolOutputDetails, PoolPointsInfo, TokenOutputDetails } from "./apy/output-details.js";
2
2
  import { DataResult, Output } from "./apy/output.js";
3
3
  import "./apy/index.js";
4
- import { GearboxExtraMerkleLmReward, GearboxLmReward, GetLmRewardsMerkleProps, PoolData, RewardAmountAPI } from "./rewards/api.js";
4
+ import { GetMerklRewardsProps, MerklReward, MerklRewardsSdk, getMerklRewards } from "./rewards/api.js";
5
5
  import { GetPointsByPoolProps, GetTotalTokensOnProtocolProps, PoolPointsAPI, PoolPointsBase, getKeyForPoolPointsInfo } from "./rewards/extra-apy.js";
6
6
  import "./rewards/index.js";
7
- export { Apy, ApyDetails, DataResult, DebtReward, ExternalApy, ExtraCollateralAPY, ExtraCollateralPointsInfo, FarmInfo, GearAPY, GearAPYDetails, GearboxExtraMerkleLmReward, GearboxLmReward, GetLmRewardsMerkleProps, GetPointsByPoolProps, GetTotalTokensOnProtocolProps, Output, PointsInfo, PointsReward, PoolData, PoolExtraApy, PoolOutputDetails, PoolPointsAPI, PoolPointsBase, PoolPointsInfo, RewardAmountAPI, TokenOutputDetails, getKeyForPoolPointsInfo };
7
+ export { Apy, ApyDetails, DataResult, DebtReward, ExternalApy, ExtraCollateralAPY, ExtraCollateralPointsInfo, FarmInfo, GearAPY, GearAPYDetails, GetMerklRewardsProps, GetPointsByPoolProps, GetTotalTokensOnProtocolProps, MerklReward, MerklRewardsSdk, Output, PointsInfo, PointsReward, PoolExtraApy, PoolOutputDetails, PoolPointsAPI, PoolPointsBase, PoolPointsInfo, TokenOutputDetails, getKeyForPoolPointsInfo, getMerklRewards };
@@ -1,39 +1,54 @@
1
- import { NetworkType } from "../../onchain/chain/chains.js";
1
+ import { ChainId, Token } from "../../model/primitives.js";
2
+ import "../../model/index.js";
3
+ import { OnchainSDK } from "../../onchain/OnchainSDK.js";
2
4
  import "../../onchain/index.js";
3
5
  import { Address } from "viem";
4
6
  //#region src/rewards/rewards/api.d.ts
5
- interface PoolData {
6
- address: Address;
7
- version: number;
8
- underlyingToken: Address;
9
- dieselRateRay: bigint;
10
- dieselToken: Address;
11
- stakedDieselToken: Address[];
12
- stakedDieselToken_old: Address[];
13
- expectedLiquidity: bigint;
7
+ /**
8
+ * One claimable Merkl liquidity-mining reward, denominated.
9
+ *
10
+ * Both tokens arrive resolved, so a consumer neither looks one up nor
11
+ * reassembles one out of the loose fields Merkl sends.
12
+ */
13
+ interface MerklReward {
14
+ readonly chainId: ChainId;
15
+ /** Market pool whose depositors the campaign rewards. */
16
+ readonly pool: Address;
17
+ /** That pool's share token — what the campaign is keyed on. */
18
+ readonly poolToken: Token;
19
+ /** The incentive token being handed out. */
20
+ readonly rewardToken: Token;
21
+ /** Claimable amount, i.e. distributed minus already claimed. Always > 0. */
22
+ readonly amount: bigint;
14
23
  }
15
- interface GearboxExtraMerkleLmReward {
16
- pool: Address;
17
- poolToken: Address;
18
- rewardTokenSymbol: string;
19
- rewardTokenDecimals: number;
20
- rewardToken: Address;
21
- amount: bigint;
22
- type: "extraMerkle";
23
- }
24
- type GearboxLmReward = GearboxExtraMerkleLmReward;
25
24
  type ReportHandler = (e: unknown, description?: string) => void;
26
- interface GetLmRewardsMerkleProps {
27
- pools: Record<Address, PoolData>;
25
+ /**
26
+ * What this read needs off a chain's SDK: which chain to ask Merkl about, the
27
+ * pools a campaign can be keyed on, and the registry that names their tokens.
28
+ *
29
+ * Sliced rather than taking the whole {@link OnchainSDK} so a caller can hand
30
+ * over a narrowed object — a test fixture included — without casting.
31
+ */
32
+ type MerklRewardsSdk = Pick<OnchainSDK, "chainId" | "marketRegister" | "tokensMeta">;
33
+ interface GetMerklRewardsProps {
34
+ /**
35
+ * The chain's SDK, attached. Reading `marketRegister` before attach throws,
36
+ * which the slice above cannot express.
37
+ */
38
+ sdk: MerklRewardsSdk;
28
39
  account: Address;
29
- network: NetworkType;
30
40
  reportError?: ReportHandler;
41
+ /** Raises Merkl's rate limit; the keyless path answers too. */
31
42
  apiKey?: string;
32
43
  }
33
- declare class RewardAmountAPI {
34
- private constructor();
35
- static getLmRewardsMerkle({ pools, account, network, reportError, apiKey }: GetLmRewardsMerkleProps): Promise<GearboxExtraMerkleLmReward[]>;
36
- private static extractFulfilled;
37
- }
44
+ /**
45
+ * The wallet's claimable Merkl rewards on one chain.
46
+ *
47
+ * Never rejects on a transport failure: the fetch is settled rather than
48
+ * awaited, and a failure goes to `reportError` and yields an empty list. A
49
+ * caller that must tell "this chain is down" from "this chain has no rewards"
50
+ * has to watch that callback.
51
+ */
52
+ declare function getMerklRewards({ sdk, account, reportError, apiKey }: GetMerklRewardsProps): Promise<MerklReward[]>;
38
53
  //#endregion
39
- export { GearboxExtraMerkleLmReward, GearboxLmReward, GetLmRewardsMerkleProps, PoolData, RewardAmountAPI };
54
+ export { GetMerklRewardsProps, MerklReward, MerklRewardsSdk, getMerklRewards };
@@ -1,3 +1,3 @@
1
- import { GearboxExtraMerkleLmReward, GearboxLmReward, GetLmRewardsMerkleProps, PoolData, RewardAmountAPI } from "./api.js";
1
+ import { GetMerklRewardsProps, MerklReward, MerklRewardsSdk, getMerklRewards } from "./api.js";
2
2
  import { GetPointsByPoolProps, GetTotalTokensOnProtocolProps, PoolPointsAPI, PoolPointsBase, getKeyForPoolPointsInfo } from "./extra-apy.js";
3
- export { GearboxExtraMerkleLmReward, GearboxLmReward, GetLmRewardsMerkleProps, GetPointsByPoolProps, GetTotalTokensOnProtocolProps, PoolData, PoolPointsAPI, PoolPointsBase, RewardAmountAPI, getKeyForPoolPointsInfo };
3
+ export { GetMerklRewardsProps, GetPointsByPoolProps, GetTotalTokensOnProtocolProps, MerklReward, MerklRewardsSdk, PoolPointsAPI, PoolPointsBase, getKeyForPoolPointsInfo, getMerklRewards };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gearbox-protocol/sdk",
3
- "version": "16.0.0-next.16",
3
+ "version": "16.0.0-next.17",
4
4
  "description": "Gearbox SDK",
5
5
  "license": "MIT",
6
6
  "repository": {