@elisym/sdk 0.22.0 → 0.24.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/agent-store.cjs +22 -0
- package/dist/agent-store.cjs.map +1 -1
- package/dist/agent-store.d.cts +9 -1
- package/dist/agent-store.d.ts +9 -1
- package/dist/agent-store.js +23 -2
- package/dist/agent-store.js.map +1 -1
- package/dist/{global-schema-CddHP2nk.d.cts → global-schema-BsVFDtkt.d.cts} +8 -8
- package/dist/{global-schema-CddHP2nk.d.ts → global-schema-BsVFDtkt.d.ts} +8 -8
- package/dist/index.cjs +177 -27
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +223 -8
- package/dist/index.d.ts +223 -8
- package/dist/index.js +174 -28
- package/dist/index.js.map +1 -1
- package/dist/llm-health.cjs +11 -0
- package/dist/llm-health.cjs.map +1 -1
- package/dist/llm-health.d.cts +2 -2
- package/dist/llm-health.d.ts +2 -2
- package/dist/llm-health.js +11 -1
- package/dist/llm-health.js.map +1 -1
- package/dist/node.cjs +181 -1
- package/dist/node.cjs.map +1 -1
- package/dist/node.d.cts +47 -2
- package/dist/node.d.ts +47 -2
- package/dist/node.js +181 -2
- package/dist/node.js.map +1 -1
- package/dist/skills.cjs +183 -38
- package/dist/skills.cjs.map +1 -1
- package/dist/skills.d.cts +49 -1
- package/dist/skills.d.ts +49 -1
- package/dist/skills.js +185 -40
- package/dist/skills.js.map +1 -1
- package/dist/{types-COvV499T.d.cts → types-Cdscy9kY.d.cts} +13 -1
- package/dist/{types-COvV499T.d.ts → types-Cdscy9kY.d.ts} +13 -1
- package/package.json +4 -1
package/dist/index.js
CHANGED
|
@@ -68,10 +68,35 @@ var DEFAULTS = {
|
|
|
68
68
|
RESULT_RETRY_COUNT: 3,
|
|
69
69
|
RESULT_RETRY_BASE_MS: 1e3,
|
|
70
70
|
QUERY_MAX_CONCURRENCY: 6,
|
|
71
|
-
VERIFY_SIGNATURE_LIMIT: 25
|
|
71
|
+
VERIFY_SIGNATURE_LIMIT: 25,
|
|
72
|
+
// Default ceiling for a single iroh file transfer (seed/fetch). A tunable
|
|
73
|
+
// default, not a protocol constant - the transfer is resumable and its own
|
|
74
|
+
// budget, decoupled from the result-wait window.
|
|
75
|
+
IROH_FETCH_TIMEOUT_MS: 3e5
|
|
72
76
|
};
|
|
73
77
|
var LIMITS = {
|
|
74
78
|
MAX_INPUT_LENGTH: 1e5,
|
|
79
|
+
// NIP-44 v2 hard cap on encrypted plaintext: the pad() length prefix is a u16,
|
|
80
|
+
// so the plaintext can be at most 65_535 BYTES (not chars). Encrypting anything
|
|
81
|
+
// larger throws `invalid plaintext size` inside nip44Encrypt. This is the binding
|
|
82
|
+
// limit for TARGETED (encrypted) jobs - lower than every relay's NIP-11 cap.
|
|
83
|
+
NIP44_MAX_PLAINTEXT_BYTES: 65535,
|
|
84
|
+
// Spill threshold for encrypted content: above this many UTF-8 bytes, callers
|
|
85
|
+
// route the text through iroh out-of-band instead of inlining it. A non-spilled
|
|
86
|
+
// job is encrypted RAW (no envelope - see marketplace.submitJobRequest), so a
|
|
87
|
+
// 60_000-byte input is a 60_000-byte plaintext; the ~5.5KB gap under the hard cap
|
|
88
|
+
// is plain slack, and NIP44_MAX_PLAINTEXT_BYTES is the SDK backstop.
|
|
89
|
+
MAX_ENCRYPTED_INLINE_BYTES: 6e4,
|
|
90
|
+
// Ceiling above which a text/* attachment is NOT materialized back into a string
|
|
91
|
+
// (re-inlined into SkillInput.data) - the consumer gets a filePath / explicit
|
|
92
|
+
// fetch instead. Also bounds the in-memory git-diff buffer (memory-DoS guard).
|
|
93
|
+
MAX_REINLINE_TEXT_BYTES: 4194304,
|
|
94
|
+
// 4 MiB
|
|
95
|
+
// Hard safety cap on a single file transferred via iroh, enforced on the
|
|
96
|
+
// actual streamed bytes (never the sender-declared `size`). A tunable default;
|
|
97
|
+
// providers may lower it per deployment.
|
|
98
|
+
MAX_FILE_SIZE: 1073741824,
|
|
99
|
+
// 1 GiB
|
|
75
100
|
MAX_TIMEOUT_SECS: 600,
|
|
76
101
|
// Upper bound for execution budgets (`max_execution_secs` / `execution_timeout_secs`).
|
|
77
102
|
// Distinct from MAX_TIMEOUT_SECS (the result-wait cap): execution budgets may be
|
|
@@ -89,6 +114,10 @@ var LIMITS = {
|
|
|
89
114
|
MAX_POLICY_SUMMARY_LENGTH: 280,
|
|
90
115
|
MAX_POLICY_VERSION_LENGTH: 32
|
|
91
116
|
};
|
|
117
|
+
var UTF8_ENCODER = new TextEncoder();
|
|
118
|
+
function utf8ByteLength(value) {
|
|
119
|
+
return UTF8_ENCODER.encode(value).length;
|
|
120
|
+
}
|
|
92
121
|
function getConfigDecoder() {
|
|
93
122
|
return getStructDecoder([
|
|
94
123
|
["discriminator", fixDecoderSize(getBytesDecoder(), 8)],
|
|
@@ -1212,6 +1241,12 @@ function parseCapabilityEvent(event, network) {
|
|
|
1212
1241
|
if (card.payment && (typeof card.payment.chain !== "string" || typeof card.payment.network !== "string" || typeof card.payment.address !== "string")) {
|
|
1213
1242
|
return null;
|
|
1214
1243
|
}
|
|
1244
|
+
if (card.payment && (card.payment.token !== void 0 && typeof card.payment.token !== "string" || card.payment.symbol !== void 0 && typeof card.payment.symbol !== "string" || card.payment.mint !== void 0 && typeof card.payment.mint !== "string")) {
|
|
1245
|
+
return null;
|
|
1246
|
+
}
|
|
1247
|
+
if (card.inputMime !== void 0 && (typeof card.inputMime !== "string" || card.inputMime.length > 255) || card.outputMime !== void 0 && (typeof card.outputMime !== "string" || card.outputMime.length > 255)) {
|
|
1248
|
+
return null;
|
|
1249
|
+
}
|
|
1215
1250
|
if (card.payment?.job_price !== null && card.payment?.job_price !== void 0 && (!Number.isInteger(card.payment.job_price) || card.payment.job_price < 0)) {
|
|
1216
1251
|
return null;
|
|
1217
1252
|
}
|
|
@@ -1472,6 +1507,7 @@ var DiscoveryService = class {
|
|
|
1472
1507
|
return agents;
|
|
1473
1508
|
}
|
|
1474
1509
|
const deliveredJobsByProvider = /* @__PURE__ */ new Map();
|
|
1510
|
+
const customerByJob = /* @__PURE__ */ new Map();
|
|
1475
1511
|
for (const ev of resultEvents) {
|
|
1476
1512
|
if (!verifyEvent(ev)) {
|
|
1477
1513
|
continue;
|
|
@@ -1491,8 +1527,13 @@ var DiscoveryService = class {
|
|
|
1491
1527
|
deliveredJobsByProvider.set(ev.pubkey, delivered);
|
|
1492
1528
|
}
|
|
1493
1529
|
delivered.add(jobEventId);
|
|
1530
|
+
const customerPubkey = ev.tags.find((tag) => tag[0] === "p")?.[1];
|
|
1531
|
+
if (customerPubkey) {
|
|
1532
|
+
customerByJob.set(jobEventId, customerPubkey);
|
|
1533
|
+
}
|
|
1494
1534
|
}
|
|
1495
1535
|
}
|
|
1536
|
+
const countedRatings = /* @__PURE__ */ new Set();
|
|
1496
1537
|
for (const ev of feedbackEvents) {
|
|
1497
1538
|
if (!verifyEvent(ev)) {
|
|
1498
1539
|
continue;
|
|
@@ -1508,19 +1549,25 @@ var DiscoveryService = class {
|
|
|
1508
1549
|
if (ev.created_at > agent.lastSeen) {
|
|
1509
1550
|
agent.lastSeen = ev.created_at;
|
|
1510
1551
|
}
|
|
1552
|
+
const jobEventId = ev.tags.find((tag) => tag[0] === "e")?.[1];
|
|
1553
|
+
const hasDeliveredResult = jobEventId !== void 0 && deliveredJobsByProvider.get(targetPubkey)?.has(jobEventId) === true;
|
|
1554
|
+
const jobCustomer = jobEventId !== void 0 ? customerByJob.get(jobEventId) : void 0;
|
|
1555
|
+
const authoredByCustomer = jobCustomer !== void 0 && ev.pubkey === jobCustomer;
|
|
1511
1556
|
const rating = ev.tags.find((tag) => tag[0] === "rating")?.[1];
|
|
1512
|
-
if (rating === "1" || rating === "0") {
|
|
1513
|
-
|
|
1514
|
-
if (
|
|
1515
|
-
|
|
1557
|
+
if ((rating === "1" || rating === "0") && hasDeliveredResult && authoredByCustomer) {
|
|
1558
|
+
const ratingKey = `${ev.pubkey}:${jobEventId}`;
|
|
1559
|
+
if (!countedRatings.has(ratingKey)) {
|
|
1560
|
+
countedRatings.add(ratingKey);
|
|
1561
|
+
agent.totalRatingCount = (agent.totalRatingCount ?? 0) + 1;
|
|
1562
|
+
if (rating === "1") {
|
|
1563
|
+
agent.positiveCount = (agent.positiveCount ?? 0) + 1;
|
|
1564
|
+
}
|
|
1516
1565
|
}
|
|
1517
1566
|
}
|
|
1518
1567
|
const status = ev.tags.find((tag) => tag[0] === "status")?.[1];
|
|
1519
1568
|
const txTag = ev.tags.find((tag) => tag[0] === "tx");
|
|
1520
1569
|
const txSignature = txTag?.[1];
|
|
1521
|
-
|
|
1522
|
-
const hasDeliveredResult = jobEventId !== void 0 && deliveredJobsByProvider.get(targetPubkey)?.has(jobEventId) === true;
|
|
1523
|
-
if (status === "payment-completed" && typeof txSignature === "string" && txSignature && hasDeliveredResult) {
|
|
1570
|
+
if (status === "payment-completed" && typeof txSignature === "string" && txSignature && hasDeliveredResult && authoredByCustomer) {
|
|
1524
1571
|
if (!agent.lastPaidJobAt || ev.created_at > agent.lastPaidJobAt) {
|
|
1525
1572
|
agent.lastPaidJobAt = ev.created_at;
|
|
1526
1573
|
agent.lastPaidJobTx = txSignature;
|
|
@@ -1776,6 +1823,67 @@ function nip44Decrypt(ciphertext, receiverSk, senderPubkey) {
|
|
|
1776
1823
|
const conversationKey = nip44.v2.utils.getConversationKey(receiverSk, senderPubkey);
|
|
1777
1824
|
return nip44.v2.decrypt(ciphertext, conversationKey);
|
|
1778
1825
|
}
|
|
1826
|
+
var ENVELOPE_VERSION = "elisym-job/1";
|
|
1827
|
+
var ENVELOPE_NAMESPACE_PREFIX = "elisym-job/";
|
|
1828
|
+
var MAX_TICKET_LENGTH = 4096;
|
|
1829
|
+
var FileTransportSchema = z.discriminatedUnion("kind", [
|
|
1830
|
+
z.object({
|
|
1831
|
+
kind: z.literal("iroh"),
|
|
1832
|
+
/** Opaque iroh `BlobTicket` string. Parsed into a real ticket only at fetch time. */
|
|
1833
|
+
ticket: z.string().min(1).max(MAX_TICKET_LENGTH)
|
|
1834
|
+
})
|
|
1835
|
+
]);
|
|
1836
|
+
var FileAttachmentSchema = z.object({
|
|
1837
|
+
/** Display name only. Never used to derive a filesystem path (callers sanitize). */
|
|
1838
|
+
name: z.string().min(1).max(255),
|
|
1839
|
+
/** Declared size in bytes (display/hint only; enforcement is on actual streamed bytes). */
|
|
1840
|
+
size: z.number().int().nonnegative(),
|
|
1841
|
+
mime: z.string().min(1).max(255),
|
|
1842
|
+
/** Ordered by sender preference; at least one. */
|
|
1843
|
+
transports: z.array(FileTransportSchema).min(1),
|
|
1844
|
+
/** Optional provider hint (unix seconds) for when seeding may stop. */
|
|
1845
|
+
seedingExpiresAt: z.number().int().nonnegative().optional()
|
|
1846
|
+
});
|
|
1847
|
+
var JobPayloadEnvelopeSchema = z.object({
|
|
1848
|
+
v: z.literal(ENVELOPE_VERSION),
|
|
1849
|
+
text: z.string().optional(),
|
|
1850
|
+
attachment: FileAttachmentSchema.optional()
|
|
1851
|
+
});
|
|
1852
|
+
function encodeJobPayload(payload) {
|
|
1853
|
+
const envelope = { v: ENVELOPE_VERSION };
|
|
1854
|
+
if (payload.text !== void 0) {
|
|
1855
|
+
envelope.text = payload.text;
|
|
1856
|
+
}
|
|
1857
|
+
if (payload.attachment !== void 0) {
|
|
1858
|
+
envelope.attachment = payload.attachment;
|
|
1859
|
+
}
|
|
1860
|
+
return JSON.stringify(envelope);
|
|
1861
|
+
}
|
|
1862
|
+
function decodeJobPayload(content) {
|
|
1863
|
+
if (content.length > LIMITS.MAX_INPUT_LENGTH) {
|
|
1864
|
+
return { text: content };
|
|
1865
|
+
}
|
|
1866
|
+
let parsed;
|
|
1867
|
+
try {
|
|
1868
|
+
parsed = JSON.parse(content);
|
|
1869
|
+
} catch {
|
|
1870
|
+
return { text: content };
|
|
1871
|
+
}
|
|
1872
|
+
if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) {
|
|
1873
|
+
return { text: content };
|
|
1874
|
+
}
|
|
1875
|
+
const version = parsed.v;
|
|
1876
|
+
if (typeof version !== "string" || !version.startsWith(ENVELOPE_NAMESPACE_PREFIX)) {
|
|
1877
|
+
return { text: content };
|
|
1878
|
+
}
|
|
1879
|
+
const result = JobPayloadEnvelopeSchema.safeParse(parsed);
|
|
1880
|
+
if (!result.success) {
|
|
1881
|
+
throw new Error(
|
|
1882
|
+
`Invalid elisym job payload (v=${JSON.stringify(version)}): ${result.error.message}`
|
|
1883
|
+
);
|
|
1884
|
+
}
|
|
1885
|
+
return { text: result.data.text, attachment: result.data.attachment };
|
|
1886
|
+
}
|
|
1779
1887
|
|
|
1780
1888
|
// src/services/marketplace.ts
|
|
1781
1889
|
function isEncrypted(event) {
|
|
@@ -1808,7 +1916,8 @@ var MarketplaceService = class {
|
|
|
1808
1916
|
}
|
|
1809
1917
|
/** Submit a job request with NIP-44 encrypted input. Returns the event ID. */
|
|
1810
1918
|
async submitJobRequest(identity, options) {
|
|
1811
|
-
|
|
1919
|
+
const hasAttachment = options.attachment !== void 0;
|
|
1920
|
+
if (!options.input && !hasAttachment) {
|
|
1812
1921
|
throw new Error("Job input must not be empty.");
|
|
1813
1922
|
}
|
|
1814
1923
|
if (options.input.length > LIMITS.MAX_INPUT_LENGTH) {
|
|
@@ -1822,7 +1931,15 @@ var MarketplaceService = class {
|
|
|
1822
1931
|
if (options.providerPubkey && !/^[0-9a-f]{64}$/.test(options.providerPubkey)) {
|
|
1823
1932
|
throw new Error("Invalid provider pubkey: expected 64 hex characters.");
|
|
1824
1933
|
}
|
|
1825
|
-
const plaintext = options.input;
|
|
1934
|
+
const plaintext = hasAttachment ? encodeJobPayload({ text: options.input || void 0, attachment: options.attachment }) : options.input;
|
|
1935
|
+
if (options.providerPubkey) {
|
|
1936
|
+
const plaintextBytes = utf8ByteLength(plaintext);
|
|
1937
|
+
if (plaintextBytes > LIMITS.NIP44_MAX_PLAINTEXT_BYTES) {
|
|
1938
|
+
throw new Error(
|
|
1939
|
+
`Encrypted job input too large: ${plaintextBytes} bytes (max ${LIMITS.NIP44_MAX_PLAINTEXT_BYTES}). Send large input as a file/iroh attachment instead.`
|
|
1940
|
+
);
|
|
1941
|
+
}
|
|
1942
|
+
}
|
|
1826
1943
|
const encrypted = options.providerPubkey ? nip44Encrypt(plaintext, identity.secretKey, options.providerPubkey) : plaintext;
|
|
1827
1944
|
const tags = [
|
|
1828
1945
|
["i", options.providerPubkey ? "encrypted" : "text", "text"],
|
|
@@ -1916,9 +2033,15 @@ var MarketplaceService = class {
|
|
|
1916
2033
|
if (content === null) {
|
|
1917
2034
|
return;
|
|
1918
2035
|
}
|
|
2036
|
+
let decoded;
|
|
2037
|
+
try {
|
|
2038
|
+
decoded = decodeJobPayload(content);
|
|
2039
|
+
} catch {
|
|
2040
|
+
return;
|
|
2041
|
+
}
|
|
1919
2042
|
resultDelivered = true;
|
|
1920
2043
|
try {
|
|
1921
|
-
cb.onResult?.(
|
|
2044
|
+
cb.onResult?.(decoded.text ?? "", ev.id, decoded.attachment);
|
|
1922
2045
|
} catch {
|
|
1923
2046
|
} finally {
|
|
1924
2047
|
done();
|
|
@@ -2082,8 +2205,9 @@ var MarketplaceService = class {
|
|
|
2082
2205
|
);
|
|
2083
2206
|
}
|
|
2084
2207
|
/** Submit a job result with NIP-44 encrypted content. Result kind is derived from the request kind. */
|
|
2085
|
-
async submitJobResult(identity, requestEvent, content, amount) {
|
|
2086
|
-
|
|
2208
|
+
async submitJobResult(identity, requestEvent, content, amount, attachment) {
|
|
2209
|
+
const hasAttachment = attachment !== void 0;
|
|
2210
|
+
if (!content && !hasAttachment) {
|
|
2087
2211
|
throw new Error("Job result content must not be empty.");
|
|
2088
2212
|
}
|
|
2089
2213
|
if (!Number.isInteger(requestEvent.kind)) {
|
|
@@ -2096,7 +2220,16 @@ var MarketplaceService = class {
|
|
|
2096
2220
|
);
|
|
2097
2221
|
}
|
|
2098
2222
|
const shouldEncrypt = isEncrypted(requestEvent);
|
|
2099
|
-
const
|
|
2223
|
+
const payload = hasAttachment ? encodeJobPayload({ text: content || void 0, attachment }) : content;
|
|
2224
|
+
if (shouldEncrypt) {
|
|
2225
|
+
const payloadBytes = utf8ByteLength(payload);
|
|
2226
|
+
if (payloadBytes > LIMITS.NIP44_MAX_PLAINTEXT_BYTES) {
|
|
2227
|
+
throw new Error(
|
|
2228
|
+
`Encrypted job result too large: ${payloadBytes} bytes (max ${LIMITS.NIP44_MAX_PLAINTEXT_BYTES}). Deliver large results as a file/iroh attachment instead.`
|
|
2229
|
+
);
|
|
2230
|
+
}
|
|
2231
|
+
}
|
|
2232
|
+
const resultContent = shouldEncrypt ? nip44Encrypt(payload, identity.secretKey, requestEvent.pubkey) : payload;
|
|
2100
2233
|
const resultKind = KIND_JOB_RESULT_BASE + offset;
|
|
2101
2234
|
const tags = [
|
|
2102
2235
|
["e", requestEvent.id],
|
|
@@ -2128,11 +2261,11 @@ var MarketplaceService = class {
|
|
|
2128
2261
|
* With maxAttempts=3: try, ~1s, try, ~2s, try, throw.
|
|
2129
2262
|
* Jitter: 0.5x-1.0x of calculated delay.
|
|
2130
2263
|
*/
|
|
2131
|
-
async submitJobResultWithRetry(identity, requestEvent, content, amount, maxAttempts = DEFAULTS.RESULT_RETRY_COUNT, baseDelayMs = DEFAULTS.RESULT_RETRY_BASE_MS) {
|
|
2264
|
+
async submitJobResultWithRetry(identity, requestEvent, content, amount, maxAttempts = DEFAULTS.RESULT_RETRY_COUNT, baseDelayMs = DEFAULTS.RESULT_RETRY_BASE_MS, attachment) {
|
|
2132
2265
|
const attempts = Math.max(1, maxAttempts);
|
|
2133
2266
|
for (let attempt = 0; attempt < attempts; attempt++) {
|
|
2134
2267
|
try {
|
|
2135
|
-
return await this.submitJobResult(identity, requestEvent, content, amount);
|
|
2268
|
+
return await this.submitJobResult(identity, requestEvent, content, amount, attachment);
|
|
2136
2269
|
} catch (e) {
|
|
2137
2270
|
if (attempt >= attempts - 1) {
|
|
2138
2271
|
throw e;
|
|
@@ -3404,35 +3537,43 @@ function formatNetworkBaseline(estimate) {
|
|
|
3404
3537
|
return `Estimated network gas: ${total} SOL (${parts.join(" + ")}).`;
|
|
3405
3538
|
}
|
|
3406
3539
|
var NEGATIVE_CACHE_TTL_MS = 6e4;
|
|
3540
|
+
var MAX_CACHE_ENTRIES = 5e3;
|
|
3407
3541
|
var verifyCache = /* @__PURE__ */ new Map();
|
|
3408
3542
|
function clearQuickVerifyCache() {
|
|
3409
3543
|
verifyCache.clear();
|
|
3410
3544
|
}
|
|
3411
3545
|
async function verifyJobPaymentQuick(rpc, txSignature, expectedRecipient) {
|
|
3412
3546
|
if (!txSignature) {
|
|
3413
|
-
return {
|
|
3547
|
+
return { receivedFunds: false, txSignature: "", reason: "invalid_input" };
|
|
3414
3548
|
}
|
|
3415
3549
|
if (!expectedRecipient || !isAddress(expectedRecipient)) {
|
|
3416
|
-
return {
|
|
3550
|
+
return { receivedFunds: false, txSignature, reason: "invalid_input" };
|
|
3417
3551
|
}
|
|
3418
3552
|
const cacheKey2 = `${txSignature}:${expectedRecipient}`;
|
|
3419
3553
|
const cached = verifyCache.get(cacheKey2);
|
|
3420
3554
|
if (cached) {
|
|
3421
|
-
if (cached.result.
|
|
3555
|
+
if (cached.result.receivedFunds) {
|
|
3422
3556
|
return cached.result;
|
|
3423
3557
|
}
|
|
3424
3558
|
if (Date.now() - cached.cachedAt < NEGATIVE_CACHE_TTL_MS) {
|
|
3425
3559
|
return cached.result;
|
|
3426
3560
|
}
|
|
3561
|
+
verifyCache.delete(cacheKey2);
|
|
3427
3562
|
}
|
|
3428
3563
|
const result = await doVerifyOnce(rpc, txSignature, expectedRecipient);
|
|
3564
|
+
if (verifyCache.size >= MAX_CACHE_ENTRIES) {
|
|
3565
|
+
const oldest = verifyCache.keys().next().value;
|
|
3566
|
+
if (oldest !== void 0) {
|
|
3567
|
+
verifyCache.delete(oldest);
|
|
3568
|
+
}
|
|
3569
|
+
}
|
|
3429
3570
|
verifyCache.set(cacheKey2, { result, cachedAt: Date.now() });
|
|
3430
3571
|
return result;
|
|
3431
3572
|
}
|
|
3432
3573
|
async function doVerifyOnce(rpc, txSignature, expectedRecipient) {
|
|
3433
3574
|
const sigStr = txSignature;
|
|
3434
3575
|
if (!rpc || typeof rpc.getTransaction !== "function") {
|
|
3435
|
-
return {
|
|
3576
|
+
return { receivedFunds: false, txSignature: sigStr, reason: "rpc_error" };
|
|
3436
3577
|
}
|
|
3437
3578
|
let tx;
|
|
3438
3579
|
try {
|
|
@@ -3442,13 +3583,13 @@ async function doVerifyOnce(rpc, txSignature, expectedRecipient) {
|
|
|
3442
3583
|
maxSupportedTransactionVersion: 0
|
|
3443
3584
|
}).send();
|
|
3444
3585
|
} catch {
|
|
3445
|
-
return {
|
|
3586
|
+
return { receivedFunds: false, txSignature: sigStr, reason: "rpc_error" };
|
|
3446
3587
|
}
|
|
3447
3588
|
if (!tx) {
|
|
3448
|
-
return {
|
|
3589
|
+
return { receivedFunds: false, txSignature: sigStr, reason: "not_found" };
|
|
3449
3590
|
}
|
|
3450
3591
|
if (!tx.meta || tx.meta.err) {
|
|
3451
|
-
return {
|
|
3592
|
+
return { receivedFunds: false, txSignature: sigStr, reason: "tx_failed" };
|
|
3452
3593
|
}
|
|
3453
3594
|
const accountKeys = tx.transaction.message.accountKeys;
|
|
3454
3595
|
const recipientStr = expectedRecipient;
|
|
@@ -3462,7 +3603,7 @@ async function doVerifyOnce(rpc, txSignature, expectedRecipient) {
|
|
|
3462
3603
|
if (pre !== void 0 && post !== void 0) {
|
|
3463
3604
|
const delta = BigInt(post) - BigInt(pre);
|
|
3464
3605
|
if (delta > 0n) {
|
|
3465
|
-
return {
|
|
3606
|
+
return { receivedFunds: true, txSignature: sigStr };
|
|
3466
3607
|
}
|
|
3467
3608
|
}
|
|
3468
3609
|
}
|
|
@@ -3480,11 +3621,11 @@ async function doVerifyOnce(rpc, txSignature, expectedRecipient) {
|
|
|
3480
3621
|
const preAmount = pre ? BigInt(pre.uiTokenAmount.amount) : 0n;
|
|
3481
3622
|
const postAmount = BigInt(post.uiTokenAmount.amount);
|
|
3482
3623
|
if (postAmount > preAmount) {
|
|
3483
|
-
return {
|
|
3624
|
+
return { receivedFunds: true, txSignature: sigStr };
|
|
3484
3625
|
}
|
|
3485
3626
|
}
|
|
3486
3627
|
}
|
|
3487
|
-
return {
|
|
3628
|
+
return { receivedFunds: false, txSignature: sigStr, reason: "recipient_mismatch" };
|
|
3488
3629
|
}
|
|
3489
3630
|
var DEFAULT_LIMIT = 1e3;
|
|
3490
3631
|
var NATIVE_KEY = "native";
|
|
@@ -3579,7 +3720,12 @@ var SessionSpendLimitEntrySchema = z.object({
|
|
|
3579
3720
|
chain: z.enum(["solana"]),
|
|
3580
3721
|
token: z.string().min(1).max(16).regex(/^[a-z0-9]+$/, "token must be lowercase alphanumeric"),
|
|
3581
3722
|
mint: z.string().min(1).max(64).optional(),
|
|
3582
|
-
|
|
3723
|
+
// Stored as a string to preserve the operator's exact decimal text (avoids
|
|
3724
|
+
// Number round-tripping to scientific notation). Legacy configs persisted a
|
|
3725
|
+
// number; accept both and normalize to a positive-decimal string.
|
|
3726
|
+
amount: z.union([z.string(), z.number()]).transform((value) => typeof value === "number" ? String(value) : value.trim()).refine((value) => /^\d+(?:\.\d+)?$/.test(value) && /[1-9]/.test(value), {
|
|
3727
|
+
message: 'amount must be a positive decimal (e.g. "0.5", "1")'
|
|
3728
|
+
})
|
|
3583
3729
|
}).strict();
|
|
3584
3730
|
var GlobalConfigSchema = z.object({
|
|
3585
3731
|
session_spend_limits: z.array(SessionSpendLimitEntrySchema).max(16).optional()
|
|
@@ -3779,6 +3925,6 @@ function makeCensor() {
|
|
|
3779
3925
|
};
|
|
3780
3926
|
}
|
|
3781
3927
|
|
|
3782
|
-
export { BoundedSet, DEFAULTS, DEFAULT_KIND_OFFSET, DEFAULT_REDACT_PATHS, DiscoveryService, ELISYM_PROTOCOL_TAG, ElisymClient, ElisymIdentity, GlobalConfigSchema, INPUT_REDACT_PATHS, JobWaitTimeoutError, KIND_APP_HANDLER, KIND_JOB_FEEDBACK, KIND_JOB_REQUEST, KIND_JOB_REQUEST_BASE, KIND_JOB_RESULT, KIND_JOB_RESULT_BASE, KIND_LONG_FORM_ARTICLE, KIND_PING, KIND_PONG, KNOWN_ASSETS, LAMPORTS_PER_SOL, LIMITS, MarketplaceService, MediaService, NATIVE_SOL, NostrPool, POLICY_D_TAG_PREFIX, POLICY_TYPE_REGEX, POLICY_T_TAG, PROTOCOL_PROGRAM_ID_DEVNET, PaymentRequestSchema, PingService, PoliciesService, RELAYS, SECRET_REDACT_PATHS, SessionSpendLimitEntrySchema, SolanaPaymentStrategy, USDC_SOLANA_DEVNET, aggregateNetworkStats, assertExpiry, assertLamports, assetByKey, assetKey, buildPaymentInstructions, calculateProtocolFee, classifyJobError, clearPriorityFeeCache, clearProtocolConfigCache, clearQuickVerifyCache, compareAgentsByRank, computeRankKey, createPaymentRequestWithOnchainConfig, createSlidingWindowLimiter, estimateNetworkBaseline, estimatePriorityFeeMicroLamports, estimateSolFeeLamports, formatAssetAmount, formatFeeBreakdown, formatNetworkBaseline, formatSol, getNetworkStats, getProtocolConfig, getProtocolProgramId, jobRequestKind, jobResultKind, makeCensor, nip44Decrypt, nip44Encrypt, parseAssetAmount, parsePaymentRequest, pickPercentileFee, resolveAssetFromPaymentRequest, resolveKnownAsset, timeAgo, toDTag, truncateKey, validateAgentName, validateExpiry, verifyJobPaymentQuick };
|
|
3928
|
+
export { BoundedSet, DEFAULTS, DEFAULT_KIND_OFFSET, DEFAULT_REDACT_PATHS, DiscoveryService, ELISYM_PROTOCOL_TAG, ENVELOPE_VERSION, ElisymClient, ElisymIdentity, GlobalConfigSchema, INPUT_REDACT_PATHS, JobWaitTimeoutError, KIND_APP_HANDLER, KIND_JOB_FEEDBACK, KIND_JOB_REQUEST, KIND_JOB_REQUEST_BASE, KIND_JOB_RESULT, KIND_JOB_RESULT_BASE, KIND_LONG_FORM_ARTICLE, KIND_PING, KIND_PONG, KNOWN_ASSETS, LAMPORTS_PER_SOL, LIMITS, MarketplaceService, MediaService, NATIVE_SOL, NostrPool, POLICY_D_TAG_PREFIX, POLICY_TYPE_REGEX, POLICY_T_TAG, PROTOCOL_PROGRAM_ID_DEVNET, PaymentRequestSchema, PingService, PoliciesService, RELAYS, SECRET_REDACT_PATHS, SessionSpendLimitEntrySchema, SolanaPaymentStrategy, USDC_SOLANA_DEVNET, aggregateNetworkStats, assertExpiry, assertLamports, assetByKey, assetKey, buildPaymentInstructions, calculateProtocolFee, classifyJobError, clearPriorityFeeCache, clearProtocolConfigCache, clearQuickVerifyCache, compareAgentsByRank, computeRankKey, createPaymentRequestWithOnchainConfig, createSlidingWindowLimiter, decodeJobPayload, encodeJobPayload, estimateNetworkBaseline, estimatePriorityFeeMicroLamports, estimateSolFeeLamports, formatAssetAmount, formatFeeBreakdown, formatNetworkBaseline, formatSol, getNetworkStats, getProtocolConfig, getProtocolProgramId, jobRequestKind, jobResultKind, makeCensor, nip44Decrypt, nip44Encrypt, parseAssetAmount, parsePaymentRequest, pickPercentileFee, resolveAssetFromPaymentRequest, resolveKnownAsset, timeAgo, toDTag, truncateKey, utf8ByteLength, validateAgentName, validateExpiry, verifyJobPaymentQuick };
|
|
3783
3929
|
//# sourceMappingURL=index.js.map
|
|
3784
3930
|
//# sourceMappingURL=index.js.map
|