@elisym/sdk 0.10.3 → 0.11.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/index.d.cts CHANGED
@@ -1,4 +1,4 @@
1
- import { Address, TransactionSigner, Rpc, SolanaRpcApi } from '@solana/kit';
1
+ import { Address, TransactionSigner, Rpc, SolanaRpcApi, Signature } from '@solana/kit';
2
2
  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';
@@ -183,8 +183,6 @@ interface PaymentValidationError {
183
183
  message: string;
184
184
  }
185
185
  interface NetworkStats {
186
- totalAgentCount: number;
187
- agentCount: number;
188
186
  jobCount: number;
189
187
  totalLamports: number;
190
188
  }
@@ -285,6 +283,14 @@ interface BuildTransactionOptions {
285
283
  * quartile (default), 90 = aggressive.
286
284
  */
287
285
  priorityFeePercentile?: number;
286
+ /**
287
+ * Nostr job request event id (hex) to embed in an SPL Memo instruction
288
+ * with payload `elisym:v1:<jobEventId>`. Off-chain indexers join the memo
289
+ * back to the originating job for per-provider/per-capability analytics.
290
+ * Memo is omitted when this option is absent; the protocol tag is still
291
+ * attached either way.
292
+ */
293
+ jobEventId?: string;
288
294
  }
289
295
 
