mnemospark 0.3.0 → 0.4.0
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/dist/cli.js +341 -3
- package/dist/cli.js.map +1 -1
- package/dist/index.d.ts +20 -0
- package/dist/index.js +341 -3
- package/dist/index.js.map +1 -1
- package/openclaw.plugin.json +1 -1
- package/package.json +1 -1
- package/skills/mnemospark/SKILL.md +2 -1
- package/skills/mnemospark/references/commands.md +7 -0
- package/skills/mnemospark/references/state-and-logs.md +8 -0
package/dist/index.d.ts
CHANGED
|
@@ -540,6 +540,24 @@ type ProxyUploadConfirmOptions = {
|
|
|
540
540
|
fetchImpl?: FetchLike$2;
|
|
541
541
|
correlation?: RequestCorrelation;
|
|
542
542
|
};
|
|
543
|
+
/** Options for requesting payment/settle via the proxy. */
|
|
544
|
+
type ProxySettleOptions = {
|
|
545
|
+
proxyBaseUrl?: string;
|
|
546
|
+
fetchImpl?: FetchLike$2;
|
|
547
|
+
correlation?: RequestCorrelation;
|
|
548
|
+
/** Optional inline payment authorization payload. */
|
|
549
|
+
payment?: Record<string, unknown>;
|
|
550
|
+
/** Optional alternate inline payment authorization envelope. */
|
|
551
|
+
paymentAuthorization?: Record<string, unknown> | string;
|
|
552
|
+
};
|
|
553
|
+
/** Result from forwarding payment/settle to the backend (or proxy). */
|
|
554
|
+
type BackendSettleForwardResult = {
|
|
555
|
+
status: number;
|
|
556
|
+
bodyText: string;
|
|
557
|
+
contentType: string;
|
|
558
|
+
paymentRequired?: string;
|
|
559
|
+
paymentResponse?: string;
|
|
560
|
+
};
|
|
543
561
|
|
|
544
562
|
type StorageObjectRequest = {
|
|
545
563
|
wallet_address: string;
|
|
@@ -647,7 +665,9 @@ type CreateCloudCommandOptions = {
|
|
|
647
665
|
idempotencyKeyFn?: () => string;
|
|
648
666
|
proxyQuoteOptions?: ProxyQuoteOptions;
|
|
649
667
|
proxyUploadOptions?: ProxyUploadOptions;
|
|
668
|
+
proxySettleOptions?: ProxySettleOptions;
|
|
650
669
|
proxyUploadConfirmOptions?: ProxyUploadConfirmOptions;
|
|
670
|
+
requestPaymentSettleViaProxyFn?: (quoteId: string, walletAddress: string, options?: ProxySettleOptions) => Promise<BackendSettleForwardResult>;
|
|
651
671
|
requestStorageLsFn?: (request: StorageObjectRequest, options?: ProxyStorageOptions) => Promise<StorageLsResponse>;
|
|
652
672
|
requestStorageDownloadFn?: (request: StorageObjectRequest, options?: ProxyStorageOptions) => Promise<StorageDownloadProxyResponse>;
|
|
653
673
|
requestStorageDeleteFn?: (request: StorageObjectRequest, options?: ProxyStorageOptions) => Promise<StorageDeleteResponse>;
|
package/dist/index.js
CHANGED
|
@@ -2835,6 +2835,7 @@ async function createCloudDatastore(homeDir) {
|
|
|
2835
2835
|
const nextDb = new DatabaseSyncCtor(dbPath);
|
|
2836
2836
|
nextDb.exec("PRAGMA journal_mode=WAL;");
|
|
2837
2837
|
nextDb.exec("PRAGMA foreign_keys=ON;");
|
|
2838
|
+
nextDb.exec("PRAGMA busy_timeout=5000;");
|
|
2838
2839
|
nextDb.exec(`
|
|
2839
2840
|
CREATE TABLE IF NOT EXISTS schema_migrations (
|
|
2840
2841
|
version INTEGER PRIMARY KEY,
|
|
@@ -2883,6 +2884,7 @@ async function createCloudDatastore(homeDir) {
|
|
|
2883
2884
|
updated_at TEXT NOT NULL
|
|
2884
2885
|
);
|
|
2885
2886
|
CREATE INDEX IF NOT EXISTS idx_cron_jobs_object_key ON cron_jobs(object_key);
|
|
2887
|
+
CREATE INDEX IF NOT EXISTS idx_cron_jobs_quote_id ON cron_jobs(quote_id);
|
|
2886
2888
|
|
|
2887
2889
|
CREATE TABLE IF NOT EXISTS operations (
|
|
2888
2890
|
operation_id TEXT PRIMARY KEY,
|
|
@@ -3083,6 +3085,38 @@ async function createCloudDatastore(homeDir) {
|
|
|
3083
3085
|
if (!row) return null;
|
|
3084
3086
|
return { cronId: row.cron_id, objectId: row.object_id };
|
|
3085
3087
|
}, null),
|
|
3088
|
+
findCronByQuoteId: async (quoteId) => safe(() => {
|
|
3089
|
+
const row = db.prepare(
|
|
3090
|
+
`SELECT cron_id, object_id, object_key, quote_id, schedule, command, status
|
|
3091
|
+
FROM cron_jobs WHERE quote_id = ? ORDER BY updated_at DESC LIMIT 1`
|
|
3092
|
+
).get(quoteId);
|
|
3093
|
+
if (!row) return null;
|
|
3094
|
+
return {
|
|
3095
|
+
cron_id: row.cron_id,
|
|
3096
|
+
object_id: row.object_id,
|
|
3097
|
+
object_key: row.object_key,
|
|
3098
|
+
quote_id: row.quote_id,
|
|
3099
|
+
schedule: row.schedule,
|
|
3100
|
+
command: row.command,
|
|
3101
|
+
status: row.status
|
|
3102
|
+
};
|
|
3103
|
+
}, null),
|
|
3104
|
+
findPaymentByQuoteId: async (quoteId) => safe(() => {
|
|
3105
|
+
const row = db.prepare(
|
|
3106
|
+
`SELECT quote_id, wallet_address, trans_id, amount, network, status, settled_at
|
|
3107
|
+
FROM payments WHERE quote_id = ? LIMIT 1`
|
|
3108
|
+
).get(quoteId);
|
|
3109
|
+
if (!row) return null;
|
|
3110
|
+
return {
|
|
3111
|
+
quote_id: row.quote_id,
|
|
3112
|
+
wallet_address: row.wallet_address,
|
|
3113
|
+
trans_id: row.trans_id,
|
|
3114
|
+
amount: row.amount,
|
|
3115
|
+
network: row.network,
|
|
3116
|
+
status: row.status,
|
|
3117
|
+
settled_at: row.settled_at
|
|
3118
|
+
};
|
|
3119
|
+
}, null),
|
|
3086
3120
|
upsertOperation: async (row) => {
|
|
3087
3121
|
await safe(() => {
|
|
3088
3122
|
const ts = nowIso();
|
|
@@ -3229,7 +3263,15 @@ var CRON_LOG_ROW_PREFIX = "cron";
|
|
|
3229
3263
|
var TAR_OVERHEAD_BYTES = 10 * 1024 * 1024;
|
|
3230
3264
|
var REQUIRED_PRICE_STORAGE = "--wallet-address, --object-id, --object-id-hash, --gb, --provider, --region";
|
|
3231
3265
|
var REQUIRED_UPLOAD = "--quote-id, --wallet-address, --object-id, --object-id-hash";
|
|
3266
|
+
var REQUIRED_PAYMENT_SETTLE = "--quote-id and --wallet-address";
|
|
3232
3267
|
var REQUIRED_STORAGE_OBJECT = "--wallet-address and one of (--object-key | --name [--latest|--at])";
|
|
3268
|
+
var PAYMENT_SETTLE_FLAG_NAMES = /* @__PURE__ */ new Set([
|
|
3269
|
+
"quote-id",
|
|
3270
|
+
"wallet-address",
|
|
3271
|
+
"object-id",
|
|
3272
|
+
"object-key",
|
|
3273
|
+
"storage-price"
|
|
3274
|
+
]);
|
|
3233
3275
|
var BOOLEAN_SELECTOR_FLAGS = /* @__PURE__ */ new Set(["latest"]);
|
|
3234
3276
|
var BOOLEAN_ASYNC_FLAGS = /* @__PURE__ */ new Set(["async"]);
|
|
3235
3277
|
var BOOLEAN_OP_STATUS_FLAGS = /* @__PURE__ */ new Set(["cancel"]);
|
|
@@ -3262,6 +3304,10 @@ var CLOUD_HELP_TEXT = [
|
|
|
3262
3304
|
" Purpose: upload an encrypted object using a valid quote-id.",
|
|
3263
3305
|
" Required: " + REQUIRED_UPLOAD,
|
|
3264
3306
|
"",
|
|
3307
|
+
"\u2022 `/mnemospark_cloud payment-settle --quote-id <quote-id> --wallet-address <addr> [--object-id <id>] [--object-key <key>] [--storage-price <n>]`",
|
|
3308
|
+
" Purpose: settle storage payment for a quote (e.g. monthly cron). Uses the same proxy + x402 path as upload pre-settlement.",
|
|
3309
|
+
" Required: --quote-id, --wallet-address (wallet private key must match the address).",
|
|
3310
|
+
"",
|
|
3265
3311
|
"\u2022 `/mnemospark_cloud ls --wallet-address <addr> [--object-key <object-key> | --name <friendly-name>] [--latest|--at <timestamp>]`",
|
|
3266
3312
|
" Purpose: look up remote object metadata.",
|
|
3267
3313
|
" Required: " + REQUIRED_STORAGE_OBJECT,
|
|
@@ -3296,7 +3342,7 @@ var CLOUD_HELP_TEXT = [
|
|
|
3296
3342
|
"\u2022 `/mnemospark_cloud op-status --operation-id <id>`",
|
|
3297
3343
|
"\u2022 `/mnemospark_cloud op-status --operation-id <id> --cancel`",
|
|
3298
3344
|
"",
|
|
3299
|
-
"Backup creates a tar+gzip object in ~/.openclaw/mnemospark/backup and appends object metadata to ~/.openclaw/mnemospark/object.log. Upload appends storage rows and cron-tracking rows to object.log, and keeps job entries in ~/.openclaw/mnemospark/crontab.txt.
|
|
3345
|
+
"Backup creates a tar+gzip object in ~/.openclaw/mnemospark/backup and appends object metadata to ~/.openclaw/mnemospark/object.log. Upload appends storage rows and cron-tracking rows to object.log, and keeps job entries in ~/.openclaw/mnemospark/crontab.txt. Commands price-storage, upload, ls, download, delete, and payment-settle require --wallet-address."
|
|
3300
3346
|
].join("\n");
|
|
3301
3347
|
var UnsupportedBackupPlatformError = class extends Error {
|
|
3302
3348
|
constructor(platform) {
|
|
@@ -3537,6 +3583,41 @@ function parseCloudArgs(args) {
|
|
|
3537
3583
|
}
|
|
3538
3584
|
};
|
|
3539
3585
|
}
|
|
3586
|
+
if (subcommand === "payment-settle") {
|
|
3587
|
+
const flags = parseNamedFlags(rest);
|
|
3588
|
+
if (!flags) {
|
|
3589
|
+
return { mode: "payment-settle-invalid" };
|
|
3590
|
+
}
|
|
3591
|
+
for (const key of Object.keys(flags)) {
|
|
3592
|
+
if (!PAYMENT_SETTLE_FLAG_NAMES.has(key)) {
|
|
3593
|
+
return { mode: "payment-settle-invalid" };
|
|
3594
|
+
}
|
|
3595
|
+
}
|
|
3596
|
+
const quoteId = flags["quote-id"]?.trim();
|
|
3597
|
+
const walletAddress = flags["wallet-address"]?.trim();
|
|
3598
|
+
if (!quoteId || !walletAddress) {
|
|
3599
|
+
return { mode: "payment-settle-invalid" };
|
|
3600
|
+
}
|
|
3601
|
+
let storagePrice;
|
|
3602
|
+
if (flags["storage-price"] !== void 0 && flags["storage-price"] !== "") {
|
|
3603
|
+
const raw = flags["storage-price"]?.trim() ?? "";
|
|
3604
|
+
const n = Number.parseFloat(raw);
|
|
3605
|
+
if (!Number.isFinite(n) || n < 0) {
|
|
3606
|
+
return { mode: "payment-settle-invalid" };
|
|
3607
|
+
}
|
|
3608
|
+
storagePrice = n;
|
|
3609
|
+
}
|
|
3610
|
+
return {
|
|
3611
|
+
mode: "payment-settle",
|
|
3612
|
+
paymentSettleRequest: {
|
|
3613
|
+
quote_id: quoteId,
|
|
3614
|
+
wallet_address: walletAddress,
|
|
3615
|
+
object_id: flags["object-id"]?.trim() || void 0,
|
|
3616
|
+
object_key: flags["object-key"]?.trim() || void 0,
|
|
3617
|
+
storage_price: storagePrice
|
|
3618
|
+
}
|
|
3619
|
+
};
|
|
3620
|
+
}
|
|
3540
3621
|
if (subcommand === "ls") {
|
|
3541
3622
|
const flags = parseNamedFlags(rest, BOOLEAN_SELECTOR_FLAGS);
|
|
3542
3623
|
if (!flags) {
|
|
@@ -3897,7 +3978,8 @@ function quoteCronArgument(value) {
|
|
|
3897
3978
|
}
|
|
3898
3979
|
function buildStoragePaymentCronCommand(job) {
|
|
3899
3980
|
return [
|
|
3900
|
-
"
|
|
3981
|
+
"/mnemospark_cloud",
|
|
3982
|
+
"payment-settle",
|
|
3901
3983
|
"--quote-id",
|
|
3902
3984
|
quoteCronArgument(job.quoteId),
|
|
3903
3985
|
"--wallet-address",
|
|
@@ -4319,10 +4401,12 @@ function createCloudCommand(options = {}) {
|
|
|
4319
4401
|
requestStorageLsFn: options.requestStorageLsFn ?? requestStorageLsViaProxy,
|
|
4320
4402
|
requestStorageDownloadFn: options.requestStorageDownloadFn ?? requestStorageDownloadViaProxy,
|
|
4321
4403
|
requestStorageDeleteFn: options.requestStorageDeleteFn ?? requestStorageDeleteViaProxy,
|
|
4404
|
+
requestPaymentSettleViaProxyFn: options.requestPaymentSettleViaProxyFn ?? requestPaymentSettleViaProxy,
|
|
4322
4405
|
objectLogHomeDir: options.objectLogHomeDir ?? options.backupOptions?.homeDir,
|
|
4323
4406
|
backupOptions: options.backupOptions,
|
|
4324
4407
|
proxyQuoteOptions: options.proxyQuoteOptions,
|
|
4325
4408
|
proxyUploadOptions: options.proxyUploadOptions,
|
|
4409
|
+
proxySettleOptions: options.proxySettleOptions,
|
|
4326
4410
|
proxyUploadConfirmOptions: options.proxyUploadConfirmOptions,
|
|
4327
4411
|
subagentOrchestrator,
|
|
4328
4412
|
proxyStorageOptions: options.proxyStorageOptions
|
|
@@ -4486,6 +4570,117 @@ function buildRequestCorrelation(forcedOperationId, forcedTraceId) {
|
|
|
4486
4570
|
const traceId = forcedTraceId?.trim() || randomUUID3();
|
|
4487
4571
|
return { operationId, traceId };
|
|
4488
4572
|
}
|
|
4573
|
+
function parseTransIdFromPaymentSettleBody(bodyText) {
|
|
4574
|
+
const trimmed = bodyText.trim();
|
|
4575
|
+
if (!trimmed.startsWith("{")) {
|
|
4576
|
+
return null;
|
|
4577
|
+
}
|
|
4578
|
+
try {
|
|
4579
|
+
const parsed = JSON.parse(trimmed);
|
|
4580
|
+
const tid = parsed.trans_id;
|
|
4581
|
+
return typeof tid === "string" && tid.trim() ? tid.trim() : null;
|
|
4582
|
+
} catch {
|
|
4583
|
+
return null;
|
|
4584
|
+
}
|
|
4585
|
+
}
|
|
4586
|
+
async function resolveAmountForPaymentSettle(quoteId, storagePriceFromFlag, datastore, homeDir) {
|
|
4587
|
+
if (storagePriceFromFlag !== void 0 && Number.isFinite(storagePriceFromFlag)) {
|
|
4588
|
+
return storagePriceFromFlag;
|
|
4589
|
+
}
|
|
4590
|
+
const quoteLookup = await datastore.findQuoteById(quoteId);
|
|
4591
|
+
if (quoteLookup && Number.isFinite(quoteLookup.storagePrice)) {
|
|
4592
|
+
return quoteLookup.storagePrice;
|
|
4593
|
+
}
|
|
4594
|
+
const logged = await findLoggedPriceStorageQuote(quoteId, homeDir);
|
|
4595
|
+
if (logged && Number.isFinite(logged.storagePrice)) {
|
|
4596
|
+
return logged.storagePrice;
|
|
4597
|
+
}
|
|
4598
|
+
const payment = await datastore.findPaymentByQuoteId(quoteId);
|
|
4599
|
+
if (payment && Number.isFinite(payment.amount)) {
|
|
4600
|
+
return payment.amount;
|
|
4601
|
+
}
|
|
4602
|
+
return 0;
|
|
4603
|
+
}
|
|
4604
|
+
async function emitPaymentSettleClientObservationBestEffort(params) {
|
|
4605
|
+
try {
|
|
4606
|
+
const {
|
|
4607
|
+
phase,
|
|
4608
|
+
correlation,
|
|
4609
|
+
quoteId,
|
|
4610
|
+
walletAddress,
|
|
4611
|
+
objectId,
|
|
4612
|
+
objectKey,
|
|
4613
|
+
httpStatus,
|
|
4614
|
+
outcomeStatus,
|
|
4615
|
+
homeDir
|
|
4616
|
+
} = params;
|
|
4617
|
+
const ts = (/* @__PURE__ */ new Date()).toISOString();
|
|
4618
|
+
if (phase === "start") {
|
|
4619
|
+
await emitCloudEventBestEffort(
|
|
4620
|
+
"payment-settle.started",
|
|
4621
|
+
{
|
|
4622
|
+
operation_id: correlation.operationId,
|
|
4623
|
+
trace_id: correlation.traceId,
|
|
4624
|
+
quote_id: quoteId,
|
|
4625
|
+
wallet_address: walletAddress,
|
|
4626
|
+
object_id: objectId,
|
|
4627
|
+
object_key: objectKey,
|
|
4628
|
+
status: "running"
|
|
4629
|
+
},
|
|
4630
|
+
homeDir
|
|
4631
|
+
);
|
|
4632
|
+
await appendJsonlEvent(
|
|
4633
|
+
"proxy-events.jsonl",
|
|
4634
|
+
{
|
|
4635
|
+
ts,
|
|
4636
|
+
event_type: "payment.settle",
|
|
4637
|
+
status: "start",
|
|
4638
|
+
trace_id: correlation.traceId,
|
|
4639
|
+
operation_id: correlation.operationId,
|
|
4640
|
+
quote_id: quoteId,
|
|
4641
|
+
wallet_address: walletAddress,
|
|
4642
|
+
object_id: objectId ?? null,
|
|
4643
|
+
object_key: objectKey ?? null,
|
|
4644
|
+
details: { source: "client" }
|
|
4645
|
+
},
|
|
4646
|
+
homeDir
|
|
4647
|
+
);
|
|
4648
|
+
return;
|
|
4649
|
+
}
|
|
4650
|
+
const terminal = outcomeStatus ?? "failed";
|
|
4651
|
+
await emitCloudEventBestEffort(
|
|
4652
|
+
"payment-settle.completed",
|
|
4653
|
+
{
|
|
4654
|
+
operation_id: correlation.operationId,
|
|
4655
|
+
trace_id: correlation.traceId,
|
|
4656
|
+
quote_id: quoteId,
|
|
4657
|
+
wallet_address: walletAddress,
|
|
4658
|
+
object_id: objectId,
|
|
4659
|
+
object_key: objectKey,
|
|
4660
|
+
status: terminal === "succeeded" ? "succeeded" : "failed",
|
|
4661
|
+
http_status: httpStatus
|
|
4662
|
+
},
|
|
4663
|
+
homeDir
|
|
4664
|
+
);
|
|
4665
|
+
await appendJsonlEvent(
|
|
4666
|
+
"proxy-events.jsonl",
|
|
4667
|
+
{
|
|
4668
|
+
ts,
|
|
4669
|
+
event_type: "payment.settle",
|
|
4670
|
+
status: "result",
|
|
4671
|
+
trace_id: correlation.traceId,
|
|
4672
|
+
operation_id: correlation.operationId,
|
|
4673
|
+
quote_id: quoteId,
|
|
4674
|
+
wallet_address: walletAddress,
|
|
4675
|
+
object_id: objectId ?? null,
|
|
4676
|
+
object_key: objectKey ?? null,
|
|
4677
|
+
details: { http_status: httpStatus ?? null, source: "client" }
|
|
4678
|
+
},
|
|
4679
|
+
homeDir
|
|
4680
|
+
);
|
|
4681
|
+
} catch {
|
|
4682
|
+
}
|
|
4683
|
+
}
|
|
4489
4684
|
async function runCloudCommandHandler(ctx, options, executionContext = {}) {
|
|
4490
4685
|
const parsed = parseCloudArgs(ctx.args);
|
|
4491
4686
|
const objectLogHomeDir = options.objectLogHomeDir;
|
|
@@ -4501,6 +4696,7 @@ async function runCloudCommandHandler(ctx, options, executionContext = {}) {
|
|
|
4501
4696
|
const requestStorageLs = options.requestStorageLsFn;
|
|
4502
4697
|
const requestStorageDownload = options.requestStorageDownloadFn;
|
|
4503
4698
|
const requestStorageDelete = options.requestStorageDeleteFn;
|
|
4699
|
+
const requestPaymentSettleViaProxy2 = options.requestPaymentSettleViaProxyFn;
|
|
4504
4700
|
const subagentOrchestrator = options.subagentOrchestrator;
|
|
4505
4701
|
if (parsed.mode === "help" || parsed.mode === "unknown") {
|
|
4506
4702
|
return {
|
|
@@ -4538,6 +4734,12 @@ async function runCloudCommandHandler(ctx, options, executionContext = {}) {
|
|
|
4538
4734
|
isError: true
|
|
4539
4735
|
};
|
|
4540
4736
|
}
|
|
4737
|
+
if (parsed.mode === "payment-settle-invalid") {
|
|
4738
|
+
return {
|
|
4739
|
+
text: `Cannot settle payment: required arguments are ${REQUIRED_PAYMENT_SETTLE}. Optional: --object-id, --object-key, --storage-price.`,
|
|
4740
|
+
isError: true
|
|
4741
|
+
};
|
|
4742
|
+
}
|
|
4541
4743
|
if (parsed.mode === "ls-invalid") {
|
|
4542
4744
|
return {
|
|
4543
4745
|
text: `Cannot list storage object: required arguments are ${REQUIRED_STORAGE_OBJECT}.`,
|
|
@@ -4682,6 +4884,142 @@ async function runCloudCommandHandler(ctx, options, executionContext = {}) {
|
|
|
4682
4884
|
}
|
|
4683
4885
|
return formatOperationStatus(operation);
|
|
4684
4886
|
}
|
|
4887
|
+
if (parsed.mode === "payment-settle") {
|
|
4888
|
+
const req = parsed.paymentSettleRequest;
|
|
4889
|
+
let walletKey;
|
|
4890
|
+
try {
|
|
4891
|
+
walletKey = await resolveWalletKey(objectLogHomeDir);
|
|
4892
|
+
} catch (err) {
|
|
4893
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
4894
|
+
return { text: message.trim() || "Cannot resolve wallet key.", isError: true };
|
|
4895
|
+
}
|
|
4896
|
+
const walletAccount = privateKeyToAccount5(walletKey);
|
|
4897
|
+
if (walletAccount.address.toLowerCase() !== req.wallet_address.toLowerCase()) {
|
|
4898
|
+
return {
|
|
4899
|
+
text: `Cannot settle payment: wallet key address ${walletAccount.address} does not match --wallet-address ${req.wallet_address}.`,
|
|
4900
|
+
isError: true
|
|
4901
|
+
};
|
|
4902
|
+
}
|
|
4903
|
+
const correlation = buildRequestCorrelation();
|
|
4904
|
+
const settleFetch = createPayment(walletKey).fetch;
|
|
4905
|
+
const objectId = req.object_id;
|
|
4906
|
+
const objectKey = req.object_key;
|
|
4907
|
+
await emitPaymentSettleClientObservationBestEffort({
|
|
4908
|
+
phase: "start",
|
|
4909
|
+
correlation,
|
|
4910
|
+
quoteId: req.quote_id,
|
|
4911
|
+
walletAddress: req.wallet_address,
|
|
4912
|
+
objectId,
|
|
4913
|
+
objectKey,
|
|
4914
|
+
homeDir: objectLogHomeDir
|
|
4915
|
+
});
|
|
4916
|
+
let settleResult;
|
|
4917
|
+
try {
|
|
4918
|
+
settleResult = await requestPaymentSettleViaProxy2(req.quote_id, req.wallet_address, {
|
|
4919
|
+
...options.proxySettleOptions,
|
|
4920
|
+
correlation,
|
|
4921
|
+
fetchImpl: (input, init) => settleFetch(input, init)
|
|
4922
|
+
});
|
|
4923
|
+
} catch (err) {
|
|
4924
|
+
const amountErr = await resolveAmountForPaymentSettle(
|
|
4925
|
+
req.quote_id,
|
|
4926
|
+
req.storage_price,
|
|
4927
|
+
datastore,
|
|
4928
|
+
objectLogHomeDir
|
|
4929
|
+
);
|
|
4930
|
+
await datastore.upsertPayment({
|
|
4931
|
+
quote_id: req.quote_id,
|
|
4932
|
+
wallet_address: req.wallet_address,
|
|
4933
|
+
trans_id: null,
|
|
4934
|
+
amount: amountErr,
|
|
4935
|
+
network: null,
|
|
4936
|
+
status: "settle_failed",
|
|
4937
|
+
settled_at: null
|
|
4938
|
+
});
|
|
4939
|
+
const cronErr = await datastore.findCronByQuoteId(req.quote_id);
|
|
4940
|
+
if (cronErr) {
|
|
4941
|
+
await datastore.upsertCronJob({ ...cronErr, status: "active" });
|
|
4942
|
+
}
|
|
4943
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
4944
|
+
await emitPaymentSettleClientObservationBestEffort({
|
|
4945
|
+
phase: "result",
|
|
4946
|
+
correlation,
|
|
4947
|
+
quoteId: req.quote_id,
|
|
4948
|
+
walletAddress: req.wallet_address,
|
|
4949
|
+
objectId,
|
|
4950
|
+
objectKey,
|
|
4951
|
+
outcomeStatus: "failed",
|
|
4952
|
+
homeDir: objectLogHomeDir
|
|
4953
|
+
});
|
|
4954
|
+
return { text: `Payment settle failed: ${msg}`, isError: true };
|
|
4955
|
+
}
|
|
4956
|
+
const amount = await resolveAmountForPaymentSettle(
|
|
4957
|
+
req.quote_id,
|
|
4958
|
+
req.storage_price,
|
|
4959
|
+
datastore,
|
|
4960
|
+
objectLogHomeDir
|
|
4961
|
+
);
|
|
4962
|
+
const transId = settleResult.status === 200 ? parseTransIdFromPaymentSettleBody(settleResult.bodyText ?? "") : null;
|
|
4963
|
+
if (settleResult.status === 200) {
|
|
4964
|
+
await datastore.upsertPayment({
|
|
4965
|
+
quote_id: req.quote_id,
|
|
4966
|
+
wallet_address: req.wallet_address,
|
|
4967
|
+
trans_id: transId,
|
|
4968
|
+
amount,
|
|
4969
|
+
network: null,
|
|
4970
|
+
status: "settled",
|
|
4971
|
+
settled_at: (/* @__PURE__ */ new Date()).toISOString()
|
|
4972
|
+
});
|
|
4973
|
+
const cronRow = await datastore.findCronByQuoteId(req.quote_id);
|
|
4974
|
+
if (cronRow) {
|
|
4975
|
+
await datastore.upsertCronJob({ ...cronRow, status: "active" });
|
|
4976
|
+
}
|
|
4977
|
+
await emitPaymentSettleClientObservationBestEffort({
|
|
4978
|
+
phase: "result",
|
|
4979
|
+
correlation,
|
|
4980
|
+
quoteId: req.quote_id,
|
|
4981
|
+
walletAddress: req.wallet_address,
|
|
4982
|
+
objectId,
|
|
4983
|
+
objectKey,
|
|
4984
|
+
httpStatus: settleResult.status,
|
|
4985
|
+
outcomeStatus: "succeeded",
|
|
4986
|
+
homeDir: objectLogHomeDir
|
|
4987
|
+
});
|
|
4988
|
+
return {
|
|
4989
|
+
text: transId ? `Payment settled for quote ${req.quote_id} (trans_id: ${transId}).` : `Payment settled for quote ${req.quote_id}.`
|
|
4990
|
+
};
|
|
4991
|
+
}
|
|
4992
|
+
await datastore.upsertPayment({
|
|
4993
|
+
quote_id: req.quote_id,
|
|
4994
|
+
wallet_address: req.wallet_address,
|
|
4995
|
+
trans_id: transId,
|
|
4996
|
+
amount,
|
|
4997
|
+
network: null,
|
|
4998
|
+
status: "settle_failed",
|
|
4999
|
+
settled_at: null
|
|
5000
|
+
});
|
|
5001
|
+
const cronRowFailed = await datastore.findCronByQuoteId(req.quote_id);
|
|
5002
|
+
if (cronRowFailed) {
|
|
5003
|
+
await datastore.upsertCronJob({ ...cronRowFailed, status: "active" });
|
|
5004
|
+
}
|
|
5005
|
+
await emitPaymentSettleClientObservationBestEffort({
|
|
5006
|
+
phase: "result",
|
|
5007
|
+
correlation,
|
|
5008
|
+
quoteId: req.quote_id,
|
|
5009
|
+
walletAddress: req.wallet_address,
|
|
5010
|
+
objectId,
|
|
5011
|
+
objectKey,
|
|
5012
|
+
httpStatus: settleResult.status,
|
|
5013
|
+
outcomeStatus: "failed",
|
|
5014
|
+
homeDir: objectLogHomeDir
|
|
5015
|
+
});
|
|
5016
|
+
const bodySnippet = settleResult.bodyText?.trim();
|
|
5017
|
+
const detail = bodySnippet && bodySnippet.length > 500 ? `${bodySnippet.slice(0, 500)}\u2026` : bodySnippet;
|
|
5018
|
+
return {
|
|
5019
|
+
text: detail ? `Payment settle failed (HTTP ${settleResult.status}): ${detail}` : `Payment settle failed with HTTP ${settleResult.status}.`,
|
|
5020
|
+
isError: true
|
|
5021
|
+
};
|
|
5022
|
+
}
|
|
4685
5023
|
if ((parsed.mode === "backup" || parsed.mode === "upload" || parsed.mode === "download") && parsed.async) {
|
|
4686
5024
|
const asyncCorrelation = buildRequestCorrelation();
|
|
4687
5025
|
const operationId = asyncCorrelation.operationId;
|
|
@@ -5192,7 +5530,7 @@ operation-id: ${operationId}`,
|
|
|
5192
5530
|
const shouldSettleBeforeUpload = requestStorageUpload !== requestStorageUploadViaProxy;
|
|
5193
5531
|
if (shouldSettleBeforeUpload) {
|
|
5194
5532
|
const paymentFetch = createPayment(walletKey).fetch;
|
|
5195
|
-
const settleResult = await
|
|
5533
|
+
const settleResult = await requestPaymentSettleViaProxy2(
|
|
5196
5534
|
parsed.uploadRequest.quote_id,
|
|
5197
5535
|
parsed.uploadRequest.wallet_address,
|
|
5198
5536
|
{
|