> For the complete documentation index, see [llms.txt](https://docs.ramper.xyz/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.ramper.xyz/embedded-wallet-sdk/quickstart/for-web-apps/version-1/sdk-specifications/transactions.md).

# Transactions

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

## Send Token

Currently, Ramper SDK supports `sendToken` which is a simple way to send a token to another address from the current logged in wallet.

```jsx
const sendToken = async (params: Partial<{
  from: string
  to: string
  value: string
  decimal: number
  symbol: string
  network: string
  theme: string
}>) => Promise<boolean>
```

Example Usage:

```jsx
import { sendToken } from '@ramper/ethereum'

await sendToken({
  to: '0xa419dfa199Df8651c3f4476546AF5E4CC4E0F73F',
  value: '0.00001',
  network: 'mainnet'
})
```

## RamperSigner

Ramper SDK allows you to request a signed transaction from the user for subsequent broadcasting to the network. Ramper SDK is built around [Ether.js](https://docs.ethers.io/v5/) and [Alchemy](https://docs.ethers.io/v5/api/providers/api-providers/) but if you'd like to see Ramper SDK support other use cases, let us know on [Discord](https://ramper.link/discord), or email us at <team@ramper.xyz>.\
\
In order to broadcast a transaction, you must first set up an Alchemy Provider.

```jsx
import { ethers } from 'ethers'

const alchemy = new ethers.providers.AlchemyProvider(80001, 'pEWvHrkSkkyWGZmezdGMk_LjYu8DAx1k')
```

\
After the user is logged in through Ramper SDK, you can set up a `RamperSigner` object with the alchemy provider that will eventually collect the user's authorization to sign the requested transaction.<br>

```jsx
import { getRamperSigner } from '@ramper/ethereum'

// User must be logged in
const ramperSigner = await getRamperSigner(alchemy)
```

### Sign Transaction

```typescript
import { TransactionRequest } from '@ethersproject/abstract-provider'

ramperSigner.signTransaction(
    transaction: Deferrable<TransactionRequest>
): Promise<string>
```

Example usage:

```jsx
import { getRamperSigner } from '@ramper/ethereum'
import { ethers } from 'ethers'

const alchemy = new ethers.providers.AlchemyProvider(80001, 'pEWvHrkSkkyWGZmezdGMk_LjYu8DAx1k')
const ramperSigner = await getRamperSigner(alchemy)

const value = ethers.utils.parseEther('0.0000001')
const nonce = await alchemy.getTransactionCount('your-wallet-address')
const gasLimit = await alchemy.estimateGas({
  to: '0xa419dfa199Df8651c3f4476546AF5E4CC4E0F73F',
  value: value,
})
const feeData = await alchemy.getFeeData()

try {
    const result = await ramperSigner.signTransaction({
        type: 2,
        from: 'your-wallet-address',
        to: '0xa419dfa199Df8651c3f4476546AF5E4CC4E0F73F',
        value: value,
        chainId: 80001,
        nonce: nonce,
        gasLimit: gasLimit,
        maxFeePerGas: feeData.maxFeePerGas,
        maxPriorityFeePerGas: feeData.maxPriorityFeePerGas,
    })
    console.log('signTransaction result', result)
} catch (e) {
  console.log(e)
}
```

### Send Transaction

```typescript
import { 
    TransactionRequest, 
    TransactionResponse 
} from '@ethersproject/abstract-provider'

ramperSigner.sendTransaction(
    transaction: Deferrable<TransactionRequest>
): Promise<TransactionResponse>
```

Example usage:

```jsx
import { getRamperSigner } from '@ramper/ethereum'
import { ethers } from 'ethers'

const alchemy = new ethers.providers.AlchemyProvider(80001, 'pEWvHrkSkkyWGZmezdGMk_LjYu8DAx1k')
const ramperSigner = await getRamperSigner(alchemy)

const value = ethers.utils.parseEther('0.0000001')
const nonce = await alchemy.getTransactionCount('your-wallet-address')
const gasLimit = await alchemy.estimateGas({
  to: '0xa419dfa199Df8651c3f4476546AF5E4CC4E0F73F',
  value: value,
})
const feeData = await alchemy.getFeeData()

try {
  await ramperSigner.sendTransaction({
    type: 2,
    from: 'your-wallet-address',
    to: '0xa419dfa199Df8651c3f4476546AF5E4CC4E0F73F',
    value: value,
    chainId: 80001,
    nonce: nonce,
    gasLimit: gasLimit,
    maxFeePerGas: feeData.maxFeePerGas,
    maxPriorityFeePerGas: feeData.maxPriorityFeePerGas,
  })
  console.log('sendTransaction result', result)
} catch (e) {
  console.log(e)
}
```

### Sign Message

```typescript
ramperSigner.signMessage(
    message: Bytes | string
): Promise<string>
```

Example usage:

```jsx
import { getRamperSigner } from '@ramper/ethereum'
import { ethers } from 'ethers'

const alchemy = new ethers.providers.AlchemyProvider(80001, 'pEWvHrkSkkyWGZmezdGMk_LjYu8DAx1k')
const ramperSigner = await getRamperSigner(alchemy)

try {
  const message = 'Ramper sign message test'
  const result = await ramperSigner.signMessage(message)
  
  console.log('signMessage result: ', result)
} catch (e) {
  console.log(e)
}
```

### Sign TypedData

```typescript
import { TypedDataField } from '@ethersproject/abstract-signer'

ramperSigner._signTypedData(
    domain: TypedDataDomain,
    types: Record<string, Array<TypedDataField>>,
    value: Record<string, any>,
  ): Promise<string>
```

Example usage:

```typescript
import { getRamperSigner } from '@ramper/ethereum'
import { ethers } from 'ethers'
import { eip712 } from './eip712

const alchemy = new ethers.providers.AlchemyProvider(80001, 'pEWvHrkSkkyWGZmezdGMk_LjYu8DAx1k')
const ramperSigner = await getRamperSigner(alchemy)

try {
  const message = 'Ramper signTypedData test'
  const result = await ramperSigner.signTypedData(
    eip712.example.domain, 
    eip712.example.types, 
    eip712.example.value
  )
  
  console.log('signTypedData result: ', result)
} catch (e) {
  console.log(e)
}
```

eip712.ts

```typescript
const example = {
  domain: {
    name: 'Ether Mail',
    version: '1',
    chainId: 1,
    verifyingContract: '0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC',
  },

  // The named list of all type definitions
  types: {
    Person: [
      { name: 'name', type: 'string' },
      { name: 'wallet', type: 'address' },
    ],
    Mail: [
      { name: 'from', type: 'Person' },
      { name: 'to', type: 'Person' },
      { name: 'contents', type: 'string' },
    ],
  },

  // The data to sign
  value: {
    from: {
      name: 'Cow',
      wallet: '0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826',
    },
    to: {
      name: 'Bob',
      wallet: '0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB',
    },
    contents: 'Hello, Bob!',
  },
}

export const eip712 = {
  example,
}
```

{% endtab %}

{% tab title="NEAR" %}

## Send Token

Currently, Ramper Connect SDK supports `sendToken` which is a simple way to send a token to another address from the current logged in wallet.

```jsx
const sendToken = async (params: Partial<{
  from: string
  to: string
  value: string
  decimal: number
  symbol: string
  network: string
  theme: string
}>) => Promise<boolean>
```

Example Usage:

```jsx
import { sendToken } from '@ramper/near'

await sendToken({
  to: '421ccd52db3465153de4591177396dc72e401b0ab1687b8c175491be32fbd148',
  value: '0.01', 
  network: 'testnet'
})
```

## Custom Transactions

Ramper Connect SDK supports custom Near transactions by supporting interactions with `near-api-js`. You can find an overview of near-api-js [here](https://docs.near.org/docs/api/javascript-library) and their TypeDocs [here](https://near.github.io/near-api-js/).

```jsx
import { sendTransaction } from '@ramper/near'
import { transactions } from 'near-api-js'
import { BN } from 'bn.js'

try {
  const actions = [transactions.transfer(new BN(10000000))]
  await sendTransaction({
    transactionActions: [{
      receiverId: '421ccd52db3465153de4591177396dc72e401b0ab1687b8c175491be32fbd148'
      actions: actions
    }],
    network: 'testnet',
  })
} catch (ex) {
  console.error('Transaction failed')
}
```

You can find a list of supported actions [here](https://nomicon.io/RuntimeSpec/Actions).

The result type is below. You can see more details about the FinalExecutionOutcome [here](https://github.com/near/near-api-js/blob/7f16b10ece3c900aebcedf6ebc660cc9e604a242/packages/near-api-js/src/providers/provider.ts#L84).

```typescript
type SendTransactionResult = {
  type: 'success' | 'failure' | 'cancel' | 'none'
  txHashes: string[]
  result?: (FinalExecutionOutcome | Error)[] | Error
}
```

Note. If you sign in with NEAR Wallet, you can get **transaction hashes only.**

## Sign Transaction

You can sign a transaction with `signTransaction` from the current logged in wallet. It is same as `signer.signMessage` of `near-api-js`. Look at the code [here](https://github.com/near/near-api-js/blob/master/src/signer.ts#L90).

```typescript
const signTransaction = async (params: {
  transaction: Transaction
  network?: NearNetwork
}) => Promise<{
  type: 'success' | 'failure' | 'cancel' | 'none',
  result?: string | Error
}>
```

```typescript
import { transactions } from 'near-api-js'

type Transaction = {
  receiverId: string
  actions: transactions.Action[]
}
```

Example Usage:

```typescript
import { signTransaction } from '@ramper/near'

try {
  const result = await signTransaction({
    transaction: {
      receiverId: '421ccd52db3465153de4591177396dc72e401b0ab1687b8c175491be32fbd148',
      actions: [transactions.transfer(new BN(10000000))],
    },
  })
  console.log('signTransaction result', result)
} catch (e) {
  console.error(e)
}
```

## Sign Message

You can sign a message with `signMessage` from the current logged in wallet. It is same as `signer.signMessage` of `near-api-js`. Look at the code [here](https://github.com/near/near-api-js/blob/master/src/signer.ts#L90).

```typescript
const signMessage = async (params: {
  message: Uint8Array
  network?: NearNetwork
}) => Promise<{
  type: TransactionResultType
  result?: Signature | Error
}>
```

Example Usage:

```typescript
import { signMessage } from '@ramper/near'

const message = [12, 13, 14, 15]
const messageBuffer = new Uint8Array(message)

try {
  const result = await signMessage({
    message: messageBuffer,
  })
  console.log('signMessage result', result)
} catch (e) {
  console.log(e)
}
```

{% endtab %}

{% tab title="Terra" %}

## Send Token

Currently, Ramper Connect SDK supports `sendToken` which is a simple way to send a token to another address from the current logged in wallet.

```jsx
const sendToken: async (params: Partial<{
  from: string
  to: string
  value: string
  decimal: number
  symbol: string
  network: string
  theme: string
  status: WalletStatus
  connectedWallet: ConnectedWallet
}>) => Promise<boolean>
```

`status` and `connectedWallet` are used in case you want to support with Terra Station and Wallet Connect.

```jsx
import {
  useConnectedWallet,
  useWallet
} from '@terra-money/wallet-provider'

...

const walletToUse = useWallet()
const { status } = walletToUse
const connectedWallet = useConnectedWallet()
```

#### Example Usage:

```jsx
import {
  useConnectedWallet,
  useWallet
} from '@terra-money/wallet-provider'
import { sendToken } from '@ramper/terra'

const walletToUse = useWallet()
const { status } = walletToUse
const connectedWallet = useConnectedWallet()
const toAddress = 'terra123aqd9edra72sehg84jk93wq44kfh05s2w02aq'

const isSuccess = await sendToken({
    to: toAddress,
    symbol: 'Luna',
    value: '0.01', 
    network: 'mainnet'
 })
```

## Custom Transactions

Ramper Connect SDK supports all the custom transaction all the custom transactions that Terra Station supports with the `post` method. Provide the same `txOption` that is commonly used in Terra.js `createAndSignTx` method - more details can be found here: <https://terra-money.github.io/terra.js/>.&#x20;

```jsx
const postTransaction: (
  txOptions: CreateTxOptions,
  ramperNetwork: 'testnet' | 'mainnet',
  status?: WalletStatus,
  connectedWallet?: ConnectedWallet,
) => Promise<TxResult>
```

{% endtab %}
{% endtabs %}

## Error Handling

Use a try/catch block to detect if the user canceled the transaction or the transaction failed to be broadcasted successfully.
