@indigo-labs/indigo-sdk
Version:
Indigo SDK for interacting with Indigo endpoints via lucid-evolution
164 lines (140 loc) • 4.38 kB
text/typescript
import {
AssetClass,
getInlineDatumOrThrow,
isSameAssetClass,
} from '@3rd-eye-labs/cardano-offchain-common';
import { AssetInfo, fromSystemParamsAsset, SystemParams } from '../../src';
import {
LucidContext,
runAndAwaitTx,
selectWalletByAddress,
} from '../test-helpers';
import {
findAllNecessaryOrefs,
findPrice,
findPriceOracleFromCollateralAsset,
} from '../cdp/cdp-queries';
import { feedPriceOracleTx } from '../../src/contracts/price-oracle/transactions';
import { findCollateralAsset } from '../queries/iasset-queries';
import { unixTimeToSlot } from '@lucid-evolution/lucid';
import { findPriceOracle } from './price-oracle-queries';
import { match, P } from 'ts-pattern';
import { parsePriceOracleDatum } from '../../src/contracts/price-oracle/types-new';
import { expect } from 'vitest';
import { Rational } from '../../src/types/rational';
/**
* Selects admin wallet and feeds the price oracle with the given price
*/
export async function runFeedPriceToOracle(
context: LucidContext,
sysParams: SystemParams,
assetInfo: AssetInfo,
collateralAsset: AssetClass,
price: Rational,
): Promise<void> {
const prevAddr = await context.lucid.wallet().address();
context.lucid.selectWallet.fromSeed(context.users.admin.seedPhrase);
const collateralOut = await findCollateralAsset(
context.lucid,
sysParams,
fromSystemParamsAsset(sysParams.cdpParams.collateralAssetAuthToken),
assetInfo.iassetTokenNameAscii,
collateralAsset,
);
const collateralInfo = assetInfo.collateralAssets.find((a) =>
isSameAssetClass(a.collateralAsset, collateralAsset),
);
if (!collateralInfo) {
throw new Error('No such collateral asset for the given iasset.');
}
const priceOracleUtxo = await findPriceOracleFromCollateralAsset(
context.lucid,
collateralOut,
);
await runAndAwaitTx(
context.lucid,
feedPriceOracleTx(
context.lucid,
priceOracleUtxo!,
price,
collateralInfo.oracleParams!,
context.emulator.slot,
),
);
selectWalletByAddress(context, prevAddr);
}
/**
* When oracle expired, refreshing updates the expiration leaving the same price.
*/
export async function refreshPriceOracle(
context: LucidContext,
sysParams: SystemParams,
assetInfo: AssetInfo,
collateralAsset: AssetClass,
): Promise<void> {
const prevAddr = await context.lucid.wallet().address();
context.lucid.selectWallet.fromSeed(context.users.admin.seedPhrase);
// Feed price oracle
const orefs = await findAllNecessaryOrefs(
context.lucid,
sysParams,
assetInfo.iassetTokenNameAscii,
collateralAsset,
);
const collateralInfo = assetInfo.collateralAssets.find((a) =>
isSameAssetClass(a.collateralAsset, collateralAsset),
);
if (!collateralInfo) {
throw new Error('No such collateral asset for the given iasset.');
}
const price = await findPrice(
context.lucid,
sysParams,
assetInfo.iassetTokenNameAscii,
collateralAsset,
);
const priceOracleUtxo = await findPriceOracleFromCollateralAsset(
context.lucid,
orefs.collateralAsset,
);
await runAndAwaitTx(
context.lucid,
feedPriceOracleTx(
context.lucid,
priceOracleUtxo!,
price,
collateralInfo.oracleParams!,
context.emulator.slot,
),
);
selectWalletByAddress(context, prevAddr);
}
export async function waitForOracleExpiration(
context: LucidContext,
sysParams: SystemParams,
iasset: string,
collateralAsset: AssetClass,
): Promise<void> {
const collateral = await findCollateralAsset(
context.lucid,
sysParams,
fromSystemParamsAsset(sysParams.cdpCreatorParams.collateralAssetAuthTk),
iasset,
collateralAsset,
);
await match(collateral.datum.priceInfo)
.with({ OracleNft: P.select() }, async (nft) => {
const priceOracle = await findPriceOracle(context.lucid, nft);
const oracle = parsePriceOracleDatum(getInlineDatumOrThrow(priceOracle));
const targetSlot = unixTimeToSlot(
context.lucid.config().network!,
Number(oracle.expirationTime),
);
if (targetSlot > context.emulator.slot) {
expect(targetSlot).toBeGreaterThan(context.emulator.slot);
context.emulator.awaitSlot(targetSlot - context.emulator.slot + 5);
}
})
// otherwise no need to await
.otherwise(() => {});
}