UNPKG

@indigo-labs/indigo-sdk

Version:

Indigo SDK for interacting with Indigo endpoints via lucid-evolution

386 lines (337 loc) 10 kB
import { TSchema, Data } from '@evolution-sdk/evolution'; import { match, P } from 'ts-pattern'; import { option as O, function as F } from 'fp-ts'; import { DEFAULT_SCHEMA_OPTIONS } from '../../types/evolution-schema-options'; import { AddressSchema, AssetClassSchema, OutputReferenceSchema, } from '@3rd-eye-labs/cardano-offchain-common'; import { divideOnChainCompatible, zeroNegatives, } from '../../utils/bigint-utils'; export const SPIntegerSchema = TSchema.Struct({ value: TSchema.Integer, }); export type SPInteger = typeof SPIntegerSchema.Type; const AccountActionSchema = TSchema.Union( TSchema.Literal('Create', { flatInUnion: true }), TSchema.Struct( { Adjust: TSchema.Struct( { amount: TSchema.Integer, outputAddress: AddressSchema, }, { flatFields: true }, ), }, { flatInUnion: true }, ), TSchema.Struct( { Close: TSchema.Struct( { outputAddress: AddressSchema, maxTxFee: TSchema.Integer }, { flatFields: true }, ), }, { flatInUnion: true }, ), ); export type AccountAction = typeof AccountActionSchema.Type; const SumSnapshotSchema = TSchema.Struct({ sumVal: SPIntegerSchema, isLastInEpoch: TSchema.Boolean, isFirstSnapshot: TSchema.Boolean, }); export type SumSnapshot = typeof SumSnapshotSchema.Type; const EpochToScaleKeySchema = TSchema.Struct({ epoch: TSchema.Integer, scale: TSchema.Integer, }); export type EpochToScaleKey = typeof EpochToScaleKeySchema.Type; const EpochToScaleToSumEntrySchema = TSchema.Tuple([ EpochToScaleKeySchema, SumSnapshotSchema, ]); export type EpochToScaleToSumEntry = typeof EpochToScaleToSumEntrySchema.Type; const StateSnapshotSchema = TSchema.Struct({ productVal: SPIntegerSchema, depositVal: SPIntegerSchema, epoch: TSchema.Integer, scale: TSchema.Integer, }); export type StateSnapshot = typeof StateSnapshotSchema.Type; const AssetSnapshotSchema = TSchema.Struct({ currentSumVal: SPIntegerSchema, epoch2scale2sum: TSchema.Array(EpochToScaleToSumEntrySchema), }); export type AssetSnapshot = typeof AssetSnapshotSchema.Type; const AssetStateSchema = TSchema.Tuple([AssetClassSchema, AssetSnapshotSchema]); export type AssetState = typeof AssetStateSchema.Type; export const StabilityPoolContentSchema = TSchema.Struct({ iasset: TSchema.ByteArray, state: StateSnapshotSchema, assetStates: TSchema.Array(AssetStateSchema), }); export type StabilityPoolContent = typeof StabilityPoolContentSchema.Type; export const AccountContentSchema = TSchema.Struct({ owner: TSchema.ByteArray, iasset: TSchema.ByteArray, state: StateSnapshotSchema, assetSums: TSchema.Array(TSchema.Tuple([AssetClassSchema, SPIntegerSchema])), request: TSchema.NullOr(AccountActionSchema), lastRequestProcessingTime: TSchema.Integer, }); export type AccountContent = typeof AccountContentSchema.Type; export const SnapshotEpochToScaleToSumContentSchema = TSchema.Struct({ snapshot: TSchema.Array(EpochToScaleToSumEntrySchema), iasset: TSchema.ByteArray, collateralAsset: AssetClassSchema, }); export type SnapshotEpochToScaleToSumContent = typeof SnapshotEpochToScaleToSumContentSchema.Type; export const StabilityPoolDatumSchema = TSchema.Union( TSchema.Struct( { StabilityPool: StabilityPoolContentSchema }, { flatInUnion: true }, ), TSchema.Struct({ Account: AccountContentSchema }, { flatInUnion: true }), TSchema.Struct( { SnapshotEpochToScaleToSum: SnapshotEpochToScaleToSumContentSchema }, { flatInUnion: true }, ), ); const E2S2SIndexSchema = TSchema.Union( TSchema.Struct( { StabilityPoolListIdx: TSchema.Integer }, { flatInUnion: true }, ), TSchema.Struct( { RefInputIdx: TSchema.Struct( { refInputIdx: TSchema.Integer, snapshotListIdx: TSchema.Integer, }, { flatFields: true }, ), }, { flatInUnion: true }, ), ); export type E2S2SIndex = typeof E2S2SIndexSchema.Type; const E2S2SIndicesPerAssetSchema = TSchema.Array( TSchema.Tuple([E2S2SIndexSchema, TSchema.NullOr(E2S2SIndexSchema)]), ); export type E2S2SIndicesPerAsset = typeof E2S2SIndicesPerAssetSchema.Type; const ProcessRequestAccountContentSchema = TSchema.Struct( { poolInputIdx: TSchema.Integer, accountInputIdx: TSchema.Integer, e2s2sIdxs: E2S2SIndicesPerAssetSchema, currentTime: TSchema.Integer, }, { flatFields: true }, ); export type ProcessRequestAccountContent = typeof ProcessRequestAccountContentSchema.Type; export const StabilityPoolRedeemerSchema = TSchema.Union( TSchema.Struct({ RequestAction: AccountActionSchema }, { flatInUnion: true }), TSchema.Struct( { ProcessRequestPool: TSchema.Struct( { poolInputIdx: TSchema.Integer, accountInputIdx: TSchema.Integer, }, { flatFields: true }, ), }, { flatInUnion: true }, ), TSchema.Struct( { ProcessRequestAccount: ProcessRequestAccountContentSchema, }, { flatInUnion: true }, ), TSchema.Literal('AnnulRequest', { flatInUnion: true }), TSchema.Struct( { LiquidateCDP: TSchema.Struct( { cdpIdx: TSchema.Integer, }, { flatFields: true }, ), }, { flatInUnion: true }, ), TSchema.Literal('RecordEpochToScaleToSum', { flatInUnion: true }), TSchema.Literal('UpgradeVersion', { flatInUnion: true }), ); export type StabilityPoolRedeemer = typeof StabilityPoolRedeemerSchema.Type; const ActionReturnDatumSchema = TSchema.Union( TSchema.Struct( { IndigoStabilityPoolAccountAdjustment: OutputReferenceSchema, }, { flatInUnion: true }, ), TSchema.Struct( { IndigoStabilityPoolAccountClosure: OutputReferenceSchema, }, { flatInUnion: true }, ), ); export type ActionReturnDatum = typeof ActionReturnDatumSchema.Type; export function serialiseActionReturnDatum(d: ActionReturnDatum): string { return Data.withSchema( ActionReturnDatumSchema, DEFAULT_SCHEMA_OPTIONS, ).toCBORHex(d); } export function serialiseStabilityPoolRedeemer( r: StabilityPoolRedeemer, ): string { return Data.withSchema( StabilityPoolRedeemerSchema, DEFAULT_SCHEMA_OPTIONS, ).toCBORHex(r); } export function parseStabilityPoolRedeemer( datum: string, ): O.Option<StabilityPoolRedeemer> { try { return O.some( Data.withSchema( StabilityPoolRedeemerSchema, DEFAULT_SCHEMA_OPTIONS, ).fromCBORHex(datum), ); } catch (_) { return O.none; } } export function parseStabilityPoolRedeemerOrThrow( datum: string, ): StabilityPoolRedeemer { return F.pipe( parseStabilityPoolRedeemer(datum), O.match(() => { throw new Error('Expected a StabilityPoolRedeemer datum.'); }, F.identity), ); } export function serialiseStabilityPoolDatum( d: typeof StabilityPoolDatumSchema.Type, /** * This is necessary to change only in case of execute propose asset. */ useIndefiniteMaps: boolean = false, ): string { return Data.withSchema(StabilityPoolDatumSchema, { ...DEFAULT_SCHEMA_OPTIONS, useIndefiniteMaps: useIndefiniteMaps, }).toCBORHex(d); } export function parseStabilityPoolDatum( datum: string, ): O.Option<StabilityPoolContent> { try { return match( Data.withSchema( StabilityPoolDatumSchema, DEFAULT_SCHEMA_OPTIONS, ).fromCBORHex(datum), ) .with({ StabilityPool: P.select() }, (res) => O.some(res)) .otherwise(() => O.none); } catch (_) { return O.none; } } export function parseStabilityPoolDatumOrThrow( datum: string, ): StabilityPoolContent { return F.pipe( parseStabilityPoolDatum(datum), O.match(() => { throw new Error('Expected stability pool datum.'); }, F.identity), ); } export function parseAccountDatum(datum: string): O.Option<AccountContent> { try { return match( Data.withSchema( StabilityPoolDatumSchema, DEFAULT_SCHEMA_OPTIONS, ).fromCBORHex(datum), ) .with({ Account: P.select() }, (res) => O.some(res)) .otherwise(() => O.none); } catch (_) { return O.none; } } export function parseAccountDatumOrThrow(datum: string): AccountContent { return F.pipe( parseAccountDatum(datum), O.match(() => { throw new Error('Expected account datum.'); }, F.identity), ); } export function parseSnapshotEpochToScaleToSumDatum( datum: string, ): O.Option<SnapshotEpochToScaleToSumContent> { try { return match( Data.withSchema( StabilityPoolDatumSchema, DEFAULT_SCHEMA_OPTIONS, ).fromCBORHex(datum), ) .with({ SnapshotEpochToScaleToSum: P.select() }, (res) => O.some(res)) .otherwise(() => O.none); } catch (_) { return O.none; } } export function parseSnapshotEpochToScaleToSumDatumOrThrow( datum: string, ): SnapshotEpochToScaleToSumContent { return F.pipe( parseSnapshotEpochToScaleToSumDatum(datum), O.match(() => { throw new Error('Expected snapshot e2s2s datum.'); }, F.identity), ); } /** SP Integer */ const spPrecision: bigint = 1_000_000_000_000_000_000n; export function mkSPInteger(value: bigint): SPInteger { return { value: value * spPrecision }; } export function fromSPInteger(value: SPInteger): bigint { return divideOnChainCompatible(value.value, spPrecision); } export function spAdd(a: SPInteger, b: SPInteger): SPInteger { return { value: a.value + b.value }; } export function spSub(a: SPInteger, b: SPInteger): SPInteger { return { value: a.value - b.value }; } export function spMul(a: SPInteger, b: SPInteger): SPInteger { return { value: divideOnChainCompatible(a.value * b.value, spPrecision) }; } export function spDiv(a: SPInteger, b: SPInteger): SPInteger { return { value: divideOnChainCompatible(a.value * spPrecision, b.value) }; } export function spZeroNegatives(a: SPInteger): SPInteger { return { value: zeroNegatives(a.value) }; }