尚未偵測到更新。GitHub 發布版本後會顯示在這裡。
個人 GitHub 帳號下公開儲存庫的擁有者可以登入並驗證所有權,自行管理介紹,無需管理員核准。
登入並產生驗證檔案,在 30 分鐘內將其提交至此儲存庫的預設分支。其他分支或分叉儲存庫中的檔案無效。然後在下方檢查檔案,即可無需管理員核准直接管理專案。請保留檔案以維持管理權限。
如需登入,將前往登入頁面。登入後請回到此處,再次點擊所選的驗證按鈕。
在專案資料夾中執行 /nomorevibe verify,即可驗證所有權並自行管理介紹。
一分鐘完成驗證製作者的介紹僅有上面的一句話。 更多詳情請閱讀儲存庫 README。 儲存庫 README ↗
正在載入完整 README。
檢視完整 README ↗An online banking website built with Next.js 16 (App Router, TypeScript), with the features of a large U.S. retail bank, a Postgres database, passkey sign-in and a separate staff console.
npm install
cp .env.example .env.local # then fill in the values
npm run dev
Open http://localhost:3000 and open an account at /signup. New accounts start with $0 balances and no activity.
| Variable | What it's for |
|---|---|
DATABASE_URL | Postgres connection string (for example from Neon). Required. Tables are created on first run. |
APP_ORIGIN | The site's public address, e.g. https://anchorbank.com. Passkeys are tied to it, so set it in production and don't change it afterwards. Leave unset for localhost. |
ADMIN_PATH | The hidden address of the staff console, e.g. /ops-3f9a1c7e2b4d. At least 6 letters, numbers, - or _ after the slash. Without it the console is switched off. |
ADMIN_PASSWORD | The staff password. Staff sign in with this alone (no username). Use a long, unique one in production. |
VAPID_PUBLIC_KEY, VAPID_PRIVATE_KEY | Push notification keys. Generate a pair with npx web-push generate-vapid-keys. Changing them turns off notifications on every device until people turn them back on. |
VAPID_SUBJECT | A contact address for push services: mailto:[email protected] or your site's https:// address. |
RESEND_API_KEY | Resend API key for email. Without it, no emails are sent and "Forgot password" is unavailable. |
EMAIL_FROM | The sender, on a domain verified in Resend, e.g. Anchor Bank <[email protected]>. |
STAFF_EMAIL | Optional. Staff inbox for new deposits and withdrawals to review. |
AUTH_SECRET | 32+ random characters used to sign session cookies. If unset, a random key is created in .data/secret. |
Changing ADMIN_PASSWORD signs out every staff session.
The console has its own sign-in at <ADMIN_PATH>/login (password only) and no sign-up. Customers can't tell it exists: it isn't linked anywhere, /admin returns 404, its pages are noindex, its APIs answer 404 to anyone without a staff session, and its code and styles (app/admin/admin.css) load only under the hidden path, so nothing a customer's browser downloads mentions it. Staff and customer sign-ins use separate cookies and never grant each other access.
| Route | What it does |
|---|---|
<ADMIN_PATH>/login | Staff sign-in |
<ADMIN_PATH> | Stats, sign-ups, searchable customer list, activity log |
<ADMIN_PATH>/users/[id] | One customer: manage, edit, balances, transactions, page access, activity |
<ADMIN_PATH>/funding | Deposit addresses, and deposits and withdrawals to approve or decline |
On a customer's page staff can:
| Route | Who can see it | What it does |
|---|---|---|
/ | Everyone | Landing page |
/login, /signup | Signed-out visitors | Sign in (with "keep me signed in") or open an account |
/dashboard | Signed in | Balance card, actions, quick transfer, monthly stats and charts, budgets, upcoming payments, goals, credit score |
/activity, /statements | Signed in | Transactions with filters; monthly statements with CSV download |
/transfer, /send, /bills | Signed in | Transfers and card payments, send/request money, bill pay |
/deposit, /withdraw | Signed in | Deposit to the address staff publish (or buy with a card through Ramp), and withdraw to your own wallet. Both wait for staff approval. |
/budget, /goals, /credit | Signed in | Budgets, savings goals, credit score |
/cards, /alerts, /profile | Signed in | Card controls, alerts, profile and security settings |
Both use BTC, ETH (Ethereum) or USDC (Ethereum, ERC-20) addresses.
Nothing moves funds on a blockchain automatically: staff check incoming deposits and send withdrawals from the bank's own wallet.
Customers turn them on per device in Profile → Preferences → Notifications on this device. They're told about deposits and withdrawals being approved or declined, new sign-ins (if Sign-in alerts is on), password changes and passkeys being added or removed. Signing out turns that device off.
Staff turn them on under Deposits & withdrawals → Notify me on this device, and hear about every new deposit and withdrawal to review. Notification text never includes customer names or full addresses.
On iPhone, notifications work once Anchor Bank is added to the Home Screen and opened from there (iOS 16.4 or later).
Sent through Resend from EMAIL_FROM, in one Anchor-branded layout (lib/server/email.ts). Customers get:
/forgot-password): one-time, valid for 30 minutes, only a hash is stored, and the reply is the same whether or not the email has an accountButtons in alert emails link to APP_ORIGIN, so set it on your host. With STAFF_EMAIL set, staff also get an email for each new deposit and withdrawal.
The visitor's country comes from the host's location header (Vercel x-vercel-ip-country, Cloudflare cf-ipcountry, CloudFront) or, failing that, the region in their browser language (app/api/locale, lib/locale.ts).
components/AutoTranslate.tsx). Page text is sent to Google to translate. The bank's name and account names are left as they are. English-speaking countries see the original.Anchor Bank is a progressive web app: app/manifest.ts, icons in public/, and a service worker (public/sw.js, registered in production only) that keeps the app's static files and shows public/offline.html without a connection. Account pages and API responses are never cached on the device. Customers can install it from the menu (Install Anchor app) or Profile → Preferences → Install the app; on iPhone that shows the Add to Home Screen steps. The app icon, maskable icon, Apple touch icon and a monochrome notification badge are in public/.
Postgres at DATABASE_URL, through pg. Missing tables are created on first run:
users: name, email, phone, scrypt password hash, status (active or suspended), session version, staff note, sign-in statsbank_accounts, ledger, scheduled_payments: accounts, the append-only ledger balances are summed from, and future-dated paymentsbank_state: each customer's settings (profile, payees, budgets, card controls) as JSONuser_page_access: pages staff have switched off or on per customer (no row means on)passkeys: each customer's passkeys (WebAuthn public keys, never private keys)push_subscriptions: devices that receive notifications (a customer's, or staff)deposit_addresses, crypto_deposits, crypto_withdrawals: deposit addresses staff publish, and deposit and withdrawal requests with their reviewaudit_log: every sign-up, sign-in and staff action, with who did it and whenEach payment runs in one transaction that holds a lock for that customer, so two requests can't spend the same balance.
ADMIN_PASSWORD.proxy.ts redirects signed-out requests, and the server layouts and every API verify the session again.Origin isn't this site.For production, serve over HTTPS (cookies are Secure in production) and set APP_ORIGIN.
proxy.ts: route protection and the hidden staff path (rewritten internally to app/admin)lib/server/db.ts: Postgres pool, schema, all/one/run queries and tx transactionslib/server/users.ts, session.ts, current.ts, http.ts: accounts, signed sessions, the signed-in customer, auth helperslib/server/adminAuth.ts: staff credentials, cookie and guardlib/server/passkeys.ts, app/api/auth/passkey, app/api/passkeys: passkey sign-in step and managing passkeyslib/server/push.ts, lib/server/pushRoute.ts, app/api/push, <ADMIN_PATH>/api/push, components/pwa.ts, public/sw.js: push notifications, install prompt, service workerlib/funding.ts, lib/server/funding.ts, app/api/funding, app/admin/api/funding: deposits, withdrawals and their approvallib/pages.ts, lib/server/permissions.ts: the pages staff can switch off per customer, and the checkslib/server/admin.ts: customer search, stats, staff actions and the activity logapp/api/auth/*: signup, login, passkey, password, logout, meapp/api/bank: load and save the signed-in customer's banking dataapp/admin/api/session, app/admin/api/users, app/admin/api/users/[id]: staff sign-in, customer list, detail, actions and deleteapp/admin, components/admin/*: staff consolelib/types.ts, lib/seed.ts, lib/logic.ts, lib/format.ts: data model, new-account state, banking rules, formattingcomponents/BankProvider.tsx: loads and saves banking data, loading screenBalances live in this app's own database and are changed by the browser, and no money moves to or from other banks. Holding real customer money needs a server-side ledger, a core banking or banking-as-a-service provider, payment rails (ACH, card networks, a person-to-person network), identity verification (KYC), fraud monitoring, and the bank charter or partner bank and compliance programs that come with it.