DeFiCh/jellyfish

View on GitHub
packages/jellyfish-api-core/src/category/loan.ts

Summary

Maintainability
C
1 day
Test Coverage
import { ApiClient, token } from '..'
import {
  AuctionPagination,
  CloseVault,
  CreateVault,
  DepositVault,
  ListAuctionHistoryDetail,
  ListAuctionHistoryPagination,
  ListVaultOptions,
  PlaceAuctionBid,
  UpdateVault,
  Vault,
  VaultActive,
  VaultLiquidation,
  VaultPagination,
  WithdrawVault
} from './vault'
import BigNumber from 'bignumber.js'

/**
 * @deprecated exports would be deprecated soon
 */
export * from './vault'

/**
 * Loan RPCs for DeFi Blockchain
 */
export class Loan {
  private readonly client: ApiClient

  constructor (client: ApiClient) {
    this.client = client
  }

  /**
   * Creates a loan scheme transaction.
   *
   * @param {CreateLoanScheme} scheme
   * @param {number} scheme.minColRatio Minimum collateralization ratio
   * @param {BigNumber} scheme.interestRate Interest rate
   * @param {string} scheme.id Unique identifier of the loan scheme, max 8 chars
   * @param {UTXO[]} [utxos = []] Specific UTXOs to spend
   * @param {string} utxos.txid Transaction Id
   * @param {number} utxos.vout Output number
   * @return {Promise<string>} LoanSchemeId, also the txn id for txn created to create loan scheme
   */
  async createLoanScheme (scheme: CreateLoanScheme, utxos: UTXO[] = []): Promise<string> {
    return await this.client.call('createloanscheme', [scheme.minColRatio, scheme.interestRate, scheme.id, utxos], 'number')
  }

  /**
   * Updates an existing loan scheme.
   *
   * @param {UpdateLoanScheme} scheme
   * @param {number} scheme.minColRatio Minimum collateralization ratio
   * @param {BigNumber} scheme.interestRate Interest rate
   * @param {string} scheme.id Unique identifier of the loan scheme, max 8 chars
   * @param {number} [scheme.activateAfterBlock] Block height at which new changes take effect
   * @param {UTXO[]} [utxos = []] Specific UTXOs to spend
   * @param {string} utxos.txid Transaction Id
   * @param {number} utxos.vout Output number
   * @return {Promise<string>} Hex string of the transaction
   */
  async updateLoanScheme (scheme: UpdateLoanScheme, utxos: UTXO[] = []): Promise<string> {
    return await this.client.call('updateloanscheme', [scheme.minColRatio, scheme.interestRate, scheme.id, scheme.activateAfterBlock, utxos], 'number')
  }

  /**
   * Destroys a loan scheme.
   *
   * @param {DestroyLoanScheme} scheme
   * @param {string} scheme.id Unique identifier of the loan scheme, max 8 chars
   * @param {number} [scheme.activateAfterBlock] Block height at which new changes take effect
   * @param {UTXO[]} [utxos = []] Specific UTXOs to spend
   * @param {string} utxos.txid Transaction Id
   * @param {number} utxos.vout Output number
   * @return {Promise<string>} Hex string of the transaction
   */
  async destroyLoanScheme (scheme: DestroyLoanScheme, utxos: UTXO[] = []): Promise<string> {
    return await this.client.call('destroyloanscheme', [scheme.id, scheme.activateAfterBlock, utxos], 'number')
  }

  /**
   * List all available loan schemes.
   *
   * @return {Promise<LoanSchemeResult[]>}
   */
  async listLoanSchemes (): Promise<LoanSchemeResult[]> {
    return await this.client.call('listloanschemes', [], 'bignumber')
  }

  /**
   * Get loan scheme.
   *
   * @param {string} id Unique identifier of the loan scheme, max 8 chars.
   * @return {Promise<GetLoanSchemeResult>}
   */
  async getLoanScheme (id: string): Promise<GetLoanSchemeResult> {
    return await this.client.call('getloanscheme', [id], 'bignumber')
  }

  /**
   * Sets the default loan scheme.
   *
   * @param {string} id Unique identifier of the loan scheme, max 8 chars
   * @param {UTXO[]} [utxos = []] Specific UTXOs to spend
   * @param {string} utxos.txid Transaction Id
   * @param {number} utxos.vout Output number
   * @return {Promise<string>} Hex string of the transaction
   */
  async setDefaultLoanScheme (id: string, utxos: UTXO[] = []): Promise<string> {
    return await this.client.call('setdefaultloanscheme', [id, utxos], 'number')
  }

