openapi: 3.0.3
info:
  title: Router Smart Contract
  description: >
    The Router Smart Contract serves as a convenient tool for efficiently
    managing and monitoring Pair contracts in a decentralized environment. It
    enables the deployer to easily keep track of the existing Pair contracts and
    offers a wide array of settings functions that make the management of the
    liquidity pools much easier.


    ## Overview


    The Router contract provides:


    - **Pair Management**: Create and manage liquidity pairs

    - **LP Token Issuance**: Issue LP tokens for liquidity providers

    - **Multi-Pair Swaps**: Execute multiple swaps in a single transaction

    - **User Pair Creation**: Allow users to create their own trading pairs


    ## How Users Create a Pair


    1. **Create the Pair**: Use `createPair` endpoint to create the liquidity
    pair

    2. **Issue LP Token**: Use `issueLpToken` endpoint to create the LP token

    3. **Add Liquidity**: Call `addInitialLiquidity` on the pair, providing a
    value greater than configured in `configEnableByUserParameters`

    4. **Lock Tokens**: After adding initial liquidity, lock the received tokens
    using `lockTokens` from Simple-Lock contract. The lock period must be equal
    to or greater than the minimum configured. After locking, the user receives
    an SFT that can be used to redeem tokens after the lock period

    5. **Enable Swap**: To activate swap on the created pair, send the SFT
    received from `lockTokens` to `setSwapEnabledByUser`. The Router validates
    the value and lock period and returns the SFT to the user


    ## ABI


    ABI reference for the Router smart contract (`Router`). Framework:
    **klever-sc v0.45.0**.


    ### createPair


    Creates a new trading pair on the DEX.


    ```json

    {
      "name": "createPair",
      "mutability": "mutable",
      "inputs": [
        { "name": "first_token_id", "type": "TokenIdentifier" },
        { "name": "second_token_id", "type": "TokenIdentifier" }
      ],
      "outputs": [
        { "type": "Address" }
      ]
    }

    ```


    ### issueLpToken


    Issues the LP token for an already created pair.


    ```json

    {
      "name": "issueLpToken",
      "mutability": "mutable",
      "inputs": [
        { "name": "pair_address", "type": "Address" },
        { "name": "lp_token_display_name", "type": "bytes" },
        { "name": "lp_token_ticker", "type": "bytes" }
      ],
      "outputs": []
    }

    ```


    ### setSwapEnabledByUser


    Enables swap on a user-created pair (requires locked tokens as payment).


    ```json

    {
      "name": "setSwapEnabledByUser",
      "mutability": "mutable",
      "payableInTokens": ["*"],
      "inputs": [
        { "name": "pair_address", "type": "Address" }
      ],
      "outputs": []
    }

    ```


    ### multiPairSwap


    Executes a multi-hop swap through multiple pairs in a single transaction.


    ```json

    {
      "name": "multiPairSwap",
      "mutability": "mutable",
      "payableInTokens": ["*"],
      "inputs": [
        {
          "name": "swap_operations",
          "type": "variadic<multi<Address,bytes,TokenIdentifier,BigUint>>",
          "multi_arg": true
        }
      ],
      "outputs": [
        { "type": "List<KdaTokenPayment>" }
      ]
    }

    ```


    Each swap operation is a tuple: `(pair_address, function_name, token_out,
    amount_out_min)`.


    ### EnableSwapByUserConfig Type


    ```json

    {
      "EnableSwapByUserConfig": {
        "type": "struct",
        "fields": [
          { "name": "locked_token_id", "type": "TokenIdentifier" },
          { "name": "min_locked_token_value", "type": "BigUint" },
          { "name": "min_lock_period_epochs", "type": "u64" }
        ]
      }
    }

    ```
  version: 1.0.0
  contact:
    name: Bitcoin.me DeFi
    url: https://bitcoin.me
servers:
  - url: https://node.testnet.klever.org
    description: Testnet
  - url: https://node.mainnet.klever.org
    description: Mainnet
