diff --git a/apps/playground/public/guides/laptop-3196481_640.jpg b/apps/playground/public/guides/laptop-3196481_640.jpg new file mode 100644 index 00000000..c3fd0fb9 Binary files /dev/null and b/apps/playground/public/guides/laptop-3196481_640.jpg differ diff --git a/apps/playground/public/guides/vesting.png b/apps/playground/public/guides/vesting.png new file mode 100644 index 00000000..25bd9248 Binary files /dev/null and b/apps/playground/public/guides/vesting.png differ diff --git a/apps/playground/src/components/layouts/sidebar/index.tsx b/apps/playground/src/components/layouts/sidebar/index.tsx index bee78460..58ae6e54 100644 --- a/apps/playground/src/components/layouts/sidebar/index.tsx +++ b/apps/playground/src/components/layouts/sidebar/index.tsx @@ -15,7 +15,7 @@ export default function Sidebar({ {sidebarItems.map((item, i) => { return (
  • - {item.to.startsWith("/") ? ( + {item.to.startsWith("/") || item.to.startsWith("http") ? ( {item.label} ) : ( diff --git a/apps/playground/src/data/links-guides.ts b/apps/playground/src/data/links-guides.ts index 257dd1b7..4ef80687 100644 --- a/apps/playground/src/data/links-guides.ts +++ b/apps/playground/src/data/links-guides.ts @@ -58,6 +58,13 @@ export const guidestandalone = { thumbnail: "/guides/standalone.png", image: "/guides/salt-harvesting-3060093_1280.jpg", }; +export const guideVesting = { + title: "Vesting Script End-to-End", + desc: "Learn how to vesting contract that locks up funds for a period of time and allows the owner to withdraw the funds after the lockup period.", + link: "/guides/vesting", + thumbnail: "/guides/vesting.png", + image: "/guides/laptop-3196481_640.jpg", +}; export const linksGuides: MenuItem[] = [ guidenextjs, @@ -68,6 +75,7 @@ export const linksGuides: MenuItem[] = [ guidetransactions, guideaiken, guidestandalone, + guideVesting, ]; export const metaGuides: MenuItem = { diff --git a/apps/playground/src/data/links-yaci.ts b/apps/playground/src/data/links-yaci.ts index a151d633..3bd23352 100644 --- a/apps/playground/src/data/links-yaci.ts +++ b/apps/playground/src/data/links-yaci.ts @@ -1,5 +1,10 @@ import { MenuItem } from "~/types/menu-item"; +export const metaYaciHosted = { + title: "Hosted Yaci Devnet", + desc: "Connect to the hosted Yaci Devnet", + link: "https://cloud.meshjs.dev/yaci", +}; export const metaYaciGettingStarted = { title: "Getting Started", desc: "Set up Yaci Dev Kit and start the devnet", @@ -17,6 +22,7 @@ export const metaYaciProvider = { }; export const linksYaci: MenuItem[] = [ metaYaciGettingStarted, + metaYaciHosted, metaYaciTransactions, metaYaciProvider, ]; diff --git a/apps/playground/src/hooks/useProviders.ts b/apps/playground/src/hooks/useProviders.ts index 61e51b74..4ff5dfe9 100644 --- a/apps/playground/src/hooks/useProviders.ts +++ b/apps/playground/src/hooks/useProviders.ts @@ -31,7 +31,7 @@ export const useProviders = create( set({ maestroKey: { network, apiKey } }), koiosKey: undefined, setKoiosKey: (network, apiKey) => set({ koiosKey: { network, apiKey } }), - yaciUrl: "http://localhost:8080/api/v1/", + yaciUrl: "https://yaci-node.meshjs.dev/api/v1/", setYaciUrl: (url) => set({ yaciUrl: url }), ogmiosUrl: "", setOgmiosUrl: (url) => set({ ogmiosUrl: url }), diff --git a/apps/playground/src/pages/apis/wallets/meshwallet/sign-data.tsx b/apps/playground/src/pages/apis/wallets/meshwallet/sign-data.tsx index c9cca0a2..f41cfeaf 100644 --- a/apps/playground/src/pages/apis/wallets/meshwallet/sign-data.tsx +++ b/apps/playground/src/pages/apis/wallets/meshwallet/sign-data.tsx @@ -35,6 +35,10 @@ function Left() { to sign arbitrary data, to verify the data was signed by the owner of the private key.

    +

    + signData takes two arguments, the first one is the payload + to sign and the second one is the address (optional). +

    Example of a response from the endpoint:

    diff --git a/apps/playground/src/pages/guides/prove-wallet-ownership/index.mdx b/apps/playground/src/pages/guides/prove-wallet-ownership/index.mdx index 76dd0fb1..dc548e82 100644 --- a/apps/playground/src/pages/guides/prove-wallet-ownership/index.mdx +++ b/apps/playground/src/pages/guides/prove-wallet-ownership/index.mdx @@ -99,7 +99,7 @@ Lastly, we will return the **nonce** for the user to sign using their private ke ## Client: Verify ownership by signing the nonce -We are ready to use the private key associated with the wallet to sign the nonce with **await wallet.signData(userAddress, nonce)**, which enables the dApp to request the user to sign a payload according to [CIP-8](https://cips.cardano.org/cips/cip8/). +We are ready to use the private key associated with the wallet to sign the nonce with **await wallet.signData(nonce, userAddress)**, which enables the dApp to request the user to sign a payload according to [CIP-8](https://cips.cardano.org/cips/cip8/). We request the user's authorization and show them the message that is to be signed: **Sign to login in to Mesh: nonce**. Once accepted, the signature will be generated and the dApp will process the signature to authenticate the user. @@ -107,7 +107,7 @@ We request the user's authorization and show them the message that is to be sign async function frontendSignMessage(nonce) { try { const userAddress = (await wallet.getRewardAddresses())[0]; - const signature = await wallet.signData(userAddress, nonce); + const signature = await wallet.signData(nonce, userAddress); // do: send request with 'signature' and 'userAddress' to the backend } catch (error) { @@ -175,7 +175,7 @@ export default function Page() { async function frontendSignMessage(nonce) { try { const userAddress = (await wallet.getRewardAddresses())[0]; - const signature = await wallet.signData(userAddress, nonce); + const signature = await wallet.signData(nonce, userAddress); await backendVerifySignature(userAddress, signature); } catch (error) { setState(0); diff --git a/apps/playground/src/pages/guides/vesting/demo.tsx b/apps/playground/src/pages/guides/vesting/demo.tsx new file mode 100644 index 00000000..c576b7ac --- /dev/null +++ b/apps/playground/src/pages/guides/vesting/demo.tsx @@ -0,0 +1,12 @@ +import { VestingDepositFundDemo } from "../../smart-contracts/vesting/deposit-fund"; +import { VestingWithdrawFundDemo } from "../../smart-contracts/vesting/withdraw-fund"; + +export default function Demo() { + return ( + <> +

    Demo

    + + + + ); +} diff --git a/apps/playground/src/pages/guides/vesting/index.mdx b/apps/playground/src/pages/guides/vesting/index.mdx new file mode 100644 index 00000000..0c377331 --- /dev/null +++ b/apps/playground/src/pages/guides/vesting/index.mdx @@ -0,0 +1,287 @@ +import LayoutImageHeaderAndBody from "~/components/layouts/image-header-and-body"; +import { guideVesting } from "~/data/links-guides"; +import Demo from "./demo"; + +export default function MDXPage({ children }) { + return ( + + <> + {children} + + + + ); +} + +Vesting contract is a smart contract that locks up funds for a period of time and allows the owner to withdraw the funds after the lockup period. Usually, vesting contract defines a beneficiary who can be different from the original owner. + +When a new employee joins an organization, they typically receive a promise of compensation to be disbursed after a specified duration of employment. This arrangement often involves the organization depositing the funds into a vesting contract, with the employee gaining access to the funds upon the completion of a predetermined lockup period. Through the utilization of vesting contracts, organizations establish a mechanism to encourage employee retention by linking financial rewards to tenure. + +## On-Chain code + +First, we define the datum's shape, as this datum serves as configuration and contains the different parameters of our vesting operation. + +```rs +pub type VestingDatum { + /// POSIX time in milliseconds, e.g. 1672843961000 + lock_until: Int, + /// Owner's credentials + owner: ByteArray, + /// Beneficiary's credentials + beneficiary: ByteArray, +} +``` + +In this example, we define a `VestingDatum` that contains the following fields: + +- `lock_until`: The POSIX timestamp in milliseconds until which the funds are locked. +- `owner`: The credentials (public key hash) of the owner of the funds. +- `beneficiary`: The credentials (public key hash) of the beneficiary of the funds. + +This datum can be found in `aiken-vesting/aiken-workspace/lib/vesting/types.ak`. + +Next, we define the spend validator. + +```rs +use aiken/transaction.{ScriptContext, Spend} +use vesting/types.{VestingDatum} +use vodka_extra_signatories.{key_signed} +use vodka_validity_range.{valid_after} + +validator { + pub fn vesting(datum: VestingDatum, _redeemer: Data, ctx: ScriptContext) { + // In principle, scripts can be used for different purpose (e.g. minting + // assets). Here we make sure it's only used when 'spending' from a eUTxO + when ctx.purpose is { + Spend(_) -> or { + key_signed(ctx.transaction.extra_signatories, datum.owner), + and { + key_signed(ctx.transaction.extra_signatories, datum.beneficiary), + valid_after(ctx.transaction.validity_range, datum.lock_until), + }, + } + _ -> False + } + } +} +``` + +In this example, we define a `vesting` validator that ensures the following conditions are met: + +- The transaction must be signed by owner + +Or: + +- The transaction must be signed by beneficiary +- The transaction must be valid after the lockup period + +This validator can be found in `aiken-vesting/aiken-workspace/validators/vesting.ak`. + +### How it works + +The owner of the funds deposits the funds into the vesting contract. The funds are locked up until the lockup period expires. + +Transactions can include validity intervals that specify when the transaction is valid, both from and until a certain time. The ledger verifies these validity bounds before executing a script and will only proceed if they are legitimate. + +This approach allows scripts to incorporate a sense of time while maintaining determinism within the script's context. For instance, if a transaction has a lower bound `A`, we can infer that the current time is at least `A`. + +It's important to note that since we don't control the upper bound, a transaction might be executed even 30 years after the vesting delay. However, from the script's perspective, this is entirely acceptable. + +The beneficiary can withdraw the funds after the lockup period expires. The beneficiary can also be different from the owner of the funds. + +## Testing + +To test the vesting contract, we have provided the a comphrehensive test script,you can run tests with `aiken check`. + +The test script includes the following test cases: + +- success unlocking +- success unlocking with only owner signature +- success unlocking with beneficiary signature and time passed +- fail unlocking with only beneficiary signature +- fail unlocking with only time passed + +We recommend you to check out `aiken-vesting/aiken-workspace/validators/tests/vesting.ak` to learn more. + +## Compile and build script + +To compile the script, run the following command: + +```sh +aiken build +``` + +This command will generate a CIP-0057 Plutus blueprint, which you can find in `aiken-vesting/aiken-workspace/plutus.json`. + +## Off-Chain code + +### Deposit funds + +First, the owner can deposit funds into the vesting contract. The owner can specify the lockup period and the beneficiary of the funds. + +```ts +const assets: Asset[] = [ + { + unit: "lovelace", + quantity: "10000000", + }, +]; + +const lockUntilTimeStamp = new Date(); +lockUntilTimeStamp.setMinutes(lockUntilTimeStamp.getMinutes() + 1); + +const beneficiary = + "addr_test1qpvx0sacufuypa2k4sngk7q40zc5c4npl337uusdh64kv0uafhxhu32dys6pvn6wlw8dav6cmp4pmtv7cc3yel9uu0nq93swx9"; +``` + +In this example, we deposit 10 ADA into the vesting contract. The funds are locked up for 1 minute, and the beneficiary is specified. + +Then, we prepare a few variables to be used in the transaction. We get the wallet address and the UTXOs of the wallet. We also get the script address of the vesting contract, to send the funds to the script address. We also get the owner and beneficiary public key hashes. + +```ts +const { utxos, walletAddress } = await getWalletInfoForTx(); + +const { scriptAddr } = getScript(); + +const { pubKeyHash: ownerPubKeyHash } = deserializeAddress(walletAddress); +const { pubKeyHash: beneficiaryPubKeyHash } = deserializeAddress(beneficiary); +``` + +Next, we construct the transaction to deposit the funds into the vesting contract. + +```ts +const txBuilder = new MeshTxBuilder({ + fetcher: blockchainProvider, + submitter: blockchainProvider, +}); + +await txBuilder + .txOut(scriptAddr, amount) + .txOutInlineDatumValue( + mConStr0([lockUntilTimeStampMs, ownerPubKeyHash, beneficiaryPubKeyHash]) + ) + .changeAddress(walletAddress) + .selectUtxosFrom(utxos) + .complete(); + +const unsignedTx = txBuilder.txHex; +``` + +In this example, we construct the transaction to deposit the funds into the vesting contract. We specify the script address of the vesting contract, the amount to deposit, and the lockup period, owner, and beneficiary of the funds. + +Finally, we sign and submit the transaction. + +```ts +const signedTx = await wallet.signTx(unsignedTx); +const txHash = await wallet.submitTx(signedTx); +``` + +To execute this code, ensure you have defined blockfrost key in the `.env` file. You can also define your wallet mnemonic in `aiken-vesting/src/configs.ts` file. + +You can run the following command execute the deposit funds code: + +```sh +npm run deposit +``` + +Upon successful execution, you will receive a transaction hash. Save this transaction hash for withdrawing the funds. + +Example of a [successful deposit transaction](https://preprod.cardanoscan.io/transaction/ede9f8176fe41f0c84cfc9802b693dedb5500c0cbe4377b7bb0d57cf0435200b). + +### Withdraw funds + +After the lockup period expires, the beneficiary can withdraw the funds from the vesting contract. The owner can also withdraw the funds from the vesting contract. + +First, let's look for the UTxOs containing the funds locked in the vesting contract. + +```ts +const txHashFromDesposit = + "ede9f8176fe41f0c84cfc9802b693dedb5500c0cbe4377b7bb0d57cf0435200b"; +const utxos = await blockchainProvider.fetchUTxOs(txHash); +const vestingUtxo = utxos[0]; +``` + +In this example, we fetch the UTxOs containing the funds locked in the vesting contract. We specify the transaction hash of the deposit transaction. + +Like before, we prepare a few variables to be used in the transaction. We get the wallet address and the UTXOs of the wallet. We also get the script address of the vesting contract, to send the funds to the script address. We also get the owner and beneficiary public key hashes. + +```ts +const { utxos, walletAddress, collateral } = await getWalletInfoForTx(); +const { input: collateralInput, output: collateralOutput } = collateral; + +const { scriptAddr, scriptCbor } = getScript(); +const { pubKeyHash } = deserializeAddress(walletAddress); +``` + +Next, we prepare the datum and the slot number to set the transaction valid interval to be valid only after the slot. + +```ts +const datum = deserializeDatum(vestingUtxo.output.plutusData!); + +const invalidBefore = + unixTimeToEnclosingSlot( + Math.min(datum.fields[0].int as number, Date.now() - 15000), + SLOT_CONFIG_NETWORK.preprod + ) + 1; +``` + +In this example, we prepare the datum and the slot number to set the transaction valid interval to be valid only after the slot. We get the lockup period from the datum and set the transaction valid interval to be valid only after the lockup period. + +Next, we construct the transaction to withdraw the funds from the vesting contract. + +```ts +const txBuilder = new MeshTxBuilder({ + fetcher: blockchainProvider, + submitter: blockchainProvider, +}); + +await txBuilder + .spendingPlutusScriptV2() + .txIn( + vestingUtxo.input.txHash, + vestingUtxo.input.outputIndex, + vestingUtxo.output.amount, + scriptAddr + ) + .spendingReferenceTxInInlineDatumPresent() + .spendingReferenceTxInRedeemerValue("") + .txInScript(scriptCbor) + .txOut(walletAddress, []) + .txInCollateral( + collateralInput.txHash, + collateralInput.outputIndex, + collateralOutput.amount, + collateralOutput.address + ) + .invalidBefore(invalidBefore) + .requiredSignerHash(pubKeyHash) + .changeAddress(walletAddress) + .selectUtxosFrom(utxos) + .complete(); + +const unsignedTx = txBuilder.txHex; +``` + +In this example, we construct the transaction to withdraw the funds from the vesting contract. We specify the UTxO containing the funds locked in the vesting contract, the script address of the vesting contract, the wallet address to send the funds to, and the transaction valid interval. + +Finally, we sign and submit the transaction. Notice that since we are unlocking fund from validator, partial sign has to be specified by passing a `true` parameter into `wallet.signTx`. + +```ts +const signedTx = await wallet.signTx(unsignedTx, true); +const txHash = await wallet.submitTx(signedTx); +``` + +To execute this code, update `aiken-vesting/src/withdraw-fund.ts` with the transaction hash from the deposit transaction. Ensure you have defined blockfrost key in the `.env` file. You can also define your wallet mnemonic in `aiken-vesting/src/configs.ts` file. + +Run the following command: + +```sh +npm run withdraw +``` + +Example of a [successful withdraw transaction](https://preprod.cardanoscan.io/transaction/b108f91a1dcd1b4c0bc978fb7557fc23ad052f1681cca078aa2515f8ab01e05e). \ No newline at end of file diff --git a/apps/playground/src/pages/smart-contracts/vesting/deposit-fund.tsx b/apps/playground/src/pages/smart-contracts/vesting/deposit-fund.tsx index 4a48f437..549440d1 100644 --- a/apps/playground/src/pages/smart-contracts/vesting/deposit-fund.tsx +++ b/apps/playground/src/pages/smart-contracts/vesting/deposit-fund.tsx @@ -16,7 +16,7 @@ export default function VestingDepositFund() { sidebarTo="depositFund" title="Deposit Fund" leftSection={Left()} - rightSection={Right()} + rightSection={VestingDepositFundDemo()} /> ); } @@ -41,7 +41,7 @@ function Left() { ); } -function Right() { +export function VestingDepositFundDemo() { const { wallet, connected } = useWallet(); const [userInput, setUserInput] = useState("5000000"); const [userInput2, setUserInput2] = useState(demoAddresses.testnet); diff --git a/apps/playground/src/pages/smart-contracts/vesting/withdraw-fund.tsx b/apps/playground/src/pages/smart-contracts/vesting/withdraw-fund.tsx index a8675786..1f4e29f3 100644 --- a/apps/playground/src/pages/smart-contracts/vesting/withdraw-fund.tsx +++ b/apps/playground/src/pages/smart-contracts/vesting/withdraw-fund.tsx @@ -14,7 +14,7 @@ export default function VestingWithdrawFund() { sidebarTo="withdrawFund" title="Withdraw Fund" leftSection={Left()} - rightSection={Right()} + rightSection={VestingWithdrawFundDemo()} /> ); } @@ -39,7 +39,7 @@ function Left() { ); } -function Right() { +export function VestingWithdrawFundDemo() { const { wallet, connected } = useWallet(); const [userInput, setUserInput] = useState(""); diff --git a/apps/playground/src/pages/yaci/getting-started/hosted.tsx b/apps/playground/src/pages/yaci/getting-started/hosted.tsx new file mode 100644 index 00000000..4ad130de --- /dev/null +++ b/apps/playground/src/pages/yaci/getting-started/hosted.tsx @@ -0,0 +1,46 @@ +import Link from "~/components/link"; +import TwoColumnsScroll from "~/components/sections/two-columns-scroll"; +import Codeblock from "~/components/text/codeblock"; + +export default function YaciHosted() { + return ( + + ); +} + +function Left() { + let code = ""; + code += `import { YaciProvider } from "@meshsdk/core";\n`; + code += `\n`; + code += `const blockchainProvider = new YaciProvider();\n`; + code += `const params = await blockchainProvider.fetchProtocolParameters();\n`; + code += `console.log(params);\n`; + + return ( + <> +

    Connect right away with Yaci Provider

    +

    + Mesh has a hosted Yaci Devnet that you can connect to right away. You + can use the following URL to connect to the hosted Yaci Devnet: +

    + +

    Import Yaci Provider

    +

    + Import YaciProvider and start using it to interact with the + Yaci Devnet. +

    + +

    + + Learn more about Yaci Provider + {" "} + and learn more about{" "} + hosted Yaci Devnet +

    + + ); +} diff --git a/apps/playground/src/pages/yaci/getting-started/index.tsx b/apps/playground/src/pages/yaci/getting-started/index.tsx index 33d0c61f..028fda42 100644 --- a/apps/playground/src/pages/yaci/getting-started/index.tsx +++ b/apps/playground/src/pages/yaci/getting-started/index.tsx @@ -6,6 +6,7 @@ import Metatags from "~/components/site/metatags"; import { metaYaciGettingStarted } from "~/data/links-yaci"; import { getPageLinks } from "../common"; import YaciCommands from "./commands"; +import YaciHosted from "./hosted"; import YaciSetup from "./setup"; import YaciStart from "./start"; @@ -24,6 +25,7 @@ const ReactPage: NextPage = () => { <> + diff --git a/apps/playground/src/pages/yaci/transactions/basic-transaction.tsx b/apps/playground/src/pages/yaci/transactions/basic-transaction.tsx index 4bb95558..0b79a3b6 100644 --- a/apps/playground/src/pages/yaci/transactions/basic-transaction.tsx +++ b/apps/playground/src/pages/yaci/transactions/basic-transaction.tsx @@ -68,7 +68,7 @@ function Left() { function Right() { const [userInput, setUserInput] = useState(yaci.address); const [userInput2, setUserInput2] = useState( - "http://localhost:8080/api/v1/", + "https://yaci-node.meshjs.dev/api/v1/", ); async function runDemo() { diff --git a/apps/playground/src/pages/yaci/transactions/provider.tsx b/apps/playground/src/pages/yaci/transactions/provider.tsx index a692f0e7..75bbbf6e 100644 --- a/apps/playground/src/pages/yaci/transactions/provider.tsx +++ b/apps/playground/src/pages/yaci/transactions/provider.tsx @@ -31,7 +31,7 @@ function Left() { />

    By default, the YaciProvider will use the default URL,{" "} - http://localhost:8080/api/v1/. If you want to use a custom + https://yaci-node.meshjs.dev/api/v1/. If you want to use a custom URL, you can pass it as a parameter.

    @@ -54,7 +54,7 @@ function Right() { demoAddresses.testnetPayment, ); const [userInput2, setUserInput2] = useState( - "http://localhost:8080/api/v1/", + "https://yaci-node.meshjs.dev/api/v1/", ); async function runDemo() { diff --git a/package-lock.json b/package-lock.json index e72935cf..c277b7ce 100644 --- a/package-lock.json +++ b/package-lock.json @@ -6857,14 +6857,14 @@ } }, "node_modules/@sidan-lab/sidan-csl-rs-browser": { - "version": "0.7.5", - "resolved": "https://registry.npmjs.org/@sidan-lab/sidan-csl-rs-browser/-/sidan-csl-rs-browser-0.7.5.tgz", - "integrity": "sha512-ME/n158D65IpnOOkQS5XCyoRc77FiHknYaMwrzosE3ziu5qXWJ7gkkQ3K1DdHFfLATwZfcKVUC/sUvTjFAmbnQ==" + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/@sidan-lab/sidan-csl-rs-browser/-/sidan-csl-rs-browser-0.8.0.tgz", + "integrity": "sha512-U3Qj9NOdqHR/sMBc3MVoMCZ2EodOZGBZQYJqErn52qJeDQA/ySqjKKL2ql3s+7UVNUiQw+Qj3ZjdxCN2UxV4nw==" }, "node_modules/@sidan-lab/sidan-csl-rs-nodejs": { - "version": "0.7.5", - "resolved": "https://registry.npmjs.org/@sidan-lab/sidan-csl-rs-nodejs/-/sidan-csl-rs-nodejs-0.7.5.tgz", - "integrity": "sha512-8IC7WsbrWrq/z/isvh/ceJljNuMOhPJSoRXuZO6GpKm0YLVShy6qWHzJ9JFsrTelWaAfElw4FsZjmZ6N9f5TGQ==" + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/@sidan-lab/sidan-csl-rs-nodejs/-/sidan-csl-rs-nodejs-0.8.0.tgz", + "integrity": "sha512-bIinZwje1a79tmnsQq22AmZCl1H13uxlGtCsLN+9SCY0IiWI+jVhWVceaHoiyL6dYvLrQh+GbecfeZiMg90UJQ==" }, "node_modules/@sinclair/typebox": { "version": "0.27.8", @@ -9334,6 +9334,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", @@ -12665,7 +12666,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", @@ -15506,6 +15508,7 @@ "version": "4.2.8", "resolved": "https://registry.npmjs.org/minipass/-/minipass-4.2.8.tgz", "integrity": "sha512-fNzuVyifolSLFL4NzpF+wEF4qrgqaaKX0haXPQEdQ7NKAN+WecoKMHV09YcuL/DHxrUsYQOK3MiuDf7Ip2OXfQ==", + "dev": true, "engines": { "node": ">=8" } @@ -15736,6 +15739,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", @@ -15747,6 +15751,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" } @@ -20106,6 +20111,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" @@ -20114,12 +20120,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" @@ -20128,7 +20136,8 @@ "node_modules/spdx-license-ids": { "version": "3.0.20", "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.20.tgz", - "integrity": "sha512-jg25NiDV/1fLtSgEgyvVyDunvaNHbuwF9lfNV17gSmPFAlYzdfNBlLtLzXTevwkPj7DhGbmN9VnmJIgLnhvaBw==" + "integrity": "sha512-jg25NiDV/1fLtSgEgyvVyDunvaNHbuwF9lfNV17gSmPFAlYzdfNBlLtLzXTevwkPj7DhGbmN9VnmJIgLnhvaBw==", + "dev": true }, "node_modules/split-ca": { "version": "1.0.1", @@ -21795,6 +21804,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" @@ -22148,6 +22158,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" @@ -22159,7 +22170,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", @@ -22352,7 +22364,7 @@ }, "packages/mesh-common": { "name": "@meshsdk/common", - "version": "1.6.13", + "version": "1.6.14", "license": "Apache-2.0", "dependencies": { "bech32": "^2.0.0", @@ -22369,14 +22381,14 @@ }, "packages/mesh-contract": { "name": "@meshsdk/contract", - "version": "1.6.13", + "version": "1.6.14", "license": "Apache-2.0", "dependencies": { - "@meshsdk/common": "*", - "@meshsdk/core": "*", - "@meshsdk/core-csl": "*", - "@meshsdk/core-cst": "*", - "@meshsdk/transaction": "*" + "@meshsdk/common": "1.6.14", + "@meshsdk/core": "1.6.14", + "@meshsdk/core-csl": "1.6.14", + "@meshsdk/core-cst": "1.6.14", + "@meshsdk/transaction": "1.6.14" }, "devDependencies": { "@meshsdk/configs": "*", @@ -22387,16 +22399,16 @@ }, "packages/mesh-core": { "name": "@meshsdk/core", - "version": "1.6.13", + "version": "1.6.14", "license": "Apache-2.0", "dependencies": { - "@meshsdk/common": "*", - "@meshsdk/core-csl": "*", - "@meshsdk/core-cst": "*", - "@meshsdk/provider": "*", - "@meshsdk/react": "*", - "@meshsdk/transaction": "*", - "@meshsdk/wallet": "*" + "@meshsdk/common": "1.6.14", + "@meshsdk/core-csl": "1.6.14", + "@meshsdk/core-cst": "1.6.14", + "@meshsdk/provider": "1.6.14", + "@meshsdk/react": "1.6.14", + "@meshsdk/transaction": "1.6.14", + "@meshsdk/wallet": "1.6.14" }, "devDependencies": { "@meshsdk/configs": "*", @@ -22407,12 +22419,12 @@ }, "packages/mesh-core-csl": { "name": "@meshsdk/core-csl", - "version": "1.6.13", + "version": "1.6.14", "license": "Apache-2.0", "dependencies": { - "@meshsdk/common": "*", - "@sidan-lab/sidan-csl-rs-browser": "0.7.5", - "@sidan-lab/sidan-csl-rs-nodejs": "0.7.5", + "@meshsdk/common": "1.6.14", + "@sidan-lab/sidan-csl-rs-browser": "0.8.0", + "@sidan-lab/sidan-csl-rs-nodejs": "0.8.0", "json-bigint": "^1.0.0" }, "devDependencies": { @@ -22426,7 +22438,7 @@ }, "packages/mesh-core-cst": { "name": "@meshsdk/core-cst", - "version": "1.6.13", + "version": "1.6.14", "license": "Apache-2.0", "dependencies": { "@cardano-sdk/core": "^0.35.4", @@ -22435,7 +22447,7 @@ "@harmoniclabs/cbor": "1.3.0", "@harmoniclabs/plutus-data": "1.2.4", "@harmoniclabs/uplc": "1.2.4", - "@meshsdk/common": "*", + "@meshsdk/common": "1.6.14", "@stricahq/bip32ed25519": "^1.1.0", "@stricahq/cbors": "^1.0.0", "pbkdf2": "^3.1.2" @@ -22452,11 +22464,11 @@ }, "packages/mesh-provider": { "name": "@meshsdk/provider", - "version": "1.6.13", + "version": "1.6.14", "license": "Apache-2.0", "dependencies": { - "@meshsdk/common": "*", - "@meshsdk/core-cst": "*", + "@meshsdk/common": "1.6.14", + "@meshsdk/core-cst": "1.6.14", "axios": "^1.7.2" }, "devDependencies": { @@ -22468,12 +22480,12 @@ }, "packages/mesh-react": { "name": "@meshsdk/react", - "version": "1.6.13", + "version": "1.6.14", "license": "Apache-2.0", "dependencies": { - "@meshsdk/common": "*", - "@meshsdk/transaction": "*", - "@meshsdk/wallet": "*", + "@meshsdk/common": "1.6.14", + "@meshsdk/transaction": "1.6.14", + "@meshsdk/wallet": "1.6.14", "react": "^18.2.0" }, "devDependencies": { @@ -22488,12 +22500,12 @@ }, "packages/mesh-transaction": { "name": "@meshsdk/transaction", - "version": "1.6.13", + "version": "1.6.14", "license": "Apache-2.0", "dependencies": { - "@meshsdk/common": "*", - "@meshsdk/core-csl": "*", - "@meshsdk/core-cst": "*", + "@meshsdk/common": "1.6.14", + "@meshsdk/core-csl": "1.6.14", + "@meshsdk/core-cst": "1.6.14", "json-bigint": "^1.0.0" }, "devDependencies": { @@ -22506,13 +22518,13 @@ }, "packages/mesh-wallet": { "name": "@meshsdk/wallet", - "version": "1.6.13", + "version": "1.6.14", "license": "Apache-2.0", "dependencies": { - "@meshsdk/common": "*", - "@meshsdk/core-csl": "*", - "@meshsdk/core-cst": "*", - "@meshsdk/transaction": "*", + "@meshsdk/common": "1.6.14", + "@meshsdk/core-csl": "1.6.14", + "@meshsdk/core-cst": "1.6.14", + "@meshsdk/transaction": "1.6.14", "@nufi/dapp-client-cardano": "^0.3.1", "@nufi/dapp-client-core": "^0.3.1" }, @@ -22526,7 +22538,7 @@ }, "scripts/mesh-cli": { "name": "meshjs", - "version": "1.6.13", + "version": "1.6.14", "license": "Apache-2.0", "dependencies": { "chalk": "5.3.0", diff --git a/packages/mesh-common/package.json b/packages/mesh-common/package.json index 46465204..92ed88a4 100644 --- a/packages/mesh-common/package.json +++ b/packages/mesh-common/package.json @@ -1,6 +1,6 @@ { "name": "@meshsdk/common", - "version": "1.6.13", + "version": "1.7.0", "description": "", "main": "./dist/index.cjs", "module": "./dist/index.js", diff --git a/packages/mesh-common/src/types/transaction-builder/output.ts b/packages/mesh-common/src/types/transaction-builder/output.ts index 1772d1ce..c58959b6 100644 --- a/packages/mesh-common/src/types/transaction-builder/output.ts +++ b/packages/mesh-common/src/types/transaction-builder/output.ts @@ -5,7 +5,7 @@ export type Output = { address: string; amount: Asset[]; datum?: { - type: "Hash" | "Inline"; + type: "Hash" | "Inline" | "Embedded"; data: BuilderData; }; referenceScript?: PlutusScript; diff --git a/packages/mesh-contract/package.json b/packages/mesh-contract/package.json index a4119d74..fb6d0586 100644 --- a/packages/mesh-contract/package.json +++ b/packages/mesh-contract/package.json @@ -1,6 +1,6 @@ { "name": "@meshsdk/contract", - "version": "1.6.13", + "version": "1.7.0", "description": "", "main": "./dist/index.cjs", "module": "./dist/index.js", @@ -33,11 +33,11 @@ "typescript": "^5.3.3" }, "dependencies": { - "@meshsdk/common": "*", - "@meshsdk/core": "*", - "@meshsdk/core-csl": "*", - "@meshsdk/core-cst": "*", - "@meshsdk/transaction": "*" + "@meshsdk/common": "1.7.0", + "@meshsdk/core": "1.7.0", + "@meshsdk/core-csl": "1.7.0", + "@meshsdk/core-cst": "1.7.0", + "@meshsdk/transaction": "1.7.0" }, "prettier": "@meshsdk/configs/prettier", "publishConfig": { diff --git a/packages/mesh-core-csl/package.json b/packages/mesh-core-csl/package.json index 2ccc53f9..5f6f49a6 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.13", + "version": "1.7.0", "description": "", "main": "./dist/index.cjs", "module": "./dist/index.js", @@ -38,9 +38,9 @@ "typescript": "^5.3.3" }, "dependencies": { - "@meshsdk/common": "*", - "@sidan-lab/sidan-csl-rs-browser": "0.7.5", - "@sidan-lab/sidan-csl-rs-nodejs": "0.7.5", + "@meshsdk/common": "1.7.0", + "@sidan-lab/sidan-csl-rs-browser": "0.8.0", + "@sidan-lab/sidan-csl-rs-nodejs": "0.8.0", "json-bigint": "^1.0.0" }, "prettier": "@meshsdk/configs/prettier", diff --git a/packages/mesh-core-csl/src/core/adaptor/output.ts b/packages/mesh-core-csl/src/core/adaptor/output.ts index 7866ae06..733e82ba 100644 --- a/packages/mesh-core-csl/src/core/adaptor/output.ts +++ b/packages/mesh-core-csl/src/core/adaptor/output.ts @@ -12,6 +12,9 @@ export const outputToObj = (output: Output): object => { case "Hash": datum = { hash: builderDataToCbor(output.datum.data) }; break; + case "Embedded": + datum = { embedded: builderDataToCbor(output.datum.data) }; + break; } } diff --git a/packages/mesh-core-cst/package.json b/packages/mesh-core-cst/package.json index 10039cc7..c25426ad 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.13", + "version": "1.7.0", "description": "", "main": "./dist/index.cjs", "module": "./dist/index.js", @@ -41,7 +41,7 @@ "@harmoniclabs/cbor": "1.3.0", "@harmoniclabs/plutus-data": "1.2.4", "@harmoniclabs/uplc": "1.2.4", - "@meshsdk/common": "*", + "@meshsdk/common": "1.7.0", "@stricahq/bip32ed25519": "^1.1.0", "@stricahq/cbors": "^1.0.0", "pbkdf2": "^3.1.2" diff --git a/packages/mesh-core/package.json b/packages/mesh-core/package.json index 449e3518..3d1b4642 100644 --- a/packages/mesh-core/package.json +++ b/packages/mesh-core/package.json @@ -1,6 +1,6 @@ { "name": "@meshsdk/core", - "version": "1.6.13", + "version": "1.7.0", "description": "", "main": "./dist/index.cjs", "module": "./dist/index.js", @@ -32,13 +32,13 @@ "typescript": "^5.3.3" }, "dependencies": { - "@meshsdk/common": "*", - "@meshsdk/core-csl": "*", - "@meshsdk/core-cst": "*", - "@meshsdk/provider": "*", - "@meshsdk/react": "*", - "@meshsdk/transaction": "*", - "@meshsdk/wallet": "*" + "@meshsdk/common": "1.7.0", + "@meshsdk/core-csl": "1.7.0", + "@meshsdk/core-cst": "1.7.0", + "@meshsdk/provider": "1.7.0", + "@meshsdk/react": "1.7.0", + "@meshsdk/transaction": "1.7.0", + "@meshsdk/wallet": "1.7.0" }, "prettier": "@meshsdk/configs/prettier", "publishConfig": { diff --git a/packages/mesh-provider/package.json b/packages/mesh-provider/package.json index ccdad98f..31ff9999 100644 --- a/packages/mesh-provider/package.json +++ b/packages/mesh-provider/package.json @@ -1,6 +1,6 @@ { "name": "@meshsdk/provider", - "version": "1.6.13", + "version": "1.7.0", "description": "", "main": "./dist/index.cjs", "module": "./dist/index.js", @@ -33,8 +33,8 @@ "typescript": "^5.3.3" }, "dependencies": { - "@meshsdk/common": "*", - "@meshsdk/core-cst": "*", + "@meshsdk/common": "1.7.0", + "@meshsdk/core-cst": "1.7.0", "axios": "^1.7.2" }, "prettier": "@meshsdk/configs/prettier", diff --git a/packages/mesh-provider/src/yaci.ts b/packages/mesh-provider/src/yaci.ts index 044d7986..ae2d779e 100644 --- a/packages/mesh-provider/src/yaci.ts +++ b/packages/mesh-provider/src/yaci.ts @@ -35,7 +35,7 @@ export class YaciProvider * Set the URL of the instance. * @param baseUrl The base URL of the instance. */ - constructor(baseUrl = "http://localhost:8080/api/v1/") { + constructor(baseUrl = "https://yaci-node.meshjs.dev/api/v1/") { this._axiosInstance = axios.create({ baseURL: baseUrl, }); diff --git a/packages/mesh-provider/test/yaci/evaluator.test.ts b/packages/mesh-provider/test/yaci/evaluator.test.ts index 2e0a90d5..b628a2ec 100644 --- a/packages/mesh-provider/test/yaci/evaluator.test.ts +++ b/packages/mesh-provider/test/yaci/evaluator.test.ts @@ -1,6 +1,6 @@ import { YaciProvider } from "@meshsdk/provider"; -const provider = new YaciProvider("http://localhost:8080/api/v1/"); +const provider = new YaciProvider("https://yaci-node.meshjs.dev/api/v1/"); const successTx = "84a60081825820ab11b83c9d46edf3e4f0124eccaec9c3469c4aa8bba47885991ea33f76f92d32000182825839005867c3b8e27840f556ac268b781578b14c5661fc63ee720dbeab663f9d4dcd7e454d2434164f4efb8edeb358d86a1dad9ec6224cfcbce3e6821a00111958a1581c9026ea35a0b0ca28e304ef94cc5a31c9e850db14a32dc3c69969fe83a14001825839005867c3b8e27840f556ac268b781578b14c5661fc63ee720dbeab663f9d4dcd7e454d2434164f4efb8edeb358d86a1dad9ec6224cfcbce3e61a3b89b0a8020009a1581c9026ea35a0b0ca28e304ef94cc5a31c9e850db14a32dc3c69969fe83a140010b5820df2de8c102f948422412af199867e5d472b9ff700473b2841e63209041b0e7df0d81825820ab11b83c9d46edf3e4f0124eccaec9c3469c4aa8bba47885991ea33f76f92d3200a20681590288590285010000332323232323232323232223232322533300832323232533300c3007300e3754002264a66601a6010601e6ea802454ccc034c020c03cdd519198008009bac30143011375400844a666026002298103d87a80001323253330113375e01e601260286ea80084cdd2a40006602c00497ae01330040040013017002301500114a229404c8cc004004c8cc004004c8cc004004dd5980b180b980b980b980b98099baa00622533301500114bd6f7b630099191919299980a99b9148900002153330153371e9101000021003100513301a337606ea4008dd3000998030030019bab3017003375c602a0046032004602e00244a666028002297ae0132333222323300100100322533301a00110031323301c374e660386ea4018cc070c064004cc070c0680052f5c066006006603c00460380026eb8c04c004dd5980a00099801801980c001180b0009129998098008a5113253330103253330113371e6eb8c0240040144cdc41bad301730183018001480005289bac301600213300300300114a0602c0026eb8c048c03cdd50008a50301130120023010001300c37540044601e0022930a99804a491856616c696461746f722072657475726e65642066616c7365001365632533300730020011533300b300a37540062930a998040030b0a99980399b874800800454ccc02cc028dd50018a4c2a6601000c2c2a6601000c2c60106ea8008dc3a4000a66666601800220022a6600a0062c2a6600a0062c2a6600a0062c2a6600a0062c92011672656465656d65723a204d696e74506f6c6172697479005734ae7155ceaab9e5573eae815d0aba257489812bd8799fd8799f5820ab11b83c9d46edf3e4f0124eccaec9c3469c4aa8bba47885991ea33f76f92d32ff00ff00010581840100d87980821a006acfc01ab2d05e00f5f6"; diff --git a/packages/mesh-react/package.json b/packages/mesh-react/package.json index 54984a53..5cd6c872 100644 --- a/packages/mesh-react/package.json +++ b/packages/mesh-react/package.json @@ -1,6 +1,6 @@ { "name": "@meshsdk/react", - "version": "1.6.13", + "version": "1.7.0", "description": "", "main": "./dist/index.cjs", "module": "./dist/index.js", @@ -29,9 +29,9 @@ }, "dependencies": { "react": "^18.2.0", - "@meshsdk/common": "*", - "@meshsdk/transaction": "*", - "@meshsdk/wallet": "*" + "@meshsdk/common": "1.7.0", + "@meshsdk/transaction": "1.7.0", + "@meshsdk/wallet": "1.7.0" }, "devDependencies": { "@meshsdk/configs": "*", diff --git a/packages/mesh-transaction/package.json b/packages/mesh-transaction/package.json index 97c56bf9..94e33376 100644 --- a/packages/mesh-transaction/package.json +++ b/packages/mesh-transaction/package.json @@ -1,6 +1,6 @@ { "name": "@meshsdk/transaction", - "version": "1.6.13", + "version": "1.7.0", "description": "", "main": "./dist/index.cjs", "module": "./dist/index.js", @@ -34,9 +34,9 @@ "typescript": "^5.3.3" }, "dependencies": { - "@meshsdk/common": "*", - "@meshsdk/core-csl": "*", - "@meshsdk/core-cst": "*", + "@meshsdk/common": "1.7.0", + "@meshsdk/core-csl": "1.7.0", + "@meshsdk/core-cst": "1.7.0", "json-bigint": "^1.0.0" }, "prettier": "@meshsdk/configs/prettier", diff --git a/packages/mesh-transaction/src/mesh-tx-builder/tx-builder-core.ts b/packages/mesh-transaction/src/mesh-tx-builder/tx-builder-core.ts index d2e4c882..ccd9032f 100644 --- a/packages/mesh-transaction/src/mesh-tx-builder/tx-builder-core.ts +++ b/packages/mesh-transaction/src/mesh-tx-builder/tx-builder-core.ts @@ -346,6 +346,43 @@ export class MeshTxBuilderCore { return this; }; + /** + * Set the output embed datum for transaction + * @param datum The datum in Mesh Data type, JSON in raw constructor like format, or CBOR hex string + * @param type The datum type, either Mesh Data type, JSON in raw constructor like format, or CBOR hex string + * @returns The MeshTxBuilder instance + */ + + txOutDatumEmbedValue = ( + datum: BuilderData["content"], + type: BuilderData["type"] = "Mesh", + ) => { + let content = datum; + if (this.txOutput) { + if (type === "Mesh") { + this.txOutput.datum = { + type: "Embedded", + data: { + type, + content: content as Data, + }, + }; + return this; + } + if (type === "JSON") { + content = this.castRawDataToJsonString(datum as object | string); + } + this.txOutput.datum = { + type: "Embedded", + data: { + type, + content: content as string, + }, + }; + } + return this; + }; + /** * Set the reference script to be attached with the output * @param scriptCbor The CBOR hex of the script to be attached to UTxO as reference script diff --git a/packages/mesh-transaction/test/mesh-tx-builder/tx.test.ts b/packages/mesh-transaction/test/mesh-tx-builder/tx.test.ts new file mode 100644 index 00000000..8361843b --- /dev/null +++ b/packages/mesh-transaction/test/mesh-tx-builder/tx.test.ts @@ -0,0 +1,32 @@ +import { MeshTxBuilder } from "@meshsdk/transaction"; + +describe("MeshTxBuilder transactions", () => { + it("Adding embedded datum should produce correct tx cbor", () => { + let mesh = new MeshTxBuilder({ verbose: true }); + + let txHex = mesh + .txIn( + "2cb57168ee66b68bd04a0d595060b546edf30c04ae1031b883c9ac797967dd85", + 3, + [{ unit: "lovelace", quantity: "9891607895" }], + "addr_test1vru4e2un2tq50q4rv6qzk7t8w34gjdtw3y2uzuqxzj0ldrqqactxh", + ) + .txOut( + "addr_test1vru4e2un2tq50q4rv6qzk7t8w34gjdtw3y2uzuqxzj0ldrqqactxh", + [{ unit: "lovelace", quantity: "2000000" }], + ) + .txOutDatumEmbedValue( + { + constructor: 0, + fields: [], + }, + "JSON", + ) + .changeAddress( + "addr_test1vru4e2un2tq50q4rv6qzk7t8w34gjdtw3y2uzuqxzj0ldrqqactxh", + ) + .completeSync(); + + expect(txHex).toBe("84a400818258202cb57168ee66b68bd04a0d595060b546edf30c04ae1031b883c9ac797967dd8503018283581d60f95cab9352c14782a366802b7967746a89356e8915c17006149ff68c1a001e84805820923918e403bf43c34b4ef6b48eb2ee04babed17320d8d1b9ff9ad086e86f44ec82581d60f95cab9352c14782a366802b7967746a89356e8915c17006149ff68c1b000000024d74dc6e021a000294690b582015dd0a3ac1244430aacc7e95c2734b51f1a8cf2aaf05e5d6e8124cb78ab54cc9a1049fd87980fff5f6"); + }); +}); diff --git a/packages/mesh-transaction/test/transaction/sendAssets.test.ts b/packages/mesh-transaction/test/transaction/sendAssets.test.ts new file mode 100644 index 00000000..e9613bb7 --- /dev/null +++ b/packages/mesh-transaction/test/transaction/sendAssets.test.ts @@ -0,0 +1,84 @@ +import { Asset, Recipient } from "@meshsdk/common"; +import { MeshTxBuilder, Transaction } from "@meshsdk/transaction"; +import { MeshWallet } from "@meshsdk/wallet"; + +jest.mock("@meshsdk/transaction", () => { + const txBuilderMock = { + txOut: jest.fn(), + txOutDatumHashValue: jest.fn(), + txOutInlineDatumValue: jest.fn(), + }; + + return { + MeshTxBuilder: jest.fn(() => txBuilderMock), + Transaction: jest.requireActual("@meshsdk/transaction").Transaction, + }; +}); + +describe("Transaction", () => { + let wallet: MeshWallet; + let transaction: Transaction; + let txBuilderMock: jest.Mocked; + + beforeEach(() => { + wallet = new MeshWallet({ + key: { + type: "mnemonic", + words: MeshWallet.brew() as string[], + }, + networkId: 0, + }); + txBuilderMock = new MeshTxBuilder({}) as jest.Mocked; + transaction = new Transaction({ + initiator: wallet, + }); + transaction.txBuilder = txBuilderMock; + }); + + it("should trigger txOutDatumHashValue when recipient has datum with inline set to false", () => { + const address = wallet.getUsedAddresses()[0]; + const recipient: Recipient = { + address: address as string, + datum: { + inline: false, + value: "datum-value", + }, + }; + const assets: Asset[] = [ + { + unit: "lovelace", + quantity: "1000", + }, + ]; + + transaction.sendAssets(recipient, assets); + + expect(txBuilderMock.txOut).toHaveBeenCalledWith(address, assets); + expect(txBuilderMock.txOutDatumHashValue).toHaveBeenCalledWith( + "datum-value", + ); + }); + it("should trigger txOutInlineDatumValue when recipient has datum with inline set to false", () => { + const address = wallet.getUsedAddresses()[0]; + const recipient: Recipient = { + address: address as string, + datum: { + inline: true, + value: "datum-value", + }, + }; + const assets: Asset[] = [ + { + unit: "lovelace", + quantity: "1000", + }, + ]; + + transaction.sendAssets(recipient, assets); + + expect(txBuilderMock.txOut).toHaveBeenCalledWith(address, assets); + expect(txBuilderMock.txOutInlineDatumValue).toHaveBeenCalledWith( + "datum-value", + ); + }); +}); diff --git a/packages/mesh-wallet/package.json b/packages/mesh-wallet/package.json index 78cd7c80..61cc80a0 100644 --- a/packages/mesh-wallet/package.json +++ b/packages/mesh-wallet/package.json @@ -1,6 +1,6 @@ { "name": "@meshsdk/wallet", - "version": "1.6.13", + "version": "1.7.0", "description": "", "main": "./dist/index.cjs", "module": "./dist/index.js", @@ -34,10 +34,10 @@ "typescript": "^5.3.3" }, "dependencies": { - "@meshsdk/common": "*", - "@meshsdk/core-csl": "*", - "@meshsdk/core-cst": "*", - "@meshsdk/transaction": "*", + "@meshsdk/common": "1.7.0", + "@meshsdk/core-csl": "1.7.0", + "@meshsdk/core-cst": "1.7.0", + "@meshsdk/transaction": "1.7.0", "@nufi/dapp-client-cardano": "^0.3.1", "@nufi/dapp-client-core": "^0.3.1" }, diff --git a/scripts/bump-version.sh b/scripts/bump-version.sh index c1ecc3ae..32e90496 100644 --- a/scripts/bump-version.sh +++ b/scripts/bump-version.sh @@ -26,6 +26,18 @@ FILES=( for FILE in "${FILES[@]}"; do if [ -f "$FILE" ]; then sed -i '' -e "s/\"version\": \".*\"/\"version\": \"$VERSION\"/" "$FILE" + + # Update @meshsdk dependencies to the latest version + sed -i '' -e "s/\"@meshsdk\/common\": \".*\"/\"@meshsdk\/common\": \"$VERSION\"/" "$FILE" + sed -i '' -e "s/\"@meshsdk\/contract\": \".*\"/\"@meshsdk\/contract\": \"$VERSION\"/" "$FILE" + sed -i '' -e "s/\"@meshsdk\/core\": \".*\"/\"@meshsdk\/core\": \"$VERSION\"/" "$FILE" + sed -i '' -e "s/\"@meshsdk\/core-csl\": \".*\"/\"@meshsdk\/core-csl\": \"$VERSION\"/" "$FILE" + sed -i '' -e "s/\"@meshsdk\/core-cst\": \".*\"/\"@meshsdk\/core-cst\": \"$VERSION\"/" "$FILE" + sed -i '' -e "s/\"@meshsdk\/provider\": \".*\"/\"@meshsdk\/provider\": \"$VERSION\"/" "$FILE" + sed -i '' -e "s/\"@meshsdk\/react\": \".*\"/\"@meshsdk\/react\": \"$VERSION\"/" "$FILE" + sed -i '' -e "s/\"@meshsdk\/transaction\": \".*\"/\"@meshsdk\/transaction\": \"$VERSION\"/" "$FILE" + sed -i '' -e "s/\"@meshsdk\/wallet\": \".*\"/\"@meshsdk\/wallet\": \"$VERSION\"/" "$FILE" + echo "Updated version in $FILE" else echo "File not found: $FILE" diff --git a/scripts/mesh-cli/package.json b/scripts/mesh-cli/package.json index aac4e67b..f8c2225d 100644 --- a/scripts/mesh-cli/package.json +++ b/scripts/mesh-cli/package.json @@ -3,7 +3,7 @@ "description": "A quick and easy way to bootstrap your dApps on Cardano using Mesh.", "homepage": "https://meshjs.dev", "author": "MeshJS", - "version": "1.6.13", + "version": "1.7.0", "license": "Apache-2.0", "type": "module", "main": "./dist/index.cjs",