@tanakayuto/intmax402-express 0.3.3 → 0.3.4

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 CHANGED
@@ -1,23 +1,149 @@
1
1
  # @tanakayuto/intmax402-express
2
2
 
3
- Part of [intmax402](https://github.com/zaq2989/intmax402) — HTTP 402, reimagined for AI agents.
3
+ Express middleware for [intmax402](https://github.com/zaq2989/intmax402) — wallet-based authentication and INTMAX L2 micropayments for Express apps.
4
4
 
5
- See [main README](https://github.com/zaq2989/intmax402) for full documentation.
5
+ ## Install
6
6
 
7
- ## Network
7
+ ```bash
8
+ npm install @tanakayuto/intmax402-express
9
+ ```
10
+
11
+ ## Usage
12
+
13
+ ### Identity Mode
8
14
 
9
- intmax402 operates on **Ethereum mainnet** by default (via INTMAX ZK L2 on Scroll). Use `environment: "testnet"` for development against Sepolia.
15
+ Require wallet ownership proof no payment, no blockchain node needed.
10
16
 
11
17
  ```typescript
12
- // Payment verification — mainnet (default)
13
- await initPaymentVerifier({
14
- eth_private_key: process.env.ETH_PRIVATE_KEY as `0x${string}`,
18
+ import express from 'express'
19
+ import { intmax402 } from '@tanakayuto/intmax402-express'
20
+
21
+ const app = express()
22
+
23
+ app.use('/protected', intmax402({
24
+ mode: 'identity',
25
+ secret: process.env.INTMAX402_SECRET!,
26
+ }))
27
+
28
+ app.get('/protected', (req, res) => {
29
+ res.json({ message: 'Access granted', address: req.intmax402?.address })
30
+ })
31
+
32
+ app.listen(3000)
33
+ ```
34
+
35
+ ### Payment Mode
36
+
37
+ Require an INTMAX L2 transfer before granting access.
38
+
39
+ ```typescript
40
+ import express from 'express'
41
+ import { intmax402 } from '@tanakayuto/intmax402-express'
42
+
43
+ const app = express()
44
+
45
+ app.use('/api/premium', intmax402({
46
+ mode: 'payment',
47
+ secret: process.env.INTMAX402_SECRET!,
48
+ serverAddress: process.env.INTMAX_ADDRESS!,
49
+ amount: '1000000000000000', // 0.001 ETH in wei
15
50
  environment: 'mainnet',
51
+ ethPrivateKey: process.env.ETH_PRIVATE_KEY!,
52
+ }))
53
+
54
+ app.get('/api/premium', (req, res) => {
55
+ res.json({
56
+ message: 'Payment verified!',
57
+ paidBy: req.intmax402?.address,
58
+ txHash: req.intmax402?.txHash,
59
+ })
16
60
  })
17
61
 
18
- // Payment verification — testnet (development)
62
+ app.listen(3000)
63
+ ```
64
+
65
+ ## API Reference
66
+
67
+ ### `intmax402(config)`
68
+
69
+ Returns an Express `RequestHandler` middleware.
70
+
71
+ On success, populates `req.intmax402`:
72
+
73
+ ```typescript
74
+ req.intmax402 = {
75
+ address: string, // verified Ethereum address
76
+ verified: boolean, // always true
77
+ txHash?: string, // payment mode only — INTMAX transfer digest
78
+ }
79
+ ```
80
+
81
+ #### Config Options
82
+
83
+ | Option | Type | Required | Description |
84
+ |---|---|---|---|
85
+ | `mode` | `'identity' \| 'payment'` | ✅ | Authentication mode |
86
+ | `secret` | `string` | ✅ | HMAC secret for nonce generation (keep private) |
87
+ | `serverAddress` | `string` | payment | Your INTMAX L2 address to receive payments |
88
+ | `amount` | `string` | payment | Required payment in token smallest unit (wei for ETH) |
89
+ | `ethPrivateKey` | `string` | payment† | Ethereum private key — auto-initializes the INTMAX payment verifier (v0.3.1+) |
90
+ | `environment` | `'mainnet' \| 'testnet'` | — | Network environment. Default: `'mainnet'` |
91
+ | `l1RpcUrl` | `string` | — | Custom L1 RPC URL override |
92
+ | `allowList` | `string[]` | — | Identity mode: restrict to specific addresses |
93
+ | `bindIp` | `boolean` | — | Bind nonce to client IP. Default `false` (recommended for AI agents) |
94
+ | `tokenAddress` | `string` | — | ERC-20 token for payment. Default: native ETH |
95
+
96
+ †`ethPrivateKey` auto-initializes the payment verifier on first use. If not provided, call `initPaymentVerifier()` manually before handling requests.
97
+
98
+ #### HTTP Responses
99
+
100
+ | Scenario | Status | Description |
101
+ |---|---|---|
102
+ | No `Authorization` header | `401` (identity) / `402` (payment) | Returns `WWW-Authenticate` header with nonce |
103
+ | Invalid signature | `401` | Signature verification failed |
104
+ | Address not in `allowList` | `403` | Access denied by allowlist |
105
+ | Payment not verified | `402` | Transfer not found or amount/recipient mismatch |
106
+ | INTMAX network down | `503` | Payment verifier temporarily unavailable |
107
+ | Auth verified | calls `next()` | `req.intmax402` is populated |
108
+
109
+ ### Additional Exports
110
+
111
+ ```typescript
112
+ import {
113
+ intmax402,
114
+ verifySignature,
115
+ initPaymentVerifier,
116
+ verifyPayment,
117
+ getPaymentVerifierAddress,
118
+ } from '@tanakayuto/intmax402-express'
119
+ ```
120
+
121
+ #### `initPaymentVerifier(config)`
122
+
123
+ Manually initialize the INTMAX payment verifier (call once at server startup).
124
+
125
+ ```typescript
126
+ import { initPaymentVerifier } from '@tanakayuto/intmax402-express'
127
+
19
128
  await initPaymentVerifier({
20
129
  eth_private_key: process.env.ETH_PRIVATE_KEY as `0x${string}`,
21
- environment: 'testnet',
130
+ environment: 'mainnet', // or 'testnet'
22
131
  })
23
132
  ```
133
+
134
+ #### `verifySignature(signature, nonce, address)`
135
+
136
+ Low-level utility to verify an Ethereum signature against a nonce.
137
+
138
+ Returns: `boolean`
139
+
140
+ ## Network
141
+
142
+ | Environment | Network | Notes |
143
+ |---|---|---|
144
+ | `mainnet` (default) | Ethereum mainnet + Scroll | Production use |
145
+ | `testnet` | Sepolia + Scroll Sepolia | Fund wallet at testnet.intmax.io |
146
+
147
+ ## License
148
+
149
+ MIT
@@ -56,7 +56,7 @@ async function initPaymentVerifier(config) {
56
56
  }
57
57
  function getPaymentVerifierAddress() {
58
58
  if (!client)
59
- throw new Error("Payment verifier not initialized. Call initPaymentVerifier() first.");
59
+ throw new intmax402_core_1.INTMAX402Error(intmax402_core_1.INTMAX402_ERROR_CODES.INTMAX_NETWORK_UNAVAILABLE, "Payment verifier not initialized. Call initPaymentVerifier() first.");
60
60
  return client.address;
61
61
  }
62
62
  async function verifyPayment(txHash, expectedAmount, serverAddress, tokenIndex) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tanakayuto/intmax402-express",
3
- "version": "0.3.3",
3
+ "version": "0.3.4",
4
4
  "main": "dist/index.js",
5
5
  "types": "dist/index.d.ts",
6
6
  "exports": {