@majikah/majik-slink 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -3,21 +3,24 @@
3
3
  [![Developed by Zelijah](https://img.shields.io/badge/Developed%20by-Zelijah-red?logo=github&logoColor=white)](https://www.thezelijah.world) ![GitHub Sponsors](https://img.shields.io/github/sponsors/jedlsf?style=plastic&label=Sponsors&link=https%3A%2F%2Fgithub.com%2Fsponsors%2Fjedlsf)
4
4
  ![npm](https://img.shields.io/npm/v/@majikah/majik-slink) ![npm downloads](https://img.shields.io/npm/dm/@majikah/majik-slink) [![License](https://img.shields.io/badge/License-Apache_2.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) ![TypeScript](https://img.shields.io/badge/TypeScript-Ready-blue)
5
5
 
6
- **MajikSLink** is a specialized TypeScript library designed for URL ownership verification and cryptographic identity linking. It provides a robust, zero-trust mechanism to prove that a specific digital identity (a **MajikKey**) controls a publicly accessible web resource (such as a YouTube channel, social media profile, DNS record, or personal blog).
6
+ **MajikSLink** is a specialized TypeScript library designed for URL binding, ownership, and cryptographic attribution. It provides a robust, zero-trust mechanism to prove that a specific digital identity (via a **MajikKey** and **MUID**) controls or is attested to a publicly accessible web resource (such as a YouTube channel, social media profile, DNS record, or personal blog).
7
7
 
8
- By combining traditional **Ed25519** signatures with post-quantum **ML-DSA-87 (Dilithium)** hybrid cryptography via `@majikah/majik-signature`, MajikSLink ensures that your identity-to-URL associations are tamper-proof and resilient against future quantum threats.
8
+ By combining traditional **Ed25519** signatures with post-quantum **ML-DSA-87 (Dilithium)** hybrid cryptography via `@majikah/majik-signature`, MajikSLink ensures that your identity-to-URL associations are tamper-proof, resilient against future quantum threats, and structurally decoupled for decentralized verification.
9
9
 
10
- Identities can be created and managed via the web application at **[https://id.majikah.solutions](https://id.majikah.solutions)** using your own Majik Keys.
10
+ Identities can be created and managed via the web application at **[https://id.majikah.solutions](https://id.majikah.solutions)**.
11
11
 
12
12
  ---
13
13
 
14
14
  ## Key Features
15
15
 
16
- 1. **Deterministic URL Normalization:** Automatically converts URLs into a canonical `cleanUrl` format (stripping tracking queries, fragments, and trailing slashes) so that the same core resource always generates a consistent verification code and hash.
17
- 2. **Challenge-Response Verification:** Generates short, OTP-style verification codes (`vCode`) that users can place in DNS TXT records, bios, or page metadata for automated verifiers to detect.
18
- 3. **Post-Quantum Hybrid Signing:** Leverages `MajikSignature` to sign the canonical URL data, guaranteeing non-repudiation.
19
- 4. **Trustless Proof of Ownership:** Enables a decentralized workflow where a web crawler verifies the presence of a challenge code, and the library independently verifies the cryptographic signature against the owner's public keys.
20
- 5. **Flexible Serialization:** Built-in support for flawless JSON rehydration (`toJSON` / `fromJSON`) and Base64 serialization (`serialize` / `deserialize`) for seamless database storage and API transmission.
16
+ 1. **Deterministic URL Normalization:** Automatically converts URLs into a canonical format (`majik-slink-v1:<subdomain>::<sld>::<tld>::<path>`). It strips tracking queries, fragments, and trailing slashes so the exact same core resource always generates a consistent hash and verification code.
17
+ 2. **Flexible Claim Types:**
18
+ * **`ownership`**: The strongest claim, indicating domain control. Verified via DNS TXT records.
19
+ * **`attribution`**: Indicates content control (e.g., a channel bio or GitHub README) but not DNS control. Verified via page content scraping.
20
+ * **`reference`**: A pure cryptographic attestation ("this URL is relevant to me") with no independent third-party verification possible.
21
+ 3. **Compact Post-Quantum Signatures:** Signatures are stored in a compact envelope. Public keys are *never* embedded directly, requiring verifiers to externally resolve them via the signer's `muid`, ensuring up-to-date registry checks.
22
+ 4. **Challenge-Response Verification:** Derives a short OTP-style code (`vCode`) from the SHA-256 hash of the canonical URL to be placed in DNS TXT records or page bios.
23
+ 5. **Serialization Ready:** Built-in support for flawless JSON rehydration (`toJSON` / `fromJSON`) and Base64 serialization (`serialize` / `deserialize`).
21
24
 
22
25
  ---
23
26
 
@@ -27,82 +30,113 @@ Identities can be created and managed via the web application at **[https://id.m
27
30
  npm install @majikah/majik-slink @majikah/majik-key @majikah/majik-signature
28
31
  ```
29
32
 
33
+ ---
34
+
30
35
  ## Quick Start & Usage
31
36
 
32
- ### 1. Creating and Signing a New SLink
33
- To link an identity to a URL, create a `MajikSLink` instance using a user's `MajikKey`.
37
+ ### 1. Generating a UI Challenge (Without Signing)
38
+ If you are building a UI and want to show the user their verification code *before* they confirm and sign, you can generate a challenge using just the URL.
34
39
 
35
40
  ```typescript
36
41
  import { MajikSLink } from "@majikah/majik-slink";
42
+
43
+ const preview = await MajikSLink.generateChallenge("https://github.com/majikah/repo?utm_source=test#readme");
44
+
45
+ if (preview) {
46
+ console.log("Canonical URL:", preview.cleanUrl); // https://github.com/majikah/repo
47
+ console.log("Ask user to add this to their bio:", preview.v_code); // majik-slink:xxxx...
48
+ }
49
+ ```
50
+
51
+ ### 2. Creating and Signing a New SLink
52
+ To permanently link an identity to a URL, create a `MajikSLink` instance using an unlocked `MajikKey`.
53
+
54
+ ```typescript
37
55
  import { MajikKey } from "@majikah/majik-key";
38
56
 
39
- // 1. Initialize your identity (MajikKey)
40
- const key = await MajikKey.fromSeedPhrase("your seed phrase here...");
57
+ // 1. Initialize and unlock your identity
58
+ const mnemonic = MajikKey.generateMnemonic();
59
+ const key = await MajikKey.create(mnemonic, 'my-passphrase', 'My Signing Key');
41
60
  const userId = "user_abc123";
42
61
  const muid = "muid_xyz987";
43
62
 
44
63
  // 2. Create the SLink payload
45
- const targetUrl = "https://www.youtube.com/watch?v=dQw4w9WgXcQ&t=42s";
64
+ const targetUrl = "https://www.youtube.com/watch?v=dQw4w9WgXcQ";
65
+
46
66
  const slink = await MajikSLink.create(targetUrl, key, userId, muid, {
47
- claimType: "ownership" // Defaults to "ownership" and verificationMethod: "dns_txt"
67
+ claimType: "attribution" // Automatically defaults verificationMethod to "page_content"
48
68
  });
49
69
 
50
- console.log("Canonical URL:", slink.cleanUrl); // https://www.youtube.com/watch
51
- console.log("Verification Code:", slink.vCode); // majik-slink:xxxx-xxxx-xxxx...
70
+ console.log("Status:", slink.status); // "unverified"
71
+ console.log("Source Platform:", slink.source); // "youtube"
52
72
  ```
53
73
 
54
- ### 2. Presenting the Challenge (For Verifiers)
55
- If you are building an application that needs to ask a user to verify a URL, you can generate a challenge without a private key.
74
+ ### 3. Displaying Verification Requirements
75
+ Depending on the `claimType`, you can guide users on how to prove their link:
56
76
 
57
77
  ```typescript
58
- const challenge = await MajikSLink.generateChallenge("https://github.com/majikah/repo");
59
-
60
- if (challenge) {
61
- console.log("Ask the user to place this code in their bio:", challenge.v_code);
62
- console.log("Expected resource hash:", challenge.hash);
78
+ if (slink.verificationMethod === "dns_txt") {
79
+ console.log("Add a TXT Record:");
80
+ console.log("Name:", slink.dnsRecordName); // _majik-challenge.youtube.com
81
+ console.log("Value:", slink.dnsRecordValue); // majik-slink-verify=majik-slink:a1b2...
82
+ } else if (slink.verificationMethod === "page_content") {
83
+ console.log("Add this code anywhere in your bio or README:");
84
+ console.log(slink.vCode); // majik-slink:a1b2...
85
+
86
+ // You can also display it in nice OTP chunks:
87
+ console.log("Display Code:", slink.codeChunks.join("-"));
63
88
  }
64
89
  ```
65
90
 
66
- ### 3. DNS TXT Verification Formatting
67
- For domain ownership claims, `MajikSLink` automatically formats the required DNS properties.
68
-
69
- ```typescript
70
- console.log("DNS Record Name:", slink.dnsRecordName); // e.g., _majik-challenge.github.com
71
- console.log("DNS Record Value:", slink.dnsRecordValue); // e.g., majik-slink-verify=majik-slink:...
72
- ```
73
-
74
91
  ### 4. Verifying Cryptographic Signatures
75
- When validating an SLink supplied by a user, use their public keys to verify the payload hasn't been tampered with.
92
+ Because MajikSLink uses **compact signatures**, public keys are not stored in the SLink payload. You must fetch the public keys (via `muid`) from your trusted identity registry to verify the claim.
76
93
 
77
94
  ```typescript
78
95
  import { MajikSignature } from "@majikah/majik-signature";
79
96
 
80
- // Retrieve public keys (usually fetched from a trusted identity registry)
81
- const publicKeys = {
82
- ed25519: "base64-ed25519-pubkey",
83
- mldsa: "base64-mldsa-pubkey"
84
- };
97
+ // 1. Fetch public keys from your trusted registry using the SLink's MUID
98
+ const publicKeys = await fetchPublicKeysForMuid(slink.muid);
85
99
 
86
- // Verify the hydrated SLink instance
100
+ // 2. Verify the cryptographic signature against the canonical URL
87
101
  const verificationResult = slink.verify(publicKeys);
88
102
 
89
103
  if (verificationResult.valid) {
90
104
  console.log("Valid signature from:", verificationResult.signerId);
91
- slink.markVerified(); // Update state to verified
105
+
106
+ // 3. (Optional) If you also successfully scraped the vCode from the web:
107
+ slink.markVerified();
92
108
  } else {
93
109
  slink.markSignatureInvalid();
94
110
  }
95
111
  ```
96
112
 
97
- ### 5. Serialization and Deserialization
98
- Easily store and retrieve `MajikSLink` objects from your database.
113
+ *Note: You can also verify statically without hydrating via `MajikSLink.verifySignature(slinkJSON, publicKeys)`.*
114
+
115
+ ### 5. Utilities & Comparisons
116
+ Easily compare URLs to see if they resolve to the exact same signed resource:
99
117
 
100
118
  ```typescript
101
- // Export to JSON for DB storage
119
+ // Ignores query params and fragments automatically
120
+ const isMatch = slink.isSameResource("https://www.youtube.com/watch?v=dQw4w9WgXcQ&t=42s");
121
+ console.log(isMatch); // true
122
+
123
+ // View a human-readable debug summary
124
+ console.log(slink.toSummary());
125
+ ```
126
+
127
+ ### 6. Serialization and Database Storage
128
+ Store and retrieve `MajikSLink` objects seamlessly.
129
+
130
+ ```typescript
131
+ // Export to JSON for Database storage
102
132
  const jsonPayload = slink.toJSON();
103
133
 
104
- // Hydrate from DB
134
+ // Hydrate from DB (Note: signatures must still be verified with external keys)
105
135
  const hydratedSLink = MajikSLink.fromJSON(jsonPayload);
136
+
137
+ // Export to Base64 (Useful for QR codes or URL parameters)
138
+ const base64String = slink.serialize();
139
+ const fromBase64 = MajikSLink.deserialize(base64String);
106
140
  ```
107
141
 
108
142
  ---
@@ -125,17 +159,16 @@ const hydratedSLink = MajikSLink.fromJSON(jsonPayload);
125
159
 
126
160
  ## Author
127
161
 
128
- Made with 💙 by **Zelijah**
162
+ Developed by **Josef Elijah Fabian (Zelijah)** | [Majikah Solutions OPC](https://majikah.solutions/about)
129
163
 
130
- **Developer**: Josef Elijah Delos Santos Fabian
131
- **Organization**: Majikah Solutions OPC
132
- **GitHub**: [https://github.com/jedlsf](https://github.com/jedlsf)
133
- **Project Repository**: [https://github.com/Majikah/majik-slink](https://github.com/Majikah/majik-slink)
164
+ **Developer**: [Josef Elijah Fabian](https://github.com/jedlsf)
165
+ **GitHub**: [https://github.com/Majikah](https://github.com/Majikah)
166
+ **Project Repository**: [https://github.com/Majikah/majik-slink](https://github.com/Majikah/majik-slink)
134
167
 
135
168
  ---
136
169
 
137
170
  ## Contact
138
171
 
139
- * **Business Email**: [business@thezelijah.world](mailto:business@thezelijah.world)
140
- * **Official Website**: [https://www.thezelijah.world](https://www.thezelijah.world)
141
- * **ID Web App**: [https://id.majikah.solutions](https://id.majikah.solutions)
172
+ - **Business Email**: [business@majikah.solutions](mailto:business@majikah.solutions)
173
+ - **Official Website**: [https://www.thezelijah.world](https://www.thezelijah.world)
174
+ - **Majikah Ecosystem**: [https://majikah.solutions](https://majikah.solutions)
@@ -1,3 +1,4 @@
1
+ import { ISODateString } from "@majikah/majik-key";
1
2
  import { MajikSignatureCompactJSON } from "@majikah/majik-signature";
2
3
  /**
3
4
  * What kind of relationship the user claims to have with this URL.
@@ -41,9 +42,9 @@ export interface MajikSLinkJSON {
41
42
  /** Verification status */
42
43
  status: SLinkVerificationStatus;
43
44
  /** ISO timestamp of when this SLink was created */
44
- timestamp: string;
45
+ timestamp: ISODateString;
45
46
  /** ISO timestamp of the last verification attempt, or null */
46
- verified_at: string | null;
47
+ verified_at: ISODateString | null;
47
48
  /** Compact envelope — no embedded public keys. Resolve via muid/signerId at verify time. */
48
49
  signature: MajikSignatureCompactJSON;
49
50
  }
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@majikah/majik-slink",
3
3
  "type": "module",
4
4
  "description": "Majik SLink is a specialized TypeScript library designed for URL ownership verification and cryptographic identity linking. It provides a robust mechanism to prove that a specific digital identity (a MajikKey) controls a publicly accessible web resource (such as a YouTube channel, social media profile, or personal blog).",
5
- "version": "0.1.0",
5
+ "version": "0.2.0",
6
6
  "license": "Apache-2.0",
7
7
  "author": "Zelijah",
8
8
  "main": "./dist/index.js",
@@ -50,13 +50,13 @@
50
50
  "update": "npm i @majikah/majik-key@latest @majikah/majik-signature@latest"
51
51
  },
52
52
  "dependencies": {
53
- "@majikah/majik-key": "^0.3.4",
54
- "@majikah/majik-signature": "^0.2.8",
53
+ "@majikah/majik-key": "^0.4.0",
54
+ "@majikah/majik-signature": "^0.3.0",
55
55
  "@types/psl": "^1.1.3",
56
56
  "psl": "^1.15.0"
57
57
  },
58
58
  "devDependencies": {
59
- "@types/node": "^26.1.2",
59
+ "@types/node": "^26.2.0",
60
60
  "vitest": "^4.1.10"
61
61
  }
62
62
  }