Skip to content

Add Bitcoin network docs and example #135

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
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
8 changes: 8 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,14 @@ Then an authz example website will be created and users can take a look how sign

---

### Bitcoin Network

| Feature | Package |
| ---------------- | ------------------------------------------------------ |
| **Transactions** | [@interchainjs/bitcoin](https://docs.hyperweb.io/interchain-js/networks/bitcoin) |

---

## Interchain JavaScript Stack ⚛️

A unified toolkit for building applications and smart contracts in the Interchain ecosystem
Expand Down
5 changes: 3 additions & 2 deletions docs/advanced/_meta.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,6 @@
"migration-from-cosmjs": "Migration from CosmJS",
"signer": "Signer",
"tutorial": "Tutorial",
"wallet": "Wallet"
}
"wallet": "Wallet",
"add-network": "Add a Network"
}
10 changes: 10 additions & 0 deletions docs/advanced/add-network.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# Adding a New Network

This guide outlines the basic steps to integrate a new blockchain network with InterchainJS. A network package exposes signers and account utilities that follow the interfaces defined in `@interchainjs/types`.

1. **Create a new package** under `networks/` with its own `package.json`, `tsconfig.json` and `src` folder. Export your signers and accounts from an `index.ts` file.
2. **Implement signers** that perform the necessary cryptographic signing. Signers typically wrap private keys or wallet providers and expose methods like `sign` or `send`.
3. **Provide account helpers** to derive addresses from public keys. Reuse hashing and encoding utilities from `@interchainjs/crypto` and `@interchainjs/encoding`.
4. **Document your network** in `docs/networks/` so users can install and use it.

Existing networks such as [Cosmos](./../networks/cosmos/index.mdx) and [Ethereum](./../networks/ethereum/index.mdx) can serve as references for structuring your package.
8 changes: 8 additions & 0 deletions docs/index.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,14 @@ Then an authz example website will be created and users can take a look how sign

---

### Bitcoin Network

| Feature | Package |
| ---------------- | ------------------------------------------------------ |
| **Transactions** | [@interchainjs/bitcoin](https://docs.hyperweb.io/interchain-js/networks/bitcoin) |

---

## Interchain JavaScript Stack ⚛️

A unified toolkit for building applications and smart contracts in the Interchain ecosystem
Expand Down
5 changes: 3 additions & 2 deletions docs/networks/_meta.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
{
"cosmos": "Cosmos",
"ethereum": "Ethereum",
"injective": "Injective"
}
"injective": "Injective",
"bitcoin": "Bitcoin"
}
3 changes: 3 additions & 0 deletions docs/networks/bitcoin/_meta.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"index": "Overview"
}
31 changes: 31 additions & 0 deletions docs/networks/bitcoin/index.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# @interchainjs/bitcoin

Transaction signing and account utilities for the Bitcoin network.

## Usage

```sh
npm install @interchainjs/bitcoin
```

```ts
import { SignerFromPrivateKey } from '@interchainjs/bitcoin'

const signer = new SignerFromPrivateKey(privateKeyHex)
const address = signer.getAddress()
```

## Implementations

- **SignerFromPrivateKey** from `@interchainjs/bitcoin/signers/SignerFromPrivateKey`
- **BitcoinAccount** from `@interchainjs/bitcoin/accounts/bitcoin-account`

## Credits

