diff --git a/apps/playground/public/articles/spices-4185324_640.jpg b/apps/playground/public/articles/spices-4185324_640.jpg new file mode 100644 index 00000000..5f77eeb7 Binary files /dev/null and b/apps/playground/public/articles/spices-4185324_640.jpg differ diff --git a/apps/playground/public/team/abdelkrim.png b/apps/playground/public/team/abdelkrim.png index 496f8a04..318bafd8 100644 Binary files a/apps/playground/public/team/abdelkrim.png and b/apps/playground/public/team/abdelkrim.png differ diff --git a/apps/playground/public/team/felix.png b/apps/playground/public/team/felix.png index 52f4f3ec..c3966204 100644 Binary files a/apps/playground/public/team/felix.png and b/apps/playground/public/team/felix.png differ diff --git a/apps/playground/public/team/hinson.png b/apps/playground/public/team/hinson.png index b715e8b0..03e3d9bb 100644 Binary files a/apps/playground/public/team/hinson.png and b/apps/playground/public/team/hinson.png differ diff --git a/apps/playground/public/team/jingles.png b/apps/playground/public/team/jingles.png index c5d509e0..e4b53d8b 100644 Binary files a/apps/playground/public/team/jingles.png and b/apps/playground/public/team/jingles.png differ diff --git a/apps/playground/public/team/tszwai.png b/apps/playground/public/team/tszwai.png index f1403953..d3e34ce6 100644 Binary files a/apps/playground/public/team/tszwai.png and b/apps/playground/public/team/tszwai.png differ diff --git a/apps/playground/src/data/links-articles.ts b/apps/playground/src/data/links-articles.ts new file mode 100644 index 00000000..e8ce1f81 --- /dev/null +++ b/apps/playground/src/data/links-articles.ts @@ -0,0 +1,35 @@ +import { NewspaperIcon } from "@heroicons/react/24/solid"; + +import { MenuItem } from "~/types/menu-item"; + +export const articleNew16 = { + title: "What's new in Mesh 1.6", + desc: "", + link: "whats-new-in-16", + thumbnail: "/articles/develop-first-web-app.png", + image: "/articles/arches-1866598_1280.jpg", +}; +export const articleMesh20 = { + title: "Introduce Mesh 2.0", + desc: "", + link: "typescript-cardano-sdk", + thumbnail: "/articles/develop-first-web-app.png", + image: "/articles/arches-1866598_1280.jpg", +}; +export const articleElementsOfCardano = { + title: "Elements of Cardano", + desc: "Cardano represents a significant advancement in blockchain technology, offering a scalable, secure, and flexible platform that is well-suited for a wide range of applications. Its unique combination of public, permissionless infrastructure, proof-of-stake consensus, and support for smart contracts and native assets makes it a powerful tool for developers and enterprises alike.", + link: "elements-of-cardano", + thumbnail: "/articles/spices-4185324_640.png", + image: "/articles/spices-4185324_640.jpg", +}; + +export const linksArticles: MenuItem[] = [articleElementsOfCardano,articleMesh20, articleNew16]; + +export const metaArticles: MenuItem = { + link: `/blogs`, + title: "Blogs", + desc: "Read the latest blogs and articles about Mesh", + icon: NewspaperIcon, + items: linksArticles, +}; diff --git a/apps/playground/src/data/links-blogs.ts b/apps/playground/src/data/links-blogs.ts deleted file mode 100644 index 0d1f64cf..00000000 --- a/apps/playground/src/data/links-blogs.ts +++ /dev/null @@ -1,28 +0,0 @@ -import { NewspaperIcon } from "@heroicons/react/24/solid"; - -import { MenuItem } from "~/types/menu-item"; - -export const blogNew16 = { - title: "What's new in Mesh 1.6", - desc: "", - link: "whats-new-in-16", - thumbnail: "/guides/develop-first-web-app.png", - image: "/guides/arches-1866598_1280.jpg", -}; -export const blogMesh20 = { - title: "Introduce Mesh 2.0", - desc: "", - link: "typescript-cardano-sdk", - thumbnail: "/guides/develop-first-web-app.png", - image: "/guides/arches-1866598_1280.jpg", -}; - -export const linksBlogs: MenuItem[] = [blogMesh20, blogNew16]; - -export const metaBlogs: MenuItem = { - link: `/blogs`, - title: "Blogs", - desc: "Read the latest blogs and articles about Mesh", - icon: NewspaperIcon, - items: linksBlogs, -}; diff --git a/apps/playground/src/data/links-data.ts b/apps/playground/src/data/links-data.ts index 97fd5cf2..62097829 100644 --- a/apps/playground/src/data/links-data.ts +++ b/apps/playground/src/data/links-data.ts @@ -27,6 +27,13 @@ export const metaDataJson = { link: "/apis/data/json", icon: Bars3Icon, }; +// todoß +export const metaDataValue = { + title: "Value", + desc: "Manipulate Cardano Value Easily", + link: "/apis/data/value", + icon: Bars3Icon, +}; export const metaDataCbor = { title: "CBOR Data", desc: "Parse and manipulate Cardano data with CBOR", @@ -44,6 +51,7 @@ export const linksData: MenuItem[] = [ metaOverview, metaDataMesh, metaDataJson, + metaDataValue, // metaDataCbor, // metaDataUtils, ]; diff --git a/apps/playground/src/pages/apis/data/value/accessor.tsx b/apps/playground/src/pages/apis/data/value/accessor.tsx new file mode 100644 index 00000000..dfebc744 --- /dev/null +++ b/apps/playground/src/pages/apis/data/value/accessor.tsx @@ -0,0 +1,104 @@ +import { MeshValue } from "@meshsdk/common"; + +import LiveCodeDemo from "~/components/sections/live-code-demo"; +import TwoColumnsScroll from "~/components/sections/two-columns-scroll"; +import { mockUnit } from "./"; + +export default function ValueAccessor() { + return ( + + ); +} + +function Left() { + return ( + <> + + + + ); +} + +function Section1() { + return ( + <> +

+ get get the quantity of asset object per unit, with + parameters +

+
    +
  • + unit - the unit of the assets e.g. lovelace +
  • +
