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-sdkor
yarn add @townsq/mm-sdkInitialization
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