  /**
   * Set a collateral token transaction.
   *
   * @param {SetCollateralToken} collateralToken
   * @param {string} collateralToken.token Symbol or id of collateral token
   * @param {BigNumber} collateralToken.factor Collateralization factor
   * @param {string} collateralToken.fixedIntervalPriceId token/currency pair to use for price of token
   * @param {number} [collateralToken.activateAfterBlock] changes will be active after the block height
   * @param {UTXO[]} [utxos = []] Specific UTXOs to spend
   * @param {string} utxos.txid Transaction Id
   * @param {number} utxos.vout Output number
   * @return {Promise<string>} collateralTokenId, also the txn id for txn created to set collateral token
   */
  async setCollateralToken (collateralToken: SetCollateralToken, utxos: UTXO[] = []): Promise<string> {
    return await this.client.call('setcollateraltoken', [collateralToken, utxos], 'number')
  }

  /**
   * List collateral tokens.
   *
   * @return {Promise<CollateralTokenDetail[]>} Get all collateral tokens
   */
  async listCollateralTokens (): Promise<CollateralTokenDetail[]> {
    return await this.client.call('listcollateraltokens', [], 'bignumber')
  }

  /**
   * Get collateral token.
   *
   * @param {string} token symbol or id
   * @return {Promise<CollateralTokenDetail>} Collateral token result
   */
  async getCollateralToken (token: string): Promise<CollateralTokenDetail> {
    return await this.client.call('getcollateraltoken', [token], 'bignumber')
  }

  /**
   * Creates (and submits to local node and network) a token for a price feed set in collateral token.
   *
   * @param {SetLoanToken} loanToken
   * @param {string} loanToken.symbol Token's symbol (unique), no longer than 8
   * @param {string} [loanToken.name] Token's name, no longer than 128
   * @param {string} loanToken.fixedIntervalPriceId token/currency pair to use for price of token
   * @param {boolean} [loanToken.mintable = true] Token's 'Mintable' property
   * @param {BigNumber} [loanToken.interest = 0] Interest rate
   * @param {UTXO[]} [utxos = []] Specific UTXOs to spend
   * @param {string} utxos.txid Transaction Id
   * @param {number} utxos.vout Output number
   * @return {Promise<string>} LoanTokenId, also the txn id for txn created to set loan token
   */
  async setLoanToken (loanToken: SetLoanToken, utxos: UTXO[] = []): Promise<string> {
    const payload = {
      mintable: true,
      interest: 0,
      ...loanToken
    }
    return await this.client.call('setloantoken', [payload, utxos], 'number')
  }

  /**
   * Quick access to multiple API with consolidated total collateral and loan value.
   * @see {@link listCollateralTokens}
   * @see {@link listLoanTokens}
   * @see {@link listLoanSchemes}
   *
   * @returns {Promise<GetLoanInfoResult>}
   */
  async getLoanInfo (): Promise<GetLoanInfoResult> {
    return await this.client.call('getloaninfo', [], 'bignumber')
  }

  /**
   * Updates an existing loan token.
   *
   * @param {string} oldToken Previous tokens's symbol, id or creation tx (unique)
   * @param {UpdateLoanToken} newTokenDetails
   * @param {string} [newTokenDetails.symbol] New token's symbol (unique), no longer than 8
   * @param {string} [newTokenDetails.name] Token's name, no longer than 128
   * @param {string} [newTokenDetails.fixedIntervalPriceId] token/currency pair to use for price of token
   * @param {boolean} [newTokenDetails.mintable] Token's 'Mintable' property
   * @param {BigNumber} [newTokenDetails.interest] Interest rate
   * @param {UTXO[]} [utxos = []] Specific UTXOs to spend
   * @param {string} utxos.txid Transaction Id
   * @param {number} utxos.vout Output number
   * @return {Promise<string>} LoanTokenId, also the txn id for txn created to update loan token
   */
  async updateLoanToken (oldToken: string, newTokenDetails: UpdateLoanToken, utxos: UTXO[] = []): Promise<string> {
    return await this.client.call('updateloantoken', [oldToken, newTokenDetails, utxos], 'number')
  }

  /**
   * Get interest info
   *
   * @param {string} id Loan scheme id
   * @param {string} [token] Specified by loan token id, loan token name and loan toekn creation tx
   * @return {Promise<Interest[]>}
   */
  async getInterest (id: string, token?: string): Promise<Interest[]> {
    return await this.client.call('getinterest', [id, token], 'bignumber')
  }

