Browser Wallet SDK

To integrate the DCA API, you'll need to use the Limit Order SDK, which provides functionality for creating and canceling limit orders.

How to install the SDK in your project

npm i @openocean.finance/limitorder-sdk

How to use the SDK in your project

import { openoceanLimitOrderSdk } from '@openocean.finance/limitorder-sdk';

You can then use all the functions explored by the SDK (API and swapSDK).

Supported Provider Types

Type
Example
Description

Web3 provider

new Web3(window.ethereum)

Traditional MetaMask-style Web3.js

Ethers provider

new ethers.providers.Web3Provider(...) (v5) / new ethers.BrowserProvider(...) (v6)

Modern Ethers.js integration

Initialize Wallet Provider

Using Web3.js (web3-provider)

import Web3 from 'web3';

await window.ethereum.request({ method: 'eth_requestAccounts' });

const provider = new Web3(window.ethereum);
const address = await provider.eth.getAccounts();

Pass the provider to the SDK like this:

const sdkParams = {
  provider,                        // Web3 instance
  chainKey: 'base',                // Supported: base, arbitrum, etc.
  account: address[0],             // Wallet address
  chainId: 8453,                   // Chain ID
};

Using Ethers.js (ethers-provider)

Ethers v5

import { ethers } from 'ethers';

const provider = new ethers.providers.Web3Provider(window.ethereum); // v5
const signer = provider.getSigner();
const address = await signer.getAddress();

Ethers v6 (Recommended)

import { ethers } from 'ethers';

const provider = new ethers.BrowserProvider(window.ethereum); // v6
const signer = await provider.getSigner();
const address = await signer.getAddress();

Usage in SDK:

const sdkParams = {
  provider,                  // Ethers provider (v5 or v6)
  chainKey: 'base',
  account: address,
  chainId: 8453,
  mode: 'Dca'
};

Create DCA Orders:

const orderData = await openoceanLimitOrderSdk.createLimitOrder(
  sdkParams,
  {
    makerTokenAddress: '0xabc...',
    takerTokenAddress: '0xdef...',
    makerTokenDecimals: 6,
    takerTokenDecimals: 6,
    makerAmount: '1000000', // 1.0 USDC
    takerAmount: '2000000', // 2.0 USDT
    gasPrice: parseInt(gasPrice * 1.2),
    expire: '1H', // Expiration time (e.g., "1H")
  }
);

let order = {
  ...orderData,
  expireTime: 180,
  time: 60, // 1 Minute
  times: 2,
  version: 'v2',
  // minPrice:1,
  // maxPrice:2,
}

const result = await axios.post(
  `https://open-api.openocean.finance/v1/${chainId}/dca/swap`,
  order,
  {
    headers: { 'Content-Type': 'application/json' },
  }
);

Cancel DCA Order


const { orderHash } = order;
const {data} = await axios.post(
  `https://open-api.openocean.finance/v1/${chainId}/dca/cancel`,
  { orderHash }
);
const { status } = (data && data.data) || {};
if (status && !(status === 3 || status === 4)) {
  let res = await openoceanLimitOrderSdk.cancelLimitOrder(
    {
      provider: this.provider,
      chainKey: this.chainName,
      account: this.myWallet.address,
      chainId: this.chain.chainId,
      mode: 'Dca'
    },
    {
      orderData: order.data,
      gasPrice: parseInt(this.gasPrice*1.2),
    }
  );
}

Demo

<template>
  <div id="app">
    <div style="color:blue">
      <div v-if="chain">chain:{{ chain.chainName }}</div>
      <div v-if="myWallet"> walletName:{{ myWallet.name }}</div>
      <div v-if="myWallet">address:{{ myWallet.address }}</div>
    </div>
    <div>
      <div>
        <h3>Connect Wallet Web3</h3>
        <button @click="ConnectWalletWeb3()" style="margin-right:10px">ConnectWalletWeb3</button>
      </div>
      <div>
        <h3>Connect Wallet Ethers</h3>
        <button @click="ConnectWalletEthers()" style="margin-right:10px">ConnectWalletEthers</button>
      </div>

      <div>
        <h3>createLimitOrder</h3>
        <button @click="createLimitOrder">createLimitOrder</button>
      </div>
      <div>
        <h3>Orders</h3>
      </div>
      <div v-for="(item, i) in orders" :key="i">
        <!-- {{ item.data }} -->
        <span>{{ item.data.makerAssetSymbol }}</span>
        <span>-></span>
        <span>{{ item.data.takerAssetSymbol }}</span>
        <button v-if="item.statuses === 5 || item.statuses === 1" @click="cancelOrder(item)">cancelOrder</button>
      </div>
      <div id="chart" style="width: 100%; height: 400px; border: 1px solid #c00;">

      </div>

    </div>
  </div>
</template>

<script>
import { openoceanLimitOrderSdk } from '@openocean.finance/limitorder-sdk';
import axios from 'axios';
import { ethers } from 'ethers';
import Web3 from 'web3';

