# What is Metal X?

A decentralized exchange (DEX) is a peer-to-peer (P2P) marketplace that connects cryptocurrency buyers and sellers. In contrast to centralized exchanges (CEXs), decentralized platforms are non-custodial, meaning a user remains in control of their private keys when transacting on a DEX platform. In the absence of a central authority, DEXs employ smart contracts that self-execute under a set of conditions and record each transaction to the blockchain. These trustless, secure transactions represent an accelerating segment of the digital asset market, and are pioneering new financial products.

Metal X uses order books to compile a record of all open buy and sell orders for a particular asset. The spread between these prices determines the depth of the order book and the prevailing market price. The orders information is held on-chain during trades, while user funds remain off-chain in user wallet.

## Why Metal X?

Metal X allows users to trade all available cryptos on the exchange and offers what most of the CEX's offer nowadays - Orderbook, different types of orders (Limit order, Market order, Stop loss order, Take profit order,) and trading view chart integration. The DEX also allows users to manage their orders - view or cancel active orders as well as view order history.

XPR Network offers no gas fees to users,  this combined with the secure DeFi wallet Webauth, offers the best decentralized trading experience!

## Learn more about the XPR Network

Learn more about the XPR Network and ecosystem in our overview.

{% content-ref url="/pages/A7H4BNmc28m4vCeKMiQ9" %}
[XPR Network & Ecosystem](/xpr-network/xpr-network-and-ecosystem)
{% endcontent-ref %}

## Metal X FAQ

Check out the most frequently asked questions here with answers.

{% content-ref url="/pages/GgFxpOfMTo95N9xMrGWS" %}
[Metal X FAQ](/dex/what-is-metal-x/metal-x-faq)
{% endcontent-ref %}

Check out our explanations of common terms used.

## Guides: Get Started On Metal X