  /**
   * Get loan token.
   *
   * @param {string} token Symbol or id of loan token
   * @return {Promise<LoanTokenResult>} Loan token details
   */
  async getLoanToken (token: string): Promise<LoanTokenResult> {
    return await this.client.call('getloantoken', [token], 'bignumber')
  }

  /**
   * List all created loan tokens.
   *
   * @return {Promise<LoanTokenResult[]>}
   */
  async listLoanTokens (): Promise<LoanTokenResult[]> {
    return await this.client.call('listloantokens', [], 'bignumber')
  }

  /**
   * Take loan
   *
   * @param {TakeLoanMetadata} metadata
   * @param {string} metadata.vaultId Vault id
   * @param {string | string[]} metadata.amounts In "amount@symbol" format
   * @param {string} [metadata.to] Address to receive tokens
   * @param {UTXO[]} [utxos = []] Specific UTXOs to spend
   * @param {string} utxos.txid Transaction Id
   * @param {number} utxos.vout Output number
   * @return {Promise<string>}
   */
  async takeLoan (metadata: TakeLoanMetadata, utxos: UTXO[] = []): Promise<string> {
    return await this.client.call('takeloan', [metadata, utxos], 'number')
  }

  /**
   * Return loan in a desired amount.
   *
   * @param {PaybackLoanMetadata | PaybackLoanMetadataV2} metadata
   * @param {string} metadata.vaultId Vault id
   * @param {string| string[]} metadata.amounts In "amount@symbol" format
   * @param {string} metadata.from Address from transfer tokens
   * @param {TokenPaybackAmount[]} metadata.loans
   * @param {string | string[]} metadata.loans[0].amounts In "amount@symbol" format to be spent
   * @param {string} metadata.loans[0].dToken Token to be paid
   * @param {UTXO[]} [utxos = []] Specific UTXOs to spend
   * @param {string} utxos.txid Transaction Id
   * @param {number} utxos.vout Output number
   * @return {Promise<string>} txid
   */
  async paybackLoan (metadata: PaybackLoanMetadata | PaybackLoanMetadataV2, utxos: UTXO[] = []): Promise<string> {
    return await this.client.call('paybackloan', [metadata, utxos], 'number')
  }

  /**
   * Return loan with vault's collaterals
   *
   * @param {string} [vaultId] Vault hex id
   * @return {Promise<string>} The hex-encoded hash of broadcasted transaction
   */
  async paybackWithCollateral (vaultId: string): Promise<string> {
    return await this.client.call('paybackwithcollateral', [vaultId], 'number')
  }

  // --- Deprecated vault methods---
  /**
   * Creates a vault transaction.
   *
   * @deprecated Vault methods are moving to dedicated vault category
   * @param {CreateVault} vault
   * @param {string} vault.ownerAddress Any valid address or "" to generate a new address
   * @param {number} [vault.loanSchemeId] Unique identifier of the loan scheme (8 chars max). If empty, the default loan scheme will be selected
   * @param {UTXO[]} [utxos = []] Specific UTXOs to spend
   * @param {string} utxos.txid Transaction Id
   * @param {number} utxos.vout Output number
   * @return {Promise<string>} Transaction id of the transaction
   */
  async createVault (vault: CreateVault, utxos: UTXO[] = []): Promise<string> {
    return await this.client.call('createvault', [vault.ownerAddress, vault.loanSchemeId, utxos], 'number')
  }

  /**
   * Create update vault transaction.
   *
   * @deprecated Vault methods are moving to dedicated vault category
   * @param {string} vaultId
   * @param {UpdateVault} vault
   * @param {string} [vault.ownerAddress] Any valid address
   * @param {string} [vault.loanSchemeId] Unique identifier of the loan scheme (8 chars max)
   * @param {UTXO[]} [utxos = []] Specific UTXOs to spend
   * @param {string} utxos.txid Transaction Id
   * @param {number} utxos.vout Output number
   * @return {Promise<string>} Transaction id of the transaction
   */
  async updateVault (vaultId: string, vault: UpdateVault, utxos: UTXO[] = []): Promise<string> {
    return await this.client.call('updatevault', [vaultId, vault, utxos], 'number')
  }

