@elisym/sdk 0.4.1 → 0.6.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 +545 -0
- package/dist/agent-store.cjs.map +1 -0
- package/dist/agent-store.d.cts +334 -0
- package/dist/agent-store.d.ts +334 -0
- package/dist/agent-store.js +505 -0
- package/dist/agent-store.js.map +1 -0
- package/dist/index.cjs +142 -25
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +294 -16
- package/dist/index.d.ts +294 -16
- package/dist/index.js +139 -26
- package/dist/index.js.map +1 -1
- package/dist/node.cjs +0 -92
- package/dist/node.cjs.map +1 -1
- package/dist/node.d.cts +1 -15
- package/dist/node.d.ts +1 -15
- package/dist/node.js +1 -92
- package/dist/node.js.map +1 -1
- package/package.json +15 -1
- package/dist/types-CII4k_8d.d.cts +0 -181
- package/dist/types-CII4k_8d.d.ts +0 -181
package/dist/index.cjs
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
var system = require('@solana-program/system');
|
|
4
4
|
var kit = require('@solana/kit');
|
|
5
5
|
var Decimal2 = require('decimal.js-light');
|
|
6
|
+
var zod = require('zod');
|
|
6
7
|
var nostrTools = require('nostr-tools');
|
|
7
8
|
var nip44 = require('nostr-tools/nip44');
|
|
8
9
|
|
|
@@ -215,7 +216,118 @@ function assertExpiry(createdAt, expirySecs) {
|
|
|
215
216
|
}
|
|
216
217
|
}
|
|
217
218
|
|
|
219
|
+
// src/payment/priorityFee.ts
|
|
220
|
+
var PRIORITY_FEE_FLOOR_MICROLAMPORTS = 1000n;
|
|
221
|
+
var DEFAULT_PERCENTILE = 75;
|
|
222
|
+
var DEFAULT_CACHE_TTL_MS = 1e4;
|
|
223
|
+
var cache2 = /* @__PURE__ */ new Map();
|
|
224
|
+
async function estimatePriorityFeeMicroLamports(rpc, options) {
|
|
225
|
+
const percentile = clampPercentile(options?.percentile ?? DEFAULT_PERCENTILE);
|
|
226
|
+
const ttl = options?.ttlMs ?? DEFAULT_CACHE_TTL_MS;
|
|
227
|
+
const accounts = options?.accounts ?? [];
|
|
228
|
+
const key = cacheKey(percentile, accounts);
|
|
229
|
+
const now = Date.now();
|
|
230
|
+
const cached = cache2.get(key);
|
|
231
|
+
if (cached && now < cached.expires) {
|
|
232
|
+
return cached.microLamports;
|
|
233
|
+
}
|
|
234
|
+
const samples = await rpc.getRecentPrioritizationFees(accounts).send();
|
|
235
|
+
const fee = pickPercentileFee(samples, percentile);
|
|
236
|
+
cache2.set(key, { microLamports: fee, expires: now + ttl });
|
|
237
|
+
return fee;
|
|
238
|
+
}
|
|
239
|
+
function clearPriorityFeeCache() {
|
|
240
|
+
cache2.clear();
|
|
241
|
+
}
|
|
242
|
+
function pickPercentileFee(samples, percentile) {
|
|
243
|
+
if (samples.length === 0) {
|
|
244
|
+
return PRIORITY_FEE_FLOOR_MICROLAMPORTS;
|
|
245
|
+
}
|
|
246
|
+
const sorted = samples.map((sample) => BigInt(sample.prioritizationFee)).sort(compareBigInt);
|
|
247
|
+
const clamped = clampPercentile(percentile);
|
|
248
|
+
const indexFloat = clamped / 100 * (sorted.length - 1) | 0;
|
|
249
|
+
const value = sorted[indexFloat];
|
|
250
|
+
return value > PRIORITY_FEE_FLOOR_MICROLAMPORTS ? value : PRIORITY_FEE_FLOOR_MICROLAMPORTS;
|
|
251
|
+
}
|
|
252
|
+
function clampPercentile(value) {
|
|
253
|
+
if (!Number.isFinite(value)) {
|
|
254
|
+
return DEFAULT_PERCENTILE;
|
|
255
|
+
}
|
|
256
|
+
if (value < 0) {
|
|
257
|
+
return 0;
|
|
258
|
+
}
|
|
259
|
+
if (value > 100) {
|
|
260
|
+
return 100;
|
|
261
|
+
}
|
|
262
|
+
return value;
|
|
263
|
+
}
|
|
264
|
+
function compareBigInt(left, right) {
|
|
265
|
+
if (left < right) {
|
|
266
|
+
return -1;
|
|
267
|
+
}
|
|
268
|
+
if (left > right) {
|
|
269
|
+
return 1;
|
|
270
|
+
}
|
|
271
|
+
return 0;
|
|
272
|
+
}
|
|
273
|
+
function cacheKey(percentile, accounts) {
|
|
274
|
+
if (accounts.length === 0) {
|
|
275
|
+
return `p:${percentile}`;
|
|
276
|
+
}
|
|
277
|
+
return `p:${percentile}:${[...accounts].sort().join(",")}`;
|
|
278
|
+
}
|
|
279
|
+
var MAX_DESCRIPTION_LENGTH = LIMITS.MAX_DESCRIPTION_LENGTH;
|
|
280
|
+
var MAX_SAFE_LAMPORTS = Number.MAX_SAFE_INTEGER;
|
|
281
|
+
var MAX_EXPIRY_SECS_SCHEMA = 86400;
|
|
282
|
+
var BASE58_RE = /^[1-9A-HJ-NP-Za-km-z]+$/;
|
|
283
|
+
var SOLANA_ADDRESS_LENGTH_RE = /^.{32,44}$/;
|
|
284
|
+
var lamportsSchema = zod.z.number().int().positive().max(MAX_SAFE_LAMPORTS, `amount must be <= ${MAX_SAFE_LAMPORTS}`);
|
|
285
|
+
var feeAmountSchema = zod.z.number().int().nonnegative().max(MAX_SAFE_LAMPORTS, `fee_amount must be <= ${MAX_SAFE_LAMPORTS}`);
|
|
286
|
+
var solanaAddressSchema = zod.z.string().regex(BASE58_RE, "must be base58").regex(SOLANA_ADDRESS_LENGTH_RE, "must be 32-44 base58 chars");
|
|
287
|
+
var PaymentRequestSchema = zod.z.object({
|
|
288
|
+
recipient: solanaAddressSchema,
|
|
289
|
+
amount: lamportsSchema,
|
|
290
|
+
reference: solanaAddressSchema,
|
|
291
|
+
description: zod.z.string().max(MAX_DESCRIPTION_LENGTH).optional(),
|
|
292
|
+
fee_address: solanaAddressSchema.optional(),
|
|
293
|
+
fee_amount: feeAmountSchema.optional(),
|
|
294
|
+
created_at: zod.z.number().int().positive(),
|
|
295
|
+
expiry_secs: zod.z.number().int().positive().max(MAX_EXPIRY_SECS_SCHEMA, `expiry_secs must be <= ${MAX_EXPIRY_SECS_SCHEMA}`)
|
|
296
|
+
});
|
|
297
|
+
function parsePaymentRequest(input, options) {
|
|
298
|
+
let parsed;
|
|
299
|
+
try {
|
|
300
|
+
parsed = JSON.parse(input);
|
|
301
|
+
} catch (e) {
|
|
302
|
+
return {
|
|
303
|
+
ok: false,
|
|
304
|
+
error: { code: "invalid_json", message: `Invalid payment request JSON: ${e}` }
|
|
305
|
+
};
|
|
306
|
+
}
|
|
307
|
+
const result = PaymentRequestSchema.safeParse(parsed);
|
|
308
|
+
if (!result.success) {
|
|
309
|
+
return {
|
|
310
|
+
ok: false,
|
|
311
|
+
error: { code: "schema", message: result.error.message }
|
|
312
|
+
};
|
|
313
|
+
}
|
|
314
|
+
if (options?.maxAmountLamports !== void 0) {
|
|
315
|
+
if (BigInt(result.data.amount) > options.maxAmountLamports) {
|
|
316
|
+
return {
|
|
317
|
+
ok: false,
|
|
318
|
+
error: {
|
|
319
|
+
code: "amount_exceeds_max",
|
|
320
|
+
message: `Payment amount ${result.data.amount} lamports exceeds approved max ${options.maxAmountLamports}.`
|
|
321
|
+
}
|
|
322
|
+
};
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
return { ok: true, data: result.data };
|
|
326
|
+
}
|
|
327
|
+
|
|
218
328
|
// src/payment/solana.ts
|
|
329
|
+
var DEFAULT_COMPUTE_UNIT_LIMIT = 2e5;
|
|
330
|
+
var DEFAULT_PRIORITY_FEE_PERCENTILE = 75;
|
|
219
331
|
var REFERENCE_BYTE_LENGTH = 32;
|
|
220
332
|
function isValidSolanaAddress(value) {
|
|
221
333
|
return kit.isAddress(value);
|
|
@@ -272,32 +384,27 @@ var SolanaPaymentStrategy = class {
|
|
|
272
384
|
expiry_secs: expirySecs
|
|
273
385
|
};
|
|
274
386
|
}
|
|
275
|
-
validatePaymentRequest(requestJson, config, expectedRecipient) {
|
|
387
|
+
validatePaymentRequest(requestJson, config, expectedRecipient, options) {
|
|
276
388
|
assertConfig(config);
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
code: "invalid_amount",
|
|
286
|
-
|
|
287
|
-
};
|
|
288
|
-
}
|
|
289
|
-
if (typeof data.recipient !== "string" || !data.recipient) {
|
|
290
|
-
return { code: "missing_recipient", message: "Missing recipient in payment request" };
|
|
389
|
+
const parsed = parsePaymentRequest(requestJson, {
|
|
390
|
+
maxAmountLamports: options?.maxAmountLamports
|
|
391
|
+
});
|
|
392
|
+
if (!parsed.ok) {
|
|
393
|
+
if (parsed.error.code === "invalid_json") {
|
|
394
|
+
return { code: "invalid_json", message: parsed.error.message };
|
|
395
|
+
}
|
|
396
|
+
if (parsed.error.code === "amount_exceeds_max") {
|
|
397
|
+
return { code: "invalid_amount", message: parsed.error.message };
|
|
398
|
+
}
|
|
399
|
+
return { code: "invalid_amount", message: parsed.error.message };
|
|
291
400
|
}
|
|
401
|
+
const data = parsed.data;
|
|
292
402
|
if (!isValidSolanaAddress(data.recipient)) {
|
|
293
403
|
return {
|
|
294
404
|
code: "invalid_recipient_address",
|
|
295
405
|
message: `Invalid Solana address for recipient: ${data.recipient}`
|
|
296
406
|
};
|
|
297
407
|
}
|
|
298
|
-
if (typeof data.reference !== "string" || !data.reference) {
|
|
299
|
-
return { code: "missing_reference", message: "Missing reference in payment request" };
|
|
300
|
-
}
|
|
301
408
|
if (!isValidSolanaAddress(data.reference)) {
|
|
302
409
|
return {
|
|
303
410
|
code: "invalid_reference_address",
|
|
@@ -357,7 +464,7 @@ var SolanaPaymentStrategy = class {
|
|
|
357
464
|
* read-only, non-signer account so providers can detect the payment via
|
|
358
465
|
* `getSignaturesForAddress(reference)`.
|
|
359
466
|
*/
|
|
360
|
-
async buildTransaction(paymentRequest, payerSigner, rpc, config) {
|
|
467
|
+
async buildTransaction(paymentRequest, payerSigner, rpc, config, options) {
|
|
361
468
|
assertConfig(config);
|
|
362
469
|
assertLamports(paymentRequest.amount, "payment amount");
|
|
363
470
|
if (paymentRequest.amount === 0) {
|
|
@@ -376,14 +483,23 @@ var SolanaPaymentStrategy = class {
|
|
|
376
483
|
`Invalid fee address: expected ${treasury}, got ${paymentRequest.fee_address}. Cannot build transaction with redirected fees.`
|
|
377
484
|
);
|
|
378
485
|
}
|
|
379
|
-
const
|
|
486
|
+
const computeUnitLimit = options?.computeUnitLimit ?? DEFAULT_COMPUTE_UNIT_LIMIT;
|
|
487
|
+
if (!Number.isInteger(computeUnitLimit) || computeUnitLimit <= 0) {
|
|
488
|
+
throw new Error(`Invalid computeUnitLimit: ${computeUnitLimit}. Must be a positive integer.`);
|
|
489
|
+
}
|
|
490
|
+
const paymentInstructions = buildPaymentInstructions(paymentRequest, payerSigner);
|
|
491
|
+
const priorityFeeMicroLamports = options?.priorityFeeMicroLamports ?? await estimatePriorityFeeMicroLamports(rpc, {
|
|
492
|
+
percentile: options?.priorityFeePercentile ?? DEFAULT_PRIORITY_FEE_PERCENTILE
|
|
493
|
+
});
|
|
380
494
|
const { value: latestBlockhash } = await rpc.getLatestBlockhash().send();
|
|
381
495
|
const message = kit.pipe(
|
|
382
496
|
kit.createTransactionMessage({ version: 0 }),
|
|
383
497
|
(m) => kit.setTransactionMessageFeePayerSigner(payerSigner, m),
|
|
384
498
|
(m) => kit.setTransactionMessageLifetimeUsingBlockhash(latestBlockhash, m),
|
|
499
|
+
(m) => kit.setTransactionMessageComputeUnitLimit(computeUnitLimit, m),
|
|
500
|
+
(m) => kit.setTransactionMessageComputeUnitPrice(priorityFeeMicroLamports, m),
|
|
385
501
|
(m) => kit.appendTransactionMessageInstructions(
|
|
386
|
-
|
|
502
|
+
paymentInstructions,
|
|
387
503
|
m
|
|
388
504
|
)
|
|
389
505
|
);
|
|
@@ -2295,9 +2411,6 @@ function validateAgentName(name) {
|
|
|
2295
2411
|
throw new Error("Agent name must be 1-64 characters, alphanumeric, underscore, or hyphen.");
|
|
2296
2412
|
}
|
|
2297
2413
|
}
|
|
2298
|
-
function serializeConfig(config) {
|
|
2299
|
-
return JSON.stringify(config, null, 2) + "\n";
|
|
2300
|
-
}
|
|
2301
2414
|
|
|
2302
2415
|
exports.BoundedSet = BoundedSet;
|
|
2303
2416
|
exports.DEFAULTS = DEFAULTS;
|
|
@@ -2321,6 +2434,7 @@ exports.NostrPool = NostrPool;
|
|
|
2321
2434
|
exports.PROTOCOL_FEE_BPS = PROTOCOL_FEE_BPS;
|
|
2322
2435
|
exports.PROTOCOL_PROGRAM_ID_DEVNET = PROTOCOL_PROGRAM_ID_DEVNET;
|
|
2323
2436
|
exports.PROTOCOL_TREASURY = PROTOCOL_TREASURY;
|
|
2437
|
+
exports.PaymentRequestSchema = PaymentRequestSchema;
|
|
2324
2438
|
exports.PingService = PingService;
|
|
2325
2439
|
exports.RELAYS = RELAYS;
|
|
2326
2440
|
exports.SolanaPaymentStrategy = SolanaPaymentStrategy;
|
|
@@ -2328,8 +2442,10 @@ exports.assertExpiry = assertExpiry;
|
|
|
2328
2442
|
exports.assertLamports = assertLamports;
|
|
2329
2443
|
exports.buildPaymentInstructions = buildPaymentInstructions;
|
|
2330
2444
|
exports.calculateProtocolFee = calculateProtocolFee;
|
|
2445
|
+
exports.clearPriorityFeeCache = clearPriorityFeeCache;
|
|
2331
2446
|
exports.clearProtocolConfigCache = clearProtocolConfigCache;
|
|
2332
2447
|
exports.createPaymentRequestWithOnchainConfig = createPaymentRequestWithOnchainConfig;
|
|
2448
|
+
exports.estimatePriorityFeeMicroLamports = estimatePriorityFeeMicroLamports;
|
|
2333
2449
|
exports.formatSol = formatSol;
|
|
2334
2450
|
exports.getProtocolConfig = getProtocolConfig;
|
|
2335
2451
|
exports.getProtocolProgramId = getProtocolProgramId;
|
|
@@ -2337,7 +2453,8 @@ exports.jobRequestKind = jobRequestKind;
|
|
|
2337
2453
|
exports.jobResultKind = jobResultKind;
|
|
2338
2454
|
exports.nip44Decrypt = nip44Decrypt;
|
|
2339
2455
|
exports.nip44Encrypt = nip44Encrypt;
|
|
2340
|
-
exports.
|
|
2456
|
+
exports.parsePaymentRequest = parsePaymentRequest;
|
|
2457
|
+
exports.pickPercentileFee = pickPercentileFee;
|
|
2341
2458
|
exports.timeAgo = timeAgo;
|
|
2342
2459
|
exports.toDTag = toDTag;
|
|
2343
2460
|
exports.truncateKey = truncateKey;
|