Skip to main content

Clarigen

A developer tool that makes it simple and pleasant to build Clarity apps

Clarigen is a code generator that gives you type-safe interfaces for interacting with your Clarity contracts. Whether you're writing unit tests with Clarinet or building web apps with micro-stacks, Clarigen will give you exactly what you need so you're building great apps - not writing boilerplate.
See the difference:
The best way to understand the value that Clarigen provides is to see how it changes the code you'd otherwise write. In these examples, we're comparing code that uses Clarinet and micro-stacks. Importantly, Clarigen does not change the tool you're using under the hood. You can use the same tools as before - just with better types.
First, let's look at code that's typically used when testing contracts in Clarinet:
Vanilla Clarinet
const wallet_1 = accounts.get('wallet_1')!;
let block = chain.mineBlock([
Tx.contractCall("counter", "increment", [types.uint(1)], wallet_1.address),
]);
block.receipts[0].result
.expectOk()
.expectUint(2);
In the above example, there are no Typescript types to help you work with your contracts. Your contract names are just strings, and you have to manually type your function arguments (like types.uint(1)). And when you're working with transaction results, you have to explicitly state the expected return (.expectUint(2)).
Here's what that test looks like after Clarigen has generated all the boilerplate for you:
Clarinet tests - with Clarigen!
const alice = accounts.get('wallet_1').address;
const receipt = chain.txOk(contracts.counter.increment(2), alice);
assertEquals(receipt.value, 2n);

Or a video to show that sweet, sweet intellisense:
Now, you've got:
✅ All your contract types pre-defined
✅ Your `Devnet` accounts are type-safe
✅ Helpers to specify expected responses (txOk)
✅ Type-safe response values, without having to specify them
Let's look at one more example - using micro-stacks to call a contract from a React app:
hooks/use-with-micro-stacks.ts
const { openContractCall, isRequestPending } = useOpenContractCall();

async function handleOpenContractCall() {
const functionArgs = [
uintCV(1234),
standardPrincipalCV('ST1X6M947Z7E58CNE0H8YJVJTVKS9VW0PHEG3NHN3'),
contractPrincipalCV('ST1X6M947Z7E58CNE0H8YJVJTVKS9VW0PHEG3NHN3.vault'),
];
await openContractCall({
contractAddress: 'ST1X6M947Z7E58CNE0H8YJVJTVKS9VW0PHEG3NHN3',
contractName: 'nft-contract',
functionName: 'transfer',
functionArgs,
onFinish: () => {},
});
}

With Clarigen, here's what that code looks like:
hooks/use-with-clarigen.ts
const { openContractCall } = useOpenContractCall();

async function handleOpenContractCall() {
await openContractCall({
...nftContract.transfer({
id: 1234,
sender: 'ST1X6M947Z7E58CNE0H8YJVJTVKS9VW0PHEG3NHN3',
recipient: 'ST1X6M947Z7E58CNE0H8YJVJTVKS9VW0PHEG3NHN3.vault',
}),
onFinish: () => {},
});
}