/install alkahest-developer
Alkahest Developer Skill
When to Use
Use this skill when a developer wants to write code that interacts with Alkahest escrow contracts. This covers:
- Integrating Alkahest into an application
- Writing bots/agents that create escrows, fulfill obligations, or arbitrate
- Building custom arbiters or obligation contracts
- Understanding SDK patterns and APIs
SDK Overview
| SDK | Language | Package | Foundation |
|---|---|---|---|
| TypeScript | TypeScript/JavaScript | @alkahest/ts-sdk |
viem |
| Rust | Rust | alkahest-rs |
alloy |
| Python | Python | alkahest-py |
PyO3 wrapper around Rust SDK |
Client Setup
TypeScript
import { createWalletClient, http } from "viem";
import { privateKeyToAccount } from "viem/accounts";
import { baseSepolia } from "viem/chains";
import { makeClient } from "@alkahest/ts-sdk";
const walletClient = createWalletClient({
account: privateKeyToAccount("0xPRIVATE_KEY"),
chain: baseSepolia,
transport: http("https://rpc-url"),
});
// Full client with all extensions
const client = makeClient(walletClient);
// Custom addresses (optional)
const client = makeClient(walletClient, customAddresses);
// Minimal client for custom extension patterns
const minimal = makeMinimalClient(walletClient);
const extended = minimal.extend((base) => ({
custom: makeErc20Client(base.viemClient, pickErc20Addresses(base.contractAddresses)),
}));
Rust
use alkahest_rs::AlkahestClient;
// Full client with all extensions (Base Sepolia default)
let client = AlkahestClient::with_base_extensions(
"0xPRIVATE_KEY",
"https://rpc-url",
None, // uses Base Sepolia addresses
).await?;
// Custom addresses
use alkahest_rs::{DefaultExtensionConfig, ETHEREUM_SEPOLIA_ADDRESSES};
let client = AlkahestClient::with_base_extensions(
"0xPRIVATE_KEY",
"https://rpc-url",
Some(ETHEREUM_SEPOLIA_ADDRESSES),
).await?;
// Bare client + custom extensions
let bare = AlkahestClient::new("0xPRIVATE_KEY", "https://rpc-url").await?;
let extended = bare.extend::\x3CErc20Module>(Some(erc20_config)).await?;
Python
from alkahest_py import PyAlkahestClient
# Full client with all extensions (Base Sepolia default)
client = PyAlkahestClient("0xPRIVATE_KEY", "https://rpc-url")
# Custom addresses
from alkahest_py import DefaultExtensionConfig, PyErc20Addresses, ...
config = DefaultExtensionConfig(erc20_addresses=..., ...)
client = PyAlkahestClient("0xPRIVATE_KEY", "https://rpc-url", config)
Core Patterns
Creating an Escrow
TypeScript:
// 1. Approve token
await client.erc20.util.approve({ address: TOKEN, value: amount }, "escrow");
// 2. Create escrow
const { hash, attested } = await client.erc20.escrow.nonTierable.doObligation(
client.erc20.escrow.nonTierable.encodeObligationRaw({
token: TOKEN, amount, arbiter: ARBITER, demand: DEMAND_BYTES,
}),
);
const escrowUid = attested.uid;
Rust:
// 1. Approve
client.erc20().approve(&Erc20Data { address: token, value: amount }, ApprovalPurpose::Escrow).await?;
// 2. Create escrow
let receipt = client.erc20().escrow().non_tierable().make_statement(
token, amount, arbiter, demand_bytes, expiration,
).await?;
let attested = client.get_attested_event(receipt)?;
Python:
# 1. Approve
await client.erc20.util.approve(token_address, amount, "escrow")
# 2. Create escrow
uid = await client.erc20.escrow.non_tierable.create(
token=token_address, amount=amount,
arbiter=arbiter_address, demand=demand_bytes,
expiration=expiration,
)
Fulfilling with StringObligation
TypeScript:
const { attested } = await client.stringObligation.doObligation(
"fulfillment content",
undefined, // schema
escrowUid, // refUID
);
Rust:
let receipt = client.string_obligation().do_obligation(
"fulfillment content", None, Some(escrow_uid),
).await?;
Python:
uid = await client.string_obligation.do_obligation(
"fulfillment content",
ref_uid=escrow_uid,
)
Collecting Escrow
TypeScript:
const { hash } = await client.erc20.escrow.nonTierable.collectObligation(
escrowUid,
fulfillmentUid,
);
Rust:
let receipt = client.erc20().escrow().non_tierable().collect_payment(
escrow_uid, fulfillment_uid,
).await?;
Python:
tx_hash = await client.erc20.escrow.non_tierable.collect(escrow_uid, fulfillment_uid)
Waiting for Fulfillment
TypeScript:
const result = await client.waitForFulfillment(
client.contractAddresses.erc20EscrowObligation,
escrowUid,
);
Rust:
let log = client.wait_for_fulfillment(
client.erc20_address(Erc20Contract::EscrowObligation),
escrow_uid,
None, // from_block
).await?;
Python:
result = await client.wait_for_fulfillment(
escrow_contract_address,
escrow_uid,
)
Encoding Demands
TypeScript:
// Trusted oracle
const demand = client.arbiters.general.trustedOracle.encodeDemand({
oracle: ORACLE, data: "0x",
});
// Logical composition
const demand = client.arbiters.logical.all.encodeDemand({
arbiters: [ARBITER_A, ARBITER_B],
demands: [DEMAND_A, DEMAND_B],
});
// Attestation properties
const demand = client.arbiters.attestationProperties.attester.encodeDemand({
attester: REQUIRED_ATTESTER,
});
Rust:
// Trusted oracle (ABI encoding)
use alloy::sol_types::SolValue;
let demand = TrustedOracleArbiter::DemandData { oracle, data: Bytes::new() }.abi_encode();
// Decode arbiter demand (auto-detects)
let decoded = client.arbiters().decode_arbiter_demand(arbiter_addr, &demand_bytes)?;
Python:
# Trusted oracle
demand = client.arbiters.trusted_oracle.encode_demand(oracle=ORACLE, data=b"")
# Logical composition
demand = client.arbiters.logical.all.encode(
arbiters=[ARBITER_A, ARBITER_B],
demands=[DEMAND_A, DEMAND_B],
)
Commit-Reveal Pattern
TypeScript:
// 1. Compute commitment
const commitment = await client.commitReveal.computeCommitment(
escrowUid, claimerAddress, { payload, salt, schema },
);
// 2. Commit (sends bond as ETH)
await client.commitReveal.commit(commitment);
// 3. Wait 1+ blocks, then reveal
const { attested } = await client.commitReveal.doObligation(
{ payload, salt, schema }, escrowUid,
);
// 4. Reclaim bond
await client.commitReveal.reclaimBond(attested.uid);
Rust:
let commitment = client.commit_reveal().compute_commitment(
escrow_uid, claimer, &obligation_data,
).await?;
client.commit_reveal().commit(commitment).await?;
// wait 1+ blocks
let receipt = client.commit_reveal().do_obligation(&obligation_data, Some(escrow_uid)).await?;
client.commit_reveal().reclaim_bond(obligation_uid).await?;
Python:
commitment = await client.commit_reveal.compute_commitment(
escrow_uid, claimer, payload, salt, schema,
)
await client.commit_reveal.commit(commitment)
# wait 1+ blocks
uid = await client.commit_reveal.do_obligation(payload, salt, schema, ref_uid=escrow_uid)
await client.commit_reveal.reclaim_bond(uid)
Barter Utilities
Barter utils provide atomic single-transaction token swaps:
TypeScript:
await client.erc20.barter.buyErc20ForErc20(
{ address: BID_TOKEN, value: bidAmount },
{ address: ASK_TOKEN, value: askAmount },
BigInt(Math.floor(Date.now() / 1000) + 3600),
);
Rust:
client.erc20().barter().buy_erc20_for_erc20(
&bid_token, &ask_token, expiration,
).await?;
Key Type Differences
| Concept | TypeScript | Rust | Python |
|---|---|---|---|
| Addresses | `0x${string}` |
Address |
str (hex) |
| Big integers | bigint |
U256 |
str (decimal) |
| Bytes | `0x${string}` |
Bytes / FixedBytes\x3C32> |
bytes / str (hex) |
| Receipts | { hash, attested } |
TransactionReceipt |
str (tx hash or uid) |
| Attestations | Attestation object |
IEAS::Attestation |
PyAttestation |
Reference Documentation
references/typescript-api.md— full TS SDK API treereferences/rust-api.md— full Rust SDK API treereferences/python-api.md— full Python SDK API treereferences/contracts.md— contract addresses and data schemasdocs/Escrow Flow (pt 1).md— token trading walkthroughdocs/Escrow Flow (pt 2).md— oracle arbitration walkthroughdocs/Escrow Flow (pt 2b).md— commit-reveal frontrunning protectiondocs/Escrow Flow (pt 3).md— composing demands with logical arbitersdocs/Writing Arbiters/— custom arbiter developmentdocs/Writing Contracts/— custom escrow/obligation developmentdocs/mcp-server/— MCP server for looking up contract details
- Make sure OpenClaw is installed (local or Docker)
- Run the install command in chat:
/install alkahest-developer - After installation, invoke the skill by name or use
/alkahest-developer - Provide required inputs per the skill's parameter spec and get structured output
What is Alkahest Developer?
Help developers write code that interacts with Alkahest escrow contracts using the TypeScript, Rust, or Python SDK. It is an AI Agent Skill for Claude Code / OpenClaw, with 217 downloads so far.
How do I install Alkahest Developer?
Run "/install alkahest-developer" in the OpenClaw or Claude Code chat to install it in one step — no extra setup required.
Is Alkahest Developer free?
Yes, Alkahest Developer is completely free, licensed under MIT-0. You can download, install and use it at no cost.
Which platforms does Alkahest Developer support?
Alkahest Developer is cross-platform and runs anywhere OpenClaw / Claude Code is available (cross-platform).
Who created Alkahest Developer?
It is built and maintained by 疒奀 (@mlegls); the current version is v1.0.0.