@indigo-labs/indigo-sdk
Version:
Indigo SDK for interacting with Indigo endpoints via lucid-evolution
261 lines (235 loc) • 7.38 kB
text/typescript
import {
addAssets,
Address,
Assets,
Data,
LucidEvolution,
OutputDatum,
OutRef,
toHex,
TxBuilder,
UTxO,
} from '@lucid-evolution/lucid';
import {
fromSystemParamsScriptRef,
SystemParams,
matchSingle,
parseInterestCollectionDatum,
serialiseInterestCollectionDatum,
serialiseInterestCollectionRedeemer,
createScriptAddress,
fromSystemParamsAsset,
} from '../../src';
import {
assetClassValueOf,
getInlineDatumOrThrow,
} from '@3rd-eye-labs/cardano-offchain-common';
import { Multisig } from '../../src/types/multisig';
type CollectSuccess = {
kind: 'CollectSuccess';
};
type CollectWithoutCDP = {
kind: 'CollectWithoutCDP';
};
type CollectFromMultipleInterestCollectors = {
kind: 'CollectFromMultipleInterestCollectors';
utxo: UTxO;
};
type CollectFromInterestAdmin = {
kind: 'CollectFromInterestAdmin';
};
type CollectCustomValue = {
kind: 'CollectCustomValue';
value: Assets;
};
export type CollectInterestVariation =
| CollectSuccess
| CollectWithoutCDP
| CollectFromInterestAdmin
| CollectFromMultipleInterestCollectors
| CollectCustomValue;
export async function testCollectInterest(
value: Assets,
lucid: LucidEvolution,
params: SystemParams,
tx: TxBuilder,
interestCollectorOutRef: OutRef,
variation: CollectInterestVariation,
): Promise<TxBuilder> {
const interestCollectorUtxo: UTxO = matchSingle(
await lucid.utxosByOutRef([interestCollectorOutRef]),
(_) => new Error('Expected a single interest collector UTXO'),
);
// Confirm that the interest collector UTXO is NOT of InterestCollectorDatum type
if (
variation.kind !== 'CollectFromInterestAdmin' &&
assetClassValueOf(
interestCollectorUtxo.assets,
fromSystemParamsAsset(params.interestCollectionParams.multisigUtxoNft),
)
) {
throw new Error(
'Interest collector UTXO is of InterestCollectorDatum type',
);
}
// Find the script reference UTXO for the interest collection validator
const interestCollectionRefScriptUtxo = matchSingle(
await lucid.utxosByOutRef([
fromSystemParamsScriptRef(
params.scriptReferences.interestCollectionValidatorRef,
),
]),
(_) => new Error('Expected a single interest collection Ref Script UTXO'),
);
// Collect the interest from the interest collector UTXO and then pay back with more assets.
tx.readFrom([interestCollectionRefScriptUtxo])
.collectFrom(
[interestCollectorUtxo],
serialiseInterestCollectionRedeemer('CollectInterest'),
)
.pay.ToContract(
createScriptAddress(
lucid.config().network!,
params.validatorHashes.interestCollectionHash,
),
{ kind: 'inline', value: Data.void() },
variation.kind === 'CollectCustomValue'
? variation.value
: addAssets(interestCollectorUtxo.assets, value),
);
if (variation.kind === 'CollectFromMultipleInterestCollectors') {
tx.collectFrom(
[variation.utxo],
serialiseInterestCollectionRedeemer('CollectInterest'),
);
}
return tx;
}
type DistributeInterestNoAdmin = {
kind: 'DistributeInterestNoAdmin';
};
type DistributeInterestWithDatum = {
kind: 'DistributeInterestWithDatum';
datum: OutputDatum;
};
export type DistributeInterestVariation =
| DistributeInterestNoAdmin
| DistributeInterestWithDatum;
export async function testDistributeInterest(
interestCollectorOutRef: OutRef,
interestAdminOutRef: OutRef,
outputAddress: Address,
outputDatum: OutputDatum | undefined,
params: SystemParams,
lucid: LucidEvolution,
variation: DistributeInterestVariation,
): Promise<TxBuilder> {
const interestCollectorUtxo: UTxO = matchSingle(
await lucid.utxosByOutRef([interestCollectorOutRef]),
(_) => new Error('Expected a single interest collector UTXO'),
);
const interestAdminUtxo: UTxO = matchSingle(
(await lucid.utxosByOutRef([interestAdminOutRef])).filter((utxo) =>
assetClassValueOf(
utxo.assets,
fromSystemParamsAsset(params.interestCollectionParams.multisigUtxoNft),
),
),
(_) => new Error('Expected a single interest admin UTXO'),
);
const interestAdminDatum = parseInterestCollectionDatum(
getInlineDatumOrThrow(interestAdminUtxo),
);
// Find the script reference UTXO for the interest collection validator
const interestCollectionRefScriptUtxo = matchSingle(
await lucid.utxosByOutRef([
fromSystemParamsScriptRef(
params.scriptReferences.interestCollectionValidatorRef,
),
]),
(_) => new Error('Expected a single interest collection Ref Script UTXO'),
);
const tx = lucid
.newTx()
.readFrom([interestCollectionRefScriptUtxo, interestAdminUtxo])
.collectFrom(
[interestCollectorUtxo],
serialiseInterestCollectionRedeemer('Distribute'),
)
.pay.ToContract(outputAddress, outputDatum, interestCollectorUtxo.assets);
if (variation.kind !== 'DistributeInterestNoAdmin') {
// TODO: Handle tx contruction for Multisig
if ('Signature' in interestAdminDatum.admin_permissions) {
tx.addSignerKey(
toHex(interestAdminDatum.admin_permissions.Signature.keyHash),
);
} else {
// TODO: Handle other admin permissions types
throw new Error('Unsupported admin permissions type');
}
}
return tx;
}
export async function updatePermissions(
interestAdminOutRef: OutRef,
newAdminPermissions: Multisig,
params: SystemParams,
lucid: LucidEvolution,
): Promise<TxBuilder> {
const interestAdminUtxo: UTxO = matchSingle(
(await lucid.utxosByOutRef([interestAdminOutRef])).filter((utxo) =>
assetClassValueOf(
utxo.assets,
fromSystemParamsAsset(params.interestCollectionParams.multisigUtxoNft),
),
),
(_) => new Error('Expected a single interest admin UTXO'),
);
const interestAdminDatum = parseInterestCollectionDatum(
getInlineDatumOrThrow(interestAdminUtxo),
);
// Find the script reference UTXO for the interest collection validator
const interestCollectionRefScriptUtxo = matchSingle(
await lucid.utxosByOutRef([
fromSystemParamsScriptRef(
params.scriptReferences.interestCollectionValidatorRef,
),
]),
(_) => new Error('Expected a single interest collection Ref Script UTXO'),
);
const tx = lucid
.newTx()
.readFrom([interestCollectionRefScriptUtxo])
.collectFrom(
[interestAdminUtxo],
serialiseInterestCollectionRedeemer('UpdatePermissions'),
)
.pay.ToContract(
createScriptAddress(
lucid.config().network!,
params.validatorHashes.interestCollectionHash,
),
{
kind: 'inline',
value: serialiseInterestCollectionDatum({
admin_permissions: newAdminPermissions,
}),
},
interestAdminUtxo.assets,
);
if ('Signature' in interestAdminDatum.admin_permissions) {
tx.addSignerKey(
toHex(interestAdminDatum.admin_permissions.Signature.keyHash),
);
} else {
// TODO: Handle other admin permissions types
throw new Error('Unsupported admin permissions type');
}
if ('Signature' in newAdminPermissions) {
tx.addSignerKey(toHex(newAdminPermissions.Signature.keyHash));
} else {
// TODO: Handle other admin permissions types
throw new Error('Unsupported admin permissions type');
}
return tx;
}