epistery 1.1.4 → 1.2.2

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 (69) hide show
  1. package/CLI.md +51 -6
  2. package/EpisteryRegistry.md +396 -0
  3. package/artifacts/build-info/9b85c8f19813050589c4ca647079da4e.json +1 -0
  4. package/artifacts/build-info/b0d21f00b5b6ae1bd915b0ac69b049ab.json +1 -0
  5. package/artifacts/contracts/IdentityContract.sol/IdentityContract.dbg.json +1 -1
  6. package/artifacts/contracts/IdentityContract.sol/IdentityContract.json +433 -3
  7. package/artifacts/contracts/agent.sol/Agent.dbg.json +1 -1
  8. package/artifacts/contracts/agent.sol/Agent.json +734 -9
  9. package/client/delegate.html +403 -0
  10. package/client/delegation.js +232 -0
  11. package/client/notabot.js +679 -0
  12. package/client/status.html +387 -17
  13. package/client/wallet.js +150 -137
  14. package/client/witness.js +441 -34
  15. package/contracts/IdentityContract.sol +253 -3
  16. package/contracts/agent.sol +598 -20
  17. package/default.ini +18 -1
  18. package/dist/api.d.ts +2 -0
  19. package/dist/api.d.ts.map +1 -0
  20. package/dist/api.js +130 -0
  21. package/dist/api.js.map +1 -0
  22. package/dist/controllers/baseController.d.ts +8 -0
  23. package/dist/controllers/baseController.d.ts.map +1 -0
  24. package/dist/controllers/baseController.js +25 -0
  25. package/dist/controllers/baseController.js.map +1 -0
  26. package/dist/controllers/create/CreateController.d.ts +6 -0
  27. package/dist/controllers/create/CreateController.d.ts.map +1 -0
  28. package/dist/controllers/create/CreateController.js +17 -0
  29. package/dist/controllers/create/CreateController.js.map +1 -0
  30. package/dist/controllers/ssl/SSLController.d.ts +17 -0
  31. package/dist/controllers/ssl/SSLController.d.ts.map +1 -0
  32. package/dist/controllers/ssl/SSLController.js +129 -0
  33. package/dist/controllers/ssl/SSLController.js.map +1 -0
  34. package/dist/controllers/status/StatusController.d.ts +6 -0
  35. package/dist/controllers/status/StatusController.d.ts.map +1 -0
  36. package/dist/controllers/status/StatusController.js +29 -0
  37. package/dist/controllers/status/StatusController.js.map +1 -0
  38. package/dist/controllers/write/WriteController.d.ts +7 -0
  39. package/dist/controllers/write/WriteController.d.ts.map +1 -0
  40. package/dist/controllers/write/WriteController.js +50 -0
  41. package/dist/controllers/write/WriteController.js.map +1 -0
  42. package/dist/epistery.d.ts +152 -1
  43. package/dist/epistery.d.ts.map +1 -1
  44. package/dist/epistery.js +1155 -19
  45. package/dist/epistery.js.map +1 -1
  46. package/dist/utils/Aqua.d.ts.map +1 -1
  47. package/dist/utils/Aqua.js +3 -0
  48. package/dist/utils/Aqua.js.map +1 -1
  49. package/dist/utils/Config.js +18 -1
  50. package/dist/utils/Config.js.map +1 -1
  51. package/dist/utils/Utils.d.ts +78 -7
  52. package/dist/utils/Utils.d.ts.map +1 -1
  53. package/dist/utils/Utils.js +391 -87
  54. package/dist/utils/Utils.js.map +1 -1
  55. package/dist/utils/types.d.ts +103 -3
  56. package/dist/utils/types.d.ts.map +1 -1
  57. package/docs/DELEGATION.md +261 -0
  58. package/docs/NotabotScore.md +723 -0
  59. package/hardhat.config.js +29 -2
  60. package/index.mjs +995 -63
  61. package/package.json +4 -3
  62. package/scripts/deploy-agent.js +96 -17
  63. package/src/epistery.ts +1408 -16
  64. package/src/utils/Aqua.ts +4 -0
  65. package/src/utils/Config.ts +18 -1
  66. package/src/utils/Utils.ts +503 -99
  67. package/src/utils/types.ts +128 -3
  68. package/test/server.mjs +1 -1
  69. package/artifacts/build-info/ed6400aaa48fa196bace39d5f250d971.json +0 -1
package/CLI.md CHANGED
@@ -174,9 +174,12 @@ email=
174
174
  url=https://rootz.digital/api/v0
175
175
 
