Get started
What Origin is
Origin lets a DogeOS app ask Dogecoin a question and use the answer. Does this wallet hold the coin? Does it own a Doginal from this collection? Did this payment confirm?
DogeSoft already indexes every Dogecoin block: DOGE, UTXOs, inscriptions, Doginals, collections and the full DRC-20 ledger. Origin puts that on one front door. You can search it, read it from your server, or use it from a DogeOS contract. When you need to write back to Dogecoin, Origin hands you the request, and your user’s wallet signs it.
Get started
Quickstart
Three ways in. Use whichever matches where you are.
1. No code
Go to ø.co, paste a Dogecoin address and type DU$T balance. You get the answer, where it came from, and your plugs.
2. From your server or frontend
Every fact Origin shows can be read straight from the public DogeSoft API. No key needed.
curl -s 'https://explorer.dogesoft.io/api/wallet/address/DPXjXNN2oiY8UWdGK1U5PgwK6ZV8cstn1s/drc20'{
"address": "DPXjXNN2oiY8UWdGK1U5PgwK6ZV8cstn1s",
"balances": [
{ "tick": "DU$T", "balance": "6969", "available": "6969.0", "transferable": "0.0", "decimals": 18 }
]
}3. From a DogeOS contract
Your contract calls Origin, Origin returns the fact. One address, one interface.
interface IOrigin {
function drc20Balance(string calldata dogeAddress, string calldata tick)
external view returns (uint256 amount, uint64 l1Height, uint64 attestedAt);
}
contract HoldersOnly {
IOrigin public immutable origin;
constructor(IOrigin origin_) { origin = origin_; }
function canEnter(string calldata dogeAddress) external view returns (bool) {
(uint256 amount, , uint64 attestedAt) = origin.drc20Balance(dogeAddress, "DU$T");
require(block.timestamp - attestedAt <= 1 hours, "stale");
return amount >= 1_000_000 * 1e18;
}
}Get started
What’s live today
We only call something live when you can use it right now.
| Piece | State | Where |
|---|---|---|
| Search and guided paths | Live | ø.co · origin.dogesoft.io |
| Read API (balances, Doginals, collections, txs) | Live | explorer.dogesoft.io/api |
| Write paths (send a coin, move a Doginal) | Live | inscriber.dogesoft.io |
| Origin, OriginInscriber, OriginPlugs contracts | Final ABI · not deployed | ABI explorer · DogeOS testnet next |
| Built on Origin badge | Live | See badge |
| Signed facts (attestations) | Building | origin-attester |
| Origin Proof | Planned | See Origin Proof |
| OP_CHECKZKP shadow indexing | Planned | See OP_CHECKZKP |
DogeOS itself is still on testnet: Chikyū, chain id 6281971, RPC https://rpc.testnet.dogeos.com.
Get started
Plugs and earning
A plug is one reusable piece of a Dogecoin-powered build. “Holders of this coin get in.” “This Doginal is a playable character.”
- Origin Plugs: the marketplace. Every plug and build, with code generated from the real Origin ABI.
- Origin Plugs: build your own plug, list it on the marketplace, and browse the ABI explorer.
- Search on ø.co answers with plugs. Type what you’re building.
How the money moves
| 99% | of every plug license sale goes to the creator. |
| 1% | platform fee to DogeSoft, fixed in the OriginPlugs contract. |
| Fact fees | dApps can pay Origin.requestFact for a fresh fact on demand. The plug named in the request earns a share (20% today, capped at 50%). The rest funds attesters and the treasury. |
| Free | reading facts on DogeOS. View calls never cost anything. |
Origin and OriginPlugs are compiled with their final interfaces but not deployed. The marketplace opens when they are.Dogecoin basics
UTXOs in one minute
Dogecoin doesn’t store account balances. It stores coins sitting in outputs.
Every transaction spends some earlier outputs and creates new ones. An output nobody has spent yet is a UTXO (unspent transaction output). A wallet’s DOGE balance is the sum of the UTXOs it can spend.
An output is named by the transaction that created it plus its position: txid:vout. That pair is an outpoint. You’ll see outpoints a lot, because inscriptions live on them.
balanceOf on Dogecoin. Think of a wallet as a purse of exact bills. Paying means handing over whole bills and getting change back as a new bill.Dogecoin basics
Inscriptions and Doginals
An inscription is data written into a Dogecoin transaction. A Doginal is a one-of-a-kind inscription, collected like an NFT.
The data (an image, text, JSON, HTML, audio, video) sits inside an envelope in the transaction. It gets an id like <txid>i0. The inscription then rides on a small output called the carrier. Whoever holds the carrier UTXO owns the inscription. To move it, you spend that output to someone else.
Collections aren’t a chain object. DogeSoft keeps a registry of which inscriptions belong to which collection (298 at last count), and Origin uses it to answer “does this wallet own one of these?”.
contentHash.Dogecoin basics
DRC-20 coins
DRC-20 coins are written on Dogecoin with plain-text inscriptions. No contract is involved.
A coin is deployed, minted and moved by inscribing small JSON bodies like {"p":"drc-20","op":"transfer","tick":"DU$T","amt":"10"}. An indexer replays every block to keep the ledger.
Sending a coin is two steps:
- Inscribe the transfer to your own address. That amount becomes transferable, meaning locked inside that inscription.
- Move the inscription to the recipient. When the move confirms, the ledger debits you and credits them.
That’s why a balance has three numbers. Balance is the total. Available is free to inscribe. Transferable is locked in transfer inscriptions that haven’t moved yet.
DU$T is not DUST). The only transform DogeSoft applies is lowercase with control characters removed. Amounts in Origin return values are base units: amount × 10^decimals.Dogecoin basics
Confirmations
A transaction is confirmed once it’s in a block. Each block after that adds a confirmation.
Dogecoin makes a block about every minute. Six confirmations is a common bar for “this won’t change”. Origin defaults to six for payments, and you can ask for more.
DRC-20 is one step behind: the ledger can only settle a block once the DogeSoft indexer has processed it. Origin reports the height the ledger is indexed to, and answers pending for anything newer.
Dogecoin basics
Words we use
| Coin | A DRC-20 asset. We say coin, not token. It’s inscribed on L1, not issued by a contract. |
| Doginal | A one-of-a-kind inscription. |
| Koinu | Smallest DOGE unit. 1 DOGE = 100,000,000 koinu. |
| Fee | Dogecoin charges per byte. There’s no gas. |
| Commit / reveal | The two transactions that write an inscription. |
| Move | The transaction that hands an inscription to its recipient. |
| Fact | One thing Origin can tell you, e.g. a coin balance at a block height. |
| L1 / L2 | Dogecoin mainnet / DogeOS. |
Guide
Reward holders of a coin
Only let people in, airdrop, or unlock a feature if their Dogecoin wallet holds enough of a coin.
- On Origin, choose I have a coin → Let DogeOS apps reward my holders, or Building an app → A wallet holds a coin.
- Enter the ticker, a wallet to test with, and the minimum.
- Copy plug 01 to check it from your server today, or plug 02 for your contract.
const res = await fetch(`https://explorer.dogesoft.io/api/wallet/address/${addr}/drc20`);
const { balances } = await res.json();
const dust = balances.find((b) => b.tick.toLowerCase() === 'du$t');
const ok = Number(dust?.balance ?? 0) >= 1_000_000;window.dogesoft.signMessage on your site, and check the signature on your server.Guide
Reward holders of a collection
“Does this wallet own at least one DU$TINAL DOG?”
- Choose I have Doginals → Let DogeOS apps reward my holders.
- Start typing the collection name. The list fills from DogeSoft’s registry.
- Origin counts the Doginals that wallet holds right now and confirms each one against the registry.
The Origin call is collectionCount(dogeAddress, collectionId). Collection ids are slugs like dustinal-dogs.
Guide
Verify a coin transfer
Paste a txid and ask “was this DRC-20 transfer valid?”.
Origin uses the same rules as the DogeSoft Bridge. A transfer is valid only when the move settled on the ledger and wasn’t settled by a manual repair or sweep. If the indexer hasn’t reached that block yet, the answer is pending, never yes.
curl -s 'https://explorer.dogesoft.io/api/explorer/tx/06f8c5cc6c54e94045db7b0fe2ee82f4d95dc8b12a4fcf3d4d5eb85d0d7450ed'
# look at drc20_operations[].data.ledger_settled and .settle_reasonGuide
Confirm a DOGE payment
Ship the order once the payment has enough confirmations.
const tx = await fetch(`https://explorer.dogesoft.io/api/tx/${txid}`).then((r) => r.json());
const paid = tx.confirmations >= 6;On DogeOS the call is txConfirmed(txid, minConfirmations). The txid is passed as bytes32, written exactly as explorers display it. See Encoding rules.
Guide
Check an inscription is real
Paste an inscription id (…i0). Origin tells you whether DogeSoft parsed it from chain, which envelope it uses, its content hash, where it was born and who holds it.
DogeSoft v1 envelope means it carries a registered ACTION tag. Legacy Doginal means a valid inscription made before the standard. Both are real. The label tells you which rules it was written under.
Guide
Send a coin
Move DRC-20 coins with the DogeSoft standard. The user signs. Nobody else holds their keys.
- Check. Origin confirms the sender has enough available balance first.
- Build.
POST /drc20-transfer-draft. DogeSoft pays for and broadcasts the transfer inscription to the sender’s address, using the standard envelope. - Sign the move. Spend the carrier (reveal output 0) and the fee float (output 1) to the recipient.
- Broadcast. The DogeSoft wallet’s
pushPsbtdoes it for you. Otherwise usePOST /broadcast.
curl -s -X POST 'https://inscriber.dogesoft.io/drc20-transfer-draft' \
-H 'content-type: application/json' \
-d '{"from_address":"D…sender","recipient":"D…recipient","tick":"DU$T","amount":"10"}'const prev = Buffer.from(draft.reveal_raw_hex, 'hex');
const psbt = new bitcoin.Psbt({ network: dogecoin });
psbt.addInput({ hash: draft.reveal_txid, index: 0, nonWitnessUtxo: prev });
psbt.addInput({ hash: draft.reveal_txid, index: draft.fee_float_vout, nonWitnessUtxo: prev });
psbt.addOutput({ address: recipient, value: draft.dust_koinu });
await window.dogesoft.connect();
const { psbtHex } = await window.dogesoft.signPsbt(psbt.toHex(), { autoFinalize: true });
const { txid } = await window.dogesoft.pushPsbt(psbtHex);Guide
Move a Doginal
No new inscription is needed. You spend the output it sits on.
curl -s -X POST 'https://inscriber.dogesoft.io/prepare' \
-H 'content-type: application/json' \
-d '{"flow":"doginal_send","inscription_outpoint":"<txid>:<vout>","from_address":"D…owner","recipient":"D…to"}'const unsignedHex = [...atob(draft.psbt_base64)]
.map((c) => c.charCodeAt(0).toString(16).padStart(2, '0')).join('');
await window.dogesoft.connect();
const { psbtHex } = await window.dogesoft.signPsbt(unsignedHex, { autoFinalize: true });
const { txid } = await window.dogesoft.pushPsbt(psbtHex);Don’t know the outpoint? Origin’s Move a Doginal path looks it up live from the inscription id.
Guide
Inscribe from DogeOS
Your DogeOS contract writes a real inscription to Dogecoin, using the DogeSoft Inscription Standard.
- Request. Your contract calls
OriginInscriber.requestInscription(action, contentType, metadata, payload, dogeRecipient, plugId)and pays the fee in DOGE. The exact envelope is committed on-chain asenvelopeHash. - Inscribe. DogeSoft writes it to Dogecoin with the standard envelope, straight to the recipient’s Dogecoin address.
- Receipt. Attesters post a signed receipt. It is accepted only if the inscription on Dogecoin hashes to the same envelope, with enough confirmations, and a reveal output that was never used before.
- Done. Your contract can get a callback (
onInscribed). If nothing lands before the timeout, the requester reclaims the fee.
bytes memory body = inscriber.launchpadMintBody("dustinal-dogs", id, "777");
uint256 fee = inscriber.previewFee("LAUNCHPAD_MINT", body.length);
(uint256 requestId, bytes32 envelopeHash) = inscriber.requestInscription{value: fee}(
"LAUNCHPAD_MINT", "application/json", new bytes[](0), body, dogeAddress, PLUG_ID
);
// later, anyone can confirm what landed is exactly this:
bool exact = origin.inscriptionMatches(inscriptionId, envelopeHash);launchpadMintBody and drc20TransferBody produce the standard JSON byte-for-byte, and encodeEnvelope shows the exact bytes that go to Dogecoin.envelopeHash = keccak256(OP_FALSE OP_IF "ord" OP_1 <content-type> [<ACTION> <metadata>…] OP_0 <payload in 520-byte pushes> OP_ENDIF). ACTION and metadata are omitted for text/plain DRC-20 bodies, exactly like the Inscriber. The same encoder ships in JavaScript (/shared/js/envelope.js) and is tested byte-for-byte against the contract.Guide
Built on Origin badge
Show users your Dogecoin data is verified by DogeSoft’s Origin. One line.
<script src="https://origin.dogesoft.io/shared/badge/origin-badge.js" defer></script>
<origin-badge plug="collection-holder-gate"></origin-badge>Attributes: plug (links to that plug’s page on Origin Plugs), variant="mark" (logo only), theme="light", size="sm", floating (pinned bottom-right).
[](https://plugs.dogesoft.io)Every plug page on Origin Plugs, every finished build on Origin and the Plugs studio hands you this snippet with your plug filled in.
Reference
Read API
Base: https://explorer.dogesoft.io/api. GET, public, JSON. These are the endpoints Origin itself reads.
| Endpoint | Gives you |
|---|---|
/health | Indexed height, chain tip, DRC-20 ledger height, staleness |
/wallet/address/{addr}/balance | DOGE balance in koinu, UTXO count |
/wallet/address/{addr}/utxos | UTXOs and the inscriptions sitting on them |
/wallet/address/{addr}/drc20 | Coin balances: balance, available, transferable |
/wallet/address/{addr}/history | Recent confirmed activity |
/tx/{txid} | Confirmations, mempool flag, raw hex |
/explorer/tx/{txid} | Decoded DRC-20 operations and inscriptions |
/explorer/drc20/{tick} | Coin deploy, supply, holders |
/explorer/inscriptions/{id} | Owner, location, genesis, content hash, collections |
/content/{id} | The content, reassembled from chain (no /api prefix) |
/explorer/collections | Collections (max 200 per page, use offset) |
/explorer/collections/{id}/items | Items in a collection |
du%24t). The decoded-tx endpoint can take several seconds on busy transactions, so cache what you can.Reference
Origin contract Draft
One entry point on DogeOS. Every method is a view, and every answer carries the L1 height it was true at.
The full, compiled interface lives in the ABI explorer (download: Origin.json, OriginPlugs.json). The calls you’ll use most:
function drc20Balance(string calldata dogeAddress, string calldata tick)
external view returns (uint256 amount, uint64 l1Height, uint64 attestedAt);
function collectionCount(string calldata dogeAddress, string calldata collectionId)
external view returns (uint256 count, uint64 l1Height, uint64 attestedAt);
function isInscriptionOwner(string calldata inscriptionId, string calldata dogeAddress)
external view returns (bool);
function inscriptionValid(string calldata inscriptionId)
external view returns (bool ok, bytes32 contentHash, uint64 l1Height);
function drc20Supply(string calldata tick)
external view returns (uint256 minted, uint256 maxSupply, uint64 l1Height);
function txConfirmed(bytes32 txid, uint256 minConfirmations)
external view returns (bool ok, uint64 l1Height);
function drc20TransferValid(bytes32 txid) external view returns (bool ok, uint64 l1Height);
function isLinked(address account, string calldata dogeAddress) external view returns (bool);
function inscriptionHasAction(string calldata inscriptionId, string calldata action) external view returns (bool);
function inscriptionMatches(string calldata inscriptionId, bytes32 envelopeHash) external view returns (bool);
function check(bytes32 factType, bytes32 subject, bytes32 key, uint8 op, uint256 threshold, uint64 maxAge)
external view returns (bool);
function requestFact(bytes32 factType, bytes32 subject, bytes32 key, uint256 plugId)
external payable returns (uint256 requestId);Fact types
| Fact | Value |
|---|---|
DOGE_BALANCE | koinu |
DRC20_BALANCE | base units (amount × 10^decimals) |
COLLECTION_COUNT | Doginals held from one collection |
INSCRIPTION_OWNER | keccak256(bytes(ownerAddress)) |
INSCRIPTION_VALID | bool + SHA-256 of content |
TX_CONFIRMED | bool |
DRC20_TRANSFER_VALID | bool |
Freshness
Facts are snapshots. Check attestedAt (or l1Height) against your own limit, e.g. one hour for a gate, and reject anything older.
Reference
Encoding rules
| Thing | How Origin encodes it |
|---|---|
| Dogecoin address | Passed as string. Hashed as keccak256(bytes(addr)), case-sensitive. |
| Ticker | Passed as string, exact. Keyed by keccak256(lowercase(tick)). |
| Inscription id | string like <txid>i0. Keyed by keccak256(lowercase(id)). |
| Collection | Slug string, e.g. dustinal-dogs. |
| txid | bytes32 = 0x + the txid as explorers display it (no byte reversal). |
| Amounts | uint256 base units. DOGE in koinu. |
Reference
Inscriber API
Base: https://inscriber.dogesoft.io. Builds transactions for the user to sign. It never asks for keys.
| Endpoint | Does |
|---|---|
GET /standard | The live inscription standard: envelope and registered actions |
POST /prepare | flow: doge_send, doginal_send or drc20_transfer. Returns psbt_base64 + unsigned_tx_hex. |
POST /drc20-transfer-draft | Balance-checked. Inscribes the transfer to the sender and returns the reveal to move. |
POST /broadcast | {"signed_tx_hex": "…"} |
Reference
Inscription standard
Every DogeSoft inscription is an ord envelope. The spec id is dogesoft_inscription_v1.
OP_FALSE OP_IF "ord"
OP_1 [content-type]
[ACTION] // omitted for DRC-20 text/plain
OP_0 [payload]
OP_ENDIFDRC-20 bodies use the plain positional envelope, byte for byte, so every Dogecoin indexer can read them. Other actions add a registered ACTION tag: TRANSFER, SWAP, ADD_LP, LIST, BUY, LAUNCHPAD_MINT, BRIDGE_L1_DEPOSIT and more. The full list is live at GET /standard. The complete spec is on DogeSoft docs.
Reference
Answers and failures
| Answer | Means |
|---|---|
| ✓ Yes | True on L1 at the stated height, under DogeSoft’s rules. |
| ✕ No | Checked, and not true. |
| … Pending | Not decided yet: too few confirmations, or the DRC-20 ledger hasn’t reached that block. |
| Ø Info | Context, not a yes/no fact. |
Origin fails closed. When data is ambiguous, missing or slow, it doesn’t guess. It says so.
Trust and roadmap
Trust model
- Source of truth: the DogeSoft indexer, replaying every Dogecoin block.
- On DogeOS: facts will be signed by Origin attesters. Their keys are separate from the Bridge’s, and at least 2-of-3 must sign before anything of value relies on them.
- Writes: always signed by the user’s wallet. Origin never holds keys.
- AI: when the assistant arrives, it only turns your words into a query. The answer always comes from DogeSoft’s deterministic index.
- Domains: ø.co is branding. Nothing on-chain or in the APIs depends on it.
Trust and roadmap
Origin Proof Planned
Prove something about a wallet’s Dogecoin history without showing all of it.
Examples: active for more than two years, used on 100 different days, held a Doginal from a collection since 2024, has created coins. These are activity and Sybil-resistance signals, not identity. A wallet is not a person, and Proof will never claim it is. No KYC, no names, no documents.
Trust and roadmap
OP_CHECKZKP Planned
A draft Dogecoin soft fork (discussion #3869) that would let scripts verify zero-knowledge proofs.
It redefines OP_NOP10 (0xB9) as OP_CHECKZKP, with a Groth16 / BLS12-381 mode and a Halo2-KZG / BN256 mode. It isn’t activated, and Dogecoin Core hasn’t agreed to it.
DogeSoft plans to index it in shadow mode. That means detecting every use from the first block, checking the proofs, and labelling them not consensus-enforced until activation. If it activates, the full history is already there, and Origin can treat a verified proof as a native L1 fact.
Trust and roadmap
FAQ
Do I need an API key?
No. Reads are public and rate-limited.
Does it cost anything?
Reading is free. Writing to Dogecoin costs the normal network fee.
Is there a Dogecoin testnet?
Origin reads Dogecoin mainnet. DogeOS is on testnet (Chikyū) today.
Why does a balance show “transferable”?
Those coins are locked inside a transfer inscription that hasn’t moved yet. See DRC-20 coins.
Can Origin move coins for my users?
No. It builds the request; the user’s wallet signs it.
Something looks wrong.
Every answer links to the raw record it came from. Send that link to DogeSoft.