Migrate to Clarinet JS SDK

Learn how to migrate your existing Clarinet projects to the Clarinet SDK.

In this guide, you will learn how to:

  1. Migrate your existing Clarinet projects to the Clarinet SDK.
  2. Run your existing tests using the Clarinet SDK.

This guide is for projects that have been created with Clarinet v1 and do not have the v2 boilerplate code auto-generated in their projects.


Prerequisites

The SDK requires Node.js >= 18.0 and NPM to be installed. Volta is a great tool to install and manage JS tooling.


Executing the migration script

Inside your Clarinet v1 project, run the following command to initialise NPM and Vitest. It will also create a sample test file.

Terminal
npx @hirosystems/clarinet-sdk@latest

Follow the prompts to initialise NPM and Vitest, this can take a few seconds.

The file tests/counter_test.ts that was created by clarinet contract new counter can be deleted.

You can also have a look at tests/contract.test.ts. It's a sample file showing how to use the SDK with Vitest. It can safely be deleted.

Unit test for counter example

tests/counter.test.ts
import { Cl } from '@stacks/transactions';
import { describe, expect, it } from 'vitest';

const accounts = simnet.getAccounts();
const address1 = accounts.get('wallet_1')!;

describe('test `increment` public function', () => {
  it('increments the count by the given value', () => {
    const incrementResponse = simnet.callPublicFn('counter', 'increment', [Cl.uint(1)], address1);
    console.log(Cl.prettyPrint(incrementResponse.result)); // (ok u2)
    expect(incrementResponse.result).toBeOk(Cl.uint(2));

    const count1 = simnet.getDataVar('counter', 'count');
    expect(count1).toBeUint(2);

    simnet.callPublicFn('counter', 'increment', [Cl.uint(40)], address1);
    const count2 = simnet.getDataVar('counter', 'count');
    expect(count2).toBeUint(42);
  });

  it('sends a print event', () => {
    const incrementResponse = simnet.callPublicFn('counter', 'increment', [Cl.uint(1)], address1);

    expect(incrementResponse.events).toHaveLength(1);
    const printEvent = incrementResponse.events[0];
    expect(printEvent.event).toBe('print_event');
    expect(printEvent.data.value).toBeTuple({
      object: Cl.stringAscii('count'),
      action: Cl.stringAscii('incremented'),
      value: Cl.uint(2),
    });
  });
});

To run the test, go back to your console and run the test command using your preferred package manager. It should display a report telling you that tests succeeded.

Terminal
npm test

The simnet object is available globally in the tests, and is automatically initialized before each test. You can have a look at the vitest.config.js file at the root of you project for more details.

Getting back to the tests - the first test checks that the increment function returns the new value and saves it to the count variable. The second test checks that an print_event is emitted when the increment function is called.

You can use Cl.prettyPrint(value: ClarityValue) to format any Clarity value into readable Clarity code. It can be useful to debug function results or event values.