@zkproofport-app/sdk 0.3.1 → 0.4.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 +69 -58
- package/dist/circuits.d.ts +42 -10
- package/dist/circuits.esm.js +47 -25
- package/dist/circuits.esm.js.map +1 -1
- package/dist/circuits.js +48 -24
- package/dist/circuits.js.map +1 -1
- package/dist/circuits.mjs +47 -25
- package/dist/circuits.mjs.map +1 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.esm.js +112 -76
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +113 -75
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +112 -76
- package/dist/index.mjs.map +1 -1
- package/dist/typedAction.d.ts +6 -1
- package/dist/typedAction.esm.js +6 -1
- package/dist/typedAction.esm.js.map +1 -1
- package/dist/typedAction.js +6 -1
- package/dist/typedAction.js.map +1 -1
- package/dist/typedAction.mjs +6 -1
- package/dist/typedAction.mjs.map +1 -1
- package/dist/types.d.ts +20 -12
- package/package.json +1 -1
package/dist/typedAction.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Checking the EIP-712 action
|
|
2
|
+
* Checking the EIP-712 action a `giwa_attestation` proof binds to.
|
|
3
3
|
*
|
|
4
4
|
* Three places need this answer and they have to agree: a dapp building the
|
|
5
5
|
* request, this SDK validating a deep link, and the mobile app before it asks
|
|
@@ -16,6 +16,11 @@ export type { TypedAction };
|
|
|
16
16
|
/**
|
|
17
17
|
* The reason the value is not a usable action, or `null` when it is one.
|
|
18
18
|
*
|
|
19
|
+
* Structural validation only, not application authorization policy. Consumers
|
|
20
|
+
* (e.g. EligibilityGate) must independently enforce the expected chain, verifying
|
|
21
|
+
* contract, actor, action parameters, nonce and deadline as applicable.
|
|
22
|
+
* EIP-712 signs only fields declared in types, not extra message properties.
|
|
23
|
+
*
|
|
19
24
|
* A string rather than a boolean because every caller shows it to somebody —
|
|
20
25
|
* a dapp developer reading a validation error, or a person looking at the
|
|
21
26
|
* mobile app's demo screen.
|
package/dist/typedAction.esm.js
CHANGED
|
@@ -2,13 +2,18 @@ const ADDRESS = /^0x[0-9a-fA-F]{40}$/;
|
|
|
2
2
|
/**
|
|
3
3
|
* The reason the value is not a usable action, or `null` when it is one.
|
|
4
4
|
*
|
|
5
|
+
* Structural validation only, not application authorization policy. Consumers
|
|
6
|
+
* (e.g. EligibilityGate) must independently enforce the expected chain, verifying
|
|
7
|
+
* contract, actor, action parameters, nonce and deadline as applicable.
|
|
8
|
+
* EIP-712 signs only fields declared in types, not extra message properties.
|
|
9
|
+
*
|
|
5
10
|
* A string rather than a boolean because every caller shows it to somebody —
|
|
6
11
|
* a dapp developer reading a validation error, or a person looking at the
|
|
7
12
|
* mobile app's demo screen.
|
|
8
13
|
*/
|
|
9
14
|
function validateTypedAction(value) {
|
|
10
15
|
if (value === undefined || value === null) {
|
|
11
|
-
return 'action is required
|
|
16
|
+
return 'action is required. The circuit proves that a wallet authorised ONE EIP-712 action; there is nothing to prove without it.';
|
|
12
17
|
}
|
|
13
18
|
if (typeof value !== 'object' || Array.isArray(value)) {
|
|
14
19
|
return 'action must be an object.';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"typedAction.esm.js","sources":["../src/typedAction.ts"],"sourcesContent":["/**\n * Checking the EIP-712 action
|
|
1
|
+
{"version":3,"file":"typedAction.esm.js","sources":["../src/typedAction.ts"],"sourcesContent":["/**\n * Checking the EIP-712 action a `giwa_attestation` proof binds to.\n *\n * Three places need this answer and they have to agree: a dapp building the\n * request, this SDK validating a deep link, and the mobile app before it asks\n * a wallet to sign. The check lived in the mobile app's demo screen and\n * nowhere else, so an action arriving from a dapp reached the prover\n * unexamined — and that is the path that ships.\n *\n * The circuit hashes the domain and the struct and proves the wallet signed\n * them. It never learns what the action says, so a malformed one does not\n * fail: it produces a valid proof of the wrong thing.\n */\nimport type { TypedAction } from './types';\n\nexport type { TypedAction };\n\nconst ADDRESS = /^0x[0-9a-fA-F]{40}$/;\n\n/**\n * The reason the value is not a usable action, or `null` when it is one.\n *\n * Structural validation only, not application authorization policy. Consumers\n * (e.g. EligibilityGate) must independently enforce the expected chain, verifying\n * contract, actor, action parameters, nonce and deadline as applicable.\n * EIP-712 signs only fields declared in types, not extra message properties.\n *\n * A string rather than a boolean because every caller shows it to somebody —\n * a dapp developer reading a validation error, or a person looking at the\n * mobile app's demo screen.\n */\nexport function validateTypedAction(value: unknown): string | null {\n if (value === undefined || value === null) {\n return 'action is required. The circuit proves that a wallet authorised ONE EIP-712 action; there is nothing to prove without it.';\n }\n if (typeof value !== 'object' || Array.isArray(value)) {\n return 'action must be an object.';\n }\n const a = value as Partial<TypedAction>;\n\n const d = a.domain;\n if (!d || typeof d !== 'object') {\n return 'action.domain is required.';\n }\n for (const k of ['name', 'version', 'verifyingContract'] as const) {\n if (typeof d[k] !== 'string' || !d[k]) {\n return `action.domain.${k} must be a non-empty string.`;\n }\n }\n if (typeof d.chainId !== 'number' || !Number.isInteger(d.chainId)) {\n return 'action.domain.chainId must be an integer.';\n }\n if (!ADDRESS.test(d.verifyingContract)) {\n return 'action.domain.verifyingContract must be a 20-byte hex address.';\n }\n\n if (!a.types || typeof a.types !== 'object' || Array.isArray(a.types)) {\n return 'action.types is required.';\n }\n if (typeof a.primaryType !== 'string' || !a.primaryType) {\n return 'action.primaryType is required.';\n }\n if (!(a.primaryType in a.types)) {\n return `action.primaryType '${a.primaryType}' is not one of the structs in action.types.`;\n }\n if (!a.message || typeof a.message !== 'object' || Array.isArray(a.message)) {\n return 'action.message is required.';\n }\n\n // Every field the struct declares must be present, or the wallet signs a\n // different message than the one the caller described.\n const fields = a.types[a.primaryType];\n if (!Array.isArray(fields) || fields.length === 0) {\n return `action.types.${a.primaryType} declares no fields.`;\n }\n const missing = fields\n .map(f => f?.name)\n .filter(n => typeof n === 'string' && !(n in (a.message as object)));\n if (missing.length) {\n return `action.message is missing: ${missing.join(', ')}`;\n }\n\n return null;\n}\n\n/** The action, or the reason it is not one. For text a person typed. */\nexport function parseTypedAction(text: string): { action: TypedAction } | { error: string } {\n let raw: unknown;\n try {\n raw = JSON.parse(text);\n } catch (e) {\n return { error: `Not valid JSON: ${(e as Error).message}` };\n }\n const error = validateTypedAction(raw);\n return error ? { error } : { action: raw as TypedAction };\n}\n"],"names":[],"mappings":"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"}
|
package/dist/typedAction.js
CHANGED
|
@@ -4,13 +4,18 @@ const ADDRESS = /^0x[0-9a-fA-F]{40}$/;
|
|
|
4
4
|
/**
|
|
5
5
|
* The reason the value is not a usable action, or `null` when it is one.
|
|
6
6
|
*
|
|
7
|
+
* Structural validation only, not application authorization policy. Consumers
|
|
8
|
+
* (e.g. EligibilityGate) must independently enforce the expected chain, verifying
|
|
9
|
+
* contract, actor, action parameters, nonce and deadline as applicable.
|
|
10
|
+
* EIP-712 signs only fields declared in types, not extra message properties.
|
|
11
|
+
*
|
|
7
12
|
* A string rather than a boolean because every caller shows it to somebody —
|
|
8
13
|
* a dapp developer reading a validation error, or a person looking at the
|
|
9
14
|
* mobile app's demo screen.
|
|
10
15
|
*/
|
|
11
16
|
function validateTypedAction(value) {
|
|
12
17
|
if (value === undefined || value === null) {
|
|
13
|
-
return 'action is required
|
|
18
|
+
return 'action is required. The circuit proves that a wallet authorised ONE EIP-712 action; there is nothing to prove without it.';
|
|
14
19
|
}
|
|
15
20
|
if (typeof value !== 'object' || Array.isArray(value)) {
|
|
16
21
|
return 'action must be an object.';
|
package/dist/typedAction.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"typedAction.js","sources":["../src/typedAction.ts"],"sourcesContent":["/**\n * Checking the EIP-712 action
|
|
1
|
+
{"version":3,"file":"typedAction.js","sources":["../src/typedAction.ts"],"sourcesContent":["/**\n * Checking the EIP-712 action a `giwa_attestation` proof binds to.\n *\n * Three places need this answer and they have to agree: a dapp building the\n * request, this SDK validating a deep link, and the mobile app before it asks\n * a wallet to sign. The check lived in the mobile app's demo screen and\n * nowhere else, so an action arriving from a dapp reached the prover\n * unexamined — and that is the path that ships.\n *\n * The circuit hashes the domain and the struct and proves the wallet signed\n * them. It never learns what the action says, so a malformed one does not\n * fail: it produces a valid proof of the wrong thing.\n */\nimport type { TypedAction } from './types';\n\nexport type { TypedAction };\n\nconst ADDRESS = /^0x[0-9a-fA-F]{40}$/;\n\n/**\n * The reason the value is not a usable action, or `null` when it is one.\n *\n * Structural validation only, not application authorization policy. Consumers\n * (e.g. EligibilityGate) must independently enforce the expected chain, verifying\n * contract, actor, action parameters, nonce and deadline as applicable.\n * EIP-712 signs only fields declared in types, not extra message properties.\n *\n * A string rather than a boolean because every caller shows it to somebody —\n * a dapp developer reading a validation error, or a person looking at the\n * mobile app's demo screen.\n */\nexport function validateTypedAction(value: unknown): string | null {\n if (value === undefined || value === null) {\n return 'action is required. The circuit proves that a wallet authorised ONE EIP-712 action; there is nothing to prove without it.';\n }\n if (typeof value !== 'object' || Array.isArray(value)) {\n return 'action must be an object.';\n }\n const a = value as Partial<TypedAction>;\n\n const d = a.domain;\n if (!d || typeof d !== 'object') {\n return 'action.domain is required.';\n }\n for (const k of ['name', 'version', 'verifyingContract'] as const) {\n if (typeof d[k] !== 'string' || !d[k]) {\n return `action.domain.${k} must be a non-empty string.`;\n }\n }\n if (typeof d.chainId !== 'number' || !Number.isInteger(d.chainId)) {\n return 'action.domain.chainId must be an integer.';\n }\n if (!ADDRESS.test(d.verifyingContract)) {\n return 'action.domain.verifyingContract must be a 20-byte hex address.';\n }\n\n if (!a.types || typeof a.types !== 'object' || Array.isArray(a.types)) {\n return 'action.types is required.';\n }\n if (typeof a.primaryType !== 'string' || !a.primaryType) {\n return 'action.primaryType is required.';\n }\n if (!(a.primaryType in a.types)) {\n return `action.primaryType '${a.primaryType}' is not one of the structs in action.types.`;\n }\n if (!a.message || typeof a.message !== 'object' || Array.isArray(a.message)) {\n return 'action.message is required.';\n }\n\n // Every field the struct declares must be present, or the wallet signs a\n // different message than the one the caller described.\n const fields = a.types[a.primaryType];\n if (!Array.isArray(fields) || fields.length === 0) {\n return `action.types.${a.primaryType} declares no fields.`;\n }\n const missing = fields\n .map(f => f?.name)\n .filter(n => typeof n === 'string' && !(n in (a.message as object)));\n if (missing.length) {\n return `action.message is missing: ${missing.join(', ')}`;\n }\n\n return null;\n}\n\n/** The action, or the reason it is not one. For text a person typed. */\nexport function parseTypedAction(text: string): { action: TypedAction } | { error: string } {\n let raw: unknown;\n try {\n raw = JSON.parse(text);\n } catch (e) {\n return { error: `Not valid JSON: ${(e as Error).message}` };\n }\n const error = validateTypedAction(raw);\n return error ? { error } : { action: raw as TypedAction };\n}\n"],"names":[],"mappings":"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"}
|
package/dist/typedAction.mjs
CHANGED
|
@@ -2,13 +2,18 @@ const ADDRESS = /^0x[0-9a-fA-F]{40}$/;
|
|
|
2
2
|
/**
|
|
3
3
|
* The reason the value is not a usable action, or `null` when it is one.
|
|
4
4
|
*
|
|
5
|
+
* Structural validation only, not application authorization policy. Consumers
|
|
6
|
+
* (e.g. EligibilityGate) must independently enforce the expected chain, verifying
|
|
7
|
+
* contract, actor, action parameters, nonce and deadline as applicable.
|
|
8
|
+
* EIP-712 signs only fields declared in types, not extra message properties.
|
|
9
|
+
*
|
|
5
10
|
* A string rather than a boolean because every caller shows it to somebody —
|
|
6
11
|
* a dapp developer reading a validation error, or a person looking at the
|
|
7
12
|
* mobile app's demo screen.
|
|
8
13
|
*/
|
|
9
14
|
function validateTypedAction(value) {
|
|
10
15
|
if (value === undefined || value === null) {
|
|
11
|
-
return 'action is required
|
|
16
|
+
return 'action is required. The circuit proves that a wallet authorised ONE EIP-712 action; there is nothing to prove without it.';
|
|
12
17
|
}
|
|
13
18
|
if (typeof value !== 'object' || Array.isArray(value)) {
|
|
14
19
|
return 'action must be an object.';
|
package/dist/typedAction.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"typedAction.mjs","sources":["../src/typedAction.ts"],"sourcesContent":["/**\n * Checking the EIP-712 action
|
|
1
|
+
{"version":3,"file":"typedAction.mjs","sources":["../src/typedAction.ts"],"sourcesContent":["/**\n * Checking the EIP-712 action a `giwa_attestation` proof binds to.\n *\n * Three places need this answer and they have to agree: a dapp building the\n * request, this SDK validating a deep link, and the mobile app before it asks\n * a wallet to sign. The check lived in the mobile app's demo screen and\n * nowhere else, so an action arriving from a dapp reached the prover\n * unexamined — and that is the path that ships.\n *\n * The circuit hashes the domain and the struct and proves the wallet signed\n * them. It never learns what the action says, so a malformed one does not\n * fail: it produces a valid proof of the wrong thing.\n */\nimport type { TypedAction } from './types';\n\nexport type { TypedAction };\n\nconst ADDRESS = /^0x[0-9a-fA-F]{40}$/;\n\n/**\n * The reason the value is not a usable action, or `null` when it is one.\n *\n * Structural validation only, not application authorization policy. Consumers\n * (e.g. EligibilityGate) must independently enforce the expected chain, verifying\n * contract, actor, action parameters, nonce and deadline as applicable.\n * EIP-712 signs only fields declared in types, not extra message properties.\n *\n * A string rather than a boolean because every caller shows it to somebody —\n * a dapp developer reading a validation error, or a person looking at the\n * mobile app's demo screen.\n */\nexport function validateTypedAction(value: unknown): string | null {\n if (value === undefined || value === null) {\n return 'action is required. The circuit proves that a wallet authorised ONE EIP-712 action; there is nothing to prove without it.';\n }\n if (typeof value !== 'object' || Array.isArray(value)) {\n return 'action must be an object.';\n }\n const a = value as Partial<TypedAction>;\n\n const d = a.domain;\n if (!d || typeof d !== 'object') {\n return 'action.domain is required.';\n }\n for (const k of ['name', 'version', 'verifyingContract'] as const) {\n if (typeof d[k] !== 'string' || !d[k]) {\n return `action.domain.${k} must be a non-empty string.`;\n }\n }\n if (typeof d.chainId !== 'number' || !Number.isInteger(d.chainId)) {\n return 'action.domain.chainId must be an integer.';\n }\n if (!ADDRESS.test(d.verifyingContract)) {\n return 'action.domain.verifyingContract must be a 20-byte hex address.';\n }\n\n if (!a.types || typeof a.types !== 'object' || Array.isArray(a.types)) {\n return 'action.types is required.';\n }\n if (typeof a.primaryType !== 'string' || !a.primaryType) {\n return 'action.primaryType is required.';\n }\n if (!(a.primaryType in a.types)) {\n return `action.primaryType '${a.primaryType}' is not one of the structs in action.types.`;\n }\n if (!a.message || typeof a.message !== 'object' || Array.isArray(a.message)) {\n return 'action.message is required.';\n }\n\n // Every field the struct declares must be present, or the wallet signs a\n // different message than the one the caller described.\n const fields = a.types[a.primaryType];\n if (!Array.isArray(fields) || fields.length === 0) {\n return `action.types.${a.primaryType} declares no fields.`;\n }\n const missing = fields\n .map(f => f?.name)\n .filter(n => typeof n === 'string' && !(n in (a.message as object)));\n if (missing.length) {\n return `action.message is missing: ${missing.join(', ')}`;\n }\n\n return null;\n}\n\n/** The action, or the reason it is not one. For text a person typed. */\nexport function parseTypedAction(text: string): { action: TypedAction } | { error: string } {\n let raw: unknown;\n try {\n raw = JSON.parse(text);\n } catch (e) {\n return { error: `Not valid JSON: ${(e as Error).message}` };\n }\n const error = validateTypedAction(raw);\n return error ? { error } : { action: raw as TypedAction };\n}\n"],"names":[],"mappings":"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"}
|
package/dist/types.d.ts
CHANGED
|
@@ -168,7 +168,7 @@ export interface MdlKrRegionInputs {
|
|
|
168
168
|
export interface EmptyInputs {
|
|
169
169
|
}
|
|
170
170
|
/**
|
|
171
|
-
* The EIP-712 action
|
|
171
|
+
* The EIP-712 action a `giwa_attestation` proof binds the wallet's signature to.
|
|
172
172
|
*
|
|
173
173
|
* Exactly what `eth_signTypedData_v4` takes, because that is what the wallet is
|
|
174
174
|
* shown and what it signs. The app does not build this — the dapp does — so the
|
|
@@ -178,7 +178,7 @@ export interface EmptyInputs {
|
|
|
178
178
|
* @example
|
|
179
179
|
* ```typescript
|
|
180
180
|
* const action: TypedAction = {
|
|
181
|
-
* domain: { name: 'MyVault', version: '1', chainId:
|
|
181
|
+
* domain: { name: 'MyVault', version: '1', chainId: 91342,
|
|
182
182
|
* verifyingContract: '0x…' },
|
|
183
183
|
* types: { Deposit: [ { name: 'amount', type: 'uint256' },
|
|
184
184
|
* { name: 'nonce', type: 'uint256' } ] },
|
|
@@ -205,34 +205,42 @@ export interface TypedAction {
|
|
|
205
205
|
message: Record<string, unknown>;
|
|
206
206
|
}
|
|
207
207
|
/**
|
|
208
|
-
* Input parameters for
|
|
208
|
+
* Input parameters for circuits that can bind an EIP-712 action
|
|
209
|
+
* (`giwa_attestation`).
|
|
209
210
|
*
|
|
210
|
-
*
|
|
211
|
-
* wallet signing a typed action instead of an opaque signal hash. The proof's
|
|
211
|
+
* The wallet signs a typed action instead of an opaque signal hash. The proof's
|
|
212
212
|
* public inputs then carry the action's domain separator and struct hash, so a
|
|
213
213
|
* verifier checks WHICH action was authorised — not merely that somebody
|
|
214
214
|
* eligible signed something.
|
|
215
215
|
*
|
|
216
|
-
* `action` is REQUIRED. There is no version of this circuit without one: its
|
|
217
|
-
* public inputs have the two slots and nothing else can fill them. Ask for
|
|
218
|
-
* `coinbase_attestation` when there is no action to bind.
|
|
219
|
-
*
|
|
220
216
|
* @property scope - Scope string for nullifier derivation
|
|
221
217
|
* @property action - The EIP-712 action the wallet signs
|
|
222
218
|
* @property userAddress - Ethereum address to prove ownership of (optional)
|
|
223
219
|
* @property rawTransaction - Raw attestation transaction data (optional)
|
|
224
220
|
*/
|
|
225
|
-
export interface
|
|
221
|
+
export interface ActionBoundInputs {
|
|
226
222
|
scope: string;
|
|
227
|
-
action: TypedAction;
|
|
228
223
|
userAddress?: string;
|
|
229
224
|
rawTransaction?: string;
|
|
225
|
+
/**
|
|
226
|
+
* The EIP-712 action this proof authorizes.
|
|
227
|
+
*
|
|
228
|
+
* Optional in the TYPE; whether a circuit requires it is the circuit's
|
|
229
|
+
* property (`giwa_attestation` signs its signal hash instead when none is
|
|
230
|
+
* given). That difference lives in `CIRCUIT_ACTION_BINDING` and is
|
|
231
|
+
* enforced by `createRelayRequest` and the deep-link validator, so it is not
|
|
232
|
+
* written a second time here -- two copies of one rule drift, and the copy
|
|
233
|
+
* that drifts is the one nobody is looking at.
|
|
234
|
+
*/
|
|
235
|
+
action?: TypedAction;
|
|
230
236
|
}
|
|
237
|
+
/** The same shape, for the circuit whose action is optional. */
|
|
238
|
+
export type GiwaAttestationInputs = ActionBoundInputs;
|
|
231
239
|
/**
|
|
232
240
|
* Union type of all circuit-specific input types.
|
|
233
241
|
* Each circuit type has a corresponding input interface.
|
|
234
242
|
*/
|
|
235
|
-
export type CircuitInputs = CoinbaseKycInputs |
|
|
243
|
+
export type CircuitInputs = CoinbaseKycInputs | ActionBoundInputs | CoinbaseCountryInputs | OidcDomainInputs | MdlKrOwnershipInputs | MdlKrAgeInputs | MdlKrRegionInputs | EmptyInputs;
|
|
236
244
|
/**
|
|
237
245
|
* Zero-knowledge proof request sent to mobile app via deep link.
|
|
238
246
|
*
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zkproofport-app/sdk",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"description": "ZKProofport SDK for requesting zero-knowledge proofs from the ZKProofport mobile app and verifying them on-chain",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"module": "dist/index.esm.js",
|