Viewing is open to everyone. Downloading and starring need a GitHub sign-in. Sign in with GitHub

ckey.d.ts

v0.1.0-build.85 Latest Commit ede38f5

Size
9.5 KB
Lines
275
Language
typescript
SHA-256
991154d4ef63…
View on GitHub

Sign in with GitHub to download. Each download is recorded with your GitHub username.

1// Type declarations for the CKey Web SDK (npm package `openckey`).
2// Hand-written; copied to dist/ckey.d.ts by scripts/assemble.mjs.
3
4export type Level = 'L' | 'M' | 'Q' | 'H';
5export type Layout = 'standard' | 'print';
6export type RasterPolicy = 'coverage' | 'binary' | 'hybrid';
7export type Preset = 'plain' | 'concept';
8/** Optical-safety policy carried by a style: strict refuses, adaptive repairs, override draws as given. */
9export type StylePolicy = 'strict' | 'adaptive' | 'override';
10export type TelemetryMode = 0 | 1 | 2;
11export type Profile = '0' | '0.1' | '1' | '2' | '3';
12/** '#rgb', '#rrggbb', [r, g, b] or { r, g, b } with 0..255 channels. */
13export type Colour = string | readonly [number, number, number] | { r: number; g: number; b: number };
14
15export interface EncodeOptions {
16 /** 1..31, or 0 (default) for the smallest version that fits. */
17 version?: number;
18 /** Error correction level, default 'M'. */
19 level?: Level;
20 /** Default 'standard'; 'print' is Profile 0.1. */
21 layout?: Layout;
22}
23
24export interface CKeySymbol {
25 readonly version: number;
26 readonly level: Level;
27 readonly layout: Layout;
28 readonly payloadLength: number;
29 readonly capacity: number;
30 /** Modules across the field (29..232). */
31 readonly modules: number;
32 readonly freed: boolean;
33 /** Releases the symbol's WebAssembly memory. Safe to call twice. */
34 free(): void;
35}
36
37export interface Style {
38 background?: Colour;
39 /** Edge of a radial vignette; defaults to `background` (solid). */
40 backgroundEdge?: Colour;
41 ink?: Colour;
42 /** Sheen shade; defaults to `ink` (flat). */
43 inkShade?: Colour;
44 accents?: Colour[];
45 accentPercent?: number;
46 modules?: 'rounded' | 'square' | 'circle' | 'diamond';
47 rings?: 'joined' | 'dots';
48 rays?: 'round' | 'flat';
49 bevel?: number;
50 shadow?: number;
51 texture?: number;
52 /** Image URL or data: URI (SVG export). */
53 logoHref?: string | null;
54 logoRadius?: number;
55 logoPlate?: boolean;
56 /** Default 'strict'. */
57 policy?: StylePolicy;
58}
59
60export interface StyleOptions {
61 /** Start from a preset (default 'plain': black on white). */
62 preset?: Preset;
63 /** Overrides applied on top of the preset. */
64 style?: Style;
65}
66
67export interface ImageLike {
68 width: number;
69 height: number;
70 data: Uint8ClampedArray | Uint8Array;
71}
72
73export interface RasterOptions extends StyleOptions {
74 /** Pixels across the full 31-unit canvas (16..16384), default 512. */
75 size?: number;
76 /** Default 'coverage'. */
77 policy?: RasterPolicy;
78 /** Paint no background: unpainted pixels have alpha 0. Default false. */
79 transparent?: boolean;
80 /** Samples per pixel axis, 1..8, default 4. */
81 supersample?: number;
82 /** HYBRID only: minimum mark width in px, default 1. */
83 minFeaturePx?: number;
84 /** Sheen, depth and grain; default true. */
85 materials?: boolean;
86 /** Straight-alpha RGBA logo drawn into the style's logo circle. */
87 logo?: ImageLike | null;
88}
89
90export interface PNGOptions extends RasterOptions {
91 /** Records the physical resolution (pHYs) when > 0. */
92 dpi?: number;
93}
94
95export interface SVGOptions extends StyleOptions {
96 /** Pixels per canonical unit (width = 31 * scale), 1..256, default 16. */
97 scale?: number;
98 /** Alternative to scale: approximate width in px. */
99 size?: number;
100}
101
102export interface PDFOptions extends StyleOptions {
103 /** Page width in points (72 per inch), default 144. */
104 widthPt?: number;
105 transparent?: boolean;
106}
107
108export interface Pixels {
109 width: number;
110 height: number;
111 data: Uint8ClampedArray;
112}
113
114export interface DecodeResult {
115 bytes: Uint8Array;
116 /** The payload as text when it is valid UTF-8 without control characters (tab, LF, CR allowed). */
117 text: string | null;
118 profile: Profile;
119 /** Profile 0 version (1..31); null for Profiles 1-3. */
120 version: number | null;
121 /** Profile 0 layout; null for Profiles 1-3. */
122 layout: Layout | null;
123}
124
125export type PayloadKind = 'https' | 'http' | 'mailto' | 'tel' | 'sms' | 'geo' | 'address' | 'vcard' | 'text';
126
127export interface PayloadAction {
128 kind: PayloadKind;
129 /** What the host hands to the platform if the user accepts; null for text. */
130 target: string | null;
131 /** The proposed action, stating its target, e.g. "Open openckey.org". */
132 label: string;
133}
134
135export interface StyleCheck {
136 ok: boolean;
137 message: string;
138}
139
140export interface CertifyOptions extends StyleOptions {
141 transparent?: boolean;
142 backdrop?: { colours?: Colour[]; pixels?: ImageLike | null };
143 model?: { pxPerModule?: number; blurPx?: number; noise?: number; glare?: number; trials?: number };
144}
145
146export interface Certification {
147 ok: boolean;
148 certified: boolean;
149 policy: StylePolicy;
150 adjustments: Array<'ink' | 'accents' | 'effects' | 'logo' | 'background' | 'materials'>;
151 trials: number;
152 trialsPassed: number;
153 minContrast: number;
154 featureSeparation: number;
155 logoLoad: number;
156 message: string;
157}
158
159export interface Histogram {
160 count: number;
161 sum: number;
162 buckets: number[];
163}
164
165export interface TelemetryCounters {
166 sessions: { started: number; succeeded: number; failed: number };
167 frames: number;
168 decoded: { p0: number; p0_1: number; p1: number; p2: number; p3: number };
169 time_to_decode_ms: Histogram;
170 frame_ms: Histogram;
171}
172
173export interface Scanner {
174 /** Decodes one RGBA frame; returns the result once per session, else null. */
175 processFrame(frame: ImageLike | ImageData): DecodeResult | null;
176 /** Scan again after a decode. */
177 reset(): void;
178 /** The host stopped scanning; ends the telemetry session. */
179 stop(): void;
180 readonly decoded: DecodeResult | null;
181 readonly scanning: boolean;
182}
183
184export interface CKey {
185 readonly version: string;
186 readonly abiVersion: number;
187 encode(payload: string | ArrayBuffer | ArrayBufferView, options?: EncodeOptions): CKeySymbol;
188 capacity(version: number, level?: Level, layout?: Layout): number;
189 renderToCanvas<C extends HTMLCanvasElement | OffscreenCanvas>(symbol: CKeySymbol, canvas: C, options?: RasterOptions): C;
190 renderPixels(symbol: CKeySymbol, options?: RasterOptions): Pixels;
191 renderPNG(symbol: CKeySymbol, options?: PNGOptions): Uint8Array;
192 renderSVG(symbol: CKeySymbol, options?: SVGOptions): string;
193 renderPDF(symbol: CKeySymbol, options?: PDFOptions): Uint8Array;
194 checkStyle(symbol: CKeySymbol, options?: StyleOptions): StyleCheck;
195 certify(symbol: CKeySymbol, options?: CertifyOptions): Certification;
196 decodeImageData(image: ImageLike | ImageData): DecodeResult | null;
197 decodeGray(image: ImageLike): DecodeResult | null;
198 classifyPayload(text: string | Uint8Array): PayloadAction;
199 /** Safe Actions for this app (spec/CKey-Safe-Actions.md). */
200 safeActions(appId: string, options?: SafeActionsOptions): SafeActions;
201 createScanner(options?: { onResult?: (result: DecodeResult) => void; onError?: (error: unknown) => void }): Scanner;
202 /** 0 off, 1 on (default), 2 local only. Any other value throws RangeError. */
203 telemetry: TelemetryMode;
204 telemetryCounters(): TelemetryCounters | null;
205 flushTelemetry(): Promise<number | null>;
206}
207
208export interface LoadOptions {
209 wasmUrl?: string | URL;
210 wasmBinary?: ArrayBuffer | Uint8Array;
211 telemetry?: TelemetryMode;
212 fetch?: typeof fetch | null;
213 telemetryEndpoint?: string;
214 moduleFactory?: (args: object) => Promise<unknown>;
215}
216
217export function loadCKey(options?: LoadOptions): Promise<CKey>;
218export function classifyPayload(text: string | Uint8Array): PayloadAction;
219
220export type SafeActionScope = 'same-device' | 'cross-device';
221export const SAME_DEVICE: 'same-device';
222export const CROSS_DEVICE: 'cross-device';
223export function isSafeAction(text: string): boolean;
224
225export interface SafeActionsOptions {
226 /** Longest lifetime this app accepts, 1..3600 seconds (default 600). */
227 maxLifetime?: number;
228 /** Also look up keys at https://<issuer>/.well-known/ckey-safe-actions.json (default false: pinned keys only). */
229 keyFiles?: boolean;
230 fetch?: typeof fetch;
231 now?: () => number;
232}
233
234export interface VerifiedSafeAction {
235 readonly issuer: string;
236 readonly app: string;
237 readonly action: string;
238 readonly keyId: string;
239 readonly requestId: string;
240 readonly scope: SafeActionScope;
241 readonly issuedAt: number;
242 readonly expiresAt: number;
243 readonly params: Uint8Array;
244 readonly paramsText: string | null;
245 readonly paramsJSON: unknown;
246}
247
248export class SafeActionRequest {
249 readonly issuer: string;
250 readonly action: string;
251 readonly title: string;
252 readonly requestInfo: { device: string | null; location: string | null; requestedAt: string | null };
253 readonly details: VerifiedSafeAction;
254 /** Shows the SDK's confirmation; the handler runs only if the person approves. */
255 present(options?: { document?: Document }): Promise<{ approved: boolean; result?: unknown; error?: unknown; reason?: string }>;
256}
257
258export type SafeActionOutcome =
259 | { kind: 'not-safe-action' }
260 | { kind: 'rejected'; reason: string; action?: { issuer: string; app: string; action: string } }
261 | { kind: 'ran'; action: VerifiedSafeAction; result: unknown }
262 | { kind: 'confirm'; request: SafeActionRequest };
263
264export class SafeActions {
265 trust(issuer: string, keyId: string, publicKey: string | Uint8Array, options?: { requestInfo?: string }): this;
266 register(action: string, options: { issuer?: string; issuers?: string[]; scope?: SafeActionScope; title?: string },
267 handler: (action: VerifiedSafeAction) => unknown): this;
268 handle(text: string): Promise<SafeActionOutcome>;
269}
270export function readableText(bytes: Uint8Array): string | null;
271export function toHex(bytes: Uint8Array): string;
272export const CKEY_TELEMETRY_ENDPOINT: string;
273export const TELEMETRY_OFF: 0;
274export const TELEMETRY_ON: 1;
275export const TELEMETRY_LOCAL: 2;