@parallel-protocol/cli 0.1.1 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +7 -0
- package/dist/index.js +321 -10
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -111,6 +111,7 @@ All optional — they override the config file when set.
|
|
|
111
111
|
| `PARALLEL_PRIVATE_KEY` | Raw private key (hex, `0x` prefix) — alternative to keystore, useful for scripts and CI |
|
|
112
112
|
| `PARALLEL_DEFAULT_CHAIN` | Default chain — overrides `network.default_chain` in config |
|
|
113
113
|
| `PARALLEL_JSON` | Set to `true` to force JSON output on all commands |
|
|
114
|
+
| `PARALLEL_API_URL` | Parallel API base URL for `--history` commands (default: `https://api.parallel.best`) |
|
|
114
115
|
|
|
115
116
|
|
|
116
117
|
---
|
|
@@ -157,6 +158,12 @@ parallel protocol exchange-rate [--chain <chain>] # sUSDp /
|
|
|
157
158
|
parallel protocol solvency [--chain <chain>] # Backing ratio per chain
|
|
158
159
|
parallel protocol surplus [--chain <chain>] # Pending surplus (USDp)
|
|
159
160
|
parallel protocol flashloan [--chain <chain>] # Flash loan capacity + fee rate
|
|
161
|
+
|
|
162
|
+
# Historical data (daily series) — flags: [--from <YYYY-MM-DD>] [--to <YYYY-MM-DD>] [--chain <chain>]
|
|
163
|
+
parallel protocol backing --history # reserves over time, per chain (source: Parallel API)
|
|
164
|
+
parallel protocol tvl --history # TVL over time (source: DeFiLlama)
|
|
165
|
+
parallel protocol savings-rate --history # sUSDp APY over time (source: DeFiLlama)
|
|
166
|
+
parallel protocol supply --history usdp # USDp circulating supply over time (source: DeFiLlama)
|
|
160
167
|
```
|
|
161
168
|
|
|
162
169
|
---
|
package/dist/index.js
CHANGED
|
@@ -4751,6 +4751,7 @@ async function buildBridgeTx(fromChain, toChain, amount, sender, recipient) {
|
|
|
4751
4751
|
var CONFIG_DIR = join(homedir(), ".parallel");
|
|
4752
4752
|
var CONFIG_PATH = join(CONFIG_DIR, "config.toml");
|
|
4753
4753
|
var PROD_FACILITATOR_URL = "https://agents.parallel.best";
|
|
4754
|
+
var PROD_API_URL = "https://api.parallel.best";
|
|
4754
4755
|
var _cache = null;
|
|
4755
4756
|
function loadConfig() {
|
|
4756
4757
|
if (_cache) return _cache;
|
|
@@ -4778,6 +4779,9 @@ function getDefaultChain() {
|
|
|
4778
4779
|
function getFacilitatorUrl() {
|
|
4779
4780
|
return process.env.FACILITATOR_URL ?? loadConfig().facilitator?.url ?? PROD_FACILITATOR_URL;
|
|
4780
4781
|
}
|
|
4782
|
+
function getApiUrl() {
|
|
4783
|
+
return process.env.PARALLEL_API_URL ?? process.env.SUPPLY_API_URL ?? loadConfig().api?.url ?? PROD_API_URL;
|
|
4784
|
+
}
|
|
4781
4785
|
function getKeystorePath() {
|
|
4782
4786
|
return loadConfig().wallet?.keystore_path;
|
|
4783
4787
|
}
|
|
@@ -10119,7 +10123,183 @@ async function getSupply(token, chain) {
|
|
|
10119
10123
|
});
|
|
10120
10124
|
}
|
|
10121
10125
|
|
|
10126
|
+
// src/providers/api.ts
|
|
10127
|
+
async function get2(path) {
|
|
10128
|
+
const base3 = getApiUrl();
|
|
10129
|
+
let res;
|
|
10130
|
+
try {
|
|
10131
|
+
res = await fetch(`${base3}${path}`);
|
|
10132
|
+
} catch (_err) {
|
|
10133
|
+
throw new CliError(
|
|
10134
|
+
ErrorCode.RPC_ERROR,
|
|
10135
|
+
`Cannot reach Parallel API at ${base3}`,
|
|
10136
|
+
"Check PARALLEL_API_URL or your network connection"
|
|
10137
|
+
);
|
|
10138
|
+
}
|
|
10139
|
+
if (!res.ok) {
|
|
10140
|
+
const text = await res.text().catch(() => res.statusText);
|
|
10141
|
+
throw new CliError(
|
|
10142
|
+
ErrorCode.UNKNOWN,
|
|
10143
|
+
`Parallel API error (${res.status}): ${text}`
|
|
10144
|
+
);
|
|
10145
|
+
}
|
|
10146
|
+
const body = await res.json();
|
|
10147
|
+
return body?.json ?? body;
|
|
10148
|
+
}
|
|
10149
|
+
function getHistoricalProtocols(from, to) {
|
|
10150
|
+
const q = new URLSearchParams();
|
|
10151
|
+
if (from) q.set("startDate", from);
|
|
10152
|
+
if (to) q.set("endDate", to);
|
|
10153
|
+
const query = q.toString();
|
|
10154
|
+
return get2(
|
|
10155
|
+
`/public/transparency/historical-protocols${query ? `?${query}` : ""}`
|
|
10156
|
+
);
|
|
10157
|
+
}
|
|
10158
|
+
function reservesByDate(points, chainId) {
|
|
10159
|
+
return points.map((point) => {
|
|
10160
|
+
const perChain = {};
|
|
10161
|
+
for (const protocol of Object.values(point.protocols)) {
|
|
10162
|
+
for (const [id, chainData] of Object.entries(protocol.chains)) {
|
|
10163
|
+
const numericId = Number(id);
|
|
10164
|
+
if (chainId !== void 0 && numericId !== chainId) continue;
|
|
10165
|
+
perChain[numericId] = (perChain[numericId] ?? 0) + Number(chainData.value);
|
|
10166
|
+
}
|
|
10167
|
+
}
|
|
10168
|
+
const total = Object.values(perChain).reduce((sum, v) => sum + v, 0);
|
|
10169
|
+
return { date: point.date, perChain, total };
|
|
10170
|
+
});
|
|
10171
|
+
}
|
|
10172
|
+
|
|
10173
|
+
// src/providers/defillama.ts
|
|
10174
|
+
var TVL_URL = "https://api.llama.fi";
|
|
10175
|
+
var YIELDS_URL = "https://yields.llama.fi";
|
|
10176
|
+
var STABLECOINS_URL = "https://stablecoins.llama.fi";
|
|
10177
|
+
var PARALLEL_SLUG = "parallel-protocol-v3";
|
|
10178
|
+
var USDP_STABLECOIN_ID = "291";
|
|
10179
|
+
var DEFILLAMA_CHAIN = {
|
|
10180
|
+
ethereum: "Ethereum",
|
|
10181
|
+
base: "Base",
|
|
10182
|
+
avalanche: "Avalanche",
|
|
10183
|
+
hyperevm: "Hyperliquid L1",
|
|
10184
|
+
sonic: "Sonic"
|
|
10185
|
+
};
|
|
10186
|
+
var STABLECOIN_CHAIN = {
|
|
10187
|
+
ethereum: "Ethereum",
|
|
10188
|
+
base: "Base",
|
|
10189
|
+
arbitrum: "Arbitrum",
|
|
10190
|
+
optimism: "OP Mainnet",
|
|
10191
|
+
polygon: "Polygon",
|
|
10192
|
+
avalanche: "Avalanche",
|
|
10193
|
+
bsc: "BSC",
|
|
10194
|
+
scroll: "Scroll",
|
|
10195
|
+
gnosis: "Gnosis",
|
|
10196
|
+
sei: "Sei",
|
|
10197
|
+
berachain: "Berachain",
|
|
10198
|
+
hyperevm: "Hyperliquid L1",
|
|
10199
|
+
unichain: "Unichain",
|
|
10200
|
+
ink: "Ink",
|
|
10201
|
+
tac: "TAC",
|
|
10202
|
+
linea: "Linea",
|
|
10203
|
+
xlayer: "X Layer",
|
|
10204
|
+
fraxtal: "Fraxtal",
|
|
10205
|
+
worldchain: "World Chain",
|
|
10206
|
+
hemi: "Hemi",
|
|
10207
|
+
plume: "Plume Mainnet",
|
|
10208
|
+
plasma: "Plasma",
|
|
10209
|
+
katana: "Katana"
|
|
10210
|
+
};
|
|
10211
|
+
var SAVINGS_POOL_ID = {
|
|
10212
|
+
ethereum: "f65159b4-7bec-40c8-8f31-1fa2f5408738",
|
|
10213
|
+
base: "f65159b4-7bec-40c8-8f31-1fa2f5408738",
|
|
10214
|
+
avalanche: "f65159b4-7bec-40c8-8f31-1fa2f5408738",
|
|
10215
|
+
hyperevm: "086da6ff-2302-4a9e-8cd8-1599e67c655d"
|
|
10216
|
+
};
|
|
10217
|
+
var DEFAULT_SAVINGS_POOL_ID = SAVINGS_POOL_ID.ethereum;
|
|
10218
|
+
async function get3(url) {
|
|
10219
|
+
let res;
|
|
10220
|
+
try {
|
|
10221
|
+
res = await fetch(url);
|
|
10222
|
+
} catch (_err) {
|
|
10223
|
+
throw new CliError(
|
|
10224
|
+
ErrorCode.RPC_ERROR,
|
|
10225
|
+
"Cannot reach DeFiLlama",
|
|
10226
|
+
"Check your network connection"
|
|
10227
|
+
);
|
|
10228
|
+
}
|
|
10229
|
+
if (!res.ok) {
|
|
10230
|
+
throw new CliError(ErrorCode.UNKNOWN, `DeFiLlama error (${res.status})`);
|
|
10231
|
+
}
|
|
10232
|
+
return res.json();
|
|
10233
|
+
}
|
|
10234
|
+
function collapseByDay(points) {
|
|
10235
|
+
const byDay = /* @__PURE__ */ new Map();
|
|
10236
|
+
for (const p of points) byDay.set(p.date, p.value);
|
|
10237
|
+
return [...byDay].map(([date, value]) => ({ date, value }));
|
|
10238
|
+
}
|
|
10239
|
+
function unknownChain(chain, supported) {
|
|
10240
|
+
return new CliError(
|
|
10241
|
+
ErrorCode.UNKNOWN_CHAIN,
|
|
10242
|
+
`No DeFiLlama history for chain "${chain}"`,
|
|
10243
|
+
`Supported chains: ${supported.join(", ")}`
|
|
10244
|
+
);
|
|
10245
|
+
}
|
|
10246
|
+
async function getTvlHistory(chain) {
|
|
10247
|
+
let chainName;
|
|
10248
|
+
if (chain) {
|
|
10249
|
+
chainName = DEFILLAMA_CHAIN[chain];
|
|
10250
|
+
if (!chainName) throw unknownChain(chain, Object.keys(DEFILLAMA_CHAIN));
|
|
10251
|
+
}
|
|
10252
|
+
const data = await get3(
|
|
10253
|
+
`${TVL_URL}/protocol/${PARALLEL_SLUG}`
|
|
10254
|
+
);
|
|
10255
|
+
const raw = (chainName ? data.chainTvls?.[chainName]?.tvl : data.tvl) ?? [];
|
|
10256
|
+
return collapseByDay(
|
|
10257
|
+
raw.map((p) => ({
|
|
10258
|
+
date: new Date(p.date * 1e3).toISOString().slice(0, 10),
|
|
10259
|
+
value: p.totalLiquidityUSD
|
|
10260
|
+
}))
|
|
10261
|
+
).map(({ date, value }) => ({ date, tvl: value }));
|
|
10262
|
+
}
|
|
10263
|
+
async function getSavingsApyHistory(chain) {
|
|
10264
|
+
let poolId = DEFAULT_SAVINGS_POOL_ID;
|
|
10265
|
+
if (chain) {
|
|
10266
|
+
const id = SAVINGS_POOL_ID[chain];
|
|
10267
|
+
if (!id) throw unknownChain(chain, Object.keys(SAVINGS_POOL_ID));
|
|
10268
|
+
poolId = id;
|
|
10269
|
+
}
|
|
10270
|
+
const data = await get3(`${YIELDS_URL}/chart/${poolId}`);
|
|
10271
|
+
return collapseByDay(
|
|
10272
|
+
(data.data ?? []).map((p) => ({
|
|
10273
|
+
date: p.timestamp.slice(0, 10),
|
|
10274
|
+
value: p.apy
|
|
10275
|
+
}))
|
|
10276
|
+
).map(({ date, value }) => ({ date, apy: value }));
|
|
10277
|
+
}
|
|
10278
|
+
async function getUsdpSupplyHistory(chain) {
|
|
10279
|
+
let chainName;
|
|
10280
|
+
if (chain) {
|
|
10281
|
+
chainName = STABLECOIN_CHAIN[chain];
|
|
10282
|
+
if (!chainName) throw unknownChain(chain, Object.keys(STABLECOIN_CHAIN));
|
|
10283
|
+
}
|
|
10284
|
+
const data = await get3(
|
|
10285
|
+
`${STABLECOINS_URL}/stablecoin/${USDP_STABLECOIN_ID}`
|
|
10286
|
+
);
|
|
10287
|
+
const raw = (chainName ? data.chainBalances?.[chainName]?.tokens : data.tokens) ?? [];
|
|
10288
|
+
return collapseByDay(
|
|
10289
|
+
raw.map((p) => ({
|
|
10290
|
+
date: new Date(p.date * 1e3).toISOString().slice(0, 10),
|
|
10291
|
+
value: p.circulating?.peggedUSD ?? 0
|
|
10292
|
+
}))
|
|
10293
|
+
).map(({ date, value }) => ({ date, supply: value }));
|
|
10294
|
+
}
|
|
10295
|
+
|
|
10122
10296
|
// src/utils/chains.ts
|
|
10297
|
+
var CHAIN_NAME_BY_ID = new Map(
|
|
10298
|
+
Object.values(CHAINS).map((cfg) => [cfg.id, cfg.name])
|
|
10299
|
+
);
|
|
10300
|
+
function chainNameById(id) {
|
|
10301
|
+
return CHAIN_NAME_BY_ID.get(id) ?? `chain:${id}`;
|
|
10302
|
+
}
|
|
10123
10303
|
function assertParallelizerChain(chain) {
|
|
10124
10304
|
const cfg = CHAINS[chain];
|
|
10125
10305
|
if (cfg?.status === "sunset")
|
|
@@ -10260,8 +10440,13 @@ function overviewCmd() {
|
|
|
10260
10440
|
});
|
|
10261
10441
|
}
|
|
10262
10442
|
function supplyCmd() {
|
|
10263
|
-
return new Command("supply").description("Token supply: usdp | susdp | prl | sprl1 | sprl2").argument("<token>", "token symbol").option("-c, --chain <chain>", "filter to a single chain").action(async function(token) {
|
|
10264
|
-
const
|
|
10443
|
+
return new Command("supply").description("Token supply: usdp | susdp | prl | sprl1 | sprl2").argument("<token>", "token symbol").option("-c, --chain <chain>", "filter to a single chain").option("--history", "supply over time \u2014 usdp only (source: DeFiLlama)").option("--from <date>", "history start date (YYYY-MM-DD)").option("--to <date>", "history end date (YYYY-MM-DD)").action(async function(token) {
|
|
10444
|
+
const opts = resolveOpts(this);
|
|
10445
|
+
if (opts.history) {
|
|
10446
|
+
await renderSupplyHistory(token, opts);
|
|
10447
|
+
return;
|
|
10448
|
+
}
|
|
10449
|
+
const { chain } = opts;
|
|
10265
10450
|
try {
|
|
10266
10451
|
const result = await getSupply(
|
|
10267
10452
|
token,
|
|
@@ -10284,11 +10469,85 @@ function supplyCmd() {
|
|
|
10284
10469
|
}
|
|
10285
10470
|
});
|
|
10286
10471
|
}
|
|
10472
|
+
function fmtDelta(delta, fmt2) {
|
|
10473
|
+
if (delta === void 0) return chalk5.dim("\u2014");
|
|
10474
|
+
return delta >= 0 ? chalk5.green(`+${fmt2(delta)}`) : chalk5.red(`\u2212${fmt2(-delta)}`);
|
|
10475
|
+
}
|
|
10476
|
+
function fmtApy(value) {
|
|
10477
|
+
return `${value.toFixed(2)}%`;
|
|
10478
|
+
}
|
|
10479
|
+
function renderHistory(series, opts, cfg) {
|
|
10480
|
+
const { from, to } = opts;
|
|
10481
|
+
let rows = series;
|
|
10482
|
+
if (from) rows = rows.filter((p) => p.date >= from);
|
|
10483
|
+
if (to) rows = rows.filter((p) => p.date <= to);
|
|
10484
|
+
rows = rows.slice().sort((a, b) => b.date.localeCompare(a.date));
|
|
10485
|
+
output({ interval: "day", source: cfg.source, series: rows }, () => {
|
|
10486
|
+
const table = rows.map((row, i) => {
|
|
10487
|
+
const prev = rows[i + 1];
|
|
10488
|
+
const delta = prev ? cfg.valueOf(row) - cfg.valueOf(prev) : void 0;
|
|
10489
|
+
return [row.date, cfg.fmt(cfg.valueOf(row)), fmtDelta(delta, cfg.fmt)];
|
|
10490
|
+
});
|
|
10491
|
+
printTable(cfg.title, ["Date", cfg.valueHeader, "\u0394 vs prev"], table);
|
|
10492
|
+
});
|
|
10493
|
+
}
|
|
10494
|
+
async function renderTvlHistory(opts) {
|
|
10495
|
+
try {
|
|
10496
|
+
const series = await getTvlHistory(opts.chain);
|
|
10497
|
+
renderHistory(series, opts, {
|
|
10498
|
+
valueOf: (r) => r.tvl,
|
|
10499
|
+
fmt: fmtUsd,
|
|
10500
|
+
title: "TVL Over Time \u2014 Daily (source: DeFiLlama)",
|
|
10501
|
+
valueHeader: "TVL",
|
|
10502
|
+
source: "defillama"
|
|
10503
|
+
});
|
|
10504
|
+
} catch (err) {
|
|
10505
|
+
formatCliError(err);
|
|
10506
|
+
}
|
|
10507
|
+
}
|
|
10508
|
+
async function renderSavingsRateHistory(opts) {
|
|
10509
|
+
try {
|
|
10510
|
+
const series = await getSavingsApyHistory(opts.chain);
|
|
10511
|
+
renderHistory(series, opts, {
|
|
10512
|
+
valueOf: (r) => r.apy,
|
|
10513
|
+
fmt: fmtApy,
|
|
10514
|
+
title: "sUSDp APY Over Time \u2014 Daily (source: DeFiLlama)",
|
|
10515
|
+
valueHeader: "APY",
|
|
10516
|
+
source: "defillama"
|
|
10517
|
+
});
|
|
10518
|
+
} catch (err) {
|
|
10519
|
+
formatCliError(err);
|
|
10520
|
+
}
|
|
10521
|
+
}
|
|
10522
|
+
async function renderSupplyHistory(token, opts) {
|
|
10523
|
+
try {
|
|
10524
|
+
if (token.toLowerCase() !== "usdp")
|
|
10525
|
+
throw new CliError(
|
|
10526
|
+
ErrorCode.UNKNOWN,
|
|
10527
|
+
`supply --history is only available for usdp (got "${token}")`,
|
|
10528
|
+
"Only USDp has a public historical supply source"
|
|
10529
|
+
);
|
|
10530
|
+
const series = await getUsdpSupplyHistory(opts.chain);
|
|
10531
|
+
renderHistory(series, opts, {
|
|
10532
|
+
valueOf: (r) => r.supply,
|
|
10533
|
+
fmt: fmtNum,
|
|
10534
|
+
title: "USDp Supply Over Time \u2014 Daily (source: DeFiLlama)",
|
|
10535
|
+
valueHeader: "Supply (USDp)",
|
|
10536
|
+
source: "defillama"
|
|
10537
|
+
});
|
|
10538
|
+
} catch (err) {
|
|
10539
|
+
formatCliError(err);
|
|
10540
|
+
}
|
|
10541
|
+
}
|
|
10287
10542
|
function tvlCmd() {
|
|
10288
|
-
return new Command("tvl").description("Total Value Locked across all Parallelizer chains").option("-c, --chain <chain>", "filter to a single chain").action(async function() {
|
|
10289
|
-
const
|
|
10543
|
+
return new Command("tvl").description("Total Value Locked across all Parallelizer chains").option("-c, --chain <chain>", "filter to a single chain").option("--history", "TVL over time (source: DeFiLlama)").option("--from <date>", "history start date (YYYY-MM-DD)").option("--to <date>", "history end date (YYYY-MM-DD)").action(async function() {
|
|
10544
|
+
const opts = resolveOpts(this);
|
|
10545
|
+
if (opts.history) {
|
|
10546
|
+
await renderTvlHistory(opts);
|
|
10547
|
+
return;
|
|
10548
|
+
}
|
|
10290
10549
|
try {
|
|
10291
|
-
const result = await getTvl(chain);
|
|
10550
|
+
const result = await getTvl(opts.chain);
|
|
10292
10551
|
output(result, () => {
|
|
10293
10552
|
printKeyValue("TVL", [["Total TVL", fmtUsd(result.totalTVL)]]);
|
|
10294
10553
|
const rows = result.breakdown.map((b) => [b.chain, fmtUsd(b.tvl)]);
|
|
@@ -10299,9 +10558,56 @@ function tvlCmd() {
|
|
|
10299
10558
|
}
|
|
10300
10559
|
});
|
|
10301
10560
|
}
|
|
10561
|
+
function orderedChainIds(series, latest) {
|
|
10562
|
+
const ids = /* @__PURE__ */ new Set();
|
|
10563
|
+
for (const row of series) {
|
|
10564
|
+
for (const id of Object.keys(row.perChain)) ids.add(Number(id));
|
|
10565
|
+
}
|
|
10566
|
+
return [...ids].sort((a, b) => (latest[b] ?? 0) - (latest[a] ?? 0));
|
|
10567
|
+
}
|
|
10568
|
+
async function renderBackingHistory(opts) {
|
|
10569
|
+
try {
|
|
10570
|
+
let chainId;
|
|
10571
|
+
if (opts.chain) {
|
|
10572
|
+
const cfg = CHAINS[opts.chain];
|
|
10573
|
+
if (!cfg)
|
|
10574
|
+
throw new CliError(
|
|
10575
|
+
ErrorCode.UNKNOWN_CHAIN,
|
|
10576
|
+
`Unknown chain "${opts.chain}"`,
|
|
10577
|
+
"Run: parallel protocol chains to see supported chains"
|
|
10578
|
+
);
|
|
10579
|
+
chainId = cfg.id;
|
|
10580
|
+
}
|
|
10581
|
+
const points = await getHistoricalProtocols(opts.from, opts.to);
|
|
10582
|
+
const series = reservesByDate(points, chainId).sort((a, b) => b.date.localeCompare(a.date));
|
|
10583
|
+
const chainIds = orderedChainIds(series, series[0]?.perChain ?? {});
|
|
10584
|
+
output({ interval: "day", series }, () => {
|
|
10585
|
+
const headers = [
|
|
10586
|
+
"Date",
|
|
10587
|
+
...chainIds.map((id) => chainNameById(id)),
|
|
10588
|
+
"Total"
|
|
10589
|
+
];
|
|
10590
|
+
const rows = series.map((row) => [
|
|
10591
|
+
row.date.slice(0, 10),
|
|
10592
|
+
...chainIds.map(
|
|
10593
|
+
(id) => row.perChain[id] ? fmtUsd(row.perChain[id]) : chalk5.dim("\u2212")
|
|
10594
|
+
),
|
|
10595
|
+
fmtUsd(row.total)
|
|
10596
|
+
]);
|
|
10597
|
+
printTable("Backing History (reserves over time) \u2014 Daily", headers, rows);
|
|
10598
|
+
});
|
|
10599
|
+
} catch (err) {
|
|
10600
|
+
formatCliError(err);
|
|
10601
|
+
}
|
|
10602
|
+
}
|
|
10302
10603
|
function backingCmd() {
|
|
10303
|
-
return new Command("backing").description("Collateral backing composition per chain").option("-c, --chain <chain>", "filter to a single chain").action(async function() {
|
|
10304
|
-
const
|
|
10604
|
+
return new Command("backing").description("Collateral backing composition per chain").option("-c, --chain <chain>", "filter to a single chain").option("--history", "reserves (backing) over time, per chain").option("--from <date>", "history start date (YYYY-MM-DD)").option("--to <date>", "history end date (YYYY-MM-DD)").action(async function() {
|
|
10605
|
+
const opts = resolveOpts(this);
|
|
10606
|
+
if (opts.history) {
|
|
10607
|
+
await renderBackingHistory(opts);
|
|
10608
|
+
return;
|
|
10609
|
+
}
|
|
10610
|
+
const { chain } = opts;
|
|
10305
10611
|
try {
|
|
10306
10612
|
const [result, usdpSupply, solvency] = await Promise.all([
|
|
10307
10613
|
getTvl(chain),
|
|
@@ -10614,8 +10920,13 @@ function feesCmd2() {
|
|
|
10614
10920
|
});
|
|
10615
10921
|
}
|
|
10616
10922
|
function savingsRateCmd() {
|
|
10617
|
-
return new Command("savings-rate").description("sUSDp savings rate (APY) across all chains").option("-c, --chain <chain>", "filter to a single chain").action(async function() {
|
|
10618
|
-
const
|
|
10923
|
+
return new Command("savings-rate").description("sUSDp savings rate (APY) across all chains").option("-c, --chain <chain>", "filter to a single chain").option("--history", "APY over time (source: DeFiLlama)").option("--from <date>", "history start date (YYYY-MM-DD)").option("--to <date>", "history end date (YYYY-MM-DD)").action(async function() {
|
|
10924
|
+
const opts = resolveOpts(this);
|
|
10925
|
+
if (opts.history) {
|
|
10926
|
+
await renderSavingsRateHistory(opts);
|
|
10927
|
+
return;
|
|
10928
|
+
}
|
|
10929
|
+
const { chain } = opts;
|
|
10619
10930
|
try {
|
|
10620
10931
|
if (chain) assertParallelizerChain(chain);
|
|
10621
10932
|
const result = await getSavingsRate();
|
|
@@ -14230,7 +14541,7 @@ var package_default = {
|
|
|
14230
14541
|
|
|
14231
14542
|
// package.json
|
|
14232
14543
|
var package_default2 = {
|
|
14233
|
-
version: "0.
|
|
14544
|
+
version: "0.2.0"};
|
|
14234
14545
|
|
|
14235
14546
|
// src/commands/version.ts
|
|
14236
14547
|
function versionCommand() {
|