The website is now back up and running. You can visit it at https://hash-this.vercel.app. You can also find the issues and solutions commentary below.
@zz_tovarishch @xingtianchunyan
Issues Encountered & Solutions
This document catalogs all major technical challenges faced during the HashThis deployment and their resolutions.
Issue 1: Lumos Concurrency Problems
Reported By: @oiclid
Date: February 28, 2026
Problem
The original implementation used @ckb-lumos/lumos SDK which had potential concurrency issues when multiple users submitted transactions simultaneously.
Root Cause
Lumos’s transaction building process wasn’t designed for concurrent operations in serverless environments where multiple function instances handle requests in parallel.
Solution
Migrated from Lumos to @ckb-ccc/core (Common Chain Connector):
-
CCC has built-in concurrency handling
-
Simpler API with automatic input collection (completeInputsByCapacity)
-
Official recommendation from CKB DevRel team
-
Active maintenance and better TypeScript support
Impact on Deployment Options
This migration benefits both deployment architectures:
Files Changed
-
api-backend/api/hashes/ckb.service.ts - Serverless version using CCC
-
backend/src/services/ckb.service.ts - Express version using CCC
-
Both package.json files - Replaced Lumos dependency with CCC
Issue 2: Cell Capacity Calculation Error
Date: February 15, 2026
Problem
InsufficientCellCapacity: expected 0x25a01c500 <= capacity 0x2540be400
Root Cause
Initial capacity set to 100 CKB, but minimum required was 101 CKB (53 bytes lock script + 8 bytes capacity + 40 bytes data).
Solution
Increased capacity to 110 CKB to provide headroom:
const ANCHOR_CAPACITY = BigInt("11000000000"); // 110 CKB in shannons
Applied To
Issue 3: Production Build TypeScript Errors
Date: February 17, 2026
Problem
error TS1470: The 'import.meta' meta-property is not allowed in CommonJS output
error TS2339: Property 'SECP256K1_BLAKE160_SIGHASH_ALL' does not exist
Root Cause
-
import.meta.url not compatible with Koyeb’s buildpack
-
Invalid Lumos script type fallback
-
Wrong TypeScript module configuration
Solution
-
Replaced import.meta.url with process.cwd() in registry.ts
-
Removed non-existent SECP256K1_BLAKE160_SIGHASH_ALL fallback
-
Updated tsconfig.json:
{ "module": "ESNext", "moduleResolution": "Bundler"}
-
Moved build dependencies from devDependencies to dependencies
Deployment Context
These fixes were necessary for server-based deployments (Koyeb, Render, Railway). The serverless version on Vercel had different requirements, leading to Issue 4.
Issue 4: Free Hosting Service Requirements
Date: February 17, 2026
Problem
All major free server hosting providers required credit cards, even for free tiers.
Services Attempted (Traditional Server Hosting)
-
Koyeb
- Required credit card after initial trial
-
Render
- Required credit card for signup
-
Railway
- Required credit card upfront
-
Cyclic, Fl0, Adaptable
- Services shut down or unreliable
Decision Point: Server vs Serverless
This obstacle led to a critical architecture decision:
Option A: Continue with Express Server
-
Pros: Familiar architecture, full control, works on any VPS
-
Cons: Requires paid hosting or own infrastructure
-
Best for: Enterprise, self-hosting, long-term projects with budget
Option B: Migrate to Serverless
-
Pros: Free tier available (Vercel), zero maintenance, auto-scaling
-
Cons: Different architecture, learning curve
-
Best for: Demos, MVPs, open-source projects
Solution Chosen
Primary: Vercel Serverless (no credit card required)
-
No credit card required
-
Already had Vercel account for frontend
-
Generous free tier (100GB bandwidth, 100k invocations)
-
No cold starts with edge deployment
-
Built-in CORS and routing
Secondary: Kept Express Backend for users who prefer traditional servers
-
Maintained backend/ folder with Express implementation
-
Both use same CKB service logic
-
Users can self-host on their own VPS/Docker
Result
Dual deployment support:
Issue 5: Vercel Serverless Architecture Conversion
Date: February 27-28, 2026
Problem
Express.js backend incompatible with Vercel’s serverless architecture.
Challenges
-
Monolithic Express app → Split into individual serverless functions
-
Shared service code → Initially in separate /services directory
-
ESM import paths → Required .js extensions in Vercel
-
Module resolution → Different path behavior in serverless context
Solution
Created new api-backend/ directory with serverless structure:
api-backend/
├── api/
│ └── hashes/
│ ├── index.ts # POST handler (replaces Express route)
│ ├── [hash].ts # GET handler (replaces Express route)
│ └── ckb.service.ts # Shared CKB logic
└── vercel.json # Function configuration
Key architectural changes:
Code comparison:
Express (backend/src/controllers/hash.controller.ts):
export const submitHash = async (req: Request, res: Response) => {
const result = await ckbService.submitHash(req.body);
res.json(result);
};
Serverless (api-backend/api/hashes/index.ts):
export default async function handler(req: VercelRequest, res: VercelResponse) {
res.setHeader('Access-Control-Allow-Origin', process.env.CORS_ORIGIN || '*');
const result = await ckbService.submitHash(req.body);
res.json(result);
}
Why Keep Both?
-
Serverless: Production deployment (free, scalable, zero maintenance)
-
Express: Development, self-hosting, enterprise deployments
Issue 6: CCC API Type Mismatches
Date: February 28, 2026
Problem Series
Multiple TypeScript errors with CCC’s type system in serverless version only (Express version worked fine).
6a. Script Parameter Type
error TS2345: Argument of type 'string' is not assignable to parameter of type 'ScriptLike'
Solution: Used type assertion (this.client.findCellsByLock as any) to bypass strict typing
6b. Missing Properties
error TS2339: Property 'address' does not exist on type 'Address'
error TS2339: Property 'blockNumber' does not exist on type 'Cell'
Solution:
6c. findCellsByLock Crashes
Cannot read properties of undefined (reading 'startsWith')
at bytesFrom in CCC library
Root Cause: addressObj.script had undefined fields that CCC couldn’t parse in serverless environment
Final Solution: Switched from findCellsByLock to findTransactions:
// Old approach (failed in serverless)
const cellIterator = this.client.findCellsByLock(addressObj.script, "asc");
// New approach (works everywhere)
const address = await signer.getRecommendedAddress();
for await (const tx of this.client.findTransactions(address)) {
const txWithStatus = await this.client.getTransaction(tx.txHash);
// Check transaction.outputsData
}
Why Only Serverless?
The Express version didn’t hit these issues because:
-
Different Node.js version in Vercel’s runtime
-
Different module resolution behavior
-
Different CCC type definitions loaded
Applied To
Issue 7: Vercel Deployment Cache
Date: February 28, 2026
Problem
Updated code wasn’t deploying - Vercel kept using cached builds even after git push.
Symptoms
-
Git showed correct code locally
-
Vercel Source tab showed old code
-
Runtime errors referenced old line numbers
Solutions Attempted
-
Empty commit: git commit --allow-empty -m "force rebuild"
-
Clear build cache in Vercel UI
-
Delete and recreate Vercel project
-
Install command changes - didn’t help
Final Resolution
Deleted Vercel project and recreated from scratch, ensuring:
-
Correct root directory set to api-backend
-
Environment variables added before first deployment
-
No existing build cache to interfere
Lesson for Express Users
Traditional server deployments (PM2, Docker, systemd) don’t have this caching issue - one advantage of self-hosting with direct deployment control.
Issue 8: Cell Data Verification
Date: February 28, 2026
Problem
Cannot read properties of undefined (reading 'startsWith')
in verifyHash function
Root Cause
cell.outputData could be undefined but code didn’t check before calling .includes()
Solution
Added null check:
const cellData = cell.outputData;
if (!cellData) {
console.log('[CKB] Cell has no outputData, skipping');
continue;
}
if (cellData.includes(cleanSearchHash)) {
// Process match
}
Applied To
Lessons Learned
Technical
-
Serverless != Traditional Backend - Different mental model for state, imports, and execution
-
CCC > Lumos for new projects - Better API, concurrency, and support (benefits both architectures)
-
Type assertions sometimes necessary - CCC types still evolving, pragmatic as any acceptable
-
Test locally before production - Vercel CLI’s vercel dev crucial for serverless debugging
-
ESM in serverless needs .js extensions - Node resolution rules different in Vercel vs traditional servers
-
Keep both options available - Serverless for demos, Express for enterprise
Process
-
Free tier landscape changed - Most traditional hosts now require cards
-
Delete > Debug for cache issues - Sometimes faster to recreate than troubleshoot (serverless)
-
Incremental debugging wins - Add logging, deploy, test, repeat
-
Committee feedback valuable - Concurrency issue caught by reviewers, not dev testing
Architecture Decisions
When to Use Serverless (Vercel):
Public demos and MVPs
Open-source projects
No budget for hosting
Want zero maintenance
Need auto-scaling
When to Use Express Server:
Enterprise deployments
Need full infrastructure control
Existing VPS/Docker setup
Compliance requirements
High-traffic production apps
Best Practice: Maintain both! They share 90% of the code (CKB service logic), only HTTP layer differs.
Architecture Comparison
| Aspect |
Serverless (Vercel) |
Express Server |
| Deployment |
Git push → auto-deploy |
Manual deploy/PM2/Docker |
| Scaling |
Automatic |
Manual/cluster mode |
| Cost |
Free tier (100k requests) |
VPS: $5-50/month |
| Maintenance |
Zero |
OS updates, security |
| Debugging |
Vercel logs |
Direct SSH access |
| Concurrency |
Parallel functions |
Node cluster/workers |
| Cold Starts |
None (edge network) |
N/A |
| File Storage |
Ephemeral |
Persistent disk |
| WebSockets |
Not supported |
Fully supported |
| Long Requests |
10s timeout |
No timeout |
Final Status:
RESOLVED
All issues resolved across both deployment options:
Serverless (Production)
-
Submission:
Working - transactions confirmed on CKB testnet
-
Verification:
Working - hashes retrieved from blockchain
-
Performance: <2s response times, no cold starts
-
Reliability: No concurrency conflicts with CCC
-
Cost: $0/month on Vercel free tier
Express (Self-Hosting)
-
Submission:
Working - identical CKB logic
-
Verification:
Working - same search algorithm
-
Performance: <500ms response times (VPS dependent)
-
Reliability: Stable with PM2/Docker
-
Cost: VPS cost (~$5-20/month)
Live URLs:
Recommendation for New Deployments
Start with Serverless (Vercel):
-
Free to deploy and test
-
Zero maintenance overhead
-
Perfect for demos and MVPs
-
Easy to migrate to Express later if needed
Migrate to Express when:
-
Need WebSocket support
-
Require >10s request processing
-
Have compliance/security requirements
-
Want full infrastructure control
-
Already have VPS infrastructure
The code is portable - both versions share the same CKB service logic, making migration straightforward in either direction.