Skip to content

Commit

Permalink
feat(cancelVesting): write code
Browse files Browse the repository at this point in the history
correctness is checked via tests that test for same think

#78
  • Loading branch information
aleeusgr committed Jun 1, 2023
1 parent 277b314 commit 266db4a
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 87 deletions.
139 changes: 53 additions & 86 deletions src/cancelVesting.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,91 +20,58 @@ import {
export const cancelVesting = async (
network: NetworkEmulator,
alice : WalletEmulator,
bob : WalletEmulator,
validatorHash: ValidatorHash,
adaQty : number,
duration : number
program: Program
) => {

const validatorAddress = Address.fromValidatorHash(validatorHash);
const benAddr = bob.address;
const emulatorDate = 1677108984000; // from src/preprod.json
const deadline = new Date(emulatorDate + duration);
const benPkh = bob.pubKeyHash;
const ownerPkh = alice.pubKeyHash;

const lovelaceAmt = Number(adaQty) * 1000000;
const adaAmountVal = new Value(BigInt(lovelaceAmt));

const datum = new ListData([new ByteArrayData(ownerPkh.bytes),
new ByteArrayData(benPkh.bytes),
new IntData(BigInt(deadline.getTime()))]);
const inlineDatum = Datum.inline(datum);

const inputUtxos = await alice.utxos;

const tx = new Tx();

tx.addInputs([inputUtxos[0]]);

const mintScript =`minting nft
enum Redeemer {
Init
}
const TX_ID: ByteArray = #` + inputUtxos[0].txId.hex + `
const txId: TxId = TxId::new(TX_ID)
const outputId: TxOutputId = TxOutputId::new(txId, ` + inputUtxos[0].utxoIdx + `)
func main(_, ctx: ScriptContext) -> Bool {
tx: Tx = ctx.tx;
mph: MintingPolicyHash = ctx.get_current_minting_policy_hash();
assetclass: AssetClass = AssetClass::new(
mph,
"Vesting Key".encode_utf8()
);
value_minted: Value = tx.minted;
// Validator logic starts
(value_minted == Value::new(assetclass, 1)).trace("NFT1: ") &&
tx.inputs.any((input: TxInput) -> Bool {
(input.output_id == outputId).trace("NFT2: ")
}
)
}`

const optimize = false; //maybe add to test context?
const mintProgram = Program.new(mintScript).compile(optimize);

tx.attachScript(mintProgram);

// Construct the NFT that we will want to send as an output
const nftTokenName = ByteArrayData.fromString("Vesting Key").toHex();
const tokens: [number[], bigint][] = [[hexToBytes(nftTokenName), BigInt(1)]];

// Create an empty Redeemer because we must always send a Redeemer with
// a plutus script transaction even if we don't actually use it.
const mintRedeemer = new ConstrData(0, []);

// Indicate the minting we want to include as part of this transaction
tx.mintTokens(
mintProgram.mintingPolicyHash,
tokens,
mintRedeemer
)

const lockedVal = new Value(adaAmountVal.lovelace, new Assets([[mintProgram.mintingPolicyHash, tokens]]));

// Add the destination address and the amount of Ada to lock including a datum
tx.addOutput(new TxOutput(validatorAddress, lockedVal, inlineDatum));

// beforeAll?
const networkParamsFile = await fs.readFile('./src/preprod.json', 'utf8');
const networkParams = new NetworkParams(JSON.parse(networkParamsFile.toString()));

await tx.finalize(networkParams, alice.address);
const txId = await network.submitTx(tx);
network.tick(BigInt(10));

const optimize = false;
const compiledProgram = program.compile(optimize);
const validatorHash = compiledProgram.validatorHash;
const validatorAddress = Address.fromValidatorHash(validatorHash);
const networkParamsFile = await fs.readFile('./src/preprod.json', 'utf8');
const networkParams = new NetworkParams(JSON.parse(networkParamsFile.toString()));

// somehow need to add this to context, defined in src/lockAda
const keyMPH = '702cd6229f16532ca9735f65037092d099b0ff78a741c82db0847bbf'

// with all above, a tx can be built:
const tx = new Tx();

const ownerAddress = alice.address;
const ownerUtxos = await alice.utxos;

const valRedeemer = new ConstrData(0, []);

// compare to https://github.com/lley154/helios-examples/blob/704cf0a92cfe252b63ffb9fd36c92ffafc1d91f6/vesting/pages/index.tsx#L283
const valUtxo = (await network.getUtxos(validatorAddress))[0]

tx.addInput(valUtxo, valRedeemer);

// Send the value of the of the valUTXO back to the owner
tx.addOutput(new TxOutput(ownerAddress, valUtxo.value));

// Specify when this transaction is valid from. This is needed so
// time is included in the transaction which will be use by the validator
// script. in NetworkEmulator, init slot is 0;
const emulatorDate = Number(await networkParams.slotToTime(0n));

const earlierTime = new Date(emulatorDate);
const laterTime = new Date(emulatorDate + 3 * 60 * 60 * 1000);

tx.validFrom(earlierTime);
tx.validTo(laterTime);

// Add the recipiants pkh
tx.addSigner(ownerAddress.pubKeyHash);

// Add the validator script to the transaction
tx.attachScript(compiledProgram);

const colatUtxo = ownerUtxos[0];
const spareUtxo = ownerUtxos[1];
tx.addCollateral(colatUtxo);

await tx.finalize(networkParams, ownerAddress, [spareUtxo]);

const txId = await network.submitTx(tx);
network.tick(BigInt(10));
}
2 changes: 1 addition & 1 deletion tests/helios-vesting-cancel.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,7 @@ describe("a vesting contract: Cancel transaction", async () => {
expect((await alice.utxos)[0].value.dump().lovelace).toBe('50000000');
expect((await alice.utxos)[1].value.dump().lovelace).toBe('9755287');

await cancelVesting();
await cancelVesting(network!, alice!, program );

const oracle = await alice.utxos;

Expand Down

0 comments on commit 266db4a

Please sign in to comment.