Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,6 @@ jobs:

- name: Run CI
run: npm exec turbo ci
env:
BLOCKFROST_API_KEY: ${{ secrets.BLOCKFROST_API_KEY }}
SEED_PHRASE: ${{ secrets.SEED_PHRASE }}
9 changes: 7 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,14 @@
"lint:eslint": "pnpm eslint .",
"lint:prettier": "pnpm exec prettier --check '**/*.{js,jsx,ts,tsx,json,yml.j2,yml,yaml,.*}'",
"lint": "npm-run-all lint:aiken lint:prettier lint:eslint",
"test": "aiken check"
"test:aiken": "aiken check",
"test:unit": "vitest run",
"test": "npm-run-all test:aiken test:unit"
},
"dependencies": {
"@evolution-sdk/aiken-uplc": "^0.0.12",
"@evolution-sdk/evolution": "^0.3.20",
"@evolution-sdk/scalus-uplc": "^0.0.10",
"@inquirer/prompts": "^8.3.0",
"@noble/hashes": "^2.0.1",
"arktype": "^2.1.29",
Expand All @@ -49,6 +53,7 @@
"prettier": "^3.8.1",
"tsx": "^4.21.0",
"turbo": "^2.8.12",
"typescript": "^5.9.3"
"typescript": "^5.9.3",
"vitest": "^4.0.18"
}
}
601 changes: 601 additions & 0 deletions pnpm-lock.yaml

Large diffs are not rendered by default.

6 changes: 6 additions & 0 deletions src/inputs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,10 +61,16 @@ const Config = type({
BLOCKFROST_API_KEY: "string==39",
Comment thread
SynthLuvr marked this conversation as resolved.
});

const IntegrationConfig = type({
BLOCKFROST_API_KEY: "string==39",
SEED_PHRASE: "string",
Comment thread
SynthLuvr marked this conversation as resolved.
});

export {
Address,
Amount,
Config,
IntegrationConfig,
logThenExit,
Options,
TokenName,
Expand Down
84 changes: 84 additions & 0 deletions src/mint.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
import { createAikenEvaluator } from "@evolution-sdk/aiken-uplc";
import {
Assets,
createClient,
ScriptHash,
SigningClient,
Text,
Transaction,
UTxO,
} from "@evolution-sdk/evolution";
import type { Evaluator } from "@evolution-sdk/evolution/sdk/builders/TransactionBuilder";
import { createScalusEvaluator } from "@evolution-sdk/scalus-uplc";
import { beforeAll, describe, expect, it } from "vitest";
import { IntegrationConfig, validate } from "./inputs";
import { createScript, loadPlutus } from "./script";
import {
expiresIn,
loadWalletFromSeed,
makeBlockfrostConfig,
parseNetwork,
} from "./wallet";

const tokenName = Text.toHex("test");
const tokenAmount = 1n;

describe("mint transaction", () => {
let token: string;
let client: SigningClient;
let ref: UTxO.UTxO;

beforeAll(async () => {
expect(
process.env.BLOCKFROST_API_KEY,
"BLOCKFROST_API_KEY is required"
).toBeTruthy();
expect(process.env.SEED_PHRASE, "SEED_PHRASE is required").toBeTruthy();

const config = validate(IntegrationConfig, process.env);
const projectId = config.BLOCKFROST_API_KEY;
const seed = config.SEED_PHRASE;

const wallet = await loadWalletFromSeed(projectId, seed);
expect(wallet.utxos.length).toBeGreaterThan(0);

const plutus = (await loadPlutus()).assert();

ref = wallet.utxos[0];
Comment thread
SynthLuvr marked this conversation as resolved.
const script = createScript(plutus, ref);
const policy = ScriptHash.toHex(ScriptHash.fromScript(script));
token = policy + tokenName;

client = createClient({
network: parseNetwork(projectId),
provider: makeBlockfrostConfig(projectId),
wallet: { type: "seed", mnemonic: seed },
});
});

const buildMintTx = (evaluator: Evaluator) => async () => {
const plutus = (await loadPlutus()).assert();
const script = createScript(plutus, ref);

const mintResult = await client
.newTx()
.mintAssets({
assets: Assets.fromRecord({ [token]: tokenAmount }),
})
.attachScript({ script })
.collectFrom({ inputs: [ref] })
.setValidity({ to: BigInt(Date.now() + expiresIn) })
.build({ evaluator });

const tx = await mintResult.toTransaction();
const cbor = Transaction.toCBORHex(tx);
expect(cbor).toBeTruthy();
};
Comment thread
SynthLuvr marked this conversation as resolved.

it("builds mint tx with aiken evaluator", buildMintTx(createAikenEvaluator));

it(
"builds mint tx with scalus evaluator",
buildMintTx(createScalusEvaluator)
);
});
15 changes: 1 addition & 14 deletions src/mint.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,6 @@ import {
Effect,
ScriptHash,
TransactionHash,
UPLC,
UTxO,
} from "@evolution-sdk/evolution";
import { Command } from "commander";
import { isProblem } from "ts-handling";
Expand All @@ -20,7 +18,7 @@ import {
TokenName,
validate,
} from "./inputs";
import { loadPlutus } from "./script";
import { createScript, loadPlutus } from "./script";
import {
expiresIn,
getNetwork,
Expand Down Expand Up @@ -150,17 +148,6 @@ const program = new Command()
);
});

