# 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.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.ramper.xyz/embedded-wallet-sdk/quickstart/for-web-apps/version-1/sdk-specifications/transactions.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
