@ambasada/skills 0.3.0 → 0.4.1
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
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ambasada/skills",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.1",
|
|
4
4
|
"description": "Skills for Claude Code, Cursor and Codex: ambasada-product (build a product that sells in the Hack A Ton Village) and ambasada-payments (TON Checkout, receipts, webhooks).",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"files": [
|
|
@@ -68,6 +68,25 @@ const { keys, used_bytes } = await village.store.list("cart:");
|
|
|
68
68
|
HTTP: `GET|PUT|DELETE /v1/store/:key` (PUT body = the JSON value), `GET /v1/store?prefix=`;
|
|
69
69
|
`POST /v1/product/deploy` (what `ambasada deploy` calls), `GET /v1/product`, `DELETE /v1/product`.
|
|
70
70
|
|
|
71
|
+
## Sign in with Ambasada
|
|
72
|
+
|
|
73
|
+
People sign in to your hosted product with their Ambasada ID. There is nothing to set up: `ambasada deploy`
|
|
74
|
+
injects `AMBASADA_AUTH_CLIENT_ID`, `AMBASADA_AUTH_CLIENT_SECRET` and `AMBASADA_AUTH_ISSUER`, and `ambasada dev`
|
|
75
|
+
injects fake ones (the mock signs you in as "Fake Visitor"). The templates already have the routes and a
|
|
76
|
+
header button.
|
|
77
|
+
|
|
78
|
+
```ts
|
|
79
|
+
// GET /api/auth/login?returnTo=/ GET /api/auth/callback GET /api/auth/logout
|
|
80
|
+
return village.auth.login(req, { returnTo: "/", email: false }); // email: true asks for it on the consent screen
|
|
81
|
+
return village.auth.callback(req); // sets an HttpOnly session cookie
|
|
82
|
+
return village.auth.logout(req);
|
|
83
|
+
const user = await village.auth.user(req); // null, or { id, name, avatar_url, builder, builder_since, member_since, pass, email? }
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
`user.id` (`user_…`) is stable: key your data by it (``village.store.set(`user:${user.id}`, …)``).
|
|
87
|
+
`pass` is `"builder" | "visitor" | "staff" | null` for the current event. Server code only; the browser asks
|
|
88
|
+
`/api/auth/me`. It works on `https://<slug>.ambasada.dev` and under `ambasada dev`, not with `--own` hosting.
|
|
89
|
+
|
|
71
90
|
## Errors
|
|
72
91
|
|
|
73
92
|
`{ "error": { "code", "message", call_id?, charged?: false, refunded?, approval_id? } }`. The SDK throws
|
|
@@ -14,6 +14,8 @@ my-shop/
|
|
|
14
14
|
app/api/webhook/route.ts checkout.paid arrives here, signed: deliver here
|
|
15
15
|
app/api/receipt/route.ts verifies a pay.js receipt from the browser
|
|
16
16
|
app/api/translate/route.ts the paid offering: agents call it with a receipt
|
|
17
|
+
app/api/auth/*/route.ts Sign in with Ambasada: login, callback, logout, me
|
|
18
|
+
app/account.tsx the header: "Sign in with Ambasada", or the person's name and avatar
|
|
17
19
|
lib/ambasada.ts the Village client for server code (reads the Worker env)
|
|
18
20
|
offerings.ts what agents can buy: name, price, endpoint, input and output
|
|
19
21
|
agent/agent.md your agent's instructions, in plain English
|
|
@@ -48,6 +50,23 @@ where `env` comes from `getCloudflareContext()` (deployed); under `next dev` the
|
|
|
48
50
|
It reads `AMBASADA_API_KEY`, `AMBASADA_API_URL`, `AMBASADA_COMPANY`, `AMBASADA_WEBHOOK_SECRET`.
|
|
49
51
|
Everything the client can do is in the ambasada-payments skill.
|
|
50
52
|
|
|
53
|
+
## Who is signed in
|
|
54
|
+
|
|
55
|
+
Every hosted product gets **Sign in with Ambasada** (Ambasada ID) for free: no keys, no settings.
|
|
56
|
+
The template's header already has the button. In server code:
|
|
57
|
+
|
|
58
|
+
```ts
|
|
59
|
+
import { currentUser } from "../lib/ambasada.ts";
|
|
60
|
+
|
|
61
|
+
const user = await currentUser(); // null, or { id, name, avatar_url, builder, pass, member_since, … }
|
|
62
|
+
if (!user) redirect("/api/auth/login?returnTo=/orders");
|
|
63
|
+
await ambasada().store.set(`orders:${user.id}`, orders); // key per-person data by user.id
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
In a route handler, `ambasada().auth.user(req)` does the same. Client components fetch `/api/auth/me`.
|
|
67
|
+
Ask for the email only if you need it: `/api/auth/login` calls `auth.login(req, { email: true })`.
|
|
68
|
+
Don't build your own login or accounts table, and don't add Clerk, Auth.js or Supabase Auth.
|
|
69
|
+
|
|
51
70
|
## Next.js: allowed and banned
|
|
52
71
|
|
|
53
72
|
Allowed, and enough for any product here:
|
|
@@ -93,7 +112,8 @@ File URLs are public: don't put private data in them.
|
|
|
93
112
|
|
|
94
113
|
- Local: `.env` in the project (Cloudflare's `.dev.vars` works too). The template writes it with test
|
|
95
114
|
values for `ambasada dev`. Both are in `.gitignore`; keep them there.
|
|
96
|
-
- Deployed: `ambasada deploy` injects `AMBASADA_API_KEY`, `AMBASADA_API_URL
|
|
115
|
+
- Deployed: `ambasada deploy` injects `AMBASADA_API_KEY`, `AMBASADA_API_URL`, `AMBASADA_COMPANY` and the
|
|
116
|
+
Sign in with Ambasada credentials (`AMBASADA_AUTH_*`) for you.
|
|
97
117
|
With `--own`, set them yourself: `npx wrangler secret put AMBASADA_API_KEY`.
|
|
98
118
|
- Other services' keys (an OpenAI key, say): same place, read on the server only.
|
|
99
119
|
- Anything named `NEXT_PUBLIC_*` is copied into the browser. Never put a key there.
|