# thor-devkit

> Typescript library to aid DApp development on VeChain Thor

Latest version **2.2.0** (published 2026-03-23) · MIT license · 0 weekly downloads

## Install

```sh
npm install thor-devkit
pnpm add thor-devkit
yarn add thor-devkit
bun add thor-devkit
```

## Health

**Score 60/100 (C)** — status: stable.

Positive: has types; esm support; no vulnerabilities; high quality score.

Warnings: low downloads.

## Facts

| | |
|---|---|
| Version | 2.2.0 |
| Published | 2026-03-23 |
| First published | 2018-07-18 |
| Weekly downloads | 0 |
| License | MIT |
| TypeScript types | bundled |
| Module format | ESM + CommonJS |
| Dependencies | 7 |
| Unpacked size | 223 KB |
| Known vulnerabilities | 0 (+1 in 1 direct dependencies) |
| Install scripts | no |
| GitHub stars | 40 |
| Author | qianbin |
| Maintainers | tony.li, cola_tin |
| Keywords | vechain, thor, blockchain, dapp, tx, transaction, crypto, mnemonic, keystore, abi |

## Links

- npm: https://www.npmjs.com/package/thor-devkit
- Repository: https://github.com/vechain/thor-devkit.js
- Homepage: https://github.com/vechain/thor-devkit.js#readme
- Issues: https://github.com/vechain/thor-devkit.js/issues
- npm.io page: https://npm.io/package/thor-devkit

## Dependencies (7)

