@indigo-labs/indigo-sdk 0.2.34 → 0.2.36

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.
@@ -1,9 +1,4 @@
1
- import {
2
- fromText,
3
- OutRef,
4
- UTxO,
5
- validatorToScriptHash,
6
- } from '@lucid-evolution/lucid';
1
+ import { fromText, UTxO, validatorToScriptHash } from '@lucid-evolution/lucid';
7
2
  import { LucidEvolution } from '@lucid-evolution/lucid';
8
3
  import { SystemParams } from '../../types/system-params';
9
4
  import {
@@ -13,7 +8,11 @@ import {
13
8
  StakingPosition,
14
9
  StakingPosLockedAmt,
15
10
  } from './types-new';
16
- import { createScriptAddress } from '../../utils/lucid-utils';
11
+ import {
12
+ createScriptAddress,
13
+ resolveUtxo,
14
+ UtxoOrOutRef,
15
+ } from '../../utils/lucid-utils';
17
16
  import { mkStakingValidatorFromSP } from './scripts';
18
17
  import { OCD_DECIMAL_UNIT } from '../../types/on-chain-decimal';
19
18
 
@@ -37,28 +36,20 @@ export function updateStakingLockedAmount(
37
36
  );
38
37
  }
39
38
 
40
- export function findStakingManagerByOutRef(
41
- stakingManagerRef: OutRef,
39
+ export async function findStakingManagerByOutRef(
40
+ stakingManager: UtxoOrOutRef,
42
41
  lucid: LucidEvolution,
43
42
  ): Promise<StakingManagerOutput> {
44
- return lucid
45
- .utxosByOutRef([stakingManagerRef])
46
- .then((utxos) =>
47
- utxos
48
- .map((utxo) => {
49
- if (!utxo.datum) return undefined;
50
- const datum = parseStakingManagerDatum(utxo.datum);
51
- return { utxo, datum };
52
- })
53
- .find((utxo) => utxo !== undefined),
54
- )
55
- .then((result) => {
56
- if (!result)
57
- throw new Error(
58
- 'Unable to locate Staking Manager by output reference.',
59
- );
60
- return result;
61
- });
43
+ const utxo = await resolveUtxo(
44
+ stakingManager,
45
+ lucid,
46
+ 'Unable to locate Staking Manager by output reference.',
47
+ );
48
+ if (!utxo.datum) {
49
+ throw new Error('Staking Manager UTxO has no datum.');
50
+ }
51
+ const datum = parseStakingManagerDatum(utxo.datum);
52
+ return { utxo, datum };
62
53
  }
63
54
 
64
55
  export function findStakingManager(
@@ -92,28 +83,20 @@ export function findStakingManager(
92
83
  });
93
84
  }
94
85
 
