Skip to content

Commit

Permalink
Merge pull request #287 from MeshJS/v1.7.1
Browse files Browse the repository at this point in the history
  • Loading branch information
jinglescode authored Sep 3, 2024
2 parents c7b7e93 + cf9e471 commit f07ff08
Show file tree
Hide file tree
Showing 27 changed files with 581 additions and 147 deletions.
69 changes: 69 additions & 0 deletions apps/playground/public/drep/meshjs.jsonld
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
{
"@context": {
"CIP100": "https://github.com/cardano-foundation/CIPs/blob/master/CIP-0100/README.md#",
"CIP119": "https://github.com/cardano-foundation/CIPs/blob/master/CIP-0119/README.md#",
"hashAlgorithm": "CIP100:hashAlgorithm",
"body": {
"@id": "CIP119:body",
"@context": {
"references": {
"@id": "CIP119:references",
"@container": "@set",
"@context": {
"GovernanceMetadata": "CIP100:GovernanceMetadataReference",
"Identity": "CIP100:IdentityReference",
"Link": "CIP100:LinkReference",
"Other": "CIP100:OtherReference",
"label": "CIP100:reference-label",
"uri": "CIP100:reference-uri",
"referenceHash": {
"@id": "CIP119:referenceHash",
"@context": {
"hashDigest": "CIP119:hashDigest",
"hashAlgorithm": "CIP100:hashAlgorithm"
}
}
}
},
"paymentAddress": "CIP119:paymentAddress",
"givenName": "CIP119:givenName",
"image": "CIP119:image",
"objectives": "CIP119:objectives",
"motivations": "CIP119:motivations",
"qualifications": "CIP119:qualifications",
"doNotList": "CIP119:doNotList"
}
},
"authors": {
"@id": "CIP100:authors",
"@container": "@set",
"@context": {
"name": "http://xmlns.com/foaf/0.1/name",
"witness": {
"@id": "CIP100:witness",
"@context": {
"witnessAlgorithm": "CIP100:witnessAlgorithm",
"publicKey": "CIP100:publicKey",
"signature": "CIP100:signature"
}
}
}
}
},
"authors": [],
"hashAlgorithm": "blake2b-256",
"body": {
"givenName": "MeshJS",
"motivations": "We're motivated by our deep belief in decentralized governance and our hands-on experience with MeshJS. We've seen firsthand how accessible tools can drive innovation, and we want to make sure developers' needs and voices are at the forefront of Cardano's evolution.",
"objectives": "We champion governance decisions that support open-source development and empower Cardano's developer community. We aim to make it easier for developers to innovate and contribute to the ecosystem.",
"paymentAddress": "addr1qyjtjxjkhskglfefwe9kanvk7wczft0q6ngyhyh9es0km27q3upff6k44dawpnj5w8w5suq8jxff0w54yv90yte9u46st87vk3",
"qualifications": "Our experience in blockchain tooling and commitment to open-source principles make us well-equipped to represent developers in Cardano's decision-making processes.",
"references": [
{
"@type": "Other",
"label": "Label",
"uri": "https://meshjs.dev/"
}
]
}
}
5 changes: 2 additions & 3 deletions apps/playground/src/data/links-data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ export const metaDataJson = {
link: "/apis/data/json",
icon: Bars3Icon,
};
// todoß
export const metaDataValue = {
title: "Value",
desc: "Manipulate Cardano Value Easily",
Expand All @@ -52,8 +51,8 @@ export const linksData: MenuItem[] = [
metaDataMesh,
metaDataJson,
metaDataValue,
// metaDataCbor,
// metaDataUtils,
// metaDataCbor, // todo
// metaDataUtils, // todo
];

export const metaData = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ function Left(userInput: string) {
codeSnippet1 += `const forgingScript = ForgeScript.withOneSignature(address);`;

let codeSnippet2 = `const asset: Asset = {\n`;
codeSnippet2 += ` unit: assetAsset,\n`;
codeSnippet2 += ` unit: '${userInput}',\n`;
codeSnippet2 += ` quantity: '1',\n`;
codeSnippet2 += `};\n`;
codeSnippet2 += `tx.burnAsset(forgingScript, asset);`;
Expand Down
3 changes: 3 additions & 0 deletions apps/playground/src/pages/apis/txbuilder/basics/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,14 @@ import TxbuilderSendValues from "./send-values";
import TxbuilderSetNetwork from "./set-network";
import TxbuilderSetRequiredSigners from "./set-required-signers";
import TxbuilderSetTime from "./set-time";
import TxbuilderMultisigNativeScript from "./multisig-native-script";

const ReactPage: NextPage = () => {
const sidebarItems = [
{ label: "Initialize Tx Builder", to: "initializeTxbuilder" },
{ label: "Send value", to: "sendValue" },
{ label: "Multi-signature", to: "multisig" },
{ label: "Multisig native script", to: "multisigNativeScript" },
{ label: "Build with object", to: "buildWithObject" },
{ label: "Coin selection", to: "coinSelection" },
{ label: "Set metadata", to: "cip20" },
Expand Down Expand Up @@ -68,6 +70,7 @@ const ReactPage: NextPage = () => {
{/* <TxbuilderCommonFunctions /> */}
<TxbuilderSendValues />
<TxbuilderMultisig />
<TxbuilderMultisigNativeScript />
<TxbuilderBuildWithObject />
{/* <TxbuilderSetMetadata /> */}
<TxbuilderCoinSelection />
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,238 @@
import {
AppWallet,
deserializeAddress,
ForgeScript,
MeshTxBuilder,
MeshWallet,
NativeScript,
resolveNativeScriptAddress,
resolveNativeScriptHash,
resolveScriptHash,
serializeNativeScript,
stringToHex,
} from "@meshsdk/core";
import { useWallet } from "@meshsdk/react";

import { getProvider } from "~/components/cardano/mesh-wallet";
import LiveCodeDemo from "~/components/sections/live-code-demo";
import TwoColumnsScroll from "~/components/sections/two-columns-scroll";
import Codeblock from "~/components/text/codeblock";
import { demoAssetMetadata, demoMnemonic } from "~/data/cardano";
import { getTxBuilder } from "../common";

// const scriptAddress =
// "addr_test1vpd5480qj5jj4pnjwq9yxnac8l9dw2k3y6gz2cpp6jawzwq838jl8";
// const scriptCbor =
// "8201828200581c556f3a70b8a68081cf36c918dd9933abdca34f20fc534499c817182b8200581c5867c3b8e27840f556ac268b781578b14c5661fc63ee720dbeab663f";

export default function TxbuilderMultisigNativeScript() {
return (
<TwoColumnsScroll
sidebarTo="multisigNativeScript"
title="Multi-signature Transaction with Native Script"
leftSection={Left()}
rightSection={Right()}
/>
);
}

function Left() {
let codeKeyHash = ``;
codeKeyHash += `const { pubKeyHash: keyHash1 } = deserializeAddress(walletAddress1);\n`;
codeKeyHash += `const { pubKeyHash: keyHash2 } = deserializeAddress(walletAddress2);\n`;

let codeNativeScript = ``;
codeNativeScript += `const nativeScript: NativeScript = {\n`;
codeNativeScript += ` type: "all",\n`;
codeNativeScript += ` scripts: [\n`;
codeNativeScript += ` {\n`;
codeNativeScript += ` type: "sig",\n`;
codeNativeScript += ` keyHash: keyHash1,\n`;
codeNativeScript += ` },\n`;
codeNativeScript += ` {\n`;
codeNativeScript += ` type: "sig",\n`;
codeNativeScript += ` keyHash: keyHash2,\n`;
codeNativeScript += ` },\n`;
codeNativeScript += ` ],\n`;
codeNativeScript += `};\n`;

let codeSerializeNativeScript = ``;
codeSerializeNativeScript += `const { address: scriptAddress, scriptCbor } =\n`;
codeSerializeNativeScript += ` serializeNativeScript(nativeScript);\n`;

let codeTx = ``;
codeTx += `// get utxo from script\n`;
codeTx += `const utxos = await blockchainProvider.fetchAddressUTxOs(scriptAddress);\n`;
codeTx += `const utxo = utxos[0];\n`;
codeTx += `\n`;
codeTx += `// create tx\n`;
codeTx += `const unsignedTx = await txBuilder\n`;
codeTx += ` .txIn(\n`;
codeTx += ` utxo.input.txHash,\n`;
codeTx += ` utxo.input.outputIndex,\n`;
codeTx += ` utxo.output.amount,\n`;
codeTx += ` utxo.output.address,\n`;
codeTx += ` )\n`;
codeTx += ` .txInScript(scriptCbor)\n`;
codeTx += ` .txOut(\n`;
codeTx += ` "addr_test1vpvx0sacufuypa2k4sngk7q40zc5c4npl337uusdh64kv0c7e4cxr",\n`;
codeTx += ` [{ unit: "lovelace", quantity: "2000000" }],\n`;
codeTx += ` )\n`;
codeTx += ` .changeAddress(scriptAddress)\n`;
codeTx += ` .selectUtxosFrom(utxos)\n`;
codeTx += ` .complete();\n`;

let codeSign = ``;
codeSign += `const signedTx1 = await wallet1.signTx(unsignedTx, true);\n`;
codeSign += `const signedTx2 = await wallet2.signTx(signedTx1, true);\n`;
codeSign += `\n`;
codeSign += `const txHash = await wallet.submitTx(signedTx2);\n`;

return (
<>
<h4>Create native script</h4>
<p>
First, we need to create a native script. In this example, we will
create a native script with two signatures. That means we need to get
the key hashes of the two wallets.
</p>
<Codeblock data={codeKeyHash} />
<p>
Next, we will create a native script object with the two key hashes. The
native script object will be used to create a multi-signature
transaction.
</p>
<Codeblock data={codeNativeScript} />
<p>
The native script object is then serialized into a CBOR object and an
address.
</p>
<Codeblock data={codeSerializeNativeScript} />
<h4>Create transaction</h4>
<p>
Now that we have the native script, we can create a transaction with the
script. We first need to get the UTXO from the script address.
</p>
<Codeblock data={codeTx} />
<p>
Finally, we sign the transaction with the two wallets and submit the
transaction.
</p>
<Codeblock data={codeSign} />
</>
);
}

function Right() {
const { wallet, connected } = useWallet();

function getMeshWallet() {
const blockchainProvider = getProvider();

const wallet = new MeshWallet({
networkId: 0,
fetcher: blockchainProvider,
submitter: blockchainProvider,
key: {
type: "mnemonic",
words: "solution,".repeat(24).split(",").slice(0, 24),
},
});

const walletAddress = wallet.getChangeAddress();

const { pubKeyHash: keyHash } = deserializeAddress(walletAddress);
return { wallet, keyHash, walletAddress };
}

async function getScript() {
if (!connected) return;

// first wallet
const walletAddress = (await wallet.getUsedAddresses())[0];
if (!walletAddress) return;
const { pubKeyHash: keyHash1 } = deserializeAddress(walletAddress);

// second wallet
const { keyHash: keyHash2 } = getMeshWallet();

const nativeScript: NativeScript = {
type: "all",
scripts: [
{
type: "sig",
keyHash: keyHash1,
},
{
type: "sig",
keyHash: keyHash2,
},
],
};

const { address: scriptAddress, scriptCbor } =
serializeNativeScript(nativeScript);

return { scriptAddress, scriptCbor: scriptCbor! };
}

async function runDemo() {
if (!connected) return;

const script = await getScript();
if (!script) {
throw new Error("Failed to get script");
}
const { scriptAddress, scriptCbor } = script;

const blockchainProvider = getProvider();
const utxos = await blockchainProvider.fetchAddressUTxOs(scriptAddress);

if (utxos.length === 0) {
throw new Error(`No utxos, fund address ${scriptAddress}`);
}
const utxo = utxos[0]!;

const { wallet: walletB } = getMeshWallet();

const txBuilder = getTxBuilder();

const unsignedTx = await txBuilder
.txIn(
utxo.input.txHash,
utxo.input.outputIndex,
utxo.output.amount,
utxo.output.address,
)
.txInScript(scriptCbor)
.txOut(
"addr_test1vpvx0sacufuypa2k4sngk7q40zc5c4npl337uusdh64kv0c7e4cxr",
[{ unit: "lovelace", quantity: "2000000" }],
)
.changeAddress(scriptAddress)
.selectUtxosFrom(utxos)
.complete();

const signedTx1 = await wallet.signTx(unsignedTx, true);
const signedTx2 = await walletB.signTx(signedTx1, true);

const txHash = await wallet.submitTx(signedTx2);
return txHash;
}

let codeSnippet = ``;

return (
<LiveCodeDemo
title="Multi-signature Transaction with native script "
subtitle="Create a multi-signature transaction with a native script. In this demo, we will create a transaction with two signatures, where one signature is from the user wallet and the other is from a minting wallet."
code={codeSnippet}
runCodeFunction={runDemo}
disabled={!connected}
runDemoButtonTooltip={
!connected ? "Connect wallet to run this demo" : undefined
}
runDemoShowBrowseWalletConnect={true}
></LiveCodeDemo>
);
}
Loading

0 comments on commit f07ff08

Please sign in to comment.