Skip to content

Commit

Permalink
initial (untested) draft of offchain tx construction/submission code
Browse files Browse the repository at this point in the history
  • Loading branch information
gnumonik committed Apr 18, 2024
1 parent f51ba9f commit 075a216
Show file tree
Hide file tree
Showing 4 changed files with 278 additions and 95 deletions.
1 change: 1 addition & 0 deletions dens-transactions/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions dens-transactions/package.json
Expand Up @@ -38,6 +38,7 @@
"lbr-plutus": "file:.extra-dependencies/lbr-plutus",
"lbr-prelude": "file:.extra-dependencies/lbr-prelude",
"lucid-cardano": "^0.10.7",
"node-fetch": "^3.3.2",
"plutus-ledger-api": "file:.extra-dependencies/plutus-ledger-api",
"prelude": "file:.extra-dependencies/prelude"
}
Expand Down
135 changes: 40 additions & 95 deletions dens-transactions/src/DensTransactions/DensTransactions.ts
@@ -1,59 +1,37 @@
import * as L from "lucid-cardano";
import {
DensKey,
DensValue,
Protocol,
RecordDatum,
SetDatum,
SetInsert,
} from "lbf-dens/LambdaBuffers/Dens.mjs";
import { IsPlutusData } from "lbr-plutus/PlutusData.js";
import * as Pla from "plutus-ledger-api/PlutusData.js";
import * as csl from "@emurgo/cardano-serialization-lib-nodejs";
import { fromJust } from "prelude";
import { scriptHashFromBytes } from "plutus-ledger-api/V1.js";

type DeNSParams = {
setValidator: L.SpendingValidator;
recordValidator: L.SpendingValidator;
setElemIDPolicy: L.MintingPolicy;
elemIDPolicy: L.MintingPolicy;
protocolPolicy: L.MintingPolicy;
};

const mkLBScriptHash = (script: L.SpendingValidator) => {
return fromJust(
scriptHashFromBytes(L.fromHex(L.applyDoubleCborEncoding(script.script))),
);
};
import * as Utils from "./Utils.js"

