# Borrowing Function

## Obligation

***

Before doing any borrowing related action, you need to have `Obligation` object. `Obligation` is an object to record your **collateral** and **debt.** So you need to create at least one to do any related borrowing action.

{% hint style="info" %}
It’s possible to have multiple obligation.
{% endhint %}

Each obligation isn’t related to another, so depositing collateral in one obligation doesn’t meant you can borrow an asset using another obligation - even you are the owner of both obligations.

{% hint style="info" %}
Understanding Obligation

`Obligation` is a shared object, instead of owning `Obligation` object in your wallet - you will hold an `ObligationKey` in your wallet. This `ObligationKey` is **a proof you own a particular** `Obligation` that connected to this `ObligationKey`. So what you will see in your wallet is an NFT of `ObligationKey`.
{% endhint %}

Let’s learn how to create `Obligation` object:

### Open Obligation

```tsx
public fun open_obligation(
  version: &Version,
  ctx: &mut TxContext,
): (Obligation, ObligationKey, ObligationHotPotato) { }
```

**Parameters:**

| **Name** | **Type** | **Description**                                                   |
| -------- | -------- | ----------------------------------------------------------------- |
| version  | Version  | The version control object, contract version must match with this |

**Return Values**

| Name                | Type                | Description                                                                                        |
| ------------------- | ------------------- | -------------------------------------------------------------------------------------------------- |
| Obligation          | Obligation          | The obligation object which will be shared                                                         |
| Obligation Key      | ObligationKey       | This is an owned object that serves as proof of ownership of the obligation object.                |
| ObligationHotPotato | ObligationHotPotato | Because open\_obligation function used HotPotato pattern which this pattern is make it composable. |

### Return Obligation

```tsx
public fun return_obligation(
	version: &Version,
	obligation: Obligation,
	obligation_hot_potato: ObligationHotPotato,
	ctx: &mut TxContext,
) { }
```

Parameters:

| **Name**                | **Type**            | **Description**                                                   |
| ----------------------- | ------------------- | ----------------------------------------------------------------- |
| version                 | Version             | The version control object, contract version must match with this |
| obligation              | Obligation          | The obligation object created by `open_obligation`.               |
| obligation\_hot\_potato | ObligationHotPotato | HotPotato object generated by `open_obligation` .                 |

{% hint style="info" %}
You might be wondering why we implement the `HotPotato` pattern in the `open_obligation` function. The reason is that the `Obligation` is a shared object. If we directly return the object, it will be shared, and we won’t be able to **combine** this transaction with another function for borrowing in a single PTB (Programmable Transaction Block).

By using this methodology, we can combine the open obligation transaction with a deposit collateral transaction in one PTB. Also to make the `Obligation` shared, we also need to include the `return_obligation` function to transaction to make the `Obligation` object become shared.
{% endhint %}

Example:

{% tabs %}
{% tab title="Move" %}

```rust
module protocol::foo {

  use sui::coin::{Self, Coin};
  use sui::clock::{Self, Clock};
  use sui::tx_context::{Self ,TxContext};
  use sui::transfer;

  use scallop_protocol::obligation::open_obligation;
  use scallop_protocol::obligation::return_obligation;
  use scallop_protocol::Market as ScallopMarket;
  use scallop_protocol::Version as ScallopVersion;

  ...

  public fun doFoo(
    scallop_version: &ScallopVersion,
    clock: &Clock,
    ctx: &mut TxContext
  ) {
    let (obligation_id, obligation_key, obligation_hot_potato) = scallop_protocol::obligation::open_obligation(
	scallop_version,
	scallop_market,
	coin,
	clock,
	ctx,
    );
    // ----------------
    // Do other tx here

    // ----------------
    scallop_protocol::obligation::return_obligation(
      scallop_version,
      obligation_id,
      obligation_hot_potato
     );
    transfer::transfer(obligation_key, ctx.sender());
  }
}
```

{% endtab %}

{% tab title="Typescript" %}

