@elisym/sdk 0.22.0 → 0.23.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/{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 +43 -18
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +17 -2
- package/dist/index.d.ts +17 -2
- package/dist/index.js +43 -18
- 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 +6 -1
- package/dist/node.cjs.map +1 -1
- package/dist/node.d.cts +1 -1
- package/dist/node.d.ts +1 -1
- package/dist/node.js +6 -1
- package/dist/node.js.map +1 -1
- package/dist/skills.cjs +62 -17
- package/dist/skills.cjs.map +1 -1
- package/dist/skills.d.cts +1 -1
- package/dist/skills.d.ts +1 -1
- package/dist/skills.js +62 -17
- 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 +1 -1
package/dist/index.d.cts
CHANGED
|
@@ -3,7 +3,7 @@ import { Filter, Event } from 'nostr-tools';
|
|
|
3
3
|
import { A as Asset } from './assets-C-nzSYD4.cjs';
|
|
4
4
|
export { C as Chain, K as KNOWN_ASSETS, N as NATIVE_SOL, U as USDC_SOLANA_DEVNET, a as assetByKey, b as assetKey, f as formatAssetAmount, p as parseAssetAmount, r as resolveAssetFromPaymentRequest, c as resolveKnownAsset } from './assets-C-nzSYD4.cjs';
|
|
5
5
|
import { z } from 'zod';
|
|
6
|
-
export { G as GlobalConfig, a as GlobalConfigSchema, S as SessionSpendLimitEntry, b as SessionSpendLimitEntrySchema } from './global-schema-
|
|
6
|
+
export { G as GlobalConfig, a as GlobalConfigSchema, S as SessionSpendLimitEntry, b as SessionSpendLimitEntrySchema } from './global-schema-BsVFDtkt.cjs';
|
|
7
7
|
export { R as RateLimitDecision, S as SlidingWindowLimiter, a as SlidingWindowLimiterOptions, c as createSlidingWindowLimiter } from './rateLimiter-CoEmZkSX.cjs';
|
|
8
8
|
|
|
9
9
|
declare class ElisymIdentity {
|
|
@@ -1053,7 +1053,16 @@ declare function parsePaymentRequest(input: string, options?: ParseOptions): Par
|
|
|
1053
1053
|
*/
|
|
1054
1054
|
type QuickVerifyReason = 'not_found' | 'tx_failed' | 'recipient_mismatch' | 'rpc_error' | 'invalid_input';
|
|
1055
1055
|
interface QuickVerifyResult {
|
|
1056
|
-
|
|
1056
|
+
/**
|
|
1057
|
+
* True when the recipient address received funds in this transaction.
|
|
1058
|
+
*
|
|
1059
|
+
* NOTE: this is NOT proof of a valid elisym job payment. It does not check
|
|
1060
|
+
* the payment `reference` key or that the amount matches the job price - it
|
|
1061
|
+
* is a best-effort signal for the fast discovery-ranking path, where the
|
|
1062
|
+
* original payment request is unavailable. For an authoritative check
|
|
1063
|
+
* (amount + reference) use `SolanaPaymentStrategy.verifyPayment`.
|
|
1064
|
+
*/
|
|
1065
|
+
receivedFunds: boolean;
|
|
1057
1066
|
txSignature: string;
|
|
1058
1067
|
reason?: QuickVerifyReason;
|
|
1059
1068
|
}
|
|
@@ -1105,6 +1114,12 @@ declare function aggregateNetworkStats(rpc: Rpc<SolanaRpcApi>, options?: Aggrega
|
|
|
1105
1114
|
* Returns `null` when the PDA has not been initialized yet (admin must call
|
|
1106
1115
|
* `initialize_stats` once after program upgrade).
|
|
1107
1116
|
*/
|
|
1117
|
+
/**
|
|
1118
|
+
* Best-effort network counters read from the on-chain PDA. These are NOT bound
|
|
1119
|
+
* to verified transfers and can be inflated by a malicious caller, so present
|
|
1120
|
+
* them as approximate/unverified, never as authoritative proof of activity. For
|
|
1121
|
+
* a transfer-derived figure use `aggregateNetworkStats`.
|
|
1122
|
+
*/
|
|
1108
1123
|
interface OnchainNetworkStats {
|
|
1109
1124
|
jobCount: number;
|
|
1110
1125
|
volumeNative: bigint;
|
package/dist/index.d.ts
CHANGED
|
@@ -3,7 +3,7 @@ import { Filter, Event } from 'nostr-tools';
|
|
|
3
3
|
import { A as Asset } from './assets-C-nzSYD4.js';
|
|
4
4
|
export { C as Chain, K as KNOWN_ASSETS, N as NATIVE_SOL, U as USDC_SOLANA_DEVNET, a as assetByKey, b as assetKey, f as formatAssetAmount, p as parseAssetAmount, r as resolveAssetFromPaymentRequest, c as resolveKnownAsset } from './assets-C-nzSYD4.js';
|
|
5
5
|
import { z } from 'zod';
|
|
6
|
-
export { G as GlobalConfig, a as GlobalConfigSchema, S as SessionSpendLimitEntry, b as SessionSpendLimitEntrySchema } from './global-schema-
|
|
6
|
+
export { G as GlobalConfig, a as GlobalConfigSchema, S as SessionSpendLimitEntry, b as SessionSpendLimitEntrySchema } from './global-schema-BsVFDtkt.js';
|
|
7
7
|
export { R as RateLimitDecision, S as SlidingWindowLimiter, a as SlidingWindowLimiterOptions, c as createSlidingWindowLimiter } from './rateLimiter-CoEmZkSX.js';
|
|
8
8
|
|
|
9
9
|
declare class ElisymIdentity {
|
|
@@ -1053,7 +1053,16 @@ declare function parsePaymentRequest(input: string, options?: ParseOptions): Par
|
|
|
1053
1053
|
*/
|
|
1054
1054
|
type QuickVerifyReason = 'not_found' | 'tx_failed' | 'recipient_mismatch' | 'rpc_error' | 'invalid_input';
|
|
1055
1055
|
interface QuickVerifyResult {
|
|
1056
|
-
|
|
1056
|
+
/**
|
|
1057
|
+
* True when the recipient address received funds in this transaction.
|
|
1058
|
+
*
|
|
1059
|
+
* NOTE: this is NOT proof of a valid elisym job payment. It does not check
|
|
1060
|
+
* the payment `reference` key or that the amount matches the job price - it
|
|
1061
|
+
* is a best-effort signal for the fast discovery-ranking path, where the
|
|
1062
|
+
* original payment request is unavailable. For an authoritative check
|
|
1063
|
+
* (amount + reference) use `SolanaPaymentStrategy.verifyPayment`.
|
|
1064
|
+
*/
|
|
1065
|
+
receivedFunds: boolean;
|
|
1057
1066
|
txSignature: string;
|
|
1058
1067
|
reason?: QuickVerifyReason;
|
|
1059
1068
|
}
|
|
@@ -1105,6 +1114,12 @@ declare function aggregateNetworkStats(rpc: Rpc<SolanaRpcApi>, options?: Aggrega
|
|
|
1105
1114
|
* Returns `null` when the PDA has not been initialized yet (admin must call
|
|
1106
1115
|
* `initialize_stats` once after program upgrade).
|
|
1107
1116
|
*/
|
|
1117
|
+
/**
|
|
1118
|
+
* Best-effort network counters read from the on-chain PDA. These are NOT bound
|
|
1119
|
+
* to verified transfers and can be inflated by a malicious caller, so present
|
|
1120
|
+
* them as approximate/unverified, never as authoritative proof of activity. For
|
|
1121
|
+
* a transfer-derived figure use `aggregateNetworkStats`.
|
|
1122
|
+
*/
|
|
1108
1123
|
interface OnchainNetworkStats {
|
|
1109
1124
|
jobCount: number;
|
|
1110
1125
|
volumeNative: bigint;
|
package/dist/index.js
CHANGED
|
@@ -1472,6 +1472,7 @@ var DiscoveryService = class {
|
|
|
1472
1472
|
return agents;
|
|
1473
1473
|
}
|
|
1474
1474
|
const deliveredJobsByProvider = /* @__PURE__ */ new Map();
|
|
1475
|
+
const customerByJob = /* @__PURE__ */ new Map();
|
|
1475
1476
|
for (const ev of resultEvents) {
|
|
1476
1477
|
if (!verifyEvent(ev)) {
|
|
1477
1478
|
continue;
|
|
@@ -1491,8 +1492,13 @@ var DiscoveryService = class {
|
|
|
1491
1492
|
deliveredJobsByProvider.set(ev.pubkey, delivered);
|
|
1492
1493
|
}
|
|
1493
1494
|
delivered.add(jobEventId);
|
|
1495
|
+
const customerPubkey = ev.tags.find((tag) => tag[0] === "p")?.[1];
|
|
1496
|
+
if (customerPubkey) {
|
|
1497
|
+
customerByJob.set(jobEventId, customerPubkey);
|
|
1498
|
+
}
|
|
1494
1499
|
}
|
|
1495
1500
|
}
|
|
1501
|
+
const countedRatings = /* @__PURE__ */ new Set();
|
|
1496
1502
|
for (const ev of feedbackEvents) {
|
|
1497
1503
|
if (!verifyEvent(ev)) {
|
|
1498
1504
|
continue;
|
|
@@ -1508,19 +1514,25 @@ var DiscoveryService = class {
|
|
|
1508
1514
|
if (ev.created_at > agent.lastSeen) {
|
|
1509
1515
|
agent.lastSeen = ev.created_at;
|
|
1510
1516
|
}
|
|
1517
|
+
const jobEventId = ev.tags.find((tag) => tag[0] === "e")?.[1];
|
|
1518
|
+
const hasDeliveredResult = jobEventId !== void 0 && deliveredJobsByProvider.get(targetPubkey)?.has(jobEventId) === true;
|
|
1519
|
+
const jobCustomer = jobEventId !== void 0 ? customerByJob.get(jobEventId) : void 0;
|
|
1520
|
+
const authoredByCustomer = jobCustomer !== void 0 && ev.pubkey === jobCustomer;
|
|
1511
1521
|
const rating = ev.tags.find((tag) => tag[0] === "rating")?.[1];
|
|
1512
|
-
if (rating === "1" || rating === "0") {
|
|
1513
|
-
|
|
1514
|
-
if (
|
|
1515
|
-
|
|
1522
|
+
if ((rating === "1" || rating === "0") && hasDeliveredResult && authoredByCustomer) {
|
|
1523
|
+
const ratingKey = `${ev.pubkey}:${jobEventId}`;
|
|
1524
|
+
if (!countedRatings.has(ratingKey)) {
|
|
1525
|
+
countedRatings.add(ratingKey);
|
|
1526
|
+
agent.totalRatingCount = (agent.totalRatingCount ?? 0) + 1;
|
|
1527
|
+
if (rating === "1") {
|
|
1528
|
+
agent.positiveCount = (agent.positiveCount ?? 0) + 1;
|
|
1529
|
+
}
|
|
1516
1530
|
}
|
|
1517
1531
|
}
|
|
1518
1532
|
const status = ev.tags.find((tag) => tag[0] === "status")?.[1];
|
|
1519
1533
|
const txTag = ev.tags.find((tag) => tag[0] === "tx");
|
|
1520
1534
|
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) {
|
|
1535
|
+
if (status === "payment-completed" && typeof txSignature === "string" && txSignature && hasDeliveredResult && authoredByCustomer) {
|
|
1524
1536
|
if (!agent.lastPaidJobAt || ev.created_at > agent.lastPaidJobAt) {
|
|
1525
1537
|
agent.lastPaidJobAt = ev.created_at;
|
|
1526
1538
|
agent.lastPaidJobTx = txSignature;
|
|
@@ -3404,35 +3416,43 @@ function formatNetworkBaseline(estimate) {
|
|
|
3404
3416
|
return `Estimated network gas: ${total} SOL (${parts.join(" + ")}).`;
|
|
3405
3417
|
}
|
|
3406
3418
|
var NEGATIVE_CACHE_TTL_MS = 6e4;
|
|
3419
|
+
var MAX_CACHE_ENTRIES = 5e3;
|
|
3407
3420
|
var verifyCache = /* @__PURE__ */ new Map();
|
|
3408
3421
|
function clearQuickVerifyCache() {
|
|
3409
3422
|
verifyCache.clear();
|
|
3410
3423
|
}
|
|
3411
3424
|
async function verifyJobPaymentQuick(rpc, txSignature, expectedRecipient) {
|
|
3412
3425
|
if (!txSignature) {
|
|
3413
|
-
return {
|
|
3426
|
+
return { receivedFunds: false, txSignature: "", reason: "invalid_input" };
|
|
3414
3427
|
}
|
|
3415
3428
|
if (!expectedRecipient || !isAddress(expectedRecipient)) {
|
|
3416
|
-
return {
|
|
3429
|
+
return { receivedFunds: false, txSignature, reason: "invalid_input" };
|
|
3417
3430
|
}
|
|
3418
3431
|
const cacheKey2 = `${txSignature}:${expectedRecipient}`;
|
|
3419
3432
|
const cached = verifyCache.get(cacheKey2);
|
|
3420
3433
|
if (cached) {
|
|
3421
|
-
if (cached.result.
|
|
3434
|
+
if (cached.result.receivedFunds) {
|
|
3422
3435
|
return cached.result;
|
|
3423
3436
|
}
|
|
3424
3437
|
if (Date.now() - cached.cachedAt < NEGATIVE_CACHE_TTL_MS) {
|
|
3425
3438
|
return cached.result;
|
|
3426
3439
|
}
|
|
3440
|
+
verifyCache.delete(cacheKey2);
|
|
3427
3441
|
}
|
|
3428
3442
|
const result = await doVerifyOnce(rpc, txSignature, expectedRecipient);
|
|
3443
|
+
if (verifyCache.size >= MAX_CACHE_ENTRIES) {
|
|
3444
|
+
const oldest = verifyCache.keys().next().value;
|
|
3445
|
+
if (oldest !== void 0) {
|
|
3446
|
+
verifyCache.delete(oldest);
|
|
3447
|
+
}
|
|
3448
|
+
}
|
|
3429
3449
|
verifyCache.set(cacheKey2, { result, cachedAt: Date.now() });
|
|
3430
3450
|
return result;
|
|
3431
3451
|
}
|
|
3432
3452
|
async function doVerifyOnce(rpc, txSignature, expectedRecipient) {
|
|
3433
3453
|
const sigStr = txSignature;
|
|
3434
3454
|
if (!rpc || typeof rpc.getTransaction !== "function") {
|
|
3435
|
-
return {
|
|
3455
|
+
return { receivedFunds: false, txSignature: sigStr, reason: "rpc_error" };
|
|
3436
3456
|
}
|
|
3437
3457
|
let tx;
|
|
3438
3458
|
try {
|
|
@@ -3442,13 +3462,13 @@ async function doVerifyOnce(rpc, txSignature, expectedRecipient) {
|
|
|
3442
3462
|
maxSupportedTransactionVersion: 0
|
|
3443
3463
|
}).send();
|
|
3444
3464
|
} catch {
|
|
3445
|
-
return {
|
|
3465
|
+
return { receivedFunds: false, txSignature: sigStr, reason: "rpc_error" };
|
|
3446
3466
|
}
|
|
3447
3467
|
if (!tx) {
|
|
3448
|
-
return {
|
|
3468
|
+
return { receivedFunds: false, txSignature: sigStr, reason: "not_found" };
|
|
3449
3469
|
}
|
|
3450
3470
|
if (!tx.meta || tx.meta.err) {
|
|
3451
|
-
return {
|
|
3471
|
+
return { receivedFunds: false, txSignature: sigStr, reason: "tx_failed" };
|
|
3452
3472
|
}
|
|
3453
3473
|
const accountKeys = tx.transaction.message.accountKeys;
|
|
3454
3474
|
const recipientStr = expectedRecipient;
|
|
@@ -3462,7 +3482,7 @@ async function doVerifyOnce(rpc, txSignature, expectedRecipient) {
|
|
|
3462
3482
|
if (pre !== void 0 && post !== void 0) {
|
|
3463
3483
|
const delta = BigInt(post) - BigInt(pre);
|
|
3464
3484
|
if (delta > 0n) {
|
|
3465
|
-
return {
|
|
3485
|
+
return { receivedFunds: true, txSignature: sigStr };
|
|
3466
3486
|
}
|
|
3467
3487
|
}
|
|
3468
3488
|
}
|
|
@@ -3480,11 +3500,11 @@ async function doVerifyOnce(rpc, txSignature, expectedRecipient) {
|
|
|
3480
3500
|
const preAmount = pre ? BigInt(pre.uiTokenAmount.amount) : 0n;
|
|
3481
3501
|
const postAmount = BigInt(post.uiTokenAmount.amount);
|
|
3482
3502
|
if (postAmount > preAmount) {
|
|
3483
|
-
return {
|
|
3503
|
+
return { receivedFunds: true, txSignature: sigStr };
|
|
3484
3504
|
}
|
|
3485
3505
|
}
|
|
3486
3506
|
}
|
|
3487
|
-
return {
|
|
3507
|
+
return { receivedFunds: false, txSignature: sigStr, reason: "recipient_mismatch" };
|
|
3488
3508
|
}
|
|
3489
3509
|
var DEFAULT_LIMIT = 1e3;
|
|
3490
3510
|
var NATIVE_KEY = "native";
|
|
@@ -3579,7 +3599,12 @@ var SessionSpendLimitEntrySchema = z.object({
|
|
|
3579
3599
|
chain: z.enum(["solana"]),
|
|
3580
3600
|
token: z.string().min(1).max(16).regex(/^[a-z0-9]+$/, "token must be lowercase alphanumeric"),
|
|
3581
3601
|
mint: z.string().min(1).max(64).optional(),
|
|
3582
|
-
|
|
3602
|
+
// Stored as a string to preserve the operator's exact decimal text (avoids
|
|
3603
|
+
// Number round-tripping to scientific notation). Legacy configs persisted a
|
|
3604
|
+
// number; accept both and normalize to a positive-decimal string.
|
|
3605
|
+
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), {
|
|
3606
|
+
message: 'amount must be a positive decimal (e.g. "0.5", "1")'
|
|
3607
|
+
})
|
|
3583
3608
|
}).strict();
|
|
3584
3609
|
var GlobalConfigSchema = z.object({
|
|
3585
3610
|
session_spend_limits: z.array(SessionSpendLimitEntrySchema).max(16).optional()
|