@raac/rpc 2.0.0-beta.6 → 2.0.0-beta.7

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.
Files changed (41) hide show
  1. package/dist/RPCLibrary.js +13 -0
  2. package/dist/configs/chains/11155111.json +30 -0
  3. package/dist/contracts/curve/common/_helpers.js +39 -0
  4. package/dist/contracts/curve/common/getPools.js +36 -0
  5. package/dist/contracts/curve/common/getVirtualPrice.js +26 -0
  6. package/dist/contracts/curve/common/index.js +18 -0
  7. package/dist/contracts/findContract.js +3 -3
  8. package/dist/contracts/getContractAddress.js +1 -0
  9. package/dist/contracts/governance/gaugeSystems/_helpers.js +2 -2
  10. package/dist/pools/lendingPool/adapters/erc20/getERC20AdapterBalance.js +4 -4
  11. package/dist/types/RPCLibrary.d.ts +8 -1
  12. package/dist/types/contracts/curve/common/_helpers.d.ts +16 -0
  13. package/dist/types/contracts/curve/common/getPools.d.ts +30 -0
  14. package/dist/types/contracts/curve/common/getVirtualPrice.d.ts +13 -0
  15. package/dist/types/contracts/curve/common/index.d.ts +2 -0
  16. package/dist/types/pools/lendingPool/adapters/erc20/getERC20AdapterBalance.d.ts +3 -3
  17. package/dist/types/user/_helpers.d.ts +23 -0
  18. package/dist/types/user/computeEffectiveReturn.d.ts +67 -0
  19. package/dist/types/user/getUserClaimables.d.ts +55 -0
  20. package/dist/types/user/getUserCollateral.d.ts +12 -0
  21. package/dist/types/user/getUserDebt.d.ts +18 -0
  22. package/dist/types/user/getUserFarming.d.ts +64 -0
  23. package/dist/types/user/getUserGovernance.d.ts +20 -0
  24. package/dist/types/user/getUserPortfolio.d.ts +61 -0
  25. package/dist/types/user/getUserWalletBalances.d.ts +20 -0
  26. package/dist/types/user/index.d.ts +9 -0
  27. package/dist/types/utils/amount.d.ts +7 -0
  28. package/dist/types/utils/contracts.d.ts +2 -0
  29. package/dist/user/_helpers.js +22 -0
  30. package/dist/user/computeEffectiveReturn.js +33 -0
  31. package/dist/user/getUserClaimables.js +97 -0
  32. package/dist/user/getUserCollateral.js +29 -0
  33. package/dist/user/getUserDebt.js +32 -0
  34. package/dist/user/getUserFarming.js +100 -0
  35. package/dist/user/getUserGovernance.js +35 -0
  36. package/dist/user/getUserPortfolio.js +109 -0
  37. package/dist/user/getUserWalletBalances.js +30 -0
  38. package/dist/user/index.js +24 -0
  39. package/dist/utils/amount.js +10 -0
  40. package/dist/utils/contracts.js +5 -2
  41. package/package.json +1 -1