```typescript
import { getFullnodeUrl, SuiClient, } from '@mysten/sui.js/client';
import { SUI_CLOCK_OBJECT_ID } from '@mysten/sui.js/utils';
import { Ed25519Keypair } from '@mysten/sui/keypairs/ed25519';

const keypair = new Ed25519Keypair();
const address = keypair.getPublicKey().toSuiAddress();

const rpcUrl = getFullnodeUrl('mainnet');
const client = new SuiClient({ url: rpcUrl });
 
const SCALLOP_MARKET_OBJECT = "0xa757975255146dc9686aa823b7838b507f315d704f428cbadad2f4ea061939d9";
const SCALLOP_VERSION_OBJECT = "0x07871c4b3c847a0f674510d4978d5cf6f960452795e8ff6f189fd2088a3f6ac7";

const txb = new TransactionBlock();
txb.setSender();

const [obligationId, obligationKey, obligationHotPotato] = txb.moveCall({
  target: "0xa45b8ffca59e5b44ec7c04481a04cb620b0e07b2b183527bca4e5f32372c5f1a::obligation::open_obligation",
  arguments: [
     txb.object(SCALLOP_VERSION_OBJECT),
  ],
  typeArguments: [],
});

// You can do another stuff here before return the obligation
// Example like deposit collateral then borrow

txb.moveCall({
  target: "0xa45b8ffca59e5b44ec7c04481a04cb620b0e07b2b183527bca4e5f32372c5f1a::obligation::open_obligation",
  arguments: [
    txb.object(SCALLOP_VERSION_OBJECT),
    obligationId,
    obligationHotPotato
  ],
  typeArguments: []
});

txb.transferObjects([obligationKey], txb.pure(address));

await client.signAndExecuteTransaction({
   signer: getKeyPair(keypair),
   transaction: txb,
   requestType: 'WaitForLocalExecution',
   options: {
     showEffects: true,
   },
});
```

{% endtab %}
{% endtabs %}

Now, you are ready to do any borrowing related actions with your Obligation.

To be able to borrow, you need to have collateral. Let’s learn how to deposit collateral.

## Collateral

***

### Deposit Collateral

Allows deposit collateral to your obligation account. This function allow anyone to deposit collateral into other user obligation account. Why everyone can do it? Because this is fine if someone doing it for you. You will not loss anything if someone does it for you. So we open it for everyone.

```tsx
public fun deposit_collateral<T>(
  version: &Version,
  obligation: &mut Obligation,
  coin: Coin<T>,
  ctx: &mut TxContext,
) { }
```

**Parameters:**

| **Name**   | **Type**   | **Description**                                                   |
| ---------- | ---------- | ----------------------------------------------------------------- |
| version    | Version    | The version control object, contract version must match with this |
| obligation | Obligation | The id of obligation, it should be shared object.                 |
| coin       | Coin       | The base asset to be deposit to the collateral pool               |

Events:

* CollateralDepositEvent is emmited when the collateral deposit tx success

Errors:

* **770:** Means your current obligation is locked and need to unstake first from borrow incentive
* **73730:** Means current collateral is not active yet.
* **1794**: Invalid collateral type.
* **1796**: Unable to deposited borrowed coin because the depositor try to deposit same asset as depositor borrowed.

Example:

{% tabs %}
{% tab title="Move" %}

```rust
module protocol::foo {

  use sui::coin::{Self, Coin};
  use sui::clock::{Self, Clock};
  use sui::tx_context::{Self ,TxContext};
  use sui::transfer;

  use scallop_protocol::obligation::open_obligation;
  use scallop_protocol::obligation::return_obligation;
  use scallop_protocol::deposit_collateral::deposit_collateral;
  use scallop_protocol::Market as ScallopMarket;
  use scallop_protocol::Version as ScallopVersion;
  use scallop_protocol::obligation::{Self, Obligation};


  public fun doFoo<T>(
    scallop_version: &ScallopVersion,
    obligation: &mut Obligation,
    coin: Coin<T>,
    ctx: &mut TxContext
   ) {
     let deposit_amount = coin::value(&coin);
	
     let (obligation_id, obligation_key, obligation_hot_potato) = scallop_protocol::obligation::open_obligation(
	scallop_version,
	scallop_market,
	coin,
	clock,
	ctx,
     );
    // ----------------
    // Do other tx here
	
    scallop_protocol::deposit_collateral::deposit_collateral(
      scallop_version,
      obligation_id,
      deposit_amount,
      ctx,
    );
   // ----------------
	
    scallop_protocol::obligation::return_obligation(
      scallop_version,
      obligation_id,
      obligation_hot_potato
    );
    transfer::transfer(obligation_key, ctx.sender());
  }
}
```

