From f65a7c74983e2013813d4764592766604b50c8c0 Mon Sep 17 00:00:00 2001 From: 0xBora <0xquantive@gmail.com> Date: Thu, 20 Feb 2025 05:54:27 +0100 Subject: [PATCH] Update Content - Lucid Evolution --- docs/get-started/lucid-evolution.md | 368 ++++++++++++++++++++++------ 1 file changed, 296 insertions(+), 72 deletions(-) diff --git a/docs/get-started/lucid-evolution.md b/docs/get-started/lucid-evolution.md index c0fac5ff50..baaa9546b6 100644 --- a/docs/get-started/lucid-evolution.md +++ b/docs/get-started/lucid-evolution.md @@ -5,39 +5,76 @@ sidebar_label: Lucid Evolution description: Get Started with Lucid Evolution --- -Lucid Evolution is a highly scalable, production-ready transaction builder & off-chain framework for users and dApps. +Lucid Evolution is a highly scalable, production-ready transaction builder & off-chain framework for users and DApps. It provides a TypeScript library for building transactions and designing off-chain code. -## Installation +## Quick Start -To install `lucid-evolution` you can use `pnpm` (or another package manager) and run the following in you root project: +To install `lucid-evolution` you can use `pnpm` (or another package manager): -#### Add `lucid-evolution` as dependency -```sh -pnpm i @lucid-evolution/lucid + + + + +```bash +pnpm i @lucid-evolution/lucid ``` -#### Get `lucid-evolution` from source + + + +```bash +npm i @lucid-evolution/lucid +``` -First clone the git repository + + -```sh -git clone https://github.com/Anastasia-Labs/lucid-evolution.git -cd lucid-evolution -pnpm install +```bash +yarn add @lucid-evolution/lucid ``` -## Instantiate Lucid Evolution + + + +```bash +bun i @lucid-evolution/lucid +``` -Lucid Evolution can be used with or without a blockchain provider, which allows you to query data and submit transactions. + + -Evolution supports the `Mainnet`, `Preprod`, `Preview` and `Custom` networks +:::note -### Provider selection +Installing the lucid package will automatically export all other Lucid Evolution packages as well. For more information on the other packages, please refer to the [lucid-evolution documentation](https://anastasia-labs.github.io/lucid-evolution/install). -There are multiple builtin providers you can choose from in Lucid Evolution not limited to: +::: -#### Blockfrost +## Instantiate Lucid Evolution + +Lucid Evolution can be used with or without a blockchain provider, which allows you to query data and submit transactions. Evolution library supports the `Mainnet`, `Preprod`, `Preview` and `Custom` networks. + +### Provider Selection + +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; + + + ```typescript import { Lucid, Blockfrost } from "@lucid-evolution/lucid"; @@ -48,7 +85,8 @@ const lucid = await Lucid( ); ``` -#### Kupmios + + ```typescript import { Lucid, Kupmios } from "@lucid-evolution/lucid"; @@ -56,30 +94,48 @@ import { Lucid, Kupmios } from "@lucid-evolution/lucid"; const lucid = await Lucid( new Kupmios( "http://localhost:1442", // Kupo endpoint - "http://localhost:1337" // Ogmios endpoint (Note: changed from ws:// to http:// in a release 1 month ago) + "http://localhost:1337" // Ogmios endpoint ), "Preview" ); ``` +**or with API Keys** + +```typescript +const lucid = await Lucid( + new Kupmios("http://localhost:1442", "http://localhost:1337", { + kupoHeader: { "priv-api-key": "" }, // for example: "dmtr-api-key": "" + ogmiosHeader: { "priv-api-key": "" }, + }), + "Preview" +); +``` + +:::note + Kupmios is a mix of [Ogmios](https://ogmios.dev/) and [Kupo](https://cardanosolutions.github.io/kupo/). -#### Maestro +::: + + + ```typescript import { Lucid, Maestro } from "@lucid-evolution/lucid"; const lucid = await Lucid( new Maestro({ - network: "Preprod", // For MAINNET: "Mainnet" + network: "Preprod", // For MAINNET: "Mainnet" (1) apiKey: "", // Get yours by visiting https://docs.gomaestro.org/docs/Getting-started/Sign-up-login turboSubmit: false, // Read about paid turbo transaction submission feature at https://docs.gomaestro.org/docs/Dapp%20Platform/Turbo%20Transaction }), - "Preprod" // For MAINNET: "Mainnet" + "Preprod" // For MAINNET: "Mainnet" (2) ); ``` -#### Koios + + ```typescript import { Lucid, Koios } from "@lucid-evolution/lucid"; @@ -90,117 +146,285 @@ const lucid = await Lucid( ); ``` +**or with a bearer token** + +```typescript +const lucid = await Lucid( + new Koios("", ""), + "Preprod" +); +``` + + + + ### Query Provider -The `provider` in `lucid.provider` is the provider instance you passed to `Lucid()` when selecting your provider (Blockfrost, Kupmios, Maestro, Koios, etc.). +By querying the provider you are essentially asking "what's on the blockchain?", this way you can query any on-chain data. + +The provider in `lucid.provider` is the provider instance you passed to `Lucid()` when selecting your provider (Blockfrost, Kupmios, Maestro, Koios, etc.). -#### Query UTxOs + + -#### Using Provider +UTxOs (Unspent Transaction Outputs) are the fundamental building blocks in Cardano’s eUTxO model. One of its differentiators from account-based models is that your wallet balance is the sum of all UTxOs at your address. + +**Using provider** ```typescript const utxos = await lucid.provider.getUtxos("addr_test..."); ``` -#### Using Convenience Method +**or using convenience method** ```typescript const utxos = await lucid.utxosAt("addr_test..."); ``` +:::note + This convenience method internally uses `lucid.provider.getUtxos()`. -#### Query Datums +::: + + + -##### Using Provider +In Cardano, datums are pieces of data attached to UTxOs. Let’s get some terminology out of the way. + +- _Inline datums_: When the complete datum is stored directly in the UTxO +- _Datum hashes_: When only a hash of the datum is stored on-chain + +**Using Provider** ```typescript const datum = await lucid.provider.getDatum(""); ``` -##### Using Convenience Method +**or using convenience method** ```typescript const datum = await lucid.datumOf(""); ``` -##### Querying datum from a UTxO +**or querying a datum from a scriptUTxO** ```typescript const [scriptUtxo] = await lucid.utxosAt("addr_test..."); const datum = await lucid.datumOf(scriptUtxo); ``` +:::note + +`lucid.datumOf(utxo)` is a convenience method that handles both inline datums and datum hashes: + +1. For UTxOs with inline datums → returns the datum directly +2. For UTxOs with datum hashes → fetches the full datum using `provider.getDatum()` + +Once fetched, the datum is cached in the UTxO object for subsequent queries, avoiding additional network requests. + +::: + + + -#### Query Protocol Parameters +Protocol parameters define the rules and constraints of the Cardano network, such as transaction fees, maximum block size, maximum transaction size, Plutus execution costs, and the minimum UTxO ada value. -##### Using the provider directly: +**Using the provider directly:** ```typescript const protocolParameters = await lucid.provider.getProtocolParameters(); ``` + + + +--- + ## Create a wallet You are provided multiple options to create and import a wallet -### Private Key - Generate a new private key: + + - ```typescript - const privateKey = generatePrivateKey(); // Bech32 encoded private key - console.log(privateKey); - ``` +Generate a new private key: -### Seed Phrase +```typescript +const privateKey = generatePrivateKey(); // Bech32 encoded private key +console.log(privateKey); +``` + + + Generate a new seed phrase (mnemonic): - ```typescript - const seedPhrase = generateSeedPhrase(); // BIP-39 - console.log(seedPhrase); - ``` +```typescript +const seedPhrase = generateSeedPhrase(); // BIP-39 +console.log(seedPhrase); +``` + + + + +--- ## Choosing Wallet -Use different methods to select a wallet and query balances, UTxOs +Use any suitable method to select a wallet and interact with the blockchain through it + + + + +Select a wallet using a private key: +```typescript +lucid.selectWallet.fromPrivateKey(privateKey); +``` + + + + +Select a wallet using a seed phrase (mnemonic): + +```typescript +const seedPhrase = "your seed phrase here..."; +lucid.selectWallet.fromSeed(seedPhrase); +``` + + + + +If you're integrating with a wallet provider that exposes an API conforming to the `WalletApi` interface. This works for any [CIP-30](https://github.com/cardano-foundation/CIPs/tree/master/CIP-0030) compliant wallet. + +```typescript +// `externalWalletApi` is your wallet provider's API +const walletApi: WalletApi = externalWalletApi; +lucid.selectWallet.fromAPI(walletApi); +``` + + + + +This method will create a limited wallet that can still query the address and its UTxOs. You can use it to build transactions that **others will sign**, as it cannot sign transactions (no private key). + +```typescript +const address = "addr_test..."; +const utxos = await lucid.utxosAt(address); +lucid.selectWallet.fromAddress(address, utxos); +``` + +:::warning + +Transactions built with an address-only wallet will need to be signed by a wallet with the actual private keys before they can be submitted. + +::: + + + + +--- + +## Your first transaction + +A couple of fundamentals to remember are that in Cardano’s eUTxO model, a transaction can consume one or more UTxOs as inputs, create one or more UTxOs as outputs, and must be balanced (sum of inputs = sum of outputs + fees). + +### 1. Build + +Let’s create a simple transaction where we send `5 ada` to two recipients each: -### Private Key +```typescript +const tx = await lucid + .newTx() + .pay.ToAddress("addr_testa...", { lovelace: 5000000n }) + .pay.ToAddress("addr_testb...", { lovelace: 5000000n }) + .complete(); +``` + +:::note +To balance the transaction and initiate coin selection, transactions always +need to end with `.complete()` +::: + +### 2. Sign + +```typescript +const signedTx = await tx.sign.withWallet().complete(); +``` - Select a wallet using a private key: +You could also choose to sign the transaction with a private key: - ```typescript - lucid.selectWallet.fromPrivateKey(privateKey); - ``` +```typescript +const signedTx = await tx.sign.withPrivateKey(privateKey).complete(); +``` + +### 3. Submit + +Lastly we submit the transaction: + +```typescript +const txHash = await signedTx.submit(); +console.log(txHash); +``` -### Address & UTXOs +:::note -This method is useful when you have the address and UTXOs of a wallet but not necessarily the private key. - ```typescript - const address = "addr_test..."; // Your wallet address - const utxos = await lucid.utxosAt(address); - lucid.selectWallet.fromAddress(address, utxos); - ``` +Remember to select a wallet before attempting to build and submit +The wallet selection methods we discussed in the previous section should be implemented before building the transaction. -### Seed Phrase +::: - Select a wallet using a seed phrase (mnemonic): +### Putting everything together - ```typescript - const seedPhrase = "your seed phrase here..."; - lucid.selectWallet.fromSeed(seedPhrase); - ``` +```typescript +import { Lucid, Blockfrost } from "@lucid-evolution/lucid"; + +// Initialize Lucid with a provider +const lucid = await Lucid( + new Blockfrost("https://cardano-preprod.blockfrost.io/api/v0", ""), + "Preprod" +); + +// Select a wallet for signing +lucid.selectWallet.fromPrivateKey(privateKey); + +// Build, sign and submit transaction +const tx = await lucid + .newTx() + .pay.ToAddress("addr_testa...", { lovelace: 5000000n }) // Pay 5 ada to addr_testa + .complete(); // Balances the transaction and initiates coin selection + +const signedTx = await tx.sign.withWallet().complete(); +const txHash = await signedTx.submit(); +console.log(txHash); +``` + +--- +## You want to learn more? -If you're integrating with a wallet provider that exposes an API conforming to the WalletApi interface: +Check out our [docs](https://anastasia-labs.github.io/lucid-evolution/documentation/core-concepts/instantiate-evolution) for more examples. - ```typescript - // `externalWalletApi` is your wallet provider's API - const walletApi: WalletApi = externalWalletApi; - lucid.selectWallet.fromAPI(walletApi); - ``` +You now have all you need to start playing with Lucid Evolution. Take a look at [under the hood](https://anastasia-labs.github.io/lucid-evolution/documentation/core-concepts/under-the-hood) to understand how Evolution library works, follow the [deep dive](https://anastasia-labs.github.io/lucid-evolution/documentation/deep-dives/make-payments) series to start building your own off-chain code and take a look at example open-source repositories to use the library in different use cases. -## More examples -You now have all you need to start playing with Lucid Evolution. Have a look at [our docs](https://anastasia-labs.github.io/lucid-evolution/documentation/core-concepts/instantiate-evolution) for more examples. +