@zkproofport-app/sdk 0.2.15 → 0.3.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 +70 -2
- package/dist/ProofportSDK.d.ts +1 -1
- package/dist/circuits.d.ts +45 -3
- package/dist/circuits.esm.js +58 -10
- package/dist/circuits.esm.js.map +1 -1
- package/dist/circuits.js +59 -9
- package/dist/circuits.js.map +1 -1
- package/dist/circuits.mjs +58 -10
- package/dist/circuits.mjs.map +1 -1
- package/dist/index.d.ts +3 -2
- package/dist/index.esm.js +472 -290
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +474 -289
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +472 -290
- package/dist/index.mjs.map +1 -1
- package/dist/typedAction.d.ts +29 -0
- package/dist/typedAction.esm.js +72 -0
- package/dist/typedAction.esm.js.map +1 -0
- package/dist/typedAction.js +75 -0
- package/dist/typedAction.js.map +1 -0
- package/dist/typedAction.mjs +72 -0
- package/dist/typedAction.mjs.map +1 -0
- package/dist/types.d.ts +62 -1
- package/dist/verifier.d.ts +9 -6
- package/package.json +8 -2
package/README.md
CHANGED
|
@@ -124,12 +124,17 @@ import { CIRCUIT_IDS, CIRCUIT_SUPPORT_STATUS } from '@zkproofport-app/sdk/circui
|
|
|
124
124
|
| `CIRCUIT_IDS.COINBASE_ATTESTATION` | `coinbase_attestation` | **Supported** |
|
|
125
125
|
| `CIRCUIT_IDS.COINBASE_COUNTRY_ATTESTATION` | `coinbase_country_attestation` | **Supported** |
|
|
126
126
|
| `CIRCUIT_IDS.OIDC_DOMAIN_ATTESTATION` | `oidc_domain_attestation` | **Supported** |
|
|
127
|
+
| `CIRCUIT_IDS.ARC_ELIGIBILITY` | `arc_eligibility` | _Experimental_ |
|
|
127
128
|
| `CIRCUIT_IDS.GIWA_ATTESTATION` | `giwa_attestation` | Planned |
|
|
128
129
|
| `CIRCUIT_IDS.MDL_KR_OWNERSHIP` | `mdl_kr_ownership` | Planned |
|
|
129
130
|
| `CIRCUIT_IDS.MDL_KR_AGE` | `mdl_kr_age` | Planned |
|
|
130
131
|
| `CIRCUIT_IDS.MDL_KR_REGION` | `mdl_kr_region` | Planned |
|
|
131
132
|
|
|
132
|
-
**Supported** means generally available — build a product on it.
|
|
133
|
+
**Supported** means generally available — build a product on it.
|
|
134
|
+
|
|
135
|
+
**Experimental** means you can prove it today and it verifies, but only against a testnet deployment. Inputs, public-input layout and the verifier address can change without a major version bump, and there is no mainnet to point at. Try it; do not ship on it.
|
|
136
|
+
|
|
137
|
+
**Planned** means the identifier is reserved and the circuit exists, but it is not officially supported yet: availability, inputs and public-input layout can change without a major version bump.
|
|
133
138
|
|
|
134
139
|
Every ID appears in `CircuitType` and in `sdk.getSupportedCircuits()`, planned ones included, so being assignable is not a support guarantee. Gate on the status, not on the type:
|
|
135
140
|
|
|
@@ -137,9 +142,11 @@ Every ID appears in `CircuitType` and in `sdk.getSupportedCircuits()`, planned o
|
|
|
137
142
|
import { CIRCUIT_SUPPORT_STATUS, isSupportedCircuitId } from '@zkproofport-app/sdk';
|
|
138
143
|
|
|
139
144
|
CIRCUIT_SUPPORT_STATUS.coinbase_attestation; // 'supported'
|
|
145
|
+
CIRCUIT_SUPPORT_STATUS.arc_eligibility; // 'experimental'
|
|
140
146
|
CIRCUIT_SUPPORT_STATUS.mdl_kr_age; // 'planned'
|
|
141
147
|
|
|
142
148
|
isSupportedCircuitId('oidc_domain_attestation'); // true
|
|
149
|
+
isSupportedCircuitId('arc_eligibility'); // false — experimental is not supported
|
|
143
150
|
isSupportedCircuitId('mdl_kr_age'); // false
|
|
144
151
|
isSupportedCircuitId('coinbase-kyc'); // false — not an ID at all
|
|
145
152
|
```
|
|
@@ -242,6 +249,65 @@ const relay = await sdk.createRelayRequest('oidc_domain_attestation', {
|
|
|
242
249
|
|
|
243
250
|
> When `provider` is set, the mobile app verifies the user's account is managed by the specified workspace provider (e.g., Google Workspace `hd` claim, Microsoft 365 `tid` claim). Without `provider`, only the email domain is verified.
|
|
244
251
|
|
|
252
|
+
## Experimental Circuits
|
|
253
|
+
|
|
254
|
+
### `arc_eligibility`
|
|
255
|
+
|
|
256
|
+
Proves the same Coinbase attestation as `coinbase_attestation`, with one thing
|
|
257
|
+
changed: the wallet signs a named EIP-712 action instead of an opaque signal
|
|
258
|
+
hash. The proof's public inputs then carry the action's domain separator and
|
|
259
|
+
struct hash, so a verifier checks **which** action was authorised — not merely
|
|
260
|
+
that somebody eligible signed something.
|
|
261
|
+
|
|
262
|
+
That matters once an agent moves money. `personal_sign` over 32 opaque bytes
|
|
263
|
+
shows a person a hex string, so they approve without seeing what they approve;
|
|
264
|
+
a typed action is rendered field by field in the wallet.
|
|
265
|
+
|
|
266
|
+
```typescript
|
|
267
|
+
import { CIRCUIT_IDS, validateTypedAction } from '@zkproofport-app/sdk';
|
|
268
|
+
|
|
269
|
+
const action = {
|
|
270
|
+
domain: {
|
|
271
|
+
name: 'MyVault',
|
|
272
|
+
version: '1',
|
|
273
|
+
chainId: 5042002, // Arc Testnet
|
|
274
|
+
verifyingContract: '0xYourContract',
|
|
275
|
+
},
|
|
276
|
+
types: {
|
|
277
|
+
Deposit: [
|
|
278
|
+
{ name: 'amount', type: 'uint256' },
|
|
279
|
+
{ name: 'nonce', type: 'uint256' },
|
|
280
|
+
],
|
|
281
|
+
},
|
|
282
|
+
primaryType: 'Deposit',
|
|
283
|
+
message: { amount: '1000000', nonce: '1' },
|
|
284
|
+
};
|
|
285
|
+
|
|
286
|
+
// Optional: catch a malformed action before sending it. The circuit hashes the
|
|
287
|
+
// action without reading it, so a broken one produces a valid proof of the
|
|
288
|
+
// wrong thing rather than failing.
|
|
289
|
+
const problem = validateTypedAction(action);
|
|
290
|
+
if (problem) throw new Error(problem);
|
|
291
|
+
|
|
292
|
+
const relay = await sdk.createRelayRequest(CIRCUIT_IDS.ARC_ELIGIBILITY, {
|
|
293
|
+
scope: 'myapp.com',
|
|
294
|
+
action,
|
|
295
|
+
});
|
|
296
|
+
```
|
|
297
|
+
|
|
298
|
+
`action` is required. A request without one is refused rather than proved
|
|
299
|
+
against some default, because the signature is the whole point.
|
|
300
|
+
|
|
301
|
+
**Testnet only.** The verifier is deployed on Arc Testnet (chain `5042002`) and
|
|
302
|
+
nowhere else. Circle has not published a mainnet chain id, so there is nothing
|
|
303
|
+
to point a production build at. The mobile app keeps the whole Arc network
|
|
304
|
+
behind Developer Mode for the same reason.
|
|
305
|
+
|
|
306
|
+
The public inputs are `signal_hash`, `domain_separator`, `action_hash`,
|
|
307
|
+
`signer_list_merkle_root`, `scope`, `nullifier` — a different order from every
|
|
308
|
+
other circuit, which is why `extractScopeFromPublicInputs` and
|
|
309
|
+
`extractNullifierFromPublicInputs` require the circuit id and refuse to guess.
|
|
310
|
+
|
|
245
311
|
## Planned Circuits
|
|
246
312
|
|
|
247
313
|
The identifiers below are reserved and exported, and the circuits exist — but they are **not officially supported yet**. Availability, input shape and public-input layout can change without a major version bump, so treat anything here as provisional. `CIRCUIT_SUPPORT_STATUS` reports each of them as `planned`.
|
|
@@ -949,7 +1015,8 @@ import type {
|
|
|
949
1015
|
|
|
950
1016
|
| Type | Description |
|
|
951
1017
|
|------|-------------|
|
|
952
|
-
| `CircuitId` | Union of the
|
|
1018
|
+
| `CircuitId` | Union of the eight canonical circuit IDs — `'coinbase_attestation' \| 'coinbase_country_attestation' \| 'oidc_domain_attestation' \| 'arc_eligibility' \| 'giwa_attestation' \| 'mdl_kr_ownership' \| 'mdl_kr_age' \| 'mdl_kr_region'`. Also exported from `@zkproofport-app/sdk/circuits` |
|
|
1019
|
+
| `TypedAction` | The EIP-712 action an `arc_eligibility` proof binds to: `{ domain, types, primaryType, message }` — the same object `eth_signTypedData_v4` takes |
|
|
953
1020
|
| `CircuitSupportStatus` | `'supported' \| 'planned'` — see [Circuit Identifiers](#circuit-identifiers) |
|
|
954
1021
|
| `CircuitType` | Alias of `CircuitId`. Kept as the name used throughout `ProofRequest`, `ProofResponse` and the SDK methods |
|
|
955
1022
|
| `ProofRequestStatus` | `'pending' \| 'completed' \| 'error' \| 'cancelled'` — the status on a `ProofResponse` |
|
|
@@ -957,6 +1024,7 @@ import type {
|
|
|
957
1024
|
| `CoinbaseCountryInputs` | Inputs for `coinbase_country_attestation`: `{ scope, countryList, isIncluded, userAddress?, rawTransaction? }` |
|
|
958
1025
|
| `OidcDomainInputs` | Inputs for `oidc_domain_attestation`: `{ domain, scope, provider? }` |
|
|
959
1026
|
| `MdlKrOwnershipInputs` | Inputs for `mdl_kr_ownership`: `{ scope, discloseFlags? }` |
|
|
1027
|
+
| `ArcEligibilityInputs` | Inputs for `arc_eligibility`: `{ scope, action, userAddress?, rawTransaction? }` — `action` is required |
|
|
960
1028
|
| `MdlKrAgeInputs` | Inputs for `mdl_kr_age`: `{ scope, ageThreshold }` |
|
|
961
1029
|
| `MdlKrRegionInputs` | Inputs for `mdl_kr_region`: `{ scope, targetRegion }` |
|
|
962
1030
|
| `CircuitInputs` | Union of every input type above (plus an empty-input form for circuits that need nothing from the dApp) |
|
package/dist/ProofportSDK.d.ts
CHANGED
|
@@ -842,7 +842,7 @@ export declare class ProofportSDK {
|
|
|
842
842
|
* const result = await sdk.waitForProof(relay.requestId);
|
|
843
843
|
* ```
|
|
844
844
|
*/
|
|
845
|
-
private static
|
|
845
|
+
private static needsWalletSignature;
|
|
846
846
|
createRelayRequest(circuit: CircuitType, inputs: CircuitInputs, options?: {
|
|
847
847
|
message?: string;
|
|
848
848
|
dappName?: string;
|
package/dist/circuits.d.ts
CHANGED
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
* not officially supported yet. Availability, inputs and public-input layout
|
|
31
31
|
* may change without a major version bump.
|
|
32
32
|
*/
|
|
33
|
-
export type CircuitSupportStatus = 'supported' | 'planned';
|
|
33
|
+
export type CircuitSupportStatus = 'supported' | 'experimental' | 'planned';
|
|
34
34
|
/**
|
|
35
35
|
* Canonical circuit identifiers, keyed by a stable constant name.
|
|
36
36
|
*
|
|
@@ -53,6 +53,8 @@ export declare const CIRCUIT_IDS: Readonly<{
|
|
|
53
53
|
readonly COINBASE_COUNTRY_ATTESTATION: "coinbase_country_attestation";
|
|
54
54
|
/** OIDC email-domain attestation. Officially supported. */
|
|
55
55
|
readonly OIDC_DOMAIN_ATTESTATION: "oidc_domain_attestation";
|
|
56
|
+
/** Arc eligibility: one EIP-712 action, authorized. Officially supported. */
|
|
57
|
+
readonly ARC_ELIGIBILITY: "arc_eligibility";
|
|
56
58
|
/** GIWA attestation. Planned — not officially supported yet. */
|
|
57
59
|
readonly GIWA_ATTESTATION: "giwa_attestation";
|
|
58
60
|
/** Korea Mobile ID ownership. Planned — not officially supported yet. */
|
|
@@ -86,14 +88,21 @@ export type CircuitId = (typeof CIRCUIT_IDS)[keyof typeof CIRCUIT_IDS];
|
|
|
86
88
|
*/
|
|
87
89
|
export declare const CIRCUIT_SUPPORT_STATUS: Readonly<Record<CircuitId, CircuitSupportStatus>>;
|
|
88
90
|
/**
|
|
89
|
-
* Where each circuit's verification key lives inside the
|
|
90
|
-
* repository, relative to its root.
|
|
91
|
+
* Where each circuit's verification key FILE lives inside the
|
|
92
|
+
* `zkproofport/circuits` repository, relative to its root.
|
|
91
93
|
*
|
|
92
94
|
* Off-chain verification needs the verification key and nothing else — no
|
|
93
95
|
* circuit bytecode, no witness. The key is public by nature: it is what anyone
|
|
94
96
|
* checking a proof must already have, and the Solidity verifiers deployed
|
|
95
97
|
* on-chain embed the same key.
|
|
96
98
|
*
|
|
99
|
+
* NOTE THE TRAILING `/vk` TWICE. In that repository `target/vk` is a DIRECTORY
|
|
100
|
+
* holding `vk`, `vk_hash` and `SHA256SUMS`; the key itself is `target/vk/vk`.
|
|
101
|
+
* These paths were first copied here from the mobile app, which keeps the
|
|
102
|
+
* directory and the filename as two fields and joins them — so taking only the
|
|
103
|
+
* directory produced a URL that answers 404, and the first browser to try
|
|
104
|
+
* off-chain verification said "Could not fetch the verification key (HTTP 404)".
|
|
105
|
+
*
|
|
97
106
|
* Exhaustive over {@link CircuitId} on purpose. A new circuit whose key path is
|
|
98
107
|
* not listed here fails to compile rather than failing at verification time,
|
|
99
108
|
* where the only symptom would be a proof that cannot be checked.
|
|
@@ -119,6 +128,17 @@ export declare const SUPPORTED_CIRCUIT_IDS: readonly CircuitId[];
|
|
|
119
128
|
*
|
|
120
129
|
* Derived from {@link CIRCUIT_SUPPORT_STATUS}, so it cannot fall out of sync.
|
|
121
130
|
*/
|
|
131
|
+
/**
|
|
132
|
+
* Circuits you can prove today, on a testnet, with everything subject to change.
|
|
133
|
+
*
|
|
134
|
+
* `arc_eligibility` is the reason this status exists. Calling it `planned`
|
|
135
|
+
* would be wrong — the circuit compiles, the verifier is deployed and a proof
|
|
136
|
+
* verifies against it — and calling it `supported` would be worse, because the
|
|
137
|
+
* only deployment is Arc Testnet, Circle has not published a mainnet chain id,
|
|
138
|
+
* and the public-input layout is still open. Neither existing word was true, so
|
|
139
|
+
* the honest move was a third word rather than picking the closer lie.
|
|
140
|
+
*/
|
|
141
|
+
export declare const EXPERIMENTAL_CIRCUIT_IDS: readonly CircuitId[];
|
|
122
142
|
export declare const PLANNED_CIRCUIT_IDS: readonly CircuitId[];
|
|
123
143
|
/**
|
|
124
144
|
* Narrows an unknown value to a canonical circuit identifier.
|
|
@@ -156,3 +176,25 @@ export declare function isSupportedCircuitId(value: unknown): value is CircuitId
|
|
|
156
176
|
* ```
|
|
157
177
|
*/
|
|
158
178
|
export declare function getCircuitSupportStatus(circuit: CircuitId): CircuitSupportStatus;
|
|
179
|
+
/**
|
|
180
|
+
* Whether a circuit's relay request must carry a wallet signature.
|
|
181
|
+
*
|
|
182
|
+
* The SDK checks this to fail fast — "Signer not set" locally beats a 401 from
|
|
183
|
+
* the relay two round trips later, with nothing saying which circuit needed
|
|
184
|
+
* what. The relay declares its OWN copy on purpose and does not import this
|
|
185
|
+
* one: it is a security boundary, and an auth policy that a published package
|
|
186
|
+
* can change is not a policy. A test in the relay asserts the two agree.
|
|
187
|
+
*
|
|
188
|
+
* `satisfies` and not an annotation, so a circuit added above is a compile
|
|
189
|
+
* error here until somebody decides which it is.
|
|
190
|
+
*/
|
|
191
|
+
export declare const CIRCUIT_NEEDS_WALLET_SIGNATURE: {
|
|
192
|
+
coinbase_attestation: true;
|
|
193
|
+
coinbase_country_attestation: true;
|
|
194
|
+
arc_eligibility: true;
|
|
195
|
+
oidc_domain_attestation: false;
|
|
196
|
+
mdl_kr_ownership: false;
|
|
197
|
+
mdl_kr_age: false;
|
|
198
|
+
mdl_kr_region: false;
|
|
199
|
+
giwa_attestation: false;
|
|
200
|
+
};
|
package/dist/circuits.esm.js
CHANGED
|
@@ -44,6 +44,8 @@ const CIRCUIT_IDS = Object.freeze({
|
|
|
44
44
|
COINBASE_COUNTRY_ATTESTATION: 'coinbase_country_attestation',
|
|
45
45
|
/** OIDC email-domain attestation. Officially supported. */
|
|
46
46
|
OIDC_DOMAIN_ATTESTATION: 'oidc_domain_attestation',
|
|
47
|
+
/** Arc eligibility: one EIP-712 action, authorized. Officially supported. */
|
|
48
|
+
ARC_ELIGIBILITY: 'arc_eligibility',
|
|
47
49
|
/** GIWA attestation. Planned — not officially supported yet. */
|
|
48
50
|
GIWA_ATTESTATION: 'giwa_attestation',
|
|
49
51
|
/** Korea Mobile ID ownership. Planned — not officially supported yet. */
|
|
@@ -72,32 +74,41 @@ const CIRCUIT_SUPPORT_STATUS = Object.freeze({
|
|
|
72
74
|
coinbase_attestation: 'supported',
|
|
73
75
|
coinbase_country_attestation: 'supported',
|
|
74
76
|
oidc_domain_attestation: 'supported',
|
|
77
|
+
arc_eligibility: 'experimental',
|
|
75
78
|
giwa_attestation: 'planned',
|
|
76
79
|
mdl_kr_ownership: 'planned',
|
|
77
80
|
mdl_kr_age: 'planned',
|
|
78
81
|
mdl_kr_region: 'planned',
|
|
79
82
|
});
|
|
80
83
|
/**
|
|
81
|
-
* Where each circuit's verification key lives inside the
|
|
82
|
-
* repository, relative to its root.
|
|
84
|
+
* Where each circuit's verification key FILE lives inside the
|
|
85
|
+
* `zkproofport/circuits` repository, relative to its root.
|
|
83
86
|
*
|
|
84
87
|
* Off-chain verification needs the verification key and nothing else — no
|
|
85
88
|
* circuit bytecode, no witness. The key is public by nature: it is what anyone
|
|
86
89
|
* checking a proof must already have, and the Solidity verifiers deployed
|
|
87
90
|
* on-chain embed the same key.
|
|
88
91
|
*
|
|
92
|
+
* NOTE THE TRAILING `/vk` TWICE. In that repository `target/vk` is a DIRECTORY
|
|
93
|
+
* holding `vk`, `vk_hash` and `SHA256SUMS`; the key itself is `target/vk/vk`.
|
|
94
|
+
* These paths were first copied here from the mobile app, which keeps the
|
|
95
|
+
* directory and the filename as two fields and joins them — so taking only the
|
|
96
|
+
* directory produced a URL that answers 404, and the first browser to try
|
|
97
|
+
* off-chain verification said "Could not fetch the verification key (HTTP 404)".
|
|
98
|
+
*
|
|
89
99
|
* Exhaustive over {@link CircuitId} on purpose. A new circuit whose key path is
|
|
90
100
|
* not listed here fails to compile rather than failing at verification time,
|
|
91
101
|
* where the only symptom would be a proof that cannot be checked.
|
|
92
102
|
*/
|
|
93
103
|
const CIRCUIT_VK_PATHS = Object.freeze({
|
|
94
|
-
coinbase_attestation: 'coinbase-attestation/target/vk',
|
|
95
|
-
coinbase_country_attestation: 'coinbase-country-attestation/target/vk',
|
|
96
|
-
oidc_domain_attestation: 'oidc-domain-attestation/target/vk',
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
104
|
+
coinbase_attestation: 'coinbase-attestation/target/vk/vk',
|
|
105
|
+
coinbase_country_attestation: 'coinbase-country-attestation/target/vk/vk',
|
|
106
|
+
oidc_domain_attestation: 'oidc-domain-attestation/target/vk/vk',
|
|
107
|
+
arc_eligibility: 'arc-eligibility/target/vk/vk',
|
|
108
|
+
giwa_attestation: 'giwa-attestation/target/vk/vk',
|
|
109
|
+
mdl_kr_ownership: 'mdl/kr-ownership/target/vk/vk',
|
|
110
|
+
mdl_kr_age: 'mdl/kr-age/target/vk/vk',
|
|
111
|
+
mdl_kr_region: 'mdl/kr-region/target/vk/vk',
|
|
101
112
|
});
|
|
102
113
|
/**
|
|
103
114
|
* Every canonical circuit identifier, in declaration order.
|
|
@@ -119,6 +130,17 @@ const SUPPORTED_CIRCUIT_IDS = Object.freeze(ALL_CIRCUIT_IDS.filter((id) => CIRCU
|
|
|
119
130
|
*
|
|
120
131
|
* Derived from {@link CIRCUIT_SUPPORT_STATUS}, so it cannot fall out of sync.
|
|
121
132
|
*/
|
|
133
|
+
/**
|
|
134
|
+
* Circuits you can prove today, on a testnet, with everything subject to change.
|
|
135
|
+
*
|
|
136
|
+
* `arc_eligibility` is the reason this status exists. Calling it `planned`
|
|
137
|
+
* would be wrong — the circuit compiles, the verifier is deployed and a proof
|
|
138
|
+
* verifies against it — and calling it `supported` would be worse, because the
|
|
139
|
+
* only deployment is Arc Testnet, Circle has not published a mainnet chain id,
|
|
140
|
+
* and the public-input layout is still open. Neither existing word was true, so
|
|
141
|
+
* the honest move was a third word rather than picking the closer lie.
|
|
142
|
+
*/
|
|
143
|
+
const EXPERIMENTAL_CIRCUIT_IDS = Object.freeze(ALL_CIRCUIT_IDS.filter(id => CIRCUIT_SUPPORT_STATUS[id] === 'experimental'));
|
|
122
144
|
const PLANNED_CIRCUIT_IDS = Object.freeze(ALL_CIRCUIT_IDS.filter((id) => CIRCUIT_SUPPORT_STATUS[id] === 'planned'));
|
|
123
145
|
/**
|
|
124
146
|
* Narrows an unknown value to a canonical circuit identifier.
|
|
@@ -165,6 +187,32 @@ function getCircuitSupportStatus(circuit) {
|
|
|
165
187
|
}
|
|
166
188
|
return CIRCUIT_SUPPORT_STATUS[circuit];
|
|
167
189
|
}
|
|
190
|
+
/**
|
|
191
|
+
* Whether a circuit's relay request must carry a wallet signature.
|
|
192
|
+
*
|
|
193
|
+
* The SDK checks this to fail fast — "Signer not set" locally beats a 401 from
|
|
194
|
+
* the relay two round trips later, with nothing saying which circuit needed
|
|
195
|
+
* what. The relay declares its OWN copy on purpose and does not import this
|
|
196
|
+
* one: it is a security boundary, and an auth policy that a published package
|
|
197
|
+
* can change is not a policy. A test in the relay asserts the two agree.
|
|
198
|
+
*
|
|
199
|
+
* `satisfies` and not an annotation, so a circuit added above is a compile
|
|
200
|
+
* error here until somebody decides which it is.
|
|
201
|
+
*/
|
|
202
|
+
const CIRCUIT_NEEDS_WALLET_SIGNATURE = {
|
|
203
|
+
coinbase_attestation: true,
|
|
204
|
+
coinbase_country_attestation: true,
|
|
205
|
+
// Same Coinbase-attested wallet as above; what changes is that it signs an
|
|
206
|
+
// EIP-712 action rather than signal_hash.
|
|
207
|
+
arc_eligibility: true,
|
|
208
|
+
// The signature is inside the OIDC identity token, checked by the prover.
|
|
209
|
+
oidc_domain_attestation: false,
|
|
210
|
+
// Web2 (OmniOne CX) flows with no wallet binding at all.
|
|
211
|
+
mdl_kr_ownership: false,
|
|
212
|
+
mdl_kr_age: false,
|
|
213
|
+
mdl_kr_region: false,
|
|
214
|
+
giwa_attestation: false,
|
|
215
|
+
};
|
|
168
216
|
|
|
169
|
-
export { ALL_CIRCUIT_IDS, CIRCUIT_IDS, CIRCUIT_SUPPORT_STATUS, CIRCUIT_VK_PATHS, PLANNED_CIRCUIT_IDS, SUPPORTED_CIRCUIT_IDS, getCircuitSupportStatus, isCircuitId, isSupportedCircuitId };
|
|
217
|
+
export { ALL_CIRCUIT_IDS, CIRCUIT_IDS, CIRCUIT_NEEDS_WALLET_SIGNATURE, CIRCUIT_SUPPORT_STATUS, CIRCUIT_VK_PATHS, EXPERIMENTAL_CIRCUIT_IDS, PLANNED_CIRCUIT_IDS, SUPPORTED_CIRCUIT_IDS, getCircuitSupportStatus, isCircuitId, isSupportedCircuitId };
|
|
170
218
|
//# sourceMappingURL=circuits.esm.js.map
|
package/dist/circuits.esm.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"circuits.esm.js","sources":["../src/circuits.ts"],"sourcesContent":["/**\n * Canonical ZKProofport circuit identifiers.\n *\n * This module is the single source of truth for circuit IDs. Every other layer\n * — the mobile app, the demo, the relay, server-side provers — reads its list\n * from here instead of keeping a private copy that silently drifts.\n *\n * It has **no imports and no dependencies**, so it can be pulled in on its own:\n *\n * ```typescript\n * import { CIRCUIT_IDS, isCircuitId } from '@zkproofport-app/sdk/circuits';\n * ```\n *\n * The same names are also re-exported from the package root\n * (`@zkproofport-app/sdk`) for callers that already import the SDK.\n *\n * ## Identifiers are canonical and case-sensitive\n *\n * Each ID is the circuit's `name` in its `Nargo.toml`, verbatim. The format is\n * lowercase with underscores. Hyphenated spellings (`coinbase-kyc`,\n * `mdl-kr-age`) are directory or UI route names in other repositories — they\n * are **not** circuit IDs, and passing one produces a nullifier mismatch or a\n * failed on-chain lookup rather than a clear error.\n */\n\n/**\n * Whether a circuit is officially supported today or still on the roadmap.\n *\n * - `supported` — generally available. Safe to build a product on.\n * - `planned` — the identifier is reserved and the circuit exists, but it is\n * not officially supported yet. Availability, inputs and public-input layout\n * may change without a major version bump.\n */\nexport type CircuitSupportStatus = 'supported' | 'planned';\n\n/**\n * Canonical circuit identifiers, keyed by a stable constant name.\n *\n * Prefer these constants over string literals so a rename is a compile error\n * rather than a runtime surprise.\n *\n * @example\n * ```typescript\n * import { CIRCUIT_IDS } from '@zkproofport-app/sdk/circuits';\n *\n * const relay = await sdk.createRelayRequest(CIRCUIT_IDS.COINBASE_ATTESTATION, {\n * scope: 'myapp.com',\n * });\n * ```\n */\nexport const CIRCUIT_IDS = Object.freeze({\n /** Coinbase KYC attestation. Officially supported. */\n COINBASE_ATTESTATION: 'coinbase_attestation',\n /** Coinbase country attestation (inclusion / exclusion). Officially supported. */\n COINBASE_COUNTRY_ATTESTATION: 'coinbase_country_attestation',\n /** OIDC email-domain attestation. Officially supported. */\n OIDC_DOMAIN_ATTESTATION: 'oidc_domain_attestation',\n /** GIWA attestation. Planned — not officially supported yet. */\n GIWA_ATTESTATION: 'giwa_attestation',\n /** Korea Mobile ID ownership. Planned — not officially supported yet. */\n MDL_KR_OWNERSHIP: 'mdl_kr_ownership',\n /** Korea Mobile ID age threshold. Planned — not officially supported yet. */\n MDL_KR_AGE: 'mdl_kr_age',\n /** Korea Mobile ID si/do region. Planned — not officially supported yet. */\n MDL_KR_REGION: 'mdl_kr_region',\n} as const);\n\n/**\n * Union of every canonical circuit identifier.\n *\n * `CircuitType` (exported from the package root) is an alias of this type — the\n * two names refer to the same union, and this module is where it is defined.\n */\nexport type CircuitId = (typeof CIRCUIT_IDS)[keyof typeof CIRCUIT_IDS];\n\n/**\n * Support status for every circuit.\n *\n * The record is exhaustive over {@link CircuitId}: adding an identifier without\n * giving it a status is a compile error, so this list cannot drift from\n * {@link CIRCUIT_IDS}.\n *\n * @example\n * ```typescript\n * import { CIRCUIT_SUPPORT_STATUS } from '@zkproofport-app/sdk/circuits';\n *\n * CIRCUIT_SUPPORT_STATUS.coinbase_attestation; // 'supported'\n * CIRCUIT_SUPPORT_STATUS.mdl_kr_age; // 'planned'\n * ```\n */\nexport const CIRCUIT_SUPPORT_STATUS: Readonly<Record<CircuitId, CircuitSupportStatus>> =\n Object.freeze({\n coinbase_attestation: 'supported',\n coinbase_country_attestation: 'supported',\n oidc_domain_attestation: 'supported',\n giwa_attestation: 'planned',\n mdl_kr_ownership: 'planned',\n mdl_kr_age: 'planned',\n mdl_kr_region: 'planned',\n } as const);\n\n/**\n * Where each circuit's verification key lives inside the `zkproofport/circuits`\n * repository, relative to its root.\n *\n * Off-chain verification needs the verification key and nothing else — no\n * circuit bytecode, no witness. The key is public by nature: it is what anyone\n * checking a proof must already have, and the Solidity verifiers deployed\n * on-chain embed the same key.\n *\n * Exhaustive over {@link CircuitId} on purpose. A new circuit whose key path is\n * not listed here fails to compile rather than failing at verification time,\n * where the only symptom would be a proof that cannot be checked.\n */\nexport const CIRCUIT_VK_PATHS: Readonly<Record<CircuitId, string>> = Object.freeze({\n coinbase_attestation: 'coinbase-attestation/target/vk',\n coinbase_country_attestation: 'coinbase-country-attestation/target/vk',\n oidc_domain_attestation: 'oidc-domain-attestation/target/vk',\n giwa_attestation: 'giwa-attestation/target/vk',\n mdl_kr_ownership: 'mdl/kr-ownership/target/vk',\n mdl_kr_age: 'mdl/kr-age/target/vk',\n mdl_kr_region: 'mdl/kr-region/target/vk',\n} as const);\n\n/**\n * Every canonical circuit identifier, in declaration order.\n *\n * Includes circuits that are still `planned`. Use {@link SUPPORTED_CIRCUIT_IDS}\n * when you only want the ones that are officially supported today.\n */\nexport const ALL_CIRCUIT_IDS: readonly CircuitId[] = Object.freeze(\n Object.values(CIRCUIT_IDS) as CircuitId[]\n);\n\n/**\n * Circuits that are officially supported today: the two Coinbase circuits and\n * OIDC domain attestation.\n *\n * Derived from {@link CIRCUIT_SUPPORT_STATUS}, so it cannot fall out of sync.\n */\nexport const SUPPORTED_CIRCUIT_IDS: readonly CircuitId[] = Object.freeze(\n ALL_CIRCUIT_IDS.filter((id) => CIRCUIT_SUPPORT_STATUS[id] === 'supported')\n);\n\n/**\n * Circuits whose identifiers are reserved but which are not officially\n * supported yet: GIWA attestation and the three Korea Mobile ID circuits.\n *\n * Derived from {@link CIRCUIT_SUPPORT_STATUS}, so it cannot fall out of sync.\n */\nexport const PLANNED_CIRCUIT_IDS: readonly CircuitId[] = Object.freeze(\n ALL_CIRCUIT_IDS.filter((id) => CIRCUIT_SUPPORT_STATUS[id] === 'planned')\n);\n\n/**\n * Narrows an unknown value to a canonical circuit identifier.\n *\n * Returns `false` for hyphenated route names such as `'coinbase-kyc'`, which\n * are not circuit IDs.\n *\n * @example\n * ```typescript\n * isCircuitId('coinbase_attestation'); // true\n * isCircuitId('coinbase-kyc'); // false\n * ```\n */\nexport function isCircuitId(value: unknown): value is CircuitId {\n return typeof value === 'string' && (ALL_CIRCUIT_IDS as readonly string[]).includes(value);\n}\n\n/**\n * Narrows an unknown value to a circuit identifier that is officially supported\n * today. Planned circuits return `false`.\n *\n * @example\n * ```typescript\n * isSupportedCircuitId('oidc_domain_attestation'); // true\n * isSupportedCircuitId('mdl_kr_age'); // false — planned\n * ```\n */\nexport function isSupportedCircuitId(value: unknown): value is CircuitId {\n return isCircuitId(value) && CIRCUIT_SUPPORT_STATUS[value] === 'supported';\n}\n\n/**\n * Returns the support status of a circuit.\n *\n * @param circuit - A canonical circuit identifier.\n * @throws Error when the value is not a canonical circuit identifier.\n *\n * @example\n * ```typescript\n * getCircuitSupportStatus('giwa_attestation'); // 'planned'\n * ```\n */\nexport function getCircuitSupportStatus(circuit: CircuitId): CircuitSupportStatus {\n if (!isCircuitId(circuit)) {\n throw new Error(\n `Unknown circuit '${String(circuit)}'. Expected one of: ${ALL_CIRCUIT_IDS.join(', ')}`\n );\n }\n return CIRCUIT_SUPPORT_STATUS[circuit];\n}\n"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;AAuBG;AAYH;;;;;;;;;;;;;;AAcG;AACI,MAAM,WAAW,GAAG,MAAM,CAAC,MAAM,CAAC;;AAEvC,IAAA,oBAAoB,EAAE,sBAAsB;;AAE5C,IAAA,4BAA4B,EAAE,8BAA8B;;AAE5D,IAAA,uBAAuB,EAAE,yBAAyB;;AAElD,IAAA,gBAAgB,EAAE,kBAAkB;;AAEpC,IAAA,gBAAgB,EAAE,kBAAkB;;AAEpC,IAAA,UAAU,EAAE,YAAY;;AAExB,IAAA,aAAa,EAAE,eAAe;AACtB,CAAA;AAUV;;;;;;;;;;;;;;AAcG;AACI,MAAM,sBAAsB,GACjC,MAAM,CAAC,MAAM,CAAC;AACZ,IAAA,oBAAoB,EAAE,WAAW;AACjC,IAAA,4BAA4B,EAAE,WAAW;AACzC,IAAA,uBAAuB,EAAE,WAAW;AACpC,IAAA,gBAAgB,EAAE,SAAS;AAC3B,IAAA,gBAAgB,EAAE,SAAS;AAC3B,IAAA,UAAU,EAAE,SAAS;AACrB,IAAA,aAAa,EAAE,SAAS;AAChB,CAAA;AAEZ;;;;;;;;;;;;AAYG;AACI,MAAM,gBAAgB,GAAwC,MAAM,CAAC,MAAM,CAAC;AACjF,IAAA,oBAAoB,EAAE,gCAAgC;AACtD,IAAA,4BAA4B,EAAE,wCAAwC;AACtE,IAAA,uBAAuB,EAAE,mCAAmC;AAC5D,IAAA,gBAAgB,EAAE,4BAA4B;AAC9C,IAAA,gBAAgB,EAAE,4BAA4B;AAC9C,IAAA,UAAU,EAAE,sBAAsB;AAClC,IAAA,aAAa,EAAE,yBAAyB;AAChC,CAAA;AAEV;;;;;AAKG;AACI,MAAM,eAAe,GAAyB,MAAM,CAAC,MAAM,CAChE,MAAM,CAAC,MAAM,CAAC,WAAW,CAAgB;AAG3C;;;;;AAKG;AACI,MAAM,qBAAqB,GAAyB,MAAM,CAAC,MAAM,CACtE,eAAe,CAAC,MAAM,CAAC,CAAC,EAAE,KAAK,sBAAsB,CAAC,EAAE,CAAC,KAAK,WAAW,CAAC;AAG5E;;;;;AAKG;AACI,MAAM,mBAAmB,GAAyB,MAAM,CAAC,MAAM,CACpE,eAAe,CAAC,MAAM,CAAC,CAAC,EAAE,KAAK,sBAAsB,CAAC,EAAE,CAAC,KAAK,SAAS,CAAC;AAG1E;;;;;;;;;;;AAWG;AACG,SAAU,WAAW,CAAC,KAAc,EAAA;IACxC,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAK,eAAqC,CAAC,QAAQ,CAAC,KAAK,CAAC;AAC5F;AAEA;;;;;;;;;AASG;AACG,SAAU,oBAAoB,CAAC,KAAc,EAAA;IACjD,OAAO,WAAW,CAAC,KAAK,CAAC,IAAI,sBAAsB,CAAC,KAAK,CAAC,KAAK,WAAW;AAC5E;AAEA;;;;;;;;;;AAUG;AACG,SAAU,uBAAuB,CAAC,OAAkB,EAAA;AACxD,IAAA,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,EAAE;AACzB,QAAA,MAAM,IAAI,KAAK,CACb,CAAA,iBAAA,EAAoB,MAAM,CAAC,OAAO,CAAC,CAAA,oBAAA,EAAuB,eAAe,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA,CAAE,CACvF;IACH;AACA,IAAA,OAAO,sBAAsB,CAAC,OAAO,CAAC;AACxC;;;;"}
|
|
1
|
+
{"version":3,"file":"circuits.esm.js","sources":["../src/circuits.ts"],"sourcesContent":["/**\n * Canonical ZKProofport circuit identifiers.\n *\n * This module is the single source of truth for circuit IDs. Every other layer\n * — the mobile app, the demo, the relay, server-side provers — reads its list\n * from here instead of keeping a private copy that silently drifts.\n *\n * It has **no imports and no dependencies**, so it can be pulled in on its own:\n *\n * ```typescript\n * import { CIRCUIT_IDS, isCircuitId } from '@zkproofport-app/sdk/circuits';\n * ```\n *\n * The same names are also re-exported from the package root\n * (`@zkproofport-app/sdk`) for callers that already import the SDK.\n *\n * ## Identifiers are canonical and case-sensitive\n *\n * Each ID is the circuit's `name` in its `Nargo.toml`, verbatim. The format is\n * lowercase with underscores. Hyphenated spellings (`coinbase-kyc`,\n * `mdl-kr-age`) are directory or UI route names in other repositories — they\n * are **not** circuit IDs, and passing one produces a nullifier mismatch or a\n * failed on-chain lookup rather than a clear error.\n */\n\n/**\n * Whether a circuit is officially supported today or still on the roadmap.\n *\n * - `supported` — generally available. Safe to build a product on.\n * - `planned` — the identifier is reserved and the circuit exists, but it is\n * not officially supported yet. Availability, inputs and public-input layout\n * may change without a major version bump.\n */\nexport type CircuitSupportStatus = 'supported' | 'experimental' | 'planned';\n\n/**\n * Canonical circuit identifiers, keyed by a stable constant name.\n *\n * Prefer these constants over string literals so a rename is a compile error\n * rather than a runtime surprise.\n *\n * @example\n * ```typescript\n * import { CIRCUIT_IDS } from '@zkproofport-app/sdk/circuits';\n *\n * const relay = await sdk.createRelayRequest(CIRCUIT_IDS.COINBASE_ATTESTATION, {\n * scope: 'myapp.com',\n * });\n * ```\n */\nexport const CIRCUIT_IDS = Object.freeze({\n /** Coinbase KYC attestation. Officially supported. */\n COINBASE_ATTESTATION: 'coinbase_attestation',\n /** Coinbase country attestation (inclusion / exclusion). Officially supported. */\n COINBASE_COUNTRY_ATTESTATION: 'coinbase_country_attestation',\n /** OIDC email-domain attestation. Officially supported. */\n OIDC_DOMAIN_ATTESTATION: 'oidc_domain_attestation',\n /** Arc eligibility: one EIP-712 action, authorized. Officially supported. */\n ARC_ELIGIBILITY: 'arc_eligibility',\n /** GIWA attestation. Planned — not officially supported yet. */\n GIWA_ATTESTATION: 'giwa_attestation',\n /** Korea Mobile ID ownership. Planned — not officially supported yet. */\n MDL_KR_OWNERSHIP: 'mdl_kr_ownership',\n /** Korea Mobile ID age threshold. Planned — not officially supported yet. */\n MDL_KR_AGE: 'mdl_kr_age',\n /** Korea Mobile ID si/do region. Planned — not officially supported yet. */\n MDL_KR_REGION: 'mdl_kr_region',\n} as const);\n\n/**\n * Union of every canonical circuit identifier.\n *\n * `CircuitType` (exported from the package root) is an alias of this type — the\n * two names refer to the same union, and this module is where it is defined.\n */\nexport type CircuitId = (typeof CIRCUIT_IDS)[keyof typeof CIRCUIT_IDS];\n\n/**\n * Support status for every circuit.\n *\n * The record is exhaustive over {@link CircuitId}: adding an identifier without\n * giving it a status is a compile error, so this list cannot drift from\n * {@link CIRCUIT_IDS}.\n *\n * @example\n * ```typescript\n * import { CIRCUIT_SUPPORT_STATUS } from '@zkproofport-app/sdk/circuits';\n *\n * CIRCUIT_SUPPORT_STATUS.coinbase_attestation; // 'supported'\n * CIRCUIT_SUPPORT_STATUS.mdl_kr_age; // 'planned'\n * ```\n */\nexport const CIRCUIT_SUPPORT_STATUS: Readonly<Record<CircuitId, CircuitSupportStatus>> =\n Object.freeze({\n coinbase_attestation: 'supported',\n coinbase_country_attestation: 'supported',\n oidc_domain_attestation: 'supported',\n arc_eligibility: 'experimental',\n giwa_attestation: 'planned',\n mdl_kr_ownership: 'planned',\n mdl_kr_age: 'planned',\n mdl_kr_region: 'planned',\n } as const);\n\n/**\n * Where each circuit's verification key FILE lives inside the\n * `zkproofport/circuits` repository, relative to its root.\n *\n * Off-chain verification needs the verification key and nothing else — no\n * circuit bytecode, no witness. The key is public by nature: it is what anyone\n * checking a proof must already have, and the Solidity verifiers deployed\n * on-chain embed the same key.\n *\n * NOTE THE TRAILING `/vk` TWICE. In that repository `target/vk` is a DIRECTORY\n * holding `vk`, `vk_hash` and `SHA256SUMS`; the key itself is `target/vk/vk`.\n * These paths were first copied here from the mobile app, which keeps the\n * directory and the filename as two fields and joins them — so taking only the\n * directory produced a URL that answers 404, and the first browser to try\n * off-chain verification said \"Could not fetch the verification key (HTTP 404)\".\n *\n * Exhaustive over {@link CircuitId} on purpose. A new circuit whose key path is\n * not listed here fails to compile rather than failing at verification time,\n * where the only symptom would be a proof that cannot be checked.\n */\nexport const CIRCUIT_VK_PATHS: Readonly<Record<CircuitId, string>> = Object.freeze({\n coinbase_attestation: 'coinbase-attestation/target/vk/vk',\n coinbase_country_attestation: 'coinbase-country-attestation/target/vk/vk',\n oidc_domain_attestation: 'oidc-domain-attestation/target/vk/vk',\n arc_eligibility: 'arc-eligibility/target/vk/vk',\n giwa_attestation: 'giwa-attestation/target/vk/vk',\n mdl_kr_ownership: 'mdl/kr-ownership/target/vk/vk',\n mdl_kr_age: 'mdl/kr-age/target/vk/vk',\n mdl_kr_region: 'mdl/kr-region/target/vk/vk',\n} as const);\n\n/**\n * Every canonical circuit identifier, in declaration order.\n *\n * Includes circuits that are still `planned`. Use {@link SUPPORTED_CIRCUIT_IDS}\n * when you only want the ones that are officially supported today.\n */\nexport const ALL_CIRCUIT_IDS: readonly CircuitId[] = Object.freeze(\n Object.values(CIRCUIT_IDS) as CircuitId[]\n);\n\n/**\n * Circuits that are officially supported today: the two Coinbase circuits and\n * OIDC domain attestation.\n *\n * Derived from {@link CIRCUIT_SUPPORT_STATUS}, so it cannot fall out of sync.\n */\nexport const SUPPORTED_CIRCUIT_IDS: readonly CircuitId[] = Object.freeze(\n ALL_CIRCUIT_IDS.filter((id) => CIRCUIT_SUPPORT_STATUS[id] === 'supported')\n);\n\n/**\n * Circuits whose identifiers are reserved but which are not officially\n * supported yet: GIWA attestation and the three Korea Mobile ID circuits.\n *\n * Derived from {@link CIRCUIT_SUPPORT_STATUS}, so it cannot fall out of sync.\n */\n/**\n * Circuits you can prove today, on a testnet, with everything subject to change.\n *\n * `arc_eligibility` is the reason this status exists. Calling it `planned`\n * would be wrong — the circuit compiles, the verifier is deployed and a proof\n * verifies against it — and calling it `supported` would be worse, because the\n * only deployment is Arc Testnet, Circle has not published a mainnet chain id,\n * and the public-input layout is still open. Neither existing word was true, so\n * the honest move was a third word rather than picking the closer lie.\n */\nexport const EXPERIMENTAL_CIRCUIT_IDS: readonly CircuitId[] = Object.freeze(\n ALL_CIRCUIT_IDS.filter(id => CIRCUIT_SUPPORT_STATUS[id] === 'experimental'),\n);\n\nexport const PLANNED_CIRCUIT_IDS: readonly CircuitId[] = Object.freeze(\n ALL_CIRCUIT_IDS.filter((id) => CIRCUIT_SUPPORT_STATUS[id] === 'planned')\n);\n\n/**\n * Narrows an unknown value to a canonical circuit identifier.\n *\n * Returns `false` for hyphenated route names such as `'coinbase-kyc'`, which\n * are not circuit IDs.\n *\n * @example\n * ```typescript\n * isCircuitId('coinbase_attestation'); // true\n * isCircuitId('coinbase-kyc'); // false\n * ```\n */\nexport function isCircuitId(value: unknown): value is CircuitId {\n return typeof value === 'string' && (ALL_CIRCUIT_IDS as readonly string[]).includes(value);\n}\n\n/**\n * Narrows an unknown value to a circuit identifier that is officially supported\n * today. Planned circuits return `false`.\n *\n * @example\n * ```typescript\n * isSupportedCircuitId('oidc_domain_attestation'); // true\n * isSupportedCircuitId('mdl_kr_age'); // false — planned\n * ```\n */\nexport function isSupportedCircuitId(value: unknown): value is CircuitId {\n return isCircuitId(value) && CIRCUIT_SUPPORT_STATUS[value] === 'supported';\n}\n\n/**\n * Returns the support status of a circuit.\n *\n * @param circuit - A canonical circuit identifier.\n * @throws Error when the value is not a canonical circuit identifier.\n *\n * @example\n * ```typescript\n * getCircuitSupportStatus('giwa_attestation'); // 'planned'\n * ```\n */\nexport function getCircuitSupportStatus(circuit: CircuitId): CircuitSupportStatus {\n if (!isCircuitId(circuit)) {\n throw new Error(\n `Unknown circuit '${String(circuit)}'. Expected one of: ${ALL_CIRCUIT_IDS.join(', ')}`\n );\n }\n return CIRCUIT_SUPPORT_STATUS[circuit];\n}\n\n/**\n * Whether a circuit's relay request must carry a wallet signature.\n *\n * The SDK checks this to fail fast — \"Signer not set\" locally beats a 401 from\n * the relay two round trips later, with nothing saying which circuit needed\n * what. The relay declares its OWN copy on purpose and does not import this\n * one: it is a security boundary, and an auth policy that a published package\n * can change is not a policy. A test in the relay asserts the two agree.\n *\n * `satisfies` and not an annotation, so a circuit added above is a compile\n * error here until somebody decides which it is.\n */\nexport const CIRCUIT_NEEDS_WALLET_SIGNATURE = {\n coinbase_attestation: true,\n coinbase_country_attestation: true,\n // Same Coinbase-attested wallet as above; what changes is that it signs an\n // EIP-712 action rather than signal_hash.\n arc_eligibility: true,\n // The signature is inside the OIDC identity token, checked by the prover.\n oidc_domain_attestation: false,\n // Web2 (OmniOne CX) flows with no wallet binding at all.\n mdl_kr_ownership: false,\n mdl_kr_age: false,\n mdl_kr_region: false,\n giwa_attestation: false,\n} satisfies Record<CircuitId, boolean>;\n"],"names":[],"mappings":"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"}
|
package/dist/circuits.js
CHANGED
|
@@ -46,6 +46,8 @@ const CIRCUIT_IDS = Object.freeze({
|
|
|
46
46
|
COINBASE_COUNTRY_ATTESTATION: 'coinbase_country_attestation',
|
|
47
47
|
/** OIDC email-domain attestation. Officially supported. */
|
|
48
48
|
OIDC_DOMAIN_ATTESTATION: 'oidc_domain_attestation',
|
|
49
|
+
/** Arc eligibility: one EIP-712 action, authorized. Officially supported. */
|
|
50
|
+
ARC_ELIGIBILITY: 'arc_eligibility',
|
|
49
51
|
/** GIWA attestation. Planned — not officially supported yet. */
|
|
50
52
|
GIWA_ATTESTATION: 'giwa_attestation',
|
|
51
53
|
/** Korea Mobile ID ownership. Planned — not officially supported yet. */
|
|
@@ -74,32 +76,41 @@ const CIRCUIT_SUPPORT_STATUS = Object.freeze({
|
|
|
74
76
|
coinbase_attestation: 'supported',
|
|
75
77
|
coinbase_country_attestation: 'supported',
|
|
76
78
|
oidc_domain_attestation: 'supported',
|
|
79
|
+
arc_eligibility: 'experimental',
|
|
77
80
|
giwa_attestation: 'planned',
|
|
78
81
|
mdl_kr_ownership: 'planned',
|
|
79
82
|
mdl_kr_age: 'planned',
|
|
80
83
|
mdl_kr_region: 'planned',
|
|
81
84
|
});
|
|
82
85
|
/**
|
|
83
|
-
* Where each circuit's verification key lives inside the
|
|
84
|
-
* repository, relative to its root.
|
|
86
|
+
* Where each circuit's verification key FILE lives inside the
|
|
87
|
+
* `zkproofport/circuits` repository, relative to its root.
|
|
85
88
|
*
|
|
86
89
|
* Off-chain verification needs the verification key and nothing else — no
|
|
87
90
|
* circuit bytecode, no witness. The key is public by nature: it is what anyone
|
|
88
91
|
* checking a proof must already have, and the Solidity verifiers deployed
|
|
89
92
|
* on-chain embed the same key.
|
|
90
93
|
*
|
|
94
|
+
* NOTE THE TRAILING `/vk` TWICE. In that repository `target/vk` is a DIRECTORY
|
|
95
|
+
* holding `vk`, `vk_hash` and `SHA256SUMS`; the key itself is `target/vk/vk`.
|
|
96
|
+
* These paths were first copied here from the mobile app, which keeps the
|
|
97
|
+
* directory and the filename as two fields and joins them — so taking only the
|
|
98
|
+
* directory produced a URL that answers 404, and the first browser to try
|
|
99
|
+
* off-chain verification said "Could not fetch the verification key (HTTP 404)".
|
|
100
|
+
*
|
|
91
101
|
* Exhaustive over {@link CircuitId} on purpose. A new circuit whose key path is
|
|
92
102
|
* not listed here fails to compile rather than failing at verification time,
|
|
93
103
|
* where the only symptom would be a proof that cannot be checked.
|
|
94
104
|
*/
|
|
95
105
|
const CIRCUIT_VK_PATHS = Object.freeze({
|
|
96
|
-
coinbase_attestation: 'coinbase-attestation/target/vk',
|
|
97
|
-
coinbase_country_attestation: 'coinbase-country-attestation/target/vk',
|
|
98
|
-
oidc_domain_attestation: 'oidc-domain-attestation/target/vk',
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
106
|
+
coinbase_attestation: 'coinbase-attestation/target/vk/vk',
|
|
107
|
+
coinbase_country_attestation: 'coinbase-country-attestation/target/vk/vk',
|
|
108
|
+
oidc_domain_attestation: 'oidc-domain-attestation/target/vk/vk',
|
|
109
|
+
arc_eligibility: 'arc-eligibility/target/vk/vk',
|
|
110
|
+
giwa_attestation: 'giwa-attestation/target/vk/vk',
|
|
111
|
+
mdl_kr_ownership: 'mdl/kr-ownership/target/vk/vk',
|
|
112
|
+
mdl_kr_age: 'mdl/kr-age/target/vk/vk',
|
|
113
|
+
mdl_kr_region: 'mdl/kr-region/target/vk/vk',
|
|
103
114
|
});
|
|
104
115
|
/**
|
|
105
116
|
* Every canonical circuit identifier, in declaration order.
|
|
@@ -121,6 +132,17 @@ const SUPPORTED_CIRCUIT_IDS = Object.freeze(ALL_CIRCUIT_IDS.filter((id) => CIRCU
|
|
|
121
132
|
*
|
|
122
133
|
* Derived from {@link CIRCUIT_SUPPORT_STATUS}, so it cannot fall out of sync.
|
|
123
134
|
*/
|
|
135
|
+
/**
|
|
136
|
+
* Circuits you can prove today, on a testnet, with everything subject to change.
|
|
137
|
+
*
|
|
138
|
+
* `arc_eligibility` is the reason this status exists. Calling it `planned`
|
|
139
|
+
* would be wrong — the circuit compiles, the verifier is deployed and a proof
|
|
140
|
+
* verifies against it — and calling it `supported` would be worse, because the
|
|
141
|
+
* only deployment is Arc Testnet, Circle has not published a mainnet chain id,
|
|
142
|
+
* and the public-input layout is still open. Neither existing word was true, so
|
|
143
|
+
* the honest move was a third word rather than picking the closer lie.
|
|
144
|
+
*/
|
|
145
|
+
const EXPERIMENTAL_CIRCUIT_IDS = Object.freeze(ALL_CIRCUIT_IDS.filter(id => CIRCUIT_SUPPORT_STATUS[id] === 'experimental'));
|
|
124
146
|
const PLANNED_CIRCUIT_IDS = Object.freeze(ALL_CIRCUIT_IDS.filter((id) => CIRCUIT_SUPPORT_STATUS[id] === 'planned'));
|
|
125
147
|
/**
|
|
126
148
|
* Narrows an unknown value to a canonical circuit identifier.
|
|
@@ -167,11 +189,39 @@ function getCircuitSupportStatus(circuit) {
|
|
|
167
189
|
}
|
|
168
190
|
return CIRCUIT_SUPPORT_STATUS[circuit];
|
|
169
191
|
}
|
|
192
|
+
/**
|
|
193
|
+
* Whether a circuit's relay request must carry a wallet signature.
|
|
194
|
+
*
|
|
195
|
+
* The SDK checks this to fail fast — "Signer not set" locally beats a 401 from
|
|
196
|
+
* the relay two round trips later, with nothing saying which circuit needed
|
|
197
|
+
* what. The relay declares its OWN copy on purpose and does not import this
|
|
198
|
+
* one: it is a security boundary, and an auth policy that a published package
|
|
199
|
+
* can change is not a policy. A test in the relay asserts the two agree.
|
|
200
|
+
*
|
|
201
|
+
* `satisfies` and not an annotation, so a circuit added above is a compile
|
|
202
|
+
* error here until somebody decides which it is.
|
|
203
|
+
*/
|
|
204
|
+
const CIRCUIT_NEEDS_WALLET_SIGNATURE = {
|
|
205
|
+
coinbase_attestation: true,
|
|
206
|
+
coinbase_country_attestation: true,
|
|
207
|
+
// Same Coinbase-attested wallet as above; what changes is that it signs an
|
|
208
|
+
// EIP-712 action rather than signal_hash.
|
|
209
|
+
arc_eligibility: true,
|
|
210
|
+
// The signature is inside the OIDC identity token, checked by the prover.
|
|
211
|
+
oidc_domain_attestation: false,
|
|
212
|
+
// Web2 (OmniOne CX) flows with no wallet binding at all.
|
|
213
|
+
mdl_kr_ownership: false,
|
|
214
|
+
mdl_kr_age: false,
|
|
215
|
+
mdl_kr_region: false,
|
|
216
|
+
giwa_attestation: false,
|
|
217
|
+
};
|
|
170
218
|
|
|
171
219
|
exports.ALL_CIRCUIT_IDS = ALL_CIRCUIT_IDS;
|
|
172
220
|
exports.CIRCUIT_IDS = CIRCUIT_IDS;
|
|
221
|
+
exports.CIRCUIT_NEEDS_WALLET_SIGNATURE = CIRCUIT_NEEDS_WALLET_SIGNATURE;
|
|
173
222
|
exports.CIRCUIT_SUPPORT_STATUS = CIRCUIT_SUPPORT_STATUS;
|
|
174
223
|
exports.CIRCUIT_VK_PATHS = CIRCUIT_VK_PATHS;
|
|
224
|
+
exports.EXPERIMENTAL_CIRCUIT_IDS = EXPERIMENTAL_CIRCUIT_IDS;
|
|
175
225
|
exports.PLANNED_CIRCUIT_IDS = PLANNED_CIRCUIT_IDS;
|
|
176
226
|
exports.SUPPORTED_CIRCUIT_IDS = SUPPORTED_CIRCUIT_IDS;
|
|
177
227
|
exports.getCircuitSupportStatus = getCircuitSupportStatus;
|
package/dist/circuits.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"circuits.js","sources":["../src/circuits.ts"],"sourcesContent":["/**\n * Canonical ZKProofport circuit identifiers.\n *\n * This module is the single source of truth for circuit IDs. Every other layer\n * — the mobile app, the demo, the relay, server-side provers — reads its list\n * from here instead of keeping a private copy that silently drifts.\n *\n * It has **no imports and no dependencies**, so it can be pulled in on its own:\n *\n * ```typescript\n * import { CIRCUIT_IDS, isCircuitId } from '@zkproofport-app/sdk/circuits';\n * ```\n *\n * The same names are also re-exported from the package root\n * (`@zkproofport-app/sdk`) for callers that already import the SDK.\n *\n * ## Identifiers are canonical and case-sensitive\n *\n * Each ID is the circuit's `name` in its `Nargo.toml`, verbatim. The format is\n * lowercase with underscores. Hyphenated spellings (`coinbase-kyc`,\n * `mdl-kr-age`) are directory or UI route names in other repositories — they\n * are **not** circuit IDs, and passing one produces a nullifier mismatch or a\n * failed on-chain lookup rather than a clear error.\n */\n\n/**\n * Whether a circuit is officially supported today or still on the roadmap.\n *\n * - `supported` — generally available. Safe to build a product on.\n * - `planned` — the identifier is reserved and the circuit exists, but it is\n * not officially supported yet. Availability, inputs and public-input layout\n * may change without a major version bump.\n */\nexport type CircuitSupportStatus = 'supported' | 'planned';\n\n/**\n * Canonical circuit identifiers, keyed by a stable constant name.\n *\n * Prefer these constants over string literals so a rename is a compile error\n * rather than a runtime surprise.\n *\n * @example\n * ```typescript\n * import { CIRCUIT_IDS } from '@zkproofport-app/sdk/circuits';\n *\n * const relay = await sdk.createRelayRequest(CIRCUIT_IDS.COINBASE_ATTESTATION, {\n * scope: 'myapp.com',\n * });\n * ```\n */\nexport const CIRCUIT_IDS = Object.freeze({\n /** Coinbase KYC attestation. Officially supported. */\n COINBASE_ATTESTATION: 'coinbase_attestation',\n /** Coinbase country attestation (inclusion / exclusion). Officially supported. */\n COINBASE_COUNTRY_ATTESTATION: 'coinbase_country_attestation',\n /** OIDC email-domain attestation. Officially supported. */\n OIDC_DOMAIN_ATTESTATION: 'oidc_domain_attestation',\n /** GIWA attestation. Planned — not officially supported yet. */\n GIWA_ATTESTATION: 'giwa_attestation',\n /** Korea Mobile ID ownership. Planned — not officially supported yet. */\n MDL_KR_OWNERSHIP: 'mdl_kr_ownership',\n /** Korea Mobile ID age threshold. Planned — not officially supported yet. */\n MDL_KR_AGE: 'mdl_kr_age',\n /** Korea Mobile ID si/do region. Planned — not officially supported yet. */\n MDL_KR_REGION: 'mdl_kr_region',\n} as const);\n\n/**\n * Union of every canonical circuit identifier.\n *\n * `CircuitType` (exported from the package root) is an alias of this type — the\n * two names refer to the same union, and this module is where it is defined.\n */\nexport type CircuitId = (typeof CIRCUIT_IDS)[keyof typeof CIRCUIT_IDS];\n\n/**\n * Support status for every circuit.\n *\n * The record is exhaustive over {@link CircuitId}: adding an identifier without\n * giving it a status is a compile error, so this list cannot drift from\n * {@link CIRCUIT_IDS}.\n *\n * @example\n * ```typescript\n * import { CIRCUIT_SUPPORT_STATUS } from '@zkproofport-app/sdk/circuits';\n *\n * CIRCUIT_SUPPORT_STATUS.coinbase_attestation; // 'supported'\n * CIRCUIT_SUPPORT_STATUS.mdl_kr_age; // 'planned'\n * ```\n */\nexport const CIRCUIT_SUPPORT_STATUS: Readonly<Record<CircuitId, CircuitSupportStatus>> =\n Object.freeze({\n coinbase_attestation: 'supported',\n coinbase_country_attestation: 'supported',\n oidc_domain_attestation: 'supported',\n giwa_attestation: 'planned',\n mdl_kr_ownership: 'planned',\n mdl_kr_age: 'planned',\n mdl_kr_region: 'planned',\n } as const);\n\n/**\n * Where each circuit's verification key lives inside the `zkproofport/circuits`\n * repository, relative to its root.\n *\n * Off-chain verification needs the verification key and nothing else — no\n * circuit bytecode, no witness. The key is public by nature: it is what anyone\n * checking a proof must already have, and the Solidity verifiers deployed\n * on-chain embed the same key.\n *\n * Exhaustive over {@link CircuitId} on purpose. A new circuit whose key path is\n * not listed here fails to compile rather than failing at verification time,\n * where the only symptom would be a proof that cannot be checked.\n */\nexport const CIRCUIT_VK_PATHS: Readonly<Record<CircuitId, string>> = Object.freeze({\n coinbase_attestation: 'coinbase-attestation/target/vk',\n coinbase_country_attestation: 'coinbase-country-attestation/target/vk',\n oidc_domain_attestation: 'oidc-domain-attestation/target/vk',\n giwa_attestation: 'giwa-attestation/target/vk',\n mdl_kr_ownership: 'mdl/kr-ownership/target/vk',\n mdl_kr_age: 'mdl/kr-age/target/vk',\n mdl_kr_region: 'mdl/kr-region/target/vk',\n} as const);\n\n/**\n * Every canonical circuit identifier, in declaration order.\n *\n * Includes circuits that are still `planned`. Use {@link SUPPORTED_CIRCUIT_IDS}\n * when you only want the ones that are officially supported today.\n */\nexport const ALL_CIRCUIT_IDS: readonly CircuitId[] = Object.freeze(\n Object.values(CIRCUIT_IDS) as CircuitId[]\n);\n\n/**\n * Circuits that are officially supported today: the two Coinbase circuits and\n * OIDC domain attestation.\n *\n * Derived from {@link CIRCUIT_SUPPORT_STATUS}, so it cannot fall out of sync.\n */\nexport const SUPPORTED_CIRCUIT_IDS: readonly CircuitId[] = Object.freeze(\n ALL_CIRCUIT_IDS.filter((id) => CIRCUIT_SUPPORT_STATUS[id] === 'supported')\n);\n\n/**\n * Circuits whose identifiers are reserved but which are not officially\n * supported yet: GIWA attestation and the three Korea Mobile ID circuits.\n *\n * Derived from {@link CIRCUIT_SUPPORT_STATUS}, so it cannot fall out of sync.\n */\nexport const PLANNED_CIRCUIT_IDS: readonly CircuitId[] = Object.freeze(\n ALL_CIRCUIT_IDS.filter((id) => CIRCUIT_SUPPORT_STATUS[id] === 'planned')\n);\n\n/**\n * Narrows an unknown value to a canonical circuit identifier.\n *\n * Returns `false` for hyphenated route names such as `'coinbase-kyc'`, which\n * are not circuit IDs.\n *\n * @example\n * ```typescript\n * isCircuitId('coinbase_attestation'); // true\n * isCircuitId('coinbase-kyc'); // false\n * ```\n */\nexport function isCircuitId(value: unknown): value is CircuitId {\n return typeof value === 'string' && (ALL_CIRCUIT_IDS as readonly string[]).includes(value);\n}\n\n/**\n * Narrows an unknown value to a circuit identifier that is officially supported\n * today. Planned circuits return `false`.\n *\n * @example\n * ```typescript\n * isSupportedCircuitId('oidc_domain_attestation'); // true\n * isSupportedCircuitId('mdl_kr_age'); // false — planned\n * ```\n */\nexport function isSupportedCircuitId(value: unknown): value is CircuitId {\n return isCircuitId(value) && CIRCUIT_SUPPORT_STATUS[value] === 'supported';\n}\n\n/**\n * Returns the support status of a circuit.\n *\n * @param circuit - A canonical circuit identifier.\n * @throws Error when the value is not a canonical circuit identifier.\n *\n * @example\n * ```typescript\n * getCircuitSupportStatus('giwa_attestation'); // 'planned'\n * ```\n */\nexport function getCircuitSupportStatus(circuit: CircuitId): CircuitSupportStatus {\n if (!isCircuitId(circuit)) {\n throw new Error(\n `Unknown circuit '${String(circuit)}'. Expected one of: ${ALL_CIRCUIT_IDS.join(', ')}`\n );\n }\n return CIRCUIT_SUPPORT_STATUS[circuit];\n}\n"],"names":[],"mappings":";;AAAA;;;;;;;;;;;;;;;;;;;;;;;AAuBG;AAYH;;;;;;;;;;;;;;AAcG;AACI,MAAM,WAAW,GAAG,MAAM,CAAC,MAAM,CAAC;;AAEvC,IAAA,oBAAoB,EAAE,sBAAsB;;AAE5C,IAAA,4BAA4B,EAAE,8BAA8B;;AAE5D,IAAA,uBAAuB,EAAE,yBAAyB;;AAElD,IAAA,gBAAgB,EAAE,kBAAkB;;AAEpC,IAAA,gBAAgB,EAAE,kBAAkB;;AAEpC,IAAA,UAAU,EAAE,YAAY;;AAExB,IAAA,aAAa,EAAE,eAAe;AACtB,CAAA;AAUV;;;;;;;;;;;;;;AAcG;AACI,MAAM,sBAAsB,GACjC,MAAM,CAAC,MAAM,CAAC;AACZ,IAAA,oBAAoB,EAAE,WAAW;AACjC,IAAA,4BAA4B,EAAE,WAAW;AACzC,IAAA,uBAAuB,EAAE,WAAW;AACpC,IAAA,gBAAgB,EAAE,SAAS;AAC3B,IAAA,gBAAgB,EAAE,SAAS;AAC3B,IAAA,UAAU,EAAE,SAAS;AACrB,IAAA,aAAa,EAAE,SAAS;AAChB,CAAA;AAEZ;;;;;;;;;;;;AAYG;AACI,MAAM,gBAAgB,GAAwC,MAAM,CAAC,MAAM,CAAC;AACjF,IAAA,oBAAoB,EAAE,gCAAgC;AACtD,IAAA,4BAA4B,EAAE,wCAAwC;AACtE,IAAA,uBAAuB,EAAE,mCAAmC;AAC5D,IAAA,gBAAgB,EAAE,4BAA4B;AAC9C,IAAA,gBAAgB,EAAE,4BAA4B;AAC9C,IAAA,UAAU,EAAE,sBAAsB;AAClC,IAAA,aAAa,EAAE,yBAAyB;AAChC,CAAA;AAEV;;;;;AAKG;AACI,MAAM,eAAe,GAAyB,MAAM,CAAC,MAAM,CAChE,MAAM,CAAC,MAAM,CAAC,WAAW,CAAgB;AAG3C;;;;;AAKG;AACI,MAAM,qBAAqB,GAAyB,MAAM,CAAC,MAAM,CACtE,eAAe,CAAC,MAAM,CAAC,CAAC,EAAE,KAAK,sBAAsB,CAAC,EAAE,CAAC,KAAK,WAAW,CAAC;AAG5E;;;;;AAKG;AACI,MAAM,mBAAmB,GAAyB,MAAM,CAAC,MAAM,CACpE,eAAe,CAAC,MAAM,CAAC,CAAC,EAAE,KAAK,sBAAsB,CAAC,EAAE,CAAC,KAAK,SAAS,CAAC;AAG1E;;;;;;;;;;;AAWG;AACG,SAAU,WAAW,CAAC,KAAc,EAAA;IACxC,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAK,eAAqC,CAAC,QAAQ,CAAC,KAAK,CAAC;AAC5F;AAEA;;;;;;;;;AASG;AACG,SAAU,oBAAoB,CAAC,KAAc,EAAA;IACjD,OAAO,WAAW,CAAC,KAAK,CAAC,IAAI,sBAAsB,CAAC,KAAK,CAAC,KAAK,WAAW;AAC5E;AAEA;;;;;;;;;;AAUG;AACG,SAAU,uBAAuB,CAAC,OAAkB,EAAA;AACxD,IAAA,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,EAAE;AACzB,QAAA,MAAM,IAAI,KAAK,CACb,CAAA,iBAAA,EAAoB,MAAM,CAAC,OAAO,CAAC,CAAA,oBAAA,EAAuB,eAAe,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA,CAAE,CACvF;IACH;AACA,IAAA,OAAO,sBAAsB,CAAC,OAAO,CAAC;AACxC;;;;;;;;;;;;"}
|
|
1
|
+
{"version":3,"file":"circuits.js","sources":["../src/circuits.ts"],"sourcesContent":["/**\n * Canonical ZKProofport circuit identifiers.\n *\n * This module is the single source of truth for circuit IDs. Every other layer\n * — the mobile app, the demo, the relay, server-side provers — reads its list\n * from here instead of keeping a private copy that silently drifts.\n *\n * It has **no imports and no dependencies**, so it can be pulled in on its own:\n *\n * ```typescript\n * import { CIRCUIT_IDS, isCircuitId } from '@zkproofport-app/sdk/circuits';\n * ```\n *\n * The same names are also re-exported from the package root\n * (`@zkproofport-app/sdk`) for callers that already import the SDK.\n *\n * ## Identifiers are canonical and case-sensitive\n *\n * Each ID is the circuit's `name` in its `Nargo.toml`, verbatim. The format is\n * lowercase with underscores. Hyphenated spellings (`coinbase-kyc`,\n * `mdl-kr-age`) are directory or UI route names in other repositories — they\n * are **not** circuit IDs, and passing one produces a nullifier mismatch or a\n * failed on-chain lookup rather than a clear error.\n */\n\n/**\n * Whether a circuit is officially supported today or still on the roadmap.\n *\n * - `supported` — generally available. Safe to build a product on.\n * - `planned` — the identifier is reserved and the circuit exists, but it is\n * not officially supported yet. Availability, inputs and public-input layout\n * may change without a major version bump.\n */\nexport type CircuitSupportStatus = 'supported' | 'experimental' | 'planned';\n\n/**\n * Canonical circuit identifiers, keyed by a stable constant name.\n *\n * Prefer these constants over string literals so a rename is a compile error\n * rather than a runtime surprise.\n *\n * @example\n * ```typescript\n * import { CIRCUIT_IDS } from '@zkproofport-app/sdk/circuits';\n *\n * const relay = await sdk.createRelayRequest(CIRCUIT_IDS.COINBASE_ATTESTATION, {\n * scope: 'myapp.com',\n * });\n * ```\n */\nexport const CIRCUIT_IDS = Object.freeze({\n /** Coinbase KYC attestation. Officially supported. */\n COINBASE_ATTESTATION: 'coinbase_attestation',\n /** Coinbase country attestation (inclusion / exclusion). Officially supported. */\n COINBASE_COUNTRY_ATTESTATION: 'coinbase_country_attestation',\n /** OIDC email-domain attestation. Officially supported. */\n OIDC_DOMAIN_ATTESTATION: 'oidc_domain_attestation',\n /** Arc eligibility: one EIP-712 action, authorized. Officially supported. */\n ARC_ELIGIBILITY: 'arc_eligibility',\n /** GIWA attestation. Planned — not officially supported yet. */\n GIWA_ATTESTATION: 'giwa_attestation',\n /** Korea Mobile ID ownership. Planned — not officially supported yet. */\n MDL_KR_OWNERSHIP: 'mdl_kr_ownership',\n /** Korea Mobile ID age threshold. Planned — not officially supported yet. */\n MDL_KR_AGE: 'mdl_kr_age',\n /** Korea Mobile ID si/do region. Planned — not officially supported yet. */\n MDL_KR_REGION: 'mdl_kr_region',\n} as const);\n\n/**\n * Union of every canonical circuit identifier.\n *\n * `CircuitType` (exported from the package root) is an alias of this type — the\n * two names refer to the same union, and this module is where it is defined.\n */\nexport type CircuitId = (typeof CIRCUIT_IDS)[keyof typeof CIRCUIT_IDS];\n\n/**\n * Support status for every circuit.\n *\n * The record is exhaustive over {@link CircuitId}: adding an identifier without\n * giving it a status is a compile error, so this list cannot drift from\n * {@link CIRCUIT_IDS}.\n *\n * @example\n * ```typescript\n * import { CIRCUIT_SUPPORT_STATUS } from '@zkproofport-app/sdk/circuits';\n *\n * CIRCUIT_SUPPORT_STATUS.coinbase_attestation; // 'supported'\n * CIRCUIT_SUPPORT_STATUS.mdl_kr_age; // 'planned'\n * ```\n */\nexport const CIRCUIT_SUPPORT_STATUS: Readonly<Record<CircuitId, CircuitSupportStatus>> =\n Object.freeze({\n coinbase_attestation: 'supported',\n coinbase_country_attestation: 'supported',\n oidc_domain_attestation: 'supported',\n arc_eligibility: 'experimental',\n giwa_attestation: 'planned',\n mdl_kr_ownership: 'planned',\n mdl_kr_age: 'planned',\n mdl_kr_region: 'planned',\n } as const);\n\n/**\n * Where each circuit's verification key FILE lives inside the\n * `zkproofport/circuits` repository, relative to its root.\n *\n * Off-chain verification needs the verification key and nothing else — no\n * circuit bytecode, no witness. The key is public by nature: it is what anyone\n * checking a proof must already have, and the Solidity verifiers deployed\n * on-chain embed the same key.\n *\n * NOTE THE TRAILING `/vk` TWICE. In that repository `target/vk` is a DIRECTORY\n * holding `vk`, `vk_hash` and `SHA256SUMS`; the key itself is `target/vk/vk`.\n * These paths were first copied here from the mobile app, which keeps the\n * directory and the filename as two fields and joins them — so taking only the\n * directory produced a URL that answers 404, and the first browser to try\n * off-chain verification said \"Could not fetch the verification key (HTTP 404)\".\n *\n * Exhaustive over {@link CircuitId} on purpose. A new circuit whose key path is\n * not listed here fails to compile rather than failing at verification time,\n * where the only symptom would be a proof that cannot be checked.\n */\nexport const CIRCUIT_VK_PATHS: Readonly<Record<CircuitId, string>> = Object.freeze({\n coinbase_attestation: 'coinbase-attestation/target/vk/vk',\n coinbase_country_attestation: 'coinbase-country-attestation/target/vk/vk',\n oidc_domain_attestation: 'oidc-domain-attestation/target/vk/vk',\n arc_eligibility: 'arc-eligibility/target/vk/vk',\n giwa_attestation: 'giwa-attestation/target/vk/vk',\n mdl_kr_ownership: 'mdl/kr-ownership/target/vk/vk',\n mdl_kr_age: 'mdl/kr-age/target/vk/vk',\n mdl_kr_region: 'mdl/kr-region/target/vk/vk',\n} as const);\n\n/**\n * Every canonical circuit identifier, in declaration order.\n *\n * Includes circuits that are still `planned`. Use {@link SUPPORTED_CIRCUIT_IDS}\n * when you only want the ones that are officially supported today.\n */\nexport const ALL_CIRCUIT_IDS: readonly CircuitId[] = Object.freeze(\n Object.values(CIRCUIT_IDS) as CircuitId[]\n);\n\n/**\n * Circuits that are officially supported today: the two Coinbase circuits and\n * OIDC domain attestation.\n *\n * Derived from {@link CIRCUIT_SUPPORT_STATUS}, so it cannot fall out of sync.\n */\nexport const SUPPORTED_CIRCUIT_IDS: readonly CircuitId[] = Object.freeze(\n ALL_CIRCUIT_IDS.filter((id) => CIRCUIT_SUPPORT_STATUS[id] === 'supported')\n);\n\n/**\n * Circuits whose identifiers are reserved but which are not officially\n * supported yet: GIWA attestation and the three Korea Mobile ID circuits.\n *\n * Derived from {@link CIRCUIT_SUPPORT_STATUS}, so it cannot fall out of sync.\n */\n/**\n * Circuits you can prove today, on a testnet, with everything subject to change.\n *\n * `arc_eligibility` is the reason this status exists. Calling it `planned`\n * would be wrong — the circuit compiles, the verifier is deployed and a proof\n * verifies against it — and calling it `supported` would be worse, because the\n * only deployment is Arc Testnet, Circle has not published a mainnet chain id,\n * and the public-input layout is still open. Neither existing word was true, so\n * the honest move was a third word rather than picking the closer lie.\n */\nexport const EXPERIMENTAL_CIRCUIT_IDS: readonly CircuitId[] = Object.freeze(\n ALL_CIRCUIT_IDS.filter(id => CIRCUIT_SUPPORT_STATUS[id] === 'experimental'),\n);\n\nexport const PLANNED_CIRCUIT_IDS: readonly CircuitId[] = Object.freeze(\n ALL_CIRCUIT_IDS.filter((id) => CIRCUIT_SUPPORT_STATUS[id] === 'planned')\n);\n\n/**\n * Narrows an unknown value to a canonical circuit identifier.\n *\n * Returns `false` for hyphenated route names such as `'coinbase-kyc'`, which\n * are not circuit IDs.\n *\n * @example\n * ```typescript\n * isCircuitId('coinbase_attestation'); // true\n * isCircuitId('coinbase-kyc'); // false\n * ```\n */\nexport function isCircuitId(value: unknown): value is CircuitId {\n return typeof value === 'string' && (ALL_CIRCUIT_IDS as readonly string[]).includes(value);\n}\n\n/**\n * Narrows an unknown value to a circuit identifier that is officially supported\n * today. Planned circuits return `false`.\n *\n * @example\n * ```typescript\n * isSupportedCircuitId('oidc_domain_attestation'); // true\n * isSupportedCircuitId('mdl_kr_age'); // false — planned\n * ```\n */\nexport function isSupportedCircuitId(value: unknown): value is CircuitId {\n return isCircuitId(value) && CIRCUIT_SUPPORT_STATUS[value] === 'supported';\n}\n\n/**\n * Returns the support status of a circuit.\n *\n * @param circuit - A canonical circuit identifier.\n * @throws Error when the value is not a canonical circuit identifier.\n *\n * @example\n * ```typescript\n * getCircuitSupportStatus('giwa_attestation'); // 'planned'\n * ```\n */\nexport function getCircuitSupportStatus(circuit: CircuitId): CircuitSupportStatus {\n if (!isCircuitId(circuit)) {\n throw new Error(\n `Unknown circuit '${String(circuit)}'. Expected one of: ${ALL_CIRCUIT_IDS.join(', ')}`\n );\n }\n return CIRCUIT_SUPPORT_STATUS[circuit];\n}\n\n/**\n * Whether a circuit's relay request must carry a wallet signature.\n *\n * The SDK checks this to fail fast — \"Signer not set\" locally beats a 401 from\n * the relay two round trips later, with nothing saying which circuit needed\n * what. The relay declares its OWN copy on purpose and does not import this\n * one: it is a security boundary, and an auth policy that a published package\n * can change is not a policy. A test in the relay asserts the two agree.\n *\n * `satisfies` and not an annotation, so a circuit added above is a compile\n * error here until somebody decides which it is.\n */\nexport const CIRCUIT_NEEDS_WALLET_SIGNATURE = {\n coinbase_attestation: true,\n coinbase_country_attestation: true,\n // Same Coinbase-attested wallet as above; what changes is that it signs an\n // EIP-712 action rather than signal_hash.\n arc_eligibility: true,\n // The signature is inside the OIDC identity token, checked by the prover.\n oidc_domain_attestation: false,\n // Web2 (OmniOne CX) flows with no wallet binding at all.\n mdl_kr_ownership: false,\n mdl_kr_age: false,\n mdl_kr_region: false,\n giwa_attestation: false,\n} satisfies Record<CircuitId, boolean>;\n"],"names":[],"mappings":"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"}
|