Doginals, collections, Doge Names
Doge Soft Art marketplace
Buy, sell, offer and auction Doginals and Doge Names with wallet-signed PSBTs: the trade layout, who signs what, auctions, fees and the API.
Doge Soft Art is the Doginals marketplace for the whole orbit: every collection the explorer
indexes, every Doge Name, and any single inscription. Buy now, offers on anything (listed or not) and
self-settling auctions. It lives at diggydoge.com
and art.dogesoft.io. Doge Soft never holds a key: every trade is one Dogecoin
transaction that both sides sign in their own wallet.
The problem it removes: "send the DOGE first, I'll send the Doginal right after." With a signed trade there is nobody to trust. The transaction either happens exactly as both sides signed it, or it doesn't happen at all.
What you can trade
- Collections. All collections in the explorer index, with floor, listed count and volume per collection.
- Doge Names. Names are inscriptions, so a
.dogename sells like any Doginal. Unregistered names link to Doge Names. - Any Doginal. Paste an inscription id into search. Images, HTML (sandboxed), video and text render inline.
DRC-20 Coins trade on Soft Swap, not here.
The trade transaction
Every buy, accepted offer and auction settlement has the same shape:
| # | Input | Output |
|---|---|---|
| 0 | Buyer's dummy coin (0.01–0.1 DOGE) | Buyer receives dummy + carrier, so the Doginal lands here |
| 1 | Seller's inscription carrier | Seller's price (auctions: the reserve) |
| 2… | Buyer's payment coins | Auction extra (bid − reserve) to the seller, the 1% buyer fee, the buyer's fresh 0.01 DOGE dummy, buyer change, then a 0-value Doge Soft tag |
The explorer routes inscriptions first-in-first-out by sat. With the buyer's dummy first and output 0 sized at dummy + carrier, every sat of the carrier (wherever the inscription sits inside it) lands in the buyer's output 0. The server re-runs that routing check before anything is broadcast. The Doge Soft tag is a 0-value output after the seller is paid, so it does not move the Doginal or change the seller's signed output. The verbs are in the inscription standard.
Who signs what
| Action | Signer | Inputs | Sighash |
|---|---|---|---|
| List / start auction | Seller | 1 | 0x83 SINGLE|ANYONECANPAY |
| Buy now | Buyer | 0, 2… | 0x01 ALL |
| Make offer / place bid | Buyer | 0, 2… | 0x01 ALL, bound to the full trade |
| Accept offer | Seller | 1 | 0x01 ALL |
| Wallet prep (once) | Buyer | all | 0x01 ALL |
Note the seller's input index: 1, not 0. SIGHASH_SINGLE pairs input 1 with output 1, which leaves index 0 free for the buyer's dummy. A listing signed at index 0 would route the Doginal into the seller's own payment output.
Trust model
- Offers and bids are signed SIGHASH_ALL over the exact trade: exact inputs (including the seller's carrier) and exact outputs. If one leaked, the only thing anyone could do with it is complete that exact trade, which still needs the holder's signature.
- Listings and auction reserves are SIGHASH_SINGLE|ANYONECANPAY: they authorize "this Doginal for this price, paid to me." Doge Soft Art keeps them server-side and never sends them to a browser. Buyers sign a copy without the seller's signature and the server joins the two.
- Delist deletes the stored signature (one
signMessage, free). To make an old listing provably dead, send the Doginal to yourself: the signature then points at a spent coin. - Moved = cancelled. A monitor checks every listed carrier each 30 seconds. If the Doginal moves anywhere, its listing, offers and bids are voided and their signatures are wiped.
- Before broadcast the server checks the wallet returned our exact unsigned transaction, verifies every signature against its own sighash, checks the signer owns each input, and re-runs sat routing. A tampered PSBT is refused.
Auctions
- The seller sets a reserve and a clock (1 hour to 7 days) and signs the reserve once.
- The first bid can be the reserve. Each next bid must be at least 1 DOGE or 5% above the top bid, whichever is larger.
- A bid in the last 5 minutes pushes the end out to 5 minutes from that bid.
- At zero the top bid settles by itself. If its coins were spent, the next-highest bid wins. No bids: the auction closes and nothing moves.
- Bidders keep their DOGE until the hammer. Raising your own bid replaces your old one.
Fees
| What | Who pays | Amount |
|---|---|---|
| Listing, delisting, offers, bids | — | Free |
| Marketplace fee | Buyer | 1% of the price, to DHt93zZn6srZJMLjyqEpcpJBqBnkKCJ9i9. This fee is marketplace policy. It is not part of the inscription standard. |
| Seller fee | — | 0% |
| Network fee | Buyer | 1 DOGE/kB, the house rate for inscription moves (a trade is about 1 kB) |
Safety rules the server enforces
- Only standard D-address (P2PKH) coins.
- A carrier must hold exactly one inscription and at most 0.1 DOGE. Otherwise the seller is asked to send it to themselves first, so a buyer never receives DOGE the seller didn't mean to sell.
- Buyer coins must be inscription-free and DRC-20-free per the explorer, with at least 3 confirmations. The exception is change and dummy coins from trades Doge Soft Art built itself, which can chain before they confirm.
- Coins promised to one of your open offers or bids aren't reused for another.
- Prices from 1 DOGE, two decimals.
Integrate: the API
Every flow is prepare → sign in the wallet → submit. Prepare returns a hex PSBT plus the exact
inputToSign list to pass to the wallet. Submit takes what the wallet returns.
const ART = "https://diggydoge.com/api";
const [buyer] = (await dogesoft.connect()).accounts;
// 1. The server builds the exact trade.
const prep = await post(`${ART}/buy/prepare`, { listingId, buyer });
// prep.summary = { price, platformFee, networkFee, total, ... }
// 409 { code: "need_dummy" } → run prep/prepare + prep/submit once, then retry.
// 2. The buyer reviews every output in the wallet and signs their inputs.
const signed = await dogesoft.signPsbt(prep.psbt, { inputToSign: prep.sign });
// 3. The server verifies, joins the seller's signature and broadcasts.
const { txid } = await post(`${ART}/buy/submit`, { draftId: prep.draftId, psbt: signed.psbtHex });
| Endpoint | Body | Notes |
|---|---|---|
POST /api/list/prepare | inscriptionId, seller, price, kind: "fixed"|"auction", durationMinutes | Seller signs input 1 with 0x83 |
POST /api/buy/prepare | listingId, buyer | Buy now |
POST /api/offer/prepare | inscriptionId, buyer, amount, days | Any indexed inscription |
POST /api/accept/prepare | offerId, seller | Holder only |
POST /api/bid/prepare | auctionId, bidder, amount | Returns endsAt after anti-snipe |
POST /api/prep/prepare | address | One-time: two 0.01 DOGE dummies |
POST /api/<flow>/submit | draftId, psbt | Drafts expire after 15 minutes |
POST /api/delist, /api/offer/cancel | listingId|offerId, ts, signature | signMessage of the text below |
GET /api/listings | ?collection= &kind= &sort=new|low|high|ending | Live listings and auctions |
GET /api/item/:inscriptionId | — | Listing, offers, bids, activity |
GET /api/collections, /api/collections/:slug/items | ?offset= &filter=listed | Collections with floor, listed, volume |
GET /api/activity, /api/stats, /api/wallet/:address | — | Feed, totals, holdings |
Doge Soft Art
Delist <listingId> (or: Cancel offer <offerId>)
Time: <unix seconds>
Signing moves no coins.
A signed message is valid for 10 minutes and works once.
Status
Beta Live on mainnet since 2026-10-15. The full flow (prep, list,
buy, offer and accept, auction with anti-snipe and fallback, delist, moved-voids-listing) passes end to end on
a Dogecoin Core 1.14.7 regtest chain, signed by the extension's own signGenericPsbt.
Mainnet PSBT building is checked against live chain data. A listing, offer, bid or cancel stays a signed record.
The sale transaction carries one tag from the
inscription standard:
BUY, AUCTION_SOLD,
OFFER_ACCEPT, GIFT,
BUNDLE, PARTIAL_FILL or
COLLECTION_TRANSFER.