@indigo-labs/indigo-sdk
Version:
Indigo SDK for interacting with Indigo endpoints via lucid-evolution
386 lines (337 loc) • 10 kB
text/typescript
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) };
}