@inco/js 0.8.0-devnet-13 → 0.8.0-devnet-22

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 (89) hide show
  1. package/README.md +18 -76
  2. package/dist/cjs/advancedacl/session-key.d.ts +1 -1
  3. package/dist/cjs/advancedacl/session-key.js +3 -2
  4. package/dist/cjs/attestedcompute/attested-compute.js +5 -2
  5. package/dist/cjs/attesteddecrypt/attested-decrypt.d.ts +5 -1
  6. package/dist/cjs/attesteddecrypt/attested-decrypt.js +14 -4
  7. package/dist/cjs/binary.d.ts +2 -4
  8. package/dist/cjs/binary.js +11 -6
  9. package/dist/cjs/encryption/index.d.ts +1 -1
  10. package/dist/cjs/encryption/index.js +17 -16
  11. package/dist/cjs/generated/abis/lightning.d.ts +70 -17
  12. package/dist/cjs/generated/abis/lightning.js +44 -19
  13. package/dist/cjs/generated/abis/test-elist.d.ts +10 -2
  14. package/dist/cjs/generated/abis/test-elist.js +8 -3
  15. package/dist/cjs/generated/abis/verifier.d.ts +78 -4
  16. package/dist/cjs/generated/abis/verifier.js +49 -4
  17. package/dist/cjs/generated/lightning.d.ts +60 -0
  18. package/dist/cjs/generated/lightning.js +64 -1
  19. package/dist/cjs/generated/local-node.d.ts +4 -4
  20. package/dist/cjs/generated/local-node.js +4 -4
  21. package/dist/cjs/index.d.ts +1 -1
  22. package/dist/cjs/index.js +11 -2
  23. package/dist/cjs/kms/quorumClient.d.ts +5 -13
  24. package/dist/cjs/kms/quorumClient.js +74 -259
  25. package/dist/cjs/kms/quorumConsistency.d.ts +58 -0
  26. package/dist/cjs/kms/quorumConsistency.js +200 -0
  27. package/dist/cjs/kms/signatureVerification.d.ts +35 -0
  28. package/dist/cjs/kms/signatureVerification.js +88 -0
  29. package/dist/cjs/kms/thresholdPromises.d.ts +4 -3
  30. package/dist/cjs/kms/thresholdPromises.js +25 -15
  31. package/dist/cjs/lite/hadu.d.ts +1 -1
  32. package/dist/cjs/lite/hadu.js +3 -3
  33. package/dist/cjs/lite/index.d.ts +0 -2
  34. package/dist/cjs/lite/index.js +1 -15
  35. package/dist/cjs/lite/lightning.d.ts +1 -1
  36. package/dist/cjs/lite/lightning.js +14 -33
  37. package/dist/esm/advancedacl/session-key.d.ts +1 -1
  38. package/dist/esm/advancedacl/session-key.js +3 -2
  39. package/dist/esm/attestedcompute/attested-compute.js +6 -3
  40. package/dist/esm/attesteddecrypt/attested-decrypt.d.ts +5 -1
  41. package/dist/esm/attesteddecrypt/attested-decrypt.js +15 -5
  42. package/dist/esm/binary.d.ts +2 -4
  43. package/dist/esm/binary.js +11 -6
  44. package/dist/esm/encryption/index.d.ts +1 -1
  45. package/dist/esm/encryption/index.js +2 -2
  46. package/dist/esm/generated/abis/lightning.d.ts +70 -17
  47. package/dist/esm/generated/abis/lightning.js +44 -19
  48. package/dist/esm/generated/abis/test-elist.d.ts +10 -2
  49. package/dist/esm/generated/abis/test-elist.js +8 -3
  50. package/dist/esm/generated/abis/verifier.d.ts +78 -4
  51. package/dist/esm/generated/abis/verifier.js +49 -4
  52. package/dist/esm/generated/lightning.d.ts +60 -0
  53. package/dist/esm/generated/lightning.js +64 -1
  54. package/dist/esm/generated/local-node.d.ts +4 -4
  55. package/dist/esm/generated/local-node.js +4 -4
  56. package/dist/esm/index.d.ts +1 -1
  57. package/dist/esm/index.js +2 -2
  58. package/dist/esm/kms/quorumClient.d.ts +5 -13
  59. package/dist/esm/kms/quorumClient.js +74 -259
  60. package/dist/esm/kms/quorumConsistency.d.ts +58 -0
  61. package/dist/esm/kms/quorumConsistency.js +193 -0
  62. package/dist/esm/kms/signatureVerification.d.ts +35 -0
  63. package/dist/esm/kms/signatureVerification.js +84 -0
  64. package/dist/esm/kms/thresholdPromises.d.ts +4 -3
  65. package/dist/esm/kms/thresholdPromises.js +25 -15
  66. package/dist/esm/lite/hadu.d.ts +1 -1
  67. package/dist/esm/lite/hadu.js +2 -2
  68. package/dist/esm/lite/index.d.ts +0 -2
  69. package/dist/esm/lite/index.js +1 -3
  70. package/dist/esm/lite/lightning.d.ts +1 -1
  71. package/dist/esm/lite/lightning.js +8 -27
  72. package/dist/types/advancedacl/session-key.d.ts +1 -1
  73. package/dist/types/attesteddecrypt/attested-decrypt.d.ts +5 -1
  74. package/dist/types/binary.d.ts +2 -4
  75. package/dist/types/encryption/index.d.ts +1 -1
  76. package/dist/types/generated/abis/lightning.d.ts +70 -17
  77. package/dist/types/generated/abis/test-elist.d.ts +10 -2
  78. package/dist/types/generated/abis/verifier.d.ts +78 -4
  79. package/dist/types/generated/lightning.d.ts +60 -0
  80. package/dist/types/generated/local-node.d.ts +4 -4
  81. package/dist/types/index.d.ts +1 -1
  82. package/dist/types/kms/quorumClient.d.ts +5 -13
  83. package/dist/types/kms/quorumConsistency.d.ts +58 -0
  84. package/dist/types/kms/signatureVerification.d.ts +35 -0
  85. package/dist/types/kms/thresholdPromises.d.ts +4 -3
  86. package/dist/types/lite/hadu.d.ts +1 -1
  87. package/dist/types/lite/index.d.ts +0 -2
  88. package/dist/types/lite/lightning.d.ts +1 -1
  89. package/package.json +12 -12
