# Take out a loan

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

| Name        | Description                                                                |
| ----------- | -------------------------------------------------------------------------- |
| `chain_id`  | The chain ID (e.g., `1` for Ethereum mainnet)                              |
| `pool`      | The inventory pool address                                                 |
| `borrower`  | Your borrower address                                                      |
| `amount`    | The amount of ERC20 to borrow (in base units)                              |
| `recipient` | The address that will receive the borrowed funds (can be same as borrower) |
| `expiry`    | Unix timestamp when the request expires (e.g., 1 hour in the future)       |
| `salt`      | Arbitrary 32-byte hex string to ensure request uniqueness                  |

**Example**

```
curl "https://api.nomial.io/borrow/digest?\
    chain_id=1&\
    pool=0xabc123...&\
    borrower=0xdef456...&\
    amount=1000000&\
    recipient=0xdef456...&\
    expiry=1234567890&\
    salt=0xabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdef"

```

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

```json
{
  "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.

#### Using Foundry cast to sign manually

You can use the [cast](https://getfoundry.sh/cast/overview) CLI tool to sign the digest manually with the [cast wallet sign](https://getfoundry.sh/cast/reference/cast-wallet-sign) command

```
cast wallet sign --private-key <BORROWER_PRIVATE_KEY> --no-hash <DIGEST>
```

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

```json
{
  "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):

```json
{
  "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:

<pre class="language-javascript"><code class="lang-javascript">const provider = new ethers.providers.JsonRpcProvider(rpcUrl);
<strong>
</strong><strong>const tx = {
</strong>  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();
</code></pre>

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

```javascript
// 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.
