@thurinlabs/identity-kit 1.0.0 → 1.0.2
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 +5 -1
- package/dist/embed.global.js +32 -2
- package/dist/embed.global.js.map +1 -1
- package/dist/index.cjs +41 -11
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +32 -2
- package/dist/index.js.map +1 -1
- package/package.json +2 -1
package/README.md
CHANGED
|
@@ -258,12 +258,16 @@ The card talks directly to Ethereum and each proof platform — no intermediary,
|
|
|
258
258
|
|
|
259
259
|
| Provider | Proof Method |
|
|
260
260
|
|----------|-------------|
|
|
261
|
-
| GitHub | Public gist |
|
|
261
|
+
| GitHub | Public gist, or a repository description (the form an organisation can use) |
|
|
262
262
|
| DNS | TXT record |
|
|
263
263
|
| Farcaster | Public cast (requires Neynar API key) |
|
|
264
264
|
| Codeberg | Repository description |
|
|
265
265
|
| Mastodon | Profile metadata |
|
|
266
266
|
|
|
267
|
+
## Key algorithms
|
|
268
|
+
|
|
269
|
+
Any curve openpgp.js can compute is accepted: Ed25519, Cv25519, NIST P-256/384/521, brainpool, RSA, and **secp256k1**. openpgp.js rejects secp256k1 by default because RFC 9580 does not list it; identity-kit turns that rejection off, since it is a compatibility rule, not a security one. A secp256k1 PGP key doubles as an Ethereum key (the address is derived from the same public point), so anything that can sign with the PGP key can sign Ethereum transactions: hold such a key if you like, but do not fund its derived address. In Node, openpgp.js needs the `eckey-utils` package for this curve; identity-kit depends on it, so `npm install` brings it in. The browser build needs nothing extra.
|
|
270
|
+
|
|
267
271
|
## Migrating from 0.9.x
|
|
268
272
|
|
|
269
273
|
1.0.0 reads the **PGPRegistry v2** contract. The v1 registry is no longer read.
|
package/dist/embed.global.js
CHANGED
|
@@ -31148,6 +31148,7 @@ ${prettyStateOverride(stateOverride)}`;
|
|
|
31148
31148
|
}
|
|
31149
31149
|
|
|
31150
31150
|
// src/core/pgp.ts
|
|
31151
|
+
var PGP_CONFIG = { rejectCurves: /* @__PURE__ */ new Set() };
|
|
31151
31152
|
function algorithmName(keyOrSubkey) {
|
|
31152
31153
|
try {
|
|
31153
31154
|
const info = keyOrSubkey.getAlgorithmInfo();
|
|
@@ -31188,7 +31189,9 @@ ${prettyStateOverride(stateOverride)}`;
|
|
|
31188
31189
|
await cert.verify(
|
|
31189
31190
|
key.keyPacket,
|
|
31190
31191
|
cert.signatureType,
|
|
31191
|
-
{ userID: user.userID, key: key.keyPacket }
|
|
31192
|
+
{ userID: user.userID, key: key.keyPacket },
|
|
31193
|
+
void 0,
|
|
31194
|
+
PGP_CONFIG
|
|
31192
31195
|
);
|
|
31193
31196
|
} catch {
|
|
31194
31197
|
continue;
|
|
@@ -31239,7 +31242,7 @@ ${prettyStateOverride(stateOverride)}`;
|
|
|
31239
31242
|
return { verified: false, reason: "Key fingerprint mismatch" };
|
|
31240
31243
|
}
|
|
31241
31244
|
const message = await readCleartextMessage({ cleartextMessage: pgpSignature });
|
|
31242
|
-
const { signatures } = await verify({ message, verificationKeys: publicKey });
|
|
31245
|
+
const { signatures } = await verify({ message, verificationKeys: publicKey, config: PGP_CONFIG });
|
|
31243
31246
|
await signatures[0].verified;
|
|
31244
31247
|
const signedText = message.getText();
|
|
31245
31248
|
if (!signedText.toLowerCase().includes(ethAddress.toLowerCase())) {
|
|
@@ -31376,6 +31379,14 @@ ${prettyStateOverride(stateOverride)}`;
|
|
|
31376
31379
|
pattern: /^https:\/\/gist\.github\.com\/([^/]+)\/([a-f0-9]+)$/i,
|
|
31377
31380
|
parse: (m2) => ({ user: m2[1], gistId: m2[2] })
|
|
31378
31381
|
},
|
|
31382
|
+
{
|
|
31383
|
+
// A repository's description — the form an organisation can use, since
|
|
31384
|
+
// gists belong to user accounts only. Same shape as the Codeberg proof.
|
|
31385
|
+
provider: "github",
|
|
31386
|
+
label: "GitHub",
|
|
31387
|
+
pattern: /^https:\/\/github\.com\/([A-Za-z0-9-]+)\/([A-Za-z0-9._-]+)$/i,
|
|
31388
|
+
parse: (m2) => ({ user: m2[1], repo: m2[2] })
|
|
31389
|
+
},
|
|
31379
31390
|
{
|
|
31380
31391
|
provider: "dns",
|
|
31381
31392
|
label: "DNS",
|
|
@@ -31447,6 +31458,7 @@ ${prettyStateOverride(stateOverride)}`;
|
|
|
31447
31458
|
return text.toUpperCase().includes(fingerprint.toUpperCase());
|
|
31448
31459
|
}
|
|
31449
31460
|
async function verifyGitHub(proof, fingerprint) {
|
|
31461
|
+
if (proof.repo) return verifyGitHubRepo(proof, fingerprint);
|
|
31450
31462
|
try {
|
|
31451
31463
|
const resp = await fetch(`https://api.github.com/gists/${proof.gistId}`);
|
|
31452
31464
|
if (!resp.ok) return { verified: false, reason: `GitHub API returned ${resp.status}` };
|
|
@@ -31464,6 +31476,24 @@ ${prettyStateOverride(stateOverride)}`;
|
|
|
31464
31476
|
return { verified: false, reason: `GitHub fetch failed: ${err.message}` };
|
|
31465
31477
|
}
|
|
31466
31478
|
}
|
|
31479
|
+
async function verifyGitHubRepo(proof, fingerprint) {
|
|
31480
|
+
try {
|
|
31481
|
+
const resp = await fetch(
|
|
31482
|
+
`https://api.github.com/repos/${encodeURIComponent(proof.user)}/${encodeURIComponent(proof.repo)}`
|
|
31483
|
+
);
|
|
31484
|
+
if (!resp.ok) return { verified: false, reason: `GitHub API returned ${resp.status}` };
|
|
31485
|
+
const data = await resp.json();
|
|
31486
|
+
if (data.owner?.login?.toLowerCase() !== proof.user.toLowerCase()) {
|
|
31487
|
+
return { verified: false, reason: "Repository owner does not match claimed account" };
|
|
31488
|
+
}
|
|
31489
|
+
if (data.description && containsFingerprint(data.description, fingerprint)) {
|
|
31490
|
+
return { verified: true };
|
|
31491
|
+
}
|
|
31492
|
+
return { verified: false, reason: "Fingerprint token not found in repository description" };
|
|
31493
|
+
} catch (err) {
|
|
31494
|
+
return { verified: false, reason: `GitHub fetch failed: ${err.message}` };
|
|
31495
|
+
}
|
|
31496
|
+
}
|
|
31467
31497
|
async function verifyDNS(proof, fingerprint) {
|
|
31468
31498
|
try {
|
|
31469
31499
|
const resp = await fetch(
|