+ + ); +} + +function Section2() { + return ( + <> +

+ units get all asset units with no parameters (e.g. unit) + needed +

+ + ); +} + +function Right() { + return ( + <> + + + + ); +} + +function getCode() { + return ` + import { MeshValue } from "@meshsdk/common"; + const value = new MeshValue({ lovelace: 20n }); + return value.get("lovelace"); + `; +} + +async function runGetDemo() { + const value = new MeshValue({ lovelace: 20n }); + value.get("lovelace"); + return value; +} + +function getCode2() { + return ` + import { MeshValue } from "@meshsdk/common"; + const value = new MeshValue({ + lovelace: 20n, + [mockUnit]: 10n, + }); + return value.units(); + `; +} + +async function runUnitsDemo() { + const value = new MeshValue({ + lovelace: 20n, + [mockUnit]: 10n, + }); + return value.units(); +} diff --git a/apps/playground/src/pages/apis/data/value/addasset-operator.tsx b/apps/playground/src/pages/apis/data/value/addasset-operator.tsx new file mode 100644 index 00000000..041cb199 --- /dev/null +++ b/apps/playground/src/pages/apis/data/value/addasset-operator.tsx @@ -0,0 +1,60 @@ +import { Asset, MeshValue } from "@meshsdk/common"; + +import LiveCodeDemo from "~/components/sections/live-code-demo"; +import TwoColumnsScroll from "~/components/sections/two-columns-scroll"; + +export default function AddAssetOperator() { + return ( + + ); +} + +function Left() { + return ( + <> +

+ addAsset Add an asset to the Value class's value record + with parameters: +

+
    + asset - Asset to add +
+ + ); +} + +function Right() { + async function runAddAssetDemo() { + const value = new MeshValue(); + const singleAsset: Asset = { + unit: "baefdc6c5b191be372a794cd8d40d839ec0dbdd3c28957267dc817001234", + quantity: "100", + }; + value.addAsset(singleAsset); + return value.value; + } + + let code = ` + import { MeshValue } from "@meshsdk/common"; + const value = new MeshValue(); + const singleAsset: Asset = { unit: "baefdc6c5b191be372a794cd8d40d839ec0dbdd3c28957267dc817001234", quantity: "100" }; + value.addAsset(singleAsset); + return value.value; + `; + + return ( + <> + + + ); +} diff --git a/apps/playground/src/pages/apis/data/value/addassets-operator.tsx b/apps/playground/src/pages/apis/data/value/addassets-operator.tsx new file mode 100644 index 00000000..fbac6bbe --- /dev/null +++ b/apps/playground/src/pages/apis/data/value/addassets-operator.tsx @@ -0,0 +1,73 @@ +import { Asset, MeshValue } from "@meshsdk/common"; + +import LiveCodeDemo from "~/components/sections/live-code-demo"; +import TwoColumnsScroll from "~/components/sections/two-columns-scroll"; + +export default function AddassetsOperator() { + return ( + + ); +} + +function Left() { + return ( + <> +

+ addAssets Add an array of assets to the Value class's value + record with parameters: +

+
    + assets - Asset[] to add +
+ + ); +} + +function Right() { + async function runaddassetsDemo() { + const value = new MeshValue(); + const assets: Asset[] = [ + { + unit: "baefdc6c5b191be372a794cd8d40d839ec0dbdd3c28957267dc817001234", + quantity: "100", + }, + { unit: "lovelace", quantity: "10" }, + { + unit: "baefdc6c5b191be372a794cd8d40d839ec0dbdd3c28957267dc817001234", + quantity: "100", + }, + { unit: "lovelace", quantity: "10" }, + ]; + value.addAssets(assets); + return value.value; + } + + let code = ` + import { MeshValue } from "@meshsdk/common"; + const value = new MeshValue(); + const assets: Asset[] = [ + { unit: "baefdc6c5b191be372a794cd8d40d839ec0dbdd3c28957267dc817001234", quantity: "100" }, + { unit: "lovelace", quantity: "10" }, + { unit: "baefdc6c5b191be372a794cd8d40d839ec0dbdd3c28957267dc817001234", quantity: "100" }, + { unit: "lovelace", quantity: "10" }, + ]; + value.addAssets(assets); + return value.value; + `; + + return ( + <> + + + ); +} diff --git a/apps/playground/src/pages/apis/data/value/comparator.tsx b/apps/playground/src/pages/apis/data/value/comparator.tsx new file mode 100644 index 00000000..cfbf70fb --- /dev/null +++ b/apps/playground/src/pages/apis/data/value/comparator.tsx @@ -0,0 +1,283 @@ +import { MeshValue } from "@meshsdk/common"; + +import LiveCodeDemo from "~/components/sections/live-code-demo"; +import TwoColumnsScroll from "~/components/sections/two-columns-scroll"; + +export default function ValueComparator() { + return ( + + ); +} + +function Left() { + return ( + <> + + + + + + + ); +} + +function Section1() { + return ( + <> +

+ geq Check if the value is greater than or equal to another + value with parameters: +

+
    +
  • + other - The MeshValue to compare against +
  • +
+ + ); +} + +function Section2() { + return ( + <> +

+ geqUnit Check if the value is greater than or equal to + another value with parameters: +

+
    +
  • + unit - The unit to compare +
  • +
  • + other - The MeshValue to compare against +
  • +
+ + ); +} + +function Section3() { + return ( + <> +

+ leq Check if the value is less than or equal to another + value with parameters: +

+
    +
  • + other - The MeshValue to compare against +
  • +
+ + ); +} + +function Section4() { + return ( + <> +

+ leqUnit Check if the specific unit of value is less than or + equal to that unit of another value with parameters: +

+
    +
  • + unit - The unit to compare +
  • +
  • + other - The MeshValue to compare against +
  • +
+ + ); +} + +function Section5() { + return ( + <> +

+ isEmpty Check if the value is empty +

+ + ); +} + +function Right() { + return ( + <> + + + + + + + ); +} + +function getCode() { + return ` + import { MeshValue } from "@meshsdk/common"; + const value = new MeshValue({ + lovelace: 20n, + c21d710605bb00e69f3c175150552fc498316d80e7efdb1b186db38c000643b04d65736820676f6f64: 10n }); + const target = new MeshValue({ + lovelace: 10n, + c21d710605bb00e69f3c175150552fc498316d80e7efdb1b186db38c000643b04d65736820676f6f64: 5n }); + return value.geq(target); + `; +} + +async function rungeqDemo() { + const value = new MeshValue({ + lovelace: 20n, + c21d710605bb00e69f3c175150552fc498316d80e7efdb1b186db38c000643b04d65736820676f6f64: + 10n, + }); + const target = new MeshValue({ + lovelace: 10n, + c21d710605bb00e69f3c175150552fc498316d80e7efdb1b186db38c000643b04d65736820676f6f64: + 5n, + }); + return value.geq(target); +} + +function getCode2() { + return ` + import { MeshValue } from "@meshsdk/common"; + const value = new MeshValue({ + lovelace: 20n, + c21d710605bb00e69f3c175150552fc498316d80e7efdb1b186db38c000643b04d65736820676f6f64: + 10n, + }); + const target = new MeshValue({ + lovelace: 10n, + c21d710605bb00e69f3c175150552fc498316d80e7efdb1b186db38c000643b04d65736820676f6f64: + 5n, + }); + const resultLovelace = value.geqUnit("lovelace", target); + const resultmockvalue = value.geqUnit( + "c21d710605bb00e69f3c175150552fc498316d80e7efdb1b186db38c000643b04d65736820676f6f64", + target, + ); + + return { resultLovelace, resultmockvalue }; + `; +} + +async function runmgeqUnitDemo() { + const value = new MeshValue({ + lovelace: 20n, + c21d710605bb00e69f3c175150552fc498316d80e7efdb1b186db38c000643b04d65736820676f6f64: + 10n, + }); + const target = new MeshValue({ + lovelace: 10n, + c21d710605bb00e69f3c175150552fc498316d80e7efdb1b186db38c000643b04d65736820676f6f64: + 5n, + }); + const resultLovelace = value.geqUnit("lovelace", target); + const resultmockvalue = value.geqUnit( + "c21d710605bb00e69f3c175150552fc498316d80e7efdb1b186db38c000643b04d65736820676f6f64", + target, + ); + + return { resultLovelace, resultmockvalue }; +} + +function getCode3() { + return ` + import { MeshValue } from "@meshsdk/common"; + const value = new MeshValue({ lovelace: 20n, "c21d710605bb00e69f3c175150552fc498316d80e7efdb1b186db38c000643b04d65736820676f6f64": 10n }); + const target = new MeshValue({ lovelace: 30n, "c21d710605bb00e69f3c175150552fc498316d80e7efdb1b186db38c000643b04d65736820676f6f64": 15n }); + return value.leq(target); + `; +} + +async function runleqDemo() { + const value = new MeshValue({ + lovelace: 20n, + c21d710605bb00e69f3c175150552fc498316d80e7efdb1b186db38c000643b04d65736820676f6f64: + 10n, + }); + const target = new MeshValue({ + lovelace: 30n, + c21d710605bb00e69f3c175150552fc498316d80e7efdb1b186db38c000643b04d65736820676f6f64: + 15n, + }); + return value.leq(target); +} + +function getCode4() { + return ` + import { MeshValue } from "@meshsdk/common"; + const value = new MeshValue(); + value.value = { lovelace: 20n, [mockUnit]: 10n }; + value.negateAssets([ + { unit: "lovelace", quantity: "5" }, + { unit: mockUnit, quantity: "3" }, + ]); + return value.value; + `; +} + +async function runleqUnitDemo() { + const value = new MeshValue({ + lovelace: 20n, + c21d710605bb00e69f3c175150552fc498316d80e7efdb1b186db38c000643b04d65736820676f6f64: + 10n, + }); + const target = new MeshValue({ + lovelace: 30n, + c21d710605bb00e69f3c175150552fc498316d80e7efdb1b186db38c000643b04d65736820676f6f64: + 15n, + }); + const resultLovelace = value.leqUnit("lovelace", target); + const resultmockvalue = value.leqUnit( + "c21d710605bb00e69f3c175150552fc498316d80e7efdb1b186db38c000643b04d65736820676f6f64", + target, + ); + + return { resultLovelace, resultmockvalue }; +} + +function getCode5() { + return ` + import { MeshValue } from "@meshsdk/common"; + const value = new MeshValue(); + return value.isEmpty(); + `; +} + +async function runisEmptyDemo() { + const value = new MeshValue(); + return value.isEmpty(); +} diff --git a/apps/playground/src/pages/apis/data/value/convertor.tsx b/apps/playground/src/pages/apis/data/value/convertor.tsx new file mode 100644 index 00000000..e62b2e2b --- /dev/null +++ b/apps/playground/src/pages/apis/data/value/convertor.tsx @@ -0,0 +1,388 @@ +import { + Asset, + byteString, + dict, + Dict, + Integer, + integer, + MeshValue, + MValue, + mValue, + Value, + value, +} from "@meshsdk/common"; +import { assocMap, currencySymbol, tokenName } from "@meshsdk/core"; + +import LiveCodeDemo from "~/components/sections/live-code-demo"; +import TwoColumnsScroll from "~/components/sections/two-columns-scroll"; + +export default function ValueConvertor() { + return ( + + ); +} + +function Left() { + return ( + <> + + + + + + + + + ); +} + +function Section1() { + return ( + <> +

+ value converts assets into Cardano data Value in JSON with + parameters: +

+
    +
  • + val - Asset[] to convert +
  • +
+ + ); +} + +function Section2() { + return ( + <> +

+ mValue converts assets into Cardano data value in Mesh Data + type with parameters: +

+
    +
  • + val - Asset[] to convert +
  • +
+ + ); +} + +function Section3() { + return ( + <> +

+ fromAssets converts assets into MeshValue with parameters: +

+
    +
  • + assets - the assets to convert +
  • +
+ + ); +} + +function Section4() { + return ( + <> +

+ fromValue get all asset units with no parameters (e.g. + unit) needed +

+
    +
  • + plutusValue - Convert Value (the JSON representation of Cardano + data Value) into MeshValue +
  • +
+ + ); +} + +function Section5() { + return ( + <> +

+ toAssets converts the MeshValue object into an array of + Asset +

+ + ); +} + +function Section6() { + return ( + <> +

+ toData Convert the MashValue object into Cardano data Value + in Mesh Data type +

+ + ); +} + +function Section7() { + return ( + <> +

+ toJSON converts the MeshValue object into a JSON + representation of Cardano data Value +

+ + ); +} + +function Right() { + return ( + <> + + + + + + + + + ); +} + +function getCode() { + return ` + const val: Asset[] = [{ unit: "lovelace", quantity: "1000000" }]; + const datum: Value = value(val); + const nameMap = dict([[byteString(""), integer(1000000)]]); + const valMap = dict>([[byteString(""), nameMap]]); + if (JSON.stringify(datum) === JSON.stringify(valMap)) { + return true; + } + `; +} + +async function runvalueDemo() { + const val: Asset[] = [{ unit: "lovelace", quantity: "1000000" }]; + const datum: Value = value(val); + const nameMap = dict([[byteString(""), integer(1000000)]]); + const valMap = dict>([[byteString(""), nameMap]]); + if (JSON.stringify(datum) === JSON.stringify(valMap)) { + return true; + } +} + +function getCode2() { + return ` + const val: Asset[] = [{ unit: "lovelace", quantity: "1000000" }]; + const datum: MValue = mValue(val); + const nameMap = new Map().set("", 1000000); + const valMap = new Map().set("", nameMap); + if (JSON.stringify(datum) === JSON.stringify(valMap)) { + return true; + `; +} + +async function runmValueDemo() { + const val: Asset[] = [{ unit: "lovelace", quantity: "1000000" }]; + const datum: MValue = mValue(val); + const nameMap = new Map().set("", 1000000); + const valMap = new Map().set("", nameMap); + if (JSON.stringify(datum) === JSON.stringify(valMap)) { + return true; + } +} + +function getCode3() { + return ` + import { MeshValue } from "@meshsdk/common"; + const assets: Asset[] = [ + { unit: "c21d710605bb00e69f3c175150552fc498316d80e7efdb1b186db38c000643b04d65736820676f6f64", quantity: "100" }, + { unit: "lovelace", quantity: "10" }, + ]; + const value = MeshValue.fromAssets(assets); + return value; + `; +} + +async function runfromAssetsDemo() { + const assets: Asset[] = [ + { + unit: "c21d710605bb00e69f3c175150552fc498316d80e7efdb1b186db38c000643b04d65736820676f6f64", + quantity: "100", + }, + { unit: "lovelace", quantity: "10" }, + ]; + const value = MeshValue.fromAssets(assets); + return value; +} + +function getCode4() { + return ` + import { MeshValue } from "@meshsdk/common"; + const val: Asset[] = [{ unit: "lovelace", quantity: "1000000" }]; + const plutusValue: Value = value(val); + const assets: Asset[] = MeshValue.fromValue(plutusValue).toAssets(); + return assets; + `; +} + +async function runtoAssetsDemo() { + const val: Asset[] = [{ unit: "lovelace", quantity: "1000000" }]; + const plutusValue: Value = value(val); + const assets: Asset[] = MeshValue.fromValue(plutusValue).toAssets(); + return assets; +} + +function getCode5() { + return ` + import { MeshValue } from "@meshsdk/common"; + const val: Asset[] = [{ unit: "lovelace", quantity: "1000000" }]; + const plutusValue: Value = value(val); + const assets: Asset[] = MeshValue.fromValue(plutusValue).toAssets(); + return assets; + `; +} + +async function runfromValueDemo() { + const val: Asset[] = [{ unit: "lovelace", quantity: "1000000" }]; + const plutusValue: Value = value(val); + const assets: Asset[] = MeshValue.fromValue(plutusValue).toAssets(); + return assets; +} + +function getCode6() { + return ` + import { MeshValue } from "@meshsdk/common"; + const val: Asset[] = [ + { + unit: "baefdc6c5b191be372a794cd8d40d839ec0dbdd3c28957267dc817001234", + quantity: "100", + }, + { + unit: "baefdc6c5b191be372a794cd8d40d839ec0dbdd3c28957267dc817001234", + quantity: "200", + }, + ]; + const plutusValue: Value = value(val); + const data = MeshValue.fromValue(plutusValue).toData(); + const expected: MValue = mValue(val); + if (JSON.stringify(expected) === JSON.stringify(data)) { + return true; + } + `; +} + +async function runtoDataDemo() { + const val: Asset[] = [ + { + unit: "baefdc6c5b191be372a794cd8d40d839ec0dbdd3c28957267dc817001234", + quantity: "100", + }, + { + unit: "baefdc6c5b191be372a794cd8d40d839ec0dbdd3c28957267dc817001234", + quantity: "200", + }, + ]; + const plutusValue: Value = value(val); + const data = MeshValue.fromValue(plutusValue).toData(); + const expected: MValue = mValue(val); + if (JSON.stringify(expected) === JSON.stringify(data)) { + return true; + } +} + +function getCode7() { + return ` + const assets: Asset[] = [ + { unit: "lovelace", quantity: "1000000" }, + { + unit: "c21d710605bb00e69f3c175150552fc498316d80e7efdb1b186db38c000643b04d65736820676f6f64", + quantity: "500", + }, + ]; + + const expectedValue = assocMap([ + [currencySymbol(""), assocMap([[tokenName(""), integer(1000000)]])], + [ + currencySymbol( + "c21d710605bb00e69f3c175150552fc498316d80e7efdb1b186db38c", + ), + assocMap([[tokenName("000643b04d65736820676f6f64"), integer(500)]]), + ], + ]); + + const meshValue = new MeshValue(); + meshValue.toAssets = () => assets; + + const jsonValue = meshValue.toJSON(); + if (JSON.stringify(jsonValue) === JSON.stringify(expectedValue)) { + return true; + } + `; +} + +async function runtoJSONDemo() { + const assets: Asset[] = [ + { unit: "lovelace", quantity: "1000000" }, + { + unit: "c21d710605bb00e69f3c175150552fc498316d80e7efdb1b186db38c000643b04d65736820676f6f64", + quantity: "500", + }, + ]; + + const expectedValue = assocMap([ + [currencySymbol(""), assocMap([[tokenName(""), integer(1000000)]])], + [ + currencySymbol( + "c21d710605bb00e69f3c175150552fc498316d80e7efdb1b186db38c", + ), + assocMap([[tokenName("000643b04d65736820676f6f64"), integer(500)]]), + ], + ]); + + const meshValue = new MeshValue(); + meshValue.toAssets = () => assets; + + const jsonValue = meshValue.toJSON(); + if (JSON.stringify(jsonValue) === JSON.stringify(expectedValue)) { + return true; + } +} diff --git a/apps/playground/src/pages/apis/data/value/fromassets-convertor.tsx b/apps/playground/src/pages/apis/data/value/fromassets-convertor.tsx new file mode 100644 index 00000000..1a140274 --- /dev/null +++ b/apps/playground/src/pages/apis/data/value/fromassets-convertor.tsx @@ -0,0 +1,65 @@ +import { Asset, MeshValue } from "@meshsdk/common"; + +import LiveCodeDemo from "~/components/sections/live-code-demo"; +import TwoColumnsScroll from "~/components/sections/two-columns-scroll"; + +export default function FromassetsConvertor() { + return ( + + ); +} + +function Left() { + return ( + <> +

+ fromAssets converts assets into MeshValue with parameters: +

+
    +
  • + assets - the assets to convert +
  • +
+ + ); +} + +function Right() { + async function runfromassetsDemo() { + const assets: Asset[] = [ + { + unit: "c21d710605bb00e69f3c175150552fc498316d80e7efdb1b186db38c000643b04d65736820676f6f64", + quantity: "100", + }, + { unit: "lovelace", quantity: "10" }, + ]; + const value = MeshValue.fromAssets(assets); + return value; + } + + let code = ` + import { MeshValue } from "@meshsdk/common"; + const assets: Asset[] = [ + { unit: "c21d710605bb00e69f3c175150552fc498316d80e7efdb1b186db38c000643b04d65736820676f6f64", quantity: "100" }, + { unit: "lovelace", quantity: "10" }, + ]; + const value = MeshValue.fromAssets(assets); + return value; + `; + + return ( + <> + + + ); +} diff --git a/apps/playground/src/pages/apis/data/value/fromvalue-convertor.tsx b/apps/playground/src/pages/apis/data/value/fromvalue-convertor.tsx new file mode 100644 index 00000000..efa475b9 --- /dev/null +++ b/apps/playground/src/pages/apis/data/value/fromvalue-convertor.tsx @@ -0,0 +1,59 @@ +import { Asset, MeshValue, Value, value } from "@meshsdk/common"; + +import LiveCodeDemo from "~/components/sections/live-code-demo"; +import TwoColumnsScroll from "~/components/sections/two-columns-scroll"; + +export default function FromvalueConvertor() { + return ( + + ); +} + +function Left() { + return ( + <> +

+ fromValue Convert Value (the JSON representation of Cardano + data Value) into MeshValue with parameters: +

+
    +
  • + plutusValue - the value to convert +
  • +
+ + ); +} + +function Right() { + async function runfromvalueDemo() { + const val: Asset[] = [{ unit: "lovelace", quantity: "1000000" }]; + const plutusValue: Value = value(val); + const assets: Asset[] = MeshValue.fromValue(plutusValue).toAssets(); + return assets; + } + + let code = ` + import { MeshValue } from "@meshsdk/common"; + const val: Asset[] = [{ unit: "lovelace", quantity: "1000000" }]; + const plutusValue: Value = value(val); + const assets: Asset[] = MeshValue.fromValue(plutusValue).toAssets(); + return assets; + `; + + return ( + <> + + + ); +} diff --git a/apps/playground/src/pages/apis/data/value/geq-comparator.tsx b/apps/playground/src/pages/apis/data/value/geq-comparator.tsx new file mode 100644 index 00000000..9bf345cc --- /dev/null +++ b/apps/playground/src/pages/apis/data/value/geq-comparator.tsx @@ -0,0 +1,71 @@ +import { MeshValue } from "@meshsdk/common"; + +import LiveCodeDemo from "~/components/sections/live-code-demo"; +import TwoColumnsScroll from "~/components/sections/two-columns-scroll"; + +export default function GeqComparator() { + return ( + + ); +} + +function Left() { + return ( + <> +

+ geq Check if the value is greater than or equal to another + value with parameters: +

+
    +
  • + other - The MeshValue to compare against +
  • +
+ + ); +} + +function Right() { + async function rungeqDemo() { + const value = new MeshValue({ + lovelace: 20n, + c21d710605bb00e69f3c175150552fc498316d80e7efdb1b186db38c000643b04d65736820676f6f64: + 10n, + }); + const target = new MeshValue({ + lovelace: 10n, + c21d710605bb00e69f3c175150552fc498316d80e7efdb1b186db38c000643b04d65736820676f6f64: + 5n, + }); + return value.geq(target); + } + + let code = ` + import { MeshValue } from "@meshsdk/common"; + const value = new MeshValue({ + lovelace: 20n, + c21d710605bb00e69f3c175150552fc498316d80e7efdb1b186db38c000643b04d65736820676f6f64: 10n, + }); + const target = new MeshValue({ + lovelace: 10n, + c21d710605bb00e69f3c175150552fc498316d80e7efdb1b186db38c000643b04d65736820676f6f64: 5n, + }); + return value.geq(target); + `; + + return ( + <> + + + ); +} diff --git a/apps/playground/src/pages/apis/data/value/gequnit-comparator.tsx b/apps/playground/src/pages/apis/data/value/gequnit-comparator.tsx new file mode 100644 index 00000000..690de39d --- /dev/null +++ b/apps/playground/src/pages/apis/data/value/gequnit-comparator.tsx @@ -0,0 +1,89 @@ +import { MeshValue } from "@meshsdk/common"; + +import LiveCodeDemo from "~/components/sections/live-code-demo"; +import TwoColumnsScroll from "~/components/sections/two-columns-scroll"; + +export default function GequnitComparator() { + return ( + + ); +} + +function Left() { + return ( + <> +

+ geqUnit Check if the value is greater than or equal to + another value with parameters: +

+
    +
  • + unit - The unit to compare +
  • +
  • + other - The MeshValue to compare against +
  • +
+ + ); +} + +function Right() { + async function rungequnitDemo() { + const value = new MeshValue({ + lovelace: 20n, + c21d710605bb00e69f3c175150552fc498316d80e7efdb1b186db38c000643b04d65736820676f6f64: + 10n, + }); + const target = new MeshValue({ + lovelace: 10n, + c21d710605bb00e69f3c175150552fc498316d80e7efdb1b186db38c000643b04d65736820676f6f64: + 5n, + }); + const resultLovelace = value.geqUnit("lovelace", target); + const resultmockvalue = value.geqUnit( + "c21d710605bb00e69f3c175150552fc498316d80e7efdb1b186db38c000643b04d65736820676f6f64", + target, + ); + + return { resultLovelace, resultmockvalue }; + } + + let code = ` + import { MeshValue } from "@meshsdk/common"; + const value = new MeshValue({ + lovelace: 20n, + c21d710605bb00e69f3c175150552fc498316d80e7efdb1b186db38c000643b04d65736820676f6f64: + 10n, + }); + const target = new MeshValue({ + lovelace: 10n, + c21d710605bb00e69f3c175150552fc498316d80e7efdb1b186db38c000643b04d65736820676f6f64: + 5n, + }); + const resultLovelace = value.geqUnit("lovelace", target); + const resultmockvalue = value.geqUnit( + "c21d710605bb00e69f3c175150552fc498316d80e7efdb1b186db38c000643b04d65736820676f6f64", + target, + ); + + return { resultLovelace, resultmockvalue }; + } + `; + + return ( + <> + + + ); +} diff --git a/apps/playground/src/pages/apis/data/value/get-accessor.tsx b/apps/playground/src/pages/apis/data/value/get-accessor.tsx new file mode 100644 index 00000000..558b9329 --- /dev/null +++ b/apps/playground/src/pages/apis/data/value/get-accessor.tsx @@ -0,0 +1,57 @@ +import { MeshValue } from "@meshsdk/common"; + +import LiveCodeDemo from "~/components/sections/live-code-demo"; +import TwoColumnsScroll from "~/components/sections/two-columns-scroll"; + +export default function GetAccessor() { + return ( + + ); +} + +function Left() { + return ( + <> +

+ get get the quantity of asset object per unit, with + parameters +

+
    +
  • + unit - the unit to get the quantity of the assets e.g. lovelace +
  • +
+ + ); +} + +function Right() { + async function rungetDemo() { + const value = new MeshValue({ lovelace: 20n }); + value.get("lovelace"); + return value; + } + + let code = ` + import { MeshValue } from "@meshsdk/common"; + const value = new MeshValue({ lovelace: 20n }); + value.get("lovelace"); + return value; + `; + + return ( + <> + + + ); +} diff --git a/apps/playground/src/pages/apis/data/value/index.tsx b/apps/playground/src/pages/apis/data/value/index.tsx new file mode 100644 index 00000000..253b5fe5 --- /dev/null +++ b/apps/playground/src/pages/apis/data/value/index.tsx @@ -0,0 +1,144 @@ +import type { NextPage } from "next"; + +import SidebarFullwidth from "~/components/layouts/sidebar-fullwidth"; +import TitleIconDescriptionBody from "~/components/sections/title-icon-description-body"; +import Metatags from "~/components/site/metatags"; +import { metaDataValue } from "~/data/links-data"; +import AddAssetOperator from "./addasset-operator"; +import AddAssetsOperator from "./addassets-operator"; +import FromAssetsConvertor from "./fromassets-convertor"; +import FromValueConvertor from "./fromvalue-convertor"; +import GeqComparator from "./geq-comparator"; +import GeqUnitComparator from "./gequnit-comparator"; +import GetAccessor from "./get-accessor"; +import IsEmptyComparator from "./isempty-comparator"; +import LeqComparator from "./leq-comparator"; +import LeqUnitComparator from "./lequnit-comparator"; +import MergeOperator from "./merge-operator"; +import MValueConvertor from "./mvalue-convertor"; +import NegateAssetOperator from "./negateasset-operator"; +import NegateAssetsOperator from "./negateassets-operator"; +import ToAssetsConvertor from "./toassets-convertor"; +import ToDataConvertor from "./todata-convertor"; +import ToJsonConvertor from "./tojson-convertor"; +import UnitsAccessor from "./units-accessor"; +import ValueConvertor from "./value-convertor"; + +const ReactPage: NextPage = () => { + const sidebarItems = [ + { label: "Convertors", to: "ValueConvertor" }, + // { label: "Convertor - mValue", to: "MvalueConvertor" }, + // { label: "Convertor - fromAssets", to: "FromassetsConvertor" }, + // { label: "Convertor - toAssets", to: "ToassetsConvertor" }, + // { label: "Convertor - fromValue", to: "FromvalueConvertor" }, + // { label: "Convertor - toData", to: "TodataConvertor" }, + // { label: "Convertor - toJSON", to: "TojsonConvertor" }, + { label: "Operators", to: "AddAssetOperator" }, + // { label: "Operator - addAssets", to: "AddassetsOperator" }, + // { label: "Operator - negateAsset", to: "NegateassetOperator" }, + // { label: "Operator - negateAssets", to: "NegateassetsOperator" }, + // { label: "Operator - merge", to: "MergeOperator" }, + { label: "Accessors", to: "GetAccessor" }, + // { label: "Accessor - units", to: "UnitsAccessor" }, + { label: "Comparators", to: "GeqComparator" }, + // { label: "Comparator - gepUnit", to: "GequnitComparator" }, + // { label: "Comparator - leq", to: "LeqComparator" }, + // { label: "Comparator - leqUnit", to: "LequnitComparator" }, + // { label: "Comparator - isEmpty", to: "IsemptyComparator" }, + ]; + + return ( + <> + + + +

+ We all know the pain of conducting Value operation in + Cardano. Mesh provides a full set of value methods to help + converting, operating, accessing and comparing Cardano data. +

+

Value Types Support

+

Convertors

+

+ Convertor functions provide utilities around round trip among + Cardano onchain data and off chain JSON and{" "} + Data type. +

+ {/*
    +
  • + value +
  • +
  • + mValue +
  • +
  • + fromAssets +
  • +
  • + toAssets +
  • +
  • + fromValue +
  • +
  • + toData +
  • +
  • + toJSON +
  • +
*/} +

Operators

+

+ Operator functions provide utilities into performing value + manipulation. They are useful in DApps which check against value + payment involving calculation in value. +

+ +

Accessor

+

+ Accessor functions provide utilities in obtaining keys or values of + the Value type. +

+ +

Comparator

+

+ Comparator functions provide utilities in comparing different{" "} + Value. It helps with offchain validation before using + for transaction building. +

+
+ + + + + + + + + + + + + + + + + + + + +
+ + ); +}; + +export default ReactPage; + +export const mockPolicyId = + "c21d710605bb00e69f3c175150552fc498316d80e7efdb1b186db38c"; +export const mockAssetName = "000643b04d65736820676f6f64"; +export const mockUnit = mockPolicyId + mockAssetName; diff --git a/apps/playground/src/pages/apis/data/value/isempty-comparator.tsx b/apps/playground/src/pages/apis/data/value/isempty-comparator.tsx new file mode 100644 index 00000000..6f9fecc1 --- /dev/null +++ b/apps/playground/src/pages/apis/data/value/isempty-comparator.tsx @@ -0,0 +1,49 @@ +import { MeshValue } from "@meshsdk/common"; + +import LiveCodeDemo from "~/components/sections/live-code-demo"; +import TwoColumnsScroll from "~/components/sections/two-columns-scroll"; + +export default function IsemptyComparator() { + return ( + + ); +} + +function Left() { + return ( + <> +

+ isEmpty Check if the value is empty +

+ + ); +} + +function Right() { + async function runisemptyDemo() { + const value = new MeshValue(); + return value.isEmpty(); + } + + let code = ` + import { MeshValue } from "@meshsdk/common"; + const value = new MeshValue(); + return value.isEmpty(); + `; + + return ( + <> + + + ); +} diff --git a/apps/playground/src/pages/apis/data/value/leq-comparator.tsx b/apps/playground/src/pages/apis/data/value/leq-comparator.tsx new file mode 100644 index 00000000..aa3a9b7a --- /dev/null +++ b/apps/playground/src/pages/apis/data/value/leq-comparator.tsx @@ -0,0 +1,73 @@ +import { MeshValue } from "@meshsdk/common"; + +import LiveCodeDemo from "~/components/sections/live-code-demo"; +import TwoColumnsScroll from "~/components/sections/two-columns-scroll"; + +export default function LeqComparator() { + return ( + + ); +} + +function Left() { + return ( + <> +

+ leq Check if the value is less than or equal to another + value with parameters: +

+
    +
  • + other - The MeshValue to compare against +
  • +
+ + ); +} + +function Right() { + async function runleqDemo() { + const value = new MeshValue({ + lovelace: 20n, + c21d710605bb00e69f3c175150552fc498316d80e7efdb1b186db38c000643b04d65736820676f6f64: + 10n, + }); + const target = new MeshValue({ + lovelace: 30n, + c21d710605bb00e69f3c175150552fc498316d80e7efdb1b186db38c000643b04d65736820676f6f64: + 15n, + }); + return value.leq(target); + } + + let code = ` + import { MeshValue } from "@meshsdk/common"; + const value = new MeshValue({ + lovelace: 20n, + c21d710605bb00e69f3c175150552fc498316d80e7efdb1b186db38c000643b04d65736820676f6f64: + 10n, + }); + const target = new MeshValue({ + lovelace: 30n, + c21d710605bb00e69f3c175150552fc498316d80e7efdb1b186db38c000643b04d65736820676f6f64: + 15n, + }); + return value.leq(target); + `; + + return ( + <> + + + ); +} diff --git a/apps/playground/src/pages/apis/data/value/lequnit-comparator.tsx b/apps/playground/src/pages/apis/data/value/lequnit-comparator.tsx new file mode 100644 index 00000000..eb200104 --- /dev/null +++ b/apps/playground/src/pages/apis/data/value/lequnit-comparator.tsx @@ -0,0 +1,86 @@ +import { MeshValue } from "@meshsdk/common"; + +import LiveCodeDemo from "~/components/sections/live-code-demo"; +import TwoColumnsScroll from "~/components/sections/two-columns-scroll"; + +export default function LequnitComparator() { + return ( + + ); +} + +function Left() { + return ( + <> +

+ leqUnit Check if the specific unit of value is less than or + equal to that unit of another value with parameters: +

+
    +
  • + unit - The unit to compare +
  • +
  • + other - The MeshValue to compare against +
  • +
+ + ); +} + +function Right() { + async function runlequnitDemo() { + const value = new MeshValue({ + lovelace: 20n, + c21d710605bb00e69f3c175150552fc498316d80e7efdb1b186db38c000643b04d65736820676f6f64: + 10n, + }); + const target = new MeshValue({ + lovelace: 30n, + c21d710605bb00e69f3c175150552fc498316d80e7efdb1b186db38c000643b04d65736820676f6f64: + 15n, + }); + const resultLovelace = value.leqUnit("lovelace", target); + const resultmockvalue = value.leqUnit( + "c21d710605bb00e69f3c175150552fc498316d80e7efdb1b186db38c000643b04d65736820676f6f64", + target, + ); + + return { resultLovelace, resultmockvalue }; + } + + let code = ` + import { MeshValue } from "@meshsdk/common"; + const value = new MeshValue({ + lovelace: 20n, + c21d710605bb00e69f3c175150552fc498316d80e7efdb1b186db38c000643b04d65736820676f6f64: 10n, + }); + const target = new MeshValue({ + lovelace: 30n, + c21d710605bb00e69f3c175150552fc498316d80e7efdb1b186db38c000643b04d65736820676f6f64: 15n, + }); + const resultLovelace = value.leqUnit("lovelace", target); + const resultmockvalue = value.leqUnit( + "c21d710605bb00e69f3c175150552fc498316d80e7efdb1b186db38c000643b04d65736820676f6f64", + target, + ); + + return { resultLovelace, resultmockvalue }; + `; + + return ( + <> + + + ); +} diff --git a/apps/playground/src/pages/apis/data/value/merge-operator.tsx b/apps/playground/src/pages/apis/data/value/merge-operator.tsx new file mode 100644 index 00000000..a549bd74 --- /dev/null +++ b/apps/playground/src/pages/apis/data/value/merge-operator.tsx @@ -0,0 +1,63 @@ +import { MeshValue } from "@meshsdk/common"; + +import LiveCodeDemo from "~/components/sections/live-code-demo"; +import TwoColumnsScroll from "~/components/sections/two-columns-scroll"; + +export default function MergeOperator() { + return ( + + ); +} + +function Left() { + return ( + <> +

+ merge Merge the given values +

+
    + values - The other values to merge +
+ + ); +} + +function Right() { + async function runmergeDemo() { + const value1 = new MeshValue(); + value1.value = { + lovelace: 20n, + baefdc6c5b191be372a794cd8d40d839ec0dbdd3c28957267dc817001234: 10n, + }; + const value2 = new MeshValue(); + value2.value = { + lovelace: 10n, + baefdc6c5b191be372a794cd8d40d839ec0dbdd3c28957267dc817001234: 5n, + }; + return value1.merge(value2).value; + } + + let code = ` + const value1 = new MeshValue(); + value1.value = { lovelace: 20n, "baefdc6c5b191be372a794cd8d40d839ec0dbdd3c28957267dc817001234": 10n }; + const value2 = new MeshValue(); + value2.value = { lovelace: 10n, "baefdc6c5b191be372a794cd8d40d839ec0dbdd3c28957267dc817001234": 5n }; + return value1.merge(value2).value; + `; + + return ( + <> + + + ); +} diff --git a/apps/playground/src/pages/apis/data/value/mvalue-convertor.tsx b/apps/playground/src/pages/apis/data/value/mvalue-convertor.tsx new file mode 100644 index 00000000..527f2408 --- /dev/null +++ b/apps/playground/src/pages/apis/data/value/mvalue-convertor.tsx @@ -0,0 +1,63 @@ +import { Asset, MValue, mValue } from "@meshsdk/common"; + +import LiveCodeDemo from "~/components/sections/live-code-demo"; +import TwoColumnsScroll from "~/components/sections/two-columns-scroll"; + +export default function MvalueConvertor() { + return ( + + ); +} + +function Left() { + return ( + <> +

+ mValue converts assets into Cardano data value in Mesh Data + type with parameters: +

+
    +
  • + assets - Asset[] to convert +
  • +
+ + ); +} + +function Right() { + async function runmvalueDemo() { + const val: Asset[] = [{ unit: "lovelace", quantity: "1000000" }]; + const datum: MValue = mValue(val); + const nameMap = new Map().set("", 1000000); + const valMap = new Map().set("", nameMap); + if (JSON.stringify(datum) === JSON.stringify(valMap)) { + return true; + } + } + + let code = ` + const val: Asset[] = [{ unit: "lovelace", quantity: "1000000" }]; + const datum: MValue = mValue(val); + const nameMap = new Map().set("", 1000000); + const valMap = new Map().set("", nameMap); + if (JSON.stringify(datum) === JSON.stringify(valMap)) { + return true; + `; + + return ( + <> + + + ); +} diff --git a/apps/playground/src/pages/apis/data/value/negateasset-operator.tsx b/apps/playground/src/pages/apis/data/value/negateasset-operator.tsx new file mode 100644 index 00000000..866785f6 --- /dev/null +++ b/apps/playground/src/pages/apis/data/value/negateasset-operator.tsx @@ -0,0 +1,57 @@ +import { MeshValue } from "@meshsdk/common"; + +import LiveCodeDemo from "~/components/sections/live-code-demo"; +import TwoColumnsScroll from "~/components/sections/two-columns-scroll"; + +export default function NegateassetOperator() { + return ( + + ); +} + +function Left() { + return ( + <> +

+ negateAsset Substract an asset from the Value class's value + record with parameters: +

+
    + asset - Asset to substract +
+ + ); +} + +function Right() { + async function runnegateassetDemo() { + const value = new MeshValue(); + value.value = { lovelace: 10n }; + value.negateAsset({ unit: "lovelace", quantity: "5" }); + return value.value; + } + + let code = ` + import { MeshValue } from "@meshsdk/common"; + const value = new MeshValue(); + value.value = { lovelace: 10n }; + value.negateAsset({ unit: "lovelace", quantity: "5" }); + return value.value; + `; + + return ( + <> + + + ); +} diff --git a/apps/playground/src/pages/apis/data/value/negateassets-operator.tsx b/apps/playground/src/pages/apis/data/value/negateassets-operator.tsx new file mode 100644 index 00000000..24bbb05a --- /dev/null +++ b/apps/playground/src/pages/apis/data/value/negateassets-operator.tsx @@ -0,0 +1,68 @@ +import { MeshValue } from "@meshsdk/common"; + +import LiveCodeDemo from "~/components/sections/live-code-demo"; +import TwoColumnsScroll from "~/components/sections/two-columns-scroll"; + +export default function NegateassetsOperator() { + return ( + + ); +} + +function Left() { + return ( + <> +

+ negateAssets Substract an array of assets from the Value + class's value record with parameters: +

+
    + assets - Asset[] to substract +
+ + ); +} + +function Right() { + async function runnegateassetsDemo() { + const value = new MeshValue(); + value.value = { + lovelace: 20n, + baefdc6c5b191be372a794cd8d40d839ec0dbdd3c28957267dc817001234: 10n, + }; + value.negateAssets([ + { unit: "lovelace", quantity: "5" }, + { + unit: "baefdc6c5b191be372a794cd8d40d839ec0dbdd3c28957267dc817001234", + quantity: "3", + }, + ]); + return value.value; + } + + let code = ` + const value = new MeshValue(); + value.value = { lovelace: 20n, "baefdc6c5b191be372a794cd8d40d839ec0dbdd3c28957267dc817001234": 10n }; + value.negateAssets([ + { unit: "lovelace", quantity: "5" }, + { unit: "baefdc6c5b191be372a794cd8d40d839ec0dbdd3c28957267dc817001234", quantity: "3" }, + ]); + return value.value; + `; + + return ( + <> + + + ); +} diff --git a/apps/playground/src/pages/apis/data/value/operators.tsx b/apps/playground/src/pages/apis/data/value/operators.tsx new file mode 100644 index 00000000..24687ec0 --- /dev/null +++ b/apps/playground/src/pages/apis/data/value/operators.tsx @@ -0,0 +1,247 @@ +import { Asset, MeshValue } from "@meshsdk/common"; + +import LiveCodeDemo from "~/components/sections/live-code-demo"; +import TwoColumnsScroll from "~/components/sections/two-columns-scroll"; +import { mockUnit } from "./"; + +export default function ValueOperator() { + return ( + + ); +} + +function Left() { + return ( + <> + + + + + + + ); +} + +function Section1() { + return ( + <> +

+ addAsset Add an asset to the Value class's value record + with parameters: +

+
    +
  • + asset - Asset to add +
  • +
+ + ); +} + +function Section2() { + return ( + <> +

+ addAssets Add an array of assets to the Value class's value + record with parameters: +

+
    +
  • + assets - Asset[] to add +
  • +
+ + ); +} + +function Section3() { + return ( + <> +

+ negateAsset Substract an asset from the Value class's value + record with parameters: +

+
    +
  • + asset - Asset to substract +
  • +
+ + ); +} + +function Section4() { + return ( + <> +

+ negateAssets Substract an array of assets from the Value + class's value record with parameters: +

+
    +
  • + assets - Asset[] to substract +
  • +
+ + ); +} + +function Section5() { + return ( + <> +

+ merge Merge the given values +

+
    +
  • + values - MeshValue to merge +
  • +
+ + ); +} + +function Right() { + return ( + <> + + + + + + + ); +} + +function getCode() { + return ` + import { MeshValue } from "@meshsdk/common"; + const value = new MeshValue(); + const singleAsset: Asset = { unit: mockUnit, quantity: "100" }; + value.addAsset(singleAsset); + return value.value; + `; +} + +async function runaddAssetDemo() { + const value = new MeshValue(); + const singleAsset: Asset = { unit: mockUnit, quantity: "100" }; + value.addAsset(singleAsset); + return value.value; +} + +function getCode2() { + return ` + import { MeshValue } from "@meshsdk/common"; + const value = new MeshValue(); + const assets: Asset[] = [ + { unit: mockUnit, quantity: "100" }, + { unit: "lovelace", quantity: "10" }, + { unit: mockUnit, quantity: "100" }, + { unit: "lovelace", quantity: "10" }, + ]; + value.addAssets(assets); + return value.value; + `; +} + +async function runmaddAssetsDemo() { + const value = new MeshValue(); + const assets: Asset[] = [ + { unit: mockUnit, quantity: "100" }, + { unit: "lovelace", quantity: "10" }, + { unit: mockUnit, quantity: "100" }, + { unit: "lovelace", quantity: "10" }, + ]; + value.addAssets(assets); + return value.value; +} + +function getCode3() { + return ` + import { MeshValue } from "@meshsdk/common"; + const value = new MeshValue(); + value.value = { lovelace: 10n }; + value.negateAsset({ unit: "lovelace", quantity: "5" }); + return value.value; + `; +} + +async function runnegateAssetDemo() { + const value = new MeshValue(); + value.value = { lovelace: 10n }; + value.negateAsset({ unit: "lovelace", quantity: "5" }); + return value.value; +} + +function getCode4() { + return ` + import { MeshValue } from "@meshsdk/common"; + const value = new MeshValue(); + value.value = { lovelace: 20n, [mockUnit]: 10n }; + value.negateAssets([ + { unit: "lovelace", quantity: "5" }, + { unit: mockUnit, quantity: "3" }, + ]); + return value.value; + `; +} + +async function runtonegateAssetsDemo() { + const value = new MeshValue(); + value.value = { lovelace: 20n, [mockUnit]: 10n }; + value.negateAssets([ + { unit: "lovelace", quantity: "5" }, + { unit: mockUnit, quantity: "3" }, + ]); + return value.value; +} + +function getCode5() { + return ` + import { MeshValue } from "@meshsdk/common"; + const value1 = new MeshValue(); + value1.value = { lovelace: 20n, [mockUnit]: 10n }; + const value2 = new MeshValue(); + value2.value = { lovelace: 10n, [mockUnit]: 5n }; + return value1.merge(value2).value; + `; +} + +async function runmergeDemo() { + const value1 = new MeshValue(); + value1.value = { lovelace: 20n, [mockUnit]: 10n }; + const value2 = new MeshValue(); + value2.value = { lovelace: 10n, [mockUnit]: 5n }; + return value1.merge(value2).value; +} diff --git a/apps/playground/src/pages/apis/data/value/toassets-convertor.tsx b/apps/playground/src/pages/apis/data/value/toassets-convertor.tsx new file mode 100644 index 00000000..f6a61621 --- /dev/null +++ b/apps/playground/src/pages/apis/data/value/toassets-convertor.tsx @@ -0,0 +1,54 @@ +import { Asset, MeshValue, Value, value } from "@meshsdk/common"; + +import LiveCodeDemo from "~/components/sections/live-code-demo"; +import TwoColumnsScroll from "~/components/sections/two-columns-scroll"; + +export default function ToassetsConvertor() { + return ( + + ); +} + +function Left() { + return ( + <> +

+ toAssets Convert the MeshValue object into an array of + Asset +

+ + ); +} + +function Right() { + async function runtoassetsDemo() { + const val: Asset[] = [{ unit: "lovelace", quantity: "1000000" }]; + const plutusValue: Value = value(val); + const assets: Asset[] = MeshValue.fromValue(plutusValue).toAssets(); + return assets; + } + + let code = ` + import { MeshValue } from "@meshsdk/common"; + const val: Asset[] = [{ unit: "lovelace", quantity: "1000000" }]; + const plutusValue: Value = value(val); + const assets: Asset[] = MeshValue.fromValue(plutusValue).toAssets(); + return assets; + `; + + return ( + <> + + + ); +} diff --git a/apps/playground/src/pages/apis/data/value/todata-convertor.tsx b/apps/playground/src/pages/apis/data/value/todata-convertor.tsx new file mode 100644 index 00000000..8b519b42 --- /dev/null +++ b/apps/playground/src/pages/apis/data/value/todata-convertor.tsx @@ -0,0 +1,84 @@ +import { + Asset, + MeshValue, + MValue, + mValue, + Value, + value, +} from "@meshsdk/common"; + +import LiveCodeDemo from "~/components/sections/live-code-demo"; +import TwoColumnsScroll from "~/components/sections/two-columns-scroll"; + +export default function TodataConvertor() { + return ( + + ); +} + +function Left() { + return ( + <> +

+ toData Convert the MashValue object into Cardano data Value + in Mesh Data type +

+ + ); +} + +function Right() { + async function runtodataDemo() { + const val: Asset[] = [ + { + unit: "baefdc6c5b191be372a794cd8d40d839ec0dbdd3c28957267dc817001234", + quantity: "100", + }, + { + unit: "baefdc6c5b191be372a794cd8d40d839ec0dbdd3c28957267dc817001234", + quantity: "200", + }, + ]; + const plutusValue: Value = value(val); + const data = MeshValue.fromValue(plutusValue).toData(); + const expected: MValue = mValue(val); + if (JSON.stringify(expected) === JSON.stringify(data)) { + return true; + } + } + + let code = ` + import { MeshValue } from "@meshsdk/common"; + const val: Asset[] = [ + { + unit: "baefdc6c5b191be372a794cd8d40d839ec0dbdd3c28957267dc817001234", + quantity: "100", + }, + { + unit: "baefdc6c5b191be372a794cd8d40d839ec0dbdd3c28957267dc817001234", + quantity: "200", + }, + ]; + const plutusValue: Value = value(val); + const data = MeshValue.fromValue(plutusValue).toData(); + const expected: MValue = mValue(val); + if (JSON.stringify(expected) === JSON.stringify(data)) { + return true; + `; + + return ( + <> + + + ); +} diff --git a/apps/playground/src/pages/apis/data/value/tojson-convertor.tsx b/apps/playground/src/pages/apis/data/value/tojson-convertor.tsx new file mode 100644 index 00000000..acf57939 --- /dev/null +++ b/apps/playground/src/pages/apis/data/value/tojson-convertor.tsx @@ -0,0 +1,97 @@ +import { Asset, integer, MeshValue } from "@meshsdk/common"; +import { assocMap, currencySymbol, tokenName } from "@meshsdk/core"; + +import LiveCodeDemo from "~/components/sections/live-code-demo"; +import TwoColumnsScroll from "~/components/sections/two-columns-scroll"; + +export default function TojsonConvertor() { + return ( + + ); +} + +function Left() { + return ( + <> +

+ toJSON Converts the MeshValue object into a JSON + representation of Cardano data Value +

+ + ); +} + +function Right() { + async function runtoJSONDemo() { + const assets: Asset[] = [ + { unit: "lovelace", quantity: "1000000" }, + { + unit: "c21d710605bb00e69f3c175150552fc498316d80e7efdb1b186db38c000643b04d65736820676f6f64", + quantity: "500", + }, + ]; + + const expectedValue = assocMap([ + [currencySymbol(""), assocMap([[tokenName(""), integer(1000000)]])], + [ + currencySymbol( + "c21d710605bb00e69f3c175150552fc498316d80e7efdb1b186db38c", + ), + assocMap([[tokenName("000643b04d65736820676f6f64"), integer(500)]]), + ], + ]); + + const meshValue = new MeshValue(); + meshValue.toAssets = () => assets; + + const jsonValue = meshValue.toJSON(); + if (JSON.stringify(jsonValue) === JSON.stringify(expectedValue)) { + return true; + } + } + + let code = ` + import { MeshValue } from "@meshsdk/common"; + const assets: Asset[] = [ + { unit: "lovelace", quantity: "1000000" }, + { + unit: "c21d710605bb00e69f3c175150552fc498316d80e7efdb1b186db38c000643b04d65736820676f6f64", + quantity: "500", + }, + ]; + + const expectedValue = assocMap([ + [currencySymbol(""), assocMap([[tokenName(""), integer(1000000)]])], + [ + currencySymbol( + "c21d710605bb00e69f3c175150552fc498316d80e7efdb1b186db38c", + ), + assocMap([[tokenName("000643b04d65736820676f6f64"), integer(500)]]), + ], + ]); + + const meshValue = new MeshValue(); + meshValue.toAssets = () => assets; + + const jsonValue = meshValue.toJSON(); + if (JSON.stringify(jsonValue) === JSON.stringify(expectedValue)) { + return true; + } + `; + + return ( + <> + + + ); +} diff --git a/apps/playground/src/pages/apis/data/value/units-accessor.tsx b/apps/playground/src/pages/apis/data/value/units-accessor.tsx new file mode 100644 index 00000000..c266b55e --- /dev/null +++ b/apps/playground/src/pages/apis/data/value/units-accessor.tsx @@ -0,0 +1,56 @@ +import { MeshValue } from "@meshsdk/common"; + +import LiveCodeDemo from "~/components/sections/live-code-demo"; +import TwoColumnsScroll from "~/components/sections/two-columns-scroll"; + +export default function UnitsAccessor() { + return ( + + ); +} + +function Left() { + return ( + <> +

+ units get all asset units with no parameters (e.g. unit) + needed +

+ + ); +} + +function Right() { + async function rungetDemo() { + const value = new MeshValue({ + lovelace: 20n, + baefdc6c5b191be372a794cd8d40d839ec0dbdd3c28957267dc817001234: 10n, + }); + return value.units(); + } + + let code = ` + import { MeshValue } from "@meshsdk/common"; + const value = new MeshValue({ + lovelace: 20n, + "baefdc6c5b191be372a794cd8d40d839ec0dbdd3c28957267dc817001234": 10n, + }); + return value.units(); + `; + + return ( + <> + + + ); +} diff --git a/apps/playground/src/pages/apis/data/value/value-convertor.tsx b/apps/playground/src/pages/apis/data/value/value-convertor.tsx new file mode 100644 index 00000000..b641b43b --- /dev/null +++ b/apps/playground/src/pages/apis/data/value/value-convertor.tsx @@ -0,0 +1,72 @@ +import { + Asset, + byteString, + dict, + Dict, + Integer, + integer, + Value, + value, +} from "@meshsdk/common"; + +import LiveCodeDemo from "~/components/sections/live-code-demo"; +import TwoColumnsScroll from "~/components/sections/two-columns-scroll"; + +export default function ValueConvertor() { + return ( + + ); +} + +function Left() { + return ( + <> +

+ value converts assets into Cardano data Value in JSON with + parameters: +

+
    +
  • + assets - Asset[] to convert +
  • +
+ + ); +} + +function Right() { + async function runvalueDemo() { + const val: Asset[] = [{ unit: "lovelace", quantity: "1000000" }]; + const datum: Value = value(val); + const nameMap = dict([[byteString(""), integer(1000000)]]); + const valMap = dict>([[byteString(""), nameMap]]); + if (JSON.stringify(datum) === JSON.stringify(valMap)) { + return true; + } + } + + let code = ` + const val: Asset[] = [{ unit: "lovelace", quantity: "1000000" }]; + const datum: Value = value(val); + const nameMap = dict([[byteString(""), integer(1000000)]]); + const valMap = dict>([[byteString(""), nameMap]]); + if (JSON.stringify(datum) === JSON.stringify(valMap)) { + return true; + `; + + return ( + <> + + + ); +} diff --git a/apps/playground/src/pages/apis/utilities/deserializers/deserialize-address.tsx b/apps/playground/src/pages/apis/utilities/deserializers/deserialize-address.tsx new file mode 100644 index 00000000..3e78bec6 --- /dev/null +++ b/apps/playground/src/pages/apis/utilities/deserializers/deserialize-address.tsx @@ -0,0 +1,63 @@ +import { useState } from "react"; + +import { deserializeAddress } from "@meshsdk/core"; + +import Input from "~/components/form/input"; +import InputTable from "~/components/sections/input-table"; +import LiveCodeDemo from "~/components/sections/live-code-demo"; +import TwoColumnsScroll from "~/components/sections/two-columns-scroll"; +import { demoAddresses } from "~/data/cardano"; + +export default function DeserializeAddress() { + return ( + + ); +} + +function Left() { + return ( + <> +

+ Deserialize bech32 address into payment and staking parts, with + visibility of whether they are script or key hash. +

+ + ); +} + +function Right() { + const [userInput, setUserInput] = useState( + demoAddresses.testnetPayment, + ); + + async function runDemo() { + return deserializeAddress(userInput); + } + + let codeSnippet = `deserializeAddress('${userInput}');`; + + return ( + + setUserInput(e.target.value)} + label="Address" + key={0} + />, + ]} + /> + + ); +} diff --git a/apps/playground/src/pages/apis/utilities/deserializers/deserialize-datum.tsx b/apps/playground/src/pages/apis/utilities/deserializers/deserialize-datum.tsx new file mode 100644 index 00000000..595d73eb --- /dev/null +++ b/apps/playground/src/pages/apis/utilities/deserializers/deserialize-datum.tsx @@ -0,0 +1,57 @@ +import { useState } from "react"; + +import { deserializeDatum } from "@meshsdk/core"; + +import Input from "~/components/form/input"; +import InputTable from "~/components/sections/input-table"; +import LiveCodeDemo from "~/components/sections/live-code-demo"; +import TwoColumnsScroll from "~/components/sections/two-columns-scroll"; + +export default function DeserializeDatum() { + return ( + + ); +} + +function Left() { + return ( + <> +

Deserialize a datum from a CBOR string to JSON object.

+ + ); +} + +function Right() { + const [userInput, setUserInput] = useState(""); + + async function runDemo() { + return deserializeDatum(userInput); + } + + let codeSnippet = `deserializeDatum('${userInput}');`; + + return ( + + setUserInput(e.target.value)} + label="Datum" + key={0} + />, + ]} + /> + + ); +} diff --git a/apps/playground/src/pages/apis/utilities/deserializers/deserialize-poolid.tsx b/apps/playground/src/pages/apis/utilities/deserializers/deserialize-poolid.tsx new file mode 100644 index 00000000..bbfe34e9 --- /dev/null +++ b/apps/playground/src/pages/apis/utilities/deserializers/deserialize-poolid.tsx @@ -0,0 +1,58 @@ +import { useState } from "react"; + +import { deserializePoolId } from "@meshsdk/core"; + +import Input from "~/components/form/input"; +import InputTable from "~/components/sections/input-table"; +import LiveCodeDemo from "~/components/sections/live-code-demo"; +import TwoColumnsScroll from "~/components/sections/two-columns-scroll"; +import { demoPool } from "~/data/cardano"; + +export default function DeserializePoolId() { + return ( + + ); +} + +function Left() { + return ( + <> +

Deserialize a script from a poolxxxx to Ed25519 key hash.

+ + ); +} + +function Right() { + const [userInput, setUserInput] = useState(demoPool); + + async function runDemo() { + return deserializePoolId(userInput); + } + + let codeSnippet = `deserializePoolId('${userInput}');`; + + return ( + + setUserInput(e.target.value)} + label="Pool Id" + key={0} + />, + ]} + /> + + ); +} diff --git a/apps/playground/src/pages/apis/utilities/deserializers/index.tsx b/apps/playground/src/pages/apis/utilities/deserializers/index.tsx index 6df1900e..d81177a2 100644 --- a/apps/playground/src/pages/apis/utilities/deserializers/index.tsx +++ b/apps/playground/src/pages/apis/utilities/deserializers/index.tsx @@ -4,10 +4,15 @@ import SidebarFullwidth from "~/components/layouts/sidebar-fullwidth"; import TitleIconDescriptionBody from "~/components/sections/title-icon-description-body"; import Metatags from "~/components/site/metatags"; import { metaDeserializers } from "~/data/links-utilities"; +import DeserializeAddress from "./deserialize-address"; +import DeserializeDatum from "./deserialize-datum"; +import DeserializePoolId from "./deserialize-poolid"; const ReactPage: NextPage = () => { const sidebarItems = [ - { label: "Coming soon", to: "resolveDataHash" }, + { label: "Deserialize Address", to: "deserializeAddress" }, + { label: "Deserialize Datum", to: "deserializeDatum" }, + { label: "Deserialize Pool Id", to: "deserializePoolId" }, ]; return ( @@ -24,6 +29,10 @@ const ReactPage: NextPage = () => { > <> + + + + ); diff --git a/apps/playground/src/pages/apis/utilities/deserializers/resolve-data-hash.tsx b/apps/playground/src/pages/apis/utilities/deserializers/resolve-data-hash.tsx deleted file mode 100644 index ae59bbb5..00000000 --- a/apps/playground/src/pages/apis/utilities/deserializers/resolve-data-hash.tsx +++ /dev/null @@ -1,70 +0,0 @@ -import { useState } from "react"; -import Link from "~/components/link"; - -import { Data } from "@meshsdk/core"; -import { resolveDataHash } from "@meshsdk/core"; - -import Input from "~/components/form/input"; -import InputTable from "~/components/sections/input-table"; -import LiveCodeDemo from "~/components/sections/live-code-demo"; -import TwoColumnsScroll from "~/components/sections/two-columns-scroll"; - -export default function ResolveDataHash() { - return ( - - ); -} - -function Left() { - return ( - <> -

- Converts datum into hash. Getting the hash is useful when you need to - query for the UTXO that contain the assets you need for your - transaction's input. -

-

- Explore Transaction to learn more - about designing Datum, and learn how to query for UTXOs containing the - datum hash. -

- - ); -} - -function Right() { - const [userInput, setUserInput] = useState("supersecretdatum"); - - async function runDemo() { - const datum: Data = userInput; - const dataHash = resolveDataHash(datum); - return dataHash; - } - - let codeSnippet = `resolveDataHash('${userInput}');`; - - return ( - - setUserInput(e.target.value)} - label="Datum" - key={0} - />, - ]} - /> - - ); -} diff --git a/apps/playground/src/pages/apis/utilities/serializers/index.tsx b/apps/playground/src/pages/apis/utilities/serializers/index.tsx index 2dac4694..e805c9d9 100644 --- a/apps/playground/src/pages/apis/utilities/serializers/index.tsx +++ b/apps/playground/src/pages/apis/utilities/serializers/index.tsx @@ -4,9 +4,20 @@ import SidebarFullwidth from "~/components/layouts/sidebar-fullwidth"; import TitleIconDescriptionBody from "~/components/sections/title-icon-description-body"; import Metatags from "~/components/site/metatags"; import { metaSerializers } from "~/data/links-utilities"; +import SerializeAddressObj from "./serialize-address-obj"; +import SerializeNativeScript from "./serialize-native-script"; +import SerializePlutusScript from "./serialize-plutus-script"; +import SerializePoolId from "./serialize-poolid"; +import SerializeRewardAddress from "./serialize-reward-address"; const ReactPage: NextPage = () => { - const sidebarItems = [{ label: "Coming soon", to: "resolveDataHash" }]; + const sidebarItems = [ + { label: "Serialize Native Script", to: "serializeNativeScript" }, + { label: "Serialize Plutus Script", to: "serializePlutusScript" }, + { label: "Serialize Address Object", to: "serializeAddressObj" }, + { label: "Serialize Pool ID", to: "serializePoolId" }, + { label: "Serialize Reward Address", to: "serializeRewardAddress" }, + ]; return ( <> @@ -22,6 +33,12 @@ const ReactPage: NextPage = () => { > <> + + + + + + ); diff --git a/apps/playground/src/pages/apis/utilities/serializers/resolve-data-hash.tsx b/apps/playground/src/pages/apis/utilities/serializers/resolve-data-hash.tsx deleted file mode 100644 index ae59bbb5..00000000 --- a/apps/playground/src/pages/apis/utilities/serializers/resolve-data-hash.tsx +++ /dev/null @@ -1,70 +0,0 @@ -import { useState } from "react"; -import Link from "~/components/link"; - -import { Data } from "@meshsdk/core"; -import { resolveDataHash } from "@meshsdk/core"; - -import Input from "~/components/form/input"; -import InputTable from "~/components/sections/input-table"; -import LiveCodeDemo from "~/components/sections/live-code-demo"; -import TwoColumnsScroll from "~/components/sections/two-columns-scroll"; - -export default function ResolveDataHash() { - return ( - - ); -} - -function Left() { - return ( - <> -

- Converts datum into hash. Getting the hash is useful when you need to - query for the UTXO that contain the assets you need for your - transaction's input. -

-

- Explore Transaction to learn more - about designing Datum, and learn how to query for UTXOs containing the - datum hash. -

- - ); -} - -function Right() { - const [userInput, setUserInput] = useState("supersecretdatum"); - - async function runDemo() { - const datum: Data = userInput; - const dataHash = resolveDataHash(datum); - return dataHash; - } - - let codeSnippet = `resolveDataHash('${userInput}');`; - - return ( - - setUserInput(e.target.value)} - label="Datum" - key={0} - />, - ]} - /> - - ); -} diff --git a/apps/playground/src/pages/apis/utilities/serializers/serialize-address-obj.tsx b/apps/playground/src/pages/apis/utilities/serializers/serialize-address-obj.tsx new file mode 100644 index 00000000..885660c0 --- /dev/null +++ b/apps/playground/src/pages/apis/utilities/serializers/serialize-address-obj.tsx @@ -0,0 +1,38 @@ +import LiveCodeDemo from "~/components/sections/live-code-demo"; +import TwoColumnsScroll from "~/components/sections/two-columns-scroll"; + +export default function SerializeAddressObj() { + return ( + + ); +} + +function Left() { + return ( + <> +

Serialize address in Cardano data JSON format into bech32 address.

+ + ); +} + +function Right() { + async function runDemo() { + // return serializeAddressObj(address); + } + + let codeSnippet = ``; + + return ( + + ); +} diff --git a/apps/playground/src/pages/apis/utilities/serializers/serialize-native-script.tsx b/apps/playground/src/pages/apis/utilities/serializers/serialize-native-script.tsx new file mode 100644 index 00000000..d39e0ca1 --- /dev/null +++ b/apps/playground/src/pages/apis/utilities/serializers/serialize-native-script.tsx @@ -0,0 +1,65 @@ +import { + deserializeAddress, + NativeScript, + serializeNativeScript, +} from "@meshsdk/core"; + +import LiveCodeDemo from "~/components/sections/live-code-demo"; +import TwoColumnsScroll from "~/components/sections/two-columns-scroll"; +import { demoAddresses } from "~/data/cardano"; + +export default function SerializeNativeScript() { + return ( + + ); +} + +function Left() { + return ( + <> +

Serialize Native script into bech32 address.

+ + ); +} + +function Right() { + async function runDemo() { + const { pubKeyHash: keyHash } = deserializeAddress( + demoAddresses.testnetPayment, + ); + + const nativeScript: NativeScript = { + type: "all", + scripts: [ + { + type: "before", + slot: "99999999", + }, + { + type: "sig", + keyHash: keyHash, + }, + ], + }; + + const address = serializeNativeScript(nativeScript); + + return address; + } + + let codeSnippet = ``; + + return ( + + ); +} diff --git a/apps/playground/src/pages/apis/utilities/serializers/serialize-plutus-script.tsx b/apps/playground/src/pages/apis/utilities/serializers/serialize-plutus-script.tsx new file mode 100644 index 00000000..86071524 --- /dev/null +++ b/apps/playground/src/pages/apis/utilities/serializers/serialize-plutus-script.tsx @@ -0,0 +1,48 @@ +import { PlutusScript, serializePlutusScript } from "@meshsdk/core"; + +import LiveCodeDemo from "~/components/sections/live-code-demo"; +import TwoColumnsScroll from "~/components/sections/two-columns-scroll"; +import { demoPlutusAlwaysSucceedScript } from "~/data/cardano"; + +export default function SerializePlutusScript() { + return ( + + ); +} + +function Left() { + return ( + <> +

Serialize Plutus script into bech32 address.

+ + ); +} + +function Right() { + async function runDemo() { + const script: PlutusScript = { + code: demoPlutusAlwaysSucceedScript, + version: "V2", + }; + + const address = serializePlutusScript(script); + + return address; + } + + let codeSnippet = ``; + + return ( + + ); +} diff --git a/apps/playground/src/pages/apis/utilities/serializers/serialize-poolid.tsx b/apps/playground/src/pages/apis/utilities/serializers/serialize-poolid.tsx new file mode 100644 index 00000000..3a2b68ff --- /dev/null +++ b/apps/playground/src/pages/apis/utilities/serializers/serialize-poolid.tsx @@ -0,0 +1,38 @@ +import LiveCodeDemo from "~/components/sections/live-code-demo"; +import TwoColumnsScroll from "~/components/sections/two-columns-scroll"; + +export default function SerializePoolId() { + return ( + + ); +} + +function Left() { + return ( + <> +

Resolve the pool ID from hash.

+ + ); +} + +function Right() { + async function runDemo() { + // return serializePoolId(address); + } + + let codeSnippet = ``; + + return ( + + ); +} diff --git a/apps/playground/src/pages/apis/utilities/serializers/serialize-reward-address.tsx b/apps/playground/src/pages/apis/utilities/serializers/serialize-reward-address.tsx new file mode 100644 index 00000000..6c37604c --- /dev/null +++ b/apps/playground/src/pages/apis/utilities/serializers/serialize-reward-address.tsx @@ -0,0 +1,38 @@ +import LiveCodeDemo from "~/components/sections/live-code-demo"; +import TwoColumnsScroll from "~/components/sections/two-columns-scroll"; + +export default function SerializeRewardAddress() { + return ( + + ); +} + +function Left() { + return ( + <> +

Serialize a script hash or key hash into bech32 reward address.

+ + ); +} + +function Right() { + async function runDemo() { + // return serializeRewardAddress(address); + } + + let codeSnippet = ``; + + return ( + + ); +} diff --git a/apps/playground/src/pages/article/elements-of-cardano.mdx b/apps/playground/src/pages/article/elements-of-cardano.mdx new file mode 100644 index 00000000..7767a7ae --- /dev/null +++ b/apps/playground/src/pages/article/elements-of-cardano.mdx @@ -0,0 +1,69 @@ +import LayoutImageHeaderAndBody from "~/components/layouts/image-header-and-body"; +import { articleElementsOfCardano } from "~/data/links-articles"; + +export default function MDXPage({ children }) { + return ( + + {children} + + ); +} + +Blockchain technology has revolutionized the way we think about decentralized systems, providing a secure, transparent, and immutable way to manage digital transactions and data. Among the many blockchain platforms, Cardano stands out as a third-generation blockchain designed to address the limitations of earlier networks like Bitcoin and Ethereum. Its unique architecture, proof-of-stake (PoS) consensus mechanism, and emphasis on scalability, interoperability, and sustainability make Cardano a powerful tool for both developers and enterprises. + +# Public and Permissionless: The Foundation of Decentralization + +Cardano is a public, permissionless blockchain, which means that it is open to anyone who wants to participate. This inclusivity is a cornerstone of the Cardano network, allowing anyone to validate transactions, develop applications, or contribute to the ecosystem without needing prior authorization. In contrast to federated networks like Ripple and Stellar, where a central council controls access, Cardano's permissionless nature ensures that no intermediary can gatekeep the network, fostering a truly decentralized environment. + +The terms "public" and "permissionless" are often used interchangeably in the blockchain space, but they have distinct meanings. A public blockchain is one where anyone can join and participate in the network's activities. This openness is essential for the transparency and security of the blockchain, as it allows for a diverse and distributed set of participants to validate transactions and maintain the network. + +A permissionless blockchain, on the other hand, goes a step further by eliminating the need for any intermediary or central authority to grant access. In a permissionless system, users can interact with the blockchain freely, ensuring that the network remains open and resistant to censorship or control. This combination of public and permissionless characteristics is what makes Cardano a truly decentralized network, where power is distributed among the participants rather than concentrated in a single entity. + +# Layer 2 Solutions and Sidechains: Enhancing Performance + +One of the significant challenges faced by early blockchain networks is scalability. As the number of users and transactions on a blockchain increases, the network can become congested, leading to slower transaction speeds and higher fees. This issue is particularly evident in Ethereum, where high demand has often resulted in network congestion and exorbitant gas fees. + +Cardano addresses these scalability issues through its layered architecture, which includes support for sidechains and layer 2 solutions. These technologies allow Cardano to handle more transactions without compromising on speed or cost, making it an ideal platform for decentralized applications (DApps) and other use cases that require high throughput. + +Layer 2 solutions are protocols that operate on top of the main blockchain, handling transactions off-chain to reduce the load on the main network. By processing transactions off-chain, layer 2 solutions can significantly increase the speed and efficiency of the blockchain while lowering costs for users. These networks still rely on the main blockchain for security, meaning they inherit the same security guarantees as the underlying network. + +Sidechains, on the other hand, are separate blockchains that run in parallel to the main blockchain. While they can interact with the main blockchain, sidechains generally have their own rules and security guarantees. This allows for greater flexibility in how transactions are processed, as sidechains can be optimized for specific use cases without affecting the main network. + +Cardano's architecture is designed to easily accommodate both layer 2 solutions and sidechains, providing a scalable and efficient platform for developers. This flexibility is one of the reasons why Cardano is well-suited for a wide range of applications, from finance and supply chain management to healthcare and education. + +# The Benefits Proof-of-Stake Consensus Mechanism + +At the heart of Cardano's blockchain is its proof-of-stake (PoS) consensus mechanism, known as Ouroboros. Unlike proof-of-work (PoW) systems like Bitcoin, where miners compete to solve complex mathematical problems to validate transactions, PoS relies on validators who are chosen to create new blocks based on the amount of cryptocurrency they hold and are willing to "stake" as collateral. + +The PoS consensus mechanism offers several advantages over PoW, including greater energy efficiency, lower barriers to entry, and enhanced security. Because PoS does not require the intensive computational power needed for PoW, it is much more environmentally friendly. This is particularly important in the context of growing concerns about the energy consumption of blockchain networks. + +In addition to its environmental benefits, PoS also lowers the barriers to entry for participants, as users do not need expensive hardware to become validators. This democratization of the validation process helps to further decentralize the network, as more users can participate in maintaining the blockchain. + +Cardano's implementation of PoS through Ouroboros is also designed with security in mind. The protocol has been rigorously tested and peer-reviewed by experts in the field, ensuring that it meets the highest standards of cryptographic security. This commitment to security is one of the reasons why Cardano has gained widespread adoption and trust among users and developers. + +# The Role of ADA in the Cardano Ecosystem + +Cardano's native cryptocurrency, ADA, plays a crucial role in the network's ecosystem. ADA is used to pay for transaction fees, participate in governance, and stake in the PoS system. By staking ADA, users can help secure the network and earn rewards in the form of additional ADA. This incentive structure encourages active participation in the network, helping to maintain its security and stability. + +Beyond its role in the PoS system, ADA is also a key player in the rapidly growing decentralized finance (DeFi) space. Cardano's infrastructure supports the development of smart contracts and DApps, enabling the creation of decentralized financial products and services. These include everything from decentralized exchanges (DEXs) and lending platforms to stablecoins and tokenized assets. + +By leveraging ADA and Cardano's scalable infrastructure, developers can build DeFi applications that are fast, secure, and accessible to users around the world. This has the potential to disrupt traditional financial systems by providing a more inclusive and transparent alternative. + +# Smart Contracts and Native Assets on Cardano + +One of the most significant advancements in blockchain technology is the development of smart contracts—self-executing contracts with the terms of the agreement directly written into code. Cardano supports smart contracts, allowing developers to create automated, trustless applications that can operate without the need for intermediaries. + +Cardano's smart contract platform is powered by Plutus, a development environment that allows developers to write and deploy smart contracts on the Cardano blockchain. Plutus is designed with a focus on security and reliability. In addition to Plutus, Cardano also offers multiple domain-specific language (DSL) for writing smart contracts. This means that developers are not limited to haskell, thus further lowering the barrier to entry for users. + +In addition to smart contracts, Cardano also supports the creation of native assets—custom tokens that can be issued and managed on the Cardano blockchain. Unlike tokens on other blockchains, Cardano's native assets are treated as first-class citizens, meaning they are built into the blockchain's architecture rather than being added on top of it. This integration allows for more efficient and secure handling of assets, making Cardano an attractive platform for tokenization and the creation of digital assets. + +# Conclusion + +Cardano represents a significant advancement in blockchain technology, offering a scalable, secure, and flexible platform that is well-suited for a wide range of applications. Its unique combination of public, permissionless infrastructure, proof-of-stake consensus, and support for smart contracts and native assets makes it a powerful tool for developers and enterprises alike. + +As the blockchain space continues to evolve, Cardano is poised to play a leading role in shaping the future of decentralized technology. Whether you're a developer looking to build the next generation of DApps or an enterprise seeking to leverage blockchain for your business, Cardano offers the tools and infrastructure you need to succeed. diff --git a/apps/playground/src/pages/blog/typescript-cardano-sdk.mdx b/apps/playground/src/pages/article/typescript-cardano-sdk.mdx similarity index 54% rename from apps/playground/src/pages/blog/typescript-cardano-sdk.mdx rename to apps/playground/src/pages/article/typescript-cardano-sdk.mdx index 49d9d96c..68e1acdc 100644 --- a/apps/playground/src/pages/blog/typescript-cardano-sdk.mdx +++ b/apps/playground/src/pages/article/typescript-cardano-sdk.mdx @@ -1,13 +1,13 @@ import LayoutImageHeaderAndBody from "~/components/layouts/image-header-and-body"; -import { blogMesh20 } from "~/data/links-blogs"; +import { articleMesh20 } from "~/data/links-articles"; export default function MDXPage({ children }) { return ( {children} diff --git a/apps/playground/src/pages/blog/whats-new-in-16.mdx b/apps/playground/src/pages/article/whats-new-in-16.mdx similarity index 55% rename from apps/playground/src/pages/blog/whats-new-in-16.mdx rename to apps/playground/src/pages/article/whats-new-in-16.mdx index 99082f9a..103f9348 100644 --- a/apps/playground/src/pages/blog/whats-new-in-16.mdx +++ b/apps/playground/src/pages/article/whats-new-in-16.mdx @@ -1,13 +1,13 @@ import LayoutImageHeaderAndBody from "~/components/layouts/image-header-and-body"; -import { blogNew16 } from "~/data/links-blogs"; +import { articleNew16 } from "~/data/links-articles"; export default function MDXPage({ children }) { return ( {children} diff --git a/apps/playground/src/pages/smart-contracts/hello-world/common.tsx b/apps/playground/src/pages/smart-contracts/hello-world/common.tsx new file mode 100644 index 00000000..a374c811 --- /dev/null +++ b/apps/playground/src/pages/smart-contracts/hello-world/common.tsx @@ -0,0 +1,26 @@ +import { MeshHelloWorldContract } from "@meshsdk/contract"; +import { BrowserWallet, MeshTxBuilder } from "@meshsdk/core"; + +import { getProvider } from "../../../components/cardano/mesh-wallet"; + +export function getContract(wallet: BrowserWallet) { + const blockchainProvider = getProvider(); + + const meshTxBuilder = new MeshTxBuilder({ + fetcher: blockchainProvider, + submitter: blockchainProvider, + }); + + const contract = new MeshHelloWorldContract({ + mesh: meshTxBuilder, + fetcher: blockchainProvider, + wallet: wallet, + networkId: 0, + }); + + return contract; +} + +export default function Placeholder() { + return <>; +} diff --git a/apps/playground/src/pages/smart-contracts/hello-world/index.tsx b/apps/playground/src/pages/smart-contracts/hello-world/index.tsx new file mode 100644 index 00000000..2a7f7227 --- /dev/null +++ b/apps/playground/src/pages/smart-contracts/hello-world/index.tsx @@ -0,0 +1,93 @@ +import type { NextPage } from "next"; + +import SidebarFullwidth from "~/components/layouts/sidebar-fullwidth"; +import Link from "~/components/link"; +import TitleIconDescriptionBody from "~/components/sections/title-icon-description-body"; +import Metatags from "~/components/site/metatags"; +import Codeblock from "~/components/text/codeblock"; +import { metaGiftcard } from "~/data/links-smart-contracts"; +import { InstallSmartContract } from "../common"; +import HelloWorldLock from "./lock-asset"; +import HelloWorldUnlock from "./unlock-asset"; + +const ReactPage: NextPage = () => { + const sidebarItems = [ + { label: "Lock assets", to: "lockAsset" }, + { label: "Unlock assets", to: "unlockAsset" }, + ]; + + let example = ``; + + example += `import { MeshHelloWorldContract } from "@meshsdk/contract";\n`; + example += `import { MeshTxBuilder } from "@meshsdk/core";\n`; + example += `\n`; + example += `const blockchainProvider = new BlockfrostProvider('');\n`; + example += `\n`; + example += `const meshTxBuilder = new MeshTxBuilder({\n`; + example += ` fetcher: blockchainProvider,\n`; + example += ` submitter: blockchainProvider,\n`; + example += `});\n`; + example += `\n`; + example += `const contract = new MeshHelloWorldContract({\n`; + example += ` mesh: meshTxBuilder,\n`; + example += ` fetcher: blockchainProvider,\n`; + example += ` wallet: wallet,\n`; + example += ` networkId: 0,\n`; + example += `});\n`; + + return ( + <> + + + + <> +

+ Giftcard contract allows users to create a transactions to lock + assets into the smart contract, which can be redeemed by any user. +

+

+ Creating a giftcard will mint a token and send the assets to the + contract. While redeeming will burn the token and send the assets + to the redeemer. +

+ +

+ There are 2 actions (or endpoints) available to interact with this + smart contract: +

+
    +
  • create giftcard
  • +
  • redeem giftcard
  • +
+ + + +

Initialize the contract

+

+ To initialize the contract, we need to initialize a{" "} + provider,{" "} + MeshTxBuilder and MeshGiftCardContract. +

+ +

+ Both on-chain and off-chain codes are open-source and available on{" "} + + Mesh Github Repository + + . +

+ +
+ + + +
+ + ); +}; + +export default ReactPage; diff --git a/apps/playground/src/pages/smart-contracts/hello-world/lock-asset.tsx b/apps/playground/src/pages/smart-contracts/hello-world/lock-asset.tsx new file mode 100644 index 00000000..fe4af4bc --- /dev/null +++ b/apps/playground/src/pages/smart-contracts/hello-world/lock-asset.tsx @@ -0,0 +1,88 @@ +import { useState } from "react"; + +import { Asset } from "@meshsdk/core"; +import { useWallet } from "@meshsdk/react"; + +import Input from "~/components/form/input"; +import InputTable from "~/components/sections/input-table"; +import LiveCodeDemo from "~/components/sections/live-code-demo"; +import TwoColumnsScroll from "~/components/sections/two-columns-scroll"; +import { getContract } from "./common"; + +export default function HelloWorldLock() { + return ( + + ); +} + +function Left() { + return ( + <> +

+ + ); +} + +function Right() { + const { wallet, connected } = useWallet(); + const [userInput, setUserInput] = useState("5000000"); + + async function runDemo() { + const contract = getContract(wallet); + + const assets: Asset[] = [ + { + unit: "lovelace", + quantity: userInput, + }, + ]; + + const tx = await contract.lockAsset(assets); + const signedTx = await wallet.signTx(tx); + const txHash = await wallet.submitTx(signedTx); + return txHash; + } + + let code = ``; + code += `const assets: Asset[] = [\n`; + code += ` {\n`; + code += ` unit: "lovelace",\n`; + code += ` quantity: '${userInput}',\n`; + code += ` },\n`; + code += `];\n`; + code += `\n`; + code += `const tx = await contract.lockAsset(assets);\n`; + code += `const signedTx = await wallet.signTx(tx);\n`; + code += `const txHash = await wallet.submitTx(signedTx);\n`; + + return ( + + setUserInput(e.target.value)} + placeholder="Lovelace amount" + label="Lovelace amount" + key={0} + />, + ]} + /> + + ); +} diff --git a/apps/playground/src/pages/smart-contracts/hello-world/unlock-asset.tsx b/apps/playground/src/pages/smart-contracts/hello-world/unlock-asset.tsx new file mode 100644 index 00000000..e9c346c5 --- /dev/null +++ b/apps/playground/src/pages/smart-contracts/hello-world/unlock-asset.tsx @@ -0,0 +1,87 @@ +import { useState } from "react"; + +import { useWallet } from "@meshsdk/react"; + +import Input from "~/components/form/input"; +import InputTable from "~/components/sections/input-table"; +import LiveCodeDemo from "~/components/sections/live-code-demo"; +import TwoColumnsScroll from "~/components/sections/two-columns-scroll"; +import { getContract } from "./common"; + +export default function HelloWorldUnlock() { + return ( + + ); +} + +function Left() { + return ( + <> +

+ + ); +} + +function Right() { + const { wallet, connected } = useWallet(); + const [userInput, setUserInput] = useState(""); + const [userInput2, setUserInput2] = useState("Hello, World!"); + + async function runDemo() { + const contract = getContract(wallet); + + const utxo = await contract.getUtxoByTxHash(userInput); + + if (utxo === undefined) throw new Error("UTxO not found"); + + const tx = await contract.unlockAsset(utxo, userInput2); + const signedTx = await wallet.signTx(tx, true); + const txHash = await wallet.submitTx(signedTx); + return txHash; + } + + let code = ``; + code += `const utxo = await contract.getUtxoByTxHash('${userInput}');\n`; + code += `\n`; + code += `const tx = await contract.unlockAsset(utxo, '${userInput2}');\n`; + code += `const signedTx = await wallet.signTx(tx);\n`; + code += `const txHash = await wallet.submitTx(signedTx);\n`; + + return ( + + setUserInput(e.target.value)} + placeholder="Tx hash" + label="Tx hash" + key={0} + />, + setUserInput2(e.target.value)} + placeholder="Message" + label="Message" + key={0} + />, + ]} + /> + + ); +} diff --git a/apps/playground/src/pages/smart-contracts/vesting/deposit-fund.tsx b/apps/playground/src/pages/smart-contracts/vesting/deposit-fund.tsx index 6dad39be..4a48f437 100644 --- a/apps/playground/src/pages/smart-contracts/vesting/deposit-fund.tsx +++ b/apps/playground/src/pages/smart-contracts/vesting/deposit-fund.tsx @@ -72,6 +72,25 @@ function Right() { } let code = ``; + code += `const assets: Asset[] = [\n`; + code += ` {\n`; + code += ` unit: "lovelace",\n`; + code += ` quantity: '${userInput}',\n`; + code += ` },\n`; + code += `];\n`; + code += `\n`; + code += `const lockUntilTimeStamp = new Date();\n`; + code += `lockUntilTimeStamp.setMinutes(lockUntilTimeStamp.getMinutes() + 1);\n`; + code += `\n`; + code += `const beneficiary = '${userInput2}';\n`; + code += `\n`; + code += `const tx = await contract.depositFund(\n`; + code += ` assets,\n`; + code += ` lockUntilTimeStamp.getTime(),\n`; + code += ` beneficiary,\n`; + code += `);\n`; + code += `const signedTx = await wallet.signTx(tx);\n`; + code += `const txHash = await wallet.submitTx(signedTx);\n`; return ( + ); +} + +function Left() { + return ( + <> +

+ Vesting contract is a smart contract that locks up funds for a period of + time and allows the owner to withdraw the funds after the lockup period. + Usually, vesting contract defines a beneficiary who can be different + from the original owner. +

+ +

+ When a new employee joins an organization, they typically receive a + promise of compensation to be disbursed after a specified duration of + employment. This arrangement often involves the organization depositing + the funds into a vesting contract, with the employee gaining access to + the funds upon the completion of a predetermined lockup period. Through + the utilization of vesting contracts, organizations establish a + mechanism to encourage employee retention by linking financial rewards + to tenure. +

+ +

On-Chain code

+ +

+ First, we define the datum's shape, as this datum serves as + configuration and contains the different parameters of our vesting + operation. +

+ + + +

+ In this example, we define a `VestingDatum` that contains the following + fields: +

+ +
    +
  • + `lock_until`: The POSIX timestamp in milliseconds until which the + funds are locked. +
  • +
  • + `owner`: The credentials (public key hash) of the owner of the funds. +
  • +
  • + `beneficiary`: The credentials (public key hash) of the beneficiary of + the funds. +
  • +
+ +

+ This datum can be found in + `aiken-vesting/aiken-workspace/lib/vesting/types.ak`. +

+ +

Next, we define the spend validator.

+ + or { + key_signed(ctx.transaction.extra_signatories, datum.owner), + and { + key_signed(ctx.transaction.extra_signatories, datum.beneficiary), + valid_after(ctx.transaction.validity_range, datum.lock_until), + }, + } + _ -> False + } + } +} +`} + /> + +

+ In this example, we define a `vesting` validator that ensures the + following conditions are met: +

+ +
    +
  • The transaction must be signed by owner
  • +
+

Or:

+
    +
  • The transaction must be signed by beneficiary
  • +
  • The transaction must be valid after the lockup period
  • +
+ +

+ This validator can be found in + `aiken-vesting/aiken-workspace/validators/vesting.ak`. +

+ +

How it works

+ +

+ The owner of the funds deposits the funds into the vesting contract. The + funds are locked up until the lockup period expires. +

+ +

+ Transactions can include validity intervals that specify when the + transaction is valid, both from and until a certain time. The ledger + verifies these validity bounds before executing a script and will only + proceed if they are legitimate. +

+ +

+ This approach allows scripts to incorporate a sense of time while + maintaining determinism within the script's context. For instance, if a + transaction has a lower bound `A`, we can infer that the current time is + at least `A`. +

+ +

+ It's important to note that since we don't control the upper bound, a + transaction might be executed even 30 years after the vesting delay. + However, from the script's perspective, this is entirely acceptable. +

+ +

+ The beneficiary can withdraw the funds after the lockup period expires. + The beneficiary can also be different from the owner of the funds. +

+ +

Testing

+ +

+ To test the vesting contract, we have provided the a comphrehensive test + script,you can run tests with `aiken check`. +

+ +

The test script includes the following test cases:

+ +
    +
  • success unlocking
  • +
  • success unlocking with only owner signature
  • +
  • success unlocking with beneficiary signature and time passed
  • +
  • fail unlocking with only beneficiary signature
  • +
  • fail unlocking with only time passed
  • +
+ +

+ We recommend you to check out + `aiken-vesting/aiken-workspace/validators/tests/vesting.ak` to learn + more. +

+ +

Compile and build script

+ +

To compile the script, run the following command:

+ + + +

+ This command will generate a CIP-0057 Plutus blueprint, which you can + find in `aiken-vesting/aiken-workspace/plutus.json`. +

+ +

Off-Chain code

+ +

Deposit funds

+ +

+ First, the owner can deposit funds into the vesting contract. The owner + can specify the lockup period and the beneficiary of the funds. +

+ + + +

+ In this example, we deposit 10 ADA into the vesting contract. The funds + are locked up for 1 minute, and the beneficiary is specified. +

+ +

+ Then, we prepare a few variables to be used in the transaction. We get + the wallet address and the UTXOs of the wallet. We also get the script + address of the vesting contract, to send the funds to the script + address. We also get the owner and beneficiary public key hashes. +

+ + + +

+ Next, we construct the transaction to deposit the funds into the vesting + contract. +

+ + + +

+ In this example, we construct the transaction to deposit the funds into + the vesting contract. We specify the script address of the vesting + contract, the amount to deposit, and the lockup period, owner, and + beneficiary of the funds. +

+ +

Finally, we sign and submit the transaction.

+ + + +

+ To execute this code, ensure you have defined blockfrost key in the + `.env` file. You can also define your wallet mnemonic in + `aiken-vesting/src/configs.ts` file. +

+ +

You can run the following command execute the deposit funds code:

+ + + +

+ Upon successful execution, you will receive a transaction hash. Save + this transaction hash for withdrawing the funds. +

+ +

+ Example of a{" "} + + successful deposit transaction + + . +

+ +

Withdraw funds

+ +

+ After the lockup period expires, the beneficiary can withdraw the funds + from the vesting contract. The owner can also withdraw the funds from + the vesting contract. +

+ +

+ First, let's look for the UTxOs containing the funds locked in the + vesting contract. +

+ + + +

+ In this example, we fetch the UTxOs containing the funds locked in the + vesting contract. We specify the transaction hash of the deposit + transaction. +

+ +

+ Like before, we prepare a few variables to be used in the transaction. + We get the wallet address and the UTXOs of the wallet. We also get the + script address of the vesting contract, to send the funds to the script + address. We also get the owner and beneficiary public key hashes. +

+ + + +

+ Next, we prepare the datum and the slot number to set the transaction + valid interval to be valid only after the slot. +

+ + (vestingUtxo.output.plutusData!); + +const invalidBefore = + unixTimeToEnclosingSlot( + Math.min(datum.fields[0].int as number, Date.now() - 15000), + SLOT_CONFIG_NETWORK.preprod + ) + 1; +`} + /> + +