export default {
  name: 'App',
  components: {
  },
  data () {
    return {
      chainName: 'base',
      outToken: {
        "address": "0x833589fcd6edb6e08f4c7c32d4f71b54bda02913",
        "decimals": 6,
        "symbol": "USDC",
      },
      inToken: {
        "address": "0xfde4c96c8593536e31f229ea8f37b2ada2699bb2",
        "decimals": 6,
        "symbol": "USDT"
      },

      // chainName: 'arbitrum',
      // inToken: {
      //   "address": "0xaf88d065e77c8cC2239327C5EDb3A432268e5831",
      //   "decimals": 6,
      //   "symbol": "USDC",
      // },
      // outToken: {
      //   "address": "0xfd086bc7cd5c481dcc9c85ebe478a1c0b69fcbb9",
      //   "decimals": 6,
      //   "symbol": "USDT"
      // },

      gasPrice:0,
      walletName: 'MetaMask',
      inTokenBalance: null,
      outTokenBalance: null,
      inAmount: 1,
      outAmount: null,

      myWallet: null,
      chain: null,
      provider: null,
      limitOrderExpireOptions: [
        {
          value: "10M",
          label: "10 Mins",
        },
        {
          value: "1H",
          label: "1 Hour",
        },
        {
          value: "1D",
          label: "1 Day",
        },
        {
          value: "3D",
          label: "3 Days",
        },
        {
          value: "7D",
          label: "7 Days",
        },
        {
          value: "30D",
          label: "1 Month",
        },
        {
          value: "3Month",
          label: "3 Month",
        },
        {
          value: "6Month",
          label: "6 Month",
        },
        {
          value: "1Y",
          label: "1 Year",
        }
      ],

      orders: []
    }
  },


  async created () {
  },
  mounted () {
    this.loadChart()
  },
  methods: {
    async createLimitOrder () {
      if(!this.provider) {
        alert('Please connect wallet first')
        return
      }
      const p = {
        provider: this.provider,
        chainKey: this.chainName,
        account: this.myWallet.address,
        chainId: this.chain.chainId,
        mode: 'Dca'
      }
      let orderData = await openoceanLimitOrderSdk.createLimitOrder(
        p,
        {
          makerTokenAddress: this.inToken.address,
          makerTokenDecimals: this.inToken.decimals,
          takerTokenAddress: this.outToken.address,
          takerTokenDecimals: this.outToken.decimals,
          makerAmount: 0.01 * (10 ** this.inToken.decimals) + '',
          takerAmount:1, //"1" as default',
          gasPrice: parseInt(this.gasPrice*1.2),
          expire: this.limitOrderExpireOptions[1].value,
        }
      );

      let order = {
        ...orderData,
        expireTime: 180,
        time: 60, // 1 Minute
        times: 2,
        version: 'v2',
        // minPrice:1,
        // maxPrice:2,
      }

      const result = await axios.post(
        `https://open-api.openocean.finance/v1/${this.chain.chainId}/dca/swap`,
        order,
        {
          headers: { 'Content-Type': 'application/json' },
        }
      );

      this.getLimitOrder()
    },
    async getLimitOrder () {
      let url = `https://open-api.openocean.finance/v1/${this.chain.chainId}/dca/address/${this.myWallet.address}?page=1&limit=100&statuses=[1,2,5]&sortBy=createDateTime&exclude=0`
      const res = await axios.get(url);
      this.orders = res.data.data
    },
    async cancelOrder (order) {

      const { orderHash } = order;
      const {data} = await axios.post(
        `https://open-api.openocean.finance/v1/${this.chain.chainId}/dca/cancel`,
        { orderHash }
      );
      const { status } = (data && data.data) || {};
      if (status && !(status === 3 || status === 4)) {
        let res = await openoceanLimitOrderSdk.cancelLimitOrder(
          {
            provider: this.provider,
            chainKey: this.chainName,
            account: this.myWallet.address,
            chainId: this.chain.chainId,
            mode: 'Dca'
          },
          {
            orderData: order.data,
            gasPrice: parseInt(this.gasPrice*1.2),
          }
        );
      }
      this.getLimitOrder()
    },
    async ConnectWalletWeb3 () {
      try {
        await window.ethereum.request({ method: 'eth_requestAccounts' });

        this.provider = new Web3(window.ethereum);

        const address = await this.provider.eth.getAccounts();
        const gasPrice = await this.provider.eth.getGasPrice();
        this.gasPrice = Number(gasPrice);
        console.log(this.gasPrice);
        this.myWallet = {
          address: address[0],
          name: 'metamask'
        }
        this.chain = {
          chainId: this.chainName === 'base' ? 8453 : 42161,
          chainName: this.chainName
        }
        this.getLimitOrder()

      } catch (error) {
        this.myWallet = null
        this.chain = null
      }
    },
    async ConnectWalletEthers () {
      await window.ethereum.request({ method: 'eth_requestAccounts' });

      // this.provider = new ethers.providers.Web3Provider(window.ethereum); //ethers v5
      this.provider = new ethers.BrowserProvider(window.ethereum); //ethers v6

      let gasData = await this.provider.getFeeData();
      this.gasPrice = Number(gasData.gasPrice);
      console.log(this.gasPrice);
      const signer = await this.provider.getSigner();
      const address = await signer.getAddress();
      this.myWallet = {
        address: address,
        name: 'metamask'
      }
      this.chain = {
        chainId: this.chainName === 'base' ? 8453 : 42161,
        chainName: this.chainName
      }
      this.getLimitOrder()

      console.log(address);
    },
    async loadChart () {
      await openoceanLimitOrderSdk.loadChart({
        chain: this.chainName, // chain code, 
        fromTokenSymbol: this.inToken.symbol, // from token symbol
        toTokenSymbol: this.outToken.symbol, // to token symbol
        container: document.getElementById('chart'), // chart's container
        timeLimit: "1d", // 1d、1w、1m、1y、all
        theme: "dark", // dark、light
        type: "line", // line、bar
        setPoint: ({ label, des }) => { // setPoint callback
          console.log('setPoint', label, des);
        }
      })
    }
  }
}

</script>

<style></style>

Last updated