{% endtab %}

{% tab title="Typescript" %}

```tsx
import { getFullnodeUrl, SuiClient, } from '@mysten/sui.js/client';
import { SUI_CLOCK_OBJECT_ID } from '@mysten/sui.js/utils';
import { Ed25519Keypair } from '@mysten/sui/keypairs/ed25519';

const keypair = new Ed25519Keypair();
const address = keypair.getPublicKey().toSuiAddress();

const rpcUrl = getFullnodeUrl('mainnet');
const client = new SuiClient({ url: rpcUrl });
 
const SCALLOP_MARKET_OBJECT = "0xa757975255146dc9686aa823b7838b507f315d704f428cbadad2f4ea061939d9";
const SCALLOP_VERSION_OBJECT = "0x07871c4b3c847a0f674510d4978d5cf6f960452795e8ff6f189fd2088a3f6ac7";

const txb = new TransactionBlock();
txb.setSender();
const [sui] = txb.splitCoins(txb.gas, [1e9]);

const [obligationId, obligationKey, obligationHotPotato] = txb.moveCall({
  target: "0xa45b8ffca59e5b44ec7c04481a04cb620b0e07b2b183527bca4e5f32372c5f1a::obligation::open_obligation",
  arguments: [
    txb.object(SCALLOP_VERSION_OBJECT),
  ],
  typeArguments: [],
});

// Deposit Collateral Transaction
txb.moveCall({
  target: "0xa45b8ffca59e5b44ec7c04481a04cb620b0e07b2b183527bca4e5f32372c5f1a::deposit_obligation::deposit_obligation",
  arguments: [
    txb.object(SCALLOP_VERSION_OBJECT),
    obligationId,
    sui
   ],
   typeArguments: ["0x2::sui::SUI"]
});

txb.moveCall({
   target: "0xa45b8ffca59e5b44ec7c04481a04cb620b0e07b2b183527bca4e5f32372c5f1a::obligation::open_obligation",
   arguments: [
      txb.object(SCALLOP_VERSION_OBJECT),
      obligationId,
      obligationHotPotato
    ],
    typeArguments: []
});

txb.transferObjects([obligationKey], txb.pure(address));

await client.signAndExecuteTransaction({
  signer: getKeyPair(keypair),
  transaction: txb,
  requestType: 'WaitForLocalExecution',
  options: {
    showEffects: true,
  },
});
```

See how composable Sui is—you can execute two transactions with just one approval. We'll explore more examples of Sui's composability in programmable transaction blocks (PTBs) within the Scallop protocol.
{% endtab %}
{% endtabs %}

### Withdraw Collateral

Unlike depositing collateral, withdrawing collateral requires the `ObligationKey` object, which is an owned object. This means that only the owner of the obligation account can withdraw collateral; another address cannot withdraw collateral from an obligation account it does not own.

```tsx
public fun withdraw_collateral<T>(
    version: &Version,
    obligation: &mut Obligation,
    obligation_key: &ObligationKey,
    market: &mut Market,
    coin_decimals_registry: &CoinDecimalsRegistry,
    withdraw_amount: u64,
    x_oracle: &XOracle,
    clock: &Clock,
    ctx: &mut TxContext,
  ): Coin<T> { }
```

Parameters:

