@continuumdao/ctm-mpc-defi 0.2.43 → 0.2.44

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.
@@ -3865,6 +3865,210 @@ async function loadEulerV2SupportedChainIds() {
3865
3865
  cached = new Set(Object.keys(EULER_V2_GOLDSKY_SUBGRAPH_URL_BY_CHAIN_ID).map((k) => Number(k)));
3866
3866
  return cached;
3867
3867
  }
3868
+ var MERKL_API_BASE = "https://api.merkl.xyz";
3869
+ var MERKL_DISTRIBUTOR_ADDRESS = "0x3Ef3D8bA38EBe18DB133cEc108f4D14CE00Dd9Ae";
3870
+ var MERKL_REWARDS_NOTES = "Wallet-wide Merkl on this chain (not protocol-filtered). Other venues\u2019 campaigns can appear. Claims the first Merkle root batch; call again if additionalRoots > 0. rEUL is omitted (Euler unlock flow). Merkl updates every 8\u201312 hours.";
3871
+ function normHex32(p) {
3872
+ const s = (p ?? "").trim();
3873
+ if (!s) return null;
3874
+ const x = s.startsWith("0x") ? s : `0x${s}`;
3875
+ if (!/^0x[0-9a-fA-F]{64}$/.test(x)) return null;
3876
+ return x;
3877
+ }
3878
+ function merklUserRewardsUrl(addr, chainId) {
3879
+ return `${MERKL_API_BASE}/v4/users/${encodeURIComponent(addr)}/rewards?chainId=${chainId}`;
3880
+ }
3881
+ async function loadMerklUserRewardsJson(args) {
3882
+ const addr = viem.getAddress(args.user);
3883
+ const url = merklUserRewardsUrl(addr, args.chainId);
3884
+ const res = await fetch(url, { cache: "no-store" });
3885
+ if (!res.ok) {
3886
+ let detail = `Merkl API error ${res.status}`;
3887
+ try {
3888
+ const j = await res.json();
3889
+ if (j?.error) {
3890
+ detail = j.details ? `${j.error}: ${j.details}` : j.error;
3891
+ }
3892
+ } catch {
3893
+ }
3894
+ throw new Error(detail);
3895
+ }
3896
+ return res.json();
3897
+ }
3898
+ function parseMerklUserRewardsToLeaves(raw, args) {
3899
+ const addr = viem.getAddress(args.user);
3900
+ if (!Array.isArray(raw)) {
3901
+ throw new Error("Merkl API returned an unexpected rewards shape.");
3902
+ }
3903
+ const collected = [];
3904
+ for (const block of raw) {
3905
+ for (const rw of block.rewards ?? []) {
3906
+ const root = (rw.root ?? "").trim();
3907
+ const dist = rw.distributionChainId;
3908
+ if (!root || dist !== args.chainId) continue;
3909
+ let recipient;
3910
+ try {
3911
+ recipient = viem.getAddress((rw.recipient ?? "").trim());
3912
+ } catch {
3913
+ continue;
3914
+ }
3915
+ if (recipient !== addr) continue;
3916
+ let amt = 0n;
3917
+ let clm = 0n;
3918
+ try {
3919
+ amt = BigInt((rw.amount ?? "0").toString().trim() || "0");
3920
+ clm = BigInt((rw.claimed ?? "0").toString().trim() || "0");
3921
+ } catch {
3922
+ continue;
3923
+ }
3924
+ if (amt <= clm) continue;
3925
+ let tokenAddr;
3926
+ try {
3927
+ tokenAddr = viem.getAddress((rw.token?.address ?? "").trim());
3928
+ } catch {
3929
+ continue;
3930
+ }
3931
+ const proofsRaw = rw.proofs ?? [];
3932
+ const proofs = [];
3933
+ for (const p of proofsRaw) {
3934
+ const h = normHex32(String(p));
3935
+ if (!h) continue;
3936
+ proofs.push(h);
3937
+ }
3938
+ if (proofsRaw.length > 0 && proofs.length !== proofsRaw.length) continue;
3939
+ const sym = (rw.token?.symbol ?? "").trim() || "\u2014";
3940
+ let dec = 18;
3941
+ try {
3942
+ const d = Number(rw.token?.decimals ?? 18);
3943
+ if (Number.isFinite(d) && d >= 0 && d <= 36) dec = d;
3944
+ } catch {
3945
+ dec = 18;
3946
+ }
3947
+ collected.push({ root, token: tokenAddr, amountWei: amt, proofs, symbol: sym, decimals: dec });
3948
+ }
3949
+ }
3950
+ return collected;
3951
+ }
3952
+ function selectFirstRootMerklLeaves(collected) {
3953
+ if (collected.length === 0) return [];
3954
+ const root0 = collected[0].root;
3955
+ return collected.filter((x) => x.root === root0);
3956
+ }
3957
+ function isMerklRewardEulLeaf(leaf) {
3958
+ const s = leaf.symbol.trim().toLowerCase().replace(/\s+/g, " ").trim();
3959
+ return s === "reul" || s === "reward eul";
3960
+ }
3961
+ async function fetchAllMerklDistributorClaimLeaves(args) {
3962
+ const raw = await loadMerklUserRewardsJson(args);
3963
+ return parseMerklUserRewardsToLeaves(raw, args);
3964
+ }
3965
+ function merklLeafToRow(leaf) {
3966
+ return {
3967
+ symbol: leaf.symbol,
3968
+ token: leaf.token,
3969
+ amountHuman: viem.formatUnits(leaf.amountWei, leaf.decimals),
3970
+ amountWei: leaf.amountWei.toString(),
3971
+ decimals: leaf.decimals,
3972
+ root: leaf.root
3973
+ };
3974
+ }
3975
+ async function fetchMerklRewardsSummary(args) {
3976
+ const user = viem.getAddress(args.user);
3977
+ const chainId = args.chainId;
3978
+ const all = await fetchAllMerklDistributorClaimLeaves({ chainId, user });
3979
+ const skippedReulCount = all.filter(isMerklRewardEulLeaf).length;
3980
+ const display = all.filter((l) => !isMerklRewardEulLeaf(l));
3981
+ const firstRoot = selectFirstRootMerklLeaves(display);
3982
+ const roots = new Set(display.map((l) => l.root));
3983
+ return {
3984
+ chainId,
3985
+ user,
3986
+ distributor: MERKL_DISTRIBUTOR_ADDRESS,
3987
+ claimable: display.map(merklLeafToRow),
3988
+ claimableCount: display.length,
3989
+ firstRootClaimableCount: firstRoot.length,
3990
+ additionalRoots: Math.max(0, roots.size - (firstRoot.length > 0 ? 1 : 0)),
3991
+ skippedReulCount,
3992
+ notes: MERKL_REWARDS_NOTES
3993
+ };
3994
+ }
3995
+
3996
+ // src/protocols/evm/euler-v2/merklRewards.ts
3997
+ async function eulerV2FetchMerklRewardsSummary(args) {
3998
+ return fetchMerklRewardsSummary(args);
3999
+ }
4000
+ var AAVE_MERKL_CLAIM_ESTIMATE_FALLBACK = 500000n;
4001
+ viem.parseAbi(["function deposit() payable"]);
4002
+ viem.parseAbi([
4003
+ "function allowance(address owner, address spender) view returns (uint256)",
4004
+ "function decimals() view returns (uint8)"
4005
+ ]);
4006
+ viem.parseAbi(["function approve(address spender, uint256 amount) returns (bool)"]);
4007
+ viem.parseAbi(["function supply(uint256 reserveId, uint256 amount, address onBehalfOf)"]);
4008
+ viem.parseAbi(["function withdraw(uint256 reserveId, uint256 amount, address onBehalfOf)"]);
4009
+ viem.parseAbi(["function borrow(uint256 reserveId, uint256 amount, address onBehalfOf)"]);
4010
+ viem.parseAbi(["function repay(uint256 reserveId, uint256 amount, address onBehalfOf)"]);
4011
+ viem.parseAbi([
4012
+ "function setUsingAsCollateral(uint256 reserveId, bool usingAsCollateral, address onBehalfOf)"
4013
+ ]);
4014
+ async function buildEvmMultisignBodyEulerV2MerklDistributorClaim(args) {
4015
+ const to = viem.getAddress(args.to);
4016
+ const executor = viem.getAddress(args.executorAddress);
4017
+ return buildEvmMultisignBodyAaveV4OneStep({
4018
+ keyGen: args.keyGen,
4019
+ chainId: args.chainId,
4020
+ rpcUrl: args.rpcUrl,
4021
+ chainDetail: args.chainDetail,
4022
+ useCustomGas: args.useCustomGas,
4023
+ customGasChainDetails: args.customGasChainDetails ?? void 0,
4024
+ purposeText: args.purposeText,
4025
+ purposeSuffix: `Euler v2: 1-tx \u2014 Merkl distributor claim (${args.claimLeafCount} reward(s), see calldata in signature text).`,
4026
+ executorAddress: executor,
4027
+ v: { to, data: args.data, value: args.valueWei },
4028
+ estimateGasFallback: AAVE_MERKL_CLAIM_ESTIMATE_FALLBACK,
4029
+ buildBatchMeta: (ctx) => ({
4030
+ destinationAddress: to,
4031
+ signatureText: JSON.stringify({
4032
+ kind: "EulerV2",
4033
+ name: "Merkl Distributor claim",
4034
+ claimLeafCount: args.claimLeafCount,
4035
+ chainId: args.chainId,
4036
+ valueWei: args.valueWei.toString(),
4037
+ note: "Merkl API proofs; Distributor.claim(users,tokens,amounts,proofs)."
4038
+ }),
4039
+ evm: { type: "euler_v2_merkl_distributor_claim", version: 1, chainId: String(args.chainId) },
4040
+ eulerV2: { step: "merkl_distributor_claim", claimLeafCount: args.claimLeafCount, gasBuildClaim: { baseGasUnits: ctx.gasLimit.toString() } }
4041
+ })
4042
+ });
4043
+ }
4044
+ async function buildEvmMultisignBodyAaveV4OneStep(args) {
4045
+ const firstDataNo0x = args.v.data.startsWith("0x") ? args.v.data.slice(2) : args.v.data;
4046
+ return buildEvmMultisignBatch({
4047
+ context: {
4048
+ chainCategory: "evm",
4049
+ keyGen: args.keyGen,
4050
+ purposeText: args.purposeText,
4051
+ chainId: args.chainId,
4052
+ rpcUrl: args.rpcUrl,
4053
+ executorAddress: args.executorAddress,
4054
+ chainDetail: args.chainDetail,
4055
+ useCustomGas: args.useCustomGas,
4056
+ customGasChainDetails: args.customGasChainDetails
4057
+ },
4058
+ steps: [
4059
+ {
4060
+ to: args.v.to,
4061
+ data: args.v.data,
4062
+ value: args.v.value,
4063
+ fallbackGas: args.estimateGasFallback
4064
+ }
4065
+ ],
4066
+ purposeSuffix: args.purposeSuffix,
4067
+ firstMsgRawNo0x: firstDataNo0x,
4068
+ destinationAddress: args.v.to,
4069
+ buildBatchMeta: ({ gasLimit }) => args.buildBatchMeta({ gasLimit })
4070
+ });
4071
+ }
3868
4072
 
