shinjuku-shielded 0.3.48 → 0.3.49
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 +354 -70
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": "4baf3bca327b51694452760cdb6a4f65d8e869a4c64040c832e92937f66ab395",
|
|
5
|
+
"bytes": 11416627,
|
|
6
|
+
"sourceCommit": "8b2cedd6f47d75d41eb39da9fc85caeed06be5c3",
|
|
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.49",
|
|
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": "4baf3bca",
|
|
7
|
+
"shinjukuSha256": "4baf3bca327b51694452760cdb6a4f65d8e869a4c64040c832e92937f66ab395",
|
|
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
|
@@ -50460,7 +50460,7 @@ function connectSplit(own, historyUrl, commitment = "finalized", { pause: pause3
|
|
|
50460
50460
|
const historyRpcWarm = () => {
|
|
50461
50461
|
if (warmedSources.has(historyUrl)) return;
|
|
50462
50462
|
warmedSources.add(historyUrl);
|
|
50463
|
-
rpcFetch(historyUrl, { method: "GET" }).then((response) => response.
|
|
50463
|
+
rpcFetch(historyUrl, keepAliveInit({ method: "GET" })).then((response) => response.arrayBuffer()).catch(() => {
|
|
50464
50464
|
});
|
|
50465
50465
|
};
|
|
50466
50466
|
const historyRpcIntegrity = Object.freeze({
|
|
@@ -52739,7 +52739,7 @@ var init_quote2 = __esm({
|
|
|
52739
52739
|
return bytes2;
|
|
52740
52740
|
};
|
|
52741
52741
|
TICKER_MINTS = Object.freeze({ USDC: "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v" });
|
|
52742
|
-
SELF_BROADCAST_MIN_LEFT_MS =
|
|
52742
|
+
SELF_BROADCAST_MIN_LEFT_MS = 16e4;
|
|
52743
52743
|
QUOTE_ID_PATTERN = /^[A-Za-z0-9._:-]{1,128}$/;
|
|
52744
52744
|
}
|
|
52745
52745
|
});
|
|
@@ -53087,7 +53087,11 @@ async function refreshFinalizedP03HistorySnapshot({
|
|
|
53087
53087
|
keepPoolState(refreshed, snapshot);
|
|
53088
53088
|
return refreshed;
|
|
53089
53089
|
}
|
|
53090
|
-
async function readFinalizedPool(connection, program, pool2) {
|
|
53090
|
+
async function readFinalizedPool(connection, program, pool2, { treeSlices = false } = {}) {
|
|
53091
|
+
if (treeSlices) {
|
|
53092
|
+
const sliced = await readFinalizedPoolSliced(connection, program, pool2);
|
|
53093
|
+
if (sliced !== void 0) return sliced;
|
|
53094
|
+
}
|
|
53091
53095
|
if (typeof connection.getMultipleAccountsInfoAndContext !== "function") {
|
|
53092
53096
|
const response = await retryTransientRpc(() => connection.getAccountInfoAndContext(pool2, "finalized"));
|
|
53093
53097
|
const only = parseFinalizedPool(response, program, pool2);
|
|
@@ -53118,6 +53122,107 @@ function withPoolStateOf(snapshot, wrapped) {
|
|
|
53118
53122
|
if (entry !== void 0) SNAPSHOT_POOL_STATES.set(wrapped, entry);
|
|
53119
53123
|
return wrapped;
|
|
53120
53124
|
}
|
|
53125
|
+
function parseE1TreeHeader(header) {
|
|
53126
|
+
const invalid4 = (detail) => {
|
|
53127
|
+
throw new Error(`E1TreeAccountInvalid: ${detail}`);
|
|
53128
|
+
};
|
|
53129
|
+
if (!(header instanceof Uint8Array) || header.length !== E1_TREE_HEADER_BYTES) invalid4("length");
|
|
53130
|
+
const bytes2 = Buffer.from(header.buffer, header.byteOffset, header.byteLength);
|
|
53131
|
+
if (bytes2.subarray(0, 8).toString("latin1") !== E1_TREE_MAGIC) invalid4("magic");
|
|
53132
|
+
if (bytes2[40] !== 1 || bytes2[41] !== E1.depth || bytes2.readUInt16LE(42) !== E1.bufferSize || bytes2[44] !== E1.canopyDepth) invalid4("header");
|
|
53133
|
+
if (bytes2[45] !== 0 || bytes2[46] !== 0 || bytes2[47] !== 0) invalid4("reserved");
|
|
53134
|
+
const u642 = (offset) => {
|
|
53135
|
+
const value = bytes2.readBigUInt64LE(offset);
|
|
53136
|
+
if (value > BigInt(Number.MAX_SAFE_INTEGER)) invalid4("u64");
|
|
53137
|
+
return Number(value);
|
|
53138
|
+
};
|
|
53139
|
+
const activeIndex = u642(64);
|
|
53140
|
+
if (activeIndex >= E1.bufferSize) invalid4("activeIndex");
|
|
53141
|
+
return {
|
|
53142
|
+
pool: new import_web396.PublicKey(bytes2.subarray(8, 40)).toBase58(),
|
|
53143
|
+
creationSlot: u642(48),
|
|
53144
|
+
sequenceNumber: u642(56),
|
|
53145
|
+
activeIndex,
|
|
53146
|
+
bufferSize: u642(72)
|
|
53147
|
+
};
|
|
53148
|
+
}
|
|
53149
|
+
function slicesRefused(connection) {
|
|
53150
|
+
const endpoint2 = connection.rpcEndpoint;
|
|
53151
|
+
return typeof endpoint2 === "string" ? SLICES_REFUSED_ENDPOINTS.has(endpoint2) : SLICES_REFUSED_CONNECTIONS.has(connection);
|
|
53152
|
+
}
|
|
53153
|
+
function rememberSlicesRefused(connection) {
|
|
53154
|
+
const endpoint2 = connection.rpcEndpoint;
|
|
53155
|
+
if (typeof endpoint2 === "string") SLICES_REFUSED_ENDPOINTS.add(endpoint2);
|
|
53156
|
+
else SLICES_REFUSED_CONNECTIONS.add(connection);
|
|
53157
|
+
}
|
|
53158
|
+
function slicesMethodMissing(error) {
|
|
53159
|
+
const message = String(error?.message ?? "");
|
|
53160
|
+
return /^(404|405|501)\b/.test(message) || /-3260[12]\b/.test(message);
|
|
53161
|
+
}
|
|
53162
|
+
function slicedAccountBytes(value, accountIndex) {
|
|
53163
|
+
if (value === null || typeof value !== "object" || typeof value.owner !== "string" || !Number.isSafeInteger(value.space) || value.space < 0 || !Array.isArray(value.data) || value.data.length !== 2 || value.data[1] !== "base64" || typeof value.data[0] !== "string") {
|
|
53164
|
+
return void 0;
|
|
53165
|
+
}
|
|
53166
|
+
const bytes2 = Buffer.from(value.data[0], "base64");
|
|
53167
|
+
if (bytes2.toString("base64") !== value.data[0]) return void 0;
|
|
53168
|
+
let expected = 0;
|
|
53169
|
+
for (const [index, offset, length] of POOL_SLICES) {
|
|
53170
|
+
if (index === accountIndex) expected += Math.max(0, Math.min(offset + length, value.space) - offset);
|
|
53171
|
+
}
|
|
53172
|
+
return bytes2.length === expected ? bytes2 : void 0;
|
|
53173
|
+
}
|
|
53174
|
+
function slicedSnapshot(result, program, pool2, tree) {
|
|
53175
|
+
if (result === null || typeof result !== "object" || !Array.isArray(result.value) || result.value.length !== 2) return void 0;
|
|
53176
|
+
const [poolValue, treeValue] = result.value;
|
|
53177
|
+
const poolBytes2 = slicedAccountBytes(poolValue, 0);
|
|
53178
|
+
if (poolBytes2 === void 0 || poolValue.space > REFRESH_READ_BYTES) return void 0;
|
|
53179
|
+
const snapshot = parseFinalizedPool({ context: result.context, value: { owner: poolValue.owner, data: poolBytes2 } }, program, pool2);
|
|
53180
|
+
if (snapshot.replayStore !== REPLAY_STORE_INDEXED) return snapshot;
|
|
53181
|
+
const treeBytes = slicedAccountBytes(treeValue, 1);
|
|
53182
|
+
if (treeBytes === void 0 || treeValue.space !== E1.treeBytes) return void 0;
|
|
53183
|
+
const ownerProgramId = canonicalKey(treeValue.owner, "e1_tree_owner").toBase58();
|
|
53184
|
+
if (ownerProgramId !== b58(program)) return void 0;
|
|
53185
|
+
const header = Buffer.from(treeBytes.subarray(0, E1_TREE_HEADER_BYTES));
|
|
53186
|
+
const { activeIndex } = parseE1TreeHeader(header);
|
|
53187
|
+
const rootAt = SLICED_ROOTS_OFFSET + 32 * activeIndex;
|
|
53188
|
+
return withPoolStateOf(snapshot, Object.freeze({
|
|
53189
|
+
...snapshot,
|
|
53190
|
+
e1TreeSlices: Object.freeze({
|
|
53191
|
+
slot: snapshot.slot,
|
|
53192
|
+
address: tree.toBase58(),
|
|
53193
|
+
ownerProgramId,
|
|
53194
|
+
space: treeValue.space,
|
|
53195
|
+
header,
|
|
53196
|
+
root: Buffer.from(treeBytes.subarray(rootAt, rootAt + 32)),
|
|
53197
|
+
leaves: treeBytes.readUInt32LE(SLICED_LEAVES_OFFSET)
|
|
53198
|
+
})
|
|
53199
|
+
}));
|
|
53200
|
+
}
|
|
53201
|
+
async function readFinalizedPoolSliced(connection, program, pool2) {
|
|
53202
|
+
if (typeof connection._rpcRequest !== "function" || slicesRefused(connection)) return void 0;
|
|
53203
|
+
const tree = new import_web396.PublicKey(e1TreeAddress2(b58(pool2), b58(program)));
|
|
53204
|
+
let response;
|
|
53205
|
+
try {
|
|
53206
|
+
response = await connection._rpcRequest(P03_POOL_SLICES_METHOD, [[b58(pool2), tree.toBase58()], { commitment: "finalized", slices: POOL_SLICES }]);
|
|
53207
|
+
} catch (error) {
|
|
53208
|
+
if (slicesMethodMissing(error)) rememberSlicesRefused(connection);
|
|
53209
|
+
markPhase(`pool-sliced-fallback-${reuseRefusalCause(error)}`);
|
|
53210
|
+
return void 0;
|
|
53211
|
+
}
|
|
53212
|
+
if (response?.error !== void 0) {
|
|
53213
|
+
if (response.error?.code === -32601 || response.error?.code === -32602) rememberSlicesRefused(connection);
|
|
53214
|
+
markPhase("pool-sliced-fallback-refused");
|
|
53215
|
+
return void 0;
|
|
53216
|
+
}
|
|
53217
|
+
let snapshot;
|
|
53218
|
+
try {
|
|
53219
|
+
snapshot = slicedSnapshot(response?.result, program, pool2, tree);
|
|
53220
|
+
} catch {
|
|
53221
|
+
snapshot = void 0;
|
|
53222
|
+
}
|
|
53223
|
+
markPhase(snapshot === void 0 ? "pool-sliced-fallback-answer" : "pool-sliced");
|
|
53224
|
+
return snapshot;
|
|
53225
|
+
}
|
|
53121
53226
|
async function readFinalizedPoolForRefresh(connection, program, pool2) {
|
|
53122
53227
|
if (typeof connection.getMultipleAccountsInfoAndContext !== "function") return readFinalizedPool(connection, program, pool2);
|
|
53123
53228
|
const tree = new import_web396.PublicKey(e1TreeAddress2(b58(pool2), b58(program)));
|
|
@@ -53861,29 +53966,44 @@ function assertP03E1TreeComplete({ program, pool: pool2, poolSnapshot, settles,
|
|
|
53861
53966
|
const mismatch = (detail) => {
|
|
53862
53967
|
throw new Error(`p03_history_e1_tree_mismatch:${detail}`);
|
|
53863
53968
|
};
|
|
53864
|
-
const
|
|
53969
|
+
const sliced = poolSnapshot.e1TreeSlices;
|
|
53970
|
+
const tree = sliced ?? poolSnapshot.e1TreeAccount;
|
|
53865
53971
|
if (!tree || tree.slot !== poolSnapshot.slot) mismatch("tree_snapshot_missing");
|
|
53866
53972
|
if (tree.address !== e1TreeAddress2(b58(pool2), b58(program))) mismatch("tree_address");
|
|
53867
|
-
const empty = tree.data === null || tree.ownerProgramId === null || tree.ownerProgramId === SYSTEM_PROGRAM && tree.data.every((byte) => byte === 0);
|
|
53973
|
+
const empty = sliced === void 0 && (tree.data === null || tree.ownerProgramId === null || tree.ownerProgramId === SYSTEM_PROGRAM && tree.data.every((byte) => byte === 0));
|
|
53868
53974
|
if (closed) {
|
|
53869
53975
|
if (!empty) mismatch("closed_pool_has_tree");
|
|
53870
53976
|
return Object.freeze({ state: "closed", address: tree.address, slot: BigInt(poolSnapshot.slot) });
|
|
53871
53977
|
}
|
|
53872
53978
|
if (empty) mismatch("tree_empty_without_close");
|
|
53873
|
-
|
|
53979
|
+
const space = sliced !== void 0 ? sliced.space : tree.data.length;
|
|
53980
|
+
if (tree.ownerProgramId !== b58(program) || space !== E1.treeBytes) mismatch("tree_owner_or_length");
|
|
53874
53981
|
let header;
|
|
53982
|
+
let treeRoot;
|
|
53983
|
+
let treeLeaves;
|
|
53875
53984
|
try {
|
|
53876
|
-
|
|
53985
|
+
if (sliced !== void 0) {
|
|
53986
|
+
header = parseE1TreeHeader(sliced.header);
|
|
53987
|
+
if (!(sliced.root instanceof Uint8Array) || sliced.root.length !== 32 || !Number.isSafeInteger(sliced.leaves)) throw new Error("E1TreeAccountInvalid: slices");
|
|
53988
|
+
treeRoot = sliced.root;
|
|
53989
|
+
treeLeaves = sliced.leaves;
|
|
53990
|
+
} else {
|
|
53991
|
+
const data = Buffer.from(tree.data.buffer, tree.data.byteOffset, tree.data.byteLength);
|
|
53992
|
+
header = parseE1TreeHeader(data.subarray(0, E1_TREE_HEADER_BYTES));
|
|
53993
|
+
const rootAt = E1_CHANGELOGS_OFFSET + E1_CHANGELOG_BYTES * header.activeIndex;
|
|
53994
|
+
treeRoot = data.subarray(rootAt, rootAt + 32);
|
|
53995
|
+
treeLeaves = data.readUInt32LE(E1_LEAF_COUNT_OFFSET);
|
|
53996
|
+
}
|
|
53877
53997
|
} catch (error) {
|
|
53878
53998
|
mismatch(`tree_header:${error?.message ?? "invalid"}`);
|
|
53879
53999
|
}
|
|
53880
54000
|
if (header.pool !== b58(pool2)) mismatch("tree_pool");
|
|
53881
54001
|
const mirror = E1TreeMirror.fromOrderedValues(settles.flatMap((values) => e1SortValues(values)));
|
|
53882
54002
|
const leaves = mirror.leaves();
|
|
53883
|
-
if (
|
|
54003
|
+
if (treeLeaves !== leaves) mismatch(`leaves:${treeLeaves}/${leaves}`);
|
|
53884
54004
|
if (Number(header.sequenceNumber) !== 2 * leaves - 1) mismatch(`sequence:${header.sequenceNumber}/${2 * leaves - 1}`);
|
|
53885
54005
|
const root = Buffer.from(mirror.root()).toString("hex");
|
|
53886
|
-
if (Buffer.from(
|
|
54006
|
+
if (Buffer.from(treeRoot).toString("hex") !== root) mismatch("root");
|
|
53887
54007
|
return Object.freeze({ state: "open", address: tree.address, slot: BigInt(poolSnapshot.slot), root, leaves });
|
|
53888
54008
|
}
|
|
53889
54009
|
function sameE1TreeHeader(snapshot, verified, program, pool2) {
|
|
@@ -54683,7 +54803,7 @@ function base58Decode(value) {
|
|
|
54683
54803
|
while (zeros < value.length && value[zeros] === "1") zeros += 1;
|
|
54684
54804
|
return Uint8Array.from(Buffer.concat([Buffer.alloc(zeros), body]));
|
|
54685
54805
|
}
|
|
54686
|
-
var import_web396, b58Cache, b58, REPLAY_STORE_INDEXED, CLOSE_REPLAY_TREE_TAG, EXTEND_ANCHOR_RING_TAG, WIDEN_ANCHOR_RING_TAG, WIDE_ANCHOR_RING_POOL_BYTES, LINK_SUCCESSOR_TAG, IMPORT_REPLAY_LEAVES_TAG, SETTLE_MOVE_TAG, SWEEP_PREDECESSOR_VAULT_TAG, RELINK_SUCCESSOR_TAG, ROTATE_PAYMENT_SETTLER_TAG, IMPORT_A_LEAF_BYTES, IMPORT_MEMBERSHIP_BYTES, IMPORT_PRESENT_SHIFT, IMPORT_MAX_ENTRIES, MOVE_HEAD_BYTES, MOVE_INSERTED_VALUES, DEFAULT_KEY, FIELD_BYTES2, PRIMARY_PROOF_BYTES, SUBTREE_LEAVES, PAGE_SIZE, FIELD_MODULUS3, BPF_LOADER_UPGRADEABLE_PROGRAM_ID, SYSTEM_PROGRAM, TEST_EXECUTABLES, derivationMemo, memo, reviewedExecutables, isProgramDataIdentityError, ASSUMED_ORIGINAL_EXECUTABLE, AUTHENTICATED_HISTORY_REPORTS, HISTORY_ATTESTATIONS, SNAPSHOT_POOL_STATES, REPORT_POOL_STATES, hasExecutableEvidence, P03_FINALIZED_HISTORY_SOURCE_MODEL, P03_PROGRAMDATA_COVERAGE_SOURCE_MODEL, P03_RUN_RECOVER_UNAVAILABLE_FROM_CHAIN, PROFILES, P03_SETTLEMENT_TAGS, P03_INLINE_SETTLEMENT_TAGS, P03_PAYMENT_REPLAY_INDICES, NO_CONTEXTS, REFRESH_READ_BYTES, E1_TREE_HEADER_BYTES, HISTORY_FETCH_CONCURRENCY, HISTORY_BULK_TRANSACTIONS, HISTORY_BULK_ADDRESSES, TRANSIENT_RPC_ATTEMPTS, TRANSIENT_RPC_BASE_DELAY_MS, LAGGING_NODE_STEP_OF_BASE, LAGGING_NODE_MAX_RETRIES, LAGGING_NODE_FAST_RETRIES, LAGGING_NODE_SLOW_STEP_OF_BASE, LAGGING_NODE_RPC_CODES;
|
|
54806
|
+
var import_web396, b58Cache, b58, REPLAY_STORE_INDEXED, CLOSE_REPLAY_TREE_TAG, EXTEND_ANCHOR_RING_TAG, WIDEN_ANCHOR_RING_TAG, WIDE_ANCHOR_RING_POOL_BYTES, LINK_SUCCESSOR_TAG, IMPORT_REPLAY_LEAVES_TAG, SETTLE_MOVE_TAG, SWEEP_PREDECESSOR_VAULT_TAG, RELINK_SUCCESSOR_TAG, ROTATE_PAYMENT_SETTLER_TAG, IMPORT_A_LEAF_BYTES, IMPORT_MEMBERSHIP_BYTES, IMPORT_PRESENT_SHIFT, IMPORT_MAX_ENTRIES, MOVE_HEAD_BYTES, MOVE_INSERTED_VALUES, DEFAULT_KEY, FIELD_BYTES2, PRIMARY_PROOF_BYTES, SUBTREE_LEAVES, PAGE_SIZE, FIELD_MODULUS3, BPF_LOADER_UPGRADEABLE_PROGRAM_ID, SYSTEM_PROGRAM, TEST_EXECUTABLES, derivationMemo, memo, reviewedExecutables, isProgramDataIdentityError, ASSUMED_ORIGINAL_EXECUTABLE, AUTHENTICATED_HISTORY_REPORTS, HISTORY_ATTESTATIONS, SNAPSHOT_POOL_STATES, REPORT_POOL_STATES, hasExecutableEvidence, P03_FINALIZED_HISTORY_SOURCE_MODEL, P03_PROGRAMDATA_COVERAGE_SOURCE_MODEL, P03_RUN_RECOVER_UNAVAILABLE_FROM_CHAIN, PROFILES, P03_SETTLEMENT_TAGS, P03_INLINE_SETTLEMENT_TAGS, P03_PAYMENT_REPLAY_INDICES, NO_CONTEXTS, REFRESH_READ_BYTES, E1_TREE_HEADER_BYTES, E1_TREE_MAGIC, E1_CHANGELOG_BYTES, E1_CHANGELOGS_OFFSET, E1_RIGHTMOST_OFFSET, E1_LEAF_COUNT_OFFSET, E1_CANOPY_OFFSET, E1_CANOPY_NODES, P03_POOL_SLICES_METHOD, POOL_SLICES, SLICED_ROOTS_OFFSET, SLICED_LEAVES_OFFSET, SLICES_REFUSED_ENDPOINTS, SLICES_REFUSED_CONNECTIONS, HISTORY_FETCH_CONCURRENCY, HISTORY_BULK_TRANSACTIONS, HISTORY_BULK_ADDRESSES, TRANSIENT_RPC_ATTEMPTS, TRANSIENT_RPC_BASE_DELAY_MS, LAGGING_NODE_STEP_OF_BASE, LAGGING_NODE_MAX_RETRIES, LAGGING_NODE_FAST_RETRIES, LAGGING_NODE_SLOW_STEP_OF_BASE, LAGGING_NODE_RPC_CODES;
|
|
54687
54807
|
var init_walk = __esm({
|
|
54688
54808
|
"wallet/src/history/walk.mjs"() {
|
|
54689
54809
|
"use strict";
|
|
@@ -54943,6 +55063,25 @@ var init_walk = __esm({
|
|
|
54943
55063
|
NO_CONTEXTS = Object.freeze([]);
|
|
54944
55064
|
REFRESH_READ_BYTES = 4096;
|
|
54945
55065
|
E1_TREE_HEADER_BYTES = 80;
|
|
55066
|
+
E1_TREE_MAGIC = "SX402T01";
|
|
55067
|
+
E1_CHANGELOG_BYTES = 32 + 32 * E1.depth + 8;
|
|
55068
|
+
E1_CHANGELOGS_OFFSET = E1_TREE_HEADER_BYTES;
|
|
55069
|
+
E1_RIGHTMOST_OFFSET = E1_CHANGELOGS_OFFSET + E1.bufferSize * E1_CHANGELOG_BYTES;
|
|
55070
|
+
E1_LEAF_COUNT_OFFSET = E1_RIGHTMOST_OFFSET + 32 * E1.depth + 32;
|
|
55071
|
+
E1_CANOPY_OFFSET = E1_RIGHTMOST_OFFSET + E1_CHANGELOG_BYTES;
|
|
55072
|
+
E1_CANOPY_NODES = 2 ** (E1.canopyDepth + 1) - 2;
|
|
55073
|
+
if (E1_CANOPY_OFFSET + 32 * E1_CANOPY_NODES !== E1.treeBytes) throw new Error("p03_history_e1_tree_mismatch:layout");
|
|
55074
|
+
P03_POOL_SLICES_METHOD = "getMultipleAccountsSlices";
|
|
55075
|
+
POOL_SLICES = Object.freeze([
|
|
55076
|
+
Object.freeze([0, 0, REFRESH_READ_BYTES]),
|
|
55077
|
+
Object.freeze([1, 0, E1_TREE_HEADER_BYTES]),
|
|
55078
|
+
...Array.from({ length: E1.bufferSize }, (_, index) => Object.freeze([1, E1_CHANGELOGS_OFFSET + E1_CHANGELOG_BYTES * index, 32])),
|
|
55079
|
+
Object.freeze([1, E1_LEAF_COUNT_OFFSET, 4])
|
|
55080
|
+
]);
|
|
55081
|
+
SLICED_ROOTS_OFFSET = E1_TREE_HEADER_BYTES;
|
|
55082
|
+
SLICED_LEAVES_OFFSET = SLICED_ROOTS_OFFSET + 32 * E1.bufferSize;
|
|
55083
|
+
SLICES_REFUSED_ENDPOINTS = /* @__PURE__ */ new Set();
|
|
55084
|
+
SLICES_REFUSED_CONNECTIONS = /* @__PURE__ */ new WeakSet();
|
|
54946
55085
|
HISTORY_FETCH_CONCURRENCY = 4;
|
|
54947
55086
|
HISTORY_BULK_TRANSACTIONS = 256;
|
|
54948
55087
|
HISTORY_BULK_ADDRESSES = 256;
|
|
@@ -55805,6 +55944,9 @@ function withBoundedOwnReads(connection) {
|
|
|
55805
55944
|
const value = Reflect.get(target, property);
|
|
55806
55945
|
if (typeof value !== "function") return value;
|
|
55807
55946
|
if (BOUNDED_OWN_METHODS.has(property)) return (...args) => boundedOwnRead(() => value.apply(target, args));
|
|
55947
|
+
if (property === "_rpcRequest") {
|
|
55948
|
+
return (...args) => args[0] === P03_POOL_SLICES_METHOD ? boundedOwnRead(() => value.apply(target, args)) : value.apply(target, args);
|
|
55949
|
+
}
|
|
55808
55950
|
return value.bind(target);
|
|
55809
55951
|
}
|
|
55810
55952
|
});
|
|
@@ -55855,7 +55997,7 @@ async function readPages(history, pool2, needed, first, { wakeSlot } = {}) {
|
|
|
55855
55997
|
return { records: records.slice(0, needed), imports, initialization, syncedSlot };
|
|
55856
55998
|
}
|
|
55857
55999
|
async function readCompactPoolSnapshot({ connection, programId, pool: pool2 }) {
|
|
55858
|
-
return readFinalizedPool(withBoundedOwnReads(connection), new import_web397.PublicKey(programId), new import_web397.PublicKey(pool2));
|
|
56000
|
+
return readFinalizedPool(withBoundedOwnReads(connection), new import_web397.PublicKey(programId), new import_web397.PublicKey(pool2), { treeSlices: true });
|
|
55859
56001
|
}
|
|
55860
56002
|
function pageShapeValid(result, pool2, from) {
|
|
55861
56003
|
return Boolean(result) && typeof result === "object" && result.pool === pool2 && result.fromOrdinal === from && isIndex(result.total) && isIndex(result.syncedSlot) && Array.isArray(result.records) && result.records.length === Math.max(0, Math.min(result.total, from + P03_COMPACT_PAGE) - from) && Boolean(result.initialization) && isSignature(result.initialization.signature) && isIndex(result.initialization.slot);
|
|
@@ -56156,7 +56298,7 @@ async function readCompactP03HistoryNow({
|
|
|
56156
56298
|
markPhase("compact-pool-preread-failed");
|
|
56157
56299
|
}
|
|
56158
56300
|
}
|
|
56159
|
-
snapshot ??= await readFinalizedPool(own, program, poolKey);
|
|
56301
|
+
snapshot ??= await readFinalizedPool(own, program, poolKey, { treeSlices: true });
|
|
56160
56302
|
markPhase(knownSnapshot !== void 0 ? "compact-pool-reused" : "compact-pool");
|
|
56161
56303
|
if (snapshot.terminal) throw refuse3("p03_compact_history_pool_terminal");
|
|
56162
56304
|
if (snapshot.currentIndex % SUBTREE_LEAVES3 !== 0n) throw refuse3("p03_compact_history_snapshot_invalid");
|
|
@@ -56637,7 +56779,7 @@ var init_compact = __esm({
|
|
|
56637
56779
|
IMPORT_MAX_VALUES = 3;
|
|
56638
56780
|
LIST_ATTEMPTS = 6;
|
|
56639
56781
|
OWN_READ_TIMEOUT_MS = HISTORY_RPC_REQUEST_TIMEOUT_MS;
|
|
56640
|
-
BOUNDED_OWN_METHODS = /* @__PURE__ */ new Set(["getAccountInfo", "getAccountInfoAndContext", "getMultipleAccountsInfo"]);
|
|
56782
|
+
BOUNDED_OWN_METHODS = /* @__PURE__ */ new Set(["getAccountInfo", "getAccountInfoAndContext", "getMultipleAccountsInfo", "getMultipleAccountsInfoAndContext"]);
|
|
56641
56783
|
}
|
|
56642
56784
|
});
|
|
56643
56785
|
|
|
@@ -64067,6 +64209,8 @@ var init_errorCodes = __esm({
|
|
|
64067
64209
|
"p03_float_seller_unanswered_paid_retry_same_request",
|
|
64068
64210
|
"p03_float_seller_kept_payment",
|
|
64069
64211
|
"p03_float_receipt_pruned",
|
|
64212
|
+
"p03_float_request_expired_nothing_paid",
|
|
64213
|
+
"request_pruned",
|
|
64070
64214
|
// Our facilitator settle reasons the self-broadcast leg reads (floatPay.mjs BROADCAST_*), and its own quote-closing note.
|
|
64071
64215
|
"invalid_exact_svm_transaction_simulation_failed",
|
|
64072
64216
|
"p03_pocket_exact_lease_unreadable_retry",
|
|
@@ -92516,6 +92660,25 @@ var init_pay = __esm({
|
|
|
92516
92660
|
}
|
|
92517
92661
|
});
|
|
92518
92662
|
|
|
92663
|
+
// wallet/src/pay/floatWords.mjs
|
|
92664
|
+
function floatRefundWhy(error) {
|
|
92665
|
+
const why = error?.broadcastRefusal;
|
|
92666
|
+
if (why === "request_pruned") return "The wallet dropped this request 1 hour after it was made, so nothing was sent to the seller.";
|
|
92667
|
+
if (why === "seller_quote_closing") return "The seller's quote was about to close, so the wallet sent no transfer to the seller.";
|
|
92668
|
+
if (typeof why === "string" && why) return `Shinjuku's facilitator refused to send the transfer to the seller (${why}).`;
|
|
92669
|
+
return "Seller did not take it.";
|
|
92670
|
+
}
|
|
92671
|
+
function floatExpiredWhy(error) {
|
|
92672
|
+
return error?.broadcastRefusal === "request_pruned" ? "the wallet drops a request 1 hour after it was made, and this one was older" : "the seller's quote had too little time left to pay it safely (a payment needs about 2.5 minutes of it)";
|
|
92673
|
+
}
|
|
92674
|
+
var FLOAT_AMBIGUOUS_NOTE;
|
|
92675
|
+
var init_floatWords = __esm({
|
|
92676
|
+
"wallet/src/pay/floatWords.mjs"() {
|
|
92677
|
+
"use strict";
|
|
92678
|
+
FLOAT_AMBIGUOUS_NOTE = "An earlier send of this payment got no answer, from the seller or from Shinjuku's facilitator; if that send landed, the seller holds the payment and no refund comes.";
|
|
92679
|
+
}
|
|
92680
|
+
});
|
|
92681
|
+
|
|
92519
92682
|
// wallet/src/pay/floatPay.mjs
|
|
92520
92683
|
import { createHash as createHash21, createHmac as createHmac8, randomBytes as randomBytes11 } from "node:crypto";
|
|
92521
92684
|
import { fileURLToPath as fileURLToPath9 } from "node:url";
|
|
@@ -92592,9 +92755,8 @@ function refundArrived(snapshot, refundTo) {
|
|
|
92592
92755
|
function returnArrivedFloatRefundBudgets(store, snapshot) {
|
|
92593
92756
|
for (const name of store.listWal()) {
|
|
92594
92757
|
if (!name.startsWith(FLOAT_PAYMENT_WAL_PREFIX)) continue;
|
|
92595
|
-
|
|
92758
|
+
const record = store.readWal(name);
|
|
92596
92759
|
if (record?.schema !== FLOAT_PAYMENT_SCHEMA) continue;
|
|
92597
|
-
record = pruneFloatRecord(store, name, record);
|
|
92598
92760
|
if (record.state !== "refund_pending" || typeof record.innerRequestId !== "string") continue;
|
|
92599
92761
|
if (refundArrived(snapshot, record.refundTo)) releaseRefundedReservation({ store, requestId: record.innerRequestId });
|
|
92600
92762
|
}
|
|
@@ -92607,6 +92769,12 @@ function finishedAtMs(record) {
|
|
|
92607
92769
|
}
|
|
92608
92770
|
function pruneFloatRecord(store, walName2, record, now = Date.now()) {
|
|
92609
92771
|
const at = finishedAtMs(record);
|
|
92772
|
+
if (at === void 0 && record.requestPruned !== true && Number.isFinite(record.createdAtMs) && now >= record.createdAtMs + FLOAT_KEEP_OPEN_REQUEST_MS) {
|
|
92773
|
+
const { bodyBase64: _body2, headers: _headers2, ...request2 } = record.request ?? {};
|
|
92774
|
+
const open3 = { ...record, request: request2, requestPruned: true, prunedAtMs: now };
|
|
92775
|
+
store.writeWal(walName2, open3);
|
|
92776
|
+
return open3;
|
|
92777
|
+
}
|
|
92610
92778
|
if (record.pruned === true || !Number.isFinite(at) || now < at + FLOAT_KEEP_BYTES_MS) return record;
|
|
92611
92779
|
const { bodyBase64: _body, headers: _headers, ...request } = record.request ?? {};
|
|
92612
92780
|
const { resultBase64, sellerHeaders: _sellerHeaders, sellerReason: _reason, ...rest } = record;
|
|
@@ -92620,6 +92788,18 @@ function pruneFloatRecord(store, walName2, record, now = Date.now()) {
|
|
|
92620
92788
|
store.writeWal(walName2, pruned);
|
|
92621
92789
|
return pruned;
|
|
92622
92790
|
}
|
|
92791
|
+
function pruneFloatRecords(store, now = Date.now()) {
|
|
92792
|
+
for (const name of store.listWal()) {
|
|
92793
|
+
if (!name.startsWith(FLOAT_PAYMENT_WAL_PREFIX)) continue;
|
|
92794
|
+
let record;
|
|
92795
|
+
try {
|
|
92796
|
+
record = store.readWal(name);
|
|
92797
|
+
} catch {
|
|
92798
|
+
continue;
|
|
92799
|
+
}
|
|
92800
|
+
if (record?.schema === FLOAT_PAYMENT_SCHEMA) pruneFloatRecord(store, name, record, now);
|
|
92801
|
+
}
|
|
92802
|
+
}
|
|
92623
92803
|
function finishedPruned(record) {
|
|
92624
92804
|
const amounts = { floatId: record.floatId, paidAtomic: record.paidAtomic, priceAtomic: record.priceAtomic, feeAtomic: record.feeAtomic };
|
|
92625
92805
|
if (record.state === "receipt") {
|
|
@@ -92632,7 +92812,12 @@ function finishedPruned(record) {
|
|
|
92632
92812
|
...isSolanaSignature(record.broadcastSignature) ? { transaction: record.broadcastSignature } : { landedSignatureUnknown: true }
|
|
92633
92813
|
});
|
|
92634
92814
|
}
|
|
92635
|
-
fail18("p03_float_refund_pending", {
|
|
92815
|
+
fail18("p03_float_refund_pending", {
|
|
92816
|
+
...amounts,
|
|
92817
|
+
refundEtaSeconds: FLOAT_REFUND_ETA_SECONDS,
|
|
92818
|
+
ambiguous: record.ambiguous === true,
|
|
92819
|
+
...record.broadcastRefusal ? { broadcastRefusal: record.broadcastRefusal } : {}
|
|
92820
|
+
});
|
|
92636
92821
|
}
|
|
92637
92822
|
function floatRefundsInFlightAtomic(store, snapshot) {
|
|
92638
92823
|
const refreshedAtMs = Date.parse(snapshot?.refreshedAt ?? "");
|
|
@@ -93023,7 +93208,9 @@ async function payViaFloat({
|
|
|
93023
93208
|
if (record.schema !== FLOAT_PAYMENT_SCHEMA) fail18("p03_float_record_invalid");
|
|
93024
93209
|
if (record.fingerprint !== fingerprint) fail18("p03_float_request_id_conflict");
|
|
93025
93210
|
record = pruneFloatRecord(store, walName2, record);
|
|
93026
|
-
if (record.pruned !== true && JSON.stringify(record.request) !== JSON.stringify(requestData))
|
|
93211
|
+
if (record.pruned !== true && record.requestPruned !== true && JSON.stringify(record.request) !== JSON.stringify(requestData)) {
|
|
93212
|
+
fail18("p03_float_request_data_mismatch");
|
|
93213
|
+
}
|
|
93027
93214
|
if (record.pruned === true) finishedPruned(record);
|
|
93028
93215
|
if (record.state === "receipt") return paidResult(record, true);
|
|
93029
93216
|
} else {
|
|
@@ -93066,6 +93253,15 @@ async function payViaFloat({
|
|
|
93066
93253
|
store.writeWal(walName2, record);
|
|
93067
93254
|
mark("float-quoted");
|
|
93068
93255
|
}
|
|
93256
|
+
if (record.xPayment === void 0 && innerUnsent() && (record.requestPruned === true || record.selfBroadcast && Date.now() + SELF_BROADCAST_LEG1_LEFT_MS > record.selfBroadcast.expiresAtMs)) {
|
|
93257
|
+
store.removeWal(walName2);
|
|
93258
|
+
if (record.requestPruned === true) fail18("p03_float_request_expired_nothing_paid", {
|
|
93259
|
+
priceAtomic: record.priceAtomic,
|
|
93260
|
+
feeAtomic: record.feeAtomic,
|
|
93261
|
+
broadcastRefusal: "request_pruned"
|
|
93262
|
+
});
|
|
93263
|
+
quoteTooShort(record);
|
|
93264
|
+
}
|
|
93069
93265
|
if (record.xPayment === void 0) {
|
|
93070
93266
|
let regenerated = false;
|
|
93071
93267
|
const finishingUntil = Date.now() + FINISHING_LIMIT_MS;
|
|
@@ -93093,7 +93289,12 @@ async function payViaFloat({
|
|
|
93093
93289
|
...withoutCallerBody(deps),
|
|
93094
93290
|
fetchImpl: floatFetch(fetchImpl, seen),
|
|
93095
93291
|
settlePriorBeforeQuote: true,
|
|
93096
|
-
acceptFrontedReceipt: front
|
|
93292
|
+
acceptFrontedReceipt: front,
|
|
93293
|
+
// An anchor wait (up to one epoch + 60 s) can use up the seller's quote: the gate above runs again
|
|
93294
|
+
// before the fresh leg-1 402, while nothing of leg 1 exists (review 2026-10-16).
|
|
93295
|
+
...record.selfBroadcast ? { afterAnchorWait: () => {
|
|
93296
|
+
if (Date.now() + SELF_BROADCAST_LEG1_LEFT_MS > record.selfBroadcast.expiresAtMs) quoteTooShort(record);
|
|
93297
|
+
} } : {}
|
|
93097
93298
|
}
|
|
93098
93299
|
});
|
|
93099
93300
|
} catch (error) {
|
|
@@ -93135,6 +93336,25 @@ async function payViaFloat({
|
|
|
93135
93336
|
if (hash8(record.xPayment) !== record.headerSha256) fail18("p03_float_record_invalid");
|
|
93136
93337
|
if (record.selfBroadcast) return selfBroadcastLeg({ store, walName: walName2, record, fetchImpl, sleep: sleep5, mark });
|
|
93137
93338
|
const lostAnswer = record.state === "submitted";
|
|
93339
|
+
if (record.requestPruned === true) {
|
|
93340
|
+
record = {
|
|
93341
|
+
...record,
|
|
93342
|
+
state: "refund_pending",
|
|
93343
|
+
broadcastRefusal: "request_pruned",
|
|
93344
|
+
refundPendingAtMs: record.refundPendingAtMs ?? Date.now(),
|
|
93345
|
+
...lostAnswer ? { ambiguous: true } : {}
|
|
93346
|
+
};
|
|
93347
|
+
store.writeWal(walName2, record);
|
|
93348
|
+
fail18("p03_float_refund_pending", {
|
|
93349
|
+
floatId: record.floatId,
|
|
93350
|
+
paidAtomic: record.paidAtomic,
|
|
93351
|
+
priceAtomic: record.priceAtomic,
|
|
93352
|
+
feeAtomic: record.feeAtomic,
|
|
93353
|
+
refundEtaSeconds: FLOAT_REFUND_ETA_SECONDS,
|
|
93354
|
+
ambiguous: record.ambiguous === true,
|
|
93355
|
+
broadcastRefusal: "request_pruned"
|
|
93356
|
+
});
|
|
93357
|
+
}
|
|
93138
93358
|
record = { ...record, state: record.state === "refund_pending" ? "refund_pending" : "submitted", submittedAtMs: record.submittedAtMs ?? Date.now() };
|
|
93139
93359
|
store.writeWal(walName2, record);
|
|
93140
93360
|
mark("seller-sent");
|
|
@@ -93227,20 +93447,28 @@ async function selfBroadcastLeg({ store, walName: walName2, record, fetchImpl, s
|
|
|
93227
93447
|
if (record.state === "seller_kept") keptUnknown();
|
|
93228
93448
|
const settleUrl = new URL("/api/x402/settle", new URL(record.payUrlPrefix).origin).href;
|
|
93229
93449
|
const until = Date.now() + BROADCAST_LIMIT_MS;
|
|
93230
|
-
let
|
|
93450
|
+
let maybeSigned = record.broadcastMaybeSigned ?? record.broadcastAtMs !== void 0;
|
|
93451
|
+
if (record.broadcastInFlight === true) maybeSigned = true;
|
|
93231
93452
|
for (let attempt = 0; ; attempt += 1) {
|
|
93232
|
-
|
|
93453
|
+
const landBy = (record.floatPaidAtMs ?? record.createdAtMs ?? Date.now()) + TRANSFER_LANDING_WINDOW_MS;
|
|
93454
|
+
if (Date.now() > record.selfBroadcast.expiresAtMs - BROADCAST_QUOTE_MARGIN_MS || landBy > record.selfBroadcast.expiresAtMs - PROOF_DELIVERY_MS) {
|
|
93233
93455
|
record = {
|
|
93234
93456
|
...record,
|
|
93235
93457
|
state: "refund_pending",
|
|
93236
93458
|
broadcastRefusal: "seller_quote_closing",
|
|
93237
93459
|
refundPendingAtMs: record.refundPendingAtMs ?? Date.now(),
|
|
93238
|
-
...
|
|
93460
|
+
...maybeSigned ? { ambiguous: true } : {}
|
|
93239
93461
|
};
|
|
93240
93462
|
store.writeWal(walName2, record);
|
|
93241
93463
|
refundPending();
|
|
93242
93464
|
}
|
|
93243
|
-
record = {
|
|
93465
|
+
record = {
|
|
93466
|
+
...record,
|
|
93467
|
+
state: "broadcasting",
|
|
93468
|
+
broadcastAtMs: record.broadcastAtMs ?? Date.now(),
|
|
93469
|
+
broadcastInFlight: true,
|
|
93470
|
+
broadcastMaybeSigned: maybeSigned
|
|
93471
|
+
};
|
|
93244
93472
|
store.writeWal(walName2, record);
|
|
93245
93473
|
if (attempt === 0) mark("float-broadcast-sent");
|
|
93246
93474
|
let answer;
|
|
@@ -93268,14 +93496,21 @@ async function selfBroadcastLeg({ store, walName: walName2, record, fetchImpl, s
|
|
|
93268
93496
|
store.writeWal(walName2, record);
|
|
93269
93497
|
keptUnknown();
|
|
93270
93498
|
}
|
|
93271
|
-
|
|
93272
|
-
|
|
93499
|
+
const refused = BROADCAST_REFUSED.has(reason) || BROADCAST_REFUSED_STANDARD.test(reason);
|
|
93500
|
+
if (BROADCAST_DEAD.has(reason) || refused) {
|
|
93501
|
+
record = {
|
|
93502
|
+
...record,
|
|
93503
|
+
state: "refund_pending",
|
|
93504
|
+
broadcastRefusal: plainText(reason),
|
|
93505
|
+
refundPendingAtMs: record.refundPendingAtMs ?? Date.now(),
|
|
93506
|
+
broadcastInFlight: false,
|
|
93507
|
+
...refused && maybeSigned ? { ambiguous: true } : {}
|
|
93508
|
+
};
|
|
93273
93509
|
store.writeWal(walName2, record);
|
|
93274
93510
|
refundPending();
|
|
93275
93511
|
}
|
|
93276
|
-
if (BROADCAST_UNSIGNED.has(reason))
|
|
93277
|
-
|
|
93278
|
-
record = { ...record, broadcastUnsigned: unsigned };
|
|
93512
|
+
if (!BROADCAST_UNSIGNED.has(reason) && !BROADCAST_NO_LOOKUP.has(reason)) maybeSigned = true;
|
|
93513
|
+
record = { ...record, broadcastInFlight: false, broadcastMaybeSigned: maybeSigned };
|
|
93279
93514
|
store.writeWal(walName2, record);
|
|
93280
93515
|
if (Date.now() >= until) fail18("p03_float_broadcast_pending_retry_same_request", { floatId: record.floatId });
|
|
93281
93516
|
await sleep5(FINISHING_POLL_MS);
|
|
@@ -93289,6 +93524,11 @@ async function selfBroadcastLeg({ store, walName: walName2, record, fetchImpl, s
|
|
|
93289
93524
|
signature: record.broadcastSignature
|
|
93290
93525
|
})).toString("base64");
|
|
93291
93526
|
const landed = { floatId: record.floatId, transaction: record.broadcastSignature, paidAtomic: record.paidAtomic };
|
|
93527
|
+
if (record.requestPruned === true) {
|
|
93528
|
+
record = { ...record, state: "seller_kept", sellerKeptAtMs: record.sellerKeptAtMs ?? Date.now() };
|
|
93529
|
+
store.writeWal(walName2, record);
|
|
93530
|
+
fail18("p03_float_seller_kept_payment", { ...landed, priceAtomic: record.priceAtomic, feeAtomic: record.feeAtomic });
|
|
93531
|
+
}
|
|
93292
93532
|
for (let attempt = 0; ; attempt += 1) {
|
|
93293
93533
|
if (record.state !== "seller_kept") {
|
|
93294
93534
|
record = { ...record, state: "submitted", submittedAtMs: record.submittedAtMs ?? Date.now() };
|
|
@@ -93355,6 +93595,13 @@ async function selfBroadcastLeg({ store, walName: walName2, record, fetchImpl, s
|
|
|
93355
93595
|
});
|
|
93356
93596
|
}
|
|
93357
93597
|
}
|
|
93598
|
+
function quoteTooShort(record) {
|
|
93599
|
+
fail18("p03_float_request_expired_nothing_paid", {
|
|
93600
|
+
priceAtomic: record.priceAtomic,
|
|
93601
|
+
feeAtomic: record.feeAtomic,
|
|
93602
|
+
broadcastRefusal: "seller_quote_closing"
|
|
93603
|
+
});
|
|
93604
|
+
}
|
|
93358
93605
|
function withoutCallerBody(deps) {
|
|
93359
93606
|
const {
|
|
93360
93607
|
freshRequestBody: _fresh,
|
|
@@ -93372,7 +93619,7 @@ function keptSellerHeaders(headers) {
|
|
|
93372
93619
|
let bytes2 = 0;
|
|
93373
93620
|
for (const [name, value] of headers) {
|
|
93374
93621
|
if (kept.length >= SELLER_HEADERS_MAX_COUNT) break;
|
|
93375
|
-
if (
|
|
93622
|
+
if (!SELLER_HEADERS_KEPT.has(String(name).toLowerCase())) continue;
|
|
93376
93623
|
const size = Buffer.byteLength(name) + Buffer.byteLength(value);
|
|
93377
93624
|
if (bytes2 + size > SELLER_HEADERS_MAX_BYTES) continue;
|
|
93378
93625
|
bytes2 += size;
|
|
@@ -93396,7 +93643,7 @@ function paidResult(record, replayed) {
|
|
|
93396
93643
|
float: { floatId: record.floatId }
|
|
93397
93644
|
};
|
|
93398
93645
|
}
|
|
93399
|
-
var import_web3109, FLOAT_PAYMENT_SCHEMA, REGENERATE_CODES, FLOAT_PAYMENT_WAL_PREFIX, FLOAT_CONFIG_SCHEMA, FLOAT_PAY_PATH, MAX_BODY_BYTES, FLOAT_REFUND_ETA_SECONDS, REFUND_SETTLED_AFTER_MS, FINISHING_POLL_MS, FINISHING_LIMIT_MS, SELLER_TIMEOUT_MS, CONFIG_TIMEOUT_MS, CONFIG_CACHE_MS, DECIMAL3, POSITIVE, PENDING_CODES, FLOAT_FRONT_HEADER, hash8, fail18, floatPaymentWalName, FLOAT_KEEP_BYTES_MS, configCache, configReads, poolDomains, poolDomainReads, poolDomainWarmFailedAt, WARM_RETRY_MS, payerGenerator, etaEntry, loadPayerGenerator, plainText, BROADCAST_DEAD,
|
|
93646
|
+
var import_web3109, FLOAT_PAYMENT_SCHEMA, REGENERATE_CODES, FLOAT_PAYMENT_WAL_PREFIX, FLOAT_CONFIG_SCHEMA, FLOAT_PAY_PATH, MAX_BODY_BYTES, FLOAT_REFUND_ETA_SECONDS, REFUND_SETTLED_AFTER_MS, FINISHING_POLL_MS, FINISHING_LIMIT_MS, SELLER_TIMEOUT_MS, CONFIG_TIMEOUT_MS, CONFIG_CACHE_MS, DECIMAL3, POSITIVE, PENDING_CODES, FLOAT_FRONT_HEADER, hash8, fail18, floatPaymentWalName, FLOAT_KEEP_BYTES_MS, FLOAT_KEEP_OPEN_REQUEST_MS, configCache, configReads, poolDomains, poolDomainReads, poolDomainWarmFailedAt, WARM_RETRY_MS, payerGenerator, etaEntry, loadPayerGenerator, plainText, BROADCAST_REFUSED, BROADCAST_REFUSED_STANDARD, BROADCAST_DEAD, TRANSFER_LANDING_WINDOW_MS, PROOF_DELIVERY_MS, SELF_BROADCAST_LEG1_LEFT_MS, BROADCAST_UNSIGNED, BROADCAST_NO_LOOKUP, BROADCAST_LANDED, BROADCAST_LIMIT_MS, BROADCAST_QUOTE_MARGIN_MS, SELF_BROADCAST_RESEND_MS, SELLER_HEADERS_MAX_COUNT, SELLER_HEADERS_MAX_BYTES, SELLER_HEADERS_KEPT;
|
|
93400
93647
|
var init_floatPay = __esm({
|
|
93401
93648
|
"wallet/src/pay/floatPay.mjs"() {
|
|
93402
93649
|
"use strict";
|
|
@@ -93413,6 +93660,7 @@ var init_floatPay = __esm({
|
|
|
93413
93660
|
init_store();
|
|
93414
93661
|
init_proxy();
|
|
93415
93662
|
init_payResource();
|
|
93663
|
+
init_floatWords();
|
|
93416
93664
|
FLOAT_PAYMENT_SCHEMA = "carbon-shielded-wallet/float-payment/v1";
|
|
93417
93665
|
REGENERATE_CODES = /* @__PURE__ */ new Set(["float_payment_in_flight", "float_quote_open"]);
|
|
93418
93666
|
FLOAT_PAYMENT_WAL_PREFIX = "float-";
|
|
@@ -93436,6 +93684,7 @@ var init_floatPay = __esm({
|
|
|
93436
93684
|
};
|
|
93437
93685
|
floatPaymentWalName = (requestKey) => `${FLOAT_PAYMENT_WAL_PREFIX}${requestKey}`;
|
|
93438
93686
|
FLOAT_KEEP_BYTES_MS = 6e5;
|
|
93687
|
+
FLOAT_KEEP_OPEN_REQUEST_MS = 36e5;
|
|
93439
93688
|
configCache = /* @__PURE__ */ new Map();
|
|
93440
93689
|
configReads = /* @__PURE__ */ new Map();
|
|
93441
93690
|
poolDomains = /* @__PURE__ */ new Map();
|
|
@@ -93447,7 +93696,7 @@ var init_floatPay = __esm({
|
|
|
93447
93696
|
new URL("__bundled_source__/wallet/src/pay/floatPay.mjs", import.meta.url).href
|
|
93448
93697
|
)), "utf8")).payerKeys.generator;
|
|
93449
93698
|
plainText = (value) => value.replace(/[^ -~]+/g, " ").trim().slice(0, 300);
|
|
93450
|
-
|
|
93699
|
+
BROADCAST_REFUSED = /* @__PURE__ */ new Set([
|
|
93451
93700
|
"unsupported_scheme",
|
|
93452
93701
|
"pocket_payment_network_unsupported",
|
|
93453
93702
|
"pocket_payment_asset_not_pool_mint",
|
|
@@ -93460,12 +93709,14 @@ var init_floatPay = __esm({
|
|
|
93460
93709
|
"pocket_authority_is_facilitator_signer",
|
|
93461
93710
|
"pocket_bound_to_other_payee",
|
|
93462
93711
|
"pocket_payment_count_exceeded",
|
|
93463
|
-
"pocket_credit_exceeded"
|
|
93464
|
-
"settlement_expired",
|
|
93465
|
-
"transaction_failed",
|
|
93466
|
-
"settlement_reverted"
|
|
93712
|
+
"pocket_credit_exceeded"
|
|
93467
93713
|
]);
|
|
93468
|
-
|
|
93714
|
+
BROADCAST_REFUSED_STANDARD = /^invalid_exact_svm_(?!.*simulation)[a-z_]+$/;
|
|
93715
|
+
BROADCAST_DEAD = /* @__PURE__ */ new Set(["settlement_expired", "transaction_failed", "settlement_reverted"]);
|
|
93716
|
+
TRANSFER_LANDING_WINDOW_MS = 12e4;
|
|
93717
|
+
PROOF_DELIVERY_MS = 1e4;
|
|
93718
|
+
SELF_BROADCAST_LEG1_LEFT_MS = TRANSFER_LANDING_WINDOW_MS + PROOF_DELIVERY_MS + 15e3;
|
|
93719
|
+
if (SELF_BROADCAST_MIN_LEFT_MS < SELF_BROADCAST_LEG1_LEFT_MS) throw new Error("self-broadcast offer minimum below the leg-1 minimum");
|
|
93469
93720
|
BROADCAST_UNSIGNED = /* @__PURE__ */ new Set([
|
|
93470
93721
|
"transaction_simulation_failed",
|
|
93471
93722
|
"invalid_exact_svm_transaction_simulation_failed",
|
|
@@ -93479,27 +93730,7 @@ var init_floatPay = __esm({
|
|
|
93479
93730
|
SELF_BROADCAST_RESEND_MS = [1e3, 2e3, 4e3, 8e3];
|
|
93480
93731
|
SELLER_HEADERS_MAX_COUNT = 32;
|
|
93481
93732
|
SELLER_HEADERS_MAX_BYTES = 8 * 1024;
|
|
93482
|
-
|
|
93483
|
-
"set-cookie",
|
|
93484
|
-
"set-cookie2",
|
|
93485
|
-
"payment-response",
|
|
93486
|
-
"x-payment-response",
|
|
93487
|
-
"connection",
|
|
93488
|
-
"keep-alive",
|
|
93489
|
-
"proxy-authenticate",
|
|
93490
|
-
"proxy-authorization",
|
|
93491
|
-
"proxy-connection",
|
|
93492
|
-
"te",
|
|
93493
|
-
"trailer",
|
|
93494
|
-
"transfer-encoding",
|
|
93495
|
-
"upgrade",
|
|
93496
|
-
"content-length",
|
|
93497
|
-
"content-encoding",
|
|
93498
|
-
"cf-ray",
|
|
93499
|
-
"traceparent",
|
|
93500
|
-
"tracestate"
|
|
93501
|
-
]);
|
|
93502
|
-
SELLER_HEADERS_LINKING = /(^|-)(request|trace|correlation)-id$|^x-balance-|^x-pod-(?!route$)|^x-amzn?-/;
|
|
93733
|
+
SELLER_HEADERS_KEPT = /* @__PURE__ */ new Set(["content-type", "content-language", "cache-control", "retry-after", "x-pod-route"]);
|
|
93503
93734
|
}
|
|
93504
93735
|
});
|
|
93505
93736
|
|
|
@@ -94544,6 +94775,7 @@ async function payResourceOnce({
|
|
|
94544
94775
|
{ connection, pool: store.state.pool }
|
|
94545
94776
|
))) {
|
|
94546
94777
|
mark("anchor-wait-done");
|
|
94778
|
+
deps.afterAnchorWait?.();
|
|
94547
94779
|
continue;
|
|
94548
94780
|
}
|
|
94549
94781
|
throw error;
|
|
@@ -100762,6 +100994,15 @@ function errorBody(error) {
|
|
|
100762
100994
|
message: `nothing was paid: usePod's price plus the Shinjuku fee${total ? ` (${total} atomic USDC)` : ""} is above this server's max payment per request. Lower max_tokens, or restart infer serve with --max-payment of at least ${total ?? "price + fee"}`
|
|
100763
100995
|
} } };
|
|
100764
100996
|
}
|
|
100997
|
+
if (code === "p03_float_request_expired_nothing_paid") {
|
|
100998
|
+
const why = floatExpiredWhy({ broadcastRefusal: error?.broadcastRefusal ?? error?.cause?.broadcastRefusal });
|
|
100999
|
+
return { status: 503, body: { error: {
|
|
101000
|
+
type: OPENAI_TYPE.api,
|
|
101001
|
+
param: null,
|
|
101002
|
+
code,
|
|
101003
|
+
message: `nothing was paid: ${why}. Send the same request again: it reads a fresh quote from usePod and pays once`
|
|
101004
|
+
} } };
|
|
101005
|
+
}
|
|
100765
101006
|
if (code === "p03_float_request_data_mismatch" || code === "p03_float_request_id_conflict") {
|
|
100766
101007
|
return { status: 400, body: { error: {
|
|
100767
101008
|
type: OPENAI_TYPE.request,
|
|
@@ -100782,6 +101023,7 @@ function errorBody(error) {
|
|
|
100782
101023
|
}
|
|
100783
101024
|
function moneyMayHaveMoved(error, code) {
|
|
100784
101025
|
if (!code) return true;
|
|
101026
|
+
if (/_nothing_paid$/.test(code)) return false;
|
|
100785
101027
|
if (/_retry_same_request$/.test(code) || /_refund_pending$/.test(code)) return true;
|
|
100786
101028
|
for (const one of [error, error?.cause]) {
|
|
100787
101029
|
if (code.startsWith("p03_float_") && (one?.floatId ?? one?.details?.floatId) !== void 0) return true;
|
|
@@ -101026,6 +101268,7 @@ var INFERENCE_SERVE_HOST, INFERENCE_SERVE_PORT, BODY_LIMIT_BYTES, IDEMPOTENCY_KE
|
|
|
101026
101268
|
var init_serve = __esm({
|
|
101027
101269
|
"wallet/src/inference/serve.mjs"() {
|
|
101028
101270
|
"use strict";
|
|
101271
|
+
init_floatWords();
|
|
101029
101272
|
INFERENCE_SERVE_HOST = "127.0.0.1";
|
|
101030
101273
|
INFERENCE_SERVE_PORT = 11402;
|
|
101031
101274
|
BODY_LIMIT_BYTES = 1024 * 1024;
|
|
@@ -128639,13 +128882,19 @@ function floatRefusal(error) {
|
|
|
128639
128882
|
case "p03_float_answer_invalid_refund_pending":
|
|
128640
128883
|
return [
|
|
128641
128884
|
code,
|
|
128642
|
-
|
|
128885
|
+
`${floatRefundWhy(error)} Refund of ${error?.paidAtomic ?? "the amount paid"} atomic on the way (up to ${Math.ceil((error?.refundEtaSeconds ?? FLOAT_REFUND_ETA_SECONDS) / 60)} min). Nothing more to do.` + (typeof error?.sellerReason === "string" ? ` The seller answered HTTP ${error.httpStatus}: ${JSON.stringify(error.sellerReason)}.` : "") + (error?.ambiguous === true ? ` (${FLOAT_AMBIGUOUS_NOTE})` : ""),
|
|
128643
128886
|
"Nothing more to do: the refund comes back to balanceAtomic by itself. Do not call x402_pay again with this request_id. To try this seller again, use a NEW request_id"
|
|
128644
128887
|
];
|
|
128888
|
+
case "p03_float_request_expired_nothing_paid":
|
|
128889
|
+
return [
|
|
128890
|
+
code,
|
|
128891
|
+
`${floatExpiredWhy(error)}; nothing was paid`,
|
|
128892
|
+
"Nothing was paid. Call x402_pay again: it reads a fresh quote from the seller and pays once"
|
|
128893
|
+
];
|
|
128645
128894
|
case "p03_float_receipt_pruned":
|
|
128646
128895
|
return [
|
|
128647
128896
|
code,
|
|
128648
|
-
`this request_id was paid and answered more than 10 minutes ago${typeof error?.transaction === "string" ? ` (${error.transaction})` : ""}; the wallet
|
|
128897
|
+
`this request_id was paid and answered more than 10 minutes ago${typeof error?.transaction === "string" ? ` (${error.transaction})` : ""}; the wallet keeps an answer 10 minutes after the call, then only its hash, and nothing was paid again`,
|
|
128649
128898
|
"To ask again, call with a NEW request_id (it pays again)"
|
|
128650
128899
|
];
|
|
128651
128900
|
case "p03_float_broadcast_pending_retry_same_request":
|
|
@@ -128930,6 +129179,10 @@ async function refreshWallet({ session, store, history: walked, share }) {
|
|
|
128930
129179
|
});
|
|
128931
129180
|
writeBalanceSnapshot(store, snapshot);
|
|
128932
129181
|
returnArrivedFloatRefundBudgets(store, snapshot);
|
|
129182
|
+
try {
|
|
129183
|
+
pruneFloatRecords(store);
|
|
129184
|
+
} catch {
|
|
129185
|
+
}
|
|
128933
129186
|
prepareFinalizedP03RecoveryFold(history).catch(() => {
|
|
128934
129187
|
});
|
|
128935
129188
|
}
|
|
@@ -137588,10 +137841,10 @@ async function offerFundNow(deps, path) {
|
|
|
137588
137841
|
const io = deps.io;
|
|
137589
137842
|
for (let attempt = 0; attempt < 3; attempt += 1) {
|
|
137590
137843
|
const answer = String(await deps.ask("Fund and shield now? Amount in USDC (Enter to skip): ")).trim();
|
|
137591
|
-
if (!answer) break;
|
|
137844
|
+
if (!answer || /^(n|no|skip)$/i.test(answer)) break;
|
|
137592
137845
|
const atomic3 = usdcToAtomic(answer);
|
|
137593
137846
|
if (!atomic3 || BigInt(atomic3) % 1000000n !== 0n) {
|
|
137594
|
-
io.err("Type a whole number of USDC, like 2 (a relayed deposit takes whole USDC only), or press Enter to skip.\n");
|
|
137847
|
+
io.err("Type a whole number of USDC, like 2 (a relayed deposit takes whole USDC only), or press Enter (or n) to skip.\n");
|
|
137595
137848
|
continue;
|
|
137596
137849
|
}
|
|
137597
137850
|
const argv = path.fund.map((word, index) => path.fund[index - 1] === "--amount" ? atomic3 : word);
|
|
@@ -137727,11 +137980,14 @@ async function runSetupCommand(values, deps) {
|
|
|
137727
137980
|
return setupBehindTor(setupArgvOf(values), deps);
|
|
137728
137981
|
}
|
|
137729
137982
|
const missing = missingPieces(home, old);
|
|
137983
|
+
const introduced = values.has("--yes") && inProxiedRun(deps.env);
|
|
137730
137984
|
io.out([
|
|
137731
|
-
|
|
137732
|
-
|
|
137733
|
-
|
|
137734
|
-
|
|
137985
|
+
...introduced ? [] : [
|
|
137986
|
+
"Shinjuku Shielded: a self-custody wallet that pays x402 URLs privately from a shielded USDC balance.",
|
|
137987
|
+
"Setup makes the wallet on this machine (your keys never leave it), downloads and checks the proof tools, and writes config.json.",
|
|
137988
|
+
"An agent host then starts it with one command: npx -y shinjuku-shielded mcp",
|
|
137989
|
+
""
|
|
137990
|
+
],
|
|
137735
137991
|
old ? `Status: ${missing.includes("pool-retired") ? `set up before for a retired pool: ${retiredPoolText(old.pool).split("; run ")[0]}. This run moves config.json to the new pool and makes its wallet` : missing.length ? `set up before; missing now: ${missing.join(", ")}` : "set up; every piece is checked again"} (home ${home}).` : `Home: ${home}`,
|
|
137736
137992
|
""
|
|
137737
137993
|
].join("\n"));
|
|
@@ -139484,6 +139740,7 @@ async function refreshSnapshot(args, values, deps) {
|
|
|
139484
139740
|
const walStates = captureWalStates(store);
|
|
139485
139741
|
const { result, history } = await deps.runRecoverCommand(args.filter((token) => token !== "--refresh"));
|
|
139486
139742
|
assertAuthenticatedFinalizedP03History(history);
|
|
139743
|
+
let saved;
|
|
139487
139744
|
const save2 = () => {
|
|
139488
139745
|
const snapshot = snapshotFromRecovery({
|
|
139489
139746
|
state: store.state,
|
|
@@ -139495,16 +139752,32 @@ async function refreshSnapshot(args, values, deps) {
|
|
|
139495
139752
|
now: deps.now()
|
|
139496
139753
|
});
|
|
139497
139754
|
writeBalanceSnapshot(store, snapshot);
|
|
139498
|
-
|
|
139755
|
+
saved = snapshot;
|
|
139499
139756
|
};
|
|
139500
|
-
|
|
139757
|
+
const prune = async () => {
|
|
139758
|
+
let release;
|
|
139759
|
+
try {
|
|
139760
|
+
release = await (deps.acquireLease ?? acquireWalletProcessLease)(walletLockPath(deps.walletPath(values.get("--pool"))));
|
|
139761
|
+
} catch {
|
|
139762
|
+
return;
|
|
139763
|
+
}
|
|
139764
|
+
try {
|
|
139765
|
+
const fresh = openPoolWallet(values, deps);
|
|
139766
|
+
if (saved) returnArrivedFloatRefundBudgets(fresh, saved);
|
|
139767
|
+
pruneFloatRecords(fresh);
|
|
139768
|
+
} catch {
|
|
139769
|
+
} finally {
|
|
139770
|
+
await release();
|
|
139771
|
+
}
|
|
139772
|
+
};
|
|
139773
|
+
return { store, result, save: save2, prune };
|
|
139501
139774
|
}
|
|
139502
139775
|
function warnUnsavedSync(result, io) {
|
|
139503
139776
|
if (result?.memoSync?.cache !== "unwritable") return;
|
|
139504
139777
|
io.err("warning: the recovery cache (recovery-cache.json beside wallet.json) was not saved; the next recover or balance --refresh reads every memo again\n");
|
|
139505
139778
|
}
|
|
139506
139779
|
async function runRecoverAndSave(args, values, deps, io) {
|
|
139507
|
-
const { result, save: save2 } = await refreshSnapshot(args, values, deps);
|
|
139780
|
+
const { result, save: save2, prune } = await refreshSnapshot(args, values, deps);
|
|
139508
139781
|
io.out(`${JSON.stringify(recoverSummary(result), null, 2)}
|
|
139509
139782
|
`);
|
|
139510
139783
|
warnUnsavedSync(result, io);
|
|
@@ -139519,6 +139792,7 @@ async function runRecoverAndSave(args, values, deps, io) {
|
|
|
139519
139792
|
io.err(`warning: the balance walk was not saved (${describeCliError(error, { fallback: "balance_snapshot_unwritable" })}); balance will ask for --refresh
|
|
139520
139793
|
`);
|
|
139521
139794
|
}
|
|
139795
|
+
await prune();
|
|
139522
139796
|
}
|
|
139523
139797
|
var RELAYED_DEPOSIT_UNIT = Object.freeze({
|
|
139524
139798
|
DFCCPHdw7pH9vKk9FEN9z6cy9M1UKjF168j7HfLwxYk3: "1000000",
|
|
@@ -139703,6 +139977,7 @@ async function runBalance(args, values, deps, io) {
|
|
|
139703
139977
|
const refreshed = await refreshSnapshot(args, values, deps);
|
|
139704
139978
|
warnUnsavedSync(refreshed.result, io);
|
|
139705
139979
|
refreshed.save();
|
|
139980
|
+
await refreshed.prune();
|
|
139706
139981
|
store = refreshed.store;
|
|
139707
139982
|
earlierDeposits = await (deps.adoptOneTime ?? adoptOneTimeForBalance)({ store, values, deps, io });
|
|
139708
139983
|
} else {
|
|
@@ -140197,7 +140472,10 @@ function privacyCashFailureHint(reason) {
|
|
|
140197
140472
|
function floatFailureHint(reason) {
|
|
140198
140473
|
const config = "GET <facilitator>/api/x402/float/config";
|
|
140199
140474
|
if (/p03_float_refund_pending/.test(reason) && !/answer_invalid/.test(reason)) {
|
|
140200
|
-
return "
|
|
140475
|
+
return "the payment did not reach the seller (the lines above say why); refund of the amount paid (price + fee) on the way (up to about 7 min). Nothing more to do: the refund lands in your shielded balance by itself";
|
|
140476
|
+
}
|
|
140477
|
+
if (/p03_float_request_expired_nothing_paid/.test(reason)) {
|
|
140478
|
+
return "nothing was paid: rerun the same command; it reads a fresh quote from the seller and pays once";
|
|
140201
140479
|
}
|
|
140202
140480
|
if (/p03_float_answer_invalid_refund_pending/.test(reason)) {
|
|
140203
140481
|
return "Shinjuku was paid, but its answer held no valid payment for this seller, so nothing went to the seller. Refund of the amount paid (price + fee) on the way (up to about 7 min). Nothing more to do";
|
|
@@ -140243,7 +140521,7 @@ function floatFailureHint(reason) {
|
|
|
140243
140521
|
return "the transfer to the seller landed (transaction above), but the seller did not answer (or answered with a server error). Rerun the exact same command: it sends the same proof of payment again and never pays twice";
|
|
140244
140522
|
}
|
|
140245
140523
|
if (/p03_float_receipt_pruned/.test(reason)) {
|
|
140246
|
-
return "this request id was paid and answered more than 10 minutes ago; the wallet
|
|
140524
|
+
return "this request id was paid and answered more than 10 minutes ago; the wallet keeps an answer 10 minutes after the call, then only its hash, and nothing was paid again. To ask again, run the command with a new request id (it pays again)";
|
|
140247
140525
|
}
|
|
140248
140526
|
if (/p03_float_seller_kept_payment/.test(reason)) {
|
|
140249
140527
|
return "the transfer to the seller landed (its transaction is above when the wallet knows it), but the seller did not serve the request. The seller holds the payment, so no refund comes from Shinjuku. Rerun the exact same command once to resend the same proof; if it is refused again, do not pay this seller";
|
|
@@ -140520,9 +140798,15 @@ next: fund that address, then rerun the same command; it continues where it stop
|
|
|
140520
140798
|
` : "";
|
|
140521
140799
|
const landedTx = error?.transaction ?? error?.cause?.transaction;
|
|
140522
140800
|
const landedLine = /^p03_float_seller_(kept_payment|unanswered_paid)/.test(reason) && typeof landedTx === "string" ? `transfer to the seller landed: ${landedTx}
|
|
140801
|
+
` : "";
|
|
140802
|
+
const floatError = { broadcastRefusal: error?.broadcastRefusal ?? error?.cause?.broadcastRefusal };
|
|
140803
|
+
const whyLine = /^p03_float_refund_pending/.test(reason) ? `why: ${floatRefundWhy(floatError)}
|
|
140804
|
+
` : /^p03_float_request_expired_nothing_paid/.test(reason) ? `why: ${floatExpiredWhy(floatError)}
|
|
140805
|
+
` : "";
|
|
140806
|
+
const ambiguousLine = /^p03_float_refund_pending/.test(reason) && (error?.ambiguous ?? error?.cause?.ambiguous) === true ? `note: ${FLOAT_AMBIGUOUS_NOTE}
|
|
140523
140807
|
` : "";
|
|
140524
140808
|
io.err(`${CLI2} ${command.name} failed: ${reason}
|
|
140525
|
-
${sellerLine}${landedLine}${blockingLine}${hint ? `hint: ${hint}
|
|
140809
|
+
${sellerLine}${landedLine}${whyLine}${ambiguousLine}${blockingLine}${hint ? `hint: ${hint}
|
|
140526
140810
|
` : ""}Help: ${CLI2} help ${command.name}
|
|
140527
140811
|
`);
|
|
140528
140812
|
return 1;
|