Nomial Docs
  • Concepts
    • What is Nomial
    • Why use Nomial
  • Protocol
    • Architecture Overview
  • Smart Contracts
  • Loan Process
  • Interest Rate Model
  • Solvers
    • Take out a loan
  • View loan status
  • Repay a loan
  • Security
    • Security Model Overview
  • Resources
    • Terminology
    • Connect with us
Powered by GitBook
On this page
  • Prerequisites
  • Process Overview
  • Step 1: Request Borrow Digest
  • Step 2: Sign the Digest
  • Step 3: Submit Borrow Request
  • Step 4: Execute the Transaction
  1. Solvers

Take out a loan

This guide explains how to take out a loan from an inventory pool

Prerequisites

  • An account that has been whitelisted as a borrower on the target inventory pool

  • A sufficient amount of collateral deposited

Process Overview

  1. Request a borrow digest from the API

  2. Sign the digest with your private key

  3. Submit the borrow request with your signature

  4. Execute the resulting transaction on-chain

Step 1: Request Borrow Digest

This step authenticates your request, preventing any other address from requesting a borrow on your behalf.

Make a GET request to https://api.nomial.io/borrow/digest with the following query parameters:

{
  "chain_id": "1",         // The chain ID (e.g., 1 for Ethereum mainnet)
  "pool": "0x...",         // The inventory pool address
  "borrower": "0x...",     // Your borrower address
  "amount": "1000000",     // The amount of ERC20 to borrow (in base units)
  "recipient": "0x...",    // The address that will receive the borrowed funds (can be borrower address)
  "expiry": "1234567890",  // Unix timestamp when the request expires (1 hour in the future or less)
  "salt": "0x..."          // An arbitrary 32-byte hex string to force request uniqueness
}

The API will return a digest that needs to be signed by your borrower address

{
  "digest": "0x..."  // The digest to sign
}

Step 2: Sign the Digest

Sign the provided hex digest directly with the private key of your borrower address. The resulting signature must use the standard 65-byte Ethereum format (r, s, v).

Be sure to sign the raw digest, without including an ERC-191 (“Ethereum Signed Message”) prefix.

Step 3: Submit Borrow Request

Make a POST request to https://api.nomial.io/borrow. This should include identical parameters and values to your digest request, with the addition of signature (your signature of the request digest).

{
  "chain_id": "1",         // The chain ID
  "pool": "0x...",         // The inventory pool address
  "borrower": "0x...",     // Your borrower address
  "amount": "1000000",     // The amount to borrow in base units
  "recipient": "0x...",    // The address that will receive the borrowed funds
  "expiry": "1234567890",  // Unix timestamp when the request expires
  "salt": "0x...",         // The same salt used for the request digest
  "signature": "0x..."     // Your signature of the request digest
}

If your borrow request is valid, the API will return a transaction with validator signatures that can be executed to the inventory pool's owner (access manager):

{
  "call": {
    "chain": {
      "id": "1",
      "name": "ethereum"
    },
    "contract": {
      "name": "InventoryPoolDefaultAccessManager01",
      "address": "0x..."
    },
    "function": "borrow(address pool, uint256 amount, address recipient, uint256 expiry, bytes32 salt, bytes[] signatures)",
    "selector": "0x...",
    "calldata": "0x...",
    "params": [
      {
        "name": "pool",
        "value": "0x..."
      },
      {
        "name": "amount",
        "value": "1000000"
      },
      {
        "name": "recipient",
        "value": "0x..."
      },
      {
        "name": "expiry",
        "value": "1234567890"
      },
      {
        "name": "salt",
        "value": "0x..."
      },
      {
        "name": "signatures",
        "value": ["0x...", "0x..."]
      }
    ]
  },
  "tx": {
    "to": "0x...",         // The access manager contract address
    "data": "0x...",       // The encoded function call data
    "value": "0",          // The amount of native token to send
    "chain_id": "1"        // The chain ID
  },
  "signed_digest": "0x...", // The digest that was signed
  "validator_signatures": [ // Array of validator signatures
    {
      "validator": "validator1",
      "signature": "0x..."
    }
  ]
}

Step 4: Execute the Transaction

You can submit your signed transaction to the chain it was intended for. Here's an example using ethers.js:

const provider = new ethers.providers.JsonRpcProvider(rpcUrl);

const tx = {
  to: response.tx.to,
  data: response.tx.data,
  value: response.tx.value
};

// Send the transaction
const result = await wallet.connect(provider).sendTransaction(tx);
await result.wait();

Alternatively, you can construct the transaction yourself using the call object:

// Import the contract ABI
const accessManagerABI = [
  "function borrow(address pool, uint256 amount, address recipient, uint256 expiry, bytes32 salt, bytes[] signatures)"
];

// Create contract instance
const accessManager = new ethers.Contract(
  response.call.contract.address,
  accessManagerABI,
  wallet
);

// Execute the borrow function
const result = await accessManager.borrow(
  response.call.params[0].value,  // pool
  response.call.params[1].value,  // amount
  response.call.params[2].value,  // recipient
  response.call.params[3].value,  // expiry
  response.call.params[4].value,  // salt
  response.call.params[5].value   // signatures
);
await result.wait();

Note that you must execute your transaction on the access manager contract that is owner on the inventory pool, and not the inventory pool itself.

PreviousInterest Rate ModelNextView loan status

Last updated 10 hours ago