@ambasada/sdk 0.7.5 → 0.8.1

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.
@@ -0,0 +1,20 @@
1
+ /**
2
+ * The platform surface of @ambasada/sdk, without the 0.7 village names (`index.ts` adds those).
3
+ * `@ambasada/village` builds on this module.
4
+ */
5
+ import { Ambasada } from "./client.js";
6
+ export { Ambasada, createAmbasada, DEFAULT_API_URL } from "./client.js";
7
+ export type { AmbasadaOptions } from "./client.js";
8
+ export * from "./errors.js";
9
+ export type * from "./types.js";
10
+ export { getHeader } from "./headers.js";
11
+ export type { HeaderSource } from "./headers.js";
12
+ export { defineApp } from "./define.js";
13
+ export type { AppConfig } from "./define.js";
14
+ export { AmbasadaAuth, AUTH_PATHS, JWKS_TTL_MS, SESSION_TTL_S } from "./auth.js";
15
+ export type { AmbasadaUser, AuthConfig, LoginOptions, ShellUser, WithHeaders } from "./auth.js";
16
+ export { AmbasadaApps, APP_SIGNATURE_HEADER, APP_TIMESTAMP_HEADER, appWebhookHeaders, signAppWebhook } from "./apps.js";
17
+ export type { AppEvent, AppEventType, AppNotifyInput, AppNotifyResult, AppsConfig, NotificationCategory, WebhookInput } from "./apps.js";
18
+ /** The default client, configured from the environment at call time. */
19
+ export declare const ambasada: Ambasada;
20
+ export default ambasada;
package/dist/types.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- /** Wire types. TON amounts are decimal numbers (`1`, `0.5`). */
1
+ /** Wire types of the platform API. */
2
2
  /** Ed25519 public key as served by `/.well-known/jwks.json`. */