290
296
  declare class NostrPool {
@@ -358,8 +364,6 @@ declare function compareAgentsByRank(a: Agent, b: Agent): number;
358
364
  declare class DiscoveryService {
359
365
  private pool;
360
366
  constructor(pool: NostrPool);
361
- /** Count elisym agents (kind:31990 with "elisym" tag). */
362
- fetchAllAgentCount(): Promise<number>;
363
367
  /**
364
368
  * Fetch a single page of elisym agents with relay-side pagination.
365
369
  * Uses `until` cursor for Nostr cursor-based pagination.
@@ -381,18 +385,20 @@ declare class DiscoveryService {
381
385
  *
382
386
  * Ranking algorithm:
383
387
  * 1. Bucket each agent into 1-minute slots by `lastPaidJobAt` (newest
384
- * `payment-completed` feedback timestamp). Cold-start agents go into a
385
- * sentinel bucket below all populated buckets.
388
+ * `payment-completed` feedback timestamp, gated by a matching kind:6xxx
389
+ * result from the provider on the same job event). Cold-start agents go
390
+ * into a sentinel bucket below all populated buckets.
386
391
  * 2. Within a bucket, sort by positive review rate descending.
387
392
  * 3. Tiebreak by raw `lastPaidJobAt`, then `lastSeen` (NIP-89 freshness).
388
393
  *
389
- * NOTE: We trust the `payment-completed` feedback timestamp directly; we do
390
- * not verify the embedded `tx` signature on-chain. Public Solana devnet RPC
391
- * rate-limits trivially exceed what discovery needs (N agents * up-to-5
392
- * candidates), and the resulting 429s blocked discovery entirely. This
393
- * means a malicious customer can publish a fake `payment-completed` to lift
394
- * an agent's ranking. Acceptable trade-off for devnet / MVP; tighten via
395
- * recipient-tied checks when the network moves to mainnet with a paid RPC
394
+ * NOTE: We do not verify the `tx` signature on-chain - public Solana devnet
395
+ * RPC rate-limits trivially exceed what discovery needs (N agents * up-to-5
396
+ * candidates), and the resulting 429s blocked discovery entirely. As a
397
+ * lighter sybil mitigation we cross-check `payment-completed` feedback
398
+ * against a kind:6xxx result event authored by the provider on the same
399
+ * job: a customer can publish a fake `payment-completed`, but they cannot
400
+ * forge a result event signed by the provider. Tighten with recipient-tied
401
+ * on-chain checks when the network moves to mainnet with a paid RPC
396
402
  * provider.
397
403
  */
398
404
  fetchAgents(network?: Network, limit?: number): Promise<Agent[]>;
@@ -589,12 +595,24 @@ declare class SolanaPaymentStrategy implements PaymentStrategy {
589
595
  * extra read-only account (canonical Solana Pay pattern);
590
596
  * 4. `TransferChecked` from payer ATA to treasury ATA if a fee applies.
591
597
  *
598
+ * Every provider transfer instruction also carries `ELISYM_PROTOCOL_TAG` as a
599
+ * read-only marker account so off-chain indexers can enumerate every elisym
600
+ * transaction with a single `getSignaturesForAddress(ELISYM_PROTOCOL_TAG)`
601
+ * call, regardless of fee size.
602
+ *
603
+ * If `options.jobEventId` is provided, an SPL Memo instruction with payload
604
+ * `elisym:v1:<jobEventId>` is prepended so explorers display the originating
605
+ * Nostr job id and indexers can join on-chain payments back to off-chain
606
+ * job context.
607
+ *
592
608
  * Async because SPL ATAs are PDAs and `findAssociatedTokenPda` is async.
593
609
  *
594
610
  * Caller is responsible for validating `paymentRequest` upstream;
595
611
  * `buildTransaction` already does that before invoking this helper.
596
612
  */
597
- declare function buildPaymentInstructions(paymentRequest: PaymentRequestData, payerSigner: Signer): Promise<readonly unknown[]>;
613
+ declare function buildPaymentInstructions(paymentRequest: PaymentRequestData, payerSigner: Signer, options?: {
614
+ jobEventId?: string;
615
+ }): Promise<readonly unknown[]>;
598
616
  /**
599
617
  * Convenience wrapper: fetch the on-chain protocol config first, then build a
600
618
  * payment request using its current fee/treasury values.
@@ -836,6 +854,40 @@ interface QuickVerifyResult {
836
854
  declare function clearQuickVerifyCache(): void;
837
855
  declare function verifyJobPaymentQuick(rpc: Rpc<SolanaRpcApi>, txSignature: string, expectedRecipient: Address): Promise<QuickVerifyResult>;
838
856
 
857
+ /**
858
+ * Aggregated on-chain stats across the entire elisym network. Volume is
859
+ * keyed by `'native'` for SOL or by SPL mint address; values are subunits
860
+ * (lamports for native, raw token units for SPL).
861
+ */
862
+ interface NetworkStatsResult {
863
+ jobCount: number;
864
+ volumeByAsset: Record<string, bigint>;
865
+ /** Most-recent signature returned by the RPC (use as cursor for forward sync). */
866
+ latestSignature?: string;
867
+ /** Oldest signature scanned in this batch (use as `before` for next page). */
868
+ oldestSignature?: string;
869
+ }
870
+ interface AggregateNetworkStatsOptions {
871
+ /** Cap on signatures fetched in one call. Defaults to 1000 (RPC max). */
872
+ limit?: number;
873
+ /** Page backwards from this signature for historical scans. */
874
+ before?: Signature;
875
+ /** Parallel `getTransaction` calls. Defaults to `DEFAULTS.QUERY_MAX_CONCURRENCY`. */
876
+ concurrency?: number;
877
+ }
878
+ /**
879
+ * Enumerate every elisym payment transaction reachable from the protocol tag
880
+ * pubkey and aggregate gross volume + count.
881
+ *
882
+ * Implementation detail: for SPL txs we sum positive token-balance deltas per
883
+ * mint (ignores ATA rent that would inflate native lamport deltas in the same
884
+ * tx). For native SOL txs we sum positive lamport deltas across all non-payer
885
+ * accounts - elisym native txs only emit provider + optional fee transfers,
886
+ * so this equals gross volume. The `tx_fee` paid by the fee-payer never shows
887
+ * up as a positive delta, so it is naturally excluded.
888
+ */
889
+ declare function aggregateNetworkStats(rpc: Rpc<SolanaRpcApi>, options?: AggregateNetworkStatsOptions): Promise<NetworkStatsResult>;
890
+
839
891
  /**
840
892
  * Snapshot of the on-chain elisym-config program state.
841
893
  *
@@ -1013,6 +1065,18 @@ declare const PROTOCOL_TREASURY: Address;
1013
1065
  * treasury address, and admin rotation state. Read via `getProtocolConfig`.
1014
1066
  */
1015
1067
  declare const PROTOCOL_PROGRAM_ID_DEVNET: Address;
1068
+ /**
1069
+ * Read-only marker pubkey attached as a non-signer account to every elisym
1070
+ * payment transaction. Lets indexers enumerate every elisym tx network-wide
1071
+ * via a single `getSignaturesForAddress(ELISYM_PROTOCOL_TAG)` call,
1072
+ * independent of fee size or recipient.
1073
+ *
1074
+ * The account does not need to exist on-chain; including its pubkey as an
1075
+ * extra read-only account in the provider transfer instruction is enough for
1076
+ * Solana's tx-by-account index to pick it up. The corresponding secret key
1077
+ * was generated and discarded - the tag never signs and never holds funds.
1078
+ */
1079
+ declare const ELISYM_PROTOCOL_TAG: Address;
1016
1080
  type ProtocolCluster = 'devnet' | 'mainnet' | 'localnet';
1017
1081
  /**
1018
1082
  * Resolve the elisym-config program ID for a given Solana cluster.
@@ -1048,4 +1112,4 @@ declare const LIMITS: {
1048
1112
  readonly MAX_CAPABILITY_LENGTH: 64;
1049
1113
  };
1050
1114
 
1051
- export { type Agent, Asset, BoundedSet, type BuildTransactionOptions, type CapabilityCard, DEFAULTS, DEFAULT_KIND_OFFSET, DEFAULT_REDACT_PATHS, DiscoveryService, ElisymClient, type ElisymClientConfig, type ElisymClientFullConfig, ElisymIdentity, type EstimatePriorityFeeOptions, type EstimateSolFeeOptions, type GetProtocolConfigOptions, INPUT_REDACT_PATHS, type Job, type JobStatus, type JobSubscriptionOptions, type JobUpdateCallbacks, 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, type Network, type NetworkStats, NostrPool, PROTOCOL_FEE_BPS, PROTOCOL_PROGRAM_ID_DEVNET, PROTOCOL_TREASURY, type ParseOptions, type ParseResult, type ParsedPaymentRequest, type PaymentAssetRef, type PaymentInfo, type PaymentRequestData, PaymentRequestSchema, type PaymentStrategy, type PaymentValidationCode, type PaymentValidationError, type PingResult, PingService, type ProtocolCluster, type ProtocolConfig, type ProtocolConfigInput, type QuickVerifyReason, type QuickVerifyResult, RELAYS, type RankKey, type RateLimitDecision, SECRET_REDACT_PATHS, type Signer, type SlidingWindowLimiter, type SlidingWindowLimiterOptions, type SolFeeEstimate, SolanaPaymentStrategy, type SubCloser, type SubmitJobOptions, type VerifyOptions, type VerifyResult, assertExpiry, assertLamports, buildPaymentInstructions, calculateProtocolFee, clearPriorityFeeCache, clearProtocolConfigCache, clearQuickVerifyCache, compareAgentsByRank, computeRankKey, createPaymentRequestWithOnchainConfig, createSlidingWindowLimiter, estimatePriorityFeeMicroLamports, estimateSolFeeLamports, formatFeeBreakdown, formatSol, getProtocolConfig, getProtocolProgramId, jobRequestKind, jobResultKind, makeCensor, nip44Decrypt, nip44Encrypt, parsePaymentRequest, pickPercentileFee, timeAgo, toDTag, truncateKey, validateAgentName, validateExpiry, verifyJobPaymentQuick };
1115
+ export { type Agent, type AggregateNetworkStatsOptions, Asset, BoundedSet, type BuildTransactionOptions, type CapabilityCard, DEFAULTS, DEFAULT_KIND_OFFSET, DEFAULT_REDACT_PATHS, DiscoveryService, ELISYM_PROTOCOL_TAG, ElisymClient, type ElisymClientConfig, type ElisymClientFullConfig, ElisymIdentity, type EstimatePriorityFeeOptions, type EstimateSolFeeOptions, type GetProtocolConfigOptions, INPUT_REDACT_PATHS, type Job, type JobStatus, type JobSubscriptionOptions, type JobUpdateCallbacks, 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, type Network, type NetworkStats, type NetworkStatsResult, NostrPool, PROTOCOL_FEE_BPS, PROTOCOL_PROGRAM_ID_DEVNET, PROTOCOL_TREASURY, type ParseOptions, type ParseResult, type ParsedPaymentRequest, type PaymentAssetRef, type PaymentInfo, type PaymentRequestData, PaymentRequestSchema, type PaymentStrategy, type PaymentValidationCode, type PaymentValidationError, type PingResult, PingService, type ProtocolCluster, type ProtocolConfig, type ProtocolConfigInput, type QuickVerifyReason, type QuickVerifyResult, RELAYS, type RankKey, type RateLimitDecision, SECRET_REDACT_PATHS, type Signer, type SlidingWindowLimiter, type SlidingWindowLimiterOptions, type SolFeeEstimate, SolanaPaymentStrategy, type SubCloser, type SubmitJobOptions, type VerifyOptions, type VerifyResult, aggregateNetworkStats, assertExpiry, assertLamports, buildPaymentInstructions, calculateProtocolFee, clearPriorityFeeCache, clearProtocolConfigCache, clearQuickVerifyCache, compareAgentsByRank, computeRankKey, createPaymentRequestWithOnchainConfig, createSlidingWindowLimiter, estimatePriorityFeeMicroLamports, estimateSolFeeLamports, formatFeeBreakdown, formatSol, getProtocolConfig, getProtocolProgramId, jobRequestKind, jobResultKind, makeCensor, nip44Decrypt, nip44Encrypt, parsePaymentRequest, pickPercentileFee, timeAgo, toDTag, truncateKey, validateAgentName, validateExpiry, verifyJobPaymentQuick };
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { Address, TransactionSigner, Rpc, SolanaRpcApi } from '@solana/kit';
1
+ import { Address, TransactionSigner, Rpc, SolanaRpcApi, Signature } from '@solana/kit';
2
2
  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';
@@ -183,8 +183,6 @@ interface PaymentValidationError {
183
183
  message: string;
184
184
  }
185
185
  interface NetworkStats {
186
- totalAgentCount: number;
187
- agentCount: number;
188
186
  jobCount: number;
189
187
  totalLamports: number;
190
188
  }
@@ -285,6 +283,14 @@ interface BuildTransactionOptions {
285
283
  * quartile (default), 90 = aggressive.
286
284
  */
287
285
  priorityFeePercentile?: number;
286
+ /**
287
+ * Nostr job request event id (hex) to embed in an SPL Memo instruction
288
+ * with payload `elisym:v1:<jobEventId>`. Off-chain indexers join the memo
289
+ * back to the originating job for per-provider/per-capability analytics.
290
+ * Memo is omitted when this option is absent; the protocol tag is still
291
+ * attached either way.
292
+ */
293
+ jobEventId?: string;
288
294
  }
289
295
 
290
296
  declare class NostrPool {
@@ -358,8 +364,6 @@ declare function compareAgentsByRank(a: Agent, b: Agent): number;
358
364
  declare class DiscoveryService {
359
365
  private pool;
360
366
  constructor(pool: NostrPool);
361
- /** Count elisym agents (kind:31990 with "elisym" tag). */
362
- fetchAllAgentCount(): Promise<number>;
363
367
  /**
364
368
  * Fetch a single page of elisym agents with relay-side pagination.
365
369
  * Uses `until` cursor for Nostr cursor-based pagination.
@@ -381,18 +385,20 @@ declare class DiscoveryService {
381
385
  *
382
386
  * Ranking algorithm:
383
387
  * 1. Bucket each agent into 1-minute slots by `lastPaidJobAt` (newest
384
- * `payment-completed` feedback timestamp). Cold-start agents go into a
385
- * sentinel bucket below all populated buckets.
388
+ * `payment-completed` feedback timestamp, gated by a matching kind:6xxx
389
+ * result from the provider on the same job event). Cold-start agents go
390
+ * into a sentinel bucket below all populated buckets.
386
391
  * 2. Within a bucket, sort by positive review rate descending.
387
392
  * 3. Tiebreak by raw `lastPaidJobAt`, then `lastSeen` (NIP-89 freshness).
388
393
  *
389
- * NOTE: We trust the `payment-completed` feedback timestamp directly; we do
390
- * not verify the embedded `tx` signature on-chain. Public Solana devnet RPC
391
- * rate-limits trivially exceed what discovery needs (N agents * up-to-5
392
- * candidates), and the resulting 429s blocked discovery entirely. This
393
- * means a malicious customer can publish a fake `payment-completed` to lift
394
- * an agent's ranking. Acceptable trade-off for devnet / MVP; tighten via
395
- * recipient-tied checks when the network moves to mainnet with a paid RPC
394
+ * NOTE: We do not verify the `tx` signature on-chain - public Solana devnet
395
+ * RPC rate-limits trivially exceed what discovery needs (N agents * up-to-5
396
+ * candidates), and the resulting 429s blocked discovery entirely. As a
397
+ * lighter sybil mitigation we cross-check `payment-completed` feedback
398
+ * against a kind:6xxx result event authored by the provider on the same
399
+ * job: a customer can publish a fake `payment-completed`, but they cannot
400
+ * forge a result event signed by the provider. Tighten with recipient-tied
401
+ * on-chain checks when the network moves to mainnet with a paid RPC
396
402
  * provider.
397
403
  */
398
404
  fetchAgents(network?: Network, limit?: number): Promise<Agent[]>;
@@ -589,12 +595,24 @@ declare class SolanaPaymentStrategy implements PaymentStrategy {
589
595
  * extra read-only account (canonical Solana Pay pattern);
590
596
  * 4. `TransferChecked` from payer ATA to treasury ATA if a fee applies.
591
597
  *
598
+ * Every provider transfer instruction also carries `ELISYM_PROTOCOL_TAG` as a
599
+ * read-only marker account so off-chain indexers can enumerate every elisym
600
+ * transaction with a single `getSignaturesForAddress(ELISYM_PROTOCOL_TAG)`
601
+ * call, regardless of fee size.
602
+ *
603
+ * If `options.jobEventId` is provided, an SPL Memo instruction with payload
604
+ * `elisym:v1:<jobEventId>` is prepended so explorers display the originating
605
+ * Nostr job id and indexers can join on-chain payments back to off-chain
606
+ * job context.
607
+ *
592
608
  * Async because SPL ATAs are PDAs and `findAssociatedTokenPda` is async.
593
609
  *
594
610
  * Caller is responsible for validating `paymentRequest` upstream;
595
611
  * `buildTransaction` already does that before invoking this helper.
596
612
  */
597
- declare function buildPaymentInstructions(paymentRequest: PaymentRequestData, payerSigner: Signer): Promise<readonly unknown[]>;
613
+ declare function buildPaymentInstructions(paymentRequest: PaymentRequestData, payerSigner: Signer, options?: {
614
+ jobEventId?: string;
615
+ }): Promise<readonly unknown[]>;
598
616
  /**
599
617
  * Convenience wrapper: fetch the on-chain protocol config first, then build a
600
618
  * payment request using its current fee/treasury values.
@@ -836,6 +854,40 @@ interface QuickVerifyResult {
836
854
  declare function clearQuickVerifyCache(): void;
837
855
  declare function verifyJobPaymentQuick(rpc: Rpc<SolanaRpcApi>, txSignature: string, expectedRecipient: Address): Promise<QuickVerifyResult>;
838
856
 
857
+ /**
858
+ * Aggregated on-chain stats across the entire elisym network. Volume is
859
+ * keyed by `'native'` for SOL or by SPL mint address; values are subunits
860
+ * (lamports for native, raw token units for SPL).
861
+ */
862
+ interface NetworkStatsResult {
863
+ jobCount: number;
864
+ volumeByAsset: Record<string, bigint>;
865
+ /** Most-recent signature returned by the RPC (use as cursor for forward sync). */
866
+ latestSignature?: string;
867
+ /** Oldest signature scanned in this batch (use as `before` for next page). */
868
+ oldestSignature?: string;
869
+ }
870
+ interface AggregateNetworkStatsOptions {
871
+ /** Cap on signatures fetched in one call. Defaults to 1000 (RPC max). */
872
+ limit?: number;
873
+ /** Page backwards from this signature for historical scans. */
874
+ before?: Signature;
875
+ /** Parallel `getTransaction` calls. Defaults to `DEFAULTS.QUERY_MAX_CONCURRENCY`. */
876
+ concurrency?: number;
877
+ }
878
+ /**
879
+ * Enumerate every elisym payment transaction reachable from the protocol tag
880
+ * pubkey and aggregate gross volume + count.
881
+ *
882
+ * Implementation detail: for SPL txs we sum positive token-balance deltas per
883
+ * mint (ignores ATA rent that would inflate native lamport deltas in the same
884
+ * tx). For native SOL txs we sum positive lamport deltas across all non-payer
885
+ * accounts - elisym native txs only emit provider + optional fee transfers,
886
+ * so this equals gross volume. The `tx_fee` paid by the fee-payer never shows
887
+ * up as a positive delta, so it is naturally excluded.
888
+ */
889
+ declare function aggregateNetworkStats(rpc: Rpc<SolanaRpcApi>, options?: AggregateNetworkStatsOptions): Promise<NetworkStatsResult>;
890
+
839
891
  /**
840
892
  * Snapshot of the on-chain elisym-config program state.
841
893
  *
@@ -1013,6 +1065,18 @@ declare const PROTOCOL_TREASURY: Address;
1013
1065
  * treasury address, and admin rotation state. Read via `getProtocolConfig`.
1014
1066
  */
1015
1067
  declare const PROTOCOL_PROGRAM_ID_DEVNET: Address;
1068
+ /**
1069
+ * Read-only marker pubkey attached as a non-signer account to every elisym
1070
+ * payment transaction. Lets indexers enumerate every elisym tx network-wide
1071
+ * via a single `getSignaturesForAddress(ELISYM_PROTOCOL_TAG)` call,
1072
+ * independent of fee size or recipient.
1073
+ *
1074
+ * The account does not need to exist on-chain; including its pubkey as an
1075
+ * extra read-only account in the provider transfer instruction is enough for
1076
+ * Solana's tx-by-account index to pick it up. The corresponding secret key
1077
+ * was generated and discarded - the tag never signs and never holds funds.
1078
+ */
1079
+ declare const ELISYM_PROTOCOL_TAG: Address;
1016
1080
  type ProtocolCluster = 'devnet' | 'mainnet' | 'localnet';
1017
1081
  /**
1018
1082
  * Resolve the elisym-config program ID for a given Solana cluster.
@@ -1048,4 +1112,4 @@ declare const LIMITS: {
1048
1112
  readonly MAX_CAPABILITY_LENGTH: 64;
1049
1113
  };
1050
1114
 
1051
- export { type Agent, Asset, BoundedSet, type BuildTransactionOptions, type CapabilityCard, DEFAULTS, DEFAULT_KIND_OFFSET, DEFAULT_REDACT_PATHS, DiscoveryService, ElisymClient, type ElisymClientConfig, type ElisymClientFullConfig, ElisymIdentity, type EstimatePriorityFeeOptions, type EstimateSolFeeOptions, type GetProtocolConfigOptions, INPUT_REDACT_PATHS, type Job, type JobStatus, type JobSubscriptionOptions, type JobUpdateCallbacks, 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, type Network, type NetworkStats, NostrPool, PROTOCOL_FEE_BPS, PROTOCOL_PROGRAM_ID_DEVNET, PROTOCOL_TREASURY, type ParseOptions, type ParseResult, type ParsedPaymentRequest, type PaymentAssetRef, type PaymentInfo, type PaymentRequestData, PaymentRequestSchema, type PaymentStrategy, type PaymentValidationCode, type PaymentValidationError, type PingResult, PingService, type ProtocolCluster, type ProtocolConfig, type ProtocolConfigInput, type QuickVerifyReason, type QuickVerifyResult, RELAYS, type RankKey, type RateLimitDecision, SECRET_REDACT_PATHS, type Signer, type SlidingWindowLimiter, type SlidingWindowLimiterOptions, type SolFeeEstimate, SolanaPaymentStrategy, type SubCloser, type SubmitJobOptions, type VerifyOptions, type VerifyResult, assertExpiry, assertLamports, buildPaymentInstructions, calculateProtocolFee, clearPriorityFeeCache, clearProtocolConfigCache, clearQuickVerifyCache, compareAgentsByRank, computeRankKey, createPaymentRequestWithOnchainConfig, createSlidingWindowLimiter, estimatePriorityFeeMicroLamports, estimateSolFeeLamports, formatFeeBreakdown, formatSol, getProtocolConfig, getProtocolProgramId, jobRequestKind, jobResultKind, makeCensor, nip44Decrypt, nip44Encrypt, parsePaymentRequest, pickPercentileFee, timeAgo, toDTag, truncateKey, validateAgentName, validateExpiry, verifyJobPaymentQuick };
1115
+ export { type Agent, type AggregateNetworkStatsOptions, Asset, BoundedSet, type BuildTransactionOptions, type CapabilityCard, DEFAULTS, DEFAULT_KIND_OFFSET, DEFAULT_REDACT_PATHS, DiscoveryService, ELISYM_PROTOCOL_TAG, ElisymClient, type ElisymClientConfig, type ElisymClientFullConfig, ElisymIdentity, type EstimatePriorityFeeOptions, type EstimateSolFeeOptions, type GetProtocolConfigOptions, INPUT_REDACT_PATHS, type Job, type JobStatus, type JobSubscriptionOptions, type JobUpdateCallbacks, 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, type Network, type NetworkStats, type NetworkStatsResult, NostrPool, PROTOCOL_FEE_BPS, PROTOCOL_PROGRAM_ID_DEVNET, PROTOCOL_TREASURY, type ParseOptions, type ParseResult, type ParsedPaymentRequest, type PaymentAssetRef, type PaymentInfo, type PaymentRequestData, PaymentRequestSchema, type PaymentStrategy, type PaymentValidationCode, type PaymentValidationError, type PingResult, PingService, type ProtocolCluster, type ProtocolConfig, type ProtocolConfigInput, type QuickVerifyReason, type QuickVerifyResult, RELAYS, type RankKey, type RateLimitDecision, SECRET_REDACT_PATHS, type Signer, type SlidingWindowLimiter, type SlidingWindowLimiterOptions, type SolFeeEstimate, SolanaPaymentStrategy, type SubCloser, type SubmitJobOptions, type VerifyOptions, type VerifyResult, aggregateNetworkStats, assertExpiry, assertLamports, buildPaymentInstructions, calculateProtocolFee, clearPriorityFeeCache, clearProtocolConfigCache, clearQuickVerifyCache, compareAgentsByRank, computeRankKey, createPaymentRequestWithOnchainConfig, createSlidingWindowLimiter, estimatePriorityFeeMicroLamports, estimateSolFeeLamports, formatFeeBreakdown, formatSol, getProtocolConfig, getProtocolProgramId, jobRequestKind, jobResultKind, makeCensor, nip44Decrypt, nip44Encrypt, parsePaymentRequest, pickPercentileFee, timeAgo, toDTag, truncateKey, validateAgentName, validateExpiry, verifyJobPaymentQuick };
package/dist/index.js CHANGED
@@ -1,3 +1,4 @@
1
+ import { getAddMemoInstruction } from '@solana-program/memo';
1
2
  import { getTransferSolInstruction } from '@solana-program/system';
2
3
  import { findAssociatedTokenPda, TOKEN_PROGRAM_ADDRESS, getCreateAssociatedTokenIdempotentInstruction, ASSOCIATED_TOKEN_PROGRAM_ADDRESS, getTransferCheckedInstruction } from '@solana-program/token';
3
4
  import { pipe, createTransactionMessage, setTransactionMessageFeePayerSigner, setTransactionMessageLifetimeUsingBlockhash, setTransactionMessageComputeUnitLimit, setTransactionMessageComputeUnitPrice, appendTransactionMessageInstructions, signTransactionMessageWithSigners, address, AccountRole, isAddress, getProgramDerivedAddress, assertAccountExists, getAddressDecoder, fetchEncodedAccount, decodeAccount, getStructDecoder, fixDecoderSize, getBytesDecoder, getU8Decoder, getOptionDecoder, getU16Decoder, getBooleanDecoder, getI64Decoder } from '@solana/kit';
@@ -39,6 +40,7 @@ var LAMPORTS_PER_SOL = 1e9;
39
40
  var PROTOCOL_FEE_BPS = 300;
40
41
  var PROTOCOL_TREASURY = "GY7vnWMkKpftU4nQ16C2ATkj1JwrQpHhknkaBUn67VTy";
41
42
  var PROTOCOL_PROGRAM_ID_DEVNET = "BrX1CRkSgvcjxBvc2bgc3QqgWjinusofDmeP7ZVxvwrE";
43
+ var ELISYM_PROTOCOL_TAG = "ELiZksgwDt41LaeuPDLkUfWgFXhGgVayTMP7L5nTSEL8";
42
44
  function getProtocolProgramId(cluster) {
43
45
  switch (cluster) {
44
46
  case "devnet":
@@ -94,13 +96,13 @@ function decodeConfig(encodedAccount) {
94
96
  getConfigDecoder()
95
97
  );
96
98
  }
97
- async function fetchConfig(rpc, address3, config) {
98
- const maybeAccount = await fetchMaybeConfig(rpc, address3, config);
99
+ async function fetchConfig(rpc, address4, config) {
100
+ const maybeAccount = await fetchMaybeConfig(rpc, address4, config);
99
101
  assertAccountExists(maybeAccount);
100
102
  return maybeAccount;
101
103
  }
102
- async function fetchMaybeConfig(rpc, address3, config) {
103
- const maybeAccount = await fetchEncodedAccount(rpc, address3, config);
104
+ async function fetchMaybeConfig(rpc, address4, config) {
105
+ const maybeAccount = await fetchEncodedAccount(rpc, address4, config);
104
106
  return decodeConfig(maybeAccount);
105
107
  }
106
108
  if (process.env.NODE_ENV !== "production") ;
@@ -572,7 +574,9 @@ var SolanaPaymentStrategy = class {
572
574
  if (!Number.isInteger(computeUnitLimit) || computeUnitLimit <= 0) {
573
575
  throw new Error(`Invalid computeUnitLimit: ${computeUnitLimit}. Must be a positive integer.`);
574
576
  }
575
- const paymentInstructions = await buildPaymentInstructions(paymentRequest, payerSigner);
577
+ const paymentInstructions = await buildPaymentInstructions(paymentRequest, payerSigner, {
578
+ jobEventId: options?.jobEventId
579
+ });
576
580
  const priorityFeeMicroLamports = options?.priorityFeeMicroLamports ?? await estimatePriorityFeeMicroLamports(rpc, {
577
581
  percentile: options?.priorityFeePercentile ?? DEFAULT_PRIORITY_FEE_PERCENTILE
578
582
  });
@@ -869,9 +873,10 @@ function bigIntDelta(post, pre) {
869
873
  function waitMs(ms) {
870
874
  return new Promise((resolve) => setTimeout(resolve, ms));
871
875
  }
872
- async function buildPaymentInstructions(paymentRequest, payerSigner) {
876
+ async function buildPaymentInstructions(paymentRequest, payerSigner, options) {
873
877
  const recipient = address(paymentRequest.recipient);
874
878
  const reference = address(paymentRequest.reference);
879
+ const protocolTag = address(ELISYM_PROTOCOL_TAG);
875
880
  const feeAmount = paymentRequest.fee_amount ?? 0;
876
881
  const providerAmount = paymentRequest.fee_address && feeAmount > 0 ? paymentRequest.amount - feeAmount : paymentRequest.amount;
877
882
  if (providerAmount <= 0) {
@@ -879,6 +884,7 @@ async function buildPaymentInstructions(paymentRequest, payerSigner) {
879
884
  `Fee amount (${feeAmount}) exceeds or equals total amount (${paymentRequest.amount}). Cannot create transaction with non-positive provider amount.`
880
885
  );
881
886
  }
887
+ const memoInstruction = options?.jobEventId ? getAddMemoInstruction({ memo: `elisym:v1:${options.jobEventId}` }) : null;
882
888
  const asset = resolveAssetFromPaymentRequest(paymentRequest);
883
889
  if (!asset.mint) {
884
890
  const providerTransferIx2 = getTransferSolInstruction({
@@ -886,14 +892,19 @@ async function buildPaymentInstructions(paymentRequest, payerSigner) {
886
892
  destination: recipient,
887
893
  amount: BigInt(providerAmount)
888
894
  });
889
- const providerTransferIxWithReference2 = {
895
+ const providerTransferIxWithMarkers2 = {
890
896
  ...providerTransferIx2,
891
897
  accounts: [
892
898
  ...providerTransferIx2.accounts,
893
- { address: reference, role: AccountRole.READONLY }
899
+ { address: reference, role: AccountRole.READONLY },
900
+ { address: protocolTag, role: AccountRole.READONLY }
894
901
  ]
895
902
  };
896
- const instructions2 = [providerTransferIxWithReference2];
903
+ const instructions2 = [];
904
+ if (memoInstruction) {
905
+ instructions2.push(memoInstruction);
906
+ }
907
+ instructions2.push(providerTransferIxWithMarkers2);
897
908
  if (paymentRequest.fee_address && feeAmount > 0) {
898
909
  instructions2.push(
899
910
  getTransferSolInstruction({
@@ -918,6 +929,9 @@ async function buildPaymentInstructions(paymentRequest, payerSigner) {
918
929
  mint
919
930
  });
920
931
  const instructions = [];
932
+ if (memoInstruction) {
933
+ instructions.push(memoInstruction);
934
+ }
921
935
  instructions.push(
922
936
  getCreateAssociatedTokenIdempotentInstruction(
923
937
  {
@@ -957,11 +971,15 @@ async function buildPaymentInstructions(paymentRequest, payerSigner) {
957
971
  amount: BigInt(providerAmount),
958
972
  decimals: asset.decimals
959
973
  });
960
- const providerTransferIxWithReference = {
974
+ const providerTransferIxWithMarkers = {
961
975
  ...providerTransferIx,
962
- accounts: [...providerTransferIx.accounts, { address: reference, role: AccountRole.READONLY }]
976
+ accounts: [
977
+ ...providerTransferIx.accounts,
978
+ { address: reference, role: AccountRole.READONLY },
979
+ { address: protocolTag, role: AccountRole.READONLY }
980
+ ]
963
981
  };
964
- instructions.push(providerTransferIxWithReference);
982
+ instructions.push(providerTransferIxWithMarkers);
965
983
  if (treasuryAta && paymentRequest.fee_address && feeAmount > 0) {
966
984
  instructions.push(
967
985
  getTransferCheckedInstruction({
@@ -1116,21 +1134,6 @@ var DiscoveryService = class {
1116
1134
  constructor(pool) {
1117
1135
  this.pool = pool;
1118
1136
  }
1119
- /** Count elisym agents (kind:31990 with "elisym" tag). */
1120
- async fetchAllAgentCount() {
1121
- const events = await this.pool.querySync({
1122
- kinds: [KIND_APP_HANDLER],
1123
- "#t": ["elisym"]
1124
- });
1125
- const uniquePubkeys = /* @__PURE__ */ new Set();
1126
- for (const event of events) {
1127
- if (!verifyEvent(event)) {
1128
- continue;
1129
- }
1130
- uniquePubkeys.add(event.pubkey);
1131
- }
1132
- return uniquePubkeys.size;
1133
- }
1134
1137
  /**
1135
1138
  * Fetch a single page of elisym agents with relay-side pagination.
1136
1139
  * Uses `until` cursor for Nostr cursor-based pagination.
@@ -1211,18 +1214,20 @@ var DiscoveryService = class {
1211
1214
  *
1212
1215
  * Ranking algorithm:
1213
1216
  * 1. Bucket each agent into 1-minute slots by `lastPaidJobAt` (newest
1214
- * `payment-completed` feedback timestamp). Cold-start agents go into a
1215
- * sentinel bucket below all populated buckets.
1217
+ * `payment-completed` feedback timestamp, gated by a matching kind:6xxx
1218
+ * result from the provider on the same job event). Cold-start agents go
1219
+ * into a sentinel bucket below all populated buckets.
1216
1220
  * 2. Within a bucket, sort by positive review rate descending.
1217
1221
  * 3. Tiebreak by raw `lastPaidJobAt`, then `lastSeen` (NIP-89 freshness).
1218
1222
  *
1219
- * NOTE: We trust the `payment-completed` feedback timestamp directly; we do
1220
- * not verify the embedded `tx` signature on-chain. Public Solana devnet RPC
1221
- * rate-limits trivially exceed what discovery needs (N agents * up-to-5
1222
- * candidates), and the resulting 429s blocked discovery entirely. This
1223
- * means a malicious customer can publish a fake `payment-completed` to lift
1224
- * an agent's ranking. Acceptable trade-off for devnet / MVP; tighten via
1225
- * recipient-tied checks when the network moves to mainnet with a paid RPC
1223
+ * NOTE: We do not verify the `tx` signature on-chain - public Solana devnet
1224
+ * RPC rate-limits trivially exceed what discovery needs (N agents * up-to-5
1225
+ * candidates), and the resulting 429s blocked discovery entirely. As a
1226
+ * lighter sybil mitigation we cross-check `payment-completed` feedback
1227
+ * against a kind:6xxx result event authored by the provider on the same
1228
+ * job: a customer can publish a fake `payment-completed`, but they cannot
1229
+ * forge a result event signed by the provider. Tighten with recipient-tied
1230
+ * on-chain checks when the network moves to mainnet with a paid RPC
1226
1231
  * provider.
1227
1232
  */
1228
1233
  async fetchAgents(network = "devnet", limit) {
@@ -1265,14 +1270,27 @@ var DiscoveryService = class {
1265
1270
  ),
1266
1271
  this.enrichWithMetadata(agents)
1267
1272
  ]);
1273
+ const deliveredJobsByProvider = /* @__PURE__ */ new Map();
1268
1274
  for (const ev of resultEvents) {
1269
1275
  if (!verifyEvent(ev)) {
1270
1276
  continue;
1271
1277
  }
1272
1278
  const agent = agentMap.get(ev.pubkey);
1273
- if (agent && ev.created_at > agent.lastSeen) {
1279
+ if (!agent) {
1280
+ continue;
1281
+ }
1282
+ if (ev.created_at > agent.lastSeen) {
1274
1283
  agent.lastSeen = ev.created_at;
1275
1284
  }
1285
+ const jobEventId = ev.tags.find((t) => t[0] === "e")?.[1];
1286
+ if (jobEventId) {
1287
+ let delivered = deliveredJobsByProvider.get(ev.pubkey);
1288
+ if (!delivered) {
1289
+ delivered = /* @__PURE__ */ new Set();
1290
+ deliveredJobsByProvider.set(ev.pubkey, delivered);
1291
+ }
1292
+ delivered.add(jobEventId);
1293
+ }
1276
1294
  }
1277
1295
  for (const ev of feedbackEvents) {
1278
1296
  if (!verifyEvent(ev)) {
@@ -1299,7 +1317,9 @@ var DiscoveryService = class {
1299
1317
  const status = ev.tags.find((t) => t[0] === "status")?.[1];
1300
1318
  const txTag = ev.tags.find((t) => t[0] === "tx");
1301
1319
  const txSignature = txTag?.[1];
1302
- if (status === "payment-completed" && typeof txSignature === "string" && txSignature) {
1320
+ const jobEventId = ev.tags.find((t) => t[0] === "e")?.[1];
1321
+ const hasDeliveredResult = jobEventId !== void 0 && deliveredJobsByProvider.get(targetPubkey)?.has(jobEventId) === true;
1322
+ if (status === "payment-completed" && typeof txSignature === "string" && txSignature && hasDeliveredResult) {
1303
1323
  if (!agent.lastPaidJobAt || ev.created_at > agent.lastPaidJobAt) {
1304
1324
  agent.lastPaidJobAt = ev.created_at;
1305
1325
  agent.lastPaidJobTx = txSignature;
@@ -2876,6 +2896,83 @@ async function doVerifyOnce(rpc, txSignature, expectedRecipient) {
2876
2896
  }
2877
2897
  return { verified: false, txSignature: sigStr, reason: "recipient_mismatch" };
2878
2898
  }
2899
+ var DEFAULT_LIMIT = 1e3;
2900
+ var NATIVE_KEY = "native";
2901
+ async function aggregateNetworkStats(rpc, options) {
2902
+ const limit = options?.limit ?? DEFAULT_LIMIT;
2903
+ const concurrency = options?.concurrency ?? DEFAULTS.QUERY_MAX_CONCURRENCY;
2904
+ const tag = address(ELISYM_PROTOCOL_TAG);
2905
+ const signatures = await rpc.getSignaturesForAddress(tag, { limit, before: options?.before }).send();
2906
+ const validSigs = signatures.filter((entry) => entry.err === null);
2907
+ if (validSigs.length === 0) {
2908
+ return { jobCount: 0, volumeByAsset: {} };
2909
+ }
2910
+ const volumeByAsset = {};
2911
+ let jobCount = 0;
2912
+ for (let start = 0; start < validSigs.length; start += concurrency) {
2913
+ const batch = validSigs.slice(start, start + concurrency);
2914
+ const txResults = await Promise.all(
2915
+ batch.map(
2916
+ (entry) => rpc.getTransaction(entry.signature, {
2917
+ commitment: "confirmed",
2918
+ encoding: "json",
2919
+ maxSupportedTransactionVersion: 0
2920
+ }).send().catch(() => null)
2921
+ )
2922
+ );
2923
+ for (const tx of txResults) {
2924
+ if (!tx?.meta || tx.meta.err) {
2925
+ continue;
2926
+ }
2927
+ jobCount += 1;
2928
+ accumulateTransfers(tx, volumeByAsset);
2929
+ }
2930
+ }
2931
+ const latest = validSigs[0]?.signature;
2932
+ const oldest = validSigs.at(-1)?.signature;
2933
+ return {
2934
+ jobCount,
2935
+ volumeByAsset,
2936
+ latestSignature: latest,
2937
+ oldestSignature: oldest
2938
+ };
2939
+ }
2940
+ function accumulateTransfers(tx, volumeByAsset) {
2941
+ const raw = tx;
2942
+ const meta = raw.meta;
2943
+ if (!meta) {
2944
+ return;
2945
+ }
2946
+ const preTokens = meta.preTokenBalances ?? [];
2947
+ const postTokens = meta.postTokenBalances ?? [];
2948
+ const isSpl = postTokens.length > 0 || preTokens.length > 0;
2949
+ if (isSpl) {
2950
+ accumulateSplDeltas(preTokens, postTokens, volumeByAsset);
2951
+ return;
2952
+ }
2953
+ accumulateNativeDeltas(meta.preBalances, meta.postBalances, volumeByAsset);
2954
+ }
2955
+ function accumulateSplDeltas(pre, post, volumeByAsset) {
2956
+ for (const postEntry of post) {
2957
+ const preEntry = pre.find((entry) => entry.accountIndex === postEntry.accountIndex);
2958
+ const preAmount = preEntry ? BigInt(preEntry.uiTokenAmount.amount) : 0n;
2959
+ const postAmount = BigInt(postEntry.uiTokenAmount.amount);
2960
+ const delta = postAmount - preAmount;
2961
+ if (delta > 0n) {
2962
+ volumeByAsset[postEntry.mint] = (volumeByAsset[postEntry.mint] ?? 0n) + delta;
2963
+ }
2964
+ }
2965
+ }
2966
+ function accumulateNativeDeltas(pre, post, volumeByAsset) {
2967
+ for (let i = 1; i < post.length; i++) {
2968
+ const preValue = pre[i] ?? 0n;
2969
+ const postValue = post[i] ?? 0n;
2970
+ const delta = BigInt(postValue) - BigInt(preValue);
2971
+ if (delta > 0n) {
2972
+ volumeByAsset[NATIVE_KEY] = (volumeByAsset[NATIVE_KEY] ?? 0n) + delta;
2973
+ }
2974
+ }
2975
+ }
2879
2976
  var SessionSpendLimitEntrySchema = z.object({
2880
2977
  chain: z.enum(["solana"]),
2881
2978
  token: z.string().min(1).max(16).regex(/^[a-z0-9]+$/, "token must be lowercase alphanumeric"),
@@ -3076,6 +3173,6 @@ function makeCensor() {
3076
3173
  };
3077
3174
  }
3078
3175
 
3079
- export { BoundedSet, DEFAULTS, DEFAULT_KIND_OFFSET, DEFAULT_REDACT_PATHS, DiscoveryService, ElisymClient, ElisymIdentity, GlobalConfigSchema, INPUT_REDACT_PATHS, KIND_APP_HANDLER, KIND_JOB_FEEDBACK, KIND_JOB_REQUEST, KIND_JOB_REQUEST_BASE, KIND_JOB_RESULT, KIND_JOB_RESULT_BASE, KIND_PING, KIND_PONG, KNOWN_ASSETS, LAMPORTS_PER_SOL, LIMITS, MarketplaceService, MediaService, NATIVE_SOL, NostrPool, PROTOCOL_FEE_BPS, PROTOCOL_PROGRAM_ID_DEVNET, PROTOCOL_TREASURY, PaymentRequestSchema, PingService, RELAYS, SECRET_REDACT_PATHS, SessionSpendLimitEntrySchema, SolanaPaymentStrategy, USDC_SOLANA_DEVNET, assertExpiry, assertLamports, assetByKey, assetKey, buildPaymentInstructions, calculateProtocolFee, clearPriorityFeeCache, clearProtocolConfigCache, clearQuickVerifyCache, compareAgentsByRank, computeRankKey, createPaymentRequestWithOnchainConfig, createSlidingWindowLimiter, estimatePriorityFeeMicroLamports, estimateSolFeeLamports, formatAssetAmount, formatFeeBreakdown, formatSol, getProtocolConfig, getProtocolProgramId, jobRequestKind, jobResultKind, makeCensor, nip44Decrypt, nip44Encrypt, parseAssetAmount, parsePaymentRequest, pickPercentileFee, resolveAssetFromPaymentRequest, resolveKnownAsset, timeAgo, toDTag, truncateKey, validateAgentName, validateExpiry, verifyJobPaymentQuick };
3176
+ export { BoundedSet, DEFAULTS, DEFAULT_KIND_OFFSET, DEFAULT_REDACT_PATHS, DiscoveryService, ELISYM_PROTOCOL_TAG, ElisymClient, ElisymIdentity, GlobalConfigSchema, INPUT_REDACT_PATHS, KIND_APP_HANDLER, KIND_JOB_FEEDBACK, KIND_JOB_REQUEST, KIND_JOB_REQUEST_BASE, KIND_JOB_RESULT, KIND_JOB_RESULT_BASE, KIND_PING, KIND_PONG, KNOWN_ASSETS, LAMPORTS_PER_SOL, LIMITS, MarketplaceService, MediaService, NATIVE_SOL, NostrPool, PROTOCOL_FEE_BPS, PROTOCOL_PROGRAM_ID_DEVNET, PROTOCOL_TREASURY, PaymentRequestSchema, PingService, RELAYS, SECRET_REDACT_PATHS, SessionSpendLimitEntrySchema, SolanaPaymentStrategy, USDC_SOLANA_DEVNET, aggregateNetworkStats, assertExpiry, assertLamports, assetByKey, assetKey, buildPaymentInstructions, calculateProtocolFee, clearPriorityFeeCache, clearProtocolConfigCache, clearQuickVerifyCache, compareAgentsByRank, computeRankKey, createPaymentRequestWithOnchainConfig, createSlidingWindowLimiter, estimatePriorityFeeMicroLamports, estimateSolFeeLamports, formatAssetAmount, formatFeeBreakdown, formatSol, getProtocolConfig, getProtocolProgramId, jobRequestKind, jobResultKind, makeCensor, nip44Decrypt, nip44Encrypt, parseAssetAmount, parsePaymentRequest, pickPercentileFee, resolveAssetFromPaymentRequest, resolveKnownAsset, timeAgo, toDTag, truncateKey, validateAgentName, validateExpiry, verifyJobPaymentQuick };
3080
3177
  //# sourceMappingURL=index.js.map
3081
3178
  //# sourceMappingURL=index.js.map