@elisym/sdk 0.3.2 → 0.4.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/README.md +2 -2
- package/dist/index.cjs +352 -166
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +166 -26
- package/dist/index.d.ts +166 -26
- package/dist/index.js +347 -167
- package/dist/index.js.map +1 -1
- package/package.json +6 -3
package/dist/index.d.cts
CHANGED
|
@@ -1,41 +1,75 @@
|
|
|
1
|
+
import { Address, TransactionSigner, Rpc, SolanaRpcApi } from '@solana/kit';
|
|
1
2
|
import { P as PaymentRequestData, a as PaymentValidationError, V as VerifyOptions, b as VerifyResult, S as SubCloser, N as Network, A as Agent, E as ElisymIdentity, C as CapabilityCard, c as SubmitJobOptions, J as JobSubscriptionOptions, d as Job, e as PingResult, f as ElisymClientConfig, g as AgentConfig } from './types-CII4k_8d.cjs';
|
|
2
3
|
export { h as Capability, I as Identity, i as JobStatus, j as JobUpdateCallbacks, L as LlmConfig, k as NetworkStats, l as PaymentAddress, m as PaymentInfo, n as PaymentValidationCode, W as WalletConfig } from './types-CII4k_8d.cjs';
|
|
3
4
|
import { Filter, Event } from 'nostr-tools';
|
|
4
|
-
import { Transaction } from '@solana/web3.js';
|
|
5
5
|
|
|
6
|
+
/**
|
|
7
|
+
* Protocol fee + treasury inputs for building a payment request.
|
|
8
|
+
*
|
|
9
|
+
* In Phase 2 the SDK no longer reads PROTOCOL_FEE_BPS / PROTOCOL_TREASURY
|
|
10
|
+
* from constants. Callers supply this config so they can either pass
|
|
11
|
+
* the bundled fallbacks or, in Phase 3, values fetched from the on-chain
|
|
12
|
+
* elisym-config program.
|
|
13
|
+
*/
|
|
14
|
+
interface ProtocolConfigInput {
|
|
15
|
+
/** Protocol fee in basis points (300 = 3%). Must be a non-negative integer. */
|
|
16
|
+
feeBps: number;
|
|
17
|
+
/** Solana address of the protocol treasury. */
|
|
18
|
+
treasury: Address;
|
|
19
|
+
}
|
|
6
20
|
/**
|
|
7
21
|
* Pluggable payment strategy interface.
|
|
8
22
|
* Implement this for each payment chain (Solana, Lightning, Cashu, EVM).
|
|
23
|
+
*
|
|
24
|
+
* The interface is intentionally generic about the on-chain transaction type
|
|
25
|
+
* (`unknown` for build/verify inputs) so future chains can plug in without
|
|
26
|
+
* pulling Solana types into shared code paths.
|
|
9
27
|
*/
|
|
10
28
|
interface PaymentStrategy {
|
|
11
29
|
readonly chain: string;
|
|
12
30
|
/** Calculate protocol fee using basis-point math. */
|
|
13
|
-
calculateFee(amount: number): number;
|
|
31
|
+
calculateFee(amount: number, config: ProtocolConfigInput): number;
|
|
14
32
|
/** Create a payment request with auto-calculated protocol fee. */
|
|
15
|
-
createPaymentRequest(recipientAddress: string, amount: number,
|
|
33
|
+
createPaymentRequest(recipientAddress: string, amount: number, config: ProtocolConfigInput, options?: {
|
|
34
|
+
expirySecs?: number;
|
|
35
|
+
}): PaymentRequestData;
|
|
16
36
|
/**
|
|
17
37
|
* Validate that a payment request has the correct recipient and protocol fee.
|
|
18
38
|
* Returns a typed validation error if invalid, null if OK.
|
|
19
39
|
*/
|
|
20
|
-
validatePaymentRequest(requestJson: string, expectedRecipient?: string): PaymentValidationError | null;
|
|
40
|
+
validatePaymentRequest(requestJson: string, config: ProtocolConfigInput, expectedRecipient?: string): PaymentValidationError | null;
|
|
21
41
|
/**
|
|
22
|
-
* Build
|
|
23
|
-
* Returns chain-specific transaction
|
|
24
|
-
*
|
|
42
|
+
* Build and sign a transaction from a payment request using a TransactionSigner.
|
|
43
|
+
* Returns a chain-specific signed transaction value. The caller is responsible
|
|
44
|
+
* for sending it (e.g. via `rpc.sendTransaction(...).send()`).
|
|
25
45
|
*/
|
|
26
|
-
buildTransaction(
|
|
46
|
+
buildTransaction(paymentRequest: PaymentRequestData, payerSigner: TransactionSigner, rpc: Rpc<SolanaRpcApi>, config: ProtocolConfigInput): Promise<unknown>;
|
|
27
47
|
/**
|
|
28
48
|
* Verify a payment on-chain.
|
|
29
|
-
* @param connection Chain-specific connection (e.g. Solana `Connection`).
|
|
30
49
|
*/
|
|
31
|
-
verifyPayment(
|
|
50
|
+
verifyPayment(rpc: Rpc<SolanaRpcApi>, paymentRequest: PaymentRequestData, config: ProtocolConfigInput, options?: VerifyOptions): Promise<VerifyResult>;
|
|
32
51
|
}
|
|
33
52
|
|
|
34
53
|
declare class NostrPool {
|
|
35
54
|
private pool;
|
|
36
55
|
private relays;
|
|
37
56
|
private activeSubscriptions;
|
|
57
|
+
private resetListeners;
|
|
38
58
|
constructor(relays?: string[]);
|
|
59
|
+
/**
|
|
60
|
+
* Register a callback to run after `reset()` completes (new SimplePool in place).
|
|
61
|
+
* Services that cache pool-derived state (e.g. ping results) must clear it here,
|
|
62
|
+
* otherwise stale values survive the reconnect. Returns an unsubscribe function.
|
|
63
|
+
*
|
|
64
|
+
* Contract:
|
|
65
|
+
* - Listeners are invoked **synchronously** at the end of `reset()`, in
|
|
66
|
+
* registration order. Do not rely on async work inside a listener having
|
|
67
|
+
* completed before `reset()` returns.
|
|
68
|
+
* - Listener exceptions are caught and swallowed so that one faulty listener
|
|
69
|
+
* cannot prevent the others from running (or abort the reset itself).
|
|
70
|
+
* If a listener needs to surface errors, it must do so out-of-band.
|
|
71
|
+
*/
|
|
72
|
+
onReset(listener: () => void): () => void;
|
|
39
73
|
/** Query relays synchronously. Returns `[]` on timeout (no error thrown). */
|
|
40
74
|
querySync(filter: Filter): Promise<Event[]>;
|
|
41
75
|
queryBatched(filter: Omit<Filter, 'authors'>, keys: string[], batchSize?: number, maxConcurrency?: number): Promise<Event[]>;
|
|
@@ -189,6 +223,20 @@ declare class MediaService {
|
|
|
189
223
|
* this instance - recreating the service generates a new keypair.
|
|
190
224
|
*
|
|
191
225
|
* Requires `globalThis.crypto` (Node 20+, Bun, browsers).
|
|
226
|
+
*
|
|
227
|
+
* Lifetime / cleanup:
|
|
228
|
+
* - The constructor registers a listener on `pool.onReset()` and never
|
|
229
|
+
* unsubscribes. This is intentional: PingService is expected to share its
|
|
230
|
+
* lifetime with the NostrPool it is bound to (both live for the lifetime
|
|
231
|
+
* of an ElisymClient). If you ever construct a PingService that outlives
|
|
232
|
+
* its pool - or vice versa - add an explicit `dispose()` that calls the
|
|
233
|
+
* unsubscribe function returned by `pool.onReset()` to avoid leaking a
|
|
234
|
+
* reference to this instance through the pool's listener set.
|
|
235
|
+
* - `clearCache()` drops cached online results but does NOT cancel in-flight
|
|
236
|
+
* pings in `pendingPings`. An in-flight ping started before a pool reset
|
|
237
|
+
* may return `online: false` even if the new pool is healthy; the next
|
|
238
|
+
* ping attempt will go through the fresh subscription and resolve
|
|
239
|
+
* correctly.
|
|
192
240
|
*/
|
|
193
241
|
declare class PingService {
|
|
194
242
|
private pool;
|
|
@@ -197,6 +245,9 @@ declare class PingService {
|
|
|
197
245
|
private pingCache;
|
|
198
246
|
private pendingPings;
|
|
199
247
|
constructor(pool: NostrPool);
|
|
248
|
+
/** Drop cached online results. In-flight pings are left alone - they'll
|
|
249
|
+
* resolve via their own timeouts and remove themselves from `pendingPings`. */
|
|
250
|
+
clearCache(): void;
|
|
200
251
|
/**
|
|
201
252
|
* Ping an agent via ephemeral Nostr events (kind 20200/20201).
|
|
202
253
|
* Uses a persistent session identity to avoid relay rate-limiting.
|
|
@@ -233,33 +284,98 @@ declare class ElisymClient {
|
|
|
233
284
|
|
|
234
285
|
declare class SolanaPaymentStrategy implements PaymentStrategy {
|
|
235
286
|
readonly chain = "solana";
|
|
236
|
-
calculateFee(amount: number): number;
|
|
237
|
-
createPaymentRequest(recipientAddress: string, amount: number,
|
|
238
|
-
|
|
287
|
+
calculateFee(amount: number, config: ProtocolConfigInput): number;
|
|
288
|
+
createPaymentRequest(recipientAddress: string, amount: number, config: ProtocolConfigInput, options?: {
|
|
289
|
+
expirySecs?: number;
|
|
290
|
+
}): PaymentRequestData;
|
|
291
|
+
validatePaymentRequest(requestJson: string, config: ProtocolConfigInput, expectedRecipient?: string): PaymentValidationError | null;
|
|
239
292
|
/**
|
|
240
|
-
* Build
|
|
241
|
-
* The caller
|
|
242
|
-
*
|
|
293
|
+
* Build, sign, and return a transaction for the supplied payment request.
|
|
294
|
+
* The caller is responsible for sending it (e.g. via `rpc.sendTransaction`).
|
|
295
|
+
*
|
|
296
|
+
* The provider transfer instruction includes the payment reference as a
|
|
297
|
+
* read-only, non-signer account so providers can detect the payment via
|
|
298
|
+
* `getSignaturesForAddress(reference)`.
|
|
243
299
|
*/
|
|
244
|
-
buildTransaction(
|
|
245
|
-
verifyPayment(
|
|
300
|
+
buildTransaction(paymentRequest: PaymentRequestData, payerSigner: TransactionSigner, rpc: Rpc<SolanaRpcApi>, config: ProtocolConfigInput): Promise<Readonly<unknown>>;
|
|
301
|
+
verifyPayment(rpc: Rpc<SolanaRpcApi>, paymentRequest: PaymentRequestData, config: ProtocolConfigInput, options?: VerifyOptions): Promise<VerifyResult>;
|
|
246
302
|
private _verifyBySignature;
|
|
247
303
|
private _verifyByReference;
|
|
248
304
|
}
|
|
305
|
+
/**
|
|
306
|
+
* Build the System program transfer instructions for a payment request.
|
|
307
|
+
*
|
|
308
|
+
* Returns the provider-amount transfer (with the payment reference attached
|
|
309
|
+
* as a read-only, non-signer account) and, if present, the protocol-fee
|
|
310
|
+
* transfer. Exposed so callers and tests can inspect amounts before signing.
|
|
311
|
+
*
|
|
312
|
+
* Caller is responsible for validating `paymentRequest` upstream;
|
|
313
|
+
* `buildTransaction` already does that before invoking this helper.
|
|
314
|
+
*/
|
|
315
|
+
declare function buildPaymentInstructions(paymentRequest: PaymentRequestData, payerSigner: TransactionSigner): readonly unknown[];
|
|
316
|
+
/**
|
|
317
|
+
* Convenience wrapper: fetch the on-chain protocol config first, then build a
|
|
318
|
+
* payment request using its current fee/treasury values.
|
|
319
|
+
*
|
|
320
|
+
* Suitable for callers that want to "do the right thing" without managing the
|
|
321
|
+
* config cache or the SolanaPaymentStrategy instance themselves. Uses the same
|
|
322
|
+
* cache as `getProtocolConfig`, so back-to-back calls within the TTL only hit
|
|
323
|
+
* RPC once.
|
|
324
|
+
*/
|
|
325
|
+
declare function createPaymentRequestWithOnchainConfig(rpc: Rpc<SolanaRpcApi>, programId: Address, recipient: string, amount: number, options?: {
|
|
326
|
+
expirySecs?: number;
|
|
327
|
+
}): Promise<PaymentRequestData>;
|
|
249
328
|
|
|
250
329
|
/** Assert that a value is a non-negative integer (lamports). */
|
|
251
330
|
declare function assertLamports(value: number, field: string): void;
|
|
252
331
|
/**
|
|
253
|
-
* Calculate protocol fee using
|
|
254
|
-
* Returns ceil(amount *
|
|
255
|
-
*
|
|
332
|
+
* Calculate the protocol fee using basis-point math (no floats).
|
|
333
|
+
* Returns ceil(amount * feeBps / 10000).
|
|
334
|
+
*
|
|
335
|
+
* The caller passes the current fee (in basis points). Phase 2 of the
|
|
336
|
+
* Solana Kit migration removes the implicit dependency on PROTOCOL_FEE_BPS
|
|
337
|
+
* so callers can supply on-chain or test values.
|
|
256
338
|
*/
|
|
257
|
-
declare function calculateProtocolFee(amount: number): number;
|
|
339
|
+
declare function calculateProtocolFee(amount: number, feeBps: number): number;
|
|
258
340
|
/** Validate payment request timestamps. Returns error message or null if valid. */
|
|
259
341
|
declare function validateExpiry(createdAt: number, expirySecs: number): string | null;
|
|
260
342
|
/** Assert that payment request timestamps are valid and not expired. Throws on failure. */
|
|
261
343
|
declare function assertExpiry(createdAt: number, expirySecs: number): void;
|
|
262
344
|
|
|
345
|
+
/**
|
|
346
|
+
* Snapshot of the on-chain elisym-config program state.
|
|
347
|
+
*
|
|
348
|
+
* `source` reflects how this snapshot was obtained:
|
|
349
|
+
* - `onchain`: fresh fetch via RPC.
|
|
350
|
+
* - `cache`: served from in-memory cache (still within TTL or stale-while-error).
|
|
351
|
+
*
|
|
352
|
+
* If RPC fails and no cached value exists, `getProtocolConfig` throws instead of
|
|
353
|
+
* returning stale hardcoded defaults - callers must handle the error explicitly.
|
|
354
|
+
*/
|
|
355
|
+
interface ProtocolConfig {
|
|
356
|
+
programId: Address;
|
|
357
|
+
feeBps: number;
|
|
358
|
+
treasury: Address;
|
|
359
|
+
admin: Address;
|
|
360
|
+
pendingAdmin: Address | null;
|
|
361
|
+
paused: boolean;
|
|
362
|
+
version: number;
|
|
363
|
+
source: 'onchain' | 'cache';
|
|
364
|
+
}
|
|
365
|
+
declare function clearProtocolConfigCache(): void;
|
|
366
|
+
interface GetProtocolConfigOptions {
|
|
367
|
+
ttlMs?: number;
|
|
368
|
+
forceRefresh?: boolean;
|
|
369
|
+
}
|
|
370
|
+
/**
|
|
371
|
+
* Fetch the protocol config from the on-chain `elisym-config` program.
|
|
372
|
+
*
|
|
373
|
+
* Caches per-program-id with a TTL (default 60s). On RPC error, returns the
|
|
374
|
+
* last known good snapshot from cache. If nothing is cached, throws - callers
|
|
375
|
+
* must handle the error (e.g. refuse the payment, show a warning).
|
|
376
|
+
*/
|
|
377
|
+
declare function getProtocolConfig(rpc: Rpc<SolanaRpcApi>, programId: Address, options?: GetProtocolConfigOptions): Promise<ProtocolConfig>;
|
|
378
|
+
|
|
263
379
|
/** Encrypt plaintext using NIP-44 v2 (sender secret key + recipient public key). */
|
|
264
380
|
declare function nip44Encrypt(plaintext: string, senderSk: Uint8Array, recipientPubkey: string): string;
|
|
265
381
|
/** Decrypt ciphertext using NIP-44 v2 (receiver secret key + sender public key). */
|
|
@@ -309,10 +425,34 @@ declare function jobResultKind(offset: number): number;
|
|
|
309
425
|
declare const KIND_PING = 20200;
|
|
310
426
|
declare const KIND_PONG = 20201;
|
|
311
427
|
declare const LAMPORTS_PER_SOL = 1000000000;
|
|
312
|
-
/**
|
|
428
|
+
/**
|
|
429
|
+
* @deprecated Fallback only - use `getProtocolConfig(rpc, programId)` for live values.
|
|
430
|
+
*
|
|
431
|
+
* Protocol fee in basis points (300 = 3%). Bundled as a default for offline use
|
|
432
|
+
* and for first-call before the on-chain config has been fetched. The on-chain
|
|
433
|
+
* `elisym-config` program is the source of truth.
|
|
434
|
+
*/
|
|
313
435
|
declare const PROTOCOL_FEE_BPS = 300;
|
|
314
|
-
/**
|
|
315
|
-
|
|
436
|
+
/**
|
|
437
|
+
* @deprecated Fallback only - use `getProtocolConfig(rpc, programId)` for live values.
|
|
438
|
+
*
|
|
439
|
+
* Solana address of the protocol treasury. Bundled fallback; the on-chain
|
|
440
|
+
* `elisym-config` program is the source of truth and may rotate this address.
|
|
441
|
+
*/
|
|
442
|
+
declare const PROTOCOL_TREASURY: Address;
|
|
443
|
+
/**
|
|
444
|
+
* Solana program ID for the elisym protocol config (devnet deployment).
|
|
445
|
+
*
|
|
446
|
+
* The Anchor program at this address is the source of truth for fee bps,
|
|
447
|
+
* treasury address, and admin rotation state. Read via `getProtocolConfig`.
|
|
448
|
+
*/
|
|
449
|
+
declare const PROTOCOL_PROGRAM_ID_DEVNET: Address;
|
|
450
|
+
type ProtocolCluster = 'devnet' | 'mainnet' | 'localnet';
|
|
451
|
+
/**
|
|
452
|
+
* Resolve the elisym-config program ID for a given Solana cluster.
|
|
453
|
+
* Mainnet is intentionally unsupported until the program ships there.
|
|
454
|
+
*/
|
|
455
|
+
declare function getProtocolProgramId(cluster: ProtocolCluster): Address;
|
|
316
456
|
/** Default values for timeouts, retries, and batch sizes. */
|
|
317
457
|
declare const DEFAULTS: {
|
|
318
458
|
readonly SUBSCRIPTION_TIMEOUT_MS: 120000;
|
|
@@ -342,4 +482,4 @@ declare const LIMITS: {
|
|
|
342
482
|
readonly MAX_CAPABILITY_LENGTH: 64;
|
|
343
483
|
};
|
|
344
484
|
|
|
345
|
-
export { Agent, AgentConfig, BoundedSet, CapabilityCard, DEFAULTS, DEFAULT_KIND_OFFSET, DiscoveryService, ElisymClient, ElisymClientConfig, type ElisymClientFullConfig, ElisymIdentity, Job, JobSubscriptionOptions, KIND_APP_HANDLER, KIND_JOB_FEEDBACK, KIND_JOB_REQUEST, KIND_JOB_REQUEST_BASE, KIND_JOB_RESULT, KIND_JOB_RESULT_BASE, KIND_PING, KIND_PONG, LAMPORTS_PER_SOL, LIMITS, MarketplaceService, MediaService, Network, NostrPool, PROTOCOL_FEE_BPS, PROTOCOL_TREASURY, PaymentRequestData, type PaymentStrategy, PaymentValidationError, PingResult, PingService, RELAYS, SolanaPaymentStrategy, SubCloser, SubmitJobOptions, VerifyOptions, VerifyResult, assertExpiry, assertLamports, calculateProtocolFee, formatSol, jobRequestKind, jobResultKind, nip44Decrypt, nip44Encrypt, serializeConfig, timeAgo, toDTag, truncateKey, validateAgentName, validateExpiry };
|
|
485
|
+
export { Agent, AgentConfig, BoundedSet, CapabilityCard, DEFAULTS, DEFAULT_KIND_OFFSET, DiscoveryService, ElisymClient, ElisymClientConfig, type ElisymClientFullConfig, ElisymIdentity, type GetProtocolConfigOptions, Job, JobSubscriptionOptions, KIND_APP_HANDLER, KIND_JOB_FEEDBACK, KIND_JOB_REQUEST, KIND_JOB_REQUEST_BASE, KIND_JOB_RESULT, KIND_JOB_RESULT_BASE, KIND_PING, KIND_PONG, LAMPORTS_PER_SOL, LIMITS, MarketplaceService, MediaService, Network, NostrPool, PROTOCOL_FEE_BPS, PROTOCOL_PROGRAM_ID_DEVNET, PROTOCOL_TREASURY, PaymentRequestData, type PaymentStrategy, PaymentValidationError, PingResult, PingService, type ProtocolCluster, type ProtocolConfig, type ProtocolConfigInput, RELAYS, SolanaPaymentStrategy, SubCloser, SubmitJobOptions, VerifyOptions, VerifyResult, assertExpiry, assertLamports, buildPaymentInstructions, calculateProtocolFee, clearProtocolConfigCache, createPaymentRequestWithOnchainConfig, formatSol, getProtocolConfig, getProtocolProgramId, jobRequestKind, jobResultKind, nip44Decrypt, nip44Encrypt, serializeConfig, timeAgo, toDTag, truncateKey, validateAgentName, validateExpiry };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,41 +1,75 @@
|
|
|
1
|
+
import { Address, TransactionSigner, Rpc, SolanaRpcApi } from '@solana/kit';
|
|
1
2
|
import { P as PaymentRequestData, a as PaymentValidationError, V as VerifyOptions, b as VerifyResult, S as SubCloser, N as Network, A as Agent, E as ElisymIdentity, C as CapabilityCard, c as SubmitJobOptions, J as JobSubscriptionOptions, d as Job, e as PingResult, f as ElisymClientConfig, g as AgentConfig } from './types-CII4k_8d.js';
|
|
2
3
|
export { h as Capability, I as Identity, i as JobStatus, j as JobUpdateCallbacks, L as LlmConfig, k as NetworkStats, l as PaymentAddress, m as PaymentInfo, n as PaymentValidationCode, W as WalletConfig } from './types-CII4k_8d.js';
|
|
3
4
|
import { Filter, Event } from 'nostr-tools';
|
|
4
|
-
import { Transaction } from '@solana/web3.js';
|
|
5
5
|
|
|
6
|
+
/**
|
|
7
|
+
* Protocol fee + treasury inputs for building a payment request.
|
|
8
|
+
*
|
|
9
|
+
* In Phase 2 the SDK no longer reads PROTOCOL_FEE_BPS / PROTOCOL_TREASURY
|
|
10
|
+
* from constants. Callers supply this config so they can either pass
|
|
11
|
+
* the bundled fallbacks or, in Phase 3, values fetched from the on-chain
|
|
12
|
+
* elisym-config program.
|
|
13
|
+
*/
|
|
14
|
+
interface ProtocolConfigInput {
|
|
15
|
+
/** Protocol fee in basis points (300 = 3%). Must be a non-negative integer. */
|
|
16
|
+
feeBps: number;
|
|
17
|
+
/** Solana address of the protocol treasury. */
|
|
18
|
+
treasury: Address;
|
|
19
|
+
}
|
|
6
20
|
/**
|
|
7
21
|
* Pluggable payment strategy interface.
|
|
8
22
|
* Implement this for each payment chain (Solana, Lightning, Cashu, EVM).
|
|
23
|
+
*
|
|
24
|
+
* The interface is intentionally generic about the on-chain transaction type
|
|
25
|
+
* (`unknown` for build/verify inputs) so future chains can plug in without
|
|
26
|
+
* pulling Solana types into shared code paths.
|
|
9
27
|
*/
|
|
10
28
|
interface PaymentStrategy {
|
|
11
29
|
readonly chain: string;
|
|
12
30
|
/** Calculate protocol fee using basis-point math. */
|
|
13
|
-
calculateFee(amount: number): number;
|
|
31
|
+
calculateFee(amount: number, config: ProtocolConfigInput): number;
|
|
14
32
|
/** Create a payment request with auto-calculated protocol fee. */
|
|
15
|
-
createPaymentRequest(recipientAddress: string, amount: number,
|
|
33
|
+
createPaymentRequest(recipientAddress: string, amount: number, config: ProtocolConfigInput, options?: {
|
|
34
|
+
expirySecs?: number;
|
|
35
|
+
}): PaymentRequestData;
|
|
16
36
|
/**
|
|
17
37
|
* Validate that a payment request has the correct recipient and protocol fee.
|
|
18
38
|
* Returns a typed validation error if invalid, null if OK.
|
|
19
39
|
*/
|
|
20
|
-
validatePaymentRequest(requestJson: string, expectedRecipient?: string): PaymentValidationError | null;
|
|
40
|
+
validatePaymentRequest(requestJson: string, config: ProtocolConfigInput, expectedRecipient?: string): PaymentValidationError | null;
|
|
21
41
|
/**
|
|
22
|
-
* Build
|
|
23
|
-
* Returns chain-specific transaction
|
|
24
|
-
*
|
|
42
|
+
* Build and sign a transaction from a payment request using a TransactionSigner.
|
|
43
|
+
* Returns a chain-specific signed transaction value. The caller is responsible
|
|
44
|
+
* for sending it (e.g. via `rpc.sendTransaction(...).send()`).
|
|
25
45
|
*/
|
|
26
|
-
buildTransaction(
|
|
46
|
+
buildTransaction(paymentRequest: PaymentRequestData, payerSigner: TransactionSigner, rpc: Rpc<SolanaRpcApi>, config: ProtocolConfigInput): Promise<unknown>;
|
|
27
47
|
/**
|
|
28
48
|
* Verify a payment on-chain.
|
|
29
|
-
* @param connection Chain-specific connection (e.g. Solana `Connection`).
|
|
30
49
|
*/
|
|
31
|
-
verifyPayment(
|
|
50
|
+
verifyPayment(rpc: Rpc<SolanaRpcApi>, paymentRequest: PaymentRequestData, config: ProtocolConfigInput, options?: VerifyOptions): Promise<VerifyResult>;
|
|
32
51
|
}
|
|
33
52
|
|
|
34
53
|
declare class NostrPool {
|
|
35
54
|
private pool;
|
|
36
55
|
private relays;
|
|
37
56
|
private activeSubscriptions;
|
|
57
|
+
private resetListeners;
|
|
38
58
|
constructor(relays?: string[]);
|
|
59
|
+
/**
|
|
60
|
+
* Register a callback to run after `reset()` completes (new SimplePool in place).
|
|
61
|
+
* Services that cache pool-derived state (e.g. ping results) must clear it here,
|
|
62
|
+
* otherwise stale values survive the reconnect. Returns an unsubscribe function.
|
|
63
|
+
*
|
|
64
|
+
* Contract:
|
|
65
|
+
* - Listeners are invoked **synchronously** at the end of `reset()`, in
|
|
66
|
+
* registration order. Do not rely on async work inside a listener having
|
|
67
|
+
* completed before `reset()` returns.
|
|
68
|
+
* - Listener exceptions are caught and swallowed so that one faulty listener
|
|
69
|
+
* cannot prevent the others from running (or abort the reset itself).
|
|
70
|
+
* If a listener needs to surface errors, it must do so out-of-band.
|
|
71
|
+
*/
|
|
72
|
+
onReset(listener: () => void): () => void;
|
|
39
73
|
/** Query relays synchronously. Returns `[]` on timeout (no error thrown). */
|
|
40
74
|
querySync(filter: Filter): Promise<Event[]>;
|
|
41
75
|
queryBatched(filter: Omit<Filter, 'authors'>, keys: string[], batchSize?: number, maxConcurrency?: number): Promise<Event[]>;
|
|
@@ -189,6 +223,20 @@ declare class MediaService {
|
|
|
189
223
|
* this instance - recreating the service generates a new keypair.
|
|
190
224
|
*
|
|
191
225
|
* Requires `globalThis.crypto` (Node 20+, Bun, browsers).
|
|
226
|
+
*
|
|
227
|
+
* Lifetime / cleanup:
|
|
228
|
+
* - The constructor registers a listener on `pool.onReset()` and never
|
|
229
|
+
* unsubscribes. This is intentional: PingService is expected to share its
|
|
230
|
+
* lifetime with the NostrPool it is bound to (both live for the lifetime
|
|
231
|
+
* of an ElisymClient). If you ever construct a PingService that outlives
|
|
232
|
+
* its pool - or vice versa - add an explicit `dispose()` that calls the
|
|
233
|
+
* unsubscribe function returned by `pool.onReset()` to avoid leaking a
|
|
234
|
+
* reference to this instance through the pool's listener set.
|
|
235
|
+
* - `clearCache()` drops cached online results but does NOT cancel in-flight
|
|
236
|
+
* pings in `pendingPings`. An in-flight ping started before a pool reset
|
|
237
|
+
* may return `online: false` even if the new pool is healthy; the next
|
|
238
|
+
* ping attempt will go through the fresh subscription and resolve
|
|
239
|
+
* correctly.
|
|
192
240
|
*/
|
|
193
241
|
declare class PingService {
|
|
194
242
|
private pool;
|
|
@@ -197,6 +245,9 @@ declare class PingService {
|
|
|
197
245
|
private pingCache;
|
|
198
246
|
private pendingPings;
|
|
199
247
|
constructor(pool: NostrPool);
|
|
248
|
+
/** Drop cached online results. In-flight pings are left alone - they'll
|
|
249
|
+
* resolve via their own timeouts and remove themselves from `pendingPings`. */
|
|
250
|
+
clearCache(): void;
|
|
200
251
|
/**
|
|
201
252
|
* Ping an agent via ephemeral Nostr events (kind 20200/20201).
|
|
202
253
|
* Uses a persistent session identity to avoid relay rate-limiting.
|
|
@@ -233,33 +284,98 @@ declare class ElisymClient {
|
|
|
233
284
|
|
|
234
285
|
declare class SolanaPaymentStrategy implements PaymentStrategy {
|
|
235
286
|
readonly chain = "solana";
|
|
236
|
-
calculateFee(amount: number): number;
|
|
237
|
-
createPaymentRequest(recipientAddress: string, amount: number,
|
|
238
|
-
|
|
287
|
+
calculateFee(amount: number, config: ProtocolConfigInput): number;
|
|
288
|
+
createPaymentRequest(recipientAddress: string, amount: number, config: ProtocolConfigInput, options?: {
|
|
289
|
+
expirySecs?: number;
|
|
290
|
+
}): PaymentRequestData;
|
|
291
|
+
validatePaymentRequest(requestJson: string, config: ProtocolConfigInput, expectedRecipient?: string): PaymentValidationError | null;
|
|
239
292
|
/**
|
|
240
|
-
* Build
|
|
241
|
-
* The caller
|
|
242
|
-
*
|
|
293
|
+
* Build, sign, and return a transaction for the supplied payment request.
|
|
294
|
+
* The caller is responsible for sending it (e.g. via `rpc.sendTransaction`).
|
|
295
|
+
*
|
|
296
|
+
* The provider transfer instruction includes the payment reference as a
|
|
297
|
+
* read-only, non-signer account so providers can detect the payment via
|
|
298
|
+
* `getSignaturesForAddress(reference)`.
|
|
243
299
|
*/
|
|
244
|
-
buildTransaction(
|
|
245
|
-
verifyPayment(
|
|
300
|
+
buildTransaction(paymentRequest: PaymentRequestData, payerSigner: TransactionSigner, rpc: Rpc<SolanaRpcApi>, config: ProtocolConfigInput): Promise<Readonly<unknown>>;
|
|
301
|
+
verifyPayment(rpc: Rpc<SolanaRpcApi>, paymentRequest: PaymentRequestData, config: ProtocolConfigInput, options?: VerifyOptions): Promise<VerifyResult>;
|
|
246
302
|
private _verifyBySignature;
|
|
247
303
|
private _verifyByReference;
|
|
248
304
|
}
|
|
305
|
+
/**
|
|
306
|
+
* Build the System program transfer instructions for a payment request.
|
|
307
|
+
*
|
|
308
|
+
* Returns the provider-amount transfer (with the payment reference attached
|
|
309
|
+
* as a read-only, non-signer account) and, if present, the protocol-fee
|
|
310
|
+
* transfer. Exposed so callers and tests can inspect amounts before signing.
|
|
311
|
+
*
|
|
312
|
+
* Caller is responsible for validating `paymentRequest` upstream;
|
|
313
|
+
* `buildTransaction` already does that before invoking this helper.
|
|
314
|
+
*/
|
|
315
|
+
declare function buildPaymentInstructions(paymentRequest: PaymentRequestData, payerSigner: TransactionSigner): readonly unknown[];
|
|
316
|
+
/**
|
|
317
|
+
* Convenience wrapper: fetch the on-chain protocol config first, then build a
|
|
318
|
+
* payment request using its current fee/treasury values.
|
|
319
|
+
*
|
|
320
|
+
* Suitable for callers that want to "do the right thing" without managing the
|
|
321
|
+
* config cache or the SolanaPaymentStrategy instance themselves. Uses the same
|
|
322
|
+
* cache as `getProtocolConfig`, so back-to-back calls within the TTL only hit
|
|
323
|
+
* RPC once.
|
|
324
|
+
*/
|
|
325
|
+
declare function createPaymentRequestWithOnchainConfig(rpc: Rpc<SolanaRpcApi>, programId: Address, recipient: string, amount: number, options?: {
|
|
326
|
+
expirySecs?: number;
|
|
327
|
+
}): Promise<PaymentRequestData>;
|
|
249
328
|
|
|
250
329
|
/** Assert that a value is a non-negative integer (lamports). */
|
|
251
330
|
declare function assertLamports(value: number, field: string): void;
|
|
252
331
|
/**
|
|
253
|
-
* Calculate protocol fee using
|
|
254
|
-
* Returns ceil(amount *
|
|
255
|
-
*
|
|
332
|
+
* Calculate the protocol fee using basis-point math (no floats).
|
|
333
|
+
* Returns ceil(amount * feeBps / 10000).
|
|
334
|
+
*
|
|
335
|
+
* The caller passes the current fee (in basis points). Phase 2 of the
|
|
336
|
+
* Solana Kit migration removes the implicit dependency on PROTOCOL_FEE_BPS
|
|
337
|
+
* so callers can supply on-chain or test values.
|
|
256
338
|
*/
|
|
257
|
-
declare function calculateProtocolFee(amount: number): number;
|
|
339
|
+
declare function calculateProtocolFee(amount: number, feeBps: number): number;
|
|
258
340
|
/** Validate payment request timestamps. Returns error message or null if valid. */
|
|
259
341
|
declare function validateExpiry(createdAt: number, expirySecs: number): string | null;
|
|
260
342
|
/** Assert that payment request timestamps are valid and not expired. Throws on failure. */
|
|
261
343
|
declare function assertExpiry(createdAt: number, expirySecs: number): void;
|
|
262
344
|
|
|
345
|
+
/**
|
|
346
|
+
* Snapshot of the on-chain elisym-config program state.
|
|
347
|
+
*
|
|
348
|
+
* `source` reflects how this snapshot was obtained:
|
|
349
|
+
* - `onchain`: fresh fetch via RPC.
|
|
350
|
+
* - `cache`: served from in-memory cache (still within TTL or stale-while-error).
|
|
351
|
+
*
|
|
352
|
+
* If RPC fails and no cached value exists, `getProtocolConfig` throws instead of
|
|
353
|
+
* returning stale hardcoded defaults - callers must handle the error explicitly.
|
|
354
|
+
*/
|
|
355
|
+
interface ProtocolConfig {
|
|
356
|
+
programId: Address;
|
|
357
|
+
feeBps: number;
|
|
358
|
+
treasury: Address;
|
|
359
|
+
admin: Address;
|
|
360
|
+
pendingAdmin: Address | null;
|
|
361
|
+
paused: boolean;
|
|
362
|
+
version: number;
|
|
363
|
+
source: 'onchain' | 'cache';
|
|
364
|
+
}
|
|
365
|
+
declare function clearProtocolConfigCache(): void;
|
|
366
|
+
interface GetProtocolConfigOptions {
|
|
367
|
+
ttlMs?: number;
|
|
368
|
+
forceRefresh?: boolean;
|
|
369
|
+
}
|
|
370
|
+
/**
|
|
371
|
+
* Fetch the protocol config from the on-chain `elisym-config` program.
|
|
372
|
+
*
|
|
373
|
+
* Caches per-program-id with a TTL (default 60s). On RPC error, returns the
|
|
374
|
+
* last known good snapshot from cache. If nothing is cached, throws - callers
|
|
375
|
+
* must handle the error (e.g. refuse the payment, show a warning).
|
|
376
|
+
*/
|
|
377
|
+
declare function getProtocolConfig(rpc: Rpc<SolanaRpcApi>, programId: Address, options?: GetProtocolConfigOptions): Promise<ProtocolConfig>;
|
|
378
|
+
|
|
263
379
|
/** Encrypt plaintext using NIP-44 v2 (sender secret key + recipient public key). */
|
|
264
380
|
declare function nip44Encrypt(plaintext: string, senderSk: Uint8Array, recipientPubkey: string): string;
|
|
265
381
|
/** Decrypt ciphertext using NIP-44 v2 (receiver secret key + sender public key). */
|
|
@@ -309,10 +425,34 @@ declare function jobResultKind(offset: number): number;
|
|
|
309
425
|
declare const KIND_PING = 20200;
|
|
310
426
|
declare const KIND_PONG = 20201;
|
|
311
427
|
declare const LAMPORTS_PER_SOL = 1000000000;
|
|
312
|
-
/**
|
|
428
|
+
/**
|
|
429
|
+
* @deprecated Fallback only - use `getProtocolConfig(rpc, programId)` for live values.
|
|
430
|
+
*
|
|
431
|
+
* Protocol fee in basis points (300 = 3%). Bundled as a default for offline use
|
|
432
|
+
* and for first-call before the on-chain config has been fetched. The on-chain
|
|
433
|
+
* `elisym-config` program is the source of truth.
|
|
434
|
+
*/
|
|
313
435
|
declare const PROTOCOL_FEE_BPS = 300;
|
|
314
|
-
/**
|
|
315
|
-
|
|
436
|
+
/**
|
|
437
|
+
* @deprecated Fallback only - use `getProtocolConfig(rpc, programId)` for live values.
|
|
438
|
+
*
|
|
439
|
+
* Solana address of the protocol treasury. Bundled fallback; the on-chain
|
|
440
|
+
* `elisym-config` program is the source of truth and may rotate this address.
|
|
441
|
+
*/
|
|
442
|
+
declare const PROTOCOL_TREASURY: Address;
|
|
443
|
+
/**
|
|
444
|
+
* Solana program ID for the elisym protocol config (devnet deployment).
|
|
445
|
+
*
|
|
446
|
+
* The Anchor program at this address is the source of truth for fee bps,
|
|
447
|
+
* treasury address, and admin rotation state. Read via `getProtocolConfig`.
|
|
448
|
+
*/
|
|
449
|
+
declare const PROTOCOL_PROGRAM_ID_DEVNET: Address;
|
|
450
|
+
type ProtocolCluster = 'devnet' | 'mainnet' | 'localnet';
|
|
451
|
+
/**
|
|
452
|
+
* Resolve the elisym-config program ID for a given Solana cluster.
|
|
453
|
+
* Mainnet is intentionally unsupported until the program ships there.
|
|
454
|
+
*/
|
|
455
|
+
declare function getProtocolProgramId(cluster: ProtocolCluster): Address;
|
|
316
456
|
/** Default values for timeouts, retries, and batch sizes. */
|
|
317
457
|
declare const DEFAULTS: {
|
|
318
458
|
readonly SUBSCRIPTION_TIMEOUT_MS: 120000;
|
|
@@ -342,4 +482,4 @@ declare const LIMITS: {
|
|
|
342
482
|
readonly MAX_CAPABILITY_LENGTH: 64;
|
|
343
483
|
};
|
|
344
484
|
|
|
345
|
-
export { Agent, AgentConfig, BoundedSet, CapabilityCard, DEFAULTS, DEFAULT_KIND_OFFSET, DiscoveryService, ElisymClient, ElisymClientConfig, type ElisymClientFullConfig, ElisymIdentity, Job, JobSubscriptionOptions, KIND_APP_HANDLER, KIND_JOB_FEEDBACK, KIND_JOB_REQUEST, KIND_JOB_REQUEST_BASE, KIND_JOB_RESULT, KIND_JOB_RESULT_BASE, KIND_PING, KIND_PONG, LAMPORTS_PER_SOL, LIMITS, MarketplaceService, MediaService, Network, NostrPool, PROTOCOL_FEE_BPS, PROTOCOL_TREASURY, PaymentRequestData, type PaymentStrategy, PaymentValidationError, PingResult, PingService, RELAYS, SolanaPaymentStrategy, SubCloser, SubmitJobOptions, VerifyOptions, VerifyResult, assertExpiry, assertLamports, calculateProtocolFee, formatSol, jobRequestKind, jobResultKind, nip44Decrypt, nip44Encrypt, serializeConfig, timeAgo, toDTag, truncateKey, validateAgentName, validateExpiry };
|
|
485
|
+
export { Agent, AgentConfig, BoundedSet, CapabilityCard, DEFAULTS, DEFAULT_KIND_OFFSET, DiscoveryService, ElisymClient, ElisymClientConfig, type ElisymClientFullConfig, ElisymIdentity, type GetProtocolConfigOptions, Job, JobSubscriptionOptions, KIND_APP_HANDLER, KIND_JOB_FEEDBACK, KIND_JOB_REQUEST, KIND_JOB_REQUEST_BASE, KIND_JOB_RESULT, KIND_JOB_RESULT_BASE, KIND_PING, KIND_PONG, LAMPORTS_PER_SOL, LIMITS, MarketplaceService, MediaService, Network, NostrPool, PROTOCOL_FEE_BPS, PROTOCOL_PROGRAM_ID_DEVNET, PROTOCOL_TREASURY, PaymentRequestData, type PaymentStrategy, PaymentValidationError, PingResult, PingService, type ProtocolCluster, type ProtocolConfig, type ProtocolConfigInput, RELAYS, SolanaPaymentStrategy, SubCloser, SubmitJobOptions, VerifyOptions, VerifyResult, assertExpiry, assertLamports, buildPaymentInstructions, calculateProtocolFee, clearProtocolConfigCache, createPaymentRequestWithOnchainConfig, formatSol, getProtocolConfig, getProtocolProgramId, jobRequestKind, jobResultKind, nip44Decrypt, nip44Encrypt, serializeConfig, timeAgo, toDTag, truncateKey, validateAgentName, validateExpiry };
|