agentbnb 5.1.11 → 7.0.0-beta.1
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 +245 -39
- package/dist/{card-RSGDCHCV.js → card-REW7BSWW.js} +1 -1
- package/dist/{chunk-FLY3WIQR.js → chunk-2HSUPCBT.js} +3 -3
- package/dist/{chunk-WGZ5AGOX.js → chunk-3CIMVISQ.js} +24 -1
- package/dist/{chunk-NH2FIERR.js → chunk-574W3HHE.js} +1 -1
- package/dist/{chunk-WTXRY7R2.js → chunk-APEG4QIN.js} +157 -9
- package/dist/chunk-BP3L2TET.js +148 -0
- package/dist/{chunk-NLAWT4DT.js → chunk-CWYPTQRQ.js} +7 -7
- package/dist/{chunk-UKT6H7YT.js → chunk-DUW6RX6I.js} +5 -2
- package/dist/chunk-EAD4A4KG.js +430 -0
- package/dist/{chunk-QT7TEVNV.js → chunk-EHSHB7TY.js} +23 -1
- package/dist/{chunk-B5FTAGFN.js → chunk-ETGOKDFR.js} +75 -75
- package/dist/{chunk-5KFI5X7B.js → chunk-F53QQIM2.js} +1 -1
- package/dist/{chunk-MLS6IGGG.js → chunk-FK2MDNTB.js} +117 -117
- package/dist/{chunk-EGUOAHCW.js → chunk-GO4FVRVN.js} +15 -13
- package/dist/{chunk-CRFCWD6V.js → chunk-J2K5S5MX.js} +136 -173
- package/dist/chunk-K5FO42YF.js +1136 -0
- package/dist/{chunk-DFBX3BBD.js → chunk-KA2VIEGM.js} +211 -16
- package/dist/chunk-NWIQJ2CL.js +108 -0
- package/dist/chunk-OCSU2S6W.js +168 -0
- package/dist/{chunk-QQFBFV4V.js → chunk-PGDBUUGR.js} +60 -19
- package/dist/{chunk-QITOPASZ.js → chunk-PSQHUZ7X.js} +1 -1
- package/dist/{chunk-C6KPAFCC.js → chunk-PU7LXOQ3.js} +23 -1
- package/dist/{chunk-JOY533UH.js → chunk-TW65F5EU.js} +1 -1
- package/dist/{chunk-ZX5623ER.js → chunk-VMH2YS2I.js} +1 -1
- package/dist/{chunk-XND2DWTZ.js → chunk-VPQ44XKE.js} +2 -2
- package/dist/{chunk-CSATDXZC.js → chunk-Y7T6IMM3.js} +1 -1
- package/dist/cli/index.js +755 -379
- package/dist/{client-T5MTY3CS.js → client-HRYRJKSA.js} +3 -3
- package/dist/{conduct-WU3VEXB6.js → conduct-JNYJCDHQ.js} +14 -13
- package/dist/conduct-KJUD2RTB.js +22 -0
- package/dist/{conductor-mode-ZMTFZGJP.js → conductor-mode-2VVFMKVE.js} +313 -14
- package/dist/conductor-mode-VGUU54QI.js +276 -0
- package/dist/execute-I4PKSNJM.js +12 -0
- package/dist/execute-MOXSSA3Q.js +15 -0
- package/dist/index.d.ts +795 -2
- package/dist/index.js +861 -111
- package/dist/{process-guard-CC7CNRQJ.js → process-guard-QCCBGILS.js} +1 -1
- package/dist/publish-capability-TS6CNR5G.js +12 -0
- package/dist/reliability-metrics-QG7WC5QK.js +18 -0
- package/dist/{request-VOXBFUOG.js → request-E7TA7COA.js} +19 -18
- package/dist/{serve-skill-IH7UAJNR.js → serve-skill-HIOWYKRU.js} +13 -11
- package/dist/{server-JVQW2TID.js → server-I63CXFX3.js} +17 -16
- package/dist/{service-coordinator-EYRDTHL5.js → service-coordinator-XBNT3SMU.js} +369 -260
- package/dist/skill-config-FETXPNVP.js +22 -0
- package/dist/skills/agentbnb/bootstrap.js +430 -84
- package/dist/websocket-client-5MH6QRJK.js +7 -0
- package/dist/{websocket-client-WRN3HO73.js → websocket-client-PFGVTXNE.js} +1 -1
- package/openclaw.plugin.json +2 -2
- package/package.json +2 -1
- package/skills/agentbnb/SKILL.md +35 -0
- package/skills/agentbnb/bootstrap.ts +126 -8
- package/skills/agentbnb/install.sh +49 -9
- package/dist/chunk-EANI2N2V.js +0 -309
- package/dist/chunk-EPIWHNB2.js +0 -946
- package/dist/conduct-6LKIJJKQ.js +0 -21
- package/dist/conductor-mode-Q4IIDY5E.js +0 -123
- package/dist/execute-4D4ITQCL.js +0 -10
- package/dist/execute-T7Y6RKSW.js +0 -13
- package/dist/websocket-client-6IIDGXKB.js +0 -7
|
@@ -1,6 +1,10 @@
|
|
|
1
|
+
import {
|
|
2
|
+
ensureReliabilityTable,
|
|
3
|
+
recordSuccessfulHire
|
|
4
|
+
} from "./chunk-NWIQJ2CL.js";
|
|
1
5
|
import {
|
|
2
6
|
AgentBnBError
|
|
3
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-3CIMVISQ.js";
|
|
4
8
|
|
|
5
9
|
// src/credit/ledger.ts
|
|
6
10
|
import Database from "better-sqlite3";
|
|
@@ -31,6 +35,22 @@ var CREDIT_SCHEMA = `
|
|
|
31
35
|
settled_at TEXT
|
|
32
36
|
);
|
|
33
37
|
|
|
38
|
+
CREATE TABLE IF NOT EXISTS provider_registry (
|
|
39
|
+
owner TEXT PRIMARY KEY,
|
|
40
|
+
provider_number INTEGER NOT NULL,
|
|
41
|
+
registered_at TEXT NOT NULL
|
|
42
|
+
);
|
|
43
|
+
|
|
44
|
+
CREATE TABLE IF NOT EXISTS demand_vouchers (
|
|
45
|
+
id TEXT PRIMARY KEY,
|
|
46
|
+
owner TEXT NOT NULL,
|
|
47
|
+
amount INTEGER NOT NULL,
|
|
48
|
+
remaining INTEGER NOT NULL,
|
|
49
|
+
created_at TEXT NOT NULL,
|
|
50
|
+
expires_at TEXT NOT NULL,
|
|
51
|
+
is_active INTEGER NOT NULL DEFAULT 1
|
|
52
|
+
);
|
|
53
|
+
|
|
34
54
|
CREATE INDEX IF NOT EXISTS idx_transactions_owner ON credit_transactions(owner, created_at);
|
|
35
55
|
CREATE INDEX IF NOT EXISTS idx_escrow_owner ON credit_escrow(owner);
|
|
36
56
|
`;
|
|
@@ -39,18 +59,28 @@ function openCreditDb(path = ":memory:") {
|
|
|
39
59
|
db.pragma("journal_mode = WAL");
|
|
40
60
|
db.pragma("foreign_keys = ON");
|
|
41
61
|
db.exec(CREDIT_SCHEMA);
|
|
62
|
+
try {
|
|
63
|
+
db.exec("ALTER TABLE credit_escrow ADD COLUMN funding_source TEXT NOT NULL DEFAULT 'balance'");
|
|
64
|
+
} catch {
|
|
65
|
+
}
|
|
66
|
+
ensureReliabilityTable(db);
|
|
42
67
|
return db;
|
|
43
68
|
}
|
|
44
69
|
function bootstrapAgent(db, owner, amount = 100) {
|
|
45
70
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
71
|
+
let isNew = false;
|
|
46
72
|
db.transaction(() => {
|
|
47
73
|
const result = db.prepare("INSERT OR IGNORE INTO credit_balances (owner, balance, updated_at) VALUES (?, ?, ?)").run(owner, amount, now);
|
|
48
74
|
if (result.changes > 0) {
|
|
75
|
+
isNew = true;
|
|
49
76
|
db.prepare(
|
|
50
77
|
"INSERT INTO credit_transactions (id, owner, amount, reason, reference_id, created_at) VALUES (?, ?, ?, ?, ?, ?)"
|
|
51
78
|
).run(randomUUID(), owner, amount, "bootstrap", null, now);
|
|
52
79
|
}
|
|
53
80
|
})();
|
|
81
|
+
if (isNew) {
|
|
82
|
+
issueVoucher(db, owner, 50, 30);
|
|
83
|
+
}
|
|
54
84
|
}
|
|
55
85
|
function getBalance(db, owner) {
|
|
56
86
|
const row = db.prepare("SELECT balance FROM credit_balances WHERE owner = ?").get(owner);
|
|
@@ -61,6 +91,44 @@ function getTransactions(db, owner, limit = 100) {
|
|
|
61
91
|
"SELECT id, owner, amount, reason, reference_id, created_at FROM credit_transactions WHERE owner = ? ORDER BY created_at DESC LIMIT ?"
|
|
62
92
|
).all(owner, limit);
|
|
63
93
|
}
|
|
94
|
+
function registerProvider(db, owner) {
|
|
95
|
+
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
96
|
+
const maxRow = db.prepare("SELECT MAX(provider_number) as maxNum FROM provider_registry").get();
|
|
97
|
+
const nextNum = (maxRow?.maxNum ?? 0) + 1;
|
|
98
|
+
db.prepare("INSERT OR IGNORE INTO provider_registry (owner, provider_number, registered_at) VALUES (?, ?, ?)").run(owner, nextNum, now);
|
|
99
|
+
const row = db.prepare("SELECT provider_number FROM provider_registry WHERE owner = ?").get(owner);
|
|
100
|
+
return row.provider_number;
|
|
101
|
+
}
|
|
102
|
+
function getProviderNumber(db, owner) {
|
|
103
|
+
const row = db.prepare("SELECT provider_number FROM provider_registry WHERE owner = ?").get(owner);
|
|
104
|
+
return row?.provider_number ?? null;
|
|
105
|
+
}
|
|
106
|
+
function getProviderBonus(providerNumber) {
|
|
107
|
+
if (providerNumber <= 50) return 2;
|
|
108
|
+
if (providerNumber <= 200) return 1.5;
|
|
109
|
+
return 1;
|
|
110
|
+
}
|
|
111
|
+
function issueVoucher(db, owner, amount = 50, daysValid = 30) {
|
|
112
|
+
const id = randomUUID();
|
|
113
|
+
const now = /* @__PURE__ */ new Date();
|
|
114
|
+
const expiresAt = new Date(now.getTime() + daysValid * 24 * 60 * 60 * 1e3);
|
|
115
|
+
db.prepare(
|
|
116
|
+
"INSERT INTO demand_vouchers (id, owner, amount, remaining, created_at, expires_at, is_active) VALUES (?, ?, ?, ?, ?, ?, 1)"
|
|
117
|
+
).run(id, owner, amount, amount, now.toISOString(), expiresAt.toISOString());
|
|
118
|
+
return id;
|
|
119
|
+
}
|
|
120
|
+
function getActiveVoucher(db, owner) {
|
|
121
|
+
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
122
|
+
const row = db.prepare(
|
|
123
|
+
"SELECT id, remaining, expires_at FROM demand_vouchers WHERE owner = ? AND is_active = 1 AND remaining > 0 AND expires_at > ? ORDER BY created_at ASC LIMIT 1"
|
|
124
|
+
).get(owner, now);
|
|
125
|
+
return row ?? null;
|
|
126
|
+
}
|
|
127
|
+
function consumeVoucher(db, voucherId, amount) {
|
|
128
|
+
db.prepare(
|
|
129
|
+
"UPDATE demand_vouchers SET remaining = remaining - ? WHERE id = ? AND remaining >= ?"
|
|
130
|
+
).run(amount, voucherId, amount);
|
|
131
|
+
}
|
|
64
132
|
function recordEarning(db, owner, amount, _cardId, receiptNonce) {
|
|
65
133
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
66
134
|
db.transaction(() => {
|
|
@@ -101,23 +169,35 @@ function migrateOwner(db, oldOwner, newOwner) {
|
|
|
101
169
|
|
|
102
170
|
// src/credit/escrow.ts
|
|
103
171
|
import { randomUUID as randomUUID2 } from "crypto";
|
|
172
|
+
var NETWORK_FEE_RATE = 0.05;
|
|
104
173
|
function holdEscrow(db, owner, amount, cardId) {
|
|
105
174
|
const escrowId = randomUUID2();
|
|
106
175
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
107
176
|
const hold = db.transaction(() => {
|
|
108
|
-
const
|
|
109
|
-
if (
|
|
110
|
-
|
|
177
|
+
const voucher = getActiveVoucher(db, owner);
|
|
178
|
+
if (voucher && voucher.remaining >= amount) {
|
|
179
|
+
consumeVoucher(db, voucher.id, amount);
|
|
180
|
+
db.prepare(
|
|
181
|
+
"INSERT INTO credit_escrow (id, owner, amount, card_id, status, created_at, funding_source) VALUES (?, ?, ?, ?, ?, ?, ?)"
|
|
182
|
+
).run(escrowId, owner, amount, cardId, "held", now, "voucher");
|
|
183
|
+
db.prepare(
|
|
184
|
+
"INSERT INTO credit_transactions (id, owner, amount, reason, reference_id, created_at) VALUES (?, ?, ?, ?, ?, ?)"
|
|
185
|
+
).run(randomUUID2(), owner, -amount, "voucher_hold", escrowId, now);
|
|
186
|
+
} else {
|
|
187
|
+
const row = db.prepare("SELECT balance FROM credit_balances WHERE owner = ?").get(owner);
|
|
188
|
+
if (!row || row.balance < amount) {
|
|
189
|
+
throw new AgentBnBError("Insufficient credits", "INSUFFICIENT_CREDITS");
|
|
190
|
+
}
|
|
191
|
+
db.prepare(
|
|
192
|
+
"UPDATE credit_balances SET balance = balance - ?, updated_at = ? WHERE owner = ? AND balance >= ?"
|
|
193
|
+
).run(amount, now, owner, amount);
|
|
194
|
+
db.prepare(
|
|
195
|
+
"INSERT INTO credit_escrow (id, owner, amount, card_id, status, created_at, funding_source) VALUES (?, ?, ?, ?, ?, ?, ?)"
|
|
196
|
+
).run(escrowId, owner, amount, cardId, "held", now, "balance");
|
|
197
|
+
db.prepare(
|
|
198
|
+
"INSERT INTO credit_transactions (id, owner, amount, reason, reference_id, created_at) VALUES (?, ?, ?, ?, ?, ?)"
|
|
199
|
+
).run(randomUUID2(), owner, -amount, "escrow_hold", escrowId, now);
|
|
111
200
|
}
|
|
112
|
-
db.prepare(
|
|
113
|
-
"UPDATE credit_balances SET balance = balance - ?, updated_at = ? WHERE owner = ? AND balance >= ?"
|
|
114
|
-
).run(amount, now, owner, amount);
|
|
115
|
-
db.prepare(
|
|
116
|
-
"INSERT INTO credit_escrow (id, owner, amount, card_id, status, created_at) VALUES (?, ?, ?, ?, ?, ?)"
|
|
117
|
-
).run(escrowId, owner, amount, cardId, "held", now);
|
|
118
|
-
db.prepare(
|
|
119
|
-
"INSERT INTO credit_transactions (id, owner, amount, reason, reference_id, created_at) VALUES (?, ?, ?, ?, ?, ?)"
|
|
120
|
-
).run(randomUUID2(), owner, -amount, "escrow_hold", escrowId, now);
|
|
121
201
|
});
|
|
122
202
|
hold();
|
|
123
203
|
return escrowId;
|
|
@@ -125,7 +205,7 @@ function holdEscrow(db, owner, amount, cardId) {
|
|
|
125
205
|
function settleEscrow(db, escrowId, recipientOwner) {
|
|
126
206
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
127
207
|
const settle = db.transaction(() => {
|
|
128
|
-
const escrow = db.prepare("SELECT id, owner, amount, status FROM credit_escrow WHERE id = ?").get(escrowId);
|
|
208
|
+
const escrow = db.prepare("SELECT id, owner, amount, status, funding_source FROM credit_escrow WHERE id = ?").get(escrowId);
|
|
129
209
|
if (!escrow) {
|
|
130
210
|
throw new AgentBnBError(`Escrow not found: ${escrowId}`, "ESCROW_NOT_FOUND");
|
|
131
211
|
}
|
|
@@ -135,25 +215,61 @@ function settleEscrow(db, escrowId, recipientOwner) {
|
|
|
135
215
|
"ESCROW_ALREADY_SETTLED"
|
|
136
216
|
);
|
|
137
217
|
}
|
|
218
|
+
const feeAmount = Math.floor(escrow.amount * NETWORK_FEE_RATE);
|
|
219
|
+
const providerAmount = escrow.amount - feeAmount;
|
|
138
220
|
db.prepare(
|
|
139
221
|
"INSERT OR IGNORE INTO credit_balances (owner, balance, updated_at) VALUES (?, 0, ?)"
|
|
140
222
|
).run(recipientOwner, now);
|
|
141
223
|
db.prepare(
|
|
142
224
|
"UPDATE credit_balances SET balance = balance + ?, updated_at = ? WHERE owner = ?"
|
|
143
|
-
).run(
|
|
225
|
+
).run(providerAmount, now, recipientOwner);
|
|
226
|
+
if (feeAmount > 0) {
|
|
227
|
+
db.prepare(
|
|
228
|
+
"INSERT OR IGNORE INTO credit_balances (owner, balance, updated_at) VALUES (?, 0, ?)"
|
|
229
|
+
).run("platform_treasury", now);
|
|
230
|
+
db.prepare(
|
|
231
|
+
"UPDATE credit_balances SET balance = balance + ?, updated_at = ? WHERE owner = ?"
|
|
232
|
+
).run(feeAmount, now, "platform_treasury");
|
|
233
|
+
db.prepare(
|
|
234
|
+
"INSERT INTO credit_transactions (id, owner, amount, reason, reference_id, created_at) VALUES (?, ?, ?, ?, ?, ?)"
|
|
235
|
+
).run(randomUUID2(), "platform_treasury", feeAmount, "network_fee", escrowId, now);
|
|
236
|
+
}
|
|
144
237
|
db.prepare(
|
|
145
238
|
"UPDATE credit_escrow SET status = ?, settled_at = ? WHERE id = ?"
|
|
146
239
|
).run("settled", now, escrowId);
|
|
147
240
|
db.prepare(
|
|
148
241
|
"INSERT INTO credit_transactions (id, owner, amount, reason, reference_id, created_at) VALUES (?, ?, ?, ?, ?, ?)"
|
|
149
|
-
).run(randomUUID2(), recipientOwner,
|
|
242
|
+
).run(randomUUID2(), recipientOwner, providerAmount, "settlement", escrowId, now);
|
|
243
|
+
let providerNum = getProviderNumber(db, recipientOwner);
|
|
244
|
+
if (providerNum === null) {
|
|
245
|
+
providerNum = registerProvider(db, recipientOwner);
|
|
246
|
+
}
|
|
247
|
+
const bonus = getProviderBonus(providerNum);
|
|
248
|
+
if (bonus > 1) {
|
|
249
|
+
const bonusAmount = Math.floor(providerAmount * (bonus - 1));
|
|
250
|
+
if (bonusAmount > 0) {
|
|
251
|
+
db.prepare(
|
|
252
|
+
"INSERT OR IGNORE INTO credit_balances (owner, balance, updated_at) VALUES (?, 0, ?)"
|
|
253
|
+
).run("platform_treasury", now);
|
|
254
|
+
db.prepare(
|
|
255
|
+
"UPDATE credit_balances SET balance = balance + ?, updated_at = ? WHERE owner = ?"
|
|
256
|
+
).run(bonusAmount, now, recipientOwner);
|
|
257
|
+
db.prepare(
|
|
258
|
+
"INSERT INTO credit_transactions (id, owner, amount, reason, reference_id, created_at) VALUES (?, ?, ?, ?, ?, ?)"
|
|
259
|
+
).run(randomUUID2(), recipientOwner, bonusAmount, "provider_bonus", escrowId, now);
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
try {
|
|
263
|
+
recordSuccessfulHire(db, recipientOwner, escrow.owner);
|
|
264
|
+
} catch {
|
|
265
|
+
}
|
|
150
266
|
});
|
|
151
267
|
settle();
|
|
152
268
|
}
|
|
153
269
|
function releaseEscrow(db, escrowId) {
|
|
154
270
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
155
271
|
const release = db.transaction(() => {
|
|
156
|
-
const escrow = db.prepare("SELECT id, owner, amount, status FROM credit_escrow WHERE id = ?").get(escrowId);
|
|
272
|
+
const escrow = db.prepare("SELECT id, owner, amount, status, funding_source FROM credit_escrow WHERE id = ?").get(escrowId);
|
|
157
273
|
if (!escrow) {
|
|
158
274
|
throw new AgentBnBError(`Escrow not found: ${escrowId}`, "ESCROW_NOT_FOUND");
|
|
159
275
|
}
|
|
@@ -178,7 +294,7 @@ function releaseEscrow(db, escrowId) {
|
|
|
178
294
|
function confirmEscrowDebit(db, escrowId) {
|
|
179
295
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
180
296
|
const confirm = db.transaction(() => {
|
|
181
|
-
const escrow = db.prepare("SELECT id, owner, amount, status FROM credit_escrow WHERE id = ?").get(escrowId);
|
|
297
|
+
const escrow = db.prepare("SELECT id, owner, amount, status, funding_source FROM credit_escrow WHERE id = ?").get(escrowId);
|
|
182
298
|
if (!escrow) {
|
|
183
299
|
throw new AgentBnBError(`Escrow not found: ${escrowId}`, "ESCROW_NOT_FOUND");
|
|
184
300
|
}
|
|
@@ -198,169 +314,16 @@ function confirmEscrowDebit(db, escrowId) {
|
|
|
198
314
|
confirm();
|
|
199
315
|
}
|
|
200
316
|
|
|
201
|
-
// src/credit/signing.ts
|
|
202
|
-
import { generateKeyPairSync, sign, verify, createPublicKey, createPrivateKey } from "crypto";
|
|
203
|
-
import { writeFileSync, readFileSync, existsSync, chmodSync } from "fs";
|
|
204
|
-
import { join } from "path";
|
|
205
|
-
function generateKeyPair() {
|
|
206
|
-
const { publicKey, privateKey } = generateKeyPairSync("ed25519", {
|
|
207
|
-
publicKeyEncoding: { type: "spki", format: "der" },
|
|
208
|
-
privateKeyEncoding: { type: "pkcs8", format: "der" }
|
|
209
|
-
});
|
|
210
|
-
return {
|
|
211
|
-
publicKey: Buffer.from(publicKey),
|
|
212
|
-
privateKey: Buffer.from(privateKey)
|
|
213
|
-
};
|
|
214
|
-
}
|
|
215
|
-
function saveKeyPair(configDir, keys) {
|
|
216
|
-
const privatePath = join(configDir, "private.key");
|
|
217
|
-
const publicPath = join(configDir, "public.key");
|
|
218
|
-
writeFileSync(privatePath, keys.privateKey);
|
|
219
|
-
chmodSync(privatePath, 384);
|
|
220
|
-
writeFileSync(publicPath, keys.publicKey);
|
|
221
|
-
}
|
|
222
|
-
function loadKeyPair(configDir) {
|
|
223
|
-
const privatePath = join(configDir, "private.key");
|
|
224
|
-
const publicPath = join(configDir, "public.key");
|
|
225
|
-
if (!existsSync(privatePath) || !existsSync(publicPath)) {
|
|
226
|
-
throw new AgentBnBError("Keypair not found. Run `agentbnb init` to generate one.", "KEYPAIR_NOT_FOUND");
|
|
227
|
-
}
|
|
228
|
-
return {
|
|
229
|
-
publicKey: readFileSync(publicPath),
|
|
230
|
-
privateKey: readFileSync(privatePath)
|
|
231
|
-
};
|
|
232
|
-
}
|
|
233
|
-
function canonicalJson(data) {
|
|
234
|
-
return JSON.stringify(data, Object.keys(data).sort());
|
|
235
|
-
}
|
|
236
|
-
function signEscrowReceipt(data, privateKey) {
|
|
237
|
-
const message = Buffer.from(canonicalJson(data), "utf-8");
|
|
238
|
-
const keyObject = createPrivateKey({ key: privateKey, format: "der", type: "pkcs8" });
|
|
239
|
-
const signature = sign(null, message, keyObject);
|
|
240
|
-
return signature.toString("base64url");
|
|
241
|
-
}
|
|
242
|
-
function verifyEscrowReceipt(data, signature, publicKey) {
|
|
243
|
-
try {
|
|
244
|
-
const message = Buffer.from(canonicalJson(data), "utf-8");
|
|
245
|
-
const keyObject = createPublicKey({ key: publicKey, format: "der", type: "spki" });
|
|
246
|
-
const sigBuffer = Buffer.from(signature, "base64url");
|
|
247
|
-
return verify(null, message, keyObject, sigBuffer);
|
|
248
|
-
} catch {
|
|
249
|
-
return false;
|
|
250
|
-
}
|
|
251
|
-
}
|
|
252
|
-
|
|
253
|
-
// src/feedback/store.ts
|
|
254
|
-
import { randomUUID as randomUUID3 } from "crypto";
|
|
255
|
-
function initFeedbackTable(db) {
|
|
256
|
-
db.exec(`
|
|
257
|
-
CREATE TABLE IF NOT EXISTS feedback (
|
|
258
|
-
id TEXT PRIMARY KEY,
|
|
259
|
-
transaction_id TEXT NOT NULL,
|
|
260
|
-
provider_agent TEXT NOT NULL,
|
|
261
|
-
skill_id TEXT NOT NULL,
|
|
262
|
-
requester_agent TEXT NOT NULL,
|
|
263
|
-
rating INTEGER NOT NULL,
|
|
264
|
-
latency_ms INTEGER NOT NULL,
|
|
265
|
-
result_quality TEXT NOT NULL,
|
|
266
|
-
quality_details TEXT,
|
|
267
|
-
would_reuse INTEGER NOT NULL,
|
|
268
|
-
cost_value_ratio TEXT NOT NULL,
|
|
269
|
-
timestamp TEXT NOT NULL,
|
|
270
|
-
created_at TEXT NOT NULL DEFAULT (datetime('now'))
|
|
271
|
-
);
|
|
272
|
-
|
|
273
|
-
CREATE INDEX IF NOT EXISTS feedback_provider_idx ON feedback(provider_agent);
|
|
274
|
-
CREATE INDEX IF NOT EXISTS feedback_skill_idx ON feedback(skill_id);
|
|
275
|
-
`);
|
|
276
|
-
}
|
|
277
|
-
function insertFeedback(db, feedback) {
|
|
278
|
-
const id = randomUUID3();
|
|
279
|
-
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
280
|
-
db.prepare(`
|
|
281
|
-
INSERT INTO feedback (
|
|
282
|
-
id, transaction_id, provider_agent, skill_id, requester_agent,
|
|
283
|
-
rating, latency_ms, result_quality, quality_details,
|
|
284
|
-
would_reuse, cost_value_ratio, timestamp, created_at
|
|
285
|
-
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
286
|
-
`).run(
|
|
287
|
-
id,
|
|
288
|
-
feedback.transaction_id,
|
|
289
|
-
feedback.provider_agent,
|
|
290
|
-
feedback.skill_id,
|
|
291
|
-
feedback.requester_agent,
|
|
292
|
-
feedback.rating,
|
|
293
|
-
feedback.latency_ms,
|
|
294
|
-
feedback.result_quality,
|
|
295
|
-
feedback.quality_details ?? null,
|
|
296
|
-
feedback.would_reuse ? 1 : 0,
|
|
297
|
-
feedback.cost_value_ratio,
|
|
298
|
-
feedback.timestamp,
|
|
299
|
-
now
|
|
300
|
-
);
|
|
301
|
-
return id;
|
|
302
|
-
}
|
|
303
|
-
function getFeedbackForSkill(db, skillId, limit = 20) {
|
|
304
|
-
const rows = db.prepare(`
|
|
305
|
-
SELECT * FROM feedback
|
|
306
|
-
WHERE skill_id = ?
|
|
307
|
-
ORDER BY timestamp DESC
|
|
308
|
-
LIMIT ?
|
|
309
|
-
`).all(skillId, limit);
|
|
310
|
-
return rows.map(rowToFeedback);
|
|
311
|
-
}
|
|
312
|
-
function getFeedbackForProvider(db, providerAgent, sinceDays) {
|
|
313
|
-
let rows;
|
|
314
|
-
if (sinceDays !== void 0) {
|
|
315
|
-
rows = db.prepare(`
|
|
316
|
-
SELECT * FROM feedback
|
|
317
|
-
WHERE provider_agent = ?
|
|
318
|
-
AND timestamp >= datetime('now', ? || ' days')
|
|
319
|
-
ORDER BY timestamp DESC
|
|
320
|
-
`).all(providerAgent, `-${sinceDays}`);
|
|
321
|
-
} else {
|
|
322
|
-
rows = db.prepare(`
|
|
323
|
-
SELECT * FROM feedback
|
|
324
|
-
WHERE provider_agent = ?
|
|
325
|
-
ORDER BY timestamp DESC
|
|
326
|
-
`).all(providerAgent);
|
|
327
|
-
}
|
|
328
|
-
return rows.map(rowToFeedback);
|
|
329
|
-
}
|
|
330
|
-
function rowToFeedback(row) {
|
|
331
|
-
return {
|
|
332
|
-
transaction_id: row["transaction_id"],
|
|
333
|
-
provider_agent: row["provider_agent"],
|
|
334
|
-
skill_id: row["skill_id"],
|
|
335
|
-
requester_agent: row["requester_agent"],
|
|
336
|
-
rating: row["rating"],
|
|
337
|
-
latency_ms: row["latency_ms"],
|
|
338
|
-
result_quality: row["result_quality"],
|
|
339
|
-
quality_details: row["quality_details"] ?? void 0,
|
|
340
|
-
would_reuse: row["would_reuse"] === 1,
|
|
341
|
-
cost_value_ratio: row["cost_value_ratio"],
|
|
342
|
-
timestamp: row["timestamp"]
|
|
343
|
-
};
|
|
344
|
-
}
|
|
345
|
-
|
|
346
317
|
export {
|
|
347
|
-
initFeedbackTable,
|
|
348
|
-
insertFeedback,
|
|
349
|
-
getFeedbackForSkill,
|
|
350
|
-
getFeedbackForProvider,
|
|
351
318
|
openCreditDb,
|
|
352
319
|
bootstrapAgent,
|
|
353
320
|
getBalance,
|
|
354
321
|
getTransactions,
|
|
355
322
|
recordEarning,
|
|
356
323
|
migrateOwner,
|
|
324
|
+
NETWORK_FEE_RATE,
|
|
357
325
|
holdEscrow,
|
|
358
326
|
settleEscrow,
|
|
359
327
|
releaseEscrow,
|
|
360
|
-
confirmEscrowDebit
|
|
361
|
-
generateKeyPair,
|
|
362
|
-
saveKeyPair,
|
|
363
|
-
loadKeyPair,
|
|
364
|
-
signEscrowReceipt,
|
|
365
|
-
verifyEscrowReceipt
|
|
328
|
+
confirmEscrowDebit
|
|
366
329
|
};
|