@4mica/cli 0.2.0 → 0.3.0-alpha.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/package.json +1 -1
- package/snapshot.json +45 -8
- package/templates/agent-buyer-node/src/pay.ts +8 -2
- package/templates/agent-seller-express/src/comedian.ts +1 -9
- package/templates/buyer-express/src/buyer.ts +8 -2
- package/templates/buyer-hono/src/buyer.ts +8 -2
- package/templates/buyer-next/src/buyer.ts +8 -2
- package/templates/seller-express/src/server.ts +0 -9
- package/templates/seller-hono/src/server.ts +0 -9
- package/templates/seller-next/app/api/protected/route.ts +0 -1
- package/templates/seller-next/app/api/session/route.ts +0 -8
package/package.json
CHANGED
package/snapshot.json
CHANGED
|
@@ -4,14 +4,25 @@
|
|
|
4
4
|
"@biomejs/biome": "^2.4.16",
|
|
5
5
|
"@changesets/cli": "^2.29.7",
|
|
6
6
|
"@clack/prompts": "^1.7.0",
|
|
7
|
+
"@clerk/backend": "^2.33.6",
|
|
8
|
+
"@clerk/clerk-react": "^5.61.9",
|
|
9
|
+
"@clerk/nextjs": "^6.39.6",
|
|
7
10
|
"@coinbase/cdp-sdk": "^1.49.2",
|
|
11
|
+
"@fastify/cors": "^11.3.0",
|
|
12
|
+
"@fastify/rate-limit": "^11.2.0",
|
|
13
|
+
"@fastify/swagger": "^9.8.1",
|
|
14
|
+
"@fastify/swagger-ui": "^6.1.1",
|
|
8
15
|
"@noble/curves": "^2.2.0",
|
|
16
|
+
"@prisma/adapter-pg": "7.9.1",
|
|
17
|
+
"@prisma/client": "7.9.1",
|
|
9
18
|
"@quillai-network/wachai-validation-sdk": "^0.1.0",
|
|
10
19
|
"@radix-ui/react-scroll-area": "^1.2.10",
|
|
11
20
|
"@radix-ui/react-slot": "^1.2.4",
|
|
21
|
+
"@react-email/ui": "^6.9.2",
|
|
12
22
|
"@react-google-maps/api": "^2.20.8",
|
|
13
23
|
"@reown/appkit": "^1.8.20",
|
|
14
24
|
"@reown/appkit-adapter-wagmi": "^1.8.20",
|
|
25
|
+
"@shikijs/rehype": "^3.23.0",
|
|
15
26
|
"@tailwindcss/postcss": "^4.3.0",
|
|
16
27
|
"@tailwindcss/vite": "^4.3.0",
|
|
17
28
|
"@tanstack/react-query": "^5.100.14",
|
|
@@ -24,23 +35,32 @@
|
|
|
24
35
|
"@types/react": "^19.2.16",
|
|
25
36
|
"@types/react-dom": "^19.2.3",
|
|
26
37
|
"@types/yargs": "^17.0.35",
|
|
38
|
+
"@valibot/to-json-schema": "^1.7.1",
|
|
27
39
|
"@vitejs/plugin-react": "^6.0.3",
|
|
28
40
|
"@vitest/coverage-v8": "^4.1.8",
|
|
29
41
|
"@vitest/ui": "^4.1.8",
|
|
30
42
|
"@wagmi/connectors": "^8.0.15",
|
|
31
43
|
"@wagmi/core": "^3.5.0",
|
|
32
44
|
"@walletconnect/ethereum-provider": "2.23.4",
|
|
45
|
+
"@x402/core": "2.23.0",
|
|
46
|
+
"@x402/extensions": "2.23.0",
|
|
47
|
+
"@x402/fetch": "2.23.0",
|
|
33
48
|
"accounts": "^0.14.6",
|
|
34
49
|
"ahooks": "^3.9.7",
|
|
35
50
|
"autoprefixer": "^10.5.0",
|
|
51
|
+
"axios": "^1.19.0",
|
|
36
52
|
"changelogen": "^0.6.2",
|
|
37
53
|
"class-variance-authority": "^0.7.1",
|
|
38
54
|
"clsx": "^2.1.1",
|
|
39
55
|
"cross-env": "10.1.0",
|
|
56
|
+
"dotenv": "^17.4.2",
|
|
40
57
|
"esbuild": "^0.28.0",
|
|
41
58
|
"execa": "^9.6.1",
|
|
42
59
|
"express": "^5.1.0",
|
|
60
|
+
"fastify": "^5.10.0",
|
|
61
|
+
"fastify-plugin": "^5.1.0",
|
|
43
62
|
"find-up": "^8.0.0",
|
|
63
|
+
"gray-matter": "^4.0.3",
|
|
44
64
|
"framer-motion": "^12.40.0",
|
|
45
65
|
"hono": "^4.6.0",
|
|
46
66
|
"husky": "^9.1.7",
|
|
@@ -55,46 +75,63 @@
|
|
|
55
75
|
"ora": "^9.4.0",
|
|
56
76
|
"picocolors": "^1.1.1",
|
|
57
77
|
"postcss": "^8.5.15",
|
|
78
|
+
"prisma": "7.9.1",
|
|
58
79
|
"publint": "^0.3.14",
|
|
59
80
|
"react": "^19.2.7",
|
|
60
81
|
"react-dom": "^19.2.7",
|
|
82
|
+
"react-email": "^6.9.2",
|
|
61
83
|
"react-i18next": "^17.0.9",
|
|
84
|
+
"react-redux": "^9.3.0",
|
|
62
85
|
"react-router-dom": "^7.18.1",
|
|
86
|
+
"react-toastify": "^11.1.0",
|
|
87
|
+
"redux": "^5.0.1",
|
|
88
|
+
"redux-saga": "^1.5.1",
|
|
63
89
|
"read-pkg": "^10.1.0",
|
|
64
90
|
"recharts": "^3.8.1",
|
|
91
|
+
"remark-frontmatter": "^5.0.0",
|
|
92
|
+
"remark-gfm": "^4.0.1",
|
|
93
|
+
"resend": "^6.19.0",
|
|
65
94
|
"rimraf": "^6.1.3",
|
|
95
|
+
"server-only": "^0.0.1",
|
|
66
96
|
"shiki": "^3.0.0",
|
|
67
97
|
"tailwind-merge": "^3.6.0",
|
|
68
98
|
"tailwindcss": "^4.3.0",
|
|
69
99
|
"tailwindcss-animate": "^1.0.7",
|
|
70
100
|
"taze": "^19.14.1",
|
|
71
101
|
"terminal-link": "^5.0.0",
|
|
102
|
+
"ts-node": "^10.9.2",
|
|
72
103
|
"tsup": "^8.5.1",
|
|
73
104
|
"tsx": "^4.22.4",
|
|
74
105
|
"turbo": "latest",
|
|
75
106
|
"typescript": "^5.9.0",
|
|
107
|
+
"valibot": "^1.4.2",
|
|
76
108
|
"viem": "2.x",
|
|
77
109
|
"vite": "^8.1.4",
|
|
78
110
|
"vitest": "^4.1.8",
|
|
79
111
|
"wagmi": "^3.6.16",
|
|
112
|
+
"winston": "^3.19.0",
|
|
113
|
+
"winston-daily-rotate-file": "^5.0.0",
|
|
80
114
|
"yargs": "^18.0.0"
|
|
81
115
|
},
|
|
82
116
|
"catalogs": {
|
|
83
117
|
"node24": {
|
|
84
118
|
"@types/node": "^24.10.1"
|
|
85
119
|
},
|
|
120
|
+
"node26": {
|
|
121
|
+
"@types/node": "^26.1.1"
|
|
122
|
+
},
|
|
86
123
|
"typescript-latest": {
|
|
87
124
|
"typescript": "^5.9.0"
|
|
88
125
|
}
|
|
89
126
|
},
|
|
90
127
|
"fourMica": {
|
|
91
|
-
"@4mica/cli": "0.
|
|
92
|
-
"@4mica/sdk": "
|
|
93
|
-
"@4mica/sdk-bun": "
|
|
94
|
-
"@4mica/sdk-deno": "
|
|
95
|
-
"@4mica/sdk-express": "
|
|
96
|
-
"@4mica/sdk-hono": "
|
|
97
|
-
"@4mica/sdk-next": "
|
|
98
|
-
"@4mica/sdk-node": "
|
|
128
|
+
"@4mica/cli": "0.3.0-alpha.0",
|
|
129
|
+
"@4mica/sdk": "2.0.0-alpha.0",
|
|
130
|
+
"@4mica/sdk-bun": "2.0.0-alpha.0",
|
|
131
|
+
"@4mica/sdk-deno": "2.0.0-alpha.0",
|
|
132
|
+
"@4mica/sdk-express": "2.0.0-alpha.0",
|
|
133
|
+
"@4mica/sdk-hono": "2.0.0-alpha.0",
|
|
134
|
+
"@4mica/sdk-next": "2.0.0-alpha.0",
|
|
135
|
+
"@4mica/sdk-node": "2.0.0-alpha.0"
|
|
99
136
|
}
|
|
100
137
|
}
|
|
@@ -4,12 +4,18 @@ type Requirement = {
|
|
|
4
4
|
asset: string;
|
|
5
5
|
amount: string;
|
|
6
6
|
payTo: string;
|
|
7
|
-
extra?:
|
|
7
|
+
extra?: Record<string, unknown>;
|
|
8
8
|
};
|
|
9
9
|
|
|
10
10
|
type Required402 = { x402Version: number; accepts: Requirement[] };
|
|
11
11
|
|
|
12
12
|
function demoPaymentHeader(req: Requirement): string {
|
|
13
|
+
// Mint a random 32-byte req_id — uniqueness is all core asks of it.
|
|
14
|
+
const reqIdBytes = new Uint8Array(32);
|
|
15
|
+
crypto.getRandomValues(reqIdBytes);
|
|
16
|
+
const reqId = `0x${Array.from(reqIdBytes, (b) =>
|
|
17
|
+
b.toString(16).padStart(2, "0"),
|
|
18
|
+
).join("")}`;
|
|
13
19
|
const envelope = {
|
|
14
20
|
x402Version: 1,
|
|
15
21
|
scheme: req.scheme,
|
|
@@ -19,7 +25,7 @@ function demoPaymentHeader(req: Requirement): string {
|
|
|
19
25
|
version: "v1",
|
|
20
26
|
user_address: "0x2222222222222222222222222222222222222222",
|
|
21
27
|
recipient_address: req.payTo,
|
|
22
|
-
req_id:
|
|
28
|
+
req_id: reqId,
|
|
23
29
|
amount: `0x${BigInt(req.amount).toString(16)}`,
|
|
24
30
|
asset_address: req.asset,
|
|
25
31
|
timestamp: Math.floor(Date.now() / 1000),
|
|
@@ -23,7 +23,7 @@ const verifier: PaywallVerifier = {
|
|
|
23
23
|
},
|
|
24
24
|
};
|
|
25
25
|
|
|
26
|
-
const CONFIG_BASE: Omit<PaywallConfig, "amount"
|
|
26
|
+
const CONFIG_BASE: Omit<PaywallConfig, "amount"> = {
|
|
27
27
|
payTo: "0x1111111111111111111111111111111111111111",
|
|
28
28
|
asset: "0x0000000000000000000000000000000000000000",
|
|
29
29
|
network: "base-sepolia",
|
|
@@ -79,7 +79,6 @@ app.get("/punchline", async (req, res) => {
|
|
|
79
79
|
const config: PaywallConfig = {
|
|
80
80
|
...CONFIG_BASE,
|
|
81
81
|
amount: String(listing.price),
|
|
82
|
-
tabEndpoint: `${baseUrl}/session`,
|
|
83
82
|
};
|
|
84
83
|
const paywall = createPaywall(verifier, config);
|
|
85
84
|
const decision = await paywall.protect({
|
|
@@ -118,13 +117,6 @@ app.post("/rating", (req, res) => {
|
|
|
118
117
|
res.json({ ok: true });
|
|
119
118
|
});
|
|
120
119
|
|
|
121
|
-
app.post("/session", (_req, res) => {
|
|
122
|
-
res.json({
|
|
123
|
-
userAddress: "0x2222222222222222222222222222222222222222",
|
|
124
|
-
nextReqId: "0x1",
|
|
125
|
-
});
|
|
126
|
-
});
|
|
127
|
-
|
|
128
120
|
function listen(port: number, attemptsLeft = 20) {
|
|
129
121
|
const server = app.listen(port);
|
|
130
122
|
server.once("listening", () => {
|
|
@@ -26,13 +26,19 @@ type X402PaymentRequired = {
|
|
|
26
26
|
asset: string;
|
|
27
27
|
amount: string;
|
|
28
28
|
payTo: string;
|
|
29
|
-
extra?:
|
|
29
|
+
extra?: Record<string, unknown>;
|
|
30
30
|
}>;
|
|
31
31
|
};
|
|
32
32
|
|
|
33
33
|
function demoPaymentHeader(
|
|
34
34
|
requirement: X402PaymentRequired["accepts"][number],
|
|
35
35
|
) {
|
|
36
|
+
// Mint a random 32-byte req_id — uniqueness is all core asks of it.
|
|
37
|
+
const reqIdBytes = new Uint8Array(32);
|
|
38
|
+
crypto.getRandomValues(reqIdBytes);
|
|
39
|
+
const reqId = `0x${Array.from(reqIdBytes, (b) =>
|
|
40
|
+
b.toString(16).padStart(2, "0"),
|
|
41
|
+
).join("")}`;
|
|
36
42
|
const envelope = {
|
|
37
43
|
x402Version: 1,
|
|
38
44
|
scheme: requirement.scheme,
|
|
@@ -42,7 +48,7 @@ function demoPaymentHeader(
|
|
|
42
48
|
version: "v1",
|
|
43
49
|
user_address: "0x2222222222222222222222222222222222222222",
|
|
44
50
|
recipient_address: requirement.payTo,
|
|
45
|
-
req_id:
|
|
51
|
+
req_id: reqId,
|
|
46
52
|
amount: `0x${BigInt(requirement.amount).toString(16)}`,
|
|
47
53
|
asset_address: requirement.asset,
|
|
48
54
|
timestamp: Math.floor(Date.now() / 1000),
|
|
@@ -26,13 +26,19 @@ type X402PaymentRequired = {
|
|
|
26
26
|
asset: string;
|
|
27
27
|
amount: string;
|
|
28
28
|
payTo: string;
|
|
29
|
-
extra?:
|
|
29
|
+
extra?: Record<string, unknown>;
|
|
30
30
|
}>;
|
|
31
31
|
};
|
|
32
32
|
|
|
33
33
|
function demoPaymentHeader(
|
|
34
34
|
requirement: X402PaymentRequired["accepts"][number],
|
|
35
35
|
) {
|
|
36
|
+
// Mint a random 32-byte req_id — uniqueness is all core asks of it.
|
|
37
|
+
const reqIdBytes = new Uint8Array(32);
|
|
38
|
+
crypto.getRandomValues(reqIdBytes);
|
|
39
|
+
const reqId = `0x${Array.from(reqIdBytes, (b) =>
|
|
40
|
+
b.toString(16).padStart(2, "0"),
|
|
41
|
+
).join("")}`;
|
|
36
42
|
const envelope = {
|
|
37
43
|
x402Version: 1,
|
|
38
44
|
scheme: requirement.scheme,
|
|
@@ -42,7 +48,7 @@ function demoPaymentHeader(
|
|
|
42
48
|
version: "v1",
|
|
43
49
|
user_address: "0x2222222222222222222222222222222222222222",
|
|
44
50
|
recipient_address: requirement.payTo,
|
|
45
|
-
req_id:
|
|
51
|
+
req_id: reqId,
|
|
46
52
|
amount: `0x${BigInt(requirement.amount).toString(16)}`,
|
|
47
53
|
asset_address: requirement.asset,
|
|
48
54
|
timestamp: Math.floor(Date.now() / 1000),
|
|
@@ -26,13 +26,19 @@ type X402PaymentRequired = {
|
|
|
26
26
|
asset: string;
|
|
27
27
|
amount: string;
|
|
28
28
|
payTo: string;
|
|
29
|
-
extra?:
|
|
29
|
+
extra?: Record<string, unknown>;
|
|
30
30
|
}>;
|
|
31
31
|
};
|
|
32
32
|
|
|
33
33
|
function demoPaymentHeader(
|
|
34
34
|
requirement: X402PaymentRequired["accepts"][number],
|
|
35
35
|
) {
|
|
36
|
+
// Mint a random 32-byte req_id — uniqueness is all core asks of it.
|
|
37
|
+
const reqIdBytes = new Uint8Array(32);
|
|
38
|
+
crypto.getRandomValues(reqIdBytes);
|
|
39
|
+
const reqId = `0x${Array.from(reqIdBytes, (b) =>
|
|
40
|
+
b.toString(16).padStart(2, "0"),
|
|
41
|
+
).join("")}`;
|
|
36
42
|
const envelope = {
|
|
37
43
|
x402Version: 1,
|
|
38
44
|
scheme: requirement.scheme,
|
|
@@ -42,7 +48,7 @@ function demoPaymentHeader(
|
|
|
42
48
|
version: "v1",
|
|
43
49
|
user_address: "0x2222222222222222222222222222222222222222",
|
|
44
50
|
recipient_address: requirement.payTo,
|
|
45
|
-
req_id:
|
|
51
|
+
req_id: reqId,
|
|
46
52
|
amount: `0x${BigInt(requirement.amount).toString(16)}`,
|
|
47
53
|
asset_address: requirement.asset,
|
|
48
54
|
timestamp: Math.floor(Date.now() / 1000),
|
|
@@ -19,20 +19,12 @@ export const PAYWALL_CONFIG: PaywallConfig = {
|
|
|
19
19
|
asset: "0x0000000000000000000000000000000000000000",
|
|
20
20
|
network: "base-sepolia",
|
|
21
21
|
amount: "1000",
|
|
22
|
-
tabEndpoint: "http://localhost:__PORT__/session",
|
|
23
22
|
description: "Premium market data feed",
|
|
24
23
|
};
|
|
25
24
|
|
|
26
25
|
const app = express();
|
|
27
26
|
app.use(express.json());
|
|
28
27
|
|
|
29
|
-
app.post("/session", (_req, res) => {
|
|
30
|
-
res.json({
|
|
31
|
-
userAddress: "0x2222222222222222222222222222222222222222",
|
|
32
|
-
nextReqId: "0x1",
|
|
33
|
-
});
|
|
34
|
-
});
|
|
35
|
-
|
|
36
28
|
app.get("/premium", paywall(verifier, PAYWALL_CONFIG), (_req, res) => {
|
|
37
29
|
res.json({ ok: true, data: "🔓 premium market data unlocked" });
|
|
38
30
|
});
|
|
@@ -41,7 +33,6 @@ function listen(port: number, attemptsLeft = 20) {
|
|
|
41
33
|
const server = app.listen(port);
|
|
42
34
|
server.once("listening", () => {
|
|
43
35
|
const url = `http://localhost:${port}`;
|
|
44
|
-
PAYWALL_CONFIG.tabEndpoint = `${url}/session`;
|
|
45
36
|
writeFileSync(PORT_FILE, url);
|
|
46
37
|
console.log(`[seller-express] listening on ${url}`);
|
|
47
38
|
console.log(` GET /premium is paywalled — run the buyer to pay for it.`);
|
|
@@ -20,19 +20,11 @@ export const PAYWALL_CONFIG: PaywallConfig = {
|
|
|
20
20
|
asset: "0x0000000000000000000000000000000000000000",
|
|
21
21
|
network: "base-sepolia",
|
|
22
22
|
amount: "1000",
|
|
23
|
-
tabEndpoint: "http://localhost:__PORT__/session",
|
|
24
23
|
description: "Premium market data feed",
|
|
25
24
|
};
|
|
26
25
|
|
|
27
26
|
const app = new Hono();
|
|
28
27
|
|
|
29
|
-
app.post("/session", (c) =>
|
|
30
|
-
c.json({
|
|
31
|
-
userAddress: "0x2222222222222222222222222222222222222222",
|
|
32
|
-
nextReqId: "0x1",
|
|
33
|
-
}),
|
|
34
|
-
);
|
|
35
|
-
|
|
36
28
|
app.use("/premium", paywall(verifier, PAYWALL_CONFIG));
|
|
37
29
|
app.get("/premium", (c) => {
|
|
38
30
|
const guarantee = c.get("paymentGuarantee");
|
|
@@ -46,7 +38,6 @@ app.get("/premium", (c) => {
|
|
|
46
38
|
function listen(port: number, attemptsLeft = 20) {
|
|
47
39
|
const server = serve({ fetch: app.fetch, port }, (info) => {
|
|
48
40
|
const url = `http://localhost:${info.port}`;
|
|
49
|
-
PAYWALL_CONFIG.tabEndpoint = `${url}/session`;
|
|
50
41
|
writeFileSync(PORT_FILE, url);
|
|
51
42
|
console.log(`[seller-hono] listening on ${url}`);
|
|
52
43
|
console.log(` GET /premium is paywalled — run the buyer to pay for it.`);
|
|
@@ -15,7 +15,6 @@ const PAYWALL_CONFIG: PaywallConfig = {
|
|
|
15
15
|
asset: "0x0000000000000000000000000000000000000000",
|
|
16
16
|
network: "base-sepolia",
|
|
17
17
|
amount: "1000",
|
|
18
|
-
tabEndpoint: `${process.env.EXAMPLE_BASE_URL ?? "http://localhost:__PORT__"}/api/session`,
|
|
19
18
|
description: "Premium market data feed",
|
|
20
19
|
};
|
|
21
20
|
|