mnemospark 0.1.21 → 0.1.22
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/README.md +2 -0
- package/dist/cli.js +220 -79
- package/dist/cli.js.map +1 -1
- package/dist/index.d.ts +9 -0
- package/dist/index.js +220 -79
- package/dist/index.js.map +1 -1
- package/openclaw.plugin.json +1 -1
- package/package.json +2 -1
- package/skills/mnemospark/SKILL.md +38 -0
- package/skills/mnemospark/references/commands.md +42 -0
- package/skills/mnemospark/references/state-and-logs.md +40 -0
- package/skills/mnemospark/references/troubleshooting.md +36 -0
- package/skills/mnemospark/scripts/debug-operation.sh +184 -0
package/dist/index.js
CHANGED
|
@@ -327,6 +327,21 @@ async function createWalletSignatureHeaderValue(method, path, walletAddress, wal
|
|
|
327
327
|
return encodeBase64Json(headerEnvelope);
|
|
328
328
|
}
|
|
329
329
|
|
|
330
|
+
// src/cloud-correlation.ts
|
|
331
|
+
var MNEMOSPARK_TRACE_ID_HEADER = "X-Mnemospark-Trace-Id";
|
|
332
|
+
var MNEMOSPARK_OPERATION_ID_HEADER = "X-Mnemospark-Operation-Id";
|
|
333
|
+
function applyCorrelationHeaders(headers, correlation) {
|
|
334
|
+
const traceId = correlation?.traceId?.trim();
|
|
335
|
+
if (traceId) {
|
|
336
|
+
headers[MNEMOSPARK_TRACE_ID_HEADER] = traceId;
|
|
337
|
+
}
|
|
338
|
+
const operationId = correlation?.operationId?.trim();
|
|
339
|
+
if (operationId) {
|
|
340
|
+
headers[MNEMOSPARK_OPERATION_ID_HEADER] = operationId;
|
|
341
|
+
}
|
|
342
|
+
return headers;
|
|
343
|
+
}
|
|
344
|
+
|
|
330
345
|
// src/cloud-utils.ts
|
|
331
346
|
function normalizeBaseUrl(baseUrl) {
|
|
332
347
|
return baseUrl.replace(/\/+$/, "");
|
|
@@ -556,9 +571,12 @@ async function requestPriceStorageViaProxy(request, options = {}) {
|
|
|
556
571
|
);
|
|
557
572
|
const response = await fetchImpl(`${baseUrl}${PRICE_STORAGE_PROXY_PATH}`, {
|
|
558
573
|
method: "POST",
|
|
559
|
-
headers:
|
|
560
|
-
|
|
561
|
-
|
|
574
|
+
headers: applyCorrelationHeaders(
|
|
575
|
+
{
|
|
576
|
+
"Content-Type": "application/json"
|
|
577
|
+
},
|
|
578
|
+
options.correlation
|
|
579
|
+
),
|
|
562
580
|
body: JSON.stringify(request)
|
|
563
581
|
});
|
|
564
582
|
const responseBody = await response.text();
|
|
@@ -583,6 +601,7 @@ async function requestStorageUploadViaProxy(request, options = {}) {
|
|
|
583
601
|
const requestHeaders = {
|
|
584
602
|
"Content-Type": "application/json"
|
|
585
603
|
};
|
|
604
|
+
applyCorrelationHeaders(requestHeaders, options.correlation);
|
|
586
605
|
if (options.idempotencyKey && options.idempotencyKey.trim().length > 0) {
|
|
587
606
|
requestHeaders["Idempotency-Key"] = options.idempotencyKey.trim();
|
|
588
607
|
}
|
|
@@ -664,9 +683,12 @@ async function requestStorageUploadConfirmViaProxy(request, options = {}) {
|
|
|
664
683
|
);
|
|
665
684
|
const response = await fetchImpl(`${baseUrl}${UPLOAD_CONFIRM_PROXY_PATH}`, {
|
|
666
685
|
method: "POST",
|
|
667
|
-
headers:
|
|
668
|
-
|
|
669
|
-
|
|
686
|
+
headers: applyCorrelationHeaders(
|
|
687
|
+
{
|
|
688
|
+
"Content-Type": "application/json"
|
|
689
|
+
},
|
|
690
|
+
options.correlation
|
|
691
|
+
),
|
|
670
692
|
body: JSON.stringify(request)
|
|
671
693
|
});
|
|
672
694
|
const responseBody = await response.text();
|
|
@@ -781,7 +803,7 @@ async function requestPaymentSettleViaProxy(quoteId, walletAddress, options = {}
|
|
|
781
803
|
}
|
|
782
804
|
const response = await fetchImpl(targetUrl, {
|
|
783
805
|
method: "POST",
|
|
784
|
-
headers: { "Content-Type": "application/json" },
|
|
806
|
+
headers: applyCorrelationHeaders({ "Content-Type": "application/json" }, options.correlation),
|
|
785
807
|
body: JSON.stringify(requestBody)
|
|
786
808
|
});
|
|
787
809
|
return {
|
|
@@ -1265,9 +1287,12 @@ async function requestJsonViaProxy(proxyPath, request, parser, options = {}) {
|
|
|
1265
1287
|
);
|
|
1266
1288
|
const response = await fetchImpl(`${baseUrl}${proxyPath}`, {
|
|
1267
1289
|
method: "POST",
|
|
1268
|
-
headers:
|
|
1269
|
-
|
|
1270
|
-
|
|
1290
|
+
headers: applyCorrelationHeaders(
|
|
1291
|
+
{
|
|
1292
|
+
"Content-Type": "application/json"
|
|
1293
|
+
},
|
|
1294
|
+
options.correlation
|
|
1295
|
+
),
|
|
1271
1296
|
body: JSON.stringify(request)
|
|
1272
1297
|
});
|
|
1273
1298
|
const bodyText = await response.text();
|
|
@@ -1591,6 +1616,20 @@ function emitProxyEvent(eventType, status, correlation, details = {}) {
|
|
|
1591
1616
|
details
|
|
1592
1617
|
}).catch(() => void 0);
|
|
1593
1618
|
}
|
|
1619
|
+
function createProxyCorrelation(headers) {
|
|
1620
|
+
const traceId = readHeaderValue(headers[MNEMOSPARK_TRACE_ID_HEADER.toLowerCase()]) ?? randomUUID();
|
|
1621
|
+
const operationId = readHeaderValue(
|
|
1622
|
+
headers[MNEMOSPARK_OPERATION_ID_HEADER.toLowerCase()] ?? headers["idempotency-key"]
|
|
1623
|
+
) ?? randomUUID();
|
|
1624
|
+
return { trace_id: traceId, operation_id: operationId };
|
|
1625
|
+
}
|
|
1626
|
+
function emitProxyTerminalFromStatus(correlation, statusCode, details = {}) {
|
|
1627
|
+
if (statusCode >= 200 && statusCode < 300) {
|
|
1628
|
+
emitProxyEvent("terminal.success", "success", correlation, { status: statusCode, ...details });
|
|
1629
|
+
return;
|
|
1630
|
+
}
|
|
1631
|
+
emitProxyEvent("terminal.failure", "failure", correlation, { status: statusCode, ...details });
|
|
1632
|
+
}
|
|
1594
1633
|
function isAlreadySettledConflict(status, bodyText) {
|
|
1595
1634
|
if (status !== 409) {
|
|
1596
1635
|
return false;
|
|
@@ -1715,10 +1754,7 @@ async function startProxy(options) {
|
|
|
1715
1754
|
console.error(`[mnemospark] Response stream error: ${err.message}`);
|
|
1716
1755
|
});
|
|
1717
1756
|
if (req.method === "POST" && matchesProxyPath(req.url, PRICE_STORAGE_PROXY_PATH)) {
|
|
1718
|
-
const correlation =
|
|
1719
|
-
trace_id: randomUUID(),
|
|
1720
|
-
operation_id: randomUUID()
|
|
1721
|
-
};
|
|
1757
|
+
const correlation = createProxyCorrelation(req.headers);
|
|
1722
1758
|
logProxyEvent("info", "proxy_price_storage_received");
|
|
1723
1759
|
emitProxyEvent("request.received", "start", correlation, { path: PRICE_STORAGE_PROXY_PATH });
|
|
1724
1760
|
try {
|
|
@@ -1727,6 +1763,7 @@ async function startProxy(options) {
|
|
|
1727
1763
|
payload = await readProxyJsonBody(req);
|
|
1728
1764
|
} catch {
|
|
1729
1765
|
logProxyEvent("warn", "proxy_price_storage_invalid_json");
|
|
1766
|
+
emitProxyTerminalFromStatus(correlation, 400, { reason: "invalid_json" });
|
|
1730
1767
|
sendJson(res, 400, {
|
|
1731
1768
|
error: "Bad request",
|
|
1732
1769
|
message: "Invalid JSON body for /mnemospark-cloud price-storage"
|
|
@@ -1736,6 +1773,7 @@ async function startProxy(options) {
|
|
|
1736
1773
|
const requestPayload = parsePriceStorageQuoteRequest(payload);
|
|
1737
1774
|
if (!requestPayload) {
|
|
1738
1775
|
logProxyEvent("warn", "proxy_price_storage_missing_fields");
|
|
1776
|
+
emitProxyTerminalFromStatus(correlation, 400, { reason: "missing_fields" });
|
|
1739
1777
|
sendJson(res, 400, {
|
|
1740
1778
|
error: "Bad request",
|
|
1741
1779
|
message: "Missing required fields: wallet_address, object_id, object_id_hash, gb, provider, region"
|
|
@@ -1754,6 +1792,7 @@ async function startProxy(options) {
|
|
|
1754
1792
|
logProxyEvent("warn", "proxy_price_storage_wallet_signature_missing");
|
|
1755
1793
|
res.writeHead(400, { "Content-Type": "application/json" });
|
|
1756
1794
|
res.end(createWalletRequiredBody());
|
|
1795
|
+
emitProxyTerminalFromStatus(correlation, 400, { reason: "wallet_signature_missing" });
|
|
1757
1796
|
return;
|
|
1758
1797
|
}
|
|
1759
1798
|
const backendResponse = await forwardPriceStorageToBackend(requestPayload, {
|
|
@@ -1779,14 +1818,13 @@ async function startProxy(options) {
|
|
|
1779
1818
|
});
|
|
1780
1819
|
res.writeHead(authFailure.status, responseHeaders2);
|
|
1781
1820
|
res.end(authFailure.bodyText);
|
|
1821
|
+
emitProxyTerminalFromStatus(correlation, authFailure.status, { reason: "auth_failure" });
|
|
1782
1822
|
return;
|
|
1783
1823
|
}
|
|
1784
1824
|
const responseHeaders = createBackendForwardHeaders(backendResponse);
|
|
1785
1825
|
res.writeHead(backendResponse.status, responseHeaders);
|
|
1786
1826
|
res.end(backendResponse.bodyText);
|
|
1787
|
-
|
|
1788
|
-
status: backendResponse.status
|
|
1789
|
-
});
|
|
1827
|
+
emitProxyTerminalFromStatus(correlation, backendResponse.status);
|
|
1790
1828
|
} catch (err) {
|
|
1791
1829
|
emitProxyEvent("terminal.failure", "failure", correlation, {
|
|
1792
1830
|
error: err instanceof Error ? err.message : String(err)
|
|
@@ -1802,10 +1840,7 @@ async function startProxy(options) {
|
|
|
1802
1840
|
return;
|
|
1803
1841
|
}
|
|
1804
1842
|
if (req.method === "POST" && matchesProxyPath(req.url, PAYMENT_SETTLE_PROXY_PATH)) {
|
|
1805
|
-
const correlation =
|
|
1806
|
-
trace_id: randomUUID(),
|
|
1807
|
-
operation_id: randomUUID()
|
|
1808
|
-
};
|
|
1843
|
+
const correlation = createProxyCorrelation(req.headers);
|
|
1809
1844
|
logProxyEvent("info", "proxy_payment_settle_received");
|
|
1810
1845
|
emitProxyEvent("request.received", "start", correlation, { path: PAYMENT_SETTLE_PROXY_PATH });
|
|
1811
1846
|
try {
|
|
@@ -1814,6 +1849,7 @@ async function startProxy(options) {
|
|
|
1814
1849
|
payload = await readProxyJsonBody(req);
|
|
1815
1850
|
} catch {
|
|
1816
1851
|
logProxyEvent("warn", "proxy_payment_settle_invalid_json");
|
|
1852
|
+
emitProxyTerminalFromStatus(correlation, 400, { reason: "invalid_json" });
|
|
1817
1853
|
sendJson(res, 400, {
|
|
1818
1854
|
error: "Bad request",
|
|
1819
1855
|
message: "Invalid JSON body for /mnemospark/payment/settle"
|
|
@@ -1827,6 +1863,7 @@ async function startProxy(options) {
|
|
|
1827
1863
|
const inlinePaymentAuthorization = record?.payment_authorization;
|
|
1828
1864
|
if (!quoteId || !walletAddress) {
|
|
1829
1865
|
logProxyEvent("warn", "proxy_payment_settle_missing_fields");
|
|
1866
|
+
emitProxyTerminalFromStatus(correlation, 400, { reason: "missing_fields" });
|
|
1830
1867
|
sendJson(res, 400, {
|
|
1831
1868
|
error: "Bad request",
|
|
1832
1869
|
message: "Missing required fields: quote_id, wallet_address"
|
|
@@ -1835,6 +1872,7 @@ async function startProxy(options) {
|
|
|
1835
1872
|
}
|
|
1836
1873
|
if (inlinePayment !== void 0 && (inlinePayment === null || typeof inlinePayment !== "object" || Array.isArray(inlinePayment))) {
|
|
1837
1874
|
logProxyEvent("warn", "proxy_payment_settle_invalid_payment_shape");
|
|
1875
|
+
emitProxyTerminalFromStatus(correlation, 400, { reason: "invalid_payment_shape" });
|
|
1838
1876
|
sendJson(res, 400, {
|
|
1839
1877
|
error: "Bad request",
|
|
1840
1878
|
message: "Invalid field: payment must be an object when provided"
|
|
@@ -1843,6 +1881,9 @@ async function startProxy(options) {
|
|
|
1843
1881
|
}
|
|
1844
1882
|
if (inlinePaymentAuthorization !== void 0 && !(typeof inlinePaymentAuthorization === "string" || inlinePaymentAuthorization !== null && typeof inlinePaymentAuthorization === "object" && !Array.isArray(inlinePaymentAuthorization))) {
|
|
1845
1883
|
logProxyEvent("warn", "proxy_payment_settle_invalid_payment_authorization_shape");
|
|
1884
|
+
emitProxyTerminalFromStatus(correlation, 400, {
|
|
1885
|
+
reason: "invalid_payment_authorization_shape"
|
|
1886
|
+
});
|
|
1846
1887
|
sendJson(res, 400, {
|
|
1847
1888
|
error: "Bad request",
|
|
1848
1889
|
message: "Invalid field: payment_authorization must be an object or string when provided"
|
|
@@ -1854,6 +1895,7 @@ async function startProxy(options) {
|
|
|
1854
1895
|
request_wallet: walletAddress,
|
|
1855
1896
|
proxy_wallet: account.address
|
|
1856
1897
|
});
|
|
1898
|
+
emitProxyTerminalFromStatus(correlation, 403, { reason: "wallet_mismatch" });
|
|
1857
1899
|
sendJson(res, 403, {
|
|
1858
1900
|
error: "wallet_proof_invalid",
|
|
1859
1901
|
message: "wallet proof invalid"
|
|
@@ -1869,6 +1911,7 @@ async function startProxy(options) {
|
|
|
1869
1911
|
logProxyEvent("warn", "proxy_payment_settle_wallet_signature_missing");
|
|
1870
1912
|
res.writeHead(400, { "Content-Type": "application/json" });
|
|
1871
1913
|
res.end(createWalletRequiredBody());
|
|
1914
|
+
emitProxyTerminalFromStatus(correlation, 400, { reason: "wallet_signature_missing" });
|
|
1872
1915
|
return;
|
|
1873
1916
|
}
|
|
1874
1917
|
correlation.quote_id = quoteId;
|
|
@@ -1903,14 +1946,13 @@ async function startProxy(options) {
|
|
|
1903
1946
|
});
|
|
1904
1947
|
res.writeHead(authFailure.status, responseHeaders2);
|
|
1905
1948
|
res.end(authFailure.bodyText);
|
|
1949
|
+
emitProxyTerminalFromStatus(correlation, authFailure.status, { reason: "auth_failure" });
|
|
1906
1950
|
return;
|
|
1907
1951
|
}
|
|
1908
1952
|
const responseHeaders = createBackendForwardHeaders(backendResponse);
|
|
1909
1953
|
res.writeHead(backendResponse.status, responseHeaders);
|
|
1910
1954
|
res.end(backendResponse.bodyText);
|
|
1911
|
-
|
|
1912
|
-
status: backendResponse.status
|
|
1913
|
-
});
|
|
1955
|
+
emitProxyTerminalFromStatus(correlation, backendResponse.status);
|
|
1914
1956
|
} catch (err) {
|
|
1915
1957
|
emitProxyEvent("terminal.failure", "failure", correlation, {
|
|
1916
1958
|
error: err instanceof Error ? err.message : String(err)
|
|
@@ -1926,10 +1968,7 @@ async function startProxy(options) {
|
|
|
1926
1968
|
return;
|
|
1927
1969
|
}
|
|
1928
1970
|
if (req.method === "POST" && matchesProxyPath(req.url, UPLOAD_PROXY_PATH)) {
|
|
1929
|
-
const correlation =
|
|
1930
|
-
trace_id: randomUUID(),
|
|
1931
|
-
operation_id: randomUUID()
|
|
1932
|
-
};
|
|
1971
|
+
const correlation = createProxyCorrelation(req.headers);
|
|
1933
1972
|
logProxyEvent("info", "proxy_upload_received");
|
|
1934
1973
|
emitProxyEvent("request.received", "start", correlation, { path: UPLOAD_PROXY_PATH });
|
|
1935
1974
|
try {
|
|
@@ -1938,6 +1977,7 @@ async function startProxy(options) {
|
|
|
1938
1977
|
payload = await readProxyJsonBody(req);
|
|
1939
1978
|
} catch {
|
|
1940
1979
|
logProxyEvent("warn", "proxy_upload_invalid_json");
|
|
1980
|
+
emitProxyTerminalFromStatus(correlation, 400, { reason: "invalid_json" });
|
|
1941
1981
|
sendJson(res, 400, {
|
|
1942
1982
|
error: "Bad request",
|
|
1943
1983
|
message: "Invalid JSON body for /mnemospark-cloud upload"
|
|
@@ -1947,6 +1987,7 @@ async function startProxy(options) {
|
|
|
1947
1987
|
const requestPayload = parseStorageUploadRequest(payload);
|
|
1948
1988
|
if (!requestPayload) {
|
|
1949
1989
|
logProxyEvent("warn", "proxy_upload_missing_fields");
|
|
1990
|
+
emitProxyTerminalFromStatus(correlation, 400, { reason: "missing_fields" });
|
|
1950
1991
|
sendJson(res, 400, {
|
|
1951
1992
|
error: "Bad request",
|
|
1952
1993
|
message: "Missing required fields: quote_id, wallet_address, object_id, object_id_hash, quoted_storage_price, payload"
|
|
@@ -1956,12 +1997,12 @@ async function startProxy(options) {
|
|
|
1956
1997
|
correlation.quote_id = requestPayload.quote_id;
|
|
1957
1998
|
correlation.wallet_address = requestPayload.wallet_address;
|
|
1958
1999
|
correlation.object_id = requestPayload.object_id;
|
|
1959
|
-
emitProxyEvent("storage.call", "start", correlation, { target: "storage/upload" });
|
|
1960
2000
|
if (requestPayload.wallet_address.toLowerCase() !== proxyWalletAddressLower) {
|
|
1961
2001
|
logProxyEvent("warn", "proxy_upload_wallet_mismatch", {
|
|
1962
2002
|
request_wallet: requestPayload.wallet_address,
|
|
1963
2003
|
proxy_wallet: account.address
|
|
1964
2004
|
});
|
|
2005
|
+
emitProxyTerminalFromStatus(correlation, 403, { reason: "wallet_mismatch" });
|
|
1965
2006
|
sendJson(res, 403, {
|
|
1966
2007
|
error: "wallet_proof_invalid",
|
|
1967
2008
|
message: "wallet proof invalid"
|
|
@@ -1977,6 +2018,7 @@ async function startProxy(options) {
|
|
|
1977
2018
|
logProxyEvent("warn", "proxy_upload_wallet_signature_missing");
|
|
1978
2019
|
res.writeHead(400, { "Content-Type": "application/json" });
|
|
1979
2020
|
res.end(createWalletRequiredBody());
|
|
2021
|
+
emitProxyTerminalFromStatus(correlation, 400, { reason: "wallet_signature_missing" });
|
|
1980
2022
|
return;
|
|
1981
2023
|
}
|
|
1982
2024
|
const requiredMicros = BigInt(
|
|
@@ -1996,6 +2038,7 @@ async function startProxy(options) {
|
|
|
1996
2038
|
requiredUSD,
|
|
1997
2039
|
walletAddress: requestPayload.wallet_address
|
|
1998
2040
|
});
|
|
2041
|
+
emitProxyTerminalFromStatus(correlation, 400, { reason: "insufficient_balance" });
|
|
1999
2042
|
sendJson(res, 400, {
|
|
2000
2043
|
error: "insufficient_balance",
|
|
2001
2044
|
message: `Insufficient USDC balance. Current: ${sufficiency.info.balanceUSD}, Required: ${requiredUSD}`,
|
|
@@ -2023,6 +2066,7 @@ async function startProxy(options) {
|
|
|
2023
2066
|
logProxyEvent("warn", "proxy_upload_settle_signature_missing");
|
|
2024
2067
|
res.writeHead(400, { "Content-Type": "application/json" });
|
|
2025
2068
|
res.end(createWalletRequiredBody());
|
|
2069
|
+
emitProxyTerminalFromStatus(correlation, 400, { reason: "settle_signature_missing" });
|
|
2026
2070
|
return;
|
|
2027
2071
|
}
|
|
2028
2072
|
const uploadPaymentFetch = createPaymentFetch(walletPrivateKey).fetch;
|
|
@@ -2052,6 +2096,9 @@ async function startProxy(options) {
|
|
|
2052
2096
|
});
|
|
2053
2097
|
res.writeHead(settleResponse.status, responseHeaders2);
|
|
2054
2098
|
res.end(settleResponse.bodyText);
|
|
2099
|
+
emitProxyTerminalFromStatus(correlation, settleResponse.status, {
|
|
2100
|
+
reason: "settle_failed"
|
|
2101
|
+
});
|
|
2055
2102
|
return;
|
|
2056
2103
|
}
|
|
2057
2104
|
if (settledAlready) {
|
|
@@ -2063,6 +2110,7 @@ async function startProxy(options) {
|
|
|
2063
2110
|
status: settleResponse.status
|
|
2064
2111
|
});
|
|
2065
2112
|
}
|
|
2113
|
+
emitProxyEvent("storage.call", "start", correlation, { target: "storage/upload" });
|
|
2066
2114
|
const backendResponse = await forwardStorageUploadToBackend(requestPayload, {
|
|
2067
2115
|
backendBaseUrl: MNEMOSPARK_BACKEND_API_BASE_URL,
|
|
2068
2116
|
walletSignature,
|
|
@@ -2087,14 +2135,13 @@ async function startProxy(options) {
|
|
|
2087
2135
|
});
|
|
2088
2136
|
res.writeHead(authFailure.status, responseHeaders2);
|
|
2089
2137
|
res.end(authFailure.bodyText);
|
|
2138
|
+
emitProxyTerminalFromStatus(correlation, authFailure.status, { reason: "auth_failure" });
|
|
2090
2139
|
return;
|
|
2091
2140
|
}
|
|
2092
2141
|
const responseHeaders = createBackendForwardHeaders(backendResponse);
|
|
2093
2142
|
res.writeHead(backendResponse.status, responseHeaders);
|
|
2094
2143
|
res.end(backendResponse.bodyText);
|
|
2095
|
-
|
|
2096
|
-
status: backendResponse.status
|
|
2097
|
-
});
|
|
2144
|
+
emitProxyTerminalFromStatus(correlation, backendResponse.status);
|
|
2098
2145
|
} catch (err) {
|
|
2099
2146
|
emitProxyEvent("terminal.failure", "failure", correlation, {
|
|
2100
2147
|
error: err instanceof Error ? err.message : String(err)
|
|
@@ -2110,13 +2157,16 @@ async function startProxy(options) {
|
|
|
2110
2157
|
return;
|
|
2111
2158
|
}
|
|
2112
2159
|
if (req.method === "POST" && matchesProxyPath(req.url, UPLOAD_CONFIRM_PROXY_PATH)) {
|
|
2160
|
+
const correlation = createProxyCorrelation(req.headers);
|
|
2113
2161
|
logProxyEvent("info", "proxy_upload_confirm_received");
|
|
2162
|
+
emitProxyEvent("request.received", "start", correlation, { path: UPLOAD_CONFIRM_PROXY_PATH });
|
|
2114
2163
|
try {
|
|
2115
2164
|
let payload;
|
|
2116
2165
|
try {
|
|
2117
2166
|
payload = await readProxyJsonBody(req);
|
|
2118
2167
|
} catch {
|
|
2119
2168
|
logProxyEvent("warn", "proxy_upload_confirm_invalid_json");
|
|
2169
|
+
emitProxyTerminalFromStatus(correlation, 400, { reason: "invalid_json" });
|
|
2120
2170
|
sendJson(res, 400, {
|
|
2121
2171
|
error: "Bad request",
|
|
2122
2172
|
message: "Invalid JSON body for /mnemospark-cloud upload/confirm"
|
|
@@ -2126,17 +2176,22 @@ async function startProxy(options) {
|
|
|
2126
2176
|
const requestPayload = parseStorageUploadConfirmRequest(payload);
|
|
2127
2177
|
if (!requestPayload) {
|
|
2128
2178
|
logProxyEvent("warn", "proxy_upload_confirm_missing_fields");
|
|
2179
|
+
emitProxyTerminalFromStatus(correlation, 400, { reason: "missing_fields" });
|
|
2129
2180
|
sendJson(res, 400, {
|
|
2130
2181
|
error: "Bad request",
|
|
2131
2182
|
message: "Missing required fields: quote_id, wallet_address, object_key, idempotency_key"
|
|
2132
2183
|
});
|
|
2133
2184
|
return;
|
|
2134
2185
|
}
|
|
2186
|
+
correlation.quote_id = requestPayload.quote_id;
|
|
2187
|
+
correlation.wallet_address = requestPayload.wallet_address;
|
|
2188
|
+
correlation.object_key = requestPayload.object_key;
|
|
2135
2189
|
if (requestPayload.wallet_address.toLowerCase() !== proxyWalletAddressLower) {
|
|
2136
2190
|
logProxyEvent("warn", "proxy_upload_confirm_wallet_mismatch", {
|
|
2137
2191
|
request_wallet: requestPayload.wallet_address,
|
|
2138
2192
|
proxy_wallet: account.address
|
|
2139
2193
|
});
|
|
2194
|
+
emitProxyTerminalFromStatus(correlation, 403, { reason: "wallet_mismatch" });
|
|
2140
2195
|
sendJson(res, 403, {
|
|
2141
2196
|
error: "wallet_proof_invalid",
|
|
2142
2197
|
message: "wallet proof invalid"
|
|
@@ -2152,8 +2207,10 @@ async function startProxy(options) {
|
|
|
2152
2207
|
logProxyEvent("warn", "proxy_upload_confirm_wallet_signature_missing");
|
|
2153
2208
|
res.writeHead(400, { "Content-Type": "application/json" });
|
|
2154
2209
|
res.end(createWalletRequiredBody());
|
|
2210
|
+
emitProxyTerminalFromStatus(correlation, 400, { reason: "wallet_signature_missing" });
|
|
2155
2211
|
return;
|
|
2156
2212
|
}
|
|
2213
|
+
emitProxyEvent("storage.call", "start", correlation, { target: "storage/upload/confirm" });
|
|
2157
2214
|
const backendResponse = await forwardStorageUploadConfirmToBackend(requestPayload, {
|
|
2158
2215
|
backendBaseUrl: MNEMOSPARK_BACKEND_API_BASE_URL,
|
|
2159
2216
|
walletSignature
|
|
@@ -2161,6 +2218,7 @@ async function startProxy(options) {
|
|
|
2161
2218
|
logProxyEvent("info", "proxy_upload_confirm_backend_response", {
|
|
2162
2219
|
status: backendResponse.status
|
|
2163
2220
|
});
|
|
2221
|
+
emitProxyEvent("storage.call", "result", correlation, { status: backendResponse.status });
|
|
2164
2222
|
const authFailure = normalizeBackendAuthFailure(
|
|
2165
2223
|
backendResponse.status,
|
|
2166
2224
|
backendResponse.bodyText
|
|
@@ -2176,12 +2234,17 @@ async function startProxy(options) {
|
|
|
2176
2234
|
});
|
|
2177
2235
|
res.writeHead(authFailure.status, responseHeaders2);
|
|
2178
2236
|
res.end(authFailure.bodyText);
|
|
2237
|
+
emitProxyTerminalFromStatus(correlation, authFailure.status, { reason: "auth_failure" });
|
|
2179
2238
|
return;
|
|
2180
2239
|
}
|
|
2181
2240
|
const responseHeaders = createBackendForwardHeaders(backendResponse);
|
|
2182
2241
|
res.writeHead(backendResponse.status, responseHeaders);
|
|
2183
2242
|
res.end(backendResponse.bodyText);
|
|
2243
|
+
emitProxyTerminalFromStatus(correlation, backendResponse.status);
|
|
2184
2244
|
} catch (err) {
|
|
2245
|
+
emitProxyEvent("terminal.failure", "failure", correlation, {
|
|
2246
|
+
error: err instanceof Error ? err.message : String(err)
|
|
2247
|
+
});
|
|
2185
2248
|
logProxyEvent("error", "proxy_upload_confirm_forward_failed", {
|
|
2186
2249
|
error: err instanceof Error ? err.message : String(err)
|
|
2187
2250
|
});
|
|
@@ -2193,10 +2256,7 @@ async function startProxy(options) {
|
|
|
2193
2256
|
return;
|
|
2194
2257
|
}
|
|
2195
2258
|
if (req.method === "POST" && matchesProxyPath(req.url, STORAGE_LS_PROXY_PATH)) {
|
|
2196
|
-
const correlation =
|
|
2197
|
-
trace_id: randomUUID(),
|
|
2198
|
-
operation_id: randomUUID()
|
|
2199
|
-
};
|
|
2259
|
+
const correlation = createProxyCorrelation(req.headers);
|
|
2200
2260
|
logProxyEvent("info", "proxy_ls_received");
|
|
2201
2261
|
emitProxyEvent("request.received", "start", correlation, { path: STORAGE_LS_PROXY_PATH });
|
|
2202
2262
|
try {
|
|
@@ -2205,6 +2265,7 @@ async function startProxy(options) {
|
|
|
2205
2265
|
payload = await readProxyJsonBody(req);
|
|
2206
2266
|
} catch {
|
|
2207
2267
|
logProxyEvent("warn", "proxy_ls_invalid_json");
|
|
2268
|
+
emitProxyTerminalFromStatus(correlation, 400, { reason: "invalid_json" });
|
|
2208
2269
|
sendJson(res, 400, {
|
|
2209
2270
|
error: "Bad request",
|
|
2210
2271
|
message: "Invalid JSON body for /mnemospark-cloud ls"
|
|
@@ -2214,6 +2275,7 @@ async function startProxy(options) {
|
|
|
2214
2275
|
const requestPayload = parseStorageObjectRequest(payload);
|
|
2215
2276
|
if (!requestPayload) {
|
|
2216
2277
|
logProxyEvent("warn", "proxy_ls_missing_fields");
|
|
2278
|
+
emitProxyTerminalFromStatus(correlation, 400, { reason: "missing_fields" });
|
|
2217
2279
|
sendJson(res, 400, {
|
|
2218
2280
|
error: "Bad request",
|
|
2219
2281
|
message: "Missing required fields: wallet_address, object_key"
|
|
@@ -2224,6 +2286,7 @@ async function startProxy(options) {
|
|
|
2224
2286
|
correlation.object_key = requestPayload.object_key;
|
|
2225
2287
|
if (requestPayload.wallet_address.toLowerCase() !== proxyWalletAddressLower) {
|
|
2226
2288
|
logProxyEvent("warn", "proxy_ls_wallet_mismatch");
|
|
2289
|
+
emitProxyTerminalFromStatus(correlation, 403, { reason: "wallet_mismatch" });
|
|
2227
2290
|
sendJson(res, 403, {
|
|
2228
2291
|
error: "wallet_proof_invalid",
|
|
2229
2292
|
message: "wallet proof invalid"
|
|
@@ -2239,6 +2302,7 @@ async function startProxy(options) {
|
|
|
2239
2302
|
logProxyEvent("warn", "proxy_ls_wallet_signature_missing");
|
|
2240
2303
|
res.writeHead(400, { "Content-Type": "application/json" });
|
|
2241
2304
|
res.end(createWalletRequiredBody());
|
|
2305
|
+
emitProxyTerminalFromStatus(correlation, 400, { reason: "wallet_signature_missing" });
|
|
2242
2306
|
return;
|
|
2243
2307
|
}
|
|
2244
2308
|
emitProxyEvent("storage.call", "start", correlation, { target: "storage/ls" });
|
|
@@ -2261,14 +2325,13 @@ async function startProxy(options) {
|
|
|
2261
2325
|
});
|
|
2262
2326
|
res.writeHead(authFailure.status, responseHeaders2);
|
|
2263
2327
|
res.end(authFailure.bodyText);
|
|
2328
|
+
emitProxyTerminalFromStatus(correlation, authFailure.status, { reason: "auth_failure" });
|
|
2264
2329
|
return;
|
|
2265
2330
|
}
|
|
2266
2331
|
const responseHeaders = createBackendForwardHeaders(backendResponse);
|
|
2267
2332
|
res.writeHead(backendResponse.status, responseHeaders);
|
|
2268
2333
|
res.end(backendResponse.bodyText);
|
|
2269
|
-
|
|
2270
|
-
status: backendResponse.status
|
|
2271
|
-
});
|
|
2334
|
+
emitProxyTerminalFromStatus(correlation, backendResponse.status);
|
|
2272
2335
|
} catch (err) {
|
|
2273
2336
|
emitProxyEvent("terminal.failure", "failure", correlation, {
|
|
2274
2337
|
error: err instanceof Error ? err.message : String(err)
|
|
@@ -2284,10 +2347,7 @@ async function startProxy(options) {
|
|
|
2284
2347
|
return;
|
|
2285
2348
|
}
|
|
2286
2349
|
if (req.method === "POST" && matchesProxyPath(req.url, STORAGE_DOWNLOAD_PROXY_PATH)) {
|
|
2287
|
-
const correlation =
|
|
2288
|
-
trace_id: randomUUID(),
|
|
2289
|
-
operation_id: randomUUID()
|
|
2290
|
-
};
|
|
2350
|
+
const correlation = createProxyCorrelation(req.headers);
|
|
2291
2351
|
logProxyEvent("info", "proxy_download_received");
|
|
2292
2352
|
emitProxyEvent("request.received", "start", correlation, {
|
|
2293
2353
|
path: STORAGE_DOWNLOAD_PROXY_PATH
|
|
@@ -2298,6 +2358,7 @@ async function startProxy(options) {
|
|
|
2298
2358
|
payload = await readProxyJsonBody(req);
|
|
2299
2359
|
} catch {
|
|
2300
2360
|
logProxyEvent("warn", "proxy_download_invalid_json");
|
|
2361
|
+
emitProxyTerminalFromStatus(correlation, 400, { reason: "invalid_json" });
|
|
2301
2362
|
sendJson(res, 400, {
|
|
2302
2363
|
error: "Bad request",
|
|
2303
2364
|
message: "Invalid JSON body for /mnemospark-cloud download"
|
|
@@ -2307,6 +2368,7 @@ async function startProxy(options) {
|
|
|
2307
2368
|
const requestPayload = parseStorageObjectRequest(payload);
|
|
2308
2369
|
if (!requestPayload) {
|
|
2309
2370
|
logProxyEvent("warn", "proxy_download_missing_fields");
|
|
2371
|
+
emitProxyTerminalFromStatus(correlation, 400, { reason: "missing_fields" });
|
|
2310
2372
|
sendJson(res, 400, {
|
|
2311
2373
|
error: "Bad request",
|
|
2312
2374
|
message: "Missing required fields: wallet_address, object_key"
|
|
@@ -2317,6 +2379,7 @@ async function startProxy(options) {
|
|
|
2317
2379
|
correlation.object_key = requestPayload.object_key;
|
|
2318
2380
|
if (requestPayload.wallet_address.toLowerCase() !== proxyWalletAddressLower) {
|
|
2319
2381
|
logProxyEvent("warn", "proxy_download_wallet_mismatch");
|
|
2382
|
+
emitProxyTerminalFromStatus(correlation, 403, { reason: "wallet_mismatch" });
|
|
2320
2383
|
sendJson(res, 403, {
|
|
2321
2384
|
error: "wallet_proof_invalid",
|
|
2322
2385
|
message: "wallet proof invalid"
|
|
@@ -2332,6 +2395,7 @@ async function startProxy(options) {
|
|
|
2332
2395
|
logProxyEvent("warn", "proxy_download_wallet_signature_missing");
|
|
2333
2396
|
res.writeHead(400, { "Content-Type": "application/json" });
|
|
2334
2397
|
res.end(createWalletRequiredBody());
|
|
2398
|
+
emitProxyTerminalFromStatus(correlation, 400, { reason: "wallet_signature_missing" });
|
|
2335
2399
|
return;
|
|
2336
2400
|
}
|
|
2337
2401
|
emitProxyEvent("storage.call", "start", correlation, { target: "storage/download" });
|
|
@@ -2358,6 +2422,7 @@ async function startProxy(options) {
|
|
|
2358
2422
|
});
|
|
2359
2423
|
res.writeHead(authFailure.status, responseHeaders);
|
|
2360
2424
|
res.end(authFailure.bodyText);
|
|
2425
|
+
emitProxyTerminalFromStatus(correlation, authFailure.status, { reason: "auth_failure" });
|
|
2361
2426
|
return;
|
|
2362
2427
|
}
|
|
2363
2428
|
if (backendResponse.status < 200 || backendResponse.status >= 300) {
|
|
@@ -2367,6 +2432,7 @@ async function startProxy(options) {
|
|
|
2367
2432
|
const responseHeaders = createBackendForwardHeaders(backendResponse);
|
|
2368
2433
|
res.writeHead(backendResponse.status, responseHeaders);
|
|
2369
2434
|
res.end(backendResponse.bodyText);
|
|
2435
|
+
emitProxyTerminalFromStatus(correlation, backendResponse.status);
|
|
2370
2436
|
return;
|
|
2371
2437
|
}
|
|
2372
2438
|
const downloadResult = await downloadStorageToDisk(requestPayload, backendResponse, {
|
|
@@ -2383,9 +2449,7 @@ async function startProxy(options) {
|
|
|
2383
2449
|
file_path: downloadResult.filePath,
|
|
2384
2450
|
bytes_written: downloadResult.bytesWritten
|
|
2385
2451
|
});
|
|
2386
|
-
|
|
2387
|
-
status: 200
|
|
2388
|
-
});
|
|
2452
|
+
emitProxyTerminalFromStatus(correlation, 200);
|
|
2389
2453
|
} catch (err) {
|
|
2390
2454
|
emitProxyEvent("terminal.failure", "failure", correlation, {
|
|
2391
2455
|
error: err instanceof Error ? err.message : String(err)
|
|
@@ -2401,10 +2465,7 @@ async function startProxy(options) {
|
|
|
2401
2465
|
return;
|
|
2402
2466
|
}
|
|
2403
2467
|
if (req.method === "POST" && matchesProxyPath(req.url, STORAGE_DELETE_PROXY_PATH)) {
|
|
2404
|
-
const correlation =
|
|
2405
|
-
trace_id: randomUUID(),
|
|
2406
|
-
operation_id: randomUUID()
|
|
2407
|
-
};
|
|
2468
|
+
const correlation = createProxyCorrelation(req.headers);
|
|
2408
2469
|
logProxyEvent("info", "proxy_delete_received");
|
|
2409
2470
|
emitProxyEvent("request.received", "start", correlation, { path: STORAGE_DELETE_PROXY_PATH });
|
|
2410
2471
|
try {
|
|
@@ -2413,6 +2474,7 @@ async function startProxy(options) {
|
|
|
2413
2474
|
payload = await readProxyJsonBody(req);
|
|
2414
2475
|
} catch {
|
|
2415
2476
|
logProxyEvent("warn", "proxy_delete_invalid_json");
|
|
2477
|
+
emitProxyTerminalFromStatus(correlation, 400, { reason: "invalid_json" });
|
|
2416
2478
|
sendJson(res, 400, {
|
|
2417
2479
|
error: "Bad request",
|
|
2418
2480
|
message: "Invalid JSON body for /mnemospark-cloud delete"
|
|
@@ -2422,6 +2484,7 @@ async function startProxy(options) {
|
|
|
2422
2484
|
const requestPayload = parseStorageObjectRequest(payload);
|
|
2423
2485
|
if (!requestPayload) {
|
|
2424
2486
|
logProxyEvent("warn", "proxy_delete_missing_fields");
|
|
2487
|
+
emitProxyTerminalFromStatus(correlation, 400, { reason: "missing_fields" });
|
|
2425
2488
|
sendJson(res, 400, {
|
|
2426
2489
|
error: "Bad request",
|
|
2427
2490
|
message: "Missing required fields: wallet_address, object_key"
|
|
@@ -2432,6 +2495,7 @@ async function startProxy(options) {
|
|
|
2432
2495
|
correlation.object_key = requestPayload.object_key;
|
|
2433
2496
|
if (requestPayload.wallet_address.toLowerCase() !== proxyWalletAddressLower) {
|
|
2434
2497
|
logProxyEvent("warn", "proxy_delete_wallet_mismatch");
|
|
2498
|
+
emitProxyTerminalFromStatus(correlation, 403, { reason: "wallet_mismatch" });
|
|
2435
2499
|
sendJson(res, 403, {
|
|
2436
2500
|
error: "wallet_proof_invalid",
|
|
2437
2501
|
message: "wallet proof invalid"
|
|
@@ -2447,6 +2511,7 @@ async function startProxy(options) {
|
|
|
2447
2511
|
logProxyEvent("warn", "proxy_delete_wallet_signature_missing");
|
|
2448
2512
|
res.writeHead(400, { "Content-Type": "application/json" });
|
|
2449
2513
|
res.end(createWalletRequiredBody());
|
|
2514
|
+
emitProxyTerminalFromStatus(correlation, 400, { reason: "wallet_signature_missing" });
|
|
2450
2515
|
return;
|
|
2451
2516
|
}
|
|
2452
2517
|
emitProxyEvent("storage.call", "start", correlation, { target: "storage/delete" });
|
|
@@ -2473,14 +2538,13 @@ async function startProxy(options) {
|
|
|
2473
2538
|
});
|
|
2474
2539
|
res.writeHead(authFailure.status, responseHeaders2);
|
|
2475
2540
|
res.end(authFailure.bodyText);
|
|
2541
|
+
emitProxyTerminalFromStatus(correlation, authFailure.status, { reason: "auth_failure" });
|
|
2476
2542
|
return;
|
|
2477
2543
|
}
|
|
2478
2544
|
const responseHeaders = createBackendForwardHeaders(backendResponse);
|
|
2479
2545
|
res.writeHead(backendResponse.status, responseHeaders);
|
|
2480
2546
|
res.end(backendResponse.bodyText);
|
|
2481
|
-
|
|
2482
|
-
status: backendResponse.status
|
|
2483
|
-
});
|
|
2547
|
+
emitProxyTerminalFromStatus(correlation, backendResponse.status);
|
|
2484
2548
|
} catch (err) {
|
|
2485
2549
|
emitProxyEvent("terminal.failure", "failure", correlation, {
|
|
2486
2550
|
error: err instanceof Error ? err.message : String(err)
|
|
@@ -2989,7 +3053,7 @@ async function createCloudDatastore(homeDir) {
|
|
|
2989
3053
|
VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
2990
3054
|
ON CONFLICT(operation_id) DO UPDATE SET
|
|
2991
3055
|
type=excluded.type,
|
|
2992
|
-
object_id=excluded.object_id,
|
|
3056
|
+
object_id=COALESCE(excluded.object_id, operations.object_id),
|
|
2993
3057
|
quote_id=excluded.quote_id,
|
|
2994
3058
|
status=excluded.status,
|
|
2995
3059
|
error_code=excluded.error_code,
|
|
@@ -4034,7 +4098,12 @@ async function emitCloudEventBestEffort(eventType, details, homeDir) {
|
|
|
4034
4098
|
} catch {
|
|
4035
4099
|
}
|
|
4036
4100
|
}
|
|
4037
|
-
|
|
4101
|
+
function buildRequestCorrelation(forcedOperationId, forcedTraceId) {
|
|
4102
|
+
const operationId = forcedOperationId?.trim() || randomUUID3();
|
|
4103
|
+
const traceId = forcedTraceId?.trim() || randomUUID3();
|
|
4104
|
+
return { operationId, traceId };
|
|
4105
|
+
}
|
|
4106
|
+
async function runCloudCommandHandler(ctx, options, executionContext = {}) {
|
|
4038
4107
|
const parsed = parseCloudArgs(ctx.args);
|
|
4039
4108
|
const objectLogHomeDir = options.objectLogHomeDir;
|
|
4040
4109
|
const backupBuilder = options.buildBackupObjectFn;
|
|
@@ -4114,9 +4183,10 @@ async function runCloudCommandHandler(ctx, options) {
|
|
|
4114
4183
|
};
|
|
4115
4184
|
}
|
|
4116
4185
|
if ((parsed.mode === "upload" || parsed.mode === "download") && parsed.async) {
|
|
4117
|
-
const
|
|
4186
|
+
const asyncCorrelation = buildRequestCorrelation();
|
|
4187
|
+
const operationId = asyncCorrelation.operationId;
|
|
4118
4188
|
const opType = parsed.mode;
|
|
4119
|
-
const opObject = parsed.mode === "upload" ? parsed.uploadRequest.object_id :
|
|
4189
|
+
const opObject = parsed.mode === "upload" ? parsed.uploadRequest.object_id : null;
|
|
4120
4190
|
const opQuote = parsed.mode === "upload" ? parsed.uploadRequest.quote_id : null;
|
|
4121
4191
|
await datastore.upsertOperation({
|
|
4122
4192
|
operation_id: operationId,
|
|
@@ -4128,7 +4198,10 @@ async function runCloudCommandHandler(ctx, options) {
|
|
|
4128
4198
|
error_message: null
|
|
4129
4199
|
});
|
|
4130
4200
|
const syncArgs = stripAsyncFlag(ctx.args);
|
|
4131
|
-
void runCloudCommandHandler({ args: syncArgs }, options
|
|
4201
|
+
void runCloudCommandHandler({ args: syncArgs }, options, {
|
|
4202
|
+
forcedOperationId: asyncCorrelation.operationId,
|
|
4203
|
+
forcedTraceId: asyncCorrelation.traceId
|
|
4204
|
+
}).then(async (result) => {
|
|
4132
4205
|
await datastore.upsertOperation({
|
|
4133
4206
|
operation_id: operationId,
|
|
4134
4207
|
type: opType,
|
|
@@ -4209,11 +4282,12 @@ Use /mnemospark-cloud op-status --operation-id ${operationId}`
|
|
|
4209
4282
|
}
|
|
4210
4283
|
}
|
|
4211
4284
|
if (parsed.mode === "price-storage") {
|
|
4285
|
+
const correlation = buildRequestCorrelation();
|
|
4212
4286
|
try {
|
|
4213
|
-
const quote = await requestPriceStorageQuote(
|
|
4214
|
-
|
|
4215
|
-
|
|
4216
|
-
);
|
|
4287
|
+
const quote = await requestPriceStorageQuote(parsed.priceStorageRequest, {
|
|
4288
|
+
...options.proxyQuoteOptions,
|
|
4289
|
+
correlation
|
|
4290
|
+
});
|
|
4217
4291
|
await appendPriceStorageQuoteLog(quote, objectLogHomeDir);
|
|
4218
4292
|
await datastore.upsertObject({
|
|
4219
4293
|
object_id: quote.object_id,
|
|
@@ -4234,10 +4308,33 @@ Use /mnemospark-cloud op-status --operation-id ${operationId}`
|
|
|
4234
4308
|
network: null,
|
|
4235
4309
|
status: "quoted"
|
|
4236
4310
|
});
|
|
4311
|
+
await emitCloudEventBestEffort(
|
|
4312
|
+
"price-storage.completed",
|
|
4313
|
+
{
|
|
4314
|
+
operation_id: correlation.operationId,
|
|
4315
|
+
trace_id: correlation.traceId,
|
|
4316
|
+
wallet_address: quote.addr,
|
|
4317
|
+
object_id: quote.object_id,
|
|
4318
|
+
quote_id: quote.quote_id,
|
|
4319
|
+
status: "succeeded"
|
|
4320
|
+
},
|
|
4321
|
+
objectLogHomeDir
|
|
4322
|
+
);
|
|
4237
4323
|
return {
|
|
4238
4324
|
text: formatPriceStorageUserMessage(quote)
|
|
4239
4325
|
};
|
|
4240
4326
|
} catch (err) {
|
|
4327
|
+
await emitCloudEventBestEffort(
|
|
4328
|
+
"price-storage.completed",
|
|
4329
|
+
{
|
|
4330
|
+
operation_id: correlation.operationId,
|
|
4331
|
+
trace_id: correlation.traceId,
|
|
4332
|
+
wallet_address: parsed.priceStorageRequest.wallet_address,
|
|
4333
|
+
object_id: parsed.priceStorageRequest.object_id,
|
|
4334
|
+
status: "failed"
|
|
4335
|
+
},
|
|
4336
|
+
objectLogHomeDir
|
|
4337
|
+
);
|
|
4241
4338
|
const message = err instanceof Error ? err.message : typeof err === "string" ? err : String(err);
|
|
4242
4339
|
return {
|
|
4243
4340
|
text: message ? `Cannot price storage: ${message}` : "Cannot price storage",
|
|
@@ -4246,6 +4343,10 @@ Use /mnemospark-cloud op-status --operation-id ${operationId}`
|
|
|
4246
4343
|
}
|
|
4247
4344
|
}
|
|
4248
4345
|
if (parsed.mode === "upload") {
|
|
4346
|
+
const uploadCorrelation = buildRequestCorrelation(
|
|
4347
|
+
executionContext.forcedOperationId ?? idempotencyKeyFn(),
|
|
4348
|
+
executionContext.forcedTraceId
|
|
4349
|
+
);
|
|
4249
4350
|
try {
|
|
4250
4351
|
const loggedQuote = await datastore.findQuoteById(parsed.uploadRequest.quote_id) ?? await findLoggedPriceStorageQuote(parsed.uploadRequest.quote_id, objectLogHomeDir);
|
|
4251
4352
|
if (!loggedQuote) {
|
|
@@ -4299,7 +4400,7 @@ Use /mnemospark-cloud op-status --operation-id ${operationId}`
|
|
|
4299
4400
|
parsed.uploadRequest.wallet_address,
|
|
4300
4401
|
objectLogHomeDir
|
|
4301
4402
|
);
|
|
4302
|
-
const idempotencyKey =
|
|
4403
|
+
const idempotencyKey = uploadCorrelation.operationId;
|
|
4303
4404
|
const shouldSettleBeforeUpload = requestStorageUpload !== requestStorageUploadViaProxy;
|
|
4304
4405
|
if (shouldSettleBeforeUpload) {
|
|
4305
4406
|
const paymentFetch = createPayment(walletKey).fetch;
|
|
@@ -4308,6 +4409,7 @@ Use /mnemospark-cloud op-status --operation-id ${operationId}`
|
|
|
4308
4409
|
parsed.uploadRequest.wallet_address,
|
|
4309
4410
|
{
|
|
4310
4411
|
...options.proxyUploadOptions,
|
|
4412
|
+
correlation: uploadCorrelation,
|
|
4311
4413
|
fetchImpl: (input, init) => paymentFetch(input, init)
|
|
4312
4414
|
}
|
|
4313
4415
|
);
|
|
@@ -4329,6 +4431,7 @@ Use /mnemospark-cloud op-status --operation-id ${operationId}`
|
|
|
4329
4431
|
{
|
|
4330
4432
|
...options.proxyUploadOptions,
|
|
4331
4433
|
idempotencyKey,
|
|
4434
|
+
correlation: uploadCorrelation,
|
|
4332
4435
|
fetchImpl: uploadFetchImpl
|
|
4333
4436
|
}
|
|
4334
4437
|
);
|
|
@@ -4348,7 +4451,10 @@ Use /mnemospark-cloud op-status --operation-id ${operationId}`
|
|
|
4348
4451
|
object_key: uploadResponse.object_key,
|
|
4349
4452
|
idempotency_key: idempotencyKey
|
|
4350
4453
|
},
|
|
4351
|
-
|
|
4454
|
+
{
|
|
4455
|
+
...options.proxyUploadConfirmOptions,
|
|
4456
|
+
correlation: uploadCorrelation
|
|
4457
|
+
}
|
|
4352
4458
|
);
|
|
4353
4459
|
} catch (confirmError) {
|
|
4354
4460
|
const transId = uploadResponse.trans_id ?? "unknown";
|
|
@@ -4424,6 +4530,7 @@ Use /mnemospark-cloud op-status --operation-id ${operationId}`
|
|
|
4424
4530
|
"upload.completed",
|
|
4425
4531
|
{
|
|
4426
4532
|
operation_id: idempotencyKey,
|
|
4533
|
+
trace_id: uploadCorrelation.traceId,
|
|
4427
4534
|
wallet_address: finalizedUploadResponse.addr,
|
|
4428
4535
|
object_id: finalizedUploadResponse.object_id,
|
|
4429
4536
|
object_key: finalizedUploadResponse.object_key,
|
|
@@ -4437,6 +4544,18 @@ Use /mnemospark-cloud op-status --operation-id ${operationId}`
|
|
|
4437
4544
|
text: formatStorageUploadUserMessage(finalizedUploadResponse, cronJob.cronId)
|
|
4438
4545
|
};
|
|
4439
4546
|
} catch (error) {
|
|
4547
|
+
await emitCloudEventBestEffort(
|
|
4548
|
+
"upload.completed",
|
|
4549
|
+
{
|
|
4550
|
+
operation_id: uploadCorrelation.operationId,
|
|
4551
|
+
trace_id: uploadCorrelation.traceId,
|
|
4552
|
+
wallet_address: parsed.uploadRequest.wallet_address,
|
|
4553
|
+
object_id: parsed.uploadRequest.object_id,
|
|
4554
|
+
quote_id: parsed.uploadRequest.quote_id,
|
|
4555
|
+
status: "failed"
|
|
4556
|
+
},
|
|
4557
|
+
objectLogHomeDir
|
|
4558
|
+
);
|
|
4440
4559
|
const uploadErrorMessage = extractUploadErrorMessage(error);
|
|
4441
4560
|
return {
|
|
4442
4561
|
text: uploadErrorMessage ?? "Cannot upload storage object",
|
|
@@ -4454,25 +4573,31 @@ Use /mnemospark-cloud op-status --operation-id ${operationId}`
|
|
|
4454
4573
|
return { text: resolved.error ?? "Cannot resolve storage object request.", isError: true };
|
|
4455
4574
|
}
|
|
4456
4575
|
const resolvedRequest = resolved.request;
|
|
4457
|
-
const
|
|
4576
|
+
const correlation = buildRequestCorrelation();
|
|
4577
|
+
const operationId = correlation.operationId;
|
|
4578
|
+
const knownObject = await datastore.findObjectByObjectKey(resolvedRequest.object_key);
|
|
4579
|
+
const operationObjectId = knownObject?.object_id ?? null;
|
|
4458
4580
|
await datastore.upsertOperation({
|
|
4459
4581
|
operation_id: operationId,
|
|
4460
4582
|
type: "ls",
|
|
4461
|
-
object_id:
|
|
4583
|
+
object_id: operationObjectId,
|
|
4462
4584
|
quote_id: null,
|
|
4463
4585
|
status: "started",
|
|
4464
4586
|
error_code: null,
|
|
4465
4587
|
error_message: null
|
|
4466
4588
|
});
|
|
4467
4589
|
try {
|
|
4468
|
-
const lsResult = await requestStorageLs(resolvedRequest,
|
|
4590
|
+
const lsResult = await requestStorageLs(resolvedRequest, {
|
|
4591
|
+
...options.proxyStorageOptions,
|
|
4592
|
+
correlation
|
|
4593
|
+
});
|
|
4469
4594
|
if (!lsResult.success) {
|
|
4470
4595
|
throw new Error("ls failed");
|
|
4471
4596
|
}
|
|
4472
4597
|
await datastore.upsertOperation({
|
|
4473
4598
|
operation_id: operationId,
|
|
4474
4599
|
type: "ls",
|
|
4475
|
-
object_id:
|
|
4600
|
+
object_id: operationObjectId,
|
|
4476
4601
|
quote_id: null,
|
|
4477
4602
|
status: "succeeded",
|
|
4478
4603
|
error_code: null,
|
|
@@ -4482,6 +4607,7 @@ Use /mnemospark-cloud op-status --operation-id ${operationId}`
|
|
|
4482
4607
|
"ls.completed",
|
|
4483
4608
|
{
|
|
4484
4609
|
operation_id: operationId,
|
|
4610
|
+
trace_id: correlation.traceId,
|
|
4485
4611
|
wallet_address: resolvedRequest.wallet_address,
|
|
4486
4612
|
object_key: resolvedRequest.object_key,
|
|
4487
4613
|
status: "succeeded"
|
|
@@ -4495,7 +4621,7 @@ Use /mnemospark-cloud op-status --operation-id ${operationId}`
|
|
|
4495
4621
|
await datastore.upsertOperation({
|
|
4496
4622
|
operation_id: operationId,
|
|
4497
4623
|
type: "ls",
|
|
4498
|
-
object_id:
|
|
4624
|
+
object_id: operationObjectId,
|
|
4499
4625
|
quote_id: null,
|
|
4500
4626
|
status: "failed",
|
|
4501
4627
|
error_code: "LS_FAILED",
|
|
@@ -4505,6 +4631,7 @@ Use /mnemospark-cloud op-status --operation-id ${operationId}`
|
|
|
4505
4631
|
"ls.completed",
|
|
4506
4632
|
{
|
|
4507
4633
|
operation_id: operationId,
|
|
4634
|
+
trace_id: correlation.traceId,
|
|
4508
4635
|
wallet_address: resolvedRequest.wallet_address,
|
|
4509
4636
|
object_key: resolvedRequest.object_key,
|
|
4510
4637
|
status: "failed"
|
|
@@ -4527,28 +4654,34 @@ Use /mnemospark-cloud op-status --operation-id ${operationId}`
|
|
|
4527
4654
|
return { text: resolved.error ?? "Cannot resolve storage object request.", isError: true };
|
|
4528
4655
|
}
|
|
4529
4656
|
const resolvedRequest = resolved.request;
|
|
4530
|
-
const
|
|
4657
|
+
const correlation = buildRequestCorrelation(
|
|
4658
|
+
executionContext.forcedOperationId,
|
|
4659
|
+
executionContext.forcedTraceId
|
|
4660
|
+
);
|
|
4661
|
+
const operationId = correlation.operationId;
|
|
4662
|
+
const knownObject = await datastore.findObjectByObjectKey(resolvedRequest.object_key);
|
|
4663
|
+
const operationObjectId = knownObject?.object_id ?? null;
|
|
4531
4664
|
await datastore.upsertOperation({
|
|
4532
4665
|
operation_id: operationId,
|
|
4533
4666
|
type: "download",
|
|
4534
|
-
object_id:
|
|
4667
|
+
object_id: operationObjectId,
|
|
4535
4668
|
quote_id: null,
|
|
4536
4669
|
status: "started",
|
|
4537
4670
|
error_code: null,
|
|
4538
4671
|
error_message: null
|
|
4539
4672
|
});
|
|
4540
4673
|
try {
|
|
4541
|
-
const downloadResult = await requestStorageDownload(
|
|
4542
|
-
|
|
4543
|
-
|
|
4544
|
-
);
|
|
4674
|
+
const downloadResult = await requestStorageDownload(resolvedRequest, {
|
|
4675
|
+
...options.proxyStorageOptions,
|
|
4676
|
+
correlation
|
|
4677
|
+
});
|
|
4545
4678
|
if (!downloadResult.success) {
|
|
4546
4679
|
throw new Error("download failed");
|
|
4547
4680
|
}
|
|
4548
4681
|
await datastore.upsertOperation({
|
|
4549
4682
|
operation_id: operationId,
|
|
4550
4683
|
type: "download",
|
|
4551
|
-
object_id:
|
|
4684
|
+
object_id: operationObjectId,
|
|
4552
4685
|
quote_id: null,
|
|
4553
4686
|
status: "succeeded",
|
|
4554
4687
|
error_code: null,
|
|
@@ -4558,6 +4691,7 @@ Use /mnemospark-cloud op-status --operation-id ${operationId}`
|
|
|
4558
4691
|
"download.completed",
|
|
4559
4692
|
{
|
|
4560
4693
|
operation_id: operationId,
|
|
4694
|
+
trace_id: correlation.traceId,
|
|
4561
4695
|
wallet_address: resolvedRequest.wallet_address,
|
|
4562
4696
|
object_key: resolvedRequest.object_key,
|
|
4563
4697
|
status: "succeeded"
|
|
@@ -4571,7 +4705,7 @@ Use /mnemospark-cloud op-status --operation-id ${operationId}`
|
|
|
4571
4705
|
await datastore.upsertOperation({
|
|
4572
4706
|
operation_id: operationId,
|
|
4573
4707
|
type: "download",
|
|
4574
|
-
object_id:
|
|
4708
|
+
object_id: operationObjectId,
|
|
4575
4709
|
quote_id: null,
|
|
4576
4710
|
status: "failed",
|
|
4577
4711
|
error_code: "DOWNLOAD_FAILED",
|
|
@@ -4581,6 +4715,7 @@ Use /mnemospark-cloud op-status --operation-id ${operationId}`
|
|
|
4581
4715
|
"download.completed",
|
|
4582
4716
|
{
|
|
4583
4717
|
operation_id: operationId,
|
|
4718
|
+
trace_id: correlation.traceId,
|
|
4584
4719
|
wallet_address: resolvedRequest.wallet_address,
|
|
4585
4720
|
object_key: resolvedRequest.object_key,
|
|
4586
4721
|
status: "failed"
|
|
@@ -4603,10 +4738,14 @@ Use /mnemospark-cloud op-status --operation-id ${operationId}`
|
|
|
4603
4738
|
return { text: resolved.error ?? "Cannot resolve storage object request.", isError: true };
|
|
4604
4739
|
}
|
|
4605
4740
|
const resolvedRequest = resolved.request;
|
|
4606
|
-
const
|
|
4741
|
+
const correlation = buildRequestCorrelation();
|
|
4742
|
+
const operationId = correlation.operationId;
|
|
4607
4743
|
const existingObjectByKey = await datastore.findObjectByObjectKey(resolvedRequest.object_key);
|
|
4608
4744
|
try {
|
|
4609
|
-
const deleteResult = await requestStorageDelete(resolvedRequest,
|
|
4745
|
+
const deleteResult = await requestStorageDelete(resolvedRequest, {
|
|
4746
|
+
...options.proxyStorageOptions,
|
|
4747
|
+
correlation
|
|
4748
|
+
});
|
|
4610
4749
|
if (!deleteResult.success) {
|
|
4611
4750
|
throw new Error("delete failed");
|
|
4612
4751
|
}
|
|
@@ -4615,6 +4754,7 @@ Use /mnemospark-cloud op-status --operation-id ${operationId}`
|
|
|
4615
4754
|
"delete.completed",
|
|
4616
4755
|
{
|
|
4617
4756
|
operation_id: operationId,
|
|
4757
|
+
trace_id: correlation.traceId,
|
|
4618
4758
|
wallet_address: resolvedRequest.wallet_address,
|
|
4619
4759
|
object_key: resolvedRequest.object_key,
|
|
4620
4760
|
status: "failed"
|
|
@@ -4672,6 +4812,7 @@ Use /mnemospark-cloud op-status --operation-id ${operationId}`
|
|
|
4672
4812
|
"delete.completed",
|
|
4673
4813
|
{
|
|
4674
4814
|
operation_id: operationId,
|
|
4815
|
+
trace_id: correlation.traceId,
|
|
4675
4816
|
wallet_address: resolvedRequest.wallet_address,
|
|
4676
4817
|
object_key: resolvedRequest.object_key,
|
|
4677
4818
|
status: "succeeded"
|