| **Name**                | **Type**             | **Description**                                                                  |
| ----------------------- | -------------------- | -------------------------------------------------------------------------------- |
| version                 | Version              | The version control object, contract version must match with this                |
| obligation              | Obligation           | The id of obligation, it should be shared object.                                |
| obligation\_key         | ObligationKey        | The key to prove the ownership of the obligation                                 |
| market                  | Market               | The Scallop market object, it contains base assets, and related protocol configs |
| coin\_decimal\_registry | CoinDecimalsRegistry | The package that has decimal coin of base assets.                                |
| withdraw\_amount        | u64                  | The amount assets will withdraw from pool                                        |
| x\_orcale               | XOracle              | The x-oracle object which provides the price of assets                           |
| clock                   | Clock                | The SUI system clock object                                                      |

**Return Value**:

| Name | Type | Description                     |
| ---- | ---- | ------------------------------- |
| Coin | Coin | The withdrawed underlying asset |

**Events**

* CollateralWithdrawEvent is emmited when transaction success

**Errors**

* **770:** Means your current obligation is locked and need to unstake first from borrow incentive
* **0:** Not owner of obligation
* **1795**: Withdraw collateral to much

**Example**

{% tabs %}
{% tab title="Move" %}

```rust
module protocol::foo {

  use sui::coin::{Self, Coin};
  use sui::clock::{Self, Clock};
  use sui::tx_context::{Self ,TxContext};
  
  use sui::transfer;

  use scallop_protocol::withdraw_collateral::withdraw_collateral;
  use scallop_protocol::Market as ScallopMarket;
  use scallop_protocol::Version as ScallopVersion;
  use scallop_protocol::obligation::{Self, Obligation, ObligationKey};
  use scallop_protocol::coin_decimals_registry::CoinDecimalsRegistry;
  use scallop_protocol::x_oracle::XOracle;
  
  ...
	
	
  public fun doFoo<T>(
    version: &ScallopVersion,
    obligation: &mut Obligation,
    obligation_key: &ObligationKey,
    market: &mut ScallopMarket,
    coin_decimals_registry: &CoinDecimalsRegistry,
    withdraw_amount: u64,
    x_oracle: &XOracle,
    clock: &Clock,
    ctx: &mut TxContext
  ) {
    let withdrawed_coin = scallop_protocol::withdraw_collateral::withdraw_collateral(
      scallop_version,
      obligation_id,
      obligation_key,
      market,
      coin_decimals_registry,
      withdraw_amount,
      x_oracle,
      clock,
      ctx,
    );
    transfer::transfer(withdrawed_coin, ctx.sender());
  }
}
```

{% endtab %}

{% tab title="Typescript" %}

```tsx
import { getFullnodeUrl, SuiClient, } from '@mysten/sui.js/client';
import { SUI_CLOCK_OBJECT_ID } from '@mysten/sui.js/utils';
import { Ed25519Keypair } from '@mysten/sui/keypairs/ed25519';

const keypair = new Ed25519Keypair();
const address = keypair.getPublicKey().toSuiAddress();

const rpcUrl = getFullnodeUrl('mainnet');
const client = new SuiClient({ url: rpcUrl });
 
const SCALLOP_MARKET_OBJECT = "0xa757975255146dc9686aa823b7838b507f315d704f428cbadad2f4ea061939d9";
const SCALLOP_VERSION_OBJECT = "0x07871c4b3c847a0f674510d4978d5cf6f960452795e8ff6f189fd2088a3f6ac7";
const SCALLOP_COIN_DECIMAL_REGISTRY = "0x200abe9bf19751cc566ae35aa58e2b7e4ff688fc1130f8d8909ea09bc137d668";
const SCALLOP_X_ORACLE = "0x93d5bf0936b71eb27255941e532fac33b5a5c7759e377b4923af0a1359ad494f";

const txb = new TransactionBlock();
txb.setSender();
const [sui] = txb.splitCoins(txb.gas, [1e9]);

// Before doing this transaction make sure you have updated the price of our x_oracle
const withdrawSui = txb.moveCall({
  target: "0xa45b8ffca59e5b44ec7c04481a04cb620b0e07b2b183527bca4e5f32372c5f1a::withdraw_collateral::withdraw_collateral",
  arguments: [
   txb.object(SCALLOP_VERSION_OBJECT),
   obligationId,
   obligationKey,
   txb.object(SCALLOP_MARKET_OBJECT),
   txb.object(SCALLOP_COIN_DECIMAL_REGISTRY),
   1e9,
   txb.object(SCALLOP_X_ORACLE),
   txb.object(SUI_CLOCK_OBJECT_ID)
  ],
  typeArguments: ["0x2::sui::SUI"]
});

txb.transferObjects([withdrawSui], txb.pure(address));

await client.signAndExecuteTransaction({
  signer: getKeyPair(keypair),
  transaction: txb,
  requestType: 'WaitForLocalExecution',
  options: {
    showEffects: true,
  },
});
```

