shinjuku-shielded 0.3.26 → 0.3.28
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/manifest.json +3 -3
- package/package.json +3 -3
- package/shinjuku-wallet.mjs +197 -16
package/manifest.json
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
{
|
|
2
2
|
"schema": "carbon-shielded-wallet/bundle-manifest/v1",
|
|
3
3
|
"file": "shinjuku-wallet.mjs",
|
|
4
|
-
"sha256": "
|
|
5
|
-
"bytes":
|
|
6
|
-
"sourceCommit": "
|
|
4
|
+
"sha256": "dd6ce54a50e0e58be863f647620b767cb760d1278ee089b74c10c98068383047",
|
|
5
|
+
"bytes": 11159107,
|
|
6
|
+
"sourceCommit": "b5316573de1f09bb207ce09a78d5ec4d02fc8035",
|
|
7
7
|
"sourceDirty": false,
|
|
8
8
|
"installRecordMatchesLockfile": true,
|
|
9
9
|
"releaseRule": "valid only when two fresh npm ci --ignore-scripts builds on different OSes give the same sha256; installRecordMatchesLockfile true means every entry npm installed equals its package-lock.json entry and every entry not marked optional, devOptional included, is installed: an optional entry (a package for another platform) may be absent",
|
package/package.json
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "shinjuku-shielded",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.28",
|
|
4
4
|
"mcpName": "io.github.ShinjukuStaition/shinjuku-mcp",
|
|
5
5
|
"description": "Shinjuku Shielded, the private x402 facilitator on Solana: the self-custody wallet CLI and its MCP server. Shield, pay, and unshield USDC from any MCP agent, under caps you set.",
|
|
6
|
-
"shinjukuRelease": "
|
|
7
|
-
"shinjukuSha256": "
|
|
6
|
+
"shinjukuRelease": "dd6ce54a",
|
|
7
|
+
"shinjukuSha256": "dd6ce54a50e0e58be863f647620b767cb760d1278ee089b74c10c98068383047",
|
|
8
8
|
"license": "SEE LICENSE IN LICENSE.txt",
|
|
9
9
|
"author": "Shinjuku Shielded",
|
|
10
10
|
"homepage": "https://github.com/ShinjukuStaition/shinjuku-mcp#readme",
|
package/shinjuku-wallet.mjs
CHANGED
|
@@ -119132,7 +119132,7 @@ function publicUrl(value) {
|
|
|
119132
119132
|
return null;
|
|
119133
119133
|
}
|
|
119134
119134
|
}
|
|
119135
|
-
function computeBalance({ store, snapshotRead, source = "local", now = Date.now() }) {
|
|
119135
|
+
function computeBalance({ store, snapshotRead, source = "local", now = Date.now(), firstDepositEstimate = false }) {
|
|
119136
119136
|
const state = store.state;
|
|
119137
119137
|
const decimals = Number(state.decimals);
|
|
119138
119138
|
const records = store.listWal().sort().map((name) => {
|
|
@@ -119217,6 +119217,12 @@ function computeBalance({ store, snapshotRead, source = "local", now = Date.now(
|
|
|
119217
119217
|
}
|
|
119218
119218
|
return report("empty", 0n, proved ? `deposit ${proved.depositId} is proved but not sent: back up (shinjuku-wallet help backup-export), then rerun the same deposit command with --submit --service <facilitator URL>` : "no deposit yet: deposit one of two ways (shinjuku-wallet help deposit). 1) The more private path, shinjuku-wallet deposit --relay: no SOL is needed; its first run prints a one-time address to fund with USDC from an exchange withdrawal or an outside privacy pool. 2) Send USDC and about 0.01 SOL to your solanaFeePayer address (printed by init), then run shinjuku-wallet deposit without --relay; that deposit edge is public. If this wallet only holds restored keys or receives payments, run balance --refresh");
|
|
119219
119219
|
}
|
|
119220
|
+
const valueRecords = records.filter((entry) => !["payment-proof", "privacy-cash", "add-funds"].includes(entry.type) && !(entry.type === "deposit" && (entry.phase === "pre-chain" || entry.phase === "void")));
|
|
119221
|
+
const landedDeposits = valueRecords.filter((entry) => entry.type === "deposit" && entry.phase === "done" && typeof entry.record?.receipt?.signature === "string" && entry.record.receipt.signature.length > 0 && canonicalAtomic(entry.record.amountAtomic));
|
|
119222
|
+
if (firstDepositEstimate && !snapshotRead?.unreadable && !state.restoredFromRecoveryText && landedDeposits.length > 0 && landedDeposits.length === valueRecords.length) {
|
|
119223
|
+
reasons.push("the first check of the pool history runs now; this number is your own deposit");
|
|
119224
|
+
return report("stale", sum2(landedDeposits.map((entry) => entry.record.amountAtomic)), refreshCommand(state));
|
|
119225
|
+
}
|
|
119220
119226
|
reasons.push(snapshotRead?.unreadable ? `the saved balance walk is unreadable (${snapshotRead.unreadable}); it is only a cache` : state.restoredFromRecoveryText && !couldHoldValue ? "this wallet was rebuilt from the recovery text (restore) and has no balance walk yet: its value is on chain, not in this file" : "this wallet has deposit or payment records but no balance walk yet");
|
|
119221
119227
|
return report("unknown", null, refreshCommand(state));
|
|
119222
119228
|
}
|
|
@@ -121947,7 +121953,8 @@ var CHAIN_RECHECK_MS = 6 * 60 * 6e4;
|
|
|
121947
121953
|
var MCP_POLL_LIMIT_MS = 3 * 6e4;
|
|
121948
121954
|
var firstCode5 = (error) => String(error?.message ?? error ?? "").split(/[\s:;(]/, 1)[0];
|
|
121949
121955
|
function createMoveScheduler({ session, underLease, log = () => {
|
|
121950
|
-
}, env = process.env,
|
|
121956
|
+
}, env = process.env, onSettled = () => {
|
|
121957
|
+
}, deps = {} }) {
|
|
121951
121958
|
const now = deps.now ?? Date.now;
|
|
121952
121959
|
const home = deps.home ?? setupHome(env);
|
|
121953
121960
|
const readConfig = deps.readConfig ?? (() => readSetupConfig(home));
|
|
@@ -121981,6 +121988,7 @@ function createMoveScheduler({ session, underLease, log = () => {
|
|
|
121981
121988
|
let interval;
|
|
121982
121989
|
let closed = false;
|
|
121983
121990
|
const failedAt = /* @__PURE__ */ new Map();
|
|
121991
|
+
const lastCredit = /* @__PURE__ */ new Map();
|
|
121984
121992
|
const leaseFor = (pool) => async (task) => {
|
|
121985
121993
|
if (resolve21(homeWalletPath(home, pool)) === sessionPath) return underLease(() => task());
|
|
121986
121994
|
let free;
|
|
@@ -122064,6 +122072,14 @@ function createMoveScheduler({ session, underLease, log = () => {
|
|
|
122064
122072
|
withTargetLease: leaseFor(move.to.pool)
|
|
122065
122073
|
});
|
|
122066
122074
|
log(`MCP_MOVE ${move.from.pool.slice(0, 8)} ${result.state}${result.code ? ` ${result.code}` : ""}`);
|
|
122075
|
+
const credit = (result.legs ?? []).map((leg) => leg?.creditTransaction).filter((signature) => typeof signature === "string" && signature).at(-1);
|
|
122076
|
+
if (credit && credit !== lastCredit.get(move.from.pool)) {
|
|
122077
|
+
lastCredit.set(move.from.pool, credit);
|
|
122078
|
+
try {
|
|
122079
|
+
onSettled(credit);
|
|
122080
|
+
} catch {
|
|
122081
|
+
}
|
|
122082
|
+
}
|
|
122067
122083
|
} catch (error) {
|
|
122068
122084
|
const code = firstCode5(error) || "wallet_move_leg_failed";
|
|
122069
122085
|
result = { state: code === "wallet_locked" ? "waiting" : "failed", code, fromPool: move.from.pool, toPool: move.to.pool };
|
|
@@ -122903,10 +122919,16 @@ var CARRY_WAIT_CODES = /* @__PURE__ */ new Set([
|
|
|
122903
122919
|
"wallet_locked"
|
|
122904
122920
|
]);
|
|
122905
122921
|
var carryRefusedForGood = (carry) => carry?.state === "refused" && !CARRY_WAIT_CODES.has(carry.code);
|
|
122906
|
-
function
|
|
122907
|
-
if (carry
|
|
122922
|
+
function pocketCarryReason(carry) {
|
|
122923
|
+
if (carry && CARRY_DONE.has(carry.state)) return { done: true, waits: false, code: null, reason: "" };
|
|
122924
|
+
if (carry?.state !== "refused") return { done: false, waits: true, code: null, reason: "the wallet has not finished its check of the pool switch" };
|
|
122908
122925
|
const code = String(carry.code ?? "");
|
|
122909
122926
|
const reason = code === "p03_pocket_carry_source_fill_pending" || code === "p03_pocket_carry_source_payment_pending" ? "a pocket top-up or a pocket payment is not final yet" : code === "wallet_locked" ? "another wallet command uses the old pool's wallet now" : CARRY_WAIT_CODES.has(code) ? "the wallet has not finished its check of the pool switch" : code === "p03_pocket_carry_target_not_empty" ? "the new pool's wallet already has pocket accounts of its own" : "the pocket records of the two wallets do not match";
|
|
122927
|
+
return { done: false, waits: CARRY_WAIT_CODES.has(code), code, reason };
|
|
122928
|
+
}
|
|
122929
|
+
function pocketCarryText(carry) {
|
|
122930
|
+
if (carry?.state !== "refused") return "";
|
|
122931
|
+
const { code, reason } = pocketCarryReason(carry);
|
|
122910
122932
|
if (CARRY_WAIT_CODES.has(code)) {
|
|
122911
122933
|
return ` Your pocket accounts stay in the old pool's records for now (${reason}). The money in them is safe. The wallet tries again by itself in a minute.`;
|
|
122912
122934
|
}
|
|
@@ -123136,7 +123158,9 @@ function createSuccessionScheduler(options) {
|
|
|
123136
123158
|
},
|
|
123137
123159
|
log = () => {
|
|
123138
123160
|
},
|
|
123139
|
-
carry = carryPocketBook
|
|
123161
|
+
carry = carryPocketBook,
|
|
123162
|
+
onSettled = () => {
|
|
123163
|
+
}
|
|
123140
123164
|
} = options;
|
|
123141
123165
|
const now = options.now ?? Date.now;
|
|
123142
123166
|
const randomInt9 = options.randomInt ?? cryptoRandomInt;
|
|
@@ -123331,6 +123355,12 @@ function createSuccessionScheduler(options) {
|
|
|
123331
123355
|
} catch {
|
|
123332
123356
|
}
|
|
123333
123357
|
}
|
|
123358
|
+
if (counts.legsDone > (job.legsDone ?? 0) && counts.transactions.length) {
|
|
123359
|
+
try {
|
|
123360
|
+
onSettled(counts.transactions.at(-1));
|
|
123361
|
+
} catch {
|
|
123362
|
+
}
|
|
123363
|
+
}
|
|
123334
123364
|
if (result.state === "moved") {
|
|
123335
123365
|
if ((prepared.extraAccounts ?? 0) > 0) return save2(store, job, { ...counts, attempts: 0, lastCode: void 0, nextTryAtMs: now() });
|
|
123336
123366
|
return save2(store, job, { ...counts, state: "moved", attempts: 0, lastCode: void 0, nextTryAtMs: void 0 });
|
|
@@ -123533,11 +123563,30 @@ function createSuccessionScheduler(options) {
|
|
|
123533
123563
|
}
|
|
123534
123564
|
return views;
|
|
123535
123565
|
}
|
|
123566
|
+
function pocketCarries() {
|
|
123567
|
+
const carries = [];
|
|
123568
|
+
for (const entry of listEntries()) {
|
|
123569
|
+
let job;
|
|
123570
|
+
try {
|
|
123571
|
+
job = readSuccessionJob(storeOf(entry.from), entry.from);
|
|
123572
|
+
} catch {
|
|
123573
|
+
job = void 0;
|
|
123574
|
+
}
|
|
123575
|
+
if (typeof job?.to !== "string") continue;
|
|
123576
|
+
carries.push({
|
|
123577
|
+
from: job.from,
|
|
123578
|
+
to: job.to,
|
|
123579
|
+
pocketCarry: job.pocketCarry ? { state: job.pocketCarry.state, code: job.pocketCarry.code ?? null } : null
|
|
123580
|
+
});
|
|
123581
|
+
}
|
|
123582
|
+
return carries;
|
|
123583
|
+
}
|
|
123536
123584
|
return Object.freeze({
|
|
123537
123585
|
tick,
|
|
123538
123586
|
beforePay,
|
|
123539
123587
|
status,
|
|
123540
123588
|
openJobs,
|
|
123589
|
+
pocketCarries,
|
|
123541
123590
|
running: () => Boolean(active),
|
|
123542
123591
|
acknowledge(from, state) {
|
|
123543
123592
|
try {
|
|
@@ -123572,6 +123621,7 @@ function startSuccessionScheduler({ store, openStore, session, underLease, log =
|
|
|
123572
123621
|
status: () => [],
|
|
123573
123622
|
acknowledge: () => false,
|
|
123574
123623
|
openJobs: () => [],
|
|
123624
|
+
pocketCarries: () => [],
|
|
123575
123625
|
running: () => false
|
|
123576
123626
|
});
|
|
123577
123627
|
}
|
|
@@ -125228,6 +125278,7 @@ async function runUnshield({
|
|
|
125228
125278
|
return { selfPayTransaction: paid.transaction ?? null, exitTransaction: exit.signature ?? null };
|
|
125229
125279
|
}
|
|
125230
125280
|
var BALANCE_REFRESH_WAIT_MS = 2e4;
|
|
125281
|
+
var BALANCE_REFRESH_GRACE_MS = 2e3;
|
|
125231
125282
|
function movingAtomic(store) {
|
|
125232
125283
|
let moving = 0n;
|
|
125233
125284
|
try {
|
|
@@ -125282,6 +125333,9 @@ function localBalanceOf(store) {
|
|
|
125282
125333
|
var CAP_BALANCE_WAIT_MS = 35e3;
|
|
125283
125334
|
var CAP_BALANCE_RETRY_MS = 5e3;
|
|
125284
125335
|
var REFRESH_RETRY_MS = 6e4;
|
|
125336
|
+
var FINALITY_POLL_MS = 2e3;
|
|
125337
|
+
var FINALITY_WAIT_MS = 6e4;
|
|
125338
|
+
var PUBLIC_READ_ANSWER_MS = 3e3;
|
|
125285
125339
|
var SWITCH_WAIT_MS = 4e4;
|
|
125286
125340
|
var ELICIT_TIMEOUT_MS = 5 * 6e4;
|
|
125287
125341
|
var POLL_SECONDS2 = 30;
|
|
@@ -125346,7 +125400,7 @@ function createWalletTools({
|
|
|
125346
125400
|
deps: ops.autoPockets ?? {}
|
|
125347
125401
|
});
|
|
125348
125402
|
if (money.autoPockets === true) autoPockets.start();
|
|
125349
|
-
const mover = createMoveScheduler({ session, underLease, log, deps: ops.move && typeof ops.move === "object" ? ops.move : {} });
|
|
125403
|
+
const mover = createMoveScheduler({ session, underLease, log, onSettled: refreshAtFinality, deps: ops.move && typeof ops.move === "object" ? ops.move : {} });
|
|
125350
125404
|
if (ops.move !== false) mover.start();
|
|
125351
125405
|
const succession = ops.succession === false ? void 0 : {
|
|
125352
125406
|
successionStatus,
|
|
@@ -125452,7 +125506,9 @@ function createWalletTools({
|
|
|
125452
125506
|
...eta === void 0 ? {} : { etaSeconds: eta },
|
|
125453
125507
|
...Number.isInteger(item.legsTotal) ? { legsDone: Number.isInteger(item.legsDone) ? item.legsDone : 0, legsTotal: item.legsTotal } : {},
|
|
125454
125508
|
...typeof item.lastCode === "string" && item.lastCode ? { code: item.lastCode } : {},
|
|
125455
|
-
...Number.isFinite(item.updatedAtMs) ? { updatedAt: new Date(item.updatedAtMs).toISOString() } : {}
|
|
125509
|
+
...Number.isFinite(item.updatedAtMs) ? { updatedAt: new Date(item.updatedAtMs).toISOString() } : {},
|
|
125510
|
+
// The pocket book carry (scheduler.mjs carryPockets): a refused carry keeps the pockets in the old pool's records.
|
|
125511
|
+
...item.pocketCarry && typeof item.pocketCarry.state === "string" ? { pocketCarry: { state: item.pocketCarry.state, code: typeof item.pocketCarry.code === "string" ? item.pocketCarry.code : null } } : {}
|
|
125456
125512
|
};
|
|
125457
125513
|
});
|
|
125458
125514
|
};
|
|
@@ -125478,6 +125534,51 @@ function createWalletTools({
|
|
|
125478
125534
|
}
|
|
125479
125535
|
return refreshRun;
|
|
125480
125536
|
}
|
|
125537
|
+
let finalityWait;
|
|
125538
|
+
let finalityTarget;
|
|
125539
|
+
let finalityDeadline = 0;
|
|
125540
|
+
let finalityClosed = false;
|
|
125541
|
+
const finalityPollMs = ops.finalityPollMs ?? FINALITY_POLL_MS;
|
|
125542
|
+
const finalityWaitMs = ops.finalityWaitMs ?? FINALITY_WAIT_MS;
|
|
125543
|
+
function refreshAtFinality(signature) {
|
|
125544
|
+
if (typeof signature !== "string" || !signature || finalityClosed) return;
|
|
125545
|
+
finalityTarget = signature;
|
|
125546
|
+
finalityDeadline = Date.now() + finalityWaitMs;
|
|
125547
|
+
if (finalityWait) return;
|
|
125548
|
+
const statuses = ops.signatureStatuses ?? ((signatures) => session.connection.getSignatureStatuses(signatures));
|
|
125549
|
+
finalityWait = (async () => {
|
|
125550
|
+
for (; ; ) {
|
|
125551
|
+
const watched = finalityTarget;
|
|
125552
|
+
let status;
|
|
125553
|
+
try {
|
|
125554
|
+
status = (await statuses([watched]))?.value?.[0] ?? void 0;
|
|
125555
|
+
} catch {
|
|
125556
|
+
status = void 0;
|
|
125557
|
+
}
|
|
125558
|
+
if (finalityClosed) return;
|
|
125559
|
+
if (watched === finalityTarget && status?.err) {
|
|
125560
|
+
log("MCP_FINALITY_WAIT_FAILED_TRANSACTION");
|
|
125561
|
+
return;
|
|
125562
|
+
}
|
|
125563
|
+
if (watched === finalityTarget && status?.confirmationStatus === "finalized") {
|
|
125564
|
+
log("MCP_FINALITY_REFRESH");
|
|
125565
|
+
await refreshShared().catch(() => {
|
|
125566
|
+
});
|
|
125567
|
+
return;
|
|
125568
|
+
}
|
|
125569
|
+
if (Date.now() + finalityPollMs > finalityDeadline) {
|
|
125570
|
+
log("MCP_FINALITY_WAIT_EXPIRED");
|
|
125571
|
+
return;
|
|
125572
|
+
}
|
|
125573
|
+
await new Promise((resolve38) => {
|
|
125574
|
+
const timer = setTimeout(resolve38, finalityPollMs);
|
|
125575
|
+
timer.unref?.();
|
|
125576
|
+
});
|
|
125577
|
+
}
|
|
125578
|
+
})().finally(() => {
|
|
125579
|
+
finalityWait = void 0;
|
|
125580
|
+
});
|
|
125581
|
+
}
|
|
125481
125582
|
async function refreshIfStale() {
|
|
125482
125583
|
let stale;
|
|
125483
125584
|
try {
|
|
@@ -125760,6 +125861,7 @@ function createWalletTools({
|
|
|
125760
125861
|
const floatPaid = float?.state === "receipt";
|
|
125761
125862
|
const amounts = floatPaid ? { priceAtomic: float.priceAtomic, feeAtomic: float.feeAtomic, amountAtomic: float.paidAtomic } : { priceAtomic: receipt.amountAtomic ?? null, feeAtomic: "0", amountAtomic: receipt.amountAtomic ?? null };
|
|
125762
125863
|
const one = paidStore ? localBalanceOf(paidStore) : null;
|
|
125864
|
+
if (receipt.replayed !== true) refreshAtFinality(floatPaid ? float.floatSettleTransaction : transaction);
|
|
125763
125865
|
mark("mcp-result");
|
|
125764
125866
|
return answerResult(paidAnswerContent({
|
|
125765
125867
|
status: response.status,
|
|
@@ -125886,21 +125988,23 @@ function createWalletTools({
|
|
|
125886
125988
|
);
|
|
125887
125989
|
}
|
|
125888
125990
|
const publicRead = withTimeout((ops.readPublicBalance ?? readOwnPublicBalance)({ session, store }), PUBLIC_READ_TIMEOUT_MS).then((read2) => ({ read: read2 }), (error2) => ({ error: error2 }));
|
|
125889
|
-
let report = computeBalance({ store, snapshotRead: readBalanceSnapshot(store), source: "local" });
|
|
125991
|
+
let report = computeBalance({ store, snapshotRead: readBalanceSnapshot(store), source: "local", firstDepositEstimate: true });
|
|
125890
125992
|
let refresh = {};
|
|
125891
125993
|
const recentlyFailed = refreshFailedAt && Date.now() - refreshFailedAt < REFRESH_RETRY_MS && !refreshRun;
|
|
125892
125994
|
if (report.split?.shieldedAtomic != null && report.status === "stale") {
|
|
125893
|
-
if (!recentlyFailed) refreshShared().catch(() => {
|
|
125995
|
+
if (!recentlyFailed && !finalityWait) refreshShared().catch(() => {
|
|
125894
125996
|
});
|
|
125895
125997
|
refresh = { refreshing: true };
|
|
125896
125998
|
} else if (report.split?.shieldedAtomic == null && recentlyFailed) {
|
|
125897
125999
|
refresh = { refreshed: false, refreshError: refreshFailedCode ?? "mcp_refresh_failed" };
|
|
125898
126000
|
} else if (report.split?.shieldedAtomic == null) {
|
|
125899
126001
|
const run5 = refreshShared().then(() => "done", (error2) => ({ failed: errorCode2(error2, "mcp_refresh_failed") }));
|
|
125900
|
-
const
|
|
125901
|
-
const timer = setTimeout(() => resolve38("waiting"),
|
|
126002
|
+
const waitFor = (ms) => Promise.race([run5, new Promise((resolve38) => {
|
|
126003
|
+
const timer = setTimeout(() => resolve38("waiting"), ms);
|
|
125902
126004
|
timer.unref?.();
|
|
125903
126005
|
})]);
|
|
126006
|
+
let outcome = await waitFor(balanceRefreshWaitMs);
|
|
126007
|
+
if (outcome === "waiting") outcome = await waitFor(BALANCE_REFRESH_GRACE_MS);
|
|
125904
126008
|
if (outcome === "done") {
|
|
125905
126009
|
try {
|
|
125906
126010
|
store = session.openStore();
|
|
@@ -125914,9 +126018,28 @@ function createWalletTools({
|
|
|
125914
126018
|
refresh = { refreshed: false, refreshError: outcome.failed };
|
|
125915
126019
|
}
|
|
125916
126020
|
}
|
|
125917
|
-
const
|
|
126021
|
+
const answered = await Promise.race([
|
|
126022
|
+
publicRead,
|
|
126023
|
+
new Promise((resolve38) => {
|
|
126024
|
+
const timer = setTimeout(() => resolve38({ reading: true }), PUBLIC_READ_ANSWER_MS);
|
|
126025
|
+
timer.unref?.();
|
|
126026
|
+
})
|
|
126027
|
+
]);
|
|
126028
|
+
if (answered.reading) {
|
|
126029
|
+
publicRead.then(({ error: late2 }) => {
|
|
126030
|
+
if (late2) log(`MCP_PUBLIC_READ_FAILED_LATE ${late2?.name ?? "Error"}`);
|
|
126031
|
+
});
|
|
126032
|
+
}
|
|
126033
|
+
const { read, error } = answered;
|
|
125918
126034
|
let unshielded;
|
|
125919
|
-
if (
|
|
126035
|
+
if (answered.reading) {
|
|
126036
|
+
unshielded = {
|
|
126037
|
+
unshieldedAtomic: null,
|
|
126038
|
+
unshielded: null,
|
|
126039
|
+
unshieldedSolLamports: null,
|
|
126040
|
+
unshieldedReason: "reading: the RPC read of the wallet's own USDC account did not answer in 3 s; the shielded balance above does not wait for it. Call wallet_balance again later"
|
|
126041
|
+
};
|
|
126042
|
+
} else if (read) {
|
|
125920
126043
|
unshielded = {
|
|
125921
126044
|
unshieldedAtomic: read.unshieldedAtomic,
|
|
125922
126045
|
unshielded: formatAtomic(BigInt(read.unshieldedAtomic), Number(store.state.decimals)),
|
|
@@ -126620,6 +126743,7 @@ function createWalletTools({
|
|
|
126620
126743
|
job.result = result;
|
|
126621
126744
|
log(`MCP_${kind.toUpperCase()}_DONE requestId=${job.requestId}`);
|
|
126622
126745
|
if (kind !== "unshield") afterShield(job);
|
|
126746
|
+
else refreshAtFinality(result?.exitTransaction ?? result?.selfPayTransaction);
|
|
126623
126747
|
}, (error) => {
|
|
126624
126748
|
job.failedStage = job.stage;
|
|
126625
126749
|
job.state = "failed";
|
|
@@ -126853,7 +126977,7 @@ function createWalletTools({
|
|
|
126853
126977
|
const moveStatus = {
|
|
126854
126978
|
name: "wallet_move_status",
|
|
126855
126979
|
title: "Pool switch status",
|
|
126856
|
-
description: "Use this when the user asks why their balance moved, whether the pool switch is done, or when an answer shows poolSwitch, or when wallet_balance shows movingAtomic or pools. When the facilitator switches to a new pool, this wallet moves the whole balance there by itself (no fee, no step by the user); poolSwitches lists each switch with its state (pending, scheduled, running, done, failed) and a plain message to tell the user. Also called wallet_pool_switch_status. When the facilitator retires a pool, this wallet moves its whole balance from the old pool to the new one by itself (no fee, no step by the user): each leg pays one account of the old pool to the facilitator, which credits the same amount to a one-time address of this wallet in the new pool. This tool reads the move's state and every leg (amountAtomic, state planned|paid|credited|done|failed, moveId); it pays nothing and signs nothing. state: none (no move announced), waiting or running (it continues by itself), done, failed (code, detail, and next say why and what to do).",
|
|
126980
|
+
description: "Use this when the user asks why their balance moved, whether the pool switch is done, or when an answer shows poolSwitch, or when wallet_balance shows movingAtomic or pools. When the facilitator switches to a new pool, this wallet moves the whole balance there by itself (no fee, no step by the user); poolSwitches lists each switch with its state (pending, scheduled, running, done, failed) and a plain message to tell the user, plus pocketCarry when the wallet tried to move the old pool's pocket records to the new pool (state carried, completed, already, none, or refused with a code; the message says what a refusal means). Also called wallet_pool_switch_status. When the facilitator retires a pool, this wallet moves its whole balance from the old pool to the new one by itself (no fee, no step by the user): each leg pays one account of the old pool to the facilitator, which credits the same amount to a one-time address of this wallet in the new pool. This tool reads the move's state and every leg (amountAtomic, state planned|paid|credited|done|failed, moveId); it pays nothing and signs nothing. state: none (no move announced), waiting or running (it continues by itself), done, failed (code, detail, and next say why and what to do).",
|
|
126857
126981
|
inputSchema: { type: "object", properties: {}, additionalProperties: false },
|
|
126858
126982
|
annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: true },
|
|
126859
126983
|
async run() {
|
|
@@ -126881,6 +127005,7 @@ function createWalletTools({
|
|
|
126881
127005
|
};
|
|
126882
127006
|
Object.defineProperties(tools, {
|
|
126883
127007
|
close: { value: () => {
|
|
127008
|
+
finalityClosed = true;
|
|
126884
127009
|
autoPockets.close();
|
|
126885
127010
|
mover.close();
|
|
126886
127011
|
adopter.close();
|
|
@@ -126891,7 +127016,14 @@ function createWalletTools({
|
|
|
126891
127016
|
startSuccession: { value: () => {
|
|
126892
127017
|
if (!succession || successionHandle) return;
|
|
126893
127018
|
try {
|
|
126894
|
-
successionHandle = succession.startSuccessionScheduler({
|
|
127019
|
+
successionHandle = succession.startSuccessionScheduler({
|
|
127020
|
+
store: session.openStore(),
|
|
127021
|
+
openStore: () => session.openStore(),
|
|
127022
|
+
session,
|
|
127023
|
+
underLease,
|
|
127024
|
+
log,
|
|
127025
|
+
deps: { onSettled: refreshAtFinality }
|
|
127026
|
+
});
|
|
126895
127027
|
} catch (error) {
|
|
126896
127028
|
log(`MCP_POOL_SWITCH_SCHEDULER_NOT_STARTED: ${error?.name ?? "Error"}`);
|
|
126897
127029
|
}
|
|
@@ -132516,6 +132648,55 @@ async function spendGate(args, values, deps, io, { amountAtomic, again }) {
|
|
|
132516
132648
|
if (!followed || index < 0 || resolve37(followed) === walletFile) return args;
|
|
132517
132649
|
return [...args.slice(0, index + 1), followed, ...args.slice(index + 2)];
|
|
132518
132650
|
}
|
|
132651
|
+
async function pocketFillGate(args, values, deps, io) {
|
|
132652
|
+
if (!values.has("--wallet") || values.has("--dwell-check")) return args;
|
|
132653
|
+
const walletFile = resolve37(values.get("--wallet"));
|
|
132654
|
+
const session = lazySpendSession(walletFile, values, deps);
|
|
132655
|
+
let handle;
|
|
132656
|
+
try {
|
|
132657
|
+
handle = (deps.startSuccessionScheduler ?? startSuccessionScheduler)({
|
|
132658
|
+
session,
|
|
132659
|
+
openStore: () => session.openStore(),
|
|
132660
|
+
underLease: sessionLease(session),
|
|
132661
|
+
log: () => {
|
|
132662
|
+
},
|
|
132663
|
+
env: deps.env
|
|
132664
|
+
});
|
|
132665
|
+
} catch {
|
|
132666
|
+
return args;
|
|
132667
|
+
}
|
|
132668
|
+
let carries;
|
|
132669
|
+
try {
|
|
132670
|
+
await Promise.resolve(handle.tick?.()).catch(() => {
|
|
132671
|
+
});
|
|
132672
|
+
carries = handle.pocketCarries?.() ?? [];
|
|
132673
|
+
} catch {
|
|
132674
|
+
carries = [];
|
|
132675
|
+
} finally {
|
|
132676
|
+
handle.stop?.();
|
|
132677
|
+
}
|
|
132678
|
+
if (!carries.length) return args;
|
|
132679
|
+
const home = setupHome(deps.env);
|
|
132680
|
+
const pathOf = (pool) => resolve37(homeWalletPath(home, pool));
|
|
132681
|
+
let target = walletFile;
|
|
132682
|
+
for (let hop = 0; hop < carries.length; hop += 1) {
|
|
132683
|
+
const next = carries.find((item) => pathOf(item.from) === target && existsSync(pathOf(item.to)));
|
|
132684
|
+
if (!next) break;
|
|
132685
|
+
target = pathOf(next.to);
|
|
132686
|
+
}
|
|
132687
|
+
for (const item of carries.filter((entry) => pathOf(entry.to) === target)) {
|
|
132688
|
+
const carry = pocketCarryReason(item.pocketCarry);
|
|
132689
|
+
if (carry.done) continue;
|
|
132690
|
+
if (carry.waits) {
|
|
132691
|
+
throw new PublicFailure(`wallet_pool_switch_wait_retry_same_request: Your facilitator switched to a new pool, and your pocket records are not in the new pool's wallet yet (${carry.reason}). Your pockets and the money in them are safe; nothing was filled or signed. Run the same pocket fill command again in 60 s`);
|
|
132692
|
+
}
|
|
132693
|
+
throw new PublicFailure(`wallet_pool_switch_failed: Your facilitator switched to a new pool, and the wallet could not move your pocket records to the new pool's wallet (${carry.reason}). Your pockets and the money in them are safe; nothing was filled or signed. Tell the operator this code. lastCode: ${carry.code}`);
|
|
132694
|
+
}
|
|
132695
|
+
if (target === walletFile) return args;
|
|
132696
|
+
io.err("pool switch: pocket fill uses your wallet of the facilitator's new pool\n");
|
|
132697
|
+
const index = args.indexOf("--wallet");
|
|
132698
|
+
return index < 0 ? args : [...args.slice(0, index + 1), target, ...args.slice(index + 2)];
|
|
132699
|
+
}
|
|
132519
132700
|
async function runCurl(values, deps) {
|
|
132520
132701
|
const io = deps.io;
|
|
132521
132702
|
const policy = createSpendPolicy({
|
|
@@ -133864,7 +134045,7 @@ var COMMANDS = [
|
|
|
133864
134045
|
}
|
|
133865
134046
|
}
|
|
133866
134047
|
},
|
|
133867
|
-
run: (args, values, deps) => deps.pocketMain(["fill", ...args])
|
|
134048
|
+
run: async (args, values, deps, io) => deps.pocketMain(["fill", ...await pocketFillGate(args, values, deps, io)])
|
|
133868
134049
|
},
|
|
133869
134050
|
{
|
|
133870
134051
|
name: "pocket release",
|