@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/README.md +32 -0
- package/dist/agent-store.cjs.map +1 -1
- package/dist/agent-store.js.map +1 -1
- package/dist/index.cjs +137 -38
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +80 -16
- package/dist/index.d.ts +80 -16
- package/dist/index.js +136 -39
- package/dist/index.js.map +1 -1
- package/dist/skills.cjs.map +1 -1
- package/dist/skills.js.map +1 -1
- package/package.json +3 -1
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
|
|
385
|
-
*
|
|
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
|
|
390
|
-
*
|
|
391
|
-
*
|
|
392
|
-
*
|
|
393
|
-
*
|
|
394
|
-
*
|
|
395
|
-
*
|
|
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
|
|
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
|
|
385
|
-
*
|
|
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
|
|
390
|
-
*
|
|
391
|
-
*
|
|
392
|
-
*
|
|
393
|
-
*
|
|
394
|
-
*
|
|
395
|
-
*
|
|
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
|
|
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,
|
|
98
|
-
const maybeAccount = await fetchMaybeConfig(rpc,
|
|
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,
|
|
103
|
-
const maybeAccount = await fetchEncodedAccount(rpc,
|
|
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
|
|
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 = [
|
|
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
|
|
974
|
+
const providerTransferIxWithMarkers = {
|
|
961
975
|
...providerTransferIx,
|
|
962
|
-
accounts: [
|
|
976
|
+
accounts: [
|
|
977
|
+
...providerTransferIx.accounts,
|
|
978
|
+
{ address: reference, role: AccountRole.READONLY },
|
|
979
|
+
{ address: protocolTag, role: AccountRole.READONLY }
|
|
980
|
+
]
|
|
963
981
|
};
|
|
964
|
-
instructions.push(
|
|
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
|
|
1215
|
-
*
|
|
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
|
|
1220
|
-
*
|
|
1221
|
-
*
|
|
1222
|
-
*
|
|
1223
|
-
*
|
|
1224
|
-
*
|
|
1225
|
-
*
|
|
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
|
|
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
|
-
|
|
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
|