176
176
  [default.provider]
177
- chainId=420420422,
178
- name=polkadot-hub-testnet
179
- rpc=https://testnet-passet-hub-eth-rpc.polkadot.io
177
+ chainId=1
178
+ name=Ethereum Mainnet
179
+ rpc=https://eth.llamarpc.com
180
+ nativeCurrencyName=Ether
181
+ nativeCurrencySymbol=ETH
182
+ nativeCurrencyDecimals=18
180
183
 
181
184
  [cli]
182
185
  default_domain=localhost
@@ -195,11 +198,53 @@ publicKey=0x04...
195
198
  privateKey=0x...
196
199
 
197
200
  [provider]
198
- chainId=420420422,
199
- name=polkadot-hub-testnet
200
- rpc=https://testnet-passet-hub-eth-rpc.polkadot.io
201
+ chainId=137
202
+ name=Polygon Mainnet
203
+ rpc=https://polygon-rpc.com
204
+ nativeCurrencyName=POL
205
+ nativeCurrencySymbol=POL
206
+ nativeCurrencyDecimals=18
201
207
  ```
202
208
 
209
+ ## Supported Chains
210
+
211
+ Epistery supports multiple blockchain networks. Configure your domain's provider to use any of these chains:
212
+
213
+ ### Ethereum Mainnet
214
+ ```ini
215
+ [provider]
216
+ chainId=1
217
+ name=Ethereum Mainnet
218
+ rpc=https://eth.llamarpc.com
219
+ nativeCurrencyName=Ether
220
+ nativeCurrencySymbol=ETH
221
+ nativeCurrencyDecimals=18
222
+ ```
223
+
224
+ ### Polygon Mainnet (POL)
225
+ ```ini
226
+ [provider]
227
+ chainId=137
228
+ name=Polygon Mainnet
229
+ rpc=https://polygon-rpc.com
230
+ nativeCurrencyName=POL
231
+ nativeCurrencySymbol=POL
232
+ nativeCurrencyDecimals=18
233
+ ```
234
+
235
+ ### Japan Open Chain (JOC)
236
+ ```ini
237
+ [provider]
238
+ chainId=81
239
+ name=Japan Open Chain
240
+ rpc=https://rpc-2.japanopenchain.org:8545
241
+ nativeCurrencyName=Japan Open Chain Token
242
+ nativeCurrencySymbol=JOC
243
+ nativeCurrencyDecimals=18
244
+ ```
245
+
246
+ To configure a specific chain for a domain, edit `~/.epistery/{domain}/config.ini` and update the `[provider]` section with the desired chain configuration.
247
+
203
248
  ## Security
204
249
 
205
250
  - Domain configs stored with 0600 permissions (user only)
@@ -0,0 +1,396 @@
1
+ # Epistery Registry
2
+
3
+ ## Overview
4
+
5
+ The Epistery Registry is a proposed centralized naming system for Epistery identities, analogous to DNS for domain names. It provides a canonical registry for human-readable identity names (e.g., "alice.epistery" or "bob.example.com") and maps them to their corresponding on-chain IdentityContract addresses.
6
+
7
+ ## Problem Statement
8
+
9
+ Identity contracts need unique, human-readable names within their domain namespaces. While blockchain contracts can verify name uniqueness through on-chain registries, this approach faces several challenges:
10
+
11
+ 1. **Gas Costs** - On-chain name lookups and registration are expensive, especially at scale
12
+ 2. **Performance** - Querying availability requires blockchain RPC calls with latency
13
+ 3. **User Experience** - Users expect instant feedback when checking name availability
14
+ 4. **Scalability** - Large-scale name enumeration on-chain is prohibitively expensive
15
+
16
+ ## Solution: Hybrid Registry Architecture
17
+
18
+ The Epistery Registry uses a **hybrid approach** combining centralized performance with decentralized verification:
19
+
20
+ - **Off-chain registry** provides fast lookups and availability checks
21
+ - **On-chain proof** ensures ownership and prevents disputes
22
+ - **Event-driven sync** keeps registry in sync with blockchain state
23
+
24
+ ## Architecture
25
+
26
+ ### Components
27
+
28
+ ```
29
+ ┌─────────────────────────────────────────────────────────────┐
30
+ │ Epistery Registry Server │
31
+ │ │
32
+ │ ┌──────────────┐ ┌──────────────┐ ┌──────────────────┐ │
33
+ │ │ Registry │ │ Indexer │ │ HTTP API │ │
34
+ │ │ Database │ │ Service │ │ Server │ │
35
+ │ └──────────────┘ └──────────────┘ │ │ │
36
+ │ │ │ │ /check │ │
37
+ │ │ │ │ /register │ │
38
+ │ └──────────────────┼─────────→│ /resolve │ │
39
+ │ │ │ /list │ │
40
+ │ ↓ └──────────────────┘ │
41
+ │ ┌──────────────┐ ↑ │
42
+ │ │ Event │ │ │
43
+ │ │ Listener │ │ │
44
+ │ └──────────────┘ │ │
45
+ └────────────────────────────┬───────────────────┼─────────────┘
46
+ │ │
47
+ ↓ ↓
48
+ ┌─────────────────┐ ┌──────────────┐
49
+ │ Blockchain │ │ Clients │
50
+ │ (Polygon) │ │ │
51
+ │ │ │ - Web Apps │
52
+ │ Agent Contract │ │ - CLI Tools │
53
+ │ Identity │ │ - Wallets │
54
+ │ Contracts │ │ │
55
+ └─────────────────┘ └──────────────┘
56
+ ```
57
+
58
+ ### Data Model
59
+
60
+ #### Registry Database Schema
61
+
62
+ ```sql
63
+ -- Names table
64
+ CREATE TABLE names (
65
+ id SERIAL PRIMARY KEY,
66
+ name VARCHAR(255) NOT NULL,
67
+ domain VARCHAR(255) NOT NULL,
68
+ full_name VARCHAR(512) GENERATED ALWAYS AS (name || '.' || domain) STORED,
69
+ identity_contract_address VARCHAR(42) NOT NULL,
70
+ owner_address VARCHAR(42) NOT NULL,
71
+ registered_at TIMESTAMP NOT NULL,
72
+ tx_hash VARCHAR(66) NOT NULL,
73
+ block_number BIGINT NOT NULL,
74
+ UNIQUE(name, domain)
75
+ );
76
+
77
+ -- Create indexes for fast lookups
78
+ CREATE INDEX idx_full_name ON names(full_name);
79
+ CREATE INDEX idx_identity_contract ON names(identity_contract_address);
80
+ CREATE INDEX idx_owner ON names(owner_address);
81
+ CREATE INDEX idx_domain ON names(domain);
82
+ ```
83
+
84
+ #### Domain Hierarchy
85
+
86
+ Names follow a hierarchical structure:
87
+ - **TLD (epistery)**: `alice.epistery` - Global Epistery namespace
88
+ - **Domain-based**: `bob.example.com` - Attached to specific domains
89
+ - **Subdomains**: Reserved for future expansion
90
+
91
+ ### Event Indexing
92
+
93
+ The registry stays synchronized with blockchain state by listening to contract events:
94
+
95
+ ```javascript
96
+ // Listen to IdentityCreated events
97
+ agentContract.on('IdentityCreated', async (owner, firstRivet, name, domain, timestamp, event) => {
98
+ if (name && name.length > 0) {
99
+ await registry.registerName({
100
+ name: name,
101
+ domain: domain,
102
+ identityContract: event.address,
103
+ owner: owner,
104
+ txHash: event.transactionHash,
105
+ blockNumber: event.blockNumber,
106
+ timestamp: timestamp
107
+ });
108
+ }
109
+ });
110
+
111
+ // Listen to IdentityNameUpdated events
112
+ identityContract.on('IdentityNameUpdated', async (oldName, newName, timestamp, event) => {
113
+ await registry.updateName({
114
+ identityContract: event.address,
115
+ oldName: oldName,
116
+ newName: newName,
117
+ txHash: event.transactionHash,
118
+ blockNumber: event.blockNumber
119
+ });
120
+ });
121
+ ```
122
+
123
+ ## API Endpoints
124
+
125
+ ### `GET /api/registry/check`
126
+ Check if a name is available in a domain.
127
+
128
+ **Query Parameters:**
129
+ - `name` - The identity name (required)
130
+ - `domain` - The domain (defaults to "epistery")
131
+
132
+ **Response:**
133
+ ```json
134
+ {
135
+ "available": true,
136
+ "name": "alice",
137
+ "domain": "epistery",
138
+ "fullName": "alice.epistery"
139
+ }
140
+ ```
141
+
142
+ ### `GET /api/registry/resolve`
143
+ Resolve a full name to an IdentityContract address.
144
+
145
+ **Query Parameters:**
146
+ - `name` - Full qualified name (e.g., "alice.epistery")
147
+
148
+ **Response:**
149
+ ```json
150
+ {
151
+ "name": "alice.epistery",
152
+ "identityContract": "0x1234...",
153
+ "owner": "0x5678...",
154
+ "registeredAt": "2025-11-28T12:00:00Z",
155
+ "txHash": "0xabcd...",
156
+ "blockNumber": 12345678
157
+ }
158
+ ```
159
+
160
+ ### `POST /api/registry/register`
161
+ Pre-register a name intent (off-chain reservation).
162
+
163
+ **Request Body:**
164
+ ```json
165
+ {
166
+ "name": "alice",
167
+ "domain": "epistery",
168
+ "ownerAddress": "0x1234..."
169
+ }
170
+ ```
171
+
172
+ **Response:**
173
+ ```json
174
+ {
175
+ "success": true,
176
+ "reservation": {
177
+ "name": "alice.epistery",
178
+ "expiresAt": "2025-11-28T12:30:00Z",
179
+ "reservationId": "uuid-1234"
180
+ }
181
+ }
182
+ ```
183
+
184
+ **Note:** Reservation is temporary (30 min) and must be confirmed by on-chain deployment.
185
+
186
+ ### `GET /api/registry/list`
187
+ List all names in a domain.
188
+
189
+ **Query Parameters:**
190
+ - `domain` - Domain to list (required)
191
+ - `page` - Page number (default: 1)
192
+ - `limit` - Results per page (default: 50, max: 500)
193
+
194
+ **Response:**
195
+ ```json
196
+ {
197
+ "domain": "epistery",
198
+ "total": 1523,
199
+ "page": 1,
200
+ "limit": 50,
201
+ "names": [
202
+ {
203
+ "name": "alice.epistery",
204
+ "identityContract": "0x1234...",
205
+ "registeredAt": "2025-11-20T10:00:00Z"
206
+ },
207
+ // ... more entries
208
+ ]
209
+ }
210
+ ```
211
+
212
+ ## Registration Flow
213
+
214
+ ### 1. Client-Side Registration
215
+
216
+ ```javascript
217
+ // Check availability
218
+ const available = await fetch('/api/registry/check?name=alice&domain=epistery')
219
+ .then(r => r.json());
220
+
221
+ if (!available.available) {
222
+ throw new Error('Name already taken');
223
+ }
224
+
225
+ // Reserve name (optional, provides race condition protection)
226
+ const reservation = await fetch('/api/registry/register', {
227
+ method: 'POST',
228
+ body: JSON.stringify({
229
+ name: 'alice',
230
+ domain: 'epistery',
231
+ ownerAddress: rivetAddress
232
+ })
233
+ }).then(r => r.json());
234
+
235
+ // Deploy IdentityContract with name
236
+ const tx = await factory.deploy('alice', 'epistery');
237
+ await tx.wait();
238
+
239
+ // Registry automatically picks up IdentityCreated event
240
+ // Name is now confirmed and reservation is removed
241
+ ```
242
+
243
+ ### 2. Event-Driven Confirmation
244
+
245
+ ```javascript
246
+ // Registry event listener picks up deployment
247
+ agentContract.on('IdentityCreated', async (owner, rivet, name, domain) => {
248
+ // Find and confirm reservation
249
+ const reservation = await findReservation(name, domain);
250
+ if (reservation) {
251
+ await confirmReservation(reservation.id);
252
+ }
253
+
254
+ // Or create new entry if no reservation exists
255
+ await createNameEntry({
256
+ name: name,
257
+ domain: domain,
258
+ identityContract: tx.contractAddress,
259
+ owner: owner
260
+ });
261
+ });
262
+ ```
263
+
264
+ ## Security Considerations
265
+
266
+ ### Name Squatting Prevention
267
+
268
+ 1. **Reservation System** - Temporary reservations (30 min) prevent front-running
269
+ 2. **On-Chain Proof** - Only on-chain deployments are authoritative
270
+ 3. **Event Verification** - All registrations verified against blockchain events
271
+ 4. **Dispute Resolution** - Blockchain state is always the source of truth
272
+
273
+ ### Race Conditions
274
+
275
+ **Scenario:** Two users try to register the same name simultaneously.
276
+
277
+ **Mitigation:**
278
+ 1. Client checks availability via API (fast feedback)
279
+ 2. Client creates reservation (locks name for 30 min)
280
+ 3. Client deploys contract with name
281
+ 4. First successful on-chain deployment wins
282
+ 5. Second deployment fails (name already taken on-chain)
283
+ 6. Failed reservation expires automatically
284
+
285
+ ### Sync Reliability
286
+
287
+ **Problem:** Registry could get out of sync with blockchain.
288
+
289
+ **Solutions:**
290
+ 1. **Event replay** - Periodic full re-sync from blockchain events
291
+ 2. **Block confirmations** - Wait for N confirmations before considering final
292
+ 3. **Health checks** - Monitor indexer lag and alert if behind
293
+ 4. **Manual override** - Admin tools to fix inconsistencies
294
+
295
+ ## Deployment Architecture
296
+
297
+ ### Production Setup
298
+
299
+ ```yaml
300
+ # docker-compose.yml
301
+ services:
302
+ registry-db:
303
+ image: postgres:15
304
+ volumes:
305
+ - registry-data:/var/lib/postgresql/data
306
+ environment:
307
+ POSTGRES_DB: epistery_registry
308
+
309
+ registry-api:
310
+ image: epistery/registry:latest
311
+ depends_on:
312
+ - registry-db
313
+ environment:
314
+ DATABASE_URL: postgres://registry-db/epistery_registry
315
+ BLOCKCHAIN_RPC: https://polygon-rpc.com
316
+ AGENT_CONTRACT_ADDRESS: 0x...
317
+
318
+ registry-indexer:
319
+ image: epistery/indexer:latest
320
+ depends_on:
321
+ - registry-db
322
+ environment:
323
+ DATABASE_URL: postgres://registry-db/epistery_registry
324
+ BLOCKCHAIN_RPC: https://polygon-rpc.com
325
+ START_BLOCK: 45000000 # Deploy block
326
+ ```
327
+
328
+ ### High Availability
329
+
330
+ - **Multi-region deployment** - Reduce latency worldwide
331
+ - **Read replicas** - Scale read operations
332
+ - **CDN caching** - Cache frequently accessed names
333
+ - **Fallback to RPC** - Direct blockchain queries if registry unavailable
334
+
335
+ ## Governance
336
+
337
+ ### Name Policy
338
+
339
+ 1. **Length** - Minimum 3 characters, maximum 32 characters
340
+ 2. **Characters** - Alphanumeric and hyphens only (a-z, 0-9, -)
341
+ 3. **Reserved names** - System reserves: admin, root, system, etc.
342
+ 4. **Profanity filter** - Optional content moderation
343
+
344
+ ### Domain Management
345
+
346
+ Each domain can set its own policies:
347
+ - **Public registration** - Anyone can register (e.g., "epistery")
348
+ - **Whitelist only** - Must be on domain whitelist
349
+ - **Invite only** - Requires invitation code
350
+ - **Custom validation** - Domain-specific name rules
351
+
352
+ ## Future Enhancements
353
+
354
+ ### Decentralization Path
355
+
356
+ While starting centralized for performance, the registry can evolve:
357
+
358
+ 1. **Federated registries** - Multiple registry operators
359
+ 2. **Blockchain checkpoints** - Periodic Merkle root commits on-chain
360
+ 3. **IPFS backup** - Distribute registry snapshots via IPFS
361
+ 4. **DAO governance** - Community control over policies
362
+ 5. **ENS integration** - Bridge to Ethereum Name Service
363
+
364
+ ### Advanced Features
365
+
366
+ - **Name transfers** - Transfer name to new IdentityContract
367
+ - **Aliases** - Multiple names pointing to same identity
368
+ - **Reverse lookup** - Contract address → names
369
+ - **Search** - Full-text search across names and metadata
370
+ - **Analytics** - Registration trends, popular names
371
+ - **Notifications** - Alert when watched names become available
372
+
373
+ ## Implementation Priority
374
+
375
+ **Phase 1: MVP** (Immediate)
376
+ - Basic PostgreSQL database
377
+ - Event indexer for IdentityCreated
378
+ - Simple HTTP API (check, resolve, list)
379
+
380
+ **Phase 2: Production** (Next)
381
+ - Reservation system
382
+ - Multi-domain support
383
+ - Monitoring and alerts
384
+ - Performance optimization
385
+
386
+ **Phase 3: Scale** (Future)
387
+ - High availability setup
388
+ - CDN integration
389
+ - Advanced search
390
+ - Federation support
391
+
392
+ ## Conclusion
393
+
394
+ The Epistery Registry provides a pragmatic solution to identity naming by combining the speed and convenience of centralized systems with the security and verifiability of blockchain. This hybrid approach delivers the best user experience while maintaining the trust properties of decentralized infrastructure.
395
+
396
+ The registry serves as a **discovery layer** rather than an authority—the blockchain remains the ultimate source of truth, and all registry data can be independently verified by querying contract events directly.