How to use 1delta's margin aggregator programmatically

1delta's smart contracts can be used via our Typescript SDK (which is also the one used for our UI).

It is using out asset-registry package here.

This package contains all lender data that is needed for on-chain actions (e.g. Aave lending tokens, Venus comptrollers etc.). The SDK automatically identifies a lender via the provided enum.

Packages

pnpm add @1delta/calldata-sdk @1delta/asset-registry
// enums for operations
import {QuickActionType, MarginTradeType} from "@1delta/calldata-sdk"
// for direct lending actions
import {ComposerDirectLending} from "@1delta/calldata-sdk"
// margin operations
import {ComposerMargin} from "@1delta/calldata-sdk"
// enums
import {Lender} from "@1delta/asset-registry"

Example usage for depositing to Aave V3

Deposits assets to Aave. The caller needs to ensure that the contract has enough permissions (e.g. token.approve(...))

// --- Configuration for chain ---
const chainId = "10"
const composer = COMPOSER_PROXIES[chainId]

// --- Asset and amount ---
// Example: deposit 1000 USDC (1e9 = 1000 * 1e6 in smallest units)
const input = 1_000_000_000n // 1e9
const depositAsset = {
  symbol: "USDC",
  name: "USDC",
  address: "0x0b2c639c533813f4aa9d7837caf62653d097ff85",
  chainId
}

// --- Caller account ---
const account = "0x..."

// --- Lender and action type ---
const lender = Lender.AAVE_V3
const action = QuickActionType.Deposit

// --- Operation parameters ---
const operation = {
  params: {
    lender,
    amount: { currency: depositAsset, amount: input }
  },
  receiver: account, // Caller deposits on their own behalf
  isAll: false,      // Only used for withdraw & repay operations
  inIsNative: false, // If true, use native asset (ETH) to deposit — operation will wrap ETH
  outIsNative: false,// If true, unwraps output (e.g. withdraw WETH and unwrap to ETH)
  composerAddress: composer,
  permitData: undefined,   // No permit used
  morphoParams: undefined, // No Morpho parameters
  useOverride: undefined   // No custom Aave fork override
}

// --- Generate calldata and value for transaction ---
const { calldata, value } = ComposerDirectLending.composeDirectMoneyMarketAction(operation)

Example usage for opening a position on Aave V3

Open a position on Aave. The caller needs to ensure that the contract has enough permissions (e.g. via debtToken.approveDelegation(...))

// Example: Opening a short position on 1 WETH using USDC as collateral

const chainId = "10"
const composer = COMPOSER_PROXIES[chainId]

// The caller's account address
const account = "0x..."

// Operation type
const marginTradeType = "Open"

// Intended input amount (in wei)
const input = 1_000_000_000_000_000_000n // 1e18

// Assets
const assetIn = {
  symbol: "WETH",
  name: "WETH",
  address: "0x4200000000000000000000000000000000000006",
  chainId
}
const assetOut = {
  symbol: "USDC",
  name: "USDC",
  address: "0x0b2c639c533813f4aa9d7837caf62653d097ff85",
  chainId
}

// Lender to use (refer to the `Lender` enum in asset-registry)
const lender = Lender.AAVE_V3

// --- Step 1: Fetch flash liquidity ---
// Example return value:
//
// [
//   {
//     "id": 0,
//     "name": "AAVE_V3",
//     "type": 2,
//     "source": "0x794a61358D6845594F94dc1DB02A252b5b4814aD",
//     "fee": "5",
//     "availableRaw": "7742114549858607894570",
//     "available": 7742.11454985861
//   },
//   ...
// ]

const assetLiquidities = await (
  await fetch(`https://margin-data.1delta.io/flashloan-asset/10/0x4200000000000000000000000000000000000006`)
).json()

// Pick the first source (ideally choose the lowest-fee source)
const flashLoanSource = assetLiquidities[0]

// Flash loan fee is used to adjust the quote input
const flashFee = BigInt(flashLoanSource.fee)


// --- Step 2: Fetch trade ---
// With a 5 bps flash fee, we can calculate the adjusted input to borrow exactly 1 WETH:
const amendedInput = (input * 10_000n) / (10_000n + flashFee)

// Query the swap provider API
// Important: Set the receiver to the composer contract
const apiBody = { ..., amountIn: amendedInput, receiver: composer }
const apiReturn = await (
  await fetch(`https://www.quote.odos....`)
).json()

// Get calldata from the API (varies by provider)
const { calldata, target } = await (
  await fetch(`https://www.assemble.odos....`)
).json()


// --- Step 3: Prepare trade object for SDK ---

const trade: GenericTrade = {
  tradeType: 0, // exact in
  inputAmount: { currency: assetIn, amount: amendedInput },
  outputAmount: { currency: assetOut, amount: apiReturn.output }, // Output amount is unused in calldata
  target, // Call target
  approvalTarget: target, // Usually same as call target, may differ for some aggregators
  // Set to `true` if `apiBody` does not allow specifying a receiver
  sweepToReceiver: false,
}

const externalCall = {
  target,
  calldata,
  value: "0", // Default (only used for native asset as input)
  useSelfbalance: false,
  callForwarder: FORWARDER
}

const marginData = {
  marginTradeType,
  // STABLE is disabled for most Aave forks
  irModeIn: AaveInterestMode.VARIABLE,
  // Unused
  irModeOut: AaveInterestMode.NONE,
  lender,
  morphoParams: undefined, // No Morpho execution
  permitData: undefined // No permits in this example
}

// This returns a bytes string for the 1delta composer
const composerOperation = ComposerMargin.createMarginFlashLoan({
  trade,
  externalCall,
  marginData,
  maxIn: false, // Default (only for non-open operations)
  maxOut: false, // Default (only for non-open operations)
  composerOverride: composer, // Composer address
  flashInfoOverride: flashLoanSource // Flash loan source info
})


// Note: Any composer operation can be prepended, e.g.:
//
// This is the calldata for the composer.
// For example, `ComposerDirectLending.composeDirectMoneyMarketAction(...)`
// could be used to generate a deposit calldata set, which can then be prepended:
//
// const depositAndOpen = encodePacked(
//   ["bytes", "bytes"],
//   [depositCalldata, composerOperation]
// )

const contractCall = encodeFunctionData({
  abi: composerAbi,
  functionName: "deltaCompose",
  args: [composerOperation]
})
© 1delta https://1delta.io/

Found an error in the docs? The source code can be found here. Please feel free to edit and contribute a merge request
Modified at: 2025-08-10 20:39:21

results matching ""

    No results matching ""