  /**
   * Returns information about vault.
   *
   * @deprecated Vault methods are moving to dedicated vault category
   * @param {string} vaultId vault hex id
   * @param {boolean} [verbose] request verbose info
   * @return {Promise<VaultActive | VaultLiquidation>}
   */
  async getVault (vaultId: string, verbose: boolean = false): Promise<VaultActive | VaultLiquidation> {
    return await this.client.call(
      'getvault',
      [vaultId, verbose],
      {
        collateralAmounts: 'bignumber',
        loanAmounts: 'bignumber',
        interestAmounts: 'bignumber',
        collateralValue: 'bignumber',
        loanValue: 'bignumber',
        interestValue: 'bignumber',
        informativeRatio: 'bignumber',
        nextCollateralRatio: 'bignumber',
        interestsPerBlock: 'bignumber'
      }
    )
  }

  /**
   * List all available vaults.
   *
   * @deprecated Vault methods are moving to dedicated vault category
   * @param {VaultPagination} [pagination]
   * @param {string} [pagination.start]
   * @param {boolean} [pagination.including_start]
   * @param {number} [pagination.limit=100]
   * @param {ListVaultOptions} [options]
   * @param {string} [options.ownerAddress] Address of the vault owner
   * @param {string} [options.loanSchemeId] Vault's loan scheme id
   * @param {VaultState} [options.state = VaultState.UNKNOWN] vault's state
   * @param {boolean} [options.verbose = false] true to return same information as getVault
   * @return {Promise<Vault | VaultActive | VaultLiquidation[]>} Array of objects including details of the vaults.
   * @deprecated
   */
  async listVaults (pagination: VaultPagination = {}, options: ListVaultOptions = {}): Promise<Array<Vault | VaultActive | VaultLiquidation>> {
    return await this.client.call(
      'listvaults',
      [options, pagination],
      {
        collateralValue: 'bignumber',
        loanValue: 'bignumber',
        interestValue: 'bignumber',
        informativeRatio: 'bignumber'
      }
    )
  }

  /**
   * Close vault
   *
   * @deprecated Vault methods are moving to dedicated vault category
   * @param {CloseVault} closeVault
   * @param {string} closeVault.vaultId Vault id
   * @param {string} closeVault.to Valid address to receive collateral tokens
   * @param {UTXO[]} [utxos = []] Specific UTXOs to spend
   * @param {string} utxos.txid Transaction Id
   * @param {number} utxos.vout Output number
   * @return {Promise<string>}
   */
  async closeVault (closeVault: CloseVault, utxos: UTXO[] = []): Promise<string> {
    return await this.client.call('closevault', [closeVault.vaultId, closeVault.to, utxos], 'number')
  }

  /**
   * Deposit to vault
   *
   * @deprecated Vault methods are moving to dedicated vault category
   * @param {DepositVault} depositVault
   * @param {string} depositVault.vaultId Vault id
   * @param {string} depositVault.from Collateral address
   * @param {string} depositVault.amount In "amount@symbol" format
   * @param {UTXO[]} [utxos = []] Specific UTXOs to spend
   * @param {string} utxos.txid Transaction Id
   * @param {number} utxos.vout Output number
   * @return {Promise<string>}
   */
  async depositToVault (depositVault: DepositVault, utxos: UTXO[] = []): Promise<string> {
    return await this.client.call('deposittovault', [depositVault.vaultId, depositVault.from, depositVault.amount, utxos], 'number')
  }

  /**
   * Withdraw from vault
   *
   * @deprecated Vault methods are moving to dedicated vault category
   * @param {WithdrawVault} withdrawVault
   * @param {string} withdrawVault.vaultId Vault id
   * @param {string} withdrawVault.to Collateral address
   * @param {string} withdrawVault.amount In "amount@symbol" format
   * @param {UTXO[]} [utxos = []] Specific UTXOs to spend
   * @param {string} utxos.txid Transaction Id
   * @param {number} utxos.vout Output number
   * @return {Promise<string>}
   */
  async withdrawFromVault (withdrawVault: WithdrawVault, utxos: UTXO[] = []): Promise<string> {
    return await this.client.call('withdrawfromvault', [withdrawVault.vaultId, withdrawVault.to, withdrawVault.amount, utxos], 'number')
  }

  /**
   * Bid to vault in auction
   *
   * @deprecated Vault methods are moving to dedicated vault category
   * @param {PlaceAuctionBid} placeAuctionBid
   * @param {string} placeAuctionBid.vaultId Vault Id
   * @param {index} placeAuctionBid.index Auction index
   * @param {from} placeAuctionBid.from Address to get token
   * @param {amount} placeAuctionBid.amount in "amount@symbol" format
   * @param {UTXO[]} [utxos = []] Specific UTXOs to spend
   * @param {string} utxos.txid Transaction Id
   * @param {number} utxos.vout Output number
   * @return {Promise<string>} The transaction id
   */
  async placeAuctionBid (placeAuctionBid: PlaceAuctionBid, utxos: UTXO[] = []): Promise<string> {
    return await this.client.call(
      'placeauctionbid',
      [placeAuctionBid.vaultId, placeAuctionBid.index, placeAuctionBid.from, placeAuctionBid.amount, utxos],
      'number'
    )
  }

