@fide.work/fcp 0.0.1-alpha.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.
Files changed (78) hide show
  1. package/README.md +18 -0
  2. package/dist/attestation/create.d.ts +173 -0
  3. package/dist/attestation/create.js +179 -0
  4. package/dist/attestation/index.d.ts +7 -0
  5. package/dist/attestation/index.js +7 -0
  6. package/dist/attestation/verify.d.ts +56 -0
  7. package/dist/attestation/verify.js +94 -0
  8. package/dist/broadcasting/config.d.ts +27 -0
  9. package/dist/broadcasting/config.js +22 -0
  10. package/dist/broadcasting/index.d.ts +7 -0
  11. package/dist/broadcasting/index.js +7 -0
  12. package/dist/broadcasting/registry.d.ts +111 -0
  13. package/dist/broadcasting/registry.js +99 -0
  14. package/dist/experimental/attestation/create.d.ts +173 -0
  15. package/dist/experimental/attestation/create.js +188 -0
  16. package/dist/experimental/attestation/index.d.ts +7 -0
  17. package/dist/experimental/attestation/index.js +7 -0
  18. package/dist/experimental/attestation/verify.d.ts +56 -0
  19. package/dist/experimental/attestation/verify.js +94 -0
  20. package/dist/experimental/broadcasting/config.d.ts +27 -0
  21. package/dist/experimental/broadcasting/config.js +22 -0
  22. package/dist/experimental/broadcasting/index.d.ts +7 -0
  23. package/dist/experimental/broadcasting/index.js +7 -0
  24. package/dist/experimental/broadcasting/registry.d.ts +111 -0
  25. package/dist/experimental/broadcasting/registry.js +99 -0
  26. package/dist/experimental/index.d.ts +9 -0
  27. package/dist/experimental/index.js +13 -0
  28. package/dist/experimental/merkle/index.d.ts +6 -0
  29. package/dist/experimental/merkle/index.js +6 -0
  30. package/dist/experimental/merkle/tree.d.ts +72 -0
  31. package/dist/experimental/merkle/tree.js +154 -0
  32. package/dist/experimental/signing/ed25519.d.ts +116 -0
  33. package/dist/experimental/signing/ed25519.js +161 -0
  34. package/dist/experimental/signing/eip191.d.ts +50 -0
  35. package/dist/experimental/signing/eip191.js +96 -0
  36. package/dist/experimental/signing/eip712.d.ts +112 -0
  37. package/dist/experimental/signing/eip712.js +187 -0
  38. package/dist/experimental/signing/index.d.ts +8 -0
  39. package/dist/experimental/signing/index.js +11 -0
  40. package/dist/fide-id/calculateFideId.d.ts +21 -0
  41. package/dist/fide-id/calculateFideId.js +53 -0
  42. package/dist/fide-id/calculateStatementFideId.d.ts +21 -0
  43. package/dist/fide-id/calculateStatementFideId.js +38 -0
  44. package/dist/fide-id/constants.d.ts +43 -0
  45. package/dist/fide-id/constants.js +55 -0
  46. package/dist/fide-id/index.d.ts +10 -0
  47. package/dist/fide-id/index.js +12 -0
  48. package/dist/fide-id/types.d.ts +52 -0
  49. package/dist/fide-id/types.js +5 -0
  50. package/dist/fide-id/utils.d.ts +30 -0
  51. package/dist/fide-id/utils.js +65 -0
  52. package/dist/index.d.ts +11 -0
  53. package/dist/index.js +19 -0
  54. package/dist/merkle/index.d.ts +6 -0
  55. package/dist/merkle/index.js +6 -0
  56. package/dist/merkle/tree.d.ts +72 -0
  57. package/dist/merkle/tree.js +154 -0
  58. package/dist/schema/evaluations.d.ts +31 -0
  59. package/dist/schema/evaluations.js +31 -0
  60. package/dist/schema/index.d.ts +6 -0
  61. package/dist/schema/index.js +6 -0
  62. package/dist/schema/predicates.d.ts +110 -0
  63. package/dist/schema/predicates.js +122 -0
  64. package/dist/signing/ed25519.d.ts +116 -0
  65. package/dist/signing/ed25519.js +161 -0
  66. package/dist/signing/eip191.d.ts +50 -0
  67. package/dist/signing/eip191.js +96 -0
  68. package/dist/signing/eip712.d.ts +112 -0
  69. package/dist/signing/eip712.js +187 -0
  70. package/dist/signing/index.d.ts +8 -0
  71. package/dist/signing/index.js +11 -0
  72. package/dist/statement/build.d.ts +99 -0
  73. package/dist/statement/build.js +71 -0
  74. package/dist/statement/index.d.ts +6 -0
  75. package/dist/statement/index.js +6 -0
  76. package/dist/statement/policy.d.ts +33 -0
  77. package/dist/statement/policy.js +183 -0
  78. package/package.json +64 -0