3869
4073
  // src/protocols/evm/euler-v2/index.ts
3870
4074
  var EULER_V2_PROTOCOL_ID = "euler-v2";
@@ -3883,7 +4087,9 @@ var eulerV2ProtocolModule = {
3883
4087
  { id: "euler-v2.vault-withdraw", protocolId: EULER_V2_PROTOCOL_ID, chainCategory: "evm", description: "Withdraw from Euler vault", commonParams: ["keyGen", "purposeText", "useCustomGas"], params: {} },
3884
4088
  { id: "euler-v2.borrow-repay", protocolId: EULER_V2_PROTOCOL_ID, chainCategory: "evm", description: "Repay Euler borrow", commonParams: ["keyGen", "purposeText", "useCustomGas"], params: {} },
3885
4089
  { id: "euler-v2.collateral-deposit", protocolId: EULER_V2_PROTOCOL_ID, chainCategory: "evm", description: "Deposit borrow collateral", commonParams: ["keyGen", "purposeText", "useCustomGas"], params: {} },
3886
- { id: "euler-v2.collateral-withdraw", protocolId: EULER_V2_PROTOCOL_ID, chainCategory: "evm", description: "Withdraw borrow collateral", commonParams: ["keyGen", "purposeText", "useCustomGas"], params: {} }
4090
+ { id: "euler-v2.collateral-withdraw", protocolId: EULER_V2_PROTOCOL_ID, chainCategory: "evm", description: "Withdraw borrow collateral", commonParams: ["keyGen", "purposeText", "useCustomGas"], params: {} },
4091
+ { id: "euler-v2.fetch-merkl-rewards", protocolId: EULER_V2_PROTOCOL_ID, chainCategory: "evm", description: "List wallet-wide Merkl claimables on a chain", commonParams: [], params: {} },
4092
+ { id: "euler-v2.merkl-claim", protocolId: EULER_V2_PROTOCOL_ID, chainCategory: "evm", description: "Claim wallet-wide Merkl rewards", commonParams: ["keyGen", "purposeText", "useCustomGas"], params: {} }
3887
4093
  ]
