sigild 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.
Files changed (97) hide show
  1. package/CONTRIBUTING.md +39 -0
  2. package/LICENSE +202 -0
  3. package/README.md +70 -0
  4. package/THREAT_MODEL.md +84 -0
  5. package/dist/src/audit/index.d.ts +2 -0
  6. package/dist/src/audit/index.d.ts.map +1 -0
  7. package/dist/src/audit/index.js +2 -0
  8. package/dist/src/audit/index.js.map +1 -0
  9. package/dist/src/audit/log.d.ts +96 -0
  10. package/dist/src/audit/log.d.ts.map +1 -0
  11. package/dist/src/audit/log.js +229 -0
  12. package/dist/src/audit/log.js.map +1 -0
  13. package/dist/src/bin/sigild.d.ts +3 -0
  14. package/dist/src/bin/sigild.d.ts.map +1 -0
  15. package/dist/src/bin/sigild.js +30 -0
  16. package/dist/src/bin/sigild.js.map +1 -0
  17. package/dist/src/crypto/aead.d.ts +9 -0
  18. package/dist/src/crypto/aead.d.ts.map +1 -0
  19. package/dist/src/crypto/aead.js +38 -0
  20. package/dist/src/crypto/aead.js.map +1 -0
  21. package/dist/src/crypto/index.d.ts +5 -0
  22. package/dist/src/crypto/index.d.ts.map +1 -0
  23. package/dist/src/crypto/index.js +5 -0
  24. package/dist/src/crypto/index.js.map +1 -0
  25. package/dist/src/crypto/kdf.d.ts +10 -0
  26. package/dist/src/crypto/kdf.d.ts.map +1 -0
  27. package/dist/src/crypto/kdf.js +27 -0
  28. package/dist/src/crypto/kdf.js.map +1 -0
  29. package/dist/src/crypto/keyfile.d.ts +12 -0
  30. package/dist/src/crypto/keyfile.d.ts.map +1 -0
  31. package/dist/src/crypto/keyfile.js +114 -0
  32. package/dist/src/crypto/keyfile.js.map +1 -0
  33. package/dist/src/crypto/secret-buffer.d.ts +19 -0
  34. package/dist/src/crypto/secret-buffer.d.ts.map +1 -0
  35. package/dist/src/crypto/secret-buffer.js +48 -0
  36. package/dist/src/crypto/secret-buffer.js.map +1 -0
  37. package/dist/src/daemon/handles.d.ts +51 -0
  38. package/dist/src/daemon/handles.d.ts.map +1 -0
  39. package/dist/src/daemon/handles.js +140 -0
  40. package/dist/src/daemon/handles.js.map +1 -0
  41. package/dist/src/daemon/index.d.ts +5 -0
  42. package/dist/src/daemon/index.d.ts.map +1 -0
  43. package/dist/src/daemon/index.js +5 -0
  44. package/dist/src/daemon/index.js.map +1 -0
  45. package/dist/src/daemon/methods.d.ts +20 -0
  46. package/dist/src/daemon/methods.d.ts.map +1 -0
  47. package/dist/src/daemon/methods.js +221 -0
  48. package/dist/src/daemon/methods.js.map +1 -0
  49. package/dist/src/daemon/passphrase.d.ts +14 -0
  50. package/dist/src/daemon/passphrase.d.ts.map +1 -0
  51. package/dist/src/daemon/passphrase.js +49 -0
  52. package/dist/src/daemon/passphrase.js.map +1 -0
  53. package/dist/src/daemon/rpc.d.ts +61 -0
  54. package/dist/src/daemon/rpc.d.ts.map +1 -0
  55. package/dist/src/daemon/rpc.js +76 -0
  56. package/dist/src/daemon/rpc.js.map +1 -0
  57. package/dist/src/daemon/runtime.d.ts +40 -0
  58. package/dist/src/daemon/runtime.d.ts.map +1 -0
  59. package/dist/src/daemon/runtime.js +61 -0
  60. package/dist/src/daemon/runtime.js.map +1 -0
  61. package/dist/src/daemon/server.d.ts +53 -0
  62. package/dist/src/daemon/server.d.ts.map +1 -0
  63. package/dist/src/daemon/server.js +103 -0
  64. package/dist/src/daemon/server.js.map +1 -0
  65. package/dist/src/eth/address.d.ts +13 -0
  66. package/dist/src/eth/address.d.ts.map +1 -0
  67. package/dist/src/eth/address.js +51 -0
  68. package/dist/src/eth/address.js.map +1 -0
  69. package/dist/src/eth/index.d.ts +8 -0
  70. package/dist/src/eth/index.d.ts.map +1 -0
  71. package/dist/src/eth/index.js +8 -0
  72. package/dist/src/eth/index.js.map +1 -0
  73. package/dist/src/eth/keccak.d.ts +2 -0
  74. package/dist/src/eth/keccak.d.ts.map +1 -0
  75. package/dist/src/eth/keccak.js +5 -0
  76. package/dist/src/eth/keccak.js.map +1 -0
  77. package/dist/src/eth/rlp.d.ts +16 -0
  78. package/dist/src/eth/rlp.d.ts.map +1 -0
  79. package/dist/src/eth/rlp.js +99 -0
  80. package/dist/src/eth/rlp.js.map +1 -0
  81. package/dist/src/eth/secp.d.ts +17 -0
  82. package/dist/src/eth/secp.d.ts.map +1 -0
  83. package/dist/src/eth/secp.js +43 -0
  84. package/dist/src/eth/secp.js.map +1 -0
  85. package/dist/src/eth/sign-message.d.ts +18 -0
  86. package/dist/src/eth/sign-message.d.ts.map +1 -0
  87. package/dist/src/eth/sign-message.js +42 -0
  88. package/dist/src/eth/sign-message.js.map +1 -0
  89. package/dist/src/eth/sign-tx.d.ts +38 -0
  90. package/dist/src/eth/sign-tx.d.ts.map +1 -0
  91. package/dist/src/eth/sign-tx.js +92 -0
  92. package/dist/src/eth/sign-tx.js.map +1 -0
  93. package/dist/src/eth/sign-typed.d.ts +33 -0
  94. package/dist/src/eth/sign-typed.d.ts.map +1 -0
  95. package/dist/src/eth/sign-typed.js +142 -0
  96. package/dist/src/eth/sign-typed.js.map +1 -0
  97. package/package.json +59 -0