+ In this example, we prepare the datum and the slot number to set the + transaction valid interval to be valid only after the slot. We get the + lockup period from the datum and set the transaction valid interval to + be valid only after the lockup period. +

+ +

+ Next, we construct the transaction to withdraw the funds from the + vesting contract. +

+ + + +

+ In this example, we construct the transaction to withdraw the funds from + the vesting contract. We specify the UTxO containing the funds locked in + the vesting contract, the script address of the vesting contract, the + wallet address to send the funds to, and the transaction valid interval. +

+ +

+ Finally, we sign and submit the transaction. Notice that since we are + unlocking fund from validator, partial sign has to be specified by + passing a `true` parameter into `wallet.signTx`. +

+ + + +

+ To execute this code, update `aiken-vesting/src/withdraw-fund.ts` with + the transaction hash from the deposit transaction. Ensure you have + defined blockfrost key in the `.env` file. You can also define your + wallet mnemonic in `aiken-vesting/src/configs.ts` file. +

+ +

Run the following command:

+ + + +

+ Example of a{" "} + + successful withdraw transaction + + . +

+ + ); +} diff --git a/apps/playground/src/pages/smart-contracts/vesting/index.tsx b/apps/playground/src/pages/smart-contracts/vesting/index.tsx index f0fee7c0..555d3e1a 100644 --- a/apps/playground/src/pages/smart-contracts/vesting/index.tsx +++ b/apps/playground/src/pages/smart-contracts/vesting/index.tsx @@ -8,12 +8,14 @@ import Codeblock from "~/components/text/codeblock"; import { metaVesting } from "~/data/links-smart-contracts"; import { InstallSmartContract } from "../common"; import VestingDepositFund from "./deposit-fund"; +import VestingFullTutorial from "./full-tutorial"; import VestingWithdrawFund from "./withdraw-fund"; const ReactPage: NextPage = () => { const sidebarItems = [ { label: "Deposit Fund", to: "depositFund" }, { label: "Withdraw Fund", to: "withdrawFund" }, + { label: "Full Tutorial", to: "tutorial" }, ]; let example = ``; @@ -85,6 +87,7 @@ const ReactPage: NextPage = () => { + ); diff --git a/apps/playground/src/pages/smart-contracts/vesting/withdraw-fund.tsx b/apps/playground/src/pages/smart-contracts/vesting/withdraw-fund.tsx index d67e15b5..a8675786 100644 --- a/apps/playground/src/pages/smart-contracts/vesting/withdraw-fund.tsx +++ b/apps/playground/src/pages/smart-contracts/vesting/withdraw-fund.tsx @@ -57,6 +57,10 @@ function Right() { } let code = ``; + code += `const utxo = await contract.getUtxoByTxHash('${userInput}');\n\n`; + code += `const tx = await contract.withdrawFund(utxo);\n`; + code += `const signedTx = await wallet.signTx(tx, true);\n`; + code += `const txHash = await wallet.submitTx(signedTx);\n`; return ( {" "} and download the latest release. Under Assets, you will - find the Source code (zip) file. + find the yaci-devkit-version.zip file.

Extract the zip file to a folder on your system. This folder will be diff --git a/apps/playground/src/pages/yaci/getting-started/start.tsx b/apps/playground/src/pages/yaci/getting-started/start.tsx index 0feebd38..d808319b 100644 --- a/apps/playground/src/pages/yaci/getting-started/start.tsx +++ b/apps/playground/src/pages/yaci/getting-started/start.tsx @@ -26,10 +26,10 @@ function Left() {

To create a new devnet, run the following command from yaci-cli:

create-node -o --start`} />

- To create a new devnet with Conway era, run the following command from + To create a new devnet with Babbage era, run the following command from yaci-cli:

- create-node -o --era conway --start`} /> + create-node -o --era babbage --start`} />

To start a devnet with zero fees, run the following command from yaci-cli: diff --git a/package-lock.json b/package-lock.json index ee52fc83..e72935cf 100644 --- a/package-lock.json +++ b/package-lock.json @@ -345,103 +345,103 @@ } }, "node_modules/@algolia/client-abtesting": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/@algolia/client-abtesting/-/client-abtesting-5.1.1.tgz", - "integrity": "sha512-Zz4c1VSwBKu1qD44/9zYd7OjcwsfiPJkqKArYcQuJJihHUwodfnmf4Agi29M07exa8dySo9SHYcWKRxrpkKRiA==", + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/@algolia/client-abtesting/-/client-abtesting-5.2.3.tgz", + "integrity": "sha512-YGBK07pVEheCqI32qXDCsCyztvaa8M+MRzjGmdaOylfhDRFsyuGeAENBLQHppGRIKhR75VqWAUTsFb6Dq7IrJA==", "peer": true, "dependencies": { - "@algolia/client-common": "5.1.1", - "@algolia/requester-browser-xhr": "5.1.1", - "@algolia/requester-node-http": "5.1.1" + "@algolia/client-common": "5.2.3", + "@algolia/requester-browser-xhr": "5.2.3", + "@algolia/requester-node-http": "5.2.3" }, "engines": { "node": ">= 14.0.0" } }, "node_modules/@algolia/client-analytics": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/@algolia/client-analytics/-/client-analytics-5.1.1.tgz", - "integrity": "sha512-0IjlWzzUtIHaoxqlHPUHCPzQQdzhUXThLHUlexeSMZSqqibmC5Ku6Hz3LFMBDGxoCC6L+qWgyd2x6aE9XupaNA==", + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/@algolia/client-analytics/-/client-analytics-5.2.3.tgz", + "integrity": "sha512-1mwi1J0imohlz4QfTTlwxkAZeNgCTfc4KaI0XFacazTTdSlVPtzHYKgA2mLOCRmKJ0Bm5aoylNexcfkfBy3acw==", "peer": true, "dependencies": { - "@algolia/client-common": "5.1.1", - "@algolia/requester-browser-xhr": "5.1.1", - "@algolia/requester-node-http": "5.1.1" + "@algolia/client-common": "5.2.3", + "@algolia/requester-browser-xhr": "5.2.3", + "@algolia/requester-node-http": "5.2.3" }, "engines": { "node": ">= 14.0.0" } }, "node_modules/@algolia/client-common": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/@algolia/client-common/-/client-common-5.1.1.tgz", - "integrity": "sha512-jkQNQbGY+XQB3Eln7wqqdUZKBzG8lETcsaUk5gcMc6iIwyN/qW0v0fhpKPH+Kli+BImLxo0CWk12CvVvx2exWA==", + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/@algolia/client-common/-/client-common-5.2.3.tgz", + "integrity": "sha512-zqfcbgjYR72Y/rx/+/6g5Li/eV33yhRq5mkGbU06JYBzvGq6viy0gZl1ckCFhLLifKzXZ4yzUQTw/KG6FV+smg==", "peer": true, "engines": { "node": ">= 14.0.0" } }, "node_modules/@algolia/client-personalization": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/@algolia/client-personalization/-/client-personalization-5.1.1.tgz", - "integrity": "sha512-Cf20l5ZyHkm7I+DnQ3d1rbgUMkx4GcLhN4AGBfN/MDhSQNG7mORCc4RKRvg62vG95NAElbfx1JcnAuLLucQ3Rw==", + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/@algolia/client-personalization/-/client-personalization-5.2.3.tgz", + "integrity": "sha512-DBMQjOwKl2r/bzDLTS2sgXuorXNkEifVqWrKr7Gj0poU8fp8Oj8K2FQ/mc6o7PCIOVLwjchRYBkeCdxavakwmA==", "peer": true, "dependencies": { - "@algolia/client-common": "5.1.1", - "@algolia/requester-browser-xhr": "5.1.1", - "@algolia/requester-node-http": "5.1.1" + "@algolia/client-common": "5.2.3", + "@algolia/requester-browser-xhr": "5.2.3", + "@algolia/requester-node-http": "5.2.3" }, "engines": { "node": ">= 14.0.0" } }, "node_modules/@algolia/client-search": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/@algolia/client-search/-/client-search-5.1.1.tgz", - "integrity": "sha512-SFpb3FI/VouGou/vpuS7qeCA5Y/KpV42P6CEA/1MZQtl/xJkl6PVjikb+Q9YadeHi2jtDV/aQ6PyiVDnX4PQcw==", + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/@algolia/client-search/-/client-search-5.2.3.tgz", + "integrity": "sha512-xXdCg8vpiwE8gqSyvjxq8V3qbFa+gHasY5epIz718IByWv3WKLLi/n4SMIfB/zRwXTLVWeGOH/UJSz5VCnAAqg==", "peer": true, "dependencies": { - "@algolia/client-common": "5.1.1", - "@algolia/requester-browser-xhr": "5.1.1", - "@algolia/requester-node-http": "5.1.1" + "@algolia/client-common": "5.2.3", + "@algolia/requester-browser-xhr": "5.2.3", + "@algolia/requester-node-http": "5.2.3" }, "engines": { "node": ">= 14.0.0" } }, "node_modules/@algolia/recommend": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/@algolia/recommend/-/recommend-5.1.1.tgz", - "integrity": "sha512-ebtbWTXBSaeg7DarDU3IXjbJgcVM6mtoHeK/VvMka+KAaJXoVsMfD402qs4cN0gaw0bAy3dNUmXkV0nNi1kq4g==", + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/@algolia/recommend/-/recommend-5.2.3.tgz", + "integrity": "sha512-Ad+KrWPldCq8/INnpGJ6pxEwLCtU/vb2wZjy9V3CnSmxAxJ8kdCsbAdIsb8BxVR/Opgc62FwPKzkYEtp/AaDyw==", "peer": true, "dependencies": { - "@algolia/client-common": "5.1.1", - "@algolia/requester-browser-xhr": "5.1.1", - "@algolia/requester-node-http": "5.1.1" + "@algolia/client-common": "5.2.3", + "@algolia/requester-browser-xhr": "5.2.3", + "@algolia/requester-node-http": "5.2.3" }, "engines": { "node": ">= 14.0.0" } }, "node_modules/@algolia/requester-browser-xhr": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/@algolia/requester-browser-xhr/-/requester-browser-xhr-5.1.1.tgz", - "integrity": "sha512-NXmN1ujJCj5GlJQaMK6DbdiXdcf6nhRef/X40lu9TYi71q9xTo/5RPMI0K2iOp6g07S26BrXFOz6RSV3Ny4LLw==", + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/@algolia/requester-browser-xhr/-/requester-browser-xhr-5.2.3.tgz", + "integrity": "sha512-lezcE4E7ax7JkDGDKA/xAnyAY9p9LZ4AxzsyL0pksqUpOvn4U0msP553M2yJRfsxxdGDp15noCnPuRsh7u8dMg==", "peer": true, "dependencies": { - "@algolia/client-common": "5.1.1" + "@algolia/client-common": "5.2.3" }, "engines": { "node": ">= 14.0.0" } }, "node_modules/@algolia/requester-node-http": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/@algolia/requester-node-http/-/requester-node-http-5.1.1.tgz", - "integrity": "sha512-xwrgnNTIzgxDEx6zuCKSKTPzQLA8fL/WZiVB6fRpIu5agLMjoAi0cWA5YSDbo+2FFxqVgLqKY/Jz6mKmWtY15Q==", + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/@algolia/requester-node-http/-/requester-node-http-5.2.3.tgz", + "integrity": "sha512-xTxsRnJqxG1dylIkxmflrHO9LJfJKjSHqEF5yGdRrtnqIEvb2hiQPCHm2XwqxMa3NBcf6lmydGfJqhPLnRJwtw==", "peer": true, "dependencies": { - "@algolia/client-common": "5.1.1" + "@algolia/client-common": "5.2.3" }, "engines": { "node": ">= 14.0.0" @@ -569,12 +569,12 @@ } }, "node_modules/@babel/generator": { - "version": "7.25.5", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.25.5.tgz", - "integrity": "sha512-abd43wyLfbWoxC6ahM8xTkqLpGB2iWBVyuKC9/srhFunCd1SDNrV1s72bBpK4hLj8KLzHBBcOblvLQZBNw9r3w==", + "version": "7.25.6", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.25.6.tgz", + "integrity": "sha512-VPC82gr1seXOpkjAAKoLhP50vx4vGNlF4msF64dSFq1P8RfB+QAuJWGHPXXPc8QyfVWwwB/TNNU4+ayZmHNbZw==", "dev": true, "dependencies": { - "@babel/types": "^7.25.4", + "@babel/types": "^7.25.6", "@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/trace-mapping": "^0.3.25", "jsesc": "^2.5.1" @@ -689,13 +689,13 @@ } }, "node_modules/@babel/helpers": { - "version": "7.25.0", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.25.0.tgz", - "integrity": "sha512-MjgLZ42aCm0oGjJj8CtSM3DB8NOOf8h2l7DCTePJs29u+v7yO/RBX9nShlKMgFnRks/Q4tBAe7Hxnov9VkGwLw==", + "version": "7.25.6", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.25.6.tgz", + "integrity": "sha512-Xg0tn4HcfTijTwfDwYlvVCl43V6h4KyVVX2aEm4qdO/PC6L2YvzLHFdmxhoeSA3eslcE6+ZVXHgWwopXYLNq4Q==", "dev": true, "dependencies": { "@babel/template": "^7.25.0", - "@babel/types": "^7.25.0" + "@babel/types": "^7.25.6" }, "engines": { "node": ">=6.9.0" @@ -788,12 +788,12 @@ } }, "node_modules/@babel/parser": { - "version": "7.25.4", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.25.4.tgz", - "integrity": "sha512-nq+eWrOgdtu3jG5Os4TQP3x3cLA8hR8TvJNjD8vnPa20WGycimcparWnLK4jJhElTK6SDyuJo1weMKO/5LpmLA==", + "version": "7.25.6", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.25.6.tgz", + "integrity": "sha512-trGdfBdbD0l1ZPmcJ83eNxB9rbEax4ALFTF7fN386TMYbeCQbyme5cOEXQhbGXKebwGaB/J52w1mrklMcbgy6Q==", "dev": true, "dependencies": { - "@babel/types": "^7.25.4" + "@babel/types": "^7.25.6" }, "bin": { "parser": "bin/babel-parser.js" @@ -854,12 +854,12 @@ } }, "node_modules/@babel/plugin-syntax-import-attributes": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.24.7.tgz", - "integrity": "sha512-hbX+lKKeUMGihnK8nvKqmXBInriT3GVjzXKFriV3YC6APGxMbP8RZNFwy91+hocLXq90Mta+HshoB31802bb8A==", + "version": "7.25.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.25.6.tgz", + "integrity": "sha512-sXaDXaJN9SNLymBdlWFA+bjzBhFD617ZaFiY13dGt7TVslVvVgA6fkZOP7Ki3IGElC45lwHdOTrCtKZGVAWeLQ==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-plugin-utils": "^7.24.8" }, "engines": { "node": ">=6.9.0" @@ -1042,9 +1042,9 @@ } }, "node_modules/@babel/runtime": { - "version": "7.25.4", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.25.4.tgz", - "integrity": "sha512-DSgLeL/FNcpXuzav5wfYvHCGvynXkJbn3Zvc3823AEe9nPwW9IK4UoCSS5yGymmQzN0pCPvivtgS6/8U2kkm1w==", + "version": "7.25.6", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.25.6.tgz", + "integrity": "sha512-VBj9MYyDb9tuLq7yzqjgzt6Q+IBQLrGZfdjOekyEirZPHxXWoTSGUTMrpsfi58Up73d13NfYLv8HT9vmznjzhQ==", "dependencies": { "regenerator-runtime": "^0.14.0" }, @@ -1067,16 +1067,16 @@ } }, "node_modules/@babel/traverse": { - "version": "7.25.4", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.25.4.tgz", - "integrity": "sha512-VJ4XsrD+nOvlXyLzmLzUs/0qjFS4sK30te5yEFlvbbUNEgKaVb2BHZUpAL+ttLPQAHNrsI3zZisbfha5Cvr8vg==", + "version": "7.25.6", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.25.6.tgz", + "integrity": "sha512-9Vrcx5ZW6UwK5tvqsj0nGpp/XzqthkT0dqIc9g1AdtygFToNtTF67XzYS//dm+SAK9cp3B9R4ZO/46p63SCjlQ==", "dev": true, "dependencies": { "@babel/code-frame": "^7.24.7", - "@babel/generator": "^7.25.4", - "@babel/parser": "^7.25.4", + "@babel/generator": "^7.25.6", + "@babel/parser": "^7.25.6", "@babel/template": "^7.25.0", - "@babel/types": "^7.25.4", + "@babel/types": "^7.25.6", "debug": "^4.3.1", "globals": "^11.1.0" }, @@ -1094,9 +1094,9 @@ } }, "node_modules/@babel/types": { - "version": "7.25.4", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.25.4.tgz", - "integrity": "sha512-zQ1ijeeCXVEh+aNL0RlmkPkG8HUiDcU2pzQQFjtbntgAczRASFzj4H+6+bV+dy1ntKR14I/DypeuRG1uma98iQ==", + "version": "7.25.6", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.25.6.tgz", + "integrity": "sha512-/l42B1qxpG6RdfYf343Uw1vmDjeNhneUXtzhojE7pDgfpEypmRhI6j1kr17XCVv4Cgl9HdAiQY2x0GwKm7rWCw==", "dev": true, "dependencies": { "@babel/helper-string-parser": "^7.24.8", @@ -7001,9 +7001,9 @@ } }, "node_modules/@tailwindcss/typography": { - "version": "0.5.14", - "resolved": "https://registry.npmjs.org/@tailwindcss/typography/-/typography-0.5.14.tgz", - "integrity": "sha512-ZvOCjUbsJBjL9CxQBn+VEnFpouzuKhxh2dH8xMIWHILL+HfOYtlAkWcyoon8LlzE53d2Yo6YO6pahKKNW3q1YQ==", + "version": "0.5.15", + "resolved": "https://registry.npmjs.org/@tailwindcss/typography/-/typography-0.5.15.tgz", + "integrity": "sha512-AqhlCXl+8grUz8uqExv5OTtgpjuVIwFTSXTrh8y9/pw6q2ek7fJ+Y8ZEVw7EB2DCcuCOtEjf9w3+J3rzts01uA==", "dev": true, "dependencies": { "lodash.castarray": "^4.4.0", @@ -7012,7 +7012,7 @@ "postcss-selector-parser": "6.0.10" }, "peerDependencies": { - "tailwindcss": ">=3.0.0 || insiders" + "tailwindcss": ">=3.0.0 || insiders || >=4.0.0-alpha.20" } }, "node_modules/@tanstack/react-virtual": { @@ -8146,19 +8146,19 @@ } }, "node_modules/algoliasearch": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/algoliasearch/-/algoliasearch-5.1.1.tgz", - "integrity": "sha512-Bmi456esf2+/nY1w3Xa2etGjQPOBw+RPtfdKRN33mWJ4hNs9cug/F4w9KAb0wiYqDjW1fduXYwu6+YKLHFMMew==", + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/algoliasearch/-/algoliasearch-5.2.3.tgz", + "integrity": "sha512-TPXs3MErOL2vdPwlXL71DnjISWuVgtOvv4CGErovXX32MyOT1oSwD1WXDjxZeY2LgVMYbIuPXwbi51AK3aATSQ==", "peer": true, "dependencies": { - "@algolia/client-abtesting": "5.1.1", - "@algolia/client-analytics": "5.1.1", - "@algolia/client-common": "5.1.1", - "@algolia/client-personalization": "5.1.1", - "@algolia/client-search": "5.1.1", - "@algolia/recommend": "5.1.1", - "@algolia/requester-browser-xhr": "5.1.1", - "@algolia/requester-node-http": "5.1.1" + "@algolia/client-abtesting": "5.2.3", + "@algolia/client-analytics": "5.2.3", + "@algolia/client-common": "5.2.3", + "@algolia/client-personalization": "5.2.3", + "@algolia/client-search": "5.2.3", + "@algolia/recommend": "5.2.3", + "@algolia/requester-browser-xhr": "5.2.3", + "@algolia/requester-node-http": "5.2.3" }, "engines": { "node": ">= 14.0.0" @@ -10474,9 +10474,9 @@ } }, "node_modules/escalade": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz", - "integrity": "sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", "engines": { "node": ">=6" } @@ -12191,9 +12191,9 @@ } }, "node_modules/get-tsconfig": { - "version": "4.7.6", - "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.7.6.tgz", - "integrity": "sha512-ZAqrLlu18NbDdRaHq+AKXzAmqIUPswPWKUchfytdAjiRFnCe5ojG2bstg6mRiZabkKfCoL/e98pbBELIV/YCeA==", + "version": "4.8.0", + "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.8.0.tgz", + "integrity": "sha512-Pgba6TExTZ0FJAn1qkJAjIeKoDJ3CsI2ChuLohJnZl/tTU8MVrq3b+2t5UOPfRa4RMsorClBjJALkJUMjG1PAw==", "dependencies": { "resolve-pkg-maps": "^1.0.0" }, @@ -12415,9 +12415,9 @@ } }, "node_modules/got/node_modules/type-fest": { - "version": "4.25.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.25.0.tgz", - "integrity": "sha512-bRkIGlXsnGBRBQRAY56UXBm//9qH4bmJfFvq83gSz41N282df+fjy8ofcEgc1sM8geNt5cl6mC2g9Fht1cs8Aw==", + "version": "4.26.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.26.0.tgz", + "integrity": "sha512-OduNjVJsFbifKb57UqZ2EMP1i4u64Xwow3NYXUtBbD4vIwJdQd4+xl8YDou1dlm4DVrtwT/7Ky8z8WyCULVfxw==", "engines": { "node": ">=16" }, @@ -12620,9 +12620,9 @@ "integrity": "sha512-qlD8YNDqyTKTyuITrDOffsl6Tdhv+UC4hcdAVuQsK4IMQ99nSgd1MIA/Q+jQYoh9r3hVUXhYh7urSRmXPkW04g==" }, "node_modules/hast-util-to-jsx-runtime/node_modules/style-to-object": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/style-to-object/-/style-to-object-1.0.6.tgz", - "integrity": "sha512-khxq+Qm3xEyZfKd/y9L3oIWQimxuc4STrQKtQn8aSDRHb8mFgpukgX1hdzfrMEW6JCjyJ8p89x+IUMVnCBI1PA==", + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/style-to-object/-/style-to-object-1.0.7.tgz", + "integrity": "sha512-uSjr59G5u6fbxUfKbb8GcqMGT3Xs9v5IbPkjb0S16GyOeBLAzSRK0CixBv5YrYvzO6TDLzIS6QCn78tkqWngPw==", "dependencies": { "inline-style-parser": "0.2.3" } @@ -15780,9 +15780,9 @@ } }, "node_modules/npm": { - "version": "10.8.2", - "resolved": "https://registry.npmjs.org/npm/-/npm-10.8.2.tgz", - "integrity": "sha512-x/AIjFIKRllrhcb48dqUNAAZl0ig9+qMuN91RpZo3Cb2+zuibfh+KISl6+kVVyktDz230JKc208UkQwwMqyB+w==", + "version": "10.8.3", + "resolved": "https://registry.npmjs.org/npm/-/npm-10.8.3.tgz", + "integrity": "sha512-0IQlyAYvVtQ7uOhDFYZCGK8kkut2nh8cpAdA9E6FvRSJaTgtZRZgNjlC5ZCct//L73ygrpY93CxXpRJDtNqPVg==", "bundleDependencies": [ "@isaacs/string-locale-compare", "@npmcli/arborist", @@ -15873,13 +15873,13 @@ "@sigstore/tuf": "^2.3.4", "abbrev": "^2.0.0", "archy": "~1.0.0", - "cacache": "^18.0.3", + "cacache": "^18.0.4", "chalk": "^5.3.0", "ci-info": "^4.0.0", "cli-columns": "^4.0.0", "fastest-levenshtein": "^1.0.16", "fs-minipass": "^3.0.3", - "glob": "^10.4.2", + "glob": "^10.4.5", "graceful-fs": "^4.2.11", "hosted-git-info": "^7.0.2", "ini": "^4.1.3", @@ -15888,7 +15888,7 @@ "json-parse-even-better-errors": "^3.0.2", "libnpmaccess": "^8.0.6", "libnpmdiff": "^6.1.4", - "libnpmexec": "^8.1.3", + "libnpmexec": "^8.1.4", "libnpmfund": "^5.0.12", "libnpmhook": "^10.0.5", "libnpmorg": "^6.0.6", @@ -15902,12 +15902,12 @@ "minipass": "^7.1.1", "minipass-pipeline": "^1.2.4", "ms": "^2.1.2", - "node-gyp": "^10.1.0", + "node-gyp": "^10.2.0", "nopt": "^7.2.1", "normalize-package-data": "^6.0.2", "npm-audit-report": "^5.0.0", "npm-install-checks": "^6.3.0", - "npm-package-arg": "^11.0.2", + "npm-package-arg": "^11.0.3", "npm-pick-manifest": "^9.1.0", "npm-profile": "^10.0.0", "npm-registry-fetch": "^17.1.0", @@ -15918,7 +15918,7 @@ "proc-log": "^4.2.0", "qrcode-terminal": "^0.12.0", "read": "^3.0.1", - "semver": "^7.6.2", + "semver": "^7.6.3", "spdx-expression-parse": "^4.0.0", "ssri": "^10.0.6", "supports-color": "^9.4.0", @@ -16501,7 +16501,7 @@ } }, "node_modules/npm/node_modules/cacache": { - "version": "18.0.3", + "version": "18.0.4", "inBundle": true, "license": "ISC", "dependencies": { @@ -16654,7 +16654,7 @@ } }, "node_modules/npm/node_modules/debug": { - "version": "4.3.5", + "version": "4.3.6", "inBundle": true, "license": "MIT", "dependencies": { @@ -16728,7 +16728,7 @@ } }, "node_modules/npm/node_modules/foreground-child": { - "version": "3.2.1", + "version": "3.3.0", "inBundle": true, "license": "ISC", "dependencies": { @@ -16754,7 +16754,7 @@ } }, "node_modules/npm/node_modules/glob": { - "version": "10.4.2", + "version": "10.4.5", "inBundle": true, "license": "ISC", "dependencies": { @@ -16768,9 +16768,6 @@ "bin": { "glob": "dist/esm/bin.mjs" }, - "engines": { - "node": ">=16 || 14 >=14.18" - }, "funding": { "url": "https://github.com/sponsors/isaacs" } @@ -16937,15 +16934,12 @@ "license": "ISC" }, "node_modules/npm/node_modules/jackspeak": { - "version": "3.4.0", + "version": "3.4.3", "inBundle": true, "license": "BlueOak-1.0.0", "dependencies": { "@isaacs/cliui": "^8.0.2" }, - "engines": { - "node": ">=14" - }, "funding": { "url": "https://github.com/sponsors/isaacs" }, @@ -17023,7 +17017,7 @@ } }, "node_modules/npm/node_modules/libnpmexec": { - "version": "8.1.3", + "version": "8.1.4", "inBundle": true, "license": "ISC", "dependencies": { @@ -17148,12 +17142,9 @@ } }, "node_modules/npm/node_modules/lru-cache": { - "version": "10.2.2", + "version": "10.4.3", "inBundle": true, - "license": "ISC", - "engines": { - "node": "14 || >=16.14" - } + "license": "ISC" }, "node_modules/npm/node_modules/make-fetch-happen": { "version": "13.0.1", @@ -17348,7 +17339,7 @@ } }, "node_modules/npm/node_modules/node-gyp": { - "version": "10.1.0", + "version": "10.2.0", "inBundle": true, "license": "MIT", "dependencies": { @@ -17358,9 +17349,9 @@ "graceful-fs": "^4.2.6", "make-fetch-happen": "^13.0.0", "nopt": "^7.0.0", - "proc-log": "^3.0.0", + "proc-log": "^4.1.0", "semver": "^7.3.5", - "tar": "^6.1.2", + "tar": "^6.2.1", "which": "^4.0.0" }, "bin": { @@ -17370,14 +17361,6 @@ "node": "^16.14.0 || >=18.0.0" } }, - "node_modules/npm/node_modules/node-gyp/node_modules/proc-log": { - "version": "3.0.0", - "inBundle": true, - "license": "ISC", - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, "node_modules/npm/node_modules/nopt": { "version": "7.2.1", "inBundle": true, @@ -17444,7 +17427,7 @@ } }, "node_modules/npm/node_modules/npm-package-arg": { - "version": "11.0.2", + "version": "11.0.3", "inBundle": true, "license": "ISC", "dependencies": { @@ -17606,7 +17589,7 @@ } }, "node_modules/npm/node_modules/postcss-selector-parser": { - "version": "6.1.0", + "version": "6.1.2", "inBundle": true, "license": "MIT", "dependencies": { @@ -17730,7 +17713,7 @@ "optional": true }, "node_modules/npm/node_modules/semver": { - "version": "7.6.2", + "version": "7.6.3", "inBundle": true, "license": "ISC", "bin": { @@ -22369,7 +22352,7 @@ }, "packages/mesh-common": { "name": "@meshsdk/common", - "version": "1.6.12", + "version": "1.6.13", "license": "Apache-2.0", "dependencies": { "bech32": "^2.0.0", @@ -22386,7 +22369,7 @@ }, "packages/mesh-contract": { "name": "@meshsdk/contract", - "version": "1.6.12", + "version": "1.6.13", "license": "Apache-2.0", "dependencies": { "@meshsdk/common": "*", @@ -22404,7 +22387,7 @@ }, "packages/mesh-core": { "name": "@meshsdk/core", - "version": "1.6.12", + "version": "1.6.13", "license": "Apache-2.0", "dependencies": { "@meshsdk/common": "*", @@ -22424,7 +22407,7 @@ }, "packages/mesh-core-csl": { "name": "@meshsdk/core-csl", - "version": "1.6.12", + "version": "1.6.13", "license": "Apache-2.0", "dependencies": { "@meshsdk/common": "*", @@ -22443,7 +22426,7 @@ }, "packages/mesh-core-cst": { "name": "@meshsdk/core-cst", - "version": "1.6.12", + "version": "1.6.13", "license": "Apache-2.0", "dependencies": { "@cardano-sdk/core": "^0.35.4", @@ -22469,7 +22452,7 @@ }, "packages/mesh-provider": { "name": "@meshsdk/provider", - "version": "1.6.12", + "version": "1.6.13", "license": "Apache-2.0", "dependencies": { "@meshsdk/common": "*", @@ -22485,7 +22468,7 @@ }, "packages/mesh-react": { "name": "@meshsdk/react", - "version": "1.6.12", + "version": "1.6.13", "license": "Apache-2.0", "dependencies": { "@meshsdk/common": "*", @@ -22505,7 +22488,7 @@ }, "packages/mesh-transaction": { "name": "@meshsdk/transaction", - "version": "1.6.12", + "version": "1.6.13", "license": "Apache-2.0", "dependencies": { "@meshsdk/common": "*", @@ -22523,7 +22506,7 @@ }, "packages/mesh-wallet": { "name": "@meshsdk/wallet", - "version": "1.6.12", + "version": "1.6.13", "license": "Apache-2.0", "dependencies": { "@meshsdk/common": "*", @@ -22543,7 +22526,7 @@ }, "scripts/mesh-cli": { "name": "meshjs", - "version": "1.5.4", + "version": "1.6.13", "license": "Apache-2.0", "dependencies": { "chalk": "5.3.0", @@ -22554,7 +22537,7 @@ "tar": "7.2.0" }, "bin": { - "meshjs": "bin/meshjs" + "meshjs": "bin/meshjs.js" }, "devDependencies": { "@preconstruct/cli": "2.8.4", diff --git a/package.json b/package.json index e9b5143e..ac267c37 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,8 @@ "name": "@meshsdk/root", "private": true, "scripts": { - "build": "turbo build --concurrency 15 && npm run build:scripts", + "build": "turbo run build:mesh && turbo run build:docs && turbo run build:apps && turbo run build:scripts", + "build2": "turbo build --concurrency 15 && npm run build:scripts", "build:apps": "turbo run build:apps", "build:docs": "turbo run build:docs", "build:mesh": "turbo run build:mesh", diff --git a/packages/mesh-common/src/data/value.ts b/packages/mesh-common/src/data/value.ts index cca749b0..f832c3b3 100644 --- a/packages/mesh-common/src/data/value.ts +++ b/packages/mesh-common/src/data/value.ts @@ -197,7 +197,7 @@ export class MeshValue { * @returns boolean */ leq = (other: MeshValue): boolean => { - return Object.keys(other.value).every((key) => this.leqUnit(key, other)); + return Object.keys(this.value).every((key) => this.leqUnit(key, other)); }; /** diff --git a/packages/mesh-common/test/data/value/comparator.test.ts b/packages/mesh-common/test/data/value/comparator.test.ts index f035ca05..da30e69a 100644 --- a/packages/mesh-common/test/data/value/comparator.test.ts +++ b/packages/mesh-common/test/data/value/comparator.test.ts @@ -21,6 +21,24 @@ describe("MeshValue class", () => { const target = new MeshValue({ lovelace: 20n, [mockUnit]: 10n }); expect(value.geq(target)).toBe(true); }); + + it("should return false if there is missing unit in the target value", () => { + const value = new MeshValue({ lovelace: 20n }); + const target = new MeshValue({ lovelace: 20n, [mockUnit]: 10n }); + expect(value.geq(target)).toBe(false); + }); + + it("should return false if there is missing unit in the value.value", () => { + const value = new MeshValue({ lovelace: 20n, [mockUnit]: 10n }); + const target = new MeshValue({ lovelace: 20n }); + expect(value.geq(target)).toBe(true); + }); + + it("should return false if there is missing unit in both value.value and target.value", () => { + const value = new MeshValue({ lovelace: 20n, somethingelse: 10n }); + const target = new MeshValue({ lovelace: 20n, [mockUnit]: 10n }); + expect(value.geq(target)).toBe(false); + }); }); describe("geqUnit", () => { it("should return true if the value is greater than or equal to the target value for a specific unit", () => { @@ -46,8 +64,14 @@ describe("MeshValue class", () => { it("should return false if the unit does not exist in value.value", () => { const value = new MeshValue({ lovelace: 20n, [mockUnit]: 10n }); - const target = new MeshValue({ somethingElse: 5n }); - expect(value.geqUnit("somethingElse", target)).toBe(false); + const target = new MeshValue({ lovelace: 20n }); + expect(value.geqUnit(mockUnit, target)).toBe(false); + }); + + it("should return false if the unit does not exist in other.value", () => { + const value = new MeshValue({ lovelace: 20n }); + const target = new MeshValue({ lovelace: 20n, [mockUnit]: 10n }); + expect(value.geqUnit(mockUnit, target)).toBe(false); }); }); describe("leq", () => { @@ -68,6 +92,24 @@ describe("MeshValue class", () => { const target = new MeshValue({ lovelace: 20n, [mockUnit]: 10n }); expect(value.leq(target)).toBe(true); }); + + it("should return false if there is missing unit in the target value", () => { + const value = new MeshValue({ lovelace: 20n }); + const target = new MeshValue({ lovelace: 20n, [mockUnit]: 10n }); + expect(value.leq(target)).toBe(true); + }); + + it("should return false if there is missing unit in the value.value", () => { + const value = new MeshValue({ lovelace: 20n, [mockUnit]: 10n }); + const target = new MeshValue({ lovelace: 20n }); + expect(value.leq(target)).toBe(false); + }); + + it("should return false if there is missing unit in both value.value and target.value", () => { + const value = new MeshValue({ lovelace: 20n, somethingelse: 10n }); + const target = new MeshValue({ lovelace: 20n, [mockUnit]: 10n }); + expect(value.leq(target)).toBe(false); + }); }); describe("leqUnit", () => { it("should return true if the value is less than or equal to the target value for a specific unit", () => { @@ -91,10 +133,16 @@ describe("MeshValue class", () => { expect(value.leqUnit(mockUnit, target)).toBe(true); }); - it("should return false if the unit does not exist in value.value", () => { + it("should return false if the unit does not exist in other.value", () => { + const value = new MeshValue({ lovelace: 20n }); + const target = new MeshValue({ lovelace: 5n, [mockUnit]: 10n }); + expect(value.leqUnit(mockUnit, target)).toBe(false); + }); + + it("should return false if the unit does not exist in this.value", () => { const value = new MeshValue({ lovelace: 20n, [mockUnit]: 10n }); - const target = new MeshValue({ somethingElse: 5n }); - expect(value.leqUnit("somethingElse", target)).toBe(false); + const target = new MeshValue({ lovelace: 20n }); + expect(value.leqUnit(mockUnit, target)).toBe(false); }); }); describe("isEmpty", () => { diff --git a/packages/mesh-common/test/data/value/convertor.test.ts b/packages/mesh-common/test/data/value/convertor.test.ts index bfff721f..0ce51ceb 100644 --- a/packages/mesh-common/test/data/value/convertor.test.ts +++ b/packages/mesh-common/test/data/value/convertor.test.ts @@ -1,6 +1,8 @@ import { Asset, + assocMap, byteString, + currencySymbol, dict, Dict, Integer, @@ -8,6 +10,7 @@ import { MeshValue, MValue, mValue, + tokenName, Value, value, } from "@meshsdk/common"; @@ -170,4 +173,100 @@ describe("MeshValue class", () => { expect(JSON.stringify(val)).toBe(JSON.stringify(assets)); }); }); + describe("toData", () => { + test("Empty Value", () => { + const val: Asset[] = []; + const plutusValue: Value = value(val); + const data = MeshValue.fromValue(plutusValue).toData(); + const expected: MValue = mValue(val); + expect(JSON.stringify(expected)).toBe(JSON.stringify(data)); + }); + + test("Multiple Assets with Same Policy", () => { + const val: Asset[] = [ + { + unit: "baefdc6c5b191be372a794cd8d40d839ec0dbdd3c28957267dc817001234", + quantity: "100", + }, + { + unit: "baefdc6c5b191be372a794cd8d40d839ec0dbdd3c28957267dc817001234", + quantity: "200", + }, + ]; + const plutusValue: Value = value(val); + const data = MeshValue.fromValue(plutusValue).toData(); + const expected: MValue = mValue(val); + + expect(JSON.stringify(expected)).toBe(JSON.stringify(data)); + }); + + test("Mixed Assets", () => { + const val: Asset[] = [ + { unit: "lovelace", quantity: "1000000" }, + { + unit: "baefdc6c5b191be372a794cd8d40d839ec0dbdd3c28957267dc817001234", + quantity: "567", + }, + { + unit: "baefdc6c5b191be372a794cd8d40d839ec0dbdd3c28957267dc8170074657374696e676e657777616c2e616461", + quantity: "345", + }, + { + unit: "baefdc6c5b191be372a794cd8d40d839ec0dbdd3c28957267dc817001234", + quantity: "100", + }, + ]; + const plutusValue: Value = value(val); + const data = MeshValue.fromValue(plutusValue).toData(); + const expected: MValue = mValue(val); + expect(JSON.stringify(expected)).toBe(JSON.stringify(data)); + }); + + test("Single Asset with Large Quantity", () => { + const val: Asset[] = [{ unit: "lovelace", quantity: "1000000000000" }]; + const plutusValue: Value = value(val); + const data = MeshValue.fromValue(plutusValue).toData(); + const expected: MValue = mValue(val); + expect(JSON.stringify(expected)).toBe(JSON.stringify(data)); + }); + }); + describe("toJSON", () => { + test("should correctly convert MeshValue to JSON with multiple assets", () => { + const assets: Asset[] = [ + { unit: "lovelace", quantity: "1000000" }, + { + unit: "c21d710605bb00e69f3c175150552fc498316d80e7efdb1b186db38c000643b04d65736820676f6f64", + quantity: "500", + }, + ]; + + const expectedValue = assocMap([ + [currencySymbol(""), assocMap([[tokenName(""), integer(1000000)]])], + [ + currencySymbol( + "c21d710605bb00e69f3c175150552fc498316d80e7efdb1b186db38c", + ), + assocMap([[tokenName("000643b04d65736820676f6f64"), integer(500)]]), + ], + ]); + + const meshValue = new MeshValue(); + meshValue.toAssets = () => assets; + + const jsonValue = meshValue.toJSON(); + expect(JSON.stringify(jsonValue)).toEqual(JSON.stringify(expectedValue)); + }); + + test("should correctly convert MeshValue to JSON with no asset", () => { + const assets: Asset[] = []; + + const expectedValue = assocMap([]); + + const meshValue = new MeshValue(); + meshValue.toAssets = () => assets; + + const jsonValue = meshValue.toJSON(); + expect(JSON.stringify(jsonValue)).toEqual(JSON.stringify(expectedValue)); + }); + }); }); diff --git a/packages/mesh-contract/src/hello-world/aiken-workspace/validators/hello_world.ak b/packages/mesh-contract/src/hello-world/aiken-workspace/validators/hello-world.ak similarity index 100% rename from packages/mesh-contract/src/hello-world/aiken-workspace/validators/hello_world.ak rename to packages/mesh-contract/src/hello-world/aiken-workspace/validators/hello-world.ak diff --git a/packages/mesh-contract/src/hello-world/offchain.ts b/packages/mesh-contract/src/hello-world/offchain.ts index df9048be..0932d417 100644 --- a/packages/mesh-contract/src/hello-world/offchain.ts +++ b/packages/mesh-contract/src/hello-world/offchain.ts @@ -1,5 +1,14 @@ -import { BuiltinByteString, ConStr0, Integer } from "@meshsdk/common"; -import { UTxO } from "@meshsdk/core"; +import { + Asset, + BuiltinByteString, + ConStr0, + deserializeAddress, + Integer, + mConStr0, + serializePlutusScript, + stringToHex, + UTxO, +} from "@meshsdk/core"; import { applyParamsToScript } from "@meshsdk/core-csl"; import { MeshTxInitiator, MeshTxInitiatorInput } from "../common"; @@ -18,6 +27,61 @@ export class MeshHelloWorldContract extends MeshTxInitiator { super(inputs); } + getScript = () => { + const { address } = serializePlutusScript( + { code: this.scriptCbor, version: "V2" }, + undefined, + this.networkId, + ); + return { + scriptAddr: address, + }; + }; + + lockAsset = async (assets: Asset[]): Promise => { + const { utxos, walletAddress } = await this.getWalletInfoForTx(); + const { scriptAddr } = this.getScript(); + const signerHash = deserializeAddress(walletAddress).pubKeyHash; + + await this.mesh + .txOut(scriptAddr, assets) + .txOutDatumHashValue(mConStr0([signerHash])) + .changeAddress(walletAddress) + .selectUtxosFrom(utxos) + .complete(); + return this.mesh.txHex; + }; + + unlockAsset = async (scriptUtxo: UTxO, message: string): Promise => { + const { utxos, walletAddress, collateral } = + await this.getWalletInfoForTx(); + const signerHash = deserializeAddress(walletAddress).pubKeyHash; + + await this.mesh + .spendingPlutusScriptV2() + .txIn( + scriptUtxo.input.txHash, + scriptUtxo.input.outputIndex, + scriptUtxo.output.amount, + scriptUtxo.output.address, + ) + .txInScript(this.scriptCbor) + .txInRedeemerValue(mConStr0([stringToHex(message)])) + .txInDatumValue(mConStr0([signerHash])) + .requiredSignerHash(signerHash) + .changeAddress(walletAddress) + .txInCollateral( + collateral.input.txHash, + collateral.input.outputIndex, + collateral.output.amount, + collateral.output.address, + ) + .selectUtxosFrom(utxos) + .complete(); + + return this.mesh.txHex; + }; + getUtxoByTxHash = async (txHash: string): Promise => { return await this._getUtxoByTxHash(txHash, this.scriptCbor); }; diff --git a/packages/mesh-contract/src/index.ts b/packages/mesh-contract/src/index.ts index c95d1a08..ad0a330e 100644 --- a/packages/mesh-contract/src/index.ts +++ b/packages/mesh-contract/src/index.ts @@ -1,6 +1,7 @@ -export * from './marketplace'; -export * from './vesting'; -export * from './escrow'; -export * from './giftcard'; -export * from './payment-splitter'; -export * from './swap'; +export * from "./escrow"; +export * from "./giftcard"; +export * from "./hello-world"; +export * from "./marketplace"; +export * from "./payment-splitter"; +export * from "./swap"; +export * from "./vesting"; diff --git a/packages/mesh-contract/src/vesting/aiken-workspace/lib/vesting/types.ak b/packages/mesh-contract/src/vesting/aiken-workspace/lib/vesting/types.ak index a189c93b..95a24f54 100644 --- a/packages/mesh-contract/src/vesting/aiken-workspace/lib/vesting/types.ak +++ b/packages/mesh-contract/src/vesting/aiken-workspace/lib/vesting/types.ak @@ -1,5 +1,5 @@ pub type VestingDatum { - /// POSIX time in second, e.g. 1672843961000 + /// POSIX time in milliseconds, e.g. 1672843961000 lock_until: Int, /// Owner's credentials owner: ByteArray,