Skip to content

Commit dfb87d2

Browse files
Merge pull request #207 from MeshJS/feature/minor-additions
chore: update configuration and enhance bot functionality
2 parents 95d054f + 23dc7cb commit dfb87d2

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

61 files changed

+4007
-200
lines changed

.agents/README.md

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
# Agent instructions (Mesh Multisig)
2+
3+
Project-specific context for AI coding agents. See also [.cursor/skills/multisig/SKILL.md](../.cursor/skills/multisig/SKILL.md) for the multisig Cursor skill.
4+
5+
## Stack and layout
6+
7+
- **Stack**: Next.js (Pages Router), TypeScript, tRPC, Prisma, PostgreSQL, Cardano (Mesh SDK). Auth: NextAuth (user) + JWT (API: wallet sign-in or bot keys).
8+
- **API**: REST v1 under `/api/v1/*`. OpenAPI: `GET /api/swagger`. Interactive docs: `/api-docs`.
9+
- **Key paths**: Pages in `src/pages/`, UI in `src/components/`, tRPC in `src/server/api/routers/`, REST handlers in `src/pages/api/v1/*.ts`, DB schema in `prisma/schema.prisma`.
10+
11+
## Build and test
12+
13+
- **Install**: `npm install`
14+
- **Env**: Copy `.env.example` to `.env`; set `DATABASE_URL`, `JWT_SECRET`, Blockfrost keys, etc. For local DB: `docker compose -f docker-compose.dev.yml up -d postgres`
15+
- **DB**: `npm run db:update` (format + push schema + generate client). Prisma Studio: `npm run db:studio`
16+
- **Dev**: `npm run dev`http://localhost:3000
17+
- **Lint**: `npm run lint`
18+
- **Tests**: `npm test` or `npm run test:ci` for CI
19+
20+
## Conventions
21+
22+
- **Wallet ID**: UUID from DB. **Address**: Cardano payment (or stake) address. Don’t confuse them.
23+
- **Scripts**: Use `scripts/` (e.g. `scripts/bot-ref/`). Run TS with `npx tsx`.
24+
- **New v1 endpoint**: Add handler in `src/pages/api/v1/<name>.ts`, apply CORS and rate limits, then add path and docs in `src/utils/swagger.ts`. If bots can call it, update the landing “Developers & Bots” section and `scripts/bot-ref/README.md` as needed.
25+
- **Bot auth**: Implemented in `src/pages/api/v1/botAuth.ts` and `src/lib/auth/botKey.ts`, `botAccess.ts`. Bot keys created in-app (User → Create bot). One key → one `paymentAddress`; use `Authorization: Bearer <token>` for v1 after `POST /api/v1/botAuth`.
26+
27+
## Bot integration (machine-friendly)
28+
29+
- **OpenAPI**: `GET /api/swagger` (JSON).
30+
- **Bot auth**: `POST /api/v1/botAuth` with body `{ "botKeyId", "secret", "paymentAddress" }``{ "token", "botId" }`. Use token as Bearer for `walletIds`, `pendingTransactions`, `freeUtxos`, `addTransaction`, `signTransaction`, etc. Reference client: `scripts/bot-ref/` (see README there).
31+
32+
## Docs to keep in sync
33+
34+
- Landing “Developers & Bots” section: `src/components/pages/homepage/index.tsx` (id `#developers-and-bots`).
35+
- API/bot docs: `src/utils/swagger.ts`, `scripts/bot-ref/README.md`.

