diff --git a/src/nft.hl b/src/nft.hl index df42df1..aa0038a 100644 --- a/src/nft.hl +++ b/src/nft.hl @@ -8,6 +8,8 @@ const TX_ID: ByteArray = #7c873bf399ed9255e38f9d897e835f017377320794a3ecd4f1d045 const txId: TxId = TxId::new(TX_ID) const TX_IDX: Int = 0 const outputId: TxOutputId = TxOutputId::new(txId, TX_IDX) +const TN: String = "" +const AMT: Int = 1 func main(_, ctx: ScriptContext) -> Bool { tx: Tx = ctx.tx; @@ -15,13 +17,13 @@ func main(_, ctx: ScriptContext) -> Bool { tt_assetclass: AssetClass = AssetClass::new( mph, - "Thread Token".encode_utf8() + TN.encode_utf8() ); value_minted: Value = tx.minted; - (value_minted == Value::new(tt_assetclass, 1)).trace("TT1: ") && + (value_minted == Value::new(tt_assetclass, AMT)).trace("TT1: ") && tx.inputs.any((input: TxInput) -> Bool { (input.output_id == outputId).trace("TT2: ") } ) -} \ No newline at end of file +} diff --git a/tests/template.test.ts b/tests/template.test.ts index 958fba3..e802900 100644 --- a/tests/template.test.ts +++ b/tests/template.test.ts @@ -48,7 +48,7 @@ describe("a template", async () => { }) - it ("docs the tx ingridients", async ({network, alice, validatorHash}) => { + it ("documents the initial state of the Emulator", async ({network, alice, validatorHash}) => { // https://www.hyperion-bt.org/helios-book/api/reference/address.html?highlight=Address#address const aliceUtxos = await network.getUtxos(alice.address); // todo diff --git a/tests/time-props-vesting.test.ts b/tests/time-props-vesting.test.ts new file mode 100644 index 0000000..52db9e4 --- /dev/null +++ b/tests/time-props-vesting.test.ts @@ -0,0 +1,123 @@ +import { describe, expect, it, expectTypeOf, beforeEach, vi } from 'vitest' +import { promises as fs } from 'fs'; +import { + Address, + Assets, + ByteArrayData, + ConstrData, + Datum, + hexToBytes, + IntData, + ListData, + NetworkEmulator, + NetworkParams, + Program, + Tx, + TxOutput, + Value, +} from "@hyperionbt/helios"; +import {lockAda} from './src/vesting-lock.ts'; +import {cancelVesting} from './src/vesting-cancel.ts'; + +describe("what happens when we add wait interval between lock and cancel?", async () => { + + // https://vitest.dev/guide/test-context.html + beforeEach(async (context) => { + let optimize = false; + + // compile script + const script = await fs.readFile('./src/vesting.hl', 'utf8'); + const program = Program.new(script); + const compiledProgram = program.compile(optimize); + const validatorHash = compiledProgram.validatorHash; + const validatorAddress = Address.fromValidatorHash(validatorHash); + + context.program = program; + // + context.validatorHash = validatorHash; + context.validatorAddress = Address.fromValidatorHash(validatorHash); + + // instantiate the Emulator + const minAda = BigInt(2000000); // minimum lovelace needed to send an NFT + const network = new NetworkEmulator(); + + const alice = network.createWallet(BigInt(20000000)); + network.createUtxo(alice, BigInt(50000000)); + const bob = network.createWallet(BigInt(10000000)); + network.tick(BigInt(10)); + + context.alice = alice; + context.bob = bob; + context.network = network; + + const networkParamsFile = await fs.readFile('./src/preprod.json', 'utf8'); + const networkParams = new NetworkParams(JSON.parse(networkParamsFile.toString())); + + context.networkParams = networkParams; + }) + + it ("documents properties", async ({network, alice, validatorHash}) => { + // https://www.hyperion-bt.org/helios-book/api/reference/address.html?highlight=Address#address + expect(alice.address.toHex().length).toBe(58) + // UTxOs + expect((await alice.utxos)[0].value.dump().lovelace).toBe('20000000'); + expect((await alice.utxos)[1].value.dump().lovelace).toBe('50000000'); + + // https://www.hyperion-bt.org/helios-book/lang/builtins/validatorhash.html?highlight=valida#validatorhash + expect(validatorHash.hex).toBe('e7015c6a1424d748f8241fe3a43b3a382b35dc9ca67320e3ee863dc8') + + + }) + + it ("succeeds cancellation", async ({network, alice, bob, program}) => { + const optimize = false; // need to add it to the context + const compiledScript = program.compile(optimize); + const validatorHash = compiledScript.validatorHash; + const validatorAddress = Address.fromValidatorHash(validatorHash); + + const adaQty = 10; + const duration = 1000000; + await lockAda(network!, alice!, bob!, program, adaQty, duration); + expect((await alice.utxos)[0].value.dump().lovelace).toBe('50000000'); + expect((await alice.utxos)[1].value.dump().lovelace).toBe('9755287'); + + // https://www.hyperion-bt.org/helios-book/api/reference/fuzzytest.html?highlight=fuzz#fuzzytest + network.tick(BigInt(10780)); + + await cancelVesting(network!, alice!, program ); + + const oracle = await alice.utxos; + + // think about which is which. + expect(oracle[2].value.dump().lovelace).toBe('9546007'); + expect(oracle[1].value.dump().lovelace).toBe('10000000');// + expect(oracle[0].value.dump().lovelace).toBe('50000000');// collateral? + }) + it.fails ("Error: tx invalid (not finalized or slot out of range) ", async ({network, alice, bob, program, networkParams}) => { + const optimize = false; // need to add it to the context + const compiledScript = program.compile(optimize); + const validatorHash = compiledScript.validatorHash; + const validatorAddress = Address.fromValidatorHash(validatorHash); + + const adaQty = 10; + const duration = 1000000; + await lockAda(network!, alice!, bob!, program, adaQty, duration); + expect((await alice.utxos)[0].value.dump().lovelace).toBe('50000000'); + expect((await alice.utxos)[1].value.dump().lovelace).toBe('9755287'); + + // https://www.hyperion-bt.org/helios-book/api/reference/fuzzytest.html?highlight=fuzz#fuzzytest + network.tick(BigInt(10781)); + + await cancelVesting(network!, alice!, program ); + + const oracle = await alice.utxos; + + // think about which is which. + expect(oracle[2].value.dump().lovelace).toBe('9546007'); + expect(oracle[1].value.dump().lovelace).toBe('10000000');// + expect(oracle[0].value.dump().lovelace).toBe('50000000');// collateral? + }) + + it ("describes the transaction", async ({network, alice, bob, program}) => { + }) +}) diff --git a/tests/unit/context-nesting.test.ts b/tests/unit/context-nesting.test.ts index 8e21ffb..9624af9 100644 --- a/tests/unit/context-nesting.test.ts +++ b/tests/unit/context-nesting.test.ts @@ -6,7 +6,7 @@ describe('suite name', (context) => { describe('suite name', (context) => { beforeEach((context) => { - context.foo = 'bar'; + context.foo = 'bar'; }) it('foo', ({foo}) => { expect(foo).toBe('bar') diff --git a/tests/unit/fuzzy.test.ts b/tests/unit/fuzzy.test.ts new file mode 100644 index 0000000..f957d67 --- /dev/null +++ b/tests/unit/fuzzy.test.ts @@ -0,0 +1,29 @@ +import { describe, expect, it, expectTypeOf, beforeEach, vi } from 'vitest' +import { promises as fs } from 'fs'; +import { + Assets, + FuzzyTest, + MintingPolicyHash, + NetworkEmulator, + Program +} from "@hyperionbt/helios"; + + +import {lockAda} from './src/lockAda.ts'; + +describe("create a network with two wallets of which one has an nft", async () => { + + // https://vitest.dev/guide/test-context.html + beforeEach(async (context) => { + + }) + + it.fails ("checks for Fuzzy", async ({network, alice, bob, mph}) => { + // https://www.hyperion-bt.org/helios-book/api/reference/fuzzytest.html?highlight=fuzzy#fuzzytest + const fuzzy = new FuzzyTest(0,100,false) + expect(await fuzzy.int(0)).toBe(); + + + }) + +}) diff --git a/tests/unit/mint-nft.test.ts b/tests/unit/mint-nft.test.ts new file mode 100644 index 0000000..e7c2b81 --- /dev/null +++ b/tests/unit/mint-nft.test.ts @@ -0,0 +1,82 @@ +import { describe, expect, it, expectTypeOf, beforeEach, vi } from 'vitest' +import { promises as fs } from 'fs'; +import { + hexToBytes, + Assets, + ByteArrayData, + ConstrData, + MintingPolicyHash, + NetworkEmulator, + NetworkParams, + Program, + Tx, + TxOutput, + Value +} from "@hyperionbt/helios"; + + +import {lockAda} from './src/lockAda.ts'; + +describe("create a network with two wallets of which one has an nft", async () => { + + // https://vitest.dev/guide/test-context.html + beforeEach(async (context) => { + + const network = new NetworkEmulator(); + const networkParamsFile = await fs.readFile('./src/preprod.json', 'utf8'); + const networkParams = new NetworkParams(JSON.parse(networkParamsFile.toString())); + const minAda = BigInt(2000000); // minimum lovelace needed to send an NFT + + const alice = network.createWallet(BigInt(20000000)); + network.createUtxo(alice, BigInt(5000000)); + + network.tick(10n) + + const amt = 5n; + const name = 'abc'; + const utxos = await alice.utxos; + const script = await fs.readFile('./src/nft.hl', 'utf8'); + const nftProgram = Program.new(script); + //const nftProgram = new Program(); + nftProgram.parameters = {["TX_ID"] : utxos[0].txId.hex}; + nftProgram.parameters = {["TX_IDX"] : utxos[0].utxoIdx}; + nftProgram.parameters = {["TN"] : name}; + nftProgram.parameters = {["AMT"] : amt}; + const nftCompiledProgram = nftProgram.compile(false); + const nftTokenName = ByteArrayData.fromString(name).toHex(); + const tokens: [number[], bigint][] = [[hexToBytes(nftTokenName), amt]]; + + const mintRedeemer = new ConstrData(0, []); + const tx = new Tx() + .addInputs(utxos) + .attachScript(nftCompiledProgram) + .mintTokens( + nftCompiledProgram.mintingPolicyHash, + tokens, + mintRedeemer) + .addOutput(new TxOutput( + (await alice.address), + new Value(minAda, new Assets([[nftCompiledProgram.mintingPolicyHash, tokens]])) + )); + + + await tx.finalize(networkParams, alice.address); + const txId = await network.submitTx(tx); + network.tick(10n); + + context.alice = alice; + context.network = network; + context.mph = nftCompiledProgram.mintingPolicyHash.hex; + context.amt = amt; + + }) + + it ("asserts properties", async ({network, alice, amt, mph }) => { + // https://www.hyperion-bt.org/helios-book/api/reference/address.html?highlight=Address#address + expect(alice.address.toHex().length).toBe(58) + expect((await alice.utxos)[0].value.dump().lovelace).toBe('2000000'); + expect((await alice.utxos)[1].value.dump().lovelace).toBe('22753044'); + expect((await alice.utxos)[0].value.dump().assets[mph][616263]).toBe(amt.toString()); + }) + +}) diff --git a/tests/vesting-cancel.test.ts b/tests/vesting-cancel.test.ts index 39be606..cdb0aad 100644 --- a/tests/vesting-cancel.test.ts +++ b/tests/vesting-cancel.test.ts @@ -56,11 +56,14 @@ describe("a vesting contract: Cancel transaction", async () => { const aliceUtxos = await alice.utxos; // https://www.hyperion-bt.org/helios-book/api/reference/address.html?highlight=Address#address expect(alice.address.toHex().length).toBe(58) - // UTxO - expect(aliceUtxos[1].value.dump().lovelace).toBe('50000000') + // UTxOs + expect((await alice.utxos)[0].value.dump().lovelace).toBe('20000000'); + expect((await alice.utxos)[1].value.dump().lovelace).toBe('50000000'); + // https://www.hyperion-bt.org/helios-book/lang/builtins/validatorhash.html?highlight=valida#validatorhash expect(validatorHash.hex).toBe('e7015c6a1424d748f8241fe3a43b3a382b35dc9ca67320e3ee863dc8') + }) it ("tests cancelVesting.ts", async ({network, alice, bob, program}) => { @@ -69,9 +72,6 @@ describe("a vesting contract: Cancel transaction", async () => { const validatorHash = compiledScript.validatorHash; const validatorAddress = Address.fromValidatorHash(validatorHash); - expect((await alice.utxos)[0].value.dump().lovelace).toBe('20000000'); - expect((await alice.utxos)[1].value.dump().lovelace).toBe('50000000'); - const adaQty = 10; const duration = 1000000; await lockAda(network!, alice!, bob!, program, adaQty, duration); @@ -107,7 +107,6 @@ 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'); - const networkParamsFile = await fs.readFile('./src/preprod.json', 'utf8'); const networkParams = new NetworkParams(JSON.parse(networkParamsFile.toString()));