@bastamp/sdk 0.1.0 → 0.3.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.
- package/README.md +53 -0
- package/dist/ai-provenance.d.ts +108 -0
- package/dist/ai-provenance.d.ts.map +1 -0
- package/dist/ai-provenance.js +152 -0
- package/dist/ai-provenance.js.map +1 -0
- package/dist/client.d.ts +4 -0
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +7 -1
- package/dist/client.js.map +1 -1
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/projects.d.ts +93 -0
- package/dist/projects.d.ts.map +1 -0
- package/dist/projects.js +140 -0
- package/dist/projects.js.map +1 -0
- package/package.json +8 -3
package/README.md
CHANGED
|
@@ -97,6 +97,59 @@ const account = await client.account.get();
|
|
|
97
97
|
console.log(account.credits);
|
|
98
98
|
```
|
|
99
99
|
|
|
100
|
+
### AI provenance — attest an AI generation event
|
|
101
|
+
|
|
102
|
+
```ts
|
|
103
|
+
import { BAStamp, hashFile } from "@bastamp/sdk";
|
|
104
|
+
|
|
105
|
+
const client = new BAStamp({ apiKey: process.env.BASTAMP_API_KEY! });
|
|
106
|
+
|
|
107
|
+
const r = await client.aiProvenance.attest({
|
|
108
|
+
model: "gpt-5",
|
|
109
|
+
modelVersion: "2026-04-15",
|
|
110
|
+
prompt: userPrompt, // hashed locally — never sent
|
|
111
|
+
output: completion.text, // hashed locally — never sent
|
|
112
|
+
params: { temperature: 0.7, seed: 42 },
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
// Save the manifest alongside the AI output:
|
|
116
|
+
await fs.writeFile("output.txt", completion.text);
|
|
117
|
+
await fs.writeFile("output.provenance.json", JSON.stringify(r.manifest, null, 2));
|
|
118
|
+
console.log("anchored hash:", r.manifestHash);
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
`r.manifest` is the canonical attestation object. Deliver it with the AI output (or store it server-side). To verify later, anyone can drop the manifest on `bastamp.com/verify/<hash>` — the page recomputes the canonical SHA-256 and confirms it matches the on-chain anchor.
|
|
122
|
+
|
|
123
|
+
If your prompt or output is private, pre-hash on your side and pass `promptHash` / `outputHash` instead — the SDK never sees the cleartext. To inspect the hash without spending a credit, use `client.aiProvenance.build({...})` which returns the same manifest + hash but skips the API call.
|
|
124
|
+
|
|
125
|
+
See [`/use-cases/ai-provenance`](https://bastamp.com/use-cases/ai-provenance) for the AI Act Art. 50 framing and concrete integration examples.
|
|
126
|
+
|
|
127
|
+
### Stamp a multi-file project
|
|
128
|
+
|
|
129
|
+
```ts
|
|
130
|
+
import { BAStamp } from "@bastamp/sdk";
|
|
131
|
+
import { readFile } from "node:fs/promises";
|
|
132
|
+
|
|
133
|
+
const client = new BAStamp({ apiKey: process.env.BASTAMP_API_KEY! });
|
|
134
|
+
|
|
135
|
+
const r = await client.projects.stamp({
|
|
136
|
+
name: "Book manuscript v1",
|
|
137
|
+
description: "12 chapters as of submission",
|
|
138
|
+
files: [
|
|
139
|
+
{ name: "chapter-01.md", content: await readFile("chapter-01.md") },
|
|
140
|
+
{ name: "chapter-02.md", content: await readFile("chapter-02.md") },
|
|
141
|
+
// … up to 10,000 files
|
|
142
|
+
],
|
|
143
|
+
});
|
|
144
|
+
|
|
145
|
+
await fs.writeFile("project.manifest.json", JSON.stringify(r.manifest, null, 2));
|
|
146
|
+
console.log("anchored hash:", r.manifestHash);
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
A canonical manifest commits to every file's SHA-256 plus the project name, description, and timestamp. **One credit total, no matter how many files.** Per-file verification: hash a file locally, find its hash in `manifest.files`, confirm `manifestHash` matches the on-chain anchor.
|
|
150
|
+
|
|
151
|
+
Pass `sha256` directly per file when you've already hashed (e.g., file is private and you don't want bytes in memory). `client.projects.build({...})` returns the manifest + hash without anchoring (no credit), useful for review before commit or for batching.
|
|
152
|
+
|
|
100
153
|
### Hash any byte source
|
|
101
154
|
|
|
102
155
|
```ts
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import type { BAStamp } from "./client.js";
|
|
2
|
+
import type { CreateStampResponse, RequestOptions } from "./types.js";
|
|
3
|
+
/**
|
|
4
|
+
* Canonical manifest format BA | Stamp anchors for AI-generated content.
|
|
5
|
+
* The fields below are committed to by the on-chain hash; preserving the
|
|
6
|
+
* exact serialization (sorted keys, no whitespace) is the verifier's job.
|
|
7
|
+
*/
|
|
8
|
+
export interface AiProvenanceManifest {
|
|
9
|
+
/** Schema id — pin this so downstream parsers can reject unknown shapes. */
|
|
10
|
+
readonly schema: "bastamp.ai-provenance/v1";
|
|
11
|
+
/** Model identifier (e.g. "gpt-5", "claude-opus-4-7", "stable-diffusion-xl"). */
|
|
12
|
+
model: string;
|
|
13
|
+
/** Optional model version / snapshot (e.g. "2026-04-15"). */
|
|
14
|
+
modelVersion?: string;
|
|
15
|
+
/** SHA-256 of the prompt, 0x-prefixed lowercase. */
|
|
16
|
+
promptHash: string;
|
|
17
|
+
/** SHA-256 of the output, 0x-prefixed lowercase. */
|
|
18
|
+
outputHash: string;
|
|
19
|
+
/** Generation timestamp, ISO 8601. Defaults to now if caller omits. */
|
|
20
|
+
generatedAt: string;
|
|
21
|
+
/** Optional generation parameters (temperature, seed, top_p, etc.). */
|
|
22
|
+
params?: Record<string, unknown>;
|
|
23
|
+
/** Caller-defined metadata (request id, user id hash, etc.). */
|
|
24
|
+
metadata?: Record<string, unknown>;
|
|
25
|
+
}
|
|
26
|
+
type Hashable = string | Uint8Array | ArrayBuffer | Blob | Buffer;
|
|
27
|
+
export interface AttestInput {
|
|
28
|
+
model: string;
|
|
29
|
+
modelVersion?: string;
|
|
30
|
+
/**
|
|
31
|
+
* Either pass `prompt` (we hash it locally — bytes never leave your
|
|
32
|
+
* machine) or `promptHash` (you've already hashed it; useful when the
|
|
33
|
+
* prompt is private and you don't want it in memory longer than needed).
|
|
34
|
+
* Pass exactly one of the two.
|
|
35
|
+
*/
|
|
36
|
+
prompt?: Hashable;
|
|
37
|
+
promptHash?: string;
|
|
38
|
+
/** Same dual mode as `prompt` — either `output` or `outputHash`, not both. */
|
|
39
|
+
output?: Hashable;
|
|
40
|
+
outputHash?: string;
|
|
41
|
+
generatedAt?: Date | string;
|
|
42
|
+
params?: Record<string, unknown>;
|
|
43
|
+
metadata?: Record<string, unknown>;
|
|
44
|
+
}
|
|
45
|
+
export interface AttestResult {
|
|
46
|
+
/** The manifest object — save this; it's needed to verify later. */
|
|
47
|
+
manifest: AiProvenanceManifest;
|
|
48
|
+
/** Canonical (sorted keys, no whitespace) JSON string — what was hashed. */
|
|
49
|
+
manifestCanon: string;
|
|
50
|
+
/** The anchored hash. Same as `stamp.stamp.contentHash`. */
|
|
51
|
+
manifestHash: string;
|
|
52
|
+
/** Underlying stamp result from /api/v1/stamps. */
|
|
53
|
+
stamp: CreateStampResponse;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* AI-provenance helper. Builds a canonical attestation manifest for a
|
|
57
|
+
* single AI generation event, hashes it locally, and anchors the hash on
|
|
58
|
+
* the BA | Stamp pipeline — no new endpoint, no schema, just an opinionated
|
|
59
|
+
* convention on top of /api/v1/stamps.
|
|
60
|
+
*
|
|
61
|
+
* The caller keeps the returned `manifest` (or `manifestCanon` string) and
|
|
62
|
+
* delivers it alongside the AI output. A verifier later drops the manifest
|
|
63
|
+
* on bastamp.com/verify/{hash}, the page recomputes the canonical SHA-256
|
|
64
|
+
* and confirms it matches the on-chain anchor.
|
|
65
|
+
*/
|
|
66
|
+
export declare class AiProvenanceResource {
|
|
67
|
+
#private;
|
|
68
|
+
constructor(client: BAStamp);
|
|
69
|
+
/**
|
|
70
|
+
* Attest a single AI generation. Charges 1 credit on first submission
|
|
71
|
+
* for a given manifest; identical re-submissions are deduped by the
|
|
72
|
+
* underlying stamping flow (returns `duplicate: true`, no charge).
|
|
73
|
+
*
|
|
74
|
+
* ```ts
|
|
75
|
+
* const r = await client.aiProvenance.attest({
|
|
76
|
+
* model: "gpt-5",
|
|
77
|
+
* modelVersion: "2026-04-15",
|
|
78
|
+
* prompt: "Summarize this email …", // hashed locally
|
|
79
|
+
* output: completion.text, // hashed locally
|
|
80
|
+
* params: { temperature: 0.7, seed: 42 },
|
|
81
|
+
* });
|
|
82
|
+
*
|
|
83
|
+
* // save r.manifest with your output; r.stamp.stamp.contentHash is on chain.
|
|
84
|
+
* await fs.writeFile("provenance.json", JSON.stringify(r.manifest, null, 2));
|
|
85
|
+
* ```
|
|
86
|
+
*/
|
|
87
|
+
attest(input: AttestInput, options?: RequestOptions): Promise<AttestResult>;
|
|
88
|
+
/**
|
|
89
|
+
* Build the canonical manifest + hash for an AI generation, WITHOUT
|
|
90
|
+
* anchoring it. Useful when the caller wants to inspect the hash before
|
|
91
|
+
* paying a credit, or when batching many attestations to anchor with
|
|
92
|
+
* `client.stamps.createBatch` instead.
|
|
93
|
+
*/
|
|
94
|
+
build(input: AttestInput): Promise<{
|
|
95
|
+
manifest: AiProvenanceManifest;
|
|
96
|
+
manifestCanon: string;
|
|
97
|
+
manifestHash: string;
|
|
98
|
+
}>;
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Canonical JSON: sorted keys at every depth, no whitespace. MUST match
|
|
102
|
+
* the implementation on bastamp.com's /verify page (verify-upload.tsx)
|
|
103
|
+
* and in the stamp-extension service worker — otherwise the hash on chain
|
|
104
|
+
* won't match what verifiers recompute.
|
|
105
|
+
*/
|
|
106
|
+
export declare function canonicalize(value: unknown): string;
|
|
107
|
+
export {};
|
|
108
|
+
//# sourceMappingURL=ai-provenance.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ai-provenance.d.ts","sourceRoot":"","sources":["../src/ai-provenance.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,KAAK,EAAE,mBAAmB,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAGtE;;;;GAIG;AACH,MAAM,WAAW,oBAAoB;IACnC,4EAA4E;IAC5E,QAAQ,CAAC,MAAM,EAAE,0BAA0B,CAAC;IAC5C,iFAAiF;IACjF,KAAK,EAAE,MAAM,CAAC;IACd,6DAA6D;IAC7D,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,oDAAoD;IACpD,UAAU,EAAE,MAAM,CAAC;IACnB,oDAAoD;IACpD,UAAU,EAAE,MAAM,CAAC;IACnB,uEAAuE;IACvE,WAAW,EAAE,MAAM,CAAC;IACpB,uEAAuE;IACvE,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACjC,gEAAgE;IAChE,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACpC;AAED,KAAK,QAAQ,GAAG,MAAM,GAAG,UAAU,GAAG,WAAW,GAAG,IAAI,GAAG,MAAM,CAAC;AAElE,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,MAAM,CAAC;IACd,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB;;;;;OAKG;IACH,MAAM,CAAC,EAAE,QAAQ,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,8EAA8E;IAC9E,MAAM,CAAC,EAAE,QAAQ,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,IAAI,GAAG,MAAM,CAAC;IAC5B,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACjC,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACpC;AAED,MAAM,WAAW,YAAY;IAC3B,oEAAoE;IACpE,QAAQ,EAAE,oBAAoB,CAAC;IAC/B,4EAA4E;IAC5E,aAAa,EAAE,MAAM,CAAC;IACtB,4DAA4D;IAC5D,YAAY,EAAE,MAAM,CAAC;IACrB,mDAAmD;IACnD,KAAK,EAAE,mBAAmB,CAAC;CAC5B;AAED;;;;;;;;;;GAUG;AACH,qBAAa,oBAAoB;;gBAEnB,MAAM,EAAE,OAAO;IAI3B;;;;;;;;;;;;;;;;;OAiBG;IACG,MAAM,CAAC,KAAK,EAAE,WAAW,EAAE,OAAO,GAAE,cAAmB,GAAG,OAAO,CAAC,YAAY,CAAC;IAoDrF;;;;;OAKG;IACG,KAAK,CAAC,KAAK,EAAE,WAAW,GAAG,OAAO,CAAC;QACvC,QAAQ,EAAE,oBAAoB,CAAC;QAC/B,aAAa,EAAE,MAAM,CAAC;QACtB,YAAY,EAAE,MAAM,CAAC;KACtB,CAAC;CAiCH;AAID;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAMnD"}
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
import { hashFile } from "./hash.js";
|
|
2
|
+
/**
|
|
3
|
+
* AI-provenance helper. Builds a canonical attestation manifest for a
|
|
4
|
+
* single AI generation event, hashes it locally, and anchors the hash on
|
|
5
|
+
* the BA | Stamp pipeline — no new endpoint, no schema, just an opinionated
|
|
6
|
+
* convention on top of /api/v1/stamps.
|
|
7
|
+
*
|
|
8
|
+
* The caller keeps the returned `manifest` (or `manifestCanon` string) and
|
|
9
|
+
* delivers it alongside the AI output. A verifier later drops the manifest
|
|
10
|
+
* on bastamp.com/verify/{hash}, the page recomputes the canonical SHA-256
|
|
11
|
+
* and confirms it matches the on-chain anchor.
|
|
12
|
+
*/
|
|
13
|
+
export class AiProvenanceResource {
|
|
14
|
+
#client;
|
|
15
|
+
constructor(client) {
|
|
16
|
+
this.#client = client;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Attest a single AI generation. Charges 1 credit on first submission
|
|
20
|
+
* for a given manifest; identical re-submissions are deduped by the
|
|
21
|
+
* underlying stamping flow (returns `duplicate: true`, no charge).
|
|
22
|
+
*
|
|
23
|
+
* ```ts
|
|
24
|
+
* const r = await client.aiProvenance.attest({
|
|
25
|
+
* model: "gpt-5",
|
|
26
|
+
* modelVersion: "2026-04-15",
|
|
27
|
+
* prompt: "Summarize this email …", // hashed locally
|
|
28
|
+
* output: completion.text, // hashed locally
|
|
29
|
+
* params: { temperature: 0.7, seed: 42 },
|
|
30
|
+
* });
|
|
31
|
+
*
|
|
32
|
+
* // save r.manifest with your output; r.stamp.stamp.contentHash is on chain.
|
|
33
|
+
* await fs.writeFile("provenance.json", JSON.stringify(r.manifest, null, 2));
|
|
34
|
+
* ```
|
|
35
|
+
*/
|
|
36
|
+
async attest(input, options = {}) {
|
|
37
|
+
if (!input.model || typeof input.model !== "string") {
|
|
38
|
+
throw new TypeError("attest: `model` is required (e.g. 'gpt-5')");
|
|
39
|
+
}
|
|
40
|
+
if ((input.prompt == null) === (input.promptHash == null)) {
|
|
41
|
+
throw new TypeError("attest: provide exactly one of `prompt` or `promptHash`");
|
|
42
|
+
}
|
|
43
|
+
if ((input.output == null) === (input.outputHash == null)) {
|
|
44
|
+
throw new TypeError("attest: provide exactly one of `output` or `outputHash`");
|
|
45
|
+
}
|
|
46
|
+
const promptHash = input.promptHash ?? (await hashFile(toBytes(input.prompt)));
|
|
47
|
+
const outputHash = input.outputHash ?? (await hashFile(toBytes(input.output)));
|
|
48
|
+
validateHash(promptHash, "promptHash");
|
|
49
|
+
validateHash(outputHash, "outputHash");
|
|
50
|
+
const generatedAt = typeof input.generatedAt === "string"
|
|
51
|
+
? input.generatedAt
|
|
52
|
+
: (input.generatedAt ?? new Date()).toISOString();
|
|
53
|
+
const manifest = {
|
|
54
|
+
schema: "bastamp.ai-provenance/v1",
|
|
55
|
+
model: input.model,
|
|
56
|
+
...(input.modelVersion != null ? { modelVersion: input.modelVersion } : {}),
|
|
57
|
+
promptHash,
|
|
58
|
+
outputHash,
|
|
59
|
+
generatedAt,
|
|
60
|
+
...(input.params != null ? { params: input.params } : {}),
|
|
61
|
+
...(input.metadata != null ? { metadata: input.metadata } : {}),
|
|
62
|
+
};
|
|
63
|
+
const manifestCanon = canonicalize(manifest);
|
|
64
|
+
const manifestHash = "0x" + (await sha256Hex(manifestCanon));
|
|
65
|
+
const short = manifestHash.slice(2, 10);
|
|
66
|
+
const fileName = `ai-provenance-${sanitize(input.model)}-${short}.json`;
|
|
67
|
+
const stamp = await this.#client.stamps.create({
|
|
68
|
+
contentHash: manifestHash,
|
|
69
|
+
fileName,
|
|
70
|
+
fileSize: manifestCanon.length,
|
|
71
|
+
mimeType: "application/x-bastamp-ai-provenance",
|
|
72
|
+
}, options);
|
|
73
|
+
return { manifest, manifestCanon, manifestHash, stamp };
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Build the canonical manifest + hash for an AI generation, WITHOUT
|
|
77
|
+
* anchoring it. Useful when the caller wants to inspect the hash before
|
|
78
|
+
* paying a credit, or when batching many attestations to anchor with
|
|
79
|
+
* `client.stamps.createBatch` instead.
|
|
80
|
+
*/
|
|
81
|
+
async build(input) {
|
|
82
|
+
// Reuse the same logic by extracting the pre-stamp part. Duplicated
|
|
83
|
+
// intentionally rather than refactored, to keep `attest` linear-
|
|
84
|
+
// readable — the function is small.
|
|
85
|
+
if (!input.model)
|
|
86
|
+
throw new TypeError("attest: `model` is required");
|
|
87
|
+
if ((input.prompt == null) === (input.promptHash == null)) {
|
|
88
|
+
throw new TypeError("attest: provide exactly one of `prompt` or `promptHash`");
|
|
89
|
+
}
|
|
90
|
+
if ((input.output == null) === (input.outputHash == null)) {
|
|
91
|
+
throw new TypeError("attest: provide exactly one of `output` or `outputHash`");
|
|
92
|
+
}
|
|
93
|
+
const promptHash = input.promptHash ?? (await hashFile(toBytes(input.prompt)));
|
|
94
|
+
const outputHash = input.outputHash ?? (await hashFile(toBytes(input.output)));
|
|
95
|
+
validateHash(promptHash, "promptHash");
|
|
96
|
+
validateHash(outputHash, "outputHash");
|
|
97
|
+
const generatedAt = typeof input.generatedAt === "string"
|
|
98
|
+
? input.generatedAt
|
|
99
|
+
: (input.generatedAt ?? new Date()).toISOString();
|
|
100
|
+
const manifest = {
|
|
101
|
+
schema: "bastamp.ai-provenance/v1",
|
|
102
|
+
model: input.model,
|
|
103
|
+
...(input.modelVersion != null ? { modelVersion: input.modelVersion } : {}),
|
|
104
|
+
promptHash,
|
|
105
|
+
outputHash,
|
|
106
|
+
generatedAt,
|
|
107
|
+
...(input.params != null ? { params: input.params } : {}),
|
|
108
|
+
...(input.metadata != null ? { metadata: input.metadata } : {}),
|
|
109
|
+
};
|
|
110
|
+
const manifestCanon = canonicalize(manifest);
|
|
111
|
+
const manifestHash = "0x" + (await sha256Hex(manifestCanon));
|
|
112
|
+
return { manifest, manifestCanon, manifestHash };
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
// ── canonicalization ──
|
|
116
|
+
/**
|
|
117
|
+
* Canonical JSON: sorted keys at every depth, no whitespace. MUST match
|
|
118
|
+
* the implementation on bastamp.com's /verify page (verify-upload.tsx)
|
|
119
|
+
* and in the stamp-extension service worker — otherwise the hash on chain
|
|
120
|
+
* won't match what verifiers recompute.
|
|
121
|
+
*/
|
|
122
|
+
export function canonicalize(value) {
|
|
123
|
+
if (value === null || typeof value !== "object")
|
|
124
|
+
return JSON.stringify(value);
|
|
125
|
+
if (Array.isArray(value))
|
|
126
|
+
return "[" + value.map(canonicalize).join(",") + "]";
|
|
127
|
+
const obj = value;
|
|
128
|
+
const keys = Object.keys(obj).sort();
|
|
129
|
+
return "{" + keys.map((k) => JSON.stringify(k) + ":" + canonicalize(obj[k])).join(",") + "}";
|
|
130
|
+
}
|
|
131
|
+
// ── helpers ──
|
|
132
|
+
function toBytes(input) {
|
|
133
|
+
if (typeof input === "string")
|
|
134
|
+
return new TextEncoder().encode(input);
|
|
135
|
+
return input;
|
|
136
|
+
}
|
|
137
|
+
function validateHash(hash, field) {
|
|
138
|
+
if (!/^0x[0-9a-f]{64}$/.test(hash)) {
|
|
139
|
+
throw new TypeError(`attest: ${field} must match 0x[0-9a-f]{64} (got "${hash.slice(0, 12)}…")`);
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
function sanitize(s) {
|
|
143
|
+
return s.replace(/[^a-zA-Z0-9._-]/g, "_").slice(0, 32);
|
|
144
|
+
}
|
|
145
|
+
async function sha256Hex(input) {
|
|
146
|
+
const bytes = new TextEncoder().encode(input);
|
|
147
|
+
const digest = await crypto.subtle.digest("SHA-256", bytes);
|
|
148
|
+
return Array.from(new Uint8Array(digest))
|
|
149
|
+
.map((b) => b.toString(16).padStart(2, "0"))
|
|
150
|
+
.join("");
|
|
151
|
+
}
|
|
152
|
+
//# sourceMappingURL=ai-provenance.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ai-provenance.js","sourceRoot":"","sources":["../src/ai-provenance.ts"],"names":[],"mappings":"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"}
|
package/dist/client.d.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { AiProvenanceResource } from "./ai-provenance.js";
|
|
2
|
+
import { ProjectsResource } from "./projects.js";
|
|
1
3
|
import type { Account, CertificateOptions, ClientOptions, CreateBatchResponse, CreateStampResponse, RequestOptions, Stamp, StampInput, BatchInput } from "./types.js";
|
|
2
4
|
/**
|
|
3
5
|
* BA | Stamp REST client.
|
|
@@ -20,6 +22,8 @@ export declare class BAStamp {
|
|
|
20
22
|
#private;
|
|
21
23
|
readonly stamps: StampsResource;
|
|
22
24
|
readonly account: AccountResource;
|
|
25
|
+
readonly aiProvenance: AiProvenanceResource;
|
|
26
|
+
readonly projects: ProjectsResource;
|
|
23
27
|
constructor(opts: ClientOptions);
|
|
24
28
|
/** @internal */
|
|
25
29
|
_request<T>(method: "GET" | "POST", path: string, options?: {
|
package/dist/client.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EACV,OAAO,EAEP,kBAAkB,EAClB,aAAa,EACb,mBAAmB,EACnB,mBAAmB,EACnB,cAAc,EACd,KAAK,EACL,UAAU,EACV,UAAU,EACX,MAAM,YAAY,CAAC;AAMpB;;;;;;;;;;;;;;;;GAgBG;AACH,qBAAa,OAAO;;IAClB,QAAQ,CAAC,MAAM,EAAE,cAAc,CAAC;IAChC,QAAQ,CAAC,OAAO,EAAE,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAUA,OAAO,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAC1D,OAAO,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AACjD,OAAO,KAAK,EACV,OAAO,EAEP,kBAAkB,EAClB,aAAa,EACb,mBAAmB,EACnB,mBAAmB,EACnB,cAAc,EACd,KAAK,EACL,UAAU,EACV,UAAU,EACX,MAAM,YAAY,CAAC;AAMpB;;;;;;;;;;;;;;;;GAgBG;AACH,qBAAa,OAAO;;IAClB,QAAQ,CAAC,MAAM,EAAE,cAAc,CAAC;IAChC,QAAQ,CAAC,OAAO,EAAE,eAAe,CAAC;IAClC,QAAQ,CAAC,YAAY,EAAE,oBAAoB,CAAC;IAC5C,QAAQ,CAAC,QAAQ,EAAE,gBAAgB,CAAC;gBAMxB,IAAI,EAAE,aAAa;IAc/B,gBAAgB;IACV,QAAQ,CAAC,CAAC,EACd,MAAM,EAAE,KAAK,GAAG,MAAM,EACtB,IAAI,EAAE,MAAM,EACZ,OAAO,GAAE;QACP,IAAI,CAAC,EAAE,OAAO,CAAC;QACf,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC;QAC3C,cAAc,CAAC,EAAE,MAAM,CAAC;QACxB,MAAM,CAAC,EAAE,WAAW,CAAC;QAErB,GAAG,CAAC,EAAE,OAAO,CAAC;KACV,GACL,OAAO,CAAC,CAAC,CAAC;CA6Dd;AAED,cAAM,cAAc;;gBAEN,MAAM,EAAE,OAAO;IAI3B;;;;OAIG;IACG,MAAM,CAAC,KAAK,EAAE,UAAU,EAAE,OAAO,GAAE,cAAmB,GAAG,OAAO,CAAC,mBAAmB,CAAC;IAQ3F;;;OAGG;IACG,WAAW,CAAC,KAAK,EAAE,UAAU,EAAE,OAAO,GAAE,cAAmB,GAAG,OAAO,CAAC,mBAAmB,CAAC;IAchG;;;;OAIG;IACG,GAAG,CAAC,WAAW,EAAE,MAAM,EAAE,OAAO,GAAE,cAAmB,GAAG,OAAO,CAAC,KAAK,CAAC;IAM5E;;;OAGG;IACG,mBAAmB,CACvB,WAAW,EAAE,MAAM,EACnB,WAAW,GAAE,kBAAkB,GAAG,cAAmB,GACpD,OAAO,CAAC,UAAU,CAAC;CAavB;AAED,cAAM,eAAe;;gBAEP,MAAM,EAAE,OAAO;IAI3B,wEAAwE;IAClE,GAAG,CAAC,OAAO,GAAE,cAAmB,GAAG,OAAO,CAAC,OAAO,CAAC;CAG1D"}
|
package/dist/client.js
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import { BAStampError, BAStampInvalidRequestError, BAStampUnauthorizedError, BAStampNoCreditsError, BAStampNotFoundError, BAStampConflictError, BAStampRateLimitedError, } from "./errors.js";
|
|
2
2
|
import { backoffMs, retryAfterMs, shouldRetry, sleep } from "./retry.js";
|
|
3
|
+
import { AiProvenanceResource } from "./ai-provenance.js";
|
|
4
|
+
import { ProjectsResource } from "./projects.js";
|
|
3
5
|
const DEFAULT_BASE_URL = "https://bastamp.com";
|
|
4
6
|
const DEFAULT_MAX_RETRIES = 3;
|
|
5
|
-
const USER_AGENT = "bastamp-sdk-ts/0.
|
|
7
|
+
const USER_AGENT = "bastamp-sdk-ts/0.3.0";
|
|
6
8
|
/**
|
|
7
9
|
* BA | Stamp REST client.
|
|
8
10
|
*
|
|
@@ -23,6 +25,8 @@ const USER_AGENT = "bastamp-sdk-ts/0.1.0";
|
|
|
23
25
|
export class BAStamp {
|
|
24
26
|
stamps;
|
|
25
27
|
account;
|
|
28
|
+
aiProvenance;
|
|
29
|
+
projects;
|
|
26
30
|
#apiKey;
|
|
27
31
|
#baseUrl;
|
|
28
32
|
#maxRetries;
|
|
@@ -37,6 +41,8 @@ export class BAStamp {
|
|
|
37
41
|
this.#fetch = opts.fetch ?? globalThis.fetch.bind(globalThis);
|
|
38
42
|
this.stamps = new StampsResource(this);
|
|
39
43
|
this.account = new AccountResource(this);
|
|
44
|
+
this.aiProvenance = new AiProvenanceResource(this);
|
|
45
|
+
this.projects = new ProjectsResource(this);
|
|
40
46
|
}
|
|
41
47
|
/** @internal */
|
|
42
48
|
async _request(method, path, options = {}) {
|
package/dist/client.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,YAAY,EACZ,0BAA0B,EAC1B,wBAAwB,EACxB,qBAAqB,EACrB,oBAAoB,EACpB,oBAAoB,EACpB,uBAAuB,GACxB,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,WAAW,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,YAAY,EACZ,0BAA0B,EAC1B,wBAAwB,EACxB,qBAAqB,EACrB,oBAAoB,EACpB,oBAAoB,EACpB,uBAAuB,GACxB,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,WAAW,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACzE,OAAO,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAC1D,OAAO,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAcjD,MAAM,gBAAgB,GAAG,qBAAqB,CAAC;AAC/C,MAAM,mBAAmB,GAAG,CAAC,CAAC;AAC9B,MAAM,UAAU,GAAG,sBAAsB,CAAC;AAE1C;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,OAAO,OAAO;IACT,MAAM,CAAiB;IACvB,OAAO,CAAkB;IACzB,YAAY,CAAuB;IACnC,QAAQ,CAAmB;IAC3B,OAAO,CAAS;IAChB,QAAQ,CAAS;IACjB,WAAW,CAAS;IACpB,MAAM,CAA0B;IAEzC,YAAY,IAAmB;QAC7B,IAAI,CAAC,IAAI,EAAE,MAAM,IAAI,OAAO,IAAI,CAAC,MAAM,KAAK,QAAQ,EAAE,CAAC;YACrD,MAAM,IAAI,SAAS,CAAC,+BAA+B,CAAC,CAAC;QACvD,CAAC;QACD,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,MAAM,CAAC;QAC3B,IAAI,CAAC,QAAQ,GAAG,CAAC,IAAI,CAAC,OAAO,IAAI,gBAAgB,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;QACvE,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,UAAU,IAAI,mBAAmB,CAAC,CAAC;QACvE,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,KAAK,IAAI,UAAU,CAAC,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QAC9D,IAAI,CAAC,MAAM,GAAG,IAAI,cAAc,CAAC,IAAI,CAAC,CAAC;QACvC,IAAI,CAAC,OAAO,GAAG,IAAI,eAAe,CAAC,IAAI,CAAC,CAAC;QACzC,IAAI,CAAC,YAAY,GAAG,IAAI,oBAAoB,CAAC,IAAI,CAAC,CAAC;QACnD,IAAI,CAAC,QAAQ,GAAG,IAAI,gBAAgB,CAAC,IAAI,CAAC,CAAC;IAC7C,CAAC;IAED,gBAAgB;IAChB,KAAK,CAAC,QAAQ,CACZ,MAAsB,EACtB,IAAY,EACZ,UAOI,EAAE;QAEN,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,CAAC;QAC1C,IAAI,OAAO,CAAC,KAAK,EAAE,CAAC;YAClB,KAAK,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;gBACnD,IAAI,CAAC,IAAI,IAAI;oBAAE,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;YAC5C,CAAC;QACH,CAAC;QAED,MAAM,OAAO,GAA2B;YACtC,eAAe,EAAE,UAAU,IAAI,CAAC,OAAO,EAAE;YACzC,YAAY,EAAE,UAAU;YACxB,QAAQ,EAAE,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,mCAAmC,CAAC,CAAC,CAAC,kBAAkB;SACjF,CAAC;QACF,IAAI,UAA8B,CAAC;QACnC,IAAI,OAAO,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;YAC/B,OAAO,CAAC,cAAc,CAAC,GAAG,kBAAkB,CAAC;YAC7C,UAAU,GAAG,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QAC5C,CAAC;QACD,IAAI,OAAO,CAAC,cAAc,EAAE,CAAC;YAC3B,OAAO,CAAC,iBAAiB,CAAC,GAAG,OAAO,CAAC,cAAc,CAAC;QACtD,CAAC;QAED,IAAI,OAAO,GAAG,CAAC,CAAC;QAChB,qEAAqE;QACrE,OAAO,IAAI,EAAE,CAAC;YACZ,IAAI,QAAkB,CAAC;YACvB,IAAI,CAAC;gBACH,QAAQ,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,QAAQ,EAAE,EAAE;oBAC3C,MAAM;oBACN,OAAO;oBACP,IAAI,EAAE,UAAU;oBAChB,MAAM,EAAE,OAAO,CAAC,MAAM;iBACvB,CAAC,CAAC;YACL,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,gEAAgE;gBAChE,IAAI,OAAO,GAAG,IAAI,CAAC,WAAW,IAAI,CAAC,CAAC,GAAG,YAAY,YAAY,IAAI,GAAG,CAAC,IAAI,KAAK,YAAY,CAAC,EAAE,CAAC;oBAC9F,MAAM,KAAK,CAAC,SAAS,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;oBAChD,OAAO,EAAE,CAAC;oBACV,SAAS;gBACX,CAAC;gBACD,MAAM,GAAG,CAAC;YACZ,CAAC;YAED,IAAI,QAAQ,CAAC,EAAE,EAAE,CAAC;gBAChB,IAAI,OAAO,CAAC,GAAG;oBAAE,OAAO,QAAwB,CAAC;gBACjD,kBAAkB;gBAClB,IAAI,QAAQ,CAAC,MAAM,KAAK,GAAG;oBAAE,OAAO,SAAc,CAAC;gBACnD,OAAO,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAM,CAAC;YACtC,CAAC;YAED,MAAM,eAAe,GAAG,WAAW,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,OAAO,GAAG,IAAI,CAAC,WAAW,CAAC;YACnF,IAAI,eAAe,EAAE,CAAC;gBACpB,MAAM,MAAM,GAAG,YAAY,CAAC,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC,IAAI,SAAS,CAAC,OAAO,CAAC,CAAC;gBACvF,MAAM,KAAK,CAAC,MAAM,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;gBACpC,OAAO,EAAE,CAAC;gBACV,SAAS;YACX,CAAC;YAED,MAAM,MAAM,UAAU,CAAC,QAAQ,CAAC,CAAC;QACnC,CAAC;IACH,CAAC;CACF;AAED,MAAM,cAAc;IACT,OAAO,CAAU;IAC1B,YAAY,MAAe;QACzB,IAAI,CAAC,OAAO,GAAG,MAAM,CAAC;IACxB,CAAC;IAED;;;;OAIG;IACH,KAAK,CAAC,MAAM,CAAC,KAAiB,EAAE,UAA0B,EAAE;QAC1D,OAAO,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,MAAM,EAAE,gBAAgB,EAAE;YACrD,IAAI,EAAE,KAAK;YACX,cAAc,EAAE,OAAO,CAAC,cAAc,IAAI,oBAAoB,EAAE;YAChE,MAAM,EAAE,OAAO,CAAC,MAAM;SACvB,CAAC,CAAC;IACL,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,WAAW,CAAC,KAAiB,EAAE,UAA0B,EAAE;QAC/D,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC5D,MAAM,IAAI,SAAS,CAAC,gDAAgD,CAAC,CAAC;QACxE,CAAC;QACD,IAAI,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,GAAG,EAAE,CAAC;YAC7B,MAAM,IAAI,SAAS,CAAC,4CAA4C,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC;QACzF,CAAC;QACD,OAAO,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,MAAM,EAAE,sBAAsB,EAAE;YAC3D,IAAI,EAAE,KAAK;YACX,cAAc,EAAE,OAAO,CAAC,cAAc,IAAI,oBAAoB,EAAE;YAChE,MAAM,EAAE,OAAO,CAAC,MAAM;SACvB,CAAC,CAAC;IACL,CAAC;IAED;;;;OAIG;IACH,KAAK,CAAC,GAAG,CAAC,WAAmB,EAAE,UAA0B,EAAE;QACzD,OAAO,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,KAAK,EAAE,kBAAkB,kBAAkB,CAAC,WAAW,CAAC,EAAE,EAAE;YACvF,MAAM,EAAE,OAAO,CAAC,MAAM;SACvB,CAAC,CAAC;IACL,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,mBAAmB,CACvB,WAAmB,EACnB,cAAmD,EAAE;QAErD,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,QAAQ,CAC1C,KAAK,EACL,kBAAkB,kBAAkB,CAAC,WAAW,CAAC,cAAc,EAC/D;YACE,KAAK,EAAE,EAAE,MAAM,EAAE,WAAW,CAAC,MAAM,EAAE,YAAY,EAAE,WAAW,CAAC,YAAY,EAAE;YAC7E,MAAM,EAAE,WAAW,CAAC,MAAM;YAC1B,GAAG,EAAE,IAAI;SACV,CACF,CAAC;QACF,MAAM,GAAG,GAAG,MAAM,QAAQ,CAAC,WAAW,EAAE,CAAC;QACzC,OAAO,IAAI,UAAU,CAAC,GAAG,CAAC,CAAC;IAC7B,CAAC;CACF;AAED,MAAM,eAAe;IACV,OAAO,CAAU;IAC1B,YAAY,MAAe;QACzB,IAAI,CAAC,OAAO,GAAG,MAAM,CAAC;IACxB,CAAC;IAED,wEAAwE;IACxE,KAAK,CAAC,GAAG,CAAC,UAA0B,EAAE;QACpC,OAAO,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,KAAK,EAAE,iBAAiB,EAAE,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IACrF,CAAC;CACF;AAED,gBAAgB;AAEhB,KAAK,UAAU,UAAU,CAAC,QAAkB;IAC1C,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;IACnC,IAAI,MAAgC,CAAC;IACrC,IAAI,CAAC;QAAC,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAAC,CAAC;IAAC,MAAM,CAAC,CAAC,cAAc,CAAC,CAAC;IAC3D,MAAM,IAAI,GAAG,MAAM,EAAE,KAAK,EAAE,IAAI,IAAI,SAAS,CAAC;IAC9C,MAAM,OAAO,GAAG,MAAM,EAAE,KAAK,EAAE,OAAO,IAAI,IAAI,IAAI,QAAQ,QAAQ,CAAC,MAAM,EAAE,CAAC;IAC5E,MAAM,IAAI,GAAY,MAAM,IAAI,IAAI,CAAC;IAErC,QAAQ,QAAQ,CAAC,MAAM,EAAE,CAAC;QACxB,KAAK,GAAG,CAAC,CAAC,OAAO,IAAI,0BAA0B,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;QAC/D,KAAK,GAAG,CAAC,CAAC,OAAO,IAAI,wBAAwB,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;QAC7D,KAAK,GAAG,CAAC,CAAC,OAAO,IAAI,qBAAqB,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;QAC1D,KAAK,GAAG,CAAC,CAAC,OAAO,IAAI,oBAAoB,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;QACzD,KAAK,GAAG,CAAC,CAAC,OAAO,IAAI,oBAAoB,CAAC,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;QAC/D,KAAK,GAAG,CAAC,CAAC,OAAO,IAAI,uBAAuB,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;QAC5D;YACE,OAAO,IAAI,YAAY,CAAC,OAAO,EAAE,QAAQ,CAAC,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;IAClE,CAAC;AACH,CAAC;AAED,SAAS,oBAAoB;IAC3B,8EAA8E;IAC9E,OAAO,UAAU,CAAC,MAAM,CAAC,UAAU,EAAE,CAAC;AACxC,CAAC"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
export { BAStamp } from "./client.js";
|
|
2
2
|
export { hashFile } from "./hash.js";
|
|
3
|
+
export { canonicalize } from "./ai-provenance.js";
|
|
4
|
+
export type { AiProvenanceManifest, AttestInput, AttestResult, } from "./ai-provenance.js";
|
|
5
|
+
export type { ProjectManifest, ProjectFileEntry, ProjectFileInput, StampProjectInput, StampProjectResult, } from "./projects.js";
|
|
3
6
|
export { BAStampError, BAStampInvalidRequestError, BAStampUnauthorizedError, BAStampNoCreditsError, BAStampNotFoundError, BAStampConflictError, BAStampRateLimitedError, } from "./errors.js";
|
|
4
7
|
export type { Account, BatchInput, BitcoinAnchor, CertificateOptions, ClientOptions, ContentHash, CreateBatchResponse, CreateStampResponse, PolygonAnchor, RequestOptions, Stamp, StampInput, StampResult, StampStatus, } from "./types.js";
|
|
5
8
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AACtC,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AACrC,OAAO,EACL,YAAY,EACZ,0BAA0B,EAC1B,wBAAwB,EACxB,qBAAqB,EACrB,oBAAoB,EACpB,oBAAoB,EACpB,uBAAuB,GACxB,MAAM,aAAa,CAAC;AACrB,YAAY,EACV,OAAO,EACP,UAAU,EACV,aAAa,EACb,kBAAkB,EAClB,aAAa,EACb,WAAW,EACX,mBAAmB,EACnB,mBAAmB,EACnB,aAAa,EACb,cAAc,EACd,KAAK,EACL,UAAU,EACV,WAAW,EACX,WAAW,GACZ,MAAM,YAAY,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AACtC,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AACrC,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,YAAY,EACV,oBAAoB,EACpB,WAAW,EACX,YAAY,GACb,MAAM,oBAAoB,CAAC;AAC5B,YAAY,EACV,eAAe,EACf,gBAAgB,EAChB,gBAAgB,EAChB,iBAAiB,EACjB,kBAAkB,GACnB,MAAM,eAAe,CAAC;AACvB,OAAO,EACL,YAAY,EACZ,0BAA0B,EAC1B,wBAAwB,EACxB,qBAAqB,EACrB,oBAAoB,EACpB,oBAAoB,EACpB,uBAAuB,GACxB,MAAM,aAAa,CAAC;AACrB,YAAY,EACV,OAAO,EACP,UAAU,EACV,aAAa,EACb,kBAAkB,EAClB,aAAa,EACb,WAAW,EACX,mBAAmB,EACnB,mBAAmB,EACnB,aAAa,EACb,cAAc,EACd,KAAK,EACL,UAAU,EACV,WAAW,EACX,WAAW,GACZ,MAAM,YAAY,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export { BAStamp } from "./client.js";
|
|
2
2
|
export { hashFile } from "./hash.js";
|
|
3
|
+
export { canonicalize } from "./ai-provenance.js";
|
|
3
4
|
export { BAStampError, BAStampInvalidRequestError, BAStampUnauthorizedError, BAStampNoCreditsError, BAStampNotFoundError, BAStampConflictError, BAStampRateLimitedError, } from "./errors.js";
|
|
4
5
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AACtC,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AACrC,OAAO,EACL,YAAY,EACZ,0BAA0B,EAC1B,wBAAwB,EACxB,qBAAqB,EACrB,oBAAoB,EACpB,oBAAoB,EACpB,uBAAuB,GACxB,MAAM,aAAa,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AACtC,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AACrC,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAalD,OAAO,EACL,YAAY,EACZ,0BAA0B,EAC1B,wBAAwB,EACxB,qBAAqB,EACrB,oBAAoB,EACpB,oBAAoB,EACpB,uBAAuB,GACxB,MAAM,aAAa,CAAC"}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import type { BAStamp } from "./client.js";
|
|
2
|
+
import type { CreateStampResponse, RequestOptions } from "./types.js";
|
|
3
|
+
/**
|
|
4
|
+
* Canonical manifest format BA | Stamp anchors when stamping a project
|
|
5
|
+
* (a folder, a release, a case file — any set of files that belongs
|
|
6
|
+
* together). The hash anchored on chain is the SHA-256 of the
|
|
7
|
+
* canonicalized manifest. Verification of any single file: recompute
|
|
8
|
+
* the file's SHA-256, find it in `files[].sha256`, confirm the manifest
|
|
9
|
+
* hash matches the on-chain anchor.
|
|
10
|
+
*
|
|
11
|
+
* Flat list rather than a Merkle tree-of-trees. For projects up to
|
|
12
|
+
* ~10k files the manifest stays under 1 MB and is parseable on any
|
|
13
|
+
* verifier device. Larger projects can move to a tree if pull demands.
|
|
14
|
+
*/
|
|
15
|
+
export interface ProjectManifest {
|
|
16
|
+
readonly schema: "bastamp.project/v1";
|
|
17
|
+
name: string;
|
|
18
|
+
description?: string;
|
|
19
|
+
createdAt: string;
|
|
20
|
+
files: ProjectFileEntry[];
|
|
21
|
+
metadata?: Record<string, unknown>;
|
|
22
|
+
}
|
|
23
|
+
export interface ProjectFileEntry {
|
|
24
|
+
/** Human-readable filename (relative path is fine; preserve hierarchy if it matters). */
|
|
25
|
+
name: string;
|
|
26
|
+
/** SHA-256 of the file's bytes, 0x-prefixed lowercase. */
|
|
27
|
+
sha256: string;
|
|
28
|
+
/** Optional: file size in bytes. */
|
|
29
|
+
size?: number;
|
|
30
|
+
/** Optional: MIME type, metadata only. */
|
|
31
|
+
mimeType?: string;
|
|
32
|
+
}
|
|
33
|
+
type Hashable = Uint8Array | ArrayBuffer | Blob | Buffer | ReadableStream<Uint8Array>;
|
|
34
|
+
export interface ProjectFileInput {
|
|
35
|
+
/** Filename (or relative path). */
|
|
36
|
+
name: string;
|
|
37
|
+
/**
|
|
38
|
+
* Either pass `content` (the SDK hashes it locally — bytes never leave
|
|
39
|
+
* your machine) or `sha256` (you've already hashed it). Exactly one.
|
|
40
|
+
*/
|
|
41
|
+
content?: Hashable;
|
|
42
|
+
sha256?: string;
|
|
43
|
+
size?: number;
|
|
44
|
+
mimeType?: string;
|
|
45
|
+
}
|
|
46
|
+
export interface StampProjectInput {
|
|
47
|
+
name: string;
|
|
48
|
+
description?: string;
|
|
49
|
+
files: ProjectFileInput[];
|
|
50
|
+
createdAt?: Date | string;
|
|
51
|
+
metadata?: Record<string, unknown>;
|
|
52
|
+
}
|
|
53
|
+
export interface StampProjectResult {
|
|
54
|
+
manifest: ProjectManifest;
|
|
55
|
+
manifestCanon: string;
|
|
56
|
+
manifestHash: string;
|
|
57
|
+
stamp: CreateStampResponse;
|
|
58
|
+
}
|
|
59
|
+
export declare class ProjectsResource {
|
|
60
|
+
#private;
|
|
61
|
+
constructor(client: BAStamp);
|
|
62
|
+
/**
|
|
63
|
+
* Stamp a multi-file project as a single on-chain unit. Builds a
|
|
64
|
+
* canonical manifest committing to every file's SHA-256, hashes it,
|
|
65
|
+
* anchors the hash via /api/v1/stamps. Charges 1 credit regardless of
|
|
66
|
+
* the number of files in the project.
|
|
67
|
+
*
|
|
68
|
+
* ```ts
|
|
69
|
+
* const r = await client.projects.stamp({
|
|
70
|
+
* name: "Book manuscript v1",
|
|
71
|
+
* description: "12 chapters as of submission",
|
|
72
|
+
* files: [
|
|
73
|
+
* { name: "chapter-01.md", content: await readFile("chapter-01.md") },
|
|
74
|
+
* { name: "chapter-02.md", content: await readFile("chapter-02.md") },
|
|
75
|
+
* // …
|
|
76
|
+
* ],
|
|
77
|
+
* });
|
|
78
|
+
*
|
|
79
|
+
* // Save the manifest with the project — it's the verification artifact.
|
|
80
|
+
* await fs.writeFile("project.manifest.json", JSON.stringify(r.manifest, null, 2));
|
|
81
|
+
* console.log("anchored hash:", r.manifestHash);
|
|
82
|
+
* ```
|
|
83
|
+
*/
|
|
84
|
+
stamp(input: StampProjectInput, options?: RequestOptions): Promise<StampProjectResult>;
|
|
85
|
+
/** Build the manifest + hash WITHOUT anchoring (mirror of aiProvenance.build). */
|
|
86
|
+
build(input: StampProjectInput): Promise<{
|
|
87
|
+
manifest: ProjectManifest;
|
|
88
|
+
manifestCanon: string;
|
|
89
|
+
manifestHash: string;
|
|
90
|
+
}>;
|
|
91
|
+
}
|
|
92
|
+
export {};
|
|
93
|
+
//# sourceMappingURL=projects.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"projects.d.ts","sourceRoot":"","sources":["../src/projects.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,KAAK,EAAE,mBAAmB,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAItE;;;;;;;;;;;GAWG;AACH,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,MAAM,EAAE,oBAAoB,CAAC;IACtC,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,gBAAgB,EAAE,CAAC;IAC1B,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACpC;AAED,MAAM,WAAW,gBAAgB;IAC/B,yFAAyF;IACzF,IAAI,EAAE,MAAM,CAAC;IACb,0DAA0D;IAC1D,MAAM,EAAE,MAAM,CAAC;IACf,oCAAoC;IACpC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,0CAA0C;IAC1C,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,KAAK,QAAQ,GAAG,UAAU,GAAG,WAAW,GAAG,IAAI,GAAG,MAAM,GAAG,cAAc,CAAC,UAAU,CAAC,CAAC;AAEtF,MAAM,WAAW,gBAAgB;IAC/B,mCAAmC;IACnC,IAAI,EAAE,MAAM,CAAC;IACb;;;OAGG;IACH,OAAO,CAAC,EAAE,QAAQ,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,KAAK,EAAE,gBAAgB,EAAE,CAAC;IAC1B,SAAS,CAAC,EAAE,IAAI,GAAG,MAAM,CAAC;IAC1B,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACpC;AAED,MAAM,WAAW,kBAAkB;IACjC,QAAQ,EAAE,eAAe,CAAC;IAC1B,aAAa,EAAE,MAAM,CAAC;IACtB,YAAY,EAAE,MAAM,CAAC;IACrB,KAAK,EAAE,mBAAmB,CAAC;CAC5B;AAID,qBAAa,gBAAgB;;gBAEf,MAAM,EAAE,OAAO;IAI3B;;;;;;;;;;;;;;;;;;;;;OAqBG;IACG,KAAK,CAAC,KAAK,EAAE,iBAAiB,EAAE,OAAO,GAAE,cAAmB,GAAG,OAAO,CAAC,kBAAkB,CAAC;IA+DhG,kFAAkF;IAC5E,KAAK,CAAC,KAAK,EAAE,iBAAiB,GAAG,OAAO,CAAC;QAC7C,QAAQ,EAAE,eAAe,CAAC;QAC1B,aAAa,EAAE,MAAM,CAAC;QACtB,YAAY,EAAE,MAAM,CAAC;KACtB,CAAC;CAyCH"}
|
package/dist/projects.js
ADDED
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
import { hashFile } from "./hash.js";
|
|
2
|
+
import { canonicalize } from "./ai-provenance.js";
|
|
3
|
+
const MAX_FILES = 10_000;
|
|
4
|
+
export class ProjectsResource {
|
|
5
|
+
#client;
|
|
6
|
+
constructor(client) {
|
|
7
|
+
this.#client = client;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Stamp a multi-file project as a single on-chain unit. Builds a
|
|
11
|
+
* canonical manifest committing to every file's SHA-256, hashes it,
|
|
12
|
+
* anchors the hash via /api/v1/stamps. Charges 1 credit regardless of
|
|
13
|
+
* the number of files in the project.
|
|
14
|
+
*
|
|
15
|
+
* ```ts
|
|
16
|
+
* const r = await client.projects.stamp({
|
|
17
|
+
* name: "Book manuscript v1",
|
|
18
|
+
* description: "12 chapters as of submission",
|
|
19
|
+
* files: [
|
|
20
|
+
* { name: "chapter-01.md", content: await readFile("chapter-01.md") },
|
|
21
|
+
* { name: "chapter-02.md", content: await readFile("chapter-02.md") },
|
|
22
|
+
* // …
|
|
23
|
+
* ],
|
|
24
|
+
* });
|
|
25
|
+
*
|
|
26
|
+
* // Save the manifest with the project — it's the verification artifact.
|
|
27
|
+
* await fs.writeFile("project.manifest.json", JSON.stringify(r.manifest, null, 2));
|
|
28
|
+
* console.log("anchored hash:", r.manifestHash);
|
|
29
|
+
* ```
|
|
30
|
+
*/
|
|
31
|
+
async stamp(input, options = {}) {
|
|
32
|
+
if (!input.name || typeof input.name !== "string") {
|
|
33
|
+
throw new TypeError("stamp: `name` is required");
|
|
34
|
+
}
|
|
35
|
+
if (!Array.isArray(input.files) || input.files.length === 0) {
|
|
36
|
+
throw new TypeError("stamp: `files` must be a non-empty array");
|
|
37
|
+
}
|
|
38
|
+
if (input.files.length > MAX_FILES) {
|
|
39
|
+
throw new TypeError(`stamp: max ${MAX_FILES} files per project (got ${input.files.length})`);
|
|
40
|
+
}
|
|
41
|
+
const fileEntries = [];
|
|
42
|
+
for (let i = 0; i < input.files.length; i++) {
|
|
43
|
+
const f = input.files[i];
|
|
44
|
+
if (!f.name || typeof f.name !== "string") {
|
|
45
|
+
throw new TypeError(`stamp: files[${i}].name is required`);
|
|
46
|
+
}
|
|
47
|
+
if ((f.content == null) === (f.sha256 == null)) {
|
|
48
|
+
throw new TypeError(`stamp: files[${i}] must have exactly one of \`content\` or \`sha256\``);
|
|
49
|
+
}
|
|
50
|
+
const sha256 = f.sha256 ?? (await hashFile(f.content));
|
|
51
|
+
if (!/^0x[0-9a-f]{64}$/.test(sha256)) {
|
|
52
|
+
throw new TypeError(`stamp: files[${i}].sha256 must match 0x[0-9a-f]{64}`);
|
|
53
|
+
}
|
|
54
|
+
const entry = { name: f.name, sha256 };
|
|
55
|
+
if (f.size != null)
|
|
56
|
+
entry.size = f.size;
|
|
57
|
+
if (f.mimeType != null)
|
|
58
|
+
entry.mimeType = f.mimeType;
|
|
59
|
+
fileEntries.push(entry);
|
|
60
|
+
}
|
|
61
|
+
const createdAt = typeof input.createdAt === "string"
|
|
62
|
+
? input.createdAt
|
|
63
|
+
: (input.createdAt ?? new Date()).toISOString();
|
|
64
|
+
const manifest = {
|
|
65
|
+
schema: "bastamp.project/v1",
|
|
66
|
+
name: input.name,
|
|
67
|
+
...(input.description != null ? { description: input.description } : {}),
|
|
68
|
+
createdAt,
|
|
69
|
+
files: fileEntries,
|
|
70
|
+
...(input.metadata != null ? { metadata: input.metadata } : {}),
|
|
71
|
+
};
|
|
72
|
+
const manifestCanon = canonicalize(manifest);
|
|
73
|
+
const manifestHash = "0x" + (await sha256Hex(manifestCanon));
|
|
74
|
+
const short = manifestHash.slice(2, 10);
|
|
75
|
+
const fileName = `project-${sanitize(input.name)}-${short}.json`;
|
|
76
|
+
const stamp = await this.#client.stamps.create({
|
|
77
|
+
contentHash: manifestHash,
|
|
78
|
+
fileName,
|
|
79
|
+
fileSize: manifestCanon.length,
|
|
80
|
+
mimeType: "application/x-bastamp-project",
|
|
81
|
+
}, options);
|
|
82
|
+
return { manifest, manifestCanon, manifestHash, stamp };
|
|
83
|
+
}
|
|
84
|
+
/** Build the manifest + hash WITHOUT anchoring (mirror of aiProvenance.build). */
|
|
85
|
+
async build(input) {
|
|
86
|
+
// Same validation as stamp() but skip the API call. Duplicated rather
|
|
87
|
+
// than refactored for linear readability.
|
|
88
|
+
if (!input.name)
|
|
89
|
+
throw new TypeError("build: `name` is required");
|
|
90
|
+
if (!Array.isArray(input.files) || input.files.length === 0) {
|
|
91
|
+
throw new TypeError("build: `files` must be a non-empty array");
|
|
92
|
+
}
|
|
93
|
+
if (input.files.length > MAX_FILES) {
|
|
94
|
+
throw new TypeError(`build: max ${MAX_FILES} files per project (got ${input.files.length})`);
|
|
95
|
+
}
|
|
96
|
+
const fileEntries = [];
|
|
97
|
+
for (let i = 0; i < input.files.length; i++) {
|
|
98
|
+
const f = input.files[i];
|
|
99
|
+
if ((f.content == null) === (f.sha256 == null)) {
|
|
100
|
+
throw new TypeError(`build: files[${i}] must have exactly one of \`content\` or \`sha256\``);
|
|
101
|
+
}
|
|
102
|
+
const sha256 = f.sha256 ?? (await hashFile(f.content));
|
|
103
|
+
if (!/^0x[0-9a-f]{64}$/.test(sha256)) {
|
|
104
|
+
throw new TypeError(`build: files[${i}].sha256 must match 0x[0-9a-f]{64}`);
|
|
105
|
+
}
|
|
106
|
+
const entry = { name: f.name, sha256 };
|
|
107
|
+
if (f.size != null)
|
|
108
|
+
entry.size = f.size;
|
|
109
|
+
if (f.mimeType != null)
|
|
110
|
+
entry.mimeType = f.mimeType;
|
|
111
|
+
fileEntries.push(entry);
|
|
112
|
+
}
|
|
113
|
+
const createdAt = typeof input.createdAt === "string"
|
|
114
|
+
? input.createdAt
|
|
115
|
+
: (input.createdAt ?? new Date()).toISOString();
|
|
116
|
+
const manifest = {
|
|
117
|
+
schema: "bastamp.project/v1",
|
|
118
|
+
name: input.name,
|
|
119
|
+
...(input.description != null ? { description: input.description } : {}),
|
|
120
|
+
createdAt,
|
|
121
|
+
files: fileEntries,
|
|
122
|
+
...(input.metadata != null ? { metadata: input.metadata } : {}),
|
|
123
|
+
};
|
|
124
|
+
const manifestCanon = canonicalize(manifest);
|
|
125
|
+
const manifestHash = "0x" + (await sha256Hex(manifestCanon));
|
|
126
|
+
return { manifest, manifestCanon, manifestHash };
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
// ── helpers ──
|
|
130
|
+
function sanitize(s) {
|
|
131
|
+
return s.replace(/[^a-zA-Z0-9._-]/g, "_").slice(0, 32);
|
|
132
|
+
}
|
|
133
|
+
async function sha256Hex(input) {
|
|
134
|
+
const bytes = new TextEncoder().encode(input);
|
|
135
|
+
const digest = await crypto.subtle.digest("SHA-256", bytes);
|
|
136
|
+
return Array.from(new Uint8Array(digest))
|
|
137
|
+
.map((b) => b.toString(16).padStart(2, "0"))
|
|
138
|
+
.join("");
|
|
139
|
+
}
|
|
140
|
+
//# sourceMappingURL=projects.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"projects.js","sourceRoot":"","sources":["../src/projects.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bastamp/sdk",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"description": "Official TypeScript SDK for the BA | Stamp REST API — anchor SHA-256 hashes on Polygon.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Aletheia Tech Ltd",
|
|
@@ -44,12 +44,17 @@
|
|
|
44
44
|
"scripts": {
|
|
45
45
|
"build": "tsc -p tsconfig.json",
|
|
46
46
|
"typecheck": "tsc -p tsconfig.json --noEmit",
|
|
47
|
+
"test": "vitest run",
|
|
48
|
+
"test:watch": "vitest",
|
|
49
|
+
"test:coverage": "vitest run --coverage",
|
|
47
50
|
"clean": "rm -rf dist",
|
|
48
|
-
"prepublishOnly": "npm run clean && npm run build"
|
|
51
|
+
"prepublishOnly": "npm run clean && npm run typecheck && npm test && npm run build"
|
|
49
52
|
},
|
|
50
53
|
"devDependencies": {
|
|
51
54
|
"@types/node": "^22.0.0",
|
|
55
|
+
"@vitest/coverage-v8": "^4.1.6",
|
|
52
56
|
"tsx": "^4.21.0",
|
|
53
|
-
"typescript": "^5.7.0"
|
|
57
|
+
"typescript": "^5.7.0",
|
|
58
|
+
"vitest": "^4.1.6"
|
|
54
59
|
}
|
|
55
60
|
}
|