Open Net Worth
Open Net Worth는 직접 운영하는 오픈소스 개인 AI 자산 비서로, 전체 재무를 하나의 원장에 기록하고 사용자가 제어하는 AI가 관리
실시간 의사결정 레이어가 결제 시점에 사전 승인 신용을 제공하고, 모든 결정(비공개 결정 포함)의 이유를 설명합니다
A real-time decision layer that surfaces pre-approved credit at the moment of paying — and explains every decision, including the ones where it stays silent.
금융TypeScript · JavaScriptGitHub @carbonFibreCode온라인운영자 미확인
써 보셨어요? 한 번만 눌러 주세요. 로그인은 필요 없어요.
아직 감지된 업데이트가 없습니다. GitHub 릴리스가 나오면 여기에 보입니다.
개인 계정의 공개 저장소 소유자는 GitHub로 로그인해 운영자를 확인하고 소개를 직접 관리할 수 있습니다. 관리자 승인은 필요하지 않습니다.
로그인한 뒤 확인 파일을 만들어 이 저장소의 기본 브랜치에 30분 안에 커밋해 주세요. 다른 브랜치나 포크의 파일은 인정하지 않습니다. 파일을 올린 뒤 아래에서 확인하면 관리자 승인 없이 관리할 수 있습니다. 자격을 유지하려면 파일을 남겨 두세요.
로그인이 필요하면 로그인 화면으로 이동합니다. 로그인 후 이곳으로 돌아와 원하는 확인 버튼을 다시 눌러 주세요.
프로젝트 폴더에서 /nomorevibe verify를 실행하면 소유권을 확인하고 소개를 직접 관리할 수 있습니다.
1분 만에 확인하기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.