@@ -0,0 +1,193 @@
1
+ import { bytesToHex, parseHex } from '../binary.js';
2
+ import { getHandleType } from '../handle.js';
3
+ import { decrypt } from '../lite/xwing.js';
4
+ /**
5
+ * Computes a canonical key for a single attestation.
6
+ * For plaintext/reencryption+keypair, the key is handle:hex(value).
7
+ * For reencryption without a keypair (XWing ciphertexts are non-deterministic),
8
+ * falls back to handle:op-type as a structural stand-in.
9
+ */
10
+ export async function computeAttestationKey(att, reencryptKeypair) {
11
+ if (!att.value)
12
+ throw new Error('No value in attestation');
13
+ if (att.value.case === 'plaintext') {
14
+ if (!att.value.value.value)
15
+ throw new Error('No plaintext value in attestation');
16
+ return att.handle + ':' + bytesToHex(att.value.value.value);
17
+ }
18
+ if (att.value.case === 'reencryption') {
19
+ const ct = att.value.value.userCiphertext;
20
+ if (!ct)
21
+ throw new Error('No ciphertext in reencryption');
22
+ if (reencryptKeypair) {
23
+ return att.handle + ':' + bytesToHex(await decrypt(reencryptKeypair, ct));
24
+ }
25
+ // Without a keypair, XWing ciphertexts are non-deterministic so we
26
+ // can only check structural equality (handle + op-type).
27
+ return att.handle + ':' + String(getHandleType(parseHex(att.handle)));
28
+ }
29
+ throw new Error(`Unexpected attestation type: ${att.value.case}, expected 'plaintext' or 'reencryption'`);
30
+ }
31
+ /**
32
+ * Validates that all responses in a winning bucket have the same attestation
33
+ * count and types as the quorum-elected reference (bucket[0]).
34
+ */
35
+ export function validateDecryptResponseStructure(bucket) {
36
+ const reference = bucket[0].response;
37
+ for (let r = 1; r < bucket.length; r++) {
38
+ if (bucket[r].response.decryptionAttestations.length !==
39
+ reference.decryptionAttestations.length) {
40
+ throw new Error('Inconsistent number of decryption attestations across KMS responses');
41
+ }
42
+ }
43
+ for (let i = 0; i < reference.decryptionAttestations.length; i++) {
44
+ const refAtt = reference.decryptionAttestations[i];
45
+ const refCase = refAtt.value?.case;
46
+ if (!refCase) {
47
+ throw new Error('No value in reference attestation');
48
+ }
49
+ for (let r = 1; r < bucket.length; r++) {
50
+ const att = bucket[r].response.decryptionAttestations[i];
51
+ if (!att.value) {
52
+ throw new Error('No value in attestation');
53
+ }
54
+ // Defensive check: handles should match within a bucket (bucketing includes handle in key)
55
+ if (att.handle !== refAtt.handle) {
56
+ throw new Error(`Handle mismatch at attestation index ${i}: expected '${refAtt.handle}' but got '${att.handle}'`);
57
+ }
58
+ if (att.value.case !== refCase) {
59
+ throw new Error(`Inconsistent attestation types: reference has '${refCase}' but response ${r} has '${att.value.case}'`);
60
+ }
61
+ }
62
+ }
63
+ }
64
+ /**
65
+ * Validates that all responses in a winning bucket have a decryption
66
+ * attestation with the same case as the quorum-elected reference (bucket[0]),
67
+ * and that the case is consistent with the request's reencryptPubKey.
68
+ */
69
+ export function validateComputeResponseStructure(bucket, request) {
70
+ const refAtt = bucket[0].response.decryptionAttestation;
71
+ if (!refAtt) {
72
+ throw new Error('No decryption attestation in reference response');
73
+ }
74
+ if (!refAtt.value) {
75
+ throw new Error('No value in reference attestation');
76
+ }
77
+ const refCase = refAtt.value.case;
78
+ const hasReencryptPubKey = request?.reencryptPubKey && request.reencryptPubKey.length > 0;
79
+ if (refCase === 'reencryption' && !hasReencryptPubKey) {
80
+ throw new Error("Unexpected attestation type: reencryption, expected 'plaintext'");
81
+ }
82
+ if (refCase !== 'plaintext' && refCase !== 'reencryption') {
83
+ throw new Error(`Unexpected attestation type: ${refCase}, expected 'plaintext' or 'reencryption'`);
84
+ }
85
+ for (let r = 1; r < bucket.length; r++) {
86
+ const att = bucket[r].response.decryptionAttestation;
87
+ if (!att)
88
+ throw new Error('No decryption attestation in response');
89
+ if (!att.value)
90
+ throw new Error('No value in attestation');
91
+ // Defensive check: handles should match within a bucket (bucketing includes handle in key)
92
+ if (att.handle !== refAtt.handle) {
93
+ throw new Error(`Handle mismatch: expected '${refAtt.handle}' but got '${att.handle}'`);
94
+ }
95
+ if (att.value.case !== refCase) {
96
+ throw new Error(`Inconsistent attestation types: reference has '${refCase}' but response ${r} has '${att.value.case}'`);
97
+ }
98
+ }
99
+ }
100
+ async function computeDecryptResponseKey(response, reencryptKeypair) {
101
+ const keys = await Promise.all(response.decryptionAttestations.map((att) => computeAttestationKey(att, reencryptKeypair)));
102
+ return keys.join('|');
103
+ }
104
+ async function computeComputeResponseKey(response, reencryptKeypair) {
105
+ const att = response.decryptionAttestation;
106
+ if (!att)
107
+ throw new Error('No decryption attestation in response');
108
+ return computeAttestationKey(att, reencryptKeypair);
109
+ }
110
+ /**
111
+ * Verifies decrypt/reveal response consistency using hash-bucket voting.
112
+ * Collects all N responses, buckets them by content key, and returns the
113
+ * winning bucket (the first one with >= threshold votes).
114
+ *
115
+ * This is robust against a faulty first-responding node: even if responses[0]
116
+ * disagrees, a quorum of agreeing responses will form a winning bucket.
117
+ */
118
+ export async function verifyDecryptResponseConsistency(allResults, threshold, reencryptKeypair) {
119
+ if (allResults.length === 0) {
120
+ throw new Error('No responses collected to verify');
121
+ }
122
+ // Compute a content key for each response and bucket by key.
123
+ // Responses whose key computation fails (malformed/invalid attestation) are
124
+ // excluded so that one faulty responder cannot abort the whole check.
125
+ const buckets = new Map();
126
+ const skippedErrors = [];
127
+ for (const result of allResults) {
128
+ let key;
129
+ try {
130
+ key = await computeDecryptResponseKey(result.response, reencryptKeypair);
131
+ }
132
+ catch (e) {
133
+ skippedErrors.push(e instanceof Error ? e.message : String(e));
134
+ continue;
135
+ }
136
+ if (!buckets.has(key))
137
+ buckets.set(key, []);
138
+ buckets.get(key).push(result);
139
+ }
140
+ // Find the first bucket that reaches the quorum threshold.
141
+ // With majority threshold (floor(n/2) + 1), at most one bucket can reach quorum,
142
+ // so iteration order doesn't affect which bucket wins.
143
+ for (const bucket of buckets.values()) {
144
+ if (bucket.length >= threshold) {
145
+ validateDecryptResponseStructure(bucket);
146
+ return { reference: bucket[0].response, winningResults: bucket };
147
+ }
148
+ }
149
+ const skippedSuffix = skippedErrors.length > 0
150
+ ? `; ${skippedErrors.length} response(s) excluded due to key-computation errors: ${skippedErrors.join(', ')}`
151
+ : '';
152
+ throw new Error(`No quorum: no group of ${threshold} KMS responses agreed on the same value${skippedSuffix}`);
153
+ }
154
+ /**
155
+ * Verifies compute response consistency using hash-bucket voting.
156
+ */
157
+ export async function verifyComputeResponseConsistency(allResults, threshold, request, reencryptKeypair) {
158
+ if (allResults.length === 0) {
159
+ throw new Error('No responses collected to verify');
160
+ }
161
+ // Compute a content key for each response and bucket by key.
162
+ // Responses whose key computation fails (malformed/invalid attestation) are
163
+ // excluded so that one faulty responder cannot abort the whole check.
164
+ const buckets = new Map();
165
+ const skippedErrors = [];
166
+ for (const result of allResults) {
167
+ let key;
168
+ try {
169
+ key = await computeComputeResponseKey(result.response, reencryptKeypair);
170
+ }
171
+ catch (e) {
172
+ skippedErrors.push(e instanceof Error ? e.message : String(e));
173
+ continue;
174
+ }
175
+ if (!buckets.has(key))
176
+ buckets.set(key, []);
177
+ buckets.get(key).push(result);
178
+ }
179
+ // Find the first bucket that reaches the quorum threshold.
180
+ // With majority threshold (floor(n/2) + 1), at most one bucket can reach quorum,
181
+ // so iteration order doesn't affect which bucket wins.
182
+ for (const bucket of buckets.values()) {
183
+ if (bucket.length >= threshold) {
184
+ validateComputeResponseStructure(bucket, request);
185
+ return { reference: bucket[0].response, winningResults: bucket };
186
+ }
187
+ }
188
+ const skippedSuffix = skippedErrors.length > 0
189
+ ? `; ${skippedErrors.length} response(s) excluded due to key-computation errors: ${skippedErrors.join(', ')}`
190
+ : '';
191
+ throw new Error(`No quorum: no group of ${threshold} KMS responses agreed on the same value${skippedSuffix}`);
192
+ }
193
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicXVvcnVtQ29uc2lzdGVuY3kuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMva21zL3F1b3J1bUNvbnNpc3RlbmN5LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUNBLE9BQU8sRUFBRSxVQUFVLEVBQUUsUUFBUSxFQUFFLE1BQU0sY0FBYyxDQUFDO0FBUXBELE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSxjQUFjLENBQUM7QUFFN0MsT0FBTyxFQUFFLE9BQU8sRUFBRSxNQUFNLGtCQUFrQixDQUFDO0FBRTNDOzs7OztHQUtHO0FBQ0gsTUFBTSxDQUFDLEtBQUssVUFBVSxxQkFBcUIsQ0FDekMsR0FBK0IsRUFDL0IsZ0JBQStCO0lBRS9CLElBQUksQ0FBQyxHQUFHLENBQUMsS0FBSztRQUFFLE1BQU0sSUFBSSxLQUFLLENBQUMseUJBQXlCLENBQUMsQ0FBQztJQUMzRCxJQUFJLEdBQUcsQ0FBQyxLQUFLLENBQUMsSUFBSSxLQUFLLFdBQVcsRUFBRSxDQUFDO1FBQ25DLElBQUksQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLEtBQUssQ0FBQyxLQUFLO1lBQ3hCLE1BQU0sSUFBSSxLQUFLLENBQUMsbUNBQW1DLENBQUMsQ0FBQztRQUN2RCxPQUFPLEdBQUcsQ0FBQyxNQUFNLEdBQUcsR0FBRyxHQUFHLFVBQVUsQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUMsQ0FBQztJQUM5RCxDQUFDO0lBQ0QsSUFBSSxHQUFHLENBQUMsS0FBSyxDQUFDLElBQUksS0FBSyxjQUFjLEVBQUUsQ0FBQztRQUN0QyxNQUFNLEVBQUUsR0FBRyxHQUFHLENBQUMsS0FBSyxDQUFDLEtBQUssQ0FBQyxjQUFjLENBQUM7UUFDMUMsSUFBSSxDQUFDLEVBQUU7WUFBRSxNQUFNLElBQUksS0FBSyxDQUFDLCtCQUErQixDQUFDLENBQUM7UUFDMUQsSUFBSSxnQkFBZ0IsRUFBRSxDQUFDO1lBQ3JCLE9BQU8sR0FBRyxDQUFDLE1B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
@@ -0,0 +1,35 @@
1
+ import type { Account, Address, Chain, PublicClient, Transport, WalletClient } from 'viem';
2
+ export type ViemClient = WalletClient<Transport, Chain, Account> | PublicClient<Transport, Chain>;
3
+ /**
4
+ * Verifies covalidator signatures for a plaintext DecryptionAttestation
5
+ * by calling `isValidDecryptionAttestation` on the IncoVerifier contract.
6
+ *
7
+ * This delegates all verification logic (EIP-712 digest computation,
8
+ * ECDSA recovery, signer authorization, threshold check) to the contract,
9
+ * ensuring exact parity with on-chain verification.
10
+ *
11
+ * @param handle - The handle hex string (bytes32)
12
+ * @param rawValueBytes - The raw plaintext value bytes (will be left-padded to 32 bytes)
13
+ * @param signatures - The covalidator ECDSA signatures to verify
14
+ * @param executorAddress - The Lightning contract address (executor)
15
+ * @param client - A viem client capable of reading contract state
16
+ * @throws If the contract returns false (insufficient valid signatures)
17
+ */
18
+ export declare function verifyPlaintextAttestationSignatures(handle: string, rawValueBytes: Uint8Array, signatures: Uint8Array[], executorAddress: Address, client: ViemClient): Promise<void>;
19
+ /**
20
+ * Verifies covalidator envelope signatures for reencryption attestations
21
+ * by calling `isValidReencryptionAttestation` on the IncoVerifier contract.
22
+ *
23
+ * Each covalidator signs over its own unique (userCiphertext, handle, encryptedSignature)
24
+ * tuple, so all three per-covalidator arrays must be aligned by index and sorted
25
+ * by signer address in ascending order.
26
+ *
27
+ * @param handle - The handle hex string (bytes32)
28
+ * @param userCiphertexts - Per-covalidator ciphertexts (sorted by signer address)
29
+ * @param encryptedSignatures - Per-covalidator encrypted inner signatures (sorted by signer address)
30
+ * @param envelopeSignatures - Per-covalidator envelope signatures (sorted by signer address)
31
+ * @param executorAddress - The Lightning contract address (executor)
32
+ * @param client - A viem client capable of reading contract state
33
+ * @throws If the contract returns false (insufficient valid signatures)
34
+ */
35
+ export declare function verifyReencryptionAttestationSignatures(handle: string, userCiphertexts: Uint8Array[], encryptedSignatures: Uint8Array[], envelopeSignatures: Uint8Array[], executorAddress: Address, client: ViemClient): Promise<void>;
@@ -0,0 +1,84 @@
1
+ import { getContract, pad, bytesToHex as viemBytesToHex } from 'viem';
2
+ import { incoLightningAbi } from '../generated/abis/lightning.js';
3
+ import { incoVerifierAbi } from '../generated/abis/verifier.js';
4
+ /**
5
+ * Resolves the IncoVerifier contract instance from the executor (Lightning) contract.
6
+ */
7
+ async function getVerifierContract(executorAddress, client) {
8
+ const lightning = getContract({
9
+ address: executorAddress,
10
+ abi: incoLightningAbi,
11
+ client,
12
+ });
13
+ const verifierAddress = await lightning.read.incoVerifier();
14
+ return getContract({
15
+ address: verifierAddress,
16
+ abi: incoVerifierAbi,
17
+ client,
18
+ });
19
+ }
20
+ /**
21
+ * Verifies covalidator signatures for a plaintext DecryptionAttestation
22
+ * by calling `isValidDecryptionAttestation` on the IncoVerifier contract.
23
+ *
24
+ * This delegates all verification logic (EIP-712 digest computation,
25
+ * ECDSA recovery, signer authorization, threshold check) to the contract,
26
+ * ensuring exact parity with on-chain verification.
27
+ *
28
+ * @param handle - The handle hex string (bytes32)
29
+ * @param rawValueBytes - The raw plaintext value bytes (will be left-padded to 32 bytes)
30
+ * @param signatures - The covalidator ECDSA signatures to verify
31
+ * @param executorAddress - The Lightning contract address (executor)
32
+ * @param client - A viem client capable of reading contract state
33
+ * @throws If the contract returns false (insufficient valid signatures)
34
+ */
35
+ export async function verifyPlaintextAttestationSignatures(handle, rawValueBytes, signatures, executorAddress, client) {
36
+ const verifier = await getVerifierContract(executorAddress, client);
37
+ // Left-pad value to 32 bytes (matching Go's common.LeftPadBytes(value, 32))
38
+ const valueHex = pad(viemBytesToHex(rawValueBytes), {
39
+ dir: 'left',
40
+ size: 32,
41
+ });
42
+ // Convert signatures to hex format for the contract call
43
+ const signaturesHex = signatures.map((sig) => viemBytesToHex(sig));
44
+ const isValid = await verifier.read.isValidDecryptionAttestation([
45
+ { handle: handle, value: valueHex },
46
+ signaturesHex,
47
+ ]);
48
+ if (!isValid) {
49
+ throw new Error('Covalidator signature verification failed: isValidDecryptionAttestation returned false');
50
+ }
51
+ }
52
+ /**
53
+ * Verifies covalidator envelope signatures for reencryption attestations
54
+ * by calling `isValidReencryptionAttestation` on the IncoVerifier contract.
55
+ *
56
+ * Each covalidator signs over its own unique (userCiphertext, handle, encryptedSignature)
57
+ * tuple, so all three per-covalidator arrays must be aligned by index and sorted
58
+ * by signer address in ascending order.
59
+ *
60
+ * @param handle - The handle hex string (bytes32)
61
+ * @param userCiphertexts - Per-covalidator ciphertexts (sorted by signer address)
62
+ * @param encryptedSignatures - Per-covalidator encrypted inner signatures (sorted by signer address)
63
+ * @param envelopeSignatures - Per-covalidator envelope signatures (sorted by signer address)
64
+ * @param executorAddress - The Lightning contract address (executor)
65
+ * @param client - A viem client capable of reading contract state
66
+ * @throws If the contract returns false (insufficient valid signatures)
67
+ */
68
+ export async function verifyReencryptionAttestationSignatures(handle, userCiphertexts, encryptedSignatures, envelopeSignatures, executorAddress, client) {
69
+ const verifier = await getVerifierContract(executorAddress, client);
70
+ const attestations = userCiphertexts.map((ct, i) => ({
71
+ handle: handle,
72
+ userCiphertext: viemBytesToHex(ct),
73
+ encryptedSignature: viemBytesToHex(encryptedSignatures[i]),
74
+ }));
75
+ const signaturesHex = envelopeSignatures.map((sig) => viemBytesToHex(sig));
76
+ const isValid = await verifier.read.isValidReencryptionAttestation([
77
+ attestations,
78
+ signaturesHex,
79
+ ]);
80
+ if (!isValid) {
81
+ throw new Error('Covalidator signature verification failed: isValidReencryptionAttestation returned false');
82
+ }
83
+ }
84
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2lnbmF0dXJlVmVyaWZpY2F0aW9uLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2ttcy9zaWduYXR1cmVWZXJpZmljYXRpb24udHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBU0EsT0FBTyxFQUFFLFdBQVcsRUFBRSxHQUFHLEVBQUUsVUFBVSxJQUFJLGNBQWMsRUFBRSxNQUFNLE1BQU0sQ0FBQztBQUN0RSxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSxnQ0FBZ0MsQ0FBQztBQUNsRSxPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0sK0JBQStCLENBQUM7QUFNaEU7O0dBRUc7QUFDSCxLQUFLLFVBQVUsbUJBQW1CLENBQ2hDLGVBQXdCLEVBQ3hCLE1BQWtCO0lBRWxCLE1BQU0sU0FBUyxHQUFHLFdBQVcsQ0FBQztRQUM1QixPQUFPLEVBQUUsZUFBZTtRQUN4QixHQUFHLEVBQUUsZ0JBQWdCO1FBQ3JCLE1BQU07S0FDUCxDQUFDLENBQUM7SUFFSCxNQUFNLGVBQWUsR0FBRyxNQUFNLFNBQVMsQ0FBQyxJQUFJLENBQUMsWUFBWSxFQUFFLENBQUM7SUFFNUQsT0FBTyxXQUFXLENBQUM7UUFDakIsT0FBTyxFQUFFLGVBQWU7UUFDeEIsR0FBRyxFQUFFLGVBQWU7UUFDcEIsTUFBTTtLQUNQLENBQUMsQ0FBQztBQUNMLENBQUM7QUFFRDs7Ozs7Ozs7Ozs7Ozs7R0FjRztBQUNILE1BQU0sQ0FBQyxLQUFLLFVBQVUsb0NBQW9DLENBQ3hELE1BQWMsRUFDZCxhQUF5QixFQUN6QixVQUF3QixFQUN4QixlQUF3QixFQUN4QixNQUFrQjtJQUVsQixNQUFNLFFBQVEsR0FBRyxNQUFNLG1CQUFtQixDQUFDLGVBQWUsRUFBRSxNQUFNLENBQUMsQ0FBQztJQUVwRSw0RUFBNEU7SUFDNUUsTUFBTSxRQUFRLEdBQUcsR0FBRyxDQUFDLGNBQWMsQ0FBQyxhQUFhLENBQUMsRUFBRTtRQUNsRCxHQUFHLEVBQUUsTUFBTTtRQUNYLElBQUksRUFBRSxFQUFFO0tBQ1QsQ0FBQyxDQUFDO0lBRUgseURBQXlEO0lBQ3pELE1BQU0sYUFBYSxHQUFVLFVBQVUsQ0FBQyxHQUFHLENBQ3pDLENBQUMsR0FBRyxFQUFFLEVBQUUsQ0FBQyxjQUFjLENBQUMsR0FBRyxDQUFRLENBQ3BDLENBQUM7SUFFRixNQUFNLE9BQU8sR0FBRyxNQUFNLFFBQVEsQ0FBQyxJQUFJLENBQUMsNEJBQTRCLENBQUM7UUFDL0QsRUFBRSxNQUFNLEVBQUUsTUFBYSxFQUFFLEtBQUssRUFBRSxRQUFRLEVBQUU7UUFDMUMsYUFBYTtLQUNkLENBQUMsQ0FBQztJQUVILElBQUksQ0FBQyxPQUFPLEVBQUUsQ0FBQztRQUNiLE1BQU0sSUFBSSxLQUFLLENBQ2Isd0ZBQXdGLENBQ3pGLENBQUM7SUFDSixDQUFDO0FBQ0gsQ0FBQztBQUVEOzs7Ozs7Ozs7Ozs7Ozs7R0FlRztBQUNILE1BQU0sQ0FBQyxLQUFLLFVBQVUsdUNBQXVDLENBQzNELE1BQWMsRUFDZCxlQUE2QixFQUM3QixtQkFBaUMsRUFDakMsa0JBQWdDLEVBQ2hDLGVBQXdCLEVBQ3hCLE1BQWtCO0lBRWxCLE1BQU0sUUFBUSxHQUFHLE1BQU0sbUJBQW1CLENBQUMsZUFBZSxFQUFFLE1BQU0sQ0FBQyxDQUFDO0lBRXBFLE1BQU0sWUFBWSxHQUFHLGVBQWUsQ0FBQyxHQUFHLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDO1FBQ25ELE1BQU0sRUFBRSxNQUFhO1FBQ3JCLGNBQWMsRUFBRSxjQUFjLENBQUMsRUFBRSxDQUFRO1FBQ3pDLGtCQUFrQixFQUFFLGNBQWMsQ0FBQyxtQkFBbUIsQ0FBQyxDQUFDLENBQUMsQ0FBUTtLQUNsRSxDQUFDLENBQUMsQ0FBQztJQUVKLE1BQU0sYUFBYSxHQUFVLGtCQUFrQixDQUFDLEdBQUcsQ0FDakQsQ0FBQyxHQUFHLEVBQUUsRUFBRSxDQUFDLGNBQWMsQ0FBQyxHQUFHLENBQVEsQ0FDcEMsQ0FBQztJQUVGLE1BQU0sT0FBTyxHQUFHLE1BQU0sUUFBUSxDQUFDLElBQUksQ0FBQyw4QkFBOEIsQ0FBQztRQUNqRSxZQUFZO1FBQ1osYUFBYTtLQUNkLENBQUMsQ0FBQztJQUVILElBQUksQ0FBQyxPQUFPLEVBQUUsQ0FBQztRQUNiLE1BQU0sSUFBSSxLQUFLLENBQ2IsMEZBQTBGLENBQzNGLENBQUM7SUFDSixDQUFDO0FBQ0gsQ0FBQyJ9
@@ -1,7 +1,8 @@
1
1
  /**
2
- * Executes promises and returns results as soon as threshold is reached
2
+ * Executes all promises and returns all successful results.
3
+ * Rejects early if it becomes mathematically impossible to reach the threshold.
3
4
  * @param promises Array of promises to execute
4
- * @param threshold Number of successful responses needed
5
- * @returns Promise that resolves with threshold number of results
5
+ * @param threshold Minimum number of successful responses required
6
+ * @returns Promise that resolves with all successful results (length >= threshold)
6
7
  */
