@inco/lightning-js 0.0.0-bootstrap.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.
- package/LICENSE +201 -0
- package/README.md +587 -0
- package/dist/cjs/advancedacl/index.d.ts +2 -0
- package/dist/cjs/advancedacl/index.js +19 -0
- package/dist/cjs/advancedacl/session-key.d.ts +95 -0
- package/dist/cjs/advancedacl/session-key.js +376 -0
- package/dist/cjs/advancedacl/types.d.ts +16 -0
- package/dist/cjs/advancedacl/types.js +3 -0
- package/dist/cjs/attestedcompute/attested-compute.d.ts +65 -0
- package/dist/cjs/attestedcompute/attested-compute.js +80 -0
- package/dist/cjs/attestedcompute/types.d.ts +35 -0
- package/dist/cjs/attestedcompute/types.js +46 -0
- package/dist/cjs/attesteddecrypt/attested-decrypt.d.ts +61 -0
- package/dist/cjs/attesteddecrypt/attested-decrypt.js +118 -0
- package/dist/cjs/attesteddecrypt/index.d.ts +1 -0
- package/dist/cjs/attesteddecrypt/index.js +18 -0
- package/dist/cjs/attesteddecrypt/types.d.ts +27 -0
- package/dist/cjs/attesteddecrypt/types.js +16 -0
- package/dist/cjs/attestedreveal/attested-reveal.d.ts +21 -0
- package/dist/cjs/attestedreveal/attested-reveal.js +31 -0
- package/dist/cjs/attestedreveal/index.d.ts +2 -0
- package/dist/cjs/attestedreveal/index.js +21 -0
- package/dist/cjs/attestedreveal/types.d.ts +4 -0
- package/dist/cjs/attestedreveal/types.js +13 -0
- package/dist/cjs/binary.d.ts +104 -0
- package/dist/cjs/binary.js +171 -0
- package/dist/cjs/chain.d.ts +50 -0
- package/dist/cjs/chain.js +62 -0
- package/dist/cjs/eip712/eip712.d.ts +18 -0
- package/dist/cjs/eip712/eip712.js +51 -0
- package/dist/cjs/eip712/index.d.ts +1 -0
- package/dist/cjs/eip712/index.js +8 -0
- package/dist/cjs/elistattesteddecrypt/elist-attested-decrypt.d.ts +51 -0
- package/dist/cjs/elistattesteddecrypt/elist-attested-decrypt.js +94 -0
- package/dist/cjs/elistattesteddecrypt/index.d.ts +2 -0
- package/dist/cjs/elistattesteddecrypt/index.js +22 -0
- package/dist/cjs/elistattesteddecrypt/types.d.ts +31 -0
- package/dist/cjs/elistattesteddecrypt/types.js +16 -0
- package/dist/cjs/encryption/encryption.d.ts +235 -0
- package/dist/cjs/encryption/encryption.js +226 -0
- package/dist/cjs/encryption/index.d.ts +1 -0
- package/dist/cjs/encryption/index.js +19 -0
- package/dist/cjs/generated/abis/add-two.d.ts +117 -0
- package/dist/cjs/generated/abis/add-two.js +80 -0
- package/dist/cjs/generated/abis/lightning.d.ts +3362 -0
- package/dist/cjs/generated/abis/lightning.js +2445 -0
- package/dist/cjs/generated/abis/test-elist.d.ts +276 -0
- package/dist/cjs/generated/abis/test-elist.js +168 -0
- package/dist/cjs/generated/abis/verifier.d.ts +1353 -0
- package/dist/cjs/generated/abis/verifier.js +954 -0
- package/dist/cjs/generated/es/inco/covalidator/compute/v1/server_pb.d.ts +1494 -0
- package/dist/cjs/generated/es/inco/covalidator/compute/v1/server_pb.js +395 -0
- package/dist/cjs/generated/es/inco/covalidator/compute/v1/types_pb.d.ts +247 -0
- package/dist/cjs/generated/es/inco/covalidator/compute/v1/types_pb.js +80 -0
- package/dist/cjs/generated/es/inco/helioswrapper/v1/helioswrapper_pb.d.ts +77 -0
- package/dist/cjs/generated/es/inco/helioswrapper/v1/helioswrapper_pb.js +28 -0
- package/dist/cjs/generated/es/inco/kms/lite/v1/kms_service_pb.d.ts +685 -0
- package/dist/cjs/generated/es/inco/kms/lite/v1/kms_service_pb.js +100 -0
- package/dist/cjs/generated/es/inco/kms/lite/v1/types_pb.d.ts +289 -0
- package/dist/cjs/generated/es/inco/kms/lite/v1/types_pb.js +136 -0
- package/dist/cjs/generated/es/inco/sealingfetcher/v1/sealingfetcher_pb.d.ts +371 -0
- package/dist/cjs/generated/es/inco/sealingfetcher/v1/sealingfetcher_pb.js +88 -0
- package/dist/cjs/generated/lightning.d.ts +830 -0
- package/dist/cjs/generated/lightning.js +872 -0
- package/dist/cjs/generated/local-node.d.ts +50 -0
- package/dist/cjs/generated/local-node.js +107 -0
- package/dist/cjs/handle.d.ts +123 -0
- package/dist/cjs/handle.js +221 -0
- package/dist/cjs/index.d.ts +5 -0
- package/dist/cjs/index.js +31 -0
- package/dist/cjs/kms/client.d.ts +12 -0
- package/dist/cjs/kms/client.js +47 -0
- package/dist/cjs/kms/quorumClient.d.ts +65 -0
- package/dist/cjs/kms/quorumClient.js +463 -0
- package/dist/cjs/kms/quorumConsistency.d.ts +82 -0
- package/dist/cjs/kms/quorumConsistency.js +269 -0
- package/dist/cjs/kms/signatureVerification.d.ts +35 -0
- package/dist/cjs/kms/signatureVerification.js +88 -0
- package/dist/cjs/kms/thresholdPromises.d.ts +8 -0
- package/dist/cjs/kms/thresholdPromises.js +62 -0
- package/dist/cjs/lite/attested-compute.d.ts +6 -0
- package/dist/cjs/lite/attested-compute.js +8 -0
- package/dist/cjs/lite/attested-decrypt.d.ts +4 -0
- package/dist/cjs/lite/attested-decrypt.js +6 -0
- package/dist/cjs/lite/deployments.d.ts +24 -0
- package/dist/cjs/lite/deployments.js +21 -0
- package/dist/cjs/lite/hadu.d.ts +4 -0
- package/dist/cjs/lite/hadu.js +28 -0
- package/dist/cjs/lite/index.d.ts +13 -0
- package/dist/cjs/lite/index.js +31 -0
- package/dist/cjs/lite/lightning.d.ts +459 -0
- package/dist/cjs/lite/lightning.js +696 -0
- package/dist/cjs/lite/types.d.ts +47 -0
- package/dist/cjs/lite/types.js +3 -0
- package/dist/cjs/lite/xwing.d.ts +154 -0
- package/dist/cjs/lite/xwing.js +326 -0
- package/dist/cjs/local/index.d.ts +1 -0
- package/dist/cjs/local/index.js +18 -0
- package/dist/cjs/local/local-node.d.ts +37 -0
- package/dist/cjs/local/local-node.js +80 -0
- package/dist/cjs/reencryption/eip712.d.ts +56 -0
- package/dist/cjs/reencryption/eip712.js +90 -0
- package/dist/cjs/reencryption/index.d.ts +2 -0
- package/dist/cjs/reencryption/index.js +19 -0
- package/dist/cjs/reencryption/types.d.ts +48 -0
- package/dist/cjs/reencryption/types.js +3 -0
- package/dist/cjs/retry.d.ts +30 -0
- package/dist/cjs/retry.js +87 -0
- package/dist/cjs/schema.d.ts +4 -0
- package/dist/cjs/schema.js +19 -0
- package/dist/cjs/test/mocks.d.ts +20 -0
- package/dist/cjs/test/mocks.js +72 -0
- package/dist/cjs/viem.d.ts +1141 -0
- package/dist/cjs/viem.js +36 -0
- package/dist/esm/advancedacl/index.d.ts +2 -0
- package/dist/esm/advancedacl/index.js +3 -0
- package/dist/esm/advancedacl/session-key.d.ts +95 -0
- package/dist/esm/advancedacl/session-key.js +367 -0
- package/dist/esm/advancedacl/types.d.ts +16 -0
- package/dist/esm/advancedacl/types.js +2 -0
- package/dist/esm/attestedcompute/attested-compute.d.ts +65 -0
- package/dist/esm/attestedcompute/attested-compute.js +76 -0
- package/dist/esm/attestedcompute/types.d.ts +35 -0
- package/dist/esm/attestedcompute/types.js +42 -0
- package/dist/esm/attesteddecrypt/attested-decrypt.d.ts +61 -0
- package/dist/esm/attesteddecrypt/attested-decrypt.js +112 -0
- package/dist/esm/attesteddecrypt/index.d.ts +1 -0
- package/dist/esm/attesteddecrypt/index.js +2 -0
- package/dist/esm/attesteddecrypt/types.d.ts +27 -0
- package/dist/esm/attesteddecrypt/types.js +12 -0
- package/dist/esm/attestedreveal/attested-reveal.d.ts +21 -0
- package/dist/esm/attestedreveal/attested-reveal.js +28 -0
- package/dist/esm/attestedreveal/index.d.ts +2 -0
- package/dist/esm/attestedreveal/index.js +3 -0
- package/dist/esm/attestedreveal/types.d.ts +4 -0
- package/dist/esm/attestedreveal/types.js +9 -0
- package/dist/esm/binary.d.ts +104 -0
- package/dist/esm/binary.js +155 -0
- package/dist/esm/chain.d.ts +50 -0
- package/dist/esm/chain.js +58 -0
- package/dist/esm/eip712/eip712.d.ts +18 -0
- package/dist/esm/eip712/eip712.js +46 -0
- package/dist/esm/eip712/index.d.ts +1 -0
- package/dist/esm/eip712/index.js +2 -0
- package/dist/esm/elistattesteddecrypt/elist-attested-decrypt.d.ts +51 -0
- package/dist/esm/elistattesteddecrypt/elist-attested-decrypt.js +89 -0
- package/dist/esm/elistattesteddecrypt/index.d.ts +2 -0
- package/dist/esm/elistattesteddecrypt/index.js +3 -0
- package/dist/esm/elistattesteddecrypt/types.d.ts +31 -0
- package/dist/esm/elistattesteddecrypt/types.js +12 -0
- package/dist/esm/encryption/encryption.d.ts +235 -0
- package/dist/esm/encryption/encryption.js +214 -0
- package/dist/esm/encryption/index.d.ts +1 -0
- package/dist/esm/encryption/index.js +2 -0
- package/dist/esm/generated/abis/add-two.d.ts +117 -0
- package/dist/esm/generated/abis/add-two.js +77 -0
- package/dist/esm/generated/abis/lightning.d.ts +3362 -0
- package/dist/esm/generated/abis/lightning.js +2442 -0
- package/dist/esm/generated/abis/test-elist.d.ts +276 -0
- package/dist/esm/generated/abis/test-elist.js +165 -0
- package/dist/esm/generated/abis/verifier.d.ts +1353 -0
- package/dist/esm/generated/abis/verifier.js +951 -0
- package/dist/esm/generated/es/inco/covalidator/compute/v1/server_pb.d.ts +1494 -0
- package/dist/esm/generated/es/inco/covalidator/compute/v1/server_pb.js +392 -0
- package/dist/esm/generated/es/inco/covalidator/compute/v1/types_pb.d.ts +247 -0
- package/dist/esm/generated/es/inco/covalidator/compute/v1/types_pb.js +77 -0
- package/dist/esm/generated/es/inco/helioswrapper/v1/helioswrapper_pb.d.ts +77 -0
- package/dist/esm/generated/es/inco/helioswrapper/v1/helioswrapper_pb.js +25 -0
- package/dist/esm/generated/es/inco/kms/lite/v1/kms_service_pb.d.ts +685 -0
- package/dist/esm/generated/es/inco/kms/lite/v1/kms_service_pb.js +97 -0
- package/dist/esm/generated/es/inco/kms/lite/v1/types_pb.d.ts +289 -0
- package/dist/esm/generated/es/inco/kms/lite/v1/types_pb.js +133 -0
- package/dist/esm/generated/es/inco/sealingfetcher/v1/sealingfetcher_pb.d.ts +371 -0
- package/dist/esm/generated/es/inco/sealingfetcher/v1/sealingfetcher_pb.js +85 -0
- package/dist/esm/generated/lightning.d.ts +830 -0
- package/dist/esm/generated/lightning.js +869 -0
- package/dist/esm/generated/local-node.d.ts +50 -0
- package/dist/esm/generated/local-node.js +104 -0
- package/dist/esm/handle.d.ts +123 -0
- package/dist/esm/handle.js +212 -0
- package/dist/esm/index.d.ts +5 -0
- package/dist/esm/index.js +6 -0
- package/dist/esm/kms/client.d.ts +12 -0
- package/dist/esm/kms/client.js +40 -0
- package/dist/esm/kms/quorumClient.d.ts +65 -0
- package/dist/esm/kms/quorumClient.js +459 -0
- package/dist/esm/kms/quorumConsistency.d.ts +82 -0
- package/dist/esm/kms/quorumConsistency.js +260 -0
- package/dist/esm/kms/signatureVerification.d.ts +35 -0
- package/dist/esm/kms/signatureVerification.js +84 -0
- package/dist/esm/kms/thresholdPromises.d.ts +8 -0
- package/dist/esm/kms/thresholdPromises.js +59 -0
- package/dist/esm/lite/attested-compute.d.ts +6 -0
- package/dist/esm/lite/attested-compute.js +4 -0
- package/dist/esm/lite/attested-decrypt.d.ts +4 -0
- package/dist/esm/lite/attested-decrypt.js +3 -0
- package/dist/esm/lite/deployments.d.ts +24 -0
- package/dist/esm/lite/deployments.js +17 -0
- package/dist/esm/lite/hadu.d.ts +4 -0
- package/dist/esm/lite/hadu.js +24 -0
- package/dist/esm/lite/index.d.ts +13 -0
- package/dist/esm/lite/index.js +10 -0
- package/dist/esm/lite/lightning.d.ts +459 -0
- package/dist/esm/lite/lightning.js +692 -0
- package/dist/esm/lite/types.d.ts +47 -0
- package/dist/esm/lite/types.js +2 -0
- package/dist/esm/lite/xwing.d.ts +154 -0
- package/dist/esm/lite/xwing.js +311 -0
- package/dist/esm/local/index.d.ts +1 -0
- package/dist/esm/local/index.js +2 -0
- package/dist/esm/local/local-node.d.ts +37 -0
- package/dist/esm/local/local-node.js +76 -0
- package/dist/esm/reencryption/eip712.d.ts +56 -0
- package/dist/esm/reencryption/eip712.js +87 -0
- package/dist/esm/reencryption/index.d.ts +2 -0
- package/dist/esm/reencryption/index.js +3 -0
- package/dist/esm/reencryption/types.d.ts +48 -0
- package/dist/esm/reencryption/types.js +2 -0
- package/dist/esm/retry.d.ts +30 -0
- package/dist/esm/retry.js +82 -0
- package/dist/esm/schema.d.ts +4 -0
- package/dist/esm/schema.js +15 -0
- package/dist/esm/test/mocks.d.ts +20 -0
- package/dist/esm/test/mocks.js +64 -0
- package/dist/esm/viem.d.ts +1141 -0
- package/dist/esm/viem.js +32 -0
- package/dist/types/advancedacl/index.d.ts +2 -0
- package/dist/types/advancedacl/session-key.d.ts +95 -0
- package/dist/types/advancedacl/types.d.ts +16 -0
- package/dist/types/attestedcompute/attested-compute.d.ts +65 -0
- package/dist/types/attestedcompute/types.d.ts +35 -0
- package/dist/types/attesteddecrypt/attested-decrypt.d.ts +61 -0
- package/dist/types/attesteddecrypt/index.d.ts +1 -0
- package/dist/types/attesteddecrypt/types.d.ts +27 -0
- package/dist/types/attestedreveal/attested-reveal.d.ts +21 -0
- package/dist/types/attestedreveal/index.d.ts +2 -0
- package/dist/types/attestedreveal/types.d.ts +4 -0
- package/dist/types/binary.d.ts +104 -0
- package/dist/types/chain.d.ts +50 -0
- package/dist/types/eip712/eip712.d.ts +18 -0
- package/dist/types/eip712/index.d.ts +1 -0
- package/dist/types/elistattesteddecrypt/elist-attested-decrypt.d.ts +51 -0
- package/dist/types/elistattesteddecrypt/index.d.ts +2 -0
- package/dist/types/elistattesteddecrypt/types.d.ts +31 -0
- package/dist/types/encryption/encryption.d.ts +235 -0
- package/dist/types/encryption/index.d.ts +1 -0
- package/dist/types/generated/abis/add-two.d.ts +117 -0
- package/dist/types/generated/abis/lightning.d.ts +3362 -0
- package/dist/types/generated/abis/test-elist.d.ts +276 -0
- package/dist/types/generated/abis/verifier.d.ts +1353 -0
- package/dist/types/generated/es/inco/covalidator/compute/v1/server_pb.d.ts +1494 -0
- package/dist/types/generated/es/inco/covalidator/compute/v1/types_pb.d.ts +247 -0
- package/dist/types/generated/es/inco/helioswrapper/v1/helioswrapper_pb.d.ts +77 -0
- package/dist/types/generated/es/inco/kms/lite/v1/kms_service_pb.d.ts +685 -0
- package/dist/types/generated/es/inco/kms/lite/v1/types_pb.d.ts +289 -0
- package/dist/types/generated/es/inco/sealingfetcher/v1/sealingfetcher_pb.d.ts +371 -0
- package/dist/types/generated/lightning.d.ts +830 -0
- package/dist/types/generated/local-node.d.ts +50 -0
- package/dist/types/handle.d.ts +123 -0
- package/dist/types/index.d.ts +5 -0
- package/dist/types/kms/client.d.ts +12 -0
- package/dist/types/kms/quorumClient.d.ts +65 -0
- package/dist/types/kms/quorumConsistency.d.ts +82 -0
- package/dist/types/kms/signatureVerification.d.ts +35 -0
- package/dist/types/kms/thresholdPromises.d.ts +8 -0
- package/dist/types/lite/attested-compute.d.ts +6 -0
- package/dist/types/lite/attested-decrypt.d.ts +4 -0
- package/dist/types/lite/deployments.d.ts +24 -0
- package/dist/types/lite/hadu.d.ts +4 -0
- package/dist/types/lite/index.d.ts +13 -0
- package/dist/types/lite/lightning.d.ts +459 -0
- package/dist/types/lite/types.d.ts +47 -0
- package/dist/types/lite/xwing.d.ts +154 -0
- package/dist/types/local/index.d.ts +1 -0
- package/dist/types/local/local-node.d.ts +37 -0
- package/dist/types/reencryption/eip712.d.ts +56 -0
- package/dist/types/reencryption/index.d.ts +2 -0
- package/dist/types/reencryption/types.d.ts +48 -0
- package/dist/types/retry.d.ts +30 -0
- package/dist/types/schema.d.ts +4 -0
- package/dist/types/test/mocks.d.ts +20 -0
- package/dist/types/viem.d.ts +1141 -0
- package/package.json +129 -0
|
@@ -0,0 +1,692 @@
|
|
|
1
|
+
import { createPublicClient, fallback, getContract, hexToBytes, http, } from 'viem';
|
|
2
|
+
import { base, baseSepolia } from 'viem/chains';
|
|
3
|
+
import { grantSessionKey, grantSessionKeyCustomVerifier, sessionKeyAttestedCompute, sessionKeyAttestedDecrypt, updateActiveVouchersSessionNonce, } from '../advancedacl/session-key.js';
|
|
4
|
+
import { attestedCompute as performAttestedCompute } from '../attestedcompute/attested-compute.js';
|
|
5
|
+
import { attestedDecrypt } from '../attesteddecrypt/attested-decrypt.js';
|
|
6
|
+
import { attestedReveal as performAttestedReveal } from '../attestedreveal/attested-reveal.js';
|
|
7
|
+
import { HexString, parseAddress } from '../binary.js';
|
|
8
|
+
import { chainShortNames } from '../chain.js';
|
|
9
|
+
import { eListAttestedDecrypt, eListAttestedReveal as performEListAttestedReveal, } from '../elistattesteddecrypt/elist-attested-decrypt.js';
|
|
10
|
+
import { encryptionSchemes, } from '../encryption/encryption.js';
|
|
11
|
+
import { incoLightningAbi } from '../generated/abis/lightning.js';
|
|
12
|
+
import { incoVerifierAbi } from '../generated/abis/verifier.js';
|
|
13
|
+
import { lightningDeployments } from '../generated/lightning.js';
|
|
14
|
+
import { localNodeLightningConfig } from '../generated/local-node.js';
|
|
15
|
+
import { handleTypes } from '../handle.js';
|
|
16
|
+
import { getViemChain } from '../index.js';
|
|
17
|
+
import { KmsQuorumClient } from '../kms/quorumClient.js';
|
|
18
|
+
import { parseLocalEnv } from '../local/index.js';
|
|
19
|
+
import { parse } from '../schema.js';
|
|
20
|
+
import { decodeXwingPublicKey, generateXwingKeypair, getXwingEncryptor, XWING_PUBLIC_KEY_SIZE, } from './xwing.js';
|
|
21
|
+
const DefaultPepper = 'testnet';
|
|
22
|
+
function isLocalNodeEnvFileSource(value) {
|
|
23
|
+
return (!!value &&
|
|
24
|
+
typeof value === 'object' &&
|
|
25
|
+
'filePath' in value &&
|
|
26
|
+
typeof value.filePath === 'string');
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Builds a viem Transport from a list of RPC URLs.
|
|
30
|
+
* - No URLs: uses viem's default public RPC endpoint.
|
|
31
|
+
* - One URL: uses a single http() transport.
|
|
32
|
+
* - Multiple URLs: uses viem's fallback() transport (rank: false by default),
|
|
33
|
+
* which tries providers in order and falls back to the next on failure.
|
|
34
|
+
*/
|
|
35
|
+
function buildTransport(rpcUrls) {
|
|
36
|
+
if (!rpcUrls || rpcUrls.length === 0)
|
|
37
|
+
return http();
|
|
38
|
+
if (rpcUrls.length === 1)
|
|
39
|
+
return http(rpcUrls[0]);
|
|
40
|
+
return fallback(rpcUrls.map((url) => http(url)));
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* The Lightning class provides a convenient way to interact with the Inco Lightning contract by binding to a specific
|
|
44
|
+
* deployment.
|
|
45
|
+
*/
|
|
46
|
+
export class Lightning {
|
|
47
|
+
_deployment;
|
|
48
|
+
covalidatorUrls;
|
|
49
|
+
signers;
|
|
50
|
+
threshold;
|
|
51
|
+
networkPubkey;
|
|
52
|
+
publicClient;
|
|
53
|
+
executorAddress;
|
|
54
|
+
chainId;
|
|
55
|
+
kmsQuorumClient;
|
|
56
|
+
encryptor = null;
|
|
57
|
+
encryptionScheme = null;
|
|
58
|
+
constructor(_deployment, covalidatorUrls, signers, threshold, networkPubkey, publicClient) {
|
|
59
|
+
this._deployment = _deployment;
|
|
60
|
+
this.covalidatorUrls = covalidatorUrls;
|
|
61
|
+
this.signers = signers;
|
|
62
|
+
this.threshold = threshold;
|
|
63
|
+
this.networkPubkey = networkPubkey;
|
|
64
|
+
this.publicClient = publicClient;
|
|
65
|
+
this.executorAddress = parseAddress(_deployment.executorAddress);
|
|
66
|
+
this.chainId = BigInt(_deployment.chainId);
|
|
67
|
+
this.kmsQuorumClient = KmsQuorumClient.fromUrls(this.covalidatorUrls, this.signers, this.threshold);
|
|
68
|
+
}
|
|
69
|
+
async getEncryptor() {
|
|
70
|
+
if (!this.encryptor || !this.encryptionScheme) {
|
|
71
|
+
const pubKeyBytes = hexToBytes(parse(HexString, this.networkPubkey));
|
|
72
|
+
// Detect encryption scheme based on public key length
|
|
73
|
+
if (pubKeyBytes.length === XWING_PUBLIC_KEY_SIZE) {
|
|
74
|
+
// X-Wing encryption
|
|
75
|
+
const pubKeyA = await decodeXwingPublicKey(pubKeyBytes);
|
|
76
|
+
// Safe cast: X-Wing encryptor processes plaintexts with scheme=2,
|
|
77
|
+
// and we ensure scheme matches when calling encrypt()
|
|
78
|
+
this.encryptor = getXwingEncryptor({ pubKeyA });
|
|
79
|
+
this.encryptionScheme = encryptionSchemes.xwing;
|
|
80
|
+
}
|
|
81
|
+
else {
|
|
82
|
+
throw new Error(`Invalid network public key length: expected ${XWING_PUBLIC_KEY_SIZE} (X-Wing), got ${pubKeyBytes.length}`);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
return { encryptor: this.encryptor, scheme: this.encryptionScheme };
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Get the encryption scheme version used by this Lightning instance.
|
|
89
|
+
* Returns the X-Wing encryption scheme identifier.
|
|
90
|
+
* This is a convenience method to get the encryption scheme used by this Lightning instance.
|
|
91
|
+
*/
|
|
92
|
+
async getEncryptionScheme() {
|
|
93
|
+
const { scheme } = await this.getEncryptor();
|
|
94
|
+
return scheme;
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Get a Lightning instance bound to the latest Lightning deployment for Base mainnet.
|
|
98
|
+
*
|
|
99
|
+
* @param options.hostChainRpcUrls optional list of RPC URLs for the host chain. When multiple URLs are
|
|
100
|
+
* provided, viem's fallback transport is used and providers are tried in order on failure.
|
|
101
|
+
*/
|
|
102
|
+
static async baseMainnet(options) {
|
|
103
|
+
return Lightning.latest('mainnet', base.id, options);
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Get a Lightning instance bound to the latest Lightning deployment for the Base Sepolia testnet.
|
|
107
|
+
*
|
|
108
|
+
* @param options.hostChainRpcUrls optional list of RPC URLs for the host chain. When multiple URLs are
|
|
109
|
+
* provided, viem's fallback transport is used and providers are tried in order on failure.
|
|
110
|
+
*/
|
|
111
|
+
static async baseSepoliaTestnet(options) {
|
|
112
|
+
return Lightning.latest('mainnet', baseSepolia.id, options);
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Get a Lightning instance bound to our canonical Anvil-based test node and test Covalidator node
|
|
116
|
+
*
|
|
117
|
+
* These can be run in docker-compose using images pushed to dockerhub as:
|
|
118
|
+
* - inconetwork/local-node-anvil
|
|
119
|
+
* - inconetwork/local-node-covalidator
|
|
120
|
+
*
|
|
121
|
+
* See the sample docker-compose file here: https://github.com/Inco-fhevm/lightning-rod/blob/main/docker-compose.yaml
|
|
122
|
+
*
|
|
123
|
+
* @param env either a Pepper such as 'testnet', 'devnet', 'alphanet' or a LocalNodeEnv object containing the
|
|
124
|
+
* executorAddress, networkPubkey, chainId, covalidatorUrl and senderPrivateKey. If none is provided, it defaults to
|
|
125
|
+
* the 'testnet' Pepper. This produces allows connection to a local node running against a state dump of the
|
|
126
|
+
* corresponding Pepper.
|
|
127
|
+
*
|
|
128
|
+
*/
|
|
129
|
+
static async localNode(env) {
|
|
130
|
+
if (!env) {
|
|
131
|
+
const config = localNodeLightningConfig[DefaultPepper];
|
|
132
|
+
return Lightning.custom({
|
|
133
|
+
...config,
|
|
134
|
+
covalidatorUrls: [...config.covalidatorUrls],
|
|
135
|
+
signers: config.signers.map((s) => parseAddress(s)),
|
|
136
|
+
hostChainRpcUrls: config.hostChainRpcUrls ?? ['http://localhost:8545'],
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
if (typeof env === 'string') {
|
|
140
|
+
const config = localNodeLightningConfig[env];
|
|
141
|
+
return Lightning.custom({
|
|
142
|
+
...config,
|
|
143
|
+
covalidatorUrls: [...config.covalidatorUrls],
|
|
144
|
+
signers: config.signers.map((s) => parseAddress(s)),
|
|
145
|
+
hostChainRpcUrls: config.hostChainRpcUrls ?? ['http://localhost:8545'],
|
|
146
|
+
});
|
|
147
|
+
}
|
|
148
|
+
const conf = localNodeLightningConfig[DefaultPepper];
|
|
149
|
+
return Lightning.custom({
|
|
150
|
+
// We assume that we always run a local node as the default anvil node
|
|
151
|
+
chainId: env.COVALIDATOR_HOST_CHAIN_ID
|
|
152
|
+
? Number(env.COVALIDATOR_HOST_CHAIN_ID)
|
|
153
|
+
: conf.chainId,
|
|
154
|
+
covalidatorUrls: env.COVALIDATOR_URL
|
|
155
|
+
? env.COVALIDATOR_URL.split(',')
|
|
156
|
+
: [...conf.covalidatorUrls],
|
|
157
|
+
signers: env.EIP712_SIGNER_ADDRESS
|
|
158
|
+
? env.EIP712_SIGNER_ADDRESS.split(',').map((address) => parseAddress(address))
|
|
159
|
+
: conf.signers.map((s) => parseAddress(s)),
|
|
160
|
+
hostChainRpcUrls: env.COVALIDATOR_HOST_CHAIN_RPC_URL
|
|
161
|
+
? env.COVALIDATOR_HOST_CHAIN_RPC_URL.split(',')
|
|
162
|
+
: (conf.hostChainRpcUrls ?? ['http://localhost:8545']),
|
|
163
|
+
// These variables vary per environment
|
|
164
|
+
executorAddress: env.EXECUTOR_ADDRESS,
|
|
165
|
+
senderPrivateKey: env.SENDER_PRIVATE_KEY,
|
|
166
|
+
});
|
|
167
|
+
}
|
|
168
|
+
/**
|
|
169
|
+
* Get a Lightning instance bound to a local node from a file containing a LocalNodeEnv environment .
|
|
170
|
+
*
|
|
171
|
+
* @param filePath the path to the file containing the environment variables in dotenv format
|
|
172
|
+
*/
|
|
173
|
+
static async localNodeFromEnv(source) {
|
|
174
|
+
let envContent;
|
|
175
|
+
if (isLocalNodeEnvFileSource(source)) {
|
|
176
|
+
if (typeof process === 'undefined' || !process.versions?.node) {
|
|
177
|
+
throw new Error('Lightning.localNodeFromEnv with a file path is only available in Node environments.');
|
|
178
|
+
}
|
|
179
|
+
const { readFile } = await import('fs/promises');
|
|
180
|
+
envContent = await readFile(source.filePath);
|
|
181
|
+
}
|
|
182
|
+
else {
|
|
183
|
+
envContent = source;
|
|
184
|
+
}
|
|
185
|
+
const env = parseLocalEnv(envContent);
|
|
186
|
+
return await Lightning.localNode(env);
|
|
187
|
+
}
|
|
188
|
+
/**
|
|
189
|
+
* Get a Lightning deployment by name or executor address on a particular chain.
|
|
190
|
+
*
|
|
191
|
+
* @param id this is an object containing either the pair of name and chainId or the executorAddress and chainId
|
|
192
|
+
* @param options.hostChainRpcUrls optional list of RPC URLs for the host chain. When multiple URLs are
|
|
193
|
+
* provided, viem's fallback transport is used and providers are tried in order on failure.
|
|
194
|
+
*/
|
|
195
|
+
static async at(id, options) {
|
|
196
|
+
const deployment = this.isIdByName(id)
|
|
197
|
+
? lightningDeployments.find((d) => d.name === id.name && d.chainId === id.chainId)
|
|
198
|
+
: lightningDeployments.find((d) => d.executorAddress === id.executorAddress &&
|
|
199
|
+
d.chainId === id.chainId);
|
|
200
|
+
if (!deployment) {
|
|
201
|
+
throw new Error(`No deployment found for ${JSON.stringify(id)}`);
|
|
202
|
+
}
|
|
203
|
+
const chain = getViemChain({ id: deployment.chainId });
|
|
204
|
+
const client = createPublicClient({
|
|
205
|
+
chain,
|
|
206
|
+
transport: buildTransport(options?.hostChainRpcUrls),
|
|
207
|
+
});
|
|
208
|
+
const { threshold, signers, networkPubkey } = await Lightning.getChainConfig(deployment, client);
|
|
209
|
+
return new Lightning(deployment, Lightning.getCovalidatorUrls(deployment, signers), signers, threshold, networkPubkey, client);
|
|
210
|
+
}
|
|
211
|
+
/**
|
|
212
|
+
* Get a Lightning deployment for a local or custom node
|
|
213
|
+
*
|
|
214
|
+
* @param config this is an object containing the executorAddress, networkPubkey, chainId and covalidatorUrl.
|
|
215
|
+
* additional fields past will be made available as part of the `deployment` property.
|
|
216
|
+
*/
|
|
217
|
+
static async custom(config) {
|
|
218
|
+
const chain = getViemChain({ id: config.chainId });
|
|
219
|
+
const client = createPublicClient({
|
|
220
|
+
chain,
|
|
221
|
+
transport: buildTransport(config.hostChainRpcUrls),
|
|
222
|
+
});
|
|
223
|
+
const { threshold, signers, networkPubkey } = await Lightning.getVerifierContractDetails(config.executorAddress, client);
|
|
224
|
+
return new Lightning(config, config.covalidatorUrls, signers, threshold, networkPubkey, client);
|
|
225
|
+
}
|
|
226
|
+
/**
|
|
227
|
+
* Get the latest deployment for a given pepper, which usually denotes a family of deployments distinct from their
|
|
228
|
+
* version such as 'devnet', 'testnet', 'mainnet', etc.
|
|
229
|
+
*
|
|
230
|
+
* @param pepper the pepper to use to filter the deployments
|
|
231
|
+
* @param chainId the chainId to use to filter the deployments
|
|
232
|
+
*/
|
|
233
|
+
static latestDeployment(pepper, chainId) {
|
|
234
|
+
// Deployments are sorted so we are guaranteed to get the latest first
|
|
235
|
+
const latestByPepper = lightningDeployments.find((d) => d.pepper === pepper && d.chainId === chainId);
|
|
236
|
+
if (!latestByPepper) {
|
|
237
|
+
// This should not actually happen provided this file compiles since we are extracting the available peppers
|
|
238
|
+
// from the const itself
|
|
239
|
+
throw new Error(`No deployment found for pepper ${pepper}`);
|
|
240
|
+
}
|
|
241
|
+
return latestByPepper;
|
|
242
|
+
}
|
|
243
|
+
/**
|
|
244
|
+
* Get the latest Lightning deployment for a given pepper amd chainId unconditionally.
|
|
245
|
+
* Note that if you upgrade the library the latest deployment may change and contracts deployed to a previous version
|
|
246
|
+
* will not be compatible with the new version.
|
|
247
|
+
*
|
|
248
|
+
* @param pepper the pepper to use to filter the deployments
|
|
249
|
+
* @param chainId the chainId to use to filter the deployments
|
|
250
|
+
* @param options.hostChainRpcUrls optional list of RPC URLs for the host chain. When multiple URLs are
|
|
251
|
+
* provided, viem's fallback transport is used and providers are tried in order on failure.
|
|
252
|
+
*/
|
|
253
|
+
static async latest(pepper, chainId, options) {
|
|
254
|
+
return Lightning.at(Lightning.latestDeployment(pepper, chainId), options);
|
|
255
|
+
}
|
|
256
|
+
/** Returns a shallow copy of the deployment configuration this Lightning instance is bound to. */
|
|
257
|
+
get deployment() {
|
|
258
|
+
return { ...this._deployment };
|
|
259
|
+
}
|
|
260
|
+
/**
|
|
261
|
+
* Encrypt a value using the network's public key (X-Wing).
|
|
262
|
+
* The encryption scheme is automatically detected based on the public key length.
|
|
263
|
+
*
|
|
264
|
+
* @param value a boolean or numeric value to encrypt
|
|
265
|
+
* @param accountAddress the address of the account interacting with the dapp contract, normally an Externally Owned Account (EOA)
|
|
266
|
+
* @param dappAddress the address of the dapp contract that interacts with the Inco Lightning contract or library
|
|
267
|
+
* @param handleType (optional) the handle type to be used for encrypting the value - this is required in case of non-default handle types
|
|
268
|
+
* default handle types:
|
|
269
|
+
* - boolean -> handleTypes.ebool
|
|
270
|
+
* - number | bigint -> handleTypes.euint256
|
|
271
|
+
* @returns a promise that resolves to the encrypted value as a HexString
|
|
272
|
+
*/
|
|
273
|
+
async encrypt(value, { accountAddress, dappAddress, handleType }) {
|
|
274
|
+
const { encryptor, scheme } = await this.getEncryptor();
|
|
275
|
+
const plaintext = Lightning.plaintextFromValue(value, handleType, scheme);
|
|
276
|
+
const { ciphertext } = await encryptor({
|
|
277
|
+
plaintext,
|
|
278
|
+
context: {
|
|
279
|
+
hostChainId: this.chainId,
|
|
280
|
+
aclAddress: this.executorAddress,
|
|
281
|
+
userAddress: parseAddress(accountAddress),
|
|
282
|
+
contractAddress: parseAddress(dappAddress),
|
|
283
|
+
version: scheme,
|
|
284
|
+
inputType: plaintext.type,
|
|
285
|
+
},
|
|
286
|
+
});
|
|
287
|
+
return ciphertext.value;
|
|
288
|
+
}
|
|
289
|
+
/**
|
|
290
|
+
* Grants a session key allowance voucher for secure reencryption operations.
|
|
291
|
+
*
|
|
292
|
+
* This method creates a signed allowance voucher that authorizes a specific requester address
|
|
293
|
+
* to perform reencryption operations using session keys. The voucher includes an expiration time
|
|
294
|
+
* and can optionally specify a custom session verifier contract address.
|
|
295
|
+
*
|
|
296
|
+
* @param walletClient - The wallet client used for signing the allowance voucher
|
|
297
|
+
* @param granteeAddress - The address of the entity requesting the session key allowance
|
|
298
|
+
* @param expiresAt - The timestamp when the allowance voucher expires (as a bigint)
|
|
299
|
+
* @param sessionVerifierAddress - Optional custom session verifier contract address. If not provided, uses the executor address
|
|
300
|
+
* @returns A promise that resolves to an AllowanceVoucherWithSig containing the signed allowance voucher
|
|
301
|
+
*
|
|
302
|
+
* @example
|
|
303
|
+
* ```typescript
|
|
304
|
+
* const voucher = await lightning.grantSessionKeyAllowanceVoucher(
|
|
305
|
+
* walletClient,
|
|
306
|
+
* "0x1234...",
|
|
307
|
+
* BigInt(Date.now() + 3600000), // 1 hour from now
|
|
308
|
+
* "0x5678..." // optional custom verifier
|
|
309
|
+
* );
|
|
310
|
+
* ```
|
|
311
|
+
*/
|
|
312
|
+
grantSessionKeyAllowanceVoucher(walletClient, granteeAddress, expiresAt, sessionVerifierAddress) {
|
|
313
|
+
return grantSessionKey({
|
|
314
|
+
chainId: this.chainId,
|
|
315
|
+
incoLiteAddress: this.executorAddress,
|
|
316
|
+
sessionVerifierContractAddress: parseAddress(sessionVerifierAddress),
|
|
317
|
+
granteeAddress: parseAddress(granteeAddress),
|
|
318
|
+
sharerWalletClient: walletClient,
|
|
319
|
+
expiresAt,
|
|
320
|
+
});
|
|
321
|
+
}
|
|
322
|
+
/**
|
|
323
|
+
* Grants a session key allowance voucher using a custom session verifier contract.
|
|
324
|
+
*
|
|
325
|
+
* This method creates a signed allowance voucher that authorizes reencryption operations
|
|
326
|
+
* using a custom session verifier. Unlike `grantSessionKeyAllowanceVoucher`, this method
|
|
327
|
+
* allows specifying custom `sharerArgData` for use with custom verifier contracts that
|
|
328
|
+
* require additional authorization parameters.
|
|
329
|
+
*
|
|
330
|
+
* @param walletClient - The wallet client used for signing the allowance voucher
|
|
331
|
+
* @param sessionVerifierAddress - The address of the custom session verifier contract
|
|
332
|
+
* @param sharerArgData - Custom encoded arguments for the session verifier's `canUseSession` function
|
|
333
|
+
* @returns A promise that resolves to an AllowanceVoucherWithSig containing the signed allowance voucher
|
|
334
|
+
*
|
|
335
|
+
* @example
|
|
336
|
+
* ```typescript
|
|
337
|
+
* const sharerArgData = encodeAbiParameters(
|
|
338
|
+
* [{ type: 'address' }, { type: 'uint256' }],
|
|
339
|
+
* [granteeAddress, expiresAt]
|
|
340
|
+
* );
|
|
341
|
+
* const voucher = await lightning.grantCustomSessionKeyAllowanceVoucher(
|
|
342
|
+
* walletClient,
|
|
343
|
+
* "0x5678...", // custom verifier address
|
|
344
|
+
* sharerArgData
|
|
345
|
+
* );
|
|
346
|
+
* ```
|
|
347
|
+
*/
|
|
348
|
+
grantCustomSessionKeyAllowanceVoucher(walletClient, sessionVerifierAddress, sharerArgData) {
|
|
349
|
+
return grantSessionKeyCustomVerifier({
|
|
350
|
+
chainId: this.chainId,
|
|
351
|
+
incoLiteAddress: this.executorAddress,
|
|
352
|
+
sessionVerifierContractAddress: parseAddress(sessionVerifierAddress),
|
|
353
|
+
sharerWalletClient: walletClient,
|
|
354
|
+
sharerArgData: sharerArgData,
|
|
355
|
+
});
|
|
356
|
+
}
|
|
357
|
+
/**
|
|
358
|
+
* Updates the active session nonce for the given wallet client.
|
|
359
|
+
*
|
|
360
|
+
* This method updates the active session nonce for the given wallet client.
|
|
361
|
+
* It nullifies all the previous shared addresses accessing the voucher.
|
|
362
|
+
*
|
|
363
|
+
* @param walletClient - The wallet client used for updating the session nonce
|
|
364
|
+
* @returns The transaction hash of the updateActiveVouchersSessionNonce transaction
|
|
365
|
+
*/
|
|
366
|
+
updateActiveVouchersSessionNonce(walletClient) {
|
|
367
|
+
return updateActiveVouchersSessionNonce(this.executorAddress, walletClient);
|
|
368
|
+
}
|
|
369
|
+
async attestedDecrypt(walletClient, handles, opts) {
|
|
370
|
+
const { reencryptPubKey: inputPubKey, reencryptKeypair: inputKeypair, backoffConfig, } = opts ?? {};
|
|
371
|
+
const common = {
|
|
372
|
+
handles,
|
|
373
|
+
backoffConfig,
|
|
374
|
+
chainId: Number(this.chainId),
|
|
375
|
+
walletClient,
|
|
376
|
+
kmsQuorumClient: this.kmsQuorumClient,
|
|
377
|
+
executorAddress: this.executorAddress,
|
|
378
|
+
};
|
|
379
|
+
if (inputPubKey) {
|
|
380
|
+
if (inputKeypair) {
|
|
381
|
+
return attestedDecrypt({
|
|
382
|
+
...common,
|
|
383
|
+
reencryptPubKey: inputPubKey,
|
|
384
|
+
reencryptKeypair: inputKeypair,
|
|
385
|
+
});
|
|
386
|
+
}
|
|
387
|
+
return attestedDecrypt({
|
|
388
|
+
...common,
|
|
389
|
+
reencryptPubKey: inputPubKey,
|
|
390
|
+
});
|
|
391
|
+
}
|
|
392
|
+
const keypair = await generateXwingKeypair();
|
|
393
|
+
const pubKey = keypair.encodePublicKey();
|
|
394
|
+
return attestedDecrypt({
|
|
395
|
+
...common,
|
|
396
|
+
reencryptPubKey: pubKey,
|
|
397
|
+
reencryptKeypair: keypair,
|
|
398
|
+
});
|
|
399
|
+
}
|
|
400
|
+
async attestedDecryptWithVoucher(ephemeralAccount, allowanceVoucherWithSig, handles, opts) {
|
|
401
|
+
const { reencryptPubKey: inputPubKey, reencryptKeypair: inputKeypair, requesterArgData, backoffConfig, } = opts ?? {};
|
|
402
|
+
const common = {
|
|
403
|
+
backoffConfig,
|
|
404
|
+
chainId: Number(this.chainId),
|
|
405
|
+
kmsQuorumClient: this.kmsQuorumClient,
|
|
406
|
+
ephemeralAccount,
|
|
407
|
+
allowanceVoucherWithSig,
|
|
408
|
+
handles,
|
|
409
|
+
requesterArgData,
|
|
410
|
+
ethClient: this.publicClient,
|
|
411
|
+
executorAddress: this.executorAddress,
|
|
412
|
+
};
|
|
413
|
+
if (inputPubKey) {
|
|
414
|
+
if (inputKeypair) {
|
|
415
|
+
return sessionKeyAttestedDecrypt({
|
|
416
|
+
...common,
|
|
417
|
+
reencryptPubKey: inputPubKey,
|
|
418
|
+
reencryptKeypair: inputKeypair,
|
|
419
|
+
});
|
|
420
|
+
}
|
|
421
|
+
return sessionKeyAttestedDecrypt({
|
|
422
|
+
...common,
|
|
423
|
+
reencryptPubKey: inputPubKey,
|
|
424
|
+
});
|
|
425
|
+
}
|
|
426
|
+
const keypair = await generateXwingKeypair();
|
|
427
|
+
const pubKey = keypair.encodePublicKey();
|
|
428
|
+
return sessionKeyAttestedDecrypt({
|
|
429
|
+
...common,
|
|
430
|
+
reencryptPubKey: pubKey,
|
|
431
|
+
reencryptKeypair: keypair,
|
|
432
|
+
});
|
|
433
|
+
}
|
|
434
|
+
async eListAttestedDecrypt(walletClient, handle, opts) {
|
|
435
|
+
const { reencryptPubKey: inputPubKey, reencryptKeypair: inputKeypair, backoffConfig, } = opts ?? {};
|
|
436
|
+
const common = {
|
|
437
|
+
handle,
|
|
438
|
+
backoffConfig,
|
|
439
|
+
chainId: Number(this.chainId),
|
|
440
|
+
walletClient,
|
|
441
|
+
kmsQuorumClient: this.kmsQuorumClient,
|
|
442
|
+
executorAddress: this.executorAddress,
|
|
443
|
+
};
|
|
444
|
+
if (inputPubKey) {
|
|
445
|
+
if (inputKeypair) {
|
|
446
|
+
return eListAttestedDecrypt({
|
|
447
|
+
...common,
|
|
448
|
+
reencryptPubKey: inputPubKey,
|
|
449
|
+
reencryptKeypair: inputKeypair,
|
|
450
|
+
});
|
|
451
|
+
}
|
|
452
|
+
return eListAttestedDecrypt({
|
|
453
|
+
...common,
|
|
454
|
+
reencryptPubKey: inputPubKey,
|
|
455
|
+
});
|
|
456
|
+
}
|
|
457
|
+
const keypair = await generateXwingKeypair();
|
|
458
|
+
const pubKey = keypair.encodePublicKey();
|
|
459
|
+
return eListAttestedDecrypt({
|
|
460
|
+
...common,
|
|
461
|
+
reencryptPubKey: pubKey,
|
|
462
|
+
reencryptKeypair: keypair,
|
|
463
|
+
});
|
|
464
|
+
}
|
|
465
|
+
/**
|
|
466
|
+
* Reveal a single elist handle without wallet authentication.
|
|
467
|
+
* Returns plaintext values along with an attestation of the checksum.
|
|
468
|
+
*
|
|
469
|
+
* @param handle - The elist handle to reveal
|
|
470
|
+
* @param opts - Optional backoff configuration
|
|
471
|
+
* @returns The elist decryption attestation with plaintext values
|
|
472
|
+
*/
|
|
473
|
+
eListAttestedReveal(handle, opts) {
|
|
474
|
+
const { backoffConfig } = opts ?? {};
|
|
475
|
+
return performEListAttestedReveal({
|
|
476
|
+
handle,
|
|
477
|
+
backoffConfig,
|
|
478
|
+
kmsQuorumClient: this.kmsQuorumClient,
|
|
479
|
+
executorAddress: this.executorAddress,
|
|
480
|
+
publicClient: this.publicClient,
|
|
481
|
+
});
|
|
482
|
+
}
|
|
483
|
+
async attestedCompute(walletClient, lhsHandle, op, rhsPlaintext, opts) {
|
|
484
|
+
const { reencryptPubKey: inputPubKey, reencryptKeypair: inputKeypair, backoffConfig, } = opts ?? {};
|
|
485
|
+
const common = {
|
|
486
|
+
executorAddress: this.executorAddress,
|
|
487
|
+
walletClient,
|
|
488
|
+
kmsQuorumClient: this.kmsQuorumClient,
|
|
489
|
+
chainId: Number(this.chainId),
|
|
490
|
+
lhsHandle,
|
|
491
|
+
op,
|
|
492
|
+
rhsPlaintext,
|
|
493
|
+
backoffConfig,
|
|
494
|
+
};
|
|
495
|
+
if (inputPubKey) {
|
|
496
|
+
if (inputKeypair) {
|
|
497
|
+
return performAttestedCompute({
|
|
498
|
+
...common,
|
|
499
|
+
reencryptPubKey: inputPubKey,
|
|
500
|
+
reencryptKeypair: inputKeypair,
|
|
501
|
+
});
|
|
502
|
+
}
|
|
503
|
+
return performAttestedCompute({
|
|
504
|
+
...common,
|
|
505
|
+
reencryptPubKey: inputPubKey,
|
|
506
|
+
});
|
|
507
|
+
}
|
|
508
|
+
const keypair = await generateXwingKeypair();
|
|
509
|
+
const pubKey = keypair.encodePublicKey();
|
|
510
|
+
return performAttestedCompute({
|
|
511
|
+
...common,
|
|
512
|
+
reencryptPubKey: pubKey,
|
|
513
|
+
reencryptKeypair: keypair,
|
|
514
|
+
});
|
|
515
|
+
}
|
|
516
|
+
async attestedComputeWithVoucher(ephemeralAccount, allowanceVoucherWithSig, lhsHandle, op, rhsPlaintext, opts) {
|
|
517
|
+
const { reencryptPubKey: inputPubKey, reencryptKeypair: inputKeypair, requesterArgData, backoffConfig, } = opts ?? {};
|
|
518
|
+
const common = {
|
|
519
|
+
chainId: Number(this.chainId),
|
|
520
|
+
kmsQuorumClient: this.kmsQuorumClient,
|
|
521
|
+
ephemeralAccount,
|
|
522
|
+
allowanceVoucherWithSig,
|
|
523
|
+
lhsHandle,
|
|
524
|
+
op,
|
|
525
|
+
rhsPlaintext,
|
|
526
|
+
requesterArgData,
|
|
527
|
+
ethClient: this.publicClient,
|
|
528
|
+
executorAddress: this.executorAddress,
|
|
529
|
+
backoffConfig,
|
|
530
|
+
};
|
|
531
|
+
if (inputPubKey) {
|
|
532
|
+
if (inputKeypair) {
|
|
533
|
+
return sessionKeyAttestedCompute({
|
|
534
|
+
...common,
|
|
535
|
+
reencryptPubKey: inputPubKey,
|
|
536
|
+
reencryptKeypair: inputKeypair,
|
|
537
|
+
});
|
|
538
|
+
}
|
|
539
|
+
return sessionKeyAttestedCompute({
|
|
540
|
+
...common,
|
|
541
|
+
reencryptPubKey: inputPubKey,
|
|
542
|
+
});
|
|
543
|
+
}
|
|
544
|
+
const keypair = await generateXwingKeypair();
|
|
545
|
+
const pubKey = keypair.encodePublicKey();
|
|
546
|
+
return sessionKeyAttestedCompute({
|
|
547
|
+
...common,
|
|
548
|
+
reencryptPubKey: pubKey,
|
|
549
|
+
reencryptKeypair: keypair,
|
|
550
|
+
});
|
|
551
|
+
}
|
|
552
|
+
/**
|
|
553
|
+
* Get an decryption of publicly revealed handles.
|
|
554
|
+
*
|
|
555
|
+
* @param handles - The handles to decrypt
|
|
556
|
+
* @param backoffConfig - The backoff configuration for the attested decrypt request
|
|
557
|
+
* @returns The decryption attestations
|
|
558
|
+
*
|
|
559
|
+
* @example
|
|
560
|
+
* ```typescript
|
|
561
|
+
* const response = await lightning.attestedReveal([handle1, handle2]);
|
|
562
|
+
* const { plaintext, covalidatorSignature } = response[0];
|
|
563
|
+
* ```
|
|
564
|
+
*/
|
|
565
|
+
attestedReveal(handles, opts) {
|
|
566
|
+
const { backoffConfig } = opts ?? {};
|
|
567
|
+
return performAttestedReveal({
|
|
568
|
+
executorAddress: this.executorAddress,
|
|
569
|
+
handles,
|
|
570
|
+
backoffConfig,
|
|
571
|
+
kmsQuorumClient: this.kmsQuorumClient,
|
|
572
|
+
publicClient: this.publicClient,
|
|
573
|
+
});
|
|
574
|
+
}
|
|
575
|
+
/**
|
|
576
|
+
* Get the GRPC endpoint for the covalidator that services this deployment.
|
|
577
|
+
*/
|
|
578
|
+
static getCovalidatorUrls(deployment, signers) {
|
|
579
|
+
const { chainId, pepper, majorVersion } = deployment;
|
|
580
|
+
const chainShortName = chainShortNames[chainId];
|
|
581
|
+
if (!chainShortName) {
|
|
582
|
+
throw new Error(`Unsupported chainId ${chainId} for covalidator URL generation`);
|
|
583
|
+
}
|
|
584
|
+
return signers.map((signer) => {
|
|
585
|
+
return `https://${signer.toLowerCase()}.${majorVersion}.covalidator.${chainShortName}.${pepper}.inco.org`;
|
|
586
|
+
});
|
|
587
|
+
}
|
|
588
|
+
static isIdByName(id) {
|
|
589
|
+
return id.name !== undefined;
|
|
590
|
+
}
|
|
591
|
+
static plaintextFromValue(value, type, scheme) {
|
|
592
|
+
if (typeof value === 'boolean') {
|
|
593
|
+
return {
|
|
594
|
+
scheme,
|
|
595
|
+
type: handleTypes.ebool,
|
|
596
|
+
value: value,
|
|
597
|
+
};
|
|
598
|
+
}
|
|
599
|
+
else if (typeof value === 'bigint' || typeof value === 'number') {
|
|
600
|
+
return {
|
|
601
|
+
scheme,
|
|
602
|
+
type: type ?? handleTypes.euint256,
|
|
603
|
+
value: BigInt(value),
|
|
604
|
+
};
|
|
605
|
+
}
|
|
606
|
+
else {
|
|
607
|
+
throw new Error(`Unsupported type ${typeof value}`);
|
|
608
|
+
}
|
|
609
|
+
}
|
|
610
|
+
/**
|
|
611
|
+
* Reads the network public key from the on-chain Inco Verifier contract.
|
|
612
|
+
*
|
|
613
|
+
* Falls back to the legacy `eciesPubkey()` getter for older contract versions.
|
|
614
|
+
*
|
|
615
|
+
* @param client - A viem public client connected to the host chain.
|
|
616
|
+
* @param executorAddress - The address of the Inco Lightning executor contract.
|
|
617
|
+
* @returns The network public key as a hex string.
|
|
618
|
+
*/
|
|
619
|
+
static async getNetworkPubkey(client, executorAddress) {
|
|
620
|
+
const incoVerifier = await Lightning.getIncoVerifierContract(client, executorAddress);
|
|
621
|
+
// TODO: Switch to use a version check instead of a try/catch
|
|
622
|
+
// See https://github.com/Inco-fhevm/inco-monorepo/blob/e17d940a6720d94c53e6b0bf12704b6097116821/js/src/lite/lightning.ts#L1164
|
|
623
|
+
// for now it's done.
|
|
624
|
+
try {
|
|
625
|
+
return await incoVerifier.read.networkPubkey();
|
|
626
|
+
}
|
|
627
|
+
catch (error) {
|
|
628
|
+
throw new Error('Network public key not found most probably you are using an old deployment or a wrong pepper', { cause: error });
|
|
629
|
+
}
|
|
630
|
+
}
|
|
631
|
+
/**
|
|
632
|
+
* Resolves the Inco Verifier contract instance associated with a Lightning executor.
|
|
633
|
+
*
|
|
634
|
+
* Reads the `incoVerifier` address from the executor contract and returns a typed contract handle.
|
|
635
|
+
*
|
|
636
|
+
* @param client - A viem public client connected to the host chain.
|
|
637
|
+
* @param executorAddress - The address of the Inco Lightning executor contract.
|
|
638
|
+
* @returns A viem contract instance bound to the Inco Verifier ABI.
|
|
639
|
+
*/
|
|
640
|
+
static async getIncoVerifierContract(client, executorAddress) {
|
|
641
|
+
const incoLightningContract = getContract({
|
|
642
|
+
abi: incoLightningAbi,
|
|
643
|
+
address: executorAddress,
|
|
644
|
+
client,
|
|
645
|
+
});
|
|
646
|
+
const incoVerifierAddress = await incoLightningContract.read.incoVerifier();
|
|
647
|
+
const incoVerifier = getContract({
|
|
648
|
+
abi: incoVerifierAbi,
|
|
649
|
+
address: incoVerifierAddress,
|
|
650
|
+
client,
|
|
651
|
+
});
|
|
652
|
+
return incoVerifier;
|
|
653
|
+
}
|
|
654
|
+
/**
|
|
655
|
+
* Retrieves the verifier contract details including threshold, signers, and XWING public key from the Inco Verifier contract.
|
|
656
|
+
*
|
|
657
|
+
* @param executorAddress The address of the Inco Lightning executor contract.
|
|
658
|
+
* @param client The public client to interact with the blockchain.
|
|
659
|
+
* @returns An object containing the threshold, signers, and XWING public key.
|
|
660
|
+
*/
|
|
661
|
+
static async getVerifierContractDetails(executorAddress, client) {
|
|
662
|
+
const incoVerifier = await Lightning.getIncoVerifierContract(client, executorAddress);
|
|
663
|
+
const threshold = await incoVerifier.read.getThreshold();
|
|
664
|
+
const networkPubkey = await Lightning.getNetworkPubkey(client, executorAddress);
|
|
665
|
+
const signersCount = await incoVerifier.read.getSignersCount();
|
|
666
|
+
const signersPromises = [];
|
|
667
|
+
for (let i = BigInt(0); i < signersCount; i++) {
|
|
668
|
+
signersPromises.push(incoVerifier.read.getSignerAtIndex([i]));
|
|
669
|
+
}
|
|
670
|
+
const signers = await Promise.all(signersPromises);
|
|
671
|
+
return {
|
|
672
|
+
threshold: Number(threshold),
|
|
673
|
+
signers: signers.map(parseAddress),
|
|
674
|
+
networkPubkey,
|
|
675
|
+
};
|
|
676
|
+
}
|
|
677
|
+
static async getChainConfig(deployment, client) {
|
|
678
|
+
if (this.supportsThresholdRetrieval(deployment)) {
|
|
679
|
+
return await this.getVerifierContractDetails(deployment.executorAddress, client);
|
|
680
|
+
}
|
|
681
|
+
throw new Error('Threshold retrieval not supported for this deployment');
|
|
682
|
+
}
|
|
683
|
+
// Check if the deployment supports threshold retrieval based on its version
|
|
684
|
+
static supportsThresholdRetrieval(deployment) {
|
|
685
|
+
// Assumes that the threshold retrieval is supported if the smart contract / deployment version is greater than or equal to 1.1.0
|
|
686
|
+
if (!deployment.version)
|
|
687
|
+
throw new Error('Deployment version is undefined');
|
|
688
|
+
const { major, minor } = deployment.version;
|
|
689
|
+
return major > 1 || (major === 1 && minor >= 1);
|
|
690
|
+
}
|
|
691
|
+
}
|
|
692
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibGlnaHRuaW5nLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2xpdGUvbGlnaHRuaW5nLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFHTCxrQkFBa0IsRUFDbEIsUUFBUSxFQUNSLFdBQVcsRUFFWCxVQUFVLEVBQ1YsSUFBSSxHQUlMLE1BQU0sTUFBTSxDQUFDO0FBRWQsT0FBTyxFQUFFLElBQUksRUFBRSxXQUFXLEVBQUUsTUFBTSxhQUFhLENBQUM7QUFDaEQsT0FBTyxFQUNMLGVBQWUsRUFDZiw2QkFBNkIsRUFDN0IseUJBQXlCLEVBQ3pCLHlCQUF5QixFQUN6QixnQ0FBZ0MsR0FDakMsTUFBTSwrQkFBK0IsQ0FBQztBQUV2QyxPQUFPLEVBQUUsZUFBZSxJQUFJLHNCQUFzQixFQUFFLE1BQU0sd0NBQXdDLENBQUM7QUFFbkcsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLHdDQUF3QyxDQUFDO0FBS3pFLE9BQU8sRUFBRSxjQUFjLElBQUkscUJBQXFCLEVBQUUsTUFBTSxzQ0FBc0MsQ0FBQztBQUMvRixPQUFPLEVBQVcsU0FBUyxFQUFFLFlBQVksRUFBRSxNQUFNLGNBQWMsQ0FBQztBQUNoRSxPQUFPLEVBQUUsZUFBZSxFQUFvQixNQUFNLGFBQWEsQ0FBQztBQUNoRSxPQUFPLEVBQ0wsb0JBQW9CLEVBQ3BCLG1CQUFtQixJQUFJLDBCQUEwQixHQUNsRCxNQUFNLG1EQUFtRCxDQUFDO0FBSzNELE9BQU8sRUFFTCxpQkFBaUIsR0FJbEIsTUFBTSw2QkFBNkIsQ0FBQztBQUNyQyxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSxnQ0FBZ0MsQ0FBQztBQUNsRSxPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0sK0JBQStCLENBQUM7QUFDaEUsT0FBTyxFQUFFLG9CQUFvQixFQUFFLE1BQU0sMkJBQTJCLENBQUM7QUFDakUsT0FBTyxFQUFFLHdCQUF3QixFQUFFLE1BQU0sNEJBQTRCLENBQUM7QUFDdEUsT0FBTyxF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
|