@zkproofport-ai/sdk 0.1.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/README.md +437 -0
- package/dist/attestation.d.ts +60 -0
- package/dist/attestation.d.ts.map +1 -0
- package/dist/attestation.js +220 -0
- package/dist/attestation.js.map +1 -0
- package/dist/cdp.d.ts +44 -0
- package/dist/cdp.d.ts.map +1 -0
- package/dist/cdp.js +89 -0
- package/dist/cdp.js.map +1 -0
- package/dist/config.d.ts +19 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +25 -0
- package/dist/config.js.map +1 -0
- package/dist/constants.d.ts +18 -0
- package/dist/constants.d.ts.map +1 -0
- package/dist/constants.js +29 -0
- package/dist/constants.js.map +1 -0
- package/dist/flow.d.ts +19 -0
- package/dist/flow.d.ts.map +1 -0
- package/dist/flow.js +82 -0
- package/dist/flow.js.map +1 -0
- package/dist/index.d.ts +17 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +22 -0
- package/dist/index.js.map +1 -0
- package/dist/inputs.d.ts +56 -0
- package/dist/inputs.d.ts.map +1 -0
- package/dist/inputs.js +204 -0
- package/dist/inputs.js.map +1 -0
- package/dist/merkle.d.ts +34 -0
- package/dist/merkle.d.ts.map +1 -0
- package/dist/merkle.js +95 -0
- package/dist/merkle.js.map +1 -0
- package/dist/payment.d.ts +15 -0
- package/dist/payment.d.ts.map +1 -0
- package/dist/payment.js +114 -0
- package/dist/payment.js.map +1 -0
- package/dist/prove.d.ts +12 -0
- package/dist/prove.d.ts.map +1 -0
- package/dist/prove.js +25 -0
- package/dist/prove.js.map +1 -0
- package/dist/session.d.ts +8 -0
- package/dist/session.d.ts.map +1 -0
- package/dist/session.js +20 -0
- package/dist/session.js.map +1 -0
- package/dist/signer.d.ts +69 -0
- package/dist/signer.d.ts.map +1 -0
- package/dist/signer.js +51 -0
- package/dist/signer.js.map +1 -0
- package/dist/types.d.ts +136 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +12 -0
- package/dist/types.js.map +1 -0
- package/dist/verify.d.ts +29 -0
- package/dist/verify.d.ts.map +1 -0
- package/dist/verify.js +56 -0
- package/dist/verify.js.map +1 -0
- package/package.json +34 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAmBA,OAAO,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAE9D,YAAY;AACZ,OAAO,EACL,QAAQ,EACR,0BAA0B,EAC1B,kBAAkB,EAClB,cAAc,GACf,MAAM,gBAAgB,CAAC;AAExB,gBAAgB;AAChB,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE3C,0BAA0B;AAC1B,OAAO,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAG1C,4CAA4C;AAC5C,OAAO,EAAE,gBAAgB,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAC/D,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAC3C,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AACzC,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAEzD,oBAAoB;AACpB,OAAO,EACL,aAAa,EACb,iBAAiB,EACjB,YAAY,EACZ,gBAAgB,EAChB,iBAAiB,EACjB,UAAU,EACV,wBAAwB,GACzB,MAAM,aAAa,CAAC;AAIrB,OAAO,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAEnF,2CAA2C;AAC3C,OAAO,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAE3C,cAAc;AACd,OAAO,EACL,gBAAgB,EAChB,uBAAuB,EACvB,mBAAmB,EACnB,qBAAqB,EACrB,gBAAgB,GACjB,MAAM,kBAAkB,CAAC;AAE1B,SAAS;AACT,OAAO,EACL,gBAAgB,EAChB,eAAe,EACf,qBAAqB,GACtB,MAAM,aAAa,CAAC"}
|
package/dist/inputs.d.ts
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import type { CircuitId, ProveInputs, ClientConfig } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Convert a hex string to an array of byte values (numbers 0-255).
|
|
4
|
+
*/
|
|
5
|
+
export declare function hexToBytes(hex: string): number[];
|
|
6
|
+
/**
|
|
7
|
+
* Extract X and Y coordinates from an uncompressed public key.
|
|
8
|
+
* Input: "0x04..." (130 hex chars) or "04..." (128 hex chars)
|
|
9
|
+
* Output: { x: "0x...", y: "0x..." } each 64 hex chars (32 bytes)
|
|
10
|
+
*/
|
|
11
|
+
export declare function extractPubkeyCoordinates(pubkey: string): {
|
|
12
|
+
x: string;
|
|
13
|
+
y: string;
|
|
14
|
+
};
|
|
15
|
+
/**
|
|
16
|
+
* Compute the deterministic signal hash.
|
|
17
|
+
* signalHash = keccak256(solidityPacked(address, scopeString, circuitName))
|
|
18
|
+
*/
|
|
19
|
+
export declare function computeSignalHash(userAddress: string, scopeString: string, circuitName: string): Uint8Array;
|
|
20
|
+
/**
|
|
21
|
+
* Recover user's uncompressed public key from their signature over the signal hash.
|
|
22
|
+
* Returns "0x04..." (130 hex chars).
|
|
23
|
+
*/
|
|
24
|
+
export declare function recoverUserPubkey(signalHash: Uint8Array, userSignature: string): string;
|
|
25
|
+
/**
|
|
26
|
+
* Compute scope bytes from a scope string.
|
|
27
|
+
* scope = keccak256(toUtf8Bytes(scopeString))
|
|
28
|
+
*/
|
|
29
|
+
export declare function computeScope(scopeString: string): Uint8Array;
|
|
30
|
+
/**
|
|
31
|
+
* Compute nullifier = keccak256(keccak256(address + signalHash) + scope)
|
|
32
|
+
*/
|
|
33
|
+
export declare function computeNullifier(userAddress: string, signalHash: Uint8Array, scopeBytes: Uint8Array): Uint8Array;
|
|
34
|
+
/**
|
|
35
|
+
* Prepare all inputs for POST /prove.
|
|
36
|
+
*
|
|
37
|
+
* Steps:
|
|
38
|
+
* 1. Compute signal hash
|
|
39
|
+
* 2. Recover user public key from signature
|
|
40
|
+
* 3. Fetch EAS attestation + raw transaction from Base chain
|
|
41
|
+
* 4. Recover Coinbase attester public key from tx signature
|
|
42
|
+
* 5. Build authorized signer Merkle tree + proof
|
|
43
|
+
* 6. Compute scope bytes and nullifier
|
|
44
|
+
* 7. Assemble the ProveInputs object
|
|
45
|
+
*
|
|
46
|
+
* All hex string fields use "0x..." format. The server converts to decimal internally.
|
|
47
|
+
*/
|
|
48
|
+
export declare function prepareInputs(config: ClientConfig, params: {
|
|
49
|
+
circuitId: CircuitId;
|
|
50
|
+
userAddress: string;
|
|
51
|
+
userSignature: string;
|
|
52
|
+
scope: string;
|
|
53
|
+
countryList?: string[];
|
|
54
|
+
isIncluded?: boolean;
|
|
55
|
+
}): Promise<ProveInputs>;
|
|
56
|
+
//# sourceMappingURL=inputs.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"inputs.d.ts","sourceRoot":"","sources":["../src/inputs.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAQvE;;GAEG;AACH,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,EAAE,CAOhD;AAED;;;;GAIG;AACH,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,MAAM,GAAG;IAAE,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAA;CAAE,CAKjF;AAID;;;GAGG;AACH,wBAAgB,iBAAiB,CAC/B,WAAW,EAAE,MAAM,EACnB,WAAW,EAAE,MAAM,EACnB,WAAW,EAAE,MAAM,GAClB,UAAU,CAMZ;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAC/B,UAAU,EAAE,UAAU,EACtB,aAAa,EAAE,MAAM,GACpB,MAAM,CAKR;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,WAAW,EAAE,MAAM,GAAG,UAAU,CAE5D;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAC9B,WAAW,EAAE,MAAM,EACnB,UAAU,EAAE,UAAU,EACtB,UAAU,EAAE,UAAU,GACrB,UAAU,CAQZ;AA4ED;;;;;;;;;;;;;GAaG;AACH,wBAAsB,aAAa,CAAC,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE;IAChE,SAAS,EAAE,SAAS,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,MAAM,CAAC;IACtB,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;IACvB,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB,GAAG,OAAO,CAAC,WAAW,CAAC,CAuEvB"}
|
package/dist/inputs.js
ADDED
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
import { ethers } from 'ethers';
|
|
2
|
+
import { CIRCUITS, MERKLE_PROOF_MAX_DEPTH, COUNTRY_LIST_MAX_LENGTH } from './constants.js';
|
|
3
|
+
import { fetchAttestation, recoverAttesterPubkey, getSignerAddress } from './attestation.js';
|
|
4
|
+
import { findSignerIndex, buildSignerMerkleTree } from './merkle.js';
|
|
5
|
+
// ─── Utility functions ──────────────────────────────────────────────────
|
|
6
|
+
/**
|
|
7
|
+
* Convert a hex string to an array of byte values (numbers 0-255).
|
|
8
|
+
*/
|
|
9
|
+
export function hexToBytes(hex) {
|
|
10
|
+
const cleanHex = hex.startsWith('0x') ? hex.slice(2) : hex;
|
|
11
|
+
const bytes = [];
|
|
12
|
+
for (let i = 0; i < cleanHex.length; i += 2) {
|
|
13
|
+
bytes.push(parseInt(cleanHex.slice(i, i + 2), 16));
|
|
14
|
+
}
|
|
15
|
+
return bytes;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Extract X and Y coordinates from an uncompressed public key.
|
|
19
|
+
* Input: "0x04..." (130 hex chars) or "04..." (128 hex chars)
|
|
20
|
+
* Output: { x: "0x...", y: "0x..." } each 64 hex chars (32 bytes)
|
|
21
|
+
*/
|
|
22
|
+
export function extractPubkeyCoordinates(pubkey) {
|
|
23
|
+
const pubkeyHex = pubkey.startsWith('0x04') ? pubkey.slice(4) : pubkey.slice(2);
|
|
24
|
+
const x = '0x' + pubkeyHex.slice(0, 64);
|
|
25
|
+
const y = '0x' + pubkeyHex.slice(64, 128);
|
|
26
|
+
return { x, y };
|
|
27
|
+
}
|
|
28
|
+
// ─── Core computation functions ─────────────────────────────────────────
|
|
29
|
+
/**
|
|
30
|
+
* Compute the deterministic signal hash.
|
|
31
|
+
* signalHash = keccak256(solidityPacked(address, scopeString, circuitName))
|
|
32
|
+
*/
|
|
33
|
+
export function computeSignalHash(userAddress, scopeString, circuitName) {
|
|
34
|
+
const signalPreimage = ethers.solidityPacked(['address', 'string', 'string'], [userAddress, scopeString, circuitName]);
|
|
35
|
+
return ethers.getBytes(ethers.keccak256(signalPreimage));
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Recover user's uncompressed public key from their signature over the signal hash.
|
|
39
|
+
* Returns "0x04..." (130 hex chars).
|
|
40
|
+
*/
|
|
41
|
+
export function recoverUserPubkey(signalHash, userSignature) {
|
|
42
|
+
const messageHex = ethers.hexlify(signalHash);
|
|
43
|
+
const ethSignedHash = ethers.hashMessage(ethers.getBytes(messageHex));
|
|
44
|
+
const pubkey = ethers.SigningKey.recoverPublicKey(ethSignedHash, userSignature);
|
|
45
|
+
return pubkey;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Compute scope bytes from a scope string.
|
|
49
|
+
* scope = keccak256(toUtf8Bytes(scopeString))
|
|
50
|
+
*/
|
|
51
|
+
export function computeScope(scopeString) {
|
|
52
|
+
return ethers.getBytes(ethers.keccak256(ethers.toUtf8Bytes(scopeString)));
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Compute nullifier = keccak256(keccak256(address + signalHash) + scope)
|
|
56
|
+
*/
|
|
57
|
+
export function computeNullifier(userAddress, signalHash, scopeBytes) {
|
|
58
|
+
const userAddressBytes = ethers.getBytes(userAddress);
|
|
59
|
+
const userSecret = ethers.getBytes(ethers.keccak256(ethers.concat([userAddressBytes, signalHash])));
|
|
60
|
+
return ethers.getBytes(ethers.keccak256(ethers.concat([userSecret, scopeBytes])));
|
|
61
|
+
}
|
|
62
|
+
// ─── Internal helpers for input assembly ────────────────────────────────
|
|
63
|
+
/**
|
|
64
|
+
* Pad a byte array to a target length with trailing zeros.
|
|
65
|
+
*/
|
|
66
|
+
function padBytes(arr, targetLength) {
|
|
67
|
+
const result = [...arr];
|
|
68
|
+
while (result.length < targetLength) {
|
|
69
|
+
result.push(0);
|
|
70
|
+
}
|
|
71
|
+
return result;
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Split a signature into r (32 bytes) + s (32 bytes) = 64 bytes.
|
|
75
|
+
* Drops the v component.
|
|
76
|
+
*/
|
|
77
|
+
function splitSignatureToBytes(signature) {
|
|
78
|
+
const sig = ethers.Signature.from(signature);
|
|
79
|
+
const rBytes = hexToBytes(sig.r);
|
|
80
|
+
const sBytes = hexToBytes(sig.s);
|
|
81
|
+
return [...rBytes, ...sBytes];
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Encode a country list into the [[u8; 2]; 10] format.
|
|
85
|
+
* Each country code is 2 ASCII bytes (e.g., "US" -> [85, 83]).
|
|
86
|
+
* Pads to 10 entries with zero pairs.
|
|
87
|
+
*/
|
|
88
|
+
function encodeCountryList(countries) {
|
|
89
|
+
const result = [];
|
|
90
|
+
for (let i = 0; i < COUNTRY_LIST_MAX_LENGTH; i++) {
|
|
91
|
+
if (i < countries.length) {
|
|
92
|
+
result.push(countries[i].charCodeAt(0).toString());
|
|
93
|
+
result.push(countries[i].charCodeAt(1).toString());
|
|
94
|
+
}
|
|
95
|
+
else {
|
|
96
|
+
result.push('0');
|
|
97
|
+
result.push('0');
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
return result;
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Convert byte values to decimal string entries.
|
|
104
|
+
*/
|
|
105
|
+
function bytesToDecimalStrings(bytes) {
|
|
106
|
+
return bytes.map(b => b.toString());
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Convert a Uint8Array to decimal string entries.
|
|
110
|
+
*/
|
|
111
|
+
function uint8ArrayToDecimalStrings(arr) {
|
|
112
|
+
return Array.from(arr).map(b => b.toString());
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Build a padded Merkle proof: 8 * 32 = 256 bytes as decimal strings.
|
|
116
|
+
*/
|
|
117
|
+
function buildPaddedMerkleProof(proof) {
|
|
118
|
+
const result = [];
|
|
119
|
+
for (let i = 0; i < MERKLE_PROOF_MAX_DEPTH; i++) {
|
|
120
|
+
if (i < proof.length) {
|
|
121
|
+
result.push(...bytesToDecimalStrings(hexToBytes(proof[i])));
|
|
122
|
+
}
|
|
123
|
+
else {
|
|
124
|
+
result.push(...bytesToDecimalStrings(new Array(32).fill(0)));
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
return result;
|
|
128
|
+
}
|
|
129
|
+
// ─── Main function ──────────────────────────────────────────────────────
|
|
130
|
+
/**
|
|
131
|
+
* Prepare all inputs for POST /prove.
|
|
132
|
+
*
|
|
133
|
+
* Steps:
|
|
134
|
+
* 1. Compute signal hash
|
|
135
|
+
* 2. Recover user public key from signature
|
|
136
|
+
* 3. Fetch EAS attestation + raw transaction from Base chain
|
|
137
|
+
* 4. Recover Coinbase attester public key from tx signature
|
|
138
|
+
* 5. Build authorized signer Merkle tree + proof
|
|
139
|
+
* 6. Compute scope bytes and nullifier
|
|
140
|
+
* 7. Assemble the ProveInputs object
|
|
141
|
+
*
|
|
142
|
+
* All hex string fields use "0x..." format. The server converts to decimal internally.
|
|
143
|
+
*/
|
|
144
|
+
export async function prepareInputs(config, params) {
|
|
145
|
+
const { circuitId, userAddress, userSignature, scope } = params;
|
|
146
|
+
// Validate circuit
|
|
147
|
+
if (!(circuitId in CIRCUITS)) {
|
|
148
|
+
throw new Error(`Unknown circuit: ${circuitId}`);
|
|
149
|
+
}
|
|
150
|
+
// Validate country fields for country circuit
|
|
151
|
+
if (circuitId === 'coinbase_country_attestation') {
|
|
152
|
+
if (!params.countryList || params.countryList.length === 0) {
|
|
153
|
+
throw new Error('countryList is required for coinbase_country_attestation');
|
|
154
|
+
}
|
|
155
|
+
if (params.isIncluded === undefined || params.isIncluded === null) {
|
|
156
|
+
throw new Error('isIncluded is required for coinbase_country_attestation');
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
// Step 1: Compute signal hash
|
|
160
|
+
const signalHash = computeSignalHash(userAddress, scope, circuitId);
|
|
161
|
+
// Step 2: Recover user public key
|
|
162
|
+
const userPubkey = recoverUserPubkey(signalHash, userSignature);
|
|
163
|
+
const { x: userPubkeyX, y: userPubkeyY } = extractPubkeyCoordinates(userPubkey);
|
|
164
|
+
// Step 3: Fetch attestation transaction from Base chain
|
|
165
|
+
const attestationData = await fetchAttestation(config, circuitId, userAddress);
|
|
166
|
+
// Step 4: Recover Coinbase attester public key
|
|
167
|
+
const attesterPubkey = recoverAttesterPubkey(attestationData.rawTransaction);
|
|
168
|
+
const attesterAddress = getSignerAddress(attesterPubkey);
|
|
169
|
+
const { x: attesterPubkeyX, y: attesterPubkeyY } = extractPubkeyCoordinates(attesterPubkey);
|
|
170
|
+
// Step 5: Build Merkle tree
|
|
171
|
+
const signerIndex = findSignerIndex(attesterAddress);
|
|
172
|
+
const merkleData = buildSignerMerkleTree(signerIndex);
|
|
173
|
+
// Step 6: Compute scope and nullifier
|
|
174
|
+
const scopeBytes = computeScope(scope);
|
|
175
|
+
const nullifierBytes = computeNullifier(userAddress, signalHash, scopeBytes);
|
|
176
|
+
// Step 7: Convert raw TX to byte array
|
|
177
|
+
const rawTxBytes = hexToBytes(attestationData.rawTransaction);
|
|
178
|
+
const txLength = rawTxBytes.length;
|
|
179
|
+
// Assemble ProveInputs -- all values as hex strings (0x...)
|
|
180
|
+
const inputs = {
|
|
181
|
+
signal_hash: ethers.hexlify(signalHash),
|
|
182
|
+
nullifier: ethers.hexlify(nullifierBytes),
|
|
183
|
+
scope_bytes: ethers.hexlify(scopeBytes),
|
|
184
|
+
merkle_root: merkleData.root,
|
|
185
|
+
user_address: userAddress,
|
|
186
|
+
signature: userSignature,
|
|
187
|
+
user_pubkey_x: userPubkeyX,
|
|
188
|
+
user_pubkey_y: userPubkeyY,
|
|
189
|
+
raw_transaction: attestationData.rawTransaction,
|
|
190
|
+
tx_length: txLength,
|
|
191
|
+
coinbase_attester_pubkey_x: attesterPubkeyX,
|
|
192
|
+
coinbase_attester_pubkey_y: attesterPubkeyY,
|
|
193
|
+
merkle_proof: merkleData.proof,
|
|
194
|
+
leaf_index: merkleData.leafIndex,
|
|
195
|
+
depth: merkleData.depth,
|
|
196
|
+
};
|
|
197
|
+
// Add country-specific fields
|
|
198
|
+
if (circuitId === 'coinbase_country_attestation') {
|
|
199
|
+
inputs.country_list = params.countryList;
|
|
200
|
+
inputs.is_included = params.isIncluded;
|
|
201
|
+
}
|
|
202
|
+
return inputs;
|
|
203
|
+
}
|
|
204
|
+
//# sourceMappingURL=inputs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"inputs.js","sourceRoot":"","sources":["../src/inputs.ts"],"names":[],"mappings":"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"}
|
package/dist/merkle.d.ts
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Simple binary Merkle tree for signer verification.
|
|
3
|
+
*
|
|
4
|
+
* Leaf: keccak256(address_bytes)
|
|
5
|
+
* Odd number of leaves: duplicate last leaf
|
|
6
|
+
* Internal node: keccak256(left || right)
|
|
7
|
+
*/
|
|
8
|
+
export declare class SimpleMerkleTree {
|
|
9
|
+
private leaves;
|
|
10
|
+
private layers;
|
|
11
|
+
constructor(addresses: string[]);
|
|
12
|
+
getRoot(): string;
|
|
13
|
+
getProof(index: number): {
|
|
14
|
+
proof: string[];
|
|
15
|
+
leafIndex: number;
|
|
16
|
+
depth: number;
|
|
17
|
+
};
|
|
18
|
+
getLeafHash(index: number): string;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Find the index of a signer address in the authorized signers list.
|
|
22
|
+
* Case-insensitive comparison.
|
|
23
|
+
*/
|
|
24
|
+
export declare function findSignerIndex(signerAddress: string): number;
|
|
25
|
+
/**
|
|
26
|
+
* Build a Merkle tree from authorized signers and get proof for the given signer index.
|
|
27
|
+
*/
|
|
28
|
+
export declare function buildSignerMerkleTree(signerIndex: number): {
|
|
29
|
+
root: string;
|
|
30
|
+
proof: string[];
|
|
31
|
+
leafIndex: number;
|
|
32
|
+
depth: number;
|
|
33
|
+
};
|
|
34
|
+
//# sourceMappingURL=merkle.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"merkle.d.ts","sourceRoot":"","sources":["../src/merkle.ts"],"names":[],"mappings":"AAGA;;;;;;GAMG;AACH,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,MAAM,CAAW;IACzB,OAAO,CAAC,MAAM,CAAa;gBAEf,SAAS,EAAE,MAAM,EAAE;IA+B/B,OAAO,IAAI,MAAM;IAIjB,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG;QAAE,KAAK,EAAE,MAAM,EAAE,CAAC;QAAC,SAAS,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE;IA8B9E,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM;CAMnC;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,aAAa,EAAE,MAAM,GAAG,MAAM,CAU7D;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,WAAW,EAAE,MAAM,GAAG;IAC1D,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;CACf,CAMA"}
|
package/dist/merkle.js
ADDED
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import { ethers } from 'ethers';
|
|
2
|
+
import { AUTHORIZED_SIGNERS } from './constants.js';
|
|
3
|
+
/**
|
|
4
|
+
* Simple binary Merkle tree for signer verification.
|
|
5
|
+
*
|
|
6
|
+
* Leaf: keccak256(address_bytes)
|
|
7
|
+
* Odd number of leaves: duplicate last leaf
|
|
8
|
+
* Internal node: keccak256(left || right)
|
|
9
|
+
*/
|
|
10
|
+
export class SimpleMerkleTree {
|
|
11
|
+
leaves;
|
|
12
|
+
layers;
|
|
13
|
+
constructor(addresses) {
|
|
14
|
+
if (addresses.length === 0) {
|
|
15
|
+
throw new Error('SimpleMerkleTree requires at least one address');
|
|
16
|
+
}
|
|
17
|
+
// Create leaf hashes: keccak256(address_bytes)
|
|
18
|
+
this.leaves = addresses.map(addr => {
|
|
19
|
+
const addrBytes = ethers.getBytes(ethers.getAddress(addr));
|
|
20
|
+
return ethers.keccak256(addrBytes);
|
|
21
|
+
});
|
|
22
|
+
// Build layers bottom-up
|
|
23
|
+
this.layers = [this.leaves];
|
|
24
|
+
let currentLayer = this.leaves;
|
|
25
|
+
while (currentLayer.length > 1) {
|
|
26
|
+
const nextLayer = [];
|
|
27
|
+
for (let i = 0; i < currentLayer.length; i += 2) {
|
|
28
|
+
const left = currentLayer[i];
|
|
29
|
+
const right = currentLayer[i + 1] || left; // duplicate if odd
|
|
30
|
+
const combined = ethers.concat([
|
|
31
|
+
ethers.getBytes(left),
|
|
32
|
+
ethers.getBytes(right),
|
|
33
|
+
]);
|
|
34
|
+
nextLayer.push(ethers.keccak256(combined));
|
|
35
|
+
}
|
|
36
|
+
this.layers.push(nextLayer);
|
|
37
|
+
currentLayer = nextLayer;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
getRoot() {
|
|
41
|
+
return this.layers[this.layers.length - 1][0];
|
|
42
|
+
}
|
|
43
|
+
getProof(index) {
|
|
44
|
+
if (index < 0 || index >= this.leaves.length) {
|
|
45
|
+
throw new Error(`Leaf index ${index} out of bounds (0..${this.leaves.length - 1})`);
|
|
46
|
+
}
|
|
47
|
+
const proof = [];
|
|
48
|
+
let idx = index;
|
|
49
|
+
for (let i = 0; i < this.layers.length - 1; i++) {
|
|
50
|
+
const layer = this.layers[i];
|
|
51
|
+
const isRight = idx % 2 === 1;
|
|
52
|
+
const siblingIdx = isRight ? idx - 1 : idx + 1;
|
|
53
|
+
if (siblingIdx < layer.length) {
|
|
54
|
+
proof.push(layer[siblingIdx]);
|
|
55
|
+
}
|
|
56
|
+
else {
|
|
57
|
+
// No sibling -- use self (duplicate)
|
|
58
|
+
proof.push(layer[idx]);
|
|
59
|
+
}
|
|
60
|
+
idx = Math.floor(idx / 2);
|
|
61
|
+
}
|
|
62
|
+
return {
|
|
63
|
+
proof,
|
|
64
|
+
leafIndex: index,
|
|
65
|
+
depth: proof.length,
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
getLeafHash(index) {
|
|
69
|
+
if (index < 0 || index >= this.leaves.length) {
|
|
70
|
+
throw new Error(`Leaf index ${index} out of bounds (0..${this.leaves.length - 1})`);
|
|
71
|
+
}
|
|
72
|
+
return this.leaves[index];
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Find the index of a signer address in the authorized signers list.
|
|
77
|
+
* Case-insensitive comparison.
|
|
78
|
+
*/
|
|
79
|
+
export function findSignerIndex(signerAddress) {
|
|
80
|
+
const index = AUTHORIZED_SIGNERS.findIndex(addr => addr.toLowerCase() === signerAddress.toLowerCase());
|
|
81
|
+
if (index === -1) {
|
|
82
|
+
throw new Error(`Signer ${signerAddress} is not in the authorized signers list`);
|
|
83
|
+
}
|
|
84
|
+
return index;
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Build a Merkle tree from authorized signers and get proof for the given signer index.
|
|
88
|
+
*/
|
|
89
|
+
export function buildSignerMerkleTree(signerIndex) {
|
|
90
|
+
const tree = new SimpleMerkleTree(AUTHORIZED_SIGNERS);
|
|
91
|
+
const root = tree.getRoot();
|
|
92
|
+
const { proof, leafIndex, depth } = tree.getProof(signerIndex);
|
|
93
|
+
return { root, proof, leafIndex, depth };
|
|
94
|
+
}
|
|
95
|
+
//# sourceMappingURL=merkle.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"merkle.js","sourceRoot":"","sources":["../src/merkle.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { PaymentInfo } from './types.js';
|
|
2
|
+
import type { ProofportSigner } from './signer.js';
|
|
3
|
+
/**
|
|
4
|
+
* Make payment for a proof session via x402 protocol.
|
|
5
|
+
*
|
|
6
|
+
* Uses EIP-3009 TransferWithAuthorization signed by the client,
|
|
7
|
+
* settled via x402 facilitator (facilitator pays gas).
|
|
8
|
+
* Works on both Base Sepolia (testnet) and Base (mainnet).
|
|
9
|
+
*
|
|
10
|
+
* @param signer - ProofportSigner (ethers, CDP MPC, or any implementation)
|
|
11
|
+
* @param payment - PaymentInfo from session or 402 response
|
|
12
|
+
* @returns Transaction hash
|
|
13
|
+
*/
|
|
14
|
+
export declare function makePayment(signer: ProofportSigner, payment: PaymentInfo): Promise<string>;
|
|
15
|
+
//# sourceMappingURL=payment.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"payment.d.ts","sourceRoot":"","sources":["../src/payment.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAC9C,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAenD;;;;;;;;;;GAUG;AACH,wBAAsB,WAAW,CAC/B,MAAM,EAAE,eAAe,EACvB,OAAO,EAAE,WAAW,GACnB,OAAO,CAAC,MAAM,CAAC,CAsGjB"}
|
package/dist/payment.js
ADDED
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
import { ethers } from 'ethers';
|
|
2
|
+
const X402_FACILITATOR = 'https://www.x402.org/facilitator';
|
|
3
|
+
const CHAIN_IDS = {
|
|
4
|
+
'base-sepolia': 84532,
|
|
5
|
+
'base': 8453,
|
|
6
|
+
};
|
|
7
|
+
// EIP-712 domain names per USDC contract (queried via name() on-chain)
|
|
8
|
+
const USDC_DOMAIN_NAMES = {
|
|
9
|
+
'base-sepolia': 'USDC',
|
|
10
|
+
'base': 'USD Coin',
|
|
11
|
+
};
|
|
12
|
+
/**
|
|
13
|
+
* Make payment for a proof session via x402 protocol.
|
|
14
|
+
*
|
|
15
|
+
* Uses EIP-3009 TransferWithAuthorization signed by the client,
|
|
16
|
+
* settled via x402 facilitator (facilitator pays gas).
|
|
17
|
+
* Works on both Base Sepolia (testnet) and Base (mainnet).
|
|
18
|
+
*
|
|
19
|
+
* @param signer - ProofportSigner (ethers, CDP MPC, or any implementation)
|
|
20
|
+
* @param payment - PaymentInfo from session or 402 response
|
|
21
|
+
* @returns Transaction hash
|
|
22
|
+
*/
|
|
23
|
+
export async function makePayment(signer, payment) {
|
|
24
|
+
const network = payment.network;
|
|
25
|
+
const chainId = CHAIN_IDS[network];
|
|
26
|
+
if (!chainId) {
|
|
27
|
+
throw new Error(`Unsupported network: ${network}`);
|
|
28
|
+
}
|
|
29
|
+
// Pad nonce to bytes32 (EIP-3009 requires bytes32 nonce)
|
|
30
|
+
const nonce = ethers.zeroPadValue(payment.nonce, 32);
|
|
31
|
+
// Validity window
|
|
32
|
+
const validAfter = 0;
|
|
33
|
+
const validBefore = Math.floor(Date.now() / 1000) + 3600; // 1 hour
|
|
34
|
+
// EIP-712 domain for USDC (domain name differs between testnet and mainnet)
|
|
35
|
+
const domain = {
|
|
36
|
+
name: USDC_DOMAIN_NAMES[network] || 'USD Coin',
|
|
37
|
+
version: '2',
|
|
38
|
+
chainId,
|
|
39
|
+
verifyingContract: payment.asset,
|
|
40
|
+
};
|
|
41
|
+
const types = {
|
|
42
|
+
TransferWithAuthorization: [
|
|
43
|
+
{ name: 'from', type: 'address' },
|
|
44
|
+
{ name: 'to', type: 'address' },
|
|
45
|
+
{ name: 'value', type: 'uint256' },
|
|
46
|
+
{ name: 'validAfter', type: 'uint256' },
|
|
47
|
+
{ name: 'validBefore', type: 'uint256' },
|
|
48
|
+
{ name: 'nonce', type: 'bytes32' },
|
|
49
|
+
],
|
|
50
|
+
};
|
|
51
|
+
const from = await signer.getAddress();
|
|
52
|
+
const message = {
|
|
53
|
+
from,
|
|
54
|
+
to: payment.recipient,
|
|
55
|
+
value: payment.amount,
|
|
56
|
+
validAfter,
|
|
57
|
+
validBefore,
|
|
58
|
+
nonce,
|
|
59
|
+
};
|
|
60
|
+
// Sign EIP-712 TransferWithAuthorization
|
|
61
|
+
const signature = await signer.signTypedData(domain, types, message);
|
|
62
|
+
// Settle via x402 facilitator (facilitator pays gas)
|
|
63
|
+
const settlePayload = {
|
|
64
|
+
x402Version: 1,
|
|
65
|
+
scheme: 'exact',
|
|
66
|
+
network,
|
|
67
|
+
paymentPayload: {
|
|
68
|
+
x402Version: 1,
|
|
69
|
+
scheme: 'exact',
|
|
70
|
+
network,
|
|
71
|
+
payload: {
|
|
72
|
+
signature,
|
|
73
|
+
authorization: {
|
|
74
|
+
from,
|
|
75
|
+
to: payment.recipient,
|
|
76
|
+
value: String(payment.amount),
|
|
77
|
+
validAfter: String(validAfter),
|
|
78
|
+
validBefore: String(validBefore),
|
|
79
|
+
nonce,
|
|
80
|
+
},
|
|
81
|
+
},
|
|
82
|
+
},
|
|
83
|
+
paymentRequirements: {
|
|
84
|
+
scheme: 'exact',
|
|
85
|
+
network,
|
|
86
|
+
maxAmountRequired: String(payment.amount),
|
|
87
|
+
asset: payment.asset,
|
|
88
|
+
resource: `${payment.recipient}/proof`,
|
|
89
|
+
description: 'ZK proof generation payment',
|
|
90
|
+
mimeType: 'application/json',
|
|
91
|
+
payTo: payment.recipient,
|
|
92
|
+
extra: {
|
|
93
|
+
name: USDC_DOMAIN_NAMES[network] || 'USD Coin',
|
|
94
|
+
version: '2',
|
|
95
|
+
},
|
|
96
|
+
},
|
|
97
|
+
};
|
|
98
|
+
const settleResponse = await fetch(`${X402_FACILITATOR}/settle`, {
|
|
99
|
+
method: 'POST',
|
|
100
|
+
headers: { 'Content-Type': 'application/json' },
|
|
101
|
+
body: JSON.stringify(settlePayload),
|
|
102
|
+
});
|
|
103
|
+
if (!settleResponse.ok) {
|
|
104
|
+
const error = await settleResponse.text();
|
|
105
|
+
throw new Error(`x402 facilitator settle failed: ${error}`);
|
|
106
|
+
}
|
|
107
|
+
const settleResult = (await settleResponse.json());
|
|
108
|
+
const txHash = settleResult.txHash || settleResult.transaction?.hash || settleResult.transaction;
|
|
109
|
+
if (!txHash) {
|
|
110
|
+
throw new Error(`x402 settle failed: ${settleResult.errorReason || 'no transaction hash'}`);
|
|
111
|
+
}
|
|
112
|
+
return txHash;
|
|
113
|
+
}
|
|
114
|
+
//# sourceMappingURL=payment.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"payment.js","sourceRoot":"","sources":["../src/payment.ts"],"names":[],"mappings":"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"}
|
package/dist/prove.d.ts
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { ClientConfig, CircuitName, ProveInputs, ProveResponse } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Submit proof generation with x402 payment headers.
|
|
4
|
+
* POST /api/v1/prove with X-Payment-TX and X-Payment-Nonce headers.
|
|
5
|
+
*/
|
|
6
|
+
export declare function submitProof(config: ClientConfig, request: {
|
|
7
|
+
circuit: CircuitName;
|
|
8
|
+
inputs: ProveInputs;
|
|
9
|
+
paymentTxHash: string;
|
|
10
|
+
paymentNonce: string;
|
|
11
|
+
}): Promise<ProveResponse>;
|
|
12
|
+
//# sourceMappingURL=prove.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prove.d.ts","sourceRoot":"","sources":["../src/prove.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,WAAW,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAExF;;;GAGG;AACH,wBAAsB,WAAW,CAC/B,MAAM,EAAE,YAAY,EACpB,OAAO,EAAE;IACP,OAAO,EAAE,WAAW,CAAC;IACrB,MAAM,EAAE,WAAW,CAAC;IACpB,aAAa,EAAE,MAAM,CAAC;IACtB,YAAY,EAAE,MAAM,CAAC;CACtB,GACA,OAAO,CAAC,aAAa,CAAC,CAqBxB"}
|
package/dist/prove.js
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Submit proof generation with x402 payment headers.
|
|
3
|
+
* POST /api/v1/prove with X-Payment-TX and X-Payment-Nonce headers.
|
|
4
|
+
*/
|
|
5
|
+
export async function submitProof(config, request) {
|
|
6
|
+
const url = `${config.baseUrl}/api/v1/prove`;
|
|
7
|
+
const response = await fetch(url, {
|
|
8
|
+
method: 'POST',
|
|
9
|
+
headers: {
|
|
10
|
+
'Content-Type': 'application/json',
|
|
11
|
+
'X-Payment-TX': request.paymentTxHash,
|
|
12
|
+
'X-Payment-Nonce': request.paymentNonce,
|
|
13
|
+
},
|
|
14
|
+
body: JSON.stringify({
|
|
15
|
+
circuit: request.circuit,
|
|
16
|
+
inputs: request.inputs,
|
|
17
|
+
}),
|
|
18
|
+
});
|
|
19
|
+
if (!response.ok) {
|
|
20
|
+
const error = await response.json().catch(() => ({ message: `HTTP ${response.status}` }));
|
|
21
|
+
throw new Error(`Proof generation failed: ${JSON.stringify(error)}`);
|
|
22
|
+
}
|
|
23
|
+
return response.json();
|
|
24
|
+
}
|
|
25
|
+
//# sourceMappingURL=prove.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prove.js","sourceRoot":"","sources":["../src/prove.ts"],"names":[],"mappings":"AAEA;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,WAAW,CAC/B,MAAoB,EACpB,OAKC;IAED,MAAM,GAAG,GAAG,GAAG,MAAM,CAAC,OAAO,eAAe,CAAC;IAC7C,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE;QAChC,MAAM,EAAE,MAAM;QACd,OAAO,EAAE;YACP,cAAc,EAAE,kBAAkB;YAClC,cAAc,EAAE,OAAO,CAAC,aAAa;YACrC,iBAAiB,EAAE,OAAO,CAAC,YAAY;SACxC;QACD,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;YACnB,OAAO,EAAE,OAAO,CAAC,OAAO;YACxB,MAAM,EAAE,OAAO,CAAC,MAAM;SACvB,CAAC;KACH,CAAC,CAAC;IAEH,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;QACjB,MAAM,KAAK,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,OAAO,EAAE,QAAQ,QAAQ,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,CAAC;QAC1F,MAAM,IAAI,KAAK,CAAC,4BAA4B,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;IACvE,CAAC;IAED,OAAO,QAAQ,CAAC,IAAI,EAA4B,CAAC;AACnD,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { ClientConfig, CircuitName, ChallengeResponse, ProveInputs } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Request a 402 payment challenge from the server.
|
|
4
|
+
* POST /api/v1/prove without payment headers → 402 with nonce + payment info.
|
|
5
|
+
*/
|
|
6
|
+
export declare function requestChallenge(config: ClientConfig, circuit: CircuitName, inputs: ProveInputs): Promise<ChallengeResponse>;
|
|
7
|
+
export { requestChallenge as createSession };
|
|
8
|
+
//# sourceMappingURL=session.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../src/session.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,WAAW,EAAE,iBAAiB,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAE5F;;;GAGG;AACH,wBAAsB,gBAAgB,CACpC,MAAM,EAAE,YAAY,EACpB,OAAO,EAAE,WAAW,EACpB,MAAM,EAAE,WAAW,GAClB,OAAO,CAAC,iBAAiB,CAAC,CAc5B;AAGD,OAAO,EAAE,gBAAgB,IAAI,aAAa,EAAE,CAAC"}
|
package/dist/session.js
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Request a 402 payment challenge from the server.
|
|
3
|
+
* POST /api/v1/prove without payment headers → 402 with nonce + payment info.
|
|
4
|
+
*/
|
|
5
|
+
export async function requestChallenge(config, circuit, inputs) {
|
|
6
|
+
const url = `${config.baseUrl}/api/v1/prove`;
|
|
7
|
+
const response = await fetch(url, {
|
|
8
|
+
method: 'POST',
|
|
9
|
+
headers: { 'Content-Type': 'application/json' },
|
|
10
|
+
body: JSON.stringify({ circuit, inputs }),
|
|
11
|
+
});
|
|
12
|
+
if (response.status !== 402) {
|
|
13
|
+
const error = await response.json().catch(() => ({ message: `HTTP ${response.status}` }));
|
|
14
|
+
throw new Error(`Expected 402 challenge, got ${response.status}: ${error.message || response.status}`);
|
|
15
|
+
}
|
|
16
|
+
return response.json();
|
|
17
|
+
}
|
|
18
|
+
// Backward-compatible alias (deprecated — use requestChallenge instead)
|
|
19
|
+
export { requestChallenge as createSession };
|
|
20
|
+
//# sourceMappingURL=session.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session.js","sourceRoot":"","sources":["../src/session.ts"],"names":[],"mappings":"AAEA;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,MAAoB,EACpB,OAAoB,EACpB,MAAmB;IAEnB,MAAM,GAAG,GAAG,GAAG,MAAM,CAAC,OAAO,eAAe,CAAC;IAC7C,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE;QAChC,MAAM,EAAE,MAAM;QACd,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;QAC/C,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC;KAC1C,CAAC,CAAC;IAEH,IAAI,QAAQ,CAAC,MAAM,KAAK,GAAG,EAAE,CAAC;QAC5B,MAAM,KAAK,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,OAAO,EAAE,QAAQ,QAAQ,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,CAAC;QAC1F,MAAM,IAAI,KAAK,CAAC,+BAA+B,QAAQ,CAAC,MAAM,KAAM,KAAa,CAAC,OAAO,IAAI,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC;IAClH,CAAC;IAED,OAAO,QAAQ,CAAC,IAAI,EAAgC,CAAC;AACvD,CAAC;AAED,wEAAwE;AACxE,OAAO,EAAE,gBAAgB,IAAI,aAAa,EAAE,CAAC"}
|