Follow our [handy guides](https://help.xprnetwork.org) to get started:


# Trading Interface

Welcome to our in-depth guide to navigating the Metal X trading interface for the decentralized exchange (DEX) portion and mastering the use of various order types. In the ever-evolving realm of cryptocurrency trading, informed decision-making is your key to success. Whether you're a seasoned trader or just beginning your journey, this article will be your trusted companion for effectively utilizing the Metal X trading platform and mastering the intricacies of different order types.

### Minting and Redeeming Metal Dollar (XMD)

Minting and Redeeming [Metal Dollar (XMD)](https://metaldollar.com/) is accessible through the dedicated minting modal on MetalX.com.

<figure><img src="https://1068387139-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F2KWLHP2zE3VO3AoelaSy%2Fuploads%2FFh8iCn7WSzhdJ2jiqxqM%2Fconnect.png?alt=media&amp;token=f83b8d24-8886-4b0d-ac24-671d7c5a6145" alt=""><figcaption></figcaption></figure>

To access the modal, simply Connect your WebAuth Wallet using the Connect Wallet button on the top right, then click the dropdown on your wallet name and click on the 'Mint/Redeem XMD' button.

<figure><img src="https://1068387139-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F2KWLHP2zE3VO3AoelaSy%2Fuploads%2FUwhbsCj5JvHazB62HFYo%2Fmint.png?alt=media&amp;token=3edc820b-1414-4c5e-b4f2-d8d7127cbc61" alt=""><figcaption></figcaption></figure>

Within the modal, you have the option to either mint or redeem Metal Dollars (XMD).

<figure><img src="https://1068387139-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F2KWLHP2zE3VO3AoelaSy%2Fuploads%2FA8fnOOXGh2TmSO3uvMQZ%2Fmint%20metal%20dollar%202.png?alt=media&amp;token=26b88421-4bc7-44f0-b4ba-eb247664e013" alt=""><figcaption></figcaption></figure>

This minting procedure operates via a secure smart contract, delivering the twin benefits of transparency and security for every transaction. Conversely, users retain the flexibility to redeem their XMD holdings for the constituent stablecoins within the basket, enabling them to efficiently manage their digital assets and maintain liquidity.

### Pair Selection

<figure><img src="https://1068387139-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F2KWLHP2zE3VO3AoelaSy%2Fuploads%2FlcFIC9x8YfYNmC5J1H7w%2Fpair%20selection%201.png?alt=media&amp;token=0968252a-8512-40f4-88d7-7e54d8dc7c22" alt=""><figcaption></figcaption></figure>

You can find the pair selector at the top left of the page, and there's also another pair selection option available in the highlighted section below.

<figure><img src="https://1068387139-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F2KWLHP2zE3VO3AoelaSy%2Fuploads%2F3daui1hErxBt1x8DqkNn%2Fpair%20selection%202.png?alt=media&amp;token=b0d4816f-880a-4112-8690-2ca37acc9f7a" alt=""><figcaption></figcaption></figure>

### Price Data

<figure><img src="https://1068387139-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F2KWLHP2zE3VO3AoelaSy%2Fuploads%2FIvBeS258cm0t3QNxSIRm%2Fpair%20selection%203.png?alt=media&amp;token=c66ca29f-478b-4671-80b8-17b0b889055d" alt=""><figcaption></figcaption></figure>

In this section, you will find pertinent asset price information:

* Last Price: This reflects the most recent trade and represents the current asset price on the exchange.
* 24-Hour Change: Indicates the percentage change in the asset's price over the past 24 hours.
* 24-Hour Volume: Shows the total trading volume for the asset within the last 24 hours.
* 24-Hour High: Highlights the highest price the asset reached in the past 24 hours.
* 24-Hour Low: Indicates the lowest price the asset reached in the past 24 hours.

### Personalize Your Trading Layout

<figure><img src="https://1068387139-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F2KWLHP2zE3VO3AoelaSy%2Fuploads%2FIfRwdOk4N8oYgywuSdb0%2Fsettings.png?alt=media&amp;token=594c9d0d-d840-4f16-8d0a-921b54adc0df" alt=""><figcaption></figcaption></figure>

Metal X has introduced new features that enable you to personalize the layout of your trading experience. By clicking on the Dashboard Settings icon, you can:

* Rearrange Widgets through Drag and Drop
* Toggle Widgets On / Off
* Switch between Simple and Advanced Views
* Reset to the Default Layout

### Tradingview Chart

<figure><img src="https://1068387139-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F2KWLHP2zE3VO3AoelaSy%2Fuploads%2FCQgT2tCYMnVZrT5t2pXU%2Fpair%20selection%204.png?alt=media&amp;token=31f14e6d-f2d2-4ee6-b5d3-a819efe0e2c6" alt=""><figcaption></figcaption></figure>

We partnered with TradingView to offer our users an in-depth technical analysis tool. Now you have all the bells and whistles you can find on TradingView right on Metal X.

The chart allows you to display indicators like RSI, moving averages, and much more. There are also drawing tools available. More information on how to use TradingView charts can be found on the [TradingView Wiki](https://www.tradingview.com/wiki/Main_Page).

### Order Book

<figure><img src="https://1068387139-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F2KWLHP2zE3VO3AoelaSy%2Fuploads%2FrQ2Cia6zDolKzidjupdz%2Fpair%20selection%205.png?alt=media&amp;token=04f0d67e-e734-4f1e-b1a9-0ed1c5352eba" alt=""><figcaption></figcaption></figure>

The order book shows a list of open orders on the exchange. The top half shows the asking side, or sell orders of the order book. The bottom half is the bidding side, or buy orders of the order.

The order book offers a quick review of the current market depth and can give you an estimate of the filled price of a market order.

In the middle, you can switch the precision of the order book.

### **Trade History**

<figure><img src="https://1068387139-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F2KWLHP2zE3VO3AoelaSy%2Fuploads%2FsRCf5TKqGKwJgpK9BQ8J%2Fpair%20selection%206.png?alt=media&amp;token=037161ab-9c6f-493b-aa17-18f27b523596" alt=""><figcaption></figcaption></figure>

This section displays the recent trading history for the selected trading pair, encompassing the trading activities of all users on the platform.

### **Order Types**

<figure><img src="https://1068387139-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F2KWLHP2zE3VO3AoelaSy%2Fuploads%2FE9uhjfTyZOVaaHPnTSi7%2FScreenshot%202026-01-20%20at%2010.29.35%E2%80%AFAM.png?alt=media&amp;token=7af68a19-3bca-4773-9d0f-571bd4899e9e" alt=""><figcaption></figcaption></figure>

In this section, you can place different trading orders:

* Market order
* Limit Order
* Stoploss order
* Takeprofit order

A full breakdown can be [read in the Order Types section.](/developers-dex/contract-mappings/order-types)

### **Exchange Activity**

In the bottom left-hand side of the interface, you can locate your personal Open Orders, Order History, Funds, Fees, and Referral Code.&#x20;

**Open Orders:** Displays which orders are not filled in their entirety and are still currently open. You can cancel orders here by clicking on the ❌ symbol.

<figure><img src="https://1068387139-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F2KWLHP2zE3VO3AoelaSy%2Fuploads%2FNzNPEAwptE4ZV2eMeENr%2FScreenshot%202026-01-20%20at%2010.32.50%E2%80%AFAM.png?alt=media&amp;token=d558b49b-1159-466b-8b69-f4ac800dae63" alt=""><figcaption></figcaption></figure>

**Order History:** Displays the orders you have placed. These orders can be filled, unfilled, or canceled.&#x20;

<figure><img src="https://1068387139-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F2KWLHP2zE3VO3AoelaSy%2Fuploads%2FDy2Yaqew3J229dcg0LLw%2FScreenshot%202026-01-20%20at%2010.33.16%E2%80%AFAM.png?alt=media&amp;token=631c4cca-56fd-49ea-9d42-5cede21d6f1e" alt=""><figcaption></figcaption></figure>

**Funds:** Displays your available assets to trade.

<figure><img src="https://1068387139-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F2KWLHP2zE3VO3AoelaSy%2Fuploads%2Fknaj58ma0DnXLpFSE0z0%2FScreenshot%202026-01-20%20at%2010.34.01%E2%80%AFAM.png?alt=media&amp;token=ad3bd979-e576-4c19-9ca4-e40e03c89c64" alt=""><figcaption></figcaption></figure>

**Fees:** This section displays your fees, 30-day volume average, and referral info.

<figure><img src="https://1068387139-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F2KWLHP2zE3VO3AoelaSy%2Fuploads%2FS8x2pIc9th5gthfNtCcn%2FScreenshot%202026-01-20%20at%2010.34.25%E2%80%AFAM.png?alt=media&amp;token=b4cd9bbc-3639-4aae-9167-7593b3fa441e" alt=""><figcaption></figcaption></figure>

**My Fees:** Displays your current maker and taker fees and the volume you generated on a 30-day average.

**Volume fees:** Trading fees on Metal X are based on the 30-day average trading volume of the user. Your current tier is highlighted in purple. [You can learn more about the different tier categories and applicable fees here.](/dex/what-is-metal-x/dex-fees-and-discounts)

**Staking fees:** Users can get a discount in fees based on how much XPR they have staked on the XPR Network. Your current tier is highlighted in purple.  [You can learn more about the different tier categories and applicable fees here.](/dex/what-is-metal-x/dex-fees-and-discounts)

**Referrals:** This section shows your referral code. Click on it to share your personal link with others. Learn more about the [referral program here.](/dex/what-is-metal-x/referral-program)

This section also displays who referred you and when the referral period ends.


# Trading on Metal X DEX

**Deposit:** Any user/trader should have sufficient funds/tokens in their account before placing a trade.

**Withdraw:** User/trader can withdraw funds/tokens into their own account by cancelling the trades.

### **Place order**

**Limit Order:** A Limit order is a sell/buy order placed at a higher/lower or better price than the current or specific price. Price needs to be quoted along with assets to buy/sell.

<figure><img src="https://1068387139-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F2KWLHP2zE3VO3AoelaSy%2Fuploads%2F4iduhUUd2mwKpZ5NWNqV%2FScreenshot%202026-01-20%20at%2010.59.50%E2%80%AFAM.png?alt=media&amp;token=c96228f5-2380-4eec-8689-f8106f08a6e8" alt=""><figcaption></figcaption></figure>

In this example, user want to trade XPR/XMD pair. `Buy XPR` window shows that user want to buy XPR worth 1 XMD at a price of 0.0035. Similarly `Sell XPR` window shows that user want to sell 222 XPR at a price of 0.0045

**Market Order:** Market orders executed immediately on placing order. If there no liquidity available, the orders will get cancelled immediately without pending in orderbook.

<figure><img src="https://1068387139-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F2KWLHP2zE3VO3AoelaSy%2Fuploads%2FpPsjKPUrZsZEzh7m7kCV%2FScreenshot%202026-01-20%20at%2011.01.16%E2%80%AFAM.png?alt=media&amp;token=358e02a7-b8b4-4643-a263-a5efeb66cf2c" alt=""><figcaption></figcaption></figure>

In this example, user want to trade XPR/XMD pair. `Buy XPR` window shows that user want to buy XPR worth 1 XMD at market price. Similarly `Sell XPR` window shows that user want to sell 300 XPR at market price.

**Stop-Loss Order:** Stoploss orders are used to liquidate assets on reaching certain price level. To trigger/move/promote this order, trigger price needs to be reached.

<figure><img src="https://1068387139-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F2KWLHP2zE3VO3AoelaSy%2Fuploads%2FDaw0JqvV92e8ADcrHx9h%2Fstop%20loss%20buy.png?alt=media&amp;token=ffeb0493-2f78-43da-8b34-8770774d5bdd" alt=""><figcaption></figcaption></figure>

In this example, `Buy XPR` window shows that user want to place a stoploss order(cover the sold assets) at a trigger of 0.004 with a price of 0.0035. Once the trigger price is reached, the order will be promoted to orderbook and get matched with available orders at a price of 0.0035 or less.

**Take-Profit Order:** Like stoploss orders takeprofit orders are also used to liquidate assets on reaching certain price level. The order will be trigger on reaching the trigger price mentioned in the order.

<figure><img src="https://1068387139-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F2KWLHP2zE3VO3AoelaSy%2Fuploads%2FtCN1ai7u1MXEl82SGTaM%2Ftake%20profit.png?alt=media&amp;token=bb1795aa-82d7-4893-9c82-0b5ea4bca822" alt=""><figcaption></figcaption></figure>

In this example, `Sell XPR` window shows that user want to place a takeprofit order(example: Book profits from the holding assets) at a trigger of 0.008 with a selling price of 0.0081. Once the trigger price is reached, the order will be promoted to orderbook and get matched with available orders at a price of 0.0081 or more.

**Cancel Order:** Pending orders(full or partial) can be cancelled. In the below mentioned example, order can be cancelled through `Actions`column

<figure><img src="https://1068387139-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F2KWLHP2zE3VO3AoelaSy%2Fuploads%2F8B9YDJm1aVHMVynkSSRk%2FScreenshot%202026-01-20%20at%2011.09.16%E2%80%AFAM.png?alt=media&amp;token=2fd98cc2-c383-4916-baed-1bbf9242df09" alt=""><figcaption></figcaption></figure>


# DEX fees and discounts

Trading fees on Metal X are based on the 30-day average trading volume of the user. Below are different tiers categories based on volume and applicable fees.

### Fees table

<table><thead><tr><th width="375">Level/Tier</th><th width="169">Volume 30 days</th><th width="150">Maker</th><th>Taker</th></tr></thead><tbody><tr><td>I</td><td>&#x3C; $250,000</td><td>0.10%</td><td>0.10%</td></tr><tr><td>II</td><td>≥ $250,000</td><td>0.08%</td><td>0.08%</td></tr><tr><td>III</td><td>≥ $500,000</td><td>0.06%</td><td>0.06%</td></tr><tr><td>IV</td><td>≥ $750,000</td><td>0.04%</td><td>0.04%</td></tr><tr><td>V</td><td>≥ $1,000,000</td><td>0.02%</td><td>0.02%</td></tr><tr><td>VIP</td><td>≥ $1,250,000</td><td>0.01%</td><td>0.01%</td></tr><tr><td>Market Maker</td><td>-</td><td>0%</td><td>0%</td></tr></tbody></table>

### Discounts

Metal X offers different discounts based on user/trader activity on the XPR Network. Below is the list of discounts offered.

**The highest discount between the volume tier, staking tier, and DEX Key is applied.**

#### Staking discount

Users can get a discount in fees based on how much XPR they have staked on the XPR Network.&#x20;

<table><thead><tr><th width="375">Level/Tier</th><th width="169">Staked XPR</th><th width="150">Maker</th><th>Taker</th></tr></thead><tbody><tr><td>I</td><td>&#x3C; 1,000,000</td><td>0.10%</td><td>0.10%</td></tr><tr><td>II</td><td>≥ 1,000,000</td><td>0.08%</td><td>0.08%</td></tr><tr><td>III</td><td>≥ 10,000,000</td><td>0.06%</td><td>0.06%</td></tr><tr><td>IV</td><td>≥ 20,000,000</td><td>0.04%</td><td>0.04%</td></tr><tr><td>V</td><td>≥ 60,000,000</td><td>0.02%</td><td>0.02%</td></tr><tr><td>VIP</td><td>≥ 100,000,000</td><td>0%</td><td>0%</td></tr></tbody></table>

#### NFT Key discount

A trading discount is applied to users holding specific NFT DEX Keys. Users holding a limited edition NFT DEX Key are eligible to receive a 100% discount on fees.&#x20;

|   NFT   | Discount |
| :-----: | :------: |
| DEX Key |   100%   |

#### Referral discount <a href="#undefined" id="undefined"></a>

The referral program is beneficial for both the referrer and referee as they both earn rewards from the fees. You can learn more about the [referral program here](/dex/what-is-metal-x/referral-program).

#### 0% Trading Fees on XBTC Market <a href="#undefined" id="undefined"></a>

The [XBTC/XMD](https://app.metalx.com/dex/XBTC_XMD) trading pair on the DEX has zero trading fees for ALL users regardless of your level/tier. You can trade Bitcoin on Metal X with absolutely zero fees.

#### Bridge Deposit fee <a href="#undefined" id="undefined"></a>

0%&#x20;

#### Bridge Withdrawal fee <a href="#undefined" id="undefined"></a>

| Token | Fee (Token Amount) |
| ----- | ------------------ |
| ADA   | 1                  |
| DOGE  | 5                  |
| EOS   | 0.2                |
| HBAR  | 10                 |
| SOL   | 0.01               |
| USDC  | 1                  |
| XLM   | 1                  |
| XRP   | 0.5                |
| XPR   | FREE               |

<sub>*Bridge operator reserves the right to add additional fees during times of network congestion.*</sub>


# Referral program

The referral program is beneficial for both the referrer and referee as they both earn rewards from the fees. This program is applicable only for new wallets/accounts. The referral program only applies to fees earned on the DEX section of Metal X and not the Swap section.&#x20;

|   Type   | Discount |
| :------: | :------: |
| Referrer |    25%   |
|  Referee |    5%    |

There is no limit to the number of referrals a trader can make. Each account can only use one referral code. Earning rewards as the referee will last for 1 year.

## **Referral link**

Get your referral link after you have connected your [WebAuth Wallet](https://webauth.com/) to Metal X app, visit the Fees tab from the [DEX](https://app.metalx.com/dex/) and click on your Wallet Name to copy the URL to your clipboard.

<figure><img src="https://1068387139-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F2KWLHP2zE3VO3AoelaSy%2Fuploads%2FrhrrLRRbN7qbcDfdXB21%2Fref.png?alt=media&amp;token=fffb6629-7d6f-4b65-83a0-d448d2e50b0c" alt=""><figcaption></figcaption></figure>

## **Referral example**

John refers Hank.&#x20;

Hank creates an account on Metal X and deposits $500 USDC to his wallet.&#x20;

Hank visits Metal X and buys $500 XUSDC worth of XPR, or 500,000 XPR.&#x20;

Hank acting as a taker in this transaction.&#x20;

Hank as the referee pays 0.95 XUSDC as a fee (1 XUSDC base fee Tier 1 minus a 5% reduction).&#x20;

John as the referrer receives 25% of the 0.95 XUSDC fee or 0.237500 XUSDC


# Metal X FAQ

### **What pairs are available to trade on Metal X?**

The following pairs are available:

* XBTC/XMD
* XETH/XMD
* XPR/XMD
* XMT/XMD
* LOAN/XMD
* METAL/XMD
* XDOGE/XMD
* XHBAR/XMD
* XLTC/XMD
* XXRP/XMD
* XSOL/XMD
* XXLM/XMD
* XADA/XMD

### How do I start using Metal X?

The first step is creating a free XPR Network account, which can be done on the Webauth Wallet that is available on [Android](https://play.google.com/store/apps/details?id=com.metallicus.webauth), [iOS](https://apps.apple.com/us/app/webauth-com/id1594500069) and [web](https://webauth.com/). You can then deposit supported cryptos to the WebAuth.com wallet and connect your wallet to Metal X.&#x20;

### **What wallet should I use to use Metal X?**

You can use any wallet that supports the XPR Network. We recommend using the WebAuth  Wallet that is available on [Android](https://play.google.com/store/apps/details?id=com.metallicus.webauth), [iOS](https://apps.apple.com/us/app/webauth-com/id1594500069) and [web](https://webauth.com/).&#x20;

### **Is it true that there are no gas or transaction fees to use Metal X?**

The XPR Network blockchain charges no gas or mining fees to end-users – transactions on XPR Network are free.&#x20;

Metal X does have [trading fees that can be reduced](/dex/what-is-metal-x/dex-fees-and-discounts).

### **Is it true that there are no trading fees on the XBTC/XMD pair?**

Yes it's true, there are no fees on the [XBTC\_XMD](https://app.metalx.com/dex/XBTC_XMD) trading pair. That is no transaction fees AND no trading fees. Only on Metal X.

### Do I need to verify my identity to use Metal X?

Metal X requires that users [verify their identity](https://identity.metalx.com/) in order to safeguard the integrity of the platform and reduce the risk of fraud, money laundering, terrorist financing, and the violation of sanctions. As such all users will need to verify their identity, to use the platform.

In order to deposit and withdraw funds to/from other blockchains using the WebAuth wallet, verifying your identity is mandatory for everyone.

You can verify within minutes from <https://identity.metalx.com/>

### What features are coming next for Metal X?

We are constantly working to improve the Metal X trading protocol, offer new features, and diversify the supported tokens on our platform.

### Does Metal X have a referral program?

Yes! Our referral program is beneficial for both the referrer (25%) and referee (5%) as they both earn rewards/discounts from the fees.  More info [on the referral program here](/dex/what-is-metal-x/referral-program).


# Smart Contract


# Contract Address

contract: `dex`


# Tables

**TABLE `global`**

* `{name} fee_contract`: the name of the account that hold the fees, by default it sets to fee.metal
* `{`uint16\_t`} last_market_id`: indicates last market id(id of the pair) that was created
* `{`uint64\_t`} last_order_id`: indicates last order id that was created(used to keep track order count and assign unique ids)
* `{`uint64\_t`} last_trade_id`: indicates last trade id that was created(used to keep track trades  and assign unique ids)
* `{`uint8\_t`} contract_status`: to keep track of the contract status

#### example

```
{
  "fee_contract": "fee.metal",
  "last_market_id": "1",
  "last_order_id": "5",
  "last_trade_id": "2",
  "contract_status": "0"
}
```

#### TABLE `markets`

* `{`uint16\_t`} market_id`: id of the market pair.
* `{`uint64\_t`} order_min`: min quantity to be placed for trade
* `{status_code} status_code`: represents status of the market id(can be ACTIVE, INACTIVE, NOTINUSE, DISABLE\_ORDERS\_FILLS, DISABLE\_ORDERS and DISABLE\_FILLS)
* `{`uint64\_t`} ask_oracle_index`: index of the oracles to get current price of the token
* `{extended_symbol} bid_token`: represents the bid value
* `{extended_asset} ask_token`: represents ask token in the form of extended asset
* `{extended_asset} total_reserves`: total reserves

```
{
    "bid_token": {
        "sym": "4,XMT",
        "contract": "eosio.token"
    },
    "ask_token": {
        "quantity": "1.361708 XUSDC",
        "contract": "eosio.token"
    },
    "order_min": 10,
    "status_code": 1,
    "ask_oracle_index": 1
}
```

#### TABLE `balances`

* `{name} account`: user account for the funds/tokens
* `{vector<extended_asset>}` balances: balance of each token that holds by user/trader

#### example

```
{
  account: 'trader',
  balances: [
    { quantity: '1000.000000 XUSDC', contract: eosioTokenContract.name.toString() }
  ]
}
```

#### TABLE `orderq`

`This table stores all placed orders`

* `{int64_t} order_id:`id of the order that was placed.
* `{uint16_t} market_id`: id of the market pair.
* `{uint64_t} quantity`: represents how much quantity to buy/sell
* `{uint64_t} price`: price of the trade
* `{name} account_name`: represents account name of the trader
* `{uint8_t} order_side`: buy or sell
* `{uint8_t} order_type`: type of order, can be LIMIT, STOPLOSS and TAKEPROFIT
* `{uint64_t} trigger_price`: price at which order triggered to new state, applicable for both  stop loss and take profit
* `{uint8_t} fill_type`: order fill types like GTC(Good Till expiry), IOC(Immediate or Cnacel) and Post\_Only(used to provide liquidity)

```
    {
      "account_name": "collector",
      "market_id": 1,
      "order_id": 1,
      "order_side": orderSide.SELL,
      "order_type": orderType.LIMIT,
      "price": 16374242,
      "quantity": 200000000,
      "fill_type": 0,
      "trigger_price": 0
    },
    {
      "account_name": "bob",
      "market_id": 1,
      "order_id": 2,
      "order_side": orderSide.BUY,
      "order_type": orderType.LIMIT,
      "price": 16384000,
      "quantity": 49152000,
      "fill_type": 0,
      "trigger_price": 0
    }
```

#### TABLE `order`

`This table represents current order book`

* `{int64_t} order_id:`id of the order that was placed.
* `{uint16_t} market_id`: id of the market pair.
* `{uint64_t} quantity`: represents how much quantity to buy/sell
* `{uint64_t} price`: price of the trade
* `{name} account_name`: represents account name of the trader
* `{uint8_t} order_side`: buy or sell

```
  {
    "account_name": "collector",
    "market_id": 1,
    "order_id": 5,
    "order_side": 2,
    "price": 16340000,
    "quantity": 199877601
  }
```

#### TABLE `fees`

* `{name} account_name`: user account to store fee related information
* `{name} referrer_name`: name of the account who referred&#x20;
* `{time_point} referrer_ends`: referral's end time&#x20;
* `{double} volume_avg_30d`: users's 30 day's average traded volume
* `{time_point} volume_avg_last_update`: time at which 30d avg volume updated
* `{uint8_t} tier`: tier of the user, can be set through Action also

#### example

```
{
  "account_name": "fee.metal",
  "referrer_name": "alice",
  "referrer_ends": "1696022087",
  "volume_avg_30d": "1'005'000.00",
  "volume_avg_last_update": "1664986087",
  "tier": "1"
}
```

#### TABLE `currency_stats`

* `{asset} supply`: supply&#x20;
* `{asset} max_supply`: max supply of the token
* `{name} issuer`: issuer account name

#### example

```
{
  "supply": "500000",
  "max_supply": "10000000",
  "name": "alice"
}
```

#### TABLE voters\_xpr

* `{name} owner`: user account holding xpr
* `{uint64_t} staked`: staked amount
* `{bool} isqualified`: qualified flag
* `{uint64_t} claimamount`: total amount claim
* `{uint64_t} lastclaim`: last claim amount
* `optional{uint64_t} startstake`: the last stake amount

#### example

```
{
  "owner": "alice",
  "staked": "1000000",
  "isqualified": "1",
  "claimamount": "50000",
  "lastclaim": "10000",
  "strtstake": "5000"
}
```

#### TABLE assets\_s

* `{uint64_t} asset_id`: unique id of the nft asset
* `{name} collection_name`: name of the collection
* `{name} schema_name`: name of the schema to store details
* `{uint32_t} template_id`: template used to mint this nft asset
* `{name} ram_payer`: account to pay for the transaction
* `vector<{asset}> backed_tokens`: list of tokens backed this asset
* `vector<{uint8_t}> immutable_serilized_data`: immutable data to be serialized
* `vector<{uint8_t}> mutable_serilized_data`: mutable data to be serialized

#### example

```
{
  "asset_id": "1099511627776",
  "collection_name": "bullscollect",
  "schema_name": "bulls",
  "template_id": "5",
  "ram_payer": "alice",
  "backed_tokens": {'5000, xpr', '400, XMT'},
  "immutable_serilized_data": 
  "mutable_serilized_data":
}
```

<br>


# Actions

#### CREATEMARKET

Creates a new market for the token pair.

This action is triggered by admin to create the market pair.

* **authority**: `admin`
* **requirements**: none

**args**

* `{extended_symbol} bid_token`: extended symbol of the buy token to create token pair
* `{extended_asset} ask_token`: extended asset of the sell token to create token pair
* `{uint16_t} order_min`: min order to place
* `{uint8_t} status_code`: status code of the market pair
* `{uint64_t} ask_oracle_index`: index of the oracle to get price of token from feed

**example**

```
{
  "account": "metalpay",
  "name": "createmarket",
  "data": {
    "bid_token": {
      "quantity": "4.0000 XPR",
      "contract": "eosio.token"
    },
    "ask_token": {
      "sym": "4.0000 XMT",
      "contract": "xtokens"
    },
    "order_min": "10",
    "status_code": "1",
    "ask_oracle_index": "1"
  }
}
```

#### UPDATEMARKET

Update an exisitng market for status change or min order.

* **authority**: `admin`
* **requirements**: market id should be existed for an update&#x20;

**args**

* `{uint16_t} market_id`: id of the token pair to update
* `{uint64_t} order_min`: min order to place
* `{uint8_t} status_code`: status code of the market
* `{uint64_t} ask_oracle_index`: index of the oracle to get price of token from feed

**example**

```
{
  "account": "admin",
  "name": "updatemarket",
  "data": {
    "market_id": "2",
    "order_min": "10",
    "status_code": "3",
    "ask_oracle_index": "2",
  }
}
```

#### PLACEORDER

Creates a new order and place it into orderq or sltp table.

This action is triggered by any user who has sufficient funds to trade token pairs.

* **authority**: `user`
* **requirements**: none

**args**

* `{uint16_t} market_id`: id of the token pair
* `{name} account`: name of the account holder who would like to buy/sell
* `{uint8_t} order_type`: type of order, LIMIT(1), STOPLOSS(2) or TAKEPROFIT(3)
* `{uint8_t} order_side`: indicates order side is BUY(1)/SELL(2)
* `{uint64_t} quantity`: quantity to be traded
* `{uint64_t} price`: quoted price by the user
* `{extended_symbol} bid_symbol`: extended symbol of the buy token from the market id(token pair)
* `{extended_symbol} ask_symbol`: extended symbol of the ask token from the market id(token pair)
* `optional{uint64_t} trigger_price`: price at which order triggered from sltp to orderq, used for stoploss and takeprofit orders
* `optional{uint8_t} fill_type`: fill type of the order, options are GTC(Good Till Expiry) EXPIRY), IOC(Immediate Or Cancel) and POST\_ONLY(a limit order placed by a user will never match with any orders already on the book)
* `{name} referrer`: name of the referrer account(the referrer would get a share in fees)

**example**

```
{
  "account": "trader",
  "name": "placeorder",
  data: {
    "market_id": 1,
    "account": "trader",
    "order_type": 1,
    "order_side": 2,
    "quantity": 100000000,
    "price": 1,
    "bid_symbol": {
        "sym": "8,XETH",
        "contract": "eosio.token"
    },
    "ask_symbol": {
        "sym": "4,XMT",
        "contract": "eosio.token"
    },
    "trigger_price": 0,
    "fill_type": 1
  }
}
```

#### PROCESS

This action is used to process the orders in the orderQ. It does apply to all orders irrespective of market-id's.

* **authority**: user
* **requirements**: none

**args**

* `{uint16_t} size`: size of the orders to process

**example**

```
{
  "account": "user",
  "name": "process",
  "data": {
    "size": "50"
  }
}
```

#### PROCESSSLTP

This action is used to process the stoploss and takeprofit orders in the orderQ.&#x20;

* **authority**: user
* **requirements**: none

**args**

* `{uint16_t} market_id`: process orders for specific market
* `{uint16_t} size`: size(number) of the orders to process

**example**

```
{
  "account": "user",
  "name": "processsltp",
  "data": {
    "market_id": "2",
    "size": "20"
  }
}
```

#### CANCELORDER

This action is used to cancel orders that are queued in stoploss or orderq or orderbook.&#x20;

* **authority**: user
* **requirements**: none

**args**

* `{name} account`: name of the account that order belongs to
* `{uint64_t} order_id`: id of the order

**example**

```
{
  "account": "user",
  "name": "cancelorder",
  "data": {
    "account": "alice",
    "order_id": "23"
  }
}
```

#### PAUSEDEX

This action is used to pause and resume all activities/actions on DEX.&#x20;

* **authority**: `admin`
* **requirements**: none

**args**

* `{bool} status`: status to be updated

**example**

```
{
  "account": "admin",
  "name": "pausedex",
  "data": {
    "status": "true"
  }
}
```

#### SETFEEACNT

All fees collected through DEX trading would be deposited into fee account. The fee account can be updated by admin.

* **authority**: `admin`
* **requirements**: none

**args**

* `{name} account`: fee account to be updated

**example**

```
{
  "account": "admin",
  "name": "setfeeacnt",
  "data": {
    "account": "bob"
  }
}
```

#### SETUSERTIER

Both maker and taker fees collected based on user acitivitiy on DEX. User tier would be calculated based on 30d average colume and it can be assigned through action by admin.

* **authority**: `admin`
* **requirements**: none

**args**

* `{name} account`: fee account to be updated
* `{uint8_t} tier`: tier value

**example**

```
{
  "account": "admin",
  "name": "setusertier",
  "data": {
    "account": "alice",
    "tier": "2"
  }
}
```


# Contract Mappings


# Order Types

Order types on Metal X Trading DEX are classified into:

* Orderbook (OrderType = **0**)
* Limit Order (OrderType **= 1**)
  * Market Buy: Price = 9223372036854775806 \
    &#x20;                         OR\
    Market Sell: Price = 1<br>

    **Note:** Above mentioned prices are raw prices, actual prices in API are divided by 10^(ask precision)
* Stop Loss order (OrderType **= 2**)
* Takep Profit order (OrderType **= 3**)

**Orderbook:** It represents an order is sitting in orderbook and waiting to get matched. The user can not place order directly under this category. The order gets promoted to this type after processing from the below categories.

**Limit Order:** It is an order with limit price placed in the orderq. This order will promoted into orderbook or executed/fills on reaching the limit price(it can be less for buy ordes or more for sell orders)

**Market Order:** Market orders are a special type of limit order that are executed/fills as quickly as possible after processing on XPR Network. It is applicable for both buy and sell orders.

{% hint style="info" %}
**NOTE:** The fill\_type for market order needs to be IOC
{% endhint %}

**Stoploss Order:** Stoploss order is an order that gives an opportunity to the user/trader to choose maximum amount of loose on the trade. Both limit and stoploss price has to be selected on the trade. Also this order is not guaranteed to be executed.

**Takeprofit Order:** Takeprofit order is an order that gives an opportunity to the user/trader to choose minimum profit on trade. Both limit and takeprofit price has to be selected on the trade. Also this order is not guaranteed to be executed.

{% hint style="info" %}
**Note**: On executing limit buy orders there are chances that the user might receive more than expected tokens. This would be possible when a better execution price(sell offer) available at that instant, mostly the additional tokens would be in small fractions instead of receiving back dust amounts like other exchanges.\
\
**Example:** If a market sell order of 200 XPR placed at 0.199, when a limit buy order of 100 XPR at 0.2 exist, user will receive 100.5026 XPR\
\
**Benefits:** Users are not left with small unsellable dust values
{% endhint %}


# Fill Types

Metal X DEX supports different fill types:

**GTC (Good-Till-Cancel) (FillType = 0):** Order will be in queue until it gets executed/fills completely or user can cacel at anytime.

**IOC (Immediate-Or-Cancel) (FillType = 1)**: Order will be executed/filled immediately based on the quantity available in the open orders in the orderbook, remaining unfilled orders will be cancelled. Incase of no matching fills, entire order will get cancelled. Market orders should be submitted with this type.

**POST\_ONLY (FillType = 2):** it will not be executed/filled immediately even though matching orders available in the orderbook. This kind of orders adds liquidity to the market.


# Order Status

Status of an order

This field represents the status of an order in the order flow.

**create**: Order successfully added to order queue.

**transfer**: During processing of orders, when the order is eligible to be executed(based on the last execution price), the order status will get updated to 'transfer' and order will be promoted to orderbook.

**update**: Partial fill of order to represent pending quantity.

**cancel**: When the remaining quantity in the order has been canceled by the user.

**delete**: Successful execution of order.


# Order Side

Order side represents whether user want to buy or sell tokens.

**BUY(= 1)**: To place a buy order.

**Sell(= 2)**: To place a sell order.


# Status codes for markets

This represents status codes for the specific market(trading pair).

**INACTIVE(= 0)**: Currently this market is not active at the moment and users can't place the orders.

**ACTIVE(= 1)**: It is active and users can place orders.

**NOT\_IN\_USE(= 2)**: This market is not in use anymore.

**DISABLE\_ORDERS(= 3)**: Placing orders is disabled for the market, but existing orders will get processed.

**DISABLE\_FILLS(= 4)**: Filling the existing orders for this market is disabled.

**DISABLE\_ORDERS\_FILLS(= 5)**: This option disables both placing and filling orders.

**DISABLE\_STOPLOSS\_TAKEPROFIT(= 6)**: Disable stoploss and takeprofit activity.


# Common Errors

This section describes the common errors(assertions) on placing/submitting new orders and cancelling exiting orders.

**Place Order Errors**: Below are the common errors occurs during the verification of order submission.

Example of error thrown from `transact`:&#x20;

```javascript
 {
   json: {
      code: 500,
      message: 'Internal Service Error',
      error: {
        code: 3050003,
        name: 'eosio_assert_message_exception',
        what: 'eosio_assert_message assertion failure',
        details: [
          {
            message: 'assertion failure with message: Invalid order type',
            file: 'wasm_interface.cpp',
            line_number: 1075,
            method: 'eosio_assert'
          },
          {
            message: 'pending console output: ',
            file: 'apply_context.cpp',
            line_number: 113,
            method: 'exec_one'
          }
        ]
      }
    }
}
```

The above errors asserts whether the order type in place order is valid or not. Since order type is not valid, it will throw an error "Invalid order type"

**Errors list**:

"Contract is paused": Currently the contract is paused and users can't submit orders.

"Market not found": The market is not existed for the submitted order.

"Placing orders is disabled for this market": Order submission is disabled for this market.

"Invalid order type": Order type is Invalid, it should be one of the {Limit(1), Stoploss(2), Takeprofit(3)}.

"Invalid order side": Order side is invalid, it should be either buy(1) or sell(2)

"Invalid price": The price quoted is invalid, it is not within 0 and INT\_MAX

"Minimum order size is ...": Min order size is not valid.

"Invalid order type - add trigger price": Trigger price is not added for stoploss and take profit orders.

"Invalid referrer name, self referral not allowed": Self referral is not allowed.

**Cancel Order errors:**

"Contract is paused": Currently the contract is paused and users can't submit orders.

"Invalid authorization": User is not authorized to cancel the order.

"Invalid order id": The order id is less than or equals to 0, so it's not valid.

"Order not found": The order id which user is intended to cancel is not found or existed

"Accounts mismatch, order cancellation not allowed": The account name provided is different from the account(order placed), so cancellation is not allowed.

"Market not found": The market id, which was referenced by order\_id is not found .


# Examples

This section contains examples to trade on DEX using JavaScript or Python.


# Installation + Initialization

DEX orders can be submitted through both JS and python library. Below are the instructions to install.

**Install:**

{% tabs %}
{% tab title="JavaScript" %}

```
npm i @proton/js
npm i node-fetch@2
```

{% endtab %}

{% tab title="Python" %}
[pyeoskit](https://github.com/learnforpractice/pyeoskit) **is the library used for DEX.**

Below are the instructions to install it on different Operating Systems.

**MAC and Linux(ubuntu):**

```
python3 -m pip install -U pip
python3 -m pip install pyeoskit
```

\
**Windows:**

```
python -m pip install -U pip
python -m pip install pyeoskit
```

####

#### M1/M2 Mac:

```
brew install go cython
python3 -m pip install cmake

xcode-select --install
in case if you see the error message "xcode-select: error: command line tools are already installed, use "Software Update" to install updates" for above command, fix the with the following command
sudo rm -rf /Library/Developer/CommandLineTools
xcode-select --install

python3 -m pip install -U pip
python3 -m pip install pyeoskit
```

```
python3 -m pip install -U pip
python3 -m pip install pyeoskit
```

{% endtab %}
{% endtabs %}

**Initialize API:**

{% tabs %}
{% tab title="Javascript" %}

```javascript
const {JsonRpc, Api, JsSignatureProvider} = require('@proton/js')

// For testnet use https://rpc.api.testnet.metalx.com/
const ENDPOINTS = [
   'https://rpc.api.mainnet.metalx.com',
]

// To export private key from your wallet, follow:
// https://help.xprnetwork.org/hc/en-us/articles/4410313687703-How-do-I-backup-my-private-key-in-the-WebAuth-Wallet-
const PRIVATE_KEY = 'PVT_K1_2fdW4UGdbgG59mUaTiMXLy1rFv3afbmSWEZGWFz6zF8dR1VZPb'

// Authorization
const username = 'metaltest1'
const authorization = [{
    actor: 'pbonblockc',
    permission: 'active'
}]

// Initialize
const rpc = new JsonRpc(ENDPOINTS)

const api = new Api({
   rpc,
   signatureProvider: new JsSignatureProvider([PRIVATE_KEY])
})

const transact = (actions) => api.transact({actions}, {
    blocksBehind: 300,
    expireSeconds: 3000,
})
```

{% endtab %}

{% tab title="Python" %}

```python
import os
from pyeoskit import eosapi, wallet
#import your account private key here
wallet.import_key('mywallet', 'PVT_K1_2fdW4UGdbgG59mUaTiMXLy1rFv3afbmSWEZGWFz6zF8dR1VZPb')

username = "user1"
#For testnet use https://rpc.api.testnet.metalx.com
eosapi.set_node('https://rpc.api.mainnet.metalx.com')
info = eosapi.get_info()
print(info)
```

{% endtab %}
{% endtabs %}


# Submit DEX Order

Below are the samples of submitting/placing order on DEX.

Base Javascript and Python example submits order directly to chain, receiving back execution transaction. Note that the order\_id returned from these examples may change in rare instances, due to blockchain forks or transaction propagation delays.

(Submit API) represents preparing a serialized transaction and signatures and posting to DEX endpoint, this provides order\_id, ordinal\_order\_id and status of the orders created in your transaction. The ordinal order ID is a deterministic ID of the order that is fork and transaction propagation delay resistant.

{% tabs %}
{% tab title="JS" %}

```typescript
// Example: XPR bid token, XMD ask token
// Replace accordingly
const USERNAME = 'pbonblockc'
const authorization = [{ actor: USERNAME, permission: 'active' }]

const BID_TOKEN_CONTRACT = 'eosio.token'
const BID_TOKEN_SYMBOL = 'XPR'
const BID_TOKEN_PRECISION = 4
const BID_AMOUNT = 700      // Amount of XPR to use for sell order

const ASK_TOKEN_CONTRACT = 'xmd.token'
const ASK_TOKEN_SYMBOL = 'XMD'
const ASK_TOKEN_PRECISION = 6
const ASK_AMOUNT = 10       // Amount of XMD to use for buy order

const MARKET_ID = 1         // Unique ID of market
const PRICE = 0.0021        // Price of XPR/XMD to place order at
const ORDER_SIDE = 2        // Buy = 1, Sell = 2
const ORDER_TYPE = 1        // Limit Order
const FILL_TYPE = 0         // Good Till Cancel

const [tokenContract, tokenSymbol, tokenPrecision, amount] =
    ORDER_SIDE === 1
        ? [ASK_TOKEN_CONTRACT, ASK_TOKEN_SYMBOL, ASK_TOKEN_PRECISION, ASK_AMOUNT]
        : [BID_TOKEN_CONTRACT, BID_TOKEN_SYMBOL, BID_TOKEN_PRECISION, BID_AMOUNT]

// Transaction actions
const actions = [
    {
        account: tokenContract,
        name: 'transfer',
        data: {
            from: USERNAME,
            to: 'dex',
            quantity: `${amount.toFixed(tokenPrecision)} ${tokenSymbol}`,
            memo: ''
        },
        authorization
    },
    {
        account: 'dex',
        name: 'placeorder',
        data: {
            market_id: MARKET_ID,
            account: USERNAME,
            order_type: ORDER_TYPE,
            order_side: ORDER_SIDE,
            fill_type: FILL_TYPE,
            bid_symbol: {
                sym: `${BID_TOKEN_PRECISION},${BID_TOKEN_SYMBOL}`,
                contract: BID_TOKEN_CONTRACT
            },
            ask_symbol: {
                sym: `${ASK_TOKEN_PRECISION},${ASK_TOKEN_SYMBOL}`,
                contract: ASK_TOKEN_CONTRACT
            },
            referrer: '',
            
            // Raw amount without precision (700.0000 XPR -> 7000000)
            quantity: (amount * Math.pow(10, tokenPrecision)).toFixed(0),
            // Raw ask price without precision, 6 in case of XMD (0.0021 -> 2100)
            price: (PRICE * Math.pow(10, ASK_TOKEN_PRECISION)).toFixed(0),
            // Trigger order price (0 if not trigger order)
            trigger_price: 0
        },
        authorization
    },
    {
        account: 'dex',
        name: "process",
        data: {
            q_size: 20,
            show_error_msg: 0
        },
        authorization
    }
]

const main = async () => {
    await transact(actions)
}
main()
```

{% endtab %}

{% tab title="JS (Submit API)" %}

```javascript
const { JsonRpc, Api, JsSignatureProvider } = require('@proton/js')
const fetch = require('node-fetch');

// For testnet use https://rpc.api.testnet.metalx.com
const ENDPOINTS = [
   'https://rpc.api.mainnet.metalx.com',
]

// For testnet use "https://dex.api.testnet.metalx.com/dex/v1/orders/submit"
const url = "https://dex.api.mainnet.metalx.com/dex/v1/orders/submit"

// To export private key from your wallet, follow:
// https://help.xprnetwork.org/hc/en-us/articles/4410313687703-How-do-I-backup-my-private-key-in-the-WebAuth-Wallet-
const PRIVATE_KEY = 'PVT_K1_2fdW4UGdbgG59mUaTiMXLy1rFv3afbmSWEZGWFz6zF8dR1VZPb'

// Initialize
const rpc = new JsonRpc(ENDPOINTS)
const api = new Api({
   rpc,
   signatureProvider: new JsSignatureProvider([PRIVATE_KEY])
})
const transact = (actions) => api.transact({actions}, {
    blocksBehind: 300,
    expireSeconds: 3000,
    broadcast: false,
})

// Example: XPR bid token, XMD ask token
// Replace accordingly
const USERNAME = 'metaltest1'
const authorization = [{ actor: USERNAME, permission: 'active' }]

const BID_TOKEN_CONTRACT = 'eosio.token'
const BID_TOKEN_SYMBOL = 'XPR'
const BID_TOKEN_PRECISION = 4
const BID_AMOUNT = 700      // Amount of XPR to use for sell order

const ASK_TOKEN_CONTRACT = 'xmd.token'
const ASK_TOKEN_SYMBOL = 'XMD'
const ASK_TOKEN_PRECISION = 6
const ASK_AMOUNT = 10       // Amount of XMD to use for buy order

const MARKET_ID = 1         // Unique ID of market
const PRICE = 0.0021        // Price of XPR/XMD to place order at
const ORDER_SIDE = 2        // Buy = 1, Sell = 2
const ORDER_TYPE = 1        // Limit Order
const FILL_TYPE = 0         // Good Till Cancel

const [tokenContract, tokenSymbol, tokenPrecision, amount] =
    ORDER_SIDE === 1
        ? [ASK_TOKEN_CONTRACT, ASK_TOKEN_SYMBOL, ASK_TOKEN_PRECISION, ASK_AMOUNT]
        : [BID_TOKEN_CONTRACT, BID_TOKEN_SYMBOL, BID_TOKEN_PRECISION, BID_AMOUNT]

// Transaction actions
const actions = [
    {
        account: tokenContract,
        name: 'transfer',
        data: {
            from: USERNAME,
            to: 'dex',
            quantity: `${amount.toFixed(tokenPrecision)} ${tokenSymbol}`,
            memo: ''
        },
        authorization
    },
    {
        account: 'dex',
        name: 'placeorder',
        data: {
            market_id: MARKET_ID,
            account: USERNAME,
            order_type: ORDER_TYPE,
            order_side: ORDER_SIDE,
            fill_type: FILL_TYPE,
            bid_symbol: {
                sym: `${BID_TOKEN_PRECISION},${BID_TOKEN_SYMBOL}`,
                contract: BID_TOKEN_CONTRACT
            },
            ask_symbol: {
                sym: `${ASK_TOKEN_PRECISION},${ASK_TOKEN_SYMBOL}`,
                contract: ASK_TOKEN_CONTRACT
            },
            referrer: '',
            
            // Raw amount without precision (700.0000 XPR -> 7000000)
            quantity: (amount * Math.pow(10, tokenPrecision)).toFixed(0),
            // Raw ask price without precision, 6 in case of XMD (0.0021 -> 2100)
            price: (PRICE * Math.pow(10, ASK_TOKEN_PRECISION)).toFixed(0),
            // Trigger order price (0 if not trigger order)
            trigger_price: 0
        },
        authorization
    },
    {
        account: 'dex',
        name: "process",
        data: {
            q_size: 25,
            show_error_msg: 0
        },
        authorization
    }
]

async function main() {
    const { serializedTransaction, serializedContextFreeData, signatures } =  await transact(actions)
    const hexTrx = Buffer.from(serializedTransaction).toString('hex')
    
    const response = await fetch(url, {
        method: 'POST',
        headers: {
            'Content-Type': 'application/json'
        },
        body: JSON.stringify({
            'serialized_tx_hex': hexTrx,
            'signatures': signatures
        }),
    });
    
    const data = await response.json();
    console.dir(data, { depth: null })
}
main()

```

{% endtab %}

{% tab title="Python" %}

```python
import os
import json
import requests
from pyeoskit import eosapi, wallet
from math import pow

# Import your account private key here
wallet.import_key('mywallet', 'PVT_K1_2fdW4UGdbgG59mUaTiMXLy1rFv3afbmSWEZGWFz6zF8dR1VZPb')

# For testnet, use https://rpc.api.testnet.metalx.com
eosapi.set_node('https://rpc.api.mainnet.metalx.com')

# Replace with your account name
USERNAME = 'username'
permission = {USERNAME: 'active'}

# Replace Trade Parameters
BID_TOKEN_CONTRACT = 'eosio.token'
BID_TOKEN_SYMBOL = 'XPR'
BID_TOKEN_PRECISION = 4
BID_AMOUNT = 700  # Amount of XPR to use for sell order

ASK_TOKEN_CONTRACT = 'xmd.token'
ASK_TOKEN_SYMBOL = 'XMD'
ASK_TOKEN_PRECISION = 6
ASK_AMOUNT = 10  # Amount of XMD to use for buy order

MARKET_ID = 1  # Unique ID of market
PRICE = 0.0021  # Price of XPR/XMD to place order at
ORDER_SIDE = 2  # Buy = 1, Sell = 2
ORDER_TYPE = 1  # Limit Order
FILL_TYPE = 0  # Good Till Cancel

if ORDER_SIDE == 1:
    token_contract = ASK_TOKEN_CONTRACT
    token_symbol = ASK_TOKEN_SYMBOL
    token_precision = ASK_TOKEN_PRECISION
    amount = ASK_AMOUNT
else:
    token_contract = BID_TOKEN_CONTRACT
    token_symbol = BID_TOKEN_SYMBOL
    token_precision = BID_TOKEN_PRECISION
    amount = BID_AMOUNT

args1 = {
    'from': USERNAME,
    'to': 'dex',
    'quantity': f'{amount:.{token_precision}f} {token_symbol}',
    'memo': ''
}

args2 = {
    'market_id': MARKET_ID,
    'account': USERNAME,
    'order_type': ORDER_TYPE,
    'order_side': ORDER_SIDE,
    'fill_type': FILL_TYPE,
    'bid_symbol': {
        'sym': f'{BID_TOKEN_PRECISION},{BID_TOKEN_SYMBOL}',
        'contract': BID_TOKEN_CONTRACT
    },
    'ask_symbol': {
        'sym': f'{ASK_TOKEN_PRECISION},{ASK_TOKEN_SYMBOL}',
        'contract': ASK_TOKEN_CONTRACT
    },
    'referrer': '',
    'quantity': int(amount * pow(10, token_precision)),
    'price': int(PRICE * pow(10, ASK_TOKEN_PRECISION)),
    'trigger_price': 0
}

args3 = {
    'q_size': 20,
    'show_error_msg': 0
}

a1 = [token_contract, 'transfer', args1, permission]
a2 = ['dex', 'placeorder', args2, permission]
a3 = ['dex', 'process', args3, permission]

eosapi.push_actions([a1, a2, a3])
```

{% endtab %}

{% tab title="Python (Submit API)" %}

```python
import os
import json
import requests
from pyeoskit import eosapi, wallet
from math import pow

# Import your account private key here
wallet.import_key('mywallet', 'PVT_K1_2fdW4UGdbgG59mUaTiMXLy1rFv3afbmSWEZGWFz6zF8dR1VZPb')

# For testnet, use https://rpc.api.testnet.metalx.com
eosapi.set_node('https://rpc.api.mainnet.metalx.com')

# Replace with your account name
USERNAME = 'username'
permission = {USERNAME: 'active'}

# For testnet use "https://dex.api.testnet.metalx.com/dex/v1/orders/submit"
url = "https://dex.api.mainnet.metalx.com/dex/v1/orders/submit"
headers = {"content-type": "application/json", "Accept-Charset": "UTF-8"}

# Replace Trade Parameters
BID_TOKEN_CONTRACT = 'eosio.token'
BID_TOKEN_SYMBOL = 'XPR'
BID_TOKEN_PRECISION = 4
BID_AMOUNT = 700  # Amount of XPR to use for sell order

ASK_TOKEN_CONTRACT = 'xmd.token'
ASK_TOKEN_SYMBOL = 'XMD'
ASK_TOKEN_PRECISION = 6
ASK_AMOUNT = 10  # Amount of XMD to use for buy order

MARKET_ID = 1  # Unique ID of market
PRICE = 0.0021  # Price of XPR/XMD to place order at
ORDER_SIDE = 2  # Buy = 1, Sell = 2
ORDER_TYPE = 1  # Limit Order
FILL_TYPE = 0  # Good Till Cancel

if ORDER_SIDE == 1:
    token_contract = ASK_TOKEN_CONTRACT
    token_symbol = ASK_TOKEN_SYMBOL
    token_precision = ASK_TOKEN_PRECISION
    amount = ASK_AMOUNT
else:
    token_contract = BID_TOKEN_CONTRACT
    token_symbol = BID_TOKEN_SYMBOL
    token_precision = BID_TOKEN_PRECISION
    amount = BID_AMOUNT

args1 = {
    'from': USERNAME,
    'to': 'dex',
    'quantity': f'{amount:.{token_precision}f} {token_symbol}',
    'memo': ''
}

args2 = {
    'market_id': MARKET_ID,
    'account': USERNAME,
    'order_type': ORDER_TYPE,
    'order_side': ORDER_SIDE,
    'fill_type': FILL_TYPE,
    'bid_symbol': {
        'sym': f'{BID_TOKEN_PRECISION},{BID_TOKEN_SYMBOL}',
        'contract': BID_TOKEN_CONTRACT
    },
    'ask_symbol': {
        'sym': f'{ASK_TOKEN_PRECISION},{ASK_TOKEN_SYMBOL}',
        'contract': ASK_TOKEN_CONTRACT
    },
    'referrer': '',
    'quantity': int(amount * pow(10, token_precision)),
    'price': int(PRICE * pow(10, ASK_TOKEN_PRECISION)),
    'trigger_price': 0
}

args3 = {
    'q_size': 20,
    'show_error_msg': 0
}

a1 = [token_contract, 'transfer', args1, permission]
a2 = ['dex', 'placeorder', args2, permission]
a3 = ['dex', 'process', args3, permission]

# Generate packed transaction
info = eosapi.get_info()
final_tx = eosapi.generate_packed_transaction(
    [a1, a2, a3],
    60,
    info['last_irreversible_block_id'],
    info['chain_id']
)
mtx = json.loads(final_tx)

# Print transaction details
print('\nSignature:', mtx["signatures"], '\nPacked Tx:', mtx["packed_trx"])

# Submit transaction
payload = {
    "serialized_tx_hex": mtx["packed_trx"],
    "signatures": mtx["signatures"]
}

response = requests.post(url, json=payload, headers=headers)
data = response.json()

# Print response data
print(data)

```

{% endtab %}
{% endtabs %}


# Cancel DEX Order

{% tabs %}
{% tab title="JS" %}

```javascript
const actions = [
  {
      // Dex Smart Contract
      "account": "dex",
      // Action name
      "name": "cancelorder",
      // Action data
      "data": {
        "account": username,
        "order_id": 23
      },
      authorization
  },
  {
      account: 'dex',
      name: "withdrawall",
      data: {
          account: username,
      },
      authorization
  },
]

const main = async () => {
     await transact(actions)
}

main()
```

{% endtab %}

{% tab title="JS (Submit API)" %}

```javascript
// npm i @proton/js node-fetch@cjs
const { JsonRpc, Api, JsSignatureProvider, Serialize } = require('@proton/js')
const fetch = require('node-fetch');

// For testnet use https://rpc.api.testnet.metalx.com
const ENDPOINTS = ['https://rpc.api.mainnet.metalx.com']

// for testnet use https://dex.api.testnet.metalx.com/dex
const DEX_API_URL = "https://dex.api.mainnet.metalx.com/dex"

// To export private key from your wallet, follow:
// https://help.xprnetwork.org/hc/en-us/articles/4410313687703-How-do-I-backup-my-private-key-in-the-WebAuth-Wallet-
const PRIVATE_KEY = 'PVT_K1_2fdW4UGdbgG59mUaTiMXLy1rFv3afbmSWEZGWFz6zF8dR1VZPb'

// Initialize
const rpc = new JsonRpc(ENDPOINTS)
const signatureProvider = new JsSignatureProvider([PRIVATE_KEY])
const api = new Api({ rpc, signatureProvider })

// Example username, replace with your own
const USERNAME = 'metaltest1'
const authorization = [{ actor: USERNAME, permission: 'active' }]

// Cancel transaction builder
const buildCancelTransaction = orderId => {
  return {
    actions: [
      {
          account: 'dex',
          name: 'cancelorder',
          data: {
            account: USERNAME,
            order_id: orderId
          },
          authorization
      },
      {
          account: 'dex',
          name: 'withdrawall',
          data: {
              account: USERNAME,
          },
          authorization
      },
    ]
  }
}

async function main() {
  // Get order by ordinal ID
  const EXAMPLE_ORDINAL_ORDER_ID = '7fc4fbef0abcc61bebb8fcc0327bf7bb50d9fb77eaa92b876d0985845475a1f3'
  const orderHistoryResponse = await fetch(`${DEX_API_URL}/v1/orders/history?account=${USERNAME}&ordinal_order_ids=${EXAMPLE_ORDINAL_ORDER_ID}`);
  const { data: orders } = await orderHistoryResponse.json()

  // Build transaction (using first order ID for example)
  const transaction = buildCancelTransaction(orders[0].order_id)

  // Sign
  const { serializedTransaction, signatures } = await api.transact(transaction, {
    blocksBehind: 300,
    expireSeconds: 3000,
    broadcast: false
  })
    
  // Submit transaction
  const submitResponse = await fetch(`${DEX_API_URL}/v1/orders/submit`, {
      method: 'POST',
      headers: {
          'Content-Type': 'application/json'
      },
      body: JSON.stringify({
          serialized_tx_hex: Buffer.from(serializedTransaction).toString('hex'),
          signatures: signatures
      }),
  });
  const submitData = await submitResponse.json()
  console.dir(submitData, { depth: null })
}
main()
```

{% endtab %}

{% tab title="Python" %}

```python
args1 = {
        # Trading account
        "account": "user1",
        # ID of order
        "order_id": 1765,
}
args2 = {
        # Trading account
        "account": "user1",
}

permission = {'user1':'active'}

a1 = ['dex', 'cancelorder', args1, permission]
a2 = ['dex', 'withdrawall', args2, permission]

eosapi.push_actions([a1, a2])
```

{% endtab %}

{% tab title="Python (Submit API)" %}

```
# Cancel Order example

import os
import json
import requests
from pyeoskit import eosapi, wallet
#import your account private key here
wallet.import_key('mywallet', 'PVT_K1_2fdW4UGdbgG59mUaTiMXLy1rFv3afbmSWEZGWFz6zF8dR1VZPb')
#For testnet use https://rpc.api.testnet.metalx.com
eosapi.set_node('https://rpc.api.mainnet.metalx.com')

USERNAME = 'otctest'
ORDERID = 000000

# for testnet use "https://dex.api.testnet.metalx.com/dex/v1/orders/submit"
url = "https://dex.api.mainnet.metalx.com/dex/v1/orders/submit"
headers = {"content-type": "application/json", "Accept-Charset": "UTF-8"}
permission = {USERNAME: 'active'}

args1 = {
        # Trading account
        'account': USERNAME,
        # ID of order
        "order_id": ORDERID,
}
args2 = {
        # User account
        'account': USERNAME,
}

a1 = ['dex', 'cancelorder', args1, permission]
a2 = ['dex', 'withdrawall', args2, permission]

info = eosapi.get_info()
final_tx = eosapi.generate_packed_transaction(
    [a1, a2],
    60,
    info['last_irreversible_block_id'],
    info['chain_id']
)

mtx = json.loads(final_tx)
# Print transaction details
print('\nSignature: ', mtx["signatures"], '\nPacked Tx: ',  mtx["packed_trx"])

# Submit transaction
payload = {
    "serialized_tx_hex": mtx["packed_trx"],
    "signatures": mtx["signatures"]
}

r = requests.post(url,  json=payload, headers=headers)
data = r.json()


print(data)
```

{% endtab %}
{% endtabs %}


# Order Lifecycle

Belos is the script to fetch order lifecyle using ordinal order id

{% tabs %}
{% tab title="JS" %}

```javascript
const fetch = require('node-fetch');

// for testnet use "https://dex.api.testnet.metalx.com/dex"
const url = "https://dex.api.mainnet.metalx.com/dex"

async function main() {
    // Replace accordingly
    const ORDINAL_ID = "81321dc485b5dd8053c4b7d0c90273ce72645b4127524d1745aebe8b4f795e21"

    const path = "/v1/orders/lifecycle"
    const response = await fetch(`${url}${path}?ordinal_order_id=${ORDINAL_ID}`);
    
    const data = await response.json()
    console.dir(data, { depth: null })
}
main()
```

{% endtab %}

{% tab title="Python" %}

```python
import requests

# Supply ordinal order id
ORDINALID = '7c58750548702a4a8dc30aebe21fb1885923b7db42dbe81239f5a64e672b82d7'
url = f"https://dex.api.mainnet.metalx.com/dex/v1/orders/lifecycle?ordinal_order_id={ORDINALID}"

headers = {"accept": "application/json"}

response = requests.get(url, headers=headers)

print(response.json())
```

{% endtab %}
{% endtabs %}


# Audit

Below is the audit report from slowmist for the DEX contracts

{% file src="/files/HgAxyHZklE4kIl4qwAZd" %}


# Oracles

Oracles provide the current market prices for all tokens. These oracles access data through feeds for live price information. The current market price of a token is used to calculate the 30-day average volume of the user which in turn calculates the [discount in fees](/dex/what-is-metal-x/dex-fees-and-discounts).


# What is Metal X Swap?

Metal X Swap is an automated market maker (AMM) that allows users to instantly swap XPR Network-based tokens between each other. Users also have the ability to convert supported tokens from different blockchains to XPR Network-based tokens and vice versa. For example, using Metal X Swap, a user can swap XBTC for XUSDT, or convert ETH to XETH before trading it for XPR.

This allows seamless transactions between blockchains due to the speed and flexibility of the XPR Network blockchain. The more liquidity that exists between the pair of tokens being swapped, the lower the slippage will be.

### **What is a wrapped asset or token?**

A wrapped token is an asset hosted on a different blockchain with a price that is the same as the underlying asset, even if it’s not on the same blockchain. A wrapped token holds the identical value to another asset that it represents, either through a smart contract or by being backed one-to-one with the underlying asset.

### **What is the advantage of an XPR-wrapped token?**

When a token becomes wrapped and converted to the XPR Network, it enjoys every benefit that native XPR Network tokens enjoy. That means instant transaction times, industry-low gas fees, and so much more. For example, while it’s nearly impossible to send one satoshi of regular BTC due to the gas fees associated with that blockchain, one satoshi of XBTC can easily and rapidly be sent to other wallets. This same logic applies for other Proton-wrapped tokens as well.

## Learn more about the XPR Network blockchain

Learn more about the XPR Network and ecosystem in our overview.

{% content-ref url="/pages/A7H4BNmc28m4vCeKMiQ9" %}
[XPR Network & Ecosystem](/xpr-network/xpr-network-and-ecosystem)
{% endcontent-ref %}

## Metal X Swap FAQ

Check out the most frequently asked questions here with answers.

{% content-ref url="/pages/fXrT0NdrymYjyDmDXxil" %}
[Metal X Swap FAQ](/swap-pools-and-farms/what-is-metal-x-swap/metal-x-swap-faq)
{% endcontent-ref %}

## Guides: Get Started On Metal X Swap

Follow our handy guides to get started:&#x20;

* [Swaps](https://help.proton.org/hc/en-us/sections/8000609730839-Swap-and-OTC)
* [Pools and farming](https://help.proton.org/hc/en-us/sections/8000567613079-Pool-Farming-and-Staking)


# Trading Interface

### Trading Chart

<figure><img src="https://1068387139-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F2KWLHP2zE3VO3AoelaSy%2Fuploads%2FwBMVUozto12vPGMviVsM%2FScreenshot%202022-11-14%20at%206.52.20%20PM.png?alt=media&amp;token=22edf993-617f-414b-b6cd-83455c308586" alt=""><figcaption></figcaption></figure>

The chart can be set to daily, weekly, yearly, or all-time views for price and liquidity.&#x20;

### Trading

<div align="left"><figure><img src="https://1068387139-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F2KWLHP2zE3VO3AoelaSy%2Fuploads%2FMGHO9dbkE7ql9UycNlXB%2FScreenshot-2022-11-14-at-7.09.33-PM.jpg?alt=media&amp;token=54a86ce9-96c0-40f6-9dee-7e4b75ba01ad" alt=""><figcaption></figcaption></figure></div>

Here you can select a token you want to exchange "from" and "to" from the list of available tokens and select the amount you want to trade.&#x20;

In this example, we're buying XPR with METAL. To complete a trade, click on the Swap button and open your wallet to verify and authorize the transaction.

**Minimum received:** you will at least receive the minimum amount that is displayed here. If not, the trade will fail.

**Price impact:** The difference between the market price and the estimated price due to trade size.

**Liquidity:** Displays the amount of liquidity on the on-chain AMM pool.

### Swapping Guide

Check out how to [swap with the Webauth wallet here.](https://help.xprnetwork.org/hc/en-us/articles/4410313183895-How-do-I-use-Swap-with-the-WebAuth-Wallet)


# Swap fees and discounts

The per-trade fee on Metal X Swap is 0.3% and is split as follows:

**Liquidity incentives:**

0.2% of every trade goes to the liquidity providers (LPs) of that pool.

**XPR burns:**

0.1% from every transaction are converted to XPR and burned or added to XPR Grants at the end of each quarter.&#x20;

### Discounts

Metal X Swap offers discounts based on the amount of XPR that is staked on the XPR Network.

| Staked XPR   | Discount |
| ------------ | -------- |
| ≥ 100,000    | 33%      |
| ≥ 1,000,000  | 66%      |
| ≥ 10,000,000 | 100%     |


# Liquidity Pools

Liquidity pools allow decentralized trading of cryptocurrencies to happen without the need for a centralized authority to hold reserves of both assets.&#x20;

Adding liquidity to the trading pool on Metal X Swap allows you to earn a percentage of any fees generated by the use of your tokens. You need to add the same value in USD to both sides of the pair.

Liquidity Providers earn 0.2% of every trade; the amount of crypto that you earned of this 0.2% is proportional to the amount of cryptocurrency that you provide to the traded pool.&#x20;

For example, let’s say there is a liquidity pool already in existence for the trading pair XUSDC and XPR, and the pool currently stands at 9,000 XUSDC and 900,000 XPR. You enter this liquidity pool, adding 1,000 XUSDC and 100,000 XPR. Since you’ve now added 10% of that liquidity pool’s total value, you’ll earn 10% of the 0.2% of fees generated by that pool.

When you withdraw your LP tokens from the [Pools](https://app.metalx.com/pools), you will receive the fees you earned.

### Lockup period

You can withdraw from the farms and liquidity pools at any time, there is no lockup period.

### Impermanent loss

Impermanent loss can occur when the price of your tokens changes compared to when you deposited them in the pool. The larger the change is, the bigger the loss. You can learn more about[ impermanent loss in this article](https://www.blockchain-council.org/defi/impermanent-loss/).

### How to become a liquidity provider on and earn fees

Check out the [support article here](https://help.xprnetwork.org/hc/en-us/articles/4412514091543-How-to-add-to-a-Liquidity-Pool-and-receive-LP-tokens).

### **Farming liquidity pool tokens**

Some pools also have a farming option, allowing you to stake the liquidity pool tokens and earn an APR. More on that in [the farming section.](/swap-pools-and-farms/what-is-metal-x-swap/farming)


# Farming

Yield farming involves you becoming a [liquidity provider](/swap-pools-and-farms/what-is-metal-x-swap/liquidity-pools) and locking your cryptocurrency into a smart contract tied to a liquidity pool in the form of liquidity provider tokens, earning you interest in the process.

<figure><img src="https://1068387139-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F2KWLHP2zE3VO3AoelaSy%2Fuploads%2Fzu7iXsUOp23EdSvYzfZj%2Fimage.png?alt=media&amp;token=43967fce-cb00-4f28-add5-9dbde0bdf85f" alt=""><figcaption></figcaption></figure>

On the farms page you can view the following:&#x20;

* All available farms
* APR for all farms
* Total staked per farm
* Total amount you staked per farm
* Total amount you earned per farm&#x20;

<figure><img src="https://1068387139-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F2KWLHP2zE3VO3AoelaSy%2Fuploads%2FBZZEKf4I7AtkZYlIWAuB%2Fimage.png?alt=media&amp;token=c9d24efe-8d04-44e6-87ca-5a2142c85212" alt=""><figcaption></figcaption></figure>

If you click on a specific farm, you will see the breakdown of how much liquidity you provided.

You can also harvest rewards here at any time, every 0.5 seconds.

### Staking period

You can withdraw from the farms and liquidity pools at any time, there is no lockup period.

### Farming APR

The APR rate is variable, the rate can change if the total staked amount changes. If more is staked, then the rate will drop, if less is staked then the rate will go up.&#x20;

The rate can also change if the USD value of the reward token changes. if the price of the reward token increases, the rate will go up, if it goes down, the rate will go down.

### Farming guides

Check out our [farming guide here](https://help.xprnetwork.org/hc/en-us/articles/6305251276567-How-to-add-LP-tokens-to-Farming).


# Metal X Swap FAQ

### **What pairs are available to trade on Metal X Swap?**

The following pairs are available:

* XPR
* XUSDC
* XBTC
* XETH
* XDOGE
* XBCH
* XLTC
* XUSDT
* XUNI
* XBNB
* XEOS
* XADA
* METAL
* XMT
* LOAN
* STRX
* MINT
* SNIPS
* XLUNR

### How do I start using Metal X Swap?

The first step is creating a free XPR Network account, which can be done on the Webauth Wallet that is available on [Android](https://play.google.com/store/apps/details?id=com.metallicus.webauth), [iOS](https://apps.apple.com/us/app/webauth-com/id1594500069) and [web](https://webauth.com/). You can then deposit supported cryptos to the WebAuth.com wallet and connect your wallet to Metal X.&#x20;

### **What wallet should I use to use Metal X Swap?**

You can use any wallet that supports the XPR Network. We recommend using the WebAuth  Wallet that is available on [Android](https://play.google.com/store/apps/details?id=com.metallicus.webauth), [iOS](https://apps.apple.com/us/app/webauth-com/id1594500069) and [web](https://webauth.com/).&#x20;

### **Is it true that there are no gas or transaction fees to use Metal X Swap?**

The XPR Network charges no gas or mining fees to end-users – transactions on XPR Network are free.&#x20;

Metal X Swap does have [trading fees that can be reduced](https://www.docs.protondex.com/fundamentals/dex-fees-and-discounts).

### Do I need to verify my identity to use Metal X Swap?

Metal X requires that US residents verify their identity in order to safeguard the integrity of the platform and reduce the risk of fraud, money laundering, terrorist financing, and the violation of sanctions. As such US residents will need to verify their identity, to use the platform.

In order to deposit and withdraw funds to/from other blockchains using the WebAuth wallet, verifying your identity is mandatory for everyone.


# Staking on Metal X

The **Staking** [page](https://app.metalx.com/staking) on Metal X allows users to earn protocol rewards by staking supported assets directly on-chain. Staking helps secure underlying networks and protocols while generating yield for participants.

Metal X currently supports staking for:

* **LOAN** (fixed-term staking)
* **XPR** (flexible staking)

All staking activity is non-custodial and executed via smart contracts on XPR Network.

<figure><img src="https://1068387139-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F2KWLHP2zE3VO3AoelaSy%2Fuploads%2FDbF6mp9eVc21MOfO9vlD%2FScreenshot%202026-01-24%20at%2010.42.11%E2%80%AFAM.png?alt=media&amp;token=c7b0a190-1744-4be8-b12e-b727c4cb5c3e" alt=""><figcaption></figcaption></figure>

***

### Accessing the Staking Page

To access staking on Metal X:

1. Navigate to [**app.metalx.com**](https://app.metalx.com/)
2. Select **Stake** from the main navigation
3. Connect your wallet if prompted

The staking dashboard provides a summary of:

* Total value staked
* Net APR across all positions
* Unclaimed rewards
* Active and matured staking positions

***

### Staking Overview

#### My Staked Assets

At the top of the page, users can view:

* **Total Staked** – Total USD value of all active staking positions
* **Net APR** – Weighted average APR across all staked assets
* **Rewards** – Accrued staking rewards available to claim

Rewards can be claimed at any time, subject to the rules of each staking product.


# Stake LOAN (Fixed Term)

LOAN staking uses a **fixed-term model** where tokens are locked for a selected duration in exchange for rewards.

<figure><img src="https://1068387139-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F2KWLHP2zE3VO3AoelaSy%2Fuploads%2FW2Gq0mCE19WW1JbjpPTV%2FScreenshot%202026-01-24%20at%2010.35.56%E2%80%AFAM.png?alt=media&amp;token=ef488d8b-5fd1-4709-af56-c5b128cf53e0" alt=""><figcaption></figcaption></figure>

#### How LOAN Staking Works

* When LOAN is staked, it is wrapped into **sLOAN**
* sLOAN accrues LOAN rewards over time
* Tokens remain locked until the selected term ends
* Upon unstaking, sLOAN is automatically unwrapped back into LOAN

#### Key Features

* **Term:** Fixed
* **APR:** Variable (displayed at time of staking)
* **Lockup:** 7 days up to 4 years
* **Reward Multiplier:** Longer lockups receive higher multipliers (up to 4×)
* **Governance:** Staked LOAN can be used for [governance voting](https://gov.xprnetwork.org/communities/5)

#### Staking LOAN

<div align="left"><figure><img src="https://1068387139-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F2KWLHP2zE3VO3AoelaSy%2Fuploads%2FtYnGeKrdOYd5jCFEbOQs%2FScreenshot%202026-01-24%20at%2010.45.15%E2%80%AFAM.png?alt=media&amp;token=8c09043e-23f1-45d6-8615-d07dcb450e21" alt="" width="375"><figcaption></figcaption></figure></div>

1. Select **Stake LOAN** (click [details](https://app.metalx.com/staking/LOAN) or stake)
2. Enter the amount of LOAN to stake
3. Choose a lockup duration
4. Review APR and multiplier
5. Confirm the transaction

Once staked, tokens cannot be withdrawn until the lockup period expires.

#### Unstaking LOAN

* Fixed-term positions automatically mature at the end of the selected term
* Matured positions can be unstaked from [**My Positions**](https://app.metalx.com/staking?tab=user#assets-content)
* Upon unstaking, LOAN and accrued rewards are returned to your wallet


# Stake XPR (Flexible)

XPR staking uses a **flexible staking model** designed to help secure the XPR Network.

<figure><img src="https://1068387139-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F2KWLHP2zE3VO3AoelaSy%2Fuploads%2F735LXfAfWktTBk60T8tz%2FScreenshot%202026-01-24%20at%2010.36.20%E2%80%AFAM.png?alt=media&amp;token=53615674-fcc1-45fc-9696-c1232cab57c5" alt=""><figcaption></figcaption></figure>

#### How XPR Staking Works

* XPR can be staked without a fixed end date
* Rewards accrue continuously and are paid in XPR
* Stakers must vote for Block Producers
* Unstaking requires a short 24 hour unlock period

#### Key Features

* **Term:** Flexible
* **APR:** Variable
* **Unstaking:** Available at any time after a 24-hour unlock
* **Block Producers:** Minimum of 4 must be selected

#### Staking XPR

<div align="left"><figure><img src="https://1068387139-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F2KWLHP2zE3VO3AoelaSy%2Fuploads%2FjSysVkDxQUEjiv8bxdvY%2FScreenshot%202026-01-24%20at%2010.48.11%E2%80%AFAM.png?alt=media&amp;token=94859695-ddcb-4264-9621-5159e30c5f37" alt="" width="375"><figcaption></figcaption></figure></div>

1. Select **Stake XPR** (click [details](https://app.metalx.com/staking/XPR) or stake)
2. Enter the amount of XPR to stake
3. Choose at least 4 Block Producers
4. Confirm the transaction

Your selected Block Producers do not affect your reward rate.

#### Unstaking XPR

* Initiate unstaking from the **Manage** panel
* Tokens enter a 24-hour unlock period
* After unlock, XPR can be withdrawn back to your wallet

***

### Historical Rates

Each staking asset includes a **Historical Rates** chart showing past APR performance.

* Rates are shown for reference only
* Historical APR does not guarantee future returns
* Users can view 7D, 30D, 90D, or all-time data


# My Positions

The **My Positions** [page](https://app.metalx.com/staking?tab=user#assets-content) provides a detailed view of all your active and completed staking positions on Metal X. This page is designed to help you track individual stakes, manage unstaking, and claim rewards.

Each staking position is listed separately, even if multiple positions use the same asset.

<figure><img src="https://1068387139-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F2KWLHP2zE3VO3AoelaSy%2Fuploads%2F64l8r8HUsYjXXR7V2rOA%2FScreenshot%202026-01-24%20at%2010.50.13%E2%80%AFAM.png?alt=media&amp;token=908ed854-ecb7-4ff0-9ff1-995652066b6d" alt=""><figcaption></figcaption></figure>

### Positions Overview

At the top of the page, users can view a summary of their staking activity, including:

* **Total Staked** – Combined USD value of all active staking positions
* **Net APR** – Weighted average APR across all positions
* **Rewards** – Total unclaimed rewards available to claim

Rewards displayed here may include rewards from multiple staking products.

***

### Position Table

Each row in the **My Positions** table represents a single staking position and includes the following details:

#### Staked Asset

Displays:

* Asset name and icon (e.g. XPR, LOAN)
* Amount staked
* Estimated USD value at current prices

#### Term

Indicates the staking model used for the position:

* **Fixed** – Tokens are locked until a specified end date
* **Flexible** – Tokens can be unstaked at any time after an unlock period

#### APR

The APR associated with that specific staking position at the time it was created.

> APRs are variable and shown for reference. Future rewards are not guaranteed.

#### Status

Shows the current state of the position, such as:

* **Active** – Position is currently earning rewards
* **Available to Unstake** – Lockup period has ended and tokens can be withdrawn
* **Available to Claim** – Rewards are available to be claimed
* **Unstaking** – Tokens are in an unlock period (if applicable)

#### Actions

Available actions depend on the position’s status:

* **Claim** – Claim accrued rewards
* **Unstake** – Withdraw staked assets after lockup or unlock period

***

### Fixed-Term Positions (LOAN)

* Fixed-term positions cannot be unstaked early
* Once the lockup period ends, the position will display **Available to Unstake**
* Unstaking returns the original LOAN plus any accrued rewards
* Each fixed-term stake is treated as a unique position

Users may have multiple fixed-term positions with different APRs and lockup durations.

***

### Flexible Positions (XPR)

* Flexible positions remain active until the user initiates unstaking
* Rewards can be claimed independently of unstaking
* When unstaking is initiated, the position enters a short unlock period
* After the unlock period, XPR can be withdrawn back to the wallet

***

### Claiming Rewards

* Rewards can be claimed directly from the **My Positions** table
* Claiming rewards does not affect the staked principal
* Claimed rewards are sent directly to your connected wallet

***

### Important Notes

* Each staking position is tracked independently
* APRs may differ between positions, even for the same asset
* Historical positions may remain visible for reference
* All staking actions are executed on-chain

Always review position details before unstaking or claiming rewards.


# Tables

**TABLE `global`**

* `{name} fee_contract`: the name of the account that hold the fees, by default it sets to fee.metal
* `{`uint16\_t`} last_market_id`: indicates last market id(id of the pair) that was created
* `{`uint64\_t`} last_order_id`: indicates last order id that was created(used to keep track order count and assign unique ids)
* `{`uint64\_t`} last_trade_id`: indicates last trade id that was created(used to keep track trades  and assign unique ids)
* `{`uint8\_t`} contract_status`: to keep track of the contract status

#### example

```
{
  "fee_contract": "fee.metal",
  "last_market_id": "1",
  "last_order_id": "5",
  "last_trade_id": "2",
  "contract_status": "0"
}
```

#### TABLE `Markets`

* `{`uint16\_t`} market_id`: id of the market pair.
* `{`uint64\_t`} order_min`: min quantity to be placed for trade
* `{status_code} status_code`: represents status of the market id(can be ACTIVE, INACTIVE, NOTINUSE, DISABLE\_ORDERS\_FILLS, DISABLE\_ORDERS and DISABLE\_FILLS)
* `{`uint64\_t`} ask_oracle_index`: index of the oracles to get current price of the token
* `{extended_symbol} bid_token`: represents the bid value
* `{extended_asset} ask_token`: represents ask token in the form of extended asset
* `{extended_asset} total_reserves`: total reserves

```
{
    "bid_token": {
        "sym": "4,XMT",
        "contract": "eosio.token"
    },
    "ask_token": {
        "quantity": "1.361708 XUSDC",
        "contract": "eosio.token"
    },
    "order_min": 10,
    "status_code": 1,
    "ask_oracle_index": 1
}
```

#### TABLE `Balances`

* `{name} account`: user account for the funds/tokens
* `{vector<extended_asset>}` balances: balance of each token that holds by user/trader

#### example

```
{
  account: 'trader',
  balances: [
    { quantity: '1000.000000 XUSDC', contract: eosioTokenContract.name.toString() }
  ]
}
```

#### TABLE `OrderQ`

`This table stores all placed orders`

* `{int64_t} order_id:`id of the order that was placed.
* `{uint16_t} market_id`: id of the market pair.
* `{uint64_t} quantity`: represents how much quantity to buy/sell
* `{uint64_t} price`: price of the trade
* `{name} account_name`: represents account name of the trader
* `{uint8_t} order_side`: buy or sell
* `{uint8_t} order_type`: type of order, can be LIMIT, STOPLOSS and TAKEPROFIT
* `{uint64_t} trigger_price`: price at which order triggered to new state, applicable for both  stop loss and take profit
* `{uint8_t} fill_type`: order fill types like GTC(Good Till expiry), IOC(Immediate or Cnacel) and Post\_Only(used to provide liquidity)

```
    {
      "account_name": "collector",
      "market_id": 1,
      "order_id": 1,
      "order_side": orderSide.SELL,
      "order_type": orderType.LIMIT,
      "price": 16374242,
      "quantity": 200000000,
      "fill_type": 0,
      "trigger_price": 0
    },
    {
      "account_name": "bob",
      "market_id": 1,
      "order_id": 2,
      "order_side": orderSide.BUY,
      "order_type": orderType.LIMIT,
      "price": 16384000,
      "quantity": 49152000,
      "fill_type": 0,
      "trigger_price": 0
    }
```

#### TABLE `Order`

`This table represents current order book`

* `{int64_t} order_id:`id of the order that was placed.
* `{uint16_t} market_id`: id of the market pair.
* `{uint64_t} quantity`: represents how much quantity to buy/sell
* `{uint64_t} price`: price of the trade
* `{name} account_name`: represents account name of the trader
* `{uint8_t} order_side`: buy or sell

```
  {
    "account_name": "collector",
    "market_id": 1,
    "order_id": 5,
    "order_side": 2,
    "price": 16340000,
    "quantity": 199877601
  }
```

#### TABLE `Fees`

* `{name} account_name`: user account to store fee related information
* `{name} referrer_name`: name of the account who referred&#x20;
* `{time_point} referrer_ends`: referral's end time&#x20;
* `{double} volume_avg_30d`: users's 30 day's average traded volume
* `{time_point} volume_avg_last_update`: time at which 30d avg volume updated
* `{uint8_t} tier`: tier of the user, can be set through Action also

#### example

```
{
  "account_name": "fee.metal",
  "referrer_name": "alice",
  "referrer_ends": "1696022087",
  "volume_avg_30d": "1'005'000.00",
  "volume_avg_last_update": "1664986087",
  "tier": "1"
}
```

#### TABLE `Currency_stats`

* `{asset} supply`: supply&#x20;
* `{asset} max_supply`: max supply of the token
* `{name} issuer`: issuer account name

#### example

```
{
  "supply": "500000",
  "max_supply": "10000000",
  "name": "alice"
}
```

#### TABLE voters\_xpr

* `{name} owner`: user account holding xpr
* `{uint64_t} staked`: staked amount
* `{bool} isqualified`: qualified flag
* `{uint64_t} claimamount`: total amount claim
* `{uint64_t} lastclaim`: last claim amount
* `optional{uint64_t} startstake`: the last stake amount

#### example

```
{
  "owner": "alice",
  "staked": "1000000",
  "isqualified": "1",
  "claimamount": "50000",
  "lastclaim": "10000",
  "strtstake": "5000"
}
```

#### TABLE assets\_s

* `{uint64_t} asset_id`: unique id of the nft asset
* `{name} collection_name`: name of the collection
* `{name} schema_name`: name of the schema to store details
* `{uint32_t} template_id`: template used to mint this nft asset
* `{name} ram_payer`: account to pay for the transaction
* `vector<{asset}> backed_tokens`: list of tokens backed this asset
* `vector<{uint8_t}> immutable_serilized_data`: immutable data to be serialized
* `vector<{uint8_t}> mutable_serilized_data`: mutable data to be serialized

#### example

```
{
  "asset_id": "1099511627776",
  "collection_name": "bullscollect",
  "schema_name": "bulls",
  "template_id": "5",
  "ram_payer": "alice",
  "backed_tokens": {'5000, xpr', '400, XMT'},
  "immutable_serilized_data": 
  "mutable_serilized_data":
}
```

<br>


# Actions

#### CREATEMARKET

Creates a new market for the token pair.

This action is triggered by admin to create the market pair.

* **authority**: `admin`
* **requirements**: none

**args**

* `{extended_symbol} bid_token`: extended symbol of the buy token to create token pair
* `{extended_asset} ask_token`: extended asset of the sell token to create token pair
* `{uint16_t} order_min`: min order to place
* `{uint8_t} status_code`: status code of the market pair
* `{uint64_t} ask_oracle_index`: index of the oracle to get price of token from feed

**example**

```
{
  "account": "metalpay",
  "name": "createmarket",
  "data": {
    "bid_token": {
      "quantity": "4.0000 XPR",
      "contract": "eosio.token"
    },
    "ask_token": {
      "sym": "4.0000 XMT",
      "contract": "xtokens"
    },
    "order_min": "10",
    "status_code": "1",
    "ask_oracle_index": "1"
  }
}
```

#### UPDATEMARKET

Update an exisitng market for status change or min order.

* **authority**: `admin`
* **requirements**: market id should be existed for an update&#x20;

**args**

* `{uint16_t} market_id`: id of the token pair to update
* `{uint64_t} order_min`: min order to place
* `{uint8_t} status_code`: status code of the market
* `{uint64_t} ask_oracle_index`: index of the oracle to get price of token from feed

**example**

```
{
  "account": "admin",
  "name": "updatemarket",
  "data": {
    "market_id": "2",
    "order_min": "10",
    "status_code": "3",
    "ask_oracle_index": "2",
  }
}
```

#### PLACEORDER

Creates a new order and place it into orderq or sltp table.

This action is triggered by any user who has sufficient funds to trade token pairs.

* **authority**: `user`
* **requirements**: none

**args**

* `{uint16_t} market_id`: id of the token pair
* `{name} account`: name of the account holder who would like to buy/sell
* `{uint8_t} order_type`: type of order, LIMIT(1), STOPLOSS(2) or TAKEPROFIT(3)
* `{uint8_t} order_side`: indicates order side is BUY(1)/SELL(2)
* `{uint64_t} quantity`: quantity to be traded
* `{uint64_t} price`: quoted price by the user
* `{extended_symbol} bid_symbol`: extended symbol of the buy token from the market id(token pair)
* `{extended_symbol} ask_symbol`: extended symbol of the ask token from the market id(token pair)
* `optional{uint64_t} trigger_price`: price at which order triggered from sltp to orderq, used for stoploss and takeprofit orders
* `optional{uint8_t} fill_type`: fill type of the order, options are GTC(Good Till Expiry) EXPIRY), IOC(Immediate Or Cancel) and POST\_ONLY(a limit order placed by a user will never match with any orders already on the book)
* `{name} referrer`: name of the referrer account(the referrer would get a share in fees)

**example**

```
{
  "account": "trader",
  "name": "placeorder",
  data: {
    "market_id": 1,
    "account": "trader",
    "order_type": 1,
    "order_side": 2,
    "quantity": 100000000,
    "price": 1,
    "bid_symbol": {
        "sym": "8,XETH",
        "contract": "eosio.token"
    },
    "ask_symbol": {
        "sym": "4,XMT",
        "contract": "eosio.token"
    },
    "trigger_price": 0,
    "fill_type": 1
  }
}
```

#### PROCESS

This action is used to process the orders in the orderQ. It does apply to all orders irrespective of market-id's.

* **authority**: user
* **requirements**: none

**args**

* `{uint16_t} size`: size of the orders to process

**example**

```
{
  "account": "user",
  "name": "process",
  "data": {
    "size": "50"
  }
}
```

#### PROCESSSLTP

This action is used to process the stoploss and takeprofit orders in the orderQ.&#x20;

* **authority**: user
* **requirements**: none

**args**

* `{uint16_t} market_id`: process orders for specific market
* `{uint16_t} size`: size(number) of the orders to process

**example**

```
{
  "account": "user",
  "name": "processsltp",
  "data": {
    "market_id": "2",
    "size": "20"
  }
}
```

#### CANCELORDER

This action is used to cancel orders that are queued in stoploss or orderq or orderbook.&#x20;

* **authority**: user
* **requirements**: none

**args**

* `{name} account`: name of the account that order belongs to
* `{uint64_t} order_id`: id of the order

**example**

```
{
  "account": "dex",
  "name": "cancelorder",
  "data": {
    "account": "alice",
    "order_id": "23"
  }
}
```

#### PAUSEDEX

This action is used to pause and resume all activities/actions on DEX.&#x20;

* **authority**: `admin`
* **requirements**: none

**args**

* `{bool} status`: status to be updated

**example**

```
{
  "account": "admin",
  "name": "pausedex",
  "data": {
    "status": "true"
  }
}
```

#### SETFEEACNT

All fees collected through DEX trading would be deposited into fee account. The fee account can be updated by admin.

* **authority**: `admin`
* **requirements**: none

**args**

* `{name} account`: fee account to be updated

**example**

```
{
  "account": "admin",
  "name": "setfeeacnt",
  "data": {
    "account": "bob"
  }
}
```

#### SETUSERTIER

Both maker and taker fees collected based on user acitivitiy on DEX. User tier would be calculated based on 30d average colume and it can be assigned through action by admin.

* **authority**: `admin`
* **requirements**: none

**args**

* `{name} account`: fee account to be updated
* `{uint8_t} tier`: tier value

**example**

```
{
  "account": "admin",
  "name": "setusertier",
  "data": {
    "account": "alice",
    "tier": "2"
  }
}
```


# Contracts

contract: `dex`

Supportings contracts: oracles, staking


# Audit

Below is the audit report from slowmist for the DEX contracts

{% file src="/files/HgAxyHZklE4kIl4qwAZd" %}


# XPR Network & Ecosystem

XPR Network is a new public blockchain and smart contract platform designed for both consumer applications and peer-to-peer payments. It is built around a secure identity and financial settlements layer that allows users to directly link their real identity and fiat accounts, pull funds and buy cryptocurrency, and use that cryptocurrency seamlessly in apps and other environments.

XPR Network was created to bridge the gap between traditional finance (TradFi) and DeFi, creating a way for blockchains to interact directly with bank accounts, vendors, merchants, and everywhere in between. Built to be fast and free, XPR Network imagines a world where push transactions minimize the risk for fraud, where currencies move freely between accounts, and where the type of money being used for a purchase is inconsequential.

### Instant and free transactions

The XPR Network blockchain can currently handle 4,000 transactions per second (TPS). This is one of the faster-performing blockchains currently available, and allows the different types of transactions possible on Proton to happen simultaneously. From rapid microtransactions, to focused authorizing requests, Proton’s TPS expands its potential use cases.

Transactions for end-users are always free. XPR Network doesn't have miner or gas  fees, validators get rewarded in XPR for validating transactions.

### Universal names

XPR Network uses a system of human-readable @names in place of confusing wallet addresses to make everyday use of Proton products easier. An @name is a unique namespace that works across multiple payment providers, identity verifiers, and payment transmitters. Gone are the days of entering your bank password or credit card number online; crypto and fiat wallets alike now interact as one network through the integration of the Proton blockchain.

Beyond being an applications platform with a unified identity model, the new XPR Network blockchain was designed to allow websites and apps to push payment requests directly to XPR Network-compliant wallets. As a result, users can leverage their unique @name when doing any type of transaction, eliminating the need to memorize or carefully copy wallet addresses that are complex and prone to mistakes.

### XPR Network ecosystem overview

Below we give an overview of Dapps and apps we build on the XPR Network blockchain.

### WebAuth Wallet

Webauth is the new industry standard for device authentication, identity management, payment processing, and cryptocurrency transactions for Web 3.0, built on the XPR Network. With WebAuth.com, you can approve transactions, make crypto payments, link your decentralized identity, verify/add/remove access for all logins, and reject impersonation attempts through the use of your smartphone – similar to how Google Authenticator and other popular 2FA platforms work, except with a higher bar for security utilizing XSR (XPR Signing Request) over OTP (one-time passwords) that can easily be phished.

Webauth is available on [Android](https://play.google.com/store/apps/details?id=com.metallicus.webauth), [iOS](https://apps.apple.com/us/app/webauth-com/id1594500069) and [web](https://webauth.com/).

Check out our blog post on WebAuth.com [here](https://blog.protonchain.com/meet-webauth/).

### Metal X Swap

[Metal X Swap](https://MetalX.com) is a decentralized exchange that allows users to instantly swap XPR Network-based tokens between each other. Users also have the ability to convert supported tokens from different blockchains to XPR Network-based tokens and vice versa. For example, using Metal X Swap, a user can swap XBTC for XUSDT, or convert ETH to XETH before trading it for XPR.

This allows seamless transactions between blockchains due to the speed and flexibility of the XPR Network. The more liquidity that exists between the pair of tokens being swapped, the lower the slippage will be.

Metal X Swap also offers[ incentives](https://blog.protonchain.com/proton-swap-is-now-officially-live/) for XPR holders and liquidity providers.

Metal X Swap offers [yield farming](https://blog.protonchain.com/proton-yield-farming-guide/) as well, where users can earn interest (variable APY) for providing liquidity to various X-token pairings.

### XPR NFT Market

Powered by the XPR Network, [XPR NFT Market](https://www.protonmarket.com/) allows NFTs to be bought and sold for fees as low as just a few cents – a radical change from the gas fees ranging from $50 to $200 paid on competing NFT marketplaces. Additionally, because the XPR Network blockchain is one of the fastest in the world, the NFTs you purchase arrive in your account instantaneously.

With XPR NFT Market being [open source](https://blog.protonchain.com/proton-market-goes-open-source-unlocking-nfts-for-billions-around-the-world/), you can integrate it directly into your own website free of charge. This avoids sending your visitors to another website to purchase your NFTs, eliminating the potential for losing visitors and lowering the barriers between them and your creations. Have merchandise you’d like to sell? Want to offer exclusive images, videos, or audio files to your fans? Sell them an NFT of your creations and ensure they feel more connected to you than ever before.


# About

The dex-bot is a custom, open source trading bot for the XPR Network and Metal X.

**Code**: <https://github.com/XPRNetwork/dex-bot>

**App**: [https://app.metalx.com](https://app.metalx.com/)

**API Docs**: [https://api.dex.docs.metalx.com](https://api.dex.docs.metalx.com/reference/what-is-metal-x)

The bot is built using node, typescript, proton/js

**Important**: Use node 18.0.0

For installation instructions click here.

### Grid Bot

Grid Trading Bots are programs that allow users to automatically buy at low and sell at high within a pre-set price range. When one sell order is fully executed, the Grid Trading Bot places a buy order in next round based on timeinterval set in tool at a lower grid level, and vice versa. The Grid Trading strategy might perform best in volatile markets, making profits through a series of orders as token’s price fluctuates.

### Market Maker Bot

This bot works against multiple markets to place orders based on levels defined in settings. The purpose of the market making strategy is to put buy and sell orders on the DEX' order books. This strategy doesn’t care about which way the market’s going. The strategy places a ladder of sells at regular intervals above base price, and another ladder of buys beneath it. Use this as a reference and implement yor own trading algorithm.

###


# Installation

### Prerequisites

To get started make sure that you have the following:

* A [WebAuth.com](https://wauth.co) account with enough funds for trading
* [Nodejs and npm](https://nodejs.org/en) installed on your computer (nodejs 18.0.0)
* [VS Code](https://code.visualstudio.com/) (or some other editor)

**Important:** You must use node 18.0.0 \
*You can use Node Version Manager (nvm) to manage your node version.*

First clone the [repo](https://github.com/XPRNetwork/dex-bot)

```
git clone https://github.com/XPRNetwork/dex-bot.git
```

Navigate to the folder and in your terminal run

```
npm install
```

Edit your default.json using vscode or your code editor of choice.

<figure><img src="https://1068387139-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F2KWLHP2zE3VO3AoelaSy%2Fuploads%2FCArKLv5ZGQaKg1YLdzNK%2Fimage.png?alt=media&amp;token=fb057780-d7f6-4922-8059-9395ad6137bd" alt=""><figcaption></figcaption></figure>

If you want the bot to automatically cancel open orders on exit (when you command + c) for your convenience you can set this parameter to true

```
    "cancelOpenOrdersOnExit": true,
```

Choose the strategy, either gridBot or marketMaker

```
    "strategy": "gridBot",
```

Set your pairs and parameters (covered in next section)

```
    "gridBot": {
      "pairs": [
        {
          "symbol": "XPR_XMD",
          "upperLimit": 0.0009000,
          "lowerLimit": 0.0006000,
          "gridLevels": 14,
          "bidAmountPerLevel": 40000
        }             
      ]
    },
```

Enter environment variables in terminal. Depending on your operating system, enter the PROTON\_USERNAME and PROTON\_PRIVATE\_KEY

```
Mac and Linux:
export PROTON_USERNAME=user1
export PROTON_PRIVATE_KEY=private_key

Windows using powershell:
$env:PROTON_USERNAME = 'user1'
$env:PROTON_PRIVATE_KEY = 'private_key'
```

Then you can run the bot

```
npm run bot
```

To stop the bot you can use **Cmd**+C (mac) or **Ctrl**+C (windows)

### Important Notes

* Minimum order is $1 or 1 XMD on Metal X
* Bot will automatically add more orders once old ones are filled
* If you have trouble using the trading interface make sure you have [verified identity](https://identity.metalx.com/)
* Keep your private key protected

You can clear your private key from the screen in your terminal before you run the bot you can run the following command;\
\
**Windows**&#x20;

```
cls
```

**Mac / Linux**

```
clear
```


# Guides

&#x20;Access all Metal X guides on the [Official XPR Network Knowledgebase](https://help.xprnetwork.org/hc/en-us/articles/6305251276567-How-to-add-LP-tokens-to-Farming)&#x20;


