npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@papaya-dao/reed

v0.0.4

Published

Reed makes playing with the Clarinet SDK easier!

Downloads

4

Readme

reed

Installation

reed is a test framework for @hirosystems/clarinet-sdk with the goal of providing a developer experience familiar to Ethereum developers.

  • npm
npm install --save-dev @papaya-dao/reed
  • yarn
yarn add -D @papaya-dao/reed

Clarinet SDK API Differences

The ExtendedSimnet class extends the Simnet class provided by the @hirosystems/clarinet-sdk package. It provides identical and additional methods and properties for interacting with the simulated network. ExtendedSimnet uses the Proxy pattern to override the methods of the Simnet class, providing more flexibility.

import { ExtendedSimnet, ExtendedSimnetParams } from "@papaya-dao/reed"
declare const simnet: Simnet;
const params: ExtendedSimnetParams = { simnet, expect };
const simNet = ExtendedSimnet.create(params);

// simNet can be used in place of simnet
const getSymbolResponse = simNet.callReadOnlyFn(
  "my-sip-010-token",
  "get-symbol",
  [stxTokenSignifier, depositAmount],
  sender
);

The connect method in ExtendedSimnet allows you to connect to the Simnet network with a specified sender. callReadOnlyFn and callPublicFn methods on ExtendedSimnet are overridden to use the sender specified in the connect method unless overridden by passing sender as the last argument as specified by the Simnet api.

declare const simnet: Simnet;
const params: ExtendedSimnetParams = { simnet, expect }; 
const simNet = ExtendedSimnet.create(params);// wallet_1 conntected by default

const getSymbolResponse = simNet.callReadOnlyFn(
  "my-sip-010-token",
  "get-symbol",
  [stxTokenSignifier, depositAmount],
  // sender <--- able to omit sender, simnet will use wallet_1 by default
);

The connect method implements the builder pattern for method chaining:

const getSymbolResponse = simNet.connect('wallet_2') // connect a different sender
  .callReadOnlyFn(
    "my-sip-010-token",
    "get-symbol",
    [stxTokenSignifier, depositAmount]
  );

ExtendedSimnet API

  • getPrincipal()

Returns the sender's principal as a string.

  • getDeployedContractPrincipal(contractName: string)

Returns the principal of a deployed contract.

ExtendedParsedTransactionResult

The ExtendedParsedTransactionResult class extends the ParsedTransactionResult class from the @hirosystems/clarinet-sdk package. It provides an expect method that allows expectation chaining on the transaction result.

const extendedSimnet = ExtendedSimnet.create(params);
const params: ExtendedSimnetParams = { simnet, expect }; // wondering why we pass expect?
extendedSimnet
  .callReadOnlyFn("counter", "get-counter", [])
  .expect // we can method chain like this
  .toHaveClarityType(ClarityType.ResponseOk);

ClarityContract magic 🪄

The ClarityContract class implements the proxy design pattern, which automatically tries to convert kebab-case stacks clarity contract names to camelCase and match the proxy prop against these functions to automatically dispatch callReadOnlyFn or callPublicFn

[...]
static create<T extends ClarityContract>(simnet: ExtendedSimnet, contractName: string, sender: string = 'wallet_1', _debug: boolean = false, _extends: T|null = null) {
      const instance = new this(simnet, contractName, sender, _debug, _extends);
      return new Proxy(instance, {
        get: (target: typeof instance, prop: string, receiver) => {
          const maybeInterface = target.tryGetFnInterface(prop);

          // first, attempt to proxy to the smart contract interface
          if (maybeInterface) {
            return function (...args: any[]) {
              if (args.length != maybeInterface.args.length) throw Error(`Wrong number of arguments, expecting: ${JSON.stringify(maybeInterface.args)}`);
              if (maybeInterface.access == 'public') {
                return target.simnet.callPublicFn(contractName, maybeInterface.name, [...args]);
              } else {
                return target.simnet.callReadOnlyFn(contractName, maybeInterface.name, [...args]);
              }
            };
          }
          [...]
        }
      });
    }

This allows you to define and interact with ClarityContracts like so:

export interface MyToken {
    getBalance(owner: PrincipalCV): ExtendedParsedTransactionResult;
    getTotalSupply(): ExtendedParsedTransactionResult;
    getName(): ExtendedParsedTransactionResult;
    getSymbol(): ExtendedParsedTransactionResult;
    getDecimals(): ExtendedParsedTransactionResult;
    transfer(amount: UIntCV, sender: PrincipalCV, recipient: PrincipalCV, memo?: OptionalCV<BufferCV>): ExtendedParsedTransactionResult;
    getTokenUri(): ExtendedParsedTransactionResult;
    mint(receiver: PrincipalCV, amount: UIntCV): ExtendedParsedTransactionResult;
}

export class MyToken extends ClarityContract {
    static contractName = 'my-token';

    static create(simnet: Simnet, contractName: string = MyToken.contractName, sender: string = 'wallet_1', _debug: boolean = false): MyToken {
        const instance = new MyToken(simnet, contractName, sender, _debug);
        return (ClarityContract.create(simnet, contractName, sender, _debug, instance) as MyToken);
    }
}

[...]

const extendedSimnet = ExtendedSimnet.create(params);
const params: ExtendedSimnetParams = { simnet, expect };
const myToken = MyToken.create(simNet);
const user = Cl.standardPrincipal(myToken.getSender());
myToken
  .getBalance(user)
  .expect
  .toBeOk(Cl.uint(rewardAmount * BigInt(3)))