# Sending Transactions

Confirm you have:

* [ ] Connected to Midgard or MAYANode
* [ ] Located the latest vault (and router) for the chain
* [ ] Prepared the transaction details (and memo)
* [ ] Checked the network is not halted for your transaction

You are ready to make the transaction and swap via MAYAChain.

### UTXO Chains

{% hint style="warning" %}
MAYAChain does NOT currently support BTC Taproot. User funds will be lost if sent to or from a taproot address!
{% endhint %}

* [ ] Send the transaction with Asgard vault as VOUT0
* [ ] Include the memo as an OP\_RETURN in VOUT1
* [ ] Pass all change back to the VIN0 address in VOUT3
* [ ] Use a high enough `gas_rate` to be included
* [ ] Do not send below the dust threshold (10k Sats BTC, DASH), exhaustive values can be found on the [Inbound Addresses](https://mayanode.mayachain.info/mayachain/inbound_addresses) endpoint

{% hint style="warning" %}
Inbound transactions should not be delayed for any reason else there is risk funds will be sent to an unreachable address. Use standard transactions, check the [`Inbound_Address`](https://docs.mayaprotocol.com/mayachain-dev-docs/querying-mayachain#getting-the-asgard-vault) before sending and use the recommended [`gas rate`](https://docs.mayaprotocol.com/mayachain-dev-docs/querying-mayachain#getting-the-asgard-vault) to ensure transactions are confirmed in the next block to the latest `Inbound_Address`.
{% endhint %}

{% hint style="info" %}
Memo limited to 80 bytes on BTC. Use abbreviated options and [MAYANames](https://docs.mayaprotocol.com/mayachain-dev-docs/introduction/mayaname-guide) where possible.
{% endhint %}

{% hint style="warning" %}
Do not use HD wallets that forward the change to a new address, because MAYAChain IDs the user as the address in VIN0. The user must keep their VIN0 address funded for refunds.
{% endhint %}

{% hint style="danger" %}
Override randomised VOUT ordering; MAYAChain requires specific output ordering.
{% endhint %}

### EVM Chains

{% embed url="<https://gitlab.com/mayachain/ethereum/eth-router/-/blob/master/contracts/MAYAChain_Router.sol?ref_type=heads>" %}

```
depositWithExpiry(vault, asset, amount, memo, expiry)
```

* [ ] If ERC20, approve the router to spend an allowance of the token first
* [ ] Send the transaction as a `depositWithExpiry()` on the router
* [ ] Vault is the Asgard vault address, asset is the token address to swap, memo as a string
* [ ] Use an expiry which is +60mins on the current time (if the tx is delayed, it will get refunded)
* [ ] Use a high enough `gas_rate` to be included, otherwise the tx will get stuck

{% hint style="info" %}
ETH is `0x0000000000000000000000000000000000000000`
{% endhint %}

{% hint style="danger" %}
ETH is sent and received as an internal transaction. Your wallet may not be set to read internal balances and transactions
{% endhint %}

### COSMOS Chains

* [ ] Send the transaction to the Asgard vault
* [ ] Include the memo
* [ ] Only use the base asset as the choice for gas asset

## MAYAChain

To initiate a $CACAO-> $ASSET swap a `MsgDeposit` must be broadcasted to the MAYAChain blockchain. The `MsgDeposit` does not have a destination address, and has the following properties. The full definition can be found [here](https://gitlab.com/mayachain/mayanode/-/blob/develop/x/mayachain/types/msg_deposit.go?ref_type=heads).

```go
MsgDeposit{
    Coins:  coins,
    Memo:   memo,
    Signer: signer,
}
```

If you are using Javascript, [CosmJS](https://github.com/cosmos/cosmjs) is the recommended package to build and broadcast custom message types. [Here is a walkthrough](https://github.com/cosmos/cosmjs/blob/main/packages/stargate/CUSTOM_PROTOBUF_CODECS.md).

{% hint style="warning" %}
`MsgDeposit` must also be broadcasted when swapping from [Synths](https://docs.mayaprotocol.com/deep-dive/mayachain-finance/synthetic-asset-model).
{% endhint %}

### Code Examples (Javascript)

1. **Generate codec files.** To build/broadcast native transactions in Javascript/Typescript, the protobuf files need to be generated into js types. The below script uses `pbjs` and `pbts` to generate the types using the relevant files from the MAYANode repo. Alternatively, the .`js` and `.d.ts` files can be downloaded directly from the [XChainJS repo](https://github.com/xchainjs/xchainjs-lib/tree/master/packages/xchain-thorchain/src/types/proto).

```bash
#!/bin/bash

# this script checks out mayanode master and generates the proto3 typescript buindings for MsgDeposit and MsgSend

MSG_COMPILED_OUTPUTFILE=src/types/proto/MsgCompiled.js
MSG_COMPILED_TYPES_OUTPUTFILE=src/types/proto/MsgCompiled.d.ts


TMP_DIR=$(mktemp -d)

tput setaf 2; echo "Checking out https://gitlab.com/mayachain/thornode  to $TMP_DIR";tput sgr0
(cd $TMP_DIR && git clone https://gitlab.com/mayachain/mayanode)

# Generate msgs
tput setaf 2; echo "Generating $MSG_COMPILED_OUTPUTFILE";tput sgr0
yarn run pbjs -w commonjs  -t static-module $TMP_DIR/mayanode/proto/mayachain/v1/common/common.proto $TMP_DIR/mayanode/proto/mayachain/v1/x/mayachain/types/msg_deposit.proto $TMP_DIR/mayanode/proto/mayachain/v1/x/mayachain/types/msg_send.proto $TMP_DIR/mayanode/third_party/proto/cosmos/base/v1beta1/coin.proto -o $MSG_COMPILED_OUTPUTFILE

tput setaf 2; echo "Generating $MSG_COMPILED_TYPES_OUTPUTFILE";tput sgr0
yarn run pbts  $MSG_COMPILED_OUTPUTFILE -o $MSG_COMPILED_TYPES_OUTPUTFILE

tput setaf 2; echo "Removing $TMP_DIR/mayanode";tput sgr0
rm -rf $TMP_DIR

```

2. **Using @cosmjs build/broadcast the TX.**

```javascript
const { DirectSecp256k1HdWallet, Registry } = require("@cosmjs/proto-signing");
const { defaultRegistryTypes: defaultStargateTypes, SigningStargateClient } = require("@cosmjs/stargate");
const { stringToPath } = require("@cosmjs/crypto");
const bech32 = require("bech32-buffer");

const { MsgDeposit } = require('./types/MsgCompiled').types

async function main() {
  const myRegistry = new Registry(defaultStargateTypes);
  myRegistry.register("/types.MsgDeposit", MsgDeposit); 

  const signerMnemonic = "mnemonic here"
  const signerAddr = "thor1..."

  const signer = await DirectSecp256k1HdWallet.fromMnemonic(
    signerMnemonic,
    { 
      prefix: "maya", // MAYAChain prefix
      hdPaths: [ stringToPath("m/44'/931'/0'/0/0")] // MAYAChain HD Path
    },
  );

  const client = await SigningStargateClient.connectWithSigner(
    "https://tendermint.mayachain.info/",
    signer,
    { registry: myRegistry },
  );

  const memo = `=:DASH/DASH:${signerAddr}` // MAYAChain memo

  const msg = {
    coins: [
      {
        asset: {
          chain: "THOR",
          symbol: "RUNE",
          ticker: "RUNE"
        },
        amount: "10000000000" // Value in 1e10 (10000000000 = 1 CACAO)
      }
    ],
    memo: memo,
    signer: bech32.decode(signerAddr).data,
  }

  const depositMsg = {
    typeUrl: "/types.MsgDeposit",
    value: MsgDeposit.fromObject(msg),
  };

  const fee = {
    amount: [],
    gas: "50000000", // Set arbitrarily high gas limit; this is not actually deducted from user account. 
  };

  const response = await client.signAndBroadcast(signerAddr, [depositMsg], fee, memo);
  console.log('response: ', response)

  if (response.code !== 0) {
    console.log('Error: ', response.rawLog)
  } else {
    console.log('Success!')
  }
}

main()
```
