One invoice. One lender. Ever.
Selo is a public registry of invoices on Solana. Lenders check an invoice before they finance it. If another lender already did, the second lock is rejected on-chain.
- No personal data on-chain
- Open-source SDK
- Confirms in under a second
- SealedSealed and attestedSupplier sealed it, verified buyer confirmed it is due
- FinancedLender A locks it09 Oct 2026 · 1 USDC-dev fee
- Lender B tries to lock itRejected by the Selo programAlready financed by Lender A on 09 Oct 2026. It cannot be financed twice.
- Global factoring volume in 2025 (FCI)
- €4.04T
- To confirm a lock on Solana
- < 1 s
- Record per invoice, however it is typed
- 1
- Names or documents stored on-chain
- 0
The problem
Lenders who finance invoices cannot see each other
A supplier can pledge the same invoice to two lenders, or invent one and finance it several times. In the First Brands collapse, prosecutors allege fake invoices and collateral pledged two or three times over, with billions lost by creditors.
How it works
Four moments, each a Solana transaction
Each one confirms in under a second. Try them in order with the demo wallets.
- 1SupplierSeals the invoice
The invoice becomes a canonical hash in the browser. Only the hash, amount, currency and due date go on-chain.
- 2Verified buyerAttests it is real
The company that owes the invoice confirms it is real and due. Lenders can only finance attested invoices.
- 3Lender AChecks and locks
The registry says the invoice is free. Lender A finances it and locks it, paying a small fee.
- 4Lender BIs rejected
Any other lender trying to lock the same invoice is rejected on-chain and sees who financed it first.
Retyping does not help
Two spellings. One invoice. One hash.
Before hashing, Selo normalizes every field: case, spaces and punctuation in tax IDs and invoice numbers stop mattering. The second registration lands on the same address and fails.
- Supplier
- "DE 811 907 980"
- Buyer
- "US 94-1081436"
- Number
- "INV-2026-0042"
- Amount
- "1250000"
- Currency
- "USD"
- Due
- "2026-12-15"
- Supplier
- "de811907980"
- Buyer
- "us 94 1081436"
- Number
- " inv - 2026 - 0042 "
- Amount
- "1250000"
- Currency
- "usd"
- Due
- "2026-12-15"
Why it holds
Enforced by the program, not by promises
Every rule below is checked on-chain on every transaction. The program is open source and covered by tests for each attack it blocks.
One address per invoice
Tax IDs, number, amount, currency and due date are normalized and hashed. The hash derives the account, so a second copy cannot exist.
Verified buyers
Only a company whose identity was verified can attest, and only for invoices issued against its own tax ID. A fraudster cannot confirm a fake invoice.
First lock wins
Locking is atomic. Once one lender locks an invoice, every other lock fails in the program itself, not in a database someone could edit.
Seals are never closed
Paid or cancelled invoices keep their record forever. Closing one would free the address and let the same invoice be financed again.
Open to every lender
Anyone can read the registry, no account needed. Each lender that checks it makes it more useful for all the others.
Private by design
Company names, tax IDs and documents never leave the parties. Lenders compare hashes, not invoices.
For lenders
One call in your credit flow
Factoring firms and credit protocols add checkInvoice() before they fund. It hashes the invoice locally and reads its record in Selo: free, sealed, financed, closed or cancelled, plus whether its buyer is verified.
import { checkInvoice } from "@selo/sdk";
const check = await checkInvoice(rpc, {
supplierTaxId: "DE 811 907 980",
buyerTaxId: "US 94-1081436",
number: "INV-2026-0042",
amount: 1250000n, // minor units: USD 12,500.00
currency: "USD",
dueDate: "2026-12-15",
});
if (check.status === "locked") {
// Already financed by Lender A on 09 Oct 2026
return decline(check.lender, check.lockedAt);
}A small fee per invoice locked, paid by the lender.
5 basis points of face value. In the demo: 1 USDC-dev.
The fee is far smaller than one double-financing loss, and every new lender makes the registry more valuable.
Privacy
What goes on-chain, and what never does
The invoice hash, face amount, currency, due date, whether the buyer attested, and which lender locked it and when. That is what a lender needs to decide.
Company names, tax IDs, descriptions and documents. They stay with the parties; only their canonical hash is published.
Tax IDs have little entropy, so someone who already knows both parties can test a guess. Selo only catches duplicates among lenders that check it, and a seal does not replace the assignment contract.
Questions
Frequently asked
Is Selo a lender?
No. Selo has no pool, no loans and no token. It is a registry that lenders use before they finance. Factoring firms and on-chain credit protocols are its customers, not its competitors.
Who pays, and how much?
The lender pays a small fee each time it locks an invoice. In the devnet demo it is a fixed 1 USDC-dev; the pricing we assume for production is 5 basis points of face value, which is less than a single loss to a double-pledged invoice.
What if a lender never checks Selo?
Selo only catches duplicates among lenders that check it. That is why its value grows with every lender that joins, and why the check is one line of code with an open-source SDK.
Can someone see my invoices?
On-chain there is only a hash, the amount, the currency and the due date. Tax IDs have little entropy, so someone who already knows both parties could test a guess, but names and documents are never published.
Does a seal replace the assignment contract?
No. The seal proves who locked the invoice first; the legal assignment between supplier and lender still happens off-chain.
Why Solana?
A check is free and a lock costs a fraction of a cent and confirms in under a second. That makes it practical to check every invoice in real time, including small ones.
Check before you finance.
Seal an invoice, attest it, lock it, and watch the second lender get rejected. Real devnet transactions, under a minute.
