@parallel-protocol/cli 0.2.7 → 0.2.9
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 +2 -2
- package/dist/index.js +109 -58
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -192,7 +192,7 @@ parallel swap redeem --collateral <symbol> --amount <n> --chain <chain> --wa
|
|
|
192
192
|
parallel swap redeem-all --amount <n> --chain <chain> --wallet # proportional redeem
|
|
193
193
|
```
|
|
194
194
|
|
|
195
|
-
> Command names match the MCP tools
|
|
195
|
+
> Command names match the MCP tools: `redeem` targets ONE
|
|
196
196
|
> collateral (formerly `burn`), `redeem-all` redeems proportionally across the
|
|
197
197
|
> whole basket (formerly `redeem`). The old `swap burn` keeps working as a
|
|
198
198
|
> hidden legacy command.
|
|
@@ -438,7 +438,7 @@ Not all chains support every feature. Use `parallel protocol chains` to see the
|
|
|
438
438
|
| `RPC_ERROR` | An HTTP provider (facilitator, history APIs) is unreachable |
|
|
439
439
|
| `UNKNOWN` | Any other failure |
|
|
440
440
|
|
|
441
|
-
Protocol-layer errors (caps, bridge limits, sunset chains, partial reads…) are surfaced with their own code in the `code` field
|
|
441
|
+
Protocol-layer errors (caps, bridge limits, sunset chains, partial reads…) are surfaced with their own code in the `code` field — e.g. `EXCEEDS_CAP`, `EXCEEDS_BRIDGE_LIMIT`, `EXCEEDS_GLOBAL_LIMIT`, `CHAIN_SUNSET`, `ROUTE_UNAVAILABLE`, `PARTIAL_READ`, `PARALLELIZER_NOT_DEPLOYED`, `COLLATERAL_NOT_SUPPORTED`, `INSUFFICIENT_BALANCE`. Match on `error.code`; the message carries the human detail (remaining capacity, valid values…) without the code prefix.
|
|
442
442
|
|
|
443
443
|
---
|
|
444
444
|
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { AsyncLocalStorage } from 'async_hooks';
|
|
3
|
-
import { Command,
|
|
3
|
+
import { Command, CommanderError } from 'commander';
|
|
4
4
|
import { existsSync, mkdirSync, writeFileSync, readFileSync } from 'fs';
|
|
5
5
|
import { join, dirname } from 'path';
|
|
6
6
|
import { fileURLToPath } from 'url';
|
|
@@ -1635,7 +1635,7 @@ function suppressLogs() {
|
|
|
1635
1635
|
|
|
1636
1636
|
// package.json
|
|
1637
1637
|
var package_default = {
|
|
1638
|
-
version: "0.2.
|
|
1638
|
+
version: "0.2.9"};
|
|
1639
1639
|
function findEnvFile(dir) {
|
|
1640
1640
|
const candidate = join(dir, ".env");
|
|
1641
1641
|
if (existsSync(candidate)) return candidate;
|
|
@@ -5722,7 +5722,7 @@ function toTxData(tx) {
|
|
|
5722
5722
|
function quoteCmd() {
|
|
5723
5723
|
return new Command("quote").description("Get a LayerZero bridge fee quote").option(
|
|
5724
5724
|
"--token <token>",
|
|
5725
|
-
"token to bridge: usdp
|
|
5725
|
+
"token to bridge: usdp (the only token currently bridgeable)",
|
|
5726
5726
|
"usdp"
|
|
5727
5727
|
).option("--from <chain>", "source chain").option("--to <chain>", "destination chain").option("--amount <n>", "amount to bridge").action(async function() {
|
|
5728
5728
|
const opts = resolveOpts(this);
|
|
@@ -5772,7 +5772,11 @@ function quoteCmd() {
|
|
|
5772
5772
|
});
|
|
5773
5773
|
}
|
|
5774
5774
|
function feesCmd() {
|
|
5775
|
-
return new Command("fees").description("Show LayerZero bridge fees to all destinations from a chain").option(
|
|
5775
|
+
return new Command("fees").description("Show LayerZero bridge fees to all destinations from a chain").option(
|
|
5776
|
+
"--token <token>",
|
|
5777
|
+
"token: usdp (the only token currently bridgeable)",
|
|
5778
|
+
"usdp"
|
|
5779
|
+
).option("--from <chain>", "source chain").action(async function() {
|
|
5776
5780
|
const opts = resolveOpts(this);
|
|
5777
5781
|
try {
|
|
5778
5782
|
if (!opts.from)
|
|
@@ -5805,7 +5809,7 @@ function feesCmd() {
|
|
|
5805
5809
|
function sendCmd() {
|
|
5806
5810
|
return new Command("send").description("Bridge tokens cross-chain via LayerZero OFT").option(
|
|
5807
5811
|
"--token <token>",
|
|
5808
|
-
"token to bridge: usdp
|
|
5812
|
+
"token to bridge: usdp (the only token currently bridgeable)",
|
|
5809
5813
|
"usdp"
|
|
5810
5814
|
).option("--from <chain>", "source chain").option("--to <chain>", "destination chain").option("--amount <n>", "amount to bridge").option("--recipient <addr>", "override destination recipient address").option("-w, --wallet [path|env]", "keystore path or 'env'").option("--address <addr>", "sender address (for dry-run without --wallet)").option("--dry-run", "build tx without broadcasting").action(async function() {
|
|
5811
5815
|
const opts = resolveOpts(this);
|
|
@@ -7153,7 +7157,11 @@ var TTL = {
|
|
|
7153
7157
|
SUPPLY: 6e4,
|
|
7154
7158
|
SAVINGS_RATE: 3e4,
|
|
7155
7159
|
EXCHANGE_RATE: 3e4,
|
|
7156
|
-
STAKING: 6e4
|
|
7160
|
+
STAKING: 6e4,
|
|
7161
|
+
// Forum topics do not move once created — a long TTL also makes the
|
|
7162
|
+
// Discourse search deterministic across consecutive calls.
|
|
7163
|
+
FORUM_URL: 6e5
|
|
7164
|
+
};
|
|
7157
7165
|
var lru = new I({
|
|
7158
7166
|
max: 500,
|
|
7159
7167
|
allowStale: false
|
|
@@ -7689,29 +7697,37 @@ async function getFeeRates(chain, collateral) {
|
|
|
7689
7697
|
);
|
|
7690
7698
|
}
|
|
7691
7699
|
|
|
7700
|
+
// ../shared/src/infra/http.ts
|
|
7701
|
+
function fetchWithTimeout(url, init = {}, timeoutMs = 1e4) {
|
|
7702
|
+
return fetch(url, { ...init, signal: AbortSignal.timeout(timeoutMs) });
|
|
7703
|
+
}
|
|
7704
|
+
|
|
7692
7705
|
// ../mcp-server/src/services/governance/proposals.ts
|
|
7693
7706
|
var SNAPSHOT_HUB = "https://hub.snapshot.org/graphql";
|
|
7694
7707
|
var SNAPSHOT_SPACE = "parallel-protocol.eth";
|
|
7695
7708
|
var DISCOURSE_BASE = "https://gov.parallel.best";
|
|
7696
|
-
|
|
7697
|
-
|
|
7698
|
-
|
|
7699
|
-
|
|
7700
|
-
|
|
7701
|
-
|
|
7702
|
-
|
|
7703
|
-
|
|
7704
|
-
|
|
7705
|
-
|
|
7706
|
-
|
|
7707
|
-
|
|
7708
|
-
|
|
7709
|
+
function fetchForumUrl(friendlyId) {
|
|
7710
|
+
return getOrSet(`gov:forum:${friendlyId}`, TTL.FORUM_URL, async () => {
|
|
7711
|
+
try {
|
|
7712
|
+
const res = await fetchWithTimeout(
|
|
7713
|
+
`${DISCOURSE_BASE}/search.json?q=${encodeURIComponent(friendlyId)}`,
|
|
7714
|
+
{},
|
|
7715
|
+
3e3
|
|
7716
|
+
);
|
|
7717
|
+
if (!res.ok) return null;
|
|
7718
|
+
const data = await res.json();
|
|
7719
|
+
const topic = data.topics?.[0];
|
|
7720
|
+
if (!topic) return null;
|
|
7721
|
+
return `${DISCOURSE_BASE}/t/${topic.slug}/${topic.id}`;
|
|
7722
|
+
} catch {
|
|
7723
|
+
return null;
|
|
7724
|
+
}
|
|
7725
|
+
});
|
|
7709
7726
|
}
|
|
7710
7727
|
async function enrichWithForumUrls(proposals) {
|
|
7711
7728
|
const urls = await Promise.all(
|
|
7712
7729
|
proposals.map((p) => {
|
|
7713
|
-
if (p.forumUrl
|
|
7714
|
-
return Promise.resolve(p.forumUrl);
|
|
7730
|
+
if (p.forumUrl) return Promise.resolve(p.forumUrl);
|
|
7715
7731
|
if (p.id !== p.snapshotId) return fetchForumUrl(p.id);
|
|
7716
7732
|
return Promise.resolve(null);
|
|
7717
7733
|
})
|
|
@@ -7719,11 +7735,18 @@ async function enrichWithForumUrls(proposals) {
|
|
|
7719
7735
|
return proposals.map((p, i) => ({ ...p, forumUrl: urls[i] ?? null }));
|
|
7720
7736
|
}
|
|
7721
7737
|
async function querySnapshot(query, variables) {
|
|
7722
|
-
const res = await
|
|
7723
|
-
|
|
7724
|
-
|
|
7725
|
-
|
|
7726
|
-
|
|
7738
|
+
const res = await fetchWithTimeout(
|
|
7739
|
+
SNAPSHOT_HUB,
|
|
7740
|
+
{
|
|
7741
|
+
method: "POST",
|
|
7742
|
+
headers: {
|
|
7743
|
+
"Content-Type": "application/json",
|
|
7744
|
+
Accept: "application/json"
|
|
7745
|
+
},
|
|
7746
|
+
body: JSON.stringify({ query, variables })
|
|
7747
|
+
},
|
|
7748
|
+
1e4
|
|
7749
|
+
);
|
|
7727
7750
|
if (!res.ok)
|
|
7728
7751
|
throw new Error(`Snapshot API error: ${res.status} ${res.statusText}`);
|
|
7729
7752
|
const json = await res.json();
|
|
@@ -7743,14 +7766,23 @@ function inferFriendlyId(title) {
|
|
|
7743
7766
|
const match = title.match(/\b(PIP|PGP|PIR)-(\d+(?:\.\d+)?)/i);
|
|
7744
7767
|
return match ? `${match[1].toUpperCase()}-${match[2]}` : null;
|
|
7745
7768
|
}
|
|
7746
|
-
function
|
|
7747
|
-
if (
|
|
7748
|
-
|
|
7749
|
-
|
|
7750
|
-
|
|
7769
|
+
function isForAgainstVote(choices) {
|
|
7770
|
+
if (!choices || choices.length < 2) return false;
|
|
7771
|
+
const second = choices[1].toLowerCase();
|
|
7772
|
+
return second.startsWith("against") || second.startsWith("no");
|
|
7773
|
+
}
|
|
7774
|
+
function mapDetailedStatus(p) {
|
|
7775
|
+
if (p.state === "active") return "active";
|
|
7776
|
+
if (p.state === "pending") return "pending";
|
|
7777
|
+
if (p.state === "closed") {
|
|
7778
|
+
if (p.quorum > 0 && p.scores_total < p.quorum) return "rejected";
|
|
7779
|
+
if (isForAgainstVote(p.choices)) {
|
|
7780
|
+
const scores = p.scores ?? [];
|
|
7781
|
+
return (scores[0] ?? 0) > (scores[1] ?? 0) ? "passed" : "rejected";
|
|
7782
|
+
}
|
|
7751
7783
|
return "passed";
|
|
7752
7784
|
}
|
|
7753
|
-
return state;
|
|
7785
|
+
return p.state;
|
|
7754
7786
|
}
|
|
7755
7787
|
function summarizeProposal(p) {
|
|
7756
7788
|
const scores = p.scores ?? [];
|
|
@@ -7763,11 +7795,11 @@ function summarizeProposal(p) {
|
|
|
7763
7795
|
title: p.title,
|
|
7764
7796
|
author: p.author,
|
|
7765
7797
|
type: inferProposalType(p.title),
|
|
7766
|
-
status: mapDetailedStatus(p
|
|
7798
|
+
status: mapDetailedStatus(p),
|
|
7767
7799
|
createdAt: new Date(p.created * 1e3).toISOString(),
|
|
7768
7800
|
votingEndsAt: new Date(p.end * 1e3).toISOString(),
|
|
7769
7801
|
snapshotUrl: `https://snapshot.org/#/${SNAPSHOT_SPACE}/proposal/${p.id}`,
|
|
7770
|
-
forumUrl: p.
|
|
7802
|
+
forumUrl: p.discussion?.trim() ? p.discussion : null,
|
|
7771
7803
|
summary: (p.body ?? "").slice(0, 200) + ((p.body?.length ?? 0) > 200 ? "\u2026" : ""),
|
|
7772
7804
|
forVotes,
|
|
7773
7805
|
againstVotes,
|
|
@@ -7795,7 +7827,7 @@ var PROPOSALS_QUERY = `
|
|
|
7795
7827
|
scores
|
|
7796
7828
|
choices
|
|
7797
7829
|
quorum
|
|
7798
|
-
|
|
7830
|
+
discussion
|
|
7799
7831
|
}
|
|
7800
7832
|
}
|
|
7801
7833
|
`;
|
|
@@ -7838,7 +7870,7 @@ var PROPOSAL_DETAILS_QUERY = `
|
|
|
7838
7870
|
scores
|
|
7839
7871
|
choices
|
|
7840
7872
|
quorum
|
|
7841
|
-
|
|
7873
|
+
discussion
|
|
7842
7874
|
}
|
|
7843
7875
|
}
|
|
7844
7876
|
`;
|
|
@@ -7846,23 +7878,28 @@ async function buildProposalDetails(p) {
|
|
|
7846
7878
|
const [enriched] = await enrichWithForumUrls([summarizeProposal(p)]);
|
|
7847
7879
|
const summary = enriched;
|
|
7848
7880
|
const scores = p.scores ?? [];
|
|
7881
|
+
const hasQuorum = p.quorum > 0;
|
|
7882
|
+
const quorumReached = hasQuorum ? p.scores_total >= p.quorum : null;
|
|
7849
7883
|
return {
|
|
7850
7884
|
...summary,
|
|
7851
7885
|
description: p.body ?? "",
|
|
7852
7886
|
choices: p.choices ?? [],
|
|
7853
7887
|
scores,
|
|
7854
7888
|
quorum: p.quorum,
|
|
7855
|
-
quorumReached
|
|
7889
|
+
quorumReached,
|
|
7856
7890
|
voteResults: {
|
|
7857
7891
|
for: scores[0] ?? 0,
|
|
7858
7892
|
against: scores[1] ?? 0,
|
|
7859
7893
|
abstain: scores[2] ?? 0,
|
|
7860
7894
|
quorum: p.quorum,
|
|
7861
|
-
quorumReached
|
|
7895
|
+
quorumReached
|
|
7862
7896
|
},
|
|
7863
7897
|
parametersChanged: null,
|
|
7864
7898
|
executionTx: null,
|
|
7865
7899
|
unavailableFields: {
|
|
7900
|
+
...hasQuorum ? {} : {
|
|
7901
|
+
quorumReached: "No quorum is configured for this space on Snapshot (proposal quorum is 0) \u2014 pass/fail is derived from the For/Against split alone."
|
|
7902
|
+
},
|
|
7866
7903
|
parametersChanged: "Snapshot does not expose structured on-chain parameter changes \u2014 this information is in the proposal body text.",
|
|
7867
7904
|
executionTx: "Snapshot does not record on-chain execution transactions \u2014 check the DAO's AccessManager or TimelockController on Etherscan."
|
|
7868
7905
|
}
|
|
@@ -8161,7 +8198,7 @@ function proposalsCmd() {
|
|
|
8161
8198
|
`--type must be PIP, PGP or PIR, got "${opts.type}"`
|
|
8162
8199
|
);
|
|
8163
8200
|
}
|
|
8164
|
-
const STATUSES = ["active", "
|
|
8201
|
+
const STATUSES = ["active", "pending", "passed", "rejected"];
|
|
8165
8202
|
if (opts.status && !STATUSES.includes(opts.status)) {
|
|
8166
8203
|
throw new CliError(
|
|
8167
8204
|
ErrorCode.INVALID_OPTION,
|
|
@@ -8208,7 +8245,11 @@ function proposalCmd() {
|
|
|
8208
8245
|
["Created", fmtDate(result.createdAt)],
|
|
8209
8246
|
["Voting Ends", fmtDate(result.votingEndsAt)],
|
|
8210
8247
|
["Quorum", fmtVotes(result.quorum)],
|
|
8211
|
-
[
|
|
8248
|
+
[
|
|
8249
|
+
"Quorum Reached",
|
|
8250
|
+
// null = no quorum configured — "No ✗" would be misleading.
|
|
8251
|
+
result.quorumReached === null ? "\u2014" : result.quorumReached ? "Yes \u2713" : "No \u2717"
|
|
8252
|
+
],
|
|
8212
8253
|
["Snapshot URL", result.snapshotUrl],
|
|
8213
8254
|
["Forum URL", result.forumUrl ?? "\u2014"]
|
|
8214
8255
|
]);
|
|
@@ -8383,9 +8424,9 @@ async function getPaymentCapabilities(chain, {
|
|
|
8383
8424
|
const hasUSDp = !!getUSDpAddress(chain);
|
|
8384
8425
|
const hasSUSDp = !!CHAINS[chain].contracts.susdp;
|
|
8385
8426
|
const hasUSDC = !!getUSDCAddress(chain);
|
|
8386
|
-
const
|
|
8387
|
-
const parallelizerActive = hasParallelizer &&
|
|
8388
|
-
const susdpVaultActive = hasSUSDp &&
|
|
8427
|
+
const chainActive = CHAINS[chain].status === "active";
|
|
8428
|
+
const parallelizerActive = hasParallelizer && chainActive;
|
|
8429
|
+
const susdpVaultActive = hasSUSDp && chainActive;
|
|
8389
8430
|
const facilitatorSupported = parallelizerActive;
|
|
8390
8431
|
const gasSponsored = parallelizerActive && chain !== "ethereum";
|
|
8391
8432
|
let hasUsdcCollateral = false;
|
|
@@ -8409,7 +8450,7 @@ async function getPaymentCapabilities(chain, {
|
|
|
8409
8450
|
}
|
|
8410
8451
|
}
|
|
8411
8452
|
const capabilities = [];
|
|
8412
|
-
if (hasUSDp) {
|
|
8453
|
+
if (hasUSDp && facilitatorSupported) {
|
|
8413
8454
|
capabilities.push({
|
|
8414
8455
|
route: "A",
|
|
8415
8456
|
method: "transferWithAuthorization",
|
|
@@ -8449,7 +8490,7 @@ async function getPaymentCapabilities(chain, {
|
|
|
8449
8490
|
gasSponsored
|
|
8450
8491
|
});
|
|
8451
8492
|
}
|
|
8452
|
-
if (hasUSDp && susdpVaultActive) {
|
|
8493
|
+
if (hasUSDp && susdpVaultActive && facilitatorSupported) {
|
|
8453
8494
|
capabilities.push({
|
|
8454
8495
|
route: "C",
|
|
8455
8496
|
method: "depositWithAuthorization",
|
|
@@ -8469,7 +8510,7 @@ async function getPaymentCapabilities(chain, {
|
|
|
8469
8510
|
gasSponsored
|
|
8470
8511
|
});
|
|
8471
8512
|
}
|
|
8472
|
-
if (hasUSDC) {
|
|
8513
|
+
if (hasUSDC && facilitatorSupported) {
|
|
8473
8514
|
capabilities.push({
|
|
8474
8515
|
route: "F",
|
|
8475
8516
|
method: "transferWithAuthorization",
|
|
@@ -11143,7 +11184,7 @@ async function renderSupplyHistory(token, opts) {
|
|
|
11143
11184
|
try {
|
|
11144
11185
|
if (token.toLowerCase() !== "usdp")
|
|
11145
11186
|
throw new CliError(
|
|
11146
|
-
ErrorCode.
|
|
11187
|
+
ErrorCode.INVALID_OPTION,
|
|
11147
11188
|
`supply --history is only available for usdp (got "${token}")`,
|
|
11148
11189
|
"Only USDp has a public historical supply source"
|
|
11149
11190
|
);
|
|
@@ -12761,8 +12802,8 @@ async function getStakingOverview() {
|
|
|
12761
12802
|
aprNote: "Base APR estimated from previous epoch rewards and token prices. Actual APR varies per user based on ParaBoost score. Same formula as app."
|
|
12762
12803
|
} : {
|
|
12763
12804
|
unavailableFields: {
|
|
12764
|
-
sprl1APR: "APR unavailable \u2014
|
|
12765
|
-
sprl2APR: "APR unavailable \u2014
|
|
12805
|
+
sprl1APR: "APR unavailable \u2014 the staking API returned no validated epoch data (unreachable, unauthorized, or no epoch settled yet).",
|
|
12806
|
+
sprl2APR: "APR unavailable \u2014 the staking API returned no validated epoch data (unreachable, unauthorized, or no epoch settled yet)."
|
|
12766
12807
|
}
|
|
12767
12808
|
}
|
|
12768
12809
|
};
|
|
@@ -12956,17 +12997,17 @@ async function getStakingInfo(userAddress) {
|
|
|
12956
12997
|
estimatedAPR: userAPR,
|
|
12957
12998
|
unavailableFields: {
|
|
12958
12999
|
...pendingRewards.sprl1Pending === null && {
|
|
12959
|
-
"sprl1.pendingRewards": "sPRL1 rewards are distributed via an off-chain Merkle distributor \u2014
|
|
13000
|
+
"sprl1.pendingRewards": "sPRL1 rewards are distributed via an off-chain Merkle distributor \u2014 the staking API returned no data for this field."
|
|
12960
13001
|
},
|
|
12961
13002
|
...pendingRewards.currentEpoch === null && {
|
|
12962
|
-
"sprl1.cooldown.epoch": "Current epoch unavailable \u2014
|
|
13003
|
+
"sprl1.cooldown.epoch": "Current epoch unavailable \u2014 the staking API returned no epoch data."
|
|
12963
13004
|
},
|
|
12964
13005
|
"sprl2.auraRewards": "BAL and AURA rewards from Aura Finance are automatically forwarded to the DAO treasury, not distributed to individual stakers.",
|
|
12965
13006
|
...pendingRewards.sprl2Pending === null && {
|
|
12966
|
-
"sprl2.protocolRewards": "Protocol rewards for sPRL2 are distributed via the same off-chain epoch-based Merkle distributor \u2014
|
|
13007
|
+
"sprl2.protocolRewards": "Protocol rewards for sPRL2 are distributed via the same off-chain epoch-based Merkle distributor \u2014 the staking API returned no data for this field."
|
|
12967
13008
|
},
|
|
12968
13009
|
...pendingRewards.paraboost === null && {
|
|
12969
|
-
"sprl2.paraboost": "Paraboost multiplier unavailable \u2014
|
|
13010
|
+
"sprl2.paraboost": "Paraboost multiplier unavailable \u2014 the staking API returned no data. Base multiplier is 2.5x; paraboost mechanics increase it over time."
|
|
12970
13011
|
},
|
|
12971
13012
|
...sprl2DelegationNotActive && {
|
|
12972
13013
|
"sprl2.votingPower": `Voting power is 0 despite having BPT staked. This address has not self-delegated. Call delegate(yourAddress) on the sPRL2 contract (${SPRL2_ADDRESS}) to activate on-chain voting power.`
|
|
@@ -13055,7 +13096,7 @@ async function getCooldownStatus(userAddress) {
|
|
|
13055
13096
|
address: userAddress,
|
|
13056
13097
|
unavailableFields: {
|
|
13057
13098
|
...epochMeta === null && {
|
|
13058
|
-
currentEpoch: "Current epoch unavailable \u2014
|
|
13099
|
+
currentEpoch: "Current epoch unavailable \u2014 the staking API returned no epoch data."
|
|
13059
13100
|
}
|
|
13060
13101
|
}
|
|
13061
13102
|
};
|
|
@@ -13257,7 +13298,7 @@ async function buildStakeSprl2Tx(amount, sender, wethAmount) {
|
|
|
13257
13298
|
const estimatedVotingPower = prlPer1Bpt !== null ? (parseFloat(amount) * prlPer1Bpt * userParaboost).toFixed(6) : null;
|
|
13258
13299
|
const unavailableFields = {};
|
|
13259
13300
|
if (estimatedAPR === null) {
|
|
13260
|
-
unavailableFields.estimatedAPR = "Failed to reach
|
|
13301
|
+
unavailableFields.estimatedAPR = "Failed to reach the staking API \u2014 APR unavailable.";
|
|
13261
13302
|
}
|
|
13262
13303
|
const { simulation: simResult, warnings: simWarnings } = toSimFields(
|
|
13263
13304
|
simulation,
|
|
@@ -15319,7 +15360,7 @@ function swapCommand() {
|
|
|
15319
15360
|
|
|
15320
15361
|
// ../mcp-server/package.json
|
|
15321
15362
|
var package_default2 = {
|
|
15322
|
-
version: "1.
|
|
15363
|
+
version: "1.1.1"};
|
|
15323
15364
|
|
|
15324
15365
|
// src/commands/version.ts
|
|
15325
15366
|
function versionCommand() {
|
|
@@ -15357,7 +15398,7 @@ var program = new Command();
|
|
|
15357
15398
|
program.name("parallel").description("Parallel Protocol CLI").version(package_default.version).option("-c, --chain <chain>", "target chain (e.g. base, ethereum)").option("-j, --json", "force JSON output").option("--dry-run", "build transaction without broadcasting").option(
|
|
15358
15399
|
"-w, --wallet [path|env]",
|
|
15359
15400
|
"keystore path, 'env', or alone to auto-resolve from config/env"
|
|
15360
|
-
).option("-v, --verbose", "verbose logs").option("--no-cache", "bypass TTL cache, force fresh RPC call").
|
|
15401
|
+
).option("-v, --verbose", "verbose logs").option("--no-cache", "bypass TTL cache, force fresh RPC call").hook("preAction", (thisCommand) => {
|
|
15361
15402
|
const opts = thisCommand.opts();
|
|
15362
15403
|
if (opts.json) process.env._PARALLEL_JSON_FLAG = "1";
|
|
15363
15404
|
});
|
|
@@ -15403,7 +15444,17 @@ try {
|
|
|
15403
15444
|
process.exitCode = 0;
|
|
15404
15445
|
} else {
|
|
15405
15446
|
if (isJsonMode()) {
|
|
15406
|
-
const invoked =
|
|
15447
|
+
const invoked = [];
|
|
15448
|
+
let node = program;
|
|
15449
|
+
for (const token of process.argv.slice(2)) {
|
|
15450
|
+
if (token.startsWith("-")) break;
|
|
15451
|
+
const child = node.commands.find(
|
|
15452
|
+
(c) => c.name() === token || c.aliases().includes(token)
|
|
15453
|
+
);
|
|
15454
|
+
if (!child) break;
|
|
15455
|
+
invoked.push(token);
|
|
15456
|
+
node = child;
|
|
15457
|
+
}
|
|
15407
15458
|
const message = err.code === "commander.help" ? `Missing subcommand for 'parallel ${invoked.join(" ")}'` : err.message.replace(/^error:\s*/, "");
|
|
15408
15459
|
console.error(
|
|
15409
15460
|
JSON.stringify(
|