3
3
  export interface Jwk {
4
4
  kty: "OKP";
@@ -9,216 +9,11 @@ export interface Jwk {
9
9
  alg?: "EdDSA";
10
10
  use?: "sig";
11
11
  }
12
- /** What a seller learns from a Gateway call receipt (`x-village-receipt`). Same shape as `@ambasada/protocol`. */
13
- export interface ReceiptClaims {
14
- iss: string;
15
- jti: string;
16
- call_id: string;
17
- /** Buyer company id. */
18
- buyer: string;
19
- /** Your company id. */
20
- seller: string;
21
- /** `<seller>/<offering name>` */
22
- offering: string;
23
- /** TON */
24
- amount: number;
25
- /** 1 for a direct buy; forward it with `buy(…, { parent })`. */
26
- depth: number;
27
- /** TON you may still spend downstream on behalf of this call. */
28
- budget?: number;
29
- deal_id?: string;
30
- body_sha256: string;
31
- iat: number;
32
- exp: number;
33
- }
34
- /** A verified paid call: the receipt plus the parsed JSON input. */
35
- export interface PaidCall<Input = any> extends ReceiptClaims {
36
- input: Input;
37
- }
38
- /** A checkout receipt (pay.js `village:paid`, or `session.receipt`). */
39
- export interface CheckoutReceiptClaims {
40
- iss: string;
41
- jti: string;
42
- kind: "checkout";
43
- session: string;
44
- /** The person's pseudonymous wallet id (`p_…`). */
45
- buyer: string;
46
- seller: string;
47
- amount: number;
48
- description: string;
49
- ref?: string;
50
- log_index: number;
51
- iat: number;
52
- exp: number;
53
- }
54
- export interface CheckoutInput {
55
- /** TON, 0.1–500. Or give `offering` to charge one of your offerings' price. */
56
- amount?: number;
57
- offering?: string;
58
- /** Shown to the person and written to the public ledger as the memo. No personal data. */
59
- description: string;
60
- /** `{CHECKOUT_SESSION_ID}` anywhere in the URL is replaced; otherwise `?session=cs_…` is appended. */
61
- success_url: string;
62
- cancel_url?: string;
63
- client_reference_id?: string;
64
- metadata?: Record<string, string>;
65
- /** Seconds, 300–86400 (default 3600). */
66
- expires_in?: number;
67
- }
68
- export interface CheckoutSession {
69
- id: string;
70
- object: "checkout.session";
71
- url: string;
72
- status: "open" | "paid" | "expired" | (string & {});
73
- amount: number;
74
- description: string;
75
- offering: string | null;
76
- /** The payment link it came from (`pl_…`), if any. */
77
- link: string | null;
78
- client_reference_id: string | null;
79
- metadata: Record<string, string>;
80
- success_url: string;
81
- cancel_url: string | null;
82
- buyer: string | null;
83
- paid_at: string | null;
84
- log_index: number | null;
85
- receipt: string | null;
86
- created_at: string;
87
- expires_at: string;
88
- [key: string]: unknown;
89
- }
90
- export interface PaymentLinkInput {
91
- amount?: number;
92
- offering?: string;
93
- description: string;
94
- success_url: string;
95
- cancel_url?: string;
96
- metadata?: Record<string, string>;
97
- }
98
- export interface PaymentLink {
99
- id: string;
100
- object: "checkout.link";
101
- url: string;
102
- active: boolean;
103
- amount: number;
104
- description: string;
105
- offering: string | null;
106
- metadata: Record<string, string>;
107
- success_url: string;
108
- cancel_url: string | null;
109
- created_at: string;
110
- [key: string]: unknown;
111
- }
112
- export interface WebhookDelivery {
113
- id: string;
114
- type: string;
115
- status: "pending" | "delivered" | "failed" | (string & {});
116
- attempts: number;
117
- [key: string]: unknown;
118
- }
119
- export interface WebhookEvent<Data = any> {
120
- /** `webhook-id` header: dedupe on it, retries reuse it. */
121
- id: string;
122
- type: "checkout.paid" | "webhook.test" | (string & {});
123
- timestamp: string;
124
- data: Data;
125
- }
126
- export interface BuyOptions {
127
- /** Refuse (PRICE_ABOVE_MAX) if the offering costs more than this, in TON. */
128
- maxPrice?: number;
129
- /** Retries with the same key never charge twice. Default: a random key per call (reused by the SDK's own retry). */
130
- idempotencyKey?: string;
131
- /** Inside a paid handler: forward the chain depth and remaining budget of the call you are serving. */
132
- parent?: Pick<ReceiptClaims, "depth" | "budget">;
133
- /** TON this call may spend downstream (`x-village-budget`). */
134
- budget?: number;
135
- /** An approved approval id, after APPROVAL_REQUIRED. */
136
- approval?: string;
137
- /** Why you are buying; shown to your team on approval requests. */
138
- reason?: string;
139
- signal?: AbortSignal;
140
- }
141
- export interface BuyResult<Output = any> {
142
- output: Output;
143
- callId: string | null;
144
- /** TON charged. */
145
- amount: number | null;
146
- /** The signed receipt for the call (you hold it too). */
147
- receipt: string | null;
148
- /** Position in the public ledger log. */
149
- logIndex: number | null;
150
- /** True when the Gateway replayed a previous result for the same idempotency key (no new charge). */
151
- replayed: boolean;
152
- /** For `need()`: which offering served it (`company/name`), if the Gateway says. */
153
- offering: string | null;
154
- }
155
- export type ChatModel = "deepseek-v4.1-flash" | "deepseek-v4-pro" | "glm-5.3-flash" | (string & {});
156
- export interface ChatMessage {
157
- role: "system" | "user" | "assistant" | "tool";
158
- content: string;
159
- [key: string]: unknown;
160
- }
161
- /** OpenAI-compatible chat request. */
162
- export interface ChatRequest {
163
- model?: ChatModel;
164
- messages: ChatMessage[];
165
- temperature?: number;
166
- max_tokens?: number;
167
- response_format?: {
168
- type: "text" | "json_object";
169
- } | Record<string, unknown>;
170
- [key: string]: unknown;
171
- }
172
- export interface ChatResponse {
173
- id: string;
174
- object: "chat.completion";
175
- model: string;
176
- choices: {
177
- index: number;
178
- message: ChatMessage;
179
- finish_reason: string | null;
180
- }[];
181
- usage?: {
182
- prompt_tokens: number;
183
- completion_tokens: number;
184
- total_tokens: number;
185
- };
186
- [key: string]: unknown;
187
- }
188
- export interface ImageRequest {
189
- model?: "nano_banana" | "gpt-image-2" | (string & {});
190
- prompt: string;
191
- }
192
- export interface ImageResult {
193
- /** Re-hosted in the village files store; safe to pass to other products. */
194
- url: string;
195
- /** TON charged. */
196
- cost: number;
197
- call_id: string;
198
- }
199
- export interface ToolListing {
200
- id: string;
201
- name: string;
202
- description: string;
203
- price_ton?: number;
204
- price?: number;
205
- unit?: string;
206
- input?: unknown;
207
- output?: unknown;
208
- [key: string]: unknown;
209
- }
210
- export interface ToolResult<Output = any> {
211
- output: Output;
212
- callId: string | null;
213
- /** TON charged. */
214
- amount: number | null;
215
- replayed: boolean;
216
- }
217
12
  export interface FileOptions {
218
13
  contentType?: string;
219
14
  ttlSeconds?: number;
220
15
  }
221
- /** `POST /v1/files` (0.1 TON a file). */
16
+ /** `POST /v1/files`. */
222
17
  export interface StoredFile {
223
18
  id: string;
224
19
  url: string;
@@ -243,104 +38,3 @@ export interface StoreWrite {
243
38
  used_bytes: number;
244
39
  limit_bytes: number;
245
40
  }
246
- /** Offering field schema shorthand: `{ text: "string", to: "string", tone: "string?" }`. */
247
- export type FieldSchema = Record<string, string>;
248
- export interface ListingInput {
249
- description: string;
250
- /** TON, 0.1–500. */
251
- price: number;
252
- /** Absolute URL the Gateway POSTs paid calls to. */
253
- endpoint: string;
254
- input?: FieldSchema | null;
255
- output?: FieldSchema | null;
256
- timeout_ms?: number;
257
- status?: "open" | "paused";
258
- preview?: boolean;
259
- }
260
- export interface Listing extends ListingInput {
261
- id: string;
262
- company: string;
263
- name: string;
264
- version: number;
265
- [key: string]: unknown;
266
- }
267
- export interface Wallet {
268
- account: string;
269
- balance: number;
270
- held: number;
271
- available: number;
272
- }
273
- export interface LedgerEntry {
274
- seq: number;
275
- id: string;
276
- ts: string;
277
- kind: string;
278
- direction: "in" | "out";
279
- counterparty: string;
280
- amount: number;
281
- balance_after: number;
282
- ref: string | null;
283
- memo: string | null;
284
- hold_id?: string | null;
285
- log_index?: number | null;
286
- [key: string]: unknown;
287
- }
288
- export interface LedgerPage {
289
- entries: LedgerEntry[];
290
- /** Pass back as `since` for the next page. */
291
- next_since: number;
292
- }
293
- export interface TransferOptions {
294
- reason?: string;
295
- ref?: string;
296
- idempotencyKey?: string;
297
- }
298
- /** `agent/settings.json`, sent with the prompt to `POST /v1/agent/config` (agent stream wire format). */
299
- export interface AgentSettings {
300
- model?: "deepseek-v4.1-flash" | "deepseek-v4-pro";
301
- enabled?: boolean;
302
- wake?: {
303
- interval_minutes?: number;
304
- min_event_gap_seconds?: number;
305
- };
306
- budget?: {
307
- tool_calls_per_wake?: number;
308
- tokens_per_wake?: number;
309
- max_turns?: number;
310
- compute_per_day?: number;
311
- };
312
- /** Agent tools offered to the model (default: all). */
313
- tools?: string[];
314
- /** Company wallet spend limits, TON. Over `auto_per_payment` an agent payment needs the team's approval. */
315
- limits?: {
316
- per_payment?: number;
317
- per_hour?: number;
318
- per_day?: number;
319
- per_payee_day?: number;
320
- auto_per_payment?: number;
321
- auto_per_day?: number;
322
- };
323
- [key: string]: unknown;
324
- }
325
- export interface AgentConfigInput extends AgentSettings {
326
- /** The text of agent/agent.md. */
327
- prompt?: string;
328
- /** Wake the agent once after saving. */
329
- wake_now?: boolean;
330
- }
331
- export interface TranscriptEntry {
332
- seq: number;
333
- ts: string;
334
- kind: string;
335
- data?: unknown;
336
- [key: string]: unknown;
337
- }
338
- export interface MarketOffering {
339
- id: string;
340
- company?: string;
341
- name: string;
342
- description: string;
343
- price: number;
344
- source?: "company" | "village-tool";
345
- [key: string]: unknown;
346
- }
@@ -0,0 +1,148 @@
1
+ import { Ambasada, type AmbasadaOptions } from "../platform.js";
2
+ import { type IncomingRequest } from "./receipt.js";
3
+ import type { AgentConfigInput, BuyOptions, BuyResult, ChatRequest, ChatResponse, CheckoutInput, CheckoutReceiptClaims, CheckoutSession, ImageRequest, ImageResult, LedgerPage, Listing, ListingInput, MarketOffering, PaidCall, PaymentLink, PaymentLinkInput, ToolListing, ToolResult, TranscriptEntry, TransferOptions, Wallet, WebhookDelivery, WebhookEvent } from "./types.js";
4
+ /** The Hack A Ton API. The platform API (`@ambasada/sdk`) is https://api.ambasada.dev. */
5
+ export declare const DEFAULT_VILLAGE_API_URL = "https://hackaton.ambasada.id";
6
+ export declare const DEFAULT_MODEL = "deepseek-v4.1-flash";
7
+ export interface VillageOptions extends AmbasadaOptions {
8
+ /** Team key (`sk_live_…`, from the village app → Developers). Default: `AMBASADA_API_KEY`. */
9
+ apiKey?: string;
10
+ /**
11
+ * Default: `AMBASADA_VILLAGE_API_URL`, else `AMBASADA_API_URL` when it is not the platform host (0.7
12
+ * projects, `ambasada dev`), else https://hackaton.ambasada.id.
13
+ */
14
+ apiUrl?: string;
15
+ /** Your company id, for receipt checks. Default: `AMBASADA_COMPANY`, else looked up once with the API key. */
16
+ company?: string;
17
+ /** Webhook signing secret (`whsec_…`). Default: `AMBASADA_WEBHOOK_SECRET`. */
18
+ webhookSecret?: string;
19
+ }
20
+ export interface VerifyReceiptOptions {
21
+ /** Pin the offering name (`translate`), so a receipt for another of your offerings is refused. */
22
+ offering?: string;
23
+ /** Refuse a second use of the same receipt in this process (default true). Persist call ids yourself across instances. */
24
+ replayGuard?: boolean;
25
+ }
26
+ export type SellHandler<Input, Output> = (input: Input, call: PaidCall<Input>, req: Request) => Output | Response | Promise<Output | Response>;
27
+ /**
28
+ * The village client: the platform client (`auth`, `apps`, `store`, `files`) plus money, AI, the agent and
29
+ * the market. `import { village } from "./index.js"` gives one configured from the environment;
30
+ * `createVillage({ env })` makes another (e.g. from a Worker's `env`).
31
+ */
32
+ export declare class Village extends Ambasada {
33
+ private readonly villageOptions;
34
+ private companyPromise?;
35
+ private readonly replays;
36
+ constructor(options?: VillageOptions);
37
+ get apiUrl(): string;
38
+ /** Your company id (from options, `AMBASADA_COMPANY`, or the wallet the API key belongs to). */
39
+ company(): Promise<string>;
40
+ private keySource;
41
+ /**
42
+ * Verifies that a request to your endpoint was paid through the Gateway and returns the receipt
43
+ * with the parsed JSON `input`. Throws `ReceiptInvalidError` (status 402) otherwise.
44
+ * Works with a fetch `Request` (not consumed) or a Node/Express request with a raw body.
45
+ */
46
+ verifyReceipt<Input = any>(req: IncomingRequest, options?: VerifyReceiptOptions): Promise<PaidCall<Input>>;
47
+ /**
48
+ * Wraps a paid offering as a fetch handler: verifies the receipt (402 if missing or bad), runs
49
+ * `handler(input, call, req)` and answers JSON. A thrown `AmbasadaError` keeps its status (the
50
+ * Gateway then refunds the buyer).
51
+ *
52
+ * export default village.sell("translate", async ({ text, to }) => ({ text: await village.llm(`…`) }));
53
+ */
54
+ sell<Input = any, Output = unknown>(offering: string, handler: SellHandler<Input, Output>): (req: Request) => Promise<Response>;
55
+ /** Verifies a signed webhook (`checkout.paid`, `webhook.test`) and returns the event. Throws `WebhookInvalidError`. */
56
+ verifyWebhook<Data = any>(req: IncomingRequest, secret?: string): Promise<WebhookEvent<Data>>;
57
+ /** Verifies a checkout receipt (pay.js `village:paid` → `e.detail.receipt`, or `session.receipt`). */
58
+ verifyCheckoutReceipt(token: string | null | undefined, options?: {
59
+ session?: string;
60
+ }): Promise<CheckoutReceiptClaims>;
61
+ /** Creates a Checkout session; redirect the person to `session.url`. Deliver on the webhook or `getCheckout(id).status === "paid"`. */
62
+ checkout(session: CheckoutInput, options?: {
63
+ idempotencyKey?: string;
64
+ }): Promise<CheckoutSession>;
65
+ getCheckout(id: string): Promise<CheckoutSession>;
66
+ /** A reusable payment link for static pages (`<button data-village-pay="pl_…">` with pay.js). */
67
+ createPaymentLink(link: PaymentLinkInput): Promise<PaymentLink>;
68
+ /** Cancels an open session (`POST /v1/checkout/sessions/:id/expire`). */
69
+ expireCheckout(id: string): Promise<CheckoutSession>;
70
+ listPaymentLinks(): Promise<PaymentLink[]>;
71
+ deactivatePaymentLink(id: string): Promise<PaymentLink>;
72
+ /** Where checkout webhooks go. Returns the signing secret (the same one until `rotateSecret`). */
73
+ setWebhook(url: string, options?: {
74
+ rotateSecret?: boolean;
75
+ }): Promise<{
76
+ url: string;
77
+ secret: string;
78
+ }>;
79
+ /** The webhook URL, its secret and the last deliveries. */
80
+ getWebhook(): Promise<{
81
+ url: string | null;
82
+ secret: string | null;
83
+ deliveries: WebhookDelivery[];
84
+ }>;
85
+ deleteWebhook(): Promise<{
86
+ deleted: true;
87
+ }>;
88
+ /** Sends a `webhook.test` event now and returns the delivery. */
89
+ testWebhook(): Promise<WebhookDelivery>;
90
+ retryWebhookDelivery(id: string): Promise<WebhookDelivery>;
91
+ /** Buys one call of `company/offering` through the Gateway. Money moves only if the seller answers 2xx with valid output. */
92
+ buy<Output = any>(offering: string, input: unknown, options?: BuyOptions): Promise<BuyResult<Output>>;
93
+ /**
94
+ * Buys whatever your agent routed the need `name` to (or the best offering within `maxPrice` if it
95
+ * has not routed it yet), with fallbacks (EXCHANGE.md §4.3). Prefer this over hardcoding a supplier.
96
+ */
97
+ need<Output = any>(name: string, input: unknown, options?: BuyOptions): Promise<BuyResult<Output>>;
98
+ private paid;
99
+ /**
100
+ * `village.llm("prompt")` → the answer text; `village.llm.chat(req)` → the full OpenAI-style response.
101
+ * Default model: deepseek-v4.1-flash.
102
+ */
103
+ readonly llm: ((prompt: string, options?: Omit<ChatRequest, "messages"> & {
104
+ system?: string;
105
+ }) => Promise<string>) & {
106
+ chat(req: ChatRequest): Promise<ChatResponse>;
107
+ };
108
+ readonly images: {
109
+ /** Generates an image; the URL is re-hosted in the village files store. Default model: nano_banana. */
110
+ generate: (req: ImageRequest) => Promise<ImageResult>;
111
+ };
112
+ readonly tools: {
113
+ /** The curated LLMOK tool catalog with TON prices. */
114
+ list: () => Promise<ToolListing[]>;
115
+ /** Runs one tool; debits your wallet only on success. Replays with the same idempotency key are free. */
116
+ call: <Output = any>(id: string, input: unknown, options?: {
117
+ idempotencyKey?: string;
118
+ }) => Promise<ToolResult<Output>>;
119
+ };
120
+ readonly listings: {
121
+ /** Creates or updates an offering (price changes are versioned). */
122
+ put: (name: string, def: ListingInput) => Promise<Listing>;
123
+ list: () => Promise<Listing[]>;
124
+ };
125
+ wallet(): Promise<Wallet>;
126
+ ledger(since?: number, limit?: number): Promise<LedgerPage>;
127
+ transfer(to: string, amount: number, options?: TransferOptions): Promise<{
128
+ entry: unknown;
129
+ }>;
130
+ readonly market: {
131
+ search: (query: string) => Promise<MarketOffering[]>;
132
+ };
133
+ readonly agent: {
134
+ /** Replaces the agent's prompt (`agent.md`) and settings (`settings.json`). */
135
+ config: (config: AgentConfigInput) => Promise<{
136
+ config: unknown;
137
+ limits?: unknown;
138
+ }>;
139
+ /** A message the agent answers on its next wake. */
140
+ steer: (text: string) => Promise<unknown>;
141
+ transcript: (since?: number, limit?: number) => Promise<{
142
+ entries: TranscriptEntry[];
143
+ next_since: number;
144
+ }>;
145
+ state: () => Promise<Record<string, unknown>>;
146
+ };
147
+ }
148
+ export declare function createVillage(options?: VillageOptions): Village;
@@ -0,0 +1,44 @@
1
+ /**
2
+ * The village keys of `ambasada.config.ts` (docs/PLATFORM.md §5). They only add types and checks; the CLI
3
+ * reads the values (`ambasada deploy`, `ambasada village offerings sync`, `ambasada dev`).
4
+ *
5
+ * export default defineCompany(defineApp({ id, name, product }), { idea, offerings, agent });
6
+ */
7
+ import type { AppConfig } from "../platform.js";
8
+ import type { FieldSchema } from "./types.js";
9
+ export interface VillageConfig {
10
+ /** Locked Fri 20:00. */
11
+ idea: {
12
+ title: string;
13
+ category?: string;
14
+ pitch?: string;
15
+ };
16
+ /** Path to the offerings module (default `./product/offerings.ts`). */
17
+ offerings?: string;
18
+ /** Agent folder with agent.md and settings.json (default `./agent`). */
19
+ agent?: {
20
+ dir?: string;
21
+ };
22
+ }
23
+ /** An app (`id` is your company id in the village) with the village keys. */
24
+ export interface CompanyConfig extends AppConfig, VillageConfig {
25
+ }
26
+ /** `defineCompany(defineApp({ … }), { idea, offerings, agent })`, or the 0.7 form `defineCompany({ id, name, idea, … })`. */
27
+ export declare function defineCompany(app: AppConfig, village: VillageConfig): CompanyConfig;
28
+ export declare function defineCompany(config: CompanyConfig): CompanyConfig;
29
+ export interface OfferingDef {
30
+ /** Slug: a-z, 0-9, _ and -. */
31
+ name: string;
32
+ /** TON per call, 0.1–500. */
33
+ price: number;
34
+ /** Path on your product (`/api/translate`) or an absolute URL. */
35
+ endpoint: string;
36
+ description: string;
37
+ input?: FieldSchema;
38
+ output?: FieldSchema;
39
+ /** Allow a free sample (`market.preview`). */
40
+ preview?: boolean;
41
+ timeout_ms?: number;
42
+ status?: "open" | "paused";
43
+ }
44
+ export declare function offering(def: OfferingDef): OfferingDef;
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Village errors. Every failure is an `AmbasadaError` (`@ambasada/sdk`) with a code from
3
+ * `@ambasada/protocol`; `VillageError` is the same class under its 0.7 name (kept through 1.x):
4
+ *
5
+ * try { await village.buy("inkwell/poem", input, { maxPrice: 2 }) }
6
+ * catch (e) { if (isVillageError(e, "PRICE_ABOVE_MAX")) … }
7
+ */
8
+ import { AmbasadaError, isAmbasadaError } from "../platform.js";
9
+ /** `AmbasadaError` under its 0.7 name. */
10
+ export declare const VillageError: typeof AmbasadaError;
11
+ export type VillageError = AmbasadaError;
12
+ /** `isAmbasadaError` under its 0.7 name. */
13
+ export declare const isVillageError: typeof isAmbasadaError;
14
+ export type ReceiptFailure = "malformed" | "unknown_key" | "bad_signature" | "expired" | "not_yet_valid" | "wrong_issuer" | "wrong_seller" | "wrong_offering" | "wrong_kind" | "wrong_session" | "body_mismatch" | "replayed" | "missing";
15
+ /** The request is not paid: no receipt, a forged or expired one, or one for another seller / offering / body. */
16
+ export declare class ReceiptInvalidError extends AmbasadaError {
17
+ readonly reason: ReceiptFailure;
18
+ constructor(reason: ReceiptFailure, message: string);
19
+ }
@@ -0,0 +1,27 @@
1
+ /**
2
+ * @ambasada/village: the Hack A Ton add-on. Accept and spend TON in the village, on top of the
3
+ * Ambasada platform client (`@ambasada/sdk`).
4
+ *
5
+ * import { village } from "./index.js"; // AMBASADA_API_KEY, AMBASADA_VILLAGE_API_URL from the env
6
+ * const { url } = await village.checkout({ amount: 3, description: "Coffee", success_url });
7
+ * export const POST = village.sell("translate", async ({ text, to }) => ({ text: await village.llm(`Translate to ${to}: ${text}`) }));
8
+ * const user = await village.auth.user(req); // the platform client's methods work too
9
+ *
10
+ * Works in Node ≥ 22, Bun, Cloudflare Workers (`createVillage({ env })`) and Next.js route handlers.
11
+ */
12
+ import { Village } from "./client.js";
13
+ export { Village, createVillage, DEFAULT_VILLAGE_API_URL, DEFAULT_MODEL } from "./client.js";
14
+ export type { VillageOptions, VerifyReceiptOptions, SellHandler } from "./client.js";
15
+ export { VillageError, isVillageError, ReceiptInvalidError } from "./errors.js";
16
+ export type { ReceiptFailure } from "./errors.js";
17
+ export type * from "./types.js";
18
+ export { verifyWebhookPayload, webhookHeaders, generateWebhookSecret, WEBHOOK_HEADERS } from "./webhook.js";
19
+ export { RECEIPT_HEADER, readIncoming, verifyCallReceipt, verifyCheckoutReceiptToken } from "./receipt.js";
20
+ export type { IncomingRequest } from "./receipt.js";
21
+ export { defineCompany, offering } from "./define.js";
22
+ export type { CompanyConfig, OfferingDef, VillageConfig } from "./define.js";
23
+ export { Ambasada, AmbasadaError, isAmbasadaError, defineApp, ERROR_STATUS, WebhookInvalidError } from "../platform.js";
24
+ export type { AmbasadaUser, AppConfig, ErrorCode, ErrorDetails, Jwk, StoredFile, StoreList, StoreWrite, WebhookFailure } from "../platform.js";
25
+ /** The default client, configured from the environment at call time. */
26
+ export declare const village: Village;
27
+ export default village;
@@ -3,8 +3,8 @@
3
3
  * by the village, committing to the buyer, seller, offering, amount and the SHA-256 of the exact body.
4
4
  * The seller checks it offline against `<api>/.well-known/jwks.json` (cached), no round-trip.
5
5
  */
6
- import type { CheckoutReceiptClaims, Jwk, ReceiptClaims } from "./types.js";
7
- import { type HeaderSource } from "./webhook.js";
6
+ import { type HeaderSource, type Jwk } from "../platform.js";
7
+ import type { CheckoutReceiptClaims, ReceiptClaims } from "./types.js";
8
8
  export declare const RECEIPT_HEADER = "x-village-receipt";
9
9
  export type KeySource = Jwk[] | (() => Promise<Jwk[]>);
10
10
  /** A fetch `Request`, or a Node / Express request (raw body in `body` / `rawBody`, or an unread stream). */