{% endtab %}
{% endtabs %}

Check here the example how to do update price `x_oracle` :

<https://github.com/scallop-io/sui-scallop-sdk/blob/main/src/builders/oracle.ts>

We recommend you to call this function using our [Scallop SDK](https://github.com/scallop-io/sui-scallop-sdk), so before calling any function related to withdraw Collateral, you need to call update price in the beginning of the [PTB (Programmable Transaction Block)](https://docs.sui.io/guides/developer/sui-101/building-ptb).

Here what your PTB should looks like:

```rust
PTB for calling function that have withdraw collateral:
- update price (you get this from SDK)
- your function that call withdraw_collateral
```

## **Borrowing**

***

### **Borrow**

Allow user to borrow assets from borrowing pools againts collateral deposited by user.

```rust
 public fun borrow<T>(
  version: &Version,
  obligation: &mut Obligation,
  obligation_key: &ObligationKey,
  market: &mut Market,
  coin_decimals_registry: &CoinDecimalsRegistry,
  borrow_amount: u64,
  x_oracle: &XOracle,
  clock: &Clock,
  ctx: &mut TxContext,
): Coin<T> { }
```

**Parameters:**

| Name                     | Type                 | Description                                                                      |
| ------------------------ | -------------------- | -------------------------------------------------------------------------------- |
| version                  | Version              | The version control object, contract version must match with this                |
| obligation               | Obligation           | The id of obligation, it should be shared object.                                |
| obligation\_key          | ObligationKey        | The key to prove the ownership of the obligation                                 |
| market                   | Market               | The Scallop market object, it contains base assets, and related protocol configs |
| coin\_decimals\_registry | CoinDecimalsRegistry | The package that has decimal coin of base assets.                                |
| borrow\_amount           | u64                  | The amount assets will borrow from pool                                          |
| x\_oracle                | XOracle              | The x-oracle object which provides the price of assets                           |
| clock                    | Clock                | The SUI system clock object                                                      |

**Returns Value**

| Name | Type | Description                   |
| ---- | ---- | ----------------------------- |
| coin | Coin | The borrowed underlying asset |

**Events:**

* BorrowEventV3 is emmited when transaction is success

**Errors:**

* **770:** Means your current obligation is locked and need to unstake first from borrow incentive
* **0:** Not owner of obligation
* **1284**: Means unable to borrow a collateral coin
* **1282**: Borrow to small
* **1281**: Borrow to much
* **81924**: Reserve not enough

Example:

{% tabs %}
{% tab title="Move" %}

```rust
module protocol::foo {

  use sui::coin::{Self, Coin};
  use sui::clock::{Self, Clock};
  use sui::tx_context::{Self ,TxContext};
  use sui::transfer;

  use scallop_protocol::borrow::borrow;
  use scallop_protocol::Market as ScallopMarket;
  use scallop_protocol::Version as ScallopVersion;
  use scallop_protocol::obligation::{Self, Obligation, ObligationKey};
  use scallop_protocol::coin_decimals_registry::CoinDecimalsRegistry;
  use scallop_protocol::x_oracle::XOracle;
	
  ...
	
	
  public fun doFoo<T>(
    version: &ScallopVersion,
    obligation: &mut Obligation,
    obligation_key: &ObligationKey,
    market: &mut ScallopMarket,
    coin_decimals_registry: &CoinDecimalsRegistry,
    borrow_amount: u64,
    x_oracle: &XOracle,
    clock: &Clock,
    ctx: &mut TxContext
  ) {
      let borrowed_coin = scallop_protocol::borrow::borrow(
	  scallop_version,
	  obligation_id,
	  obligation_key,
	  market,
	  coin_decimals_registry,
	  borrow_amount,
	  x_oracle,
	  clock,
	  ctx,
	);
		
      transfer::transfer(borrowed_coin, ctx.sender());
  }
}
```

{% endtab %}

{% tab title="Typescript" %}

```tsx
import { getFullnodeUrl, SuiClient, } from '@mysten/sui.js/client';
import { SUI_CLOCK_OBJECT_ID } from '@mysten/sui.js/utils';
import { Ed25519Keypair } from '@mysten/sui/keypairs/ed25519';

const keypair = new Ed25519Keypair();
const address = keypair.getPublicKey().toSuiAddress();

const rpcUrl = getFullnodeUrl('mainnet');
const client = new SuiClient({ url: rpcUrl });
 
const SCALLOP_MARKET_OBJECT = "0xa757975255146dc9686aa823b7838b507f315d704f428cbadad2f4ea061939d9";
const SCALLOP_VERSION_OBJECT = "0x07871c4b3c847a0f674510d4978d5cf6f960452795e8ff6f189fd2088a3f6ac7";
const SCALLOP_COIN_DECIMAL_REGISTRY = "0x200abe9bf19751cc566ae35aa58e2b7e4ff688fc1130f8d8909ea09bc137d668";
const SCALLOP_X_ORACLE = "0x93d5bf0936b71eb27255941e532fac33b5a5c7759e377b4923af0a1359ad494f";

const txb = new TransactionBlock();
txb.setSender();
const [sui] = txb.splitCoins(txb.gas, [1e9]);

// Before doing this transaction make sure you have updated the price of our x_oracle
const withdrawSui = txb.moveCall({
  target: "0xa45b8ffca59e5b44ec7c04481a04cb620b0e07b2b183527bca4e5f32372c5f1a::borrow::borrow",
  arguments: [
    txb.object(SCALLOP_VERSION_OBJECT),
    obligationId,
    obligationKey,
    txb.object(SCALLOP_MARKET_OBJECT),
    txb.object(SCALLOP_COIN_DECIMAL_REGISTRY),
    1e9,
    txb.object(SCALLOP_X_ORACLE),
    txb.object(SUI_CLOCK_OBJECT_ID)
  ],
  typeArguments: ["0x2::sui::SUI"]
});

txb.transferObjects([withdrawSui], txb.pure(address));

await client.signAndExecuteTransaction({
  signer: getKeyPair(keypair),
  transaction: txb,
  requestType: 'WaitForLocalExecution',
  options: {
    showEffects: true,
  },
});
```

{% endtab %}
{% endtabs %}

Check here the example how to do update price `x_oracle` :

<https://github.com/scallop-io/sui-scallop-sdk/blob/main/src/builders/oracle.ts>

We recommend you to call this function using our [Scallop SDK](https://github.com/scallop-io/sui-scallop-sdk), so before calling any function related to borrow, you need to call update price in the beginning of the [PTB (Programmable Transaction Block)](https://docs.sui.io/guides/developer/sui-101/building-ptb).

Here what your PTB should looks like:

```rust
PTB for calling function that have borrow:
- update price (you get this from SDK)
- your function that call borrow
```

### **Repay**

Enabled user to repay underlying assets without requiring the ObligationKey object. Therefore, users can repay the borrowing obligation using any account, not just the obligation owner’s account.

```rust
public entry fun repay<T>(
  version: &Version,
  obligation: &mut Obligation,
  market: &mut Market,
  user_coin: Coin<T>,
  clock: &Clock,
  ctx: &mut TxContext,
) { }
```

**Parameters:**

| Name       | Type       | Description                                                                      |
| ---------- | ---------- | -------------------------------------------------------------------------------- |
| version    | Version    | The version control object, contract version must match with this                |
| obligation | Obligation | The id of obligation, it should be shared object.                                |
| market     | Market     | The Scallop market object, it contains base assets, and related protocol configs |
| user\_coin | Coin       | The coin object used to repay borrowed underlying asset                          |
| clock      | Clock      | The SUI system clock object                                                      |

**Events:**

* RepayEventV3 is emmited when transaction is success

**Errors:**

* **770:** Means your current obligation is locked and need to unstake first from borrow incentive

Example:

{% tabs %}
{% tab title="Move" %}

```rust
module protocol::foo {

  use sui::coin::{Self, Coin};
  use sui::clock::{Self, Clock};
  use sui::tx_context::{Self ,TxContext};
  use sui::transfer;
  use scallop_protocol::repay::repay;
  use scallop_protocol::Market as ScallopMarket;
  use scallop_protocol::Version as ScallopVersion;
  use scallop_protocol::obligation::{Self, Obligation};
  use scallop_protocol::coin_decimals_registry::CoinDecimalsRegistry;

  public fun doFoo<T>(
    version: &ScallopVersion,
    obligation: &mut Obligation,
    market: &mut ScallopMarket,
    user_coin: Coin<T>,
    clock: &Clock,
    ctx: &mut TxContext
  ) {
      scallop_protocol::repay::repay(
	scallop_version,
        obligation_id,
	market,
	user_coin,
	clock,
	ctx,
      );
  }
}
```

{% endtab %}

{% tab title="Typescript" %}

```tsx
import { getFullnodeUrl, SuiClient, } from '@mysten/sui.js/client';
import { SUI_CLOCK_OBJECT_ID } from '@mysten/sui.js/utils';
import { Ed25519Keypair } from '@mysten/sui/keypairs/ed25519';

const keypair = new Ed25519Keypair();
const address = keypair.getPublicKey().toSuiAddress();

const rpcUrl = getFullnodeUrl('mainnet');
const client = new SuiClient({ url: rpcUrl });
 
const SCALLOP_MARKET_OBJECT = "0xa757975255146dc9686aa823b7838b507f315d704f428cbadad2f4ea061939d9";
const SCALLOP_VERSION_OBJECT = "0x07871c4b3c847a0f674510d4978d5cf6f960452795e8ff6f189fd2088a3f6ac7";
const SCALLOP_COIN_DECIMAL_REGISTRY = "0x200abe9bf19751cc566ae35aa58e2b7e4ff688fc1130f8d8909ea09bc137d668";
const SCALLOP_X_ORACLE = "0x93d5bf0936b71eb27255941e532fac33b5a5c7759e377b4923af0a1359ad494f";

const txb = new TransactionBlock();
txb.setSender();
const [sui] = txb.splitCoins(txb.gas, [1e9]);

// Before doing this transaction make sure you have updated the price of our x_oracle
const withdrawSui = txb.moveCall({
  target: "0xa45b8ffca59e5b44ec7c04481a04cb620b0e07b2b183527bca4e5f32372c5f1a::repay::repay",
  arguments: [
    txb.object(SCALLOP_VERSION_OBJECT),
    obligationId,
    txb.object(SCALLOP_MARKET_OBJECT),
    sui,
    txb.object(SUI_CLOCK_OBJECT_ID)
  ],
  typeArguments: ["0x2::sui::SUI"]
});

await client.signAndExecuteTransaction({
  signer: getKeyPair(keypair),
  transaction: txb,
  requestType: 'WaitForLocalExecution',
  options: {
    showEffects: true,
  },
});
```

{% endtab %}
{% endtabs %}


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.scallop.io/integrations/contract-integration/borrowing-function.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