const createScript = (plutus: string, ref: UTxO.UTxO): PlutusV3 => {
const scriptHex = UPLC.applySingleCborEncoding(
UPLC.applyParamsToScript(plutus, [
TransactionHash.toBytes(ref.transactionId),
ref.index,
])
);

return new PlutusV3({ bytes: hexToBytes(scriptHex) });
};

const createBlackholeAddress = (
network: "Mainnet" | "Preprod" | "Preview"
): Address.Address => {
Expand Down
16 changes: 14 additions & 2 deletions src/script.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import fs from "fs/promises";
import { dirname, join } from "path";
import { fileURLToPath } from "url";
import { UPLC } from "@evolution-sdk/evolution";
import { PlutusV3 } from "@evolution-sdk/evolution/PlutusV3";
import { TransactionHash, UPLC, UTxO } from "@evolution-sdk/evolution";
import { type } from "arktype";
import { Err, Ok, Result } from "ts-handling";
import { hexToBytes } from "./utils";

const Validators = ["mint.mint.mint", "multiple.mint.mint"] as const;
type Validator = (typeof Validators)[number];
Expand Down Expand Up @@ -38,4 +40,14 @@ const loadPlutus = async (
return Ok(UPLC.applyDoubleCborEncoding(compiledCode));
};
Comment thread
SynthLuvr marked this conversation as resolved.

export { loadPlutus };
const createScript = (plutus: string, ref: UTxO.UTxO): PlutusV3 => {
const scriptHex = UPLC.applySingleCborEncoding(
UPLC.applyParamsToScript(plutus, [
TransactionHash.toBytes(ref.transactionId),
ref.index,
])
);
return new PlutusV3({ bytes: hexToBytes(scriptHex) });
};
Comment thread
SynthLuvr marked this conversation as resolved.

export { createScript, loadPlutus };
1 change: 1 addition & 0 deletions turbo.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
{
"$schema": "https://turbo.build/schema.json",
"globalEnv": ["BLOCKFROST_API_KEY", "SEED_PHRASE"],
"tasks": {
"build": {},
"lint": {},
Expand Down
12 changes: 12 additions & 0 deletions vitest.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { defineConfig } from "vitest/config";

export default defineConfig({
test: {
globals: true,
server: {
deps: {
inline: ["@evolution-sdk/aiken-uplc", "@evolution-sdk/scalus-uplc"],
},
},
},
});