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 🙏

© 2025 – Pkg Stats / Ryan Hefner

@btc-vision/opnet-transform

v0.2.1

Published

OP_NET AssemblyScript transform

Downloads

4,133

Readme

AssemblyScript Smart Contract Transform

Bitcoin AssemblyScript TypeScript NodeJS WebAssembly NPM

code style: prettier

This package is an AssemblyScript transform that automatically scans your smart-contract source code for:

  • Methods decorated with @method, @returns, and @emit
  • Event classes (declared via @event or classes extending NetEvent)
  • Constructor parameters for event classes
  • ABI definitions and type definitions for each contract class

It then:

  1. Generates ABI files (.abi.json) in an abis/ folder for each contract class.
  2. Generates .d.ts definitions for each ABI.
  3. Injects an execute(...) method that dispatches calls based on a 4-byte selector.

This is useful for writing contracts in AssemblyScript while automatically producing typed ABIs and event definitions.


Table of Contents


Configuration

To use this transform, you should configure your AssemblyScript project with the following files:

tsconfig.json:

{
  "extends": "@btc-vision/opnet-transform/std/assembly.json",
  "include": [
    "./**/*.ts",
    "../contracts/**/*.ts"
  ]
}
  • Extends a basic AssemblyScript/TypeScript config from @btc-vision/opnet-transform.
  • In include, list all the .ts paths to be compiled.

asconfig.json:

{
  "targets": {
    "release": {
      "outFile": "build/MyToken.wasm",
      "textFile": "build/MyToken.wat",
      "sourceMap": false,
      "optimizeLevel": 3,
      "shrinkLevel": 2,
      "converge": true,
      "noAssert": true,
      "disable": [
        "mutable-globals",
        "sign-extension",
        "nontrapping-f2i",
        "bulk-memory"
      ],
      "runtime": "stub",
      "memoryBase": 0,
      "initialMemory": 1,
      "maximumMemory": 512,
      "bindings": "esm",
      "exportStart": "start",
      "use": [
        "abort=src/index/abort"
      ]
    }
  },
  "options": {
    "transform": "@btc-vision/opnet-transform"
  }
}

In particular:

  • "transform": "@btc-vision/opnet-transform" instructs AssemblyScript to run this transform on your code.
  • The "targets.release" block is where you specify how to compile your .wasm, how aggressively to optimize, memory limits, etc.

With both tsconfig.json and asconfig.json in place, simply run your build script (e.g. asc --config asconfig.json) to compile your AssemblyScript code through the transform.


How It Works

Decorators

  • @method(...): Marks a method as callable; this is added to the contract’s ABI.
  • @returns(...): Defines return values for a method, which the transform adds to the ABI.
  • @emit(...): Declares that the method will emit certain event names.

Event Classes

Event classes can be declared in two ways:

  1. Extending NetEvent:

    export class Deposit extends NetEvent {
      constructor(user: Address, poolId: u64, amount: u256, to: Address) {
        const eventData = new BytesWriter(...);
        eventData.writeAddress(user);
        ...
        super("Deposit", eventData);
      }
    }
    • Automatically recognized as an event, even without @event.
  2. Using the @event Decorator:

    @event("Deposit")
    export class Deposit {
      user: Address;
      amount: u256;
      ...
    }

Methods & Returns

Each callable method can have a @method(...) decorator to:

  • Override the method name for ABI purposes.
  • Provide parameter definitions (either as strings or { name, type } objects).

A @returns(...) decorator can define the output parameters. For example:

@method("mint", { name: "to", type: ABIDataTypes.ADDRESS }, { name: "amount", type: ABIDataTypes.UINT256 })
@returns({ name: "success", type: ABIDataTypes.BOOL })

Emit Decorator

Annotate a method with @emit("EventNameA", "EventNameB") if it triggers events. The transform will:

  1. Assign those events to the contract’s ABI.
  2. Generate typed event definitions (like EventNameAEvent in the .d.ts).
  3. Warn if you reference an event that isn’t declared.

Example Contract

import { u256 } from '@btc-vision/as-bignum/assembly';
import {
    Address,
    AddressMap,
    Blockchain,
    BytesWriter,
    Calldata,
    DeployableOP_20,
    OP20InitParameters,
    BOOLEAN_BYTE_LENGTH,
} from '@btc-vision/btc-runtime/runtime';

@final
export class MyToken extends DeployableOP_20 {
    public constructor() {
        super();
        // ...
    }

    public override onDeployment(_calldata: Calldata): void {
        const maxSupply: u256 = u256.fromString('100000000000000000000000000000000000');
        const decimals: u8 = 18;
        const name: string = 'BobTheNoob';
        const symbol: string = 'BOB';

        this.instantiate(new OP20InitParameters(maxSupply, decimals, name, symbol));
    }

    @method(
        { name: 'address', type: ABIDataTypes.ADDRESS },
        { name: 'amount', type: ABIDataTypes.UINT256 },
    )
    @returns({ name: 'success', type: ABIDataTypes.BOOL })
    public mint(calldata: Calldata): BytesWriter {
        this.onlyDeployer(Blockchain.tx.sender);

        const response = new BytesWriter(BOOLEAN_BYTE_LENGTH);
        const resp = this._mint(calldata.readAddress(), calldata.readU256());
        response.writeBoolean(resp);

        return response;
    }

    // ...
}

Missing @emit?

If you define a method that emits an event class, you can mark it:

@method()
@emit("TransferEvent")
public
transfer(calldata
:
Calldata
):
BytesWriter
{
    // ...
    // triggers event 'TransferEvent'
    return new BytesWriter(0);
}

This ensures the event gets added to the contract’s ABI.


Generated ABI Artifacts

After compiling, you’ll find a directory named abis/ containing:

  1. <ClassName>.abi.json
    Describes the methods (and their input/output types) plus any events the class uses.
  2. <ClassName>.d.ts
    A TypeScript declaration file for typed usage in client code, e.g.:
    import { IMyToken } from "./abis/MyToken";

Each .d.ts includes:

  • Event interfaces: <EventName>Event.
  • CallResult types: describing the method outputs and the events it emits.

Typical Usage with asc

Use the AssemblyScript compiler, referencing asconfig.json:

npx asc -c asconfig.json
  • The transform scans your code for @method, @returns, @emit, and event classes.
  • It automatically creates an abis/ folder next to your compiler output.

FAQ / Tips

  1. Can I rename a method for ABI without changing its actual function name?
    Yes, you can do @method("someOtherName", "uint256").

  2. How do I define multiple returns?
    Use @returns("uint256", "bool") or multiple named objects: @returns({ name: "foo", type: "uint256" }, { name: "bar", type: "bool" }).

  3. Where do events go if I never reference them with @emit?
    The transform logs a warning that an event was declared but never used. Unused events won’t appear in any contract’s final ABI.

  4. How do I reference events across multiple files?
    As long as the event class (extending NetEvent) is imported into the same compilation scope, the transform sees it. @emit("EventName") just has to match the event’s class name or override name (if you used @event("SomeName")).


License

MIT