@@ -0,0 +1,161 @@
1
+ /**
2
+ * FCP SDK Signing Utilities
3
+ * Ed25519 key generation and signing using native Web Crypto API
4
+ */
5
+ /**
6
+ * Get the Web Crypto API (works in browsers and Node.js)
7
+ */
8
+ async function getWebCrypto() {
9
+ if (globalThis.crypto) {
10
+ return globalThis.crypto;
11
+ }
12
+ // Node.js fallback
13
+ const { webcrypto } = await import("node:crypto");
14
+ return webcrypto;
15
+ }
16
+ /**
17
+ * Generate a new Ed25519 key pair for signing
18
+ *
19
+ * Uses native Web Crypto API - no external dependencies required.
20
+ *
21
+ * @returns Promise resolving to a CryptoKey pair
22
+ *
23
+ * @remarks
24
+ * This is a zero-dependency function that works in both Node.js and browsers.
25
+ * The generated key pair can be exported as hex strings using {@link exportEd25519Keys}.
26
+ *
27
+ * @example
28
+ * ```ts
29
+ * const keyPair = await generateEd25519KeyPair();
30
+ * const exported = await exportEd25519Keys(keyPair);
31
+ * console.log('Address:', exported.address);
32
+ * ```
33
+ */
34
+ export async function generateEd25519KeyPair() {
35
+ const crypto = await getWebCrypto();
36
+ const keyPair = await crypto.subtle.generateKey({
37
+ name: "Ed25519",
38
+ }, true, // extractable
39
+ ["sign", "verify"]);
40
+ return {
41
+ publicKey: keyPair.publicKey,
42
+ privateKey: keyPair.privateKey
43
+ };
44
+ }
45
+ /**
46
+ * Export Ed25519 keys as hex strings
47
+ *
48
+ * @param keyPair - The Ed25519 key pair (JWK format)
49
+ * @returns Exported keys with public key, private key, and derived address
50
+ *
51
+ * @remarks
52
+ * Keys are exported in standard formats:
53
+ * - Public key: SubjectPublicKeyInfo (SPKI) format as hex
54
+ * - Private key: PKCS8 format as hex
55
+ * - Address: Derived from the raw public key bytes (last 32 bytes of SPKI key)
56
+ *
57
+ * @example
58
+ * ```ts
59
+ * const keyPair = await generateEd25519KeyPair();
60
+ * const { publicKeyHex, privateKeyHex, address } = await exportEd25519Keys(keyPair);
61
+ * ```
62
+ */
63
+ export async function exportEd25519Keys(keyPair) {
64
+ const crypto = await getWebCrypto();
65
+ // Export public key (SubjectPublicKeyInfo format)
66
+ const publicKeyBuffer = await crypto.subtle.exportKey("spki", keyPair.publicKey);
67
+ const publicKeyHex = Buffer.from(publicKeyBuffer).toString("hex");
68
+ // Export private key (PKCS8 format)
69
+ const privateKeyBuffer = await crypto.subtle.exportKey("pkcs8", keyPair.privateKey);
70
+ const privateKeyHex = Buffer.from(privateKeyBuffer).toString("hex");
71
+ // Derive address from public key (last 32 bytes of public key in hex)
72
+ // Ed25519 public keys are 32 bytes, but SPKI format adds metadata
73
+ const publicKeyBytes = new Uint8Array(publicKeyBuffer);
74
+ const rawPublicKey = publicKeyBytes.slice(-32); // Last 32 bytes are the actual key
75
+ const address = Buffer.from(rawPublicKey).toString("hex");
76
+ return {
77
+ publicKeyHex,
78
+ privateKeyHex,
79
+ address
80
+ };
81
+ }
82
+ /**
83
+ * Import Ed25519 keys from hex strings
84
+ *
85
+ * @param publicKeyHex - Public key in hex format (SPKI)
86
+ * @param privateKeyHex - Private key in hex format (PKCS8)
87
+ * @returns Imported CryptoKey pair
88
+ *
89
+ * @remarks
90
+ * Keys must be in standard formats:
91
+ * - Public key: SubjectPublicKeyInfo (SPKI) format as hex
92
+ * - Private key: PKCS8 format as hex
93
+ *
94
+ * Use this to restore keys previously exported with {@link exportEd25519Keys}.
95
+ *
96
+ * @example
97
+ * ```ts
98
+ * const keyPair = await importEd25519Keys(publicKeyHex, privateKeyHex);
99
+ * ```
100
+ */
101
+ export async function importEd25519Keys(publicKeyHex, privateKeyHex) {
102
+ const crypto = await getWebCrypto();
103
+ const publicKeyBuffer = Buffer.from(publicKeyHex, "hex");
104
+ const privateKeyBuffer = Buffer.from(privateKeyHex, "hex");
105
+ const publicKey = await crypto.subtle.importKey("spki", publicKeyBuffer, {
106
+ name: "Ed25519",
107
+ }, true, ["verify"]);
108
+ const privateKey = await crypto.subtle.importKey("pkcs8", privateKeyBuffer, {
109
+ name: "Ed25519",
110
+ }, true, ["sign"]);
111
+ return { publicKey, privateKey };
112
+ }
113
+ /**
114
+ * Sign data using Ed25519 private key
115
+ *
116
+ * @param data - The data/message to sign or verify (hex string for EIP standards, plaintext for EIP-191)
117
+ * @param privateKey - The Ed25519 key pair (JWK format)
118
+ * @returns Hex-encoded signature
119
+ *
120
+ * @remarks
121
+ * This function:
122
+ * - UTF-8 encodes the input data
123
+ * - Signs using the Ed25519 algorithm
124
+ * - Returns the signature as a hex string
125
+ *
126
+ * @example
127
+ * ```ts
128
+ * const signature = await signEd25519("Hello, world!", keyPair.privateKey);
129
+ * ```
130
+ */
131
+ export async function signEd25519(data, privateKey) {
132
+ const crypto = await getWebCrypto();
133
+ const encoder = new TextEncoder();
134
+ const signature = await crypto.subtle.sign("Ed25519", privateKey, encoder.encode(data));
135
+ return Buffer.from(signature).toString("hex");
136
+ }
137
+ /**
138
+ * Verify an Ed25519 signature
139
+ *
140
+ * @param data - The data/message to sign or verify (hex string for EIP standards, plaintext for EIP-191)
141
+ * @param signatureHex - The cryptographic signature (0x-prefixed hex string)
142
+ * @param publicKey - The Ed25519 key pair (JWK format)
143
+ * @returns True if signature is valid
144
+ *
145
+ * @remarks
146
+ * This function:
147
+ * - UTF-8 encodes the input data
148
+ * - Verifies the hex-encoded signature using the Ed25519 algorithm
149
+ * - Returns true only if the signature is cryptographically valid
150
+ *
151
+ * @example
152
+ * ```ts
153
+ * const isValid = await verifyEd25519("Hello, world!", signature, keyPair.publicKey);
154
+ * ```
155
+ */
156
+ export async function verifyEd25519(data, signatureHex, publicKey) {
157
+ const crypto = await getWebCrypto();
158
+ const encoder = new TextEncoder();
159
+ const signature = Buffer.from(signatureHex, "hex");
160
+ return await crypto.subtle.verify("Ed25519", publicKey, signature, encoder.encode(data));
161
+ }
@@ -0,0 +1,50 @@
1
+ /**
2
+ * FCP SDK EIP-191 Signing Utilities
3
+ * Ethereum-compatible signing using EIP-191 Personal Sign (requires viem peer dependency)
4
+ */
5
+ /**
6
+ * Sign data using EIP-191 Personal Sign
7
+ *
8
+ * Requires viem to be installed as a peer dependency.
9
+ *
10
+ * @param data - The data/message to sign or verify (hex string for EIP standards, plaintext for EIP-191)
11
+ * @param privateKey - The private key for signing (0x-prefixed hex)
12
+ * @returns Hex-encoded signature
13
+ * @throws Error if viem is not installed
14
+ *
15
+ * @remarks
16
+ * This function implements EIP-191 Personal Sign, which:
17
+ * - Prefixes the data with the Ethereum signed message header
18
+ * - Hashes the prefixed data with Keccak256
19
+ * - Signs using the Ethereum private key
20
+ *
21
+ * Commonly used for Ethereum wallet signatures.
22
+ *
23
+ * @example
24
+ * ```ts
25
+ * const signature = await signEip191(merkleRoot, privateKey);
26
+ * ```
27
+ */
28
+ export declare function signEip191(data: string, privateKey: `0x${string}`): Promise<`0x${string}`>;
29
+ /**
30
+ * Verify an EIP-191 signature
31
+ *
32
+ * Requires viem to be installed as a peer dependency.
33
+ *
34
+ * @param data - The data/message to sign or verify (hex string for EIP standards, plaintext for EIP-191)
35
+ * @param signature - The cryptographic signature (0x-prefixed hex string)
36
+ * @param address - The signer's Ethereum address (0x-prefixed hex)
37
+ * @returns True if signature is valid
38
+ * @throws Error if viem is not installed
39
+ *
40
+ * @remarks
41
+ * This function verifies an EIP-191 Personal Sign signature by:
42
+ * - Reconstructing the signed message with the Ethereum header
43
+ * - Checking that the signature matches the expected signer address
44
+ *
45
+ * @example
46
+ * ```ts
47
+ * const isValid = await verifyEip191(merkleRoot, signature, address);
48
+ * ```
49
+ */
50
+ export declare function verifyEip191(data: string, signature: `0x${string}`, address: `0x${string}`): Promise<boolean>;
@@ -0,0 +1,96 @@
1
+ /**
2
+ * FCP SDK EIP-191 Signing Utilities
3
+ * Ethereum-compatible signing using EIP-191 Personal Sign (requires viem peer dependency)
4
+ */
5
+ /**
6
+ * Detect which package manager is being used
7
+ */
8
+ function detectPackageManager() {
9
+ const userAgent = process.env.npm_config_user_agent || '';
10
+ if (userAgent.includes('pnpm'))
11
+ return 'pnpm add viem';
12
+ if (userAgent.includes('yarn'))
13
+ return 'yarn add viem';
14
+ if (userAgent.includes('bun'))
15
+ return 'bun add viem';
16
+ if (userAgent.includes('npm'))
17
+ return 'npm install viem';
18
+ return 'npm install viem';
19
+ }
20
+ /**
21
+ * Check if viem is installed
22
+ */
23
+ async function checkViemInstalled() {
24
+ try {
25
+ await import('viem');
26
+ }
27
+ catch (error) {
28
+ const installCommand = detectPackageManager();
29
+ throw new Error('EIP-191 signing requires viem to be installed.\n\n' +
30
+ `Install it with: ${installCommand}\n\n` +
31
+ 'Or use the zero-dependency Ed25519 signing instead:\n' +
32
+ ' import { generateEd25519KeyPair, signEd25519 } from \'@fide.work/fcp\'');
33
+ }
34
+ }
35
+ /**
36
+ * Sign data using EIP-191 Personal Sign
37
+ *
38
+ * Requires viem to be installed as a peer dependency.
39
+ *
40
+ * @param data - The data/message to sign or verify (hex string for EIP standards, plaintext for EIP-191)
41
+ * @param privateKey - The private key for signing (0x-prefixed hex)
42
+ * @returns Hex-encoded signature
43
+ * @throws Error if viem is not installed
44
+ *
45
+ * @remarks
46
+ * This function implements EIP-191 Personal Sign, which:
47
+ * - Prefixes the data with the Ethereum signed message header
48
+ * - Hashes the prefixed data with Keccak256
49
+ * - Signs using the Ethereum private key
50
+ *
51
+ * Commonly used for Ethereum wallet signatures.
52
+ *
53
+ * @example
54
+ * ```ts
55
+ * const signature = await signEip191(merkleRoot, privateKey);
56
+ * ```
57
+ */
58
+ export async function signEip191(data, privateKey) {
59
+ await checkViemInstalled();
60
+ const { privateKeyToAccount } = await import('viem/accounts');
61
+ const account = privateKeyToAccount(privateKey);
62
+ const signature = await account.signMessage({
63
+ message: data
64
+ });
65
+ return signature;
66
+ }
67
+ /**
68
+ * Verify an EIP-191 signature
69
+ *
70
+ * Requires viem to be installed as a peer dependency.
71
+ *
72
+ * @param data - The data/message to sign or verify (hex string for EIP standards, plaintext for EIP-191)
73
+ * @param signature - The cryptographic signature (0x-prefixed hex string)
74
+ * @param address - The signer's Ethereum address (0x-prefixed hex)
75
+ * @returns True if signature is valid
76
+ * @throws Error if viem is not installed
77
+ *
78
+ * @remarks
79
+ * This function verifies an EIP-191 Personal Sign signature by:
80
+ * - Reconstructing the signed message with the Ethereum header
81
+ * - Checking that the signature matches the expected signer address
82
+ *
83
+ * @example
84
+ * ```ts
85
+ * const isValid = await verifyEip191(merkleRoot, signature, address);
86
+ * ```
87
+ */
88
+ export async function verifyEip191(data, signature, address) {
89
+ await checkViemInstalled();
90
+ const { verifyMessage } = await import('viem');
91
+ return await verifyMessage({
92
+ address,
93
+ message: data,
94
+ signature
95
+ });
96
+ }
@@ -0,0 +1,112 @@
1
+ /**
2
+ * FCP SDK EIP-712 Signing Utilities
3
+ * Ethereum-compatible signing using viem (optional peer dependency)
4
+ */
5
+ /**
6
+ * EIP-712 Domain for Fide Context Protocol
7
+ */
8
+ export interface Eip712Domain {
9
+ name: string;
10
+ version: string;
11
+ chainId: number;
12
+ verifyingContract: `0x${string}`;
13
+ }
14
+ /**
15
+ * Default FCP EIP-712 Domain
16
+ */
17
+ export declare const FCP_EIP712_DOMAIN: Eip712Domain;
18
+ /**
19
+ * Get Ethereum address from private key
20
+ *
21
+ * Requires viem to be installed as a peer dependency.
22
+ *
23
+ * @param privateKey - The private key for signing (0x-prefixed hex)
24
+ * @returns Ethereum address
25
+ * @throws Error if viem is not installed
26
+ *
27
+ * @remarks
28
+ * Derives the Ethereum address from the private key using:
29
+ * - ECDSA public key derivation
30
+ * - Keccak256 hashing
31
+ * - Last 20 bytes as the address
32
+ *
33
+ * @example
34
+ * ```ts
35
+ * const address = await getEthereumAddress(privateKey);
36
+ * // Result: "0x742d35Cc6634C0532925a3b844Bc9e7595f42e"
37
+ * ```
38
+ */
39
+ export declare function getEthereumAddress(privateKey: `0x${string}`): Promise<`0x${string}`>;
40
+ /**
41
+ * Sign data using EIP-712 typed data signing
42
+ *
43
+ * Requires viem to be installed as a peer dependency.
44
+ *
45
+ * @param data - The data/message to sign or verify (hex string for EIP standards, plaintext for EIP-191)
46
+ * @param privateKey - The private key for signing (0x-prefixed hex)
47
+ * @param domain - EIP-712 domain (defaults to FCP domain)
48
+ * @returns Hex-encoded signature
49
+ * @throws Error if viem is not installed
50
+ *
51
+ * @remarks
52
+ * This function signs data using EIP-712 typed data signing:
53
+ * - Structures the message in FideAttestation format
54
+ * - Uses the provided domain (or defaults to FCP_EIP712_DOMAIN)
55
+ * - Returns an ECDSA signature over the structured hash
56
+ *
57
+ * Supports custom domains for integration with different smart contracts.
58
+ *
59
+ * @example
60
+ * ```ts
61
+ * const signature = await signEip712(merkleRoot, privateKey);
62
+ * ```
63
+ */
64
+ export declare function signEip712(data: string, privateKey: `0x${string}`, domain?: Eip712Domain): Promise<`0x${string}`>;
65
+ /**
66
+ * Verify an EIP-712 signature
67
+ *
68
+ * Requires viem to be installed as a peer dependency.
69
+ *
70
+ * @param data - The data/message to sign or verify (hex string for EIP standards, plaintext for EIP-191)
71
+ * @param signature - The cryptographic signature (0x-prefixed hex string)
72
+ * @param address - The signer's Ethereum address (0x-prefixed hex)
73
+ * @param domain - EIP-712 domain (defaults to FCP domain)
74
+ * @returns True if signature is valid
75
+ * @throws Error if viem is not installed
76
+ *
77
+ * @remarks
78
+ * This function verifies an EIP-712 typed data signature by:
79
+ * - Reconstructing the FideAttestation message structure
80
+ * - Using the provided domain (or defaults to FCP_EIP712_DOMAIN)
81
+ * - Verifying the ECDSA signature against the expected signer address
82
+ *
83
+ * @example
84
+ * ```ts
85
+ * const isValid = await verifyEip712(merkleRoot, signature, address);
86
+ * ```
87
+ */
88
+ export declare function verifyEip712(data: string, signature: `0x${string}`, address: `0x${string}`, domain?: Eip712Domain): Promise<boolean>;
89
+ /**
90
+ * Create a CAIP-10 identifier for an Ethereum address
91
+ *
92
+ * @param address - The signer's Ethereum address (0x-prefixed hex)
93
+ * @param chainId - Chain ID (defaults to 1 for mainnet)
94
+ * @returns CAIP-10 identifier (e.g., "eip155:1:0x...")
95
+ *
96
+ * @remarks
97
+ * CAIP-10 (Chain Agnostic Improvement Proposal 10) is a standard format for
98
+ * representing blockchain addresses across different chains. This function creates
99
+ * identifiers in the format: `eip155:{chainId}:{address}`
100
+ *
101
+ * Common chainIds:
102
+ * - 1: Ethereum Mainnet
103
+ * - 5: Goerli Testnet
104
+ * - 11155111: Sepolia Testnet
105
+ *
106
+ * @example
107
+ * ```ts
108
+ * const caip10 = createEthereumCaip10(address, 1);
109
+ * // Result: "eip155:1:0x742d35cc6634c0532925a3b844bc9e7595f42e"
110
+ * ```
111
+ */
112
+ export declare function createEthereumCaip10(address: `0x${string}`, chainId?: number): string;
@@ -0,0 +1,187 @@
1
+ /**
2
+ * FCP SDK EIP-712 Signing Utilities
3
+ * Ethereum-compatible signing using viem (optional peer dependency)
4
+ */
5
+ /**
6
+ * Default FCP EIP-712 Domain
7
+ */
8
+ export const FCP_EIP712_DOMAIN = {
9
+ name: 'Fide Context Protocol',
10
+ version: '1',
11
+ chainId: 1, // Mainnet (should be configured per chain)
12
+ verifyingContract: '0x0000000000000000000000000000000000000000'
13
+ };
14
+ /**
15
+ * Detect which package manager is being used
16
+ */
17
+ function detectPackageManager() {
18
+ // Check for package manager environment variables
19
+ const userAgent = process.env.npm_config_user_agent || '';
20
+ if (userAgent.includes('pnpm'))
21
+ return 'pnpm add viem';
22
+ if (userAgent.includes('yarn'))
23
+ return 'yarn add viem';
24
+ if (userAgent.includes('bun'))
25
+ return 'bun add viem';
26
+ if (userAgent.includes('npm'))
27
+ return 'npm install viem';
28
+ // Default to npm if we can't detect
29
+ return 'npm install viem';
30
+ }
31
+ /**
32
+ * Check if viem is installed
33
+ */
34
+ async function checkViemInstalled() {
35
+ try {
36
+ await import('viem');
37
+ }
38
+ catch (error) {
39
+ const installCommand = detectPackageManager();
40
+ throw new Error('EIP-712 signing requires viem to be installed.\n\n' +
41
+ `Install it with: ${installCommand}\n\n` +
42
+ 'Or use the zero-dependency Ed25519 signing instead:\n' +
43
+ ' import { generateEd25519KeyPair, signEd25519 } from \'@fide.work/fcp\'');
44
+ }
45
+ }
46
+ /**
47
+ * Get Ethereum address from private key
48
+ *
49
+ * Requires viem to be installed as a peer dependency.
50
+ *
51
+ * @param privateKey - The private key for signing (0x-prefixed hex)
52
+ * @returns Ethereum address
53
+ * @throws Error if viem is not installed
54
+ *
55
+ * @remarks
56
+ * Derives the Ethereum address from the private key using:
57
+ * - ECDSA public key derivation
58
+ * - Keccak256 hashing
59
+ * - Last 20 bytes as the address
60
+ *
61
+ * @example
62
+ * ```ts
63
+ * const address = await getEthereumAddress(privateKey);
64
+ * // Result: "0x742d35Cc6634C0532925a3b844Bc9e7595f42e"
65
+ * ```
66
+ */
67
+ export async function getEthereumAddress(privateKey) {
68
+ await checkViemInstalled();
69
+ const { privateKeyToAddress } = await import('viem/accounts');
70
+ return privateKeyToAddress(privateKey);
71
+ }
72
+ /**
73
+ * Sign data using EIP-712 typed data signing
74
+ *
75
+ * Requires viem to be installed as a peer dependency.
76
+ *
77
+ * @param data - The data/message to sign or verify (hex string for EIP standards, plaintext for EIP-191)
78
+ * @param privateKey - The private key for signing (0x-prefixed hex)
79
+ * @param domain - EIP-712 domain (defaults to FCP domain)
80
+ * @returns Hex-encoded signature
81
+ * @throws Error if viem is not installed
82
+ *
83
+ * @remarks
84
+ * This function signs data using EIP-712 typed data signing:
85
+ * - Structures the message in FideAttestation format
86
+ * - Uses the provided domain (or defaults to FCP_EIP712_DOMAIN)
87
+ * - Returns an ECDSA signature over the structured hash
88
+ *
89
+ * Supports custom domains for integration with different smart contracts.
90
+ *
91
+ * @example
92
+ * ```ts
93
+ * const signature = await signEip712(merkleRoot, privateKey);
94
+ * ```
95
+ */
96
+ export async function signEip712(data, privateKey, domain = FCP_EIP712_DOMAIN) {
97
+ await checkViemInstalled();
98
+ const { privateKeyToAccount } = await import('viem/accounts');
99
+ const { hashTypedData, keccak256, toHex } = await import('viem');
100
+ const account = privateKeyToAccount(privateKey);
101
+ // Define the EIP-712 typed data structure
102
+ const types = {
103
+ FideAttestation: [
104
+ { name: 'data', type: 'string' }
105
+ ]
106
+ };
107
+ const message = {
108
+ data
109
+ };
110
+ // Sign using EIP-712
111
+ const signature = await account.signTypedData({
112
+ domain,
113
+ types,
114
+ primaryType: 'FideAttestation',
115
+ message
116
+ });
117
+ return signature;
118
+ }
119
+ /**
120
+ * Verify an EIP-712 signature
121
+ *
122
+ * Requires viem to be installed as a peer dependency.
123
+ *
124
+ * @param data - The data/message to sign or verify (hex string for EIP standards, plaintext for EIP-191)
125
+ * @param signature - The cryptographic signature (0x-prefixed hex string)
126
+ * @param address - The signer's Ethereum address (0x-prefixed hex)
127
+ * @param domain - EIP-712 domain (defaults to FCP domain)
128
+ * @returns True if signature is valid
129
+ * @throws Error if viem is not installed
130
+ *
131
+ * @remarks
132
+ * This function verifies an EIP-712 typed data signature by:
133
+ * - Reconstructing the FideAttestation message structure
134
+ * - Using the provided domain (or defaults to FCP_EIP712_DOMAIN)
135
+ * - Verifying the ECDSA signature against the expected signer address
136
+ *
137
+ * @example
138
+ * ```ts
139
+ * const isValid = await verifyEip712(merkleRoot, signature, address);
140
+ * ```
141
+ */
142
+ export async function verifyEip712(data, signature, address, domain = FCP_EIP712_DOMAIN) {
143
+ await checkViemInstalled();
144
+ const { verifyTypedData } = await import('viem');
145
+ const types = {
146
+ FideAttestation: [
147
+ { name: 'data', type: 'string' }
148
+ ]
149
+ };
150
+ const message = {
151
+ data
152
+ };
153
+ return await verifyTypedData({
154
+ address,
155
+ domain,
156
+ types,
157
+ primaryType: 'FideAttestation',
158
+ message,
159
+ signature
160
+ });
161
+ }
162
+ /**
163
+ * Create a CAIP-10 identifier for an Ethereum address
164
+ *
165
+ * @param address - The signer's Ethereum address (0x-prefixed hex)
166
+ * @param chainId - Chain ID (defaults to 1 for mainnet)
167
+ * @returns CAIP-10 identifier (e.g., "eip155:1:0x...")
168
+ *
169
+ * @remarks
170
+ * CAIP-10 (Chain Agnostic Improvement Proposal 10) is a standard format for
171
+ * representing blockchain addresses across different chains. This function creates
172
+ * identifiers in the format: `eip155:{chainId}:{address}`
173
+ *
174
+ * Common chainIds:
175
+ * - 1: Ethereum Mainnet
176
+ * - 5: Goerli Testnet
177
+ * - 11155111: Sepolia Testnet
178
+ *
179
+ * @example
180
+ * ```ts
181
+ * const caip10 = createEthereumCaip10(address, 1);
182
+ * // Result: "eip155:1:0x742d35cc6634c0532925a3b844bc9e7595f42e"
183
+ * ```
184
+ */
185
+ export function createEthereumCaip10(address, chainId = 1) {
186
+ return `eip155:${chainId}:${address.toLowerCase()}`;
187
+ }
@@ -0,0 +1,8 @@
1
+ /**
2
+ * FCP SDK - Signing Module
3
+ *
4
+ * Re-exports all signing utilities from submodules.
5
+ */
6
+ export { generateEd25519KeyPair, exportEd25519Keys, importEd25519Keys, signEd25519, verifyEd25519, type Ed25519KeyPair, type ExportedEd25519Keys } from "./ed25519.js";
7
+ export { getEthereumAddress, signEip712, verifyEip712, createEthereumCaip10, FCP_EIP712_DOMAIN, type Eip712Domain } from "./eip712.js";
8
+ export { signEip191, verifyEip191 } from "./eip191.js";
@@ -0,0 +1,11 @@
1
+ /**
2
+ * FCP SDK - Signing Module
3
+ *
4
+ * Re-exports all signing utilities from submodules.
5
+ */
6
+ // Ed25519 Signing (native, zero-dependency)
7
+ export { generateEd25519KeyPair, exportEd25519Keys, importEd25519Keys, signEd25519, verifyEd25519 } from "./ed25519.js";
8
+ // EIP-712 Signing (requires viem peer dependency)
9
+ export { getEthereumAddress, signEip712, verifyEip712, createEthereumCaip10, FCP_EIP712_DOMAIN } from "./eip712.js";
10
+ // EIP-191 Signing (requires viem peer dependency)
11
+ export { signEip191, verifyEip191 } from "./eip191.js";