DeWorks
Blockchain escrow for freelance payments.
Overview
A platform bridging freelancers and clients, using blockchain to make payments secure and transparent. Built at the Unfold'23 hackathon around a problem worth solving: freelance payments that arrive late, or not at all.
DeWorks is a freelance marketplace built on blockchain. Clients post jobs and lock the pay in a smart contract. Freelancers browse the postings and request the ones they want. We built it at the Unfold'23 hackathon in Bangalore in October 2023, where blockchain was the theme.
I worked on the Next.js frontend and the backend API routes, in a team with Jayanth Srinivasan, Surendar PD and Chanakyha. I wasn't the primary blockchain developer. The contract work sat mostly with teammates, and I connected the app to it.
The Problem
Payments between freelancers and clients can go wrong on both sides. Sometimes the work isn't delivered by the freelancer who committed to it. Sometimes the client doesn't pay properly. We wanted to address both sides, and the hackathon's blockchain theme made an escrow contract a natural fit.
The idea behind DeWorks:
- The client commits the pay up front, so the freelancer can see the money is already locked in the contract.
- The job's progress is recorded on-chain, so the state of the work is visible to both parties rather than resting on a promise.
- Payment moves through the contract instead of by trust between the two sides.
My Role
I took on the frontend and the backend, and we put a lot of effort into making the frontend look good. My work included:
- The landing page content and shared navigation and footer.
- The post-a-job and find-a-job pages, plus the individual posting page.
- The client dashboard, the connect-wallet button, and wiring the pages to the contract.
- The Push Protocol notification API route, and fetching user data.
The other contributors were Jayanth Srinivasan, Surendar PD and
Chanakyha.
How It Works
The app is a Next.js (Pages Router) site styled with Tailwind CSS and shadcn/ui components. Users connect a wallet with RainbowKit and Wagmi, and the pages read from and write to a smart contract on the Polygon Mumbai testnet. The server side is small: two API routes, one for notifications and one for file uploads.
The job and payment flow
The contract's interface (its ABI) lists the functions behind the flow:
- postJob is payable. The client sends the job's pay in MATIC along with the posting.
- requestJob lets a freelancer request a posted job.
- acceptJobRequest selects a freelancer for the job.
- completeJob marks the job completed, and the contract emits a MATICTransferred event.
Jobs also carry their own details on-chain: title, location, category, experience level and pay. Client and freelancer profiles are stored in the contract too.
In the web app, the pages call postJob, the job read functions and the profile functions. The requestJob, acceptJobRequest and completeJob functions are in the ABI, but I couldn't find a call to them in the frontend.
Notifications and file upload
A notification API route signs with a server-side wallet and sends a notification to a Push Protocol channel. A second route issues a Spheron upload token so the browser can upload a file to IPFS from the freelancer's posting page.
Challenges
- Integrating the smart contracts. They are the backbone of the platform, and connecting them to a working UI took most of the effort.
- Initializing the Push Protocol channel. We wanted real-time notifications between clients and freelancers.
- Initializing the payment contracts. Payment handling needed careful setup.
- A smooth, fast user experience. Next.js and shadcn/ui components helped us get a polished frontend within the hackathon's time limit.
- Migrating from Web3.js to Ethers and Wagmi. This changed how the app managed wallets and contract calls. The old Web3-style helper code is still visible as comments in the contract utility file.
Outcome
DeWorks worked as a hackathon prototype on a testnet. Users could connect a wallet, create a profile as a client or freelancer, post a job with its pay locked in the contract, browse postings, and use client and freelancer dashboards.
It was never a production product. Some pages used mock posting content during development, and the request, accept and complete steps of the flow aren't wired into the frontend. The project is archived, and the repository has no Solidity source. Polygon has since retired the Mumbai testnet the contract was deployed on.
What I Learned
- Keep signing keys on the server. The notification route reads its wallet from server environment variables, and the commented-out earlier version used a public-prefixed variable, which would expose it to the browser.
- Public chains hold public data. Profile fields, including email, are written to the contract, which is a real trade-off for a marketplace.
- A contract's interface is part of the frontend's job. The ABI, the helper functions and the pages all had to stay in sync as the contract changed.
- Hackathon speed shows in the structure. Mock content, a few unused files and several bug-fix commits are what a three-day build looks like.
If I Started Today
- Keep the Solidity source and tests in the repository, with a framework like Hardhat or Foundry.
- Model milestones in the contract, so partial payments and partial delivery are tracked on-chain.
- Generate typed contract bindings so the frontend can't drift from the ABI.
- Keep personal details such as email off-chain and store only a reference on-chain.
- Use Push Protocol's production environment, and add a deploy step for the contract as well as the site.