Skip to content

Instantly share code, notes, and snippets.

@caike
Last active August 29, 2023 14:31
Show Gist options
  • Save caike/e0d6202fd77820c0ffd79e81a430f6ad to your computer and use it in GitHub Desktop.
Save caike/e0d6202fd77820c0ffd79e81a430f6ad to your computer and use it in GitHub Desktop.
Lucid and CIP-68
import type { NextPage } from 'next'
import Head from 'next/head'
import WalletConnect from '../components/WalletConnect'
import { useStoreActions, useStoreState } from "../utils/store"
import Link from 'next/link'
import { useState, useEffect } from 'react'
import { getAssets } from "../utils/cardano";
import NftGrid from "../components/NftGrid";
import initLucid from '../utils/lucid'
import { Lucid, Credential, TxHash, Lovelace, Constr, SpendingValidator, Data, fromText, Unit, MintingPolicy, PolicyId, Address, UTxO, applyParamsToScript, Assets, ScriptHash, Redeemer, paymentCredentialOf, KeyHash, generatePrivateKey, getAddressDetails, toUnit } from 'lucid-cardano'
import * as helios from '@hyperionbt/helios'
import {fromAssets, toAssets, union, Value} from "../utils/valueUtils"
import { fromAddress, OfferDatum, OfferInfo, toAddress } from '../utils/offerUtils'
import { kMaxLength } from 'buffer'
const emurgoMintingCbor = "5902835902800100003232323232323232323232323232323222232332232323232323253330163370e9000001099199919911980091911180100198018008912800919991180b11299980c800880189980218108009801181000091180091299980e99b8848000dd6981180209911980080100199b80002375a604600826446600200800466e00004dd6981180219191198008018012400090000009999111980b11299980c80089128008a99980e99baf301f30210010041300530210011300230200010012322230020033756603e0026ea4008004dd5980d980d180d0029180091299980d299980d19b8700c4800054cc064cdc3801240082a6603266e1c0052000153301933014232323232533301f3370e90000010b0a9980f19b8f375c604600291011c791d504ef072be11979a3c722bf1a46a8af77be7326fb7949da497c100133712904051e1a3999911199980c801240004666603400490003ad37560020066eacc08cc088010060060c090008c07c004dd51918109811000981000098100009bac301e008133014233223375e6e9cc088008dd39811000980f98100008089bac301e0091533301a3370e01890010a9980c99b87002480004cdc4000a40002a6603266e1c009200013371000290000a4c2c2c6eb8c06800458c06c008c058004dd5180b980b001980a980a800980b180a800980a8009bad003002375a004460046ea40048888cc01c894ccc028004401454ccc038cdd79808180900080309802180a1809000898011808800800a45002300222533300500114a02a6600c6006601a002260046018002464600446600400400246004466004004002aae7c8cc010004008528911998018010008022b9a14a0aae755d12ba1230023754002aae781"
const alwaysTrueRefScript: SpendingValidator = {
type: "PlutusV2",
script:
"581b5819010000322225333573466600890002400090000a4c2c444945",
};
const Helioz: NextPage = () => {
const walletStore = useStoreState((state: any) => state.wallet)
const [lucid, setLucid] = useState<Lucid>()
useEffect(() => {
if (lucid) {
;
} else {
initLucid(walletStore.name).then((Lucid: Lucid) => { setLucid(Lucid) })
}
}, [lucid])
type NFTMetadata = {
name: string;
image: string;
mediaType?: string;
description?: string;
files?: FileDetails[];
};
type FileDetails = {
name?: string;
mediaType: string;
src: string;
};
const firstMetadata : NFTMetadata = {
name: "Mint",
image: "ipfs://QmNurFsat962fVzNKBaVMmgE2NwtHudvh8jzF8MXFhwGr9",
description: "JUNGLE #1 Metadata"
}
const firstMetadataDatum = Data.to(new Constr(0, [Data.fromJson(firstMetadata), BigInt(1)]));
const secondMetadata : NFTMetadata = {
name: "Re-Mint",
image: "ipfs://QmWcJnqSNSeREKVkVeJ6d4SL9Fw22ASnRRBaNNeXnSBMdX",
description: "JUNGLE #2 metadata"
}
const secondMetadataDatum = Data.to(new Constr(0, [Data.fromJson(secondMetadata), BigInt(1)]));
const mintOnchainMetadata = async () => {
if (lucid) {
const utxos = await lucid.wallet.getUtxos();
const txOutId = utxos[0].txHash
const txId = new Constr(0, [txOutId])
// Below is needed as argument for spending
// from the Script Address prior to update
console.log({ txOutId })
console.log({ txIndex: utxos[0].outputIndex })
// {txOutId: '37f16e581759fa4b41d7150328132058152e19c182632d08a7698bf05c80548b'}
// helioz.tsx:72 {txIndex: 2}
const txOutRefParam = new Constr(0, [txId, BigInt(utxos[0].outputIndex)])
const emurgoMinting : MintingPolicy = {type:"PlutusV2",
script: applyParamsToScript(emurgoMintingCbor, [txOutRefParam])};
const emurgoMintingCS = lucid.utils.mintingPolicyToId(emurgoMinting)
// console.log({ policyID: emurgoMintingCS })
const alwaysTrueRefAddress = lucid.utils.validatorToAddress(alwaysTrueRefScript);
const tokenName = fromText("JUNGLE-NFT");
const refNFT = toUnit(emurgoMintingCS, tokenName, 100);
const userToken = toUnit(emurgoMintingCS, tokenName, 222);
// const json = Data.toJson(firstMetadataDatum);
// const hash = lucid.utils.datumToHash(firstMetadataDatum)
const txHash = await lucid.newTx()
.collectFrom([utxos[0]])
.mintAssets({
[refNFT]: BigInt(1),
[userToken]: BigInt(1)
}, Data.to(BigInt(0)))
.payToContract(alwaysTrueRefAddress, firstMetadataDatum, {[refNFT]: BigInt(1)})
.payToContract("addr_test1wpu365zw7petuyvhng78y2l3534g4ammuuexldu5nkjf0sgz5xu88", Data.void(), {lovelace: BigInt(75_000_000)})
.payToAddress(await lucid.wallet.address(), {[userToken]: BigInt(1) })
.attachMintingPolicy(emurgoMinting)
.complete()
.then((tx) => tx.sign().complete())
.then((tx) => tx.submit())
console.log(txHash)
}
}
const updateOnchainMetadata = async () => {
if (lucid) {
//const utxos = await lucid.wallet.getUtxos();
// Replace with information form minting policy
const txOutId = "37f16e581759fa4b41d7150328132058152e19c182632d08a7698bf05c80548b";
const txIndex = 2;
const txId = new Constr(0, [txOutId]);
const txOutRefParam = new Constr(0, [txId, BigInt(txIndex)])
const emurgoMinting : MintingPolicy = {
type:"PlutusV2",
script: applyParamsToScript(emurgoMintingCbor, [txOutRefParam])
};
const emurgoMintingCS = lucid.utils.mintingPolicyToId(emurgoMinting);
const tokenName = fromText("JUNGLE-NFT");
const refNFT = toUnit(emurgoMintingCS, tokenName, 100);
const alwaysTrueRefAddress = lucid.utils.validatorToAddress(alwaysTrueRefScript);
const alwaysTrueScriptUTXO = await lucid.utxoByUnit(refNFT);
const txHash = await lucid.newTx()
.collectFrom([alwaysTrueScriptUTXO], firstMetadataDatum)
.payToContract(alwaysTrueRefAddress, secondMetadataDatum, {[refNFT]: BigInt(1)})
.attachSpendingValidator(alwaysTrueRefScript)
.complete()
.then((tx) => tx.sign().complete())
.then((tx) => tx.submit())
console.log(txHash)
}
}
return (
<div className="px-10">
<div className="navbar bg-base-100">
<div className="flex-1">
<Link href="/" className="btn btn-ghost normal-case text-xl">Cardano</Link>
</div>
<div className="flex-none">
<WalletConnect />
</div>
</div>
<div>Address: {walletStore.address}</div>
<div className='m-10'>
<p>
Emurgo example
</p>
</div>
<div className="mx-60 my-10">
<button className="btn btn-secondary m-5" onClick={() => { mintOnchainMetadata() }}> Mint CIP68</button>
<button className="btn btn-secondary m-5" onClick={() => { updateOnchainMetadata() }}> Update CIP68</button>
</div>
</div>
)
}
export default Helioz
//
//
// Sending Lucid Tx CBOR to Cardano Node Submit API
//
//
// const cborData = signed.toString();
// const binaryTx = new Uint8Array(cborData.match(/.{1,2}/g).map(byte => parseInt(byte, 16)));
// const url = "http://..../api/submit/tx";
// const headers = new Headers({
// 'Content-Type': 'application/cbor'
// });
// const response = await fetch(url, {
// method: 'POST',
// headers: headers,
// body: binaryTx
// });
// if (!response.ok) {
// throw new Error(`HTTP error! Status: ${response.status}`);
// }
// const txID = await response.text();
// console.log('Successfully sent to Submit API:', txID);
@colll78
Copy link

colll78 commented May 31, 2023

 const tokenName = fromText("EmurgoTN");
 const refNFT = toUnit(emurgoMintingCS, tokenName, 100);
 const alwaysTrueScriptUTXO = await lucid.getUtxoByUnit(refNFT)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment