Inside Creditopia: The Anatomy of an On-Chain Lending App
Creditopia is the peer-to-peer lending platform my team built on the Internet Computer — and the one that took first place at the Chain Fusion Hacker House. I already wrote the story of the 48 hours. This one is the teardown: the actual shape of the product, told in pictures, a diagram, code, and a clip of it running.
BlockchainWhat we actually shipped
Creditopia connects small businesses that need capital with a global pool of lenders, and puts the smart contract in the middle so neither side has to trust the other. Here is the product itself — the dashboard a borrower sees when they open a financing request.

The core idea in one sentence
Traditional P2P lending needs a trusted platform in the middle. Creditopia replaces that platform with a smart contract, so the rules are trusted instead of a company.
The lending loop
The whole app is one loop: a request flows in from an SME, the contract escrows and matches it, and funding flows back from lenders. Drawn out, it looks like this — and it never stops moving.
The contract, in code
Because we built on ICP, the lending logic lives in a canister written in Motoko. The heart of it is small — a request is created, funded by lenders, and only released once it is fully backed. Simplified, the funding path reads like this:
public shared({ caller }) func fundRequest(id : RequestId, amount : Nat) : async Result<(), Text> {
switch (requests.get(id)) {
case null { #err("request not found") };
case (?req) {
if (req.status != #open) return #err("request is not open");
if (req.funded + amount > req.target) return #err("over-funds target");
// Record the lender's stake on-chain, then advance state.
let updated = { req with funded = req.funded + amount };
ledger.credit(caller, id, amount);
requests.put(id, updated);
if (updated.funded == req.target) { await release(id) };
#ok(())
};
};
};Why the checks come first
On an append-only ledger there is no undo. Every guard clause runs before a single token moves — a bug here is not a rollback, it is a permanent public record of the mistake.
The result
We took it on stage at Coinfest Asia in Bali and ran the full loop live. The numbers, for the record:
1st
Place, out of 100+ teams
48h
From empty repo to demo
$3,000
Developer grant won
4
Stacks: Motoko · Rust · JS · Vue


The demo path is the product. Everything else is scaffolding you can throw away after the judges leave.
See it move
Screens and diagrams only go so far. Here is a short capture of the dashboard itself — the same build we demoed.
If you want to build one
- 1Model the state machine first — open, funded, released — and make illegal transitions impossible, not just unlikely.
- 2Put every validation before any state change. On-chain, order is safety.
- 3Read balances from the chain, not a mirror database, or your UI will lie the moment they drift.
- 4Protect the one loop that has to work, and cut everything that does not serve it.
That is the whole app, start to finish. Want the story of the 48 hours that produced it? That is in the companion post — read on below.
Written by
Alfara Nafi Dinara
Full-stack, blockchain, and LLM engineer. Building something and want a hand? Tell me what you're building and where you're stuck — I usually reply within minutes.
Start a project