Skip to content

Commit a93f14c

Browse files
authored
Merge pull request #265 from ckb-cell/release/0.5.0
Merge release/0.5.0 to main branch
2 parents b802eb1 + 2cf54a0 commit a93f14c

Some content is hidden

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

46 files changed

+1559
-1988
lines changed

.github/workflows/integration-test.yaml

+7-6
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ name: Integration Tests
44

55
on:
66
workflow_dispatch:
7+
pull_request:
78
# Run integration-tests every day
89
schedule:
910
- cron: '59 0 * * *'
@@ -48,9 +49,9 @@ jobs:
4849
if: ${{ matrix.env_set == 'xudt' }}
4950
run: pnpm run integration:xudt
5051
env:
51-
VITE_SERVICE_URL: https://api.signet.rgbpp.io
52-
VITE_SERVICE_TOKEN: ${{ secrets.SIGNET_SERVICE_TOKEN }}
53-
VITE_SERVICE_ORIGIN: https://api.signet.rgbpp.io
52+
VITE_SERVICE_URL: https://btc-assets-api.testnet.mibao.pro
53+
VITE_SERVICE_TOKEN: ${{ secrets.TESTNET_SERVICE_TOKEN }}
54+
VITE_SERVICE_ORIGIN: https://btc-assets-api.testnet.mibao.pro
5455
INTEGRATION_CKB_PRIVATE_KEY: ${{ secrets.INTEGRATION_CKB_PRIVATE_KEY }}
5556
INTEGRATION_BTC_PRIVATE_KEY: ${{ secrets.INTEGRATION_BTC_PRIVATE_KEY }}
5657

@@ -59,8 +60,8 @@ jobs:
5960
if: ${{ matrix.env_set == 'spore' }}
6061
run: pnpm run integration:spore
6162
env:
62-
VITE_SERVICE_URL: https://api.signet.rgbpp.io
63-
VITE_SERVICE_TOKEN: ${{ secrets.SIGNET_SERVICE_TOKEN }}
64-
VITE_SERVICE_ORIGIN: https://api.signet.rgbpp.io
63+
VITE_SERVICE_URL: https://btc-assets-api.testnet.mibao.pro
64+
VITE_SERVICE_TOKEN: ${{ secrets.TESTNET_SERVICE_TOKEN }}
65+
VITE_SERVICE_ORIGIN: https://btc-assets-api.testnet.mibao.pro
6566
INTEGRATION_CKB_PRIVATE_KEY: ${{ secrets.INTEGRATION_CKB_SPORE_PRIVATE_KEY }}
6667
INTEGRATION_BTC_PRIVATE_KEY: ${{ secrets.INTEGRATION_BTC_SPORE_PRIVATE_KEY }}

