@verimago/sdk 1.0.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,70 @@
1
+ import { Certificate, Manifest, ManifestMetadata, VerifyResult, UGCAnalysis, UGCPlatform, Environment, PaginatedResponse } from '@verimago/shared';
2
+ export * from '@verimago/shared';
3
+ export interface VerimagoOptions {
4
+ apiKey: string;
5
+ env?: Environment;
6
+ baseUrl?: string;
7
+ timeout?: number;
8
+ }
9
+ export interface SignOptions {
10
+ certId: string;
11
+ privateKey: string;
12
+ metadata: ManifestMetadata;
13
+ }
14
+ export interface PublishResult {
15
+ id: string;
16
+ registryUrl: string;
17
+ certId: string;
18
+ videoHash: string;
19
+ }
20
+ export interface UGCSubmitOptions {
21
+ platform?: UGCPlatform;
22
+ claimedAt?: string;
23
+ claimedLocation?: string;
24
+ }
25
+ export declare class Verimago {
26
+ private readonly baseUrl;
27
+ private readonly apiKey;
28
+ private readonly timeout;
29
+ constructor(opts: VerimagoOptions);
30
+ private request;
31
+ /** Compute SHA-256 hash of a video file buffer */
32
+ hashFile(file: Buffer | Uint8Array): Promise<string>;
33
+ /**
34
+ * Verify a video file or hash against the Verimago registry.
35
+ * Accepts a Buffer, Uint8Array, or a pre-computed 'sha256:hex' string.
36
+ * Results are cached at the CDN layer for 4 hours.
37
+ */
38
+ verify(fileOrHash: Buffer | Uint8Array | string): Promise<VerifyResult>;
39
+ /**
40
+ * Sign a video locally and return a manifest object.
41
+ * Does NOT publish — call publish() separately.
42
+ * The private key never leaves your environment.
43
+ */
44
+ sign(file: Buffer | Uint8Array, opts: SignOptions): Promise<Manifest>;
45
+ /** Publish a signed manifest to the Verimago registry */
46
+ publish(manifest: Manifest): Promise<PublishResult>;
47
+ /**
48
+ * Submit a social media URL for UGC corroboration analysis.
49
+ * Returns immediately with an analysis ID; poll /v1/ugc/:id for results.
50
+ */
51
+ analyzeUGC(url: string, opts?: UGCSubmitOptions): Promise<{
52
+ id: string;
53
+ status: 'QUEUED';
54
+ }>;
55
+ /** Poll for UGC analysis results */
56
+ getUGCAnalysis(id: string): Promise<UGCAnalysis>;
57
+ /** List all verified publisher certificates */
58
+ listCertificates(page?: number, pageSize?: number): Promise<PaginatedResponse<Certificate>>;
59
+ /** Get a single certificate by ID */
60
+ getCertificate(certId: string): Promise<Certificate>;
61
+ /** Check API health — useful in health-check scripts */
62
+ health(): Promise<{
63
+ status: 'ok';
64
+ version: string;
65
+ db: string;
66
+ redis: string;
67
+ }>;
68
+ }
69
+ export default Verimago;
70
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAKA,OAAO,EACL,WAAW,EAAE,QAAQ,EAAE,gBAAgB,EAAE,YAAY,EACrD,WAAW,EAAE,WAAW,EAAE,WAAW,EAAW,iBAAiB,EAClE,MAAM,kBAAkB,CAAC;AAE1B,cAAc,kBAAkB,CAAC;AAIjC,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,GAAG,CAAC,EAAE,WAAW,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,gBAAgB,CAAC;CAC5B;AAED,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,EAAE,WAAW,CAAC;IACvB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAID,qBAAa,QAAQ;IACnB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAChC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;gBAErB,IAAI,EAAE,eAAe;YASnB,OAAO;IA6BrB,kDAAkD;IAC5C,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,UAAU,GAAG,OAAO,CAAC,MAAM,CAAC;IAM1D;;;;OAIG;IACG,MAAM,CAAC,UAAU,EAAE,MAAM,GAAG,UAAU,GAAG,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC;IAS7E;;;;OAIG;IACG,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,UAAU,EAAE,IAAI,EAAE,WAAW,GAAG,OAAO,CAAC,QAAQ,CAAC;IA8B3E,yDAAyD;IACnD,OAAO,CAAC,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAAC,aAAa,CAAC;IASzD;;;OAGG;IACG,UAAU,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,GAAE,gBAAqB,GAAG,OAAO,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,QAAQ,CAAA;KAAE,CAAC;IAOrG,oCAAoC;IAC9B,cAAc,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC;IAMtD,+CAA+C;IACzC,gBAAgB,CAAC,IAAI,SAAI,EAAE,QAAQ,SAAK,GAAG,OAAO,CAAC,iBAAiB,CAAC,WAAW,CAAC,CAAC;IAMxF,qCAAqC;IAC/B,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC;IAM1D,wDAAwD;IAClD,MAAM,IAAI,OAAO,CAAC;QAAE,MAAM,EAAE,IAAI,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC;CAGtF;AAGD,eAAe,QAAQ,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,167 @@
1
+ "use strict";
2
+ // packages/sdk/src/index.ts
3
+ // @verimago/sdk — official Verimago Node.js + Browser SDK
4
+ // Usage: const vi = new Verimago({ apiKey: process.env.VERIMAGO_KEY })
5
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
6
+ if (k2 === undefined) k2 = k;
7
+ var desc = Object.getOwnPropertyDescriptor(m, k);
8
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
9
+ desc = { enumerable: true, get: function() { return m[k]; } };
10
+ }
11
+ Object.defineProperty(o, k2, desc);
12
+ }) : (function(o, m, k, k2) {
13
+ if (k2 === undefined) k2 = k;
14
+ o[k2] = m[k];
15
+ }));
16
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
17
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
18
+ }) : function(o, v) {
19
+ o["default"] = v;
20
+ });
21
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
22
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
23
+ };
24
+ var __importStar = (this && this.__importStar) || (function () {
25
+ var ownKeys = function(o) {
26
+ ownKeys = Object.getOwnPropertyNames || function (o) {
27
+ var ar = [];
28
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
29
+ return ar;
30
+ };
31
+ return ownKeys(o);
32
+ };
33
+ return function (mod) {
34
+ if (mod && mod.__esModule) return mod;
35
+ var result = {};
36
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
37
+ __setModuleDefault(result, mod);
38
+ return result;
39
+ };
40
+ })();
41
+ Object.defineProperty(exports, "__esModule", { value: true });
42
+ exports.Verimago = void 0;
43
+ const crypto_1 = require("crypto");
44
+ const shared_1 = require("@verimago/shared");
45
+ __exportStar(require("@verimago/shared"), exports);
46
+ // ── CLIENT ─────────────────────────────────────────────────────────────────
47
+ class Verimago {
48
+ constructor(opts) {
49
+ const urls = (0, shared_1.getUrls)(opts.env ?? 'production');
50
+ this.baseUrl = opts.baseUrl ?? urls.api;
51
+ this.apiKey = opts.apiKey;
52
+ this.timeout = opts.timeout ?? 10000;
53
+ }
54
+ // ── PRIVATE ────────────────────────────────────────────────────────────
55
+ async request(path, init = {}) {
56
+ const controller = new AbortController();
57
+ const timer = setTimeout(() => controller.abort(), this.timeout);
58
+ try {
59
+ const res = await fetch(`${this.baseUrl}${path}`, {
60
+ ...init,
61
+ signal: controller.signal,
62
+ headers: {
63
+ 'Authorization': `Bearer ${this.apiKey}`,
64
+ 'Content-Type': 'application/json',
65
+ 'User-Agent': 'verimago-sdk/1.0.0',
66
+ ...init.headers,
67
+ },
68
+ });
69
+ if (!res.ok) {
70
+ const body = await res.text().catch(() => '');
71
+ throw new Error(`Verimago API ${res.status}: ${body || res.statusText}`);
72
+ }
73
+ return res.json();
74
+ }
75
+ finally {
76
+ clearTimeout(timer);
77
+ }
78
+ }
79
+ // ── HASHING ────────────────────────────────────────────────────────────
80
+ /** Compute SHA-256 hash of a video file buffer */
81
+ async hashFile(file) {
82
+ return 'sha256:' + (0, crypto_1.createHash)('sha256').update(file).digest('hex');
83
+ }
84
+ // ── VERIFY ─────────────────────────────────────────────────────────────
85
+ /**
86
+ * Verify a video file or hash against the Verimago registry.
87
+ * Accepts a Buffer, Uint8Array, or a pre-computed 'sha256:hex' string.
88
+ * Results are cached at the CDN layer for 4 hours.
89
+ */
90
+ async verify(fileOrHash) {
91
+ const hash = typeof fileOrHash === 'string'
92
+ ? fileOrHash
93
+ : await this.hashFile(fileOrHash);
94
+ return this.request(`/v1/verify/${encodeURIComponent(hash)}`);
95
+ }
96
+ // ── SIGN ───────────────────────────────────────────────────────────────
97
+ /**
98
+ * Sign a video locally and return a manifest object.
99
+ * Does NOT publish — call publish() separately.
100
+ * The private key never leaves your environment.
101
+ */
102
+ async sign(file, opts) {
103
+ const videoHash = await this.hashFile(file);
104
+ const signedAt = new Date().toISOString();
105
+ // Assemble the canonical payload — order matters for deterministic signing
106
+ const payload = JSON.stringify({
107
+ videoHash,
108
+ certId: opts.certId,
109
+ metadata: opts.metadata,
110
+ signedAt,
111
+ });
112
+ // Dynamic import of @noble/ed25519 to support both Node and browser
113
+ const ed = await Promise.resolve().then(() => __importStar(require('@noble/ed25519')));
114
+ const privBytes = Buffer.from(opts.privateKey, 'base64');
115
+ const sigBytes = await ed.signAsync(new TextEncoder().encode(payload), privBytes);
116
+ const signature = Buffer.from(sigBytes).toString('base64');
117
+ return {
118
+ id: '', // assigned by registry on publish
119
+ videoHash,
120
+ certId: opts.certId,
121
+ signature,
122
+ metadata: opts.metadata,
123
+ signedAt,
124
+ };
125
+ }
126
+ // ── PUBLISH ────────────────────────────────────────────────────────────
127
+ /** Publish a signed manifest to the Verimago registry */
128
+ async publish(manifest) {
129
+ return this.request('/v1/manifests', {
130
+ method: 'POST',
131
+ body: JSON.stringify(manifest),
132
+ });
133
+ }
134
+ // ── UGC ────────────────────────────────────────────────────────────────
135
+ /**
136
+ * Submit a social media URL for UGC corroboration analysis.
137
+ * Returns immediately with an analysis ID; poll /v1/ugc/:id for results.
138
+ */
139
+ async analyzeUGC(url, opts = {}) {
140
+ return this.request('/v1/ugc/analyze', {
141
+ method: 'POST',
142
+ body: JSON.stringify({ url, ...opts }),
143
+ });
144
+ }
145
+ /** Poll for UGC analysis results */
146
+ async getUGCAnalysis(id) {
147
+ return this.request(`/v1/ugc/${id}`);
148
+ }
149
+ // ── CERTIFICATES ───────────────────────────────────────────────────────
150
+ /** List all verified publisher certificates */
151
+ async listCertificates(page = 1, pageSize = 50) {
152
+ return this.request(`/v1/certs?page=${page}&pageSize=${pageSize}`);
153
+ }
154
+ /** Get a single certificate by ID */
155
+ async getCertificate(certId) {
156
+ return this.request(`/v1/certs/${certId}`);
157
+ }
158
+ // ── HEALTH ─────────────────────────────────────────────────────────────
159
+ /** Check API health — useful in health-check scripts */
160
+ async health() {
161
+ return this.request('/v1/health');
162
+ }
163
+ }
164
+ exports.Verimago = Verimago;
165
+ // ── DEFAULT EXPORT ─────────────────────────────────────────────────────────
166
+ exports.default = Verimago;
167
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/index.mjs ADDED
@@ -0,0 +1,739 @@
1
+ var __create = Object.create;
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __getProtoOf = Object.getPrototypeOf;
6
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
7
+ var __esm = (fn, res) => function __init() {
8
+ return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
9
+ };
10
+ var __commonJS = (cb, mod) => function __require() {
11
+ return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
12
+ };
13
+ var __export = (target, all) => {
14
+ for (var name in all)
15
+ __defProp(target, name, { get: all[name], enumerable: true });
16
+ };
17
+ var __copyProps = (to, from, except, desc) => {
18
+ if (from && typeof from === "object" || typeof from === "function") {
19
+ for (let key of __getOwnPropNames(from))
20
+ if (!__hasOwnProp.call(to, key) && key !== except)
21
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
22
+ }
23
+ return to;
24
+ };
25
+ var __reExport = (target, mod, secondTarget) => (__copyProps(target, mod, "default"), secondTarget && __copyProps(secondTarget, mod, "default"));
26
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
27
+ // If the importer is in node compatibility mode or this is not an ESM
28
+ // file that has been converted to a CommonJS file using a Babel-
29
+ // compatible transform (i.e. "__esModule" has not been set), then set
30
+ // "default" to the CommonJS "module.exports" for node compatibility.
31
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
32
+ mod
33
+ ));
34
+
35
+ // ../shared/dist/index.js
36
+ var require_dist = __commonJS({
37
+ "../shared/dist/index.js"(exports) {
38
+ "use strict";
39
+ Object.defineProperty(exports, "__esModule", { value: true });
40
+ exports.LOCAL_URLS = exports.STAGING_URLS = exports.VERIMAGO_URLS = exports.CONTENT_TYPE_DESCRIPTIONS = exports.CONTENT_TYPE_COLORS = exports.CONTENT_TYPE_LABELS = void 0;
41
+ exports.getUrls = getUrls2;
42
+ exports.formatCertId = formatCertId;
43
+ exports.truncateHash = truncateHash;
44
+ exports.CONTENT_TYPE_LABELS = {
45
+ AUTHENTIC: "Authentic",
46
+ AI_ENHANCED: "AI Enhanced",
47
+ AI_CREATED: "AI Created"
48
+ };
49
+ exports.CONTENT_TYPE_COLORS = {
50
+ AUTHENTIC: "#00b894",
51
+ // green
52
+ AI_ENHANCED: "#f39c12",
53
+ // amber
54
+ AI_CREATED: "#8b5cf6"
55
+ // purple
56
+ };
57
+ exports.CONTENT_TYPE_DESCRIPTIONS = {
58
+ AUTHENTIC: "Original, unaltered content. No AI modifications applied.",
59
+ AI_ENHANCED: "Real content enhanced with AI tools (e.g. noise reduction, upscaling, color grading).",
60
+ AI_CREATED: "Fully or substantially generated by AI. Not a recording of real events."
61
+ };
62
+ exports.VERIMAGO_URLS = {
63
+ api: "https://api.verimago.io",
64
+ registry: "https://registry.verimago.io",
65
+ publisher: "https://publisher.verimago.io",
66
+ cdn: "https://cdn.verimago.io",
67
+ ocsp: "https://ocsp.verimago.io",
68
+ status: "https://status.verimago.io",
69
+ corporate: "https://verimago.com"
70
+ };
71
+ exports.STAGING_URLS = {
72
+ ...exports.VERIMAGO_URLS,
73
+ api: "https://staging-api.verimago.io",
74
+ registry: "https://staging-registry.verimago.io",
75
+ publisher: "https://staging-publisher.verimago.io"
76
+ };
77
+ exports.LOCAL_URLS = {
78
+ ...exports.VERIMAGO_URLS,
79
+ api: "http://localhost:3000",
80
+ registry: "http://localhost:3001",
81
+ publisher: "http://localhost:3002"
82
+ };
83
+ function getUrls2(env = "production") {
84
+ if (env === "staging")
85
+ return exports.STAGING_URLS;
86
+ if (env === "local")
87
+ return exports.LOCAL_URLS;
88
+ return exports.VERIMAGO_URLS;
89
+ }
90
+ function formatCertId(id) {
91
+ return `VMGO-${id.slice(0, 8).toUpperCase()}`;
92
+ }
93
+ function truncateHash(hash, len = 12) {
94
+ const hex = hash.replace("sha256:", "");
95
+ return `${hex.slice(0, len)}\u2026`;
96
+ }
97
+ }
98
+ });
99
+
100
+ // ../../node_modules/@noble/ed25519/index.js
101
+ var ed25519_exports = {};
102
+ __export(ed25519_exports, {
103
+ CURVE: () => ed25519_CURVE,
104
+ ExtendedPoint: () => Point,
105
+ Point: () => Point,
106
+ etc: () => etc,
107
+ getPublicKey: () => getPublicKey,
108
+ getPublicKeyAsync: () => getPublicKeyAsync,
109
+ sign: () => sign,
110
+ signAsync: () => signAsync,
111
+ utils: () => utils,
112
+ verify: () => verify,
113
+ verifyAsync: () => verifyAsync
114
+ });
115
+ var ed25519_CURVE, P, N, Gx, Gy, _a, _d, h, L, L2, err, isBig, isStr, isBytes, abytes, u8n, u8fr, padh, bytesToHex, C, _ch, hexToBytes, toU8, cr, subtle, concatBytes, randomBytes, big, arange, M, modN, invert, callHash, apoint, B256, Point, G, I, numTo32bLE, bytesToNumLE, pow2, pow_2_252_3, RM1, uvRatio, modL_LE, sha512a, sha512s, hash2extK, getExtendedPublicKeyAsync, getExtendedPublicKey, getPublicKeyAsync, getPublicKey, hashFinishA, hashFinishS, _sign, signAsync, sign, veriOpts, _verify, verifyAsync, verify, etc, utils, W, scalarBits, pwindows, pwindowSize, precompute, Gpows, ctneg, wNAF;
116
+ var init_ed25519 = __esm({
117
+ "../../node_modules/@noble/ed25519/index.js"() {
118
+ ed25519_CURVE = {
119
+ p: 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffedn,
120
+ n: 0x1000000000000000000000000000000014def9dea2f79cd65812631a5cf5d3edn,
121
+ h: 8n,
122
+ a: 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffecn,
123
+ d: 0x52036cee2b6ffe738cc740797779e89800700a4d4141d8ab75eb4dca135978a3n,
124
+ Gx: 0x216936d3cd6e53fec0a4e231fdd6dc5c692cc7609525a7b2c9562d608f25d51an,
125
+ Gy: 0x6666666666666666666666666666666666666666666666666666666666666658n
126
+ };
127
+ ({ p: P, n: N, Gx, Gy, a: _a, d: _d } = ed25519_CURVE);
128
+ h = 8n;
129
+ L = 32;
130
+ L2 = 64;
131
+ err = (m = "") => {
132
+ throw new Error(m);
133
+ };
134
+ isBig = (n) => typeof n === "bigint";
135
+ isStr = (s) => typeof s === "string";
136
+ isBytes = (a) => a instanceof Uint8Array || ArrayBuffer.isView(a) && a.constructor.name === "Uint8Array";
137
+ abytes = (a, l) => !isBytes(a) || typeof l === "number" && l > 0 && a.length !== l ? err("Uint8Array expected") : a;
138
+ u8n = (len) => new Uint8Array(len);
139
+ u8fr = (buf) => Uint8Array.from(buf);
140
+ padh = (n, pad) => n.toString(16).padStart(pad, "0");
141
+ bytesToHex = (b) => Array.from(abytes(b)).map((e) => padh(e, 2)).join("");
142
+ C = { _0: 48, _9: 57, A: 65, F: 70, a: 97, f: 102 };
143
+ _ch = (ch) => {
144
+ if (ch >= C._0 && ch <= C._9)
145
+ return ch - C._0;
146
+ if (ch >= C.A && ch <= C.F)
147
+ return ch - (C.A - 10);
148
+ if (ch >= C.a && ch <= C.f)
149
+ return ch - (C.a - 10);
150
+ return;
151
+ };
152
+ hexToBytes = (hex) => {
153
+ const e = "hex invalid";
154
+ if (!isStr(hex))
155
+ return err(e);
156
+ const hl = hex.length;
157
+ const al = hl / 2;
158
+ if (hl % 2)
159
+ return err(e);
160
+ const array = u8n(al);
161
+ for (let ai = 0, hi = 0; ai < al; ai++, hi += 2) {
162
+ const n1 = _ch(hex.charCodeAt(hi));
163
+ const n2 = _ch(hex.charCodeAt(hi + 1));
164
+ if (n1 === void 0 || n2 === void 0)
165
+ return err(e);
166
+ array[ai] = n1 * 16 + n2;
167
+ }
168
+ return array;
169
+ };
170
+ toU8 = (a, len) => abytes(isStr(a) ? hexToBytes(a) : u8fr(abytes(a)), len);
171
+ cr = () => globalThis?.crypto;
172
+ subtle = () => cr()?.subtle ?? err("crypto.subtle must be defined");
173
+ concatBytes = (...arrs) => {
174
+ const r = u8n(arrs.reduce((sum, a) => sum + abytes(a).length, 0));
175
+ let pad = 0;
176
+ arrs.forEach((a) => {
177
+ r.set(a, pad);
178
+ pad += a.length;
179
+ });
180
+ return r;
181
+ };
182
+ randomBytes = (len = L) => {
183
+ const c = cr();
184
+ return c.getRandomValues(u8n(len));
185
+ };
186
+ big = BigInt;
187
+ arange = (n, min, max, msg = "bad number: out of range") => isBig(n) && min <= n && n < max ? n : err(msg);
188
+ M = (a, b = P) => {
189
+ const r = a % b;
190
+ return r >= 0n ? r : b + r;
191
+ };
192
+ modN = (a) => M(a, N);
193
+ invert = (num, md) => {
194
+ if (num === 0n || md <= 0n)
195
+ err("no inverse n=" + num + " mod=" + md);
196
+ let a = M(num, md), b = md, x = 0n, y = 1n, u = 1n, v = 0n;
197
+ while (a !== 0n) {
198
+ const q = b / a, r = b % a;
199
+ const m = x - u * q, n = y - v * q;
200
+ b = a, a = r, x = u, y = v, u = m, v = n;
201
+ }
202
+ return b === 1n ? M(x, md) : err("no inverse");
203
+ };
204
+ callHash = (name) => {
205
+ const fn = etc[name];
206
+ if (typeof fn !== "function")
207
+ err("hashes." + name + " not set");
208
+ return fn;
209
+ };
210
+ apoint = (p) => p instanceof Point ? p : err("Point expected");
211
+ B256 = 2n ** 256n;
212
+ Point = class _Point {
213
+ static BASE;
214
+ static ZERO;
215
+ ex;
216
+ ey;
217
+ ez;
218
+ et;
219
+ constructor(ex, ey, ez, et) {
220
+ const max = B256;
221
+ this.ex = arange(ex, 0n, max);
222
+ this.ey = arange(ey, 0n, max);
223
+ this.ez = arange(ez, 1n, max);
224
+ this.et = arange(et, 0n, max);
225
+ Object.freeze(this);
226
+ }
227
+ static fromAffine(p) {
228
+ return new _Point(p.x, p.y, 1n, M(p.x * p.y));
229
+ }
230
+ /** RFC8032 5.1.3: Uint8Array to Point. */
231
+ static fromBytes(hex, zip215 = false) {
232
+ const d = _d;
233
+ const normed = u8fr(abytes(hex, L));
234
+ const lastByte = hex[31];
235
+ normed[31] = lastByte & ~128;
236
+ const y = bytesToNumLE(normed);
237
+ const max = zip215 ? B256 : P;
238
+ arange(y, 0n, max);
239
+ const y2 = M(y * y);
240
+ const u = M(y2 - 1n);
241
+ const v = M(d * y2 + 1n);
242
+ let { isValid, value: x } = uvRatio(u, v);
243
+ if (!isValid)
244
+ err("bad point: y not sqrt");
245
+ const isXOdd = (x & 1n) === 1n;
246
+ const isLastByteOdd = (lastByte & 128) !== 0;
247
+ if (!zip215 && x === 0n && isLastByteOdd)
248
+ err("bad point: x==0, isLastByteOdd");
249
+ if (isLastByteOdd !== isXOdd)
250
+ x = M(-x);
251
+ return new _Point(x, y, 1n, M(x * y));
252
+ }
253
+ /** Checks if the point is valid and on-curve. */
254
+ assertValidity() {
255
+ const a = _a;
256
+ const d = _d;
257
+ const p = this;
258
+ if (p.is0())
259
+ throw new Error("bad point: ZERO");
260
+ const { ex: X, ey: Y, ez: Z, et: T } = p;
261
+ const X2 = M(X * X);
262
+ const Y2 = M(Y * Y);
263
+ const Z2 = M(Z * Z);
264
+ const Z4 = M(Z2 * Z2);
265
+ const aX2 = M(X2 * a);
266
+ const left = M(Z2 * M(aX2 + Y2));
267
+ const right = M(Z4 + M(d * M(X2 * Y2)));
268
+ if (left !== right)
269
+ throw new Error("bad point: equation left != right (1)");
270
+ const XY = M(X * Y);
271
+ const ZT = M(Z * T);
272
+ if (XY !== ZT)
273
+ throw new Error("bad point: equation left != right (2)");
274
+ return this;
275
+ }
276
+ /** Equality check: compare points P&Q. */
277
+ equals(other) {
278
+ const { ex: X1, ey: Y1, ez: Z1 } = this;
279
+ const { ex: X2, ey: Y2, ez: Z2 } = apoint(other);
280
+ const X1Z2 = M(X1 * Z2);
281
+ const X2Z1 = M(X2 * Z1);
282
+ const Y1Z2 = M(Y1 * Z2);
283
+ const Y2Z1 = M(Y2 * Z1);
284
+ return X1Z2 === X2Z1 && Y1Z2 === Y2Z1;
285
+ }
286
+ is0() {
287
+ return this.equals(I);
288
+ }
289
+ /** Flip point over y coordinate. */
290
+ negate() {
291
+ return new _Point(M(-this.ex), this.ey, this.ez, M(-this.et));
292
+ }
293
+ /** Point doubling. Complete formula. Cost: `4M + 4S + 1*a + 6add + 1*2`. */
294
+ double() {
295
+ const { ex: X1, ey: Y1, ez: Z1 } = this;
296
+ const a = _a;
297
+ const A = M(X1 * X1);
298
+ const B = M(Y1 * Y1);
299
+ const C2 = M(2n * M(Z1 * Z1));
300
+ const D = M(a * A);
301
+ const x1y1 = X1 + Y1;
302
+ const E = M(M(x1y1 * x1y1) - A - B);
303
+ const G2 = D + B;
304
+ const F = G2 - C2;
305
+ const H = D - B;
306
+ const X3 = M(E * F);
307
+ const Y3 = M(G2 * H);
308
+ const T3 = M(E * H);
309
+ const Z3 = M(F * G2);
310
+ return new _Point(X3, Y3, Z3, T3);
311
+ }
312
+ /** Point addition. Complete formula. Cost: `8M + 1*k + 8add + 1*2`. */
313
+ add(other) {
314
+ const { ex: X1, ey: Y1, ez: Z1, et: T1 } = this;
315
+ const { ex: X2, ey: Y2, ez: Z2, et: T2 } = apoint(other);
316
+ const a = _a;
317
+ const d = _d;
318
+ const A = M(X1 * X2);
319
+ const B = M(Y1 * Y2);
320
+ const C2 = M(T1 * d * T2);
321
+ const D = M(Z1 * Z2);
322
+ const E = M((X1 + Y1) * (X2 + Y2) - A - B);
323
+ const F = M(D - C2);
324
+ const G2 = M(D + C2);
325
+ const H = M(B - a * A);
326
+ const X3 = M(E * F);
327
+ const Y3 = M(G2 * H);
328
+ const T3 = M(E * H);
329
+ const Z3 = M(F * G2);
330
+ return new _Point(X3, Y3, Z3, T3);
331
+ }
332
+ /**
333
+ * Point-by-scalar multiplication. Scalar must be in range 1 <= n < CURVE.n.
334
+ * Uses {@link wNAF} for base point.
335
+ * Uses fake point to mitigate side-channel leakage.
336
+ * @param n scalar by which point is multiplied
337
+ * @param safe safe mode guards against timing attacks; unsafe mode is faster
338
+ */
339
+ multiply(n, safe = true) {
340
+ if (!safe && (n === 0n || this.is0()))
341
+ return I;
342
+ arange(n, 1n, N);
343
+ if (n === 1n)
344
+ return this;
345
+ if (this.equals(G))
346
+ return wNAF(n).p;
347
+ let p = I;
348
+ let f = G;
349
+ for (let d = this; n > 0n; d = d.double(), n >>= 1n) {
350
+ if (n & 1n)
351
+ p = p.add(d);
352
+ else if (safe)
353
+ f = f.add(d);
354
+ }
355
+ return p;
356
+ }
357
+ /** Convert point to 2d xy affine point. (X, Y, Z) ∋ (x=X/Z, y=Y/Z) */
358
+ toAffine() {
359
+ const { ex: x, ey: y, ez: z } = this;
360
+ if (this.equals(I))
361
+ return { x: 0n, y: 1n };
362
+ const iz = invert(z, P);
363
+ if (M(z * iz) !== 1n)
364
+ err("invalid inverse");
365
+ return { x: M(x * iz), y: M(y * iz) };
366
+ }
367
+ toBytes() {
368
+ const { x, y } = this.assertValidity().toAffine();
369
+ const b = numTo32bLE(y);
370
+ b[31] |= x & 1n ? 128 : 0;
371
+ return b;
372
+ }
373
+ toHex() {
374
+ return bytesToHex(this.toBytes());
375
+ }
376
+ // encode to hex string
377
+ clearCofactor() {
378
+ return this.multiply(big(h), false);
379
+ }
380
+ isSmallOrder() {
381
+ return this.clearCofactor().is0();
382
+ }
383
+ isTorsionFree() {
384
+ let p = this.multiply(N / 2n, false).double();
385
+ if (N % 2n)
386
+ p = p.add(this);
387
+ return p.is0();
388
+ }
389
+ static fromHex(hex, zip215) {
390
+ return _Point.fromBytes(toU8(hex), zip215);
391
+ }
392
+ get x() {
393
+ return this.toAffine().x;
394
+ }
395
+ get y() {
396
+ return this.toAffine().y;
397
+ }
398
+ toRawBytes() {
399
+ return this.toBytes();
400
+ }
401
+ };
402
+ G = new Point(Gx, Gy, 1n, M(Gx * Gy));
403
+ I = new Point(0n, 1n, 1n, 0n);
404
+ Point.BASE = G;
405
+ Point.ZERO = I;
406
+ numTo32bLE = (num) => hexToBytes(padh(arange(num, 0n, B256), L2)).reverse();
407
+ bytesToNumLE = (b) => big("0x" + bytesToHex(u8fr(abytes(b)).reverse()));
408
+ pow2 = (x, power) => {
409
+ let r = x;
410
+ while (power-- > 0n) {
411
+ r *= r;
412
+ r %= P;
413
+ }
414
+ return r;
415
+ };
416
+ pow_2_252_3 = (x) => {
417
+ const x2 = x * x % P;
418
+ const b2 = x2 * x % P;
419
+ const b4 = pow2(b2, 2n) * b2 % P;
420
+ const b5 = pow2(b4, 1n) * x % P;
421
+ const b10 = pow2(b5, 5n) * b5 % P;
422
+ const b20 = pow2(b10, 10n) * b10 % P;
423
+ const b40 = pow2(b20, 20n) * b20 % P;
424
+ const b80 = pow2(b40, 40n) * b40 % P;
425
+ const b160 = pow2(b80, 80n) * b80 % P;
426
+ const b240 = pow2(b160, 80n) * b80 % P;
427
+ const b250 = pow2(b240, 10n) * b10 % P;
428
+ const pow_p_5_8 = pow2(b250, 2n) * x % P;
429
+ return { pow_p_5_8, b2 };
430
+ };
431
+ RM1 = 0x2b8324804fc1df0b2b4d00993dfbd7a72f431806ad2fe478c4ee1b274a0ea0b0n;
432
+ uvRatio = (u, v) => {
433
+ const v3 = M(v * v * v);
434
+ const v7 = M(v3 * v3 * v);
435
+ const pow = pow_2_252_3(u * v7).pow_p_5_8;
436
+ let x = M(u * v3 * pow);
437
+ const vx2 = M(v * x * x);
438
+ const root1 = x;
439
+ const root2 = M(x * RM1);
440
+ const useRoot1 = vx2 === u;
441
+ const useRoot2 = vx2 === M(-u);
442
+ const noRoot = vx2 === M(-u * RM1);
443
+ if (useRoot1)
444
+ x = root1;
445
+ if (useRoot2 || noRoot)
446
+ x = root2;
447
+ if ((M(x) & 1n) === 1n)
448
+ x = M(-x);
449
+ return { isValid: useRoot1 || useRoot2, value: x };
450
+ };
451
+ modL_LE = (hash) => modN(bytesToNumLE(hash));
452
+ sha512a = (...m) => etc.sha512Async(...m);
453
+ sha512s = (...m) => callHash("sha512Sync")(...m);
454
+ hash2extK = (hashed) => {
455
+ const head = hashed.slice(0, L);
456
+ head[0] &= 248;
457
+ head[31] &= 127;
458
+ head[31] |= 64;
459
+ const prefix = hashed.slice(L, L2);
460
+ const scalar = modL_LE(head);
461
+ const point = G.multiply(scalar);
462
+ const pointBytes = point.toBytes();
463
+ return { head, prefix, scalar, point, pointBytes };
464
+ };
465
+ getExtendedPublicKeyAsync = (priv) => sha512a(toU8(priv, L)).then(hash2extK);
466
+ getExtendedPublicKey = (priv) => hash2extK(sha512s(toU8(priv, L)));
467
+ getPublicKeyAsync = (priv) => getExtendedPublicKeyAsync(priv).then((p) => p.pointBytes);
468
+ getPublicKey = (priv) => getExtendedPublicKey(priv).pointBytes;
469
+ hashFinishA = (res) => sha512a(res.hashable).then(res.finish);
470
+ hashFinishS = (res) => res.finish(sha512s(res.hashable));
471
+ _sign = (e, rBytes, msg) => {
472
+ const { pointBytes: P2, scalar: s } = e;
473
+ const r = modL_LE(rBytes);
474
+ const R = G.multiply(r).toBytes();
475
+ const hashable = concatBytes(R, P2, msg);
476
+ const finish = (hashed) => {
477
+ const S = modN(r + modL_LE(hashed) * s);
478
+ return abytes(concatBytes(R, numTo32bLE(S)), L2);
479
+ };
480
+ return { hashable, finish };
481
+ };
482
+ signAsync = async (msg, privKey) => {
483
+ const m = toU8(msg);
484
+ const e = await getExtendedPublicKeyAsync(privKey);
485
+ const rBytes = await sha512a(e.prefix, m);
486
+ return hashFinishA(_sign(e, rBytes, m));
487
+ };
488
+ sign = (msg, privKey) => {
489
+ const m = toU8(msg);
490
+ const e = getExtendedPublicKey(privKey);
491
+ const rBytes = sha512s(e.prefix, m);
492
+ return hashFinishS(_sign(e, rBytes, m));
493
+ };
494
+ veriOpts = { zip215: true };
495
+ _verify = (sig, msg, pub, opts = veriOpts) => {
496
+ sig = toU8(sig, L2);
497
+ msg = toU8(msg);
498
+ pub = toU8(pub, L);
499
+ const { zip215 } = opts;
500
+ let A;
501
+ let R;
502
+ let s;
503
+ let SB;
504
+ let hashable = Uint8Array.of();
505
+ try {
506
+ A = Point.fromHex(pub, zip215);
507
+ R = Point.fromHex(sig.slice(0, L), zip215);
508
+ s = bytesToNumLE(sig.slice(L, L2));
509
+ SB = G.multiply(s, false);
510
+ hashable = concatBytes(R.toBytes(), A.toBytes(), msg);
511
+ } catch (error) {
512
+ }
513
+ const finish = (hashed) => {
514
+ if (SB == null)
515
+ return false;
516
+ if (!zip215 && A.isSmallOrder())
517
+ return false;
518
+ const k = modL_LE(hashed);
519
+ const RkA = R.add(A.multiply(k, false));
520
+ return RkA.add(SB.negate()).clearCofactor().is0();
521
+ };
522
+ return { hashable, finish };
523
+ };
524
+ verifyAsync = async (s, m, p, opts = veriOpts) => hashFinishA(_verify(s, m, p, opts));
525
+ verify = (s, m, p, opts = veriOpts) => hashFinishS(_verify(s, m, p, opts));
526
+ etc = {
527
+ sha512Async: async (...messages) => {
528
+ const s = subtle();
529
+ const m = concatBytes(...messages);
530
+ return u8n(await s.digest("SHA-512", m.buffer));
531
+ },
532
+ sha512Sync: void 0,
533
+ bytesToHex,
534
+ hexToBytes,
535
+ concatBytes,
536
+ mod: M,
537
+ invert,
538
+ randomBytes
539
+ };
540
+ utils = {
541
+ getExtendedPublicKeyAsync,
542
+ getExtendedPublicKey,
543
+ randomPrivateKey: () => randomBytes(L),
544
+ precompute: (w = 8, p = G) => {
545
+ p.multiply(3n);
546
+ w;
547
+ return p;
548
+ }
549
+ // no-op
550
+ };
551
+ W = 8;
552
+ scalarBits = 256;
553
+ pwindows = Math.ceil(scalarBits / W) + 1;
554
+ pwindowSize = 2 ** (W - 1);
555
+ precompute = () => {
556
+ const points = [];
557
+ let p = G;
558
+ let b = p;
559
+ for (let w = 0; w < pwindows; w++) {
560
+ b = p;
561
+ points.push(b);
562
+ for (let i = 1; i < pwindowSize; i++) {
563
+ b = b.add(p);
564
+ points.push(b);
565
+ }
566
+ p = b.double();
567
+ }
568
+ return points;
569
+ };
570
+ Gpows = void 0;
571
+ ctneg = (cnd, p) => {
572
+ const n = p.negate();
573
+ return cnd ? n : p;
574
+ };
575
+ wNAF = (n) => {
576
+ const comp = Gpows || (Gpows = precompute());
577
+ let p = I;
578
+ let f = G;
579
+ const pow_2_w = 2 ** W;
580
+ const maxNum = pow_2_w;
581
+ const mask = big(pow_2_w - 1);
582
+ const shiftBy = big(W);
583
+ for (let w = 0; w < pwindows; w++) {
584
+ let wbits = Number(n & mask);
585
+ n >>= shiftBy;
586
+ if (wbits > pwindowSize) {
587
+ wbits -= maxNum;
588
+ n += 1n;
589
+ }
590
+ const off = w * pwindowSize;
591
+ const offF = off;
592
+ const offP = off + Math.abs(wbits) - 1;
593
+ const isEven = w % 2 !== 0;
594
+ const isNeg = wbits < 0;
595
+ if (wbits === 0) {
596
+ f = f.add(ctneg(isEven, comp[offF]));
597
+ } else {
598
+ p = p.add(ctneg(isNeg, comp[offP]));
599
+ }
600
+ }
601
+ return { p, f };
602
+ };
603
+ }
604
+ });
605
+
606
+ // src/index.ts
607
+ var src_exports = {};
608
+ __export(src_exports, {
609
+ Verimago: () => Verimago,
610
+ default: () => src_default
611
+ });
612
+ var import_shared = __toESM(require_dist());
613
+ __reExport(src_exports, __toESM(require_dist()));
614
+ import { createHash } from "crypto";
615
+ var Verimago = class {
616
+ constructor(opts) {
617
+ const urls = (0, import_shared.getUrls)(opts.env ?? "production");
618
+ this.baseUrl = opts.baseUrl ?? urls.api;
619
+ this.apiKey = opts.apiKey;
620
+ this.timeout = opts.timeout ?? 1e4;
621
+ }
622
+ // ── PRIVATE ────────────────────────────────────────────────────────────
623
+ async request(path, init = {}) {
624
+ const controller = new AbortController();
625
+ const timer = setTimeout(() => controller.abort(), this.timeout);
626
+ try {
627
+ const res = await fetch(`${this.baseUrl}${path}`, {
628
+ ...init,
629
+ signal: controller.signal,
630
+ headers: {
631
+ "Authorization": `Bearer ${this.apiKey}`,
632
+ "Content-Type": "application/json",
633
+ "User-Agent": "verimago-sdk/1.0.0",
634
+ ...init.headers
635
+ }
636
+ });
637
+ if (!res.ok) {
638
+ const body = await res.text().catch(() => "");
639
+ throw new Error(`Verimago API ${res.status}: ${body || res.statusText}`);
640
+ }
641
+ return res.json();
642
+ } finally {
643
+ clearTimeout(timer);
644
+ }
645
+ }
646
+ // ── HASHING ────────────────────────────────────────────────────────────
647
+ /** Compute SHA-256 hash of a video file buffer */
648
+ async hashFile(file) {
649
+ return "sha256:" + createHash("sha256").update(file).digest("hex");
650
+ }
651
+ // ── VERIFY ─────────────────────────────────────────────────────────────
652
+ /**
653
+ * Verify a video file or hash against the Verimago registry.
654
+ * Accepts a Buffer, Uint8Array, or a pre-computed 'sha256:hex' string.
655
+ * Results are cached at the CDN layer for 4 hours.
656
+ */
657
+ async verify(fileOrHash) {
658
+ const hash = typeof fileOrHash === "string" ? fileOrHash : await this.hashFile(fileOrHash);
659
+ return this.request(`/v1/verify/${encodeURIComponent(hash)}`);
660
+ }
661
+ // ── SIGN ───────────────────────────────────────────────────────────────
662
+ /**
663
+ * Sign a video locally and return a manifest object.
664
+ * Does NOT publish — call publish() separately.
665
+ * The private key never leaves your environment.
666
+ */
667
+ async sign(file, opts) {
668
+ const videoHash = await this.hashFile(file);
669
+ const signedAt = (/* @__PURE__ */ new Date()).toISOString();
670
+ const payload = JSON.stringify({
671
+ videoHash,
672
+ certId: opts.certId,
673
+ metadata: opts.metadata,
674
+ signedAt
675
+ });
676
+ const ed = await Promise.resolve().then(() => (init_ed25519(), ed25519_exports));
677
+ const privBytes = Buffer.from(opts.privateKey, "base64");
678
+ const sigBytes = await ed.signAsync(new TextEncoder().encode(payload), privBytes);
679
+ const signature = Buffer.from(sigBytes).toString("base64");
680
+ return {
681
+ id: "",
682
+ // assigned by registry on publish
683
+ videoHash,
684
+ certId: opts.certId,
685
+ signature,
686
+ metadata: opts.metadata,
687
+ signedAt
688
+ };
689
+ }
690
+ // ── PUBLISH ────────────────────────────────────────────────────────────
691
+ /** Publish a signed manifest to the Verimago registry */
692
+ async publish(manifest) {
693
+ return this.request("/v1/manifests", {
694
+ method: "POST",
695
+ body: JSON.stringify(manifest)
696
+ });
697
+ }
698
+ // ── UGC ────────────────────────────────────────────────────────────────
699
+ /**
700
+ * Submit a social media URL for UGC corroboration analysis.
701
+ * Returns immediately with an analysis ID; poll /v1/ugc/:id for results.
702
+ */
703
+ async analyzeUGC(url, opts = {}) {
704
+ return this.request("/v1/ugc/analyze", {
705
+ method: "POST",
706
+ body: JSON.stringify({ url, ...opts })
707
+ });
708
+ }
709
+ /** Poll for UGC analysis results */
710
+ async getUGCAnalysis(id) {
711
+ return this.request(`/v1/ugc/${id}`);
712
+ }
713
+ // ── CERTIFICATES ───────────────────────────────────────────────────────
714
+ /** List all verified publisher certificates */
715
+ async listCertificates(page = 1, pageSize = 50) {
716
+ return this.request(
717
+ `/v1/certs?page=${page}&pageSize=${pageSize}`
718
+ );
719
+ }
720
+ /** Get a single certificate by ID */
721
+ async getCertificate(certId) {
722
+ return this.request(`/v1/certs/${certId}`);
723
+ }
724
+ // ── HEALTH ─────────────────────────────────────────────────────────────
725
+ /** Check API health — useful in health-check scripts */
726
+ async health() {
727
+ return this.request("/v1/health");
728
+ }
729
+ };
730
+ var src_default = Verimago;
731
+ export {
732
+ Verimago,
733
+ src_default as default
734
+ };
735
+ /*! Bundled license information:
736
+
737
+ @noble/ed25519/index.js:
738
+ (*! noble-ed25519 - MIT License (c) 2019 Paul Miller (paulmillr.com) *)
739
+ */
package/package.json ADDED
@@ -0,0 +1,40 @@
1
+ {
2
+ "name": "@verimago/sdk",
3
+ "version": "1.0.0",
4
+ "description": "Official Verimago SDK — verify, sign, and publish video authenticity certificates",
5
+ "main": "dist/index.js",
6
+ "types": "dist/index.d.ts",
7
+ "exports": {
8
+ ".": {
9
+ "require": "./dist/index.js",
10
+ "import": "./dist/index.mjs",
11
+ "types": "./dist/index.d.ts"
12
+ }
13
+ },
14
+ "files": ["dist", "README.md"],
15
+ "scripts": {
16
+ "build": "tsc && npm run build:esm",
17
+ "build:esm": "esbuild src/index.ts --bundle --format=esm --platform=browser --outfile=dist/index.mjs --external:crypto",
18
+ "test": "jest --passWithNoTests",
19
+ "prepublishOnly": "npm run build && npm test"
20
+ },
21
+ "dependencies": {
22
+ "@noble/ed25519": "^2.0.0",
23
+ "@noble/hashes": "^1.3.0",
24
+ "@verimago/shared": "*"
25
+ },
26
+ "peerDependencies": {
27
+ "typescript": ">=5.0"
28
+ },
29
+ "devDependencies": {
30
+ "@types/node": "^20.0.0",
31
+ "esbuild": "^0.20.0",
32
+ "jest": "^29.0.0",
33
+ "ts-jest": "^29.0.0",
34
+ "typescript": "^5.3.0"
35
+ },
36
+ "publishConfig": { "access": "public" },
37
+ "repository": { "type": "git", "url": "https://github.com/verimago/verimago" },
38
+ "license": "MIT",
39
+ "keywords": ["video", "authenticity", "certificate", "provenance", "deepfake", "c2pa"]
40
+ }