AMM Contract
Overview
This tutorial demonstrates how to create and use an AMM contract on Glittr:
Create two assets
Mint these assets
Create an AMM contract
Add liquidity to the AMM
Perform swap with slippage tolerance
Prerequisites
Node.js and Yarn installed
Basic understanding of TypeScript
1. Project setup
Let's create a new directory on your machine:
mkdir amm-example
cd amm-exampleInitialize the typescript project
Just press Enter for every prompt:
After that, let's add the dependencies
2. Create a new Bitcoin Private Key
This tutorial will use a hardcoded bitcoin private key instead of using wallet. So let's first generate the private key using WIF:
You can create this online using https://learnmeabitcoin.com/technical/keys/private-key/wif/ (select testnet, and then copy the WIF Private Key ). \
After you obtain the WIF, create a new file address-check.tsin your project file, this will output the address. Replace the wifstring with yours.
Run the script with
The address for my example is: bcrt1pvt3uzd3effh222v6wr8kx0sqhj07743lu0w9e7m74urqtgd85mgq6gwtes.
Next, let's get some BTC to that address.
Devnet: Faucet
Testnet4: mempool.space faucet
NOTE: We are using Glittr Devnet for this tutorial.
Creating and using AMM contract
Step 1: Create the First Token
First, we create the first asset using a MOA (Mintable Only Asset) contract, for simplicity, the ticker for this asset would be "FIRST". Make a new file named 1-create-1st-asset.tsand copy the file below, change the apiKeyandwif to your values.
NOTE: When you try this, you want to change the ticker to something more unique, or you can leave it as undefined.
This file will create a simple free mint asset, broadcast it to bitcoin node (devnet), and then wait for the tx to be mined, ~1 minute in devnet. Run the script.
Result:
The first contractId is [248419, 1] with the format of [block_height, tx_order]. Please take note of this somewhere, we will use the contractId to mint.
Step 2: Create the Second Token
Similarly, create the second token (ticker is SECOND), copy the file from the 1st step, and name it 2-create-2nd-asset.ts . Change the ticker from "FIRST" to "SECOND", and leave everything else.
NOTE: When you try this, you want to change the ticker to something more unique, or you can leave it as undefined.
Run the script.
Result:
The second contractId is [248424, 1], note this somewhere because we will use this information to mint.
Step 3: Mint Both Tokens
After creating the tokens, you need to mint them. This is done in two separate steps for each token. Create a new file named 3-mint-1st-asset.tsand copy the file below. Change the apiKey, wifand also contract. The contractis your contract's BlockTx from step 1.
Run the script.
Result:
Do the same with the second contract, copy the file into 4-mint-2nd-asset.ts , and then change the contract's BlockTx to the second contractId. Run the new script.
Result:
You'll now have two UTXOs holding the corresponding assets, to look into your list of assets, you can refer to the Helper API. The output below is the list of address' UTXOs (format is TXID:VOUT) that hold assets, you can see that there are two UTXOs for each asset.
Step 4: Create the AMM Contract
Now create the AMM contract that will manage the token pair, copy the file below into a new file 5-create-amm-asset.ts . Change the apiKey, wifand also the two contract.
This script will create a new asset, this asset is a collateralized asset with two input assets. Setting this asset with a proportional mint structure as "constant_product", is the same as creating AMM contract.
Run the script
Result:
Again, please take note somewhere the contractId for the AMM contract, you can find this on block_txfield, for this example the contractId is [248437, 1].
This creates an AMM with:
Ticker: AMM (or whatever you change)
Uses constant product formula (x y = k)
Accepts both FIRST and SECOND tokens as collateral
Step 5: Add Liquidity
To enable trading, add initial liquidity to the AMM. Copy the file below into a file 6-deposit-liquidity-amm.ts. Change the apiKey, wifand also the contract.
This script will first check your address' UTXO for the two contract assets, checking if it is enough for the amount specified, and then mint the AMM LP token. Let's run the script.
Result:
By default, the deposits are equal amounts (100 units each) of both tokens into the AMM pool. Let's take a look at your asset UTXOs after minting the liquidity pool token, you have now a new asset for the AMM liquidity pool token.
Step 6: Perform Swap
Finally, users can perform swaps between the two tokens, on this example we will use the 1st contract as input, and we will receive 2nd contract asset in return. Copy the file below into 7-swap-amm.ts. Change the apiKey, wifand also the two contract.
Let's run the script to perform the swap.
Result:
You have successfully swapped your asset here, let's take a look at the balance summary of your address. Your first asset will decrease by 10 units, while your second asset will increase by 9.
In this example, we use slippage tolerance to prevent transaction failures after the block is mined. The use of slippage in this way is still vulnerable to MEV, but better than without any assertion at all. We are open to any suggestions or PR to solve this problem.
Function explanations for setting the slippage tolerance:
calculateOutAmountis a function to calculate the result of a swap.
After obtaining the calculated output amount, decrease it with x% as slippage tolerance. So if the output amount changes (because of other swaps in the block), your tx will still be processed with a lower output amount.
Last updated