@querais/shared 0.2.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.
@@ -0,0 +1,77 @@
1
+ /**
2
+ * Signed model manifest — the operator's off-chain statement of which model
3
+ * binaries (by Ollama sha256 digest) count as "the real model" on this network.
4
+ *
5
+ * Lives in shared because both sides of the trust relationship consume it:
6
+ * the gateway loads + signs the manifest at boot and enforces it at node
7
+ * handshake; the node daemon fetches it from `GET /v1/models/manifest` and
8
+ * verifies the signature against the gateway's settler address (which it
9
+ * already learns from `/v1/credit/info`) before trusting the digests.
10
+ *
11
+ * Signing is EIP-191 (`personal_sign`) over a canonical JSON form — model keys
12
+ * sorted, entry fields in fixed order — so any holder of the manifest can
13
+ * re-derive the exact signed bytes and verify offline. No contract involved
14
+ * (Slice 9 decision: exclusion, not punishment — a mismatched model is simply
15
+ * not served; slashing stays with the dispute system).
16
+ */
17
+ import { recoverMessageAddress } from 'viem';
18
+ import { z } from 'zod';
19
+ /** Ollama-style digest of the model blob: "sha256:" + 64 lowercase hex chars. */
20
+ export const MODEL_DIGEST_REGEX = /^sha256:[0-9a-f]{64}$/;
21
+ export const modelManifestEntrySchema = z.object({
22
+ digest: z.string().regex(MODEL_DIGEST_REGEX, 'digest must be "sha256:" + 64 lowercase hex chars'),
23
+ /** Free-form operator note ("gemma3:4b pulled 2026-06-01"); not enforced. */
24
+ note: z.string().max(500).optional(),
25
+ });
26
+ /** The unsigned manifest body — what the operator authors as a JSON file. */
27
+ export const modelManifestSchema = z
28
+ .object({
29
+ models: z.record(z.string().min(1).max(200), modelManifestEntrySchema),
30
+ })
31
+ .strict();
32
+ const hexAddress = z.string().regex(/^0x[0-9a-fA-F]{40}$/);
33
+ /** Wire form served by `GET /v1/models/manifest` (and verified by daemons). */
34
+ export const signedModelManifestSchema = z.object({
35
+ models: z.record(z.string().min(1).max(200), modelManifestEntrySchema),
36
+ signer: hexAddress,
37
+ signature: z.string().regex(/^0x[0-9a-fA-F]+$/),
38
+ });
39
+ /**
40
+ * The exact byte string that gets signed: `{"models":{...}}` with model keys
41
+ * sorted and entry fields in fixed (digest, note) order. Deterministic across
42
+ * runtimes, so gateway and daemon always derive identical bytes.
43
+ */
44
+ export function canonicalModelManifestJson(models) {
45
+ const sorted = {};
46
+ for (const name of Object.keys(models).sort()) {
47
+ const entry = models[name];
48
+ sorted[name] =
49
+ entry.note === undefined
50
+ ? { digest: entry.digest }
51
+ : { digest: entry.digest, note: entry.note };
52
+ }
53
+ return JSON.stringify({ models: sorted });
54
+ }
55
+ /** Sign the manifest with the gateway key (done once at boot). */
56
+ export async function signModelManifest(signer, signerAddress, models) {
57
+ const signature = await signer.signMessage({ message: canonicalModelManifestJson(models) });
58
+ return { models, signer: signerAddress, signature };
59
+ }
60
+ /**
61
+ * Verify a fetched manifest: recover the EIP-191 signer from the canonical
62
+ * JSON and compare to the claimed `signer`. Pure (no RPC); returns false on
63
+ * any malformed input rather than throwing.
64
+ */
65
+ export async function verifyModelManifest(manifest) {
66
+ try {
67
+ const recovered = await recoverMessageAddress({
68
+ message: canonicalModelManifestJson(manifest.models),
69
+ signature: manifest.signature,
70
+ });
71
+ return recovered.toLowerCase() === manifest.signer.toLowerCase();
72
+ }
73
+ catch {
74
+ return false;
75
+ }
76
+ }
77
+ //# sourceMappingURL=model-manifest.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"model-manifest.js","sourceRoot":"","sources":["../src/model-manifest.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,140 @@
1
+ import { z } from 'zod';
2
+ /** Roles QueraIS supports in the MVP chat API. */
3
+ export declare const chatRoleSchema: z.ZodEnum<["system", "user", "assistant"]>;
4
+ export type ChatRole = z.infer<typeof chatRoleSchema>;
5
+ export declare const chatMessageSchema: z.ZodObject<{
6
+ role: z.ZodEnum<["system", "user", "assistant"]>;
7
+ content: z.ZodString;
8
+ }, "strip", z.ZodTypeAny, {
9
+ role: "system" | "user" | "assistant";
10
+ content: string;
11
+ }, {
12
+ role: "system" | "user" | "assistant";
13
+ content: string;
14
+ }>;
15
+ export type ChatMessage = z.infer<typeof chatMessageSchema>;
16
+ /**
17
+ * OpenAI-compatible chat completion request, plus QueraIS routing extensions.
18
+ * Unknown fields are passed through (ignored) so existing OpenAI clients work
19
+ * unchanged. `.strip()` would drop extras; we keep the surface forgiving.
20
+ */
21
+ export declare const chatCompletionRequestSchema: z.ZodObject<{
22
+ model: z.ZodString;
23
+ messages: z.ZodArray<z.ZodObject<{
24
+ role: z.ZodEnum<["system", "user", "assistant"]>;
25
+ content: z.ZodString;
26
+ }, "strip", z.ZodTypeAny, {
27
+ role: "system" | "user" | "assistant";
28
+ content: string;
29
+ }, {
30
+ role: "system" | "user" | "assistant";
31
+ content: string;
32
+ }>, "many">;
33
+ max_tokens: z.ZodOptional<z.ZodNumber>;
34
+ temperature: z.ZodOptional<z.ZodNumber>;
35
+ stream: z.ZodOptional<z.ZodBoolean>;
36
+ /** Max price the requester will pay, in QAIS per 1,000 tokens. */
37
+ max_price_per_1k_tokens: z.ZodOptional<z.ZodNumber>;
38
+ /** Minimum node reputation in [0,1]. */
39
+ min_reputation: z.ZodOptional<z.ZodNumber>;
40
+ }, "passthrough", z.ZodTypeAny, z.objectOutputType<{
41
+ model: z.ZodString;
42
+ messages: z.ZodArray<z.ZodObject<{
43
+ role: z.ZodEnum<["system", "user", "assistant"]>;
44
+ content: z.ZodString;
45
+ }, "strip", z.ZodTypeAny, {
46
+ role: "system" | "user" | "assistant";
47
+ content: string;
48
+ }, {
49
+ role: "system" | "user" | "assistant";
50
+ content: string;
51
+ }>, "many">;
52
+ max_tokens: z.ZodOptional<z.ZodNumber>;
53
+ temperature: z.ZodOptional<z.ZodNumber>;
54
+ stream: z.ZodOptional<z.ZodBoolean>;
55
+ /** Max price the requester will pay, in QAIS per 1,000 tokens. */
56
+ max_price_per_1k_tokens: z.ZodOptional<z.ZodNumber>;
57
+ /** Minimum node reputation in [0,1]. */
58
+ min_reputation: z.ZodOptional<z.ZodNumber>;
59
+ }, z.ZodTypeAny, "passthrough">, z.objectInputType<{
60
+ model: z.ZodString;
61
+ messages: z.ZodArray<z.ZodObject<{
62
+ role: z.ZodEnum<["system", "user", "assistant"]>;
63
+ content: z.ZodString;
64
+ }, "strip", z.ZodTypeAny, {
65
+ role: "system" | "user" | "assistant";
66
+ content: string;
67
+ }, {
68
+ role: "system" | "user" | "assistant";
69
+ content: string;
70
+ }>, "many">;
71
+ max_tokens: z.ZodOptional<z.ZodNumber>;
72
+ temperature: z.ZodOptional<z.ZodNumber>;
73
+ stream: z.ZodOptional<z.ZodBoolean>;
74
+ /** Max price the requester will pay, in QAIS per 1,000 tokens. */
75
+ max_price_per_1k_tokens: z.ZodOptional<z.ZodNumber>;
76
+ /** Minimum node reputation in [0,1]. */
77
+ min_reputation: z.ZodOptional<z.ZodNumber>;
78
+ }, z.ZodTypeAny, "passthrough">>;
79
+ export type ChatCompletionRequest = z.infer<typeof chatCompletionRequestSchema>;
80
+ export type FinishReason = 'stop' | 'length' | 'content_filter' | null;
81
+ export interface ChatCompletionUsage {
82
+ prompt_tokens: number;
83
+ completion_tokens: number;
84
+ total_tokens: number;
85
+ }
86
+ export interface ChatCompletionChoice {
87
+ index: number;
88
+ message: ChatMessage;
89
+ finish_reason: FinishReason;
90
+ }
91
+ export interface ChatCompletionResponse {
92
+ id: string;
93
+ object: 'chat.completion';
94
+ created: number;
95
+ model: string;
96
+ choices: ChatCompletionChoice[];
97
+ usage: ChatCompletionUsage;
98
+ }
99
+ export interface ChatCompletionChunk {
100
+ id: string;
101
+ object: 'chat.completion.chunk';
102
+ created: number;
103
+ model: string;
104
+ choices: Array<{
105
+ index: number;
106
+ delta: {
107
+ role?: ChatRole;
108
+ content?: string;
109
+ };
110
+ finish_reason: FinishReason;
111
+ }>;
112
+ }
113
+ /** Build a non-streaming chat completion response from a finished generation. */
114
+ export declare function buildChatCompletion(params: {
115
+ id: string;
116
+ created: number;
117
+ model: string;
118
+ content: string;
119
+ promptTokens: number;
120
+ completionTokens: number;
121
+ finishReason: FinishReason;
122
+ }): ChatCompletionResponse;
123
+ /** Build a single streaming chunk carrying a content delta. */
124
+ export declare function buildChunk(params: {
125
+ id: string;
126
+ created: number;
127
+ model: string;
128
+ content?: string;
129
+ role?: ChatRole;
130
+ finishReason?: FinishReason;
131
+ }): ChatCompletionChunk;
132
+ export interface ModelListResponse {
133
+ object: 'list';
134
+ data: Array<{
135
+ id: string;
136
+ object: 'model';
137
+ owned_by: string;
138
+ }>;
139
+ }
140
+ //# sourceMappingURL=openai.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"openai.d.ts","sourceRoot":"","sources":["../src/openai.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,kDAAkD;AAClD,eAAO,MAAM,cAAc,4CAA0C,CAAC;AACtE,MAAM,MAAM,QAAQ,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,cAAc,CAAC,CAAC;AAEtD,eAAO,MAAM,iBAAiB;;;;;;;;;EAG5B,CAAC;AACH,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAC;AAE5D;;;;GAIG;AACH,eAAO,MAAM,2BAA2B;;;;;;;;;;;;;;;IAQpC,kEAAkE;;IAElE,wCAAwC;;;;;;;;;;;;;;;;;IAFxC,kEAAkE;;IAElE,wCAAwC;;;;;;;;;;;;;;;;;IAFxC,kEAAkE;;IAElE,wCAAwC;;gCAG5B,CAAC;AACjB,MAAM,MAAM,qBAAqB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,2BAA2B,CAAC,CAAC;AAEhF,MAAM,MAAM,YAAY,GAAG,MAAM,GAAG,QAAQ,GAAG,gBAAgB,GAAG,IAAI,CAAC;AAEvE,MAAM,WAAW,mBAAmB;IAClC,aAAa,EAAE,MAAM,CAAC;IACtB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,oBAAoB;IACnC,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,WAAW,CAAC;IACrB,aAAa,EAAE,YAAY,CAAC;CAC7B;AAED,MAAM,WAAW,sBAAsB;IACrC,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,iBAAiB,CAAC;IAC1B,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,oBAAoB,EAAE,CAAC;IAChC,KAAK,EAAE,mBAAmB,CAAC;CAC5B;AAED,MAAM,WAAW,mBAAmB;IAClC,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,uBAAuB,CAAC;IAChC,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,KAAK,CAAC;QACb,KAAK,EAAE,MAAM,CAAC;QACd,KAAK,EAAE;YAAE,IAAI,CAAC,EAAE,QAAQ,CAAC;YAAC,OAAO,CAAC,EAAE,MAAM,CAAA;SAAE,CAAC;QAC7C,aAAa,EAAE,YAAY,CAAC;KAC7B,CAAC,CAAC;CACJ;AAED,iFAAiF;AACjF,wBAAgB,mBAAmB,CAAC,MAAM,EAAE;IAC1C,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,MAAM,CAAC;IACrB,gBAAgB,EAAE,MAAM,CAAC;IACzB,YAAY,EAAE,YAAY,CAAC;CAC5B,GAAG,sBAAsB,CAmBzB;AAED,+DAA+D;AAC/D,wBAAgB,UAAU,CAAC,MAAM,EAAE;IACjC,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,QAAQ,CAAC;IAChB,YAAY,CAAC,EAAE,YAAY,CAAC;CAC7B,GAAG,mBAAmB,CAiBtB;AAED,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,KAAK,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,OAAO,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CAChE"}
package/dist/openai.js ADDED
@@ -0,0 +1,67 @@
1
+ import { z } from 'zod';
2
+ /** Roles QueraIS supports in the MVP chat API. */
3
+ export const chatRoleSchema = z.enum(['system', 'user', 'assistant']);
4
+ export const chatMessageSchema = z.object({
5
+ role: chatRoleSchema,
6
+ content: z.string(),
7
+ });
8
+ /**
9
+ * OpenAI-compatible chat completion request, plus QueraIS routing extensions.
10
+ * Unknown fields are passed through (ignored) so existing OpenAI clients work
11
+ * unchanged. `.strip()` would drop extras; we keep the surface forgiving.
12
+ */
13
+ export const chatCompletionRequestSchema = z
14
+ .object({
15
+ model: z.string().min(1),
16
+ messages: z.array(chatMessageSchema).min(1),
17
+ max_tokens: z.number().int().positive().max(32_768).optional(),
18
+ temperature: z.number().min(0).max(2).optional(),
19
+ stream: z.boolean().optional(),
20
+ // ── QueraIS extensions (all optional) ──
21
+ /** Max price the requester will pay, in QAIS per 1,000 tokens. */
22
+ max_price_per_1k_tokens: z.number().positive().optional(),
23
+ /** Minimum node reputation in [0,1]. */
24
+ min_reputation: z.number().min(0).max(1).optional(),
25
+ })
26
+ .passthrough();
27
+ /** Build a non-streaming chat completion response from a finished generation. */
28
+ export function buildChatCompletion(params) {
29
+ return {
30
+ id: params.id,
31
+ object: 'chat.completion',
32
+ created: params.created,
33
+ model: params.model,
34
+ choices: [
35
+ {
36
+ index: 0,
37
+ message: { role: 'assistant', content: params.content },
38
+ finish_reason: params.finishReason,
39
+ },
40
+ ],
41
+ usage: {
42
+ prompt_tokens: params.promptTokens,
43
+ completion_tokens: params.completionTokens,
44
+ total_tokens: params.promptTokens + params.completionTokens,
45
+ },
46
+ };
47
+ }
48
+ /** Build a single streaming chunk carrying a content delta. */
49
+ export function buildChunk(params) {
50
+ return {
51
+ id: params.id,
52
+ object: 'chat.completion.chunk',
53
+ created: params.created,
54
+ model: params.model,
55
+ choices: [
56
+ {
57
+ index: 0,
58
+ delta: {
59
+ ...(params.role ? { role: params.role } : {}),
60
+ ...(params.content !== undefined ? { content: params.content } : {}),
61
+ },
62
+ finish_reason: params.finishReason ?? null,
63
+ },
64
+ ],
65
+ };
66
+ }
67
+ //# sourceMappingURL=openai.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"openai.js","sourceRoot":"","sources":["../src/openai.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,kDAAkD;AAClD,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,MAAM,EAAE,WAAW,CAAC,CAAC,CAAC;AAGtE,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,CAAC,MAAM,CAAC;IACxC,IAAI,EAAE,cAAc;IACpB,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE;CACpB,CAAC,CAAC;AAGH;;;;GAIG;AACH,MAAM,CAAC,MAAM,2BAA2B,GAAG,CAAC;KACzC,MAAM,CAAC;IACN,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IACxB,QAAQ,EAAE,CAAC,CAAC,KAAK,CAAC,iBAAiB,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IAC3C,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,QAAQ,EAAE;IAC9D,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE;IAChD,MAAM,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE;IAC9B,0CAA0C;IAC1C,kEAAkE;IAClE,uBAAuB,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE;IACzD,wCAAwC;IACxC,cAAc,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE;CACpD,CAAC;KACD,WAAW,EAAE,CAAC;AAsCjB,iFAAiF;AACjF,MAAM,UAAU,mBAAmB,CAAC,MAQnC;IACC,OAAO;QACL,EAAE,EAAE,MAAM,CAAC,EAAE;QACb,MAAM,EAAE,iBAAiB;QACzB,OAAO,EAAE,MAAM,CAAC,OAAO;QACvB,KAAK,EAAE,MAAM,CAAC,KAAK;QACnB,OAAO,EAAE;YACP;gBACE,KAAK,EAAE,CAAC;gBACR,OAAO,EAAE,EAAE,IAAI,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,CAAC,OAAO,EAAE;gBACvD,aAAa,EAAE,MAAM,CAAC,YAAY;aACnC;SACF;QACD,KAAK,EAAE;YACL,aAAa,EAAE,MAAM,CAAC,YAAY;YAClC,iBAAiB,EAAE,MAAM,CAAC,gBAAgB;YAC1C,YAAY,EAAE,MAAM,CAAC,YAAY,GAAG,MAAM,CAAC,gBAAgB;SAC5D;KACF,CAAC;AACJ,CAAC;AAED,+DAA+D;AAC/D,MAAM,UAAU,UAAU,CAAC,MAO1B;IACC,OAAO;QACL,EAAE,EAAE,MAAM,CAAC,EAAE;QACb,MAAM,EAAE,uBAAuB;QAC/B,OAAO,EAAE,MAAM,CAAC,OAAO;QACvB,KAAK,EAAE,MAAM,CAAC,KAAK;QACnB,OAAO,EAAE;YACP;gBACE,KAAK,EAAE,CAAC;gBACR,KAAK,EAAE;oBACL,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;oBAC7C,GAAG,CAAC,MAAM,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;iBACrE;gBACD,aAAa,EAAE,MAAM,CAAC,YAAY,IAAI,IAAI;aAC3C;SACF;KACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,27 @@
1
+ /** Protocol fee in basis points (5%). Mirrors JobEscrow.protocolFeeRate default. */
2
+ export declare const FEE_BPS = 500;
3
+ export declare const BPS_DENOMINATOR = 10000n;
4
+ /** Convert a QAIS amount (decimal string or number) to wei. */
5
+ export declare function qaisToWei(qais: number | string): bigint;
6
+ /** Human-readable QAIS string from wei. */
7
+ export declare function weiToQais(wei: bigint): string;
8
+ /**
9
+ * Convert a "QAIS per 1,000 tokens" price (the developer-facing unit in the
10
+ * OpenAI-compatible request) into integer wei-per-token. Done ONCE at job
11
+ * creation so the chain never sees a float.
12
+ */
13
+ export declare function per1kQaisToWeiPerToken(qaisPer1k: number | string): bigint;
14
+ /** Amount locked in escrow for a job: maxPricePerToken * maxTokens (integer wei). */
15
+ export declare function lockAmount(maxPricePerTokenWei: bigint, maxTokens: number | bigint): bigint;
16
+ /** Actual payment owed: agreedPricePerToken * actualTokens (integer wei). */
17
+ export declare function paymentFor(agreedPricePerTokenWei: bigint, actualTokens: number | bigint): bigint;
18
+ /**
19
+ * Split a payment into provider and protocol shares using basis-point integer
20
+ * math — identical to JobEscrow.verifyAndRelease so off-chain estimates match
21
+ * on-chain settlement exactly.
22
+ */
23
+ export declare function splitPayment(actualPayment: bigint, feeBps?: number): {
24
+ providerPay: bigint;
25
+ fee: bigint;
26
+ };
27
+ //# sourceMappingURL=pricing.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pricing.d.ts","sourceRoot":"","sources":["../src/pricing.ts"],"names":[],"mappings":"AAEA,oFAAoF;AACpF,eAAO,MAAM,OAAO,MAAM,CAAC;AAC3B,eAAO,MAAM,eAAe,SAAS,CAAC;AAEtC,+DAA+D;AAC/D,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,CAEvD;AAED,2CAA2C;AAC3C,wBAAgB,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAE7C;AAED;;;;GAIG;AACH,wBAAgB,sBAAsB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,CAEzE;AAED,qFAAqF;AACrF,wBAAgB,UAAU,CAAC,mBAAmB,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,CAE1F;AAED,6EAA6E;AAC7E,wBAAgB,UAAU,CAAC,sBAAsB,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,CAEhG;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAC1B,aAAa,EAAE,MAAM,EACrB,MAAM,GAAE,MAAgB,GACvB;IAAE,WAAW,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,CAGtC"}
@@ -0,0 +1,38 @@
1
+ import { parseEther, formatEther } from 'viem';
2
+ /** Protocol fee in basis points (5%). Mirrors JobEscrow.protocolFeeRate default. */
3
+ export const FEE_BPS = 500;
4
+ export const BPS_DENOMINATOR = 10000n;
5
+ /** Convert a QAIS amount (decimal string or number) to wei. */
6
+ export function qaisToWei(qais) {
7
+ return parseEther(typeof qais === 'number' ? qais.toString() : qais);
8
+ }
9
+ /** Human-readable QAIS string from wei. */
10
+ export function weiToQais(wei) {
11
+ return formatEther(wei);
12
+ }
13
+ /**
14
+ * Convert a "QAIS per 1,000 tokens" price (the developer-facing unit in the
15
+ * OpenAI-compatible request) into integer wei-per-token. Done ONCE at job
16
+ * creation so the chain never sees a float.
17
+ */
18
+ export function per1kQaisToWeiPerToken(qaisPer1k) {
19
+ return qaisToWei(qaisPer1k) / 1000n;
20
+ }
21
+ /** Amount locked in escrow for a job: maxPricePerToken * maxTokens (integer wei). */
22
+ export function lockAmount(maxPricePerTokenWei, maxTokens) {
23
+ return maxPricePerTokenWei * BigInt(maxTokens);
24
+ }
25
+ /** Actual payment owed: agreedPricePerToken * actualTokens (integer wei). */
26
+ export function paymentFor(agreedPricePerTokenWei, actualTokens) {
27
+ return agreedPricePerTokenWei * BigInt(actualTokens);
28
+ }
29
+ /**
30
+ * Split a payment into provider and protocol shares using basis-point integer
31
+ * math — identical to JobEscrow.verifyAndRelease so off-chain estimates match
32
+ * on-chain settlement exactly.
33
+ */
34
+ export function splitPayment(actualPayment, feeBps = FEE_BPS) {
35
+ const fee = (actualPayment * BigInt(feeBps)) / BPS_DENOMINATOR;
36
+ return { fee, providerPay: actualPayment - fee };
37
+ }
38
+ //# sourceMappingURL=pricing.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pricing.js","sourceRoot":"","sources":["../src/pricing.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,MAAM,CAAC;AAE/C,oFAAoF;AACpF,MAAM,CAAC,MAAM,OAAO,GAAG,GAAG,CAAC;AAC3B,MAAM,CAAC,MAAM,eAAe,GAAG,MAAM,CAAC;AAEtC,+DAA+D;AAC/D,MAAM,UAAU,SAAS,CAAC,IAAqB;IAC7C,OAAO,UAAU,CAAC,OAAO,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;AACvE,CAAC;AAED,2CAA2C;AAC3C,MAAM,UAAU,SAAS,CAAC,GAAW;IACnC,OAAO,WAAW,CAAC,GAAG,CAAC,CAAC;AAC1B,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,sBAAsB,CAAC,SAA0B;IAC/D,OAAO,SAAS,CAAC,SAAS,CAAC,GAAG,KAAK,CAAC;AACtC,CAAC;AAED,qFAAqF;AACrF,MAAM,UAAU,UAAU,CAAC,mBAA2B,EAAE,SAA0B;IAChF,OAAO,mBAAmB,GAAG,MAAM,CAAC,SAAS,CAAC,CAAC;AACjD,CAAC;AAED,6EAA6E;AAC7E,MAAM,UAAU,UAAU,CAAC,sBAA8B,EAAE,YAA6B;IACtF,OAAO,sBAAsB,GAAG,MAAM,CAAC,YAAY,CAAC,CAAC;AACvD,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,YAAY,CAC1B,aAAqB,EACrB,SAAiB,OAAO;IAExB,MAAM,GAAG,GAAG,CAAC,aAAa,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,eAAe,CAAC;IAC/D,OAAO,EAAE,GAAG,EAAE,WAAW,EAAE,aAAa,GAAG,GAAG,EAAE,CAAC;AACnD,CAAC"}
@@ -0,0 +1,101 @@
1
+ /**
2
+ * EIP-712 spending cap — the off-chain authorization a requester signs once per session
3
+ * so the gateway can batch-settle many jobs against a pre-funded CreditAccount balance
4
+ * without a per-call wallet tx. The struct and domain MUST match CreditAccount.sol exactly
5
+ * (SPENDING_CAP_TYPEHASH + EIP712("QueraIS CreditAccount", "1")), so the digest the
6
+ * requester signs is the one the contract recovers.
7
+ */
8
+ import { type Address, type Hex, type TypedDataDomain } from 'viem';
9
+ import { z } from 'zod';
10
+ /** Mirrors CreditAccount.SpendingCap. bigints are uint256 wei/seconds. */
11
+ export interface SpendingCap {
12
+ requester: Address;
13
+ settler: Address;
14
+ maxSpendWei: bigint;
15
+ nonce: bigint;
16
+ deadline: bigint;
17
+ }
18
+ /** EIP-712 type definition — field order must match SPENDING_CAP_TYPEHASH. */
19
+ export declare const SPENDING_CAP_TYPES: {
20
+ readonly SpendingCap: readonly [{
21
+ readonly name: "requester";
22
+ readonly type: "address";
23
+ }, {
24
+ readonly name: "settler";
25
+ readonly type: "address";
26
+ }, {
27
+ readonly name: "maxSpendWei";
28
+ readonly type: "uint256";
29
+ }, {
30
+ readonly name: "nonce";
31
+ readonly type: "uint256";
32
+ }, {
33
+ readonly name: "deadline";
34
+ readonly type: "uint256";
35
+ }];
36
+ };
37
+ export declare const SPENDING_CAP_DOMAIN_NAME = "QueraIS CreditAccount";
38
+ export declare const SPENDING_CAP_DOMAIN_VERSION = "1";
39
+ /** Build the EIP-712 domain for a CreditAccount deployment. */
40
+ export declare function spendingCapDomain(chainId: number, verifyingContract: Address): TypedDataDomain;
41
+ /** Minimal shape a signer must expose (viem LocalAccount / WalletClient both satisfy it). */
42
+ export interface TypedDataSigner {
43
+ signTypedData(args: {
44
+ domain: TypedDataDomain;
45
+ types: typeof SPENDING_CAP_TYPES;
46
+ primaryType: 'SpendingCap';
47
+ message: SpendingCap;
48
+ }): Promise<Hex>;
49
+ }
50
+ /** Sign a spending cap with a viem account/wallet client. Returns the 65-byte signature. */
51
+ export declare function signSpendingCap(signer: TypedDataSigner, cap: SpendingCap, domain: TypedDataDomain): Promise<Hex>;
52
+ /** The EIP-712 digest for a cap — must equal CreditAccount.hashSpendingCap(cap) on-chain. */
53
+ export declare function hashSpendingCap(cap: SpendingCap, domain: TypedDataDomain): Hex;
54
+ /** Recover the signer address from a cap + signature (mirrors ECDSA.recover on-chain). */
55
+ export declare function recoverSpendingCapSigner(cap: SpendingCap, domain: TypedDataDomain, signature: Hex): Promise<Address>;
56
+ export declare const signedSpendingCapSchema: z.ZodObject<{
57
+ requester: z.ZodString;
58
+ settler: z.ZodString;
59
+ maxSpendWei: z.ZodString;
60
+ nonce: z.ZodString;
61
+ deadline: z.ZodString;
62
+ signature: z.ZodString;
63
+ }, "strip", z.ZodTypeAny, {
64
+ nonce: string;
65
+ signature: string;
66
+ deadline: string;
67
+ requester: string;
68
+ settler: string;
69
+ maxSpendWei: string;
70
+ }, {
71
+ nonce: string;
72
+ signature: string;
73
+ deadline: string;
74
+ requester: string;
75
+ settler: string;
76
+ maxSpendWei: string;
77
+ }>;
78
+ export type SignedSpendingCapWire = z.infer<typeof signedSpendingCapSchema>;
79
+ /** Parse the wire form into a typed cap + signature (bigints decoded). */
80
+ export declare function toSpendingCap(wire: SignedSpendingCapWire): {
81
+ cap: SpendingCap;
82
+ signature: Hex;
83
+ };
84
+ /** Everything needed to build + sign a session cap from a private key (the SDK's view). */
85
+ export interface BuildSessionParams {
86
+ maxSpendWei: bigint;
87
+ nonce: bigint;
88
+ deadline: bigint;
89
+ settler: Address;
90
+ chainId: number;
91
+ verifyingContract: Address;
92
+ }
93
+ /**
94
+ * Build, sign, and serialize a spending cap from a private key — the one call the SDK makes
95
+ * to open a session. The requester is derived from the key; the result is POSTed to
96
+ * `/v1/sessions`. Keeps all signing in `shared` so the SDK needs no viem dependency.
97
+ */
98
+ export declare function buildSignedSession(privateKey: Hex, p: BuildSessionParams): Promise<SignedSpendingCapWire>;
99
+ /** Serialize a typed cap + signature into the wire form (bigints → decimal strings). */
100
+ export declare function toSignedSpendingCapWire(cap: SpendingCap, signature: Hex): SignedSpendingCapWire;
101
+ //# sourceMappingURL=spending-cap.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"spending-cap.d.ts","sourceRoot":"","sources":["../src/spending-cap.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,EAGL,KAAK,OAAO,EACZ,KAAK,GAAG,EACR,KAAK,eAAe,EACrB,MAAM,MAAM,CAAC;AAEd,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,0EAA0E;AAC1E,MAAM,WAAW,WAAW;IAC1B,SAAS,EAAE,OAAO,CAAC;IACnB,OAAO,EAAE,OAAO,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,8EAA8E;AAC9E,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;;;;;CAQrB,CAAC;AAEX,eAAO,MAAM,wBAAwB,0BAA0B,CAAC;AAChE,eAAO,MAAM,2BAA2B,MAAM,CAAC;AAE/C,+DAA+D;AAC/D,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,EAAE,iBAAiB,EAAE,OAAO,GAAG,eAAe,CAO9F;AAED,6FAA6F;AAC7F,MAAM,WAAW,eAAe;IAC9B,aAAa,CAAC,IAAI,EAAE;QAClB,MAAM,EAAE,eAAe,CAAC;QACxB,KAAK,EAAE,OAAO,kBAAkB,CAAC;QACjC,WAAW,EAAE,aAAa,CAAC;QAC3B,OAAO,EAAE,WAAW,CAAC;KACtB,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC;CAClB;AAED,4FAA4F;AAC5F,wBAAgB,eAAe,CAC7B,MAAM,EAAE,eAAe,EACvB,GAAG,EAAE,WAAW,EAChB,MAAM,EAAE,eAAe,GACtB,OAAO,CAAC,GAAG,CAAC,CAOd;AAED,6FAA6F;AAC7F,wBAAgB,eAAe,CAAC,GAAG,EAAE,WAAW,EAAE,MAAM,EAAE,eAAe,GAAG,GAAG,CAO9E;AAED,0FAA0F;AAC1F,wBAAgB,wBAAwB,CACtC,GAAG,EAAE,WAAW,EAChB,MAAM,EAAE,eAAe,EACvB,SAAS,EAAE,GAAG,GACb,OAAO,CAAC,OAAO,CAAC,CAQlB;AAUD,eAAO,MAAM,uBAAuB;;;;;;;;;;;;;;;;;;;;;EAOlC,CAAC;AAEH,MAAM,MAAM,qBAAqB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,uBAAuB,CAAC,CAAC;AAE5E,0EAA0E;AAC1E,wBAAgB,aAAa,CAAC,IAAI,EAAE,qBAAqB,GAAG;IAAE,GAAG,EAAE,WAAW,CAAC;IAAC,SAAS,EAAE,GAAG,CAAA;CAAE,CAW/F;AAED,2FAA2F;AAC3F,MAAM,WAAW,kBAAkB;IACjC,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,iBAAiB,EAAE,OAAO,CAAC;CAC5B;AAED;;;;GAIG;AACH,wBAAsB,kBAAkB,CACtC,UAAU,EAAE,GAAG,EACf,CAAC,EAAE,kBAAkB,GACpB,OAAO,CAAC,qBAAqB,CAAC,CAYhC;AAED,wFAAwF;AACxF,wBAAgB,uBAAuB,CAAC,GAAG,EAAE,WAAW,EAAE,SAAS,EAAE,GAAG,GAAG,qBAAqB,CAS/F"}
@@ -0,0 +1,117 @@
1
+ /**
2
+ * EIP-712 spending cap — the off-chain authorization a requester signs once per session
3
+ * so the gateway can batch-settle many jobs against a pre-funded CreditAccount balance
4
+ * without a per-call wallet tx. The struct and domain MUST match CreditAccount.sol exactly
5
+ * (SPENDING_CAP_TYPEHASH + EIP712("QueraIS CreditAccount", "1")), so the digest the
6
+ * requester signs is the one the contract recovers.
7
+ */
8
+ import { hashTypedData, recoverTypedDataAddress, } from 'viem';
9
+ import { privateKeyToAccount } from 'viem/accounts';
10
+ import { z } from 'zod';
11
+ /** EIP-712 type definition — field order must match SPENDING_CAP_TYPEHASH. */
12
+ export const SPENDING_CAP_TYPES = {
13
+ SpendingCap: [
14
+ { name: 'requester', type: 'address' },
15
+ { name: 'settler', type: 'address' },
16
+ { name: 'maxSpendWei', type: 'uint256' },
17
+ { name: 'nonce', type: 'uint256' },
18
+ { name: 'deadline', type: 'uint256' },
19
+ ],
20
+ };
21
+ export const SPENDING_CAP_DOMAIN_NAME = 'QueraIS CreditAccount';
22
+ export const SPENDING_CAP_DOMAIN_VERSION = '1';
23
+ /** Build the EIP-712 domain for a CreditAccount deployment. */
24
+ export function spendingCapDomain(chainId, verifyingContract) {
25
+ return {
26
+ name: SPENDING_CAP_DOMAIN_NAME,
27
+ version: SPENDING_CAP_DOMAIN_VERSION,
28
+ chainId,
29
+ verifyingContract,
30
+ };
31
+ }
32
+ /** Sign a spending cap with a viem account/wallet client. Returns the 65-byte signature. */
33
+ export function signSpendingCap(signer, cap, domain) {
34
+ return signer.signTypedData({
35
+ domain,
36
+ types: SPENDING_CAP_TYPES,
37
+ primaryType: 'SpendingCap',
38
+ message: cap,
39
+ });
40
+ }
41
+ /** The EIP-712 digest for a cap — must equal CreditAccount.hashSpendingCap(cap) on-chain. */
42
+ export function hashSpendingCap(cap, domain) {
43
+ return hashTypedData({
44
+ domain,
45
+ types: SPENDING_CAP_TYPES,
46
+ primaryType: 'SpendingCap',
47
+ message: cap,
48
+ });
49
+ }
50
+ /** Recover the signer address from a cap + signature (mirrors ECDSA.recover on-chain). */
51
+ export function recoverSpendingCapSigner(cap, domain, signature) {
52
+ return recoverTypedDataAddress({
53
+ domain,
54
+ types: SPENDING_CAP_TYPES,
55
+ primaryType: 'SpendingCap',
56
+ message: cap,
57
+ signature,
58
+ });
59
+ }
60
+ /**
61
+ * Wire schema for a signed cap as sent to the gateway (`POST /v1/sessions`). bigints are
62
+ * carried as decimal strings; `toSpendingCap` parses them back. Addresses are lowercased
63
+ * 0x-hex; the signature is 0x-hex.
64
+ */
65
+ const hexAddress = z.string().regex(/^0x[0-9a-fA-F]{40}$/);
66
+ const decimalString = z.string().regex(/^[0-9]+$/);
67
+ export const signedSpendingCapSchema = z.object({
68
+ requester: hexAddress,
69
+ settler: hexAddress,
70
+ maxSpendWei: decimalString,
71
+ nonce: decimalString,
72
+ deadline: decimalString,
73
+ signature: z.string().regex(/^0x[0-9a-fA-F]+$/),
74
+ });
75
+ /** Parse the wire form into a typed cap + signature (bigints decoded). */
76
+ export function toSpendingCap(wire) {
77
+ return {
78
+ cap: {
79
+ requester: wire.requester,
80
+ settler: wire.settler,
81
+ maxSpendWei: BigInt(wire.maxSpendWei),
82
+ nonce: BigInt(wire.nonce),
83
+ deadline: BigInt(wire.deadline),
84
+ },
85
+ signature: wire.signature,
86
+ };
87
+ }
88
+ /**
89
+ * Build, sign, and serialize a spending cap from a private key — the one call the SDK makes
90
+ * to open a session. The requester is derived from the key; the result is POSTed to
91
+ * `/v1/sessions`. Keeps all signing in `shared` so the SDK needs no viem dependency.
92
+ */
93
+ export async function buildSignedSession(privateKey, p) {
94
+ const account = privateKeyToAccount(privateKey);
95
+ const cap = {
96
+ requester: account.address,
97
+ settler: p.settler,
98
+ maxSpendWei: p.maxSpendWei,
99
+ nonce: p.nonce,
100
+ deadline: p.deadline,
101
+ };
102
+ const domain = spendingCapDomain(p.chainId, p.verifyingContract);
103
+ const signature = await signSpendingCap(account, cap, domain);
104
+ return toSignedSpendingCapWire(cap, signature);
105
+ }
106
+ /** Serialize a typed cap + signature into the wire form (bigints → decimal strings). */
107
+ export function toSignedSpendingCapWire(cap, signature) {
108
+ return {
109
+ requester: cap.requester,
110
+ settler: cap.settler,
111
+ maxSpendWei: cap.maxSpendWei.toString(),
112
+ nonce: cap.nonce.toString(),
113
+ deadline: cap.deadline.toString(),
114
+ signature,
115
+ };
116
+ }
117
+ //# sourceMappingURL=spending-cap.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"spending-cap.js","sourceRoot":"","sources":["../src/spending-cap.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,38 @@
1
+ {
2
+ "name": "@querais/shared",
3
+ "version": "0.2.0",
4
+ "license": "MIT",
5
+ "description": "Shared types, schemas, wire protocol, and EIP-712 helpers for the QueraIS protocol. Published as a dependency of @querais/sdk.",
6
+ "repository": {
7
+ "type": "git",
8
+ "url": "git+https://github.com/ShavitR/querais.git",
9
+ "directory": "packages/shared"
10
+ },
11
+ "type": "module",
12
+ "main": "./dist/index.js",
13
+ "types": "./dist/index.d.ts",
14
+ "exports": {
15
+ ".": {
16
+ "types": "./dist/index.d.ts",
17
+ "default": "./dist/index.js"
18
+ }
19
+ },
20
+ "files": [
21
+ "dist",
22
+ "!dist/**/*.test.*",
23
+ "!dist/.tsbuildinfo"
24
+ ],
25
+ "publishConfig": {
26
+ "access": "public"
27
+ },
28
+ "dependencies": {
29
+ "viem": "^2.52.2",
30
+ "zod": "^3.24.1",
31
+ "@querais/contracts": "0.2.0"
32
+ },
33
+ "scripts": {
34
+ "build": "tsc -b",
35
+ "typecheck": "tsc --noEmit",
36
+ "test": "node --import tsx --test \"src/**/*.test.ts\""
37
+ }
38
+ }