Skip to content

Commit 88050df

Browse files
authored
Merge pull request #217 from ckb-cell/release/0.3.0
Merge release/0.3.0 to main branch
2 parents 0948ef6 + 6a44c3b commit 88050df

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

58 files changed

+536
-210
lines changed

README.md

+2
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,8 @@ This repository offers utilities for Bitcoin and RGB++ asset integration.
6666
### How to get an access token of Bitcoin/RGB++ Assets Service?
6767
See [Generate a JSON Web Token (JWT) for Bitcoin/RGB++ Assets Service](./packages/service/README.md#get-an-access-token)
6868

69+
### Where is the error code description for the RgbppLockScript?
70+
See [RGB++ Lock Script Error Codes](https://github.com/nervosnetwork/ckb-script-error-codes/blob/main/by-type-hash/bc6c568a1a0d0a09f6844dc9d74ddb4343c32143ff25f727c59edf4fb72d6936.md)
6971

7072
## License
7173

examples/rgbpp/.env.example

+2
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ CKB_INDEXER_URL=https://testnet.ckb.dev/indexer
1616
# BTC Variables
1717

1818
# The BTC private key whose format is 32bytes hex string without 0x prefix
19+
# The Native Segwit P2WPKH address will be generated with the BTC private key
20+
# Read more about P2WPKH in BIP141: https://github.com/bitcoin/bips/blob/master/bip-0141.mediawiki#p2wpkh
1921
BTC_PRIVATE_KEY=private-key
2022

2123
# The BTC assets api url which should be matched with IS_MAINNET

examples/rgbpp/README.md

+45-1
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,18 @@
33
- xUDT directory: The examples for RGB++ UDT issuance, transfer, and leap
44
- Spore directory: The examples for RGB++ Spore creation, transfer and leap
55

6+
> [!TIP]
7+
> All the parameters of the examples should be repalced with your own, including BTC private key, CKB private key, BTC Service origin, BTC Service token, BTC UTXO, xUDT type args, Spore type args, etc. Please confirm whether the parameters are correct according to the code comments
8+
69
## How to Start
710

11+
### Install dependencies and build packages
12+
13+
```
14+
pnpm install && pnpm build:packages
15+
```
16+
### Update .env
17+
818
Copy the `.env.example` file to `.env`:
919

1020
```shell
@@ -31,6 +41,8 @@ CKB_INDEXER_URL=https://testnet.ckb.dev/indexer
3141
# BTC Variables
3242

3343
# The BTC private key whose format is 32bytes hex string without 0x prefix
44+
# The Native Segwit P2WPKH address will be generated with the BTC private key
45+
# Read more about P2WPKH in BIP141: https://github.com/bitcoin/bips/blob/master/bip-0141.mediawiki#p2wpkh
3446
BTC_PRIVATE_KEY=private-key
3547

3648
# The BTC assets api url which should be matched with IS_MAINNET
@@ -44,23 +56,36 @@ VITE_BTC_SERVICE_TOKEN=;
4456
VITE_BTC_SERVICE_ORIGIN=https://btc-test.app;
4557
```
4658

47-
4859
## RGB++ xUDT Examples
4960

5061
### RGB++ xUDT Launch on BTC
5162

5263
#### 1. Prepare Launch
5364

65+
> [!TIP]
66+
> Please make sure the CKB private key in the .env is correct
67+
5468
```shell
69+
# Create a CKB empty rgbpp lock cell to launch RGB++ xUDT assets later
5570
npx ts-node xudt/launch/1-prepare-launch.ts
5671
```
5772
#### 2. Launch RGB++ xUDT on BTC
5873

74+
> [!TIP]
75+
> Please make sure the `1-prepare-launch.ts` has been run and the corresponding CKB transaction has been committed
76+
5977
```shell
6078
npx ts-node xudt/launch/2-launch-rgbpp.ts
6179
```
80+
81+
When the command is executed successfully, the **RGB++ Asset type script args** will appear in the output log
82+
6283
#### 3. Distribute RGB++ xUDT on BTC
6384

85+
> [!TIP]
86+
> Please make sure the `2-launch-rgbpp.ts` has been run and the corresponding BTC and CKB transactions have been committed
87+
> The **RGB++ Asset type script args** in the above should be set to the `xudtTypeArgs`
88+
6489
```shell
6590
npx ts-node xudt/launch/3-distribute-rgbpp.ts
6691
```
@@ -103,14 +128,26 @@ npx ts-node xudt/4-unlock-btc-time.ts
103128

104129
#### 1. Create RGB++ Cluster Cell
105130

131+
> [!TIP]
132+
> Please make sure all the variables in the .env are correct
133+
> The BTC UTXO of `1-prepare-cluster.ts` and `2-create-cluster.ts` should be same
134+
106135
```shell
136+
# Create a CKB empty rgbpp lock cell to create cluster later
107137
npx ts-node spore/launch/1-prepare-cluster.ts
108138

139+
# Create a cluster cell with rgbpp lock
109140
npx ts-node spore/launch/2-create-cluster.ts
110141
```
111142

143+
When the commands are executed successfully, the **clusterId** and **cluster rgbpp lock args** will appear in the output log
144+
112145
#### 2. Create RGB++ Spores with Cluster on BTC
113146

147+
> [!TIP]
148+
> Please make sure the `2-create-cluster.ts` has been run and the corresponding BTC and CKB transactions have been committed
149+
> The **clusterId** in the above should be set to the `clusterId` and the **cluster rgbpp lock args** should be set to the `clusterRgbppLockArgs`
150+
114151
```shell
115152
npx ts-node spore/launch/3-create-spores.ts
116153
```
@@ -147,6 +184,13 @@ npx ts-node spore/6-unlock-btc-time-cell.ts
147184
npx ts-node spore/7-leap-spore-to-btc.ts
148185
```
149186

187+
## FAQ
188+
189+
If you have any questions, please refer to the FAQ first.
190+
191+
See [RGBPP FAQ](https://github.com/ckb-cell/rgbpp-sdk/wiki/RGBPP--FAQ)
192+
193+
150194
## What you must know about BTC transaction id
151195

152196
**The BTC transaction id(hash) displayed on BTC explorer is different from the BTC transaction id(hash) in RGB++ lock args. They are in reverse byte order.**

examples/rgbpp/env.ts

+14-4
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,10 @@
1-
import { AddressPrefix, privateKeyToAddress } from '@nervosnetwork/ckb-sdk-utils';
1+
import {
2+
blake160,
3+
bytesToHex,
4+
privateKeyToPublicKey,
5+
scriptToAddress,
6+
systemScripts,
7+
} from '@nervosnetwork/ckb-sdk-utils';
28
import { DataSource, BtcAssetsApi } from 'rgbpp';
39
import { ECPair, ECPairInterface, bitcoin, NetworkType } from 'rgbpp/btc';
410
import dotenv from 'dotenv';
@@ -13,9 +19,11 @@ export const collector = new Collector({
1319
ckbIndexerUrl: process.env.CKB_INDEXER_URL!,
1420
});
1521
export const CKB_PRIVATE_KEY = process.env.CKB_SECP256K1_PRIVATE_KEY!;
16-
export const ckbAddress = privateKeyToAddress(CKB_PRIVATE_KEY, {
17-
prefix: isMainnet ? AddressPrefix.Mainnet : AddressPrefix.Testnet,
18-
});
22+
const secp256k1Lock: CKBComponents.Script = {
23+
...systemScripts.SECP256K1_BLAKE160,
24+
args: bytesToHex(blake160(privateKeyToPublicKey(CKB_PRIVATE_KEY))),
25+
};
26+
export const ckbAddress = scriptToAddress(secp256k1Lock, isMainnet);
1927

2028
export const BTC_PRIVATE_KEY = process.env.BTC_PRIVATE_KEY!;
2129
export const BTC_SERVICE_URL = process.env.VITE_BTC_SERVICE_URL!;
@@ -24,6 +32,8 @@ export const BTC_SERVICE_ORIGIN = process.env.VITE_BTC_SERVICE_ORIGIN!;
2432

2533
const network = isMainnet ? bitcoin.networks.bitcoin : bitcoin.networks.testnet;
2634
export const btcKeyPair: ECPairInterface = ECPair.fromPrivateKey(Buffer.from(BTC_PRIVATE_KEY, 'hex'), { network });
35+
// The Native Segwit P2WPKH address will be generated with the BTC private key
36+
// Read more about P2WPKH in BIP141: https://github.com/bitcoin/bips/blob/master/bip-0141.mediawiki#p2wpkh
2737
export const { address: btcAddress } = bitcoin.payments.p2wpkh({
2838
pubkey: btcKeyPair.publicKey,
2939
network,

examples/rgbpp/shared/utils.ts

+2
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import {
55
SporeVirtualTxResult,
66
SporeCreateVirtualTxResult,
77
SporeTransferVirtualTxResult,
8+
RgbppLaunchVirtualTxResult,
89
} from 'rgbpp/ckb';
910

1011
/**
@@ -15,6 +16,7 @@ import {
1516

1617
export type CkbVirtualTxResultType =
1718
| BaseCkbVirtualTxResult
19+
| RgbppLaunchVirtualTxResult
1820
| SporeVirtualTxResult
1921
| SporeCreateVirtualTxResult
2022
| SporeTransferVirtualTxResult;

examples/rgbpp/spore/4-transfer-spore.ts

+4-2
Original file line numberDiff line numberDiff line change
@@ -27,13 +27,14 @@ const transferSpore = async ({ sporeRgbppLockArgs, toBtcAddress, sporeTypeArgs }
2727
// Save ckbVirtualTxResult
2828
saveCkbVirtualTxResult(ckbVirtualTxResult, '4-transfer-spore');
2929

30-
const { commitment, ckbRawTx } = ckbVirtualTxResult;
30+
const { commitment, ckbRawTx, needPaymasterCell } = ckbVirtualTxResult;
3131

3232
// Send BTC tx
3333
const psbt = await sendRgbppUtxos({
3434
ckbVirtualTx: ckbRawTx,
3535
commitment,
3636
tos: [toBtcAddress],
37+
needPaymaster: needPaymasterCell,
3738
ckbCollector: collector,
3839
from: btcAddress!,
3940
source: btcDataSource,
@@ -68,10 +69,11 @@ const transferSpore = async ({ sporeRgbppLockArgs, toBtcAddress, sporeTypeArgs }
6869
}
6970
};
7071

71-
// Use your real BTC UTXO information on the BTC Testnet
72+
// Please use your real BTC UTXO information on the BTC Testnet
7273
// rgbppLockArgs: outIndexU32 + btcTxId
7374
transferSpore({
7475
sporeRgbppLockArgs: buildRgbppLockArgs(2, 'd5868dbde4be5e49876b496449df10150c356843afb6f94b08f8d81f394bb350'),
7576
toBtcAddress: 'tb1qhp9fh9qsfeyh0yhewgu27ndqhs5qlrqwau28m7',
77+
// Please use your own RGB++ spore asset's sporeTypeArgs
7678
sporeTypeArgs: '0x42898ea77062256f46e8f1b861d526ae47810ecc51ab50477945d5fa90452706',
7779
});

examples/rgbpp/spore/5-leap-spore-to-ckb.ts

+4-2
Original file line numberDiff line numberDiff line change
@@ -28,13 +28,14 @@ const leapSporeFromBtcToCkb = async ({ sporeRgbppLockArgs, toCkbAddress, sporeTy
2828
// Save ckbVirtualTxResult
2929
saveCkbVirtualTxResult(ckbVirtualTxResult, '5-leap-spore-to-ckb');
3030

31-
const { commitment, ckbRawTx } = ckbVirtualTxResult;
31+
const { commitment, ckbRawTx, needPaymasterCell } = ckbVirtualTxResult;
3232

3333
// Send BTC tx
3434
const psbt = await sendRgbppUtxos({
3535
ckbVirtualTx: ckbRawTx,
3636
commitment,
3737
tos: [btcAddress!],
38+
needPaymaster: needPaymasterCell,
3839
ckbCollector: collector,
3940
from: btcAddress!,
4041
source: btcDataSource,
@@ -69,10 +70,11 @@ const leapSporeFromBtcToCkb = async ({ sporeRgbppLockArgs, toCkbAddress, sporeTy
6970
}
7071
};
7172

72-
// Use your real BTC UTXO information on the BTC Testnet
73+
// Please use your real BTC UTXO information on the BTC Testnet
7374
// rgbppLockArgs: outIndexU32 + btcTxId
7475
leapSporeFromBtcToCkb({
7576
sporeRgbppLockArgs: buildRgbppLockArgs(3, 'd8a31796fbd42c546f6b22014b9b82b16586ce1df81b0e7ca9a552cdc492a0af'),
7677
toCkbAddress: 'ckt1qzda0cr08m85hc8jlnfp3zer7xulejywt49kt2rr0vthywaa50xwsq0e4xk4rmg5jdkn8aams492a7jlg73ue0gc0ddfj',
78+
// Please use your own RGB++ spore asset's sporeTypeArgs
7779
sporeTypeArgs: '0x42898ea77062256f46e8f1b861d526ae47810ecc51ab50477945d5fa90452706',
7880
});

examples/rgbpp/spore/7-leap-spore-to-btc.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -40,9 +40,10 @@ const leapSporeFromCkbToBtc = async ({
4040
console.info(`RGB++ Spore has been jumped from CKB to BTC and tx hash is ${txHash}`);
4141
};
4242

43-
// Use your real BTC UTXO information on the BTC Testnet
43+
// Please use your real BTC UTXO information on the BTC Testnet
4444
leapSporeFromCkbToBtc({
4545
outIndex: 1,
4646
btcTxId: '448897515cf07b4ca0cd38af9806399ede55775b4c760b274ed2322121ed185f',
47+
// Please use your own RGB++ spore asset's sporeTypeArgs
4748
sporeTypeArgs: '0x42898ea77062256f46e8f1b861d526ae47810ecc51ab50477945d5fa90452706',
4849
});

examples/rgbpp/spore/launch/1-prepare-cluster.ts

+1
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ const prepareClusterCell = async ({ outIndex, btcTxId }: { outIndex: number; btc
7070
console.info(`Cluster cell has been prepared and the tx hash ${txHash}`);
7171
};
7272

73+
// Please use your real BTC UTXO information on the BTC Testnet
7374
prepareClusterCell({
7475
outIndex: 3,
7576
btcTxId: 'aee4e8e3aa95e9e9ab1f0520714031d92d3263262099dcc7f7d64e62fa2fcb44',

examples/rgbpp/spore/launch/2-create-cluster.ts

+4-2
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import {
1111
} from 'rgbpp/ckb';
1212
import { saveCkbVirtualTxResult } from '../../shared/utils';
1313

14+
// Warning: Before runing this file, please run 1-prepare-cluster.ts
1415
const createCluster = async ({ ownerRgbppLockArgs }: { ownerRgbppLockArgs: string }) => {
1516
const ckbVirtualTxResult = await genCreateClusterCkbVirtualTx({
1617
collector,
@@ -23,7 +24,7 @@ const createCluster = async ({ ownerRgbppLockArgs }: { ownerRgbppLockArgs: strin
2324
// Save ckbVirtualTxResult
2425
saveCkbVirtualTxResult(ckbVirtualTxResult, '2-create-cluster');
2526

26-
const { commitment, ckbRawTx, clusterId } = ckbVirtualTxResult;
27+
const { commitment, ckbRawTx, clusterId, needPaymasterCell } = ckbVirtualTxResult;
2728

2829
console.log('clusterId: ', clusterId);
2930

@@ -32,6 +33,7 @@ const createCluster = async ({ ownerRgbppLockArgs }: { ownerRgbppLockArgs: strin
3233
ckbVirtualTx: ckbRawTx,
3334
commitment,
3435
tos: [btcAddress!],
36+
needPaymaster: needPaymasterCell,
3537
ckbCollector: collector,
3638
from: btcAddress!,
3739
source: btcDataSource,
@@ -79,7 +81,7 @@ const createCluster = async ({ ownerRgbppLockArgs }: { ownerRgbppLockArgs: strin
7981
}, 30 * 1000);
8082
};
8183

82-
// Use your real BTC UTXO information on the BTC Testnet
84+
// Please use your real BTC UTXO information on the BTC Testnet which should be same as the 1-prepare-cluster.ts
8385
// rgbppLockArgs: outIndexU32 + btcTxId
8486
createCluster({
8587
ownerRgbppLockArgs: buildRgbppLockArgs(3, 'aee4e8e3aa95e9e9ab1f0520714031d92d3263262099dcc7f7d64e62fa2fcb44'),

examples/rgbpp/spore/launch/3-create-spores.ts

+4-2
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ interface SporeCreateParams {
3030
}[];
3131
}
3232

33+
// Warning: Before runing this file for the first time, please run 2-prepare-cluster.ts
3334
const createSpores = async ({ clusterRgbppLockArgs, receivers }: SporeCreateParams) => {
3435
const ckbVirtualTxResult = await genCreateSporeCkbVirtualTx({
3536
collector,
@@ -42,7 +43,7 @@ const createSpores = async ({ clusterRgbppLockArgs, receivers }: SporeCreatePara
4243
// Save ckbVirtualTxResult
4344
saveCkbVirtualTxResult(ckbVirtualTxResult, '3-create-spores');
4445

45-
const { commitment, ckbRawTx, sumInputsCapacity, clusterCell } = ckbVirtualTxResult;
46+
const { commitment, ckbRawTx, sumInputsCapacity, clusterCell, needPaymasterCell } = ckbVirtualTxResult;
4647

4748
// Send BTC tx
4849
// The first btc address is the owner of the cluster cell and the rest btc addresses are spore receivers
@@ -51,6 +52,7 @@ const createSpores = async ({ clusterRgbppLockArgs, receivers }: SporeCreatePara
5152
ckbVirtualTx: ckbRawTx,
5253
commitment,
5354
tos: btcTos,
55+
needPaymaster: needPaymasterCell,
5456
ckbCollector: collector,
5557
from: btcAddress!,
5658
source: btcDataSource,
@@ -114,7 +116,7 @@ const createSpores = async ({ clusterRgbppLockArgs, receivers }: SporeCreatePara
114116
}, 30 * 1000);
115117
};
116118

117-
// Use your real BTC UTXO information on the BTC Testnet
119+
// Please use your real BTC UTXO information on the BTC Testnet
118120
// rgbppLockArgs: outIndexU32 + btcTxId
119121
createSpores({
120122
// The cluster cell will be spent and the new cluster cell will be created in each spore creation tx,

examples/rgbpp/spore/local/4-transfer-spore.ts

+4-2
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ const transferSpore = async ({ sporeRgbppLockArgs, toBtcAddress, sporeTypeArgs }
3939
// Save ckbVirtualTxResult
4040
saveCkbVirtualTxResult(ckbVirtualTxResult, '4-transfer-spore-local');
4141

42-
const { commitment, ckbRawTx, sporeCell } = ckbVirtualTxResult;
42+
const { commitment, ckbRawTx, sporeCell, needPaymasterCell } = ckbVirtualTxResult;
4343

4444
// console.log(JSON.stringify(ckbRawTx))
4545

@@ -48,6 +48,7 @@ const transferSpore = async ({ sporeRgbppLockArgs, toBtcAddress, sporeTypeArgs }
4848
ckbVirtualTx: ckbRawTx,
4949
commitment,
5050
tos: [toBtcAddress],
51+
needPaymaster: needPaymasterCell,
5152
ckbCollector: collector,
5253
from: btcAddress!,
5354
source: btcDataSource,
@@ -91,11 +92,12 @@ const transferSpore = async ({ sporeRgbppLockArgs, toBtcAddress, sporeTypeArgs }
9192
}, 30 * 1000);
9293
};
9394

94-
// Use your real BTC UTXO information on the BTC Testnet
95+
// Please use your real BTC UTXO information on the BTC Testnet
9596
// rgbppLockArgs: outIndexU32 + btcTxId
9697
transferSpore({
9798
// The spore rgbpp lock args is from 3-create-spore.ts
9899
sporeRgbppLockArgs: buildRgbppLockArgs(1, 'f203c8c13eacdbd126f85d286a963c85f233f8145363b1d997c4d552afb990e1'),
99100
toBtcAddress: 'tb1qhp9fh9qsfeyh0yhewgu27ndqhs5qlrqwau28m7',
101+
// Please use your own RGB++ spore asset's sporeTypeArgs
100102
sporeTypeArgs: '0x42898ea77062256f46e8f1b861d526ae47810ecc51ab50477945d5fa90452706',
101103
});

examples/rgbpp/spore/local/5-leap-spore-to-ckb.ts

+4-2
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ const leapSpore = async ({ sporeRgbppLockArgs, toCkbAddress, sporeTypeArgs }: Sp
3939
// Save ckbVirtualTxResult
4040
saveCkbVirtualTxResult(ckbVirtualTxResult, '5-leap-spore-to-ckb-local');
4141

42-
const { commitment, ckbRawTx, sporeCell } = ckbVirtualTxResult;
42+
const { commitment, ckbRawTx, sporeCell, needPaymasterCell } = ckbVirtualTxResult;
4343

4444
// console.log(JSON.stringify(ckbRawTx))
4545

@@ -48,6 +48,7 @@ const leapSpore = async ({ sporeRgbppLockArgs, toCkbAddress, sporeTypeArgs }: Sp
4848
ckbVirtualTx: ckbRawTx,
4949
commitment,
5050
tos: [btcAddress!],
51+
needPaymaster: needPaymasterCell,
5152
ckbCollector: collector,
5253
from: btcAddress!,
5354
source: btcDataSource,
@@ -91,11 +92,12 @@ const leapSpore = async ({ sporeRgbppLockArgs, toCkbAddress, sporeTypeArgs }: Sp
9192
}, 30 * 1000);
9293
};
9394

94-
// Use your real BTC UTXO information on the BTC Testnet
95+
// Please use your real BTC UTXO information on the BTC Testnet
9596
// rgbppLockArgs: outIndexU32 + btcTxId
9697
leapSpore({
9798
// The spore rgbpp lock args is from 3-create-spore.ts
9899
sporeRgbppLockArgs: buildRgbppLockArgs(3, 'd8a31796fbd42c546f6b22014b9b82b16586ce1df81b0e7ca9a552cdc492a0af'),
99100
toCkbAddress: 'ckt1qzda0cr08m85hc8jlnfp3zer7xulejywt49kt2rr0vthywaa50xwsq0e4xk4rmg5jdkn8aams492a7jlg73ue0gc0ddfj',
101+
// Please use your own RGB++ spore asset's sporeTypeArgs
100102
sporeTypeArgs: '0x42898ea77062256f46e8f1b861d526ae47810ecc51ab50477945d5fa90452706',
101103
});

examples/rgbpp/tsconfig.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,6 @@
2121
"skipLibCheck": true,
2222
"strict": true
2323
},
24-
"include": ["queue/**/*.ts", "xudt/**/*.ts"],
24+
"include": ["spore", "xudt", "shared"],
2525
"exclude": ["node_modules"]
2626
}

0 commit comments

Comments
 (0)