# dYdX (Cosmos)

Source: https://developers.bitgo.com/docs/dydxcosmos

## Overview

DYDX is the native asset of the dYdX Chain blockchain. It utilizes:

- Account model
- EcDSA signature algorithm

The dYdX Chain is a Cosmos SDK-based Layer 1 that powers the v4 dYdX decentralized exchange. It uses CometBFT (Tendermint) consensus with a delegated proof-of-stake (DPoS) model. DYDX is used to pay transaction fees, secure the network through staking, and participate in on-chain governance.

## Explorer

<a href="https://www.mintscan.io/dydx/" target="_blank" rel="noreferrer">https://www.mintscan.io/dydx/</a>

## Wallets Types

BitGo enables holding DYDX in the following wallet types:

|                  | Multisig Cold | Multisig Hot | MPC Cold | MPC Hot |
|------------------|---------------|--------------|----------|---------|
| **Custodial**    | ❌             | ❌            | ✅        | ❌       |
| **Self Managed** | ❌             | ❌            | ✅        | ✅       |

## Ticker Symbols

| Mainnet    | Testnet       |
|------------|---------------|
| dydxcosmos | tdydxcosmos   |

## Faucet

Testnet DYDX can be obtained programmatically from the dYdX v4 testnet faucet. See the <a href="https://docs.dydx.exchange/infrastructure_providers-network/faucet" target="_blank" rel="noreferrer">dYdX Faucet documentation</a> for instructions on using the `FaucetClient` from `@dydxprotocol/v4-client-js`.

## Units

DYDX is divisible by 10<sup>-18</sup> and the base unit is adydx (atto-dydx):

- 1 DYDX = 1,000,000,000,000,000,000 adydx
- 1 adydx = 0.000000000000000001 DYDX

DYDX balances can be in either integer or string format. However, BitGo recommends using string format to ensure values don't exceed the programmable number limit.

## Tokens

The dYdX Chain blockchain doesn't natively support tokens.

## Fees

dYdX Chain fees are dynamic - there are no minimum or default fee rates.

## Address Format

dYdX Chain addresses follow the format: `dydx1<38-character-bech32-body>`. All addresses are exactly 43 characters in length and begin with the fixed prefix `dydx1`. This format adheres to the following regular expression:
```regex
/^(dydx)1(['qpzry9x8gf2tvdw0s3jn54khce6mua7l]{38})$/
```

### Memo ID Support

- Optionally, a `?memoId=<n>` query parameter can be appended to the address for use cases such as identifying transaction metadata. Here, `<n>` can be any integer.
- Using `memoId`-based addressing eliminates the need to generate multiple deposit addresses per user. A single static address can be reused safely across users and use cases, with the `memoId` serving as the unique identifier.
- Since the dYdX Chain uses `memoId`-based receive addresses, manual consolidation is not required.

## Create Wallet

```shell cURL
export BITGO_EXPRESS_HOST="<YOUR_LOCALHOST>"
export COIN="tdydxcosmos"
export ACCESS_TOKEN="<YOUR_ACCESS_TOKEN>"
export LABEL="<DESIRED_WALLET_NAME>"
export PASSPHRASE="<YOUR_BITGO_LOGIN_PASSPHRASE>"
export ENTERPRISE_ID="<YOUR_ENTERPRISE_ID>"

curl -X POST \
  http://$BITGO_EXPRESS_HOST/api/v2/$COIN/wallet/generate \
  -H 'Content-Type: application/json' \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -d '{
    "label": "'"$LABEL"'",
    "passphrase": "'"$PASSPHRASE"'",
    "enterprise": "'"$ENTERPRISE_ID"'",
    "disableTransactionNotifications": true,
    "disableKRSEmail": true
}'
```
```js JavaScript
const { BitGo } = require('bitgo');

const accessToken = '<YOUR_ACCESS_TOKEN>';

// Initialize the SDK
const bitgo = new BitGo({
  accessToken: accessToken,
  env: 'test',
});

// Generate hot wallet
async function createHotWalletSimple() {
  const newWallet = await bitgo.coin('tdydxcosmos').wallets().generateWallet({
    label: '<DESIRED_WALLET_NAME>',
    passphrase: '<YOUR_BITGO_LOGIN_PASSWORD>',
  });

  console.log(JSON.stringify(newWallet, undefined, 2));
}
```

## Create Address

