Skip to content

Getting Started

Start interacting with Kontor in just a few lines of code

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
npm install @kontor/kontor-sdk

Quick 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.
balance
balances
totalSupply
 
 
contract.proc.
attach
burn
detach
mint
transfer

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,  
})