@parallel-protocol/cli 0.2.7 → 0.2.8
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/dist/index.js +87 -46
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -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.8"};
|
|
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",
|
|
@@ -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.0"};
|
|
15323
15364
|
|
|
15324
15365
|
// src/commands/version.ts
|
|
15325
15366
|
function versionCommand() {
|