Skip to content

fiftyeightandeight/ordyswap

 
 

Repository files navigation

Ordyswap

Trustless atomic swaps between Ordinals and Stacks (STX).

Warning This repo is purely made for demonstration purposes. It has not been audited or even deeply tested. Use at your own risk.

Warning This version of ordyswap should only be used with "Genesis" Ordinals, not Ordinals that have already been transferred.

What is this?

This is a proof-of-concept smart contract that allows anyone to create an "offer" for a specific Ordinal.

By creating an offer, you lock up STX tokens and specify the Bitcoin address where you'd like to receive the Ordinal. If the Ordinal owner sends you the Ordinal, they can claim the STX. There are no trusted custodians involved.

Why?

The Stacks blockchain has a unique capability that no other blockchain or sidechain can do: it can verify a Bitcoin transaction inclusion proof from within a smart contract.

What does that mean?

It means you can write smart contracts on Stacks that allow for special execution to happen if a specific Bitcoin transaction is confirmed on the Bitcoin chain. This happens without oracles - Stacks consensus is built on top of Bitcoin consensus. If Bitcoin forks, Stacks forks too.

You can write smart contracts with logic like "If you send X BTC to Y address, you can have this asset that is currently held in this contract".

For a more complex version of this type of logic, see the magic protocol.

How to use

Installation

It's an NPM package, so install it via your package manager of choice:

npm install -g ordyswap
pnpm add -g ordyswap
yarn global add ordyswap

You can run the CLI as ordyswap.

Create an offer

To create an offer, first find the "Ordinal ID" for the Ordinal you want to buy. From an inscription's page, this is the "Id" property. It's in the format {txid}.{index}. Important if the "output" property doesn't look like the "ID" property (different hash), then pay attention to the "advanced" section at the bottom of this document.

Next, get an Ordinal "receive" address using the ord CLI. Or, follow the instructions for using Sparrow to receive Ordinals.

You'll need a STX account with STX funded in it. Use the Hiro Wallet or XVerse.

To make an offer, run:

ordyswap <ordinalId> <amount> <btcAddress> <recipient>

The arguments are:

  • ordinalId: specified above
  • amount: amount of STX. Can be a float, ie 1.023
  • btcAddress: Your BTC address for receiving Ordinals
  • recipient: The STX address where the owner of the Ordinal will receive STX upon claiming. This means you need to ask for their STX address before making an offer.

In the output will be a big JSON blob containing a transaction payload. Open up https://mechanismhq.github.io/ordyswap and paste in the transaction data. Hit "submit" and your installed wallet will open a popup allowing you to approve and sign your transaction.

After you broadcast your transction, you can find your swap ID in the "result" section of the explorer. If the transaction was successful, you'll see something like (ok u1) - where "1" is the swap ID.

Get offer details

ordyswap get-offer <id>

The id argument is auto-generated by the ordyswap contract - this is not the Ordinal ID.

This command will show you details about the offer, including the BTC receive address.

Send the Ordinal

ord wallet send <btcAddress> <ordinalId>

Finalize the offer

After the transaction sending the Ordinal has 1 confirmation, you can finalize the swap:

ordyswap finalize-offer <btcTxid> <offerId>

The console will output a big JSON blob containing a transaction payload. Open up https://mechanismhq.github.io/ordyswap, paste in the data, and hit submit. Your wallet will prompt you to approve and sign the transaction.

Check the validity of a transfer

You can check to make sure a transfer is valid by running

ordyswap get-tx-data <btcTxid> <offerId>

Cancelling an offer

Users can cancel an offer and eventually get their STX back. The flow for fully cancelling is:

  1. Cancel your order. The offer is still valid for 50 BTC blocks
  2. After 50 blocks, refund your order. Your STX will be sent back to you

The 50 block required wait is to prevent an attack where an offer is cancelled as soon as they see the Ordinal transfer in the mempool.

To cancel an order:

ordyswap cancel-order <id>

After 50 blocks:

ordyswap refund-order <id>

Get recent contract events

You can see the full stream of ordyswap events by running:

ordyswap events

Advanced: swapping an Ordinal that was already sent somewhere

The easiest way to use ordyswap is by swapping for an Ordinal that was minted by the seller. It's still perfectly possible to swap for Ordinals that have been traded, although you need to pay attention to more details.

When creating an offer for an already-transferred Ordinal, you need to use the "output ID" as the Ordinal ID.

Here's an example: Alice wants to swap with Bob for this very rare inscription. If you look at the properties of that inscription, you can see that the "output" isn't the same as the "ID". This means that the Ordinal has been sent out of the minter's address.

When making an offer for this ordinal, first click the "output" link, which takes you to this output page. Make sure that this output only contains one Ordinal. Ordyswap probably won't work otherwise.

Once that's all good, use the output ID when making an offer. For example, you would run:

ordyswap make-offer cba22ff59a5d65a34bfbeea9a4220c922bdd0d9ce35a3ff3813b98fd81133ecd:0 <amount> <btcAddress> <sellerStxAddress>

FAQ

Can I make a swap with other Stacks assets (like an NFT or a fungible token like xBTC)?

Not in this version of the contract, but it wouldn't take a big change to make that possible.

Can I make a swap for BTC?

This project is really only built to support Ordinal<->Stacks swaps. Swapping for BTC requires a totally different scheme.

Is this actively developed?

No, this was made for fun

What is up with this funky website where I paste in my tx?

In the spirit of shipping quickly, this project is just a CLI. I didn't want users to have to manage private keys manually, so the web app is a very simple way for the project to broadcast a transaction using a wallet. It's not possible to trigger a transaction from a CLI directly.

Help! The CLI says my offer doesn't exist (or similar)

The RPC endpoints sometimes have a little lag compared to what you might see on an explorer. If the transaction was just confirmed, wait a minute and try again.

Is there a changelog?

Yep - in the cli directory: ./cli/CHANGELOG.md

Where is the source code?

All the CLI code is under ./cli. The web app's code is under ./web

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • TypeScript 72.8%
  • Clarity 22.0%
  • JavaScript 4.2%
  • Other 1.0%