UNPKG

@indigo-labs/indigo-sdk

Version:

Indigo SDK for interacting with Indigo endpoints via lucid-evolution

121 lines (108 loc) 3.44 kB
import { addAssets, Data, fromHex, fromText, LucidEvolution, OutRef, slotToUnixTime, TxBuilder, validatorToAddress, } from '@lucid-evolution/lucid'; import { PriceOracleParams } from './types'; import { mkPriceOracleValidator } from './scripts'; import { oneShotMintTx } from '../one-shot/transactions'; import { AssetClass, mkAssetsOf } from '@3rd-eye-labs/cardano-offchain-common'; import { matchSingle } from '../../utils/utils'; import { ONE_SECOND } from '../../utils/time-helpers'; import { PriceOracleDatum, serialisePriceOracleDatum, serialisePriceOracleRedeemer, } from './types-new'; import * as Core from '@evolution-sdk/evolution'; import { Rational } from '../../types/rational'; export async function startPriceOracleTx( lucid: LucidEvolution, assetName: string, startPrice: Rational, oracleParams: PriceOracleParams, currentSlot: number, refOutRef?: OutRef, auxiliaryData?: Core.Data.Data, ): Promise<[TxBuilder, AssetClass]> { const network = lucid.config().network!; const now = BigInt(slotToUnixTime(network, currentSlot)); if (!refOutRef) { refOutRef = (await lucid.wallet().getUtxos())[0]; } const [tx, oracleNftPolicyId] = await oneShotMintTx(lucid, { referenceOutRef: { txHash: refOutRef.txHash, outputIdx: BigInt(refOutRef.outputIndex), }, mintAmounts: [ { tokenName: fromText(assetName), amount: 1n, }, ], }); const priceOracleNft: AssetClass = { currencySymbol: fromHex(oracleNftPolicyId), tokenName: fromHex(fromText(assetName)), }; const oracleValidator = mkPriceOracleValidator(oracleParams); const oracleDatum: PriceOracleDatum = { price: startPrice, expirationTime: BigInt(now) + oracleParams.expirationPeriod, auxiliaryData: auxiliaryData ?? Core.Data.fromCBORHex(Data.void()), }; tx.pay.ToContract( validatorToAddress(lucid.config().network!, oracleValidator), { kind: 'inline', value: serialisePriceOracleDatum(oracleDatum) }, addAssets(mkAssetsOf(priceOracleNft, 1n)), ); return [tx, priceOracleNft]; } export async function feedPriceOracleTx( lucid: LucidEvolution, oracleOref: OutRef, newPrice: Rational, oracleParams: PriceOracleParams, currentSlot: number, auxiliaryData?: Core.Data.Data, ): Promise<TxBuilder> { const network = lucid.config().network!; const currentTime = BigInt(slotToUnixTime(network, currentSlot)); const priceOracleUtxo = matchSingle( await lucid.utxosByOutRef([oracleOref]), (_) => new Error('Expected a single price oracle UTXO'), ); const oracleValidator = mkPriceOracleValidator(oracleParams); return lucid .newTx() .validFrom(Number(currentTime - oracleParams.biasTime) + ONE_SECOND) .validTo(Number(currentTime + oracleParams.biasTime) - ONE_SECOND) .attach.SpendingValidator(oracleValidator) .collectFrom( [priceOracleUtxo], serialisePriceOracleRedeemer({ currentTime: currentTime, newPrice: newPrice, }), ) .pay.ToContract( priceOracleUtxo.address, { kind: 'inline', value: serialisePriceOracleDatum({ price: newPrice, expirationTime: currentTime + oracleParams.expirationPeriod, auxiliaryData: auxiliaryData ?? Core.Data.fromCBORHex(Data.void()), }), }, priceOracleUtxo.assets, ) .addSignerKey(oracleParams.owner); }