.cursor/skills/multisig/SKILL.md

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
---
2+
name: multisig
3+
description: Build and integrate with the Mesh Multisig (Cardano multisig wallet) codebase. Use when working on multisig wallets, bot API, v1 REST endpoints, wallet flows, governance, or Cardano treasury tooling.
4+
---
5+
6+
# Multisig (Mesh)
7+
8+
## Project overview
9+
10+
- **Stack**: Next.js (Pages Router), tRPC, Prisma, Cardano (Mesh SDK).
11+
- **Auth**: NextAuth (user) + JWT for API (wallet sign-in or bot keys).
12+
- **API**: REST v1 under `/api/v1/*` (Swagger at `/api-docs`, spec at `/api/swagger`).
13+
14+
## Key areas
15+
16+
| Area | Location | Notes |
17+
|------|----------|--------|
18+
| Landing page | `src/components/pages/homepage/index.tsx` | Hero, features, DApps, Developers & Bots section |
19+
| API docs (Swagger) | `src/pages/api-docs.tsx`, `src/utils/swagger.ts` | OpenAPI 3.0; add new paths in `swagger.ts` |
20+
| Bot API | `src/pages/api/v1/botAuth.ts`, `src/lib/auth/botKey.ts`, `src/lib/auth/botAccess.ts` | Bot auth: POST `/api/v1/botAuth` with `botKeyId`, `secret`, `paymentAddress` |
21+
| Reference bot client | `scripts/bot-ref/` | `bot-client.ts`; auth → walletIds, pendingTransactions, freeUtxos |
22+
| Wallet flows | `src/components/pages/homepage/wallets/new-wallet-flow/`, `useWalletFlowState.tsx` | New wallet creation and invite flow |
23+
| tRPC | `src/server/api/routers/`, `src/server/api/root.ts` | Wallets, bot routers |
24+
| DB | `prisma/schema.prisma` | Wallet, BotKey, BotUser, etc. |
25+
26+
## Bot integration (machine-friendly)
27+
28+
- **OpenAPI spec (JSON)**: `GET /api/swagger` — use for codegen or automation.
29+
- **Auth (bots)**: `POST /api/v1/botAuth`
30+
Body: `{ "botKeyId": string, "secret": string, "paymentAddress": string, "stakeAddress"?: string }`
31+
Response: `{ "token": string, "botId": string }`. Use `Authorization: Bearer <token>` for v1 endpoints.
32+
- **Bot keys**: Created in-app (User → Create bot). One bot key can have one `paymentAddress`; same address cannot be used by another bot.
33+
- **Scopes**: Bot keys have scope (e.g. `multisig:read`); `botAccess.ts` enforces wallet access for bots.
34+
- **V1 endpoints used by bots**: `walletIds` (query `address` = bot’s `paymentAddress`), `pendingTransactions`, `freeUtxos`, `addTransaction`, `signTransaction`, etc. Same as wallet-authenticated calls but identity is the bot’s registered address.
35+
36+
## Conventions
37+
38+
- **Wallet ID**: UUID from DB; **address**: Cardano payment (or stake) address.
39+
- **Scripts**: Reference scripts in `scripts/` (e.g. `scripts/bot-ref/`). Use `npx tsx` for TS scripts.
40+
- **Env**: `JWT_SECRET` required for API tokens; bot keys stored hashed in DB.
41+
42+
## When editing
43+
44+
- Adding a new v1 endpoint: implement in `src/pages/api/v1/<name>.ts`, add path and CORS/rate limits, then add to `src/utils/swagger.ts` and document bot usage if applicable.
45+
- Changing bot auth or scopes: update `botAuth.ts`, `botAccess.ts`, and landing “Developers & Bots” section plus `scripts/bot-ref/README.md` if needed.
46+
- Landing page: human and bot-friendly docs live in the “Developers & Bots” section; keep OpenAPI URL and bot auth summary accurate.

.gitignore

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,11 @@ yarn-error.log*
3636
.env
3737
.env*.local
3838

39+
# bot ref client config (contains secret)
40+
scripts/bot-ref/bot-config.json
41+
# generated bot wallet for testing (mnemonic + address)
42+
scripts/bot-ref/bot-wallet.json
43+
3944
# vercel
4045
.vercel
4146

AGENTS.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# Agent instructions
2+
3+
Project instructions for coding agents are in **[.agents/README.md](.agents/README.md)**.

docker-compose.dev.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ services:
33
image: postgres:14-alpine
44
container_name: multisig-postgres-dev
55
ports:
6-
- "5433:5432"
6+
- "5434:5432"
77
environment:
88
POSTGRES_USER: postgres
99
POSTGRES_PASSWORD: postgres

docker/init-db.sh

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,17 @@ set -e
33

44
echo "Initializing database..."
55

