@provex/eas 1.9.2-rc.20260720143033.2906fda

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.
Files changed (2) hide show
  1. package/README.md +114 -0
  2. package/package.json +62 -0
package/README.md ADDED
@@ -0,0 +1,114 @@
1
+ # @provex/eas
2
+
3
+ Ethereum Attestation Service primitives behind Provex identity, age, and
4
+ release credentials — the schema definitions, the per-chain deployment
5
+ addresses, the claim encoders, and the decoders and signature-recovery
6
+ helpers a third party needs to **verify** a Provex credential.
7
+
8
+ Provex issues credentials as Ethereum Attestation Service **off-chain
9
+ attestations**: a signed EIP-712 payload carrying an encoded claim. Anyone
10
+ holding that payload can verify it without a blockchain read and without
11
+ asking Provex.
12
+
13
+ ## Install
14
+
15
+ ```
16
+ npm install @provex/eas viem
17
+ ```
18
+
19
+ `viem` is a peer dependency.
20
+
21
+ ## Entry points
22
+
23
+ | Import path | Contents | Runtime dependencies |
24
+ | --- | --- | --- |
25
+ | `@provex/eas` | Schema strings, chain deployment addresses, schema unique identifiers, claim encoders, off-chain and delegated builders | `viem`, Ethereum Attestation Service software development kit |
26
+ | `@provex/eas/build` | Claim encoders and attestation builders only | `viem`, Ethereum Attestation Service software development kit |
27
+ | `@provex/eas/verify` | Claim decoders and signature recovery | **`viem` only** |
28
+
29
+ If you are verifying rather than issuing, import from `@provex/eas/verify`.
30
+ That path never touches the Ethereum Attestation Service software
31
+ development kit, at any depth — the invariant is enforced by a test that
32
+ walks the module graph. It keeps browser bundles small and keeps your
33
+ dependency footprint to `viem`.
34
+
35
+ ## Schemas
36
+
37
+ ```
38
+ Identity bytes32 platformHash,string handle,address user,uint64 expiresAt
39
+ Release bytes32 dappKey,bytes32 manifestHash,string domain,string version
40
+ Age bytes32 nullifier,bool overN,uint8 threshold,bool identityVerified,uint64 expiresAt
41
+ ```
42
+
43
+ Field order is load-bearing: the decoders read positionally.
44
+
45
+ The age claim deliberately carries no personal field. The date of birth,
46
+ legal name, and account identifier stay inside the issuer's trust boundary;
47
+ only `overN` ("is at least `threshold` years old") escapes it. `overN: false`
48
+ is a real signed answer, not an absence. The subject is bound by the
49
+ attestation's `recipient`, not by anything inside the claim.
50
+
51
+ Exported as `PROVEX_IDENTITY_SCHEMA`, `PROVEX_RELEASE_SCHEMA`, and
52
+ `PROVEX_AGE_SCHEMA` from `@provex/eas`.
53
+
54
+ ## Schema unique identifiers
55
+
56
+ A schema's unique identifier is derived deterministically from the schema
57
+ itself:
58
+
59
+ ```
60
+ uid = keccak256(abi.encodePacked(schema, resolver, revocable))
61
+ ```
62
+
63
+ Provex registers every schema with `resolver = address(0)` and
64
+ `revocable = true`, so the unique identifier is reproducible from the schema
65
+ string alone — you do not have to trust a value we publish. The pinned
66
+ per-chain values are available through `getSchemaUid(chainId)`,
67
+ `getAgeSchemaUid(chainId)`, and `getReleaseSchemaUid(chainId)`.
68
+
69
+ ## Verifying a Provex age credential
70
+
71
+ ```ts
72
+ import {
73
+ decodeAgeClaim,
74
+ liftWireOffchainAttestation,
75
+ recoverOffchainAttestationSigner,
76
+ } from '@provex/eas/verify'
77
+
78
+ // `wire` is the attestation as it arrived — JSON, so its numeric fields are
79
+ // strings. `liftWireOffchainAttestation` validates the shape and lifts
80
+ // `time` / `expirationTime` back to bigint, which signature recovery needs.
81
+ const attestation = liftWireOffchainAttestation(wire)
82
+
83
+ const { valid, signer } = await recoverOffchainAttestationSigner(
84
+ attestation,
85
+ PROVEX_ATTESTER_ADDRESS, // optional; omit to recover without asserting
86
+ )
87
+
88
+ if (!valid) throw new Error('Attestation signature did not verify')
89
+
90
+ const claim = decodeAgeClaim(attestation.message.data)
91
+
92
+ const nowInSeconds = BigInt(Math.floor(Date.now() / 1000))
93
+ const accepted =
94
+ claim.overN &&
95
+ claim.threshold >= 18 &&
96
+ claim.expiresAt > nowInSeconds
97
+ ```
98
+
99
+ Three things are worth being explicit about:
100
+
101
+ 1. **Without `expectedSigner`, `valid` means only that recovery succeeded.**
102
+ The signer could be anyone. Compare `signer` against an attester you
103
+ actually trust before acting on the claim.
104
+ 2. **Check `expiresAt` yourself.** Signature validity says nothing about
105
+ freshness.
106
+ 3. **Check `threshold` against your own requirement.** A credential attesting
107
+ `overN` at `threshold: 13` is a valid signature that does not establish
108
+ that the holder is 18.
109
+
110
+ The `nullifier` is a stable per-subject identifier you can use to detect the
111
+ same person presenting twice, without learning who they are.
112
+
113
+ Identity and release credentials verify the same way, via `decodeIdentityClaim`
114
+ and `decodeReleaseClaim`.
package/package.json ADDED
@@ -0,0 +1,62 @@
1
+ {
2
+ "name": "@provex/eas",
3
+ "version": "1.9.2-rc.20260720143033.2906fda",
4
+ "main": "dist/index.js",
5
+ "types": "dist/index.d.ts",
6
+ "type": "module",
7
+ "repository": {
8
+ "type": "git",
9
+ "url": "git+https://github.com/provex-tech/monorepo.git",
10
+ "directory": "packages/eas"
11
+ },
12
+ "publishConfig": {
13
+ "access": "public"
14
+ },
15
+ "exports": {
16
+ ".": {
17
+ "import": "./dist/index.js",
18
+ "types": "./dist/index.d.ts"
19
+ },
20
+ "./build": {
21
+ "import": "./dist/eas-builder.js",
22
+ "types": "./dist/eas-builder.d.ts"
23
+ },
24
+ "./verify": {
25
+ "import": "./dist/offchain-verify.js",
26
+ "types": "./dist/offchain-verify.d.ts"
27
+ },
28
+ "./eas": {
29
+ "import": "./dist/eas.js",
30
+ "types": "./dist/eas.d.ts"
31
+ },
32
+ "./eas-builder": {
33
+ "import": "./dist/eas-builder.js",
34
+ "types": "./dist/eas-builder.d.ts"
35
+ },
36
+ "./offchain-verify": {
37
+ "import": "./dist/offchain-verify.js",
38
+ "types": "./dist/offchain-verify.d.ts"
39
+ }
40
+ },
41
+ "scripts": {
42
+ "build": "tsc",
43
+ "test": "node --import tsx --test 'src/**/*.test.ts'",
44
+ "test:watch": "node --import tsx --test --watch 'src/**/*.test.ts'"
45
+ },
46
+ "files": [
47
+ "dist",
48
+ "README.md"
49
+ ],
50
+ "dependencies": {
51
+ "@ethereum-attestation-service/eas-sdk": "^2.9.0"
52
+ },
53
+ "peerDependencies": {
54
+ "viem": "^2.0.0"
55
+ },
56
+ "devDependencies": {
57
+ "@types/node": "^22.0.0",
58
+ "tsx": "^4.20.3",
59
+ "typescript": "^5.9.2",
60
+ "viem": "^2.38.0"
61
+ }
62
+ }