@elisym/sdk 0.18.1 → 0.19.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
@@ -56,6 +56,37 @@ interface PaymentInfo {
56
56
  /** Display symbol (e.g. 'SOL', 'USDC'). */
57
57
  symbol?: string;
58
58
  }
59
+ /**
60
+ * Legal/operational policy published by an agent (NIP-23 long-form article,
61
+ * kind 30023). One event per `(pubkey, type)` slot; replaceable by `d`-tag.
62
+ *
63
+ * `type` is open vocabulary - common values: `tos`, `privacy`, `refund`,
64
+ * `aup`, `sla`, `dpa`, `jurisdiction`. Validation regex `POLICY_TYPE_REGEX`.
65
+ */
66
+ interface AgentPolicy {
67
+ type: string;
68
+ version: string;
69
+ title: string;
70
+ summary?: string;
71
+ /** Full markdown body. */
72
+ content: string;
73
+ /** NIP-19 `naddr` reference, e.g. for sharing or migration to dedicated kind. */
74
+ naddr: string;
75
+ /** Underlying NIP-23 d-tag (e.g. `elisym-policy-tos`). */
76
+ dTag: string;
77
+ /** Event `created_at` in unix seconds (NIP-23 spec: defaults to publication date). */
78
+ publishedAt: number;
79
+ eventId: string;
80
+ authorPubkey: string;
81
+ }
82
+ /** Input shape for `PoliciesService.publishPolicy`. */
83
+ interface PolicyInput {
84
+ type: string;
85
+ version: string;
86
+ title: string;
87
+ summary?: string;
88
+ content: string;
89
+ }
59
90
  /** Agent discovered from the network. */
