diff --git a/.changeset/chain-interface.md b/.changeset/chain-interface.md new file mode 100644 index 00000000..ccb0becc --- /dev/null +++ b/.changeset/chain-interface.md @@ -0,0 +1,47 @@ +--- +"@evolution-sdk/evolution": patch +"@evolution-sdk/devnet": patch +--- + +`createClient` now requires an explicit `chain` field instead of the optional `network?: string` field. + +Previously, selecting a network required passing a string identifier and, separately, a `slotConfig` object for slot/time conversions. There was no single source of truth that tied network identity, magic number, and timing parameters together: + +```ts +// Before +createClient({ + network: "preprod", + slotConfig: { zeroTime: 1655769600000n, zeroSlot: 86400n, slotLength: 1000 }, + provider: { ... }, + wallet: { ... } +}) +``` + +Now the `chain` field is a rich descriptor that carries all of this together. Three built-in constants are exported from the top-level package: + +```ts +// After +import { createClient, preprod } from "@evolution-sdk/evolution" + +createClient({ + chain: preprod, + provider: { ... }, + wallet: { ... } +}) +``` + +For custom networks — local devnets, private chains, or future forks — use `defineChain`: + +```ts +import { defineChain } from "@evolution-sdk/evolution" + +const devnet = defineChain({ + name: "Devnet", + id: 0, + networkMagic: 42, + slotConfig: { zeroTime: 0n, zeroSlot: 0n, slotLength: 1000 }, + epochLength: 432000, +}) +``` + +The `networkId: number | string` property on client objects is replaced with `chain: Chain`. The `@evolution-sdk/devnet` package adds `getChain(cluster)` and `BOOTSTRAP_CHAIN` for constructing a `Chain` from a running local devnet. diff --git a/docs/content/docs/addresses/construction.mdx b/docs/content/docs/addresses/construction.mdx index 3aaa713d..ab0a5991 100644 --- a/docs/content/docs/addresses/construction.mdx +++ b/docs/content/docs/addresses/construction.mdx @@ -51,10 +51,10 @@ const bech32 = Address.toBech32(address) ## Getting Your Wallet Address ```typescript twoslash -import { createClient } from "@evolution-sdk/evolution" +import { createClient, preprod} from "@evolution-sdk/evolution" const client = createClient({ - network: "preprod", + chain: preprod, wallet: { type: "seed", mnemonic: process.env.WALLET_MNEMONIC!, accountIndex: 0 } }) diff --git a/docs/content/docs/advanced/custom-providers.mdx b/docs/content/docs/advanced/custom-providers.mdx index 51028fcb..cf2cac33 100644 --- a/docs/content/docs/advanced/custom-providers.mdx +++ b/docs/content/docs/advanced/custom-providers.mdx @@ -38,11 +38,11 @@ interface ProviderEffect { ## Using a Provider ```typescript twoslash -import { createClient } from "@evolution-sdk/evolution" +import { createClient, preprod} from "@evolution-sdk/evolution" // Blockfrost const blockfrostClient = createClient({ - network: "preprod", + chain: preprod, provider: { type: "blockfrost", baseUrl: "https://cardano-preprod.blockfrost.io/api/v0", @@ -52,7 +52,7 @@ const blockfrostClient = createClient({ // Kupo/Ogmios const kupmiosClient = createClient({ - network: "preprod", + chain: preprod, provider: { type: "kupmios", kupoUrl: "http://localhost:1442", diff --git a/docs/content/docs/advanced/error-handling.mdx b/docs/content/docs/advanced/error-handling.mdx index ca063a68..05ac27dc 100644 --- a/docs/content/docs/advanced/error-handling.mdx +++ b/docs/content/docs/advanced/error-handling.mdx @@ -20,10 +20,10 @@ Evolution SDK is built on Effect, providing structured error handling with typed The standard `.build()`, `.sign()`, `.submit()` methods return Promises. Errors throw as exceptions: ```typescript twoslash -import { Address, Assets, createClient } from "@evolution-sdk/evolution" +import { Address, Assets, createClient, preprod} from "@evolution-sdk/evolution" const client = createClient({ - network: "preprod", + chain: preprod, provider: { type: "blockfrost", baseUrl: "https://cardano-preprod.blockfrost.io/api/v0", projectId: process.env.BLOCKFROST_API_KEY! }, wallet: { type: "seed", mnemonic: process.env.WALLET_MNEMONIC!, accountIndex: 0 } }) @@ -50,10 +50,10 @@ Use `.buildEffect()` for composable error handling with Effect: ```typescript twoslash import { Effect } from "effect" -import { Address, Assets, createClient } from "@evolution-sdk/evolution" +import { Address, Assets, createClient, preprod} from "@evolution-sdk/evolution" const client = createClient({ - network: "preprod", + chain: preprod, provider: { type: "blockfrost", baseUrl: "https://cardano-preprod.blockfrost.io/api/v0", projectId: process.env.BLOCKFROST_API_KEY! }, wallet: { type: "seed", mnemonic: process.env.WALLET_MNEMONIC!, accountIndex: 0 } }) @@ -76,10 +76,10 @@ const program = client Use `.buildEither()` for explicit success/failure without exceptions: ```typescript twoslash -import { Address, Assets, createClient } from "@evolution-sdk/evolution" +import { Address, Assets, createClient, preprod} from "@evolution-sdk/evolution" const client = createClient({ - network: "preprod", + chain: preprod, provider: { type: "blockfrost", baseUrl: "https://cardano-preprod.blockfrost.io/api/v0", projectId: process.env.BLOCKFROST_API_KEY! }, wallet: { type: "seed", mnemonic: process.env.WALLET_MNEMONIC!, accountIndex: 0 } }) diff --git a/docs/content/docs/advanced/performance.mdx b/docs/content/docs/advanced/performance.mdx index 911ac912..b1eda1f6 100644 --- a/docs/content/docs/advanced/performance.mdx +++ b/docs/content/docs/advanced/performance.mdx @@ -18,10 +18,10 @@ Evolution SDK provides several configuration options to optimize transaction bui The default algorithm is `"largest-first"`. You can also provide a custom coin selection function: ```typescript twoslash -import { Address, Assets, createClient } from "@evolution-sdk/evolution" +import { Address, Assets, createClient, preprod} from "@evolution-sdk/evolution" const client = createClient({ - network: "preprod", + chain: preprod, provider: { type: "blockfrost", baseUrl: "https://cardano-preprod.blockfrost.io/api/v0", projectId: process.env.BLOCKFROST_API_KEY! }, wallet: { type: "seed", mnemonic: process.env.WALLET_MNEMONIC!, accountIndex: 0 } }) @@ -40,10 +40,10 @@ const tx = await client The `unfrack` option optimizes your wallet's UTxO structure during transaction building: ```typescript twoslash -import { Address, Assets, createClient } from "@evolution-sdk/evolution" +import { Address, Assets, createClient, preprod} from "@evolution-sdk/evolution" const client = createClient({ - network: "preprod", + chain: preprod, provider: { type: "blockfrost", baseUrl: "https://cardano-preprod.blockfrost.io/api/v0", projectId: process.env.BLOCKFROST_API_KEY! }, wallet: { type: "seed", mnemonic: process.env.WALLET_MNEMONIC!, accountIndex: 0 } }) diff --git a/docs/content/docs/advanced/typescript.mdx b/docs/content/docs/advanced/typescript.mdx index c77dee38..88ad851c 100644 --- a/docs/content/docs/advanced/typescript.mdx +++ b/docs/content/docs/advanced/typescript.mdx @@ -42,17 +42,17 @@ const addr = Address.fromBech32("addr_test1vrm9x2dgvdau8vckj4duc89m638t8djmluqw5 The client type narrows based on configuration: ```typescript twoslash -import { createClient } from "@evolution-sdk/evolution" +import { createClient, preprod} from "@evolution-sdk/evolution" // Provider-only client (no wallet) — can query but not sign const queryClient = createClient({ - network: "preprod", + chain: preprod, provider: { type: "blockfrost", baseUrl: "", projectId: "" } }) // Signing client (wallet + provider) — full capabilities const signingClient = createClient({ - network: "preprod", + chain: preprod, provider: { type: "blockfrost", baseUrl: "", projectId: "" }, wallet: { type: "seed", mnemonic: "", accountIndex: 0 } }) diff --git a/docs/content/docs/assets/metadata.mdx b/docs/content/docs/assets/metadata.mdx index 1ec3de15..75bb90ac 100644 --- a/docs/content/docs/assets/metadata.mdx +++ b/docs/content/docs/assets/metadata.mdx @@ -18,10 +18,10 @@ Transaction metadata lets you attach arbitrary data to transactions without affe ## Attach a Message (CIP-20) ```typescript twoslash -import { Address, Assets, TransactionMetadatum, createClient } from "@evolution-sdk/evolution" +import { Address, Assets, TransactionMetadatum, createClient, preprod} from "@evolution-sdk/evolution" const client = createClient({ - network: "preprod", + chain: preprod, provider: { type: "blockfrost", baseUrl: "https://cardano-preprod.blockfrost.io/api/v0", projectId: process.env.BLOCKFROST_API_KEY! }, wallet: { type: "seed", mnemonic: process.env.WALLET_MNEMONIC!, accountIndex: 0 } }) @@ -49,10 +49,10 @@ await signed.submit() Chain multiple `attachMetadata` calls for different labels: ```typescript twoslash -import { Address, Assets, TransactionMetadatum, createClient } from "@evolution-sdk/evolution" +import { Address, Assets, TransactionMetadatum, createClient, preprod} from "@evolution-sdk/evolution" const client = createClient({ - network: "preprod", + chain: preprod, provider: { type: "blockfrost", baseUrl: "https://cardano-preprod.blockfrost.io/api/v0", projectId: process.env.BLOCKFROST_API_KEY! }, wallet: { type: "seed", mnemonic: process.env.WALLET_MNEMONIC!, accountIndex: 0 } }) diff --git a/docs/content/docs/clients/architecture.mdx b/docs/content/docs/clients/architecture.mdx index f4bae19e..708a3780 100644 --- a/docs/content/docs/clients/architecture.mdx +++ b/docs/content/docs/clients/architecture.mdx @@ -32,11 +32,11 @@ interface ReadOnlyWalletConfig { ### Backend Transaction Building ```typescript twoslash -import { Address, Assets, Transaction, createClient } from "@evolution-sdk/evolution"; +import { Address, Assets, Transaction, createClient, mainnet } from "@evolution-sdk/evolution"; // Backend: Create provider client, then attach read-only wallet const providerClient = createClient({ - network: "mainnet", + chain: mainnet, provider: { type: "blockfrost", baseUrl: "https://cardano-mainnet.blockfrost.io/api/v0", @@ -87,7 +87,7 @@ Frontend applications connect to user wallets through CIP-30 but never have prov ### Implementation ```typescript -import { Address, Assets, Transaction, createClient } from "@evolution-sdk/evolution"; +import { Address, Assets, Transaction, createClient, mainnet } from "@evolution-sdk/evolution"; // 1. Connect wallet declare const cardano: any; @@ -95,7 +95,7 @@ const walletApi = await cardano.eternl.enable(); // 2. Create signing-only client const client = createClient({ - network: "mainnet", + chain: mainnet, wallet: { type: "api", api: walletApi } }); @@ -138,13 +138,13 @@ Backend services use read-only wallets configured with user addresses to build u ### Implementation ```typescript -import { Address, Assets, Transaction, createClient } from "@evolution-sdk/evolution"; +import { Address, Assets, Transaction, createClient, mainnet } from "@evolution-sdk/evolution"; // Backend endpoint export async function buildTransaction(userAddress: string) { // Create read-only client with user's address const client = createClient({ - network: "mainnet", + chain: mainnet, provider: { type: "blockfrost", baseUrl: "https://cardano-mainnet.blockfrost.io/api/v0", @@ -193,7 +193,7 @@ export type BuildPaymentResponse = { txCbor: string }; // @filename: frontend.ts // ===== Frontend (Browser) ===== -import { Address, Assets, Transaction, createClient } from "@evolution-sdk/evolution"; +import { Address, Assets, Transaction, createClient, mainnet } from "@evolution-sdk/evolution"; import type { BuildPaymentResponse } from "./shared"; declare const cardano: any; @@ -202,7 +202,7 @@ async function sendPayment(recipientAddress: string, lovelace: bigint) { // 1. Connect user wallet const walletApi = await cardano.eternl.enable(); const walletClient = createClient({ - network: "mainnet", + chain: mainnet, wallet: { type: "api", api: walletApi } }); @@ -232,7 +232,7 @@ async function sendPayment(recipientAddress: string, lovelace: bigint) { // @filename: backend.ts // ===== Backend (Server) ===== -import { Address, Assets, Transaction, createClient } from "@evolution-sdk/evolution"; +import { Address, Assets, Transaction, createClient, mainnet } from "@evolution-sdk/evolution"; export async function buildPayment( userAddressBech32: string, @@ -244,7 +244,7 @@ export async function buildPayment( // Create provider client first, then attach read-only wallet const providerClient = createClient({ - network: "mainnet", + chain: mainnet, provider: { type: "blockfrost", baseUrl: "https://cardano-mainnet.blockfrost.io/api/v0", @@ -302,7 +302,7 @@ User keys never leave their device. Provider API keys never exposed to frontend. ```typescript // WRONG - Frontend has no provider const client = createClient({ - network: "mainnet", + chain: mainnet, wallet: { type: "api", api: walletApi } // No provider! }); @@ -315,7 +315,7 @@ const builder = client.newTx(); // Error: Cannot build without provider ```typescript // CORRECT - Frontend signs, backend builds const client = createClient({ - network: "mainnet", + chain: mainnet, wallet: { type: "api", api: walletApi } }); @@ -328,7 +328,7 @@ const witnessSet = await client.signTx(txCborFromBackend); ```typescript // WRONG - Backend has no private keys const client = createClient({ - network: "mainnet", + chain: mainnet, provider: { /* ... */ }, wallet: { type: "read-only", @@ -344,8 +344,8 @@ await client.sign(); // Error: Cannot sign with read-only wallet ```typescript // CORRECT - Backend builds, frontend signs const client = createClient({ - network: "mainnet", - provider: { /* ... */ }, + chain: mainnet, + provider: { /* ... */ }, wallet: { type: "read-only", address: userAddress diff --git a/docs/content/docs/clients/architecture/frontend-backend.mdx b/docs/content/docs/clients/architecture/frontend-backend.mdx index 168bd616..5d3a6945 100644 --- a/docs/content/docs/clients/architecture/frontend-backend.mdx +++ b/docs/content/docs/clients/architecture/frontend-backend.mdx @@ -32,7 +32,7 @@ Frontend applications use API wallet clients (CIP-30) for signing only. They hav **Cannot Do**: Build transactions, query blockchain, fee calculation ```typescript twoslash -import { Address, Assets, Transaction, createClient } from "@evolution-sdk/evolution"; +import { Address, Assets, Transaction, createClient, mainnet} from "@evolution-sdk/evolution"; declare const cardano: any; @@ -41,7 +41,7 @@ const walletApi = await cardano.eternl.enable(); // 2. Create API wallet client (no provider) const client = createClient({ - network: "mainnet", + chain: mainnet, wallet: { type: "api", api: walletApi } }); @@ -81,12 +81,12 @@ Backend services use read-only clients configured with user addresses to build u **Cannot Do**: Sign transactions, access private keys ```typescript twoslash -import { Address, Assets, Transaction, createClient } from "@evolution-sdk/evolution"; +import { Address, Assets, Transaction, createClient, mainnet} from "@evolution-sdk/evolution"; export async function buildTransaction(userAddressBech32: string) { // Create read-only client with user's address (bech32 string) const client = createClient({ - network: "mainnet", + chain: mainnet, provider: { type: "blockfrost", baseUrl: "https://cardano-mainnet.blockfrost.io/api/v0", @@ -142,7 +142,7 @@ export type BuildPaymentResponse = { // @filename: frontend.ts // ===== Frontend (Browser) ===== -import { Address, Assets, Transaction, createClient } from "@evolution-sdk/evolution"; +import { Address, Assets, Transaction, createClient, mainnet } from "@evolution-sdk/evolution"; import type { BuildPaymentRequest, BuildPaymentResponse } from "./shared"; declare const cardano: any; @@ -153,7 +153,7 @@ async function sendPayment(recipientAddress: string, lovelace: bigint) { // 2. Create API wallet client (signing only) const walletClient = createClient({ - network: "mainnet", + chain: mainnet, wallet: { type: "api", api: walletApi } }); @@ -186,7 +186,7 @@ async function sendPayment(recipientAddress: string, lovelace: bigint) { // @filename: backend.ts // ===== Backend (Server) ===== -import { Address, Assets, Transaction, createClient } from "@evolution-sdk/evolution"; +import { Address, Assets, Transaction, createClient, mainnet} from "@evolution-sdk/evolution"; import type { BuildPaymentResponse } from "./shared"; export async function buildPayment( @@ -199,7 +199,7 @@ export async function buildPayment( // Create read-only client with user's address (bech32 string) const client = createClient({ - network: "mainnet", + chain: mainnet, provider: { type: "blockfrost", baseUrl: "https://cardano-mainnet.blockfrost.io/api/v0", @@ -274,7 +274,7 @@ This architecture provides complete security through proper separation: ```typescript // WRONG - API wallet client has no provider const client = createClient({ - network: "mainnet", + chain: mainnet, wallet: { type: "api", api: walletApi } // No provider configured! }); @@ -289,7 +289,7 @@ const builder = client.newTx(); // Error: Cannot build without provider ```typescript // CORRECT - API wallet client signs only const client = createClient({ - network: "mainnet", + chain: mainnet, wallet: { type: "api", api: walletApi } }); @@ -307,7 +307,7 @@ const witnessSet = await client.signTx(txCbor); ```typescript // WRONG - Read-only client has no private keys const client = createClient({ - network: "mainnet", + chain: mainnet, provider: { /* ... */ }, wallet: { type: "read-only", @@ -325,7 +325,7 @@ await client.sign(data); // Error: Cannot sign with read-only wallet ```typescript // CORRECT - Read-only client builds only const client = createClient({ - network: "mainnet", + chain: mainnet, provider: { /* ... */ }, wallet: { type: "read-only", diff --git a/docs/content/docs/clients/client-basics.mdx b/docs/content/docs/clients/client-basics.mdx index 3c7efbd5..d37f79f8 100644 --- a/docs/content/docs/clients/client-basics.mdx +++ b/docs/content/docs/clients/client-basics.mdx @@ -7,17 +7,17 @@ description: "Learn the basics of creating and using an Evolution SDK client" The Evolution SDK client is your primary interface to the Cardano blockchain. It combines wallet management, provider communication, and transaction building into a single, cohesive API. Once configured, the client handles UTxO selection, fee calculation, and signing—letting you focus on your application logic. -Think of the client as your persistent connection: configure it once with your network, provider, and wallet, then use it throughout your application to build and submit transactions. All operations maintain type safety and composability through Effect-TS. +Think of the client as your persistent connection: configure it once with your chain, provider, and wallet, then use it throughout your application to build and submit transactions. All operations maintain type safety and composability through Effect-TS. ## Creating a Client -Configure your client with three essential pieces: the network (mainnet/preprod/preview), your blockchain provider, and the wallet for signing: +Configure your client with three essential pieces: the **chain** (which Cardano network to target), your blockchain provider, and the wallet for signing: ```ts twoslash -import { Address, Assets, createClient } from "@evolution-sdk/evolution"; +import { Address, Assets, createClient, preprod } from "@evolution-sdk/evolution"; const client = createClient({ - network: "preprod", + chain: preprod, provider: { type: "blockfrost", baseUrl: "https://cardano-preprod.blockfrost.io/api/v0", @@ -31,6 +31,38 @@ const client = createClient({ }); ``` +## Chain Configuration + +The `chain` field is a rich descriptor, not just a string identifier. It carries network magic, slot timing parameters, and optional block explorer URLs — everything the SDK needs to interact with a specific Cardano network. + +Evolution SDK exports three built-in chain constants: + +| Constant | Network | Network Magic | +|----------|---------|---------------| +| `mainnet` | Production | `764824073` | +| `preprod` | Pre-production testnet | `1` | +| `preview` | Preview testnet | `2` | + +```ts twoslash +import { mainnet, preprod, preview } from "@evolution-sdk/evolution"; +``` + +For custom networks — local devnets, private chains, or future Cardano forks — use `defineChain`: + +```ts twoslash +import { defineChain } from "@evolution-sdk/evolution"; + +const devnet = defineChain({ + name: "Devnet", + id: 0, + networkMagic: 42, + slotConfig: { zeroTime: 0n, zeroSlot: 0n, slotLength: 1000 }, + epochLength: 432000, +}); +``` + +The `slotConfig` is embedded in the chain constant and consumed directly by the transaction builder for slot-to-POSIX time conversions. There is no separate `slotConfig` parameter on `createClient`. + ## The Transaction Workflow Evolution SDK follows a three-stage pattern: build, sign, submit. Each stage returns a new builder with stage-specific methods, preventing invalid operations (like submitting before signing). @@ -40,10 +72,10 @@ Evolution SDK follows a three-stage pattern: build, sign, submit. Each stage ret Start with `client.newTx()` and chain operations to specify outputs, metadata, or validity ranges: ```ts twoslash -import { Address, Assets, createClient } from "@evolution-sdk/evolution"; +import { Address, Assets, createClient, preprod } from "@evolution-sdk/evolution"; const client = createClient({ - network: "preprod", + chain: preprod, provider: { type: "blockfrost", baseUrl: "", projectId: "" }, wallet: { type: "seed", mnemonic: "", accountIndex: 0 } }); @@ -63,10 +95,10 @@ const signBuilder = await builder.build(); Call `.sign()` on the built transaction to create signatures with your wallet: ```ts twoslash -import { Address, Assets, createClient } from "@evolution-sdk/evolution"; +import { Address, Assets, createClient, preprod } from "@evolution-sdk/evolution"; const client = createClient({ - network: "preprod", + chain: preprod, provider: { type: "blockfrost", baseUrl: "", projectId: "" }, wallet: { type: "seed", mnemonic: "", accountIndex: 0 } }); @@ -83,10 +115,10 @@ const submitBuilder = await signBuilder.sign(); Finally, `.submit()` broadcasts the signed transaction to the blockchain and returns the transaction hash: ```ts twoslash -import { Address, Assets, createClient } from "@evolution-sdk/evolution"; +import { Address, Assets, createClient, preprod } from "@evolution-sdk/evolution"; const client = createClient({ - network: "preprod", + chain: preprod, provider: { type: "blockfrost", baseUrl: "", projectId: "" }, wallet: { type: "seed", mnemonic: "", accountIndex: 0 } }); @@ -105,10 +137,10 @@ console.log("Transaction submitted:", txId); Here's the complete workflow in a single example—from client creation through transaction submission: ```ts twoslash -import { Address, Assets, createClient } from "@evolution-sdk/evolution"; +import { Address, Assets, createClient, preprod } from "@evolution-sdk/evolution"; const client = createClient({ - network: "preprod", + chain: preprod, provider: { type: "blockfrost", baseUrl: "https://cardano-preprod.blockfrost.io/api/v0", diff --git a/docs/content/docs/clients/index.mdx b/docs/content/docs/clients/index.mdx index e298ab0a..b96cf55c 100644 --- a/docs/content/docs/clients/index.mdx +++ b/docs/content/docs/clients/index.mdx @@ -30,10 +30,12 @@ Different combinations create different client types with distinct capabilities. All clients use `createClient` with different configurations: ```typescript +import { mainnet, preprod, preview, defineChain } from "@evolution-sdk/evolution"; + createClient({ - network: "mainnet" | "preprod" | "preview", - provider?: ProviderConfig, // Optional - wallet?: WalletConfig // Optional + chain: mainnet | preprod | preview, // or a custom chain via defineChain(...) + provider?: ProviderConfig, // Optional + wallet?: WalletConfig // Optional }) ``` diff --git a/docs/content/docs/clients/providers.mdx b/docs/content/docs/clients/providers.mdx index 0789a452..7679cf0f 100644 --- a/docs/content/docs/clients/providers.mdx +++ b/docs/content/docs/clients/providers.mdx @@ -14,10 +14,10 @@ Choose Blockfrost for quick setup with hosted infrastructure, or Kupmios for sel Blockfrost offers hosted infrastructure with a free tier, perfect for development and small-scale applications. Setup takes minutes—just get an API key and connect. ```ts twoslash -import { createClient } from "@evolution-sdk/evolution"; +import { createClient, preprod } from "@evolution-sdk/evolution"; const client = createClient({ - network: "preprod", + chain: preprod, provider: { type: "blockfrost", baseUrl: "https://cardano-preprod.blockfrost.io/api/v0", @@ -41,10 +41,10 @@ const client = createClient({ Run your own Cardano node infrastructure for complete control and privacy. Kupmios combines Kupo (UTxO indexing) and Ogmios (node queries) for a fully local setup. Ideal for production applications that need guaranteed uptime and don't want external dependencies. ```ts twoslash -import { createClient } from "@evolution-sdk/evolution"; +import { createClient, preprod } from "@evolution-sdk/evolution"; const client = createClient({ - network: "preprod", + chain: preprod, provider: { type: "kupmios", kupoUrl: "http://localhost:1442", @@ -79,11 +79,11 @@ Use Blockfrost for rapid prototyping and development. Switch to Kupmios when you The beauty of Evolution SDK's provider abstraction: your transaction code doesn't change. Only the configuration does: ```ts twoslash -import { createClient } from "@evolution-sdk/evolution"; +import { createClient, preprod } from "@evolution-sdk/evolution"; // Start with Blockfrost const blockfrostClient = createClient({ - network: "preprod", + chain: preprod, provider: { type: "blockfrost", baseUrl: "https://cardano-preprod.blockfrost.io/api/v0", @@ -98,7 +98,7 @@ const blockfrostClient = createClient({ // Switch to Kupmios const kupmiosClient = createClient({ - network: "preprod", + chain: preprod, provider: { type: "kupmios", kupoUrl: "http://localhost:1442", @@ -126,7 +126,7 @@ OGMIOS_URL=http://localhost:1337 Then in your code: ```ts twoslash -import { createClient } from "@evolution-sdk/evolution"; +import { createClient, preprod } from "@evolution-sdk/evolution"; const provider = process.env.BLOCKFROST_API_KEY ? { @@ -141,7 +141,7 @@ const provider = process.env.BLOCKFROST_API_KEY }; const client = createClient({ - network: "preprod", + chain: preprod, provider, wallet: { type: "seed", diff --git a/docs/content/docs/devnet/configuration.mdx b/docs/content/docs/devnet/configuration.mdx index 327ce5be..ae2f7185 100644 --- a/docs/content/docs/devnet/configuration.mdx +++ b/docs/content/docs/devnet/configuration.mdx @@ -27,7 +27,7 @@ import { Address, TransactionHash, createClient } from "@evolution-sdk/evolution // Create a client to generate an address const client = createClient({ - network: 0, // Network magic 0 for custom devnet + chain: Cluster.BOOTSTRAP_CHAIN, wallet: { type: "seed", mnemonic: "your twenty-four word mnemonic phrase here", @@ -74,7 +74,7 @@ import { Cluster, Config } from "@evolution-sdk/devnet"; import { Address, TransactionHash, createClient } from "@evolution-sdk/evolution"; const client1 = createClient({ - network: 0, + chain: Cluster.BOOTSTRAP_CHAIN, wallet: { type: "seed", mnemonic: "your mnemonic here", @@ -83,7 +83,7 @@ const client1 = createClient({ }); const client2 = createClient({ - network: 0, + chain: Cluster.BOOTSTRAP_CHAIN, wallet: { type: "seed", mnemonic: "your mnemonic here", @@ -308,7 +308,7 @@ import { Address, TransactionHash, createClient } from "@evolution-sdk/evolution // Generate funded addresses const wallet1 = createClient({ - network: 0, + chain: Cluster.BOOTSTRAP_CHAIN, wallet: { type: "seed", mnemonic: "test wallet one mnemonic here", @@ -317,7 +317,7 @@ const wallet1 = createClient({ }); const wallet2 = createClient({ - network: 0, + chain: Cluster.BOOTSTRAP_CHAIN, wallet: { type: "seed", mnemonic: "test wallet two mnemonic here", @@ -460,6 +460,6 @@ With custom genesis configuration, you can now: **Protocol parameter validation**: Some parameter combinations are invalid (e.g., `lovelacePerUTxOWord` too low in Alonzo genesis). Check cardano-node logs if startup fails. -**Client network parameter**: Always use `network: 0` for devnet clients to create testnet-format addresses (addr_test...). +**Client chain parameter**: Always use `Cluster.BOOTSTRAP_CHAIN` for devnet clients to create testnet-format addresses (addr_test...). **Excessive funds**: While genesis supports arbitrary amounts, extremely large values may cause numeric overflow in some calculations. Stay under 45B ADA (total supply) per address. diff --git a/docs/content/docs/devnet/integration.mdx b/docs/content/docs/devnet/integration.mdx index ad2b7973..70145980 100644 --- a/docs/content/docs/devnet/integration.mdx +++ b/docs/content/docs/devnet/integration.mdx @@ -35,7 +35,7 @@ const MNEMONIC = "your twenty-four word mnemonic phrase here"; async function completeWorkflow() { // Step 1: Generate sender address const wallet = createClient({ - network: 0, + chain: Cluster.BOOTSTRAP_CHAIN, wallet: { type: "seed", mnemonic: MNEMONIC, accountIndex: 0 } }); @@ -72,7 +72,7 @@ async function completeWorkflow() { // Step 4: Create client connected to devnet const client = createClient({ - network: 0, + chain: Cluster.getChain(cluster), provider: { type: "kupmios", kupoUrl: "http://localhost:1442", @@ -190,7 +190,7 @@ await new Promise(resolve => setTimeout(resolve, 6000)); // Provider-only client (no wallet configured) const providerClient = createClient({ - network: 0, + chain: Cluster.getChain(cluster), provider: { type: "kupmios", kupoUrl: "http://localhost:1442", @@ -232,7 +232,7 @@ describe("Transaction Tests", () => { const mnemonic = "test test test test test test test test test test test test test test test test test test test test test test test sauce"; const wallet = createClient({ - network: 0, + chain: Cluster.BOOTSTRAP_CHAIN, wallet: { type: "seed", mnemonic, accountIndex: 0 } }); @@ -257,7 +257,7 @@ describe("Transaction Tests", () => { await new Promise(resolve => setTimeout(resolve, 8000)); client = createClient({ - network: 0, + chain: Cluster.getChain(cluster), provider: { type: "kupmios", kupoUrl: "http://localhost:1442", @@ -323,7 +323,7 @@ import { Address, Assets, TransactionHash, createClient } from "@evolution-sdk/e async function multiWalletExample() { // Create two wallets const wallet1 = createClient({ - network: 0, + chain: Cluster.BOOTSTRAP_CHAIN, wallet: { type: "seed", mnemonic: "wallet one mnemonic here", @@ -332,7 +332,7 @@ async function multiWalletExample() { }); const wallet2 = createClient({ - network: 0, + chain: Cluster.BOOTSTRAP_CHAIN, wallet: { type: "seed", mnemonic: "wallet two mnemonic here", @@ -367,7 +367,7 @@ await new Promise(resolve => setTimeout(resolve, 8000)); // Create connected clients for both wallets const client1 = createClient({ - network: 0, + chain: Cluster.getChain(cluster), provider: { type: "kupmios", kupoUrl: "http://localhost:1442", @@ -381,7 +381,7 @@ const client1 = createClient({ }); const client2 = createClient({ - network: 0, + chain: Cluster.getChain(cluster), provider: { type: "kupmios", kupoUrl: "http://localhost:1442", diff --git a/docs/content/docs/governance/drep-registration.mdx b/docs/content/docs/governance/drep-registration.mdx index c1d7c068..87648fc4 100644 --- a/docs/content/docs/governance/drep-registration.mdx +++ b/docs/content/docs/governance/drep-registration.mdx @@ -10,10 +10,10 @@ Delegated Representatives (DReps) vote on governance actions on behalf of ADA ho ## Register as a DRep ```typescript twoslash -import { Credential, createClient } from "@evolution-sdk/evolution" +import { Credential, createClient, preprod} from "@evolution-sdk/evolution" const client = createClient({ - network: "preprod", + chain: preprod, provider: { type: "blockfrost", baseUrl: "https://cardano-preprod.blockfrost.io/api/v0", projectId: process.env.BLOCKFROST_API_KEY! }, wallet: { type: "seed", mnemonic: process.env.WALLET_MNEMONIC!, accountIndex: 0 } }) @@ -36,10 +36,10 @@ The deposit amount is fetched automatically from protocol parameters (`drepDepos Attach an anchor containing a metadata URL and its hash: ```typescript twoslash -import { Anchor, Credential, createClient } from "@evolution-sdk/evolution" +import { Anchor, Credential, createClient, preprod} from "@evolution-sdk/evolution" const client = createClient({ - network: "preprod", + chain: preprod, provider: { type: "blockfrost", baseUrl: "https://cardano-preprod.blockfrost.io/api/v0", projectId: process.env.BLOCKFROST_API_KEY! }, wallet: { type: "seed", mnemonic: process.env.WALLET_MNEMONIC!, accountIndex: 0 } }) @@ -64,10 +64,10 @@ await signed.submit() Change the metadata anchor for an existing DRep registration: ```typescript twoslash -import { Anchor, Credential, createClient } from "@evolution-sdk/evolution" +import { Anchor, Credential, createClient, preprod} from "@evolution-sdk/evolution" const client = createClient({ - network: "preprod", + chain: preprod, provider: { type: "blockfrost", baseUrl: "https://cardano-preprod.blockfrost.io/api/v0", projectId: process.env.BLOCKFROST_API_KEY! }, wallet: { type: "seed", mnemonic: process.env.WALLET_MNEMONIC!, accountIndex: 0 } }) @@ -92,10 +92,10 @@ await signed.submit() Remove DRep registration and reclaim the deposit: ```typescript twoslash -import { Credential, createClient } from "@evolution-sdk/evolution" +import { Credential, createClient, preprod} from "@evolution-sdk/evolution" const client = createClient({ - network: "preprod", + chain: preprod, provider: { type: "blockfrost", baseUrl: "https://cardano-preprod.blockfrost.io/api/v0", projectId: process.env.BLOCKFROST_API_KEY! }, wallet: { type: "seed", mnemonic: process.env.WALLET_MNEMONIC!, accountIndex: 0 } }) @@ -118,10 +118,10 @@ await signed.submit() Committee members keep their cold credential offline and authorize a hot credential for day-to-day signing: ```typescript twoslash -import { Credential, createClient } from "@evolution-sdk/evolution" +import { Credential, createClient, preprod} from "@evolution-sdk/evolution" const client = createClient({ - network: "preprod", + chain: preprod, provider: { type: "blockfrost", baseUrl: "https://cardano-preprod.blockfrost.io/api/v0", projectId: process.env.BLOCKFROST_API_KEY! }, wallet: { type: "seed", mnemonic: process.env.WALLET_MNEMONIC!, accountIndex: 0 } }) @@ -141,10 +141,10 @@ await signed.submit() ### Resign from Committee ```typescript twoslash -import { Anchor, Credential, createClient } from "@evolution-sdk/evolution" +import { Anchor, Credential, createClient, preprod} from "@evolution-sdk/evolution" const client = createClient({ - network: "preprod", + chain: preprod, provider: { type: "blockfrost", baseUrl: "https://cardano-preprod.blockfrost.io/api/v0", projectId: process.env.BLOCKFROST_API_KEY! }, wallet: { type: "seed", mnemonic: process.env.WALLET_MNEMONIC!, accountIndex: 0 } }) diff --git a/docs/content/docs/governance/index.mdx b/docs/content/docs/governance/index.mdx index 307f1e49..63544cb6 100644 --- a/docs/content/docs/governance/index.mdx +++ b/docs/content/docs/governance/index.mdx @@ -21,10 +21,10 @@ Evolution SDK supports Cardano's Conway-era governance system (CIP-1694). Regist ## Quick Example ```typescript twoslash -import { Credential, createClient } from "@evolution-sdk/evolution" +import { Credential, createClient, preprod} from "@evolution-sdk/evolution" const client = createClient({ - network: "preprod", + chain: preprod, provider: { type: "blockfrost", baseUrl: "https://cardano-preprod.blockfrost.io/api/v0", projectId: process.env.BLOCKFROST_API_KEY! }, wallet: { type: "seed", mnemonic: process.env.WALLET_MNEMONIC!, accountIndex: 0 } }) @@ -46,10 +46,10 @@ await signed.submit() All governance operations support script-controlled credentials. Provide a redeemer when the credential is a script hash: ```typescript twoslash -import { Credential, Data, createClient } from "@evolution-sdk/evolution" +import { Credential, Data, createClient, preprod} from "@evolution-sdk/evolution" const client = createClient({ - network: "preprod", + chain: preprod, provider: { type: "blockfrost", baseUrl: "https://cardano-preprod.blockfrost.io/api/v0", projectId: process.env.BLOCKFROST_API_KEY! }, wallet: { type: "seed", mnemonic: process.env.WALLET_MNEMONIC!, accountIndex: 0 } }) diff --git a/docs/content/docs/governance/proposals.mdx b/docs/content/docs/governance/proposals.mdx index 00deb809..73d0470b 100644 --- a/docs/content/docs/governance/proposals.mdx +++ b/docs/content/docs/governance/proposals.mdx @@ -10,10 +10,10 @@ Governance proposals submit actions for the community to vote on. The deposit is ## Submitting a Proposal ```typescript twoslash -import { Anchor, GovernanceAction, RewardAccount, createClient } from "@evolution-sdk/evolution" +import { Anchor, GovernanceAction, RewardAccount, createClient, preprod} from "@evolution-sdk/evolution" const client = createClient({ - network: "preprod", + chain: preprod, provider: { type: "blockfrost", baseUrl: "https://cardano-preprod.blockfrost.io/api/v0", projectId: process.env.BLOCKFROST_API_KEY! }, wallet: { type: "seed", mnemonic: process.env.WALLET_MNEMONIC!, accountIndex: 0 } }) @@ -54,10 +54,10 @@ The `govActionDeposit` is deducted automatically during transaction balancing. Submit multiple proposals in a single transaction by chaining `.propose()`: ```typescript twoslash -import { Anchor, GovernanceAction, RewardAccount, createClient } from "@evolution-sdk/evolution" +import { Anchor, GovernanceAction, RewardAccount, createClient, preprod} from "@evolution-sdk/evolution" const client = createClient({ - network: "preprod", + chain: preprod, provider: { type: "blockfrost", baseUrl: "https://cardano-preprod.blockfrost.io/api/v0", projectId: process.env.BLOCKFROST_API_KEY! }, wallet: { type: "seed", mnemonic: process.env.WALLET_MNEMONIC!, accountIndex: 0 } }) diff --git a/docs/content/docs/governance/vote-delegation.mdx b/docs/content/docs/governance/vote-delegation.mdx index 61ad6246..8c4fab45 100644 --- a/docs/content/docs/governance/vote-delegation.mdx +++ b/docs/content/docs/governance/vote-delegation.mdx @@ -10,10 +10,10 @@ In the Conway era, ADA holders can delegate their governance voting power to a D ## Delegate to a DRep ```typescript twoslash -import { Credential, DRep, createClient } from "@evolution-sdk/evolution" +import { Credential, DRep, createClient, preprod} from "@evolution-sdk/evolution" const client = createClient({ - network: "preprod", + chain: preprod, provider: { type: "blockfrost", baseUrl: "https://cardano-preprod.blockfrost.io/api/v0", projectId: process.env.BLOCKFROST_API_KEY! }, wallet: { type: "seed", mnemonic: process.env.WALLET_MNEMONIC!, accountIndex: 0 } }) @@ -43,10 +43,10 @@ Instead of delegating to a specific DRep, you can choose a built-in option: | **AlwaysNoConfidence** | Your power always counts as "no confidence" in the committee | ```typescript twoslash -import { Credential, DRep, createClient } from "@evolution-sdk/evolution" +import { Credential, DRep, createClient, preprod} from "@evolution-sdk/evolution" const client = createClient({ - network: "preprod", + chain: preprod, provider: { type: "blockfrost", baseUrl: "https://cardano-preprod.blockfrost.io/api/v0", projectId: process.env.BLOCKFROST_API_KEY! }, wallet: { type: "seed", mnemonic: process.env.WALLET_MNEMONIC!, accountIndex: 0 } }) @@ -71,10 +71,10 @@ await signed.submit() Use `delegateToPoolAndDRep` to delegate both in a single certificate: ```typescript twoslash -import { Credential, DRep, createClient } from "@evolution-sdk/evolution" +import { Credential, DRep, createClient, preprod} from "@evolution-sdk/evolution" const client = createClient({ - network: "preprod", + chain: preprod, provider: { type: "blockfrost", baseUrl: "https://cardano-preprod.blockfrost.io/api/v0", projectId: process.env.BLOCKFROST_API_KEY! }, wallet: { type: "seed", mnemonic: process.env.WALLET_MNEMONIC!, accountIndex: 0 } }) @@ -101,10 +101,10 @@ await signed.submit() For new stake credentials, combine registration with vote delegation: ```typescript twoslash -import { Credential, DRep, createClient } from "@evolution-sdk/evolution" +import { Credential, DRep, createClient, preprod} from "@evolution-sdk/evolution" const client = createClient({ - network: "preprod", + chain: preprod, provider: { type: "blockfrost", baseUrl: "https://cardano-preprod.blockfrost.io/api/v0", projectId: process.env.BLOCKFROST_API_KEY! }, wallet: { type: "seed", mnemonic: process.env.WALLET_MNEMONIC!, accountIndex: 0 } }) diff --git a/docs/content/docs/governance/voting.mdx b/docs/content/docs/governance/voting.mdx index aed35285..c7f7ced9 100644 --- a/docs/content/docs/governance/voting.mdx +++ b/docs/content/docs/governance/voting.mdx @@ -10,10 +10,10 @@ DReps, Constitutional Committee members, and Stake Pool Operators can vote on go ## Casting a Vote ```typescript twoslash -import { VotingProcedures, createClient } from "@evolution-sdk/evolution" +import { VotingProcedures, createClient, preprod} from "@evolution-sdk/evolution" const client = createClient({ - network: "preprod", + chain: preprod, provider: { type: "blockfrost", baseUrl: "https://cardano-preprod.blockfrost.io/api/v0", projectId: process.env.BLOCKFROST_API_KEY! }, wallet: { type: "seed", mnemonic: process.env.WALLET_MNEMONIC!, accountIndex: 0 } }) @@ -42,10 +42,10 @@ await signed.submit() For DReps or Committee members with script credentials, provide a redeemer: ```typescript twoslash -import { Data, VotingProcedures, createClient } from "@evolution-sdk/evolution" +import { Data, VotingProcedures, createClient, preprod} from "@evolution-sdk/evolution" const client = createClient({ - network: "preprod", + chain: preprod, provider: { type: "blockfrost", baseUrl: "https://cardano-preprod.blockfrost.io/api/v0", projectId: process.env.BLOCKFROST_API_KEY! }, wallet: { type: "seed", mnemonic: process.env.WALLET_MNEMONIC!, accountIndex: 0 } }) diff --git a/docs/content/docs/introduction/getting-started.mdx b/docs/content/docs/introduction/getting-started.mdx index 9c8350da..727281f9 100644 --- a/docs/content/docs/introduction/getting-started.mdx +++ b/docs/content/docs/introduction/getting-started.mdx @@ -27,10 +27,10 @@ npm install @evolution-sdk/evolution ### 2. Create a Wallet Instantiate a wallet using your seed phrase or private keys: ```ts twoslash -import { Address, Assets, createClient } from "@evolution-sdk/evolution"; +import { Address, Assets, createClient, preprod} from "@evolution-sdk/evolution"; const client = createClient({ - network: "preprod", + chain: preprod, wallet: { type: "seed", mnemonic: "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about", @@ -44,10 +44,10 @@ See [Creating Wallets](/docs/wallets) for all wallet types. ### 3. Attach a Provider Connect to the blockchain via a provider: ```ts twoslash -import { Address, Assets, createClient } from "@evolution-sdk/evolution"; +import { Address, Assets, createClient, preprod} from "@evolution-sdk/evolution"; const client = createClient({ - network: "preprod", + chain: preprod, provider: { type: "blockfrost", baseUrl: "https://cardano-preprod.blockfrost.io/api/v0", @@ -66,10 +66,10 @@ Learn more in [Clients](/docs/clients) and [Providers](/docs/clients/providers). ### 4. Build a Transaction Construct your first payment: ```ts twoslash -import { Address, Assets, createClient } from "@evolution-sdk/evolution"; +import { Address, Assets, createClient, preprod} from "@evolution-sdk/evolution"; const client = createClient({ - network: "preprod", + chain: preprod, provider: { type: "blockfrost", baseUrl: "https://cardano-preprod.blockfrost.io/api/v0", @@ -97,10 +97,10 @@ Details in [Transactions](/docs/transactions). ### 5. Sign & Submit Sign with your wallet and send to the network: ```ts twoslash -import { Address, Assets, createClient } from "@evolution-sdk/evolution"; +import { Address, Assets, createClient, preprod} from "@evolution-sdk/evolution"; const client = createClient({ - network: "preprod", + chain: preprod, provider: { type: "blockfrost", baseUrl: "https://cardano-preprod.blockfrost.io/api/v0", diff --git a/docs/content/docs/introduction/installation.mdx b/docs/content/docs/introduction/installation.mdx index 185743c9..41b66ab1 100644 --- a/docs/content/docs/introduction/installation.mdx +++ b/docs/content/docs/introduction/installation.mdx @@ -56,10 +56,10 @@ Most modern frameworks (React, Vue, Svelte) bundle Evolution SDK without issues. Test that everything is working: ```ts twoslash -import { createClient } from "@evolution-sdk/evolution"; +import { createClient, preprod} from "@evolution-sdk/evolution"; const client = createClient({ - network: "preprod", + chain: preprod, provider: { type: "blockfrost", baseUrl: "https://cardano-preprod.blockfrost.io/api/v0", diff --git a/docs/content/docs/introduction/migration-from-lucid.mdx b/docs/content/docs/introduction/migration-from-lucid.mdx index c54ea01a..ed4bed11 100644 --- a/docs/content/docs/introduction/migration-from-lucid.mdx +++ b/docs/content/docs/introduction/migration-from-lucid.mdx @@ -36,10 +36,10 @@ const lucid = await Lucid.new(blockfrostProvider, "Preprod"); **Evolution SDK:** ```ts twoslash -import { Address, Assets, createClient } from "@evolution-sdk/evolution"; +import { Address, Assets, createClient, preprod} from "@evolution-sdk/evolution"; const client = createClient({ - network: "preprod", + chain: preprod, provider: { type: "blockfrost", baseUrl: "https://cardano-preprod.blockfrost.io/api/v0", @@ -65,10 +65,10 @@ lucid **Evolution SDK:** ```ts twoslash -import { Address, Assets, createClient } from "@evolution-sdk/evolution"; +import { Address, Assets, createClient, preprod} from "@evolution-sdk/evolution"; const client = createClient({ - network: "preprod", + chain: preprod, provider: { type: "blockfrost", baseUrl: "https://cardano-preprod.blockfrost.io/api/v0", @@ -97,7 +97,7 @@ Here are the typical changes you'll make throughout your codebase: | Lucid | Evolution SDK | |-------|---------------| -| `Lucid.new(provider, network)` | `createClient({ network, provider, wallet })` | +| `Lucid.new(provider, network)` | `createClient({ chain, provider, wallet })` | | `.payToAddress(addr, assets)` | `.payToAddress({ address, assets })` | | `.complete()` | `.build()` | | `.signWithWallet()` | `tx.sign()` | diff --git a/docs/content/docs/modules/CBOR.mdx b/docs/content/docs/modules/CBOR.mdx index f42af70b..2d0ae087 100644 --- a/docs/content/docs/modules/CBOR.mdx +++ b/docs/content/docs/modules/CBOR.mdx @@ -20,17 +20,41 @@ parent: Modules - [CML_DATA_DEFAULT_OPTIONS](#cml_data_default_options) - [CML_DEFAULT_OPTIONS](#cml_default_options) - [STRUCT_FRIENDLY_OPTIONS](#struct_friendly_options) +- [decoding](#decoding) + - [decodeItemWithOffset](#decodeitemwithoffset) - [encoding](#encoding) - [toCBORBytes](#tocborbytes) + - [toCBORBytesWithFormat](#tocborbyteswithformat) - [toCBORHex](#tocborhex) + - [toCBORHexWithFormat](#tocborhexwithformat) +- [equality](#equality) + - [equals](#equals) - [errors](#errors) - [CBORError (class)](#cborerror-class) - [model](#model) + - [BoundedBytes](#boundedbytes) + - [ByteSize (type alias)](#bytesize-type-alias) - [CBOR (type alias)](#cbor-type-alias) + - [CBORFormat (type alias)](#cborformat-type-alias) + - [CBORFormat (namespace)](#cborformat-namespace) + - [Array (type alias)](#array-type-alias) + - [Bytes (type alias)](#bytes-type-alias) + - [Map (type alias)](#map-type-alias) + - [NInt (type alias)](#nint-type-alias) + - [Simple (type alias)](#simple-type-alias) + - [Tag (type alias)](#tag-type-alias) + - [Text (type alias)](#text-type-alias) + - [UInt (type alias)](#uint-type-alias) - [CodecOptions (type alias)](#codecoptions-type-alias) + - [DecodedWithFormat (type alias)](#decodedwithformat-type-alias) + - [LengthEncoding (type alias)](#lengthencoding-type-alias) + - [StringEncoding (type alias)](#stringencoding-type-alias) - [parsing](#parsing) - [fromCBORBytes](#fromcborbytes) + - [fromCBORBytesWithFormat](#fromcborbyteswithformat) - [fromCBORHex](#fromcborhex) + - [fromCBORHexWithFormat](#fromcborhexwithformat) + - [internalDecodeWithFormatSync](#internaldecodewithformatsync) - [schemas](#schemas) - [CBORSchema](#cborschema) - [FromBytes](#frombytes) @@ -68,14 +92,17 @@ parent: Modules ## AIKEN_DEFAULT_OPTIONS -Aiken-compatible CBOR encoding options +Aiken-compatible CBOR encoding options. -Matches the encoding used by Aiken's cbor.serialise(): +Matches the encoding produced by `cbor.serialise()` in Aiken: -- Indefinite-length arrays (9f...ff) +- Indefinite-length arrays (`9f...ff`) - Maps encoded as arrays of pairs (not CBOR maps) -- Strings as bytearrays (major type 2, not 3) -- Constructor tags: 121-127 for indices 0-6, then 1280+ for 7+ +- Strings as byte arrays (major type 2, not 3) +- Constructor tags: 121–127 for indices 0–6, then 1280+ for 7+ + +PlutusData byte strings are chunked per the Conway `bounded_bytes` rule +via the `BoundedBytes` CBOR node, independent of these codec options. **Signature** @@ -169,7 +196,11 @@ Added in v1.0.0 ## CML_DATA_DEFAULT_OPTIONS -Default CBOR encoding option for Data +Default CBOR encoding options for PlutusData. + +Uses indefinite-length arrays and maps. The `bounded_bytes` constraint +(Conway CDDL: byte strings ≤ 64 bytes) is enforced at the data-type layer +via the `BoundedBytes` CBOR node, independent of these codec options. **Signature** @@ -203,6 +234,25 @@ export declare const STRUCT_FRIENDLY_OPTIONS: CodecOptions Added in v2.0.0 +# decoding + +## decodeItemWithOffset + +Decode a single CBOR item at a given byte offset, returning the decoded value and the new offset. +Useful for extracting raw byte slices from CBOR-encoded data without re-encoding. + +**Signature** + +```ts +export declare const decodeItemWithOffset: ( + data: Uint8Array, + offset: number, + options?: CodecOptions +) => { item: CBOR; newOffset: number } +``` + +Added in v2.0.0 + # encoding ## toCBORBytes @@ -217,6 +267,18 @@ export declare const toCBORBytes: (value: CBOR, options?: CodecOptions) => Uint8 Added in v1.0.0 +## toCBORBytesWithFormat + +Convert a CBOR value to CBOR bytes using an explicit root format tree. + +**Signature** + +```ts +export declare const toCBORBytesWithFormat: (value: CBOR, format: CBORFormat) => Uint8Array +``` + +Added in v2.0.0 + ## toCBORHex Convert a CBOR value to CBOR hex string. @@ -229,6 +291,36 @@ export declare const toCBORHex: (value: CBOR, options?: CodecOptions) => string Added in v1.0.0 +## toCBORHexWithFormat + +Convert a CBOR value to CBOR hex string using an explicit root format tree. + +**Signature** + +```ts +export declare const toCBORHexWithFormat: (value: CBOR, format: CBORFormat) => string +``` + +Added in v2.0.0 + +# equality + +## equals + +Schema-derived structural equivalence for CBOR values. +Handles Uint8Array, Array, Map, Tag and all primitives via the +recursive CBORSchema definition — no hand-rolled comparison needed. + +Derived once at module init; at call time it's a plain function. + +**Signature** + +```ts +export declare const equals: (a: CBOR, b: CBOR) => boolean +``` + +Added in v2.0.0 + # errors ## CBORError (class) @@ -245,6 +337,41 @@ Added in v1.0.0 # model +## BoundedBytes + +`BoundedBytes` CBOR node — represents a PlutusData byte string that must comply +with the Conway CDDL constraint `bounded_bytes = bytes .size (0..64)`. + +The encoding rule is unconditional and options-independent: + +- ≤ 64 bytes → definite-length CBOR bytes +- > 64 bytes → indefinite-length 64-byte chunked byte string (`0x5f` + chunks + `0xff`) + +Use `BoundedBytes.make` to construct the node; the encoder handles the rest. + +**Signature** + +```ts +export declare const BoundedBytes: { + readonly make: (bytes: Uint8Array) => CBOR + readonly is: (value: CBOR) => value is { _tag: "BoundedBytes"; bytes: Uint8Array } +} +``` + +Added in v2.0.0 + +## ByteSize (type alias) + +Width of a CBOR integer argument: inline (0), 1-byte, 2-byte, 4-byte, or 8-byte. + +**Signature** + +```ts +export type ByteSize = 0 | 1 | 2 | 4 | 8 +``` + +Added in v2.0.0 + ## CBOR (type alias) Type representing a CBOR value with simplified, non-tagged structure @@ -263,11 +390,131 @@ export type CBOR = | boolean // boolean values | null // null value | undefined // undefined value - | number + | number // floating point numbers + | { _tag: "BoundedBytes"; bytes: Uint8Array } ``` Added in v1.0.0 +## CBORFormat (type alias) + +Tagged discriminated union capturing how each CBOR node was originally +serialized. Every variant carries a `_tag` discriminant. Encoding-detail +fields are optional — absent means "use canonical / minimal default". + +**Signature** + +```ts +export type CBORFormat = + | CBORFormat.UInt + | CBORFormat.NInt + | CBORFormat.Bytes + | CBORFormat.Text + | CBORFormat.Array + | CBORFormat.Map + | CBORFormat.Tag + | CBORFormat.Simple +``` + +Added in v2.0.0 + +## CBORFormat (namespace) + +Added in v2.0.0 + +### Array (type alias) + +Array (major 4). `length` absent → definite, minimal length header. + +**Signature** + +```ts +export type Array = { + readonly _tag: "array" + readonly length?: LengthEncoding + readonly children: ReadonlyArray +} +``` + +### Bytes (type alias) + +Byte string (major 2). `encoding` absent → definite, minimal length. + +**Signature** + +```ts +export type Bytes = { readonly _tag: "bytes"; readonly encoding?: StringEncoding } +``` + +### Map (type alias) + +Map (major 5). `keyOrder` stores CBOR-encoded key bytes for serializable ordering. + +**Signature** + +```ts +export type Map = { + readonly _tag: "map" + readonly length?: LengthEncoding + readonly keyOrder?: ReadonlyArray + readonly entries: ReadonlyArray +} +``` + +### NInt (type alias) + +Negative integer (major 1). `byteSize` absent → minimal encoding. + +**Signature** + +```ts +export type NInt = { readonly _tag: "nint"; readonly byteSize?: ByteSize } +``` + +### Simple (type alias) + +Simple value or float (major 7). No encoding choices to preserve. + +**Signature** + +```ts +export type Simple = { readonly _tag: "simple" } +``` + +### Tag (type alias) + +Tag (major 6). `width` absent → minimal tag header. + +**Signature** + +```ts +export type Tag = { + readonly _tag: "tag" + readonly width?: ByteSize + readonly child: CBORFormat +} +``` + +### Text (type alias) + +Text string (major 3). `encoding` absent → definite, minimal length. + +**Signature** + +```ts +export type Text = { readonly _tag: "text"; readonly encoding?: StringEncoding } +``` + +### UInt (type alias) + +Unsigned integer (major 0). `byteSize` absent → minimal encoding. + +**Signature** + +```ts +export type UInt = { readonly _tag: "uint"; readonly byteSize?: ByteSize } +``` + ## CodecOptions (type alias) CBOR codec configuration options @@ -295,6 +542,50 @@ export type CodecOptions = Added in v1.0.0 +## DecodedWithFormat (type alias) + +Decoded value paired with its captured root format tree. + +**Signature** + +```ts +export type DecodedWithFormat = { + value: A + format: CBORFormat +} +``` + +Added in v2.0.0 + +## LengthEncoding (type alias) + +Container length encoding style captured during decode. + +**Signature** + +```ts +export type LengthEncoding = { readonly tag: "indefinite" } | { readonly tag: "definite"; readonly byteSize: ByteSize } +``` + +Added in v2.0.0 + +## StringEncoding (type alias) + +Byte/text string encoding style captured during decode. + +**Signature** + +```ts +export type StringEncoding = + | { readonly tag: "definite"; readonly byteSize: ByteSize } + | { + readonly tag: "indefinite" + readonly chunks: ReadonlyArray<{ readonly length: number; readonly byteSize: ByteSize }> + } +``` + +Added in v2.0.0 + # parsing ## fromCBORBytes @@ -309,6 +600,18 @@ export declare const fromCBORBytes: (bytes: Uint8Array, options?: CodecOptions) Added in v1.0.0 +## fromCBORBytesWithFormat + +Parse a CBOR value from CBOR bytes and return the root format tree. + +**Signature** + +```ts +export declare const fromCBORBytesWithFormat: (bytes: Uint8Array) => DecodedWithFormat +``` + +Added in v2.0.0 + ## fromCBORHex Parse a CBOR value from CBOR hex string. @@ -321,6 +624,30 @@ export declare const fromCBORHex: (hex: string, options?: CodecOptions) => CBOR Added in v1.0.0 +## fromCBORHexWithFormat + +Parse a CBOR value from CBOR hex string and return the root format tree. + +**Signature** + +```ts +export declare const fromCBORHexWithFormat: (hex: string) => DecodedWithFormat +``` + +Added in v2.0.0 + +## internalDecodeWithFormatSync + +Decode CBOR bytes and return both the decoded value and the root format tree. + +**Signature** + +```ts +export declare const internalDecodeWithFormatSync: (data: Uint8Array) => DecodedWithFormat +``` + +Added in v2.0.0 + # schemas ## CBORSchema @@ -385,6 +712,7 @@ export declare const match: ( null: () => R undefined: () => R float: (value: number) => R + boundedBytes: (value: Uint8Array) => R } ) => R ``` @@ -524,7 +852,7 @@ export declare const internalDecodeSync: (data: Uint8Array, options?: CodecOptio **Signature** ```ts -export declare const internalEncodeSync: (value: CBOR, options?: CodecOptions) => Uint8Array +export declare const internalEncodeSync: (value: CBOR, options?: CodecOptions, fmt?: CBORFormat) => Uint8Array ``` ## isArray diff --git a/docs/content/docs/modules/Data.mdx b/docs/content/docs/modules/Data.mdx index d693e788..4dd2e1c6 100644 --- a/docs/content/docs/modules/Data.mdx +++ b/docs/content/docs/modules/Data.mdx @@ -180,8 +180,9 @@ Added in v2.0.0 ## equals -Deep structural equality for Plutus Data values. -Handles maps, lists, ints, bytes, and constrs. +Schema-derived structural equality for Plutus Data values. +Handles maps, lists, ints, bytes, and constrs via the +recursive DataSchema definition — no hand-rolled comparison needed. **Signature** diff --git a/docs/content/docs/modules/PrivateKey.mdx b/docs/content/docs/modules/PrivateKey.mdx index dc82ab72..86ddb65f 100644 --- a/docs/content/docs/modules/PrivateKey.mdx +++ b/docs/content/docs/modules/PrivateKey.mdx @@ -13,13 +13,14 @@ parent: Modules - [arbitrary](#arbitrary) - [arbitrary](#arbitrary-1) - [bip32](#bip32) - - [derive](#derive) + - [~~derive~~](#derive) - [bip39](#bip39) - - [fromMnemonic](#frommnemonic) + - [~~fromMnemonic~~](#frommnemonic) - [generateMnemonic](#generatemnemonic) - [validateMnemonic](#validatemnemonic) - [cardano](#cardano) - - [CardanoPath](#cardanopath) + - [~~CardanoPath~~](#cardanopath) + - [fromMnemonicCardano](#frommnemoniccardano) - [cryptography](#cryptography) - [sign](#sign) - [toPublicKey](#topublickey) @@ -70,10 +71,12 @@ Added in v2.0.0 # bip32 -## derive +## ~~derive~~ Derive a child private key using BIP32 path (sync version that throws PrivateKeyError). -All errors are normalized to PrivateKeyError with contextual information. + +**WARNING**: This uses secp256k1 BIP32 derivation (`@scure/bip32`), NOT Cardano's +BIP32-Ed25519. For Cardano key derivation, use `fromMnemonicCardano` instead. **Signature** @@ -85,10 +88,12 @@ Added in v2.0.0 # bip39 -## fromMnemonic +## ~~fromMnemonic~~ Create a PrivateKey from a mnemonic phrase (sync version that throws PrivateKeyError). -All errors are normalized to PrivateKeyError with contextual information. + +**WARNING**: This uses secp256k1 BIP32 derivation (`@scure/bip32`), NOT Cardano's +BIP32-Ed25519. For Cardano key derivation, use `fromMnemonicCardano` instead. **Signature** @@ -124,10 +129,15 @@ Added in v2.0.0 # cardano -## CardanoPath +## ~~CardanoPath~~ Cardano BIP44 derivation path utilities. +**WARNING**: These paths are only useful with BIP32-Ed25519 derivation +(`Bip32PrivateKey`). Using them with `derive` (which uses secp256k1 BIP32) +will produce incorrect keys. Use `fromMnemonicCardano` or +`Bip32PrivateKey.CardanoPath` instead. + **Signature** ```ts @@ -140,6 +150,41 @@ export declare const CardanoPath: { Added in v2.0.0 +## fromMnemonicCardano + +Derive a Cardano payment or stake key from a mnemonic using BIP32-Ed25519. + +This is the correct way to derive Cardano keys from a mnemonic. It uses the +Icarus/V2 BIP32-Ed25519 derivation scheme, matching CML and cardano-cli behavior. + +**Signature** + +```ts +export declare const fromMnemonicCardano: ( + mnemonic: string, + options?: { account?: number; role?: 0 | 2; index?: number; password?: string } +) => PrivateKey +``` + +**Example** + +```ts +import * as PrivateKey from "@evolution-sdk/evolution/PrivateKey" + +const mnemonic = PrivateKey.generateMnemonic() + +// Payment key (default: account 0, index 0) +const paymentKey = PrivateKey.fromMnemonicCardano(mnemonic) + +// Stake key +const stakeKey = PrivateKey.fromMnemonicCardano(mnemonic, { role: 2 }) + +// Custom account/index +const key = PrivateKey.fromMnemonicCardano(mnemonic, { account: 1, index: 3 }) +``` + +Added in v2.0.0 + # cryptography ## sign diff --git a/docs/content/docs/modules/Redeemers.mdx b/docs/content/docs/modules/Redeemers.mdx index 5a6f3892..5292b895 100644 --- a/docs/content/docs/modules/Redeemers.mdx +++ b/docs/content/docs/modules/Redeemers.mdx @@ -12,19 +12,34 @@ parent: Modules - [arbitrary](#arbitrary) - [arbitrary](#arbitrary-1) +- [constructors](#constructors) + - [makeRedeemerMap](#makeredeemermap) - [encoding](#encoding) - [toCBORBytes](#tocborbytes) - [toCBORBytesMap](#tocborbytesmap) - [toCBORHex](#tocborhex) - [toCBORHexMap](#tocborhexmap) - [model](#model) - - [Format (type alias)](#format-type-alias) - - [Redeemers (class)](#redeemers-class) + - [RedeemerArray (class)](#redeemerarray-class) + - [toArray (method)](#toarray-method) - [toJSON (method)](#tojson-method) - [toString (method)](#tostring-method) - [[Inspectable.NodeInspectSymbol] (method)](#inspectablenodeinspectsymbol-method) - [[Equal.symbol] (method)](#equalsymbol-method) - [[Hash.symbol] (method)](#hashsymbol-method) + - [RedeemerKey (type alias)](#redeemerkey-type-alias) + - [RedeemerMap (class)](#redeemermap-class) + - [get (method)](#get-method) + - [toArray (method)](#toarray-method-1) + - [toJSON (method)](#tojson-method-1) + - [toString (method)](#tostring-method-1) + - [[Inspectable.NodeInspectSymbol] (method)](#inspectablenodeinspectsymbol-method-1) + - [[Equal.symbol] (method)](#equalsymbol-method-1) + - [[Hash.symbol] (method)](#hashsymbol-method-1) + - [RedeemerValue (class)](#redeemervalue-class) + - [[Equal.symbol] (method)](#equalsymbol-method-2) + - [[Hash.symbol] (method)](#hashsymbol-method-2) + - [Redeemers (type alias)](#redeemers-type-alias) - [parsing](#parsing) - [fromCBORBytes](#fromcborbytes) - [fromCBORBytesMap](#fromcborbytesmap) @@ -41,6 +56,9 @@ parent: Modules - [FromCDDL](#fromcddl) - [FromMapCDDL](#frommapcddl) - [MapCDDLSchema](#mapcddlschema) + - [Redeemers](#redeemers) +- [utilities](#utilities) + - [keyToString](#keytostring) --- @@ -48,12 +66,26 @@ parent: Modules ## arbitrary -FastCheck arbitrary for Redeemers. +FastCheck arbitrary for Redeemers — generates both map and array variants. **Signature** ```ts -export declare const arbitrary: FastCheck.Arbitrary +export declare const arbitrary: FastCheck.Arbitrary +``` + +Added in v2.0.0 + +# constructors + +## makeRedeemerMap + +Create a `RedeemerMap` from an array of `Redeemer` objects. + +**Signature** + +```ts +export declare const makeRedeemerMap: (redeemers: ReadonlyArray) => RedeemerMap ``` Added in v2.0.0 @@ -62,90 +94,183 @@ Added in v2.0.0 ## toCBORBytes -Encode Redeemers to CBOR bytes (array format). +Encode to CBOR bytes (array format). **Signature** ```ts -export declare const toCBORBytes: (data: Redeemers, options?: CBOR.CodecOptions) => any +export declare const toCBORBytes: (data: RedeemerArray, options?: CBOR.CodecOptions) => any ``` Added in v2.0.0 ## toCBORBytesMap -Encode Redeemers to CBOR bytes (map format). +Encode to CBOR bytes (map format). **Signature** ```ts -export declare const toCBORBytesMap: (data: Redeemers, options?: CBOR.CodecOptions) => any +export declare const toCBORBytesMap: (data: RedeemerMap, options?: CBOR.CodecOptions) => any ``` Added in v2.0.0 ## toCBORHex -Encode Redeemers to CBOR hex string (array format). +Encode to CBOR hex string (array format). **Signature** ```ts -export declare const toCBORHex: (data: Redeemers, options?: CBOR.CodecOptions) => string +export declare const toCBORHex: (data: RedeemerArray, options?: CBOR.CodecOptions) => string ``` Added in v2.0.0 ## toCBORHexMap -Encode Redeemers to CBOR hex string (map format). +Encode to CBOR hex string (map format). **Signature** ```ts -export declare const toCBORHexMap: (data: Redeemers, options?: CBOR.CodecOptions) => string +export declare const toCBORHexMap: (data: RedeemerMap, options?: CBOR.CodecOptions) => string ``` Added in v2.0.0 # model -## Format (type alias) +## RedeemerArray (class) -Encoding format for redeemers collection. +Redeemers in legacy array format. -Conway CDDL supports two formats: +Mirrors the CDDL: ``` -; Flat Array support is included for backwards compatibility and -; will be removed in the next era. It is recommended for tools to -; adopt using a Map instead of Array going forward. -redeemers = - [ + redeemer ] - / { + [tag : redeemer_tag, index : uint .size 4] => [ data : plutus_data, ex_units : ex_units ] } +[ + redeemer ] ``` -- "array": Legacy flat array format - backwards compatible, will be deprecated -- "map": New map format - recommended for Conway+ +Backwards compatible — will be deprecated in the next era. +Prefer `RedeemerMap` for new transactions. **Signature** ```ts -export type Format = "array" | "map" +export declare class RedeemerArray ``` Added in v2.0.0 -## Redeemers (class) +### toArray (method) + +Convert to an array of `Redeemer` objects (identity for array format). -Redeemers collection based on Conway CDDL specification. +**Signature** + +```ts +toArray(): ReadonlyArray +``` -Represents a collection of redeemers that can be encoded in either array or map format. +Added in v2.0.0 + +### toJSON (method) **Signature** ```ts -export declare class Redeemers +toJSON() +``` + +### toString (method) + +**Signature** + +```ts +toString(): string +``` + +### [Inspectable.NodeInspectSymbol] (method) + +**Signature** + +```ts +[Inspectable.NodeInspectSymbol](): unknown +``` + +### [Equal.symbol] (method) + +**Signature** + +```ts +[Equal.symbol](that: unknown): boolean +``` + +### [Hash.symbol] (method) + +**Signature** + +```ts +[Hash.symbol](): number +``` + +## RedeemerKey (type alias) + +A redeemer map key: `[tag, index]`. + +Mirrors the CDDL: `[tag : redeemer_tag, index : uint .size 4]` + +**Signature** + +```ts +export type RedeemerKey = readonly [Redeemer.RedeemerTag, bigint] +``` + +Added in v2.0.0 + +## RedeemerMap (class) + +Redeemers in map format (Conway recommended). + +Mirrors the CDDL exactly: + +``` +{ + [tag : redeemer_tag, index : uint .size 4] => [ data : plutus_data, ex_units : ex_units ] } +``` + +The map is keyed by `[tag, index]` tuples. Note: JS Map uses reference +equality for non-primitive keys, so lookups by tuple won't work — use +`get()` or `toArray()` helpers instead. + +**Signature** + +```ts +export declare class RedeemerMap +``` + +Added in v2.0.0 + +### get (method) + +Look up a redeemer entry by tag and index. + +**Signature** + +```ts +get(tag: Redeemer.RedeemerTag, index: bigint): RedeemerValue | undefined +``` + +Added in v2.0.0 + +### toArray (method) + +Convert to an array of `Redeemer` objects (convenience for consumers). + +**Signature** + +```ts +toArray(): ReadonlyArray ``` Added in v2.0.0 @@ -190,52 +315,94 @@ toString(): string [Hash.symbol](): number ``` +## RedeemerValue (class) + +A redeemer map entry value: `[data, ex_units]`. + +Mirrors the CDDL: `[data : plutus_data, ex_units : ex_units]` + +**Signature** + +```ts +export declare class RedeemerValue +``` + +Added in v2.0.0 + +### [Equal.symbol] (method) + +**Signature** + +```ts +[Equal.symbol](that: unknown): boolean +``` + +### [Hash.symbol] (method) + +**Signature** + +```ts +[Hash.symbol](): number +``` + +## Redeemers (type alias) + +Union type: `RedeemerMap | RedeemerArray` + +**Signature** + +```ts +export type Redeemers = typeof Redeemers.Type +``` + +Added in v2.0.0 + # parsing ## fromCBORBytes -Parse Redeemers from CBOR bytes (array format). +Parse from CBOR bytes (array format). **Signature** ```ts -export declare const fromCBORBytes: (bytes: Uint8Array, options?: CBOR.CodecOptions) => Redeemers +export declare const fromCBORBytes: (bytes: Uint8Array, options?: CBOR.CodecOptions) => RedeemerArray ``` Added in v2.0.0 ## fromCBORBytesMap -Parse Redeemers from CBOR bytes (map format). +Parse from CBOR bytes (map format). **Signature** ```ts -export declare const fromCBORBytesMap: (bytes: Uint8Array, options?: CBOR.CodecOptions) => Redeemers +export declare const fromCBORBytesMap: (bytes: Uint8Array, options?: CBOR.CodecOptions) => RedeemerMap ``` Added in v2.0.0 ## fromCBORHex -Parse Redeemers from CBOR hex string (array format). +Parse from CBOR hex string (array format). **Signature** ```ts -export declare const fromCBORHex: (hex: string, options?: CBOR.CodecOptions) => Redeemers +export declare const fromCBORHex: (hex: string, options?: CBOR.CodecOptions) => RedeemerArray ``` Added in v2.0.0 ## fromCBORHexMap -Parse Redeemers from CBOR hex string (map format). +Parse from CBOR hex string (map format). **Signature** ```ts -export declare const fromCBORHexMap: (hex: string, options?: CBOR.CodecOptions) => Redeemers +export declare const fromCBORHexMap: (hex: string, options?: CBOR.CodecOptions) => RedeemerMap ``` Added in v2.0.0 @@ -244,9 +411,7 @@ Added in v2.0.0 ## ArrayCDDLSchema -CDDL schema for Redeemers in array format. - -`redeemers = [ + redeemer ]` +CDDL schema for array format: `[ + redeemer ]` **Signature** @@ -267,19 +432,16 @@ Added in v2.0.0 ## CDDLSchema -Default CDDL schema for Redeemers (array format). +Default CDDL schema (map format — Conway recommended). **Signature** ```ts -export declare const CDDLSchema: Schema.Array$< - Schema.Tuple< - [ - Schema.SchemaClass, - Schema.SchemaClass, - Schema.Schema, - Schema.Tuple2 - ] +export declare const CDDLSchema: Schema.MapFromSelf< + Schema.Tuple2, + Schema.Tuple2< + Schema.Schema, + Schema.Tuple2 > > ``` @@ -288,7 +450,7 @@ Added in v2.0.0 ## FromArrayCDDL -CDDL transformation schema for Redeemers array format. +CDDL transformation for array format → `RedeemerArray`. **Signature** @@ -304,7 +466,7 @@ export declare const FromArrayCDDL: Schema.transformOrFail< ] > >, - Schema.SchemaClass, + Schema.SchemaClass, never > ``` @@ -313,7 +475,7 @@ Added in v2.0.0 ## FromCBORBytes -CBOR bytes transformation schema for Redeemers (array format). +CBOR bytes schema for array format. **Signature** @@ -337,7 +499,7 @@ export declare const FromCBORBytes: ( ] > >, - Schema.SchemaClass, + Schema.SchemaClass, never > > @@ -347,7 +509,7 @@ Added in v2.0.0 ## FromCBORBytesMap -CBOR bytes transformation schema for Redeemers (map format). +CBOR bytes schema for map format. **Signature** @@ -361,14 +523,14 @@ export declare const FromCBORBytesMap: ( never >, Schema.transformOrFail< - Schema.Map$< + Schema.MapFromSelf< Schema.Tuple2, Schema.Tuple2< Schema.Schema, Schema.Tuple2 > >, - Schema.SchemaClass, + Schema.SchemaClass, never > > @@ -378,7 +540,7 @@ Added in v2.0.0 ## FromCBORHex -CBOR hex transformation schema for Redeemers (array format). +CBOR hex schema for array format. **Signature** @@ -404,7 +566,7 @@ export declare const FromCBORHex: ( ] > >, - Schema.SchemaClass, + Schema.SchemaClass, never > > @@ -415,7 +577,7 @@ Added in v2.0.0 ## FromCBORHexMap -CBOR hex transformation schema for Redeemers (map format). +CBOR hex schema for map format. **Signature** @@ -431,14 +593,14 @@ export declare const FromCBORHexMap: ( never >, Schema.transformOrFail< - Schema.Map$< + Schema.MapFromSelf< Schema.Tuple2, Schema.Tuple2< Schema.Schema, Schema.Tuple2 > >, - Schema.SchemaClass, + Schema.SchemaClass, never > > @@ -449,23 +611,20 @@ Added in v2.0.0 ## FromCDDL -Default CDDL transformation (array format). +Default CDDL transformation (map format). **Signature** ```ts export declare const FromCDDL: Schema.transformOrFail< - Schema.Array$< - Schema.Tuple< - [ - Schema.SchemaClass, - Schema.SchemaClass, - Schema.Schema, - Schema.Tuple2 - ] + Schema.MapFromSelf< + Schema.Tuple2, + Schema.Tuple2< + Schema.Schema, + Schema.Tuple2 > >, - Schema.SchemaClass, + Schema.SchemaClass, never > ``` @@ -474,20 +633,20 @@ Added in v2.0.0 ## FromMapCDDL -CDDL transformation schema for Redeemers map format. +CDDL transformation for map format → `RedeemerMap`. **Signature** ```ts export declare const FromMapCDDL: Schema.transformOrFail< - Schema.Map$< + Schema.MapFromSelf< Schema.Tuple2, Schema.Tuple2< Schema.Schema, Schema.Tuple2 > >, - Schema.SchemaClass, + Schema.SchemaClass, never > ``` @@ -496,14 +655,16 @@ Added in v2.0.0 ## MapCDDLSchema -CDDL schema for Redeemers in map format. +CDDL schema for map format: `{ + [tag, index] => [data, ex_units] }` -`{ + [tag, index] => [data, ex_units] }` +Uses `MapFromSelf` (not `Map`) so the Encoded type is a JS Map — matching +how `CBOR.FromBytes` represents CBOR major-type-5 maps at runtime. +This is the same pattern used by Withdrawals, Mint, MultiAsset, CostModel. **Signature** ```ts -export declare const MapCDDLSchema: Schema.Map$< +export declare const MapCDDLSchema: Schema.MapFromSelf< Schema.Tuple2, Schema.Tuple2< Schema.Schema, @@ -513,3 +674,30 @@ export declare const MapCDDLSchema: Schema.Map$< ``` Added in v2.0.0 + +## Redeemers + +Union schema for redeemers — accepts either map or array format. +Follows the Credential pattern: `Credential = Union(KeyHash, ScriptHash)`. + +**Signature** + +```ts +export declare const Redeemers: Schema.Union<[typeof RedeemerMap, typeof RedeemerArray]> +``` + +Added in v2.0.0 + +# utilities + +## keyToString + +Create a string key from a RedeemerKey for lookup convenience. + +**Signature** + +```ts +export declare const keyToString: ([tag, index]: RedeemerKey) => string +``` + +Added in v2.0.0 diff --git a/docs/content/docs/modules/TSchema.mdx b/docs/content/docs/modules/TSchema.mdx index 99a264bb..422bbacf 100644 --- a/docs/content/docs/modules/TSchema.mdx +++ b/docs/content/docs/modules/TSchema.mdx @@ -18,6 +18,7 @@ parent: Modules - [schemas](#schemas) - [ByteArray](#bytearray) - [Integer](#integer) + - [PlutusData](#plutusdata) - [utils](#utils) - [Array](#array) - [Array (interface)](#array-interface) @@ -32,6 +33,7 @@ parent: Modules - [Map (interface)](#map-interface) - [NullOr](#nullor) - [NullOr (interface)](#nullor-interface) + - [PlutusData (interface)](#plutusdata-interface) - [Struct](#struct) - [Struct (interface)](#struct-interface) - [StructOptions (interface)](#structoptions-interface) @@ -133,6 +135,21 @@ export declare const Integer: Integer Added in v2.0.0 +## PlutusData + +Opaque PlutusData schema for use inside TSchema combinators. +Represents an arbitrary PlutusData value that passes through encoding unchanged. + +Use this when a field can hold any PlutusData without a specific schema. + +**Signature** + +```ts +export declare const PlutusData: PlutusData +``` + +Added in v2.0.0 + # utils ## Array @@ -298,6 +315,14 @@ export interface NullOr extends Schema.transform, Schema.NullOr> {} ``` +## PlutusData (interface) + +**Signature** + +```ts +export interface PlutusData extends Schema.Schema {} +``` + ## Struct Creates a schema for struct types using Plutus Data Constructor diff --git a/docs/content/docs/modules/Transaction.mdx b/docs/content/docs/modules/Transaction.mdx index dee0f686..f595f3fd 100644 --- a/docs/content/docs/modules/Transaction.mdx +++ b/docs/content/docs/modules/Transaction.mdx @@ -10,6 +10,13 @@ parent: Modules

