Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions modules/sdk-coin-kaspa/.eslintignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
node_modules
.idea
public
dist

7 changes: 7 additions & 0 deletions modules/sdk-coin-kaspa/.eslintrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"extends": "../../.eslintrc.json",
"rules": {
"@typescript-eslint/explicit-module-boundary-types": "error",
"indent": "off"
}
}
8 changes: 8 additions & 0 deletions modules/sdk-coin-kaspa/.mocharc.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
require: 'tsx'
timeout: '60000'
reporter: 'min'
reporter-option:
- 'cdn=true'
- 'json=false'
exit: true
spec: ['test/unit/**/*.ts']
126 changes: 126 additions & 0 deletions modules/sdk-coin-kaspa/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
# @bitgo/sdk-coin-kaspa

BitGo's SDK module for the **Kaspa (KASPA)** blockchain.

## Overview

Kaspa is a proof-of-work blockchain based on the GHOSTDAG protocol (a generalization of Nakamoto consensus), enabling high block rates. This module implements Kaspa's UTXO model with **secp256k1 Schnorr signatures** (BIP-143-like sighash) and the custom **kaspa/kaspatest** bech32 address format.

Supported coin identifiers:

- `kaspa` — Kaspa mainnet
- `tkaspa` — Kaspa testnet

## Features

- Key pair generation (secp256k1)
- Address derivation (kaspa bech32 P2PK Schnorr)
- UTXO transaction building
- Schnorr signing and verification (Blake2b-256 sighash)
- TSS/MPC support (ECDSA algorithm)
- Full serialization round-trip (hex/JSON)

## Installation

```bash
yarn add @bitgo/sdk-coin-kaspa
```

## Usage

### Register with BitGo SDK

```typescript
import { register } from '@bitgo/sdk-coin-kaspa';
register(bitgo);
```

### Key Pair

```typescript
import { KeyPair } from '@bitgo/sdk-coin-kaspa';

// Generate a random key pair
const kp = new KeyPair();
const { pub, prv } = kp.getKeys();

// Derive address
const mainnetAddress = kp.getAddress('mainnet');
const testnetAddress = kp.getAddress('testnet');
```

### Build and Sign a Transaction

```typescript
import { TransactionBuilderFactory } from '@bitgo/sdk-coin-kaspa';
import { coins } from '@bitgo/statics';

const factory = new TransactionBuilderFactory(coins.get('kaspa'));
const builder = factory.getBuilder();

builder
.addInput({
transactionId: '<prev-tx-id>',
transactionIndex: 0,
amount: '100000000', // 1 KASPA in sompi
scriptPublicKey: '<spk>',
sequence: '0',
sigOpCount: 1,
})
.to('<recipient-kaspa-address>', '99998000')
.fee('2000');

const tx = await builder.build();
tx.sign(Buffer.from(privateKeyHex, 'hex'));

const broadcastPayload = tx.toBroadcastFormat(); // JSON string for RPC
```

## Module Structure

```
src/
├── kaspa.ts # Kaspa mainnet coin class
├── tkaspa.ts # Kaspa testnet coin class
├── register.ts # SDK registration
├── index.ts
└── lib/
├── constants.ts # Chain constants (prefixes, decimals, fees)
├── iface.ts # TypeScript interfaces
├── keyPair.ts # secp256k1 key pair
├── sighash.ts # Blake2b-256 Schnorr sighash
├── transaction.ts # Transaction class (sign/verify/explain)
├── transactionBuilder.ts # UTXO transaction builder
├── transactionBuilderFactory.ts
├── utils.ts # Address validation and encoding
└── index.ts
test/
├── fixtures/
│ ├── kaspa.fixtures.ts # Deterministic test vectors
│ └── kaspaFixtures.ts # Synthetic test fixtures
└── unit/
├── coin.test.ts
├── keyPair.test.ts
├── transaction.test.ts
├── transactionBuilder.test.ts
├── transactionFlow.test.ts
└── utils.test.ts
```

## Address Format

Kaspa uses a custom cashaddr-like bech32 encoding:

- Mainnet: `kaspa:<bech32-encoded-data>`
- Testnet: `kaspatest:<bech32-encoded-data>`
- Version byte `0` = Schnorr P2PK (x-only secp256k1 pubkey)

## Signing

Kaspa uses **Schnorr signatures over secp256k1** with a **Blake2b-256** sighash. The sighash preimage follows the Kaspa BIP-143-like specification. Each input is signed independently, producing a 65-byte signature: 64 bytes Schnorr + 1 byte sighash type.

## References

- [Kaspa Website](https://kaspa.org/)
- [Kaspa BIP-143-like SigHashes](https://github.com/kaspanet/docs/blob/main/Specs/BIP143-like%20SigHashes.md)
- [Kaspa RPC API](https://kaspa.aspectron.org/docs/)
52 changes: 52 additions & 0 deletions modules/sdk-coin-kaspa/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
{
"name": "@bitgo/sdk-coin-kaspa",
"version": "1.0.0",
"description": "BitGo's SDK coin library for Kaspa (KASPA)",
"main": "./dist/src/index.js",
"types": "./dist/src/index.d.ts",
"scripts": {
"build": "yarn tsc --build --incremental --verbose .",
"fmt": "prettier --write .",
"check-fmt": "prettier --check '**/*.{ts,js,json}'",
"clean": "rm -r ./dist",
"lint": "eslint --quiet .",
"prepare": "npm run build",
"test": "npm run coverage",
"coverage": "nyc -- npm run unit-test",
"unit-test": "mocha"
},
"repository": {
"type": "git",
"url": "https://github.com/BitGo/BitGoJS.git",
"directory": "modules/sdk-coin-kaspa"
},
"author": "BitGo SDK Team <[email protected]>",
"license": "MIT",
"engines": {
"node": ">=20"
},
"lint-staged": {
"*.{js,ts}": [
"yarn prettier --write",
"yarn eslint --fix"
]
},
"publishConfig": {
"access": "public"
},
"nyc": {
"extension": [
".ts"
]
},
"dependencies": {
"@bitgo/sdk-core": "^36.40.0",
"@bitgo/secp256k1": "^1.11.0",
"@bitgo/statics": "^58.35.0",
"bignumber.js": "9.0.0",
"blakejs": "^1.2.1"
},
"files": [
"dist"
]
}
5 changes: 5 additions & 0 deletions modules/sdk-coin-kaspa/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export * from './kaspa';
export * from './tkaspa';
export * from './lib';
export * as KaspaLib from './lib';
export * from './register';
Loading
Loading