Skip to content
This repository was archived by the owner on May 27, 2025. It is now read-only.
Merged
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
9 changes: 9 additions & 0 deletions .changeset/fair-impalas-crash.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
---
"@rgbpp-sdk/btc": patch
---

Add sendUtxos() API for building transactions that has wider support for predefined inputs/outputs.
This feature also includes breaking changes, such as:

- Type/Function/Constant name changes
- Refactor of the fee/satoshi collection process
5 changes: 5 additions & 0 deletions .changeset/new-phones-lick.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@rgbpp-sdk/btc": patch
---

Remove the "TxBuilder.collectInputsAndPayFee" API as it is deprecated and no longer in use
6 changes: 6 additions & 0 deletions .changeset/twelve-forks-float.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"@rgbpp-sdk/btc": patch
---

Add sendRgbppUtxos() API for building RGBPP sync transactions on the bitcoin side.
Also renamed some errors that are unrelated to the feature implementation.
3 changes: 3 additions & 0 deletions .github/workflows/test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,9 @@ jobs:

- name: Install dependencies
run: pnpm i

- name: Build packages
run: pnpm run build:packages

- name: Run tests for packages
run: pnpm run test:packages
Expand Down
259 changes: 226 additions & 33 deletions packages/btc/README.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
# @rgbpp-sdk/btc

This lib provides:
## About

