Skip to main content

Deploy CLI

CLI Overview

The lambit CLI compiles contracts, generates projects, and runs tests; it does not have a built-in deploy subcommand. Deployment is performed programmatically by running a short deployment script through the Lambit runtime.

The available CLI commands are:

lambit compile <module> [--export <name>]... [--out-dir <dir> | -d <dir>] [--pretty | --compact]
lambit artifact <module> [--export <name>] [--output <file>] [--pretty | --compact]
lambit scaffold <target-directory> [--lambit <specifier>] [--public]
lambit test [--testnet | --config <path> | --no-config] [mocha args...]

Compile the Artifact (optional)

If you want a standalone artifact JSON — for inspection, publishing, or artifact-first deployment — compile it with the CLI:

npx lambit artifact ./contracts/demo.ts --export Demo --output artifacts/Demo.json

or, to compile every exported contract from a module into a directory:

npx lambit compile ./contracts/demo.ts --out-dir artifacts

You can also compile programmatically with buildArtifact(Demo) or bind props directly (Demo(props)) — the artifact is produced automatically when you bind.

The Deploy Script

Deployment is a script that (1) binds the contract props, (2) creates the WIF-backed testnet provider, and (3) calls bound.deploy(state?, { provider, satoshis }).

Create a deploy.ts at the root of the project:

import { createHash } from "node:crypto";
import * as dotenv from "dotenv";
import { Demo } from "./src/contracts/demo";
import { createTestnetProvider, createWifSigner } from "@opcat-labs/lambit";

// Load the .env file (which should contain TESTNET_WIF)
dotenv.config();

async function main() {
const TESTNET_WIF = process.env.TESTNET_WIF;
if (!TESTNET_WIF) {
throw new Error("Set TESTNET_WIF in your .env file before deploying.");
}

// Compute the prop value baked into the locking script:
// sha256("hello world") as hex.
const hash = createHash("sha256")
.update(Buffer.from("hello world", "utf8"))
.digest("hex");

// Bind props — this produces the deployable locking script.
const demo = Demo({ hash });

// The provider funds the deployment from the WIF wallet and broadcasts.
const provider = createTestnetProvider({
wif: TESTNET_WIF,
network: "testnet",
});

// Signer is used when calling methods on the deployed contract later.
const signer = createWifSigner(TESTNET_WIF, "testnet");

const deployed = await demo.deploy({ provider, satoshis: 1_000n });

console.log(`Demo contract deployed: ${deployed.utxo.txid}`);
}

void main();

For a stateful contract, pass the initial state as the first argument:

const counter = Counter({});
const deployed = await counter.deploy(
{ count: 0n },
{ provider, satoshis: 1_000n },
);

Running the script

npx deploy.ts

or, if your project defines a script in package.json:

{
"scripts": {
"deploy": "deploy.ts"
}
}
npm run deploy

Deferred deployment

If you want to validate and initialize the deployment inputs without broadcasting yet, use bound.prepareDeploy(state?, { provider, satoshis }). It returns a deferred handle that broadcasts only when its deploy() method is called:

const prepared = await demo.prepareDeploy({ provider, satoshis: 1_000n });
// ... inspect `prepared.instance` ...
const deployed = await prepared.deploy();

Expected Output

Upon a successful execution you should see an output like the following:

Demo contract deployed: 4080c16237b8d8e25af54a1d8b151fb5aa804410d70c0d1ba1fa6f7bb8d1ab25

You can inspect the deployed smart contract in the blockchain explorer. In our example, the first output contains the compiled smart contract code.

Artifact-First Deployment

If you already compiled an artifact JSON (for example with lambit artifact above), create the instance with createInstance({ artifact, constructorArgs, state }) and deploy through the provider:

import { readFileSync } from "node:fs";
import {
attachDeployedMethods,
createInstance,
createTestnetProvider,
} from "@opcat-labs/lambit";

const artifact = JSON.parse(readFileSync("./artifacts/Demo.json", "utf8"));
const instance = createInstance({
artifact,
constructorArgs: {
hash: "b94d27b9934d3e08a52e52d7da7dabfac484efe04294e576f9d9e5d5a5a6e8d0",
},
});

const provider = createTestnetProvider({
wif: process.env.TESTNET_WIF!,
network: "testnet",
});
const deployed = attachDeployedMethods(await provider.deploy(instance, 1_000n));

console.log(`Demo contract deployed: ${deployed.utxo.txid}`);