.github/workflows/release.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ jobs:
6666
with:
6767
script: |
6868
const packages = JSON.parse(process.env.PACKAGES)
69-
const packagesTable = packages.map((p) => `| ${p.name} | \`${p.version}\` |`)
69+
const packagesTable = packages.map((p) => `| ${p.name} | \`${p.version}\` |`).join('\n')
7070
const body = ['New official version of the rgbpp-sdk packages have been released:', '| Name | Version |', '| --- | --- |', packagesTable].join('\n')
7171
github.rest.repos.createCommitComment({
7272
commit_sha: context.sha,

.github/workflows/snapshot.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ jobs:
8181
with:
8282
script: |
8383
const packages = JSON.parse(process.env.PACKAGES)
84-
const packagesTable = packages.map((p) => `| ${p.name} | \`${p.version}\` |`)
84+
const packagesTable = packages.map((p) => `| ${p.name} | \`${p.version}\` |`).join('\n')
8585
const body = ['New snapshot version of the rgbpp-sdk packages have been released:', '| Name | Version |', '| --- | --- |', packagesTable].join('\n')
8686
github.rest.repos.createCommitComment({
8787
commit_sha: context.sha,

README.md

+11-6
Original file line numberDiff line numberDiff line change
@@ -8,17 +8,20 @@ This repository offers utilities for Bitcoin and RGB++ asset integration.
88
- [@rgbpp-sdk/ckb](./packages/ckb): Nervos CKB part of the SDK
99
- [@rgbpp-sdk/service](./packages/service): Wrapped interfaces of `Bitcoin/RGB++ Assets Service`
1010

11+
1112
## RGB++ Code Examples
1213

1314
- Find code examples at https://github.com/ckb-cell/rgbpp-sdk/tree/develop/examples/rgbpp
1415

16+
1517
## Related CKB Scripts (Contracts)
16-
- [CKB Bitcoin SPV Type Script](https://github.com/ckb-cell/ckb-bitcoin-spv-contracts/tree/master/contracts/ckb-bitcoin-spv-type-lock): A [type script](https://docs.nervos.org/docs/basics/glossary#type-script) for [Bitcoin SPV](https://bitcoinwiki.org/wiki/simplified-payment-verification) clients which synchronize [Bitcoin](https://bitcoin.org) state into [CKB](https://github.com/nervosnetwork/ckb)
18+
- [CKB Bitcoin SPV Type Script](https://github.com/ckb-cell/ckb-bitcoin-spv-contracts/tree/master/contracts/ckb-bitcoin-spv-type-lock): A [type script](https://docs-old.nervos.org/docs/basics/glossary#type-script) for [Bitcoin SPV](https://bitcoinwiki.org/wiki/simplified-payment-verification) clients which synchronize [Bitcoin](https://bitcoin.org) state into [CKB](https://github.com/nervosnetwork/ckb)
19+
20+
- **RGB++ scripts/contracts**: [RgbppLockScript](https://github.com/ckb-cell/rgbpp/tree/main/contracts/rgbpp-lock) and [BtcTimeLockScript](https://github.com/ckb-cell/rgbpp/tree/main/contracts/btc-time-lock)
21+
* design docs: https://github.com/ckb-cell/RGBPlusPlus-design/blob/main/docs/lockscript-design-prd-en.md
22+
* testnet deployment: https://pudge.explorer.nervos.org/scripts#RGB++
23+
* mainnet deployment: https://explorer.nervos.org/scripts#RGB++
1724

18-
- [RgbppLockScript and BtcTimeLockScript](https://github.com/ckb-cell/rgbpp-sdk/blob/63df2dcd95b1b735b5d235e156e4361a3c87b0ac/packages/ckb/src/constants/index.ts#L12-L206)
19-
* design: https://github.com/ckb-cell/RGBPlusPlus-design/blob/main/docs/light-paper-en.md
20-
* testnet: https://pudge.explorer.nervos.org/scripts#RGB++
21-
* mainnet: https://explorer.nervos.org/scripts#RGB++
2225

2326
## RGB++ Asset Workflow Overview
2427

@@ -50,9 +53,11 @@ This repository offers utilities for Bitcoin and RGB++ asset integration.
5053
2. continuously fetch request from the queue through a **cron job**
5154
3. check whether the **confirmations** of `req.rgbpp_btc_txid` is sufficient
5255
4. generate the **witnesses for RgbppLocks** in the `rgbpp_ckb_tx_virtual`
53-
5. add a **paymaster cell** into `rgbpp_ckb_tx_virtual`.inputs if the CKB capacity is insufficient
56+
5. add a **paymaster cell** into `rgbpp_ckb_tx_virtual` inputs if the CKB capacity is insufficient
5457
1. need to **verify the existence of paymaster UTXO** in the rgbpp_btc_tx
58+
> based on the exchange rates of BTC and CKB, [the paymaster BTC UTXO's value](https://api.rgbpp.io/docs/static/index.html#/RGB%2B%2B/get_rgbpp_v1_paymaster_info) required to subsidize a paymaster CKB cell is approximately: `paymaster_utxo_sats ~= 316 * ${ckb_price} / ${btc_price} * 100000000`
5559
2. sign the paymaster cell and the entire transaction if needed
60+
5661
6. **finalize** the `rgbpp_ckb_tx_virtual` to a `rgbpp_ckb_tx`
5762
7. **broadcast** `rgbpp_ckb_tx` and mark the job as completed upon tx-confirmation
5863

examples/rgbpp/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
"lint:fix": "tsc && eslint --fix --ext .js,.ts . && prettier --write '**/*.{js,ts}'"
1111
},
1212
"dependencies": {
13-
"@nervosnetwork/ckb-sdk-utils": "^0.109.1",
13+
"@nervosnetwork/ckb-sdk-utils": "0.109.1",
1414
"rgbpp": "workspace:*"
1515
},
1616
"devDependencies": {

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

+2
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,8 @@ const createCluster = async ({ ownerRgbppLockArgs }: { ownerRgbppLockArgs: strin
5454
const newCkbRawTx = updateCkbTxWithRealBtcTxId({ ckbRawTx, btcTxId, isMainnet });
5555

5656
console.log('The cluster rgbpp lock args: ', newCkbRawTx.outputs[0].lock.args);
57+
console.log('The cluster rgbpp lock args -- btc tx id: ', btcTxId);
58+
console.log('The cluster rgbpp lock args -- btc tx out index: 1');
5759

5860
const ckbTx = await appendCkbTxWitnesses({
5961
ckbRawTx: newCkbRawTx,

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

+2
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,8 @@ const createSpores = async ({ clusterRgbppLockArgs, receivers }: SporeCreatePara
7373
// Update CKB transaction with the real BTC txId
7474
const newCkbRawTx = updateCkbTxWithRealBtcTxId({ ckbRawTx, btcTxId, isMainnet });
7575
console.log('The new cluster rgbpp lock args: ', newCkbRawTx.outputs[0].lock.args);
76+
console.log('The new cluster rgbpp lock args -- btc tx id: ', btcTxId);
77+
console.log('The new cluster rgbpp lock args -- btc tx out index: 1');
7678

7779
const ckbTx = await appendCkbTxWitnesses({
7880
ckbRawTx: newCkbRawTx,

examples/rgbpp/xudt/3-btc-leap-ckb.ts

+4-3
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ const leapFromBtcToCKB = async ({ rgbppLockArgsList, toCkbAddress, xudtTypeArgs,
2626
toCkbAddress,
2727
isMainnet,
2828
btcTestnetType: BTC_TESTNET_TYPE,
29+
// btcConfirmationBlocks: 20, // default value is 6
2930
});
3031

3132
// Save ckbVirtualTxResult
@@ -74,9 +75,9 @@ const leapFromBtcToCKB = async ({ rgbppLockArgsList, toCkbAddress, xudtTypeArgs,
7475

7576
// rgbppLockArgs: outIndexU32 + btcTxId
7677
leapFromBtcToCKB({
77-
rgbppLockArgsList: [buildRgbppLockArgs(1, '6edd4b9327506fab09fb9a0f5e5f35136a6a94bd4c9dd79af04921618fa6c800')],
78-
toCkbAddress: 'ckt1qrfrwcdnvssswdwpn3s9v8fp87emat306ctjwsm3nmlkjg8qyza2cqgqq9kxr7vy7yknezj0vj0xptx6thk6pwyr0sxamv6q',
78+
rgbppLockArgsList: [buildRgbppLockArgs(1, '52148de63ddd4dcd8ba1d2e105d43c62adf6ccd7e7098c24616640cd5e485c03')],
79+
toCkbAddress: 'ckt1qzda0cr08m85hc8jlnfp3zer7xulejywt49kt2rr0vthywaa50xwsq0e4xk4rmg5jdkn8aams492a7jlg73ue0gc0ddfj',
7980
// Please use your own RGB++ xudt asset's xudtTypeArgs
80-
xudtTypeArgs: '0x1ba116c119d1cfd98a53e9d1a615cf2af2bb87d95515c9d217d367054cfc696b',
81+
xudtTypeArgs: '0x562e4e8a2f64a3e9c24beb4b7dd002d0ad3b842d0cc77924328e36ad114e3ebe',
8182
transferAmount: BigInt(800_0000_0000),
8283
});

examples/rgbpp/xudt/4-unlock-btc-time-cell.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -38,5 +38,5 @@ const unlockBtcTimeCell = async ({ btcTimeCellArgs }: { btcTimeCellArgs: string
3838
// The btcTimeCellArgs is from the outputs[0].lock.args(BTC Time lock args) of the 3-btc-leap-ckb.ts CKB transaction
3939
unlockBtcTimeCell({
4040
btcTimeCellArgs:
41-
'0x7f000000100000005b0000005f0000004b000000100000003000000031000000d23761b364210735c19c60561d213fb3beae2fd6172743719eff6920e020baac011600000000016c61f984f12d3c8a4f649e60acda5deda0b8837c06000000799a0f55202939e6801924c87c66df75932ecf79774370beebe31eaa94b6d8b8',
41+
'0x7d00000010000000590000005d000000490000001000000030000000310000009bd7e06f3ecf4be0f2fcd2188b23f1b9fcc88e5d4b65a8637b17723bbda3cce80114000000f9a9ad51ed14936d33f7bb854aaefa5f47a3ccbd880d0100ffc34d3d23f86df84a23a3b2cf72b45c8a309fec417ab196bee8e7a74483e05f',
4242
});

examples/xudt-on-ckb/2-transfer-xudt.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import {
1212
calculateTransactionFee,
1313
NoXudtLiveCellError,
1414
fetchTypeIdCellDeps,
15+
getXudtTypeScript,
1516
} from 'rgbpp/ckb';
1617
import { CKB_PRIVATE_KEY, ckbAddress, collector, isMainnet } from './env';
1718

@@ -139,8 +140,7 @@ const XUDT_TOKEN_INFO: RgbppTokenInfo = {
139140
transferXudt({
140141
// The xudtType comes from 1-issue-xudt
141142
xudtType: {
142-
codeHash: '0x25c29dc317811a6f6f3985a7a9ebc4838bd388d19d0feeecf0bcd60f6c0975bb',
143-
hashType: 'type',
143+
...getXudtTypeScript(isMainnet),
144144
args: '0x562e4e8a2f64a3e9c24beb4b7dd002d0ad3b842d0cc77924328e36ad114e3ebe',
145145
},
146146
receivers: [
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,151 @@
1+
import { addressToScript, getTransactionSize } from '@nervosnetwork/ckb-sdk-utils';
2+
import {
3+
getSecp256k1CellDep,
4+
NoLiveCellError,
5+
calculateUdtCellCapacity,
6+
MAX_FEE,
7+
MIN_CAPACITY,
8+
append0x,
9+
u128ToLe,
10+
SECP256K1_WITNESS_LOCK_SIZE,
11+
calculateTransactionFee,
12+
NoXudtLiveCellError,
13+
fetchTypeIdCellDeps,
14+
calculateRgbppCellCapacity,
15+
getBtcTimeLockScript,
16+
genBtcTimeLockArgs,
17+
getXudtTypeScript,
18+
} from 'rgbpp/ckb';
19+
import { CKB_PRIVATE_KEY, ckbAddress, collector, isMainnet } from './env';
20+
21+
interface BtcTimeCellParams {
22+
xudtType: CKBComponents.Script;
23+
toCkbAddress: string;
24+
xudtAmount: bigint;
25+
btcTxId: string;
26+
after: number;
27+
}
28+
29+
/**
30+
* Generate btc time cell with custom btc txid, after and target lock script
31+
* @param xudtType The xUDT type script that comes from 1-issue-xudt or 2-transfer-xudt
32+
* BTC time lock args:
33+
* table BTCTimeLock {
34+
to_lock_script: Script,
35+
after: Uint32,
36+
btc_txid: Byte32,
37+
}
38+
*/
39+
const generateBtcTimeCell = async ({ xudtType, toCkbAddress, xudtAmount, btcTxId, after }: BtcTimeCellParams) => {
40+
const fromLock = addressToScript(ckbAddress);
41+
42+
const xudtCells = await collector.getCells({
43+
lock: fromLock,
44+
type: xudtType,
45+
});
46+
if (!xudtCells || xudtCells.length === 0) {
47+
throw new NoXudtLiveCellError('The address has no xudt cells');
48+
}
49+
50+
const btcTimeOutputCapacity = calculateRgbppCellCapacity(xudtType);
51+
let sumXudtOutputCapacity = btcTimeOutputCapacity;
52+
53+
const {
54+
inputs: udtInputs,
55+
sumInputsCapacity: sumXudtInputsCapacity,
56+
sumAmount,
57+
} = collector.collectUdtInputs({
58+
liveCells: xudtCells,
59+
needAmount: xudtAmount,
60+
});
61+
let actualInputsCapacity = sumXudtInputsCapacity;
62+
let inputs = udtInputs;
63+
64+
const outputs: CKBComponents.CellOutput[] = [
65+
{
66+
lock: {
67+
...getBtcTimeLockScript(isMainnet),
68+
args: genBtcTimeLockArgs(addressToScript(toCkbAddress), btcTxId, after),
69+
},
70+
type: xudtType,
71+
capacity: append0x(btcTimeOutputCapacity.toString(16)),
72+
},
73+
];
74+
const outputsData = [append0x(u128ToLe(xudtAmount))];
75+
76+
if (sumAmount > xudtAmount) {
77+
const xudtChangeCapacity = calculateUdtCellCapacity(fromLock);
78+
outputs.push({
79+
lock: fromLock,
80+
type: xudtType,
81+
capacity: append0x(xudtChangeCapacity.toString(16)),
82+
});
83+
outputsData.push(append0x(u128ToLe(sumAmount - xudtAmount)));
84+
sumXudtOutputCapacity += xudtChangeCapacity;
85+
}
86+
87+
const txFee = MAX_FEE;
88+
if (sumXudtInputsCapacity <= sumXudtOutputCapacity) {
89+
let emptyCells = await collector.getCells({
90+
lock: fromLock,
91+
});
92+
if (!emptyCells || emptyCells.length === 0) {
93+
throw new NoLiveCellError('The address has no empty cells');
94+
}
95+
emptyCells = emptyCells.filter((cell) => !cell.output.type);
96+
const needCapacity = sumXudtOutputCapacity - sumXudtInputsCapacity;
97+
const { inputs: emptyInputs, sumInputsCapacity: sumEmptyCapacity } = collector.collectInputs(
98+
emptyCells,
99+
needCapacity,
100+
txFee,
101+
{ minCapacity: MIN_CAPACITY },
102+
);
103+
inputs = [...inputs, ...emptyInputs];
104+
actualInputsCapacity += sumEmptyCapacity;
105+
}
106+
107+
let changeCapacity = actualInputsCapacity - sumXudtOutputCapacity;
108+
outputs.push({
109+
lock: fromLock,
110+
capacity: append0x(changeCapacity.toString(16)),
111+
});
112+
outputsData.push('0x');
113+
114+
const emptyWitness = { lock: '', inputType: '', outputType: '' };
115+
const witnesses = inputs.map((_, index) => (index === 0 ? emptyWitness : '0x'));
116+
117+
const cellDeps = [getSecp256k1CellDep(isMainnet), ...(await fetchTypeIdCellDeps(isMainnet, { xudt: true }))];
118+
119+
const unsignedTx = {
120+
version: '0x0',
121+
cellDeps,
122+
headerDeps: [],
123+
inputs,
124+
outputs,
125+
outputsData,
126+
witnesses,
127+
};
128+
129+
if (txFee === MAX_FEE) {
130+
const txSize = getTransactionSize(unsignedTx) + SECP256K1_WITNESS_LOCK_SIZE;
131+
const estimatedTxFee = calculateTransactionFee(txSize);
132+
changeCapacity -= estimatedTxFee;
133+
unsignedTx.outputs[unsignedTx.outputs.length - 1].capacity = append0x(changeCapacity.toString(16));
134+
}
135+
136+
const signedTx = collector.getCkb().signTransaction(CKB_PRIVATE_KEY)(unsignedTx);
137+
const txHash = await collector.getCkb().rpc.sendTransaction(signedTx, 'passthrough');
138+
139+
console.info(`xUDT asset has been transferred to BTC time lock and CKB tx hash is ${txHash}`);
140+
};
141+
142+
generateBtcTimeCell({
143+
xudtType: {
144+
...getXudtTypeScript(isMainnet),
145+
args: '0x562e4e8a2f64a3e9c24beb4b7dd002d0ad3b842d0cc77924328e36ad114e3ebe',
146+
},
147+
toCkbAddress: 'ckt1qzda0cr08m85hc8jlnfp3zer7xulejywt49kt2rr0vthywaa50xwsq0e4xk4rmg5jdkn8aams492a7jlg73ue0gc0ddfj',
148+
xudtAmount: BigInt(1000) * BigInt(10 ** 8),
149+
btcTxId: '5fe08344a7e7e8be96b17a41ec9f308a5cb472cfb2a3234af86df8233d4dc3ff',
150+
after: 69000,
151+
});

examples/xudt-on-ckb/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
"lint:fix": "tsc && eslint --fix --ext .ts . && prettier --write '**/*.ts'"
1111
},
1212
"dependencies": {
13-
"@nervosnetwork/ckb-sdk-utils": "^0.109.1",
13+
"@nervosnetwork/ckb-sdk-utils": "0.109.1",
1414
"rgbpp": "^0.3.0"
1515
},
1616
"devDependencies": {

packages/btc/CHANGELOG.md

+16-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,21 @@
11
# @rgbpp-sdk/btc
22

3-
## 0.4.0
3+
## v0.5.0
4+
5+
### Minor Changes
6+
7+
- [#261](https://github.com/ckb-cell/rgbpp-sdk/pull/261): Batch fetch CKB RGB++ live cells to construct BTC transaction ([@duanyytop](https://github.com/duanyytop))
8+
9+
- Batch fetch CKB RGB++ live cells to construct BTC transaction
10+
- Remove useless fields for RGB++ lock args list
11+
12+
### Patch Changes
13+
14+
- Updated dependencies [[`9afc2a9`](https://github.com/ckb-cell/rgbpp-sdk/commit/9afc2a911e6a4ba8a200755b01159b5b149e4010), [`8f99429`](https://github.com/ckb-cell/rgbpp-sdk/commit/8f99429de45899e5169771e87e73603318a49ae8), [`475b3c3`](https://github.com/ckb-cell/rgbpp-sdk/commit/475b3c35ab1a25ba3aae28123f2820460101c889)]:
15+
- @rgbpp-sdk/service@0.5.0
16+
- @rgbpp-sdk/ckb@0.5.0
17+
18+
## v0.4.0
419

520
### Minor Changes
621

packages/btc/package.json

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@rgbpp-sdk/btc",
3-
"version": "0.4.0",
3+
"version": "0.5.0",
44
"scripts": {
55
"test": "vitest",
66
"build": "tsc -p tsconfig.build.json",
@@ -18,7 +18,7 @@
1818
"dependencies": {
1919
"@bitcoinerlab/secp256k1": "^1.1.1",
2020
"@ckb-lumos/codec": "0.22.2",
21-
"@nervosnetwork/ckb-types": "^0.109.1",
21+
"@nervosnetwork/ckb-types": "0.109.1",
2222
"@rgbpp-sdk/ckb": "workspace:^",
2323
"@rgbpp-sdk/service": "workspace:^",
2424
"bip32": "^4.0.0",

0 commit comments

Comments
 (0)