@hark-protocol/sdk 0.1.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 ADDED
@@ -0,0 +1,56 @@
1
+ # @hark-protocol/sdk
2
+
3
+ Publisher and advertiser clients for [Hark Protocol](https://github.com/SiddharthaMadhav/ETHOnline-2026) -
4
+ an open intent-advertising protocol where platforms publish temporary,
5
+ privacy-preserving user intent and autonomous advertising agents pay through
6
+ x402 on Hedera to reach matching users.
7
+
8
+ ## Publisher client
9
+
10
+ Authenticated with a publisher secret - never expose this in browser code.
11
+
12
+ ```ts
13
+ import { HarkPublisherClient } from "@hark-protocol/sdk";
14
+
15
+ const hark = new HarkPublisherClient({
16
+ baseUrl: "https://your-hark-api.example.com",
17
+ publisherKey: process.env.DEMO_PUBLISHER_KEY!,
18
+ });
19
+
20
+ const intent = await hark.intents.create({
21
+ subjectRef: "user-001",
22
+ placementIds: ["plc_..."],
23
+ topics: [{ id: "electronics.computer.laptop", confidence: 0.91 }],
24
+ semanticSummary: "Looking for a lightweight computer for coding.",
25
+ });
26
+
27
+ await hark.intents.update(intent.id, { expiresInSeconds: 2592000 });
28
+ await hark.intents.revoke(intent.id, "user_requested");
29
+ const feed = await hark.feed.get("user-001");
30
+ await hark.deliveries.markServed(feed[0].id);
31
+ ```
32
+
33
+ ## Advertiser client
34
+
35
+ Every method except `reach()` is free - no Hark API key required.
36
+
37
+ ```ts
38
+ import { HarkAdvertiserClient } from "@hark-protocol/sdk";
39
+
40
+ const hark = new HarkAdvertiserClient({ baseUrl: "https://your-hark-api.example.com" });
41
+
42
+ const discovery = await hark.discovery.get();
43
+ const opportunities = await hark.opportunities.list(campaignId);
44
+ ```
45
+
46
+ `reach()` is x402-gated: pass an x402-capable `fetch` (e.g. `@x402/fetch`'s
47
+ `wrapFetchWithPayment`) as the client's `fetch` option. This client never
48
+ owns or touches Hedera keys itself.
49
+
50
+ ```ts
51
+ const hark = new HarkAdvertiserClient({ baseUrl, fetch: fetchWithPayment });
52
+ const { confirmation, transactionId } = await hark.reach({ opportunityId, campaignId });
53
+ ```
54
+
55
+ Part of the [Hark Protocol](https://github.com/SiddharthaMadhav/ETHOnline-2026)
56
+ monorepo. See that repo for the full protocol spec, API, and demo apps.
@@ -0,0 +1,61 @@
1
+ import { type HarkOpportunity, type Campaign, type CreateCampaignInput, type ReachConfirmation } from "@hark-protocol/protocol";
2
+ import { type HarkClientConfig } from "./client.js";
3
+ export type DiscoveryDocument = {
4
+ name: string;
5
+ protocolVersion: string;
6
+ description: string;
7
+ network: string;
8
+ paymentProtocol: string;
9
+ asset: string;
10
+ services: Array<{
11
+ name: string;
12
+ method: string;
13
+ path: string;
14
+ paid: boolean;
15
+ }>;
16
+ };
17
+ export type TopicDefinition = {
18
+ id: string;
19
+ label: string;
20
+ parentId?: string;
21
+ };
22
+ export type ReachParams = {
23
+ opportunityId: string;
24
+ campaignId: string;
25
+ /** Defaults to a random UUID (CLAUDE.md section 19). */
26
+ idempotencyKey?: string;
27
+ };
28
+ export type ReachResult = {
29
+ confirmation: ReachConfirmation;
30
+ /** Settled Hedera transaction id, decoded from the x402 payment-response header, when present. */
31
+ transactionId?: string;
32
+ };
33
+ /**
34
+ * Advertiser-side client (CLAUDE.md section 20). Every method except
35
+ * `reach()` is free and requires no Hark API key at all (CLAUDE.md section
36
+ * 2.8) - it needs no publisher secret, only whatever `fetch` you pass in.
37
+ *
38
+ * `reach()` is x402-gated: pass an x402-capable `fetch` in the constructor
39
+ * (e.g. `@x402/fetch`'s `wrapFetchWithPayment`). This client never owns or
40
+ * touches Hedera keys itself - it only calls whatever `fetch` it was given.
41
+ */
42
+ export declare class HarkAdvertiserClient {
43
+ private readonly baseUrl;
44
+ private readonly fetchImpl;
45
+ constructor(config: HarkClientConfig);
46
+ discovery: {
47
+ get: () => Promise<DiscoveryDocument>;
48
+ };
49
+ topics: {
50
+ list: () => Promise<TopicDefinition[]>;
51
+ };
52
+ campaigns: {
53
+ create: (input: CreateCampaignInput) => Promise<Campaign>;
54
+ list: () => Promise<Campaign[]>;
55
+ };
56
+ opportunities: {
57
+ list: (campaignId?: string) => Promise<HarkOpportunity[]>;
58
+ };
59
+ reach: (params: ReachParams) => Promise<ReachResult>;
60
+ }
61
+ //# sourceMappingURL=advertiser.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"advertiser.d.ts","sourceRoot":"","sources":["../src/advertiser.ts"],"names":[],"mappings":"AAEA,OAAO,EAKL,KAAK,eAAe,EACpB,KAAK,QAAQ,EACb,KAAK,mBAAmB,EACxB,KAAK,iBAAiB,EACvB,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAAiC,KAAK,gBAAgB,EAAkB,MAAM,aAAa,CAAC;AAEnG,MAAM,MAAM,iBAAiB,GAAG;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,eAAe,EAAE,MAAM,CAAC;IACxB,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,eAAe,EAAE,MAAM,CAAC;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,OAAO,CAAA;KAAE,CAAC,CAAC;CAChF,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC;AAE/E,MAAM,MAAM,WAAW,GAAG;IACxB,aAAa,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;IACnB,wDAAwD;IACxD,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB,CAAC;AAEF,MAAM,MAAM,WAAW,GAAG;IACxB,YAAY,EAAE,iBAAiB,CAAC;IAChC,kGAAkG;IAClG,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB,CAAC;AAEF;;;;;;;;GAQG;AACH,qBAAa,oBAAoB;IAC/B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAY;gBAE1B,MAAM,EAAE,gBAAgB;IAKpC,SAAS;mBACQ,OAAO,CAAC,iBAAiB,CAAC;MAIzC;IAEF,MAAM;oBACY,OAAO,CAAC,eAAe,EAAE,CAAC;MAQ1C;IAEF,SAAS;wBACe,mBAAmB,KAAG,OAAO,CAAC,QAAQ,CAAC;oBAU7C,OAAO,CAAC,QAAQ,EAAE,CAAC;MAInC;IAEF,aAAa;4BACe,MAAM,KAAG,OAAO,CAAC,eAAe,EAAE,CAAC;MAM7D;IAEF,KAAK,GAAU,QAAQ,WAAW,KAAG,OAAO,CAAC,WAAW,CAAC,CAoBvD;CACH"}
@@ -0,0 +1,81 @@
1
+ import { z } from "zod";
2
+ import { decodePaymentResponseHeader } from "@x402/core/http";
3
+ import { harkOpportunitySchema, campaignSchema, createCampaignInputSchema, reachConfirmationSchema, } from "@hark-protocol/protocol";
4
+ import { normalizeBaseUrl, requestJson } from "./client.js";
5
+ /**
6
+ * Advertiser-side client (CLAUDE.md section 20). Every method except
7
+ * `reach()` is free and requires no Hark API key at all (CLAUDE.md section
8
+ * 2.8) - it needs no publisher secret, only whatever `fetch` you pass in.
9
+ *
10
+ * `reach()` is x402-gated: pass an x402-capable `fetch` in the constructor
11
+ * (e.g. `@x402/fetch`'s `wrapFetchWithPayment`). This client never owns or
12
+ * touches Hedera keys itself - it only calls whatever `fetch` it was given.
13
+ */
14
+ export class HarkAdvertiserClient {
15
+ baseUrl;
16
+ fetchImpl;
17
+ constructor(config) {
18
+ this.baseUrl = normalizeBaseUrl(config.baseUrl);
19
+ this.fetchImpl = config.fetch ?? fetch;
20
+ }
21
+ discovery = {
22
+ get: async () => {
23
+ const { data } = await requestJson(this.fetchImpl, `${this.baseUrl}/.well-known/hark.json`);
24
+ return data;
25
+ },
26
+ };
27
+ topics = {
28
+ list: async () => {
29
+ const { data } = await requestJson(this.fetchImpl, `${this.baseUrl}/v1/topics`);
30
+ return z
31
+ .object({
32
+ items: z.array(z.object({ id: z.string(), label: z.string(), parentId: z.string().optional() })),
33
+ })
34
+ .parse(data).items;
35
+ },
36
+ };
37
+ campaigns = {
38
+ create: async (input) => {
39
+ createCampaignInputSchema.parse(input);
40
+ const { data } = await requestJson(this.fetchImpl, `${this.baseUrl}/v1/campaigns`, {
41
+ method: "POST",
42
+ headers: { "content-type": "application/json" },
43
+ body: JSON.stringify(input),
44
+ });
45
+ return campaignSchema.parse(data);
46
+ },
47
+ list: async () => {
48
+ const { data } = await requestJson(this.fetchImpl, `${this.baseUrl}/v1/campaigns`);
49
+ return z.object({ items: z.array(campaignSchema) }).parse(data).items;
50
+ },
51
+ };
52
+ opportunities = {
53
+ list: async (campaignId) => {
54
+ const url = new URL(`${this.baseUrl}/v1/opportunities`);
55
+ if (campaignId)
56
+ url.searchParams.set("campaignId", campaignId);
57
+ const { data } = await requestJson(this.fetchImpl, url.toString());
58
+ return z.object({ items: z.array(harkOpportunitySchema) }).parse(data).items;
59
+ },
60
+ };
61
+ reach = async (params) => {
62
+ const idempotencyKey = params.idempotencyKey ?? crypto.randomUUID();
63
+ const { data, response } = await requestJson(this.fetchImpl, `${this.baseUrl}/v1/reach`, {
64
+ method: "POST",
65
+ headers: { "content-type": "application/json", "x-hark-idempotency-key": idempotencyKey },
66
+ body: JSON.stringify({ opportunityId: params.opportunityId, campaignId: params.campaignId }),
67
+ });
68
+ const paymentResponseHeader = response.headers.get("payment-response") ?? response.headers.get("x-payment-response");
69
+ let transactionId;
70
+ if (paymentResponseHeader) {
71
+ try {
72
+ transactionId = decodePaymentResponseHeader(paymentResponseHeader).transaction;
73
+ }
74
+ catch {
75
+ transactionId = undefined;
76
+ }
77
+ }
78
+ return { confirmation: reachConfirmationSchema.parse(data), transactionId };
79
+ };
80
+ }
81
+ //# sourceMappingURL=advertiser.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"advertiser.js","sourceRoot":"","sources":["../src/advertiser.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,30 @@
1
+ /**
2
+ * Shared HTTP plumbing for both Hark clients (CLAUDE.md section 20).
3
+ * Deliberately has no Hedera/x402 signing logic of its own - callers pass in
4
+ * whatever `fetch` they want (plain fetch for free endpoints, an x402-wrapped
5
+ * fetch for the advertiser client's paid `reach()`).
6
+ */
7
+ export type HarkFetch = typeof fetch;
8
+ export type HarkClientConfig = {
9
+ baseUrl: string;
10
+ /** Defaults to the global `fetch`. */
11
+ fetch?: HarkFetch;
12
+ };
13
+ /** Mirrors the error contract in CLAUDE.md section 39. */
14
+ export declare class HarkApiError extends Error {
15
+ readonly status: number;
16
+ readonly code?: string | undefined;
17
+ constructor(status: number, message: string, code?: string | undefined);
18
+ }
19
+ export declare function normalizeBaseUrl(baseUrl: string): string;
20
+ /**
21
+ * Performs the request and returns the parsed JSON body alongside the raw
22
+ * `Response` (needed by `reach()` to read the x402 payment-response header).
23
+ * Throws `HarkApiError` for any non-2xx response, using the error body's
24
+ * `error.message`/`error.code` when present.
25
+ */
26
+ export declare function requestJson(fetchImpl: HarkFetch, url: string, init?: RequestInit): Promise<{
27
+ data: unknown;
28
+ response: Response;
29
+ }>;
30
+ //# sourceMappingURL=client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,MAAM,MAAM,SAAS,GAAG,OAAO,KAAK,CAAC;AAErC,MAAM,MAAM,gBAAgB,GAAG;IAC7B,OAAO,EAAE,MAAM,CAAC;IAChB,sCAAsC;IACtC,KAAK,CAAC,EAAE,SAAS,CAAC;CACnB,CAAC;AAEF,0DAA0D;AAC1D,qBAAa,YAAa,SAAQ,KAAK;aAEnB,MAAM,EAAE,MAAM;aAEd,IAAI,CAAC,EAAE,MAAM;gBAFb,MAAM,EAAE,MAAM,EAC9B,OAAO,EAAE,MAAM,EACC,IAAI,CAAC,EAAE,MAAM,YAAA;CAIhC;AAED,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAExD;AAED;;;;;GAKG;AACH,wBAAsB,WAAW,CAC/B,SAAS,EAAE,SAAS,EACpB,GAAG,EAAE,MAAM,EACX,IAAI,GAAE,WAAgB,GACrB,OAAO,CAAC;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,QAAQ,EAAE,QAAQ,CAAA;CAAE,CAAC,CAYhD"}
package/dist/client.js ADDED
@@ -0,0 +1,29 @@
1
+ /** Mirrors the error contract in CLAUDE.md section 39. */
2
+ export class HarkApiError extends Error {
3
+ status;
4
+ code;
5
+ constructor(status, message, code) {
6
+ super(message);
7
+ this.status = status;
8
+ this.code = code;
9
+ }
10
+ }
11
+ export function normalizeBaseUrl(baseUrl) {
12
+ return baseUrl.replace(/\/+$/, "");
13
+ }
14
+ /**
15
+ * Performs the request and returns the parsed JSON body alongside the raw
16
+ * `Response` (needed by `reach()` to read the x402 payment-response header).
17
+ * Throws `HarkApiError` for any non-2xx response, using the error body's
18
+ * `error.message`/`error.code` when present.
19
+ */
20
+ export async function requestJson(fetchImpl, url, init = {}) {
21
+ const response = await fetchImpl(url, init);
22
+ const data = await response.json().catch(() => ({}));
23
+ if (!response.ok) {
24
+ const errorBody = data;
25
+ throw new HarkApiError(response.status, errorBody?.error?.message ?? `Hark API error: ${response.status}`, errorBody?.error?.code);
26
+ }
27
+ return { data, response };
28
+ }
29
+ //# sourceMappingURL=client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAcA,0DAA0D;AAC1D,MAAM,OAAO,YAAa,SAAQ,KAAK;IAEnB;IAEA;IAHlB,YACkB,MAAc,EAC9B,OAAe,EACC,IAAa;QAE7B,KAAK,CAAC,OAAO,CAAC,CAAC;QAJC,WAAM,GAAN,MAAM,CAAQ;QAEd,SAAI,GAAJ,IAAI,CAAS;IAG/B,CAAC;CACF;AAED,MAAM,UAAU,gBAAgB,CAAC,OAAe;IAC9C,OAAO,OAAO,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;AACrC,CAAC;AAED;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,WAAW,CAC/B,SAAoB,EACpB,GAAW,EACX,OAAoB,EAAE;IAEtB,MAAM,QAAQ,GAAG,MAAM,SAAS,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;IAC5C,MAAM,IAAI,GAAY,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IAC9D,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;QACjB,MAAM,SAAS,GAAG,IAAuD,CAAC;QAC1E,MAAM,IAAI,YAAY,CACpB,QAAQ,CAAC,MAAM,EACf,SAAS,EAAE,KAAK,EAAE,OAAO,IAAI,mBAAmB,QAAQ,CAAC,MAAM,EAAE,EACjE,SAAS,EAAE,KAAK,EAAE,IAAI,CACvB,CAAC;IACJ,CAAC;IACD,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC;AAC5B,CAAC"}
@@ -0,0 +1,4 @@
1
+ export * from "./client.js";
2
+ export * from "./publisher.js";
3
+ export * from "./advertiser.js";
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAC;AAC5B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,iBAAiB,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,4 @@
1
+ export * from "./client.js";
2
+ export * from "./publisher.js";
3
+ export * from "./advertiser.js";
4
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAC;AAC5B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,iBAAiB,CAAC"}
@@ -0,0 +1,30 @@
1
+ import { type CreateIntentInput, type UpdateIntentInput, type RevokeReason, type HarkIntent, type FeedDelivery } from "@hark-protocol/protocol";
2
+ import { type HarkClientConfig } from "./client.js";
3
+ export type HarkPublisherClientConfig = HarkClientConfig & {
4
+ /** The publisher's own secret (CLAUDE.md section 11) - sent as a Bearer token. */
5
+ publisherKey: string;
6
+ };
7
+ /**
8
+ * Publisher-side client (CLAUDE.md section 20). Every call is authenticated
9
+ * with the publisher's own secret - never expose an instance of this client,
10
+ * or the key passed into it, to untrusted/browser code.
11
+ */
12
+ export declare class HarkPublisherClient {
13
+ private readonly baseUrl;
14
+ private readonly fetchImpl;
15
+ private readonly publisherKey;
16
+ constructor(config: HarkPublisherClientConfig);
17
+ private authHeaders;
18
+ intents: {
19
+ create: (input: CreateIntentInput) => Promise<HarkIntent>;
20
+ update: (intentId: string, input: UpdateIntentInput) => Promise<HarkIntent>;
21
+ revoke: (intentId: string, reason?: RevokeReason) => Promise<HarkIntent>;
22
+ };
23
+ feed: {
24
+ get: (subjectRef: string) => Promise<FeedDelivery[]>;
25
+ };
26
+ deliveries: {
27
+ markServed: (deliveryId: string) => Promise<FeedDelivery>;
28
+ };
29
+ }
30
+ //# sourceMappingURL=publisher.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"publisher.d.ts","sourceRoot":"","sources":["../src/publisher.ts"],"names":[],"mappings":"AACA,OAAO,EAKL,KAAK,iBAAiB,EACtB,KAAK,iBAAiB,EACtB,KAAK,YAAY,EACjB,KAAK,UAAU,EACf,KAAK,YAAY,EAClB,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAAiC,KAAK,gBAAgB,EAAkB,MAAM,aAAa,CAAC;AAEnG,MAAM,MAAM,yBAAyB,GAAG,gBAAgB,GAAG;IACzD,kFAAkF;IAClF,YAAY,EAAE,MAAM,CAAC;CACtB,CAAC;AAEF;;;;GAIG;AACH,qBAAa,mBAAmB;IAC9B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAY;IACtC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAS;gBAE1B,MAAM,EAAE,yBAAyB;IAM7C,OAAO,CAAC,WAAW;IAInB,OAAO;wBACiB,iBAAiB,KAAG,OAAO,CAAC,UAAU,CAAC;2BAUpC,MAAM,SAAS,iBAAiB,KAAG,OAAO,CAAC,UAAU,CAAC;2BActD,MAAM,WAAU,YAAY,KAAa,OAAO,CAAC,UAAU,CAAC;MAYrF;IAEF,IAAI;0BACsB,MAAM,KAAG,OAAO,CAAC,YAAY,EAAE,CAAC;MAQxD;IAEF,UAAU;iCACuB,MAAM,KAAG,OAAO,CAAC,YAAY,CAAC;MAQ7D;CACH"}
@@ -0,0 +1,62 @@
1
+ import { z } from "zod";
2
+ import { createIntentInputSchema, updateIntentInputSchema, harkIntentSchema, feedDeliverySchema, } from "@hark-protocol/protocol";
3
+ import { normalizeBaseUrl, requestJson } from "./client.js";
4
+ /**
5
+ * Publisher-side client (CLAUDE.md section 20). Every call is authenticated
6
+ * with the publisher's own secret - never expose an instance of this client,
7
+ * or the key passed into it, to untrusted/browser code.
8
+ */
9
+ export class HarkPublisherClient {
10
+ baseUrl;
11
+ fetchImpl;
12
+ publisherKey;
13
+ constructor(config) {
14
+ this.baseUrl = normalizeBaseUrl(config.baseUrl);
15
+ this.fetchImpl = config.fetch ?? fetch;
16
+ this.publisherKey = config.publisherKey;
17
+ }
18
+ authHeaders() {
19
+ return { authorization: `Bearer ${this.publisherKey}` };
20
+ }
21
+ intents = {
22
+ create: async (input) => {
23
+ createIntentInputSchema.parse(input);
24
+ const { data } = await requestJson(this.fetchImpl, `${this.baseUrl}/v1/intents`, {
25
+ method: "POST",
26
+ headers: { "content-type": "application/json", ...this.authHeaders() },
27
+ body: JSON.stringify(input),
28
+ });
29
+ return harkIntentSchema.parse(data);
30
+ },
31
+ update: async (intentId, input) => {
32
+ updateIntentInputSchema.parse(input);
33
+ const { data } = await requestJson(this.fetchImpl, `${this.baseUrl}/v1/intents/${encodeURIComponent(intentId)}`, {
34
+ method: "PATCH",
35
+ headers: { "content-type": "application/json", ...this.authHeaders() },
36
+ body: JSON.stringify(input),
37
+ });
38
+ return harkIntentSchema.parse(data);
39
+ },
40
+ revoke: async (intentId, reason = "other") => {
41
+ const { data } = await requestJson(this.fetchImpl, `${this.baseUrl}/v1/intents/${encodeURIComponent(intentId)}`, {
42
+ method: "DELETE",
43
+ headers: { "content-type": "application/json", ...this.authHeaders() },
44
+ body: JSON.stringify({ reason }),
45
+ });
46
+ return harkIntentSchema.parse(data);
47
+ },
48
+ };
49
+ feed = {
50
+ get: async (subjectRef) => {
51
+ const { data } = await requestJson(this.fetchImpl, `${this.baseUrl}/v1/feed/${encodeURIComponent(subjectRef)}`, { headers: this.authHeaders() });
52
+ return z.object({ items: z.array(feedDeliverySchema) }).parse(data).items;
53
+ },
54
+ };
55
+ deliveries = {
56
+ markServed: async (deliveryId) => {
57
+ const { data } = await requestJson(this.fetchImpl, `${this.baseUrl}/v1/deliveries/${encodeURIComponent(deliveryId)}/served`, { method: "POST", headers: this.authHeaders() });
58
+ return feedDeliverySchema.parse(data);
59
+ },
60
+ };
61
+ }
62
+ //# sourceMappingURL=publisher.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"publisher.js","sourceRoot":"","sources":["../src/publisher.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,40 @@
1
+ {
2
+ "name": "@hark-protocol/sdk",
3
+ "version": "0.1.0",
4
+ "description": "Publisher and advertiser clients for the Hark Protocol - intent advertising with x402 payments on Hedera.",
5
+ "license": "MIT",
6
+ "repository": {
7
+ "type": "git",
8
+ "url": "git+https://github.com/SiddharthaMadhav/ETHOnline-2026.git",
9
+ "directory": "packages/sdk"
10
+ },
11
+ "keywords": ["hark-protocol", "hedera", "x402", "intent-advertising"],
12
+ "type": "module",
13
+ "main": "./dist/index.js",
14
+ "types": "./dist/index.d.ts",
15
+ "files": ["dist"],
16
+ "publishConfig": {
17
+ "access": "public"
18
+ },
19
+ "exports": {
20
+ ".": {
21
+ "types": "./dist/index.d.ts",
22
+ "default": "./dist/index.js"
23
+ }
24
+ },
25
+ "scripts": {
26
+ "build": "tsc -p tsconfig.json",
27
+ "typecheck": "tsc --noEmit",
28
+ "test": "vitest run"
29
+ },
30
+ "dependencies": {
31
+ "@hark-protocol/protocol": "workspace:*",
32
+ "@x402/core": "2.25.0",
33
+ "zod": "^3.25.76"
34
+ },
35
+ "devDependencies": {
36
+ "@types/node": "^22.10.2",
37
+ "typescript": "^5.6.3",
38
+ "vitest": "^2.1.4"
39
+ }
40
+ }