```shell cURL
export COIN="tdydxcosmos"
export WALLET_ID="<YOUR_WALLET_ID>"
export ACCESS_TOKEN="<YOUR_ACCESS_TOKEN>"

curl -X POST \
  https://app.bitgo-test.com/api/v2/$COIN/wallet/$WALLET_ID/address \
  -H 'Content-Type: application/json' \
  -H "Authorization: Bearer $ACCESS_TOKEN"
```
```js JavaScript
const { BitGo } = require('bitgo');
const accessToken = '<YOUR_ACCESS_TOKEN>';

// Initialize the SDK
const bitgo = new BitGo({
  accessToken: accessToken,
  env: 'custom',
  customRootURI: 'https://app.bitgo.com',
});

// Create address
const wallet = await bitgo.coin('tdydxcosmos').wallets().generateWallet({
  label: '<DESIRED_WALLET_NAME>',
  passphrase: '<YOUR_BITGO_LOGIN_PASSPHRASE>',
});

const address = await wallet.createAddress();

// Print address details
console.log(JSON.stringify(address, undefined, 2));
```

## Estimate Fee

```shell cURL
export COIN="tdydxcosmos"
export ACCESS_TOKEN="<YOUR_ACCESS_TOKEN>"

curl -X GET \
  https://app.bitgo-test.com/api/v2/$COIN/tx/fee \
  -H 'Content-Type: application/json' \
  -H "Authorization: Bearer $ACCESS_TOKEN"
```
```js JavaScript
const BitGoJS = require('bitgo');
const bitgo = new BitGoJS.BitGo({ env: 'test' });
const accessToken = '<YOUR_ACCESS_TOKEN>';
const coin = 'tdydxcosmos';

async function getFeeEstimate() {
  try {
    await bitgo.authenticateWithAccessToken({ accessToken });
    const res = await bitgo.coin(coin).feeEstimate({ numBlocks: 2 });
    console.dir(res);
  } catch (err) {
    console.error('Error fetching fee estimate:', err);
  }
}
getFeeEstimate();
```

## Transact

```shell cURL
export BITGO_EXPRESS_HOST="<YOUR_LOCALHOST>"
export COIN="tdydxcosmos"
export WALLET_ID="<YOUR_WALLET_ID>"
export ACCESS_TOKEN="<YOUR_ACCESS_TOKEN>"
export ADDRESS="<DESTINATION_ADDRESS>"
export AMOUNT="<AMOUNT_IN_BASE_UNITS>"
export WALLET_PASSPHRASE="<YOUR_WALLET_PASSPHRASE>"

curl -X POST \
  http://$BITGO_EXPRESS_HOST/api/v2/$COIN/wallet/$WALLET_ID/sendcoins \
  -H 'Content-Type: application/json' \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -d '{
    "address": "'"$ADDRESS"'",
    "amount": "'"$AMOUNT"'",
    "walletPassphrase": "'"$WALLET_PASSPHRASE"'"
}'
```
```shell cURL (send to many)
export BITGO_EXPRESS_HOST="<YOUR_LOCALHOST>"
export COIN="tdydxcosmos"
export WALLET_ID="<YOUR_WALLET_ID>"
export ACCESS_TOKEN="<YOUR_ACCESS_TOKEN>"
export ADDRESS_1="<DESTINATION_ADDRESS_1>"
export ADDRESS_2="<DESTINATION_ADDRESS_2>"
export AMOUNT_1="<AMOUNT_1_IN_BASE_UNITS>"
export AMOUNT_2="<AMOUNT_2_IN_BASE_UNITS>"
export WALLET_PASSPHRASE="<YOUR_WALLET_PASSPHRASE>"

curl -X POST \
  http://$BITGO_EXPRESS_HOST/api/v2/$COIN/wallet/$WALLET_ID/sendmany \
  -H 'Content-Type: application/json' \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -d '{
    "recipients": [
      {
        "address": "'"$ADDRESS_1"'",
        "amount": "'"$AMOUNT_1"'"
      },
      {
        "address": "'"$ADDRESS_2"'",
        "amount": "'"$AMOUNT_2"'"
      }
    ],
    "walletPassphrase": "'"$WALLET_PASSPHRASE"'"
}'
```
```js JavaScript
const tx = await fundedWallet.send({
  address: `<DESTINATION_ADDRESS>`,
  amount: `<AMOUNT>`,
  walletPassphrase: process.env.PASSWORD as string,
});
```
```js JavaScript (send to many)
let params = {
  recipients: [
    {
      amount: "<AMOUNT_1>",
      address: "<DESTINATION_ADDRESS_1>",
    },
    {
      amount: "<AMOUNT_2>",
      address: "<DESTINATION_ADDRESS_2>",
    },
  ],
  walletPassphrase: "<YOUR_WALLET_PASSPHRASE>",
};
wallet.sendMany(params).then(function (transaction) {
  // Print transaction details
  console.dir(transaction);
});
```
