@indigo-labs/indigo-sdk 0.2.41 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/workflows/ci.yml +4 -2
- package/dist/index.d.mts +3008 -2194
- package/dist/index.d.ts +3008 -2194
- package/dist/index.js +9827 -6194
- package/dist/index.mjs +8591 -4809
- package/package.json +14 -3
- package/src/contracts/cdp/helpers.ts +68 -72
- package/src/contracts/cdp/scripts.ts +50 -13
- package/src/contracts/cdp/transactions.ts +831 -545
- package/src/contracts/cdp/types-new.ts +256 -0
- package/src/contracts/cdp/types.ts +26 -144
- package/src/contracts/cdp-creator/scripts.ts +15 -9
- package/src/contracts/cdp-creator/types-new.ts +50 -0
- package/src/contracts/cdp-creator/types.ts +5 -31
- package/src/contracts/collector/scripts.ts +1 -1
- package/src/contracts/collector/transactions.ts +23 -13
- package/src/contracts/collector/types-new.ts +17 -0
- package/src/contracts/execute/scripts.ts +19 -10
- package/src/contracts/execute/types-new.ts +44 -0
- package/src/contracts/execute/types.ts +5 -38
- package/src/contracts/gov/helpers.ts +187 -51
- package/src/contracts/gov/scripts.ts +17 -10
- package/src/contracts/gov/transactions.ts +599 -271
- package/src/contracts/gov/types-new.ts +253 -100
- package/src/contracts/gov/types.ts +4 -71
- package/src/contracts/iasset/helpers.ts +172 -0
- package/src/contracts/iasset/scripts.ts +38 -0
- package/src/contracts/iasset/types.ts +154 -0
- package/src/contracts/initialize/actions.ts +768 -0
- package/src/contracts/initialize/helpers.ts +611 -36
- package/src/contracts/initialize/types.ts +102 -28
- package/src/contracts/interest-collection/helpers.ts +19 -0
- package/src/contracts/interest-collection/scripts.ts +44 -0
- package/src/contracts/interest-collection/transactions.ts +436 -0
- package/src/contracts/interest-collection/types-new.ts +50 -0
- package/src/contracts/interest-collection/types.ts +26 -0
- package/src/contracts/interest-oracle/helpers.ts +2 -30
- package/src/contracts/interest-oracle/scripts.ts +1 -1
- package/src/contracts/interest-oracle/transactions.ts +21 -16
- package/src/contracts/interest-oracle/types-new.ts +32 -0
- package/src/contracts/interest-oracle/types.ts +1 -40
- package/src/contracts/one-shot/transactions.ts +1 -2
- package/src/contracts/poll/helpers.ts +5 -23
- package/src/contracts/poll/scripts.ts +12 -13
- package/src/contracts/poll/types-poll-manager.ts +1 -19
- package/src/contracts/poll/types-poll-new.ts +170 -0
- package/src/contracts/poll/types-poll-shard.ts +2 -24
- package/src/contracts/price-oracle/helpers.ts +1 -4
- package/src/contracts/price-oracle/scripts.ts +3 -8
- package/src/contracts/price-oracle/transactions.ts +32 -25
- package/src/contracts/price-oracle/types-new.ts +50 -0
- package/src/contracts/price-oracle/types.ts +2 -36
- package/src/contracts/pyth-feed/helpers.ts +58 -0
- package/src/contracts/pyth-feed/scripts.ts +15 -0
- package/src/contracts/pyth-feed/types.ts +181 -0
- package/src/contracts/rob/helpers.ts +405 -0
- package/src/contracts/rob/scripts.ts +35 -0
- package/src/contracts/rob/transactions.ts +410 -0
- package/src/contracts/rob/types-new.ts +128 -0
- package/src/contracts/rob/types.ts +16 -0
- package/src/contracts/rob-leverage/helpers.ts +424 -0
- package/src/contracts/{leverage → rob-leverage}/transactions.ts +68 -48
- package/src/contracts/stability-pool/helpers.ts +714 -230
- package/src/contracts/stability-pool/scripts.ts +20 -15
- package/src/contracts/stability-pool/transactions.ts +625 -495
- package/src/contracts/stability-pool/types-new.ts +237 -100
- package/src/contracts/stability-pool/types.ts +5 -22
- package/src/contracts/stableswap/helpers.ts +22 -0
- package/src/contracts/stableswap/scripts.ts +37 -0
- package/src/contracts/stableswap/transactions.ts +647 -0
- package/src/contracts/stableswap/types-new.ts +131 -0
- package/src/contracts/stableswap/types.ts +17 -0
- package/src/contracts/staking/helpers.ts +49 -34
- package/src/contracts/staking/scripts.ts +1 -1
- package/src/contracts/staking/transactions.ts +85 -130
- package/src/contracts/staking/types-new.ts +60 -28
- package/src/contracts/staking/types.ts +1 -28
- package/src/contracts/treasury/helpers.ts +21 -0
- package/src/contracts/treasury/scripts.ts +16 -26
- package/src/contracts/treasury/transactions.ts +256 -27
- package/src/contracts/treasury/types-new.ts +69 -0
- package/src/contracts/treasury/types.ts +2 -43
- package/src/contracts/version-registry/scripts.ts +2 -2
- package/src/contracts/version-registry/types-new.ts +6 -7
- package/src/index.ts +37 -20
- package/src/scripts/auth-token-policy.ts +3 -2
- package/src/scripts/iasset-policy.ts +3 -2
- package/src/types/evolution-schema-options.ts +3 -3
- package/src/types/generic.ts +17 -89
- package/src/types/multisig.ts +48 -0
- package/src/types/on-chain-decimal.ts +14 -7
- package/src/types/rational.ts +61 -0
- package/src/types/system-params.ts +237 -41
- package/src/utils/array-utils.ts +70 -1
- package/src/utils/bigint-utils.ts +12 -0
- package/src/utils/indigo-helpers.ts +8 -10
- package/src/utils/lucid-utils.ts +47 -40
- package/src/utils/oracle-helpers.ts +62 -0
- package/src/utils/pyth/decode.ts +223 -0
- package/src/utils/pyth/encode.ts +262 -0
- package/src/utils/pyth/index.ts +14 -0
- package/src/utils/pyth/types.ts +87 -0
- package/src/validators/always-succeed-validator.ts +6 -0
- package/src/validators/cdp-creator-validator.ts +2 -2
- package/src/validators/cdp-redeem-validator.ts +7 -0
- package/src/validators/cdp-validator.ts +2 -2
- package/src/validators/collector-validator.ts +2 -2
- package/src/validators/execute-validator.ts +2 -2
- package/src/validators/governance-validator.ts +2 -2
- package/src/validators/iasset-validator.ts +7 -0
- package/src/validators/interest-collection-validator.ts +7 -0
- package/src/validators/interest-oracle-validator.ts +2 -2
- package/src/validators/poll-manager-validator.ts +2 -2
- package/src/validators/poll-shard-validator.ts +2 -2
- package/src/validators/price-oracle-validator.ts +7 -0
- package/src/validators/pyth-feed-validator.ts +7 -0
- package/src/validators/rob-validator.ts +7 -0
- package/src/validators/stability-pool-validator.ts +2 -2
- package/src/validators/stableswap-validator.ts +7 -0
- package/src/validators/staking-validator.ts +2 -2
- package/src/validators/treasury-validator.ts +2 -2
- package/src/validators/version-record-policy.ts +2 -2
- package/src/validators/version-registry-validator.ts +2 -2
- package/tests/always-succeed/script.ts +7 -0
- package/tests/bigint-utils.test.ts +41 -0
- package/tests/cdp/actions.ts +611 -0
- package/tests/cdp/cdp-helpers.ts +55 -0
- package/tests/cdp/cdp-queries.ts +440 -0
- package/tests/cdp/cdp.test.ts +6087 -0
- package/tests/cdp/transactions-mutated.ts +1729 -0
- package/tests/data/system-params.json +177 -34
- package/tests/datums.test.ts +209 -210
- package/tests/endpoints/initialize.ts +68 -0
- package/tests/endpoints/interest-collector.ts +37 -0
- package/tests/endpoints/treasury.ts +70 -0
- package/tests/gov/actions.ts +406 -0
- package/tests/gov/gov.test.ts +4450 -0
- package/tests/{queries → gov}/governance-queries.ts +6 -3
- package/tests/hash-checks.test.ts +38 -11
- package/tests/indigo-test-helpers.ts +100 -0
- package/tests/initialize.test.ts +61 -9
- package/tests/interest-collection/interest-collection.test.ts +892 -0
- package/tests/interest-collection/interest-collector-queries.ts +49 -0
- package/tests/interest-collection/transactions-mutated.ts +260 -0
- package/tests/interest-oracle.test.ts +43 -35
- package/tests/mock/assets-mock.ts +234 -23
- package/tests/mock/protocol-params-mock.ts +21 -0
- package/tests/price-oracle/actions.ts +163 -0
- package/tests/price-oracle/price-oracle-queries.ts +12 -0
- package/tests/price-oracle/price-oracle.test.ts +240 -0
- package/tests/price-oracle/transactions-mutated.ts +62 -0
- package/tests/pyth/endpoints.ts +96 -0
- package/tests/pyth/helpers.ts +37 -0
- package/tests/pyth/pyth-encoding.test.ts +376 -0
- package/tests/pyth/pyth-indigo.test.ts +509 -0
- package/tests/pyth/pyth.test.ts +300 -0
- package/tests/queries/execute-queries.ts +6 -5
- package/tests/queries/iasset-queries.ts +175 -5
- package/tests/queries/interest-oracle-queries.ts +4 -2
- package/tests/queries/poll-queries.ts +8 -9
- package/tests/queries/stability-pool-queries.ts +95 -48
- package/tests/queries/staking-queries.ts +4 -2
- package/tests/queries/treasury-queries.ts +80 -5
- package/tests/rob/actions.ts +58 -0
- package/tests/{lrp-leverage.test.ts → rob/rob-leverage.test.ts} +393 -296
- package/tests/rob/rob-queries.ts +95 -0
- package/tests/rob/rob.test.ts +3762 -0
- package/tests/rob/transactions-mutated.ts +853 -0
- package/tests/script-size.test.ts +240 -0
- package/tests/setup.ts +135 -0
- package/tests/stability-pool/actions.ts +210 -0
- package/tests/stability-pool.test.ts +5469 -666
- package/tests/stableswap/stableswap-actions.ts +84 -0
- package/tests/stableswap/stableswap-queries.ts +89 -0
- package/tests/stableswap/stableswap.test.ts +3891 -0
- package/tests/stableswap/transactions-mutated.ts +348 -0
- package/tests/staking.test.ts +82 -99
- package/tests/test-helpers.ts +58 -11
- package/tests/treasury.test.ts +242 -0
- package/tests/utils/asserts.ts +74 -0
- package/tests/utils/benchmark-utils.ts +81 -0
- package/tests/utils/index.ts +122 -4
- package/tsconfig.json +9 -1
- package/vitest.config.ts +3 -1
- package/src/contracts/collector/types.ts +0 -16
- package/src/contracts/initialize/transactions.ts +0 -891
- package/src/contracts/leverage/helpers.ts +0 -424
- package/src/contracts/lrp/helpers.ts +0 -294
- package/src/contracts/lrp/scripts.ts +0 -27
- package/src/contracts/lrp/transactions.ts +0 -250
- package/src/contracts/lrp/types.ts +0 -131
- package/src/contracts/poll/types-poll.ts +0 -88
- package/src/contracts/vesting/helpers.ts +0 -218
- package/src/utils/value-helpers.ts +0 -37
- package/src/validators/lrp-validator.ts +0 -7
- package/tests/cdp.test.ts +0 -1528
- package/tests/gov.test.ts +0 -2011
- package/tests/lrp.test.ts +0 -673
- package/tests/queries/cdp-queries.ts +0 -220
- package/tests/queries/lrp-queries.ts +0 -76
- package/tests/queries/price-oracle-queries.ts +0 -10
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
addAssets,
|
|
3
|
+
Data,
|
|
4
|
+
fromHex,
|
|
3
5
|
fromText,
|
|
4
6
|
LucidEvolution,
|
|
5
7
|
OutRef,
|
|
@@ -7,29 +9,32 @@ import {
|
|
|
7
9
|
TxBuilder,
|
|
8
10
|
validatorToAddress,
|
|
9
11
|
} from '@lucid-evolution/lucid';
|
|
10
|
-
import {
|
|
12
|
+
import { PriceOracleParams } from './types';
|
|
13
|
+
import { mkPriceOracleValidator } from './scripts';
|
|
14
|
+
import { oneShotMintTx } from '../one-shot/transactions';
|
|
15
|
+
import { AssetClass, mkAssetsOf } from '@3rd-eye-labs/cardano-offchain-common';
|
|
16
|
+
import { matchSingle } from '../../utils/utils';
|
|
17
|
+
import { ONE_SECOND } from '../../utils/time-helpers';
|
|
11
18
|
import {
|
|
12
|
-
OracleAssetNft,
|
|
13
19
|
PriceOracleDatum,
|
|
14
|
-
PriceOracleParams,
|
|
15
20
|
serialisePriceOracleDatum,
|
|
16
21
|
serialisePriceOracleRedeemer,
|
|
17
|
-
} from './types';
|
|
18
|
-
import
|
|
19
|
-
import {
|
|
20
|
-
import { mkAssetsOf, mkLovelacesOf } from '../../utils/value-helpers';
|
|
21
|
-
import { OnChainDecimal } from '../../types/on-chain-decimal';
|
|
22
|
-
import { ONE_SECOND } from '../../utils/time-helpers';
|
|
23
|
-
import { resolveUtxo, UtxoOrOutRef } from '../../utils/lucid-utils';
|
|
22
|
+
} from './types-new';
|
|
23
|
+
import * as Core from '@evolution-sdk/evolution';
|
|
24
|
+
import { Rational } from '../../types/rational';
|
|
24
25
|
|
|
25
26
|
export async function startPriceOracleTx(
|
|
26
27
|
lucid: LucidEvolution,
|
|
27
28
|
assetName: string,
|
|
28
|
-
startPrice:
|
|
29
|
+
startPrice: Rational,
|
|
29
30
|
oracleParams: PriceOracleParams,
|
|
30
|
-
|
|
31
|
+
currentSlot: number,
|
|
31
32
|
refOutRef?: OutRef,
|
|
32
|
-
|
|
33
|
+
auxiliaryData?: Core.Data.Data,
|
|
34
|
+
): Promise<[TxBuilder, AssetClass]> {
|
|
35
|
+
const network = lucid.config().network!;
|
|
36
|
+
const now = BigInt(slotToUnixTime(network, currentSlot));
|
|
37
|
+
|
|
33
38
|
if (!refOutRef) {
|
|
34
39
|
refOutRef = (await lucid.wallet().getUtxos())[0];
|
|
35
40
|
}
|
|
@@ -48,40 +53,41 @@ export async function startPriceOracleTx(
|
|
|
48
53
|
});
|
|
49
54
|
|
|
50
55
|
const priceOracleNft: AssetClass = {
|
|
51
|
-
currencySymbol: oracleNftPolicyId,
|
|
52
|
-
tokenName: fromText(assetName),
|
|
56
|
+
currencySymbol: fromHex(oracleNftPolicyId),
|
|
57
|
+
tokenName: fromHex(fromText(assetName)),
|
|
53
58
|
};
|
|
54
59
|
|
|
55
60
|
const oracleValidator = mkPriceOracleValidator(oracleParams);
|
|
56
61
|
|
|
57
62
|
const oracleDatum: PriceOracleDatum = {
|
|
58
63
|
price: startPrice,
|
|
59
|
-
|
|
64
|
+
expirationTime: BigInt(now) + oracleParams.expirationPeriod,
|
|
65
|
+
auxiliaryData: auxiliaryData ?? Core.Data.fromCBORHex(Data.void()),
|
|
60
66
|
};
|
|
61
67
|
|
|
62
68
|
tx.pay.ToContract(
|
|
63
69
|
validatorToAddress(lucid.config().network!, oracleValidator),
|
|
64
70
|
{ kind: 'inline', value: serialisePriceOracleDatum(oracleDatum) },
|
|
65
|
-
addAssets(
|
|
71
|
+
addAssets(mkAssetsOf(priceOracleNft, 1n)),
|
|
66
72
|
);
|
|
67
73
|
|
|
68
|
-
return [tx,
|
|
74
|
+
return [tx, priceOracleNft];
|
|
69
75
|
}
|
|
70
76
|
|
|
71
77
|
export async function feedPriceOracleTx(
|
|
72
78
|
lucid: LucidEvolution,
|
|
73
|
-
|
|
74
|
-
newPrice:
|
|
79
|
+
oracleOref: OutRef,
|
|
80
|
+
newPrice: Rational,
|
|
75
81
|
oracleParams: PriceOracleParams,
|
|
76
82
|
currentSlot: number,
|
|
83
|
+
auxiliaryData?: Core.Data.Data,
|
|
77
84
|
): Promise<TxBuilder> {
|
|
78
85
|
const network = lucid.config().network!;
|
|
79
86
|
const currentTime = BigInt(slotToUnixTime(network, currentSlot));
|
|
80
87
|
|
|
81
|
-
const priceOracleUtxo =
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
'Expected a single price oracle UTXO',
|
|
88
|
+
const priceOracleUtxo = matchSingle(
|
|
89
|
+
await lucid.utxosByOutRef([oracleOref]),
|
|
90
|
+
(_) => new Error('Expected a single price oracle UTXO'),
|
|
85
91
|
);
|
|
86
92
|
|
|
87
93
|
const oracleValidator = mkPriceOracleValidator(oracleParams);
|
|
@@ -104,7 +110,8 @@ export async function feedPriceOracleTx(
|
|
|
104
110
|
kind: 'inline',
|
|
105
111
|
value: serialisePriceOracleDatum({
|
|
106
112
|
price: newPrice,
|
|
107
|
-
|
|
113
|
+
expirationTime: currentTime + oracleParams.expirationPeriod,
|
|
114
|
+
auxiliaryData: auxiliaryData ?? Core.Data.fromCBORHex(Data.void()),
|
|
108
115
|
}),
|
|
109
116
|
},
|
|
110
117
|
priceOracleUtxo.assets,
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { TSchema, Data } from '@evolution-sdk/evolution';
|
|
2
|
+
import { Schema } from 'effect';
|
|
3
|
+
import { RationalSchema } from '../../types/rational';
|
|
4
|
+
|
|
5
|
+
const OpaqueData = Schema.typeSchema(Data.DataSchema);
|
|
6
|
+
|
|
7
|
+
export const OracleIdxSchema = TSchema.Union(
|
|
8
|
+
TSchema.Struct(
|
|
9
|
+
{
|
|
10
|
+
OracleRefInputIdx: TSchema.Integer,
|
|
11
|
+
},
|
|
12
|
+
{ flatInUnion: true },
|
|
13
|
+
),
|
|
14
|
+
TSchema.Struct(
|
|
15
|
+
{
|
|
16
|
+
OracleOutputIdx: TSchema.Integer,
|
|
17
|
+
},
|
|
18
|
+
{ flatInUnion: true },
|
|
19
|
+
),
|
|
20
|
+
TSchema.Literal('OracleVoid', { flatInUnion: true }),
|
|
21
|
+
);
|
|
22
|
+
|
|
23
|
+
export type OracleIdx = typeof OracleIdxSchema;
|
|
24
|
+
|
|
25
|
+
const PriceOracleDatumSchema = TSchema.Struct({
|
|
26
|
+
price: RationalSchema,
|
|
27
|
+
expirationTime: TSchema.Integer,
|
|
28
|
+
auxiliaryData: OpaqueData,
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
export type PriceOracleDatum = typeof PriceOracleDatumSchema.Type;
|
|
32
|
+
|
|
33
|
+
const PriceOracleRedeemerSchema = TSchema.Struct({
|
|
34
|
+
currentTime: TSchema.Integer,
|
|
35
|
+
newPrice: RationalSchema,
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
export type PriceOracleRedeemer = typeof PriceOracleRedeemerSchema.Type;
|
|
39
|
+
|
|
40
|
+
export function serialisePriceOracleRedeemer(r: PriceOracleRedeemer): string {
|
|
41
|
+
return Data.withSchema(PriceOracleRedeemerSchema).toCBORHex(r);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export function serialisePriceOracleDatum(d: PriceOracleDatum): string {
|
|
45
|
+
return Data.withSchema(PriceOracleDatumSchema).toCBORHex(d);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export function parsePriceOracleDatum(datum: string): PriceOracleDatum {
|
|
49
|
+
return Data.withSchema(PriceOracleDatumSchema).fromCBORHex(datum);
|
|
50
|
+
}
|
|
@@ -1,50 +1,16 @@
|
|
|
1
|
-
import { Data
|
|
2
|
-
import { AssetClassSchema } from '../../types/generic';
|
|
3
|
-
import { OnChainDecimalSchema } from '../../types/on-chain-decimal';
|
|
4
|
-
|
|
5
|
-
export const OracleAssetNftSchema = Data.Object({
|
|
6
|
-
oracleNft: AssetClassSchema,
|
|
7
|
-
});
|
|
8
|
-
export type OracleAssetNft = Data.Static<typeof OracleAssetNftSchema>;
|
|
1
|
+
import { Data } from '@lucid-evolution/lucid';
|
|
9
2
|
|
|
10
3
|
export const PriceOracleParamsSchema = Data.Object({
|
|
11
4
|
owner: Data.Bytes(),
|
|
12
5
|
/** Milliseconds */
|
|
13
6
|
biasTime: Data.Integer(),
|
|
14
7
|
/** Milliseconds */
|
|
15
|
-
|
|
8
|
+
expirationPeriod: Data.Integer(),
|
|
16
9
|
});
|
|
17
10
|
export type PriceOracleParams = Data.Static<typeof PriceOracleParamsSchema>;
|
|
18
11
|
const PriceOracleParams =
|
|
19
12
|
PriceOracleParamsSchema as unknown as PriceOracleParams;
|
|
20
13
|
|
|
21
|
-
export const PriceOracleDatumSchema = Data.Object({
|
|
22
|
-
price: OnChainDecimalSchema,
|
|
23
|
-
expiration: Data.Integer(),
|
|
24
|
-
});
|
|
25
|
-
export type PriceOracleDatum = Data.Static<typeof PriceOracleDatumSchema>;
|
|
26
|
-
const PriceOracleDatum = PriceOracleDatumSchema as unknown as PriceOracleDatum;
|
|
27
|
-
|
|
28
|
-
const PriceOracleRedeemerSchema = Data.Object({
|
|
29
|
-
currentTime: Data.Integer(),
|
|
30
|
-
newPrice: OnChainDecimalSchema,
|
|
31
|
-
});
|
|
32
|
-
export type PriceOracleRedeemer = Data.Static<typeof PriceOracleRedeemerSchema>;
|
|
33
|
-
const PriceOracleRedeemer =
|
|
34
|
-
PriceOracleRedeemerSchema as unknown as PriceOracleRedeemer;
|
|
35
|
-
|
|
36
|
-
export function serialisePriceOracleRedeemer(r: PriceOracleRedeemer): Redeemer {
|
|
37
|
-
return Data.to<PriceOracleRedeemer>(r, PriceOracleRedeemer);
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
export function parsePriceOracleDatum(datum: Datum): PriceOracleDatum {
|
|
41
|
-
return Data.from<PriceOracleDatum>(datum, PriceOracleDatum);
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
export function serialisePriceOracleDatum(datum: PriceOracleDatum): Datum {
|
|
45
|
-
return Data.to<PriceOracleDatum>(datum, PriceOracleDatum);
|
|
46
|
-
}
|
|
47
|
-
|
|
48
14
|
export function castPriceOracleParams(params: PriceOracleParams): Data {
|
|
49
15
|
return Data.castTo(params, PriceOracleParams);
|
|
50
16
|
}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { match, P } from 'ts-pattern';
|
|
2
|
+
import { Rational } from '../../types/rational';
|
|
3
|
+
import { decodePriceUpdate, decodePythMessage } from '../../utils/pyth';
|
|
4
|
+
import {
|
|
5
|
+
DerivedPythPrice,
|
|
6
|
+
fromDataDerivedPythPrice,
|
|
7
|
+
PythConfiguration,
|
|
8
|
+
} from './types';
|
|
9
|
+
import { ParsedFeedPayload } from '@pythnetwork/pyth-lazer-sdk';
|
|
10
|
+
import { fromHex } from '@lucid-evolution/lucid';
|
|
11
|
+
|
|
12
|
+
/** Rational form { num, den } so we can do exact division (e.g. 1/0.00001 = 100000). */
|
|
13
|
+
export function derivePythPrice(
|
|
14
|
+
derivedPythPrice: DerivedPythPrice,
|
|
15
|
+
messageHex: string,
|
|
16
|
+
): Rational {
|
|
17
|
+
const decodedMessage = decodePythMessage(fromHex(messageHex));
|
|
18
|
+
const pricePayload = decodePriceUpdate(decodedMessage.payload);
|
|
19
|
+
return match(derivedPythPrice)
|
|
20
|
+
.with(
|
|
21
|
+
{ Value: P.select() },
|
|
22
|
+
(value: { configuration: PythConfiguration }) => {
|
|
23
|
+
const payload = pricePayload.priceFeeds.find(
|
|
24
|
+
(p: ParsedFeedPayload) =>
|
|
25
|
+
p.priceFeedId === Number(value.configuration.priceFeedId),
|
|
26
|
+
);
|
|
27
|
+
if (!payload)
|
|
28
|
+
throw new Error(
|
|
29
|
+
`Pyth payload not found for feed ID: ${value.configuration.priceFeedId}`,
|
|
30
|
+
);
|
|
31
|
+
const priceStr = payload.price;
|
|
32
|
+
if (priceStr === undefined)
|
|
33
|
+
throw new Error(`Pyth feed ${payload.priceFeedId} has no price`);
|
|
34
|
+
const price = BigInt(priceStr);
|
|
35
|
+
const exp = payload.exponent ?? 0;
|
|
36
|
+
if (exp >= 0) {
|
|
37
|
+
return { numerator: price * 10n ** BigInt(exp), denominator: 1n };
|
|
38
|
+
}
|
|
39
|
+
return { numerator: price, denominator: 10n ** BigInt(-exp) };
|
|
40
|
+
},
|
|
41
|
+
)
|
|
42
|
+
.with({ Inverse: P.select() }, (inverse) => {
|
|
43
|
+
const inner = derivePythPrice(
|
|
44
|
+
fromDataDerivedPythPrice(inverse.value),
|
|
45
|
+
messageHex,
|
|
46
|
+
);
|
|
47
|
+
return { numerator: inner.denominator, denominator: inner.numerator };
|
|
48
|
+
})
|
|
49
|
+
.with({ Divide: P.select() }, (divide) => {
|
|
50
|
+
const x = derivePythPrice(fromDataDerivedPythPrice(divide.x), messageHex);
|
|
51
|
+
const y = derivePythPrice(fromDataDerivedPythPrice(divide.y), messageHex);
|
|
52
|
+
return {
|
|
53
|
+
numerator: x.numerator * y.denominator,
|
|
54
|
+
denominator: x.denominator * y.numerator,
|
|
55
|
+
};
|
|
56
|
+
})
|
|
57
|
+
.exhaustive();
|
|
58
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { SpendingValidator } from '@lucid-evolution/lucid';
|
|
2
|
+
import { _pythFeedValidator } from '../../validators/pyth-feed-validator';
|
|
3
|
+
import { applyParamsToScript } from '@evolution-sdk/evolution/uplc';
|
|
4
|
+
import { PythFeedParams, serialisePythFeedParams } from './types';
|
|
5
|
+
|
|
6
|
+
export const mkPythFeedValidator = (
|
|
7
|
+
params: PythFeedParams,
|
|
8
|
+
): SpendingValidator => {
|
|
9
|
+
return {
|
|
10
|
+
type: 'PlutusV3',
|
|
11
|
+
script: applyParamsToScript(_pythFeedValidator.cborHex, [
|
|
12
|
+
serialisePythFeedParams(params),
|
|
13
|
+
]),
|
|
14
|
+
};
|
|
15
|
+
};
|
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
import { TSchema, Data, Schema } from '@evolution-sdk/evolution';
|
|
2
|
+
import { DEFAULT_SCHEMA_OPTIONS } from '../../types/evolution-schema-options';
|
|
3
|
+
import { RationalSchema } from '../../types/rational';
|
|
4
|
+
|
|
5
|
+
const PythConfigurationSchema = TSchema.Struct({
|
|
6
|
+
priceFeedId: TSchema.Integer,
|
|
7
|
+
});
|
|
8
|
+
|
|
9
|
+
export type PythConfiguration = typeof PythConfigurationSchema.Type;
|
|
10
|
+
|
|
11
|
+
const OpaqueData = Schema.typeSchema(Data.DataSchema);
|
|
12
|
+
|
|
13
|
+
export const DerivedPythPriceSchema = TSchema.Union(
|
|
14
|
+
TSchema.Struct(
|
|
15
|
+
{
|
|
16
|
+
Value: TSchema.Struct(
|
|
17
|
+
{ configuration: PythConfigurationSchema },
|
|
18
|
+
{ flatFields: true },
|
|
19
|
+
),
|
|
20
|
+
},
|
|
21
|
+
{ flatInUnion: true },
|
|
22
|
+
),
|
|
23
|
+
TSchema.Struct(
|
|
24
|
+
{
|
|
25
|
+
Inverse: TSchema.Struct({ value: OpaqueData }, { flatFields: true }),
|
|
26
|
+
},
|
|
27
|
+
{ flatInUnion: true },
|
|
28
|
+
),
|
|
29
|
+
TSchema.Struct(
|
|
30
|
+
{
|
|
31
|
+
Divide: TSchema.Struct(
|
|
32
|
+
{ x: OpaqueData, y: OpaqueData },
|
|
33
|
+
{ flatFields: true },
|
|
34
|
+
),
|
|
35
|
+
},
|
|
36
|
+
{ flatInUnion: true },
|
|
37
|
+
),
|
|
38
|
+
);
|
|
39
|
+
|
|
40
|
+
export type DerivedPythPrice = typeof DerivedPythPriceSchema.Type;
|
|
41
|
+
|
|
42
|
+
export function fromDataDerivedPythPrice(data: Data.Data): DerivedPythPrice {
|
|
43
|
+
return Data.withSchema(DerivedPythPriceSchema).fromCBORHex(
|
|
44
|
+
Data.toCBORHex(data),
|
|
45
|
+
);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export function toDataDerivedPythPrice(
|
|
49
|
+
derivedPythPrice: DerivedPythPrice,
|
|
50
|
+
): Data.Data {
|
|
51
|
+
return Data.withSchema(DerivedPythPriceSchema).toData(derivedPythPrice);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
const PythFeedParamsSchema = TSchema.Struct({
|
|
55
|
+
config: DerivedPythPriceSchema,
|
|
56
|
+
pythStatePolicyId: TSchema.ByteArray,
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
export type PythFeedParams = typeof PythFeedParamsSchema.Type;
|
|
60
|
+
|
|
61
|
+
export function serialisePythFeedParams(params: PythFeedParams): Data.Data {
|
|
62
|
+
return Data.withSchema(PythFeedParamsSchema).toData(params);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
const PythFeedRedeemerSchema = TSchema.Struct(
|
|
66
|
+
{
|
|
67
|
+
price: RationalSchema,
|
|
68
|
+
auxiliaryData: OpaqueData,
|
|
69
|
+
},
|
|
70
|
+
{ flatInUnion: true },
|
|
71
|
+
);
|
|
72
|
+
export type PythFeedRedeemer = typeof PythFeedRedeemerSchema.Type;
|
|
73
|
+
|
|
74
|
+
export function serialisePythFeedRedeemer(r: PythFeedRedeemer): string {
|
|
75
|
+
return Data.withSchema(
|
|
76
|
+
PythFeedRedeemerSchema,
|
|
77
|
+
DEFAULT_SCHEMA_OPTIONS,
|
|
78
|
+
).toCBORHex(r);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* IntervalBoundType
|
|
83
|
+
* A type of interval bound. The value for the `Finite` case typically
|
|
84
|
+
represents a number of seconds or milliseconds.
|
|
85
|
+
*/
|
|
86
|
+
export const AikenIntervalIntervalBoundType = TSchema.Union(
|
|
87
|
+
TSchema.TaggedStruct('NegativeInfinity', {}, { flatInUnion: true }),
|
|
88
|
+
TSchema.TaggedStruct(
|
|
89
|
+
'Finite',
|
|
90
|
+
{ finite: TSchema.Integer },
|
|
91
|
+
{ flatInUnion: true },
|
|
92
|
+
),
|
|
93
|
+
TSchema.TaggedStruct('PositiveInfinity', {}, { flatInUnion: true }),
|
|
94
|
+
);
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* IntervalBound
|
|
98
|
+
* An interval bound, either inclusive or exclusive.
|
|
99
|
+
*/
|
|
100
|
+
export const AikenIntervalIntervalBound = TSchema.Struct({
|
|
101
|
+
bound_type: AikenIntervalIntervalBoundType,
|
|
102
|
+
is_inclusive: TSchema.Boolean,
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* ValidityRange
|
|
107
|
+
* A type to represent intervals of values. Interval are inhabited by an
|
|
108
|
+
integer value representing have a finite lower-bound and/or upper-bound.
|
|
109
|
+
This allows to represent all kind of mathematical intervals:
|
|
110
|
+
```aiken
|
|
111
|
+
// [1; 10]
|
|
112
|
+
let i0: Interval = Interval
|
|
113
|
+
{ lower_bound:
|
|
114
|
+
IntervalBound { bound_type: Finite(1), is_inclusive: True }
|
|
115
|
+
, upper_bound:
|
|
116
|
+
IntervalBound { bound_type: Finite(10), is_inclusive: True }
|
|
117
|
+
}
|
|
118
|
+
```
|
|
119
|
+
```aiken
|
|
120
|
+
// (20; infinity)
|
|
121
|
+
let i1: Interval = Interval
|
|
122
|
+
{ lower_bound:
|
|
123
|
+
IntervalBound { bound_type: Finite(20), is_inclusive: False }
|
|
124
|
+
, upper_bound:
|
|
125
|
+
IntervalBound { bound_type: PositiveInfinity, is_inclusive: False }
|
|
126
|
+
}
|
|
127
|
+
```
|
|
128
|
+
*/
|
|
129
|
+
export const CardanoTransactionValidityRange = TSchema.Struct({
|
|
130
|
+
lower_bound: AikenIntervalIntervalBound,
|
|
131
|
+
upper_bound: AikenIntervalIntervalBound,
|
|
132
|
+
});
|
|
133
|
+
|
|
134
|
+
const PythStateDatumSchema = TSchema.Struct(
|
|
135
|
+
{
|
|
136
|
+
governance: TSchema.Struct(
|
|
137
|
+
{
|
|
138
|
+
wormhole: TSchema.ByteArray,
|
|
139
|
+
emitterChain: TSchema.Integer,
|
|
140
|
+
emitterAddress: TSchema.ByteArray,
|
|
141
|
+
seenSequence: TSchema.Integer,
|
|
142
|
+
},
|
|
143
|
+
{ flatInUnion: true },
|
|
144
|
+
),
|
|
145
|
+
trustedSigners: TSchema.Map(
|
|
146
|
+
TSchema.ByteArray,
|
|
147
|
+
CardanoTransactionValidityRange,
|
|
148
|
+
),
|
|
149
|
+
deprecatedWithdrawScripts: TSchema.Map(
|
|
150
|
+
CardanoTransactionValidityRange,
|
|
151
|
+
TSchema.ByteArray,
|
|
152
|
+
),
|
|
153
|
+
withdraw_script: TSchema.ByteArray,
|
|
154
|
+
},
|
|
155
|
+
{ flatInUnion: true },
|
|
156
|
+
);
|
|
157
|
+
export type PythStateDatum = typeof PythStateDatumSchema.Type;
|
|
158
|
+
|
|
159
|
+
export function serialisePythStateDatum(r: PythStateDatum): string {
|
|
160
|
+
return Data.withSchema(
|
|
161
|
+
PythStateDatumSchema,
|
|
162
|
+
DEFAULT_SCHEMA_OPTIONS,
|
|
163
|
+
).toCBORHex(r);
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
export function parsePythStateDatum(datum: string): PythStateDatum {
|
|
167
|
+
return Data.withSchema(
|
|
168
|
+
PythStateDatumSchema,
|
|
169
|
+
DEFAULT_SCHEMA_OPTIONS,
|
|
170
|
+
).fromCBORHex(datum);
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
const PythUpdatesRedeemerSchema = TSchema.Array(TSchema.ByteArray);
|
|
174
|
+
export type PythUpdatesRedeemer = typeof PythUpdatesRedeemerSchema.Type;
|
|
175
|
+
|
|
176
|
+
export function serialisePythUpdatesRedeemer(r: PythUpdatesRedeemer): string {
|
|
177
|
+
return Data.withSchema(
|
|
178
|
+
PythUpdatesRedeemerSchema,
|
|
179
|
+
DEFAULT_SCHEMA_OPTIONS,
|
|
180
|
+
).toCBORHex(r);
|
|
181
|
+
}
|