  /**
   * List all available auctions.
   *
   * @deprecated Vault methods are moving to dedicated vault category
   * @param {AuctionPagination} pagination
   * @param {AuctionPaginationStart} [pagination.start]
   * @param {string} [pagination.start.vaultId]
   * @param {number} [pagination.start.height]
   * @param {boolean} [pagination.including_start]
   * @param {number} [pagination.limit=100]
   * @return {Promise<VaultLiquidation[]>}
   */
  async listAuctions (pagination: AuctionPagination = {}): Promise<VaultLiquidation[]> {
    const defaultPagination = {
      limit: 100
    }
    return await this.client.call('listauctions', [{ ...defaultPagination, ...pagination }], 'number')
  }

  /**
   * Returns information about auction history.
   *
   * @deprecated Vault methods are moving to dedicated vault category
   * @param {string} [owner] address or reserved word : mine / all (Default to mine)
   * @param {ListAuctionHistoryPagination} pagination
   * @param {number} [pagination.maxBlockHeight] Maximum block height
   * @param {string} [pagination.vaultId] Vault Id
   * @param {number} [pagination.index] Auction index
   * @param {number} [pagination.limit = 100]
   * @return {Promise<ListAuctionHistoryDetail>}
   */
  async listAuctionHistory (owner: string = 'mine', pagination?: ListAuctionHistoryPagination): Promise<ListAuctionHistoryDetail[]> {
    const defaultPagination = {
      limit: 100
    }
    return await this.client.call('listauctionhistory', [owner, { ...defaultPagination, ...pagination }], 'number')
  }
}

export interface CreateLoanScheme {
  minColRatio: number
  interestRate: BigNumber
  id: string
}

export interface UpdateLoanScheme {
  minColRatio: number
  interestRate: BigNumber
  id: string
  activateAfterBlock?: number
}

export interface DestroyLoanScheme {
  id: string
  activateAfterBlock?: number
}

export interface LoanSchemeResult {
  id: string
  mincolratio: BigNumber
  interestrate: BigNumber
  default: boolean
}

export interface SetCollateralToken {
  token: string
  factor: BigNumber
  fixedIntervalPriceId: string
  activateAfterBlock?: number
}

export interface GetLoanSchemeResult {
  id: string
  interestrate: BigNumber
  mincolratio: BigNumber
  default: boolean
}

export interface CollateralTokenDetail {
  token: string
  factor: BigNumber
  fixedIntervalPriceId: string
  tokenId: string
}

export interface SetLoanToken {
  symbol: string
  name?: string
  fixedIntervalPriceId: string
  mintable?: boolean
  interest?: BigNumber
}

export interface LoanTokenResult {
  token: token.TokenResult
  fixedIntervalPriceId: string
  interest: BigNumber
}

export interface LoanConfig {
  fixedIntervalBlocks: BigNumber
  maxPriceDeviationPct: BigNumber
  minOraclesPerPrice: BigNumber
  scheme: string
}

export interface LoanSummary {
  collateralTokens: BigNumber
  collateralValue: BigNumber
  loanTokens: BigNumber
  loanValue: BigNumber
  openAuctions: BigNumber
  openVaults: BigNumber
  schemes: BigNumber
}

export interface GetLoanInfoResult {
  currentPriceBlock: BigNumber
  nextPriceBlock: BigNumber
  defaults: LoanConfig
  totals: LoanSummary
}

export interface UpdateLoanToken {
  symbol?: string
  name?: string
  fixedIntervalPriceId?: string
  mintable?: boolean
  interest?: BigNumber
}

export interface Interest {
  token: string
  realizedInterestPerBlock: BigNumber
  totalInterest: BigNumber
  interestPerBlock: BigNumber
}

export interface UTXO {
  txid: string
  vout: number
}

export interface TakeLoanMetadata {
  vaultId: string
  amounts: string | string[] // amount@symbol
  to?: string
}

export interface PaybackLoanMetadata {
  vaultId: string
  amounts: string | string[] // amount@symbol
  from: string
}

export interface TokenPaybackAmount {
  dToken: string
  amounts: string | string[] // amount@symbol
}

export interface PaybackLoanMetadataV2 {
  vaultId: string
  from: string
  loans: TokenPaybackAmount[]
}