6-
# This script runs automatically when PostgreSQL container starts for the first time
7-
# Add any custom initialization SQL here if needed
6+
# Roles required by migration 20251215090000_enable_rls_disable_postgrest (Supabase-style RLS)
7+
psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" --dbname "$POSTGRES_DB" <<-EOSQL
8+
DO \$\$
9+
BEGIN
10+
IF NOT EXISTS (SELECT 1 FROM pg_roles WHERE rolname = 'anon') THEN
11+
CREATE ROLE anon NOLOGIN;
12+
END IF;
13+
IF NOT EXISTS (SELECT 1 FROM pg_roles WHERE rolname = 'authenticated') THEN
14+
CREATE ROLE authenticated NOLOGIN;
15+
END IF;
16+
END \$\$;
17+
EOSQL
818

919
echo "Database initialization complete."

package-lock.json

Lines changed: 18 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,8 @@
1919
"test:watch": "jest --watch",
2020
"test:coverage": "jest --coverage",
2121
"test:ci": "jest --ci --coverage --watchAll=false",
22-
"analyze": "ANALYZE=true npm run build"
22+
"analyze": "ANALYZE=true npm run build",
23+
"apply-project": "node scripts/apply-project-to-github.mjs"
2324
},
2425
"dependencies": {
2526
"@auth/prisma-adapter": "^2.11.1",
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
-- AlterTable
2+
ALTER TABLE "NewWallet" ADD COLUMN "stakeCredentialHash" TEXT;
23
ALTER TABLE "NewWallet" ADD COLUMN "scriptType" TEXT;
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
-- AlterTable
2+
ALTER TABLE "Wallet" ADD COLUMN IF NOT EXISTS "ownerAddress" TEXT;
3+
4+
-- CreateTable
5+
CREATE TABLE "BotKey" (
6+
"id" TEXT NOT NULL,
7+
"ownerAddress" TEXT NOT NULL,
8+
"name" TEXT NOT NULL,
9+
"keyHash" TEXT NOT NULL,
10+
"scope" TEXT NOT NULL,
11+
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
12+
13+
CONSTRAINT "BotKey_pkey" PRIMARY KEY ("id")
14+
);
15+
16+
-- CreateTable
17+
CREATE TABLE "BotUser" (
18+
"id" TEXT NOT NULL,
19+
"botKeyId" TEXT NOT NULL,
20+
"paymentAddress" TEXT NOT NULL,
21+
"stakeAddress" TEXT,
22+
"displayName" TEXT,
23+
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
24+
25+
CONSTRAINT "BotUser_pkey" PRIMARY KEY ("id")
26+
);
27+
28+
-- CreateEnum
29+
CREATE TYPE "BotWalletRole" AS ENUM ('cosigner', 'observer');
30+
31+
-- CreateTable
32+
CREATE TABLE "WalletBotAccess" (
33+
"walletId" TEXT NOT NULL,
34+
"botId" TEXT NOT NULL,
35+
"role" "BotWalletRole" NOT NULL,
36+
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
37+
38+
CONSTRAINT "WalletBotAccess_pkey" PRIMARY KEY ("walletId","botId")
39+
);
40+
41+
-- CreateIndex
42+
CREATE INDEX "BotKey_ownerAddress_idx" ON "BotKey"("ownerAddress");
43+
44+
-- CreateIndex
45+
CREATE UNIQUE INDEX "BotUser_botKeyId_key" ON "BotUser"("botKeyId");
46+
47+
-- CreateIndex
48+
CREATE UNIQUE INDEX "BotUser_paymentAddress_key" ON "BotUser"("paymentAddress");
49+
50+
-- CreateIndex
51+
CREATE INDEX "BotUser_paymentAddress_idx" ON "BotUser"("paymentAddress");
52+
53+
-- CreateIndex
54+
CREATE INDEX "WalletBotAccess_walletId_idx" ON "WalletBotAccess"("walletId");
55+
56+
-- CreateIndex
57+
CREATE INDEX "WalletBotAccess_botId_idx" ON "WalletBotAccess"("botId");
58+
59+
-- AddForeignKey
60+
ALTER TABLE "BotUser" ADD CONSTRAINT "BotUser_botKeyId_fkey" FOREIGN KEY ("botKeyId") REFERENCES "BotKey"("id") ON DELETE CASCADE ON UPDATE CASCADE;

0 commit comments

Comments
 (0)