Table of contents

+- [encoding](#encoding) + - [addVKeyWitnesses](#addvkeywitnesses) + - [addVKeyWitnessesBytes](#addvkeywitnessesbytes) + - [addVKeyWitnessesHex](#addvkeywitnesseshex) + - [extractBodyBytes](#extractbodybytes) + - [toCBORBytesWithFormat](#tocborbyteswithformat) + - [toCBORHexWithFormat](#tocborhexwithformat) - [model](#model) - [Transaction (class)](#transaction-class) - [toJSON (method)](#tojson-method) @@ -17,6 +24,9 @@ parent: Modules - [[Inspectable.NodeInspectSymbol] (method)](#inspectablenodeinspectsymbol-method) - [[Equal.symbol] (method)](#equalsymbol-method) - [[Hash.symbol] (method)](#hashsymbol-method) +- [parsing](#parsing) + - [fromCBORBytesWithFormat](#fromcborbyteswithformat) + - [fromCBORHexWithFormat](#fromcborhexwithformat) - [utils](#utils) - [CDDLSchema](#cddlschema) - [FromCBORBytes](#fromcborbytes) @@ -30,6 +40,102 @@ parent: Modules --- +# encoding + +## addVKeyWitnesses + +Add VKey witnesses to a transaction at the domain level. + +This creates a new Transaction with the additional witnesses merged in. +All encoding metadata (body bytes, redeemers format, witness map structure) +is preserved so that txId and scriptDataHash remain stable. + +**Signature** + +```ts +export declare const addVKeyWitnesses: ( + tx: Transaction, + witnesses: ReadonlyArray +) => Transaction +``` + +Added in v2.0.0 + +## addVKeyWitnessesBytes + +Merge wallet vkey witnesses into a transaction at the raw CBOR byte level. + +Works like CML: the entire transaction byte stream is preserved except for +the vkey witnesses value in the witness set map. Body, redeemers, datums, +scripts, isValid, auxiliaryData, and map entry ordering stay byte-for-byte +identical — preserving both the txId and scriptDataHash. + +**Signature** + +```ts +export declare const addVKeyWitnessesBytes: ( + txBytes: Uint8Array, + walletWitnessSetBytes: Uint8Array, + options?: CBOR.CodecOptions +) => Uint8Array +``` + +Added in v2.0.0 + +## addVKeyWitnessesHex + +Hex variant of `addVKeyWitnessesBytes`. + +**Signature** + +```ts +export declare const addVKeyWitnessesHex: ( + txHex: string, + walletWitnessSetHex: string, + options?: CBOR.CodecOptions +) => string +``` + +Added in v2.0.0 + +## extractBodyBytes + +Extract the original body bytes from a raw transaction CBOR byte array. +A Cardano transaction is a 4-element CBOR array: `[body, witnessSet, isValid, auxiliaryData]`. +This returns the raw body bytes without decoding/re-encoding, preserving the exact CBOR encoding. + +**Signature** + +```ts +export declare const extractBodyBytes: (txBytes: Uint8Array) => Uint8Array +``` + +Added in v2.0.0 + +## toCBORBytesWithFormat + +Convert a Transaction to CBOR bytes using an explicit root format tree. + +**Signature** + +```ts +export declare const toCBORBytesWithFormat: (data: Transaction, format: CBOR.CBORFormat) => Uint8Array +``` + +Added in v2.0.0 + +## toCBORHexWithFormat + +Convert a Transaction to CBOR hex string using an explicit root format tree. + +**Signature** + +```ts +export declare const toCBORHexWithFormat: (data: Transaction, format: CBOR.CBORFormat) => string +``` + +Added in v2.0.0 + # model ## Transaction (class) @@ -87,6 +193,32 @@ toString(): string [Hash.symbol](): number ``` +# parsing + +## fromCBORBytesWithFormat + +Parse a Transaction from CBOR bytes and return the root format tree. + +**Signature** + +```ts +export declare const fromCBORBytesWithFormat: (bytes: Uint8Array) => CBOR.DecodedWithFormat +``` + +Added in v2.0.0 + +## fromCBORHexWithFormat + +Parse a Transaction from CBOR hex string and return the root format tree. + +**Signature** + +```ts +export declare const fromCBORHexWithFormat: (hex: string) => CBOR.DecodedWithFormat +``` + +Added in v2.0.0 + # utils ## CDDLSchema @@ -98,13 +230,11 @@ CDDL: transaction = [transaction_body, transaction_witness_set, bool, auxiliary_ **Signature** ```ts -export declare const CDDLSchema: Schema.Tuple< - [ - Schema.MapFromSelf>, - Schema.MapFromSelf>, - typeof Schema.Boolean, - Schema.Schema - ] +export declare const CDDLSchema: Schema.declare< + readonly [Map, Map, boolean, CBOR.CBOR], + readonly [Map, Map, boolean, CBOR.CBOR], + readonly [], + never > ``` @@ -124,13 +254,11 @@ export declare const FromCBORBytes: ( never >, Schema.transformOrFail< - Schema.Tuple< - [ - Schema.MapFromSelf>, - Schema.MapFromSelf>, - typeof Schema.Boolean, - Schema.Schema - ] + Schema.declare< + readonly [Map, Map, boolean, CBOR.CBOR], + readonly [Map, Map, boolean, CBOR.CBOR], + readonly [], + never >, Schema.SchemaClass, never @@ -157,13 +285,11 @@ export declare const FromCBORHex: ( > >, Schema.transformOrFail< - Schema.Tuple< - [ - Schema.MapFromSelf>, - Schema.MapFromSelf>, - typeof Schema.Boolean, - Schema.Schema - ] + Schema.declare< + readonly [Map, Map, boolean, CBOR.CBOR], + readonly [Map, Map, boolean, CBOR.CBOR], + readonly [], + never >, Schema.SchemaClass, never @@ -179,13 +305,11 @@ Transform between CDDL tuple and Transaction class. ```ts export declare const FromCDDL: Schema.transformOrFail< - Schema.Tuple< - [ - Schema.MapFromSelf>, - Schema.MapFromSelf>, - typeof Schema.Boolean, - Schema.Schema - ] + Schema.declare< + readonly [Map, Map, boolean, CBOR.CBOR], + readonly [Map, Map, boolean, CBOR.CBOR], + readonly [], + never >, Schema.SchemaClass, never diff --git a/docs/content/docs/modules/TransactionBody.mdx b/docs/content/docs/modules/TransactionBody.mdx index 22b89d45..66b7ba0b 100644 --- a/docs/content/docs/modules/TransactionBody.mdx +++ b/docs/content/docs/modules/TransactionBody.mdx @@ -14,9 +14,13 @@ parent: Modules - [arbitrary](#arbitrary-1) - [conversion](#conversion) - [fromCBORBytes](#fromcborbytes) + - [fromCBORBytesWithFormat](#fromcborbyteswithformat) - [fromCBORHex](#fromcborhex) + - [fromCBORHexWithFormat](#fromcborhexwithformat) - [toCBORBytes](#tocborbytes) + - [toCBORBytesWithFormat](#tocborbyteswithformat) - [toCBORHex](#tocborhex) + - [toCBORHexWithFormat](#tocborhexwithformat) - [model](#model) - [TransactionBody (class)](#transactionbody-class) - [toJSON (method)](#tojson-method) @@ -66,6 +70,18 @@ export declare const fromCBORBytes: (bytes: Uint8Array, options?: CBOR.CodecOpti Added in v2.0.0 +## fromCBORBytesWithFormat + +Parse a TransactionBody from CBOR bytes and return the root format tree. + +**Signature** + +```ts +export declare const fromCBORBytesWithFormat: (bytes: Uint8Array) => CBOR.DecodedWithFormat +``` + +Added in v2.0.0 + ## fromCBORHex Convert CBOR hex string to TransactionBody. @@ -78,6 +94,18 @@ export declare const fromCBORHex: (hex: string, options?: CBOR.CodecOptions) => Added in v2.0.0 +## fromCBORHexWithFormat + +Parse a TransactionBody from CBOR hex string and return the root format tree. + +**Signature** + +```ts +export declare const fromCBORHexWithFormat: (hex: string) => CBOR.DecodedWithFormat +``` + +Added in v2.0.0 + ## toCBORBytes Convert TransactionBody to CBOR bytes. @@ -90,6 +118,18 @@ export declare const toCBORBytes: (data: TransactionBody, options?: CBOR.CodecOp Added in v2.0.0 +## toCBORBytesWithFormat + +Convert a TransactionBody to CBOR bytes using an explicit root format tree. + +**Signature** + +```ts +export declare const toCBORBytesWithFormat: (data: TransactionBody, format: CBOR.CBORFormat) => Uint8Array +``` + +Added in v2.0.0 + ## toCBORHex Convert TransactionBody to CBOR hex string. @@ -102,6 +142,18 @@ export declare const toCBORHex: (data: TransactionBody, options?: CBOR.CodecOpti Added in v2.0.0 +## toCBORHexWithFormat + +Convert a TransactionBody to CBOR hex string using an explicit root format tree. + +**Signature** + +```ts +export declare const toCBORHexWithFormat: (data: TransactionBody, format: CBOR.CBORFormat) => string +``` + +Added in v2.0.0 + # model ## TransactionBody (class) @@ -195,10 +247,7 @@ CDDL schema for TransactionBody struct structure. **Signature** ```ts -export declare const CDDLSchema: Schema.MapFromSelf< - typeof Schema.BigIntFromSelf, - Schema.Schema -> +export declare const CDDLSchema: Schema.declare, Map, readonly [], never> ``` Added in v2.0.0 @@ -220,7 +269,7 @@ export declare const FromCBORBytes: ( never >, Schema.transformOrFail< - Schema.MapFromSelf>, + Schema.declare, Map, readonly [], never>, Schema.SchemaClass, never > @@ -249,7 +298,7 @@ export declare const FromCBORHex: ( > >, Schema.transformOrFail< - Schema.MapFromSelf>, + Schema.declare, Map, readonly [], never>, Schema.SchemaClass, never > @@ -266,7 +315,7 @@ Added in v2.0.0 ```ts export declare const FromCDDL: Schema.transformOrFail< - Schema.MapFromSelf>, + Schema.declare, Map, readonly [], never>, Schema.SchemaClass, never > diff --git a/docs/content/docs/modules/TransactionMetadatum.mdx b/docs/content/docs/modules/TransactionMetadatum.mdx index 673bea81..ea3acc42 100644 --- a/docs/content/docs/modules/TransactionMetadatum.mdx +++ b/docs/content/docs/modules/TransactionMetadatum.mdx @@ -20,6 +20,8 @@ parent: Modules - [encoding](#encoding) - [toCBORBytes](#tocborbytes) - [toCBORHex](#tocborhex) +- [equality](#equality) + - [equals](#equals) - [model](#model) - [List (type alias)](#list-type-alias) - [Map (type alias)](#map-type-alias) @@ -37,8 +39,6 @@ parent: Modules - [MapSchema](#mapschema) - [TextSchema](#textschema) - [TransactionMetadatumSchema](#transactionmetadatumschema) -- [utilities](#utilities) - - [equals](#equals) - [utils](#utils) - [arbitrary](#arbitrary) @@ -144,6 +144,22 @@ export declare const toCBORHex: (data: TransactionMetadatum, options?: CBOR.Code Added in v2.0.0 +# equality + +## equals + +Schema-derived structural equality for TransactionMetadatum values. +Handles maps, lists, ints, bytes, and text via the +recursive TransactionMetadatumSchema definition — no hand-rolled comparison needed. + +**Signature** + +```ts +export declare const equals: (a: TransactionMetadatum, b: TransactionMetadatum) => boolean +``` + +Added in v2.0.0 + # model ## List (type alias) @@ -436,20 +452,6 @@ export declare const TransactionMetadatumSchema: Schema.Union< Added in v2.0.0 -# utilities - -## equals - -Check if two TransactionMetadatum instances are equal. - -**Signature** - -```ts -export declare const equals: (a: TransactionMetadatum, b: TransactionMetadatum) => boolean -``` - -Added in v2.0.0 - # utils ## arbitrary diff --git a/docs/content/docs/modules/TransactionWitnessSet.mdx b/docs/content/docs/modules/TransactionWitnessSet.mdx index c310cf0f..6431d15c 100644 --- a/docs/content/docs/modules/TransactionWitnessSet.mdx +++ b/docs/content/docs/modules/TransactionWitnessSet.mdx @@ -18,7 +18,9 @@ parent: Modules - [fromVKeyWitnesses](#fromvkeywitnesses) - [encoding](#encoding) - [toCBORBytes](#tocborbytes) + - [toCBORBytesWithFormat](#tocborbyteswithformat) - [toCBORHex](#tocborhex) + - [toCBORHexWithFormat](#tocborhexwithformat) - [model](#model) - [PlutusScript](#plutusscript) - [TransactionWitnessSet (class)](#transactionwitnessset-class) @@ -35,7 +37,9 @@ parent: Modules - [[Hash.symbol] (method)](#hashsymbol-method-1) - [parsing](#parsing) - [fromCBORBytes](#fromcborbytes) + - [fromCBORBytesWithFormat](#fromcborbyteswithformat) - [fromCBORHex](#fromcborhex) + - [fromCBORHexWithFormat](#fromcborhexwithformat) - [schemas](#schemas) - [CDDLSchema](#cddlschema) - [FromCDDL](#fromcddl) @@ -112,6 +116,18 @@ export declare const toCBORBytes: (data: TransactionWitnessSet, options?: CBOR.C Added in v2.0.0 +## toCBORBytesWithFormat + +Convert a TransactionWitnessSet to CBOR bytes using an explicit root format tree. + +**Signature** + +```ts +export declare const toCBORBytesWithFormat: (data: TransactionWitnessSet, format: CBOR.CBORFormat) => Uint8Array +``` + +Added in v2.0.0 + ## toCBORHex Convert a TransactionWitnessSet to CBOR hex string. @@ -124,6 +140,18 @@ export declare const toCBORHex: (data: TransactionWitnessSet, options?: CBOR.Cod Added in v2.0.0 +## toCBORHexWithFormat + +Convert a TransactionWitnessSet to CBOR hex string using an explicit root format tree. + +**Signature** + +```ts +export declare const toCBORHexWithFormat: (data: TransactionWitnessSet, format: CBOR.CBORFormat) => string +``` + +Added in v2.0.0 + # model ## PlutusScript @@ -302,6 +330,18 @@ export declare const fromCBORBytes: (bytes: Uint8Array, options?: CBOR.CodecOpti Added in v2.0.0 +## fromCBORBytesWithFormat + +Parse a TransactionWitnessSet from CBOR bytes and return the root format tree. + +**Signature** + +```ts +export declare const fromCBORBytesWithFormat: (bytes: Uint8Array) => CBOR.DecodedWithFormat +``` + +Added in v2.0.0 + ## fromCBORHex Parse a TransactionWitnessSet from CBOR hex string. @@ -314,6 +354,18 @@ export declare const fromCBORHex: (hex: string, options?: CBOR.CodecOptions) => Added in v2.0.0 +## fromCBORHexWithFormat + +Parse a TransactionWitnessSet from CBOR hex string and return the root format tree. + +**Signature** + +```ts +export declare const fromCBORHexWithFormat: (hex: string) => CBOR.DecodedWithFormat +``` + +Added in v2.0.0 + # schemas ## CDDLSchema @@ -337,10 +389,7 @@ nonempty_set = #6.258([+ a0]) / [+ a0] **Signature** ```ts -export declare const CDDLSchema: Schema.MapFromSelf< - typeof Schema.BigIntFromSelf, - Schema.Schema -> +export declare const CDDLSchema: Schema.declare, Map, readonly [], never> ``` Added in v2.0.0 @@ -353,7 +402,7 @@ CDDL transformation schema for TransactionWitnessSet. ```ts export declare const FromCDDL: Schema.transformOrFail< - Schema.MapFromSelf>, + Schema.declare, Map, readonly [], never>, Schema.SchemaClass, never > @@ -377,7 +426,7 @@ export declare const FromCBORBytes: ( never >, Schema.transformOrFail< - Schema.MapFromSelf>, + Schema.declare, Map, readonly [], never>, Schema.SchemaClass, never > @@ -401,7 +450,7 @@ export declare const FromCBORHex: ( > >, Schema.transformOrFail< - Schema.MapFromSelf>, + Schema.declare, Map, readonly [], never>, Schema.SchemaClass, never > diff --git a/docs/content/docs/modules/sdk/builders/TransactionBuilder.mdx b/docs/content/docs/modules/sdk/builders/TransactionBuilder.mdx index e3b210e5..6f5a0e63 100644 --- a/docs/content/docs/modules/sdk/builders/TransactionBuilder.mdx +++ b/docs/content/docs/modules/sdk/builders/TransactionBuilder.mdx @@ -984,6 +984,9 @@ export interface ProtocolParameters { /** Price per CPU step for script execution (optional, for ExUnits cost calculation) */ priceStep?: number + /** Cost per byte for reference scripts (Conway-era, default 44) */ + minFeeRefScriptCostPerByte?: number + // Future fields for advanced features: // maxBlockHeaderSize?: number // maxTxExecutionUnits?: ExUnits @@ -1735,12 +1738,9 @@ export interface BuildOptions { /** * Format for encoding redeemers in the script data hash. * - * - `"array"` (DEFAULT): Conway-era format, redeemers encoded as array - * - `"map"`: Babbage-era format, redeemers encoded as map - * - * Use `"map"` for Babbage compatibility or debugging. + * @deprecated Redeemer format is now determined by the concrete `Redeemers` type + * (`RedeemerMap` or `RedeemerArray`). This option is ignored. * - * @default "array" * @since 2.0.0 */ readonly scriptDataFormat?: "array" | "map" diff --git a/docs/content/docs/modules/sdk/builders/TxBuilderImpl.mdx b/docs/content/docs/modules/sdk/builders/TxBuilderImpl.mdx index cb3f8889..3f1063e8 100644 --- a/docs/content/docs/modules/sdk/builders/TxBuilderImpl.mdx +++ b/docs/content/docs/modules/sdk/builders/TxBuilderImpl.mdx @@ -33,6 +33,7 @@ parent: Modules - [makeTxOutput](#maketxoutput) - [mergeAssetsIntoOutput](#mergeassetsintooutput) - [mergeAssetsIntoUTxO](#mergeassetsintoutxo) + - [tierRefScriptFee](#tierrefscriptfee) - [validation](#validation) - [calculateLeftoverAssets](#calculateleftoverassets) - [validateTransactionBalance](#validatetransactionbalance) @@ -87,7 +88,11 @@ Added in v2.0.0 ## calculateMinimumUtxoLovelace Calculate minimum ADA required for a UTxO based on its actual CBOR size. -Uses the Babbage-era formula: coinsPerUtxoByte \* utxoSize. +Uses the Babbage/Conway-era formula: coinsPerUtxoByte \* (160 + serializedOutputSize). + +The 160-byte constant accounts for the UTxO entry overhead in the ledger state +(transaction hash + index). A lovelace placeholder is used during CBOR encoding +to ensure the coin field width matches the final result. This function creates a temporary TransactionOutput, encodes it to CBOR, and calculates the exact size to determine the minimum lovelace required. @@ -248,18 +253,24 @@ Added in v2.0.0 Calculate reference script fees using tiered pricing. -Reference scripts stored on-chain incur additional fees based on their size: +Matches the Cardano node's `tierRefScriptFee` from Conway ledger: + +- Stride: 25,600 bytes (hardcoded, becomes a protocol param post-Conway) +- Multiplier: 1.2× per tier (hardcoded, becomes a protocol param post-Conway) +- Base cost: `minFeeRefScriptCostPerByte` protocol parameter -- First 25KB: 15 lovelace/byte -- Next 25KB: 25 lovelace/byte -- Next 150KB: 100 lovelace/byte -- Maximum: 200KB total +For each 25,600-byte chunk the price per byte increases by 1.2×. +The final (partial) chunk is charged proportionally. Result is `floor(total)`. + +The Cardano node sums scriptRef sizes from both spent inputs and reference +inputs (`txNonDistinctRefScriptsSize`), so callers must pass both. **Signature** ```ts export declare const calculateReferenceScriptFee: ( - referenceInputs: ReadonlyArray + utxos: ReadonlyArray, + costPerByte: number ) => Effect.Effect ``` @@ -375,6 +386,27 @@ export declare const mergeAssetsIntoUTxO: ( Added in v2.0.0 +## tierRefScriptFee + +Calculate reference script fees using tiered pricing. + +Direct port of the Cardano ledger's `tierRefScriptFee` function. +Each `sizeIncrement`-byte chunk is priced at `curTierPrice` per byte, +then `curTierPrice *= multiplier` for the next chunk. Final result: `floor(total)`. + +**Signature** + +```ts +export declare const tierRefScriptFee: ( + multiplier: number, + sizeIncrement: number, + baseFee: number, + totalSize: number +) => bigint +``` + +Added in v2.0.0 + # validation ## calculateLeftoverAssets diff --git a/docs/content/docs/modules/utils/Hash.mdx b/docs/content/docs/modules/utils/Hash.mdx index b49b75a0..8c6a6c88 100644 --- a/docs/content/docs/modules/utils/Hash.mdx +++ b/docs/content/docs/modules/utils/Hash.mdx @@ -11,29 +11,16 @@ parent: Modules

Table of contents

- [utils](#utils) - - [RedeemersFormat (type alias)](#redeemersformat-type-alias) - [computeTotalExUnits](#computetotalexunits) - [hashAuxiliaryData](#hashauxiliarydata) - [hashScriptData](#hashscriptdata) - [hashTransaction](#hashtransaction) + - [hashTransactionRaw](#hashtransactionraw) --- # utils -## RedeemersFormat (type alias) - -Format for encoding redeemers in the script data hash. - -- "array": Legacy format `[ + redeemer ]` (Shelley-Babbage) -- "map": Conway format `{ + [tag, index] => [data, ex_units] }` - -**Signature** - -```ts -export type RedeemersFormat = "array" | "map" -``` - ## computeTotalExUnits Compute total ex_units by summing over redeemers. @@ -58,6 +45,9 @@ export declare const hashAuxiliaryData: (aux: AuxiliaryData.AuxiliaryData) => Au Compute script_data_hash using standard module encoders. +Accepts the concrete `Redeemers` union type — encoding format is determined +by `_tag` (`RedeemerMap` → map CBOR, `RedeemerArray` → array CBOR). + The payload format per CDDL spec is raw concatenation (not a CBOR structure): ``` @@ -68,10 +58,9 @@ redeemers_bytes || datums_bytes || language_views_bytes ```ts export declare const hashScriptData: ( - redeemers: ReadonlyArray, + redeemers: Redeemers.Redeemers, costModels: CostModel.CostModels, datums?: ReadonlyArray, - format?: RedeemersFormat, options?: CBOR.CodecOptions ) => ScriptDataHash.ScriptDataHash ``` @@ -85,3 +74,14 @@ Compute the transaction body hash (blake2b-256 over CBOR of body). ```ts export declare const hashTransaction: (body: TransactionBody.TransactionBody) => TransactionHash.TransactionHash ``` + +## hashTransactionRaw + +Compute the transaction body hash from raw CBOR bytes, preserving original encoding. +Uses `Transaction.extractBodyBytes` to avoid the decode→re-encode round-trip. + +**Signature** + +```ts +export declare const hashTransactionRaw: (bodyBytes: Uint8Array) => TransactionHash.TransactionHash +``` diff --git a/docs/content/docs/providers/index.mdx b/docs/content/docs/providers/index.mdx index 8242fa1d..69e172d2 100644 --- a/docs/content/docs/providers/index.mdx +++ b/docs/content/docs/providers/index.mdx @@ -18,10 +18,10 @@ The SDK abstracts provider differences through a unified interface. Choose your Create a provider-only client to query blockchain data: ```typescript -import { createClient } from "@evolution-sdk/evolution"; +import { createClient, mainnet } from "@evolution-sdk/evolution"; const client = createClient({ - network: "mainnet", + chain: mainnet, provider: { type: "blockfrost", baseUrl: "https://cardano-mainnet.blockfrost.io/api/v0", diff --git a/docs/content/docs/providers/provider-only-client.mdx b/docs/content/docs/providers/provider-only-client.mdx index 7459c763..06ad7402 100644 --- a/docs/content/docs/providers/provider-only-client.mdx +++ b/docs/content/docs/providers/provider-only-client.mdx @@ -29,10 +29,10 @@ Provider-only clients are ideal when you need blockchain data but not wallet-spe Create a client with only provider configuration: ```typescript twoslash -import { Address, Assets, Bytes, DatumHash, RewardAddress, Transaction, TransactionHash, TransactionInput, createClient } from "@evolution-sdk/evolution"; +import { Address, Assets, Bytes, DatumHash, RewardAddress, Transaction, TransactionHash, TransactionInput, createClient, mainnet} from "@evolution-sdk/evolution"; const client = createClient({ - network: "mainnet", + chain: mainnet, provider: { type: "blockfrost", baseUrl: "https://cardano-mainnet.blockfrost.io/api/v0", @@ -56,10 +56,10 @@ console.log("Min fee A:", params.minFeeA); Provider-only clients expose all provider methods directly: ```typescript twoslash -import { Address, Assets, Bytes, DatumHash, RewardAddress, Transaction, TransactionHash, TransactionInput, createClient } from "@evolution-sdk/evolution"; +import { Address, Assets, Bytes, DatumHash, RewardAddress, Transaction, TransactionHash, TransactionInput, createClient, mainnet} from "@evolution-sdk/evolution"; const client = createClient({ - network: "mainnet", + chain: mainnet, provider: { type: "blockfrost", baseUrl: "https://cardano-mainnet.blockfrost.io/api/v0", @@ -103,10 +103,10 @@ const evaluated = await client.evaluateTx(unsignedTx); Portfolio tracker for multiple addresses: ```typescript twoslash -import { Address, Assets, Bytes, DatumHash, RewardAddress, Transaction, TransactionHash, TransactionInput, createClient } from "@evolution-sdk/evolution"; +import { Address, Assets, Bytes, DatumHash, RewardAddress, Transaction, TransactionHash, TransactionInput, createClient, mainnet} from "@evolution-sdk/evolution"; const client = createClient({ - network: "mainnet", + chain: mainnet, provider: { type: "blockfrost", baseUrl: "https://cardano-mainnet.blockfrost.io/api/v0", @@ -143,10 +143,10 @@ const portfolio = await getPortfolioBalance([ Accept signed transactions and submit to blockchain: ```typescript twoslash -import { Address, Assets, Bytes, DatumHash, RewardAddress, Transaction, TransactionHash, TransactionInput, createClient } from "@evolution-sdk/evolution"; +import { Address, Assets, Bytes, DatumHash, RewardAddress, Transaction, TransactionHash, TransactionInput, createClient, mainnet} from "@evolution-sdk/evolution"; const client = createClient({ - network: "mainnet", + chain: mainnet, provider: { type: "blockfrost", baseUrl: "https://cardano-mainnet.blockfrost.io/api/v0", @@ -182,10 +182,10 @@ export async function submitTransaction(signedTxCbor: string) { Track network parameters for fee estimation or protocol changes: ```typescript twoslash -import { Address, Assets, Bytes, DatumHash, RewardAddress, Transaction, TransactionHash, TransactionInput, createClient } from "@evolution-sdk/evolution"; +import { Address, Assets, Bytes, DatumHash, RewardAddress, Transaction, TransactionHash, TransactionInput, createClient, mainnet} from "@evolution-sdk/evolution"; const client = createClient({ - network: "mainnet", + chain: mainnet, provider: { type: "blockfrost", baseUrl: "https://cardano-mainnet.blockfrost.io/api/v0", @@ -221,10 +221,10 @@ Provider-only clients cannot perform wallet-specific operations: ```typescript twoslash // @errors: 2339 -import { Address, Assets, Bytes, DatumHash, RewardAddress, Transaction, TransactionHash, TransactionInput, createClient } from "@evolution-sdk/evolution"; +import { Address, Assets, Bytes, DatumHash, RewardAddress, Transaction, TransactionHash, TransactionInput, createClient, mainnet} from "@evolution-sdk/evolution"; const client = createClient({ - network: "mainnet", + chain: mainnet, provider: { type: "blockfrost", baseUrl: "https://cardano-mainnet.blockfrost.io/api/v0", @@ -259,11 +259,11 @@ const txHash = await client.submitTx(signedTx); Add wallet to provider-only client using `attachWallet()`: ```typescript twoslash -import { Address, Assets, Bytes, DatumHash, RewardAddress, Transaction, TransactionHash, TransactionInput, createClient } from "@evolution-sdk/evolution"; +import { Address, Assets, Bytes, DatumHash, RewardAddress, Transaction, TransactionHash, TransactionInput, createClient, mainnet} from "@evolution-sdk/evolution"; // Start with provider only const providerClient = createClient({ - network: "mainnet", + chain: mainnet, provider: { type: "blockfrost", baseUrl: "https://cardano-mainnet.blockfrost.io/api/v0", @@ -292,13 +292,13 @@ const result = await builder.build(); Switch between environments: ```typescript twoslash -import { Address, Assets, Bytes, DatumHash, RewardAddress, Transaction, TransactionHash, TransactionInput, createClient } from "@evolution-sdk/evolution"; +import { Address, Assets, Bytes, DatumHash, RewardAddress, Transaction, TransactionHash, TransactionInput, createClient, preprod, mainnet} from "@evolution-sdk/evolution"; const env = (process.env.NODE_ENV || "development") as "development" | "production"; const config = { development: { - network: "preprod" as const, + chain: preprod, provider: { type: "blockfrost" as const, baseUrl: "https://cardano-preprod.blockfrost.io/api/v0", @@ -306,7 +306,7 @@ const config = { } }, production: { - network: "mainnet" as const, + chain: mainnet, provider: { type: "kupmios" as const, ogmiosUrl: process.env.OGMIOS_URL!, diff --git a/docs/content/docs/providers/provider-types.mdx b/docs/content/docs/providers/provider-types.mdx index 3300f9b5..3b40abb7 100644 --- a/docs/content/docs/providers/provider-types.mdx +++ b/docs/content/docs/providers/provider-types.mdx @@ -14,10 +14,10 @@ Hosted API service with generous free tier and pay-as-you-grow pricing. ### Configuration ```typescript twoslash -import { createClient } from "@evolution-sdk/evolution"; +import { createClient, mainnet} from "@evolution-sdk/evolution"; const client = createClient({ - network: "mainnet", + chain: mainnet, provider: { type: "blockfrost", baseUrl: "https://cardano-mainnet.blockfrost.io/api/v0", @@ -76,10 +76,10 @@ Self-hosted combination of Ogmios (Cardano node interface) and Kupo (lightweight ### Configuration ```typescript twoslash -import { createClient } from "@evolution-sdk/evolution"; +import { createClient, mainnet} from "@evolution-sdk/evolution"; const client = createClient({ - network: "mainnet", + chain: mainnet, provider: { type: "kupmios", ogmiosUrl: "http://localhost:1337", @@ -118,12 +118,12 @@ services: ```typescript // Mainnet -network: "mainnet", +chain: mainnet, ogmiosUrl: "http://localhost:1337", kupoUrl: "http://localhost:1442" // Preprod testnet -network: "preprod", +chain: preprod, ogmiosUrl: "http://localhost:1337", kupoUrl: "http://localhost:1442" ``` @@ -154,10 +154,10 @@ Hosted API service with advanced features and analytics capabilities. ### Configuration ```typescript twoslash -import { createClient } from "@evolution-sdk/evolution"; +import { createClient, mainnet} from "@evolution-sdk/evolution"; const client = createClient({ - network: "mainnet", + chain: mainnet, provider: { type: "maestro", baseUrl: "https://mainnet.gomaestro-api.org/v1", @@ -215,10 +215,10 @@ Community-driven distributed API infrastructure. ### Configuration ```typescript twoslash -import { createClient } from "@evolution-sdk/evolution"; +import { createClient, mainnet} from "@evolution-sdk/evolution"; const client = createClient({ - network: "mainnet", + chain: mainnet, provider: { type: "koios", baseUrl: "https://api.koios.rest/api/v1" @@ -279,11 +279,11 @@ Applications prioritizing decentralization, community infrastructure, or wanting The unified interface allows switching providers with minimal code changes: ```typescript twoslash -import { createClient } from "@evolution-sdk/evolution"; +import { createClient, preprod, mainnet} from "@evolution-sdk/evolution"; // Development: Blockfrost const devClient = createClient({ - network: "preprod", + chain: preprod, provider: { type: "blockfrost", baseUrl: "https://cardano-preprod.blockfrost.io/api/v0", @@ -293,7 +293,7 @@ const devClient = createClient({ // Production: Self-hosted Kupmios const prodClient = createClient({ - network: "mainnet", + chain: mainnet, provider: { type: "kupmios", ogmiosUrl: process.env.OGMIOS_URL!, @@ -310,7 +310,7 @@ const params = await devClient.getProtocolParameters(); Manage provider configuration per environment: ```typescript twoslash -import { createClient } from "@evolution-sdk/evolution"; +import { createClient, mainnet, preprod } from "@evolution-sdk/evolution"; const environment = (process.env.NODE_ENV || "development") as "development" | "staging" | "production"; @@ -333,7 +333,7 @@ const providerConfig = { }; const client = createClient({ - network: environment === "production" ? "mainnet" : "preprod", + chain: environment === "production" ? mainnet : preprod, provider: providerConfig[environment] }); ``` diff --git a/docs/content/docs/providers/querying.mdx b/docs/content/docs/providers/querying.mdx index 8653e27a..962738b3 100644 --- a/docs/content/docs/providers/querying.mdx +++ b/docs/content/docs/providers/querying.mdx @@ -12,10 +12,10 @@ Providers expose methods to query UTxOs, protocol parameters, delegation informa Retrieve current network parameters for fee calculation and transaction constraints: ```typescript twoslash -import { Address, Bytes, Credential, DatumHash, PoolKeyHash, RewardAddress, TransactionHash, TransactionInput, createClient } from "@evolution-sdk/evolution"; +import { Address, Bytes, Credential, DatumHash, PoolKeyHash, RewardAddress, TransactionHash, TransactionInput, createClient, mainnet} from "@evolution-sdk/evolution"; const client = createClient({ - network: "mainnet", + chain: mainnet, provider: { type: "blockfrost", baseUrl: "https://cardano-mainnet.blockfrost.io/api/v0", @@ -48,10 +48,10 @@ Query unspent transaction outputs by address, credential, unit, or reference. ### By Address ```typescript twoslash -import { Address, Bytes, Credential, DatumHash, PoolKeyHash, RewardAddress, TransactionHash, TransactionInput, createClient } from "@evolution-sdk/evolution"; +import { Address, Bytes, Credential, DatumHash, PoolKeyHash, RewardAddress, TransactionHash, TransactionInput, createClient, mainnet} from "@evolution-sdk/evolution"; const client = createClient({ - network: "mainnet", + chain: mainnet, provider: { type: "blockfrost", baseUrl: "https://cardano-mainnet.blockfrost.io/api/v0", @@ -86,10 +86,10 @@ utxos.forEach((utxo) => { Query UTxOs by payment credential instead of full address: ```typescript -import { Address, Bytes, Credential, DatumHash, PoolKeyHash, RewardAddress, TransactionHash, TransactionInput, createClient } from "@evolution-sdk/evolution"; +import { Address, Bytes, Credential, DatumHash, PoolKeyHash, RewardAddress, TransactionHash, TransactionInput, createClient, mainnet } from "@evolution-sdk/evolution"; const client = createClient({ - network: "mainnet", + chain: mainnet, provider: { type: "blockfrost", baseUrl: "https://cardano-mainnet.blockfrost.io/api/v0", @@ -109,10 +109,10 @@ const utxos = await client.getUtxos(credential); Query UTxOs containing specific native asset: ```typescript twoslash -import { Address, Bytes, Credential, DatumHash, PoolKeyHash, RewardAddress, TransactionHash, TransactionInput, createClient } from "@evolution-sdk/evolution"; +import { Address, Bytes, Credential, DatumHash, PoolKeyHash, RewardAddress, TransactionHash, TransactionInput, createClient, mainnet} from "@evolution-sdk/evolution"; const client = createClient({ - network: "mainnet", + chain: mainnet, provider: { type: "blockfrost", baseUrl: "https://cardano-mainnet.blockfrost.io/api/v0", @@ -138,10 +138,10 @@ console.log("UTxOs with token:", utxosWithToken.length); Query specific UTxOs by transaction output reference: ```typescript twoslash -import { Address, Bytes, Credential, DatumHash, PoolKeyHash, RewardAddress, TransactionHash, TransactionInput, createClient } from "@evolution-sdk/evolution"; +import { Address, Bytes, Credential, DatumHash, PoolKeyHash, RewardAddress, TransactionHash, TransactionInput, createClient, mainnet} from "@evolution-sdk/evolution"; const client = createClient({ - network: "mainnet", + chain: mainnet, provider: { type: "blockfrost", baseUrl: "https://cardano-mainnet.blockfrost.io/api/v0", @@ -169,10 +169,10 @@ console.log("Found UTxOs:", utxos.length); Find a single UTxO by unique unit identifier: ```typescript twoslash -import { Address, Bytes, Credential, DatumHash, PoolKeyHash, RewardAddress, TransactionHash, TransactionInput, createClient } from "@evolution-sdk/evolution"; +import { Address, Bytes, Credential, DatumHash, PoolKeyHash, RewardAddress, TransactionHash, TransactionInput, createClient, mainnet} from "@evolution-sdk/evolution"; const client = createClient({ - network: "mainnet", + chain: mainnet, provider: { type: "blockfrost", baseUrl: "https://cardano-mainnet.blockfrost.io/api/v0", @@ -193,10 +193,10 @@ console.log("Current owner UTxO:", TransactionHash.toHex(utxo.transactionId)); Query staking delegation and reward information: ```typescript twoslash -import { Address, Bytes, Credential, DatumHash, PoolKeyHash, RewardAddress, TransactionHash, TransactionInput, createClient } from "@evolution-sdk/evolution"; +import { Address, Bytes, Credential, DatumHash, PoolKeyHash, RewardAddress, TransactionHash, TransactionInput, createClient, mainnet} from "@evolution-sdk/evolution"; const client = createClient({ - network: "mainnet", + chain: mainnet, provider: { type: "blockfrost", baseUrl: "https://cardano-mainnet.blockfrost.io/api/v0", @@ -216,10 +216,10 @@ console.log("Rewards:", delegation.rewards); Retrieve datum content by hash: ```typescript twoslash -import { Address, Bytes, Credential, DatumHash, PoolKeyHash, RewardAddress, TransactionHash, TransactionInput, createClient } from "@evolution-sdk/evolution"; +import { Address, Bytes, Credential, DatumHash, PoolKeyHash, RewardAddress, TransactionHash, TransactionInput, createClient, mainnet} from "@evolution-sdk/evolution"; const client = createClient({ - network: "mainnet", + chain: mainnet, provider: { type: "blockfrost", baseUrl: "https://cardano-mainnet.blockfrost.io/api/v0", @@ -241,10 +241,10 @@ console.log("Datum CBOR:", datumCbor); Calculate total balance across multiple addresses: ```typescript twoslash -import { Address, Bytes, Credential, DatumHash, PoolKeyHash, RewardAddress, TransactionHash, TransactionInput, createClient } from "@evolution-sdk/evolution"; +import { Address, Bytes, Credential, DatumHash, PoolKeyHash, RewardAddress, TransactionHash, TransactionInput, createClient, mainnet} from "@evolution-sdk/evolution"; const client = createClient({ - network: "mainnet", + chain: mainnet, provider: { type: "blockfrost", baseUrl: "https://cardano-mainnet.blockfrost.io/api/v0", @@ -290,10 +290,10 @@ async function getPortfolioBalance(addressesBech32: string[]) { Find all holders of a specific token: ```typescript twoslash -import { Address, Bytes, Credential, DatumHash, PoolKeyHash, RewardAddress, TransactionHash, TransactionInput, createClient } from "@evolution-sdk/evolution"; +import { Address, Bytes, Credential, DatumHash, PoolKeyHash, RewardAddress, TransactionHash, TransactionInput, createClient, mainnet} from "@evolution-sdk/evolution"; const client = createClient({ - network: "mainnet", + chain: mainnet, provider: { type: "blockfrost", baseUrl: "https://cardano-mainnet.blockfrost.io/api/v0", @@ -330,10 +330,10 @@ async function getTokenHolders( Check if addresses are delegated to specific pool: ```typescript twoslash -import { Address, Bytes, Credential, DatumHash, PoolKeyHash, RewardAddress, TransactionHash, TransactionInput, createClient } from "@evolution-sdk/evolution"; +import { Address, Bytes, Credential, DatumHash, PoolKeyHash, RewardAddress, TransactionHash, TransactionInput, createClient, mainnet} from "@evolution-sdk/evolution"; const client = createClient({ - network: "mainnet", + chain: mainnet, provider: { type: "blockfrost", baseUrl: "https://cardano-mainnet.blockfrost.io/api/v0", @@ -368,10 +368,10 @@ async function checkPoolDelegation( Track NFT ownership across collection: ```typescript twoslash -import { Address, Bytes, Credential, DatumHash, PoolKeyHash, RewardAddress, TransactionHash, TransactionInput, createClient } from "@evolution-sdk/evolution"; +import { Address, Bytes, Credential, DatumHash, PoolKeyHash, RewardAddress, TransactionHash, TransactionInput, createClient, mainnet} from "@evolution-sdk/evolution"; const client = createClient({ - network: "mainnet", + chain: mainnet, provider: { type: "blockfrost", baseUrl: "https://cardano-mainnet.blockfrost.io/api/v0", @@ -409,10 +409,10 @@ async function getNFTOwnership(nftUnits: string[]) { Handle query errors gracefully: ```typescript twoslash -import { Address, Bytes, Credential, DatumHash, PoolKeyHash, RewardAddress, TransactionHash, TransactionInput, createClient } from "@evolution-sdk/evolution"; +import { Address, Bytes, Credential, DatumHash, PoolKeyHash, RewardAddress, TransactionHash, TransactionInput, createClient, mainnet} from "@evolution-sdk/evolution"; const client = createClient({ - network: "mainnet", + chain: mainnet, provider: { type: "blockfrost", baseUrl: "https://cardano-mainnet.blockfrost.io/api/v0", @@ -447,10 +447,10 @@ async function safeGetDelegation(rewardAddress: string) { Optimize queries for better performance: ```typescript twoslash -import { Address, Bytes, Credential, DatumHash, PoolKeyHash, RewardAddress, TransactionHash, TransactionInput, createClient } from "@evolution-sdk/evolution"; +import { Address, Bytes, Credential, DatumHash, PoolKeyHash, RewardAddress, TransactionHash, TransactionInput, createClient, mainnet} from "@evolution-sdk/evolution"; const client = createClient({ - network: "mainnet", + chain: mainnet, provider: { type: "blockfrost", baseUrl: "https://cardano-mainnet.blockfrost.io/api/v0", diff --git a/docs/content/docs/providers/submission.mdx b/docs/content/docs/providers/submission.mdx index 5e54aa58..af8a0391 100644 --- a/docs/content/docs/providers/submission.mdx +++ b/docs/content/docs/providers/submission.mdx @@ -12,10 +12,10 @@ Providers handle transaction submission and confirmation monitoring. Submit pre- Submit a signed transaction CBOR string: ```typescript twoslash -import { Transaction, TransactionHash, createClient } from "@evolution-sdk/evolution"; +import { Transaction, TransactionHash, createClient, mainnet} from "@evolution-sdk/evolution"; const client = createClient({ - network: "mainnet", + chain: mainnet, provider: { type: "blockfrost", baseUrl: "https://cardano-mainnet.blockfrost.io/api/v0", @@ -36,10 +36,10 @@ console.log("Transaction submitted:", txHash); Monitor transaction until confirmed on blockchain: ```typescript twoslash -import { Transaction, TransactionHash, createClient } from "@evolution-sdk/evolution"; +import { Transaction, TransactionHash, createClient, mainnet} from "@evolution-sdk/evolution"; const client = createClient({ - network: "mainnet", + chain: mainnet, provider: { type: "blockfrost", baseUrl: "https://cardano-mainnet.blockfrost.io/api/v0", @@ -66,10 +66,10 @@ if (confirmed) { Specify how often to check for confirmation: ```typescript twoslash -import { Transaction, TransactionHash, createClient } from "@evolution-sdk/evolution"; +import { Transaction, TransactionHash, createClient, mainnet} from "@evolution-sdk/evolution"; const client = createClient({ - network: "mainnet", + chain: mainnet, provider: { type: "blockfrost", baseUrl: "https://cardano-mainnet.blockfrost.io/api/v0", @@ -91,10 +91,10 @@ console.log("Confirmed:", confirmed); Evaluate transaction before submission to estimate script execution costs: ```typescript twoslash -import { Transaction, TransactionHash, createClient } from "@evolution-sdk/evolution"; +import { Transaction, TransactionHash, createClient, mainnet} from "@evolution-sdk/evolution"; const client = createClient({ - network: "mainnet", + chain: mainnet, provider: { type: "blockfrost", baseUrl: "https://cardano-mainnet.blockfrost.io/api/v0", @@ -121,10 +121,10 @@ redeemers.forEach((redeemer) => { Create a transaction submission service with error handling: ```typescript twoslash -import { Transaction, TransactionHash, createClient } from "@evolution-sdk/evolution"; +import { Transaction, TransactionHash, createClient, mainnet} from "@evolution-sdk/evolution"; const client = createClient({ - network: "mainnet", + chain: mainnet, provider: { type: "blockfrost", baseUrl: "https://cardano-mainnet.blockfrost.io/api/v0", @@ -172,10 +172,10 @@ export async function submitAndWait( Submit multiple transactions sequentially: ```typescript twoslash -import { Transaction, TransactionHash, createClient } from "@evolution-sdk/evolution"; +import { Transaction, TransactionHash, createClient, mainnet} from "@evolution-sdk/evolution"; const client = createClient({ - network: "mainnet", + chain: mainnet, provider: { type: "blockfrost", baseUrl: "https://cardano-mainnet.blockfrost.io/api/v0", @@ -216,10 +216,10 @@ async function submitBatch(signedTxs: string[]) { Handle common submission errors: ```typescript twoslash -import { Transaction, TransactionHash, createClient } from "@evolution-sdk/evolution"; +import { Transaction, TransactionHash, createClient, mainnet} from "@evolution-sdk/evolution"; const client = createClient({ - network: "mainnet", + chain: mainnet, provider: { type: "blockfrost", baseUrl: "https://cardano-mainnet.blockfrost.io/api/v0", @@ -275,10 +275,10 @@ async function safeSubmit(signedTxCbor: string) { Implement retry logic for transient failures: ```typescript twoslash -import { Transaction, TransactionHash, createClient } from "@evolution-sdk/evolution"; +import { Transaction, TransactionHash, createClient, mainnet} from "@evolution-sdk/evolution"; const client = createClient({ - network: "mainnet", + chain: mainnet, provider: { type: "blockfrost", baseUrl: "https://cardano-mainnet.blockfrost.io/api/v0", @@ -329,10 +329,10 @@ async function submitWithRetry( Track transaction status with periodic checks: ```typescript twoslash -import { Transaction, TransactionHash, createClient } from "@evolution-sdk/evolution"; +import { Transaction, TransactionHash, createClient, mainnet} from "@evolution-sdk/evolution"; const client = createClient({ - network: "mainnet", + chain: mainnet, provider: { type: "blockfrost", baseUrl: "https://cardano-mainnet.blockfrost.io/api/v0", @@ -373,10 +373,10 @@ async function monitorTransaction( End-to-end transaction submission with all error handling: ```typescript twoslash -import { Transaction, TransactionHash, createClient } from "@evolution-sdk/evolution"; +import { Transaction, TransactionHash, createClient, mainnet} from "@evolution-sdk/evolution"; const client = createClient({ - network: "mainnet", + chain: mainnet, provider: { type: "blockfrost", baseUrl: "https://cardano-mainnet.blockfrost.io/api/v0", @@ -462,10 +462,10 @@ export async function submitTransaction( Validate scripts before submitting: ```typescript twoslash -import { Transaction, TransactionHash, createClient } from "@evolution-sdk/evolution"; +import { Transaction, TransactionHash, createClient, mainnet} from "@evolution-sdk/evolution"; const client = createClient({ - network: "mainnet", + chain: mainnet, provider: { type: "blockfrost", baseUrl: "https://cardano-mainnet.blockfrost.io/api/v0", diff --git a/docs/content/docs/providers/use-cases.mdx b/docs/content/docs/providers/use-cases.mdx index d6a73690..03d0fd84 100644 --- a/docs/content/docs/providers/use-cases.mdx +++ b/docs/content/docs/providers/use-cases.mdx @@ -12,10 +12,10 @@ Practical patterns and complete examples showing how to use providers in real ap Query and display address information: ```typescript twoslash -import { Address, PoolKeyHash, RewardAddress, Transaction, TransactionHash, createClient } from "@evolution-sdk/evolution"; +import { Address, PoolKeyHash, RewardAddress, Transaction, TransactionHash, createClient, mainnet} from "@evolution-sdk/evolution"; const client = createClient({ - network: "mainnet", + chain: mainnet, provider: { type: "blockfrost", baseUrl: "https://cardano-mainnet.blockfrost.io/api/v0", @@ -56,10 +56,10 @@ export async function exploreAddress( Track balances across multiple addresses: ```typescript twoslash -import { Address, PoolKeyHash, RewardAddress, Transaction, TransactionHash, createClient } from "@evolution-sdk/evolution"; +import { Address, PoolKeyHash, RewardAddress, Transaction, TransactionHash, createClient, mainnet} from "@evolution-sdk/evolution"; const client = createClient({ - network: "mainnet", + chain: mainnet, provider: { type: "blockfrost", baseUrl: "https://cardano-mainnet.blockfrost.io/api/v0", @@ -132,10 +132,10 @@ export async function trackPortfolio( Backend API endpoint for transaction submission: ```typescript twoslash -import { Address, PoolKeyHash, RewardAddress, Transaction, TransactionHash, createClient } from "@evolution-sdk/evolution"; +import { Address, PoolKeyHash, RewardAddress, Transaction, TransactionHash, createClient, mainnet} from "@evolution-sdk/evolution"; const client = createClient({ - network: "mainnet", + chain: mainnet, provider: { type: "blockfrost", baseUrl: "https://cardano-mainnet.blockfrost.io/api/v0", @@ -211,10 +211,10 @@ app.post("/api/submit", async (req, res) => { Track token distribution across holders: ```typescript twoslash -import { Address, PoolKeyHash, RewardAddress, Transaction, TransactionHash, createClient } from "@evolution-sdk/evolution"; +import { Address, PoolKeyHash, RewardAddress, Transaction, TransactionHash, createClient, mainnet} from "@evolution-sdk/evolution"; const client = createClient({ - network: "mainnet", + chain: mainnet, provider: { type: "blockfrost", baseUrl: "https://cardano-mainnet.blockfrost.io/api/v0", @@ -277,10 +277,10 @@ export async function trackDistribution( Track NFT ownership and rarity: ```typescript twoslash -import { Address, PoolKeyHash, RewardAddress, Transaction, TransactionHash, createClient } from "@evolution-sdk/evolution"; +import { Address, PoolKeyHash, RewardAddress, Transaction, TransactionHash, createClient, mainnet} from "@evolution-sdk/evolution"; const client = createClient({ - network: "mainnet", + chain: mainnet, provider: { type: "blockfrost", baseUrl: "https://cardano-mainnet.blockfrost.io/api/v0", @@ -357,10 +357,10 @@ export async function getCollectionStats( Track delegators to a specific stake pool: ```typescript twoslash -import { Address, PoolKeyHash, RewardAddress, Transaction, TransactionHash, createClient } from "@evolution-sdk/evolution"; +import { Address, PoolKeyHash, RewardAddress, Transaction, TransactionHash, createClient, mainnet} from "@evolution-sdk/evolution"; const client = createClient({ - network: "mainnet", + chain: mainnet, provider: { type: "blockfrost", baseUrl: "https://cardano-mainnet.blockfrost.io/api/v0", @@ -428,10 +428,10 @@ export async function getPoolStats( Monitor network parameters for changes: ```typescript twoslash -import { Address, PoolKeyHash, RewardAddress, Transaction, TransactionHash, createClient } from "@evolution-sdk/evolution"; +import { Address, PoolKeyHash, RewardAddress, Transaction, TransactionHash, createClient, mainnet} from "@evolution-sdk/evolution"; const client = createClient({ - network: "mainnet", + chain: mainnet, provider: { type: "blockfrost", baseUrl: "https://cardano-mainnet.blockfrost.io/api/v0", @@ -514,7 +514,7 @@ export class ParameterMonitor { Implement provider failover for reliability: ```typescript twoslash -import { Address, PoolKeyHash, RewardAddress, Transaction, TransactionHash, createClient } from "@evolution-sdk/evolution"; +import { Address, Chain, PoolKeyHash, RewardAddress, Transaction, TransactionHash, createClient, mainnet} from "@evolution-sdk/evolution"; // Type for clients with common provider methods interface ProviderClient { @@ -529,7 +529,7 @@ class ProviderWithFallback { constructor( configs: Array<{ - network: "mainnet" | "preprod" | "preview"; + chain: Chain; provider: | { type: "blockfrost"; baseUrl: string; projectId: string } | { type: "maestro"; baseUrl: string; apiKey: string } @@ -537,8 +537,8 @@ class ProviderWithFallback { | { type: "koios"; baseUrl: string }; }> ) { - this.clients = configs.map(({ network, provider }) => - createClient({ network, provider }) + this.clients = configs.map(({ chain, provider }) => + createClient({ chain, provider }) ); } @@ -583,7 +583,7 @@ class ProviderWithFallback { // Usage const resilientProvider = new ProviderWithFallback([ { - network: "mainnet", + chain: mainnet, provider: { type: "blockfrost", baseUrl: "https://cardano-mainnet.blockfrost.io/api/v0", @@ -591,7 +591,7 @@ const resilientProvider = new ProviderWithFallback([ } }, { - network: "mainnet", + chain: mainnet, provider: { type: "maestro", baseUrl: "https://mainnet.gomaestro-api.org/v1", diff --git a/docs/content/docs/querying/datums.mdx b/docs/content/docs/querying/datums.mdx index 418c5997..73a8790c 100644 --- a/docs/content/docs/querying/datums.mdx +++ b/docs/content/docs/querying/datums.mdx @@ -10,10 +10,10 @@ When a UTxO uses a datum hash (instead of an inline datum), the full datum must ## Fetch Datum by Hash ```typescript twoslash -import { createClient } from "@evolution-sdk/evolution" +import { createClient, preprod} from "@evolution-sdk/evolution" const client = createClient({ - network: "preprod", + chain: preprod, provider: { type: "blockfrost", baseUrl: "https://cardano-preprod.blockfrost.io/api/v0", projectId: process.env.BLOCKFROST_API_KEY! }, wallet: { type: "seed", mnemonic: process.env.WALLET_MNEMONIC!, accountIndex: 0 } }) diff --git a/docs/content/docs/querying/delegation.mdx b/docs/content/docs/querying/delegation.mdx index 4b5c53f2..892f4669 100644 --- a/docs/content/docs/querying/delegation.mdx +++ b/docs/content/docs/querying/delegation.mdx @@ -12,10 +12,10 @@ Check which pool a stake credential is delegated to and how many rewards have ac The simplest way to check delegation for your connected wallet: ```typescript twoslash -import { createClient } from "@evolution-sdk/evolution" +import { createClient, preprod} from "@evolution-sdk/evolution" const client = createClient({ - network: "preprod", + chain: preprod, provider: { type: "blockfrost", baseUrl: "https://cardano-preprod.blockfrost.io/api/v0", projectId: process.env.BLOCKFROST_API_KEY! }, wallet: { type: "seed", mnemonic: process.env.WALLET_MNEMONIC!, accountIndex: 0 } }) @@ -31,10 +31,10 @@ console.log("Rewards:", delegation.rewards) // Accumulated lovelace For querying any address's delegation, use `getDelegation` with a reward address: ```typescript twoslash -import { createClient } from "@evolution-sdk/evolution" +import { createClient, preprod} from "@evolution-sdk/evolution" const client = createClient({ - network: "preprod", + chain: preprod, provider: { type: "blockfrost", baseUrl: "https://cardano-preprod.blockfrost.io/api/v0", projectId: process.env.BLOCKFROST_API_KEY! }, wallet: { type: "seed", mnemonic: process.env.WALLET_MNEMONIC!, accountIndex: 0 } }) diff --git a/docs/content/docs/querying/index.mdx b/docs/content/docs/querying/index.mdx index c733698a..4e01dea7 100644 --- a/docs/content/docs/querying/index.mdx +++ b/docs/content/docs/querying/index.mdx @@ -26,10 +26,10 @@ Evolution SDK provides a unified query interface across all providers (Blockfros ## Quick Example ```typescript twoslash -import { Address, createClient } from "@evolution-sdk/evolution" +import { Address, createClient, preprod} from "@evolution-sdk/evolution" const client = createClient({ - network: "preprod", + chain: preprod, provider: { type: "blockfrost", baseUrl: "https://cardano-preprod.blockfrost.io/api/v0", projectId: process.env.BLOCKFROST_API_KEY! }, wallet: { type: "seed", mnemonic: process.env.WALLET_MNEMONIC!, accountIndex: 0 } }) diff --git a/docs/content/docs/querying/protocol-parameters.mdx b/docs/content/docs/querying/protocol-parameters.mdx index 43fa34c8..73701680 100644 --- a/docs/content/docs/querying/protocol-parameters.mdx +++ b/docs/content/docs/querying/protocol-parameters.mdx @@ -10,10 +10,10 @@ Protocol parameters define the network's rules — fee calculations, size limits ## Query Parameters ```typescript twoslash -import { createClient } from "@evolution-sdk/evolution" +import { createClient, preprod} from "@evolution-sdk/evolution" const client = createClient({ - network: "preprod", + chain: preprod, provider: { type: "blockfrost", baseUrl: "https://cardano-preprod.blockfrost.io/api/v0", projectId: process.env.BLOCKFROST_API_KEY! }, wallet: { type: "seed", mnemonic: process.env.WALLET_MNEMONIC!, accountIndex: 0 } }) @@ -46,10 +46,10 @@ console.log("Pool deposit:", params.poolDeposit) You can provide custom protocol parameters when building transactions: ```typescript twoslash -import { Address, Assets, createClient } from "@evolution-sdk/evolution" +import { Address, Assets, createClient, preprod} from "@evolution-sdk/evolution" const client = createClient({ - network: "preprod", + chain: preprod, provider: { type: "blockfrost", baseUrl: "https://cardano-preprod.blockfrost.io/api/v0", projectId: process.env.BLOCKFROST_API_KEY! }, wallet: { type: "seed", mnemonic: process.env.WALLET_MNEMONIC!, accountIndex: 0 } }) diff --git a/docs/content/docs/querying/transaction-status.mdx b/docs/content/docs/querying/transaction-status.mdx index 31cdea4c..4d0e778b 100644 --- a/docs/content/docs/querying/transaction-status.mdx +++ b/docs/content/docs/querying/transaction-status.mdx @@ -10,10 +10,10 @@ After submitting a transaction, use `awaitTx` to wait for it to appear on-chain. ## Wait for Confirmation ```typescript twoslash -import { Address, Assets, createClient } from "@evolution-sdk/evolution" +import { Address, Assets, createClient, preprod} from "@evolution-sdk/evolution" const client = createClient({ - network: "preprod", + chain: preprod, provider: { type: "blockfrost", baseUrl: "https://cardano-preprod.blockfrost.io/api/v0", projectId: process.env.BLOCKFROST_API_KEY! }, wallet: { type: "seed", mnemonic: process.env.WALLET_MNEMONIC!, accountIndex: 0 } }) diff --git a/docs/content/docs/querying/utxos.mdx b/docs/content/docs/querying/utxos.mdx index 258827a9..5745d41b 100644 --- a/docs/content/docs/querying/utxos.mdx +++ b/docs/content/docs/querying/utxos.mdx @@ -10,10 +10,10 @@ UTxOs (Unspent Transaction Outputs) represent available funds on the blockchain. ## By Address ```typescript twoslash -import { Address, createClient } from "@evolution-sdk/evolution" +import { Address, createClient, preprod} from "@evolution-sdk/evolution" const client = createClient({ - network: "preprod", + chain: preprod, provider: { type: "blockfrost", baseUrl: "https://cardano-preprod.blockfrost.io/api/v0", projectId: process.env.BLOCKFROST_API_KEY! }, wallet: { type: "seed", mnemonic: process.env.WALLET_MNEMONIC!, accountIndex: 0 } }) @@ -32,10 +32,10 @@ for (const utxo of utxos) { Query all UTxOs belonging to your connected wallet: ```typescript twoslash -import { createClient } from "@evolution-sdk/evolution" +import { createClient, preprod} from "@evolution-sdk/evolution" const client = createClient({ - network: "preprod", + chain: preprod, provider: { type: "blockfrost", baseUrl: "https://cardano-preprod.blockfrost.io/api/v0", projectId: process.env.BLOCKFROST_API_KEY! }, wallet: { type: "seed", mnemonic: process.env.WALLET_MNEMONIC!, accountIndex: 0 } }) @@ -50,10 +50,10 @@ console.log("Total balance:", totalLovelace, "lovelace") Find UTxOs containing a specific native token: ```typescript twoslash -import { Address, createClient } from "@evolution-sdk/evolution" +import { Address, createClient, preprod} from "@evolution-sdk/evolution" const client = createClient({ - network: "preprod", + chain: preprod, provider: { type: "blockfrost", baseUrl: "https://cardano-preprod.blockfrost.io/api/v0", projectId: process.env.BLOCKFROST_API_KEY! }, wallet: { type: "seed", mnemonic: process.env.WALLET_MNEMONIC!, accountIndex: 0 } }) @@ -73,10 +73,10 @@ const nftUtxo = await client.getUtxoByUnit(unit) Fetch specific UTxOs by their transaction hash and output index: ```typescript twoslash -import { createClient } from "@evolution-sdk/evolution" +import { createClient, preprod} from "@evolution-sdk/evolution" const client = createClient({ - network: "preprod", + chain: preprod, provider: { type: "blockfrost", baseUrl: "https://cardano-preprod.blockfrost.io/api/v0", projectId: process.env.BLOCKFROST_API_KEY! }, wallet: { type: "seed", mnemonic: process.env.WALLET_MNEMONIC!, accountIndex: 0 } }) diff --git a/docs/content/docs/smart-contracts/datums.mdx b/docs/content/docs/smart-contracts/datums.mdx index c081a47a..2209607c 100644 --- a/docs/content/docs/smart-contracts/datums.mdx +++ b/docs/content/docs/smart-contracts/datums.mdx @@ -21,10 +21,10 @@ Evolution SDK supports two ways to attach datums to outputs: Inline datums embed the full data in the output. The spending transaction can read it directly without needing to provide the datum separately: ```typescript twoslash -import { Address, Assets, Data, InlineDatum, createClient } from "@evolution-sdk/evolution" +import { Address, Assets, Data, InlineDatum, createClient, preprod} from "@evolution-sdk/evolution" const client = createClient({ - network: "preprod", + chain: preprod, provider: { type: "blockfrost", baseUrl: "https://cardano-preprod.blockfrost.io/api/v0", projectId: process.env.BLOCKFROST_API_KEY! }, wallet: { type: "seed", mnemonic: process.env.WALLET_MNEMONIC!, accountIndex: 0 } }) @@ -45,10 +45,10 @@ const tx = await client Datum hashes store only a 32-byte hash in the output. The full datum must be provided when spending: ```typescript -import { Address, Assets, Data, createClient } from "@evolution-sdk/evolution" +import { Address, Assets, Data, createClient, preprod } from "@evolution-sdk/evolution" const client = createClient({ - network: "preprod", + chain: preprod, provider: { type: "blockfrost", baseUrl: "https://cardano-preprod.blockfrost.io/api/v0", projectId: process.env.BLOCKFROST_API_KEY! }, wallet: { type: "seed", mnemonic: process.env.WALLET_MNEMONIC!, accountIndex: 0 } }) @@ -151,10 +151,10 @@ const datum = Data.constr(0n, [ When querying UTxOs, inline datums are available directly on the UTxO object: ```typescript twoslash -import { Address, Data, TSchema, Bytes, createClient } from "@evolution-sdk/evolution" +import { Address, Data, TSchema, Bytes, createClient, preprod} from "@evolution-sdk/evolution" const client = createClient({ - network: "preprod", + chain: preprod, provider: { type: "blockfrost", baseUrl: "https://cardano-preprod.blockfrost.io/api/v0", projectId: process.env.BLOCKFROST_API_KEY! }, wallet: { type: "seed", mnemonic: process.env.WALLET_MNEMONIC!, accountIndex: 0 } }) diff --git a/docs/content/docs/smart-contracts/index.mdx b/docs/content/docs/smart-contracts/index.mdx index d505f2a1..dbf35e48 100644 --- a/docs/content/docs/smart-contracts/index.mdx +++ b/docs/content/docs/smart-contracts/index.mdx @@ -25,10 +25,10 @@ Smart contract interaction in Cardano involves three concepts: **Locking** (sending funds to a script): ```typescript twoslash -import { Address, Assets, Data, InlineDatum, createClient } from "@evolution-sdk/evolution" +import { Address, Assets, Data, InlineDatum, createClient, preprod} from "@evolution-sdk/evolution" const client = createClient({ - network: "preprod", + chain: preprod, provider: { type: "blockfrost", baseUrl: "https://cardano-preprod.blockfrost.io/api/v0", projectId: process.env.BLOCKFROST_API_KEY! }, wallet: { type: "seed", mnemonic: process.env.WALLET_MNEMONIC!, accountIndex: 0 } }) @@ -49,10 +49,10 @@ const hash = await signed.submit() **Spending** (unlocking funds from a script): ```typescript twoslash -import { Address, Assets, Data, createClient, type UTxO } from "@evolution-sdk/evolution" +import { Address, Assets, Data, createClient, type UTxO, preprod} from "@evolution-sdk/evolution" const client = createClient({ - network: "preprod", + chain: preprod, provider: { type: "blockfrost", baseUrl: "https://cardano-preprod.blockfrost.io/api/v0", projectId: process.env.BLOCKFROST_API_KEY! }, wallet: { type: "seed", mnemonic: process.env.WALLET_MNEMONIC!, accountIndex: 0 } }) diff --git a/docs/content/docs/smart-contracts/locking.mdx b/docs/content/docs/smart-contracts/locking.mdx index aae6d8e8..aafe6c06 100644 --- a/docs/content/docs/smart-contracts/locking.mdx +++ b/docs/content/docs/smart-contracts/locking.mdx @@ -14,10 +14,10 @@ This is the first half of any smart contract interaction — you lock funds, the Send ADA to a script address with an inline datum: ```typescript twoslash -import { Address, Assets, Data, InlineDatum, createClient } from "@evolution-sdk/evolution" +import { Address, Assets, Data, InlineDatum, createClient, preprod} from "@evolution-sdk/evolution" const client = createClient({ - network: "preprod", + chain: preprod, provider: { type: "blockfrost", baseUrl: "https://cardano-preprod.blockfrost.io/api/v0", projectId: process.env.BLOCKFROST_API_KEY! }, wallet: { type: "seed", mnemonic: process.env.WALLET_MNEMONIC!, accountIndex: 0 } }) @@ -45,10 +45,10 @@ console.log("Locked funds at:", txHash) For real contracts, define your datum with TSchema for type safety: ```typescript twoslash -import { Address, Assets, Bytes, Data, InlineDatum, TSchema, createClient } from "@evolution-sdk/evolution" +import { Address, Assets, Bytes, Data, InlineDatum, TSchema, createClient, preprod} from "@evolution-sdk/evolution" const client = createClient({ - network: "preprod", + chain: preprod, provider: { type: "blockfrost", baseUrl: "https://cardano-preprod.blockfrost.io/api/v0", projectId: process.env.BLOCKFROST_API_KEY! }, wallet: { type: "seed", mnemonic: process.env.WALLET_MNEMONIC!, accountIndex: 0 } }) @@ -91,10 +91,10 @@ const txHash = await signed.submit() Lock both ADA and native tokens to a script: ```typescript twoslash -import { Address, Assets, Data, InlineDatum, createClient } from "@evolution-sdk/evolution" +import { Address, Assets, Data, InlineDatum, createClient, preprod} from "@evolution-sdk/evolution" const client = createClient({ - network: "preprod", + chain: preprod, provider: { type: "blockfrost", baseUrl: "https://cardano-preprod.blockfrost.io/api/v0", projectId: process.env.BLOCKFROST_API_KEY! }, wallet: { type: "seed", mnemonic: process.env.WALLET_MNEMONIC!, accountIndex: 0 } }) @@ -130,10 +130,10 @@ await signed.submit() Store a script on-chain alongside the locked funds. Other transactions can reference this script instead of including it directly: ```typescript twoslash -import { Address, Assets, Data, InlineDatum, createClient } from "@evolution-sdk/evolution" +import { Address, Assets, Data, InlineDatum, createClient, preprod} from "@evolution-sdk/evolution" const client = createClient({ - network: "preprod", + chain: preprod, provider: { type: "blockfrost", baseUrl: "https://cardano-preprod.blockfrost.io/api/v0", projectId: process.env.BLOCKFROST_API_KEY! }, wallet: { type: "seed", mnemonic: process.env.WALLET_MNEMONIC!, accountIndex: 0 } }) @@ -163,10 +163,10 @@ await signed.submit() Lock funds to multiple script addresses in a single transaction: ```typescript twoslash -import { Address, Assets, Data, InlineDatum, createClient } from "@evolution-sdk/evolution" +import { Address, Assets, Data, InlineDatum, createClient, preprod} from "@evolution-sdk/evolution" const client = createClient({ - network: "preprod", + chain: preprod, provider: { type: "blockfrost", baseUrl: "https://cardano-preprod.blockfrost.io/api/v0", projectId: process.env.BLOCKFROST_API_KEY! }, wallet: { type: "seed", mnemonic: process.env.WALLET_MNEMONIC!, accountIndex: 0 } }) diff --git a/docs/content/docs/smart-contracts/redeemers.mdx b/docs/content/docs/smart-contracts/redeemers.mdx index 9bb4fb8a..4e8ca881 100644 --- a/docs/content/docs/smart-contracts/redeemers.mdx +++ b/docs/content/docs/smart-contracts/redeemers.mdx @@ -18,10 +18,10 @@ Cardano redeemers reference inputs by their sorted position in the transaction. The simplest mode — provide a direct `Data` value. Use this when your redeemer doesn't need to know its input index: ```typescript twoslash -import { Data, createClient, type UTxO } from "@evolution-sdk/evolution" +import { Data, createClient, type UTxO, preprod} from "@evolution-sdk/evolution" const client = createClient({ - network: "preprod", + chain: preprod, provider: { type: "blockfrost", baseUrl: "https://cardano-preprod.blockfrost.io/api/v0", projectId: process.env.BLOCKFROST_API_KEY! }, wallet: { type: "seed", mnemonic: process.env.WALLET_MNEMONIC!, accountIndex: 0 } }) @@ -47,10 +47,10 @@ const tx = await client A callback that receives the input's final index after coin selection. Use this when the redeemer needs to encode its own position: ```typescript twoslash -import { Data, createClient, type UTxO } from "@evolution-sdk/evolution" +import { Data, createClient, type UTxO, preprod} from "@evolution-sdk/evolution" const client = createClient({ - network: "preprod", + chain: preprod, provider: { type: "blockfrost", baseUrl: "https://cardano-preprod.blockfrost.io/api/v0", projectId: process.env.BLOCKFROST_API_KEY! }, wallet: { type: "seed", mnemonic: process.env.WALLET_MNEMONIC!, accountIndex: 0 } }) @@ -85,10 +85,10 @@ interface IndexedInput { A callback that sees all specified inputs with their final indices. Use this when multiple script inputs need coordinated redeemer values: ```typescript twoslash -import { Data, createClient, type UTxO } from "@evolution-sdk/evolution" +import { Data, createClient, type UTxO, preprod} from "@evolution-sdk/evolution" const client = createClient({ - network: "preprod", + chain: preprod, provider: { type: "blockfrost", baseUrl: "https://cardano-preprod.blockfrost.io/api/v0", projectId: process.env.BLOCKFROST_API_KEY! }, wallet: { type: "seed", mnemonic: process.env.WALLET_MNEMONIC!, accountIndex: 0 } }) @@ -119,10 +119,10 @@ const tx = await client Redeemers also apply to minting policies. The same three modes work: ```typescript twoslash -import { Assets, Data, createClient } from "@evolution-sdk/evolution" +import { Assets, Data, createClient, preprod} from "@evolution-sdk/evolution" const client = createClient({ - network: "preprod", + chain: preprod, provider: { type: "blockfrost", baseUrl: "https://cardano-preprod.blockfrost.io/api/v0", projectId: process.env.BLOCKFROST_API_KEY! }, wallet: { type: "seed", mnemonic: process.env.WALLET_MNEMONIC!, accountIndex: 0 } }) diff --git a/docs/content/docs/smart-contracts/reference-scripts.mdx b/docs/content/docs/smart-contracts/reference-scripts.mdx index 5c23ee7e..74ccb9be 100644 --- a/docs/content/docs/smart-contracts/reference-scripts.mdx +++ b/docs/content/docs/smart-contracts/reference-scripts.mdx @@ -18,10 +18,10 @@ Reference scripts (Plutus V2+) let you store a script on-chain in a UTxO and ref Store your validator script on-chain by including it in a UTxO output: ```typescript twoslash -import { Address, Assets, createClient } from "@evolution-sdk/evolution" +import { Address, Assets, createClient, preprod} from "@evolution-sdk/evolution" const client = createClient({ - network: "preprod", + chain: preprod, provider: { type: "blockfrost", baseUrl: "https://cardano-preprod.blockfrost.io/api/v0", projectId: process.env.BLOCKFROST_API_KEY! }, wallet: { type: "seed", mnemonic: process.env.WALLET_MNEMONIC!, accountIndex: 0 } }) @@ -50,10 +50,10 @@ console.log("Reference script deployed:", txHash) Reference the deployed script UTxO when spending from the validator: ```typescript twoslash -import { Address, Data, createClient, type UTxO } from "@evolution-sdk/evolution" +import { Address, Data, createClient, type UTxO, preprod} from "@evolution-sdk/evolution" const client = createClient({ - network: "preprod", + chain: preprod, provider: { type: "blockfrost", baseUrl: "https://cardano-preprod.blockfrost.io/api/v0", projectId: process.env.BLOCKFROST_API_KEY! }, wallet: { type: "seed", mnemonic: process.env.WALLET_MNEMONIC!, accountIndex: 0 } }) @@ -93,10 +93,10 @@ The key difference: `readFrom` makes the UTxO available as a reference input wit Reference inputs aren't just for scripts — you can also read datums from UTxOs without consuming them: ```typescript twoslash -import { Data, createClient, type UTxO } from "@evolution-sdk/evolution" +import { Data, createClient, type UTxO, preprod} from "@evolution-sdk/evolution" const client = createClient({ - network: "preprod", + chain: preprod, provider: { type: "blockfrost", baseUrl: "https://cardano-preprod.blockfrost.io/api/v0", projectId: process.env.BLOCKFROST_API_KEY! }, wallet: { type: "seed", mnemonic: process.env.WALLET_MNEMONIC!, accountIndex: 0 } }) diff --git a/docs/content/docs/smart-contracts/spending.mdx b/docs/content/docs/smart-contracts/spending.mdx index 8ffd2e99..6a78e568 100644 --- a/docs/content/docs/smart-contracts/spending.mdx +++ b/docs/content/docs/smart-contracts/spending.mdx @@ -12,10 +12,10 @@ Spending from a script means consuming a UTxO locked at a script address by prov Use `collectFrom` to specify which script UTxOs to spend and what redeemer to provide: ```typescript twoslash -import { Address, Assets, Data, createClient, type UTxO } from "@evolution-sdk/evolution" +import { Address, Assets, Data, createClient, type UTxO, preprod} from "@evolution-sdk/evolution" const client = createClient({ - network: "preprod", + chain: preprod, provider: { type: "blockfrost", baseUrl: "https://cardano-preprod.blockfrost.io/api/v0", projectId: process.env.BLOCKFROST_API_KEY! }, wallet: { type: "seed", mnemonic: process.env.WALLET_MNEMONIC!, accountIndex: 0 } }) @@ -42,10 +42,10 @@ const txHash = await signed.submit() Many validators check that a specific key signed the transaction. Use `addSigner` to include the required signer: ```typescript twoslash -import { Address, Assets, Data, KeyHash, createClient, type UTxO } from "@evolution-sdk/evolution" +import { Address, Assets, Data, KeyHash, createClient, type UTxO, preprod} from "@evolution-sdk/evolution" const client = createClient({ - network: "preprod", + chain: preprod, provider: { type: "blockfrost", baseUrl: "https://cardano-preprod.blockfrost.io/api/v0", projectId: process.env.BLOCKFROST_API_KEY! }, wallet: { type: "seed", mnemonic: process.env.WALLET_MNEMONIC!, accountIndex: 0 } }) @@ -73,10 +73,10 @@ await signed.submit() For time-locked validators, set the transaction validity interval so the script can verify the current time: ```typescript twoslash -import { Data, createClient, type UTxO } from "@evolution-sdk/evolution" +import { Data, createClient, type UTxO, preprod} from "@evolution-sdk/evolution" const client = createClient({ - network: "preprod", + chain: preprod, provider: { type: "blockfrost", baseUrl: "https://cardano-preprod.blockfrost.io/api/v0", projectId: process.env.BLOCKFROST_API_KEY! }, wallet: { type: "seed", mnemonic: process.env.WALLET_MNEMONIC!, accountIndex: 0 } }) @@ -108,10 +108,10 @@ await signed.submit() Collect from a script and send the unlocked funds to a recipient: ```typescript twoslash -import { Address, Assets, Data, createClient, type UTxO } from "@evolution-sdk/evolution" +import { Address, Assets, Data, createClient, type UTxO, preprod} from "@evolution-sdk/evolution" const client = createClient({ - network: "preprod", + chain: preprod, provider: { type: "blockfrost", baseUrl: "https://cardano-preprod.blockfrost.io/api/v0", projectId: process.env.BLOCKFROST_API_KEY! }, wallet: { type: "seed", mnemonic: process.env.WALLET_MNEMONIC!, accountIndex: 0 } }) @@ -167,10 +167,10 @@ redeemer: { Add labels to identify operations in error messages when debugging script failures: ```typescript twoslash -import { Data, createClient, type UTxO } from "@evolution-sdk/evolution" +import { Data, createClient, type UTxO, preprod} from "@evolution-sdk/evolution" const client = createClient({ - network: "preprod", + chain: preprod, provider: { type: "blockfrost", baseUrl: "https://cardano-preprod.blockfrost.io/api/v0", projectId: process.env.BLOCKFROST_API_KEY! }, wallet: { type: "seed", mnemonic: process.env.WALLET_MNEMONIC!, accountIndex: 0 } }) diff --git a/docs/content/docs/staking/delegation.mdx b/docs/content/docs/staking/delegation.mdx index 9a9ac5a0..d9568a2a 100644 --- a/docs/content/docs/staking/delegation.mdx +++ b/docs/content/docs/staking/delegation.mdx @@ -12,10 +12,10 @@ Once your stake credential is registered, you can delegate your stake to earn re Assign your stake to a stake pool to earn rewards: ```typescript twoslash -import { Credential, createClient } from "@evolution-sdk/evolution" +import { Credential, createClient, preprod} from "@evolution-sdk/evolution" const client = createClient({ - network: "preprod", + chain: preprod, provider: { type: "blockfrost", baseUrl: "https://cardano-preprod.blockfrost.io/api/v0", projectId: process.env.BLOCKFROST_API_KEY! }, wallet: { type: "seed", mnemonic: process.env.WALLET_MNEMONIC!, accountIndex: 0 } }) @@ -37,10 +37,10 @@ await signed.submit() In the Conway era, delegate your governance voting power to a Delegated Representative: ```typescript twoslash -import { Credential, DRep, createClient } from "@evolution-sdk/evolution" +import { Credential, DRep, createClient, preprod} from "@evolution-sdk/evolution" const client = createClient({ - network: "preprod", + chain: preprod, provider: { type: "blockfrost", baseUrl: "https://cardano-preprod.blockfrost.io/api/v0", projectId: process.env.BLOCKFROST_API_KEY! }, wallet: { type: "seed", mnemonic: process.env.WALLET_MNEMONIC!, accountIndex: 0 } }) @@ -66,10 +66,10 @@ await signed.submit() You can also delegate to built-in options: ```typescript twoslash -import { Credential, DRep, createClient } from "@evolution-sdk/evolution" +import { Credential, DRep, createClient, preprod} from "@evolution-sdk/evolution" const client = createClient({ - network: "preprod", + chain: preprod, provider: { type: "blockfrost", baseUrl: "https://cardano-preprod.blockfrost.io/api/v0", projectId: process.env.BLOCKFROST_API_KEY! }, wallet: { type: "seed", mnemonic: process.env.WALLET_MNEMONIC!, accountIndex: 0 } }) @@ -100,10 +100,10 @@ const tx2 = await client Delegate to a pool and DRep in a single certificate: ```typescript twoslash -import { Credential, DRep, createClient } from "@evolution-sdk/evolution" +import { Credential, DRep, createClient, preprod} from "@evolution-sdk/evolution" const client = createClient({ - network: "preprod", + chain: preprod, provider: { type: "blockfrost", baseUrl: "https://cardano-preprod.blockfrost.io/api/v0", projectId: process.env.BLOCKFROST_API_KEY! }, wallet: { type: "seed", mnemonic: process.env.WALLET_MNEMONIC!, accountIndex: 0 } }) @@ -130,10 +130,10 @@ await signed.submit() For script-controlled stake credentials, provide a redeemer: ```typescript twoslash -import { Credential, Data, createClient } from "@evolution-sdk/evolution" +import { Credential, Data, createClient, preprod} from "@evolution-sdk/evolution" const client = createClient({ - network: "preprod", + chain: preprod, provider: { type: "blockfrost", baseUrl: "https://cardano-preprod.blockfrost.io/api/v0", projectId: process.env.BLOCKFROST_API_KEY! }, wallet: { type: "seed", mnemonic: process.env.WALLET_MNEMONIC!, accountIndex: 0 } }) diff --git a/docs/content/docs/staking/deregistration.mdx b/docs/content/docs/staking/deregistration.mdx index 1463b130..3f151c82 100644 --- a/docs/content/docs/staking/deregistration.mdx +++ b/docs/content/docs/staking/deregistration.mdx @@ -10,10 +10,10 @@ Deregistering a stake credential removes it from the chain and refunds the depos ## Basic Deregistration ```typescript twoslash -import { Credential, createClient } from "@evolution-sdk/evolution" +import { Credential, createClient, preprod} from "@evolution-sdk/evolution" const client = createClient({ - network: "preprod", + chain: preprod, provider: { type: "blockfrost", baseUrl: "https://cardano-preprod.blockfrost.io/api/v0", projectId: process.env.BLOCKFROST_API_KEY! }, wallet: { type: "seed", mnemonic: process.env.WALLET_MNEMONIC!, accountIndex: 0 } }) @@ -34,10 +34,10 @@ await signed.submit() Best practice: withdraw rewards and deregister in the same transaction to avoid losing rewards: ```typescript twoslash -import { Credential, createClient } from "@evolution-sdk/evolution" +import { Credential, createClient, preprod} from "@evolution-sdk/evolution" const client = createClient({ - network: "preprod", + chain: preprod, provider: { type: "blockfrost", baseUrl: "https://cardano-preprod.blockfrost.io/api/v0", projectId: process.env.BLOCKFROST_API_KEY! }, wallet: { type: "seed", mnemonic: process.env.WALLET_MNEMONIC!, accountIndex: 0 } }) @@ -58,10 +58,10 @@ await signed.submit() ## Script-Controlled Deregistration ```typescript twoslash -import { Credential, Data, createClient } from "@evolution-sdk/evolution" +import { Credential, Data, createClient, preprod} from "@evolution-sdk/evolution" const client = createClient({ - network: "preprod", + chain: preprod, provider: { type: "blockfrost", baseUrl: "https://cardano-preprod.blockfrost.io/api/v0", projectId: process.env.BLOCKFROST_API_KEY! }, wallet: { type: "seed", mnemonic: process.env.WALLET_MNEMONIC!, accountIndex: 0 } }) diff --git a/docs/content/docs/staking/index.mdx b/docs/content/docs/staking/index.mdx index f1688a78..d9afbcb3 100644 --- a/docs/content/docs/staking/index.mdx +++ b/docs/content/docs/staking/index.mdx @@ -20,10 +20,10 @@ Evolution SDK provides complete staking operations — register stake credential ## Quick Example ```typescript twoslash -import { Credential, createClient } from "@evolution-sdk/evolution" +import { Credential, createClient, preprod} from "@evolution-sdk/evolution" const client = createClient({ - network: "preprod", + chain: preprod, provider: { type: "blockfrost", baseUrl: "https://cardano-preprod.blockfrost.io/api/v0", projectId: process.env.BLOCKFROST_API_KEY! }, wallet: { type: "seed", mnemonic: process.env.WALLET_MNEMONIC!, accountIndex: 0 } }) diff --git a/docs/content/docs/staking/registration.mdx b/docs/content/docs/staking/registration.mdx index 66ffde22..6ad83442 100644 --- a/docs/content/docs/staking/registration.mdx +++ b/docs/content/docs/staking/registration.mdx @@ -10,10 +10,10 @@ Before you can delegate or earn rewards, your stake credential must be registere ## Basic Registration ```typescript twoslash -import { Credential, createClient } from "@evolution-sdk/evolution" +import { Credential, createClient, preprod} from "@evolution-sdk/evolution" const client = createClient({ - network: "preprod", + chain: preprod, provider: { type: "blockfrost", baseUrl: "https://cardano-preprod.blockfrost.io/api/v0", projectId: process.env.BLOCKFROST_API_KEY! }, wallet: { type: "seed", mnemonic: process.env.WALLET_MNEMONIC!, accountIndex: 0 } }) @@ -36,10 +36,10 @@ The deposit amount is fetched automatically from protocol parameters. The Conway era introduced combined certificates that register and delegate in one step, saving a certificate fee: ```typescript twoslash -import { Credential, createClient } from "@evolution-sdk/evolution" +import { Credential, createClient, preprod} from "@evolution-sdk/evolution" const client = createClient({ - network: "preprod", + chain: preprod, provider: { type: "blockfrost", baseUrl: "https://cardano-preprod.blockfrost.io/api/v0", projectId: process.env.BLOCKFROST_API_KEY! }, wallet: { type: "seed", mnemonic: process.env.WALLET_MNEMONIC!, accountIndex: 0 } }) @@ -64,10 +64,10 @@ await signed.submit() You can also combine registration with DRep delegation or both: ```typescript twoslash -import { Credential, createClient } from "@evolution-sdk/evolution" +import { Credential, createClient, preprod} from "@evolution-sdk/evolution" const client = createClient({ - network: "preprod", + chain: preprod, provider: { type: "blockfrost", baseUrl: "https://cardano-preprod.blockfrost.io/api/v0", projectId: process.env.BLOCKFROST_API_KEY! }, wallet: { type: "seed", mnemonic: process.env.WALLET_MNEMONIC!, accountIndex: 0 } }) @@ -95,10 +95,10 @@ await signed.submit() For stake credentials controlled by Plutus scripts, provide a redeemer: ```typescript twoslash -import { Credential, Data, createClient } from "@evolution-sdk/evolution" +import { Credential, Data, createClient, preprod} from "@evolution-sdk/evolution" const client = createClient({ - network: "preprod", + chain: preprod, provider: { type: "blockfrost", baseUrl: "https://cardano-preprod.blockfrost.io/api/v0", projectId: process.env.BLOCKFROST_API_KEY! }, wallet: { type: "seed", mnemonic: process.env.WALLET_MNEMONIC!, accountIndex: 0 } }) diff --git a/docs/content/docs/staking/withdrawal.mdx b/docs/content/docs/staking/withdrawal.mdx index 54ebb1d6..20137c6b 100644 --- a/docs/content/docs/staking/withdrawal.mdx +++ b/docs/content/docs/staking/withdrawal.mdx @@ -10,10 +10,10 @@ Staking rewards accumulate each epoch and must be explicitly withdrawn to your w ## Basic Withdrawal ```typescript twoslash -import { Credential, createClient } from "@evolution-sdk/evolution" +import { Credential, createClient, preprod} from "@evolution-sdk/evolution" const client = createClient({ - network: "preprod", + chain: preprod, provider: { type: "blockfrost", baseUrl: "https://cardano-preprod.blockfrost.io/api/v0", projectId: process.env.BLOCKFROST_API_KEY! }, wallet: { type: "seed", mnemonic: process.env.WALLET_MNEMONIC!, accountIndex: 0 } }) @@ -42,10 +42,10 @@ await signed.submit() Use `amount: 0n` to trigger a stake validator without actually withdrawing rewards. This is the **coordinator pattern** used by some DeFi protocols: ```typescript twoslash -import { Credential, Data, createClient } from "@evolution-sdk/evolution" +import { Credential, Data, createClient, preprod} from "@evolution-sdk/evolution" const client = createClient({ - network: "preprod", + chain: preprod, provider: { type: "blockfrost", baseUrl: "https://cardano-preprod.blockfrost.io/api/v0", projectId: process.env.BLOCKFROST_API_KEY! }, wallet: { type: "seed", mnemonic: process.env.WALLET_MNEMONIC!, accountIndex: 0 } }) @@ -74,10 +74,10 @@ This pattern is useful for validators that need to run stake-level checks as par ## Script-Controlled Withdrawal ```typescript twoslash -import { Credential, Data, createClient } from "@evolution-sdk/evolution" +import { Credential, Data, createClient, preprod} from "@evolution-sdk/evolution" const client = createClient({ - network: "preprod", + chain: preprod, provider: { type: "blockfrost", baseUrl: "https://cardano-preprod.blockfrost.io/api/v0", projectId: process.env.BLOCKFROST_API_KEY! }, wallet: { type: "seed", mnemonic: process.env.WALLET_MNEMONIC!, accountIndex: 0 } }) diff --git a/docs/content/docs/testing/integration-tests.mdx b/docs/content/docs/testing/integration-tests.mdx index 9ca5395a..5af4a8dc 100644 --- a/docs/content/docs/testing/integration-tests.mdx +++ b/docs/content/docs/testing/integration-tests.mdx @@ -23,7 +23,7 @@ describe("Transaction Tests", () => { const mnemonic = "test test test test test test test test test test test test test test test test test test test test test test test sauce" const wallet = createClient({ - network: 0, + chain: Cluster.BOOTSTRAP_CHAIN, wallet: { type: "seed", mnemonic, accountIndex: 0 } }) @@ -48,7 +48,7 @@ describe("Transaction Tests", () => { await new Promise(resolve => setTimeout(resolve, 8000)) client = createClient({ - network: 0, + chain: Cluster.getChain(cluster), provider: { type: "kupmios", kupoUrl: "http://localhost:1442", diff --git a/docs/content/docs/time/index.mdx b/docs/content/docs/time/index.mdx index 6f747ca0..a78a94f4 100644 --- a/docs/content/docs/time/index.mdx +++ b/docs/content/docs/time/index.mdx @@ -23,10 +23,10 @@ Cardano uses a slot-based time system. Each slot has a fixed duration (typically When you call `.setValidity({ from, to })`, you provide Unix timestamps in milliseconds. The transaction builder converts these to slots using the network's slot configuration: ```typescript twoslash -import { createClient } from "@evolution-sdk/evolution" +import { createClient, preprod} from "@evolution-sdk/evolution" const client = createClient({ - network: "preprod", + chain: preprod, provider: { type: "blockfrost", baseUrl: "https://cardano-preprod.blockfrost.io/api/v0", projectId: process.env.BLOCKFROST_API_KEY! }, wallet: { type: "seed", mnemonic: process.env.WALLET_MNEMONIC!, accountIndex: 0 } }) diff --git a/docs/content/docs/time/posix.mdx b/docs/content/docs/time/posix.mdx index dda90ff6..6c80138b 100644 --- a/docs/content/docs/time/posix.mdx +++ b/docs/content/docs/time/posix.mdx @@ -36,10 +36,10 @@ const expiresIn1Hour = now + oneHour Time values are passed to `.setValidity()` as Unix milliseconds. The builder converts them to slots automatically: ```typescript twoslash -import { createClient } from "@evolution-sdk/evolution" +import { createClient, preprod} from "@evolution-sdk/evolution" const client = createClient({ - network: "preprod", + chain: preprod, provider: { type: "blockfrost", baseUrl: "https://cardano-preprod.blockfrost.io/api/v0", projectId: process.env.BLOCKFROST_API_KEY! }, wallet: { type: "seed", mnemonic: process.env.WALLET_MNEMONIC!, accountIndex: 0 } }) diff --git a/docs/content/docs/time/slots.mdx b/docs/content/docs/time/slots.mdx index d90c6e2d..5a0d8a6c 100644 --- a/docs/content/docs/time/slots.mdx +++ b/docs/content/docs/time/slots.mdx @@ -30,10 +30,10 @@ The builder uses these to convert: `slot = zeroSlot + (unixTime - zeroTime) / sl For devnet or custom networks, you can override the slot config in build options: ```typescript twoslash -import { Address, Assets, createClient } from "@evolution-sdk/evolution" +import { Address, Assets, createClient, preprod} from "@evolution-sdk/evolution" const client = createClient({ - network: "preprod", + chain: preprod, provider: { type: "blockfrost", baseUrl: "https://cardano-preprod.blockfrost.io/api/v0", projectId: process.env.BLOCKFROST_API_KEY! }, wallet: { type: "seed", mnemonic: process.env.WALLET_MNEMONIC!, accountIndex: 0 } }) diff --git a/docs/content/docs/time/validity-ranges.mdx b/docs/content/docs/time/validity-ranges.mdx index 5e021425..d3bda8cc 100644 --- a/docs/content/docs/time/validity-ranges.mdx +++ b/docs/content/docs/time/validity-ranges.mdx @@ -12,10 +12,10 @@ Validity ranges define the time window during which a transaction can be include Use `.setValidity()` with Unix timestamps in milliseconds: ```typescript twoslash -import { Address, Assets, createClient } from "@evolution-sdk/evolution" +import { Address, Assets, createClient, preprod} from "@evolution-sdk/evolution" const client = createClient({ - network: "preprod", + chain: preprod, provider: { type: "blockfrost", baseUrl: "https://cardano-preprod.blockfrost.io/api/v0", projectId: process.env.BLOCKFROST_API_KEY! }, wallet: { type: "seed", mnemonic: process.env.WALLET_MNEMONIC!, accountIndex: 0 } }) diff --git a/docs/content/docs/transactions/chaining.mdx b/docs/content/docs/transactions/chaining.mdx index 37ec37a9..655a15bf 100644 --- a/docs/content/docs/transactions/chaining.mdx +++ b/docs/content/docs/transactions/chaining.mdx @@ -47,10 +47,10 @@ Transactions must be **submitted in order**. Each transaction spends outputs cre The simplest case: two payments built back-to-back, submitted in order. ```typescript twoslash -import { Address, Assets, createClient } from "@evolution-sdk/evolution" +import { Address, Assets, createClient, preprod} from "@evolution-sdk/evolution" const client = createClient({ - network: "preprod", + chain: preprod, provider: { type: "blockfrost", baseUrl: "https://cardano-preprod.blockfrost.io/api/v0", projectId: process.env.BLOCKFROST_API_KEY! }, wallet: { type: "seed", mnemonic: process.env.WALLET_MNEMONIC!, accountIndex: 0 } }) @@ -83,10 +83,10 @@ await signed2.submit() Use `tx1.chainResult().available` to find the output you want to spend in tx2. ```typescript twoslash -import { Address, Assets, createClient } from "@evolution-sdk/evolution" +import { Address, Assets, createClient, preprod} from "@evolution-sdk/evolution" const client = createClient({ - network: "preprod", + chain: preprod, provider: { type: "blockfrost", baseUrl: "https://cardano-preprod.blockfrost.io/api/v0", projectId: process.env.BLOCKFROST_API_KEY! }, wallet: { type: "seed", mnemonic: process.env.WALLET_MNEMONIC!, accountIndex: 0 } }) @@ -125,10 +125,10 @@ await (await tx2.sign()).submit() Chain three builds together up-front, then submit all three. ```typescript twoslash -import { Address, Assets, createClient } from "@evolution-sdk/evolution" +import { Address, Assets, createClient, preprod} from "@evolution-sdk/evolution" const client = createClient({ - network: "preprod", + chain: preprod, provider: { type: "blockfrost", baseUrl: "https://cardano-preprod.blockfrost.io/api/v0", projectId: process.env.BLOCKFROST_API_KEY! }, wallet: { type: "seed", mnemonic: process.env.WALLET_MNEMONIC!, accountIndex: 0 } }) diff --git a/docs/content/docs/transactions/first-transaction.mdx b/docs/content/docs/transactions/first-transaction.mdx index f1d93808..bad61ce0 100644 --- a/docs/content/docs/transactions/first-transaction.mdx +++ b/docs/content/docs/transactions/first-transaction.mdx @@ -14,11 +14,11 @@ This guide walks through a complete payment transaction from client setup to on- Here's a full transaction workflow—configure once, then build, sign, and submit: ```ts twoslash -import { Address, Assets, createClient } from "@evolution-sdk/evolution"; +import { Address, Assets, createClient, preprod} from "@evolution-sdk/evolution"; // 1. Configure your client const client = createClient({ - network: "preprod", + chain: preprod, provider: { type: "blockfrost", baseUrl: "https://cardano-preprod.blockfrost.io/api/v0", @@ -54,10 +54,10 @@ console.log("Transaction submitted:", txHash); Set up your connection to the network. This happens once—you'll reuse the client throughout your application: ```ts twoslash -import { Address, Assets, createClient } from "@evolution-sdk/evolution"; +import { Address, Assets, createClient, preprod} from "@evolution-sdk/evolution"; const client = createClient({ - network: "preprod", + chain: preprod, provider: { type: "blockfrost", baseUrl: "https://cardano-preprod.blockfrost.io/api/v0", @@ -76,10 +76,10 @@ const client = createClient({ Chain operations to specify what the transaction should do. Call `.build()` when ready to finalize: ```ts twoslash -import { Address, Assets, createClient } from "@evolution-sdk/evolution"; +import { Address, Assets, createClient, preprod} from "@evolution-sdk/evolution"; const client = createClient({ - network: "preprod", + chain: preprod, provider: { type: "blockfrost", baseUrl: "", projectId: "" }, wallet: { type: "seed", mnemonic: "", accountIndex: 0 } }); @@ -99,10 +99,10 @@ The builder handles UTxO selection, fee calculation, and change outputs automati Authorize the transaction with your wallet's private keys: ```ts twoslash -import { Address, Assets, createClient } from "@evolution-sdk/evolution"; +import { Address, Assets, createClient, preprod} from "@evolution-sdk/evolution"; const client = createClient({ - network: "preprod", + chain: preprod, provider: { type: "blockfrost", baseUrl: "", projectId: "" }, wallet: { type: "seed", mnemonic: "", accountIndex: 0 } }); @@ -119,10 +119,10 @@ const signed = await tx.sign(); Broadcast the signed transaction to the blockchain and get the transaction hash: ```ts twoslash -import { Address, Assets, createClient } from "@evolution-sdk/evolution"; +import { Address, Assets, createClient, preprod} from "@evolution-sdk/evolution"; const client = createClient({ - network: "preprod", + chain: preprod, provider: { type: "blockfrost", baseUrl: "", projectId: "" }, wallet: { type: "seed", mnemonic: "", accountIndex: 0 } }); diff --git a/docs/content/docs/transactions/multi-output.mdx b/docs/content/docs/transactions/multi-output.mdx index e4e6ff32..bc976639 100644 --- a/docs/content/docs/transactions/multi-output.mdx +++ b/docs/content/docs/transactions/multi-output.mdx @@ -10,10 +10,10 @@ Chain multiple `.payToAddress()` calls to send to several recipients in a single ## Multiple Recipients ```typescript twoslash -import { Address, Assets, createClient } from "@evolution-sdk/evolution" +import { Address, Assets, createClient, preprod} from "@evolution-sdk/evolution" const client = createClient({ - network: "preprod", + chain: preprod, provider: { type: "blockfrost", baseUrl: "https://cardano-preprod.blockfrost.io/api/v0", projectId: process.env.BLOCKFROST_API_KEY! }, wallet: { type: "seed", mnemonic: process.env.WALLET_MNEMONIC!, accountIndex: 0 } }) @@ -43,10 +43,10 @@ await signed.submit() Drain your entire wallet to a single address using `sendAll`: ```typescript twoslash -import { Address, createClient } from "@evolution-sdk/evolution" +import { Address, createClient, preprod} from "@evolution-sdk/evolution" const client = createClient({ - network: "preprod", + chain: preprod, provider: { type: "blockfrost", baseUrl: "https://cardano-preprod.blockfrost.io/api/v0", projectId: process.env.BLOCKFROST_API_KEY! }, wallet: { type: "seed", mnemonic: process.env.WALLET_MNEMONIC!, accountIndex: 0 } }) diff --git a/docs/content/docs/transactions/retry-safe.mdx b/docs/content/docs/transactions/retry-safe.mdx index 594ac37a..554b0769 100644 --- a/docs/content/docs/transactions/retry-safe.mdx +++ b/docs/content/docs/transactions/retry-safe.mdx @@ -42,10 +42,10 @@ Querying chain state **outside** the action and passing it in as a static value The simplest approach: wrap the full pipeline in an async function and call it from a retry loop. ```ts twoslash -import { Address, Assets, createClient } from "@evolution-sdk/evolution"; +import { Address, Assets, createClient, preprod} from "@evolution-sdk/evolution"; const client = createClient({ - network: "preprod", + chain: preprod, provider: { type: "blockfrost", baseUrl: "https://cardano-preprod.blockfrost.io/api/v0", @@ -89,10 +89,10 @@ console.log("Submitted:", txHash); When collecting from a script address, query the script UTxOs inside the action so each retry gets a fresh view of what is available at that address. ```ts twoslash -import { Address, Assets, createClient } from "@evolution-sdk/evolution"; +import { Address, Assets, createClient, preprod} from "@evolution-sdk/evolution"; const client = createClient({ - network: "preprod", + chain: preprod, provider: { type: "blockfrost", baseUrl: "https://cardano-preprod.blockfrost.io/api/v0", @@ -125,11 +125,11 @@ async function unlockFromScript() { When using Effect, compose the full pipeline as a single `Effect.gen` and apply `Effect.retry` directly. `Schedule` controls the timing and number of attempts. ```ts twoslash -import { Address, createClient } from "@evolution-sdk/evolution"; +import { Address, createClient, preprod} from "@evolution-sdk/evolution"; import { Effect, Schedule } from "effect"; const client = createClient({ - network: "preprod", + chain: preprod, provider: { type: "blockfrost", baseUrl: "https://cardano-preprod.blockfrost.io/api/v0", diff --git a/docs/content/docs/transactions/simple-payment.mdx b/docs/content/docs/transactions/simple-payment.mdx index 70e07a88..a4124a77 100644 --- a/docs/content/docs/transactions/simple-payment.mdx +++ b/docs/content/docs/transactions/simple-payment.mdx @@ -14,10 +14,10 @@ This guide covers common payment patterns—from basic ADA transfers to payments The simplest transaction sends only lovelace (ADA's smallest unit). 1 ADA = 1,000,000 lovelace: ```ts twoslash -import { Address, Assets, createClient } from "@evolution-sdk/evolution"; +import { Address, Assets, createClient, preprod} from "@evolution-sdk/evolution"; const client = createClient({ - network: "preprod", + chain: preprod, provider: { type: "blockfrost", baseUrl: "https://cardano-preprod.blockfrost.io/api/v0", @@ -66,10 +66,10 @@ console.log(lovelace); // 2500000n Include native tokens (custom tokens or NFTs) alongside ADA. The `assets` object takes any asset by its policy ID + asset name: ```ts twoslash -import { Address, Assets, createClient } from "@evolution-sdk/evolution"; +import { Address, Assets, createClient, preprod} from "@evolution-sdk/evolution"; const client = createClient({ - network: "preprod", + chain: preprod, provider: { type: "blockfrost", baseUrl: "https://cardano-preprod.blockfrost.io/api/v0", @@ -109,10 +109,10 @@ The policy ID + asset name is concatenated into a single hex string. Make your code more readable with descriptive variable names: ```ts twoslash -import { Address, Assets, createClient } from "@evolution-sdk/evolution"; +import { Address, Assets, createClient, preprod} from "@evolution-sdk/evolution"; const client = createClient({ - network: "preprod", + chain: preprod, provider: { type: "blockfrost", baseUrl: "", projectId: "" }, wallet: { type: "seed", mnemonic: "", accountIndex: 0 } }); @@ -135,10 +135,10 @@ const tx = await client Adjust transaction values based on network or configuration: ```ts twoslash -import { Address, Assets, createClient } from "@evolution-sdk/evolution"; +import { Address, Assets, createClient, preprod} from "@evolution-sdk/evolution"; const client = createClient({ - network: "preprod", + chain: preprod, provider: { type: "blockfrost", baseUrl: "", projectId: "" }, wallet: { type: "seed", mnemonic: "", accountIndex: 0 } }); diff --git a/docs/content/docs/wallets/api-wallet.mdx b/docs/content/docs/wallets/api-wallet.mdx index fa4f6224..7323f0f6 100644 --- a/docs/content/docs/wallets/api-wallet.mdx +++ b/docs/content/docs/wallets/api-wallet.mdx @@ -39,7 +39,7 @@ Never request or store user keys. Frontend signs only and should not include pro Frontend creates API wallet client without provider. Can sign and submit transactions but cannot build them. ```typescript twoslash -import { createClient } from "@evolution-sdk/evolution"; +import { createClient, mainnet } from "@evolution-sdk/evolution"; declare const cardano: any; // window.cardano @@ -49,7 +49,7 @@ async function signAndSubmit() { // 2. Create API wallet client (no provider needed for signing/submitting) const client = createClient({ - network: "mainnet", + chain: mainnet, wallet: { type: "api", api: walletApi } }); @@ -88,7 +88,7 @@ interface ApiWalletConfig { ## Complete dApp Example ```typescript twoslash -import { createClient } from "@evolution-sdk/evolution"; +import { createClient, mainnet } from "@evolution-sdk/evolution"; declare const cardano: any; @@ -107,7 +107,7 @@ async function connectAndPay() { // Create API wallet client const client = createClient({ - network: "mainnet", + chain: mainnet, wallet: { type: "api", api: walletApi } }); @@ -141,7 +141,7 @@ async function connectAndPay() { Hardware wallets work through browser extensions. The extension communicates with the hardware device. ```typescript twoslash -import { createClient } from "@evolution-sdk/evolution"; +import { createClient, mainnet } from "@evolution-sdk/evolution"; declare const cardano: any; @@ -151,7 +151,7 @@ async function useHardwareWallet() { // Create API wallet client (same as software wallets) const client = createClient({ - network: "mainnet", + chain: mainnet, wallet: { type: "api", api: walletApi } }); @@ -182,7 +182,7 @@ Hardware wallets and extensions follow Cardano's BIP-32 derivation paths: ## Error Handling ```typescript twoslash -import { createClient } from "@evolution-sdk/evolution"; +import { createClient, mainnet } from "@evolution-sdk/evolution"; declare const cardano: any; @@ -198,7 +198,7 @@ async function connectWallet(walletName: string) { // Create API wallet client const client = createClient({ - network: "mainnet", + chain: mainnet, wallet: { type: "api", api: walletApi } }); diff --git a/docs/content/docs/wallets/private-key.mdx b/docs/content/docs/wallets/private-key.mdx index 20346cec..301b7963 100644 --- a/docs/content/docs/wallets/private-key.mdx +++ b/docs/content/docs/wallets/private-key.mdx @@ -39,12 +39,12 @@ Never log or transmit keys in plaintext. Never store in environment variables as ## Basic Setup ```typescript twoslash -import { createClient } from "@evolution-sdk/evolution"; +import { createClient, preprod } from "@evolution-sdk/evolution"; // Create signing-only client with private key (no provider) // Can sign transactions but cannot query blockchain or submit const client = createClient({ - network: "preprod", + chain: preprod, wallet: { type: "private-key", paymentKey: process.env.PAYMENT_SIGNING_KEY! // 192 hex chars @@ -74,7 +74,7 @@ interface PrivateKeyWalletConfig { Load keys from secure secret management systems: ```typescript twoslash -import { createClient } from "@evolution-sdk/evolution"; +import { createClient, mainnet } from "@evolution-sdk/evolution"; // Mock vault client for documentation purposes declare const secretsManager: { @@ -88,7 +88,7 @@ async function createSecureClient() { const signingKey = await loadFromSecureVault("cardano-payment-key"); return createClient({ - network: "mainnet", + chain: mainnet, wallet: { type: "private-key", paymentKey: signingKey @@ -128,7 +128,7 @@ Log all key access events without logging the keys themselves. Alert on unusual ## AWS Secrets Manager Example ```typescript twoslash -import { createClient } from "@evolution-sdk/evolution"; +import { createClient, mainnet } from "@evolution-sdk/evolution"; // Mock AWS SDK classes for documentation declare class SecretsManagerClient { @@ -153,7 +153,7 @@ async function createProductionClient() { // Create client with retrieved key return createClient({ - network: "mainnet", + chain: mainnet, wallet: { type: "private-key", paymentKey: secret.paymentKey @@ -165,7 +165,7 @@ async function createProductionClient() { ## Azure Key Vault Example ```typescript twoslash -import { createClient } from "@evolution-sdk/evolution"; +import { createClient, mainnet } from "@evolution-sdk/evolution"; // Mock Azure SDK classes for documentation declare class DefaultAzureCredential {} @@ -184,7 +184,7 @@ async function createProductionClient() { const secret = await secretClient.getSecret("cardano-payment-key"); return createClient({ - network: "mainnet", + chain: mainnet, wallet: { type: "private-key", paymentKey: secret.value! @@ -196,7 +196,7 @@ async function createProductionClient() { ## Key Rotation Strategy ```typescript twoslash -import { createClient } from "@evolution-sdk/evolution"; +import { createClient, mainnet } from "@evolution-sdk/evolution"; async function rotateKeys() { // 1. Generate new key (offline, secure environment) @@ -207,7 +207,7 @@ async function rotateKeys() { // 3. Create client with new key const client = createClient({ - network: "mainnet", + chain: mainnet, wallet: { type: "private-key", paymentKey: await loadFromVault("cardano-payment-key-new") @@ -235,11 +235,11 @@ declare function archiveKey(id: string): Promise; ## Environment Separation ```typescript twoslash -import { createClient } from "@evolution-sdk/evolution"; +import { createClient, preprod, mainnet } from "@evolution-sdk/evolution"; // Development const devClient = createClient({ - network: "preprod", + chain: preprod, wallet: { type: "private-key", paymentKey: await loadFromVault("dev/cardano-payment-key") @@ -248,7 +248,7 @@ const devClient = createClient({ // Staging const stagingClient = createClient({ - network: "preprod", // Still testnet + chain: preprod, // Still testnet wallet: { type: "private-key", paymentKey: await loadFromVault("staging/cardano-payment-key") // Different key @@ -257,7 +257,7 @@ const stagingClient = createClient({ // Production const prodClient = createClient({ - network: "mainnet", + chain: mainnet, wallet: { type: "private-key", paymentKey: await loadFromVault("prod/cardano-payment-key") // Different key diff --git a/docs/content/docs/wallets/security.mdx b/docs/content/docs/wallets/security.mdx index 5594bac4..8c94fc0c 100644 --- a/docs/content/docs/wallets/security.mdx +++ b/docs/content/docs/wallets/security.mdx @@ -160,7 +160,7 @@ BLOCKFROST_PROJECT_ID=preprodxxxxxxxxxxxx // backend code (see /docs/clients for client creation examples). const providerConfig = { - network: process.env.NETWORK as "preprod" | "mainnet", + chain: process.env.NETWORK === "preprod" ? preprod : mainnet, provider: { type: "blockfrost", baseUrl: process.env.NETWORK === "preprod" diff --git a/docs/content/docs/wallets/seed-phrase.mdx b/docs/content/docs/wallets/seed-phrase.mdx index f1d1c0a8..179d6330 100644 --- a/docs/content/docs/wallets/seed-phrase.mdx +++ b/docs/content/docs/wallets/seed-phrase.mdx @@ -48,12 +48,12 @@ console.log(mnemonic); ## Basic Setup ```typescript twoslash -import { PrivateKey, createClient } from "@evolution-sdk/evolution"; +import { PrivateKey, createClient, preprod } from "@evolution-sdk/evolution"; // Create a signing-only client with seed wallet (no provider) // Can sign transactions but cannot query blockchain or submit const client = createClient({ - network: "preprod", + chain: preprod, wallet: { type: "seed", mnemonic: "fitness juice ankle box prepare gallery purse narrow miracle next soccer category analyst wait verb patch kit era hen clerk write skin trumpet attract", @@ -84,11 +84,11 @@ interface SeedWalletConfig { Different networks use the same wallet configuration—just change the network parameter: ```typescript twoslash -import { PrivateKey, createClient } from "@evolution-sdk/evolution"; +import { PrivateKey, createClient, preprod, mainnet } from "@evolution-sdk/evolution"; // Testnet client const testClient = createClient({ - network: "preprod", + chain: preprod, wallet: { type: "seed", mnemonic: "fitness juice ankle box prepare gallery purse narrow miracle next soccer category analyst wait verb patch kit era hen clerk write skin trumpet attract", @@ -98,7 +98,7 @@ const testClient = createClient({ // Mainnet client (use DIFFERENT mnemonic in production!) const mainClient = createClient({ - network: "mainnet", + chain: mainnet, wallet: { type: "seed", mnemonic: process.env.WALLET_MNEMONIC!, // Different mnemonic! @@ -116,10 +116,10 @@ BLOCKFROST_PROJECT_ID="preprodYourProjectIdHere" ``` ```typescript twoslash -import { PrivateKey, createClient } from "@evolution-sdk/evolution"; +import { PrivateKey, createClient, preprod } from "@evolution-sdk/evolution"; const client = createClient({ - network: "preprod", + chain: preprod, wallet: { type: "seed", mnemonic: process.env.WALLET_MNEMONIC!, // From environment @@ -133,11 +133,11 @@ const client = createClient({ Generate independent wallets from the same mnemonic using different `accountIndex` values: ```typescript twoslash -import { PrivateKey, createClient } from "@evolution-sdk/evolution"; +import { PrivateKey, createClient, preprod } from "@evolution-sdk/evolution"; // Account 0 (default) const account0 = createClient({ - network: "preprod", + chain: preprod, wallet: { type: "seed", mnemonic: process.env.WALLET_MNEMONIC!, @@ -147,7 +147,7 @@ const account0 = createClient({ // Account 1 (different addresses, same mnemonic) const account1 = createClient({ - network: "preprod", + chain: preprod, wallet: { type: "seed", mnemonic: process.env.WALLET_MNEMONIC!, @@ -165,7 +165,7 @@ console.log("Different addresses:", addr0 !== addr1); // true ### Development Testing ```typescript twoslash -import { PrivateKey, createClient } from "@evolution-sdk/evolution"; +import { PrivateKey, createClient, preprod } from "@evolution-sdk/evolution"; // Mock test runner functions for documentation declare function describe(name: string, fn: () => void): void; @@ -181,7 +181,7 @@ describe("Payment tests", () => { beforeEach(() => { client = createClient({ - network: "preprod", + chain: preprod, wallet: { type: "seed", mnemonic: process.env.TEST_WALLET_MNEMONIC!, diff --git a/docs/next-env.d.ts b/docs/next-env.d.ts index 7a70f65a..9edff1c7 100644 --- a/docs/next-env.d.ts +++ b/docs/next-env.d.ts @@ -1,6 +1,6 @@ /// /// -import "./.next/types/routes.d.ts" +import "./.next/types/routes.d.ts"; // NOTE: This file should not be edited // see https://nextjs.org/docs/app/api-reference/config/typescript for more information. diff --git a/examples/with-vite-react/src/components/TransactionBuilder.tsx b/examples/with-vite-react/src/components/TransactionBuilder.tsx index fa89e78d..1d05f2df 100644 --- a/examples/with-vite-react/src/components/TransactionBuilder.tsx +++ b/examples/with-vite-react/src/components/TransactionBuilder.tsx @@ -1,7 +1,7 @@ import { useCardano } from "@cardano-foundation/cardano-connect-with-wallet" import { NetworkType } from "@cardano-foundation/cardano-connect-with-wallet-core" import { useState } from "react" -import { Address, Assets, createClient, TransactionHash } from "@evolution-sdk/evolution" +import { Address, Assets, createClient, mainnet, preprod, preview, TransactionHash } from "@evolution-sdk/evolution" export default function TransactionBuilder() { const [txHash, setTxHash] = useState(null) @@ -46,8 +46,12 @@ export default function TransactionBuilder() { throw new Error("Failed to enable wallet") } - // Determine network ID and provider config - const networkId = networkEnv // "preprod", "preview", or "mainnet" + // Determine chain from environment variable + const chainMap = { mainnet, preprod, preview } as const + const resolvedKey = (networkEnv as keyof typeof chainMap) in chainMap + ? (networkEnv as keyof typeof chainMap) + : "preprod" + const chain = chainMap[resolvedKey] // Configure Blockfrost provider based on network const blockfrostUrls = { @@ -58,13 +62,13 @@ export default function TransactionBuilder() { const providerConfig = { type: "blockfrost" as const, - baseUrl: blockfrostUrls[networkId as keyof typeof blockfrostUrls], + baseUrl: blockfrostUrls[resolvedKey], projectId: import.meta.env.VITE_BLOCKFROST_PROJECT_ID || "" } // Create client with wallet and provider const client = createClient({ - network: networkId, + chain, provider: providerConfig, wallet: { type: "api", api } }) diff --git a/packages/evolution-devnet/src/Cluster.ts b/packages/evolution-devnet/src/Cluster.ts index d49fa385..51aa346f 100644 --- a/packages/evolution-devnet/src/Cluster.ts +++ b/packages/evolution-devnet/src/Cluster.ts @@ -519,17 +519,9 @@ export interface SlotConfig { * @example * ```typescript * import * as Cluster from "@evolution-sdk/devnet/Cluster" - * import { createClient } from "@evolution-sdk/evolution/sdk/client/ClientImpl" * * const cluster = await Cluster.make({ ... }) * const slotConfig = Cluster.getSlotConfig(cluster) - * - * const client = createClient({ - * network: 0, - * slotConfig, - * provider: { type: "kupmios", kupoUrl: "...", ogmiosUrl: "..." }, - * wallet: { type: "seed", mnemonic: "..." } - * }) * ``` * * @since 2.0.0 @@ -547,3 +539,49 @@ export const getSlotConfig = (cluster: Cluster): SlotConfig => { slotLength } } + +/** + * Create a Chain descriptor for a running devnet cluster. + * + * The returned object is structurally compatible with the `Chain` interface + * from `@evolution-sdk/evolution` and can be passed directly to `createClient`. + * + * @example + * ```typescript + * const cluster = await Cluster.make({ ... }) + * await Cluster.start(cluster) + * const client = createClient({ + * chain: Cluster.getChain(cluster), + * provider: { type: "kupmios", kupoUrl: "...", ogmiosUrl: "..." }, + * wallet: { type: "seed", mnemonic: "..." } + * }) + * ``` + * + * @since 2.1.0 + * @category utilities + */ +export const getChain = (cluster: Cluster) => ({ + name: "Devnet", + id: 0 as const, + networkMagic: cluster.shelleyGenesis.networkMagic, + slotConfig: getSlotConfig(cluster), + epochLength: cluster.shelleyGenesis.epochLength +}) + +/** + * A minimal testnet chain descriptor for bootstrapping (e.g., deriving wallet addresses + * before a cluster is started). Uses `id: 0` so addresses are in testnet bech32 format. + * + * Slot config values are zero-based placeholders — valid for address derivation but + * not for time-based validity windows. Use `getChain(cluster)` once the cluster is running. + * + * @since 2.1.0 + * @category constants + */ +export const BOOTSTRAP_CHAIN = { + name: "Devnet", + id: 0 as const, + networkMagic: Config.DEFAULT_DEVNET_CONFIG.networkMagic, + slotConfig: { zeroTime: 0n, zeroSlot: 0n, slotLength: 1000 }, + epochLength: Config.DEFAULT_DEVNET_CONFIG.shelleyGenesis.epochLength ?? 432000 +} as const diff --git a/packages/evolution-devnet/test/Client.Devnet.test.ts b/packages/evolution-devnet/test/Client.Devnet.test.ts index 39b1bd80..7f669c11 100644 --- a/packages/evolution-devnet/test/Client.Devnet.test.ts +++ b/packages/evolution-devnet/test/Client.Devnet.test.ts @@ -24,7 +24,7 @@ describe("Client with Devnet", () => { const createTestClient = () => createClient({ - network: 0, + chain: Cluster.getChain(devnetCluster!), provider: { type: "kupmios", kupoUrl: "http://localhost:1443", @@ -39,7 +39,7 @@ describe("Client with Devnet", () => { beforeAll(async () => { const testClient = createClient({ - network: 0, + chain: Cluster.BOOTSTRAP_CHAIN, wallet: { type: "seed", mnemonic: TEST_MNEMONIC, accountIndex: 0 } }) diff --git a/packages/evolution-devnet/test/TxBuilder.AddSigner.test.ts b/packages/evolution-devnet/test/TxBuilder.AddSigner.test.ts index 60fcb3f0..79021e49 100644 --- a/packages/evolution-devnet/test/TxBuilder.AddSigner.test.ts +++ b/packages/evolution-devnet/test/TxBuilder.AddSigner.test.ts @@ -25,10 +25,8 @@ describe("TxBuilder addSigner (Devnet Submit)", () => { const createTestClient = (accountIndex: number = 0) => { if (!devnetCluster) throw new Error("Cluster not initialized") - const slotConfig = Cluster.getSlotConfig(devnetCluster) return createClient({ - network: 0, - slotConfig, + chain: Cluster.getChain(devnetCluster), provider: { type: "kupmios", kupoUrl: "http://localhost:1449", @@ -45,7 +43,7 @@ describe("TxBuilder addSigner (Devnet Submit)", () => { beforeAll(async () => { const tempClient = createClient({ - network: 0, + chain: Cluster.BOOTSTRAP_CHAIN, wallet: { type: "seed", mnemonic: TEST_MNEMONIC, accountIndex: 0, addressType: "Base" } }) diff --git a/packages/evolution-devnet/test/TxBuilder.Chain.test.ts b/packages/evolution-devnet/test/TxBuilder.Chain.test.ts index f9ab95c8..da7576d6 100644 --- a/packages/evolution-devnet/test/TxBuilder.Chain.test.ts +++ b/packages/evolution-devnet/test/TxBuilder.Chain.test.ts @@ -18,10 +18,8 @@ describe("TxBuilder.chainResult", () => { const createTestClient = (accountIndex: number = 0) => { if (!devnetCluster) throw new Error("Cluster not initialized") - const slotConfig = Cluster.getSlotConfig(devnetCluster) return createClient({ - network: 0, - slotConfig, + chain: Cluster.getChain(devnetCluster), provider: { type: "kupmios", kupoUrl: "http://localhost:1449", @@ -38,7 +36,7 @@ describe("TxBuilder.chainResult", () => { beforeAll(async () => { const tempClient = createClient({ - network: 0, + chain: Cluster.BOOTSTRAP_CHAIN, wallet: { type: "seed", mnemonic: TEST_MNEMONIC, accountIndex: 0, addressType: "Base" } }) diff --git a/packages/evolution-devnet/test/TxBuilder.Compose.test.ts b/packages/evolution-devnet/test/TxBuilder.Compose.test.ts index 6d4c5a3c..011960f3 100644 --- a/packages/evolution-devnet/test/TxBuilder.Compose.test.ts +++ b/packages/evolution-devnet/test/TxBuilder.Compose.test.ts @@ -26,10 +26,8 @@ describe("TxBuilder compose (Devnet Submit)", () => { const createTestClient = (accountIndex: number = 0) => { if (!devnetCluster) throw new Error("Cluster not initialized") - const slotConfig = Cluster.getSlotConfig(devnetCluster) return createClient({ - network: 0, - slotConfig, + chain: Cluster.getChain(devnetCluster), provider: { type: "kupmios", kupoUrl: "http://localhost:1451", @@ -46,7 +44,7 @@ describe("TxBuilder compose (Devnet Submit)", () => { beforeAll(async () => { const tempClient = createClient({ - network: 0, + chain: Cluster.BOOTSTRAP_CHAIN, wallet: { type: "seed", mnemonic: TEST_MNEMONIC, accountIndex: 0, addressType: "Base" } }) diff --git a/packages/evolution-devnet/test/TxBuilder.Governance.test.ts b/packages/evolution-devnet/test/TxBuilder.Governance.test.ts index 917922b4..4020ec17 100644 --- a/packages/evolution-devnet/test/TxBuilder.Governance.test.ts +++ b/packages/evolution-devnet/test/TxBuilder.Governance.test.ts @@ -27,7 +27,7 @@ describe("TxBuilder Governance Operations", () => { const createTestClient = (accountIndex: number = 0) => createClient({ - network: 0, + chain: Cluster.getChain(devnetCluster!), provider: { type: "kupmios", kupoUrl: "http://localhost:1452", @@ -45,7 +45,7 @@ describe("TxBuilder Governance Operations", () => { // Create clients for governance tests const accounts = [0, 1, 2, 3, 4].map((accountIndex) => createClient({ - network: 0, + chain: Cluster.BOOTSTRAP_CHAIN, wallet: { type: "seed", mnemonic: TEST_MNEMONIC, accountIndex, addressType: "Base" } }) ) diff --git a/packages/evolution-devnet/test/TxBuilder.Metadata.test.ts b/packages/evolution-devnet/test/TxBuilder.Metadata.test.ts index 8036a21f..eab1f56a 100644 --- a/packages/evolution-devnet/test/TxBuilder.Metadata.test.ts +++ b/packages/evolution-devnet/test/TxBuilder.Metadata.test.ts @@ -25,10 +25,8 @@ describe("TxBuilder attachMetadata (Devnet Submit)", () => { const createTestClient = (accountIndex: number = 0) => { if (!devnetCluster) throw new Error("Cluster not initialized") - const slotConfig = Cluster.getSlotConfig(devnetCluster) return createClient({ - network: 0, - slotConfig, + chain: Cluster.getChain(devnetCluster), provider: { type: "kupmios", kupoUrl: "http://localhost:1450", @@ -45,7 +43,7 @@ describe("TxBuilder attachMetadata (Devnet Submit)", () => { beforeAll(async () => { const tempClient = createClient({ - network: 0, + chain: Cluster.BOOTSTRAP_CHAIN, wallet: { type: "seed", mnemonic: TEST_MNEMONIC, accountIndex: 0, addressType: "Base" } }) diff --git a/packages/evolution-devnet/test/TxBuilder.Mint.test.ts b/packages/evolution-devnet/test/TxBuilder.Mint.test.ts index 1e413da9..17db7dfc 100644 --- a/packages/evolution-devnet/test/TxBuilder.Mint.test.ts +++ b/packages/evolution-devnet/test/TxBuilder.Mint.test.ts @@ -31,7 +31,7 @@ describe("TxBuilder Minting (Devnet Submit)", () => { const createTestClient = () => createClient({ - network: 0, + chain: Cluster.getChain(devnetCluster!), provider: { type: "kupmios", kupoUrl: "http://localhost:1443", @@ -46,7 +46,7 @@ describe("TxBuilder Minting (Devnet Submit)", () => { beforeAll(async () => { const testClient = createClient({ - network: 0, + chain: Cluster.BOOTSTRAP_CHAIN, wallet: { type: "seed", mnemonic: TEST_MNEMONIC, accountIndex: 0 } }) diff --git a/packages/evolution-devnet/test/TxBuilder.NativeScript.test.ts b/packages/evolution-devnet/test/TxBuilder.NativeScript.test.ts index c4c43850..a3f5bf2e 100644 --- a/packages/evolution-devnet/test/TxBuilder.NativeScript.test.ts +++ b/packages/evolution-devnet/test/TxBuilder.NativeScript.test.ts @@ -42,10 +42,8 @@ describe("TxBuilder NativeScript (Devnet Submit)", () => { const createTestClient = (accountIndex: number = 0) => { if (!devnetCluster) throw new Error("Cluster not initialized") - const slotConfig = Cluster.getSlotConfig(devnetCluster) return createClient({ - network: 0, - slotConfig, + chain: Cluster.getChain(devnetCluster), provider: { type: "kupmios", kupoUrl: "http://localhost:1449", @@ -62,7 +60,7 @@ describe("TxBuilder NativeScript (Devnet Submit)", () => { beforeAll(async () => { const tempClient = createClient({ - network: 0, + chain: Cluster.BOOTSTRAP_CHAIN, wallet: { type: "seed", mnemonic: TEST_MNEMONIC, accountIndex: 0, addressType: "Base" } }) diff --git a/packages/evolution-devnet/test/TxBuilder.PlutusMint.test.ts b/packages/evolution-devnet/test/TxBuilder.PlutusMint.test.ts index bc328d91..a47ccbb7 100644 --- a/packages/evolution-devnet/test/TxBuilder.PlutusMint.test.ts +++ b/packages/evolution-devnet/test/TxBuilder.PlutusMint.test.ts @@ -66,7 +66,7 @@ describe("TxBuilder Plutus Minting (Devnet Submit)", () => { const createTestClient = () => createClient({ - network: 0, + chain: Cluster.getChain(devnetCluster!), provider: { type: "kupmios", kupoUrl: "http://localhost:1444", @@ -84,7 +84,7 @@ describe("TxBuilder Plutus Minting (Devnet Submit)", () => { expect(calculatedPolicyId).toBe(SIMPLE_MINT_POLICY_ID_HEX) const testClient = createClient({ - network: 0, + chain: Cluster.BOOTSTRAP_CHAIN, wallet: { type: "seed", mnemonic: TEST_MNEMONIC, accountIndex: 0 } }) diff --git a/packages/evolution-devnet/test/TxBuilder.Pool.test.ts b/packages/evolution-devnet/test/TxBuilder.Pool.test.ts index 796b1313..b93a6575 100644 --- a/packages/evolution-devnet/test/TxBuilder.Pool.test.ts +++ b/packages/evolution-devnet/test/TxBuilder.Pool.test.ts @@ -32,7 +32,7 @@ describe("TxBuilder Pool Operations", () => { const createTestClient = (accountIndex: number = 0) => createClient({ - network: 0, + chain: Cluster.getChain(devnetCluster!), provider: { type: "kupmios", kupoUrl: "http://localhost:1453", @@ -50,7 +50,7 @@ describe("TxBuilder Pool Operations", () => { // Create clients for pool tests const accounts = [0, 1].map((accountIndex) => createClient({ - network: 0, + chain: Cluster.BOOTSTRAP_CHAIN, wallet: { type: "seed", mnemonic: TEST_MNEMONIC, accountIndex, addressType: "Base" } }) ) diff --git a/packages/evolution-devnet/test/TxBuilder.RedeemerBuilder.test.ts b/packages/evolution-devnet/test/TxBuilder.RedeemerBuilder.test.ts index 62534689..f632989e 100644 --- a/packages/evolution-devnet/test/TxBuilder.RedeemerBuilder.test.ts +++ b/packages/evolution-devnet/test/TxBuilder.RedeemerBuilder.test.ts @@ -85,7 +85,7 @@ describe("TxBuilder RedeemerBuilder", () => { const createTestClient = () => createClient({ - network: 0, + chain: Cluster.getChain(devnetCluster!), provider: { type: "kupmios", kupoUrl: "http://localhost:1445", @@ -103,7 +103,7 @@ describe("TxBuilder RedeemerBuilder", () => { expect(calculatedPolicyId).toBe(MINT_MULTI_POLICY_ID_HEX) const testClient = createClient({ - network: 0, + chain: Cluster.BOOTSTRAP_CHAIN, wallet: { type: "seed", mnemonic: TEST_MNEMONIC, accountIndex: 0 } }) diff --git a/packages/evolution-devnet/test/TxBuilder.ScriptStake.test.ts b/packages/evolution-devnet/test/TxBuilder.ScriptStake.test.ts index 780d354d..cf97b001 100644 --- a/packages/evolution-devnet/test/TxBuilder.ScriptStake.test.ts +++ b/packages/evolution-devnet/test/TxBuilder.ScriptStake.test.ts @@ -83,7 +83,7 @@ describe("TxBuilder Script Stake Operations", () => { const createTestClient = (accountIndex: number = 0) => createClient({ - network: 0, + chain: Cluster.getChain(devnetCluster!), provider: { type: "kupmios", kupoUrl: "http://localhost:1447", @@ -102,7 +102,7 @@ describe("TxBuilder Script Stake Operations", () => { expect(calculatedScriptHash).toBe(STAKE_MULTI_SCRIPT_HASH) const testClient = createClient({ - network: 0, + chain: Cluster.BOOTSTRAP_CHAIN, wallet: { type: "seed", mnemonic: TEST_MNEMONIC, accountIndex: 0, addressType: "Base" } }) diff --git a/packages/evolution-devnet/test/TxBuilder.SpendScriptRef.test.ts b/packages/evolution-devnet/test/TxBuilder.SpendScriptRef.test.ts index 8c40cff4..3ec59bb1 100644 --- a/packages/evolution-devnet/test/TxBuilder.SpendScriptRef.test.ts +++ b/packages/evolution-devnet/test/TxBuilder.SpendScriptRef.test.ts @@ -39,7 +39,7 @@ describe("TxBuilder Spend ScriptRef (Devnet Submit)", () => { const createTestClient = () => createClient({ - network: 0, + chain: Cluster.getChain(devnetCluster!), provider: { type: "kupmios", kupoUrl: "http://localhost:1454", @@ -52,7 +52,7 @@ describe("TxBuilder Spend ScriptRef (Devnet Submit)", () => { expect(ScriptHash.toHex(alwaysSucceedScriptHash)).toBe(ALWAYS_SUCCEED_HASH) const testClient = createClient({ - network: 0, + chain: Cluster.BOOTSTRAP_CHAIN, wallet: { type: "seed", mnemonic: TEST_MNEMONIC, accountIndex: 0 } }) diff --git a/packages/evolution-devnet/test/TxBuilder.Stake.test.ts b/packages/evolution-devnet/test/TxBuilder.Stake.test.ts index 8679400d..cebeeb03 100644 --- a/packages/evolution-devnet/test/TxBuilder.Stake.test.ts +++ b/packages/evolution-devnet/test/TxBuilder.Stake.test.ts @@ -35,7 +35,7 @@ describe("TxBuilder Stake Operations", () => { // Create client for a specific account index (each test uses different account) const createTestClient = (accountIndex: number = 0) => createClient({ - network: 0, + chain: Cluster.getChain(devnetCluster!), provider: { type: "kupmios", kupoUrl: "http://localhost:1446", @@ -53,7 +53,7 @@ describe("TxBuilder Stake Operations", () => { // Create clients for each account we'll use in tests const accounts = [0, 1, 2, 3, 4, 5, 6, 7, 8].map((accountIndex) => createClient({ - network: 0, + chain: Cluster.BOOTSTRAP_CHAIN, wallet: { type: "seed", mnemonic: TEST_MNEMONIC, accountIndex, addressType: "Base" } }) ) diff --git a/packages/evolution-devnet/test/TxBuilder.Validity.test.ts b/packages/evolution-devnet/test/TxBuilder.Validity.test.ts index b4bec974..b682be63 100644 --- a/packages/evolution-devnet/test/TxBuilder.Validity.test.ts +++ b/packages/evolution-devnet/test/TxBuilder.Validity.test.ts @@ -33,10 +33,8 @@ describe("TxBuilder Validity Interval", () => { // Creates a client with correct slot config for devnet const createTestClient = (accountIndex: number = 0) => { if (!devnetCluster) throw new Error("Cluster not initialized") - const slotConfig = Cluster.getSlotConfig(devnetCluster) return createClient({ - network: 0, - slotConfig, + chain: Cluster.getChain(devnetCluster), provider: { type: "kupmios", kupoUrl: "http://localhost:1448", @@ -54,7 +52,7 @@ describe("TxBuilder Validity Interval", () => { beforeAll(async () => { // Create a minimal client just to get the address (before cluster is ready) const tempClient = createClient({ - network: 0, + chain: Cluster.BOOTSTRAP_CHAIN, wallet: { type: "seed", mnemonic: TEST_MNEMONIC, accountIndex: 0, addressType: "Base" } }) diff --git a/packages/evolution-devnet/test/TxBuilder.Vote.test.ts b/packages/evolution-devnet/test/TxBuilder.Vote.test.ts index 2fdef359..7e642fb5 100644 --- a/packages/evolution-devnet/test/TxBuilder.Vote.test.ts +++ b/packages/evolution-devnet/test/TxBuilder.Vote.test.ts @@ -33,7 +33,7 @@ describe("TxBuilder Vote Operations (script-free)", () => { const createTestClient = (accountIndex: number = 0) => createClient({ - network: 0, + chain: Cluster.getChain(devnetCluster!), provider: { type: "kupmios", kupoUrl: "http://localhost:1453", @@ -51,7 +51,7 @@ describe("TxBuilder Vote Operations (script-free)", () => { // Create clients for multiple test accounts const accounts = [0, 1, 2, 3].map((accountIndex) => createClient({ - network: 0, + chain: Cluster.BOOTSTRAP_CHAIN, wallet: { type: "seed", mnemonic: TEST_MNEMONIC, accountIndex, addressType: "Base" } }) ) diff --git a/packages/evolution-devnet/test/TxBuilder.VoteValidators.test.ts b/packages/evolution-devnet/test/TxBuilder.VoteValidators.test.ts index b592b39e..3d60792c 100644 --- a/packages/evolution-devnet/test/TxBuilder.VoteValidators.test.ts +++ b/packages/evolution-devnet/test/TxBuilder.VoteValidators.test.ts @@ -49,13 +49,11 @@ const makeAnchor = (url: string) => describe("TxBuilder Vote Validator (script DRep)", () => { let devnetCluster: Cluster.Cluster | undefined - let slotConfig: Cluster.SlotConfig | undefined const createTestClient = (accountIndex: number = 0) => { - if (!slotConfig) throw new Error("slotConfig not initialized") + if (!devnetCluster) throw new Error("Cluster not initialized") return createClient({ - network: 0, - slotConfig, + chain: Cluster.getChain(devnetCluster), provider: { type: "kupmios", kupoUrl: "http://localhost:1453", @@ -74,7 +72,7 @@ describe("TxBuilder Vote Validator (script DRep)", () => { beforeAll(async () => { const accounts = [0, 1].map((accountIndex) => createClient({ - network: 0, + chain: Cluster.BOOTSTRAP_CHAIN, wallet: { type: "seed", mnemonic: TEST_MNEMONIC, accountIndex, addressType: "Base" } }) ) @@ -103,8 +101,6 @@ describe("TxBuilder Vote Validator (script DRep)", () => { ogmios: { enabled: true, port: 1343, logLevel: "info" } }) - slotConfig = Cluster.getSlotConfig(devnetCluster) - await Cluster.start(devnetCluster) await new Promise((r) => setTimeout(r, 3_000)) }, 180_000) diff --git a/packages/evolution/src/index.ts b/packages/evolution/src/index.ts index ba5fd6ac..00e19d63 100644 --- a/packages/evolution/src/index.ts +++ b/packages/evolution/src/index.ts @@ -98,6 +98,7 @@ export * as Script from "./Script.js" export * as ScriptDataHash from "./ScriptDataHash.js" export * as ScriptHash from "./ScriptHash.js" export * as ScriptRef from "./ScriptRef.js" +export * from "./sdk/client/Chain.js" export * from "./sdk/client/Client.js" export { createClient } from "./sdk/client/ClientImpl.js" export * as SingleHostAddr from "./SingleHostAddr.js" diff --git a/packages/evolution/src/sdk/client/Chain.ts b/packages/evolution/src/sdk/client/Chain.ts new file mode 100644 index 00000000..c2e368df --- /dev/null +++ b/packages/evolution/src/sdk/client/Chain.ts @@ -0,0 +1,137 @@ +/** + * Cardano chain descriptors for client configuration. + * + * A `Chain` is a complete, self-describing network descriptor. It carries all + * the information needed to configure addresses, slot arithmetic, and block + * explorer URLs for a given Cardano network. + * + * Use the built-in constants for known networks, or `defineChain` for custom + * devnets and private networks. + * + * @example + * import { preprod, mainnet, preview, defineChain } from "@evolution-sdk/evolution" + * + * @since 2.1.0 + * @category model + */ +export interface Chain { + /** Human-readable network name */ + readonly name: string + /** + * CBOR network encoding. + * `1` = mainnet, `0` = all testnets. + */ + readonly id: 0 | 1 + /** + * Protocol magic number — uniquely identifies the network instance. + * Mainnet: 764824073 | Preprod: 1 | Preview: 2 | Custom: any + */ + readonly networkMagic: number + /** Slot configuration for time ↔ slot conversion */ + readonly slotConfig: { + /** Unix timestamp (milliseconds) of the Shelley era start */ + readonly zeroTime: bigint + /** First slot number of the Shelley era */ + readonly zeroSlot: bigint + /** Duration of each slot in milliseconds (typically 1000) */ + readonly slotLength: number + } + /** Number of slots per epoch */ + readonly epochLength: number + /** Block explorer base URLs (optional — not available for custom chains) */ + readonly blockExplorers?: { + readonly cardanoscan?: string + readonly cexplorer?: string + } +} + +/** + * Define a custom Cardano chain for devnets, private networks, or any network + * not built into the SDK. + * + * @example + * import { defineChain, createClient } from "@evolution-sdk/evolution" + * + * const devnet = defineChain({ + * name: "Local Devnet", + * id: 0, + * networkMagic: 42, + * slotConfig: { zeroTime: 1743379200000n, zeroSlot: 0n, slotLength: 1000 }, + * epochLength: 500, + * }) + * + * const client = createClient({ + * chain: devnet, + * provider: { type: "kupmios", kupoUrl: "http://localhost:1442", ogmiosUrl: "ws://localhost:1337" } + * }) + * + * @since 2.1.0 + * @category constructors + */ +export const defineChain = (chain: Chain): Chain => chain + +/** + * Cardano Mainnet. + * + * @since 2.1.0 + * @category chains + */ +export const mainnet: Chain = { + name: "Cardano Mainnet", + id: 1, + networkMagic: 764824073, + slotConfig: { + zeroTime: 1596059091000n, + zeroSlot: 4492800n, + slotLength: 1000 + }, + epochLength: 432000, + blockExplorers: { + cardanoscan: "https://cardanoscan.io", + cexplorer: "https://cexplorer.io" + } +} + +/** + * Cardano Pre-Production Testnet (Preprod). + * + * @since 2.1.0 + * @category chains + */ +export const preprod: Chain = { + name: "Cardano Preprod", + id: 0, + networkMagic: 1, + slotConfig: { + zeroTime: 1655769600000n, + zeroSlot: 86400n, + slotLength: 1000 + }, + epochLength: 432000, + blockExplorers: { + cardanoscan: "https://preprod.cardanoscan.io", + cexplorer: "https://preprod.cexplorer.io" + } +} + +/** + * Cardano Preview Testnet. + * + * @since 2.1.0 + * @category chains + */ +export const preview: Chain = { + name: "Cardano Preview", + id: 0, + networkMagic: 2, + slotConfig: { + zeroTime: 1666656000000n, + zeroSlot: 0n, + slotLength: 1000 + }, + epochLength: 86400, + blockExplorers: { + cardanoscan: "https://preview.cardanoscan.io", + cexplorer: "https://preview.cexplorer.io" + } +} diff --git a/packages/evolution/src/sdk/client/Client.ts b/packages/evolution/src/sdk/client/Client.ts index 48f9fbe1..439f647e 100644 --- a/packages/evolution/src/sdk/client/Client.ts +++ b/packages/evolution/src/sdk/client/Client.ts @@ -11,6 +11,7 @@ import type { WalletApi, WalletError } from "../wallet/WalletNew.js" +import type { Chain } from "./Chain.js" /** * Error class for provider-related operations. @@ -24,13 +25,13 @@ export class ProviderError extends Data.TaggedError("ProviderError")<{ }> {} /** - * MinimalClient Effect - holds network context. + * MinimalClient Effect - holds chain context. * * @since 2.0.0 * @category model */ export interface MinimalClientEffect { - readonly networkId: Effect.Effect + readonly chain: Chain } /** @@ -62,7 +63,7 @@ export interface SigningClientEffect extends Provider.ProviderEffect, SigningWal * @category model */ export interface MinimalClient { - readonly networkId: number | string + readonly chain: Chain readonly attachProvider: (config: ProviderConfig) => ProviderOnlyClient readonly attachWallet: ( config: T @@ -149,7 +150,7 @@ export type ApiWalletClient = EffectToPromiseAPI & { * @category model */ export type SigningWalletClient = EffectToPromiseAPI & { - readonly networkId: number | string + readonly chain: Chain readonly attachProvider: (config: ProviderConfig) => SigningClient readonly Effect: SigningWalletEffect } @@ -162,19 +163,11 @@ export type SigningWalletClient = EffectToPromiseAPI & { * @category model */ export type ReadOnlyWalletClient = EffectToPromiseAPI & { - readonly networkId: number | string + readonly chain: Chain readonly attachProvider: (config: ProviderConfig) => ReadOnlyClient readonly Effect: ReadOnlyWalletEffect } -/** - * Network identifier for client configuration. - * - * @since 2.0.0 - * @category model - */ -export type NetworkId = "mainnet" | "preprod" | "preview" | number - /** * Retry policy configuration with exponential backoff. * diff --git a/packages/evolution/src/sdk/client/ClientImpl.ts b/packages/evolution/src/sdk/client/ClientImpl.ts index c446ebb7..f0f21768 100644 --- a/packages/evolution/src/sdk/client/ClientImpl.ts +++ b/packages/evolution/src/sdk/client/ClientImpl.ts @@ -4,11 +4,9 @@ import * as CoreAddress from "../../Address.js" import * as Bytes from "../../Bytes.js" import * as KeyHash from "../../KeyHash.js" import type * as NativeScripts from "../../NativeScripts.js" -import type * as Network from "../../Network.js" import * as PrivateKey from "../../PrivateKey.js" import * as CoreRewardAccount from "../../RewardAccount.js" import * as CoreRewardAddress from "../../RewardAddress.js" -import type * as Time from "../../Time/index.js" import * as Transaction from "../../Transaction.js" import * as TransactionHash from "../../TransactionHash.js" import * as TransactionWitnessSet from "../../TransactionWitnessSet.js" @@ -28,12 +26,12 @@ import * as Maestro from "../provider/Maestro.js" import * as Provider from "../provider/Provider.js" import * as Derivation from "../wallet/Derivation.js" import * as WalletNew from "../wallet/WalletNew.js" +import type { Chain } from "./Chain.js" import { type ApiWalletClient, type ApiWalletConfig, type MinimalClient, type MinimalClientEffect, - type NetworkId, type PrivateKeyWalletConfig, type ProviderConfig, type ProviderOnlyClient, @@ -65,72 +63,6 @@ const createProvider = (config: ProviderConfig): Provider.Provider => { } } -/** - * Map NetworkId to numeric representation. - * "mainnet" → 1, "preprod"/"preview" → 0, numeric values pass through unchanged. - * - * @since 2.0.0 - * @category transformation - */ -const normalizeNetworkId = (network: NetworkId): number => { - if (typeof network === "number") return network - switch (network) { - case "mainnet": - return 1 - case "preprod": - return 0 - case "preview": - return 0 - default: - return 0 - } -} - -/** - * Map NetworkId to wallet network enumeration. - * Returns "Mainnet" for numeric 1 or string "mainnet"; returns "Testnet" otherwise. - * - * @since 2.0.0 - * @category transformation - */ -const toWalletNetwork = (networkId: NetworkId): WalletNew.Network => { - if (typeof networkId === "number") { - return networkId === 1 ? "Mainnet" : "Testnet" - } - switch (networkId) { - case "mainnet": - return "Mainnet" - case "preprod": - case "preview": - return "Testnet" - default: - return "Testnet" - } -} - -/** - * Map NetworkId to Network type for slot configuration resolution. - * Returns the correct Network variant so resolveSlotConfig picks the right preset. - * - * @since 2.0.0 - * @category transformation - */ -const toBuilderNetwork = (networkId: NetworkId): Network.Network => { - if (typeof networkId === "number") { - return networkId === 1 ? "Mainnet" : "Preview" - } - switch (networkId) { - case "mainnet": - return "Mainnet" - case "preprod": - return "Preprod" - case "preview": - return "Preview" - default: - return "Mainnet" - } -} - /** * Construct read-only wallet from network, payment address, and optional reward address. * @@ -163,22 +95,17 @@ const createReadOnlyWallet = ( * @since 2.0.0 * @category constructors */ -const createReadOnlyWalletClient = (network: NetworkId, config: ReadOnlyWalletConfig): ReadOnlyWalletClient => { - const walletNetwork = toWalletNetwork(network) +const createReadOnlyWalletClient = (chain: Chain, config: ReadOnlyWalletConfig): ReadOnlyWalletClient => { + const walletNetwork = chain.id === 1 ? "Mainnet" : "Testnet" const wallet = createReadOnlyWallet(walletNetwork, config.address, config.rewardAddress) - const networkId = normalizeNetworkId(network) return { - // Direct Promise properties from wallet address: wallet.address, rewardAddress: wallet.rewardAddress, - // Metadata - networkId, - // Combinator methods + chain, attachProvider: (providerConfig) => { - return createReadOnlyClient(network, providerConfig, config) + return createReadOnlyClient(chain, providerConfig, config) }, - // Effect namespace - wallet's Effect interface Effect: wallet.Effect } } @@ -190,13 +117,12 @@ const createReadOnlyWalletClient = (network: NetworkId, config: ReadOnlyWalletCo * @category constructors */ const createReadOnlyClient = ( - network: NetworkId, + chain: Chain, providerConfig: ProviderConfig, - walletConfig: ReadOnlyWalletConfig, - slotConfig?: Time.SlotConfig + walletConfig: ReadOnlyWalletConfig ): ReadOnlyClient => { const provider = createProvider(providerConfig) - const walletNetwork = toWalletNetwork(network) + const walletNetwork = chain.id === 1 ? "Mainnet" : "Testnet" const wallet = createReadOnlyWallet(walletNetwork, walletConfig.address, walletConfig.rewardAddress) // Parse the bech32 address to Core Address for provider calls const coreAddress = CoreAddress.fromBech32(walletConfig.address) @@ -216,8 +142,7 @@ const createReadOnlyClient = ( return makeTxBuilder({ wallet, provider, - network: toBuilderNetwork(network), - slotConfig + slotConfig: chain.slotConfig }) }, Effect: { @@ -650,19 +575,18 @@ const createApiWallet = (_network: WalletNew.Network, config: ApiWalletConfig): * @category constructors */ const createSigningWalletClient = ( - network: NetworkId, + chain: Chain, config: SeedWalletConfig | PrivateKeyWalletConfig ): SigningWalletClient => { - const walletNetwork = toWalletNetwork(network) + const walletNetwork = chain.id === 1 ? "Mainnet" : "Testnet" const wallet = config.type === "seed" ? createSigningWallet(walletNetwork, config) : createPrivateKeyWallet(walletNetwork, config) - const networkId = normalizeNetworkId(network) return { ...wallet, - networkId, + chain, attachProvider: (providerConfig) => { - return createSigningClient(network, providerConfig, config) + return createSigningClient(chain, providerConfig, config) } } } @@ -673,14 +597,14 @@ const createSigningWalletClient = ( * @since 2.0.0 * @category constructors */ -const createApiWalletClient = (network: NetworkId, config: ApiWalletConfig): ApiWalletClient => { - const walletNetwork = toWalletNetwork(network) +const createApiWalletClient = (chain: Chain, config: ApiWalletConfig): ApiWalletClient => { + const walletNetwork = chain.id === 1 ? "Mainnet" : "Testnet" const wallet = createApiWallet(walletNetwork, config) return { ...wallet, attachProvider: (providerConfig) => { - return createSigningClient(network, providerConfig, config) + return createSigningClient(chain, providerConfig, config) } } } @@ -692,13 +616,12 @@ const createApiWalletClient = (network: NetworkId, config: ApiWalletConfig): Api * @category constructors */ const createSigningClient = ( - network: NetworkId, + chain: Chain, providerConfig: ProviderConfig, - walletConfig: SeedWalletConfig | PrivateKeyWalletConfig | ApiWalletConfig, - slotConfig?: Time.SlotConfig + walletConfig: SeedWalletConfig | PrivateKeyWalletConfig | ApiWalletConfig ): SigningClient => { const provider = createProvider(providerConfig) - const walletNetwork = toWalletNetwork(network) + const walletNetwork = chain.id === 1 ? "Mainnet" : "Testnet" const wallet = walletConfig.type === "seed" @@ -779,10 +702,9 @@ const createSigningClient = ( // The wallet is passed to the builder config, which handles address and UTxO resolution automatically // Protocol parameters are auto-fetched from provider during build() return makeTxBuilder({ - provider, // Pass provider for submission - wallet, // Pass wallet for signing - network: toBuilderNetwork(network), - slotConfig // Pass slot config for time conversion + provider, + wallet, + slotConfig: chain.slotConfig }) }, // Effect namespace @@ -796,7 +718,7 @@ const createSigningClient = ( * @since 2.0.0 * @category constructors */ -const createProviderOnlyClient = (network: NetworkId, config: ProviderConfig): ProviderOnlyClient => { +const createProviderOnlyClient = (chain: Chain, config: ProviderConfig): ProviderOnlyClient => { const provider = createProvider(config) return { @@ -804,11 +726,11 @@ const createProviderOnlyClient = (network: NetworkId, config: ProviderConfig): P attachWallet(walletConfig: T) { switch (walletConfig.type) { case "read-only": - return createReadOnlyClient(network, config, walletConfig) as any + return createReadOnlyClient(chain, config, walletConfig) as any case "seed": - return createSigningClient(network, config, walletConfig) as any + return createSigningClient(chain, config, walletConfig) as any case "api": - return createSigningClient(network, config, walletConfig) as any + return createSigningClient(chain, config, walletConfig) as any } } } @@ -820,28 +742,26 @@ const createProviderOnlyClient = (network: NetworkId, config: ProviderConfig): P * @since 2.0.0 * @category constructors */ -const createMinimalClient = (network: NetworkId = "mainnet"): MinimalClient => { - const networkId = normalizeNetworkId(network) - +const createMinimalClient = (chain: Chain): MinimalClient => { const effectInterface: MinimalClientEffect = { - networkId: Effect.succeed(networkId) + chain } return { - networkId, + chain, attachProvider: (config) => { - return createProviderOnlyClient(network, config) + return createProviderOnlyClient(chain, config) }, attachWallet(walletConfig: T) { // TypeScript cannot narrow conditional return types from runtime discriminants. // The conditional type interface provides type safety at call sites. switch (walletConfig.type) { case "read-only": - return createReadOnlyWalletClient(network, walletConfig) as any + return createReadOnlyWalletClient(chain, walletConfig) as any case "seed": - return createSigningWalletClient(network, walletConfig) as any + return createSigningWalletClient(chain, walletConfig) as any case "api": - return createApiWalletClient(network, walletConfig) as any + return createApiWalletClient(chain, walletConfig) as any } }, attach(providerConfig: ProviderConfig, walletConfig: TW) { @@ -849,11 +769,11 @@ const createMinimalClient = (network: NetworkId = "mainnet"): MinimalClient => { // The conditional type interface provides type safety at call sites. switch (walletConfig.type) { case "read-only": - return createReadOnlyClient(network, providerConfig, walletConfig) as any + return createReadOnlyClient(chain, providerConfig, walletConfig) as any case "seed": - return createSigningClient(network, providerConfig, walletConfig) as any + return createSigningClient(chain, providerConfig, walletConfig) as any case "api": - return createSigningClient(network, providerConfig, walletConfig) as any + return createSigningClient(chain, providerConfig, walletConfig) as any } }, // Effect namespace @@ -875,60 +795,55 @@ const createMinimalClient = (network: NetworkId = "mainnet"): MinimalClient => { // Most specific overloads first - wallet type determines client capability // Provider + ReadOnly Wallet → ReadOnlyClient export function createClient(config: { - network?: NetworkId + chain: Chain provider: ProviderConfig wallet: ReadOnlyWalletConfig - slotConfig?: Time.SlotConfig }): ReadOnlyClient // Provider + Seed Wallet → SigningClient export function createClient(config: { - network?: NetworkId + chain: Chain provider: ProviderConfig wallet: SeedWalletConfig - slotConfig?: Time.SlotConfig }): SigningClient // Provider + PrivateKey Wallet → SigningClient export function createClient(config: { - network?: NetworkId + chain: Chain provider: ProviderConfig wallet: PrivateKeyWalletConfig - slotConfig?: Time.SlotConfig }): SigningClient // Provider + API Wallet → SigningClient export function createClient(config: { - network?: NetworkId + chain: Chain provider: ProviderConfig wallet: ApiWalletConfig - slotConfig?: Time.SlotConfig }): SigningClient // Provider only → ProviderOnlyClient -export function createClient(config: { network?: NetworkId; provider: ProviderConfig }): ProviderOnlyClient +export function createClient(config: { chain: Chain; provider: ProviderConfig }): ProviderOnlyClient // ReadOnly Wallet only → ReadOnlyWalletClient -export function createClient(config: { network?: NetworkId; wallet: ReadOnlyWalletConfig }): ReadOnlyWalletClient +export function createClient(config: { chain: Chain; wallet: ReadOnlyWalletConfig }): ReadOnlyWalletClient // Seed Wallet only → SigningWalletClient -export function createClient(config: { network?: NetworkId; wallet: SeedWalletConfig }): SigningWalletClient +export function createClient(config: { chain: Chain; wallet: SeedWalletConfig }): SigningWalletClient // Private Key Wallet only → SigningWalletClient -export function createClient(config: { network?: NetworkId; wallet: PrivateKeyWalletConfig }): SigningWalletClient +export function createClient(config: { chain: Chain; wallet: PrivateKeyWalletConfig }): SigningWalletClient // API Wallet only → ApiWalletClient -export function createClient(config: { network?: NetworkId; wallet: ApiWalletConfig }): ApiWalletClient +export function createClient(config: { chain: Chain; wallet: ApiWalletConfig }): ApiWalletClient -// Network only or minimal → MinimalClient -export function createClient(config?: { network?: NetworkId }): MinimalClient +// Chain only → MinimalClient +export function createClient(config: { chain: Chain }): MinimalClient // Implementation signature - handles all cases (all synchronous now) -export function createClient(config?: { - network?: NetworkId +export function createClient(config: { + chain: Chain provider?: ProviderConfig wallet?: WalletConfig - slotConfig?: Time.SlotConfig }): | MinimalClient | ReadOnlyClient @@ -937,38 +852,37 @@ export function createClient(config?: { | ReadOnlyWalletClient | SigningWalletClient | ApiWalletClient { - const network = config?.network ?? "mainnet" - const slotConfig = config?.slotConfig + const chain = config.chain - if (config?.provider && config?.wallet) { + if (config.provider && config.wallet) { switch (config.wallet.type) { case "read-only": - return createReadOnlyClient(network, config.provider, config.wallet, slotConfig) + return createReadOnlyClient(chain, config.provider, config.wallet) case "seed": - return createSigningClient(network, config.provider, config.wallet, slotConfig) + return createSigningClient(chain, config.provider, config.wallet) case "private-key": - return createSigningClient(network, config.provider, config.wallet, slotConfig) + return createSigningClient(chain, config.provider, config.wallet) case "api": - return createSigningClient(network, config.provider, config.wallet, slotConfig) + return createSigningClient(chain, config.provider, config.wallet) } } - if (config?.wallet) { + if (config.wallet) { switch (config.wallet.type) { case "read-only": - return createReadOnlyWalletClient(network, config.wallet) + return createReadOnlyWalletClient(chain, config.wallet) case "seed": - return createSigningWalletClient(network, config.wallet) + return createSigningWalletClient(chain, config.wallet) case "private-key": - return createSigningWalletClient(network, config.wallet) + return createSigningWalletClient(chain, config.wallet) case "api": - return createApiWalletClient(network, config.wallet) + return createApiWalletClient(chain, config.wallet) } } - if (config?.provider) { - return createProviderOnlyClient(network, config.provider) + if (config.provider) { + return createProviderOnlyClient(chain, config.provider) } - return createMinimalClient(network) + return createMinimalClient(chain) }