@parallel-protocol/cli 0.1.1 → 0.2.1
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 +346 -16
- 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
|
}
|
|
@@ -8075,15 +8079,34 @@ function slippageDown(amount) {
|
|
|
8075
8079
|
return amount - amount * SLIPPAGE_BPS / 10000n;
|
|
8076
8080
|
}
|
|
8077
8081
|
async function readTokenDomain(chain, token) {
|
|
8082
|
+
return readTokenDomainFull(chain, token);
|
|
8083
|
+
}
|
|
8084
|
+
async function readTokenDomainFull(chain, token) {
|
|
8078
8085
|
const client = getClient(chain);
|
|
8079
|
-
const
|
|
8080
|
-
|
|
8081
|
-
|
|
8082
|
-
|
|
8083
|
-
|
|
8086
|
+
const versionAbi = [
|
|
8087
|
+
{
|
|
8088
|
+
name: "version",
|
|
8089
|
+
type: "function",
|
|
8090
|
+
stateMutability: "view",
|
|
8091
|
+
inputs: [],
|
|
8092
|
+
outputs: [{ type: "string" }]
|
|
8093
|
+
}
|
|
8094
|
+
];
|
|
8095
|
+
const [name, version] = await Promise.all([
|
|
8096
|
+
client.readContract({
|
|
8097
|
+
address: token,
|
|
8098
|
+
abi: ERC20_ABI,
|
|
8099
|
+
functionName: "name"
|
|
8100
|
+
}),
|
|
8101
|
+
client.readContract({
|
|
8102
|
+
address: token,
|
|
8103
|
+
abi: versionAbi,
|
|
8104
|
+
functionName: "version"
|
|
8105
|
+
}).catch(() => "1")
|
|
8106
|
+
]);
|
|
8084
8107
|
return {
|
|
8085
8108
|
name,
|
|
8086
|
-
version
|
|
8109
|
+
version,
|
|
8087
8110
|
chainId: client.chain.id,
|
|
8088
8111
|
verifyingContract: token
|
|
8089
8112
|
};
|
|
@@ -10119,7 +10142,183 @@ async function getSupply(token, chain) {
|
|
|
10119
10142
|
});
|
|
10120
10143
|
}
|
|
10121
10144
|
|
|
10145
|
+
// src/providers/api.ts
|
|
10146
|
+
async function get2(path) {
|
|
10147
|
+
const base3 = getApiUrl();
|
|
10148
|
+
let res;
|
|
10149
|
+
try {
|
|
10150
|
+
res = await fetch(`${base3}${path}`);
|
|
10151
|
+
} catch (_err) {
|
|
10152
|
+
throw new CliError(
|
|
10153
|
+
ErrorCode.RPC_ERROR,
|
|
10154
|
+
`Cannot reach Parallel API at ${base3}`,
|
|
10155
|
+
"Check PARALLEL_API_URL or your network connection"
|
|
10156
|
+
);
|
|
10157
|
+
}
|
|
10158
|
+
if (!res.ok) {
|
|
10159
|
+
const text = await res.text().catch(() => res.statusText);
|
|
10160
|
+
throw new CliError(
|
|
10161
|
+
ErrorCode.UNKNOWN,
|
|
10162
|
+
`Parallel API error (${res.status}): ${text}`
|
|
10163
|
+
);
|
|
10164
|
+
}
|
|
10165
|
+
const body = await res.json();
|
|
10166
|
+
return body?.json ?? body;
|
|
10167
|
+
}
|
|
10168
|
+
function getHistoricalProtocols(from, to) {
|
|
10169
|
+
const q = new URLSearchParams();
|
|
10170
|
+
if (from) q.set("startDate", from);
|
|
10171
|
+
if (to) q.set("endDate", to);
|
|
10172
|
+
const query = q.toString();
|
|
10173
|
+
return get2(
|
|
10174
|
+
`/public/transparency/historical-protocols${query ? `?${query}` : ""}`
|
|
10175
|
+
);
|
|
10176
|
+
}
|
|
10177
|
+
function reservesByDate(points, chainId) {
|
|
10178
|
+
return points.map((point) => {
|
|
10179
|
+
const perChain = {};
|
|
10180
|
+
for (const protocol of Object.values(point.protocols)) {
|
|
10181
|
+
for (const [id, chainData] of Object.entries(protocol.chains)) {
|
|
10182
|
+
const numericId = Number(id);
|
|
10183
|
+
if (chainId !== void 0 && numericId !== chainId) continue;
|
|
10184
|
+
perChain[numericId] = (perChain[numericId] ?? 0) + Number(chainData.value);
|
|
10185
|
+
}
|
|
10186
|
+
}
|
|
10187
|
+
const total = Object.values(perChain).reduce((sum, v) => sum + v, 0);
|
|
10188
|
+
return { date: point.date, perChain, total };
|
|
10189
|
+
});
|
|
10190
|
+
}
|
|
10191
|
+
|
|
10192
|
+
// src/providers/defillama.ts
|
|
10193
|
+
var TVL_URL = "https://api.llama.fi";
|
|
10194
|
+
var YIELDS_URL = "https://yields.llama.fi";
|
|
10195
|
+
var STABLECOINS_URL = "https://stablecoins.llama.fi";
|
|
10196
|
+
var PARALLEL_SLUG = "parallel-protocol-v3";
|
|
10197
|
+
var USDP_STABLECOIN_ID = "291";
|
|
10198
|
+
var DEFILLAMA_CHAIN = {
|
|
10199
|
+
ethereum: "Ethereum",
|
|
10200
|
+
base: "Base",
|
|
10201
|
+
avalanche: "Avalanche",
|
|
10202
|
+
hyperevm: "Hyperliquid L1",
|
|
10203
|
+
sonic: "Sonic"
|
|
10204
|
+
};
|
|
10205
|
+
var STABLECOIN_CHAIN = {
|
|
10206
|
+
ethereum: "Ethereum",
|
|
10207
|
+
base: "Base",
|
|
10208
|
+
arbitrum: "Arbitrum",
|
|
10209
|
+
optimism: "OP Mainnet",
|
|
10210
|
+
polygon: "Polygon",
|
|
10211
|
+
avalanche: "Avalanche",
|
|
10212
|
+
bsc: "BSC",
|
|
10213
|
+
scroll: "Scroll",
|
|
10214
|
+
gnosis: "Gnosis",
|
|
10215
|
+
sei: "Sei",
|
|
10216
|
+
berachain: "Berachain",
|
|
10217
|
+
hyperevm: "Hyperliquid L1",
|
|
10218
|
+
unichain: "Unichain",
|
|
10219
|
+
ink: "Ink",
|
|
10220
|
+
tac: "TAC",
|
|
10221
|
+
linea: "Linea",
|
|
10222
|
+
xlayer: "X Layer",
|
|
10223
|
+
fraxtal: "Fraxtal",
|
|
10224
|
+
worldchain: "World Chain",
|
|
10225
|
+
hemi: "Hemi",
|
|
10226
|
+
plume: "Plume Mainnet",
|
|
10227
|
+
plasma: "Plasma",
|
|
10228
|
+
katana: "Katana"
|
|
10229
|
+
};
|
|
10230
|
+
var SAVINGS_POOL_ID = {
|
|
10231
|
+
ethereum: "f65159b4-7bec-40c8-8f31-1fa2f5408738",
|
|
10232
|
+
base: "f65159b4-7bec-40c8-8f31-1fa2f5408738",
|
|
10233
|
+
avalanche: "f65159b4-7bec-40c8-8f31-1fa2f5408738",
|
|
10234
|
+
hyperevm: "086da6ff-2302-4a9e-8cd8-1599e67c655d"
|
|
10235
|
+
};
|
|
10236
|
+
var DEFAULT_SAVINGS_POOL_ID = SAVINGS_POOL_ID.ethereum;
|
|
10237
|
+
async function get3(url) {
|
|
10238
|
+
let res;
|
|
10239
|
+
try {
|
|
10240
|
+
res = await fetch(url);
|
|
10241
|
+
} catch (_err) {
|
|
10242
|
+
throw new CliError(
|
|
10243
|
+
ErrorCode.RPC_ERROR,
|
|
10244
|
+
"Cannot reach DeFiLlama",
|
|
10245
|
+
"Check your network connection"
|
|
10246
|
+
);
|
|
10247
|
+
}
|
|
10248
|
+
if (!res.ok) {
|
|
10249
|
+
throw new CliError(ErrorCode.UNKNOWN, `DeFiLlama error (${res.status})`);
|
|
10250
|
+
}
|
|
10251
|
+
return res.json();
|
|
10252
|
+
}
|
|
10253
|
+
function collapseByDay(points) {
|
|
10254
|
+
const byDay = /* @__PURE__ */ new Map();
|
|
10255
|
+
for (const p of points) byDay.set(p.date, p.value);
|
|
10256
|
+
return [...byDay].map(([date, value]) => ({ date, value }));
|
|
10257
|
+
}
|
|
10258
|
+
function unknownChain(chain, supported) {
|
|
10259
|
+
return new CliError(
|
|
10260
|
+
ErrorCode.UNKNOWN_CHAIN,
|
|
10261
|
+
`No DeFiLlama history for chain "${chain}"`,
|
|
10262
|
+
`Supported chains: ${supported.join(", ")}`
|
|
10263
|
+
);
|
|
10264
|
+
}
|
|
10265
|
+
async function getTvlHistory(chain) {
|
|
10266
|
+
let chainName;
|
|
10267
|
+
if (chain) {
|
|
10268
|
+
chainName = DEFILLAMA_CHAIN[chain];
|
|
10269
|
+
if (!chainName) throw unknownChain(chain, Object.keys(DEFILLAMA_CHAIN));
|
|
10270
|
+
}
|
|
10271
|
+
const data = await get3(
|
|
10272
|
+
`${TVL_URL}/protocol/${PARALLEL_SLUG}`
|
|
10273
|
+
);
|
|
10274
|
+
const raw = (chainName ? data.chainTvls?.[chainName]?.tvl : data.tvl) ?? [];
|
|
10275
|
+
return collapseByDay(
|
|
10276
|
+
raw.map((p) => ({
|
|
10277
|
+
date: new Date(p.date * 1e3).toISOString().slice(0, 10),
|
|
10278
|
+
value: p.totalLiquidityUSD
|
|
10279
|
+
}))
|
|
10280
|
+
).map(({ date, value }) => ({ date, tvl: value }));
|
|
10281
|
+
}
|
|
10282
|
+
async function getSavingsApyHistory(chain) {
|
|
10283
|
+
let poolId = DEFAULT_SAVINGS_POOL_ID;
|
|
10284
|
+
if (chain) {
|
|
10285
|
+
const id = SAVINGS_POOL_ID[chain];
|
|
10286
|
+
if (!id) throw unknownChain(chain, Object.keys(SAVINGS_POOL_ID));
|
|
10287
|
+
poolId = id;
|
|
10288
|
+
}
|
|
10289
|
+
const data = await get3(`${YIELDS_URL}/chart/${poolId}`);
|
|
10290
|
+
return collapseByDay(
|
|
10291
|
+
(data.data ?? []).map((p) => ({
|
|
10292
|
+
date: p.timestamp.slice(0, 10),
|
|
10293
|
+
value: p.apy
|
|
10294
|
+
}))
|
|
10295
|
+
).map(({ date, value }) => ({ date, apy: value }));
|
|
10296
|
+
}
|
|
10297
|
+
async function getUsdpSupplyHistory(chain) {
|
|
10298
|
+
let chainName;
|
|
10299
|
+
if (chain) {
|
|
10300
|
+
chainName = STABLECOIN_CHAIN[chain];
|
|
10301
|
+
if (!chainName) throw unknownChain(chain, Object.keys(STABLECOIN_CHAIN));
|
|
10302
|
+
}
|
|
10303
|
+
const data = await get3(
|
|
10304
|
+
`${STABLECOINS_URL}/stablecoin/${USDP_STABLECOIN_ID}`
|
|
10305
|
+
);
|
|
10306
|
+
const raw = (chainName ? data.chainBalances?.[chainName]?.tokens : data.tokens) ?? [];
|
|
10307
|
+
return collapseByDay(
|
|
10308
|
+
raw.map((p) => ({
|
|
10309
|
+
date: new Date(p.date * 1e3).toISOString().slice(0, 10),
|
|
10310
|
+
value: p.circulating?.peggedUSD ?? 0
|
|
10311
|
+
}))
|
|
10312
|
+
).map(({ date, value }) => ({ date, supply: value }));
|
|
10313
|
+
}
|
|
10314
|
+
|
|
10122
10315
|
// src/utils/chains.ts
|
|
10316
|
+
var CHAIN_NAME_BY_ID = new Map(
|
|
10317
|
+
Object.values(CHAINS).map((cfg) => [cfg.id, cfg.name])
|
|
10318
|
+
);
|
|
10319
|
+
function chainNameById(id) {
|
|
10320
|
+
return CHAIN_NAME_BY_ID.get(id) ?? `chain:${id}`;
|
|
10321
|
+
}
|
|
10123
10322
|
function assertParallelizerChain(chain) {
|
|
10124
10323
|
const cfg = CHAINS[chain];
|
|
10125
10324
|
if (cfg?.status === "sunset")
|
|
@@ -10260,8 +10459,13 @@ function overviewCmd() {
|
|
|
10260
10459
|
});
|
|
10261
10460
|
}
|
|
10262
10461
|
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
|
|
10462
|
+
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) {
|
|
10463
|
+
const opts = resolveOpts(this);
|
|
10464
|
+
if (opts.history) {
|
|
10465
|
+
await renderSupplyHistory(token, opts);
|
|
10466
|
+
return;
|
|
10467
|
+
}
|
|
10468
|
+
const { chain } = opts;
|
|
10265
10469
|
try {
|
|
10266
10470
|
const result = await getSupply(
|
|
10267
10471
|
token,
|
|
@@ -10284,11 +10488,85 @@ function supplyCmd() {
|
|
|
10284
10488
|
}
|
|
10285
10489
|
});
|
|
10286
10490
|
}
|
|
10491
|
+
function fmtDelta(delta, fmt2) {
|
|
10492
|
+
if (delta === void 0) return chalk5.dim("\u2014");
|
|
10493
|
+
return delta >= 0 ? chalk5.green(`+${fmt2(delta)}`) : chalk5.red(`\u2212${fmt2(-delta)}`);
|
|
10494
|
+
}
|
|
10495
|
+
function fmtApy(value) {
|
|
10496
|
+
return `${value.toFixed(2)}%`;
|
|
10497
|
+
}
|
|
10498
|
+
function renderHistory(series, opts, cfg) {
|
|
10499
|
+
const { from, to } = opts;
|
|
10500
|
+
let rows = series;
|
|
10501
|
+
if (from) rows = rows.filter((p) => p.date >= from);
|
|
10502
|
+
if (to) rows = rows.filter((p) => p.date <= to);
|
|
10503
|
+
rows = rows.slice().sort((a, b) => b.date.localeCompare(a.date));
|
|
10504
|
+
output({ interval: "day", source: cfg.source, series: rows }, () => {
|
|
10505
|
+
const table = rows.map((row, i) => {
|
|
10506
|
+
const prev = rows[i + 1];
|
|
10507
|
+
const delta = prev ? cfg.valueOf(row) - cfg.valueOf(prev) : void 0;
|
|
10508
|
+
return [row.date, cfg.fmt(cfg.valueOf(row)), fmtDelta(delta, cfg.fmt)];
|
|
10509
|
+
});
|
|
10510
|
+
printTable(cfg.title, ["Date", cfg.valueHeader, "\u0394 vs prev"], table);
|
|
10511
|
+
});
|
|
10512
|
+
}
|
|
10513
|
+
async function renderTvlHistory(opts) {
|
|
10514
|
+
try {
|
|
10515
|
+
const series = await getTvlHistory(opts.chain);
|
|
10516
|
+
renderHistory(series, opts, {
|
|
10517
|
+
valueOf: (r) => r.tvl,
|
|
10518
|
+
fmt: fmtUsd,
|
|
10519
|
+
title: "TVL Over Time \u2014 Daily (source: DeFiLlama)",
|
|
10520
|
+
valueHeader: "TVL",
|
|
10521
|
+
source: "defillama"
|
|
10522
|
+
});
|
|
10523
|
+
} catch (err) {
|
|
10524
|
+
formatCliError(err);
|
|
10525
|
+
}
|
|
10526
|
+
}
|
|
10527
|
+
async function renderSavingsRateHistory(opts) {
|
|
10528
|
+
try {
|
|
10529
|
+
const series = await getSavingsApyHistory(opts.chain);
|
|
10530
|
+
renderHistory(series, opts, {
|
|
10531
|
+
valueOf: (r) => r.apy,
|
|
10532
|
+
fmt: fmtApy,
|
|
10533
|
+
title: "sUSDp APY Over Time \u2014 Daily (source: DeFiLlama)",
|
|
10534
|
+
valueHeader: "APY",
|
|
10535
|
+
source: "defillama"
|
|
10536
|
+
});
|
|
10537
|
+
} catch (err) {
|
|
10538
|
+
formatCliError(err);
|
|
10539
|
+
}
|
|
10540
|
+
}
|
|
10541
|
+
async function renderSupplyHistory(token, opts) {
|
|
10542
|
+
try {
|
|
10543
|
+
if (token.toLowerCase() !== "usdp")
|
|
10544
|
+
throw new CliError(
|
|
10545
|
+
ErrorCode.UNKNOWN,
|
|
10546
|
+
`supply --history is only available for usdp (got "${token}")`,
|
|
10547
|
+
"Only USDp has a public historical supply source"
|
|
10548
|
+
);
|
|
10549
|
+
const series = await getUsdpSupplyHistory(opts.chain);
|
|
10550
|
+
renderHistory(series, opts, {
|
|
10551
|
+
valueOf: (r) => r.supply,
|
|
10552
|
+
fmt: fmtNum,
|
|
10553
|
+
title: "USDp Supply Over Time \u2014 Daily (source: DeFiLlama)",
|
|
10554
|
+
valueHeader: "Supply (USDp)",
|
|
10555
|
+
source: "defillama"
|
|
10556
|
+
});
|
|
10557
|
+
} catch (err) {
|
|
10558
|
+
formatCliError(err);
|
|
10559
|
+
}
|
|
10560
|
+
}
|
|
10287
10561
|
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
|
|
10562
|
+
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() {
|
|
10563
|
+
const opts = resolveOpts(this);
|
|
10564
|
+
if (opts.history) {
|
|
10565
|
+
await renderTvlHistory(opts);
|
|
10566
|
+
return;
|
|
10567
|
+
}
|
|
10290
10568
|
try {
|
|
10291
|
-
const result = await getTvl(chain);
|
|
10569
|
+
const result = await getTvl(opts.chain);
|
|
10292
10570
|
output(result, () => {
|
|
10293
10571
|
printKeyValue("TVL", [["Total TVL", fmtUsd(result.totalTVL)]]);
|
|
10294
10572
|
const rows = result.breakdown.map((b) => [b.chain, fmtUsd(b.tvl)]);
|
|
@@ -10299,9 +10577,56 @@ function tvlCmd() {
|
|
|
10299
10577
|
}
|
|
10300
10578
|
});
|
|
10301
10579
|
}
|
|
10580
|
+
function orderedChainIds(series, latest) {
|
|
10581
|
+
const ids = /* @__PURE__ */ new Set();
|
|
10582
|
+
for (const row of series) {
|
|
10583
|
+
for (const id of Object.keys(row.perChain)) ids.add(Number(id));
|
|
10584
|
+
}
|
|
10585
|
+
return [...ids].sort((a, b) => (latest[b] ?? 0) - (latest[a] ?? 0));
|
|
10586
|
+
}
|
|
10587
|
+
async function renderBackingHistory(opts) {
|
|
10588
|
+
try {
|
|
10589
|
+
let chainId;
|
|
10590
|
+
if (opts.chain) {
|
|
10591
|
+
const cfg = CHAINS[opts.chain];
|
|
10592
|
+
if (!cfg)
|
|
10593
|
+
throw new CliError(
|
|
10594
|
+
ErrorCode.UNKNOWN_CHAIN,
|
|
10595
|
+
`Unknown chain "${opts.chain}"`,
|
|
10596
|
+
"Run: parallel protocol chains to see supported chains"
|
|
10597
|
+
);
|
|
10598
|
+
chainId = cfg.id;
|
|
10599
|
+
}
|
|
10600
|
+
const points = await getHistoricalProtocols(opts.from, opts.to);
|
|
10601
|
+
const series = reservesByDate(points, chainId).sort((a, b) => b.date.localeCompare(a.date));
|
|
10602
|
+
const chainIds = orderedChainIds(series, series[0]?.perChain ?? {});
|
|
10603
|
+
output({ interval: "day", series }, () => {
|
|
10604
|
+
const headers = [
|
|
10605
|
+
"Date",
|
|
10606
|
+
...chainIds.map((id) => chainNameById(id)),
|
|
10607
|
+
"Total"
|
|
10608
|
+
];
|
|
10609
|
+
const rows = series.map((row) => [
|
|
10610
|
+
row.date.slice(0, 10),
|
|
10611
|
+
...chainIds.map(
|
|
10612
|
+
(id) => row.perChain[id] ? fmtUsd(row.perChain[id]) : chalk5.dim("\u2212")
|
|
10613
|
+
),
|
|
10614
|
+
fmtUsd(row.total)
|
|
10615
|
+
]);
|
|
10616
|
+
printTable("Backing History (reserves over time) \u2014 Daily", headers, rows);
|
|
10617
|
+
});
|
|
10618
|
+
} catch (err) {
|
|
10619
|
+
formatCliError(err);
|
|
10620
|
+
}
|
|
10621
|
+
}
|
|
10302
10622
|
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
|
|
10623
|
+
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() {
|
|
10624
|
+
const opts = resolveOpts(this);
|
|
10625
|
+
if (opts.history) {
|
|
10626
|
+
await renderBackingHistory(opts);
|
|
10627
|
+
return;
|
|
10628
|
+
}
|
|
10629
|
+
const { chain } = opts;
|
|
10305
10630
|
try {
|
|
10306
10631
|
const [result, usdpSupply, solvency] = await Promise.all([
|
|
10307
10632
|
getTvl(chain),
|
|
@@ -10614,8 +10939,13 @@ function feesCmd2() {
|
|
|
10614
10939
|
});
|
|
10615
10940
|
}
|
|
10616
10941
|
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
|
|
10942
|
+
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() {
|
|
10943
|
+
const opts = resolveOpts(this);
|
|
10944
|
+
if (opts.history) {
|
|
10945
|
+
await renderSavingsRateHistory(opts);
|
|
10946
|
+
return;
|
|
10947
|
+
}
|
|
10948
|
+
const { chain } = opts;
|
|
10619
10949
|
try {
|
|
10620
10950
|
if (chain) assertParallelizerChain(chain);
|
|
10621
10951
|
const result = await getSavingsRate();
|
|
@@ -14230,7 +14560,7 @@ var package_default = {
|
|
|
14230
14560
|
|
|
14231
14561
|
// package.json
|
|
14232
14562
|
var package_default2 = {
|
|
14233
|
-
version: "0.
|
|
14563
|
+
version: "0.2.1"};
|
|
14234
14564
|
|
|
14235
14565
|
// src/commands/version.ts
|
|
14236
14566
|
function versionCommand() {
|