@@ -0,0 +1,43 @@
1
+ import * as secp from '@noble/secp256k1';
2
+ import { sha256 } from '@noble/hashes/sha2.js';
3
+ import { hmac } from '@noble/hashes/hmac.js';
4
+ secp.hashes.sha256 = sha256;
5
+ secp.hashes.hmacSha256 = ((key, msg) => hmac(sha256, key, msg));
6
+ export function getPublicKeyUncompressed(privateKey) {
7
+ return Buffer.from(secp.getPublicKey(privateKey, false));
8
+ }
9
+ /**
10
+ * Signs a 32-byte digest and returns the Ethereum-shaped components.
11
+ * The noble v3 recovered format is `recovery || r || s` (recovery is byte 0).
12
+ */
13
+ export function signDigest(digest, privateKey) {
14
+ if (digest.length !== 32)
15
+ throw new Error(`digest must be 32 bytes, got ${digest.length}`);
16
+ const sigR = secp.sign(digest, privateKey, { format: 'recovered' });
17
+ const recovery = sigR[0];
18
+ if (recovery !== 0 && recovery !== 1) {
19
+ throw new Error(`unexpected recovery byte: ${recovery}`);
20
+ }
21
+ return {
22
+ recovery,
23
+ r: Buffer.from(sigR.slice(1, 33)),
24
+ s: Buffer.from(sigR.slice(33, 65)),
25
+ };
26
+ }
27
+ /**
28
+ * Recover the 65-byte uncompressed public key (with 0x04 prefix) from a digest and signature.
29
+ * Used in tests and address derivation from signature.
30
+ */
31
+ export function recoverPublicKey(digest, sig) {
32
+ if (digest.length !== 32)
33
+ throw new Error(`digest must be 32 bytes, got ${digest.length}`);
34
+ const sigR = new Uint8Array(65);
35
+ sigR[0] = sig.recovery;
36
+ sigR.set(sig.r, 1);
37
+ sigR.set(sig.s, 33);
38
+ const compressed = secp.recoverPublicKey(sigR, digest);
39
+ // recoverPublicKey returns compressed (33 bytes) — convert to uncompressed.
40
+ const point = secp.Point.fromBytes(compressed);
41
+ return Buffer.from(point.toBytes(false));
42
+ }
43
+ //# sourceMappingURL=secp.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"secp.js","sourceRoot":"","sources":["../../../src/eth/secp.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,IAAI,MAAM,kBAAkB,CAAC;AACzC,OAAO,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAC;AAC/C,OAAO,EAAE,IAAI,EAAE,MAAM,uBAAuB,CAAC;AAQ5C,IAAI,CAAC,MAAiB,CAAC,MAAM,GAAG,MAAqC,CAAC;AACtE,IAAI,CAAC,MAAiB,CAAC,UAAU,GAAG,CAAC,CAAC,GAAe,EAAE,GAAe,EAAE,EAAE,CACzE,IAAI,CAAC,MAAM,EAAE,GAAG,EAAE,GAAG,CAAC,CAAoC,CAAC;AAQ7D,MAAM,UAAU,wBAAwB,CAAC,UAA+B;IACtE,OAAO,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,UAAU,EAAE,KAAK,CAAC,CAAC,CAAC;AAC3D,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,UAAU,CAAC,MAA2B,EAAE,UAA+B;IACrF,IAAI,MAAM,CAAC,MAAM,KAAK,EAAE;QAAE,MAAM,IAAI,KAAK,CAAC,gCAAgC,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC;IAC3F,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,UAAU,EAAE,EAAE,MAAM,EAAE,WAAW,EAAE,CAAC,CAAC;IACpE,MAAM,QAAQ,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;IACzB,IAAI,QAAQ,KAAK,CAAC,IAAI,QAAQ,KAAK,CAAC,EAAE,CAAC;QACrC,MAAM,IAAI,KAAK,CAAC,6BAA6B,QAAQ,EAAE,CAAC,CAAC;IAC3D,CAAC;IACD,OAAO;QACL,QAAQ;QACR,CAAC,EAAE,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QACjC,CAAC,EAAE,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;KACnC,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,gBAAgB,CAC9B,MAA2B,EAC3B,GAAiB;IAEjB,IAAI,MAAM,CAAC,MAAM,KAAK,EAAE;QAAE,MAAM,IAAI,KAAK,CAAC,gCAAgC,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC;IAC3F,MAAM,IAAI,GAAG,IAAI,UAAU,CAAC,EAAE,CAAC,CAAC;IAChC,IAAI,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,QAAQ,CAAC;IACvB,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IACnB,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IACpB,MAAM,UAAU,GAAG,IAAI,CAAC,gBAAgB,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IACvD,4EAA4E;IAC5E,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC;IAC/C,OAAO,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC;AAC3C,CAAC"}
@@ -0,0 +1,18 @@
1
+ import { type EthSignature } from './secp.js';
2
+ /**
3
+ * EIP-191 personal_sign: keccak256("\x19Ethereum Signed Message:\n" + len + message).
4
+ *
5
+ * `message` is treated as opaque bytes. If you have a string, encode it to UTF-8 first.
6
+ */
7
+ export declare function personalSignDigest(message: Buffer | Uint8Array): Buffer;
8
+ /**
9
+ * EIP-191 personal_sign returning a 65-byte serialized sig (r || s || v) where v = recovery + 27.
10
+ */
11
+ export declare function personalSign(message: Buffer | Uint8Array, privateKey: Buffer | Uint8Array): Buffer;
12
+ /**
13
+ * Serialize an EthSignature to the 65-byte form used by personal_sign / eth_sign_typed_data:
14
+ * r (32) || s (32) || v (1, where v = recovery + 27).
15
+ */
16
+ export declare function serializeEthSignature(sig: EthSignature): Buffer;
17
+ export declare function deserializeEthSignature(bytes: Buffer | Uint8Array): EthSignature;
18
+ //# sourceMappingURL=sign-message.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sign-message.d.ts","sourceRoot":"","sources":["../../../src/eth/sign-message.ts"],"names":[],"mappings":"AACA,OAAO,EAAc,KAAK,YAAY,EAAE,MAAM,WAAW,CAAC;AAE1D;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG,UAAU,GAAG,MAAM,CAGvE;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,UAAU,EAAE,UAAU,EAAE,MAAM,GAAG,UAAU,GAAG,MAAM,CAGlG;AAED;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,YAAY,GAAG,MAAM,CAM/D;AAED,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,MAAM,GAAG,UAAU,GAAG,YAAY,CAShF"}
@@ -0,0 +1,42 @@
1
+ import { keccak256 } from './keccak.js';
2
+ import { signDigest } from './secp.js';
3
+ /**
4
+ * EIP-191 personal_sign: keccak256("\x19Ethereum Signed Message:\n" + len + message).
5
+ *
6
+ * `message` is treated as opaque bytes. If you have a string, encode it to UTF-8 first.
7
+ */
8
+ export function personalSignDigest(message) {
9
+ const prefix = Buffer.from(`\x19Ethereum Signed Message:\n${message.length}`, 'utf8');
10
+ return keccak256(Buffer.concat([prefix, Buffer.isBuffer(message) ? message : Buffer.from(message)]));
11
+ }
12
+ /**
13
+ * EIP-191 personal_sign returning a 65-byte serialized sig (r || s || v) where v = recovery + 27.
14
+ */
15
+ export function personalSign(message, privateKey) {
16
+ const digest = personalSignDigest(message);
17
+ return serializeEthSignature(signDigest(digest, privateKey));
18
+ }
19
+ /**
20
+ * Serialize an EthSignature to the 65-byte form used by personal_sign / eth_sign_typed_data:
21
+ * r (32) || s (32) || v (1, where v = recovery + 27).
22
+ */
23
+ export function serializeEthSignature(sig) {
24
+ const out = Buffer.alloc(65);
25
+ sig.r.copy(out, 0);
26
+ sig.s.copy(out, 32);
27
+ out[64] = sig.recovery + 27;
28
+ return out;
29
+ }
30
+ export function deserializeEthSignature(bytes) {
31
+ if (bytes.length !== 65)
32
+ throw new Error(`expected 65-byte signature, got ${bytes.length}`);
33
+ const v = bytes[64];
34
+ if (v !== 27 && v !== 28)
35
+ throw new Error(`expected v in {27, 28}, got ${v}`);
36
+ return {
37
+ r: Buffer.from(bytes.subarray(0, 32)),
38
+ s: Buffer.from(bytes.subarray(32, 64)),
39
+ recovery: (v - 27),
40
+ };
41
+ }
42
+ //# sourceMappingURL=sign-message.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sign-message.js","sourceRoot":"","sources":["../../../src/eth/sign-message.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,EAAE,UAAU,EAAqB,MAAM,WAAW,CAAC;AAE1D;;;;GAIG;AACH,MAAM,UAAU,kBAAkB,CAAC,OAA4B;IAC7D,MAAM,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC,iCAAiC,OAAO,CAAC,MAAM,EAAE,EAAE,MAAM,CAAC,CAAC;IACtF,OAAO,SAAS,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,MAAM,EAAE,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC;AACvG,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,YAAY,CAAC,OAA4B,EAAE,UAA+B;IACxF,MAAM,MAAM,GAAG,kBAAkB,CAAC,OAAO,CAAC,CAAC;IAC3C,OAAO,qBAAqB,CAAC,UAAU,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC,CAAC;AAC/D,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,qBAAqB,CAAC,GAAiB;IACrD,MAAM,GAAG,GAAG,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;IAC7B,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;IACnB,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;IACpB,GAAG,CAAC,EAAE,CAAC,GAAG,GAAG,CAAC,QAAQ,GAAG,EAAE,CAAC;IAC5B,OAAO,GAAG,CAAC;AACb,CAAC;AAED,MAAM,UAAU,uBAAuB,CAAC,KAA0B;IAChE,IAAI,KAAK,CAAC,MAAM,KAAK,EAAE;QAAE,MAAM,IAAI,KAAK,CAAC,mCAAmC,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC;IAC5F,MAAM,CAAC,GAAG,KAAK,CAAC,EAAE,CAAE,CAAC;IACrB,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE;QAAE,MAAM,IAAI,KAAK,CAAC,+BAA+B,CAAC,EAAE,CAAC,CAAC;IAC9E,OAAO;QACL,CAAC,EAAE,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QACrC,CAAC,EAAE,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;QACtC,QAAQ,EAAE,CAAC,CAAC,GAAG,EAAE,CAAU;KAC5B,CAAC;AACJ,CAAC"}
@@ -0,0 +1,38 @@
1
+ export type Hex = `0x${string}`;
2
+ export interface LegacyTx {
3
+ type: 'legacy';
4
+ chainId: number | bigint;
5
+ nonce: number | bigint;
6
+ gasPrice: number | bigint;
7
+ gasLimit: number | bigint;
8
+ to: Hex | null;
9
+ value: number | bigint;
10
+ data: Hex | Buffer;
11
+ }
12
+ export interface AccessListItem {
13
+ address: Hex;
14
+ storageKeys: Hex[];
15
+ }
16
+ export interface Eip1559Tx {
17
+ type: 'eip1559';
18
+ chainId: number | bigint;
19
+ nonce: number | bigint;
20
+ maxPriorityFeePerGas: number | bigint;
21
+ maxFeePerGas: number | bigint;
22
+ gasLimit: number | bigint;
23
+ to: Hex | null;
24
+ value: number | bigint;
25
+ data: Hex | Buffer;
26
+ accessList?: AccessListItem[];
27
+ }
28
+ export type SignableTx = LegacyTx | Eip1559Tx;
29
+ /**
30
+ * Returns the 32-byte keccak digest that should be signed for the given tx.
31
+ * For legacy this is the EIP-155 digest; for EIP-1559 it is the type-prefixed digest.
32
+ */
33
+ export declare function txDigest(tx: SignableTx): Buffer;
34
+ /**
35
+ * Sign a transaction and return its 0x-prefixed serialized hex.
36
+ */
37
+ export declare function signTransaction(tx: SignableTx, privateKey: Buffer | Uint8Array): Hex;
38
+ //# sourceMappingURL=sign-tx.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sign-tx.d.ts","sourceRoot":"","sources":["../../../src/eth/sign-tx.ts"],"names":[],"mappings":"AAIA,MAAM,MAAM,GAAG,GAAG,KAAK,MAAM,EAAE,CAAC;AAEhC,MAAM,WAAW,QAAQ;IACvB,IAAI,EAAE,QAAQ,CAAC;IACf,OAAO,EAAE,MAAM,GAAG,MAAM,CAAC;IACzB,KAAK,EAAE,MAAM,GAAG,MAAM,CAAC;IACvB,QAAQ,EAAE,MAAM,GAAG,MAAM,CAAC;IAC1B,QAAQ,EAAE,MAAM,GAAG,MAAM,CAAC;IAC1B,EAAE,EAAE,GAAG,GAAG,IAAI,CAAC;IACf,KAAK,EAAE,MAAM,GAAG,MAAM,CAAC;IACvB,IAAI,EAAE,GAAG,GAAG,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,GAAG,CAAC;IACb,WAAW,EAAE,GAAG,EAAE,CAAC;CACpB;AAED,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,SAAS,CAAC;IAChB,OAAO,EAAE,MAAM,GAAG,MAAM,CAAC;IACzB,KAAK,EAAE,MAAM,GAAG,MAAM,CAAC;IACvB,oBAAoB,EAAE,MAAM,GAAG,MAAM,CAAC;IACtC,YAAY,EAAE,MAAM,GAAG,MAAM,CAAC;IAC9B,QAAQ,EAAE,MAAM,GAAG,MAAM,CAAC;IAC1B,EAAE,EAAE,GAAG,GAAG,IAAI,CAAC;IACf,KAAK,EAAE,MAAM,GAAG,MAAM,CAAC;IACvB,IAAI,EAAE,GAAG,GAAG,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,cAAc,EAAE,CAAC;CAC/B;AAED,MAAM,MAAM,UAAU,GAAG,QAAQ,GAAG,SAAS,CAAC;AAiB9C;;;GAGG;AACH,wBAAgB,QAAQ,CAAC,EAAE,EAAE,UAAU,GAAG,MAAM,CA6B/C;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,EAAE,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,GAAG,UAAU,GAAG,GAAG,CAsCpF"}
@@ -0,0 +1,92 @@
1
+ import { keccak256 } from './keccak.js';
2
+ import { encodeInt, rlpEncode } from './rlp.js';
3
+ import { signDigest } from './secp.js';
4
+ function hexToBuf(h) {
5
+ if (Buffer.isBuffer(h))
6
+ return h;
7
+ const s = h.startsWith('0x') ? h.slice(2) : h;
8
+ return Buffer.from(s, 'hex');
9
+ }
10
+ function addrToBuf(a) {
11
+ if (a === null)
12
+ return Buffer.alloc(0);
13
+ return hexToBuf(a);
14
+ }
15
+ function encodeAccessList(list) {
16
+ return list.map((item) => [hexToBuf(item.address), item.storageKeys.map(hexToBuf)]);
17
+ }
18
+ /**
19
+ * Returns the 32-byte keccak digest that should be signed for the given tx.
20
+ * For legacy this is the EIP-155 digest; for EIP-1559 it is the type-prefixed digest.
21
+ */
22
+ export function txDigest(tx) {
23
+ if (tx.type === 'legacy') {
24
+ // EIP-155: keccak256(rlp([nonce, gasPrice, gasLimit, to, value, data, chainId, 0, 0]))
25
+ const fields = [
26
+ encodeInt(tx.nonce),
27
+ encodeInt(tx.gasPrice),
28
+ encodeInt(tx.gasLimit),
29
+ addrToBuf(tx.to),
30
+ encodeInt(tx.value),
31
+ hexToBuf(tx.data),
32
+ encodeInt(tx.chainId),
33
+ encodeInt(0),
34
+ encodeInt(0),
35
+ ];
36
+ return keccak256(rlpEncode(fields));
37
+ }
38
+ // EIP-1559: keccak256(0x02 || rlp([chainId, nonce, maxPriorityFeePerGas, maxFeePerGas, gasLimit, to, value, data, accessList]))
39
+ const fields = [
40
+ encodeInt(tx.chainId),
41
+ encodeInt(tx.nonce),
42
+ encodeInt(tx.maxPriorityFeePerGas),
43
+ encodeInt(tx.maxFeePerGas),
44
+ encodeInt(tx.gasLimit),
45
+ addrToBuf(tx.to),
46
+ encodeInt(tx.value),
47
+ hexToBuf(tx.data),
48
+ encodeAccessList(tx.accessList ?? []),
49
+ ];
50
+ return keccak256(Buffer.concat([Buffer.from([0x02]), rlpEncode(fields)]));
51
+ }
52
+ /**
53
+ * Sign a transaction and return its 0x-prefixed serialized hex.
54
+ */
55
+ export function signTransaction(tx, privateKey) {
56
+ const digest = txDigest(tx);
57
+ const sig = signDigest(digest, privateKey);
58
+ if (tx.type === 'legacy') {
59
+ // EIP-155 v = chainId * 2 + 35 + recovery
60
+ const chainId = typeof tx.chainId === 'bigint' ? tx.chainId : BigInt(tx.chainId);
61
+ const v = chainId * 2n + 35n + BigInt(sig.recovery);
62
+ const fields = [
63
+ encodeInt(tx.nonce),
64
+ encodeInt(tx.gasPrice),
65
+ encodeInt(tx.gasLimit),
66
+ addrToBuf(tx.to),
67
+ encodeInt(tx.value),
68
+ hexToBuf(tx.data),
69
+ encodeInt(v),
70
+ sig.r,
71
+ sig.s,
72
+ ];
73
+ return ('0x' + rlpEncode(fields).toString('hex'));
74
+ }
75
+ // EIP-1559: 0x02 || rlp([...txFields, yParity, r, s])
76
+ const fields = [
77
+ encodeInt(tx.chainId),
78
+ encodeInt(tx.nonce),
79
+ encodeInt(tx.maxPriorityFeePerGas),
80
+ encodeInt(tx.maxFeePerGas),
81
+ encodeInt(tx.gasLimit),
82
+ addrToBuf(tx.to),
83
+ encodeInt(tx.value),
84
+ hexToBuf(tx.data),
85
+ encodeAccessList(tx.accessList ?? []),
86
+ encodeInt(sig.recovery),
87
+ sig.r,
88
+ sig.s,
89
+ ];
90
+ return ('0x02' + rlpEncode(fields).toString('hex'));
91
+ }
92
+ //# sourceMappingURL=sign-tx.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sign-tx.js","sourceRoot":"","sources":["../../../src/eth/sign-tx.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,33 @@
1
+ export interface TypedDataDomain {
2
+ name?: string;
3
+ version?: string;
4
+ chainId?: number | bigint;
5
+ verifyingContract?: `0x${string}`;
6
+ salt?: `0x${string}`;
7
+ }
8
+ export interface TypedDataField {
9
+ name: string;
10
+ type: string;
11
+ }
12
+ export interface TypedDataTypes {
13
+ EIP712Domain?: TypedDataField[];
14
+ [typeName: string]: TypedDataField[] | undefined;
15
+ }
16
+ export interface TypedData {
17
+ types: TypedDataTypes;
18
+ primaryType: string;
19
+ domain: TypedDataDomain;
20
+ message: Record<string, unknown>;
21
+ }
22
+ /**
23
+ * encodeType: "Type(field1 t1,field2 t2)Dep1(...)Dep2(...)"
24
+ */
25
+ export declare function encodeType(primaryType: string, types: TypedDataTypes): string;
26
+ export declare function typeHash(primaryType: string, types: TypedDataTypes): Buffer;
27
+ export declare function hashStruct(primaryType: string, data: Record<string, unknown>, types: TypedDataTypes): Buffer;
28
+ /**
29
+ * The EIP-712 digest: keccak256("\x19\x01" || domainSeparator || hashStruct(primaryType, message)).
30
+ */
31
+ export declare function typedDataDigest(td: TypedData): Buffer;
32
+ export declare function signTypedData(td: TypedData, privateKey: Buffer | Uint8Array): Buffer;
33
+ //# sourceMappingURL=sign-typed.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sign-typed.d.ts","sourceRoot":"","sources":["../../../src/eth/sign-typed.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,eAAe;IAC9B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAC1B,iBAAiB,CAAC,EAAE,KAAK,MAAM,EAAE,CAAC;IAClC,IAAI,CAAC,EAAE,KAAK,MAAM,EAAE,CAAC;CACtB;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,cAAc;IAC7B,YAAY,CAAC,EAAE,cAAc,EAAE,CAAC;IAChC,CAAC,QAAQ,EAAE,MAAM,GAAG,cAAc,EAAE,GAAG,SAAS,CAAC;CAClD;AAED,MAAM,WAAW,SAAS;IACxB,KAAK,EAAE,cAAc,CAAC;IACtB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,eAAe,CAAC;IACxB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAClC;AAqCD;;GAEG;AACH,wBAAgB,UAAU,CAAC,WAAW,EAAE,MAAM,EAAE,KAAK,EAAE,cAAc,GAAG,MAAM,CAW7E;AAED,wBAAgB,QAAQ,CAAC,WAAW,EAAE,MAAM,EAAE,KAAK,EAAE,cAAc,GAAG,MAAM,CAE3E;AAiDD,wBAAgB,UAAU,CAAC,WAAW,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,KAAK,EAAE,cAAc,GAAG,MAAM,CAQ5G;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,EAAE,EAAE,SAAS,GAAG,MAAM,CAarD;AAED,wBAAgB,aAAa,CAAC,EAAE,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,GAAG,UAAU,GAAG,MAAM,CAGpF"}
@@ -0,0 +1,142 @@
1
+ import { keccak256 } from './keccak.js';
2
+ import { signDigest } from './secp.js';
3
+ import { serializeEthSignature } from './sign-message.js';
4
+ function hexToBuf(h) {
5
+ const s = h.startsWith('0x') ? h.slice(2) : h;
6
+ return Buffer.from(s, 'hex');
7
+ }
8
+ function bigToBuf(n, bytes) {
9
+ let v = typeof n === 'bigint' ? n : BigInt(n);
10
+ if (v < 0n) {
11
+ // two's complement for signed int<N>
12
+ v = (1n << BigInt(bytes * 8)) + v;
13
+ }
14
+ let hex = v.toString(16);
15
+ if (hex.length > bytes * 2)
16
+ throw new Error(`integer overflow for ${bytes}-byte slot`);
17
+ hex = hex.padStart(bytes * 2, '0');
18
+ return Buffer.from(hex, 'hex');
19
+ }
20
+ /**
21
+ * Collect all dependencies of a struct type, transitively, sorted alphabetically
22
+ * with the primary type first.
23
+ */
24
+ function findDependencies(primaryType, types, deps = new Set()) {
25
+ if (deps.has(primaryType))
26
+ return deps;
27
+ const fields = types[primaryType];
28
+ if (!fields)
29
+ return deps;
30
+ deps.add(primaryType);
31
+ for (const field of fields) {
32
+ const baseType = field.type.replace(/(\[\d*\])+$/, '');
33
+ if (types[baseType] && !deps.has(baseType)) {
34
+ findDependencies(baseType, types, deps);
35
+ }
36
+ }
37
+ return deps;
38
+ }
39
+ /**
40
+ * encodeType: "Type(field1 t1,field2 t2)Dep1(...)Dep2(...)"
41
+ */
42
+ export function encodeType(primaryType, types) {
43
+ const deps = findDependencies(primaryType, types);
44
+ deps.delete(primaryType);
45
+ const ordered = [primaryType, ...Array.from(deps).sort()];
46
+ return ordered
47
+ .map((t) => {
48
+ const fields = types[t];
49
+ if (!fields)
50
+ throw new Error(`type ${t} not defined`);
51
+ return `${t}(${fields.map((f) => `${f.type} ${f.name}`).join(',')})`;
52
+ })
53
+ .join('');
54
+ }
55
+ export function typeHash(primaryType, types) {
56
+ return keccak256(Buffer.from(encodeType(primaryType, types), 'utf8'));
57
+ }
58
+ function encodeValue(type, value, types) {
59
+ // Arrays
60
+ const arrayMatch = type.match(/^(.*)(\[(\d*)\])$/);
61
+ if (arrayMatch) {
62
+ const inner = arrayMatch[1];
63
+ if (!Array.isArray(value))
64
+ throw new Error(`expected array for ${type}`);
65
+ const encoded = Buffer.concat(value.map((v) => encodeValue(inner, v, types)));
66
+ return keccak256(encoded);
67
+ }
68
+ // Structs
69
+ if (types[type]) {
70
+ return hashStruct(type, value, types);
71
+ }
72
+ // Atomic types
73
+ if (type === 'string') {
74
+ return keccak256(Buffer.from(value, 'utf8'));
75
+ }
76
+ if (type === 'bytes') {
77
+ const buf = typeof value === 'string' ? hexToBuf(value) : value;
78
+ return keccak256(buf);
79
+ }
80
+ if (type === 'address') {
81
+ const buf = hexToBuf(value);
82
+ if (buf.length !== 20)
83
+ throw new Error(`address must be 20 bytes, got ${buf.length}`);
84
+ return Buffer.concat([Buffer.alloc(12), buf]);
85
+ }
86
+ if (type === 'bool') {
87
+ return bigToBuf(value ? 1 : 0, 32);
88
+ }
89
+ const uintMatch = type.match(/^u?int(\d+)?$/);
90
+ if (uintMatch) {
91
+ // Both int and uint are encoded as 32-byte big-endian.
92
+ return bigToBuf(value, 32);
93
+ }
94
+ const bytesMatch = type.match(/^bytes(\d+)$/);
95
+ if (bytesMatch) {
96
+ const len = parseInt(bytesMatch[1], 10);
97
+ const buf = typeof value === 'string' ? hexToBuf(value) : value;
98
+ if (buf.length !== len)
99
+ throw new Error(`expected bytes${len}, got ${buf.length} bytes`);
100
+ // Right-padded to 32 bytes
101
+ const out = Buffer.alloc(32);
102
+ buf.copy(out, 0);
103
+ return out;
104
+ }
105
+ throw new Error(`unsupported type ${type}`);
106
+ }
107
+ export function hashStruct(primaryType, data, types) {
108
+ const fields = types[primaryType];
109
+ if (!fields)
110
+ throw new Error(`type ${primaryType} not defined`);
111
+ const encoded = [typeHash(primaryType, types)];
112
+ for (const field of fields) {
113
+ encoded.push(encodeValue(field.type, data[field.name], types));
114
+ }
115
+ return keccak256(Buffer.concat(encoded));
116
+ }
117
+ /**
118
+ * The EIP-712 digest: keccak256("\x19\x01" || domainSeparator || hashStruct(primaryType, message)).
119
+ */
120
+ export function typedDataDigest(td) {
121
+ // Build EIP712Domain type from the domain fields actually present (canonical order).
122
+ const domainFields = [];
123
+ if (td.domain.name !== undefined)
124
+ domainFields.push({ name: 'name', type: 'string' });
125
+ if (td.domain.version !== undefined)
126
+ domainFields.push({ name: 'version', type: 'string' });
127
+ if (td.domain.chainId !== undefined)
128
+ domainFields.push({ name: 'chainId', type: 'uint256' });
129
+ if (td.domain.verifyingContract !== undefined)
130
+ domainFields.push({ name: 'verifyingContract', type: 'address' });
131
+ if (td.domain.salt !== undefined)
132
+ domainFields.push({ name: 'salt', type: 'bytes32' });
133
+ const typesWithDomain = { ...td.types, EIP712Domain: domainFields };
134
+ const domainHash = hashStruct('EIP712Domain', td.domain, typesWithDomain);
135
+ const messageHash = hashStruct(td.primaryType, td.message, td.types);
136
+ return keccak256(Buffer.concat([Buffer.from([0x19, 0x01]), domainHash, messageHash]));
137
+ }
138
+ export function signTypedData(td, privateKey) {
139
+ const digest = typedDataDigest(td);
140
+ return serializeEthSignature(signDigest(digest, privateKey));
141
+ }
142
+ //# sourceMappingURL=sign-typed.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sign-typed.js","sourceRoot":"","sources":["../../../src/eth/sign-typed.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,59 @@
1
+ {
2
+ "name": "sigild",
3
+ "version": "0.0.1",
4
+ "description": "Claude can sign, but never see. Local signing daemon that keeps private keys out of LLM context.",
5
+ "license": "Apache-2.0",
6
+ "author": "Chris Doran",
7
+ "homepage": "https://github.com/cdrn/sigil#readme",
8
+ "bugs": {
9
+ "url": "https://github.com/cdrn/sigil/issues"
10
+ },
11
+ "repository": {
12
+ "type": "git",
13
+ "url": "git+https://github.com/cdrn/sigil.git"
14
+ },
15
+ "keywords": [
16
+ "claude",
17
+ "claude-code",
18
+ "anthropic",
19
+ "agent",
20
+ "mcp",
21
+ "model-context-protocol",
22
+ "signing",
23
+ "ethereum",
24
+ "eip-1559",
25
+ "eip-712",
26
+ "eip-191",
27
+ "key-management",
28
+ "wallet-security",
29
+ "supply-chain"
30
+ ],
31
+ "type": "module",
32
+ "bin": {
33
+ "sigild": "dist/src/bin/sigild.js"
34
+ },
35
+ "files": [
36
+ "dist/src/**/*",
37
+ "README.md",
38
+ "THREAT_MODEL.md",
39
+ "CONTRIBUTING.md",
40
+ "LICENSE"
41
+ ],
42
+ "engines": {
43
+ "node": ">=22.0.0"
44
+ },
45
+ "scripts": {
46
+ "build": "tsc && node scripts/post-build.mjs",
47
+ "test": "npm run build && node --test 'dist/test/**/*.test.js'",
48
+ "test:watch": "node --watch --test 'dist/test/**/*.test.js'"
49
+ },
50
+ "dependencies": {
51
+ "@noble/ciphers": "1.3.0",
52
+ "@noble/hashes": "1.8.0",
53
+ "@noble/secp256k1": "3.1.0"
54
+ },
55
+ "devDependencies": {
56
+ "@types/node": "^22.10.0",
57
+ "typescript": "^5.7.0"
58
+ }
59
+ }