@@ -204,6 +204,10 @@ const distributorMethods = __importStar(require("./contracts/governance/distribu
204
204
  const gaugeMethods = __importStar(require("./contracts/governance/gauge"));
205
205
  const controllerMethods = __importStar(require("./contracts/governance/gaugeController"));
206
206
  const gaugeSystemMethods = __importStar(require("./contracts/governance/gaugeSystems"));
207
+ // ===== Curve =====
208
+ const curveCommonMethods = __importStar(require("./contracts/curve/common"));
209
+ // ===== User aggregates (dashboard) =====
210
+ const userMethods = __importStar(require("./user"));
207
211
  // Proposals
208
212
  const cancel_1 = require("./contracts/governance/proposals/cancel");
209
213
  const getQuorumNumerator_1 = require("./contracts/governance/proposals/getQuorumNumerator");
@@ -400,6 +404,10 @@ class RPCLibrary {
400
404
  chainId;
401
405
  privateKey;
402
406
  // prices
407
+ // Curve pools from the chain config's `curve` section
408
+ curve;
409
+ // Aggregate reads of one user's position and claimables, composed from the methods above
410
+ user;
403
411
  prices;
404
412
  // valid
405
413
  assets;
@@ -846,6 +854,10 @@ class RPCLibrary {
846
854
  priceAt: priceAt_1.priceAt,
847
855
  quoteBuy: quoteBuy_1.quoteBuy,
848
856
  };
857
+ this.curve = {
858
+ common: curveCommonMethods,
859
+ };
860
+ this.user = userMethods;
849
861
  this.prices = {
850
862
  getPrices: getPrices_1.getPrices,
851
863
  getTokenPriceUSD: tokenPricesUSD_1.getTokenPriceUSD,
@@ -859,6 +871,7 @@ class RPCLibrary {
859
871
  toScaled: amount_1.toScaled,
860
872
  parseAmount: amount_1.parseAmount,
861
873
  toDecimalString: amount_1.toDecimalString,
874
+ toNumber: amount_1.toNumber,
862
875
  serializeAmount: amount_1.serializeAmount,
863
876
  deserializeAmount: amount_1.deserializeAmount,
864
877
  getAssetDecimals: amount_1.getAssetDecimals,
@@ -179,6 +179,36 @@
179
179
  "contract": "0x7F7d0924C9082F4C3F0D5D97bF9a26C3D3DEf706"
180
180
  }
181
181
  },
182
+ "curve": {
183
+ "raac-pmusd": {
184
+ "id": "raac-pmusd",
185
+ "name": "RAAC / pmUSD",
186
+ "contract": "0xF65C691aE1782A9A504d6865F0dAeC88Ef46a592",
187
+ "flavour": "twocrypto",
188
+ "coins": ["pmusd", "raactoken"]
189
+ },
190
+ "ireet-pmusd": {
191
+ "id": "ireet-pmusd",
192
+ "name": "iREET / pmUSD",
193
+ "contract": "0x7F7d0924C9082F4C3F0D5D97bF9a26C3D3DEf706",
194
+ "flavour": "twocrypto",
195
+ "coins": ["pmusd", "rwaindextoken"]
196
+ },
197
+ "rpmusd-depmusd": {
198
+ "id": "rpmusd-depmusd",
199
+ "name": "RpmUSD / DEpmUSD",
200
+ "contract": "0x421E9431E751c8fC02E53F8e54a1772aE6021BeD",
201
+ "flavour": "stableswap",
202
+ "coins": ["rtoken", "detoken"]
203
+ },
204
+ "leraac-raac-pmusd": {
205
+ "id": "leraac-raac-pmusd",
206
+ "name": "leRAAC / RAAC / pmUSD",
207
+ "contract": "0x1D0805Bd3EF5338b66158770c28fD6f4Cd685F28",
208
+ "flavour": "tricrypto",
209
+ "coins": ["pmusd", "raactoken", "leraac"]
210
+ }
211
+ },
182
212
  "nfts": {
183
213
  "raacnft": {
184
214
  "id": "raacnft",
@@ -0,0 +1,39 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.getCurvePools = exports.CURVE_POOL_READ_ABI = void 0;
7
+ exports.resolveCurvePool = resolveCurvePool;
8
+ exports.getCurvePoolContract = getCurvePoolContract;
9
+ const ethers_1 = require("ethers");
10
+ const chains_1 = __importDefault(require("../../../configs/chains"));
11
+ /**
12
+ * Reads every Curve pool flavour shares. Coin indexes differ (uint256 vs int128) only in swap and liquidity
13
+ * methods, which are not here.
14
+ */
15
+ exports.CURVE_POOL_READ_ABI = [
16
+ "function coins(uint256) view returns (address)",
17
+ "function balances(uint256) view returns (uint256)",
18
+ "function totalSupply() view returns (uint256)",
19
+ "function balanceOf(address) view returns (uint256)",
20
+ "function get_virtual_price() view returns (uint256)",
21
+ ];
22
+ const getCurvePools = (chainId) => chains_1.default[chainId]?.curve ?? {};
23
+ exports.getCurvePools = getCurvePools;
24
+ /** Resolves a Curve pool by its config key (any casing) or its address. */
25
+ function resolveCurvePool(chainId, poolAddressOrId) {
26
+ const pools = (0, exports.getCurvePools)(chainId);
27
+ const needle = poolAddressOrId.toLowerCase();
28
+ const entry = pools[needle] ?? Object.values(pools).find((pool) => pool.contract.toLowerCase() === needle);
29
+ if (!entry)
30
+ throw new Error(`Curve pool "${poolAddressOrId}" not configured for chain ${chainId}`);
31
+ return entry;
32
+ }
33
+ function getCurvePoolContract(chainId, poolAddressOrId, provider) {
34
+ if (!provider) {
35
+ provider = new ethers_1.ethers.JsonRpcProvider(chains_1.default[chainId].rpcs[0]);
36
+ }
37
+ const entry = resolveCurvePool(chainId, poolAddressOrId);
38
+ return { entry, contract: new ethers_1.ethers.Contract(entry.contract, exports.CURVE_POOL_READ_ABI, provider), provider };
39
+ }
@@ -0,0 +1,36 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getPool = exports.getPools = void 0;
4
+ const amount_1 = require("../../../utils/amount");
5
+ const contracts_1 = require("../../../utils/contracts");
6
+ const _helpers_1 = require("./_helpers");
7
+ const toPool = (chainId, entry) => ({
8
+ ...entry,
9
+ coins: entry.coins.map((asset) => {
10
+ const info = (0, amount_1.getTokenInfo)(chainId, asset);
11
+ return {
12
+ asset,
13
+ address: (0, contracts_1.getContractAddress)(chainId, asset),
14
+ symbol: info?.symbol ?? asset,
15
+ decimals: info?.decimals ?? 18,
16
+ };
17
+ }),
18
+ });
19
+ /**
20
+ * Lists the Curve pools in the chain config.
21
+ *
22
+ * @param chainId - The chain/network to use.
23
+ * @returns Every configured pool with its flavour and coins in pool index order; empty when the chain has none.
24
+ */
25
+ const getPools = (chainId) => Object.values((0, _helpers_1.getCurvePools)(chainId)).map((entry) => toPool(chainId, entry));
26
+ exports.getPools = getPools;
27
+ /**
28
+ * Looks up one Curve pool in the chain config. Reads the config only; no RPC call is made.
29
+ *
30
+ * @param chainId - The chain/network to use.
31
+ * @param poolAddressOrId - The pool's config key or its address.
32
+ * @returns The pool with its flavour and coins in pool index order.
33
+ * @throws If the pool is not configured on the chain.
34
+ */
35
+ const getPool = (chainId, poolAddressOrId) => toPool(chainId, (0, _helpers_1.resolveCurvePool)(chainId, poolAddressOrId));
36
+ exports.getPool = getPool;
@@ -0,0 +1,26 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getVirtualPrice = void 0;
4
+ const amount_1 = require("../../../utils/amount");
5
+ const rpcError_1 = require("../../../utils/rpcError");
6
+ const _helpers_1 = require("./_helpers");
7
+ /**
8
+ * Reads a Curve pool's virtual price: the value of one whole LP token in units of the pool's underlying coins,
9
+ * which only grows with fees. For a stableswap pool of $1 coins it is the LP token's USD price.
10
+ *
11
+ * @param chainId - The chain/network to use.
12
+ * @param poolAddressOrId - The pool's key in the chain config's `curve` section, or its address.
13
+ * @param provider - Optional ethers.js Provider instance.
14
+ * @returns `get_virtual_price()` as an 18-decimal amount, e.g. 1.0021 underlying per LP token.
15
+ */
16
+ const getVirtualPrice = async (chainId, poolAddressOrId, provider) => {
17
+ const { entry, contract } = (0, _helpers_1.getCurvePoolContract)(chainId, poolAddressOrId, provider);
18
+ try {
19
+ const price = await contract.get_virtual_price();
20
+ return (0, amount_1.toAmount)(price, amount_1.WAD_DECIMALS);
21
+ }
22
+ catch (error) {
23
+ throw (0, rpcError_1.toRpcError)("curve.common.getVirtualPrice", error, { chainId, address: entry.contract });
24
+ }
25
+ };
26
+ exports.getVirtualPrice = getVirtualPrice;
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./getPools"), exports);
18
+ __exportStar(require("./getVirtualPrice"), exports);
@@ -7,10 +7,10 @@ exports.findContract = void 0;
7
7
  const ethers_1 = require("ethers");
8
8
  const chains_1 = __importDefault(require("../configs/chains"));
9
9
  const artifacts_1 = require("../utils/artifacts");
10
+ const contracts_1 = require("../utils/contracts");
10
11
  /** Sections scanned in order; the first match wins. */
11
- const FLAT_SECTIONS = ["contracts", "governance", "pools", "lockers", "zap", "psm", "nfts", "assets"];
12
+ const FLAT_SECTIONS = ["contracts", "governance", "pools", "lockers", "zap", "psm", "nfts", "assets", "curve"];
12
13
  const abiKey = (key) => (key in artifacts_1.ABIS ? key : null);
13
- const isDeployed = (address) => !!address && ethers_1.ethers.isAddress(address) && address !== ethers_1.ethers.ZeroAddress;
14
14
  /** Builds every configured contract on the chain with its name and ABI key. */
15
15
  function listContracts(chainId) {
16
16
  const config = chains_1.default[chainId];
@@ -19,7 +19,7 @@ function listContracts(chainId) {
19
19
  }
20
20
  const found = [];
21
21
  const push = (entry) => {
22
- if (isDeployed(entry.address))
22
+ if ((0, contracts_1.isDeployed)(entry.address))
23
23
  found.push({ ...entry, address: ethers_1.ethers.getAddress(entry.address) });
24
24
  };
25
25
  // gauges: { <system>: { label, gaugeType, controller, distributor, gauges: [{ id, name, contract }] } }
@@ -31,6 +31,7 @@ const getContractAddress = (chainId, contractName) => {
31
31
  "lockers",
32
32
  "zap",
33
33
  "psm",
34
+ "curve",
34
35
  ];
35
36
  let address = null;
36
37
  for (const key of lookupKeys) {
@@ -7,8 +7,8 @@ exports.resolveGauge = exports.lookupGauge = exports.listGauges = exports.resolv
7
7
  const ethers_1 = require("ethers");
8
8
  const chains_1 = __importDefault(require("../../../configs/chains"));
9
9
  const _helpers_1 = require("../_helpers");
10
+ const contracts_1 = require("../../../utils/contracts");
10
11
  exports.GAUGE_SYSTEM_IDS = ["raacgauges", "rwagauges"];
11
- const isDeployed = (address) => !!address && ethers_1.ethers.isAddress(address) && address !== ethers_1.ethers.ZeroAddress;
12
12
  /**
13
13
  * Reads the `gauges` section of a chain config.
14
14
  *
@@ -51,7 +51,7 @@ const resolveSystemContract = (chainId, ref, field, name) => {
51
51
  return (0, _helpers_1.requireAddress)(ref, name);
52
52
  }
53
53
  const system = (0, exports.requireGaugeSystem)(chainId, ref);
54
- if (!isDeployed(system[field])) {
54
+ if (!(0, contracts_1.isDeployed)(system[field])) {
55
55
  throw new Error(`Gauge system "${system.id}" has no ${name} deployed on chainId: ${chainId}`);
56
56
  }
57
57
  return ethers_1.ethers.getAddress(system[field]);
@@ -9,16 +9,16 @@ const rpcError_1 = require("../../../../utils/rpcError");
9
9
  * @param chainId The chain id, used to look up the adapter token's decimals in the token registry.
10
10
  * @param adapterAddress The ERC20 asset adapter address.
11
11
  * @param userAddress The user.
12
- * @param signer The signer to read with.
12
+ * @param runner The signer or provider to read with. A read-only provider is enough.
13
13
  * @returns The deposited balance in base units of the adapter's token, with its registry decimals and symbol (18 decimals if the token is not in the registry).
14
14
  */
15
- async function getERC20AdapterBalance(chainId, adapterAddress, userAddress, signer) {
16
- if (!signer) {
15
+ async function getERC20AdapterBalance(chainId, adapterAddress, userAddress, runner) {
16
+ if (!runner) {
17
17
  throw new Error("Wallet not connected");
18
18
  }
19
19
  try {
20
20
  const abi = (0, artifacts_1.getABI)("erc20assetadapter");
21
- const adapterContract = new ethers_1.ethers.Contract(adapterAddress, abi, signer);
21
+ const adapterContract = new ethers_1.ethers.Contract(adapterAddress, abi, runner);
22
22
  const [balance, token] = await Promise.all([
23
23
  adapterContract.balanceOf(userAddress),
24
24
  adapterContract.token(),
@@ -134,11 +134,13 @@ import { cancelExit as cancelExitPsm } from "./contracts/psm/cancelExit";
134
134
  import { redeem as redeemPsm } from "./contracts/psm/redeem";
135
135
  import { swap as swapPsm } from "./contracts/psm/swap";
136
136
  import { getABI } from "./utils/artifacts";
137
- import { toAmount, toScaled, parseAmount, toDecimalString, serializeAmount, deserializeAmount, getAssetDecimals, getTokenInfo, toTokenAmount } from "./utils/amount";
137
+ import { toAmount, toScaled, parseAmount, toDecimalString, toNumber, serializeAmount, deserializeAmount, getAssetDecimals, getTokenInfo, toTokenAmount } from "./utils/amount";
138
138
  import * as distributorMethods from "./contracts/governance/distributor";
139
139
  import * as gaugeMethods from "./contracts/governance/gauge";
140
140
  import * as controllerMethods from "./contracts/governance/gaugeController";
141
141
  import * as gaugeSystemMethods from "./contracts/governance/gaugeSystems";
142
+ import * as curveCommonMethods from "./contracts/curve/common";
143
+ import * as userMethods from "./user";
142
144
  import { cancel as cancelProposals } from "./contracts/governance/proposals/cancel";
143
145
  import { getQuorumNumerator as getQuorumNumeratorProposals } from "./contracts/governance/proposals/getQuorumNumerator";
144
146
  import { getVotingPeriod as getVotingPeriodProposals } from "./contracts/governance/proposals/getVotingPeriod";
@@ -316,6 +318,10 @@ declare class RPCLibrary {
316
318
  address: JsonRpcSigner | string;
317
319
  chainId: ChainId | bigint | null;
318
320
  privateKey: any;
321
+ curve: {
322
+ common: typeof curveCommonMethods;
323
+ };
324
+ user: typeof userMethods;
319
325
  prices: {
320
326
  getPrices: typeof getPrices;
321
327
  getTokenPriceUSD: typeof getTokenPriceUSD;
@@ -732,6 +738,7 @@ declare class RPCLibrary {
732
738
  toScaled: typeof toScaled;
733
739
  parseAmount: typeof parseAmount;
734
740
  toDecimalString: typeof toDecimalString;
741
+ toNumber: typeof toNumber;
735
742
  serializeAmount: typeof serializeAmount;
736
743
  deserializeAmount: typeof deserializeAmount;
737
744
  getAssetDecimals: typeof getAssetDecimals;
@@ -0,0 +1,16 @@
1
+ import { ethers, Provider } from "ethers";
2
+ import { ChainId } from "../../../configs/chains";
3
+ import { CurvePoolEntry, CurvePools } from "../../../configs/chains/chain";
4
+ /**
5
+ * Reads every Curve pool flavour shares. Coin indexes differ (uint256 vs int128) only in swap and liquidity
6
+ * methods, which are not here.
7
+ */
8
+ export declare const CURVE_POOL_READ_ABI: string[];
9
+ export declare const getCurvePools: (chainId: ChainId) => CurvePools;
10
+ /** Resolves a Curve pool by its config key (any casing) or its address. */
11
+ export declare function resolveCurvePool(chainId: ChainId, poolAddressOrId: string): CurvePoolEntry;
12
+ export declare function getCurvePoolContract(chainId: ChainId, poolAddressOrId: string, provider?: Provider): {
13
+ entry: CurvePoolEntry;
14
+ contract: ethers.Contract;
15
+ provider: ethers.Provider;
16
+ };
@@ -0,0 +1,30 @@
1
+ import { ChainId } from "../../../configs/chains";
2
+ import { CurvePoolEntry } from "../../../configs/chains/chain";
3
+ export interface CurvePoolCoin {
4
+ /** Asset key in the chain config, e.g. "pmusd". */
5
+ asset: string;
6
+ address: string;
7
+ /** From the token registry; the asset key when the registry has no symbol. */
8
+ symbol: string;
9
+ decimals: number;
10
+ }
11
+ export interface CurvePool extends Omit<CurvePoolEntry, "coins"> {
12
+ /** In pool index order: coins[i] is coin i on chain. */
13
+ coins: CurvePoolCoin[];
14
+ }
15
+ /**
16
+ * Lists the Curve pools in the chain config.
17
+ *
18
+ * @param chainId - The chain/network to use.
19
+ * @returns Every configured pool with its flavour and coins in pool index order; empty when the chain has none.
20
+ */
21
+ export declare const getPools: (chainId: ChainId) => CurvePool[];
22
+ /**
23
+ * Looks up one Curve pool in the chain config. Reads the config only; no RPC call is made.
24
+ *
25
+ * @param chainId - The chain/network to use.
26
+ * @param poolAddressOrId - The pool's config key or its address.
27
+ * @returns The pool with its flavour and coins in pool index order.
28
+ * @throws If the pool is not configured on the chain.
29
+ */
30
+ export declare const getPool: (chainId: ChainId, poolAddressOrId: string) => CurvePool;
@@ -0,0 +1,13 @@
1
+ import { Provider } from "ethers";
2
+ import { ChainId } from "../../../configs/chains";
3
+ import { TokenAmount } from "../../../utils/amount";
4
+ /**
5
+ * Reads a Curve pool's virtual price: the value of one whole LP token in units of the pool's underlying coins,
6
+ * which only grows with fees. For a stableswap pool of $1 coins it is the LP token's USD price.
7
+ *
8
+ * @param chainId - The chain/network to use.
9
+ * @param poolAddressOrId - The pool's key in the chain config's `curve` section, or its address.
10
+ * @param provider - Optional ethers.js Provider instance.
11
+ * @returns `get_virtual_price()` as an 18-decimal amount, e.g. 1.0021 underlying per LP token.
12
+ */
13
+ export declare const getVirtualPrice: (chainId: ChainId, poolAddressOrId: string, provider?: Provider) => Promise<TokenAmount>;
@@ -0,0 +1,2 @@
1
+ export * from "./getPools";
2
+ export * from "./getVirtualPrice";
@@ -1,4 +1,4 @@
1
- import { Signer } from "ethers";
1
+ import { Provider, Signer } from "ethers";
2
2
  import { ChainId } from "../../../../configs/chains";
3
3
  import { TokenAmount } from "../../../../utils/amount";
4
4
  /**
@@ -6,8 +6,8 @@ import { TokenAmount } from "../../../../utils/amount";
6
6
  * @param chainId The chain id, used to look up the adapter token's decimals in the token registry.
7
7
  * @param adapterAddress The ERC20 asset adapter address.
8
8
  * @param userAddress The user.
9
- * @param signer The signer to read with.
9
+ * @param runner The signer or provider to read with. A read-only provider is enough.
10
10
  * @returns The deposited balance in base units of the adapter's token, with its registry decimals and symbol (18 decimals if the token is not in the registry).
11
11
  */
12
- declare function getERC20AdapterBalance(chainId: ChainId, adapterAddress: string, userAddress: string, signer: Signer): Promise<TokenAmount>;
12
+ declare function getERC20AdapterBalance(chainId: ChainId, adapterAddress: string, userAddress: string, runner: Signer | Provider): Promise<TokenAmount>;
13
13
  export default getERC20AdapterBalance;
@@ -0,0 +1,23 @@
1
+ import { TokenAmount } from "../utils/amount";
2
+ /**
3
+ * USD price of one whole token, keyed by lowercase symbol, e.g. `{ raac: 5, pmusd: 1, ireet: 0.995 }`. The app
4
+ * builds it with its `usePrices` hook, so the rpc and the UI value everything identically.
5
+ */
6
+ export type UsdPrices = Record<string, number>;
7
+ /** A read that settled independently of the others: its data, or why it failed. One failure never blanks the rest. */
8
+ export type Section<T> = {
9
+ data: T;
10
+ error: null;
11
+ } | {
12
+ data: null;
13
+ error: Error;
14
+ };
15
+ /** Settles one read into a {@link Section}: never rejects, so reads awaited together fail independently. */
16
+ export declare const settled: <T>(read: Promise<T>) => Promise<Section<T>>;
17
+ /**
18
+ * USD value of an amount from `prices`, by the symbol `toTokenAmount` gave it from the chain config's token registry.
19
+ * Throws when there is no price, so the section fails visibly instead of reading 0.
20
+ *
21
+ * @param token - The amount's asset key or token address, named in the error.
22
+ */
23
+ export declare function requireUsd(prices: UsdPrices, amount: TokenAmount, token: string): number;
@@ -0,0 +1,67 @@
1
+ /** Whether a leg earns income or costs it. */
2
+ export type ReturnLegKind = "earning" | "cost";
3
+ /** What a leg earns or costs. A unit of capital earns each yield type at most once. */
4
+ export type ReturnLegYieldType = "supply" | "gauge" | "borrow";
5
+ /**
6
+ * One income stream in the user's position, as {@link computeEffectiveReturn} consumes it. Adding a venue (a new
7
+ * gauge, another pmUSD venue) only means adding a leg; the calculator does not change.
8
+ */
9
+ export interface ReturnLeg {
10
+ /** Stable key, e.g. "borrow", "supply", "gauge:r-rpmdepmUSD". */
11
+ id: string;
12
+ /** Display name, e.g. "Borrow pmUSD". */
13
+ source: string;
14
+ kind: ReturnLegKind;
15
+ yieldType: ReturnLegYieldType;
16
+ /**
17
+ * True when the leg's value is money the user holds and counts towards net capital (supplied). False for the
18
+ * debt itself, and for overlays such as a gauge, whose staked value is already counted in another leg.
19
+ */
20
+ countsAsCapital: boolean;
21
+ /** USD value the rate applies to. Never negative. */
22
+ valueUsd: number;
23
+ /** The projected one-year rate as a fraction, e.g. 0.0077 for 0.77%. */
24
+ rate: number;
25
+ /** How `rate` is quoted: "apy" when it already compounds (borrow), "apr" when it does not (supply, gauge). */
26
+ rateKind: "apr" | "apy";
27
+ }
28
+ export interface ReturnLegWithIncome extends ReturnLeg {
29
+ /** Projected income over one year in USD: `valueUsd * rate`, negative for a cost leg. */
30
+ income1y: number;
31
+ }
32
+ export interface EffectiveReturnInput {
33
+ legs: readonly ReturnLeg[];
34
+ /** USD value of the collateral backing the debt. */
35
+ collateralUsd: number;
36
+ /**
37
+ * USD value of capital that earns nothing, e.g. idle pmUSD in the wallet or a non-yielding coin inside a staked
38
+ * LP. It is not a leg (no income, not listed in a breakdown); it only adds to net capital.
39
+ */
40
+ idleUsd?: number;
41
+ }
42
+ export interface EffectiveReturn {
43
+ /** Earning legs' income minus cost legs' cost over one year, in USD. */
44
+ netIncome1y: number;
45
+ /** `netIncome1y / debtUsd` as a fraction; null when there is no debt. */
46
+ onDebt: number | null;
47
+ /** `netIncome1y / netCapitalUsd` as a fraction; null when net capital is zero or negative. */
48
+ onNetCapital: number | null;
49
+ /** Sum of the cost legs' values. */
50
+ debtUsd: number;
51
+ /** Collateral + capital legs + idle - debt. */
52
+ netCapitalUsd: number;
53
+ legs: ReturnLegWithIncome[];
54
+ }
55
+ /**
56
+ * Projects the user's net return over one year from a list of legs. Pure: no reads.
57
+ *
58
+ * netIncome1y = sum(earning valueUsd * rate) - sum(cost valueUsd * rate)
59
+ * onDebt = netIncome1y / total debt
60
+ * onNetCapital = netIncome1y / (collateral + capital legs + idle - total debt)
61
+ *
62
+ * The legs do not reinvest into each other, so this is a projected net return, not an APY.
63
+ *
64
+ * @param input - The legs, the collateral value and any idle capital, all in USD.
65
+ * @returns The net income, both returns and each leg with its own projected income.
66
+ */
67
+ export declare function computeEffectiveReturn({ legs, collateralUsd, idleUsd }: EffectiveReturnInput): EffectiveReturn;
@@ -0,0 +1,55 @@
1
+ import { Provider } from "ethers";
2
+ import { ChainId } from "../configs/chains";
3
+ import { GaugeSystemId } from "../configs/chains/chain";
4
+ import { TokenAmount } from "../utils/amount";
5
+ export interface ClaimableToken {
6
+ /** Token address. */
7
+ token: string;
8
+ amount: TokenAmount;
9
+ }
10
+ export interface ClaimableSource {
11
+ /** False when the source is not deployed on this chain. Nothing to show. */
12
+ available: boolean;
13
+ /** Tokens with a non-zero claimable amount. */
14
+ tokens: ClaimableToken[];
15
+ /** Why the source could not be read. The UI shows it on this row, never a silent zero. */
16
+ error: Error | null;
17
+ }
18
+ export interface GaugeClaimable extends ClaimableSource {
19
+ gauge: string;
20
+ id: string;
21
+ name: string;
22
+ system: GaugeSystemId;
23
+ }
24
+ export interface GaugeClaimables extends ClaimableSource {
25
+ /** One entry per configured gauge, including those with nothing to claim or a failed read. */
26
+ items: GaugeClaimable[];
27
+ /** Number of gauges with something to claim. */
28
+ claimableCount: number;
29
+ }
30
+ export interface UserClaimables {
31
+ chainId: ChainId;
32
+ user: string;
33
+ /** Main and extra rewards on every configured gauge of both systems. Claimed gauge RAAC goes to the liquid locker. */
34
+ gauges: GaugeClaimables;
35
+ /** veRAAC fee distributions, one token per reward token. */
36
+ veRAAC: ClaimableSource;
37
+ /** Realised RAAC in the maturity vault. */
38
+ maturityVault: ClaimableSource;
39
+ /** Bot locker rewards, every reward token. */
40
+ botLocker: ClaimableSource;
41
+ }
42
+ /**
43
+ * Everything a user can claim right now, across gauges, veRAAC fees, the maturity vault and the bot locker. Amounts
44
+ * only: the caller values them in USD with its own prices. Each source (and each gauge) is read independently, so one
45
+ * failing read shows as an error on that source and every other source still returns.
46
+ *
47
+ * Every configured gauge is scanned, not only those the user is staked in: a user can still have rewards after fully
48
+ * unstaking.
49
+ *
50
+ * @param chainId - The chain/network to use.
51
+ * @param user - The user's address.
52
+ * @param provider - Optional ethers.js Provider instance.
53
+ * @returns Per source: the non-zero claimable tokens, and an `error` when it failed.
54
+ */
55
+ export declare const getUserClaimables: (chainId: ChainId, user: string, provider?: Provider) => Promise<UserClaimables>;
@@ -0,0 +1,12 @@
1
+ import { Provider } from "ethers";
2
+ import { ChainId } from "../configs/chains";
3
+ import { TokenAmount } from "../utils/amount";
4
+ /**
5
+ * The iREET a user has deposited as collateral in the lending pool's iREET adapter. NFT collateral is not included.
6
+ *
7
+ * @param chainId - The chain/network to use.
8
+ * @param user - The user's address.
9
+ * @param provider - Optional ethers.js Provider instance.
10
+ * @returns The deposited iREET, with its registry decimals and symbol.
11
+ */
12
+ export declare const getUserCollateral: (chainId: ChainId, user: string, provider?: Provider) => Promise<TokenAmount>;
@@ -0,0 +1,18 @@
1
+ import { Provider } from "ethers";
2
+ import { ChainId } from "../configs/chains";
3
+ import { ScaledValue, TokenAmount } from "../utils/amount";
4
+ export interface UserDebt {
5
+ /** Current debt including accrued interest, in reserve units (pmUSD). */
6
+ amount: TokenAmount;
7
+ /** WAD health factor (liquidatable below 1e18); null when there is no debt. */
8
+ healthFactor: ScaledValue | null;
9
+ }
10
+ /**
11
+ * The debt and health factor of a user's iREET position in the lending pool.
12
+ *
13
+ * @param chainId - The chain/network to use.
14
+ * @param user - The user's address.
15
+ * @param provider - Optional ethers.js Provider instance.
16
+ * @returns The debt, and the health factor when there is debt.
17
+ */
18
+ export declare const getUserDebt: (chainId: ChainId, user: string, provider?: Provider) => Promise<UserDebt>;
@@ -0,0 +1,64 @@
1
+ import { Provider } from "ethers";
2
+ import { ChainId } from "../configs/chains";
3
+ import { TokenAmount } from "../utils/amount";
4
+ import { UsdPrices } from "./_helpers";
5
+ /** What a coin earns on its own while it sits in a pool. */
6
+ export type UnderlyingYield =
7
+ /** Earns the lending pool supply rate (RpmUSD, DEpmUSD), wherever it sits. */
8
+ "supply"
9
+ /** Earns nothing on its own (pmUSD, RAAC; iREET for now, with fixed pricing). Counts only as capital. */
10
+ | "none";
11
+ export interface FarmingPoolCoin {
12
+ asset: string;
13
+ /** The user's share of the pool's balance of this coin, through LP in the wallet and staked in gauges. */
14
+ amount: TokenAmount;
15
+ valueUsd: number;
16
+ yield: UnderlyingYield;
17
+ }
18
+ export interface FarmingPool {
19
+ /** Curve pool id in the chain config. */
20
+ pool: string;
21
+ address: string;
22
+ /** LP held in the wallet. */
23
+ walletLp: TokenAmount;
24
+ /** LP staked in the pool's gauges. */
25
+ stakedLp: TokenAmount;
26
+ /** The user's share of each coin; empty when the user holds none of the pool's LP. */
27
+ coins: FarmingPoolCoin[];
28
+ }
29
+ export interface FarmingGauge {
30
+ /** Gauge id in the chain config. */
31
+ id: string;
32
+ gauge: string;
33
+ name: string;
34
+ pool: string;
35
+ /** LP staked (raw balance, not boosted). */
36
+ staked: TokenAmount;
37
+ /** Staked LP valued through the pool's coins at the passed prices. */
38
+ valueUsd: number;
39
+ /** The user's current boosted reward APR as a fraction; null with no stake. */
40
+ apr: number | null;
41
+ }
42
+ export interface UserFarming {
43
+ pools: FarmingPool[];
44
+ /** Every gauge on a read pool, including those the user has no stake in. */
45
+ gauges: FarmingGauge[];
46
+ /** Pools that could not be read. They and their gauges are left out of `pools` and `gauges`. */
47
+ errors: {
48
+ pool: string;
49
+ error: Error;
50
+ }[];
51
+ }
52
+ /**
53
+ * A user's Curve LP and gauge positions: every configured Curve pool that a configured gauge stakes, the user's share
54
+ * of each pool's coins, and their stake and boosted APR in each gauge. Each pool is read independently, so one failing
55
+ * pool shows in `errors` and the rest still return. Reserves, prices and APRs are only read for pools the user holds.
56
+ *
57
+ * @param chainId - The chain/network to use.
58
+ * @param user - The user's address.
59
+ * @param prices - USD per whole token, keyed by lowercase symbol. Needs every coin of a pool the user holds, and the
60
+ * reward tokens of a gauge the user is staked in.
61
+ * @param provider - Optional ethers.js Provider instance.
62
+ * @returns The pools and gauges read, and the pools that failed.
63
+ */
64
+ export declare const getUserFarming: (chainId: ChainId, user: string, prices: UsdPrices, provider?: Provider) => Promise<UserFarming>;