Loan - Create order

The following code example is provided to help you understand the business process. For commercial use, you must handle parameter validation and exception handling on your own.

This example is tested on the Polygon-Amoy chain. Information used in the example can be retrieved from the Source directory. All ERC20 assets in the example have been pre-approved (authorized) to the contract amoy_contract_approveTrade. For any amounts involved, precision should be converted using toWei(amount, "decimal").

  • Loan/OTC Collateral - Assets Token (Assets): Only supports ERC20 and ERC721, network native tokens are not supported.

  • Loan/OTC Payment Token (Currency): Only supports ERC20 and network native tokens, ERC721 is not supported.


Code Example

javascriptCopy code// Import web3js library
import Web3 from 'web3';
import ApproveTradeABI from '../abi/ApproveTrade.json';

// This example is tested on the Polygon-Amoy chain
const amoy_chainId = 80002;
const amoy_chainName = "AMOY";
const amoy_chainRpcUrl = "https://polygon-amoy.infura.io/v3/4ba314367838400fb88f2a1d0e14d42d";
const amoy_contract_approveTrade = "0xF1831ebb3f92A8607E644A1E54Fde4b09F6FE5dE";
const amoy_account = "0xA3932E6Dbf96983Ffdf43974c0BF7edE9fed76DF";

// Initialize web3 instance
// WalletProvider or HttpProvider
const web3 = new Web3("** Wallet **"); // window.ethereum
const Contract = new web3.eth.Contract(ApproveTradeABI, amoy_contract_approveTrade);

// 1. Listing parameters
const maker = "0xA3932E6Dbf96983Ffdf43974c0BF7edE9fed76DF";
const taker = "0x0000000000000000000000000000000000000000"; // Open to all buyers/lenders
const assets = [
  {collection:"0x9A3fad316eB9cC7db65aB6f89672796574CD1B76", assetClass:"0x0000000000000000000000000000000000000721", amountOrID:"28308257", name: "Bored Ape Yacht Club", symbol:"BAYC", decimal: 0},
  {collection:"0x9A3fad316eB9cC7db65aB6f89672796574CD1B76", assetClass:"0x0000000000000000000000000000000000000721", amountOrID:"28308487", name: "Bored Ape Yacht Club", symbol:"BAYC", decimal: 0}, 
  {collection:"0x98700d8fF27Af5F16FdA3bE3bD30aa4585234DCa", assetClass:"0x0000000000000000000000000000000000000020", amountOrID: toWei(1,9), name: "WBTC", symbol:"Wrapped BTC", decimal: 9},
  {collection:"0xc94BC02ecFf5f14b73fe1A3137bb587f5Fa62F5d", assetClass:"0x0000000000000000000000000000000000000020", amountOrID: toWei(1,6), name: "USDT", symbol:"Tether USD", decimal: 6}
];
const currency = [
  {collection:"0x0000000000000000000000000000000000000001", assetClass:"0x0000000000000000000000000000000000000000", amountOrID: toWei(1,18), name: "MATIC", symbol:"MATIC", decimal: 18}
];
const deadline = "1728955149"; // End of fundraising time (in seconds)
const duration = "1036800"; // Loan duration (in seconds)
const interestPerSecond = toWei(toWei(0.00034880771182141044,18),18); // Interest per second

// 2. Retrieve nonces from contract
const nonce = await Contract.methods.nonces(amoy_account).call();

// 3. Sign the order parameters
// Note: Hardware wallet signatures may differ from web wallet signatures, handle accordingly
const signParams = {
  "types": {
    "EIP712Domain": [
      { "name": "name", "type": "string" },
      { "name": "version", "type": "string" },
      { "name": "chainId", "type": "uint256" },
      { "name": "verifyingContract", "type": "address" }
    ],
    "Asset": [
      { "name": "collection", "type": "address" },
      { "name": "assetClass", "type": "address" },
      { "name": "amountOrID", "type": "uint256" }
    ],
    "Order": [
      { "name": "maker", "type": "address" },
      { "name": "taker", "type": "address" },
      { "name": "asset", "type": "Asset[]" },
      { "name": "currency", "type": "address" },
      { "name": "price", "type": "uint256" },
      { "name": "deadline", "type": "uint256" },
      { "name": "duration", "type": "uint256" },
      { "name": "interestPerSecond", "type": "uint256" },
      { "name": "nonce", "type": "uint256" }
    ]
  },
  "domain": {
    "name": "ApproveTrade",
    "version": "1",
    "chainId": amoy_chainId,
    "verifyingContract": amoy_contract_approveTrade
  },
  "primaryType": "Order",
  "message": {
    maker: maker,
    taker: taker,
    asset: assets,
    currency: currency[0].collection,
    price: currency[0].amountOrID,
    deadline: deadline,
    duration: duration,
    interestPerSecond: interestPerSecond,
    nonce: nonce
  }
};
const signResult = await window.ethereum.send('eth_signTypedData_v4',[amoy_account, signParams]);
const sigStr = signResult.result;

// 4. Create a new order
const orderParams = {
  chainname: amoy_chainName,
  chainid: amoy_chainId,
  useraddr: amoy_account,
  orderinfo: {
    maker: maker,
    taker: taker,
    asset: assets,
    currency: currency,
    deadline: deadline,
    duration: duration,
    interestPerSecond: interestPerSecond,
    nonce: nonce,
    startTime: parseInt(Date.now() / 1000),
    endTime: "0",
    sig: sigStr,
    ordertype: "LOAN"
  }
};
const formData = new URLSearchParams();
formData.append("p", JSON.stringify(orderParams));

fetch("https://test-api.paddlefi.com/api/dapp/createorder.do", {
  method: 'POST',
  headers: {
    "content-type": "application/x-www-form-urlencoded"
  },
  body: formData.toString()
}).then(res => res.json())
  .then(datas => {
    console.log(datas);
  }).catch(err => {
    console.log('Error', err);
  });

Key Notes:

  1. Nonce: Nonce must be retrieved from the contract using Contract.methods.nonces(account).call(). Do not skip this step, even if the nonce is 0.

  2. Signature: Be cautious with hardware wallets, as they may require special handling for signatures.

  3. Assets: Only ERC20 and ERC721 assets are supported as collateral items.

  4. Currency: Only ERC20 tokens and network native tokens are supported as the currency for borrowing.

This example can be used as a starting point for creating loan orders on the Polygon-Amoy chain. Be sure to customize it according to your project's requirements.

Last updated