Skip to content

Commit

Permalink
docs: create loan, deposit, borrowing, linking address and liquidatio…
Browse files Browse the repository at this point in the history
…n examples (#209)
  • Loading branch information
moshenskyDV authored Jan 7, 2025
1 parent 35673ee commit 4d125ba
Show file tree
Hide file tree
Showing 10 changed files with 474 additions and 17 deletions.
5 changes: 5 additions & 0 deletions .changeset/wild-olives-smell.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@folks-finance/xchain-sdk": patch
---

Added more examples
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,8 @@ const createAccount = async (sourceFolksChainId: FolksChainId) => {

Remember that any changes made to `FolksCore` (like changing the network or signer) will affect all subsequent module calls. This design allows for flexible and context-aware interactions with the Folks Finance protocol across different chains and environments.

More examples provided in [`./examples`](./examples) folder.

### React Usage

When using the SDK with React, there are a few additional considerations to ensure proper initialization and synchronization. Here's how to set up and use the SDK in a React environment:
Expand Down
98 changes: 98 additions & 0 deletions examples/borrow.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
import * as dn from "dnum";
import { createWalletClient, http, parseUnits } from "viem";
import { mnemonicToAccount } from "viem/accounts";

import {
NetworkType,
FolksCore,
FolksLoan,
FolksPool,
FOLKS_CHAIN_ID,
getSupportedMessageAdapters,
Action,
MessageAdapterParamsType,
CHAIN_VIEM,
TESTNET_FOLKS_TOKEN_ID,
} from "../src/index.js";

import type { FolksCoreConfig, MessageAdapters, AccountId, LoanId } from "../src/index.js";

async function main() {
const network = NetworkType.TESTNET;
const chain = FOLKS_CHAIN_ID.BSC_TESTNET;
const tokenId = TESTNET_FOLKS_TOKEN_ID.BNB;

const folksConfig: FolksCoreConfig = { network, provider: { evm: {} } };

FolksCore.init(folksConfig);
FolksCore.setNetwork(network);

const MNEMONIC = "your mnemonic here";
const account = mnemonicToAccount(MNEMONIC);

const signer = createWalletClient({
account,
chain: CHAIN_VIEM[chain],
transport: http(),
});

const { adapterIds, returnAdapterIds } = getSupportedMessageAdapters({
action: Action.Borrow,
messageAdapterParamType: MessageAdapterParamsType.ReceiveToken,
network,
sourceFolksChainId: chain,
destFolksChainId: chain,
folksTokenId: tokenId,
});

const adapters: MessageAdapters = {
adapterId: adapterIds[0],
returnAdapterId: returnAdapterIds[0],
};

FolksCore.setFolksSigner({ signer, folksChainId: chain });

const accountId = "0x7d6...b66" as AccountId; // Your xChainApp account id
const loanId = "0x166...c12" as LoanId; // Your loan id
const amountToBorrow = parseUnits("0.0005", 18); // 0.0005 BNB (BNB has 18 decimals)
const isStableRate = false;

let maxStableRate;
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
if (isStableRate) {
const poolInfo = await FolksPool.read.poolInfo(tokenId);
const interestRate = poolInfo.stableBorrowData.interestRate[0];
const [rateWithSlippage] = dn.mul(interestRate, 1.05); // 5% max deviation from current rate
maxStableRate = rateWithSlippage;
} else {
maxStableRate = BigInt(0);
}

const prepareBorrowCall = await FolksLoan.prepare.borrow(
accountId,
loanId,
tokenId,
amountToBorrow,
maxStableRate,
chain,
adapters,
);
const createBorrowCallRes = await FolksLoan.write.borrow(
accountId,
loanId,
tokenId,
amountToBorrow,
maxStableRate,
chain,
prepareBorrowCall,
);
console.log(`Transaction ID: ${createBorrowCallRes}`);
}

main()
.then(() => {
console.log("done");
})
.catch((error: unknown) => {
console.error(error);
});
76 changes: 76 additions & 0 deletions examples/create-loan.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
import { createWalletClient, http } from "viem";
import { mnemonicToAccount } from "viem/accounts";

import { convertStringToLoanName } from "../src/common/utils/lending.js";
import {
NetworkType,
FolksCore,
getRandomBytes,
FolksLoan,
FOLKS_CHAIN_ID,
BYTES4_LENGTH,
getSupportedMessageAdapters,
Action,
MessageAdapterParamsType,
LoanTypeId,
CHAIN_VIEM,
} from "../src/index.js";

import type { FolksCoreConfig, MessageAdapters, Nonce, AccountId } from "../src/index.js";

async function main() {
const network = NetworkType.TESTNET;
const chain = FOLKS_CHAIN_ID.AVALANCHE_FUJI;

const folksConfig: FolksCoreConfig = { network, provider: { evm: {} } };

FolksCore.init(folksConfig);
FolksCore.setNetwork(network);

const nonce: Nonce = getRandomBytes(BYTES4_LENGTH) as Nonce;

const MNEMONIC = "your mnemonic here";
const account = mnemonicToAccount(MNEMONIC);

const signer = createWalletClient({
account,
chain: CHAIN_VIEM[chain],
transport: http(),
});

const { adapterIds, returnAdapterIds } = getSupportedMessageAdapters({
action: Action.CreateLoan,
messageAdapterParamType: MessageAdapterParamsType.Data,
network,
sourceFolksChainId: chain,
});

const adapters: MessageAdapters = {
adapterId: adapterIds[0],
returnAdapterId: returnAdapterIds[0],
};

FolksCore.setFolksSigner({ signer, folksChainId: chain });

const accountId = "0x7d6...b66" as AccountId; // Your xChainApp account id
const loanType = LoanTypeId.GENERAL; // LoanTypeId.DEPOSIT for deposits
const loanName = convertStringToLoanName("Test Loan");

const prepareCreateLoanCall = await FolksLoan.prepare.createLoan(accountId, nonce, loanType, loanName, adapters);
const createLoanCallRes = await FolksLoan.write.createLoan(
accountId,
nonce,
loanType,
loanName,
prepareCreateLoanCall,
);
console.log(`Transaction ID: ${createLoanCallRes}`);
}

main()
.then(() => {
console.log("done");
})
.catch((error: unknown) => {
console.error(error);
});
82 changes: 82 additions & 0 deletions examples/deposit-or-collateralise.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
import { createWalletClient, http, parseUnits } from "viem";
import { mnemonicToAccount } from "viem/accounts";

import {
NetworkType,
FolksCore,
FolksLoan,
FOLKS_CHAIN_ID,
getSupportedMessageAdapters,
Action,
MessageAdapterParamsType,
LoanTypeId,
CHAIN_VIEM,
TESTNET_FOLKS_TOKEN_ID,
} from "../src/index.js";

import type { FolksCoreConfig, MessageAdapters, AccountId, LoanId } from "../src/index.js";

async function main() {
const network = NetworkType.TESTNET;
const chain = FOLKS_CHAIN_ID.AVALANCHE_FUJI;
const tokenId = TESTNET_FOLKS_TOKEN_ID.AVAX;

const folksConfig: FolksCoreConfig = { network, provider: { evm: {} } };

FolksCore.init(folksConfig);
FolksCore.setNetwork(network);

const MNEMONIC = "your mnemonic here";
const account = mnemonicToAccount(MNEMONIC);

const signer = createWalletClient({
account,
chain: CHAIN_VIEM[chain],
transport: http(),
});

const { adapterIds, returnAdapterIds } = getSupportedMessageAdapters({
action: Action.Deposit,
messageAdapterParamType: MessageAdapterParamsType.SendToken,
network,
sourceFolksChainId: chain,
folksTokenId: tokenId,
});

const adapters: MessageAdapters = {
adapterId: adapterIds[0],
returnAdapterId: returnAdapterIds[0],
};

FolksCore.setFolksSigner({ signer, folksChainId: chain });

const accountId = "0x7d6...b66" as AccountId; // Your xChainApp account id
const loanId = "0x166...c12" as LoanId; // Your loan id
const loanType = LoanTypeId.GENERAL; // LoanTypeId.DEPOSIT for deposits
const amountToDeposit = parseUnits("0.1", 18); // 0.1 AVAX (AVAX has 18 decimals)

const prepareDepositCall = await FolksLoan.prepare.deposit(
accountId,
loanId,
loanType,
tokenId,
amountToDeposit,
adapters,
);
const createDepositCallRes = await FolksLoan.write.deposit(
accountId,
loanId,
amountToDeposit,
true,
prepareDepositCall,
);
console.log(`Transaction ID: ${createDepositCallRes}`);
}

main()
.then(() => {
console.log("done");
})
.catch((error: unknown) => {
console.error(error);
});
102 changes: 102 additions & 0 deletions examples/link-address.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
import { createWalletClient, http } from "viem";
import { mnemonicToAccount } from "viem/accounts";

import {
Action,
CHAIN_VIEM,
ChainType,
convertToGenericAddress,
FOLKS_CHAIN_ID,
FolksAccount,
FolksCore,
getSupportedMessageAdapters,
MessageAdapterParamsType,
NetworkType,
} from "../src/index.js";

import type { AccountId, EvmAddress, FolksCoreConfig, MessageAdapters } from "../src/index.js";

async function main() {
const network = NetworkType.TESTNET;
const chain = FOLKS_CHAIN_ID.AVALANCHE_FUJI;
const chainToLink = FOLKS_CHAIN_ID.BSC_TESTNET;

const folksConfig: FolksCoreConfig = { network, provider: { evm: {} } };

FolksCore.init(folksConfig);
FolksCore.setNetwork(network);

// invite
const MNEMONIC = "your mnemonic here";
const account = mnemonicToAccount(MNEMONIC);

const signer = createWalletClient({
account,
chain: CHAIN_VIEM[chain],
transport: http(),
});

const chainAdapters = getSupportedMessageAdapters({
action: Action.InviteAddress,
messageAdapterParamType: MessageAdapterParamsType.Data,
network,
sourceFolksChainId: chain,
});

const adapters: MessageAdapters = {
adapterId: chainAdapters.adapterIds[0],
returnAdapterId: chainAdapters.returnAdapterIds[0],
};

FolksCore.setFolksSigner({
signer,
folksChainId: chain,
});

const accountId = "0x7d6...b66" as AccountId; // Your xChainApp account id
const addressToLink = convertToGenericAddress("0x322...b78" as EvmAddress, ChainType.EVM);

const prepareInviteCall = await FolksAccount.prepare.inviteAddress(accountId, chainToLink, addressToLink, adapters);
const inviteRes = await FolksAccount.write.inviteAddress(accountId, chainToLink, addressToLink, prepareInviteCall);
console.log(`Invitation transaction ID: ${inviteRes}`);

// accept invitation
const MNEMONIC_TO_LINK = "your mnemonic here";
const accountToLink = mnemonicToAccount(MNEMONIC_TO_LINK);

const signerToLink = createWalletClient({
account: accountToLink,
chain: CHAIN_VIEM[chainToLink],
transport: http(),
});

const chainAdaptersToLink = getSupportedMessageAdapters({
action: Action.AcceptInviteAddress,
messageAdapterParamType: MessageAdapterParamsType.Data,
network,
sourceFolksChainId: chainToLink,
});

const adaptersToLink: MessageAdapters = {
adapterId: chainAdaptersToLink.adapterIds[0],
returnAdapterId: chainAdaptersToLink.returnAdapterIds[0],
};

FolksCore.setFolksSigner({
signer: signerToLink,
folksChainId: chainToLink,
});

const prepareAcceptInviteCall = await FolksAccount.prepare.acceptInvite(accountId, adaptersToLink);

const acceptInviteRes = await FolksAccount.write.acceptInvite(accountId, prepareAcceptInviteCall);
console.log(`Accept transaction ID: ${acceptInviteRes}`);
}

main()
.then(() => {
console.log("done");
})
.catch((error: unknown) => {
console.error(error);
});
Loading

0 comments on commit 4d125ba

Please sign in to comment.