3888
4094
  };
3889
4095
  registerProtocolModule(eulerV2ProtocolModule);
@@ -3908,6 +4114,7 @@ exports.buildEvmMultisignBodyEulerV2BorrowCollateralWithdrawBatch = buildEvmMult
3908
4114
  exports.buildEvmMultisignBodyEulerV2BorrowRepayBatch = buildEvmMultisignBodyEulerV2BorrowRepayBatch;
3909
4115
  exports.buildEvmMultisignBodyEulerV2IsolatedBorrowBatch = buildEvmMultisignBodyEulerV2IsolatedBorrowBatch;
3910
4116
  exports.buildEvmMultisignBodyEulerV2IsolatedLendDepositBatch = buildEvmMultisignBodyEulerV2IsolatedLendDepositBatch;
4117
+ exports.buildEvmMultisignBodyEulerV2MerklDistributorClaim = buildEvmMultisignBodyEulerV2MerklDistributorClaim;
3911
4118
  exports.buildEvmMultisignBodyEulerV2VaultWithdraw = buildEvmMultisignBodyEulerV2VaultWithdraw;
3912
4119
  exports.clampEulerUnderlyingDecimalsForEulerUi = clampEulerUnderlyingDecimalsForEulerUi;
3913
4120
  exports.encodeEulerReulWithdrawToByLockTimestampsData = encodeEulerReulWithdrawToByLockTimestampsData;
@@ -3922,6 +4129,7 @@ exports.eulerSameAssetTotalCollateralPullWei = eulerSameAssetTotalCollateralPull
3922
4129
  exports.eulerSubgraphVaultCapToUnderlyingWei = eulerSubgraphVaultCapToUnderlyingWei;
3923
4130
  exports.eulerV2FetchEarnVaultsSummary = eulerV2FetchEarnVaultsSummary;
3924
4131
  exports.eulerV2FetchLendVaultsSummary = eulerV2FetchLendVaultsSummary;
4132
+ exports.eulerV2FetchMerklRewardsSummary = eulerV2FetchMerklRewardsSummary;
3925
4133
  exports.eulerV2GoldskyUrlForChain = eulerV2GoldskyUrlForChain;
3926
4134
  exports.eulerV2KeyForNodeAssetRow = eulerV2KeyForNodeAssetRow;
3927
4135
  exports.eulerV2ProtocolModule = eulerV2ProtocolModule;