shinjuku-shielded 0.3.15 → 0.3.16
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 +42 -8
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": "b32bffc727e1e7e33fb134a3918638006259033511e1a2aaf455d037da1f70b3",
|
|
5
|
+
"bytes": 11124201,
|
|
6
|
+
"sourceCommit": "4b3c69bd892409a11b931e3a01f254a8b2f4af0f",
|
|
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.16",
|
|
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": "b32bffc7",
|
|
7
|
+
"shinjukuSha256": "b32bffc727e1e7e33fb134a3918638006259033511e1a2aaf455d037da1f70b3",
|
|
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
|
@@ -118735,6 +118735,8 @@ function snapshotFromRecovery({ state, programId, recovery, history, walStates,
|
|
|
118735
118735
|
});
|
|
118736
118736
|
const slot3 = history?.finalizedPoolSnapshot?.slot;
|
|
118737
118737
|
if (slot3 === void 0 || !canonicalAtomic(String(slot3))) throw new Error("balance_snapshot_slot_invalid");
|
|
118738
|
+
const anchorIndexes = Array.isArray(history?.finalizedPoolSnapshot?.anchors) ? history.finalizedPoolSnapshot.anchors.map((anchor) => BigInt(anchor.index)) : [];
|
|
118739
|
+
const anchorIndex = anchorIndexes.length ? anchorIndexes.reduce((a, b) => b > a ? b : a).toString() : void 0;
|
|
118738
118740
|
return {
|
|
118739
118741
|
schema: BALANCE_SNAPSHOT_SCHEMA,
|
|
118740
118742
|
pool: state.pool,
|
|
@@ -118742,6 +118744,7 @@ function snapshotFromRecovery({ state, programId, recovery, history, walStates,
|
|
|
118742
118744
|
refreshedAt: new Date(now).toISOString(),
|
|
118743
118745
|
slot: String(slot3),
|
|
118744
118746
|
poolIndex: String(recovery.poolIndex),
|
|
118747
|
+
...anchorIndex === void 0 ? {} : { anchorIndex },
|
|
118745
118748
|
fresh: fresh === true,
|
|
118746
118749
|
walStates: { ...walStates },
|
|
118747
118750
|
outputs
|
|
@@ -119021,7 +119024,8 @@ function computeBalance({ store, snapshotRead, source = "local", now = Date.now(
|
|
|
119021
119024
|
const reservedAtomic = unknownInputs ? unspentAtomic : sum2([...reserved].filter((commitment) => unspent.has(commitment)).map((commitment) => unspent.get(commitment).valueAtomic));
|
|
119022
119025
|
detail.reservedAtomic = reservedAtomic.toString();
|
|
119023
119026
|
const spendable = unspentAtomic - reservedAtomic;
|
|
119024
|
-
|
|
119027
|
+
const anchorIndex = canonicalAtomic(snapshot.anchorIndex) ? BigInt(snapshot.anchorIndex) : void 0;
|
|
119028
|
+
detail.fundedAccounts = unknownInputs ? 0 : [...unspent.values()].filter((output2) => output2.kind === "account" && BigInt(output2.valueAtomic) > 0n && !reserved.has(output2.commitment) && (anchorIndex === void 0 || BigInt(output2.leafIndex) < anchorIndex)).length;
|
|
119025
119029
|
const next = detail.inFlight.length ? "finish or cancel the work in detail.inFlight; the wallet runs one payment at a time" : pendingDeposits.length ? `deposit ${pendingDeposits[0].depositId} is not finished: rerun the same deposit command with --submit --service <facilitator URL>` : pocketsUnscanned ? scanPockets2 : unspentAtomic === 0n && successionMovableAtomic > 0n ? "this pool was succeeded by a new pool: its value moves there (a move per account, the facilitator pays the fee) and counts in this balance until then" : unspentAtomic === 0n ? "nothing to spend: deposit (shinjuku-wallet help deposit), or run balance --refresh if a payment to this wallet settled" : void 0;
|
|
119026
119030
|
return report("current", spendable + successionMovableAtomic, next);
|
|
119027
119031
|
}
|
|
@@ -124142,6 +124146,7 @@ function writeCache(key, record, ctx) {
|
|
|
124142
124146
|
// wallet/src/mcp/tools.mjs
|
|
124143
124147
|
init_pool_denomination();
|
|
124144
124148
|
init_serviceUrl();
|
|
124149
|
+
init_anchorClock();
|
|
124145
124150
|
var shownCaps = (caps) => Object.fromEntries(Object.entries(caps).map(([name, value]) => [name, String(value) === NO_LIMIT_ATOMIC2 ? "none" : value]));
|
|
124146
124151
|
var RESOURCE_PAYMENT_WAL_PREFIX2 = "resource-payment-";
|
|
124147
124152
|
var SELF_PAY_ORIGIN3 = "https://self-pay.invalid/";
|
|
@@ -124714,6 +124719,8 @@ function localBalance(session) {
|
|
|
124714
124719
|
return null;
|
|
124715
124720
|
}
|
|
124716
124721
|
}
|
|
124722
|
+
var CAP_BALANCE_WAIT_MS = 35e3;
|
|
124723
|
+
var CAP_BALANCE_RETRY_MS = 5e3;
|
|
124717
124724
|
var REFRESH_RETRY_MS = 6e4;
|
|
124718
124725
|
var SWITCH_WAIT_MS = 4e4;
|
|
124719
124726
|
var ELICIT_TIMEOUT_MS = 5 * 6e4;
|
|
@@ -124730,7 +124737,9 @@ function createWalletTools({
|
|
|
124730
124737
|
client,
|
|
124731
124738
|
exportBackup,
|
|
124732
124739
|
balanceRefreshWaitMs = BALANCE_REFRESH_WAIT_MS,
|
|
124733
|
-
elicitTimeoutMs = ELICIT_TIMEOUT_MS
|
|
124740
|
+
elicitTimeoutMs = ELICIT_TIMEOUT_MS,
|
|
124741
|
+
capBalanceWaitMs = CAP_BALANCE_WAIT_MS,
|
|
124742
|
+
capBalanceRetryMs = CAP_BALANCE_RETRY_MS
|
|
124734
124743
|
}) {
|
|
124735
124744
|
const outDir = join26(dirname23(session.walletPath), "mcp-out");
|
|
124736
124745
|
const knownIds = /* @__PURE__ */ new Map();
|
|
@@ -125564,6 +125573,19 @@ function createWalletTools({
|
|
|
125564
125573
|
const again = (kind, job) => `call ${KINDS[kind].tool} again with request_id "${job.requestId}", amount_atomic "${job.amountAtomic}"${job.to ? `, and to "${job.to}"` : ""}`;
|
|
125565
125574
|
const unboundNext = (requestId, amountAtomic) => `Nothing was signed. Do not retry this request_id. Tell your owner: the self-payment of this unshield has no recipient bound to it, so this server will not choose one. The owner finishes it with the CLI: shinjuku-wallet unshield (the same --wallet, proof tools, --profile, --program, --facilitator) --unshield-id ${moneyId(requestId)} --amount ${amountAtomic} --to <recipient USDC account> --recipient-owner <recipient owner>`;
|
|
125566
125575
|
const preApproved = () => [...new Set(unshieldTo)];
|
|
125576
|
+
async function anchorWaitAfterDeposit() {
|
|
125577
|
+
try {
|
|
125578
|
+
const read = await underLease((store) => readBalanceSnapshot(store));
|
|
125579
|
+
const anchorIndex = read.snapshot?.anchorIndex;
|
|
125580
|
+
if (anchorIndex === void 0) return {};
|
|
125581
|
+
const waiting = read.snapshot.outputs.some((output2) => output2.kind === "account" && output2.spendStatus === "unspent" && BigInt(output2.leafIndex) >= BigInt(anchorIndex));
|
|
125582
|
+
if (!waiting) return {};
|
|
125583
|
+
noteAnchorOrigin(session.memoServiceUrl);
|
|
125584
|
+
return { spendableAtMs: Date.now() + nextAnchorWaitMs(Date.now(), 0) };
|
|
125585
|
+
} catch {
|
|
125586
|
+
return {};
|
|
125587
|
+
}
|
|
125588
|
+
}
|
|
125567
125589
|
function doneNext(kind, job) {
|
|
125568
125590
|
if (kind === "unshield") {
|
|
125569
125591
|
return `the USDC was sent to ${job.to}; tell the user (exitTransaction). wallet_balance shows the new shielded balance${job.result?.backupPath ? `. An encrypted backup of the wallet was saved at ${job.result.backupPath}` : ""}`;
|
|
@@ -125573,6 +125595,9 @@ function createWalletTools({
|
|
|
125573
125595
|
return `the deposit landed. The wallet now reads it from the chain so it becomes spendable: call wallet_balance in ${POLL_SECONDS2} s (x402_pay and wallet_unshield also wait for it by themselves)`;
|
|
125574
125596
|
}
|
|
125575
125597
|
if (!post.refreshed) return `the deposit landed; reading it from the chain failed (${post.refreshError}): call wallet_balance in a minute, it retries by itself`;
|
|
125598
|
+
if (post.spendableAtMs !== void 0 && post.spendableAtMs > Date.now()) {
|
|
125599
|
+
return `the deposit landed and is in the shielded balance. It is spendable after the next pool anchor, in about ${Math.ceil((post.spendableAtMs - Date.now()) / 1e3)} s: x402_pay and wallet_unshield wait for it by themselves, so call them now if the user wants to${post.backupPath ? `. An encrypted backup of the wallet was saved at ${post.backupPath}` : ""}`;
|
|
125600
|
+
}
|
|
125576
125601
|
return `the deposit landed and is in the shielded balance: x402_pay and wallet_unshield can spend it now${post.backupPath ? `. An encrypted backup of the wallet was saved at ${post.backupPath}` : ""}`;
|
|
125577
125602
|
}
|
|
125578
125603
|
const ELSEWHERE_PRIVACY = "the chain shows the other wallet paying this new one-time address, and that address depositing this amount into the pool (both public; the facilitator also sees the amount and time). Later payments from the shielded balance do not show which deposit paid them. With few depositors in the pool, an amount few other deposits share, or a payment soon after the deposit, is easier to pair";
|
|
@@ -125899,13 +125924,19 @@ function createWalletTools({
|
|
|
125899
125924
|
} catch {
|
|
125900
125925
|
stale = true;
|
|
125901
125926
|
}
|
|
125902
|
-
|
|
125903
|
-
|
|
125904
|
-
const
|
|
125905
|
-
|
|
125927
|
+
let one = stale ? null : localBalance(session);
|
|
125928
|
+
const unknown = () => one?.balanceAtomic === null || one?.balanceAtomic === void 0;
|
|
125929
|
+
for (const deadline = Date.now() + capBalanceWaitMs; unknown(); ) {
|
|
125930
|
+
await refreshShared().catch(() => {
|
|
125931
|
+
});
|
|
125932
|
+
one = localBalance(session);
|
|
125933
|
+
if (!unknown() || Date.now() + capBalanceRetryMs > deadline) break;
|
|
125934
|
+
await new Promise((resolve36) => setTimeout(resolve36, capBalanceRetryMs));
|
|
125935
|
+
}
|
|
125936
|
+
if (unknown()) {
|
|
125906
125937
|
return refuse9(
|
|
125907
125938
|
"mcp_balance_unknown",
|
|
125908
|
-
`the shielded balance could not be read just now (the chain read failed, or another wallet command holds this wallet), so the wallet cannot check the ${usdcText(MAX_SHIELDED_BALANCE_ATOMIC)} USDC balance cap; nothing was moved`,
|
|
125939
|
+
`the shielded balance could not be read just now (a payment from moments ago is not final yet, the chain read failed, or another wallet command holds this wallet), so the wallet cannot check the ${usdcText(MAX_SHIELDED_BALANCE_ATOMIC)} USDC balance cap; nothing was moved`,
|
|
125909
125940
|
`call ${spec.tool} again with the same request_id and amount_atomic in ${POLL_SECONDS2} s`,
|
|
125910
125941
|
{ requestId: request.requestId }
|
|
125911
125942
|
);
|
|
@@ -126041,7 +126072,10 @@ function createWalletTools({
|
|
|
126041
126072
|
}
|
|
126042
126073
|
function afterShield(job) {
|
|
126043
126074
|
job.post = { state: "running" };
|
|
126044
|
-
job.postPromise = refreshShared().then(
|
|
126075
|
+
job.postPromise = refreshShared().then(
|
|
126076
|
+
() => anchorWaitAfterDeposit().then((wait2) => ({ refreshed: true, ...wait2 })),
|
|
126077
|
+
(error) => ({ refreshed: false, refreshError: errorCode2(error, "mcp_refresh_failed") })
|
|
126078
|
+
).then((refresh) => underLease((store) => backupNow(store)).catch((error) => typeof exportBackup === "function" ? { backupPath: null, backupError: errorCode2(error, "wallet_locked") } : {}).then((backup) => {
|
|
126045
126079
|
job.post = { state: "done", ...refresh, ...backup };
|
|
126046
126080
|
})).finally(() => {
|
|
126047
126081
|
if (money.autoPockets === true) autoPockets.onShielded();
|