# Guide to Create a Flexible Loan Transaction

Objective

Guide to create a loan transaction from the Flexible Pool Lending based on API:&#x20;

<https://docs.danogo.io/developers/integration/apis/loan>

{% stepper %}
{% step %}

### Step 1: Get Required Parameters

Use the provided API to get necessary information for the transaction.
{% endstep %}

{% step %}

### Step 2: Understanding Redeemer Structures

#### Float LendingAction Redeemer Structure

* LendingAction redeemer structure for Create Loan:

{% code title="LendingAction (type)" %}

```
pub type LendingAction {
    CreatePool {..}
    UpdateMarketParam {..}
    TopupWithdraw {..}
    CreateLoan {
        pool_out_idx: Int, // Required
        loan_out_idx: Int, // Required
        fee_out_idx: Option<Int>, // Required if fee > 0
        protocol_cfg_ref_idx: Int, // Required
        market_ref_idx: Int, // Required
        pool_in_out_ref: OutputReference, // Required
    }
}
```

{% endcode %}

* Concrete example for Create Loan:

```
CreateLoan {
        pool_out_idx: 2,
        loan_out_idx: 1,
        fee_out_idx: Some(0),
        protocol_cfg_ref_idx: 1,
        market_ref_idx: 0,
        pool_in_out_ref: pool_in.output_reference,
}
```

* Diagnostic Notation form:

```
124_0([_
        2,
        1,
        121([_ 0]),
        1,
        0,
        121_0([_
                h'516a6e6806e9dc771c3dce9a5fa27a4e6ec994b4609839c4df42778e9bd63bc5',
                0,
        ]),
])
```

***

#### Staking Contract StakingContractAction Redeemer Structure

* StakingContractAction redeemer structure for Topup Withdraw Staking:

```
pub type StakingContractAction {
    CreateContract {..}
    TopupWithdrawStaking(Int) // staking contract out_idx
    ...
}
```

* Concrete example for Topup Withdraw Staking:

```
TopupWithdrawStaking(0)
```

* Diagnostic Notation form:

```
122([_ 0])
```

***

#### OraclePriceCalcRdmr Redeemer Structure

* OraclePriceCalcRdmr redeemer structure:

```
pub type OraclePriceCalcRdmr {
  global_config_idx: Int,
  // List<Int>
  // Serialized list of indices of OraclePath UTxOs in reference inputs, each containing price path configurations. Each index is encoded as a single byte.
  oracle_path_idxs: ByteArray,
  // List<(UTxOTarget, OracleUtxoType, Index)>
  // Serialized oracle source specifications containing: (UTxO location type, oracle type, index). Encoded as 3 bytes per oracle: byte 1 = UTxO target type (0=Ref, 1=Out, 2=In), byte 2 = oracle type constant, byte 3 = index value
  oracle_idxs: ByteArray,
  prices: OraclePriceInfo,
  borrow_rates: Pairs<YieldToken, Basis>,
}

pub type UTxOTarget {
    Ref
    Out
    In
}

pub type OracleUtxoType {
    TOrcfaxFsp
    TOrcfaxFs
    TLiqwidMarketState
    TLiqwidMarketParam
    TLiqwidOracleV2
    TDanogoPool
    TIndigo
    TDjed
    TDanogoStaking
    TMinswapLP
    TLiqwidOracleV1
    TSplashLiquidityPoolCpammG1
    TSplashLiquidityPoolCpammG2
    TSplashLiquidityPoolCpammG3
    TSplashLiquidityPoolStable
    TCharli3
    TMinswapLPStable
}

// Pairs<ToToken, Pairs<FromToken, PRational>>,
pub type OraclePriceInfo =
    Pairs<TupleAsset, Pairs<TupleAsset, (CalcType, PRational)>>

// 0: Normal
// 1: Splash
pub type CalcType =
    Int
```

* Concrete example:

```
OraclePriceCalcRdmr {
  global_config_idx: 2,
  oracle_path_idxs: h'05', // [5]
  oracle_idxs: h'010800020d01' // [(Out, TDanogoStaking, 0), (In, TSplashLiquidityPoolCpammG3, 1)],
  // Price from sAda to Ada and from fUSDM to Ada
  prices: [Pair(Ada, [Pair(sAda, (0, PRational(63278285520, 62837134123))), Pair(fUSDM, (1, PRational(186046204, 181197120)))])],
  borrow_rates: None,
}

```