- [rlp](https://npm.io/package/rlp.md) ^2.0.0
- [ethers](https://npm.io/package/ethers.md) ^6.13.0
- [blakejs](https://npm.io/package/blakejs.md) ^1.1.2
- [js-sha3](https://npm.io/package/js-sha3.md) 0.5.7
- [elliptic](https://npm.io/package/elliptic.md) ^6.6.1
- [bignumber.js](https://npm.io/package/bignumber.js.md) ^7.2.1
- [fast-json-stable-stringify](https://npm.io/package/fast-json-stable-stringify.md) ^2.1.0

## Alternatives

- [@gemini-wallet/core](https://npm.io/package/@gemini-wallet/core.md) — 515.6K weekly downloads
- [utility](https://npm.io/package/utility.md) — 416.6K weekly downloads
- [@primno/dpapi](https://npm.io/package/@primno/dpapi.md) — 7.2K weekly downloads
- [pi-readseek](https://npm.io/package/pi-readseek.md) — 3.7K weekly downloads
- [@emilia-protocol/verify](https://npm.io/package/@emilia-protocol/verify.md) — 1.1K weekly downloads

## Recent versions

- 2.2.0 (latest) — 2026-03-23
- 2.0.0 (beta) — 2020-10-29
- 2.1.1 — 2025-06-03
- 2.1.0 — 2025-05-09
- 2.0.9 — 2023-09-07
- 2.0.8 — 2023-06-09
- 2.0.7 — 2023-02-15
- 2.0.6 — 2022-11-22
- 2.0.5 — 2022-05-05
- 2.0.4 — 2021-12-23
- 2.0.3 — 2021-12-22
- 2.0.2 — 2021-11-26
- 2.0.1 — 2021-01-07
- 1.3.4-beta — 2020-10-28
- 1.3.3 — 2020-10-27
- … 43 more at https://npm.io/package/thor-devkit/versions

## README

# Thor DevKit

Typescript library to aid dApp development on VeChainThor.

[![NPM Version](https://badge.fury.io/js/thor-devkit.svg)](https://www.npmjs.com/package/thor-devkit)
[![Unit Test](https://github.com/vechain/thor-devkit.js/actions/workflows/test.yml/badge.svg)](https://github.com/vechain/thor-devkit.js/actions/workflows/test.yml)
[![Coverage Status](https://coveralls.io/repos/github/vechain/thor-devkit.js/badge.svg?branch=master)](https://coveralls.io/github/vechain/thor-devkit.js?branch=master)

## ⚠️ Repository Notice: End-of-Life (EOL)

**This repository now has reached its end-of-life (EOL).** We have transitioned to brand new and comprehensive [VeChain SDK](https://github.com/vechain/vechain-sdk-js) that will continue to receive updates, support, and new features.

For any further questions or migration guidance, please reach out using our [support portal](https://support.vechain.org/support/home).

## Prerequisites

 - [Git](https://git-scm.com/book/en/v2/Getting-Started-Installing-Git)
 - [Node.js](https://nodejs.org/en): minimum version is `18`.

## Installation

To install the library, run:

```bash
npm i thor-devkit
```

## Usage

### Transaction

To build and sign a transaction:

```javascript
import { Transaction, secp256k1 } from 'thor-devkit'

const clauses =  [{
    to: '0x7567d83b7b8d80addcb281a71d54fc7b3364ffed',
    value: 10000,
    data: '0x'
}]

// calc intrinsic gas
const gas = Transaction.intrinsicGas(clauses)
console.log(gas)
// 21000

let body: Transaction.LegacyBody = {
    type: Transaction.Type.Legacy,
    chainTag: 0x9a,
    blockRef: '0x0000000000000000',
    expiration: 32,
    clauses: clauses,
    gasPriceCoef: 128,
    gas,
    dependsOn: null,
    nonce: 12345678
}

const tx = new Transaction(body)
const signingHash = tx.signingHash()
tx.signature = secp256k1.sign(signingHash, /* your private key */)

const raw = tx.encode()
const decoded = Transaction.decode(raw)

// To create a dynamic fee transaction, use the following:
let body = {
    type: Transaction.Type.DynamicFee,
    chainTag: 0x9a,
    blockRef: '0x0000000000000000',
    clauses: clauses,
    maxPriorityFeePerGas: 1000000000000,
    maxFeePerGas: 1200000000000,
    gas,
    dependsOn: null,
    nonce: 12345678
}

const tx = new Transaction(body)
const signingHash = tx.signingHash()
tx.signature = secp256k1.sign(signingHash, /* your private key */)

const raw = tx.encode()
const decoded = Transaction.decode(raw)

// To decode a transaction, use the following:
const raw = Buffer.from('51cf80808203e8c001018252088080c080', 'hex')
const unsigned = false
const decoded = Transaction.decode(raw, unsigned)
```

### Certificate

Client side self-signed certificate:

```javascript
import { Certificate, secp256k1, blake2b256 } from 'thor-devkit'

const cert: Certificate = {
    purpose: 'identification',
    payload: {
        type: 'text',
        content: 'fyi'
    },
    domain: 'localhost',
    timestamp: 1545035330,
    signer: <<<signer-address>>>
}

const jsonStr = Certificate.encode(cert)
const signature = secp256k1.sign(blake2b256(jsonStr), <<<private-key>>>)

cert.signature = '0x' + signature.toString('hex')

Certificate.verify(cert)

// certificate id
const id = '0x' + blake2b256(Certificate.encode(cert)).toString('hex')
```

### ABI

```javascript
import { abi } from 'thor-devkit'

const fn = new abi.Function({
    "constant": false,
    "inputs": [
        {
            "name": "a1",
            "type": "uint256"
        },
        {
            "name": "a2",
            "type": "string"
        }
    ],
    "name": "f1",
    "outputs": [
        {
            "name": "r1",
            "type": "address"
        },
        {
            "name": "r2",
            "type": "bytes"
        }
    ],
    "payable": false,
    "stateMutability": "nonpayable",
    "type": "function"
})

const data = fn.encode(1, 'foo')
```

### RLP

```javascript
import { RLP } from 'thor-devkit'

// define the profile for tx clause structure
const profile: RLP.Profile = {
    name: 'clause',
    kind: [
        { name: 'to', kind: new RLP.NullableFixedBlobKind(20) },
        { name: 'value', kind: new RLP.NumericKind(32) },
        { name: 'data', kind: new RLP.BlobKind() }
    ]
}

const clause = {
    to: '0x7567d83b7b8d80addcb281a71d54fc7b3364ffed',
    value: 10,
    data: '0x'
}

const rlp = new RLP(profile)

const data = rlp.encode(clause)
console.log(data.toString('hex'))
// d7947567d83b7b8d80addcb281a71d54fc7b3364ffed0a80

const obj = rlp.decode(data)
// `obj` should be identical to `clause`
```

### Crypto methods

#### Hash functions

```javascript
import { blake2b256, keccak256 } from 'thor-devkit'

const hash = blake2b256('hello world')
console.log(hash.toString('hex'))
// 256c83b297114d201b30179f3f0ef0cace9783622da5974326b436178aeef610

hash = keccak256('hello world')
console.log(hash.toString('hex'))
// 47173285a8d7341e5e972fc677286384f802f8ef42a5ec5f03bbfa254cb01fad
```

#### Secp256k1

```javascript
import { secp256k1, keccak256, address } from 'thor-devkit'

const privKey = secp256k1.generatePrivateKey()
const pubKey = secp256k1.derivePublicKey(privKey)
const addr = address.fromPublicKey(pubKey)
const signature = secp256k1.sign(keccak256('hello world'), privKey)
const recoveredPubKey = secp256k1.recover(keccak256('hello world'), signature)
```

#### Mnemonic & Keystore

```javascript
import { mnemonic, Keystore, HDNode } from 'thor-devkit'

// generate BIP39 mnemonic words, default to 12 words(128bit strength)
const words = mnemonic.generate()

// derive private key from mnemonic words according to BIP32, using the path `m/44'/818'/0'/0`.
// defined for VET at https://github.com/satoshilabs/slips/blob/master/slip-0044.md
const privateKey = mnemonic.derivePrivateKey(words)

// in recovery process, validation is recommended
let ok = mnemonic.validate(words)

// encrypt/decrypt private key using Ethereum's keystore scheme
const keystore = await Keystore.encrypt(privateKey, 'your password')

// throw for wrong password
const recoveredPrivateKey = await Keystore.decrypt(keystore, 'your password')

// roughly check keystore format
ok = Keystore.wellFormed(keystore)

// create BIP32 HD node from mnemonic words
const hdnode = HDNode.fromMnemonic(words)

// derive 5 child private keys
for (let i = 0; i < 5; i++) {
    let child = hdnode.derive(i)
    // get child private key
    // child.privateKey
}

// or create HD node from xpub
const pub = Buffer.from('04dc40b4324626eb393dbf77b6930e915dcca6297b42508adb743674a8ad5c69a046010f801a62cb945a6cb137a050cefaba0572429fc4afc57df825bfca2f219a', 'hex')
const chainCode = Buffer.from('105da5578eb3228655a8abe70bf4c317e525c7f7bb333634f5b7d1f70e111a33', 'hex')
hdnode = HDNode.fromPublicKey(pub, chainCode)
// derive 5 child public keys
for (let i = 0; i < 5; i++) {
    let child = hdnode.derive(i)
    // get child public key
    // child.publicKey
}
```


## License

Thor DevKit is licensed under the
[MIT License](https://github.com/vechain/thor-devkit.js/blob/master/LICENSE).

---
_Source: https://npm.io/package/thor-devkit · Machine-readable twin of the npm.io package page. Health data is recomputed on every publish._
