Getting Started
Overview
Kontor’s SDK is a TypeScript toolkit for building applications that interact with Kontor.
It provides a structured, type-safe way to query contract state, compose contract calls, sign transactions, and broadcast them to the network.
The SDK is designed around a small set of core concepts:
- Clients: objects that know how to talk to the network.
- Accounts: key material or wallet-backed signers used for transaction signing.
- Interfaces: contract definitions described using WIT.
Contract interfaces with WIT
Kontor contracts are described using WIT (WebAssembly Interface Types) definitions. Contract WITs define:
- available contract functions,
- argument and return types,
- user defined records and enums
The SDK uses WIT as the source of truth for interacting with contracts. From a WIT definition, it can:
- expose typed function names and arguments,
- encode function calls correctly,
- decode responses into structured JavaScript values.
This makes it possible to work with contracts in a predictable and type-safe way without manually handling low-level encoding details.
Installation
npm install @kontor/kontor-sdkQuick Start
1. Define a contract
The kontor-sdk knows how to interpret WITs and produce type safe interfaces to view and proc calls.
Below is an example of the native-token contract which is included in the SDK.
import { parseWit } from "@kontor/kontor-sdk";
export const nativeTokenRaw = [
"record balance { acc: string, amt: decimal }",
"record transfer { src: string, dst: string, amt: decimal }",
"record burn { src: string, amt: decimal }",
"record mint { dst: string, amt: decimal }",
"export mint: func(ctx: borrow<proc-context>, amt: decimal) -> result<mint, error>;",
"export burn: func(ctx: borrow<proc-context>, amt: decimal) -> result<burn, error>;",
"export transfer: func(ctx: borrow<proc-context>, dst: string, amt: decimal) -> result<transfer, error>;",
"export balance: func(ctx: borrow<view-context>, acc: string) -> option<decimal>;",
"export balances: func(ctx: borrow<view-context>) -> list<balance>;",
"export total-supply: func(ctx: borrow<view-context>) -> decimal;",
"export attach: func(ctx: borrow<proc-context>, vout: u64, amt: decimal) -> result<transfer, error>;",
"export detach: func(ctx: borrow<proc-context>) -> result<transfer, error>;",
] as const;
export const nativeToken = parseWit(nativeTokenRaw);2. Create a indexer client
The indexer client can be used to read contract state and compose Kontor transactions using a type-safe interface.
import { getContractClient, signet, createKontorIndexerClient, http, nativeToken } from "@kontor/kontor-sdk";
const indexerClient = createKontorIndexerClient({
chain: signet,
transport: http(),
}); 3. Create a contract object
import {
getContractClient, signet, createKontorIndexerClient, http, nativeToken
} from "@kontor/kontor-sdk";
const indexerClient = createKontorIndexerClient({
chain: signet,
transport: http(),
});
const contract = getContractClient({
wit: nativeToken.wit,
contractAddress: "token_0_0",
client: indexerClient,
}) You know have a fully type safe interface to the contract.
contract.view.balancebalancestotalSupply
contract.proc.attachburndetachminttransfer
4. View contract state
const contract = getContractClient({
wit: nativeToken.wit,
contractAddress: "token_0_0",
client: indexerClient,
})
const const balances: readonly {
acc: string;
amt: [bigint, number];
}[]balances = await contract.view.balances();
5. Compose a Kontor transaction
const composeResponse = await contract.proc.transfer(
["dst-x-only-public-key", [42n, 18]],
{
utxos: ["txid:vout"],
account: ["src-taproot-address", "src-x-only-public-key"],
gas: 1000n,
satsPerVByte: 1,
},
);6. Create a wallet client
import {
createKontorWalletClient,
signet,
custom,
mnemonicToAccount
} from "@kontor/kontor-sdk";
const account = mnemonicToAccount("mnemomic phrase", {
networkConfig: signet.networkConfig,
coinType: 1,
}
);
const walletClient = createKontorWalletClient({
account,
chain: signet,
transport: custom({
request: async (args: any) => {},
}),
});7. Sign the commit and reveal
const signedCommitHex = await walletClient.signCommit({
psbt: composeResponse.result.commit_psbt_hex,
})
const signedRevealHex = await walletClient.signReveal({
psbt: composeResponse.result.reveal_psbt_hex,
participantScripts: composeResponse.result.per_participant,
})