@hyperauth/contracts 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,119 @@
1
+ # HyperAuth Contracts
2
+
3
+ Smart contract wallet powered by passkeys. ERC-4337 account abstraction with P-256 signature verification via RIP-7212 precompile, plus soulbound session tokens.
4
+
5
+ ## Architecture
6
+
7
+ | Contract | Description |
8
+ |----------|-------------|
9
+ | `HyperAuthAccount` | ERC-4337 smart account — validates passkey (P-256) signatures via LibP256/RIP-7212 precompile |
10
+ | `HyperAuthFactory` | Deterministic CREATE2 deployment of accounts from passkey public keys (X, Y) |
11
+ | `DIDRegistry` | On-chain DID anchor — maps W3C DIDs to controller accounts with metadata CID |
12
+ | `AccountHelper` | Lens contract — single `eth_call` to fetch nonce, DID, pubkey, and deployment status |
13
+ | `SessionSBT` | Soulbound ERC-721 — non-transferable session tokens with mint/revoke lifecycle |
14
+ | `LibP256` | Library — reusable P-256 signature verification via RIP-7212 precompile at `0x100` |
15
+
16
+ ## Prerequisites
17
+
18
+ - [Foundry](https://book.getfoundry.sh/getting-started/installation)
19
+ - [Node.js](https://nodejs.org/) (v18+)
20
+ - [Docker](https://www.docker.com/) (for local Postgres)
21
+
22
+ ## Installation
23
+
24
+ ```bash
25
+ git clone https://github.com/hyperauth-org/contracts.git
26
+ cd contracts
27
+ forge install
28
+ ```
29
+
30
+ ## Build
31
+
32
+ ```bash
33
+ forge build
34
+ ```
35
+
36
+ ## Test
37
+
38
+ ```bash
39
+ forge test -vvv
40
+ ```
41
+
42
+ ## Format
43
+
44
+ ```bash
45
+ forge fmt
46
+ ```
47
+
48
+ ## Deploy
49
+
50
+ ```bash
51
+ # Set deployer private key
52
+ export PRIVATE_KEY=<your_private_key>
53
+
54
+ # Deploy to Base Sepolia
55
+ forge script script/Deploy.s.sol --rpc-url https://sepolia.base.org --broadcast
56
+ ```
57
+
58
+ ## Indexer
59
+
60
+ A Cloudflare Worker that indexes on-chain events (`DIDRegistered`, `DIDUpdated`, `DIDDeactivated`, `AliasRegistered`, `AccountCreated`) into Postgres. Runs on a cron schedule and writes to [Neon](https://neon.tech) (serverless Postgres) in production.
61
+
62
+ ### Neon DB Setup
63
+
64
+ 1. Create a free project at [neon.tech](https://neon.tech)
65
+ 2. Copy the connection string (looks like `postgresql://user:pass@ep-xyz.us-east-2.aws.neon.tech/neondb?sslmode=require`)
66
+ 3. Run the migration against your Neon database:
67
+
68
+ ```bash
69
+ psql "$DATABASE_URL" -f db/migrations/001_did_registration_schema.sql
70
+ ```
71
+
72
+ ### Local Development
73
+
74
+ For local development, Postgres runs via Docker and the schema is auto-applied on startup:
75
+
76
+ ```bash
77
+ # Start local Postgres (schema auto-migrates via docker-entrypoint-initdb.d)
78
+ docker compose up postgres -d
79
+
80
+ # Install indexer dependencies
81
+ cd indexer && npm install
82
+
83
+ # Create a .dev.vars file with your secrets
84
+ cat > .dev.vars <<EOF
85
+ DATABASE_URL=postgresql://hyperauth:password@localhost:5432/hyperauth_local
86
+ RPC_URL=https://sepolia.base.org
87
+ EOF
88
+
89
+ # Run the indexer locally (triggers on HTTP, not cron)
90
+ npm run dev
91
+
92
+ # Trigger a manual indexing run
93
+ curl http://localhost:8787/run
94
+
95
+ # Health check
96
+ curl http://localhost:8787/health
97
+ ```
98
+
99
+ ### Deploy to Cloudflare
100
+
101
+ ```bash
102
+ cd indexer
103
+
104
+ # Set secrets (one-time)
105
+ wrangler secret put DATABASE_URL # Neon connection string
106
+ wrangler secret put RPC_URL # Base Sepolia RPC endpoint
107
+
108
+ # Deploy
109
+ npm run deploy
110
+
111
+ # Tail logs
112
+ npm run tail
113
+ ```
114
+
115
+ The worker runs every minute and indexes up to 2,000 blocks per contract per invocation. Progress is tracked in the `indexer_cursors` table so it resumes from where it left off.
116
+
117
+ ## License
118
+
119
+ MIT
package/package.json ADDED
@@ -0,0 +1,29 @@
1
+ {
2
+ "name": "@hyperauth/contracts",
3
+ "version": "0.1.0",
4
+ "private": false,
5
+ "type": "module",
6
+ "description": "HyperAuth smart contract ABIs, deployment addresses, and KV sync tooling",
7
+ "main": "./dist/index.js",
8
+ "types": "./dist/index.d.ts",
9
+ "exports": {
10
+ ".": {
11
+ "types": "./dist/index.d.ts",
12
+ "import": "./dist/index.js"
13
+ }
14
+ },
15
+ "files": [
16
+ "dist",
17
+ "ts"
18
+ ],
19
+ "scripts": {
20
+ "generate": "node scripts/generate-sdk.mjs",
21
+ "build": "npm run generate && tsc",
22
+ "kv:generate": "node scripts/generate-kv-bulk.mjs",
23
+ "kv:push": "npm run kv:generate && wrangler kv bulk put .kv-bulk.json --namespace-id ec17209c9c8c4ece9a974774138c031e --remote"
24
+ },
25
+ "devDependencies": {
26
+ "typescript": "^5.7",
27
+ "wrangler": "^4"
28
+ }
29
+ }
@@ -0,0 +1,68 @@
1
+ /// Auto-generated by scripts/generate-sdk.mjs — do not edit manually.
2
+ export const accountHelperAbi = [
3
+ {
4
+ "type": "constructor",
5
+ "inputs": [
6
+ {
7
+ "name": "registry_",
8
+ "type": "address",
9
+ "internalType": "address"
10
+ }
11
+ ],
12
+ "stateMutability": "nonpayable"
13
+ },
14
+ {
15
+ "type": "function",
16
+ "name": "REGISTRY",
17
+ "inputs": [],
18
+ "outputs": [
19
+ {
20
+ "name": "",
21
+ "type": "address",
22
+ "internalType": "contract DIDRegistry"
23
+ }
24
+ ],
25
+ "stateMutability": "view"
26
+ },
27
+ {
28
+ "type": "function",
29
+ "name": "getAccountState",
30
+ "inputs": [
31
+ {
32
+ "name": "account",
33
+ "type": "address",
34
+ "internalType": "address"
35
+ }
36
+ ],
37
+ "outputs": [
38
+ {
39
+ "name": "state",
40
+ "type": "tuple",
41
+ "internalType": "struct AccountHelper.AccountState",
42
+ "components": [
43
+ {
44
+ "name": "nonce",
45
+ "type": "uint256",
46
+ "internalType": "uint256"
47
+ },
48
+ {
49
+ "name": "did",
50
+ "type": "bytes32",
51
+ "internalType": "bytes32"
52
+ },
53
+ {
54
+ "name": "isActive",
55
+ "type": "bool",
56
+ "internalType": "bool"
57
+ },
58
+ {
59
+ "name": "pubKey",
60
+ "type": "uint256[2]",
61
+ "internalType": "uint256[2]"
62
+ }
63
+ ]
64
+ }
65
+ ],
66
+ "stateMutability": "view"
67
+ }
68
+ ] as const;
@@ -0,0 +1,400 @@
1
+ /// Auto-generated by scripts/generate-sdk.mjs — do not edit manually.
2
+ export const didRegistryAbi = [
3
+ {
4
+ "type": "constructor",
5
+ "inputs": [],
6
+ "stateMutability": "nonpayable"
7
+ },
8
+ {
9
+ "type": "function",
10
+ "name": "aliases",
11
+ "inputs": [
12
+ {
13
+ "name": "",
14
+ "type": "bytes32",
15
+ "internalType": "bytes32"
16
+ }
17
+ ],
18
+ "outputs": [
19
+ {
20
+ "name": "",
21
+ "type": "bytes32",
22
+ "internalType": "bytes32"
23
+ }
24
+ ],
25
+ "stateMutability": "view"
26
+ },
27
+ {
28
+ "type": "function",
29
+ "name": "controllerToDid",
30
+ "inputs": [
31
+ {
32
+ "name": "",
33
+ "type": "address",
34
+ "internalType": "address"
35
+ }
36
+ ],
37
+ "outputs": [
38
+ {
39
+ "name": "",
40
+ "type": "bytes32",
41
+ "internalType": "bytes32"
42
+ }
43
+ ],
44
+ "stateMutability": "view"
45
+ },
46
+ {
47
+ "type": "function",
48
+ "name": "deactivate",
49
+ "inputs": [
50
+ {
51
+ "name": "didHash",
52
+ "type": "bytes32",
53
+ "internalType": "bytes32"
54
+ }
55
+ ],
56
+ "outputs": [],
57
+ "stateMutability": "nonpayable"
58
+ },
59
+ {
60
+ "type": "function",
61
+ "name": "didToAlias",
62
+ "inputs": [
63
+ {
64
+ "name": "",
65
+ "type": "bytes32",
66
+ "internalType": "bytes32"
67
+ }
68
+ ],
69
+ "outputs": [
70
+ {
71
+ "name": "",
72
+ "type": "bytes32",
73
+ "internalType": "bytes32"
74
+ }
75
+ ],
76
+ "stateMutability": "view"
77
+ },
78
+ {
79
+ "type": "function",
80
+ "name": "dids",
81
+ "inputs": [
82
+ {
83
+ "name": "",
84
+ "type": "bytes32",
85
+ "internalType": "bytes32"
86
+ }
87
+ ],
88
+ "outputs": [
89
+ {
90
+ "name": "controller",
91
+ "type": "address",
92
+ "internalType": "address"
93
+ },
94
+ {
95
+ "name": "created",
96
+ "type": "uint256",
97
+ "internalType": "uint256"
98
+ },
99
+ {
100
+ "name": "updated",
101
+ "type": "uint256",
102
+ "internalType": "uint256"
103
+ },
104
+ {
105
+ "name": "metadataCid",
106
+ "type": "string",
107
+ "internalType": "string"
108
+ },
109
+ {
110
+ "name": "active",
111
+ "type": "bool",
112
+ "internalType": "bool"
113
+ }
114
+ ],
115
+ "stateMutability": "view"
116
+ },
117
+ {
118
+ "type": "function",
119
+ "name": "owner",
120
+ "inputs": [],
121
+ "outputs": [
122
+ {
123
+ "name": "",
124
+ "type": "address",
125
+ "internalType": "address"
126
+ }
127
+ ],
128
+ "stateMutability": "view"
129
+ },
130
+ {
131
+ "type": "function",
132
+ "name": "register",
133
+ "inputs": [
134
+ {
135
+ "name": "didHash",
136
+ "type": "bytes32",
137
+ "internalType": "bytes32"
138
+ },
139
+ {
140
+ "name": "aliasHash",
141
+ "type": "bytes32",
142
+ "internalType": "bytes32"
143
+ },
144
+ {
145
+ "name": "metadataCid",
146
+ "type": "string",
147
+ "internalType": "string"
148
+ }
149
+ ],
150
+ "outputs": [],
151
+ "stateMutability": "nonpayable"
152
+ },
153
+ {
154
+ "type": "function",
155
+ "name": "renounceOwnership",
156
+ "inputs": [],
157
+ "outputs": [],
158
+ "stateMutability": "nonpayable"
159
+ },
160
+ {
161
+ "type": "function",
162
+ "name": "resolve",
163
+ "inputs": [
164
+ {
165
+ "name": "didHash",
166
+ "type": "bytes32",
167
+ "internalType": "bytes32"
168
+ }
169
+ ],
170
+ "outputs": [
171
+ {
172
+ "name": "",
173
+ "type": "tuple",
174
+ "internalType": "struct DIDRegistry.DidDocument",
175
+ "components": [
176
+ {
177
+ "name": "controller",
178
+ "type": "address",
179
+ "internalType": "address"
180
+ },
181
+ {
182
+ "name": "created",
183
+ "type": "uint256",
184
+ "internalType": "uint256"
185
+ },
186
+ {
187
+ "name": "updated",
188
+ "type": "uint256",
189
+ "internalType": "uint256"
190
+ },
191
+ {
192
+ "name": "metadataCid",
193
+ "type": "string",
194
+ "internalType": "string"
195
+ },
196
+ {
197
+ "name": "active",
198
+ "type": "bool",
199
+ "internalType": "bool"
200
+ }
201
+ ]
202
+ }
203
+ ],
204
+ "stateMutability": "view"
205
+ },
206
+ {
207
+ "type": "function",
208
+ "name": "resolveAlias",
209
+ "inputs": [
210
+ {
211
+ "name": "aliasHash",
212
+ "type": "bytes32",
213
+ "internalType": "bytes32"
214
+ }
215
+ ],
216
+ "outputs": [
217
+ {
218
+ "name": "",
219
+ "type": "tuple",
220
+ "internalType": "struct DIDRegistry.DidDocument",
221
+ "components": [
222
+ {
223
+ "name": "controller",
224
+ "type": "address",
225
+ "internalType": "address"
226
+ },
227
+ {
228
+ "name": "created",
229
+ "type": "uint256",
230
+ "internalType": "uint256"
231
+ },
232
+ {
233
+ "name": "updated",
234
+ "type": "uint256",
235
+ "internalType": "uint256"
236
+ },
237
+ {
238
+ "name": "metadataCid",
239
+ "type": "string",
240
+ "internalType": "string"
241
+ },
242
+ {
243
+ "name": "active",
244
+ "type": "bool",
245
+ "internalType": "bool"
246
+ }
247
+ ]
248
+ }
249
+ ],
250
+ "stateMutability": "view"
251
+ },
252
+ {
253
+ "type": "function",
254
+ "name": "transferOwnership",
255
+ "inputs": [
256
+ {
257
+ "name": "newOwner",
258
+ "type": "address",
259
+ "internalType": "address"
260
+ }
261
+ ],
262
+ "outputs": [],
263
+ "stateMutability": "nonpayable"
264
+ },
265
+ {
266
+ "type": "function",
267
+ "name": "update",
268
+ "inputs": [
269
+ {
270
+ "name": "didHash",
271
+ "type": "bytes32",
272
+ "internalType": "bytes32"
273
+ },
274
+ {
275
+ "name": "newMetadataCid",
276
+ "type": "string",
277
+ "internalType": "string"
278
+ }
279
+ ],
280
+ "outputs": [],
281
+ "stateMutability": "nonpayable"
282
+ },
283
+ {
284
+ "type": "event",
285
+ "name": "AliasRegistered",
286
+ "inputs": [
287
+ {
288
+ "name": "aliasHash",
289
+ "type": "bytes32",
290
+ "indexed": true,
291
+ "internalType": "bytes32"
292
+ },
293
+ {
294
+ "name": "didHash",
295
+ "type": "bytes32",
296
+ "indexed": true,
297
+ "internalType": "bytes32"
298
+ }
299
+ ],
300
+ "anonymous": false
301
+ },
302
+ {
303
+ "type": "event",
304
+ "name": "DIDDeactivated",
305
+ "inputs": [
306
+ {
307
+ "name": "didHash",
308
+ "type": "bytes32",
309
+ "indexed": true,
310
+ "internalType": "bytes32"
311
+ }
312
+ ],
313
+ "anonymous": false
314
+ },
315
+ {
316
+ "type": "event",
317
+ "name": "DIDRegistered",
318
+ "inputs": [
319
+ {
320
+ "name": "didHash",
321
+ "type": "bytes32",
322
+ "indexed": true,
323
+ "internalType": "bytes32"
324
+ },
325
+ {
326
+ "name": "controller",
327
+ "type": "address",
328
+ "indexed": true,
329
+ "internalType": "address"
330
+ },
331
+ {
332
+ "name": "metadataCid",
333
+ "type": "string",
334
+ "indexed": false,
335
+ "internalType": "string"
336
+ }
337
+ ],
338
+ "anonymous": false
339
+ },
340
+ {
341
+ "type": "event",
342
+ "name": "DIDUpdated",
343
+ "inputs": [
344
+ {
345
+ "name": "didHash",
346
+ "type": "bytes32",
347
+ "indexed": true,
348
+ "internalType": "bytes32"
349
+ },
350
+ {
351
+ "name": "newMetadataCid",
352
+ "type": "string",
353
+ "indexed": false,
354
+ "internalType": "string"
355
+ }
356
+ ],
357
+ "anonymous": false
358
+ },
359
+ {
360
+ "type": "event",
361
+ "name": "OwnershipTransferred",
362
+ "inputs": [
363
+ {
364
+ "name": "previousOwner",
365
+ "type": "address",
366
+ "indexed": true,
367
+ "internalType": "address"
368
+ },
369
+ {
370
+ "name": "newOwner",
371
+ "type": "address",
372
+ "indexed": true,
373
+ "internalType": "address"
374
+ }
375
+ ],
376
+ "anonymous": false
377
+ },
378
+ {
379
+ "type": "error",
380
+ "name": "OwnableInvalidOwner",
381
+ "inputs": [
382
+ {
383
+ "name": "owner",
384
+ "type": "address",
385
+ "internalType": "address"
386
+ }
387
+ ]
388
+ },
389
+ {
390
+ "type": "error",
391
+ "name": "OwnableUnauthorizedAccount",
392
+ "inputs": [
393
+ {
394
+ "name": "account",
395
+ "type": "address",
396
+ "internalType": "address"
397
+ }
398
+ ]
399
+ }
400
+ ] as const;