@epochcore/identity-sdk 1.0.0 → 1.1.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,109 @@
1
+ /**
2
+ * @epochcore/identity-sdk
3
+ * World's First Universal Infrastructure Identity SDK
4
+ *
5
+ * Provides Ed25519 cryptographic identities for:
6
+ * - Cloudflare Workers
7
+ * - D1 Databases
8
+ * - R2 Storage Buckets
9
+ * - Durable Objects
10
+ * - Local Daemons
11
+ */
12
+ type IdentityType = 'worker' | 'database' | 'storage' | 'durable_object' | 'daemon';
13
+ interface EpochCoreIdentity {
14
+ did: string;
15
+ publicKey: string;
16
+ fingerprint: string;
17
+ type: IdentityType;
18
+ name: string;
19
+ createdAt: string;
20
+ }
21
+ interface EpochCoreWallet {
22
+ address: string;
23
+ publicKey: string;
24
+ identityDid: string;
25
+ }
26
+ interface SignedPayload {
27
+ payload: string;
28
+ signature: string;
29
+ publicKey: string;
30
+ timestamp: string;
31
+ }
32
+ /**
33
+ * Generate a new Ed25519 keypair for infrastructure identity
34
+ */
35
+ declare function generateKeypair(): Promise<{
36
+ privateKey: string;
37
+ publicKey: string;
38
+ }>;
39
+ /**
40
+ * Create a DID (Decentralized Identifier) for infrastructure
41
+ * Format: did:epochcore:<type>:<name>:<fingerprint>
42
+ */
43
+ declare function createDID(type: IdentityType, name: string, publicKey: string): string;
44
+ /**
45
+ * Generate a complete infrastructure identity
46
+ */
47
+ declare function generateIdentity(type: IdentityType, name: string): Promise<{
48
+ identity: EpochCoreIdentity;
49
+ privateKey: string;
50
+ }>;
51
+ /**
52
+ * Derive a secp256k1 wallet from an identity for Web3 operations
53
+ */
54
+ declare function deriveWallet(privateKey: string, identityDid: string): EpochCoreWallet;
55
+ /**
56
+ * Sign a payload with Ed25519 private key
57
+ */
58
+ declare function signPayload(payload: string, privateKey: string): Promise<SignedPayload>;
59
+ /**
60
+ * Verify an Ed25519 signature
61
+ */
62
+ declare function verifySignature(payload: string, signature: string, publicKey: string): Promise<boolean>;
63
+ /**
64
+ * Parse a DID string into components
65
+ */
66
+ declare function parseDID(did: string): {
67
+ method: string;
68
+ type: IdentityType;
69
+ name: string;
70
+ fingerprint: string;
71
+ } | null;
72
+ /**
73
+ * Generate JWKS (JSON Web Key Set) for OAuth2/OIDC integration
74
+ */
75
+ declare function generateJWKS(publicKeys: string[]): {
76
+ keys: Array<{
77
+ kty: string;
78
+ crv: string;
79
+ x: string;
80
+ use: string;
81
+ kid: string;
82
+ }>;
83
+ };
84
+ declare const CONSTANTS: {
85
+ DID_PREFIX: string;
86
+ SIGNING_ALGORITHM: string;
87
+ WALLET_ALGORITHM: string;
88
+ SUPPORTED_TYPES: IdentityType[];
89
+ VERSION: string;
90
+ };
91
+ declare const _default: {
92
+ generateKeypair: typeof generateKeypair;
93
+ generateIdentity: typeof generateIdentity;
94
+ createDID: typeof createDID;
95
+ parseDID: typeof parseDID;
96
+ deriveWallet: typeof deriveWallet;
97
+ signPayload: typeof signPayload;
98
+ verifySignature: typeof verifySignature;
99
+ generateJWKS: typeof generateJWKS;
100
+ CONSTANTS: {
101
+ DID_PREFIX: string;
102
+ SIGNING_ALGORITHM: string;
103
+ WALLET_ALGORITHM: string;
104
+ SUPPORTED_TYPES: IdentityType[];
105
+ VERSION: string;
106
+ };
107
+ };
108
+
109
+ export { CONSTANTS, type EpochCoreIdentity, type EpochCoreWallet, type IdentityType, type SignedPayload, createDID, _default as default, deriveWallet, generateIdentity, generateJWKS, generateKeypair, parseDID, signPayload, verifySignature };
package/dist/index.d.ts CHANGED
@@ -9,8 +9,8 @@
9
9
  * - Durable Objects
10
10
  * - Local Daemons
11
11
  */
