Open Net Worth
Open Net Worth is an open-source personal AI wealth assistant you run yourself: one ledger for your whole financial life, worked by an AI agent you control.
翻譯準備中
尚未偵測到更新。GitHub 發布版本後會顯示在這裡。
個人 GitHub 帳號下公開儲存庫的擁有者可以登入並驗證所有權,自行管理介紹,無需管理員核准。
登入並產生驗證檔案,在 30 分鐘內將其提交至此儲存庫的預設分支。其他分支或分叉儲存庫中的檔案無效。然後在下方檢查檔案,即可無需管理員核准直接管理專案。請保留檔案以維持管理權限。
如需登入,將前往登入頁面。登入後請回到此處,再次點擊所選的驗證按鈕。
在專案資料夾中執行 /nomorevibe verify,即可驗證所有權並自行管理介紹。
一分鐘完成驗證正在載入完整 README。 以下為已儲存的摘錄。
Paytm Build for India AI Hackathon — Delhi Edition · Track 2: AI-Powered Financial Journeys
Team1 — Arun Kumar, Vivek Goswami
A real-time decision layer that decides, at the moment of payment, whether to surface
pre-approved credit — and which product — so the customer never has to separately discover,
apply for and wait on a loan.
The novel piece is not the checkout screen. It is an engine that can explain every decision it
makes, including the ones where it stays silent.檢視完整 README ↗Paytm Build for India AI Hackathon — Delhi Edition · Track 2: AI-Powered Financial Journeys Team1 — Arun Kumar, Vivek Goswami
A real-time decision layer that decides, at the moment of payment, whether to surface pre-approved credit — and which product — so the customer never has to separately discover, apply for and wait on a loan.
The novel piece is not the checkout screen. It is an engine that can explain every decision it makes, including the ones where it stays silent.
npm install
npm run dev # http://localhost:3000
npm test # 32 engine tests, ~150ms
npm run scenarios # prints every demo scenario with its reasoning
Nothing needs configuring. Without any API keys the app runs end to end on template copy and the
direct API path; keys upgrade those two slots in place. See .env.example.
| Built here | The decision engine, the memory/feature layer, the audit trail, the checkout UI, the orchestration wiring |
| Mocked | Credit issuance, KYC, OTP, the partner-bank approval call — Paytm and its partner banks (SBI / HDFC / IDFC First / Suryoday) run this in production already |
| Synthetic | Every user, merchant and transaction. Eligibility is a simplified stand-in for Paytm's real underwriting, not an attempt to reproduce it |
Synthetic does not mean arbitrary. Each persona has a seeded transaction ledger, and every behavioural signal is re-derived from those rows — see below.
checkout screen
└─> n8n webhook ──> POST /api/decide ──> IF showNudge ──> POST /api/nudge-text
(3s timeout, (Sarvam, with
auto-fallback) template fallback)
└─> POST /api/decide [fallback path, identical result]
lib/
memory/ ledger.ts seeded transaction history per persona
features.ts detects salary + recurring obligations from the rows
signal.ts features -> eligibility signal, with a breakdown
engine/ gates.ts 14 hard blocks, ordered, short-circuiting
score.ts 4 weighted relevance factors
product.ts Postpaid vs card, deterministic
emi.ts tenures and exact-rounding schedules
decide.ts orchestrates the above
nudge/ sarvam.ts generation, validation, cache, fallback
templates.ts contextual copy in hi / en / ta / bn
The engine is a pure function. It reads no clock, no database and no environment — the caller supplies the timestamp and the nudge history. Three consequences:
The pitch rests on "the system already knows." That claim is backed rather than asserted:
affordabilityCapacity, which is what the affordability gate checks.So three of the fourteen gates are grounded in derived behaviour rather than a hardcoded flag. Open the demo drawer → "What the system already knows" to see the ledger, the detections and the resulting signal side by side.
Ordered, short-circuiting; the first failure decides the outcome and no score overrides it.
CATEGORY_PROHIBITED · MERCHANT_NOT_ENABLED · AMOUNT_FLOOR · AMOUNT_CEILING ·
CATEGORY_RELEVANCE · OPTED_OUT · COLD_START · NOT_ELIGIBLE · BANK_COOLOFF ·
FREQUENCY_CAP · NO_PRODUCT · ALREADY_ACTIVE · INSUFFICIENT_LIMIT · AFFORDABILITY
Two worth calling out. CATEGORY_PROHIBITED blocks person-to-person transfers, wallet
top-ups, gambling and crypto outright — routing borrowed money into a cash-equivalent is what
lending rules exist to prevent. AFFORDABILITY declines users who pass eligibility but whose
existing commitments leave no room; it is the gate that says we are not optimising for disbursal.
All three endpoints are plain HTTP and callable from n8n.
POST /api/decide// request — merchantId, or merchantCategory for merchants outside the catalogue
{ "userId": "u_rohit", "merchantId": "m_kroma", "amount": 50000 }
// response
{
"showNudge": true,
"product": "postpaid",
"score": 90,
"amount": 50000,
"blockedBy": null,
"offer": {
"partner": "Paytm Postpaid",
"limit": 100000,
"tenures": [
{ "months": 3, "emi": 16667, "lastEmi": 16666, "noCost": true, "interest": 0 },
{ "months": 6, "emi": 8727, "lastEmi": 8727, "noCost": false, "interest": 2362 }
]
},
"decline": { "label": "No thanks, pay normally", "suppressDays": 7 },
"trace": { "gates": [], "factors": [], "productRationale": "", "counterfactual": "", "summary": "" },
"eligibilitySignal": 86,
"eligibilityBreakdown": []
}
A withheld nudge returns the same shape with showNudge: false, a blockedBy code and a
human-readable blockedReason. No-nudge is a first-class response, not an error.
POST /api/nudge-textTakes terms the engine has already settled and returns one line of copy. Always succeeds —
source is sarvam, cache or template, and reason says why if it fell back.
GET /api/health · GET /api/profile?userId=Health is for the n8n healthcheck. Profile returns the derived features plus the ledger they came from.
Sarvam's job is phrasing, never deciding. The engine settles what to offer and on what terms; Sarvam says it well in the user's language. A language model must never be able to talk a user into credit the engine did not approve.
Three protections wrap the call:
Set SARVAM_API_KEY to go live. Without it every response is a template and says so.
Import n8n/one-tap-credit.workflow.json, then replace https://REPLACE-ME.vercel.app in the two
HTTP Request nodes with your deployed URL. Copy the production webhook URL into
NEXT_PUBLIC_N8N_WEBHOOK_URL.
Transaction event (webhook)
└─> Decision engine POST /api/decide
└─> Eligible? IF showNudge
├─ true ─> Pick headline plan ─> Sarvam nudge copy ─> Attach copy ─> Respond
└─ false ─────────────────────────────────────────────────────────> Respond
n8n Cloud cannot reach localhost, so the app must be deployed before the orchestrated path
works. The checkout falls back to calling /api/decide directly after 3 seconds, and the demo
drawer shows which path actually served the response — so a dead network degrades silently
instead of breaking the demo.
If the import misbehaves, the workflow is six nodes and takes about five minutes to rebuild by hand from the diagram above.
Open the drawer by tapping the avatar on the home screen. Each row is one tap.
| # | Do this | What happens | The line to say |
|---|---|---|---|
| 1 | Rohit → Kroma Electronics, ₹50,000 | Nudge: Postpaid, 3 × ₹16,667, no cost | "The offer appears at the moment of paying, in Hindi, already priced." |
| 2 | Tap Why am I seeing this? | 14 checks, 4 score factors, 5 signal components | "Every decision is auditable. That's slide 11, shipped." |
| 3 | Keypad → change to ₹450 | Nudge disappears, engine strip shows AMOUNT_FLOOR | "It declines more often than it offers." |
| 4 | Merchant → Rahul Sharma (P2P), ₹35,000 | CATEGORY_PROHIBITED | "No amount and no eligibility signal unlocks this one." |
| 5 | Persona → Priya, ₹50,000 | AFFORDABILITY, signal 70 | "She passes eligibility. We decline anyway — ₹8,727/month against ₹7,951 of capacity." |
| 6 | Persona → Aman | COLD_START — 18 days, 8 transactions | "Cold start is on our risk slide. Here it is, handled." |
| 7 | Drawer → What the system already knows | Ledger rows, detected salary, detected EMIs | "This is where the eligibility number comes from. Nothing is hardcoded." |
| 8 | Back to Rohit ₹50,000 → Activate & Pay → confirm | Approval, schedule, success | "16,667 + 16,667 + 16,666 — it adds up to exactly ₹50,000." |
| 9 | Terminal: npm test | 32 passing in ~150ms | "And it's covered." |
Closing line: "The credit products already exist. The bank approvals already exist. What was missing was the decision layer that knows when to ask — and, more often, when not to."
npm test # 32 tests: every gate, product selection, EMI rounding, the audit trail
npm run scenarios
The EMI tests are worth a look — no-cost instalments must sum to the principal exactly, and the final payment must never be the largest one.