@fide.work/fcp 0.0.1

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 ADDED
@@ -0,0 +1,19 @@
1
+ # `@fide-work/fcp` (v0)
2
+
3
+ Minimal FCP SDK focused on deterministic Fide ID derivation.
4
+
5
+ ## Exported API
6
+
7
+ - `calculateFideID(entityType, sourceEntityType, rawIdentifier)`
8
+
9
+ ## Notes
10
+
11
+ - Hash algorithm is SHA-256.
12
+ - `rawIdentifier` is UTF-8 encoded inside `calculateFideID`.
13
+ - Output format is `did:fide:0x{type}{source}{fingerprint}`.
14
+ - Fingerprint rule is the last 38 hex chars of the SHA-256 digest.
15
+ - `calculateFideID` is async.
16
+
17
+ ## Golden Vectors
18
+
19
+ Reference vectors are in `vectors/calculateFideID.v0.json`.
@@ -0,0 +1,15 @@
1
+ export declare const TYPE_MAP: {
2
+ readonly Statement: "0";
3
+ readonly Attestation: "a";
4
+ readonly EvaluationMethod: "e";
5
+ readonly Person: "1";
6
+ readonly Organization: "2";
7
+ readonly Place: "3";
8
+ readonly Event: "4";
9
+ readonly Product: "5";
10
+ readonly CreativeWork: "6";
11
+ readonly AutonomousAgent: "7";
12
+ readonly CryptographicAccount: "8";
13
+ };
14
+ export type FideEntityType = keyof typeof TYPE_MAP;
15
+ export declare function calculateFideID(entityType: FideEntityType, sourceEntityType: FideEntityType, rawIdentifier: string): Promise<`did:fide:0x${string}`>;
@@ -0,0 +1,43 @@
1
+ export const TYPE_MAP = {
2
+ Statement: "0",
3
+ Attestation: "a",
4
+ EvaluationMethod: "e",
5
+ Person: "1",
6
+ Organization: "2",
7
+ Place: "3",
8
+ Event: "4",
9
+ Product: "5",
10
+ CreativeWork: "6",
11
+ AutonomousAgent: "7",
12
+ CryptographicAccount: "8"
13
+ };
14
+ async function getSubtleCrypto() {
15
+ if (globalThis.crypto?.subtle) {
16
+ return globalThis.crypto.subtle;
17
+ }
18
+ const { webcrypto } = await import("node:crypto");
19
+ return webcrypto.subtle;
20
+ }
21
+ function isStatementFideID(value) {
22
+ return /^did:fide:0x00[0-9a-f]{38}$/i.test(value) || /^0x00[0-9a-f]{38}$/i.test(value);
23
+ }
24
+ export async function calculateFideID(entityType, sourceEntityType, rawIdentifier) {
25
+ if (typeof rawIdentifier !== "string") {
26
+ throw new TypeError(`Invalid rawIdentifier: expected string, got ${typeof rawIdentifier}`);
27
+ }
28
+ if ((entityType === "Statement" && sourceEntityType !== "Statement") ||
29
+ (entityType === "Attestation" && sourceEntityType !== "Attestation")) {
30
+ throw new Error(`Protocol entity ${entityType} must be self-sourced. Expected source type: ${entityType}, got: ${sourceEntityType}`);
31
+ }
32
+ if (sourceEntityType === "Statement" && entityType !== "Statement" && !isStatementFideID(rawIdentifier)) {
33
+ throw new Error(`Invalid Statement source for ${entityType}: rawIdentifier must be a Statement Fide ID (did:fide:0x00... or 0x00...).`);
34
+ }
35
+ const subtle = await getSubtleCrypto();
36
+ const bytes = new TextEncoder().encode(rawIdentifier);
37
+ const digest = await subtle.digest("SHA-256", bytes);
38
+ const hashHex = Array.from(new Uint8Array(digest))
39
+ .map((byte) => byte.toString(16).padStart(2, "0"))
40
+ .join("");
41
+ const fingerprint = hashHex.slice(-38);
42
+ return `did:fide:0x${TYPE_MAP[entityType]}${TYPE_MAP[sourceEntityType]}${fingerprint}`;
43
+ }
@@ -0,0 +1 @@
1
+ export { TYPE_MAP, calculateFideID, type FideEntityType } from "./calculateFideID.js";
package/dist/index.js ADDED
@@ -0,0 +1 @@
1
+ export { TYPE_MAP, calculateFideID } from "./calculateFideID.js";
package/package.json ADDED
@@ -0,0 +1,44 @@
1
+ {
2
+ "name": "@fide.work/fcp",
3
+ "version": "0.0.1",
4
+ "description": "Fide Context Protocol SDK (v0)",
5
+ "license": "Apache-2.0",
6
+ "repository": {
7
+ "type": "git",
8
+ "url": "https://github.com/fide-work/fcp.git"
9
+ },
10
+ "homepage": "https://github.com/fide-work/fcp",
11
+ "keywords": [
12
+ "fide",
13
+ "fcp",
14
+ "did",
15
+ "identity",
16
+ "sha256"
17
+ ],
18
+ "sideEffects": false,
19
+ "engines": {
20
+ "node": ">=20"
21
+ },
22
+ "type": "module",
23
+ "main": "./dist/index.js",
24
+ "types": "./dist/index.d.ts",
25
+ "exports": {
26
+ ".": {
27
+ "types": "./dist/index.d.ts",
28
+ "default": "./dist/index.js"
29
+ }
30
+ },
31
+ "files": [
32
+ "dist",
33
+ "README.md",
34
+ "vectors"
35
+ ],
36
+ "scripts": {
37
+ "build": "tsc -p tsconfig.json",
38
+ "test": "pnpm run build && node scripts/check-vectors.mjs"
39
+ },
40
+ "devDependencies": {
41
+ "@types/node": "^22.13.10",
42
+ "typescript": "^5.9.3"
43
+ }
44
+ }
@@ -0,0 +1,28 @@
1
+ {
2
+ "version": "v0",
3
+ "algorithm": "SHA-256",
4
+ "fingerprintRule": "last-38-hex-chars",
5
+ "cases": [
6
+ {
7
+ "name": "person-product-url",
8
+ "entityType": "Person",
9
+ "sourceEntityType": "Product",
10
+ "rawIdentifier": "https://x.com/alice",
11
+ "expectedFideID": "did:fide:0x152f02f1d1c1e62b2e569e11818420c1968be3d9"
12
+ },
13
+ {
14
+ "name": "person-product-unicode",
15
+ "entityType": "Person",
16
+ "sourceEntityType": "Product",
17
+ "rawIdentifier": "Alice 🚀",
18
+ "expectedFideID": "did:fide:0x1515bbb7d07cd07283b643b8bc179fc841ceff36"
19
+ },
20
+ {
21
+ "name": "statement-statement-empty",
22
+ "entityType": "Statement",
23
+ "sourceEntityType": "Statement",
24
+ "rawIdentifier": "",
25
+ "expectedFideID": "did:fide:0x006fb92427ae41e4649b934ca495991b7852b855"
26
+ }
27
+ ]
28
+ }