@elisym/sdk 0.11.0 → 0.12.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/dist/agent-store.cjs.map +1 -1
- package/dist/agent-store.js.map +1 -1
- package/dist/index.cjs +247 -83
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +47 -24
- package/dist/index.d.ts +47 -24
- package/dist/index.js +248 -82
- package/dist/index.js.map +1 -1
- package/dist/skills.cjs.map +1 -1
- package/dist/skills.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -62,8 +62,6 @@ function jobResultKind(offset) {
|
|
|
62
62
|
var KIND_PING = 20200;
|
|
63
63
|
var KIND_PONG = 20201;
|
|
64
64
|
var LAMPORTS_PER_SOL = 1e9;
|
|
65
|
-
var PROTOCOL_FEE_BPS = 300;
|
|
66
|
-
var PROTOCOL_TREASURY = "GY7vnWMkKpftU4nQ16C2ATkj1JwrQpHhknkaBUn67VTy";
|
|
67
65
|
var PROTOCOL_PROGRAM_ID_DEVNET = "BrX1CRkSgvcjxBvc2bgc3QqgWjinusofDmeP7ZVxvwrE";
|
|
68
66
|
var ELISYM_PROTOCOL_TAG = "ELiZksgwDt41LaeuPDLkUfWgFXhGgVayTMP7L5nTSEL8";
|
|
69
67
|
function getProtocolProgramId(cluster) {
|
|
@@ -1032,6 +1030,7 @@ async function createPaymentRequestWithOnchainConfig(rpc, programId, recipient,
|
|
|
1032
1030
|
var RANKING_ACTIVITY_WINDOW_SECS = 30 * 24 * 60 * 60;
|
|
1033
1031
|
var RANKING_BUCKET_SIZE_SECS = 60;
|
|
1034
1032
|
var COLD_START_BUCKET = -Infinity;
|
|
1033
|
+
var NEVER_ABORTED_SIGNAL = new AbortController().signal;
|
|
1035
1034
|
function toDTag(name) {
|
|
1036
1035
|
const tag = name.toLowerCase().replace(/[^a-z0-9\s-]/g, (ch) => "_" + ch.charCodeAt(0).toString(16).padStart(2, "0")).replace(/\s+/g, "-").replace(/^-+|-+$/g, "");
|
|
1037
1036
|
if (!tag) {
|
|
@@ -1061,13 +1060,63 @@ function compareAgentsByRank(a, b) {
|
|
|
1061
1060
|
}
|
|
1062
1061
|
return kb.lastSeen - ka.lastSeen;
|
|
1063
1062
|
}
|
|
1063
|
+
function parseCapabilityEvent(event, network) {
|
|
1064
|
+
if (!nostrTools.verifyEvent(event)) {
|
|
1065
|
+
return null;
|
|
1066
|
+
}
|
|
1067
|
+
if (!event.content) {
|
|
1068
|
+
return null;
|
|
1069
|
+
}
|
|
1070
|
+
let raw;
|
|
1071
|
+
try {
|
|
1072
|
+
raw = JSON.parse(event.content);
|
|
1073
|
+
} catch {
|
|
1074
|
+
return null;
|
|
1075
|
+
}
|
|
1076
|
+
if (!raw || typeof raw !== "object") {
|
|
1077
|
+
return null;
|
|
1078
|
+
}
|
|
1079
|
+
const candidate = raw;
|
|
1080
|
+
if (typeof candidate.name !== "string" || !candidate.name) {
|
|
1081
|
+
return null;
|
|
1082
|
+
}
|
|
1083
|
+
if (typeof candidate.description !== "string") {
|
|
1084
|
+
return null;
|
|
1085
|
+
}
|
|
1086
|
+
if (!Array.isArray(candidate.capabilities) || !candidate.capabilities.every((cap) => typeof cap === "string")) {
|
|
1087
|
+
return null;
|
|
1088
|
+
}
|
|
1089
|
+
if (candidate.deleted) {
|
|
1090
|
+
return null;
|
|
1091
|
+
}
|
|
1092
|
+
const card = candidate;
|
|
1093
|
+
if (card.payment && (typeof card.payment.chain !== "string" || typeof card.payment.network !== "string" || typeof card.payment.address !== "string")) {
|
|
1094
|
+
return null;
|
|
1095
|
+
}
|
|
1096
|
+
if (card.payment?.job_price !== null && card.payment?.job_price !== void 0 && (!Number.isInteger(card.payment.job_price) || card.payment.job_price < 0)) {
|
|
1097
|
+
return null;
|
|
1098
|
+
}
|
|
1099
|
+
const agentNetwork = card.payment?.network ?? "devnet";
|
|
1100
|
+
if (agentNetwork !== network) {
|
|
1101
|
+
return null;
|
|
1102
|
+
}
|
|
1103
|
+
const kTags = event.tags.filter((tag) => tag[0] === "k").map((tag) => parseInt(tag[1] ?? "", 10)).filter((kind) => !isNaN(kind));
|
|
1104
|
+
return {
|
|
1105
|
+
pubkey: event.pubkey,
|
|
1106
|
+
npub: nostrTools.nip19.npubEncode(event.pubkey),
|
|
1107
|
+
cards: [card],
|
|
1108
|
+
eventId: event.id,
|
|
1109
|
+
supportedKinds: kTags,
|
|
1110
|
+
lastSeen: event.created_at
|
|
1111
|
+
};
|
|
1112
|
+
}
|
|
1064
1113
|
function buildAgentsFromEvents(events, network) {
|
|
1065
1114
|
const latestByDTag = /* @__PURE__ */ new Map();
|
|
1066
1115
|
for (const event of events) {
|
|
1067
1116
|
if (!nostrTools.verifyEvent(event)) {
|
|
1068
1117
|
continue;
|
|
1069
1118
|
}
|
|
1070
|
-
const dTag = event.tags.find((
|
|
1119
|
+
const dTag = event.tags.find((tag) => tag[0] === "d")?.[1] ?? "";
|
|
1071
1120
|
const key = `${event.pubkey}:${dTag}`;
|
|
1072
1121
|
const prev = latestByDTag.get(key);
|
|
1073
1122
|
if (!prev || event.created_at > prev.created_at) {
|
|
@@ -1076,82 +1125,51 @@ function buildAgentsFromEvents(events, network) {
|
|
|
1076
1125
|
}
|
|
1077
1126
|
const accumMap = /* @__PURE__ */ new Map();
|
|
1078
1127
|
for (const event of latestByDTag.values()) {
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
if (raw.deleted) {
|
|
1097
|
-
continue;
|
|
1098
|
-
}
|
|
1099
|
-
const card = raw;
|
|
1100
|
-
if (card.payment && (typeof card.payment.chain !== "string" || typeof card.payment.network !== "string" || typeof card.payment.address !== "string")) {
|
|
1101
|
-
continue;
|
|
1102
|
-
}
|
|
1103
|
-
if (card.payment?.job_price !== null && card.payment?.job_price !== void 0 && (!Number.isInteger(card.payment.job_price) || card.payment.job_price < 0)) {
|
|
1104
|
-
continue;
|
|
1105
|
-
}
|
|
1106
|
-
const agentNetwork = card.payment?.network ?? "devnet";
|
|
1107
|
-
if (agentNetwork !== network) {
|
|
1108
|
-
continue;
|
|
1109
|
-
}
|
|
1110
|
-
const kTags = event.tags.filter((t) => t[0] === "k").map((t) => parseInt(t[1] ?? "", 10)).filter((k) => !isNaN(k));
|
|
1111
|
-
const entry = { card, kTags, createdAt: event.created_at };
|
|
1112
|
-
const existing = accumMap.get(event.pubkey);
|
|
1113
|
-
if (existing) {
|
|
1114
|
-
const dupIndex = existing.entries.findIndex((e) => e.card.name === card.name);
|
|
1115
|
-
if (dupIndex >= 0) {
|
|
1116
|
-
if (entry.createdAt >= existing.entries[dupIndex].createdAt) {
|
|
1117
|
-
existing.entries[dupIndex] = entry;
|
|
1128
|
+
const parsed = parseCapabilityEvent(event, network);
|
|
1129
|
+
if (!parsed) {
|
|
1130
|
+
continue;
|
|
1131
|
+
}
|
|
1132
|
+
const card = parsed.cards[0];
|
|
1133
|
+
const cardKinds = parsed.supportedKinds;
|
|
1134
|
+
const createdAt = parsed.lastSeen;
|
|
1135
|
+
const existing = accumMap.get(parsed.pubkey);
|
|
1136
|
+
if (existing) {
|
|
1137
|
+
const prevForName = existing.perCard.get(card.name);
|
|
1138
|
+
if (prevForName) {
|
|
1139
|
+
if (createdAt >= prevForName.createdAt) {
|
|
1140
|
+
const idx = existing.agent.cards.findIndex(
|
|
1141
|
+
(existingCard) => existingCard.name === card.name
|
|
1142
|
+
);
|
|
1143
|
+
if (idx >= 0) {
|
|
1144
|
+
existing.agent.cards[idx] = card;
|
|
1118
1145
|
}
|
|
1119
|
-
|
|
1120
|
-
existing.entries.push(entry);
|
|
1121
|
-
}
|
|
1122
|
-
if (event.created_at > existing.lastSeen) {
|
|
1123
|
-
existing.lastSeen = event.created_at;
|
|
1124
|
-
existing.eventId = event.id;
|
|
1146
|
+
existing.perCard.set(card.name, { createdAt, kTags: cardKinds });
|
|
1125
1147
|
}
|
|
1126
1148
|
} else {
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
npub: nostrTools.nip19.npubEncode(event.pubkey),
|
|
1130
|
-
entries: [entry],
|
|
1131
|
-
eventId: event.id,
|
|
1132
|
-
lastSeen: event.created_at
|
|
1133
|
-
});
|
|
1149
|
+
existing.agent.cards.push(card);
|
|
1150
|
+
existing.perCard.set(card.name, { createdAt, kTags: cardKinds });
|
|
1134
1151
|
}
|
|
1135
|
-
|
|
1152
|
+
if (createdAt > existing.agent.lastSeen) {
|
|
1153
|
+
existing.agent.lastSeen = createdAt;
|
|
1154
|
+
existing.agent.eventId = parsed.eventId;
|
|
1155
|
+
}
|
|
1156
|
+
} else {
|
|
1157
|
+
accumMap.set(parsed.pubkey, {
|
|
1158
|
+
agent: parsed,
|
|
1159
|
+
perCard: /* @__PURE__ */ new Map([[card.name, { createdAt, kTags: cardKinds }]])
|
|
1160
|
+
});
|
|
1136
1161
|
}
|
|
1137
1162
|
}
|
|
1138
1163
|
const agentMap = /* @__PURE__ */ new Map();
|
|
1139
1164
|
for (const [pubkey, acc] of accumMap) {
|
|
1140
1165
|
const kindsSet = /* @__PURE__ */ new Set();
|
|
1141
|
-
for (const
|
|
1142
|
-
for (const
|
|
1143
|
-
kindsSet.add(
|
|
1144
|
-
}
|
|
1145
|
-
}
|
|
1146
|
-
|
|
1147
|
-
agentMap.set(pubkey,
|
|
1148
|
-
pubkey: acc.pubkey,
|
|
1149
|
-
npub: acc.npub,
|
|
1150
|
-
cards: acc.entries.map((e) => e.card),
|
|
1151
|
-
eventId: acc.eventId,
|
|
1152
|
-
supportedKinds,
|
|
1153
|
-
lastSeen: acc.lastSeen
|
|
1154
|
-
});
|
|
1166
|
+
for (const { kTags } of acc.perCard.values()) {
|
|
1167
|
+
for (const kind of kTags) {
|
|
1168
|
+
kindsSet.add(kind);
|
|
1169
|
+
}
|
|
1170
|
+
}
|
|
1171
|
+
acc.agent.supportedKinds = [...kindsSet];
|
|
1172
|
+
agentMap.set(pubkey, acc.agent);
|
|
1155
1173
|
}
|
|
1156
1174
|
return agentMap;
|
|
1157
1175
|
}
|
|
@@ -1266,6 +1284,19 @@ var DiscoveryService = class {
|
|
|
1266
1284
|
const events = await this.pool.querySync(filter);
|
|
1267
1285
|
const agentMap = buildAgentsFromEvents(events, network);
|
|
1268
1286
|
const agents = Array.from(agentMap.values());
|
|
1287
|
+
return this.runEnrichment(agents, agentMap, NEVER_ABORTED_SIGNAL);
|
|
1288
|
+
}
|
|
1289
|
+
/**
|
|
1290
|
+
* Enrich an agent map with paid-job stats, feedback counters, and kind:0
|
|
1291
|
+
* metadata, then return them sorted by `compareAgentsByRank`. Mutates the
|
|
1292
|
+
* passed-in `Agent` objects in place.
|
|
1293
|
+
*
|
|
1294
|
+
* Shared between `fetchAgents` (one-shot) and `streamAgents` (post-EOSE
|
|
1295
|
+
* second pass). The `signal` short-circuits the post-query work; in-flight
|
|
1296
|
+
* pool queries are not cancellable today (they fall through to the standard
|
|
1297
|
+
* timeout) and the caller drops the resolved value.
|
|
1298
|
+
*/
|
|
1299
|
+
async runEnrichment(agents, agentMap, signal) {
|
|
1269
1300
|
const agentPubkeys = Array.from(agentMap.keys());
|
|
1270
1301
|
if (agentPubkeys.length === 0) {
|
|
1271
1302
|
return agents;
|
|
@@ -1273,9 +1304,9 @@ var DiscoveryService = class {
|
|
|
1273
1304
|
const activitySince = Math.floor(Date.now() / 1e3) - RANKING_ACTIVITY_WINDOW_SECS;
|
|
1274
1305
|
const resultKinds = /* @__PURE__ */ new Set();
|
|
1275
1306
|
for (const agent of agentMap.values()) {
|
|
1276
|
-
for (const
|
|
1277
|
-
if (
|
|
1278
|
-
resultKinds.add(KIND_JOB_RESULT_BASE + (
|
|
1307
|
+
for (const supportedKind of agent.supportedKinds) {
|
|
1308
|
+
if (supportedKind >= KIND_JOB_REQUEST_BASE && supportedKind < KIND_JOB_RESULT_BASE) {
|
|
1309
|
+
resultKinds.add(KIND_JOB_RESULT_BASE + (supportedKind - KIND_JOB_REQUEST_BASE));
|
|
1279
1310
|
}
|
|
1280
1311
|
}
|
|
1281
1312
|
}
|
|
@@ -1295,6 +1326,9 @@ var DiscoveryService = class {
|
|
|
1295
1326
|
),
|
|
1296
1327
|
this.enrichWithMetadata(agents)
|
|
1297
1328
|
]);
|
|
1329
|
+
if (signal.aborted) {
|
|
1330
|
+
return agents;
|
|
1331
|
+
}
|
|
1298
1332
|
const deliveredJobsByProvider = /* @__PURE__ */ new Map();
|
|
1299
1333
|
for (const ev of resultEvents) {
|
|
1300
1334
|
if (!nostrTools.verifyEvent(ev)) {
|
|
@@ -1307,7 +1341,7 @@ var DiscoveryService = class {
|
|
|
1307
1341
|
if (ev.created_at > agent.lastSeen) {
|
|
1308
1342
|
agent.lastSeen = ev.created_at;
|
|
1309
1343
|
}
|
|
1310
|
-
const jobEventId = ev.tags.find((
|
|
1344
|
+
const jobEventId = ev.tags.find((tag) => tag[0] === "e")?.[1];
|
|
1311
1345
|
if (jobEventId) {
|
|
1312
1346
|
let delivered = deliveredJobsByProvider.get(ev.pubkey);
|
|
1313
1347
|
if (!delivered) {
|
|
@@ -1321,7 +1355,7 @@ var DiscoveryService = class {
|
|
|
1321
1355
|
if (!nostrTools.verifyEvent(ev)) {
|
|
1322
1356
|
continue;
|
|
1323
1357
|
}
|
|
1324
|
-
const targetPubkey = ev.tags.find((
|
|
1358
|
+
const targetPubkey = ev.tags.find((tag) => tag[0] === "p")?.[1];
|
|
1325
1359
|
if (!targetPubkey) {
|
|
1326
1360
|
continue;
|
|
1327
1361
|
}
|
|
@@ -1332,17 +1366,17 @@ var DiscoveryService = class {
|
|
|
1332
1366
|
if (ev.created_at > agent.lastSeen) {
|
|
1333
1367
|
agent.lastSeen = ev.created_at;
|
|
1334
1368
|
}
|
|
1335
|
-
const rating = ev.tags.find((
|
|
1369
|
+
const rating = ev.tags.find((tag) => tag[0] === "rating")?.[1];
|
|
1336
1370
|
if (rating === "1" || rating === "0") {
|
|
1337
1371
|
agent.totalRatingCount = (agent.totalRatingCount ?? 0) + 1;
|
|
1338
1372
|
if (rating === "1") {
|
|
1339
1373
|
agent.positiveCount = (agent.positiveCount ?? 0) + 1;
|
|
1340
1374
|
}
|
|
1341
1375
|
}
|
|
1342
|
-
const status = ev.tags.find((
|
|
1343
|
-
const txTag = ev.tags.find((
|
|
1376
|
+
const status = ev.tags.find((tag) => tag[0] === "status")?.[1];
|
|
1377
|
+
const txTag = ev.tags.find((tag) => tag[0] === "tx");
|
|
1344
1378
|
const txSignature = txTag?.[1];
|
|
1345
|
-
const jobEventId = ev.tags.find((
|
|
1379
|
+
const jobEventId = ev.tags.find((tag) => tag[0] === "e")?.[1];
|
|
1346
1380
|
const hasDeliveredResult = jobEventId !== void 0 && deliveredJobsByProvider.get(targetPubkey)?.has(jobEventId) === true;
|
|
1347
1381
|
if (status === "payment-completed" && typeof txSignature === "string" && txSignature && hasDeliveredResult) {
|
|
1348
1382
|
if (!agent.lastPaidJobAt || ev.created_at > agent.lastPaidJobAt) {
|
|
@@ -1354,6 +1388,135 @@ var DiscoveryService = class {
|
|
|
1354
1388
|
agents.sort(compareAgentsByRank);
|
|
1355
1389
|
return agents;
|
|
1356
1390
|
}
|
|
1391
|
+
/**
|
|
1392
|
+
* Stream elisym agents progressively as relays deliver events.
|
|
1393
|
+
*
|
|
1394
|
+
* Two live subscriptions:
|
|
1395
|
+
* - kind:31990 (capability cards) - emits `onAgent(agent)` for every new or
|
|
1396
|
+
* updated `(pubkey, d-tag)`. The emitted Agent is the merged view across
|
|
1397
|
+
* all surviving cards for that author.
|
|
1398
|
+
* - kind:6100 (default-offset job results) tagged `t=elisym` since 30d ago -
|
|
1399
|
+
* emits `onPaidJob(pubkey, ts)` for each delivered result. Custom-kind
|
|
1400
|
+
* results (offset != 100) are not on this stream; they enter the final
|
|
1401
|
+
* ranking via the post-EOSE enrichment pass.
|
|
1402
|
+
*
|
|
1403
|
+
* After capabilities EOSE, an enrichment pass runs in parallel to the live
|
|
1404
|
+
* subscriptions and produces a ranked snapshot via `onComplete`. The snapshot
|
|
1405
|
+
* is a clone, so further live updates do not mutate it.
|
|
1406
|
+
*
|
|
1407
|
+
* `closer.close()` tears down both subscriptions and aborts an in-flight
|
|
1408
|
+
* enrichment. If `opts.signal` is provided, aborting it does the same.
|
|
1409
|
+
*/
|
|
1410
|
+
streamAgents(network, opts) {
|
|
1411
|
+
const eventsByPubkey = /* @__PURE__ */ new Map();
|
|
1412
|
+
const agentByPubkey = /* @__PURE__ */ new Map();
|
|
1413
|
+
const eoseSeen = { caps: false, results: false };
|
|
1414
|
+
let enrichmentStarted = false;
|
|
1415
|
+
const enrichmentAbort = new AbortController();
|
|
1416
|
+
const onExternalAbort = () => enrichmentAbort.abort();
|
|
1417
|
+
if (opts.signal) {
|
|
1418
|
+
if (opts.signal.aborted) {
|
|
1419
|
+
enrichmentAbort.abort();
|
|
1420
|
+
} else {
|
|
1421
|
+
opts.signal.addEventListener("abort", onExternalAbort, { once: true });
|
|
1422
|
+
}
|
|
1423
|
+
}
|
|
1424
|
+
const checkEose = () => {
|
|
1425
|
+
if (eoseSeen.caps && eoseSeen.results) {
|
|
1426
|
+
opts.onEose?.();
|
|
1427
|
+
}
|
|
1428
|
+
};
|
|
1429
|
+
const startEnrichment = () => {
|
|
1430
|
+
if (enrichmentStarted) {
|
|
1431
|
+
return;
|
|
1432
|
+
}
|
|
1433
|
+
enrichmentStarted = true;
|
|
1434
|
+
const snapshotAgents = Array.from(agentByPubkey.values()).map((agent) => ({ ...agent }));
|
|
1435
|
+
const snapshotMap = new Map(snapshotAgents.map((agent) => [agent.pubkey, agent]));
|
|
1436
|
+
void this.runEnrichment(snapshotAgents, snapshotMap, enrichmentAbort.signal).then(
|
|
1437
|
+
(sorted) => {
|
|
1438
|
+
if (enrichmentAbort.signal.aborted) {
|
|
1439
|
+
return;
|
|
1440
|
+
}
|
|
1441
|
+
opts.onComplete?.(sorted);
|
|
1442
|
+
},
|
|
1443
|
+
() => {
|
|
1444
|
+
}
|
|
1445
|
+
);
|
|
1446
|
+
};
|
|
1447
|
+
const capSub = this.pool.subscribe(
|
|
1448
|
+
{ kinds: [KIND_APP_HANDLER], "#t": ["elisym"] },
|
|
1449
|
+
(event) => {
|
|
1450
|
+
const dTag = event.tags.find((tag) => tag[0] === "d")?.[1] ?? "";
|
|
1451
|
+
let perDTag = eventsByPubkey.get(event.pubkey);
|
|
1452
|
+
const prev = perDTag?.get(dTag);
|
|
1453
|
+
if (prev && event.created_at <= prev.created_at) {
|
|
1454
|
+
return;
|
|
1455
|
+
}
|
|
1456
|
+
if (!nostrTools.verifyEvent(event)) {
|
|
1457
|
+
return;
|
|
1458
|
+
}
|
|
1459
|
+
if (!event.content) {
|
|
1460
|
+
return;
|
|
1461
|
+
}
|
|
1462
|
+
let payload;
|
|
1463
|
+
try {
|
|
1464
|
+
payload = JSON.parse(event.content);
|
|
1465
|
+
} catch {
|
|
1466
|
+
return;
|
|
1467
|
+
}
|
|
1468
|
+
const isTombstone = payload !== null && typeof payload === "object" && Boolean(payload.deleted);
|
|
1469
|
+
if (!isTombstone && !parseCapabilityEvent(event, network)) {
|
|
1470
|
+
return;
|
|
1471
|
+
}
|
|
1472
|
+
if (!perDTag) {
|
|
1473
|
+
perDTag = /* @__PURE__ */ new Map();
|
|
1474
|
+
eventsByPubkey.set(event.pubkey, perDTag);
|
|
1475
|
+
}
|
|
1476
|
+
perDTag.set(dTag, event);
|
|
1477
|
+
const merged = buildAgentsFromEvents(Array.from(perDTag.values()), network).get(
|
|
1478
|
+
event.pubkey
|
|
1479
|
+
);
|
|
1480
|
+
if (!merged) {
|
|
1481
|
+
agentByPubkey.delete(event.pubkey);
|
|
1482
|
+
return;
|
|
1483
|
+
}
|
|
1484
|
+
agentByPubkey.set(event.pubkey, merged);
|
|
1485
|
+
opts.onAgent(merged);
|
|
1486
|
+
},
|
|
1487
|
+
{
|
|
1488
|
+
oneose: () => {
|
|
1489
|
+
eoseSeen.caps = true;
|
|
1490
|
+
startEnrichment();
|
|
1491
|
+
checkEose();
|
|
1492
|
+
}
|
|
1493
|
+
}
|
|
1494
|
+
);
|
|
1495
|
+
const activitySince = Math.floor(Date.now() / 1e3) - RANKING_ACTIVITY_WINDOW_SECS;
|
|
1496
|
+
const resultsSub = this.pool.subscribe(
|
|
1497
|
+
{ kinds: [KIND_JOB_RESULT], "#t": ["elisym"], since: activitySince },
|
|
1498
|
+
(event) => {
|
|
1499
|
+
if (!nostrTools.verifyEvent(event)) {
|
|
1500
|
+
return;
|
|
1501
|
+
}
|
|
1502
|
+
opts.onPaidJob?.(event.pubkey, event.created_at);
|
|
1503
|
+
},
|
|
1504
|
+
{
|
|
1505
|
+
oneose: () => {
|
|
1506
|
+
eoseSeen.results = true;
|
|
1507
|
+
checkEose();
|
|
1508
|
+
}
|
|
1509
|
+
}
|
|
1510
|
+
);
|
|
1511
|
+
return {
|
|
1512
|
+
close: (reason) => {
|
|
1513
|
+
capSub.close(reason);
|
|
1514
|
+
resultsSub.close(reason);
|
|
1515
|
+
enrichmentAbort.abort();
|
|
1516
|
+
opts.signal?.removeEventListener("abort", onExternalAbort);
|
|
1517
|
+
}
|
|
1518
|
+
};
|
|
1519
|
+
}
|
|
1357
1520
|
/**
|
|
1358
1521
|
* Publish a capability card (kind:31990) as a provider.
|
|
1359
1522
|
* Solana address is validated for Base58 format only - full decode
|
|
@@ -2569,8 +2732,11 @@ var NostrPool = class {
|
|
|
2569
2732
|
throw new Error(`Failed to publish to all ${this.relays.length} relays`);
|
|
2570
2733
|
}
|
|
2571
2734
|
}
|
|
2572
|
-
subscribe(filter, onEvent) {
|
|
2573
|
-
const rawSub = this.pool.subscribeMany(this.relays, filter, {
|
|
2735
|
+
subscribe(filter, onEvent, opts) {
|
|
2736
|
+
const rawSub = this.pool.subscribeMany(this.relays, filter, {
|
|
2737
|
+
onevent: onEvent,
|
|
2738
|
+
oneose: opts?.oneose
|
|
2739
|
+
});
|
|
2574
2740
|
const tracked = {
|
|
2575
2741
|
close: (reason) => {
|
|
2576
2742
|
this.activeSubscriptions.delete(tracked);
|
|
@@ -3223,9 +3389,7 @@ exports.MarketplaceService = MarketplaceService;
|
|
|
3223
3389
|
exports.MediaService = MediaService;
|
|
3224
3390
|
exports.NATIVE_SOL = NATIVE_SOL;
|
|
3225
3391
|
exports.NostrPool = NostrPool;
|
|
3226
|
-
exports.PROTOCOL_FEE_BPS = PROTOCOL_FEE_BPS;
|
|
3227
3392
|
exports.PROTOCOL_PROGRAM_ID_DEVNET = PROTOCOL_PROGRAM_ID_DEVNET;
|
|
3228
|
-
exports.PROTOCOL_TREASURY = PROTOCOL_TREASURY;
|
|
3229
3393
|
exports.PaymentRequestSchema = PaymentRequestSchema;
|
|
3230
3394
|
exports.PingService = PingService;
|
|
3231
3395
|
exports.RELAYS = RELAYS;
|