UNPKG

@indigo-labs/indigo-sdk

Version:

Indigo SDK for interacting with Indigo endpoints via lucid-evolution

155 lines (138 loc) 3.87 kB
import { fromHex, fromText, LucidEvolution, OutRef, slotToUnixTime, toUnit, TxBuilder, UTxO, validatorToAddress, } from '@lucid-evolution/lucid'; import { InterestOracleParams } from './types'; import { oneShotMintTx } from '../one-shot/transactions'; import { mkInterestOracleValidator } from './scripts'; import { findInterestOracle } from '../../../tests/queries/interest-oracle-queries'; import { ONE_SECOND } from '../../utils/time-helpers'; import { calculateUnitaryInterestSinceOracleLastUpdated } from '../interest-oracle/helpers'; import { getInlineDatumOrThrow } from '../../utils/lucid-utils'; import { AssetClass } from '@3rd-eye-labs/cardano-offchain-common'; import { parseInterestOracleDatum, serialiseFeedInterestOracleRedeemer, serialiseInterestOracleDatum, } from './types-new'; export async function startInterestOracle( initialUnitaryInterest: bigint, initialInterestRate: bigint, initialLastInterestUpdate: bigint, oracleParams: InterestOracleParams, lucid: LucidEvolution, interestTokenName?: string, withScriptRef: boolean = false, refOutRef?: OutRef, ): Promise<[TxBuilder, AssetClass]> { const network = lucid.config().network!; const tokenName = interestTokenName ?? 'INTEREST_ORACLE'; if (!refOutRef) { refOutRef = (await lucid.wallet().getUtxos())[0]; } const [tx, policyId] = await oneShotMintTx(lucid, { referenceOutRef: { txHash: refOutRef.txHash, outputIdx: BigInt(refOutRef.outputIndex), }, mintAmounts: [ { tokenName: fromText(tokenName), amount: 1n, }, ], }); const validator = mkInterestOracleValidator(oracleParams); tx.pay.ToContract( validatorToAddress(network, validator), { kind: 'inline', value: serialiseInterestOracleDatum({ unitaryInterest: initialUnitaryInterest, interestRate: { getOnChainInt: initialInterestRate, }, lastUpdated: initialLastInterestUpdate, }), }, { lovelace: 2_500_000n, [toUnit(policyId, fromText(tokenName))]: 1n, }, ); if (withScriptRef) { tx.pay.ToAddressWithData( validatorToAddress(network, validator), undefined, undefined, validator, ); } return [ tx, { currencySymbol: fromHex(policyId), tokenName: fromHex(fromText(tokenName)), }, ]; } export async function feedInterestOracle( params: InterestOracleParams, newInterestRate: bigint, lucid: LucidEvolution, currentSlot: number, assetClass?: AssetClass, utxo?: UTxO, scriptRef?: UTxO, ): Promise<TxBuilder> { if (!assetClass && !utxo) throw new Error('Either interest oracle nft or utxo must be provided'); if (assetClass && !utxo) { utxo = await findInterestOracle(lucid, assetClass); } const network = lucid.config().network!; const now = BigInt(slotToUnixTime(network, currentSlot)); const tx = lucid.newTx(); const datum = parseInterestOracleDatum(getInlineDatumOrThrow(utxo!)); if (scriptRef) { tx.readFrom([scriptRef]); } else { tx.attach.Script(mkInterestOracleValidator(params)); } tx.collectFrom( [utxo!], serialiseFeedInterestOracleRedeemer({ newInterestRate: { getOnChainInt: newInterestRate, }, currentTime: now, }), ); tx.pay.ToContract( utxo!.address, { kind: 'inline', value: serialiseInterestOracleDatum({ unitaryInterest: datum.unitaryInterest + calculateUnitaryInterestSinceOracleLastUpdated(now, datum), interestRate: { getOnChainInt: newInterestRate, }, lastUpdated: now, }), }, utxo!.assets, ); tx.validFrom(Number(now) - ONE_SECOND); tx.validTo(Number(now + params.biasTime) - ONE_SECOND); tx.addSignerKey(params.owner); return tx; }