tags:
  - name: Endpoints
    description: Write operations that modify contract state
paths:
  /vm/query#createPair:
    post:
      tags:
        - Endpoints
      summary: Create Pair
      description: >
        Creates a new liquidity pair and returns the pair contract address.


        **Process:**

        1. Validates the token pair

        2. Deploys a new Pair contract based on the template

        3. Returns the new pair contract address in the response data


        **Response Decoding:**

        The returned address is hex-encoded and needs to be decoded using the
        Klever decoder.


        **Example Response:**

        ```

        Raw: 00000000000000000500b7b4a14e4567a64b122ee61b8717ae11e210809ac3e6

        Decoded: klv1qqqqqqqqqqqqqpgqk762znj9v7nyky3wucdcw9awz83ppqy6c0nqhe2qaz

        ```
      operationId: createPair
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - scAddress
                - funcName
                - args
              properties:
                scAddress:
                  type: string
                  description: Router contract address
                  example: >-
                    klv1qqqqqqqqqqqqqpgqu34l5t0w5qjajuk5w7j9jy4rxxhj974rx04sdw565h
                funcName:
                  type: string
                  enum:
                    - createPair
                  example: createPair
                args:
                  type: array
                  items:
                    type: string
                  description: >
                    Arguments:

                    - `first_token_id` (TokenIdentifier): First token identifier

                    - `second_token_id` (TokenIdentifier): Second token
                    identifier
                  example:
                    - string:KFI
                    - string:KLV
            examples:
              create_pair:
                summary: Create KFI-KLV pair
                value:
                  scAddress: >-
                    klv1qqqqqqqqqqqqqpgqu34l5t0w5qjajuk5w7j9jy4rxxhj974rx04sdw565h
                  funcName: createPair
                  args:
                    - string:KFI
                    - string:KLV
      responses:
        '200':
          description: Returns the new pair contract address (hex-encoded)
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/VMQueryResponse'
  /vm/query#issueLpToken:
    post:
      tags:
        - Endpoints
      summary: Issue LP Token
      description: >
        Creates the LP token that will be distributed to users who add liquidity
        to the pool.


        **Process:**

        1. Validates the pair exists

        2. Creates a new LP token with the specified name and ticker

        3. Assigns the token to the pair contract


        **Prerequisites:**

        - The pair must be created first using `createPair`

        - Caller must be the pair owner or have appropriate permissions


        **Note:** After issuing the LP token, you need to set the local roles
        using `setLocalRoles` to allow minting.
      operationId: issueLpToken
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - scAddress
                - funcName
                - args
              properties:
                scAddress:
                  type: string
                  description: Router contract address
                funcName:
                  type: string
                  enum:
                    - issueLpToken
                args:
                  type: array
                  items:
                    type: string
                  description: >
                    Arguments:

                    - `pair_address` (ManagedAddress): Address of the pair
                    contract

                    - `lp_token_display_name` (ManagedBuffer): Display name for
                    the LP token

                    - `lp_token_ticker` (ManagedBuffer): Ticker symbol for the
                    LP token
                  example:
                    - >-
                      address:klv1qqqqqqqqqqqqqpgqk762znj9v7nyky3wucdcw9awz83ppqy6c0nqhe2qaz
                    - string:KFIKLV-LP
                    - string:KFIKLVLP
            examples:
              issue_lp_token:
                summary: Issue LP token for KFI-KLV pair
                value:
                  scAddress: >-
                    klv1qqqqqqqqqqqqqpgqu34l5t0w5qjajuk5w7j9jy4rxxhj974rx04sdw565h
                  funcName: issueLpToken
                  args:
                    - >-
                      address:klv1qqqqqqqqqqqqqpgqk762znj9v7nyky3wucdcw9awz83ppqy6c0nqhe2qaz
                    - string:KFIKLV-LP
                    - string:KFIKLVLP
      responses:
        '200':
          description: LP token created successfully
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/VMQueryResponse'
  /vm/query#setSwapEnabledByUser:
    post:
      tags:
        - Endpoints
      summary: Set Swap Enabled By User
      description: >
        Allows the creator of a pair to activate the swap functionality for that
        pair.


        **Process:**

        1. After adding initial liquidity (`addInitialLiquidity`), the user
        receives LP tokens

        2. These LP tokens must be locked in the Simple-Lock contract

        3. After locking, the user receives an SFT (Semi-Fungible Token)

        4. To activate swap, send the SFT to this endpoint

        5. The Router validates the value and lock period

        6. The SFT is returned to the user after validation


        **Requirements:**

        - The SFT must have a value greater than `min_locked_token_value`

        - The lock period must be greater than `min_lock_period_epochs`

        - Both values are configured via `configEnableByUserParameters`


        **Payment:** The SFT received from locking LP tokens
      operationId: setSwapEnabledByUser
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - scAddress
                - funcName
                - args
                - value
              properties:
                scAddress:
                  type: string
                  description: Router contract address
                funcName:
                  type: string
                  enum:
                    - setSwapEnabledByUser
                args:
                  type: array
                  items:
                    type: string
                  description: >
                    Arguments:

                    - `pair_address` (ManagedAddress): Address of the pair to
                    enable
                  example:
                    - >-
                      address:klv1qqqqqqqqqqqqqpgqk762znj9v7nyky3wucdcw9awz83ppqy6c0nqhe2qaz
                value:
                  type: string
                  description: SFT payment from Simple-Lock
                  example: LOCK-2U1O/1=1000000
            examples:
              enable_swap:
                summary: Enable swap for a pair
                value:
                  scAddress: >-
                    klv1qqqqqqqqqqqqqpgqu34l5t0w5qjajuk5w7j9jy4rxxhj974rx04sdw565h
                  funcName: setSwapEnabledByUser
                  args:
                    - >-
                      address:klv1qqqqqqqqqqqqqpgqk762znj9v7nyky3wucdcw9awz83ppqy6c0nqhe2qaz
                  value: LOCK-2U1O/1=1000000
      responses:
        '200':
          description: Swap enabled and SFT returned to user
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/VMQueryResponse'
  /vm/query#multiPairSwap:
    post:
      tags:
        - Endpoints
      summary: Multi Pair Swap
      description: >
        Allows users to execute a list of swaps in a single transaction, routing
        through multiple pairs.


        **Use Case:**

        When there's no direct pair between two tokens, you can route through
        intermediate pairs. For example, to swap KFI to ZART when only KFI-KLV
        and KLV-ZART pairs exist.


        **Swap Parameters (for each swap):**

        - `pair_address`: The liquidity pair contract address

        - `function`: Swap type - `swapTokensFixedInput` or
        `swapTokensFixedOutput`

        - `token_wanted`: The token to receive from the swap

        - `amount_wanted`: The amount of `token_wanted` to receive


        **Supported Functions:**

        - `swapTokensFixedInput`: Fixed input amount, variable output

        - `swapTokensFixedOutput`: Variable input, fixed output amount


        **Note:** You can mix `swapTokensFixedInput` and `swapTokensFixedOutput`
        in the same multi-swap transaction.
      operationId: multiPairSwap
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - scAddress
                - funcName
                - args
                - value
              properties:
                scAddress:
                  type: string
                  description: Router contract address
                funcName:
                  type: string
                  enum:
                    - multiPairSwap
                args:
                  type: array
                  items:
                    type: string
                  description: >
                    Arguments (repeated for each swap in the route):

                    - `pair_address` (ManagedAddress): Pair contract address

                    - `function` (string): "swapTokensFixedInput" or
                    "swapTokensFixedOutput"

                    - `token_wanted` (TokenIdentifier): Output token

                    - `amount_wanted` (BigUint): Minimum/exact output amount
                  example:
                    - >-
                      address:klv1qqqqqqqqqqqqqpgqk762znj9v7nyky3wucdcw9awz83ppqy6c0nqhe2qaz
                    - string:swapTokensFixedInput
                    - string:KLV
                    - BigUint:9
                    - >-
                      address:klv1qqqqqqqqqqqqqpgqlequ2zkergzrpzh5nzadduh0r80qau7mc0nqtwx8hz
                    - string:swapTokensFixedInput
                    - string:ZART-3RIP
                    - BigUint:8
                value:
                  type: string
                  description: Initial token payment
                  example: KFI=10
            examples:
              multi_swap_fixed_input:
                summary: Multi-swap with fixed input (KFI → KLV → ZART)
                value:
                  scAddress: >-
                    klv1qqqqqqqqqqqqqpgqu34l5t0w5qjajuk5w7j9jy4rxxhj974rx04sdw565h
                  funcName: multiPairSwap
                  args:
                    - >-
                      address:klv1qqqqqqqqqqqqqpgqk762znj9v7nyky3wucdcw9awz83ppqy6c0nqhe2qaz
                    - string:swapTokensFixedInput
                    - string:KLV
                    - BigUint:9
                    - >-
                      address:klv1qqqqqqqqqqqqqpgqlequ2zkergzrpzh5nzadduh0r80qau7mc0nqtwx8hz
                    - string:swapTokensFixedInput
                    - string:ZART-3RIP
                    - BigUint:8
                  value: KFI=10
              multi_swap_fixed_output:
                summary: Multi-swap with fixed output
                value:
                  scAddress: >-
                    klv1qqqqqqqqqqqqqpgqu34l5t0w5qjajuk5w7j9jy4rxxhj974rx04sdw565h
                  funcName: multiPairSwap
                  args:
                    - >-
                      address:klv1qqqqqqqqqqqqqpgqk762znj9v7nyky3wucdcw9awz83ppqy6c0nqhe2qaz
                    - string:swapTokensFixedOutput
                    - string:KLV
                    - BigUint:9
                    - >-
                      address:klv1qqqqqqqqqqqqqpgqlequ2zkergzrpzh5nzadduh0r80qau7mc0nqtwx8hz
                    - string:swapTokensFixedOutput
                    - string:ZART-25M9
                    - BigUint:8
                  value: KFI=100
              multi_swap_mixed:
                summary: Multi-swap mixing fixed input and output
                value:
                  scAddress: >-
                    klv1qqqqqqqqqqqqqpgqu34l5t0w5qjajuk5w7j9jy4rxxhj974rx04sdw565h
                  funcName: multiPairSwap
                  args:
                    - >-
                      address:klv1qqqqqqqqqqqqqpgqk762znj9v7nyky3wucdcw9awz83ppqy6c0nqhe2qaz
                    - string:swapTokensFixedInput
                    - string:KLV
                    - BigUint:10
                    - >-
                      address:klv1qqqqqqqqqqqqqpgqlequ2zkergzrpzh5nzadduh0r80qau7mc0nqtwx8hz
                    - string:swapTokensFixedOutput
                    - string:ZART-25M9
                    - BigUint:50
                  value: KFI=100
      responses:
        '200':
          description: Returns final output tokens and any excess input tokens
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/VMQueryResponse'
components:
  schemas:
    VMQueryResponse:
      type: object
      properties:
        data:
          type: object
          properties:
            returnData:
              type: array
              items:
                type: string
            returnCode:
              type: string
            returnMessage:
              type: string
        error:
          type: string
        code:
          type: string
    KdaTokenPayment:
      type: object
      description: Token payment structure
      properties:
        assetId:
          type: string
          description: Asset identifier (e.g., "KFI", "KLV")
        assetType:
          type: string
          enum:
            - Fungible
            - SemiFungible
        from:
          type: string
          description: Sender address
        to:
          type: string
          description: Recipient address
        value:
          type: string
          description: Amount transferred