🛠 Built by Hyperweb (formerly Cosmology) — if you like our tools, please check out and contribute to [our github ⚛️](https://github.com/hyperweb-io)

## Disclaimer

AS DESCRIBED IN THE LICENSES, THE SOFTWARE IS PROVIDED "AS IS", AT YOUR OWN RISK, AND WITHOUT WARRANTIES OF ANY KIND.

No developer or entity involved in creating this software will be liable for any claims or damages whatsoever associated with your use, inability to use, or your interaction with other users of the code, including any direct, indirect, incidental, special, exemplary, punitive or consequential damages, or loss of profits, cryptocurrencies, tokens, or anything else of value.
32 changes: 32 additions & 0 deletions networks/bitcoin/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# @interchainjs/bitcoin

Transaction signing and account utilities for the Bitcoin network.

## Usage

```sh
npm install @interchainjs/bitcoin
```

```ts
import { SignerFromPrivateKey } from '@interchainjs/bitcoin'

const signer = new SignerFromPrivateKey(privateKeyHex)
const address = signer.getAddress()
```

## Implementations

- **SignerFromPrivateKey** from `@interchainjs/bitcoin/signers/SignerFromPrivateKey`
- **BitcoinAccount** from `@interchainjs/bitcoin/accounts/bitcoin-account`

## Credits

🛠 Built by Hyperweb (formerly Cosmology) — if you like our tools, please check out and contribute to [our github ⚛️](https://github.com/hyperweb-io)

## Disclaimer

AS DESCRIBED IN THE LICENSES, THE SOFTWARE IS PROVIDED "AS IS", AT YOUR OWN RISK, AND WITHOUT WARRANTIES OF ANY KIND.

No developer or entity involved in creating this software will be liable for any claims or damages whatsoever associated with your use, inability to use, or your interaction with other users of the code, including any direct, indirect, incidental, special, exemplary, punitive or consequential damages, or loss of profits, cryptocurrencies, tokens, or anything else of value.

33 changes: 33 additions & 0 deletions networks/bitcoin/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
{
"name": "@interchainjs/bitcoin",
"version": "1.11.11",
"description": "Bitcoin signing utilities",
"main": "index.js",
"module": "esm/index.js",
"types": "index.d.ts",
"author": "Hyperweb <developers@hyperweb.io>",
"homepage": "https://github.com/hyperweb-io/interchainjs",
"repository": {
"type": "git",
"url": "https://github.com/hyperweb-io/interchainjs"
},
"license": "MIT",
"publishConfig": {
"access": "public",
"directory": "dist"
},
"scripts": {
"copy": "copyfiles -f ../../LICENSE-MIT ../../LICENSE-Apache README.md package.json dist",
"clean": "rimraf dist/**",
"prepare": "npm run build",
"build": "npm run clean; tsc; tsc -p tsconfig.esm.json; npm run copy",
"build:dev": "npm run clean; tsc --declarationMap; tsc -p tsconfig.esm.json; npm run copy",
"lint": "eslint . --fix"
},
"dependencies": {
"@interchainjs/auth": "1.11.11",
"@interchainjs/crypto": "1.11.11",
"@interchainjs/types": "1.11.11",
"@interchainjs/utils": "1.11.11"
}
}
14 changes: 14 additions & 0 deletions networks/bitcoin/src/accounts/bitcoin-account.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { AccountBase } from '@interchainjs/types/account';
import { sha256, ripemd160 } from '@interchainjs/crypto';
import { toBech32 } from '@interchainjs/encoding';

export class BitcoinAccount extends AccountBase {
getAddressByPubKey(): string {
const pub = this.auth.getPublicKey(true);
const hash160 = ripemd160(sha256(pub.value));
const data = new Uint8Array(1 + hash160.length);
data[0] = 0x00; // witness version 0
data.set(hash160, 1);
return toBech32(this.prefix, data);
}
}
2 changes: 2 additions & 0 deletions networks/bitcoin/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export * from './signers/SignerFromPrivateKey';
export * from './accounts/bitcoin-account';
71 changes: 71 additions & 0 deletions networks/bitcoin/src/signers/SignerFromPrivateKey.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
import { sha256, ripemd160 } from '@interchainjs/crypto';
import { Key } from '@interchainjs/utils';
import { secp256k1 } from '@noble/curves/secp256k1';
import { bytesToHex, hexToBytes } from '@noble/hashes/utils';

function base58Encode(data: Uint8Array): string {
const alphabet = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz';
const digits = [0];
for (const byte of data) {
let carry = byte;
for (let i = 0; i < digits.length; i++) {
carry += digits[i] << 8;
digits[i] = carry % 58;
carry = (carry / 58) | 0;
}
while (carry > 0) {
digits.push(carry % 58);
carry = (carry / 58) | 0;
}
}
let zeros = 0;
for (const byte of data) {
if (byte === 0) {
zeros++;
} else {
break;
}
}
let result = '';
for (let i = 0; i < zeros; i++) {
result += '1';
}
for (let i = digits.length - 1; i >= 0; i--) {
result += alphabet[digits[i]];
}
return result;
}

function base58CheckEncode(data: Uint8Array): string {
const checksum = sha256(sha256(data)).slice(0, 4);
const total = new Uint8Array(data.length + 4);
total.set(data);
total.set(checksum, data.length);
return base58Encode(total);
}

export class SignerFromPrivateKey {
private privateKey: Uint8Array;

constructor(privateKeyHex: string) {
this.privateKey = hexToBytes(privateKeyHex.replace(/^0x/, ''));
}

getPublicKey(compressed = true): Uint8Array {
return secp256k1.getPublicKey(this.privateKey, compressed);
}

getAddress(prefix = 0x00): string {
const pub = this.getPublicKey(true);
const hash160 = ripemd160(sha256(pub));
const payload = new Uint8Array(1 + hash160.length);
payload[0] = prefix;
payload.set(hash160, 1);
return base58CheckEncode(payload);
}

sign(hash: Uint8Array): Uint8Array {
const sig = secp256k1.sign(hash, this.privateKey);
return sig.toCompactRawBytes();
}
}
9 changes: 9 additions & 0 deletions networks/bitcoin/tsconfig.esm.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"extends": "./tsconfig.json",
"compilerOptions": {
"outDir": "dist/esm",
"module": "es2022",
"rootDir": "src/",
"declaration": false
}
}
9 changes: 9 additions & 0 deletions networks/bitcoin/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"extends": "../../tsconfig.json",
"compilerOptions": {
"outDir": "dist",
"rootDir": "src/"
},
"include": ["src/**/*.ts"],
"exclude": ["dist", "node_modules", "**/*.spec.*", "**/*.test.*"]
}
Loading