🧪 Skills
Alkahest Developer
Help developers write code that interacts with Alkahest escrow contracts using the TypeScript, Rust, or Python SDK
v1.0.0
Description
name: alkahest-developer description: Help developers write code that interacts with Alkahest escrow contracts using the TypeScript, Rust, or Python SDK
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::<Erc20Module>(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<32> |
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
Reviews (0)
Sign in to write a review.
No reviews yet. Be the first to review!
Comments (0)
No comments yet. Be the first to share your thoughts!