@chaindaddy/mcp 0.6.9 → 0.6.10
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": "@chaindaddy/mcp",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.10",
|
|
4
4
|
"description": "MCP server for Chain Daddy: search tickers, launch a token or verify ownership of one, and run its creator store",
|
|
5
5
|
"mcpName": "io.chaindaddy/mcp",
|
|
6
6
|
"homepage": "https://docs.chaindaddy.io/developer/store-and-rewards#tools-for-agents",
|
|
@@ -27,7 +27,7 @@ Use discovery: `https://api.chaindaddy.io/.well-known/openid-configuration`
|
|
|
27
27
|
|
|
28
28
|
Any site can sign people in without registering anything.
|
|
29
29
|
|
|
30
|
-
Replace `YOUR_SITE` with the site's
|
|
30
|
+
Replace `YOUR_SITE` with the site's host, such as `example.com`. Nothing is registered with Chain Daddy. The site must be public, on https, even while you build (a tunnel such as `cloudflared tunnel --url http://localhost:3000`, which needs no account, or a preview deployment): Chain Daddy's server fetches `client.json`, so `localhost` cannot be a client id.
|
|
31
31
|
|
|
32
32
|
1. Host this at `https://YOUR_SITE/client.json` (served 200, no redirect; `client_id` must equal its own URL):
|
|
33
33
|
|
|
@@ -111,9 +111,15 @@ async function verifyChainDaddy(idToken) {
|
|
|
111
111
|
return payload; // sub: the person's id at this site; wallets[0]: the wallet they signed in with
|
|
112
112
|
}
|
|
113
113
|
|
|
114
|
-
// Your own sessions, by the id in the cookie. A real deployment keeps these in its session store or Redis.
|
|
114
|
+
// Your own sessions, by the id in the cookie, for a day. A real deployment keeps these in its session store or Redis.
|
|
115
115
|
const sessions = new Map();
|
|
116
|
-
const
|
|
116
|
+
const DAY = 24 * 60 * 60 * 1000;
|
|
117
|
+
const sessionId = (req) => /(?:^|; )session=([^;]+)/.exec(req.headers.cookie ?? '')?.[1] ?? '';
|
|
118
|
+
const sessionOf = (req) => {
|
|
119
|
+
const user = sessions.get(sessionId(req));
|
|
120
|
+
if (user && user.expires > Date.now()) return user;
|
|
121
|
+
sessions.delete(sessionId(req));
|
|
122
|
+
};
|
|
117
123
|
|
|
118
124
|
const app = express();
|
|
119
125
|
app.use(express.json());
|
|
@@ -127,8 +133,8 @@ app.post('/session', async (req, res) => {
|
|
|
127
133
|
return res.status(401).json({ error: 'sign_in_failed', message: 'That sign-in could not be checked. Sign in again.' });
|
|
128
134
|
}
|
|
129
135
|
const id = randomUUID();
|
|
130
|
-
sessions.set(id, { sub: payload.sub, wallet: payload.wallets?.[0] });
|
|
131
|
-
res.cookie('session', id, { httpOnly: true, secure: true, sameSite: 'lax' });
|
|
136
|
+
sessions.set(id, { sub: payload.sub, wallet: payload.wallets?.[0], expires: Date.now() + DAY });
|
|
137
|
+
res.cookie('session', id, { httpOnly: true, secure: true, sameSite: 'lax', maxAge: DAY });
|
|
132
138
|
res.json({ ok: true });
|
|
133
139
|
});
|
|
134
140
|
|
|
@@ -158,7 +164,7 @@ export function holdsCoin(payload) {
|
|
|
158
164
|
}
|
|
159
165
|
```
|
|
160
166
|
|
|
161
|
-
In `POST /session`, keep the answer in the session: `sessions.set(id, { sub: payload.sub, wallet: payload.wallets?.[0], holder: holdsCoin(payload) });`. Then add the holders' route:
|
|
167
|
+
In `POST /session`, keep the answer in the session: `sessions.set(id, { sub: payload.sub, wallet: payload.wallets?.[0], holder: holdsCoin(payload), expires: Date.now() + DAY });`. Then add the holders' route:
|
|
162
168
|
|
|
163
169
|
```js
|
|
164
170
|
// Only a holder gets this. Everyone else stays signed in and is told why not.
|