- APIs for constructing simple BTC transactions
- APIs for accessing the [btc-assets-api](https://github.com/ckb-cell/btc-assets-api) service in TypeScript
This is the BTC part of the rgbpp-sdk for:

## Disclaimer
- BTC/RGBPP transaction construction
- Wrapped API of the [BtcAssetsApi](https://github.com/ckb-cell/btc-assets-api) service in Node and browser

- The main logic of the `@rgbpp-sdk/btc` lib is referenced and cut/simplified from the [unisat wallet-sdk](https://github.com/unisat-wallet/wallet-sdk) package to adapt to the specific needs of our own projects. The unisat wallet-sdk is using the [ISC license](https://github.com/unisat-wallet/wallet-sdk/blob/master/LICENSE). If we open-source our project in the future, it would be best to include the appropriate license referencing the unisat wallet-sdk.
This lib is based on the foundation of the [unisat wallet-sdk](https://github.com/unisat-wallet/wallet-sdk) ([license](https://github.com/unisat-wallet/wallet-sdk/blob/master/LICENSE)). We've simplified the logic of transaction construction and fee collection process to adapt to the specific needs of RGBPP. You can refer to the unisat wallet-sdk repo for more difference.

## Getting started

Expand Down Expand Up @@ -75,12 +75,9 @@ Transfer BTC from a `P2WPKH` address:
```typescript
import { sendBtc, BtcAssetsApi, DataSource, NetworkType } from '@rgbpp-sdk/btc';

const networkType = NetworkType.TESTNET;

const service = BtcAssetsApi.fromToken('btc_assets_api_url', 'your_token');
const source = new DataSource(service, networkType);
const source = new DataSource(service, NetworkType.TESTNET);

// Create a PSBT
const psbt = await sendBtc({
from: account.address, // your P2WPKH address
tos: [
Expand All @@ -89,8 +86,7 @@ const psbt = await sendBtc({
value: 1000, // transfer satoshi amount
},
],
feeRate: 1, // optional
networkType,
feeRate: 1, // optional, default to 1 sat/vbyte
source,
});

Expand All @@ -104,15 +100,49 @@ const res = await service.sendTransaction(tx.toHex());
console.log('txid:', res.txid);
```

Create an `OP_RETURN` output:
Transfer BTC from a `P2TR` address:

```typescript
import { sendBtc, BtcAssetsApi, DataSource, NetworkType } from '@rgbpp-sdk/btc';

const networkType = NetworkType.TESTNET;
const service = BtcAssetsApi.fromToken('btc_assets_api_url', 'your_token');
const source = new DataSource(service, NetworkType.TESTNET);

const psbt = await sendBtc({
from: account.address, // your P2TR address
fromPubkey: account.publicKey, // your public key, this is required for P2TR
tos: [
{
address: 'to_address', // destination btc address
value: 1000, // transfer satoshi amount
},
],
feeRate: 1, // optional, default to 1 sat/vbyte
source,
});

// Create a tweaked signer
const tweakedSigner = tweakSigner(account.keyPair, {
network,
});

// Sign & finalize inputs
psbt.signAllInputs(tweakedSigner);
psbt.finalizeAllInputs();

// Broadcast transaction
const tx = psbt.extractTransaction();
const res = await service.sendTransaction(tx.toHex());
console.log('txid:', res.txid);
```

Create an `OP_RETURN` output:

```typescript
import { sendBtc, BtcAssetsApi, DataSource, NetworkType } from '@rgbpp-sdk/btc';

const service = BtcAssetsApi.fromToken('btc_assets_api_url', 'your_token');
const source = new DataSource(service, networkType);
const source = new DataSource(service, NetworkType.TESTNET);

// Create a PSBT
const psbt = await sendBtc({
Expand All @@ -123,8 +153,57 @@ const psbt = await sendBtc({
value: 0, // normally the value is 0
},
],
feeRate: 1, // optional
networkType,
changeAddress: account.address, // optional, where to return the change
feeRate: 1, // optional, default to 1 sat/vbyte
source,
});

// Sign & finalize inputs
psbt.signAllInputs(account.keyPair);
psbt.finalizeAllInputs();

// Broadcast transaction
const tx = psbt.extractTransaction();
const res = await service.sendTransaction(tx.toHex());
console.log('txid:', res.txid);
```

Transfer with predefined inputs/outputs:

```typescript
import { sendUtxos, BtcAssetsApi, DataSource, NetworkType } from '@rgbpp-sdk/btc';

const service = BtcAssetsApi.fromToken('btc_assets_api_url', 'your_token');
const source = new DataSource(service, NetworkType.TESTNET);

const psbt = await sendUtxos({
inputs: [
{
txid: 'txid',
vout: 1,
value: 546,
address: 'btc_address',
addressType: AddressType.P2WPKH,
scriptPk: 'script_publickey_hex',
},
],
outputs: [
{
data: Buffer.from('commentment_hex', 'hex'), // RGBPP commitment
value: 0,
fixed: true, // mark as fixed, so the output.value will not be changed
},
{
address: 'to_address',
value: 546,
fixed: true,
minUtxoSatoshi: 546, // customize the dust limit of the output
},
],
from: account.address, // provide fee to the transaction
fromPubkey: account.publicKey, // optional, required if "from" is a P2TR address
changeAddress: account.address, // optional, where to send the change
feeRate: 1, // optional, default to 1 sat/vbyte
source,
});

Expand All @@ -145,18 +224,118 @@ console.log('txid:', res.txid);
#### sendBtc

```typescript
declare function sendBtc(props: {
from: string;
tos: {
address: string;
value: number;
}[];
source: DataSource;
networkType: NetworkType;
interface sendBtc {
(props: {
from: string;
tos: InitOutput[];
source: DataSource;
fromPubkey?: string;
changeAddress?: string;
minUtxoSatoshi?: number;
feeRate?: number;
}): Promise<bitcoin.Psbt>;
}
```

#### sendUtxos

```typescript
interface sendUtxos {
(props: {
inputs: Utxo[];
outputs: InitOutput[];
source: DataSource;
from: string;
fromPubkey?: string;
changeAddress?: string;
minUtxoSatoshi?: number;
feeRate?: number;
}): Promise<bitcoin.Psbt>;
}
```

#### sendRgbppUtxos

```typescript
interface sendRgbppUtxos {
(props: {
ckbVirtualTx: RawTransaction;
paymaster: TxAddressOutput;
commitment: Hash;
tos?: string[];

ckbNodeUrl: string;
rgbppLockCodeHash: Hash;
rgbppTimeLockCodeHash: Hash;
rgbppMinUtxoSatoshi?: number;

from: string;
source: DataSource;
fromPubkey?: string;
changeAddress?: string;
minUtxoSatoshi?: number;
feeRate?: number;
}): Promise<bitcoin.Psbt>;
}
```

#### InitOutput

```typescript
type InitOutput = TxAddressOutput | TxDataOutput | TxScriptOutput;
```

#### TxAddressOutput / TxDataOutput / TxScriptOutput

```typescript
interface TxAddressOutput extends BaseOutput {
address: string;
}
```

```typescript
interface TxDataOutput extends BaseOutput {
data: Buffer | string;
}
```

```typescript
interface TxScriptOutput extends BaseOutput {
script: Buffer;
}
```

#### BaseOutput

```typescript
interface BaseOutput {
value: number;
fixed?: boolean;
protected?: boolean;
minUtxoSatoshi?: number;
changeAddress?: string;
feeRate?: number;
}): Promise<bitcoin.Psbt>;
}
```

#### DataSource

```typescript
interface DataSource {
constructor(service: BtcAssetsApi, networkType: NetworkType): void;
getUtxos(address: string, params?: BtcAssetsApiUtxoParams): Promise<Utxo[]>;
collectSatoshi(props: {
address: string;
targetAmount: number;
minUtxoSatoshi?: number;
excludeUtxos?: {
txid: string;
vout: number;
}[];
}): Promise<{
utxos: Utxo[];
satoshi: number;
exceedSatoshi: number;
}>;
}
```

### Service
Expand All @@ -167,8 +346,8 @@ declare function sendBtc(props: {
interface BtcAssetsApi {
init(): Promise<void>;
generateToken(): Promise<BtcAssetsApiToken>;
getBalance(address: string): Promise<BtcAssetsApiBalance>;
getUtxos(address: string): Promise<BtcAssetsApiUtxo[]>;
getBalance(address: string, params?: BtcAssetsApiBalanceParams): Promise<BtcAssetsApiBalance>;
getUtxos(address: string, params?: BtcAssetsApiUtxoParams): Promise<BtcAssetsApiUtxo[]>;
getTransactions(address: string): Promise<BtcAssetsApiTransaction[]>;
getTransaction(txid: string): Promise<BtcAssetsApiTransaction>;
sendTransaction(txHex: string): Promise<BtcAssetsApiSentTransaction>;
Expand All @@ -183,6 +362,14 @@ interface BtcAssetsApiToken {
}
```

#### BtcAssetsApiBalanceParams

```typescript
interface BtcAssetsApiBalanceParams {
min_satoshi?: number;
}
```

#### BtcAssetsApiBalance

```typescript
Expand All @@ -194,6 +381,14 @@ interface BtcAssetsApiBalance {
}
```

#### BtcAssetsApiUtxoParams

```typescript
interface BtcAssetsApiUtxoParams {
min_satoshi?: number;
}
```

#### BtcAssetsApiUtxo

```typescript
Expand Down Expand Up @@ -262,10 +457,10 @@ interface BtcAssetsApiTransaction {

### Basic

#### UnspentOutput
#### Utxo

```typescript
interface UnspentOutput {
interface Utxo {
txid: string;
vout: number;
value: number;
Expand All @@ -284,8 +479,6 @@ enum AddressType {
P2WPKH,
P2TR,
P2SH_P2WPKH,
M44_P2WPKH, // deprecated
M44_P2TR, // deprecated
P2WSH,
P2SH,
UNKNOWN,
Expand Down
4 changes: 3 additions & 1 deletion packages/btc/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"name": "@rgbpp-sdk/btc",
"version": "0.1.0",
"scripts": {
"test": "vitest --watch=false",
"test": "vitest",
"build": "tsc -p tsconfig.build.json",
"lint": "prettier --check '{src,tests}/**/*.{js,jsx,ts,tsx}'",
"lint:fix": "prettier --write '{src,tests}/**/*.{js,jsx,ts,tsx}'",
Expand All @@ -17,6 +17,8 @@
],
"dependencies": {
"@bitcoinerlab/secp256k1": "^1.1.1",
"@ckb-lumos/lumos": "0.22.0-next.5",
"@rgbpp-sdk/ckb": "workspace:^",
"bip32": "^4.0.0",
"bitcoinjs-lib": "^6.1.5",
"ecpair": "^2.1.0",
Expand Down
Loading