12
- export type IdentityType = 'worker' | 'database' | 'storage' | 'durable_object' | 'daemon';
13
- export interface EpochCoreIdentity {
12
+ type IdentityType = 'worker' | 'database' | 'storage' | 'durable_object' | 'daemon';
13
+ interface EpochCoreIdentity {
14
14
  did: string;
15
15
  publicKey: string;
16
16
  fingerprint: string;
@@ -18,12 +18,12 @@ export interface EpochCoreIdentity {
18
18
  name: string;
19
19
  createdAt: string;
20
20
  }
21
- export interface EpochCoreWallet {
21
+ interface EpochCoreWallet {
22
22
  address: string;
23
23
  publicKey: string;
24
24
  identityDid: string;
25
25
  }
26
- export interface SignedPayload {
26
+ interface SignedPayload {
27
27
  payload: string;
28
28
  signature: string;
29
29
  publicKey: string;
@@ -32,7 +32,7 @@ export interface SignedPayload {
32
32
  /**
33
33
  * Generate a new Ed25519 keypair for infrastructure identity
34
34
  */
35
- export declare function generateKeypair(): Promise<{
35
+ declare function generateKeypair(): Promise<{
36
36
  privateKey: string;
37
37
  publicKey: string;
38
38
  }>;
@@ -40,30 +40,30 @@ export declare function generateKeypair(): Promise<{
40
40
  * Create a DID (Decentralized Identifier) for infrastructure
41
41
  * Format: did:epochcore:<type>:<name>:<fingerprint>
42
42
  */
43
- export declare function createDID(type: IdentityType, name: string, publicKey: string): string;
43
+ declare function createDID(type: IdentityType, name: string, publicKey: string): string;
44
44
  /**
45
45
  * Generate a complete infrastructure identity
46
46
  */
47
- export declare function generateIdentity(type: IdentityType, name: string): Promise<{
47
+ declare function generateIdentity(type: IdentityType, name: string): Promise<{
48
48
  identity: EpochCoreIdentity;
49
49
  privateKey: string;
50
50
  }>;
51
51
  /**
52
52
  * Derive a secp256k1 wallet from an identity for Web3 operations
53
53
  */
54
- export declare function deriveWallet(privateKey: string, identityDid: string): EpochCoreWallet;
54
+ declare function deriveWallet(privateKey: string, identityDid: string): EpochCoreWallet;
55
55
  /**
56
56
  * Sign a payload with Ed25519 private key
57
57
  */
58
- export declare function signPayload(payload: string, privateKey: string): Promise<SignedPayload>;
58
+ declare function signPayload(payload: string, privateKey: string): Promise<SignedPayload>;
59
59
  /**
60
60
  * Verify an Ed25519 signature
61
61
  */
62
- export declare function verifySignature(payload: string, signature: string, publicKey: string): Promise<boolean>;
62
+ declare function verifySignature(payload: string, signature: string, publicKey: string): Promise<boolean>;
63
63
  /**
64
64
  * Parse a DID string into components
65
65
  */
66
- export declare function parseDID(did: string): {
66
+ declare function parseDID(did: string): {
67
67
  method: string;
68
68
  type: IdentityType;
69
69
  name: string;
@@ -72,7 +72,7 @@ export declare function parseDID(did: string): {
72
72
  /**
73
73
  * Generate JWKS (JSON Web Key Set) for OAuth2/OIDC integration
74
74
  */
75
- export declare function generateJWKS(publicKeys: string[]): {
75
+ declare function generateJWKS(publicKeys: string[]): {
76
76
  keys: Array<{
77
77
  kty: string;
78
78
  crv: string;
@@ -81,7 +81,7 @@ export declare function generateJWKS(publicKeys: string[]): {
81
81
  kid: string;
82
82
  }>;
83
83
  };
84
- export declare const CONSTANTS: {
84
+ declare const CONSTANTS: {
85
85
  DID_PREFIX: string;
86
86
  SIGNING_ALGORITHM: string;
87
87
  WALLET_ALGORITHM: string;
@@ -105,5 +105,5 @@ declare const _default: {
105
105
  VERSION: string;
106
106
  };
107
107
  };
108
- export default _default;
109
- //# sourceMappingURL=index.d.ts.map
108
+
109
+ export { CONSTANTS, type EpochCoreIdentity, type EpochCoreWallet, type IdentityType, type SignedPayload, createDID, _default as default, deriveWallet, generateIdentity, generateJWKS, generateKeypair, parseDID, signPayload, verifySignature };
package/dist/index.js CHANGED
@@ -1,138 +1,236 @@
1
- /**
2
- * @epochcore/identity-sdk
3
- * World's First Universal Infrastructure Identity SDK
4
- *
5
- * Provides Ed25519 cryptographic identities for:
6
- * - Cloudflare Workers
7
- * - D1 Databases
8
- * - R2 Storage Buckets
9
- * - Durable Objects
10
- * - Local Daemons
11
- */
12
- import * as ed25519 from '@noble/ed25519';
13
- import * as secp256k1 from '@noble/secp256k1';
14
- import { sha256 } from '@noble/hashes/sha256';
15
- import { bytesToHex, hexToBytes } from '@noble/hashes/utils';
16
- /**
17
- * Generate a new Ed25519 keypair for infrastructure identity
18
- */
19
- export async function generateKeypair() {
20
- const privateKey = ed25519.utils.randomPrivateKey();
21
- const publicKey = await ed25519.getPublicKeyAsync(privateKey);
22
- return {
23
- privateKey: bytesToHex(privateKey),
24
- publicKey: bytesToHex(publicKey)
25
- };
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
+
30
+ // src/index.ts
31
+ var index_exports = {};
32
+ __export(index_exports, {
33
+ CONSTANTS: () => CONSTANTS,
34
+ createDID: () => createDID,
35
+ default: () => index_default,
36
+ deriveWallet: () => deriveWallet,
37
+ generateIdentity: () => generateIdentity,
38
+ generateJWKS: () => generateJWKS,
39
+ generateKeypair: () => generateKeypair,
40
+ parseDID: () => parseDID,
41
+ signPayload: () => signPayload,
42
+ verifySignature: () => verifySignature
43
+ });
44
+ module.exports = __toCommonJS(index_exports);
45
+ var ed25519 = __toESM(require("@noble/ed25519"));
46
+ var secp256k1 = __toESM(require("@noble/secp256k1"));
47
+ var import_sha256 = require("@noble/hashes/sha256");
48
+ var import_utils = require("@noble/hashes/utils");
49
+ var HEX_64_RE = /^[0-9a-f]{64}$/i;
50
+ var NAME_RE = /^[\w.-]{1,128}$/;
51
+ var MAX_DID_LENGTH = 512;
52
+ var MAX_PAYLOAD_BYTES = 1048576;
53
+ var SECP256K1_ORDER = BigInt("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141");
54
+ function toBase64Url(bytes) {
55
+ let binary = "";
56
+ for (let i = 0; i < bytes.length; i++) binary += String.fromCharCode(bytes[i]);
57
+ const base64 = btoa(binary);
58
+ return base64.replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
26
59
  }
27
- /**
28
- * Create a DID (Decentralized Identifier) for infrastructure
29
- * Format: did:epochcore:<type>:<name>:<fingerprint>
30
- */
31
- export function createDID(type, name, publicKey) {
32
- const fingerprint = bytesToHex(sha256(hexToBytes(publicKey))).slice(0, 16);
33
- return `did:epochcore:${type}:${name}:${fingerprint}`;
60
+ function validateHex64(value, name) {
61
+ if (typeof value !== "string" || !HEX_64_RE.test(value)) {
62
+ throw new TypeError(`${name} must be a 64-character hex string`);
63
+ }
34
64
  }
35
- /**
36
- * Generate a complete infrastructure identity
37
- */
38
- export async function generateIdentity(type, name) {
39
- const { privateKey, publicKey } = await generateKeypair();
40
- const fingerprint = bytesToHex(sha256(hexToBytes(publicKey))).slice(0, 16);
41
- const did = createDID(type, name, publicKey);
42
- return {
43
- identity: {
44
- did,
45
- publicKey,
46
- fingerprint,
47
- type,
48
- name,
49
- createdAt: new Date().toISOString()
50
- },
51
- privateKey
52
- };
65
+ function validateType(type) {
66
+ if (typeof type !== "string" || !CONSTANTS.SUPPORTED_TYPES.includes(type)) {
67
+ throw new TypeError(
68
+ `Invalid identity type: ${String(type)}. Must be one of: ${CONSTANTS.SUPPORTED_TYPES.join(", ")}`
69
+ );
70
+ }
53
71
  }
54
- /**
55
- * Derive a secp256k1 wallet from an identity for Web3 operations
56
- */
57
- export function deriveWallet(privateKey, identityDid) {
58
- const seedBytes = sha256(hexToBytes(privateKey));
59
- const walletPrivKey = secp256k1.utils.normPrivateKeyToScalar(seedBytes);
60
- const walletPubKey = secp256k1.getPublicKey(walletPrivKey, false);
61
- // Ethereum-style address derivation
62
- const pubKeyHash = sha256(walletPubKey.slice(1));
63
- const address = '0x' + bytesToHex(pubKeyHash).slice(-40);
64
- return {
65
- address,
66
- publicKey: bytesToHex(walletPubKey),
67
- identityDid
68
- };
72
+ function validateName(name) {
73
+ if (typeof name !== "string" || !NAME_RE.test(name)) {
74
+ throw new TypeError("name must be 1-128 characters matching /^[\\w.-]+$/");
75
+ }
69
76
  }
70
- /**
71
- * Sign a payload with Ed25519 private key
72
- */
73
- export async function signPayload(payload, privateKey) {
74
- const message = new TextEncoder().encode(payload);
75
- const signature = await ed25519.signAsync(message, hexToBytes(privateKey));
76
- const publicKey = await ed25519.getPublicKeyAsync(hexToBytes(privateKey));
77
- return {
78
- payload,
79
- signature: bytesToHex(signature),
80
- publicKey: bytesToHex(publicKey),
81
- timestamp: new Date().toISOString()
82
- };
77
+ async function generateKeypair() {
78
+ const privateKey = ed25519.utils.randomPrivateKey();
79
+ let allZero = true;
80
+ for (let i = 0; i < privateKey.length; i++) {
81
+ if (privateKey[i] !== 0) {
82
+ allZero = false;
83
+ break;
84
+ }
85
+ }
86
+ if (allZero) {
87
+ throw new Error("Key generation produced zero-entropy private key; CSPRNG may be broken");
88
+ }
89
+ const publicKey = await ed25519.getPublicKeyAsync(privateKey);
90
+ return {
91
+ privateKey: (0, import_utils.bytesToHex)(privateKey),
92
+ publicKey: (0, import_utils.bytesToHex)(publicKey)
93
+ };
83
94
  }
84
- /**
85
- * Verify an Ed25519 signature
86
- */
87
- export async function verifySignature(payload, signature, publicKey) {
88
- const message = new TextEncoder().encode(payload);
89
- return ed25519.verifyAsync(hexToBytes(signature), message, hexToBytes(publicKey));
95
+ function createDID(type, name, publicKey) {
96
+ validateType(type);
97
+ validateName(name);
98
+ validateHex64(publicKey, "publicKey");
99
+ const fingerprint = (0, import_utils.bytesToHex)((0, import_sha256.sha256)((0, import_utils.hexToBytes)(publicKey))).slice(0, 32);
100
+ return `did:epochcore:${type}:${name}:${fingerprint}`;
90
101
  }
91
- /**
92
- * Parse a DID string into components
93
- */
94
- export function parseDID(did) {
95
- const parts = did.split(':');
96
- if (parts.length !== 5 || parts[0] !== 'did' || parts[1] !== 'epochcore') {
97
- return null;
98
- }
99
- return {
100
- method: parts[1],
101
- type: parts[2],
102
- name: parts[3],
103
- fingerprint: parts[4]
104
- };
102
+ async function generateIdentity(type, name) {
103
+ validateType(type);
104
+ validateName(name);
105
+ const { privateKey, publicKey } = await generateKeypair();
106
+ const fingerprint = (0, import_utils.bytesToHex)((0, import_sha256.sha256)((0, import_utils.hexToBytes)(publicKey))).slice(0, 32);
107
+ const did = createDID(type, name, publicKey);
108
+ return {
109
+ identity: {
110
+ did,
111
+ publicKey,
112
+ fingerprint,
113
+ type,
114
+ name,
115
+ createdAt: (/* @__PURE__ */ new Date()).toISOString()
116
+ },
117
+ privateKey
118
+ };
119
+ }
120
+ function deriveWallet(privateKey, identityDid) {
121
+ validateHex64(privateKey, "privateKey");
122
+ if (typeof identityDid !== "string" || !identityDid.startsWith("did:epochcore:")) {
123
+ throw new TypeError('identityDid must start with "did:epochcore:"');
124
+ }
125
+ const seedBytes = (0, import_sha256.sha256)((0, import_utils.hexToBytes)(privateKey));
126
+ const walletPrivKey = secp256k1.utils.normPrivateKeyToScalar(seedBytes);
127
+ if (walletPrivKey <= 0n || walletPrivKey >= SECP256K1_ORDER) {
128
+ throw new RangeError("Derived wallet private key scalar is out of valid secp256k1 range [1, n-1]");
129
+ }
130
+ const walletPubKey = secp256k1.getPublicKey(walletPrivKey, false);
131
+ const pubKeyHash = (0, import_sha256.sha256)(walletPubKey.slice(1));
132
+ const address = "0x" + (0, import_utils.bytesToHex)(pubKeyHash).slice(-40);
133
+ return {
134
+ address,
135
+ publicKey: (0, import_utils.bytesToHex)(walletPubKey),
136
+ identityDid
137
+ };
138
+ }
139
+ async function signPayload(payload, privateKey) {
140
+ if (typeof payload !== "string" || payload.length === 0) {
141
+ throw new TypeError("payload must be a non-empty string");
142
+ }
143
+ const payloadBytes = new TextEncoder().encode(payload);
144
+ if (payloadBytes.byteLength > MAX_PAYLOAD_BYTES) {
145
+ throw new RangeError(`payload exceeds maximum size of ${MAX_PAYLOAD_BYTES} bytes`);
146
+ }
147
+ validateHex64(privateKey, "privateKey");
148
+ const signature = await ed25519.signAsync(payloadBytes, (0, import_utils.hexToBytes)(privateKey));
149
+ const publicKey = await ed25519.getPublicKeyAsync((0, import_utils.hexToBytes)(privateKey));
150
+ return {
151
+ payload,
152
+ signature: (0, import_utils.bytesToHex)(signature),
153
+ publicKey: (0, import_utils.bytesToHex)(publicKey),
154
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
155
+ };
156
+ }
157
+ async function verifySignature(payload, signature, publicKey) {
158
+ if (typeof payload !== "string" || payload.length === 0) {
159
+ throw new TypeError("payload must be a non-empty string");
160
+ }
161
+ if (typeof signature !== "string" || !/^[0-9a-f]{128}$/i.test(signature)) {
162
+ throw new TypeError("signature must be a 128-character hex string");
163
+ }
164
+ validateHex64(publicKey, "publicKey");
165
+ const message = new TextEncoder().encode(payload);
166
+ return ed25519.verifyAsync(
167
+ (0, import_utils.hexToBytes)(signature),
168
+ message,
169
+ (0, import_utils.hexToBytes)(publicKey)
170
+ );
171
+ }
172
+ function parseDID(did) {
173
+ if (typeof did !== "string" || did.length > MAX_DID_LENGTH) {
174
+ return null;
175
+ }
176
+ const parts = did.split(":");
177
+ if (parts.length !== 5 || parts[0] !== "did" || parts[1] !== "epochcore") {
178
+ return null;
179
+ }
180
+ if (!CONSTANTS.SUPPORTED_TYPES.includes(parts[2])) {
181
+ return null;
182
+ }
183
+ return {
184
+ method: parts[1],
185
+ type: parts[2],
186
+ name: parts[3],
187
+ fingerprint: parts[4]
188
+ };
105
189
  }
106
- /**
107
- * Generate JWKS (JSON Web Key Set) for OAuth2/OIDC integration
108
- */
109
- export function generateJWKS(publicKeys) {
110
- return {
111
- keys: publicKeys.map((pk, i) => ({
112
- kty: 'OKP',
113
- crv: 'Ed25519',
114
- x: Buffer.from(hexToBytes(pk)).toString('base64url'),
115
- use: 'sig',
116
- kid: `epochcore-${i + 1}`
117
- }))
118
- };
190
+ function generateJWKS(publicKeys) {
191
+ if (!Array.isArray(publicKeys)) {
192
+ throw new TypeError("publicKeys must be an array");
193
+ }
194
+ for (let i = 0; i < publicKeys.length; i++) {
195
+ validateHex64(publicKeys[i], `publicKeys[${i}]`);
196
+ }
197
+ return {
198
+ keys: publicKeys.map((pk, i) => ({
199
+ kty: "OKP",
200
+ crv: "Ed25519",
201
+ x: toBase64Url((0, import_utils.hexToBytes)(pk)),
202
+ use: "sig",
203
+ kid: `epochcore-${i + 1}`
204
+ }))
205
+ };
119
206
  }
120
- // Constants
121
- export const CONSTANTS = {
122
- DID_PREFIX: 'did:epochcore',
123
- SIGNING_ALGORITHM: 'Ed25519',
124
- WALLET_ALGORITHM: 'secp256k1',
125
- SUPPORTED_TYPES: ['worker', 'database', 'storage', 'durable_object', 'daemon'],
126
- VERSION: '1.0.0'
207
+ var CONSTANTS = {
208
+ DID_PREFIX: "did:epochcore",
209
+ SIGNING_ALGORITHM: "Ed25519",
210
+ WALLET_ALGORITHM: "secp256k1",
211
+ SUPPORTED_TYPES: ["worker", "database", "storage", "durable_object", "daemon"],
212
+ VERSION: "1.1.0"
127
213
  };
128
- export default {
129
- generateKeypair,
130
- generateIdentity,
131
- createDID,
132
- parseDID,
133
- deriveWallet,
134
- signPayload,
135
- verifySignature,
136
- generateJWKS,
137
- CONSTANTS
214
+ var index_default = {
215
+ generateKeypair,
216
+ generateIdentity,
217
+ createDID,
218
+ parseDID,
219
+ deriveWallet,
220
+ signPayload,
221
+ verifySignature,
222
+ generateJWKS,
223
+ CONSTANTS
138
224
  };
225
+ // Annotate the CommonJS export names for ESM import in node:
226
+ 0 && (module.exports = {
227
+ CONSTANTS,
228
+ createDID,
229
+ deriveWallet,
230
+ generateIdentity,
231
+ generateJWKS,
232
+ generateKeypair,
233
+ parseDID,
234
+ signPayload,
235
+ verifySignature
236
+ });
package/dist/index.mjs ADDED
@@ -0,0 +1,193 @@
1
+ // src/index.ts
2
+ import * as ed25519 from "@noble/ed25519";
3
+ import * as secp256k1 from "@noble/secp256k1";
4
+ import { sha256 } from "@noble/hashes/sha256";
5
+ import { bytesToHex, hexToBytes } from "@noble/hashes/utils";
6
+ var HEX_64_RE = /^[0-9a-f]{64}$/i;
7
+ var NAME_RE = /^[\w.-]{1,128}$/;
8
+ var MAX_DID_LENGTH = 512;
9
+ var MAX_PAYLOAD_BYTES = 1048576;
10
+ var SECP256K1_ORDER = BigInt("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141");
11
+ function toBase64Url(bytes) {
12
+ let binary = "";
13
+ for (let i = 0; i < bytes.length; i++) binary += String.fromCharCode(bytes[i]);
14
+ const base64 = btoa(binary);
15
+ return base64.replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
16
+ }
17
+ function validateHex64(value, name) {
18
+ if (typeof value !== "string" || !HEX_64_RE.test(value)) {
19
+ throw new TypeError(`${name} must be a 64-character hex string`);
20
+ }
21
+ }
22
+ function validateType(type) {
23
+ if (typeof type !== "string" || !CONSTANTS.SUPPORTED_TYPES.includes(type)) {
24
+ throw new TypeError(
25
+ `Invalid identity type: ${String(type)}. Must be one of: ${CONSTANTS.SUPPORTED_TYPES.join(", ")}`
26
+ );
27
+ }
28
+ }
29
+ function validateName(name) {
30
+ if (typeof name !== "string" || !NAME_RE.test(name)) {
31
+ throw new TypeError("name must be 1-128 characters matching /^[\\w.-]+$/");
32
+ }
33
+ }
34
+ async function generateKeypair() {
35
+ const privateKey = ed25519.utils.randomPrivateKey();
36
+ let allZero = true;
37
+ for (let i = 0; i < privateKey.length; i++) {
38
+ if (privateKey[i] !== 0) {
39
+ allZero = false;
40
+ break;
41
+ }
42
+ }
43
+ if (allZero) {
44
+ throw new Error("Key generation produced zero-entropy private key; CSPRNG may be broken");
45
+ }
46
+ const publicKey = await ed25519.getPublicKeyAsync(privateKey);
47
+ return {
48
+ privateKey: bytesToHex(privateKey),
49
+ publicKey: bytesToHex(publicKey)
50
+ };
51
+ }
52
+ function createDID(type, name, publicKey) {
53
+ validateType(type);
54
+ validateName(name);
55
+ validateHex64(publicKey, "publicKey");
56
+ const fingerprint = bytesToHex(sha256(hexToBytes(publicKey))).slice(0, 32);
57
+ return `did:epochcore:${type}:${name}:${fingerprint}`;
58
+ }
59
+ async function generateIdentity(type, name) {
60
+ validateType(type);
61
+ validateName(name);
62
+ const { privateKey, publicKey } = await generateKeypair();
63
+ const fingerprint = bytesToHex(sha256(hexToBytes(publicKey))).slice(0, 32);
64
+ const did = createDID(type, name, publicKey);
65
+ return {
66
+ identity: {
67
+ did,
68
+ publicKey,
69
+ fingerprint,
70
+ type,
71
+ name,
72
+ createdAt: (/* @__PURE__ */ new Date()).toISOString()
73
+ },
74
+ privateKey
75
+ };
76
+ }
77
+ function deriveWallet(privateKey, identityDid) {
78
+ validateHex64(privateKey, "privateKey");
79
+ if (typeof identityDid !== "string" || !identityDid.startsWith("did:epochcore:")) {
80
+ throw new TypeError('identityDid must start with "did:epochcore:"');
81
+ }
82
+ const seedBytes = sha256(hexToBytes(privateKey));
83
+ const walletPrivKey = secp256k1.utils.normPrivateKeyToScalar(seedBytes);
84
+ if (walletPrivKey <= 0n || walletPrivKey >= SECP256K1_ORDER) {
85
+ throw new RangeError("Derived wallet private key scalar is out of valid secp256k1 range [1, n-1]");
86
+ }
87
+ const walletPubKey = secp256k1.getPublicKey(walletPrivKey, false);
88
+ const pubKeyHash = sha256(walletPubKey.slice(1));
89
+ const address = "0x" + bytesToHex(pubKeyHash).slice(-40);
90
+ return {
91
+ address,
92
+ publicKey: bytesToHex(walletPubKey),
93
+ identityDid
94
+ };
95
+ }
96
+ async function signPayload(payload, privateKey) {
97
+ if (typeof payload !== "string" || payload.length === 0) {
98
+ throw new TypeError("payload must be a non-empty string");
99
+ }
100
+ const payloadBytes = new TextEncoder().encode(payload);
101
+ if (payloadBytes.byteLength > MAX_PAYLOAD_BYTES) {
102
+ throw new RangeError(`payload exceeds maximum size of ${MAX_PAYLOAD_BYTES} bytes`);
103
+ }
104
+ validateHex64(privateKey, "privateKey");
105
+ const signature = await ed25519.signAsync(payloadBytes, hexToBytes(privateKey));
106
+ const publicKey = await ed25519.getPublicKeyAsync(hexToBytes(privateKey));
107
+ return {
108
+ payload,
109
+ signature: bytesToHex(signature),
110
+ publicKey: bytesToHex(publicKey),
111
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
112
+ };
113
+ }
114
+ async function verifySignature(payload, signature, publicKey) {
115
+ if (typeof payload !== "string" || payload.length === 0) {
116
+ throw new TypeError("payload must be a non-empty string");
117
+ }
118
+ if (typeof signature !== "string" || !/^[0-9a-f]{128}$/i.test(signature)) {
119
+ throw new TypeError("signature must be a 128-character hex string");
120
+ }
121
+ validateHex64(publicKey, "publicKey");
122
+ const message = new TextEncoder().encode(payload);
123
+ return ed25519.verifyAsync(
124
+ hexToBytes(signature),
125
+ message,
126
+ hexToBytes(publicKey)
127
+ );
128
+ }
129
+ function parseDID(did) {
130
+ if (typeof did !== "string" || did.length > MAX_DID_LENGTH) {
131
+ return null;
132
+ }
133
+ const parts = did.split(":");
134
+ if (parts.length !== 5 || parts[0] !== "did" || parts[1] !== "epochcore") {
135
+ return null;
136
+ }
137
+ if (!CONSTANTS.SUPPORTED_TYPES.includes(parts[2])) {
138
+ return null;
139
+ }
140
+ return {
141
+ method: parts[1],
142
+ type: parts[2],
143
+ name: parts[3],
144
+ fingerprint: parts[4]
145
+ };
146
+ }
147
+ function generateJWKS(publicKeys) {
148
+ if (!Array.isArray(publicKeys)) {
149
+ throw new TypeError("publicKeys must be an array");
150
+ }
151
+ for (let i = 0; i < publicKeys.length; i++) {
152
+ validateHex64(publicKeys[i], `publicKeys[${i}]`);
153
+ }
154
+ return {
155
+ keys: publicKeys.map((pk, i) => ({
156
+ kty: "OKP",
157
+ crv: "Ed25519",
158
+ x: toBase64Url(hexToBytes(pk)),
159
+ use: "sig",
160
+ kid: `epochcore-${i + 1}`
161
+ }))
162
+ };
163
+ }
164
+ var CONSTANTS = {
165
+ DID_PREFIX: "did:epochcore",
166
+ SIGNING_ALGORITHM: "Ed25519",
167
+ WALLET_ALGORITHM: "secp256k1",
168
+ SUPPORTED_TYPES: ["worker", "database", "storage", "durable_object", "daemon"],
169
+ VERSION: "1.1.0"
170
+ };
171
+ var index_default = {
172
+ generateKeypair,
173
+ generateIdentity,
174
+ createDID,
175
+ parseDID,
176
+ deriveWallet,
177
+ signPayload,
178
+ verifySignature,
179
+ generateJWKS,
180
+ CONSTANTS
181
+ };
182
+ export {
183
+ CONSTANTS,
184
+ createDID,
185
+ index_default as default,
186
+ deriveWallet,
187
+ generateIdentity,
188
+ generateJWKS,
189
+ generateKeypair,
190
+ parseDID,
191
+ signPayload,
192
+ verifySignature
193
+ };
package/package.json CHANGED
@@ -1,12 +1,20 @@
1
1
  {
2
2
  "name": "@epochcore/identity-sdk",
3
- "version": "1.0.0",
3
+ "version": "1.1.0",
4
4
  "description": "World's First Universal Infrastructure Identity SDK - Ed25519 cryptographic identities for workers, databases, storage, and daemons",
5
5
  "main": "dist/index.js",
6
+ "module": "dist/index.mjs",
6
7
  "types": "dist/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "types": "./dist/index.d.ts",
11
+ "import": "./dist/index.mjs",
12
+ "require": "./dist/index.js"
13
+ }
14
+ },
7
15
  "scripts": {
8
- "build": "tsc",
9
- "test": "vitest",
16
+ "build": "tsup src/index.ts --format cjs,esm --dts --clean --external @noble/ed25519 --external @noble/secp256k1 --external @noble/hashes",
17
+ "test": "vitest run",
10
18
  "prepublishOnly": "npm run build"
11
19
  },
12
20
  "keywords": [
@@ -33,6 +41,7 @@
33
41
  "@noble/hashes": "^1.3.0"
34
42
  },
35
43
  "devDependencies": {
44
+ "tsup": "^8.0.0",
36
45
  "typescript": "^5.3.0",
37
46
  "vitest": "^1.0.0"
38
47
  },
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAOH,MAAM,MAAM,YAAY,GAAG,QAAQ,GAAG,UAAU,GAAG,SAAS,GAAG,gBAAgB,GAAG,QAAQ,CAAC;AAE3F,MAAM,WAAW,iBAAiB;IAChC,GAAG,EAAE,MAAM,CAAC;IACZ,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,YAAY,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;GAEG;AACH,wBAAsB,eAAe,IAAI,OAAO,CAAC;IAC/C,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC,CAQD;AAED;;;GAGG;AACH,wBAAgB,SAAS,CACvB,IAAI,EAAE,YAAY,EAClB,IAAI,EAAE,MAAM,EACZ,SAAS,EAAE,MAAM,GAChB,MAAM,CAGR;AAED;;GAEG;AACH,wBAAsB,gBAAgB,CACpC,IAAI,EAAE,YAAY,EAClB,IAAI,EAAE,MAAM,GACX,OAAO,CAAC;IACT,QAAQ,EAAE,iBAAiB,CAAC;IAC5B,UAAU,EAAE,MAAM,CAAC;CACpB,CAAC,CAgBD;AAED;;GAEG;AACH,wBAAgB,YAAY,CAC1B,UAAU,EAAE,MAAM,EAClB,WAAW,EAAE,MAAM,GAClB,eAAe,CAcjB;AAED;;GAEG;AACH,wBAAsB,WAAW,CAC/B,OAAO,EAAE,MAAM,EACf,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,aAAa,CAAC,CAWxB;AAED;;GAEG;AACH,wBAAsB,eAAe,CACnC,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,OAAO,CAAC,CAOlB;AAED;;GAEG;AACH,wBAAgB,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG;IACrC,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,YAAY,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;CACrB,GAAG,IAAI,CAYP;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,UAAU,EAAE,MAAM,EAAE,GAAG;IAClD,IAAI,EAAE,KAAK,CAAC;QACV,GAAG,EAAE,MAAM,CAAC;QACZ,GAAG,EAAE,MAAM,CAAC;QACZ,CAAC,EAAE,MAAM,CAAC;QACV,GAAG,EAAE,MAAM,CAAC;QACZ,GAAG,EAAE,MAAM,CAAC;KACb,CAAC,CAAC;CACJ,CAUA;AAGD,eAAO,MAAM,SAAS;;;;qBAI8D,YAAY,EAAE;;CAEjG,CAAC;;;;;;;;;;;;;;yBAFkF,YAAY,EAAE;;;;AAIlG,wBAUE"}