95
- export function findStakingPositionByOutRef(
96
- stakingPositionRef: OutRef,
86
+ export async function findStakingPositionByOutRef(
87
+ stakingPosition: UtxoOrOutRef,
97
88
  lucid: LucidEvolution,
98
89
  ): Promise<StakingPositionOutput> {
99
- return lucid
100
- .utxosByOutRef([stakingPositionRef])
101
- .then((utxos) =>
102
- utxos
103
- .map((utxo) => {
104
- if (!utxo.datum) return undefined;
105
- const datum = parseStakingPositionOrThrow(utxo.datum);
106
- return { utxo, datum };
107
- })
108
- .find((utxo) => utxo !== undefined),
109
- )
110
- .then((result) => {
111
- if (!result)
112
- throw new Error(
113
- 'Unable to locate Staking Position by output reference.',
114
- );
115
- return result;
116
- });
90
+ const utxo = await resolveUtxo(
91
+ stakingPosition,
92
+ lucid,
93
+ 'Unable to locate Staking Position by output reference.',
94
+ );
95
+ if (!utxo.datum) {
96
+ throw new Error('Staking Position UTxO has no datum.');
97
+ }
98
+ const datum = parseStakingPositionOrThrow(utxo.datum);
99
+ return { utxo, datum };
117
100
  }
118
101
 
119
102
  export const rewardSnapshotPrecision = OCD_DECIMAL_UNIT * OCD_DECIMAL_UNIT;
@@ -13,17 +13,20 @@ import {
13
13
  fromSystemParamsScriptRef,
14
14
  SystemParams,
15
15
  } from '../../types/system-params';
16
- import { addrDetails, getInlineDatumOrThrow } from '../../utils/lucid-utils';
16
+ import {
17
+ addrDetails,
18
+ getInlineDatumOrThrow,
19
+ resolveUtxo,
20
+ UtxoOrOutRef,
21
+ } from '../../utils/lucid-utils';
17
22
  import {
18
23
  distributeReward,
19
- findStakingManager,
20
- findStakingManagerByOutRef,
21
- findStakingPositionByOutRef,
22
24
  rewardSnapshotPrecision,
23
25
  updateStakingLockedAmount,
24
26
  } from './helpers';
25
27
  import {
26
28
  parseStakingManagerDatum,
29
+ parseStakingPositionOrThrow,
27
30
  serialiseStakingDatum,
28
31
  StakingManager,
29
32
  StakingPosition,
@@ -38,13 +41,18 @@ export async function openStakingPosition(
38
41
  amount: bigint,
39
42
  params: SystemParams,
40
43
  lucid: LucidEvolution,
41
- stakingManagerRef?: OutRef,
44
+ stakingManager: UtxoOrOutRef,
42
45
  ): Promise<TxBuilder> {
43
46
  const [pkh, _] = await addrDetails(lucid);
44
47
 
45
- const stakingManagerOut = stakingManagerRef
46
- ? await findStakingManagerByOutRef(stakingManagerRef, lucid)
47
- : await findStakingManager(params, lucid);
48
+ const stakingManagerUtxo = await resolveUtxo(
49
+ stakingManager,
50
+ lucid,
51
+ 'Expected a single staking manager UTXO',
52
+ );
53
+ const stakingManagerDatum = parseStakingManagerDatum(
54
+ getInlineDatumOrThrow(stakingManagerUtxo),
55
+ );
48
56
 
49
57
  const stakingRefScriptUtxo = matchSingle(
50
58
  await lucid.utxosByOutRef([
@@ -62,9 +70,9 @@ export async function openStakingPosition(
62
70
  );
63
71
 
64
72
  const newStakingManagerDatum: StakingManager = {
65
- totalStake: stakingManagerOut.datum.totalStake + amount,
73
+ totalStake: stakingManagerDatum.totalStake + amount,
66
74
  managerSnapshot: {
67
- snapshotAda: stakingManagerOut.datum.managerSnapshot.snapshotAda,
75
+ snapshotAda: stakingManagerDatum.managerSnapshot.snapshotAda,
68
76
  },
69
77
  };
70
78
 
@@ -72,7 +80,7 @@ export async function openStakingPosition(
72
80
  owner: fromHex(pkh.hash),
73
81
  lockedAmount: new Map([]),
74
82
  positionSnapshot: {
75
- snapshotAda: stakingManagerOut.datum.managerSnapshot.snapshotAda,
83
+ snapshotAda: stakingManagerDatum.managerSnapshot.snapshotAda,
76
84
  },
77
85
  };
78
86
 
@@ -85,19 +93,19 @@ export async function openStakingPosition(
85
93
  return lucid
86
94
  .newTx()
87
95
  .collectFrom(
88
- [stakingManagerOut.utxo],
96
+ [stakingManagerUtxo],
89
97
  serialiseStakingRedeemer({
90
98
  CreateStakingPosition: { creatorPkh: pkh.hash },
91
99
  }),
92
100
  )
93
101
  .readFrom([stakingRefScriptUtxo])
94
102
  .pay.ToContract(
95
- stakingManagerOut.utxo.address,
103
+ stakingManagerUtxo.address,
96
104
  {
97
105
  kind: 'inline',
98
106
  value: serialiseStakingDatum(newStakingManagerDatum),
99
107
  },
100
- stakingManagerOut.utxo.assets,
108
+ stakingManagerUtxo.assets,
101
109
  )
102
110
  .readFrom([stakingTokenPolicyRefScriptUtxo])
103
111
  .mintAssets(
@@ -107,7 +115,7 @@ export async function openStakingPosition(
107
115
  Data.void(),
108
116
  )
109
117
  .pay.ToContract(
110
- stakingManagerOut.utxo.address,
118
+ stakingManagerUtxo.address,
111
119
  {
112
120
  kind: 'inline',
113
121
  value: serialiseStakingDatum(stakingPositionDatum),
@@ -121,23 +129,33 @@ export async function openStakingPosition(
121
129
  }
122
130
 
123
131
  export async function adjustStakingPosition(
124
- stakingPositionRef: OutRef,
132
+ stakingPosition: UtxoOrOutRef,
125
133
  amount: bigint,
126
134
  params: SystemParams,
127
135
  lucid: LucidEvolution,
128
136
  currentSlot: number,
129
- stakingManagerRef?: OutRef,
137
+ stakingManager: UtxoOrOutRef,
130
138
  ): Promise<TxBuilder> {
131
139
  const network = lucid.config().network!;
132
140
  const currentTime = slotToUnixTime(network, currentSlot) - 120 * ONE_SECOND;
133
141
 
134
- const stakingPositionOut = await findStakingPositionByOutRef(
135
- stakingPositionRef,
142
+ const stakingPositionUtxo = await resolveUtxo(
143
+ stakingPosition,
136
144
  lucid,
145
+ 'Expected a single staking position UTXO',
146
+ );
147
+ const stakingPositionDatum = parseStakingPositionOrThrow(
148
+ getInlineDatumOrThrow(stakingPositionUtxo),
149
+ );
150
+
151
+ const stakingManagerUtxo = await resolveUtxo(
152
+ stakingManager,
153
+ lucid,
154
+ 'Expected a single staking manager UTXO',
155
+ );
156
+ const stakingManagerDatum = parseStakingManagerDatum(
157
+ getInlineDatumOrThrow(stakingManagerUtxo),
137
158
  );
138
- const stakingManagerOut = stakingManagerRef
139
- ? await findStakingManagerByOutRef(stakingManagerRef, lucid)
140
- : await findStakingManager(params, lucid);
141
159
 
142
160
  const stakingRefScriptUtxo = matchSingle(
143
161
  await lucid.utxosByOutRef([
@@ -150,16 +168,15 @@ export async function adjustStakingPosition(
150
168
  params.stakingParams.indyToken[0].unCurrencySymbol +
151
169
  fromText(params.stakingParams.indyToken[1].unTokenName);
152
170
 
153
- const existingIndyAmount = stakingPositionOut.utxo.assets[indyToken] ?? 0n;
154
- const currentSnapshotAda =
155
- stakingManagerOut.datum.managerSnapshot.snapshotAda;
156
- const oldSnapshotAda = stakingPositionOut.datum.positionSnapshot.snapshotAda;
171
+ const existingIndyAmount = stakingPositionUtxo.assets[indyToken] ?? 0n;
172
+ const currentSnapshotAda = stakingManagerDatum.managerSnapshot.snapshotAda;
173
+ const oldSnapshotAda = stakingPositionDatum.positionSnapshot.snapshotAda;
157
174
  const adaReward =
158
175
  ((currentSnapshotAda - oldSnapshotAda) * existingIndyAmount) /
159
176
  rewardSnapshotPrecision;
160
177
 
161
178
  const newLockedAmount = updateStakingLockedAmount(
162
- stakingPositionOut.datum.lockedAmount,
179
+ stakingPositionDatum.lockedAmount,
163
180
  BigInt(currentTime),
164
181
  );
165
182
 
@@ -168,38 +185,38 @@ export async function adjustStakingPosition(
168
185
  .validFrom(currentTime)
169
186
  .readFrom([stakingRefScriptUtxo])
170
187
  .collectFrom(
171
- [stakingPositionOut.utxo],
188
+ [stakingPositionUtxo],
172
189
  serialiseStakingRedeemer({
173
190
  AdjustStakedAmount: { adjustAmount: amount },
174
191
  }),
175
192
  )
176
193
  .collectFrom(
177
- [stakingManagerOut.utxo],
194
+ [stakingManagerUtxo],
178
195
  serialiseStakingRedeemer('UpdateTotalStake'),
179
196
  )
180
197
  .pay.ToContract(
181
- stakingManagerOut.utxo.address,
198
+ stakingManagerUtxo.address,
182
199
  {
183
200
  kind: 'inline',
184
201
  value: serialiseStakingDatum({
185
- ...stakingManagerOut.datum,
186
- totalStake: stakingManagerOut.datum.totalStake + amount,
202
+ ...stakingManagerDatum,
203
+ totalStake: stakingManagerDatum.totalStake + amount,
187
204
  }),
188
205
  },
189
- addAssets(stakingManagerOut.utxo.assets, mkLovelacesOf(-adaReward)),
206
+ addAssets(stakingManagerUtxo.assets, mkLovelacesOf(-adaReward)),
190
207
  )
191
208
  .pay.ToContract(
192
- stakingPositionOut.utxo.address,
209
+ stakingPositionUtxo.address,
193
210
  {
194
211
  kind: 'inline',
195
212
  value: serialiseStakingDatum({
196
- ...stakingPositionOut.datum,
213
+ ...stakingPositionDatum,
197
214
  lockedAmount: newLockedAmount,
198
- positionSnapshot: stakingManagerOut.datum.managerSnapshot,
215
+ positionSnapshot: stakingManagerDatum.managerSnapshot,
199
216
  }),
200
217
  },
201
218
  addAssets(
202
- stakingPositionOut.utxo.assets,
219
+ stakingPositionUtxo.assets,
203
220
  mkAssetsOf(
204
221
  {
205
222
  currencySymbol: params.stakingParams.indyToken[0].unCurrencySymbol,
@@ -209,26 +226,36 @@ export async function adjustStakingPosition(
209
226
  ),
210
227
  ),
211
228
  )
212
- .addSignerKey(toHex(stakingPositionOut.datum.owner));
229
+ .addSignerKey(toHex(stakingPositionDatum.owner));
213
230
  }
214
231
 
215
232
  export async function closeStakingPosition(
216
- stakingPositionRef: OutRef,
233
+ stakingPosition: UtxoOrOutRef,
217
234
  params: SystemParams,
218
235
  lucid: LucidEvolution,
219
236
  currentSlot: number,
220
- stakingManagerRef?: OutRef,
237
+ stakingManager: UtxoOrOutRef,
221
238
  ): Promise<TxBuilder> {
222
239
  const network = lucid.config().network!;
223
240
  const currentTime = slotToUnixTime(network, currentSlot) - ONE_SECOND;
224
241
 
225
- const stakingPositionOut = await findStakingPositionByOutRef(
226
- stakingPositionRef,
242
+ const stakingPositionUtxo = await resolveUtxo(
243
+ stakingPosition,
227
244
  lucid,
245
+ 'Expected a single staking position UTXO',
246
+ );
247
+ const stakingPositionDatum = parseStakingPositionOrThrow(
248
+ getInlineDatumOrThrow(stakingPositionUtxo),
249
+ );
250
+
251
+ const stakingManagerUtxo = await resolveUtxo(
252
+ stakingManager,
253
+ lucid,
254
+ 'Expected a single staking manager UTXO',
255
+ );
256
+ const stakingManagerDatum = parseStakingManagerDatum(
257
+ getInlineDatumOrThrow(stakingManagerUtxo),
228
258
  );
229
- const stakingManagerOut = stakingManagerRef
230
- ? await findStakingManagerByOutRef(stakingManagerRef, lucid)
231
- : await findStakingManager(params, lucid);
232
259
 
233
260
  const stakingRefScriptUtxo = matchSingle(
234
261
  await lucid.utxosByOutRef([
@@ -252,10 +279,9 @@ export async function closeStakingPosition(
252
279
  params.stakingParams.indyToken[0].unCurrencySymbol +
253
280
  fromText(params.stakingParams.indyToken[1].unTokenName);
254
281
 
255
- const existingIndyAmount = stakingPositionOut.utxo.assets[indyToken] ?? 0n;
256
- const currentSnapshotAda =
257
- stakingManagerOut.datum.managerSnapshot.snapshotAda;
258
- const oldSnapshotAda = stakingPositionOut.datum.positionSnapshot.snapshotAda;
282
+ const existingIndyAmount = stakingPositionUtxo.assets[indyToken] ?? 0n;
283
+ const currentSnapshotAda = stakingManagerDatum.managerSnapshot.snapshotAda;
284
+ const oldSnapshotAda = stakingPositionDatum.positionSnapshot.snapshotAda;
259
285
  const adaReward =
260
286
  ((currentSnapshotAda - oldSnapshotAda) * existingIndyAmount) /
261
287
  (1000000n * 1000000n);
@@ -264,21 +290,21 @@ export async function closeStakingPosition(
264
290
  .newTx()
265
291
  .validFrom(currentTime)
266
292
  .readFrom([stakingRefScriptUtxo, stakingTokenPolicyRefScriptUtxo])
267
- .collectFrom([stakingPositionOut.utxo], serialiseStakingRedeemer('Unstake'))
293
+ .collectFrom([stakingPositionUtxo], serialiseStakingRedeemer('Unstake'))
268
294
  .collectFrom(
269
- [stakingManagerOut.utxo],
295
+ [stakingManagerUtxo],
270
296
  serialiseStakingRedeemer('UpdateTotalStake'),
271
297
  )
272
298
  .pay.ToContract(
273
- stakingManagerOut.utxo.address,
299
+ stakingManagerUtxo.address,
274
300
  {
275
301
  kind: 'inline',
276
302
  value: serialiseStakingDatum({
277
- ...stakingManagerOut.datum,
278
- totalStake: stakingManagerOut.datum.totalStake - existingIndyAmount,
303
+ ...stakingManagerDatum,
304
+ totalStake: stakingManagerDatum.totalStake - existingIndyAmount,
279
305
  }),
280
306
  },
281
- addAssets(stakingManagerOut.utxo.assets, mkLovelacesOf(-adaReward)),
307
+ addAssets(stakingManagerUtxo.assets, mkLovelacesOf(-adaReward)),
282
308
  )
283
309
  .mintAssets(
284
310
  {
@@ -286,21 +312,26 @@ export async function closeStakingPosition(
286
312
  },
287
313
  Data.void(),
288
314
  )
289
- .addSignerKey(toHex(stakingPositionOut.datum.owner));
315
+ .addSignerKey(toHex(stakingPositionDatum.owner));
290
316
  }
291
317
 
292
318
  const MIN_UTXO_AMOUNT = 2_000_000n;
293
319
 
294
320
  export async function distributeAda(
295
- stakingManagerRef: OutRef,
321
+ stakingManager: UtxoOrOutRef,
296
322
  collectorRefs: OutRef[],
297
323
  params: SystemParams,
298
324
  lucid: LucidEvolution,
299
325
  ): Promise<TxBuilder> {
300
- const [stakingManagerUtxo] = await lucid.utxosByOutRef([stakingManagerRef]);
326
+ const stakingManagerUtxo = await resolveUtxo(
327
+ stakingManager,
328
+ lucid,
329
+ 'Expected a single staking manager UTXO',
330
+ );
301
331
  const stakingManagerDatum = parseStakingManagerDatum(
302
332
  getInlineDatumOrThrow(stakingManagerUtxo),
303
333
  );
334
+
304
335
  const collectorUtxos = (await lucid.utxosByOutRef(collectorRefs))
305
336
  .filter((utxo) => utxo.datum && utxo.datum === Data.void())
306
337
  .filter((utxo) => utxo.assets.lovelace > MIN_UTXO_AMOUNT);
@@ -2,7 +2,6 @@ import {
2
2
  addAssets,
3
3
  Data,
4
4
  LucidEvolution,
5
- OutRef,
6
5
  TxBuilder,
7
6
  } from '@lucid-evolution/lucid';
8
7
  import {
@@ -13,20 +12,25 @@ import {
13
12
  import { matchSingle } from '../../utils/utils';
14
13
  import { mkLovelacesOf } from '../../utils/value-helpers';
15
14
  import { serialiseTreasuryRedeemer } from './types';
16
- import { createScriptAddress } from '../../utils/lucid-utils';
15
+ import {
16
+ createScriptAddress,
17
+ resolveUtxo,
18
+ UtxoOrOutRef,
19
+ } from '../../utils/lucid-utils';
17
20
 
18
21
  export async function treasuryFeeTx(
19
22
  fee: bigint,
20
23
  lucid: LucidEvolution,
21
24
  sysParams: SystemParams,
22
25
  tx: TxBuilder,
23
- treasuryOref: OutRef,
26
+ treasury: UtxoOrOutRef,
24
27
  ): Promise<void> {
25
28
  if (fee <= 0n) return;
26
29
 
27
- const treasuryUtxo = matchSingle(
28
- await lucid.utxosByOutRef([treasuryOref]),
29
- (_) => new Error('Expected a single treasury UTXO'),
30
+ const treasuryUtxo = await resolveUtxo(
31
+ treasury,
32
+ lucid,
33
+ 'Expected a single treasury UTXO',
30
34
  );
31
35
 
32
36
  const treasuryRefScriptUtxo = matchSingle(
@@ -14,7 +14,7 @@ type VestingSchedule = {
14
14
  schedule: Schedule[];
15
15
  };
16
16
 
17
- const teamVestingSchedule: Schedule[] = [
17
+ export const teamVestingSchedule: Schedule[] = [
18
18
  {
19
19
  vestedAtTime: 1669067100000n,
20
20
  unlockAmt: 328_125n * OCD_DECIMAL_UNIT,
@@ -113,93 +113,43 @@ const teamVestingSchedule: Schedule[] = [
113
113
  },
114
114
  ];
115
115
 
116
- const spDistributionSchedule: VestingSchedule = {
117
- maxUnlockable: 14_000_000n * OCD_DECIMAL_UNIT,
116
+ export const spDistributionSchedule: VestingSchedule = {
117
+ maxUnlockable: 2_013_760n * OCD_DECIMAL_UNIT,
118
118
  schedule: [
119
119
  {
120
120
  vestedAtTime: 1669931100000n,
121
121
  unlockAmt: 28_768n * OCD_DECIMAL_UNIT,
122
122
  },
123
- {
124
- vestedAtTime: 1701467100000n,
125
- unlockAmt: 33_562n * OCD_DECIMAL_UNIT,
126
- },
127
- {
128
- vestedAtTime: 1727387100000n,
129
- unlockAmt: 33_561n * OCD_DECIMAL_UNIT,
130
- },
131
- {
132
- vestedAtTime: 1733003100000n,
133
- unlockAmt: 38_356n * OCD_DECIMAL_UNIT,
134
- },
135
- {
136
- vestedAtTime: 1764539100000n,
137
- unlockAmt: 43_150n * OCD_DECIMAL_UNIT,
138
- },
139
- {
140
- vestedAtTime: 1796075100000n,
141
- unlockAmt: 47_945n * OCD_DECIMAL_UNIT,
142
- },
143
123
  ],
144
124
  };
145
125
 
146
- const liqDistributionSchedule: VestingSchedule = {
147
- maxUnlockable: 5_250_000n * OCD_DECIMAL_UNIT,
126
+ export const liqDistributionSchedule: VestingSchedule = {
127
+ maxUnlockable: 316_470n * OCD_DECIMAL_UNIT,
148
128
  schedule: [
149
129
  {
150
130
  vestedAtTime: 1671659100000n,
151
131
  unlockAmt: 4_795n * OCD_DECIMAL_UNIT,
152
- },
153
- {
154
- vestedAtTime: 1703195100000n,
155
- unlockAmt: 9_590n * OCD_DECIMAL_UNIT,
156
- },
157
- {
158
- vestedAtTime: 1728683100000n,
159
- unlockAmt: 9_589n * OCD_DECIMAL_UNIT,
160
- },
161
- {
162
- vestedAtTime: 1734731100000n,
163
- unlockAmt: 14_383n * OCD_DECIMAL_UNIT,
164
- },
165
- {
166
- vestedAtTime: 1766267100000n,
167
- unlockAmt: 19_178n * OCD_DECIMAL_UNIT,
168
- },
132
+ }
133
+ ],
134
+ };
135
+
136
+ export const spLpDistributionSchedule: VestingSchedule = {
137
+ maxUnlockable: 17_016_441n * OCD_DECIMAL_UNIT,
138
+ schedule: [
169
139
  {
170
- vestedAtTime: 1797803100000n,
171
- unlockAmt: 23_972n * OCD_DECIMAL_UNIT,
172
- },
140
+ vestedAtTime: 1700171100000n,
141
+ unlockAmt: 33_563n * OCD_DECIMAL_UNIT,
142
+ }
173
143
  ],
174
144
  };
175
145
 
176
- const govDistributionSchedule: VestingSchedule = {
177
- maxUnlockable: 1_750_000n * OCD_DECIMAL_UNIT,
146
+ export const govDistributionSchedule: VestingSchedule = {
147
+ maxUnlockable: 1_381_248n * OCD_DECIMAL_UNIT,
178
148
  schedule: [
179
149
  {
180
150
  vestedAtTime: 1670363100000n,
181
151
  unlockAmt: 2_398n * OCD_DECIMAL_UNIT,
182
152
  },
183
- {
184
- vestedAtTime: 1701899100000n,
185
- unlockAmt: 3_596n * OCD_DECIMAL_UNIT,
186
- },
187
- {
188
- vestedAtTime: 1733435100000n,
189
- unlockAmt: 4_795n * OCD_DECIMAL_UNIT,
190
- },
191
- {
192
- vestedAtTime: 1752443100000n,
193
- unlockAmt: 4_794n * OCD_DECIMAL_UNIT,
194
- },
195
- {
196
- vestedAtTime: 1764971100000n,
197
- unlockAmt: 5_993n * OCD_DECIMAL_UNIT,
198
- },
199
- {
200
- vestedAtTime: 1796507100000n,
201
- unlockAmt: 7_191n * OCD_DECIMAL_UNIT,
202
- },
203
153
  ],
204
154
  };
205
155
 
@@ -213,7 +163,7 @@ export function calculateTotalVestedTeam(currentTime: bigint): bigint {
213
163
  })(teamVestingSchedule);
214
164
  }
215
165
 
216
- function calculateVestedPerEpoch(
166
+ export function calculateVestedPerEpoch(
217
167
  schedule: VestingSchedule,
218
168
  currentTime: bigint,
219
169
  ): bigint {
@@ -262,6 +212,7 @@ export function calculateTotalVestedRewards(currentTime: bigint): bigint {
262
212
  return (
263
213
  calculateVestedPerEpoch(spDistributionSchedule, currentTime) +
264
214
  calculateVestedPerEpoch(govDistributionSchedule, currentTime) +
265
- calculateVestedPerEpoch(liqDistributionSchedule, currentTime)
215
+ calculateVestedPerEpoch(liqDistributionSchedule, currentTime) +
216
+ calculateVestedPerEpoch(spLpDistributionSchedule, currentTime)
266
217
  );
267
218
  }
@@ -15,6 +15,39 @@ import {
15
15
  UTxO,
16
16
  } from '@lucid-evolution/lucid';
17
17
  import { ScriptReference } from '../types/system-params';
18
+ import { matchSingle } from './utils';
19
+
20
+ /**
21
+ * Union type accepting either a full UTxO or just an OutRef.
22
+ * When a full UTxO is provided, no network fetch is needed.
23
+ * When only an OutRef is provided, the UTxO will be fetched via utxosByOutRef.
24
+ */
25
+ export type UtxoOrOutRef = UTxO | OutRef;
26
+
27
+ /**
28
+ * Resolves a UTxOOrOutRef to a full UTxO.
29
+ * If the input is already a UTxO (has 'address' property), returns it directly.
30
+ * If the input is an OutRef, fetches the UTxO from the network.
31
+ *
32
+ * @param input - Either a full UTxO or an OutRef
33
+ * @param lucid - The LucidEvolution instance for network queries
34
+ * @param errorMsg - Custom error message if the UTxO cannot be found
35
+ * @returns The resolved UTxO
36
+ */
37
+ export async function resolveUtxo(
38
+ input: UtxoOrOutRef,
39
+ lucid: LucidEvolution,
40
+ errorMsg: string = 'Expected a single UTXO',
41
+ ): Promise<UTxO> {
42
+ // UTxO has 'address' property, OutRef only has 'txHash' and 'outputIndex'
43
+ if ('address' in input) {
44
+ return input;
45
+ }
46
+ return matchSingle(
47
+ await lucid.utxosByOutRef([input]),
48
+ (_) => new Error(errorMsg),
49
+ );
50
+ }
18
51
 
19
52
  /**
20
53
  * Returns the inline datum.