Lucid Documentation

repository·main·Indexed 18 days ago

https://github.com/spacebudz/lucid

A library for simplifying the creation of Cardano transactions and writing off-chain code for Plutus contracts. Lucid provides a high-level API for interacting with the Cardano blockchain, featuring wallet integration, CIP-0057 blueprint support, and portable JSON transaction instructions. It supports multiple providers including Blockfrost, Kupmios, and Maestro, and is compatible with Deno and Node.js.

Tokens
31K
Snippets
130
Records
153
Agent score
63%

What's inside Lucid

  1. What is Lucid?

    main

    Lucid is an off-chain framework for Cardano designed to simplify development by providing an abstraction layer over Cardano's infrastructure. It is built using JavaScript/TypeScript, allowing developers to leverage the existing JavaScript ecosystem.

    Key Capabilities:

    • Simplifies the process of building transactions that satisfy smart contract (validator) constraints.
    • Streamlines transaction management.
    • Provides tools for wallet management.
    • Enables developers to focus on dApp logic rather than low-level Cardano infrastructure.

    Important Distinctions:

    • Lucid is not a smart contract language.
    • Lucid is not a tool for creating validators (scripts).
    • Lucid is an off-chain component used to interact with validators and manage the state of the chain via transactions.
  2. How Plutus validators work in Lucid

    main

    On Cardano, you do not interact with 'smart contracts' directly; instead, you work with validators. A validator verifies whether a transaction meets specific requirements. If the requirements are met, the transaction succeeds; otherwise, it fails.

    To build and submit transactions involving validators, you must have a wallet and a provider selected in your Lucid instance.

  3. How CIP-0057 blueprints work with Lucid

    main

    Lucid supports CIP-0057 blueprints. You can generate TypeScript bindings for your Plutus contracts using the Lucid blueprint CLI tool.

    1. Run the blueprint command in a directory containing your plutus.json file:
    deno run -A https://deno.land/x/lucid/blueprint.ts
    1. This generates a plutus.ts file which you can import to interact with your validator.

    Example of minting with a generated validator:

    import { ValidateMint } from "./plutus.ts";
    
    const validator = new ValidateMint({ a: 123n, b: "0000" });
    const policyId = lucid.newScript(validator).toHash();
    
    const tx = await lucid
      .newTx()
      .mint(
        { [policyId]: 1n },
        Data.to({ a: 123n, b: "0000" }, ValidateMint.redeemer),
      )
      .attachScript(validator)
      .commit();
    deno run -A https://deno.land/x/lucid/blueprint.ts
  4. Build and submit a transaction with Lucid

    main

    To create, sign, and submit a transaction in Lucid, you follow a three-step lifecycle:

    1. Build: Use lucid.newTx() to initialize a transaction, chain .payTo(address, amount) calls for each recipient, and finish with .commit(). The .commit() call is required to balance the transaction and perform coin selection.
    2. Sign: Call .sign() on the transaction object and follow it with .commit() to finalize the signing process.
    3. Submit: Call .submit() on the signed transaction to broadcast it to the network, which returns the transaction hash.

    Note: Always ensure you call .commit() after building and after signing to ensure the transaction state is correctly finalized for the next step.

    import { Blockfrost, Lucid } from "https://deno.land/x/lucid/mod.ts";
    
    const lucid = new Lucid({
      provider: new Blockfrost(
        "https://cardano-preprod.blockfrost.io/api/v0",
        "<projectId>",
      ),
    });
    
    lucid.selectWalletFromPrivateKey(privateKey);
    
    // 1. Build
    const tx = await lucid.newTx()
      .payTo("addr_testa...", { lovelace: 5000000n })
      .payTo("addr_testb...", { lovelace: 5000000n })
      .commit();
    
    // 2. Sign
    const signedTx = await tx.sign().commit();
    
    // 3. Submit
    const txHash = await signedTx.submit();
    
    console.log(txHash);
  5. Install Lucid in Deno or Node.js

    main

    Deno

    You can import Lucid directly from JSR or via the Deno land URL:

    import { Lucid } from "jsr:@spacebudz/lucid";

    or

    import { Lucid } from "https://deno.land/x/lucid/mod.ts";

    Node.js

    Add the package using JSR:

    npx jsr add @spacebudz/lucid

    Note: If using Node.js, you must set the --experimental-wasm-modules flag and ensure your package.json contains { "type": "module" }.

    npx jsr add @spacebudz/lucid
  6. Burn native assets

    main

    Burning assets in Lucid is performed by using the .mint() method on a transaction with a negative quantity. The asset unit is constructed using the policyId and the token name. Like minting, the transaction must attach the relevant minting policy script.

    const unit = policyId + fromText("MyMintedToken");
    
    const tx = await lucid
      .newTx()
      .mint({ [unit]: -1n }) // Use a negative BigInt to burn
      .validTo(Date.now() + 200000)
      .attachScript(mintingPolicy)
      .commit();
    
    const signedTx = await tx.sign().commit();
    const txHash = await signedTx.submit();
  7. Import Lucid using NPM/Node.js

    main

    To use Lucid in a Node.js environment, ensure you have Node.js version 20 or higher installed.

    Lucid is an ES Module and utilizes WebAssembly. To use it in Node.js, you must:

    1. Set { "type": "module" } in your package.json.
    2. Run Node.js with the --experimental-wasm-modules flag.

    If you are using Webpack to bundle your project, you must enable asyncWebAssembly in your configuration.

    npm install lucid-cardano
    import { Lucid } from "lucid-cardano";
    
    const lucid = new Lucid();
    // webpack.config.json
    experiments: {
        "asyncWebAssembly": true,
      }
  8. Mint native assets

    main

    To mint native assets in Lucid, you must first define a minting policy script. This script defines the conditions under which tokens can be minted. Once the policy is defined, you derive a policyId using .toHash(). You then construct a transaction using .newTx(), specifying the asset unit (a combination of the policyId and a token name) and the quantity to mint. The transaction must include the minting policy via .attachScript().

    Note: You must have a wallet and a provider selected to build and submit transactions.

    import { Addresses } from "https://deno.land/x/lucid/mod.ts";
    
    // 1. Create a minting policy
    const mintingPolicy = lucid.newScript(
      {
        type: "All",
        scripts: [
          { type: "Sig", keyHash: paymentCredential.hash },
          {
            type: "Before",
            slot: lucid.utils.unixTimeToSlots(Date.now() + 1000000),
          },
        ],
      },
    );
    
    // 2. Derive the policy ID
    const policyId = mintingPolicy.toHash();
    
    // 3. Mint the tokens
    const unit = policyId + fromText("MyMintedToken");
    
    const tx = await lucid.newTx()
      .mint({ [unit]: 1n })
      .validTo(Date.now() + 200000)
      .attachScript(mintingPolicy)
      .commit();
    
    const signedTx = await tx.sign().commit();
    const txHash = await signedTx.submit();
  9. Import Lucid using Deno

    main

    Lucid is written in Deno and can be imported directly via URL. It is highly recommended to include a version tag in your import URL for stability (e.g., https://deno.land/x/lucid@0.20.14/mod.ts).

    If you use Visual Studio Code, install the Deno extension to ensure proper IntelliSense and tooling support.

    import { Lucid } from "https://deno.land/x/lucid/mod.ts";
    
    const lucid = new Lucid();
  10. Select a wallet using a private key

    main

    To enable building and submitting transactions, you must select a wallet in your Lucid instance. Use the selectWalletFromPrivateKey(privateKey) method on your Lucid instance, passing in the bech32 encoded private key string.

    // Assuming 'lucid' is your initialized Lucid instance
    lucid.selectWalletFromPrivateKey(privateKey);