SDK Guide

The TownSquare SDK (@townsq/mm-sdk) provides developers with tools to interact seamlessly with the protocol — creating accounts, managing loans, depositing, borrowing, repaying, and withdrawing assets — without directly calling smart contracts.

Installation

npm install @townsq/mm-sdk

or

yarn add @townsq/mm-sdk

Initialization

Before using the SDK, you need to configure the core instance and signer.

import { TSCore, NetworkType, TS_CHAIN_ID, CHAIN_VIEM } from "@townsq/mm-sdk";
import { createWalletClient, http } from "viem";
import { privateKeyToAccount } from "viem/accounts";

// Select network and chain
const network = NetworkType.TESTNET;
const chain = TS_CHAIN_ID.MONAD_TESTNET;

// Initialize SDK configuration
const tsConfig: TSCoreConfig = { network, provider: { evm: {} } };
TSCore.init(tsConfig);
TSCore.setNetwork(network);

// Create signer (example with private key)
const signer = createWalletClient({
  chain: CHAIN_VIEM[chain],
  transport: http(),
  account: privateKeyToAccount("0x..."), // Replace with private key
});

// Set signer
TSCore.setTSsSigner({ signer, tsChainId: chain });

Reading Loan Information

The SDK provides utilities to fetch and compute detailed information about a loan, including collateral value, debt value, and health factors. This is useful for dashboards, liquidation bots, or analytics.

import {
  TSPool,
  TSOracle,
  TSLoan,
  TESTNET_TS_TOKEN_ID,
  TESTNET_LOAN_TYPE_ID,
} from "@townsq/mm-sdk";

const poolsInfo: Partial<Record<TSTokenId, PoolInfo>> = {};

// 1. Load pool information for all tokens
await Promise.all(
  Object.values(TESTNET_TS_TOKEN_ID).map(async (tsTokenId) => {
    const poolInfo = await TSPool.read.poolInfo(tsTokenId);
    poolsInfo[tsTokenId] = poolInfo;
  })
);

// 2. Get loanId (example from event logs)
const loanId = '0xLoanId' as LoanId;

// 3. Build a mapping of loan type IDs
const loanTypeMap = Object.entries(TESTNET_LOAN_TYPE_ID).reduce(
  (acc, [key, value]) => {
    acc[key as any] = value;
    return acc;
  },
  {} as Record<number, LoanTypeId>
);

try {
  // 4. Read current oracle prices
  const oraclePrices = await TSOracle.read.oraclePrices();

  // 5. Fetch user loan data
  const userLoans = await TSLoan.read.userLoans([loanId]);
  const loan = userLoans?.get(loanId);

  if (!loan) return;

  // 6. Match the loan type
  const loanType = Object.values(loanTypeMap).find(
    (type) => type === loan.loanTypeId
  );

  if (!loanType || loanType === TESTNET_LOAN_TYPE_ID.DEPOSIT) return;

  // 7. Fetch loan type info
  const loanTypeInfo = {
    [loanType]: await TSLoan.read.loanTypeInfo(loanType),
  };

  // 8. Compute full loan info (collateral, debt, ratios)
  const loanInfo = TSLoan.util.userLoansInfo(
    userLoans,
    poolsInfo,
    loanTypeInfo,
    oraclePrices
  )[loanId];

  if (!loanInfo) return;

  console.log("Loan Info:", loanInfo);
} catch (e) {
  console.error("Failed to compute loan info", e);
}

Creating Account

import { TSAccount } from "@townsq/mm-sdk";

const nonce = "0x"; // bytes4 nonce

// Prepare transaction
const createAccount = await TSAccount.prepare.createAccount(nonce, {
  adapterId: 3,
  returnAdapterId: 3,
});

// Send transaction
const txnReceipt = await TSAccount.write.createAccount(nonce, createAccount);

console.log(txnReceipt);

The account will be created on the chain defined during initialization.

Creating a Loan

TownSquare supports three loan types:

  • General Loan → accepts all supported tokens.

  • Stable Efficiency Loan → restricted to stablecoin-related assets.

  • MON Efficiency Loan → supports MON-related assets only.

import { TSLoan } from "@townsq/mm-sdk";
import { ethers } from "ethers";

const loanName = "My loan";
const encodedLoanName = ethers.encodeBytes32String(loanName);
const nonce = "0x"; // bytes4

// Prepare transaction
const prepareCreateLoan = await TSLoan.prepare.createLoan(
  accountId,
  nonce,
  TESTNET_LOAN_TYPE_ID.GENERAL,
  encodedLoanName,
  { adapterId: 3, returnAdapterId: 3 }
);

// Send transaction
const txnReceipt = await TSLoan.write.createLoan(
  accountId,
  nonce,
  TESTNET_LOAN_TYPE_ID.GENERAL,
  encodedLoanName,
  prepareCreateLoan
);

Deposit

Deposit tokens into a loan.

const poolId = TESTNET_TS_TOKEN_ID.MON;
const loanId = "0xYourLoanId";

// Prepare deposit
const deposit = await TSLoan.prepare.deposit(
  accountId,
  loanId,
  TESTNET_LOAN_TYPE_ID.GENERAL,
  poolId,
  parseUnits("0.1", 18),
  { adapterId: 3, returnAdapterId: 3 }
);

// Send transaction
const txnReceipt = await TSLoan.write.deposit(
  accountId,
  loanId,
  parseUnits("0.1", 18),
  false,
  deposit
);

console.log(txnReceipt);

Borrow

  const borrow = await TSLoan.prepare.borrow(
    accountId,
    loanId,
    TESTNET_TS_TOKEN_ID.aprMON,
    parseUnits('0.05', 18),
    0n,
    TS_CHAIN_ID.MONAD_TESTNET,
    {
      adapterId: 3,
      returnAdapterId: 3,
    } 
  );


  const txnReceipt = await TSLoan.write.borrow(
    accountId,
    loanId,
    TESTNET_TS_TOKEN_ID.aprMON,
    parseUnits('0.05', 18),
    0n,
    TS_CHAIN_ID.MONAD_TESTNET,
    borrow
  );

Repay

const repay = await TSLoan.prepare.repay(
  accountId,
  loanId,
  TESTNET_LOAN_TYPE_ID.GENERAL,
  TESTNET_TS_TOKEN_ID.aprMON,
  parseUnits("0.06", 18), // borrow amount
  parseUnits("0.1", 18),  // repayment amount
  { adapterId: 3, returnAdapterId: 3 }
);

const txnReceipt = await TSLoan.write.repay(
  accountId,
  loanId,
  parseUnits("0.06", 18),
  parseUnits("0.1", 18),
  true,
  repay
);


Withdraw

const withdraw = await TSLoan.prepare.withdraw(
  accountId,
  loanId,
  TESTNET_TS_TOKEN_ID.MON,
  parseUnits("0.05", 18),
  true,
  TESTNET_EVM_TS_CHAIN_ID.MONAD_TESTNET,
  { adapterId: 3, returnAdapterId: 3 }
);

const txnReceipt = await TSLoan.write.withdraw(
  accountId,
  loanId,
  TESTNET_TS_TOKEN_ID.MON,
  parseUnits("0.05", 18),
  true,
  TESTNET_EVM_TS_CHAIN_ID.MONAD_TESTNET,
  withdraw
);

Last updated