@ambasada/sdk 0.8.1 → 0.8.2

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ambasada/sdk",
3
- "version": "0.8.1",
3
+ "version": "0.8.2",
4
4
  "description": "The Ambasada platform SDK: Sign in with Ambasada, mini-app notifications, the project store, files.",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -9,6 +9,10 @@
9
9
  ".": {
10
10
  "types": "./dist/index.d.ts",
11
11
  "default": "./dist/index.js"
12
+ },
13
+ "./platform": {
14
+ "types": "./dist/platform.d.ts",
15
+ "default": "./dist/platform.js"
12
16
  }
13
17
  },
14
18
  "publishConfig": {
@@ -22,13 +26,15 @@
22
26
  "engines": {
23
27
  "node": ">=22"
24
28
  },
29
+ "dependencies": {
30
+ "@ambasada/village": "^0.8.2"
31
+ },
25
32
  "devDependencies": {
26
33
  "@types/node": "^22.20.5",
27
34
  "esbuild": "^0.28.2",
28
35
  "typescript": "~5.9.3",
29
36
  "vitest": "^4.1.12",
30
- "@ambasada/protocol": "0.1.0",
31
- "@ambasada/village": "0.8.1"
37
+ "@ambasada/protocol": "0.1.0"
32
38
  },
33
39
  "author": "CENTYSO (https://centyso.com)",
34
40
  "homepage": "https://ambasada.id",
@@ -1,148 +0,0 @@
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;
@@ -1,44 +0,0 @@
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;
@@ -1,19 +0,0 @@
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
- }
@@ -1,27 +0,0 @@
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;
@@ -1,50 +0,0 @@
1
- /**
2
- * Receipt verification. A paid call reaches a seller with `x-village-receipt`: an Ed25519 JWT signed
3
- * by the village, committing to the buyer, seller, offering, amount and the SHA-256 of the exact body.
4
- * The seller checks it offline against `<api>/.well-known/jwks.json` (cached), no round-trip.
5
- */
6
- import { type HeaderSource, type Jwk } from "../platform.js";
7
- import type { CheckoutReceiptClaims, ReceiptClaims } from "./types.js";
8
- export declare const RECEIPT_HEADER = "x-village-receipt";
9
- export type KeySource = Jwk[] | (() => Promise<Jwk[]>);
10
- /** A fetch `Request`, or a Node / Express request (raw body in `body` / `rawBody`, or an unread stream). */
11
- export type IncomingRequest = Request | {
12
- headers: HeaderSource;
13
- body?: unknown;
14
- rawBody?: unknown;
15
- [Symbol.asyncIterator]?: () => AsyncIterator<unknown>;
16
- };
17
- export interface Incoming {
18
- headers: HeaderSource;
19
- body: Uint8Array;
20
- }
21
- /** Reads headers and the raw body without consuming a fetch `Request` (it is cloned). */
22
- export declare function readIncoming(req: IncomingRequest): Promise<Incoming>;
23
- export interface CallReceiptCheck {
24
- keys: KeySource;
25
- /** Your company id: required, so a receipt bought from someone else can't be replayed at you. */
26
- seller: string;
27
- /** `<seller>/<offering>`, when you want to pin the offering. */
28
- offering?: string;
29
- issuer?: string;
30
- now?: number;
31
- }
32
- /** Verifies a call receipt token against the raw body. Throws `ReceiptInvalidError`. */
33
- export declare function verifyCallReceipt(token: string | null, body: Uint8Array, check: CallReceiptCheck): Promise<ReceiptClaims>;
34
- export interface CheckoutReceiptCheck {
35
- keys: KeySource;
36
- seller: string;
37
- session?: string;
38
- issuer?: string;
39
- now?: number;
40
- clockSkewSeconds?: number;
41
- }
42
- /** Verifies a checkout receipt (from pay.js `village:paid` or `session.receipt`) with `@ambasada/protocol`. Throws `ReceiptInvalidError`. */
43
- export declare function verifyCheckoutReceiptToken(token: string | null | undefined, check: CheckoutReceiptCheck): Promise<CheckoutReceiptClaims>;
44
- /** Remembers call ids until their receipt expires, so one receipt pays for one call (per process). */
45
- export declare class ReplayGuard {
46
- private seen;
47
- /** Returns false if the call id was already used. */
48
- claim(callId: string, exp: number): boolean;
49
- }
50
- export declare function receiptHeader(headers: HeaderSource): string | null;
@@ -1,307 +0,0 @@
1
- /** Village wire types. TON amounts are decimal numbers (`1`, `0.5`). */
2
- /** What a seller learns from a Gateway call receipt (`x-village-receipt`). Same shape as `@ambasada/protocol`. */
3
- export interface ReceiptClaims {
4
- iss: string;
5
- jti: string;
6
- call_id: string;
7
- /** Buyer company id. */
8
- buyer: string;
9
- /** Your company id. */
10
- seller: string;
11
- /** `<seller>/<offering name>` */
12
- offering: string;
13
- /** TON */
14
- amount: number;
15
- /** 1 for a direct buy; forward it with `buy(…, { parent })`. */
16
- depth: number;
17
- /** TON you may still spend downstream on behalf of this call. */
18
- budget?: number;
19
- deal_id?: string;
20
- body_sha256: string;
21
- iat: number;
22
- exp: number;
23
- }
24
- /** A verified paid call: the receipt plus the parsed JSON input. */
25
- export interface PaidCall<Input = any> extends ReceiptClaims {
26
- input: Input;
27
- }
28
- /** A checkout receipt (pay.js `village:paid`, or `session.receipt`). */
29
- export interface CheckoutReceiptClaims {
30
- iss: string;
31
- jti: string;
32
- kind: "checkout";
33
- session: string;
34
- /** The person's pseudonymous wallet id (`p_…`). */
35
- buyer: string;
36
- seller: string;
37
- amount: number;
38
- description: string;
39
- ref?: string;
40
- log_index: number;
41
- iat: number;
42
- exp: number;
43
- }
44
- export interface CheckoutInput {
45
- /** TON, 0.1–500. Or give `offering` to charge one of your offerings' price. */
46
- amount?: number;
47
- offering?: string;
48
- /** Shown to the person and written to the public ledger as the memo. No personal data. */
49
- description: string;
50
- /** `{CHECKOUT_SESSION_ID}` anywhere in the URL is replaced; otherwise `?session=cs_…` is appended. */
51
- success_url: string;
52
- cancel_url?: string;
53
- client_reference_id?: string;
54
- metadata?: Record<string, string>;
55
- /** Seconds, 300–86400 (default 3600). */
56
- expires_in?: number;
57
- }
58
- export interface CheckoutSession {
59
- id: string;
60
- object: "checkout.session";
61
- url: string;
62
- status: "open" | "paid" | "expired" | (string & {});
63
- amount: number;
64
- description: string;
65
- offering: string | null;
66
- /** The payment link it came from (`pl_…`), if any. */
67
- link: string | null;
68
- client_reference_id: string | null;
69
- metadata: Record<string, string>;
70
- success_url: string;
71
- cancel_url: string | null;
72
- buyer: string | null;
73
- paid_at: string | null;
74
- log_index: number | null;
75
- receipt: string | null;
76
- created_at: string;
77
- expires_at: string;
78
- [key: string]: unknown;
79
- }
80
- export interface PaymentLinkInput {
81
- amount?: number;
82
- offering?: string;
83
- description: string;
84
- success_url: string;
85
- cancel_url?: string;
86
- metadata?: Record<string, string>;
87
- }
88
- export interface PaymentLink {
89
- id: string;
90
- object: "checkout.link";
91
- url: string;
92
- active: boolean;
93
- amount: number;
94
- description: string;
95
- offering: string | null;
96
- metadata: Record<string, string>;
97
- success_url: string;
98
- cancel_url: string | null;
99
- created_at: string;
100
- [key: string]: unknown;
101
- }
102
- export interface WebhookDelivery {
103
- id: string;
104
- type: string;
105
- status: "pending" | "delivered" | "failed" | (string & {});
106
- attempts: number;
107
- [key: string]: unknown;
108
- }
109
- export interface WebhookEvent<Data = any> {
110
- /** `webhook-id` header: dedupe on it, retries reuse it. */
111
- id: string;
112
- type: "checkout.paid" | "webhook.test" | (string & {});
113
- timestamp: string;
114
- data: Data;
115
- }
116
- export interface BuyOptions {
117
- /** Refuse (PRICE_ABOVE_MAX) if the offering costs more than this, in TON. */
118
- maxPrice?: number;
119
- /** Retries with the same key never charge twice. Default: a random key per call (reused by the SDK's own retry). */
120
- idempotencyKey?: string;
121
- /** Inside a paid handler: forward the chain depth and remaining budget of the call you are serving. */
122
- parent?: Pick<ReceiptClaims, "depth" | "budget">;
123
- /** TON this call may spend downstream (`x-village-budget`). */
124
- budget?: number;
125
- /** An approved approval id, after APPROVAL_REQUIRED. */
126
- approval?: string;
127
- /** Why you are buying; shown to your team on approval requests. */
128
- reason?: string;
129
- signal?: AbortSignal;
130
- }
131
- export interface BuyResult<Output = any> {
132
- output: Output;
133
- callId: string | null;
134
- /** TON charged. */
135
- amount: number | null;
136
- /** The signed receipt for the call (you hold it too). */
137
- receipt: string | null;
138
- /** Position in the public ledger log. */
139
- logIndex: number | null;
140
- /** True when the Gateway replayed a previous result for the same idempotency key (no new charge). */
141
- replayed: boolean;
142
- /** For `need()`: which offering served it (`company/name`), if the Gateway says. */
143
- offering: string | null;
144
- }
145
- export type ChatModel = "deepseek-v4.1-flash" | "deepseek-v4-pro" | "glm-5.3-flash" | (string & {});
146
- export interface ChatMessage {
147
- role: "system" | "user" | "assistant" | "tool";
148
- content: string;
149
- [key: string]: unknown;
150
- }
151
- /** OpenAI-compatible chat request. */
152
- export interface ChatRequest {
153
- model?: ChatModel;
154
- messages: ChatMessage[];
155
- temperature?: number;
156
- max_tokens?: number;
157
- response_format?: {
158
- type: "text" | "json_object";
159
- } | Record<string, unknown>;
160
- [key: string]: unknown;
161
- }
162
- export interface ChatResponse {
163
- id: string;
164
- object: "chat.completion";
165
- model: string;
166
- choices: {
167
- index: number;
168
- message: ChatMessage;
169
- finish_reason: string | null;
170
- }[];
171
- usage?: {
172
- prompt_tokens: number;
173
- completion_tokens: number;
174
- total_tokens: number;
175
- };
176
- [key: string]: unknown;
177
- }
178
- export interface ImageRequest {
179
- model?: "nano_banana" | "gpt-image-2" | (string & {});
180
- prompt: string;
181
- }
182
- export interface ImageResult {
183
- /** Re-hosted in the village files store; safe to pass to other products. */
184
- url: string;
185
- /** TON charged. */
186
- cost: number;
187
- call_id: string;
188
- }
189
- export interface ToolListing {
190
- id: string;
191
- name: string;
192
- description: string;
193
- price_ton?: number;
194
- price?: number;
195
- unit?: string;
196
- input?: unknown;
197
- output?: unknown;
198
- [key: string]: unknown;
199
- }
200
- export interface ToolResult<Output = any> {
201
- output: Output;
202
- callId: string | null;
203
- /** TON charged. */
204
- amount: number | null;
205
- replayed: boolean;
206
- }
207
- /** Offering field schema shorthand: `{ text: "string", to: "string", tone: "string?" }`. */
208
- export type FieldSchema = Record<string, string>;
209
- export interface ListingInput {
210
- description: string;
211
- /** TON, 0.1–500. */
212
- price: number;
213
- /** Absolute URL the Gateway POSTs paid calls to. */
214
- endpoint: string;
215
- input?: FieldSchema | null;
216
- output?: FieldSchema | null;
217
- timeout_ms?: number;
218
- status?: "open" | "paused";
219
- preview?: boolean;
220
- }
221
- export interface Listing extends ListingInput {
222
- id: string;
223
- company: string;
224
- name: string;
225
- version: number;
226
- [key: string]: unknown;
227
- }
228
- export interface Wallet {
229
- account: string;
230
- balance: number;
231
- held: number;
232
- available: number;
233
- }
234
- export interface LedgerEntry {
235
- seq: number;
236
- id: string;
237
- ts: string;
238
- kind: string;
239
- direction: "in" | "out";
240
- counterparty: string;
241
- amount: number;
242
- balance_after: number;
243
- ref: string | null;
244
- memo: string | null;
245
- hold_id?: string | null;
246
- log_index?: number | null;
247
- [key: string]: unknown;
248
- }
249
- export interface LedgerPage {
250
- entries: LedgerEntry[];
251
- /** Pass back as `since` for the next page. */
252
- next_since: number;
253
- }
254
- export interface TransferOptions {
255
- reason?: string;
256
- ref?: string;
257
- idempotencyKey?: string;
258
- }
259
- /** `agent/settings.json`, sent with the prompt to `POST /v1/agent/config` (agent stream wire format). */
260
- export interface AgentSettings {
261
- model?: "deepseek-v4.1-flash" | "deepseek-v4-pro";
262
- enabled?: boolean;
263
- wake?: {
264
- interval_minutes?: number;
265
- min_event_gap_seconds?: number;
266
- };
267
- budget?: {
268
- tool_calls_per_wake?: number;
269
- tokens_per_wake?: number;
270
- max_turns?: number;
271
- compute_per_day?: number;
272
- };
273
- /** Agent tools offered to the model (default: all). */
274
- tools?: string[];
275
- /** Company wallet spend limits, TON. Over `auto_per_payment` an agent payment needs the team's approval. */
276
- limits?: {
277
- per_payment?: number;
278
- per_hour?: number;
279
- per_day?: number;
280
- per_payee_day?: number;
281
- auto_per_payment?: number;
282
- auto_per_day?: number;
283
- };
284
- [key: string]: unknown;
285
- }
286
- export interface AgentConfigInput extends AgentSettings {
287
- /** The text of agent/agent.md. */
288
- prompt?: string;
289
- /** Wake the agent once after saving. */
290
- wake_now?: boolean;
291
- }
292
- export interface TranscriptEntry {
293
- seq: number;
294
- ts: string;
295
- kind: string;
296
- data?: unknown;
297
- [key: string]: unknown;
298
- }
299
- export interface MarketOffering {
300
- id: string;
301
- company?: string;
302
- name: string;
303
- description: string;
304
- price: number;
305
- source?: "company" | "village-tool";
306
- [key: string]: unknown;
307
- }
@@ -1,30 +0,0 @@
1
- /**
2
- * Webhook signatures: Standard Webhooks (https://www.standardwebhooks.com), exactly as the village
3
- * signs them in `@ambasada/protocol` (packages/protocol/src/webhook.ts):
4
- *
5
- * webhook-id: msg_… webhook-timestamp: <unix s> webhook-signature: v1,<base64 HMAC-SHA256>
6
- * signed content = "<id>.<timestamp>.<raw body>", key = the base64 bytes after `whsec_`
7
- * body = { "type": "checkout.paid" | "webhook.test", "timestamp": ISO, "data": … }
8
- *
9
- * This module wraps the protocol functions with the SDK's error type and event shape.
10
- */
11
- import { type HeaderSource } from "../platform.js";
12
- import type { WebhookEvent } from "./types.js";
13
- /** The three Standard Webhooks headers. */
14
- export declare const WEBHOOK_HEADERS: {
15
- readonly id: "webhook-id";
16
- readonly timestamp: "webhook-timestamp";
17
- readonly signature: "webhook-signature";
18
- };
19
- /** A fresh `whsec_…` signing secret. */
20
- export declare const generateWebhookSecret: () => string;
21
- /** The headers that sign `body` (tests, your own senders). */
22
- export declare const webhookHeaders: (secret: string, id: string, timestamp: number, body: string) => Promise<Record<string, string>>;
23
- /**
24
- * Verifies a raw webhook (headers + body exactly as received) and returns the event, or throws
25
- * `WebhookInvalidError`. Prefer `village.verifyWebhook(req)`, which reads a `Request` for you.
26
- */
27
- export declare function verifyWebhookPayload<Data = any>(secret: string, headers: HeaderSource, body: string | Uint8Array, options?: {
28
- toleranceSeconds?: number;
29
- now?: number;
30
- }): Promise<WebhookEvent<Data>>;