Lending Operations
Updated
This recipe demonstrates a complete lending workflow: depositing collateral, borrowing an asset, and repaying a loan. Each step uses the appropriate primitive constant and type guard for safe extraction.
Full Example
import {
Chaos,
WALLET_MODEL,
PRIMITIVE_LENDING_DEPOSIT,
PRIMITIVE_LENDING_BORROW,
PRIMITIVE_LENDING_REPAY,
findTransactionsByPrimitive,
extractPrimitives,
isLendingDepositPrimitive,
isLendingBorrowPrimitive,
isLendingRepayPrimitive,
hasRisks,
getHighestRiskLevel,
getAllWarnings,
} from '@chaoslabs/ai-sdk';
const chaos = new Chaos({ apiKey: process.env.CHAOS_API_KEY! });
const walletMeta = {
user_id: 'user-123',
session_id: 'session-lending',
wallets: [{ address: '0xYourWallet', chain: 'ethereum' }],
};
// ─── Step 1: Deposit Collateral ─────────────────────────────────────────────────
const depositResponse = await chaos.chat.responses.create({
model: WALLET_MODEL,
input: [
{ type: 'message', role: 'user', content: 'Deposit 10 ETH as collateral on Aave' },
],
metadata: walletMeta,
});
// Find action blocks containing the deposit primitive
const depositBlocks = findTransactionsByPrimitive(depositResponse, PRIMITIVE_LENDING_DEPOSIT);
console.log(`Found ${depositBlocks.length} deposit action block(s)`);
// Extract and narrow the deposit primitive
const depositPrimitives = extractPrimitives(depositResponse).filter(isLendingDepositPrimitive);
for (const dep of depositPrimitives) {
console.log('Deposit:', {
type: dep.type, // 'lending_deposit'
params: dep.params, // LendingDepositParams (token, amount, protocol, etc.)
display: dep.display, // PrimitiveDisplay (action_verb, summary, etc.)
});
}
// ─── Step 2: Borrow ─────────────────────────────────────────────────────────────
const borrowResponse = await chaos.chat.responses.create({
model: WALLET_MODEL,
input: [
{ type: 'message', role: 'user', content: 'Borrow 5000 USDC against my collateral on Aave' },
],
metadata: walletMeta,
});
const borrowBlocks = findTransactionsByPrimitive(borrowResponse, PRIMITIVE_LENDING_BORROW);
const borrowPrimitives = extractPrimitives(borrowResponse).filter(isLendingBorrowPrimitive);
for (const borrow of borrowPrimitives) {
console.log('Borrow:', borrow.params);
}
// Check risk levels on the borrow
if (hasRisks(borrowResponse)) {
console.warn('Borrow risk:', getHighestRiskLevel(borrowResponse));
console.warn('Warnings:', getAllWarnings(borrowResponse).map((w) => w.message));
}
// ─── Step 3: Repay ──────────────────────────────────────────────────────────────
const repayResponse = await chaos.chat.responses.create({
model: WALLET_MODEL,
input: [
{ type: 'message', role: 'user', content: 'Repay 2500 USDC on Aave' },
],
metadata: walletMeta,
});
const repayBlocks = findTransactionsByPrimitive(repayResponse, PRIMITIVE_LENDING_REPAY);
const repayPrimitives = extractPrimitives(repayResponse).filter(isLendingRepayPrimitive);
for (const repay of repayPrimitives) {
console.log('Repay:', repay.params);
}
// ─── Summary ────────────────────────────────────────────────────────────────────
console.log('Lending workflow complete:', {
deposits: depositBlocks.length,
borrows: borrowBlocks.length,
repays: repayBlocks.length,
});Copy code
Open in Cursor
Open in VS Code
Open in v0
Open in Claude
Open in ChatGPT
Finding Transactions by Primitive
findTransactionsByPrimitive filters action blocks to only those containing a given primitive type. This is useful when a response includes multiple action blocks (e.g., an approve + deposit).
import {
findTransactionsByPrimitive,
PRIMITIVE_LENDING_DEPOSIT,
} from '@chaoslabs/ai-sdk';
// Returns ActionBlock[] where at least one primitive has type 'lending_deposit'
const blocks = findTransactionsByPrimitive(response, PRIMITIVE_LENDING_DEPOSIT);
for (const block of blocks) {
console.log('Notes:', block.notes);
console.log('Primitives:', block.primitives?.map((p) => p.type));
console.log('Transactions:', block.transactions?.length);
}Copy code
Open in Cursor
Open in VS Code
Open in v0
Open in Claude
Open in ChatGPT
Type-Safe Primitive Extraction
Each primitive type guard narrows the Primitive union to a specific type with typed params.
import {
extractPrimitives,
isLendingDepositPrimitive,
isLendingBorrowPrimitive,
isLendingRepayPrimitive,
isLendingWithdrawPrimitive,
isLendingClaimRewardsPrimitive,
} from '@chaoslabs/ai-sdk';
const primitives = extractPrimitives(response);
for (const p of primitives) {
if (isLendingDepositPrimitive(p)) {
// p is LendingDepositPrimitive, p.params is LendingDepositParams
console.log('Deposit:', p.params);
} else if (isLendingBorrowPrimitive(p)) {
// p is LendingBorrowPrimitive, p.params is LendingBorrowParams
console.log('Borrow:', p.params);
} else if (isLendingRepayPrimitive(p)) {
// p is LendingRepayPrimitive, p.params is LendingRepayParams
console.log('Repay:', p.params);
} else if (isLendingWithdrawPrimitive(p)) {
// p is LendingWithdrawPrimitive, p.params is LendingWithdrawParams
console.log('Withdraw:', p.params);
} else if (isLendingClaimRewardsPrimitive(p)) {
// p is LendingClaimRewardsPrimitive, p.params is LendingClaimRewardsParams
console.log('Claim rewards:', p.params);
}
}Copy code
Open in Cursor
Open in VS Code
Open in v0
Open in Claude
Open in ChatGPT
Was this helpful?