7
8
  export declare function executeWithThreshold<T>(promises: Promise<T>[], threshold: number): Promise<T[]>;
@@ -1,8 +1,9 @@
1
1
  /**
2
- * Executes promises and returns results as soon as threshold is reached
2
+ * Executes all promises and returns all successful results.
3
+ * Rejects early if it becomes mathematically impossible to reach the threshold.
3
4
  * @param promises Array of promises to execute
4
- * @param threshold Number of successful responses needed
5
- * @returns Promise that resolves with threshold number of results
5
+ * @param threshold Minimum number of successful responses required
6
+ * @returns Promise that resolves with all successful results (length >= threshold)
6
7
  */
7
8
  export async function executeWithThreshold(promises, threshold) {
8
9
  if (threshold < 0) {
@@ -19,31 +20,40 @@ export async function executeWithThreshold(promises, threshold) {
19
20
  throw new Error(`Threshold ${threshold} exceeds number of promises ${promises.length}`);
20
21
  }
21
22
  const results = [];
22
- let failures = 0;
23
+ let settled = 0;
24
+ let rejected = false;
23
25
  return new Promise((resolve, reject) => {
24
26
  promises.forEach((promise) => {
25
27
  promise
26
28
  .then((response) => {
27
- if (results.length < threshold) {
28
- results.push(response);
29
- if (results.length === threshold) {
30
- resolve(results);
31
- }
29
+ // After early rejection (threshold became unreachable), ignore late-arriving
30
+ // successes since we've already rejected the overall promise.
31
+ if (rejected)
32
+ return;
33
+ results.push(response);
34
+ settled++;
35
+ if (settled === promises.length) {
36
+ resolve(results);
32
37
  }
33
38
  })
34
39
  .catch((error) => {
35
- console.error(`Error executing promise: ${error}`);
36
- failures++;
40
+ // After early rejection, ignore subsequent failures since we've already
41
+ // rejected the overall promise.
42
+ if (rejected)
43
+ return;
44
+ settled++;
37
45
  // Check if we can still reach the threshold
38
- // We need (threshold - results.length) more successes
39
- // from (promises.length - results.length - failures) remaining promises
40
- const remainingPromises = promises.length - results.length - failures;
46
+ const remainingPromises = promises.length - settled;
41
47
  const neededSuccesses = threshold - results.length;
42
48
  if (remainingPromises < neededSuccesses) {
49
+ rejected = true;
43
50
  reject(new Error(`Cannot reach threshold of ${threshold} responses. Failed clients exceed limit. Last error: ${error}`));
44
51
  }
52
+ else if (settled === promises.length) {
53
+ resolve(results);
54
+ }
45
55
  });
46
56
  });
47
57
  });
48
58
  }
49
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGhyZXNob2xkUHJvbWlzZXMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMva21zL3RocmVzaG9sZFByb21pc2VzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7OztHQUtHO0FBQ0gsTUFBTSxDQUFDLEtBQUssVUFBVSxvQkFBb0IsQ0FDeEMsUUFBc0IsRUFDdEIsU0FBaUI7SUFFakIsSUFBSSxTQUFTLEdBQUcsQ0FBQyxFQUFFLENBQUM7UUFDbEIsTUFBTSxJQUFJLEtBQUssQ0FBQyw4QkFBOEIsQ0FBQyxDQUFDO0lBQ2xELENBQUM7SUFDRCwwQ0FBMEM7SUFDMUMsSUFBSSxTQUFTLEtBQUssQ0FBQyxFQUFFLENBQUM7UUFDcEIsT0FBTyxFQUFFLENBQUM7SUFDWixDQUFDO0lBQ0QsSUFBSSxRQUFRLENBQUMsTUFBTSxLQUFLLENBQUMsSUFBSSxTQUFTLEdBQUcsQ0FBQyxFQUFFLENBQUM7UUFDM0MsTUFBTSxJQUFJLEtBQUssQ0FBQyxrREFBa0QsQ0FBQyxDQUFDO0lBQ3RFLENBQUM7SUFDRCxJQUFJLFNBQVMsR0FBRyxRQUFRLENBQUMsTUFBTSxFQUFFLENBQUM7UUFDaEMsTUFBTSxJQUFJLEtBQUssQ0FDYixhQUFhLFNBQVMsK0JBQStCLFFBQVEsQ0FBQyxNQUFNLEVBQUUsQ0FDdkUsQ0FBQztJQUNKLENBQUM7SUFFRCxNQUFNLE9BQU8sR0FBUSxFQUFFLENBQUM7SUFDeEIsSUFBSSxRQUFRLEdBQUcsQ0FBQyxDQUFDO0lBRWpCLE9BQU8sSUFBSSxPQUFPLENBQUMsQ0FBQyxPQUFPLEVBQUUsTUFBTSxFQUFFLEVBQUU7UUFDckMsUUFBUSxDQUFDLE9BQU8sQ0FBQyxDQUFDLE9BQU8sRUFBRSxFQUFFO1lBQzNCLE9BQU87aUJBQ0osSUFBSSxDQUFDLENBQUMsUUFBUSxFQUFFLEVBQUU7Z0JBQ2pCLElBQUksT0FBTyxDQUFDLE1BQU0sR0FBRyxTQUFTLEVBQUUsQ0FBQztvQkFDL0IsT0FBTyxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQztvQkFDdkIsSUFBSSxPQUFPLENBQUMsTUFBTSxLQUFLLFNBQVMsRUFBRSxDQUFDO3dCQUNqQyxPQUFPLENBQUMsT0FBTyxDQUFDLENBQUM7b0JBQ25CLENBQUM7Z0JBQ0gsQ0FBQztZQUNILENBQUMsQ0FBQztpQkFDRCxLQUFLLENBQUMsQ0FBQyxLQUFLLEVBQUUsRUFBRTtnQkFDZixPQUFPLENBQUMsS0FBSyxDQUFDLDRCQUE0QixLQUFLLEVBQUUsQ0FBQyxDQUFDO2dCQUNuRCxRQUFRLEVBQUUsQ0FBQztnQkFDWCw0Q0FBNEM7Z0JBQzVDLHNEQUFzRDtnQkFDdEQsd0VBQXdFO2dCQUN4RSxNQUFNLGlCQUFpQixHQUFHLFFBQVEsQ0FBQyxNQUFNLEdBQUcsT0FBTyxDQUFDLE1BQU0sR0FBRyxRQUFRLENBQUM7Z0JBQ3RFLE1BQU0sZUFBZSxHQUFHLFNBQVMsR0FBRyxPQUFPLENBQUMsTUFBTSxDQUFDO2dCQUNuRCxJQUFJLGlCQUFpQixHQUFHLGVBQWUsRUFBRSxDQUFDO29CQUN4QyxNQUFNLENBQ0osSUFBSSxLQUFLLENBQ1AsNkJBQTZCLFNBQVMsd0RBQXdELEtBQUssRUFBRSxDQUN0RyxDQUNGLENBQUM7Z0JBQ0osQ0FBQztZQUNILENBQUMsQ0FBQyxDQUFDO1FBQ1AsQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDLENBQUMsQ0FBQztBQUNMLENBQUMifQ==
59
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGhyZXNob2xkUHJvbWlzZXMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMva21zL3RocmVzaG9sZFByb21pc2VzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7Ozs7R0FNRztBQUNILE1BQU0sQ0FBQyxLQUFLLFVBQVUsb0JBQW9CLENBQ3hDLFFBQXNCLEVBQ3RCLFNBQWlCO0lBRWpCLElBQUksU0FBUyxHQUFHLENBQUMsRUFBRSxDQUFDO1FBQ2xCLE1BQU0sSUFBSSxLQUFLLENBQUMsOEJBQThCLENBQUMsQ0FBQztJQUNsRCxDQUFDO0lBQ0QsMENBQTBDO0lBQzFDLElBQUksU0FBUyxLQUFLLENBQUMsRUFBRSxDQUFDO1FBQ3BCLE9BQU8sRUFBRSxDQUFDO0lBQ1osQ0FBQztJQUNELElBQUksUUFBUSxDQUFDLE1BQU0sS0FBSyxDQUFDLElBQUksU0FBUyxHQUFHLENBQUMsRUFBRSxDQUFDO1FBQzNDLE1BQU0sSUFBSSxLQUFLLENBQUMsa0RBQWtELENBQUMsQ0FBQztJQUN0RSxDQUFDO0lBQ0QsSUFBSSxTQUFTLEdBQUcsUUFBUSxDQUFDLE1BQU0sRUFBRSxDQUFDO1FBQ2hDLE1BQU0sSUFBSSxLQUFLLENBQ2IsYUFBYSxTQUFTLCtCQUErQixRQUFRLENBQUMsTUFBTSxFQUFFLENBQ3ZFLENBQUM7SUFDSixDQUFDO0lBRUQsTUFBTSxPQUFPLEdBQVEsRUFBRSxDQUFDO0lBQ3hCLElBQUksT0FBTyxHQUFHLENBQUMsQ0FBQztJQUNoQixJQUFJLFFBQVEsR0FBRyxLQUFLLENBQUM7SUFFckIsT0FBTyxJQUFJLE9BQU8sQ0FBQyxDQUFDLE9BQU8sRUFBRSxNQUFNLEVBQUUsRUFBRTtRQUNyQyxRQUFRLENBQUMsT0FBTyxDQUFDLENBQUMsT0FBTyxFQUFFLEVBQUU7WUFDM0IsT0FBTztpQkFDSixJQUFJLENBQUMsQ0FBQyxRQUFRLEVBQUUsRUFBRTtnQkFDakIsNkVBQTZFO2dCQUM3RSw4REFBOEQ7Z0JBQzlELElBQUksUUFBUTtvQkFBRSxPQUFPO2dCQUNyQixPQUFPLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDO2dCQUN2QixPQUFPLEVBQUUsQ0FBQztnQkFDVixJQUFJLE9BQU8sS0FBSyxRQUFRLENBQUMsTUFBTSxFQUFFLENBQUM7b0JBQ2hDLE9BQU8sQ0FBQyxPQUFPLENBQUMsQ0FBQztnQkFDbkIsQ0FBQztZQUNILENBQUMsQ0FBQztpQkFDRCxLQUFLLENBQUMsQ0FBQyxLQUFLLEVBQUUsRUFBRTtnQkFDZix3RUFBd0U7Z0JBQ3hFLGdDQUFnQztnQkFDaEMsSUFBSSxRQUFRO29CQUFFLE9BQU87Z0JBQ3JCLE9BQU8sRUFBRSxDQUFDO2dCQUNWLDRDQUE0QztnQkFDNUMsTUFBTSxpQkFBaUIsR0FBRyxRQUFRLENBQUMsTUFBTSxHQUFHLE9BQU8sQ0FBQztnQkFDcEQsTUFBTSxlQUFlLEdBQUcsU0FBUyxHQUFHLE9BQU8sQ0FBQyxNQUFNLENBQUM7Z0JBQ25ELElBQUksaUJBQWlCLEdBQUcsZUFBZSxFQUFFLENBQUM7b0JBQ3hDLFFBQVEsR0FBRyxJQUFJLENBQUM7b0JBQ2hCLE1BQU0sQ0FDSixJQUFJLEtBQUssQ0FDUCw2QkFBNkIsU0FBUyx3REFBd0QsS0FBSyxFQUFFLENBQ3RHLENBQ0YsQ0FBQztnQkFDSixDQUFDO3FCQUFNLElBQUksT0FBTyxLQUFLLFFBQVEsQ0FBQyxNQUFNLEVBQUUsQ0FBQztvQkFDdkMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxDQUFDO2dCQUNuQixDQUFDO1lBQ0gsQ0FBQyxDQUFDLENBQUM7UUFDUCxDQUFDLENBQUMsQ0FBQztJQUNMLENBQUMsQ0FBQyxDQUFDO0FBQ0wsQ0FBQyJ9
@@ -1,4 +1,4 @@
1
- import { PlaintextWithContext } from '../encryption/index.js';
1
+ import { PlaintextWithContext } from '../encryption/encryption.js';
2
2
  import { InputPayload } from '../generated/es/inco/covalidator/compute/v1/types_pb.js';
3
3
  export declare function encodeInput({ plaintext, context, }: PlaintextWithContext): Uint8Array;
4
4
  export declare function decodeInput(input: Uint8Array): InputPayload;
@@ -1,5 +1,5 @@
1
1
  import { create, fromBinary, toBinary } from '@bufbuild/protobuf';
2
- import { plaintextToBytes } from '../encryption/index.js';
2
+ import { plaintextToBytes, } from '../encryption/encryption.js';
3
3
  import { InputPayloadSchema, ScalarSchema, } from '../generated/es/inco/covalidator/compute/v1/types_pb.js';
4
4
  import { hashInputContext } from '../handle.js';
5
5
  // HADU stands for "Host Chain, ACL, DApp, and User" it maps to the InputContext type where the aclAddress
@@ -21,4 +21,4 @@ export function decodeInput(input) {
21
21
  const payload = fromBinary(InputPayloadSchema, input);
22
22
  return payload;
23
23
  }
24
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaGFkdS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9saXRlL2hhZHUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLE1BQU0sRUFBRSxVQUFVLEVBQUUsUUFBUSxFQUFFLE1BQU0sb0JBQW9CLENBQUM7QUFDbEUsT0FBTyxFQUFFLGdCQUFnQixFQUF3QixNQUFNLHdCQUF3QixDQUFDO0FBQ2hGLE9BQU8sRUFFTCxrQkFBa0IsRUFDbEIsWUFBWSxHQUNiLE1BQU0seURBQXlELENBQUM7QUFDakUsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0sY0FBYyxDQUFDO0FBRWhELDBHQUEwRztBQUMxRywwRUFBMEU7QUFFMUUsTUFBTSxVQUFVLFdBQVcsQ0FBQyxFQUMxQixTQUFTLEVBQ1QsT0FBTyxHQUNjO0lBQ3JCLE1BQU0sT0FBTyxHQUFHLE1BQU0sQ0FBQyxrQkFBa0IsRUFBRTtRQUN6QyxXQUFXLEVBQUUsZ0JBQWdCLENBQUMsT0FBTyxDQUFDO1FBQ3RDLEtBQUssRUFBRTtZQUNMLElBQUksRUFBRSxRQUFRO1lBQ2QsS0FBSyxFQUFFLE1BQU0sQ0FBQyxZQUFZLEVBQUU7Z0JBQzFCLElBQUksRUFBRSxTQUFTLENBQUMsSUFBSTtnQkFDcEIsS0FBSyxFQUFFLGdCQUFnQixDQUFDLFNBQVMsQ0FBQzthQUNuQyxDQUFDO1NBQ0g7S0FDRixDQUFDLENBQUM7SUFDSCxPQUFPLFFBQVEsQ0FBQyxrQkFBa0IsRUFBRSxPQUFPLENBQUMsQ0FBQztBQUMvQyxDQUFDO0FBRUQsTUFBTSxVQUFVLFdBQVcsQ0FBQyxLQUFpQjtJQUMzQyxNQUFNLE9BQU8sR0FBRyxVQUFVLENBQUMsa0JBQWtCLEVBQUUsS0FBSyxDQUFDLENBQUM7SUFDdEQsT0FBTyxPQUFPLENBQUM7QUFDakIsQ0FBQyJ9
24
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaGFkdS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9saXRlL2hhZHUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLE1BQU0sRUFBRSxVQUFVLEVBQUUsUUFBUSxFQUFFLE1BQU0sb0JBQW9CLENBQUM7QUFDbEUsT0FBTyxFQUNMLGdCQUFnQixHQUVqQixNQUFNLDZCQUE2QixDQUFDO0FBQ3JDLE9BQU8sRUFFTCxrQkFBa0IsRUFDbEIsWUFBWSxHQUNiLE1BQU0seURBQXlELENBQUM7QUFDakUsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0sY0FBYyxDQUFDO0FBRWhELDBHQUEwRztBQUMxRywwRUFBMEU7QUFFMUUsTUFBTSxVQUFVLFdBQVcsQ0FBQyxFQUMxQixTQUFTLEVBQ1QsT0FBTyxHQUNjO0lBQ3JCLE1BQU0sT0FBTyxHQUFHLE1BQU0sQ0FBQyxrQkFBa0IsRUFBRTtRQUN6QyxXQUFXLEVBQUUsZ0JBQWdCLENBQUMsT0FBTyxDQUFDO1FBQ3RDLEtBQUssRUFBRTtZQUNMLElBQUksRUFBRSxRQUFRO1lBQ2QsS0FBSyxFQUFFLE1BQU0sQ0FBQyxZQUFZLEVBQUU7Z0JBQzFCLElBQUksRUFBRSxTQUFTLENBQUMsSUFBSTtnQkFDcEIsS0FBSyxFQUFFLGdCQUFnQixDQUFDLFNBQVMsQ0FBQzthQUNuQyxDQUFDO1NBQ0g7S0FDRixDQUFDLENBQUM7SUFDSCxPQUFPLFFBQVEsQ0FBQyxrQkFBa0IsRUFBRSxPQUFPLENBQUMsQ0FBQztBQUMvQyxDQUFDO0FBRUQsTUFBTSxVQUFVLFdBQVcsQ0FBQyxLQUFpQjtJQUMzQyxNQUFNLE9BQU8sR0FBRyxVQUFVLENBQUMsa0JBQWtCLEVBQUUsS0FBSyxDQUFDLENBQUM7SUFDdEQsT0FBTyxPQUFPLENBQUM7QUFDakIsQ0FBQyJ9
@@ -4,6 +4,4 @@ export type { HandleWithProof } from '../generated/es/inco/kms/lite/v1/types_pb.
4
4
  export * from './attested-compute.js';
5
5
  export * from './attested-decrypt.js';
6
6
  export * from './deployments.js';
7
- export * from './hadu.js';
8
7
  export * from './lightning.js';
9
- export { TEST_NETWORK_SEED_KEY, XWING_PUBLIC_KEY_SIZE, decodeXwingPrivateKey, decodeXwingPublicKey, decrypt, deriveXwingKeypairFromSeed, encodeXwingPublicKey, encrypt, generateXwingKeypair, getXwingDecryptor, getXwingEncryptor, type XwingDecryptorArgs, type XwingEncryptorArgs, type XwingKeypair, } from './xwing.js';
@@ -2,7 +2,5 @@ export * from '../generated/abis/lightning.js';
2
2
  export * from './attested-compute.js';
3
3
  export * from './attested-decrypt.js';
4
4
  export * from './deployments.js';
5
- export * from './hadu.js';
6
5
  export * from './lightning.js';
7
- export { TEST_NETWORK_SEED_KEY, XWING_PUBLIC_KEY_SIZE, decodeXwingPrivateKey, decodeXwingPublicKey, decrypt, deriveXwingKeypairFromSeed, encodeXwingPublicKey, encrypt, generateXwingKeypair, getXwingDecryptor, getXwingEncryptor, } from './xwing.js';
8
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvbGl0ZS9pbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxjQUFjLGdDQUFnQyxDQUFDO0FBTy9DLGNBQWMsdUJBQXVCLENBQUM7QUFDdEMsY0FBYyx1QkFBdUIsQ0FBQztBQUN0QyxjQUFjLGtCQUFrQixDQUFDO0FBQ2pDLGNBQWMsV0FBVyxDQUFDO0FBQzFCLGNBQWMsZ0JBQWdCLENBQUM7QUFDL0IsT0FBTyxFQUNMLHFCQUFxQixFQUNyQixxQkFBcUIsRUFDckIscUJBQXFCLEVBQ3JCLG9CQUFvQixFQUNwQixPQUFPLEVBQ1AsMEJBQTBCLEVBQzFCLG9CQUFvQixFQUNwQixPQUFPLEVBQ1Asb0JBQW9CLEVBQ3BCLGlCQUFpQixFQUNqQixpQkFBaUIsR0FJbEIsTUFBTSxZQUFZLENBQUMifQ==
6
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvbGl0ZS9pbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxjQUFjLGdDQUFnQyxDQUFDO0FBTy9DLGNBQWMsdUJBQXVCLENBQUM7QUFDdEMsY0FBYyx1QkFBdUIsQ0FBQztBQUN0QyxjQUFjLGtCQUFrQixDQUFDO0FBQ2pDLGNBQWMsZ0JBQWdCLENBQUMifQ==
@@ -4,7 +4,7 @@ import { AllowanceVoucherWithSig } from '../advancedacl/types.js';
4
4
  import { AttestedComputeOP } from '../attestedcompute/types.js';
5
5
  import { DecryptionAttestation, EncryptedDecryptionAttestation } from '../attesteddecrypt/index.js';
6
6
  import { Address, HexString } from '../binary.js';
7
- import { EncryptionScheme, SupportedFheType } from '../encryption/index.js';
7
+ import { EncryptionScheme, SupportedFheType } from '../encryption/encryption.js';
8
8
  import { incoVerifierAbi } from '../generated/abis/verifier.js';
9
9
  import { lightningDeployments } from '../generated/lightning.js';
10
10
  import { localNodeLightningConfig } from '../generated/local-node.js';