shinjuku-shielded 0.3.42 → 0.3.44
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 +405 -18
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": "99e5ce600a930373051d72e16b2fe75bec451cfbdd509439e58546d0e77058d2",
|
|
5
|
+
"bytes": 11247206,
|
|
6
|
+
"sourceCommit": "5a8c47eba8d07d89334e63f6467f17692e009d30",
|
|
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.44",
|
|
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": "99e5ce60",
|
|
7
|
+
"shinjukuSha256": "99e5ce600a930373051d72e16b2fe75bec451cfbdd509439e58546d0e77058d2",
|
|
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
|
@@ -96641,6 +96641,312 @@ var init_config = __esm({
|
|
|
96641
96641
|
}
|
|
96642
96642
|
});
|
|
96643
96643
|
|
|
96644
|
+
// wallet/src/seller/memoEcdhWorker.mjs
|
|
96645
|
+
import { Worker as Worker3 } from "node:worker_threads";
|
|
96646
|
+
function createMemoEcdhWorker(options) {
|
|
96647
|
+
const threads = Array.from({ length: WORKER_THREADS }, () => createThread(options));
|
|
96648
|
+
const compute = (memoBundle) => {
|
|
96649
|
+
const records = Math.floor(memoBundle.length / MEMO_RECORD_BYTES2);
|
|
96650
|
+
const share = Math.ceil(records / threads.length);
|
|
96651
|
+
const jobs = [];
|
|
96652
|
+
for (let index = 0; index < threads.length; index += 1) {
|
|
96653
|
+
const from = index * share;
|
|
96654
|
+
const to = Math.min(records, from + share);
|
|
96655
|
+
if (from >= to) continue;
|
|
96656
|
+
const job = threads[index].compute(memoBundle.subarray(from * MEMO_RECORD_BYTES2, to * MEMO_RECORD_BYTES2));
|
|
96657
|
+
if (job !== void 0) jobs.push(job);
|
|
96658
|
+
}
|
|
96659
|
+
if (jobs.length === 0) return void 0;
|
|
96660
|
+
const result = Promise.all(jobs.map((job) => job.result)).then((parts) => parts.flatMap((part) => part ?? [])).catch(() => void 0);
|
|
96661
|
+
return { result, cancel: () => {
|
|
96662
|
+
for (const job of jobs) job.cancel();
|
|
96663
|
+
} };
|
|
96664
|
+
};
|
|
96665
|
+
return {
|
|
96666
|
+
warm: () => {
|
|
96667
|
+
for (const thread of threads) thread.warm();
|
|
96668
|
+
},
|
|
96669
|
+
compute: (memoBundle) => {
|
|
96670
|
+
try {
|
|
96671
|
+
return compute(memoBundle);
|
|
96672
|
+
} catch {
|
|
96673
|
+
return void 0;
|
|
96674
|
+
}
|
|
96675
|
+
},
|
|
96676
|
+
close: () => {
|
|
96677
|
+
for (const thread of threads) thread.close();
|
|
96678
|
+
}
|
|
96679
|
+
};
|
|
96680
|
+
}
|
|
96681
|
+
function createThread({ scalar, curvePointFromX, sharedXOf, log }) {
|
|
96682
|
+
let worker;
|
|
96683
|
+
let verified = false;
|
|
96684
|
+
let disabled = false;
|
|
96685
|
+
let closed = false;
|
|
96686
|
+
let lastStartAt = -Infinity;
|
|
96687
|
+
let nextId = 1;
|
|
96688
|
+
const pending = /* @__PURE__ */ new Map();
|
|
96689
|
+
const say6 = (line) => {
|
|
96690
|
+
try {
|
|
96691
|
+
log(line);
|
|
96692
|
+
} catch {
|
|
96693
|
+
}
|
|
96694
|
+
};
|
|
96695
|
+
const settleAll = () => {
|
|
96696
|
+
for (const resolve38 of pending.values()) resolve38(void 0);
|
|
96697
|
+
pending.clear();
|
|
96698
|
+
};
|
|
96699
|
+
const drop = (current) => {
|
|
96700
|
+
if (worker !== current) return;
|
|
96701
|
+
worker = void 0;
|
|
96702
|
+
verified = false;
|
|
96703
|
+
settleAll();
|
|
96704
|
+
current.terminate().catch(() => void 0);
|
|
96705
|
+
};
|
|
96706
|
+
const post = (current, message) => {
|
|
96707
|
+
try {
|
|
96708
|
+
current.postMessage(message);
|
|
96709
|
+
return true;
|
|
96710
|
+
} catch {
|
|
96711
|
+
drop(current);
|
|
96712
|
+
return false;
|
|
96713
|
+
}
|
|
96714
|
+
};
|
|
96715
|
+
const start = () => {
|
|
96716
|
+
if (worker !== void 0 || disabled || closed || performance.now() - lastStartAt < WORKER_RESTART_MS) return;
|
|
96717
|
+
lastStartAt = performance.now();
|
|
96718
|
+
let current;
|
|
96719
|
+
let expected;
|
|
96720
|
+
try {
|
|
96721
|
+
const point = curvePointFromX(CHECK_X);
|
|
96722
|
+
expected = [point.x.toString(16), point.y.toString(16), sharedXOf(point).toString(16)].join(":");
|
|
96723
|
+
current = new Worker3(WORKER_SOURCE2, { eval: true, execArgv: [], workerData: { scalar: scalar.toString() } });
|
|
96724
|
+
} catch (error) {
|
|
96725
|
+
say6(`SELLER_MEMO_ECDH_WORKER_START_FAILED ${error?.name ?? "Error"}`);
|
|
96726
|
+
return;
|
|
96727
|
+
}
|
|
96728
|
+
worker = current;
|
|
96729
|
+
const checkId = nextId++;
|
|
96730
|
+
pending.set(checkId, (out) => {
|
|
96731
|
+
if (worker !== current) return;
|
|
96732
|
+
if (Array.isArray(out) && out.length === 1 && Array.isArray(out[0]) && out[0].join(":") === expected) {
|
|
96733
|
+
verified = true;
|
|
96734
|
+
return;
|
|
96735
|
+
}
|
|
96736
|
+
disabled = true;
|
|
96737
|
+
say6("SELLER_MEMO_ECDH_WORKER_CHECK_FAILED the intake computes in the scan for this process");
|
|
96738
|
+
drop(current);
|
|
96739
|
+
});
|
|
96740
|
+
current.on("message", (message) => {
|
|
96741
|
+
try {
|
|
96742
|
+
const resolve38 = pending.get(message?.id);
|
|
96743
|
+
if (resolve38 === void 0) return;
|
|
96744
|
+
pending.delete(message.id);
|
|
96745
|
+
resolve38(message.failed === true || !Array.isArray(message.out) ? void 0 : message.out);
|
|
96746
|
+
} catch {
|
|
96747
|
+
drop(current);
|
|
96748
|
+
}
|
|
96749
|
+
});
|
|
96750
|
+
current.on("error", (error) => {
|
|
96751
|
+
if (worker === current) say6(`SELLER_MEMO_ECDH_WORKER_FAILED ${error?.name ?? "Error"}`);
|
|
96752
|
+
drop(current);
|
|
96753
|
+
});
|
|
96754
|
+
current.on("messageerror", () => {
|
|
96755
|
+
drop(current);
|
|
96756
|
+
});
|
|
96757
|
+
current.on("exit", (code) => {
|
|
96758
|
+
if (worker === current && !closed) say6(`SELLER_MEMO_ECDH_WORKER_EXIT ${Number.isInteger(code) ? code : "?"}`);
|
|
96759
|
+
drop(current);
|
|
96760
|
+
});
|
|
96761
|
+
current.unref();
|
|
96762
|
+
post(current, { id: checkId, check: CHECK_X.toString() });
|
|
96763
|
+
};
|
|
96764
|
+
const compute = (memoBundle) => {
|
|
96765
|
+
start();
|
|
96766
|
+
const current = worker;
|
|
96767
|
+
if (current === void 0) return void 0;
|
|
96768
|
+
const id = nextId++;
|
|
96769
|
+
const result = new Promise((resolve38) => {
|
|
96770
|
+
pending.set(id, (out) => {
|
|
96771
|
+
if (!verified || worker !== current || !Array.isArray(out)) {
|
|
96772
|
+
resolve38(void 0);
|
|
96773
|
+
return;
|
|
96774
|
+
}
|
|
96775
|
+
try {
|
|
96776
|
+
resolve38(out.map((row) => {
|
|
96777
|
+
if (!Array.isArray(row) || row.length !== 3 || !row.every((part) => /^[0-9a-f]{1,64}$/.test(part))) throw new Error("row");
|
|
96778
|
+
return [`${BigInt(`0x${row[0]}`)}:${BigInt(`0x${row[1]}`)}`, BigInt(`0x${row[2]}`)];
|
|
96779
|
+
}));
|
|
96780
|
+
} catch {
|
|
96781
|
+
resolve38(void 0);
|
|
96782
|
+
}
|
|
96783
|
+
});
|
|
96784
|
+
}).catch(() => void 0);
|
|
96785
|
+
if (!post(current, { id, bundle: Uint8Array.from(memoBundle) })) return void 0;
|
|
96786
|
+
const cancel = () => {
|
|
96787
|
+
const resolve38 = pending.get(id);
|
|
96788
|
+
if (resolve38 === void 0) return;
|
|
96789
|
+
pending.delete(id);
|
|
96790
|
+
resolve38(void 0);
|
|
96791
|
+
if (worker === current) post(current, { cancel: id });
|
|
96792
|
+
};
|
|
96793
|
+
return { result, cancel };
|
|
96794
|
+
};
|
|
96795
|
+
return {
|
|
96796
|
+
warm: () => {
|
|
96797
|
+
try {
|
|
96798
|
+
start();
|
|
96799
|
+
} catch {
|
|
96800
|
+
}
|
|
96801
|
+
},
|
|
96802
|
+
compute: (memoBundle) => {
|
|
96803
|
+
try {
|
|
96804
|
+
return compute(memoBundle);
|
|
96805
|
+
} catch {
|
|
96806
|
+
return void 0;
|
|
96807
|
+
}
|
|
96808
|
+
},
|
|
96809
|
+
close: () => {
|
|
96810
|
+
closed = true;
|
|
96811
|
+
const current = worker;
|
|
96812
|
+
worker = void 0;
|
|
96813
|
+
settleAll();
|
|
96814
|
+
current?.terminate().catch(() => void 0);
|
|
96815
|
+
}
|
|
96816
|
+
};
|
|
96817
|
+
}
|
|
96818
|
+
var MEMO_RECORD_BYTES2, WORKER_RESTART_MS, WORKER_THREADS, CHECK_X, WORKER_SOURCE2;
|
|
96819
|
+
var init_memoEcdhWorker = __esm({
|
|
96820
|
+
"wallet/src/seller/memoEcdhWorker.mjs"() {
|
|
96821
|
+
"use strict";
|
|
96822
|
+
MEMO_RECORD_BYTES2 = 200;
|
|
96823
|
+
WORKER_RESTART_MS = 6e4;
|
|
96824
|
+
WORKER_THREADS = 2;
|
|
96825
|
+
CHECK_X = 5n;
|
|
96826
|
+
WORKER_SOURCE2 = `"use strict";
|
|
96827
|
+
const { parentPort, workerData } = require("node:worker_threads");
|
|
96828
|
+
const P = 21888242871839275222246405745257275088548364400416034343698204186575808495617n;
|
|
96829
|
+
const RECORD_BYTES = ${MEMO_RECORD_BYTES2};
|
|
96830
|
+
const SLICE_MS = 8;
|
|
96831
|
+
const mod = (value) => { const result = value % P; return result >= 0n ? result : result + P; };
|
|
96832
|
+
function powMod(baseInput, exponentInput) {
|
|
96833
|
+
let base = mod(baseInput); let exponent = exponentInput; let result = 1n;
|
|
96834
|
+
while (exponent > 0n) { if ((exponent & 1n) === 1n) result = mod(result * base); base = mod(base * base); exponent >>= 1n; }
|
|
96835
|
+
return result;
|
|
96836
|
+
}
|
|
96837
|
+
function inverse(value) {
|
|
96838
|
+
const normalized = mod(value);
|
|
96839
|
+
if (normalized === 0n) throw new Error();
|
|
96840
|
+
return powMod(normalized, P - 2n);
|
|
96841
|
+
}
|
|
96842
|
+
function inversePublic(value) {
|
|
96843
|
+
let x = mod(value);
|
|
96844
|
+
if (x === 0n) throw new Error();
|
|
96845
|
+
let y = P; let u = 1n; let v = 0n;
|
|
96846
|
+
while (x !== 0n) { const q = y / x; const r = y - q * x; y = x; x = r; const next = v - q * u; v = u; u = next; }
|
|
96847
|
+
return mod(v);
|
|
96848
|
+
}
|
|
96849
|
+
const D = mod(-168696n * inverse(168700n));
|
|
96850
|
+
const LEGENDRE = (P - 1n) / 2n;
|
|
96851
|
+
let SQ = P - 1n; let SS = 0n;
|
|
96852
|
+
while ((SQ & 1n) === 0n) { SQ >>= 1n; SS += 1n; }
|
|
96853
|
+
const NON_RESIDUE_POWER = (() => { let z = 2n; while (powMod(z, LEGENDRE) !== P - 1n) z += 1n; return powMod(z, SQ); })();
|
|
96854
|
+
function sqrt(value) {
|
|
96855
|
+
const normalized = mod(value);
|
|
96856
|
+
if (normalized === 0n) return 0n;
|
|
96857
|
+
const w = powMod(normalized, (SQ - 1n) / 2n);
|
|
96858
|
+
let t = mod(w * w * normalized);
|
|
96859
|
+
let legendre = t;
|
|
96860
|
+
for (let square = 1n; square < SS; square += 1n) legendre = mod(legendre * legendre);
|
|
96861
|
+
if (legendre !== 1n) return undefined;
|
|
96862
|
+
let m = SS; let c = NON_RESIDUE_POWER; let root = mod(w * normalized);
|
|
96863
|
+
while (t !== 1n) {
|
|
96864
|
+
let i = 1n; let squared = mod(t * t);
|
|
96865
|
+
while (squared !== 1n) { squared = mod(squared * squared); i += 1n; if (i >= m) throw new Error(); }
|
|
96866
|
+
const b = powMod(c, 1n << (m - i - 1n));
|
|
96867
|
+
root = mod(root * b); c = mod(b * b); t = mod(t * c); m = i;
|
|
96868
|
+
}
|
|
96869
|
+
return root;
|
|
96870
|
+
}
|
|
96871
|
+
function pointFromX(x) {
|
|
96872
|
+
if (x >= P) throw new Error();
|
|
96873
|
+
const x2 = mod(x * x);
|
|
96874
|
+
const denominator = mod(1n - D * x2);
|
|
96875
|
+
if (denominator === 0n) throw new Error();
|
|
96876
|
+
const y = sqrt(mod((x2 + 1n) * inversePublic(denominator)));
|
|
96877
|
+
if (y === undefined) throw new Error();
|
|
96878
|
+
return { x, y };
|
|
96879
|
+
}
|
|
96880
|
+
const toExtended = (point) => ({ x: point.x, y: point.y, t: mod(point.x * point.y), z: 1n });
|
|
96881
|
+
const toTable = (point) => ({ x: point.x, y: point.y, t: point.t, z: point.z, dt: mod(D * point.t) });
|
|
96882
|
+
function addTable(left, right) {
|
|
96883
|
+
const a = mod(left.x * right.x); const b = mod(left.y * right.y);
|
|
96884
|
+
const c = mod(left.t * right.dt); const d = mod(left.z * right.z);
|
|
96885
|
+
const h = b + a; const e = mod((left.x + left.y) * (right.x + right.y) - h);
|
|
96886
|
+
const f = d - c; const g = d + c;
|
|
96887
|
+
return { x: mod(e * f), y: mod(g * h), t: mod(e * h), z: mod(f * g) };
|
|
96888
|
+
}
|
|
96889
|
+
function double(point, withT) {
|
|
96890
|
+
const a = mod(point.x * point.x); const b = mod(point.y * point.y);
|
|
96891
|
+
const c = mod(2n * point.z * point.z); const sum = point.x + point.y;
|
|
96892
|
+
const e = mod(sum * sum - a - b); const g = b - a; const f = g - c; const h = -a - b;
|
|
96893
|
+
return { x: mod(e * f), y: mod(g * h), t: withT ? mod(e * h) : 0n, z: mod(f * g) };
|
|
96894
|
+
}
|
|
96895
|
+
function sharedX(point, scalar) {
|
|
96896
|
+
const table = [toTable(toExtended({ x: 0n, y: 1n })), toTable(toExtended(point))];
|
|
96897
|
+
for (let index = 2; index < 16; index += 1) table.push(toTable(addTable(table[index - 1], table[1])));
|
|
96898
|
+
const windows = scalar === 0n ? 1 : Math.ceil(scalar.toString(2).length / 4);
|
|
96899
|
+
let result = table[Number((scalar >> BigInt((windows - 1) * 4)) & 15n)];
|
|
96900
|
+
for (let window = windows - 2; window >= 0; window -= 1) {
|
|
96901
|
+
for (let bit = 0; bit < 4; bit += 1) result = double(result, bit === 3);
|
|
96902
|
+
result = addTable(result, table[Number((scalar >> BigInt(window * 4)) & 15n)]);
|
|
96903
|
+
}
|
|
96904
|
+
return mod(result.x * inverse(result.z));
|
|
96905
|
+
}
|
|
96906
|
+
const scalar = BigInt(workerData.scalar);
|
|
96907
|
+
const cancelled = new Set();
|
|
96908
|
+
const queue = [];
|
|
96909
|
+
let running = false;
|
|
96910
|
+
function entry(x) { const point = pointFromX(x); return [point.x.toString(16), point.y.toString(16), sharedX(point, scalar).toString(16)]; }
|
|
96911
|
+
async function run() {
|
|
96912
|
+
running = true;
|
|
96913
|
+
while (queue.length > 0) {
|
|
96914
|
+
const job = queue.shift();
|
|
96915
|
+
for (const id of cancelled) if (id < job.id) cancelled.delete(id);
|
|
96916
|
+
// A job cancelled while it waited in the queue is not started.
|
|
96917
|
+
if (cancelled.has(job.id)) { cancelled.delete(job.id); parentPort.postMessage({ id: job.id, out: [] }); continue; }
|
|
96918
|
+
const out = [];
|
|
96919
|
+
try {
|
|
96920
|
+
if (job.check !== undefined) out.push(entry(BigInt(job.check)));
|
|
96921
|
+
else {
|
|
96922
|
+
const bundle = job.bundle;
|
|
96923
|
+
let sliceStart = performance.now();
|
|
96924
|
+
for (let offset = 0; offset + RECORD_BYTES <= bundle.length; offset += RECORD_BYTES) {
|
|
96925
|
+
if (performance.now() - sliceStart >= SLICE_MS) {
|
|
96926
|
+
await new Promise((resolveTurn) => { setImmediate(resolveTurn); });
|
|
96927
|
+
sliceStart = performance.now();
|
|
96928
|
+
if (cancelled.has(job.id)) break;
|
|
96929
|
+
}
|
|
96930
|
+
try { out.push(entry(BigInt("0x" + Buffer.from(bundle.subarray(offset, offset + 32)).toString("hex")))); }
|
|
96931
|
+
catch { /* no point: the scan refuses or skips it as before */ }
|
|
96932
|
+
}
|
|
96933
|
+
}
|
|
96934
|
+
parentPort.postMessage({ id: job.id, out: cancelled.delete(job.id) ? [] : out });
|
|
96935
|
+
} catch {
|
|
96936
|
+
parentPort.postMessage({ id: job.id, failed: true });
|
|
96937
|
+
}
|
|
96938
|
+
}
|
|
96939
|
+
running = false;
|
|
96940
|
+
}
|
|
96941
|
+
parentPort.on("message", (message) => {
|
|
96942
|
+
if (message.cancel !== undefined) { cancelled.add(message.cancel); return; }
|
|
96943
|
+
queue.push(message);
|
|
96944
|
+
if (!running) run();
|
|
96945
|
+
});
|
|
96946
|
+
`;
|
|
96947
|
+
}
|
|
96948
|
+
});
|
|
96949
|
+
|
|
96644
96950
|
// wallet/src/seller/service.mjs
|
|
96645
96951
|
import { createServer } from "node:http";
|
|
96646
96952
|
import { randomBytes as randomBytes17 } from "node:crypto";
|
|
@@ -96770,12 +97076,19 @@ async function createSellerAdapter({
|
|
|
96770
97076
|
const signingBytes = Buffer.from(config.signingKey.slice(2), "hex");
|
|
96771
97077
|
const signerPublicKey = `0x${Buffer.from(secp256k1.getPublicKey(signingBytes, true)).toString("hex")}`;
|
|
96772
97078
|
deriveShieldedSolanaP03Recipient({ eta: config.eta, resourceNonce: randomBytes17(32), poolDomain: BigInt(profile.poolDomain) });
|
|
97079
|
+
const ecdhScalar = config.eta % SHIELDED_SOLANA_P03_JUBJUB_SCALAR_MODULUS;
|
|
97080
|
+
const sharedXOf = (point) => shieldedSolanaP03ScalarMultiply(point, ecdhScalar).x;
|
|
97081
|
+
const sharedXByPoint = /* @__PURE__ */ new Map();
|
|
97082
|
+
let precomputesRunning = 0;
|
|
96773
97083
|
const scanner = new ShieldedSolanaP03MemoScanner({ ecdh: {
|
|
96774
|
-
deriveSharedX: (point) =>
|
|
96775
|
-
point,
|
|
96776
|
-
config.eta % SHIELDED_SOLANA_P03_JUBJUB_SCALAR_MODULUS
|
|
96777
|
-
).x
|
|
97084
|
+
deriveSharedX: (point) => sharedXByPoint.get(`${point.x}:${point.y}`) ?? sharedXOf(point)
|
|
96778
97085
|
} });
|
|
97086
|
+
const memoEcdh = createMemoEcdhWorker({
|
|
97087
|
+
scalar: ecdhScalar,
|
|
97088
|
+
curvePointFromX: shieldedSolanaP03CurvePointFromX,
|
|
97089
|
+
sharedXOf,
|
|
97090
|
+
log: (line) => console.error(line)
|
|
97091
|
+
});
|
|
96779
97092
|
const readChainAnchor = createAnchorReader({ connection: memoizeFinalizedReads(connection), profile });
|
|
96780
97093
|
let anchorRequest;
|
|
96781
97094
|
const requestFacilitatorAnchor = () => anchorRequest ??= (async () => {
|
|
@@ -97178,15 +97491,48 @@ async function createSellerAdapter({
|
|
|
97178
97491
|
try {
|
|
97179
97492
|
if (!offer.outboundJson) {
|
|
97180
97493
|
const parsed = parseSolanaP03HttpPaymentPayload(payment.payload);
|
|
97181
|
-
const
|
|
97182
|
-
|
|
97183
|
-
|
|
97184
|
-
|
|
97185
|
-
|
|
97186
|
-
|
|
97187
|
-
|
|
97188
|
-
|
|
97189
|
-
|
|
97494
|
+
const quoteIssuer = issuer(offer.resource, payment.accepted.amount);
|
|
97495
|
+
const authInput = { requirements: payment.accepted, resource: payment.resource, publicInput7: parsed.publicInputs[7] };
|
|
97496
|
+
await quoteIssuer.authenticateForClaim(authInput);
|
|
97497
|
+
const authenticated = quoteIssuer.authenticate(authInput);
|
|
97498
|
+
authenticated.catch(() => void 0);
|
|
97499
|
+
const owned = { keys: [], done: false, cancel: void 0 };
|
|
97500
|
+
let precomputed;
|
|
97501
|
+
const job = precomputesRunning < MEMO_PRECOMPUTES_MAX ? memoEcdh.compute(parsed.memoBundle) : void 0;
|
|
97502
|
+
if (job !== void 0) {
|
|
97503
|
+
precomputesRunning += 1;
|
|
97504
|
+
owned.cancel = job.cancel;
|
|
97505
|
+
precomputed = job.result.then((entries) => {
|
|
97506
|
+
if (entries === void 0 || owned.done) return;
|
|
97507
|
+
for (const [key, sharedX] of entries) {
|
|
97508
|
+
if (sharedXByPoint.has(key)) continue;
|
|
97509
|
+
sharedXByPoint.set(key, sharedX);
|
|
97510
|
+
owned.keys.push(key);
|
|
97511
|
+
}
|
|
97512
|
+
}).catch(() => void 0).finally(() => {
|
|
97513
|
+
precomputesRunning -= 1;
|
|
97514
|
+
});
|
|
97515
|
+
}
|
|
97516
|
+
let recoveredNote;
|
|
97517
|
+
let intakeRead;
|
|
97518
|
+
try {
|
|
97519
|
+
const auth = await authenticated;
|
|
97520
|
+
mark("intake-authenticated");
|
|
97521
|
+
intakeRead = readAnchor();
|
|
97522
|
+
intakeRead.catch(() => void 0);
|
|
97523
|
+
if (precomputed !== void 0) {
|
|
97524
|
+
let timer;
|
|
97525
|
+
await Promise.race([precomputed, new Promise((resolveWait) => {
|
|
97526
|
+
timer = setTimeout(resolveWait, MEMO_PRECOMPUTE_WAIT_MS);
|
|
97527
|
+
})]);
|
|
97528
|
+
clearTimeout(timer);
|
|
97529
|
+
}
|
|
97530
|
+
recoveredNote = await scanner.recoverMerchantNoteYielding({ parsed, authenticatedQuote: auth });
|
|
97531
|
+
} finally {
|
|
97532
|
+
owned.done = true;
|
|
97533
|
+
owned.cancel?.();
|
|
97534
|
+
for (const key of owned.keys) sharedXByPoint.delete(key);
|
|
97535
|
+
}
|
|
97190
97536
|
mark("intake-note-recovered");
|
|
97191
97537
|
const chain = await intakeRead;
|
|
97192
97538
|
intakeChain = chain;
|
|
@@ -97344,6 +97690,7 @@ async function createSellerAdapter({
|
|
|
97344
97690
|
};
|
|
97345
97691
|
await put(nonce, offer);
|
|
97346
97692
|
mark("challenge");
|
|
97693
|
+
memoEcdh.warm();
|
|
97347
97694
|
return { status: 402, paymentRequired: issued.paymentRequired };
|
|
97348
97695
|
}
|
|
97349
97696
|
const server = createServer({ maxHeaderSize: 192 * 1024 }, async (request, response) => {
|
|
@@ -97398,6 +97745,7 @@ async function createSellerAdapter({
|
|
|
97398
97745
|
}
|
|
97399
97746
|
}
|
|
97400
97747
|
closed = true;
|
|
97748
|
+
memoEcdh.close();
|
|
97401
97749
|
for (const timer of followUps.values()) clearTimeout(timer);
|
|
97402
97750
|
followUps.clear();
|
|
97403
97751
|
};
|
|
@@ -97415,7 +97763,7 @@ async function createSellerAdapter({
|
|
|
97415
97763
|
}));
|
|
97416
97764
|
return { server, handle, close, signerPublicKey, settledTransactions, offerSummaries };
|
|
97417
97765
|
}
|
|
97418
|
-
var import_web3120, BINDING, SCHEMA2, OFFERS_LAYOUT, SNAPSHOT_EVERY_MS, LOADER2, canonical4, storeProfileIdentity, jsonSafe, bigint, encodeHeader, PAYMENT_REFUSED, FACILITATOR_UNDERFUNDED, DEFINITE_VERIFY_REFUSALS, definiteVerifyRefusal, refusedBeforeSettlement, ANCHOR_REQUEST_TIMEOUT_MS2, ANCHOR_POLL_ATTEMPTS, ANCHOR_POLL_MS, PRE_SETTLE_REUSE_MARGIN_S, PRE_SETTLE_REUSE_MAX_AGE_MS, FINALIZED_MEMO_MAX_AGE_MS, pause, FOLLOW_UP_DELAYS_MS, FOLLOW_UP_RESETTLE_FROM, CONFIRMED_TRANSACTION_READ;
|
|
97766
|
+
var import_web3120, BINDING, SCHEMA2, OFFERS_LAYOUT, SNAPSHOT_EVERY_MS, LOADER2, canonical4, storeProfileIdentity, jsonSafe, bigint, encodeHeader, PAYMENT_REFUSED, FACILITATOR_UNDERFUNDED, DEFINITE_VERIFY_REFUSALS, definiteVerifyRefusal, refusedBeforeSettlement, ANCHOR_REQUEST_TIMEOUT_MS2, ANCHOR_POLL_ATTEMPTS, ANCHOR_POLL_MS, MEMO_PRECOMPUTES_MAX, MEMO_PRECOMPUTE_WAIT_MS, PRE_SETTLE_REUSE_MARGIN_S, PRE_SETTLE_REUSE_MAX_AGE_MS, FINALIZED_MEMO_MAX_AGE_MS, pause, FOLLOW_UP_DELAYS_MS, FOLLOW_UP_RESETTLE_FROM, CONFIRMED_TRANSACTION_READ;
|
|
97419
97767
|
var init_service = __esm({
|
|
97420
97768
|
"wallet/src/seller/service.mjs"() {
|
|
97421
97769
|
"use strict";
|
|
@@ -97432,6 +97780,7 @@ var init_service = __esm({
|
|
|
97432
97780
|
init_config();
|
|
97433
97781
|
init_receiptTransaction();
|
|
97434
97782
|
init_timing();
|
|
97783
|
+
init_memoEcdhWorker();
|
|
97435
97784
|
BINDING = "carbon-shielded-exact/svm-v3";
|
|
97436
97785
|
SCHEMA2 = "carbon-independent-seller-offers/v1";
|
|
97437
97786
|
OFFERS_LAYOUT = "per-offer-v1";
|
|
@@ -97466,6 +97815,8 @@ var init_service = __esm({
|
|
|
97466
97815
|
ANCHOR_REQUEST_TIMEOUT_MS2 = 9e4;
|
|
97467
97816
|
ANCHOR_POLL_ATTEMPTS = 15;
|
|
97468
97817
|
ANCHOR_POLL_MS = 2e3;
|
|
97818
|
+
MEMO_PRECOMPUTES_MAX = 2;
|
|
97819
|
+
MEMO_PRECOMPUTE_WAIT_MS = 1e3;
|
|
97469
97820
|
PRE_SETTLE_REUSE_MARGIN_S = 60;
|
|
97470
97821
|
PRE_SETTLE_REUSE_MAX_AGE_MS = 2e4;
|
|
97471
97822
|
FINALIZED_MEMO_MAX_AGE_MS = 1e3;
|
|
@@ -126800,7 +127151,18 @@ function createWalletTools({
|
|
|
126800
127151
|
...share ? { share } : {}
|
|
126801
127152
|
});
|
|
126802
127153
|
let lastWriterEndedAt = 0;
|
|
126803
|
-
|
|
127154
|
+
let paysInFlight = 0;
|
|
127155
|
+
let refreshDeferred = false;
|
|
127156
|
+
let refreshForeground = false;
|
|
127157
|
+
let refreshRunDeferred = false;
|
|
127158
|
+
const REFRESH_DEFERRED = /* @__PURE__ */ Symbol("deferred refresh");
|
|
127159
|
+
const runDeferredRefresh = () => {
|
|
127160
|
+
if (!refreshDeferred || paysInFlight !== 0 || finalityWait || refreshRun || finalityClosed) return;
|
|
127161
|
+
refreshDeferred = false;
|
|
127162
|
+
refreshShared({ background: true }).catch(() => {
|
|
127163
|
+
});
|
|
127164
|
+
};
|
|
127165
|
+
const refreshWalk = ops.refreshWalk ?? (ops.refresh ? void 0 : (store, share) => walkWalletHistory(session, store, share));
|
|
126804
127166
|
const errorCode2 = (error, fallback) => describeError(error, { fallback, safeText: SAFE_TEXT }).split(/[\s:;(]/, 1)[0];
|
|
126805
127167
|
const underLease = (task) => session.serial(async () => {
|
|
126806
127168
|
let release;
|
|
@@ -126899,10 +127261,16 @@ function createWalletTools({
|
|
|
126899
127261
|
};
|
|
126900
127262
|
const withPoolSwitch = (tool) => ({ ...tool, run: async (...args) => {
|
|
126901
127263
|
let output2;
|
|
127264
|
+
const paying = tool.name === "x402_pay";
|
|
127265
|
+
if (paying) paysInFlight += 1;
|
|
126902
127266
|
try {
|
|
126903
127267
|
output2 = await tool.run(...args);
|
|
126904
127268
|
} finally {
|
|
126905
127269
|
if (tool.annotations?.readOnlyHint !== true) lastWriterEndedAt = Date.now();
|
|
127270
|
+
if (paying) {
|
|
127271
|
+
paysInFlight -= 1;
|
|
127272
|
+
runDeferredRefresh();
|
|
127273
|
+
}
|
|
126906
127274
|
}
|
|
126907
127275
|
if (!succession || !output2 || output2.isError || typeof output2.text !== "string") return output2;
|
|
126908
127276
|
const read = readSwitch();
|
|
@@ -126951,9 +127319,20 @@ function createWalletTools({
|
|
|
126951
127319
|
});
|
|
126952
127320
|
if (ops.oneTimeAdopt !== false) adopter.start();
|
|
126953
127321
|
function refreshShared({ background = false } = {}) {
|
|
127322
|
+
if (refreshRun && !background && refreshRunDeferred) return refreshRun.then(() => refreshShared(), () => refreshShared());
|
|
127323
|
+
if (refreshRun && !background) refreshForeground = true;
|
|
126954
127324
|
if (!refreshRun) {
|
|
126955
127325
|
refreshInBackground = background;
|
|
127326
|
+
refreshForeground = !background;
|
|
127327
|
+
refreshRunDeferred = false;
|
|
126956
127328
|
const calledAt = Date.now();
|
|
127329
|
+
const deferNow = () => {
|
|
127330
|
+
if (!background || refreshForeground || paysInFlight === 0) return false;
|
|
127331
|
+
refreshRunDeferred = true;
|
|
127332
|
+
refreshDeferred = true;
|
|
127333
|
+
log("MCP_REFRESH_DEFERRED");
|
|
127334
|
+
return true;
|
|
127335
|
+
};
|
|
126957
127336
|
refreshRun = (async () => {
|
|
126958
127337
|
let early;
|
|
126959
127338
|
if (background && refreshWalk) {
|
|
@@ -126961,18 +127340,21 @@ function createWalletTools({
|
|
|
126961
127340
|
const store = session.openStore();
|
|
126962
127341
|
const records = JSON.stringify(captureWalStates(store));
|
|
126963
127342
|
const pool2 = store.state.pool;
|
|
126964
|
-
early = { records, pool: pool2, history: await refreshWalk(store) };
|
|
127343
|
+
early = { records, pool: pool2, history: await refreshWalk(store, { notBeforeMs: Math.max(calledAt, lastWriterEndedAt) }) };
|
|
126965
127344
|
} catch {
|
|
126966
127345
|
early = void 0;
|
|
126967
127346
|
}
|
|
126968
127347
|
}
|
|
126969
127348
|
return underLease((store) => {
|
|
127349
|
+
if (deferNow()) return REFRESH_DEFERRED;
|
|
127350
|
+
refreshDeferred = false;
|
|
126970
127351
|
const same2 = early !== void 0 && early.pool === store.state.pool && early.records === JSON.stringify(captureWalStates(store));
|
|
126971
127352
|
if (early !== void 0 && !same2) log("MCP_REFRESH_WALK_AGAIN");
|
|
126972
127353
|
const share = early !== void 0 && !same2 ? { notBeforeMs: Math.max(calledAt, lastWriterEndedAt) } : void 0;
|
|
126973
127354
|
return refreshStep(store, same2 ? early.history : void 0, share);
|
|
126974
127355
|
});
|
|
126975
|
-
})().then(() => {
|
|
127356
|
+
})().then((result) => {
|
|
127357
|
+
if (result === REFRESH_DEFERRED) return;
|
|
126976
127358
|
refreshFailedAt = 0;
|
|
126977
127359
|
log("MCP_REFRESH_DONE");
|
|
126978
127360
|
}, (error) => {
|
|
@@ -126981,8 +127363,12 @@ function createWalletTools({
|
|
|
126981
127363
|
log(`MCP_REFRESH_FAILED ${refreshFailedCode}`);
|
|
126982
127364
|
throw error;
|
|
126983
127365
|
}).finally(() => {
|
|
127366
|
+
const deferred = refreshRunDeferred;
|
|
126984
127367
|
refreshRun = void 0;
|
|
126985
127368
|
refreshInBackground = false;
|
|
127369
|
+
refreshForeground = false;
|
|
127370
|
+
refreshRunDeferred = false;
|
|
127371
|
+
if (deferred || refreshDeferred) runDeferredRefresh();
|
|
126986
127372
|
});
|
|
126987
127373
|
}
|
|
126988
127374
|
return refreshRun;
|
|
@@ -127053,6 +127439,7 @@ function createWalletTools({
|
|
|
127053
127439
|
finalityWait = void 0;
|
|
127054
127440
|
if (finalityClosed || finalityTarget === watched) finalityTarget = void 0;
|
|
127055
127441
|
else startFinalityWait();
|
|
127442
|
+
runDeferredRefresh();
|
|
127056
127443
|
});
|
|
127057
127444
|
}
|
|
127058
127445
|
async function refreshIfStale() {
|
|
@@ -127473,7 +127860,7 @@ function createWalletTools({
|
|
|
127473
127860
|
let refresh = {};
|
|
127474
127861
|
const recentlyFailed = refreshFailedAt && Date.now() - refreshFailedAt < REFRESH_RETRY_MS && !refreshRun;
|
|
127475
127862
|
if (report.split?.shieldedAtomic != null && report.status === "stale") {
|
|
127476
|
-
if (!recentlyFailed && !finalityWait) refreshShared().catch(() => {
|
|
127863
|
+
if (!recentlyFailed && (!finalityWait || refreshDeferred)) refreshShared().catch(() => {
|
|
127477
127864
|
});
|
|
127478
127865
|
refresh = { refreshing: true };
|
|
127479
127866
|
} else if (report.split?.shieldedAtomic == null && recentlyFailed) {
|