60
91
  interface Agent {
61
92
  pubkey: string;
@@ -597,6 +628,33 @@ declare class PingService {
597
628
  sendPong(identity: ElisymIdentity, recipientPubkey: string, nonce: string): Promise<void>;
598
629
  }
599
630
 
631
+ declare class PoliciesService {
632
+ private pool;
633
+ constructor(pool: NostrPool);
634
+ /**
635
+ * Fetch all elisym policies published by `pubkey`. Verifies signatures,
636
+ * dedupes by d-tag (latest `created_at` wins), and returns sorted by `type`
637
+ * for deterministic UI rendering.
638
+ *
639
+ * Returns `[]` on empty result. Network errors propagate to the caller.
640
+ */
641
+ fetchPolicies(pubkey: string): Promise<AgentPolicy[]>;
642
+ /**
643
+ * Publish a policy as a NIP-23 long-form article (kind 30023). Replaces any
644
+ * existing policy of the same `type` for this pubkey via the addressable
645
+ * `(kind, pubkey, d-tag)` slot.
646
+ */
647
+ publishPolicy(identity: ElisymIdentity, input: PolicyInput): Promise<{
648
+ eventId: string;
649
+ naddr: string;
650
+ }>;
651
+ /**
652
+ * Tombstone a policy by publishing an empty replacement under the same
653
+ * `(kind, pubkey, d-tag)` slot. Readers skip events with empty content.
654
+ */
655
+ deletePolicy(identity: ElisymIdentity, type: string): Promise<string>;
656
+ }
657
+
600
658
  interface ElisymClientFullConfig extends ElisymClientConfig {
601
659
  payment?: PaymentStrategy;
602
660
  /** Custom upload URL for file uploads (defaults to nostr.build). */
@@ -608,6 +666,7 @@ declare class ElisymClient {
608
666
  readonly marketplace: MarketplaceService;
609
667
  readonly ping: PingService;
610
668
  readonly media: MediaService;
669
+ readonly policies: PoliciesService;
611
670
  readonly payment: PaymentStrategy;
612
671
  constructor(config?: ElisymClientFullConfig);
613
672
  close(): void;
@@ -1130,10 +1189,17 @@ declare function makeCensor(): (value: unknown, path: string[]) => string;
1130
1189
 
1131
1190
  declare const RELAYS: string[];
1132
1191
  declare const KIND_APP_HANDLER = 31990;
1192
+ declare const KIND_LONG_FORM_ARTICLE = 30023;
1133
1193
  declare const KIND_JOB_REQUEST_BASE = 5000;
1134
1194
  declare const KIND_JOB_RESULT_BASE = 6000;
1135
1195
  declare const KIND_JOB_FEEDBACK = 7000;
1136
1196
  declare const DEFAULT_KIND_OFFSET = 100;
1197
+ /** Discovery tag attached to elisym agent policy events (kind 30023). */
1198
+ declare const POLICY_T_TAG = "elisym-policy";
1199
+ /** d-tag prefix for policy events: full d-tag = `<prefix><type>` (e.g. `elisym-policy-tos`). */
1200
+ declare const POLICY_D_TAG_PREFIX = "elisym-policy-";
1201
+ /** Validation regex for policy `type` slug. Lowercase ASCII + hyphen, 1-32 chars, no leading/trailing hyphen. */
1202
+ declare const POLICY_TYPE_REGEX: RegExp;
1137
1203
  /** Default job request kind (5000 + 100). */
1138
1204
  declare const KIND_JOB_REQUEST: number;
1139
1205
  /** Default job result kind (6000 + 100). */
@@ -1198,6 +1264,12 @@ declare const LIMITS: {
1198
1264
  readonly MAX_DESCRIPTION_LENGTH: 500;
1199
1265
  readonly MAX_AGENT_NAME_LENGTH: 64;
1200
1266
  readonly MAX_CAPABILITY_LENGTH: 64;
1267
+ readonly MAX_POLICY_CONTENT_LENGTH: 50000;
1268
+ readonly MAX_POLICIES_PER_AGENT: 12;
1269
+ readonly MAX_POLICY_TYPE_LENGTH: 32;
1270
+ readonly MAX_POLICY_TITLE_LENGTH: 120;
1271
+ readonly MAX_POLICY_SUMMARY_LENGTH: 280;
1272
+ readonly MAX_POLICY_VERSION_LENGTH: 32;
1201
1273
  };
1202
1274
 
1203
- 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 JobErrorKind, 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 NetworkBaselineEstimate, type NetworkBaselineOptions, type NetworkStats, type NetworkStatsResult, NostrPool, type OnchainNetworkStats, PROTOCOL_PROGRAM_ID_DEVNET, 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, SECRET_REDACT_PATHS, type Signer, type SolFeeEstimate, SolanaPaymentStrategy, type SubCloser, type SubmitJobOptions, type VerifyOptions, type VerifyResult, aggregateNetworkStats, assertExpiry, assertLamports, buildPaymentInstructions, calculateProtocolFee, classifyJobError, clearPriorityFeeCache, clearProtocolConfigCache, clearQuickVerifyCache, compareAgentsByRank, computeRankKey, createPaymentRequestWithOnchainConfig, estimateNetworkBaseline, estimatePriorityFeeMicroLamports, estimateSolFeeLamports, formatFeeBreakdown, formatNetworkBaseline, formatSol, getNetworkStats, getProtocolConfig, getProtocolProgramId, jobRequestKind, jobResultKind, makeCensor, nip44Decrypt, nip44Encrypt, parsePaymentRequest, pickPercentileFee, timeAgo, toDTag, truncateKey, validateAgentName, validateExpiry, verifyJobPaymentQuick };
1275
+ export { type Agent, type AgentPolicy, 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 JobErrorKind, 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_LONG_FORM_ARTICLE, KIND_PING, KIND_PONG, LAMPORTS_PER_SOL, LIMITS, MarketplaceService, MediaService, type Network, type NetworkBaselineEstimate, type NetworkBaselineOptions, type NetworkStats, type NetworkStatsResult, NostrPool, type OnchainNetworkStats, POLICY_D_TAG_PREFIX, POLICY_TYPE_REGEX, POLICY_T_TAG, PROTOCOL_PROGRAM_ID_DEVNET, type ParseOptions, type ParseResult, type ParsedPaymentRequest, type PaymentAssetRef, type PaymentInfo, type PaymentRequestData, PaymentRequestSchema, type PaymentStrategy, type PaymentValidationCode, type PaymentValidationError, type PingResult, PingService, PoliciesService, type PolicyInput, type ProtocolCluster, type ProtocolConfig, type ProtocolConfigInput, type QuickVerifyReason, type QuickVerifyResult, RELAYS, type RankKey, SECRET_REDACT_PATHS, type Signer, type SolFeeEstimate, SolanaPaymentStrategy, type SubCloser, type SubmitJobOptions, type VerifyOptions, type VerifyResult, aggregateNetworkStats, assertExpiry, assertLamports, buildPaymentInstructions, calculateProtocolFee, classifyJobError, clearPriorityFeeCache, clearProtocolConfigCache, clearQuickVerifyCache, compareAgentsByRank, computeRankKey, createPaymentRequestWithOnchainConfig, estimateNetworkBaseline, estimatePriorityFeeMicroLamports, estimateSolFeeLamports, formatFeeBreakdown, formatNetworkBaseline, formatSol, getNetworkStats, getProtocolConfig, getProtocolProgramId, jobRequestKind, jobResultKind, makeCensor, nip44Decrypt, nip44Encrypt, parsePaymentRequest, pickPercentileFee, timeAgo, toDTag, truncateKey, validateAgentName, validateExpiry, verifyJobPaymentQuick };
package/dist/index.d.ts CHANGED
@@ -56,6 +56,37 @@ interface PaymentInfo {
56
56
  /** Display symbol (e.g. 'SOL', 'USDC'). */
57
57
  symbol?: string;
58
58
  }
59
+ /**
60
+ * Legal/operational policy published by an agent (NIP-23 long-form article,
61
+ * kind 30023). One event per `(pubkey, type)` slot; replaceable by `d`-tag.
62
+ *
63
+ * `type` is open vocabulary - common values: `tos`, `privacy`, `refund`,
64
+ * `aup`, `sla`, `dpa`, `jurisdiction`. Validation regex `POLICY_TYPE_REGEX`.
65
+ */
66
+ interface AgentPolicy {
67
+ type: string;
68
+ version: string;
69
+ title: string;
70
+ summary?: string;
71
+ /** Full markdown body. */
72
+ content: string;
73
+ /** NIP-19 `naddr` reference, e.g. for sharing or migration to dedicated kind. */
74
+ naddr: string;
75
+ /** Underlying NIP-23 d-tag (e.g. `elisym-policy-tos`). */
76
+ dTag: string;
77
+ /** Event `created_at` in unix seconds (NIP-23 spec: defaults to publication date). */
78
+ publishedAt: number;
79
+ eventId: string;
80
+ authorPubkey: string;
81
+ }
82
+ /** Input shape for `PoliciesService.publishPolicy`. */
83
+ interface PolicyInput {
84
+ type: string;
85
+ version: string;
86
+ title: string;
87
+ summary?: string;
88
+ content: string;
89
+ }
59
90
  /** Agent discovered from the network. */
60
91
  interface Agent {
61
92
  pubkey: string;
@@ -597,6 +628,33 @@ declare class PingService {
597
628
  sendPong(identity: ElisymIdentity, recipientPubkey: string, nonce: string): Promise<void>;
598
629
  }
599
630
 
631
+ declare class PoliciesService {
632
+ private pool;
633
+ constructor(pool: NostrPool);
634
+ /**
635
+ * Fetch all elisym policies published by `pubkey`. Verifies signatures,
636
+ * dedupes by d-tag (latest `created_at` wins), and returns sorted by `type`
637
+ * for deterministic UI rendering.
638
+ *
639
+ * Returns `[]` on empty result. Network errors propagate to the caller.
640
+ */
641
+ fetchPolicies(pubkey: string): Promise<AgentPolicy[]>;
642
+ /**
643
+ * Publish a policy as a NIP-23 long-form article (kind 30023). Replaces any
644
+ * existing policy of the same `type` for this pubkey via the addressable
645
+ * `(kind, pubkey, d-tag)` slot.
646
+ */
647
+ publishPolicy(identity: ElisymIdentity, input: PolicyInput): Promise<{
648
+ eventId: string;
649
+ naddr: string;
650
+ }>;
651
+ /**
652
+ * Tombstone a policy by publishing an empty replacement under the same
653
+ * `(kind, pubkey, d-tag)` slot. Readers skip events with empty content.
654
+ */
655
+ deletePolicy(identity: ElisymIdentity, type: string): Promise<string>;
656
+ }
657
+
600
658
  interface ElisymClientFullConfig extends ElisymClientConfig {
601
659
  payment?: PaymentStrategy;
602
660
  /** Custom upload URL for file uploads (defaults to nostr.build). */
@@ -608,6 +666,7 @@ declare class ElisymClient {
608
666
  readonly marketplace: MarketplaceService;
609
667
  readonly ping: PingService;
610
668
  readonly media: MediaService;
669
+ readonly policies: PoliciesService;
611
670
  readonly payment: PaymentStrategy;
612
671
  constructor(config?: ElisymClientFullConfig);
613
672
  close(): void;
@@ -1130,10 +1189,17 @@ declare function makeCensor(): (value: unknown, path: string[]) => string;
1130
1189
 
1131
1190
  declare const RELAYS: string[];
1132
1191
  declare const KIND_APP_HANDLER = 31990;
1192
+ declare const KIND_LONG_FORM_ARTICLE = 30023;
1133
1193
  declare const KIND_JOB_REQUEST_BASE = 5000;
1134
1194
  declare const KIND_JOB_RESULT_BASE = 6000;
1135
1195
  declare const KIND_JOB_FEEDBACK = 7000;
1136
1196
  declare const DEFAULT_KIND_OFFSET = 100;
1197
+ /** Discovery tag attached to elisym agent policy events (kind 30023). */
1198
+ declare const POLICY_T_TAG = "elisym-policy";
1199
+ /** d-tag prefix for policy events: full d-tag = `<prefix><type>` (e.g. `elisym-policy-tos`). */
1200
+ declare const POLICY_D_TAG_PREFIX = "elisym-policy-";
1201
+ /** Validation regex for policy `type` slug. Lowercase ASCII + hyphen, 1-32 chars, no leading/trailing hyphen. */
1202
+ declare const POLICY_TYPE_REGEX: RegExp;
1137
1203
  /** Default job request kind (5000 + 100). */
1138
1204
  declare const KIND_JOB_REQUEST: number;
1139
1205
  /** Default job result kind (6000 + 100). */
@@ -1198,6 +1264,12 @@ declare const LIMITS: {
1198
1264
  readonly MAX_DESCRIPTION_LENGTH: 500;
1199
1265
  readonly MAX_AGENT_NAME_LENGTH: 64;
1200
1266
  readonly MAX_CAPABILITY_LENGTH: 64;
1267
+ readonly MAX_POLICY_CONTENT_LENGTH: 50000;
1268
+ readonly MAX_POLICIES_PER_AGENT: 12;
1269
+ readonly MAX_POLICY_TYPE_LENGTH: 32;
1270
+ readonly MAX_POLICY_TITLE_LENGTH: 120;
1271
+ readonly MAX_POLICY_SUMMARY_LENGTH: 280;
1272
+ readonly MAX_POLICY_VERSION_LENGTH: 32;
1201
1273
  };
1202
1274
 
1203
- 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 JobErrorKind, 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 NetworkBaselineEstimate, type NetworkBaselineOptions, type NetworkStats, type NetworkStatsResult, NostrPool, type OnchainNetworkStats, PROTOCOL_PROGRAM_ID_DEVNET, 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, SECRET_REDACT_PATHS, type Signer, type SolFeeEstimate, SolanaPaymentStrategy, type SubCloser, type SubmitJobOptions, type VerifyOptions, type VerifyResult, aggregateNetworkStats, assertExpiry, assertLamports, buildPaymentInstructions, calculateProtocolFee, classifyJobError, clearPriorityFeeCache, clearProtocolConfigCache, clearQuickVerifyCache, compareAgentsByRank, computeRankKey, createPaymentRequestWithOnchainConfig, estimateNetworkBaseline, estimatePriorityFeeMicroLamports, estimateSolFeeLamports, formatFeeBreakdown, formatNetworkBaseline, formatSol, getNetworkStats, getProtocolConfig, getProtocolProgramId, jobRequestKind, jobResultKind, makeCensor, nip44Decrypt, nip44Encrypt, parsePaymentRequest, pickPercentileFee, timeAgo, toDTag, truncateKey, validateAgentName, validateExpiry, verifyJobPaymentQuick };
1275
+ export { type Agent, type AgentPolicy, 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 JobErrorKind, 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_LONG_FORM_ARTICLE, KIND_PING, KIND_PONG, LAMPORTS_PER_SOL, LIMITS, MarketplaceService, MediaService, type Network, type NetworkBaselineEstimate, type NetworkBaselineOptions, type NetworkStats, type NetworkStatsResult, NostrPool, type OnchainNetworkStats, POLICY_D_TAG_PREFIX, POLICY_TYPE_REGEX, POLICY_T_TAG, PROTOCOL_PROGRAM_ID_DEVNET, type ParseOptions, type ParseResult, type ParsedPaymentRequest, type PaymentAssetRef, type PaymentInfo, type PaymentRequestData, PaymentRequestSchema, type PaymentStrategy, type PaymentValidationCode, type PaymentValidationError, type PingResult, PingService, PoliciesService, type PolicyInput, type ProtocolCluster, type ProtocolConfig, type ProtocolConfigInput, type QuickVerifyReason, type QuickVerifyResult, RELAYS, type RankKey, SECRET_REDACT_PATHS, type Signer, type SolFeeEstimate, SolanaPaymentStrategy, type SubCloser, type SubmitJobOptions, type VerifyOptions, type VerifyResult, aggregateNetworkStats, assertExpiry, assertLamports, buildPaymentInstructions, calculateProtocolFee, classifyJobError, clearPriorityFeeCache, clearProtocolConfigCache, clearQuickVerifyCache, compareAgentsByRank, computeRankKey, createPaymentRequestWithOnchainConfig, estimateNetworkBaseline, estimatePriorityFeeMicroLamports, estimateSolFeeLamports, formatFeeBreakdown, formatNetworkBaseline, formatSol, getNetworkStats, getProtocolConfig, getProtocolProgramId, jobRequestKind, jobResultKind, makeCensor, nip44Decrypt, nip44Encrypt, parsePaymentRequest, pickPercentileFee, timeAgo, toDTag, truncateKey, validateAgentName, validateExpiry, verifyJobPaymentQuick };
package/dist/index.js CHANGED
@@ -16,10 +16,14 @@ var RELAYS = [
16
16
  "wss://relay.snort.social"
17
17
  ];
18
18
  var KIND_APP_HANDLER = 31990;
19
+ var KIND_LONG_FORM_ARTICLE = 30023;
19
20
  var KIND_JOB_REQUEST_BASE = 5e3;
20
21
  var KIND_JOB_RESULT_BASE = 6e3;
21
22
  var KIND_JOB_FEEDBACK = 7e3;
22
23
  var DEFAULT_KIND_OFFSET = 100;
24
+ var POLICY_T_TAG = "elisym-policy";
25
+ var POLICY_D_TAG_PREFIX = "elisym-policy-";
26
+ var POLICY_TYPE_REGEX = /^[a-z0-9](?:[a-z0-9-]{0,30}[a-z0-9])?$/;
23
27
  var KIND_JOB_REQUEST = KIND_JOB_REQUEST_BASE + DEFAULT_KIND_OFFSET;
24
28
  var KIND_JOB_RESULT = KIND_JOB_RESULT_BASE + DEFAULT_KIND_OFFSET;
25
29
  function jobRequestKind(offset) {
@@ -72,7 +76,13 @@ var LIMITS = {
72
76
  MAX_CAPABILITIES: 20,
73
77
  MAX_DESCRIPTION_LENGTH: 500,
74
78
  MAX_AGENT_NAME_LENGTH: 64,
75
- MAX_CAPABILITY_LENGTH: 64
79
+ MAX_CAPABILITY_LENGTH: 64,
80
+ MAX_POLICY_CONTENT_LENGTH: 5e4,
81
+ MAX_POLICIES_PER_AGENT: 12,
82
+ MAX_POLICY_TYPE_LENGTH: 32,
83
+ MAX_POLICY_TITLE_LENGTH: 120,
84
+ MAX_POLICY_SUMMARY_LENGTH: 280,
85
+ MAX_POLICY_VERSION_LENGTH: 32
76
86
  };
77
87
  function getConfigDecoder() {
78
88
  return getStructDecoder([
@@ -2700,6 +2710,184 @@ var PingService = class _PingService {
2700
2710
  await this.pool.publishAll(pongEvent);
2701
2711
  }
2702
2712
  };
2713
+ function dTagFor(type) {
2714
+ return `${POLICY_D_TAG_PREFIX}${type}`;
2715
+ }
2716
+ function validatePolicyInput(input) {
2717
+ if (!POLICY_TYPE_REGEX.test(input.type)) {
2718
+ throw new Error(
2719
+ `Invalid policy type "${input.type}". Must be lowercase ASCII + hyphen, 1-${LIMITS.MAX_POLICY_TYPE_LENGTH} chars, no leading/trailing hyphen.`
2720
+ );
2721
+ }
2722
+ if (input.version.length === 0 || input.version.length > LIMITS.MAX_POLICY_VERSION_LENGTH) {
2723
+ throw new Error(
2724
+ `Policy version must be 1-${LIMITS.MAX_POLICY_VERSION_LENGTH} chars (got ${input.version.length}).`
2725
+ );
2726
+ }
2727
+ if (input.title.length === 0 || input.title.length > LIMITS.MAX_POLICY_TITLE_LENGTH) {
2728
+ throw new Error(
2729
+ `Policy title must be 1-${LIMITS.MAX_POLICY_TITLE_LENGTH} chars (got ${input.title.length}).`
2730
+ );
2731
+ }
2732
+ if (input.summary !== void 0 && input.summary.length > LIMITS.MAX_POLICY_SUMMARY_LENGTH) {
2733
+ throw new Error(
2734
+ `Policy summary too long: ${input.summary.length} chars (max ${LIMITS.MAX_POLICY_SUMMARY_LENGTH}).`
2735
+ );
2736
+ }
2737
+ if (input.content.length === 0) {
2738
+ throw new Error("Policy content cannot be empty.");
2739
+ }
2740
+ if (input.content.length > LIMITS.MAX_POLICY_CONTENT_LENGTH) {
2741
+ throw new Error(
2742
+ `Policy content too long: ${input.content.length} chars (max ${LIMITS.MAX_POLICY_CONTENT_LENGTH}).`
2743
+ );
2744
+ }
2745
+ }
2746
+ function parsePolicyEvent(event) {
2747
+ if (!verifyEvent(event)) {
2748
+ return null;
2749
+ }
2750
+ if (event.kind !== KIND_LONG_FORM_ARTICLE) {
2751
+ return null;
2752
+ }
2753
+ if (!event.content || event.content.length > LIMITS.MAX_POLICY_CONTENT_LENGTH) {
2754
+ return null;
2755
+ }
2756
+ const dTag = event.tags.find((tag) => tag[0] === "d")?.[1];
2757
+ if (!dTag || !dTag.startsWith(POLICY_D_TAG_PREFIX)) {
2758
+ return null;
2759
+ }
2760
+ const type = event.tags.find((tag) => tag[0] === "policy_type")?.[1];
2761
+ if (!type || !POLICY_TYPE_REGEX.test(type)) {
2762
+ return null;
2763
+ }
2764
+ const version = event.tags.find((tag) => tag[0] === "policy_version")?.[1];
2765
+ if (!version || version.length > LIMITS.MAX_POLICY_VERSION_LENGTH) {
2766
+ return null;
2767
+ }
2768
+ const title = event.tags.find((tag) => tag[0] === "title")?.[1];
2769
+ if (!title || title.length > LIMITS.MAX_POLICY_TITLE_LENGTH) {
2770
+ return null;
2771
+ }
2772
+ const summaryTag = event.tags.find((tag) => tag[0] === "summary")?.[1];
2773
+ const summary = summaryTag !== void 0 && summaryTag.length <= LIMITS.MAX_POLICY_SUMMARY_LENGTH ? summaryTag : void 0;
2774
+ const naddr = nip19.naddrEncode({
2775
+ kind: KIND_LONG_FORM_ARTICLE,
2776
+ pubkey: event.pubkey,
2777
+ identifier: dTag,
2778
+ relays: []
2779
+ });
2780
+ return {
2781
+ type,
2782
+ version,
2783
+ title,
2784
+ summary,
2785
+ content: event.content,
2786
+ naddr,
2787
+ dTag,
2788
+ publishedAt: event.created_at,
2789
+ eventId: event.id,
2790
+ authorPubkey: event.pubkey
2791
+ };
2792
+ }
2793
+ var PoliciesService = class {
2794
+ constructor(pool) {
2795
+ this.pool = pool;
2796
+ }
2797
+ /**
2798
+ * Fetch all elisym policies published by `pubkey`. Verifies signatures,
2799
+ * dedupes by d-tag (latest `created_at` wins), and returns sorted by `type`
2800
+ * for deterministic UI rendering.
2801
+ *
2802
+ * Returns `[]` on empty result. Network errors propagate to the caller.
2803
+ */
2804
+ async fetchPolicies(pubkey) {
2805
+ const filter = {
2806
+ kinds: [KIND_LONG_FORM_ARTICLE],
2807
+ authors: [pubkey],
2808
+ "#t": [POLICY_T_TAG]
2809
+ };
2810
+ const events = await this.pool.querySync(filter);
2811
+ const latestByDTag = /* @__PURE__ */ new Map();
2812
+ for (const event of events) {
2813
+ const dTag = event.tags.find((tag) => tag[0] === "d")?.[1] ?? "";
2814
+ const prev = latestByDTag.get(dTag);
2815
+ if (!prev || event.created_at > prev.created_at) {
2816
+ latestByDTag.set(dTag, event);
2817
+ }
2818
+ }
2819
+ const policies = [];
2820
+ for (const event of latestByDTag.values()) {
2821
+ const parsed = parsePolicyEvent(event);
2822
+ if (parsed) {
2823
+ policies.push(parsed);
2824
+ }
2825
+ }
2826
+ policies.sort((a, b) => a.type.localeCompare(b.type));
2827
+ return policies;
2828
+ }
2829
+ /**
2830
+ * Publish a policy as a NIP-23 long-form article (kind 30023). Replaces any
2831
+ * existing policy of the same `type` for this pubkey via the addressable
2832
+ * `(kind, pubkey, d-tag)` slot.
2833
+ */
2834
+ async publishPolicy(identity, input) {
2835
+ validatePolicyInput(input);
2836
+ const dTag = dTagFor(input.type);
2837
+ const tags = [
2838
+ ["d", dTag],
2839
+ ["t", POLICY_T_TAG],
2840
+ ["title", input.title],
2841
+ ["policy_type", input.type],
2842
+ ["policy_version", input.version]
2843
+ ];
2844
+ if (input.summary) {
2845
+ tags.push(["summary", input.summary]);
2846
+ }
2847
+ const event = finalizeEvent(
2848
+ {
2849
+ kind: KIND_LONG_FORM_ARTICLE,
2850
+ created_at: Math.floor(Date.now() / 1e3),
2851
+ tags,
2852
+ content: input.content
2853
+ },
2854
+ identity.secretKey
2855
+ );
2856
+ await this.pool.publishAll(event);
2857
+ const naddr = nip19.naddrEncode({
2858
+ kind: KIND_LONG_FORM_ARTICLE,
2859
+ pubkey: event.pubkey,
2860
+ identifier: dTag,
2861
+ relays: []
2862
+ });
2863
+ return { eventId: event.id, naddr };
2864
+ }
2865
+ /**
2866
+ * Tombstone a policy by publishing an empty replacement under the same
2867
+ * `(kind, pubkey, d-tag)` slot. Readers skip events with empty content.
2868
+ */
2869
+ async deletePolicy(identity, type) {
2870
+ if (!POLICY_TYPE_REGEX.test(type)) {
2871
+ throw new Error(`Invalid policy type "${type}".`);
2872
+ }
2873
+ const dTag = dTagFor(type);
2874
+ const event = finalizeEvent(
2875
+ {
2876
+ kind: KIND_LONG_FORM_ARTICLE,
2877
+ created_at: Math.floor(Date.now() / 1e3),
2878
+ tags: [
2879
+ ["d", dTag],
2880
+ ["t", POLICY_T_TAG],
2881
+ ["policy_type", type]
2882
+ ],
2883
+ content: ""
2884
+ },
2885
+ identity.secretKey
2886
+ );
2887
+ await this.pool.publishAll(event);
2888
+ return event.id;
2889
+ }
2890
+ };
2703
2891
 
2704
2892
  // src/primitives/bounded-set.ts
2705
2893
  var BoundedSet = class {
@@ -3008,6 +3196,7 @@ var ElisymClient = class {
3008
3196
  marketplace;
3009
3197
  ping;
3010
3198
  media;
3199
+ policies;
3011
3200
  payment;
3012
3201
  constructor(config = {}) {
3013
3202
  this.pool = new NostrPool(config.relays ?? RELAYS);
@@ -3015,6 +3204,7 @@ var ElisymClient = class {
3015
3204
  this.marketplace = new MarketplaceService(this.pool);
3016
3205
  this.ping = new PingService(this.pool);
3017
3206
  this.media = new MediaService(config.uploadUrl);
3207
+ this.policies = new PoliciesService(this.pool);
3018
3208
  this.payment = config.payment ?? new SolanaPaymentStrategy();
3019
3209
  }
3020
3210
  close() {
@@ -3572,6 +3762,6 @@ function makeCensor() {
3572
3762
  };
3573
3763
  }
3574
3764
 
3575
- 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_PROGRAM_ID_DEVNET, PaymentRequestSchema, PingService, RELAYS, SECRET_REDACT_PATHS, SessionSpendLimitEntrySchema, SolanaPaymentStrategy, USDC_SOLANA_DEVNET, aggregateNetworkStats, assertExpiry, assertLamports, assetByKey, assetKey, buildPaymentInstructions, calculateProtocolFee, classifyJobError, clearPriorityFeeCache, clearProtocolConfigCache, clearQuickVerifyCache, compareAgentsByRank, computeRankKey, createPaymentRequestWithOnchainConfig, createSlidingWindowLimiter, estimateNetworkBaseline, estimatePriorityFeeMicroLamports, estimateSolFeeLamports, formatAssetAmount, formatFeeBreakdown, formatNetworkBaseline, formatSol, getNetworkStats, getProtocolConfig, getProtocolProgramId, jobRequestKind, jobResultKind, makeCensor, nip44Decrypt, nip44Encrypt, parseAssetAmount, parsePaymentRequest, pickPercentileFee, resolveAssetFromPaymentRequest, resolveKnownAsset, timeAgo, toDTag, truncateKey, validateAgentName, validateExpiry, verifyJobPaymentQuick };
3765
+ 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_LONG_FORM_ARTICLE, KIND_PING, KIND_PONG, KNOWN_ASSETS, LAMPORTS_PER_SOL, LIMITS, MarketplaceService, MediaService, NATIVE_SOL, NostrPool, POLICY_D_TAG_PREFIX, POLICY_TYPE_REGEX, POLICY_T_TAG, PROTOCOL_PROGRAM_ID_DEVNET, PaymentRequestSchema, PingService, PoliciesService, RELAYS, SECRET_REDACT_PATHS, SessionSpendLimitEntrySchema, SolanaPaymentStrategy, USDC_SOLANA_DEVNET, aggregateNetworkStats, assertExpiry, assertLamports, assetByKey, assetKey, buildPaymentInstructions, calculateProtocolFee, classifyJobError, clearPriorityFeeCache, clearProtocolConfigCache, clearQuickVerifyCache, compareAgentsByRank, computeRankKey, createPaymentRequestWithOnchainConfig, createSlidingWindowLimiter, estimateNetworkBaseline, estimatePriorityFeeMicroLamports, estimateSolFeeLamports, formatAssetAmount, formatFeeBreakdown, formatNetworkBaseline, formatSol, getNetworkStats, getProtocolConfig, getProtocolProgramId, jobRequestKind, jobResultKind, makeCensor, nip44Decrypt, nip44Encrypt, parseAssetAmount, parsePaymentRequest, pickPercentileFee, resolveAssetFromPaymentRequest, resolveKnownAsset, timeAgo, toDTag, truncateKey, validateAgentName, validateExpiry, verifyJobPaymentQuick };
3576
3766
  //# sourceMappingURL=index.js.map
3577
3767
  //# sourceMappingURL=index.js.map