const initializeDeNS = async (
export const initializeDeNS = async (
lucid: L.Lucid,
params: DeNSParams,
params: Utils.DeNSParams,
): Promise<L.Tx> => {
const builder = new L.Tx(lucid);
const utils = new L.Utils(lucid);

const initialSetDatum: SetDatum = undefined;
const initialSetDatumPD = IsPlutusData[SetDatum].toData(initialSetDatum);
const initialSetDatumCSL = (toCslPlutusData(initialSetDatumPD)).to_hex();
const initialSetDatumPD = IsPlutusData[SetDatum].toData(Utils.initialSetDatum);
const initialSetDatumCSL = (Utils.toCslPlutusData(initialSetDatumPD)).to_hex();
const initialSetDatumDatum: L.OutputData = { inline: initialSetDatumCSL };

const protocolDatumRaw: Protocol = {
elementIdMintingPolicy: mkLBScriptHash(params.elemIDPolicy),
setElemMintingPolicy: mkLBScriptHash(params.setElemIDPolicy),
setValidator: mkLBScriptHash(params.setValidator),
recordsValidator: mkLBScriptHash(params.recordValidator),
elementIdMintingPolicy: Utils.mkLBScriptHash(params.elemIDPolicy),
setElemMintingPolicy: Utils.mkLBScriptHash(params.setElemIDPolicy),
setValidator: Utils.mkLBScriptHash(params.setValidator),
recordsValidator: Utils.mkLBScriptHash(params.recordValidator),
};

const protocolDatum: L.OutputData = {
inline: toCslPlutusData(IsPlutusData[Protocol].toData(protocolDatumRaw))
inline: Utils.toCslPlutusData(IsPlutusData[Protocol].toData(protocolDatumRaw))
.to_hex(),
};

const findProtocolOut: () => Promise<L.UTxO> = undefined;

const protocolOut = await findProtocolOut();
const protocolOut = await Utils.findProtocolOut(lucid);

// Mint one protocol token
const protocolPolicyID = utils.mintingPolicyToId(params.protocolPolicy);
Expand All @@ -78,9 +56,9 @@ const initializeDeNS = async (
.collectFrom([protocolOut]);
};

const registerDomain = async (
export const registerDomain = async (
lucid: L.Lucid,
params: DeNSParams,
params: Utils.DeNSParams,
domain: string,
): Promise<L.Tx> => {
const builder = new L.Tx(lucid);
Expand All @@ -90,36 +68,48 @@ const registerDomain = async (
[utils.mintingPolicyToId(params.setElemIDPolicy)]: BigInt(1),
};

const newSetDatumL: L.OutputData = undefined;
const newSetDatumR: L.OutputData = undefined;
const setDatumResponse = await Utils.findOldSetDatum(lucid,domain);

const elemIDPolicy = utils.mintingPolicyToId(params.elemIDPolicy);
const elemIDAssetClass: L.Unit = elemIDPolicy + L.fromText(domain);
const oldSetDatum = setDatumResponse.setDatum;
const oldSetDatumUtxo = setDatumResponse.setDatumUTxO;

const oneElemIDToken = { [elemIDAssetClass]: BigInt(1) };
const k: DensKey = oldSetDatum.key;
const nxt: DensKey = oldSetDatum.next;

const findOldSetDatumUTxO: () => Promise<L.UTxO> = undefined;
const sdl: SetDatum = {key: k,
next: {densName: Buffer.from(domain,'utf8'), densClass: BigInt(0)},
ownerApproval: Utils.emptyCS
};
const sdr: SetDatum = {key: {densName: Buffer.from(domain,'utf8'), densClass: BigInt(0)},
next: nxt,
ownerApproval: Utils.emptyCS
};

const oldSetDatumUTxO = await findOldSetDatumUTxO();

const findProtocolOut: () => Promise<L.UTxO> = undefined;
const newSetDatumL: L.OutputData = {inline: Utils.toCslPlutusData(IsPlutusData[SetDatum].toData(sdl)).to_hex()};
const newSetDatumR: L.OutputData = {inline: Utils.toCslPlutusData(IsPlutusData[SetDatum].toData(sdr)).to_hex()};

const protocolOut = await findProtocolOut();
const elemIDPolicy = utils.mintingPolicyToId(params.elemIDPolicy);
const elemIDAssetClass: L.Unit = elemIDPolicy + L.fromText(domain);

const oneElemIDToken = { [elemIDAssetClass]: BigInt(1) };

const protocolOut = await Utils.findProtocolOut(lucid);

const setValidatorAddr = utils.validatorToAddress(params.setValidator);

return builder // TODO: null redeemers
.mintAssets(oneSetElemToken)
.mintAssets(oneElemIDToken)
.readFrom([protocolOut])
.collectFrom([oldSetDatumUTxO])
.collectFrom([oldSetDatumUtxo])
.payToAddressWithData(setValidatorAddr, newSetDatumL, oneSetElemToken)
.payToAddressWithData(setValidatorAddr, newSetDatumR, oneSetElemToken);
};

const updateRecord = async (
export const updateRecord = async (
lucid: L.Lucid,
params: DeNSParams,
params: Utils.DeNSParams,
user: L.Address,
domain: string,
record: RecordDatum,
Expand All @@ -134,16 +124,13 @@ const updateRecord = async (

const elemIDToken = { [elemIDAssetClass]: BigInt(1) };

const findProtocolOut: () => Promise<L.UTxO> = undefined;

const protocolOut = await findProtocolOut();
const protocolOut = await Utils.findProtocolOut(lucid);

const findElemIDUTxO: () => Promise<L.UTxO> = undefined;

const elemIDUTxO: L.UTxO = await findElemIDUTxO();
const elemIDUTxO: L.UTxO = await Utils.findElemIDUTxO(elemIDAssetClass,lucid);

const recordDatum: L.OutputData = {
inline: toCslPlutusData(IsPlutusData[RecordDatum].toData(record)).to_hex(),
inline: Utils.toCslPlutusData(IsPlutusData[RecordDatum].toData(record)).to_hex(),
};

return builder
Expand All @@ -155,45 +142,3 @@ const updateRecord = async (
.payToAddress(user, elemIDToken);
};

export function toCslPlutusData(
plutusData: Pla.PlutusData,
): csl.PlutusData {
switch (plutusData.name) {
case "Integer":
return csl.PlutusData.new_integer(
csl.BigInt.from_str(plutusData.fields.toString()),
);
case "Bytes":
return csl.PlutusData.new_bytes(plutusData.fields);
case "List":
return csl.PlutusData.new_list(
plaPdListToCslPlutusList(plutusData.fields),
);
case "Constr":
return csl.PlutusData.new_constr_plutus_data(
csl.ConstrPlutusData.new(
csl.BigNum.from_str(plutusData.fields[0].toString()),
plaPdListToCslPlutusList(plutusData.fields[1]),
),
);
case "Map": {
const plutusMap = csl.PlutusMap.new();
for (const elem of plutusData.fields) {
plutusMap.insert(
toCslPlutusData(elem[0]),
toCslPlutusData(elem[1]),
);
}
return csl.PlutusData.new_map(plutusMap);
}
}
}

function plaPdListToCslPlutusList(list: Pla.PlutusData[]): csl.PlutusList {
const result = csl.PlutusList.new();

for (const elem of list) {
result.add(toCslPlutusData(elem));
}
return result;
}

0 comments on commit 075a216

Please sign in to comment.