* Diagnostic Notation form:

```
121_0([_
    2,
    h'05',
    h'010800020d01',
    {
        [_ h'', h'']: {
            [_
                h'703d581d9a657d1326aea6a754cdcf191efb22133a62a181951156cf',
                h'',
            ]: [_ 0, 121_0([_ 63278285520_3, 62837134123_3])],
            [_
                h'834a15101873b4e1ddfaa830df46792913995d8738dcde34eda27905',
                h'665553444d',
            ]: [_ 1, 121_0([_ 186046204_2, 181197120_2])],
        },
    },
    {},
])
```

{% endstep %}

{% step %}

### Step 3: Create Transaction

Follow these substeps to craft the transaction. Convert API-returned times (milliseconds) to the format expected by your tooling.

{% stepper %}
{% step %}

#### Validity Range

* Ensure transaction time-to-live (TTL) <= 6 minutes.
* Transaction start time is set to value from `PoolOutputUtxo.datum.interestTime`.
* API returns data in milliseconds, convert to appropriate format for your tool.
  {% endstep %}

{% step %}

#### Inputs

Note: All `outRef`, `address`, `coin`, `multiAssets` information is provided by the API.

* PoolInUtxo: Pool you want to borrow from.
  * Spend redeemer: Build according to Float's LendingAction redeemer CreateLoan structure, ensure correct index specifications.
* StakingContractInUtxo: Staking Contract pool to withdraw base token for lending, returned by API.
  * Spend redeemer: Build according to StakingContractAction redeemer TopupWithdrawStaking structure, ensure correct index specifications.
* Input from wallet containing tokens needed for loan collateral.
  {% endstep %}

{% step %}

#### Outputs

* PoolOutUtxo: Pool output after borrowing.
  * All pool output UTxO information is provided by API.
* LoanOutUtxo: Loan output.
  * All loan output UTxO information is provided by API.
  * Note: Address returned by API only includes loan script payment key. If you want to receive rewards from loan when delegating to pool, specify borrower's stake key for loan address.
* FeeOutUtxo: Transaction fee output.
  * All fee output UTxO information is provided by API.
  * Not required if API doesn't return it.
* StakingContractOutUtxo: Staking Contract output after withdrawing base token for lending.
  * All Staking Contract output UTxO information is provided by API.
  * Not required if API doesn't return it.
* WithdrawalFeeOutUtxo: Withdrawal fee output.
  * All withdrawal fee output UTxO information is provided by API.
  * Not required if API doesn't return it.
    {% endstep %}

{% step %}

#### Reference Inputs

Add all reference inputs returned in API.
{% endstep %}

{% step %}

#### Withdrawal

* OraclePriceCalcRdmr
  * Add withdrawal to reward address with reward amount as returned by API.
  * Reward redeemer: Has OraclePriceCalcRdmr redeemer structure:
    * `prices` information returned by API. With `borrowToken` as `ToToken` and `collateralToken` as `FromToken`.
    * `global_config_idx`, `oracle_path_idxs` and `oracle_idxs` information from reference inputs.
    * For `oracle_idxs`, if UTxO is in output then `UTxOTarget` is `Out`; if in reference input then `UTxOTarget` is `Ref`. (No `In` case in Create Float Loan.)
    * CalcType in `prices`: Always 1 for Create Float Loan.
* Withdraw Staking Reward (Optional)
  * Reward address with reward amount as returned by API.
  * Redeemer: Build according to StakingContractAction redeemer TopupWithdrawStaking structure.
    {% endstep %}

{% step %}

#### Mint

* API returns complete mint information including `policyId`, `assets` and `redeemerType`.
* For `redeemerType`:
  * `FLOAT`: Add mint with `policyId` and `assets` set with Float's LendingAction CreateLoan redeemer.
  * `STAKING`: Add mint with `policyId` and `assets` set with StakingContractAction TopupWithdrawStaking redeemer.
    {% endstep %}

{% step %}

#### Auxiliary Data

* Add metadata for loanOwnerNft according to information returned by API (Optional).

Note: After sorting inputs and reference inputs according to chain sort order, ensure correct index specification in redeemers.
{% endstep %}
{% endstepper %}
{% endstep %}
{% endstepper %}
