Alkahest developer
Skill aiskillstore/marketplace/skills/internet-court/internet-court/vendored/arkhai/alkahest-developer
Help developers write code that interacts with Alkahest escrow contracts using the TypeScript, Rust, or Python SDKFrom its SKILL.md
npx -y skills add aiskillstore/marketplace --skill alkahest-developerAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
One thing to look at
- no licenseNo license file was found in the repository. Code published without one is not open source by default, so using it at work is a question for whoever answers licensing questions where you are.
SKILL.md
8.8 KB, ~2.4k tokens by cl100k_base, as published. Nobody here has run it
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.default.doObligation(
client.erc20.escrow.default.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().default().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.default.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.default.collectObligation(
escrowUid,
fulfillmentUid,
);
Rust:
let receipt = client.erc20().escrow().default().collect_payment(
escrow_uid, fulfillment_uid,
).await?;
Python:
tx_hash = await client.erc20.escrow.default.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, bondAmount, commitDeadline);
// 3. Wait 1+ blocks, then reveal. The matching bond is reclaimed on reveal.
await client.commitReveal.doObligation(
{ payload, salt, schema }, escrowUid,
);
Rust:
let commitment = client.commit_reveal().compute_commitment(
escrow_uid, claimer, &obligation_data,
).await?;
client.commit_reveal().commit(commitment, bond_amount, commit_deadline).await?;
// wait 1+ blocks; the matching bond is reclaimed on reveal
let receipt = client.commit_reveal().do_obligation(&obligation_data, Some(escrow_uid)).await?;
Python:
commitment = await client.commit_reveal.compute_commitment(
escrow_uid, claimer, payload, salt, schema,
)
await client.commit_reveal.commit(commitment, bond_amount, commit_deadline)
# wait 1+ blocks; the matching bond is reclaimed on reveal
uid = await client.commit_reveal.do_obligation(payload, salt, schema, ref_uid=escrow_uid)
Atomic Payment Utilities
Atomic payment utilities provide single-transaction payment and collection for existing escrows:
TypeScript:
await client.erc20.payment.payErc20AndCollect(escrowUid);
Rust:
client.erc20().payment().pay_erc20_and_collect(escrow_uid).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/website/Escrow Flow/Token Trading.mdx— token trading walkthroughdocs/website/Escrow Flow/Job Trading.mdx— oracle arbitration walkthroughdocs/drafts/Escrow Flow (pt 2b - Frontrunning Protection).md— commit-reveal frontrunning protectiondocs/website/Escrow Flow/Composing Demands.mdx— composing demands with logical arbitersdocs/website/Writing Arbiters/— custom arbiter developmentdocs/website/Writing Escrow Contracts.mdanddocs/website/Writing Fulfillment Contracts.md— custom escrow/obligation developmentdocs/mcp-server/— MCP server for looking up contract details
What ships with it: 4 files
44.1 KB alongside SKILL.md
references/
- contracts.md16.7 KB
- python-api.md9.7 KB
- rust-api.md8.4 KB
- typescript-api.md9.4 KB