From 6343044f51cfc6695cc819ef782c35d8c5de24cd Mon Sep 17 00:00:00 2001 From: Dawn <77844990+Dawn-githup@users.noreply.github.com> Date: Wed, 5 Jun 2024 12:02:02 +0800 Subject: [PATCH 01/90] chore(examples): update rgbpp-sdk to v0.3.0 (#220) * chore(examples): update rgbpp-sdk to v0.3.0 * chore: update pnpm-lock.yaml --- examples/rgbpp/package.json | 2 +- examples/xudt-on-ckb/package.json | 2 +- pnpm-lock.yaml | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/examples/rgbpp/package.json b/examples/rgbpp/package.json index 9131267f..7d44e4f8 100644 --- a/examples/rgbpp/package.json +++ b/examples/rgbpp/package.json @@ -11,7 +11,7 @@ }, "dependencies": { "@nervosnetwork/ckb-sdk-utils": "^0.109.1", - "rgbpp": "workspace:*" + "rgbpp": "^0.3.0" }, "devDependencies": { "@types/node": "^20.11.28", diff --git a/examples/xudt-on-ckb/package.json b/examples/xudt-on-ckb/package.json index 792a1a7d..98f545f6 100644 --- a/examples/xudt-on-ckb/package.json +++ b/examples/xudt-on-ckb/package.json @@ -11,7 +11,7 @@ }, "dependencies": { "@nervosnetwork/ckb-sdk-utils": "^0.109.1", - "rgbpp": "workspace:*" + "rgbpp": "^0.3.0" }, "devDependencies": { "dotenv": "^16.4.5", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index ecf567c3..094056db 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -143,7 +143,7 @@ importers: specifier: ^0.109.1 version: 0.109.1 rgbpp: - specifier: workspace:* + specifier: ^0.3.0 version: link:../../packages/rgbpp devDependencies: '@types/dotenv': @@ -165,7 +165,7 @@ importers: specifier: ^0.109.1 version: 0.109.1 rgbpp: - specifier: workspace:* + specifier: ^0.3.0 version: link:../../packages/rgbpp devDependencies: '@types/dotenv': From a7cda739b2a441b3c73b0e21e8e66e9ba50f0105 Mon Sep 17 00:00:00 2001 From: Shook <44739165+ShookLyngs@users.noreply.github.com> Date: Wed, 5 Jun 2024 12:05:25 +0800 Subject: [PATCH 02/90] chore: update comment style and remove the "--no-git-tag" option with publishing snapshot versions (#219) chore: update comment style and remove no-git-tag option in the snapshot.yaml --- .github/workflows/release.yml | 19 ++++++++++++++++++- .github/workflows/snapshot.yml | 29 ++++++++++++++++++----------- .github/workflows/test.yaml | 2 +- 3 files changed, 37 insertions(+), 13 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 4a8dfe93..2d89e09f 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -48,8 +48,8 @@ jobs: run: pnpm i - name: Create bump PR or release version - id: changesets uses: changesets/action@v1 + id: changesets with: publish: pnpm run release:packages title: "bump: assumable rgbpp-sdk version" @@ -57,3 +57,20 @@ jobs: env: NPM_TOKEN: ${{ secrets.NPM_TOKEN }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - name: Create comment on commit + uses: actions/github-script@v7 + if: steps.changesets.outputs.published + env: + PACKAGES: ${{ steps.changesets.outputs.publishedPackages }} + with: + script: | + const packages = JSON.parse(process.env.PACKAGES) + const packagesTable = packages.map((p) => `| ${p.name} | \`${p.version}\` |`) + const body = ['New official version of the rgbpp-sdk packages have been released:', '| Name | Version |', '| --- | --- |', packagesTable].join('\n') + github.rest.repos.createCommitComment({ + commit_sha: context.sha, + owner: context.repo.owner, + repo: context.repo.repo, + body: body, + }); diff --git a/.github/workflows/snapshot.yml b/.github/workflows/snapshot.yml index 948394c8..71620ac0 100644 --- a/.github/workflows/snapshot.yml +++ b/.github/workflows/snapshot.yml @@ -63,22 +63,29 @@ jobs: env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - - name: Publish to npm - id: changesets + - name: Publish snapshot versions to npm uses: changesets/action@v1 + id: changesets with: - publish: npx changeset publish --no-git-tag --snapshot --tag snap + publish: npx changeset publish --snapshot --tag snap createGithubReleases: false env: NPM_TOKEN: ${{ secrets.NPM_TOKEN }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - - name: Create commit comment - uses: peter-evans/commit-comment@v3 - if: ${{ steps.changesets.outputs.published == 'true' }} + - name: Create comment on commit + uses: actions/github-script@v7 + if: steps.changesets.outputs.published + env: + PACKAGES: ${{ steps.changesets.outputs.publishedPackages }} with: - token: ${{ secrets.GITHUB_TOKEN }} - body: | - ```json - ${{ steps.changesets.outputs.publishedPackages }} - ``` + script: | + const packages = JSON.parse(process.env.PACKAGES) + const packagesTable = packages.map((p) => `| ${p.name} | \`${p.version}\` |`) + const body = ['New snapshot version of the rgbpp-sdk packages have been released:', '| Name | Version |', '| --- | --- |', packagesTable].join('\n') + github.rest.repos.createCommitComment({ + commit_sha: context.sha, + owner: context.repo.owner, + repo: context.repo.repo, + body: body, + }); diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index 1fb20fed..07d120a6 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -1,6 +1,6 @@ # Test the functionality of the rgbpp-sdk packages. -name: Test +name: Unit Tests on: workflow_dispatch: From fec2b4b4626419a9cdd164672de7591fe5c958dc Mon Sep 17 00:00:00 2001 From: Flouse <1297478+Flouse@users.noreply.github.com> Date: Wed, 5 Jun 2024 12:14:24 +0800 Subject: [PATCH 03/90] chore(CI): Run integration-tests every day --- .github/workflows/integration-test.yaml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/integration-test.yaml b/.github/workflows/integration-test.yaml index e70dfaad..85b55c8b 100644 --- a/.github/workflows/integration-test.yaml +++ b/.github/workflows/integration-test.yaml @@ -5,6 +5,9 @@ name: Integration Tests on: workflow_dispatch: pull_request: + # Run integration-tests every day + schedule: + - cron: '59 0 * * *' concurrency: group: ${{ github.workflow }}-${{ github.ref }} From 4cd077b884bc43672a00512006c7960145c65fe6 Mon Sep 17 00:00:00 2001 From: Flouse <1297478+Flouse@users.noreply.github.com> Date: Wed, 5 Jun 2024 12:23:42 +0800 Subject: [PATCH 04/90] chore: only one integration-tests runs at any given time since only one group of keys is been using --- .github/workflows/integration-test.yaml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/integration-test.yaml b/.github/workflows/integration-test.yaml index 85b55c8b..1f40b504 100644 --- a/.github/workflows/integration-test.yaml +++ b/.github/workflows/integration-test.yaml @@ -9,8 +9,10 @@ on: schedule: - cron: '59 0 * * *' +# https://docs.github.com/en/actions/using-jobs/using-concurrency concurrency: - group: ${{ github.workflow }}-${{ github.ref }} + group: ${{ github.workflow }} + cancel-in-progress: false jobs: test: From e5f41fd2b275182d2ab3fdf17e3b8853025fd2b9 Mon Sep 17 00:00:00 2001 From: Shook Date: Wed, 5 Jun 2024 17:20:58 +0800 Subject: [PATCH 05/90] feat: add BtcAssetsApi.getRgbppApiBalanceByAddress() API for querying RGBPP XUDT balances --- .changeset/silly-rules-collect.md | 5 +++++ packages/service/src/service/service.ts | 8 ++++++++ packages/service/src/types/rgbpp.ts | 19 +++++++++++++++++++ packages/service/tests/Service.test.ts | 18 +++++++++++++----- 4 files changed, 45 insertions(+), 5 deletions(-) create mode 100644 .changeset/silly-rules-collect.md diff --git a/.changeset/silly-rules-collect.md b/.changeset/silly-rules-collect.md new file mode 100644 index 00000000..fba24d0d --- /dev/null +++ b/.changeset/silly-rules-collect.md @@ -0,0 +1,5 @@ +--- +"@rgbpp-sdk/service": minor +--- + +Add BtcAssetsApi.getRgbppApiBalanceByAddress() API for querying RGBPP XUDT balances by a BTC address diff --git a/packages/service/src/service/service.ts b/packages/service/src/service/service.ts index 9783054f..62045bd4 100644 --- a/packages/service/src/service/service.ts +++ b/packages/service/src/service/service.ts @@ -24,6 +24,8 @@ import { RgbppApiSendCkbTransactionPayload, RgbppApiCkbTransactionHash, RgbppApiAssetsByAddressParams, + RgbppApiBalanceByAddressParams, + RgbppApiBalance, RgbppApiRetryCkbTransactionPayload, RgbppApiTransactionStateParams, RgbppApiTransactionRetry, @@ -128,6 +130,12 @@ export class BtcAssetsApi extends BtcAssetsApiBase implements BtcApis, RgbppApis }); } + getRgbppBalanceByBtcAddress(btcAddress: string, params?: RgbppApiBalanceByAddressParams) { + return this.request(`/rgbpp/v1/address/${btcAddress}/balance`, { + params, + }); + } + getRgbppSpvProof(btcTxId: string, confirmations: number) { return this.request('/rgbpp/v1/btc-spv/proof', { params: { diff --git a/packages/service/src/types/rgbpp.ts b/packages/service/src/types/rgbpp.ts index 3f42bb5a..a7d7d584 100644 --- a/packages/service/src/types/rgbpp.ts +++ b/packages/service/src/types/rgbpp.ts @@ -7,6 +7,7 @@ export interface RgbppApis { getRgbppAssetsByBtcTxId(btcTxId: string): Promise; getRgbppAssetsByBtcUtxo(btcTxId: string, vout: number): Promise; getRgbppAssetsByBtcAddress(btcAddress: string, params?: RgbppApiAssetsByAddressParams): Promise; + getRgbppBalanceByBtcAddress(btcAddress: string, params?: RgbppApiBalanceByAddressParams): Promise; getRgbppSpvProof(btcTxId: string, confirmations: number): Promise; sendRgbppCkbTransaction(payload: RgbppApiSendCkbTransactionPayload): Promise; retryRgbppCkbTransaction(payload: RgbppApiRetryCkbTransactionPayload): Promise; @@ -47,6 +48,24 @@ export interface RgbppApiAssetsByAddressParams { no_cache?: boolean; } +export interface RgbppApiBalanceByAddressParams { + type_script?: string; + no_cache?: boolean; +} +export interface RgbppApiBalance { + address: string; + xudt: RgbppApiXudtBalance[]; +} +export interface RgbppApiXudtBalance { + name: string; + decimal: number; + symbol: string; + total_amount: string; + available_amount: string; + pending_amount: string; + type_hash: string; +} + export interface RgbppApiSpvProof { proof: string; spv_client: { diff --git a/packages/service/tests/Service.test.ts b/packages/service/tests/Service.test.ts index a8fa09aa..e01a1ebd 100644 --- a/packages/service/tests/Service.test.ts +++ b/packages/service/tests/Service.test.ts @@ -261,12 +261,20 @@ describe( expectCell(cell); } }); - it('getRgbppAssetsByBtcAddress() with no_cache', async () => { - const res = await service.getRgbppAssetsByBtcAddress(rgbppBtcAddress, { - no_cache: true, - }); + it('getRgbppBalanceByBtcAddress()', async () => { + const res = await service.getRgbppBalanceByBtcAddress(rgbppBtcAddress); expect(res).toBeDefined(); - expect(res.length).toBeGreaterThan(0); + expect(res.address).toBeTypeOf('string'); + expect(res.xudt.length).toBeGreaterThan(0); + for (const xudt of res.xudt) { + expect(xudt.name).toBeTypeOf('string'); + expect(xudt.decimal).toBeTypeOf('number'); + expect(xudt.symbol).toBeTypeOf('string'); + expect(xudt.total_amount).toBeTypeOf('string'); + expect(xudt.available_amount).toBeTypeOf('string'); + expect(xudt.pending_amount).toBeTypeOf('string'); + expect(xudt.type_hash).toBeTypeOf('string'); + } }); it('getRgbppSpvProof()', async () => { const res = await service.getRgbppSpvProof(rgbppBtcTxId, 6); From cfdc857aa95c1d4a2b7fd0433a03f25e5226f5f0 Mon Sep 17 00:00:00 2001 From: Shook Date: Thu, 30 May 2024 18:48:17 +0800 Subject: [PATCH 06/90] feat: add BtcAccount in examples/rgbpp to support both P2WPKH and P2TR address types --- examples/rgbpp/.env.example | 3 + examples/rgbpp/README.md | 9 +- examples/rgbpp/env.ts | 36 ++++--- examples/rgbpp/shared/btc-account.ts | 100 ++++++++++++++++++ examples/rgbpp/spore/4-transfer-spore.ts | 12 +-- examples/rgbpp/spore/5-leap-spore-to-ckb.ts | 14 ++- .../rgbpp/spore/launch/2-create-cluster.ts | 16 ++- .../rgbpp/spore/launch/3-create-spores.ts | 26 ++--- .../rgbpp/spore/local/4-transfer-spore.ts | 15 ++- .../rgbpp/spore/local/5-leap-spore-to-ckb.ts | 17 ++- examples/rgbpp/xudt/2-btc-transfer.ts | 12 +-- examples/rgbpp/xudt/3-btc-leap-ckb.ts | 14 ++- examples/rgbpp/xudt/launch/2-launch-rgbpp.ts | 16 ++- .../rgbpp/xudt/launch/3-distribute-rgbpp.ts | 23 +--- examples/rgbpp/xudt/local/2-btc-transfer.ts | 15 +-- examples/rgbpp/xudt/local/3-btc-leap-ckb.ts | 17 ++- 16 files changed, 202 insertions(+), 143 deletions(-) create mode 100644 examples/rgbpp/shared/btc-account.ts diff --git a/examples/rgbpp/.env.example b/examples/rgbpp/.env.example index 7a6d1e10..8359f171 100644 --- a/examples/rgbpp/.env.example +++ b/examples/rgbpp/.env.example @@ -20,6 +20,9 @@ CKB_INDEXER_URL=https://testnet.ckb.dev/indexer # Read more about P2WPKH in BIP141: https://github.com/bitcoin/bips/blob/master/bip-0141.mediawiki#p2wpkh BTC_PRIVATE_KEY=private-key +# The BTC address type to use, available options: P2WPKH or P2TR +BTC_ADDRESS_TYPE=P2WPKH + # The BTC assets api url which should be matched with IS_MAINNET VITE_BTC_SERVICE_URL=https://btc-assets-api.testnet.mibao.pro diff --git a/examples/rgbpp/README.md b/examples/rgbpp/README.md index c0810eb3..4337c85e 100644 --- a/examples/rgbpp/README.md +++ b/examples/rgbpp/README.md @@ -45,15 +45,18 @@ CKB_INDEXER_URL=https://testnet.ckb.dev/indexer # Read more about P2WPKH in BIP141: https://github.com/bitcoin/bips/blob/master/bip-0141.mediawiki#p2wpkh BTC_PRIVATE_KEY=private-key +# The BTC address type to use, available options: P2WPKH or P2TR +BTC_ADDRESS_TYPE=P2WPKH + # The BTC assets api url which should be matched with IS_MAINNET -VITE_BTC_SERVICE_URL=https://btc-assets-api.testnet.mibao.pro; +VITE_BTC_SERVICE_URL=https://btc-assets-api.testnet.mibao.pro # The BTC assets api token which should be matched with IS_MAINNET # To get an access token, please refer to https://github.com/ckb-cell/rgbpp-sdk/tree/develop/packages/service#get-an-access-token -VITE_BTC_SERVICE_TOKEN=; +VITE_BTC_SERVICE_TOKEN= # The BTC assets api origin which should be matched with IS_MAINNET -VITE_BTC_SERVICE_ORIGIN=https://btc-test.app; +VITE_BTC_SERVICE_ORIGIN=https://btc-test.app ``` ## RGB++ xUDT Examples diff --git a/examples/rgbpp/env.ts b/examples/rgbpp/env.ts index 05ec5b96..36d2f6b0 100644 --- a/examples/rgbpp/env.ts +++ b/examples/rgbpp/env.ts @@ -1,3 +1,4 @@ +import dotenv from 'dotenv'; import { blake160, bytesToHex, @@ -5,14 +6,22 @@ import { scriptToAddress, systemScripts, } from '@nervosnetwork/ckb-sdk-utils'; -import { DataSource, BtcAssetsApi } from 'rgbpp'; -import { ECPair, ECPairInterface, bitcoin, NetworkType } from 'rgbpp/btc'; -import dotenv from 'dotenv'; +import { NetworkType, AddressType, DataSource } from 'rgbpp/btc'; +import { BtcAssetsApi } from 'rgbpp/service'; import { Collector } from 'rgbpp/ckb'; +import { createBtcAccount } from './shared/btc-account'; dotenv.config({ path: __dirname + '/.env' }); -export const isMainnet = process.env.IS_MAINNET === 'true' ? true : false; +/** + * Network + */ + +export const isMainnet = process.env.IS_MAINNET === 'true'; + +/** + * CKB + */ export const collector = new Collector({ ckbNodeUrl: process.env.CKB_NODE_URL!, @@ -25,20 +34,21 @@ const secp256k1Lock: CKBComponents.Script = { }; export const ckbAddress = scriptToAddress(secp256k1Lock, isMainnet); +/** + * BTC + */ + export const BTC_PRIVATE_KEY = process.env.BTC_PRIVATE_KEY!; export const BTC_SERVICE_URL = process.env.VITE_BTC_SERVICE_URL!; export const BTC_SERVICE_TOKEN = process.env.VITE_BTC_SERVICE_TOKEN!; export const BTC_SERVICE_ORIGIN = process.env.VITE_BTC_SERVICE_ORIGIN!; -const network = isMainnet ? bitcoin.networks.bitcoin : bitcoin.networks.testnet; -export const btcKeyPair: ECPairInterface = ECPair.fromPrivateKey(Buffer.from(BTC_PRIVATE_KEY, 'hex'), { network }); -// The Native Segwit P2WPKH address will be generated with the BTC private key -// Read more about P2WPKH in BIP141: https://github.com/bitcoin/bips/blob/master/bip-0141.mediawiki#p2wpkh -export const { address: btcAddress } = bitcoin.payments.p2wpkh({ - pubkey: btcKeyPair.publicKey, - network, -}); - +// Read more about the available address types: +// - P2WPKH: https://github.com/bitcoin/bips/blob/master/bip-0141.mediawiki#p2wpkh +// - P2TR: https://github.com/bitcoin/bips/blob/master/bip-0341.mediawiki +const addressType = process.env.BTC_ADDRESS_TYPE === 'P2TR' ? AddressType.P2WPKH : AddressType.P2TR; const networkType = isMainnet ? NetworkType.MAINNET : NetworkType.TESTNET; +export const btcAccount = createBtcAccount(BTC_PRIVATE_KEY, addressType, networkType); + export const btcService = BtcAssetsApi.fromToken(BTC_SERVICE_URL, BTC_SERVICE_TOKEN, BTC_SERVICE_ORIGIN); export const btcDataSource = new DataSource(btcService, networkType); diff --git a/examples/rgbpp/shared/btc-account.ts b/examples/rgbpp/shared/btc-account.ts new file mode 100644 index 00000000..9a6b6415 --- /dev/null +++ b/examples/rgbpp/shared/btc-account.ts @@ -0,0 +1,100 @@ +import { + addressToScriptPublicKeyHex, + networkTypeToNetwork, + remove0x, + toXOnly, + transactionToHex, + tweakSigner, +} from 'rgbpp/btc'; +import { AddressType, NetworkType, bitcoin, ECPair } from 'rgbpp/btc'; +import { BtcAssetsApi } from 'rgbpp/service'; + +export interface BtcAccount { + from: string; + fromPubkey?: string; + keyPair: bitcoin.Signer; + payment: bitcoin.Payment; + addressType: AddressType; + networkType: NetworkType; +} + +export function createBtcAccount(privateKey: string, addressType: AddressType, networkType: NetworkType): BtcAccount { + const network = networkTypeToNetwork(networkType); + + const key = Buffer.from(remove0x(privateKey), 'hex'); + const keyPair = ECPair.fromPrivateKey(key, { network }); + + if (addressType === AddressType.P2WPKH) { + const p2wpkh = bitcoin.payments.p2wpkh({ + pubkey: keyPair.publicKey, + network, + }); + return { + from: p2wpkh.address!, + payment: p2wpkh, + keyPair, + addressType, + networkType, + }; + } else if (addressType === AddressType.P2TR) { + const p2tr = bitcoin.payments.p2tr({ + internalPubkey: toXOnly(keyPair.publicKey), + network, + }); + return { + from: p2tr.address!, + fromPubkey: keyPair.publicKey.toString('hex'), + payment: p2tr, + keyPair, + addressType, + networkType, + }; + } else { + throw new Error('Unsupported address type, only support P2WPKH and P2TR'); + } +} + +export function signPsbt(psbt: bitcoin.Psbt, account: BtcAccount): bitcoin.Psbt { + const accountScript = addressToScriptPublicKeyHex(account.from, account.networkType); + const tweakedSigner = tweakSigner(account.keyPair, { + network: account.payment.network, + }); + + psbt.data.inputs.forEach((input, index) => { + if (input.witnessUtxo) { + const script = input.witnessUtxo.script.toString('hex'); + if (script === accountScript && account.addressType === AddressType.P2WPKH) { + psbt.signInput(index, account.keyPair); + } + if (script === accountScript && account.addressType === AddressType.P2TR) { + psbt.signInput(index, tweakedSigner); + } + } + }); + + return psbt; +} + +export async function signAndSendPsbt( + psbt: bitcoin.Psbt, + account: BtcAccount, + service: BtcAssetsApi, +): Promise<{ + txId: string; + txHex: string; + txHexRaw: string; +}> { + signPsbt(psbt, account); + psbt.finalizeAllInputs(); + + const tx = psbt.extractTransaction(); + const txHex = tx.toHex(); + + const { txid } = await service.sendBtcTransaction(txHex); + + return { + txHex, + txId: txid, + txHexRaw: transactionToHex(tx, false), + }; +} diff --git a/examples/rgbpp/spore/4-transfer-spore.ts b/examples/rgbpp/spore/4-transfer-spore.ts index cf39c8e0..431ca76e 100644 --- a/examples/rgbpp/spore/4-transfer-spore.ts +++ b/examples/rgbpp/spore/4-transfer-spore.ts @@ -2,8 +2,9 @@ import { buildRgbppLockArgs } from 'rgbpp/ckb'; import { genTransferSporeCkbVirtualTx, sendRgbppUtxos } from 'rgbpp'; import { getSporeTypeScript, Hex } from 'rgbpp/ckb'; import { serializeScript } from '@nervosnetwork/ckb-sdk-utils'; -import { isMainnet, collector, btcAddress, btcDataSource, btcKeyPair, btcService } from '../env'; +import { isMainnet, collector, btcDataSource, btcService, btcAccount } from '../env'; import { saveCkbVirtualTxResult } from '../shared/utils'; +import { signAndSendPsbt } from '../shared/btc-account'; interface SporeTransferParams { sporeRgbppLockArgs: Hex; @@ -36,16 +37,13 @@ const transferSpore = async ({ sporeRgbppLockArgs, toBtcAddress, sporeTypeArgs } tos: [toBtcAddress], needPaymaster: needPaymasterCell, ckbCollector: collector, - from: btcAddress!, + from: btcAccount.from, + fromPubkey: btcAccount.fromPubkey, source: btcDataSource, feeRate: 30, }); - psbt.signAllInputs(btcKeyPair); - psbt.finalizeAllInputs(); - - const btcTx = psbt.extractTransaction(); - const { txid: btcTxId } = await btcService.sendBtcTransaction(btcTx.toHex()); + const { txId: btcTxId } = await signAndSendPsbt(psbt, btcAccount, btcService); console.log('BTC TxId: ', btcTxId); await btcService.sendRgbppCkbTransaction({ btc_txid: btcTxId, ckb_virtual_result: ckbVirtualTxResult }); diff --git a/examples/rgbpp/spore/5-leap-spore-to-ckb.ts b/examples/rgbpp/spore/5-leap-spore-to-ckb.ts index 3fdbf5cf..23e6f46f 100644 --- a/examples/rgbpp/spore/5-leap-spore-to-ckb.ts +++ b/examples/rgbpp/spore/5-leap-spore-to-ckb.ts @@ -2,8 +2,9 @@ import { buildRgbppLockArgs } from 'rgbpp/ckb'; import { genLeapSporeFromBtcToCkbVirtualTx, sendRgbppUtxos } from 'rgbpp'; import { getSporeTypeScript, Hex } from 'rgbpp/ckb'; import { serializeScript } from '@nervosnetwork/ckb-sdk-utils'; -import { isMainnet, collector, btcAddress, btcDataSource, btcKeyPair, btcService } from '../env'; +import { isMainnet, collector, btcDataSource, btcService, btcAccount } from '../env'; import { saveCkbVirtualTxResult } from '../shared/utils'; +import { signAndSendPsbt } from '../shared/btc-account'; interface SporeLeapParams { sporeRgbppLockArgs: Hex; @@ -34,19 +35,16 @@ const leapSporeFromBtcToCkb = async ({ sporeRgbppLockArgs, toCkbAddress, sporeTy const psbt = await sendRgbppUtxos({ ckbVirtualTx: ckbRawTx, commitment, - tos: [btcAddress!], + tos: [btcAccount.from], needPaymaster: needPaymasterCell, ckbCollector: collector, - from: btcAddress!, + from: btcAccount.from, + fromPubkey: btcAccount.fromPubkey, source: btcDataSource, feeRate: 30, }); - psbt.signAllInputs(btcKeyPair); - psbt.finalizeAllInputs(); - - const btcTx = psbt.extractTransaction(); - const { txid: btcTxId } = await btcService.sendBtcTransaction(btcTx.toHex()); + const { txId: btcTxId } = await signAndSendPsbt(psbt, btcAccount, btcService); console.log('BTC TxId: ', btcTxId); await btcService.sendRgbppCkbTransaction({ btc_txid: btcTxId, ckb_virtual_result: ckbVirtualTxResult }); diff --git a/examples/rgbpp/spore/launch/2-create-cluster.ts b/examples/rgbpp/spore/launch/2-create-cluster.ts index 745e66e5..52ba9648 100644 --- a/examples/rgbpp/spore/launch/2-create-cluster.ts +++ b/examples/rgbpp/spore/launch/2-create-cluster.ts @@ -1,7 +1,6 @@ import { BtcAssetsApiError, genCreateClusterCkbVirtualTx, sendRgbppUtxos } from 'rgbpp'; -import { isMainnet, collector, btcAddress, btcDataSource, btcKeyPair, btcService } from '../../env'; +import { isMainnet, collector, btcAccount, btcDataSource, btcService } from '../../env'; import { CLUSTER_DATA } from './0-cluster-info'; -import { transactionToHex } from 'rgbpp/btc'; import { appendCkbTxWitnesses, buildRgbppLockArgs, @@ -10,6 +9,7 @@ import { updateCkbTxWithRealBtcTxId, } from 'rgbpp/ckb'; import { saveCkbVirtualTxResult } from '../../shared/utils'; +import { signAndSendPsbt } from '../../shared/btc-account'; // Warning: Before runing this file, please run 1-prepare-cluster.ts const createCluster = async ({ ownerRgbppLockArgs }: { ownerRgbppLockArgs: string }) => { @@ -32,20 +32,16 @@ const createCluster = async ({ ownerRgbppLockArgs }: { ownerRgbppLockArgs: strin const psbt = await sendRgbppUtxos({ ckbVirtualTx: ckbRawTx, commitment, - tos: [btcAddress!], + tos: [btcAccount.from], needPaymaster: needPaymasterCell, ckbCollector: collector, - from: btcAddress!, + from: btcAccount.from, + fromPubkey: btcAccount.fromPubkey, source: btcDataSource, feeRate: 30, }); - psbt.signAllInputs(btcKeyPair); - psbt.finalizeAllInputs(); - - const btcTx = psbt.extractTransaction(); - const btcTxBytes = transactionToHex(btcTx, false); - const { txid: btcTxId } = await btcService.sendBtcTransaction(btcTx.toHex()); + const { txId: btcTxId, txHexRaw: btcTxBytes } = await signAndSendPsbt(psbt, btcAccount, btcService); console.log('BTC TxId: ', btcTxId); const interval = setInterval(async () => { diff --git a/examples/rgbpp/spore/launch/3-create-spores.ts b/examples/rgbpp/spore/launch/3-create-spores.ts index 8b6b4532..cb873919 100644 --- a/examples/rgbpp/spore/launch/3-create-spores.ts +++ b/examples/rgbpp/spore/launch/3-create-spores.ts @@ -1,14 +1,5 @@ import { BtcAssetsApiError, genCreateSporeCkbVirtualTx, sendRgbppUtxos } from 'rgbpp'; -import { - isMainnet, - collector, - btcAddress, - btcDataSource, - btcKeyPair, - btcService, - CKB_PRIVATE_KEY, - ckbAddress, -} from '../../env'; +import { isMainnet, collector, btcDataSource, btcService, CKB_PRIVATE_KEY, ckbAddress, btcAccount } from '../../env'; import { Hex, appendCkbTxWitnesses, @@ -19,8 +10,9 @@ import { updateCkbTxWithRealBtcTxId, RawSporeData, } from 'rgbpp/ckb'; -import { transactionToHex, utf8ToBuffer } from 'rgbpp/btc'; +import { utf8ToBuffer } from 'rgbpp/btc'; import { saveCkbVirtualTxResult } from '../../shared/utils'; +import { signAndSendPsbt } from '../../shared/btc-account'; interface SporeCreateParams { clusterRgbppLockArgs: Hex; @@ -47,24 +39,20 @@ const createSpores = async ({ clusterRgbppLockArgs, receivers }: SporeCreatePara // Send BTC tx // The first btc address is the owner of the cluster cell and the rest btc addresses are spore receivers - const btcTos = [btcAddress!, ...receivers.map((receiver) => receiver.toBtcAddress)]; + const btcTos = [btcAccount.from, ...receivers.map((receiver) => receiver.toBtcAddress)]; const psbt = await sendRgbppUtxos({ ckbVirtualTx: ckbRawTx, commitment, tos: btcTos, needPaymaster: needPaymasterCell, ckbCollector: collector, - from: btcAddress!, + from: btcAccount.from, + fromPubkey: btcAccount.fromPubkey, source: btcDataSource, feeRate: 120, }); - psbt.signAllInputs(btcKeyPair); - psbt.finalizeAllInputs(); - - const btcTx = psbt.extractTransaction(); - const btcTxBytes = transactionToHex(btcTx, false); - const { txid: btcTxId } = await btcService.sendBtcTransaction(btcTx.toHex()); + const { txId: btcTxId, txHexRaw: btcTxBytes } = await signAndSendPsbt(psbt, btcAccount, btcService); console.log('BTC TxId: ', btcTxId); const interval = setInterval(async () => { diff --git a/examples/rgbpp/spore/local/4-transfer-spore.ts b/examples/rgbpp/spore/local/4-transfer-spore.ts index 9c947106..d26216e4 100644 --- a/examples/rgbpp/spore/local/4-transfer-spore.ts +++ b/examples/rgbpp/spore/local/4-transfer-spore.ts @@ -8,11 +8,12 @@ import { generateSporeTransferCoBuild, genTransferSporeCkbVirtualTx, } from 'rgbpp/ckb'; -import { sendRgbppUtxos, transactionToHex } from 'rgbpp/btc'; +import { sendRgbppUtxos } from 'rgbpp/btc'; import { BtcAssetsApiError } from 'rgbpp'; import { serializeScript } from '@nervosnetwork/ckb-sdk-utils'; -import { isMainnet, collector, btcAddress, btcDataSource, btcKeyPair, btcService } from '../../env'; +import { isMainnet, collector, btcDataSource, btcService, btcAccount } from '../../env'; import { saveCkbVirtualTxResult } from '../../shared/utils'; +import { signAndSendPsbt } from '../../shared/btc-account'; interface SporeTransferParams { sporeRgbppLockArgs: Hex; @@ -50,17 +51,13 @@ const transferSpore = async ({ sporeRgbppLockArgs, toBtcAddress, sporeTypeArgs } tos: [toBtcAddress], needPaymaster: needPaymasterCell, ckbCollector: collector, - from: btcAddress!, + from: btcAccount.from, + fromPubkey: btcAccount.fromPubkey, source: btcDataSource, feeRate: 30, }); - psbt.signAllInputs(btcKeyPair); - psbt.finalizeAllInputs(); - - const btcTx = psbt.extractTransaction(); - const btcTxBytes = transactionToHex(btcTx, false); - const { txid: btcTxId } = await btcService.sendBtcTransaction(btcTx.toHex()); + const { txId: btcTxId, txHexRaw: btcTxBytes } = await signAndSendPsbt(psbt, btcAccount, btcService); console.log('BTC TxId: ', btcTxId); const interval = setInterval(async () => { diff --git a/examples/rgbpp/spore/local/5-leap-spore-to-ckb.ts b/examples/rgbpp/spore/local/5-leap-spore-to-ckb.ts index 0f7bf610..65d9b54d 100644 --- a/examples/rgbpp/spore/local/5-leap-spore-to-ckb.ts +++ b/examples/rgbpp/spore/local/5-leap-spore-to-ckb.ts @@ -8,11 +8,12 @@ import { generateSporeTransferCoBuild, genLeapSporeFromBtcToCkbVirtualTx, } from 'rgbpp/ckb'; -import { sendRgbppUtxos, transactionToHex } from 'rgbpp/btc'; +import { sendRgbppUtxos } from 'rgbpp/btc'; import { serializeScript } from '@nervosnetwork/ckb-sdk-utils'; -import { isMainnet, collector, btcAddress, btcDataSource, btcKeyPair, btcService } from '../../env'; +import { isMainnet, collector, btcDataSource, btcService, btcAccount } from '../../env'; import { BtcAssetsApiError } from 'rgbpp'; import { saveCkbVirtualTxResult } from '../../shared/utils'; +import { signAndSendPsbt } from '../../shared/btc-account'; interface SporeLeapParams { sporeRgbppLockArgs: Hex; @@ -47,20 +48,16 @@ const leapSpore = async ({ sporeRgbppLockArgs, toCkbAddress, sporeTypeArgs }: Sp const psbt = await sendRgbppUtxos({ ckbVirtualTx: ckbRawTx, commitment, - tos: [btcAddress!], + tos: [btcAccount.from], needPaymaster: needPaymasterCell, ckbCollector: collector, - from: btcAddress!, + from: btcAccount.from, + fromPubkey: btcAccount.fromPubkey, source: btcDataSource, feeRate: 120, }); - psbt.signAllInputs(btcKeyPair); - psbt.finalizeAllInputs(); - - const btcTx = psbt.extractTransaction(); - const btcTxBytes = transactionToHex(btcTx, false); - const { txid: btcTxId } = await btcService.sendBtcTransaction(btcTx.toHex()); + const { txId: btcTxId, txHexRaw: btcTxBytes } = await signAndSendPsbt(psbt, btcAccount, btcService); console.log('BTC TxId: ', btcTxId); const interval = setInterval(async () => { diff --git a/examples/rgbpp/xudt/2-btc-transfer.ts b/examples/rgbpp/xudt/2-btc-transfer.ts index f0ccf195..721ee1a3 100644 --- a/examples/rgbpp/xudt/2-btc-transfer.ts +++ b/examples/rgbpp/xudt/2-btc-transfer.ts @@ -1,8 +1,9 @@ import { buildRgbppLockArgs, getXudtTypeScript } from 'rgbpp/ckb'; import { serializeScript } from '@nervosnetwork/ckb-sdk-utils'; import { genBtcTransferCkbVirtualTx, sendRgbppUtxos } from 'rgbpp'; -import { isMainnet, collector, btcAddress, btcKeyPair, btcService, btcDataSource } from '../env'; +import { isMainnet, collector, btcService, btcDataSource, btcAccount } from '../env'; import { saveCkbVirtualTxResult } from '../shared/utils'; +import { signAndSendPsbt } from '../shared/btc-account'; interface RgbppTransferParams { rgbppLockArgsList: string[]; @@ -36,15 +37,12 @@ const transfer = async ({ rgbppLockArgsList, toBtcAddress, xudtTypeArgs, transfe commitment, tos: [toBtcAddress], ckbCollector: collector, - from: btcAddress!, + from: btcAccount.from, + fromPubkey: btcAccount.fromPubkey, source: btcDataSource, }); - psbt.signAllInputs(btcKeyPair); - psbt.finalizeAllInputs(); - - const btcTx = psbt.extractTransaction(); - const { txid: btcTxId } = await btcService.sendBtcTransaction(btcTx.toHex()); + const { txId: btcTxId } = await signAndSendPsbt(psbt, btcAccount, btcService); console.log('BTC TxId: ', btcTxId); await btcService.sendRgbppCkbTransaction({ btc_txid: btcTxId, ckb_virtual_result: ckbVirtualTxResult }); diff --git a/examples/rgbpp/xudt/3-btc-leap-ckb.ts b/examples/rgbpp/xudt/3-btc-leap-ckb.ts index c038b08c..58533c8d 100644 --- a/examples/rgbpp/xudt/3-btc-leap-ckb.ts +++ b/examples/rgbpp/xudt/3-btc-leap-ckb.ts @@ -1,8 +1,9 @@ import { buildRgbppLockArgs, getXudtTypeScript } from 'rgbpp/ckb'; import { serializeScript } from '@nervosnetwork/ckb-sdk-utils'; import { genBtcJumpCkbVirtualTx, sendRgbppUtxos } from 'rgbpp'; -import { isMainnet, collector, btcAddress, btcKeyPair, btcService, btcDataSource } from '../env'; +import { isMainnet, collector, btcService, btcDataSource, btcAccount } from '../env'; import { saveCkbVirtualTxResult } from '../shared/utils'; +import { signAndSendPsbt } from '../shared/btc-account'; interface LeapToCkbParams { rgbppLockArgsList: string[]; @@ -35,17 +36,14 @@ const leapFromBtcToCKB = async ({ rgbppLockArgsList, toCkbAddress, xudtTypeArgs, const psbt = await sendRgbppUtxos({ ckbVirtualTx: ckbRawTx, commitment, - tos: [btcAddress!], + tos: [btcAccount.from], ckbCollector: collector, - from: btcAddress!, + from: btcAccount.from, + fromPubkey: btcAccount.fromPubkey, source: btcDataSource, }); - psbt.signAllInputs(btcKeyPair); - psbt.finalizeAllInputs(); - - const btcTx = psbt.extractTransaction(); - const { txid: btcTxId } = await btcService.sendBtcTransaction(btcTx.toHex()); + const { txId: btcTxId } = await signAndSendPsbt(psbt, btcAccount, btcService); console.log('BTC TxId: ', btcTxId); await btcService.sendRgbppCkbTransaction({ btc_txid: btcTxId, ckb_virtual_result: ckbVirtualTxResult }); diff --git a/examples/rgbpp/xudt/launch/2-launch-rgbpp.ts b/examples/rgbpp/xudt/launch/2-launch-rgbpp.ts index 1d4034b1..d1f580f2 100644 --- a/examples/rgbpp/xudt/launch/2-launch-rgbpp.ts +++ b/examples/rgbpp/xudt/launch/2-launch-rgbpp.ts @@ -7,9 +7,9 @@ import { sendCkbTx, } from 'rgbpp/ckb'; import { RGBPP_TOKEN_INFO } from './0-rgbpp-token-info'; -import { btcAddress, btcDataSource, btcKeyPair, btcService, collector, isMainnet } from '../../env'; -import { transactionToHex } from 'rgbpp/btc'; +import { btcAccount, btcDataSource, btcService, collector, isMainnet } from '../../env'; import { saveCkbVirtualTxResult } from '../../shared/utils'; +import { signAndSendPsbt } from '../../shared/btc-account'; interface Params { ownerRgbppLockArgs: string; @@ -38,19 +38,15 @@ const launchRgppAsset = async ({ ownerRgbppLockArgs, launchAmount, rgbppTokenInf const psbt = await sendRgbppUtxos({ ckbVirtualTx: ckbRawTx, commitment, - tos: [btcAddress!], + tos: [btcAccount.from], needPaymaster: needPaymasterCell, ckbCollector: collector, - from: btcAddress!, + from: btcAccount.from, + fromPubkey: btcAccount.fromPubkey, source: btcDataSource, }); - psbt.signAllInputs(btcKeyPair); - psbt.finalizeAllInputs(); - - const btcTx = psbt.extractTransaction(); - const btcTxBytes = transactionToHex(btcTx, false); - const { txid: btcTxId } = await btcService.sendBtcTransaction(btcTx.toHex()); + const { txId: btcTxId, txHexRaw: btcTxBytes } = await signAndSendPsbt(psbt, btcAccount, btcService); console.log('BTC TxId: ', btcTxId); const interval = setInterval(async () => { diff --git a/examples/rgbpp/xudt/launch/3-distribute-rgbpp.ts b/examples/rgbpp/xudt/launch/3-distribute-rgbpp.ts index 3b6b26d5..661a999d 100644 --- a/examples/rgbpp/xudt/launch/3-distribute-rgbpp.ts +++ b/examples/rgbpp/xudt/launch/3-distribute-rgbpp.ts @@ -1,16 +1,7 @@ import { serializeScript } from '@nervosnetwork/ckb-sdk-utils'; import { BtcAssetsApiError, genBtcBatchTransferCkbVirtualTx, sendRgbppUtxos } from 'rgbpp'; import { RGBPP_TOKEN_INFO } from './0-rgbpp-token-info'; -import { - isMainnet, - collector, - btcAddress, - btcDataSource, - btcKeyPair, - btcService, - CKB_PRIVATE_KEY, - ckbAddress, -} from '../../env'; +import { isMainnet, collector, btcDataSource, btcService, CKB_PRIVATE_KEY, ckbAddress, btcAccount } from '../../env'; import { RgbppBtcAddressReceiver, appendCkbTxWitnesses, @@ -20,8 +11,8 @@ import { sendCkbTx, updateCkbTxWithRealBtcTxId, } from 'rgbpp/ckb'; -import { transactionToHex } from 'rgbpp/btc'; import { saveCkbVirtualTxResult } from '../../shared/utils'; +import { signAndSendPsbt } from '../../shared/btc-account'; interface Params { rgbppLockArgsList: string[]; @@ -62,16 +53,12 @@ const distributeRgbppAssetOnBtc = async ({ rgbppLockArgsList, receivers, xudtTyp tos: receivers.map((receiver) => receiver.toBtcAddress), needPaymaster: needPaymasterCell, ckbCollector: collector, - from: btcAddress!, + from: btcAccount.from, + fromPubkey: btcAccount.fromPubkey, source: btcDataSource, }); - psbt.signAllInputs(btcKeyPair); - psbt.finalizeAllInputs(); - - const btcTx = psbt.extractTransaction(); - const btcTxBytes = transactionToHex(btcTx, false); - const { txid: btcTxId } = await btcService.sendBtcTransaction(btcTx.toHex()); + const { txId: btcTxId, txHexRaw: btcTxBytes } = await signAndSendPsbt(psbt, btcAccount, btcService); console.log('BTC TxId: ', btcTxId); const interval = setInterval(async () => { diff --git a/examples/rgbpp/xudt/local/2-btc-transfer.ts b/examples/rgbpp/xudt/local/2-btc-transfer.ts index e8cd4376..34478f4b 100644 --- a/examples/rgbpp/xudt/local/2-btc-transfer.ts +++ b/examples/rgbpp/xudt/local/2-btc-transfer.ts @@ -7,9 +7,9 @@ import { getXudtTypeScript, updateCkbTxWithRealBtcTxId, } from 'rgbpp/ckb'; -import { isMainnet, collector, btcAddress, btcDataSource, btcKeyPair, btcService } from '../../env'; -import { transactionToHex } from 'rgbpp/btc'; +import { isMainnet, collector, btcDataSource, btcService, btcAccount } from '../../env'; import { saveCkbVirtualTxResult } from '../../shared/utils'; +import { signAndSendPsbt } from '../../shared/btc-account'; interface RgbppTransferParams { rgbppLockArgsList: string[]; @@ -44,17 +44,12 @@ const transfer = async ({ rgbppLockArgsList, toBtcAddress, xudtTypeArgs, transfe commitment, tos: [toBtcAddress], ckbCollector: collector, - from: btcAddress!, + from: btcAccount.from, + fromPubkey: btcAccount.fromPubkey, source: btcDataSource, }); - psbt.signAllInputs(btcKeyPair); - psbt.finalizeAllInputs(); - - const btcTx = psbt.extractTransaction(); - // Remove the witness from BTC tx for RGBPP unlock - const btcTxBytes = transactionToHex(btcTx, false); - const { txid: btcTxId } = await btcService.sendBtcTransaction(btcTx.toHex()); + const { txId: btcTxId, txHexRaw: btcTxBytes } = await signAndSendPsbt(psbt, btcAccount, btcService); console.log('BTC TxId: ', btcTxId); // Wait for BTC tx and proof to be ready, and then send isomorphic CKB transactions diff --git a/examples/rgbpp/xudt/local/3-btc-leap-ckb.ts b/examples/rgbpp/xudt/local/3-btc-leap-ckb.ts index b3c329a7..4bc4acae 100644 --- a/examples/rgbpp/xudt/local/3-btc-leap-ckb.ts +++ b/examples/rgbpp/xudt/local/3-btc-leap-ckb.ts @@ -7,9 +7,9 @@ import { getXudtTypeScript, updateCkbTxWithRealBtcTxId, } from 'rgbpp/ckb'; -import { isMainnet, collector, btcAddress, btcDataSource, btcKeyPair, btcService } from '../../env'; -import { transactionToHex } from 'rgbpp/btc'; +import { isMainnet, collector, btcDataSource, btcService, btcAccount } from '../../env'; import { saveCkbVirtualTxResult } from '../../shared/utils'; +import { signAndSendPsbt } from '../../shared/btc-account'; interface LeapToCkbParams { rgbppLockArgsList: string[]; @@ -43,19 +43,14 @@ const leapFromBtcToCkb = async ({ rgbppLockArgsList, toCkbAddress, xudtTypeArgs, const psbt = await sendRgbppUtxos({ ckbVirtualTx: ckbRawTx, commitment, - tos: [btcAddress!], + tos: [btcAccount.from], ckbCollector: collector, - from: btcAddress!, + from: btcAccount.from, + fromPubkey: btcAccount.fromPubkey, source: btcDataSource, }); - psbt.signAllInputs(btcKeyPair); - psbt.finalizeAllInputs(); - - const btcTx = psbt.extractTransaction(); - // Remove the witness from BTC tx for RGBPP unlock - const btcTxBytes = transactionToHex(btcTx, false); - const { txid: btcTxId } = await btcService.sendBtcTransaction(btcTx.toHex()); + const { txId: btcTxId, txHexRaw: btcTxBytes } = await signAndSendPsbt(psbt, btcAccount, btcService); console.log('BTC Tx bytes: ', btcTxBytes); console.log('BTC TxId: ', btcTxId); console.log('ckbRawTx', JSON.stringify(ckbRawTx)); From 51e960b21be939f0c71ffd1f886cb4333e020283 Mon Sep 17 00:00:00 2001 From: Shook Date: Thu, 6 Jun 2024 20:47:38 +0800 Subject: [PATCH 07/90] fix: wrong address type read from the BTC_ADDRESS_TYPE --- examples/rgbpp/env.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/rgbpp/env.ts b/examples/rgbpp/env.ts index 36d2f6b0..6186586a 100644 --- a/examples/rgbpp/env.ts +++ b/examples/rgbpp/env.ts @@ -46,7 +46,7 @@ export const BTC_SERVICE_ORIGIN = process.env.VITE_BTC_SERVICE_ORIGIN!; // Read more about the available address types: // - P2WPKH: https://github.com/bitcoin/bips/blob/master/bip-0141.mediawiki#p2wpkh // - P2TR: https://github.com/bitcoin/bips/blob/master/bip-0341.mediawiki -const addressType = process.env.BTC_ADDRESS_TYPE === 'P2TR' ? AddressType.P2WPKH : AddressType.P2TR; +const addressType = process.env.BTC_ADDRESS_TYPE === 'P2TR' ? AddressType.P2TR : AddressType.P2WPKH; const networkType = isMainnet ? NetworkType.MAINNET : NetworkType.TESTNET; export const btcAccount = createBtcAccount(BTC_PRIVATE_KEY, addressType, networkType); From 17c4648a2532f6b2308e36ec94f265b27d84c1e6 Mon Sep 17 00:00:00 2001 From: Shook Date: Thu, 6 Jun 2024 20:51:04 +0800 Subject: [PATCH 08/90] refactor: rename txHexRaw to rawTxHex in the return type of signAndSendPsbt() API --- examples/rgbpp/shared/btc-account.ts | 5 +++-- examples/rgbpp/spore/launch/2-create-cluster.ts | 2 +- examples/rgbpp/spore/launch/3-create-spores.ts | 2 +- examples/rgbpp/spore/local/4-transfer-spore.ts | 2 +- examples/rgbpp/spore/local/5-leap-spore-to-ckb.ts | 2 +- examples/rgbpp/xudt/launch/2-launch-rgbpp.ts | 2 +- examples/rgbpp/xudt/launch/3-distribute-rgbpp.ts | 2 +- examples/rgbpp/xudt/local/2-btc-transfer.ts | 2 +- examples/rgbpp/xudt/local/3-btc-leap-ckb.ts | 2 +- 9 files changed, 11 insertions(+), 10 deletions(-) diff --git a/examples/rgbpp/shared/btc-account.ts b/examples/rgbpp/shared/btc-account.ts index 9a6b6415..8fbb2c7c 100644 --- a/examples/rgbpp/shared/btc-account.ts +++ b/examples/rgbpp/shared/btc-account.ts @@ -82,7 +82,7 @@ export async function signAndSendPsbt( ): Promise<{ txId: string; txHex: string; - txHexRaw: string; + rawTxHex: string; }> { signPsbt(psbt, account); psbt.finalizeAllInputs(); @@ -95,6 +95,7 @@ export async function signAndSendPsbt( return { txHex, txId: txid, - txHexRaw: transactionToHex(tx, false), + // Exclude witness from the BTC_TX for unlocking RGBPP assets + rawTxHex: transactionToHex(tx, false), }; } diff --git a/examples/rgbpp/spore/launch/2-create-cluster.ts b/examples/rgbpp/spore/launch/2-create-cluster.ts index 52ba9648..b6056a3a 100644 --- a/examples/rgbpp/spore/launch/2-create-cluster.ts +++ b/examples/rgbpp/spore/launch/2-create-cluster.ts @@ -41,7 +41,7 @@ const createCluster = async ({ ownerRgbppLockArgs }: { ownerRgbppLockArgs: strin feeRate: 30, }); - const { txId: btcTxId, txHexRaw: btcTxBytes } = await signAndSendPsbt(psbt, btcAccount, btcService); + const { txId: btcTxId, rawTxHex: btcTxBytes } = await signAndSendPsbt(psbt, btcAccount, btcService); console.log('BTC TxId: ', btcTxId); const interval = setInterval(async () => { diff --git a/examples/rgbpp/spore/launch/3-create-spores.ts b/examples/rgbpp/spore/launch/3-create-spores.ts index cb873919..592e9a20 100644 --- a/examples/rgbpp/spore/launch/3-create-spores.ts +++ b/examples/rgbpp/spore/launch/3-create-spores.ts @@ -52,7 +52,7 @@ const createSpores = async ({ clusterRgbppLockArgs, receivers }: SporeCreatePara feeRate: 120, }); - const { txId: btcTxId, txHexRaw: btcTxBytes } = await signAndSendPsbt(psbt, btcAccount, btcService); + const { txId: btcTxId, rawTxHex: btcTxBytes } = await signAndSendPsbt(psbt, btcAccount, btcService); console.log('BTC TxId: ', btcTxId); const interval = setInterval(async () => { diff --git a/examples/rgbpp/spore/local/4-transfer-spore.ts b/examples/rgbpp/spore/local/4-transfer-spore.ts index d26216e4..fd256b06 100644 --- a/examples/rgbpp/spore/local/4-transfer-spore.ts +++ b/examples/rgbpp/spore/local/4-transfer-spore.ts @@ -57,7 +57,7 @@ const transferSpore = async ({ sporeRgbppLockArgs, toBtcAddress, sporeTypeArgs } feeRate: 30, }); - const { txId: btcTxId, txHexRaw: btcTxBytes } = await signAndSendPsbt(psbt, btcAccount, btcService); + const { txId: btcTxId, rawTxHex: btcTxBytes } = await signAndSendPsbt(psbt, btcAccount, btcService); console.log('BTC TxId: ', btcTxId); const interval = setInterval(async () => { diff --git a/examples/rgbpp/spore/local/5-leap-spore-to-ckb.ts b/examples/rgbpp/spore/local/5-leap-spore-to-ckb.ts index 65d9b54d..23d3b808 100644 --- a/examples/rgbpp/spore/local/5-leap-spore-to-ckb.ts +++ b/examples/rgbpp/spore/local/5-leap-spore-to-ckb.ts @@ -57,7 +57,7 @@ const leapSpore = async ({ sporeRgbppLockArgs, toCkbAddress, sporeTypeArgs }: Sp feeRate: 120, }); - const { txId: btcTxId, txHexRaw: btcTxBytes } = await signAndSendPsbt(psbt, btcAccount, btcService); + const { txId: btcTxId, rawTxHex: btcTxBytes } = await signAndSendPsbt(psbt, btcAccount, btcService); console.log('BTC TxId: ', btcTxId); const interval = setInterval(async () => { diff --git a/examples/rgbpp/xudt/launch/2-launch-rgbpp.ts b/examples/rgbpp/xudt/launch/2-launch-rgbpp.ts index d1f580f2..e4825938 100644 --- a/examples/rgbpp/xudt/launch/2-launch-rgbpp.ts +++ b/examples/rgbpp/xudt/launch/2-launch-rgbpp.ts @@ -46,7 +46,7 @@ const launchRgppAsset = async ({ ownerRgbppLockArgs, launchAmount, rgbppTokenInf source: btcDataSource, }); - const { txId: btcTxId, txHexRaw: btcTxBytes } = await signAndSendPsbt(psbt, btcAccount, btcService); + const { txId: btcTxId, rawTxHex: btcTxBytes } = await signAndSendPsbt(psbt, btcAccount, btcService); console.log('BTC TxId: ', btcTxId); const interval = setInterval(async () => { diff --git a/examples/rgbpp/xudt/launch/3-distribute-rgbpp.ts b/examples/rgbpp/xudt/launch/3-distribute-rgbpp.ts index 661a999d..32f29e28 100644 --- a/examples/rgbpp/xudt/launch/3-distribute-rgbpp.ts +++ b/examples/rgbpp/xudt/launch/3-distribute-rgbpp.ts @@ -58,7 +58,7 @@ const distributeRgbppAssetOnBtc = async ({ rgbppLockArgsList, receivers, xudtTyp source: btcDataSource, }); - const { txId: btcTxId, txHexRaw: btcTxBytes } = await signAndSendPsbt(psbt, btcAccount, btcService); + const { txId: btcTxId, rawTxHex: btcTxBytes } = await signAndSendPsbt(psbt, btcAccount, btcService); console.log('BTC TxId: ', btcTxId); const interval = setInterval(async () => { diff --git a/examples/rgbpp/xudt/local/2-btc-transfer.ts b/examples/rgbpp/xudt/local/2-btc-transfer.ts index 34478f4b..16b8bd87 100644 --- a/examples/rgbpp/xudt/local/2-btc-transfer.ts +++ b/examples/rgbpp/xudt/local/2-btc-transfer.ts @@ -49,7 +49,7 @@ const transfer = async ({ rgbppLockArgsList, toBtcAddress, xudtTypeArgs, transfe source: btcDataSource, }); - const { txId: btcTxId, txHexRaw: btcTxBytes } = await signAndSendPsbt(psbt, btcAccount, btcService); + const { txId: btcTxId, rawTxHex: btcTxBytes } = await signAndSendPsbt(psbt, btcAccount, btcService); console.log('BTC TxId: ', btcTxId); // Wait for BTC tx and proof to be ready, and then send isomorphic CKB transactions diff --git a/examples/rgbpp/xudt/local/3-btc-leap-ckb.ts b/examples/rgbpp/xudt/local/3-btc-leap-ckb.ts index 4bc4acae..fa5d1927 100644 --- a/examples/rgbpp/xudt/local/3-btc-leap-ckb.ts +++ b/examples/rgbpp/xudt/local/3-btc-leap-ckb.ts @@ -50,7 +50,7 @@ const leapFromBtcToCkb = async ({ rgbppLockArgsList, toCkbAddress, xudtTypeArgs, source: btcDataSource, }); - const { txId: btcTxId, txHexRaw: btcTxBytes } = await signAndSendPsbt(psbt, btcAccount, btcService); + const { txId: btcTxId, rawTxHex: btcTxBytes } = await signAndSendPsbt(psbt, btcAccount, btcService); console.log('BTC Tx bytes: ', btcTxBytes); console.log('BTC TxId: ', btcTxId); console.log('ckbRawTx', JSON.stringify(ckbRawTx)); From 463c6cc3719c9829103160d408b3f0b67ca254b4 Mon Sep 17 00:00:00 2001 From: Dylan Date: Mon, 3 Jun 2024 20:53:08 +0800 Subject: [PATCH 09/90] feat: Export buildRgbppTransferTx from rgbpp package --- examples/rgbpp/xudt/2-btc-transfer.ts | 32 +++++---------- packages/rgbpp/package.json | 3 +- packages/rgbpp/src/index.ts | 6 +++ packages/rgbpp/src/rgbpp/types.ts | 24 ++++++++++++ packages/rgbpp/src/rgbpp/xudt.ts | 56 +++++++++++++++++++++++++++ pnpm-lock.yaml | 3 ++ 6 files changed, 101 insertions(+), 23 deletions(-) create mode 100644 packages/rgbpp/src/rgbpp/types.ts create mode 100644 packages/rgbpp/src/rgbpp/xudt.ts diff --git a/examples/rgbpp/xudt/2-btc-transfer.ts b/examples/rgbpp/xudt/2-btc-transfer.ts index 721ee1a3..4f4eaf10 100644 --- a/examples/rgbpp/xudt/2-btc-transfer.ts +++ b/examples/rgbpp/xudt/2-btc-transfer.ts @@ -1,9 +1,9 @@ -import { buildRgbppLockArgs, getXudtTypeScript } from 'rgbpp/ckb'; -import { serializeScript } from '@nervosnetwork/ckb-sdk-utils'; -import { genBtcTransferCkbVirtualTx, sendRgbppUtxos } from 'rgbpp'; -import { isMainnet, collector, btcService, btcDataSource, btcAccount } from '../env'; +import { buildRgbppLockArgs } from 'rgbpp/ckb'; +import { buildRgbppTransferTx } from 'rgbpp'; +import { isMainnet, collector, btcService, btcAccount } from '../env'; import { saveCkbVirtualTxResult } from '../shared/utils'; import { signAndSendPsbt } from '../shared/btc-account'; +import { bitcoin } from 'rgbpp/btc'; interface RgbppTransferParams { rgbppLockArgsList: string[]; @@ -13,34 +13,22 @@ interface RgbppTransferParams { } const transfer = async ({ rgbppLockArgsList, toBtcAddress, xudtTypeArgs, transferAmount }: RgbppTransferParams) => { - const xudtType: CKBComponents.Script = { - ...getXudtTypeScript(isMainnet), - args: xudtTypeArgs, - }; - - const ckbVirtualTxResult = await genBtcTransferCkbVirtualTx({ + const { ckbVirtualTxResult, btcTxHexToSign } = await buildRgbppTransferTx({ collector, + xudtTypeArgs, rgbppLockArgsList, - xudtTypeBytes: serializeScript(xudtType), transferAmount, + fromBtcAddress: btcAccount.from, + toBtcAddress, + btcDataSource, isMainnet, }); // Save ckbVirtualTxResult saveCkbVirtualTxResult(ckbVirtualTxResult, '2-btc-transfer'); - const { commitment, ckbRawTx } = ckbVirtualTxResult; - // Send BTC tx - const psbt = await sendRgbppUtxos({ - ckbVirtualTx: ckbRawTx, - commitment, - tos: [toBtcAddress], - ckbCollector: collector, - from: btcAccount.from, - fromPubkey: btcAccount.fromPubkey, - source: btcDataSource, - }); + const psbt = bitcoin.Psbt.fromHex(btcTxHexToSign); const { txId: btcTxId } = await signAndSendPsbt(psbt, btcAccount, btcService); console.log('BTC TxId: ', btcTxId); diff --git a/packages/rgbpp/package.json b/packages/rgbpp/package.json index a78f6fdd..09a0a8d1 100644 --- a/packages/rgbpp/package.json +++ b/packages/rgbpp/package.json @@ -36,7 +36,8 @@ "dependencies": { "@rgbpp-sdk/btc": "workspace:*", "@rgbpp-sdk/ckb": "workspace:*", - "@rgbpp-sdk/service": "workspace:*" + "@rgbpp-sdk/service": "workspace:*", + "@nervosnetwork/ckb-sdk-utils": "^0.109.1" }, "publishConfig": { "access": "public" diff --git a/packages/rgbpp/src/index.ts b/packages/rgbpp/src/index.ts index b7836861..7903ff3d 100644 --- a/packages/rgbpp/src/index.ts +++ b/packages/rgbpp/src/index.ts @@ -54,3 +54,9 @@ export { createSendRgbppUtxosBuilder, } from '@rgbpp-sdk/btc'; export type { SendBtcProps, SendUtxosProps, SendRgbppUtxosProps } from '@rgbpp-sdk/btc'; + +/** + * RGB++ + */ +export { buildRgbppTransferTx } from './rgbpp/xudt'; +export type { RgbppTransferTxParams, RgbppTransferTxResult } from './rgbpp/types'; diff --git a/packages/rgbpp/src/rgbpp/types.ts b/packages/rgbpp/src/rgbpp/types.ts new file mode 100644 index 00000000..2edf7dee --- /dev/null +++ b/packages/rgbpp/src/rgbpp/types.ts @@ -0,0 +1,24 @@ +import { DataSource } from '@rgbpp-sdk/btc'; +import { BtcTransferVirtualTxResult, Collector, Hex } from '@rgbpp-sdk/ckb'; + +export interface RgbppTransferTxParams { + // The collector that collects CKB live cells and transactions + collector: Collector; + // The transferred RGB++ xUDT type script args + xudtTypeArgs: Hex; + // The rgbpp assets cell lock script args array whose data structure is: out_index | bitcoin_tx_id + rgbppLockArgsList: Hex[]; + // The XUDT amount to be transferred, if the noMergeOutputCells is true, the transferAmount will be ignored + transferAmount: bigint; + // The sender BTC address + fromBtcAddress: string; + // The receiver BTC address + toBtcAddress: string; + btcDataSource: DataSource; + isMainnet: boolean; +} + +export interface RgbppTransferTxResult { + ckbVirtualTxResult: BtcTransferVirtualTxResult; + btcTxHexToSign: Hex; +} diff --git a/packages/rgbpp/src/rgbpp/xudt.ts b/packages/rgbpp/src/rgbpp/xudt.ts new file mode 100644 index 00000000..345aa0da --- /dev/null +++ b/packages/rgbpp/src/rgbpp/xudt.ts @@ -0,0 +1,56 @@ +import { genBtcTransferCkbVirtualTx, getXudtTypeScript } from '@rgbpp-sdk/ckb'; +import { serializeScript } from '@nervosnetwork/ckb-sdk-utils'; +import { sendRgbppUtxos } from '@rgbpp-sdk/btc'; +import { RgbppTransferTxParams, RgbppTransferTxResult } from './types'; + +/** + * Build the CKB virtual transaction and BTC transaction to be signed for the RGB++ transfer tx + * @param collector The collector that collects CKB live cells and transactions + * @param xudtTypeArgs The transferred xUDT type script args + * @param rgbppLockArgsList The RGB++ assets cell lock script args array whose data structure is: out_index | bitcoin_tx_id + * @param transferAmount The XUDT amount to be transferred, if the noMergeOutputCells is true, the transferAmount will be ignored + * @param fromBtcAddress The sender BTC address + * @param toBtcAddress The receiver BTC address + * @param btcDataSource The BTC data source + * @param isMainnet + */ +export const buildRgbppTransferTx = async ({ + collector, + xudtTypeArgs, + rgbppLockArgsList, + transferAmount, + fromBtcAddress, + toBtcAddress, + btcDataSource, + isMainnet, +}: RgbppTransferTxParams): Promise => { + const xudtType: CKBComponents.Script = { + ...getXudtTypeScript(isMainnet), + args: xudtTypeArgs, + }; + + const ckbVirtualTxResult = await genBtcTransferCkbVirtualTx({ + collector, + rgbppLockArgsList, + xudtTypeBytes: serializeScript(xudtType), + transferAmount, + isMainnet, + }); + + const { commitment, ckbRawTx } = ckbVirtualTxResult; + + // Send BTC tx + const psbt = await sendRgbppUtxos({ + ckbVirtualTx: ckbRawTx, + commitment, + tos: [toBtcAddress], + ckbCollector: collector, + from: fromBtcAddress!, + source: btcDataSource, + }); + + return { + ckbVirtualTxResult, + btcTxHexToSign: psbt.toHex(), + }; +}; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 094056db..2c5c92e0 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -263,6 +263,9 @@ importers: packages/rgbpp: dependencies: + '@nervosnetwork/ckb-sdk-utils': + specifier: ^0.109.1 + version: 0.109.1 '@rgbpp-sdk/btc': specifier: workspace:* version: link:../btc From 513eca9c3d1acb80e67bae4e104091b108700f61 Mon Sep 17 00:00:00 2001 From: Dylan Date: Mon, 3 Jun 2024 20:54:14 +0800 Subject: [PATCH 10/90] chore: Add changeset --- .changeset/great-baboons-smash.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/great-baboons-smash.md diff --git a/.changeset/great-baboons-smash.md b/.changeset/great-baboons-smash.md new file mode 100644 index 00000000..73fe4b23 --- /dev/null +++ b/.changeset/great-baboons-smash.md @@ -0,0 +1,5 @@ +--- +"rgbpp": minor +--- + +feat: Export buildRgbppTransferTx from rgbpp package From 1f39d827e3304db45ee08f468a8d5c7747624f6d Mon Sep 17 00:00:00 2001 From: Dylan Date: Tue, 4 Jun 2024 13:14:00 +0800 Subject: [PATCH 11/90] refactor: Rename btcTxHexToSign to btcPsbtHex --- examples/rgbpp/xudt/2-btc-transfer.ts | 5 ++- examples/rgbpp/xudt/local/2-btc-transfer.ts | 37 ++++++--------------- packages/rgbpp/src/rgbpp/types.ts | 3 +- packages/rgbpp/src/rgbpp/xudt.ts | 2 +- 4 files changed, 15 insertions(+), 32 deletions(-) diff --git a/examples/rgbpp/xudt/2-btc-transfer.ts b/examples/rgbpp/xudt/2-btc-transfer.ts index 4f4eaf10..bb1ae689 100644 --- a/examples/rgbpp/xudt/2-btc-transfer.ts +++ b/examples/rgbpp/xudt/2-btc-transfer.ts @@ -13,7 +13,7 @@ interface RgbppTransferParams { } const transfer = async ({ rgbppLockArgsList, toBtcAddress, xudtTypeArgs, transferAmount }: RgbppTransferParams) => { - const { ckbVirtualTxResult, btcTxHexToSign } = await buildRgbppTransferTx({ + const { ckbVirtualTxResult, btcPsbtHex } = await buildRgbppTransferTx({ collector, xudtTypeArgs, rgbppLockArgsList, @@ -28,8 +28,7 @@ const transfer = async ({ rgbppLockArgsList, toBtcAddress, xudtTypeArgs, transfe saveCkbVirtualTxResult(ckbVirtualTxResult, '2-btc-transfer'); // Send BTC tx - const psbt = bitcoin.Psbt.fromHex(btcTxHexToSign); - + const psbt = bitcoin.Psbt.fromHex(btcPsbtHex); const { txId: btcTxId } = await signAndSendPsbt(psbt, btcAccount, btcService); console.log('BTC TxId: ', btcTxId); diff --git a/examples/rgbpp/xudt/local/2-btc-transfer.ts b/examples/rgbpp/xudt/local/2-btc-transfer.ts index 16b8bd87..6fbf4ef4 100644 --- a/examples/rgbpp/xudt/local/2-btc-transfer.ts +++ b/examples/rgbpp/xudt/local/2-btc-transfer.ts @@ -1,13 +1,7 @@ -import { serializeScript } from '@nervosnetwork/ckb-sdk-utils'; -import { genBtcTransferCkbVirtualTx, sendRgbppUtxos, BtcAssetsApiError } from 'rgbpp'; -import { - appendCkbTxWitnesses, - buildRgbppLockArgs, - sendCkbTx, - getXudtTypeScript, - updateCkbTxWithRealBtcTxId, -} from 'rgbpp/ckb'; +import { BtcAssetsApiError, buildRgbppTransferTx } from 'rgbpp'; +import { appendCkbTxWitnesses, buildRgbppLockArgs, sendCkbTx, updateCkbTxWithRealBtcTxId } from 'rgbpp/ckb'; import { isMainnet, collector, btcDataSource, btcService, btcAccount } from '../../env'; +import { bitcoin } from 'rgbpp/btc'; import { saveCkbVirtualTxResult } from '../../shared/utils'; import { signAndSendPsbt } from '../../shared/btc-account'; @@ -20,35 +14,24 @@ interface RgbppTransferParams { // Warning: It is not recommended for developers to use local examples unless you understand the entire process of RGB++ transactions. const transfer = async ({ rgbppLockArgsList, toBtcAddress, xudtTypeArgs, transferAmount }: RgbppTransferParams) => { - const xudtType: CKBComponents.Script = { - ...getXudtTypeScript(isMainnet), - args: xudtTypeArgs, - }; - - const ckbVirtualTxResult = await genBtcTransferCkbVirtualTx({ + const { ckbVirtualTxResult, btcPsbtHex } = await buildRgbppTransferTx({ collector, + xudtTypeArgs, rgbppLockArgsList, - xudtTypeBytes: serializeScript(xudtType), transferAmount, + fromBtcAddress: btcAddress!, + toBtcAddress, + btcDataSource, isMainnet, }); // Save ckbVirtualTxResult saveCkbVirtualTxResult(ckbVirtualTxResult, '2-btc-transfer-local'); - const { commitment, ckbRawTx } = ckbVirtualTxResult; + const { ckbRawTx } = ckbVirtualTxResult; // Send BTC tx - const psbt = await sendRgbppUtxos({ - ckbVirtualTx: ckbRawTx, - commitment, - tos: [toBtcAddress], - ckbCollector: collector, - from: btcAccount.from, - fromPubkey: btcAccount.fromPubkey, - source: btcDataSource, - }); - + const psbt = bitcoin.Psbt.fromHex(btcPsbtHex); const { txId: btcTxId, rawTxHex: btcTxBytes } = await signAndSendPsbt(psbt, btcAccount, btcService); console.log('BTC TxId: ', btcTxId); diff --git a/packages/rgbpp/src/rgbpp/types.ts b/packages/rgbpp/src/rgbpp/types.ts index 2edf7dee..36dbbceb 100644 --- a/packages/rgbpp/src/rgbpp/types.ts +++ b/packages/rgbpp/src/rgbpp/types.ts @@ -20,5 +20,6 @@ export interface RgbppTransferTxParams { export interface RgbppTransferTxResult { ckbVirtualTxResult: BtcTransferVirtualTxResult; - btcTxHexToSign: Hex; + // The BTC transaction hex string which can be used to construct Bitcoin PSBT + btcPsbtHex: Hex; } diff --git a/packages/rgbpp/src/rgbpp/xudt.ts b/packages/rgbpp/src/rgbpp/xudt.ts index 345aa0da..5f7d3a6f 100644 --- a/packages/rgbpp/src/rgbpp/xudt.ts +++ b/packages/rgbpp/src/rgbpp/xudt.ts @@ -51,6 +51,6 @@ export const buildRgbppTransferTx = async ({ return { ckbVirtualTxResult, - btcTxHexToSign: psbt.toHex(), + btcPsbtHex: psbt.toHex(), }; }; From c5a2b2fcdb7f4f5540913e39b9993f1e462c1538 Mon Sep 17 00:00:00 2001 From: Dylan Date: Tue, 4 Jun 2024 13:31:21 +0800 Subject: [PATCH 12/90] docs: Add introduction to readme --- packages/rgbpp/README.md | 30 ++++++++++++++++++++++++++++++ packages/rgbpp/src/rgbpp/types.ts | 2 +- 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/packages/rgbpp/README.md b/packages/rgbpp/README.md index 8680c297..70be041b 100644 --- a/packages/rgbpp/README.md +++ b/packages/rgbpp/README.md @@ -12,4 +12,34 @@ $ npm i rgbpp $ yarn add rgbpp # or $ pnpm add rgbpp +``` + +## Transfer RGB++ Assets on BTC + +The function `buildRgbppTransferTx` will generate CKB virtual transaction and related BTC transaction with the commitment for the RGB++ assets transfer on BTC. + +The `btcPsbtHex` can be used to construct bitcoin PSBT to sign and send BTC transaction with BTC wallet, and then the BTC transaction id and `ckbVirtualTxResult` will be used to post to RGB++ Queue Service to complete the isomorphic CKB transaction. + +```TypeScript +const { ckbVirtualTxResult, btcPsbtHex } = await buildRgbppTransferTx({ + collector, + xudtTypeArgs, + rgbppLockArgsList, + transferAmount, + fromBtcAddress, + toBtcAddress, + btcDataSource, + isMainnet, + }); + +// Construct SPBT with btcPsbtHex to sign and send BTC transaction with the BTC key pair +const psbt = bitcoin.Psbt.fromHex(btcPsbtHex); +psbt.signAllInputs(btcKeyPair); +psbt.finalizeAllInputs(); + +const btcTx = psbt.extractTransaction(); +const { txid: btcTxId } = await btcService.sendBtcTransaction(btcTx.toHex()); + +// Post the BTC txId and ckbVirtualTxResult to the RGB++ Queue Service +await btcService.sendRgbppCkbTransaction({ btc_txid: btcTxId, ckb_virtual_result: ckbVirtualTxResult }); ``` \ No newline at end of file diff --git a/packages/rgbpp/src/rgbpp/types.ts b/packages/rgbpp/src/rgbpp/types.ts index 36dbbceb..5344d7e1 100644 --- a/packages/rgbpp/src/rgbpp/types.ts +++ b/packages/rgbpp/src/rgbpp/types.ts @@ -20,6 +20,6 @@ export interface RgbppTransferTxParams { export interface RgbppTransferTxResult { ckbVirtualTxResult: BtcTransferVirtualTxResult; - // The BTC transaction hex string which can be used to construct Bitcoin PSBT + // The BTC PSBT hex string which can be used to construct Bitcoin PSBT btcPsbtHex: Hex; } From f57fd2b60900886ee0e8ce6b1a093f9a4ba9d872 Mon Sep 17 00:00:00 2001 From: Dylan Duan Date: Thu, 6 Jun 2024 19:48:08 +0800 Subject: [PATCH 13/90] refactor: Update buildRgbppTransferTx parameters --- packages/rgbpp/README.md | 11 +++++++++-- packages/rgbpp/src/rgbpp/types.ts | 16 +++++++++++++++- packages/rgbpp/src/rgbpp/xudt.ts | 18 +++++++++++------- 3 files changed, 35 insertions(+), 10 deletions(-) diff --git a/packages/rgbpp/README.md b/packages/rgbpp/README.md index 70be041b..12a5ea7c 100644 --- a/packages/rgbpp/README.md +++ b/packages/rgbpp/README.md @@ -22,15 +22,22 @@ The `btcPsbtHex` can be used to construct bitcoin PSBT to sign and send BTC tran ```TypeScript const { ckbVirtualTxResult, btcPsbtHex } = await buildRgbppTransferTx({ + ckb: { collector, xudtTypeArgs, rgbppLockArgsList, transferAmount, + ckbFeeRate, + }, + btc: { fromBtcAddress, toBtcAddress, btcDataSource, - isMainnet, - }); + fromPubkey, + feeRate + }, + isMainnet, +}); // Construct SPBT with btcPsbtHex to sign and send BTC transaction with the BTC key pair const psbt = bitcoin.Psbt.fromHex(btcPsbtHex); diff --git a/packages/rgbpp/src/rgbpp/types.ts b/packages/rgbpp/src/rgbpp/types.ts index 5344d7e1..6a640ca9 100644 --- a/packages/rgbpp/src/rgbpp/types.ts +++ b/packages/rgbpp/src/rgbpp/types.ts @@ -1,7 +1,7 @@ import { DataSource } from '@rgbpp-sdk/btc'; import { BtcTransferVirtualTxResult, Collector, Hex } from '@rgbpp-sdk/ckb'; -export interface RgbppTransferTxParams { +export interface RgbppTransferCkb { // The collector that collects CKB live cells and transactions collector: Collector; // The transferred RGB++ xUDT type script args @@ -10,11 +10,25 @@ export interface RgbppTransferTxParams { rgbppLockArgsList: Hex[]; // The XUDT amount to be transferred, if the noMergeOutputCells is true, the transferAmount will be ignored transferAmount: bigint; + // The CKB transaction fee rate, default value is 1100 + ckbFeeRate?: bigint; +} + +export interface RgbppTransferBtc { // The sender BTC address fromBtcAddress: string; // The receiver BTC address toBtcAddress: string; btcDataSource: DataSource; + // The public key of sender BTC address + fromPubkey?: Hex; + // The fee rate of the BTC transaction + feeRate?: number; +} + +export interface RgbppTransferTxParams { + ckb: RgbppTransferCkb; + btc: RgbppTransferBtc; isMainnet: boolean; } diff --git a/packages/rgbpp/src/rgbpp/xudt.ts b/packages/rgbpp/src/rgbpp/xudt.ts index 5f7d3a6f..9f08e4d4 100644 --- a/packages/rgbpp/src/rgbpp/xudt.ts +++ b/packages/rgbpp/src/rgbpp/xudt.ts @@ -5,23 +5,24 @@ import { RgbppTransferTxParams, RgbppTransferTxResult } from './types'; /** * Build the CKB virtual transaction and BTC transaction to be signed for the RGB++ transfer tx + * CKB parameters * @param collector The collector that collects CKB live cells and transactions * @param xudtTypeArgs The transferred xUDT type script args * @param rgbppLockArgsList The RGB++ assets cell lock script args array whose data structure is: out_index | bitcoin_tx_id * @param transferAmount The XUDT amount to be transferred, if the noMergeOutputCells is true, the transferAmount will be ignored + * @param ckbFeeRate The CKB transaction fee rate, default value is 1100 + * + * BTC pramaeters * @param fromBtcAddress The sender BTC address + * @param fromPubkey The public key of the sender BTC address * @param toBtcAddress The receiver BTC address * @param btcDataSource The BTC data source + * @param feeRate The fee rate of the BTC transaction * @param isMainnet */ export const buildRgbppTransferTx = async ({ - collector, - xudtTypeArgs, - rgbppLockArgsList, - transferAmount, - fromBtcAddress, - toBtcAddress, - btcDataSource, + ckb: { collector, xudtTypeArgs, rgbppLockArgsList, transferAmount, ckbFeeRate }, + btc: { fromBtcAddress, toBtcAddress, btcDataSource, fromPubkey, feeRate }, isMainnet, }: RgbppTransferTxParams): Promise => { const xudtType: CKBComponents.Script = { @@ -35,6 +36,7 @@ export const buildRgbppTransferTx = async ({ xudtTypeBytes: serializeScript(xudtType), transferAmount, isMainnet, + ckbFeeRate, }); const { commitment, ckbRawTx } = ckbVirtualTxResult; @@ -46,7 +48,9 @@ export const buildRgbppTransferTx = async ({ tos: [toBtcAddress], ckbCollector: collector, from: fromBtcAddress!, + fromPubkey, source: btcDataSource, + feeRate, }); return { From dde9527aa3c5d997a238d10965b914c320af4224 Mon Sep 17 00:00:00 2001 From: Dylan Duan Date: Thu, 6 Jun 2024 19:48:37 +0800 Subject: [PATCH 14/90] refactor: Update L1 transfer examples with new parameters --- examples/rgbpp/xudt/2-btc-transfer.ts | 20 ++++++++++++-------- examples/rgbpp/xudt/local/2-btc-transfer.ts | 18 +++++++++++------- 2 files changed, 23 insertions(+), 15 deletions(-) diff --git a/examples/rgbpp/xudt/2-btc-transfer.ts b/examples/rgbpp/xudt/2-btc-transfer.ts index bb1ae689..27a27de9 100644 --- a/examples/rgbpp/xudt/2-btc-transfer.ts +++ b/examples/rgbpp/xudt/2-btc-transfer.ts @@ -1,6 +1,6 @@ import { buildRgbppLockArgs } from 'rgbpp/ckb'; import { buildRgbppTransferTx } from 'rgbpp'; -import { isMainnet, collector, btcService, btcAccount } from '../env'; +import { isMainnet, collector, btcService, btcAccount, btcDataSource } from '../env'; import { saveCkbVirtualTxResult } from '../shared/utils'; import { signAndSendPsbt } from '../shared/btc-account'; import { bitcoin } from 'rgbpp/btc'; @@ -14,13 +14,17 @@ interface RgbppTransferParams { const transfer = async ({ rgbppLockArgsList, toBtcAddress, xudtTypeArgs, transferAmount }: RgbppTransferParams) => { const { ckbVirtualTxResult, btcPsbtHex } = await buildRgbppTransferTx({ - collector, - xudtTypeArgs, - rgbppLockArgsList, - transferAmount, - fromBtcAddress: btcAccount.from, - toBtcAddress, - btcDataSource, + ckb: { + collector, + xudtTypeArgs, + rgbppLockArgsList, + transferAmount, + }, + btc: { + fromAddress: btcAccount.from, + toAddress: toBtcAddress, + dataSource: btcDataSource, + }, isMainnet, }); diff --git a/examples/rgbpp/xudt/local/2-btc-transfer.ts b/examples/rgbpp/xudt/local/2-btc-transfer.ts index 6fbf4ef4..21492c3d 100644 --- a/examples/rgbpp/xudt/local/2-btc-transfer.ts +++ b/examples/rgbpp/xudt/local/2-btc-transfer.ts @@ -15,13 +15,17 @@ interface RgbppTransferParams { // Warning: It is not recommended for developers to use local examples unless you understand the entire process of RGB++ transactions. const transfer = async ({ rgbppLockArgsList, toBtcAddress, xudtTypeArgs, transferAmount }: RgbppTransferParams) => { const { ckbVirtualTxResult, btcPsbtHex } = await buildRgbppTransferTx({ - collector, - xudtTypeArgs, - rgbppLockArgsList, - transferAmount, - fromBtcAddress: btcAddress!, - toBtcAddress, - btcDataSource, + ckb: { + collector, + xudtTypeArgs, + rgbppLockArgsList, + transferAmount, + }, + btc: { + fromAddress: btcAccount.from, + toAddress: toBtcAddress, + dataSource: btcDataSource, + }, isMainnet, }); From 4893d8f36d09de2b7515f4eb0a473637b09d539c Mon Sep 17 00:00:00 2001 From: Dylan Duan Date: Thu, 6 Jun 2024 20:17:02 +0800 Subject: [PATCH 15/90] refactor: Update buildRgbppTransferTx parameters' name --- packages/rgbpp/src/rgbpp/types.ts | 16 ++++++++-------- packages/rgbpp/src/rgbpp/xudt.ts | 22 +++++++++++----------- 2 files changed, 19 insertions(+), 19 deletions(-) diff --git a/packages/rgbpp/src/rgbpp/types.ts b/packages/rgbpp/src/rgbpp/types.ts index 6a640ca9..eb213eae 100644 --- a/packages/rgbpp/src/rgbpp/types.ts +++ b/packages/rgbpp/src/rgbpp/types.ts @@ -1,7 +1,7 @@ import { DataSource } from '@rgbpp-sdk/btc'; import { BtcTransferVirtualTxResult, Collector, Hex } from '@rgbpp-sdk/ckb'; -export interface RgbppTransferCkb { +export interface RgbppTransferCkbParams { // The collector that collects CKB live cells and transactions collector: Collector; // The transferred RGB++ xUDT type script args @@ -11,15 +11,15 @@ export interface RgbppTransferCkb { // The XUDT amount to be transferred, if the noMergeOutputCells is true, the transferAmount will be ignored transferAmount: bigint; // The CKB transaction fee rate, default value is 1100 - ckbFeeRate?: bigint; + feeRate?: bigint; } -export interface RgbppTransferBtc { +export interface RgbppTransferBtcParams { // The sender BTC address - fromBtcAddress: string; + fromAddress: string; // The receiver BTC address - toBtcAddress: string; - btcDataSource: DataSource; + toAddress: string; + dataSource: DataSource; // The public key of sender BTC address fromPubkey?: Hex; // The fee rate of the BTC transaction @@ -27,8 +27,8 @@ export interface RgbppTransferBtc { } export interface RgbppTransferTxParams { - ckb: RgbppTransferCkb; - btc: RgbppTransferBtc; + ckb: RgbppTransferCkbParams; + btc: RgbppTransferBtcParams; isMainnet: boolean; } diff --git a/packages/rgbpp/src/rgbpp/xudt.ts b/packages/rgbpp/src/rgbpp/xudt.ts index 9f08e4d4..21a9eaf3 100644 --- a/packages/rgbpp/src/rgbpp/xudt.ts +++ b/packages/rgbpp/src/rgbpp/xudt.ts @@ -10,19 +10,19 @@ import { RgbppTransferTxParams, RgbppTransferTxResult } from './types'; * @param xudtTypeArgs The transferred xUDT type script args * @param rgbppLockArgsList The RGB++ assets cell lock script args array whose data structure is: out_index | bitcoin_tx_id * @param transferAmount The XUDT amount to be transferred, if the noMergeOutputCells is true, the transferAmount will be ignored - * @param ckbFeeRate The CKB transaction fee rate, default value is 1100 + * @param feeRate The CKB transaction fee rate, default value is 1100 * * BTC pramaeters - * @param fromBtcAddress The sender BTC address + * @param fromAddress The sender BTC address * @param fromPubkey The public key of the sender BTC address - * @param toBtcAddress The receiver BTC address - * @param btcDataSource The BTC data source + * @param toAddress The receiver BTC address + * @param dataSource The BTC data source * @param feeRate The fee rate of the BTC transaction * @param isMainnet */ export const buildRgbppTransferTx = async ({ - ckb: { collector, xudtTypeArgs, rgbppLockArgsList, transferAmount, ckbFeeRate }, - btc: { fromBtcAddress, toBtcAddress, btcDataSource, fromPubkey, feeRate }, + ckb: { collector, xudtTypeArgs, rgbppLockArgsList, transferAmount, feeRate: ckbFeeRate }, + btc, isMainnet, }: RgbppTransferTxParams): Promise => { const xudtType: CKBComponents.Script = { @@ -45,12 +45,12 @@ export const buildRgbppTransferTx = async ({ const psbt = await sendRgbppUtxos({ ckbVirtualTx: ckbRawTx, commitment, - tos: [toBtcAddress], + tos: [btc.toAddress], ckbCollector: collector, - from: fromBtcAddress!, - fromPubkey, - source: btcDataSource, - feeRate, + from: btc.fromAddress!, + fromPubkey: btc.fromPubkey, + source: btc.dataSource, + feeRate: btc.feeRate, }); return { From 21304feb90d57466c670acbe4e2912fe2726b474 Mon Sep 17 00:00:00 2001 From: Dylan Duan Date: Fri, 7 Jun 2024 09:47:39 +0800 Subject: [PATCH 16/90] feat: Add btc pubkey to L1 transfer examples --- examples/rgbpp/xudt/2-btc-transfer.ts | 1 + examples/rgbpp/xudt/local/2-btc-transfer.ts | 1 + 2 files changed, 2 insertions(+) diff --git a/examples/rgbpp/xudt/2-btc-transfer.ts b/examples/rgbpp/xudt/2-btc-transfer.ts index 27a27de9..ea98a126 100644 --- a/examples/rgbpp/xudt/2-btc-transfer.ts +++ b/examples/rgbpp/xudt/2-btc-transfer.ts @@ -23,6 +23,7 @@ const transfer = async ({ rgbppLockArgsList, toBtcAddress, xudtTypeArgs, transfe btc: { fromAddress: btcAccount.from, toAddress: toBtcAddress, + fromPubkey: btcAccount.fromPubkey, dataSource: btcDataSource, }, isMainnet, diff --git a/examples/rgbpp/xudt/local/2-btc-transfer.ts b/examples/rgbpp/xudt/local/2-btc-transfer.ts index 21492c3d..f7195550 100644 --- a/examples/rgbpp/xudt/local/2-btc-transfer.ts +++ b/examples/rgbpp/xudt/local/2-btc-transfer.ts @@ -24,6 +24,7 @@ const transfer = async ({ rgbppLockArgsList, toBtcAddress, xudtTypeArgs, transfe btc: { fromAddress: btcAccount.from, toAddress: toBtcAddress, + fromPubkey: btcAccount.fromPubkey, dataSource: btcDataSource, }, isMainnet, From e1175f2a43afe2baa525404ada4dce29381be3ec Mon Sep 17 00:00:00 2001 From: Dawn <77844990+Dawn-githup@users.noreply.github.com> Date: Fri, 7 Jun 2024 09:56:26 +0800 Subject: [PATCH 17/90] test: Create spore integration tests (#210) * test: Create spore integration tests * Refactor: Integrate Testing Workflow * Refactor: Refactor integration test workflow for readability and clarity * fix: Resolve issue with integration tests not running * chore: use clear step names in test script * fix: resolve issue with file not being read * fix: fix spore integration test failure * fix: fix transfer-spore test failure issue --- .github/workflows/integration-test.yaml | 18 ++ tests/rgbpp/package.json | 3 +- tests/rgbpp/shared/prepare-utxo.ts | 6 +- tests/rgbpp/shared/utils.ts | 19 +- tests/rgbpp/spore/4-transfer-spore.ts | 88 ++++++++++ tests/rgbpp/spore/5-leap-spore-to-ckb.ts | 89 ++++++++++ tests/rgbpp/spore/launch/0-cluster-info.ts | 6 + tests/rgbpp/spore/launch/1-prepare-cluster.ts | 82 +++++++++ tests/rgbpp/spore/launch/2-create-cluster.ts | 105 +++++++++++ tests/rgbpp/spore/launch/3-create-spores.ts | 163 ++++++++++++++++++ tests/rgbpp/xudt/1-ckb-leap-btc.ts | 6 +- tests/rgbpp/xudt/2-btc-transfer.ts | 6 +- tests/rgbpp/xudt/3-btc-leap-ckb.ts | 4 +- tests/rgbpp/xudt/xudt-on-ckb/1-issue-xudt.ts | 2 +- 14 files changed, 583 insertions(+), 14 deletions(-) create mode 100644 tests/rgbpp/spore/4-transfer-spore.ts create mode 100644 tests/rgbpp/spore/5-leap-spore-to-ckb.ts create mode 100644 tests/rgbpp/spore/launch/0-cluster-info.ts create mode 100644 tests/rgbpp/spore/launch/1-prepare-cluster.ts create mode 100644 tests/rgbpp/spore/launch/2-create-cluster.ts create mode 100644 tests/rgbpp/spore/launch/3-create-spores.ts diff --git a/.github/workflows/integration-test.yaml b/.github/workflows/integration-test.yaml index 1f40b504..82011340 100644 --- a/.github/workflows/integration-test.yaml +++ b/.github/workflows/integration-test.yaml @@ -17,6 +17,11 @@ concurrency: jobs: test: runs-on: ubuntu-latest + + strategy: + matrix: + env_set: [ xudt, spore ] + steps: - name: Checkout rgbpp-sdk uses: actions/checkout@v4 @@ -38,8 +43,10 @@ jobs: - name: Build packages run: pnpm run build:packages + - name: Run integration:xudt script working-directory: ./tests/rgbpp + if: ${{ matrix.env_set == 'xudt' }} run: pnpm run integration:xudt env: VITE_SERVICE_URL: ${{ secrets.SERVICE_URL }} @@ -47,3 +54,14 @@ jobs: VITE_SERVICE_ORIGIN: ${{ secrets.SERVICE_ORIGIN }} INTEGRATION_CKB_PRIVATE_KEY: ${{ secrets.INTEGRATION_CKB_PRIVATE_KEY }} INTEGRATION_BTC_PRIVATE_KEY: ${{ secrets.INTEGRATION_BTC_PRIVATE_KEY }} + + - name: Run integration:spore script + working-directory: ./tests/rgbpp + if: ${{ matrix.env_set == 'spore' }} + run: pnpm run integration:spore + env: + VITE_SERVICE_URL: ${{ secrets.SERVICE_URL }} + VITE_SERVICE_TOKEN: ${{ secrets.SERVICE_TOKEN }} + VITE_SERVICE_ORIGIN: ${{ secrets.SERVICE_ORIGIN }} + INTEGRATION_CKB_PRIVATE_KEY: ${{ secrets.INTEGRATION_CKB_SPORE_PRIVATE_KEY }} + INTEGRATION_BTC_PRIVATE_KEY: ${{ secrets.INTEGRATION_BTC_SPORE_PRIVATE_KEY }} diff --git a/tests/rgbpp/package.json b/tests/rgbpp/package.json index 33f834c2..5cd7d0bc 100644 --- a/tests/rgbpp/package.json +++ b/tests/rgbpp/package.json @@ -8,7 +8,8 @@ "format": "prettier --write '**/*.{js,ts}'", "lint": "tsc && eslint . && prettier --check '**/*.{js,ts}'", "lint:fix": "tsc && eslint --fix --ext .js,.ts . && prettier --write '**/*.{js,ts}'", - "integration:xudt": "npx ts-node shared/prepare-utxo.ts && npx ts-node xudt/xudt-on-ckb/1-issue-xudt.ts && npx ts-node xudt/1-ckb-leap-btc.ts && npx ts-node xudt/2-btc-transfer.ts && npx ts-node xudt/3-btc-leap-ckb.ts" + "integration:xudt": "npx ts-node shared/prepare-utxo.ts && npx ts-node xudt/xudt-on-ckb/1-issue-xudt.ts && npx ts-node xudt/1-ckb-leap-btc.ts && npx ts-node xudt/2-btc-transfer.ts && npx ts-node xudt/3-btc-leap-ckb.ts", + "integration:spore": "npx ts-node shared/prepare-utxo.ts && npx ts-node spore/launch/1-prepare-cluster.ts && npx ts-node spore/launch/2-create-cluster.ts && npx ts-node spore/launch/3-create-spores.ts && npx ts-node spore/4-transfer-spore.ts && npx ts-node spore/5-leap-spore-to-ckb.ts" }, "dependencies": { "@nervosnetwork/ckb-sdk-utils": "^0.109.1", diff --git a/tests/rgbpp/shared/prepare-utxo.ts b/tests/rgbpp/shared/prepare-utxo.ts index 582917d5..a10c9e4c 100644 --- a/tests/rgbpp/shared/prepare-utxo.ts +++ b/tests/rgbpp/shared/prepare-utxo.ts @@ -3,7 +3,7 @@ import { getFastestFeeRate, writeStepLog } from './utils'; import { BtcAssetsApiError } from 'rgbpp/service'; import { btcAddress, btcDataSource, btcKeyPair, btcService } from '../env'; -const prepareUtxo = async () => { +const prepareUtxo = async (index: string | number) => { const feeRate = await getFastestFeeRate(); console.log('feeRate = ', feeRate); console.log(btcAddress); @@ -33,7 +33,7 @@ const prepareUtxo = async () => { const { txid: btcTxId } = await btcService.sendBtcTransaction(tx.toHex()); console.log(`explorer: https://mempool.space/testnet/tx/${btcTxId}`); - writeStepLog('0', { + writeStepLog(String(index), { txid: btcTxId, index: 0, }); @@ -54,4 +54,4 @@ const prepareUtxo = async () => { }, 20 * 1000); }; -prepareUtxo(); +prepareUtxo('prepare-utxo'); diff --git a/tests/rgbpp/shared/utils.ts b/tests/rgbpp/shared/utils.ts index 79394338..7b49760f 100644 --- a/tests/rgbpp/shared/utils.ts +++ b/tests/rgbpp/shared/utils.ts @@ -21,5 +21,22 @@ export async function writeStepLog(step: string, data: string | object) { export function readStepLog(step: string) { const file = path.join(__dirname, `../${network}/step-${step}.log`); - return JSON.parse(fs.readFileSync(file).toString()); + const retryInterval = 10000; + const maxRetries = 3; + + for (let i = 0; i < 3; i++) { + try { + const data = fs.readFileSync(file, 'utf8'); + return JSON.parse(data); + } catch (error) { + console.error(`Failed to read file ${file} on attempt ${i + 1}: ${error}`); + if (i < maxRetries - 1) { + console.log(`Waiting ${retryInterval / 1000} seconds before retrying...`); + setTimeout(() => {}, retryInterval); + } + } + } + + console.error(`Failed to read file ${file} after ${maxRetries} attempts.`); + return null; } diff --git a/tests/rgbpp/spore/4-transfer-spore.ts b/tests/rgbpp/spore/4-transfer-spore.ts new file mode 100644 index 00000000..30d53c0a --- /dev/null +++ b/tests/rgbpp/spore/4-transfer-spore.ts @@ -0,0 +1,88 @@ +import { buildRgbppLockArgs } from 'rgbpp/ckb'; +import { genTransferSporeCkbVirtualTx, sendRgbppUtxos } from 'rgbpp'; +import { getSporeTypeScript, Hex } from 'rgbpp/ckb'; +import { serializeScript } from '@nervosnetwork/ckb-sdk-utils'; +import { isMainnet, collector, btcAddress, btcDataSource, btcKeyPair, btcService } from '../env'; +import { getFastestFeeRate, readStepLog } from '../shared/utils'; +import { saveCkbVirtualTxResult } from '../../../examples/rgbpp/shared/utils'; + +interface SporeTransferParams { + sporeRgbppLockArgs: Hex; + toBtcAddress: string; + sporeTypeArgs: Hex; +} + +const transferSpore = async ({ sporeRgbppLockArgs, toBtcAddress, sporeTypeArgs }: SporeTransferParams) => { + const { retry } = await import('zx'); + await retry(20, '10s', async () => { + const sporeTypeBytes = serializeScript({ + ...getSporeTypeScript(isMainnet), + args: sporeTypeArgs, + }); + + const feeRate = await getFastestFeeRate(); + console.log('feeRate = ', feeRate); + + const ckbVirtualTxResult = await genTransferSporeCkbVirtualTx({ + collector, + sporeRgbppLockArgs, + sporeTypeBytes, + isMainnet, + }); + + // Save ckbVirtualTxResult + saveCkbVirtualTxResult(ckbVirtualTxResult, '4-transfer-spore'); + + const { commitment, ckbRawTx, needPaymasterCell } = ckbVirtualTxResult; + + // Send BTC tx + const psbt = await sendRgbppUtxos({ + ckbVirtualTx: ckbRawTx, + commitment, + tos: [toBtcAddress], + needPaymaster: needPaymasterCell, + ckbCollector: collector, + from: btcAddress!, + source: btcDataSource, + feeRate: feeRate, + }); + psbt.signAllInputs(btcKeyPair); + psbt.finalizeAllInputs(); + + const btcTx = psbt.extractTransaction(); + const { txid: btcTxId } = await btcService.sendBtcTransaction(btcTx.toHex()); + + console.log('BTC TxId: ', btcTxId); + console.log(`explorer: https://mempool.space/testnet/tx/${btcTxId}`); + + await btcService.sendRgbppCkbTransaction({ btc_txid: btcTxId, ckb_virtual_result: ckbVirtualTxResult }); + + try { + const interval = setInterval(async () => { + const { state, failedReason } = await btcService.getRgbppTransactionState(btcTxId); + console.log('state', state); + if (state === 'completed' || state === 'failed') { + clearInterval(interval); + if (state === 'completed') { + const { txhash: txHash } = await btcService.getRgbppTransactionHash(btcTxId); + console.info(`Rgbpp spore has been transferred on BTC and the related CKB tx hash is ${txHash}`); + console.info(`explorer: https://pudge.explorer.nervos.org/transaction/${txHash}`); + } else { + console.warn(`Rgbpp CKB transaction failed and the reason is ${failedReason} `); + } + } + }, 30 * 1000); + } catch (error) { + console.error(error); + } + }); +}; + +// Please use your real BTC UTXO information on the BTC Testnet +// rgbppLockArgs: outIndexU32 + btcTxId +transferSpore({ + sporeRgbppLockArgs: buildRgbppLockArgs(2, readStepLog('create-spores-id').txid), + toBtcAddress: 'tb1qhp9fh9qsfeyh0yhewgu27ndqhs5qlrqwau28m7', + // Please use your own RGB++ spore asset's sporeTypeArgs + sporeTypeArgs: readStepLog('sporeTypeScripts')[0].args, +}); diff --git a/tests/rgbpp/spore/5-leap-spore-to-ckb.ts b/tests/rgbpp/spore/5-leap-spore-to-ckb.ts new file mode 100644 index 00000000..6346c088 --- /dev/null +++ b/tests/rgbpp/spore/5-leap-spore-to-ckb.ts @@ -0,0 +1,89 @@ +import { buildRgbppLockArgs } from 'rgbpp/ckb'; +import { genLeapSporeFromBtcToCkbVirtualTx, sendRgbppUtxos } from 'rgbpp'; +import { getSporeTypeScript, Hex } from 'rgbpp/ckb'; +import { serializeScript } from '@nervosnetwork/ckb-sdk-utils'; +import { isMainnet, collector, btcAddress, btcDataSource, btcKeyPair, btcService } from '../env'; +import { getFastestFeeRate, readStepLog } from '../shared/utils'; +import { saveCkbVirtualTxResult } from '../../../examples/rgbpp/shared/utils'; + +interface SporeLeapParams { + sporeRgbppLockArgs: Hex; + toCkbAddress: string; + sporeTypeArgs: Hex; +} + +const leapSporeFromBtcToCkb = async ({ sporeRgbppLockArgs, toCkbAddress, sporeTypeArgs }: SporeLeapParams) => { + const { retry } = await import('zx'); + await retry(20, '10s', async () => { + const sporeTypeBytes = serializeScript({ + ...getSporeTypeScript(isMainnet), + args: sporeTypeArgs, + }); + + const feeRate = await getFastestFeeRate(); + console.log('feeRate = ', feeRate); + + const ckbVirtualTxResult = await genLeapSporeFromBtcToCkbVirtualTx({ + collector, + sporeRgbppLockArgs, + sporeTypeBytes, + toCkbAddress, + isMainnet, + }); + + // Save ckbVirtualTxResult + saveCkbVirtualTxResult(ckbVirtualTxResult, '5-leap-spore-to-ckb'); + + const { commitment, ckbRawTx, needPaymasterCell } = ckbVirtualTxResult; + + // Send BTC tx + const psbt = await sendRgbppUtxos({ + ckbVirtualTx: ckbRawTx, + commitment, + tos: [btcAddress!], + needPaymaster: needPaymasterCell, + ckbCollector: collector, + from: btcAddress!, + source: btcDataSource, + feeRate: feeRate, + }); + psbt.signAllInputs(btcKeyPair); + psbt.finalizeAllInputs(); + + const btcTx = psbt.extractTransaction(); + const { txid: btcTxId } = await btcService.sendBtcTransaction(btcTx.toHex()); + + console.log('BTC TxId: ', btcTxId); + console.log(`explorer: https://mempool.space/testnet/tx/${btcTxId}`); + + await btcService.sendRgbppCkbTransaction({ btc_txid: btcTxId, ckb_virtual_result: ckbVirtualTxResult }); + + try { + const interval = setInterval(async () => { + const { state, failedReason } = await btcService.getRgbppTransactionState(btcTxId); + console.log('state', state); + if (state === 'completed' || state === 'failed') { + clearInterval(interval); + if (state === 'completed') { + const { txhash: txHash } = await btcService.getRgbppTransactionHash(btcTxId); + console.info(`Rgbpp spore has been leaped from BTC to CKB and the related CKB tx hash is ${txHash}`); + console.info(`explorer: https://pudge.explorer.nervos.org/transaction/${txHash}`); + } else { + console.warn(`Rgbpp CKB transaction failed and the reason is ${failedReason} `); + } + } + }, 30 * 1000); + } catch (error) { + console.error(error); + } + }); +}; + +// Please use your real BTC UTXO information on the BTC Testnet +// rgbppLockArgs: outIndexU32 + btcTxId +leapSporeFromBtcToCkb({ + sporeRgbppLockArgs: buildRgbppLockArgs(3, readStepLog('create-spores-id').txid), + toCkbAddress: 'ckt1qzda0cr08m85hc8jlnfp3zer7xulejywt49kt2rr0vthywaa50xwsq0e4xk4rmg5jdkn8aams492a7jlg73ue0gc0ddfj', + // Please use your own RGB++ spore asset's sporeTypeArgs + sporeTypeArgs: readStepLog('sporeTypeScripts')[1].args, +}); diff --git a/tests/rgbpp/spore/launch/0-cluster-info.ts b/tests/rgbpp/spore/launch/0-cluster-info.ts new file mode 100644 index 00000000..cd89d711 --- /dev/null +++ b/tests/rgbpp/spore/launch/0-cluster-info.ts @@ -0,0 +1,6 @@ +import { RawClusterData } from 'rgbpp/ckb'; + +export const CLUSTER_DATA: RawClusterData = { + name: 'Cluster name', + description: 'Description of the cluster', +}; diff --git a/tests/rgbpp/spore/launch/1-prepare-cluster.ts b/tests/rgbpp/spore/launch/1-prepare-cluster.ts new file mode 100644 index 00000000..76636543 --- /dev/null +++ b/tests/rgbpp/spore/launch/1-prepare-cluster.ts @@ -0,0 +1,82 @@ +import { addressToScript, getTransactionSize } from '@nervosnetwork/ckb-sdk-utils'; +import { + MAX_FEE, + NoLiveCellError, + SECP256K1_WITNESS_LOCK_SIZE, + append0x, + buildRgbppLockArgs, + calculateRgbppClusterCellCapacity, + calculateTransactionFee, + genRgbppLockScript, + getSecp256k1CellDep, +} from 'rgbpp/ckb'; +import { ckbAddress, isMainnet, collector, CKB_PRIVATE_KEY } from '../../env'; +import { CLUSTER_DATA } from './0-cluster-info'; +import { readStepLog } from '../../shared/utils'; + +const prepareClusterCell = async ({ outIndex, btcTxId }: { outIndex: number; btcTxId: string }) => { + const { retry } = await import('zx'); + await retry(20, '10s', async () => { + const masterLock = addressToScript(ckbAddress); + console.log('ckb address: ', ckbAddress); + + // The capacity required to launch cells is determined by the token info cell capacity, and transaction fee. + const clusterCellCapacity = calculateRgbppClusterCellCapacity(CLUSTER_DATA); + + let emptyCells = await collector.getCells({ + lock: masterLock, + }); + if (!emptyCells || emptyCells.length === 0) { + throw new NoLiveCellError('The address has no empty cells'); + } + emptyCells = emptyCells.filter((cell) => !cell.output.type); + + const txFee = MAX_FEE; + const { inputs, sumInputsCapacity } = collector.collectInputs(emptyCells, clusterCellCapacity, txFee); + + const outputs: CKBComponents.CellOutput[] = [ + { + lock: genRgbppLockScript(buildRgbppLockArgs(outIndex, btcTxId), isMainnet), + capacity: append0x(clusterCellCapacity.toString(16)), + }, + ]; + let changeCapacity = sumInputsCapacity - clusterCellCapacity; + outputs.push({ + lock: masterLock, + capacity: append0x(changeCapacity.toString(16)), + }); + const outputsData = ['0x', '0x']; + + const emptyWitness = { lock: '', inputType: '', outputType: '' }; + const witnesses = inputs.map((_, index) => (index === 0 ? emptyWitness : '0x')); + + const cellDeps = [getSecp256k1CellDep(isMainnet)]; + + const unsignedTx = { + version: '0x0', + cellDeps, + headerDeps: [], + inputs, + outputs, + outputsData, + witnesses, + }; + + const txSize = getTransactionSize(unsignedTx) + SECP256K1_WITNESS_LOCK_SIZE; + const estimatedTxFee = calculateTransactionFee(txSize); + changeCapacity -= estimatedTxFee; + unsignedTx.outputs[unsignedTx.outputs.length - 1].capacity = append0x(changeCapacity.toString(16)); + + const signedTx = collector.getCkb().signTransaction(CKB_PRIVATE_KEY)(unsignedTx); + const txHash = await collector.getCkb().rpc.sendTransaction(signedTx, 'passthrough'); + + console.info(`Cluster cell has been prepared and the tx hash ${txHash}`); + console.info(`explorer: https://pudge.explorer.nervos.org/transaction/${txHash}`); + }); +}; + +// Please use your real BTC UTXO information on the BTC Testnet +prepareClusterCell({ + outIndex: readStepLog('prepare-utxo').index, + btcTxId: readStepLog('prepare-utxo').txid, +}); diff --git a/tests/rgbpp/spore/launch/2-create-cluster.ts b/tests/rgbpp/spore/launch/2-create-cluster.ts new file mode 100644 index 00000000..4e5d9fe8 --- /dev/null +++ b/tests/rgbpp/spore/launch/2-create-cluster.ts @@ -0,0 +1,105 @@ +import { BtcAssetsApiError, genCreateClusterCkbVirtualTx, sendRgbppUtxos } from 'rgbpp'; +import { isMainnet, collector, btcAddress, btcDataSource, btcKeyPair, btcService } from '../../env'; +import { CLUSTER_DATA } from './0-cluster-info'; +import { transactionToHex } from 'rgbpp/btc'; +import { + appendCkbTxWitnesses, + buildRgbppLockArgs, + generateClusterCreateCoBuild, + sendCkbTx, + updateCkbTxWithRealBtcTxId, +} from 'rgbpp/ckb'; +import { getFastestFeeRate, readStepLog, writeStepLog } from '../../shared/utils'; +import { saveCkbVirtualTxResult } from '../../../../examples/rgbpp/shared/utils'; + +// Warning: Before runing this file, please run 1-prepare-cluster.ts +const createCluster = async ({ ownerRgbppLockArgs }: { ownerRgbppLockArgs: string }) => { + console.log(btcAddress); + const { retry } = await import('zx'); + await retry(20, '10s', async () => { + const feeRate = await getFastestFeeRate(); + console.log('feeRate = ', feeRate); + + const ckbVirtualTxResult = await genCreateClusterCkbVirtualTx({ + collector, + rgbppLockArgs: ownerRgbppLockArgs, + clusterData: CLUSTER_DATA, + isMainnet, + ckbFeeRate: BigInt(2000), + }); + + // Save ckbVirtualTxResult + saveCkbVirtualTxResult(ckbVirtualTxResult, '2-create-cluster'); + + const { commitment, ckbRawTx, clusterId, needPaymasterCell } = ckbVirtualTxResult; + + writeStepLog('clusterid', { + clusterid: clusterId, + }); + console.log('clusterId: ', clusterId); + + // Send BTC tx + const psbt = await sendRgbppUtxos({ + ckbVirtualTx: ckbRawTx, + commitment, + tos: [btcAddress!], + needPaymaster: needPaymasterCell, + ckbCollector: collector, + from: btcAddress!, + source: btcDataSource, + feeRate: feeRate, + }); + psbt.signAllInputs(btcKeyPair); + psbt.finalizeAllInputs(); + + const btcTx = psbt.extractTransaction(); + const btcTxBytes = transactionToHex(btcTx, false); + const { txid: btcTxId } = await btcService.sendBtcTransaction(btcTx.toHex()); + + writeStepLog('create-cluster-id', { + txid: btcTxId, + index: 1, + }); + console.log('BTC TxId: ', btcTxId); + console.log(`explorer: https://mempool.space/testnet/tx/${btcTxId}`); + + const interval = setInterval(async () => { + try { + console.log('Waiting for BTC tx and proof to be ready'); + const rgbppApiSpvProof = await btcService.getRgbppSpvProof(btcTxId, 0); + clearInterval(interval); + // Update CKB transaction with the real BTC txId + const newCkbRawTx = updateCkbTxWithRealBtcTxId({ ckbRawTx, btcTxId, isMainnet }); + + console.log('The cluster rgbpp lock args: ', newCkbRawTx.outputs[0].lock.args); + + const ckbTx = await appendCkbTxWitnesses({ + ckbRawTx: newCkbRawTx, + btcTxBytes, + rgbppApiSpvProof, + }); + // Replace cobuild witness with the final rgbpp lock script + ckbTx.witnesses[ckbTx.witnesses.length - 1] = generateClusterCreateCoBuild( + ckbTx.outputs[0], + ckbTx.outputsData[0], + ); + + console.log(JSON.stringify(ckbTx)); + + const txHash = await sendCkbTx({ collector, signedTx: ckbTx }); + console.info(`RGB++ Cluster has been created and tx hash is ${txHash}`); + console.info(`explorer: https://pudge.explorer.nervos.org/transaction/${txHash}`); + } catch (error) { + if (!(error instanceof BtcAssetsApiError)) { + console.error(error); + } + } + }, 30 * 1000); + }); +}; + +// Please use your real BTC UTXO information on the BTC Testnet which should be same as the 1-prepare-cluster.ts +// rgbppLockArgs: outIndexU32 + btcTxId +createCluster({ + ownerRgbppLockArgs: buildRgbppLockArgs(readStepLog('prepare-utxo').index, readStepLog('prepare-utxo').txid), +}); diff --git a/tests/rgbpp/spore/launch/3-create-spores.ts b/tests/rgbpp/spore/launch/3-create-spores.ts new file mode 100644 index 00000000..9f180407 --- /dev/null +++ b/tests/rgbpp/spore/launch/3-create-spores.ts @@ -0,0 +1,163 @@ +import { BtcAssetsApiError, genCreateSporeCkbVirtualTx, sendRgbppUtxos } from 'rgbpp'; +import { + isMainnet, + collector, + btcAddress, + btcDataSource, + btcKeyPair, + btcService, + CKB_PRIVATE_KEY, + ckbAddress, +} from '../../env'; +import { + Hex, + appendCkbTxWitnesses, + appendIssuerCellToSporesCreate, + buildRgbppLockArgs, + generateSporeCreateCoBuild, + sendCkbTx, + updateCkbTxWithRealBtcTxId, + RawSporeData, +} from 'rgbpp/ckb'; +import { transactionToHex, utf8ToBuffer } from 'rgbpp/btc'; +import { getFastestFeeRate, readStepLog, writeStepLog } from '../../shared/utils'; +import { saveCkbVirtualTxResult } from '../../../../examples/rgbpp/shared/utils'; + +interface SporeCreateParams { + clusterRgbppLockArgs: Hex; + receivers: { + toBtcAddress: string; + sporeData: RawSporeData; + }[]; +} + +// Warning: Before runing this file for the first time, please run 2-prepare-cluster.ts +const createSpores = async ({ clusterRgbppLockArgs, receivers }: SporeCreateParams) => { + const { retry } = await import('zx'); + await retry(20, '10s', async () => { + const feeRate = await getFastestFeeRate(); + console.log('feeRate = ', feeRate); + + const ckbVirtualTxResult = await genCreateSporeCkbVirtualTx({ + collector, + sporeDataList: receivers.map((receiver) => receiver.sporeData), + clusterRgbppLockArgs, + isMainnet, + ckbFeeRate: BigInt(2000), + }); + + // Save ckbVirtualTxResult + saveCkbVirtualTxResult(ckbVirtualTxResult, '3-create-spores'); + + const { commitment, ckbRawTx, sumInputsCapacity, clusterCell, needPaymasterCell } = ckbVirtualTxResult; + + // Send BTC tx + // The first btc address is the owner of the cluster cell and the rest btc addresses are spore receivers + const btcTos = [btcAddress!, ...receivers.map((receiver) => receiver.toBtcAddress)]; + const psbt = await sendRgbppUtxos({ + ckbVirtualTx: ckbRawTx, + commitment, + tos: btcTos, + needPaymaster: needPaymasterCell, + ckbCollector: collector, + from: btcAddress!, + source: btcDataSource, + feeRate: feeRate, + }); + psbt.signAllInputs(btcKeyPair); + psbt.finalizeAllInputs(); + + const btcTx = psbt.extractTransaction(); + const btcTxBytes = transactionToHex(btcTx, false); + const { txid: btcTxId } = await btcService.sendBtcTransaction(btcTx.toHex()); + + writeStepLog('create-spores-id', { + txid: btcTxId, + }); + console.log('BTC TxId: ', btcTxId); + console.log(`explorer: https://mempool.space/testnet/tx/${btcTxId}`); + + const interval = setInterval(async () => { + try { + console.log('Waiting for BTC tx and proof to be ready'); + const rgbppApiSpvProof = await btcService.getRgbppSpvProof(btcTxId, 0); + clearInterval(interval); + // Update CKB transaction with the real BTC txId + const newCkbRawTx = updateCkbTxWithRealBtcTxId({ ckbRawTx, btcTxId, isMainnet }); + console.log('The new cluster rgbpp lock args: ', newCkbRawTx.outputs[0].lock.args); + + const ckbTx = await appendCkbTxWitnesses({ + ckbRawTx: newCkbRawTx, + btcTxBytes, + rgbppApiSpvProof, + }); + + // The outputs[1..] are spore cells from which you can find spore type scripts, + // and the spore type scripts will be used to transfer and leap spores + const sporeTypeScripts = ckbTx.outputs.slice(1).map((output) => output.type); + console.log('Spore type scripts: ', JSON.stringify(sporeTypeScripts)); + writeStepLog('sporeTypeScripts', sporeTypeScripts); + + // Replace cobuild witness with the final rgbpp lock script + ckbTx.witnesses[ckbTx.witnesses.length - 1] = generateSporeCreateCoBuild({ + // The first output is cluster cell and the rest of the outputs are spore cells + sporeOutputs: ckbTx.outputs.slice(1), + sporeOutputsData: ckbTx.outputsData.slice(1), + clusterCell, + clusterOutputCell: ckbTx.outputs[0], + }); + + // console.log('ckbTx: ', JSON.stringify(ckbTx)); + + const signedTx = await appendIssuerCellToSporesCreate({ + secp256k1PrivateKey: CKB_PRIVATE_KEY, + issuerAddress: ckbAddress, + ckbRawTx: ckbTx, + collector, + sumInputsCapacity, + isMainnet, + }); + + const txHash = await sendCkbTx({ collector, signedTx }); + console.info(`RGB++ Spore has been created and tx hash is ${txHash}`); + console.info(`explorer: https://pudge.explorer.nervos.org/transaction/${txHash}`); + } catch (error) { + if (!(error instanceof BtcAssetsApiError)) { + console.error(error); + } + } + }, 30 * 1000); + }); +}; + +// Please use your real BTC UTXO information on the BTC Testnet +// rgbppLockArgs: outIndexU32 + btcTxId +createSpores({ + // The cluster cell will be spent and the new cluster cell will be created in each spore creation tx, + // so the cluster rgbpp lock args should be updated after each spore creation tx is completed. + // The first cluster rgbpp lock args is from 2-create-cluster.ts and the new cluster rgbpp lock args can be found from the log in the line 71 of this file + clusterRgbppLockArgs: buildRgbppLockArgs( + readStepLog('create-cluster-id').index, + readStepLog('create-cluster-id').txid, + ), + receivers: [ + { + toBtcAddress: 'tb1qssu8pscsuevnmvhnr08840wvuzdan27k9m46ja', + sporeData: { + contentType: 'text/plain', + content: utf8ToBuffer('First Spore'), + // The cluster id is from 2-create-cluster.ts + clusterId: readStepLog('clusterid').clusterid, + }, + }, + { + toBtcAddress: 'tb1qssu8pscsuevnmvhnr08840wvuzdan27k9m46ja', + sporeData: { + contentType: 'text/plain', + content: utf8ToBuffer('Second Spore'), + // The cluster id is from 2-create-cluster.ts + clusterId: readStepLog('clusterid').clusterid, + }, + }, + ], +}); diff --git a/tests/rgbpp/xudt/1-ckb-leap-btc.ts b/tests/rgbpp/xudt/1-ckb-leap-btc.ts index 93401b91..340e02b4 100644 --- a/tests/rgbpp/xudt/1-ckb-leap-btc.ts +++ b/tests/rgbpp/xudt/1-ckb-leap-btc.ts @@ -47,8 +47,8 @@ const leapFromCkbToBtc = async ({ outIndex, btcTxId, xudtTypeArgs, transferAmoun // Use your real BTC UTXO information on the BTC Testnet leapFromCkbToBtc({ - outIndex: readStepLog('0').index, - btcTxId: readStepLog('0').txid, - xudtTypeArgs: readStepLog('1').args, + outIndex: readStepLog('prepare-utxo').index, + btcTxId: readStepLog('prepare-utxo').txid, + xudtTypeArgs: readStepLog('xUDT-type-script').args, transferAmount: BigInt(800_0000_0000), }); diff --git a/tests/rgbpp/xudt/2-btc-transfer.ts b/tests/rgbpp/xudt/2-btc-transfer.ts index 884697eb..d1f7a7ff 100644 --- a/tests/rgbpp/xudt/2-btc-transfer.ts +++ b/tests/rgbpp/xudt/2-btc-transfer.ts @@ -47,7 +47,7 @@ const transfer = async ({ rgbppLockArgsList, toBtcAddress, xudtTypeArgs, transfe console.log('BTC TxId: ', btcTxId); console.log(`explorer: https://mempool.space/testnet/tx/${btcTxId}`); - writeStepLog('2', { + writeStepLog('transfer-id', { txid: btcTxId, index: 1, }); @@ -78,8 +78,8 @@ const transfer = async ({ rgbppLockArgsList, toBtcAddress, xudtTypeArgs, transfe // Use your real BTC UTXO information on the BTC Testnet // rgbppLockArgs: outIndexU32 + btcTxId transfer({ - rgbppLockArgsList: [buildRgbppLockArgs(readStepLog('0').index, readStepLog('0').txid)], + rgbppLockArgsList: [buildRgbppLockArgs(readStepLog('prepare-utxo').index, readStepLog('prepare-utxo').txid)], toBtcAddress: 'tb1qtt2vh9q8xam35xxsy35ec6majad8lz8fep8w04', - xudtTypeArgs: readStepLog('1').args, + xudtTypeArgs: readStepLog('xUDT-type-script').args, transferAmount: BigInt(500_0000_0000), }); diff --git a/tests/rgbpp/xudt/3-btc-leap-ckb.ts b/tests/rgbpp/xudt/3-btc-leap-ckb.ts index 578dafcc..5f2c752f 100644 --- a/tests/rgbpp/xudt/3-btc-leap-ckb.ts +++ b/tests/rgbpp/xudt/3-btc-leap-ckb.ts @@ -73,8 +73,8 @@ const leapFromBtcToCKB = async ({ rgbppLockArgsList, toCkbAddress, xudtTypeArgs, // rgbppLockArgs: outIndexU32 + btcTxId leapFromBtcToCKB({ - rgbppLockArgsList: [buildRgbppLockArgs(readStepLog('2').index, readStepLog('2').txid)], + rgbppLockArgsList: [buildRgbppLockArgs(readStepLog('transfer-id').index, readStepLog('transfer-id').txid)], toCkbAddress: 'ckt1qrfrwcdnvssswdwpn3s9v8fp87emat306ctjwsm3nmlkjg8qyza2cqgqq9kxr7vy7yknezj0vj0xptx6thk6pwyr0sxamv6q', - xudtTypeArgs: readStepLog('1').args, + xudtTypeArgs: readStepLog('xUDT-type-script').args, transferAmount: BigInt(300_0000_0000), }); diff --git a/tests/rgbpp/xudt/xudt-on-ckb/1-issue-xudt.ts b/tests/rgbpp/xudt/xudt-on-ckb/1-issue-xudt.ts index 5430e4b7..522d9ff2 100644 --- a/tests/rgbpp/xudt/xudt-on-ckb/1-issue-xudt.ts +++ b/tests/rgbpp/xudt/xudt-on-ckb/1-issue-xudt.ts @@ -52,7 +52,7 @@ const issueXudt = async ({ xudtTotalAmount, tokenInfo }: { xudtTotalAmount: bigi console.log('xUDT type script', xudtType); - writeStepLog('1', { + writeStepLog('xUDT-type-script', { codeHash: xudtType.codeHash, hashType: xudtType.hashType, args: xudtType.args, From 90d8642a9cc8bf844bc96ba6586a5e4ae2e2d7a5 Mon Sep 17 00:00:00 2001 From: ahonn Date: Tue, 4 Jun 2024 17:26:34 +1000 Subject: [PATCH 18/90] feat: add basic rgbpp-sdk-service JSON-RPC impl --- apps/service/.gitignore | 56 + apps/service/nest-cli.json | 8 + apps/service/package.json | 64 + apps/service/src/app.module.ts | 13 + .../src/json-rpc/json-rpc.decorators.ts | 20 + apps/service/src/json-rpc/json-rpc.module.ts | 41 + apps/service/src/json-rpc/json-rpc.server.ts | 64 + apps/service/src/main.ts | 8 + apps/service/src/rgbpp/rgbpp.module.ts | 8 + apps/service/src/rgbpp/rgbpp.service.ts | 10 + apps/service/tsconfig.build.json | 4 + apps/service/tsconfig.json | 21 + package.json | 3 +- pnpm-lock.yaml | 3106 ++++++++++++++++- 14 files changed, 3355 insertions(+), 71 deletions(-) create mode 100644 apps/service/.gitignore create mode 100644 apps/service/nest-cli.json create mode 100644 apps/service/package.json create mode 100644 apps/service/src/app.module.ts create mode 100644 apps/service/src/json-rpc/json-rpc.decorators.ts create mode 100644 apps/service/src/json-rpc/json-rpc.module.ts create mode 100644 apps/service/src/json-rpc/json-rpc.server.ts create mode 100644 apps/service/src/main.ts create mode 100644 apps/service/src/rgbpp/rgbpp.module.ts create mode 100644 apps/service/src/rgbpp/rgbpp.service.ts create mode 100644 apps/service/tsconfig.build.json create mode 100644 apps/service/tsconfig.json diff --git a/apps/service/.gitignore b/apps/service/.gitignore new file mode 100644 index 00000000..4b56acfb --- /dev/null +++ b/apps/service/.gitignore @@ -0,0 +1,56 @@ +# compiled output +/dist +/node_modules +/build + +# Logs +logs +*.log +npm-debug.log* +pnpm-debug.log* +yarn-debug.log* +yarn-error.log* +lerna-debug.log* + +# OS +.DS_Store + +# Tests +/coverage +/.nyc_output + +# IDEs and editors +/.idea +.project +.classpath +.c9/ +*.launch +.settings/ +*.sublime-workspace + +# IDE - VSCode +.vscode/* +!.vscode/settings.json +!.vscode/tasks.json +!.vscode/launch.json +!.vscode/extensions.json + +# dotenv environment variable files +.env +.env.development.local +.env.test.local +.env.production.local +.env.local + +# temp directory +.temp +.tmp + +# Runtime data +pids +*.pid +*.seed +*.pid.lock + +# Diagnostic reports (https://nodejs.org/api/report.html) +report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json diff --git a/apps/service/nest-cli.json b/apps/service/nest-cli.json new file mode 100644 index 00000000..f9aa683b --- /dev/null +++ b/apps/service/nest-cli.json @@ -0,0 +1,8 @@ +{ + "$schema": "https://json.schemastore.org/nest-cli", + "collection": "@nestjs/schematics", + "sourceRoot": "src", + "compilerOptions": { + "deleteOutDir": true + } +} diff --git a/apps/service/package.json b/apps/service/package.json new file mode 100644 index 00000000..6ef5b6b2 --- /dev/null +++ b/apps/service/package.json @@ -0,0 +1,64 @@ +{ + "name": "rgbpp-sdk-service", + "version": "0.0.1", + "description": "", + "author": "", + "private": true, + "license": "UNLICENSED", + "scripts": { + "build": "nest build", + "format": "prettier --write \"src/**/*.ts\" \"test/**/*.ts\"", + "dev": "pnpm run start:dev", + "start": "nest start", + "start:dev": "nest start --watch", + "start:debug": "nest start --debug --watch", + "start:prod": "node dist/main", + "lint": "eslint \"{src,apps,libs,test}/**/*.ts\" --fix", + "test": "jest", + "test:watch": "jest --watch", + "test:cov": "jest --coverage", + "test:debug": "node --inspect-brk -r tsconfig-paths/register -r ts-node/register node_modules/.bin/jest --runInBand", + "test:e2e": "jest --config ./test/jest-e2e.json" + }, + "dependencies": { + "@nestjs/common": "^10.0.0", + "@nestjs/core": "^10.0.0", + "@nestjs/platform-express": "^10.0.0", + "json-rpc-2.0": "^1.7.0", + "reflect-metadata": "^0.2.0", + "rxjs": "^7.8.1" + }, + "devDependencies": { + "@nestjs/cli": "^10.0.0", + "@nestjs/schematics": "^10.0.0", + "@nestjs/testing": "^10.0.0", + "@types/express": "^4.17.17", + "@types/jest": "^29.5.2", + "@types/node": "^20.3.1", + "@types/supertest": "^6.0.0", + "source-map-support": "^0.5.21", + "supertest": "^6.3.3", + "ts-jest": "^29.1.0", + "ts-loader": "^9.4.3", + "ts-node": "^10.9.1", + "tsconfig-paths": "^4.2.0", + "typescript": "^5.1.3" + }, + "jest": { + "moduleFileExtensions": [ + "js", + "json", + "ts" + ], + "rootDir": "src", + "testRegex": ".*\\.spec\\.ts$", + "transform": { + "^.+\\.(t|j)s$": "ts-jest" + }, + "collectCoverageFrom": [ + "**/*.(t|j)s" + ], + "coverageDirectory": "../coverage", + "testEnvironment": "node" + } +} diff --git a/apps/service/src/app.module.ts b/apps/service/src/app.module.ts new file mode 100644 index 00000000..47454009 --- /dev/null +++ b/apps/service/src/app.module.ts @@ -0,0 +1,13 @@ +import { Module } from '@nestjs/common'; +import JsonRpcModule from './json-rpc/json-rpc.module'; +import { RgbppModule } from './rgbpp/rgbpp.module'; + +@Module({ + imports: [ + JsonRpcModule.forRoot({ + path: '/json-rpc', + }), + RgbppModule, + ], +}) +export class AppModule {} diff --git a/apps/service/src/json-rpc/json-rpc.decorators.ts b/apps/service/src/json-rpc/json-rpc.decorators.ts new file mode 100644 index 00000000..5f054ced --- /dev/null +++ b/apps/service/src/json-rpc/json-rpc.decorators.ts @@ -0,0 +1,20 @@ +import { applyDecorators, Injectable, InjectableOptions, SetMetadata } from '@nestjs/common'; + +export const JsonRpcMetadataKey = '__json-rpc@metadata__'; +export interface JsonRpcMetadata { + name: string; +} + +export const JsonRpcMethodMetadataKey = '__json-rpc-method@metadata__'; +export interface JsonRpcMethodMetadata { + name?: string; +} + +export const RpcHandler = (data: JsonRpcMetadata & InjectableOptions) => { + const { name, scope } = data; + return applyDecorators(SetMetadata(JsonRpcMetadataKey, { name }), Injectable({ scope })); +}; + +export const RpcMethodHandler = (data?: JsonRpcMethodMetadata) => { + return applyDecorators(SetMetadata(JsonRpcMethodMetadataKey, data ?? {})); +}; diff --git a/apps/service/src/json-rpc/json-rpc.module.ts b/apps/service/src/json-rpc/json-rpc.module.ts new file mode 100644 index 00000000..4bf9b06f --- /dev/null +++ b/apps/service/src/json-rpc/json-rpc.module.ts @@ -0,0 +1,41 @@ +import { Inject, Logger, Module, OnModuleInit } from '@nestjs/common'; +import { JsonRpcServer } from './json-rpc.server'; +import { NestContainer } from '@nestjs/core'; + +export const JSON_RPC_OPTIONS = '__JSON_RPC_OPTIONS__'; + +export interface JsonRpcConfig { + path: string; +} + +@Module({ + providers: [NestContainer], +}) +export class JsonRpcModule implements OnModuleInit { + private logger = new Logger(JsonRpcModule.name); + + constructor( + @Inject(JSON_RPC_OPTIONS) private config: JsonRpcConfig, + private jsonRpcServer: JsonRpcServer, + ) {} + + public static forRoot(config: JsonRpcConfig) { + return { + module: JsonRpcModule, + providers: [ + { + provide: JSON_RPC_OPTIONS, + useValue: config, + }, + JsonRpcServer, + ], + }; + } + + public async onModuleInit() { + this.jsonRpcServer.run(this.config); + this.logger.log(`JSON-RPC server is running on ${this.config.path}`); + } +} + +export default JsonRpcModule; diff --git a/apps/service/src/json-rpc/json-rpc.server.ts b/apps/service/src/json-rpc/json-rpc.server.ts new file mode 100644 index 00000000..cafae837 --- /dev/null +++ b/apps/service/src/json-rpc/json-rpc.server.ts @@ -0,0 +1,64 @@ +import { Injectable } from '@nestjs/common'; +import { HttpAdapterHost, ModulesContainer } from '@nestjs/core'; +import { JSONRPCServer, SimpleJSONRPCMethod } from 'json-rpc-2.0'; +import { InstanceWrapper } from '@nestjs/core/injector/instance-wrapper'; +import { JsonRpcMetadataKey, JsonRpcMethodMetadataKey } from './json-rpc.decorators'; +import { JsonRpcConfig } from './json-rpc.module'; + +@Injectable() +export class JsonRpcServer { + private server: JSONRPCServer; + + constructor( + private httpAdapterHost: HttpAdapterHost, + private modulesContainer: ModulesContainer, + ) { + this.server = new JSONRPCServer(); + + const handlers = this.getRegisteredHandlers(); + handlers.forEach((handler, name) => { + this.server.addMethod(name, handler); + }); + console.log(this.server); + } + + private getRegisteredHandlers() { + const modules = [...this.modulesContainer.values()]; + const wrappers = modules.reduce( + (providers, module) => providers.concat([...module.providers.values()]), + [] as InstanceWrapper[], + ); + + const rpcHandlers = new Map>(); + wrappers.forEach((wrapper) => { + const { instance } = wrapper; + if (!instance) { + return; + } + const metadata = Reflect.getMetadata(JsonRpcMetadataKey, instance.constructor); + if (!metadata) { + return; + } + + const methodNames = Object.getOwnPropertyNames(Object.getPrototypeOf(instance)); + methodNames.forEach((methodName) => { + const methodMetadata = Reflect.getMetadata(JsonRpcMethodMetadataKey, instance[methodName]); + if (!methodMetadata) { + return; + } + const name = `${metadata.name}.${methodMetadata.name ?? methodName}`; + const handler = instance[methodName].bind(instance); + rpcHandlers.set(name, handler); + }); + }); + return rpcHandlers; + } + + public async run(config: JsonRpcConfig) { + this.httpAdapterHost.httpAdapter.post(config.path, async (req, res) => { + const jsonRpcResponse = await this.server.receive(req.body); + this.httpAdapterHost.httpAdapter.setHeader(res, 'Content-Type', 'application/json'); + this.httpAdapterHost.httpAdapter.reply(res, jsonRpcResponse); + }); + } +} diff --git a/apps/service/src/main.ts b/apps/service/src/main.ts new file mode 100644 index 00000000..13cad38c --- /dev/null +++ b/apps/service/src/main.ts @@ -0,0 +1,8 @@ +import { NestFactory } from '@nestjs/core'; +import { AppModule } from './app.module'; + +async function bootstrap() { + const app = await NestFactory.create(AppModule); + await app.listen(3000); +} +bootstrap(); diff --git a/apps/service/src/rgbpp/rgbpp.module.ts b/apps/service/src/rgbpp/rgbpp.module.ts new file mode 100644 index 00000000..bdfec8a5 --- /dev/null +++ b/apps/service/src/rgbpp/rgbpp.module.ts @@ -0,0 +1,8 @@ +import { Module } from '@nestjs/common'; +import { RgbppService } from './rgbpp.service'; + +@Module({ + imports: [], + providers: [RgbppService], +}) +export class RgbppModule {} diff --git a/apps/service/src/rgbpp/rgbpp.service.ts b/apps/service/src/rgbpp/rgbpp.service.ts new file mode 100644 index 00000000..2eb6d4f2 --- /dev/null +++ b/apps/service/src/rgbpp/rgbpp.service.ts @@ -0,0 +1,10 @@ +import { RpcHandler, RpcMethodHandler } from 'src/json-rpc/json-rpc.decorators'; + +@RpcHandler({ name: 'rgbpp' }) +export class RgbppService { + @RpcMethodHandler({ name: 'hello' }) + public getHello(params: unknown): string { + console.log(params); + return 'Hello World!'; + } +} diff --git a/apps/service/tsconfig.build.json b/apps/service/tsconfig.build.json new file mode 100644 index 00000000..64f86c6b --- /dev/null +++ b/apps/service/tsconfig.build.json @@ -0,0 +1,4 @@ +{ + "extends": "./tsconfig.json", + "exclude": ["node_modules", "test", "dist", "**/*spec.ts"] +} diff --git a/apps/service/tsconfig.json b/apps/service/tsconfig.json new file mode 100644 index 00000000..95f5641c --- /dev/null +++ b/apps/service/tsconfig.json @@ -0,0 +1,21 @@ +{ + "compilerOptions": { + "module": "commonjs", + "declaration": true, + "removeComments": true, + "emitDecoratorMetadata": true, + "experimentalDecorators": true, + "allowSyntheticDefaultImports": true, + "target": "ES2021", + "sourceMap": true, + "outDir": "./dist", + "baseUrl": "./", + "incremental": true, + "skipLibCheck": true, + "strictNullChecks": false, + "noImplicitAny": false, + "strictBindCallApply": false, + "forceConsistentCasingInFileNames": false, + "noFallthroughCasesInSwitch": false + } +} diff --git a/package.json b/package.json index f9543082..478dc13b 100644 --- a/package.json +++ b/package.json @@ -8,6 +8,7 @@ "prepare": "husky", "test:packages": "turbo run test --filter=./packages/*", "build:packages": "turbo run build --filter=./packages/*", + "dev:service": "turbo run dev --filter=./apps/service", "lint:fix": "turbo run lint:fix", "lint:packages": "turbo run lint --filter=./{packages,examples,tests}/*", "format": "prettier --write '{packages,apps,examples,tests}/**/*.{js,jsx,ts,tsx}'", @@ -19,8 +20,8 @@ }, "devDependencies": { "@changesets/cli": "^2.27.1", - "@changesets/types": "^6.0.0", "@changesets/get-github-info": "^0.6.0", + "@changesets/types": "^6.0.0", "@typescript-eslint/eslint-plugin": "^7.8.0", "@typescript-eslint/parser": "^7.8.0", "eslint": "^8.56.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 2c5c92e0..0bf1e976 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -82,6 +82,70 @@ importers: specifier: ^5 version: 5.4.2 + apps/service: + dependencies: + '@nestjs/common': + specifier: ^10.0.0 + version: 10.3.9(reflect-metadata@0.2.2)(rxjs@7.8.1) + '@nestjs/core': + specifier: ^10.0.0 + version: 10.3.9(@nestjs/common@10.3.9)(@nestjs/platform-express@10.3.9)(reflect-metadata@0.2.2)(rxjs@7.8.1) + '@nestjs/platform-express': + specifier: ^10.0.0 + version: 10.3.9(@nestjs/common@10.3.9)(@nestjs/core@10.3.9) + json-rpc-2.0: + specifier: ^1.7.0 + version: 1.7.0 + reflect-metadata: + specifier: ^0.2.0 + version: 0.2.2 + rxjs: + specifier: ^7.8.1 + version: 7.8.1 + devDependencies: + '@nestjs/cli': + specifier: ^10.0.0 + version: 10.3.2 + '@nestjs/schematics': + specifier: ^10.0.0 + version: 10.1.1(typescript@5.4.3) + '@nestjs/testing': + specifier: ^10.0.0 + version: 10.3.9(@nestjs/common@10.3.9)(@nestjs/core@10.3.9)(@nestjs/platform-express@10.3.9) + '@types/express': + specifier: ^4.17.17 + version: 4.17.21 + '@types/jest': + specifier: ^29.5.2 + version: 29.5.12 + '@types/node': + specifier: ^20.3.1 + version: 20.12.12 + '@types/supertest': + specifier: ^6.0.0 + version: 6.0.2 + source-map-support: + specifier: ^0.5.21 + version: 0.5.21 + supertest: + specifier: ^6.3.3 + version: 6.3.4 + ts-jest: + specifier: ^29.1.0 + version: 29.1.4(@babel/core@7.24.0)(jest@29.7.0)(typescript@5.4.3) + ts-loader: + specifier: ^9.4.3 + version: 9.5.1(typescript@5.4.3)(webpack@5.91.0) + ts-node: + specifier: ^10.9.1 + version: 10.9.2(@types/node@20.12.12)(typescript@5.4.3) + tsconfig-paths: + specifier: ^4.2.0 + version: 4.2.0 + typescript: + specifier: ^5.1.3 + version: 5.4.3 + apps/vite: dependencies: '@rgbpp-sdk/btc': @@ -338,6 +402,52 @@ packages: '@jridgewell/trace-mapping': 0.3.25 dev: true + /@angular-devkit/core@17.1.2(chokidar@3.6.0): + resolution: {integrity: sha512-ku+/W/HMCBacSWFppenr9y6Lx8mDuTuQvn1IkTyBLiJOpWnzgVbx9kHDeaDchGa1PwLlJUBBrv27t3qgJOIDPw==} + engines: {node: ^18.13.0 || >=20.9.0, npm: ^6.11.0 || ^7.5.6 || >=8.0.0, yarn: '>= 1.13.0'} + peerDependencies: + chokidar: ^3.5.2 + peerDependenciesMeta: + chokidar: + optional: true + dependencies: + ajv: 8.12.0 + ajv-formats: 2.1.1(ajv@8.12.0) + chokidar: 3.6.0 + jsonc-parser: 3.2.0 + picomatch: 3.0.1 + rxjs: 7.8.1 + source-map: 0.7.4 + dev: true + + /@angular-devkit/schematics-cli@17.1.2(chokidar@3.6.0): + resolution: {integrity: sha512-bvXykYzSST05qFdlgIzUguNOb3z0hCa8HaTwtqdmQo9aFPf+P+/AC56I64t1iTchMjQtf3JrBQhYM25gUdcGbg==} + engines: {node: ^18.13.0 || >=20.9.0, npm: ^6.11.0 || ^7.5.6 || >=8.0.0, yarn: '>= 1.13.0'} + hasBin: true + dependencies: + '@angular-devkit/core': 17.1.2(chokidar@3.6.0) + '@angular-devkit/schematics': 17.1.2(chokidar@3.6.0) + ansi-colors: 4.1.3 + inquirer: 9.2.12 + symbol-observable: 4.0.0 + yargs-parser: 21.1.1 + transitivePeerDependencies: + - chokidar + dev: true + + /@angular-devkit/schematics@17.1.2(chokidar@3.6.0): + resolution: {integrity: sha512-8S9RuM8olFN/gwN+mjbuF1CwHX61f0i59EGXz9tXLnKRUTjsRR+8vVMTAmX0dvVAT5fJTG/T69X+HX7FeumdqA==} + engines: {node: ^18.13.0 || >=20.9.0, npm: ^6.11.0 || ^7.5.6 || >=8.0.0, yarn: '>= 1.13.0'} + dependencies: + '@angular-devkit/core': 17.1.2(chokidar@3.6.0) + jsonc-parser: 3.2.0 + magic-string: 0.30.5 + ora: 5.4.1 + rxjs: 7.8.1 + transitivePeerDependencies: + - chokidar + dev: true + /@babel/code-frame@7.23.5: resolution: {integrity: sha512-CgH3s1a96LipHCmSUmYFPwY7MNx8C3avkq7i4Wl3cfa662ldtUe4VM1TPXX70pfmrlWTb6jLqTYrZyT2ZTJBgA==} engines: {node: '>=6.9.0'} @@ -449,6 +559,11 @@ packages: engines: {node: '>=6.9.0'} dev: true + /@babel/helper-plugin-utils@7.24.6: + resolution: {integrity: sha512-MZG/JcWfxybKwsA9N9PmtF2lOSFSEMVCpIRrbxccZFLJPrJciJdG/UhSh5W96GEteJI2ARqm5UAHxISwRDLSNg==} + engines: {node: '>=6.9.0'} + dev: true + /@babel/helper-simple-access@7.22.5: resolution: {integrity: sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w==} engines: {node: '>=6.9.0'} @@ -516,6 +631,135 @@ packages: '@babel/types': 7.24.0 dev: true + /@babel/plugin-syntax-async-generators@7.8.4(@babel/core@7.24.0): + resolution: {integrity: sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.24.0 + '@babel/helper-plugin-utils': 7.24.0 + dev: true + + /@babel/plugin-syntax-bigint@7.8.3(@babel/core@7.24.0): + resolution: {integrity: sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.24.0 + '@babel/helper-plugin-utils': 7.24.0 + dev: true + + /@babel/plugin-syntax-class-properties@7.12.13(@babel/core@7.24.0): + resolution: {integrity: sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.24.0 + '@babel/helper-plugin-utils': 7.24.0 + dev: true + + /@babel/plugin-syntax-import-meta@7.10.4(@babel/core@7.24.0): + resolution: {integrity: sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.24.0 + '@babel/helper-plugin-utils': 7.24.0 + dev: true + + /@babel/plugin-syntax-json-strings@7.8.3(@babel/core@7.24.0): + resolution: {integrity: sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.24.0 + '@babel/helper-plugin-utils': 7.24.0 + dev: true + + /@babel/plugin-syntax-jsx@7.24.6(@babel/core@7.24.0): + resolution: {integrity: sha512-lWfvAIFNWMlCsU0DRUun2GpFwZdGTukLaHJqRh1JRb80NdAP5Sb1HDHB5X9P9OtgZHQl089UzQkpYlBq2VTPRw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.24.0 + '@babel/helper-plugin-utils': 7.24.6 + dev: true + + /@babel/plugin-syntax-logical-assignment-operators@7.10.4(@babel/core@7.24.0): + resolution: {integrity: sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.24.0 + '@babel/helper-plugin-utils': 7.24.0 + dev: true + + /@babel/plugin-syntax-nullish-coalescing-operator@7.8.3(@babel/core@7.24.0): + resolution: {integrity: sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.24.0 + '@babel/helper-plugin-utils': 7.24.0 + dev: true + + /@babel/plugin-syntax-numeric-separator@7.10.4(@babel/core@7.24.0): + resolution: {integrity: sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.24.0 + '@babel/helper-plugin-utils': 7.24.0 + dev: true + + /@babel/plugin-syntax-object-rest-spread@7.8.3(@babel/core@7.24.0): + resolution: {integrity: sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.24.0 + '@babel/helper-plugin-utils': 7.24.0 + dev: true + + /@babel/plugin-syntax-optional-catch-binding@7.8.3(@babel/core@7.24.0): + resolution: {integrity: sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.24.0 + '@babel/helper-plugin-utils': 7.24.0 + dev: true + + /@babel/plugin-syntax-optional-chaining@7.8.3(@babel/core@7.24.0): + resolution: {integrity: sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.24.0 + '@babel/helper-plugin-utils': 7.24.0 + dev: true + + /@babel/plugin-syntax-top-level-await@7.14.5(@babel/core@7.24.0): + resolution: {integrity: sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.24.0 + '@babel/helper-plugin-utils': 7.24.0 + dev: true + + /@babel/plugin-syntax-typescript@7.24.6(@babel/core@7.24.0): + resolution: {integrity: sha512-TzCtxGgVTEJWWwcYwQhCIQ6WaKlo80/B+Onsk4RRCcYqpYGFcG9etPW94VToGte5AAcxRrhjPUFvUS3Y2qKi4A==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.24.0 + '@babel/helper-plugin-utils': 7.24.6 + dev: true + /@babel/plugin-transform-react-jsx-self@7.23.3(@babel/core@7.24.0): resolution: {integrity: sha512-qXRvbeKDSfwnlJnanVRp0SfuWE5DQhwQr5xtLBzp56Wabyo+4CMosF6Kfp+eOD/4FYpql64XVJ2W0pVLlJZxOQ==} engines: {node: '>=6.9.0'} @@ -579,6 +823,10 @@ packages: to-fast-properties: 2.0.0 dev: true + /@bcoe/v8-coverage@0.2.3: + resolution: {integrity: sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==} + dev: true + /@bitcoinerlab/secp256k1@1.1.1: resolution: {integrity: sha512-uhjW51WfVLpnHN7+G0saDcM/k9IqcyTbZ+bDgLF3AX8V/a3KXSE9vn7UPBrcdU72tp0J4YPR7BHp2m7MLAZ/1Q==} dependencies: @@ -996,6 +1244,13 @@ packages: - encoding dev: false + /@colors/colors@1.5.0: + resolution: {integrity: sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==} + engines: {node: '>=0.1.90'} + requiresBuild: true + dev: true + optional: true + /@cspotcode/source-map-support@0.8.1: resolution: {integrity: sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==} engines: {node: '>=12'} @@ -1284,6 +1539,165 @@ packages: wrap-ansi-cjs: /wrap-ansi@7.0.0 dev: true + /@istanbuljs/load-nyc-config@1.1.0: + resolution: {integrity: sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==} + engines: {node: '>=8'} + dependencies: + camelcase: 5.3.1 + find-up: 4.1.0 + get-package-type: 0.1.0 + js-yaml: 3.14.1 + resolve-from: 5.0.0 + dev: true + + /@istanbuljs/schema@0.1.3: + resolution: {integrity: sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==} + engines: {node: '>=8'} + dev: true + + /@jest/console@29.7.0: + resolution: {integrity: sha512-5Ni4CU7XHQi32IJ398EEP4RrB8eV09sXP2ROqD4bksHrnTree52PsxvX8tpL8LvTZ3pFzXyPbNQReSN41CAhOg==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@jest/types': 29.6.3 + '@types/node': 20.12.12 + chalk: 4.1.2 + jest-message-util: 29.7.0 + jest-util: 29.7.0 + slash: 3.0.0 + dev: true + + /@jest/core@29.7.0(ts-node@10.9.2): + resolution: {integrity: sha512-n7aeXWKMnGtDA48y8TLWJPJmLmmZ642Ceo78cYWEpiD7FzDgmNDV/GCVRorPABdXLJZ/9wzzgZAlHjXjxDHGsg==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + peerDependencies: + node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 + peerDependenciesMeta: + node-notifier: + optional: true + dependencies: + '@jest/console': 29.7.0 + '@jest/reporters': 29.7.0 + '@jest/test-result': 29.7.0 + '@jest/transform': 29.7.0 + '@jest/types': 29.6.3 + '@types/node': 20.12.12 + ansi-escapes: 4.3.2 + chalk: 4.1.2 + ci-info: 3.9.0 + exit: 0.1.2 + graceful-fs: 4.2.11 + jest-changed-files: 29.7.0 + jest-config: 29.7.0(@types/node@20.12.12)(ts-node@10.9.2) + jest-haste-map: 29.7.0 + jest-message-util: 29.7.0 + jest-regex-util: 29.6.3 + jest-resolve: 29.7.0 + jest-resolve-dependencies: 29.7.0 + jest-runner: 29.7.0 + jest-runtime: 29.7.0 + jest-snapshot: 29.7.0 + jest-util: 29.7.0 + jest-validate: 29.7.0 + jest-watcher: 29.7.0 + micromatch: 4.0.5 + pretty-format: 29.7.0 + slash: 3.0.0 + strip-ansi: 6.0.1 + transitivePeerDependencies: + - babel-plugin-macros + - supports-color + - ts-node + dev: true + + /@jest/environment@29.7.0: + resolution: {integrity: sha512-aQIfHDq33ExsN4jP1NWGXhxgQ/wixs60gDiKO+XVMd8Mn0NWPWgc34ZQDTb2jKaUWQ7MuwoitXAsN2XVXNMpAw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@jest/fake-timers': 29.7.0 + '@jest/types': 29.6.3 + '@types/node': 20.12.12 + jest-mock: 29.7.0 + dev: true + + /@jest/expect-utils@29.7.0: + resolution: {integrity: sha512-GlsNBWiFQFCVi9QVSx7f5AgMeLxe9YCCs5PuP2O2LdjDAA8Jh9eX7lA1Jq/xdXw3Wb3hyvlFNfZIfcRetSzYcA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + jest-get-type: 29.6.3 + dev: true + + /@jest/expect@29.7.0: + resolution: {integrity: sha512-8uMeAMycttpva3P1lBHB8VciS9V0XAr3GymPpipdyQXbBcuhkLQOSe8E/p92RyAdToS6ZD1tFkX+CkhoECE0dQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + expect: 29.7.0 + jest-snapshot: 29.7.0 + transitivePeerDependencies: + - supports-color + dev: true + + /@jest/fake-timers@29.7.0: + resolution: {integrity: sha512-q4DH1Ha4TTFPdxLsqDXK1d3+ioSL7yL5oCMJZgDYm6i+6CygW5E5xVr/D1HdsGxjt1ZWSfUAs9OxSB/BNelWrQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@jest/types': 29.6.3 + '@sinonjs/fake-timers': 10.3.0 + '@types/node': 20.12.12 + jest-message-util: 29.7.0 + jest-mock: 29.7.0 + jest-util: 29.7.0 + dev: true + + /@jest/globals@29.7.0: + resolution: {integrity: sha512-mpiz3dutLbkW2MNFubUGUEVLkTGiqW6yLVTA+JbP6fI6J5iL9Y0Nlg8k95pcF8ctKwCS7WVxteBs29hhfAotzQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@jest/environment': 29.7.0 + '@jest/expect': 29.7.0 + '@jest/types': 29.6.3 + jest-mock: 29.7.0 + transitivePeerDependencies: + - supports-color + dev: true + + /@jest/reporters@29.7.0: + resolution: {integrity: sha512-DApq0KJbJOEzAFYjHADNNxAE3KbhxQB1y5Kplb5Waqw6zVbuWatSnMjE5gs8FUgEPmNsnZA3NCWl9NG0ia04Pg==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + peerDependencies: + node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 + peerDependenciesMeta: + node-notifier: + optional: true + dependencies: + '@bcoe/v8-coverage': 0.2.3 + '@jest/console': 29.7.0 + '@jest/test-result': 29.7.0 + '@jest/transform': 29.7.0 + '@jest/types': 29.6.3 + '@jridgewell/trace-mapping': 0.3.25 + '@types/node': 20.12.12 + chalk: 4.1.2 + collect-v8-coverage: 1.0.2 + exit: 0.1.2 + glob: 7.2.3 + graceful-fs: 4.2.11 + istanbul-lib-coverage: 3.2.2 + istanbul-lib-instrument: 6.0.2 + istanbul-lib-report: 3.0.1 + istanbul-lib-source-maps: 4.0.1 + istanbul-reports: 3.1.7 + jest-message-util: 29.7.0 + jest-util: 29.7.0 + jest-worker: 29.7.0 + slash: 3.0.0 + string-length: 4.0.2 + strip-ansi: 6.0.1 + v8-to-istanbul: 9.2.0 + transitivePeerDependencies: + - supports-color + dev: true + /@jest/schemas@29.6.3: resolution: {integrity: sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} @@ -1291,6 +1705,70 @@ packages: '@sinclair/typebox': 0.27.8 dev: true + /@jest/source-map@29.6.3: + resolution: {integrity: sha512-MHjT95QuipcPrpLM+8JMSzFx6eHp5Bm+4XeFDJlwsvVBjmKNiIAvasGK2fxz2WbGRlnvqehFbh07MMa7n3YJnw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@jridgewell/trace-mapping': 0.3.25 + callsites: 3.1.0 + graceful-fs: 4.2.11 + dev: true + + /@jest/test-result@29.7.0: + resolution: {integrity: sha512-Fdx+tv6x1zlkJPcWXmMDAG2HBnaR9XPSd5aDWQVsfrZmLVT3lU1cwyxLgRmXR9yrq4NBoEm9BMsfgFzTQAbJYA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@jest/console': 29.7.0 + '@jest/types': 29.6.3 + '@types/istanbul-lib-coverage': 2.0.6 + collect-v8-coverage: 1.0.2 + dev: true + + /@jest/test-sequencer@29.7.0: + resolution: {integrity: sha512-GQwJ5WZVrKnOJuiYiAF52UNUJXgTZx1NHjFSEB0qEMmSZKAkdMoIzw/Cj6x6NF4AvV23AUqDpFzQkN/eYCYTxw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@jest/test-result': 29.7.0 + graceful-fs: 4.2.11 + jest-haste-map: 29.7.0 + slash: 3.0.0 + dev: true + + /@jest/transform@29.7.0: + resolution: {integrity: sha512-ok/BTPFzFKVMwO5eOHRrvnBVHdRy9IrsrW1GpMaQ9MCnilNLXQKmAX8s1YXDFaai9xJpac2ySzV0YeRRECr2Vw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@babel/core': 7.24.0 + '@jest/types': 29.6.3 + '@jridgewell/trace-mapping': 0.3.25 + babel-plugin-istanbul: 6.1.1 + chalk: 4.1.2 + convert-source-map: 2.0.0 + fast-json-stable-stringify: 2.1.0 + graceful-fs: 4.2.11 + jest-haste-map: 29.7.0 + jest-regex-util: 29.6.3 + jest-util: 29.7.0 + micromatch: 4.0.5 + pirates: 4.0.6 + slash: 3.0.0 + write-file-atomic: 4.0.2 + transitivePeerDependencies: + - supports-color + dev: true + + /@jest/types@29.6.3: + resolution: {integrity: sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@jest/schemas': 29.6.3 + '@types/istanbul-lib-coverage': 2.0.6 + '@types/istanbul-reports': 3.0.4 + '@types/node': 20.12.12 + '@types/yargs': 17.0.32 + chalk: 4.1.2 + dev: true + /@jridgewell/gen-mapping@0.3.5: resolution: {integrity: sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==} engines: {node: '>=6.0.0'} @@ -1310,6 +1788,13 @@ packages: engines: {node: '>=6.0.0'} dev: true + /@jridgewell/source-map@0.3.6: + resolution: {integrity: sha512-1ZJTZebgqllO79ue2bm3rIGud/bOe0pP5BjSRCRxxYkEZS8STV7zN84UBbiYu7jy+eCKSnVIUgoWWE/tt+shMQ==} + dependencies: + '@jridgewell/gen-mapping': 0.3.5 + '@jridgewell/trace-mapping': 0.3.25 + dev: true + /@jridgewell/sourcemap-codec@1.4.15: resolution: {integrity: sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==} dev: true @@ -1328,6 +1813,17 @@ packages: '@jridgewell/sourcemap-codec': 1.4.15 dev: true + /@ljharb/through@2.3.13: + resolution: {integrity: sha512-/gKJun8NNiWGZJkGzI/Ragc53cOdcLNdzjLaIa+GEjguQs0ulsurx8WN0jijdK9yPqDvziX995sMRLyLt1uZMQ==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.7 + dev: true + + /@lukeed/csprng@1.1.0: + resolution: {integrity: sha512-Z7C/xXCiGWsg0KuKsHTKJxbWhpI3Vs5GwLfOean7MGyVFGqdRgBbAjOCh6u4bbjPc/8MJ2pZmK/0DLdCbivLDA==} + engines: {node: '>=8'} + /@manypkg/find-root@1.1.0: resolution: {integrity: sha512-mki5uBvhHzO8kYYix/WRy2WX8S3B5wdVSc9D6KcU5lQNglP2yt58/VfLuAK49glRXChosY8ap2oJ1qgma3GUVA==} dependencies: @@ -1383,6 +1879,162 @@ packages: resolution: {integrity: sha512-mD5mOCGa1JertKZekHSUVYwFPW27VJ0/MdwblWvEEK7pNIU6az+dLiIxgvl4TxR+j+7/GqmXNH1U59CM92y/wg==} dev: false + /@nestjs/cli@10.3.2: + resolution: {integrity: sha512-aWmD1GLluWrbuC4a1Iz/XBk5p74Uj6nIVZj6Ov03JbTfgtWqGFLtXuMetvzMiHxfrHehx/myt2iKAPRhKdZvTg==} + engines: {node: '>= 16.14'} + hasBin: true + peerDependencies: + '@swc/cli': ^0.1.62 || ^0.3.0 + '@swc/core': ^1.3.62 + peerDependenciesMeta: + '@swc/cli': + optional: true + '@swc/core': + optional: true + dependencies: + '@angular-devkit/core': 17.1.2(chokidar@3.6.0) + '@angular-devkit/schematics': 17.1.2(chokidar@3.6.0) + '@angular-devkit/schematics-cli': 17.1.2(chokidar@3.6.0) + '@nestjs/schematics': 10.1.1(chokidar@3.6.0)(typescript@5.3.3) + chalk: 4.1.2 + chokidar: 3.6.0 + cli-table3: 0.6.3 + commander: 4.1.1 + fork-ts-checker-webpack-plugin: 9.0.2(typescript@5.3.3)(webpack@5.90.1) + glob: 10.3.10 + inquirer: 8.2.6 + node-emoji: 1.11.0 + ora: 5.4.1 + rimraf: 4.4.1 + shelljs: 0.8.5 + source-map-support: 0.5.21 + tree-kill: 1.2.2 + tsconfig-paths: 4.2.0 + tsconfig-paths-webpack-plugin: 4.1.0 + typescript: 5.3.3 + webpack: 5.90.1 + webpack-node-externals: 3.0.0 + transitivePeerDependencies: + - esbuild + - uglify-js + - webpack-cli + dev: true + + /@nestjs/common@10.3.9(reflect-metadata@0.2.2)(rxjs@7.8.1): + resolution: {integrity: sha512-JAQONPagMa+sy/fcIqh/Hn3rkYQ9pQM51vXCFNOM5ujefxUVqn3gwFRMN8Y1+MxdUHipV+8daEj2jEm0IqJzOA==} + peerDependencies: + class-transformer: '*' + class-validator: '*' + reflect-metadata: ^0.1.12 || ^0.2.0 + rxjs: ^7.1.0 + peerDependenciesMeta: + class-transformer: + optional: true + class-validator: + optional: true + dependencies: + iterare: 1.2.1 + reflect-metadata: 0.2.2 + rxjs: 7.8.1 + tslib: 2.6.2 + uid: 2.0.2 + + /@nestjs/core@10.3.9(@nestjs/common@10.3.9)(@nestjs/platform-express@10.3.9)(reflect-metadata@0.2.2)(rxjs@7.8.1): + resolution: {integrity: sha512-NzZUfWAmaf8sqhhwoRA+CuqxQe+P4Rz8PZp5U7CdCbjyeB9ZVGcBkihcJC9wMdtiOWHRndB2J8zRfs5w06jK3w==} + requiresBuild: true + peerDependencies: + '@nestjs/common': ^10.0.0 + '@nestjs/microservices': ^10.0.0 + '@nestjs/platform-express': ^10.0.0 + '@nestjs/websockets': ^10.0.0 + reflect-metadata: ^0.1.12 || ^0.2.0 + rxjs: ^7.1.0 + peerDependenciesMeta: + '@nestjs/microservices': + optional: true + '@nestjs/platform-express': + optional: true + '@nestjs/websockets': + optional: true + dependencies: + '@nestjs/common': 10.3.9(reflect-metadata@0.2.2)(rxjs@7.8.1) + '@nestjs/platform-express': 10.3.9(@nestjs/common@10.3.9)(@nestjs/core@10.3.9) + '@nuxtjs/opencollective': 0.3.2 + fast-safe-stringify: 2.1.1 + iterare: 1.2.1 + path-to-regexp: 3.2.0 + reflect-metadata: 0.2.2 + rxjs: 7.8.1 + tslib: 2.6.2 + uid: 2.0.2 + transitivePeerDependencies: + - encoding + + /@nestjs/platform-express@10.3.9(@nestjs/common@10.3.9)(@nestjs/core@10.3.9): + resolution: {integrity: sha512-si/UzobP6YUtYtCT1cSyQYHHzU3yseqYT6l7OHSMVvfG1+TqxaAqI6nmrix02LO+l1YntHRXEs3p+v9a7EfrSQ==} + peerDependencies: + '@nestjs/common': ^10.0.0 + '@nestjs/core': ^10.0.0 + dependencies: + '@nestjs/common': 10.3.9(reflect-metadata@0.2.2)(rxjs@7.8.1) + '@nestjs/core': 10.3.9(@nestjs/common@10.3.9)(@nestjs/platform-express@10.3.9)(reflect-metadata@0.2.2)(rxjs@7.8.1) + body-parser: 1.20.2 + cors: 2.8.5 + express: 4.19.2 + multer: 1.4.4-lts.1 + tslib: 2.6.2 + transitivePeerDependencies: + - supports-color + + /@nestjs/schematics@10.1.1(chokidar@3.6.0)(typescript@5.3.3): + resolution: {integrity: sha512-o4lfCnEeIkfJhGBbLZxTuVWcGuqDCFwg5OrvpgRUBM7vI/vONvKKiB5riVNpO+JqXoH0I42NNeDb0m4V5RREig==} + peerDependencies: + typescript: '>=4.8.2' + dependencies: + '@angular-devkit/core': 17.1.2(chokidar@3.6.0) + '@angular-devkit/schematics': 17.1.2(chokidar@3.6.0) + comment-json: 4.2.3 + jsonc-parser: 3.2.1 + pluralize: 8.0.0 + typescript: 5.3.3 + transitivePeerDependencies: + - chokidar + dev: true + + /@nestjs/schematics@10.1.1(typescript@5.4.3): + resolution: {integrity: sha512-o4lfCnEeIkfJhGBbLZxTuVWcGuqDCFwg5OrvpgRUBM7vI/vONvKKiB5riVNpO+JqXoH0I42NNeDb0m4V5RREig==} + peerDependencies: + typescript: '>=4.8.2' + dependencies: + '@angular-devkit/core': 17.1.2(chokidar@3.6.0) + '@angular-devkit/schematics': 17.1.2(chokidar@3.6.0) + comment-json: 4.2.3 + jsonc-parser: 3.2.1 + pluralize: 8.0.0 + typescript: 5.4.3 + transitivePeerDependencies: + - chokidar + dev: true + + /@nestjs/testing@10.3.9(@nestjs/common@10.3.9)(@nestjs/core@10.3.9)(@nestjs/platform-express@10.3.9): + resolution: {integrity: sha512-z24SdpZIRtYyM5s2vnu7rbBosXJY/KcAP7oJlwgFa/h/z/wg8gzyoKy5lhibH//OZNO+pYKajV5wczxuy5WeAg==} + peerDependencies: + '@nestjs/common': ^10.0.0 + '@nestjs/core': ^10.0.0 + '@nestjs/microservices': ^10.0.0 + '@nestjs/platform-express': ^10.0.0 + peerDependenciesMeta: + '@nestjs/microservices': + optional: true + '@nestjs/platform-express': + optional: true + dependencies: + '@nestjs/common': 10.3.9(reflect-metadata@0.2.2)(rxjs@7.8.1) + '@nestjs/core': 10.3.9(@nestjs/common@10.3.9)(@nestjs/platform-express@10.3.9)(reflect-metadata@0.2.2)(rxjs@7.8.1) + '@nestjs/platform-express': 10.3.9(@nestjs/common@10.3.9)(@nestjs/core@10.3.9) + tslib: 2.6.2 + dev: true + /@next/env@14.1.2: resolution: {integrity: sha512-U0iEG+JF86j6qyu330sfPgsMmDVH8vWVmzZadl+an5EU3o5HqdNytOpM+HsFpl58PmhGBTKx3UmM9c+eoLK0mA==} dev: false @@ -1498,6 +2150,17 @@ packages: fastq: 1.17.1 dev: true + /@nuxtjs/opencollective@0.3.2: + resolution: {integrity: sha512-um0xL3fO7Mf4fDxcqx9KryrB7zgRM5JSlvGN5AGkP6JLM5XEKyjeAiPbNxdXVXQ16isuAhYpvP88NgL2BGd6aA==} + engines: {node: '>=8.0.0', npm: '>=5.0.0'} + hasBin: true + dependencies: + chalk: 4.1.2 + consola: 2.15.3 + node-fetch: 2.7.0 + transitivePeerDependencies: + - encoding + /@pkgjs/parseargs@0.11.0: resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} engines: {node: '>=14'} @@ -1661,6 +2324,18 @@ packages: resolution: {integrity: sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==} dev: true + /@sinonjs/commons@3.0.1: + resolution: {integrity: sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ==} + dependencies: + type-detect: 4.0.8 + dev: true + + /@sinonjs/fake-timers@10.3.0: + resolution: {integrity: sha512-V4BG07kuYSUkTCSBHG8G8TNhM+F19jXFWnQtzj+we8DrkpSBCee9Z3Ms8yiGer/dlmhe35/Xdgyo3/0rQKg7YA==} + dependencies: + '@sinonjs/commons': 3.0.1 + dev: true + /@spore-sdk/core@0.2.0-beta.6(@ckb-lumos/lumos@0.22.0-next.5)(lodash@4.17.21): resolution: {integrity: sha512-g2QerxzNZ+ABKH7VfXDPHZ2saipJpG3oJPAmRRSm72T59YvFJMlrannVxMaIIkLseDL6YAyvqkTxLwPTuo55ww==} peerDependencies: @@ -1726,6 +2401,23 @@ packages: resolution: {integrity: sha512-MFCdX0MNxFBP/xEILO5Td0kv6nI7+Q2iRWZbTL/yzH2/eDVZS5Wd1LHdsmXClvsCyzqaZfHFzZaN6BUeUCfSDA==} dev: false + /@types/body-parser@1.19.5: + resolution: {integrity: sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg==} + dependencies: + '@types/connect': 3.4.38 + '@types/node': 20.12.12 + dev: true + + /@types/connect@3.4.38: + resolution: {integrity: sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==} + dependencies: + '@types/node': 20.12.12 + dev: true + + /@types/cookiejar@2.1.5: + resolution: {integrity: sha512-he+DHOWReW0nghN24E1WUqM0efK4kI9oTqDm6XmK8ZPe2djZ90BSNdGnIyCLzCPw7/pogPlGbzI2wHGGmi4O/Q==} + dev: true + /@types/deep-freeze-strict@1.1.2: resolution: {integrity: sha512-VvMETBojHvhX4f+ocYTySQlXMZfxKV3Jyb7iCWlWaC+exbedkv6Iv2bZZqI736qXjVguH6IH7bzwMBMfTT+zuQ==} dev: false @@ -1737,10 +2429,42 @@ packages: dotenv: 16.4.5 dev: true + /@types/eslint-scope@3.7.7: + resolution: {integrity: sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg==} + dependencies: + '@types/eslint': 8.56.10 + '@types/estree': 1.0.5 + dev: true + + /@types/eslint@8.56.10: + resolution: {integrity: sha512-Shavhk87gCtY2fhXDctcfS3e6FdxWkCx1iUZ9eEUbh7rTqlZT0/IzOkCOVt0fCjcFuZ9FPYfuezTBImfHCDBGQ==} + dependencies: + '@types/estree': 1.0.5 + '@types/json-schema': 7.0.15 + dev: true + /@types/estree@1.0.5: resolution: {integrity: sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==} dev: true + /@types/express-serve-static-core@4.19.3: + resolution: {integrity: sha512-KOzM7MhcBFlmnlr/fzISFF5vGWVSvN6fTd4T+ExOt08bA/dA5kpSzY52nMsI1KDFmUREpJelPYyuslLRSjjgCg==} + dependencies: + '@types/node': 20.12.12 + '@types/qs': 6.9.15 + '@types/range-parser': 1.2.7 + '@types/send': 0.17.4 + dev: true + + /@types/express@4.17.21: + resolution: {integrity: sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ==} + dependencies: + '@types/body-parser': 1.19.5 + '@types/express-serve-static-core': 4.19.3 + '@types/qs': 6.9.15 + '@types/serve-static': 1.15.7 + dev: true + /@types/fs-extra@11.0.4: resolution: {integrity: sha512-yTbItCNreRooED33qjunPthRcSjERP1r4MqCZc7wv0u2sUkzTFp45tgUfS5+r7FrZPdmCCNflLhVSP/o+SemsQ==} requiresBuild: true @@ -1750,6 +2474,39 @@ packages: dev: false optional: true + /@types/graceful-fs@4.1.9: + resolution: {integrity: sha512-olP3sd1qOEe5dXTSaFvQG+02VdRXcdytWLAZsAq1PecU8uqQAhkrnbli7DagjtXKW/Bl7YJbUsa8MPcuc8LHEQ==} + dependencies: + '@types/node': 20.12.12 + dev: true + + /@types/http-errors@2.0.4: + resolution: {integrity: sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA==} + dev: true + + /@types/istanbul-lib-coverage@2.0.6: + resolution: {integrity: sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==} + dev: true + + /@types/istanbul-lib-report@3.0.3: + resolution: {integrity: sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA==} + dependencies: + '@types/istanbul-lib-coverage': 2.0.6 + dev: true + + /@types/istanbul-reports@3.0.4: + resolution: {integrity: sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==} + dependencies: + '@types/istanbul-lib-report': 3.0.3 + dev: true + + /@types/jest@29.5.12: + resolution: {integrity: sha512-eDC8bTvT/QhYdxJAulQikueigY5AsdBRH2yDKW3yveW7svY3+DzN84/2NUgkw10RTiJbWqZrTtoGVdYlvFJdLw==} + dependencies: + expect: 29.7.0 + pretty-format: 29.7.0 + dev: true + /@types/json-schema@7.0.15: resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} dev: true @@ -1771,6 +2528,14 @@ packages: /@types/lodash@4.17.0: resolution: {integrity: sha512-t7dhREVv6dbNj0q17X12j7yDG4bD/DHYX7o5/DbDxobP0HnGPgpRz2Ej77aL7TZT3DSw13fqUTj8J4mMnqa7WA==} + /@types/methods@1.1.4: + resolution: {integrity: sha512-ymXWVrDiCxTBE3+RIrrP533E70eA+9qu7zdWoHuOmGujkYtzf4HQF96b8nwHLqhuf4ykX61IGRIB38CC6/sImQ==} + dev: true + + /@types/mime@1.3.5: + resolution: {integrity: sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==} + dev: true + /@types/minimist@1.2.5: resolution: {integrity: sha512-hov8bUuiLiyFPGyFPE1lwWhmzYbirOXQNNo40+y3zow8aFVTeyn3VWL0VFFfdNddA8S4Vf0Tc062rzyNr7Paag==} dev: true @@ -1807,6 +2572,14 @@ packages: resolution: {integrity: sha512-ga8y9v9uyeiLdpKddhxYQkxNDrfvuPrlFb0N1qnZZByvcElJaXthF1UhvCh9TLWJBEHeNtdnbysW7Y6Uq8CVng==} dev: true + /@types/qs@6.9.15: + resolution: {integrity: sha512-uXHQKES6DQKKCLh441Xv/dwxOq1TVS3JPUMlEqoEglvlhR6Mxnlew/Xq/LRVHpLyk7iK3zODe1qYHIMltO7XGg==} + dev: true + + /@types/range-parser@1.2.7: + resolution: {integrity: sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==} + dev: true + /@types/react-dom@18.2.19: resolution: {integrity: sha512-aZvQL6uUbIJpjZk4U8JZGbau9KDeAwMfmhyWorxgBkqDIEf6ROjRozcmPIicqsUwPUjbkDfHKgGee1Lq65APcA==} dependencies: @@ -1829,6 +2602,50 @@ packages: resolution: {integrity: sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ==} dev: true + /@types/send@0.17.4: + resolution: {integrity: sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA==} + dependencies: + '@types/mime': 1.3.5 + '@types/node': 20.12.12 + dev: true + + /@types/serve-static@1.15.7: + resolution: {integrity: sha512-W8Ym+h8nhuRwaKPaDw34QUkwsGi6Rc4yYqvKFo5rm2FUEhCFbzVWrxXUxuKK8TASjWsysJY0nsmNCGhCOIsrOw==} + dependencies: + '@types/http-errors': 2.0.4 + '@types/node': 20.12.12 + '@types/send': 0.17.4 + dev: true + + /@types/stack-utils@2.0.3: + resolution: {integrity: sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==} + dev: true + + /@types/superagent@8.1.7: + resolution: {integrity: sha512-NmIsd0Yj4DDhftfWvvAku482PZum4DBW7U51OvS8gvOkDDY0WT1jsVyDV3hK+vplrsYw8oDwi9QxOM7U68iwww==} + dependencies: + '@types/cookiejar': 2.1.5 + '@types/methods': 1.1.4 + '@types/node': 20.12.12 + dev: true + + /@types/supertest@6.0.2: + resolution: {integrity: sha512-137ypx2lk/wTQbW6An6safu9hXmajAifU/s7szAHLN/FeIm5w7yR0Wkl9fdJMRSHwOn4HLAI0DaB2TOORuhPDg==} + dependencies: + '@types/methods': 1.1.4 + '@types/superagent': 8.1.7 + dev: true + + /@types/yargs-parser@21.0.3: + resolution: {integrity: sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==} + dev: true + + /@types/yargs@17.0.32: + resolution: {integrity: sha512-xQ67Yc/laOG5uMfX/093MRlGGCIBzZMarVa+gfNKJxWAIgykYpVGkBdbqEzGDDfCrVUj6Hiff4mTZ5BA6TmAog==} + dependencies: + '@types/yargs-parser': 21.0.3 + dev: true + /@typescript-eslint/eslint-plugin@7.0.2(@typescript-eslint/parser@7.0.2)(eslint@8.56.0)(typescript@5.4.2): resolution: {integrity: sha512-/XtVZJtbaphtdrWjr+CJclaCVGPtOdBpFEnvtNf/jRV0IiEemRrL0qABex/nEt8isYcnFacm3nPHYQwL+Wb7qg==} engines: {node: ^16.0.0 || >=18.0.0} @@ -2152,6 +2969,120 @@ packages: pretty-format: 29.7.0 dev: true + /@webassemblyjs/ast@1.12.1: + resolution: {integrity: sha512-EKfMUOPRRUTy5UII4qJDGPpqfwjOmZ5jeGFwid9mnoqIFK+e0vqoi1qH56JpmZSzEL53jKnNzScdmftJyG5xWg==} + dependencies: + '@webassemblyjs/helper-numbers': 1.11.6 + '@webassemblyjs/helper-wasm-bytecode': 1.11.6 + dev: true + + /@webassemblyjs/floating-point-hex-parser@1.11.6: + resolution: {integrity: sha512-ejAj9hfRJ2XMsNHk/v6Fu2dGS+i4UaXBXGemOfQ/JfQ6mdQg/WXtwleQRLLS4OvfDhv8rYnVwH27YJLMyYsxhw==} + dev: true + + /@webassemblyjs/helper-api-error@1.11.6: + resolution: {integrity: sha512-o0YkoP4pVu4rN8aTJgAyj9hC2Sv5UlkzCHhxqWj8butaLvnpdc2jOwh4ewE6CX0txSfLn/UYaV/pheS2Txg//Q==} + dev: true + + /@webassemblyjs/helper-buffer@1.12.1: + resolution: {integrity: sha512-nzJwQw99DNDKr9BVCOZcLuJJUlqkJh+kVzVl6Fmq/tI5ZtEyWT1KZMyOXltXLZJmDtvLCDgwsyrkohEtopTXCw==} + dev: true + + /@webassemblyjs/helper-numbers@1.11.6: + resolution: {integrity: sha512-vUIhZ8LZoIWHBohiEObxVm6hwP034jwmc9kuq5GdHZH0wiLVLIPcMCdpJzG4C11cHoQ25TFIQj9kaVADVX7N3g==} + dependencies: + '@webassemblyjs/floating-point-hex-parser': 1.11.6 + '@webassemblyjs/helper-api-error': 1.11.6 + '@xtuc/long': 4.2.2 + dev: true + + /@webassemblyjs/helper-wasm-bytecode@1.11.6: + resolution: {integrity: sha512-sFFHKwcmBprO9e7Icf0+gddyWYDViL8bpPjJJl0WHxCdETktXdmtWLGVzoHbqUcY4Be1LkNfwTmXOJUFZYSJdA==} + dev: true + + /@webassemblyjs/helper-wasm-section@1.12.1: + resolution: {integrity: sha512-Jif4vfB6FJlUlSbgEMHUyk1j234GTNG9dBJ4XJdOySoj518Xj0oGsNi59cUQF4RRMS9ouBUxDDdyBVfPTypa5g==} + dependencies: + '@webassemblyjs/ast': 1.12.1 + '@webassemblyjs/helper-buffer': 1.12.1 + '@webassemblyjs/helper-wasm-bytecode': 1.11.6 + '@webassemblyjs/wasm-gen': 1.12.1 + dev: true + + /@webassemblyjs/ieee754@1.11.6: + resolution: {integrity: sha512-LM4p2csPNvbij6U1f19v6WR56QZ8JcHg3QIJTlSwzFcmx6WSORicYj6I63f9yU1kEUtrpG+kjkiIAkevHpDXrg==} + dependencies: + '@xtuc/ieee754': 1.2.0 + dev: true + + /@webassemblyjs/leb128@1.11.6: + resolution: {integrity: sha512-m7a0FhE67DQXgouf1tbN5XQcdWoNgaAuoULHIfGFIEVKA6tu/edls6XnIlkmS6FrXAquJRPni3ZZKjw6FSPjPQ==} + dependencies: + '@xtuc/long': 4.2.2 + dev: true + + /@webassemblyjs/utf8@1.11.6: + resolution: {integrity: sha512-vtXf2wTQ3+up9Zsg8sa2yWiQpzSsMyXj0qViVP6xKGCUT8p8YJ6HqI7l5eCnWx1T/FYdsv07HQs2wTFbbof/RA==} + dev: true + + /@webassemblyjs/wasm-edit@1.12.1: + resolution: {integrity: sha512-1DuwbVvADvS5mGnXbE+c9NfA8QRcZ6iKquqjjmR10k6o+zzsRVesil54DKexiowcFCPdr/Q0qaMgB01+SQ1u6g==} + dependencies: + '@webassemblyjs/ast': 1.12.1 + '@webassemblyjs/helper-buffer': 1.12.1 + '@webassemblyjs/helper-wasm-bytecode': 1.11.6 + '@webassemblyjs/helper-wasm-section': 1.12.1 + '@webassemblyjs/wasm-gen': 1.12.1 + '@webassemblyjs/wasm-opt': 1.12.1 + '@webassemblyjs/wasm-parser': 1.12.1 + '@webassemblyjs/wast-printer': 1.12.1 + dev: true + + /@webassemblyjs/wasm-gen@1.12.1: + resolution: {integrity: sha512-TDq4Ojh9fcohAw6OIMXqiIcTq5KUXTGRkVxbSo1hQnSy6lAM5GSdfwWeSxpAo0YzgsgF182E/U0mDNhuA0tW7w==} + dependencies: + '@webassemblyjs/ast': 1.12.1 + '@webassemblyjs/helper-wasm-bytecode': 1.11.6 + '@webassemblyjs/ieee754': 1.11.6 + '@webassemblyjs/leb128': 1.11.6 + '@webassemblyjs/utf8': 1.11.6 + dev: true + + /@webassemblyjs/wasm-opt@1.12.1: + resolution: {integrity: sha512-Jg99j/2gG2iaz3hijw857AVYekZe2SAskcqlWIZXjji5WStnOpVoat3gQfT/Q5tb2djnCjBtMocY/Su1GfxPBg==} + dependencies: + '@webassemblyjs/ast': 1.12.1 + '@webassemblyjs/helper-buffer': 1.12.1 + '@webassemblyjs/wasm-gen': 1.12.1 + '@webassemblyjs/wasm-parser': 1.12.1 + dev: true + + /@webassemblyjs/wasm-parser@1.12.1: + resolution: {integrity: sha512-xikIi7c2FHXysxXe3COrVUPSheuBtpcfhbpFj4gmu7KRLYOzANztwUU0IbsqvMqzuNK2+glRGWCEqZo1WCLyAQ==} + dependencies: + '@webassemblyjs/ast': 1.12.1 + '@webassemblyjs/helper-api-error': 1.11.6 + '@webassemblyjs/helper-wasm-bytecode': 1.11.6 + '@webassemblyjs/ieee754': 1.11.6 + '@webassemblyjs/leb128': 1.11.6 + '@webassemblyjs/utf8': 1.11.6 + dev: true + + /@webassemblyjs/wast-printer@1.12.1: + resolution: {integrity: sha512-+X4WAlOisVWQMikjbcvY2e0rwPsKQ9F688lksZhBcPycBBuii3O7m8FACbDMWDojpAqvjIncrG8J0XHKyQfVeA==} + dependencies: + '@webassemblyjs/ast': 1.12.1 + '@xtuc/long': 4.2.2 + dev: true + + /@xtuc/ieee754@1.2.0: + resolution: {integrity: sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==} + dev: true + + /@xtuc/long@4.2.2: + resolution: {integrity: sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==} + dev: true + /abort-controller@3.0.0: resolution: {integrity: sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==} engines: {node: '>=6.5'} @@ -2159,6 +3090,21 @@ packages: event-target-shim: 5.0.1 dev: false + /accepts@1.3.8: + resolution: {integrity: sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==} + engines: {node: '>= 0.6'} + dependencies: + mime-types: 2.1.35 + negotiator: 0.6.3 + + /acorn-import-assertions@1.9.0(acorn@8.11.3): + resolution: {integrity: sha512-cmMwop9x+8KFhxvKrKfPYmN6/pKTYYHBqLa0DfvVZcKMJWNyWLnaqND7dx/qn66R7ewM1UX5XMaDVP5wlVTaVA==} + peerDependencies: + acorn: ^8 + dependencies: + acorn: 8.11.3 + dev: true + /acorn-jsx@5.3.2(acorn@8.11.3): resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} peerDependencies: @@ -2178,6 +3124,25 @@ packages: hasBin: true dev: true + /ajv-formats@2.1.1(ajv@8.12.0): + resolution: {integrity: sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==} + peerDependencies: + ajv: ^8.0.0 + peerDependenciesMeta: + ajv: + optional: true + dependencies: + ajv: 8.12.0 + dev: true + + /ajv-keywords@3.5.2(ajv@6.12.6): + resolution: {integrity: sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==} + peerDependencies: + ajv: ^6.9.1 + dependencies: + ajv: 6.12.6 + dev: true + /ajv@6.12.6: resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==} dependencies: @@ -2187,11 +3152,27 @@ packages: uri-js: 4.4.1 dev: true + /ajv@8.12.0: + resolution: {integrity: sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==} + dependencies: + fast-deep-equal: 3.1.3 + json-schema-traverse: 1.0.0 + require-from-string: 2.0.2 + uri-js: 4.4.1 + dev: true + /ansi-colors@4.1.3: resolution: {integrity: sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==} engines: {node: '>=6'} dev: true + /ansi-escapes@4.3.2: + resolution: {integrity: sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==} + engines: {node: '>=8'} + dependencies: + type-fest: 0.21.3 + dev: true + /ansi-escapes@6.2.1: resolution: {integrity: sha512-4nJ3yixlEthEJ9Rk4vPcdBRkZvQZlYyu8j4/Mqz5sgIkddmEnH2Yj2ZrnP9S3tQOvSNRUIgVNF/1yPpRAGNRig==} engines: {node: '>=14.16'} @@ -2219,7 +3200,6 @@ packages: engines: {node: '>=8'} dependencies: color-convert: 2.0.1 - dev: true /ansi-styles@5.2.0: resolution: {integrity: sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==} @@ -2231,6 +3211,17 @@ packages: engines: {node: '>=12'} dev: true + /anymatch@3.1.3: + resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} + engines: {node: '>= 8'} + dependencies: + normalize-path: 3.0.0 + picomatch: 2.3.1 + dev: true + + /append-field@1.0.0: + resolution: {integrity: sha512-klpgFSWLW1ZEs8svjfb7g4qWY0YS5imI82dTg+QahUvJ8YqAY0P10Uk8tTyh9ZGuYEZEMaeJYCF5BFuX552hsw==} + /arg@4.1.3: resolution: {integrity: sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==} dev: true @@ -2253,6 +3244,13 @@ packages: is-array-buffer: 3.0.4 dev: true + /array-flatten@1.1.1: + resolution: {integrity: sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==} + + /array-timsort@1.0.3: + resolution: {integrity: sha512-/+3GRL7dDAGEfM6TseQk/U+mi18TU2Ms9I3UlLdUMhz2hbvGNTKdj9xniwXfUqgYhHxRx0+8UnKkvlNwVU+cWQ==} + dev: true + /array-union@2.1.0: resolution: {integrity: sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==} engines: {node: '>=8'} @@ -2287,6 +3285,10 @@ packages: engines: {node: '>=0.10.0'} dev: true + /asap@2.0.6: + resolution: {integrity: sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==} + dev: true + /asn1.js@4.10.1: resolution: {integrity: sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw==} dependencies: @@ -2311,7 +3313,6 @@ packages: /asynckit@0.4.0: resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} - dev: false /available-typed-arrays@1.0.7: resolution: {integrity: sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==} @@ -2344,18 +3345,90 @@ packages: resolution: {integrity: sha512-5Tk1HLk6b6ctmjIkAcU/Ujv/1WqiDl0F0JdRCR80VsOcUlHcu7pWeWRlOqQLHfDEsVx9YH/aif5AG4ehoCtTmg==} dev: false - /balanced-match@1.0.2: - resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + /babel-jest@29.7.0(@babel/core@7.24.0): + resolution: {integrity: sha512-BrvGY3xZSwEcCzKvKsCi2GgHqDqsYkOP4/by5xCgIwGXQxIEh+8ew3gmrE1y7XRR6LHZIj6yLYnUi/mm2KXKBg==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + peerDependencies: + '@babel/core': ^7.8.0 + dependencies: + '@babel/core': 7.24.0 + '@jest/transform': 29.7.0 + '@types/babel__core': 7.20.5 + babel-plugin-istanbul: 6.1.1 + babel-preset-jest: 29.6.3(@babel/core@7.24.0) + chalk: 4.1.2 + graceful-fs: 4.2.11 + slash: 3.0.0 + transitivePeerDependencies: + - supports-color dev: true - /base-x@3.0.9: - resolution: {integrity: sha512-H7JU6iBHTal1gp56aKoaa//YUxEaAOUiydvrV/pILqIHXTtqxSkATOnDA2u+jZ/61sD+L/412+7kzXRtWukhpQ==} + /babel-plugin-istanbul@6.1.1: + resolution: {integrity: sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==} + engines: {node: '>=8'} dependencies: - safe-buffer: 5.2.1 - dev: false - - /base-x@4.0.0: - resolution: {integrity: sha512-FuwxlW4H5kh37X/oW59pwTzzTKRzfrrQwhmyspRM7swOEZcHtDZSCt45U6oKgtuFE+WYPblePMVIPR4RZrh/hw==} + '@babel/helper-plugin-utils': 7.24.0 + '@istanbuljs/load-nyc-config': 1.1.0 + '@istanbuljs/schema': 0.1.3 + istanbul-lib-instrument: 5.2.1 + test-exclude: 6.0.0 + transitivePeerDependencies: + - supports-color + dev: true + + /babel-plugin-jest-hoist@29.6.3: + resolution: {integrity: sha512-ESAc/RJvGTFEzRwOTT4+lNDk/GNHMkKbNzsvT0qKRfDyyYTskxB5rnU2njIDYVxXCBHHEI1c0YwHob3WaYujOg==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@babel/template': 7.24.0 + '@babel/types': 7.24.0 + '@types/babel__core': 7.20.5 + '@types/babel__traverse': 7.20.5 + dev: true + + /babel-preset-current-node-syntax@1.0.1(@babel/core@7.24.0): + resolution: {integrity: sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ==} + peerDependencies: + '@babel/core': ^7.0.0 + dependencies: + '@babel/core': 7.24.0 + '@babel/plugin-syntax-async-generators': 7.8.4(@babel/core@7.24.0) + '@babel/plugin-syntax-bigint': 7.8.3(@babel/core@7.24.0) + '@babel/plugin-syntax-class-properties': 7.12.13(@babel/core@7.24.0) + '@babel/plugin-syntax-import-meta': 7.10.4(@babel/core@7.24.0) + '@babel/plugin-syntax-json-strings': 7.8.3(@babel/core@7.24.0) + '@babel/plugin-syntax-logical-assignment-operators': 7.10.4(@babel/core@7.24.0) + '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.24.0) + '@babel/plugin-syntax-numeric-separator': 7.10.4(@babel/core@7.24.0) + '@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@7.24.0) + '@babel/plugin-syntax-optional-catch-binding': 7.8.3(@babel/core@7.24.0) + '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.24.0) + '@babel/plugin-syntax-top-level-await': 7.14.5(@babel/core@7.24.0) + dev: true + + /babel-preset-jest@29.6.3(@babel/core@7.24.0): + resolution: {integrity: sha512-0B3bhxR6snWXJZtR/RliHTDPRgn1sNHOR0yVtq/IiQFyuOVjFS+wuio/R4gSNkyYmKmJB4wGZv2NZanmKmTnNA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + peerDependencies: + '@babel/core': ^7.0.0 + dependencies: + '@babel/core': 7.24.0 + babel-plugin-jest-hoist: 29.6.3 + babel-preset-current-node-syntax: 1.0.1(@babel/core@7.24.0) + dev: true + + /balanced-match@1.0.2: + resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + dev: true + + /base-x@3.0.9: + resolution: {integrity: sha512-H7JU6iBHTal1gp56aKoaa//YUxEaAOUiydvrV/pILqIHXTtqxSkATOnDA2u+jZ/61sD+L/412+7kzXRtWukhpQ==} + dependencies: + safe-buffer: 5.2.1 + dev: false + + /base-x@4.0.0: + resolution: {integrity: sha512-FuwxlW4H5kh37X/oW59pwTzzTKRzfrrQwhmyspRM7swOEZcHtDZSCt45U6oKgtuFE+WYPblePMVIPR4RZrh/hw==} dev: false /base64-js@1.5.1: @@ -2372,6 +3445,11 @@ packages: is-windows: 1.0.2 dev: true + /binary-extensions@2.3.0: + resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==} + engines: {node: '>=8'} + dev: true + /bip174@2.1.1: resolution: {integrity: sha512-mdFV5+/v0XyNYXjBS6CQPLo9ekCx4gtKZFnJm5PMto7Fs9hTTDpkkzOB7/FtluRI6JbUUAu+snTYfJRgHLZbZQ==} engines: {node: '>=8.0.0'} @@ -2399,6 +3477,14 @@ packages: varuint-bitcoin: 1.1.2 dev: false + /bl@4.1.0: + resolution: {integrity: sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==} + dependencies: + buffer: 5.7.1 + inherits: 2.0.4 + readable-stream: 3.6.2 + dev: true + /blake2b-wasm@2.4.0: resolution: {integrity: sha512-S1kwmW2ZhZFFFOghcx73+ZajEfKBqhP82JMssxtLVMxlaPea1p9uoLiUZ5WYyHn0KddwbLc+0vh4wR0KBNoT5w==} dependencies: @@ -2419,6 +3505,25 @@ packages: /bn.js@5.2.1: resolution: {integrity: sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==} + /body-parser@1.20.2: + resolution: {integrity: sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA==} + engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16} + dependencies: + bytes: 3.1.2 + content-type: 1.0.5 + debug: 2.6.9 + depd: 2.0.0 + destroy: 1.2.0 + http-errors: 2.0.0 + iconv-lite: 0.4.24 + on-finished: 2.4.1 + qs: 6.11.0 + raw-body: 2.5.2 + type-is: 1.6.18 + unpipe: 1.0.0 + transitivePeerDependencies: + - supports-color + /brace-expansion@1.1.11: resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} dependencies: @@ -2522,6 +3627,13 @@ packages: update-browserslist-db: 1.0.13(browserslist@4.23.0) dev: true + /bs-logger@0.2.6: + resolution: {integrity: sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog==} + engines: {node: '>= 6'} + dependencies: + fast-json-stable-stringify: 2.1.0 + dev: true + /bs58@4.0.1: resolution: {integrity: sha512-Ok3Wdf5vOIlBrgCvTq96gBkJw+JUEzdBgyaza5HLtPm7yTHkjRy8+JzNyHF7BHa0bNWOQIp3m5YF0nnFcOIKLw==} dependencies: @@ -2549,6 +3661,15 @@ packages: bs58: 5.0.0 dev: false + /bser@2.1.1: + resolution: {integrity: sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==} + dependencies: + node-int64: 0.4.0 + dev: true + + /buffer-from@1.1.2: + resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} + /buffer-xor@1.0.3: resolution: {integrity: sha512-571s0T7nZWK6vB67HI5dyUF7wXiNcfaPPPTl6zYCNApANjIvYJTg7hlud/+cJpdAhS7dVzqMLmfhfHR3rAcOjQ==} dev: true @@ -2576,7 +3697,10 @@ packages: engines: {node: '>=10.16.0'} dependencies: streamsearch: 1.1.0 - dev: false + + /bytes@3.1.2: + resolution: {integrity: sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==} + engines: {node: '>= 0.8'} /cac@6.7.14: resolution: {integrity: sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==} @@ -2592,7 +3716,6 @@ packages: function-bind: 1.1.2 get-intrinsic: 1.2.4 set-function-length: 1.2.2 - dev: true /callsites@3.1.0: resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} @@ -2626,7 +3749,6 @@ packages: /camelcase@6.3.0: resolution: {integrity: sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==} engines: {node: '>=10'} - dev: false /caniuse-lite@1.0.30001599: resolution: {integrity: sha512-LRAQHZ4yT1+f9LemSMeqdMpMxZcc4RMWdj4tiFe3G8tNkWK+E58g+/tzotb5cU6TbcVJLr4fySiAW7XmxQvZQA==} @@ -2659,13 +3781,17 @@ packages: dependencies: ansi-styles: 4.3.0 supports-color: 7.2.0 - dev: true /chalk@5.3.0: resolution: {integrity: sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==} engines: {node: ^12.17.0 || ^14.13 || >=16.0.0} dev: true + /char-regex@1.0.2: + resolution: {integrity: sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==} + engines: {node: '>=10'} + dev: true + /chardet@0.7.0: resolution: {integrity: sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==} dev: true @@ -2676,6 +3802,26 @@ packages: get-func-name: 2.0.2 dev: true + /chokidar@3.6.0: + resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==} + engines: {node: '>= 8.10.0'} + dependencies: + anymatch: 3.1.3 + braces: 3.0.2 + glob-parent: 5.1.2 + is-binary-path: 2.1.0 + is-glob: 4.0.3 + normalize-path: 3.0.0 + readdirp: 3.6.0 + optionalDependencies: + fsevents: 2.3.3 + dev: true + + /chrome-trace-event@1.0.4: + resolution: {integrity: sha512-rNjApaLzuwaOTjCiT8lSDdGN1APCiqkChLMJxJPWLunPAt5fy8xgU9/jNOchV84wfIxrA0lRQB7oCT8jrn/wrQ==} + engines: {node: '>=6.0'} + dev: true + /ci-info@3.9.0: resolution: {integrity: sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==} engines: {node: '>=8'} @@ -2687,6 +3833,17 @@ packages: inherits: 2.0.4 safe-buffer: 5.2.1 + /cjs-module-lexer@1.3.1: + resolution: {integrity: sha512-a3KdPAANPbNE4ZUv9h6LckSl9zLsYOP4MBmhIPkRaeyybt+r4UghLvq+xw/YwUcC1gqylCkL4rdVs3Lwupjm4Q==} + dev: true + + /cli-cursor@3.1.0: + resolution: {integrity: sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==} + engines: {node: '>=8'} + dependencies: + restore-cursor: 3.1.0 + dev: true + /cli-cursor@4.0.0: resolution: {integrity: sha512-VGtlMu3x/4DOtIUwEkRezxUZ2lBacNJCHash0N0WeZDBS+7Ux1dm3XWAgWYxLJFMMdOeXMHXorshEFhbMSGelg==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} @@ -2694,6 +3851,20 @@ packages: restore-cursor: 4.0.0 dev: true + /cli-spinners@2.9.2: + resolution: {integrity: sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg==} + engines: {node: '>=6'} + dev: true + + /cli-table3@0.6.3: + resolution: {integrity: sha512-w5Jac5SykAeZJKntOxJCrm63Eg5/4dhMWIcuTbo9rpE+brgaSZo0RuNJZeOyMgsUdhDeojvgyQLmjI+K50ZGyg==} + engines: {node: 10.* || >= 12.*} + dependencies: + string-width: 4.2.3 + optionalDependencies: + '@colors/colors': 1.5.0 + dev: true + /cli-truncate@4.0.0: resolution: {integrity: sha512-nPdaFdQ0h/GEigbPClz11D0v/ZJEwxmeVZGeMo3Z5StPtUTkA9o1lD6QwoirYiSDzbcwn2XcjwmCp68W1IS4TA==} engines: {node: '>=18'} @@ -2702,6 +3873,16 @@ packages: string-width: 7.1.0 dev: true + /cli-width@3.0.0: + resolution: {integrity: sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw==} + engines: {node: '>= 10'} + dev: true + + /cli-width@4.1.0: + resolution: {integrity: sha512-ouuZd4/dm2Sw5Gmqy6bGyNNNe1qt9RpmxveLSO7KcgsTnU7RXfsw+/bukWGo1abgBiMAic068rclZsO4IWmmxQ==} + engines: {node: '>= 12'} + dev: true + /client-only@0.0.1: resolution: {integrity: sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==} dev: false @@ -2728,6 +3909,15 @@ packages: engines: {node: '>=0.8'} dev: true + /co@4.6.0: + resolution: {integrity: sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==} + engines: {iojs: '>= 1.0.0', node: '>= 0.12.0'} + dev: true + + /collect-v8-coverage@1.0.2: + resolution: {integrity: sha512-lHl4d5/ONEbLlJvaJNtsF/Lz+WvB07u2ycqTYbdrq7UypDXailES4valYb2eWiJFxZlVmpGekfqoxQhzyFdT4Q==} + dev: true + /color-convert@1.9.3: resolution: {integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==} dependencies: @@ -2739,7 +3929,6 @@ packages: engines: {node: '>=7.0.0'} dependencies: color-name: 1.1.4 - dev: true /color-name@1.1.3: resolution: {integrity: sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==} @@ -2747,7 +3936,6 @@ packages: /color-name@1.1.4: resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} - dev: true /colorette@2.0.20: resolution: {integrity: sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==} @@ -2758,7 +3946,6 @@ packages: engines: {node: '>= 0.8'} dependencies: delayed-stream: 1.0.0 - dev: false /commander@11.1.0: resolution: {integrity: sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ==} @@ -2769,10 +3956,42 @@ packages: resolution: {integrity: sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==} dev: true + /commander@4.1.1: + resolution: {integrity: sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==} + engines: {node: '>= 6'} + dev: true + + /comment-json@4.2.3: + resolution: {integrity: sha512-SsxdiOf064DWoZLH799Ata6u7iV658A11PlWtZATDlXPpKGJnbJZ5Z24ybixAi+LUUqJ/GKowAejtC5GFUG7Tw==} + engines: {node: '>= 6'} + dependencies: + array-timsort: 1.0.3 + core-util-is: 1.0.3 + esprima: 4.0.1 + has-own-prop: 2.0.0 + repeat-string: 1.6.1 + dev: true + + /component-emitter@1.3.1: + resolution: {integrity: sha512-T0+barUSQRTUQASh8bx02dl+DhF54GtIDY13Y3m9oWTklKbb3Wv974meRpeZ3lp1JpLVECWWNHC4vaG2XHXouQ==} + dev: true + /concat-map@0.0.1: resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} dev: true + /concat-stream@1.6.2: + resolution: {integrity: sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==} + engines: {'0': node >= 0.8} + dependencies: + buffer-from: 1.1.2 + inherits: 2.0.4 + readable-stream: 2.3.8 + typedarray: 0.0.6 + + /consola@2.15.3: + resolution: {integrity: sha512-9vAdYbHj6x2fLKC4+oPH0kFzY/orMZyG2Aj+kNylHxKGJ/Ed4dpNyAQYwJOdqO4zdM7XpVHmyejQDcQHrnuXbw==} + /console-browserify@1.2.0: resolution: {integrity: sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA==} dev: true @@ -2781,12 +4000,55 @@ packages: resolution: {integrity: sha512-xFxOwqIzR/e1k1gLiWEophSCMqXcwVHIH7akf7b/vxcUeGunlj3hvZaaqxwHsTgn+IndtkQJgSztIDWeumWJDQ==} dev: true + /content-disposition@0.5.4: + resolution: {integrity: sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==} + engines: {node: '>= 0.6'} + dependencies: + safe-buffer: 5.2.1 + + /content-type@1.0.5: + resolution: {integrity: sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==} + engines: {node: '>= 0.6'} + /convert-source-map@2.0.0: resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} dev: true + /cookie-signature@1.0.6: + resolution: {integrity: sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==} + + /cookie@0.6.0: + resolution: {integrity: sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==} + engines: {node: '>= 0.6'} + + /cookiejar@2.1.4: + resolution: {integrity: sha512-LDx6oHrK+PhzLKJU9j5S7/Y3jM/mUHvD/DeI1WQmJn652iPC5Y4TBzC9l+5OMOXlyTTA+SmVUPm0HQUwpD5Jqw==} + dev: true + /core-util-is@1.0.3: resolution: {integrity: sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==} + + /cors@2.8.5: + resolution: {integrity: sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==} + engines: {node: '>= 0.10'} + dependencies: + object-assign: 4.1.1 + vary: 1.1.2 + + /cosmiconfig@8.3.6(typescript@5.3.3): + resolution: {integrity: sha512-kcZ6+W5QzcJ3P1Mt+83OUv/oHFqZHIx8DuxG6eZ5RGMERoLqp4BuGjhHLYGK+Kf5XVkQvqBSmAy/nGWN3qDgEA==} + engines: {node: '>=14'} + peerDependencies: + typescript: '>=4.9.5' + peerDependenciesMeta: + typescript: + optional: true + dependencies: + import-fresh: 3.3.0 + js-yaml: 4.1.0 + parse-json: 5.2.0 + path-type: 4.0.0 + typescript: 5.3.3 dev: true /create-ecdh@4.0.4: @@ -2816,6 +4078,25 @@ packages: sha.js: 2.4.11 dev: true + /create-jest@29.7.0(@types/node@20.12.12)(ts-node@10.9.2): + resolution: {integrity: sha512-Adz2bdH0Vq3F53KEMJOoftQFutWCukm6J24wbPWRO4k1kMY7gS7ds/uoJkNuV8wDCtWWnuwGcJwpWcih+zEW1Q==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + hasBin: true + dependencies: + '@jest/types': 29.6.3 + chalk: 4.1.2 + exit: 0.1.2 + graceful-fs: 4.2.11 + jest-config: 29.7.0(@types/node@20.12.12)(ts-node@10.9.2) + jest-util: 29.7.0 + prompts: 2.4.2 + transitivePeerDependencies: + - '@types/node' + - babel-plugin-macros + - supports-color + - ts-node + dev: true + /create-require@1.1.1: resolution: {integrity: sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==} dev: true @@ -2918,6 +4199,16 @@ packages: resolution: {integrity: sha512-68s5jYdlvasItOJnCuI2Q9s4q98g0pCyL3HrcKJu8KNugUl8ahgmZYg38ysLTgQjjXX3H8CJLkAvWrclWfcalw==} dev: true + /debug@2.6.9: + resolution: {integrity: sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + dependencies: + ms: 2.0.0 + /debug@4.3.4: resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==} engines: {node: '>=6.0'} @@ -2943,6 +4234,15 @@ packages: engines: {node: '>=0.10.0'} dev: true + /dedent@1.5.3: + resolution: {integrity: sha512-NHQtfOOW68WD8lgypbLA5oT+Bt0xXJhiYvoR6SmmNXZfpzOGXwdKWmcwG8N7PwVVWV3eF/68nmD9BaJSsTBhyQ==} + peerDependencies: + babel-plugin-macros: ^3.1.0 + peerDependenciesMeta: + babel-plugin-macros: + optional: true + dev: true + /deep-eql@4.1.3: resolution: {integrity: sha512-WaEtAOpRA1MQ0eohqZjpGD8zdI0Ovsm8mmFhaDN8dvDZzyoUMcYDnf5Y6iu7HTXxf8JDS23qWa4a+hKCDyOPzw==} engines: {node: '>=6'} @@ -2958,6 +4258,11 @@ packages: resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} dev: true + /deepmerge@4.3.1: + resolution: {integrity: sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==} + engines: {node: '>=0.10.0'} + dev: true + /defaults@1.0.4: resolution: {integrity: sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==} dependencies: @@ -2971,7 +4276,6 @@ packages: es-define-property: 1.0.0 es-errors: 1.3.0 gopd: 1.0.1 - dev: true /define-properties@1.2.1: resolution: {integrity: sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==} @@ -2985,7 +4289,10 @@ packages: /delayed-stream@1.0.0: resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} engines: {node: '>=0.4.0'} - dev: false + + /depd@2.0.0: + resolution: {integrity: sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==} + engines: {node: '>= 0.8'} /des.js@1.1.0: resolution: {integrity: sha512-r17GxjhUCjSRy8aiJpr8/UadFIzMzJGexI3Nmz4ADi9LYSFx4gTBp80+NaX/YsXWWLhpZ7v/v/ubEc/bCNfKwg==} @@ -2994,11 +4301,27 @@ packages: minimalistic-assert: 1.0.1 dev: true + /destroy@1.2.0: + resolution: {integrity: sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==} + engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16} + /detect-indent@6.1.0: resolution: {integrity: sha512-reYkTUJAZb9gUuZ2RvVCNhVHdg62RHnJ7WJl8ftMi4diZ6NWlciOzQN88pUhSELEwflJht4oQDv0F0BMlwaYtA==} engines: {node: '>=8'} dev: true + /detect-newline@3.1.0: + resolution: {integrity: sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==} + engines: {node: '>=8'} + dev: true + + /dezalgo@1.0.4: + resolution: {integrity: sha512-rXSP0bf+5n0Qonsb+SVVfNfIsimO4HEtmnIpPHY8Q1UCzKlQrDMfdobr8nJOOsRgWCyMRqeSBQzmWUMq7zvVig==} + dependencies: + asap: 2.0.6 + wrappy: 1.0.2 + dev: true + /diff-sequences@29.6.3: resolution: {integrity: sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} @@ -3058,6 +4381,9 @@ packages: wif: 2.0.6 dev: false + /ee-first@1.1.1: + resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==} + /electron-to-chromium@1.4.710: resolution: {integrity: sha512-w+9yAVHoHhysCa+gln7AzbO9CdjFcL/wN/5dd+XW/Msl2d/4+WisEaCF1nty0xbAKaxdaJfgLB2296U7zZB7BA==} dev: true @@ -3085,6 +4411,11 @@ packages: minimalistic-assert: 1.0.1 minimalistic-crypto-utils: 1.0.1 + /emittery@0.13.1: + resolution: {integrity: sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ==} + engines: {node: '>=12'} + dev: true + /emoji-regex@10.3.0: resolution: {integrity: sha512-QpLs9D9v9kArv4lfDEgg1X/gN5XLnf/A6l9cs8SPZLRZR3ZkY9+kwIQTxm+fsSej5UMYGE8fdoaZVIBlqG0XTw==} dev: true @@ -3097,6 +4428,18 @@ packages: resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} dev: true + /encodeurl@1.0.2: + resolution: {integrity: sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==} + engines: {node: '>= 0.8'} + + /enhanced-resolve@5.16.1: + resolution: {integrity: sha512-4U5pNsuDl0EhuZpq46M5xPslstkviJuhrdobaRDBk2Jy2KO37FDAJl4lb2KlNabxT0m4MTK2UHNrsAcphE8nyw==} + engines: {node: '>=10.13.0'} + dependencies: + graceful-fs: 4.2.11 + tapable: 2.2.1 + dev: true + /enquirer@2.4.1: resolution: {integrity: sha512-rRqJg/6gd538VHvR3PSrdRBb/1Vy2YfzHqzvbhGIQpDRKIa4FgV/54b5Q1xYSxOOwKvjXweS26E0Q+nAMwp2pQ==} engines: {node: '>=8.6'} @@ -3168,11 +4511,13 @@ packages: engines: {node: '>= 0.4'} dependencies: get-intrinsic: 1.2.4 - dev: true /es-errors@1.3.0: resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==} engines: {node: '>= 0.4'} + + /es-module-lexer@1.5.3: + resolution: {integrity: sha512-i1gCgmR9dCl6Vil6UKPI/trA69s08g/syhiDK9TG0Nf1RJjjFI+AzoWW7sPufzkgYAn861skuCwJa0pIIHYxvg==} dev: true /es-object-atoms@1.0.0: @@ -3242,16 +4587,29 @@ packages: engines: {node: '>=6'} dev: true + /escape-html@1.0.3: + resolution: {integrity: sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==} + /escape-string-regexp@1.0.5: resolution: {integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==} engines: {node: '>=0.8.0'} dev: true + /escape-string-regexp@2.0.0: + resolution: {integrity: sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==} + engines: {node: '>=8'} + dev: true + /escape-string-regexp@4.0.0: resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} engines: {node: '>=10'} dev: true + /escape-string-regexp@5.0.0: + resolution: {integrity: sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==} + engines: {node: '>=12'} + dev: true + /eslint-plugin-react-hooks@4.6.0(eslint@8.56.0): resolution: {integrity: sha512-oFc7Itz9Qxh2x4gNHStv3BqJq54ExXmfC+a1NjAta66IAN87Wu0R/QArgIS9qKzX3dXKPI9H5crl9QchNMY9+g==} engines: {node: '>=10'} @@ -3269,6 +4627,14 @@ packages: eslint: 8.56.0 dev: true + /eslint-scope@5.1.1: + resolution: {integrity: sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==} + engines: {node: '>=8.0.0'} + dependencies: + esrecurse: 4.3.0 + estraverse: 4.3.0 + dev: true + /eslint-scope@7.2.2: resolution: {integrity: sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} @@ -3358,6 +4724,11 @@ packages: estraverse: 5.3.0 dev: true + /estraverse@4.3.0: + resolution: {integrity: sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==} + engines: {node: '>=4.0'} + dev: true + /estraverse@5.3.0: resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==} engines: {node: '>=4.0'} @@ -3378,6 +4749,10 @@ packages: engines: {node: '>=0.10.0'} dev: true + /etag@1.8.1: + resolution: {integrity: sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==} + engines: {node: '>= 0.6'} + /event-target-shim@5.0.1: resolution: {integrity: sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==} engines: {node: '>=6'} @@ -3398,6 +4773,21 @@ packages: safe-buffer: 5.2.1 dev: true + /execa@5.1.1: + resolution: {integrity: sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==} + engines: {node: '>=10'} + dependencies: + cross-spawn: 7.0.3 + get-stream: 6.0.1 + human-signals: 2.1.0 + is-stream: 2.0.1 + merge-stream: 2.0.0 + npm-run-path: 4.0.1 + onetime: 5.1.2 + signal-exit: 3.0.7 + strip-final-newline: 2.0.0 + dev: true + /execa@8.0.1: resolution: {integrity: sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==} engines: {node: '>=16.17'} @@ -3413,6 +4803,60 @@ packages: strip-final-newline: 3.0.0 dev: true + /exit@0.1.2: + resolution: {integrity: sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ==} + engines: {node: '>= 0.8.0'} + dev: true + + /expect@29.7.0: + resolution: {integrity: sha512-2Zks0hf1VLFYI1kbh0I5jP3KHHyCHpkfyHBzsSXRFgl/Bg9mWYfMW8oD+PdMPlEwy5HNsR9JutYy6pMeOh61nw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@jest/expect-utils': 29.7.0 + jest-get-type: 29.6.3 + jest-matcher-utils: 29.7.0 + jest-message-util: 29.7.0 + jest-util: 29.7.0 + dev: true + + /express@4.19.2: + resolution: {integrity: sha512-5T6nhjsT+EOMzuck8JjBHARTHfMht0POzlA60WV2pMD3gyXw2LZnZ+ueGdNxG+0calOJcWKbpFcuzLZ91YWq9Q==} + engines: {node: '>= 0.10.0'} + dependencies: + accepts: 1.3.8 + array-flatten: 1.1.1 + body-parser: 1.20.2 + content-disposition: 0.5.4 + content-type: 1.0.5 + cookie: 0.6.0 + cookie-signature: 1.0.6 + debug: 2.6.9 + depd: 2.0.0 + encodeurl: 1.0.2 + escape-html: 1.0.3 + etag: 1.8.1 + finalhandler: 1.2.0 + fresh: 0.5.2 + http-errors: 2.0.0 + merge-descriptors: 1.0.1 + methods: 1.1.2 + on-finished: 2.4.1 + parseurl: 1.3.3 + path-to-regexp: 0.1.7 + proxy-addr: 2.0.7 + qs: 6.11.0 + range-parser: 1.2.1 + safe-buffer: 5.2.1 + send: 0.18.0 + serve-static: 1.15.0 + setprototypeof: 1.2.0 + statuses: 2.0.1 + type-is: 1.6.18 + utils-merge: 1.0.1 + vary: 1.1.2 + transitivePeerDependencies: + - supports-color + /extendable-error@0.1.7: resolution: {integrity: sha512-UOiS2in6/Q0FK0R0q6UY9vYpQ21mr/Qn1KOnte7vsACuNJf514WvCCUHSRCPcgjPT2bAhNIJdlE6bVap1GKmeg==} dev: true @@ -3449,12 +4893,36 @@ packages: resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==} dev: true + /fast-safe-stringify@2.1.1: + resolution: {integrity: sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==} + /fastq@1.17.1: resolution: {integrity: sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==} dependencies: reusify: 1.0.4 dev: true + /fb-watchman@2.0.2: + resolution: {integrity: sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==} + dependencies: + bser: 2.1.1 + dev: true + + /figures@3.2.0: + resolution: {integrity: sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==} + engines: {node: '>=8'} + dependencies: + escape-string-regexp: 1.0.5 + dev: true + + /figures@5.0.0: + resolution: {integrity: sha512-ej8ksPF4x6e5wvK9yevct0UCXh8TTFlWGVLlgjZuoBH1HwjIfKE/IdL5mq89sFA7zELi1VhKpmtDnrs7zWyeyg==} + engines: {node: '>=14'} + dependencies: + escape-string-regexp: 5.0.0 + is-unicode-supported: 1.3.0 + dev: true + /file-entry-cache@6.0.1: resolution: {integrity: sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==} engines: {node: ^10.12.0 || >=12.0.0} @@ -3469,6 +4937,20 @@ packages: to-regex-range: 5.0.1 dev: true + /finalhandler@1.2.0: + resolution: {integrity: sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==} + engines: {node: '>= 0.8'} + dependencies: + debug: 2.6.9 + encodeurl: 1.0.2 + escape-html: 1.0.3 + on-finished: 2.4.1 + parseurl: 1.3.3 + statuses: 2.0.1 + unpipe: 1.0.0 + transitivePeerDependencies: + - supports-color + /find-up@4.1.0: resolution: {integrity: sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==} engines: {node: '>=8'} @@ -3529,14 +5011,62 @@ packages: signal-exit: 4.1.0 dev: true - /form-data@4.0.0: - resolution: {integrity: sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==} - engines: {node: '>= 6'} + /fork-ts-checker-webpack-plugin@9.0.2(typescript@5.3.3)(webpack@5.90.1): + resolution: {integrity: sha512-Uochze2R8peoN1XqlSi/rGUkDQpRogtLFocP9+PGu68zk1BDAKXfdeCdyVZpgTk8V8WFVQXdEz426VKjXLO1Gg==} + engines: {node: '>=12.13.0', yarn: '>=1.0.0'} + peerDependencies: + typescript: '>3.6.0' + webpack: ^5.11.0 dependencies: - asynckit: 0.4.0 - combined-stream: 1.0.8 + '@babel/code-frame': 7.24.2 + chalk: 4.1.2 + chokidar: 3.6.0 + cosmiconfig: 8.3.6(typescript@5.3.3) + deepmerge: 4.3.1 + fs-extra: 10.1.0 + memfs: 3.5.3 + minimatch: 3.1.2 + node-abort-controller: 3.1.1 + schema-utils: 3.3.0 + semver: 7.6.0 + tapable: 2.2.1 + typescript: 5.3.3 + webpack: 5.90.1 + dev: true + + /form-data@4.0.0: + resolution: {integrity: sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==} + engines: {node: '>= 6'} + dependencies: + asynckit: 0.4.0 + combined-stream: 1.0.8 mime-types: 2.1.35 - dev: false + + /formidable@2.1.2: + resolution: {integrity: sha512-CM3GuJ57US06mlpQ47YcunuUZ9jpm8Vx+P2CGt2j7HpgkKZO/DJYQ0Bobim8G6PFQmK5lOqOOdUXboU+h73A4g==} + dependencies: + dezalgo: 1.0.4 + hexoid: 1.0.0 + once: 1.4.0 + qs: 6.12.0 + dev: true + + /forwarded@0.2.0: + resolution: {integrity: sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==} + engines: {node: '>= 0.6'} + + /fresh@0.5.2: + resolution: {integrity: sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==} + engines: {node: '>= 0.6'} + + /fs-extra@10.1.0: + resolution: {integrity: sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==} + engines: {node: '>=12'} + dependencies: + graceful-fs: 4.2.11 + jsonfile: 6.1.0 + universalify: 2.0.1 + dev: true /fs-extra@7.0.1: resolution: {integrity: sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==} @@ -3556,6 +5086,10 @@ packages: universalify: 0.1.2 dev: true + /fs-monkey@1.0.6: + resolution: {integrity: sha512-b1FMfwetIKymC0eioW7mTywihSQE4oLzQn1dB6rZB5fx/3NpNEdAWeCSMB+60/AeT0TCXsxzAlcYVEFCTAksWg==} + dev: true + /fs.realpath@1.0.0: resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} dev: true @@ -3570,7 +5104,6 @@ packages: /function-bind@1.1.2: resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} - dev: true /function.prototype.name@1.1.6: resolution: {integrity: sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg==} @@ -3614,6 +5147,15 @@ packages: has-proto: 1.0.3 has-symbols: 1.0.3 hasown: 2.0.2 + + /get-package-type@0.1.0: + resolution: {integrity: sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==} + engines: {node: '>=8.0.0'} + dev: true + + /get-stream@6.0.1: + resolution: {integrity: sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==} + engines: {node: '>=10'} dev: true /get-stream@8.0.1: @@ -3644,6 +5186,22 @@ packages: is-glob: 4.0.3 dev: true + /glob-to-regexp@0.4.1: + resolution: {integrity: sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==} + dev: true + + /glob@10.3.10: + resolution: {integrity: sha512-fa46+tv1Ak0UPK1TOy/pZrIybNNt4HCv7SDzwyfiOZkvZLEbjsZkJBPtDHVshZjbecAoAGSC20MjLDG/qr679g==} + engines: {node: '>=16 || 14 >=14.17'} + hasBin: true + dependencies: + foreground-child: 3.1.1 + jackspeak: 2.3.6 + minimatch: 9.0.4 + minipass: 7.0.4 + path-scurry: 1.10.2 + dev: true + /glob@10.3.12: resolution: {integrity: sha512-TCNv8vJ+xz4QiqTpfOJA7HvYv+tNIRHKfUWw/q+v2jdgN4ebz+KY9tGx5J4rHP0o84mNP+ApH66HRX8us3Khqg==} engines: {node: '>=16 || 14 >=14.17'} @@ -3658,6 +5216,7 @@ packages: /glob@7.2.3: resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} + deprecated: Glob versions prior to v9 are no longer supported dependencies: fs.realpath: 1.0.0 inflight: 1.0.6 @@ -3667,6 +5226,16 @@ packages: path-is-absolute: 1.0.1 dev: true + /glob@9.3.5: + resolution: {integrity: sha512-e1LleDykUz2Iu+MTYdkSsuWX8lvAjAcs0Xef0lNIu0S2wOAzuTxCJtcd9S3cijlwYF18EsU3rzb8jPVobxDh9Q==} + engines: {node: '>=16 || 14 >=14.17'} + dependencies: + fs.realpath: 1.0.0 + minimatch: 8.0.4 + minipass: 4.2.8 + path-scurry: 1.10.2 + dev: true + /globals@11.12.0: resolution: {integrity: sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==} engines: {node: '>=4'} @@ -3702,7 +5271,6 @@ packages: resolution: {integrity: sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==} dependencies: get-intrinsic: 1.2.4 - dev: true /graceful-fs@4.2.11: resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} @@ -3732,23 +5300,24 @@ packages: /has-flag@4.0.0: resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} engines: {node: '>=8'} + + /has-own-prop@2.0.0: + resolution: {integrity: sha512-Pq0h+hvsVm6dDEa8x82GnLSYHOzNDt7f0ddFa3FqcQlgzEiptPqL+XrOJNavjOzSYiYWIrgeVYYgGlLmnxwilQ==} + engines: {node: '>=8'} dev: true /has-property-descriptors@1.0.2: resolution: {integrity: sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==} dependencies: es-define-property: 1.0.0 - dev: true /has-proto@1.0.3: resolution: {integrity: sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==} engines: {node: '>= 0.4'} - dev: true /has-symbols@1.0.3: resolution: {integrity: sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==} engines: {node: '>= 0.4'} - dev: true /has-tostringtag@1.0.2: resolution: {integrity: sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==} @@ -3784,6 +5353,10 @@ packages: engines: {node: '>= 0.4'} dependencies: function-bind: 1.1.2 + + /hexoid@1.0.0: + resolution: {integrity: sha512-QFLV0taWQOZtvIRIAdBChesmogZrtuXvVWsFHZTk2SU+anspqZ2vMnoLg7IE1+Uk16N19APic1BuF8bC8c2m5g==} + engines: {node: '>=8'} dev: true /hmac-drbg@1.0.1: @@ -3797,6 +5370,20 @@ packages: resolution: {integrity: sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==} dev: true + /html-escaper@2.0.2: + resolution: {integrity: sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==} + dev: true + + /http-errors@2.0.0: + resolution: {integrity: sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==} + engines: {node: '>= 0.8'} + dependencies: + depd: 2.0.0 + inherits: 2.0.4 + setprototypeof: 1.2.0 + statuses: 2.0.1 + toidentifier: 1.0.1 + /https-browserify@1.0.0: resolution: {integrity: sha512-J+FkSdyD+0mA0N+81tMotaRMfSL9SGi+xpD3T6YApKsc3bGSXJlfXri3VyFOeYkfLRQisDk1W+jIFFKBeUBbBg==} dev: true @@ -3805,6 +5392,11 @@ packages: resolution: {integrity: sha512-UNopramDEhHJD+VR+ehk8rOslwSfByxPIZyJRfV739NDhN5LF1fa1MqnzKm2lGTQRjNrjK19Q5fhkgIfjlVUKw==} dev: true + /human-signals@2.1.0: + resolution: {integrity: sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==} + engines: {node: '>=10.17.0'} + dev: true + /human-signals@5.0.0: resolution: {integrity: sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==} engines: {node: '>=16.17.0'} @@ -3821,7 +5413,6 @@ packages: engines: {node: '>=0.10.0'} dependencies: safer-buffer: 2.1.2 - dev: true /ieee754@1.2.1: resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} @@ -3843,6 +5434,15 @@ packages: resolve-from: 4.0.0 dev: true + /import-local@3.1.0: + resolution: {integrity: sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg==} + engines: {node: '>=8'} + hasBin: true + dependencies: + pkg-dir: 4.2.0 + resolve-cwd: 3.0.0 + dev: true + /imurmurhash@0.1.4: resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} engines: {node: '>=0.8.19'} @@ -3863,6 +5463,48 @@ packages: /inherits@2.0.4: resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} + /inquirer@8.2.6: + resolution: {integrity: sha512-M1WuAmb7pn9zdFRtQYk26ZBoY043Sse0wVDdk4Bppr+JOXyQYybdtvK+l9wUibhtjdjvtoiNy8tk+EgsYIUqKg==} + engines: {node: '>=12.0.0'} + dependencies: + ansi-escapes: 4.3.2 + chalk: 4.1.2 + cli-cursor: 3.1.0 + cli-width: 3.0.0 + external-editor: 3.1.0 + figures: 3.2.0 + lodash: 4.17.21 + mute-stream: 0.0.8 + ora: 5.4.1 + run-async: 2.4.1 + rxjs: 7.8.1 + string-width: 4.2.3 + strip-ansi: 6.0.1 + through: 2.3.8 + wrap-ansi: 6.2.0 + dev: true + + /inquirer@9.2.12: + resolution: {integrity: sha512-mg3Fh9g2zfuVWJn6lhST0O7x4n03k7G8Tx5nvikJkbq8/CK47WDVm+UznF0G6s5Zi0KcyUisr6DU8T67N5U+1Q==} + engines: {node: '>=14.18.0'} + dependencies: + '@ljharb/through': 2.3.13 + ansi-escapes: 4.3.2 + chalk: 5.3.0 + cli-cursor: 3.1.0 + cli-width: 4.1.0 + external-editor: 3.1.0 + figures: 5.0.0 + lodash: 4.17.21 + mute-stream: 1.0.0 + ora: 5.4.1 + run-async: 3.0.0 + rxjs: 7.8.1 + string-width: 4.2.3 + strip-ansi: 6.0.1 + wrap-ansi: 6.2.0 + dev: true + /internal-slot@1.0.7: resolution: {integrity: sha512-NGnrKwXzSms2qUUih/ILZ5JBqNTSa1+ZmP6flaIp6KmSElgE9qdndzS3cqjrDovwFdmwsGsLdeFgB6suw+1e9g==} engines: {node: '>= 0.4'} @@ -3872,6 +5514,15 @@ packages: side-channel: 1.0.6 dev: true + /interpret@1.4.0: + resolution: {integrity: sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==} + engines: {node: '>= 0.10'} + dev: true + + /ipaddr.js@1.9.1: + resolution: {integrity: sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==} + engines: {node: '>= 0.10'} + /is-arguments@1.1.1: resolution: {integrity: sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==} engines: {node: '>= 0.4'} @@ -3898,6 +5549,13 @@ packages: has-bigints: 1.0.2 dev: true + /is-binary-path@2.1.0: + resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==} + engines: {node: '>=8'} + dependencies: + binary-extensions: 2.3.0 + dev: true + /is-boolean-object@1.1.2: resolution: {integrity: sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==} engines: {node: '>= 0.4'} @@ -3953,6 +5611,11 @@ packages: get-east-asian-width: 1.2.0 dev: true + /is-generator-fn@2.1.0: + resolution: {integrity: sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==} + engines: {node: '>=6'} + dev: true + /is-generator-function@1.0.10: resolution: {integrity: sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==} engines: {node: '>= 0.4'} @@ -3967,6 +5630,11 @@ packages: is-extglob: 2.1.1 dev: true + /is-interactive@1.0.0: + resolution: {integrity: sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==} + engines: {node: '>=8'} + dev: true + /is-nan@1.3.2: resolution: {integrity: sha512-E+zBKpQ2t6MEo1VsonYmluk9NxGrbzpeeLC2xIViuO2EjU2xsXsBPwTr3Ykv9l08UYEVEdWeRZNouaZqF6RN0w==} engines: {node: '>= 0.4'} @@ -4017,6 +5685,11 @@ packages: call-bind: 1.0.7 dev: true + /is-stream@2.0.1: + resolution: {integrity: sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==} + engines: {node: '>=8'} + dev: true + /is-stream@3.0.0: resolution: {integrity: sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} @@ -4050,48 +5723,540 @@ packages: which-typed-array: 1.1.15 dev: true + /is-unicode-supported@0.1.0: + resolution: {integrity: sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==} + engines: {node: '>=10'} + dev: true + + /is-unicode-supported@1.3.0: + resolution: {integrity: sha512-43r2mRvz+8JRIKnWJ+3j8JtjRKZ6GmjzfaE/qiBJnikNnYv/6bagRJ1kUhNk8R5EX/GkobD+r+sfxCPJsiKBLQ==} + engines: {node: '>=12'} + dev: true + /is-weakref@1.0.2: resolution: {integrity: sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==} dependencies: - call-bind: 1.0.7 + call-bind: 1.0.7 + dev: true + + /is-windows@1.0.2: + resolution: {integrity: sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==} + engines: {node: '>=0.10.0'} + dev: true + + /isarray@1.0.0: + resolution: {integrity: sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==} + + /isarray@2.0.5: + resolution: {integrity: sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==} + dev: true + + /isexe@2.0.0: + resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} + dev: true + + /isobject@2.1.0: + resolution: {integrity: sha512-+OUdGJlgjOBZDfxnDjYYG6zp487z0JGNQq3cYQYg5f5hKR+syHMsaztzGeml/4kGG55CSpKSpWTY+jYGgsHLgA==} + engines: {node: '>=0.10.0'} + dependencies: + isarray: 1.0.0 + dev: true + + /isomorphic-timers-promises@1.0.1: + resolution: {integrity: sha512-u4sej9B1LPSxTGKB/HiuzvEQnXH0ECYkSVQU39koSwmFAxhlEAFl9RdTvLv4TOTQUgBS5O3O5fwUxk6byBZ+IQ==} + engines: {node: '>=10'} + dev: true + + /istanbul-lib-coverage@3.2.2: + resolution: {integrity: sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==} + engines: {node: '>=8'} + dev: true + + /istanbul-lib-instrument@5.2.1: + resolution: {integrity: sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==} + engines: {node: '>=8'} + dependencies: + '@babel/core': 7.24.0 + '@babel/parser': 7.24.0 + '@istanbuljs/schema': 0.1.3 + istanbul-lib-coverage: 3.2.2 + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + dev: true + + /istanbul-lib-instrument@6.0.2: + resolution: {integrity: sha512-1WUsZ9R1lA0HtBSohTkm39WTPlNKSJ5iFk7UwqXkBLoHQT+hfqPsfsTDVuZdKGaBwn7din9bS7SsnoAr943hvw==} + engines: {node: '>=10'} + dependencies: + '@babel/core': 7.24.0 + '@babel/parser': 7.24.0 + '@istanbuljs/schema': 0.1.3 + istanbul-lib-coverage: 3.2.2 + semver: 7.6.0 + transitivePeerDependencies: + - supports-color + dev: true + + /istanbul-lib-report@3.0.1: + resolution: {integrity: sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==} + engines: {node: '>=10'} + dependencies: + istanbul-lib-coverage: 3.2.2 + make-dir: 4.0.0 + supports-color: 7.2.0 + dev: true + + /istanbul-lib-source-maps@4.0.1: + resolution: {integrity: sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==} + engines: {node: '>=10'} + dependencies: + debug: 4.3.4 + istanbul-lib-coverage: 3.2.2 + source-map: 0.6.1 + transitivePeerDependencies: + - supports-color + dev: true + + /istanbul-reports@3.1.7: + resolution: {integrity: sha512-BewmUXImeuRk2YY0PVbxgKAysvhRPUQE0h5QRM++nVWyubKGV0l8qQ5op8+B2DOmwSe63Jivj0BjkPQVf8fP5g==} + engines: {node: '>=8'} + dependencies: + html-escaper: 2.0.2 + istanbul-lib-report: 3.0.1 + dev: true + + /iterare@1.2.1: + resolution: {integrity: sha512-RKYVTCjAnRthyJes037NX/IiqeidgN1xc3j1RjFfECFp28A1GVwK9nA+i0rJPaHqSZwygLzRnFlzUuHFoWWy+Q==} + engines: {node: '>=6'} + + /jackspeak@2.3.6: + resolution: {integrity: sha512-N3yCS/NegsOBokc8GAdM8UcmfsKiSS8cipheD/nivzr700H+nsMOxJjQnvwOcRYVuFkdH0wGUvW2WbXGmrZGbQ==} + engines: {node: '>=14'} + dependencies: + '@isaacs/cliui': 8.0.2 + optionalDependencies: + '@pkgjs/parseargs': 0.11.0 + dev: true + + /jest-changed-files@29.7.0: + resolution: {integrity: sha512-fEArFiwf1BpQ+4bXSprcDc3/x4HSzL4al2tozwVpDFpsxALjLYdyiIK4e5Vz66GQJIbXJ82+35PtysofptNX2w==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + execa: 5.1.1 + jest-util: 29.7.0 + p-limit: 3.1.0 + dev: true + + /jest-circus@29.7.0: + resolution: {integrity: sha512-3E1nCMgipcTkCocFwM90XXQab9bS+GMsjdpmPrlelaxwD93Ad8iVEjX/vvHPdLPnFf+L40u+5+iutRdA1N9myw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@jest/environment': 29.7.0 + '@jest/expect': 29.7.0 + '@jest/test-result': 29.7.0 + '@jest/types': 29.6.3 + '@types/node': 20.12.12 + chalk: 4.1.2 + co: 4.6.0 + dedent: 1.5.3 + is-generator-fn: 2.1.0 + jest-each: 29.7.0 + jest-matcher-utils: 29.7.0 + jest-message-util: 29.7.0 + jest-runtime: 29.7.0 + jest-snapshot: 29.7.0 + jest-util: 29.7.0 + p-limit: 3.1.0 + pretty-format: 29.7.0 + pure-rand: 6.1.0 + slash: 3.0.0 + stack-utils: 2.0.6 + transitivePeerDependencies: + - babel-plugin-macros + - supports-color + dev: true + + /jest-cli@29.7.0(@types/node@20.12.12)(ts-node@10.9.2): + resolution: {integrity: sha512-OVVobw2IubN/GSYsxETi+gOe7Ka59EFMR/twOU3Jb2GnKKeMGJB5SGUUrEz3SFVmJASUdZUzy83sLNNQ2gZslg==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + hasBin: true + peerDependencies: + node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 + peerDependenciesMeta: + node-notifier: + optional: true + dependencies: + '@jest/core': 29.7.0(ts-node@10.9.2) + '@jest/test-result': 29.7.0 + '@jest/types': 29.6.3 + chalk: 4.1.2 + create-jest: 29.7.0(@types/node@20.12.12)(ts-node@10.9.2) + exit: 0.1.2 + import-local: 3.1.0 + jest-config: 29.7.0(@types/node@20.12.12)(ts-node@10.9.2) + jest-util: 29.7.0 + jest-validate: 29.7.0 + yargs: 17.7.2 + transitivePeerDependencies: + - '@types/node' + - babel-plugin-macros + - supports-color + - ts-node + dev: true + + /jest-config@29.7.0(@types/node@20.12.12)(ts-node@10.9.2): + resolution: {integrity: sha512-uXbpfeQ7R6TZBqI3/TxCU4q4ttk3u0PJeC+E0zbfSoSjq6bJ7buBPxzQPL0ifrkY4DNu4JUdk0ImlBUYi840eQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + peerDependencies: + '@types/node': '*' + ts-node: '>=9.0.0' + peerDependenciesMeta: + '@types/node': + optional: true + ts-node: + optional: true + dependencies: + '@babel/core': 7.24.0 + '@jest/test-sequencer': 29.7.0 + '@jest/types': 29.6.3 + '@types/node': 20.12.12 + babel-jest: 29.7.0(@babel/core@7.24.0) + chalk: 4.1.2 + ci-info: 3.9.0 + deepmerge: 4.3.1 + glob: 7.2.3 + graceful-fs: 4.2.11 + jest-circus: 29.7.0 + jest-environment-node: 29.7.0 + jest-get-type: 29.6.3 + jest-regex-util: 29.6.3 + jest-resolve: 29.7.0 + jest-runner: 29.7.0 + jest-util: 29.7.0 + jest-validate: 29.7.0 + micromatch: 4.0.5 + parse-json: 5.2.0 + pretty-format: 29.7.0 + slash: 3.0.0 + strip-json-comments: 3.1.1 + ts-node: 10.9.2(@types/node@20.12.12)(typescript@5.4.3) + transitivePeerDependencies: + - babel-plugin-macros + - supports-color + dev: true + + /jest-diff@29.7.0: + resolution: {integrity: sha512-LMIgiIrhigmPrs03JHpxUh2yISK3vLFPkAodPeo0+BuF7wA2FoQbkEg1u8gBYBThncu7e1oEDUfIXVuTqLRUjw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + chalk: 4.1.2 + diff-sequences: 29.6.3 + jest-get-type: 29.6.3 + pretty-format: 29.7.0 + dev: true + + /jest-docblock@29.7.0: + resolution: {integrity: sha512-q617Auw3A612guyaFgsbFeYpNP5t2aoUNLwBUbc/0kD1R4t9ixDbyFTHd1nok4epoVFpr7PmeWHrhvuV3XaJ4g==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + detect-newline: 3.1.0 + dev: true + + /jest-each@29.7.0: + resolution: {integrity: sha512-gns+Er14+ZrEoC5fhOfYCY1LOHHr0TI+rQUHZS8Ttw2l7gl+80eHc/gFf2Ktkw0+SIACDTeWvpFcv3B04VembQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@jest/types': 29.6.3 + chalk: 4.1.2 + jest-get-type: 29.6.3 + jest-util: 29.7.0 + pretty-format: 29.7.0 + dev: true + + /jest-environment-node@29.7.0: + resolution: {integrity: sha512-DOSwCRqXirTOyheM+4d5YZOrWcdu0LNZ87ewUoywbcb2XR4wKgqiG8vNeYwhjFMbEkfju7wx2GYH0P2gevGvFw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@jest/environment': 29.7.0 + '@jest/fake-timers': 29.7.0 + '@jest/types': 29.6.3 + '@types/node': 20.12.12 + jest-mock: 29.7.0 + jest-util: 29.7.0 + dev: true + + /jest-get-type@29.6.3: + resolution: {integrity: sha512-zrteXnqYxfQh7l5FHyL38jL39di8H8rHoecLH3JNxH3BwOrBsNeabdap5e0I23lD4HHI8W5VFBZqG4Eaq5LNcw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dev: true + + /jest-haste-map@29.7.0: + resolution: {integrity: sha512-fP8u2pyfqx0K1rGn1R9pyE0/KTn+G7PxktWidOBTqFPLYX0b9ksaMFkhK5vrS3DVun09pckLdlx90QthlW7AmA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@jest/types': 29.6.3 + '@types/graceful-fs': 4.1.9 + '@types/node': 20.12.12 + anymatch: 3.1.3 + fb-watchman: 2.0.2 + graceful-fs: 4.2.11 + jest-regex-util: 29.6.3 + jest-util: 29.7.0 + jest-worker: 29.7.0 + micromatch: 4.0.5 + walker: 1.0.8 + optionalDependencies: + fsevents: 2.3.3 + dev: true + + /jest-leak-detector@29.7.0: + resolution: {integrity: sha512-kYA8IJcSYtST2BY9I+SMC32nDpBT3J2NvWJx8+JCuCdl/CR1I4EKUJROiP8XtCcxqgTTBGJNdbB1A8XRKbTetw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + jest-get-type: 29.6.3 + pretty-format: 29.7.0 + dev: true + + /jest-matcher-utils@29.7.0: + resolution: {integrity: sha512-sBkD+Xi9DtcChsI3L3u0+N0opgPYnCRPtGcQYrgXmR+hmt/fYfWAL0xRXYU8eWOdfuLgBe0YCW3AFtnRLagq/g==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + chalk: 4.1.2 + jest-diff: 29.7.0 + jest-get-type: 29.6.3 + pretty-format: 29.7.0 + dev: true + + /jest-message-util@29.7.0: + resolution: {integrity: sha512-GBEV4GRADeP+qtB2+6u61stea8mGcOT4mCtrYISZwfu9/ISHFJ/5zOMXYbpBE9RsS5+Gb63DW4FgmnKJ79Kf6w==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@babel/code-frame': 7.24.2 + '@jest/types': 29.6.3 + '@types/stack-utils': 2.0.3 + chalk: 4.1.2 + graceful-fs: 4.2.11 + micromatch: 4.0.5 + pretty-format: 29.7.0 + slash: 3.0.0 + stack-utils: 2.0.6 + dev: true + + /jest-mock@29.7.0: + resolution: {integrity: sha512-ITOMZn+UkYS4ZFh83xYAOzWStloNzJFO2s8DWrE4lhtGD+AorgnbkiKERe4wQVBydIGPx059g6riW5Btp6Llnw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@jest/types': 29.6.3 + '@types/node': 20.12.12 + jest-util: 29.7.0 + dev: true + + /jest-pnp-resolver@1.2.3(jest-resolve@29.7.0): + resolution: {integrity: sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w==} + engines: {node: '>=6'} + peerDependencies: + jest-resolve: '*' + peerDependenciesMeta: + jest-resolve: + optional: true + dependencies: + jest-resolve: 29.7.0 + dev: true + + /jest-regex-util@29.6.3: + resolution: {integrity: sha512-KJJBsRCyyLNWCNBOvZyRDnAIfUiRJ8v+hOBQYGn8gDyF3UegwiP4gwRR3/SDa42g1YbVycTidUF3rKjyLFDWbg==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dev: true + + /jest-resolve-dependencies@29.7.0: + resolution: {integrity: sha512-un0zD/6qxJ+S0et7WxeI3H5XSe9lTBBR7bOHCHXkKR6luG5mwDDlIzVQ0V5cZCuoTgEdcdwzTghYkTWfubi+nA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + jest-regex-util: 29.6.3 + jest-snapshot: 29.7.0 + transitivePeerDependencies: + - supports-color + dev: true + + /jest-resolve@29.7.0: + resolution: {integrity: sha512-IOVhZSrg+UvVAshDSDtHyFCCBUl/Q3AAJv8iZ6ZjnZ74xzvwuzLXid9IIIPgTnY62SJjfuupMKZsZQRsCvxEgA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + chalk: 4.1.2 + graceful-fs: 4.2.11 + jest-haste-map: 29.7.0 + jest-pnp-resolver: 1.2.3(jest-resolve@29.7.0) + jest-util: 29.7.0 + jest-validate: 29.7.0 + resolve: 1.22.8 + resolve.exports: 2.0.2 + slash: 3.0.0 + dev: true + + /jest-runner@29.7.0: + resolution: {integrity: sha512-fsc4N6cPCAahybGBfTRcq5wFR6fpLznMg47sY5aDpsoejOcVYFb07AHuSnR0liMcPTgBsA3ZJL6kFOjPdoNipQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@jest/console': 29.7.0 + '@jest/environment': 29.7.0 + '@jest/test-result': 29.7.0 + '@jest/transform': 29.7.0 + '@jest/types': 29.6.3 + '@types/node': 20.12.12 + chalk: 4.1.2 + emittery: 0.13.1 + graceful-fs: 4.2.11 + jest-docblock: 29.7.0 + jest-environment-node: 29.7.0 + jest-haste-map: 29.7.0 + jest-leak-detector: 29.7.0 + jest-message-util: 29.7.0 + jest-resolve: 29.7.0 + jest-runtime: 29.7.0 + jest-util: 29.7.0 + jest-watcher: 29.7.0 + jest-worker: 29.7.0 + p-limit: 3.1.0 + source-map-support: 0.5.13 + transitivePeerDependencies: + - supports-color + dev: true + + /jest-runtime@29.7.0: + resolution: {integrity: sha512-gUnLjgwdGqW7B4LvOIkbKs9WGbn+QLqRQQ9juC6HndeDiezIwhDP+mhMwHWCEcfQ5RUXa6OPnFF8BJh5xegwwQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@jest/environment': 29.7.0 + '@jest/fake-timers': 29.7.0 + '@jest/globals': 29.7.0 + '@jest/source-map': 29.6.3 + '@jest/test-result': 29.7.0 + '@jest/transform': 29.7.0 + '@jest/types': 29.6.3 + '@types/node': 20.12.12 + chalk: 4.1.2 + cjs-module-lexer: 1.3.1 + collect-v8-coverage: 1.0.2 + glob: 7.2.3 + graceful-fs: 4.2.11 + jest-haste-map: 29.7.0 + jest-message-util: 29.7.0 + jest-mock: 29.7.0 + jest-regex-util: 29.6.3 + jest-resolve: 29.7.0 + jest-snapshot: 29.7.0 + jest-util: 29.7.0 + slash: 3.0.0 + strip-bom: 4.0.0 + transitivePeerDependencies: + - supports-color dev: true - /is-windows@1.0.2: - resolution: {integrity: sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==} - engines: {node: '>=0.10.0'} + /jest-snapshot@29.7.0: + resolution: {integrity: sha512-Rm0BMWtxBcioHr1/OX5YCP8Uov4riHvKPknOGs804Zg9JGZgmIBkbtlxJC/7Z4msKYVbIJtfU+tKb8xlYNfdkw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@babel/core': 7.24.0 + '@babel/generator': 7.23.6 + '@babel/plugin-syntax-jsx': 7.24.6(@babel/core@7.24.0) + '@babel/plugin-syntax-typescript': 7.24.6(@babel/core@7.24.0) + '@babel/types': 7.24.0 + '@jest/expect-utils': 29.7.0 + '@jest/transform': 29.7.0 + '@jest/types': 29.6.3 + babel-preset-current-node-syntax: 1.0.1(@babel/core@7.24.0) + chalk: 4.1.2 + expect: 29.7.0 + graceful-fs: 4.2.11 + jest-diff: 29.7.0 + jest-get-type: 29.6.3 + jest-matcher-utils: 29.7.0 + jest-message-util: 29.7.0 + jest-util: 29.7.0 + natural-compare: 1.4.0 + pretty-format: 29.7.0 + semver: 7.6.0 + transitivePeerDependencies: + - supports-color dev: true - /isarray@1.0.0: - resolution: {integrity: sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==} + /jest-util@29.7.0: + resolution: {integrity: sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@jest/types': 29.6.3 + '@types/node': 20.12.12 + chalk: 4.1.2 + ci-info: 3.9.0 + graceful-fs: 4.2.11 + picomatch: 2.3.1 dev: true - /isarray@2.0.5: - resolution: {integrity: sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==} + /jest-validate@29.7.0: + resolution: {integrity: sha512-ZB7wHqaRGVw/9hST/OuFUReG7M8vKeq0/J2egIGLdvjHCmYqGARhzXmtgi+gVeZ5uXFF219aOc3Ls2yLg27tkw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@jest/types': 29.6.3 + camelcase: 6.3.0 + chalk: 4.1.2 + jest-get-type: 29.6.3 + leven: 3.1.0 + pretty-format: 29.7.0 dev: true - /isexe@2.0.0: - resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} + /jest-watcher@29.7.0: + resolution: {integrity: sha512-49Fg7WXkU3Vl2h6LbLtMQ/HyB6rXSIX7SqvBLQmssRBGN9I0PNvPmAmCWSOY6SOvrjhI/F7/bGAv9RtnsPA03g==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@jest/test-result': 29.7.0 + '@jest/types': 29.6.3 + '@types/node': 20.12.12 + ansi-escapes: 4.3.2 + chalk: 4.1.2 + emittery: 0.13.1 + jest-util: 29.7.0 + string-length: 4.0.2 dev: true - /isobject@2.1.0: - resolution: {integrity: sha512-+OUdGJlgjOBZDfxnDjYYG6zp487z0JGNQq3cYQYg5f5hKR+syHMsaztzGeml/4kGG55CSpKSpWTY+jYGgsHLgA==} - engines: {node: '>=0.10.0'} + /jest-worker@27.5.1: + resolution: {integrity: sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==} + engines: {node: '>= 10.13.0'} dependencies: - isarray: 1.0.0 + '@types/node': 20.12.12 + merge-stream: 2.0.0 + supports-color: 8.1.1 dev: true - /isomorphic-timers-promises@1.0.1: - resolution: {integrity: sha512-u4sej9B1LPSxTGKB/HiuzvEQnXH0ECYkSVQU39koSwmFAxhlEAFl9RdTvLv4TOTQUgBS5O3O5fwUxk6byBZ+IQ==} - engines: {node: '>=10'} + /jest-worker@29.7.0: + resolution: {integrity: sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@types/node': 20.12.12 + jest-util: 29.7.0 + merge-stream: 2.0.0 + supports-color: 8.1.1 dev: true - /jackspeak@2.3.6: - resolution: {integrity: sha512-N3yCS/NegsOBokc8GAdM8UcmfsKiSS8cipheD/nivzr700H+nsMOxJjQnvwOcRYVuFkdH0wGUvW2WbXGmrZGbQ==} - engines: {node: '>=14'} + /jest@29.7.0(@types/node@20.12.12)(ts-node@10.9.2): + resolution: {integrity: sha512-NIy3oAFp9shda19hy4HK0HRTWKtPJmGdnvywu01nOqNC2vZg+Z+fvJDxpMQA88eb2I9EcafcdjYgsDthnYTvGw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + hasBin: true + peerDependencies: + node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 + peerDependenciesMeta: + node-notifier: + optional: true dependencies: - '@isaacs/cliui': 8.0.2 - optionalDependencies: - '@pkgjs/parseargs': 0.11.0 + '@jest/core': 29.7.0(ts-node@10.9.2) + '@jest/types': 29.6.3 + import-local: 3.1.0 + jest-cli: 29.7.0(@types/node@20.12.12)(ts-node@10.9.2) + transitivePeerDependencies: + - '@types/node' + - babel-plugin-macros + - supports-color + - ts-node dev: true /js-sha256@0.11.0: @@ -4146,10 +6311,18 @@ packages: resolution: {integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==} dev: true + /json-rpc-2.0@1.7.0: + resolution: {integrity: sha512-asnLgC1qD5ytP+fvBP8uL0rvj+l8P6iYICbzZ8dVxCpESffVjzA7KkYkbKCIbavs7cllwH1ZUaNtJwphdeRqpg==} + dev: false + /json-schema-traverse@0.4.1: resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} dev: true + /json-schema-traverse@1.0.0: + resolution: {integrity: sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==} + dev: true + /json-stable-stringify-without-jsonify@1.0.1: resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==} dev: true @@ -4160,6 +6333,10 @@ packages: hasBin: true dev: true + /jsonc-parser@3.2.0: + resolution: {integrity: sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w==} + dev: true + /jsonc-parser@3.2.1: resolution: {integrity: sha512-AilxAyFOAcK5wA1+LeaySVBrHsGQvUFCDWXKpZjzaL0PqW+xfBOttn8GNtWKFWqneyMZj41MWF9Kl6iPWLwgOA==} dev: true @@ -4170,6 +6347,14 @@ packages: graceful-fs: 4.2.11 dev: true + /jsonfile@6.1.0: + resolution: {integrity: sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==} + dependencies: + universalify: 2.0.1 + optionalDependencies: + graceful-fs: 4.2.11 + dev: true + /keyv@4.5.4: resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==} dependencies: @@ -4181,11 +6366,21 @@ packages: engines: {node: '>=0.10.0'} dev: true + /kleur@3.0.3: + resolution: {integrity: sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==} + engines: {node: '>=6'} + dev: true + /kleur@4.1.5: resolution: {integrity: sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==} engines: {node: '>=6'} dev: true + /leven@3.1.0: + resolution: {integrity: sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==} + engines: {node: '>=6'} + dev: true + /levn@0.4.1: resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} engines: {node: '>= 0.8.0'} @@ -4244,6 +6439,11 @@ packages: strip-bom: 3.0.0 dev: true + /loader-runner@4.3.0: + resolution: {integrity: sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==} + engines: {node: '>=6.11.5'} + dev: true + /local-pkg@0.5.0: resolution: {integrity: sha512-ok6z3qlYyCDS4ZEU27HaU6x/xZa9Whf8jD4ptH5UZTQYZVYeb9bnZ3ojVhiJNLiXK1Hfc0GNbLXcmZ5plLDDBg==} engines: {node: '>=14'} @@ -4270,6 +6470,10 @@ packages: resolution: {integrity: sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ==} dev: false + /lodash.memoize@4.1.2: + resolution: {integrity: sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==} + dev: true + /lodash.merge@4.6.2: resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} dev: true @@ -4280,7 +6484,14 @@ packages: /lodash@4.17.21: resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} - dev: false + + /log-symbols@4.1.0: + resolution: {integrity: sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==} + engines: {node: '>=10'} + dependencies: + chalk: 4.1.2 + is-unicode-supported: 0.1.0 + dev: true /log-update@6.0.0: resolution: {integrity: sha512-niTvB4gqvtof056rRIrTZvjNYE4rCUzO6X/X+kYjd7WFxXeJ0NwEFnRxX6ehkvv3jTwrXnNdtAak5XYZuIyPFw==} @@ -4331,6 +6542,13 @@ packages: yallist: 4.0.0 dev: true + /magic-string@0.30.5: + resolution: {integrity: sha512-7xlpfBaQaP/T6Vh8MO/EqXSW5En6INHEvEXQiuff7Gku0PWjU3uf6w/j9o7O+SpB5fOAkrI5HeoNgwjEO0pFsA==} + engines: {node: '>=12'} + dependencies: + '@jridgewell/sourcemap-codec': 1.4.15 + dev: true + /magic-string@0.30.8: resolution: {integrity: sha512-ISQTe55T2ao7XtlAStud6qwYPZjE4GK1S/BeVPus4jrq6JuOnQ00YKQC581RWhR122W7msZV263KzVeLoqidyQ==} engines: {node: '>=12'} @@ -4338,10 +6556,23 @@ packages: '@jridgewell/sourcemap-codec': 1.4.15 dev: true + /make-dir@4.0.0: + resolution: {integrity: sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==} + engines: {node: '>=10'} + dependencies: + semver: 7.6.0 + dev: true + /make-error@1.3.6: resolution: {integrity: sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==} dev: true + /makeerror@1.0.12: + resolution: {integrity: sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==} + dependencies: + tmpl: 1.0.5 + dev: true + /map-obj@1.0.1: resolution: {integrity: sha512-7N/q3lyZ+LVCp7PzuxrJr4KMbBE2hW7BT7YNia330OFxIf4d3r5zVpicP2650l7CPN6RM9zOJRl3NGpqSiw3Eg==} engines: {node: '>=0.10.0'} @@ -4358,6 +6589,17 @@ packages: inherits: 2.0.4 safe-buffer: 5.2.1 + /media-typer@0.3.0: + resolution: {integrity: sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==} + engines: {node: '>= 0.6'} + + /memfs@3.5.3: + resolution: {integrity: sha512-UERzLsxzllchadvbPs5aolHh65ISpKpM+ccLbOJ8/vvpBKmAWf+la7dXFy7Mr0ySHbdHrFv5kGFCUHHe6GFEmw==} + engines: {node: '>= 4.0.0'} + dependencies: + fs-monkey: 1.0.6 + dev: true + /meow@6.1.1: resolution: {integrity: sha512-3YffViIt2QWgTy6Pale5QpopX/IvU3LPL03jOTqp6pGj3VjesdO/U8CuHMKpnQr4shCNCM5fd5XFFvIIl6JBHg==} engines: {node: '>=8'} @@ -4375,6 +6617,9 @@ packages: yargs-parser: 18.1.3 dev: true + /merge-descriptors@1.0.1: + resolution: {integrity: sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==} + /merge-stream@2.0.0: resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==} dev: true @@ -4384,6 +6629,10 @@ packages: engines: {node: '>= 8'} dev: true + /methods@1.1.2: + resolution: {integrity: sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==} + engines: {node: '>= 0.6'} + /micromatch@4.0.5: resolution: {integrity: sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==} engines: {node: '>=8.6'} @@ -4403,14 +6652,23 @@ packages: /mime-db@1.52.0: resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} engines: {node: '>= 0.6'} - dev: false /mime-types@2.1.35: resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} engines: {node: '>= 0.6'} dependencies: mime-db: 1.52.0 - dev: false + + /mime@1.6.0: + resolution: {integrity: sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==} + engines: {node: '>=4'} + hasBin: true + + /mime@2.6.0: + resolution: {integrity: sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==} + engines: {node: '>=4.0.0'} + hasBin: true + dev: true /mimic-fn@2.1.0: resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==} @@ -4439,6 +6697,13 @@ packages: brace-expansion: 1.1.11 dev: true + /minimatch@8.0.4: + resolution: {integrity: sha512-W0Wvr9HyFXZRGIDgCicunpQ299OKXs9RgZfaukz4qAW/pJhcpUfupc9c+OObPOFueNy8VSrZgEmDtk6Kh4WzDA==} + engines: {node: '>=16 || 14 >=14.17'} + dependencies: + brace-expansion: 2.0.1 + dev: true + /minimatch@9.0.3: resolution: {integrity: sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==} engines: {node: '>=16 || 14 >=14.17'} @@ -4464,6 +6729,10 @@ packages: /minimist@1.2.8: resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} + + /minipass@4.2.8: + resolution: {integrity: sha512-fNzuVyifolSLFL4NzpF+wEF4qrgqaaKX0haXPQEdQ7NKAN+WecoKMHV09YcuL/DHxrUsYQOK3MiuDf7Ip2OXfQ==} + engines: {node: '>=8'} dev: true /minipass@7.0.4: @@ -4476,6 +6745,12 @@ packages: engines: {node: '>= 8.0.0'} dev: true + /mkdirp@0.5.6: + resolution: {integrity: sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==} + hasBin: true + dependencies: + minimist: 1.2.8 + /mlly@1.6.1: resolution: {integrity: sha512-vLgaHvaeunuOXHSmEbZ9izxPx3USsk8KCQ8iC+aTlp5sKRSoZvwhHh5L9VbKSaVC6sJDqbyohIS76E2VmHIPAA==} dependencies: @@ -4489,10 +6764,37 @@ packages: resolution: {integrity: sha512-iSAJLHYKnX41mKcJKjqvnAN9sf0LMDTXDEvFv+ffuRR9a1MIuXLjMNL6EsnDHSkKLTWNqQQ5uo61P4EbU4NU+Q==} dev: true + /ms@2.0.0: + resolution: {integrity: sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==} + /ms@2.1.2: resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==} dev: true + /ms@2.1.3: + resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + + /multer@1.4.4-lts.1: + resolution: {integrity: sha512-WeSGziVj6+Z2/MwQo3GvqzgR+9Uc+qt8SwHKh3gvNPiISKfsMfG4SvCOFYlxxgkXt7yIV2i1yczehm0EOKIxIg==} + engines: {node: '>= 6.0.0'} + dependencies: + append-field: 1.0.0 + busboy: 1.6.0 + concat-stream: 1.6.2 + mkdirp: 0.5.6 + object-assign: 4.1.1 + type-is: 1.6.18 + xtend: 4.0.2 + + /mute-stream@0.0.8: + resolution: {integrity: sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==} + dev: true + + /mute-stream@1.0.0: + resolution: {integrity: sha512-avsJQhyd+680gKXyG/sQc0nXaC6rBkPOfyHYcFb9+hdkqQkR9bdnkJ0AMZhke0oesPqIO+mFFJ+IdBc7mst4IA==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + dev: true + /nanoassert@2.0.0: resolution: {integrity: sha512-7vO7n28+aYO4J+8w96AzhmU8G+Y/xpPDJz/se19ICsqj/momRbb9mh9ZUtkoJ5X3nTnPdhEJyc0qnM6yAsHBaA==} dev: false @@ -4516,6 +6818,14 @@ packages: randexp: 0.4.6 dev: true + /negotiator@0.6.3: + resolution: {integrity: sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==} + engines: {node: '>= 0.6'} + + /neo-async@2.6.2: + resolution: {integrity: sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==} + dev: true + /next@14.1.2(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-p4RfNmopqkzRP1uUyBJnHii+qMg71f2udWhTTZopBB8b3T5QXNzn7yO+LCYHPWZG2kAvEn4l4neyJHqkXvo2wg==} engines: {node: '>=18.17.0'} @@ -4555,6 +6865,16 @@ packages: - babel-plugin-macros dev: false + /node-abort-controller@3.1.1: + resolution: {integrity: sha512-AGK2yQKIjRuqnc6VkX2Xj5d+QW8xZ87pa1UK6yA6ouUyuxfHuMP6umE5QK7UmTeOAymo+Zx1Fxiuw9rVx8taHQ==} + dev: true + + /node-emoji@1.11.0: + resolution: {integrity: sha512-wo2DpQkQp7Sjm2A0cq+sN7EHKO6Sl0ctXeBdFZrL9T9+UywORbufTcTZxom8YqpLQt/FqNMUkOpkZrJVYSKD3A==} + dependencies: + lodash: 4.17.21 + dev: true + /node-fetch@2.7.0: resolution: {integrity: sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==} engines: {node: 4.x || >=6.0.0} @@ -4566,6 +6886,10 @@ packages: dependencies: whatwg-url: 5.0.0 + /node-int64@0.4.0: + resolution: {integrity: sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==} + dev: true + /node-releases@2.0.14: resolution: {integrity: sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==} dev: true @@ -4612,6 +6936,18 @@ packages: validate-npm-package-license: 3.0.4 dev: true + /normalize-path@3.0.0: + resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} + engines: {node: '>=0.10.0'} + dev: true + + /npm-run-path@4.0.1: + resolution: {integrity: sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==} + engines: {node: '>=8'} + dependencies: + path-key: 3.1.1 + dev: true + /npm-run-path@5.3.0: resolution: {integrity: sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} @@ -4619,9 +6955,12 @@ packages: path-key: 4.0.0 dev: true + /object-assign@4.1.1: + resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} + engines: {node: '>=0.10.0'} + /object-inspect@1.13.1: resolution: {integrity: sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==} - dev: true /object-is@1.1.6: resolution: {integrity: sha512-F8cZ+KfGlSGi09lJT7/Nd6KJZ9ygtvYC0/UYYLI9nmQKLMnydpB9yvbv9K1uSkEu7FU9vYPmVwLg328tX+ot3Q==} @@ -4646,6 +6985,12 @@ packages: object-keys: 1.1.1 dev: true + /on-finished@2.4.1: + resolution: {integrity: sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==} + engines: {node: '>= 0.8'} + dependencies: + ee-first: 1.1.1 + /once@1.4.0: resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} dependencies: @@ -4678,6 +7023,21 @@ packages: type-check: 0.4.0 dev: true + /ora@5.4.1: + resolution: {integrity: sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ==} + engines: {node: '>=10'} + dependencies: + bl: 4.1.0 + chalk: 4.1.2 + cli-cursor: 3.1.0 + cli-spinners: 2.9.2 + is-interactive: 1.0.0 + is-unicode-supported: 0.1.0 + log-symbols: 4.1.0 + strip-ansi: 6.0.1 + wcwidth: 1.0.1 + dev: true + /os-browserify@0.3.0: resolution: {integrity: sha512-gjcpUc3clBf9+210TRaDWbf+rZZZEshZ+DlXMRCeAjp0xhTrnQsKHypIy1J3d5hKdUzj69t708EHtU8P6bUn0A==} dev: true @@ -4775,6 +7135,10 @@ packages: lines-and-columns: 1.2.4 dev: true + /parseurl@1.3.3: + resolution: {integrity: sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==} + engines: {node: '>= 0.8'} + /path-browserify@1.0.1: resolution: {integrity: sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==} dev: true @@ -4811,6 +7175,12 @@ packages: minipass: 7.0.4 dev: true + /path-to-regexp@0.1.7: + resolution: {integrity: sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==} + + /path-to-regexp@3.2.0: + resolution: {integrity: sha512-jczvQbCUS7XmS7o+y1aEO9OBVFeZBQ1MDSEqmO7xSoPgOPoowY/SxLpZ6Vh97/8qHZOteiCKb7gkG9gA2ZUxJA==} + /path-type@4.0.0: resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} engines: {node: '>=8'} @@ -4843,6 +7213,11 @@ packages: engines: {node: '>=8.6'} dev: true + /picomatch@3.0.1: + resolution: {integrity: sha512-I3EurrIQMlRc9IaAZnqRR044Phh2DXY+55o7uJ0V+hYZAcQYSuFWsc9q5PvyDHUSCe1Qxn/iBz+78s86zWnGag==} + engines: {node: '>=10'} + dev: true + /pidtree@0.6.0: resolution: {integrity: sha512-eG2dWTVw5bzqGRztnHExczNxt5VGsE6OwTeCG3fdUf9KBsZzO3R5OIIIzWR+iZA0NtZ+RDVdaoE2dK1cn6jH4g==} engines: {node: '>=0.10'} @@ -4854,6 +7229,11 @@ packages: engines: {node: '>=6'} dev: true + /pirates@4.0.6: + resolution: {integrity: sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==} + engines: {node: '>= 6'} + dev: true + /pkg-dir@4.2.0: resolution: {integrity: sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==} engines: {node: '>=8'} @@ -4876,6 +7256,11 @@ packages: pathe: 1.1.2 dev: true + /pluralize@8.0.0: + resolution: {integrity: sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==} + engines: {node: '>=4'} + dev: true + /possible-typed-array-names@1.0.0: resolution: {integrity: sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==} engines: {node: '>= 0.4'} @@ -4937,13 +7322,27 @@ packages: /process-nextick-args@2.0.1: resolution: {integrity: sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==} - dev: true /process@0.11.10: resolution: {integrity: sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==} engines: {node: '>= 0.6.0'} dev: true + /prompts@2.4.2: + resolution: {integrity: sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==} + engines: {node: '>= 6'} + dependencies: + kleur: 3.0.3 + sisteransi: 1.0.5 + dev: true + + /proxy-addr@2.0.7: + resolution: {integrity: sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==} + engines: {node: '>= 0.10'} + dependencies: + forwarded: 0.2.0 + ipaddr.js: 1.9.1 + /proxy-from-env@1.1.0: resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==} dev: false @@ -4972,6 +7371,16 @@ packages: engines: {node: '>=6'} dev: true + /pure-rand@6.1.0: + resolution: {integrity: sha512-bVWawvoZoBYpp6yIoQtQXHZjmz35RSVHnUOTefl8Vcjr8snTPY1wnpSPMWekcFwbxI6gtmT7rSYPFvz71ldiOA==} + dev: true + + /qs@6.11.0: + resolution: {integrity: sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==} + engines: {node: '>=0.6'} + dependencies: + side-channel: 1.0.6 + /qs@6.12.0: resolution: {integrity: sha512-trVZiI6RMOkO476zLGaBIzszOdFPnCCXHPG9kn0yuS1uz6xdVxPfZdB3vUig9pxPFDM9BRAgz/YUIVQ1/vuiUg==} engines: {node: '>=0.6'} @@ -5022,6 +7431,19 @@ packages: safe-buffer: 5.2.1 dev: true + /range-parser@1.2.1: + resolution: {integrity: sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==} + engines: {node: '>= 0.6'} + + /raw-body@2.5.2: + resolution: {integrity: sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==} + engines: {node: '>= 0.8'} + dependencies: + bytes: 3.1.2 + http-errors: 2.0.0 + iconv-lite: 0.4.24 + unpipe: 1.0.0 + /react-dom@18.2.0(react@18.2.0): resolution: {integrity: sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g==} peerDependencies: @@ -5087,7 +7509,6 @@ packages: safe-buffer: 5.1.2 string_decoder: 1.1.1 util-deprecate: 1.0.2 - dev: true /readable-stream@3.6.2: resolution: {integrity: sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==} @@ -5097,6 +7518,20 @@ packages: string_decoder: 1.3.0 util-deprecate: 1.0.2 + /readdirp@3.6.0: + resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==} + engines: {node: '>=8.10.0'} + dependencies: + picomatch: 2.3.1 + dev: true + + /rechoir@0.6.2: + resolution: {integrity: sha512-HFM8rkZ+i3zrV+4LQjwQ0W+ez98pApMGM3HUrN04j3CqzPOzl9nmP15Y8YXNm8QHGv/eacOVEjqhmWpkRV0NAw==} + engines: {node: '>= 0.10'} + dependencies: + resolve: 1.22.8 + dev: true + /redent@3.0.0: resolution: {integrity: sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==} engines: {node: '>=8'} @@ -5105,6 +7540,9 @@ packages: strip-indent: 3.0.0 dev: true + /reflect-metadata@0.2.2: + resolution: {integrity: sha512-urBwgfrvVP/eAyXx4hluJivBKzuEbSQs9rKWCrCkbSxNv8mxPcUZKeuoF3Uy4mJl3Lwprp6yy5/39VWigZ4K6Q==} + /regenerator-runtime@0.14.1: resolution: {integrity: sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==} dev: true @@ -5126,15 +7564,32 @@ packages: isobject: 2.1.0 dev: true + /repeat-string@1.6.1: + resolution: {integrity: sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w==} + engines: {node: '>=0.10'} + dev: true + /require-directory@2.1.1: resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} engines: {node: '>=0.10.0'} dev: true + /require-from-string@2.0.2: + resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==} + engines: {node: '>=0.10.0'} + dev: true + /require-main-filename@2.0.0: resolution: {integrity: sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==} dev: true + /resolve-cwd@3.0.0: + resolution: {integrity: sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==} + engines: {node: '>=8'} + dependencies: + resolve-from: 5.0.0 + dev: true + /resolve-from@4.0.0: resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} engines: {node: '>=4'} @@ -5145,6 +7600,11 @@ packages: engines: {node: '>=8'} dev: true + /resolve.exports@2.0.2: + resolution: {integrity: sha512-X2UW6Nw3n/aMgDVy+0rSqgHlv39WZAlZrXCdnbyEiKm17DSqHX4MmQMaST3FbeWR5FTuRcUwYAziZajji0Y7mg==} + engines: {node: '>=10'} + dev: true + /resolve@1.22.8: resolution: {integrity: sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==} hasBin: true @@ -5154,6 +7614,14 @@ packages: supports-preserve-symlinks-flag: 1.0.0 dev: true + /restore-cursor@3.1.0: + resolution: {integrity: sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==} + engines: {node: '>=8'} + dependencies: + onetime: 5.1.2 + signal-exit: 3.0.7 + dev: true + /restore-cursor@4.0.0: resolution: {integrity: sha512-I9fPXU9geO9bHOt9pHHOhOkYerIMsmVaWB0rA2AI9ERh/+x/i7MV5HKBNrg+ljO5eoPVgCcnFuRjJ9uH6I/3eg==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} @@ -5178,11 +7646,20 @@ packages: /rimraf@3.0.2: resolution: {integrity: sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==} + deprecated: Rimraf versions prior to v4 are no longer supported hasBin: true dependencies: glob: 7.2.3 dev: true + /rimraf@4.4.1: + resolution: {integrity: sha512-Gk8NlF062+T9CqNGn6h4tls3k6T1+/nXdOcSZVikNVtlRdYpA7wRJJMoXmuvOnLW844rPjdQ7JgXCYM6PPC/og==} + engines: {node: '>=14'} + hasBin: true + dependencies: + glob: 9.3.5 + dev: true + /rimraf@5.0.5: resolution: {integrity: sha512-CqDakW+hMe/Bz202FPEymy68P+G50RfMQK+Qo5YUqc9SPipvbGjCGKd0RSKEelbsfQuw3g5NZDSrlZZAJurH1A==} engines: {node: '>=14'} @@ -5222,12 +7699,27 @@ packages: fsevents: 2.3.3 dev: true + /run-async@2.4.1: + resolution: {integrity: sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==} + engines: {node: '>=0.12.0'} + dev: true + + /run-async@3.0.0: + resolution: {integrity: sha512-540WwVDOMxA6dN6We19EcT9sc3hkXPw5mzRNGM3FkdN/vtE9NFvj5lFAPNwUDmJjXidm3v7TC1cTE7t17Ulm1Q==} + engines: {node: '>=0.12.0'} + dev: true + /run-parallel@1.2.0: resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} dependencies: queue-microtask: 1.2.3 dev: true + /rxjs@7.8.1: + resolution: {integrity: sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==} + dependencies: + tslib: 2.6.2 + /safe-array-concat@1.1.2: resolution: {integrity: sha512-vj6RsCsWBCf19jIeHEfkRMw8DPiBb+DMXklQ/1SGDHOMlHdPUkZXFQ2YdplS23zESTijAcurb1aSgJA3AgMu1Q==} engines: {node: '>=0.4'} @@ -5240,7 +7732,6 @@ packages: /safe-buffer@5.1.2: resolution: {integrity: sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==} - dev: true /safe-buffer@5.2.1: resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} @@ -5256,7 +7747,6 @@ packages: /safer-buffer@2.1.2: resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} - dev: true /scheduler@0.23.0: resolution: {integrity: sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw==} @@ -5264,6 +7754,15 @@ packages: loose-envify: 1.4.0 dev: false + /schema-utils@3.3.0: + resolution: {integrity: sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==} + engines: {node: '>= 10.13.0'} + dependencies: + '@types/json-schema': 7.0.15 + ajv: 6.12.6 + ajv-keywords: 3.5.2(ajv@6.12.6) + dev: true + /scrypt-js@3.0.1: resolution: {integrity: sha512-cdwTTnqPu0Hyvf5in5asVdZocVDTNRmR7XEcJuIzMjJeSHybHl7vpB66AzwTaIg6CLSbtjcxc8fqcySfnTkccA==} dev: false @@ -5286,6 +7785,43 @@ packages: lru-cache: 6.0.0 dev: true + /send@0.18.0: + resolution: {integrity: sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==} + engines: {node: '>= 0.8.0'} + dependencies: + debug: 2.6.9 + depd: 2.0.0 + destroy: 1.2.0 + encodeurl: 1.0.2 + escape-html: 1.0.3 + etag: 1.8.1 + fresh: 0.5.2 + http-errors: 2.0.0 + mime: 1.6.0 + ms: 2.1.3 + on-finished: 2.4.1 + range-parser: 1.2.1 + statuses: 2.0.1 + transitivePeerDependencies: + - supports-color + + /serialize-javascript@6.0.2: + resolution: {integrity: sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==} + dependencies: + randombytes: 2.1.0 + dev: true + + /serve-static@1.15.0: + resolution: {integrity: sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==} + engines: {node: '>= 0.8.0'} + dependencies: + encodeurl: 1.0.2 + escape-html: 1.0.3 + parseurl: 1.3.3 + send: 0.18.0 + transitivePeerDependencies: + - supports-color + /set-blocking@2.0.0: resolution: {integrity: sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==} dev: true @@ -5300,7 +7836,6 @@ packages: get-intrinsic: 1.2.4 gopd: 1.0.1 has-property-descriptors: 1.0.2 - dev: true /set-function-name@2.0.2: resolution: {integrity: sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==} @@ -5316,6 +7851,9 @@ packages: resolution: {integrity: sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==} dev: true + /setprototypeof@1.2.0: + resolution: {integrity: sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==} + /sha.js@2.4.11: resolution: {integrity: sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==} hasBin: true @@ -5353,6 +7891,16 @@ packages: engines: {node: '>=8'} dev: true + /shelljs@0.8.5: + resolution: {integrity: sha512-TiwcRcrkhHvbrZbnRcFYMLl30Dfov3HKqzp5tO5b4pt6G/SezKcYhmDg15zXVBswHmctSAQKznqNW2LO5tTDow==} + engines: {node: '>=4'} + hasBin: true + dependencies: + glob: 7.2.3 + interpret: 1.4.0 + rechoir: 0.6.2 + dev: true + /side-channel@1.0.6: resolution: {integrity: sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==} engines: {node: '>= 0.4'} @@ -5361,7 +7909,6 @@ packages: es-errors: 1.3.0 get-intrinsic: 1.2.4 object-inspect: 1.13.1 - dev: true /siginfo@2.0.0: resolution: {integrity: sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==} @@ -5376,6 +7923,10 @@ packages: engines: {node: '>=14'} dev: true + /sisteransi@1.0.5: + resolution: {integrity: sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==} + dev: true + /slash@3.0.0: resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==} engines: {node: '>=8'} @@ -5420,6 +7971,30 @@ packages: engines: {node: '>=0.10.0'} dev: true + /source-map-support@0.5.13: + resolution: {integrity: sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==} + dependencies: + buffer-from: 1.1.2 + source-map: 0.6.1 + dev: true + + /source-map-support@0.5.21: + resolution: {integrity: sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==} + dependencies: + buffer-from: 1.1.2 + source-map: 0.6.1 + dev: true + + /source-map@0.6.1: + resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} + engines: {node: '>=0.10.0'} + dev: true + + /source-map@0.7.4: + resolution: {integrity: sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==} + engines: {node: '>= 8'} + dev: true + /spawndamnit@2.0.0: resolution: {integrity: sha512-j4JKEcncSjFlqIwU5L/rp2N5SIPsdxaRsIv678+TZxZ0SRDJTm8JrxJMjE/XuiEZNEir3S8l0Fa3Ke339WI4qA==} dependencies: @@ -5453,10 +8028,21 @@ packages: resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==} dev: true + /stack-utils@2.0.6: + resolution: {integrity: sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==} + engines: {node: '>=10'} + dependencies: + escape-string-regexp: 2.0.0 + dev: true + /stackback@0.0.2: resolution: {integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==} dev: true + /statuses@2.0.1: + resolution: {integrity: sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==} + engines: {node: '>= 0.8'} + /std-env@3.7.0: resolution: {integrity: sha512-JPbdCEQLj1w5GilpiHAx3qJvFndqybBysA3qUOnznweH4QbNYUsW/ea8QzSrnh0vNsezMMw5bcVool8lM0gwzg==} dev: true @@ -5486,13 +8072,20 @@ packages: /streamsearch@1.1.0: resolution: {integrity: sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==} engines: {node: '>=10.0.0'} - dev: false /string-argv@0.3.2: resolution: {integrity: sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q==} engines: {node: '>=0.6.19'} dev: true + /string-length@4.0.2: + resolution: {integrity: sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==} + engines: {node: '>=10'} + dependencies: + char-regex: 1.0.2 + strip-ansi: 6.0.1 + dev: true + /string-width@4.2.3: resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} engines: {node: '>=8'} @@ -5551,7 +8144,6 @@ packages: resolution: {integrity: sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==} dependencies: safe-buffer: 5.1.2 - dev: true /string_decoder@1.3.0: resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==} @@ -5577,6 +8169,16 @@ packages: engines: {node: '>=4'} dev: true + /strip-bom@4.0.0: + resolution: {integrity: sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==} + engines: {node: '>=8'} + dev: true + + /strip-final-newline@2.0.0: + resolution: {integrity: sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==} + engines: {node: '>=6'} + dev: true + /strip-final-newline@3.0.0: resolution: {integrity: sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==} engines: {node: '>=12'} @@ -5617,6 +8219,35 @@ packages: react: 18.2.0 dev: false + /superagent@8.1.2: + resolution: {integrity: sha512-6WTxW1EB6yCxV5VFOIPQruWGHqc3yI7hEmZK6h+pyk69Lk/Ut7rLUY6W/ONF2MjBuGjvmMiIpsrVJ2vjrHlslA==} + engines: {node: '>=6.4.0 <13 || >=14'} + deprecated: Please upgrade to v9.0.0+ as we have fixed a public vulnerability with formidable dependency. Note that v9.0.0+ requires Node.js v14.18.0+. See https://github.com/ladjs/superagent/pull/1800 for insight. This project is supported and maintained by the team at Forward Email @ https://forwardemail.net + dependencies: + component-emitter: 1.3.1 + cookiejar: 2.1.4 + debug: 4.3.4 + fast-safe-stringify: 2.1.1 + form-data: 4.0.0 + formidable: 2.1.2 + methods: 1.1.2 + mime: 2.6.0 + qs: 6.12.0 + semver: 7.6.0 + transitivePeerDependencies: + - supports-color + dev: true + + /supertest@6.3.4: + resolution: {integrity: sha512-erY3HFDG0dPnhw4U+udPfrzXa4xhSG+n4rxfRuZWCUvjFWwKl+OxWf/7zk50s84/fAAs7vf5QAb9uRa0cCykxw==} + engines: {node: '>=6.4.0'} + dependencies: + methods: 1.1.2 + superagent: 8.1.2 + transitivePeerDependencies: + - supports-color + dev: true + /supports-color@5.5.0: resolution: {integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==} engines: {node: '>=4'} @@ -5629,6 +8260,12 @@ packages: engines: {node: '>=8'} dependencies: has-flag: 4.0.0 + + /supports-color@8.1.1: + resolution: {integrity: sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==} + engines: {node: '>=10'} + dependencies: + has-flag: 4.0.0 dev: true /supports-preserve-symlinks-flag@1.0.0: @@ -5636,15 +8273,97 @@ packages: engines: {node: '>= 0.4'} dev: true + /symbol-observable@4.0.0: + resolution: {integrity: sha512-b19dMThMV4HVFynSAM1++gBHAbk2Tc/osgLIBZMKsyqh34jb2e8Os7T6ZW/Bt3pJFdBTd2JwAnAAEQV7rSNvcQ==} + engines: {node: '>=0.10'} + dev: true + + /tapable@2.2.1: + resolution: {integrity: sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==} + engines: {node: '>=6'} + dev: true + /term-size@2.2.1: resolution: {integrity: sha512-wK0Ri4fOGjv/XPy8SBHZChl8CM7uMc5VML7SqiQ0zG7+J5Vr+RMQDoHa2CNT6KHUnTGIXH34UDMkPzAUyapBZg==} engines: {node: '>=8'} dev: true + /terser-webpack-plugin@5.3.10(webpack@5.90.1): + resolution: {integrity: sha512-BKFPWlPDndPs+NGGCr1U59t0XScL5317Y0UReNrHaw9/FwhPENlq6bfgs+4yPfyP51vqC1bQ4rp1EfXW5ZSH9w==} + engines: {node: '>= 10.13.0'} + peerDependencies: + '@swc/core': '*' + esbuild: '*' + uglify-js: '*' + webpack: ^5.1.0 + peerDependenciesMeta: + '@swc/core': + optional: true + esbuild: + optional: true + uglify-js: + optional: true + dependencies: + '@jridgewell/trace-mapping': 0.3.25 + jest-worker: 27.5.1 + schema-utils: 3.3.0 + serialize-javascript: 6.0.2 + terser: 5.31.0 + webpack: 5.90.1 + dev: true + + /terser-webpack-plugin@5.3.10(webpack@5.91.0): + resolution: {integrity: sha512-BKFPWlPDndPs+NGGCr1U59t0XScL5317Y0UReNrHaw9/FwhPENlq6bfgs+4yPfyP51vqC1bQ4rp1EfXW5ZSH9w==} + engines: {node: '>= 10.13.0'} + peerDependencies: + '@swc/core': '*' + esbuild: '*' + uglify-js: '*' + webpack: ^5.1.0 + peerDependenciesMeta: + '@swc/core': + optional: true + esbuild: + optional: true + uglify-js: + optional: true + dependencies: + '@jridgewell/trace-mapping': 0.3.25 + jest-worker: 27.5.1 + schema-utils: 3.3.0 + serialize-javascript: 6.0.2 + terser: 5.31.0 + webpack: 5.91.0 + dev: true + + /terser@5.31.0: + resolution: {integrity: sha512-Q1JFAoUKE5IMfI4Z/lkE/E6+SwgzO+x4tq4v1AyBLRj8VSYvRO6A/rQrPg1yud4g0En9EKI1TvFRF2tQFcoUkg==} + engines: {node: '>=10'} + hasBin: true + dependencies: + '@jridgewell/source-map': 0.3.6 + acorn: 8.11.3 + commander: 2.20.3 + source-map-support: 0.5.21 + dev: true + + /test-exclude@6.0.0: + resolution: {integrity: sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==} + engines: {node: '>=8'} + dependencies: + '@istanbuljs/schema': 0.1.3 + glob: 7.2.3 + minimatch: 3.1.2 + dev: true + /text-table@0.2.0: resolution: {integrity: sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==} dev: true + /through@2.3.8: + resolution: {integrity: sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==} + dev: true + /timers-browserify@2.0.12: resolution: {integrity: sha512-9phl76Cqm6FhSX9Xe1ZUAMLtm1BLkKj2Qd5ApyWkXzsMRaA7dgr81kf4wJmQf/hAvg8EEyJxDo3du/0KlhPiKQ==} engines: {node: '>=0.6.0'} @@ -5673,6 +8392,10 @@ packages: os-tmpdir: 1.0.2 dev: true + /tmpl@1.0.5: + resolution: {integrity: sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==} + dev: true + /to-fast-properties@2.0.0: resolution: {integrity: sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==} engines: {node: '>=4'} @@ -5685,9 +8408,18 @@ packages: is-number: 7.0.0 dev: true + /toidentifier@1.0.1: + resolution: {integrity: sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==} + engines: {node: '>=0.6'} + /tr46@0.0.3: resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==} + /tree-kill@1.2.2: + resolution: {integrity: sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==} + hasBin: true + dev: true + /trim-newlines@3.0.1: resolution: {integrity: sha512-c1PTsA3tYrIsLGkJkzHF+w9F2EyxfXGo4UyJc4pFL++FMjnq0HJS69T3M7d//gKrFKwy429bouPescbjecU+Zw==} engines: {node: '>=8'} @@ -5711,6 +8443,59 @@ packages: typescript: 5.4.3 dev: true + /ts-jest@29.1.4(@babel/core@7.24.0)(jest@29.7.0)(typescript@5.4.3): + resolution: {integrity: sha512-YiHwDhSvCiItoAgsKtoLFCuakDzDsJ1DLDnSouTaTmdOcOwIkSzbLXduaQ6M5DRVhuZC/NYaaZ/mtHbWMv/S6Q==} + engines: {node: ^14.15.0 || ^16.10.0 || ^18.0.0 || >=20.0.0} + hasBin: true + peerDependencies: + '@babel/core': '>=7.0.0-beta.0 <8' + '@jest/transform': ^29.0.0 + '@jest/types': ^29.0.0 + babel-jest: ^29.0.0 + esbuild: '*' + jest: ^29.0.0 + typescript: '>=4.3 <6' + peerDependenciesMeta: + '@babel/core': + optional: true + '@jest/transform': + optional: true + '@jest/types': + optional: true + babel-jest: + optional: true + esbuild: + optional: true + dependencies: + '@babel/core': 7.24.0 + bs-logger: 0.2.6 + fast-json-stable-stringify: 2.1.0 + jest: 29.7.0(@types/node@20.12.12)(ts-node@10.9.2) + jest-util: 29.7.0 + json5: 2.2.3 + lodash.memoize: 4.1.2 + make-error: 1.3.6 + semver: 7.6.0 + typescript: 5.4.3 + yargs-parser: 21.1.1 + dev: true + + /ts-loader@9.5.1(typescript@5.4.3)(webpack@5.91.0): + resolution: {integrity: sha512-rNH3sK9kGZcH9dYzC7CewQm4NtxJTjSEVRJ2DyBZR7f8/wcta+iV44UPCXc5+nzDzivKtlzV6c9P4e+oFhDLYg==} + engines: {node: '>=12.0.0'} + peerDependencies: + typescript: '*' + webpack: ^5.0.0 + dependencies: + chalk: 4.1.2 + enhanced-resolve: 5.16.1 + micromatch: 4.0.5 + semver: 7.6.0 + source-map: 0.7.4 + typescript: 5.4.3 + webpack: 5.91.0 + dev: true + /ts-node@10.9.2(@types/node@20.12.12)(typescript@5.4.3): resolution: {integrity: sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==} hasBin: true @@ -5742,13 +8527,30 @@ packages: yn: 3.1.1 dev: true + /tsconfig-paths-webpack-plugin@4.1.0: + resolution: {integrity: sha512-xWFISjviPydmtmgeUAuXp4N1fky+VCtfhOkDUFIv5ea7p4wuTomI4QTrXvFBX2S4jZsmyTSrStQl+E+4w+RzxA==} + engines: {node: '>=10.13.0'} + dependencies: + chalk: 4.1.2 + enhanced-resolve: 5.16.1 + tsconfig-paths: 4.2.0 + dev: true + + /tsconfig-paths@4.2.0: + resolution: {integrity: sha512-NoZ4roiN7LnbKn9QqE1amc9DJfzvZXxF4xDavcOWt1BPkdx+m+0gJuPM+S0vCe7zTJMYUP0R8pO2XMr+Y8oLIg==} + engines: {node: '>=6'} + dependencies: + json5: 2.2.3 + minimist: 1.2.8 + strip-bom: 3.0.0 + dev: true + /tslib@2.3.1: resolution: {integrity: sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==} dev: false /tslib@2.6.2: resolution: {integrity: sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==} - dev: false /tty-browserify@0.0.1: resolution: {integrity: sha512-C3TaO7K81YvjCgQH9Q1S3R3P3BtN3RIM8n+OvX4il1K1zgE8ZhI0op7kClgkxtutIE8hQrcrHBXvIheqKUUCxw==} @@ -5850,6 +8652,11 @@ packages: engines: {node: '>=10'} dev: true + /type-fest@0.21.3: + resolution: {integrity: sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==} + engines: {node: '>=10'} + dev: true + /type-fest@0.6.0: resolution: {integrity: sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==} engines: {node: '>=8'} @@ -5865,6 +8672,13 @@ packages: engines: {node: '>=10'} dev: false + /type-is@1.6.18: + resolution: {integrity: sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==} + engines: {node: '>= 0.6'} + dependencies: + media-typer: 0.3.0 + mime-types: 2.1.35 + /typed-array-buffer@1.0.2: resolution: {integrity: sha512-gEymJYKZtKXzzBzM4jqa9w6Q1Jjm7x2d+sh19AdsD4wqnMPDYyvwpsIc2Q/835kHuo3BEQ7CjelGhfTsoBb2MQ==} engines: {node: '>= 0.4'} @@ -5909,10 +8723,19 @@ packages: possible-typed-array-names: 1.0.0 dev: true + /typedarray@0.0.6: + resolution: {integrity: sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==} + /typeforce@1.18.0: resolution: {integrity: sha512-7uc1O8h1M1g0rArakJdf0uLRSSgFcYexrVoKo+bzJd32gd4gDy2L/Z+8/FjPnU9ydY3pEnVPtr9FyscYY60K1g==} dev: false + /typescript@5.3.3: + resolution: {integrity: sha512-pXWcraxM0uxAS+tN0AG/BF2TyqmHO014Z070UsJ+pFvYuRSq8KH8DmWpnbXe0pEPDHXZV3FcAbJkijJ5oNEnWw==} + engines: {node: '>=14.17'} + hasBin: true + dev: true + /typescript@5.4.2: resolution: {integrity: sha512-+2/g0Fds1ERlP6JsakQQDXjZdZMM+rqpamFZJEKh4kwTIn3iDkgKtby0CeNd5ATNZ4Ry1ax15TMx0W2V+miizQ==} engines: {node: '>=14.17'} @@ -5929,6 +8752,12 @@ packages: resolution: {integrity: sha512-eiutMaL0J2MKdhcOM1tUy13pIrYnyR87fEd8STJQFrrAwImwvlXkxlZEjaKah8r2viPohld08lt73QfLG1NxMg==} dev: true + /uid@2.0.2: + resolution: {integrity: sha512-u3xV3X7uzvi5b1MncmZo3i2Aw222Zk1keqLA1YkHldREkAhAqi65wuPfe7lHx8H/Wzy+8CE7S7uS3jekIM5s8g==} + engines: {node: '>=8'} + dependencies: + '@lukeed/csprng': 1.1.0 + /unbox-primitive@1.0.2: resolution: {integrity: sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==} dependencies: @@ -5946,6 +8775,15 @@ packages: engines: {node: '>= 4.0.0'} dev: true + /universalify@2.0.1: + resolution: {integrity: sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==} + engines: {node: '>= 10.0.0'} + dev: true + + /unpipe@1.0.0: + resolution: {integrity: sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==} + engines: {node: '>= 0.8'} + /update-browserslist-db@1.0.13(browserslist@4.23.0): resolution: {integrity: sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==} hasBin: true @@ -5983,6 +8821,10 @@ packages: which-typed-array: 1.1.15 dev: true + /utils-merge@1.0.1: + resolution: {integrity: sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==} + engines: {node: '>= 0.4.0'} + /uuid@8.3.2: resolution: {integrity: sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==} hasBin: true @@ -5992,6 +8834,15 @@ packages: resolution: {integrity: sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==} dev: true + /v8-to-istanbul@9.2.0: + resolution: {integrity: sha512-/EH/sDgxU2eGxajKdwLCDmQ4FWq+kpi3uCmBGpw1xJtnAxEjlD8j8PEiGWpCIMIs3ciNAgH0d3TTJiUkYzyZjA==} + engines: {node: '>=10.12.0'} + dependencies: + '@jridgewell/trace-mapping': 0.3.25 + '@types/istanbul-lib-coverage': 2.0.6 + convert-source-map: 2.0.0 + dev: true + /validate-npm-package-license@3.0.4: resolution: {integrity: sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==} dependencies: @@ -6005,6 +8856,10 @@ packages: safe-buffer: 5.2.1 dev: false + /vary@1.1.2: + resolution: {integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==} + engines: {node: '>= 0.8'} + /vite-node@1.4.0(@types/node@20.12.12): resolution: {integrity: sha512-VZDAseqjrHgNd4Kh8icYHWzTKSCZMhia7GyHfhtzLW33fZlG9SwsB6CEhgyVOWkJfJ2pFLrp/Gj1FSfAiqH9Lw==} engines: {node: ^18.0.0 || >=20.0.0} @@ -6134,6 +8989,20 @@ packages: resolution: {integrity: sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ==} dev: true + /walker@1.0.8: + resolution: {integrity: sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==} + dependencies: + makeerror: 1.0.12 + dev: true + + /watchpack@2.4.1: + resolution: {integrity: sha512-8wrBCMtVhqcXP2Sup1ctSkga6uc2Bx0IIvKyT7yTFier5AXHooSI+QyQQAtTb7+E0IUCCKyTFmXqdqgum2XWGg==} + engines: {node: '>=10.13.0'} + dependencies: + glob-to-regexp: 0.4.1 + graceful-fs: 4.2.11 + dev: true + /wcwidth@1.0.1: resolution: {integrity: sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==} dependencies: @@ -6143,6 +9012,96 @@ packages: /webidl-conversions@3.0.1: resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==} + /webpack-node-externals@3.0.0: + resolution: {integrity: sha512-LnL6Z3GGDPht/AigwRh2dvL9PQPFQ8skEpVrWZXLWBYmqcaojHNN0onvHzie6rq7EWKrrBfPYqNEzTJgiwEQDQ==} + engines: {node: '>=6'} + dev: true + + /webpack-sources@3.2.3: + resolution: {integrity: sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==} + engines: {node: '>=10.13.0'} + dev: true + + /webpack@5.90.1: + resolution: {integrity: sha512-SstPdlAC5IvgFnhiRok8hqJo/+ArAbNv7rhU4fnWGHNVfN59HSQFaxZDSAL3IFG2YmqxuRs+IU33milSxbPlog==} + engines: {node: '>=10.13.0'} + hasBin: true + peerDependencies: + webpack-cli: '*' + peerDependenciesMeta: + webpack-cli: + optional: true + dependencies: + '@types/eslint-scope': 3.7.7 + '@types/estree': 1.0.5 + '@webassemblyjs/ast': 1.12.1 + '@webassemblyjs/wasm-edit': 1.12.1 + '@webassemblyjs/wasm-parser': 1.12.1 + acorn: 8.11.3 + acorn-import-assertions: 1.9.0(acorn@8.11.3) + browserslist: 4.23.0 + chrome-trace-event: 1.0.4 + enhanced-resolve: 5.16.1 + es-module-lexer: 1.5.3 + eslint-scope: 5.1.1 + events: 3.3.0 + glob-to-regexp: 0.4.1 + graceful-fs: 4.2.11 + json-parse-even-better-errors: 2.3.1 + loader-runner: 4.3.0 + mime-types: 2.1.35 + neo-async: 2.6.2 + schema-utils: 3.3.0 + tapable: 2.2.1 + terser-webpack-plugin: 5.3.10(webpack@5.90.1) + watchpack: 2.4.1 + webpack-sources: 3.2.3 + transitivePeerDependencies: + - '@swc/core' + - esbuild + - uglify-js + dev: true + + /webpack@5.91.0: + resolution: {integrity: sha512-rzVwlLeBWHJbmgTC/8TvAcu5vpJNII+MelQpylD4jNERPwpBJOE2lEcko1zJX3QJeLjTTAnQxn/OJ8bjDzVQaw==} + engines: {node: '>=10.13.0'} + hasBin: true + peerDependencies: + webpack-cli: '*' + peerDependenciesMeta: + webpack-cli: + optional: true + dependencies: + '@types/eslint-scope': 3.7.7 + '@types/estree': 1.0.5 + '@webassemblyjs/ast': 1.12.1 + '@webassemblyjs/wasm-edit': 1.12.1 + '@webassemblyjs/wasm-parser': 1.12.1 + acorn: 8.11.3 + acorn-import-assertions: 1.9.0(acorn@8.11.3) + browserslist: 4.23.0 + chrome-trace-event: 1.0.4 + enhanced-resolve: 5.16.1 + es-module-lexer: 1.5.3 + eslint-scope: 5.1.1 + events: 3.3.0 + glob-to-regexp: 0.4.1 + graceful-fs: 4.2.11 + json-parse-even-better-errors: 2.3.1 + loader-runner: 4.3.0 + mime-types: 2.1.35 + neo-async: 2.6.2 + schema-utils: 3.3.0 + tapable: 2.2.1 + terser-webpack-plugin: 5.3.10(webpack@5.91.0) + watchpack: 2.4.1 + webpack-sources: 3.2.3 + transitivePeerDependencies: + - '@swc/core' + - esbuild + - uglify-js + dev: true + /whatwg-url@5.0.0: resolution: {integrity: sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==} dependencies: @@ -6252,10 +9211,17 @@ packages: resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} dev: true + /write-file-atomic@4.0.2: + resolution: {integrity: sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==} + engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} + dependencies: + imurmurhash: 0.1.4 + signal-exit: 3.0.7 + dev: true + /xtend@4.0.2: resolution: {integrity: sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==} engines: {node: '>=0.4'} - dev: true /y18n@4.0.3: resolution: {integrity: sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==} From aad7d63563cc147bfb9cba26f3618df4355151d0 Mon Sep 17 00:00:00 2001 From: ahonn Date: Tue, 4 Jun 2024 17:29:52 +1000 Subject: [PATCH 19/90] feat: add json-rpc logger --- apps/service/src/json-rpc/json-rpc.server.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/apps/service/src/json-rpc/json-rpc.server.ts b/apps/service/src/json-rpc/json-rpc.server.ts index cafae837..5922b2cf 100644 --- a/apps/service/src/json-rpc/json-rpc.server.ts +++ b/apps/service/src/json-rpc/json-rpc.server.ts @@ -1,4 +1,4 @@ -import { Injectable } from '@nestjs/common'; +import { Injectable, Logger } from '@nestjs/common'; import { HttpAdapterHost, ModulesContainer } from '@nestjs/core'; import { JSONRPCServer, SimpleJSONRPCMethod } from 'json-rpc-2.0'; import { InstanceWrapper } from '@nestjs/core/injector/instance-wrapper'; @@ -8,6 +8,7 @@ import { JsonRpcConfig } from './json-rpc.module'; @Injectable() export class JsonRpcServer { private server: JSONRPCServer; + private logger = new Logger(JsonRpcServer.name); constructor( private httpAdapterHost: HttpAdapterHost, @@ -17,9 +18,9 @@ export class JsonRpcServer { const handlers = this.getRegisteredHandlers(); handlers.forEach((handler, name) => { + this.logger.log(`Registering JSON-RPC method: ${name}`); this.server.addMethod(name, handler); }); - console.log(this.server); } private getRegisteredHandlers() { @@ -56,6 +57,7 @@ export class JsonRpcServer { public async run(config: JsonRpcConfig) { this.httpAdapterHost.httpAdapter.post(config.path, async (req, res) => { + this.logger.debug(`Received JSON-RPC request: ${JSON.stringify(req.body)}`); const jsonRpcResponse = await this.server.receive(req.body); this.httpAdapterHost.httpAdapter.setHeader(res, 'Content-Type', 'application/json'); this.httpAdapterHost.httpAdapter.reply(res, jsonRpcResponse); From 02589c0b6cc015d07e1c6813f8e35aa95d99c413 Mon Sep 17 00:00:00 2001 From: ahonn Date: Tue, 4 Jun 2024 17:33:43 +1000 Subject: [PATCH 20/90] chore: remove apps/next and apps/vite --- apps/next/.env.example | 2 - apps/next/.gitignore | 36 ---------- apps/next/README.md | 36 ---------- apps/next/next.config.mjs | 18 ----- apps/next/package.json | 25 ------- apps/next/src/app/favicon.ico | Bin 25931 -> 0 bytes apps/next/src/app/layout.tsx | 19 ------ apps/next/src/app/page.tsx | 34 ---------- apps/next/tsconfig.json | 26 ------- apps/service/src/json-rpc/json-rpc.module.ts | 5 +- apps/vite/.env.example | 2 - apps/vite/.eslintrc.cjs | 18 ----- apps/vite/.gitignore | 24 ------- apps/vite/README.md | 30 -------- apps/vite/index.html | 13 ---- apps/vite/package.json | 33 --------- apps/vite/public/vite.svg | 1 - apps/vite/src/App.css | 42 ------------ apps/vite/src/App.tsx | 37 ---------- apps/vite/src/assets/react.svg | 1 - apps/vite/src/index.css | 68 ------------------- apps/vite/src/main.tsx | 5 -- apps/vite/src/vite-env.d.ts | 1 - apps/vite/tsconfig.json | 25 ------- apps/vite/tsconfig.node.json | 11 --- apps/vite/vite.config.ts | 7 -- 26 files changed, 1 insertion(+), 518 deletions(-) delete mode 100644 apps/next/.env.example delete mode 100644 apps/next/.gitignore delete mode 100644 apps/next/README.md delete mode 100644 apps/next/next.config.mjs delete mode 100644 apps/next/package.json delete mode 100644 apps/next/src/app/favicon.ico delete mode 100644 apps/next/src/app/layout.tsx delete mode 100644 apps/next/src/app/page.tsx delete mode 100644 apps/next/tsconfig.json delete mode 100644 apps/vite/.env.example delete mode 100644 apps/vite/.eslintrc.cjs delete mode 100644 apps/vite/.gitignore delete mode 100644 apps/vite/README.md delete mode 100644 apps/vite/index.html delete mode 100644 apps/vite/package.json delete mode 100644 apps/vite/public/vite.svg delete mode 100644 apps/vite/src/App.css delete mode 100644 apps/vite/src/App.tsx delete mode 100644 apps/vite/src/assets/react.svg delete mode 100644 apps/vite/src/index.css delete mode 100644 apps/vite/src/main.tsx delete mode 100644 apps/vite/src/vite-env.d.ts delete mode 100644 apps/vite/tsconfig.json delete mode 100644 apps/vite/tsconfig.node.json delete mode 100644 apps/vite/vite.config.ts diff --git a/apps/next/.env.example b/apps/next/.env.example deleted file mode 100644 index 22e91499..00000000 --- a/apps/next/.env.example +++ /dev/null @@ -1,2 +0,0 @@ -NEXT_PUBLIC_BTC_SERVICE_URL= -NEXT_PUBLIC_BTC_SERVICE_TOKEN= diff --git a/apps/next/.gitignore b/apps/next/.gitignore deleted file mode 100644 index fd3dbb57..00000000 --- a/apps/next/.gitignore +++ /dev/null @@ -1,36 +0,0 @@ -# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. - -# dependencies -/node_modules -/.pnp -.pnp.js -.yarn/install-state.gz - -# testing -/coverage - -# next.js -/.next/ -/out/ - -# production -/build - -# misc -.DS_Store -*.pem - -# debug -npm-debug.log* -yarn-debug.log* -yarn-error.log* - -# local env files -.env*.local - -# vercel -.vercel - -# typescript -*.tsbuildinfo -next-env.d.ts diff --git a/apps/next/README.md b/apps/next/README.md deleted file mode 100644 index c4033664..00000000 --- a/apps/next/README.md +++ /dev/null @@ -1,36 +0,0 @@ -This is a [Next.js](https://nextjs.org/) project bootstrapped with [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app). - -## Getting Started - -First, run the development server: - -```bash -npm run dev -# or -yarn dev -# or -pnpm dev -# or -bun dev -``` - -Open [http://localhost:3000](http://localhost:3000) with your browser to see the result. - -You can start editing the page by modifying `app/page.tsx`. The page auto-updates as you edit the file. - -This project uses [`next/font`](https://nextjs.org/docs/basic-features/font-optimization) to automatically optimize and load Inter, a custom Google Font. - -## Learn More - -To learn more about Next.js, take a look at the following resources: - -- [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API. -- [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial. - -You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js/) - your feedback and contributions are welcome! - -## Deploy on Vercel - -The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js. - -Check out our [Next.js deployment documentation](https://nextjs.org/docs/deployment) for more details. diff --git a/apps/next/next.config.mjs b/apps/next/next.config.mjs deleted file mode 100644 index 0d295c5c..00000000 --- a/apps/next/next.config.mjs +++ /dev/null @@ -1,18 +0,0 @@ -/** @type {import('next').NextConfig} */ -const nextConfig = { - webpack: function (config, options) { - config.experiments = { - layers: true, - }; - config.resolve = { - fallback: { - net: false, - tls: false, - }, - }; - - return config; - } -}; - -export default nextConfig; diff --git a/apps/next/package.json b/apps/next/package.json deleted file mode 100644 index 5c3af1b0..00000000 --- a/apps/next/package.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "name": "next-example", - "version": "0.1.0", - "private": true, - "scripts": { - "dev": "next dev --port 12345", - "build": "next build", - "start": "next start", - "lint": "next lint" - }, - "dependencies": { - "@rgbpp-sdk/service": "workspace:^", - "@rgbpp-sdk/btc": "workspace:^", - "@rgbpp-sdk/ckb": "workspace:^", - "react": "^18", - "react-dom": "^18", - "next": "14.1.2" - }, - "devDependencies": { - "typescript": "^5", - "@types/node": "^20", - "@types/react": "^18", - "@types/react-dom": "^18" - } -} diff --git a/apps/next/src/app/favicon.ico b/apps/next/src/app/favicon.ico deleted file mode 100644 index 718d6fea4835ec2d246af9800eddb7ffb276240c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 25931 zcmeHv30#a{`}aL_*G&7qml|y<+KVaDM2m#dVr!KsA!#An?kSQM(q<_dDNCpjEux83 zLb9Z^XxbDl(w>%i@8hT6>)&Gu{h#Oeyszu?xtw#Zb1mO{pgX9699l+Qppw7jXaYf~-84xW z)w4x8?=youko|}Vr~(D$UXIbiXABHh`p1?nn8Po~fxRJv}|0e(BPs|G`(TT%kKVJAdg5*Z|x0leQq0 zkdUBvb#>9F()jo|T~kx@OM8$9wzs~t2l;K=woNssA3l6|sx2r3+kdfVW@e^8e*E}v zA1y5{bRi+3Z`uD3{F7LgFJDdvm;nJilkzDku>BwXH(8ItVCXk*-lSJnR?-2UN%hJ){&rlvg`CDTj z)Bzo!3v7Ou#83zEDEFcKt(f1E0~=rqeEbTnMvWR#{+9pg%7G8y>u1OVRUSoox-ovF z2Ydma(;=YuBY(eI|04{hXzZD6_f(v~H;C~y5=DhAC{MMS>2fm~1H_t2$56pc$NH8( z5bH|<)71dV-_oCHIrzrT`2s-5w_+2CM0$95I6X8p^r!gHp+j_gd;9O<1~CEQQGS8) zS9Qh3#p&JM-G8rHekNmKVewU;pJRcTAog68KYo^dRo}(M>36U4Us zfgYWSiHZL3;lpWT=zNAW>Dh#mB!_@Lg%$ms8N-;aPqMn+C2HqZgz&9~Eu z4|Kp<`$q)Uw1R?y(~S>ePdonHxpV1#eSP1B;Ogo+-Pk}6#0GsZZ5!||ev2MGdh}_m z{DeR7?0-1^zVs&`AV6Vt;r3`I`OI_wgs*w=eO%_#7Kepl{B@xiyCANc(l zzIyd4y|c6PXWq9-|KM8(zIk8LPk(>a)zyFWjhT!$HJ$qX1vo@d25W<fvZQ2zUz5WRc(UnFMKHwe1| zWmlB1qdbiA(C0jmnV<}GfbKtmcu^2*P^O?MBLZKt|As~ge8&AAO~2K@zbXelK|4T<{|y4`raF{=72kC2Kn(L4YyenWgrPiv z@^mr$t{#X5VuIMeL!7Ab6_kG$&#&5p*Z{+?5U|TZ`B!7llpVmp@skYz&n^8QfPJzL z0G6K_OJM9x+Wu2gfN45phANGt{7=C>i34CV{Xqlx(fWpeAoj^N0Biu`w+MVcCUyU* zDZuzO0>4Z6fbu^T_arWW5n!E45vX8N=bxTVeFoep_G#VmNlQzAI_KTIc{6>c+04vr zx@W}zE5JNSU>!THJ{J=cqjz+4{L4A{Ob9$ZJ*S1?Ggg3klFp!+Y1@K+pK1DqI|_gq z5ZDXVpge8-cs!o|;K73#YXZ3AShj50wBvuq3NTOZ`M&qtjj#GOFfgExjg8Gn8>Vq5 z`85n+9|!iLCZF5$HJ$Iu($dm?8~-ofu}tEc+-pyke=3!im#6pk_Wo8IA|fJwD&~~F zc16osQ)EBo58U7XDuMexaPRjU@h8tXe%S{fA0NH3vGJFhuyyO!Uyl2^&EOpX{9As0 zWj+P>{@}jxH)8|r;2HdupP!vie{sJ28b&bo!8`D^x}TE$%zXNb^X1p@0PJ86`dZyj z%ce7*{^oo+6%&~I!8hQy-vQ7E)0t0ybH4l%KltWOo~8cO`T=157JqL(oq_rC%ea&4 z2NcTJe-HgFjNg-gZ$6!Y`SMHrlj}Etf7?r!zQTPPSv}{so2e>Fjs1{gzk~LGeesX%r(Lh6rbhSo_n)@@G-FTQy93;l#E)hgP@d_SGvyCp0~o(Y;Ee8{ zdVUDbHm5`2taPUOY^MAGOw*>=s7=Gst=D+p+2yON!0%Hk` zz5mAhyT4lS*T3LS^WSxUy86q&GnoHxzQ6vm8)VS}_zuqG?+3td68_x;etQAdu@sc6 zQJ&5|4(I?~3d-QOAODHpZ=hlSg(lBZ!JZWCtHHSj`0Wh93-Uk)_S%zsJ~aD>{`A0~ z9{AG(e|q3g5B%wYKRxiL2Y$8(4w6bzchKuloQW#e&S3n+P- z8!ds-%f;TJ1>)v)##>gd{PdS2Oc3VaR`fr=`O8QIO(6(N!A?pr5C#6fc~Ge@N%Vvu zaoAX2&(a6eWy_q&UwOhU)|P3J0Qc%OdhzW=F4D|pt0E4osw;%<%Dn58hAWD^XnZD= z>9~H(3bmLtxpF?a7su6J7M*x1By7YSUbxGi)Ot0P77`}P3{)&5Un{KD?`-e?r21!4vTTnN(4Y6Lin?UkSM z`MXCTC1@4A4~mvz%Rh2&EwY))LeoT=*`tMoqcEXI>TZU9WTP#l?uFv+@Dn~b(>xh2 z;>B?;Tz2SR&KVb>vGiBSB`@U7VIWFSo=LDSb9F{GF^DbmWAfpms8Sx9OX4CnBJca3 zlj9(x!dIjN?OG1X4l*imJNvRCk}F%!?SOfiOq5y^mZW)jFL@a|r-@d#f7 z2gmU8L3IZq0ynIws=}~m^#@&C%J6QFo~Mo4V`>v7MI-_!EBMMtb%_M&kvAaN)@ZVw z+`toz&WG#HkWDjnZE!6nk{e-oFdL^$YnbOCN}JC&{$#$O27@|Tn-skXr)2ml2~O!5 zX+gYoxhoc7qoU?C^3~&!U?kRFtnSEecWuH0B0OvLodgUAi}8p1 zrO6RSXHH}DMc$&|?D004DiOVMHV8kXCP@7NKB zgaZq^^O<7PoKEp72kby@W0Z!Y*Ay{&vfg#C&gG@YVR9g?FEocMUi1gSN$+V+ayF45{a zuDZDTN}mS|;BO%gEf}pjBfN2-gIrU#G5~cucA;dokXW89%>AyXJJI z9X4UlIWA|ZYHgbI z5?oFk@A=Ik7lrEQPDH!H+b`7_Y~aDb_qa=B2^Y&Ow41cU=4WDd40dp5(QS-WMN-=Y z9g;6_-JdNU;|6cPwf$ak*aJIcwL@1n$#l~zi{c{EW?T;DaW*E8DYq?Umtz{nJ&w-M zEMyTDrC&9K$d|kZe2#ws6)L=7K+{ zQw{XnV6UC$6-rW0emqm8wJoeZK)wJIcV?dST}Z;G0Arq{dVDu0&4kd%N!3F1*;*pW zR&qUiFzK=@44#QGw7k1`3t_d8&*kBV->O##t|tonFc2YWrL7_eqg+=+k;!F-`^b8> z#KWCE8%u4k@EprxqiV$VmmtiWxDLgnGu$Vs<8rppV5EajBXL4nyyZM$SWVm!wnCj-B!Wjqj5-5dNXukI2$$|Bu3Lrw}z65Lc=1G z^-#WuQOj$hwNGG?*CM_TO8Bg-1+qc>J7k5c51U8g?ZU5n?HYor;~JIjoWH-G>AoUP ztrWWLbRNqIjW#RT*WqZgPJXU7C)VaW5}MiijYbABmzoru6EmQ*N8cVK7a3|aOB#O& zBl8JY2WKfmj;h#Q!pN%9o@VNLv{OUL?rixHwOZuvX7{IJ{(EdPpuVFoQqIOa7giLVkBOKL@^smUA!tZ1CKRK}#SSM)iQHk)*R~?M!qkCruaS!#oIL1c z?J;U~&FfH#*98^G?i}pA{ z9Jg36t4=%6mhY(quYq*vSxptes9qy|7xSlH?G=S@>u>Ebe;|LVhs~@+06N<4CViBk zUiY$thvX;>Tby6z9Y1edAMQaiH zm^r3v#$Q#2T=X>bsY#D%s!bhs^M9PMAcHbCc0FMHV{u-dwlL;a1eJ63v5U*?Q_8JO zT#50!RD619#j_Uf))0ooADz~*9&lN!bBDRUgE>Vud-i5ck%vT=r^yD*^?Mp@Q^v+V zG#-?gKlr}Eeqifb{|So?HM&g91P8|av8hQoCmQXkd?7wIJwb z_^v8bbg`SAn{I*4bH$u(RZ6*xUhuA~hc=8czK8SHEKTzSxgbwi~9(OqJB&gwb^l4+m`k*Q;_?>Y-APi1{k zAHQ)P)G)f|AyjSgcCFps)Fh6Bca*Xznq36!pV6Az&m{O8$wGFD? zY&O*3*J0;_EqM#jh6^gMQKpXV?#1?>$ml1xvh8nSN>-?H=V;nJIwB07YX$e6vLxH( zqYwQ>qxwR(i4f)DLd)-$P>T-no_c!LsN@)8`e;W@)-Hj0>nJ-}Kla4-ZdPJzI&Mce zv)V_j;(3ERN3_@I$N<^|4Lf`B;8n+bX@bHbcZTopEmDI*Jfl)-pFDvo6svPRoo@(x z);_{lY<;);XzT`dBFpRmGrr}z5u1=pC^S-{ce6iXQlLGcItwJ^mZx{m$&DA_oEZ)B{_bYPq-HA zcH8WGoBG(aBU_j)vEy+_71T34@4dmSg!|M8Vf92Zj6WH7Q7t#OHQqWgFE3ARt+%!T z?oLovLVlnf?2c7pTc)~cc^($_8nyKwsN`RA-23ed3sdj(ys%pjjM+9JrctL;dy8a( z@en&CQmnV(()bu|Y%G1-4a(6x{aLytn$T-;(&{QIJB9vMox11U-1HpD@d(QkaJdEb zG{)+6Dos_L+O3NpWo^=gR?evp|CqEG?L&Ut#D*KLaRFOgOEK(Kq1@!EGcTfo+%A&I z=dLbB+d$u{sh?u)xP{PF8L%;YPPW53+@{>5W=Jt#wQpN;0_HYdw1{ksf_XhO4#2F= zyPx6Lx2<92L-;L5PD`zn6zwIH`Jk($?Qw({erA$^bC;q33hv!d!>%wRhj# zal^hk+WGNg;rJtb-EB(?czvOM=H7dl=vblBwAv>}%1@{}mnpUznfq1cE^sgsL0*4I zJ##!*B?=vI_OEVis5o+_IwMIRrpQyT_Sq~ZU%oY7c5JMIADzpD!Upz9h@iWg_>>~j zOLS;wp^i$-E?4<_cp?RiS%Rd?i;f*mOz=~(&3lo<=@(nR!_Rqiprh@weZlL!t#NCc zO!QTcInq|%#>OVgobj{~ixEUec`E25zJ~*DofsQdzIa@5^nOXj2T;8O`l--(QyU^$t?TGY^7#&FQ+2SS3B#qK*k3`ye?8jUYSajE5iBbJls75CCc(m3dk{t?- zopcER9{Z?TC)mk~gpi^kbbu>b-+a{m#8-y2^p$ka4n60w;Sc2}HMf<8JUvhCL0B&Btk)T`ctE$*qNW8L$`7!r^9T+>=<=2qaq-;ll2{`{Rg zc5a0ZUI$oG&j-qVOuKa=*v4aY#IsoM+1|c4Z)<}lEDvy;5huB@1RJPquU2U*U-;gu z=En2m+qjBzR#DEJDO`WU)hdd{Vj%^0V*KoyZ|5lzV87&g_j~NCjwv0uQVqXOb*QrQ zy|Qn`hxx(58c70$E;L(X0uZZ72M1!6oeg)(cdKO ze0gDaTz+ohR-#d)NbAH4x{I(21yjwvBQfmpLu$)|m{XolbgF!pmsqJ#D}(ylp6uC> z{bqtcI#hT#HW=wl7>p!38sKsJ`r8}lt-q%Keqy%u(xk=yiIJiUw6|5IvkS+#?JTBl z8H5(Q?l#wzazujH!8o>1xtn8#_w+397*_cy8!pQGP%K(Ga3pAjsaTbbXJlQF_+m+-UpUUent@xM zg%jqLUExj~o^vQ3Gl*>wh=_gOr2*|U64_iXb+-111aH}$TjeajM+I20xw(((>fej-@CIz4S1pi$(#}P7`4({6QS2CaQS4NPENDp>sAqD z$bH4KGzXGffkJ7R>V>)>tC)uax{UsN*dbeNC*v}#8Y#OWYwL4t$ePR?VTyIs!wea+ z5Urmc)X|^`MG~*dS6pGSbU+gPJoq*^a=_>$n4|P^w$sMBBy@f*Z^Jg6?n5?oId6f{ z$LW4M|4m502z0t7g<#Bx%X;9<=)smFolV&(V^(7Cv2-sxbxopQ!)*#ZRhTBpx1)Fc zNm1T%bONzv6@#|dz(w02AH8OXe>kQ#1FMCzO}2J_mST)+ExmBr9cva-@?;wnmWMOk z{3_~EX_xadgJGv&H@zK_8{(x84`}+c?oSBX*Ge3VdfTt&F}yCpFP?CpW+BE^cWY0^ zb&uBN!Ja3UzYHK-CTyA5=L zEMW{l3Usky#ly=7px648W31UNV@K)&Ub&zP1c7%)`{);I4b0Q<)B}3;NMG2JH=X$U zfIW4)4n9ZM`-yRj67I)YSLDK)qfUJ_ij}a#aZN~9EXrh8eZY2&=uY%2N0UFF7<~%M zsB8=erOWZ>Ct_#^tHZ|*q`H;A)5;ycw*IcmVxi8_0Xk}aJA^ath+E;xg!x+As(M#0=)3!NJR6H&9+zd#iP(m0PIW8$ z1Y^VX`>jm`W!=WpF*{ioM?C9`yOR>@0q=u7o>BP-eSHqCgMDj!2anwH?s%i2p+Q7D zzszIf5XJpE)IG4;d_(La-xenmF(tgAxK`Y4sQ}BSJEPs6N_U2vI{8=0C_F?@7<(G; zo$~G=8p+076G;`}>{MQ>t>7cm=zGtfbdDXm6||jUU|?X?CaE?(<6bKDYKeHlz}DA8 zXT={X=yp_R;HfJ9h%?eWvQ!dRgz&Su*JfNt!Wu>|XfU&68iRikRrHRW|ZxzRR^`eIGt zIeiDgVS>IeExKVRWW8-=A=yA`}`)ZkWBrZD`hpWIxBGkh&f#ijr449~m`j6{4jiJ*C!oVA8ZC?$1RM#K(_b zL9TW)kN*Y4%^-qPpMP7d4)o?Nk#>aoYHT(*g)qmRUb?**F@pnNiy6Fv9rEiUqD(^O zzyS?nBrX63BTRYduaG(0VVG2yJRe%o&rVrLjbxTaAFTd8s;<<@Qs>u(<193R8>}2_ zuwp{7;H2a*X7_jryzriZXMg?bTuegABb^87@SsKkr2)0Gyiax8KQWstw^v#ix45EVrcEhr>!NMhprl$InQMzjSFH54x5k9qHc`@9uKQzvL4ihcq{^B zPrVR=o_ic%Y>6&rMN)hTZsI7I<3&`#(nl+3y3ys9A~&^=4?PL&nd8)`OfG#n zwAMN$1&>K++c{^|7<4P=2y(B{jJsQ0a#U;HTo4ZmWZYvI{+s;Td{Yzem%0*k#)vjpB zia;J&>}ICate44SFYY3vEelqStQWFihx%^vQ@Do(sOy7yR2@WNv7Y9I^yL=nZr3mb zXKV5t@=?-Sk|b{XMhA7ZGB@2hqsx}4xwCW!in#C zI@}scZlr3-NFJ@NFaJlhyfcw{k^vvtGl`N9xSo**rDW4S}i zM9{fMPWo%4wYDG~BZ18BD+}h|GQKc-g^{++3MY>}W_uq7jGHx{mwE9fZiPCoxN$+7 zrODGGJrOkcPQUB(FD5aoS4g~7#6NR^ma7-!>mHuJfY5kTe6PpNNKC9GGRiu^L31uG z$7v`*JknQHsYB!Tm_W{a32TM099djW%5e+j0Ve_ct}IM>XLF1Ap+YvcrLV=|CKo6S zb+9Nl3_YdKP6%Cxy@6TxZ>;4&nTneadr z_ES90ydCev)LV!dN=#(*f}|ZORFdvkYBni^aLbUk>BajeWIOcmHP#8S)*2U~QKI%S zyrLmtPqb&TphJ;>yAxri#;{uyk`JJqODDw%(Z=2`1uc}br^V%>j!gS)D*q*f_-qf8&D;W1dJgQMlaH5er zN2U<%Smb7==vE}dDI8K7cKz!vs^73o9f>2sgiTzWcwY|BMYHH5%Vn7#kiw&eItCqa zIkR2~Q}>X=Ar8W|^Ms41Fm8o6IB2_j60eOeBB1Br!boW7JnoeX6Gs)?7rW0^5psc- zjS16yb>dFn>KPOF;imD}e!enuIniFzv}n$m2#gCCv4jM#ArwlzZ$7@9&XkFxZ4n!V zj3dyiwW4Ki2QG{@i>yuZXQizw_OkZI^-3otXC{!(lUpJF33gI60ak;Uqitp74|B6I zgg{b=Iz}WkhCGj1M=hu4#Aw173YxIVbISaoc z-nLZC*6Tgivd5V`K%GxhBsp@SUU60-rfc$=wb>zdJzXS&-5(NRRodFk;Kxk!S(O(a0e7oY=E( zAyS;Ow?6Q&XA+cnkCb{28_1N8H#?J!*$MmIwLq^*T_9-z^&UE@A(z9oGYtFy6EZef LrJugUA?W`A8`#=m diff --git a/apps/next/src/app/layout.tsx b/apps/next/src/app/layout.tsx deleted file mode 100644 index 3c934c40..00000000 --- a/apps/next/src/app/layout.tsx +++ /dev/null @@ -1,19 +0,0 @@ -import type { Metadata } from 'next'; -import { ReactNode } from 'react'; - -export const metadata: Metadata = { - title: 'Create Next App', - description: 'Generated by create next app', -}; - -export default function RootLayout({ - children, -}: Readonly<{ - children: ReactNode; -}>) { - return ( - - {children} - - ); -} diff --git a/apps/next/src/app/page.tsx b/apps/next/src/app/page.tsx deleted file mode 100644 index f68107e2..00000000 --- a/apps/next/src/app/page.tsx +++ /dev/null @@ -1,34 +0,0 @@ -'use client'; -import { sendBtc, NetworkType, DataSource } from '@rgbpp-sdk/btc'; -import { BtcAssetsApi } from '@rgbpp-sdk/service'; - -export default function Home() { - async function send() { - const networkType = NetworkType.TESTNET; - - const service = BtcAssetsApi.fromToken( - process.env.NEXT_PUBLIC_BTC_SERVICE_URL!, - process.env.NEXT_PUBLIC_BTC_SERVICE_TOKEN!, - ); - const source = new DataSource(service, networkType); - - const psbt = await sendBtc({ - from: 'tb1qm06rvrq8jyyckzc5v709u7qpthel9j4d9f7nh3', - tos: [ - { - address: 'tb1qm06rvrq8jyyckzc5v709u7qpthel9j4d9f7nh3', - value: 1000, - }, - ], - source, - }); - - console.log('passed', psbt.toHex()); - } - - return ( -
- -
- ); -} diff --git a/apps/next/tsconfig.json b/apps/next/tsconfig.json deleted file mode 100644 index 7b285893..00000000 --- a/apps/next/tsconfig.json +++ /dev/null @@ -1,26 +0,0 @@ -{ - "compilerOptions": { - "lib": ["dom", "dom.iterable", "esnext"], - "allowJs": true, - "skipLibCheck": true, - "strict": true, - "noEmit": true, - "esModuleInterop": true, - "module": "esnext", - "moduleResolution": "bundler", - "resolveJsonModule": true, - "isolatedModules": true, - "jsx": "preserve", - "incremental": true, - "plugins": [ - { - "name": "next" - } - ], - "paths": { - "@/*": ["./src/*"] - } - }, - "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"], - "exclude": ["node_modules"] -} diff --git a/apps/service/src/json-rpc/json-rpc.module.ts b/apps/service/src/json-rpc/json-rpc.module.ts index 4bf9b06f..032ebb47 100644 --- a/apps/service/src/json-rpc/json-rpc.module.ts +++ b/apps/service/src/json-rpc/json-rpc.module.ts @@ -1,6 +1,5 @@ import { Inject, Logger, Module, OnModuleInit } from '@nestjs/common'; import { JsonRpcServer } from './json-rpc.server'; -import { NestContainer } from '@nestjs/core'; export const JSON_RPC_OPTIONS = '__JSON_RPC_OPTIONS__'; @@ -8,9 +7,7 @@ export interface JsonRpcConfig { path: string; } -@Module({ - providers: [NestContainer], -}) +@Module({}) export class JsonRpcModule implements OnModuleInit { private logger = new Logger(JsonRpcModule.name); diff --git a/apps/vite/.env.example b/apps/vite/.env.example deleted file mode 100644 index 23e23fcf..00000000 --- a/apps/vite/.env.example +++ /dev/null @@ -1,2 +0,0 @@ -VITE_BTC_SERVICE_URL= -VITE_BTC_SERVICE_TOKEN= diff --git a/apps/vite/.eslintrc.cjs b/apps/vite/.eslintrc.cjs deleted file mode 100644 index d6c95379..00000000 --- a/apps/vite/.eslintrc.cjs +++ /dev/null @@ -1,18 +0,0 @@ -module.exports = { - root: true, - env: { browser: true, es2020: true }, - extends: [ - 'eslint:recommended', - 'plugin:@typescript-eslint/recommended', - 'plugin:react-hooks/recommended', - ], - ignorePatterns: ['dist', '.eslintrc.cjs'], - parser: '@typescript-eslint/parser', - plugins: ['react-refresh'], - rules: { - 'react-refresh/only-export-components': [ - 'warn', - { allowConstantExport: true }, - ], - }, -} diff --git a/apps/vite/.gitignore b/apps/vite/.gitignore deleted file mode 100644 index a547bf36..00000000 --- a/apps/vite/.gitignore +++ /dev/null @@ -1,24 +0,0 @@ -# Logs -logs -*.log -npm-debug.log* -yarn-debug.log* -yarn-error.log* -pnpm-debug.log* -lerna-debug.log* - -node_modules -dist -dist-ssr -*.local - -# Editor directories and files -.vscode/* -!.vscode/extensions.json -.idea -.DS_Store -*.suo -*.ntvs* -*.njsproj -*.sln -*.sw? diff --git a/apps/vite/README.md b/apps/vite/README.md deleted file mode 100644 index 9d0b4bcd..00000000 --- a/apps/vite/README.md +++ /dev/null @@ -1,30 +0,0 @@ -# React + TypeScript + Vite - -This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules. - -Currently, two official plugins are available: - -- [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react/README.md) uses [Babel](https://babeljs.io/) for Fast Refresh -- [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react-swc) uses [SWC](https://swc.rs/) for Fast Refresh - -## Expanding the ESLint configuration - -If you are developing a production application, we recommend updating the configuration to enable type aware lint rules: - -- Configure the top-level `parserOptions` property like this: - -```js -export default { - // other rules... - parserOptions: { - ecmaVersion: 'latest', - sourceType: 'module', - project: ['./tsconfig.json', './tsconfig.node.json'], - tsconfigRootDir: __dirname, - }, -}; -``` - -- Replace `plugin:@typescript-eslint/recommended` to `plugin:@typescript-eslint/recommended-type-checked` or `plugin:@typescript-eslint/strict-type-checked` -- Optionally add `plugin:@typescript-eslint/stylistic-type-checked` -- Install [eslint-plugin-react](https://github.com/jsx-eslint/eslint-plugin-react) and add `plugin:react/recommended` & `plugin:react/jsx-runtime` to the `extends` list diff --git a/apps/vite/index.html b/apps/vite/index.html deleted file mode 100644 index e4b78eae..00000000 --- a/apps/vite/index.html +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - Vite + React + TS - - -
- - - diff --git a/apps/vite/package.json b/apps/vite/package.json deleted file mode 100644 index c2c54150..00000000 --- a/apps/vite/package.json +++ /dev/null @@ -1,33 +0,0 @@ -{ - "name": "vite", - "private": true, - "version": "0.0.0", - "type": "module", - "scripts": { - "dev": "vite --host", - "build": "tsc && vite build", - "lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0", - "preview": "vite preview" - }, - "dependencies": { - "@rgbpp-sdk/service": "workspace:^", - "@rgbpp-sdk/ckb": "workspace:^", - "@rgbpp-sdk/btc": "workspace:^", - "buffer": "^6.0.3", - "react": "^18.2.0", - "react-dom": "^18.2.0" - }, - "devDependencies": { - "@types/react": "^18.2.56", - "@types/react-dom": "^18.2.19", - "@typescript-eslint/eslint-plugin": "^7.0.2", - "@typescript-eslint/parser": "^7.0.2", - "@vitejs/plugin-react": "^4.2.1", - "eslint": "^8.56.0", - "eslint-plugin-react-hooks": "^4.6.0", - "eslint-plugin-react-refresh": "^0.4.5", - "typescript": "^5.2.2", - "vite": "^5.2.11", - "vite-plugin-node-polyfills": "^0.21.0" - } -} diff --git a/apps/vite/public/vite.svg b/apps/vite/public/vite.svg deleted file mode 100644 index e7b8dfb1..00000000 --- a/apps/vite/public/vite.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/apps/vite/src/App.css b/apps/vite/src/App.css deleted file mode 100644 index b9d355df..00000000 --- a/apps/vite/src/App.css +++ /dev/null @@ -1,42 +0,0 @@ -#root { - max-width: 1280px; - margin: 0 auto; - padding: 2rem; - text-align: center; -} - -.logo { - height: 6em; - padding: 1.5em; - will-change: filter; - transition: filter 300ms; -} -.logo:hover { - filter: drop-shadow(0 0 2em #646cffaa); -} -.logo.react:hover { - filter: drop-shadow(0 0 2em #61dafbaa); -} - -@keyframes logo-spin { - from { - transform: rotate(0deg); - } - to { - transform: rotate(360deg); - } -} - -@media (prefers-reduced-motion: no-preference) { - a:nth-of-type(2) .logo { - animation: logo-spin infinite 20s linear; - } -} - -.card { - padding: 2em; -} - -.read-the-docs { - color: #888; -} diff --git a/apps/vite/src/App.tsx b/apps/vite/src/App.tsx deleted file mode 100644 index 02edecef..00000000 --- a/apps/vite/src/App.tsx +++ /dev/null @@ -1,37 +0,0 @@ -import './App.css'; -import { sendBtc, NetworkType, DataSource } from '@rgbpp-sdk/btc'; -import { BtcAssetsApi } from '@rgbpp-sdk/service'; - -function App() { - async function send() { - const networkType = NetworkType.TESTNET; - - const service = BtcAssetsApi.fromToken( - import.meta.env.VITE_BTC_SERVICE_URL!, - import.meta.env.VITE_BTC_SERVICE_TOKEN!, - ); - const source = new DataSource(service, networkType); - - const psbt = await sendBtc({ - from: 'tb1qm06rvrq8jyyckzc5v709u7qpthel9j4d9f7nh3', - tos: [ - { - address: 'tb1qm06rvrq8jyyckzc5v709u7qpthel9j4d9f7nh3', - value: 1000, - }, - ], - source, - }); - - console.log('passed', psbt.toHex()); - } - - return ( -
-

Hello

- -
- ); -} - -export default App; diff --git a/apps/vite/src/assets/react.svg b/apps/vite/src/assets/react.svg deleted file mode 100644 index 6c87de9b..00000000 --- a/apps/vite/src/assets/react.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/apps/vite/src/index.css b/apps/vite/src/index.css deleted file mode 100644 index 6119ad9a..00000000 --- a/apps/vite/src/index.css +++ /dev/null @@ -1,68 +0,0 @@ -:root { - font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif; - line-height: 1.5; - font-weight: 400; - - color-scheme: light dark; - color: rgba(255, 255, 255, 0.87); - background-color: #242424; - - font-synthesis: none; - text-rendering: optimizeLegibility; - -webkit-font-smoothing: antialiased; - -moz-osx-font-smoothing: grayscale; -} - -a { - font-weight: 500; - color: #646cff; - text-decoration: inherit; -} -a:hover { - color: #535bf2; -} - -body { - margin: 0; - display: flex; - place-items: center; - min-width: 320px; - min-height: 100vh; -} - -h1 { - font-size: 3.2em; - line-height: 1.1; -} - -button { - border-radius: 8px; - border: 1px solid transparent; - padding: 0.6em 1.2em; - font-size: 1em; - font-weight: 500; - font-family: inherit; - background-color: #1a1a1a; - cursor: pointer; - transition: border-color 0.25s; -} -button:hover { - border-color: #646cff; -} -button:focus, -button:focus-visible { - outline: 4px auto -webkit-focus-ring-color; -} - -@media (prefers-color-scheme: light) { - :root { - color: #213547; - background-color: #ffffff; - } - a:hover { - color: #747bff; - } - button { - background-color: #f9f9f9; - } -} diff --git a/apps/vite/src/main.tsx b/apps/vite/src/main.tsx deleted file mode 100644 index 0fe89954..00000000 --- a/apps/vite/src/main.tsx +++ /dev/null @@ -1,5 +0,0 @@ -import ReactDOM from 'react-dom/client'; -import App from './App.tsx'; -import './index.css'; - -ReactDOM.createRoot(document.getElementById('root')!).render(); diff --git a/apps/vite/src/vite-env.d.ts b/apps/vite/src/vite-env.d.ts deleted file mode 100644 index 11f02fe2..00000000 --- a/apps/vite/src/vite-env.d.ts +++ /dev/null @@ -1 +0,0 @@ -/// diff --git a/apps/vite/tsconfig.json b/apps/vite/tsconfig.json deleted file mode 100644 index a7fc6fbf..00000000 --- a/apps/vite/tsconfig.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "compilerOptions": { - "target": "ES2020", - "useDefineForClassFields": true, - "lib": ["ES2020", "DOM", "DOM.Iterable"], - "module": "ESNext", - "skipLibCheck": true, - - /* Bundler mode */ - "moduleResolution": "bundler", - "allowImportingTsExtensions": true, - "resolveJsonModule": true, - "isolatedModules": true, - "noEmit": true, - "jsx": "react-jsx", - - /* Linting */ - "strict": true, - "noUnusedLocals": true, - "noUnusedParameters": true, - "noFallthroughCasesInSwitch": true - }, - "include": ["src"], - "references": [{ "path": "./tsconfig.node.json" }] -} diff --git a/apps/vite/tsconfig.node.json b/apps/vite/tsconfig.node.json deleted file mode 100644 index 97ede7ee..00000000 --- a/apps/vite/tsconfig.node.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "compilerOptions": { - "composite": true, - "skipLibCheck": true, - "module": "ESNext", - "moduleResolution": "bundler", - "allowSyntheticDefaultImports": true, - "strict": true - }, - "include": ["vite.config.ts"] -} diff --git a/apps/vite/vite.config.ts b/apps/vite/vite.config.ts deleted file mode 100644 index 46a007c5..00000000 --- a/apps/vite/vite.config.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { defineConfig } from 'vite'; -import { nodePolyfills } from 'vite-plugin-node-polyfills'; - -// https://vitejs.dev/config/ -export default defineConfig({ - plugins: [nodePolyfills()], -}); From ed5ae24b25998a9081d54e59ca5a7d17b10a205f Mon Sep 17 00:00:00 2001 From: ahonn Date: Tue, 4 Jun 2024 17:37:09 +1000 Subject: [PATCH 21/90] build: update pnpm-lock.yaml --- pnpm-lock.yaml | 1010 ++---------------------------------------------- 1 file changed, 37 insertions(+), 973 deletions(-) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 0bf1e976..2d2cc611 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -48,40 +48,6 @@ importers: specifier: ^5.4.3 version: 5.4.3 - apps/next: - dependencies: - '@rgbpp-sdk/btc': - specifier: workspace:^ - version: link:../../packages/btc - '@rgbpp-sdk/ckb': - specifier: workspace:^ - version: link:../../packages/ckb - '@rgbpp-sdk/service': - specifier: workspace:^ - version: link:../../packages/service - next: - specifier: 14.1.2 - version: 14.1.2(react-dom@18.2.0)(react@18.2.0) - react: - specifier: ^18 - version: 18.2.0 - react-dom: - specifier: ^18 - version: 18.2.0(react@18.2.0) - devDependencies: - '@types/node': - specifier: ^20 - version: 20.11.28 - '@types/react': - specifier: ^18 - version: 18.2.56 - '@types/react-dom': - specifier: ^18 - version: 18.2.19 - typescript: - specifier: ^5 - version: 5.4.2 - apps/service: dependencies: '@nestjs/common': @@ -146,61 +112,6 @@ importers: specifier: ^5.1.3 version: 5.4.3 - apps/vite: - dependencies: - '@rgbpp-sdk/btc': - specifier: workspace:^ - version: link:../../packages/btc - '@rgbpp-sdk/ckb': - specifier: workspace:^ - version: link:../../packages/ckb - '@rgbpp-sdk/service': - specifier: workspace:^ - version: link:../../packages/service - buffer: - specifier: ^6.0.3 - version: 6.0.3 - react: - specifier: ^18.2.0 - version: 18.2.0 - react-dom: - specifier: ^18.2.0 - version: 18.2.0(react@18.2.0) - devDependencies: - '@types/react': - specifier: ^18.2.56 - version: 18.2.56 - '@types/react-dom': - specifier: ^18.2.19 - version: 18.2.19 - '@typescript-eslint/eslint-plugin': - specifier: ^7.0.2 - version: 7.0.2(@typescript-eslint/parser@7.0.2)(eslint@8.56.0)(typescript@5.4.2) - '@typescript-eslint/parser': - specifier: ^7.0.2 - version: 7.0.2(eslint@8.56.0)(typescript@5.4.2) - '@vitejs/plugin-react': - specifier: ^4.2.1 - version: 4.2.1(vite@5.2.11) - eslint: - specifier: ^8.56.0 - version: 8.56.0 - eslint-plugin-react-hooks: - specifier: ^4.6.0 - version: 4.6.0(eslint@8.56.0) - eslint-plugin-react-refresh: - specifier: ^0.4.5 - version: 0.4.5(eslint@8.56.0) - typescript: - specifier: ^5.2.2 - version: 5.4.2 - vite: - specifier: ^5.2.11 - version: 5.2.11(@types/node@20.12.12) - vite-plugin-node-polyfills: - specifier: ^0.21.0 - version: 0.21.0(vite@5.2.11) - examples/rgbpp: dependencies: '@nervosnetwork/ckb-sdk-utils': @@ -448,14 +359,6 @@ packages: - chokidar dev: true - /@babel/code-frame@7.23.5: - resolution: {integrity: sha512-CgH3s1a96LipHCmSUmYFPwY7MNx8C3avkq7i4Wl3cfa662ldtUe4VM1TPXX70pfmrlWTb6jLqTYrZyT2ZTJBgA==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/highlight': 7.23.4 - chalk: 2.4.2 - dev: true - /@babel/code-frame@7.24.2: resolution: {integrity: sha512-y5+tLQyV8pg3fsiln67BVLD1P13Eg4lh5RW9mF0zUuvLrv9uIQ4MCL+CRT+FTsBlBjcIan6PGsLcBN0m3ClUyQ==} engines: {node: '>=6.9.0'} @@ -474,7 +377,7 @@ packages: engines: {node: '>=6.9.0'} dependencies: '@ampproject/remapping': 2.3.0 - '@babel/code-frame': 7.23.5 + '@babel/code-frame': 7.24.2 '@babel/generator': 7.23.6 '@babel/helper-compilation-targets': 7.23.6 '@babel/helper-module-transforms': 7.23.3(@babel/core@7.24.0) @@ -554,11 +457,6 @@ packages: '@babel/helper-validator-identifier': 7.22.20 dev: true - /@babel/helper-plugin-utils@7.24.0: - resolution: {integrity: sha512-9cUznXMG0+FxRuJfvL82QlTqIzhVW9sL0KjMPHhAOOvpQGL8QtdxnBKILjBqxlHyliz0yCa1G903ZXI/FuHy2w==} - engines: {node: '>=6.9.0'} - dev: true - /@babel/helper-plugin-utils@7.24.6: resolution: {integrity: sha512-MZG/JcWfxybKwsA9N9PmtF2lOSFSEMVCpIRrbxccZFLJPrJciJdG/UhSh5W96GEteJI2ARqm5UAHxISwRDLSNg==} engines: {node: '>=6.9.0'} @@ -604,15 +502,6 @@ packages: - supports-color dev: true - /@babel/highlight@7.23.4: - resolution: {integrity: sha512-acGdbYSfp2WheJoJm/EBBBLh/ID8KDc64ISZ9DYtBmC8/Q204PZJLHyzeB5qMzJ5trcOkybd78M4x2KWsUq++A==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/helper-validator-identifier': 7.22.20 - chalk: 2.4.2 - js-tokens: 4.0.0 - dev: true - /@babel/highlight@7.24.2: resolution: {integrity: sha512-Yac1ao4flkTxTteCDZLEvdxg2fZfz1v8M4QpaGypq/WPDqg3ijHYbDfs+LG5hvzSoqaSZ9/Z9lKSP3CjZjv+pA==} engines: {node: '>=6.9.0'} @@ -637,7 +526,7 @@ packages: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.24.0 - '@babel/helper-plugin-utils': 7.24.0 + '@babel/helper-plugin-utils': 7.24.6 dev: true /@babel/plugin-syntax-bigint@7.8.3(@babel/core@7.24.0): @@ -646,7 +535,7 @@ packages: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.24.0 - '@babel/helper-plugin-utils': 7.24.0 + '@babel/helper-plugin-utils': 7.24.6 dev: true /@babel/plugin-syntax-class-properties@7.12.13(@babel/core@7.24.0): @@ -655,7 +544,7 @@ packages: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.24.0 - '@babel/helper-plugin-utils': 7.24.0 + '@babel/helper-plugin-utils': 7.24.6 dev: true /@babel/plugin-syntax-import-meta@7.10.4(@babel/core@7.24.0): @@ -664,7 +553,7 @@ packages: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.24.0 - '@babel/helper-plugin-utils': 7.24.0 + '@babel/helper-plugin-utils': 7.24.6 dev: true /@babel/plugin-syntax-json-strings@7.8.3(@babel/core@7.24.0): @@ -673,7 +562,7 @@ packages: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.24.0 - '@babel/helper-plugin-utils': 7.24.0 + '@babel/helper-plugin-utils': 7.24.6 dev: true /@babel/plugin-syntax-jsx@7.24.6(@babel/core@7.24.0): @@ -692,7 +581,7 @@ packages: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.24.0 - '@babel/helper-plugin-utils': 7.24.0 + '@babel/helper-plugin-utils': 7.24.6 dev: true /@babel/plugin-syntax-nullish-coalescing-operator@7.8.3(@babel/core@7.24.0): @@ -701,7 +590,7 @@ packages: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.24.0 - '@babel/helper-plugin-utils': 7.24.0 + '@babel/helper-plugin-utils': 7.24.6 dev: true /@babel/plugin-syntax-numeric-separator@7.10.4(@babel/core@7.24.0): @@ -710,7 +599,7 @@ packages: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.24.0 - '@babel/helper-plugin-utils': 7.24.0 + '@babel/helper-plugin-utils': 7.24.6 dev: true /@babel/plugin-syntax-object-rest-spread@7.8.3(@babel/core@7.24.0): @@ -719,7 +608,7 @@ packages: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.24.0 - '@babel/helper-plugin-utils': 7.24.0 + '@babel/helper-plugin-utils': 7.24.6 dev: true /@babel/plugin-syntax-optional-catch-binding@7.8.3(@babel/core@7.24.0): @@ -728,7 +617,7 @@ packages: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.24.0 - '@babel/helper-plugin-utils': 7.24.0 + '@babel/helper-plugin-utils': 7.24.6 dev: true /@babel/plugin-syntax-optional-chaining@7.8.3(@babel/core@7.24.0): @@ -737,7 +626,7 @@ packages: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.24.0 - '@babel/helper-plugin-utils': 7.24.0 + '@babel/helper-plugin-utils': 7.24.6 dev: true /@babel/plugin-syntax-top-level-await@7.14.5(@babel/core@7.24.0): @@ -747,7 +636,7 @@ packages: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.24.0 - '@babel/helper-plugin-utils': 7.24.0 + '@babel/helper-plugin-utils': 7.24.6 dev: true /@babel/plugin-syntax-typescript@7.24.6(@babel/core@7.24.0): @@ -760,26 +649,6 @@ packages: '@babel/helper-plugin-utils': 7.24.6 dev: true - /@babel/plugin-transform-react-jsx-self@7.23.3(@babel/core@7.24.0): - resolution: {integrity: sha512-qXRvbeKDSfwnlJnanVRp0SfuWE5DQhwQr5xtLBzp56Wabyo+4CMosF6Kfp+eOD/4FYpql64XVJ2W0pVLlJZxOQ==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.24.0 - '@babel/helper-plugin-utils': 7.24.0 - dev: true - - /@babel/plugin-transform-react-jsx-source@7.23.3(@babel/core@7.24.0): - resolution: {integrity: sha512-91RS0MDnAWDNvGC6Wio5XYkyWI39FMFO+JK9+4AlgaTH+yWwVTsw7/sn6LK0lH7c5F+TFkpv/3LfCJ1Ydwof/g==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.24.0 - '@babel/helper-plugin-utils': 7.24.0 - dev: true - /@babel/runtime@7.24.1: resolution: {integrity: sha512-+BIznRzyqBf+2wCTxcKE3wDjfGeCoVE61KSHGpkzqrLi8qxqFwBeUFyId2cxkTmm55fzDGnm0+yCxaxygrLUnQ==} engines: {node: '>=6.9.0'} @@ -791,7 +660,7 @@ packages: resolution: {integrity: sha512-Bkf2q8lMB0AFpX0NFEqSbx1OkTHf0f+0j82mkw+ZpzBnkk7e9Ql0891vlfgi+kHwOk8tQjiQHpqh4LaSa0fKEA==} engines: {node: '>=6.9.0'} dependencies: - '@babel/code-frame': 7.23.5 + '@babel/code-frame': 7.24.2 '@babel/parser': 7.24.0 '@babel/types': 7.24.0 dev: true @@ -800,7 +669,7 @@ packages: resolution: {integrity: sha512-HfuJlI8qq3dEDmNU5ChzzpZRWq+oxCZQyMzIMEqLho+AQnhMnKQUzH6ydo3RBl/YjPCuk68Y6s0Gx0AeyULiWw==} engines: {node: '>=6.9.0'} dependencies: - '@babel/code-frame': 7.23.5 + '@babel/code-frame': 7.24.2 '@babel/generator': 7.23.6 '@babel/helper-environment-visitor': 7.22.20 '@babel/helper-function-name': 7.23.0 @@ -2035,91 +1904,6 @@ packages: tslib: 2.6.2 dev: true - /@next/env@14.1.2: - resolution: {integrity: sha512-U0iEG+JF86j6qyu330sfPgsMmDVH8vWVmzZadl+an5EU3o5HqdNytOpM+HsFpl58PmhGBTKx3UmM9c+eoLK0mA==} - dev: false - - /@next/swc-darwin-arm64@14.1.2: - resolution: {integrity: sha512-E4/clgk0ZrYMo9eMRwP/4IO/cvXF1yEYSnGcdGfH+NYTR8bNFy76TSlc1Vb2rK3oaQY4BVHRpx8f/sMN/D5gNw==} - engines: {node: '>= 10'} - cpu: [arm64] - os: [darwin] - requiresBuild: true - dev: false - optional: true - - /@next/swc-darwin-x64@14.1.2: - resolution: {integrity: sha512-j8mEOI+ZM0tU9B/L/OGa6F7d9FXYMkog5OWWuhTWzz3iZ91UKIGGpD/ojTNKuejainDMgbqOBTNnLg0jZywM/g==} - engines: {node: '>= 10'} - cpu: [x64] - os: [darwin] - requiresBuild: true - dev: false - optional: true - - /@next/swc-linux-arm64-gnu@14.1.2: - resolution: {integrity: sha512-qpRrd5hl6BFTWiFLgHtJmqqQGRMs+ol0MN9pEp0SYoLs3j8OTErPiDMhbKWjMWHGdc2E3kg4RRBV3cSTZiePiQ==} - engines: {node: '>= 10'} - cpu: [arm64] - os: [linux] - requiresBuild: true - dev: false - optional: true - - /@next/swc-linux-arm64-musl@14.1.2: - resolution: {integrity: sha512-HAhvVXAv+wnbj0wztT0YnpgJVoHtw1Mv4Y1R/JJcg5yXSU8FsP2uEGUwjQaqPoD76YSZjuKl32YbJlmPgQbLFw==} - engines: {node: '>= 10'} - cpu: [arm64] - os: [linux] - requiresBuild: true - dev: false - optional: true - - /@next/swc-linux-x64-gnu@14.1.2: - resolution: {integrity: sha512-PCWC312woXLWOXiedi1E+fEw6B/ECP1fMiK1nSoGS2E43o56Z8kq4WeJLbJoufFQGVj5ZOKU3jIVyV//3CI4wQ==} - engines: {node: '>= 10'} - cpu: [x64] - os: [linux] - requiresBuild: true - dev: false - optional: true - - /@next/swc-linux-x64-musl@14.1.2: - resolution: {integrity: sha512-KQSKzdWPNrYZjeTPCsepEpagOzU8Nf3Zzu53X1cLsSY6QlOIkYcSgEihRjsMKyeQW4aSvc+nN5pIpC2pLWNSMA==} - engines: {node: '>= 10'} - cpu: [x64] - os: [linux] - requiresBuild: true - dev: false - optional: true - - /@next/swc-win32-arm64-msvc@14.1.2: - resolution: {integrity: sha512-3b0PouKd09Ulm2T1tjaRnwQj9+UwSsMO680d/sD4XAlm29KkNmVLAEIwWTfb3L+E11Qyw+jdcN3HtbDCg5+vYA==} - engines: {node: '>= 10'} - cpu: [arm64] - os: [win32] - requiresBuild: true - dev: false - optional: true - - /@next/swc-win32-ia32-msvc@14.1.2: - resolution: {integrity: sha512-CC1gaJY4h+wg6d5r2biggGM6nCFXh/6WEim2VOQI0WrA6easCQi2P2hzWyrU6moQ0g1GOiWzesGc6nn0a92Kgg==} - engines: {node: '>= 10'} - cpu: [ia32] - os: [win32] - requiresBuild: true - dev: false - optional: true - - /@next/swc-win32-x64-msvc@14.1.2: - resolution: {integrity: sha512-pfASwanOd+yP3D80O63DuQffrBySZPuB7wRN0IGSRq/0rDm9p/MvvnLzzgP2kSiLOUklOrFYVax7P6AEzjGykQ==} - engines: {node: '>= 10'} - cpu: [x64] - os: [win32] - requiresBuild: true - dev: false - optional: true - /@noble/hashes@1.4.0: resolution: {integrity: sha512-V1JJ1WTRUqHHrOSh597hURcMqVKVGL/ea3kv0gSnEdsEZ0/+VyPghM1lMNGc00z7CIQorSvbKpuJkxvuHbvdbg==} engines: {node: '>= 16'} @@ -2168,34 +1952,6 @@ packages: dev: true optional: true - /@rollup/plugin-inject@5.0.5: - resolution: {integrity: sha512-2+DEJbNBoPROPkgTDNe8/1YXWcqxbN5DTjASVIOx8HS+pITXushyNiBV56RB08zuptzz8gT3YfkqriTBVycepg==} - engines: {node: '>=14.0.0'} - peerDependencies: - rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0 - peerDependenciesMeta: - rollup: - optional: true - dependencies: - '@rollup/pluginutils': 5.1.0 - estree-walker: 2.0.2 - magic-string: 0.30.8 - dev: true - - /@rollup/pluginutils@5.1.0: - resolution: {integrity: sha512-XTIWOPPcpvyKI6L1NHo0lFlCyznUEyPmPY1mc3KpPVDYulHSTvyeLNVW00QTLIAFNhR3kYnJTQHeGqU4M3n09g==} - engines: {node: '>=14.0.0'} - peerDependencies: - rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0 - peerDependenciesMeta: - rollup: - optional: true - dependencies: - '@types/estree': 1.0.5 - estree-walker: 2.0.2 - picomatch: 2.3.1 - dev: true - /@rollup/rollup-android-arm-eabi@4.13.2: resolution: {integrity: sha512-3XFIDKWMFZrMnao1mJhnOT1h2g0169Os848NhhmGweEcfJ4rCi+3yMCOLG4zA61rbJdkcrM/DjVZm9Hg5p5w7g==} cpu: [arm] @@ -2346,12 +2102,6 @@ packages: lodash: 4.17.21 dev: false - /@swc/helpers@0.5.2: - resolution: {integrity: sha512-E4KcWTpoLHqwPHLxidpOqQbcrZVgi0rsmmZXUle1jXmJfuIf/UWpczUJ7MZZ5tlxytgJXyp0w4PGkkeLiuIdZw==} - dependencies: - tslib: 2.6.2 - dev: false - /@tsconfig/node10@1.0.11: resolution: {integrity: sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==} dev: true @@ -2568,10 +2318,6 @@ packages: resolution: {integrity: sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA==} dev: true - /@types/prop-types@15.7.11: - resolution: {integrity: sha512-ga8y9v9uyeiLdpKddhxYQkxNDrfvuPrlFb0N1qnZZByvcElJaXthF1UhvCh9TLWJBEHeNtdnbysW7Y6Uq8CVng==} - dev: true - /@types/qs@6.9.15: resolution: {integrity: sha512-uXHQKES6DQKKCLh441Xv/dwxOq1TVS3JPUMlEqoEglvlhR6Mxnlew/Xq/LRVHpLyk7iK3zODe1qYHIMltO7XGg==} dev: true @@ -2580,24 +2326,6 @@ packages: resolution: {integrity: sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==} dev: true - /@types/react-dom@18.2.19: - resolution: {integrity: sha512-aZvQL6uUbIJpjZk4U8JZGbau9KDeAwMfmhyWorxgBkqDIEf6ROjRozcmPIicqsUwPUjbkDfHKgGee1Lq65APcA==} - dependencies: - '@types/react': 18.2.56 - dev: true - - /@types/react@18.2.56: - resolution: {integrity: sha512-NpwHDMkS/EFZF2dONFQHgkPRwhvgq/OAvIaGQzxGSBmaeR++kTg6njr15Vatz0/2VcCEwJQFi6Jf4Q0qBu0rLA==} - dependencies: - '@types/prop-types': 15.7.11 - '@types/scheduler': 0.16.8 - csstype: 3.1.3 - dev: true - - /@types/scheduler@0.16.8: - resolution: {integrity: sha512-WZLiwShhwLRmeV6zH+GkbOFT6Z6VklCItrDioxUnv+u4Ll+8vKeFySoFyK/0ctcRpOmwAicELfmys1sDc/Rw+A==} - dev: true - /@types/semver@7.5.8: resolution: {integrity: sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ==} dev: true @@ -2646,35 +2374,6 @@ packages: '@types/yargs-parser': 21.0.3 dev: true - /@typescript-eslint/eslint-plugin@7.0.2(@typescript-eslint/parser@7.0.2)(eslint@8.56.0)(typescript@5.4.2): - resolution: {integrity: sha512-/XtVZJtbaphtdrWjr+CJclaCVGPtOdBpFEnvtNf/jRV0IiEemRrL0qABex/nEt8isYcnFacm3nPHYQwL+Wb7qg==} - engines: {node: ^16.0.0 || >=18.0.0} - peerDependencies: - '@typescript-eslint/parser': ^7.0.0 - eslint: ^8.56.0 - typescript: '*' - peerDependenciesMeta: - typescript: - optional: true - dependencies: - '@eslint-community/regexpp': 4.10.0 - '@typescript-eslint/parser': 7.0.2(eslint@8.56.0)(typescript@5.4.2) - '@typescript-eslint/scope-manager': 7.0.2 - '@typescript-eslint/type-utils': 7.0.2(eslint@8.56.0)(typescript@5.4.2) - '@typescript-eslint/utils': 7.0.2(eslint@8.56.0)(typescript@5.4.2) - '@typescript-eslint/visitor-keys': 7.0.2 - debug: 4.3.4 - eslint: 8.56.0 - graphemer: 1.4.0 - ignore: 5.3.1 - natural-compare: 1.4.0 - semver: 7.6.0 - ts-api-utils: 1.3.0(typescript@5.4.2) - typescript: 5.4.2 - transitivePeerDependencies: - - supports-color - dev: true - /@typescript-eslint/eslint-plugin@7.8.0(@typescript-eslint/parser@7.8.0)(eslint@8.56.0)(typescript@5.4.3): resolution: {integrity: sha512-gFTT+ezJmkwutUPmB0skOj3GZJtlEGnlssems4AjkVweUPGj7jRwwqg0Hhg7++kPGJqKtTYx+R05Ftww372aIg==} engines: {node: ^18.18.0 || >=20.0.0} @@ -2704,27 +2403,6 @@ packages: - supports-color dev: true - /@typescript-eslint/parser@7.0.2(eslint@8.56.0)(typescript@5.4.2): - resolution: {integrity: sha512-GdwfDglCxSmU+QTS9vhz2Sop46ebNCXpPPvsByK7hu0rFGRHL+AusKQJ7SoN+LbLh6APFpQwHKmDSwN35Z700Q==} - engines: {node: ^16.0.0 || >=18.0.0} - peerDependencies: - eslint: ^8.56.0 - typescript: '*' - peerDependenciesMeta: - typescript: - optional: true - dependencies: - '@typescript-eslint/scope-manager': 7.0.2 - '@typescript-eslint/types': 7.0.2 - '@typescript-eslint/typescript-estree': 7.0.2(typescript@5.4.2) - '@typescript-eslint/visitor-keys': 7.0.2 - debug: 4.3.4 - eslint: 8.56.0 - typescript: 5.4.2 - transitivePeerDependencies: - - supports-color - dev: true - /@typescript-eslint/parser@7.8.0(eslint@8.56.0)(typescript@5.4.3): resolution: {integrity: sha512-KgKQly1pv0l4ltcftP59uQZCi4HUYswCLbTqVZEJu7uLX8CTLyswqMLqLN+2QFz4jCptqWVV4SB7vdxcH2+0kQ==} engines: {node: ^18.18.0 || >=20.0.0} @@ -2746,14 +2424,6 @@ packages: - supports-color dev: true - /@typescript-eslint/scope-manager@7.0.2: - resolution: {integrity: sha512-l6sa2jF3h+qgN2qUMjVR3uCNGjWw4ahGfzIYsCtFrQJCjhbrDPdiihYT8FnnqFwsWX+20hK592yX9I2rxKTP4g==} - engines: {node: ^16.0.0 || >=18.0.0} - dependencies: - '@typescript-eslint/types': 7.0.2 - '@typescript-eslint/visitor-keys': 7.0.2 - dev: true - /@typescript-eslint/scope-manager@7.8.0: resolution: {integrity: sha512-viEmZ1LmwsGcnr85gIq+FCYI7nO90DVbE37/ll51hjv9aG+YZMb4WDE2fyWpUR4O/UrhGRpYXK/XajcGTk2B8g==} engines: {node: ^18.18.0 || >=20.0.0} @@ -2762,26 +2432,6 @@ packages: '@typescript-eslint/visitor-keys': 7.8.0 dev: true - /@typescript-eslint/type-utils@7.0.2(eslint@8.56.0)(typescript@5.4.2): - resolution: {integrity: sha512-IKKDcFsKAYlk8Rs4wiFfEwJTQlHcdn8CLwLaxwd6zb8HNiMcQIFX9sWax2k4Cjj7l7mGS5N1zl7RCHOVwHq2VQ==} - engines: {node: ^16.0.0 || >=18.0.0} - peerDependencies: - eslint: ^8.56.0 - typescript: '*' - peerDependenciesMeta: - typescript: - optional: true - dependencies: - '@typescript-eslint/typescript-estree': 7.0.2(typescript@5.4.2) - '@typescript-eslint/utils': 7.0.2(eslint@8.56.0)(typescript@5.4.2) - debug: 4.3.4 - eslint: 8.56.0 - ts-api-utils: 1.3.0(typescript@5.4.2) - typescript: 5.4.2 - transitivePeerDependencies: - - supports-color - dev: true - /@typescript-eslint/type-utils@7.8.0(eslint@8.56.0)(typescript@5.4.3): resolution: {integrity: sha512-H70R3AefQDQpz9mGv13Uhi121FNMh+WEaRqcXTX09YEDky21km4dV1ZXJIp8QjXc4ZaVkXVdohvWDzbnbHDS+A==} engines: {node: ^18.18.0 || >=20.0.0} @@ -2802,38 +2452,11 @@ packages: - supports-color dev: true - /@typescript-eslint/types@7.0.2: - resolution: {integrity: sha512-ZzcCQHj4JaXFjdOql6adYV4B/oFOFjPOC9XYwCaZFRvqN8Llfvv4gSxrkQkd2u4Ci62i2c6W6gkDwQJDaRc4nA==} - engines: {node: ^16.0.0 || >=18.0.0} - dev: true - /@typescript-eslint/types@7.8.0: resolution: {integrity: sha512-wf0peJ+ZGlcH+2ZS23aJbOv+ztjeeP8uQ9GgwMJGVLx/Nj9CJt17GWgWWoSmoRVKAX2X+7fzEnAjxdvK2gqCLw==} engines: {node: ^18.18.0 || >=20.0.0} dev: true - /@typescript-eslint/typescript-estree@7.0.2(typescript@5.4.2): - resolution: {integrity: sha512-3AMc8khTcELFWcKcPc0xiLviEvvfzATpdPj/DXuOGIdQIIFybf4DMT1vKRbuAEOFMwhWt7NFLXRkbjsvKZQyvw==} - engines: {node: ^16.0.0 || >=18.0.0} - peerDependencies: - typescript: '*' - peerDependenciesMeta: - typescript: - optional: true - dependencies: - '@typescript-eslint/types': 7.0.2 - '@typescript-eslint/visitor-keys': 7.0.2 - debug: 4.3.4 - globby: 11.1.0 - is-glob: 4.0.3 - minimatch: 9.0.3 - semver: 7.6.0 - ts-api-utils: 1.3.0(typescript@5.4.2) - typescript: 5.4.2 - transitivePeerDependencies: - - supports-color - dev: true - /@typescript-eslint/typescript-estree@7.8.0(typescript@5.4.3): resolution: {integrity: sha512-5pfUCOwK5yjPaJQNy44prjCwtr981dO8Qo9J9PwYXZ0MosgAbfEMB008dJ5sNo3+/BN6ytBPuSvXUg9SAqB0dg==} engines: {node: ^18.18.0 || >=20.0.0} @@ -2856,25 +2479,6 @@ packages: - supports-color dev: true - /@typescript-eslint/utils@7.0.2(eslint@8.56.0)(typescript@5.4.2): - resolution: {integrity: sha512-PZPIONBIB/X684bhT1XlrkjNZJIEevwkKDsdwfiu1WeqBxYEEdIgVDgm8/bbKHVu+6YOpeRqcfImTdImx/4Bsw==} - engines: {node: ^16.0.0 || >=18.0.0} - peerDependencies: - eslint: ^8.56.0 - dependencies: - '@eslint-community/eslint-utils': 4.4.0(eslint@8.56.0) - '@types/json-schema': 7.0.15 - '@types/semver': 7.5.8 - '@typescript-eslint/scope-manager': 7.0.2 - '@typescript-eslint/types': 7.0.2 - '@typescript-eslint/typescript-estree': 7.0.2(typescript@5.4.2) - eslint: 8.56.0 - semver: 7.6.0 - transitivePeerDependencies: - - supports-color - - typescript - dev: true - /@typescript-eslint/utils@7.8.0(eslint@8.56.0)(typescript@5.4.3): resolution: {integrity: sha512-L0yFqOCflVqXxiZyXrDr80lnahQfSOfc9ELAAZ75sqicqp2i36kEZZGuUymHNFoYOqxRT05up760b4iGsl02nQ==} engines: {node: ^18.18.0 || >=20.0.0} @@ -2894,14 +2498,6 @@ packages: - typescript dev: true - /@typescript-eslint/visitor-keys@7.0.2: - resolution: {integrity: sha512-8Y+YiBmqPighbm5xA2k4wKTxRzx9EkBu7Rlw+WHqMvRJ3RPz/BMBO9b2ru0LUNmXg120PHUXD5+SWFy2R8DqlQ==} - engines: {node: ^16.0.0 || >=18.0.0} - dependencies: - '@typescript-eslint/types': 7.0.2 - eslint-visitor-keys: 3.4.3 - dev: true - /@typescript-eslint/visitor-keys@7.8.0: resolution: {integrity: sha512-q4/gibTNBQNA0lGyYQCmWRS5D15n8rXh4QjK3KV+MBPlTYHpfBUT3D3PaPR/HeNiI9W6R7FvlkcGhNyAoP+caA==} engines: {node: ^18.18.0 || >=20.0.0} @@ -2914,22 +2510,6 @@ packages: resolution: {integrity: sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==} dev: true - /@vitejs/plugin-react@4.2.1(vite@5.2.11): - resolution: {integrity: sha512-oojO9IDc4nCUUi8qIR11KoQm0XFFLIwsRBwHRR4d/88IWghn1y6ckz/bJ8GHDCsYEJee8mDzqtJxh15/cisJNQ==} - engines: {node: ^14.18.0 || >=16.0.0} - peerDependencies: - vite: ^4.2.0 || ^5.0.0 - dependencies: - '@babel/core': 7.24.0 - '@babel/plugin-transform-react-jsx-self': 7.23.3(@babel/core@7.24.0) - '@babel/plugin-transform-react-jsx-source': 7.23.3(@babel/core@7.24.0) - '@types/babel__core': 7.20.5 - react-refresh: 0.14.0 - vite: 5.2.11(@types/node@20.12.12) - transitivePeerDependencies: - - supports-color - dev: true - /@vitest/expect@1.4.0: resolution: {integrity: sha512-Jths0sWCJZ8BxjKe+p+eKsoqev1/T8lYcrjavEaz8auEJ4jAVY0GwW3JKmdVU4mmNPLPHixh4GNXP7GFtAiDHA==} dependencies: @@ -3289,24 +2869,6 @@ packages: resolution: {integrity: sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==} dev: true - /asn1.js@4.10.1: - resolution: {integrity: sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw==} - dependencies: - bn.js: 4.12.0 - inherits: 2.0.4 - minimalistic-assert: 1.0.1 - dev: true - - /assert@2.1.0: - resolution: {integrity: sha512-eLHpSK/Y4nhMJ07gDaAzoX/XAKS8PSaojml3M0DM4JpV1LAi5JOJ/p6H/XWrl8L+DzVEvVCW1z3vWAaB9oTsQw==} - dependencies: - call-bind: 1.0.7 - is-nan: 1.3.2 - object-is: 1.1.6 - object.assign: 4.1.5 - util: 0.12.5 - dev: true - /assertion-error@1.1.0: resolution: {integrity: sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==} dev: true @@ -3367,7 +2929,7 @@ packages: resolution: {integrity: sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==} engines: {node: '>=8'} dependencies: - '@babel/helper-plugin-utils': 7.24.0 + '@babel/helper-plugin-utils': 7.24.6 '@istanbuljs/load-nyc-config': 1.1.0 '@istanbuljs/schema': 0.1.3 istanbul-lib-instrument: 5.2.1 @@ -3501,9 +3063,11 @@ packages: /bn.js@4.12.0: resolution: {integrity: sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==} + dev: false /bn.js@5.2.1: resolution: {integrity: sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==} + dev: false /body-parser@1.20.2: resolution: {integrity: sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA==} @@ -3552,69 +3116,7 @@ packages: /brorand@1.1.0: resolution: {integrity: sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w==} - - /browser-resolve@2.0.0: - resolution: {integrity: sha512-7sWsQlYL2rGLy2IWm8WL8DCTJvYLc/qlOnsakDac87SOoCd16WLsaAMdCiAqsTNHIe+SXfaqyxyo6THoWqs8WQ==} - dependencies: - resolve: 1.22.8 - dev: true - - /browserify-aes@1.2.0: - resolution: {integrity: sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==} - dependencies: - buffer-xor: 1.0.3 - cipher-base: 1.0.4 - create-hash: 1.2.0 - evp_bytestokey: 1.0.3 - inherits: 2.0.4 - safe-buffer: 5.2.1 - dev: true - - /browserify-cipher@1.0.1: - resolution: {integrity: sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==} - dependencies: - browserify-aes: 1.2.0 - browserify-des: 1.0.2 - evp_bytestokey: 1.0.3 - dev: true - - /browserify-des@1.0.2: - resolution: {integrity: sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==} - dependencies: - cipher-base: 1.0.4 - des.js: 1.1.0 - inherits: 2.0.4 - safe-buffer: 5.2.1 - dev: true - - /browserify-rsa@4.1.0: - resolution: {integrity: sha512-AdEER0Hkspgno2aR97SAf6vi0y0k8NuOpGnVH3O99rcA5Q6sh8QxcngtHuJ6uXwnfAXNM4Gn1Gb7/MV1+Ymbog==} - dependencies: - bn.js: 5.2.1 - randombytes: 2.1.0 - dev: true - - /browserify-sign@4.2.3: - resolution: {integrity: sha512-JWCZW6SKhfhjJxO8Tyiiy+XYB7cqd2S5/+WeYHsKdNKFlCBhKbblba1A/HN/90YwtxKc8tCErjffZl++UNmGiw==} - engines: {node: '>= 0.12'} - dependencies: - bn.js: 5.2.1 - browserify-rsa: 4.1.0 - create-hash: 1.2.0 - create-hmac: 1.1.7 - elliptic: 6.5.5 - hash-base: 3.0.4 - inherits: 2.0.4 - parse-asn1: 5.1.7 - readable-stream: 2.3.8 - safe-buffer: 5.2.1 - dev: true - - /browserify-zlib@0.2.0: - resolution: {integrity: sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==} - dependencies: - pako: 1.0.11 - dev: true + dev: false /browserslist@4.23.0: resolution: {integrity: sha512-QW8HiM1shhT2GuzkvklfjcKDiWFXHOeFCIA/huJPwHsslwcydgk7X+z2zXpEijP98UCY7HbubZt5J2Zgvf0CaQ==} @@ -3670,10 +3172,6 @@ packages: /buffer-from@1.1.2: resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} - /buffer-xor@1.0.3: - resolution: {integrity: sha512-571s0T7nZWK6vB67HI5dyUF7wXiNcfaPPPTl6zYCNApANjIvYJTg7hlud/+cJpdAhS7dVzqMLmfhfHR3rAcOjQ==} - dev: true - /buffer@5.7.1: resolution: {integrity: sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==} dependencies: @@ -3688,10 +3186,6 @@ packages: ieee754: 1.2.1 dev: false - /builtin-status-codes@3.0.0: - resolution: {integrity: sha512-HpGFw18DgFWlncDfjTa2rcQ4W88O1mC8e8yZ2AvQY5KDaktSTwo+KRf6nHK6FRI5FyRyb/5T6+TSxfP7QyGsmQ==} - dev: true - /busboy@1.6.0: resolution: {integrity: sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==} engines: {node: '>=10.16.0'} @@ -3752,6 +3246,7 @@ packages: /caniuse-lite@1.0.30001599: resolution: {integrity: sha512-LRAQHZ4yT1+f9LemSMeqdMpMxZcc4RMWdj4tiFe3G8tNkWK+E58g+/tzotb5cU6TbcVJLr4fySiAW7XmxQvZQA==} + dev: true /chai@4.4.1: resolution: {integrity: sha512-13sOfMv2+DWduEU+/xbun3LScLoqN17nBeTLUsmDfKdoiC1fr0n9PU4guu4AhRcOVFk/sW8LyZWHuhWtQZiF+g==} @@ -3832,6 +3327,7 @@ packages: dependencies: inherits: 2.0.4 safe-buffer: 5.2.1 + dev: false /cjs-module-lexer@1.3.1: resolution: {integrity: sha512-a3KdPAANPbNE4ZUv9h6LckSl9zLsYOP4MBmhIPkRaeyybt+r4UghLvq+xw/YwUcC1gqylCkL4rdVs3Lwupjm4Q==} @@ -3883,10 +3379,6 @@ packages: engines: {node: '>= 12'} dev: true - /client-only@0.0.1: - resolution: {integrity: sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==} - dev: false - /cliui@6.0.0: resolution: {integrity: sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==} dependencies: @@ -3992,14 +3484,6 @@ packages: /consola@2.15.3: resolution: {integrity: sha512-9vAdYbHj6x2fLKC4+oPH0kFzY/orMZyG2Aj+kNylHxKGJ/Ed4dpNyAQYwJOdqO4zdM7XpVHmyejQDcQHrnuXbw==} - /console-browserify@1.2.0: - resolution: {integrity: sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA==} - dev: true - - /constants-browserify@1.0.0: - resolution: {integrity: sha512-xFxOwqIzR/e1k1gLiWEophSCMqXcwVHIH7akf7b/vxcUeGunlj3hvZaaqxwHsTgn+IndtkQJgSztIDWeumWJDQ==} - dev: true - /content-disposition@0.5.4: resolution: {integrity: sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==} engines: {node: '>= 0.6'} @@ -4047,15 +3531,8 @@ packages: import-fresh: 3.3.0 js-yaml: 4.1.0 parse-json: 5.2.0 - path-type: 4.0.0 - typescript: 5.3.3 - dev: true - - /create-ecdh@4.0.4: - resolution: {integrity: sha512-mf+TCx8wWc9VpuxfP2ht0iSISLZnt0JgWlrOKZiNqyUZWnjIaCIVNQArMHnCZKfEYRg6IM7A+NeJoN8gf/Ws0A==} - dependencies: - bn.js: 4.12.0 - elliptic: 6.5.5 + path-type: 4.0.0 + typescript: 5.3.3 dev: true /create-hash@1.2.0: @@ -4066,17 +3543,7 @@ packages: md5.js: 1.3.5 ripemd160: 2.0.2 sha.js: 2.4.11 - - /create-hmac@1.1.7: - resolution: {integrity: sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==} - dependencies: - cipher-base: 1.0.4 - create-hash: 1.2.0 - inherits: 2.0.4 - ripemd160: 2.0.2 - safe-buffer: 5.2.1 - sha.js: 2.4.11 - dev: true + dev: false /create-jest@29.7.0(@types/node@20.12.12)(ts-node@10.9.2): resolution: {integrity: sha512-Adz2bdH0Vq3F53KEMJOoftQFutWCukm6J24wbPWRO4k1kMY7gS7ds/uoJkNuV8wDCtWWnuwGcJwpWcih+zEW1Q==} @@ -4126,26 +3593,6 @@ packages: which: 2.0.2 dev: true - /crypto-browserify@3.12.0: - resolution: {integrity: sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==} - dependencies: - browserify-cipher: 1.0.1 - browserify-sign: 4.2.3 - create-ecdh: 4.0.4 - create-hash: 1.2.0 - create-hmac: 1.1.7 - diffie-hellman: 5.0.3 - inherits: 2.0.4 - pbkdf2: 3.1.2 - public-encrypt: 4.0.3 - randombytes: 2.1.0 - randomfill: 1.0.4 - dev: true - - /csstype@3.1.3: - resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==} - dev: true - /csv-generate@3.4.3: resolution: {integrity: sha512-w/T+rqR0vwvHqWs/1ZyMDWtHHSJaN06klRqJXBEpDJaM/+dZkso0OKh1VcuuYvK3XM53KysVNq8Ko/epCK8wOw==} dev: true @@ -4294,13 +3741,6 @@ packages: resolution: {integrity: sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==} engines: {node: '>= 0.8'} - /des.js@1.1.0: - resolution: {integrity: sha512-r17GxjhUCjSRy8aiJpr8/UadFIzMzJGexI3Nmz4ADi9LYSFx4gTBp80+NaX/YsXWWLhpZ7v/v/ubEc/bCNfKwg==} - dependencies: - inherits: 2.0.4 - minimalistic-assert: 1.0.1 - dev: true - /destroy@1.2.0: resolution: {integrity: sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==} engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16} @@ -4332,14 +3772,6 @@ packages: engines: {node: '>=0.3.1'} dev: true - /diffie-hellman@5.0.3: - resolution: {integrity: sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==} - dependencies: - bn.js: 4.12.0 - miller-rabin: 4.0.1 - randombytes: 2.1.0 - dev: true - /dir-glob@3.0.1: resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==} engines: {node: '>=8'} @@ -4358,11 +3790,6 @@ packages: esutils: 2.0.3 dev: true - /domain-browser@4.23.0: - resolution: {integrity: sha512-ArzcM/II1wCCujdCNyQjXrAFwS4mrLh4C7DZWlaI8mdh7h3BfKdNd3bKXITfl2PT9FtfQqaGvhi1vPRQPimjGA==} - engines: {node: '>=10'} - dev: true - /dotenv@16.4.5: resolution: {integrity: sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg==} engines: {node: '>=12'} @@ -4410,6 +3837,7 @@ packages: inherits: 2.0.4 minimalistic-assert: 1.0.1 minimalistic-crypto-utils: 1.0.1 + dev: false /emittery@0.13.1: resolution: {integrity: sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ==} @@ -4610,23 +4038,6 @@ packages: engines: {node: '>=12'} dev: true - /eslint-plugin-react-hooks@4.6.0(eslint@8.56.0): - resolution: {integrity: sha512-oFc7Itz9Qxh2x4gNHStv3BqJq54ExXmfC+a1NjAta66IAN87Wu0R/QArgIS9qKzX3dXKPI9H5crl9QchNMY9+g==} - engines: {node: '>=10'} - peerDependencies: - eslint: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 - dependencies: - eslint: 8.56.0 - dev: true - - /eslint-plugin-react-refresh@0.4.5(eslint@8.56.0): - resolution: {integrity: sha512-D53FYKJa+fDmZMtriODxvhwrO+IOqrxoEo21gMA0sjHdU6dPVH4OhyFip9ypl8HOF5RV5KdTo+rBQLvnY2cO8w==} - peerDependencies: - eslint: '>=7' - dependencies: - eslint: 8.56.0 - dev: true - /eslint-scope@5.1.1: resolution: {integrity: sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==} engines: {node: '>=8.0.0'} @@ -4734,10 +4145,6 @@ packages: engines: {node: '>=4.0'} dev: true - /estree-walker@2.0.2: - resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==} - dev: true - /estree-walker@3.0.3: resolution: {integrity: sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==} dependencies: @@ -4766,13 +4173,6 @@ packages: resolution: {integrity: sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==} engines: {node: '>=0.8.x'} - /evp_bytestokey@1.0.3: - resolution: {integrity: sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==} - dependencies: - md5.js: 1.3.5 - safe-buffer: 5.2.1 - dev: true - /execa@5.1.1: resolution: {integrity: sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==} engines: {node: '>=10'} @@ -5274,6 +4674,7 @@ packages: /graceful-fs@4.2.11: resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} + dev: true /grapheme-splitter@1.0.4: resolution: {integrity: sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==} @@ -5326,14 +4727,6 @@ packages: has-symbols: 1.0.3 dev: true - /hash-base@3.0.4: - resolution: {integrity: sha512-EeeoJKjTyt868liAlVmcv2ZsUfGHlE3Q+BICOXcZiwN3osr5Q/zFGYmTJpoIzuaSTAwndFy+GqhEwlU4L3j4Ow==} - engines: {node: '>=4'} - dependencies: - inherits: 2.0.4 - safe-buffer: 5.2.1 - dev: true - /hash-base@3.1.0: resolution: {integrity: sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==} engines: {node: '>=4'} @@ -5341,12 +4734,14 @@ packages: inherits: 2.0.4 readable-stream: 3.6.2 safe-buffer: 5.2.1 + dev: false /hash.js@1.1.7: resolution: {integrity: sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==} dependencies: inherits: 2.0.4 minimalistic-assert: 1.0.1 + dev: false /hasown@2.0.2: resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} @@ -5365,6 +4760,7 @@ packages: hash.js: 1.1.7 minimalistic-assert: 1.0.1 minimalistic-crypto-utils: 1.0.1 + dev: false /hosted-git-info@2.8.9: resolution: {integrity: sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==} @@ -5384,10 +4780,6 @@ packages: statuses: 2.0.1 toidentifier: 1.0.1 - /https-browserify@1.0.0: - resolution: {integrity: sha512-J+FkSdyD+0mA0N+81tMotaRMfSL9SGi+xpD3T6YApKsc3bGSXJlfXri3VyFOeYkfLRQisDk1W+jIFFKBeUBbBg==} - dev: true - /human-id@1.0.2: resolution: {integrity: sha512-UNopramDEhHJD+VR+ehk8rOslwSfByxPIZyJRfV739NDhN5LF1fa1MqnzKm2lGTQRjNrjK19Q5fhkgIfjlVUKw==} dev: true @@ -5523,14 +4915,6 @@ packages: resolution: {integrity: sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==} engines: {node: '>= 0.10'} - /is-arguments@1.1.1: - resolution: {integrity: sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==} - engines: {node: '>= 0.4'} - dependencies: - call-bind: 1.0.7 - has-tostringtag: 1.0.2 - dev: true - /is-array-buffer@3.0.4: resolution: {integrity: sha512-wcjaerHw0ydZwfhiKbXJWLDY8A7yV7KhjQOpb83hGgGfId/aQa4TOvwyzn2PuswW2gPCYEL/nEAiSVpdOj1lXw==} engines: {node: '>= 0.4'} @@ -5616,13 +5000,6 @@ packages: engines: {node: '>=6'} dev: true - /is-generator-function@1.0.10: - resolution: {integrity: sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==} - engines: {node: '>= 0.4'} - dependencies: - has-tostringtag: 1.0.2 - dev: true - /is-glob@4.0.3: resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} engines: {node: '>=0.10.0'} @@ -5635,14 +5012,6 @@ packages: engines: {node: '>=8'} dev: true - /is-nan@1.3.2: - resolution: {integrity: sha512-E+zBKpQ2t6MEo1VsonYmluk9NxGrbzpeeLC2xIViuO2EjU2xsXsBPwTr3Ykv9l08UYEVEdWeRZNouaZqF6RN0w==} - engines: {node: '>= 0.4'} - dependencies: - call-bind: 1.0.7 - define-properties: 1.2.1 - dev: true - /is-negative-zero@2.0.3: resolution: {integrity: sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==} engines: {node: '>= 0.4'} @@ -5762,11 +5131,6 @@ packages: isarray: 1.0.0 dev: true - /isomorphic-timers-promises@1.0.1: - resolution: {integrity: sha512-u4sej9B1LPSxTGKB/HiuzvEQnXH0ECYkSVQU39koSwmFAxhlEAFl9RdTvLv4TOTQUgBS5O3O5fwUxk6byBZ+IQ==} - engines: {node: '>=10'} - dev: true - /istanbul-lib-coverage@3.2.2: resolution: {integrity: sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==} engines: {node: '>=8'} @@ -6265,6 +5629,7 @@ packages: /js-tokens@4.0.0: resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} + dev: true /js-tokens@9.0.0: resolution: {integrity: sha512-WriZw1luRMlmV3LGJaR6QOJjWwgLUTf89OwT2lUOyjX2dJGBwgmIkbcz+7WFZjrZM635JOIR517++e/67CP9dQ==} @@ -6504,13 +5869,6 @@ packages: wrap-ansi: 9.0.0 dev: true - /loose-envify@1.4.0: - resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==} - hasBin: true - dependencies: - js-tokens: 4.0.0 - dev: false - /loupe@2.3.7: resolution: {integrity: sha512-zSMINGVYkdpYSOBmLi0D1Uo7JU9nVdQKrHxC8eYlV+9YKK9WePqAlL7lSlorG/U2Fw1w0hTBmaa/jrQ3UbPHtA==} dependencies: @@ -6588,6 +5946,7 @@ packages: hash-base: 3.1.0 inherits: 2.0.4 safe-buffer: 5.2.1 + dev: false /media-typer@0.3.0: resolution: {integrity: sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==} @@ -6641,14 +6000,6 @@ packages: picomatch: 2.3.1 dev: true - /miller-rabin@4.0.1: - resolution: {integrity: sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==} - hasBin: true - dependencies: - bn.js: 4.12.0 - brorand: 1.1.0 - dev: true - /mime-db@1.52.0: resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} engines: {node: '>= 0.6'} @@ -6687,9 +6038,11 @@ packages: /minimalistic-assert@1.0.1: resolution: {integrity: sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==} + dev: false /minimalistic-crypto-utils@1.0.1: resolution: {integrity: sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg==} + dev: false /minimatch@3.1.2: resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} @@ -6704,13 +6057,6 @@ packages: brace-expansion: 2.0.1 dev: true - /minimatch@9.0.3: - resolution: {integrity: sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==} - engines: {node: '>=16 || 14 >=14.17'} - dependencies: - brace-expansion: 2.0.1 - dev: true - /minimatch@9.0.4: resolution: {integrity: sha512-KqWh+VchfxcMNRAJjj2tnsSJdNbHsVgnkBhTNrW7AjVo6OvLtxw8zfT9oLw1JSohlFzJ8jCoTgaoXvJ+kHt6fw==} engines: {node: '>=16 || 14 >=14.17'} @@ -6803,6 +6149,7 @@ packages: resolution: {integrity: sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==} engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} hasBin: true + dev: true /natural-compare@1.4.0: resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} @@ -6826,45 +6173,6 @@ packages: resolution: {integrity: sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==} dev: true - /next@14.1.2(react-dom@18.2.0)(react@18.2.0): - resolution: {integrity: sha512-p4RfNmopqkzRP1uUyBJnHii+qMg71f2udWhTTZopBB8b3T5QXNzn7yO+LCYHPWZG2kAvEn4l4neyJHqkXvo2wg==} - engines: {node: '>=18.17.0'} - hasBin: true - peerDependencies: - '@opentelemetry/api': ^1.1.0 - react: ^18.2.0 - react-dom: ^18.2.0 - sass: ^1.3.0 - peerDependenciesMeta: - '@opentelemetry/api': - optional: true - sass: - optional: true - dependencies: - '@next/env': 14.1.2 - '@swc/helpers': 0.5.2 - busboy: 1.6.0 - caniuse-lite: 1.0.30001599 - graceful-fs: 4.2.11 - postcss: 8.4.31 - react: 18.2.0 - react-dom: 18.2.0(react@18.2.0) - styled-jsx: 5.1.1(react@18.2.0) - optionalDependencies: - '@next/swc-darwin-arm64': 14.1.2 - '@next/swc-darwin-x64': 14.1.2 - '@next/swc-linux-arm64-gnu': 14.1.2 - '@next/swc-linux-arm64-musl': 14.1.2 - '@next/swc-linux-x64-gnu': 14.1.2 - '@next/swc-linux-x64-musl': 14.1.2 - '@next/swc-win32-arm64-msvc': 14.1.2 - '@next/swc-win32-ia32-msvc': 14.1.2 - '@next/swc-win32-x64-msvc': 14.1.2 - transitivePeerDependencies: - - '@babel/core' - - babel-plugin-macros - dev: false - /node-abort-controller@3.1.1: resolution: {integrity: sha512-AGK2yQKIjRuqnc6VkX2Xj5d+QW8xZ87pa1UK6yA6ouUyuxfHuMP6umE5QK7UmTeOAymo+Zx1Fxiuw9rVx8taHQ==} dev: true @@ -6894,39 +6202,6 @@ packages: resolution: {integrity: sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==} dev: true - /node-stdlib-browser@1.2.0: - resolution: {integrity: sha512-VSjFxUhRhkyed8AtLwSCkMrJRfQ3e2lGtG3sP6FEgaLKBBbxM/dLfjRe1+iLhjvyLFW3tBQ8+c0pcOtXGbAZJg==} - engines: {node: '>=10'} - dependencies: - assert: 2.1.0 - browser-resolve: 2.0.0 - browserify-zlib: 0.2.0 - buffer: 5.7.1 - console-browserify: 1.2.0 - constants-browserify: 1.0.0 - create-require: 1.1.1 - crypto-browserify: 3.12.0 - domain-browser: 4.23.0 - events: 3.3.0 - https-browserify: 1.0.0 - isomorphic-timers-promises: 1.0.1 - os-browserify: 0.3.0 - path-browserify: 1.0.1 - pkg-dir: 5.0.0 - process: 0.11.10 - punycode: 1.4.1 - querystring-es3: 0.2.1 - readable-stream: 3.6.2 - stream-browserify: 3.0.0 - stream-http: 3.2.0 - string_decoder: 1.3.0 - timers-browserify: 2.0.12 - tty-browserify: 0.0.1 - url: 0.11.3 - util: 0.12.5 - vm-browserify: 1.1.2 - dev: true - /normalize-package-data@2.5.0: resolution: {integrity: sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==} dependencies: @@ -6962,14 +6237,6 @@ packages: /object-inspect@1.13.1: resolution: {integrity: sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==} - /object-is@1.1.6: - resolution: {integrity: sha512-F8cZ+KfGlSGi09lJT7/Nd6KJZ9ygtvYC0/UYYLI9nmQKLMnydpB9yvbv9K1uSkEu7FU9vYPmVwLg328tX+ot3Q==} - engines: {node: '>= 0.4'} - dependencies: - call-bind: 1.0.7 - define-properties: 1.2.1 - dev: true - /object-keys@1.1.1: resolution: {integrity: sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==} engines: {node: '>= 0.4'} @@ -7038,10 +6305,6 @@ packages: wcwidth: 1.0.1 dev: true - /os-browserify@0.3.0: - resolution: {integrity: sha512-gjcpUc3clBf9+210TRaDWbf+rZZZEshZ+DlXMRCeAjp0xhTrnQsKHypIy1J3d5hKdUzj69t708EHtU8P6bUn0A==} - dev: true - /os-tmpdir@1.0.2: resolution: {integrity: sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==} engines: {node: '>=0.10.0'} @@ -7102,10 +6365,6 @@ packages: engines: {node: '>=6'} dev: true - /pako@1.0.11: - resolution: {integrity: sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==} - dev: true - /parent-module@1.0.1: resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} engines: {node: '>=6'} @@ -7113,18 +6372,6 @@ packages: callsites: 3.1.0 dev: true - /parse-asn1@5.1.7: - resolution: {integrity: sha512-CTM5kuWR3sx9IFamcl5ErfPl6ea/N8IYwiJ+vpeB2g+1iknv7zBl5uPwbMbRVznRVbrNY6lGuDoE5b30grmbqg==} - engines: {node: '>= 0.10'} - dependencies: - asn1.js: 4.10.1 - browserify-aes: 1.2.0 - evp_bytestokey: 1.0.3 - hash-base: 3.0.4 - pbkdf2: 3.1.2 - safe-buffer: 5.2.1 - dev: true - /parse-json@5.2.0: resolution: {integrity: sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==} engines: {node: '>=8'} @@ -7139,10 +6386,6 @@ packages: resolution: {integrity: sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==} engines: {node: '>= 0.8'} - /path-browserify@1.0.1: - resolution: {integrity: sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==} - dev: true - /path-exists@4.0.0: resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} engines: {node: '>=8'} @@ -7194,19 +6437,9 @@ packages: resolution: {integrity: sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==} dev: true - /pbkdf2@3.1.2: - resolution: {integrity: sha512-iuh7L6jA7JEGu2WxDwtQP1ddOpaJNC4KlDEFfdQajSGgGPNi4OyDc2R7QnbY2bR9QjBVGwgvTdNJZoE7RaxUMA==} - engines: {node: '>=0.12'} - dependencies: - create-hash: 1.2.0 - create-hmac: 1.1.7 - ripemd160: 2.0.2 - safe-buffer: 5.2.1 - sha.js: 2.4.11 - dev: true - /picocolors@1.0.0: resolution: {integrity: sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==} + dev: true /picomatch@2.3.1: resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} @@ -7241,13 +6474,6 @@ packages: find-up: 4.1.0 dev: true - /pkg-dir@5.0.0: - resolution: {integrity: sha512-NPE8TDbzl/3YQYY7CSS228s3g2ollTFnc+Qi3tqmqJp9Vg2ovUpixcJEo2HJScN2Ez+kEaal6y70c0ehqJBJeA==} - engines: {node: '>=10'} - dependencies: - find-up: 5.0.0 - dev: true - /pkg-types@1.0.3: resolution: {integrity: sha512-nN7pYi0AQqJnoLPC9eHFQ8AcyaixBUOwvqc5TDnIKCMEE6I0y8P7OKA7fPexsXGCGxQDl/cmrLAp26LhcwxZ4A==} dependencies: @@ -7266,15 +6492,6 @@ packages: engines: {node: '>= 0.4'} dev: true - /postcss@8.4.31: - resolution: {integrity: sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==} - engines: {node: ^10 || ^12 || >=14} - dependencies: - nanoid: 3.3.7 - picocolors: 1.0.0 - source-map-js: 1.1.0 - dev: false - /postcss@8.4.38: resolution: {integrity: sha512-Wglpdk03BSfXkHoQa3b/oulrotAkwrlLDRSOb9D0bN86FdRyE9lppSp33aHNPgBa0JKCoB+drFLZkQoRRYae5A==} engines: {node: ^10 || ^12 || >=14} @@ -7323,11 +6540,6 @@ packages: /process-nextick-args@2.0.1: resolution: {integrity: sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==} - /process@0.11.10: - resolution: {integrity: sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==} - engines: {node: '>= 0.6.0'} - dev: true - /prompts@2.4.2: resolution: {integrity: sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==} engines: {node: '>= 6'} @@ -7351,21 +6563,6 @@ packages: resolution: {integrity: sha512-b/YwNhb8lk1Zz2+bXXpS/LK9OisiZZ1SNsSLxN1x2OXVEhW2Ckr/7mWE5vrC1ZTiJlD9g19jWszTmJsB+oEpFQ==} dev: true - /public-encrypt@4.0.3: - resolution: {integrity: sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==} - dependencies: - bn.js: 4.12.0 - browserify-rsa: 4.1.0 - create-hash: 1.2.0 - parse-asn1: 5.1.7 - randombytes: 2.1.0 - safe-buffer: 5.2.1 - dev: true - - /punycode@1.4.1: - resolution: {integrity: sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ==} - dev: true - /punycode@2.3.1: resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} engines: {node: '>=6'} @@ -7388,11 +6585,6 @@ packages: side-channel: 1.0.6 dev: true - /querystring-es3@0.2.1: - resolution: {integrity: sha512-773xhDQnZBMFobEiztv8LIl70ch5MSF/jUQVlhwFyBILqq96anmoctVIYz+ZRp0qbCKATTn6ev02M3r7Ga5vqA==} - engines: {node: '>=0.4.x'} - dev: true - /queue-microtask@1.2.3: resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} dev: true @@ -7424,13 +6616,6 @@ packages: dependencies: safe-buffer: 5.2.1 - /randomfill@1.0.4: - resolution: {integrity: sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==} - dependencies: - randombytes: 2.1.0 - safe-buffer: 5.2.1 - dev: true - /range-parser@1.2.1: resolution: {integrity: sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==} engines: {node: '>= 0.6'} @@ -7444,32 +6629,10 @@ packages: iconv-lite: 0.4.24 unpipe: 1.0.0 - /react-dom@18.2.0(react@18.2.0): - resolution: {integrity: sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g==} - peerDependencies: - react: ^18.2.0 - dependencies: - loose-envify: 1.4.0 - react: 18.2.0 - scheduler: 0.23.0 - dev: false - /react-is@18.2.0: resolution: {integrity: sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==} dev: true - /react-refresh@0.14.0: - resolution: {integrity: sha512-wViHqhAd8OHeLS/IRMJjTSDHF3U9eWi62F/MledQGPdJGDhodXJ9PBLNGr6WWL7qlH12Mt3TyTpbS+hGXMjCzQ==} - engines: {node: '>=0.10.0'} - dev: true - - /react@18.2.0: - resolution: {integrity: sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==} - engines: {node: '>=0.10.0'} - dependencies: - loose-envify: 1.4.0 - dev: false - /read-pkg-up@7.0.1: resolution: {integrity: sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==} engines: {node: '>=8'} @@ -7673,6 +6836,7 @@ packages: dependencies: hash-base: 3.1.0 inherits: 2.0.4 + dev: false /rollup@4.13.2: resolution: {integrity: sha512-MIlLgsdMprDBXC+4hsPgzWUasLO9CE4zOkj/u6j+Z6j5A4zRY+CtiXAdJyPtgCsc42g658Aeh1DlrdVEJhsL2g==} @@ -7748,12 +6912,6 @@ packages: /safer-buffer@2.1.2: resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} - /scheduler@0.23.0: - resolution: {integrity: sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw==} - dependencies: - loose-envify: 1.4.0 - dev: false - /schema-utils@3.3.0: resolution: {integrity: sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==} engines: {node: '>= 10.13.0'} @@ -7847,10 +7005,6 @@ packages: has-property-descriptors: 1.0.2 dev: true - /setimmediate@1.0.5: - resolution: {integrity: sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==} - dev: true - /setprototypeof@1.2.0: resolution: {integrity: sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==} @@ -7860,6 +7014,7 @@ packages: dependencies: inherits: 2.0.4 safe-buffer: 5.2.1 + dev: false /sha3@2.1.4: resolution: {integrity: sha512-S8cNxbyb0UGUM2VhRD4Poe5N58gJnJsLJ5vC7FYWGUmGhcsj4++WaIOBFVDxlG0W3To6xBuiRh+i0Qp2oNCOtg==} @@ -7961,11 +7116,6 @@ packages: yargs: 15.4.1 dev: true - /source-map-js@1.1.0: - resolution: {integrity: sha512-9vC2SfsJzlej6MAaMPLu8HiBSHGdRAJ9hVFYN1ibZoNkeanmDmLUcIrj6G9DGL7XMJ54AKg/G75akXl1/izTOw==} - engines: {node: '>=0.10.0'} - dev: false - /source-map-js@1.2.0: resolution: {integrity: sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==} engines: {node: '>=0.10.0'} @@ -8047,22 +7197,6 @@ packages: resolution: {integrity: sha512-JPbdCEQLj1w5GilpiHAx3qJvFndqybBysA3qUOnznweH4QbNYUsW/ea8QzSrnh0vNsezMMw5bcVool8lM0gwzg==} dev: true - /stream-browserify@3.0.0: - resolution: {integrity: sha512-H73RAHsVBapbim0tU2JwwOiXUj+fikfiaoYAKHF3VJfA0pe2BCzkhAHBlLG6REzE+2WNZcxOXjK7lkso+9euLA==} - dependencies: - inherits: 2.0.4 - readable-stream: 3.6.2 - dev: true - - /stream-http@3.2.0: - resolution: {integrity: sha512-Oq1bLqisTyK3TSCXpPbT4sdeYNdmyZJv1LxpEm2vu1ZhK89kSE5YXwZc3cWk0MagGaKriBh9mCFbVGtO+vY29A==} - dependencies: - builtin-status-codes: 3.0.0 - inherits: 2.0.4 - readable-stream: 3.6.2 - xtend: 4.0.2 - dev: true - /stream-transform@2.1.3: resolution: {integrity: sha512-9GHUiM5hMiCi6Y03jD2ARC1ettBXkQBoQAe7nJsPknnI0ow10aXjTnew8QtYQmLjzn974BnmWEAJgCY6ZP1DeQ==} dependencies: @@ -8202,23 +7336,6 @@ packages: js-tokens: 9.0.0 dev: true - /styled-jsx@5.1.1(react@18.2.0): - resolution: {integrity: sha512-pW7uC1l4mBZ8ugbiZrcIsiIvVx1UmTfw7UkC3Um2tmfUq9Bhk8IiyEIPl6F8agHgjzku6j0xQEZbfA5uSgSaCw==} - engines: {node: '>= 12.0.0'} - peerDependencies: - '@babel/core': '*' - babel-plugin-macros: '*' - react: '>= 16.8.0 || 17.x.x || ^18.0.0-0' - peerDependenciesMeta: - '@babel/core': - optional: true - babel-plugin-macros: - optional: true - dependencies: - client-only: 0.0.1 - react: 18.2.0 - dev: false - /superagent@8.1.2: resolution: {integrity: sha512-6WTxW1EB6yCxV5VFOIPQruWGHqc3yI7hEmZK6h+pyk69Lk/Ut7rLUY6W/ONF2MjBuGjvmMiIpsrVJ2vjrHlslA==} engines: {node: '>=6.4.0 <13 || >=14'} @@ -8364,13 +7481,6 @@ packages: resolution: {integrity: sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==} dev: true - /timers-browserify@2.0.12: - resolution: {integrity: sha512-9phl76Cqm6FhSX9Xe1ZUAMLtm1BLkKj2Qd5ApyWkXzsMRaA7dgr81kf4wJmQf/hAvg8EEyJxDo3du/0KlhPiKQ==} - engines: {node: '>=0.6.0'} - dependencies: - setimmediate: 1.0.5 - dev: true - /tinybench@2.6.0: resolution: {integrity: sha512-N8hW3PG/3aOoZAN5V/NSAEDz0ZixDSSt5b/a05iqtpgfLWMSVuCo7w0k2vVvEjdrIoeGqZzweX2WlyioNIHchA==} dev: true @@ -8425,15 +7535,6 @@ packages: engines: {node: '>=8'} dev: true - /ts-api-utils@1.3.0(typescript@5.4.2): - resolution: {integrity: sha512-UQMIo7pb8WRomKR1/+MFVLTroIvDVtMX3K6OUir8ynLyzB8Jeriont2bTAtmNPa1ekAgN7YPDyf6V+ygrdU+eQ==} - engines: {node: '>=16'} - peerDependencies: - typescript: '>=4.2.0' - dependencies: - typescript: 5.4.2 - dev: true - /ts-api-utils@1.3.0(typescript@5.4.3): resolution: {integrity: sha512-UQMIo7pb8WRomKR1/+MFVLTroIvDVtMX3K6OUir8ynLyzB8Jeriont2bTAtmNPa1ekAgN7YPDyf6V+ygrdU+eQ==} engines: {node: '>=16'} @@ -8552,10 +7653,6 @@ packages: /tslib@2.6.2: resolution: {integrity: sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==} - /tty-browserify@0.0.1: - resolution: {integrity: sha512-C3TaO7K81YvjCgQH9Q1S3R3P3BtN3RIM8n+OvX4il1K1zgE8ZhI0op7kClgkxtutIE8hQrcrHBXvIheqKUUCxw==} - dev: true - /tty-table@4.2.3: resolution: {integrity: sha512-Fs15mu0vGzCrj8fmJNP7Ynxt5J7praPXqFN0leZeZBXJwkMxv9cb2D454k1ltrtUSJbZ4yH4e0CynsHLxmUfFA==} engines: {node: '>=8.0.0'} @@ -8801,26 +7898,9 @@ packages: punycode: 2.3.1 dev: true - /url@0.11.3: - resolution: {integrity: sha512-6hxOLGfZASQK/cijlZnZJTq8OXAkt/3YGfQX45vvMYXpZoo8NdWZcY73K108Jf759lS1Bv/8wXnHDTSz17dSRw==} - dependencies: - punycode: 1.4.1 - qs: 6.12.0 - dev: true - /util-deprecate@1.0.2: resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} - /util@0.12.5: - resolution: {integrity: sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA==} - dependencies: - inherits: 2.0.4 - is-arguments: 1.1.1 - is-generator-function: 1.0.10 - is-typed-array: 1.1.13 - which-typed-array: 1.1.15 - dev: true - /utils-merge@1.0.1: resolution: {integrity: sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==} engines: {node: '>= 0.4.0'} @@ -8881,18 +7961,6 @@ packages: - terser dev: true - /vite-plugin-node-polyfills@0.21.0(vite@5.2.11): - resolution: {integrity: sha512-Sk4DiKnmxN8E0vhgEhzLudfJQfaT8k4/gJ25xvUPG54KjLJ6HAmDKbr4rzDD/QWEY+Lwg80KE85fGYBQihEPQA==} - peerDependencies: - vite: ^2.0.0 || ^3.0.0 || ^4.0.0 || ^5.0.0 - dependencies: - '@rollup/plugin-inject': 5.0.5 - node-stdlib-browser: 1.2.0 - vite: 5.2.11(@types/node@20.12.12) - transitivePeerDependencies: - - rollup - dev: true - /vite@5.2.11(@types/node@20.12.12): resolution: {integrity: sha512-HndV31LWW05i1BLPMUCE1B9E9GFbOu1MbenhS58FuK6owSO5qHm7GiCotrNY1YE5rMeQSFBGmT5ZaLEjFizgiQ==} engines: {node: ^18.0.0 || >=20.0.0} @@ -8985,10 +8053,6 @@ packages: - terser dev: true - /vm-browserify@1.1.2: - resolution: {integrity: sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ==} - dev: true - /walker@1.0.8: resolution: {integrity: sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==} dependencies: From 7c25505a2cc655d198a8f212641b17deacbb5ab2 Mon Sep 17 00:00:00 2001 From: ahonn Date: Tue, 4 Jun 2024 17:46:12 +1000 Subject: [PATCH 22/90] feat: rpc handler name optional and not required by default --- apps/service/package.json | 3 ++- apps/service/src/json-rpc/json-rpc.decorators.ts | 8 ++++---- apps/service/src/json-rpc/json-rpc.server.ts | 13 ++++++++++++- apps/service/src/rgbpp/rgbpp.service.ts | 8 +++++--- pnpm-lock.yaml | 3 +++ 5 files changed, 26 insertions(+), 9 deletions(-) diff --git a/apps/service/package.json b/apps/service/package.json index 6ef5b6b2..5f0ed33f 100644 --- a/apps/service/package.json +++ b/apps/service/package.json @@ -26,7 +26,8 @@ "@nestjs/platform-express": "^10.0.0", "json-rpc-2.0": "^1.7.0", "reflect-metadata": "^0.2.0", - "rxjs": "^7.8.1" + "rxjs": "^7.8.1", + "rgbpp": "workspace:*" }, "devDependencies": { "@nestjs/cli": "^10.0.0", diff --git a/apps/service/src/json-rpc/json-rpc.decorators.ts b/apps/service/src/json-rpc/json-rpc.decorators.ts index 5f054ced..3dbcf1f7 100644 --- a/apps/service/src/json-rpc/json-rpc.decorators.ts +++ b/apps/service/src/json-rpc/json-rpc.decorators.ts @@ -2,7 +2,7 @@ import { applyDecorators, Injectable, InjectableOptions, SetMetadata } from '@ne export const JsonRpcMetadataKey = '__json-rpc@metadata__'; export interface JsonRpcMetadata { - name: string; + name?: string; } export const JsonRpcMethodMetadataKey = '__json-rpc-method@metadata__'; @@ -10,9 +10,9 @@ export interface JsonRpcMethodMetadata { name?: string; } -export const RpcHandler = (data: JsonRpcMetadata & InjectableOptions) => { - const { name, scope } = data; - return applyDecorators(SetMetadata(JsonRpcMetadataKey, { name }), Injectable({ scope })); +export const RpcHandler = (data?: JsonRpcMetadata & InjectableOptions) => { + const { name, scope } = data ?? {}; + return applyDecorators(SetMetadata(JsonRpcMetadataKey, name ? { name } : {}), Injectable({ scope })); }; export const RpcMethodHandler = (data?: JsonRpcMethodMetadata) => { diff --git a/apps/service/src/json-rpc/json-rpc.server.ts b/apps/service/src/json-rpc/json-rpc.server.ts index 5922b2cf..e9be6174 100644 --- a/apps/service/src/json-rpc/json-rpc.server.ts +++ b/apps/service/src/json-rpc/json-rpc.server.ts @@ -5,6 +5,12 @@ import { InstanceWrapper } from '@nestjs/core/injector/instance-wrapper'; import { JsonRpcMetadataKey, JsonRpcMethodMetadataKey } from './json-rpc.decorators'; import { JsonRpcConfig } from './json-rpc.module'; +class JsonRpcServerError extends Error { + constructor(message: string) { + super(message); + } +} + @Injectable() export class JsonRpcServer { private server: JSONRPCServer; @@ -47,8 +53,13 @@ export class JsonRpcServer { if (!methodMetadata) { return; } - const name = `${metadata.name}.${methodMetadata.name ?? methodName}`; + const name = metadata.name + ? `${metadata.name}.${methodMetadata.name ?? methodName}` + : methodMetadata.name ?? methodName; const handler = instance[methodName].bind(instance); + if (rpcHandlers.has(name)) { + throw new JsonRpcServerError(`Duplicate JSON-RPC method: ${name}`); + } rpcHandlers.set(name, handler); }); }); diff --git a/apps/service/src/rgbpp/rgbpp.service.ts b/apps/service/src/rgbpp/rgbpp.service.ts index 2eb6d4f2..11ec59d3 100644 --- a/apps/service/src/rgbpp/rgbpp.service.ts +++ b/apps/service/src/rgbpp/rgbpp.service.ts @@ -1,10 +1,12 @@ import { RpcHandler, RpcMethodHandler } from 'src/json-rpc/json-rpc.decorators'; +// import { genCkbJumpBtcVirtualTx } from 'rgbpp'; -@RpcHandler({ name: 'rgbpp' }) +@RpcHandler() export class RgbppService { - @RpcMethodHandler({ name: 'hello' }) + @RpcMethodHandler({ name: 'genCkbJumpBtcVirtualTx' }) public getHello(params: unknown): string { console.log(params); - return 'Hello World!'; + // return genCkbJumpBtcVirtualTx(params); + return 'genCkbJumpBtcVirtualTx called'; } } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 2d2cc611..383199e0 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -65,6 +65,9 @@ importers: reflect-metadata: specifier: ^0.2.0 version: 0.2.2 + rgbpp: + specifier: workspace:* + version: link:../../packages/rgbpp rxjs: specifier: ^7.8.1 version: 7.8.1 From f1e3c81982a7719fa020b98a50c310a612262ec1 Mon Sep 17 00:00:00 2001 From: ahonn Date: Tue, 4 Jun 2024 17:49:55 +1000 Subject: [PATCH 23/90] feat: add getVersion rpc method --- apps/service/src/app.module.ts | 2 ++ apps/service/src/app.service.ts | 10 ++++++++++ apps/service/tsconfig.json | 1 + 3 files changed, 13 insertions(+) create mode 100644 apps/service/src/app.service.ts diff --git a/apps/service/src/app.module.ts b/apps/service/src/app.module.ts index 47454009..f9a534db 100644 --- a/apps/service/src/app.module.ts +++ b/apps/service/src/app.module.ts @@ -1,6 +1,7 @@ import { Module } from '@nestjs/common'; import JsonRpcModule from './json-rpc/json-rpc.module'; import { RgbppModule } from './rgbpp/rgbpp.module'; +import { AppService } from './app.service'; @Module({ imports: [ @@ -9,5 +10,6 @@ import { RgbppModule } from './rgbpp/rgbpp.module'; }), RgbppModule, ], + providers: [AppService], }) export class AppModule {} diff --git a/apps/service/src/app.service.ts b/apps/service/src/app.service.ts new file mode 100644 index 00000000..47cdd29f --- /dev/null +++ b/apps/service/src/app.service.ts @@ -0,0 +1,10 @@ +import { RpcHandler, RpcMethodHandler } from 'src/json-rpc/json-rpc.decorators'; +import * as pkg from '../package.json'; + +@RpcHandler() +export class AppService { + @RpcMethodHandler({ name: 'getVersion' }) + public getAppVersion(): string { + return pkg.version; + } +} diff --git a/apps/service/tsconfig.json b/apps/service/tsconfig.json index 95f5641c..8a53a58a 100644 --- a/apps/service/tsconfig.json +++ b/apps/service/tsconfig.json @@ -2,6 +2,7 @@ "compilerOptions": { "module": "commonjs", "declaration": true, + "resolveJsonModule": true, "removeComments": true, "emitDecoratorMetadata": true, "experimentalDecorators": true, From 2fc112970e731d8fb98b7f274e2b48fc4e726809 Mon Sep 17 00:00:00 2001 From: ahonn Date: Tue, 4 Jun 2024 18:31:29 +1000 Subject: [PATCH 24/90] feat: add configService and collector --- apps/service/package.json | 4 ++- apps/service/src/app.module.ts | 21 ++++++++++++++- apps/service/src/env.ts | 6 +++++ apps/service/src/rgbpp/rgbpp.service.ts | 26 +++++++++++++----- packages/rgbpp/src/ckb.ts | 1 + pnpm-lock.yaml | 35 ++++++++++++++++++++++++- 6 files changed, 84 insertions(+), 9 deletions(-) create mode 100644 apps/service/src/env.ts diff --git a/apps/service/package.json b/apps/service/package.json index 5f0ed33f..8b06cd6f 100644 --- a/apps/service/package.json +++ b/apps/service/package.json @@ -22,12 +22,14 @@ }, "dependencies": { "@nestjs/common": "^10.0.0", + "@nestjs/config": "^3.2.2", "@nestjs/core": "^10.0.0", "@nestjs/platform-express": "^10.0.0", "json-rpc-2.0": "^1.7.0", "reflect-metadata": "^0.2.0", + "rgbpp": "workspace:*", "rxjs": "^7.8.1", - "rgbpp": "workspace:*" + "zod": "^3.23.8" }, "devDependencies": { "@nestjs/cli": "^10.0.0", diff --git a/apps/service/src/app.module.ts b/apps/service/src/app.module.ts index f9a534db..2aaad0c3 100644 --- a/apps/service/src/app.module.ts +++ b/apps/service/src/app.module.ts @@ -1,15 +1,34 @@ import { Module } from '@nestjs/common'; +import { ConfigModule, ConfigService } from '@nestjs/config'; import JsonRpcModule from './json-rpc/json-rpc.module'; import { RgbppModule } from './rgbpp/rgbpp.module'; import { AppService } from './app.service'; +import { envSchema } from './env'; +import { Collector } from 'rgbpp/ckb'; @Module({ imports: [ + ConfigModule.forRoot({ + validate: envSchema.parse, + }), JsonRpcModule.forRoot({ path: '/json-rpc', }), RgbppModule, ], - providers: [AppService], + providers: [ + AppService, + { + provide: 'COLLECTOR', + useFactory: (configService: ConfigService) => { + const ckbRpcUrl = configService.get('CKB_RPC_URL'); + return new Collector({ + ckbIndexerUrl: ckbRpcUrl, + ckbNodeUrl: ckbRpcUrl, + }); + }, + inject: [ConfigService], + }, + ], }) export class AppModule {} diff --git a/apps/service/src/env.ts b/apps/service/src/env.ts new file mode 100644 index 00000000..bcedf442 --- /dev/null +++ b/apps/service/src/env.ts @@ -0,0 +1,6 @@ +import z from 'zod'; + +export const envSchema = z.object({ + NETWORK: z.enum(['mainnet', 'testnet']).default('testnet'), + CKB_RPC_URL: z.string().default('https://testnet.ckb.dev'), +}); diff --git a/apps/service/src/rgbpp/rgbpp.service.ts b/apps/service/src/rgbpp/rgbpp.service.ts index 11ec59d3..f6642bcb 100644 --- a/apps/service/src/rgbpp/rgbpp.service.ts +++ b/apps/service/src/rgbpp/rgbpp.service.ts @@ -1,12 +1,26 @@ +import { Inject } from '@nestjs/common'; import { RpcHandler, RpcMethodHandler } from 'src/json-rpc/json-rpc.decorators'; -// import { genCkbJumpBtcVirtualTx } from 'rgbpp'; +import { CkbJumpBtcVirtualTxParams, genCkbJumpBtcVirtualTx } from 'rgbpp'; +import { Collector } from 'rgbpp/ckb'; @RpcHandler() export class RgbppService { - @RpcMethodHandler({ name: 'genCkbJumpBtcVirtualTx' }) - public getHello(params: unknown): string { - console.log(params); - // return genCkbJumpBtcVirtualTx(params); - return 'genCkbJumpBtcVirtualTx called'; + constructor(@Inject('COLLECTOR') private collector: Collector) {} + + @RpcMethodHandler() + public genCkbJumpBtcVirtualTx(params: [Omit]) { + console.log('genCkbJumpBtcVirtualTx', this.collector); + const [{ xudtTypeBytes, fromCkbAddress, toRgbppLockArgs, transferAmount, witnessLockPlaceholderSize, ckbFeeRate }] = + params; + const virtualTx = genCkbJumpBtcVirtualTx({ + collector: this.collector, + xudtTypeBytes, + fromCkbAddress, + toRgbppLockArgs, + transferAmount, + witnessLockPlaceholderSize, + ckbFeeRate, + }); + return virtualTx; } } diff --git a/packages/rgbpp/src/ckb.ts b/packages/rgbpp/src/ckb.ts index 8232ce2c..84cb66f2 100644 --- a/packages/rgbpp/src/ckb.ts +++ b/packages/rgbpp/src/ckb.ts @@ -1 +1,2 @@ export * from '@rgbpp-sdk/ckb'; +export * from '@rgbpp-sdk/ckb/lib'; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 383199e0..7c1fe7f6 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -53,6 +53,9 @@ importers: '@nestjs/common': specifier: ^10.0.0 version: 10.3.9(reflect-metadata@0.2.2)(rxjs@7.8.1) + '@nestjs/config': + specifier: ^3.2.2 + version: 3.2.2(@nestjs/common@10.3.9)(rxjs@7.8.1) '@nestjs/core': specifier: ^10.0.0 version: 10.3.9(@nestjs/common@10.3.9)(@nestjs/platform-express@10.3.9)(reflect-metadata@0.2.2)(rxjs@7.8.1) @@ -71,6 +74,9 @@ importers: rxjs: specifier: ^7.8.1 version: 7.8.1 + zod: + specifier: ^3.23.8 + version: 3.23.8 devDependencies: '@nestjs/cli': specifier: ^10.0.0 @@ -1811,6 +1817,20 @@ packages: tslib: 2.6.2 uid: 2.0.2 + /@nestjs/config@3.2.2(@nestjs/common@10.3.9)(rxjs@7.8.1): + resolution: {integrity: sha512-vGICPOui5vE6kPz1iwQ7oCnp3qWgqxldPmBQ9onkVoKlBtyc83KJCr7CjuVtf4OdovMAVcux1d8Q6jglU2ZphA==} + peerDependencies: + '@nestjs/common': ^8.0.0 || ^9.0.0 || ^10.0.0 + rxjs: ^7.1.0 + dependencies: + '@nestjs/common': 10.3.9(reflect-metadata@0.2.2)(rxjs@7.8.1) + dotenv: 16.4.5 + dotenv-expand: 10.0.0 + lodash: 4.17.21 + rxjs: 7.8.1 + uuid: 9.0.1 + dev: false + /@nestjs/core@10.3.9(@nestjs/common@10.3.9)(@nestjs/platform-express@10.3.9)(reflect-metadata@0.2.2)(rxjs@7.8.1): resolution: {integrity: sha512-NzZUfWAmaf8sqhhwoRA+CuqxQe+P4Rz8PZp5U7CdCbjyeB9ZVGcBkihcJC9wMdtiOWHRndB2J8zRfs5w06jK3w==} requiresBuild: true @@ -3793,10 +3813,14 @@ packages: esutils: 2.0.3 dev: true + /dotenv-expand@10.0.0: + resolution: {integrity: sha512-GopVGCpVS1UKH75VKHGuQFqS1Gusej0z4FyQkPdwjil2gNIv+LNsqBlboOzpJFZKVT95GkCyWJbBSdFEFUWI2A==} + engines: {node: '>=12'} + dev: false + /dotenv@16.4.5: resolution: {integrity: sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg==} engines: {node: '>=12'} - dev: true /eastasianwidth@0.2.0: resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} @@ -7913,6 +7937,11 @@ packages: hasBin: true dev: false + /uuid@9.0.1: + resolution: {integrity: sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==} + hasBin: true + dev: false + /v8-compile-cache-lib@3.0.1: resolution: {integrity: sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==} dev: true @@ -8373,6 +8402,10 @@ packages: engines: {node: '>=12.20'} dev: true + /zod@3.23.8: + resolution: {integrity: sha512-XBx9AXhXktjUqnepgTiE5flcKIYWi/rme0Eaj+5Y0lftuGBq+jyRu/md4WnuxqgP1ubdpNCsYEYPxrzVHD8d6g==} + dev: false + /zx@8.1.0: resolution: {integrity: sha512-2BCoOK6JTWikAkwPCV2dFr+1ou29WoY+6XltLu+Ou9dvxrqm/p+HuHCgBtMRMIVFexQzUSGfB5VbYeY8XmGBPQ==} engines: {node: '>= 12.17.0'} From a7a9ee428b17730f91b02155d6ec4fe96163bfd3 Mon Sep 17 00:00:00 2001 From: ahonn Date: Tue, 4 Jun 2024 20:04:14 +1000 Subject: [PATCH 25/90] feat: fix collector inject and provide btc data source --- apps/service/.env.example | 7 +++ apps/service/package.json | 2 +- apps/service/src/app.module.ts | 17 +++++- apps/service/src/env.ts | 4 ++ apps/service/src/json-rpc/json-rpc.module.ts | 8 ++- apps/service/src/json-rpc/json-rpc.server.ts | 27 +++++---- apps/service/src/main.ts | 3 + apps/service/src/rgbpp/rgbpp.service.ts | 25 +++----- apps/service/tsconfig.json | 3 +- pnpm-lock.yaml | 63 +++++++++++++++++++- 10 files changed, 125 insertions(+), 34 deletions(-) create mode 100644 apps/service/.env.example diff --git a/apps/service/.env.example b/apps/service/.env.example new file mode 100644 index 00000000..0f85fac1 --- /dev/null +++ b/apps/service/.env.example @@ -0,0 +1,7 @@ +NETWORK=testnet + +CKB_RPC_URL=https://testnet.ckb.dev + +BTC_SERVICE_URL=https://btc-assets-api.testnet.mibao.pro +BTC_SERVICE_TOKEN=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJteS1hcHAiLCJhdWQiOiJidGMtYXNzZXRzLWFwaS50ZXN0bmV0Lm1pYmFvLnBybyIsImp0aSI6IjdjOWE4NjE1LWE4ZjYtNDRmYy04ODk5LTM2NmU0ZjQ2MWVjZCIsImlhdCI6MTcxNzQ5NDc5Mn0.oZVkSJPxQ_bxH6MvQmB_UrMgd4LmaDDx4jgfkJgBXY0 +BTC_SERVICE_ORIGIN=https://btc-assets-api.testnet.mibao.pro diff --git a/apps/service/package.json b/apps/service/package.json index 8b06cd6f..cb6e4879 100644 --- a/apps/service/package.json +++ b/apps/service/package.json @@ -27,7 +27,7 @@ "@nestjs/platform-express": "^10.0.0", "json-rpc-2.0": "^1.7.0", "reflect-metadata": "^0.2.0", - "rgbpp": "workspace:*", + "rgbpp": "^0.3.0", "rxjs": "^7.8.1", "zod": "^3.23.8" }, diff --git a/apps/service/src/app.module.ts b/apps/service/src/app.module.ts index 2aaad0c3..6ae8ab5d 100644 --- a/apps/service/src/app.module.ts +++ b/apps/service/src/app.module.ts @@ -1,11 +1,13 @@ -import { Module } from '@nestjs/common'; +import { Global, Module } from '@nestjs/common'; import { ConfigModule, ConfigService } from '@nestjs/config'; import JsonRpcModule from './json-rpc/json-rpc.module'; import { RgbppModule } from './rgbpp/rgbpp.module'; import { AppService } from './app.service'; import { envSchema } from './env'; import { Collector } from 'rgbpp/ckb'; +import { BtcAssetsApi, DataSource } from 'rgbpp'; +@Global() @Module({ imports: [ ConfigModule.forRoot({ @@ -29,6 +31,19 @@ import { Collector } from 'rgbpp/ckb'; }, inject: [ConfigService], }, + { + provide: 'BTC_DATA_SOURCE', + useFactory: (configService: ConfigService) => { + const url = configService.get('BTC_SERVICE_URL'); + const token = configService.get('BTC_SERVICE_TOKEN'); + const origin = configService.get('BTC_SERVICE_ORIGIN'); + const btcAssestApi = BtcAssetsApi.fromToken(url, token, origin); + const dataSource = new DataSource(btcAssestApi, configService.get('NETWORK')); + return dataSource; + }, + inject: [ConfigService], + }, ], + exports: ['COLLECTOR', 'BTC_DATA_SOURCE'], }) export class AppModule {} diff --git a/apps/service/src/env.ts b/apps/service/src/env.ts index bcedf442..d103ae4d 100644 --- a/apps/service/src/env.ts +++ b/apps/service/src/env.ts @@ -3,4 +3,8 @@ import z from 'zod'; export const envSchema = z.object({ NETWORK: z.enum(['mainnet', 'testnet']).default('testnet'), CKB_RPC_URL: z.string().default('https://testnet.ckb.dev'), + + BTC_SERVICE_URL: z.string(), + BTC_SERVICE_TOKEN: z.string(), + BTC_SERVICE_ORIGIN: z.string(), }); diff --git a/apps/service/src/json-rpc/json-rpc.module.ts b/apps/service/src/json-rpc/json-rpc.module.ts index 032ebb47..76ca165d 100644 --- a/apps/service/src/json-rpc/json-rpc.module.ts +++ b/apps/service/src/json-rpc/json-rpc.module.ts @@ -1,4 +1,4 @@ -import { Inject, Logger, Module, OnModuleInit } from '@nestjs/common'; +import { Inject, Logger, Module, OnApplicationBootstrap, OnModuleInit } from '@nestjs/common'; import { JsonRpcServer } from './json-rpc.server'; export const JSON_RPC_OPTIONS = '__JSON_RPC_OPTIONS__'; @@ -8,7 +8,7 @@ export interface JsonRpcConfig { } @Module({}) -export class JsonRpcModule implements OnModuleInit { +export class JsonRpcModule implements OnModuleInit, OnApplicationBootstrap { private logger = new Logger(JsonRpcModule.name); constructor( @@ -33,6 +33,10 @@ export class JsonRpcModule implements OnModuleInit { this.jsonRpcServer.run(this.config); this.logger.log(`JSON-RPC server is running on ${this.config.path}`); } + + public async onApplicationBootstrap() { + await this.jsonRpcServer.resolve(); + } } export default JsonRpcModule; diff --git a/apps/service/src/json-rpc/json-rpc.server.ts b/apps/service/src/json-rpc/json-rpc.server.ts index e9be6174..bbdf116b 100644 --- a/apps/service/src/json-rpc/json-rpc.server.ts +++ b/apps/service/src/json-rpc/json-rpc.server.ts @@ -1,5 +1,5 @@ import { Injectable, Logger } from '@nestjs/common'; -import { HttpAdapterHost, ModulesContainer } from '@nestjs/core'; +import { HttpAdapterHost, ModuleRef, ModulesContainer } from '@nestjs/core'; import { JSONRPCServer, SimpleJSONRPCMethod } from 'json-rpc-2.0'; import { InstanceWrapper } from '@nestjs/core/injector/instance-wrapper'; import { JsonRpcMetadataKey, JsonRpcMethodMetadataKey } from './json-rpc.decorators'; @@ -19,14 +19,9 @@ export class JsonRpcServer { constructor( private httpAdapterHost: HttpAdapterHost, private modulesContainer: ModulesContainer, + private moduleRef: ModuleRef, ) { this.server = new JSONRPCServer(); - - const handlers = this.getRegisteredHandlers(); - handlers.forEach((handler, name) => { - this.logger.log(`Registering JSON-RPC method: ${name}`); - this.server.addMethod(name, handler); - }); } private getRegisteredHandlers() { @@ -47,16 +42,18 @@ export class JsonRpcServer { return; } - const methodNames = Object.getOwnPropertyNames(Object.getPrototypeOf(instance)); - methodNames.forEach((methodName) => { - const methodMetadata = Reflect.getMetadata(JsonRpcMethodMetadataKey, instance[methodName]); + const instanceRef = this.moduleRef.get(instance.constructor, { strict: false }); + + const properties = Object.getOwnPropertyNames(Object.getPrototypeOf(instanceRef)); + properties.forEach((methodName) => { + const methodMetadata = Reflect.getMetadata(JsonRpcMethodMetadataKey, instanceRef[methodName]); if (!methodMetadata) { return; } const name = metadata.name ? `${metadata.name}.${methodMetadata.name ?? methodName}` : methodMetadata.name ?? methodName; - const handler = instance[methodName].bind(instance); + const handler = (params: unknown) => instanceRef[methodName](params); if (rpcHandlers.has(name)) { throw new JsonRpcServerError(`Duplicate JSON-RPC method: ${name}`); } @@ -66,6 +63,14 @@ export class JsonRpcServer { return rpcHandlers; } + public async resolve() { + const handlers = this.getRegisteredHandlers(); + handlers.forEach((handler, name) => { + this.logger.log(`Registering JSON-RPC method: ${name}`); + this.server.addMethod(name, handler); + }); + } + public async run(config: JsonRpcConfig) { this.httpAdapterHost.httpAdapter.post(config.path, async (req, res) => { this.logger.debug(`Received JSON-RPC request: ${JSON.stringify(req.body)}`); diff --git a/apps/service/src/main.ts b/apps/service/src/main.ts index 13cad38c..b7ad93dc 100644 --- a/apps/service/src/main.ts +++ b/apps/service/src/main.ts @@ -1,8 +1,11 @@ import { NestFactory } from '@nestjs/core'; import { AppModule } from './app.module'; +import { Logger } from '@nestjs/common'; async function bootstrap() { + const logger = new Logger('AppBootstrap'); const app = await NestFactory.create(AppModule); await app.listen(3000); + logger.log('Application is running on: http://localhost:3000'); } bootstrap(); diff --git a/apps/service/src/rgbpp/rgbpp.service.ts b/apps/service/src/rgbpp/rgbpp.service.ts index f6642bcb..93ebb2f9 100644 --- a/apps/service/src/rgbpp/rgbpp.service.ts +++ b/apps/service/src/rgbpp/rgbpp.service.ts @@ -1,26 +1,19 @@ import { Inject } from '@nestjs/common'; import { RpcHandler, RpcMethodHandler } from 'src/json-rpc/json-rpc.decorators'; -import { CkbJumpBtcVirtualTxParams, genCkbJumpBtcVirtualTx } from 'rgbpp'; +import { DataSource } from 'rgbpp'; import { Collector } from 'rgbpp/ckb'; @RpcHandler() export class RgbppService { - constructor(@Inject('COLLECTOR') private collector: Collector) {} + constructor( + @Inject('COLLECTOR') private collector: Collector, + @Inject('BTC_DATA_SOURCE') private btcDataSource: DataSource, + ) {} @RpcMethodHandler() - public genCkbJumpBtcVirtualTx(params: [Omit]) { - console.log('genCkbJumpBtcVirtualTx', this.collector); - const [{ xudtTypeBytes, fromCkbAddress, toRgbppLockArgs, transferAmount, witnessLockPlaceholderSize, ckbFeeRate }] = - params; - const virtualTx = genCkbJumpBtcVirtualTx({ - collector: this.collector, - xudtTypeBytes, - fromCkbAddress, - toRgbppLockArgs, - transferAmount, - witnessLockPlaceholderSize, - ckbFeeRate, - }); - return virtualTx; + public async hello(params: unknown): Promise<{ address: string }> { + console.log(params, this.collector, this.btcDataSource); + const paymaster = await this.btcDataSource.getPaymasterOutput(); + return paymaster; } } diff --git a/apps/service/tsconfig.json b/apps/service/tsconfig.json index 8a53a58a..7e880a37 100644 --- a/apps/service/tsconfig.json +++ b/apps/service/tsconfig.json @@ -1,9 +1,10 @@ { "compilerOptions": { - "module": "commonjs", + "module": "NodeNext", "declaration": true, "resolveJsonModule": true, "removeComments": true, + "moduleResolution": "NodeNext", "emitDecoratorMetadata": true, "experimentalDecorators": true, "allowSyntheticDefaultImports": true, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 7c1fe7f6..8d843de6 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -69,8 +69,8 @@ importers: specifier: ^0.2.0 version: 0.2.2 rgbpp: - specifier: workspace:* - version: link:../../packages/rgbpp + specifier: ^0.3.0 + version: 0.3.0(@ckb-lumos/lumos@0.22.0-next.5)(lodash@4.17.21) rxjs: specifier: ^7.8.1 version: 7.8.1 @@ -1975,6 +1975,53 @@ packages: dev: true optional: true + /@rgbpp-sdk/btc@0.3.0(@ckb-lumos/lumos@0.22.0-next.5): + resolution: {integrity: sha512-0KLVRAlYxA/m2K1FTrrtAHezfaEg0MXfEmlHjMIK1oOUjUuis5UAJPSyB83Ql5RjVRFFolxdyPoW2Xe7MhAp4A==} + dependencies: + '@bitcoinerlab/secp256k1': 1.1.1 + '@ckb-lumos/codec': 0.22.2 + '@nervosnetwork/ckb-types': 0.109.1 + '@rgbpp-sdk/ckb': 0.3.0(@ckb-lumos/lumos@0.22.0-next.5)(lodash@4.17.21) + '@rgbpp-sdk/service': 0.3.0 + bip32: 4.0.0 + bitcoinjs-lib: 6.1.5 + ecpair: 2.1.0 + lodash: 4.17.21 + p-limit: 3.1.0 + transitivePeerDependencies: + - '@ckb-lumos/lumos' + - debug + dev: false + + /@rgbpp-sdk/ckb@0.3.0(@ckb-lumos/lumos@0.22.0-next.5)(lodash@4.17.21): + resolution: {integrity: sha512-Qf6Yhgakz8UhkZ+PulIHdrMVSDbZPW7+GDTA8KLrfVB/EEMoXA5L5LVanJKrYKTgBkGXYwEXW8Tti0Lr76SBmA==} + dependencies: + '@ckb-lumos/base': 0.22.2 + '@ckb-lumos/codec': 0.22.2 + '@exact-realty/multipart-parser': 1.0.13 + '@nervosnetwork/ckb-sdk-core': 0.109.1 + '@nervosnetwork/ckb-sdk-utils': 0.109.1 + '@nervosnetwork/ckb-types': 0.109.1 + '@rgbpp-sdk/service': 0.3.0 + '@spore-sdk/core': 0.2.0-beta.6(@ckb-lumos/lumos@0.22.0-next.5)(lodash@4.17.21) + axios: 1.6.8 + camelcase-keys: 7.0.2 + js-sha256: 0.11.0 + transitivePeerDependencies: + - '@ckb-lumos/lumos' + - debug + - lodash + dev: false + + /@rgbpp-sdk/service@0.3.0: + resolution: {integrity: sha512-MvVBVWbdYQVnjnCf3xYH6HXqHaUmL7DjUVucTYMjbB0cMeBqVjEAkX1RIVUqqcCpgSeYnK1nFEQHXB51rx8bMw==} + dependencies: + '@ckb-lumos/base': 0.22.2 + '@ckb-lumos/codec': 0.22.2 + '@nervosnetwork/ckb-types': 0.109.1 + lodash: 4.17.21 + dev: false + /@rollup/rollup-android-arm-eabi@4.13.2: resolution: {integrity: sha512-3XFIDKWMFZrMnao1mJhnOT1h2g0169Os848NhhmGweEcfJ4rCi+3yMCOLG4zA61rbJdkcrM/DjVZm9Hg5p5w7g==} cpu: [arm] @@ -6834,6 +6881,18 @@ packages: resolution: {integrity: sha512-r5a3l5HzYlIC68TpmYKlxWjmOP6wiPJ1vWv2HeLhNsRZMrCkxeqxiHlQ21oXmQ4F3SiryXBHhAD7JZqvOJjFmg==} dev: true + /rgbpp@0.3.0(@ckb-lumos/lumos@0.22.0-next.5)(lodash@4.17.21): + resolution: {integrity: sha512-SvvQsTwcTpxedKhzKY+fJQCavfnO2wtyAgO6zkuXBxveLKQQrsvCNumhwzfLOkZW8PhEDz4qAks3WhYnyOR2Vw==} + dependencies: + '@rgbpp-sdk/btc': 0.3.0(@ckb-lumos/lumos@0.22.0-next.5) + '@rgbpp-sdk/ckb': 0.3.0(@ckb-lumos/lumos@0.22.0-next.5)(lodash@4.17.21) + '@rgbpp-sdk/service': 0.3.0 + transitivePeerDependencies: + - '@ckb-lumos/lumos' + - debug + - lodash + dev: false + /rimraf@3.0.2: resolution: {integrity: sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==} deprecated: Rimraf versions prior to v4 are no longer supported From 792adb9f5625e94fcb27e97eae20f45423490200 Mon Sep 17 00:00:00 2001 From: ahonn Date: Tue, 4 Jun 2024 20:06:37 +1000 Subject: [PATCH 26/90] feat: update hello world method --- apps/service/src/rgbpp/rgbpp.service.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/service/src/rgbpp/rgbpp.service.ts b/apps/service/src/rgbpp/rgbpp.service.ts index 93ebb2f9..bdb61e65 100644 --- a/apps/service/src/rgbpp/rgbpp.service.ts +++ b/apps/service/src/rgbpp/rgbpp.service.ts @@ -10,8 +10,8 @@ export class RgbppService { @Inject('BTC_DATA_SOURCE') private btcDataSource: DataSource, ) {} - @RpcMethodHandler() - public async hello(params: unknown): Promise<{ address: string }> { + @RpcMethodHandler({ name: 'hello_world' }) + public async helloWorld(params: unknown): Promise<{ address: string }> { console.log(params, this.collector, this.btcDataSource); const paymaster = await this.btcDataSource.getPaymasterOutput(); return paymaster; From 6d45809050b7e23a2d2bae95f65e01d8fa8207c2 Mon Sep 17 00:00:00 2001 From: ahonn Date: Tue, 4 Jun 2024 20:19:09 +1000 Subject: [PATCH 27/90] fix: get module ref when rpc method called --- apps/service/src/app.service.ts | 2 +- apps/service/src/json-rpc/json-rpc.module.ts | 9 +++------ apps/service/src/json-rpc/json-rpc.server.ts | 11 ++++++----- 3 files changed, 10 insertions(+), 12 deletions(-) diff --git a/apps/service/src/app.service.ts b/apps/service/src/app.service.ts index 47cdd29f..6c2b54a4 100644 --- a/apps/service/src/app.service.ts +++ b/apps/service/src/app.service.ts @@ -3,7 +3,7 @@ import * as pkg from '../package.json'; @RpcHandler() export class AppService { - @RpcMethodHandler({ name: 'getVersion' }) + @RpcMethodHandler({ name: 'get_version' }) public getAppVersion(): string { return pkg.version; } diff --git a/apps/service/src/json-rpc/json-rpc.module.ts b/apps/service/src/json-rpc/json-rpc.module.ts index 76ca165d..2c17ac91 100644 --- a/apps/service/src/json-rpc/json-rpc.module.ts +++ b/apps/service/src/json-rpc/json-rpc.module.ts @@ -1,4 +1,4 @@ -import { Inject, Logger, Module, OnApplicationBootstrap, OnModuleInit } from '@nestjs/common'; +import { Inject, Logger, Module, OnModuleInit } from '@nestjs/common'; import { JsonRpcServer } from './json-rpc.server'; export const JSON_RPC_OPTIONS = '__JSON_RPC_OPTIONS__'; @@ -8,7 +8,7 @@ export interface JsonRpcConfig { } @Module({}) -export class JsonRpcModule implements OnModuleInit, OnApplicationBootstrap { +export class JsonRpcModule implements OnModuleInit { private logger = new Logger(JsonRpcModule.name); constructor( @@ -30,13 +30,10 @@ export class JsonRpcModule implements OnModuleInit, OnApplicationBootstrap { } public async onModuleInit() { + await this.jsonRpcServer.resolve(); this.jsonRpcServer.run(this.config); this.logger.log(`JSON-RPC server is running on ${this.config.path}`); } - - public async onApplicationBootstrap() { - await this.jsonRpcServer.resolve(); - } } export default JsonRpcModule; diff --git a/apps/service/src/json-rpc/json-rpc.server.ts b/apps/service/src/json-rpc/json-rpc.server.ts index bbdf116b..f556f6d5 100644 --- a/apps/service/src/json-rpc/json-rpc.server.ts +++ b/apps/service/src/json-rpc/json-rpc.server.ts @@ -42,18 +42,19 @@ export class JsonRpcServer { return; } - const instanceRef = this.moduleRef.get(instance.constructor, { strict: false }); - - const properties = Object.getOwnPropertyNames(Object.getPrototypeOf(instanceRef)); + const properties = Object.getOwnPropertyNames(Object.getPrototypeOf(instance)); properties.forEach((methodName) => { - const methodMetadata = Reflect.getMetadata(JsonRpcMethodMetadataKey, instanceRef[methodName]); + const methodMetadata = Reflect.getMetadata(JsonRpcMethodMetadataKey, instance[methodName]); if (!methodMetadata) { return; } const name = metadata.name ? `${metadata.name}.${methodMetadata.name ?? methodName}` : methodMetadata.name ?? methodName; - const handler = (params: unknown) => instanceRef[methodName](params); + const handler = (params: unknown) => { + const instanceRef = this.moduleRef.get(instance.constructor, { strict: false }); + return instanceRef[methodName](params); + }; if (rpcHandlers.has(name)) { throw new JsonRpcServerError(`Duplicate JSON-RPC method: ${name}`); } From dc54046f6c506d37b39b83fa336638216d0af826 Mon Sep 17 00:00:00 2001 From: Dylan Duan Date: Wed, 5 Jun 2024 10:57:16 +0800 Subject: [PATCH 28/90] chore: Update sdk-service env example --- apps/service/.env.example | 10 +++++++++- packages/rgbpp/src/ckb.ts | 1 - 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/apps/service/.env.example b/apps/service/.env.example index 0f85fac1..e3f5009c 100644 --- a/apps/service/.env.example +++ b/apps/service/.env.example @@ -1,7 +1,15 @@ +# testnet for CKB and BTC Testnet and mainnet for CKB and BTC Mainnet, the default value is testnet NETWORK=testnet +# CKB node url which should be matched with NETWORK CKB_RPC_URL=https://testnet.ckb.dev +# The BTC assets api url which should be matched with NETWORK BTC_SERVICE_URL=https://btc-assets-api.testnet.mibao.pro -BTC_SERVICE_TOKEN=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJteS1hcHAiLCJhdWQiOiJidGMtYXNzZXRzLWFwaS50ZXN0bmV0Lm1pYmFvLnBybyIsImp0aSI6IjdjOWE4NjE1LWE4ZjYtNDRmYy04ODk5LTM2NmU0ZjQ2MWVjZCIsImlhdCI6MTcxNzQ5NDc5Mn0.oZVkSJPxQ_bxH6MvQmB_UrMgd4LmaDDx4jgfkJgBXY0 + +# The BTC assets api token which should be matched with IS_MAINNET +# To get an access token, please refer to https://github.com/ckb-cell/rgbpp-sdk/tree/develop/packages/service#get-an-access-token +BTC_SERVICE_TOKEN= + +# The BTC assets api origin which should be matched with IS_MAINNET BTC_SERVICE_ORIGIN=https://btc-assets-api.testnet.mibao.pro diff --git a/packages/rgbpp/src/ckb.ts b/packages/rgbpp/src/ckb.ts index 84cb66f2..8232ce2c 100644 --- a/packages/rgbpp/src/ckb.ts +++ b/packages/rgbpp/src/ckb.ts @@ -1,2 +1 @@ export * from '@rgbpp-sdk/ckb'; -export * from '@rgbpp-sdk/ckb/lib'; From 3d204de21d56f30ec0eb67115e2348f0162cbd0f Mon Sep 17 00:00:00 2001 From: Dylan Duan Date: Wed, 5 Jun 2024 14:16:20 +0800 Subject: [PATCH 29/90] feat: Add generateRgbppTransferTx RPC --- apps/service/package.json | 3 +- apps/service/src/app.module.ts | 14 +++- apps/service/src/rgbpp/rgbpp.service.ts | 32 +++++++-- apps/service/src/rgbpp/types.ts | 21 ++++++ apps/service/src/utils/snake.ts | 10 +++ packages/ckb/src/index.ts | 2 + pnpm-lock.yaml | 91 ++++++++----------------- 7 files changed, 101 insertions(+), 72 deletions(-) create mode 100644 apps/service/src/rgbpp/types.ts create mode 100644 apps/service/src/utils/snake.ts diff --git a/apps/service/package.json b/apps/service/package.json index cb6e4879..62ca8ea3 100644 --- a/apps/service/package.json +++ b/apps/service/package.json @@ -25,9 +25,10 @@ "@nestjs/config": "^3.2.2", "@nestjs/core": "^10.0.0", "@nestjs/platform-express": "^10.0.0", + "convert-keys": "^1.3.4", "json-rpc-2.0": "^1.7.0", "reflect-metadata": "^0.2.0", - "rgbpp": "^0.3.0", + "rgbpp": "workspace:*", "rxjs": "^7.8.1", "zod": "^3.23.8" }, diff --git a/apps/service/src/app.module.ts b/apps/service/src/app.module.ts index 6ae8ab5d..ec0cdfd5 100644 --- a/apps/service/src/app.module.ts +++ b/apps/service/src/app.module.ts @@ -5,7 +5,9 @@ import { RgbppModule } from './rgbpp/rgbpp.module'; import { AppService } from './app.service'; import { envSchema } from './env'; import { Collector } from 'rgbpp/ckb'; -import { BtcAssetsApi, DataSource } from 'rgbpp'; +import { BtcAssetsApi, DataSource, NetworkType } from 'rgbpp'; + +const parseNetwork = (configService: ConfigService): boolean => configService.get('NETWORK') === 'mainnet'; @Global() @Module({ @@ -20,6 +22,11 @@ import { BtcAssetsApi, DataSource } from 'rgbpp'; ], providers: [ AppService, + { + provide: 'IS_MAINNET', + useFactory: parseNetwork, + inject: [ConfigService], + }, { provide: 'COLLECTOR', useFactory: (configService: ConfigService) => { @@ -38,12 +45,13 @@ import { BtcAssetsApi, DataSource } from 'rgbpp'; const token = configService.get('BTC_SERVICE_TOKEN'); const origin = configService.get('BTC_SERVICE_ORIGIN'); const btcAssestApi = BtcAssetsApi.fromToken(url, token, origin); - const dataSource = new DataSource(btcAssestApi, configService.get('NETWORK')); + const networkType = parseNetwork(configService) ? NetworkType.MAINNET : NetworkType.TESTNET; + const dataSource = new DataSource(btcAssestApi, networkType); return dataSource; }, inject: [ConfigService], }, ], - exports: ['COLLECTOR', 'BTC_DATA_SOURCE'], + exports: ['IS_MAINNET', 'COLLECTOR', 'BTC_DATA_SOURCE'], }) export class AppModule {} diff --git a/apps/service/src/rgbpp/rgbpp.service.ts b/apps/service/src/rgbpp/rgbpp.service.ts index bdb61e65..3331891e 100644 --- a/apps/service/src/rgbpp/rgbpp.service.ts +++ b/apps/service/src/rgbpp/rgbpp.service.ts @@ -1,19 +1,37 @@ import { Inject } from '@nestjs/common'; import { RpcHandler, RpcMethodHandler } from 'src/json-rpc/json-rpc.decorators'; -import { DataSource } from 'rgbpp'; -import { Collector } from 'rgbpp/ckb'; +import { DataSource } from 'rgbpp/btc'; +import { Collector, toCamelcase } from 'rgbpp/ckb'; +import { RgbppTransferReq, RgbppTransferResp } from './types'; +import { toSnakeCase } from 'src/utils/snake'; +import { buildRgbppTransferTx } from 'rgbpp'; @RpcHandler() export class RgbppService { constructor( + @Inject('IS_MAINNET') private isMainnet: boolean, @Inject('COLLECTOR') private collector: Collector, @Inject('BTC_DATA_SOURCE') private btcDataSource: DataSource, ) {} - @RpcMethodHandler({ name: 'hello_world' }) - public async helloWorld(params: unknown): Promise<{ address: string }> { - console.log(params, this.collector, this.btcDataSource); - const paymaster = await this.btcDataSource.getPaymasterOutput(); - return paymaster; + @RpcMethodHandler({ name: 'generate_rgbpp_transfer_tx' }) + public async generateRgbppTransferTx(request: object[]) { + const { xudtTypeArgs, rgbppLockArgsList, transferAmount, fromBtcAddress, toBtcAddress } = + toCamelcase(request[0]); + const { ckbVirtualTxResult, btcPsbtHex } = await buildRgbppTransferTx({ + collector: this.collector, + xudtTypeArgs, + rgbppLockArgsList, + transferAmount: BigInt(transferAmount), + fromBtcAddress, + toBtcAddress, + btcDataSource: this.btcDataSource, + isMainnet: this.isMainnet, + }); + const response: RgbppTransferResp = { + ckbVirtualTxResult: JSON.stringify(ckbVirtualTxResult), + btcPsbtHex, + }; + return toSnakeCase(response); } } diff --git a/apps/service/src/rgbpp/types.ts b/apps/service/src/rgbpp/types.ts new file mode 100644 index 00000000..a92f4e9b --- /dev/null +++ b/apps/service/src/rgbpp/types.ts @@ -0,0 +1,21 @@ +import { Hex } from 'rgbpp/ckb'; + +export interface RgbppTransferReq { + // The transferred RGB++ xUDT type script args + xudtTypeArgs: string; + // The rgbpp assets cell lock script args array whose data structure is: out_index | btc_tx_id + rgbppLockArgsList: string[]; + // The xUDT amount to be transferred + transferAmount: Hex; + // The sender BTC address + fromBtcAddress: string; + // The receiver BTC address + toBtcAddress: string; +} + +export interface RgbppTransferResp { + // The JSON string for the `BtcTransferVirtualTxResult` + ckbVirtualTxResult: string; + // The BTC PSBT hex string which can be used to construct Bitcoin PSBT + btcPsbtHex: Hex; +} diff --git a/apps/service/src/utils/snake.ts b/apps/service/src/utils/snake.ts new file mode 100644 index 00000000..5ce20f00 --- /dev/null +++ b/apps/service/src/utils/snake.ts @@ -0,0 +1,10 @@ +import { toSnake } from 'convert-keys'; + +export const toSnakeCase = (obj: object): T | null => { + try { + return toSnake(obj); + } catch (error) { + console.error(error); + } + return null; +}; diff --git a/packages/ckb/src/index.ts b/packages/ckb/src/index.ts index 2a40bc10..9c954cdd 100644 --- a/packages/ckb/src/index.ts +++ b/packages/ckb/src/index.ts @@ -1,3 +1,5 @@ +export { serializeScript } from '@nervosnetwork/ckb-sdk-utils'; + export * from './schemas/generated/blockchain'; export * from './schemas/generated/rgbpp'; export * from './collector'; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 8d843de6..4db629cc 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -62,6 +62,9 @@ importers: '@nestjs/platform-express': specifier: ^10.0.0 version: 10.3.9(@nestjs/common@10.3.9)(@nestjs/core@10.3.9) + convert-keys: + specifier: ^1.3.4 + version: 1.3.4 json-rpc-2.0: specifier: ^1.7.0 version: 1.7.0 @@ -69,8 +72,8 @@ importers: specifier: ^0.2.0 version: 0.2.2 rgbpp: - specifier: ^0.3.0 - version: 0.3.0(@ckb-lumos/lumos@0.22.0-next.5)(lodash@4.17.21) + specifier: workspace:* + version: link:../../packages/rgbpp rxjs: specifier: ^7.8.1 version: 7.8.1 @@ -1975,53 +1978,6 @@ packages: dev: true optional: true - /@rgbpp-sdk/btc@0.3.0(@ckb-lumos/lumos@0.22.0-next.5): - resolution: {integrity: sha512-0KLVRAlYxA/m2K1FTrrtAHezfaEg0MXfEmlHjMIK1oOUjUuis5UAJPSyB83Ql5RjVRFFolxdyPoW2Xe7MhAp4A==} - dependencies: - '@bitcoinerlab/secp256k1': 1.1.1 - '@ckb-lumos/codec': 0.22.2 - '@nervosnetwork/ckb-types': 0.109.1 - '@rgbpp-sdk/ckb': 0.3.0(@ckb-lumos/lumos@0.22.0-next.5)(lodash@4.17.21) - '@rgbpp-sdk/service': 0.3.0 - bip32: 4.0.0 - bitcoinjs-lib: 6.1.5 - ecpair: 2.1.0 - lodash: 4.17.21 - p-limit: 3.1.0 - transitivePeerDependencies: - - '@ckb-lumos/lumos' - - debug - dev: false - - /@rgbpp-sdk/ckb@0.3.0(@ckb-lumos/lumos@0.22.0-next.5)(lodash@4.17.21): - resolution: {integrity: sha512-Qf6Yhgakz8UhkZ+PulIHdrMVSDbZPW7+GDTA8KLrfVB/EEMoXA5L5LVanJKrYKTgBkGXYwEXW8Tti0Lr76SBmA==} - dependencies: - '@ckb-lumos/base': 0.22.2 - '@ckb-lumos/codec': 0.22.2 - '@exact-realty/multipart-parser': 1.0.13 - '@nervosnetwork/ckb-sdk-core': 0.109.1 - '@nervosnetwork/ckb-sdk-utils': 0.109.1 - '@nervosnetwork/ckb-types': 0.109.1 - '@rgbpp-sdk/service': 0.3.0 - '@spore-sdk/core': 0.2.0-beta.6(@ckb-lumos/lumos@0.22.0-next.5)(lodash@4.17.21) - axios: 1.6.8 - camelcase-keys: 7.0.2 - js-sha256: 0.11.0 - transitivePeerDependencies: - - '@ckb-lumos/lumos' - - debug - - lodash - dev: false - - /@rgbpp-sdk/service@0.3.0: - resolution: {integrity: sha512-MvVBVWbdYQVnjnCf3xYH6HXqHaUmL7DjUVucTYMjbB0cMeBqVjEAkX1RIVUqqcCpgSeYnK1nFEQHXB51rx8bMw==} - dependencies: - '@ckb-lumos/base': 0.22.2 - '@ckb-lumos/codec': 0.22.2 - '@nervosnetwork/ckb-types': 0.109.1 - lodash: 4.17.21 - dev: false - /@rollup/rollup-android-arm-eabi@4.13.2: resolution: {integrity: sha512-3XFIDKWMFZrMnao1mJhnOT1h2g0169Os848NhhmGweEcfJ4rCi+3yMCOLG4zA61rbJdkcrM/DjVZm9Hg5p5w7g==} cpu: [arm] @@ -3564,6 +3520,15 @@ packages: resolution: {integrity: sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==} engines: {node: '>= 0.6'} + /convert-keys@1.3.4: + resolution: {integrity: sha512-+ltki+EUagotW/x7r+15nuHyk4nzcSkBk1lZpmbHjscF2E9ZmNErgV7K18LNshB0qglECcsnwy29ODlJ0pI0KA==} + dependencies: + lodash.camelcase: 4.3.0 + lodash.forown: 4.4.0 + lodash.isplainobject: 4.0.6 + lodash.snakecase: 4.1.1 + dev: false + /convert-source-map@2.0.0: resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} dev: true @@ -5905,10 +5870,22 @@ packages: p-locate: 5.0.0 dev: true + /lodash.camelcase@4.3.0: + resolution: {integrity: sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==} + dev: false + + /lodash.forown@4.4.0: + resolution: {integrity: sha512-xcpca6BCshoe5SFSrQOoV8FBEbNzcBa6QQYmtv48eEFNzdwQLkHkcWSaBlecHhyHb1BUk1xqFdXoiSLJkt/w5w==} + dev: false + /lodash.isequal@4.5.0: resolution: {integrity: sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ==} dev: false + /lodash.isplainobject@4.0.6: + resolution: {integrity: sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==} + dev: false + /lodash.memoize@4.1.2: resolution: {integrity: sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==} dev: true @@ -5917,6 +5894,10 @@ packages: resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} dev: true + /lodash.snakecase@4.1.1: + resolution: {integrity: sha512-QZ1d4xoBHYUeuouhEq3lk3Uq7ldgyFXGBhg04+oRLnIz8o9T65Eh+8YdroUwn846zchkA9yDsDl5CVVaV2nqYw==} + dev: false + /lodash.startcase@4.4.0: resolution: {integrity: sha512-+WKqsK294HMSc2jEbNgpHpd0JfIBhp7rEV4aqXWqFr6AlXov+SlcgB1Fv01y2kGe3Gc8nMW7VA0SrGuSkRfIEg==} dev: true @@ -6881,18 +6862,6 @@ packages: resolution: {integrity: sha512-r5a3l5HzYlIC68TpmYKlxWjmOP6wiPJ1vWv2HeLhNsRZMrCkxeqxiHlQ21oXmQ4F3SiryXBHhAD7JZqvOJjFmg==} dev: true - /rgbpp@0.3.0(@ckb-lumos/lumos@0.22.0-next.5)(lodash@4.17.21): - resolution: {integrity: sha512-SvvQsTwcTpxedKhzKY+fJQCavfnO2wtyAgO6zkuXBxveLKQQrsvCNumhwzfLOkZW8PhEDz4qAks3WhYnyOR2Vw==} - dependencies: - '@rgbpp-sdk/btc': 0.3.0(@ckb-lumos/lumos@0.22.0-next.5) - '@rgbpp-sdk/ckb': 0.3.0(@ckb-lumos/lumos@0.22.0-next.5)(lodash@4.17.21) - '@rgbpp-sdk/service': 0.3.0 - transitivePeerDependencies: - - '@ckb-lumos/lumos' - - debug - - lodash - dev: false - /rimraf@3.0.2: resolution: {integrity: sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==} deprecated: Rimraf versions prior to v4 are no longer supported From ba80fea5e65992cf6d9e48aace20a56dae871970 Mon Sep 17 00:00:00 2001 From: Dylan Duan Date: Wed, 5 Jun 2024 17:44:18 +0800 Subject: [PATCH 30/90] feat: Update sendRgbppCkbTransaction request type --- packages/service/src/types/rgbpp.ts | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/packages/service/src/types/rgbpp.ts b/packages/service/src/types/rgbpp.ts index 3f42bb5a..c3090f23 100644 --- a/packages/service/src/types/rgbpp.ts +++ b/packages/service/src/types/rgbpp.ts @@ -57,12 +57,15 @@ export interface RgbppApiSpvProof { export interface RgbppApiSendCkbTransactionPayload { btc_txid: string; - ckb_virtual_result: { - ckbRawTx: CKBComponents.RawTransaction; - needPaymasterCell: boolean; - sumInputsCapacity: string; - commitment: string; - }; + // Support ckbVirtaulTxResult and it's JSON string as request parameter + ckb_virtual_result: + | { + ckbRawTx: CKBComponents.RawTransaction; + needPaymasterCell: boolean; + sumInputsCapacity: string; + commitment: string; + } + | string; } export interface RgbppApiRetryCkbTransactionPayload { From f1a4f817b67cd05b3a770bf2323d3c725a7ca2c1 Mon Sep 17 00:00:00 2001 From: Dylan Duan Date: Wed, 5 Jun 2024 17:47:33 +0800 Subject: [PATCH 31/90] feat: Add reportRgbppCkbTxBtcTxId RPC --- apps/service/package.json | 4 ++-- apps/service/src/app.module.ts | 15 +++++---------- apps/service/src/rgbpp/rgbpp.service.ts | 23 ++++++++++++++++++----- apps/service/src/rgbpp/types.ts | 9 ++++++++- 4 files changed, 33 insertions(+), 18 deletions(-) diff --git a/apps/service/package.json b/apps/service/package.json index 62ca8ea3..23e7ba1e 100644 --- a/apps/service/package.json +++ b/apps/service/package.json @@ -7,13 +7,13 @@ "license": "UNLICENSED", "scripts": { "build": "nest build", - "format": "prettier --write \"src/**/*.ts\" \"test/**/*.ts\"", + "format": "prettier --write \"src/**/*.ts\"", "dev": "pnpm run start:dev", "start": "nest start", "start:dev": "nest start --watch", "start:debug": "nest start --debug --watch", "start:prod": "node dist/main", - "lint": "eslint \"{src,apps,libs,test}/**/*.ts\" --fix", + "lint": "eslint \"src/**/*.ts\" --fix", "test": "jest", "test:watch": "jest --watch", "test:cov": "jest --coverage", diff --git a/apps/service/src/app.module.ts b/apps/service/src/app.module.ts index ec0cdfd5..6d2da414 100644 --- a/apps/service/src/app.module.ts +++ b/apps/service/src/app.module.ts @@ -5,9 +5,7 @@ import { RgbppModule } from './rgbpp/rgbpp.module'; import { AppService } from './app.service'; import { envSchema } from './env'; import { Collector } from 'rgbpp/ckb'; -import { BtcAssetsApi, DataSource, NetworkType } from 'rgbpp'; - -const parseNetwork = (configService: ConfigService): boolean => configService.get('NETWORK') === 'mainnet'; +import { BtcAssetsApi } from 'rgbpp'; @Global() @Module({ @@ -24,7 +22,7 @@ const parseNetwork = (configService: ConfigService): boolean => configService.ge AppService, { provide: 'IS_MAINNET', - useFactory: parseNetwork, + useFactory: (configService: ConfigService): boolean => configService.get('NETWORK') === 'mainnet', inject: [ConfigService], }, { @@ -39,19 +37,16 @@ const parseNetwork = (configService: ConfigService): boolean => configService.ge inject: [ConfigService], }, { - provide: 'BTC_DATA_SOURCE', + provide: 'BTC_ASSETS_API', useFactory: (configService: ConfigService) => { const url = configService.get('BTC_SERVICE_URL'); const token = configService.get('BTC_SERVICE_TOKEN'); const origin = configService.get('BTC_SERVICE_ORIGIN'); - const btcAssestApi = BtcAssetsApi.fromToken(url, token, origin); - const networkType = parseNetwork(configService) ? NetworkType.MAINNET : NetworkType.TESTNET; - const dataSource = new DataSource(btcAssestApi, networkType); - return dataSource; + return BtcAssetsApi.fromToken(url, token, origin); }, inject: [ConfigService], }, ], - exports: ['IS_MAINNET', 'COLLECTOR', 'BTC_DATA_SOURCE'], + exports: ['IS_MAINNET', 'COLLECTOR', 'BTC_ASSETS_API'], }) export class AppModule {} diff --git a/apps/service/src/rgbpp/rgbpp.service.ts b/apps/service/src/rgbpp/rgbpp.service.ts index 3331891e..4dccebe4 100644 --- a/apps/service/src/rgbpp/rgbpp.service.ts +++ b/apps/service/src/rgbpp/rgbpp.service.ts @@ -1,23 +1,26 @@ import { Inject } from '@nestjs/common'; import { RpcHandler, RpcMethodHandler } from 'src/json-rpc/json-rpc.decorators'; -import { DataSource } from 'rgbpp/btc'; +import { DataSource, NetworkType } from 'rgbpp/btc'; import { Collector, toCamelcase } from 'rgbpp/ckb'; -import { RgbppTransferReq, RgbppTransferResp } from './types'; +import { RgbppTransferReq, RgbppCkbBtcTransaction, RgbppCkbTxBtcTxId } from './types'; import { toSnakeCase } from 'src/utils/snake'; import { buildRgbppTransferTx } from 'rgbpp'; +import { BtcAssetsApi } from 'rgbpp/service'; @RpcHandler() export class RgbppService { constructor( @Inject('IS_MAINNET') private isMainnet: boolean, @Inject('COLLECTOR') private collector: Collector, - @Inject('BTC_DATA_SOURCE') private btcDataSource: DataSource, + @Inject('BTC_ASSETS_API') private btcAssetsApi: BtcAssetsApi, ) {} @RpcMethodHandler({ name: 'generate_rgbpp_transfer_tx' }) public async generateRgbppTransferTx(request: object[]) { const { xudtTypeArgs, rgbppLockArgsList, transferAmount, fromBtcAddress, toBtcAddress } = toCamelcase(request[0]); + const networkType = this.isMainnet ? NetworkType.MAINNET : NetworkType.TESTNET; + const btcDataSource = new DataSource(this.btcAssetsApi, networkType); const { ckbVirtualTxResult, btcPsbtHex } = await buildRgbppTransferTx({ collector: this.collector, xudtTypeArgs, @@ -25,13 +28,23 @@ export class RgbppService { transferAmount: BigInt(transferAmount), fromBtcAddress, toBtcAddress, - btcDataSource: this.btcDataSource, + btcDataSource, isMainnet: this.isMainnet, }); - const response: RgbppTransferResp = { + const response: RgbppCkbBtcTransaction = { ckbVirtualTxResult: JSON.stringify(ckbVirtualTxResult), btcPsbtHex, }; return toSnakeCase(response); } + + @RpcMethodHandler({ name: 'report_rgbpp_ckb_tx_btc_txid' }) + public async reportRgbppCkbTxBtcTxId(request: object[]) { + const { ckbVirtualTxResult, btcTxId } = toCamelcase(request[0]); + const { state } = await this.btcAssetsApi.sendRgbppCkbTransaction({ + btc_txid: btcTxId, + ckb_virtual_result: ckbVirtualTxResult, + }); + return state; + } } diff --git a/apps/service/src/rgbpp/types.ts b/apps/service/src/rgbpp/types.ts index a92f4e9b..fee1f2de 100644 --- a/apps/service/src/rgbpp/types.ts +++ b/apps/service/src/rgbpp/types.ts @@ -13,9 +13,16 @@ export interface RgbppTransferReq { toBtcAddress: string; } -export interface RgbppTransferResp { +export interface RgbppCkbBtcTransaction { // The JSON string for the `BtcTransferVirtualTxResult` ckbVirtualTxResult: string; // The BTC PSBT hex string which can be used to construct Bitcoin PSBT btcPsbtHex: Hex; } + +export interface RgbppCkbTxBtcTxId { + // The JSON string for the `BtcTransferVirtualTxResult` + ckbVirtualTxResult: string; + // The BTC transaction id of the RGB++ operations + btcTxId: Hex; +} From f0d77f7eb11677cad9b0e9136bd3e2232d43b7dc Mon Sep 17 00:00:00 2001 From: Dylan Duan Date: Wed, 5 Jun 2024 17:56:30 +0800 Subject: [PATCH 32/90] feat: Add getRgbppTxState RPC --- apps/service/src/rgbpp/rgbpp.service.ts | 11 +++++++++-- apps/service/src/rgbpp/types.ts | 5 +++++ 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/apps/service/src/rgbpp/rgbpp.service.ts b/apps/service/src/rgbpp/rgbpp.service.ts index 4dccebe4..43255f87 100644 --- a/apps/service/src/rgbpp/rgbpp.service.ts +++ b/apps/service/src/rgbpp/rgbpp.service.ts @@ -2,10 +2,10 @@ import { Inject } from '@nestjs/common'; import { RpcHandler, RpcMethodHandler } from 'src/json-rpc/json-rpc.decorators'; import { DataSource, NetworkType } from 'rgbpp/btc'; import { Collector, toCamelcase } from 'rgbpp/ckb'; -import { RgbppTransferReq, RgbppCkbBtcTransaction, RgbppCkbTxBtcTxId } from './types'; +import { RgbppTransferReq, RgbppCkbBtcTransaction, RgbppCkbTxBtcTxId, RgbppStateReq } from './types'; import { toSnakeCase } from 'src/utils/snake'; import { buildRgbppTransferTx } from 'rgbpp'; -import { BtcAssetsApi } from 'rgbpp/service'; +import { BtcAssetsApi, RgbppApiTransactionState } from 'rgbpp/service'; @RpcHandler() export class RgbppService { @@ -47,4 +47,11 @@ export class RgbppService { }); return state; } + + @RpcMethodHandler({ name: 'get_rgbpp_tx_state' }) + public async getRgbppTxState(request: object[]): Promise { + const { btcTxId, withData } = toCamelcase(request[0]); + const response = await this.btcAssetsApi.getRgbppTransactionState(btcTxId, { withData }); + return response; + } } diff --git a/apps/service/src/rgbpp/types.ts b/apps/service/src/rgbpp/types.ts index fee1f2de..e4ea8ff7 100644 --- a/apps/service/src/rgbpp/types.ts +++ b/apps/service/src/rgbpp/types.ts @@ -26,3 +26,8 @@ export interface RgbppCkbTxBtcTxId { // The BTC transaction id of the RGB++ operations btcTxId: Hex; } + +export interface RgbppStateReq { + btcTxId: Hex; + withData?: boolean; +} From 0601496be29ea1aee3f340198d8b59661f477305 Mon Sep 17 00:00:00 2001 From: Dylan Duan Date: Thu, 6 Jun 2024 10:34:01 +0800 Subject: [PATCH 33/90] fix: Update RgbppApiTransactionStateParams with_data --- packages/service/src/types/rgbpp.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/service/src/types/rgbpp.ts b/packages/service/src/types/rgbpp.ts index c3090f23..a356c964 100644 --- a/packages/service/src/types/rgbpp.ts +++ b/packages/service/src/types/rgbpp.ts @@ -24,7 +24,7 @@ export interface RgbppApiCkbTransactionHash { } export interface RgbppApiTransactionStateParams { - withData?: boolean; + with_data?: boolean; } export interface RgbppApiTransactionState { From e50b2049ca7c72871335be1357a6490f55b7e6da Mon Sep 17 00:00:00 2001 From: Dylan Duan Date: Thu, 6 Jun 2024 10:39:25 +0800 Subject: [PATCH 34/90] refactor: Add withData to rgbpp state getting api --- apps/service/src/rgbpp/rgbpp.service.ts | 7 +++++-- apps/service/src/rgbpp/types.ts | 4 +++- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/apps/service/src/rgbpp/rgbpp.service.ts b/apps/service/src/rgbpp/rgbpp.service.ts index 43255f87..3831813b 100644 --- a/apps/service/src/rgbpp/rgbpp.service.ts +++ b/apps/service/src/rgbpp/rgbpp.service.ts @@ -50,8 +50,11 @@ export class RgbppService { @RpcMethodHandler({ name: 'get_rgbpp_tx_state' }) public async getRgbppTxState(request: object[]): Promise { - const { btcTxId, withData } = toCamelcase(request[0]); - const response = await this.btcAssetsApi.getRgbppTransactionState(btcTxId, { withData }); + const { + btcTxId, + params: { withData }, + } = toCamelcase(request[0]); + const response = await this.btcAssetsApi.getRgbppTransactionState(btcTxId, { with_data: withData }); return response; } } diff --git a/apps/service/src/rgbpp/types.ts b/apps/service/src/rgbpp/types.ts index e4ea8ff7..dfd2a54d 100644 --- a/apps/service/src/rgbpp/types.ts +++ b/apps/service/src/rgbpp/types.ts @@ -29,5 +29,7 @@ export interface RgbppCkbTxBtcTxId { export interface RgbppStateReq { btcTxId: Hex; - withData?: boolean; + params?: { + withData?: boolean; + }; } From ba84dc7d09ed4010fbecce92d627320c46788eff Mon Sep 17 00:00:00 2001 From: ahonn Date: Thu, 6 Jun 2024 19:07:23 +1000 Subject: [PATCH 35/90] feat: use fastify instead of express --- apps/service/package.json | 1 + apps/service/src/main.ts | 3 +- pnpm-lock.yaml | 319 ++++++++++++++++++++++++++++++++++++-- 3 files changed, 309 insertions(+), 14 deletions(-) diff --git a/apps/service/package.json b/apps/service/package.json index 23e7ba1e..28917173 100644 --- a/apps/service/package.json +++ b/apps/service/package.json @@ -25,6 +25,7 @@ "@nestjs/config": "^3.2.2", "@nestjs/core": "^10.0.0", "@nestjs/platform-express": "^10.0.0", + "@nestjs/platform-fastify": "^10.3.9", "convert-keys": "^1.3.4", "json-rpc-2.0": "^1.7.0", "reflect-metadata": "^0.2.0", diff --git a/apps/service/src/main.ts b/apps/service/src/main.ts index b7ad93dc..c536bd53 100644 --- a/apps/service/src/main.ts +++ b/apps/service/src/main.ts @@ -1,10 +1,11 @@ import { NestFactory } from '@nestjs/core'; import { AppModule } from './app.module'; import { Logger } from '@nestjs/common'; +import { FastifyAdapter, NestFastifyApplication } from '@nestjs/platform-fastify'; async function bootstrap() { const logger = new Logger('AppBootstrap'); - const app = await NestFactory.create(AppModule); + const app = await NestFactory.create(AppModule, new FastifyAdapter()); await app.listen(3000); logger.log('Application is running on: http://localhost:3000'); } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 4db629cc..3718d268 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -62,6 +62,9 @@ importers: '@nestjs/platform-express': specifier: ^10.0.0 version: 10.3.9(@nestjs/common@10.3.9)(@nestjs/core@10.3.9) + '@nestjs/platform-fastify': + specifier: ^10.3.9 + version: 10.3.9(@nestjs/common@10.3.9)(@nestjs/core@10.3.9) convert-keys: specifier: ^1.3.4 version: 1.3.4 @@ -1388,6 +1391,53 @@ packages: engines: {node: '>=16.0.0', npm: '>=8.0.0'} dev: false + /@fastify/ajv-compiler@3.5.0: + resolution: {integrity: sha512-ebbEtlI7dxXF5ziNdr05mOY8NnDiPB1XvAlLHctRt/Rc+C3LCOVW5imUVX+mhvUhnNzmPBHewUkOFgGlCxgdAA==} + dependencies: + ajv: 8.12.0 + ajv-formats: 2.1.1(ajv@8.12.0) + fast-uri: 2.3.1 + dev: false + + /@fastify/cors@9.0.1: + resolution: {integrity: sha512-YY9Ho3ovI+QHIL2hW+9X4XqQjXLjJqsU+sMV/xFsxZkE8p3GNnYVFpoOxF7SsP5ZL76gwvbo3V9L+FIekBGU4Q==} + dependencies: + fastify-plugin: 4.5.1 + mnemonist: 0.39.6 + dev: false + + /@fastify/error@3.4.1: + resolution: {integrity: sha512-wWSvph+29GR783IhmvdwWnN4bUxTD01Vm5Xad4i7i1VuAOItLvbPAb69sb0IQ2N57yprvhNIwAP5B6xfKTmjmQ==} + dev: false + + /@fastify/fast-json-stringify-compiler@4.3.0: + resolution: {integrity: sha512-aZAXGYo6m22Fk1zZzEUKBvut/CIIQe/BapEORnxiD5Qr0kPHqqI69NtEMCme74h+at72sPhbkb4ZrLd1W3KRLA==} + dependencies: + fast-json-stringify: 5.16.0 + dev: false + + /@fastify/formbody@7.4.0: + resolution: {integrity: sha512-H3C6h1GN56/SMrZS8N2vCT2cZr7mIHzBHzOBa5OPpjfB/D6FzP9mMpE02ZzrFX0ANeh0BAJdoXKOF2e7IbV+Og==} + dependencies: + fast-querystring: 1.1.2 + fastify-plugin: 4.5.1 + dev: false + + /@fastify/merge-json-schemas@0.1.1: + resolution: {integrity: sha512-fERDVz7topgNjtXsJTTW1JKLy0rhuLRcquYqNR9rF7OcVpCa2OVW49ZPDIhaRRCaUuvVxI+N416xUoF76HNSXA==} + dependencies: + fast-deep-equal: 3.1.3 + dev: false + + /@fastify/middie@8.3.1: + resolution: {integrity: sha512-qrQ8U3iCdjNum3+omnIvAyz21ifFx+Pp5jYW7PJJ7b9ueKTCPXsH6vEvaZQrjEZvOpTnWte+CswfBODWD0NqYQ==} + dependencies: + '@fastify/error': 3.4.1 + fastify-plugin: 4.5.1 + path-to-regexp: 6.2.2 + reusify: 1.0.4 + dev: false + /@humanwhocodes/config-array@0.11.14: resolution: {integrity: sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==} engines: {node: '>=10.10.0'} @@ -1881,6 +1931,30 @@ packages: transitivePeerDependencies: - supports-color + /@nestjs/platform-fastify@10.3.9(@nestjs/common@10.3.9)(@nestjs/core@10.3.9): + resolution: {integrity: sha512-bw/RjGjGQsUwTlHFgSYQv58XKSti6in/X6d32G7LYemh7NYzeEhiHjtYay/TpvNkhqW6mrMrX3GYvl8WVH96TQ==} + peerDependencies: + '@fastify/static': ^6.0.0 || ^7.0.0 + '@fastify/view': ^7.0.0 || ^8.0.0 + '@nestjs/common': ^10.0.0 + '@nestjs/core': ^10.0.0 + peerDependenciesMeta: + '@fastify/static': + optional: true + '@fastify/view': + optional: true + dependencies: + '@fastify/cors': 9.0.1 + '@fastify/formbody': 7.4.0 + '@fastify/middie': 8.3.1 + '@nestjs/common': 10.3.9(reflect-metadata@0.2.2)(rxjs@7.8.1) + '@nestjs/core': 10.3.9(@nestjs/common@10.3.9)(@nestjs/platform-express@10.3.9)(reflect-metadata@0.2.2)(rxjs@7.8.1) + fastify: 4.27.0 + light-my-request: 5.13.0 + path-to-regexp: 3.2.0 + tslib: 2.6.2 + dev: false + /@nestjs/schematics@10.1.1(chokidar@3.6.0)(typescript@5.3.3): resolution: {integrity: sha512-o4lfCnEeIkfJhGBbLZxTuVWcGuqDCFwg5OrvpgRUBM7vI/vONvKKiB5riVNpO+JqXoH0I42NNeDb0m4V5RREig==} peerDependencies: @@ -2696,6 +2770,10 @@ packages: event-target-shim: 5.0.1 dev: false + /abstract-logging@2.0.1: + resolution: {integrity: sha512-2BjRTZxTPvheOvGbBslFSYOUkr+SjPtOnrLP33f+VIWLzezQpZcqVg7ja3L4dBXmzzgwT+a029jRx5PCi3JuiA==} + dev: false + /accepts@1.3.8: resolution: {integrity: sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==} engines: {node: '>= 0.6'} @@ -2739,7 +2817,17 @@ packages: optional: true dependencies: ajv: 8.12.0 - dev: true + + /ajv-formats@3.0.1(ajv@8.12.0): + resolution: {integrity: sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==} + peerDependencies: + ajv: ^8.0.0 + peerDependenciesMeta: + ajv: + optional: true + dependencies: + ajv: 8.12.0 + dev: false /ajv-keywords@3.5.2(ajv@6.12.6): resolution: {integrity: sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==} @@ -2765,7 +2853,6 @@ packages: json-schema-traverse: 1.0.0 require-from-string: 2.0.2 uri-js: 4.4.1 - dev: true /ansi-colors@4.1.3: resolution: {integrity: sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==} @@ -2902,6 +2989,11 @@ packages: /asynckit@0.4.0: resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} + /atomic-sleep@1.0.0: + resolution: {integrity: sha512-kNOjDqAh7px0XWNI+4QbzoiR/nTkHAWNud2uvnJquD1/x5a7EQZMJT0AczqK0Qn67oY/TTQ1LbUKajZpp3I9tQ==} + engines: {node: '>=8.0.0'} + dev: false + /available-typed-arrays@1.0.7: resolution: {integrity: sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==} engines: {node: '>= 0.4'} @@ -2909,6 +3001,13 @@ packages: possible-typed-array-names: 1.0.0 dev: true + /avvio@8.3.2: + resolution: {integrity: sha512-st8e519GWHa/azv8S87mcJvZs4WsgTBjOw/Ih1CP6u+8SZvcOeAYNG6JbsIrAUUJJ7JfmrnOkR8ipDS+u9SIRQ==} + dependencies: + '@fastify/error': 3.4.1 + fastq: 1.17.1 + dev: false + /axios@1.6.7: resolution: {integrity: sha512-/hDJGff6/c7u0hDkvkGxR/oy6CbCs8ziCsC7SqmhjfozqiJGc8Z11wrv9z9lYfY4K8l+H9TpjcMDX0xOZmx+RA==} dependencies: @@ -4309,9 +4408,16 @@ packages: tmp: 0.0.33 dev: true + /fast-content-type-parse@1.1.0: + resolution: {integrity: sha512-fBHHqSTFLVnR61C+gltJuE5GkVQMV0S2nqUO8TJ+5Z3qAKG8vAx4FKai1s5jq/inV1+sREynIWSuQ6HgoSXpDQ==} + dev: false + + /fast-decode-uri-component@1.0.1: + resolution: {integrity: sha512-WKgKWg5eUxvRZGwW8FvfbaH7AXSh2cL+3j5fMGzUMCxWBJ3dV3a7Wz8y2f/uQ0e3B6WmodD3oS54jTQ9HVTIIg==} + dev: false + /fast-deep-equal@3.1.3: resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} - dev: true /fast-glob@3.3.2: resolution: {integrity: sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==} @@ -4328,18 +4434,69 @@ packages: resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} dev: true + /fast-json-stringify@5.16.0: + resolution: {integrity: sha512-A4bg6E15QrkuVO3f0SwIASgzMzR6XC4qTyTqhf3hYXy0iazbAdZKwkE+ox4WgzKyzM6ygvbdq3r134UjOaaAnA==} + dependencies: + '@fastify/merge-json-schemas': 0.1.1 + ajv: 8.12.0 + ajv-formats: 3.0.1(ajv@8.12.0) + fast-deep-equal: 3.1.3 + fast-uri: 2.3.1 + json-schema-ref-resolver: 1.0.1 + rfdc: 1.3.1 + dev: false + /fast-levenshtein@2.0.6: resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==} dev: true + /fast-querystring@1.1.2: + resolution: {integrity: sha512-g6KuKWmFXc0fID8WWH0jit4g0AGBoJhCkJMb1RmbsSEUNvQ+ZC8D6CUZ+GtF8nMzSPXnhiePyyqqipzNNEnHjg==} + dependencies: + fast-decode-uri-component: 1.0.1 + dev: false + + /fast-redact@3.5.0: + resolution: {integrity: sha512-dwsoQlS7h9hMeYUq1W++23NDcBLV4KqONnITDV9DjfS3q1SgDGVrBdvvTLUotWtPSD7asWDV9/CmsZPy8Hf70A==} + engines: {node: '>=6'} + dev: false + /fast-safe-stringify@2.1.1: resolution: {integrity: sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==} + /fast-uri@2.3.1: + resolution: {integrity: sha512-iC7SLdMJx2KGdBkhJ6UulbNfpeIGTMS3/OIJpPa1JkZu9DKVQmPtBBme9Esoa4XP2eLGaHBv4vzRqlolXKo9cg==} + dev: false + + /fastify-plugin@4.5.1: + resolution: {integrity: sha512-stRHYGeuqpEZTL1Ef0Ovr2ltazUT9g844X5z/zEBFLG8RYlpDiOCIG+ATvYEp+/zmc7sN29mcIMp8gvYplYPIQ==} + dev: false + + /fastify@4.27.0: + resolution: {integrity: sha512-ci9IXzbigB8dyi0mSy3faa3Bsj0xWAPb9JeT4KRzubdSb6pNhcADRUaXCBml6V1Ss/a05kbtQls5LBmhHydoTA==} + dependencies: + '@fastify/ajv-compiler': 3.5.0 + '@fastify/error': 3.4.1 + '@fastify/fast-json-stringify-compiler': 4.3.0 + abstract-logging: 2.0.1 + avvio: 8.3.2 + fast-content-type-parse: 1.1.0 + fast-json-stringify: 5.16.0 + find-my-way: 8.2.0 + light-my-request: 5.13.0 + pino: 9.1.0 + process-warning: 3.0.0 + proxy-addr: 2.0.7 + rfdc: 1.3.1 + secure-json-parse: 2.7.0 + semver: 7.6.0 + toad-cache: 3.7.0 + dev: false + /fastq@1.17.1: resolution: {integrity: sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==} dependencies: reusify: 1.0.4 - dev: true /fb-watchman@2.0.2: resolution: {integrity: sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==} @@ -4390,6 +4547,15 @@ packages: transitivePeerDependencies: - supports-color + /find-my-way@8.2.0: + resolution: {integrity: sha512-HdWXgFYc6b1BJcOBDBwjqWuHJj1WYiqrxSh25qtU4DabpMFdj/gSunNBQb83t+8Zt67D7CXEzJWTkxaShMTMOA==} + engines: {node: '>=14'} + dependencies: + fast-deep-equal: 3.1.3 + fast-querystring: 1.1.2 + safe-regex2: 3.1.0 + dev: false + /find-up@4.1.0: resolution: {integrity: sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==} engines: {node: '>=8'} @@ -5719,13 +5885,18 @@ packages: resolution: {integrity: sha512-asnLgC1qD5ytP+fvBP8uL0rvj+l8P6iYICbzZ8dVxCpESffVjzA7KkYkbKCIbavs7cllwH1ZUaNtJwphdeRqpg==} dev: false + /json-schema-ref-resolver@1.0.1: + resolution: {integrity: sha512-EJAj1pgHc1hxF6vo2Z3s69fMjO1INq6eGHXZ8Z6wCQeldCuwxGK9Sxf4/cScGn3FZubCVUehfWtcDM/PLteCQw==} + dependencies: + fast-deep-equal: 3.1.3 + dev: false + /json-schema-traverse@0.4.1: resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} dev: true /json-schema-traverse@1.0.0: resolution: {integrity: sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==} - dev: true /json-stable-stringify-without-jsonify@1.0.1: resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==} @@ -5793,6 +5964,14 @@ packages: type-check: 0.4.0 dev: true + /light-my-request@5.13.0: + resolution: {integrity: sha512-9IjUN9ZyCS9pTG+KqTDEQo68Sui2lHsYBrfMyVUTTZ3XhH8PMZq7xO94Kr+eP9dhi/kcKsx4N41p2IXEBil1pQ==} + dependencies: + cookie: 0.6.0 + process-warning: 3.0.0 + set-cookie-parser: 2.6.0 + dev: false + /lilconfig@3.0.0: resolution: {integrity: sha512-K2U4W2Ff5ibV7j7ydLr+zLAkIg5JJ4lPn1Ltsdt+Tz/IjQ8buJ55pZAxoP34lqIiwtF9iAvtLv3JGv7CAyAg+g==} engines: {node: '>=14'} @@ -5953,7 +6132,6 @@ packages: engines: {node: '>=10'} dependencies: yallist: 4.0.0 - dev: true /magic-string@0.30.5: resolution: {integrity: sha512-7xlpfBaQaP/T6Vh8MO/EqXSW5En6INHEvEXQiuff7Gku0PWjU3uf6w/j9o7O+SpB5fOAkrI5HeoNgwjEO0pFsA==} @@ -6161,6 +6339,12 @@ packages: ufo: 1.5.2 dev: true + /mnemonist@0.39.6: + resolution: {integrity: sha512-A/0v5Z59y63US00cRSLiloEIw3t5G+MiKz4BhX21FI+YBJXBOGW0ohFxTxO08dsOYlzxo87T7vGfZKYp2bcAWA==} + dependencies: + obliterator: 2.0.4 + dev: false + /moo@0.5.2: resolution: {integrity: sha512-iSAJLHYKnX41mKcJKjqvnAN9sf0LMDTXDEvFv+ffuRR9a1MIuXLjMNL6EsnDHSkKLTWNqQQ5uo61P4EbU4NU+Q==} dev: true @@ -6307,6 +6491,15 @@ packages: object-keys: 1.1.1 dev: true + /obliterator@2.0.4: + resolution: {integrity: sha512-lgHwxlxV1qIg1Eap7LgIeoBWIMFibOjbrYPIPJZcI1mmGAI2m3lNYpK12Y+GBdPQ0U1hRwSord7GIaawz962qQ==} + dev: false + + /on-exit-leak-free@2.1.2: + resolution: {integrity: sha512-0eJJY6hXLGf1udHwfNftBqH+g73EU4B504nZeKpz1sYRKafAghwxEJunB2O7rDZkL4PGfsMVnTXZ2EjibbqcsA==} + engines: {node: '>=14.0.0'} + dev: false + /on-finished@2.4.1: resolution: {integrity: sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==} engines: {node: '>= 0.8'} @@ -6479,6 +6672,10 @@ packages: /path-to-regexp@3.2.0: resolution: {integrity: sha512-jczvQbCUS7XmS7o+y1aEO9OBVFeZBQ1MDSEqmO7xSoPgOPoowY/SxLpZ6Vh97/8qHZOteiCKb7gkG9gA2ZUxJA==} + /path-to-regexp@6.2.2: + resolution: {integrity: sha512-GQX3SSMokngb36+whdpRXE+3f9V8UzyAorlYvOGx87ufGHehNTn5lCxrKtLyZ4Yl/wEKnNnr98ZzOwwDZV5ogw==} + dev: false + /path-type@4.0.0: resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} engines: {node: '>=8'} @@ -6517,6 +6714,34 @@ packages: engines: {node: '>=6'} dev: true + /pino-abstract-transport@1.2.0: + resolution: {integrity: sha512-Guhh8EZfPCfH+PMXAb6rKOjGQEoy0xlAIn+irODG5kgfYV+BQ0rGYYWTIel3P5mmyXqkYkPmdIkywsn6QKUR1Q==} + dependencies: + readable-stream: 4.5.2 + split2: 4.2.0 + dev: false + + /pino-std-serializers@7.0.0: + resolution: {integrity: sha512-e906FRY0+tV27iq4juKzSYPbUj2do2X2JX4EzSca1631EB2QJQUqGbDuERal7LCtOpxl6x3+nvo9NPZcmjkiFA==} + dev: false + + /pino@9.1.0: + resolution: {integrity: sha512-qUcgfrlyOtjwhNLdbhoL7NR4NkHjzykAPw0V2QLFbvu/zss29h4NkRnibyFzBrNCbzCOY3WZ9hhKSwfOkNggYA==} + hasBin: true + dependencies: + atomic-sleep: 1.0.0 + fast-redact: 3.5.0 + on-exit-leak-free: 2.1.2 + pino-abstract-transport: 1.2.0 + pino-std-serializers: 7.0.0 + process-warning: 3.0.0 + quick-format-unescaped: 4.0.4 + real-require: 0.2.0 + safe-stable-stringify: 2.4.3 + sonic-boom: 4.0.1 + thread-stream: 3.0.2 + dev: false + /pirates@4.0.6: resolution: {integrity: sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==} engines: {node: '>= 6'} @@ -6595,6 +6820,15 @@ packages: /process-nextick-args@2.0.1: resolution: {integrity: sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==} + /process-warning@3.0.0: + resolution: {integrity: sha512-mqn0kFRl0EoqhnL0GQ0veqFHyIN1yig9RHh/InzORTUiZHFRAur+aMtRkELNwGs9aNwKS6tg/An4NYBPGwvtzQ==} + dev: false + + /process@0.11.10: + resolution: {integrity: sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==} + engines: {node: '>= 0.6.0'} + dev: false + /prompts@2.4.2: resolution: {integrity: sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==} engines: {node: '>= 6'} @@ -6621,7 +6855,6 @@ packages: /punycode@2.3.1: resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} engines: {node: '>=6'} - dev: true /pure-rand@6.1.0: resolution: {integrity: sha512-bVWawvoZoBYpp6yIoQtQXHZjmz35RSVHnUOTefl8Vcjr8snTPY1wnpSPMWekcFwbxI6gtmT7rSYPFvz71ldiOA==} @@ -6644,6 +6877,10 @@ packages: resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} dev: true + /quick-format-unescaped@4.0.4: + resolution: {integrity: sha512-tYC1Q1hgyRuHgloV/YXs2w15unPVh8qfu/qCTfhTYamaw7fyhumKa2yGpdSo87vY32rIclj+4fWYQXUMs9EHvg==} + dev: false + /quick-lru@4.0.1: resolution: {integrity: sha512-ARhCpm70fzdcvNQfPoy49IaanKkTlRWF2JMzqhcJbhSFRZv7nPTvZJdcY7301IPmvW+/p0RgIWnQDLJxifsQ7g==} engines: {node: '>=8'} @@ -6736,6 +6973,17 @@ packages: string_decoder: 1.3.0 util-deprecate: 1.0.2 + /readable-stream@4.5.2: + resolution: {integrity: sha512-yjavECdqeZ3GLXNgRXgeQEdz9fvDDkNKyHnbHRFtOr7/LcfgBcmct7t/ET+HaCTqfh06OzoAxrkN/IfjJBVe+g==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + dependencies: + abort-controller: 3.0.0 + buffer: 6.0.3 + events: 3.3.0 + process: 0.11.10 + string_decoder: 1.3.0 + dev: false + /readdirp@3.6.0: resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==} engines: {node: '>=8.10.0'} @@ -6743,6 +6991,11 @@ packages: picomatch: 2.3.1 dev: true + /real-require@0.2.0: + resolution: {integrity: sha512-57frrGM/OCTLqLOAh0mhVA9VBMHd+9U7Zb2THMGdBUoZVOtGbJzjxsYGDJ3A9AYYCP4hn6y1TVbaOfzWtm5GFg==} + engines: {node: '>= 12.13.0'} + dev: false + /rechoir@0.6.2: resolution: {integrity: sha512-HFM8rkZ+i3zrV+4LQjwQ0W+ez98pApMGM3HUrN04j3CqzPOzl9nmP15Y8YXNm8QHGv/eacOVEjqhmWpkRV0NAw==} engines: {node: '>= 0.10'} @@ -6795,7 +7048,6 @@ packages: /require-from-string@2.0.2: resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==} engines: {node: '>=0.10.0'} - dev: true /require-main-filename@2.0.0: resolution: {integrity: sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==} @@ -6853,14 +7105,17 @@ packages: engines: {node: '>=0.12'} dev: true + /ret@0.4.3: + resolution: {integrity: sha512-0f4Memo5QP7WQyUEAYUO3esD/XjOc3Zjjg5CPsAq1p8sIu0XPeMbHJemKA0BO7tV0X7+A0FoEpbmHXWxPyD3wQ==} + engines: {node: '>=10'} + dev: false + /reusify@1.0.4: resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==} engines: {iojs: '>=1.0.0', node: '>=0.10.0'} - dev: true /rfdc@1.3.1: resolution: {integrity: sha512-r5a3l5HzYlIC68TpmYKlxWjmOP6wiPJ1vWv2HeLhNsRZMrCkxeqxiHlQ21oXmQ4F3SiryXBHhAD7JZqvOJjFmg==} - dev: true /rimraf@3.0.2: resolution: {integrity: sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==} @@ -6964,6 +7219,17 @@ packages: is-regex: 1.1.4 dev: true + /safe-regex2@3.1.0: + resolution: {integrity: sha512-RAAZAGbap2kBfbVhvmnTFv73NWLMvDGOITFYTZBAaY8eR+Ir4ef7Up/e7amo+y1+AH+3PtLkrt9mvcTsG9LXug==} + dependencies: + ret: 0.4.3 + dev: false + + /safe-stable-stringify@2.4.3: + resolution: {integrity: sha512-e2bDA2WJT0wxseVd4lsDP4+3ONX6HpMXQa1ZhFQ7SU+GjvORCmShbCMltrtIDfkYhVHrOcPtj+KhmDBdPdZD1g==} + engines: {node: '>=10'} + dev: false + /safer-buffer@2.1.2: resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} @@ -6980,6 +7246,10 @@ packages: resolution: {integrity: sha512-cdwTTnqPu0Hyvf5in5asVdZocVDTNRmR7XEcJuIzMjJeSHybHl7vpB66AzwTaIg6CLSbtjcxc8fqcySfnTkccA==} dev: false + /secure-json-parse@2.7.0: + resolution: {integrity: sha512-6aU+Rwsezw7VR8/nyvKTx8QpWH9FrcYiXXlqC4z5d5XQBDRqtbfsRjnwGyqbi3gddNtWHuEk9OANUotL26qKUw==} + dev: false + /semver@5.7.2: resolution: {integrity: sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==} hasBin: true @@ -6996,7 +7266,6 @@ packages: hasBin: true dependencies: lru-cache: 6.0.0 - dev: true /send@0.18.0: resolution: {integrity: sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==} @@ -7039,6 +7308,10 @@ packages: resolution: {integrity: sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==} dev: true + /set-cookie-parser@2.6.0: + resolution: {integrity: sha512-RVnVQxTXuerk653XfuliOxBP81Sf0+qfQE73LIYKcyMYHG94AuH0kgrQpRDuTZnSmjpysHmzxJXKNfa6PjFhyQ==} + dev: false + /set-function-length@1.2.2: resolution: {integrity: sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==} engines: {node: '>= 0.4'} @@ -7171,6 +7444,12 @@ packages: yargs: 15.4.1 dev: true + /sonic-boom@4.0.1: + resolution: {integrity: sha512-hTSD/6JMLyT4r9zeof6UtuBDpjJ9sO08/nmS5djaA9eozT9oOlNdpXSnzcgj4FTqpk3nkLrs61l4gip9r1HCrQ==} + dependencies: + atomic-sleep: 1.0.0 + dev: false + /source-map-js@1.2.0: resolution: {integrity: sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==} engines: {node: '>=0.10.0'} @@ -7229,6 +7508,11 @@ packages: resolution: {integrity: sha512-sh8PWc/ftMqAAdFiBu6Fy6JUOYjqDJBJvIhpfDMyHrr0Rbp5liZqd4TjtQ/RgfLjKFZb+LMx5hpml5qOWy0qvg==} dev: true + /split2@4.2.0: + resolution: {integrity: sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==} + engines: {node: '>= 10.x'} + dev: false + /sprintf-js@1.0.3: resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==} dev: true @@ -7532,6 +7816,12 @@ packages: resolution: {integrity: sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==} dev: true + /thread-stream@3.0.2: + resolution: {integrity: sha512-cBL4xF2A3lSINV4rD5tyqnKH4z/TgWPvT+NaVhJDSwK962oo/Ye7cHSMbDzwcu7tAE1SfU6Q4XtV6Hucmi6Hlw==} + dependencies: + real-require: 0.2.0 + dev: false + /through@2.3.8: resolution: {integrity: sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==} dev: true @@ -7573,6 +7863,11 @@ packages: is-number: 7.0.0 dev: true + /toad-cache@3.7.0: + resolution: {integrity: sha512-/m8M+2BJUpoJdgAHoG+baCwBT+tf2VraSfkBgl0Y00qIWt41DJ8R5B8nsEw0I58YwF5IZH6z24/2TobDKnqSWw==} + engines: {node: '>=12'} + dev: false + /toidentifier@1.0.1: resolution: {integrity: sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==} engines: {node: '>=0.6'} @@ -7951,7 +8246,6 @@ packages: resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} dependencies: punycode: 2.3.1 - dev: true /util-deprecate@1.0.2: resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} @@ -8366,7 +8660,6 @@ packages: /yallist@4.0.0: resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==} - dev: true /yaml@2.3.4: resolution: {integrity: sha512-8aAvwVUSHpfEqTQ4w/KMlf3HcRdt50E5ODIQJBw1fQ5RL34xabzxtUlzTXVqc4rkZsPbvrXKWnABCD7kWSmocA==} From ea56aaefbb72e6ca8666ecfbd9af4f35bef75947 Mon Sep 17 00:00:00 2001 From: Dylan Duan Date: Thu, 6 Jun 2024 17:40:30 +0800 Subject: [PATCH 36/90] refactor: Update reportRgbppCkbTxBtcTxId response --- apps/service/src/rgbpp/rgbpp.service.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/apps/service/src/rgbpp/rgbpp.service.ts b/apps/service/src/rgbpp/rgbpp.service.ts index 3831813b..2661393d 100644 --- a/apps/service/src/rgbpp/rgbpp.service.ts +++ b/apps/service/src/rgbpp/rgbpp.service.ts @@ -39,13 +39,13 @@ export class RgbppService { } @RpcMethodHandler({ name: 'report_rgbpp_ckb_tx_btc_txid' }) - public async reportRgbppCkbTxBtcTxId(request: object[]) { + public async reportRgbppCkbTxBtcTxId(request: object[]): Promise { const { ckbVirtualTxResult, btcTxId } = toCamelcase(request[0]); - const { state } = await this.btcAssetsApi.sendRgbppCkbTransaction({ + const response = await this.btcAssetsApi.sendRgbppCkbTransaction({ btc_txid: btcTxId, ckb_virtual_result: ckbVirtualTxResult, }); - return state; + return response; } @RpcMethodHandler({ name: 'get_rgbpp_tx_state' }) From 06bfe3257a972281ecf50d318129835776b39d06 Mon Sep 17 00:00:00 2001 From: Dylan Duan Date: Thu, 6 Jun 2024 20:22:42 +0800 Subject: [PATCH 37/90] chore: Remove useless dependices --- apps/service/package.json | 2 - pnpm-lock.yaml | 462 +++----------------------------------- 2 files changed, 31 insertions(+), 433 deletions(-) diff --git a/apps/service/package.json b/apps/service/package.json index 28917173..e052a7be 100644 --- a/apps/service/package.json +++ b/apps/service/package.json @@ -24,7 +24,6 @@ "@nestjs/common": "^10.0.0", "@nestjs/config": "^3.2.2", "@nestjs/core": "^10.0.0", - "@nestjs/platform-express": "^10.0.0", "@nestjs/platform-fastify": "^10.3.9", "convert-keys": "^1.3.4", "json-rpc-2.0": "^1.7.0", @@ -37,7 +36,6 @@ "@nestjs/cli": "^10.0.0", "@nestjs/schematics": "^10.0.0", "@nestjs/testing": "^10.0.0", - "@types/express": "^4.17.17", "@types/jest": "^29.5.2", "@types/node": "^20.3.1", "@types/supertest": "^6.0.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 3718d268..2ceefae9 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -58,10 +58,7 @@ importers: version: 3.2.2(@nestjs/common@10.3.9)(rxjs@7.8.1) '@nestjs/core': specifier: ^10.0.0 - version: 10.3.9(@nestjs/common@10.3.9)(@nestjs/platform-express@10.3.9)(reflect-metadata@0.2.2)(rxjs@7.8.1) - '@nestjs/platform-express': - specifier: ^10.0.0 - version: 10.3.9(@nestjs/common@10.3.9)(@nestjs/core@10.3.9) + version: 10.3.9(@nestjs/common@10.3.9)(reflect-metadata@0.2.2)(rxjs@7.8.1) '@nestjs/platform-fastify': specifier: ^10.3.9 version: 10.3.9(@nestjs/common@10.3.9)(@nestjs/core@10.3.9) @@ -92,10 +89,7 @@ importers: version: 10.1.1(typescript@5.4.3) '@nestjs/testing': specifier: ^10.0.0 - version: 10.3.9(@nestjs/common@10.3.9)(@nestjs/core@10.3.9)(@nestjs/platform-express@10.3.9) - '@types/express': - specifier: ^4.17.17 - version: 4.17.21 + version: 10.3.9(@nestjs/common@10.3.9)(@nestjs/core@10.3.9) '@types/jest': specifier: ^29.5.2 version: 29.5.12 @@ -1884,7 +1878,7 @@ packages: uuid: 9.0.1 dev: false - /@nestjs/core@10.3.9(@nestjs/common@10.3.9)(@nestjs/platform-express@10.3.9)(reflect-metadata@0.2.2)(rxjs@7.8.1): + /@nestjs/core@10.3.9(@nestjs/common@10.3.9)(reflect-metadata@0.2.2)(rxjs@7.8.1): resolution: {integrity: sha512-NzZUfWAmaf8sqhhwoRA+CuqxQe+P4Rz8PZp5U7CdCbjyeB9ZVGcBkihcJC9wMdtiOWHRndB2J8zRfs5w06jK3w==} requiresBuild: true peerDependencies: @@ -1903,7 +1897,6 @@ packages: optional: true dependencies: '@nestjs/common': 10.3.9(reflect-metadata@0.2.2)(rxjs@7.8.1) - '@nestjs/platform-express': 10.3.9(@nestjs/common@10.3.9)(@nestjs/core@10.3.9) '@nuxtjs/opencollective': 0.3.2 fast-safe-stringify: 2.1.1 iterare: 1.2.1 @@ -1915,22 +1908,6 @@ packages: transitivePeerDependencies: - encoding - /@nestjs/platform-express@10.3.9(@nestjs/common@10.3.9)(@nestjs/core@10.3.9): - resolution: {integrity: sha512-si/UzobP6YUtYtCT1cSyQYHHzU3yseqYT6l7OHSMVvfG1+TqxaAqI6nmrix02LO+l1YntHRXEs3p+v9a7EfrSQ==} - peerDependencies: - '@nestjs/common': ^10.0.0 - '@nestjs/core': ^10.0.0 - dependencies: - '@nestjs/common': 10.3.9(reflect-metadata@0.2.2)(rxjs@7.8.1) - '@nestjs/core': 10.3.9(@nestjs/common@10.3.9)(@nestjs/platform-express@10.3.9)(reflect-metadata@0.2.2)(rxjs@7.8.1) - body-parser: 1.20.2 - cors: 2.8.5 - express: 4.19.2 - multer: 1.4.4-lts.1 - tslib: 2.6.2 - transitivePeerDependencies: - - supports-color - /@nestjs/platform-fastify@10.3.9(@nestjs/common@10.3.9)(@nestjs/core@10.3.9): resolution: {integrity: sha512-bw/RjGjGQsUwTlHFgSYQv58XKSti6in/X6d32G7LYemh7NYzeEhiHjtYay/TpvNkhqW6mrMrX3GYvl8WVH96TQ==} peerDependencies: @@ -1948,7 +1925,7 @@ packages: '@fastify/formbody': 7.4.0 '@fastify/middie': 8.3.1 '@nestjs/common': 10.3.9(reflect-metadata@0.2.2)(rxjs@7.8.1) - '@nestjs/core': 10.3.9(@nestjs/common@10.3.9)(@nestjs/platform-express@10.3.9)(reflect-metadata@0.2.2)(rxjs@7.8.1) + '@nestjs/core': 10.3.9(@nestjs/common@10.3.9)(reflect-metadata@0.2.2)(rxjs@7.8.1) fastify: 4.27.0 light-my-request: 5.13.0 path-to-regexp: 3.2.0 @@ -1985,7 +1962,7 @@ packages: - chokidar dev: true - /@nestjs/testing@10.3.9(@nestjs/common@10.3.9)(@nestjs/core@10.3.9)(@nestjs/platform-express@10.3.9): + /@nestjs/testing@10.3.9(@nestjs/common@10.3.9)(@nestjs/core@10.3.9): resolution: {integrity: sha512-z24SdpZIRtYyM5s2vnu7rbBosXJY/KcAP7oJlwgFa/h/z/wg8gzyoKy5lhibH//OZNO+pYKajV5wczxuy5WeAg==} peerDependencies: '@nestjs/common': ^10.0.0 @@ -1999,8 +1976,7 @@ packages: optional: true dependencies: '@nestjs/common': 10.3.9(reflect-metadata@0.2.2)(rxjs@7.8.1) - '@nestjs/core': 10.3.9(@nestjs/common@10.3.9)(@nestjs/platform-express@10.3.9)(reflect-metadata@0.2.2)(rxjs@7.8.1) - '@nestjs/platform-express': 10.3.9(@nestjs/common@10.3.9)(@nestjs/core@10.3.9) + '@nestjs/core': 10.3.9(@nestjs/common@10.3.9)(reflect-metadata@0.2.2)(rxjs@7.8.1) tslib: 2.6.2 dev: true @@ -2251,19 +2227,6 @@ packages: resolution: {integrity: sha512-MFCdX0MNxFBP/xEILO5Td0kv6nI7+Q2iRWZbTL/yzH2/eDVZS5Wd1LHdsmXClvsCyzqaZfHFzZaN6BUeUCfSDA==} dev: false - /@types/body-parser@1.19.5: - resolution: {integrity: sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg==} - dependencies: - '@types/connect': 3.4.38 - '@types/node': 20.12.12 - dev: true - - /@types/connect@3.4.38: - resolution: {integrity: sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==} - dependencies: - '@types/node': 20.12.12 - dev: true - /@types/cookiejar@2.1.5: resolution: {integrity: sha512-he+DHOWReW0nghN24E1WUqM0efK4kI9oTqDm6XmK8ZPe2djZ90BSNdGnIyCLzCPw7/pogPlGbzI2wHGGmi4O/Q==} dev: true @@ -2297,24 +2260,6 @@ packages: resolution: {integrity: sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==} dev: true - /@types/express-serve-static-core@4.19.3: - resolution: {integrity: sha512-KOzM7MhcBFlmnlr/fzISFF5vGWVSvN6fTd4T+ExOt08bA/dA5kpSzY52nMsI1KDFmUREpJelPYyuslLRSjjgCg==} - dependencies: - '@types/node': 20.12.12 - '@types/qs': 6.9.15 - '@types/range-parser': 1.2.7 - '@types/send': 0.17.4 - dev: true - - /@types/express@4.17.21: - resolution: {integrity: sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ==} - dependencies: - '@types/body-parser': 1.19.5 - '@types/express-serve-static-core': 4.19.3 - '@types/qs': 6.9.15 - '@types/serve-static': 1.15.7 - dev: true - /@types/fs-extra@11.0.4: resolution: {integrity: sha512-yTbItCNreRooED33qjunPthRcSjERP1r4MqCZc7wv0u2sUkzTFp45tgUfS5+r7FrZPdmCCNflLhVSP/o+SemsQ==} requiresBuild: true @@ -2330,10 +2275,6 @@ packages: '@types/node': 20.12.12 dev: true - /@types/http-errors@2.0.4: - resolution: {integrity: sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA==} - dev: true - /@types/istanbul-lib-coverage@2.0.6: resolution: {integrity: sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==} dev: true @@ -2382,10 +2323,6 @@ packages: resolution: {integrity: sha512-ymXWVrDiCxTBE3+RIrrP533E70eA+9qu7zdWoHuOmGujkYtzf4HQF96b8nwHLqhuf4ykX61IGRIB38CC6/sImQ==} dev: true - /@types/mime@1.3.5: - resolution: {integrity: sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==} - dev: true - /@types/minimist@1.2.5: resolution: {integrity: sha512-hov8bUuiLiyFPGyFPE1lwWhmzYbirOXQNNo40+y3zow8aFVTeyn3VWL0VFFfdNddA8S4Vf0Tc062rzyNr7Paag==} dev: true @@ -2418,33 +2355,10 @@ packages: resolution: {integrity: sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA==} dev: true - /@types/qs@6.9.15: - resolution: {integrity: sha512-uXHQKES6DQKKCLh441Xv/dwxOq1TVS3JPUMlEqoEglvlhR6Mxnlew/Xq/LRVHpLyk7iK3zODe1qYHIMltO7XGg==} - dev: true - - /@types/range-parser@1.2.7: - resolution: {integrity: sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==} - dev: true - /@types/semver@7.5.8: resolution: {integrity: sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ==} dev: true - /@types/send@0.17.4: - resolution: {integrity: sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA==} - dependencies: - '@types/mime': 1.3.5 - '@types/node': 20.12.12 - dev: true - - /@types/serve-static@1.15.7: - resolution: {integrity: sha512-W8Ym+h8nhuRwaKPaDw34QUkwsGi6Rc4yYqvKFo5rm2FUEhCFbzVWrxXUxuKK8TASjWsysJY0nsmNCGhCOIsrOw==} - dependencies: - '@types/http-errors': 2.0.4 - '@types/node': 20.12.12 - '@types/send': 0.17.4 - dev: true - /@types/stack-utils@2.0.3: resolution: {integrity: sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==} dev: true @@ -2774,13 +2688,6 @@ packages: resolution: {integrity: sha512-2BjRTZxTPvheOvGbBslFSYOUkr+SjPtOnrLP33f+VIWLzezQpZcqVg7ja3L4dBXmzzgwT+a029jRx5PCi3JuiA==} dev: false - /accepts@1.3.8: - resolution: {integrity: sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==} - engines: {node: '>= 0.6'} - dependencies: - mime-types: 2.1.35 - negotiator: 0.6.3 - /acorn-import-assertions@1.9.0(acorn@8.11.3): resolution: {integrity: sha512-cmMwop9x+8KFhxvKrKfPYmN6/pKTYYHBqLa0DfvVZcKMJWNyWLnaqND7dx/qn66R7ewM1UX5XMaDVP5wlVTaVA==} peerDependencies: @@ -2912,9 +2819,6 @@ packages: picomatch: 2.3.1 dev: true - /append-field@1.0.0: - resolution: {integrity: sha512-klpgFSWLW1ZEs8svjfb7g4qWY0YS5imI82dTg+QahUvJ8YqAY0P10Uk8tTyh9ZGuYEZEMaeJYCF5BFuX552hsw==} - /arg@4.1.3: resolution: {integrity: sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==} dev: true @@ -2937,9 +2841,6 @@ packages: is-array-buffer: 3.0.4 dev: true - /array-flatten@1.1.1: - resolution: {integrity: sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==} - /array-timsort@1.0.3: resolution: {integrity: sha512-/+3GRL7dDAGEfM6TseQk/U+mi18TU2Ms9I3UlLdUMhz2hbvGNTKdj9xniwXfUqgYhHxRx0+8UnKkvlNwVU+cWQ==} dev: true @@ -3194,25 +3095,6 @@ packages: resolution: {integrity: sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==} dev: false - /body-parser@1.20.2: - resolution: {integrity: sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA==} - engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16} - dependencies: - bytes: 3.1.2 - content-type: 1.0.5 - debug: 2.6.9 - depd: 2.0.0 - destroy: 1.2.0 - http-errors: 2.0.0 - iconv-lite: 0.4.24 - on-finished: 2.4.1 - qs: 6.11.0 - raw-body: 2.5.2 - type-is: 1.6.18 - unpipe: 1.0.0 - transitivePeerDependencies: - - supports-color - /brace-expansion@1.1.11: resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} dependencies: @@ -3296,6 +3178,7 @@ packages: /buffer-from@1.1.2: resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} + dev: true /buffer@5.7.1: resolution: {integrity: sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==} @@ -3311,16 +3194,6 @@ packages: ieee754: 1.2.1 dev: false - /busboy@1.6.0: - resolution: {integrity: sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==} - engines: {node: '>=10.16.0'} - dependencies: - streamsearch: 1.1.0 - - /bytes@3.1.2: - resolution: {integrity: sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==} - engines: {node: '>= 0.8'} - /cac@6.7.14: resolution: {integrity: sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==} engines: {node: '>=8'} @@ -3335,6 +3208,7 @@ packages: function-bind: 1.1.2 get-intrinsic: 1.2.4 set-function-length: 1.2.2 + dev: true /callsites@3.1.0: resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} @@ -3597,28 +3471,9 @@ packages: resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} dev: true - /concat-stream@1.6.2: - resolution: {integrity: sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==} - engines: {'0': node >= 0.8} - dependencies: - buffer-from: 1.1.2 - inherits: 2.0.4 - readable-stream: 2.3.8 - typedarray: 0.0.6 - /consola@2.15.3: resolution: {integrity: sha512-9vAdYbHj6x2fLKC4+oPH0kFzY/orMZyG2Aj+kNylHxKGJ/Ed4dpNyAQYwJOdqO4zdM7XpVHmyejQDcQHrnuXbw==} - /content-disposition@0.5.4: - resolution: {integrity: sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==} - engines: {node: '>= 0.6'} - dependencies: - safe-buffer: 5.2.1 - - /content-type@1.0.5: - resolution: {integrity: sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==} - engines: {node: '>= 0.6'} - /convert-keys@1.3.4: resolution: {integrity: sha512-+ltki+EUagotW/x7r+15nuHyk4nzcSkBk1lZpmbHjscF2E9ZmNErgV7K18LNshB0qglECcsnwy29ODlJ0pI0KA==} dependencies: @@ -3632,12 +3487,10 @@ packages: resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} dev: true - /cookie-signature@1.0.6: - resolution: {integrity: sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==} - /cookie@0.6.0: resolution: {integrity: sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==} engines: {node: '>= 0.6'} + dev: false /cookiejar@2.1.4: resolution: {integrity: sha512-LDx6oHrK+PhzLKJU9j5S7/Y3jM/mUHvD/DeI1WQmJn652iPC5Y4TBzC9l+5OMOXlyTTA+SmVUPm0HQUwpD5Jqw==} @@ -3645,13 +3498,7 @@ packages: /core-util-is@1.0.3: resolution: {integrity: sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==} - - /cors@2.8.5: - resolution: {integrity: sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==} - engines: {node: '>= 0.10'} - dependencies: - object-assign: 4.1.1 - vary: 1.1.2 + dev: true /cosmiconfig@8.3.6(typescript@5.3.3): resolution: {integrity: sha512-kcZ6+W5QzcJ3P1Mt+83OUv/oHFqZHIx8DuxG6eZ5RGMERoLqp4BuGjhHLYGK+Kf5XVkQvqBSmAy/nGWN3qDgEA==} @@ -3780,16 +3627,6 @@ packages: resolution: {integrity: sha512-68s5jYdlvasItOJnCuI2Q9s4q98g0pCyL3HrcKJu8KNugUl8ahgmZYg38ysLTgQjjXX3H8CJLkAvWrclWfcalw==} dev: true - /debug@2.6.9: - resolution: {integrity: sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==} - peerDependencies: - supports-color: '*' - peerDependenciesMeta: - supports-color: - optional: true - dependencies: - ms: 2.0.0 - /debug@4.3.4: resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==} engines: {node: '>=6.0'} @@ -3857,6 +3694,7 @@ packages: es-define-property: 1.0.0 es-errors: 1.3.0 gopd: 1.0.1 + dev: true /define-properties@1.2.1: resolution: {integrity: sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==} @@ -3871,14 +3709,6 @@ packages: resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} engines: {node: '>=0.4.0'} - /depd@2.0.0: - resolution: {integrity: sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==} - engines: {node: '>= 0.8'} - - /destroy@1.2.0: - resolution: {integrity: sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==} - engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16} - /detect-indent@6.1.0: resolution: {integrity: sha512-reYkTUJAZb9gUuZ2RvVCNhVHdg62RHnJ7WJl8ftMi4diZ6NWlciOzQN88pUhSELEwflJht4oQDv0F0BMlwaYtA==} engines: {node: '>=8'} @@ -3946,9 +3776,6 @@ packages: wif: 2.0.6 dev: false - /ee-first@1.1.1: - resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==} - /electron-to-chromium@1.4.710: resolution: {integrity: sha512-w+9yAVHoHhysCa+gln7AzbO9CdjFcL/wN/5dd+XW/Msl2d/4+WisEaCF1nty0xbAKaxdaJfgLB2296U7zZB7BA==} dev: true @@ -3994,10 +3821,6 @@ packages: resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} dev: true - /encodeurl@1.0.2: - resolution: {integrity: sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==} - engines: {node: '>= 0.8'} - /enhanced-resolve@5.16.1: resolution: {integrity: sha512-4U5pNsuDl0EhuZpq46M5xPslstkviJuhrdobaRDBk2Jy2KO37FDAJl4lb2KlNabxT0m4MTK2UHNrsAcphE8nyw==} engines: {node: '>=10.13.0'} @@ -4077,10 +3900,12 @@ packages: engines: {node: '>= 0.4'} dependencies: get-intrinsic: 1.2.4 + dev: true /es-errors@1.3.0: resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==} engines: {node: '>= 0.4'} + dev: true /es-module-lexer@1.5.3: resolution: {integrity: sha512-i1gCgmR9dCl6Vil6UKPI/trA69s08g/syhiDK9TG0Nf1RJjjFI+AzoWW7sPufzkgYAn861skuCwJa0pIIHYxvg==} @@ -4153,9 +3978,6 @@ packages: engines: {node: '>=6'} dev: true - /escape-html@1.0.3: - resolution: {integrity: sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==} - /escape-string-regexp@1.0.5: resolution: {integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==} engines: {node: '>=0.8.0'} @@ -4294,10 +4116,6 @@ packages: engines: {node: '>=0.10.0'} dev: true - /etag@1.8.1: - resolution: {integrity: sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==} - engines: {node: '>= 0.6'} - /event-target-shim@5.0.1: resolution: {integrity: sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==} engines: {node: '>=6'} @@ -4357,44 +4175,6 @@ packages: jest-util: 29.7.0 dev: true - /express@4.19.2: - resolution: {integrity: sha512-5T6nhjsT+EOMzuck8JjBHARTHfMht0POzlA60WV2pMD3gyXw2LZnZ+ueGdNxG+0calOJcWKbpFcuzLZ91YWq9Q==} - engines: {node: '>= 0.10.0'} - dependencies: - accepts: 1.3.8 - array-flatten: 1.1.1 - body-parser: 1.20.2 - content-disposition: 0.5.4 - content-type: 1.0.5 - cookie: 0.6.0 - cookie-signature: 1.0.6 - debug: 2.6.9 - depd: 2.0.0 - encodeurl: 1.0.2 - escape-html: 1.0.3 - etag: 1.8.1 - finalhandler: 1.2.0 - fresh: 0.5.2 - http-errors: 2.0.0 - merge-descriptors: 1.0.1 - methods: 1.1.2 - on-finished: 2.4.1 - parseurl: 1.3.3 - path-to-regexp: 0.1.7 - proxy-addr: 2.0.7 - qs: 6.11.0 - range-parser: 1.2.1 - safe-buffer: 5.2.1 - send: 0.18.0 - serve-static: 1.15.0 - setprototypeof: 1.2.0 - statuses: 2.0.1 - type-is: 1.6.18 - utils-merge: 1.0.1 - vary: 1.1.2 - transitivePeerDependencies: - - supports-color - /extendable-error@0.1.7: resolution: {integrity: sha512-UOiS2in6/Q0FK0R0q6UY9vYpQ21mr/Qn1KOnte7vsACuNJf514WvCCUHSRCPcgjPT2bAhNIJdlE6bVap1GKmeg==} dev: true @@ -4533,20 +4313,6 @@ packages: to-regex-range: 5.0.1 dev: true - /finalhandler@1.2.0: - resolution: {integrity: sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==} - engines: {node: '>= 0.8'} - dependencies: - debug: 2.6.9 - encodeurl: 1.0.2 - escape-html: 1.0.3 - on-finished: 2.4.1 - parseurl: 1.3.3 - statuses: 2.0.1 - unpipe: 1.0.0 - transitivePeerDependencies: - - supports-color - /find-my-way@8.2.0: resolution: {integrity: sha512-HdWXgFYc6b1BJcOBDBwjqWuHJj1WYiqrxSh25qtU4DabpMFdj/gSunNBQb83t+8Zt67D7CXEzJWTkxaShMTMOA==} engines: {node: '>=14'} @@ -4659,10 +4425,7 @@ packages: /forwarded@0.2.0: resolution: {integrity: sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==} engines: {node: '>= 0.6'} - - /fresh@0.5.2: - resolution: {integrity: sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==} - engines: {node: '>= 0.6'} + dev: false /fs-extra@10.1.0: resolution: {integrity: sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==} @@ -4709,6 +4472,7 @@ packages: /function-bind@1.1.2: resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} + dev: true /function.prototype.name@1.1.6: resolution: {integrity: sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg==} @@ -4752,6 +4516,7 @@ packages: has-proto: 1.0.3 has-symbols: 1.0.3 hasown: 2.0.2 + dev: true /get-package-type@0.1.0: resolution: {integrity: sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==} @@ -4876,6 +4641,7 @@ packages: resolution: {integrity: sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==} dependencies: get-intrinsic: 1.2.4 + dev: true /graceful-fs@4.2.11: resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} @@ -4916,14 +4682,17 @@ packages: resolution: {integrity: sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==} dependencies: es-define-property: 1.0.0 + dev: true /has-proto@1.0.3: resolution: {integrity: sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==} engines: {node: '>= 0.4'} + dev: true /has-symbols@1.0.3: resolution: {integrity: sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==} engines: {node: '>= 0.4'} + dev: true /has-tostringtag@1.0.2: resolution: {integrity: sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==} @@ -4953,6 +4722,7 @@ packages: engines: {node: '>= 0.4'} dependencies: function-bind: 1.1.2 + dev: true /hexoid@1.0.0: resolution: {integrity: sha512-QFLV0taWQOZtvIRIAdBChesmogZrtuXvVWsFHZTk2SU+anspqZ2vMnoLg7IE1+Uk16N19APic1BuF8bC8c2m5g==} @@ -4975,16 +4745,6 @@ packages: resolution: {integrity: sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==} dev: true - /http-errors@2.0.0: - resolution: {integrity: sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==} - engines: {node: '>= 0.8'} - dependencies: - depd: 2.0.0 - inherits: 2.0.4 - setprototypeof: 1.2.0 - statuses: 2.0.1 - toidentifier: 1.0.1 - /human-id@1.0.2: resolution: {integrity: sha512-UNopramDEhHJD+VR+ehk8rOslwSfByxPIZyJRfV739NDhN5LF1fa1MqnzKm2lGTQRjNrjK19Q5fhkgIfjlVUKw==} dev: true @@ -5010,6 +4770,7 @@ packages: engines: {node: '>=0.10.0'} dependencies: safer-buffer: 2.1.2 + dev: true /ieee754@1.2.1: resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} @@ -5119,6 +4880,7 @@ packages: /ipaddr.js@1.9.1: resolution: {integrity: sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==} engines: {node: '>= 0.10'} + dev: false /is-array-buffer@3.0.4: resolution: {integrity: sha512-wcjaerHw0ydZwfhiKbXJWLDY8A7yV7KhjQOpb83hGgGfId/aQa4TOvwyzn2PuswW2gPCYEL/nEAiSVpdOj1lXw==} @@ -5320,6 +5082,7 @@ packages: /isarray@1.0.0: resolution: {integrity: sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==} + dev: true /isarray@2.0.5: resolution: {integrity: sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==} @@ -6181,10 +5944,6 @@ packages: safe-buffer: 5.2.1 dev: false - /media-typer@0.3.0: - resolution: {integrity: sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==} - engines: {node: '>= 0.6'} - /memfs@3.5.3: resolution: {integrity: sha512-UERzLsxzllchadvbPs5aolHh65ISpKpM+ccLbOJ8/vvpBKmAWf+la7dXFy7Mr0ySHbdHrFv5kGFCUHHe6GFEmw==} engines: {node: '>= 4.0.0'} @@ -6209,9 +5968,6 @@ packages: yargs-parser: 18.1.3 dev: true - /merge-descriptors@1.0.1: - resolution: {integrity: sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==} - /merge-stream@2.0.0: resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==} dev: true @@ -6224,6 +5980,7 @@ packages: /methods@1.1.2: resolution: {integrity: sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==} engines: {node: '>= 0.6'} + dev: true /micromatch@4.0.5: resolution: {integrity: sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==} @@ -6243,11 +6000,6 @@ packages: dependencies: mime-db: 1.52.0 - /mime@1.6.0: - resolution: {integrity: sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==} - engines: {node: '>=4'} - hasBin: true - /mime@2.6.0: resolution: {integrity: sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==} engines: {node: '>=4.0.0'} @@ -6308,6 +6060,7 @@ packages: /minimist@1.2.8: resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} + dev: true /minipass@4.2.8: resolution: {integrity: sha512-fNzuVyifolSLFL4NzpF+wEF4qrgqaaKX0haXPQEdQ7NKAN+WecoKMHV09YcuL/DHxrUsYQOK3MiuDf7Ip2OXfQ==} @@ -6324,12 +6077,6 @@ packages: engines: {node: '>= 8.0.0'} dev: true - /mkdirp@0.5.6: - resolution: {integrity: sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==} - hasBin: true - dependencies: - minimist: 1.2.8 - /mlly@1.6.1: resolution: {integrity: sha512-vLgaHvaeunuOXHSmEbZ9izxPx3USsk8KCQ8iC+aTlp5sKRSoZvwhHh5L9VbKSaVC6sJDqbyohIS76E2VmHIPAA==} dependencies: @@ -6349,28 +6096,10 @@ packages: resolution: {integrity: sha512-iSAJLHYKnX41mKcJKjqvnAN9sf0LMDTXDEvFv+ffuRR9a1MIuXLjMNL6EsnDHSkKLTWNqQQ5uo61P4EbU4NU+Q==} dev: true - /ms@2.0.0: - resolution: {integrity: sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==} - /ms@2.1.2: resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==} dev: true - /ms@2.1.3: - resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} - - /multer@1.4.4-lts.1: - resolution: {integrity: sha512-WeSGziVj6+Z2/MwQo3GvqzgR+9Uc+qt8SwHKh3gvNPiISKfsMfG4SvCOFYlxxgkXt7yIV2i1yczehm0EOKIxIg==} - engines: {node: '>= 6.0.0'} - dependencies: - append-field: 1.0.0 - busboy: 1.6.0 - concat-stream: 1.6.2 - mkdirp: 0.5.6 - object-assign: 4.1.1 - type-is: 1.6.18 - xtend: 4.0.2 - /mute-stream@0.0.8: resolution: {integrity: sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==} dev: true @@ -6404,10 +6133,6 @@ packages: randexp: 0.4.6 dev: true - /negotiator@0.6.3: - resolution: {integrity: sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==} - engines: {node: '>= 0.6'} - /neo-async@2.6.2: resolution: {integrity: sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==} dev: true @@ -6469,12 +6194,9 @@ packages: path-key: 4.0.0 dev: true - /object-assign@4.1.1: - resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} - engines: {node: '>=0.10.0'} - /object-inspect@1.13.1: resolution: {integrity: sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==} + dev: true /object-keys@1.1.1: resolution: {integrity: sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==} @@ -6500,12 +6222,6 @@ packages: engines: {node: '>=14.0.0'} dev: false - /on-finished@2.4.1: - resolution: {integrity: sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==} - engines: {node: '>= 0.8'} - dependencies: - ee-first: 1.1.1 - /once@1.4.0: resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} dependencies: @@ -6630,10 +6346,6 @@ packages: lines-and-columns: 1.2.4 dev: true - /parseurl@1.3.3: - resolution: {integrity: sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==} - engines: {node: '>= 0.8'} - /path-exists@4.0.0: resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} engines: {node: '>=8'} @@ -6666,9 +6378,6 @@ packages: minipass: 7.0.4 dev: true - /path-to-regexp@0.1.7: - resolution: {integrity: sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==} - /path-to-regexp@3.2.0: resolution: {integrity: sha512-jczvQbCUS7XmS7o+y1aEO9OBVFeZBQ1MDSEqmO7xSoPgOPoowY/SxLpZ6Vh97/8qHZOteiCKb7gkG9gA2ZUxJA==} @@ -6817,9 +6526,6 @@ packages: react-is: 18.2.0 dev: true - /process-nextick-args@2.0.1: - resolution: {integrity: sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==} - /process-warning@3.0.0: resolution: {integrity: sha512-mqn0kFRl0EoqhnL0GQ0veqFHyIN1yig9RHh/InzORTUiZHFRAur+aMtRkELNwGs9aNwKS6tg/An4NYBPGwvtzQ==} dev: false @@ -6843,6 +6549,7 @@ packages: dependencies: forwarded: 0.2.0 ipaddr.js: 1.9.1 + dev: false /proxy-from-env@1.1.0: resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==} @@ -6860,12 +6567,6 @@ packages: resolution: {integrity: sha512-bVWawvoZoBYpp6yIoQtQXHZjmz35RSVHnUOTefl8Vcjr8snTPY1wnpSPMWekcFwbxI6gtmT7rSYPFvz71ldiOA==} dev: true - /qs@6.11.0: - resolution: {integrity: sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==} - engines: {node: '>=0.6'} - dependencies: - side-channel: 1.0.6 - /qs@6.12.0: resolution: {integrity: sha512-trVZiI6RMOkO476zLGaBIzszOdFPnCCXHPG9kn0yuS1uz6xdVxPfZdB3vUig9pxPFDM9BRAgz/YUIVQ1/vuiUg==} engines: {node: '>=0.6'} @@ -6908,19 +6609,6 @@ packages: dependencies: safe-buffer: 5.2.1 - /range-parser@1.2.1: - resolution: {integrity: sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==} - engines: {node: '>= 0.6'} - - /raw-body@2.5.2: - resolution: {integrity: sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==} - engines: {node: '>= 0.8'} - dependencies: - bytes: 3.1.2 - http-errors: 2.0.0 - iconv-lite: 0.4.24 - unpipe: 1.0.0 - /react-is@18.2.0: resolution: {integrity: sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==} dev: true @@ -6954,17 +6642,6 @@ packages: strip-bom: 3.0.0 dev: true - /readable-stream@2.3.8: - resolution: {integrity: sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==} - dependencies: - core-util-is: 1.0.3 - inherits: 2.0.4 - isarray: 1.0.0 - process-nextick-args: 2.0.1 - safe-buffer: 5.1.2 - string_decoder: 1.1.1 - util-deprecate: 1.0.2 - /readable-stream@3.6.2: resolution: {integrity: sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==} engines: {node: '>= 6'} @@ -7204,9 +6881,6 @@ packages: isarray: 2.0.5 dev: true - /safe-buffer@5.1.2: - resolution: {integrity: sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==} - /safe-buffer@5.2.1: resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} @@ -7232,6 +6906,7 @@ packages: /safer-buffer@2.1.2: resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} + dev: true /schema-utils@3.3.0: resolution: {integrity: sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==} @@ -7267,43 +6942,12 @@ packages: dependencies: lru-cache: 6.0.0 - /send@0.18.0: - resolution: {integrity: sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==} - engines: {node: '>= 0.8.0'} - dependencies: - debug: 2.6.9 - depd: 2.0.0 - destroy: 1.2.0 - encodeurl: 1.0.2 - escape-html: 1.0.3 - etag: 1.8.1 - fresh: 0.5.2 - http-errors: 2.0.0 - mime: 1.6.0 - ms: 2.1.3 - on-finished: 2.4.1 - range-parser: 1.2.1 - statuses: 2.0.1 - transitivePeerDependencies: - - supports-color - /serialize-javascript@6.0.2: resolution: {integrity: sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==} dependencies: randombytes: 2.1.0 dev: true - /serve-static@1.15.0: - resolution: {integrity: sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==} - engines: {node: '>= 0.8.0'} - dependencies: - encodeurl: 1.0.2 - escape-html: 1.0.3 - parseurl: 1.3.3 - send: 0.18.0 - transitivePeerDependencies: - - supports-color - /set-blocking@2.0.0: resolution: {integrity: sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==} dev: true @@ -7322,6 +6966,7 @@ packages: get-intrinsic: 1.2.4 gopd: 1.0.1 has-property-descriptors: 1.0.2 + dev: true /set-function-name@2.0.2: resolution: {integrity: sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==} @@ -7333,9 +6978,6 @@ packages: has-property-descriptors: 1.0.2 dev: true - /setprototypeof@1.2.0: - resolution: {integrity: sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==} - /sha.js@2.4.11: resolution: {integrity: sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==} hasBin: true @@ -7392,6 +7034,7 @@ packages: es-errors: 1.3.0 get-intrinsic: 1.2.4 object-inspect: 1.13.1 + dev: true /siginfo@2.0.0: resolution: {integrity: sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==} @@ -7528,10 +7171,6 @@ packages: resolution: {integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==} dev: true - /statuses@2.0.1: - resolution: {integrity: sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==} - engines: {node: '>= 0.8'} - /std-env@3.7.0: resolution: {integrity: sha512-JPbdCEQLj1w5GilpiHAx3qJvFndqybBysA3qUOnznweH4QbNYUsW/ea8QzSrnh0vNsezMMw5bcVool8lM0gwzg==} dev: true @@ -7542,10 +7181,6 @@ packages: mixme: 0.5.10 dev: true - /streamsearch@1.1.0: - resolution: {integrity: sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==} - engines: {node: '>=10.0.0'} - /string-argv@0.3.2: resolution: {integrity: sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q==} engines: {node: '>=0.6.19'} @@ -7613,11 +7248,6 @@ packages: es-object-atoms: 1.0.0 dev: true - /string_decoder@1.1.1: - resolution: {integrity: sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==} - dependencies: - safe-buffer: 5.1.2 - /string_decoder@1.3.0: resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==} dependencies: @@ -7868,10 +7498,6 @@ packages: engines: {node: '>=12'} dev: false - /toidentifier@1.0.1: - resolution: {integrity: sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==} - engines: {node: '>=0.6'} - /tr46@0.0.3: resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==} @@ -8119,13 +7745,6 @@ packages: engines: {node: '>=10'} dev: false - /type-is@1.6.18: - resolution: {integrity: sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==} - engines: {node: '>= 0.6'} - dependencies: - media-typer: 0.3.0 - mime-types: 2.1.35 - /typed-array-buffer@1.0.2: resolution: {integrity: sha512-gEymJYKZtKXzzBzM4jqa9w6Q1Jjm7x2d+sh19AdsD4wqnMPDYyvwpsIc2Q/835kHuo3BEQ7CjelGhfTsoBb2MQ==} engines: {node: '>= 0.4'} @@ -8170,9 +7789,6 @@ packages: possible-typed-array-names: 1.0.0 dev: true - /typedarray@0.0.6: - resolution: {integrity: sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==} - /typeforce@1.18.0: resolution: {integrity: sha512-7uc1O8h1M1g0rArakJdf0uLRSSgFcYexrVoKo+bzJd32gd4gDy2L/Z+8/FjPnU9ydY3pEnVPtr9FyscYY60K1g==} dev: false @@ -8227,10 +7843,6 @@ packages: engines: {node: '>= 10.0.0'} dev: true - /unpipe@1.0.0: - resolution: {integrity: sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==} - engines: {node: '>= 0.8'} - /update-browserslist-db@1.0.13(browserslist@4.23.0): resolution: {integrity: sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==} hasBin: true @@ -8250,10 +7862,6 @@ packages: /util-deprecate@1.0.2: resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} - /utils-merge@1.0.1: - resolution: {integrity: sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==} - engines: {node: '>= 0.4.0'} - /uuid@8.3.2: resolution: {integrity: sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==} hasBin: true @@ -8290,10 +7898,6 @@ packages: safe-buffer: 5.2.1 dev: false - /vary@1.1.2: - resolution: {integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==} - engines: {node: '>= 0.8'} - /vite-node@1.4.0(@types/node@20.12.12): resolution: {integrity: sha512-VZDAseqjrHgNd4Kh8icYHWzTKSCZMhia7GyHfhtzLW33fZlG9SwsB6CEhgyVOWkJfJ2pFLrp/Gj1FSfAiqH9Lw==} engines: {node: ^18.0.0 || >=20.0.0} @@ -8637,10 +8241,6 @@ packages: signal-exit: 3.0.7 dev: true - /xtend@4.0.2: - resolution: {integrity: sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==} - engines: {node: '>=0.4'} - /y18n@4.0.3: resolution: {integrity: sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==} dev: true From 41fa06e7d95db182db49070d84c08decf795ee6d Mon Sep 17 00:00:00 2001 From: Dylan Duan Date: Fri, 7 Jun 2024 15:50:46 +0800 Subject: [PATCH 38/90] feat: Add get_rgbpp_ckb_tx_hash RPC --- apps/service/src/rgbpp/rgbpp.service.ts | 39 ++++++++++++++++--------- apps/service/src/rgbpp/types.ts | 4 +++ 2 files changed, 29 insertions(+), 14 deletions(-) diff --git a/apps/service/src/rgbpp/rgbpp.service.ts b/apps/service/src/rgbpp/rgbpp.service.ts index 2661393d..da1f7754 100644 --- a/apps/service/src/rgbpp/rgbpp.service.ts +++ b/apps/service/src/rgbpp/rgbpp.service.ts @@ -1,11 +1,11 @@ import { Inject } from '@nestjs/common'; import { RpcHandler, RpcMethodHandler } from 'src/json-rpc/json-rpc.decorators'; import { DataSource, NetworkType } from 'rgbpp/btc'; -import { Collector, toCamelcase } from 'rgbpp/ckb'; -import { RgbppTransferReq, RgbppCkbBtcTransaction, RgbppCkbTxBtcTxId, RgbppStateReq } from './types'; +import { Collector, Hex, toCamelcase } from 'rgbpp/ckb'; +import { RgbppTransferReq, RgbppCkbBtcTransaction, RgbppCkbTxBtcTxId, RgbppStateReq, RgbppCkbTxHashReq } from './types'; import { toSnakeCase } from 'src/utils/snake'; import { buildRgbppTransferTx } from 'rgbpp'; -import { BtcAssetsApi, RgbppApiTransactionState } from 'rgbpp/service'; +import { BtcAssetsApi } from 'rgbpp/service'; @RpcHandler() export class RgbppService { @@ -22,13 +22,17 @@ export class RgbppService { const networkType = this.isMainnet ? NetworkType.MAINNET : NetworkType.TESTNET; const btcDataSource = new DataSource(this.btcAssetsApi, networkType); const { ckbVirtualTxResult, btcPsbtHex } = await buildRgbppTransferTx({ - collector: this.collector, - xudtTypeArgs, - rgbppLockArgsList, - transferAmount: BigInt(transferAmount), - fromBtcAddress, - toBtcAddress, - btcDataSource, + ckb: { + collector: this.collector, + xudtTypeArgs, + rgbppLockArgsList, + transferAmount: BigInt(transferAmount), + }, + btc: { + fromAddress: fromBtcAddress, + toAddress: toBtcAddress, + dataSource: btcDataSource, + }, isMainnet: this.isMainnet, }); const response: RgbppCkbBtcTransaction = { @@ -39,22 +43,29 @@ export class RgbppService { } @RpcMethodHandler({ name: 'report_rgbpp_ckb_tx_btc_txid' }) - public async reportRgbppCkbTxBtcTxId(request: object[]): Promise { + public async reportRgbppCkbTxBtcTxId(request: object[]) { const { ckbVirtualTxResult, btcTxId } = toCamelcase(request[0]); const response = await this.btcAssetsApi.sendRgbppCkbTransaction({ btc_txid: btcTxId, ckb_virtual_result: ckbVirtualTxResult, }); - return response; + return toSnakeCase(response); } @RpcMethodHandler({ name: 'get_rgbpp_tx_state' }) - public async getRgbppTxState(request: object[]): Promise { + public async getRgbppTxState(request: object[]) { const { btcTxId, params: { withData }, } = toCamelcase(request[0]); const response = await this.btcAssetsApi.getRgbppTransactionState(btcTxId, { with_data: withData }); - return response; + return toSnakeCase(response); + } + + @RpcMethodHandler({ name: 'get_rgbpp_ckb_tx_hash' }) + public async getRgbppCkbTxHash(request: object[]): Promise { + const { btcTxId } = toCamelcase(request[0]); + const { txhash: txHash } = await this.btcAssetsApi.getRgbppTransactionHash(btcTxId); + return txHash; } } diff --git a/apps/service/src/rgbpp/types.ts b/apps/service/src/rgbpp/types.ts index dfd2a54d..34913bcd 100644 --- a/apps/service/src/rgbpp/types.ts +++ b/apps/service/src/rgbpp/types.ts @@ -33,3 +33,7 @@ export interface RgbppStateReq { withData?: boolean; }; } + +export interface RgbppCkbTxHashReq { + btcTxId: Hex; +} From 3b076dcf5bdeb0823e557d11c43223ff57d39216 Mon Sep 17 00:00:00 2001 From: Dylan Duan Date: Fri, 7 Jun 2024 17:36:58 +0800 Subject: [PATCH 39/90] fix: Update start:prod script --- apps/service/README.md | 45 +++++++++++++++++++++++++++++++++++++++ apps/service/package.json | 2 +- 2 files changed, 46 insertions(+), 1 deletion(-) create mode 100644 apps/service/README.md diff --git a/apps/service/README.md b/apps/service/README.md new file mode 100644 index 00000000..b423c324 --- /dev/null +++ b/apps/service/README.md @@ -0,0 +1,45 @@ +# RGB++ SDK Service + + +## Quick Start + +### Clone rgbpp-sdk repository + +```shell +git clone https://github.com/ckb-cell/rgbpp-sdk.git +cd apps/service +``` + +### Update Environment Variables + +Copy the `.env.example` file to `.env`: + +```shell +cp .env.example .env +``` + +Update the configuration values: + +```yml +# testnet for CKB and BTC Testnet and mainnet for CKB and BTC Mainnet, the default value is testnet +NETWORK=testnet + +# CKB node url which should be matched with NETWORK +CKB_RPC_URL=https://testnet.ckb.dev + +# The BTC assets api url which should be matched with NETWORK +BTC_SERVICE_URL=https://btc-assets-api.testnet.mibao.pro + +# The BTC assets api token which should be matched with IS_MAINNET +# To get an access token, please refer to https://github.com/ckb-cell/rgbpp-sdk/tree/develop/packages/service#get-an-access-token +BTC_SERVICE_TOKEN= + +# The BTC assets api origin which should be matched with IS_MAINNET +BTC_SERVICE_ORIGIN=https://btc-assets-api.testnet.mibao.pro +``` + +### Run RGB++ SDK Service + +```shell +pnpm install && pnpm dev +``` \ No newline at end of file diff --git a/apps/service/package.json b/apps/service/package.json index e052a7be..bbd84af8 100644 --- a/apps/service/package.json +++ b/apps/service/package.json @@ -12,7 +12,7 @@ "start": "nest start", "start:dev": "nest start --watch", "start:debug": "nest start --debug --watch", - "start:prod": "node dist/main", + "start:prod": "node dist/src/main", "lint": "eslint \"src/**/*.ts\" --fix", "test": "jest", "test:watch": "jest --watch", From 018278d37ff74d87b0783617e60beb1798c8458a Mon Sep 17 00:00:00 2001 From: Dylan Duan Date: Fri, 7 Jun 2024 17:52:57 +0800 Subject: [PATCH 40/90] docs: Add sdk service readme --- apps/service/README.md | 36 +++++++++++++++++++++++++++++++----- 1 file changed, 31 insertions(+), 5 deletions(-) diff --git a/apps/service/README.md b/apps/service/README.md index b423c324..a87f854e 100644 --- a/apps/service/README.md +++ b/apps/service/README.md @@ -1,13 +1,15 @@ # RGB++ SDK Service +A RPC service for Wrapping essential RGB++ Assets Operations(**only support RGB++ Transfer on BTC now**) with [rgbpp-sdk](https://github.com/ckb-cell/rgbpp-sdk) for other programming languages to quickly manage RGB++ Assets. ## Quick Start ### Clone rgbpp-sdk repository ```shell -git clone https://github.com/ckb-cell/rgbpp-sdk.git -cd apps/service +$ git clone https://github.com/ckb-cell/rgbpp-sdk.git +$ pnpm install +$ cd apps/service ``` ### Update Environment Variables @@ -15,7 +17,7 @@ cd apps/service Copy the `.env.example` file to `.env`: ```shell -cp .env.example .env +$ cp .env.example .env ``` Update the configuration values: @@ -41,5 +43,29 @@ BTC_SERVICE_ORIGIN=https://btc-assets-api.testnet.mibao.pro ### Run RGB++ SDK Service ```shell -pnpm install && pnpm dev -``` \ No newline at end of file +# Debug environment +$ pnpm start:dev + +# Production environment +$ pnpm start:prod +``` + +## Deploy and Manage RGB++ SDK Service + +### 1. Use a process manager like PM2 + +- Install PM2 + +```shell +$ npm install -g pm2 +``` + +- Start RGB++ SDK Service with PM2 + +``` +$ pm2 start dist/src/main.js --name rgbpp-sdk-service +``` + +### 2. Use Docker + +TODO \ No newline at end of file From c67c3a3692b7b84e39cb172c42b3a0dd66b82f97 Mon Sep 17 00:00:00 2001 From: Dylan Duan Date: Sat, 8 Jun 2024 19:28:43 +0800 Subject: [PATCH 41/90] fix: Update inputs capacity for the xudt transfer tx --- examples/xudt-on-ckb/2-transfer-xudt.ts | 28 ++++++++++++------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/examples/xudt-on-ckb/2-transfer-xudt.ts b/examples/xudt-on-ckb/2-transfer-xudt.ts index c5d01e0a..dba100aa 100644 --- a/examples/xudt-on-ckb/2-transfer-xudt.ts +++ b/examples/xudt-on-ckb/2-transfer-xudt.ts @@ -54,7 +54,7 @@ const transferXudt = async ({ xudtType, receivers }: XudtTransferParams) => { let inputs = udtInputs; const xudtCapacity = calculateUdtCellCapacity(fromLock); - const sumXudtCapacity = xudtCapacity * BigInt(receivers.length); + let sumXudtoutputCapacity = xudtCapacity * BigInt(receivers.length); const outputs: CKBComponents.CellOutput[] = receivers.map((receiver) => ({ lock: addressToScript(receiver.toAddress), @@ -63,8 +63,18 @@ const transferXudt = async ({ xudtType, receivers }: XudtTransferParams) => { })); const outputsData = receivers.map((receiver) => append0x(u128ToLe(receiver.transferAmount))); + if (sumAmount > sumTransferAmount) { + outputs.push({ + lock: fromLock, + type: xudtType, + capacity: append0x(xudtCapacity.toString(16)), + }); + outputsData.push(append0x(u128ToLe(sumAmount - sumTransferAmount))); + sumXudtoutputCapacity += xudtCapacity; + } + const txFee = MAX_FEE; - if (sumXudtInputsCapacity < sumXudtCapacity) { + if (sumXudtInputsCapacity <= sumXudtoutputCapacity) { let emptyCells = await collector.getCells({ lock: fromLock, }); @@ -72,7 +82,7 @@ const transferXudt = async ({ xudtType, receivers }: XudtTransferParams) => { throw new NoLiveCellError('The address has no empty cells'); } emptyCells = emptyCells.filter((cell) => !cell.output.type); - const needCapacity = sumXudtCapacity - sumXudtInputsCapacity + xudtCapacity; + const needCapacity = sumXudtoutputCapacity - sumXudtInputsCapacity; const { inputs: emptyInputs, sumInputsCapacity: sumEmptyCapacity } = collector.collectInputs( emptyCells, needCapacity, @@ -83,17 +93,7 @@ const transferXudt = async ({ xudtType, receivers }: XudtTransferParams) => { actualInputsCapacity += sumEmptyCapacity; } - let changeCapacity = actualInputsCapacity - sumXudtCapacity; - if (sumAmount > sumTransferAmount) { - outputs.push({ - lock: fromLock, - type: xudtType, - capacity: append0x(xudtCapacity.toString(16)), - }); - outputsData.push(append0x(u128ToLe(sumAmount - sumTransferAmount))); - changeCapacity -= xudtCapacity; - } - + let changeCapacity = actualInputsCapacity - sumXudtoutputCapacity; outputs.push({ lock: fromLock, capacity: append0x(changeCapacity.toString(16)), From 84829096f1b4d120adc454a3236e9ef2d50df675 Mon Sep 17 00:00:00 2001 From: Dylan Duan Date: Sun, 9 Jun 2024 10:45:37 +0800 Subject: [PATCH 42/90] refactor: Calculate every capacity for each output --- examples/xudt-on-ckb/2-transfer-xudt.ts | 28 +++++++++++++------------ 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/examples/xudt-on-ckb/2-transfer-xudt.ts b/examples/xudt-on-ckb/2-transfer-xudt.ts index dba100aa..6f5068ef 100644 --- a/examples/xudt-on-ckb/2-transfer-xudt.ts +++ b/examples/xudt-on-ckb/2-transfer-xudt.ts @@ -42,6 +42,10 @@ const transferXudt = async ({ xudtType, receivers }: XudtTransferParams) => { .map((receiver) => receiver.transferAmount) .reduce((prev, current) => prev + current, BigInt(0)); + let sumXudtOutputCapacity = receivers + .map(({ toAddress }) => calculateUdtCellCapacity(addressToScript(toAddress))) + .reduce((prev, current) => prev + current, BigInt(0)); + const { inputs: udtInputs, sumInputsCapacity: sumXudtInputsCapacity, @@ -53,28 +57,26 @@ const transferXudt = async ({ xudtType, receivers }: XudtTransferParams) => { let actualInputsCapacity = sumXudtInputsCapacity; let inputs = udtInputs; - const xudtCapacity = calculateUdtCellCapacity(fromLock); - let sumXudtoutputCapacity = xudtCapacity * BigInt(receivers.length); - - const outputs: CKBComponents.CellOutput[] = receivers.map((receiver) => ({ - lock: addressToScript(receiver.toAddress), + const outputs: CKBComponents.CellOutput[] = receivers.map(({ toAddress }) => ({ + lock: addressToScript(toAddress), type: xudtType, - capacity: append0x(xudtCapacity.toString(16)), + capacity: append0x(calculateUdtCellCapacity(addressToScript(toAddress)).toString(16)), })); - const outputsData = receivers.map((receiver) => append0x(u128ToLe(receiver.transferAmount))); + const outputsData = receivers.map(({ transferAmount }) => append0x(u128ToLe(transferAmount))); if (sumAmount > sumTransferAmount) { + const xudtChangeCapacity = calculateUdtCellCapacity(fromLock); outputs.push({ lock: fromLock, type: xudtType, - capacity: append0x(xudtCapacity.toString(16)), + capacity: append0x(xudtChangeCapacity.toString(16)), }); outputsData.push(append0x(u128ToLe(sumAmount - sumTransferAmount))); - sumXudtoutputCapacity += xudtCapacity; + sumXudtOutputCapacity += xudtChangeCapacity; } const txFee = MAX_FEE; - if (sumXudtInputsCapacity <= sumXudtoutputCapacity) { + if (sumXudtInputsCapacity <= sumXudtOutputCapacity) { let emptyCells = await collector.getCells({ lock: fromLock, }); @@ -82,7 +84,7 @@ const transferXudt = async ({ xudtType, receivers }: XudtTransferParams) => { throw new NoLiveCellError('The address has no empty cells'); } emptyCells = emptyCells.filter((cell) => !cell.output.type); - const needCapacity = sumXudtoutputCapacity - sumXudtInputsCapacity; + const needCapacity = sumXudtOutputCapacity - sumXudtInputsCapacity; const { inputs: emptyInputs, sumInputsCapacity: sumEmptyCapacity } = collector.collectInputs( emptyCells, needCapacity, @@ -93,7 +95,7 @@ const transferXudt = async ({ xudtType, receivers }: XudtTransferParams) => { actualInputsCapacity += sumEmptyCapacity; } - let changeCapacity = actualInputsCapacity - sumXudtoutputCapacity; + let changeCapacity = actualInputsCapacity - sumXudtOutputCapacity; outputs.push({ lock: fromLock, capacity: append0x(changeCapacity.toString(16)), @@ -143,7 +145,7 @@ transferXudt({ }, receivers: [ { - toAddress: 'ckt1qyqpyw8j7tlu3v44am8d54066zrzk4vz5lvqat8fpf', + toAddress: 'ckt1qrfrwcdnvssswdwpn3s9v8fp87emat306ctjwsm3nmlkjg8qyza2cqgqq92pncevj8c3nwz7f3mlx2fwqn6l44y73yr5swl5', transferAmount: BigInt(1000) * BigInt(10 ** XUDT_TOKEN_INFO.decimal), }, { From fccaa7429e0497ab7c2424a5096990b86505f0cd Mon Sep 17 00:00:00 2001 From: Dawn <13477199767@163.com> Date: Tue, 11 Jun 2024 14:39:33 +0800 Subject: [PATCH 43/90] test: Add transfer-xudt integration tests --- tests/rgbpp/package.json | 2 +- .../rgbpp/xudt/xudt-on-ckb/2-transfer-xudt.ts | 154 ++++++++++++++++++ 2 files changed, 155 insertions(+), 1 deletion(-) create mode 100644 tests/rgbpp/xudt/xudt-on-ckb/2-transfer-xudt.ts diff --git a/tests/rgbpp/package.json b/tests/rgbpp/package.json index 5cd7d0bc..458984c1 100644 --- a/tests/rgbpp/package.json +++ b/tests/rgbpp/package.json @@ -8,7 +8,7 @@ "format": "prettier --write '**/*.{js,ts}'", "lint": "tsc && eslint . && prettier --check '**/*.{js,ts}'", "lint:fix": "tsc && eslint --fix --ext .js,.ts . && prettier --write '**/*.{js,ts}'", - "integration:xudt": "npx ts-node shared/prepare-utxo.ts && npx ts-node xudt/xudt-on-ckb/1-issue-xudt.ts && npx ts-node xudt/1-ckb-leap-btc.ts && npx ts-node xudt/2-btc-transfer.ts && npx ts-node xudt/3-btc-leap-ckb.ts", + "integration:xudt": "npx ts-node shared/prepare-utxo.ts && npx ts-node xudt/xudt-on-ckb/1-issue-xudt.ts && npx ts-node xudt/xudt-on-ckb/2-transfer-xudt.ts && npx ts-node xudt/1-ckb-leap-btc.ts && npx ts-node xudt/2-btc-transfer.ts && npx ts-node xudt/3-btc-leap-ckb.ts", "integration:spore": "npx ts-node shared/prepare-utxo.ts && npx ts-node spore/launch/1-prepare-cluster.ts && npx ts-node spore/launch/2-create-cluster.ts && npx ts-node spore/launch/3-create-spores.ts && npx ts-node spore/4-transfer-spore.ts && npx ts-node spore/5-leap-spore-to-ckb.ts" }, "dependencies": { diff --git a/tests/rgbpp/xudt/xudt-on-ckb/2-transfer-xudt.ts b/tests/rgbpp/xudt/xudt-on-ckb/2-transfer-xudt.ts new file mode 100644 index 00000000..418f4d10 --- /dev/null +++ b/tests/rgbpp/xudt/xudt-on-ckb/2-transfer-xudt.ts @@ -0,0 +1,154 @@ +import { addressToScript, getTransactionSize } from '@nervosnetwork/ckb-sdk-utils'; +import { + getSecp256k1CellDep, + RgbppTokenInfo, + NoLiveCellError, + calculateUdtCellCapacity, + MAX_FEE, + MIN_CAPACITY, + append0x, + u128ToLe, + SECP256K1_WITNESS_LOCK_SIZE, + calculateTransactionFee, + NoXudtLiveCellError, + fetchTypeIdCellDeps, +} from 'rgbpp/ckb'; +import { CKB_PRIVATE_KEY, ckbAddress, collector, isMainnet } from './env'; +import { readStepLog } from '../../shared/utils'; + +interface XudtTransferParams { + xudtType: CKBComponents.Script; + receivers: { + toAddress: string; + transferAmount: bigint; + }[]; +} + +/** + * transferXudt can be used to mint xUDT assets or transfer xUDT assets. + * @param xudtType The xUDT type script that comes from 1-issue-xudt + * @param receivers The receiver includes toAddress and transferAmount + */ +const transferXudt = async ({ xudtType, receivers }: XudtTransferParams) => { + const fromLock = addressToScript(ckbAddress); + + const xudtCells = await collector.getCells({ + lock: fromLock, + type: xudtType, + }); + if (!xudtCells || xudtCells.length === 0) { + throw new NoXudtLiveCellError('The address has no xudt cells'); + } + const sumTransferAmount = receivers + .map((receiver) => receiver.transferAmount) + .reduce((prev, current) => prev + current, BigInt(0)); + + let sumXudtOutputCapacity = receivers + .map(({ toAddress }) => calculateUdtCellCapacity(addressToScript(toAddress))) + .reduce((prev, current) => prev + current, BigInt(0)); + + const { + inputs: udtInputs, + sumInputsCapacity: sumXudtInputsCapacity, + sumAmount, + } = collector.collectUdtInputs({ + liveCells: xudtCells, + needAmount: sumTransferAmount, + }); + let actualInputsCapacity = sumXudtInputsCapacity; + let inputs = udtInputs; + + const outputs: CKBComponents.CellOutput[] = receivers.map(({ toAddress }) => ({ + lock: addressToScript(toAddress), + type: xudtType, + capacity: append0x(calculateUdtCellCapacity(addressToScript(toAddress)).toString(16)), + })); + const outputsData = receivers.map(({ transferAmount }) => append0x(u128ToLe(transferAmount))); + + if (sumAmount > sumTransferAmount) { + const xudtChangeCapacity = calculateUdtCellCapacity(fromLock); + outputs.push({ + lock: fromLock, + type: xudtType, + capacity: append0x(xudtChangeCapacity.toString(16)), + }); + outputsData.push(append0x(u128ToLe(sumAmount - sumTransferAmount))); + sumXudtOutputCapacity += xudtChangeCapacity; + } + + const txFee = MAX_FEE; + if (sumXudtInputsCapacity <= sumXudtOutputCapacity) { + let emptyCells = await collector.getCells({ + lock: fromLock, + }); + if (!emptyCells || emptyCells.length === 0) { + throw new NoLiveCellError('The address has no empty cells'); + } + emptyCells = emptyCells.filter((cell) => !cell.output.type); + const needCapacity = sumXudtOutputCapacity - sumXudtInputsCapacity; + const { inputs: emptyInputs, sumInputsCapacity: sumEmptyCapacity } = collector.collectInputs( + emptyCells, + needCapacity, + txFee, + { minCapacity: MIN_CAPACITY }, + ); + inputs = [...inputs, ...emptyInputs]; + actualInputsCapacity += sumEmptyCapacity; + } + + let changeCapacity = actualInputsCapacity - sumXudtOutputCapacity; + outputs.push({ + lock: fromLock, + capacity: append0x(changeCapacity.toString(16)), + }); + outputsData.push('0x'); + + const emptyWitness = { lock: '', inputType: '', outputType: '' }; + const witnesses = inputs.map((_, index) => (index === 0 ? emptyWitness : '0x')); + + const cellDeps = [getSecp256k1CellDep(isMainnet), ...(await fetchTypeIdCellDeps(isMainnet, { xudt: true }))]; + + const unsignedTx = { + version: '0x0', + cellDeps, + headerDeps: [], + inputs, + outputs, + outputsData, + witnesses, + }; + + if (txFee === MAX_FEE) { + const txSize = getTransactionSize(unsignedTx) + SECP256K1_WITNESS_LOCK_SIZE; + const estimatedTxFee = calculateTransactionFee(txSize); + changeCapacity -= estimatedTxFee; + unsignedTx.outputs[unsignedTx.outputs.length - 1].capacity = append0x(changeCapacity.toString(16)); + } + + const signedTx = collector.getCkb().signTransaction(CKB_PRIVATE_KEY)(unsignedTx); + const txHash = await collector.getCkb().rpc.sendTransaction(signedTx, 'passthrough'); + + console.info(`xUDT asset has been minted or transferred and tx hash is ${txHash}`); + console.info(`explorer: https://pudge.explorer.nervos.org/transaction/${txHash}`); +}; + +const XUDT_TOKEN_INFO: RgbppTokenInfo = { + decimal: 8, + name: 'XUDT Test Token', + symbol: 'PDD', +}; + +transferXudt({ + // The xudtType comes from 1-issue-xudt + xudtType: { + codeHash: readStepLog('xUDT-type-script').codeHash, + hashType: readStepLog('xUDT-type-script').hashType, + args: readStepLog('xUDT-type-script').args, + }, + receivers: [ + { + toAddress: 'ckt1qrfrwcdnvssswdwpn3s9v8fp87emat306ctjwsm3nmlkjg8qyza2cqgqqxtfdmw2e5kzfcz536qrnf6w36kyhpzweupegx46', + transferAmount: BigInt(1) * BigInt(10 ** XUDT_TOKEN_INFO.decimal), + }, + ], +}); From b400b04ce04bfe935ce86b1cffe76c198ff055fe Mon Sep 17 00:00:00 2001 From: Dawn <13477199767@163.com> Date: Tue, 11 Jun 2024 15:30:59 +0800 Subject: [PATCH 44/90] chore: Add retry mechanism for transfer-xudt testing --- .../rgbpp/xudt/xudt-on-ckb/2-transfer-xudt.ts | 187 +++++++++--------- 1 file changed, 95 insertions(+), 92 deletions(-) diff --git a/tests/rgbpp/xudt/xudt-on-ckb/2-transfer-xudt.ts b/tests/rgbpp/xudt/xudt-on-ckb/2-transfer-xudt.ts index 418f4d10..f705a9cd 100644 --- a/tests/rgbpp/xudt/xudt-on-ckb/2-transfer-xudt.ts +++ b/tests/rgbpp/xudt/xudt-on-ckb/2-transfer-xudt.ts @@ -13,7 +13,7 @@ import { NoXudtLiveCellError, fetchTypeIdCellDeps, } from 'rgbpp/ckb'; -import { CKB_PRIVATE_KEY, ckbAddress, collector, isMainnet } from './env'; +import { CKB_PRIVATE_KEY, ckbAddress, collector, isMainnet } from '../../env'; import { readStepLog } from '../../shared/utils'; interface XudtTransferParams { @@ -30,106 +30,109 @@ interface XudtTransferParams { * @param receivers The receiver includes toAddress and transferAmount */ const transferXudt = async ({ xudtType, receivers }: XudtTransferParams) => { - const fromLock = addressToScript(ckbAddress); + const { retry } = await import('zx'); + await retry(12, '10s', async () => { + const fromLock = addressToScript(ckbAddress); - const xudtCells = await collector.getCells({ - lock: fromLock, - type: xudtType, - }); - if (!xudtCells || xudtCells.length === 0) { - throw new NoXudtLiveCellError('The address has no xudt cells'); - } - const sumTransferAmount = receivers - .map((receiver) => receiver.transferAmount) - .reduce((prev, current) => prev + current, BigInt(0)); - - let sumXudtOutputCapacity = receivers - .map(({ toAddress }) => calculateUdtCellCapacity(addressToScript(toAddress))) - .reduce((prev, current) => prev + current, BigInt(0)); - - const { - inputs: udtInputs, - sumInputsCapacity: sumXudtInputsCapacity, - sumAmount, - } = collector.collectUdtInputs({ - liveCells: xudtCells, - needAmount: sumTransferAmount, - }); - let actualInputsCapacity = sumXudtInputsCapacity; - let inputs = udtInputs; - - const outputs: CKBComponents.CellOutput[] = receivers.map(({ toAddress }) => ({ - lock: addressToScript(toAddress), - type: xudtType, - capacity: append0x(calculateUdtCellCapacity(addressToScript(toAddress)).toString(16)), - })); - const outputsData = receivers.map(({ transferAmount }) => append0x(u128ToLe(transferAmount))); - - if (sumAmount > sumTransferAmount) { - const xudtChangeCapacity = calculateUdtCellCapacity(fromLock); - outputs.push({ + const xudtCells = await collector.getCells({ lock: fromLock, type: xudtType, - capacity: append0x(xudtChangeCapacity.toString(16)), }); - outputsData.push(append0x(u128ToLe(sumAmount - sumTransferAmount))); - sumXudtOutputCapacity += xudtChangeCapacity; - } + if (!xudtCells || xudtCells.length === 0) { + throw new NoXudtLiveCellError('The address has no xudt cells'); + } + const sumTransferAmount = receivers + .map((receiver) => receiver.transferAmount) + .reduce((prev, current) => prev + current, BigInt(0)); + + let sumXudtOutputCapacity = receivers + .map(({ toAddress }) => calculateUdtCellCapacity(addressToScript(toAddress))) + .reduce((prev, current) => prev + current, BigInt(0)); + + const { + inputs: udtInputs, + sumInputsCapacity: sumXudtInputsCapacity, + sumAmount, + } = collector.collectUdtInputs({ + liveCells: xudtCells, + needAmount: sumTransferAmount, + }); + let actualInputsCapacity = sumXudtInputsCapacity; + let inputs = udtInputs; - const txFee = MAX_FEE; - if (sumXudtInputsCapacity <= sumXudtOutputCapacity) { - let emptyCells = await collector.getCells({ + const outputs: CKBComponents.CellOutput[] = receivers.map(({ toAddress }) => ({ + lock: addressToScript(toAddress), + type: xudtType, + capacity: append0x(calculateUdtCellCapacity(addressToScript(toAddress)).toString(16)), + })); + const outputsData = receivers.map(({ transferAmount }) => append0x(u128ToLe(transferAmount))); + + if (sumAmount > sumTransferAmount) { + const xudtChangeCapacity = calculateUdtCellCapacity(fromLock); + outputs.push({ + lock: fromLock, + type: xudtType, + capacity: append0x(xudtChangeCapacity.toString(16)), + }); + outputsData.push(append0x(u128ToLe(sumAmount - sumTransferAmount))); + sumXudtOutputCapacity += xudtChangeCapacity; + } + + const txFee = MAX_FEE; + if (sumXudtInputsCapacity <= sumXudtOutputCapacity) { + let emptyCells = await collector.getCells({ + lock: fromLock, + }); + if (!emptyCells || emptyCells.length === 0) { + throw new NoLiveCellError('The address has no empty cells'); + } + emptyCells = emptyCells.filter((cell) => !cell.output.type); + const needCapacity = sumXudtOutputCapacity - sumXudtInputsCapacity; + const { inputs: emptyInputs, sumInputsCapacity: sumEmptyCapacity } = collector.collectInputs( + emptyCells, + needCapacity, + txFee, + { minCapacity: MIN_CAPACITY }, + ); + inputs = [...inputs, ...emptyInputs]; + actualInputsCapacity += sumEmptyCapacity; + } + + let changeCapacity = actualInputsCapacity - sumXudtOutputCapacity; + outputs.push({ lock: fromLock, + capacity: append0x(changeCapacity.toString(16)), }); - if (!emptyCells || emptyCells.length === 0) { - throw new NoLiveCellError('The address has no empty cells'); + outputsData.push('0x'); + + const emptyWitness = { lock: '', inputType: '', outputType: '' }; + const witnesses = inputs.map((_, index) => (index === 0 ? emptyWitness : '0x')); + + const cellDeps = [getSecp256k1CellDep(isMainnet), ...(await fetchTypeIdCellDeps(isMainnet, { xudt: true }))]; + + const unsignedTx = { + version: '0x0', + cellDeps, + headerDeps: [], + inputs, + outputs, + outputsData, + witnesses, + }; + + if (txFee === MAX_FEE) { + const txSize = getTransactionSize(unsignedTx) + SECP256K1_WITNESS_LOCK_SIZE; + const estimatedTxFee = calculateTransactionFee(txSize); + changeCapacity -= estimatedTxFee; + unsignedTx.outputs[unsignedTx.outputs.length - 1].capacity = append0x(changeCapacity.toString(16)); } - emptyCells = emptyCells.filter((cell) => !cell.output.type); - const needCapacity = sumXudtOutputCapacity - sumXudtInputsCapacity; - const { inputs: emptyInputs, sumInputsCapacity: sumEmptyCapacity } = collector.collectInputs( - emptyCells, - needCapacity, - txFee, - { minCapacity: MIN_CAPACITY }, - ); - inputs = [...inputs, ...emptyInputs]; - actualInputsCapacity += sumEmptyCapacity; - } - - let changeCapacity = actualInputsCapacity - sumXudtOutputCapacity; - outputs.push({ - lock: fromLock, - capacity: append0x(changeCapacity.toString(16)), + + const signedTx = collector.getCkb().signTransaction(CKB_PRIVATE_KEY)(unsignedTx); + const txHash = await collector.getCkb().rpc.sendTransaction(signedTx, 'passthrough'); + + console.info(`xUDT asset has been minted or transferred and tx hash is ${txHash}`); + console.info(`explorer: https://pudge.explorer.nervos.org/transaction/${txHash}`); }); - outputsData.push('0x'); - - const emptyWitness = { lock: '', inputType: '', outputType: '' }; - const witnesses = inputs.map((_, index) => (index === 0 ? emptyWitness : '0x')); - - const cellDeps = [getSecp256k1CellDep(isMainnet), ...(await fetchTypeIdCellDeps(isMainnet, { xudt: true }))]; - - const unsignedTx = { - version: '0x0', - cellDeps, - headerDeps: [], - inputs, - outputs, - outputsData, - witnesses, - }; - - if (txFee === MAX_FEE) { - const txSize = getTransactionSize(unsignedTx) + SECP256K1_WITNESS_LOCK_SIZE; - const estimatedTxFee = calculateTransactionFee(txSize); - changeCapacity -= estimatedTxFee; - unsignedTx.outputs[unsignedTx.outputs.length - 1].capacity = append0x(changeCapacity.toString(16)); - } - - const signedTx = collector.getCkb().signTransaction(CKB_PRIVATE_KEY)(unsignedTx); - const txHash = await collector.getCkb().rpc.sendTransaction(signedTx, 'passthrough'); - - console.info(`xUDT asset has been minted or transferred and tx hash is ${txHash}`); - console.info(`explorer: https://pudge.explorer.nervos.org/transaction/${txHash}`); }; const XUDT_TOKEN_INFO: RgbppTokenInfo = { From c3a2fa915fcbad9c22061958363835e403187d5f Mon Sep 17 00:00:00 2001 From: Dawn <13477199767@163.com> Date: Wed, 12 Jun 2024 17:04:27 +0800 Subject: [PATCH 45/90] chore: Test multiple recipients with different transferAmounts in transfer-xudt --- tests/rgbpp/xudt/xudt-on-ckb/2-transfer-xudt.ts | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/tests/rgbpp/xudt/xudt-on-ckb/2-transfer-xudt.ts b/tests/rgbpp/xudt/xudt-on-ckb/2-transfer-xudt.ts index f705a9cd..4c953dad 100644 --- a/tests/rgbpp/xudt/xudt-on-ckb/2-transfer-xudt.ts +++ b/tests/rgbpp/xudt/xudt-on-ckb/2-transfer-xudt.ts @@ -153,5 +153,13 @@ transferXudt({ toAddress: 'ckt1qrfrwcdnvssswdwpn3s9v8fp87emat306ctjwsm3nmlkjg8qyza2cqgqqxtfdmw2e5kzfcz536qrnf6w36kyhpzweupegx46', transferAmount: BigInt(1) * BigInt(10 ** XUDT_TOKEN_INFO.decimal), }, + { + toAddress: 'ckt1qzda0cr08m85hc8jlnfp3zer7xulejywt49kt2rr0vthywaa50xwsqgj8re09l7gk267ank62hadpp3t2kp20kqnud0jc', + transferAmount: BigInt(1000) * BigInt(10 ** XUDT_TOKEN_INFO.decimal), + }, + { + toAddress: 'ckt1qzda0cr08m85hc8jlnfp3zer7xulejywt49kt2rr0vthywaa50xwsqgj8re09l7gk267ank62hadpp3t2kp20kqnud0jc', + transferAmount: BigInt(2000) * BigInt(10 ** XUDT_TOKEN_INFO.decimal), + }, ], }); From 6ab7e7de40c89f101ad280962ab2affe5f4914cd Mon Sep 17 00:00:00 2001 From: ahonn Date: Thu, 13 Jun 2024 15:44:26 +1000 Subject: [PATCH 46/90] build: add Dockerfile and .dockerignore --- .dockerignore | 6 ++++++ Dockerfile | 28 ++++++++++++++++++++++++++++ package.json | 3 ++- 3 files changed, 36 insertions(+), 1 deletion(-) create mode 100644 .dockerignore create mode 100644 Dockerfile diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 00000000..a67e3bdb --- /dev/null +++ b/.dockerignore @@ -0,0 +1,6 @@ +node_modules +.git +.gitignore +*.md +tests +examples diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 00000000..c2446a70 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,28 @@ +FROM node:20-slim AS base + +ENV PNPM_HOME="/pnpm" +ENV PATH="$PNPM_HOME:$PATH" +RUN corepack enable +RUN corepack use pnpm@latest +RUN apt-get update -y && apt-get install -y ca-certificates + +COPY . /app +WORKDIR /app + +FROM base AS prod-deps +RUN npm pkg delete scripts.prepare +RUN --mount=type=cache,id=pnpm,target=/pnpm/store pnpm install --prod --frozen-lockfile + +FROM base AS build +RUN --mount=type=cache,id=pnpm,target=/pnpm/store pnpm install --frozen-lockfile +RUN pnpm run build + +FROM base AS service +COPY --from=prod-deps /app/node_modules /node_modules +COPY --from=build /app/apps /app/apps +COPY --from=build /app/packages /app/packages + +WORKDIR /app/apps/service +RUN pnpm add @nestjs/cli -D +EXPOSE 3000 +CMD [ "pnpm", "start" ] diff --git a/package.json b/package.json index 478dc13b..032b8b44 100644 --- a/package.json +++ b/package.json @@ -6,6 +6,7 @@ ], "scripts": { "prepare": "husky", + "build": "turbo run build", "test:packages": "turbo run test --filter=./packages/*", "build:packages": "turbo run build --filter=./packages/*", "dev:service": "turbo run dev --filter=./apps/service", @@ -39,7 +40,7 @@ "prettier --ignore-unknown --write" ] }, - "packageManager": "^pnpm@8.0.0", + "packageManager": "pnpm@8.15.8+sha512.d1a029e1a447ad90bc96cd58b0fad486d2993d531856396f7babf2d83eb1823bb83c5a3d0fc18f675b2d10321d49eb161fece36fe8134aa5823ecd215feed392", "engines": { "node": ">=18.0.0", "pnpm": ">=8.0.0" From a368e2312b83469a9da74945405e7f677f2a504c Mon Sep 17 00:00:00 2001 From: ahonn Date: Thu, 13 Jun 2024 16:32:13 +1000 Subject: [PATCH 47/90] build: add docker-compose.yml and fix docker issue --- .dockerignore | 1 + Dockerfile | 7 ++++--- apps/service/docker-compose.yml | 13 +++++++++++++ apps/service/package.json | 2 +- apps/service/src/main.ts | 4 ++-- pnpm-lock.yaml | 2 +- 6 files changed, 22 insertions(+), 7 deletions(-) create mode 100644 apps/service/docker-compose.yml diff --git a/.dockerignore b/.dockerignore index a67e3bdb..05731f09 100644 --- a/.dockerignore +++ b/.dockerignore @@ -4,3 +4,4 @@ node_modules *.md tests examples +dist diff --git a/Dockerfile b/Dockerfile index c2446a70..6f165215 100644 --- a/Dockerfile +++ b/Dockerfile @@ -4,13 +4,12 @@ ENV PNPM_HOME="/pnpm" ENV PATH="$PNPM_HOME:$PATH" RUN corepack enable RUN corepack use pnpm@latest -RUN apt-get update -y && apt-get install -y ca-certificates COPY . /app WORKDIR /app FROM base AS prod-deps -RUN npm pkg delete scripts.prepare +RUN npm pkg delete scripts.prepare RUN --mount=type=cache,id=pnpm,target=/pnpm/store pnpm install --prod --frozen-lockfile FROM base AS build @@ -19,10 +18,12 @@ RUN pnpm run build FROM base AS service COPY --from=prod-deps /app/node_modules /node_modules -COPY --from=build /app/apps /app/apps COPY --from=build /app/packages /app/packages +COPY --from=build /app/apps/service /app/apps/service WORKDIR /app/apps/service RUN pnpm add @nestjs/cli -D + +ENV NODE_ENV=production EXPOSE 3000 CMD [ "pnpm", "start" ] diff --git a/apps/service/docker-compose.yml b/apps/service/docker-compose.yml new file mode 100644 index 00000000..efe0c7a4 --- /dev/null +++ b/apps/service/docker-compose.yml @@ -0,0 +1,13 @@ +version: '3.8' + +services: + rgbpp-sdk-service: + build: + context: ../.. + target: service + # image: ghcr.io/ckb-cell/rgbpp-sdk-service:develop + ports: + - '3000:3000' + env_file: + - .env + diff --git a/apps/service/package.json b/apps/service/package.json index bbd84af8..be49801c 100644 --- a/apps/service/package.json +++ b/apps/service/package.json @@ -23,7 +23,7 @@ "dependencies": { "@nestjs/common": "^10.0.0", "@nestjs/config": "^3.2.2", - "@nestjs/core": "^10.0.0", + "@nestjs/core": "^10.3.9", "@nestjs/platform-fastify": "^10.3.9", "convert-keys": "^1.3.4", "json-rpc-2.0": "^1.7.0", diff --git a/apps/service/src/main.ts b/apps/service/src/main.ts index c536bd53..4727a21b 100644 --- a/apps/service/src/main.ts +++ b/apps/service/src/main.ts @@ -6,7 +6,7 @@ import { FastifyAdapter, NestFastifyApplication } from '@nestjs/platform-fastify async function bootstrap() { const logger = new Logger('AppBootstrap'); const app = await NestFactory.create(AppModule, new FastifyAdapter()); - await app.listen(3000); - logger.log('Application is running on: http://localhost:3000'); + await app.listen(3000, '0.0.0.0'); + logger.log('Application is running on: http://0.0.0.0:3000'); } bootstrap(); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 2ceefae9..6ca97b4c 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -57,7 +57,7 @@ importers: specifier: ^3.2.2 version: 3.2.2(@nestjs/common@10.3.9)(rxjs@7.8.1) '@nestjs/core': - specifier: ^10.0.0 + specifier: ^10.3.9 version: 10.3.9(@nestjs/common@10.3.9)(reflect-metadata@0.2.2)(rxjs@7.8.1) '@nestjs/platform-fastify': specifier: ^10.3.9 From cb8395a064fc8d60ec9a3678962d6bc188c498d8 Mon Sep 17 00:00:00 2001 From: ahonn Date: Thu, 13 Jun 2024 16:39:25 +1000 Subject: [PATCH 48/90] docs: update README.md and add vercel deploy button --- apps/service/README.md | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/apps/service/README.md b/apps/service/README.md index a87f854e..490edde3 100644 --- a/apps/service/README.md +++ b/apps/service/README.md @@ -68,4 +68,14 @@ $ pm2 start dist/src/main.js --name rgbpp-sdk-service ### 2. Use Docker -TODO \ No newline at end of file +- Copy the `.env.example` file to `.env` and Update the configuration values + +- Use the provided `docker-compose.yml` file to run the service: + +```bash +docker-compose up +``` + +### 3. Deploy to Vercel + +[![Deploy with Vercel](https://vercel.com/button)](https://vercel.com/new/clone?repository-url=https%3A%2F%2Fgithub.com%2Fckb-cell%2Frgbpp-sdk%2Ftree%2Ffeat%2Frgbpp-sdk-service%2Fapps%2Fservice&env=NETWORK,CKB_RPC_URL,BTC_SERVICE_URL,BTC_SERVICE_TOKEN,BTC_SERVICE_ORIGIN&project-name=rgbpp-sdk-service&repository-name=rgbpp-sdk) From 5a5bb4a6e0b1ea94bd063fc631216b429d292b56 Mon Sep 17 00:00:00 2001 From: ahonn Date: Thu, 13 Jun 2024 16:51:38 +1000 Subject: [PATCH 49/90] docs: update README.md --- apps/service/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/service/README.md b/apps/service/README.md index 490edde3..237b85ef 100644 --- a/apps/service/README.md +++ b/apps/service/README.md @@ -78,4 +78,4 @@ docker-compose up ### 3. Deploy to Vercel -[![Deploy with Vercel](https://vercel.com/button)](https://vercel.com/new/clone?repository-url=https%3A%2F%2Fgithub.com%2Fckb-cell%2Frgbpp-sdk%2Ftree%2Ffeat%2Frgbpp-sdk-service%2Fapps%2Fservice&env=NETWORK,CKB_RPC_URL,BTC_SERVICE_URL,BTC_SERVICE_TOKEN,BTC_SERVICE_ORIGIN&project-name=rgbpp-sdk-service&repository-name=rgbpp-sdk) +[![Deploy with Vercel](https://vercel.com/button)](https://vercel.com/new/clone?repository-url=https%3A%2F%2Fgithub.com%2Fckb-cell%2Frgbpp-sdk%2Ftree%2Fmain%2Fapps%2Fservice&env=NETWORK,CKB_RPC_URL,BTC_SERVICE_URL,BTC_SERVICE_TOKEN,BTC_SERVICE_ORIGIN&project-name=rgbpp-sdk-service&repository-name=rgbpp-sdk) From 1094ebb3ed011f6ffed1a306f4bde609fb48f342 Mon Sep 17 00:00:00 2001 From: ahonn Date: Thu, 13 Jun 2024 16:57:34 +1000 Subject: [PATCH 50/90] ci: add docker publish workflow --- .github/workflows/docker.yml | 59 ++++++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) create mode 100644 .github/workflows/docker.yml diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml new file mode 100644 index 00000000..b03d5c33 --- /dev/null +++ b/.github/workflows/docker.yml @@ -0,0 +1,59 @@ +name: Docker Publish + +on: + workflow_dispatch: + push: + branches: + - main + - develop + tags: + - release/* + +jobs: + docker-build-push: + runs-on: ubuntu-22.04 + permissions: + packages: write + contents: read + + steps: + - uses: actions/checkout@v4 + + - name: Docker metadata + id: meta + uses: docker/metadata-action@v5 + with: + context: git + images: ghcr.io/${{ github.repository }} + flavor: | + latest=auto + tags: | + type=ref,event=tag + type=semver,pattern={{version}} + type=ref,event=branch + type=ref,event=branch,suffix=-{{date 'YYYYMMDDHHmm'}} + type=sha,enable=true,prefix=sha-,format=short + env: + DOCKER_METADATA_ANNOTATIONS_LEVELS: manifest,index + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Login to GitHub Container Registry + uses: docker/login-action@v3 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Build Docker image + uses: docker/build-push-action@v5 + with: + context: . + target: service + push: true + provenance: false + platforms: linux/amd64, linux/arm64 + tags: ${{ steps.meta.outputs.tags }} + labels: ${{ steps.meta.outputs.labels }} + annotations: ${{ steps.meta.outputs.annotations }} From da4257b49858fe954835e9cc130df6cbadcca278 Mon Sep 17 00:00:00 2001 From: ahonn Date: Thu, 13 Jun 2024 17:08:08 +1000 Subject: [PATCH 51/90] docs: update README --- apps/service/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/service/README.md b/apps/service/README.md index 237b85ef..6fd743a3 100644 --- a/apps/service/README.md +++ b/apps/service/README.md @@ -73,7 +73,7 @@ $ pm2 start dist/src/main.js --name rgbpp-sdk-service - Use the provided `docker-compose.yml` file to run the service: ```bash -docker-compose up +$ docker-compose up ``` ### 3. Deploy to Vercel From 01e11d51deccd3cafc15d423f40e47fc0dcb04b1 Mon Sep 17 00:00:00 2001 From: Yuexun Date: Thu, 13 Jun 2024 19:56:09 +1000 Subject: [PATCH 52/90] ci: update .github/workflows/docker.yml Co-authored-by: Flouse <1297478+Flouse@users.noreply.github.com> --- .github/workflows/docker.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index b03d5c33..06c09bed 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -7,7 +7,7 @@ on: - main - develop tags: - - release/* + - v*.*.* jobs: docker-build-push: From a169c8863af9719bcba075138767ccd70a65e98f Mon Sep 17 00:00:00 2001 From: Dylan Duan Date: Wed, 12 Jun 2024 16:43:43 +0800 Subject: [PATCH 53/90] feat: Support Bitcoin Signet network --- packages/ckb/README.md | 45 +++++++++----- packages/ckb/src/constants/index.ts | 84 ++++++++++++++++++++++---- packages/ckb/src/rgbpp/btc-jump-ckb.ts | 9 +-- packages/ckb/src/rgbpp/btc-time.ts | 15 +++-- packages/ckb/src/rgbpp/btc-transfer.ts | 19 +++--- packages/ckb/src/rgbpp/ckb-jump-btc.ts | 2 - packages/ckb/src/rgbpp/launch.ts | 10 +-- packages/ckb/src/spore/cluster.ts | 12 +++- packages/ckb/src/spore/leap.ts | 25 +++++--- packages/ckb/src/spore/spore.ts | 24 +++++--- packages/ckb/src/types/common.ts | 2 + packages/ckb/src/types/rgbpp.ts | 22 ++++++- packages/ckb/src/types/spore.ts | 18 +++++- packages/ckb/src/utils/cell-dep.ts | 13 +++- packages/rgbpp/src/rgbpp/types.ts | 1 + 15 files changed, 228 insertions(+), 73 deletions(-) diff --git a/packages/ckb/README.md b/packages/ckb/README.md index a94cf28e..0f3a4fbe 100644 --- a/packages/ckb/README.md +++ b/packages/ckb/README.md @@ -46,10 +46,11 @@ export interface BtcTransferVirtualTxResult { * @param xudtTypeBytes The serialized hex string of the XUDT type script * @param rgbppLockArgsList The rgbpp assets cell lock script args array whose data structure is: out_index | bitcoin_tx_id * @param transferAmount The XUDT amount to be transferred, if the noMergeOutputCells is true, the transferAmount will be ignored - * @param isMainnet - * @param witnessLockPlaceholderSize The WitnessArgs.lock placeholder bytes array size and the default value is 5000 - * @param noMergeOutputCells The noMergeOutputCells indicates whether the CKB outputs need to be merged. By default, the outputs will be merged. - * @param ckbFeeRate The CKB transaction fee rate, default value is 1100 + * @param isMainnet True is for BTC and CKB Mainnet, flase is for BTC and CKB Testnet(see btcTestnetType for details about BTC Testnet) + * @param witnessLockPlaceholderSize(Optional) The WitnessArgs.lock placeholder bytes array size and the default value is 5000 + * @param noMergeOutputCells(Optional) The noMergeOutputCells indicates whether the CKB outputs need to be merged. By default, the outputs will be merged. + * @param ckbFeeRate(Optional) The CKB transaction fee rate, default value is 1100 + * @param btcTestnetType(Optional) The Bitcoin Testnet type including Testnet3 and Signet, default value is Testnet3 */ export const genBtcTransferCkbVirtualTx = async ({ collector, @@ -60,6 +61,7 @@ export const genBtcTransferCkbVirtualTx = async ({ witnessLockPlaceholderSize, noMergeOutputCells, ckbFeeRate, + btcTestnetType }: BtcTransferVirtualTxParams): Promise ``` @@ -84,9 +86,9 @@ interface BtcJumpCkbVirtualTxResult { * @param xudtTypeBytes The serialized hex string of the XUDT type script * @param rgbppLockArgsList The rgbpp assets cell lock script args array whose data structure is: out_index | bitcoin_tx_id * @param transferAmount The XUDT amount to be transferred - * @param witnessLockPlaceholderSize The WitnessArgs.lock placeholder bytes array size and the default value is 5000 - * @param ckbFeeRate The CKB transaction fee rate, default value is 1100 - * @param isMainnet + * @param witnessLockPlaceholderSize(Optional) The WitnessArgs.lock placeholder bytes array size and the default value is 5000 + * @param ckbFeeRate(Optional) The CKB transaction fee rate, default value is 1100 + * @param btcTestnetType(Optional) The Bitcoin Testnet type including Testnet3 and Signet, default value is Testnet3 */ export const genBtcJumpCkbVirtualTx = async ({ collector, @@ -96,6 +98,7 @@ export const genBtcJumpCkbVirtualTx = async ({ toCkbAddress, witnessLockPlaceholderSize, ckbFeeRate, + btcTestnetType }: BtcJumpCkbVirtualTxParams): Promise ``` @@ -111,9 +114,8 @@ The method `genCkbJumpBtcVirtualTx` can generate a CKB transaction for RGB++ xUD * @param fromCkbAddress The from ckb address who will use his private key to sign the ckb tx * @param toRgbppLockArgs The receiver rgbpp lock script args whose data structure is: out_index | bitcoin_tx_id * @param transferAmount The XUDT amount to be transferred - * @param witnessLockPlaceholderSize The WitnessArgs.lock placeholder bytes array size and the default value is 5000 - * @param ckbFeeRate The CKB transaction fee rate, default value is 1100 - * @param isMainnet + * @param witnessLockPlaceholderSize(Optional) The WitnessArgs.lock placeholder bytes array size and the default value is 5000 + * @param ckbFeeRate(Optional) The CKB transaction fee rate, default value is 1100 */ export const genCkbJumpBtcVirtualTx = async ({ collector, @@ -147,12 +149,15 @@ export interface SporeCreateVirtualTxResult { * @param collector The collector that collects CKB live cells and transactions * @param clusterRgbppLockArgs The cluster rgbpp cell lock script args whose data structure is: out_index | bitcoin_tx_id * @param sporeDataList The spore's data list, including name and description. + * @param isMainnet True is for BTC and CKB Mainnet, flase is for BTC and CKB Testnet(see btcTestnetType for details about BTC Testnet) + * @param btcTestnetType(Optional) The Bitcoin Testnet type including Testnet3 and Signet, default value is Testnet3 */ export const genCreateSporeCkbVirtualTx = async ({ collector, clusterRgbppLockArgs, sporeDataList, isMainnet, + btcTestnetType }: CreateSporeCkbVirtualTxParams): Promise ``` @@ -179,8 +184,10 @@ export interface SporeTransferVirtualTxResult { * @param collector The collector that collects CKB live cells and transactions * @param sporeRgbppLockArgs The spore rgbpp cell lock script args whose data structure is: out_index | bitcoin_tx_id * @param sporeTypeBytes The spore type script serialized bytes - * @param witnessLockPlaceholderSize The WitnessArgs.lock placeholder bytes array size and the default value is 5000 - * @param ckbFeeRate The CKB transaction fee rate, default value is 1100 + * @param isMainnet True is for BTC and CKB Mainnet, flase is for BTC and CKB Testnet(see btcTestnetType for details about BTC Testnet) + * @param witnessLockPlaceholderSize(Optional) The WitnessArgs.lock placeholder bytes array size and the default value is 5000 + * @param ckbFeeRate(Optional) The CKB transaction fee rate, default value is 1100 + * @param btcTestnetType(Optional) The Bitcoin Testnet type including Testnet3 and Signet, default value is Testnet3 */ export const genTransferSporeCkbVirtualTx = async ({ collector, @@ -189,6 +196,7 @@ export const genTransferSporeCkbVirtualTx = async ({ isMainnet, witnessLockPlaceholderSize, ckbFeeRate, + btcTestnetType }: TransferSporeCkbVirtualTxParams): Promise ``` @@ -216,8 +224,10 @@ export interface SporeLeapVirtualTxResult { * @param sporeRgbppLockArgs The spore rgbpp cell lock script args whose data structure is: out_index | bitcoin_tx_id * @param sporeTypeBytes The spore type script serialized bytes * @param toCkbAddress The receiver ckb address - * @param witnessLockPlaceholderSize The WitnessArgs.lock placeholder bytes array size and the default value is 5000 - * @param ckbFeeRate The CKB transaction fee rate, default value is 1100 + * @param isMainnet True is for BTC and CKB Mainnet, flase is for BTC and CKB Testnet(see btcTestnetType for details about BTC Testnet) + * @param witnessLockPlaceholderSize(Optional) The WitnessArgs.lock placeholder bytes array size and the default value is 5000 + * @param ckbFeeRate(Optional) The CKB transaction fee rate, default value is 1100 + * @param btcTestnetType(Optional) The Bitcoin Testnet type including Testnet3 and Signet, default value is Testnet3 */ export const genLeapSporeFromBtcToCkbVirtualTx = async ({ collector, @@ -227,6 +237,7 @@ export const genLeapSporeFromBtcToCkbVirtualTx = async ({ isMainnet, witnessLockPlaceholderSize, ckbFeeRate, + btcTestnetType }: LeapSporeFromBtcToCkbVirtualTxParams): Promise ``` @@ -241,8 +252,10 @@ The method `genLeapSporeFromCkbToBtcRawTx` can generate a CKB transaction for RG * @param sporeRgbppLockArgs The spore rgbpp cell lock script args whose data structure is: out_index | bitcoin_tx_id * @param sporeTypeBytes The spore type script serialized bytes * @param toCkbAddress The receiver ckb address - * @param witnessLockPlaceholderSize The WitnessArgs.lock placeholder bytes array size and the default value is 5000 - * @param ckbFeeRate The CKB transaction fee rate, default value is 1100 + * @param isMainnet True is for BTC and CKB Mainnet, flase is for BTC and CKB Testnet + * @param witnessLockPlaceholderSize(Optional) The WitnessArgs.lock placeholder bytes array size and the default value is 5000 + * @param ckbFeeRate(Optional) The CKB transaction fee rate, default value is 1100 + * @param btcTestnetType(Optional) The Bitcoin Testnet type including Testnet3 and Signet */ export const genLeapSporeFromCkbToBtcRawTx = async ({ collector, diff --git a/packages/ckb/src/constants/index.ts b/packages/ckb/src/constants/index.ts index cf92757a..b6d8be97 100644 --- a/packages/ckb/src/constants/index.ts +++ b/packages/ckb/src/constants/index.ts @@ -1,3 +1,5 @@ +import { BTCTestnetType } from '../types'; + export const CKB_UNIT = BigInt(10000_0000); export const MAX_FEE = BigInt(2000_0000); export const MIN_CAPACITY = BigInt(61) * BigInt(10000_0000); @@ -105,6 +107,39 @@ const TestnetInfo = { }, depType: 'code', } as CKBComponents.CellDep, + + // The CKB testnet RGB++ deployment information for the BTC Signet network + RgbppSignetLockScript: { + codeHash: '0x61ca7a4796a4eb19ca4f0d065cb9b10ddcf002f10f7cbb810c706cb6bb5c3248', + hashType: 'type', + args: '', + } as CKBComponents.Script, + + RgbppSignetLockDep: { + outPoint: { txHash: '0xf1de59e973b85791ec32debbba08dff80c63197e895eb95d67fc1e9f6b413e00', index: '0x0' }, + depType: 'code', + } as CKBComponents.CellDep, + + RgbppSignetLockConfigDep: { + outPoint: { txHash: '0xf1de59e973b85791ec32debbba08dff80c63197e895eb95d67fc1e9f6b413e00', index: '0x1' }, + depType: 'code', + } as CKBComponents.CellDep, + + BtcTimeSignetLockScript: { + codeHash: '0x00cdf8fab0f8ac638758ebf5ea5e4052b1d71e8a77b9f43139718621f6849326', + hashType: 'type', + args: '', + } as CKBComponents.Script, + + BtcTimeSignetLockDep: { + outPoint: { txHash: '0xde0f87878a97500f549418e5d46d2f7704c565a262aa17036c9c1c13ad638529', index: '0x0' }, + depType: 'code', + } as CKBComponents.CellDep, + + BtcTimeSignetLockConfigDep: { + outPoint: { txHash: '0xde0f87878a97500f549418e5d46d2f7704c565a262aa17036c9c1c13ad638529', index: '0x1' }, + depType: 'code', + } as CKBComponents.CellDep, }; const MainnetInfo = { @@ -218,21 +253,46 @@ export const getXudtTypeScript = (isMainnet: boolean) => isMainnet ? MainnetInfo.XUDTTypeScript : TestnetInfo.XUDTTypeScript; export const getXudtDep = (isMainnet: boolean) => (isMainnet ? MainnetInfo.XUDTTypeDep : TestnetInfo.XUDTTypeDep); -export const getRgbppLockScript = (isMainnet: boolean) => - isMainnet ? MainnetInfo.RgbppLockScript : TestnetInfo.RgbppLockScript; -export const getRgbppLockDep = (isMainnet: boolean) => - isMainnet ? MainnetInfo.RgbppLockDep : TestnetInfo.RgbppLockDep; +export const getRgbppLockScript = (isMainnet: boolean, btcTestnetType?: BTCTestnetType) => { + if (isMainnet) { + return MainnetInfo.RgbppLockScript; + } + return btcTestnetType === 'Signet' ? TestnetInfo.RgbppSignetLockScript : TestnetInfo.RgbppLockScript; +}; + +export const getRgbppLockDep = (isMainnet: boolean, btcTestnetType?: BTCTestnetType) => { + if (isMainnet) { + return MainnetInfo.RgbppLockDep; + } + return btcTestnetType === 'Signet' ? TestnetInfo.RgbppSignetLockDep : TestnetInfo.RgbppLockDep; +}; -export const getRgbppLockConfigDep = (isMainnet: boolean) => - isMainnet ? MainnetInfo.RgbppLockConfigDep : TestnetInfo.RgbppLockConfigDep; +export const getRgbppLockConfigDep = (isMainnet: boolean, btcTestnetType?: BTCTestnetType) => { + if (isMainnet) { + return MainnetInfo.RgbppLockConfigDep; + } + return btcTestnetType === 'Signet' ? TestnetInfo.RgbppSignetLockConfigDep : TestnetInfo.RgbppLockConfigDep; +}; -export const getBtcTimeLockScript = (isMainnet: boolean) => - isMainnet ? MainnetInfo.BtcTimeLockScript : TestnetInfo.BtcTimeLockScript; -export const getBtcTimeLockDep = (isMainnet: boolean) => - isMainnet ? MainnetInfo.BtcTimeLockDep : TestnetInfo.BtcTimeLockDep; +export const getBtcTimeLockScript = (isMainnet: boolean, btcTestnetType?: BTCTestnetType) => { + if (isMainnet) { + return MainnetInfo.BtcTimeLockScript; + } + return btcTestnetType === 'Signet' ? TestnetInfo.BtcTimeSignetLockScript : TestnetInfo.BtcTimeLockScript; +}; +export const getBtcTimeLockDep = (isMainnet: boolean, btcTestnetType?: BTCTestnetType) => { + if (isMainnet) { + return MainnetInfo.BtcTimeLockDep; + } + return btcTestnetType === 'Signet' ? TestnetInfo.BtcTimeSignetLockDep : TestnetInfo.BtcTimeLockDep; +}; -export const getBtcTimeLockConfigDep = (isMainnet: boolean) => - isMainnet ? MainnetInfo.BtcTimeLockConfigDep : TestnetInfo.BtcTimeLockConfigDep; +export const getBtcTimeLockConfigDep = (isMainnet: boolean, btcTestnetType?: BTCTestnetType) => { + if (isMainnet) { + return MainnetInfo.BtcTimeLockConfigDep; + } + return btcTestnetType === 'Signet' ? TestnetInfo.BtcTimeSignetLockConfigDep : TestnetInfo.BtcTimeLockConfigDep; +}; export const getUniqueTypeScript = (isMainnet: boolean) => isMainnet ? MainnetInfo.UniqueTypeScript : TestnetInfo.UniqueTypeScript; diff --git a/packages/ckb/src/rgbpp/btc-jump-ckb.ts b/packages/ckb/src/rgbpp/btc-jump-ckb.ts index 6bafad84..a3400ce9 100644 --- a/packages/ckb/src/rgbpp/btc-jump-ckb.ts +++ b/packages/ckb/src/rgbpp/btc-jump-ckb.ts @@ -34,9 +34,9 @@ import { addressToScript, getTransactionSize } from '@nervosnetwork/ckb-sdk-util * @param rgbppLockArgsList The rgbpp assets cell lock script args array whose data structure is: out_index | bitcoin_tx_id * @param transferAmount The XUDT amount to be transferred * @param toCkbAddress The receiver ckb address - * @param witnessLockPlaceholderSize The WitnessArgs.lock placeholder bytes array size and the default value is 5000 - * @param ckbFeeRate The CKB transaction fee rate, default value is 1100 - * @param isMainnet + * @param witnessLockPlaceholderSize(Optional) The WitnessArgs.lock placeholder bytes array size and the default value is 5000 + * @param ckbFeeRate(Optional) The CKB transaction fee rate, default value is 1100 + * @param btcTestnetType(Optional) The Bitcoin Testnet type including Testnet3 and Signet, default value is Testnet3 */ export const genBtcJumpCkbVirtualTx = async ({ collector, @@ -46,6 +46,7 @@ export const genBtcJumpCkbVirtualTx = async ({ toCkbAddress, witnessLockPlaceholderSize, ckbFeeRate, + btcTestnetType, }: BtcJumpCkbVirtualTxParams): Promise => { const isMainnet = toCkbAddress.startsWith('ckb'); const xudtType = blockchain.Script.unpack(xudtTypeBytes) as CKBComponents.Script; @@ -134,7 +135,7 @@ export const genBtcJumpCkbVirtualTx = async ({ outputsData.push(otherRgbppCell.outputData); } - const cellDeps = await fetchTypeIdCellDeps(isMainnet, { rgbpp: true, xudt: true }); + const cellDeps = await fetchTypeIdCellDeps(isMainnet, { rgbpp: true, xudt: true }, btcTestnetType); if (needPaymasterCell) { cellDeps.push(getSecp256k1CellDep(isMainnet)); } diff --git a/packages/ckb/src/rgbpp/btc-time.ts b/packages/ckb/src/rgbpp/btc-time.ts index c7beecc5..a553075b 100644 --- a/packages/ckb/src/rgbpp/btc-time.ts +++ b/packages/ckb/src/rgbpp/btc-time.ts @@ -39,12 +39,14 @@ export const buildBtcTimeUnlockWitness = (btcTxProof: Hex): Hex => { * The btc time lock args data structure is: lock_script | after | new_bitcoin_tx_id * @param btcTimeCells The BTC time cells of xUDT * @param btcAssetsApi BTC Assets Api - * @param isMainnet + * @param isMainnet True is for BTC and CKB Mainnet, flase is for BTC and CKB Testnet(see btcTestnetType for details about BTC Testnet) + * @param btcTestnetType(Optional) The Bitcoin Testnet type including Testnet3 and Signet, default value is Testnet3 */ export const buildBtcTimeCellsSpentTx = async ({ btcTimeCells, btcAssetsApi, isMainnet, + btcTestnetType, }: BtcTimeCellsParams): Promise => { const sortedBtcTimeCells = btcTimeCells.sort(compareInputs); const inputs: CKBComponents.CellInput[] = sortedBtcTimeCells.map((cell) => ({ @@ -60,7 +62,11 @@ export const buildBtcTimeCellsSpentTx = async ({ const outputsData = sortedBtcTimeCells.map((cell) => cell.outputData); - const cellDeps: CKBComponents.CellDep[] = await fetchTypeIdCellDeps(isMainnet, { btcTime: true, xudt: true }); + const cellDeps: CKBComponents.CellDep[] = await fetchTypeIdCellDeps( + isMainnet, + { btcTime: true, xudt: true }, + btcTestnetType, + ); const witnesses: Hex[] = []; @@ -108,9 +114,8 @@ export const buildBtcTimeCellsSpentTx = async ({ * @param ckbRawTx The CKB raw transaction to be signed * @param collector The collector that collects CKB live cells and transactions * @param masterCkbAddress The master CKB address - * @param outputCapacityRange [u64; 2], filter cells by output capacity range, [inclusive, exclusive] - * @param ckbFeeRate The CKB transaction fee rate, default value is 1100 - * @param isMainnet + * @param outputCapacityRange(Optional) [u64; 2], filter cells by output capacity range, [inclusive, exclusive] + * @param ckbFeeRate(Optional) The CKB transaction fee rate, default value is 1100 */ export const signBtcTimeCellSpentTx = async ({ secp256k1PrivateKey, diff --git a/packages/ckb/src/rgbpp/btc-transfer.ts b/packages/ckb/src/rgbpp/btc-transfer.ts index 6ff45dbc..0c089072 100644 --- a/packages/ckb/src/rgbpp/btc-transfer.ts +++ b/packages/ckb/src/rgbpp/btc-transfer.ts @@ -52,10 +52,11 @@ import signWitnesses from '@nervosnetwork/ckb-sdk-core/lib/signWitnesses'; * @param xudtTypeBytes The serialized hex string of the XUDT type script * @param rgbppLockArgsList The rgbpp assets cell lock script args array whose data structure is: out_index | bitcoin_tx_id * @param transferAmount The XUDT amount to be transferred, if the noMergeOutputCells is true, the transferAmount will be ignored - * @param isMainnet - * @param noMergeOutputCells The noMergeOutputCells indicates whether the CKB outputs need to be merged. By default, the outputs will be merged. - * @param witnessLockPlaceholderSize The WitnessArgs.lock placeholder bytes array size and the default value is 5000 - * @param ckbFeeRate The CKB transaction fee rate, default value is 1100 + * @param isMainnet True is for BTC and CKB Mainnet, flase is for BTC and CKB Testnet(see btcTestnetType for details about BTC Testnet) + * @param noMergeOutputCells(Optional) The noMergeOutputCells indicates whether the CKB outputs need to be merged. By default, the outputs will be merged. + * @param witnessLockPlaceholderSize(Optional) The WitnessArgs.lock placeholder bytes array size and the default value is 5000 + * @param ckbFeeRate(Optional) The CKB transaction fee rate, default value is 1100 + * @param btcTestnetType(Optional) The Bitcoin Testnet type including Testnet3 and Signet, default value is Testnet3 */ export const genBtcTransferCkbVirtualTx = async ({ collector, @@ -66,6 +67,7 @@ export const genBtcTransferCkbVirtualTx = async ({ noMergeOutputCells, witnessLockPlaceholderSize, ckbFeeRate, + btcTestnetType, }: BtcTransferVirtualTxParams): Promise => { const xudtType = blockchain.Script.unpack(xudtTypeBytes) as CKBComponents.Script; @@ -170,7 +172,7 @@ export const genBtcTransferCkbVirtualTx = async ({ handleNonTargetRgbppCells(outputs.length); } - const cellDeps = await fetchTypeIdCellDeps(isMainnet, { rgbpp: true, xudt: true }); + const cellDeps = await fetchTypeIdCellDeps(isMainnet, { rgbpp: true, xudt: true }, btcTestnetType); if (needPaymasterCell) { cellDeps.push(getSecp256k1CellDep(isMainnet)); } @@ -224,7 +226,8 @@ export const genBtcTransferCkbVirtualTx = async ({ * @param xudtTypeBytes The serialized hex string of the XUDT type script * @param rgbppLockArgsList The rgbpp assets cell lock script args array whose data structure is: out_index | bitcoin_tx_id * @param rgbppReceivers The rgbpp receiver list which include toBtcAddress and transferAmount - * @param isMainnet + * @param isMainnet True is for BTC and CKB Mainnet, flase is for BTC and CKB Testnet(see btcTestnetType for details about BTC Testnet) + * @param btcTestnetType(Optional) The Bitcoin Testnet type including Testnet3 and Signet, default value is Testnet3 */ export const genBtcBatchTransferCkbVirtualTx = async ({ collector, @@ -232,6 +235,7 @@ export const genBtcBatchTransferCkbVirtualTx = async ({ rgbppLockArgsList, rgbppReceivers, isMainnet, + btcTestnetType, }: BtcBatchTransferVirtualTxParams): Promise => { const xudtType = blockchain.Script.unpack(xudtTypeBytes) as CKBComponents.Script; @@ -285,7 +289,7 @@ export const genBtcBatchTransferCkbVirtualTx = async ({ } const cellDeps = [ - ...(await fetchTypeIdCellDeps(isMainnet, { rgbpp: true, xudt: true })), + ...(await fetchTypeIdCellDeps(isMainnet, { rgbpp: true, xudt: true }, btcTestnetType)), getSecp256k1CellDep(isMainnet), ]; const witnesses: Hex[] = []; @@ -330,6 +334,7 @@ export const genBtcBatchTransferCkbVirtualTx = async ({ * @param collector The collector that collects CKB live cells and transactions * @param ckbRawTx CKB raw transaction * @param sumInputsCapacity The sum capacity of ckb inputs which is to be used to calculate ckb tx fee + * @param isMainnet True is for BTC and CKB Mainnet, flase is for BTC and CKB Testnet * @param ckbFeeRate The CKB transaction fee rate, default value is 1100 */ export const appendIssuerCellToBtcBatchTransfer = async ({ diff --git a/packages/ckb/src/rgbpp/ckb-jump-btc.ts b/packages/ckb/src/rgbpp/ckb-jump-btc.ts index ab3f5eb5..12deeea5 100644 --- a/packages/ckb/src/rgbpp/ckb-jump-btc.ts +++ b/packages/ckb/src/rgbpp/ckb-jump-btc.ts @@ -23,7 +23,6 @@ import { addressToScript, getTransactionSize } from '@nervosnetwork/ckb-sdk-util * @param transferAmount The XUDT amount to be transferred * @param witnessLockPlaceholderSize The WitnessArgs.lock placeholder bytes array size and the default value is 5000 * @param ckbFeeRate The CKB transaction fee rate, default value is 1100 - * @param isMainnet */ export const genCkbJumpBtcVirtualTx = async ({ collector, @@ -130,7 +129,6 @@ export const genCkbJumpBtcVirtualTx = async ({ * @param rgbppReceivers The rgbpp receiver list which include toRgbppLockArgs and transferAmount * @param witnessLockPlaceholderSize The WitnessArgs.lock placeholder bytes array size and the default value is 5000 * @param ckbFeeRate The CKB transaction fee rate, default value is 1100 - * @param isMainnet */ export const genCkbBatchJumpBtcVirtualTx = async ({ collector, diff --git a/packages/ckb/src/rgbpp/launch.ts b/packages/ckb/src/rgbpp/launch.ts index 58dc3e15..f17a3899 100644 --- a/packages/ckb/src/rgbpp/launch.ts +++ b/packages/ckb/src/rgbpp/launch.ts @@ -32,9 +32,10 @@ import { getTransactionSize, scriptToHash } from '@nervosnetwork/ckb-sdk-utils'; * @param ownerRgbppLockArgs The owner RGBPP lock args whose data structure is: out_index | bitcoin_tx_id * @param launchAmount The total amount of RGBPP assets issued * @param rgbppTokenInfo The RGBPP token info https://github.com/ckb-cell/unique-cell?tab=readme-ov-file#xudt-information - * @param witnessLockPlaceholderSize The WitnessArgs.lock placeholder bytes array size and the default value is 5000 - * @param ckbFeeRate The CKB transaction fee rate, default value is 1100 - * @param isMainnet + * @param isMainnet True is for BTC and CKB Mainnet, flase is for BTC and CKB Testnet(see btcTestnetType for details about BTC Testnet) + * @param witnessLockPlaceholderSize(Optional) The WitnessArgs.lock placeholder bytes array size and the default value is 5000 + * @param ckbFeeRate(Optional) The CKB transaction fee rate, default value is 1100 + * @param btcTestnetType(Optional) The Bitcoin Testnet type including Testnet3 and Signet, default value is Testnet3 */ export const genRgbppLaunchCkbVirtualTx = async ({ collector, @@ -44,6 +45,7 @@ export const genRgbppLaunchCkbVirtualTx = async ({ witnessLockPlaceholderSize, ckbFeeRate, isMainnet, + btcTestnetType, }: RgbppLaunchCkbVirtualTxParams): Promise => { const ownerLock = genRgbppLockScript(ownerRgbppLockArgs, isMainnet); let emptyCells = await collector.getCells({ lock: ownerLock }); @@ -77,7 +79,7 @@ export const genRgbppLaunchCkbVirtualTx = async ({ ]; const outputsData = [append0x(u128ToLe(launchAmount)), encodeRgbppTokenInfo(rgbppTokenInfo)]; - const cellDeps = await fetchTypeIdCellDeps(isMainnet, { rgbpp: true, xudt: true, unique: true }); + const cellDeps = await fetchTypeIdCellDeps(isMainnet, { rgbpp: true, xudt: true, unique: true }, btcTestnetType); const witnesses: Hex[] = inputs.map((_, index) => (index === 0 ? RGBPP_WITNESS_PLACEHOLDER : '0x')); diff --git a/packages/ckb/src/spore/cluster.ts b/packages/ckb/src/spore/cluster.ts index 224b295c..17baf942 100644 --- a/packages/ckb/src/spore/cluster.ts +++ b/packages/ckb/src/spore/cluster.ts @@ -19,8 +19,10 @@ import { bytesToHex, getTransactionSize } from '@nervosnetwork/ckb-sdk-utils'; * @param collector The collector that collects CKB live cells and transactions * @param rgbppLockArgs The rgbpp assets cell lock script args whose data structure is: out_index | bitcoin_tx_id * @param clusterData The cluster's data, including name and description. - * @param witnessLockPlaceholderSize The WitnessArgs.lock placeholder bytes array size and the default value is 5000 - * @param ckbFeeRate The CKB transaction fee rate, default value is 1100 + * @param isMainnet True is for BTC and CKB Mainnet, flase is for BTC and CKB Testnet(see btcTestnetType for details about BTC Testnet) + * @param witnessLockPlaceholderSize(Optional) The WitnessArgs.lock placeholder bytes array size and the default value is 5000 + * @param ckbFeeRate(Optional) The CKB transaction fee rate, default value is 1100 + * @param btcTestnetType(Optional) The Bitcoin Testnet type including Testnet3 and Signet, default value is Testnet3 */ export const genCreateClusterCkbVirtualTx = async ({ collector, @@ -29,6 +31,7 @@ export const genCreateClusterCkbVirtualTx = async ({ isMainnet, witnessLockPlaceholderSize, ckbFeeRate, + btcTestnetType, }: CreateClusterCkbVirtualTxParams): Promise => { const rgbppLock = { ...getRgbppLockScript(isMainnet), @@ -60,7 +63,10 @@ export const genCreateClusterCkbVirtualTx = async ({ }, ]; const outputsData: Hex[] = [bytesToHex(packRawClusterData(clusterData))]; - const cellDeps = [...(await fetchTypeIdCellDeps(isMainnet, { rgbpp: true })), getClusterTypeDep(isMainnet)]; + const cellDeps = [ + ...(await fetchTypeIdCellDeps(isMainnet, { rgbpp: true }, btcTestnetType)), + getClusterTypeDep(isMainnet), + ]; const sporeCoBuild = generateClusterCreateCoBuild(outputs[0], outputsData[0]); const witnesses = [RGBPP_WITNESS_PLACEHOLDER, sporeCoBuild]; diff --git a/packages/ckb/src/spore/leap.ts b/packages/ckb/src/spore/leap.ts index b7edefed..56f2622a 100644 --- a/packages/ckb/src/spore/leap.ts +++ b/packages/ckb/src/spore/leap.ts @@ -39,8 +39,10 @@ import { buildBtcTimeUnlockWitness } from '../rgbpp'; * @param sporeRgbppLockArgs The spore rgbpp cell lock script args whose data structure is: out_index | bitcoin_tx_id * @param sporeTypeBytes The spore type script serialized bytes * @param toCkbAddress The receiver ckb address - * @param witnessLockPlaceholderSize The WitnessArgs.lock placeholder bytes array size and the default value is 5000 - * @param ckbFeeRate The CKB transaction fee rate, default value is 1100 + * @param isMainnet True is for BTC and CKB Mainnet, flase is for BTC and CKB Testnet(see btcTestnetType for details about BTC Testnet) + * @param witnessLockPlaceholderSize(Optional) The WitnessArgs.lock placeholder bytes array size and the default value is 5000 + * @param ckbFeeRate(Optional) The CKB transaction fee rate, default value is 1100 + * @param btcTestnetType(Optional) The Bitcoin Testnet type including Testnet3 and Signet, default value is Testnet3 */ export const genLeapSporeFromBtcToCkbVirtualTx = async ({ collector, @@ -50,6 +52,7 @@ export const genLeapSporeFromBtcToCkbVirtualTx = async ({ isMainnet, witnessLockPlaceholderSize, ckbFeeRate, + btcTestnetType, }: LeapSporeFromBtcToCkbVirtualTxParams): Promise => { const sporeRgbppLock = { ...getRgbppLockScript(isMainnet), @@ -76,7 +79,10 @@ export const genLeapSporeFromBtcToCkbVirtualTx = async ({ }, ]; const outputsData: Hex[] = [sporeCell.outputData]; - const cellDeps = [...(await fetchTypeIdCellDeps(isMainnet, { rgbpp: true })), getSporeTypeDep(isMainnet)]; + const cellDeps = [ + ...(await fetchTypeIdCellDeps(isMainnet, { rgbpp: true }, btcTestnetType)), + getSporeTypeDep(isMainnet), + ]; const sporeCoBuild = generateSporeTransferCoBuild([sporeCell], outputs); const witnesses = [RGBPP_WITNESS_PLACEHOLDER, sporeCoBuild]; @@ -116,12 +122,14 @@ export const genLeapSporeFromBtcToCkbVirtualTx = async ({ * The btc time lock args data structure is: lock_script | after | new_bitcoin_tx_id * @param btcTimeCells The BTC time cells of spore * @param btcAssetsApi BTC Assets Api - * @param isMainnet + * @param isMainnet True is for BTC and CKB Mainnet, flase is for BTC and CKB Testnet(see btcTestnetType for details about BTC Testnet) + * @param btcTestnetType(Optional) The Bitcoin Testnet type including Testnet3 and Signet, default value is Testnet3 */ export const buildSporeBtcTimeCellsSpentTx = async ({ btcTimeCells, btcAssetsApi, isMainnet, + btcTestnetType, }: BtcTimeCellsParams): Promise => { const sortedBtcTimeCells = btcTimeCells.sort(compareInputs); const inputs: CKBComponents.CellInput[] = sortedBtcTimeCells.map((cell) => ({ @@ -138,7 +146,7 @@ export const buildSporeBtcTimeCellsSpentTx = async ({ const outputsData = sortedBtcTimeCells.map((cell) => cell.outputData); const cellDeps: CKBComponents.CellDep[] = [ - ...(await fetchTypeIdCellDeps(isMainnet, { btcTime: true })), + ...(await fetchTypeIdCellDeps(isMainnet, { btcTime: true }, btcTestnetType)), getSporeTypeDep(isMainnet), ]; @@ -191,8 +199,9 @@ export const buildSporeBtcTimeCellsSpentTx = async ({ * @param sporeRgbppLockArgs The spore rgbpp cell lock script args whose data structure is: out_index | bitcoin_tx_id * @param sporeTypeBytes The spore type script serialized bytes * @param toCkbAddress The receiver ckb address - * @param witnessLockPlaceholderSize The WitnessArgs.lock placeholder bytes array size and the default value is 5000 - * @param ckbFeeRate The CKB transaction fee rate, default value is 1100 + * @param isMainnet True is for BTC and CKB Mainnet, flase is for BTC and CKB Testnet + * @param witnessLockPlaceholderSize(Optional) The WitnessArgs.lock placeholder bytes array size and the default value is 5000 + * @param ckbFeeRate(Optional) The CKB transaction fee rate, default value is 1100 */ export const genLeapSporeFromCkbToBtcRawTx = async ({ collector, @@ -228,7 +237,7 @@ export const genLeapSporeFromCkbToBtcRawTx = async ({ }, ]; const outputsData: Hex[] = [sporeCell.outputData]; - const cellDeps = [...(await fetchTypeIdCellDeps(isMainnet, { rgbpp: true })), getSporeTypeDep(isMainnet)]; + const cellDeps = [getSporeTypeDep(isMainnet)]; const sporeCoBuild = generateSporeTransferCoBuild([sporeCell], outputs); const witnesses = [RGBPP_WITNESS_PLACEHOLDER, sporeCoBuild]; diff --git a/packages/ckb/src/spore/spore.ts b/packages/ckb/src/spore/spore.ts index d566f0bf..b3c69757 100644 --- a/packages/ckb/src/spore/spore.ts +++ b/packages/ckb/src/spore/spore.ts @@ -56,12 +56,15 @@ import signWitnesses from '@nervosnetwork/ckb-sdk-core/lib/signWitnesses'; * @param collector The collector that collects CKB live cells and transactions * @param clusterRgbppLockArgs The cluster rgbpp cell lock script args whose data structure is: out_index | bitcoin_tx_id * @param sporeDataList The spore's data list, including name and description. + * @param isMainnet True is for BTC and CKB Mainnet, flase is for BTC and CKB Testnet(see btcTestnetType for details about BTC Testnet) + * @param btcTestnetType(Optional) The Bitcoin Testnet type including Testnet3 and Signet, default value is Testnet3 */ export const genCreateSporeCkbVirtualTx = async ({ collector, clusterRgbppLockArgs, sporeDataList, isMainnet, + btcTestnetType, }: CreateSporeCkbVirtualTxParams): Promise => { const clusterRgbppLock = { ...getRgbppLockScript(isMainnet), @@ -116,7 +119,7 @@ export const genCreateSporeCkbVirtualTx = async ({ ]; const outputsData: Hex[] = [clusterCell.outputData, ...sporeOutputsData]; const cellDeps = [ - ...(await fetchTypeIdCellDeps(isMainnet, { rgbpp: true })), + ...(await fetchTypeIdCellDeps(isMainnet, { rgbpp: true }, btcTestnetType)), getClusterTypeDep(isMainnet), getSporeTypeDep(isMainnet), clusterCellDep, @@ -161,8 +164,8 @@ const CELL_DEP_SIZE = 32 + 4 + 1; * @param collector The collector that collects CKB live cells and transactions * @param ckbRawTx CKB raw transaction * @param sumInputsCapacity The sum capacity of ckb inputs which is to be used to calculate ckb tx fee - * @param witnessLockPlaceholderSize The WitnessArgs.lock placeholder bytes array size and the default value is 65 - * @param ckbFeeRate The CKB transaction fee rate, default value is 1100 + * @param witnessLockPlaceholderSize(Optional) The WitnessArgs.lock placeholder bytes array size and the default value is 65 + * @param ckbFeeRate(Optional) The CKB transaction fee rate, default value is 1100 */ export const buildAppendingIssuerCellToSporesCreateTx = async ({ issuerAddress, @@ -217,7 +220,8 @@ export const buildAppendingIssuerCellToSporesCreateTx = async ({ * @param collector The collector that collects CKB live cells and transactions * @param ckbRawTx CKB raw transaction * @param sumInputsCapacity The sum capacity of ckb inputs which is to be used to calculate ckb tx fee - * @param ckbFeeRate The CKB transaction fee rate, default value is 1100 + * @param isMainnet True is for BTC and CKB Mainnet, flase is for BTC and CKB Testnet(see btcTestnetType for details about BTC Testnet) + * @param ckbFeeRate(Optional) The CKB transaction fee rate, default value is 1100 */ export const appendIssuerCellToSporesCreate = async ({ secp256k1PrivateKey, @@ -285,8 +289,10 @@ export const appendIssuerCellToSporesCreate = async ({ * @param collector The collector that collects CKB live cells and transactions * @param sporeRgbppLockArgs The spore rgbpp cell lock script args whose data structure is: out_index | bitcoin_tx_id * @param sporeTypeBytes The spore type script serialized bytes - * @param witnessLockPlaceholderSize The WitnessArgs.lock placeholder bytes array size and the default value is 5000 - * @param ckbFeeRate The CKB transaction fee rate, default value is 1100 + * @param isMainnet True is for BTC and CKB Mainnet, flase is for BTC and CKB Testnet(see btcTestnetType for details about BTC Testnet) + * @param witnessLockPlaceholderSize(Optional) The WitnessArgs.lock placeholder bytes array size and the default value is 5000 + * @param ckbFeeRate(Optional) The CKB transaction fee rate, default value is 1100 + * @param btcTestnetType(Optional) The Bitcoin Testnet type including Testnet3 and Signet, default value is Testnet3 */ export const genTransferSporeCkbVirtualTx = async ({ collector, @@ -295,6 +301,7 @@ export const genTransferSporeCkbVirtualTx = async ({ isMainnet, witnessLockPlaceholderSize, ckbFeeRate, + btcTestnetType, }: TransferSporeCkbVirtualTxParams): Promise => { const sporeRgbppLock = { ...getRgbppLockScript(isMainnet), @@ -321,7 +328,10 @@ export const genTransferSporeCkbVirtualTx = async ({ }, ]; const outputsData: Hex[] = [sporeCell.outputData]; - const cellDeps = [...(await fetchTypeIdCellDeps(isMainnet, { rgbpp: true })), getSporeTypeDep(isMainnet)]; + const cellDeps = [ + ...(await fetchTypeIdCellDeps(isMainnet, { rgbpp: true }, btcTestnetType)), + getSporeTypeDep(isMainnet), + ]; const sporeCoBuild = generateSporeTransferCoBuild([sporeCell], outputs); const witnesses = [RGBPP_WITNESS_PLACEHOLDER, sporeCoBuild]; diff --git a/packages/ckb/src/types/common.ts b/packages/ckb/src/types/common.ts index 361889e4..cdaa02c5 100644 --- a/packages/ckb/src/types/common.ts +++ b/packages/ckb/src/types/common.ts @@ -2,3 +2,5 @@ export type Hex = string; export type U32 = bigint; export type Address = string; export type Capacity = bigint; + +export type BTCTestnetType = 'Testnet3' | 'Signet'; diff --git a/packages/ckb/src/types/rgbpp.ts b/packages/ckb/src/types/rgbpp.ts index 4bcc77c9..e25bd4d1 100644 --- a/packages/ckb/src/types/rgbpp.ts +++ b/packages/ckb/src/types/rgbpp.ts @@ -1,7 +1,7 @@ import { BtcAssetsApi, RgbppApiSpvProof } from '@rgbpp-sdk/service'; import { Collector } from '../collector'; import { IndexerCell } from './collector'; -import { Address, Hex } from './common'; +import { Address, Hex, BTCTestnetType } from './common'; export interface ConstructPaymasterParams { // The collector that collects CKB live cells and transactions @@ -25,7 +25,10 @@ export interface BtcTransferVirtualTxParams { rgbppLockArgsList: Hex[]; // The XUDT amount to be transferred, if the noMergeOutputCells is true, the transferAmount will be ignored transferAmount: bigint; + // True is for BTC and CKB Mainnet, flase is for BTC and CKB Testnet(see btcTestnetType for details about BTC Testnet) isMainnet: boolean; + // The Bitcoin Testnet type including Testnet3 and Signet, default value is Testnet3 + btcTestnetType?: BTCTestnetType; // The noMergeOutputCells indicates whether the CKB outputs need to be merged. By default, the outputs will be merged. noMergeOutputCells?: boolean; // The WitnessArgs.lock placeholder bytes array size and the default value is 5000 @@ -50,7 +53,10 @@ export interface BtcBatchTransferVirtualTxParams { rgbppLockArgsList: Hex[]; // The rgbpp receiver list which include toRgbppLockArgs and transferAmount rgbppReceivers: RgbppBtcAddressReceiver[]; + // True is for BTC and CKB Mainnet, flase is for BTC and CKB Testnet(see btcTestnetType for details about BTC Testnet) isMainnet: boolean; + // The Bitcoin Testnet type including Testnet3 and Signet, default value is Testnet3 + btcTestnetType?: BTCTestnetType; } export interface RgbppCkbVirtualTx { @@ -95,6 +101,8 @@ export interface AppendWitnessesParams { rgbppApiSpvProof: RgbppApiSpvProof; // The hex string of btc transaction, refer to https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/ts_src/transaction.ts#L609 btcTxBytes: Hex; + // The Bitcoin Testnet type including Testnet3 and Signet, default value is Testnet3 + btcTestnetType?: BTCTestnetType; } export interface AppendPaymasterCellAndSignTxParams { @@ -106,6 +114,7 @@ export interface AppendPaymasterCellAndSignTxParams { sumInputsCapacity: Hex; // The paymaster cell to be inserted into CKB transaction to pay an extra output cell paymasterCell: IndexerCell; + // True is for BTC and CKB Mainnet, flase is for BTC and CKB Testnet isMainnet: boolean; // The CKB transaction fee rate, default value is 1100 ckbFeeRate?: bigint; @@ -130,7 +139,10 @@ export interface BtcTimeCellsParams { btcTimeCells: IndexerCell[]; // BTC Assets Api btcAssetsApi: BtcAssetsApi; + // True is for BTC and CKB Mainnet, flase is for BTC and CKB Testnet isMainnet: boolean; + // The Bitcoin Testnet type including Testnet3 and Signet, default value is Testnet3 + btcTestnetType?: BTCTestnetType; } export interface SignBtcTimeCellsTxParams { @@ -142,6 +154,7 @@ export interface SignBtcTimeCellsTxParams { collector: Collector; // The master CKB address to pay the time cells spent tx fee masterCkbAddress: Address; + // True is for BTC and CKB Mainnet, flase is for BTC and CKB Testnet isMainnet: boolean; // [u64; 2], filter cells by output capacity range, [inclusive, exclusive] outputCapacityRange?: Hex[]; @@ -171,6 +184,7 @@ export interface UpdateCkbTxWithRealBtcTxIdParams { ckbRawTx: CKBComponents.RawTransaction; // The BTC transaction id btcTxId: Hex; + // True is for BTC and CKB Mainnet, flase is for BTC and CKB Testnet isMainnet: boolean; } @@ -216,6 +230,7 @@ export interface AppendIssuerCellToBtcBatchTransfer { ckbRawTx: CKBComponents.RawTransaction; // The sum capacity of the ckb inputs sumInputsCapacity: Hex; + // True is for BTC and CKB Mainnet, flase is for BTC and CKB Testnet isMainnet: boolean; // The CKB transaction fee rate, default value is 1100 ckbFeeRate?: bigint; @@ -242,9 +257,12 @@ export interface RgbppLaunchCkbVirtualTxParams { launchAmount: bigint; // The RGBPP token info https://github.com/ckb-cell/unique-cell?tab=readme-ov-file#xudt-information rgbppTokenInfo: RgbppTokenInfo; + // True is for BTC and CKB Mainnet, flase is for BTC and CKB Testnet(see btcTestnetType for details about BTC Testnet) + isMainnet: boolean; + // The Bitcoin Testnet type including Testnet3 and Signet, default value is Testnet3 + btcTestnetType?: BTCTestnetType; // The WitnessArgs.lock placeholder bytes array size and the default value is 5000 witnessLockPlaceholderSize?: number; // The CKB transaction fee rate, default value is 1100 ckbFeeRate?: bigint; - isMainnet: boolean; } diff --git a/packages/ckb/src/types/spore.ts b/packages/ckb/src/types/spore.ts index d599c591..0fe0a418 100644 --- a/packages/ckb/src/types/spore.ts +++ b/packages/ckb/src/types/spore.ts @@ -1,5 +1,5 @@ import { RawClusterData, RawSporeData } from '@spore-sdk/core'; -import { Address, Hex } from './common'; +import { Address, Hex, BTCTestnetType } from './common'; import { Collector } from '../collector'; import { IndexerCell } from './collector'; @@ -10,7 +10,10 @@ export interface CreateClusterCkbVirtualTxParams { rgbppLockArgs: Hex; // The cluster's data, including name and description. clusterData: RawClusterData; + // True is for BTC and CKB Mainnet, flase is for BTC and CKB Testnet isMainnet: boolean; + // The Bitcoin Testnet type including Testnet3 and Signet, default value is Testnet3 + btcTestnetType?: BTCTestnetType; // The WitnessArgs.lock placeholder bytes array size and the default value is 5000 witnessLockPlaceholderSize?: number; // The CKB transaction fee rate, default value is 1100 @@ -35,7 +38,10 @@ export interface CreateSporeCkbVirtualTxParams { clusterRgbppLockArgs: Hex; // The cluster's data, including name and description. sporeDataList: RawSporeData[]; + // True is for BTC and CKB Mainnet, flase is for BTC and CKB Testnet isMainnet: boolean; + // The Bitcoin Testnet type including Testnet3 and Signet, default value is Testnet3 + btcTestnetType?: BTCTestnetType; // The WitnessArgs.lock placeholder bytes array size and the default value is 5000 witnessLockPlaceholderSize?: number; // The CKB transaction fee rate, default value is 1100 @@ -81,6 +87,7 @@ export interface AppendIssuerCellToSporeCreate { ckbRawTx: CKBComponents.RawTransaction; // The sum capacity of the ckb inputs sumInputsCapacity: Hex; + // True is for BTC and CKB Mainnet, flase is for BTC and CKB Testnet isMainnet: boolean; // The CKB transaction fee rate, default value is 1100 ckbFeeRate?: bigint; @@ -100,7 +107,10 @@ export interface TransferSporeCkbVirtualTxParams { sporeRgbppLockArgs: Hex; // The spore type script serialized bytes sporeTypeBytes: Hex; + // True is for BTC and CKB Mainnet, flase is for BTC and CKB Testnet isMainnet: boolean; + // The Bitcoin Testnet type including Testnet3 and Signet, default value is Testnet3 + btcTestnetType?: BTCTestnetType; // The WitnessArgs.lock placeholder bytes array size and the default value is 5000 witnessLockPlaceholderSize?: number; // The CKB transaction fee rate, default value is 1100 @@ -131,7 +141,10 @@ export interface LeapSporeFromBtcToCkbVirtualTxParams { sporeTypeBytes: Hex; // The receiver ckb address toCkbAddress: Address; + // True is for BTC and CKB Mainnet, flase is for BTC and CKB Testnet isMainnet: boolean; + // The Bitcoin Testnet type including Testnet3 and Signet, default value is Testnet3 + btcTestnetType?: BTCTestnetType; // The WitnessArgs.lock placeholder bytes array size and the default value is 5000 witnessLockPlaceholderSize?: number; // The CKB transaction fee rate, default value is 1100 @@ -147,7 +160,10 @@ export interface LeapSporeFromCkbToBtcVirtualTxParams { toRgbppLockArgs: Hex; // The spore type script serialized bytes sporeTypeBytes: Hex; + // True is for BTC and CKB Mainnet, flase is for BTC and CKB Testnet isMainnet: boolean; + // The Bitcoin Testnet type including Testnet3 and Signet, default value is Testnet3 + btcTestnetType?: BTCTestnetType; // The WitnessArgs.lock placeholder bytes array size and the default value is 5000 witnessLockPlaceholderSize?: number; // The CKB transaction fee rate, default value is 1100 diff --git a/packages/ckb/src/utils/cell-dep.ts b/packages/ckb/src/utils/cell-dep.ts index 76f1e4cf..09c8f5ae 100644 --- a/packages/ckb/src/utils/cell-dep.ts +++ b/packages/ckb/src/utils/cell-dep.ts @@ -1,14 +1,17 @@ import axios from 'axios'; import { getBtcTimeLockDep, getRgbppLockDep, getUniqueTypeDep, getXudtDep } from '../constants'; +import { BTCTestnetType } from '../types'; interface CellDepsObject { rgbpp: { mainnet: CKBComponents.CellDep; testnet: CKBComponents.CellDep; + signet: CKBComponents.CellDep; }; btcTime: { mainnet: CKBComponents.CellDep; testnet: CKBComponents.CellDep; + signet: CKBComponents.CellDep; }; xudt: { testnet: CKBComponents.CellDep; @@ -44,6 +47,7 @@ export interface CellDepsSelected { export const fetchTypeIdCellDeps = async ( isMainnet: boolean, selected: CellDepsSelected, + btcTestnetType?: BTCTestnetType, ): Promise => { let rgbppLockDep = getRgbppLockDep(isMainnet); let btcTimeDep = getBtcTimeLockDep(isMainnet); @@ -52,8 +56,13 @@ export const fetchTypeIdCellDeps = async ( const cellDepsObj = await fetchCellDepsJson(); if (cellDepsObj) { - rgbppLockDep = isMainnet ? cellDepsObj.rgbpp.mainnet : cellDepsObj.rgbpp.testnet; - btcTimeDep = isMainnet ? cellDepsObj.btcTime.mainnet : cellDepsObj.btcTime.testnet; + if (btcTestnetType === 'Signet') { + rgbppLockDep = cellDepsObj.rgbpp.signet; + btcTimeDep = cellDepsObj.btcTime.signet; + } else { + rgbppLockDep = isMainnet ? cellDepsObj.rgbpp.mainnet : cellDepsObj.rgbpp.testnet; + btcTimeDep = isMainnet ? cellDepsObj.btcTime.mainnet : cellDepsObj.btcTime.testnet; + } if (!isMainnet) { xudtDep = cellDepsObj.xudt.testnet; uniqueDep = cellDepsObj.unique.testnet; diff --git a/packages/rgbpp/src/rgbpp/types.ts b/packages/rgbpp/src/rgbpp/types.ts index eb213eae..8fadba9d 100644 --- a/packages/rgbpp/src/rgbpp/types.ts +++ b/packages/rgbpp/src/rgbpp/types.ts @@ -29,6 +29,7 @@ export interface RgbppTransferBtcParams { export interface RgbppTransferTxParams { ckb: RgbppTransferCkbParams; btc: RgbppTransferBtcParams; + // True is for BTC and CKB Mainnet, flase is for BTC and CKB Testnet isMainnet: boolean; } From a019b217ff31905ebea4b5386328eaad95c89ef5 Mon Sep 17 00:00:00 2001 From: Dylan Duan Date: Wed, 12 Jun 2024 17:53:08 +0800 Subject: [PATCH 54/90] feat: Add testnet deployment for btc signet --- packages/ckb/src/constants/index.ts | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/ckb/src/constants/index.ts b/packages/ckb/src/constants/index.ts index b6d8be97..8d3e532c 100644 --- a/packages/ckb/src/constants/index.ts +++ b/packages/ckb/src/constants/index.ts @@ -110,34 +110,34 @@ const TestnetInfo = { // The CKB testnet RGB++ deployment information for the BTC Signet network RgbppSignetLockScript: { - codeHash: '0x61ca7a4796a4eb19ca4f0d065cb9b10ddcf002f10f7cbb810c706cb6bb5c3248', + codeHash: '0xd07598deec7ce7b5665310386b4abd06a6d48843e953c5cc2112ad0d5a220364', hashType: 'type', args: '', } as CKBComponents.Script, RgbppSignetLockDep: { - outPoint: { txHash: '0xf1de59e973b85791ec32debbba08dff80c63197e895eb95d67fc1e9f6b413e00', index: '0x0' }, + outPoint: { txHash: '0x61efdeddbaa0bb4132c0eb174b3e8002ff5ec430f61ba46f30768d683c516eec', index: '0x0' }, depType: 'code', } as CKBComponents.CellDep, RgbppSignetLockConfigDep: { - outPoint: { txHash: '0xf1de59e973b85791ec32debbba08dff80c63197e895eb95d67fc1e9f6b413e00', index: '0x1' }, + outPoint: { txHash: '0x61efdeddbaa0bb4132c0eb174b3e8002ff5ec430f61ba46f30768d683c516eec', index: '0x1' }, depType: 'code', } as CKBComponents.CellDep, BtcTimeSignetLockScript: { - codeHash: '0x00cdf8fab0f8ac638758ebf5ea5e4052b1d71e8a77b9f43139718621f6849326', + codeHash: '0x80a09eca26d77cea1f5a69471c59481be7404febf40ee90f886c36a948385b55', hashType: 'type', args: '', } as CKBComponents.Script, BtcTimeSignetLockDep: { - outPoint: { txHash: '0xde0f87878a97500f549418e5d46d2f7704c565a262aa17036c9c1c13ad638529', index: '0x0' }, + outPoint: { txHash: '0x5364b3535965e9eac9a35dd7af8e9e45a61d30a16e115923c032f80b28783e21', index: '0x0' }, depType: 'code', } as CKBComponents.CellDep, BtcTimeSignetLockConfigDep: { - outPoint: { txHash: '0xde0f87878a97500f549418e5d46d2f7704c565a262aa17036c9c1c13ad638529', index: '0x1' }, + outPoint: { txHash: '0x5364b3535965e9eac9a35dd7af8e9e45a61d30a16e115923c032f80b28783e21', index: '0x1' }, depType: 'code', } as CKBComponents.CellDep, }; From c1815c1cae056ffd32345943d8fcfd9c1cf6a74c Mon Sep 17 00:00:00 2001 From: Dylan Duan Date: Thu, 13 Jun 2024 09:51:11 +0800 Subject: [PATCH 55/90] feat: Add btc testnet type to RGB++ locks --- packages/ckb/README.md | 1 + packages/ckb/src/rgbpp/btc-jump-ckb.ts | 6 +-- packages/ckb/src/rgbpp/btc-time.ts | 5 ++- packages/ckb/src/rgbpp/btc-transfer.ts | 17 ++++----- packages/ckb/src/rgbpp/ckb-builder.ts | 2 +- packages/ckb/src/rgbpp/ckb-jump-btc.ts | 11 ++++-- packages/ckb/src/rgbpp/launch.ts | 4 +- packages/ckb/src/spore/cluster.ts | 8 +--- packages/ckb/src/spore/leap.ts | 5 ++- packages/ckb/src/spore/spore.ts | 17 +++------ packages/ckb/src/types/rgbpp.ts | 8 +++- packages/ckb/src/utils/rgbpp.ts | 52 +++++++++++++++----------- 12 files changed, 72 insertions(+), 64 deletions(-) diff --git a/packages/ckb/README.md b/packages/ckb/README.md index 0f3a4fbe..9ac2bccd 100644 --- a/packages/ckb/README.md +++ b/packages/ckb/README.md @@ -116,6 +116,7 @@ The method `genCkbJumpBtcVirtualTx` can generate a CKB transaction for RGB++ xUD * @param transferAmount The XUDT amount to be transferred * @param witnessLockPlaceholderSize(Optional) The WitnessArgs.lock placeholder bytes array size and the default value is 5000 * @param ckbFeeRate(Optional) The CKB transaction fee rate, default value is 1100 + * @param btcTestnetType(Optional) The Bitcoin Testnet type including Testnet3 and Signet, default value is Testnet3 */ export const genCkbJumpBtcVirtualTx = async ({ collector, diff --git a/packages/ckb/src/rgbpp/btc-jump-ckb.ts b/packages/ckb/src/rgbpp/btc-jump-ckb.ts index a3400ce9..cdf12bff 100644 --- a/packages/ckb/src/rgbpp/btc-jump-ckb.ts +++ b/packages/ckb/src/rgbpp/btc-jump-ckb.ts @@ -57,7 +57,7 @@ export const genBtcJumpCkbVirtualTx = async ({ const deduplicatedLockArgsList = deduplicateList(rgbppLockArgsList); - const rgbppLocks = deduplicatedLockArgsList.map((args) => genRgbppLockScript(args, isMainnet)); + const rgbppLocks = deduplicatedLockArgsList.map((args) => genRgbppLockScript(args, isMainnet, btcTestnetType)); let rgbppTargetCells: IndexerCell[] = []; let rgbppOtherTypeCells: IndexerCell[] = []; for await (const rgbppLock of rgbppLocks) { @@ -113,7 +113,7 @@ export const genBtcJumpCkbVirtualTx = async ({ const udtChangeCapacity = isCapacitySufficient ? sumInputsCapacity - receiverOutputCapacity : rgbppCellCapacity; outputs.push({ // The Vouts[0] for OP_RETURN and Vouts[1] for RGBPP assets, BTC time cells don't need btc tx out_index - lock: genRgbppLockScript(buildPreLockArgs(1), isMainnet), + lock: genRgbppLockScript(buildPreLockArgs(1), isMainnet, btcTestnetType), type: xudtType, capacity: append0x(udtChangeCapacity.toString(16)), }); @@ -130,7 +130,7 @@ export const genBtcJumpCkbVirtualTx = async ({ outputs.push({ ...otherRgbppCell.output, // Vouts[targetRgbppOutputLen + 1], ..., Vouts[targetRgbppOutputLen + rgbppOtherTypeCells.length] for other RGBPP assets - lock: genRgbppLockScript(buildPreLockArgs(targetRgbppOutputLen + index + 1), isMainnet), + lock: genRgbppLockScript(buildPreLockArgs(targetRgbppOutputLen + index + 1), isMainnet, btcTestnetType), }); outputsData.push(otherRgbppCell.outputData); } diff --git a/packages/ckb/src/rgbpp/btc-time.ts b/packages/ckb/src/rgbpp/btc-time.ts index a553075b..a3707087 100644 --- a/packages/ckb/src/rgbpp/btc-time.ts +++ b/packages/ckb/src/rgbpp/btc-time.ts @@ -116,6 +116,7 @@ export const buildBtcTimeCellsSpentTx = async ({ * @param masterCkbAddress The master CKB address * @param outputCapacityRange(Optional) [u64; 2], filter cells by output capacity range, [inclusive, exclusive] * @param ckbFeeRate(Optional) The CKB transaction fee rate, default value is 1100 + * @param isMainnet True is for BTC and CKB Mainnet, flase is for BTC and CKB Testnet */ export const signBtcTimeCellSpentTx = async ({ secp256k1PrivateKey, @@ -158,7 +159,6 @@ export const signBtcTimeCellSpentTx = async ({ const keyMap = new Map(); keyMap.set(scriptToHash(masterLock), secp256k1PrivateKey); - keyMap.set(scriptToHash(getBtcTimeLockScript(isMainnet)), ''); const cells = rawTx.inputs.map((input, index) => ({ outPoint: input.previousOutput, @@ -193,11 +193,12 @@ export const isBtcTimeCellsSpent = async ({ collector, ckbAddress, btcTxId, + btcTestnetType, }: BtcTimeCellStatusParams): Promise => { const isMainnet = ckbAddress.startsWith('ckb'); const lock = addressToScript(ckbAddress); const btcTimeLock: CKBComponents.Script = { - ...getBtcTimeLockScript(isMainnet), + ...getBtcTimeLockScript(isMainnet, btcTestnetType), args: genBtcTimeLockArgs(lock, btcTxId, BTC_JUMP_CONFIRMATION_BLOCKS), }; const btcTimeCells = await collector.getCells({ lock: btcTimeLock, isDataMustBeEmpty: false }); diff --git a/packages/ckb/src/rgbpp/btc-transfer.ts b/packages/ckb/src/rgbpp/btc-transfer.ts index 0c089072..de7db693 100644 --- a/packages/ckb/src/rgbpp/btc-transfer.ts +++ b/packages/ckb/src/rgbpp/btc-transfer.ts @@ -77,7 +77,7 @@ export const genBtcTransferCkbVirtualTx = async ({ const deduplicatedLockArgsList = deduplicateList(rgbppLockArgsList); - const rgbppLocks = deduplicatedLockArgsList.map((args) => genRgbppLockScript(args, isMainnet)); + const rgbppLocks = deduplicatedLockArgsList.map((args) => genRgbppLockScript(args, isMainnet, btcTestnetType)); let rgbppTargetCells: IndexerCell[] = []; let rgbppOtherTypeCells: IndexerCell[] = []; for await (const rgbppLock of rgbppLocks) { @@ -110,7 +110,7 @@ export const genBtcTransferCkbVirtualTx = async ({ outputs.push({ ...otherRgbppCell.output, // Vouts[targetRgbppOutputLen + 1], ..., Vouts[targetRgbppOutputLen + rgbppOtherTypeCells.length] for other RGBPP assets - lock: genRgbppLockScript(buildPreLockArgs(targetRgbppOutputLen + index + 1), isMainnet), + lock: genRgbppLockScript(buildPreLockArgs(targetRgbppOutputLen + index + 1), isMainnet, btcTestnetType), }); outputsData.push(otherRgbppCell.outputData); } @@ -127,7 +127,7 @@ export const genBtcTransferCkbVirtualTx = async ({ outputs.push({ ...targetRgbppCell.output, // The Vouts[0] for OP_RETURN and Vouts[1], ..., Vouts[rgbppTargetCells.length] for target RGBPP assets - lock: genRgbppLockScript(buildPreLockArgs(index + 1), isMainnet), + lock: genRgbppLockScript(buildPreLockArgs(index + 1), isMainnet, btcTestnetType), }); outputsData.push(targetRgbppCell.outputData); } @@ -149,7 +149,7 @@ export const genBtcTransferCkbVirtualTx = async ({ const receiverOutputCapacity = needRgbppChange ? BigInt(rgbppTargetCells[0].output.capacity) : sumInputsCapacity; // The Vouts[0] for OP_RETURN and Vouts[1] for target transfer RGBPP assets outputs.push({ - lock: genRgbppLockScript(buildPreLockArgs(1), isMainnet), + lock: genRgbppLockScript(buildPreLockArgs(1), isMainnet, btcTestnetType), type: xudtType, capacity: append0x(receiverOutputCapacity.toString(16)), }); @@ -162,7 +162,7 @@ export const genBtcTransferCkbVirtualTx = async ({ const udtChangeCapacity = isCapacitySufficient ? sumInputsCapacity - receiverOutputCapacity : rgbppCellCapacity; // The Vouts[2] for target change RGBPP assets outputs.push({ - lock: genRgbppLockScript(buildPreLockArgs(2), isMainnet), + lock: genRgbppLockScript(buildPreLockArgs(2), isMainnet, btcTestnetType), type: xudtType, capacity: append0x(udtChangeCapacity.toString(16)), }); @@ -243,7 +243,7 @@ export const genBtcBatchTransferCkbVirtualTx = async ({ throw new TypeAssetNotSupportedError('The type script asset is not supported now'); } - const rgbppLocks = rgbppLockArgsList.map((args) => genRgbppLockScript(args, isMainnet)); + const rgbppLocks = rgbppLockArgsList.map((args) => genRgbppLockScript(args, isMainnet, btcTestnetType)); let rgbppCells: IndexerCell[] = []; for await (const rgbppLock of rgbppLocks) { const cells = await collector.getCells({ lock: rgbppLock, type: xudtType }); @@ -261,7 +261,7 @@ export const genBtcBatchTransferCkbVirtualTx = async ({ const rpbppCellCapacity = calculateRgbppCellCapacity(xudtType); const outputs: CKBComponents.CellOutput[] = rgbppReceivers.map((_, index) => ({ // The Vouts[0] for OP_RETURN and Vouts[1], Vouts[2], ... for RGBPP assets - lock: genRgbppLockScript(buildPreLockArgs(index + 1), isMainnet), + lock: genRgbppLockScript(buildPreLockArgs(index + 1), isMainnet, btcTestnetType), type: xudtType, capacity: append0x(rpbppCellCapacity.toString(16)), })); @@ -281,7 +281,7 @@ export const genBtcBatchTransferCkbVirtualTx = async ({ rgbppChangeOutIndex = rgbppReceivers.length + 1; outputs.push({ // The Vouts[0] for OP_RETURN and Vouts[rgbppChangeOutIndex] for RGBPP change assets - lock: genRgbppLockScript(buildPreLockArgs(rgbppChangeOutIndex), isMainnet), + lock: genRgbppLockScript(buildPreLockArgs(rgbppChangeOutIndex), isMainnet, btcTestnetType), type: xudtType, capacity: append0x(rpbppCellCapacity.toString(16)), }); @@ -385,7 +385,6 @@ export const appendIssuerCellToBtcBatchTransfer = async ({ const keyMap = new Map(); keyMap.set(scriptToHash(issuerLock), secp256k1PrivateKey); - keyMap.set(scriptToHash(getRgbppLockScript(isMainnet)), ''); const issuerCellIndex = rgbppInputsLength; const cells = rawTx.inputs.map((input, index) => ({ diff --git a/packages/ckb/src/rgbpp/ckb-builder.ts b/packages/ckb/src/rgbpp/ckb-builder.ts index 85badfe6..82b39704 100644 --- a/packages/ckb/src/rgbpp/ckb-builder.ts +++ b/packages/ckb/src/rgbpp/ckb-builder.ts @@ -154,7 +154,7 @@ export const sendCkbTx = async ({ collector, signedTx }: SendCkbTxParams) => { * Replace the RGBPP_TX_ID_PLACEHOLDER with the real btc tx id of the rgbpp lock args and BTC time lock args * @param ckbRawTx CKB raw transaction * @param btcTxId The BTC transaction id - * @param isMainnet + * @param isMainnet True is for BTC and CKB Mainnet, flase is for BTC and CKB Testnet */ export const updateCkbTxWithRealBtcTxId = ({ ckbRawTx, diff --git a/packages/ckb/src/rgbpp/ckb-jump-btc.ts b/packages/ckb/src/rgbpp/ckb-jump-btc.ts index 12deeea5..1d506a86 100644 --- a/packages/ckb/src/rgbpp/ckb-jump-btc.ts +++ b/packages/ckb/src/rgbpp/ckb-jump-btc.ts @@ -21,8 +21,9 @@ import { addressToScript, getTransactionSize } from '@nervosnetwork/ckb-sdk-util * @param fromCkbAddress The from ckb address who will use his private key to sign the ckb tx * @param toRgbppLockArgs The receiver rgbpp lock script args whose data structure is: out_index | bitcoin_tx_id * @param transferAmount The XUDT amount to be transferred - * @param witnessLockPlaceholderSize The WitnessArgs.lock placeholder bytes array size and the default value is 5000 - * @param ckbFeeRate The CKB transaction fee rate, default value is 1100 + * @param witnessLockPlaceholderSize(Optional) The WitnessArgs.lock placeholder bytes array size and the default value is 5000 + * @param ckbFeeRate(Optional) The CKB transaction fee rate, default value is 1100 + * @param btcTestnetType(Optional) The Bitcoin Testnet type including Testnet3 and Signet, default value is Testnet3 */ export const genCkbJumpBtcVirtualTx = async ({ collector, @@ -32,6 +33,7 @@ export const genCkbJumpBtcVirtualTx = async ({ transferAmount, witnessLockPlaceholderSize, ckbFeeRate, + btcTestnetType, }: CkbJumpBtcVirtualTxParams): Promise => { const isMainnet = fromCkbAddress.startsWith('ckb'); const xudtType = blockchain.Script.unpack(xudtTypeBytes) as CKBComponents.Script; @@ -59,7 +61,7 @@ export const genCkbJumpBtcVirtualTx = async ({ const outputs: CKBComponents.CellOutput[] = [ { - lock: genRgbppLockScript(toRgbppLockArgs, isMainnet), + lock: genRgbppLockScript(toRgbppLockArgs, isMainnet, btcTestnetType), type: xudtType, capacity: append0x(rpbppCellCapacity.toString(16)), }, @@ -137,6 +139,7 @@ export const genCkbBatchJumpBtcVirtualTx = async ({ rgbppReceivers, witnessLockPlaceholderSize, ckbFeeRate, + btcTestnetType, }: CkbBatchJumpBtcVirtualTxParams): Promise => { const isMainnet = fromCkbAddress.startsWith('ckb'); const xudtType = blockchain.Script.unpack(xudtTypeBytes) as CKBComponents.Script; @@ -166,7 +169,7 @@ export const genCkbBatchJumpBtcVirtualTx = async ({ const rpbppCellCapacity = calculateRgbppCellCapacity(xudtType); const sumRgbppCellCapacity = rpbppCellCapacity * BigInt(rgbppReceivers.length); const outputs: CKBComponents.CellOutput[] = rgbppReceivers.map((receiver) => ({ - lock: genRgbppLockScript(receiver.toRgbppLockArgs, isMainnet), + lock: genRgbppLockScript(receiver.toRgbppLockArgs, isMainnet, btcTestnetType), type: xudtType, capacity: append0x(rpbppCellCapacity.toString(16)), })); diff --git a/packages/ckb/src/rgbpp/launch.ts b/packages/ckb/src/rgbpp/launch.ts index f17a3899..e112eb3e 100644 --- a/packages/ckb/src/rgbpp/launch.ts +++ b/packages/ckb/src/rgbpp/launch.ts @@ -47,7 +47,7 @@ export const genRgbppLaunchCkbVirtualTx = async ({ isMainnet, btcTestnetType, }: RgbppLaunchCkbVirtualTxParams): Promise => { - const ownerLock = genRgbppLockScript(ownerRgbppLockArgs, isMainnet); + const ownerLock = genRgbppLockScript(ownerRgbppLockArgs, isMainnet, btcTestnetType); let emptyCells = await collector.getCells({ lock: ownerLock }); if (!emptyCells || emptyCells.length === 0) { throw new NoLiveCellError('The owner address has no empty cells'); @@ -61,7 +61,7 @@ export const genRgbppLaunchCkbVirtualTx = async ({ let rgbppCellCapacity = sumInputsCapacity - infoCellCapacity; const outputs: CKBComponents.CellOutput[] = [ { - lock: genRgbppLockScript(buildPreLockArgs(1), isMainnet), + lock: genRgbppLockScript(buildPreLockArgs(1), isMainnet, btcTestnetType), type: { ...getXudtTypeScript(isMainnet), args: append0x(scriptToHash(ownerLock)), diff --git a/packages/ckb/src/spore/cluster.ts b/packages/ckb/src/spore/cluster.ts index 17baf942..57b2bb46 100644 --- a/packages/ckb/src/spore/cluster.ts +++ b/packages/ckb/src/spore/cluster.ts @@ -8,7 +8,6 @@ import { RGBPP_WITNESS_PLACEHOLDER, getClusterTypeDep, getClusterTypeScript, - getRgbppLockScript, } from '../constants'; import { generateClusterCreateCoBuild, generateClusterId } from '../utils/spore'; import { NoRgbppLiveCellError } from '../error'; @@ -33,10 +32,7 @@ export const genCreateClusterCkbVirtualTx = async ({ ckbFeeRate, btcTestnetType, }: CreateClusterCkbVirtualTxParams): Promise => { - const rgbppLock = { - ...getRgbppLockScript(isMainnet), - args: append0x(rgbppLockArgs), - }; + const rgbppLock = genRgbppLockScript(rgbppLockArgs, isMainnet, btcTestnetType); const rgbppCells = await collector.getCells({ lock: rgbppLock }); if (!rgbppCells || rgbppCells.length === 0) { throw new NoRgbppLiveCellError('No rgbpp cells found with the rgbpp lock args'); @@ -55,7 +51,7 @@ export const genCreateClusterCkbVirtualTx = async ({ { ...rgbppCell.output, // The BTC transaction Vouts[0] for OP_RETURN, Vouts[1] for cluster - lock: genRgbppLockScript(buildPreLockArgs(1), isMainnet), + lock: genRgbppLockScript(buildPreLockArgs(1), isMainnet, btcTestnetType), type: { ...getClusterTypeScript(isMainnet), args: clusterId, diff --git a/packages/ckb/src/spore/leap.ts b/packages/ckb/src/spore/leap.ts index 56f2622a..8b1a896e 100644 --- a/packages/ckb/src/spore/leap.ts +++ b/packages/ckb/src/spore/leap.ts @@ -55,7 +55,7 @@ export const genLeapSporeFromBtcToCkbVirtualTx = async ({ btcTestnetType, }: LeapSporeFromBtcToCkbVirtualTxParams): Promise => { const sporeRgbppLock = { - ...getRgbppLockScript(isMainnet), + ...getRgbppLockScript(isMainnet, btcTestnetType), args: append0x(sporeRgbppLockArgs), }; const sporeCells = await collector.getCells({ lock: sporeRgbppLock, isDataMustBeEmpty: false }); @@ -211,6 +211,7 @@ export const genLeapSporeFromCkbToBtcRawTx = async ({ isMainnet, witnessLockPlaceholderSize, ckbFeeRate, + btcTestnetType, }: LeapSporeFromCkbToBtcVirtualTxParams): Promise => { const fromLock = addressToScript(fromCkbAddress); const sporeType = blockchain.Script.unpack(sporeTypeBytes) as CKBComponents.Script; @@ -231,7 +232,7 @@ export const genLeapSporeFromCkbToBtcRawTx = async ({ { ...sporeCell.output, lock: { - ...getRgbppLockScript(isMainnet), + ...getRgbppLockScript(isMainnet, btcTestnetType), args: append0x(toRgbppLockArgs), }, }, diff --git a/packages/ckb/src/spore/spore.ts b/packages/ckb/src/spore/spore.ts index b3c69757..689a3898 100644 --- a/packages/ckb/src/spore/spore.ts +++ b/packages/ckb/src/spore/spore.ts @@ -66,10 +66,7 @@ export const genCreateSporeCkbVirtualTx = async ({ isMainnet, btcTestnetType, }: CreateSporeCkbVirtualTxParams): Promise => { - const clusterRgbppLock = { - ...getRgbppLockScript(isMainnet), - args: append0x(clusterRgbppLockArgs), - }; + const clusterRgbppLock = genRgbppLockScript(clusterRgbppLockArgs, isMainnet, btcTestnetType); const clusterCells = await collector.getCells({ lock: clusterRgbppLock, isDataMustBeEmpty: false }); if (!clusterCells || clusterCells.length === 0) { throw new NoRgbppLiveCellError('No cluster rgbpp cells found with the cluster rgbpp lock args'); @@ -99,7 +96,7 @@ export const genCreateSporeCkbVirtualTx = async ({ const sporeOutputs = sporeDataList.map((data, index) => ({ // The BTC transaction Vouts[0] for OP_RETURN, Vouts[1] for cluster and Vouts[2]... for spore - lock: genRgbppLockScript(buildPreLockArgs(index + 2), isMainnet), + lock: genRgbppLockScript(buildPreLockArgs(index + 2), isMainnet, btcTestnetType), type: { ...getSporeTypeScript(isMainnet), // The CKB transaction outputs[0] fro cluster and outputs[1]... for spore @@ -113,7 +110,7 @@ export const genCreateSporeCkbVirtualTx = async ({ { ...clusterCell.output, // The BTC transaction Vouts[0] for OP_RETURN, Vouts[1] for cluster - lock: genRgbppLockScript(buildPreLockArgs(1), isMainnet), + lock: genRgbppLockScript(buildPreLockArgs(1), isMainnet, btcTestnetType), }, ...sporeOutputs, ]; @@ -248,7 +245,6 @@ export const appendIssuerCellToSporesCreate = async ({ const keyMap = new Map(); keyMap.set(scriptToHash(issuerLock), secp256k1PrivateKey); - keyMap.set(scriptToHash(getRgbppLockScript(isMainnet)), ''); const issuerCellIndex = rgbppInputsLength; const cells = rawTx.inputs.map((input, index) => ({ @@ -303,10 +299,7 @@ export const genTransferSporeCkbVirtualTx = async ({ ckbFeeRate, btcTestnetType, }: TransferSporeCkbVirtualTxParams): Promise => { - const sporeRgbppLock = { - ...getRgbppLockScript(isMainnet), - args: append0x(sporeRgbppLockArgs), - }; + const sporeRgbppLock = genRgbppLockScript(sporeRgbppLockArgs, isMainnet, btcTestnetType); const sporeCells = await collector.getCells({ lock: sporeRgbppLock, isDataMustBeEmpty: false }); throwErrorWhenSporeCellsInvalid(sporeCells, sporeTypeBytes, isMainnet); @@ -324,7 +317,7 @@ export const genTransferSporeCkbVirtualTx = async ({ { ...sporeCell.output, // The BTC transaction Vouts[0] for OP_RETURN, Vouts[1] for spore - lock: genRgbppLockScript(buildPreLockArgs(1), isMainnet), + lock: genRgbppLockScript(buildPreLockArgs(1), isMainnet, btcTestnetType), }, ]; const outputsData: Hex[] = [sporeCell.outputData]; diff --git a/packages/ckb/src/types/rgbpp.ts b/packages/ckb/src/types/rgbpp.ts index e25bd4d1..f757d1fd 100644 --- a/packages/ckb/src/types/rgbpp.ts +++ b/packages/ckb/src/types/rgbpp.ts @@ -101,8 +101,6 @@ export interface AppendWitnessesParams { rgbppApiSpvProof: RgbppApiSpvProof; // The hex string of btc transaction, refer to https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/ts_src/transaction.ts#L609 btcTxBytes: Hex; - // The Bitcoin Testnet type including Testnet3 and Signet, default value is Testnet3 - btcTestnetType?: BTCTestnetType; } export interface AppendPaymasterCellAndSignTxParams { @@ -177,6 +175,8 @@ export interface CkbJumpBtcVirtualTxParams { witnessLockPlaceholderSize?: number; // The CKB transaction fee rate, default value is 1100 ckbFeeRate?: bigint; + // The Bitcoin Testnet type including Testnet3 and Signet, default value is Testnet3 + btcTestnetType?: BTCTestnetType; } export interface UpdateCkbTxWithRealBtcTxIdParams { @@ -195,6 +195,8 @@ export interface BtcTimeCellStatusParams { ckbAddress: Address; // The BTC transaction id btcTxId: Hex; + // The Bitcoin Testnet type including Testnet3 and Signet, default value is Testnet3 + btcTestnetType?: BTCTestnetType; } export interface RgbppLockArgsReceiver { @@ -217,6 +219,8 @@ export interface CkbBatchJumpBtcVirtualTxParams { witnessLockPlaceholderSize?: number; // The CKB transaction fee rate, default value is 1100 ckbFeeRate?: bigint; + // The Bitcoin Testnet type including Testnet3 and Signet, default value is Testnet3 + btcTestnetType?: BTCTestnetType; } export interface AppendIssuerCellToBtcBatchTransfer { diff --git a/packages/ckb/src/utils/rgbpp.ts b/packages/ckb/src/utils/rgbpp.ts index 19515685..8d09c4c1 100644 --- a/packages/ckb/src/utils/rgbpp.ts +++ b/packages/ckb/src/utils/rgbpp.ts @@ -1,5 +1,5 @@ import { sha256 } from 'js-sha256'; -import { Hex, IndexerCell, RgbppCkbVirtualTx, RgbppTokenInfo, SpvClientCellTxProof } from '../types'; +import { BTCTestnetType, Hex, IndexerCell, RgbppCkbVirtualTx, RgbppTokenInfo, SpvClientCellTxProof } from '../types'; import { append0x, remove0x, reverseHex, u32ToLe, u8ToHex, utf8ToHex } from './hex'; import { BTC_JUMP_CONFIRMATION_BLOCKS, @@ -31,9 +31,9 @@ import { } from '../error'; import { calculateRgbppCellCapacity, isScriptEqual, isUDTTypeSupported } from './ckb-tx'; -export const genRgbppLockScript = (rgbppLockArgs: Hex, isMainnet: boolean) => { +export const genRgbppLockScript = (rgbppLockArgs: Hex, isMainnet: boolean, btcTestnetType?: BTCTestnetType) => { return { - ...getRgbppLockScript(isMainnet), + ...getRgbppLockScript(isMainnet, btcTestnetType), args: append0x(rgbppLockArgs), } as CKBComponents.Script; }; @@ -51,10 +51,14 @@ export const genBtcTimeLockArgs = (lock: CKBComponents.Script, btcTxId: Hex, aft btc_txid: Byte32, } */ -export const genBtcTimeLockScript = (toLock: CKBComponents.Script, isMainnet: boolean) => { +export const genBtcTimeLockScript = ( + toLock: CKBComponents.Script, + isMainnet: boolean, + btcTestnetType?: BTCTestnetType, +) => { const args = genBtcTimeLockArgs(toLock, RGBPP_TX_ID_PLACEHOLDER, BTC_JUMP_CONFIRMATION_BLOCKS); return { - ...getBtcTimeLockScript(isMainnet), + ...getBtcTimeLockScript(isMainnet, btcTestnetType), args, } as CKBComponents.Script; }; @@ -113,16 +117,6 @@ export const btcTxIdFromBtcTimeLockArgs = (args: Hex): Hex => { return reverseHex(append0x(btcTimeLockArgs.btcTxid)); }; -export const isRgbppLockOrBtcTimeLock = (lock: CKBComponents.Script, isMainnet: boolean) => { - const rgbppLock = getRgbppLockScript(isMainnet); - const isRgbppLock = lock.codeHash === rgbppLock.codeHash && lock.hashType === rgbppLock.hashType; - - const btcTimeLock = getBtcTimeLockScript(isMainnet); - const isBtcTimeLock = lock.codeHash === btcTimeLock.codeHash && lock.hashType === btcTimeLock.hashType; - - return isRgbppLock || isBtcTimeLock; -}; - /** * https://learnmeabitcoin.com/technical/general/byte-order/ * Whenever you're working with transaction/block hashes internally (e.g. inside raw bitcoin data), you use the natural byte order. @@ -164,10 +158,15 @@ export const replaceLockArgsWithRealBtcTxId = (lockArgs: Hex, txId: Hex): Hex => return `0x${remove0x(lockArgs).substring(0, argsLength - BTC_TX_ID_SIZE)}${remove0x(reverseHex(txId))}`; }; +const BTC_TESTNETS: BTCTestnetType[] = ['Testnet3', 'Signet']; +const isLockEqual = (lock1: CKBComponents.Script, lock2: CKBComponents.Script) => + lock1.codeHash === lock2.codeHash && lock1.hashType === lock2.hashType; + export const isRgbppLockCell = (cell: CKBComponents.CellOutput, isMainnet: boolean): boolean => { - const rgbppLock = getRgbppLockScript(isMainnet); - const isRgbppLock = cell.lock.codeHash === rgbppLock.codeHash && cell.lock.hashType === rgbppLock.hashType; - return isRgbppLock; + if (isMainnet) { + return isLockEqual(cell.lock, getRgbppLockScript(isMainnet)); + } + return BTC_TESTNETS.some((network) => isLockEqual(cell.lock, getRgbppLockScript(isMainnet, network))); }; export const isRgbppLockCellIgnoreChain = (cell: CKBComponents.CellOutput): boolean => { @@ -175,9 +174,20 @@ export const isRgbppLockCellIgnoreChain = (cell: CKBComponents.CellOutput): bool }; export const isBtcTimeLockCell = (cell: CKBComponents.CellOutput, isMainnet: boolean): boolean => { - const btcTimeLock = getBtcTimeLockScript(isMainnet); - const isBtcTimeLock = cell.lock.codeHash === btcTimeLock.codeHash && cell.lock.hashType === btcTimeLock.hashType; - return isBtcTimeLock; + if (isMainnet) { + return isLockEqual(cell.lock, getBtcTimeLockScript(isMainnet)); + } + return BTC_TESTNETS.some((network) => isLockEqual(cell.lock, getBtcTimeLockScript(isMainnet, network))); +}; + +export const isRgbppLockOrBtcTimeLock = (lock: CKBComponents.Script, isMainnet: boolean) => { + if (isMainnet) { + return isLockEqual(lock, getRgbppLockScript(isMainnet)) || isLockEqual(lock, getBtcTimeLockScript(isMainnet)); + } + return BTC_TESTNETS.flatMap((network) => [ + getRgbppLockScript(isMainnet, network), + getBtcTimeLockScript(isMainnet, network), + ]).some((script) => isLockEqual(script, lock)); }; export const transformSpvProof = (spvProof: RgbppApiSpvProof): SpvClientCellTxProof => { From 7571e314d72bdefd7b9dee4928623908b4c854da Mon Sep 17 00:00:00 2001 From: Dylan Duan Date: Thu, 13 Jun 2024 09:52:25 +0800 Subject: [PATCH 56/90] feat: Add btc testnet type to rgbpp package --- packages/rgbpp/src/rgbpp/types.ts | 4 +++- packages/rgbpp/src/rgbpp/xudt.ts | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/packages/rgbpp/src/rgbpp/types.ts b/packages/rgbpp/src/rgbpp/types.ts index 8fadba9d..d34a03fd 100644 --- a/packages/rgbpp/src/rgbpp/types.ts +++ b/packages/rgbpp/src/rgbpp/types.ts @@ -1,5 +1,5 @@ import { DataSource } from '@rgbpp-sdk/btc'; -import { BtcTransferVirtualTxResult, Collector, Hex } from '@rgbpp-sdk/ckb'; +import { BTCTestnetType, BtcTransferVirtualTxResult, Collector, Hex } from '@rgbpp-sdk/ckb'; export interface RgbppTransferCkbParams { // The collector that collects CKB live cells and transactions @@ -24,6 +24,8 @@ export interface RgbppTransferBtcParams { fromPubkey?: Hex; // The fee rate of the BTC transaction feeRate?: number; + // The Bitcoin Testnet type including Testnet3 and Signet, default value is Testnet3 + testnetType?: BTCTestnetType; } export interface RgbppTransferTxParams { diff --git a/packages/rgbpp/src/rgbpp/xudt.ts b/packages/rgbpp/src/rgbpp/xudt.ts index 21a9eaf3..f527f1b1 100644 --- a/packages/rgbpp/src/rgbpp/xudt.ts +++ b/packages/rgbpp/src/rgbpp/xudt.ts @@ -18,7 +18,8 @@ import { RgbppTransferTxParams, RgbppTransferTxResult } from './types'; * @param toAddress The receiver BTC address * @param dataSource The BTC data source * @param feeRate The fee rate of the BTC transaction - * @param isMainnet + * @param isMainnet True is for BTC and CKB Mainnet, flase is for BTC and CKB Testnet(see btcTestnetType for details about BTC Testnet) + * @param btcTestnetType(Optional) The Bitcoin Testnet type including Testnet3 and Signet, default value is Testnet3 */ export const buildRgbppTransferTx = async ({ ckb: { collector, xudtTypeArgs, rgbppLockArgsList, transferAmount, feeRate: ckbFeeRate }, @@ -37,6 +38,7 @@ export const buildRgbppTransferTx = async ({ transferAmount, isMainnet, ckbFeeRate, + btcTestnetType: btc.testnetType, }); const { commitment, ckbRawTx } = ckbVirtualTxResult; From 049511645326bd743cf378333b2c97c070f40f02 Mon Sep 17 00:00:00 2001 From: Dylan Duan Date: Thu, 13 Jun 2024 13:24:27 +0800 Subject: [PATCH 57/90] feat: Add btc time lock script for signet network --- packages/ckb/src/rgbpp/btc-jump-ckb.ts | 2 +- packages/ckb/src/rgbpp/launch.ts | 2 +- packages/ckb/src/spore/leap.ts | 2 +- packages/rgbpp/src/rgbpp/xudt.ts | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/ckb/src/rgbpp/btc-jump-ckb.ts b/packages/ckb/src/rgbpp/btc-jump-ckb.ts index cdf12bff..d5521635 100644 --- a/packages/ckb/src/rgbpp/btc-jump-ckb.ts +++ b/packages/ckb/src/rgbpp/btc-jump-ckb.ts @@ -99,7 +99,7 @@ export const genBtcJumpCkbVirtualTx = async ({ // The BTC time cell does not need to be bound to the BTC UTXO const outputs: CKBComponents.CellOutput[] = [ { - lock: genBtcTimeLockScript(toLock, isMainnet), + lock: genBtcTimeLockScript(toLock, isMainnet, btcTestnetType), type: xudtType, capacity: append0x(receiverOutputCapacity.toString(16)), }, diff --git a/packages/ckb/src/rgbpp/launch.ts b/packages/ckb/src/rgbpp/launch.ts index e112eb3e..00adbf79 100644 --- a/packages/ckb/src/rgbpp/launch.ts +++ b/packages/ckb/src/rgbpp/launch.ts @@ -69,7 +69,7 @@ export const genRgbppLaunchCkbVirtualTx = async ({ capacity: append0x(rgbppCellCapacity.toString(16)), }, { - lock: genBtcTimeLockScript(UNLOCKABLE_LOCK_SCRIPT, isMainnet), + lock: genBtcTimeLockScript(UNLOCKABLE_LOCK_SCRIPT, isMainnet, btcTestnetType), type: { ...getUniqueTypeScript(isMainnet), args: generateUniqueTypeArgs(inputs[0], 1), diff --git a/packages/ckb/src/spore/leap.ts b/packages/ckb/src/spore/leap.ts index 8b1a896e..ffa62fbd 100644 --- a/packages/ckb/src/spore/leap.ts +++ b/packages/ckb/src/spore/leap.ts @@ -75,7 +75,7 @@ export const genLeapSporeFromBtcToCkbVirtualTx = async ({ const outputs: CKBComponents.CellOutput[] = [ { ...sporeCell.output, - lock: genBtcTimeLockScript(toLock, isMainnet), + lock: genBtcTimeLockScript(toLock, isMainnet, btcTestnetType), }, ]; const outputsData: Hex[] = [sporeCell.outputData]; diff --git a/packages/rgbpp/src/rgbpp/xudt.ts b/packages/rgbpp/src/rgbpp/xudt.ts index f527f1b1..2c5dbb1c 100644 --- a/packages/rgbpp/src/rgbpp/xudt.ts +++ b/packages/rgbpp/src/rgbpp/xudt.ts @@ -19,7 +19,7 @@ import { RgbppTransferTxParams, RgbppTransferTxResult } from './types'; * @param dataSource The BTC data source * @param feeRate The fee rate of the BTC transaction * @param isMainnet True is for BTC and CKB Mainnet, flase is for BTC and CKB Testnet(see btcTestnetType for details about BTC Testnet) - * @param btcTestnetType(Optional) The Bitcoin Testnet type including Testnet3 and Signet, default value is Testnet3 + * @param testnetType(Optional) The Bitcoin Testnet type including Testnet3 and Signet, default value is Testnet3 */ export const buildRgbppTransferTx = async ({ ckb: { collector, xudtTypeArgs, rgbppLockArgsList, transferAmount, feeRate: ckbFeeRate }, From c2a32a5c89e14c0572e17ba933458842625b7493 Mon Sep 17 00:00:00 2001 From: Dylan Duan Date: Thu, 13 Jun 2024 16:58:06 +0800 Subject: [PATCH 58/90] fix: Update fetchTypeIdCellDeps signet parameter --- packages/ckb/src/utils/cell-dep.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/ckb/src/utils/cell-dep.ts b/packages/ckb/src/utils/cell-dep.ts index 09c8f5ae..c8e2555f 100644 --- a/packages/ckb/src/utils/cell-dep.ts +++ b/packages/ckb/src/utils/cell-dep.ts @@ -49,8 +49,8 @@ export const fetchTypeIdCellDeps = async ( selected: CellDepsSelected, btcTestnetType?: BTCTestnetType, ): Promise => { - let rgbppLockDep = getRgbppLockDep(isMainnet); - let btcTimeDep = getBtcTimeLockDep(isMainnet); + let rgbppLockDep = getRgbppLockDep(isMainnet, btcTestnetType); + let btcTimeDep = getBtcTimeLockDep(isMainnet, btcTestnetType); let xudtDep = getXudtDep(isMainnet); let uniqueDep = getUniqueTypeDep(isMainnet); From a40bb1f7764ef161cc8fc355d7d154c8da74fdf7 Mon Sep 17 00:00:00 2001 From: Dylan Duan Date: Thu, 13 Jun 2024 17:07:57 +0800 Subject: [PATCH 59/90] feat: Support signet for rgbpp xudt examples --- .gitignore | 2 ++ examples/rgbpp/xudt/1-ckb-leap-btc.ts | 9 +++++--- examples/rgbpp/xudt/2-btc-transfer.ts | 12 ++++++---- examples/rgbpp/xudt/3-btc-leap-ckb.ts | 8 +++++-- examples/rgbpp/xudt/4-unlock-btc-time-cell.ts | 7 +++--- .../rgbpp/xudt/launch/1-prepare-launch.ts | 8 ++++--- examples/rgbpp/xudt/launch/2-launch-rgbpp.ts | 10 +++++--- .../rgbpp/xudt/launch/3-distribute-rgbpp.ts | 23 +++++++++++++++---- examples/rgbpp/xudt/local/2-btc-transfer.ts | 18 +++++++++------ examples/rgbpp/xudt/local/3-btc-leap-ckb.ts | 18 ++++++++++----- pnpm-lock.yaml | 2 +- 11 files changed, 80 insertions(+), 37 deletions(-) diff --git a/.gitignore b/.gitignore index f3c703cd..c7f02b23 100644 --- a/.gitignore +++ b/.gitignore @@ -42,3 +42,5 @@ devbox.json devbox.lock .envrc +# examples logs +examples/rgbpp/logs \ No newline at end of file diff --git a/examples/rgbpp/xudt/1-ckb-leap-btc.ts b/examples/rgbpp/xudt/1-ckb-leap-btc.ts index a979acdc..e729b91b 100644 --- a/examples/rgbpp/xudt/1-ckb-leap-btc.ts +++ b/examples/rgbpp/xudt/1-ckb-leap-btc.ts @@ -1,7 +1,7 @@ import { serializeScript } from '@nervosnetwork/ckb-sdk-utils'; import { genCkbJumpBtcVirtualTx } from 'rgbpp'; import { getSecp256k1CellDep, buildRgbppLockArgs, getXudtTypeScript } from 'rgbpp/ckb'; -import { CKB_PRIVATE_KEY, isMainnet, collector, ckbAddress } from '../env'; +import { CKB_PRIVATE_KEY, isMainnet, collector, ckbAddress, BTC_TESTNET_TYPE } from '../env'; interface LeapToBtcParams { outIndex: number; @@ -25,6 +25,7 @@ const leapFromCkbToBtc = async ({ outIndex, btcTxId, xudtTypeArgs, transferAmoun toRgbppLockArgs, xudtTypeBytes: serializeScript(xudtType), transferAmount, + btcTestnetType: BTC_TESTNET_TYPE, }); const emptyWitness = { lock: '', inputType: '', outputType: '' }; @@ -41,10 +42,12 @@ const leapFromCkbToBtc = async ({ outIndex, btcTxId, xudtTypeArgs, transferAmoun }; // Please use your real BTC UTXO information on the BTC Testnet +// BTC Testnet3: https://mempool.space/testnet +// BTC Signet: https://mempool.space/signet leapFromCkbToBtc({ outIndex: 1, - btcTxId: '4ff1855b64b309afa19a8b9be3d4da99dcb18b083b65d2d851662995c7d99e7a', + btcTxId: '3f6db9a387587006cb2fa8c6352bc728984bf39cb010789dffe574f27775a6ac', // Please use your own RGB++ xudt asset's xudtTypeArgs - xudtTypeArgs: '0x1ba116c119d1cfd98a53e9d1a615cf2af2bb87d95515c9d217d367054cfc696b', + xudtTypeArgs: '0x562e4e8a2f64a3e9c24beb4b7dd002d0ad3b842d0cc77924328e36ad114e3ebe', transferAmount: BigInt(800_0000_0000), }); diff --git a/examples/rgbpp/xudt/2-btc-transfer.ts b/examples/rgbpp/xudt/2-btc-transfer.ts index ea98a126..a812f39b 100644 --- a/examples/rgbpp/xudt/2-btc-transfer.ts +++ b/examples/rgbpp/xudt/2-btc-transfer.ts @@ -1,6 +1,6 @@ import { buildRgbppLockArgs } from 'rgbpp/ckb'; import { buildRgbppTransferTx } from 'rgbpp'; -import { isMainnet, collector, btcService, btcAccount, btcDataSource } from '../env'; +import { isMainnet, collector, btcService, btcAccount, btcDataSource, BTC_TESTNET_TYPE } from '../env'; import { saveCkbVirtualTxResult } from '../shared/utils'; import { signAndSendPsbt } from '../shared/btc-account'; import { bitcoin } from 'rgbpp/btc'; @@ -25,6 +25,7 @@ const transfer = async ({ rgbppLockArgsList, toBtcAddress, xudtTypeArgs, transfe toAddress: toBtcAddress, fromPubkey: btcAccount.fromPubkey, dataSource: btcDataSource, + testnetType: BTC_TESTNET_TYPE, }, isMainnet, }); @@ -35,7 +36,7 @@ const transfer = async ({ rgbppLockArgsList, toBtcAddress, xudtTypeArgs, transfe // Send BTC tx const psbt = bitcoin.Psbt.fromHex(btcPsbtHex); const { txId: btcTxId } = await signAndSendPsbt(psbt, btcAccount, btcService); - console.log('BTC TxId: ', btcTxId); + console.log(`BTC ${BTC_TESTNET_TYPE} TxId: ${btcTxId}`); await btcService.sendRgbppCkbTransaction({ btc_txid: btcTxId, ckb_virtual_result: ckbVirtualTxResult }); @@ -59,11 +60,14 @@ const transfer = async ({ rgbppLockArgsList, toBtcAddress, xudtTypeArgs, transfe }; // Please use your real BTC UTXO information on the BTC Testnet +// BTC Testnet3: https://mempool.space/testnet +// BTC Signet: https://mempool.space/signet + // rgbppLockArgs: outIndexU32 + btcTxId transfer({ - rgbppLockArgsList: [buildRgbppLockArgs(1, '64252b582aea1249ed969a20385fae48bba35bf1ab9b3df3b0fcddc754ccf592')], + rgbppLockArgsList: [buildRgbppLockArgs(1, '5ddd7b60ba93e01d9781be50eaa5c1aa634f799fc9c47bf59d1566eacf47b1e8')], toBtcAddress: 'tb1qvt7p9g6mw70sealdewtfp0sekquxuru6j3gwmt', // Please use your own RGB++ xudt asset's xudtTypeArgs - xudtTypeArgs: '0x1ba116c119d1cfd98a53e9d1a615cf2af2bb87d95515c9d217d367054cfc696b', + xudtTypeArgs: '0x562e4e8a2f64a3e9c24beb4b7dd002d0ad3b842d0cc77924328e36ad114e3ebe', transferAmount: BigInt(800_0000_0000), }); diff --git a/examples/rgbpp/xudt/3-btc-leap-ckb.ts b/examples/rgbpp/xudt/3-btc-leap-ckb.ts index 58533c8d..475ba91d 100644 --- a/examples/rgbpp/xudt/3-btc-leap-ckb.ts +++ b/examples/rgbpp/xudt/3-btc-leap-ckb.ts @@ -1,7 +1,7 @@ import { buildRgbppLockArgs, getXudtTypeScript } from 'rgbpp/ckb'; import { serializeScript } from '@nervosnetwork/ckb-sdk-utils'; import { genBtcJumpCkbVirtualTx, sendRgbppUtxos } from 'rgbpp'; -import { isMainnet, collector, btcService, btcDataSource, btcAccount } from '../env'; +import { isMainnet, collector, btcService, btcDataSource, btcAccount, BTC_TESTNET_TYPE } from '../env'; import { saveCkbVirtualTxResult } from '../shared/utils'; import { signAndSendPsbt } from '../shared/btc-account'; @@ -25,6 +25,7 @@ const leapFromBtcToCKB = async ({ rgbppLockArgsList, toCkbAddress, xudtTypeArgs, transferAmount, toCkbAddress, isMainnet, + btcTestnetType: BTC_TESTNET_TYPE, }); // Save ckbVirtualTxResult @@ -44,7 +45,7 @@ const leapFromBtcToCKB = async ({ rgbppLockArgsList, toCkbAddress, xudtTypeArgs, }); const { txId: btcTxId } = await signAndSendPsbt(psbt, btcAccount, btcService); - console.log('BTC TxId: ', btcTxId); + console.log(`BTC ${BTC_TESTNET_TYPE} TxId: ${btcTxId}`); await btcService.sendRgbppCkbTransaction({ btc_txid: btcTxId, ckb_virtual_result: ckbVirtualTxResult }); @@ -68,6 +69,9 @@ const leapFromBtcToCKB = async ({ rgbppLockArgsList, toCkbAddress, xudtTypeArgs, }; // Please use your real BTC UTXO information on the BTC Testnet +// BTC Testnet3: https://mempool.space/testnet +// BTC Signet: https://mempool.space/signet + // rgbppLockArgs: outIndexU32 + btcTxId leapFromBtcToCKB({ rgbppLockArgsList: [buildRgbppLockArgs(1, '6edd4b9327506fab09fb9a0f5e5f35136a6a94bd4c9dd79af04921618fa6c800')], diff --git a/examples/rgbpp/xudt/4-unlock-btc-time-cell.ts b/examples/rgbpp/xudt/4-unlock-btc-time-cell.ts index 6cece8ce..45359324 100644 --- a/examples/rgbpp/xudt/4-unlock-btc-time-cell.ts +++ b/examples/rgbpp/xudt/4-unlock-btc-time-cell.ts @@ -1,12 +1,12 @@ import { buildBtcTimeCellsSpentTx, signBtcTimeCellSpentTx } from 'rgbpp'; import { sendCkbTx, getBtcTimeLockScript } from 'rgbpp/ckb'; -import { CKB_PRIVATE_KEY, btcService, ckbAddress, collector, isMainnet } from '../env'; +import { BTC_TESTNET_TYPE, CKB_PRIVATE_KEY, btcService, ckbAddress, collector, isMainnet } from '../env'; // Warning: Wait at least 6 BTC confirmation blocks to spend the BTC time cells after 3-btc-leap-ckb.ts const unlockBtcTimeCell = async ({ btcTimeCellArgs }: { btcTimeCellArgs: string }) => { const btcTimeCells = await collector.getCells({ lock: { - ...getBtcTimeLockScript(false), + ...getBtcTimeLockScript(isMainnet, BTC_TESTNET_TYPE), args: btcTimeCellArgs, }, isDataMustBeEmpty: false, @@ -20,6 +20,7 @@ const unlockBtcTimeCell = async ({ btcTimeCellArgs }: { btcTimeCellArgs: string btcTimeCells, btcAssetsApi: btcService, isMainnet, + btcTestnetType: BTC_TESTNET_TYPE, }); const signedTx = await signBtcTimeCellSpentTx({ @@ -37,5 +38,5 @@ const unlockBtcTimeCell = async ({ btcTimeCellArgs }: { btcTimeCellArgs: string // The btcTimeCellArgs is from the outputs[0].lock.args(BTC Time lock args) of the 3-btc-leap-ckb.ts CKB transaction unlockBtcTimeCell({ btcTimeCellArgs: - '0x7f000000100000005b0000005f0000004b000000100000003000000031000000d23761b364210735c19c60561d213fb3beae2fd6172743719eff6920e020baac011600000000016c61f984f12d3c8a4f649e60acda5deda0b8837c060000001c95b9d726e4ab337d6a4572680598947954d7b6ff4f1e767e605eeeec49e7ed', + '0x7f000000100000005b0000005f0000004b000000100000003000000031000000d23761b364210735c19c60561d213fb3beae2fd6172743719eff6920e020baac011600000000016c61f984f12d3c8a4f649e60acda5deda0b8837c06000000799a0f55202939e6801924c87c66df75932ecf79774370beebe31eaa94b6d8b8', }); diff --git a/examples/rgbpp/xudt/launch/1-prepare-launch.ts b/examples/rgbpp/xudt/launch/1-prepare-launch.ts index d3ea1a5b..b0e740bc 100644 --- a/examples/rgbpp/xudt/launch/1-prepare-launch.ts +++ b/examples/rgbpp/xudt/launch/1-prepare-launch.ts @@ -13,7 +13,7 @@ import { getSecp256k1CellDep, } from 'rgbpp/ckb'; import { RGBPP_TOKEN_INFO } from './0-rgbpp-token-info'; -import { CKB_PRIVATE_KEY, ckbAddress, collector, isMainnet } from '../../env'; +import { BTC_TESTNET_TYPE, CKB_PRIVATE_KEY, ckbAddress, collector, isMainnet } from '../../env'; const prepareLaunchCell = async ({ outIndex, @@ -44,7 +44,7 @@ const prepareLaunchCell = async ({ const outputs: CKBComponents.CellOutput[] = [ { - lock: genRgbppLockScript(buildRgbppLockArgs(outIndex, btcTxId), isMainnet), + lock: genRgbppLockScript(buildRgbppLockArgs(outIndex, btcTxId), isMainnet, BTC_TESTNET_TYPE), capacity: append0x(launchCellCapacity.toString(16)), }, ]; @@ -82,8 +82,10 @@ const prepareLaunchCell = async ({ }; // Please use your real BTC UTXO information on the BTC Testnet +// BTC Testnet3: https://mempool.space/testnet +// BTC Signet: https://mempool.space/signet prepareLaunchCell({ outIndex: 1, - btcTxId: '6259ea7852e294afbd2aaf9ccd5c9c1f95087b0b08ba7e47ae35ce31170732bc', + btcTxId: 'c1f7fe5d4898194ed8ee5a38597cd28c7981e32e0e6aeb770f3f1b87df21434c', rgbppTokenInfo: RGBPP_TOKEN_INFO, }); diff --git a/examples/rgbpp/xudt/launch/2-launch-rgbpp.ts b/examples/rgbpp/xudt/launch/2-launch-rgbpp.ts index e4825938..f51982f7 100644 --- a/examples/rgbpp/xudt/launch/2-launch-rgbpp.ts +++ b/examples/rgbpp/xudt/launch/2-launch-rgbpp.ts @@ -7,7 +7,7 @@ import { sendCkbTx, } from 'rgbpp/ckb'; import { RGBPP_TOKEN_INFO } from './0-rgbpp-token-info'; -import { btcAccount, btcDataSource, btcService, collector, isMainnet } from '../../env'; +import { BTC_TESTNET_TYPE, btcAccount, btcDataSource, btcService, collector, isMainnet } from '../../env'; import { saveCkbVirtualTxResult } from '../../shared/utils'; import { signAndSendPsbt } from '../../shared/btc-account'; @@ -25,6 +25,7 @@ const launchRgppAsset = async ({ ownerRgbppLockArgs, launchAmount, rgbppTokenInf rgbppTokenInfo, launchAmount, isMainnet, + btcTestnetType: BTC_TESTNET_TYPE, }); // Save ckbVirtualTxResult @@ -47,7 +48,7 @@ const launchRgppAsset = async ({ ownerRgbppLockArgs, launchAmount, rgbppTokenInf }); const { txId: btcTxId, rawTxHex: btcTxBytes } = await signAndSendPsbt(psbt, btcAccount, btcService); - console.log('BTC TxId: ', btcTxId); + console.log(`BTC ${BTC_TESTNET_TYPE} TxId: ${btcTxId}`); const interval = setInterval(async () => { try { @@ -73,9 +74,12 @@ const launchRgppAsset = async ({ ownerRgbppLockArgs, launchAmount, rgbppTokenInf }; // Please use your real BTC UTXO information on the BTC Testnet which should be same as the 1-prepare-launch.ts +// BTC Testnet3: https://mempool.space/testnet +// BTC Signet: https://mempool.space/signet + // rgbppLockArgs: outIndexU32 + btcTxId launchRgppAsset({ - ownerRgbppLockArgs: buildRgbppLockArgs(1, '6259ea7852e294afbd2aaf9ccd5c9c1f95087b0b08ba7e47ae35ce31170732bc'), + ownerRgbppLockArgs: buildRgbppLockArgs(1, 'c1f7fe5d4898194ed8ee5a38597cd28c7981e32e0e6aeb770f3f1b87df21434c'), rgbppTokenInfo: RGBPP_TOKEN_INFO, // The total issuance amount of RGBPP Token, the decimal is determined by RGBPP Token info launchAmount: BigInt(2100_0000) * BigInt(10 ** RGBPP_TOKEN_INFO.decimal), diff --git a/examples/rgbpp/xudt/launch/3-distribute-rgbpp.ts b/examples/rgbpp/xudt/launch/3-distribute-rgbpp.ts index 32f29e28..52799411 100644 --- a/examples/rgbpp/xudt/launch/3-distribute-rgbpp.ts +++ b/examples/rgbpp/xudt/launch/3-distribute-rgbpp.ts @@ -1,7 +1,16 @@ import { serializeScript } from '@nervosnetwork/ckb-sdk-utils'; import { BtcAssetsApiError, genBtcBatchTransferCkbVirtualTx, sendRgbppUtxos } from 'rgbpp'; import { RGBPP_TOKEN_INFO } from './0-rgbpp-token-info'; -import { isMainnet, collector, btcDataSource, btcService, CKB_PRIVATE_KEY, ckbAddress, btcAccount } from '../../env'; +import { + isMainnet, + collector, + btcDataSource, + btcService, + CKB_PRIVATE_KEY, + ckbAddress, + btcAccount, + BTC_TESTNET_TYPE, +} from '../../env'; import { RgbppBtcAddressReceiver, appendCkbTxWitnesses, @@ -35,6 +44,7 @@ const distributeRgbppAssetOnBtc = async ({ rgbppLockArgsList, receivers, xudtTyp xudtTypeBytes: serializeScript(xudtType), rgbppReceivers: receivers, isMainnet, + btcTestnetType: BTC_TESTNET_TYPE, }); // Save ckbVirtualTxResult @@ -59,7 +69,7 @@ const distributeRgbppAssetOnBtc = async ({ rgbppLockArgsList, receivers, xudtTyp }); const { txId: btcTxId, rawTxHex: btcTxBytes } = await signAndSendPsbt(psbt, btcAccount, btcService); - console.log('BTC TxId: ', btcTxId); + console.log(`BTC ${BTC_TESTNET_TYPE} TxId: ${btcTxId}`); const interval = setInterval(async () => { try { @@ -94,15 +104,18 @@ const distributeRgbppAssetOnBtc = async ({ rgbppLockArgsList, receivers, xudtTyp }; // Please use your real BTC UTXO information on the BTC Testnet +// BTC Testnet3: https://mempool.space/testnet +// BTC Signet: https://mempool.space/signet + // rgbppLockArgs: outIndexU32 + btcTxId distributeRgbppAssetOnBtc({ // Warning: If rgbpp assets are distributed continuously, then the position of the current rgbpp asset utxo depends on the position of the previous change utxo distributed - rgbppLockArgsList: [buildRgbppLockArgs(2, '012bfee9c1e8a6e9e272b63ff54d5138efe910cc7aac413221cb3634ea176866')], + rgbppLockArgsList: [buildRgbppLockArgs(1, '5ab72e296c7e4f93302f5b1827c59860a95b94958942c65977bf25fcd7364bf3')], // The xudtTypeArgs comes from the logs "RGB++ Asset type script args" of 2-launch-rgbpp.ts - xudtTypeArgs: '0x4c1ecf2f14edae73b76ccf115ecfa40ba68ee315c96bd4fcfd771c2fb4c69e8f', + xudtTypeArgs: '0x157339c6b1ad2156bc9aa3f901abb07253f198160fb484226127ccafedd690c8', receivers: [ { - toBtcAddress: 'tb1qvt7p9g6mw70sealdewtfp0sekquxuru6j3gwmt', + toBtcAddress: 'tb1qhp9fh9qsfeyh0yhewgu27ndqhs5qlrqwau28m7', transferAmount: BigInt(1000) * BigInt(10 ** RGBPP_TOKEN_INFO.decimal), }, ], diff --git a/examples/rgbpp/xudt/local/2-btc-transfer.ts b/examples/rgbpp/xudt/local/2-btc-transfer.ts index f7195550..ad7d6893 100644 --- a/examples/rgbpp/xudt/local/2-btc-transfer.ts +++ b/examples/rgbpp/xudt/local/2-btc-transfer.ts @@ -1,6 +1,6 @@ import { BtcAssetsApiError, buildRgbppTransferTx } from 'rgbpp'; import { appendCkbTxWitnesses, buildRgbppLockArgs, sendCkbTx, updateCkbTxWithRealBtcTxId } from 'rgbpp/ckb'; -import { isMainnet, collector, btcDataSource, btcService, btcAccount } from '../../env'; +import { isMainnet, collector, btcDataSource, btcService, btcAccount, BTC_TESTNET_TYPE } from '../../env'; import { bitcoin } from 'rgbpp/btc'; import { saveCkbVirtualTxResult } from '../../shared/utils'; import { signAndSendPsbt } from '../../shared/btc-account'; @@ -26,6 +26,7 @@ const transfer = async ({ rgbppLockArgsList, toBtcAddress, xudtTypeArgs, transfe toAddress: toBtcAddress, fromPubkey: btcAccount.fromPubkey, dataSource: btcDataSource, + testnetType: BTC_TESTNET_TYPE, }, isMainnet, }); @@ -38,12 +39,12 @@ const transfer = async ({ rgbppLockArgsList, toBtcAddress, xudtTypeArgs, transfe // Send BTC tx const psbt = bitcoin.Psbt.fromHex(btcPsbtHex); const { txId: btcTxId, rawTxHex: btcTxBytes } = await signAndSendPsbt(psbt, btcAccount, btcService); - console.log('BTC TxId: ', btcTxId); + console.log(`BTC ${BTC_TESTNET_TYPE} TxId: ${btcTxId}`); // Wait for BTC tx and proof to be ready, and then send isomorphic CKB transactions const interval = setInterval(async () => { try { - console.log('Waiting for BTC tx and proof to be ready'); + console.log(`Waiting for BTC tx and proof to be ready`); const rgbppApiSpvProof = await btcService.getRgbppSpvProof(btcTxId, 0); clearInterval(interval); // Update CKB transaction with the real BTC txId @@ -64,12 +65,15 @@ const transfer = async ({ rgbppLockArgsList, toBtcAddress, xudtTypeArgs, transfe }, 30 * 1000); }; -// Please use your real BTC UTXO information on the BTC Testnet +// Please use your real BTC UTXO information on the BTC Signet Testnet +// BTC Testnet3: https://mempool.space/testnet +// BTC Signet: https://mempool.space/signet + // rgbppLockArgs: outIndexU32 + btcTxId transfer({ - rgbppLockArgsList: [buildRgbppLockArgs(1, '70b250e2a3cc7a33b47f7a4e94e41e1ee2501ce73b393d824db1dd4c872c5348')], - toBtcAddress: 'tb1qvt7p9g6mw70sealdewtfp0sekquxuru6j3gwmt', + rgbppLockArgsList: [buildRgbppLockArgs(2, '57212668f2738aa07a51861a2f8cd7a083aab05b01ede8b79dff948c0041f808')], + toBtcAddress: 'tb1qhp9fh9qsfeyh0yhewgu27ndqhs5qlrqwau28m7', // Please use your own RGB++ asset's xudtTypeArgs - xudtTypeArgs: '0x1ba116c119d1cfd98a53e9d1a615cf2af2bb87d95515c9d217d367054cfc696b', + xudtTypeArgs: '0x562e4e8a2f64a3e9c24beb4b7dd002d0ad3b842d0cc77924328e36ad114e3ebe', transferAmount: BigInt(800_0000_0000), }); diff --git a/examples/rgbpp/xudt/local/3-btc-leap-ckb.ts b/examples/rgbpp/xudt/local/3-btc-leap-ckb.ts index fa5d1927..437314ab 100644 --- a/examples/rgbpp/xudt/local/3-btc-leap-ckb.ts +++ b/examples/rgbpp/xudt/local/3-btc-leap-ckb.ts @@ -7,7 +7,7 @@ import { getXudtTypeScript, updateCkbTxWithRealBtcTxId, } from 'rgbpp/ckb'; -import { isMainnet, collector, btcDataSource, btcService, btcAccount } from '../../env'; +import { isMainnet, collector, btcDataSource, btcService, btcAccount, BTC_TESTNET_TYPE } from '../../env'; import { saveCkbVirtualTxResult } from '../../shared/utils'; import { signAndSendPsbt } from '../../shared/btc-account'; @@ -32,6 +32,7 @@ const leapFromBtcToCkb = async ({ rgbppLockArgsList, toCkbAddress, xudtTypeArgs, transferAmount, toCkbAddress, isMainnet, + btcTestnetType: BTC_TESTNET_TYPE, }); // Save ckbVirtualTxResult @@ -39,6 +40,8 @@ const leapFromBtcToCkb = async ({ rgbppLockArgsList, toCkbAddress, xudtTypeArgs, const { commitment, ckbRawTx } = ckbVirtualTxResult; + console.log('ckbRawTx', JSON.stringify(ckbRawTx)); + // Send BTC tx const psbt = await sendRgbppUtxos({ ckbVirtualTx: ckbRawTx, @@ -51,9 +54,7 @@ const leapFromBtcToCkb = async ({ rgbppLockArgsList, toCkbAddress, xudtTypeArgs, }); const { txId: btcTxId, rawTxHex: btcTxBytes } = await signAndSendPsbt(psbt, btcAccount, btcService); - console.log('BTC Tx bytes: ', btcTxBytes); - console.log('BTC TxId: ', btcTxId); - console.log('ckbRawTx', JSON.stringify(ckbRawTx)); + console.log(`BTC ${BTC_TESTNET_TYPE} TxId: ${btcTxId}`); // Wait for BTC tx and proof to be ready, and then send isomorphic CKB transactions const interval = setInterval(async () => { @@ -69,6 +70,8 @@ const leapFromBtcToCkb = async ({ rgbppLockArgsList, toCkbAddress, xudtTypeArgs, rgbppApiSpvProof, }); + console.log(JSON.stringify(ckbTx)); + const txHash = await sendCkbTx({ collector, signedTx: ckbTx }); console.info(`RGB++ Asset has been leaped from BTC to CKB and the CKB tx hash is ${txHash}`); } catch (error) { @@ -80,11 +83,14 @@ const leapFromBtcToCkb = async ({ rgbppLockArgsList, toCkbAddress, xudtTypeArgs, }; // Please use your real BTC UTXO information on the BTC Testnet +// BTC Testnet3: https://mempool.space/testnet +// BTC Signet: https://mempool.space/signet + // rgbppLockArgs: outIndexU32 + btcTxId leapFromBtcToCkb({ - rgbppLockArgsList: [buildRgbppLockArgs(1, '24e622419156dd3a277a90bcbb40c7117462a18d5329dd1ada320ca8bdfba715')], + rgbppLockArgsList: [buildRgbppLockArgs(1, '3f6db9a387587006cb2fa8c6352bc728984bf39cb010789dffe574f27775a6ac')], toCkbAddress: 'ckt1qrfrwcdnvssswdwpn3s9v8fp87emat306ctjwsm3nmlkjg8qyza2cqgqq9kxr7vy7yknezj0vj0xptx6thk6pwyr0sxamv6q', // Please use your own RGB++ xudt asset's xudtTypeArgs - xudtTypeArgs: '0x1ba116c119d1cfd98a53e9d1a615cf2af2bb87d95515c9d217d367054cfc696b', + xudtTypeArgs: '0x562e4e8a2f64a3e9c24beb4b7dd002d0ad3b842d0cc77924328e36ad114e3ebe', transferAmount: BigInt(800_0000_0000), }); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 6ca97b4c..5457e808 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -127,7 +127,7 @@ importers: specifier: ^0.109.1 version: 0.109.1 rgbpp: - specifier: ^0.3.0 + specifier: workspace:* version: link:../../packages/rgbpp devDependencies: '@types/dotenv': From 8c06d188d1cddcb429ee31e6f489d08e7d57080b Mon Sep 17 00:00:00 2001 From: Dylan Duan Date: Thu, 13 Jun 2024 17:08:49 +0800 Subject: [PATCH 60/90] feat: Add BTC_TESTNET_TYPE env variable for examples --- examples/rgbpp/.env.example | 5 +++++ examples/rgbpp/env.ts | 3 ++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/examples/rgbpp/.env.example b/examples/rgbpp/.env.example index 8359f171..3fa02ac9 100644 --- a/examples/rgbpp/.env.example +++ b/examples/rgbpp/.env.example @@ -32,3 +32,8 @@ VITE_BTC_SERVICE_TOKEN= # The BTC assets api origin which should be matched with IS_MAINNET VITE_BTC_SERVICE_ORIGIN=https://btc-test.app + +# The Bitcoin Testnet type including Testnet3 and Signet, default value is Testnet3 +# Testnet3: https://mempool.space/testnet +# Signet: https://mempool.space/signet +VITE_BTC_TESTNET_TYPE=Testnet3 diff --git a/examples/rgbpp/env.ts b/examples/rgbpp/env.ts index 6186586a..ecc26e48 100644 --- a/examples/rgbpp/env.ts +++ b/examples/rgbpp/env.ts @@ -8,7 +8,7 @@ import { } from '@nervosnetwork/ckb-sdk-utils'; import { NetworkType, AddressType, DataSource } from 'rgbpp/btc'; import { BtcAssetsApi } from 'rgbpp/service'; -import { Collector } from 'rgbpp/ckb'; +import { BTCTestnetType, Collector } from 'rgbpp/ckb'; import { createBtcAccount } from './shared/btc-account'; dotenv.config({ path: __dirname + '/.env' }); @@ -42,6 +42,7 @@ export const BTC_PRIVATE_KEY = process.env.BTC_PRIVATE_KEY!; export const BTC_SERVICE_URL = process.env.VITE_BTC_SERVICE_URL!; export const BTC_SERVICE_TOKEN = process.env.VITE_BTC_SERVICE_TOKEN!; export const BTC_SERVICE_ORIGIN = process.env.VITE_BTC_SERVICE_ORIGIN!; +export const BTC_TESTNET_TYPE = process.env.VITE_BTC_TESTNET_TYPE! as BTCTestnetType; // Read more about the available address types: // - P2WPKH: https://github.com/bitcoin/bips/blob/master/bip-0141.mediawiki#p2wpkh From 8eb3854dc46a6aae42657f203a823fc8c50b5034 Mon Sep 17 00:00:00 2001 From: Dylan Duan Date: Thu, 13 Jun 2024 17:09:31 +0800 Subject: [PATCH 61/90] feat: Add BTC_TESTNET_TYPE to spore examples --- examples/rgbpp/package.json | 2 +- examples/rgbpp/spore/4-transfer-spore.ts | 6 +++++- examples/rgbpp/spore/5-leap-spore-to-ckb.ts | 6 +++++- examples/rgbpp/spore/6-unlock-btc-time-cell.ts | 5 +++-- examples/rgbpp/spore/7-leap-spore-to-btc.ts | 5 ++++- examples/rgbpp/spore/launch/1-prepare-cluster.ts | 4 ++-- examples/rgbpp/spore/launch/2-create-cluster.ts | 6 +++++- examples/rgbpp/spore/launch/3-create-spores.ts | 15 ++++++++++++++- examples/rgbpp/spore/local/4-transfer-spore.ts | 6 +++++- examples/rgbpp/spore/local/5-leap-spore-to-ckb.ts | 6 +++++- 10 files changed, 49 insertions(+), 12 deletions(-) diff --git a/examples/rgbpp/package.json b/examples/rgbpp/package.json index 7d44e4f8..9131267f 100644 --- a/examples/rgbpp/package.json +++ b/examples/rgbpp/package.json @@ -11,7 +11,7 @@ }, "dependencies": { "@nervosnetwork/ckb-sdk-utils": "^0.109.1", - "rgbpp": "^0.3.0" + "rgbpp": "workspace:*" }, "devDependencies": { "@types/node": "^20.11.28", diff --git a/examples/rgbpp/spore/4-transfer-spore.ts b/examples/rgbpp/spore/4-transfer-spore.ts index 431ca76e..f8571f88 100644 --- a/examples/rgbpp/spore/4-transfer-spore.ts +++ b/examples/rgbpp/spore/4-transfer-spore.ts @@ -2,7 +2,7 @@ import { buildRgbppLockArgs } from 'rgbpp/ckb'; import { genTransferSporeCkbVirtualTx, sendRgbppUtxos } from 'rgbpp'; import { getSporeTypeScript, Hex } from 'rgbpp/ckb'; import { serializeScript } from '@nervosnetwork/ckb-sdk-utils'; -import { isMainnet, collector, btcDataSource, btcService, btcAccount } from '../env'; +import { isMainnet, collector, btcDataSource, btcService, btcAccount, BTC_TESTNET_TYPE } from '../env'; import { saveCkbVirtualTxResult } from '../shared/utils'; import { signAndSendPsbt } from '../shared/btc-account'; @@ -23,6 +23,7 @@ const transferSpore = async ({ sporeRgbppLockArgs, toBtcAddress, sporeTypeArgs } sporeRgbppLockArgs, sporeTypeBytes, isMainnet, + btcTestnetType: BTC_TESTNET_TYPE, }); // Save ckbVirtualTxResult @@ -68,6 +69,9 @@ const transferSpore = async ({ sporeRgbppLockArgs, toBtcAddress, sporeTypeArgs } }; // Please use your real BTC UTXO information on the BTC Testnet +// BTC Testnet3: https://mempool.space/testnet +// BTC Signet: https://mempool.space/signet + // rgbppLockArgs: outIndexU32 + btcTxId transferSpore({ sporeRgbppLockArgs: buildRgbppLockArgs(2, 'd5868dbde4be5e49876b496449df10150c356843afb6f94b08f8d81f394bb350'), diff --git a/examples/rgbpp/spore/5-leap-spore-to-ckb.ts b/examples/rgbpp/spore/5-leap-spore-to-ckb.ts index 23e6f46f..3592a94a 100644 --- a/examples/rgbpp/spore/5-leap-spore-to-ckb.ts +++ b/examples/rgbpp/spore/5-leap-spore-to-ckb.ts @@ -2,7 +2,7 @@ import { buildRgbppLockArgs } from 'rgbpp/ckb'; import { genLeapSporeFromBtcToCkbVirtualTx, sendRgbppUtxos } from 'rgbpp'; import { getSporeTypeScript, Hex } from 'rgbpp/ckb'; import { serializeScript } from '@nervosnetwork/ckb-sdk-utils'; -import { isMainnet, collector, btcDataSource, btcService, btcAccount } from '../env'; +import { isMainnet, collector, btcDataSource, btcService, btcAccount, BTC_TESTNET_TYPE } from '../env'; import { saveCkbVirtualTxResult } from '../shared/utils'; import { signAndSendPsbt } from '../shared/btc-account'; @@ -24,6 +24,7 @@ const leapSporeFromBtcToCkb = async ({ sporeRgbppLockArgs, toCkbAddress, sporeTy sporeTypeBytes, toCkbAddress, isMainnet, + btcTestnetType: BTC_TESTNET_TYPE, }); // Save ckbVirtualTxResult @@ -69,6 +70,9 @@ const leapSporeFromBtcToCkb = async ({ sporeRgbppLockArgs, toCkbAddress, sporeTy }; // Please use your real BTC UTXO information on the BTC Testnet +// BTC Testnet3: https://mempool.space/testnet +// BTC Signet: https://mempool.space/signet + // rgbppLockArgs: outIndexU32 + btcTxId leapSporeFromBtcToCkb({ sporeRgbppLockArgs: buildRgbppLockArgs(3, 'd8a31796fbd42c546f6b22014b9b82b16586ce1df81b0e7ca9a552cdc492a0af'), diff --git a/examples/rgbpp/spore/6-unlock-btc-time-cell.ts b/examples/rgbpp/spore/6-unlock-btc-time-cell.ts index 65153ccb..3880fcf7 100644 --- a/examples/rgbpp/spore/6-unlock-btc-time-cell.ts +++ b/examples/rgbpp/spore/6-unlock-btc-time-cell.ts @@ -1,12 +1,12 @@ import { buildSporeBtcTimeCellsSpentTx, signBtcTimeCellSpentTx } from 'rgbpp'; -import { CKB_PRIVATE_KEY, btcService, ckbAddress, collector, isMainnet } from '../env'; +import { BTC_TESTNET_TYPE, CKB_PRIVATE_KEY, btcService, ckbAddress, collector, isMainnet } from '../env'; import { sendCkbTx, getBtcTimeLockScript } from 'rgbpp/ckb'; // Warning: Wait at least 6 BTC confirmation blocks to spend the BTC time cells after 5-leap-spore-to-ckb.ts const unlockSporeBtcTimeCell = async ({ btcTimeCellArgs }: { btcTimeCellArgs: string }) => { const btcTimeCells = await collector.getCells({ lock: { - ...getBtcTimeLockScript(false), + ...getBtcTimeLockScript(isMainnet, BTC_TESTNET_TYPE), args: btcTimeCellArgs, }, isDataMustBeEmpty: false, @@ -20,6 +20,7 @@ const unlockSporeBtcTimeCell = async ({ btcTimeCellArgs }: { btcTimeCellArgs: st btcTimeCells, btcAssetsApi: btcService, isMainnet, + btcTestnetType: BTC_TESTNET_TYPE, }); const signedTx = await signBtcTimeCellSpentTx({ diff --git a/examples/rgbpp/spore/7-leap-spore-to-btc.ts b/examples/rgbpp/spore/7-leap-spore-to-btc.ts index 5f85e6c8..1a03b2ee 100644 --- a/examples/rgbpp/spore/7-leap-spore-to-btc.ts +++ b/examples/rgbpp/spore/7-leap-spore-to-btc.ts @@ -1,6 +1,6 @@ import { serializeScript } from '@nervosnetwork/ckb-sdk-utils'; import { genLeapSporeFromCkbToBtcRawTx } from 'rgbpp'; -import { isMainnet, collector, ckbAddress, CKB_PRIVATE_KEY } from '../env'; +import { isMainnet, collector, ckbAddress, CKB_PRIVATE_KEY, BTC_TESTNET_TYPE } from '../env'; import { buildRgbppLockArgs, getSecp256k1CellDep, getSporeTypeScript } from 'rgbpp/ckb'; const leapSporeFromCkbToBtc = async ({ @@ -25,6 +25,7 @@ const leapSporeFromCkbToBtc = async ({ toRgbppLockArgs, sporeTypeBytes: serializeScript(sporeType), isMainnet, + btcTestnetType: BTC_TESTNET_TYPE, }); const emptyWitness = { lock: '', inputType: '', outputType: '' }; @@ -41,6 +42,8 @@ const leapSporeFromCkbToBtc = async ({ }; // Please use your real BTC UTXO information on the BTC Testnet +// BTC Testnet3: https://mempool.space/testnet +// BTC Signet: https://mempool.space/signet leapSporeFromCkbToBtc({ outIndex: 1, btcTxId: '448897515cf07b4ca0cd38af9806399ede55775b4c760b274ed2322121ed185f', diff --git a/examples/rgbpp/spore/launch/1-prepare-cluster.ts b/examples/rgbpp/spore/launch/1-prepare-cluster.ts index 215b7951..6e31ab4a 100644 --- a/examples/rgbpp/spore/launch/1-prepare-cluster.ts +++ b/examples/rgbpp/spore/launch/1-prepare-cluster.ts @@ -10,7 +10,7 @@ import { genRgbppLockScript, getSecp256k1CellDep, } from 'rgbpp/ckb'; -import { ckbAddress, isMainnet, collector, CKB_PRIVATE_KEY } from '../../env'; +import { ckbAddress, isMainnet, collector, CKB_PRIVATE_KEY, BTC_TESTNET_TYPE } from '../../env'; import { CLUSTER_DATA } from './0-cluster-info'; const prepareClusterCell = async ({ outIndex, btcTxId }: { outIndex: number; btcTxId: string }) => { @@ -33,7 +33,7 @@ const prepareClusterCell = async ({ outIndex, btcTxId }: { outIndex: number; btc const outputs: CKBComponents.CellOutput[] = [ { - lock: genRgbppLockScript(buildRgbppLockArgs(outIndex, btcTxId), isMainnet), + lock: genRgbppLockScript(buildRgbppLockArgs(outIndex, btcTxId), isMainnet, BTC_TESTNET_TYPE), capacity: append0x(clusterCellCapacity.toString(16)), }, ]; diff --git a/examples/rgbpp/spore/launch/2-create-cluster.ts b/examples/rgbpp/spore/launch/2-create-cluster.ts index b6056a3a..475fd78b 100644 --- a/examples/rgbpp/spore/launch/2-create-cluster.ts +++ b/examples/rgbpp/spore/launch/2-create-cluster.ts @@ -1,5 +1,5 @@ import { BtcAssetsApiError, genCreateClusterCkbVirtualTx, sendRgbppUtxos } from 'rgbpp'; -import { isMainnet, collector, btcAccount, btcDataSource, btcService } from '../../env'; +import { isMainnet, collector, btcAccount, btcDataSource, btcService, BTC_TESTNET_TYPE } from '../../env'; import { CLUSTER_DATA } from './0-cluster-info'; import { appendCkbTxWitnesses, @@ -19,6 +19,7 @@ const createCluster = async ({ ownerRgbppLockArgs }: { ownerRgbppLockArgs: strin clusterData: CLUSTER_DATA, isMainnet, ckbFeeRate: BigInt(2000), + btcTestnetType: BTC_TESTNET_TYPE, }); // Save ckbVirtualTxResult @@ -78,6 +79,9 @@ const createCluster = async ({ ownerRgbppLockArgs }: { ownerRgbppLockArgs: strin }; // Please use your real BTC UTXO information on the BTC Testnet which should be same as the 1-prepare-cluster.ts +// BTC Testnet3: https://mempool.space/testnet +// BTC Signet: https://mempool.space/signet + // rgbppLockArgs: outIndexU32 + btcTxId createCluster({ ownerRgbppLockArgs: buildRgbppLockArgs(3, 'aee4e8e3aa95e9e9ab1f0520714031d92d3263262099dcc7f7d64e62fa2fcb44'), diff --git a/examples/rgbpp/spore/launch/3-create-spores.ts b/examples/rgbpp/spore/launch/3-create-spores.ts index 592e9a20..6ddc85c2 100644 --- a/examples/rgbpp/spore/launch/3-create-spores.ts +++ b/examples/rgbpp/spore/launch/3-create-spores.ts @@ -1,5 +1,14 @@ import { BtcAssetsApiError, genCreateSporeCkbVirtualTx, sendRgbppUtxos } from 'rgbpp'; -import { isMainnet, collector, btcDataSource, btcService, CKB_PRIVATE_KEY, ckbAddress, btcAccount } from '../../env'; +import { + isMainnet, + collector, + btcDataSource, + btcService, + CKB_PRIVATE_KEY, + ckbAddress, + btcAccount, + BTC_TESTNET_TYPE, +} from '../../env'; import { Hex, appendCkbTxWitnesses, @@ -30,6 +39,7 @@ const createSpores = async ({ clusterRgbppLockArgs, receivers }: SporeCreatePara clusterRgbppLockArgs, isMainnet, ckbFeeRate: BigInt(2000), + btcTestnetType: BTC_TESTNET_TYPE, }); // Save ckbVirtualTxResult @@ -105,6 +115,9 @@ const createSpores = async ({ clusterRgbppLockArgs, receivers }: SporeCreatePara }; // Please use your real BTC UTXO information on the BTC Testnet +// BTC Testnet3: https://mempool.space/testnet +// BTC Signet: https://mempool.space/signet + // rgbppLockArgs: outIndexU32 + btcTxId createSpores({ // The cluster cell will be spent and the new cluster cell will be created in each spore creation tx, diff --git a/examples/rgbpp/spore/local/4-transfer-spore.ts b/examples/rgbpp/spore/local/4-transfer-spore.ts index fd256b06..10069d33 100644 --- a/examples/rgbpp/spore/local/4-transfer-spore.ts +++ b/examples/rgbpp/spore/local/4-transfer-spore.ts @@ -11,7 +11,7 @@ import { import { sendRgbppUtxos } from 'rgbpp/btc'; import { BtcAssetsApiError } from 'rgbpp'; import { serializeScript } from '@nervosnetwork/ckb-sdk-utils'; -import { isMainnet, collector, btcDataSource, btcService, btcAccount } from '../../env'; +import { isMainnet, collector, btcDataSource, btcService, btcAccount, BTC_TESTNET_TYPE } from '../../env'; import { saveCkbVirtualTxResult } from '../../shared/utils'; import { signAndSendPsbt } from '../../shared/btc-account'; @@ -35,6 +35,7 @@ const transferSpore = async ({ sporeRgbppLockArgs, toBtcAddress, sporeTypeArgs } sporeTypeBytes, isMainnet, ckbFeeRate: BigInt(5000), + btcTestnetType: BTC_TESTNET_TYPE, }); // Save ckbVirtualTxResult @@ -90,6 +91,9 @@ const transferSpore = async ({ sporeRgbppLockArgs, toBtcAddress, sporeTypeArgs } }; // Please use your real BTC UTXO information on the BTC Testnet +// BTC Testnet3: https://mempool.space/testnet +// BTC Signet: https://mempool.space/signet + // rgbppLockArgs: outIndexU32 + btcTxId transferSpore({ // The spore rgbpp lock args is from 3-create-spore.ts diff --git a/examples/rgbpp/spore/local/5-leap-spore-to-ckb.ts b/examples/rgbpp/spore/local/5-leap-spore-to-ckb.ts index 23d3b808..104b16d5 100644 --- a/examples/rgbpp/spore/local/5-leap-spore-to-ckb.ts +++ b/examples/rgbpp/spore/local/5-leap-spore-to-ckb.ts @@ -10,7 +10,7 @@ import { } from 'rgbpp/ckb'; import { sendRgbppUtxos } from 'rgbpp/btc'; import { serializeScript } from '@nervosnetwork/ckb-sdk-utils'; -import { isMainnet, collector, btcDataSource, btcService, btcAccount } from '../../env'; +import { isMainnet, collector, btcDataSource, btcService, btcAccount, BTC_TESTNET_TYPE } from '../../env'; import { BtcAssetsApiError } from 'rgbpp'; import { saveCkbVirtualTxResult } from '../../shared/utils'; import { signAndSendPsbt } from '../../shared/btc-account'; @@ -35,6 +35,7 @@ const leapSpore = async ({ sporeRgbppLockArgs, toCkbAddress, sporeTypeArgs }: Sp sporeTypeBytes, toCkbAddress, isMainnet, + btcTestnetType: BTC_TESTNET_TYPE, }); // Save ckbVirtualTxResult @@ -90,6 +91,9 @@ const leapSpore = async ({ sporeRgbppLockArgs, toCkbAddress, sporeTypeArgs }: Sp }; // Please use your real BTC UTXO information on the BTC Testnet +// BTC Testnet3: https://mempool.space/testnet +// BTC Signet: https://mempool.space/signet + // rgbppLockArgs: outIndexU32 + btcTxId leapSpore({ // The spore rgbpp lock args is from 3-create-spore.ts From 32ff4a3d42f784465d22504ac5a9efe9900682cd Mon Sep 17 00:00:00 2001 From: Dylan Duan Date: Thu, 13 Jun 2024 17:43:42 +0800 Subject: [PATCH 62/90] docs: Update env variables for README --- examples/rgbpp/.env.example | 4 +-- examples/rgbpp/README.md | 29 ++++++++++++------- examples/rgbpp/xudt/1-ckb-leap-btc.ts | 2 +- examples/rgbpp/xudt/4-unlock-btc-time-cell.ts | 2 +- .../rgbpp/xudt/launch/1-prepare-launch.ts | 2 +- examples/rgbpp/xudt/launch/2-launch-rgbpp.ts | 2 +- .../rgbpp/xudt/launch/3-distribute-rgbpp.ts | 2 +- 7 files changed, 25 insertions(+), 18 deletions(-) diff --git a/examples/rgbpp/.env.example b/examples/rgbpp/.env.example index 3fa02ac9..39a13e63 100644 --- a/examples/rgbpp/.env.example +++ b/examples/rgbpp/.env.example @@ -16,11 +16,11 @@ CKB_INDEXER_URL=https://testnet.ckb.dev/indexer # BTC Variables # The BTC private key whose format is 32bytes hex string without 0x prefix -# The Native Segwit P2WPKH address will be generated with the BTC private key -# Read more about P2WPKH in BIP141: https://github.com/bitcoin/bips/blob/master/bip-0141.mediawiki#p2wpkh BTC_PRIVATE_KEY=private-key # The BTC address type to use, available options: P2WPKH or P2TR +# The Native Segwit P2WPKH address will be generated with the BTC private key as default +# Read more about P2WPKH in BIP141: https://github.com/bitcoin/bips/blob/master/bip-0141.mediawiki#p2wpkh BTC_ADDRESS_TYPE=P2WPKH # The BTC assets api url which should be matched with IS_MAINNET diff --git a/examples/rgbpp/README.md b/examples/rgbpp/README.md index 4337c85e..1bef64a1 100644 --- a/examples/rgbpp/README.md +++ b/examples/rgbpp/README.md @@ -4,7 +4,9 @@ - Spore directory: The examples for RGB++ Spore creation, transfer and leap > [!TIP] -> 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 +> 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 ## How to Start @@ -41,11 +43,11 @@ CKB_INDEXER_URL=https://testnet.ckb.dev/indexer # BTC Variables # The BTC private key whose format is 32bytes hex string without 0x prefix -# The Native Segwit P2WPKH address will be generated with the BTC private key -# Read more about P2WPKH in BIP141: https://github.com/bitcoin/bips/blob/master/bip-0141.mediawiki#p2wpkh BTC_PRIVATE_KEY=private-key # The BTC address type to use, available options: P2WPKH or P2TR +# The Native Segwit P2WPKH address will be generated with the BTC private key as default +# Read more about P2WPKH in BIP141: https://github.com/bitcoin/bips/blob/master/bip-0141.mediawiki#p2wpkh BTC_ADDRESS_TYPE=P2WPKH # The BTC assets api url which should be matched with IS_MAINNET @@ -57,6 +59,11 @@ VITE_BTC_SERVICE_TOKEN= # The BTC assets api origin which should be matched with IS_MAINNET VITE_BTC_SERVICE_ORIGIN=https://btc-test.app + +# The Bitcoin Testnet type including Testnet3 and Signet, default value is Testnet3 +# Testnet3: https://mempool.space/testnet +# Signet: https://mempool.space/signet +VITE_BTC_TESTNET_TYPE=Testnet3 ``` ## RGB++ xUDT Examples @@ -66,7 +73,7 @@ VITE_BTC_SERVICE_ORIGIN=https://btc-test.app #### 1. Prepare Launch > [!TIP] -> Please make sure the CKB private key in the .env is correct +> Please make sure the CKB private key in the .env is correct. ```shell # Create a CKB empty rgbpp lock cell to launch RGB++ xUDT assets later @@ -75,7 +82,7 @@ npx ts-node xudt/launch/1-prepare-launch.ts #### 2. Launch RGB++ xUDT on BTC > [!TIP] -> Please make sure the `1-prepare-launch.ts` has been run and the corresponding CKB transaction has been committed +> Please make sure the `1-prepare-launch.ts` has been run and the corresponding CKB transaction has been committed. ```shell npx ts-node xudt/launch/2-launch-rgbpp.ts @@ -86,8 +93,8 @@ When the command is executed successfully, the **RGB++ Asset type script args** #### 3. Distribute RGB++ xUDT on BTC > [!TIP] -> Please make sure the `2-launch-rgbpp.ts` has been run and the corresponding BTC and CKB transactions have been committed -> The **RGB++ Asset type script args** in the above should be set to the `xudtTypeArgs` +> Please make sure the `2-launch-rgbpp.ts` has been run and the corresponding BTC and CKB transactions have been committed. +> The **RGB++ Asset type script args** in the above should be set to the `xudtTypeArgs`. ```shell npx ts-node xudt/launch/3-distribute-rgbpp.ts @@ -132,8 +139,8 @@ npx ts-node xudt/4-unlock-btc-time.ts #### 1. Create RGB++ Cluster Cell > [!TIP] -> Please make sure all the variables in the .env are correct -> The BTC UTXO of `1-prepare-cluster.ts` and `2-create-cluster.ts` should be same +> Please make sure all the variables in the .env are correct. +> The BTC UTXO of `1-prepare-cluster.ts` and `2-create-cluster.ts` should be same. ```shell # Create a CKB empty rgbpp lock cell to create cluster later @@ -148,8 +155,8 @@ When the commands are executed successfully, the **clusterId** and **cluster rgb #### 2. Create RGB++ Spores with Cluster on BTC > [!TIP] -> Please make sure the `2-create-cluster.ts` has been run and the corresponding BTC and CKB transactions have been committed -> The **clusterId** in the above should be set to the `clusterId` and the **cluster rgbpp lock args** should be set to the `clusterRgbppLockArgs` +> Please make sure the `2-create-cluster.ts` has been run and the corresponding BTC and CKB transactions have been committed. +> The **clusterId** in the above should be set to the `clusterId` and the **cluster rgbpp lock args** should be set to the `clusterRgbppLockArgs`. ```shell npx ts-node spore/launch/3-create-spores.ts diff --git a/examples/rgbpp/xudt/1-ckb-leap-btc.ts b/examples/rgbpp/xudt/1-ckb-leap-btc.ts index e729b91b..b917989f 100644 --- a/examples/rgbpp/xudt/1-ckb-leap-btc.ts +++ b/examples/rgbpp/xudt/1-ckb-leap-btc.ts @@ -38,7 +38,7 @@ const leapFromCkbToBtc = async ({ outIndex, btcTxId, xudtTypeArgs, transferAmoun const signedTx = collector.getCkb().signTransaction(CKB_PRIVATE_KEY)(unsignedTx); const txHash = await collector.getCkb().rpc.sendTransaction(signedTx, 'passthrough'); - console.info(`Rgbpp asset has been jumped from CKB to BTC and tx hash is ${txHash}`); + console.info(`Rgbpp asset has been jumped from CKB to BTC and CKB tx hash is ${txHash}`); }; // Please use your real BTC UTXO information on the BTC Testnet diff --git a/examples/rgbpp/xudt/4-unlock-btc-time-cell.ts b/examples/rgbpp/xudt/4-unlock-btc-time-cell.ts index 45359324..46d56598 100644 --- a/examples/rgbpp/xudt/4-unlock-btc-time-cell.ts +++ b/examples/rgbpp/xudt/4-unlock-btc-time-cell.ts @@ -32,7 +32,7 @@ const unlockBtcTimeCell = async ({ btcTimeCellArgs }: { btcTimeCellArgs: string }); const txHash = await sendCkbTx({ collector, signedTx }); - console.info(`BTC time cell has been spent and tx hash is ${txHash}`); + console.info(`BTC time cell has been spent and CKB tx hash is ${txHash}`); }; // The btcTimeCellArgs is from the outputs[0].lock.args(BTC Time lock args) of the 3-btc-leap-ckb.ts CKB transaction diff --git a/examples/rgbpp/xudt/launch/1-prepare-launch.ts b/examples/rgbpp/xudt/launch/1-prepare-launch.ts index b0e740bc..6be0a910 100644 --- a/examples/rgbpp/xudt/launch/1-prepare-launch.ts +++ b/examples/rgbpp/xudt/launch/1-prepare-launch.ts @@ -78,7 +78,7 @@ const prepareLaunchCell = async ({ const signedTx = collector.getCkb().signTransaction(CKB_PRIVATE_KEY)(unsignedTx); const txHash = await collector.getCkb().rpc.sendTransaction(signedTx, 'passthrough'); - console.info(`Launch cell has been created and the tx hash ${txHash}`); + console.info(`Launch cell has been created and the CKB tx hash ${txHash}`); }; // Please use your real BTC UTXO information on the BTC Testnet diff --git a/examples/rgbpp/xudt/launch/2-launch-rgbpp.ts b/examples/rgbpp/xudt/launch/2-launch-rgbpp.ts index f51982f7..c09d1e5b 100644 --- a/examples/rgbpp/xudt/launch/2-launch-rgbpp.ts +++ b/examples/rgbpp/xudt/launch/2-launch-rgbpp.ts @@ -64,7 +64,7 @@ const launchRgppAsset = async ({ ownerRgbppLockArgs, launchAmount, rgbppTokenInf }); const txHash = await sendCkbTx({ collector, signedTx: ckbTx }); - console.info(`RGB++ Asset has been launched and tx hash is ${txHash}`); + console.info(`RGB++ Asset has been launched and CKB tx hash is ${txHash}`); } catch (error) { if (!(error instanceof BtcAssetsApiError)) { console.error(error); diff --git a/examples/rgbpp/xudt/launch/3-distribute-rgbpp.ts b/examples/rgbpp/xudt/launch/3-distribute-rgbpp.ts index 52799411..38c779ae 100644 --- a/examples/rgbpp/xudt/launch/3-distribute-rgbpp.ts +++ b/examples/rgbpp/xudt/launch/3-distribute-rgbpp.ts @@ -94,7 +94,7 @@ const distributeRgbppAssetOnBtc = async ({ rgbppLockArgsList, receivers, xudtTyp }); const txHash = await sendCkbTx({ collector, signedTx }); - console.info(`RGB++ Asset has been distributed and tx hash is ${txHash}`); + console.info(`RGB++ Asset has been distributed and CKB tx hash is ${txHash}`); } catch (error) { if (!(error instanceof BtcAssetsApiError)) { console.error(error); From 1493919f44699f84d17de49a924731d412e0fa2b Mon Sep 17 00:00:00 2001 From: Dylan Duan Date: Thu, 13 Jun 2024 19:32:51 +0800 Subject: [PATCH 63/90] feat: Add BTC_TESTNET_TYPE to sdk service --- apps/service/.env.example | 5 +++++ apps/service/README.md | 5 +++++ apps/service/src/app.module.ts | 9 +++++++-- apps/service/src/env.ts | 1 + apps/service/src/rgbpp/rgbpp.service.ts | 4 +++- 5 files changed, 21 insertions(+), 3 deletions(-) diff --git a/apps/service/.env.example b/apps/service/.env.example index e3f5009c..4d3cff68 100644 --- a/apps/service/.env.example +++ b/apps/service/.env.example @@ -13,3 +13,8 @@ BTC_SERVICE_TOKEN= # The BTC assets api origin which should be matched with IS_MAINNET BTC_SERVICE_ORIGIN=https://btc-assets-api.testnet.mibao.pro + +# The Bitcoin Testnet type including Testnet3 and Signet, default value is Testnet3 +# Testnet3: https://mempool.space/testnet +# Signet: https://mempool.space/signet +BTC_TESTNET_TYPE=Testnet3 \ No newline at end of file diff --git a/apps/service/README.md b/apps/service/README.md index 6fd743a3..d92f48cd 100644 --- a/apps/service/README.md +++ b/apps/service/README.md @@ -38,6 +38,11 @@ BTC_SERVICE_TOKEN= # The BTC assets api origin which should be matched with IS_MAINNET BTC_SERVICE_ORIGIN=https://btc-assets-api.testnet.mibao.pro + +# The Bitcoin Testnet type including Testnet3 and Signet, default value is Testnet3 +# Testnet3: https://mempool.space/testnet +# Signet: https://mempool.space/signet +BTC_TESTNET_TYPE=Testnet3 ``` ### Run RGB++ SDK Service diff --git a/apps/service/src/app.module.ts b/apps/service/src/app.module.ts index 6d2da414..7b55caad 100644 --- a/apps/service/src/app.module.ts +++ b/apps/service/src/app.module.ts @@ -4,7 +4,7 @@ import JsonRpcModule from './json-rpc/json-rpc.module'; import { RgbppModule } from './rgbpp/rgbpp.module'; import { AppService } from './app.service'; import { envSchema } from './env'; -import { Collector } from 'rgbpp/ckb'; +import { BTCTestnetType, Collector } from 'rgbpp/ckb'; import { BtcAssetsApi } from 'rgbpp'; @Global() @@ -25,6 +25,11 @@ import { BtcAssetsApi } from 'rgbpp'; useFactory: (configService: ConfigService): boolean => configService.get('NETWORK') === 'mainnet', inject: [ConfigService], }, + { + provide: 'BTC_TESTNET_TYPE', + useFactory: (configService: ConfigService): BTCTestnetType => configService.get('BTC_TESTNET_TYPE'), + inject: [ConfigService], + }, { provide: 'COLLECTOR', useFactory: (configService: ConfigService) => { @@ -47,6 +52,6 @@ import { BtcAssetsApi } from 'rgbpp'; inject: [ConfigService], }, ], - exports: ['IS_MAINNET', 'COLLECTOR', 'BTC_ASSETS_API'], + exports: ['IS_MAINNET', 'COLLECTOR', 'BTC_ASSETS_API', 'BTC_TESTNET_TYPE'], }) export class AppModule {} diff --git a/apps/service/src/env.ts b/apps/service/src/env.ts index d103ae4d..752e1e49 100644 --- a/apps/service/src/env.ts +++ b/apps/service/src/env.ts @@ -7,4 +7,5 @@ export const envSchema = z.object({ BTC_SERVICE_URL: z.string(), BTC_SERVICE_TOKEN: z.string(), BTC_SERVICE_ORIGIN: z.string(), + BTC_TESTNET_TYPE: z.string().default('Testnet3'), }); diff --git a/apps/service/src/rgbpp/rgbpp.service.ts b/apps/service/src/rgbpp/rgbpp.service.ts index da1f7754..0de87937 100644 --- a/apps/service/src/rgbpp/rgbpp.service.ts +++ b/apps/service/src/rgbpp/rgbpp.service.ts @@ -1,7 +1,7 @@ import { Inject } from '@nestjs/common'; import { RpcHandler, RpcMethodHandler } from 'src/json-rpc/json-rpc.decorators'; import { DataSource, NetworkType } from 'rgbpp/btc'; -import { Collector, Hex, toCamelcase } from 'rgbpp/ckb'; +import { BTCTestnetType, Collector, Hex, toCamelcase } from 'rgbpp/ckb'; import { RgbppTransferReq, RgbppCkbBtcTransaction, RgbppCkbTxBtcTxId, RgbppStateReq, RgbppCkbTxHashReq } from './types'; import { toSnakeCase } from 'src/utils/snake'; import { buildRgbppTransferTx } from 'rgbpp'; @@ -11,6 +11,7 @@ import { BtcAssetsApi } from 'rgbpp/service'; export class RgbppService { constructor( @Inject('IS_MAINNET') private isMainnet: boolean, + @Inject('BTC_TESTNET_TYPE') private btcTestnetType: BTCTestnetType, @Inject('COLLECTOR') private collector: Collector, @Inject('BTC_ASSETS_API') private btcAssetsApi: BtcAssetsApi, ) {} @@ -32,6 +33,7 @@ export class RgbppService { fromAddress: fromBtcAddress, toAddress: toBtcAddress, dataSource: btcDataSource, + testnetType: this.btcTestnetType, }, isMainnet: this.isMainnet, }); From 62f2e8ade3ff21436726b51525487770d2c880d6 Mon Sep 17 00:00:00 2001 From: Dylan Duan Date: Thu, 13 Jun 2024 19:53:03 +0800 Subject: [PATCH 64/90] refactor: Update env variables --- apps/service/.env.example | 14 +++++++------- apps/service/README.md | 14 +++++++------- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/apps/service/.env.example b/apps/service/.env.example index 4d3cff68..36c9d4d9 100644 --- a/apps/service/.env.example +++ b/apps/service/.env.example @@ -1,20 +1,20 @@ # testnet for CKB and BTC Testnet and mainnet for CKB and BTC Mainnet, the default value is testnet NETWORK=testnet +# The Bitcoin Testnet type including Testnet3 and Signet, default value is Testnet3 +# Testnet3: https://mempool.space/testnet +# Signet: https://mempool.space/signet +BTC_TESTNET_TYPE=Testnet3 + # CKB node url which should be matched with NETWORK CKB_RPC_URL=https://testnet.ckb.dev # The BTC assets api url which should be matched with NETWORK BTC_SERVICE_URL=https://btc-assets-api.testnet.mibao.pro -# The BTC assets api token which should be matched with IS_MAINNET +# The BTC assets api token which should be matched with NETWORK and BTC_TESTNET_TYPE # To get an access token, please refer to https://github.com/ckb-cell/rgbpp-sdk/tree/develop/packages/service#get-an-access-token BTC_SERVICE_TOKEN= -# The BTC assets api origin which should be matched with IS_MAINNET +# The BTC assets api origin which should be matched with NETWORK and BTC_TESTNET_TYPE BTC_SERVICE_ORIGIN=https://btc-assets-api.testnet.mibao.pro - -# The Bitcoin Testnet type including Testnet3 and Signet, default value is Testnet3 -# Testnet3: https://mempool.space/testnet -# Signet: https://mempool.space/signet -BTC_TESTNET_TYPE=Testnet3 \ No newline at end of file diff --git a/apps/service/README.md b/apps/service/README.md index d92f48cd..e310ddaa 100644 --- a/apps/service/README.md +++ b/apps/service/README.md @@ -26,23 +26,23 @@ Update the configuration values: # testnet for CKB and BTC Testnet and mainnet for CKB and BTC Mainnet, the default value is testnet NETWORK=testnet +# The Bitcoin Testnet type including Testnet3 and Signet, default value is Testnet3 +# Testnet3: https://mempool.space/testnet +# Signet: https://mempool.space/signet +BTC_TESTNET_TYPE=Testnet3 + # CKB node url which should be matched with NETWORK CKB_RPC_URL=https://testnet.ckb.dev # The BTC assets api url which should be matched with NETWORK BTC_SERVICE_URL=https://btc-assets-api.testnet.mibao.pro -# The BTC assets api token which should be matched with IS_MAINNET +# The BTC assets api token which should be matched with NETWORK and BTC_TESTNET_TYPE # To get an access token, please refer to https://github.com/ckb-cell/rgbpp-sdk/tree/develop/packages/service#get-an-access-token BTC_SERVICE_TOKEN= -# The BTC assets api origin which should be matched with IS_MAINNET +# The BTC assets api origin which should be matched with NETWORK and BTC_TESTNET_TYPE BTC_SERVICE_ORIGIN=https://btc-assets-api.testnet.mibao.pro - -# The Bitcoin Testnet type including Testnet3 and Signet, default value is Testnet3 -# Testnet3: https://mempool.space/testnet -# Signet: https://mempool.space/signet -BTC_TESTNET_TYPE=Testnet3 ``` ### Run RGB++ SDK Service From 729147b1d64f3d3c392f1470ade7eed1bdfd5be2 Mon Sep 17 00:00:00 2001 From: Dylan Duan Date: Thu, 13 Jun 2024 19:56:07 +0800 Subject: [PATCH 65/90] docs: Update env variables for README --- examples/rgbpp/.env.example | 15 ++++++++------- examples/rgbpp/README.md | 10 +++++----- examples/rgbpp/env.ts | 2 +- 3 files changed, 14 insertions(+), 13 deletions(-) diff --git a/examples/rgbpp/.env.example b/examples/rgbpp/.env.example index 39a13e63..f80d7be1 100644 --- a/examples/rgbpp/.env.example +++ b/examples/rgbpp/.env.example @@ -15,6 +15,11 @@ CKB_INDEXER_URL=https://testnet.ckb.dev/indexer # BTC Variables +# The Bitcoin Testnet type including Testnet3 and Signet, default value is Testnet3 +# Testnet3: https://mempool.space/testnet +# Signet: https://mempool.space/signet +BTC_TESTNET_TYPE=Testnet3 + # The BTC private key whose format is 32bytes hex string without 0x prefix BTC_PRIVATE_KEY=private-key @@ -23,17 +28,13 @@ BTC_PRIVATE_KEY=private-key # Read more about P2WPKH in BIP141: https://github.com/bitcoin/bips/blob/master/bip-0141.mediawiki#p2wpkh BTC_ADDRESS_TYPE=P2WPKH -# The BTC assets api url which should be matched with IS_MAINNET +# The BTC assets api url which should be matched with IS_MAINNET and BTC_TESTNET_TYPE VITE_BTC_SERVICE_URL=https://btc-assets-api.testnet.mibao.pro -# The BTC assets api token which should be matched with IS_MAINNET +# The BTC assets api token which should be matched with IS_MAINNET and BTC_TESTNET_TYPE # To get an access token, please refer to https://github.com/ckb-cell/rgbpp-sdk/tree/develop/packages/service#get-an-access-token VITE_BTC_SERVICE_TOKEN= -# The BTC assets api origin which should be matched with IS_MAINNET +# The BTC assets api origin which should be matched with IS_MAINNET and BTC_TESTNET_TYPE VITE_BTC_SERVICE_ORIGIN=https://btc-test.app -# The Bitcoin Testnet type including Testnet3 and Signet, default value is Testnet3 -# Testnet3: https://mempool.space/testnet -# Signet: https://mempool.space/signet -VITE_BTC_TESTNET_TYPE=Testnet3 diff --git a/examples/rgbpp/README.md b/examples/rgbpp/README.md index 1bef64a1..ca01c27a 100644 --- a/examples/rgbpp/README.md +++ b/examples/rgbpp/README.md @@ -42,6 +42,11 @@ CKB_INDEXER_URL=https://testnet.ckb.dev/indexer # BTC Variables +# The Bitcoin Testnet type including Testnet3 and Signet, default value is Testnet3 +# Testnet3: https://mempool.space/testnet +# Signet: https://mempool.space/signet +BTC_TESTNET_TYPE=Testnet3 + # The BTC private key whose format is 32bytes hex string without 0x prefix BTC_PRIVATE_KEY=private-key @@ -59,11 +64,6 @@ VITE_BTC_SERVICE_TOKEN= # The BTC assets api origin which should be matched with IS_MAINNET VITE_BTC_SERVICE_ORIGIN=https://btc-test.app - -# The Bitcoin Testnet type including Testnet3 and Signet, default value is Testnet3 -# Testnet3: https://mempool.space/testnet -# Signet: https://mempool.space/signet -VITE_BTC_TESTNET_TYPE=Testnet3 ``` ## RGB++ xUDT Examples diff --git a/examples/rgbpp/env.ts b/examples/rgbpp/env.ts index ecc26e48..b4d64265 100644 --- a/examples/rgbpp/env.ts +++ b/examples/rgbpp/env.ts @@ -39,10 +39,10 @@ export const ckbAddress = scriptToAddress(secp256k1Lock, isMainnet); */ export const BTC_PRIVATE_KEY = process.env.BTC_PRIVATE_KEY!; +export const BTC_TESTNET_TYPE = process.env.BTC_TESTNET_TYPE! as BTCTestnetType; export const BTC_SERVICE_URL = process.env.VITE_BTC_SERVICE_URL!; export const BTC_SERVICE_TOKEN = process.env.VITE_BTC_SERVICE_TOKEN!; export const BTC_SERVICE_ORIGIN = process.env.VITE_BTC_SERVICE_ORIGIN!; -export const BTC_TESTNET_TYPE = process.env.VITE_BTC_TESTNET_TYPE! as BTCTestnetType; // Read more about the available address types: // - P2WPKH: https://github.com/bitcoin/bips/blob/master/bip-0141.mediawiki#p2wpkh From f301a5010de3394f236a732cc18c99e639e8d164 Mon Sep 17 00:00:00 2001 From: Dylan Duan Date: Thu, 13 Jun 2024 19:56:35 +0800 Subject: [PATCH 66/90] chore: Release snapshot version for btc signet --- .github/workflows/snapshot.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/snapshot.yml b/.github/workflows/snapshot.yml index 71620ac0..5cd9cc19 100644 --- a/.github/workflows/snapshot.yml +++ b/.github/workflows/snapshot.yml @@ -7,6 +7,7 @@ on: push: branches: - develop + - feat/btc-signet concurrency: ${{ github.workflow }}-${{ github.ref }} From 7d4dee91db5203c3892470454f961fafc4d46fec Mon Sep 17 00:00:00 2001 From: Yuexun Date: Thu, 13 Jun 2024 23:12:46 +1000 Subject: [PATCH 67/90] ci: change service docker image name (#229) --- .github/workflows/docker.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index 06c09bed..3c96ac4e 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -24,7 +24,7 @@ jobs: uses: docker/metadata-action@v5 with: context: git - images: ghcr.io/${{ github.repository }} + images: ghcr.io/${{ github.repository }}-service flavor: | latest=auto tags: | From 4e6eb398ab0d8c7daf4b42bd6a0f494a948319c1 Mon Sep 17 00:00:00 2001 From: Dylan Duan Date: Fri, 14 Jun 2024 10:08:26 +0800 Subject: [PATCH 68/90] Update packages/ckb/src/rgbpp/ckb-jump-btc.ts Co-authored-by: Flouse <1297478+Flouse@users.noreply.github.com> --- packages/ckb/src/rgbpp/ckb-jump-btc.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/ckb/src/rgbpp/ckb-jump-btc.ts b/packages/ckb/src/rgbpp/ckb-jump-btc.ts index 1d506a86..8780c11a 100644 --- a/packages/ckb/src/rgbpp/ckb-jump-btc.ts +++ b/packages/ckb/src/rgbpp/ckb-jump-btc.ts @@ -131,6 +131,7 @@ export const genCkbJumpBtcVirtualTx = async ({ * @param rgbppReceivers The rgbpp receiver list which include toRgbppLockArgs and transferAmount * @param witnessLockPlaceholderSize The WitnessArgs.lock placeholder bytes array size and the default value is 5000 * @param ckbFeeRate The CKB transaction fee rate, default value is 1100 + * @param btcTestnetType(Optional) The Bitcoin Testnet type including Testnet3 and Signet, default value is Testnet3 */ export const genCkbBatchJumpBtcVirtualTx = async ({ collector, From d13ae6f2b264c0708e86c8f235ee2e2d8c4f41fd Mon Sep 17 00:00:00 2001 From: Dylan Duan Date: Fri, 14 Jun 2024 11:15:52 +0800 Subject: [PATCH 69/90] docs: Update function comments --- .github/workflows/snapshot.yml | 1 - packages/ckb/src/rgbpp/ckb-jump-btc.ts | 4 ++-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/.github/workflows/snapshot.yml b/.github/workflows/snapshot.yml index 5cd9cc19..71620ac0 100644 --- a/.github/workflows/snapshot.yml +++ b/.github/workflows/snapshot.yml @@ -7,7 +7,6 @@ on: push: branches: - develop - - feat/btc-signet concurrency: ${{ github.workflow }}-${{ github.ref }} diff --git a/packages/ckb/src/rgbpp/ckb-jump-btc.ts b/packages/ckb/src/rgbpp/ckb-jump-btc.ts index 8780c11a..36ecc4c3 100644 --- a/packages/ckb/src/rgbpp/ckb-jump-btc.ts +++ b/packages/ckb/src/rgbpp/ckb-jump-btc.ts @@ -129,8 +129,8 @@ export const genCkbJumpBtcVirtualTx = async ({ * @param xudtTypeBytes The serialized hex string of the XUDT type script * @param fromCkbAddress The from ckb address who will use his private key to sign the ckb tx * @param rgbppReceivers The rgbpp receiver list which include toRgbppLockArgs and transferAmount - * @param witnessLockPlaceholderSize The WitnessArgs.lock placeholder bytes array size and the default value is 5000 - * @param ckbFeeRate The CKB transaction fee rate, default value is 1100 + * @param witnessLockPlaceholderSize(Optional) The WitnessArgs.lock placeholder bytes array size and the default value is 5000 + * @param ckbFeeRate(Optional) The CKB transaction fee rate, default value is 1100 * @param btcTestnetType(Optional) The Bitcoin Testnet type including Testnet3 and Signet, default value is Testnet3 */ export const genCkbBatchJumpBtcVirtualTx = async ({ From 8ce35931af9b9136771f1358c172987606064bdd Mon Sep 17 00:00:00 2001 From: Shook Date: Tue, 30 Apr 2024 22:43:47 +0800 Subject: [PATCH 70/90] feat: add isP2xScript methods to validate script type --- packages/btc/src/bitcoin.ts | 3 ++- packages/btc/src/index.ts | 1 + packages/btc/src/script.ts | 11 +++++++++++ packages/btc/tests/Script.test.ts | 17 +++++++++++++++++ 4 files changed, 31 insertions(+), 1 deletion(-) create mode 100644 packages/btc/src/script.ts create mode 100644 packages/btc/tests/Script.test.ts diff --git a/packages/btc/src/bitcoin.ts b/packages/btc/src/bitcoin.ts index 7673eeac..a208e7f4 100644 --- a/packages/btc/src/bitcoin.ts +++ b/packages/btc/src/bitcoin.ts @@ -2,10 +2,11 @@ import ECPairFactory, { ECPairInterface } from 'ecpair'; import ecc from '@bitcoinerlab/secp256k1'; import * as bitcoin from 'bitcoinjs-lib'; import { isTaprootInput } from 'bitcoinjs-lib/src/psbt/bip371'; +import { isP2TR, isP2WPKH, isP2PKH } from 'bitcoinjs-lib/src/psbt/psbtutils'; bitcoin.initEccLib(ecc); const ECPair = ECPairFactory(ecc); export type { ECPairInterface }; -export { ecc, ECPair, bitcoin, isTaprootInput }; +export { ecc, ECPair, bitcoin, isP2TR, isP2PKH, isP2WPKH, isTaprootInput }; diff --git a/packages/btc/src/index.ts b/packages/btc/src/index.ts index 13a197b7..f81e523e 100644 --- a/packages/btc/src/index.ts +++ b/packages/btc/src/index.ts @@ -6,6 +6,7 @@ export * from './utils'; export * from './error'; export * from './bitcoin'; export * from './address'; +export * from './script'; export * from './query/source'; diff --git a/packages/btc/src/script.ts b/packages/btc/src/script.ts new file mode 100644 index 00000000..a17339f0 --- /dev/null +++ b/packages/btc/src/script.ts @@ -0,0 +1,11 @@ +import { isP2TR, isP2WPKH } from './bitcoin'; + +export function isP2wpkhScript(script: Buffer | string): boolean { + const buffer = typeof script === 'string' ? Buffer.from(script, 'hex') : script; + return isP2WPKH(buffer); +} + +export function isP2trScript(script: Buffer | string): boolean { + const buffer = typeof script === 'string' ? Buffer.from(script, 'hex') : script; + return isP2TR(buffer); +} diff --git a/packages/btc/tests/Script.test.ts b/packages/btc/tests/Script.test.ts new file mode 100644 index 00000000..18298a1f --- /dev/null +++ b/packages/btc/tests/Script.test.ts @@ -0,0 +1,17 @@ +import { isP2trScript, isP2wpkhScript } from '../src'; +import { describe, expect, it } from 'vitest'; +import { accounts } from './shared/env'; + +describe('Script', () => { + const p2wpkh = accounts.charlie.p2wpkh.scriptPubkey; + const p2tr = accounts.charlie.p2tr.scriptPubkey; + + it('isP2trScript()', () => { + expect(isP2trScript(p2tr)).toBe(true); + expect(isP2trScript(p2wpkh)).toBe(false); + }); + it('isP2wpkhScript()', () => { + expect(isP2wpkhScript(p2wpkh)).toBe(true); + expect(isP2wpkhScript(p2tr)).toBe(false); + }); +}); From 08200c974ef336661723cc7556a003932babda9a Mon Sep 17 00:00:00 2001 From: Shook Date: Wed, 1 May 2024 00:41:05 +0800 Subject: [PATCH 71/90] feat: add sendRbf() API to support full replace-by-fee --- .changeset/spicy-cups-cheat.md | 9 + packages/btc/README.md | 102 +++++- packages/btc/src/api/sendBtc.ts | 3 +- packages/btc/src/api/sendRbf.ts | 174 +++++++++ packages/btc/src/api/sendRgbppUtxos.ts | 14 +- packages/btc/src/api/sendUtxos.ts | 13 +- packages/btc/src/error.ts | 2 + packages/btc/src/index.ts | 1 + packages/btc/src/query/source.ts | 7 +- packages/btc/src/transaction/build.ts | 92 +++-- packages/btc/src/transaction/utxo.ts | 5 +- packages/btc/tests/Transaction.test.ts | 482 ++++++++++++++++++++++--- packages/btc/tests/shared/env.ts | 38 +- packages/btc/tests/shared/utils.ts | 132 ++++++- 14 files changed, 934 insertions(+), 140 deletions(-) create mode 100644 .changeset/spicy-cups-cheat.md create mode 100644 packages/btc/src/api/sendRbf.ts diff --git a/.changeset/spicy-cups-cheat.md b/.changeset/spicy-cups-cheat.md new file mode 100644 index 00000000..6aaebfb3 --- /dev/null +++ b/.changeset/spicy-cups-cheat.md @@ -0,0 +1,9 @@ +--- +"@rgbpp-sdk/btc": minor +--- + +Support Full-RBF feature with the sendRbf() and createSendRbfBuilder() API + + - Add `excludeUtxos`, `skipInputsValidation` options in the `sendUtxos()` API to support the RBF feature + - Add `onlyProvableUtxos` option in the `sendRgbppUtxos()` API for future update supports + - Add `changeIndex` in the return type of the BTC Builder APIs diff --git a/packages/btc/README.md b/packages/btc/README.md index e92232f7..351f565b 100644 --- a/packages/btc/README.md +++ b/packages/btc/README.md @@ -221,10 +221,35 @@ const psbt = await sendRgbppUtxos({ minUtxoSatoshi: config.btcUtxoDustLimit, // optional, default to 1000 on the testnet, 1,0000 on the mainnet rgbppMinUtxoSatoshi: config.rgbppUtxoDustLimit, // optional, default to 546 on both testnet/mainnet onlyConfirmedUtxos: false, // optional, default to false, only confirmed utxos are allowed in the transaction + onlyProvableUtxos: true, // optional, default to true, only utxos that satisfy (utxo.address == from) are allowed feeRate: 1, // optional, default to 1 on the testnet, and it is a floating number on the mainnet }); ``` +### Construct a Full-RBF transaction + +```typescript +import { sendRbf, networkTypeToConfig, DataSource, Collector, NetworkType } from '@rgbpp-sdk/btc'; +import { BtcAssetsApi } from '@rgbpp-sdk/service'; + +const networkType = NetworkType.TESTNET; +const config = networkTypeToConfig(networkType); + +const service = BtcAssetsApi.fromToken('btc_assets_api_url', 'your_token'); +const source = new DataSource(service, networkType); + +const psbt = await sendRbf({ + txHex: 'your_original_transaction_hex', + from: account.address, + feeRate: 40, // the feeRate should be greater than the feeRate of the original transaction + changeIndex: 1, // optional, return change to outputs[changeIndex], will create a new output if not specified + changeAddress: 'address_to_return_change', // optional, where should the change satoshi be returned to + requireValidOutputsValue: false, // optional, default to false, require each output's value to be >= minUtxoSatoshi + requireGreaterFeeAndRate: true, // optional, default to true, require the fee rate&amount to be greater than the original transction + source, +}); +``` + ## Types ### Transaction @@ -238,8 +263,9 @@ declare function sendBtc(props: SendBtcProps): Promise; ```typescript declare function createSendBtcBuilder(props: SendBtcProps): Promise<{ builder: TxBuilder; - feeRate: number; fee: number; + feeRate: number; + changeIndex: number; }>; ``` @@ -265,8 +291,9 @@ declare function sendUtxos(props: SendUtxosProps): Promise; ```typescript declare function createSendUtxosBuilder(props: SendUtxosProps): Promise<{ builder: TxBuilder; - feeRate: number; fee: number; + feeRate: number; + changeIndex: number; }>; ``` @@ -281,6 +308,10 @@ interface SendUtxosProps { changeAddress?: string; minUtxoSatoshi?: number; onlyConfirmedUtxos?: boolean; + excludeUtxos?: BaseOutput[]; + + // EXPERIMENTAL: the below props are unstable and can be altered at any time + skipInputsValidation?: boolean; } ``` @@ -293,8 +324,9 @@ declare function sendRgbppUtxos(props: SendRgbppUtxosProps): Promise; ``` @@ -317,6 +349,44 @@ interface SendRgbppUtxosProps { changeAddress?: string; minUtxoSatoshi?: number; onlyConfirmedUtxos?: boolean; + excludeUtxos?: BaseOutput[]; + + // EXPERIMENTAL: the below props are experimental and can be altered at any time + onlyProvableUtxos?: boolean; +} +``` + +#### sendRbf / createSendRbfBuilder / SendRbfProps + +```typescript +declare function sendRbf(props: SendRbfProps): Promise; +``` + +```typescript +declare function createSendRbfBuilder(props: SendRbfProps): Promise<{ + builder: TxBuilder; + fee: number; + feeRate: number; + changeIndex: number; +}>; +``` + +```typescript +interface SendRbfProps { + from: string; + txHex: string; + source: DataSource; + feeRate?: number; + fromPubkey?: string; + changeIndex?: number; + changeAddress?: string; + minUtxoSatoshi?: number; + onlyConfirmedUtxos?: boolean; + requireValidOutputsValue?: boolean; + requireGreaterFeeAndRate?: boolean; + + // EXPERIMENTAL: the below props are experimental and can be altered at any time + inputsPubkey?: Record; // Record } ``` @@ -329,27 +399,27 @@ type InitOutput = TxAddressOutput | TxDataOutput | TxScriptOutput; #### TxAddressOutput / TxDataOutput / TxScriptOutput ```typescript -interface TxAddressOutput extends BaseOutput { +interface TxAddressOutput extends TxBaseOutput { address: string; } ``` ```typescript -interface TxDataOutput extends BaseOutput { +interface TxDataOutput extends TxBaseOutput { data: Buffer | string; } ``` ```typescript -interface TxScriptOutput extends BaseOutput { +interface TxScriptOutput extends TxBaseOutput { script: Buffer; } ``` -#### BaseOutput +#### TxBaseOutput ```typescript -interface BaseOutput { +interface TxBaseOutput { value: number; fixed?: boolean; protected?: boolean; @@ -374,10 +444,7 @@ interface DataSource { onlyConfirmedUtxos?: boolean; noAssetsApiCache?: boolean; internalCacheKey?: string; - excludeUtxos?: { - txid: string; - vout: number; - }[]; + excludeUtxos?: BaseOutput[]; }): Promise<{ utxos: Utxo[]; satoshi: number; @@ -399,16 +466,23 @@ interface FeesRecommended { ### Basic -#### Utxo / Output +#### BaseOutput / Output / Utxo ```typescript -interface Output { +interface BaseOutput { txid: string; vout: number; +} +``` + +```typescript +interface Output extends BaseOutput { value: number; scriptPk: string; } +``` +```typescript interface Utxo extends Output { addressType: AddressType; address: string; diff --git a/packages/btc/src/api/sendBtc.ts b/packages/btc/src/api/sendBtc.ts index 09aae2bc..076f4f54 100644 --- a/packages/btc/src/api/sendBtc.ts +++ b/packages/btc/src/api/sendBtc.ts @@ -16,8 +16,9 @@ export interface SendBtcProps { export async function createSendBtcBuilder(props: SendBtcProps): Promise<{ builder: TxBuilder; - feeRate: number; fee: number; + feeRate: number; + changeIndex: number; }> { // By default, all outputs in the sendBtc() API are fixed const outputs = props.tos.map((to) => ({ diff --git a/packages/btc/src/api/sendRbf.ts b/packages/btc/src/api/sendRbf.ts new file mode 100644 index 00000000..466ee1b5 --- /dev/null +++ b/packages/btc/src/api/sendRbf.ts @@ -0,0 +1,174 @@ +import { BaseOutput, Utxo } from '../transaction/utxo'; +import { DataSource } from '../query/source'; +import { ErrorCodes, TxBuildError } from '../error'; +import { InitOutput, TxBuilder } from '../transaction/build'; +import { isOpReturnScriptPubkey } from '../transaction/embed'; +import { networkTypeToNetwork } from '../preset/network'; +import { networkTypeToConfig } from '../preset/config'; +import { createSendUtxosBuilder } from './sendUtxos'; +import { isP2trScript } from '../script'; +import { bitcoin } from '../bitcoin'; + +export interface SendRbfProps { + from: string; + txHex: string; + source: DataSource; + feeRate?: number; + fromPubkey?: string; + changeIndex?: number; + changeAddress?: string; + minUtxoSatoshi?: number; + onlyConfirmedUtxos?: boolean; + requireValidOutputsValue?: boolean; + requireGreaterFeeAndRate?: boolean; + + // EXPERIMENTAL: the below props are unstable and can be altered at any time + inputsPubkey?: Record; // Record +} + +export async function createSendRbfBuilder(props: SendRbfProps): Promise<{ + builder: TxBuilder; + fee: number; + feeRate: number; + changeIndex: number; +}> { + const previousTx = bitcoin.Transaction.fromHex(props.txHex); + const network = networkTypeToNetwork(props.source.networkType); + + // Rebuild inputs + const inputs: Utxo[] = []; + for (const input of previousTx.ins) { + const hash = Buffer.from(input.hash).reverse().toString('hex'); + const utxo = await props.source.getUtxo(hash, input.index); + if (!utxo) { + throw TxBuildError.withComment(ErrorCodes.CANNOT_FIND_UTXO, `hash: ${hash}, index: ${input.index}`); + } + + // Ensure each P2TR input has a corresponding pubkey + const fromPubkey = utxo.address === props.from ? props.fromPubkey : undefined; + const inputPubkey = props.inputsPubkey?.[utxo.address]; + const pubkey = inputPubkey ?? fromPubkey; + if (pubkey) { + utxo.pubkey = pubkey; + } + if (isP2trScript(utxo.scriptPk) && !utxo.pubkey) { + throw TxBuildError.withComment(ErrorCodes.MISSING_PUBKEY, utxo.address); + } + + inputs.push(utxo); + } + + // Rebuild outputs + const requireValidOutputsValue = props.requireValidOutputsValue ?? false; + const outputs: InitOutput[] = previousTx.outs.map((output) => { + if (isOpReturnScriptPubkey(output.script)) { + return { + script: output.script, + value: output.value, + fixed: true, + }; + } else { + return { + minUtxoSatoshi: requireValidOutputsValue ? undefined : output.value, + address: bitcoin.address.fromOutputScript(output.script, network), + value: output.value, + fixed: true, + }; + } + }); + + // Set change output if specified + let changeAddress: string | undefined = props.changeAddress; + if (props.changeIndex !== undefined) { + const changeOutput = outputs[props.changeIndex]; + if (!changeOutput) { + throw TxBuildError.withComment(ErrorCodes.INVALID_CHANGE_OUTPUT, `outputs[${props.changeIndex}] is not found`); + } + const isReturnableOutput = changeOutput && 'address' in changeOutput; + if (!isReturnableOutput) { + throw TxBuildError.withComment( + ErrorCodes.INVALID_CHANGE_OUTPUT, + `outputs[${props.changeIndex}] is not a returnable output for change`, + ); + } + const changeOutputAddress = changeOutput.address; + if (changeOutputAddress && changeAddress && changeAddress !== changeOutputAddress) { + throw TxBuildError.withComment( + ErrorCodes.INVALID_CHANGE_OUTPUT, + `The address of outputs[${props.changeIndex}] does not match the specified changeAddress, expected: ${changeAddress}, actual: ${changeOutputAddress}`, + ); + } + if (changeOutputAddress && !changeAddress) { + changeAddress = changeOutputAddress; + } + const isLastOutput = outputs.length === props.changeIndex + 1; + if (isLastOutput) { + outputs.pop(); + } else { + const config = networkTypeToConfig(props.source.networkType); + const minUtxoSatoshi = props.minUtxoSatoshi ?? config.btcUtxoDustLimit; + changeOutput.minUtxoSatoshi = minUtxoSatoshi; + changeOutput.value = minUtxoSatoshi; + changeOutput.protected = true; + changeOutput.fixed = false; + } + } + + // Fee rate + const requireGreaterFeeAndRate = props.requireGreaterFeeAndRate ?? true; + let feeRate: number | undefined = props.feeRate; + if (requireGreaterFeeAndRate && !feeRate) { + const feeRates = await props.source.service.getBtcRecommendedFeeRates(); + feeRate = feeRates.fastestFee; + } + + // The RBF transaction should offer a higher fee rate + const previousInsValue = inputs.reduce((sum, input) => sum + input.value, 0); + const previousOutsValue = previousTx.outs.reduce((sum, output) => sum + output.value, 0); + const previousFee = previousInsValue - previousOutsValue; + const previousFeeRate = Math.floor(previousFee / previousTx.virtualSize()); + if (requireGreaterFeeAndRate && feeRate !== undefined && feeRate <= previousFeeRate) { + throw TxBuildError.withComment( + ErrorCodes.INVALID_FEE_RATE, + `RBF should offer a higher fee rate, previous: ${previousFeeRate}, current: ${feeRate}`, + ); + } + + // Exclude all outputs of the previous transaction during the collection + // TODO: also exclude all outputs of the previous transaction's children transactions + const previousTxId = previousTx.getId(); + const excludeUtxos: BaseOutput[] = previousTx.outs.map((_, index) => ({ + txid: previousTxId, + vout: index, + })); + + // Build RBF transaction + const res = await createSendUtxosBuilder({ + inputs, + outputs, + excludeUtxos, + changeAddress, + from: props.from, + source: props.source, + feeRate: props.feeRate, + fromPubkey: props.fromPubkey, + minUtxoSatoshi: props.minUtxoSatoshi, + onlyConfirmedUtxos: props.onlyConfirmedUtxos ?? true, + skipInputsValidation: true, + }); + + // The RBF transaction should offer a higher fee amount + if (requireGreaterFeeAndRate && res.fee <= previousFee) { + throw TxBuildError.withComment( + ErrorCodes.INVALID_FEE_RATE, + `RBF should offer a higher fee amount, previous: ${previousFee}, current: ${res.fee}`, + ); + } + + return res; +} + +export async function sendRbf(props: SendRbfProps): Promise { + const { builder } = await createSendRbfBuilder(props); + return builder.toPsbt(); +} diff --git a/packages/btc/src/api/sendRgbppUtxos.ts b/packages/btc/src/api/sendRgbppUtxos.ts index 22a52516..69b3ab8e 100644 --- a/packages/btc/src/api/sendRgbppUtxos.ts +++ b/packages/btc/src/api/sendRgbppUtxos.ts @@ -1,7 +1,7 @@ import { Collector, checkCkbTxInputsCapacitySufficient } from '@rgbpp-sdk/ckb'; import { isRgbppLockCell, isBtcTimeLockCell, calculateCommitment } from '@rgbpp-sdk/ckb'; import { bitcoin } from '../bitcoin'; -import { Utxo } from '../transaction/utxo'; +import { BaseOutput, Utxo } from '../transaction/utxo'; import { DataSource } from '../query/source'; import { NetworkType } from '../preset/types'; import { ErrorCodes, TxBuildError } from '../error'; @@ -28,6 +28,10 @@ export interface SendRgbppUtxosProps { changeAddress?: string; minUtxoSatoshi?: number; onlyConfirmedUtxos?: boolean; + excludeUtxos?: BaseOutput[]; + + // EXPERIMENTAL: the below props are unstable and can be altered at any time + onlyProvableUtxos?: boolean; } /** @@ -37,9 +41,12 @@ export const sendRgbppUtxosBuilder = createSendRgbppUtxosBuilder; export async function createSendRgbppUtxosBuilder(props: SendRgbppUtxosProps): Promise<{ builder: TxBuilder; - feeRate: number; fee: number; + feeRate: number; + changeIndex: number; }> { + const onlyProvableUtxos = props.onlyProvableUtxos ?? true; + const btcInputs: Utxo[] = []; const btcOutputs: InitOutput[] = []; let lastCkbTypeOutputIndex = -1; @@ -90,7 +97,7 @@ export async function createSendRgbppUtxosBuilder(props: SendRgbppUtxosProps): P if (!utxo) { throw TxBuildError.withComment(ErrorCodes.CANNOT_FIND_UTXO, `hash: ${args.btcTxid}, index: ${args.outIndex}`); } - if (utxo.address !== props.from) { + if (onlyProvableUtxos && utxo.address !== props.from) { throw TxBuildError.withComment( ErrorCodes.REFERENCED_UNPROVABLE_UTXO, `hash: ${args.btcTxid}, index: ${args.outIndex}`, @@ -171,6 +178,7 @@ export async function createSendRgbppUtxosBuilder(props: SendRgbppUtxosProps): P changeAddress: props.changeAddress, minUtxoSatoshi: props.minUtxoSatoshi, onlyConfirmedUtxos: props.onlyConfirmedUtxos, + excludeUtxos: props.excludeUtxos, }); } diff --git a/packages/btc/src/api/sendUtxos.ts b/packages/btc/src/api/sendUtxos.ts index 1bfff942..5f6abacf 100644 --- a/packages/btc/src/api/sendUtxos.ts +++ b/packages/btc/src/api/sendUtxos.ts @@ -1,6 +1,6 @@ import { bitcoin } from '../bitcoin'; -import { Utxo } from '../transaction/utxo'; import { DataSource } from '../query/source'; +import { BaseOutput, Utxo } from '../transaction/utxo'; import { TxBuilder, InitOutput } from '../transaction/build'; export interface SendUtxosProps { @@ -13,12 +13,17 @@ export interface SendUtxosProps { changeAddress?: string; minUtxoSatoshi?: number; onlyConfirmedUtxos?: boolean; + excludeUtxos?: BaseOutput[]; + + // EXPERIMENTAL: the below props are unstable and can be altered at any time + skipInputsValidation?: boolean; } export async function createSendUtxosBuilder(props: SendUtxosProps): Promise<{ builder: TxBuilder; - feeRate: number; fee: number; + feeRate: number; + changeIndex: number; }> { const tx = new TxBuilder({ source: props.source, @@ -30,7 +35,7 @@ export async function createSendUtxosBuilder(props: SendUtxosProps): Promise<{ tx.addInputs(props.inputs); tx.addOutputs(props.outputs); - if (props.onlyConfirmedUtxos) { + if (props.onlyConfirmedUtxos && !props.skipInputsValidation) { await tx.validateInputs(); } @@ -38,12 +43,14 @@ export async function createSendUtxosBuilder(props: SendUtxosProps): Promise<{ address: props.from, publicKey: props.fromPubkey, changeAddress: props.changeAddress, + excludeUtxos: props.excludeUtxos, }); return { builder: tx, fee: paid.fee, feeRate: paid.feeRate, + changeIndex: paid.changeIndex, }; } diff --git a/packages/btc/src/error.ts b/packages/btc/src/error.ts index 14291762..8562ac09 100644 --- a/packages/btc/src/error.ts +++ b/packages/btc/src/error.ts @@ -10,6 +10,7 @@ export enum ErrorCodes { DUPLICATED_UTXO, DUST_OUTPUT, UNSUPPORTED_OUTPUT, + INVALID_CHANGE_OUTPUT, UNSUPPORTED_NETWORK_TYPE, UNSUPPORTED_ADDRESS_TYPE, UNSUPPORTED_OP_RETURN_SCRIPT, @@ -38,6 +39,7 @@ export const ErrorMessages = { [ErrorCodes.UNSPENDABLE_OUTPUT]: 'Target output is not an UTXO', [ErrorCodes.DUST_OUTPUT]: 'Output defined value is below the dust limit', [ErrorCodes.UNSUPPORTED_OUTPUT]: 'Unsupported output format', + [ErrorCodes.INVALID_CHANGE_OUTPUT]: 'Invalid change output', [ErrorCodes.UNSUPPORTED_NETWORK_TYPE]: 'Unsupported network type', [ErrorCodes.UNSUPPORTED_ADDRESS_TYPE]: 'Unsupported address type', [ErrorCodes.UNSUPPORTED_OP_RETURN_SCRIPT]: 'Unsupported OP_RETURN script format', diff --git a/packages/btc/src/index.ts b/packages/btc/src/index.ts index f81e523e..36dbac94 100644 --- a/packages/btc/src/index.ts +++ b/packages/btc/src/index.ts @@ -16,5 +16,6 @@ export * from './transaction/utxo'; export * from './transaction/fee'; export * from './api/sendBtc'; +export * from './api/sendRbf'; export * from './api/sendUtxos'; export * from './api/sendRgbppUtxos'; diff --git a/packages/btc/src/query/source.ts b/packages/btc/src/query/source.ts index e368b29b..3f01aee8 100644 --- a/packages/btc/src/query/source.ts +++ b/packages/btc/src/query/source.ts @@ -1,5 +1,5 @@ import { BtcApiUtxoParams, BtcAssetsApi, BtcAssetsApiError, ErrorCodes as ServiceErrorCodes } from '@rgbpp-sdk/service'; -import { Output, Utxo } from '../transaction/utxo'; +import { BaseOutput, Output, Utxo } from '../transaction/utxo'; import { NetworkType } from '../preset/types'; import { ErrorCodes, TxBuildError } from '../error'; import { TxAddressOutput } from '../transaction/build'; @@ -107,10 +107,7 @@ export class DataSource { onlyConfirmedUtxos?: boolean; noAssetsApiCache?: boolean; internalCacheKey?: string; - excludeUtxos?: { - txid: string; - vout: number; - }[]; + excludeUtxos?: BaseOutput[]; }): Promise<{ utxos: Utxo[]; satoshi: number; diff --git a/packages/btc/src/transaction/build.ts b/packages/btc/src/transaction/build.ts index 7d34ab7b..a5c84082 100644 --- a/packages/btc/src/transaction/build.ts +++ b/packages/btc/src/transaction/build.ts @@ -6,8 +6,8 @@ import { NetworkType, RgbppBtcConfig } from '../preset/types'; import { AddressType, addressToScriptPublicKeyHex, getAddressType, isSupportedFromAddress } from '../address'; import { dataToOpReturnScriptPubkey, isOpReturnScriptPubkey } from './embed'; import { networkTypeToConfig } from '../preset/config'; +import { BaseOutput, Utxo, utxoToInput } from './utxo'; import { limitPromiseBatchSize } from '../utils'; -import { Utxo, utxoToInput } from './utxo'; import { FeeEstimator } from './fee'; export interface TxInput { @@ -21,21 +21,21 @@ export interface TxInput { } export type TxOutput = TxAddressOutput | TxScriptOutput; -export interface BaseOutput { +export interface TxBaseOutput { value: number; fixed?: boolean; protected?: boolean; minUtxoSatoshi?: number; } -export interface TxAddressOutput extends BaseOutput { +export interface TxAddressOutput extends TxBaseOutput { address: string; } -export interface TxScriptOutput extends BaseOutput { +export interface TxScriptOutput extends TxBaseOutput { script: Buffer; } export type InitOutput = TxAddressOutput | TxDataOutput | TxScriptOutput; -export interface TxDataOutput extends BaseOutput { +export interface TxDataOutput extends TxBaseOutput { data: Buffer | string; } @@ -141,12 +141,14 @@ export class TxBuilder { publicKey?: string; changeAddress?: string; deductFromOutputs?: boolean; + excludeUtxos?: BaseOutput[]; feeRate?: number; }): Promise<{ fee: number; feeRate: number; + changeIndex: number; }> { - const { address, publicKey, feeRate, changeAddress, deductFromOutputs } = props; + const { address, publicKey, feeRate, changeAddress, deductFromOutputs, excludeUtxos } = props; const originalInputs = clone(this.inputs); const originalOutputs = clone(this.outputs); @@ -168,6 +170,7 @@ export class TxBuilder { let previousFee = 0; let isLoopedOnce = false; let isFeeExpected = false; + let currentChangeIndex = -1; while (!isFeeExpected) { if (isLoopedOnce) { previousFee = currentFee; @@ -181,26 +184,32 @@ export class TxBuilder { if (safeToProcess && returnAmount > 0) { // If sum(inputs) - sum(outputs) > fee, return (change - fee) to a non-fixed output or to a new output. // Note when returning change to a new output, another satoshi collection may be needed. - await this.injectChange({ + const { changeIndex } = await this.injectChange({ address: changeAddress ?? address, amount: returnAmount, fromAddress: address, fromPublicKey: publicKey, internalCacheKey, + excludeUtxos, }); + + currentChangeIndex = changeIndex; } else { // If the inputs have insufficient satoshi, a satoshi collection is required. // For protection, at least collect 1 satoshi if the inputs are empty or the fee hasn't been calculated. const protectionAmount = safeToProcess ? 0 : 1; const targetAmount = needCollect - needReturn + previousFee + protectionAmount; - await this.injectSatoshi({ + const { changeIndex } = await this.injectSatoshi({ address, publicKey, targetAmount, changeAddress, deductFromOutputs, internalCacheKey, + excludeUtxos, }); + + currentChangeIndex = changeIndex; } // Calculate network fee @@ -220,6 +229,7 @@ export class TxBuilder { return { fee: currentFee, feeRate: currentFeeRate, + changeIndex: currentChangeIndex, }; } @@ -231,12 +241,18 @@ export class TxBuilder { injectCollected?: boolean; deductFromOutputs?: boolean; internalCacheKey?: string; - }) { + excludeUtxos?: BaseOutput[]; + }): Promise<{ + collected: number; + changeIndex: number; + changeAmount: number; + }> { if (!isSupportedFromAddress(props.address)) { throw TxBuildError.withComment(ErrorCodes.UNSUPPORTED_ADDRESS_TYPE, props.address); } const targetAmount = props.targetAmount; + const excludeUtxos = props.excludeUtxos ?? []; const injectCollected = props.injectCollected ?? false; const deductFromOutputs = props.deductFromOutputs ?? true; @@ -261,7 +277,7 @@ export class TxBuilder { minUtxoSatoshi: this.minUtxoSatoshi, onlyNonRgbppUtxos: this.onlyNonRgbppUtxos, onlyConfirmedUtxos: this.onlyConfirmedUtxos, - excludeUtxos: this.inputs.map((row) => row.utxo), + excludeUtxos: [...this.inputs.map((v) => v.utxo), ...excludeUtxos], }); utxos.forEach((utxo) => { this.addInput({ @@ -331,10 +347,12 @@ export class TxBuilder { // 3. Collect from "from" one more time if: // - Need to create an output to return change (changeAmount > 0) // - The change is insufficient for a non-dust output (changeAmount < minUtxoSatoshi) - const needForChange = changeAmount > 0 && changeAmount < this.minUtxoSatoshi; - const changeUtxoNeedAmount = needForChange ? this.minUtxoSatoshi - changeAmount : 0; - if (needForChange) { - await _collect(changeUtxoNeedAmount); + const changeAddress = props.changeAddress ?? props.address; + const changeToOutputs = !this.canInjectChangeToOutputs(changeAddress); + const needChangeOutput = !changeToOutputs && changeAmount > 0 && changeAmount < this.minUtxoSatoshi; + const changeOutputNeedAmount = needChangeOutput ? this.minUtxoSatoshi - changeAmount : 0; + if (changeOutputNeedAmount > 0) { + await _collect(changeOutputNeedAmount); } // 4. If not collected enough satoshi, throw an error @@ -346,9 +364,9 @@ export class TxBuilder { `expected: ${targetAmount}, actual: ${collected}. You may wanna deposit more satoshi to prevent the error, for example: ${recommendedDeposit}`, ); } - const insufficientForChange = changeAmount > 0 && changeAmount < this.minUtxoSatoshi; + const insufficientForChange = !changeToOutputs && changeAmount > 0 && changeAmount < this.minUtxoSatoshi; if (insufficientForChange) { - const shiftedExpectAmount = collected + changeUtxoNeedAmount; + const shiftedExpectAmount = collected + changeOutputNeedAmount; throw TxBuildError.withComment( ErrorCodes.INSUFFICIENT_UTXO, `expected: ${shiftedExpectAmount}, actual: ${collected}`, @@ -360,14 +378,14 @@ export class TxBuilder { // - If changeAmount>0, return change to an output or create a change output let changeIndex: number = -1; if (changeAmount > 0) { - changeIndex = this.outputs.length; - const changeAddress = props.changeAddress ?? props.address; - await this.injectChange({ + const injectedChanged = await this.injectChange({ amount: changeAmount, address: changeAddress, fromAddress: props.address, fromPublicKey: props.publicKey, }); + + changeIndex = injectedChanged.changeIndex; } return { @@ -383,8 +401,11 @@ export class TxBuilder { fromAddress: string; fromPublicKey?: string; internalCacheKey?: string; - }) { - const { address, fromAddress, fromPublicKey, amount, internalCacheKey } = props; + excludeUtxos?: BaseOutput[]; + }): Promise<{ + changeIndex: number; + }> { + const { address, fromAddress, fromPublicKey, amount, excludeUtxos, internalCacheKey } = props; // If any (output.fixed != true) is found in the outputs (search in ASC order), // return the change value to the first matched output. @@ -398,9 +419,12 @@ export class TxBuilder { } output.value += amount; - return; + return { + changeIndex: i, + }; } + let changeIndex: number = -1; if (amount < this.minUtxoSatoshi) { // If the change is not enough to create a non-dust output, try collect more. // - injectCollected=true, expect to put all (collected + amount) of satoshi as change @@ -409,7 +433,7 @@ export class TxBuilder { // 1. Expected to return change of 500 satoshi, amount=500 // 2. Collected 2000 satoshi from the "fromAddress", collected=2000 // 3. Create a change output and return (collected + amount), output.value=2000+500=2500 - const { collected } = await this.injectSatoshi({ + const injected = await this.injectSatoshi({ address: fromAddress, publicKey: fromPublicKey, targetAmount: amount, @@ -417,16 +441,34 @@ export class TxBuilder { injectCollected: true, deductFromOutputs: false, internalCacheKey, + excludeUtxos, }); - if (collected < amount) { - throw TxBuildError.withComment(ErrorCodes.INSUFFICIENT_UTXO, `expected: ${amount}, actual: ${collected}`); + if (injected.collected < amount) { + throw TxBuildError.withComment( + ErrorCodes.INSUFFICIENT_UTXO, + `expected: ${amount}, actual: ${injected.collected}`, + ); } + + changeIndex = injected.changeIndex; } else { this.addOutput({ address: address, value: amount, }); + + changeIndex = this.outputs.length - 1; } + + return { + changeIndex, + }; + } + + canInjectChangeToOutputs(changeAddress: string): boolean { + return this.outputs.some((output) => { + return !output.fixed && (!('address' in output) || output.address === changeAddress); + }); } async calculateFee(addressType: AddressType, feeRate?: number): Promise { diff --git a/packages/btc/src/transaction/utxo.ts b/packages/btc/src/transaction/utxo.ts index 1cddd514..a5076e14 100644 --- a/packages/btc/src/transaction/utxo.ts +++ b/packages/btc/src/transaction/utxo.ts @@ -3,9 +3,12 @@ import { AddressType } from '../address'; import { TxInput } from './build'; import { remove0x, toXOnly } from '../utils'; -export interface Output { +export interface BaseOutput { txid: string; vout: number; +} + +export interface Output extends BaseOutput { value: number; scriptPk: string; } diff --git a/packages/btc/tests/Transaction.test.ts b/packages/btc/tests/Transaction.test.ts index 0de77c9b..7c7f8e18 100644 --- a/packages/btc/tests/Transaction.test.ts +++ b/packages/btc/tests/Transaction.test.ts @@ -1,8 +1,8 @@ import { describe, expect, it } from 'vitest'; -import { expectPsbtFeeInRange } from './shared/utils'; import { accounts, config, network, service, source } from './shared/env'; -import { bitcoin, ErrorMessages, ErrorCodes, AddressType, createSendUtxosBuilder } from '../src'; -import { createSendBtcBuilder, sendBtc, sendUtxos, tweakSigner } from '../src'; +import { expectPsbtFeeInRange, signAndBroadcastPsbt, waitFor } from './shared/utils'; +import { bitcoin, ErrorMessages, ErrorCodes, AddressType } from '../src'; +import { createSendUtxosBuilder, createSendBtcBuilder, sendBtc, sendUtxos, sendRbf, tweakSigner } from '../src'; const STATIC_FEE_RATE = 1; const BTC_UTXO_DUST_LIMIT = config.btcUtxoDustLimit; @@ -19,6 +19,7 @@ describe('Transaction', () => { value: 1000, }, ], + feeRate: STATIC_FEE_RATE, source, }); @@ -27,7 +28,7 @@ describe('Transaction', () => { psbt.signAllInputs(accounts.charlie.keyPair); psbt.finalizeAllInputs(); - console.log('tx paid fee:', psbt.getFee()); + expect(feeRate).toEqual(STATIC_FEE_RATE); expectPsbtFeeInRange(psbt, feeRate); // Broadcast transaction @@ -45,6 +46,7 @@ describe('Transaction', () => { value: 1000, }, ], + feeRate: STATIC_FEE_RATE, source, }); @@ -57,11 +59,7 @@ describe('Transaction', () => { psbt.signAllInputs(tweakedSigner); psbt.finalizeAllInputs(); - console.log(psbt.txInputs); - console.log(psbt.txOutputs); - - console.log('tx paid fee:', psbt.getFee()); - expectPsbtFeeInRange(psbt); + expectPsbtFeeInRange(psbt, STATIC_FEE_RATE); // Broadcast transaction // const tx = psbt.extractTransaction(); @@ -78,6 +76,7 @@ describe('Transaction', () => { value: 546, }, ], + feeRate: STATIC_FEE_RATE, source, }), ).rejects.toThrow(); @@ -99,6 +98,7 @@ describe('Transaction', () => { }, ], minUtxoSatoshi: impossibleLimit, + feeRate: STATIC_FEE_RATE, source, }), ).rejects.toThrow(ErrorMessages[ErrorCodes.INSUFFICIENT_UTXO]); @@ -116,6 +116,7 @@ describe('Transaction', () => { value: 1000, }, ], + feeRate: STATIC_FEE_RATE, source, }); @@ -141,8 +142,7 @@ describe('Transaction', () => { expect(data).toBeInstanceOf(Buffer); expect((data as Buffer).toString('hex')).toEqual('00'.repeat(32)); - console.log('tx paid fee:', psbt.getFee()); - expectPsbtFeeInRange(psbt); + expectPsbtFeeInRange(psbt, STATIC_FEE_RATE); // Broadcast transaction // const tx = psbt.extractTransaction(); @@ -153,7 +153,7 @@ describe('Transaction', () => { describe('sendUtxos()', () => { it('Transfer fixed UTXO, sum(ins) = sum(outs)', async () => { - const { builder, feeRate } = await createSendUtxosBuilder({ + const { builder, feeRate, changeIndex } = await createSendUtxosBuilder({ from: accounts.charlie.p2wpkh.address, inputs: [ { @@ -173,6 +173,7 @@ describe('Transaction', () => { }, ], source, + feeRate: STATIC_FEE_RATE, }); // Sign & finalize inputs @@ -182,9 +183,9 @@ describe('Transaction', () => { expect(psbt.txInputs.length).toBeGreaterThanOrEqual(2); expect(psbt.txOutputs).toHaveLength(2); - - console.log('tx paid fee:', psbt.getFee()); - expectPsbtFeeInRange(psbt, feeRate); + expect(changeIndex).toEqual(1); + expect(feeRate).toEqual(STATIC_FEE_RATE); + expectPsbtFeeInRange(psbt, STATIC_FEE_RATE); // Broadcast transaction // const tx = psbt.extractTransaction(); @@ -212,8 +213,6 @@ describe('Transaction', () => { expect(psbt.txInputs.length).toBeGreaterThanOrEqual(1); expect(psbt.txOutputs).toHaveLength(2); - - console.log('tx paid fee:', psbt.getFee()); expectPsbtFeeInRange(psbt, feeRate); // Broadcast transaction @@ -241,6 +240,7 @@ describe('Transaction', () => { fixed: true, }, ], + feeRate: STATIC_FEE_RATE, source, }); @@ -250,9 +250,7 @@ describe('Transaction', () => { expect(psbt.txInputs.length).toBeGreaterThanOrEqual(2); expect(psbt.txOutputs).toHaveLength(2); - - console.log('tx paid fee:', psbt.getFee()); - expectPsbtFeeInRange(psbt); + expectPsbtFeeInRange(psbt, STATIC_FEE_RATE); // Broadcast transaction // const tx = psbt.extractTransaction(); @@ -279,6 +277,7 @@ describe('Transaction', () => { fixed: true, }, ], + feeRate: STATIC_FEE_RATE, source, }); @@ -288,9 +287,7 @@ describe('Transaction', () => { expect(psbt.txInputs.length).toBeGreaterThanOrEqual(2); expect(psbt.txOutputs).toHaveLength(2); - - console.log('tx paid fee:', psbt.getFee()); - expectPsbtFeeInRange(psbt); + expectPsbtFeeInRange(psbt, STATIC_FEE_RATE); // Broadcast transaction // const tx = psbt.extractTransaction(); @@ -327,8 +324,6 @@ describe('Transaction', () => { expect(psbt.txInputs).toHaveLength(1); expect(psbt.txOutputs).toHaveLength(2); - - console.log('tx paid fee:', psbt.getFee()); expectPsbtFeeInRange(psbt, STATIC_FEE_RATE); // Broadcast transaction @@ -366,8 +361,6 @@ describe('Transaction', () => { expect(psbt.txInputs).toHaveLength(1); expect(psbt.txOutputs).toHaveLength(2); - - console.log('tx paid fee:', psbt.getFee()); expectPsbtFeeInRange(psbt, STATIC_FEE_RATE); // Broadcast transaction @@ -376,7 +369,7 @@ describe('Transaction', () => { // console.log(`explorer: https://mempool.space/testnet/tx/${res.txid}`); }); it('Transfer fixed UTXO, sum(ins) > sum(outs), change < fee', async () => { - const { builder, feeRate } = await createSendUtxosBuilder({ + const { builder, feeRate, changeIndex } = await createSendUtxosBuilder({ from: accounts.charlie.p2wpkh.address, inputs: [ { @@ -395,7 +388,7 @@ describe('Transaction', () => { fixed: true, }, ], - feeRate: 10, + feeRate: STATIC_FEE_RATE, source, }); @@ -406,9 +399,8 @@ describe('Transaction', () => { expect(psbt.txInputs.length).toBeGreaterThanOrEqual(2); expect(psbt.txOutputs).toHaveLength(2); - - console.log('tx fee:', psbt.getFee()); - console.log('tx fee rate:', psbt.getFeeRate()); + expect(changeIndex).toEqual(1); + expect(feeRate).toEqual(STATIC_FEE_RATE); expectPsbtFeeInRange(psbt, feeRate); // Broadcast transaction @@ -417,7 +409,7 @@ describe('Transaction', () => { // console.log(`explorer: https://mempool.space/testnet/tx/${res.txid}`); }); it('Transfer fixed UTXO, sum(ins) > sum(outs), change = fee', async () => { - const psbt = await sendUtxos({ + const { builder, feeRate, changeIndex } = await createSendUtxosBuilder({ from: accounts.charlie.p2wpkh.address, inputs: [ { @@ -432,7 +424,7 @@ describe('Transaction', () => { outputs: [ { address: accounts.charlie.p2wpkh.address, - value: 1856, + value: 1859, fixed: true, }, { @@ -445,13 +437,14 @@ describe('Transaction', () => { }); // Sign & finalize inputs + const psbt = builder.toPsbt(); psbt.signAllInputs(accounts.charlie.keyPair); psbt.finalizeAllInputs(); expect(psbt.txInputs).toHaveLength(1); expect(psbt.txOutputs).toHaveLength(2); - - console.log('tx paid fee:', psbt.getFee()); + expect(changeIndex).toEqual(-1); + expect(feeRate).toEqual(STATIC_FEE_RATE); expectPsbtFeeInRange(psbt, STATIC_FEE_RATE); // Broadcast transaction @@ -496,12 +489,8 @@ describe('Transaction', () => { psbt.signAllInputs(accounts.charlie.keyPair); psbt.finalizeAllInputs(); - console.log(psbt.data.inputs.map((row) => row.finalScriptWitness!.byteLength)); - expect(psbt.txInputs).toHaveLength(2); expect(psbt.txOutputs).toHaveLength(1); - - console.log('tx paid fee:', psbt.getFee()); expectPsbtFeeInRange(psbt, STATIC_FEE_RATE); // Broadcast transaction @@ -529,6 +518,7 @@ describe('Transaction', () => { protected: true, }, ], + feeRate: STATIC_FEE_RATE, source, }); @@ -538,9 +528,7 @@ describe('Transaction', () => { expect(psbt.txInputs.length).toBeGreaterThanOrEqual(2); expect(psbt.txOutputs).toHaveLength(1); - - console.log('tx paid fee:', psbt.getFee()); - expectPsbtFeeInRange(psbt); + expectPsbtFeeInRange(psbt, STATIC_FEE_RATE); // Broadcast transaction // const tx = psbt.extractTransaction(); @@ -577,8 +565,6 @@ describe('Transaction', () => { expect(psbt.txInputs).toHaveLength(1); expect(psbt.txOutputs).toHaveLength(1); - - console.log('tx paid fee:', psbt.getFee()); expectPsbtFeeInRange(psbt, STATIC_FEE_RATE); // Broadcast transaction @@ -617,9 +603,7 @@ describe('Transaction', () => { expect(psbt.txInputs.length).toBeGreaterThanOrEqual(2); expect(psbt.txOutputs).toHaveLength(1); - - console.log('tx paid fee:', psbt.getFee()); - console.log('tx paid fee rate:', psbt.getFeeRate()); + expect(feeRate).toEqual(10); expectPsbtFeeInRange(psbt, feeRate); // Broadcast transaction @@ -628,6 +612,95 @@ describe('Transaction', () => { // console.log(`explorer: https://mempool.space/testnet/tx/${res.txid}`); }); + it('Transfer protected UTXO, change to the first address-matched output', async () => { + const { builder, changeIndex } = await createSendUtxosBuilder({ + from: accounts.charlie.p2wpkh.address, + inputs: [ + { + txid: '4e1e9f8ff4bf245793c05bf2da58bff812c332a296d93c6935fbc980d906e567', + vout: 1, + value: 10000, + addressType: AddressType.P2WPKH, + address: accounts.charlie.p2wpkh.address, + scriptPk: accounts.charlie.p2wpkh.scriptPubkey.toString('hex'), + }, + ], + outputs: [ + { + address: accounts.charlie.p2tr.address, + value: 1000, + protected: true, + }, + { + address: accounts.charlie.p2wpkh.address, + value: 1000, + protected: true, + }, + ], + feeRate: STATIC_FEE_RATE, + source, + }); + + // Sign & finalize inputs + const psbt = builder.toPsbt(); + psbt.signAllInputs(accounts.charlie.keyPair); + psbt.finalizeAllInputs(); + + expect(changeIndex).toEqual(1); + expect(psbt.txInputs).toHaveLength(1); + expect(psbt.txOutputs).toHaveLength(2); + expectPsbtFeeInRange(psbt, STATIC_FEE_RATE); + + // Broadcast transaction + // const tx = psbt.extractTransaction(); + // const res = await service.sendBtcTransaction(tx.toHex()); + // console.log(`explorer: https://mempool.space/testnet/tx/${res.txid}`); + }); + it('Transfer mixed UTXO, change to the first non-fixed output', async () => { + const { builder, changeIndex } = await createSendUtxosBuilder({ + from: accounts.charlie.p2wpkh.address, + inputs: [ + { + txid: '4e1e9f8ff4bf245793c05bf2da58bff812c332a296d93c6935fbc980d906e567', + vout: 1, + value: 10000, + addressType: AddressType.P2WPKH, + address: accounts.charlie.p2wpkh.address, + scriptPk: accounts.charlie.p2wpkh.scriptPubkey.toString('hex'), + }, + ], + outputs: [ + { + address: accounts.charlie.p2wpkh.address, + value: 1000, + fixed: true, + }, + { + address: accounts.charlie.p2wpkh.address, + value: 1000, + protected: true, + }, + ], + feeRate: STATIC_FEE_RATE, + source, + }); + + // Sign & finalize inputs + const psbt = builder.toPsbt(); + psbt.signAllInputs(accounts.charlie.keyPair); + psbt.finalizeAllInputs(); + + expect(changeIndex).toEqual(1); + expect(psbt.txInputs).toHaveLength(1); + expect(psbt.txOutputs).toHaveLength(2); + expectPsbtFeeInRange(psbt, STATIC_FEE_RATE); + + // Broadcast transaction + // const tx = psbt.extractTransaction(); + // const res = await service.sendBtcTransaction(tx.toHex()); + // console.log(`explorer: https://mempool.space/testnet/tx/${res.txid}`); + }); + it('Transfer protected RGBPP_UTXOs, sum(ins) = sum(outs)', async () => { const psbt = await sendUtxos({ from: accounts.charlie.p2wpkh.address, @@ -663,6 +736,7 @@ describe('Transaction', () => { protected: true, }, ], + feeRate: STATIC_FEE_RATE, source, }); @@ -675,8 +749,7 @@ describe('Transaction', () => { expect(psbt.txOutputs[0].value).toBeGreaterThan(RGBPP_UTXO_DUST_LIMIT); expect(psbt.txOutputs[1].value).toBe(RGBPP_UTXO_DUST_LIMIT); - console.log('tx paid fee:', psbt.getFee()); - expectPsbtFeeInRange(psbt); + expectPsbtFeeInRange(psbt, STATIC_FEE_RATE); // Broadcast transaction // const tx = psbt.extractTransaction(); @@ -724,13 +797,11 @@ describe('Transaction', () => { psbt.signAllInputs(accounts.charlie.keyPair); psbt.finalizeAllInputs(); - console.log(psbt.txOutputs); expect(psbt.txInputs).toHaveLength(1); expect(psbt.txOutputs).toHaveLength(3); expect(psbt.txOutputs[0].value).toBeLessThan(psbt.txOutputs[1].value); expect(psbt.txOutputs[1].value).toBeLessThan(psbt.txOutputs[2].value); - console.log('tx paid fee:', psbt.getFee()); expectPsbtFeeInRange(psbt, STATIC_FEE_RATE); // Broadcast transaction @@ -773,13 +844,11 @@ describe('Transaction', () => { psbt.signAllInputs(accounts.charlie.keyPair); psbt.finalizeAllInputs(); - console.log(psbt.txOutputs); expect(psbt.txInputs.length).toBeGreaterThanOrEqual(2); expect(psbt.txOutputs).toHaveLength(2); expect(psbt.txOutputs[0].value).toBeGreaterThan(RGBPP_UTXO_DUST_LIMIT); expect(psbt.txOutputs[1].value).toBe(RGBPP_UTXO_DUST_LIMIT); - console.log('tx paid fee:', psbt.getFee()); expectPsbtFeeInRange(psbt, STATIC_FEE_RATE); // Broadcast transaction @@ -809,12 +878,317 @@ describe('Transaction', () => { }, ], onlyConfirmedUtxos: true, + feeRate: STATIC_FEE_RATE, source, }), ).rejects.toThrow(); }); }); + describe.skip('sendRbf()', () => { + it('Full RBF', async () => { + /** + * TX_1, feeRate=minimumFee/2 + */ + const feeRates = await service.getBtcRecommendedFeeRates(); + const expectFeeRate = Math.max(Math.round(feeRates.minimumFee / 2), 1); + const psbt = await sendBtc({ + from: accounts.charlie.p2wpkh.address, + tos: [ + { + address: accounts.charlie.p2wpkh.address, + value: BTC_UTXO_DUST_LIMIT, + }, + ], + feeRate: expectFeeRate, + source, + }); + const { txHex } = await signAndBroadcastPsbt({ + psbt, + account: accounts.charlie, + feeRate: expectFeeRate, + }); + + /** + * Wait for 2 seconds + */ + await waitFor(2000); + console.log('---'); + + /** + * TX_2, feeRate=fastestFee + */ + const expectFeeRate2 = Math.max(feeRates.fastestFee, expectFeeRate + 1); + const psbt2 = await sendRbf({ + txHex: txHex, + from: accounts.charlie.p2wpkh.address, + feeRate: expectFeeRate2, + source, + }); + await signAndBroadcastPsbt({ + psbt: psbt2, + account: accounts.charlie, + feeRate: expectFeeRate2, + }); + }, 0); + it('Full RBF with changeIndex', async () => { + /** + * TX_1, feeRate=1 + */ + const feeRates = await service.getBtcRecommendedFeeRates(); + const expectFeeRate = Math.max(Math.round(feeRates.minimumFee / 2), 1); + const psbt = await sendBtc({ + from: accounts.charlie.p2wpkh.address, + tos: [ + { + address: accounts.charlie.p2wpkh.address, + value: BTC_UTXO_DUST_LIMIT, + }, + ], + feeRate: expectFeeRate, + source, + }); + const { tx, txHex } = await signAndBroadcastPsbt({ + psbt, + account: accounts.charlie, + feeRate: expectFeeRate, + }); + + /** + * Wait for 2 seconds + */ + await waitFor(2000); + console.log('---'); + + /** + * TX_2, feeRate=fastestFee + */ + const expectFeeRate2 = Math.max(feeRates.fastestFee, expectFeeRate + 1); + const changeIndex = tx.outs.length - 1; + const psbt2 = await sendRbf({ + txHex: txHex, + from: accounts.charlie.p2wpkh.address, + feeRate: expectFeeRate2, + changeIndex, + source, + }); + await signAndBroadcastPsbt({ + psbt: psbt2, + account: accounts.charlie, + feeRate: expectFeeRate2, + }); + }, 0); + it('Full RBF with changeIndex, outputs.length == 1', async () => { + /** + * TX_1, feeRate=1 + */ + const feeRates = await service.getBtcRecommendedFeeRates(); + const expectFeeRate = Math.max(Math.round(feeRates.minimumFee / 2), 1); + const psbt = await sendBtc({ + from: accounts.charlie.p2wpkh.address, + tos: [ + { + address: accounts.charlie.p2wpkh.address, + value: BTC_UTXO_DUST_LIMIT, + protected: true, + fixed: false, + }, + ], + feeRate: expectFeeRate, + source, + }); + const { tx, txHex } = await signAndBroadcastPsbt({ + psbt, + account: accounts.charlie, + feeRate: expectFeeRate, + }); + + console.log(tx.outs); + + /** + * Wait for 2 seconds + */ + await waitFor(2000); + console.log('---'); + + /** + * TX_2, feeRate=fastestFee + */ + const expectFeeRate2 = Math.max(feeRates.fastestFee, expectFeeRate + 1); + const changeIndex = tx.outs.length - 1; + const psbt2 = await sendRbf({ + txHex: txHex, + from: accounts.charlie.p2wpkh.address, + feeRate: expectFeeRate2, + changeIndex, + source, + }); + await signAndBroadcastPsbt({ + psbt: psbt2, + account: accounts.charlie, + feeRate: expectFeeRate2, + }); + }, 0); + it('Full RBF with changeIndex, outputs.length != changeIndex + 1', async () => { + /** + * TX_1, feeRate=1 + */ + const feeRates = await service.getBtcRecommendedFeeRates(); + const expectFeeRate = Math.max(Math.round(feeRates.minimumFee / 2), 1); + const psbt = await sendBtc({ + from: accounts.charlie.p2wpkh.address, + tos: [ + { + address: accounts.charlie.p2wpkh.address, + value: 3000, + }, + ], + feeRate: expectFeeRate, + source, + }); + const { txHex } = await signAndBroadcastPsbt({ + psbt, + account: accounts.charlie, + feeRate: expectFeeRate, + }); + + /** + * Wait for 2 seconds + */ + await waitFor(2000); + console.log('---'); + + /** + * TX_2, feeRate=fastestFee + */ + const expectFeeRate2 = Math.max(feeRates.fastestFee, expectFeeRate + 1); + const psbt2 = await sendRbf({ + txHex: txHex, + from: accounts.charlie.p2wpkh.address, + feeRate: expectFeeRate2, + changeIndex: 0, + source, + }); + await signAndBroadcastPsbt({ + psbt: psbt2, + account: accounts.charlie, + feeRate: expectFeeRate2, + }); + }, 0); + it('Try Full RBF with invalid change', async () => { + /** + * TX_1, feeRate=1 + */ + const expectFeeRate = 1; + const psbt = await sendBtc({ + from: accounts.charlie.p2wpkh.address, + tos: [ + { + data: Buffer.from('hello'), + value: 0, + }, + { + address: accounts.charlie.p2tr.address, + value: BTC_UTXO_DUST_LIMIT, + }, + ], + feeRate: expectFeeRate, + source, + }); + const { tx, txHex } = await signAndBroadcastPsbt({ + psbt, + account: accounts.charlie, + feeRate: expectFeeRate, + }); + + /** + * Wait for 2 seconds + */ + console.log('---'); + await waitFor(2000); + const expectFeeRate2 = expectFeeRate * 2; + + /** + * TX_2, outputs[changeIndex] == undefined + */ + await expect(() => + sendRbf({ + txHex: txHex, + from: accounts.charlie.p2wpkh.address, + changeAddress: accounts.charlie.p2tr.address, + feeRate: expectFeeRate2, + changeIndex: 3, + source, + }), + ).rejects.toHaveProperty('code', ErrorCodes.INVALID_CHANGE_OUTPUT); + /** + * TX_3, changeOutput is not returnable + */ + await expect(() => + sendRbf({ + txHex: txHex, + from: accounts.charlie.p2wpkh.address, + feeRate: expectFeeRate2, + changeIndex: 0, + source, + }), + ).rejects.toHaveProperty('code', ErrorCodes.INVALID_CHANGE_OUTPUT); + /** + * TX_4, changeAddress !== changeOutputAddress + */ + await expect(() => + sendRbf({ + txHex: txHex, + from: accounts.charlie.p2wpkh.address, + changeAddress: accounts.charlie.p2tr.address, + changeIndex: tx.outs.length - 1, + feeRate: expectFeeRate2, + source, + }), + ).rejects.toHaveProperty('code', ErrorCodes.INVALID_CHANGE_OUTPUT); + }, 0); + it('Try Full RBF with invalid feeRate', async () => { + /** + * TX_1, feeRate=1 + */ + const expectFeeRate = 1; + const psbt = await sendBtc({ + from: accounts.charlie.p2wpkh.address, + tos: [ + { + address: accounts.charlie.p2wpkh.address, + value: BTC_UTXO_DUST_LIMIT, + }, + ], + feeRate: expectFeeRate, + source, + }); + const { txHex } = await signAndBroadcastPsbt({ + psbt, + account: accounts.charlie, + feeRate: expectFeeRate, + }); + + /** + * Wait for 2 seconds + */ + await waitFor(2000); + console.log('---'); + + /** + * TX_2, feeRate=1 + */ + await expect( + await sendRbf({ + txHex: txHex, + from: accounts.charlie.p2wpkh.address, + feeRate: expectFeeRate, + source, + }), + ).rejects.toHaveProperty('code', ErrorCodes.INVALID_FEE_RATE); + }, 0); + }); + describe.todo('sendRgbppUtxos()', () => { // TODO: fill tests }); diff --git a/packages/btc/tests/shared/env.ts b/packages/btc/tests/shared/env.ts index 195a200b..fffb444d 100644 --- a/packages/btc/tests/shared/env.ts +++ b/packages/btc/tests/shared/env.ts @@ -1,5 +1,6 @@ import { BtcAssetsApi } from '@rgbpp-sdk/service'; -import { bitcoin, ECPair, toXOnly, networkTypeToConfig, DataSource, NetworkType } from '../../src'; +import { DataSource, NetworkType, networkTypeToConfig } from '../../src'; +import { createAccount } from './utils'; export const networkType = NetworkType.TESTNET; export const config = networkTypeToConfig(networkType); @@ -14,35 +15,8 @@ export const service = BtcAssetsApi.fromToken( export const source = new DataSource(service, networkType); export const accounts = { - charlie: createAccount('8d3c23d340ac0841e6c3b58a9bbccb9a28e94ab444f972cff35736fa2fcf9f3f', network), + charlie: createAccount({ + privateKey: '8d3c23d340ac0841e6c3b58a9bbccb9a28e94ab444f972cff35736fa2fcf9f3f', + network, + }), }; - -function createAccount(privateKey: string, _network?: bitcoin.Network) { - const keyPair = ECPair.fromPrivateKey(Buffer.from(privateKey, 'hex'), { network: _network }); - const p2wpkh = bitcoin.payments.p2wpkh({ - pubkey: keyPair.publicKey, - network: _network, - }); - const p2tr = bitcoin.payments.p2tr({ - internalPubkey: toXOnly(keyPair.publicKey), - network: _network, - }); - - return { - keyPair, - privateKey, - publicKey: keyPair.publicKey.toString('hex'), - p2wpkh: { - scriptPubkey: p2wpkh.output!, - address: p2wpkh.address!, - pubkey: p2wpkh.pubkey!, - data: p2wpkh.data!, - }, - p2tr: { - scriptPubkey: p2tr.output!, - address: p2tr.address!, - pubkey: p2tr.pubkey!, - data: p2tr.data!, - }, - }; -} diff --git a/packages/btc/tests/shared/utils.ts b/packages/btc/tests/shared/utils.ts index e259f56b..b8598ca5 100644 --- a/packages/btc/tests/shared/utils.ts +++ b/packages/btc/tests/shared/utils.ts @@ -1,6 +1,15 @@ import { expect } from 'vitest'; -import { bitcoin } from '../../src'; -import { config } from './env'; +import { ECPairInterface } from 'ecpair'; +import { NetworkType, bitcoin, ECPair } from '../../src'; +import { toXOnly, remove0x, tweakSigner, isP2trScript, isP2wpkhScript } from '../../src'; +import { config, network, networkType, service } from './env'; + +/** + * Wait for a number of milliseconds. + */ +export function waitFor(ms: number) { + return new Promise((resolve) => setTimeout(resolve, ms)); +} /** * Estimate a network fee of a PSBT. @@ -22,9 +31,128 @@ export function expectPsbtFeeInRange(psbt: bitcoin.Psbt, feeRate?: number) { const estimated = calculatePsbtFee(psbt, feeRate); const paid = psbt.getFee(); + console.log('fee rate:', psbt.getFeeRate(), 'expected:', feeRate ?? config.feeRate); + console.log('fee:', paid, 'expected:', estimated); + const inputs = psbt.data.inputs.length; const diff = paid - estimated; expect(diff).toBeGreaterThanOrEqual(0); expect(diff).toBeLessThanOrEqual(diff + inputs); } + +/** + * Report transaction info in log + */ +export function logTransaction(tx: bitcoin.Transaction, networkType: NetworkType) { + const id = tx.getId(); + const hex = tx.toHex(); + const url = networkType === NetworkType.MAINNET ? 'https://mempool.space/tx' : 'https://mempool.space/testnet/tx'; + + console.log('id:', id); + console.log('hex:', hex); + console.log('explorer:', `${url}/${id}`); +} + +/** + * Create accounts in tests for signing transactions + */ +export interface Account { + keyPair: ECPairInterface; + privateKey: Buffer; + publicKey: string; + p2wpkh: { + scriptPubkey: Buffer; + address: string; + pubkey: Buffer; + data: Buffer[]; + }; + p2tr: { + scriptPubkey: Buffer; + address: string; + pubkey: Buffer; + data: Buffer[]; + }; +} +export function createAccount(props: { privateKey: string; network?: bitcoin.Network }): Account { + const privateKey = Buffer.from(remove0x(props.privateKey), 'hex'); + const keyPair = ECPair.fromPrivateKey(privateKey, { + network: props.network, + }); + + const p2wpkh = bitcoin.payments.p2wpkh({ + pubkey: keyPair.publicKey, + network: props.network, + }); + const p2tr = bitcoin.payments.p2tr({ + internalPubkey: toXOnly(keyPair.publicKey), + network: props.network, + }); + + return { + keyPair, + privateKey, + publicKey: keyPair.publicKey.toString('hex'), + p2wpkh: { + scriptPubkey: p2wpkh.output!, + address: p2wpkh.address!, + pubkey: p2wpkh.pubkey!, + data: p2wpkh.data!, + }, + p2tr: { + scriptPubkey: p2tr.output!, + address: p2tr.address!, + pubkey: p2tr.pubkey!, + data: p2tr.data!, + }, + }; +} + +/** + * Sign and broadcast a transaction to the service + */ +export async function signAndBroadcastPsbt(props: { + psbt: bitcoin.Psbt; + account: Account; + feeRate?: number; + send?: boolean; +}): Promise<{ + tx: bitcoin.Transaction; + txId: string; + txHex: string; +}> { + const { psbt, account, feeRate, send = true } = props; + + // Create a tweaked signer for P2TR + const tweakedSigner = tweakSigner(account.keyPair, { network }); + + // Sign each input + psbt.data.inputs.forEach((input, index) => { + if (input.witnessUtxo) { + const script = input.witnessUtxo.script.toString('hex'); + if (isP2wpkhScript(script) && script === account.p2wpkh.scriptPubkey.toString('hex')) { + psbt.signInput(index, account.keyPair); + } + if (isP2trScript(script) && script === account.p2tr.scriptPubkey.toString('hex')) { + psbt.signInput(index, tweakedSigner); + } + } + }); + + psbt.finalizeAllInputs(); + expectPsbtFeeInRange(psbt, feeRate); + + const tx = psbt.extractTransaction(); + logTransaction(tx, networkType); + + if (send) { + const res = await service.sendBtcTransaction(tx.toHex()); + expect(res.txid).toEqual(tx.getId()); + } + + return { + tx, + txId: tx.getId(), + txHex: tx.toHex(), + }; +} From 1ecac341d5ced04e59bfdcd432a9bce84bedd959 Mon Sep 17 00:00:00 2001 From: Shook Date: Fri, 7 Jun 2024 13:58:25 +0800 Subject: [PATCH 72/90] feat: support including multi-origin UTXOs in the same transaction --- .changeset/orange-mice-trade.md | 9 +++ packages/btc/src/address.ts | 15 ++++ packages/btc/src/api/sendRbf.ts | 16 +--- packages/btc/src/api/sendRgbppUtxos.ts | 21 ++--- packages/btc/src/api/sendUtxos.ts | 24 ++++-- packages/btc/src/transaction/build.ts | 24 +++--- packages/btc/src/transaction/fee.ts | 108 +++++++++++++++++-------- packages/btc/src/transaction/utxo.ts | 66 ++++++++++++++- packages/btc/tests/Transaction.test.ts | 105 ++++++++++++++++++++++++ packages/btc/tests/shared/utils.ts | 60 ++++++++++---- 10 files changed, 346 insertions(+), 102 deletions(-) create mode 100644 .changeset/orange-mice-trade.md diff --git a/.changeset/orange-mice-trade.md b/.changeset/orange-mice-trade.md new file mode 100644 index 00000000..2ac305a4 --- /dev/null +++ b/.changeset/orange-mice-trade.md @@ -0,0 +1,9 @@ +--- +"@rgbpp-sdk/btc": minor +--- + +Support including multi-origin UTXOs in the same transaction + + - Add `pubkeyMap` option in the sendUtxos(), sendRgbppUtxos() and sendRbf() API + - Rename `inputsPubkey` option to `pubkeyMap` in the sendRbf() API + - Delete `onlyProvableUtxos` option from the sendRgbppUtxos() API diff --git a/packages/btc/src/address.ts b/packages/btc/src/address.ts index fa562d45..659d2ebd 100644 --- a/packages/btc/src/address.ts +++ b/packages/btc/src/address.ts @@ -210,3 +210,18 @@ function getAddressTypeDust(addressType: AddressType) { return 546; } } + +/** + * Add address/pubkey pair to a Record map + */ +export function addAddressToPubkeyMap( + pubkeyMap: Record, + address: string, + pubkey?: string, +): Record { + const newMap = { ...pubkeyMap }; + if (pubkey) { + newMap[address] = pubkey; + } + return newMap; +} diff --git a/packages/btc/src/api/sendRbf.ts b/packages/btc/src/api/sendRbf.ts index 466ee1b5..0e84e16b 100644 --- a/packages/btc/src/api/sendRbf.ts +++ b/packages/btc/src/api/sendRbf.ts @@ -6,7 +6,6 @@ import { isOpReturnScriptPubkey } from '../transaction/embed'; import { networkTypeToNetwork } from '../preset/network'; import { networkTypeToConfig } from '../preset/config'; import { createSendUtxosBuilder } from './sendUtxos'; -import { isP2trScript } from '../script'; import { bitcoin } from '../bitcoin'; export interface SendRbfProps { @@ -23,7 +22,7 @@ export interface SendRbfProps { requireGreaterFeeAndRate?: boolean; // EXPERIMENTAL: the below props are unstable and can be altered at any time - inputsPubkey?: Record; // Record + pubkeyMap?: Record; // Record } export async function createSendRbfBuilder(props: SendRbfProps): Promise<{ @@ -43,18 +42,6 @@ export async function createSendRbfBuilder(props: SendRbfProps): Promise<{ if (!utxo) { throw TxBuildError.withComment(ErrorCodes.CANNOT_FIND_UTXO, `hash: ${hash}, index: ${input.index}`); } - - // Ensure each P2TR input has a corresponding pubkey - const fromPubkey = utxo.address === props.from ? props.fromPubkey : undefined; - const inputPubkey = props.inputsPubkey?.[utxo.address]; - const pubkey = inputPubkey ?? fromPubkey; - if (pubkey) { - utxo.pubkey = pubkey; - } - if (isP2trScript(utxo.scriptPk) && !utxo.pubkey) { - throw TxBuildError.withComment(ErrorCodes.MISSING_PUBKEY, utxo.address); - } - inputs.push(utxo); } @@ -151,6 +138,7 @@ export async function createSendRbfBuilder(props: SendRbfProps): Promise<{ from: props.from, source: props.source, feeRate: props.feeRate, + pubkeyMap: props.pubkeyMap, fromPubkey: props.fromPubkey, minUtxoSatoshi: props.minUtxoSatoshi, onlyConfirmedUtxos: props.onlyConfirmedUtxos ?? true, diff --git a/packages/btc/src/api/sendRgbppUtxos.ts b/packages/btc/src/api/sendRgbppUtxos.ts index 69b3ab8e..f793e5b0 100644 --- a/packages/btc/src/api/sendRgbppUtxos.ts +++ b/packages/btc/src/api/sendRgbppUtxos.ts @@ -31,7 +31,7 @@ export interface SendRgbppUtxosProps { excludeUtxos?: BaseOutput[]; // EXPERIMENTAL: the below props are unstable and can be altered at any time - onlyProvableUtxos?: boolean; + pubkeyMap?: Record; // Record } /** @@ -45,8 +45,6 @@ export async function createSendRgbppUtxosBuilder(props: SendRgbppUtxosProps): P feeRate: number; changeIndex: number; }> { - const onlyProvableUtxos = props.onlyProvableUtxos ?? true; - const btcInputs: Utxo[] = []; const btcOutputs: InitOutput[] = []; let lastCkbTypeOutputIndex = -1; @@ -86,33 +84,23 @@ export async function createSendRgbppUtxosBuilder(props: SendRgbppUtxosProps): P for (let i = 0; i < ckbVirtualTx.inputs.length; i++) { const { lockArgs, isRgbppLock } = ckbLiveCells[i]; - // If input.lock == RgbppLock, add to inputs if: + // Add to inputs if all the following conditions are met: // 1. input.lock.args can be unpacked to RgbppLockArgs // 2. utxo can be found via the DataSource.getUtxo() API - // 3. utxo.scriptPk == addressToScriptPk(props.from) - // 4. utxo is not duplicated in the inputs + // 3. utxo is not duplicated in the inputs if (isRgbppLock) { const args = lockArgs!; const utxo = btcUtxos[i]; if (!utxo) { throw TxBuildError.withComment(ErrorCodes.CANNOT_FIND_UTXO, `hash: ${args.btcTxid}, index: ${args.outIndex}`); } - if (onlyProvableUtxos && utxo.address !== props.from) { - throw TxBuildError.withComment( - ErrorCodes.REFERENCED_UNPROVABLE_UTXO, - `hash: ${args.btcTxid}, index: ${args.outIndex}`, - ); - } const foundInInputs = btcInputs.some((v) => v.txid === utxo.txid && v.vout === utxo.vout); if (foundInInputs) { continue; } - btcInputs.push({ - ...utxo, - pubkey: props.fromPubkey, // For P2TR addresses, a pubkey is required - }); + btcInputs.push(utxo); } } @@ -179,6 +167,7 @@ export async function createSendRgbppUtxosBuilder(props: SendRgbppUtxosProps): P minUtxoSatoshi: props.minUtxoSatoshi, onlyConfirmedUtxos: props.onlyConfirmedUtxos, excludeUtxos: props.excludeUtxos, + pubkeyMap: props.pubkeyMap, }); } diff --git a/packages/btc/src/api/sendUtxos.ts b/packages/btc/src/api/sendUtxos.ts index 5f6abacf..ad5f44e8 100644 --- a/packages/btc/src/api/sendUtxos.ts +++ b/packages/btc/src/api/sendUtxos.ts @@ -1,7 +1,8 @@ import { bitcoin } from '../bitcoin'; import { DataSource } from '../query/source'; -import { BaseOutput, Utxo } from '../transaction/utxo'; import { TxBuilder, InitOutput } from '../transaction/build'; +import { BaseOutput, Utxo, prepareUtxoInputs } from '../transaction/utxo'; +import { addAddressToPubkeyMap } from '../address'; export interface SendUtxosProps { inputs: Utxo[]; @@ -17,6 +18,7 @@ export interface SendUtxosProps { // EXPERIMENTAL: the below props are unstable and can be altered at any time skipInputsValidation?: boolean; + pubkeyMap?: Record; // Record } export async function createSendUtxosBuilder(props: SendUtxosProps): Promise<{ @@ -32,16 +34,24 @@ export async function createSendUtxosBuilder(props: SendUtxosProps): Promise<{ onlyConfirmedUtxos: props.onlyConfirmedUtxos, }); - tx.addInputs(props.inputs); - tx.addOutputs(props.outputs); + // Prepare the UTXO inputs: + // 1. Fill pubkey for each P2TR UTXO, and throw if the corresponding pubkey is not found + // 2. Throw if unconfirmed UTXOs are found (if onlyConfirmedUtxos == true && skipInputsValidation == false) + const pubkeyMap = addAddressToPubkeyMap(props.pubkeyMap ?? {}, props.from, props.fromPubkey); + const inputs = await prepareUtxoInputs({ + utxos: props.inputs, + source: props.source, + requireConfirmed: props.onlyConfirmedUtxos && !props.skipInputsValidation, + requirePubkey: true, + pubkeyMap, + }); - if (props.onlyConfirmedUtxos && !props.skipInputsValidation) { - await tx.validateInputs(); - } + tx.addInputs(inputs); + tx.addOutputs(props.outputs); const paid = await tx.payFee({ address: props.from, - publicKey: props.fromPubkey, + publicKey: pubkeyMap[props.from], changeAddress: props.changeAddress, excludeUtxos: props.excludeUtxos, }); diff --git a/packages/btc/src/transaction/build.ts b/packages/btc/src/transaction/build.ts index a5c84082..7407fb59 100644 --- a/packages/btc/src/transaction/build.ts +++ b/packages/btc/src/transaction/build.ts @@ -3,7 +3,7 @@ import { bitcoin } from '../bitcoin'; import { DataSource } from '../query/source'; import { ErrorCodes, TxBuildError } from '../error'; import { NetworkType, RgbppBtcConfig } from '../preset/types'; -import { AddressType, addressToScriptPublicKeyHex, getAddressType, isSupportedFromAddress } from '../address'; +import { isSupportedFromAddress } from '../address'; import { dataToOpReturnScriptPubkey, isOpReturnScriptPubkey } from './embed'; import { networkTypeToConfig } from '../preset/config'; import { BaseOutput, Utxo, utxoToInput } from './utxo'; @@ -213,8 +213,7 @@ export class TxBuilder { } // Calculate network fee - const addressType = getAddressType(address); - currentFee = await this.calculateFee(addressType, currentFeeRate); + currentFee = await this.calculateFee(currentFeeRate); // If (fee = previousFee ±1), the fee is considered acceptable/expected. isFeeExpected = [-1, 0, 1].includes(currentFee - previousFee); @@ -471,14 +470,14 @@ export class TxBuilder { }); } - async calculateFee(addressType: AddressType, feeRate?: number): Promise { + async calculateFee(feeRate?: number): Promise { if (!feeRate && !this.feeRate) { throw TxBuildError.withComment(ErrorCodes.INVALID_FEE_RATE, `${feeRate ?? this.feeRate}`); } const currentFeeRate = feeRate ?? this.feeRate!; - const psbt = await this.createEstimatedPsbt(addressType); + const psbt = await this.createEstimatedPsbt(); const tx = psbt.extractTransaction(true); const inputs = tx.ins.length; @@ -490,20 +489,17 @@ export class TxBuilder { return Math.ceil(virtualSize * currentFeeRate); } - async createEstimatedPsbt(addressType: AddressType): Promise { - const estimate = FeeEstimator.fromRandom(addressType, this.networkType); - const estimateScriptPk = addressToScriptPublicKeyHex(estimate.address, this.networkType); + async createEstimatedPsbt(): Promise { + const estimator = FeeEstimator.fromRandom(this.networkType); const tx = this.clone(); - const utxos = tx.inputs.map((input) => input.utxo); - tx.inputs = utxos.map((utxo) => { - utxo.scriptPk = estimateScriptPk; - utxo.pubkey = estimate.publicKey; - return utxoToInput(utxo); + tx.inputs = tx.inputs.map((input) => { + const replacedUtxo = estimator.replaceUtxo(input.utxo); + return utxoToInput(replacedUtxo); }); const psbt = tx.toPsbt(); - await estimate.signPsbt(psbt); + await estimator.signPsbt(psbt); return psbt; } diff --git a/packages/btc/src/transaction/fee.ts b/packages/btc/src/transaction/fee.ts index 110f1d8e..3653ef85 100644 --- a/packages/btc/src/transaction/fee.ts +++ b/packages/btc/src/transaction/fee.ts @@ -1,61 +1,105 @@ import { ECPairInterface } from 'ecpair'; +import { AddressType } from '../address'; import { NetworkType } from '../preset/types'; +import { toXOnly, tweakSigner } from '../utils'; import { networkTypeToNetwork } from '../preset/network'; -import { AddressType, publicKeyToAddress } from '../address'; +import { isP2trScript, isP2wpkhScript } from '../script'; import { bitcoin, ECPair, isTaprootInput } from '../bitcoin'; -import { toXOnly, tweakSigner } from '../utils'; +import { Utxo } from './utxo'; + +interface FeeEstimateAccount { + payment: bitcoin.Payment; + addressType: AddressType; + address: string; + scriptPubkey: string; + tapInternalKey?: Buffer; +} export class FeeEstimator { public networkType: NetworkType; - public addressType: AddressType; public network: bitcoin.Network; private readonly keyPair: ECPairInterface; - public publicKey: string; - public address: string; + public readonly pubkey: string; + public accounts: { + p2wpkh: FeeEstimateAccount; + p2tr: FeeEstimateAccount; + }; - constructor(wif: string, networkType: NetworkType, addressType: AddressType) { + constructor(wif: string, networkType: NetworkType) { const network = networkTypeToNetwork(networkType); - const keyPair = ECPair.fromWIF(wif, network); + this.networkType = networkType; + this.network = network; + const keyPair = ECPair.fromWIF(wif, network); + this.pubkey = keyPair.publicKey.toString('hex'); this.keyPair = keyPair; - this.publicKey = keyPair.publicKey.toString('hex'); - this.address = publicKeyToAddress(this.publicKey, addressType, networkType); - this.addressType = addressType; - this.networkType = networkType; - this.network = network; + const p2wpkh = bitcoin.payments.p2wpkh({ + pubkey: keyPair.publicKey, + network, + }); + const p2tr = bitcoin.payments.p2tr({ + internalPubkey: toXOnly(keyPair.publicKey), + network, + }); + this.accounts = { + p2wpkh: { + payment: p2wpkh, + address: p2wpkh.address!, + addressType: AddressType.P2WPKH, + scriptPubkey: p2wpkh.output!.toString('hex'), + }, + p2tr: { + payment: p2tr, + address: p2tr.address!, + addressType: AddressType.P2TR, + tapInternalKey: toXOnly(keyPair.publicKey), + scriptPubkey: p2tr.output!.toString('hex'), + }, + }; } - static fromRandom(addressType: AddressType, networkType: NetworkType) { + static fromRandom(networkType: NetworkType) { const network = networkTypeToNetwork(networkType); const keyPair = ECPair.makeRandom({ network }); - return new FeeEstimator(keyPair.toWIF(), networkType, addressType); + return new FeeEstimator(keyPair.toWIF(), networkType); + } + + replaceUtxo(utxo: Utxo): Utxo { + if (utxo.addressType === AddressType.P2WPKH || isP2wpkhScript(utxo.scriptPk)) { + utxo.scriptPk = this.accounts.p2wpkh.scriptPubkey; + utxo.pubkey = this.pubkey; + } + if (utxo.addressType === AddressType.P2TR || isP2trScript(utxo.scriptPk)) { + utxo.scriptPk = this.accounts.p2tr.scriptPubkey; + utxo.pubkey = this.pubkey; + } + + return utxo; } async signPsbt(psbt: bitcoin.Psbt): Promise { - psbt.data.inputs.forEach((v) => { - const isNotSigned = !(v.finalScriptSig || v.finalScriptWitness); - const isP2TR = this.addressType === AddressType.P2TR; - const lostInternalPubkey = !v.tapInternalKey; - // Special measures taken for compatibility with certain applications. - if (isNotSigned && isP2TR && lostInternalPubkey) { - const tapInternalKey = toXOnly(Buffer.from(this.publicKey, 'hex')); - const { output } = bitcoin.payments.p2tr({ - internalPubkey: tapInternalKey, - network: networkTypeToNetwork(this.networkType), - }); - if (v.witnessUtxo?.script.toString('hex') == output?.toString('hex')) { - v.tapInternalKey = tapInternalKey; - } - } + // Tweak signer for P2TR inputs + const tweakedSigner = tweakSigner(this.keyPair, { + network: this.network, }); psbt.data.inputs.forEach((input, index) => { + // Fill tapInternalKey for P2TR inputs if missing + if (input.witnessUtxo) { + const isNotSigned = !(input.finalScriptSig || input.finalScriptWitness); + const isP2trInput = isP2trScript(input.witnessUtxo.script); + const lostInternalPubkey = !input.tapInternalKey; + if (isNotSigned && isP2trInput && lostInternalPubkey) { + if (input.witnessUtxo.script.toString('hex') === this.accounts.p2tr.scriptPubkey) { + input.tapInternalKey = this.accounts.p2tr.tapInternalKey!; + } + } + } + + // Sign P2WPKH/P2TR inputs if (isTaprootInput(input)) { - const tweakedSigner = tweakSigner(this.keyPair, { - network: this.network, - }); psbt.signInput(index, tweakedSigner); } else { psbt.signInput(index, this.keyPair); diff --git a/packages/btc/src/transaction/utxo.ts b/packages/btc/src/transaction/utxo.ts index a5076e14..d0af8c18 100644 --- a/packages/btc/src/transaction/utxo.ts +++ b/packages/btc/src/transaction/utxo.ts @@ -1,7 +1,10 @@ +import cloneDeep from 'lodash/cloneDeep'; import { ErrorCodes, TxBuildError } from '../error'; +import { DataSource } from '../query/source'; import { AddressType } from '../address'; import { TxInput } from './build'; -import { remove0x, toXOnly } from '../utils'; +import { limitPromiseBatchSize, remove0x, toXOnly } from '../utils'; +import { isP2trScript } from '../script'; export interface BaseOutput { txid: string; @@ -37,7 +40,7 @@ export function utxoToInput(utxo: Utxo): TxInput { } if (utxo.addressType === AddressType.P2TR) { if (!utxo.pubkey) { - throw new TxBuildError(ErrorCodes.MISSING_PUBKEY); + throw TxBuildError.withComment(ErrorCodes.MISSING_PUBKEY, utxo.address); } const data = { hash: utxo.txid, @@ -56,3 +59,62 @@ export function utxoToInput(utxo: Utxo): TxInput { throw new TxBuildError(ErrorCodes.UNSUPPORTED_ADDRESS_TYPE); } + +/** + * Fill pubkey for P2TR UTXO, and optionally throw an error if pubkey is missing + */ +export function fillUtxoPubkey( + utxo: Utxo, + pubkeyMap: Record, // Record + options?: { + requirePubkey?: boolean; + }, +): Utxo { + const newUtxo = cloneDeep(utxo); + if (isP2trScript(newUtxo.scriptPk) && !newUtxo.pubkey) { + const pubkey = pubkeyMap[newUtxo.address]; + if (options?.requirePubkey && !pubkey) { + throw TxBuildError.withComment(ErrorCodes.MISSING_PUBKEY, newUtxo.address); + } + if (pubkey) { + newUtxo.pubkey = pubkey; + } + } + + return newUtxo; +} + +/** + * Prepare and validate UTXOs for transaction building: + * 1. Fill pubkey for P2TR UTXOs, and optionally throw an error if pubkey is missing + * 2. Optionally check if the UTXOs are confirmed, and throw an error if not + */ +export async function prepareUtxoInputs(props: { + utxos: Utxo[]; + source: DataSource; + requirePubkey?: boolean; + requireConfirmed?: boolean; + pubkeyMap?: Record; // Record +}): Promise { + const pubkeyMap = props.pubkeyMap ?? {}; + const utxos = props.utxos.map((utxo) => { + return fillUtxoPubkey(utxo, pubkeyMap, { + requirePubkey: props.requirePubkey, + }); + }); + + if (props.requireConfirmed) { + await Promise.all( + utxos.map(async (utxo) => { + return limitPromiseBatchSize(async () => { + const transactionConfirmed = await props.source.isTransactionConfirmed(utxo.txid); + if (!transactionConfirmed) { + throw TxBuildError.withComment(ErrorCodes.UNCONFIRMED_UTXO, `hash: ${utxo.txid}, index: ${utxo.vout}`); + } + }); + }), + ); + } + + return utxos; +} diff --git a/packages/btc/tests/Transaction.test.ts b/packages/btc/tests/Transaction.test.ts index 7c7f8e18..b4fcd4c1 100644 --- a/packages/btc/tests/Transaction.test.ts +++ b/packages/btc/tests/Transaction.test.ts @@ -857,6 +857,111 @@ describe('Transaction', () => { // console.log(`explorer: https://mempool.space/testnet/tx/${res.txid}`); }); + it('Transfer P2TR, pay fee with P2WPKH', async () => { + const p2trUtxos = await source.getUtxos(accounts.charlie.p2tr.address, { + min_satoshi: BTC_UTXO_DUST_LIMIT, + only_confirmed: true, + }); + + const psbt = await sendUtxos({ + inputs: [p2trUtxos[0]], + outputs: [ + { + address: accounts.charlie.p2tr.address, + value: p2trUtxos[0].value, + fixed: true, + }, + ], + from: accounts.charlie.p2wpkh.address, + feeRate: STATIC_FEE_RATE, + pubkeyMap: { + [accounts.charlie.p2tr.address]: accounts.charlie.publicKey, + }, + source, + }); + + // Sign & finalize inputs + await signAndBroadcastPsbt({ + psbt, + account: accounts.charlie, + feeRate: STATIC_FEE_RATE, + send: false, + }); + }); + it('Transfer P2WPKH, pay fee with P2TR', async () => { + const p2wpkhUtxos = await source.getUtxos(accounts.charlie.p2wpkh.address, { + min_satoshi: BTC_UTXO_DUST_LIMIT, + only_confirmed: true, + }); + + const psbt = await sendUtxos({ + inputs: [p2wpkhUtxos[0]], + outputs: [ + { + address: accounts.charlie.p2wpkh.address, + value: p2wpkhUtxos[0].value, + fixed: true, + }, + ], + from: accounts.charlie.p2tr.address, + fromPubkey: accounts.charlie.publicKey, + feeRate: STATIC_FEE_RATE, + source, + }); + + // Sign & finalize inputs + await signAndBroadcastPsbt({ + psbt, + account: accounts.charlie, + feeRate: STATIC_FEE_RATE, + send: false, + }); + }); + it('Try mixed transfer, without pubkeyMap', async () => { + const p2trUtxos = await source.getUtxos(accounts.charlie.p2tr.address, { + min_satoshi: BTC_UTXO_DUST_LIMIT, + only_confirmed: true, + }); + + await expect(() => + sendUtxos({ + inputs: [p2trUtxos[0]], + outputs: [ + { + address: accounts.charlie.p2tr.address, + value: p2trUtxos[0].value, + fixed: true, + }, + ], + from: accounts.charlie.p2wpkh.address, + feeRate: STATIC_FEE_RATE, + source, + }), + ).rejects.toHaveProperty('code', ErrorCodes.MISSING_PUBKEY); + }); + it('Try mixed transfer, pay fee with P2TR without fromPubkey', async () => { + const p2wpkhUtxos = await source.getUtxos(accounts.charlie.p2wpkh.address, { + min_satoshi: BTC_UTXO_DUST_LIMIT, + only_confirmed: true, + }); + + await expect(() => + sendUtxos({ + inputs: [p2wpkhUtxos[0]], + outputs: [ + { + address: accounts.charlie.p2wpkh.address, + value: p2wpkhUtxos[0].value, + fixed: true, + }, + ], + from: accounts.charlie.p2tr.address, + feeRate: STATIC_FEE_RATE, + source, + }), + ).rejects.toHaveProperty('code', ErrorCodes.MISSING_PUBKEY); + }); + it('Try transfer non-existence UTXO', async () => { await expect(() => sendUtxos({ diff --git a/packages/btc/tests/shared/utils.ts b/packages/btc/tests/shared/utils.ts index b8598ca5..4efdb08d 100644 --- a/packages/btc/tests/shared/utils.ts +++ b/packages/btc/tests/shared/utils.ts @@ -109,11 +109,47 @@ export function createAccount(props: { privateKey: string; network?: bitcoin.Net } /** - * Sign and broadcast a transaction to the service + * Sign a PSBT with one or multiple BtcAccounts + */ +export function signPsbt(props: { + psbt: bitcoin.Psbt; + account: Account | Account[]; + finalizeInputs?: boolean; +}): bitcoin.Psbt { + const accounts = Array.isArray(props.account) ? props.account : [props.account]; + + const psbt = props.psbt; + for (const account of accounts) { + // Create a tweaked signer for P2TR + const tweakedSigner = tweakSigner(account.keyPair, { network }); + + // Sign each input + psbt.data.inputs.forEach((input, index) => { + if (input.witnessUtxo) { + const script = input.witnessUtxo.script.toString('hex'); + if (isP2wpkhScript(script) && script === account.p2wpkh.scriptPubkey.toString('hex')) { + psbt.signInput(index, account.keyPair); + } + if (isP2trScript(script) && script === account.p2tr.scriptPubkey.toString('hex')) { + psbt.signInput(index, tweakedSigner); + } + } + }); + } + + if (props.finalizeInputs) { + psbt.finalizeAllInputs(); + } + + return psbt; +} + +/** + * Sign and broadcast a PSBT to the service */ export async function signAndBroadcastPsbt(props: { psbt: bitcoin.Psbt; - account: Account; + account: Account | Account[]; feeRate?: number; send?: boolean; }): Promise<{ @@ -123,23 +159,13 @@ export async function signAndBroadcastPsbt(props: { }> { const { psbt, account, feeRate, send = true } = props; - // Create a tweaked signer for P2TR - const tweakedSigner = tweakSigner(account.keyPair, { network }); - - // Sign each input - psbt.data.inputs.forEach((input, index) => { - if (input.witnessUtxo) { - const script = input.witnessUtxo.script.toString('hex'); - if (isP2wpkhScript(script) && script === account.p2wpkh.scriptPubkey.toString('hex')) { - psbt.signInput(index, account.keyPair); - } - if (isP2trScript(script) && script === account.p2tr.scriptPubkey.toString('hex')) { - psbt.signInput(index, tweakedSigner); - } - } + // Sign inputs + signPsbt({ + psbt, + account, + finalizeInputs: true, }); - psbt.finalizeAllInputs(); expectPsbtFeeInRange(psbt, feeRate); const tx = psbt.extractTransaction(); From 4f59bb31693740c8774f384f77066af363f3848e Mon Sep 17 00:00:00 2001 From: Dylan Duan Date: Mon, 17 Jun 2024 09:16:54 +0800 Subject: [PATCH 73/90] feat: Support batch request for live cells --- packages/ckb/src/collector/collector.spec.ts | 30 ++++++++++++++++++++ packages/ckb/src/collector/index.ts | 7 +++++ 2 files changed, 37 insertions(+) create mode 100644 packages/ckb/src/collector/collector.spec.ts diff --git a/packages/ckb/src/collector/collector.spec.ts b/packages/ckb/src/collector/collector.spec.ts new file mode 100644 index 00000000..c4ec70bb --- /dev/null +++ b/packages/ckb/src/collector/collector.spec.ts @@ -0,0 +1,30 @@ +import { describe, it, expect } from 'vitest'; +import { Collector } from '.'; + +describe('collector', () => { + const collector = new Collector({ + ckbNodeUrl: 'https://testnet.ckb.dev/rpc', + ckbIndexerUrl: 'https://testnet.ckb.dev/indexer', + }); + + it('getLiveCells', async () => { + const cell = await collector.getLiveCell({ + txHash: '0xfa87db3187be8cf850117ccfcdfe2525c44f1a58f71d9714dd2ce489e9723182', + index: '0x0', + }); + expect(cell.output.lock.args).toBe('0x0450340178ae277261a838c89f9ccb76a190ed4b'); + }); + + it('getLiveCells', async () => { + const [cell1, cell2, cell3] = await collector.getLiveCells([ + // Cellbase + { txHash: '0xfa87db3187be8cf850117ccfcdfe2525c44f1a58f71d9714dd2ce489e9723182', index: '0x0' }, + { txHash: '0xed5adcba9bbbfe76c546264f2b8a33cbf9c95d09a88550bb0a4f98d6f36a6ed2', index: '0x0' }, + // Nervos DAO + { txHash: '0x8277d74d33850581f8d843613ded0c2a1722dec0e87e748f45c115dfb14210f1', index: '0x0' }, + ]); + expect(cell1.output.lock.args).toBe('0x0450340178ae277261a838c89f9ccb76a190ed4b'); + expect(cell2.output.lock.args).toBe('0xf1cbacc833b5c62f79ac8de6aa7ffbe464cae563'); + expect(cell3.output.type?.codeHash).toBe('0x82d76d1b75fe2fd9a27dfbaa65a039221a380d76c926f378d3f81cf3e7e13f2e'); + }); +}); diff --git a/packages/ckb/src/collector/index.ts b/packages/ckb/src/collector/index.ts index bd3ace31..aca6d505 100644 --- a/packages/ckb/src/collector/index.ts +++ b/packages/ckb/src/collector/index.ts @@ -166,4 +166,11 @@ export class Collector { const { cell } = await ckb.rpc.getLiveCell(outPoint, withData); return cell; } + + async getLiveCells(outPoints: CKBComponents.OutPoint[], withData = false): Promise { + const ckb = new CKB(this.ckbNodeUrl); + /* @ts-expect-error The parameters data types of batch request don't support boolean */ + const batch = ckb.rpc.createBatchRequest(outPoints.map((outPoint) => ['getLiveCell', outPoint, withData])); + return batch.exec().then((liveCells) => liveCells.map((liveCell) => liveCell.cell)); + } } From 89e263eca4b3617babaa3ad79d41431c14b721dc Mon Sep 17 00:00:00 2001 From: Dylan Duan Date: Mon, 17 Jun 2024 09:59:33 +0800 Subject: [PATCH 74/90] Update packages/ckb/src/collector/collector.spec.ts Co-authored-by: Flouse <1297478+Flouse@users.noreply.github.com> --- packages/ckb/src/collector/collector.spec.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/ckb/src/collector/collector.spec.ts b/packages/ckb/src/collector/collector.spec.ts index c4ec70bb..b71d3e66 100644 --- a/packages/ckb/src/collector/collector.spec.ts +++ b/packages/ckb/src/collector/collector.spec.ts @@ -7,7 +7,7 @@ describe('collector', () => { ckbIndexerUrl: 'https://testnet.ckb.dev/indexer', }); - it('getLiveCells', async () => { + it('getLiveCell', async () => { const cell = await collector.getLiveCell({ txHash: '0xfa87db3187be8cf850117ccfcdfe2525c44f1a58f71d9714dd2ce489e9723182', index: '0x0', From 11594ea58649a5840c685ea5e66d198f6cf2d9b4 Mon Sep 17 00:00:00 2001 From: Dylan Duan Date: Mon, 17 Jun 2024 15:25:26 +0800 Subject: [PATCH 75/90] docs: Add BTC Signet to readme and .env.example (#232) * docs: Add BTC Signet to readme and .env.example * docs: Use signet as default for BTC network * feat: Use signet as default for BTC network * docs: Update BTC testnet Assets API url --------- Co-authored-by: Flouse <1297478+Flouse@users.noreply.github.com> --- apps/service/.env.example | 21 ++++++++++++--------- apps/service/README.md | 23 +++++++++++++---------- examples/rgbpp/.env.example | 18 ++++++++++-------- examples/rgbpp/README.md | 18 ++++++++++-------- examples/xudt-on-ckb/.env.example | 4 ++-- examples/xudt-on-ckb/README.md | 4 ++-- packages/service/README.md | 8 ++++++-- 7 files changed, 55 insertions(+), 41 deletions(-) diff --git a/apps/service/.env.example b/apps/service/.env.example index 36c9d4d9..2e12085a 100644 --- a/apps/service/.env.example +++ b/apps/service/.env.example @@ -1,20 +1,23 @@ -# testnet for CKB and BTC Testnet and mainnet for CKB and BTC Mainnet, the default value is testnet +# The network includes testnet and mainnet, the default value is testnet NETWORK=testnet -# The Bitcoin Testnet type including Testnet3 and Signet, default value is Testnet3 +# The Bitcoin Testnet type including Testnet3 and Signet, default value is Signet # Testnet3: https://mempool.space/testnet # Signet: https://mempool.space/signet -BTC_TESTNET_TYPE=Testnet3 +BTC_TESTNET_TYPE=Signet -# CKB node url which should be matched with NETWORK +# CKB node url which should match NETWORK CKB_RPC_URL=https://testnet.ckb.dev -# The BTC assets api url which should be matched with NETWORK -BTC_SERVICE_URL=https://btc-assets-api.testnet.mibao.pro +# The BTC assets api url which should match NETWORK +# The BTC Testnet Service url is: https://api.testnet.rgbpp.io +# The BTC Signet Service url is: https://api.signet.rgbpp.io +BTC_SERVICE_URL=https://api.signet.rgbpp.io -# The BTC assets api token which should be matched with NETWORK and BTC_TESTNET_TYPE +# The BTC assets api token which should match NETWORK and BTC_TESTNET_TYPE # To get an access token, please refer to https://github.com/ckb-cell/rgbpp-sdk/tree/develop/packages/service#get-an-access-token BTC_SERVICE_TOKEN= -# The BTC assets api origin which should be matched with NETWORK and BTC_TESTNET_TYPE -BTC_SERVICE_ORIGIN=https://btc-assets-api.testnet.mibao.pro +# The BTC assets api origin which should match `BTC_SERVICE_TOKEN` +# JWT Debugger: https://jwt.io +BTC_SERVICE_ORIGIN=https://btc-test.app diff --git a/apps/service/README.md b/apps/service/README.md index e310ddaa..448e1948 100644 --- a/apps/service/README.md +++ b/apps/service/README.md @@ -23,26 +23,29 @@ $ cp .env.example .env Update the configuration values: ```yml -# testnet for CKB and BTC Testnet and mainnet for CKB and BTC Mainnet, the default value is testnet -NETWORK=testnet +# The network includes testnet and mainnet, the default value is testnet +NETWORK=testnet # or mainnet -# The Bitcoin Testnet type including Testnet3 and Signet, default value is Testnet3 +# The Bitcoin Testnet type includs Testnet3 and Signet, the default value is Signet # Testnet3: https://mempool.space/testnet # Signet: https://mempool.space/signet -BTC_TESTNET_TYPE=Testnet3 +BTC_TESTNET_TYPE=Signet -# CKB node url which should be matched with NETWORK +# CKB node url which should match NETWORK CKB_RPC_URL=https://testnet.ckb.dev -# The BTC assets api url which should be matched with NETWORK -BTC_SERVICE_URL=https://btc-assets-api.testnet.mibao.pro +# The BTC assets api url which should match NETWORK and BTC_TESTNET_TYPE +# The BTC Testnet Service url is: https://api.testnet.rgbpp.io +# The BTC Signet Service url is: https://api.signet.rgbpp.io +BTC_SERVICE_URL=hhttps://api.signet.rgbpp.io -# The BTC assets api token which should be matched with NETWORK and BTC_TESTNET_TYPE +# The BTC assets api token which should match NETWORK and BTC_TESTNET_TYPE # To get an access token, please refer to https://github.com/ckb-cell/rgbpp-sdk/tree/develop/packages/service#get-an-access-token BTC_SERVICE_TOKEN= -# The BTC assets api origin which should be matched with NETWORK and BTC_TESTNET_TYPE -BTC_SERVICE_ORIGIN=https://btc-assets-api.testnet.mibao.pro +# The BTC assets api origin which should match `BTC_SERVICE_TOKEN` +# JWT Debugger: https://jwt.io +BTC_SERVICE_ORIGIN=https://btc-test.app ``` ### Run RGB++ SDK Service diff --git a/examples/rgbpp/.env.example b/examples/rgbpp/.env.example index f80d7be1..1d402162 100644 --- a/examples/rgbpp/.env.example +++ b/examples/rgbpp/.env.example @@ -6,19 +6,19 @@ IS_MAINNET=false # The CKB secp256k1 private key whose format is 32bytes hex string with 0x prefix CKB_SECP256K1_PRIVATE_KEY=0x-private-key -# CKB node url which should be matched with IS_MAINNET +# CKB node url which should match IS_MAINNET CKB_NODE_URL=https://testnet.ckb.dev/rpc -# CKB indexer url which should be matched with IS_MAINNET +# CKB indexer url which should match IS_MAINNET CKB_INDEXER_URL=https://testnet.ckb.dev/indexer # BTC Variables -# The Bitcoin Testnet type including Testnet3 and Signet, default value is Testnet3 +# The Bitcoin Testnet type including Testnet3 and Signet, default value is Signet # Testnet3: https://mempool.space/testnet # Signet: https://mempool.space/signet -BTC_TESTNET_TYPE=Testnet3 +BTC_TESTNET_TYPE=Signet # The BTC private key whose format is 32bytes hex string without 0x prefix BTC_PRIVATE_KEY=private-key @@ -28,13 +28,15 @@ BTC_PRIVATE_KEY=private-key # Read more about P2WPKH in BIP141: https://github.com/bitcoin/bips/blob/master/bip-0141.mediawiki#p2wpkh BTC_ADDRESS_TYPE=P2WPKH -# The BTC assets api url which should be matched with IS_MAINNET and BTC_TESTNET_TYPE -VITE_BTC_SERVICE_URL=https://btc-assets-api.testnet.mibao.pro +# The BTC assets api url which should match IS_MAINNET and BTC_TESTNET_TYPE +# The BTC Testnet Service url is: https://api.testnet.rgbpp.io +# The BTC Signet Service url is: https://api.signet.rgbpp.io +VITE_BTC_SERVICE_URL=https://api.signet.rgbpp.io -# The BTC assets api token which should be matched with IS_MAINNET and BTC_TESTNET_TYPE +# The BTC assets api token which should match IS_MAINNET and BTC_TESTNET_TYPE # To get an access token, please refer to https://github.com/ckb-cell/rgbpp-sdk/tree/develop/packages/service#get-an-access-token VITE_BTC_SERVICE_TOKEN= -# The BTC assets api origin which should be matched with IS_MAINNET and BTC_TESTNET_TYPE +# The BTC assets api origin which should match IS_MAINNET and BTC_TESTNET_TYPE VITE_BTC_SERVICE_ORIGIN=https://btc-test.app diff --git a/examples/rgbpp/README.md b/examples/rgbpp/README.md index ca01c27a..e3f4847c 100644 --- a/examples/rgbpp/README.md +++ b/examples/rgbpp/README.md @@ -34,18 +34,18 @@ IS_MAINNET=false # The CKB secp256k1 private key whose format is 32bytes hex string with 0x prefix CKB_SECP256K1_PRIVATE_KEY=0x-private-key -# CKB node url which should be matched with IS_MAINNET +# CKB node url which should match IS_MAINNET CKB_NODE_URL=https://testnet.ckb.dev/rpc -# CKB indexer url which should be matched with IS_MAINNET +# CKB indexer url which should match IS_MAINNET CKB_INDEXER_URL=https://testnet.ckb.dev/indexer # BTC Variables -# The Bitcoin Testnet type including Testnet3 and Signet, default value is Testnet3 +# The Bitcoin Testnet type including Testnet3 and Signet, default value is Signet # Testnet3: https://mempool.space/testnet # Signet: https://mempool.space/signet -BTC_TESTNET_TYPE=Testnet3 +BTC_TESTNET_TYPE=Signet # The BTC private key whose format is 32bytes hex string without 0x prefix BTC_PRIVATE_KEY=private-key @@ -55,14 +55,16 @@ BTC_PRIVATE_KEY=private-key # Read more about P2WPKH in BIP141: https://github.com/bitcoin/bips/blob/master/bip-0141.mediawiki#p2wpkh BTC_ADDRESS_TYPE=P2WPKH -# The BTC assets api url which should be matched with IS_MAINNET -VITE_BTC_SERVICE_URL=https://btc-assets-api.testnet.mibao.pro +# The BTC assets api url which should match IS_MAINNET and BTC_TESTNET_TYPE +# The BTC Testnet Service url is: https://api.testnet.rgbpp.io +# The BTC Signet Service url is: https://api.signet.rgbpp.io +VITE_BTC_SERVICE_URL=https://api.signet.rgbpp.io -# The BTC assets api token which should be matched with IS_MAINNET +# The BTC assets api token which should match IS_MAINNET and BTC_TESTNET_TYPE # To get an access token, please refer to https://github.com/ckb-cell/rgbpp-sdk/tree/develop/packages/service#get-an-access-token VITE_BTC_SERVICE_TOKEN= -# The BTC assets api origin which should be matched with IS_MAINNET +# The BTC assets api origin which should match IS_MAINNET and BTC_TESTNET_TYPE VITE_BTC_SERVICE_ORIGIN=https://btc-test.app ``` diff --git a/examples/xudt-on-ckb/.env.example b/examples/xudt-on-ckb/.env.example index 3f2ce3bf..c99f8057 100644 --- a/examples/xudt-on-ckb/.env.example +++ b/examples/xudt-on-ckb/.env.example @@ -4,8 +4,8 @@ IS_MAINNET=false # The CKB secp256k1 private key whose format is 32bytes hex string with 0x prefix CKB_SECP256K1_PRIVATE_KEY=0x-private-key -# CKB node url which should be matched with IS_MAINNET +# CKB node url which should match IS_MAINNET CKB_NODE_URL=https://testnet.ckb.dev/rpc -# CKB indexer url which should be matched with IS_MAINNET +# CKB indexer url which should match IS_MAINNET CKB_INDEXER_URL=https://testnet.ckb.dev/indexer diff --git a/examples/xudt-on-ckb/README.md b/examples/xudt-on-ckb/README.md index 5e3d4afb..c0362fda 100644 --- a/examples/xudt-on-ckb/README.md +++ b/examples/xudt-on-ckb/README.md @@ -19,10 +19,10 @@ IS_MAINNET=false # The CKB secp256k1 private key whose format is 32bytes hex string with 0x prefix CKB_SECP256K1_PRIVATE_KEY=0x-private-key -# CKB node url which should be matched with IS_MAINNET +# CKB node url which should match IS_MAINNET CKB_NODE_URL=https://testnet.ckb.dev/rpc -# CKB indexer url which should be matched with IS_MAINNET +# CKB indexer url which should match IS_MAINNET CKB_INDEXER_URL=https://testnet.ckb.dev/indexer ``` diff --git a/packages/service/README.md b/packages/service/README.md index 8132bfe4..32f1368d 100644 --- a/packages/service/README.md +++ b/packages/service/README.md @@ -8,7 +8,7 @@ The `@rgbpp-sdk/service` package provides a wrapped class to interact with `Bitc - **Handle transactions** by posting to `/bitcoin/v1/transaction` or `/rgbpp/v1/transaction/ckb-tx` - **Generate Bitcoin transaction Proof** via `/rgbpp/v1/btc-spv/proof` through [Bitcoin SPV Service on CKB](https://github.com/ckb-cell/ckb-bitcoin-spv-service) - Simplify RGB++ assets workflows with **RGB++ CKB transaction Queue** and cron jobs -- More detailed API documentation can be found on [Testnet](https://btc-assets-api.testnet.mibao.pro/docs) and [Mainnet](https://api.rgbpp.io/docs) +- More detailed API documentation can be found on [Testnet](https://api.testnet.rgbpp.io/docs), [Signet](https://api.signet.rgbpp.io/docs) and [Mainnet](https://api.rgbpp.io/docs) > [!NOTE] > `Bitcoin/RGB++ Assets Service` is designed to streamline the transaction workflow. Developers have the option to implement its features by themselves without limitation. @@ -30,7 +30,11 @@ $ pnpm add @rgbpp-sdk/service #### Testnet -You can get a testnet access token through the [/token/generate](https://btc-assets-api.testnet.mibao.pro/docs/static/index.html#/Token/post_token_generate) API directly. +You can get a testnet access token through the [/token/generate](https://api.testnet.rgbpp.io/docs/static/index.html#/Token/post_token_generate) API directly. + +### Signet + +And you can get an access token of BTC Signet network through the [/token/generate](https://api.signet.rgbpp.io/docs/static/index.html#/Token/post_token_generate) API directly. #### Mainnet From 00ec297e275d1bcb73a2478039c87afce7e1050a Mon Sep 17 00:00:00 2001 From: Dylan Duan Date: Mon, 17 Jun 2024 15:47:39 +0800 Subject: [PATCH 76/90] feat: Add send_btc_transaction rpc to sdk service --- apps/service/src/rgbpp/rgbpp.service.ts | 16 +++++++++++++++- apps/service/src/rgbpp/types.ts | 4 ++++ 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/apps/service/src/rgbpp/rgbpp.service.ts b/apps/service/src/rgbpp/rgbpp.service.ts index 0de87937..ebc9ed72 100644 --- a/apps/service/src/rgbpp/rgbpp.service.ts +++ b/apps/service/src/rgbpp/rgbpp.service.ts @@ -2,7 +2,14 @@ import { Inject } from '@nestjs/common'; import { RpcHandler, RpcMethodHandler } from 'src/json-rpc/json-rpc.decorators'; import { DataSource, NetworkType } from 'rgbpp/btc'; import { BTCTestnetType, Collector, Hex, toCamelcase } from 'rgbpp/ckb'; -import { RgbppTransferReq, RgbppCkbBtcTransaction, RgbppCkbTxBtcTxId, RgbppStateReq, RgbppCkbTxHashReq } from './types'; +import { + RgbppTransferReq, + RgbppCkbBtcTransaction, + RgbppCkbTxBtcTxId, + RgbppStateReq, + RgbppCkbTxHashReq, + BtcTxSendReq, +} from './types'; import { toSnakeCase } from 'src/utils/snake'; import { buildRgbppTransferTx } from 'rgbpp'; import { BtcAssetsApi } from 'rgbpp/service'; @@ -70,4 +77,11 @@ export class RgbppService { const { txhash: txHash } = await this.btcAssetsApi.getRgbppTransactionHash(btcTxId); return txHash; } + + @RpcMethodHandler({ name: 'send_btc_transaction' }) + public async sendBtcTransaction(request: object[]): Promise { + const { txHex } = toCamelcase(request[0]); + const { txid } = await this.btcAssetsApi.sendBtcTransaction(txHex); + return txid; + } } diff --git a/apps/service/src/rgbpp/types.ts b/apps/service/src/rgbpp/types.ts index 34913bcd..b5da3f9e 100644 --- a/apps/service/src/rgbpp/types.ts +++ b/apps/service/src/rgbpp/types.ts @@ -37,3 +37,7 @@ export interface RgbppStateReq { export interface RgbppCkbTxHashReq { btcTxId: Hex; } + +export interface BtcTxSendReq { + txHex: Hex; +} From a708b3fe45f41a7870fb643ab26fd3c15adff4f5 Mon Sep 17 00:00:00 2001 From: Dawn <13477199767@163.com> Date: Mon, 17 Jun 2024 17:08:32 +0800 Subject: [PATCH 77/90] refactor: Refactor integration test cases --- .github/workflows/integration-test.yaml | 12 ++--- .github/workflows/test.yaml | 6 +-- tests/rgbpp/env.ts | 14 +++-- tests/rgbpp/shared/prepare-utxo.ts | 15 +++--- tests/rgbpp/spore/4-transfer-spore.ts | 21 ++++---- tests/rgbpp/spore/5-leap-spore-to-ckb.ts | 23 ++++---- tests/rgbpp/spore/launch/2-create-cluster.ts | 25 ++++----- tests/rgbpp/spore/launch/3-create-spores.ts | 37 +++++-------- tests/rgbpp/xudt/2-btc-transfer.ts | 57 ++++++++++---------- tests/rgbpp/xudt/3-btc-leap-ckb.ts | 22 ++++---- 10 files changed, 108 insertions(+), 124 deletions(-) diff --git a/.github/workflows/integration-test.yaml b/.github/workflows/integration-test.yaml index 82011340..13c30285 100644 --- a/.github/workflows/integration-test.yaml +++ b/.github/workflows/integration-test.yaml @@ -49,9 +49,9 @@ jobs: if: ${{ matrix.env_set == 'xudt' }} run: pnpm run integration:xudt env: - VITE_SERVICE_URL: ${{ secrets.SERVICE_URL }} - VITE_SERVICE_TOKEN: ${{ secrets.SERVICE_TOKEN }} - VITE_SERVICE_ORIGIN: ${{ secrets.SERVICE_ORIGIN }} + VITE_SERVICE_URL: https://api.signet.rgbpp.io + VITE_SERVICE_TOKEN: ${{ secrets.SIGNET_SERVICE_TOKEN }} + VITE_SERVICE_ORIGIN: https://api.signet.rgbpp.io INTEGRATION_CKB_PRIVATE_KEY: ${{ secrets.INTEGRATION_CKB_PRIVATE_KEY }} INTEGRATION_BTC_PRIVATE_KEY: ${{ secrets.INTEGRATION_BTC_PRIVATE_KEY }} @@ -60,8 +60,8 @@ jobs: if: ${{ matrix.env_set == 'spore' }} run: pnpm run integration:spore env: - VITE_SERVICE_URL: ${{ secrets.SERVICE_URL }} - VITE_SERVICE_TOKEN: ${{ secrets.SERVICE_TOKEN }} - VITE_SERVICE_ORIGIN: ${{ secrets.SERVICE_ORIGIN }} + VITE_SERVICE_URL: https://api.signet.rgbpp.io + VITE_SERVICE_TOKEN: ${{ secrets.SIGNET_SERVICE_TOKEN }} + VITE_SERVICE_ORIGIN: https://api.signet.rgbpp.io INTEGRATION_CKB_PRIVATE_KEY: ${{ secrets.INTEGRATION_CKB_SPORE_PRIVATE_KEY }} INTEGRATION_BTC_PRIVATE_KEY: ${{ secrets.INTEGRATION_BTC_SPORE_PRIVATE_KEY }} diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index 07d120a6..b3c412f2 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -52,6 +52,6 @@ jobs: - name: Run tests for packages run: pnpm run test:packages env: - VITE_BTC_SERVICE_URL: ${{ secrets.SERVICE_URL }} - VITE_BTC_SERVICE_TOKEN: ${{ secrets.SERVICE_TOKEN }} - VITE_BTC_SERVICE_ORIGIN: ${{ secrets.SERVICE_ORIGIN }} + VITE_BTC_SERVICE_URL: https://api.signet.rgbpp.io + VITE_BTC_SERVICE_TOKEN: ${{ secrets.SIGNET_SERVICE_TOKEN }} + VITE_BTC_SERVICE_ORIGIN: https://api.signet.rgbpp.io diff --git a/tests/rgbpp/env.ts b/tests/rgbpp/env.ts index e65e8a27..e78e809a 100644 --- a/tests/rgbpp/env.ts +++ b/tests/rgbpp/env.ts @@ -1,12 +1,14 @@ import { AddressPrefix, privateKeyToAddress } from '@nervosnetwork/ckb-sdk-utils'; -import { DataSource, BtcAssetsApi } from 'rgbpp'; +import { DataSource, BtcAssetsApi, AddressType } from 'rgbpp'; import { ECPair, ECPairInterface, bitcoin, NetworkType } from 'rgbpp/btc'; import dotenv from 'dotenv'; import { Collector } from 'rgbpp/ckb'; +import { createBtcAccount } from '../../examples/rgbpp/shared/btc-account'; dotenv.config({ path: __dirname + '/.env' }); export const isMainnet = false; +export const BTC_TESTNET_TYPE = 'Signet'; export const collector = new Collector({ ckbNodeUrl: 'https://testnet.ckb.dev/rpc', @@ -24,11 +26,13 @@ export const BTC_SERVICE_ORIGIN = process.env.VITE_SERVICE_ORIGIN!; const network = isMainnet ? bitcoin.networks.bitcoin : bitcoin.networks.testnet; export const btcKeyPair: ECPairInterface = ECPair.fromPrivateKey(Buffer.from(BTC_PRIVATE_KEY, 'hex'), { network }); -export const { address: btcAddress } = bitcoin.payments.p2wpkh({ - pubkey: btcKeyPair.publicKey, - network, -}); +// Read more about the available address types: +// - P2WPKH: https://github.com/bitcoin/bips/blob/master/bip-0141.mediawiki#p2wpkh +// - P2TR: https://github.com/bitcoin/bips/blob/master/bip-0341.mediawiki +const addressType = AddressType.P2WPKH; const networkType = isMainnet ? NetworkType.MAINNET : NetworkType.TESTNET; +export const btcAccount = createBtcAccount(BTC_PRIVATE_KEY, addressType, networkType); + export const btcService = BtcAssetsApi.fromToken(BTC_SERVICE_URL, BTC_SERVICE_TOKEN, BTC_SERVICE_ORIGIN); export const btcDataSource = new DataSource(btcService, networkType); diff --git a/tests/rgbpp/shared/prepare-utxo.ts b/tests/rgbpp/shared/prepare-utxo.ts index a10c9e4c..12ac11cf 100644 --- a/tests/rgbpp/shared/prepare-utxo.ts +++ b/tests/rgbpp/shared/prepare-utxo.ts @@ -1,24 +1,23 @@ import { sendBtc } from 'rgbpp/btc'; -import { getFastestFeeRate, writeStepLog } from './utils'; +import { writeStepLog } from './utils'; import { BtcAssetsApiError } from 'rgbpp/service'; -import { btcAddress, btcDataSource, btcKeyPair, btcService } from '../env'; +import { btcAccount, btcDataSource, btcKeyPair, btcService } from '../env'; const prepareUtxo = async (index: string | number) => { - const feeRate = await getFastestFeeRate(); - console.log('feeRate = ', feeRate); - console.log(btcAddress); + const address = btcAccount.toString(); + console.log(address); // Send BTC tx const psbt = await sendBtc({ - from: btcAddress!, + from: address!, tos: [ { - address: btcAddress!, + address: address!, value: 546, minUtxoSatoshi: 546, }, ], - feeRate: feeRate, + feeRate: 1, source: btcDataSource, }); diff --git a/tests/rgbpp/spore/4-transfer-spore.ts b/tests/rgbpp/spore/4-transfer-spore.ts index 30d53c0a..c99cf9e3 100644 --- a/tests/rgbpp/spore/4-transfer-spore.ts +++ b/tests/rgbpp/spore/4-transfer-spore.ts @@ -2,9 +2,11 @@ import { buildRgbppLockArgs } from 'rgbpp/ckb'; import { genTransferSporeCkbVirtualTx, sendRgbppUtxos } from 'rgbpp'; import { getSporeTypeScript, Hex } from 'rgbpp/ckb'; import { serializeScript } from '@nervosnetwork/ckb-sdk-utils'; -import { isMainnet, collector, btcAddress, btcDataSource, btcKeyPair, btcService } from '../env'; -import { getFastestFeeRate, readStepLog } from '../shared/utils'; +import { isMainnet, collector, btcDataSource, btcService, btcAccount } from '../env'; +import { readStepLog } from '../shared/utils'; import { saveCkbVirtualTxResult } from '../../../examples/rgbpp/shared/utils'; +import { BTC_TESTNET_TYPE } from '../../../examples/rgbpp/env'; +import { signAndSendPsbt } from '../../../examples/rgbpp/shared/btc-account'; interface SporeTransferParams { sporeRgbppLockArgs: Hex; @@ -20,14 +22,12 @@ const transferSpore = async ({ sporeRgbppLockArgs, toBtcAddress, sporeTypeArgs } args: sporeTypeArgs, }); - const feeRate = await getFastestFeeRate(); - console.log('feeRate = ', feeRate); - const ckbVirtualTxResult = await genTransferSporeCkbVirtualTx({ collector, sporeRgbppLockArgs, sporeTypeBytes, isMainnet, + btcTestnetType: BTC_TESTNET_TYPE, }); // Save ckbVirtualTxResult @@ -42,16 +42,13 @@ const transferSpore = async ({ sporeRgbppLockArgs, toBtcAddress, sporeTypeArgs } tos: [toBtcAddress], needPaymaster: needPaymasterCell, ckbCollector: collector, - from: btcAddress!, + from: btcAccount.from, + fromPubkey: btcAccount.fromPubkey, source: btcDataSource, - feeRate: feeRate, + feeRate: 1, }); - psbt.signAllInputs(btcKeyPair); - psbt.finalizeAllInputs(); - - const btcTx = psbt.extractTransaction(); - const { txid: btcTxId } = await btcService.sendBtcTransaction(btcTx.toHex()); + const { txId: btcTxId } = await signAndSendPsbt(psbt, btcAccount, btcService); console.log('BTC TxId: ', btcTxId); console.log(`explorer: https://mempool.space/testnet/tx/${btcTxId}`); diff --git a/tests/rgbpp/spore/5-leap-spore-to-ckb.ts b/tests/rgbpp/spore/5-leap-spore-to-ckb.ts index 6346c088..fc36708f 100644 --- a/tests/rgbpp/spore/5-leap-spore-to-ckb.ts +++ b/tests/rgbpp/spore/5-leap-spore-to-ckb.ts @@ -2,9 +2,11 @@ import { buildRgbppLockArgs } from 'rgbpp/ckb'; import { genLeapSporeFromBtcToCkbVirtualTx, sendRgbppUtxos } from 'rgbpp'; import { getSporeTypeScript, Hex } from 'rgbpp/ckb'; import { serializeScript } from '@nervosnetwork/ckb-sdk-utils'; -import { isMainnet, collector, btcAddress, btcDataSource, btcKeyPair, btcService } from '../env'; -import { getFastestFeeRate, readStepLog } from '../shared/utils'; +import { isMainnet, collector, btcDataSource, btcService, btcAccount } from '../env'; +import { readStepLog } from '../shared/utils'; import { saveCkbVirtualTxResult } from '../../../examples/rgbpp/shared/utils'; +import { BTC_TESTNET_TYPE } from '../../../examples/rgbpp/env'; +import { signAndSendPsbt } from '../../../examples/rgbpp/shared/btc-account'; interface SporeLeapParams { sporeRgbppLockArgs: Hex; @@ -20,15 +22,13 @@ const leapSporeFromBtcToCkb = async ({ sporeRgbppLockArgs, toCkbAddress, sporeTy args: sporeTypeArgs, }); - const feeRate = await getFastestFeeRate(); - console.log('feeRate = ', feeRate); - const ckbVirtualTxResult = await genLeapSporeFromBtcToCkbVirtualTx({ collector, sporeRgbppLockArgs, sporeTypeBytes, toCkbAddress, isMainnet, + btcTestnetType: BTC_TESTNET_TYPE, }); // Save ckbVirtualTxResult @@ -40,19 +40,16 @@ const leapSporeFromBtcToCkb = async ({ sporeRgbppLockArgs, toCkbAddress, sporeTy const psbt = await sendRgbppUtxos({ ckbVirtualTx: ckbRawTx, commitment, - tos: [btcAddress!], + tos: [btcAccount.from], needPaymaster: needPaymasterCell, ckbCollector: collector, - from: btcAddress!, + from: btcAccount.from, + fromPubkey: btcAccount.fromPubkey, source: btcDataSource, - feeRate: feeRate, + feeRate: 1, }); - psbt.signAllInputs(btcKeyPair); - psbt.finalizeAllInputs(); - - const btcTx = psbt.extractTransaction(); - const { txid: btcTxId } = await btcService.sendBtcTransaction(btcTx.toHex()); + const { txId: btcTxId } = await signAndSendPsbt(psbt, btcAccount, btcService); console.log('BTC TxId: ', btcTxId); console.log(`explorer: https://mempool.space/testnet/tx/${btcTxId}`); diff --git a/tests/rgbpp/spore/launch/2-create-cluster.ts b/tests/rgbpp/spore/launch/2-create-cluster.ts index 4e5d9fe8..4e4dc697 100644 --- a/tests/rgbpp/spore/launch/2-create-cluster.ts +++ b/tests/rgbpp/spore/launch/2-create-cluster.ts @@ -1,7 +1,6 @@ import { BtcAssetsApiError, genCreateClusterCkbVirtualTx, sendRgbppUtxos } from 'rgbpp'; -import { isMainnet, collector, btcAddress, btcDataSource, btcKeyPair, btcService } from '../../env'; +import { isMainnet, collector, btcDataSource, btcService, btcAccount, BTC_TESTNET_TYPE } from '../../env'; import { CLUSTER_DATA } from './0-cluster-info'; -import { transactionToHex } from 'rgbpp/btc'; import { appendCkbTxWitnesses, buildRgbppLockArgs, @@ -9,23 +8,22 @@ import { sendCkbTx, updateCkbTxWithRealBtcTxId, } from 'rgbpp/ckb'; -import { getFastestFeeRate, readStepLog, writeStepLog } from '../../shared/utils'; +import { readStepLog, writeStepLog } from '../../shared/utils'; import { saveCkbVirtualTxResult } from '../../../../examples/rgbpp/shared/utils'; +import { signAndSendPsbt } from '../../../../examples/rgbpp/shared/btc-account'; // Warning: Before runing this file, please run 1-prepare-cluster.ts const createCluster = async ({ ownerRgbppLockArgs }: { ownerRgbppLockArgs: string }) => { - console.log(btcAddress); + console.log(btcAccount); const { retry } = await import('zx'); await retry(20, '10s', async () => { - const feeRate = await getFastestFeeRate(); - console.log('feeRate = ', feeRate); - const ckbVirtualTxResult = await genCreateClusterCkbVirtualTx({ collector, rgbppLockArgs: ownerRgbppLockArgs, clusterData: CLUSTER_DATA, isMainnet, ckbFeeRate: BigInt(2000), + btcTestnetType: BTC_TESTNET_TYPE, }); // Save ckbVirtualTxResult @@ -42,19 +40,16 @@ const createCluster = async ({ ownerRgbppLockArgs }: { ownerRgbppLockArgs: strin const psbt = await sendRgbppUtxos({ ckbVirtualTx: ckbRawTx, commitment, - tos: [btcAddress!], + tos: [btcAccount.from], needPaymaster: needPaymasterCell, ckbCollector: collector, - from: btcAddress!, + from: btcAccount.from, + fromPubkey: btcAccount.fromPubkey, source: btcDataSource, - feeRate: feeRate, + feeRate: 1, }); - psbt.signAllInputs(btcKeyPair); - psbt.finalizeAllInputs(); - const btcTx = psbt.extractTransaction(); - const btcTxBytes = transactionToHex(btcTx, false); - const { txid: btcTxId } = await btcService.sendBtcTransaction(btcTx.toHex()); + const { txId: btcTxId, rawTxHex: btcTxBytes } = await signAndSendPsbt(psbt, btcAccount, btcService); writeStepLog('create-cluster-id', { txid: btcTxId, diff --git a/tests/rgbpp/spore/launch/3-create-spores.ts b/tests/rgbpp/spore/launch/3-create-spores.ts index 9f180407..35cac3af 100644 --- a/tests/rgbpp/spore/launch/3-create-spores.ts +++ b/tests/rgbpp/spore/launch/3-create-spores.ts @@ -1,14 +1,5 @@ import { BtcAssetsApiError, genCreateSporeCkbVirtualTx, sendRgbppUtxos } from 'rgbpp'; -import { - isMainnet, - collector, - btcAddress, - btcDataSource, - btcKeyPair, - btcService, - CKB_PRIVATE_KEY, - ckbAddress, -} from '../../env'; +import { isMainnet, collector, btcDataSource, btcService, CKB_PRIVATE_KEY, ckbAddress } from '../../env'; import { Hex, appendCkbTxWitnesses, @@ -19,9 +10,11 @@ import { updateCkbTxWithRealBtcTxId, RawSporeData, } from 'rgbpp/ckb'; -import { transactionToHex, utf8ToBuffer } from 'rgbpp/btc'; -import { getFastestFeeRate, readStepLog, writeStepLog } from '../../shared/utils'; +import { utf8ToBuffer } from 'rgbpp/btc'; +import { readStepLog, writeStepLog } from '../../shared/utils'; import { saveCkbVirtualTxResult } from '../../../../examples/rgbpp/shared/utils'; +import { BTC_TESTNET_TYPE, btcAccount } from '../../../../examples/rgbpp/env'; +import { signAndSendPsbt } from '../../../../examples/rgbpp/shared/btc-account'; interface SporeCreateParams { clusterRgbppLockArgs: Hex; @@ -35,15 +28,13 @@ interface SporeCreateParams { const createSpores = async ({ clusterRgbppLockArgs, receivers }: SporeCreateParams) => { const { retry } = await import('zx'); await retry(20, '10s', async () => { - const feeRate = await getFastestFeeRate(); - console.log('feeRate = ', feeRate); - const ckbVirtualTxResult = await genCreateSporeCkbVirtualTx({ collector, sporeDataList: receivers.map((receiver) => receiver.sporeData), clusterRgbppLockArgs, isMainnet, ckbFeeRate: BigInt(2000), + btcTestnetType: BTC_TESTNET_TYPE, }); // Save ckbVirtualTxResult @@ -53,23 +44,20 @@ const createSpores = async ({ clusterRgbppLockArgs, receivers }: SporeCreatePara // Send BTC tx // The first btc address is the owner of the cluster cell and the rest btc addresses are spore receivers - const btcTos = [btcAddress!, ...receivers.map((receiver) => receiver.toBtcAddress)]; + const btcTos = [btcAccount.from, ...receivers.map((receiver) => receiver.toBtcAddress)]; const psbt = await sendRgbppUtxos({ ckbVirtualTx: ckbRawTx, commitment, tos: btcTos, needPaymaster: needPaymasterCell, ckbCollector: collector, - from: btcAddress!, + from: btcAccount.from, + fromPubkey: btcAccount.fromPubkey, source: btcDataSource, - feeRate: feeRate, + feeRate: 1, }); - psbt.signAllInputs(btcKeyPair); - psbt.finalizeAllInputs(); - const btcTx = psbt.extractTransaction(); - const btcTxBytes = transactionToHex(btcTx, false); - const { txid: btcTxId } = await btcService.sendBtcTransaction(btcTx.toHex()); + const { txId: btcTxId, rawTxHex: btcTxBytes } = await signAndSendPsbt(psbt, btcAccount, btcService); writeStepLog('create-spores-id', { txid: btcTxId, @@ -131,6 +119,9 @@ const createSpores = async ({ clusterRgbppLockArgs, receivers }: SporeCreatePara }; // Please use your real BTC UTXO information on the BTC Testnet +// BTC Testnet3: https://mempool.space/testnet +// BTC Signet: https://mempool.space/signet + // rgbppLockArgs: outIndexU32 + btcTxId createSpores({ // The cluster cell will be spent and the new cluster cell will be created in each spore creation tx, diff --git a/tests/rgbpp/xudt/2-btc-transfer.ts b/tests/rgbpp/xudt/2-btc-transfer.ts index d1f7a7ff..272d9b7a 100644 --- a/tests/rgbpp/xudt/2-btc-transfer.ts +++ b/tests/rgbpp/xudt/2-btc-transfer.ts @@ -1,8 +1,11 @@ -import { buildRgbppLockArgs, getXudtTypeScript } from 'rgbpp/ckb'; -import { serializeScript } from '@nervosnetwork/ckb-sdk-utils'; -import { genBtcTransferCkbVirtualTx, sendRgbppUtxos } from 'rgbpp'; -import { isMainnet, collector, btcAddress, btcKeyPair, btcService, btcDataSource } from '../env'; +import { buildRgbppLockArgs } from 'rgbpp/ckb'; +import { buildRgbppTransferTx } from 'rgbpp'; +import { isMainnet, collector, btcService, btcDataSource } from '../env'; import { readStepLog, writeStepLog } from '../shared/utils'; +import { BTC_TESTNET_TYPE, btcAccount } from '../env'; +import { saveCkbVirtualTxResult } from '../../../examples/rgbpp/shared/utils'; +import { bitcoin } from 'rgbpp/btc'; +import { signAndSendPsbt } from '../../../examples/rgbpp/shared/btc-account'; interface RgbppTransferParams { rgbppLockArgsList: string[]; @@ -14,37 +17,31 @@ interface RgbppTransferParams { const transfer = async ({ rgbppLockArgsList, toBtcAddress, xudtTypeArgs, transferAmount }: RgbppTransferParams) => { const { retry } = await import('zx'); await retry(120, '10s', async () => { - const xudtType: CKBComponents.Script = { - ...getXudtTypeScript(isMainnet), - args: xudtTypeArgs, - }; - - const ckbVirtualTxResult = await genBtcTransferCkbVirtualTx({ - collector, - rgbppLockArgsList, - xudtTypeBytes: serializeScript(xudtType), - transferAmount, + const { ckbVirtualTxResult, btcPsbtHex } = await buildRgbppTransferTx({ + ckb: { + collector, + xudtTypeArgs, + rgbppLockArgsList, + transferAmount, + }, + btc: { + fromAddress: btcAccount.from, + toAddress: toBtcAddress, + fromPubkey: btcAccount.fromPubkey, + dataSource: btcDataSource, + testnetType: BTC_TESTNET_TYPE, + feeRate: 1, + }, isMainnet, }); - const { commitment, ckbRawTx } = ckbVirtualTxResult; + // Save ckbVirtualTxResult + saveCkbVirtualTxResult(ckbVirtualTxResult, '2-btc-transfer'); // Send BTC tx - const psbt = await sendRgbppUtxos({ - ckbVirtualTx: ckbRawTx, - commitment, - tos: [toBtcAddress], - ckbCollector: collector, - from: btcAddress!, - source: btcDataSource, - }); - psbt.signAllInputs(btcKeyPair); - psbt.finalizeAllInputs(); - - const btcTx = psbt.extractTransaction(); - const { txid: btcTxId } = await btcService.sendBtcTransaction(btcTx.toHex()); - - console.log('BTC TxId: ', btcTxId); + const psbt = bitcoin.Psbt.fromHex(btcPsbtHex); + const { txId: btcTxId } = await signAndSendPsbt(psbt, btcAccount, btcService); + console.log(`BTC ${BTC_TESTNET_TYPE} TxId: ${btcTxId}`); console.log(`explorer: https://mempool.space/testnet/tx/${btcTxId}`); writeStepLog('transfer-id', { diff --git a/tests/rgbpp/xudt/3-btc-leap-ckb.ts b/tests/rgbpp/xudt/3-btc-leap-ckb.ts index 5f2c752f..e7e66bf4 100644 --- a/tests/rgbpp/xudt/3-btc-leap-ckb.ts +++ b/tests/rgbpp/xudt/3-btc-leap-ckb.ts @@ -1,8 +1,10 @@ import { buildRgbppLockArgs, getXudtTypeScript } from 'rgbpp/ckb'; import { serializeScript } from '@nervosnetwork/ckb-sdk-utils'; import { genBtcJumpCkbVirtualTx, sendRgbppUtxos } from 'rgbpp'; -import { isMainnet, collector, btcAddress, btcKeyPair, btcService, btcDataSource } from '../env'; +import { isMainnet, collector, btcService, btcDataSource, btcAccount, BTC_TESTNET_TYPE } from '../env'; import { readStepLog } from '../shared/utils'; +import { saveCkbVirtualTxResult } from '../../../examples/rgbpp/shared/utils'; +import { signAndSendPsbt } from '../../../examples/rgbpp/shared/btc-account'; interface LeapToCkbParams { rgbppLockArgsList: string[]; @@ -26,26 +28,28 @@ const leapFromBtcToCKB = async ({ rgbppLockArgsList, toCkbAddress, xudtTypeArgs, transferAmount, toCkbAddress, isMainnet, + btcTestnetType: BTC_TESTNET_TYPE, }); + // Save ckbVirtualTxResult + saveCkbVirtualTxResult(ckbVirtualTxResult, '3-btc-leap-ckb'); + const { commitment, ckbRawTx } = ckbVirtualTxResult; // Send BTC tx const psbt = await sendRgbppUtxos({ ckbVirtualTx: ckbRawTx, commitment, - tos: [btcAddress!], + tos: [btcAccount.from], ckbCollector: collector, - from: btcAddress!, + from: btcAccount.from, + fromPubkey: btcAccount.fromPubkey, source: btcDataSource, + feeRate: 1, }); - psbt.signAllInputs(btcKeyPair); - psbt.finalizeAllInputs(); - - const btcTx = psbt.extractTransaction(); - const { txid: btcTxId } = await btcService.sendBtcTransaction(btcTx.toHex()); - console.log('BTC TxId: ', btcTxId); + const { txId: btcTxId } = await signAndSendPsbt(psbt, btcAccount, btcService); + console.log(`BTC ${BTC_TESTNET_TYPE} TxId: ${btcTxId}`); console.log(`explorer: https://mempool.space/testnet/tx/${btcTxId}`); await btcService.sendRgbppCkbTransaction({ btc_txid: btcTxId, ckb_virtual_result: ckbVirtualTxResult }); From f27cd8e3faeced5a5a2e1741556d99a52cf788a3 Mon Sep 17 00:00:00 2001 From: Dawn <13477199767@163.com> Date: Mon, 17 Jun 2024 17:22:11 +0800 Subject: [PATCH 78/90] fix: Fix the error in obtaining the address in the integration test --- .github/workflows/integration-test.yaml | 1 - tests/rgbpp/shared/prepare-utxo.ts | 7 +++---- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/.github/workflows/integration-test.yaml b/.github/workflows/integration-test.yaml index 13c30285..43b3dbf4 100644 --- a/.github/workflows/integration-test.yaml +++ b/.github/workflows/integration-test.yaml @@ -4,7 +4,6 @@ name: Integration Tests on: workflow_dispatch: - pull_request: # Run integration-tests every day schedule: - cron: '59 0 * * *' diff --git a/tests/rgbpp/shared/prepare-utxo.ts b/tests/rgbpp/shared/prepare-utxo.ts index 12ac11cf..b9f0b456 100644 --- a/tests/rgbpp/shared/prepare-utxo.ts +++ b/tests/rgbpp/shared/prepare-utxo.ts @@ -4,15 +4,14 @@ import { BtcAssetsApiError } from 'rgbpp/service'; import { btcAccount, btcDataSource, btcKeyPair, btcService } from '../env'; const prepareUtxo = async (index: string | number) => { - const address = btcAccount.toString(); - console.log(address); + console.log(btcAccount.from); // Send BTC tx const psbt = await sendBtc({ - from: address!, + from: btcAccount.from!, tos: [ { - address: address!, + address: btcAccount.from!, value: 546, minUtxoSatoshi: 546, }, From add545149382c145605daee57f5ec5a44da60b8f Mon Sep 17 00:00:00 2001 From: Dawn <13477199767@163.com> Date: Mon, 17 Jun 2024 17:40:36 +0800 Subject: [PATCH 79/90] chore: Modify output messages --- .github/workflows/integration-test.yaml | 1 + .github/workflows/test.yaml | 6 +++--- tests/rgbpp/shared/prepare-utxo.ts | 2 +- tests/rgbpp/spore/4-transfer-spore.ts | 2 +- tests/rgbpp/spore/5-leap-spore-to-ckb.ts | 2 +- tests/rgbpp/spore/launch/2-create-cluster.ts | 2 +- tests/rgbpp/spore/launch/3-create-spores.ts | 2 +- tests/rgbpp/xudt/2-btc-transfer.ts | 2 +- tests/rgbpp/xudt/3-btc-leap-ckb.ts | 2 +- 9 files changed, 11 insertions(+), 10 deletions(-) diff --git a/.github/workflows/integration-test.yaml b/.github/workflows/integration-test.yaml index 43b3dbf4..13c30285 100644 --- a/.github/workflows/integration-test.yaml +++ b/.github/workflows/integration-test.yaml @@ -4,6 +4,7 @@ name: Integration Tests on: workflow_dispatch: + pull_request: # Run integration-tests every day schedule: - cron: '59 0 * * *' diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index b3c412f2..62c7d695 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -52,6 +52,6 @@ jobs: - name: Run tests for packages run: pnpm run test:packages env: - VITE_BTC_SERVICE_URL: https://api.signet.rgbpp.io - VITE_BTC_SERVICE_TOKEN: ${{ secrets.SIGNET_SERVICE_TOKEN }} - VITE_BTC_SERVICE_ORIGIN: https://api.signet.rgbpp.io + VITE_BTC_SERVICE_URL: https://btc-assets-api.testnet.mibao.pro + VITE_BTC_SERVICE_TOKEN: ${{ secrets.TESTNET_SERVICE_TOKEN }} + VITE_BTC_SERVICE_ORIGIN: https://btc-assets-api.testnet.mibao.pro diff --git a/tests/rgbpp/shared/prepare-utxo.ts b/tests/rgbpp/shared/prepare-utxo.ts index b9f0b456..5ac8b17a 100644 --- a/tests/rgbpp/shared/prepare-utxo.ts +++ b/tests/rgbpp/shared/prepare-utxo.ts @@ -29,7 +29,7 @@ const prepareUtxo = async (index: string | number) => { console.log(tx.toHex()); const { txid: btcTxId } = await btcService.sendBtcTransaction(tx.toHex()); - console.log(`explorer: https://mempool.space/testnet/tx/${btcTxId}`); + console.log(`explorer: https://mempool.space/signet/tx/${btcTxId}`); writeStepLog(String(index), { txid: btcTxId, diff --git a/tests/rgbpp/spore/4-transfer-spore.ts b/tests/rgbpp/spore/4-transfer-spore.ts index c99cf9e3..8a74e82a 100644 --- a/tests/rgbpp/spore/4-transfer-spore.ts +++ b/tests/rgbpp/spore/4-transfer-spore.ts @@ -50,7 +50,7 @@ const transferSpore = async ({ sporeRgbppLockArgs, toBtcAddress, sporeTypeArgs } const { txId: btcTxId } = await signAndSendPsbt(psbt, btcAccount, btcService); console.log('BTC TxId: ', btcTxId); - console.log(`explorer: https://mempool.space/testnet/tx/${btcTxId}`); + console.log(`explorer: https://mempool.space/signet/tx/${btcTxId}`); await btcService.sendRgbppCkbTransaction({ btc_txid: btcTxId, ckb_virtual_result: ckbVirtualTxResult }); diff --git a/tests/rgbpp/spore/5-leap-spore-to-ckb.ts b/tests/rgbpp/spore/5-leap-spore-to-ckb.ts index fc36708f..0a4e9e09 100644 --- a/tests/rgbpp/spore/5-leap-spore-to-ckb.ts +++ b/tests/rgbpp/spore/5-leap-spore-to-ckb.ts @@ -51,7 +51,7 @@ const leapSporeFromBtcToCkb = async ({ sporeRgbppLockArgs, toCkbAddress, sporeTy const { txId: btcTxId } = await signAndSendPsbt(psbt, btcAccount, btcService); console.log('BTC TxId: ', btcTxId); - console.log(`explorer: https://mempool.space/testnet/tx/${btcTxId}`); + console.log(`explorer: https://mempool.space/signet/tx/${btcTxId}`); await btcService.sendRgbppCkbTransaction({ btc_txid: btcTxId, ckb_virtual_result: ckbVirtualTxResult }); diff --git a/tests/rgbpp/spore/launch/2-create-cluster.ts b/tests/rgbpp/spore/launch/2-create-cluster.ts index 4e4dc697..136d9371 100644 --- a/tests/rgbpp/spore/launch/2-create-cluster.ts +++ b/tests/rgbpp/spore/launch/2-create-cluster.ts @@ -56,7 +56,7 @@ const createCluster = async ({ ownerRgbppLockArgs }: { ownerRgbppLockArgs: strin index: 1, }); console.log('BTC TxId: ', btcTxId); - console.log(`explorer: https://mempool.space/testnet/tx/${btcTxId}`); + console.log(`explorer: https://mempool.space/signet/tx/${btcTxId}`); const interval = setInterval(async () => { try { diff --git a/tests/rgbpp/spore/launch/3-create-spores.ts b/tests/rgbpp/spore/launch/3-create-spores.ts index 35cac3af..21daf795 100644 --- a/tests/rgbpp/spore/launch/3-create-spores.ts +++ b/tests/rgbpp/spore/launch/3-create-spores.ts @@ -63,7 +63,7 @@ const createSpores = async ({ clusterRgbppLockArgs, receivers }: SporeCreatePara txid: btcTxId, }); console.log('BTC TxId: ', btcTxId); - console.log(`explorer: https://mempool.space/testnet/tx/${btcTxId}`); + console.log(`explorer: https://mempool.space/signet/tx/${btcTxId}`); const interval = setInterval(async () => { try { diff --git a/tests/rgbpp/xudt/2-btc-transfer.ts b/tests/rgbpp/xudt/2-btc-transfer.ts index 272d9b7a..f71a3779 100644 --- a/tests/rgbpp/xudt/2-btc-transfer.ts +++ b/tests/rgbpp/xudt/2-btc-transfer.ts @@ -42,7 +42,7 @@ const transfer = async ({ rgbppLockArgsList, toBtcAddress, xudtTypeArgs, transfe const psbt = bitcoin.Psbt.fromHex(btcPsbtHex); const { txId: btcTxId } = await signAndSendPsbt(psbt, btcAccount, btcService); console.log(`BTC ${BTC_TESTNET_TYPE} TxId: ${btcTxId}`); - console.log(`explorer: https://mempool.space/testnet/tx/${btcTxId}`); + console.log(`explorer: https://mempool.space/signet/tx/${btcTxId}`); writeStepLog('transfer-id', { txid: btcTxId, diff --git a/tests/rgbpp/xudt/3-btc-leap-ckb.ts b/tests/rgbpp/xudt/3-btc-leap-ckb.ts index e7e66bf4..7d16fc5b 100644 --- a/tests/rgbpp/xudt/3-btc-leap-ckb.ts +++ b/tests/rgbpp/xudt/3-btc-leap-ckb.ts @@ -50,7 +50,7 @@ const leapFromBtcToCKB = async ({ rgbppLockArgsList, toCkbAddress, xudtTypeArgs, const { txId: btcTxId } = await signAndSendPsbt(psbt, btcAccount, btcService); console.log(`BTC ${BTC_TESTNET_TYPE} TxId: ${btcTxId}`); - console.log(`explorer: https://mempool.space/testnet/tx/${btcTxId}`); + console.log(`explorer: https://mempool.space/signet/tx/${btcTxId}`); await btcService.sendRgbppCkbTransaction({ btc_txid: btcTxId, ckb_virtual_result: ckbVirtualTxResult }); From 240c68e6957a5fdcdaaf6ce891375b87d6b0c8ee Mon Sep 17 00:00:00 2001 From: Dawn <13477199767@163.com> Date: Mon, 17 Jun 2024 23:13:51 +0800 Subject: [PATCH 80/90] fix: Resolve issue of no RGBPP cells found with the RGBPP lock args --- tests/rgbpp/env.ts | 32 ++++++++++++------- tests/rgbpp/spore/launch/1-prepare-cluster.ts | 4 +-- tests/rgbpp/spore/launch/2-create-cluster.ts | 2 +- 3 files changed, 24 insertions(+), 14 deletions(-) diff --git a/tests/rgbpp/env.ts b/tests/rgbpp/env.ts index e78e809a..8479a062 100644 --- a/tests/rgbpp/env.ts +++ b/tests/rgbpp/env.ts @@ -1,28 +1,38 @@ -import { AddressPrefix, privateKeyToAddress } from '@nervosnetwork/ckb-sdk-utils'; +import { + blake160, + bytesToHex, + privateKeyToPublicKey, + scriptToAddress, + systemScripts, +} from '@nervosnetwork/ckb-sdk-utils'; import { DataSource, BtcAssetsApi, AddressType } from 'rgbpp'; import { ECPair, ECPairInterface, bitcoin, NetworkType } from 'rgbpp/btc'; import dotenv from 'dotenv'; -import { Collector } from 'rgbpp/ckb'; +import { BTCTestnetType, Collector } from 'rgbpp/ckb'; import { createBtcAccount } from '../../examples/rgbpp/shared/btc-account'; dotenv.config({ path: __dirname + '/.env' }); export const isMainnet = false; -export const BTC_TESTNET_TYPE = 'Signet'; +// export const BTC_TESTNET_TYPE = 'Signet'; +export const BTC_TESTNET_TYPE = process.env.BTC_TESTNET_TYPE! as BTCTestnetType; export const collector = new Collector({ ckbNodeUrl: 'https://testnet.ckb.dev/rpc', ckbIndexerUrl: 'https://testnet.ckb.dev/indexer', }); -export const CKB_PRIVATE_KEY = process.env.INTEGRATION_CKB_PRIVATE_KEY!; -export const ckbAddress = privateKeyToAddress(CKB_PRIVATE_KEY, { - prefix: isMainnet ? AddressPrefix.Mainnet : AddressPrefix.Testnet, -}); +export const CKB_PRIVATE_KEY = '0x469cc5b62555090f376866fe3fe780339104cfdcf5011e7d887d71bb99ca2e2b'; +const secp256k1Lock: CKBComponents.Script = { + ...systemScripts.SECP256K1_BLAKE160, + args: bytesToHex(blake160(privateKeyToPublicKey(CKB_PRIVATE_KEY))), +}; +export const ckbAddress = scriptToAddress(secp256k1Lock, isMainnet); -export const BTC_PRIVATE_KEY = process.env.INTEGRATION_BTC_PRIVATE_KEY!; -export const BTC_SERVICE_URL = process.env.VITE_SERVICE_URL!; -export const BTC_SERVICE_TOKEN = process.env.VITE_SERVICE_TOKEN!; -export const BTC_SERVICE_ORIGIN = process.env.VITE_SERVICE_ORIGIN!; +export const BTC_PRIVATE_KEY = '5c213d9478a310fcf9fb4a973d1b4a7592769b4bccbda335b5c1886a3929a00b'; +export const BTC_SERVICE_URL = 'https://api.signet.rgbpp.io'; +export const BTC_SERVICE_TOKEN = + 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJteS1hcHAiLCJhdWQiOiJhcGkuc2lnbmV0LnJnYnBwLmlvIiwianRpIjoiZWJkMGJlNGYtZTZlNS00M2M4LTlmMmMtNGUwYjk3YWM1ZjVkIiwiaWF0IjoxNzE4NTk1Mzg2fQ.8Q35BzMYHNHS0Fqe_4coALnIsBDVUm3Ro-zF6SN83PM'; +export const BTC_SERVICE_ORIGIN = 'https://api.signet.rgbpp.io'; const network = isMainnet ? bitcoin.networks.bitcoin : bitcoin.networks.testnet; export const btcKeyPair: ECPairInterface = ECPair.fromPrivateKey(Buffer.from(BTC_PRIVATE_KEY, 'hex'), { network }); diff --git a/tests/rgbpp/spore/launch/1-prepare-cluster.ts b/tests/rgbpp/spore/launch/1-prepare-cluster.ts index 76636543..d1e70d91 100644 --- a/tests/rgbpp/spore/launch/1-prepare-cluster.ts +++ b/tests/rgbpp/spore/launch/1-prepare-cluster.ts @@ -10,7 +10,7 @@ import { genRgbppLockScript, getSecp256k1CellDep, } from 'rgbpp/ckb'; -import { ckbAddress, isMainnet, collector, CKB_PRIVATE_KEY } from '../../env'; +import { ckbAddress, isMainnet, collector, CKB_PRIVATE_KEY, BTC_TESTNET_TYPE } from '../../env'; import { CLUSTER_DATA } from './0-cluster-info'; import { readStepLog } from '../../shared/utils'; @@ -36,7 +36,7 @@ const prepareClusterCell = async ({ outIndex, btcTxId }: { outIndex: number; btc const outputs: CKBComponents.CellOutput[] = [ { - lock: genRgbppLockScript(buildRgbppLockArgs(outIndex, btcTxId), isMainnet), + lock: genRgbppLockScript(buildRgbppLockArgs(outIndex, btcTxId), isMainnet, BTC_TESTNET_TYPE), capacity: append0x(clusterCellCapacity.toString(16)), }, ]; diff --git a/tests/rgbpp/spore/launch/2-create-cluster.ts b/tests/rgbpp/spore/launch/2-create-cluster.ts index 136d9371..e398e52e 100644 --- a/tests/rgbpp/spore/launch/2-create-cluster.ts +++ b/tests/rgbpp/spore/launch/2-create-cluster.ts @@ -14,7 +14,7 @@ import { signAndSendPsbt } from '../../../../examples/rgbpp/shared/btc-account'; // Warning: Before runing this file, please run 1-prepare-cluster.ts const createCluster = async ({ ownerRgbppLockArgs }: { ownerRgbppLockArgs: string }) => { - console.log(btcAccount); + console.log(btcAccount.from); const { retry } = await import('zx'); await retry(20, '10s', async () => { const ckbVirtualTxResult = await genCreateClusterCkbVirtualTx({ From 4efd9d24e85c00d0e647564f1e094075acdca969 Mon Sep 17 00:00:00 2001 From: Dawn <13477199767@163.com> Date: Mon, 17 Jun 2024 23:22:16 +0800 Subject: [PATCH 81/90] chore: Set BTC_TESTNET_TYPE to default to signet --- .github/workflows/integration-test.yaml | 1 - tests/rgbpp/env.ts | 6 +++--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/.github/workflows/integration-test.yaml b/.github/workflows/integration-test.yaml index 13c30285..43b3dbf4 100644 --- a/.github/workflows/integration-test.yaml +++ b/.github/workflows/integration-test.yaml @@ -4,7 +4,6 @@ name: Integration Tests on: workflow_dispatch: - pull_request: # Run integration-tests every day schedule: - cron: '59 0 * * *' diff --git a/tests/rgbpp/env.ts b/tests/rgbpp/env.ts index 8479a062..51144335 100644 --- a/tests/rgbpp/env.ts +++ b/tests/rgbpp/env.ts @@ -8,14 +8,14 @@ import { import { DataSource, BtcAssetsApi, AddressType } from 'rgbpp'; import { ECPair, ECPairInterface, bitcoin, NetworkType } from 'rgbpp/btc'; import dotenv from 'dotenv'; -import { BTCTestnetType, Collector } from 'rgbpp/ckb'; +import { Collector } from 'rgbpp/ckb'; import { createBtcAccount } from '../../examples/rgbpp/shared/btc-account'; dotenv.config({ path: __dirname + '/.env' }); export const isMainnet = false; -// export const BTC_TESTNET_TYPE = 'Signet'; -export const BTC_TESTNET_TYPE = process.env.BTC_TESTNET_TYPE! as BTCTestnetType; + +export const BTC_TESTNET_TYPE = 'Signet'; export const collector = new Collector({ ckbNodeUrl: 'https://testnet.ckb.dev/rpc', From a4dbb33480df5b2f91f7e3ba65d5cc3be581120c Mon Sep 17 00:00:00 2001 From: Dawn <13477199767@163.com> Date: Tue, 18 Jun 2024 00:24:34 +0800 Subject: [PATCH 82/90] fix: Fix the problem that Private key cannot be read --- tests/rgbpp/env.ts | 11 +++++------ tests/rgbpp/spore/4-transfer-spore.ts | 3 +-- tests/rgbpp/spore/5-leap-spore-to-ckb.ts | 3 +-- tests/rgbpp/spore/launch/3-create-spores.ts | 2 +- tests/rgbpp/xudt/2-btc-transfer.ts | 3 +-- 5 files changed, 9 insertions(+), 13 deletions(-) diff --git a/tests/rgbpp/env.ts b/tests/rgbpp/env.ts index 51144335..6a4ba5f7 100644 --- a/tests/rgbpp/env.ts +++ b/tests/rgbpp/env.ts @@ -21,18 +21,17 @@ export const collector = new Collector({ ckbNodeUrl: 'https://testnet.ckb.dev/rpc', ckbIndexerUrl: 'https://testnet.ckb.dev/indexer', }); -export const CKB_PRIVATE_KEY = '0x469cc5b62555090f376866fe3fe780339104cfdcf5011e7d887d71bb99ca2e2b'; +export const CKB_PRIVATE_KEY = process.env.INTEGRATION_CKB_PRIVATE_KEY!; const secp256k1Lock: CKBComponents.Script = { ...systemScripts.SECP256K1_BLAKE160, args: bytesToHex(blake160(privateKeyToPublicKey(CKB_PRIVATE_KEY))), }; export const ckbAddress = scriptToAddress(secp256k1Lock, isMainnet); -export const BTC_PRIVATE_KEY = '5c213d9478a310fcf9fb4a973d1b4a7592769b4bccbda335b5c1886a3929a00b'; -export const BTC_SERVICE_URL = 'https://api.signet.rgbpp.io'; -export const BTC_SERVICE_TOKEN = - 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJteS1hcHAiLCJhdWQiOiJhcGkuc2lnbmV0LnJnYnBwLmlvIiwianRpIjoiZWJkMGJlNGYtZTZlNS00M2M4LTlmMmMtNGUwYjk3YWM1ZjVkIiwiaWF0IjoxNzE4NTk1Mzg2fQ.8Q35BzMYHNHS0Fqe_4coALnIsBDVUm3Ro-zF6SN83PM'; -export const BTC_SERVICE_ORIGIN = 'https://api.signet.rgbpp.io'; +export const BTC_PRIVATE_KEY = process.env.INTEGRATION_BTC_PRIVATE_KEY!; +export const BTC_SERVICE_URL = process.env.VITE_SERVICE_URL!; +export const BTC_SERVICE_TOKEN = process.env.VITE_SERVICE_TOKEN!; +export const BTC_SERVICE_ORIGIN = process.env.VITE_SERVICE_ORIGIN!; const network = isMainnet ? bitcoin.networks.bitcoin : bitcoin.networks.testnet; export const btcKeyPair: ECPairInterface = ECPair.fromPrivateKey(Buffer.from(BTC_PRIVATE_KEY, 'hex'), { network }); diff --git a/tests/rgbpp/spore/4-transfer-spore.ts b/tests/rgbpp/spore/4-transfer-spore.ts index 8a74e82a..d0b16d4a 100644 --- a/tests/rgbpp/spore/4-transfer-spore.ts +++ b/tests/rgbpp/spore/4-transfer-spore.ts @@ -2,10 +2,9 @@ import { buildRgbppLockArgs } from 'rgbpp/ckb'; import { genTransferSporeCkbVirtualTx, sendRgbppUtxos } from 'rgbpp'; import { getSporeTypeScript, Hex } from 'rgbpp/ckb'; import { serializeScript } from '@nervosnetwork/ckb-sdk-utils'; -import { isMainnet, collector, btcDataSource, btcService, btcAccount } from '../env'; +import { isMainnet, collector, btcDataSource, btcService, btcAccount, BTC_TESTNET_TYPE } from '../env'; import { readStepLog } from '../shared/utils'; import { saveCkbVirtualTxResult } from '../../../examples/rgbpp/shared/utils'; -import { BTC_TESTNET_TYPE } from '../../../examples/rgbpp/env'; import { signAndSendPsbt } from '../../../examples/rgbpp/shared/btc-account'; interface SporeTransferParams { diff --git a/tests/rgbpp/spore/5-leap-spore-to-ckb.ts b/tests/rgbpp/spore/5-leap-spore-to-ckb.ts index 0a4e9e09..5600d681 100644 --- a/tests/rgbpp/spore/5-leap-spore-to-ckb.ts +++ b/tests/rgbpp/spore/5-leap-spore-to-ckb.ts @@ -2,10 +2,9 @@ import { buildRgbppLockArgs } from 'rgbpp/ckb'; import { genLeapSporeFromBtcToCkbVirtualTx, sendRgbppUtxos } from 'rgbpp'; import { getSporeTypeScript, Hex } from 'rgbpp/ckb'; import { serializeScript } from '@nervosnetwork/ckb-sdk-utils'; -import { isMainnet, collector, btcDataSource, btcService, btcAccount } from '../env'; +import { isMainnet, collector, btcDataSource, btcService, btcAccount, BTC_TESTNET_TYPE } from '../env'; import { readStepLog } from '../shared/utils'; import { saveCkbVirtualTxResult } from '../../../examples/rgbpp/shared/utils'; -import { BTC_TESTNET_TYPE } from '../../../examples/rgbpp/env'; import { signAndSendPsbt } from '../../../examples/rgbpp/shared/btc-account'; interface SporeLeapParams { diff --git a/tests/rgbpp/spore/launch/3-create-spores.ts b/tests/rgbpp/spore/launch/3-create-spores.ts index 21daf795..61efe851 100644 --- a/tests/rgbpp/spore/launch/3-create-spores.ts +++ b/tests/rgbpp/spore/launch/3-create-spores.ts @@ -13,7 +13,7 @@ import { import { utf8ToBuffer } from 'rgbpp/btc'; import { readStepLog, writeStepLog } from '../../shared/utils'; import { saveCkbVirtualTxResult } from '../../../../examples/rgbpp/shared/utils'; -import { BTC_TESTNET_TYPE, btcAccount } from '../../../../examples/rgbpp/env'; +import { BTC_TESTNET_TYPE, btcAccount } from '../../env'; import { signAndSendPsbt } from '../../../../examples/rgbpp/shared/btc-account'; interface SporeCreateParams { diff --git a/tests/rgbpp/xudt/2-btc-transfer.ts b/tests/rgbpp/xudt/2-btc-transfer.ts index f71a3779..c0f656bf 100644 --- a/tests/rgbpp/xudt/2-btc-transfer.ts +++ b/tests/rgbpp/xudt/2-btc-transfer.ts @@ -1,8 +1,7 @@ import { buildRgbppLockArgs } from 'rgbpp/ckb'; import { buildRgbppTransferTx } from 'rgbpp'; -import { isMainnet, collector, btcService, btcDataSource } from '../env'; +import { isMainnet, collector, btcService, btcDataSource, BTC_TESTNET_TYPE, btcAccount } from '../env'; import { readStepLog, writeStepLog } from '../shared/utils'; -import { BTC_TESTNET_TYPE, btcAccount } from '../env'; import { saveCkbVirtualTxResult } from '../../../examples/rgbpp/shared/utils'; import { bitcoin } from 'rgbpp/btc'; import { signAndSendPsbt } from '../../../examples/rgbpp/shared/btc-account'; From 775e36a8f81e6cd00e189b5929ed1541e374b7db Mon Sep 17 00:00:00 2001 From: Dawn <13477199767@163.com> Date: Tue, 18 Jun 2024 01:28:42 +0800 Subject: [PATCH 83/90] fix: Resolve integration:xudt test failure issue --- tests/rgbpp/xudt/1-ckb-leap-btc.ts | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/tests/rgbpp/xudt/1-ckb-leap-btc.ts b/tests/rgbpp/xudt/1-ckb-leap-btc.ts index 340e02b4..6c3ed6a6 100644 --- a/tests/rgbpp/xudt/1-ckb-leap-btc.ts +++ b/tests/rgbpp/xudt/1-ckb-leap-btc.ts @@ -1,7 +1,7 @@ import { serializeScript } from '@nervosnetwork/ckb-sdk-utils'; import { genCkbJumpBtcVirtualTx } from 'rgbpp'; import { getSecp256k1CellDep, buildRgbppLockArgs, getXudtTypeScript } from 'rgbpp/ckb'; -import { CKB_PRIVATE_KEY, isMainnet, collector, ckbAddress } from '../env'; +import { CKB_PRIVATE_KEY, isMainnet, collector, ckbAddress, BTC_TESTNET_TYPE } from '../env'; import { readStepLog } from '../shared/utils'; interface LeapToBtcParams { @@ -28,19 +28,20 @@ const leapFromCkbToBtc = async ({ outIndex, btcTxId, xudtTypeArgs, transferAmoun toRgbppLockArgs, xudtTypeBytes: serializeScript(xudtType), transferAmount, + btcTestnetType: BTC_TESTNET_TYPE, }); const emptyWitness = { lock: '', inputType: '', outputType: '' }; const unsignedTx: CKBComponents.RawTransactionToSign = { ...ckbRawTx, - cellDeps: [...ckbRawTx.cellDeps, getSecp256k1CellDep(false)], + cellDeps: [...ckbRawTx.cellDeps, getSecp256k1CellDep(isMainnet)], witnesses: [emptyWitness, ...ckbRawTx.witnesses.slice(1)], }; const signedTx = collector.getCkb().signTransaction(CKB_PRIVATE_KEY)(unsignedTx); const txHash = await collector.getCkb().rpc.sendTransaction(signedTx, 'passthrough'); - console.info(`Rgbpp asset has been jumped from CKB to BTC and tx hash is ${txHash}`); + console.info(`Rgbpp asset has been jumped from CKB to BTC and CKB tx hash is ${txHash}`); console.info(`explorer: https://pudge.explorer.nervos.org/transaction/${txHash}`); }); }; From af42947ecbbc305953933ce1184e76bde246efb6 Mon Sep 17 00:00:00 2001 From: Shook Date: Tue, 18 Jun 2024 11:06:57 +0800 Subject: [PATCH 84/90] refactor: add a type proxy AddressToPubkeyMap of the pubkeyMap prop in Builder APIs --- packages/btc/src/address.ts | 9 ++++++++- packages/btc/src/api/sendRbf.ts | 3 ++- packages/btc/src/api/sendRgbppUtxos.ts | 3 ++- packages/btc/src/api/sendUtxos.ts | 4 ++-- packages/btc/src/transaction/utxo.ts | 6 +++--- 5 files changed, 17 insertions(+), 8 deletions(-) diff --git a/packages/btc/src/address.ts b/packages/btc/src/address.ts index 659d2ebd..311b5c3b 100644 --- a/packages/btc/src/address.ts +++ b/packages/btc/src/address.ts @@ -14,6 +14,13 @@ export enum AddressType { UNKNOWN, } +/** + * Type: Record + * + * The map of address and pubkey, usually for recognizing the P2TR inputs in the transaction. + */ +export type AddressToPubkeyMap = Record; + /** * Check weather the address is supported as a from address. * Currently, only P2WPKH and P2TR addresses are supported. @@ -215,7 +222,7 @@ function getAddressTypeDust(addressType: AddressType) { * Add address/pubkey pair to a Record map */ export function addAddressToPubkeyMap( - pubkeyMap: Record, + pubkeyMap: AddressToPubkeyMap, address: string, pubkey?: string, ): Record { diff --git a/packages/btc/src/api/sendRbf.ts b/packages/btc/src/api/sendRbf.ts index 0e84e16b..e629a49c 100644 --- a/packages/btc/src/api/sendRbf.ts +++ b/packages/btc/src/api/sendRbf.ts @@ -1,5 +1,6 @@ import { BaseOutput, Utxo } from '../transaction/utxo'; import { DataSource } from '../query/source'; +import { AddressToPubkeyMap } from '../address'; import { ErrorCodes, TxBuildError } from '../error'; import { InitOutput, TxBuilder } from '../transaction/build'; import { isOpReturnScriptPubkey } from '../transaction/embed'; @@ -22,7 +23,7 @@ export interface SendRbfProps { requireGreaterFeeAndRate?: boolean; // EXPERIMENTAL: the below props are unstable and can be altered at any time - pubkeyMap?: Record; // Record + pubkeyMap?: AddressToPubkeyMap; } export async function createSendRbfBuilder(props: SendRbfProps): Promise<{ diff --git a/packages/btc/src/api/sendRgbppUtxos.ts b/packages/btc/src/api/sendRgbppUtxos.ts index f793e5b0..f75f018e 100644 --- a/packages/btc/src/api/sendRgbppUtxos.ts +++ b/packages/btc/src/api/sendRgbppUtxos.ts @@ -2,6 +2,7 @@ import { Collector, checkCkbTxInputsCapacitySufficient } from '@rgbpp-sdk/ckb'; import { isRgbppLockCell, isBtcTimeLockCell, calculateCommitment } from '@rgbpp-sdk/ckb'; import { bitcoin } from '../bitcoin'; import { BaseOutput, Utxo } from '../transaction/utxo'; +import { AddressToPubkeyMap } from '../address'; import { DataSource } from '../query/source'; import { NetworkType } from '../preset/types'; import { ErrorCodes, TxBuildError } from '../error'; @@ -31,7 +32,7 @@ export interface SendRgbppUtxosProps { excludeUtxos?: BaseOutput[]; // EXPERIMENTAL: the below props are unstable and can be altered at any time - pubkeyMap?: Record; // Record + pubkeyMap?: AddressToPubkeyMap; } /** diff --git a/packages/btc/src/api/sendUtxos.ts b/packages/btc/src/api/sendUtxos.ts index ad5f44e8..4e225d93 100644 --- a/packages/btc/src/api/sendUtxos.ts +++ b/packages/btc/src/api/sendUtxos.ts @@ -2,7 +2,7 @@ import { bitcoin } from '../bitcoin'; import { DataSource } from '../query/source'; import { TxBuilder, InitOutput } from '../transaction/build'; import { BaseOutput, Utxo, prepareUtxoInputs } from '../transaction/utxo'; -import { addAddressToPubkeyMap } from '../address'; +import { AddressToPubkeyMap, addAddressToPubkeyMap } from '../address'; export interface SendUtxosProps { inputs: Utxo[]; @@ -18,7 +18,7 @@ export interface SendUtxosProps { // EXPERIMENTAL: the below props are unstable and can be altered at any time skipInputsValidation?: boolean; - pubkeyMap?: Record; // Record + pubkeyMap?: AddressToPubkeyMap; } export async function createSendUtxosBuilder(props: SendUtxosProps): Promise<{ diff --git a/packages/btc/src/transaction/utxo.ts b/packages/btc/src/transaction/utxo.ts index d0af8c18..7efae0f0 100644 --- a/packages/btc/src/transaction/utxo.ts +++ b/packages/btc/src/transaction/utxo.ts @@ -1,7 +1,7 @@ import cloneDeep from 'lodash/cloneDeep'; import { ErrorCodes, TxBuildError } from '../error'; import { DataSource } from '../query/source'; -import { AddressType } from '../address'; +import { AddressType, AddressToPubkeyMap } from '../address'; import { TxInput } from './build'; import { limitPromiseBatchSize, remove0x, toXOnly } from '../utils'; import { isP2trScript } from '../script'; @@ -65,7 +65,7 @@ export function utxoToInput(utxo: Utxo): TxInput { */ export function fillUtxoPubkey( utxo: Utxo, - pubkeyMap: Record, // Record + pubkeyMap: AddressToPubkeyMap, options?: { requirePubkey?: boolean; }, @@ -94,7 +94,7 @@ export async function prepareUtxoInputs(props: { source: DataSource; requirePubkey?: boolean; requireConfirmed?: boolean; - pubkeyMap?: Record; // Record + pubkeyMap?: AddressToPubkeyMap; }): Promise { const pubkeyMap = props.pubkeyMap ?? {}; const utxos = props.utxos.map((utxo) => { From 2e61e730894fd8d1ff7a254a8547494c8f5269ae Mon Sep 17 00:00:00 2001 From: Shook Date: Tue, 18 Jun 2024 11:24:20 +0800 Subject: [PATCH 85/90] docs: update btc README for pubkeyMap --- packages/btc/README.md | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/packages/btc/README.md b/packages/btc/README.md index 351f565b..f06877f8 100644 --- a/packages/btc/README.md +++ b/packages/btc/README.md @@ -312,6 +312,7 @@ interface SendUtxosProps { // EXPERIMENTAL: the below props are unstable and can be altered at any time skipInputsValidation?: boolean; + pubkeyMap?: AddressToPubkeyMap; } ``` @@ -352,7 +353,7 @@ interface SendRgbppUtxosProps { excludeUtxos?: BaseOutput[]; // EXPERIMENTAL: the below props are experimental and can be altered at any time - onlyProvableUtxos?: boolean; + pubkeyMap?: AddressToPubkeyMap; } ``` @@ -386,7 +387,7 @@ interface SendRbfProps { requireGreaterFeeAndRate?: boolean; // EXPERIMENTAL: the below props are experimental and can be altered at any time - inputsPubkey?: Record; // Record + pubkeyMap?: AddressToPubkeyMap; } ``` @@ -513,3 +514,9 @@ enum NetworkType { REGTEST, } ``` + +#### AddressToPubkeyMap + +```typescript +type AddressToPubkeyMap = Record; +``` From bdf5d8790149a52518cc111bc728e2e15ac5b773 Mon Sep 17 00:00:00 2001 From: Dylan Duan Date: Tue, 18 Jun 2024 19:15:51 +0800 Subject: [PATCH 86/90] refactor: Remove useless queue types --- packages/ckb/src/types/queue.ts | 24 ------------------------ 1 file changed, 24 deletions(-) delete mode 100644 packages/ckb/src/types/queue.ts diff --git a/packages/ckb/src/types/queue.ts b/packages/ckb/src/types/queue.ts deleted file mode 100644 index edcb9a73..00000000 --- a/packages/ckb/src/types/queue.ts +++ /dev/null @@ -1,24 +0,0 @@ -import { Hex } from './common'; -import { BaseCkbVirtualTxResult } from './rgbpp'; - -export interface AppendRgppTxRequest { - txid: Hex; - ckbVirtualResult: BaseCkbVirtualTxResult; -} - -export interface AppendRgppTxResp { - state: string; -} - -/** - * completed: The CKB transaction has been sent and confirmed. - * failed: Something went wrong during the process, and it has failed. - * delayed: The transaction has not been confirmed yet and is waiting for confirmation. - * active: The transaction is currently being processed. - * waiting: The transaction is pending and is waiting to be processed. - */ -export type RgbppTxState = 'completed' | 'failed' | 'delayed' | 'active' | 'waiting'; -export interface CheckRgppTxResp { - ckbTxHash: string; - state: RgbppTxState; -} From be8132c1397782deb70598760f8240e1f1507ff2 Mon Sep 17 00:00:00 2001 From: Dylan Duan Date: Tue, 18 Jun 2024 19:16:16 +0800 Subject: [PATCH 87/90] docs: Fix typo --- packages/ckb/README.md | 10 +++++----- packages/ckb/src/rgbpp/btc-time.ts | 4 ++-- packages/ckb/src/rgbpp/btc-transfer.ts | 6 +++--- packages/ckb/src/rgbpp/ckb-builder.ts | 2 +- packages/ckb/src/rgbpp/launch.ts | 2 +- packages/ckb/src/spore/cluster.ts | 2 +- packages/ckb/src/spore/leap.ts | 6 +++--- packages/ckb/src/spore/spore.ts | 6 +++--- packages/ckb/src/types/index.ts | 1 - packages/ckb/src/types/rgbpp.ts | 16 ++++++++-------- packages/ckb/src/types/spore.ts | 12 ++++++------ packages/rgbpp/src/rgbpp/types.ts | 2 +- packages/rgbpp/src/rgbpp/xudt.ts | 4 ++-- 13 files changed, 36 insertions(+), 37 deletions(-) diff --git a/packages/ckb/README.md b/packages/ckb/README.md index 9ac2bccd..dba33a13 100644 --- a/packages/ckb/README.md +++ b/packages/ckb/README.md @@ -46,7 +46,7 @@ export interface BtcTransferVirtualTxResult { * @param xudtTypeBytes The serialized hex string of the XUDT type script * @param rgbppLockArgsList The rgbpp assets cell lock script args array whose data structure is: out_index | bitcoin_tx_id * @param transferAmount The XUDT amount to be transferred, if the noMergeOutputCells is true, the transferAmount will be ignored - * @param isMainnet True is for BTC and CKB Mainnet, flase is for BTC and CKB Testnet(see btcTestnetType for details about BTC Testnet) + * @param isMainnet True is for BTC and CKB Mainnet, false is for BTC and CKB Testnet(see btcTestnetType for details about BTC Testnet) * @param witnessLockPlaceholderSize(Optional) The WitnessArgs.lock placeholder bytes array size and the default value is 5000 * @param noMergeOutputCells(Optional) The noMergeOutputCells indicates whether the CKB outputs need to be merged. By default, the outputs will be merged. * @param ckbFeeRate(Optional) The CKB transaction fee rate, default value is 1100 @@ -150,7 +150,7 @@ export interface SporeCreateVirtualTxResult { * @param collector The collector that collects CKB live cells and transactions * @param clusterRgbppLockArgs The cluster rgbpp cell lock script args whose data structure is: out_index | bitcoin_tx_id * @param sporeDataList The spore's data list, including name and description. - * @param isMainnet True is for BTC and CKB Mainnet, flase is for BTC and CKB Testnet(see btcTestnetType for details about BTC Testnet) + * @param isMainnet True is for BTC and CKB Mainnet, false is for BTC and CKB Testnet(see btcTestnetType for details about BTC Testnet) * @param btcTestnetType(Optional) The Bitcoin Testnet type including Testnet3 and Signet, default value is Testnet3 */ export const genCreateSporeCkbVirtualTx = async ({ @@ -185,7 +185,7 @@ export interface SporeTransferVirtualTxResult { * @param collector The collector that collects CKB live cells and transactions * @param sporeRgbppLockArgs The spore rgbpp cell lock script args whose data structure is: out_index | bitcoin_tx_id * @param sporeTypeBytes The spore type script serialized bytes - * @param isMainnet True is for BTC and CKB Mainnet, flase is for BTC and CKB Testnet(see btcTestnetType for details about BTC Testnet) + * @param isMainnet True is for BTC and CKB Mainnet, false is for BTC and CKB Testnet(see btcTestnetType for details about BTC Testnet) * @param witnessLockPlaceholderSize(Optional) The WitnessArgs.lock placeholder bytes array size and the default value is 5000 * @param ckbFeeRate(Optional) The CKB transaction fee rate, default value is 1100 * @param btcTestnetType(Optional) The Bitcoin Testnet type including Testnet3 and Signet, default value is Testnet3 @@ -225,7 +225,7 @@ export interface SporeLeapVirtualTxResult { * @param sporeRgbppLockArgs The spore rgbpp cell lock script args whose data structure is: out_index | bitcoin_tx_id * @param sporeTypeBytes The spore type script serialized bytes * @param toCkbAddress The receiver ckb address - * @param isMainnet True is for BTC and CKB Mainnet, flase is for BTC and CKB Testnet(see btcTestnetType for details about BTC Testnet) + * @param isMainnet True is for BTC and CKB Mainnet, false is for BTC and CKB Testnet(see btcTestnetType for details about BTC Testnet) * @param witnessLockPlaceholderSize(Optional) The WitnessArgs.lock placeholder bytes array size and the default value is 5000 * @param ckbFeeRate(Optional) The CKB transaction fee rate, default value is 1100 * @param btcTestnetType(Optional) The Bitcoin Testnet type including Testnet3 and Signet, default value is Testnet3 @@ -253,7 +253,7 @@ The method `genLeapSporeFromCkbToBtcRawTx` can generate a CKB transaction for RG * @param sporeRgbppLockArgs The spore rgbpp cell lock script args whose data structure is: out_index | bitcoin_tx_id * @param sporeTypeBytes The spore type script serialized bytes * @param toCkbAddress The receiver ckb address - * @param isMainnet True is for BTC and CKB Mainnet, flase is for BTC and CKB Testnet + * @param isMainnet True is for BTC and CKB Mainnet, false is for BTC and CKB Testnet * @param witnessLockPlaceholderSize(Optional) The WitnessArgs.lock placeholder bytes array size and the default value is 5000 * @param ckbFeeRate(Optional) The CKB transaction fee rate, default value is 1100 * @param btcTestnetType(Optional) The Bitcoin Testnet type including Testnet3 and Signet diff --git a/packages/ckb/src/rgbpp/btc-time.ts b/packages/ckb/src/rgbpp/btc-time.ts index a3707087..1c5c7c53 100644 --- a/packages/ckb/src/rgbpp/btc-time.ts +++ b/packages/ckb/src/rgbpp/btc-time.ts @@ -39,7 +39,7 @@ export const buildBtcTimeUnlockWitness = (btcTxProof: Hex): Hex => { * The btc time lock args data structure is: lock_script | after | new_bitcoin_tx_id * @param btcTimeCells The BTC time cells of xUDT * @param btcAssetsApi BTC Assets Api - * @param isMainnet True is for BTC and CKB Mainnet, flase is for BTC and CKB Testnet(see btcTestnetType for details about BTC Testnet) + * @param isMainnet True is for BTC and CKB Mainnet, false is for BTC and CKB Testnet(see btcTestnetType for details about BTC Testnet) * @param btcTestnetType(Optional) The Bitcoin Testnet type including Testnet3 and Signet, default value is Testnet3 */ export const buildBtcTimeCellsSpentTx = async ({ @@ -116,7 +116,7 @@ export const buildBtcTimeCellsSpentTx = async ({ * @param masterCkbAddress The master CKB address * @param outputCapacityRange(Optional) [u64; 2], filter cells by output capacity range, [inclusive, exclusive] * @param ckbFeeRate(Optional) The CKB transaction fee rate, default value is 1100 - * @param isMainnet True is for BTC and CKB Mainnet, flase is for BTC and CKB Testnet + * @param isMainnet True is for BTC and CKB Mainnet, false is for BTC and CKB Testnet */ export const signBtcTimeCellSpentTx = async ({ secp256k1PrivateKey, diff --git a/packages/ckb/src/rgbpp/btc-transfer.ts b/packages/ckb/src/rgbpp/btc-transfer.ts index de7db693..ff47d488 100644 --- a/packages/ckb/src/rgbpp/btc-transfer.ts +++ b/packages/ckb/src/rgbpp/btc-transfer.ts @@ -52,7 +52,7 @@ import signWitnesses from '@nervosnetwork/ckb-sdk-core/lib/signWitnesses'; * @param xudtTypeBytes The serialized hex string of the XUDT type script * @param rgbppLockArgsList The rgbpp assets cell lock script args array whose data structure is: out_index | bitcoin_tx_id * @param transferAmount The XUDT amount to be transferred, if the noMergeOutputCells is true, the transferAmount will be ignored - * @param isMainnet True is for BTC and CKB Mainnet, flase is for BTC and CKB Testnet(see btcTestnetType for details about BTC Testnet) + * @param isMainnet True is for BTC and CKB Mainnet, false is for BTC and CKB Testnet(see btcTestnetType for details about BTC Testnet) * @param noMergeOutputCells(Optional) The noMergeOutputCells indicates whether the CKB outputs need to be merged. By default, the outputs will be merged. * @param witnessLockPlaceholderSize(Optional) The WitnessArgs.lock placeholder bytes array size and the default value is 5000 * @param ckbFeeRate(Optional) The CKB transaction fee rate, default value is 1100 @@ -226,7 +226,7 @@ export const genBtcTransferCkbVirtualTx = async ({ * @param xudtTypeBytes The serialized hex string of the XUDT type script * @param rgbppLockArgsList The rgbpp assets cell lock script args array whose data structure is: out_index | bitcoin_tx_id * @param rgbppReceivers The rgbpp receiver list which include toBtcAddress and transferAmount - * @param isMainnet True is for BTC and CKB Mainnet, flase is for BTC and CKB Testnet(see btcTestnetType for details about BTC Testnet) + * @param isMainnet True is for BTC and CKB Mainnet, false is for BTC and CKB Testnet(see btcTestnetType for details about BTC Testnet) * @param btcTestnetType(Optional) The Bitcoin Testnet type including Testnet3 and Signet, default value is Testnet3 */ export const genBtcBatchTransferCkbVirtualTx = async ({ @@ -334,7 +334,7 @@ export const genBtcBatchTransferCkbVirtualTx = async ({ * @param collector The collector that collects CKB live cells and transactions * @param ckbRawTx CKB raw transaction * @param sumInputsCapacity The sum capacity of ckb inputs which is to be used to calculate ckb tx fee - * @param isMainnet True is for BTC and CKB Mainnet, flase is for BTC and CKB Testnet + * @param isMainnet True is for BTC and CKB Mainnet, false is for BTC and CKB Testnet * @param ckbFeeRate The CKB transaction fee rate, default value is 1100 */ export const appendIssuerCellToBtcBatchTransfer = async ({ diff --git a/packages/ckb/src/rgbpp/ckb-builder.ts b/packages/ckb/src/rgbpp/ckb-builder.ts index 82b39704..fe293511 100644 --- a/packages/ckb/src/rgbpp/ckb-builder.ts +++ b/packages/ckb/src/rgbpp/ckb-builder.ts @@ -154,7 +154,7 @@ export const sendCkbTx = async ({ collector, signedTx }: SendCkbTxParams) => { * Replace the RGBPP_TX_ID_PLACEHOLDER with the real btc tx id of the rgbpp lock args and BTC time lock args * @param ckbRawTx CKB raw transaction * @param btcTxId The BTC transaction id - * @param isMainnet True is for BTC and CKB Mainnet, flase is for BTC and CKB Testnet + * @param isMainnet True is for BTC and CKB Mainnet, false is for BTC and CKB Testnet */ export const updateCkbTxWithRealBtcTxId = ({ ckbRawTx, diff --git a/packages/ckb/src/rgbpp/launch.ts b/packages/ckb/src/rgbpp/launch.ts index 00adbf79..8542b5a6 100644 --- a/packages/ckb/src/rgbpp/launch.ts +++ b/packages/ckb/src/rgbpp/launch.ts @@ -32,7 +32,7 @@ import { getTransactionSize, scriptToHash } from '@nervosnetwork/ckb-sdk-utils'; * @param ownerRgbppLockArgs The owner RGBPP lock args whose data structure is: out_index | bitcoin_tx_id * @param launchAmount The total amount of RGBPP assets issued * @param rgbppTokenInfo The RGBPP token info https://github.com/ckb-cell/unique-cell?tab=readme-ov-file#xudt-information - * @param isMainnet True is for BTC and CKB Mainnet, flase is for BTC and CKB Testnet(see btcTestnetType for details about BTC Testnet) + * @param isMainnet True is for BTC and CKB Mainnet, false is for BTC and CKB Testnet(see btcTestnetType for details about BTC Testnet) * @param witnessLockPlaceholderSize(Optional) The WitnessArgs.lock placeholder bytes array size and the default value is 5000 * @param ckbFeeRate(Optional) The CKB transaction fee rate, default value is 1100 * @param btcTestnetType(Optional) The Bitcoin Testnet type including Testnet3 and Signet, default value is Testnet3 diff --git a/packages/ckb/src/spore/cluster.ts b/packages/ckb/src/spore/cluster.ts index 57b2bb46..95571424 100644 --- a/packages/ckb/src/spore/cluster.ts +++ b/packages/ckb/src/spore/cluster.ts @@ -18,7 +18,7 @@ import { bytesToHex, getTransactionSize } from '@nervosnetwork/ckb-sdk-utils'; * @param collector The collector that collects CKB live cells and transactions * @param rgbppLockArgs The rgbpp assets cell lock script args whose data structure is: out_index | bitcoin_tx_id * @param clusterData The cluster's data, including name and description. - * @param isMainnet True is for BTC and CKB Mainnet, flase is for BTC and CKB Testnet(see btcTestnetType for details about BTC Testnet) + * @param isMainnet True is for BTC and CKB Mainnet, false is for BTC and CKB Testnet(see btcTestnetType for details about BTC Testnet) * @param witnessLockPlaceholderSize(Optional) The WitnessArgs.lock placeholder bytes array size and the default value is 5000 * @param ckbFeeRate(Optional) The CKB transaction fee rate, default value is 1100 * @param btcTestnetType(Optional) The Bitcoin Testnet type including Testnet3 and Signet, default value is Testnet3 diff --git a/packages/ckb/src/spore/leap.ts b/packages/ckb/src/spore/leap.ts index ffa62fbd..fbf3c563 100644 --- a/packages/ckb/src/spore/leap.ts +++ b/packages/ckb/src/spore/leap.ts @@ -39,7 +39,7 @@ import { buildBtcTimeUnlockWitness } from '../rgbpp'; * @param sporeRgbppLockArgs The spore rgbpp cell lock script args whose data structure is: out_index | bitcoin_tx_id * @param sporeTypeBytes The spore type script serialized bytes * @param toCkbAddress The receiver ckb address - * @param isMainnet True is for BTC and CKB Mainnet, flase is for BTC and CKB Testnet(see btcTestnetType for details about BTC Testnet) + * @param isMainnet True is for BTC and CKB Mainnet, false is for BTC and CKB Testnet(see btcTestnetType for details about BTC Testnet) * @param witnessLockPlaceholderSize(Optional) The WitnessArgs.lock placeholder bytes array size and the default value is 5000 * @param ckbFeeRate(Optional) The CKB transaction fee rate, default value is 1100 * @param btcTestnetType(Optional) The Bitcoin Testnet type including Testnet3 and Signet, default value is Testnet3 @@ -122,7 +122,7 @@ export const genLeapSporeFromBtcToCkbVirtualTx = async ({ * The btc time lock args data structure is: lock_script | after | new_bitcoin_tx_id * @param btcTimeCells The BTC time cells of spore * @param btcAssetsApi BTC Assets Api - * @param isMainnet True is for BTC and CKB Mainnet, flase is for BTC and CKB Testnet(see btcTestnetType for details about BTC Testnet) + * @param isMainnet True is for BTC and CKB Mainnet, false is for BTC and CKB Testnet(see btcTestnetType for details about BTC Testnet) * @param btcTestnetType(Optional) The Bitcoin Testnet type including Testnet3 and Signet, default value is Testnet3 */ export const buildSporeBtcTimeCellsSpentTx = async ({ @@ -199,7 +199,7 @@ export const buildSporeBtcTimeCellsSpentTx = async ({ * @param sporeRgbppLockArgs The spore rgbpp cell lock script args whose data structure is: out_index | bitcoin_tx_id * @param sporeTypeBytes The spore type script serialized bytes * @param toCkbAddress The receiver ckb address - * @param isMainnet True is for BTC and CKB Mainnet, flase is for BTC and CKB Testnet + * @param isMainnet True is for BTC and CKB Mainnet, false is for BTC and CKB Testnet * @param witnessLockPlaceholderSize(Optional) The WitnessArgs.lock placeholder bytes array size and the default value is 5000 * @param ckbFeeRate(Optional) The CKB transaction fee rate, default value is 1100 */ diff --git a/packages/ckb/src/spore/spore.ts b/packages/ckb/src/spore/spore.ts index 689a3898..44ac2c53 100644 --- a/packages/ckb/src/spore/spore.ts +++ b/packages/ckb/src/spore/spore.ts @@ -56,7 +56,7 @@ import signWitnesses from '@nervosnetwork/ckb-sdk-core/lib/signWitnesses'; * @param collector The collector that collects CKB live cells and transactions * @param clusterRgbppLockArgs The cluster rgbpp cell lock script args whose data structure is: out_index | bitcoin_tx_id * @param sporeDataList The spore's data list, including name and description. - * @param isMainnet True is for BTC and CKB Mainnet, flase is for BTC and CKB Testnet(see btcTestnetType for details about BTC Testnet) + * @param isMainnet True is for BTC and CKB Mainnet, false is for BTC and CKB Testnet(see btcTestnetType for details about BTC Testnet) * @param btcTestnetType(Optional) The Bitcoin Testnet type including Testnet3 and Signet, default value is Testnet3 */ export const genCreateSporeCkbVirtualTx = async ({ @@ -217,7 +217,7 @@ export const buildAppendingIssuerCellToSporesCreateTx = async ({ * @param collector The collector that collects CKB live cells and transactions * @param ckbRawTx CKB raw transaction * @param sumInputsCapacity The sum capacity of ckb inputs which is to be used to calculate ckb tx fee - * @param isMainnet True is for BTC and CKB Mainnet, flase is for BTC and CKB Testnet(see btcTestnetType for details about BTC Testnet) + * @param isMainnet True is for BTC and CKB Mainnet, false is for BTC and CKB Testnet(see btcTestnetType for details about BTC Testnet) * @param ckbFeeRate(Optional) The CKB transaction fee rate, default value is 1100 */ export const appendIssuerCellToSporesCreate = async ({ @@ -285,7 +285,7 @@ export const appendIssuerCellToSporesCreate = async ({ * @param collector The collector that collects CKB live cells and transactions * @param sporeRgbppLockArgs The spore rgbpp cell lock script args whose data structure is: out_index | bitcoin_tx_id * @param sporeTypeBytes The spore type script serialized bytes - * @param isMainnet True is for BTC and CKB Mainnet, flase is for BTC and CKB Testnet(see btcTestnetType for details about BTC Testnet) + * @param isMainnet True is for BTC and CKB Mainnet, false is for BTC and CKB Testnet(see btcTestnetType for details about BTC Testnet) * @param witnessLockPlaceholderSize(Optional) The WitnessArgs.lock placeholder bytes array size and the default value is 5000 * @param ckbFeeRate(Optional) The CKB transaction fee rate, default value is 1100 * @param btcTestnetType(Optional) The Bitcoin Testnet type including Testnet3 and Signet, default value is Testnet3 diff --git a/packages/ckb/src/types/index.ts b/packages/ckb/src/types/index.ts index dd502f9c..981529cd 100644 --- a/packages/ckb/src/types/index.ts +++ b/packages/ckb/src/types/index.ts @@ -2,5 +2,4 @@ export * from './common'; export * from './collector'; export * from './rgbpp'; export * from './spv'; -export * from './queue'; export * from './spore'; diff --git a/packages/ckb/src/types/rgbpp.ts b/packages/ckb/src/types/rgbpp.ts index f757d1fd..d53219a7 100644 --- a/packages/ckb/src/types/rgbpp.ts +++ b/packages/ckb/src/types/rgbpp.ts @@ -25,7 +25,7 @@ export interface BtcTransferVirtualTxParams { rgbppLockArgsList: Hex[]; // The XUDT amount to be transferred, if the noMergeOutputCells is true, the transferAmount will be ignored transferAmount: bigint; - // True is for BTC and CKB Mainnet, flase is for BTC and CKB Testnet(see btcTestnetType for details about BTC Testnet) + // True is for BTC and CKB Mainnet, false is for BTC and CKB Testnet(see btcTestnetType for details about BTC Testnet) isMainnet: boolean; // The Bitcoin Testnet type including Testnet3 and Signet, default value is Testnet3 btcTestnetType?: BTCTestnetType; @@ -53,7 +53,7 @@ export interface BtcBatchTransferVirtualTxParams { rgbppLockArgsList: Hex[]; // The rgbpp receiver list which include toRgbppLockArgs and transferAmount rgbppReceivers: RgbppBtcAddressReceiver[]; - // True is for BTC and CKB Mainnet, flase is for BTC and CKB Testnet(see btcTestnetType for details about BTC Testnet) + // True is for BTC and CKB Mainnet, false is for BTC and CKB Testnet(see btcTestnetType for details about BTC Testnet) isMainnet: boolean; // The Bitcoin Testnet type including Testnet3 and Signet, default value is Testnet3 btcTestnetType?: BTCTestnetType; @@ -112,7 +112,7 @@ export interface AppendPaymasterCellAndSignTxParams { sumInputsCapacity: Hex; // The paymaster cell to be inserted into CKB transaction to pay an extra output cell paymasterCell: IndexerCell; - // True is for BTC and CKB Mainnet, flase is for BTC and CKB Testnet + // True is for BTC and CKB Mainnet, false is for BTC and CKB Testnet isMainnet: boolean; // The CKB transaction fee rate, default value is 1100 ckbFeeRate?: bigint; @@ -137,7 +137,7 @@ export interface BtcTimeCellsParams { btcTimeCells: IndexerCell[]; // BTC Assets Api btcAssetsApi: BtcAssetsApi; - // True is for BTC and CKB Mainnet, flase is for BTC and CKB Testnet + // True is for BTC and CKB Mainnet, false is for BTC and CKB Testnet isMainnet: boolean; // The Bitcoin Testnet type including Testnet3 and Signet, default value is Testnet3 btcTestnetType?: BTCTestnetType; @@ -152,7 +152,7 @@ export interface SignBtcTimeCellsTxParams { collector: Collector; // The master CKB address to pay the time cells spent tx fee masterCkbAddress: Address; - // True is for BTC and CKB Mainnet, flase is for BTC and CKB Testnet + // True is for BTC and CKB Mainnet, false is for BTC and CKB Testnet isMainnet: boolean; // [u64; 2], filter cells by output capacity range, [inclusive, exclusive] outputCapacityRange?: Hex[]; @@ -184,7 +184,7 @@ export interface UpdateCkbTxWithRealBtcTxIdParams { ckbRawTx: CKBComponents.RawTransaction; // The BTC transaction id btcTxId: Hex; - // True is for BTC and CKB Mainnet, flase is for BTC and CKB Testnet + // True is for BTC and CKB Mainnet, false is for BTC and CKB Testnet isMainnet: boolean; } @@ -234,7 +234,7 @@ export interface AppendIssuerCellToBtcBatchTransfer { ckbRawTx: CKBComponents.RawTransaction; // The sum capacity of the ckb inputs sumInputsCapacity: Hex; - // True is for BTC and CKB Mainnet, flase is for BTC and CKB Testnet + // True is for BTC and CKB Mainnet, false is for BTC and CKB Testnet isMainnet: boolean; // The CKB transaction fee rate, default value is 1100 ckbFeeRate?: bigint; @@ -261,7 +261,7 @@ export interface RgbppLaunchCkbVirtualTxParams { launchAmount: bigint; // The RGBPP token info https://github.com/ckb-cell/unique-cell?tab=readme-ov-file#xudt-information rgbppTokenInfo: RgbppTokenInfo; - // True is for BTC and CKB Mainnet, flase is for BTC and CKB Testnet(see btcTestnetType for details about BTC Testnet) + // True is for BTC and CKB Mainnet, false is for BTC and CKB Testnet(see btcTestnetType for details about BTC Testnet) isMainnet: boolean; // The Bitcoin Testnet type including Testnet3 and Signet, default value is Testnet3 btcTestnetType?: BTCTestnetType; diff --git a/packages/ckb/src/types/spore.ts b/packages/ckb/src/types/spore.ts index 0fe0a418..84a851cf 100644 --- a/packages/ckb/src/types/spore.ts +++ b/packages/ckb/src/types/spore.ts @@ -10,7 +10,7 @@ export interface CreateClusterCkbVirtualTxParams { rgbppLockArgs: Hex; // The cluster's data, including name and description. clusterData: RawClusterData; - // True is for BTC and CKB Mainnet, flase is for BTC and CKB Testnet + // True is for BTC and CKB Mainnet, false is for BTC and CKB Testnet isMainnet: boolean; // The Bitcoin Testnet type including Testnet3 and Signet, default value is Testnet3 btcTestnetType?: BTCTestnetType; @@ -38,7 +38,7 @@ export interface CreateSporeCkbVirtualTxParams { clusterRgbppLockArgs: Hex; // The cluster's data, including name and description. sporeDataList: RawSporeData[]; - // True is for BTC and CKB Mainnet, flase is for BTC and CKB Testnet + // True is for BTC and CKB Mainnet, false is for BTC and CKB Testnet isMainnet: boolean; // The Bitcoin Testnet type including Testnet3 and Signet, default value is Testnet3 btcTestnetType?: BTCTestnetType; @@ -87,7 +87,7 @@ export interface AppendIssuerCellToSporeCreate { ckbRawTx: CKBComponents.RawTransaction; // The sum capacity of the ckb inputs sumInputsCapacity: Hex; - // True is for BTC and CKB Mainnet, flase is for BTC and CKB Testnet + // True is for BTC and CKB Mainnet, false is for BTC and CKB Testnet isMainnet: boolean; // The CKB transaction fee rate, default value is 1100 ckbFeeRate?: bigint; @@ -107,7 +107,7 @@ export interface TransferSporeCkbVirtualTxParams { sporeRgbppLockArgs: Hex; // The spore type script serialized bytes sporeTypeBytes: Hex; - // True is for BTC and CKB Mainnet, flase is for BTC and CKB Testnet + // True is for BTC and CKB Mainnet, false is for BTC and CKB Testnet isMainnet: boolean; // The Bitcoin Testnet type including Testnet3 and Signet, default value is Testnet3 btcTestnetType?: BTCTestnetType; @@ -141,7 +141,7 @@ export interface LeapSporeFromBtcToCkbVirtualTxParams { sporeTypeBytes: Hex; // The receiver ckb address toCkbAddress: Address; - // True is for BTC and CKB Mainnet, flase is for BTC and CKB Testnet + // True is for BTC and CKB Mainnet, false is for BTC and CKB Testnet isMainnet: boolean; // The Bitcoin Testnet type including Testnet3 and Signet, default value is Testnet3 btcTestnetType?: BTCTestnetType; @@ -160,7 +160,7 @@ export interface LeapSporeFromCkbToBtcVirtualTxParams { toRgbppLockArgs: Hex; // The spore type script serialized bytes sporeTypeBytes: Hex; - // True is for BTC and CKB Mainnet, flase is for BTC and CKB Testnet + // True is for BTC and CKB Mainnet, false is for BTC and CKB Testnet isMainnet: boolean; // The Bitcoin Testnet type including Testnet3 and Signet, default value is Testnet3 btcTestnetType?: BTCTestnetType; diff --git a/packages/rgbpp/src/rgbpp/types.ts b/packages/rgbpp/src/rgbpp/types.ts index d34a03fd..c5e9b6c7 100644 --- a/packages/rgbpp/src/rgbpp/types.ts +++ b/packages/rgbpp/src/rgbpp/types.ts @@ -31,7 +31,7 @@ export interface RgbppTransferBtcParams { export interface RgbppTransferTxParams { ckb: RgbppTransferCkbParams; btc: RgbppTransferBtcParams; - // True is for BTC and CKB Mainnet, flase is for BTC and CKB Testnet + // True is for BTC and CKB Mainnet, false is for BTC and CKB Testnet isMainnet: boolean; } diff --git a/packages/rgbpp/src/rgbpp/xudt.ts b/packages/rgbpp/src/rgbpp/xudt.ts index 2c5dbb1c..acdf14a7 100644 --- a/packages/rgbpp/src/rgbpp/xudt.ts +++ b/packages/rgbpp/src/rgbpp/xudt.ts @@ -12,13 +12,13 @@ import { RgbppTransferTxParams, RgbppTransferTxResult } from './types'; * @param transferAmount The XUDT amount to be transferred, if the noMergeOutputCells is true, the transferAmount will be ignored * @param feeRate The CKB transaction fee rate, default value is 1100 * - * BTC pramaeters + * BTC parameters * @param fromAddress The sender BTC address * @param fromPubkey The public key of the sender BTC address * @param toAddress The receiver BTC address * @param dataSource The BTC data source * @param feeRate The fee rate of the BTC transaction - * @param isMainnet True is for BTC and CKB Mainnet, flase is for BTC and CKB Testnet(see btcTestnetType for details about BTC Testnet) + * @param isMainnet True is for BTC and CKB Mainnet, false is for BTC and CKB Testnet(see btcTestnetType for details about BTC Testnet) * @param testnetType(Optional) The Bitcoin Testnet type including Testnet3 and Signet, default value is Testnet3 */ export const buildRgbppTransferTx = async ({ From 6e840c196fbece06430c559aebbdadaf7fb6e632 Mon Sep 17 00:00:00 2001 From: Dylan Duan Date: Tue, 18 Jun 2024 19:19:46 +0800 Subject: [PATCH 88/90] chore: Add changeset --- .changeset/wise-years-swim.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/wise-years-swim.md diff --git a/.changeset/wise-years-swim.md b/.changeset/wise-years-swim.md new file mode 100644 index 00000000..1281e1a5 --- /dev/null +++ b/.changeset/wise-years-swim.md @@ -0,0 +1,5 @@ +--- +"@rgbpp-sdk/ckb": minor +--- + +fix: Fix typo and remove useless queue types From e789c4e306a878dcd91b8c91844f844d2312e178 Mon Sep 17 00:00:00 2001 From: Shook Date: Wed, 19 Jun 2024 00:47:38 +0800 Subject: [PATCH 89/90] docs: remove deleted prop in the btc README --- packages/btc/README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/btc/README.md b/packages/btc/README.md index f06877f8..788c0206 100644 --- a/packages/btc/README.md +++ b/packages/btc/README.md @@ -221,7 +221,6 @@ const psbt = await sendRgbppUtxos({ minUtxoSatoshi: config.btcUtxoDustLimit, // optional, default to 1000 on the testnet, 1,0000 on the mainnet rgbppMinUtxoSatoshi: config.rgbppUtxoDustLimit, // optional, default to 546 on both testnet/mainnet onlyConfirmedUtxos: false, // optional, default to false, only confirmed utxos are allowed in the transaction - onlyProvableUtxos: true, // optional, default to true, only utxos that satisfy (utxo.address == from) are allowed feeRate: 1, // optional, default to 1 on the testnet, and it is a floating number on the mainnet }); ``` From 0f2be64fa74905febcb9716549c41b4f88f9896c Mon Sep 17 00:00:00 2001 From: Shook <44739165+ShookLyngs@users.noreply.github.com> Date: Wed, 19 Jun 2024 11:48:21 +0800 Subject: [PATCH 90/90] Bump RGB++ SDK to v0.4.0 (#238) --- .changeset/great-baboons-smash.md | 5 ----- .changeset/orange-mice-trade.md | 9 --------- .changeset/silly-rules-collect.md | 5 ----- .changeset/spicy-cups-cheat.md | 9 --------- .changeset/wise-years-swim.md | 5 ----- packages/btc/CHANGELOG.md | 22 ++++++++++++++++++++++ packages/btc/package.json | 2 +- packages/ckb/CHANGELOG.md | 13 ++++++++++++- packages/ckb/package.json | 2 +- packages/rgbpp/CHANGELOG.md | 13 +++++++++++++ packages/rgbpp/package.json | 2 +- packages/service/CHANGELOG.md | 6 ++++++ packages/service/package.json | 2 +- 13 files changed, 57 insertions(+), 38 deletions(-) delete mode 100644 .changeset/great-baboons-smash.md delete mode 100644 .changeset/orange-mice-trade.md delete mode 100644 .changeset/silly-rules-collect.md delete mode 100644 .changeset/spicy-cups-cheat.md delete mode 100644 .changeset/wise-years-swim.md diff --git a/.changeset/great-baboons-smash.md b/.changeset/great-baboons-smash.md deleted file mode 100644 index 73fe4b23..00000000 --- a/.changeset/great-baboons-smash.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"rgbpp": minor ---- - -feat: Export buildRgbppTransferTx from rgbpp package diff --git a/.changeset/orange-mice-trade.md b/.changeset/orange-mice-trade.md deleted file mode 100644 index 2ac305a4..00000000 --- a/.changeset/orange-mice-trade.md +++ /dev/null @@ -1,9 +0,0 @@ ---- -"@rgbpp-sdk/btc": minor ---- - -Support including multi-origin UTXOs in the same transaction - - - Add `pubkeyMap` option in the sendUtxos(), sendRgbppUtxos() and sendRbf() API - - Rename `inputsPubkey` option to `pubkeyMap` in the sendRbf() API - - Delete `onlyProvableUtxos` option from the sendRgbppUtxos() API diff --git a/.changeset/silly-rules-collect.md b/.changeset/silly-rules-collect.md deleted file mode 100644 index fba24d0d..00000000 --- a/.changeset/silly-rules-collect.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@rgbpp-sdk/service": minor ---- - -Add BtcAssetsApi.getRgbppApiBalanceByAddress() API for querying RGBPP XUDT balances by a BTC address diff --git a/.changeset/spicy-cups-cheat.md b/.changeset/spicy-cups-cheat.md deleted file mode 100644 index 6aaebfb3..00000000 --- a/.changeset/spicy-cups-cheat.md +++ /dev/null @@ -1,9 +0,0 @@ ---- -"@rgbpp-sdk/btc": minor ---- - -Support Full-RBF feature with the sendRbf() and createSendRbfBuilder() API - - - Add `excludeUtxos`, `skipInputsValidation` options in the `sendUtxos()` API to support the RBF feature - - Add `onlyProvableUtxos` option in the `sendRgbppUtxos()` API for future update supports - - Add `changeIndex` in the return type of the BTC Builder APIs diff --git a/.changeset/wise-years-swim.md b/.changeset/wise-years-swim.md deleted file mode 100644 index 1281e1a5..00000000 --- a/.changeset/wise-years-swim.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@rgbpp-sdk/ckb": minor ---- - -fix: Fix typo and remove useless queue types diff --git a/packages/btc/CHANGELOG.md b/packages/btc/CHANGELOG.md index ca3d4ca0..eb0d8263 100644 --- a/packages/btc/CHANGELOG.md +++ b/packages/btc/CHANGELOG.md @@ -1,5 +1,27 @@ # @rgbpp-sdk/btc +## 0.4.0 + +### Minor Changes + +- [#228](https://github.com/ckb-cell/rgbpp-sdk/pull/228): Support including multi-origin UTXOs in the same transaction ([@ShookLyngs](https://github.com/ShookLyngs)) + + - Add `pubkeyMap` option in the sendUtxos(), sendRgbppUtxos() and sendRbf() API + - Rename `inputsPubkey` option to `pubkeyMap` in the sendRbf() API + - Delete `onlyProvableUtxos` option from the sendRgbppUtxos() API + +- [#150](https://github.com/ckb-cell/rgbpp-sdk/pull/150): Support Full-RBF feature with the sendRbf() and createSendRbfBuilder() API ([@ShookLyngs](https://github.com/ShookLyngs)) + + - Add `excludeUtxos`, `skipInputsValidation` options in the `sendUtxos()` API to support the RBF feature + - Add `onlyProvableUtxos` option in the `sendRgbppUtxos()` API for future update supports + - Add `changeIndex` in the return type of the BTC Builder APIs + +### Patch Changes + +- Updated dependencies [[`e5f41fd`](https://github.com/ckb-cell/rgbpp-sdk/commit/e5f41fd2b275182d2ab3fdf17e3b8853025fd2b9), [`6e840c1`](https://github.com/ckb-cell/rgbpp-sdk/commit/6e840c196fbece06430c559aebbdadaf7fb6e632)]: + - @rgbpp-sdk/service@0.4.0 + - @rgbpp-sdk/ckb@0.4.0 + ## v0.3.0 ### Minor Changes diff --git a/packages/btc/package.json b/packages/btc/package.json index bfa9e513..b668e9df 100644 --- a/packages/btc/package.json +++ b/packages/btc/package.json @@ -1,6 +1,6 @@ { "name": "@rgbpp-sdk/btc", - "version": "0.3.0", + "version": "0.4.0", "scripts": { "test": "vitest", "build": "tsc -p tsconfig.build.json", diff --git a/packages/ckb/CHANGELOG.md b/packages/ckb/CHANGELOG.md index 1b01af94..25e339c2 100644 --- a/packages/ckb/CHANGELOG.md +++ b/packages/ckb/CHANGELOG.md @@ -1,10 +1,21 @@ # @rgbpp-sdk/ckb +## 0.4.0 + +### Minor Changes + +- [#236](https://github.com/ckb-cell/rgbpp-sdk/pull/236): Fix typo and remove useless queue types ([@duanyytop](https://github.com/duanyytop)) + +### Patch Changes + +- Updated dependencies [[`e5f41fd`](https://github.com/ckb-cell/rgbpp-sdk/commit/e5f41fd2b275182d2ab3fdf17e3b8853025fd2b9)]: + - @rgbpp-sdk/service@0.4.0 + ## v0.3.0 ### Minor Changes -- [#197](https://github.com/ckb-cell/rgbpp-sdk/pull/197): feat: Return needPaymasterCell for RGB++ ckb cirtual tx ([@duanyytop](https://github.com/duanyytop)) +- [#197](https://github.com/ckb-cell/rgbpp-sdk/pull/197): Return needPaymasterCell for RGB++ ckb cirtual tx ([@duanyytop](https://github.com/duanyytop)) - [#191](https://github.com/ckb-cell/rgbpp-sdk/pull/191): Dynamic fetching cell deps deployed by TypeID ([@duanyytop](https://github.com/duanyytop)) diff --git a/packages/ckb/package.json b/packages/ckb/package.json index 862b1aad..9f509a0f 100644 --- a/packages/ckb/package.json +++ b/packages/ckb/package.json @@ -1,6 +1,6 @@ { "name": "@rgbpp-sdk/ckb", - "version": "0.3.0", + "version": "0.4.0", "scripts": { "test": "vitest", "build": "tsc -p tsconfig.build.json", diff --git a/packages/rgbpp/CHANGELOG.md b/packages/rgbpp/CHANGELOG.md index 2e521abc..e7b48447 100644 --- a/packages/rgbpp/CHANGELOG.md +++ b/packages/rgbpp/CHANGELOG.md @@ -1,5 +1,18 @@ # rgbpp +## 0.4.0 + +### Minor Changes + +- [#216](https://github.com/ckb-cell/rgbpp-sdk/pull/216): Export buildRgbppTransferTx from rgbpp package ([@duanyytop](https://github.com/duanyytop)) + +### Patch Changes + +- Updated dependencies [[`1ecac34`](https://github.com/ckb-cell/rgbpp-sdk/commit/1ecac341d5ced04e59bfdcd432a9bce84bedd959), [`e5f41fd`](https://github.com/ckb-cell/rgbpp-sdk/commit/e5f41fd2b275182d2ab3fdf17e3b8853025fd2b9), [`08200c9`](https://github.com/ckb-cell/rgbpp-sdk/commit/08200c974ef336661723cc7556a003932babda9a), [`6e840c1`](https://github.com/ckb-cell/rgbpp-sdk/commit/6e840c196fbece06430c559aebbdadaf7fb6e632)]: + - @rgbpp-sdk/btc@0.4.0 + - @rgbpp-sdk/service@0.4.0 + - @rgbpp-sdk/ckb@0.4.0 + ## v0.3.0 ### Patch Changes diff --git a/packages/rgbpp/package.json b/packages/rgbpp/package.json index 09a0a8d1..4f9b740e 100644 --- a/packages/rgbpp/package.json +++ b/packages/rgbpp/package.json @@ -1,6 +1,6 @@ { "name": "rgbpp", - "version": "0.3.0", + "version": "0.4.0", "scripts": { "build": "tsc -p tsconfig.build.json", "lint": "tsc && eslint --ext .ts src/* && prettier --check 'src/*.ts'", diff --git a/packages/service/CHANGELOG.md b/packages/service/CHANGELOG.md index e7736579..4f62e064 100644 --- a/packages/service/CHANGELOG.md +++ b/packages/service/CHANGELOG.md @@ -1,5 +1,11 @@ # @rgbpp-sdk/service +## 0.4.0 + +### Minor Changes + +- [#222](https://github.com/ckb-cell/rgbpp-sdk/pull/222): Add BtcAssetsApi.getRgbppApiBalanceByAddress() API for querying RGBPP XUDT balances by a BTC address ([@ShookLyngs](https://github.com/ShookLyngs)) + ## v0.3.0 ### Minor Changes diff --git a/packages/service/package.json b/packages/service/package.json index 50c800a6..a089e93a 100644 --- a/packages/service/package.json +++ b/packages/service/package.json @@ -1,6 +1,6 @@ { "name": "@rgbpp-sdk/service", - "version": "0.3.0", + "version": "0.4.0", "scripts": { "test": "vitest", "build": "tsc -p tsconfig.build.json",