Example responses from unlocking assets from the always succeed smart
contract.
- Return a list of assets in connected wallet from all UTXOs.
- Return amount of lovelace in wallet.
- Return the network of connected wallet.
- Returns a list of wallets installed on user's device.
-
+ You can define the NuFi network to connect to by adding the{" "}
+ nufiNetwork
prop.
+
+
<>
-
+
{wallets.map((wallet, i) => {
return (
diff --git a/apps/playground/src/pages/smart-contracts/common.tsx b/apps/playground/src/pages/smart-contracts/common.tsx
index 30699bd49..bed6602f3 100644
--- a/apps/playground/src/pages/smart-contracts/common.tsx
+++ b/apps/playground/src/pages/smart-contracts/common.tsx
@@ -7,7 +7,7 @@ export function InstallSmartContract() {
First you can to install the @meshsdk/contracts
package:
-
+
>
);
}
diff --git a/apps/playground/src/pages/smart-contracts/escrow/index.tsx b/apps/playground/src/pages/smart-contracts/escrow/index.tsx
index 79e1444ce..179c75685 100644
--- a/apps/playground/src/pages/smart-contracts/escrow/index.tsx
+++ b/apps/playground/src/pages/smart-contracts/escrow/index.tsx
@@ -1,6 +1,7 @@
import type { NextPage } from "next";
import Link from "next/link";
+import MintMeshToken from "~/components/cardano/mint-mesh-token";
import SidebarFullwidth from "~/components/layouts/sidebar-fullwidth";
import TitleIconDescriptionBody from "~/components/sections/title-icon-description-body";
import Metatags from "~/components/site/metatags";
@@ -73,14 +74,16 @@ const ReactPage: NextPage = () => {
provider,{" "}
MeshTxBuilder
and MeshEscrowContract
.
-
+
Both on-chain and off-chain codes are open-source and available on{" "}
-
+
Mesh Github Repository
.
+
+
>
diff --git a/apps/playground/src/pages/smart-contracts/giftcard/index.tsx b/apps/playground/src/pages/smart-contracts/giftcard/index.tsx
index c806e018b..edd483058 100644
--- a/apps/playground/src/pages/smart-contracts/giftcard/index.tsx
+++ b/apps/playground/src/pages/smart-contracts/giftcard/index.tsx
@@ -72,10 +72,10 @@ const ReactPage: NextPage = () => {
provider,{" "}
MeshTxBuilder
and MeshGiftCardContract
.
-
+
Both on-chain and off-chain codes are open-source and available on{" "}
-
+
Mesh Github Repository
.
diff --git a/apps/playground/src/pages/smart-contracts/marketplace/index.tsx b/apps/playground/src/pages/smart-contracts/marketplace/index.tsx
index 7caf6d364..b9bc024a1 100644
--- a/apps/playground/src/pages/smart-contracts/marketplace/index.tsx
+++ b/apps/playground/src/pages/smart-contracts/marketplace/index.tsx
@@ -1,6 +1,7 @@
import type { NextPage } from "next";
import Link from "next/link";
+import MintMeshToken from "~/components/cardano/mint-mesh-token";
import SidebarFullwidth from "~/components/layouts/sidebar-fullwidth";
import TitleIconDescriptionBody from "~/components/sections/title-icon-description-body";
import Metatags from "~/components/site/metatags";
@@ -81,7 +82,7 @@ const ReactPage: NextPage = () => {
and a connected browser wallet. Here is an example how we can
initialize the Marketplace.
-
+
To initialize the Marketplace, we import the{" "}
MeshMarketplaceContract
. The first JSON object is the{" "}
@@ -102,11 +103,13 @@ const ReactPage: NextPage = () => {
Both on-chain and off-chain codes are open-source and available on{" "}
-
+
Mesh Github Repository
.
+
+
>
diff --git a/apps/playground/src/pages/smart-contracts/marketplace/list-asset.tsx b/apps/playground/src/pages/smart-contracts/marketplace/list-asset.tsx
index aa7c51070..53d50d007 100644
--- a/apps/playground/src/pages/smart-contracts/marketplace/list-asset.tsx
+++ b/apps/playground/src/pages/smart-contracts/marketplace/list-asset.tsx
@@ -2,6 +2,7 @@ import { useState } from "react";
import { useWallet } from "@meshsdk/react";
+import MintMeshToken from "~/components/cardano/mint-mesh-token";
import Input from "~/components/form/input";
import InputTable from "~/components/sections/input-table";
import LiveCodeDemo from "~/components/sections/live-code-demo";
diff --git a/apps/playground/src/pages/smart-contracts/payment-splitter/index.tsx b/apps/playground/src/pages/smart-contracts/payment-splitter/index.tsx
index 8d68e67cd..b07edc412 100644
--- a/apps/playground/src/pages/smart-contracts/payment-splitter/index.tsx
+++ b/apps/playground/src/pages/smart-contracts/payment-splitter/index.tsx
@@ -92,10 +92,10 @@ const ReactPage: NextPage = () => {
payees is required to define the allowed payout addresses for the
contract.
-
+
Both on-chain and off-chain codes are open-source and available on{" "}
-
+
Mesh Github Repository
.
diff --git a/apps/playground/src/pages/smart-contracts/swap/index.tsx b/apps/playground/src/pages/smart-contracts/swap/index.tsx
index 968da425a..f496e18d7 100644
--- a/apps/playground/src/pages/smart-contracts/swap/index.tsx
+++ b/apps/playground/src/pages/smart-contracts/swap/index.tsx
@@ -1,6 +1,7 @@
import type { NextPage } from "next";
import Link from "next/link";
+import MintMeshToken from "~/components/cardano/mint-mesh-token";
import SidebarFullwidth from "~/components/layouts/sidebar-fullwidth";
import TitleIconDescriptionBody from "~/components/sections/title-icon-description-body";
import Metatags from "~/components/site/metatags";
@@ -73,14 +74,16 @@ const ReactPage: NextPage = () => {
provider,{" "}
MeshTxBuilder
and MeshSwapContract
.
-
+
Both on-chain and off-chain codes are open-source and available on{" "}
-
+
Mesh Github Repository
.
+
+
>
diff --git a/apps/playground/src/pages/smart-contracts/vesting/index.tsx b/apps/playground/src/pages/smart-contracts/vesting/index.tsx
index 2e17713cf..fe76191a0 100644
--- a/apps/playground/src/pages/smart-contracts/vesting/index.tsx
+++ b/apps/playground/src/pages/smart-contracts/vesting/index.tsx
@@ -72,10 +72,10 @@ const ReactPage: NextPage = () => {
provider,{" "}
MeshTxBuilder
and MeshVestingContract
.
-
+
Both on-chain and off-chain codes are open-source and available on{" "}
-
+
Mesh Github Repository
.
diff --git a/package-lock.json b/package-lock.json
index 8381022c6..22a436656 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -5795,6 +5795,14 @@
"resolved": "packages/mesh-wallet",
"link": true
},
+ "node_modules/@metamask/detect-provider": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/@metamask/detect-provider/-/detect-provider-2.0.0.tgz",
+ "integrity": "sha512-sFpN+TX13E9fdBDh9lvQeZdJn4qYoRb/6QF2oZZK/Pn559IhCFacPMU1rMuqyXoFQF3JSJfii2l98B87QDPeCQ==",
+ "engines": {
+ "node": ">=14.0.0"
+ }
+ },
"node_modules/@microsoft/tsdoc": {
"version": "0.14.2",
"resolved": "https://registry.npmjs.org/@microsoft/tsdoc/-/tsdoc-0.14.2.tgz",
@@ -6080,6 +6088,22 @@
"node": ">= 8"
}
},
+ "node_modules/@nufi/dapp-client-cardano": {
+ "version": "0.3.1",
+ "resolved": "https://registry.npmjs.org/@nufi/dapp-client-cardano/-/dapp-client-cardano-0.3.1.tgz",
+ "integrity": "sha512-9anqGHu+OP0U0po/Rk6thmR+qcgqtRY3bppudC3As0dgXIhSfsWJBKIXw2Q/byCYL5l/GsmyC9XgdEKB7+oVeQ==",
+ "dependencies": {
+ "@nufi/dapp-client-core": "0.3.1"
+ }
+ },
+ "node_modules/@nufi/dapp-client-core": {
+ "version": "0.3.1",
+ "resolved": "https://registry.npmjs.org/@nufi/dapp-client-core/-/dapp-client-core-0.3.1.tgz",
+ "integrity": "sha512-MexKhCE1dZGYTyxZuqQGCaZN0tZW0RyqDY/wzMafwuP5LUKxoxahCJ5U+SF37v4FrrDz6svNddV69aUSMIldag==",
+ "dependencies": {
+ "@metamask/detect-provider": "^2.0.0"
+ }
+ },
"node_modules/@pkgjs/parseargs": {
"version": "0.11.0",
"resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz",
@@ -8943,6 +8967,7 @@
"version": "3.9.0",
"resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz",
"integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==",
+ "dev": true,
"funding": [
{
"type": "github",
@@ -11877,7 +11902,8 @@
"node_modules/hosted-git-info": {
"version": "2.8.9",
"resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz",
- "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw=="
+ "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==",
+ "dev": true
},
"node_modules/html-escaper": {
"version": "2.0.2",
@@ -14677,6 +14703,7 @@
"version": "2.5.0",
"resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz",
"integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==",
+ "dev": true,
"dependencies": {
"hosted-git-info": "^2.1.4",
"resolve": "^1.10.0",
@@ -14688,6 +14715,7 @@
"version": "5.7.2",
"resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz",
"integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==",
+ "dev": true,
"bin": {
"semver": "bin/semver"
}
@@ -18874,6 +18902,7 @@
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.2.0.tgz",
"integrity": "sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==",
+ "dev": true,
"dependencies": {
"spdx-expression-parse": "^3.0.0",
"spdx-license-ids": "^3.0.0"
@@ -18882,12 +18911,14 @@
"node_modules/spdx-exceptions": {
"version": "2.5.0",
"resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.5.0.tgz",
- "integrity": "sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w=="
+ "integrity": "sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==",
+ "dev": true
},
"node_modules/spdx-expression-parse": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz",
"integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==",
+ "dev": true,
"dependencies": {
"spdx-exceptions": "^2.1.0",
"spdx-license-ids": "^3.0.0"
@@ -18896,7 +18927,8 @@
"node_modules/spdx-license-ids": {
"version": "3.0.18",
"resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.18.tgz",
- "integrity": "sha512-xxRs31BqRYHwiMzudOrpSiHtZ8i/GeionCBDSilhYRj+9gIcI8wCZTlXZKu9vZIVqViP3dcp9qE5G6AlIaD+TQ=="
+ "integrity": "sha512-xxRs31BqRYHwiMzudOrpSiHtZ8i/GeionCBDSilhYRj+9gIcI8wCZTlXZKu9vZIVqViP3dcp9qE5G6AlIaD+TQ==",
+ "dev": true
},
"node_modules/split-ca": {
"version": "1.0.1",
@@ -20469,6 +20501,7 @@
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz",
"integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==",
+ "dev": true,
"dependencies": {
"spdx-correct": "^3.0.0",
"spdx-expression-parse": "^3.0.0"
@@ -20824,6 +20857,7 @@
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-4.0.2.tgz",
"integrity": "sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==",
+ "dev": true,
"dependencies": {
"imurmurhash": "^0.1.4",
"signal-exit": "^3.0.7"
@@ -20835,7 +20869,8 @@
"node_modules/write-file-atomic/node_modules/signal-exit": {
"version": "3.0.7",
"resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz",
- "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ=="
+ "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==",
+ "dev": true
},
"node_modules/ws": {
"version": "7.5.10",
@@ -21029,7 +21064,7 @@
},
"packages/mesh-common": {
"name": "@meshsdk/common",
- "version": "1.5.32",
+ "version": "1.6.1",
"license": "Apache-2.0",
"dependencies": {
"@emurgo/cip14-js": "3.0.1",
@@ -21045,7 +21080,7 @@
},
"packages/mesh-contract": {
"name": "@meshsdk/contract",
- "version": "1.5.32",
+ "version": "1.6.1",
"license": "Apache-2.0",
"dependencies": {
"@meshsdk/common": "*",
@@ -21064,7 +21099,7 @@
},
"packages/mesh-core": {
"name": "@meshsdk/core",
- "version": "1.5.32",
+ "version": "1.6.1",
"license": "Apache-2.0",
"dependencies": {
"@meshsdk/common": "*",
@@ -21085,7 +21120,7 @@
},
"packages/mesh-core-csl": {
"name": "@meshsdk/core-csl",
- "version": "1.5.32",
+ "version": "1.6.1",
"license": "Apache-2.0",
"dependencies": {
"@meshsdk/common": "*",
@@ -21105,7 +21140,7 @@
},
"packages/mesh-core-cst": {
"name": "@meshsdk/core-cst",
- "version": "1.5.32",
+ "version": "1.6.1",
"license": "Apache-2.0",
"dependencies": {
"@cardano-sdk/core": "^0.35.4",
@@ -21128,7 +21163,7 @@
},
"packages/mesh-provider": {
"name": "@meshsdk/provider",
- "version": "1.5.32",
+ "version": "1.6.1",
"license": "Apache-2.0",
"dependencies": {
"@meshsdk/common": "*",
@@ -21144,7 +21179,7 @@
},
"packages/mesh-react": {
"name": "@meshsdk/react",
- "version": "1.5.32",
+ "version": "1.6.1",
"license": "Apache-2.0",
"dependencies": {
"@meshsdk/common": "*",
@@ -21166,7 +21201,7 @@
},
"packages/mesh-transaction": {
"name": "@meshsdk/transaction",
- "version": "1.5.32",
+ "version": "1.6.1",
"license": "Apache-2.0",
"dependencies": {
"@meshsdk/common": "*",
@@ -21184,12 +21219,14 @@
},
"packages/mesh-wallet": {
"name": "@meshsdk/wallet",
- "version": "1.5.32",
+ "version": "1.6.1",
"license": "Apache-2.0",
"dependencies": {
"@meshsdk/common": "*",
"@meshsdk/core-cst": "*",
- "@meshsdk/transaction": "*"
+ "@meshsdk/transaction": "*",
+ "@nufi/dapp-client-cardano": "^0.3.1",
+ "@nufi/dapp-client-core": "^0.3.1"
},
"devDependencies": {
"@meshsdk/typescript-config": "*",
diff --git a/packages/config-jest/jest.config.ts b/packages/config-jest/jest.config.ts
index efbea4310..9042e9fd7 100644
--- a/packages/config-jest/jest.config.ts
+++ b/packages/config-jest/jest.config.ts
@@ -6,21 +6,14 @@ const jestConfig: Config = {
testEnvironment: "node",
testMatch: ["**/packages/**/*.test.ts"],
setupFiles: ["dotenv/config"],
- preset: "ts-jest/presets/default-esm",
+ preset: "ts-jest",
moduleNameMapper: {
"^(\\.{1,2}/.*)\\.js$": "$1",
},
transform: {
- "^.+\\.tsx?$": [
- "ts-jest",
- {
- useESM: true,
- },
- ],
+ "^.+\\.[jt]s?$": "ts-jest",
},
- transformIgnorePatterns: [
- "/node_modules/(?!@meshsdk/core-csl)", // Add exceptions for ESM packages
- ],
+ transformIgnorePatterns: ["/node_modules/(?!@meshsdk/.*)"],
};
export default jestConfig;
diff --git a/packages/mesh-common/package.json b/packages/mesh-common/package.json
index f2e6771e6..56a938837 100644
--- a/packages/mesh-common/package.json
+++ b/packages/mesh-common/package.json
@@ -1,6 +1,6 @@
{
"name": "@meshsdk/common",
- "version": "1.6.1",
+ "version": "1.6.2",
"description": "",
"main": "./dist/index.cjs",
"module": "./dist/index.js",
diff --git a/packages/mesh-common/src/data/value.ts b/packages/mesh-common/src/data/value.ts
index f88b7089f..cca749b0c 100644
--- a/packages/mesh-common/src/data/value.ts
+++ b/packages/mesh-common/src/data/value.ts
@@ -4,6 +4,7 @@
*/
import { Asset } from "../types";
+import { BigNum } from "../utils";
import {
assocMap,
AssocMap,
@@ -15,56 +16,303 @@ import {
tokenName,
} from "./json";
+/**
+ * Aiken alias
+ * Value is the JSON representation of Cardano data Value
+ */
export type Value = AssocMap>;
+/**
+ * Aiken alias
+ * MValue is the Cardano data Value in Mesh Data type
+ */
export type MValue = Map>;
-export const value = (assets: Asset[]): Value => {
- const valueMapToParse: [CurrencySymbol, AssocMap][] = [];
- const valueMap: { [key: string]: { [key: string]: number } } = {};
+/**
+ * The utility function to convert assets into Cardano data Value in JSON
+ * @param assets The assets to convert
+ * @returns The Cardano data Value in JSON
+ */
+export const value = (assets: Asset[]) => {
+ return MeshValue.fromAssets(assets).toJSON();
+};
+
+/**
+ * The utility function to convert assets into Cardano data Value in Mesh Data type
+ * @param assets The assets to convert
+ * @returns The Cardano data Value in Mesh Data type
+ */
+export const mValue = (assets: Asset[]) => {
+ return MeshValue.fromAssets(assets).toData();
+};
+
+/**
+ * MeshValue provide utility to handle the Cardano value manipulation. It offers certain axioms:
+ * 1. No duplication of asset - adding assets with same asset name will increase the quantity of the asset in the same record.
+ * 2. No zero and negative entry - the quantity of the asset should not be zero or negative.
+ * 3. Sanitization of lovelace asset name - the class handle back and forth conversion of lovelace asset name to empty string.
+ * 4. Easy convertion to Cardano data - offer utility to convert into either Mesh Data type and JSON type for its Cardano data representation.
+ */
+export class MeshValue {
+ value: Record;
+
+ constructor(value: Record = {}) {
+ this.value = value;
+ }
+
+ /**
+ * Converting assets into MeshValue
+ * @param assets The assets to convert
+ * @returns MeshValue
+ */
+ static fromAssets = (assets: Asset[]): MeshValue => {
+ const value = new MeshValue();
+ value.addAssets(assets);
+ return value;
+ };
+
+ /**
+ * Converting Value (the JSON representation of Cardano data Value) into MeshValue
+ * @param plutusValue The Value to convert
+ * @returns MeshValue
+ */
+ static fromValue = (plutusValue: Value): MeshValue => {
+ const assets: Asset[] = [];
+
+ plutusValue.map.forEach((policyMap) => {
+ const policy = policyMap.k.bytes;
+ policyMap.v.map.forEach((tokenMap) => {
+ const token = tokenMap.k.bytes;
+ const quantity = tokenMap.v.int.toString();
+ const unsanitizedUnit = policy + token;
+ const unit = unsanitizedUnit === "" ? "lovelace" : unsanitizedUnit;
+ assets.push({ unit, quantity });
+ });
+ });
+
+ return MeshValue.fromAssets(assets);
+ };
- assets.forEach((asset) => {
- const sanitizedName = asset.unit.replace("lovelace", "");
- const policy = sanitizedName.slice(0, 56) || "";
- const token = sanitizedName.slice(56) || "";
+ /**
+ * Add an asset to the Value class's value record.
+ * @param asset The asset to add
+ * @returns The updated MeshValue object
+ */
+ addAsset = (asset: Asset): this => {
+ const quantity = BigInt(asset.quantity);
+ const { unit } = asset;
- if (!valueMap[policy]) {
- valueMap[policy] = {};
+ if (this.value[unit]) {
+ this.value[unit] += quantity;
+ } else {
+ this.value[unit] = quantity;
}
+ return this;
+ };
+
+ /**
+ * Add an array of assets to the Value class's value record.
+ * @param assets The assets to add
+ * @returns The updated MeshValue object
+ */
+ addAssets = (assets: Asset[]): this => {
+ assets.forEach((asset) => {
+ this.addAsset(asset);
+ });
+ return this;
+ };
- if (!valueMap[policy]![token]) {
- valueMap[policy]![token] = Number(asset.quantity);
+ /**
+ * Substract an asset from the Value class's value record.
+ * @param asset The asset to subtract
+ * @returns The updated MeshValue object
+ */
+ negateAsset = (asset: Asset): this => {
+ const { unit, quantity: assetQty } = asset;
+ const quantity = BigNum.new(this.value[unit]);
+ quantity.clampedSub(BigNum.new(assetQty));
+
+ if (quantity.value === BigInt(0)) {
+ delete this.value[unit];
} else {
- valueMap[policy]![token] += Number(asset.quantity);
+ this.value[unit] = quantity.value;
}
- });
+ return this;
+ };
- Object.keys(valueMap).forEach((policy) => {
- const policyByte = currencySymbol(policy);
- const tokens: [TokenName, Integer][] = Object.keys(valueMap[policy]!).map(
- (name) => [tokenName(name), integer(valueMap[policy]![name]!)],
- );
+ /**
+ * Subtract an array of assets from the Value class's value record.
+ * @param assets The assets to subtract
+ * @returns The updated MeshValue object
+ */
+ negateAssets = (assets: Asset[]): this => {
+ assets.forEach((asset) => {
+ this.negateAsset(asset);
+ });
+ return this;
+ };
- const policyMap = assocMap(tokens);
- valueMapToParse.push([policyByte, policyMap]);
- });
+ /**
+ * Get the quantity of asset object per unit
+ * @param unit The unit to get the quantity of
+ * @returns The quantity of the asset
+ */
+ get = (unit: string): bigint => {
+ return this.value[unit] ? BigInt(this.value[unit]) : BigInt(0);
+ };
- return assocMap(valueMapToParse);
-};
+ /**
+ * Get all asset units
+ * @returns The asset units
+ */
+ units = (): string[] => {
+ return Object.keys(this.value);
+ };
-export const parsePlutusValueToAssets = (plutusValue: Value): Asset[] => {
- const assets: Asset[] = [];
-
- plutusValue.map.forEach((policyMap) => {
- const policy = policyMap.k.bytes;
- policyMap.v.map.forEach((tokenMap) => {
- const token = tokenMap.k.bytes;
- const quantity = tokenMap.v.int.toString();
- const unsanitizedUnit = policy + token;
- const unit = unsanitizedUnit === "" ? "lovelace" : unsanitizedUnit;
- assets.push({ unit, quantity });
+ /**
+ * Check if the value is greater than or equal to another value
+ * @param other - The value to compare against
+ * @returns boolean
+ */
+ geq = (other: MeshValue): boolean => {
+ return Object.keys(other.value).every((key) => this.geqUnit(key, other));
+ };
+
+ /**
+ * Check if the specific unit of value is greater than or equal to that unit of another value
+ * @param unit - The unit to compare
+ * @param other - The value to compare against
+ * @returns boolean
+ */
+ geqUnit = (unit: string, other: MeshValue): boolean => {
+ if (this.value[unit] === undefined || other.value[unit] === undefined) {
+ return false;
+ }
+ return BigInt(this.value[unit]) >= BigInt(other.value[unit]);
+ };
+
+ /**
+ * Check if the value is less than or equal to another value
+ * @param other - The value to compare against
+ * @returns boolean
+ */
+ leq = (other: MeshValue): boolean => {
+ return Object.keys(other.value).every((key) => this.leqUnit(key, other));
+ };
+
+ /**
+ * Check if the specific unit of value is less than or equal to that unit of another value
+ * @param unit - The unit to compare
+ * @param other - The value to compare against
+ * @returns boolean
+ */
+ leqUnit = (unit: string, other: MeshValue): boolean => {
+ if (this.value[unit] === undefined || other.value[unit] === undefined) {
+ return false;
+ }
+ return BigInt(this.value[unit]) <= BigInt(other.value[unit]);
+ };
+
+ /**
+ * Check if the value is empty
+ * @returns boolean
+ */
+ isEmpty = (): boolean => {
+ return Object.keys(this.value).length === 0;
+ };
+
+ /**
+ * Merge the given values
+ * @param values The other values to merge
+ * @returns this
+ */
+ merge = (values: MeshValue | MeshValue[]): this => {
+ const valuesArray = Array.isArray(values) ? values : [values];
+
+ valuesArray.forEach((other) => {
+ Object.entries(other.value).forEach(([key, value]) => {
+ this.value[key] =
+ (this.value[key] !== undefined
+ ? BigInt(this.value[key])
+ : BigInt(0)) + BigInt(value);
+ });
});
- });
- return assets;
-};
+ return this;
+ };
+
+ /**
+ * Convert the MeshValue object into an array of Asset
+ * @returns The array of Asset
+ */
+ toAssets = (): Asset[] => {
+ const assets: Asset[] = [];
+ Object.entries(this.value).forEach(([unit, quantity]) => {
+ assets.push({ unit, quantity: quantity.toString() });
+ });
+ return assets;
+ };
+
+ /**
+ * Convert the MeshValue object into Cardano data Value in Mesh Data type
+ */
+ toData = (): MValue => {
+ const valueMap: MValue = new Map();
+ this.toAssets().forEach((asset) => {
+ const policy = asset.unit.slice(0, 56) || "";
+ const token = asset.unit.slice(56) || "";
+
+ if (!valueMap.has(policy)) {
+ valueMap.set(policy, new Map());
+ }
+
+ const tokenMap = valueMap.get(policy)!;
+ const quantity = tokenMap?.get(token);
+ if (!quantity) {
+ tokenMap.set(token, BigInt(asset.quantity));
+ } else {
+ tokenMap.set(token, quantity + BigInt(asset.quantity));
+ }
+ });
+
+ return valueMap;
+ };
+
+ /**
+ * Convert the MeshValue object into a JSON representation of Cardano data Value
+ * @returns Cardano data Value in JSON
+ */
+ toJSON = (): Value => {
+ const valueMapToParse: [CurrencySymbol, AssocMap][] =
+ [];
+ const valueMap: { [key: string]: { [key: string]: number } } = {};
+
+ this.toAssets().forEach((asset) => {
+ const sanitizedName = asset.unit.replace("lovelace", "");
+ const policy = sanitizedName.slice(0, 56) || "";
+ const token = sanitizedName.slice(56) || "";
+
+ if (!valueMap[policy]) {
+ valueMap[policy] = {};
+ }
+
+ if (!valueMap[policy]![token]) {
+ valueMap[policy]![token] = Number(asset.quantity);
+ } else {
+ valueMap[policy]![token] += Number(asset.quantity);
+ }
+ });
+
+ Object.keys(valueMap).forEach((policy) => {
+ const policyByte = currencySymbol(policy);
+ const tokens: [TokenName, Integer][] = Object.keys(valueMap[policy]!).map(
+ (name) => [tokenName(name), integer(valueMap[policy]![name]!)],
+ );
+
+ const policyMap = assocMap(tokens);
+ valueMapToParse.push([policyByte, policyMap]);
+ });
+
+ return assocMap(valueMapToParse);
+ };
+}
diff --git a/packages/mesh-common/src/interfaces/serializer.ts b/packages/mesh-common/src/interfaces/serializer.ts
index 924b120b5..b89c6cad7 100644
--- a/packages/mesh-common/src/interfaces/serializer.ts
+++ b/packages/mesh-common/src/interfaces/serializer.ts
@@ -19,6 +19,7 @@ export interface IMeshTxSerializer {
deserializer: IDeserializer;
serializeData(data: BuilderData): string;
serializeAddress(address: DeserializedAddress, networkId?: 0 | 1): string;
+ serializePoolId(hash: string): string;
}
export interface IResolver {
keys: {
@@ -36,9 +37,6 @@ export interface IResolver {
script: {
resolveScriptRef(script: NativeScript | PlutusScript): string;
};
- pool: {
- resolvePoolId(hash: string): string;
- };
}
export interface IDeserializer {
@@ -49,4 +47,7 @@ export interface IDeserializer {
deserializeNativeScript(script: NativeScript): DeserializedScript;
deserializePlutusScript(script: PlutusScript): DeserializedScript;
};
+ cert: {
+ deserializePoolId(poolId: string): string;
+ };
}
diff --git a/packages/mesh-common/src/utils/asset-fingerprint.ts b/packages/mesh-common/src/utils/asset-fingerprint.ts
index 2a8e353c7..49861be7c 100644
--- a/packages/mesh-common/src/utils/asset-fingerprint.ts
+++ b/packages/mesh-common/src/utils/asset-fingerprint.ts
@@ -5,7 +5,7 @@ import { toBytes } from "../data";
export const AssetFingerprint = CIP14;
export const resolveFingerprint = (policyId: string, assetName: string) => {
- return (AssetFingerprint as any).default
+ return (AssetFingerprint as any).default // todo: check the behaviour
.fromParts(toBytes(policyId), toBytes(assetName))
.fingerprint();
};
diff --git a/packages/mesh-common/src/utils/bigNum.ts b/packages/mesh-common/src/utils/bigNum.ts
index bbded1a03..b6acc44c7 100644
--- a/packages/mesh-common/src/utils/bigNum.ts
+++ b/packages/mesh-common/src/utils/bigNum.ts
@@ -1,10 +1,21 @@
export class BigNum {
value: bigint;
- constructor(value: number | string) {
+ constructor(value?: bigint | number | string) {
+ if (!value) {
+ this.value = BigInt(0);
+ return;
+ }
this.value = BigInt(value);
}
+ static new(value: number | string | bigint | undefined): BigNum {
+ if (!value) {
+ return new BigNum(0);
+ }
+ return new BigNum(value);
+ }
+
// Operators
divFloor(other: BigNum): BigNum {
@@ -49,10 +60,6 @@ export class BigNum {
}
}
- static new = (value: number | string): BigNum => {
- return new BigNum(value);
- };
-
// Override
toString(): string {
diff --git a/packages/mesh-common/test/data/mesh/aliases.test.ts b/packages/mesh-common/test/data/mesh/aliases.test.ts
index c9cb4d3a6..fe07568f2 100644
--- a/packages/mesh-common/test/data/mesh/aliases.test.ts
+++ b/packages/mesh-common/test/data/mesh/aliases.test.ts
@@ -5,7 +5,8 @@ import {
mTxOutRef,
outputReference,
txOutRef,
-} from "../../../src";
+} from "@meshsdk/common";
+
import { serializeData } from "./common";
const testHash = "baefdc6c5b191be372a794cd8d40d839ec0dbdd3c28957267dc81700";
diff --git a/packages/mesh-common/test/data/mesh/common.ts b/packages/mesh-common/test/data/mesh/common.ts
index b19bbac3e..99f6336dd 100644
--- a/packages/mesh-common/test/data/mesh/common.ts
+++ b/packages/mesh-common/test/data/mesh/common.ts
@@ -1,7 +1,6 @@
+import { Data } from "@meshsdk/common";
import { castDataToPlutusData } from "@meshsdk/core-csl";
-import { Data } from "../../../src";
-
export const serializeData = (mesh: Data, json: any) => {
const meshData = castDataToPlutusData({
type: "Mesh",
diff --git a/packages/mesh-common/test/data/mesh/constructors.test.ts b/packages/mesh-common/test/data/mesh/constructors.test.ts
index ab2c18209..46ea13503 100644
--- a/packages/mesh-common/test/data/mesh/constructors.test.ts
+++ b/packages/mesh-common/test/data/mesh/constructors.test.ts
@@ -4,12 +4,12 @@ import {
conStr0,
conStr1,
conStr2,
- Data,
mConStr,
mConStr0,
mConStr1,
mConStr2,
-} from "../../../src";
+} from "@meshsdk/common";
+
import { serializeData } from "./common";
const testByteString = "abcd";
diff --git a/packages/mesh-common/test/data/mesh/credentials.test.ts b/packages/mesh-common/test/data/mesh/credentials.test.ts
index 097e393ad..72db3cd8c 100644
--- a/packages/mesh-common/test/data/mesh/credentials.test.ts
+++ b/packages/mesh-common/test/data/mesh/credentials.test.ts
@@ -1,15 +1,12 @@
import {
- conStr0,
- conStr1,
maybeStakingHash,
mMaybeStakingHash,
mPubKeyAddress,
mScriptAddress,
pubKeyAddress,
- pubKeyHash,
scriptAddress,
- scriptHash,
-} from "../../../src";
+} from "@meshsdk/common";
+
import { serializeData } from "./common";
const testKeyHash1 = "1e4eb194e3335a0dcc4f5c5d009318167c583bb3b0879d9f718cd9e0";
diff --git a/packages/mesh-common/test/data/mesh/primitives.test.ts b/packages/mesh-common/test/data/mesh/primitives.test.ts
index aaebd06b1..65e92aa60 100644
--- a/packages/mesh-common/test/data/mesh/primitives.test.ts
+++ b/packages/mesh-common/test/data/mesh/primitives.test.ts
@@ -3,7 +3,8 @@ import {
mBool,
mPlutusBSArrayToString,
mStringToPlutusBSArray,
-} from "../../../src";
+} from "@meshsdk/common";
+
import { serializeData } from "./common";
describe("Plutus data type", () => {
diff --git a/packages/mesh-common/test/data/value.test.ts b/packages/mesh-common/test/data/value.test.ts
deleted file mode 100644
index 94d65ab5f..000000000
--- a/packages/mesh-common/test/data/value.test.ts
+++ /dev/null
@@ -1,108 +0,0 @@
-import {
- Asset,
- byteString,
- ByteString,
- dict,
- Dict,
- Integer,
- integer,
- parsePlutusValueToAssets,
- Value,
- value,
-} from "../../src";
-
-describe("value", () => {
- test("Simple ADA Value", () => {
- const val: Asset[] = [{ unit: "lovelace", quantity: "1000000" }];
- const datum: Value = value(val);
-
- const nameMap = dict([[byteString(""), integer(1000000)]]);
- const valMap = dict>([[byteString(""), nameMap]]);
- expect(JSON.stringify(datum)).toBe(JSON.stringify(valMap));
- });
- test("Simple token Value", () => {
- const val: Asset[] = [
- {
- unit: "baefdc6c5b191be372a794cd8d40d839ec0dbdd3c28957267dc8170074657374696e676e657777616c2e616461",
- quantity: "345",
- },
- ];
- const datum: Value = value(val);
-
- const nameMap = dict([
- [byteString("74657374696e676e657777616c2e616461"), integer(345)],
- ]);
- const valMap = dict>([
- [
- byteString("baefdc6c5b191be372a794cd8d40d839ec0dbdd3c28957267dc81700"),
- nameMap,
- ],
- ]);
- expect(JSON.stringify(datum)).toBe(JSON.stringify(valMap));
- });
- test("Complex Value", () => {
- const val: Asset[] = [
- { unit: "lovelace", quantity: "1000000" },
- {
- unit: "baefdc6c5b191be372a794cd8d40d839ec0dbdd3c28957267dc8170074657374696e676e657777616c2e616461",
- quantity: "345",
- },
- {
- unit: "baefdc6c5b191be372a794cd8d40d839ec0dbdd3c28957267dc817001234",
- quantity: "567",
- },
- ];
- const datum: Value = value(val);
-
- const nameMap = dict([
- [byteString("1234"), integer(567)],
- [byteString("74657374696e676e657777616c2e616461"), integer(345)],
- ]);
- const valMap = dict>([
- [byteString(""), dict([[byteString(""), integer(1000000)]])],
- [
- byteString("baefdc6c5b191be372a794cd8d40d839ec0dbdd3c28957267dc81700"),
- nameMap,
- ],
- ]);
- expect(JSON.stringify(datum)).toBe(JSON.stringify(valMap));
- });
-});
-
-describe("Value", () => {
- test("Simple ADA Value", () => {
- const val: Asset[] = [{ unit: "lovelace", quantity: "1000000" }];
- const plutusValue: Value = value(val);
- const assets: Asset[] = parsePlutusValueToAssets(plutusValue);
-
- expect(JSON.stringify(val)).toBe(JSON.stringify(assets));
- });
- test("Simple token Value", () => {
- const val: Asset[] = [
- {
- unit: "baefdc6c5b191be372a794cd8d40d839ec0dbdd3c28957267dc8170074657374696e676e657777616c2e616461",
- quantity: "345",
- },
- ];
- const plutusValue: Value = value(val);
- const assets: Asset[] = parsePlutusValueToAssets(plutusValue);
-
- expect(JSON.stringify(val)).toBe(JSON.stringify(assets));
- });
- test("Complex Value", () => {
- const val: Asset[] = [
- { unit: "lovelace", quantity: "1000000" },
- {
- unit: "baefdc6c5b191be372a794cd8d40d839ec0dbdd3c28957267dc817001234",
- quantity: "567",
- },
- {
- unit: "baefdc6c5b191be372a794cd8d40d839ec0dbdd3c28957267dc8170074657374696e676e657777616c2e616461",
- quantity: "345",
- },
- ];
- const plutusValue: Value = value(val);
- const assets: Asset[] = parsePlutusValueToAssets(plutusValue);
- expect(JSON.stringify(val)).toBe(JSON.stringify(assets));
- });
-});
diff --git a/packages/mesh-common/test/data/value/accessor.test.ts b/packages/mesh-common/test/data/value/accessor.test.ts
new file mode 100644
index 000000000..4e9e15735
--- /dev/null
+++ b/packages/mesh-common/test/data/value/accessor.test.ts
@@ -0,0 +1,68 @@
+import { MeshValue } from "@meshsdk/common";
+
+import { mockUnit } from "./common";
+
+describe("MeshValue class", () => {
+ describe("get", () => {
+ it("should return the quantity of an existing asset", () => {
+ const value = new MeshValue({
+ lovelace: 20n,
+ [mockUnit]: 10n,
+ });
+ expect(value.get("lovelace")).toEqual(BigInt(20));
+ expect(value.get(mockUnit)).toEqual(BigInt(10));
+ });
+
+ it("should return 0 for a non-existing asset", () => {
+ const value = new MeshValue({ lovelace: 20n });
+ expect(value.get(mockUnit)).toEqual(BigInt(0));
+ });
+
+ it("should handle an empty value object", () => {
+ const value = new MeshValue();
+ expect(value.get("lovelace")).toEqual(BigInt(0));
+ });
+
+ it("should return the correct quantity after adding assets", () => {
+ const value = new MeshValue({ lovelace: 20n });
+ value.addAsset({
+ unit: mockUnit,
+ quantity: "10",
+ });
+ expect(value.get(mockUnit)).toEqual(BigInt(10));
+ });
+
+ it("should return the correct quantity after subtracting assets", () => {
+ const value = new MeshValue({
+ lovelace: 20n,
+ [mockUnit]: 10n,
+ });
+ value.negateAssets([
+ {
+ unit: mockUnit,
+ quantity: "5",
+ },
+ ]);
+ expect(value.get(mockUnit)).toEqual(BigInt(5));
+ });
+ });
+ describe("units", () => {
+ it("should return an empty object when value is empty", () => {
+ const value = new MeshValue();
+ expect(value.units()).toEqual([]);
+ });
+
+ it("should return the correct structure for a single asset", () => {
+ const value = new MeshValue({ lovelace: 20n });
+ expect(value.units()).toEqual(["lovelace"]);
+ });
+
+ it("should return the correct structure for multiple assets", () => {
+ const value = new MeshValue({
+ lovelace: 20n,
+ [mockUnit]: 10n,
+ });
+ expect(value.units()).toEqual(["lovelace", mockUnit]);
+ });
+ });
+});
diff --git a/packages/mesh-common/test/data/value/common.ts b/packages/mesh-common/test/data/value/common.ts
new file mode 100644
index 000000000..8c531bda7
--- /dev/null
+++ b/packages/mesh-common/test/data/value/common.ts
@@ -0,0 +1,4 @@
+export const mockPolicyId =
+ "c21d710605bb00e69f3c175150552fc498316d80e7efdb1b186db38c";
+export const mockAssetName = "000643b04d65736820676f6f64";
+export const mockUnit = mockPolicyId + mockAssetName;
diff --git a/packages/mesh-common/test/data/value/comparator.test.ts b/packages/mesh-common/test/data/value/comparator.test.ts
new file mode 100644
index 000000000..f035ca054
--- /dev/null
+++ b/packages/mesh-common/test/data/value/comparator.test.ts
@@ -0,0 +1,111 @@
+import { MeshValue } from "@meshsdk/common";
+
+import { mockUnit } from "./common";
+
+describe("MeshValue class", () => {
+ describe("geq", () => {
+ it("should return true if the value is greater than or equal to the target value for a specific unit", () => {
+ const value = new MeshValue({ lovelace: 20n, [mockUnit]: 10n });
+ const target = new MeshValue({ lovelace: 10n, [mockUnit]: 5n });
+ expect(value.geq(target)).toBe(true);
+ });
+
+ it("should return false if the value is less than the target value for a specific unit", () => {
+ const value = new MeshValue({ lovelace: 20n, [mockUnit]: 10n });
+ const target = new MeshValue({ lovelace: 30n, [mockUnit]: 15n });
+ expect(value.geq(target)).toBe(false);
+ });
+
+ it("should return true if the value is equal to the target value for a specific unit", () => {
+ const value = new MeshValue({ lovelace: 20n, [mockUnit]: 10n });
+ const target = new MeshValue({ lovelace: 20n, [mockUnit]: 10n });
+ expect(value.geq(target)).toBe(true);
+ });
+ });
+ describe("geqUnit", () => {
+ it("should return true if the value is greater than or equal to the target value for a specific unit", () => {
+ const value = new MeshValue({ lovelace: 20n, [mockUnit]: 10n });
+ const target = new MeshValue({ lovelace: 10n, [mockUnit]: 5n });
+ expect(value.geqUnit("lovelace", target)).toBe(true);
+ expect(value.geqUnit(mockUnit, target)).toBe(true);
+ });
+
+ it("should return false if the value is less than the target value for a specific unit", () => {
+ const value = new MeshValue({ lovelace: 20n, [mockUnit]: 10n });
+ const target = new MeshValue({ lovelace: 30n, [mockUnit]: 15n });
+ expect(value.geqUnit("lovelace", target)).toBe(false);
+ expect(value.geqUnit(mockUnit, target)).toBe(false);
+ });
+
+ it("should return true if the value is equal to the target value for a specific unit", () => {
+ const value = new MeshValue({ lovelace: 20n, [mockUnit]: 10n });
+ const target = new MeshValue({ lovelace: 20n, [mockUnit]: 10n });
+ expect(value.geqUnit("lovelace", target)).toBe(true);
+ expect(value.geqUnit(mockUnit, target)).toBe(true);
+ });
+
+ 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);
+ });
+ });
+ describe("leq", () => {
+ it("should return true if the value is less than or equal to the target value for a specific unit", () => {
+ const value = new MeshValue({ lovelace: 20n, [mockUnit]: 10n });
+ const target = new MeshValue({ lovelace: 30n, [mockUnit]: 15n });
+ expect(value.leq(target)).toBe(true);
+ });
+
+ it("should return false if the value is greater than the target value for a specific unit", () => {
+ const value = new MeshValue({ lovelace: 20n, [mockUnit]: 10n });
+ const target = new MeshValue({ lovelace: 10n, [mockUnit]: 5n });
+ expect(value.leq(target)).toBe(false);
+ });
+
+ it("should return true if the value is equal to the target value for a specific unit", () => {
+ const value = new MeshValue({ lovelace: 20n, [mockUnit]: 10n });
+ const target = new MeshValue({ lovelace: 20n, [mockUnit]: 10n });
+ expect(value.leq(target)).toBe(true);
+ });
+ });
+ describe("leqUnit", () => {
+ it("should return true if the value is less than or equal to the target value for a specific unit", () => {
+ const value = new MeshValue({ lovelace: 20n, [mockUnit]: 10n });
+ const target = new MeshValue({ lovelace: 30n, [mockUnit]: 15n });
+ expect(value.leqUnit("lovelace", target)).toBe(true);
+ expect(value.leqUnit(mockUnit, target)).toBe(true);
+ });
+
+ it("should return false if the value is greater than the target value for a specific unit", () => {
+ const value = new MeshValue({ lovelace: 20n, [mockUnit]: 10n });
+ const target = new MeshValue({ lovelace: 10n, [mockUnit]: 5n });
+ expect(value.leqUnit("lovelace", target)).toBe(false);
+ expect(value.leqUnit(mockUnit, target)).toBe(false);
+ });
+
+ it("should return true if the value is equal to the target value for a specific unit", () => {
+ const value = new MeshValue({ lovelace: 20n, [mockUnit]: 10n });
+ const target = new MeshValue({ lovelace: 20n, [mockUnit]: 10n });
+ expect(value.leqUnit("lovelace", target)).toBe(true);
+ expect(value.leqUnit(mockUnit, target)).toBe(true);
+ });
+
+ 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.leqUnit("somethingElse", target)).toBe(false);
+ });
+ });
+ describe("isEmpty", () => {
+ it("should return true if the value is empty", () => {
+ const value = new MeshValue();
+ expect(value.isEmpty()).toBe(true);
+ });
+
+ it("should return false if the value is not empty", () => {
+ const value = new MeshValue({ lovelace: 20n });
+ expect(value.isEmpty()).toBe(false);
+ });
+ });
+});
diff --git a/packages/mesh-common/test/data/value/convertor.test.ts b/packages/mesh-common/test/data/value/convertor.test.ts
new file mode 100644
index 000000000..bfff721f7
--- /dev/null
+++ b/packages/mesh-common/test/data/value/convertor.test.ts
@@ -0,0 +1,173 @@
+import {
+ Asset,
+ byteString,
+ dict,
+ Dict,
+ Integer,
+ integer,
+ MeshValue,
+ MValue,
+ mValue,
+ Value,
+ value,
+} from "@meshsdk/common";
+
+import { mockUnit } from "./common";
+
+describe("value", () => {
+ it("should create a new Value instance with the correct value", () => {
+ const val: Asset[] = [{ unit: "lovelace", quantity: "1000000" }];
+ const datum: Value = value(val);
+ const nameMap = dict([[byteString(""), integer(1000000)]]);
+ const valMap = dict>([[byteString(""), nameMap]]);
+ expect(JSON.stringify(datum)).toBe(JSON.stringify(valMap));
+ });
+ it("Simple token Value", () => {
+ const val: Asset[] = [
+ {
+ unit: "baefdc6c5b191be372a794cd8d40d839ec0dbdd3c28957267dc8170074657374696e676e657777616c2e616461",
+ quantity: "345",
+ },
+ ];
+ const datum: Value = value(val);
+ const nameMap = dict([
+ [byteString("74657374696e676e657777616c2e616461"), integer(345)],
+ ]);
+ const valMap = dict>([
+ [
+ byteString("baefdc6c5b191be372a794cd8d40d839ec0dbdd3c28957267dc81700"),
+ nameMap,
+ ],
+ ]);
+ expect(JSON.stringify(datum)).toBe(JSON.stringify(valMap));
+ });
+ it("Complex Value", () => {
+ const val: Asset[] = [
+ { unit: "lovelace", quantity: "1000000" },
+ {
+ unit: "baefdc6c5b191be372a794cd8d40d839ec0dbdd3c28957267dc8170074657374696e676e657777616c2e616461",
+ quantity: "345",
+ },
+ {
+ unit: "baefdc6c5b191be372a794cd8d40d839ec0dbdd3c28957267dc817001234",
+ quantity: "567",
+ },
+ ];
+ const datum: Value = value(val);
+
+ const nameMap = dict([
+ [byteString("1234"), integer(567)],
+ [byteString("74657374696e676e657777616c2e616461"), integer(345)],
+ ]);
+ const valMap = dict>([
+ [byteString(""), dict([[byteString(""), integer(1000000)]])],
+ [
+ byteString("baefdc6c5b191be372a794cd8d40d839ec0dbdd3c28957267dc81700"),
+ nameMap,
+ ],
+ ]);
+ expect(JSON.stringify(datum)).toBe(JSON.stringify(valMap));
+ });
+});
+
+describe("mValue", () => {
+ it("should create a new Value instance with the correct value", () => {
+ const val: Asset[] = [{ unit: "lovelace", quantity: "1000000" }];
+ const datum: MValue = mValue(val);
+ const nameMap = new Map().set("", 1000000);
+ const valMap = new Map().set("", nameMap);
+ expect(JSON.stringify(datum)).toBe(JSON.stringify(valMap));
+ });
+ it("Simple token Value", () => {
+ const val: Asset[] = [
+ {
+ unit: "baefdc6c5b191be372a794cd8d40d839ec0dbdd3c28957267dc8170074657374696e676e657777616c2e616461",
+ quantity: "345",
+ },
+ ];
+ const datum: MValue = mValue(val);
+ const nameMap = new Map().set("74657374696e676e657777616c2e616461", 345);
+ const valMap = new Map().set(
+ "baefdc6c5b191be372a794cd8d40d839ec0dbdd3c28957267dc81700",
+ nameMap,
+ );
+ expect(JSON.stringify(datum)).toBe(JSON.stringify(valMap));
+ });
+ it("Complex Value", () => {
+ const val: Asset[] = [
+ { unit: "lovelace", quantity: "1000000" },
+ {
+ unit: "baefdc6c5b191be372a794cd8d40d839ec0dbdd3c28957267dc8170074657374696e676e657777616c2e616461",
+ quantity: "345",
+ },
+ {
+ unit: "baefdc6c5b191be372a794cd8d40d839ec0dbdd3c28957267dc817001234",
+ quantity: "567",
+ },
+ ];
+ const datum: MValue = mValue(val);
+
+ const lovelaceMap = new Map().set("", 1000000);
+ const tokenMap = new Map()
+ .set("1234", 567)
+ .set("74657374696e676e657777616c2e616461", 345);
+ const valMap = new Map()
+ .set("", lovelaceMap)
+ .set(
+ "baefdc6c5b191be372a794cd8d40d839ec0dbdd3c28957267dc81700",
+ tokenMap,
+ );
+ expect(JSON.stringify(datum)).toBe(JSON.stringify(valMap));
+ });
+});
+
+describe("MeshValue class", () => {
+ describe("fromAssets", () => {
+ it("should create a new Value instance with the correct value", () => {
+ const assets: Asset[] = [
+ { unit: mockUnit, quantity: "100" },
+ { unit: "lovelace", quantity: "10" },
+ ];
+ const value = MeshValue.fromAssets(assets);
+ expect(value.value).toEqual({
+ [mockUnit]: BigInt(100),
+ lovelace: BigInt(10),
+ });
+ });
+ });
+ describe("toAssets", () => {
+ test("Simple ADA Value", () => {
+ const val: Asset[] = [{ unit: "lovelace", quantity: "1000000" }];
+ const plutusValue: Value = value(val);
+ const assets: Asset[] = MeshValue.fromValue(plutusValue).toAssets();
+ expect(JSON.stringify(val)).toBe(JSON.stringify(assets));
+ });
+ test("Simple token Value", () => {
+ const val: Asset[] = [
+ {
+ unit: "baefdc6c5b191be372a794cd8d40d839ec0dbdd3c28957267dc8170074657374696e676e657777616c2e616461",
+ quantity: "345",
+ },
+ ];
+ const plutusValue: Value = value(val);
+ const assets: Asset[] = MeshValue.fromValue(plutusValue).toAssets();
+ expect(JSON.stringify(val)).toBe(JSON.stringify(assets));
+ });
+ test("Complex Value", () => {
+ const val: Asset[] = [
+ { unit: "lovelace", quantity: "1000000" },
+ {
+ unit: "baefdc6c5b191be372a794cd8d40d839ec0dbdd3c28957267dc817001234",
+ quantity: "567",
+ },
+ {
+ unit: "baefdc6c5b191be372a794cd8d40d839ec0dbdd3c28957267dc8170074657374696e676e657777616c2e616461",
+ quantity: "345",
+ },
+ ];
+ const plutusValue: Value = value(val);
+ const assets: Asset[] = MeshValue.fromValue(plutusValue).toAssets();
+ expect(JSON.stringify(val)).toBe(JSON.stringify(assets));
+ });
+ });
+});
diff --git a/packages/mesh-common/test/data/value/operators.test.ts b/packages/mesh-common/test/data/value/operators.test.ts
new file mode 100644
index 000000000..aac75488a
--- /dev/null
+++ b/packages/mesh-common/test/data/value/operators.test.ts
@@ -0,0 +1,153 @@
+import { Asset, MeshValue } from "@meshsdk/common";
+
+import { mockUnit } from "./common";
+
+describe("MeshValue class", () => {
+ describe("addAsset", () => {
+ it("should add a new asset correctly", () => {
+ const value = new MeshValue();
+ const singleAsset: Asset = { unit: mockUnit, quantity: "100" };
+ value.addAsset(singleAsset);
+ expect(value.value).toEqual({ [mockUnit]: BigInt(100) });
+ });
+ it("should add to an existing asset correctly", () => {
+ const value = new MeshValue();
+ const singleAsset: Asset = { unit: mockUnit, quantity: "100" };
+ value.addAsset(singleAsset);
+ value.addAsset(singleAsset);
+ expect(value.value).toEqual({ [mockUnit]: BigInt(200) });
+ });
+ it("should add multiple assets correctly", () => {
+ const value = new MeshValue();
+ const assets: Asset[] = [
+ { unit: mockUnit, quantity: "100" },
+ { unit: "lovelace", quantity: "10" },
+ ];
+ value.addAsset(assets[0]!).addAsset(assets[1]!);
+ expect(value.value).toEqual({
+ [mockUnit]: BigInt(100),
+ lovelace: BigInt(10),
+ });
+ });
+ });
+ describe("addAssets", () => {
+ it("should add multiple assets correctly", () => {
+ 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);
+ expect(value.value).toEqual({
+ [mockUnit]: BigInt(200),
+ lovelace: BigInt(20),
+ });
+ });
+ it("should add multiple assets correctly with different units", () => {
+ const value = new MeshValue();
+ const assets: Asset[] = [
+ { unit: mockUnit, quantity: "100" },
+ { unit: "lovelace", quantity: "10" },
+ { unit: "USDC", quantity: "100" },
+ { unit: "lovelace", quantity: "10" },
+ ];
+ value.addAssets(assets);
+ expect(value.value).toEqual({
+ [mockUnit]: BigInt(100),
+ lovelace: BigInt(20),
+ USDC: BigInt(100),
+ });
+ });
+ });
+ describe("negateAsset", () => {
+ describe("negateAsset", () => {
+ it("should subtract quantity from an existing asset", () => {
+ const value = new MeshValue();
+ value.value = { lovelace: 10n };
+ value.negateAsset({ unit: "lovelace", quantity: "5" });
+ expect(value.value).toEqual({ lovelace: BigInt(5) });
+ });
+
+ it("should remove the asset if the resulting quantity is zero", () => {
+ const value = new MeshValue();
+ value.value = { lovelace: 10n };
+ value.negateAsset({ unit: "lovelace", quantity: "10" });
+ expect(value.value.lovelace).toBeUndefined();
+ });
+
+ it("should allow negative quantity if the subtraction results in negative value", () => {
+ const value = new MeshValue();
+ value.value = { lovelace: 10n };
+ value.negateAsset({ unit: "lovelace", quantity: "15" });
+ expect(Object.keys(value.value).length).toBe(0);
+ });
+
+ it("should add a new asset with negative quantity if the asset does not exist", () => {
+ const value = new MeshValue();
+ value.negateAsset({ unit: "lovelace", quantity: "5" });
+ expect(Object.keys(value.value).length).toBe(0);
+ });
+ });
+ });
+ describe("negateAssets", () => {
+ it("should subtract quantities from existing assets", () => {
+ const value = new MeshValue();
+ value.value = { lovelace: 20n, [mockUnit]: 10n };
+ value.negateAssets([
+ { unit: "lovelace", quantity: "5" },
+ { unit: mockUnit, quantity: "3" },
+ ]);
+ expect(value.value).toEqual({
+ lovelace: BigInt(15),
+ [mockUnit]: BigInt(7),
+ });
+ });
+
+ it("should remove the asset if the resulting quantity is zero", () => {
+ const value = new MeshValue();
+ value.value = { lovelace: 10n, [mockUnit]: 5n };
+ value.negateAssets([
+ { unit: "lovelace", quantity: "10" },
+ { unit: mockUnit, quantity: "5" },
+ ]);
+ expect(Object.keys(value.value).length).toBe(0);
+ });
+
+ it("should allow negative quantity if the subtraction results in negative value", () => {
+ const value = new MeshValue();
+ value.value = { lovelace: 10n, [mockUnit]: 5n };
+ value.negateAssets([
+ { unit: "lovelace", quantity: "15" },
+ { unit: mockUnit, quantity: "10" },
+ ]);
+ expect(Object.keys(value.value).length).toBe(0);
+ });
+ });
+
+ describe("merge", () => {
+ it("should merge two values correctly", () => {
+ const value1 = new MeshValue();
+ value1.value = { lovelace: 20n, [mockUnit]: 10n };
+ const value2 = new MeshValue();
+ value2.value = { lovelace: 10n, [mockUnit]: 5n };
+ expect(value1.merge(value2).value).toEqual({
+ lovelace: 30n,
+ [mockUnit]: 15n,
+ });
+ });
+
+ it("should merge two values correctly with different units", () => {
+ const value1 = new MeshValue();
+ value1.value = { lovelace: 20n, [mockUnit]: 10n };
+ const value2 = new MeshValue();
+ value2.value = { ETH: 10n, [mockUnit]: 5n };
+ expect(value1.merge(value2).value).toEqual({
+ lovelace: 20n,
+ [mockUnit]: 15n,
+ ETH: 10n,
+ });
+ });
+ });
+});
diff --git a/packages/mesh-common/test/utils/bigNum.test.ts b/packages/mesh-common/test/utils/bigNum.test.ts
new file mode 100644
index 000000000..22cd11096
--- /dev/null
+++ b/packages/mesh-common/test/utils/bigNum.test.ts
@@ -0,0 +1,157 @@
+import { BigNum } from "@meshsdk/common";
+
+describe("BigNum class", () => {
+ describe("constructor", () => {
+ it("should get correct new BigNum with number", () => {
+ const bigNum = new BigNum(100);
+ expect(bigNum.value).toBe(BigInt(100));
+ });
+ it("should get correct new BigNum with string", () => {
+ const bigNum = new BigNum("100");
+ expect(bigNum.value).toBe(BigInt(100));
+ });
+ it("should get correct new BigNum with bigint", () => {
+ const bigNum = new BigNum(BigInt(100));
+ expect(bigNum.value).toBe(BigInt(100));
+ });
+ it("should get correct new BigNum without param", () => {
+ const bigNum = new BigNum();
+ expect(bigNum.value).toBe(BigInt(0));
+ });
+ });
+ describe("new", () => {
+ it("should get correct new BigNum with number", () => {
+ const bigNum = BigNum.new(100);
+ expect(bigNum.value).toBe(BigInt(100));
+ });
+ it("should get correct new BigNum with string", () => {
+ const bigNum = BigNum.new("100");
+ expect(bigNum.value).toBe(BigInt(100));
+ });
+ it("should get correct new BigNum with bigint", () => {
+ const bigNum = BigNum.new(BigInt(100));
+ expect(bigNum.value).toBe(BigInt(100));
+ });
+ it("should get correct new BigNum without param", () => {
+ const bigNum = BigNum.new(undefined);
+ expect(bigNum.value).toBe(BigInt(0));
+ });
+ });
+ describe("divFloor", () => {
+ it("should get correct divFloor", () => {
+ const bigNum = new BigNum(100);
+ const other = new BigNum(10);
+ const result = bigNum.divFloor(other);
+ expect(result.value).toBe(BigInt(10));
+ });
+ it("should get correct divFloor with remainder", () => {
+ const bigNum = new BigNum(101);
+ const other = new BigNum(10);
+ const result = bigNum.divFloor(other);
+ expect(result.value).toBe(BigInt(10));
+ });
+ });
+ describe("checkedMul", () => {
+ it("should get correct checkedMul", () => {
+ const bigNum = new BigNum(100);
+ const other = new BigNum(10);
+ const result = bigNum.checkedMul(other);
+ expect(result.value).toBe(BigInt(1000));
+ });
+ it("should get correct checkedMul with negative", () => {
+ const bigNum = new BigNum(100);
+ const other = new BigNum(-10);
+ const result = bigNum.checkedMul(other);
+ expect(result.value).toBe(BigInt(-1000));
+ });
+ });
+ describe("checkedAdd", () => {
+ it("should get correct checkedAdd", () => {
+ const bigNum = new BigNum(100);
+ const other = new BigNum(10);
+ const result = bigNum.checkedAdd(other);
+ expect(result.value).toBe(BigInt(110));
+ });
+ it("should get correct checkedAdd with negative", () => {
+ const bigNum = new BigNum(100);
+ const other = new BigNum(-10);
+ const result = bigNum.checkedAdd(other);
+ expect(result.value).toBe(BigInt(90));
+ });
+ });
+ describe("checkedSub", () => {
+ it("should get correct checkedSub", () => {
+ const bigNum = new BigNum(100);
+ const other = new BigNum(10);
+ const result = bigNum.checkedSub(other);
+ expect(result.value).toBe(BigInt(90));
+ });
+ it("should get correct checkedSub with negative", () => {
+ const bigNum = new BigNum(100);
+ const other = new BigNum(110);
+ const result = bigNum.checkedSub(other);
+ expect(result.value).toBe(BigInt(-10));
+ });
+ });
+ describe("clampedSub", () => {
+ it("should get correct clampedSub", () => {
+ const bigNum = new BigNum(100);
+ const other = new BigNum(10);
+ const result = bigNum.clampedSub(other);
+ expect(result.value).toBe(BigInt(90));
+ });
+ it("should get correct clampedSub with negative", () => {
+ const bigNum = new BigNum(100);
+ const other = new BigNum(110);
+ const result = bigNum.clampedSub(other);
+ expect(result.value).toBe(BigInt(0));
+ });
+ });
+ describe("lessThan", () => {
+ it("should get correct lessThan", () => {
+ const bigNum = new BigNum(100);
+ const other = new BigNum(110);
+ const result = bigNum.lessThan(other);
+ expect(result).toBe(true);
+ });
+ it("should get correct lessThan with equal", () => {
+ const bigNum = new BigNum(100);
+ const other = new BigNum(100);
+ const result = bigNum.lessThan(other);
+ expect(result).toBe(false);
+ });
+ it("should get correct lessThan with greater", () => {
+ const bigNum = new BigNum(100);
+ const other = new BigNum(90);
+ const result = bigNum.lessThan(other);
+ expect(result).toBe(false);
+ });
+ });
+ describe("compare", () => {
+ it("should get correct compare", () => {
+ const bigNum = new BigNum(100);
+ const other = new BigNum(110);
+ const result = bigNum.compare(other);
+ expect(result).toBe(-1);
+ });
+ it("should get correct compare with equal", () => {
+ const bigNum = new BigNum(100);
+ const other = new BigNum(100);
+ const result = bigNum.compare(other);
+ expect(result).toBe(0);
+ });
+ it("should get correct compare with greater", () => {
+ const bigNum = new BigNum(100);
+ const other = new BigNum(90);
+ const result = bigNum.compare(other);
+ expect(result).toBe(1);
+ });
+ });
+ describe("toString", () => {
+ it("should get correct toString", () => {
+ const bigNum = new BigNum(100);
+ const result = bigNum.toString();
+ expect(result).toBe("100");
+ });
+ });
+});
diff --git a/packages/mesh-contract/package.json b/packages/mesh-contract/package.json
index 135cc3d45..24d7121eb 100644
--- a/packages/mesh-contract/package.json
+++ b/packages/mesh-contract/package.json
@@ -1,6 +1,6 @@
{
"name": "@meshsdk/contract",
- "version": "1.6.1",
+ "version": "1.6.2",
"description": "",
"main": "./dist/index.cjs",
"module": "./dist/index.js",
diff --git a/packages/mesh-contract/src/common.ts b/packages/mesh-contract/src/common.ts
index cb87309ff..5562367f4 100644
--- a/packages/mesh-contract/src/common.ts
+++ b/packages/mesh-contract/src/common.ts
@@ -164,20 +164,24 @@ export class MeshTxInitiator {
};
protected _getUtxoByTxHash = async (
- scriptCbor: string,
txHash: string,
+ scriptCbor?: string,
): Promise => {
if (this.fetcher) {
const utxos = await this.fetcher?.fetchUTxOs(txHash);
- const scriptAddr = v2ScriptToBech32(
- scriptCbor,
- undefined,
- this.networkId,
- );
+ let scriptUtxo = utxos[0];
- const scriptUtxo =
- utxos.filter((utxo) => utxo.output.address === scriptAddr)[0] ||
- utxos[0];
+ if (scriptCbor) {
+ const scriptAddr = v2ScriptToBech32(
+ scriptCbor,
+ undefined,
+ this.networkId,
+ );
+ scriptUtxo =
+ utxos.filter((utxo) => utxo.output.address === scriptAddr)[0] ||
+ utxos[0];
+ }
+
return scriptUtxo;
}
diff --git a/packages/mesh-contract/src/escrow/offchain.ts b/packages/mesh-contract/src/escrow/offchain.ts
index 892ed333f..8530ef321 100644
--- a/packages/mesh-contract/src/escrow/offchain.ts
+++ b/packages/mesh-contract/src/escrow/offchain.ts
@@ -5,11 +5,11 @@ import {
conStr1,
mConStr1,
mConStr2,
- parsePlutusValueToAssets,
PubKeyAddress,
pubKeyAddress,
Value,
value,
+ MeshValue
} from "@meshsdk/common";
import {
Asset,
@@ -113,8 +113,8 @@ export class MeshEscrowContract extends MeshTxInitiator {
const initiatorAddress = serializeAddressObj(initiatorAddressObj);
const recipientAddress = serializeAddressObj(recipientAddressObj!);
- const initiatorToReceive = parsePlutusValueToAssets(initiatorAmount);
- const recipientToReceive = parsePlutusValueToAssets(recipientAmount!);
+ const initiatorToReceive = MeshValue.fromValue(initiatorAmount).toAssets();
+ const recipientToReceive = MeshValue.fromValue(recipientAmount!).toAssets();
this.mesh
.txOut(initiatorAddress, initiatorToReceive)
.txOut(recipientAddress, recipientToReceive);
@@ -164,7 +164,7 @@ export class MeshEscrowContract extends MeshTxInitiator {
depositAmount,
);
- const inputAssets = parsePlutusValueToAssets(inputDatum.fields[1]);
+ const inputAssets = MeshValue.fromValue(inputDatum.fields[1]).toAssets();
const escrowAmount = mergeAssets([...depositAmount, ...inputAssets]);
await this.mesh
@@ -218,8 +218,8 @@ export class MeshEscrowContract extends MeshTxInitiator {
] = inputDatum.fields;
const initiatorAddress = serializeAddressObj(initiatorAddressObj);
const recipientAddress = serializeAddressObj(recipientAddressObj);
- const initiatorToReceive = parsePlutusValueToAssets(recipientAmount);
- const recipientToReceive = parsePlutusValueToAssets(initiatorAmount);
+ const initiatorToReceive = MeshValue.fromValue(recipientAmount).toAssets();
+ const recipientToReceive = MeshValue.fromValue(initiatorAmount).toAssets();
await this.mesh
.spendingPlutusScriptV2()
@@ -249,6 +249,6 @@ export class MeshEscrowContract extends MeshTxInitiator {
};
getUtxoByTxHash = async (txHash: string): Promise => {
- return await this._getUtxoByTxHash(this.scriptCbor, txHash);
+ return await this._getUtxoByTxHash(txHash, this.scriptCbor);
};
}
diff --git a/packages/mesh-contract/src/giftcard/offchain.ts b/packages/mesh-contract/src/giftcard/offchain.ts
index dae67bae1..379edcf4f 100644
--- a/packages/mesh-contract/src/giftcard/offchain.ts
+++ b/packages/mesh-contract/src/giftcard/offchain.ts
@@ -27,12 +27,17 @@ export class MeshGiftCardContract extends MeshTxInitiator {
tokenNameHex: string = "";
paramUtxo: UTxO["input"] = { outputIndex: 0, txHash: "" };
- giftCardCbor = (tokenNameHex: string, utxoTxHash: string, utxoTxId: number) =>
- applyParamsToScript(
+ giftCardCbor = (
+ tokenNameHex: string,
+ utxoTxHash: string,
+ utxoTxId: number,
+ ) => {
+ return applyParamsToScript(
blueprint.validators[0]!.compiledCode,
[builtinByteString(tokenNameHex), txOutRef(utxoTxHash, utxoTxId)],
"JSON",
);
+ };
redeemCbor = (tokenNameHex: string, policyId: string) =>
applyParamsToScript(blueprint.validators[1]!.compiledCode, [
@@ -167,8 +172,7 @@ export class MeshGiftCardContract extends MeshTxInitiator {
};
getUtxoByTxHash = async (txHash: string): Promise => {
- const { redeemScript } = this.getScripts();
- return await this._getUtxoByTxHash(redeemScript, txHash);
+ return await this._getUtxoByTxHash(txHash);
};
private getScripts = () => {
diff --git a/packages/mesh-contract/src/hello-world/offchain.ts b/packages/mesh-contract/src/hello-world/offchain.ts
index 8cbccf5f1..df9048bef 100644
--- a/packages/mesh-contract/src/hello-world/offchain.ts
+++ b/packages/mesh-contract/src/hello-world/offchain.ts
@@ -19,6 +19,6 @@ export class MeshHelloWorldContract extends MeshTxInitiator {
}
getUtxoByTxHash = async (txHash: string): Promise => {
- return await this._getUtxoByTxHash(this.scriptCbor, txHash);
+ return await this._getUtxoByTxHash(txHash, this.scriptCbor);
};
}
diff --git a/packages/mesh-contract/src/marketplace/offchain.ts b/packages/mesh-contract/src/marketplace/offchain.ts
index ab1fc487f..7e943f3cd 100644
--- a/packages/mesh-contract/src/marketplace/offchain.ts
+++ b/packages/mesh-contract/src/marketplace/offchain.ts
@@ -240,6 +240,6 @@ export class MeshMarketplaceContract extends MeshTxInitiator {
};
getUtxoByTxHash = async (txHash: string): Promise => {
- return await this._getUtxoByTxHash(this.scriptCbor, txHash);
+ return await this._getUtxoByTxHash(txHash, this.scriptCbor);
};
}
diff --git a/packages/mesh-contract/src/swap/offchain.ts b/packages/mesh-contract/src/swap/offchain.ts
index 47c608747..40abc2b02 100644
--- a/packages/mesh-contract/src/swap/offchain.ts
+++ b/packages/mesh-contract/src/swap/offchain.ts
@@ -4,12 +4,12 @@ import {
ConStr0,
mConStr0,
mConStr1,
- parsePlutusValueToAssets,
pubKeyAddress,
PubKeyAddress,
UTxO,
value,
Value,
+ MeshValue
} from "@meshsdk/common";
import {
deserializeAddress,
@@ -89,7 +89,7 @@ export class MeshSwapContract extends MeshTxInitiator {
.spendingReferenceTxInInlineDatumPresent()
.spendingReferenceTxInRedeemerValue(mConStr1([]))
.txInScript(this.scriptCbor)
- .txOut(initiatorAddress, parsePlutusValueToAssets(initiatorToReceive))
+ .txOut(initiatorAddress, MeshValue.fromValue(initiatorToReceive).toAssets())
.changeAddress(walletAddress)
.txInCollateral(
collateral.input.txHash,
@@ -134,6 +134,6 @@ export class MeshSwapContract extends MeshTxInitiator {
};
getUtxoByTxHash = async (txHash: string): Promise => {
- return await this._getUtxoByTxHash(this.scriptCbor, txHash);
+ return await this._getUtxoByTxHash(txHash, this.scriptCbor);
};
}
diff --git a/packages/mesh-contract/src/vesting/offchain.ts b/packages/mesh-contract/src/vesting/offchain.ts
index dea32460e..c5ebe3c87 100644
--- a/packages/mesh-contract/src/vesting/offchain.ts
+++ b/packages/mesh-contract/src/vesting/offchain.ts
@@ -112,6 +112,6 @@ export class MeshVestingContract extends MeshTxInitiator {
};
getUtxoByTxHash = async (txHash: string): Promise => {
- return await this._getUtxoByTxHash(this.scriptCbor, txHash);
+ return await this._getUtxoByTxHash(txHash, this.scriptCbor);
};
}
diff --git a/packages/mesh-core-csl/package.json b/packages/mesh-core-csl/package.json
index d212607dd..808c36b95 100644
--- a/packages/mesh-core-csl/package.json
+++ b/packages/mesh-core-csl/package.json
@@ -1,6 +1,6 @@
{
"name": "@meshsdk/core-csl",
- "version": "1.6.1",
+ "version": "1.6.2",
"description": "",
"main": "./dist/index.cjs",
"module": "./dist/index.js",
@@ -20,10 +20,10 @@
"build:mesh": "tsup src/index.ts --format esm,cjs --dts",
"dev": "tsup src/index.ts --format esm,cjs --watch --dts",
"lint": "eslint",
- "test": "jest --verbose",
"clean": "rm -rf .turbo && rm -rf dist && rm -rf node_modules",
"format": "prettier --check . --ignore-path ../../.gitignore",
- "build:docs": "typedoc src/index.ts --json ../../apps/docs/src/data/mesh-core-csl.json"
+ "build:docs": "typedoc src/index.ts --json ../../apps/docs/src/data/mesh-core-csl.json",
+ "test": "jest"
},
"browser": {
"@sidan-lab/sidan-csl-rs-nodejs": "@sidan-lab/sidan-csl-rs-browser"
diff --git a/packages/mesh-core-csl/src/core/serializer.ts b/packages/mesh-core-csl/src/core/serializer.ts
index 97f07c597..c535498ef 100644
--- a/packages/mesh-core-csl/src/core/serializer.ts
+++ b/packages/mesh-core-csl/src/core/serializer.ts
@@ -26,10 +26,10 @@ import {
deserializePlutusScript,
resolveDataHash,
resolveEd25519KeyHash,
- resolvePoolId,
resolvePrivateKey,
resolveRewardAddress,
resolveScriptRef,
+ serializePoolId,
toNativeScript,
} from "../deser";
import {
@@ -43,12 +43,17 @@ import { meshTxBuilderBodyToObj } from "./adaptor";
import { builderDataToCbor } from "./adaptor/data";
export class CSLSerializer implements IMeshTxSerializer {
+ /**
+ * Set to true to enable verbose logging for the txBodyJson prior going into build
+ */
+ verbose: boolean;
protocolParams: Protocol;
meshTxBuilderBody: MeshTxBuilderBody = emptyTxBuilderBody();
- constructor(protocolParams?: Protocol) {
+ constructor(protocolParams?: Protocol, verbose = false) {
this.protocolParams = protocolParams || DEFAULT_PROTOCOL_PARAMETERS;
+ this.verbose = verbose;
}
serializeTxBody(
@@ -59,7 +64,9 @@ export class CSLSerializer implements IMeshTxSerializer {
const params = JSONbig.stringify(protocolParams || this.protocolParams);
- console.log("txBodyJson", txBodyJson);
+ if (this.verbose) {
+ console.log("txBodyJson", txBodyJson);
+ }
const txBuildResult = csl.js_serialize_tx_body(txBodyJson, params);
if (txBuildResult.get_status() !== "success") {
throw new Error(txBuildResult.get_data());
@@ -85,6 +92,10 @@ export class CSLSerializer implements IMeshTxSerializer {
return serialzeAddress(address, networkId);
}
+ serializePoolId(hash: string): string {
+ return serializePoolId(hash);
+ }
+
deserializer: IDeserializer = {
key: {
deserializeAddress: function (bech32: string): DeserializedAddress {
@@ -112,6 +123,11 @@ export class CSLSerializer implements IMeshTxSerializer {
return { scriptHash, scriptCbor: script.code };
},
},
+ cert: {
+ deserializePoolId: function (poolId: string): string {
+ return resolveEd25519KeyHash(poolId);
+ },
+ },
};
resolver: IResolver = {
@@ -147,10 +163,5 @@ export class CSLSerializer implements IMeshTxSerializer {
return resolveScriptRef(script);
},
},
- pool: {
- resolvePoolId: function (hash: string): string {
- return resolvePoolId(hash);
- },
- },
};
}
diff --git a/packages/mesh-core-csl/src/deser/resolver.ts b/packages/mesh-core-csl/src/deser/resolver.ts
index efc11b804..6b9a6ffa8 100644
--- a/packages/mesh-core-csl/src/deser/resolver.ts
+++ b/packages/mesh-core-csl/src/deser/resolver.ts
@@ -122,7 +122,7 @@ export const resolveNativeScriptHex = (script: NativeScript) => {
return toNativeScript(script).to_hex();
};
-export const resolvePoolId = (hash: string) => {
+export const serializePoolId = (hash: string) => {
return csl.Ed25519KeyHash.from_hex(hash).to_bech32("pool1");
};
diff --git a/packages/mesh-core-csl/test/core/builder.test.ts b/packages/mesh-core-csl/test/core/builder.test.ts
index 7c02467a4..ed1836ca9 100644
--- a/packages/mesh-core-csl/test/core/builder.test.ts
+++ b/packages/mesh-core-csl/test/core/builder.test.ts
@@ -3,8 +3,7 @@ import {
DEFAULT_PROTOCOL_PARAMETERS,
MeshTxBuilderBody,
} from "@meshsdk/common";
-
-import { CSLSerializer } from "../../src";
+import { CSLSerializer } from "@meshsdk/core-csl";
describe("Builder", () => {
test("serializeTxBody - send lovelace", () => {
diff --git a/packages/mesh-core-csl/test/utils/address.test.ts b/packages/mesh-core-csl/test/utils/address.test.ts
index fb02f4c5e..74c8f6dbe 100644
--- a/packages/mesh-core-csl/test/utils/address.test.ts
+++ b/packages/mesh-core-csl/test/utils/address.test.ts
@@ -1,10 +1,9 @@
import { pubKeyAddress, scriptAddress } from "@meshsdk/common";
-
import {
deserializeBech32Address,
scriptHashToBech32,
serializeAddressObj,
-} from "../../src";
+} from "@meshsdk/core-csl";
describe("Address", () => {
test("deserializeBech32Address", () => {
diff --git a/packages/mesh-core-csl/test/utils/aiken.test.ts b/packages/mesh-core-csl/test/utils/aiken.test.ts
index a77a39cfb..24e89920f 100644
--- a/packages/mesh-core-csl/test/utils/aiken.test.ts
+++ b/packages/mesh-core-csl/test/utils/aiken.test.ts
@@ -1,6 +1,8 @@
import { builtinByteString } from "@meshsdk/common";
-
-import { applyParamsToScript, deserializeBech32Address } from "../../src";
+import {
+ applyParamsToScript,
+ deserializeBech32Address,
+} from "@meshsdk/core-csl";
describe("Aiken", () => {
test("applyParamsToScript 1", () => {
diff --git a/packages/mesh-core-csl/test/utils/scripts.test.ts b/packages/mesh-core-csl/test/utils/scripts.test.ts
index fe26894a4..7204d5235 100644
--- a/packages/mesh-core-csl/test/utils/scripts.test.ts
+++ b/packages/mesh-core-csl/test/utils/scripts.test.ts
@@ -1,4 +1,4 @@
-import { applyParamsToScript, getV2ScriptHash } from "../../src";
+import { applyParamsToScript, getV2ScriptHash } from "@meshsdk/core-csl";
describe("Scripts", () => {
test("getV2ScriptHash", () => {
diff --git a/packages/mesh-core-csl/test/utils/transaction.test.ts b/packages/mesh-core-csl/test/utils/transaction.test.ts
index a377425db..f121b41b2 100644
--- a/packages/mesh-core-csl/test/utils/transaction.test.ts
+++ b/packages/mesh-core-csl/test/utils/transaction.test.ts
@@ -1,4 +1,4 @@
-import { calculateTxHash } from "../../src";
+import { calculateTxHash } from "@meshsdk/core-csl";
describe("Transaction", () => {
test("calculateTxHash", () => {
diff --git a/packages/mesh-core-cst/package.json b/packages/mesh-core-cst/package.json
index 3f816be16..ef2b784fd 100644
--- a/packages/mesh-core-cst/package.json
+++ b/packages/mesh-core-cst/package.json
@@ -1,6 +1,6 @@
{
"name": "@meshsdk/core-cst",
- "version": "1.6.1",
+ "version": "1.6.2",
"description": "",
"main": "./dist/index.cjs",
"module": "./dist/index.js",
@@ -20,7 +20,7 @@
"build:mesh": "tsup src/index.ts --format esm,cjs --dts --minify",
"dev": "tsup src/index.ts --format esm,cjs --watch --dts",
"lint": "eslint",
- "test": "jest --verbose",
+ "test": "jest",
"clean": "rm -rf .turbo && rm -rf dist && rm -rf node_modules",
"format": "prettier --check . --ignore-path ../../.gitignore"
},
diff --git a/packages/mesh-core-cst/src/resolvers/index.ts b/packages/mesh-core-cst/src/resolvers/index.ts
index 930970d10..a5fb4a05f 100644
--- a/packages/mesh-core-cst/src/resolvers/index.ts
+++ b/packages/mesh-core-cst/src/resolvers/index.ts
@@ -93,7 +93,6 @@ export const resolvePoolId = (hash: string) => {
};
export const resolvePrivateKey = (words: string[]) => {
- console.log(words);
return "not implemented";
};
diff --git a/packages/mesh-core-cst/src/serializer/index.ts b/packages/mesh-core-cst/src/serializer/index.ts
index 3c85deaaa..8536ee46d 100644
--- a/packages/mesh-core-cst/src/serializer/index.ts
+++ b/packages/mesh-core-cst/src/serializer/index.ts
@@ -96,6 +96,9 @@ export class CardanoSDKSerializer implements IMeshTxSerializer {
);
this.txWitnessSet = new TransactionWitnessSet();
}
+ serializePoolId(hash: string): string {
+ throw new Error("Method not implemented.");
+ }
serializeAddress(address: DeserializedAddress, networkId?: 0 | 1): string {
throw new Error("Method not implemented.");
@@ -130,6 +133,11 @@ export class CardanoSDKSerializer implements IMeshTxSerializer {
throw new Error("Function not implemented.");
},
},
+ cert: {
+ deserializePoolId: function (poolId: string): string {
+ throw new Error("Function not implemented.");
+ },
+ },
};
resolver: IResolver = {
@@ -192,11 +200,6 @@ export class CardanoSDKSerializer implements IMeshTxSerializer {
throw new Error("Function not implemented.");
},
},
- pool: {
- resolvePoolId: function (hash: string): string {
- throw new Error("Function not implemented.");
- },
- },
};
serializeTxBody = (
@@ -647,21 +650,27 @@ export class CardanoSDKSerializer implements IMeshTxSerializer {
case "V1":
this.scriptsProvided.add(
Script.newPlutusV1Script(
- PlutusV1Script.fromCbor(HexBlob(plutusScriptSource.script.code)),
+ PlutusV1Script.fromCbor(
+ HexBlob(plutusScriptSource.script.code),
+ ),
),
);
break;
case "V2":
this.scriptsProvided.add(
Script.newPlutusV2Script(
- PlutusV2Script.fromCbor(HexBlob(plutusScriptSource.script.code)),
+ PlutusV2Script.fromCbor(
+ HexBlob(plutusScriptSource.script.code),
+ ),
),
);
break;
case "V3":
this.scriptsProvided.add(
Script.newPlutusV3Script(
- PlutusV3Script.fromCbor(HexBlob(plutusScriptSource.script.code)),
+ PlutusV3Script.fromCbor(
+ HexBlob(plutusScriptSource.script.code),
+ ),
),
);
break;
diff --git a/packages/mesh-core-cst/src/stricahq/index.ts b/packages/mesh-core-cst/src/stricahq/index.ts
index b9910e05e..7d5a7cb7b 100644
--- a/packages/mesh-core-cst/src/stricahq/index.ts
+++ b/packages/mesh-core-cst/src/stricahq/index.ts
@@ -1,17 +1,4 @@
-import strica from "@stricahq/bip32ed25519"; // This works with broswer, but not node
-
-// import * as strica from "@stricahq/bip32ed25519"; // This works with node, but not browser
-
-// let strica: any;
-
-// if (typeof window !== "undefined") {
-// // Browser environment
-// strica = await import("@stricahq/bip32ed25519");
-// } else {
-// // Node.js environment
-// strica = require("@stricahq/bip32ed25519");
-// }
-
+import strica from "@stricahq/bip32ed25519";
import hash from "hash.js";
class PrivateKey extends strica.PrivateKey {
diff --git a/packages/mesh-core-cst/test/resolvers.test.ts b/packages/mesh-core-cst/test/resolvers.test.ts
index 94ab149b4..115aef108 100644
--- a/packages/mesh-core-cst/test/resolvers.test.ts
+++ b/packages/mesh-core-cst/test/resolvers.test.ts
@@ -3,7 +3,6 @@ import {
PlutusScript,
resolveFingerprint,
} from "@meshsdk/common";
-
import {
resolveDataHash,
resolveNativeScriptAddress,
@@ -11,10 +10,9 @@ import {
resolvePaymentKeyHash,
resolvePlutusScriptAddress,
resolvePlutusScriptHash,
- resolvePrivateKey,
resolveRewardAddress,
resolveStakeKeyHash,
-} from "../src";
+} from "@meshsdk/core-cst";
describe("resolveDataHash", () => {
it("should return correct data", () => {
diff --git a/packages/mesh-core-cst/test/utils/converter.test.ts b/packages/mesh-core-cst/test/utils/converter.test.ts
index bb57e248f..076e83f47 100644
--- a/packages/mesh-core-cst/test/utils/converter.test.ts
+++ b/packages/mesh-core-cst/test/utils/converter.test.ts
@@ -1,6 +1,5 @@
import { PlutusScript } from "@meshsdk/common";
-
-import { fromScriptRef } from "../../src/utils/converter";
+import { fromScriptRef } from "@meshsdk/core-cst";
describe("fromScriptRef", () => {
// it("with native script cbor should return correct NativeScript", () => {});
diff --git a/packages/mesh-core/package.json b/packages/mesh-core/package.json
index 2d4603e0b..e2618ec00 100644
--- a/packages/mesh-core/package.json
+++ b/packages/mesh-core/package.json
@@ -1,6 +1,6 @@
{
"name": "@meshsdk/core",
- "version": "1.6.1",
+ "version": "1.6.2",
"description": "",
"main": "./dist/index.cjs",
"module": "./dist/index.js",
diff --git a/packages/mesh-core/src/utils/deserializer.ts b/packages/mesh-core/src/utils/deserializer.ts
index 9c6e0e185..db4db004c 100644
--- a/packages/mesh-core/src/utils/deserializer.ts
+++ b/packages/mesh-core/src/utils/deserializer.ts
@@ -21,3 +21,11 @@ export const deserializeAddress = (bech32: string): DeserializedAddress =>
*/
export const deserializeDatum = (datumCbor: string): T =>
core.parseDatumCbor(datumCbor);
+
+/**
+ * Deserialize a script from a poolxxxx to Ed25519 key hash
+ * @param poolId The poolxxxx bech32 pool id
+ * @returns The Ed25519 key hash
+ */
+export const deserializePoolId = (poolId: string): string =>
+ core.resolveEd25519KeyHash(poolId);
diff --git a/packages/mesh-core/src/utils/resolver.ts b/packages/mesh-core/src/utils/resolver.ts
index 7434c787d..03b589b19 100644
--- a/packages/mesh-core/src/utils/resolver.ts
+++ b/packages/mesh-core/src/utils/resolver.ts
@@ -56,13 +56,6 @@ export const resolveScriptHash = (
return core.deserializePlutusScript(scriptCode, version).hash().to_hex();
};
-/**
- * Resolve the pool id from hash
- * @param hash The pool hash
- * @returns The pool id
- */
-export const resolvePoolId = (hash: string) => core.resolvePoolId(hash);
-
/**
* Resolve the Ed25519 key hash from bech32 address
* @param bech32 The bech32 address
@@ -71,6 +64,14 @@ export const resolvePoolId = (hash: string) => core.resolvePoolId(hash);
export const resolveRewardAddress = (bech32: string) =>
core.resolveRewardAddress(bech32);
+/**
+ * Resolve the stake key hash from bech32 address
+ * @param bech32 The bech32 address, either in addrxxx or stakexxx
+ * @returns The stake key hash
+ */
+export const resolveStakeKeyHash = (bech32: string) =>
+ core.resolveStakeKeyHash(bech32);
+
// ------------------- Deprecated zone ---------------------
/**
@@ -107,12 +108,6 @@ export const resolvePaymentKeyHash = (bech32: string) =>
export const resolvePlutusScriptHash = (bech32: string) =>
core.deserializeBech32Address(bech32).scriptHash;
-/**
- * Deprecated - use `deserializeAddress` instead
- */
-export const resolveStakeKeyHash = (bech32: string) =>
- core.deserializeBech32Address(bech32).stakeCredentialHash;
-
/**
* Deprecated - this is more used with the low level process inside Mesh
*
@@ -120,3 +115,8 @@ export const resolveStakeKeyHash = (bech32: string) =>
*/
export const resolveScriptRef = (script: NativeScript | PlutusScript) =>
core.resolveScriptRef(script);
+
+/**
+ * Deprecated - use `serializePoolId` instead
+ */
+export const resolvePoolId = (hash: string) => core.serializePoolId(hash);
diff --git a/packages/mesh-core/src/utils/serializer.ts b/packages/mesh-core/src/utils/serializer.ts
index 6dcd6da1d..7cc2ba061 100644
--- a/packages/mesh-core/src/utils/serializer.ts
+++ b/packages/mesh-core/src/utils/serializer.ts
@@ -68,3 +68,10 @@ export const serializePlutusScript = (
export const serializeAddressObj = (address: PubKeyAddress | ScriptAddress) => {
return core.serializeAddressObj(address);
};
+
+/**
+ * Resolve the pool id from hash
+ * @param hash The pool hash
+ * @returns The pool id
+ */
+export const serializePoolId = (hash: string) => core.serializePoolId(hash);
diff --git a/.env.example b/packages/mesh-provider/.env.example
similarity index 100%
rename from .env.example
rename to packages/mesh-provider/.env.example
diff --git a/packages/mesh-provider/package.json b/packages/mesh-provider/package.json
index e244c407f..4449ea876 100644
--- a/packages/mesh-provider/package.json
+++ b/packages/mesh-provider/package.json
@@ -1,6 +1,6 @@
{
"name": "@meshsdk/provider",
- "version": "1.6.1",
+ "version": "1.6.2",
"description": "",
"main": "./dist/index.cjs",
"module": "./dist/index.js",
@@ -21,7 +21,7 @@
"dev": "tsup src/index.ts --format esm,cjs --watch --dts",
"lint": "eslint",
"clean": "rm -rf .turbo && rm -rf dist && rm -rf node_modules",
- "test": "jest --verbose",
+ "test": "jest",
"format": "prettier --check . --ignore-path ../../.gitignore",
"build:docs": "typedoc src/index.ts --json ../../apps/docs/src/data/mesh-providers.json"
},
diff --git a/packages/mesh-provider/src/blockfrost.ts b/packages/mesh-provider/src/blockfrost.ts
index 2444f1430..8f8a3af90 100644
--- a/packages/mesh-provider/src/blockfrost.ts
+++ b/packages/mesh-provider/src/blockfrost.ts
@@ -99,7 +99,7 @@ export class BlockfrostProvider implements IFetcher, IListener, ISubmitter {
throw parseHttpError(data);
} catch (error) {
- console.log("error", error);
+ console.error("error", error);
throw parseHttpError(error);
}
}
@@ -196,7 +196,6 @@ export class BlockfrostProvider implements IFetcher, IListener, ISubmitter {
const { data, status } = await this._axiosInstance.get(
`assets/${policyId}${assetName}`,
);
- console.log(3, data)
if (status === 200 || status == 202)
return {
...data.onchain_metadata,
diff --git a/packages/mesh-provider/src/koios.ts b/packages/mesh-provider/src/koios.ts
index 1354c151c..1e3cb8470 100644
--- a/packages/mesh-provider/src/koios.ts
+++ b/packages/mesh-provider/src/koios.ts
@@ -325,8 +325,6 @@ export class KoiosProvider implements IFetcher, IListener, ISubmitter {
_tx_hashes: [hash],
});
- console.log(88, data);
-
if (status === 200) {
const utxos = data[0].outputs.map((utxo: KoiosUTxO) =>
this.toUTxO(utxo, "undefined"),
diff --git a/packages/mesh-provider/src/maestro.ts b/packages/mesh-provider/src/maestro.ts
index 995dcd24a..f1f4d1bde 100644
--- a/packages/mesh-provider/src/maestro.ts
+++ b/packages/mesh-provider/src/maestro.ts
@@ -200,8 +200,6 @@ export class MaestroProvider
const { data: timestampedData, status } = await this._axiosInstance.get(
`assets/${policyId}${assetName}`,
);
-
- console.log(2, timestampedData)
if (status === 200) {
const data = timestampedData.data;
return {
diff --git a/packages/mesh-provider/src/ogmios.ts b/packages/mesh-provider/src/ogmios.ts
index 9705255c1..502988bf8 100644
--- a/packages/mesh-provider/src/ogmios.ts
+++ b/packages/mesh-provider/src/ogmios.ts
@@ -32,8 +32,6 @@ export class OgmiosProvider implements IEvaluator, ISubmitter {
(response: MessageEvent) => {
try {
const { result } = JSON.parse(response.data);
- console.log(1, 'result', result)
-
if (result.EvaluationResult) {
resolve(
Object.keys(result.EvaluationResult).map((key) => {
diff --git a/packages/mesh-provider/src/yaci.ts b/packages/mesh-provider/src/yaci.ts
index 8f6f581ad..4cfd8e4d8 100644
--- a/packages/mesh-provider/src/yaci.ts
+++ b/packages/mesh-provider/src/yaci.ts
@@ -380,7 +380,7 @@ export class YaciProvider implements IFetcher, IListener, ISubmitter {
throw parseHttpError(data);
} catch (error) {
- console.log("error", error);
+ console.error("error", error);
throw parseHttpError(error);
}
}
@@ -402,7 +402,7 @@ export class YaciProvider implements IFetcher, IListener, ISubmitter {
throw parseHttpError(data);
} catch (error) {
- console.log("error", error);
+ console.error("error", error);
throw parseHttpError(error);
}
}
diff --git a/packages/mesh-provider/test/blockfrost/evaluator.test.ts b/packages/mesh-provider/test/blockfrost/evaluator.test.ts
index 2a9f68931..3322eb8f2 100644
--- a/packages/mesh-provider/test/blockfrost/evaluator.test.ts
+++ b/packages/mesh-provider/test/blockfrost/evaluator.test.ts
@@ -1,6 +1,6 @@
import dotenv from "dotenv";
-import { BlockfrostProvider } from "../../src";
+import { BlockfrostProvider } from "@meshsdk/provider";
dotenv.config();
const apiKey = process.env.BLOCKFROST_API_KEY_PREPROD!;
diff --git a/packages/mesh-provider/test/maestro/evaluator.test.ts b/packages/mesh-provider/test/maestro/evaluator.test.ts
index d3cba2a17..7a92933ae 100644
--- a/packages/mesh-provider/test/maestro/evaluator.test.ts
+++ b/packages/mesh-provider/test/maestro/evaluator.test.ts
@@ -1,6 +1,6 @@
import dotenv from "dotenv";
-import { MaestroProvider } from "../../src/maestro";
+import { MaestroProvider } from "@meshsdk/provider";
dotenv.config();
const apiKey = process.env.MAESTRO_API_KEY!;
diff --git a/packages/mesh-react/package.json b/packages/mesh-react/package.json
index ae04c77de..ef7fb7485 100644
--- a/packages/mesh-react/package.json
+++ b/packages/mesh-react/package.json
@@ -1,6 +1,6 @@
{
"name": "@meshsdk/react",
- "version": "1.6.1",
+ "version": "1.6.2",
"description": "",
"main": "./dist/index.cjs",
"module": "./dist/index.js",
diff --git a/packages/mesh-react/src/cardano-wallet/index.tsx b/packages/mesh-react/src/cardano-wallet/index.tsx
index 0e925ce99..b69c3d8fb 100644
--- a/packages/mesh-react/src/cardano-wallet/index.tsx
+++ b/packages/mesh-react/src/cardano-wallet/index.tsx
@@ -1,10 +1,7 @@
import { useEffect, useState } from "react";
-import { Wallet } from "@meshsdk/common";
-import { BrowserWallet } from "@meshsdk/wallet";
-
import Button from "../common/button";
-import { useWallet } from "../hooks";
+import { useWallet, useWalletList } from "../hooks";
import { MenuItem } from "./menu-item";
import { WalletBalance } from "./wallet-balance";
@@ -12,18 +9,20 @@ interface ButtonProps {
label?: string;
onConnected?: Function;
isDark?: boolean;
+ nufiNetwork?: string;
}
export const CardanoWallet = ({
label = "Connect Wallet",
onConnected = undefined,
isDark = false,
+ nufiNetwork = "preprod",
}: ButtonProps) => {
const [isDarkMode, setIsDarkMode] = useState(false);
const [hideMenuList, setHideMenuList] = useState(true);
- const [wallets, setWallets] = useState([]);
const { connect, connecting, connected, disconnect, name } = useWallet();
+ const wallets = useWalletList({ nufiNetwork });
useEffect(() => {
if (connected && onConnected) {
@@ -31,19 +30,15 @@ export const CardanoWallet = ({
}
}, [connected]);
- useEffect(() => {
- setWallets(BrowserWallet.getInstalledWallets());
- }, []);
-
useEffect(() => {
setIsDarkMode(isDark);
}, [isDark]);
return (
setHideMenuList(false)}
onMouseLeave={() => setHideMenuList(true)}
+ style={{ width: "min-content", zIndex: 50 }}
>
wallet.name === name)}
+ wallet={wallets.find((wallet) => wallet.id === name)}
/>
{
- connect(wallet.name);
+ connect(wallet.id);
setHideMenuList(!hideMenuList);
}}
- active={name === wallet.name}
+ active={name === wallet.id}
/>
))}
{/*
void;
+ onMouseEnter?: () => void;
+ onMouseLeave?: () => void;
}) {
return (
setHideMenuList && setHideMenuList(!hideMenuList)}
+ onMouseEnter={onMouseEnter}
+ onMouseLeave={onMouseLeave}
>
{children}
diff --git a/packages/mesh-react/src/hooks/useWalletList.ts b/packages/mesh-react/src/hooks/useWalletList.ts
index 480f01e89..246707bd6 100644
--- a/packages/mesh-react/src/hooks/useWalletList.ts
+++ b/packages/mesh-react/src/hooks/useWalletList.ts
@@ -3,11 +3,18 @@ import { useEffect, useState } from "react";
import type { Wallet } from "@meshsdk/common";
import { BrowserWallet } from "@meshsdk/wallet";
-export const useWalletList = () => {
+export const useWalletList = ({
+ nufiNetwork = "preprod",
+}: {
+ nufiNetwork?: string;
+} = {}) => {
const [wallets, setWallets] = useState([]);
useEffect(() => {
- setWallets(BrowserWallet.getInstalledWallets());
+ async function get() {
+ setWallets(await BrowserWallet.getAvailableWallets({ nufiNetwork }));
+ }
+ get();
}, []);
return wallets;
diff --git a/packages/mesh-transaction/package.json b/packages/mesh-transaction/package.json
index a3fe0f6a6..55201c079 100644
--- a/packages/mesh-transaction/package.json
+++ b/packages/mesh-transaction/package.json
@@ -1,6 +1,6 @@
{
"name": "@meshsdk/transaction",
- "version": "1.6.1",
+ "version": "1.6.2",
"description": "",
"main": "./dist/index.cjs",
"module": "./dist/index.js",
diff --git a/packages/mesh-transaction/src/mesh-tx-builder/index.ts b/packages/mesh-transaction/src/mesh-tx-builder/index.ts
index 547e774f5..42d17e3a9 100644
--- a/packages/mesh-transaction/src/mesh-tx-builder/index.ts
+++ b/packages/mesh-transaction/src/mesh-tx-builder/index.ts
@@ -105,7 +105,6 @@ export class MeshTxBuilder extends MeshTxBuilderCore {
this._protocolParams,
);
}
- console.log(txHex);
this.txHex = txHex;
return txHex;
diff --git a/packages/mesh-transaction/src/transaction/index.ts b/packages/mesh-transaction/src/transaction/index.ts
index 0113311c5..29c2d8729 100644
--- a/packages/mesh-transaction/src/transaction/index.ts
+++ b/packages/mesh-transaction/src/transaction/index.ts
@@ -1,32 +1,34 @@
import {
Action,
Asset,
+ AssetMetadata,
Budget,
CIP68_100,
CIP68_222,
- DEFAULT_REDEEMER_BUDGET,
Data,
+ DEFAULT_REDEEMER_BUDGET,
+ hexToString,
IInitiator,
+ metadataToCip68,
Mint,
NativeScript,
- POLICY_ID_LENGTH,
PlutusScript,
+ POLICY_ID_LENGTH,
PoolParams,
Recipient,
+ stringToHex,
SUPPORTED_TOKENS,
Token,
UTxO,
- hexToString,
- metadataToCip68,
- stringToHex,
} from "@meshsdk/common";
-import { MeshTxBuilder, MeshTxBuilderOptions } from "../mesh-tx-builder";
import {
deserializeNativeScript,
deserializePlutusScript,
fromScriptRef,
} from "@meshsdk/core-cst";
+import { MeshTxBuilder, MeshTxBuilderOptions } from "../mesh-tx-builder";
+
export interface TransactionOptions extends MeshTxBuilderOptions {
initiator: IInitiator;
}
@@ -145,7 +147,7 @@ export class Transaction {
input.input.txHash,
input.input.outputIndex,
input.output.amount,
- input.output.address
+ input.output.address,
);
});
@@ -162,7 +164,7 @@ export class Transaction {
inputs.forEach((input) => {
this.txBuilder.readOnlyTxInReference(
input.input.txHash,
- input.input.outputIndex
+ input.input.outputIndex,
);
});
@@ -178,14 +180,14 @@ export class Transaction {
setNativeScriptInput(script: NativeScript, utxo: UTxO): Transaction {
const { scriptCbor } =
this.txBuilder.serializer.deserializer.script.deserializeNativeScript(
- script
+ script,
);
this.txBuilder
.txIn(
utxo.input.txHash,
utxo.input.outputIndex,
utxo.output.amount,
- utxo.output.address
+ utxo.output.address,
)
.txInScript(scriptCbor!);
@@ -213,7 +215,7 @@ export class Transaction {
value.input.txHash,
value.input.outputIndex,
value.output.amount,
- value.output.address
+ value.output.address,
)
.txInScript(script.code)
.txInRedeemerValue(red.data, "Mesh", red.budget);
@@ -235,12 +237,12 @@ export class Transaction {
value.input.txHash,
value.input.outputIndex,
value.output.amount,
- value.output.address
+ value.output.address,
)
.spendingTxInReference(
script.input.txHash,
script.input.outputIndex,
- script.output.scriptHash
+ script.output.scriptHash,
)
.txInRedeemerValue(red.data, "Mesh", red.budget);
}
@@ -267,7 +269,7 @@ export class Transaction {
mintAsset(
forgeScript: string | PlutusScript | UTxO,
mint: Mint,
- redeemer?: Pick & { budget?: Budget }
+ redeemer?: Pick & { budget?: Budget },
): Transaction {
const assetQuantity = mint.assetQuantity;
let assetNameHex = stringToHex(mint.assetName);
@@ -293,13 +295,13 @@ export class Transaction {
case "object":
if (!redeemer)
throw new Error(
- "burnAsset: Redeemer data is required for Plutus minting"
+ "burnAsset: Redeemer data is required for Plutus minting",
);
if ("code" in forgeScript) {
// Burn plutus script assets with provided script
policyId = deserializePlutusScript(
forgeScript.code,
- forgeScript.version
+ forgeScript.version,
)
.hash()
.toString();
@@ -337,7 +339,7 @@ export class Transaction {
.mint(assetQuantity, policyId, assetNameHex)
.mintTxInReference(
forgeScript.input.txHash,
- forgeScript.input.outputIndex
+ forgeScript.input.outputIndex,
)
.mintRedeemerValue(redeemer.data, "Mesh", redeemer.budget);
if (mint.cip68ScriptAddress) {
@@ -345,7 +347,7 @@ export class Transaction {
.mint(assetQuantity, policyId, referenceAssetNameHex)
.mintTxInReference(
forgeScript.input.txHash,
- forgeScript.input.outputIndex
+ forgeScript.input.outputIndex,
)
.mintRedeemerValue(redeemer.data, "Mesh", redeemer.budget);
break;
@@ -355,7 +357,7 @@ export class Transaction {
} else {
// TODO: to implement reference script minting for native script tokens
throw new Error(
- "mintAsset: Reference script minting not implemented"
+ "mintAsset: Reference script minting not implemented",
);
// this.txBuilder
// .mint(assetQuantity, policyId, assetName)
@@ -368,14 +370,6 @@ export class Transaction {
break;
}
- if (mint.metadata && mint.label) {
- this.setMetadata(Number(mint.label), {
- [policyId]: {
- [mint.assetName]: mint.metadata,
- },
- version: 1,
- });
- }
if (mint.recipient) {
this.sendAssets(mint.recipient, [
{ unit: policyId + assetNameHex, quantity: mint.assetQuantity },
@@ -392,9 +386,17 @@ export class Transaction {
unit: policyId + referenceAssetNameHex,
quantity: mint.assetQuantity,
},
- ]
+ ],
);
}
+ if (!mint.cip68ScriptAddress && mint.metadata && mint.label) {
+ if (mint.label === "721" || mint.label === "20") {
+ this.setMetadata(Number(mint.label), {
+ [policyId]: { [mint.assetName]: mint.metadata },
+ });
+ }
+ this.setMetadata(Number(mint.label), mint.metadata);
+ }
return this;
}
@@ -404,7 +406,7 @@ export class Transaction {
burnAsset(
forgeScript: string | PlutusScript | UTxO,
asset: Asset,
- redeemer?: Pick & { budget?: Budget }
+ redeemer?: Pick & { budget?: Budget },
): Transaction {
const assetQuantity = "-" + asset.quantity;
const mint: Mint = {
@@ -443,7 +445,7 @@ export class Transaction {
collateralUtxo.input.txHash,
collateralUtxo.input.outputIndex,
collateralUtxo.output.amount,
- collateralUtxo.output.address
+ collateralUtxo.output.address,
);
});
@@ -511,23 +513,27 @@ export class Transaction {
delegateStake(rewardAddress: string, poolId: string): Transaction {
this.txBuilder.delegateStakeCertificate(
this.txBuilder.serializer.resolver.keys.resolveStakeKeyHash(
- rewardAddress
+ rewardAddress,
),
- this.txBuilder.serializer.resolver.keys.resolveEd25519KeyHash(poolId)
+ this.txBuilder.serializer.resolver.keys.resolveEd25519KeyHash(poolId),
);
return this;
}
deregisterStake(rewardAddress: string): Transaction {
this.txBuilder.deregisterStakeCertificate(
- this.txBuilder.serializer.resolver.keys.resolveStakeKeyHash(rewardAddress)
+ this.txBuilder.serializer.resolver.keys.resolveStakeKeyHash(
+ rewardAddress,
+ ),
);
return this;
}
registerStake(rewardAddress: string): Transaction {
this.txBuilder.registerStakeCertificate(
- this.txBuilder.serializer.resolver.keys.resolveStakeKeyHash(rewardAddress)
+ this.txBuilder.serializer.resolver.keys.resolveStakeKeyHash(
+ rewardAddress,
+ ),
);
return this;
}
@@ -553,7 +559,7 @@ export class Transaction {
return this.txBuilder.complete();
} catch (error) {
throw new Error(
- `[Transaction] An error occurred during build: ${error}.`
+ `[Transaction] An error occurred during build: ${error}.`,
);
}
}
diff --git a/packages/mesh-wallet/package.json b/packages/mesh-wallet/package.json
index d2a45f08b..3c0403b86 100644
--- a/packages/mesh-wallet/package.json
+++ b/packages/mesh-wallet/package.json
@@ -1,6 +1,6 @@
{
"name": "@meshsdk/wallet",
- "version": "1.6.1",
+ "version": "1.6.2",
"description": "",
"main": "./dist/index.cjs",
"module": "./dist/index.js",
@@ -21,7 +21,7 @@
"dev": "tsup src/index.ts --format esm,cjs --watch --dts",
"lint": "eslint",
"clean": "rm -rf .turbo && rm -rf dist && rm -rf node_modules",
- "test": "jest --verbose",
+ "test": "jest",
"format": "prettier --check . --ignore-path ../../.gitignore",
"build:docs": "typedoc src/index.ts --json ../../apps/docs/src/data/mesh-wallets.json"
},
@@ -29,13 +29,15 @@
"@meshsdk/typescript-config": "*",
"eslint": "^8.57.0",
"tsup": "^8.0.2",
- "typescript": "^5.3.3",
- "typedoc": "^0.26.3"
+ "typedoc": "^0.26.3",
+ "typescript": "^5.3.3"
},
"dependencies": {
"@meshsdk/common": "*",
"@meshsdk/core-cst": "*",
- "@meshsdk/transaction": "*"
+ "@meshsdk/transaction": "*",
+ "@nufi/dapp-client-cardano": "^0.3.1",
+ "@nufi/dapp-client-core": "^0.3.1"
},
"prettier": "@meshsdk/prettier-config",
"publishConfig": {
@@ -49,4 +51,4 @@
"blockchain",
"sdk"
]
-}
\ No newline at end of file
+}
diff --git a/packages/mesh-wallet/src/browser/index.ts b/packages/mesh-wallet/src/browser/index.ts
index 95341f582..a0fc9f106 100644
--- a/packages/mesh-wallet/src/browser/index.ts
+++ b/packages/mesh-wallet/src/browser/index.ts
@@ -30,6 +30,7 @@ import {
} from "@meshsdk/core-cst";
import { Cardano, WalletInstance } from "../types";
+import { checkIfMetamaskInstalled } from "./metamask";
declare global {
interface Window {
@@ -69,7 +70,7 @@ export class BrowserWallet implements IInitiator, ISigner, ISubmitter {
if (_wallet.apiVersion === undefined) continue;
wallets.push({
id: key,
- name: _wallet.name,
+ name: key == "nufiSnap" ? "MetaMask" : _wallet.name,
icon: _wallet.icon,
version: _wallet.apiVersion,
});
@@ -79,6 +80,25 @@ export class BrowserWallet implements IInitiator, ISigner, ISubmitter {
return wallets;
}
+ /**
+ * Returns a list of wallets installed on user's device. Each wallet is an object with the following properties:
+ * - A name is provided to display wallet's name on the user interface.
+ * - A version is provided to display wallet's version on the user interface.
+ * - An icon is provided to display wallet's icon on the user interface.
+ *
+ * @returns a list of wallet names
+ */
+ static async getAvailableWallets({
+ nufiNetwork = "preprod",
+ }: {
+ nufiNetwork?: string;
+ } = {}): Promise {
+ if (window === undefined) return [];
+ await checkIfMetamaskInstalled(nufiNetwork);
+ const wallets = BrowserWallet.getInstalledWallets();
+ return wallets;
+ }
+
/**
* This is the entrypoint to start communication with the user's wallet. The wallet should request the user's permission to connect the web page to the user's wallet, and if permission has been granted, the wallet will be returned and exposing the full API for the dApp to use.
*
@@ -237,7 +257,6 @@ export class BrowserWallet implements IInitiator, ISigner, ISubmitter {
*/
async signTx(unsignedTx: string, partialSign = false): Promise {
const witness = await this._walletInstance.signTx(unsignedTx, partialSign);
- console.log("witness", witness);
return BrowserWallet.addBrowserWitnesses(unsignedTx, witness);
}
diff --git a/packages/mesh-wallet/src/browser/metamask.ts b/packages/mesh-wallet/src/browser/metamask.ts
new file mode 100644
index 000000000..58af1f568
--- /dev/null
+++ b/packages/mesh-wallet/src/browser/metamask.ts
@@ -0,0 +1,46 @@
+import { initNufiDappCardanoSdk } from "@nufi/dapp-client-cardano";
+import nufiCoreSdk from "@nufi/dapp-client-core";
+
+import { Wallet } from "@meshsdk/common";
+
+const nufiDomain: { [key: string]: string } = {
+ production: "https://wallet.nu.fi",
+ mainnet: "https://wallet-staging.nu.fi",
+ preprod: "https://wallet-testnet-staging.nu.fi",
+ preview: "https://wallet-preview-staging.nu.fi",
+};
+
+export function checkIfMetamaskInstalled(
+ network = "preprod",
+): Promise {
+ try {
+ const _nufiCoreSdk = (nufiCoreSdk as any).default;
+
+ if (Object.keys(nufiDomain).includes(network)) {
+ _nufiCoreSdk.init(nufiDomain[network]);
+ } else {
+ _nufiCoreSdk.init(network);
+ }
+
+ return new Promise((resolve) => {
+ _nufiCoreSdk
+ .getApi()
+ .isMetamaskInstalled()
+ .then((isMetamaskInstalled: boolean) => {
+ if (isMetamaskInstalled) {
+ initNufiDappCardanoSdk(_nufiCoreSdk, "snap");
+ resolve({
+ id: "nufiSnap",
+ name: "MetaMask",
+ icon: "data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPHN2ZyBpZD0iTGF5ZXJfMiIgZGF0YS1uYW1lPSJMYXllciAyIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAxNjkuMiAxNjMuNzEiPgogIDxkZWZzPgogICAgPHN0eWxlPgogICAgICAuY2xzLTEgewogICAgICAgIGZpbGw6ICNlMjc2MjU7CiAgICAgIH0KCiAgICAgIC5jbHMtMSwgLmNscy0yLCAuY2xzLTMsIC5jbHMtNCwgLmNscy01LCAuY2xzLTYsIC5jbHMtNywgLmNscy04LCAuY2xzLTkgewogICAgICAgIHN0cm9rZS13aWR0aDogMHB4OwogICAgICB9CgogICAgICAuY2xzLTIgewogICAgICAgIGZpbGw6ICM3NjNlMWE7CiAgICAgIH0KCiAgICAgIC5jbHMtMyB7CiAgICAgICAgZmlsbDogI2MwYWQ5ZTsKICAgICAgfQoKICAgICAgLmNscy00IHsKICAgICAgICBmaWxsOiAjMzQ2OGQxOwogICAgICB9CgogICAgICAuY2xzLTUgewogICAgICAgIGZpbGw6ICNjYzYyMjg7CiAgICAgIH0KCiAgICAgIC5jbHMtNiB7CiAgICAgICAgZmlsbDogI2Y1ODQxZjsKICAgICAgfQoKICAgICAgLmNscy03IHsKICAgICAgICBmaWxsOiAjZDdjMWIzOwogICAgICB9CgogICAgICAuY2xzLTggewogICAgICAgIGZpbGw6ICNmZmY7CiAgICAgICAgZmlsbC1ydWxlOiBldmVub2RkOwogICAgICB9CgogICAgICAuY2xzLTkgewogICAgICAgIGZpbGw6ICMyZjM0M2I7CiAgICAgIH0KICAgIDwvc3R5bGU+CiAgPC9kZWZzPgogIDxnIGlkPSJMYXllcl8xLTIiIGRhdGEtbmFtZT0iTGF5ZXIgMSI+CiAgICA8ZyBpZD0iTU1fSGVhZF9iYWNrZ3JvdW5kX0RvX25vdF9lZGl0XyIgZGF0YS1uYW1lPSJNTSBIZWFkIGJhY2tncm91bmQgKERvIG5vdCBlZGl0KSI+CiAgICAgIDxwYXRoIGNsYXNzPSJjbHMtNiIgZD0iTTE0MS44LDcwLjVsNi45LTguMS0zLTIuMiw0LjgtNC40LTMuNy0yLjgsNC44LTMuNi0zLjEtMi40LDUtMjQuNC03LjYtMjIuNk0xNDUuOSwwbC00OC44LDE4LjFoLTQwLjdMNy42LDBsLjMuMkw3LjYsMCwwLDIyLjZsNS4xLDI0LjQtMy4yLDIuNCw0LjksMy42LTMuNywyLjgsNC44LDQuNC0zLDIuMiw2LjksOC4xTDEuMywxMDIuOWgwbDkuNywzMy4xLDM0LjEtOS40di0uMS4xaDBsNi42LDUuNCwxMy41LDkuMmgyMy4xbDEzLjUtOS4yLDYuNi01LjRoMGwzNC4yLDkuNCw5LjgtMzMuMWgwbC0xMC42LTMyLjQiLz4KICAgIDwvZz4KICAgIDxnIGlkPSJMb2dvcyI+CiAgICAgIDxnPgogICAgICAgIDxwb2x5Z29uIGNsYXNzPSJjbHMtMSIgcG9pbnRzPSIxNDUuOSAwIDg2IDQ0LjEgOTcuMSAxOC4xIDE0NS45IDAiLz4KICAgICAgICA8cG9seWdvbiBjbGFzcz0iY2xzLTEiIHBvaW50cz0iNy42IDAgNjcgNDQuNSA1Ni40IDE4LjEgNy42IDAiLz4KICAgICAgICA8cG9seWdvbiBjbGFzcz0iY2xzLTEiIHBvaW50cz0iMTI0LjQgMTAyLjMgMTA4LjQgMTI2LjUgMTQyLjYgMTM1LjkgMTUyLjQgMTAyLjggMTI0LjQgMTAyLjMiLz4KICAgICAgICA8cG9seWdvbiBjbGFzcz0iY2xzLTEiIHBvaW50cz0iMS4zIDEwMi44IDExIDEzNS45IDQ1LjEgMTI2LjUgMjkuMiAxMDIuMyAxLjMgMTAyLjgiLz4KICAgICAgICA8cG9seWdvbiBjbGFzcz0iY2xzLTEiIHBvaW50cz0iNDMuMyA2MS4zIDMzLjggNzUuNiA2Ny42IDc3LjEgNjYuNSA0MC45IDQzLjMgNjEuMyIvPgogICAgICAgIDxwb2x5Z29uIGNsYXNzPSJjbHMtMSIgcG9pbnRzPSIxMTAuMyA2MS4zIDg2LjcgNDAuNSA4NiA3Ny4xIDExOS44IDc1LjYgMTEwLjMgNjEuMyIvPgogICAgICAgIDxwb2x5Z29uIGNsYXNzPSJjbHMtMSIgcG9pbnRzPSI0NS4xIDEyNi41IDY1LjYgMTE2LjcgNDcuOSAxMDMuMSA0NS4xIDEyNi41Ii8+CiAgICAgICAgPHBvbHlnb24gY2xhc3M9ImNscy0xIiBwb2ludHM9Ijg4IDExNi43IDEwOC40IDEyNi41IDEwNS42IDEwMy4xIDg4IDExNi43Ii8+CiAgICAgICAgPHBvbHlnb24gY2xhc3M9ImNscy03IiBwb2ludHM9IjEwOC40IDEyNi41IDg4IDExNi43IDg5LjcgMTI5LjkgODkuNSAxMzUuNSAxMDguNCAxMjYuNSIvPgogICAgICAgIDxwb2x5Z29uIGNsYXNzPSJjbHMtNyIgcG9pbnRzPSI0NS4xIDEyNi41IDY0LjEgMTM1LjUgNjQgMTI5LjkgNjUuNiAxMTYuNyA0NS4xIDEyNi41Ii8+CiAgICAgICAgPHBvbHlnb24gY2xhc3M9ImNscy05IiBwb2ludHM9IjY0LjQgOTQuMyA0Ny41IDg5LjQgNTkuNSA4My45IDY0LjQgOTQuMyIvPgogICAgICAgIDxwb2x5Z29uIGNsYXNzPSJjbHMtOSIgcG9pbnRzPSI4OS4xIDk0LjMgOTQuMSA4My45IDEwNi4xIDg5LjQgODkuMSA5NC4zIi8+CiAgICAgICAgPHBvbHlnb24gY2xhc3M9ImNscy01IiBwb2ludHM9IjQ1LjEgMTI2LjUgNDguMSAxMDIuMyAyOS4yIDEwMi44IDQ1LjEgMTI2LjUiLz4KICAgICAgICA8cG9seWdvbiBjbGFzcz0iY2xzLTUiIHBvaW50cz0iMTA1LjUgMTAyLjMgMTA4LjQgMTI2LjUgMTI0LjQgMTAyLjggMTA1LjUgMTAyLjMiLz4KICAgICAgICA8cG9seWdvbiBjbGFzcz0iY2xzLTUiIHBvaW50cz0iMTE5LjggNzUuNiA4NiA3Ny4xIDg5LjEgOTQuMyA5NC4xIDgzLjkgMTA2LjEgODkuNCAxMTkuOCA3NS42Ii8+CiAgICAgICAgPHBvbHlnb24gY2xhc3M9ImNscy01IiBwb2ludHM9IjQ3LjUgODkuNCA1OS41IDgzLjkgNjQuNCA5NC4zIDY3LjYgNzcuMSAzMy44IDc1LjYgNDcuNSA4OS40Ii8+CiAgICAgICAgPHBvbHlnb24gY2xhc3M9ImNscy0xIiBwb2ludHM9IjMzLjggNzUuNiA0Ny45IDEwMy4xIDQ3LjUgODkuNCAzMy44IDc1LjYiLz4KICAgICAgICA8cG9seWdvbiBjbGFzcz0iY2xzLTEiIHBvaW50cz0iMTA2LjEgODkuNCAxMDUuNiAxMDMuMSAxMTkuOCA3NS42IDEwNi4xIDg5LjQiLz4KICAgICAgICA8cG9seWdvbiBjbGFzcz0iY2xzLTEiIHBvaW50cz0iNjcuNiA3Ny4xIDY0LjQgOTQuMyA2OC40IDExNC43IDY5LjMgODcuOSA2Ny42IDc3LjEiLz4KICAgICAgICA8cG9seWdvbiBjbGFzcz0iY2xzLTEiIHBvaW50cz0iODYgNzcuMSA4NC4zIDg3LjggODUuMSAxMTQuNyA4OS4xIDk0LjMgODYgNzcuMSIvPgogICAgICAgIDxwb2x5Z29uIGNsYXNzPSJjbHMtNiIgcG9pbnRzPSI4OS4xIDk0LjMgODUuMSAxMTQuNyA4OCAxMTYuNyAxMDUuNiAxMDMuMSAxMDYuMSA4OS40IDg5LjEgOTQuMyIvPgogICAgICAgIDxwb2x5Z29uIGNsYXNzPSJjbHMtNiIgcG9pbnRzPSI0Ny41IDg5LjQgNDcuOSAxMDMuMSA2NS42IDExNi43IDY4LjQgMTE0LjcgNjQuNCA5NC4zIDQ3LjUgODkuNCIvPgogICAgICAgIDxwb2x5Z29uIGNsYXNzPSJjbHMtMyIgcG9pbnRzPSI4OS41IDEzNS41IDg5LjcgMTI5LjkgODguMSAxMjguNiA2NS40IDEyOC42IDY0IDEyOS45IDY0LjEgMTM1LjUgNDUuMSAxMjYuNSA1MS43IDEzMS45IDY1LjIgMTQxLjIgODguMyAxNDEuMiAxMDEuOCAxMzEuOSAxMDguNCAxMjYuNSA4OS41IDEzNS41Ii8+CiAgICAgICAgPHBvbHlnb24gY2xhc3M9ImNscy05IiBwb2ludHM9Ijg4IDExNi43IDg1LjEgMTE0LjcgNjguNCAxMTQuNyA2NS42IDExNi43IDY0IDEyOS45IDY1LjQgMTI4LjYgODguMSAxMjguNiA4OS43IDEyOS45IDg4IDExNi43Ii8+CiAgICAgICAgPHBvbHlnb24gY2xhc3M9ImNscy0yIiBwb2ludHM9IjE0OC41IDQ3IDE1My41IDIyLjYgMTQ1LjkgMCA4OCA0Mi42IDExMC4zIDYxLjMgMTQxLjggNzAuNSAxNDguNyA2Mi40IDE0NS43IDYwLjIgMTUwLjUgNTUuOSAxNDYuOCA1MyAxNTEuNiA0OS40IDE0OC41IDQ3Ii8+CiAgICAgICAgPHBvbHlnb24gY2xhc3M9ImNscy0yIiBwb2ludHM9IjAgMjIuNiA1LjEgNDcgMS45IDQ5LjQgNi43IDUzLjEgMyA1NS45IDcuOCA2MC4yIDQuOCA2Mi40IDExLjggNzAuNSA0My4zIDYxLjMgNjUuNiA0Mi42IDcuNiAwIDAgMjIuNiIvPgogICAgICAgIDxwb2x5Z29uIGNsYXNzPSJjbHMtNiIgcG9pbnRzPSIxNDEuOCA3MC41IDExMC4zIDYxLjMgMTE5LjggNzUuNiAxMDUuNiAxMDMuMSAxMjQuNCAxMDIuOCAxNTIuNCAxMDIuOCAxNDEuOCA3MC41Ii8+CiAgICAgICAgPHBvbHlnb24gY2xhc3M9ImNscy02IiBwb2ludHM9IjQzLjMgNjEuMyAxMS44IDcwLjUgMS4zIDEwMi44IDI5LjIgMTAyLjggNDcuOSAxMDMuMSAzMy44IDc1LjYgNDMuMyA2MS4zIi8+CiAgICAgICAgPHBvbHlnb24gY2xhc3M9ImNscy02IiBwb2ludHM9Ijg2IDc3LjEgODggNDIuNiA5Ny4xIDE4LjEgNTYuNCAxOC4xIDY1LjYgNDIuNiA2Ny42IDc3LjEgNjguNCA4Ny45IDY4LjQgMTE0LjcgODUuMSAxMTQuNyA4NS4yIDg3LjkgODYgNzcuMSIvPgogICAgICA8L2c+CiAgICA8L2c+CiAgICA8ZyBpZD0iY2FyZGFub19hZGEiIGRhdGEtbmFtZT0iY2FyZGFubyBhZGEiPgogICAgICA8ZyBpZD0iY2FyZGFub19hZGEtMiIgZGF0YS1uYW1lPSJjYXJkYW5vIGFkYS0yIj4KICAgICAgICA8Y2lyY2xlIGlkPSJf0K3Qu9C70LjQv9GBXzYiIGRhdGEtbmFtZT0i0K3Qu9C70LjQv9GBIDYiIGNsYXNzPSJjbHMtNCIgY3g9IjEyOC4wNSIgY3k9IjEyMi41NiIgcj0iNDEuMTUiLz4KICAgICAgICA8cGF0aCBpZD0iX9Ct0LvQu9C40L/RgV82X9C60L7Qv9C40Y9fMjkiIGRhdGEtbmFtZT0i0K3Qu9C70LjQv9GBIDYg0LrQvtC/0LjRjyAyOSIgY2xhc3M9ImNscy04IiBkPSJNMTIzLjQ2LDEwOS45M2MyLjI1LDAsNC4wNywxLjgyLDQuMDcsNC4wNywwLDIuMjUtMS44Miw0LjA3LTQuMDcsNC4wNy0yLjI1LDAtNC4wNy0xLjgyLTQuMDctNC4wNywwLTIuMjUsMS44Mi00LjA3LDQuMDctNC4wN1pNMTMzLjI4LDEwOS45M2MyLjI1LDAsNC4wNywxLjgyLDQuMDcsNC4wNywwLDIuMjUtMS44Miw0LjA3LTQuMDcsNC4wNy0yLjI1LDAtNC4wNy0xLjgyLTQuMDctNC4wNywwLTIuMjUsMS44Mi00LjA3LDQuMDctNC4wN2gwWk0xMzMuMjgsMTI3LjA1YzIuMjUsMCw0LjA3LDEuODIsNC4wNyw0LjA3LDAsMi4yNS0xLjgyLDQuMDctNC4wNyw0LjA3LTIuMjUsMC00LjA3LTEuODItNC4wNy00LjA3LDAtMi4yNSwxLjgyLTQuMDcsNC4wNy00LjA3aDAsMFpNMTIzLjQ2LDEyNy4wNWMyLjI1LDAsNC4wNywxLjgyLDQuMDcsNC4wNywwLDIuMjUtMS44Miw0LjA3LTQuMDcsNC4wNy0yLjI1LDAtNC4wNy0xLjgyLTQuMDctNC4wNywwLTIuMjUsMS44Mi00LjA3LDQuMDctNC4wN1pNMTE4LjQxLDExOC42M2MyLjI1LDAsNC4wNywxLjgyLDQuMDcsNC4wNywwLDIuMjUtMS44Miw0LjA3LTQuMDcsNC4wNy0yLjI1LDAtNC4wNy0xLjgyLTQuMDctNC4wNywwLTIuMjUsMS44Mi00LjA3LDQuMDctNC4wN2gwWk0xMzguMzMsMTE4LjYzYzIuMjUsMCw0LjA3LDEuODIsNC4wNyw0LjA3LDAsMi4yNS0xLjgyLDQuMDctNC4wNyw0LjA3LTIuMjUsMC00LjA3LTEuODItNC4wNy00LjA3LDAtMi4yNSwxLjgyLTQuMDcsNC4wNy00LjA3aDBaTTE0Mi45NiwxMTEuNjJjMS4zOSwwLDIuNTIsMS4xMywyLjUyLDIuNTMsMCwxLjM5LTEuMTMsMi41Mi0yLjUzLDIuNTItMS4zOSwwLTIuNTItMS4xMy0yLjUyLTIuNTJzMS4xMy0yLjUyLDIuNTItMi41MmgwWk0xNDIuOTYsMTI4LjQ1YzEuMzksMCwyLjUyLDEuMTMsMi41MiwyLjUzLDAsMS4zOS0xLjEzLDIuNTItMi41MywyLjUyLTEuMzksMC0yLjUyLTEuMTMtMi41Mi0yLjUyczEuMTMtMi41MiwyLjUyLTIuNTJoMFpNMTEzLjc4LDEyOC40NWMxLjM5LDAsMi41MiwxLjEzLDIuNTIsMi41MywwLDEuMzktMS4xMywyLjUyLTIuNTMsMi41Mi0xLjM5LDAtMi41Mi0xLjEzLTIuNTItMi41MiwwLTEuMzksMS4xMy0yLjUyLDIuNTMtMi41MmgwWk0xMTMuNzgsMTExLjYyYzEuMzksMCwyLjUyLDEuMTMsMi41MiwyLjUzLDAsMS4zOS0xLjEzLDIuNTItMi41MywyLjUyLTEuMzksMC0yLjUyLTEuMTMtMi41Mi0yLjUyLDAtMS4zOSwxLjEzLTIuNTIsMi41My0yLjUyaDBaTTEyOC4zNywxMDMuMmMxLjM5LDAsMi41MiwxLjEzLDIuNTIsMi41MywwLDEuMzktMS4xMywyLjUyLTIuNTMsMi41Mi0xLjM5LDAtMi41Mi0xLjEzLTIuNTItMi41MnMxLjEzLTIuNTIsMi41Mi0yLjUyaDBaTTEyOC4zNywxMzYuODZjMS4zOSwwLDIuNTIsMS4xMywyLjUyLDIuNTMsMCwxLjM5LTEuMTMsMi41Mi0yLjUzLDIuNTItMS4zOSwwLTIuNTItMS4xMy0yLjUyLTIuNTJzMS4xMy0yLjUyLDIuNTItMi41MmgwWk0xMzkuMTcsMTM5LjM5YzEuMTYsMCwyLjEuOTQsMi4xLDIuMSwwLDEuMTYtLjk0LDIuMS0yLjEsMi4xLTEuMTYsMC0yLjEtLjk0LTIuMS0yLjFzLjk0LTIuMSwyLjEtMi4xaDBaTTExNy41NywxMzkuMzljMS4xNiwwLDIuMS45NCwyLjEsMi4xLDAsMS4xNi0uOTQsMi4xLTIuMSwyLjEtMS4xNiwwLTIuMS0uOTQtMi4xLTIuMXMuOTQtMi4xLDIuMS0yLjFoMFpNMTE3LjU3LDEwMS41MmMxLjE2LDAsMi4xLjk0LDIuMSwyLjEsMCwxLjE2LS45NCwyLjEtMi4xLDIuMS0xLjE2LDAtMi4xLS45NC0yLjEtMi4xcy45NC0yLjEsMi4xLTIuMWgwWk0xMzkuMTcsMTAxLjUyYzEuMTYsMCwyLjEuOTQsMi4xLDIuMSwwLDEuMTYtLjk0LDIuMS0yLjEsMi4xLTEuMTYsMC0yLjEtLjk0LTIuMS0yLjFzLjk0LTIuMSwyLjEtMi4xaDBaTTE1MC4xMSwxMjAuMzFjMS4xNiwwLDIuMS45NCwyLjEsMi4xLDAsMS4xNi0uOTQsMi4xLTIuMSwyLjEtMS4xNiwwLTIuMS0uOTQtMi4xLTIuMSwwLTEuMTYuOTQtMi4xLDIuMS0yLjFoMFpNMTA2LjYyLDEyMC4zMWMxLjE2LDAsMi4xLjk0LDIuMSwyLjEsMCwxLjE2LS45NCwyLjEtMi4xLDIuMS0xLjE2LDAtMi4xLS45NC0yLjEtMi4xcy45NC0yLjEsMi4xLTIuMWgwWk0xMDUuMDgsMTA3LjQxYy45MywwLDEuNjguNzUsMS42OCwxLjY4cy0uNzUsMS42OC0xLjY4LDEuNjgtMS42OC0uNzUtMS42OC0xLjY4aDBjMC0uOTMuNzUtMS42OCwxLjY4LTEuNjhoMFpNMTA1LjA4LDEzNC4zNGMuOTMsMCwxLjY4Ljc1LDEuNjgsMS42OHMtLjc1LDEuNjgtMS42OCwxLjY4LTEuNjgtLjc1LTEuNjgtMS42OGgwYzAtLjkzLjc1LTEuNjgsMS42OC0xLjY4aDBaTTE1MS42NiwxMzQuMzRjLjkzLDAsMS42OC43NSwxLjY4LDEuNjgsMCwuOTMtLjc1LDEuNjgtMS42OCwxLjY4cy0xLjY4LS43NS0xLjY4LTEuNjhoMGMwLS45My43NS0xLjY4LDEuNjgtMS42OGgwWk0xNTEuNjYsMTA3LjQxYy45MywwLDEuNjguNzUsMS42OCwxLjY4LDAsLjkzLS43NSwxLjY4LTEuNjgsMS42OHMtMS42OC0uNzUtMS42OC0xLjY4aDBjMC0uOTMuNzUtMS42OCwxLjY4LTEuNjhoMFpNMTI4LjM3LDkzLjk0Yy45MywwLDEuNjguNzUsMS42OCwxLjY4LDAsLjkzLS43NSwxLjY4LTEuNjgsMS42OC0uOTMsMC0xLjY4LS43NS0xLjY4LTEuNjhoMGMwLS45My43NS0xLjY4LDEuNjgtMS42OGgwWk0xMjguMzcsMTQ3LjhjLjkzLDAsMS42OC43NSwxLjY4LDEuNjgsMCwuOTMtLjc1LDEuNjgtMS42OCwxLjY4LS45MywwLTEuNjgtLjc1LTEuNjgtMS42OHMuNzUtMS42OCwxLjY4LTEuNjhoMFpNMTQzLjI0LDE0Ni42OGMuNzcsMCwxLjQuNjMsMS40LDEuNCwwLC43Ny0uNjMsMS40LTEuNCwxLjRzLTEuNC0uNjMtMS40LTEuNGgwYzAtLjc3LjYzLTEuNCwxLjQtMS40Wk0xMTMuNSwxNDYuNjhjLjc3LDAsMS40LjYzLDEuNCwxLjRzLS42MywxLjQtMS40LDEuNC0xLjQtLjYzLTEuNC0xLjRoMGMwLS43Ny42My0xLjQsMS40LTEuNFpNMTEzLjUsOTUuNjNjLjc3LDAsMS40LjYzLDEuNCwxLjRzLS42MywxLjQtMS40LDEuNC0xLjQtLjYzLTEuNC0xLjRoMGMwLS43Ny42My0xLjQsMS40LTEuNGgwWk0xNDMuMjQsOTUuNjNjLjc3LDAsMS40LjYzLDEuNCwxLjQsMCwuNzctLjYzLDEuNC0xLjQsMS40cy0xLjQtLjYzLTEuNC0xLjRoMGMwLS43Ny42My0xLjQsMS40LTEuNGgwWk0xNTcuODMsMTIxLjE2Yy43NywwLDEuNC42MywxLjQsMS40LDAsLjc3LS42MywxLjQtMS40LDEuNHMtMS40LS42My0xLjQtMS40aDBjMC0uNzguNjMtMS40LDEuNC0xLjRoMFpNOTguOTEsMTIxLjE2Yy43NywwLDEuNC42MywxLjQsMS40cy0uNjMsMS40LTEuNCwxLjQtMS40LS42My0xLjQtMS40aDBjMC0uNzguNjMtMS40LDEuNC0xLjRoMFoiLz4KICAgICAgPC9nPgogICAgPC9nPgogIDwvZz4KPC9zdmc+",
+ version: "version",
+ });
+ } else {
+ resolve(undefined);
+ }
+ });
+ });
+ } catch (err) {
+ return Promise.resolve(undefined);
+ }
+}
diff --git a/packages/mesh-wallet/src/mesh/index.ts b/packages/mesh-wallet/src/mesh/index.ts
index d36b8769c..7531fd18d 100644
--- a/packages/mesh-wallet/src/mesh/index.ts
+++ b/packages/mesh-wallet/src/mesh/index.ts
@@ -15,19 +15,27 @@ import {
} from "@meshsdk/common";
import {
Address,
+ buildBaseAddress,
+ buildEnterpriseAddress,
+ buildRewardAddress,
+ CardanoSDKSerializer,
+ deserializeAddress,
+ deserializeTx,
+ Ed25519KeyHashHex,
fromTxUnspentOutput,
+ Hash28ByteBase16,
resolvePrivateKey,
+ toAddress,
toTxUnspentOutput,
TransactionUnspentOutput,
} from "@meshsdk/core-cst";
import { Transaction } from "@meshsdk/transaction";
-import { AppWallet } from "../app";
import { EmbeddedWallet } from "../embedded";
import { GetAddressType } from "../types";
export type CreateMeshWalletOptions = {
- networkId: number;
+ networkId: 0 | 1;
fetcher?: IFetcher;
submitter?: ISubmitter;
key:
@@ -44,6 +52,12 @@ export type CreateMeshWalletOptions = {
type: "mnemonic";
words: string[];
};
+ // | {
+ // type: "address";
+ // address: string;
+ // }
+ accountIndex?: number;
+ keyIndex?: number;
};
/**
@@ -68,45 +82,69 @@ export type CreateMeshWalletOptions = {
* ```
*/
export class MeshWallet implements IInitiator, ISigner, ISubmitter {
- private readonly _wallet: AppWallet;
+ private readonly _wallet: EmbeddedWallet | null;
+ // private readonly _account: Account;
+ private readonly _accountIndex: number = 0;
+ private readonly _keyIndex: number = 0;
+ private readonly _fetcher?: IFetcher;
+ private readonly _submitter?: ISubmitter;
+ private readonly _networkId: 0 | 1;
+ private _addresses: {
+ baseAddress?: Address;
+ enterpriseAddress?: Address;
+ rewardAddress?: Address;
+ baseAddressBech32?: string;
+ enterpriseAddressBech32?: string;
+ rewardAddressBech32?: string;
+ } = {};
constructor(options: CreateMeshWalletOptions) {
switch (options.key.type) {
case "root":
- this._wallet = new AppWallet({
+ this._wallet = new EmbeddedWallet({
networkId: options.networkId,
- fetcher: options.fetcher,
- submitter: options.submitter,
key: {
type: "root",
bech32: options.key.bech32,
},
});
+ this.getAddressesFromWallet(this._wallet);
break;
case "cli":
- this._wallet = new AppWallet({
+ this._wallet = new EmbeddedWallet({
networkId: options.networkId,
- fetcher: options.fetcher,
- submitter: options.submitter,
key: {
type: "cli",
payment: options.key.payment,
stake: options.key.stake,
},
});
+ this.getAddressesFromWallet(this._wallet);
break;
case "mnemonic":
- this._wallet = new AppWallet({
+ this._wallet = new EmbeddedWallet({
networkId: options.networkId,
- fetcher: options.fetcher,
- submitter: options.submitter,
key: {
type: "mnemonic",
words: options.key.words,
},
});
+ this.getAddressesFromWallet(this._wallet);
break;
+ // case "address":
+ // console.log(4);
+ // this._wallet = null;
+ // this.buildAddressFromBech32Address(options.key.address);
+ // console.log(5);
+ // break;
}
+
+ this._networkId = options.networkId;
+
+ if (options.fetcher) this._fetcher = options.fetcher;
+ if (options.submitter) this._submitter = options.submitter;
+ if (options.accountIndex) this._accountIndex = options.accountIndex;
+ if (options.keyIndex) this._keyIndex = options.keyIndex;
}
/**
@@ -148,7 +186,7 @@ export class MeshWallet implements IInitiator, ISigner, ISubmitter {
* @returns an address
*/
getChangeAddress(): string {
- return this._wallet.getPaymentAddress();
+ return this._addresses.baseAddressBech32!;
}
/**
@@ -162,19 +200,53 @@ export class MeshWallet implements IInitiator, ISigner, ISubmitter {
async getCollateral(
addressType: GetAddressType = "payment",
): Promise {
- const utxos = await this._wallet.getCollateralUnspentOutput(0, addressType);
+ const utxos = await this.getCollateralUnspentOutput(addressType);
return utxos.map((utxo, i) => {
return fromTxUnspentOutput(utxo);
});
}
+ /**
+ * Get a list of UTXOs to be used as collateral inputs for transactions with plutus script inputs.
+ *
+ * This is used in transaction building.
+ *
+ * @returns a list of UTXOs
+ */
+ async getCollateralUnspentOutput(
+ addressType: GetAddressType = "payment",
+ ): Promise {
+ const utxos = await this.getUnspentOutputs(addressType);
+
+ // find utxos that are pure ADA-only
+ const pureAdaUtxos = utxos.filter((utxo) => {
+ return utxo.output().amount().multiasset() === undefined;
+ });
+
+ // sort utxos by their lovelace amount
+ pureAdaUtxos.sort((a, b) => {
+ return (
+ Number(a.output().amount().coin()) - Number(b.output().amount().coin())
+ );
+ });
+
+ // return the smallest utxo but not less than 5000000 lovelace
+ for (const utxo of pureAdaUtxos) {
+ if (Number(utxo.output().amount().coin()) >= 5000000) {
+ return [utxo];
+ }
+ }
+
+ return [];
+ }
+
/**
* Returns the network ID of the currently connected account. 0 is testnet and 1 is mainnet but other networks can possibly be returned by wallets. Those other network ID values are not governed by CIP-30. This result will stay the same unless the connected account has changed.
*
* @returns network ID
*/
getNetworkId(): number {
- return this._wallet.getNetworkId();
+ return this._networkId;
}
/**
@@ -183,7 +255,7 @@ export class MeshWallet implements IInitiator, ISigner, ISubmitter {
* @returns a list of reward addresses
*/
getRewardAddresses(): string[] {
- return [this._wallet.getRewardAddress()];
+ return [this._addresses.rewardAddressBech32!];
}
/**
@@ -254,6 +326,11 @@ export class MeshWallet implements IInitiator, ISigner, ISubmitter {
* @returns a signature
*/
signData(payload: string): DataSignature {
+ if (!this._wallet) {
+ throw new Error(
+ "[MeshWallet] Read only wallet does not support signing data.",
+ );
+ }
return this._wallet.signData(this.getChangeAddress(), payload);
}
@@ -265,7 +342,30 @@ export class MeshWallet implements IInitiator, ISigner, ISubmitter {
* @returns a signed transaction in CBOR
*/
signTx(unsignedTx: string, partialSign = false): string {
- return this._wallet.signTx(unsignedTx, partialSign);
+ if (!this._wallet) {
+ throw new Error(
+ "[MeshWallet] Read only wallet does not support signing data.",
+ );
+ }
+
+ const tx = deserializeTx(unsignedTx);
+ if (
+ !partialSign &&
+ tx.witnessSet().vkeys() !== undefined &&
+ tx.witnessSet().vkeys()!.size() !== 0
+ )
+ throw new Error(
+ "Signatures already exist in the transaction in a non partial sign call",
+ );
+
+ const newSignatures = this._wallet.signTx(
+ unsignedTx,
+ this._accountIndex,
+ this._keyIndex,
+ );
+
+ let signedTx = EmbeddedWallet.addWitnessSets(unsignedTx, [newSignatures]);
+ return signedTx;
}
/**
@@ -295,7 +395,12 @@ export class MeshWallet implements IInitiator, ISigner, ISubmitter {
* @returns a transaction hash
*/
async submitTx(tx: string): Promise {
- return await this._wallet.submitTx(tx);
+ if (!this._submitter) {
+ throw new Error(
+ "[AppWallet] Submitter is required to submit transactions. Please provide a submitter.",
+ );
+ }
+ return this._submitter.submitTx(tx);
}
/**
@@ -306,7 +411,11 @@ export class MeshWallet implements IInitiator, ISigner, ISubmitter {
* @returns an Address object
*/
getUsedAddress(addressType?: GetAddressType): Address {
- return this._wallet.getUsedAddress(0, 0, addressType);
+ if (addressType === "enterprise") {
+ return toAddress(this._addresses.enterpriseAddressBech32!);
+ } else {
+ return toAddress(this._addresses.baseAddressBech32!);
+ }
}
/**
@@ -319,7 +428,19 @@ export class MeshWallet implements IInitiator, ISigner, ISubmitter {
async getUnspentOutputs(
addressType?: GetAddressType,
): Promise {
- return await this._wallet.getUnspentOutputs(0, addressType);
+ if (!this._fetcher) {
+ throw new Error(
+ "[AppWallet] Fetcher is required to fetch UTxOs. Please provide a fetcher.",
+ );
+ }
+
+ const utxos = await this._fetcher.fetchAddressUTxOs(
+ addressType == "enterprise"
+ ? this._addresses.enterpriseAddressBech32!
+ : this._addresses.baseAddressBech32!,
+ );
+
+ return utxos.map((utxo) => toTxUnspentOutput(utxo));
}
/**
@@ -410,4 +531,66 @@ export class MeshWallet implements IInitiator, ISigner, ISubmitter {
return mnemonic;
}
+
+ getAddressesFromWallet(wallet: EmbeddedWallet) {
+ const account = wallet.getAccount(this._accountIndex, this._keyIndex);
+
+ this._addresses = {
+ baseAddress: account.baseAddress,
+ enterpriseAddress: account.enterpriseAddress,
+ rewardAddress: account.rewardAddress,
+ baseAddressBech32: account.baseAddressBech32,
+ enterpriseAddressBech32: account.enterpriseAddressBech32,
+ rewardAddressBech32: account.rewardAddressBech32,
+ };
+ }
+
+ buildAddressFromBech32Address(address: string) {
+ const serializer = new CardanoSDKSerializer();
+
+ const deserializedAddress =
+ serializer.deserializer.key.deserializeAddress(address);
+
+ if (
+ deserializedAddress.pubKeyHash &&
+ deserializedAddress.stakeCredentialHash
+ ) {
+ this._addresses.baseAddress = buildBaseAddress(
+ this._networkId,
+ Hash28ByteBase16.fromEd25519KeyHashHex(
+ Ed25519KeyHashHex(deserializedAddress.pubKeyHash),
+ ),
+ Hash28ByteBase16.fromEd25519KeyHashHex(
+ Ed25519KeyHashHex(
+ Ed25519KeyHashHex(deserializedAddress.stakeCredentialHash),
+ ),
+ ),
+ ).toAddress();
+ this._addresses.baseAddressBech32 =
+ this._addresses.baseAddress.toBech32();
+ }
+
+ if (deserializedAddress.pubKeyHash) {
+ this._addresses.enterpriseAddress = buildEnterpriseAddress(
+ this._networkId,
+ Hash28ByteBase16.fromEd25519KeyHashHex(
+ Ed25519KeyHashHex(deserializedAddress.pubKeyHash),
+ ),
+ ).toAddress();
+ this._addresses.enterpriseAddressBech32 =
+ this._addresses.enterpriseAddress.toBech32();
+ }
+
+ if (deserializedAddress.stakeCredentialHash) {
+ this._addresses.rewardAddress = buildRewardAddress(
+ this._networkId,
+ Hash28ByteBase16.fromEd25519KeyHashHex(
+ Ed25519KeyHashHex(deserializedAddress.stakeCredentialHash),
+ ),
+ ).toAddress();
+
+ this._addresses.rewardAddressBech32 =
+ this._addresses.rewardAddress.toBech32();
+ }
+ }
}
diff --git a/packages/mesh-wallet/src/mesh_old/index.ts b/packages/mesh-wallet/src/mesh_old/index.ts
new file mode 100644
index 000000000..d36b8769c
--- /dev/null
+++ b/packages/mesh-wallet/src/mesh_old/index.ts
@@ -0,0 +1,413 @@
+import type {
+ Asset,
+ AssetExtended,
+ DataSignature,
+ UTxO,
+} from "@meshsdk/common";
+import {
+ IFetcher,
+ IInitiator,
+ ISigner,
+ ISubmitter,
+ POLICY_ID_LENGTH,
+ resolveFingerprint,
+ toUTF8,
+} from "@meshsdk/common";
+import {
+ Address,
+ fromTxUnspentOutput,
+ resolvePrivateKey,
+ toTxUnspentOutput,
+ TransactionUnspentOutput,
+} from "@meshsdk/core-cst";
+import { Transaction } from "@meshsdk/transaction";
+
+import { AppWallet } from "../app";
+import { EmbeddedWallet } from "../embedded";
+import { GetAddressType } from "../types";
+
+export type CreateMeshWalletOptions = {
+ networkId: number;
+ fetcher?: IFetcher;
+ submitter?: ISubmitter;
+ key:
+ | {
+ type: "root";
+ bech32: string;
+ }
+ | {
+ type: "cli";
+ payment: string;
+ stake?: string;
+ }
+ | {
+ type: "mnemonic";
+ words: string[];
+ };
+};
+
+/**
+ * Mesh Wallet provides a set of APIs to interact with the blockchain. This wallet is compatible with Mesh transaction builders.
+ *
+ * It is a single address wallet, a wrapper around the AppWallet class.
+ *
+ * ```javascript
+ * import { MeshWallet, BlockfrostProvider } from '@meshsdksdk/core';
+ *
+ * const blockchainProvider = new BlockfrostProvider('');
+ *
+ * const wallet = new MeshWallet({
+ * networkId: 0,
+ * fetcher: blockchainProvider,
+ * submitter: blockchainProvider,
+ * key: {
+ * type: 'mnemonic',
+ * words: ["solution","solution","solution","solution","solution",","solution","solution","solution","solution","solution","solution","solution","solution","solution","solution","solution","solution","solution","solution","solution","solution","solution","solution"],
+ * },
+ * });
+ * ```
+ */
+export class MeshWallet implements IInitiator, ISigner, ISubmitter {
+ private readonly _wallet: AppWallet;
+
+ constructor(options: CreateMeshWalletOptions) {
+ switch (options.key.type) {
+ case "root":
+ this._wallet = new AppWallet({
+ networkId: options.networkId,
+ fetcher: options.fetcher,
+ submitter: options.submitter,
+ key: {
+ type: "root",
+ bech32: options.key.bech32,
+ },
+ });
+ break;
+ case "cli":
+ this._wallet = new AppWallet({
+ networkId: options.networkId,
+ fetcher: options.fetcher,
+ submitter: options.submitter,
+ key: {
+ type: "cli",
+ payment: options.key.payment,
+ stake: options.key.stake,
+ },
+ });
+ break;
+ case "mnemonic":
+ this._wallet = new AppWallet({
+ networkId: options.networkId,
+ fetcher: options.fetcher,
+ submitter: options.submitter,
+ key: {
+ type: "mnemonic",
+ words: options.key.words,
+ },
+ });
+ break;
+ }
+ }
+
+ /**
+ * Returns a list of assets in the wallet. This API will return every assets in the wallet. Each asset is an object with the following properties:
+ * - A unit is provided to display asset's name on the user interface.
+ * - A quantity is provided to display asset's quantity on the user interface.
+ *
+ * @returns a list of assets and their quantities
+ */
+ async getBalance(): Promise {
+ const utxos = await this.getUnspentOutputs();
+
+ const assets = new Map();
+ utxos.map((utxo) => {
+ const _utxo = fromTxUnspentOutput(utxo);
+ _utxo.output.amount.map((asset) => {
+ const assetId = asset.unit;
+ const amount = Number(asset.quantity);
+ if (assets.has(assetId)) {
+ const quantity = assets.get(assetId)!;
+ assets.set(assetId, quantity + amount);
+ } else {
+ assets.set(assetId, amount);
+ }
+ });
+ });
+
+ const arrayAssets: Asset[] = Array.from(assets, ([unit, quantity]) => ({
+ unit,
+ quantity: quantity.toString(),
+ }));
+
+ return arrayAssets;
+ }
+
+ /**
+ * Returns an address owned by the wallet that should be used as a change address to return leftover assets during transaction creation back to the connected wallet.
+ *
+ * @returns an address
+ */
+ getChangeAddress(): string {
+ return this._wallet.getPaymentAddress();
+ }
+
+ /**
+ * This function shall return a list of one or more UTXOs (unspent transaction outputs) controlled by the wallet that are required to reach AT LEAST the combined ADA value target specified in amount AND the best suitable to be used as collateral inputs for transactions with plutus script inputs (pure ADA-only UTXOs).
+ *
+ * If this cannot be attained, an error message with an explanation of the blocking problem shall be returned. NOTE: wallets are free to return UTXOs that add up to a greater total ADA value than requested in the amount parameter, but wallets must never return any result where UTXOs would sum up to a smaller total ADA value, instead in a case like that an error message must be returned.
+ *
+ * @returns a list of UTXOs
+ */
+
+ async getCollateral(
+ addressType: GetAddressType = "payment",
+ ): Promise {
+ const utxos = await this._wallet.getCollateralUnspentOutput(0, addressType);
+ return utxos.map((utxo, i) => {
+ return fromTxUnspentOutput(utxo);
+ });
+ }
+
+ /**
+ * Returns the network ID of the currently connected account. 0 is testnet and 1 is mainnet but other networks can possibly be returned by wallets. Those other network ID values are not governed by CIP-30. This result will stay the same unless the connected account has changed.
+ *
+ * @returns network ID
+ */
+ getNetworkId(): number {
+ return this._wallet.getNetworkId();
+ }
+
+ /**
+ * Returns a list of reward addresses owned by the wallet. A reward address is a stake address that is used to receive rewards from staking, generally starts from `stake` prefix.
+ *
+ * @returns a list of reward addresses
+ */
+ getRewardAddresses(): string[] {
+ return [this._wallet.getRewardAddress()];
+ }
+
+ /**
+ * Returns a list of unused addresses controlled by the wallet.
+ *
+ * @returns a list of unused addresses
+ */
+ getUnusedAddresses(): string[] {
+ return [this.getChangeAddress()];
+ }
+
+ /**
+ * Returns a list of used addresses controlled by the wallet.
+ *
+ * @returns a list of used addresses
+ */
+ getUsedAddresses(): string[] {
+ return [this.getChangeAddress()];
+ }
+
+ /**
+ * Get a list of UTXOs to be used as collateral inputs for transactions with plutus script inputs.
+ *
+ * This is used in transaction building.
+ *
+ * @returns a list of UTXOs
+ */
+ async getUsedCollateral(): Promise {
+ const collateralUtxo = await this.getCollateral();
+
+ const unspentOutput = collateralUtxo.map((utxo) => {
+ return toTxUnspentOutput(utxo);
+ });
+
+ return unspentOutput;
+ }
+
+ /**
+ * Get a list of UTXOs to be used for transaction building.
+ *
+ * This is used in transaction building.
+ *
+ * @returns a list of UTXOs
+ */
+ async getUsedUTxOs(
+ addressType?: GetAddressType,
+ ): Promise {
+ return await this.getUnspentOutputs(addressType);
+ }
+
+ /**
+ * Return a list of all UTXOs (unspent transaction outputs) controlled by the wallet.
+ *
+ * @returns a list of UTXOs
+ */
+ async getUtxos(addressType?: GetAddressType): Promise {
+ const utxos = await this.getUsedUTxOs(addressType);
+ return utxos.map((c) => fromTxUnspentOutput(c));
+ }
+
+ /**
+ * This endpoint utilizes the [CIP-8 - Message Signing](https://github.com/cardano-foundation/CIPs/tree/master/CIP-0030) to sign arbitrary data, to verify the data was signed by the owner of the private key.
+ *
+ * Here, we get the first wallet's address with wallet.getUsedAddresses(), alternativelly you can use reward addresses (getRewardAddresses()) too. It's really up to you as the developer which address you want to use in your application.
+ *
+ * @param address
+ * @param payload
+ * @returns a signature
+ */
+ signData(payload: string): DataSignature {
+ return this._wallet.signData(this.getChangeAddress(), payload);
+ }
+
+ /**
+ * Requests user to sign the provided transaction (tx). The wallet should ask the user for permission, and if given, try to sign the supplied body and return a signed transaction. partialSign should be true if the transaction provided requires multiple signatures.
+ *
+ * @param unsignedTx
+ * @param partialSign
+ * @returns a signed transaction in CBOR
+ */
+ signTx(unsignedTx: string, partialSign = false): string {
+ return this._wallet.signTx(unsignedTx, partialSign);
+ }
+
+ /**
+ * Experimental feature - sign multiple transactions at once.
+ *
+ * @param unsignedTxs - array of unsigned transactions in CborHex string
+ * @param partialSign - if the transactions are signed partially
+ * @returns array of signed transactions CborHex string
+ */
+ signTxs(unsignedTxs: string[], partialSign = false): string[] {
+ const signedTxs: string[] = [];
+
+ for (const unsignedTx of unsignedTxs) {
+ const signedTx = this.signTx(unsignedTx, partialSign);
+ signedTxs.push(signedTx);
+ }
+
+ return signedTxs;
+ }
+
+ /**
+ * Submits the signed transaction to the blockchain network.
+ *
+ * As wallets should already have this ability to submit transaction, we allow dApps to request that a transaction be sent through it. If the wallet accepts the transaction and tries to send it, it shall return the transaction ID for the dApp to track. The wallet can return error messages or failure if there was an error in sending it.
+ *
+ * @param tx
+ * @returns a transaction hash
+ */
+ async submitTx(tx: string): Promise {
+ return await this._wallet.submitTx(tx);
+ }
+
+ /**
+ * Get a used address of type Address from the wallet.
+ *
+ * This is used in transaction building.
+ *
+ * @returns an Address object
+ */
+ getUsedAddress(addressType?: GetAddressType): Address {
+ return this._wallet.getUsedAddress(0, 0, addressType);
+ }
+
+ /**
+ * Get a list of UTXOs to be used for transaction building.
+ *
+ * This is used in transaction building.
+ *
+ * @returns a list of UTXOs
+ */
+ async getUnspentOutputs(
+ addressType?: GetAddressType,
+ ): Promise {
+ return await this._wallet.getUnspentOutputs(0, addressType);
+ }
+
+ /**
+ * A helper function to get the assets in the wallet.
+ *
+ * @returns a list of assets
+ */
+ async getAssets(): Promise {
+ const balance = await this.getBalance();
+ return balance
+ .filter((v) => v.unit !== "lovelace")
+ .map((v) => {
+ const policyId = v.unit.slice(0, POLICY_ID_LENGTH);
+ const assetName = v.unit.slice(POLICY_ID_LENGTH);
+ const fingerprint = resolveFingerprint(policyId, assetName);
+
+ return {
+ unit: v.unit,
+ policyId,
+ assetName: toUTF8(assetName),
+ fingerprint,
+ quantity: v.quantity,
+ };
+ });
+ }
+
+ /**
+ * A helper function to get the lovelace balance in the wallet.
+ *
+ * @returns lovelace balance
+ */
+ async getLovelace(): Promise {
+ const balance = await this.getBalance();
+ const nativeAsset = balance.find((v) => v.unit === "lovelace");
+
+ return nativeAsset !== undefined ? nativeAsset.quantity : "0";
+ }
+
+ /**
+ * A helper function to get the assets of a specific policy ID in the wallet.
+ *
+ * @param policyId
+ * @returns a list of assets
+ */
+ async getPolicyIdAssets(policyId: string): Promise {
+ const assets = await this.getAssets();
+ return assets.filter((v) => v.policyId === policyId);
+ }
+
+ /**
+ * A helper function to get the policy IDs of all the assets in the wallet.
+ *
+ * @returns a list of policy IDs
+ */
+ async getPolicyIds(): Promise {
+ const balance = await this.getBalance();
+ return Array.from(
+ new Set(balance.map((v) => v.unit.slice(0, POLICY_ID_LENGTH))),
+ ).filter((p) => p !== "lovelace");
+ }
+
+ /**
+ * A helper function to create a collateral input for a transaction.
+ *
+ * @returns a transaction hash
+ */
+ async createCollateral(): Promise {
+ const tx = new Transaction({ initiator: this });
+ tx.sendLovelace(this.getChangeAddress(), "5000000");
+ const unsignedTx = await tx.build();
+ const signedTx = await this.signTx(unsignedTx);
+ const txHash = await this.submitTx(signedTx);
+ return txHash;
+ }
+
+ /**
+ * Generate mnemonic or private key
+ *
+ * @param privateKey return private key if true
+ * @returns a transaction hash
+ */
+ static brew(privateKey = false, strength = 256): string[] | string {
+ const mnemonic = EmbeddedWallet.generateMnemonic(strength);
+
+ if (privateKey) {
+ return resolvePrivateKey(mnemonic);
+ }
+
+ return mnemonic;
+ }
+}
diff --git a/packages/mesh-wallet/test/app.test.ts b/packages/mesh-wallet/test/app.test.ts
index fed9c007d..02c6730f7 100644
--- a/packages/mesh-wallet/test/app.test.ts
+++ b/packages/mesh-wallet/test/app.test.ts
@@ -1,4 +1,4 @@
-import { AppWallet } from "../src";
+import { AppWallet } from "@meshsdk/wallet";
describe("AppWallet", () => {
const wallet = new AppWallet({
diff --git a/packages/mesh-wallet/test/browser.test.ts b/packages/mesh-wallet/test/browser.test.ts
index ac7d6f9c4..e2db9b52f 100644
--- a/packages/mesh-wallet/test/browser.test.ts
+++ b/packages/mesh-wallet/test/browser.test.ts
@@ -1,6 +1,5 @@
import { CardanoSDKUtil, Serialization } from "@meshsdk/core-cst";
-
-import { WalletStaticMethods } from "../src";
+import { WalletStaticMethods } from "@meshsdk/wallet";
describe("BroswerWallet", () => {
it("signTx: addWitnessSet", () => {
diff --git a/packages/mesh-wallet/test/embedded.test.ts b/packages/mesh-wallet/test/embedded.test.ts
index 7c95132e9..9b0e84c2c 100644
--- a/packages/mesh-wallet/test/embedded.test.ts
+++ b/packages/mesh-wallet/test/embedded.test.ts
@@ -1,6 +1,5 @@
import { checkSignature } from "@meshsdk/core-cst";
-
-import { EmbeddedWallet } from "../src";
+import { EmbeddedWallet } from "@meshsdk/wallet";
describe("EmbeddedWallet mnemonic", () => {
const wallet = new EmbeddedWallet({
diff --git a/packages/mesh-wallet/test/mesh.test.ts b/packages/mesh-wallet/test/mesh.test.ts
index 7b78638cc..0b3bbf20e 100644
--- a/packages/mesh-wallet/test/mesh.test.ts
+++ b/packages/mesh-wallet/test/mesh.test.ts
@@ -1,4 +1,4 @@
-import { MeshWallet } from "../src";
+import { MeshWallet } from "@meshsdk/wallet";
describe("MeshWallet", () => {
const wallet = new MeshWallet({