@sip-protocol/sdk 0.7.2 → 0.7.4
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 +21 -0
- package/README.md +267 -0
- package/dist/{TransportWebUSB-TQ7WZ4LE.mjs → TransportWebUSB-YQMAGJAJ.mjs} +12 -9
- package/dist/browser.d.mts +10 -4
- package/dist/browser.d.ts +10 -4
- package/dist/browser.js +48874 -18336
- package/dist/browser.mjs +674 -48
- package/dist/chunk-4GRJ5MAW.mjs +152 -0
- package/dist/chunk-5D7A3L3W.mjs +717 -0
- package/dist/chunk-64AYA5F5.mjs +7834 -0
- package/dist/chunk-GMDGB22A.mjs +379 -0
- package/dist/chunk-I534WKN7.mjs +328 -0
- package/dist/chunk-IBZVA5Y7.mjs +1003 -0
- package/dist/chunk-PRRZAWJE.mjs +223 -0
- package/dist/{chunk-UJCSKKID.mjs → chunk-XGB3TDIC.mjs} +13 -1
- package/dist/chunk-YWGJ77A2.mjs +33806 -0
- package/dist/{chunk-6WGN57S2.mjs → chunk-Z3K7W5S3.mjs} +48 -0
- package/dist/constants-LHAAUC2T.mjs +51 -0
- package/dist/dist-2OGQ7FED.mjs +3957 -0
- package/dist/dist-IFHPYLDX.mjs +254 -0
- package/dist/fulfillment_proof-ANHVPKTB.mjs +21 -0
- package/dist/funding_proof-ICFZ5LHY.mjs +21 -0
- package/dist/index-DXh2IGkz.d.ts +24681 -0
- package/dist/index-DeE1ZzA4.d.mts +24681 -0
- package/dist/index.d.mts +9 -3
- package/dist/index.d.ts +9 -3
- package/dist/index.js +48676 -17318
- package/dist/index.mjs +583 -19
- package/dist/interface-Bf7w1PLW.d.mts +679 -0
- package/dist/interface-Bf7w1PLW.d.ts +679 -0
- package/dist/{noir-DKfEzWy9.d.mts → noir-kzbLVTei.d.mts} +31 -21
- package/dist/{noir-DKfEzWy9.d.ts → noir-kzbLVTei.d.ts} +31 -21
- package/dist/proofs/halo2.d.mts +151 -0
- package/dist/proofs/halo2.d.ts +151 -0
- package/dist/proofs/halo2.js +350 -0
- package/dist/proofs/halo2.mjs +11 -0
- package/dist/proofs/kimchi.d.mts +160 -0
- package/dist/proofs/kimchi.d.ts +160 -0
- package/dist/proofs/kimchi.js +431 -0
- package/dist/proofs/kimchi.mjs +13 -0
- package/dist/proofs/noir.d.mts +1 -1
- package/dist/proofs/noir.d.ts +1 -1
- package/dist/proofs/noir.js +74 -18
- package/dist/proofs/noir.mjs +84 -24
- package/dist/solana-U3MEGU7W.mjs +280 -0
- package/dist/validity_proof-3POXLPNY.mjs +21 -0
- package/package.json +54 -21
- package/src/adapters/index.ts +41 -0
- package/src/adapters/jupiter.ts +571 -0
- package/src/adapters/near-intents.ts +135 -0
- package/src/advisor/advisor.ts +653 -0
- package/src/advisor/index.ts +54 -0
- package/src/advisor/tools.ts +303 -0
- package/src/advisor/types.ts +164 -0
- package/src/chains/ethereum/announcement.ts +536 -0
- package/src/chains/ethereum/bnb-optimizations.ts +474 -0
- package/src/chains/ethereum/commitment.ts +522 -0
- package/src/chains/ethereum/constants.ts +462 -0
- package/src/chains/ethereum/deployment.ts +596 -0
- package/src/chains/ethereum/gas-estimation.ts +538 -0
- package/src/chains/ethereum/index.ts +268 -0
- package/src/chains/ethereum/optimizations.ts +614 -0
- package/src/chains/ethereum/privacy-adapter.ts +855 -0
- package/src/chains/ethereum/registry.ts +584 -0
- package/src/chains/ethereum/rpc.ts +905 -0
- package/src/chains/ethereum/stealth.ts +491 -0
- package/src/chains/ethereum/token.ts +790 -0
- package/src/chains/ethereum/transfer.ts +637 -0
- package/src/chains/ethereum/types.ts +456 -0
- package/src/chains/ethereum/viewing-key.ts +455 -0
- package/src/chains/near/commitment.ts +608 -0
- package/src/chains/near/constants.ts +284 -0
- package/src/chains/near/function-call.ts +871 -0
- package/src/chains/near/history.ts +654 -0
- package/src/chains/near/implicit-account.ts +840 -0
- package/src/chains/near/index.ts +393 -0
- package/src/chains/near/native-transfer.ts +658 -0
- package/src/chains/near/nep141.ts +775 -0
- package/src/chains/near/privacy-adapter.ts +889 -0
- package/src/chains/near/resolver.ts +971 -0
- package/src/chains/near/rpc.ts +1016 -0
- package/src/chains/near/stealth.ts +419 -0
- package/src/chains/near/types.ts +317 -0
- package/src/chains/near/viewing-key.ts +876 -0
- package/src/chains/solana/anchor-transfer.ts +386 -0
- package/src/chains/solana/commitment.ts +577 -0
- package/src/chains/solana/constants.ts +126 -12
- package/src/chains/solana/ephemeral-keys.ts +543 -0
- package/src/chains/solana/index.ts +276 -1
- package/src/chains/solana/key-derivation.ts +418 -0
- package/src/chains/solana/kit-compat.ts +334 -0
- package/src/chains/solana/optimizations.ts +560 -0
- package/src/chains/solana/privacy-adapter.ts +605 -0
- package/src/chains/solana/providers/generic.ts +201 -0
- package/src/chains/solana/providers/helius-enhanced-types.ts +336 -0
- package/src/chains/solana/providers/helius-enhanced.ts +623 -0
- package/src/chains/solana/providers/helius.ts +402 -0
- package/src/chains/solana/providers/index.ts +85 -0
- package/src/chains/solana/providers/interface.ts +221 -0
- package/src/chains/solana/providers/quicknode.ts +409 -0
- package/src/chains/solana/providers/triton.ts +426 -0
- package/src/chains/solana/providers/webhook.ts +790 -0
- package/src/chains/solana/rpc-client.ts +1150 -0
- package/src/chains/solana/scan.ts +170 -73
- package/src/chains/solana/sol-transfer.ts +732 -0
- package/src/chains/solana/spl-transfer.ts +886 -0
- package/src/chains/solana/stealth-scanner.ts +703 -0
- package/src/chains/solana/sunspot-verifier.ts +453 -0
- package/src/chains/solana/transaction-builder.ts +755 -0
- package/src/chains/solana/transfer.ts +74 -5
- package/src/chains/solana/types.ts +77 -7
- package/src/chains/solana/utils.ts +110 -0
- package/src/chains/solana/viewing-key.ts +807 -0
- package/src/compliance/fireblocks.ts +921 -0
- package/src/compliance/index.ts +37 -0
- package/src/compliance/range-sas.ts +956 -0
- package/src/config/endpoints.ts +100 -0
- package/src/crypto.ts +11 -8
- package/src/errors.ts +82 -0
- package/src/evm/erc4337-relayer.ts +830 -0
- package/src/evm/index.ts +47 -0
- package/src/fees/calculator.ts +396 -0
- package/src/fees/index.ts +87 -0
- package/src/fees/near-contract.ts +429 -0
- package/src/fees/types.ts +268 -0
- package/src/index.ts +785 -1
- package/src/intent.ts +6 -3
- package/src/logger.ts +324 -0
- package/src/network/index.ts +80 -0
- package/src/network/proxy.ts +691 -0
- package/src/optimizations/index.ts +541 -0
- package/src/oracle/types.ts +1 -0
- package/src/privacy-backends/arcium-types.ts +727 -0
- package/src/privacy-backends/arcium.ts +719 -0
- package/src/privacy-backends/combined-privacy.ts +866 -0
- package/src/privacy-backends/cspl-token.ts +595 -0
- package/src/privacy-backends/cspl-types.ts +512 -0
- package/src/privacy-backends/cspl.ts +907 -0
- package/src/privacy-backends/health.ts +488 -0
- package/src/privacy-backends/inco-types.ts +323 -0
- package/src/privacy-backends/inco.ts +616 -0
- package/src/privacy-backends/index.ts +336 -0
- package/src/privacy-backends/interface.ts +906 -0
- package/src/privacy-backends/lru-cache.ts +343 -0
- package/src/privacy-backends/magicblock.ts +458 -0
- package/src/privacy-backends/mock.ts +258 -0
- package/src/privacy-backends/privacycash-types.ts +278 -0
- package/src/privacy-backends/privacycash.ts +456 -0
- package/src/privacy-backends/private-swap.ts +570 -0
- package/src/privacy-backends/rate-limiter.ts +683 -0
- package/src/privacy-backends/registry.ts +690 -0
- package/src/privacy-backends/router.ts +626 -0
- package/src/privacy-backends/shadowwire.ts +449 -0
- package/src/privacy-backends/sip-native.ts +256 -0
- package/src/privacy-logger.ts +191 -0
- package/src/production-safety.ts +373 -0
- package/src/proofs/aggregator.ts +1029 -0
- package/src/proofs/browser-composer.ts +1150 -0
- package/src/proofs/browser.ts +113 -25
- package/src/proofs/cache/index.ts +127 -0
- package/src/proofs/cache/interface.ts +545 -0
- package/src/proofs/cache/key-generator.ts +188 -0
- package/src/proofs/cache/lru-cache.ts +481 -0
- package/src/proofs/cache/multi-tier-cache.ts +575 -0
- package/src/proofs/cache/persistent-cache.ts +788 -0
- package/src/proofs/compliance-proof.ts +872 -0
- package/src/proofs/composer/base.ts +923 -0
- package/src/proofs/composer/index.ts +25 -0
- package/src/proofs/composer/interface.ts +518 -0
- package/src/proofs/composer/types.ts +383 -0
- package/src/proofs/converters/halo2.ts +452 -0
- package/src/proofs/converters/index.ts +208 -0
- package/src/proofs/converters/interface.ts +363 -0
- package/src/proofs/converters/kimchi.ts +462 -0
- package/src/proofs/converters/noir.ts +451 -0
- package/src/proofs/fallback.ts +888 -0
- package/src/proofs/halo2.ts +42 -0
- package/src/proofs/index.ts +471 -0
- package/src/proofs/interface.ts +13 -0
- package/src/proofs/kimchi.ts +42 -0
- package/src/proofs/lazy.ts +1004 -0
- package/src/proofs/mock.ts +25 -1
- package/src/proofs/noir.ts +111 -30
- package/src/proofs/orchestrator.ts +960 -0
- package/src/proofs/parallel/concurrency.ts +297 -0
- package/src/proofs/parallel/dependency-graph.ts +602 -0
- package/src/proofs/parallel/executor.ts +420 -0
- package/src/proofs/parallel/index.ts +131 -0
- package/src/proofs/parallel/interface.ts +685 -0
- package/src/proofs/parallel/worker-pool.ts +644 -0
- package/src/proofs/providers/halo2.ts +560 -0
- package/src/proofs/providers/index.ts +34 -0
- package/src/proofs/providers/kimchi.ts +641 -0
- package/src/proofs/validator.ts +881 -0
- package/src/proofs/verifier.ts +867 -0
- package/src/quantum/index.ts +112 -0
- package/src/quantum/winternitz-vault.ts +639 -0
- package/src/quantum/wots.ts +611 -0
- package/src/settlement/backends/direct-chain.ts +1 -0
- package/src/settlement/index.ts +9 -0
- package/src/settlement/router.ts +732 -46
- package/src/solana/index.ts +72 -0
- package/src/solana/jito-relayer.ts +687 -0
- package/src/solana/noir-verifier-types.ts +430 -0
- package/src/solana/noir-verifier.ts +816 -0
- package/src/stealth/address-derivation.ts +193 -0
- package/src/stealth/ed25519.ts +431 -0
- package/src/stealth/index.ts +233 -0
- package/src/stealth/meta-address.ts +221 -0
- package/src/stealth/secp256k1.ts +368 -0
- package/src/stealth/utils.ts +194 -0
- package/src/stealth.ts +50 -1504
- package/src/surveillance/algorithms/address-reuse.ts +143 -0
- package/src/surveillance/algorithms/cluster.ts +247 -0
- package/src/surveillance/algorithms/exchange.ts +295 -0
- package/src/surveillance/algorithms/temporal.ts +337 -0
- package/src/surveillance/analyzer.ts +442 -0
- package/src/surveillance/index.ts +64 -0
- package/src/surveillance/scoring.ts +372 -0
- package/src/surveillance/types.ts +264 -0
- package/src/sync/index.ts +106 -0
- package/src/sync/manager.ts +504 -0
- package/src/sync/mock-provider.ts +318 -0
- package/src/sync/oblivious.ts +625 -0
- package/src/tokens/index.ts +15 -0
- package/src/tokens/registry.ts +301 -0
- package/src/utils/deprecation.ts +94 -0
- package/src/utils/index.ts +9 -0
- package/src/wallet/ethereum/index.ts +68 -0
- package/src/wallet/ethereum/metamask-privacy.ts +420 -0
- package/src/wallet/ethereum/multi-wallet.ts +646 -0
- package/src/wallet/ethereum/privacy-adapter.ts +700 -0
- package/src/wallet/ethereum/types.ts +3 -1
- package/src/wallet/ethereum/walletconnect-adapter.ts +675 -0
- package/src/wallet/hardware/index.ts +10 -0
- package/src/wallet/hardware/ledger-privacy.ts +414 -0
- package/src/wallet/index.ts +71 -0
- package/src/wallet/near/adapter.ts +626 -0
- package/src/wallet/near/index.ts +86 -0
- package/src/wallet/near/meteor-wallet.ts +1153 -0
- package/src/wallet/near/my-near-wallet.ts +790 -0
- package/src/wallet/near/wallet-selector.ts +702 -0
- package/src/wallet/solana/adapter.ts +6 -4
- package/src/wallet/solana/index.ts +13 -0
- package/src/wallet/solana/privacy-adapter.ts +567 -0
- package/src/wallet/sui/types.ts +6 -4
- package/src/zcash/rpc-client.ts +13 -6
- package/dist/chunk-3INS3PR5.mjs +0 -884
- package/dist/chunk-3OVABDRH.mjs +0 -17096
- package/dist/chunk-DLDWZFYC.mjs +0 -1495
- package/dist/chunk-E6SZWREQ.mjs +0 -57
- package/dist/chunk-G33LB27A.mjs +0 -16166
- package/dist/chunk-HGU6HZRC.mjs +0 -231
- package/dist/chunk-L2K34JCU.mjs +0 -1496
- package/dist/chunk-SN4ZDTVW.mjs +0 -16166
- package/dist/constants-VOI7BSLK.mjs +0 -27
- package/dist/index-BYZbDjal.d.ts +0 -11390
- package/dist/index-CHB3KuOB.d.mts +0 -11859
- package/dist/index-CzWPI6Le.d.ts +0 -11859
- package/dist/index-xbWjohNq.d.mts +0 -11390
- package/dist/solana-5EMCTPTS.mjs +0 -46
- package/dist/solana-Q4NAVBTS.mjs +0 -46
|
@@ -0,0 +1,453 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Sunspot ZK Proof Verifier Integration
|
|
3
|
+
*
|
|
4
|
+
* Enables verification of Noir ZK proofs on Solana via Groth16.
|
|
5
|
+
*
|
|
6
|
+
* ## Pipeline
|
|
7
|
+
*
|
|
8
|
+
* ```
|
|
9
|
+
* Noir Circuit → ACIR → Groth16 Proof → Solana Verifier Program
|
|
10
|
+
* ```
|
|
11
|
+
*
|
|
12
|
+
* ## Proof Types
|
|
13
|
+
*
|
|
14
|
+
* - `funding` - Prove balance >= minimum without revealing balance
|
|
15
|
+
* - `ownership` - Prove stealth key ownership
|
|
16
|
+
* - `validity` - Prove intent authorization
|
|
17
|
+
*
|
|
18
|
+
* @example
|
|
19
|
+
* ```typescript
|
|
20
|
+
* import { SunspotVerifier, ProofType } from '@sip-protocol/sdk'
|
|
21
|
+
*
|
|
22
|
+
* const verifier = new SunspotVerifier({
|
|
23
|
+
* fundingVerifierProgram: 'FUNDxxxx...',
|
|
24
|
+
* ownershipVerifierProgram: 'OWNRxxxx...',
|
|
25
|
+
* })
|
|
26
|
+
*
|
|
27
|
+
* // Verify a proof on-chain
|
|
28
|
+
* const result = await verifier.verify({
|
|
29
|
+
* connection,
|
|
30
|
+
* proofType: ProofType.Funding,
|
|
31
|
+
* proof: proofBytes,
|
|
32
|
+
* publicInputs: [commitmentHash, minimumRequired, assetId],
|
|
33
|
+
* payer: wallet.publicKey,
|
|
34
|
+
* signTransaction: wallet.signTransaction,
|
|
35
|
+
* })
|
|
36
|
+
*
|
|
37
|
+
* console.log('Verified:', result.verified)
|
|
38
|
+
* console.log('CU used:', result.computeUnits)
|
|
39
|
+
* ```
|
|
40
|
+
*
|
|
41
|
+
* @packageDocumentation
|
|
42
|
+
*/
|
|
43
|
+
|
|
44
|
+
import {
|
|
45
|
+
PublicKey,
|
|
46
|
+
Connection,
|
|
47
|
+
Transaction,
|
|
48
|
+
TransactionInstruction,
|
|
49
|
+
ComputeBudgetProgram,
|
|
50
|
+
} from '@solana/web3.js'
|
|
51
|
+
import { ValidationError } from '../../errors'
|
|
52
|
+
import type { HexString } from '@sip-protocol/types'
|
|
53
|
+
import { hexToBytes } from '@noble/hashes/utils'
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Supported proof types
|
|
57
|
+
*/
|
|
58
|
+
export enum ProofType {
|
|
59
|
+
/** Prove balance >= minimum without revealing balance */
|
|
60
|
+
Funding = 'funding',
|
|
61
|
+
/** Prove stealth key ownership for claiming */
|
|
62
|
+
Ownership = 'ownership',
|
|
63
|
+
/** Prove intent authorization */
|
|
64
|
+
Validity = 'validity',
|
|
65
|
+
/** Prove fulfillment correctness */
|
|
66
|
+
Fulfillment = 'fulfillment',
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Configuration for Sunspot verifier
|
|
71
|
+
*/
|
|
72
|
+
export interface SunspotVerifierConfig {
|
|
73
|
+
/** Program ID for funding proof verifier */
|
|
74
|
+
fundingVerifierProgram?: PublicKey | string
|
|
75
|
+
/** Program ID for ownership proof verifier */
|
|
76
|
+
ownershipVerifierProgram?: PublicKey | string
|
|
77
|
+
/** Program ID for validity proof verifier */
|
|
78
|
+
validityVerifierProgram?: PublicKey | string
|
|
79
|
+
/** Program ID for fulfillment proof verifier */
|
|
80
|
+
fulfillmentVerifierProgram?: PublicKey | string
|
|
81
|
+
/** Compute units to request (default: 300,000) */
|
|
82
|
+
computeUnits?: number
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Parameters for proof verification
|
|
87
|
+
*/
|
|
88
|
+
export interface VerifyProofParams {
|
|
89
|
+
/** Solana connection */
|
|
90
|
+
connection: Connection
|
|
91
|
+
/** Type of proof being verified */
|
|
92
|
+
proofType: ProofType
|
|
93
|
+
/** Serialized Groth16 proof bytes */
|
|
94
|
+
proof: Uint8Array | HexString
|
|
95
|
+
/** Public inputs for the proof */
|
|
96
|
+
publicInputs: (Uint8Array | HexString | bigint)[]
|
|
97
|
+
/** Payer for transaction */
|
|
98
|
+
payer: PublicKey
|
|
99
|
+
/** Transaction signer */
|
|
100
|
+
signTransaction: <T extends Transaction>(tx: T) => Promise<T>
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* Result of proof verification
|
|
105
|
+
*/
|
|
106
|
+
export interface VerifyProofResult {
|
|
107
|
+
/** Whether the proof was verified successfully */
|
|
108
|
+
verified: boolean
|
|
109
|
+
/** Transaction signature */
|
|
110
|
+
signature: string
|
|
111
|
+
/** Compute units used */
|
|
112
|
+
computeUnits: number
|
|
113
|
+
/** Error message if verification failed */
|
|
114
|
+
error?: string
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* Groth16 proof structure
|
|
119
|
+
*/
|
|
120
|
+
export interface Groth16Proof {
|
|
121
|
+
/** Proof A point (G1, 64 bytes uncompressed or 33 compressed) */
|
|
122
|
+
a: Uint8Array
|
|
123
|
+
/** Proof B point (G2, 128 bytes uncompressed or 65 compressed) */
|
|
124
|
+
b: Uint8Array
|
|
125
|
+
/** Proof C point (G1, 64 bytes uncompressed or 33 compressed) */
|
|
126
|
+
c: Uint8Array
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
/**
|
|
130
|
+
* Default compute units for verification
|
|
131
|
+
*/
|
|
132
|
+
const DEFAULT_COMPUTE_UNITS = 300_000
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* Expected proof sizes
|
|
136
|
+
*/
|
|
137
|
+
const PROOF_SIZE = {
|
|
138
|
+
/** Compressed G1 point */
|
|
139
|
+
G1_COMPRESSED: 33,
|
|
140
|
+
/** Uncompressed G1 point */
|
|
141
|
+
G1_UNCOMPRESSED: 64,
|
|
142
|
+
/** Compressed G2 point */
|
|
143
|
+
G2_COMPRESSED: 65,
|
|
144
|
+
/** Uncompressed G2 point */
|
|
145
|
+
G2_UNCOMPRESSED: 128,
|
|
146
|
+
/** Typical Groth16 proof size (uncompressed) */
|
|
147
|
+
GROTH16_UNCOMPRESSED: 256, // a(64) + b(128) + c(64)
|
|
148
|
+
/** Typical Groth16 proof size (compressed) */
|
|
149
|
+
GROTH16_COMPRESSED: 131, // a(33) + b(65) + c(33)
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
/**
|
|
153
|
+
* Sunspot ZK Proof Verifier
|
|
154
|
+
*
|
|
155
|
+
* Provides on-chain verification of Noir ZK proofs via Groth16.
|
|
156
|
+
*/
|
|
157
|
+
export class SunspotVerifier {
|
|
158
|
+
private config: SunspotVerifierConfig
|
|
159
|
+
private verifierPrograms: Map<ProofType, PublicKey>
|
|
160
|
+
|
|
161
|
+
/**
|
|
162
|
+
* Create a new Sunspot verifier
|
|
163
|
+
*
|
|
164
|
+
* @param config - Verifier configuration with program IDs
|
|
165
|
+
*/
|
|
166
|
+
constructor(config: SunspotVerifierConfig = {}) {
|
|
167
|
+
this.config = {
|
|
168
|
+
computeUnits: DEFAULT_COMPUTE_UNITS,
|
|
169
|
+
...config,
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
this.verifierPrograms = new Map()
|
|
173
|
+
|
|
174
|
+
// Initialize program mappings
|
|
175
|
+
if (config.fundingVerifierProgram) {
|
|
176
|
+
this.verifierPrograms.set(
|
|
177
|
+
ProofType.Funding,
|
|
178
|
+
toPublicKey(config.fundingVerifierProgram)
|
|
179
|
+
)
|
|
180
|
+
}
|
|
181
|
+
if (config.ownershipVerifierProgram) {
|
|
182
|
+
this.verifierPrograms.set(
|
|
183
|
+
ProofType.Ownership,
|
|
184
|
+
toPublicKey(config.ownershipVerifierProgram)
|
|
185
|
+
)
|
|
186
|
+
}
|
|
187
|
+
if (config.validityVerifierProgram) {
|
|
188
|
+
this.verifierPrograms.set(
|
|
189
|
+
ProofType.Validity,
|
|
190
|
+
toPublicKey(config.validityVerifierProgram)
|
|
191
|
+
)
|
|
192
|
+
}
|
|
193
|
+
if (config.fulfillmentVerifierProgram) {
|
|
194
|
+
this.verifierPrograms.set(
|
|
195
|
+
ProofType.Fulfillment,
|
|
196
|
+
toPublicKey(config.fulfillmentVerifierProgram)
|
|
197
|
+
)
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
/**
|
|
202
|
+
* Get the verifier program for a proof type
|
|
203
|
+
*/
|
|
204
|
+
getVerifierProgram(proofType: ProofType): PublicKey | undefined {
|
|
205
|
+
return this.verifierPrograms.get(proofType)
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
/**
|
|
209
|
+
* Check if a proof type is supported
|
|
210
|
+
*/
|
|
211
|
+
isSupported(proofType: ProofType): boolean {
|
|
212
|
+
return this.verifierPrograms.has(proofType)
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
/**
|
|
216
|
+
* Verify a ZK proof on-chain
|
|
217
|
+
*
|
|
218
|
+
* @param params - Verification parameters
|
|
219
|
+
* @returns Verification result
|
|
220
|
+
*/
|
|
221
|
+
async verify(params: VerifyProofParams): Promise<VerifyProofResult> {
|
|
222
|
+
const {
|
|
223
|
+
connection,
|
|
224
|
+
proofType,
|
|
225
|
+
proof,
|
|
226
|
+
publicInputs,
|
|
227
|
+
payer,
|
|
228
|
+
signTransaction,
|
|
229
|
+
} = params
|
|
230
|
+
|
|
231
|
+
// Get verifier program
|
|
232
|
+
const verifierProgram = this.verifierPrograms.get(proofType)
|
|
233
|
+
if (!verifierProgram) {
|
|
234
|
+
throw new ValidationError(
|
|
235
|
+
`No verifier program configured for ${proofType}`,
|
|
236
|
+
'proofType'
|
|
237
|
+
)
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
// Convert proof to bytes
|
|
241
|
+
const proofBytes = toBytes(proof)
|
|
242
|
+
|
|
243
|
+
// Validate proof size
|
|
244
|
+
if (
|
|
245
|
+
proofBytes.length !== PROOF_SIZE.GROTH16_UNCOMPRESSED &&
|
|
246
|
+
proofBytes.length !== PROOF_SIZE.GROTH16_COMPRESSED
|
|
247
|
+
) {
|
|
248
|
+
throw new ValidationError(
|
|
249
|
+
`Invalid proof size: ${proofBytes.length} bytes. Expected ${PROOF_SIZE.GROTH16_COMPRESSED} or ${PROOF_SIZE.GROTH16_UNCOMPRESSED}`,
|
|
250
|
+
'proof'
|
|
251
|
+
)
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
// Convert public inputs to bytes
|
|
255
|
+
const publicInputBytes = publicInputs.map((input) => {
|
|
256
|
+
if (typeof input === 'bigint') {
|
|
257
|
+
return bigintToBytes32(input)
|
|
258
|
+
}
|
|
259
|
+
return toBytes(input)
|
|
260
|
+
})
|
|
261
|
+
|
|
262
|
+
// Build instruction data: [proof_bytes][public_inputs]
|
|
263
|
+
const instructionData = Buffer.concat([
|
|
264
|
+
proofBytes,
|
|
265
|
+
...publicInputBytes.map((b) => Buffer.from(b)),
|
|
266
|
+
])
|
|
267
|
+
|
|
268
|
+
// Build transaction
|
|
269
|
+
const transaction = new Transaction()
|
|
270
|
+
|
|
271
|
+
// Add compute budget
|
|
272
|
+
transaction.add(
|
|
273
|
+
ComputeBudgetProgram.setComputeUnitLimit({
|
|
274
|
+
units: this.config.computeUnits!,
|
|
275
|
+
})
|
|
276
|
+
)
|
|
277
|
+
|
|
278
|
+
// Add verify instruction
|
|
279
|
+
transaction.add(
|
|
280
|
+
new TransactionInstruction({
|
|
281
|
+
keys: [], // Verifier programs typically don't need accounts
|
|
282
|
+
programId: verifierProgram,
|
|
283
|
+
data: instructionData,
|
|
284
|
+
})
|
|
285
|
+
)
|
|
286
|
+
|
|
287
|
+
// Get blockhash
|
|
288
|
+
const { blockhash, lastValidBlockHeight } =
|
|
289
|
+
await connection.getLatestBlockhash()
|
|
290
|
+
transaction.recentBlockhash = blockhash
|
|
291
|
+
transaction.feePayer = payer
|
|
292
|
+
|
|
293
|
+
try {
|
|
294
|
+
// Sign and send
|
|
295
|
+
const signedTx = await signTransaction(transaction)
|
|
296
|
+
const signature = await connection.sendRawTransaction(signedTx.serialize())
|
|
297
|
+
|
|
298
|
+
// Confirm and get logs
|
|
299
|
+
const confirmation = await connection.confirmTransaction({
|
|
300
|
+
signature,
|
|
301
|
+
blockhash,
|
|
302
|
+
lastValidBlockHeight,
|
|
303
|
+
})
|
|
304
|
+
|
|
305
|
+
if (confirmation.value.err) {
|
|
306
|
+
return {
|
|
307
|
+
verified: false,
|
|
308
|
+
signature,
|
|
309
|
+
computeUnits: this.config.computeUnits!,
|
|
310
|
+
error: `Verification failed: ${JSON.stringify(confirmation.value.err)}`,
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
// Get transaction details for CU usage
|
|
315
|
+
const txDetails = await connection.getTransaction(signature, {
|
|
316
|
+
commitment: 'confirmed',
|
|
317
|
+
maxSupportedTransactionVersion: 0,
|
|
318
|
+
})
|
|
319
|
+
|
|
320
|
+
const computeUnits = txDetails?.meta?.computeUnitsConsumed ?? this.config.computeUnits!
|
|
321
|
+
|
|
322
|
+
return {
|
|
323
|
+
verified: true,
|
|
324
|
+
signature,
|
|
325
|
+
computeUnits: Number(computeUnits),
|
|
326
|
+
}
|
|
327
|
+
} catch (error) {
|
|
328
|
+
return {
|
|
329
|
+
verified: false,
|
|
330
|
+
signature: '',
|
|
331
|
+
computeUnits: 0,
|
|
332
|
+
error: error instanceof Error ? error.message : 'Unknown error',
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
/**
|
|
338
|
+
* Estimate compute units for verification
|
|
339
|
+
*
|
|
340
|
+
* @param proofType - Type of proof
|
|
341
|
+
* @returns Estimated compute units
|
|
342
|
+
*/
|
|
343
|
+
estimateComputeUnits(proofType: ProofType): number {
|
|
344
|
+
// Groth16 verification is roughly constant across proof types
|
|
345
|
+
// ~200K for the actual verification + overhead
|
|
346
|
+
switch (proofType) {
|
|
347
|
+
case ProofType.Funding:
|
|
348
|
+
return 220_000
|
|
349
|
+
case ProofType.Ownership:
|
|
350
|
+
return 200_000
|
|
351
|
+
case ProofType.Validity:
|
|
352
|
+
return 250_000
|
|
353
|
+
case ProofType.Fulfillment:
|
|
354
|
+
return 230_000
|
|
355
|
+
default:
|
|
356
|
+
return DEFAULT_COMPUTE_UNITS
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
/**
|
|
361
|
+
* Parse a Groth16 proof from bytes
|
|
362
|
+
*/
|
|
363
|
+
static parseProof(proofBytes: Uint8Array): Groth16Proof {
|
|
364
|
+
if (proofBytes.length === PROOF_SIZE.GROTH16_UNCOMPRESSED) {
|
|
365
|
+
return {
|
|
366
|
+
a: proofBytes.slice(0, 64),
|
|
367
|
+
b: proofBytes.slice(64, 192),
|
|
368
|
+
c: proofBytes.slice(192, 256),
|
|
369
|
+
}
|
|
370
|
+
} else if (proofBytes.length === PROOF_SIZE.GROTH16_COMPRESSED) {
|
|
371
|
+
return {
|
|
372
|
+
a: proofBytes.slice(0, 33),
|
|
373
|
+
b: proofBytes.slice(33, 98),
|
|
374
|
+
c: proofBytes.slice(98, 131),
|
|
375
|
+
}
|
|
376
|
+
} else {
|
|
377
|
+
throw new ValidationError(
|
|
378
|
+
`Invalid proof size: ${proofBytes.length}`,
|
|
379
|
+
'proofBytes'
|
|
380
|
+
)
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
/**
|
|
385
|
+
* Serialize a Groth16 proof to bytes
|
|
386
|
+
*/
|
|
387
|
+
static serializeProof(proof: Groth16Proof): Uint8Array {
|
|
388
|
+
return new Uint8Array([...proof.a, ...proof.b, ...proof.c])
|
|
389
|
+
}
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
/**
|
|
393
|
+
* Create instruction data for verifier call
|
|
394
|
+
*/
|
|
395
|
+
export function createVerifyInstructionData(
|
|
396
|
+
proof: Uint8Array,
|
|
397
|
+
publicInputs: Uint8Array[]
|
|
398
|
+
): Buffer {
|
|
399
|
+
return Buffer.concat([proof, ...publicInputs.map((p) => Buffer.from(p))])
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
/**
|
|
403
|
+
* Format public inputs for funding proof
|
|
404
|
+
*/
|
|
405
|
+
export function formatFundingInputs(params: {
|
|
406
|
+
commitmentHash: HexString
|
|
407
|
+
minimumRequired: bigint
|
|
408
|
+
assetId: HexString
|
|
409
|
+
}): Uint8Array[] {
|
|
410
|
+
return [
|
|
411
|
+
hexToBytes(params.commitmentHash.slice(2)),
|
|
412
|
+
bigintToBytes32(params.minimumRequired),
|
|
413
|
+
hexToBytes(params.assetId.slice(2)),
|
|
414
|
+
]
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
/**
|
|
418
|
+
* Format public inputs for ownership proof
|
|
419
|
+
*/
|
|
420
|
+
export function formatOwnershipInputs(params: {
|
|
421
|
+
stealthPubkey: HexString
|
|
422
|
+
ephemeralPubkey: HexString
|
|
423
|
+
nullifier: HexString
|
|
424
|
+
}): Uint8Array[] {
|
|
425
|
+
return [
|
|
426
|
+
hexToBytes(params.stealthPubkey.slice(2)),
|
|
427
|
+
hexToBytes(params.ephemeralPubkey.slice(2)),
|
|
428
|
+
hexToBytes(params.nullifier.slice(2)),
|
|
429
|
+
]
|
|
430
|
+
}
|
|
431
|
+
|
|
432
|
+
// ─── Helpers ─────────────────────────────────────────────────────────────────
|
|
433
|
+
|
|
434
|
+
function toPublicKey(input: PublicKey | string): PublicKey {
|
|
435
|
+
return typeof input === 'string' ? new PublicKey(input) : input
|
|
436
|
+
}
|
|
437
|
+
|
|
438
|
+
function toBytes(input: Uint8Array | HexString): Uint8Array {
|
|
439
|
+
if (typeof input === 'string') {
|
|
440
|
+
return hexToBytes(input.startsWith('0x') ? input.slice(2) : input)
|
|
441
|
+
}
|
|
442
|
+
return input
|
|
443
|
+
}
|
|
444
|
+
|
|
445
|
+
function bigintToBytes32(value: bigint): Uint8Array {
|
|
446
|
+
const bytes = new Uint8Array(32)
|
|
447
|
+
let v = value
|
|
448
|
+
for (let i = 31; i >= 0; i--) {
|
|
449
|
+
bytes[i] = Number(v & 0xffn)
|
|
450
|
+
v >>= 8n
|
|
451
|
+
}
|
|
452
|
+
return bytes
|
|
453
|
+
}
|