diff --git a/.changeset/sweet-cheetahs-drop.md b/.changeset/sweet-cheetahs-drop.md new file mode 100644 index 00000000..fae53f2f --- /dev/null +++ b/.changeset/sweet-cheetahs-drop.md @@ -0,0 +1,8 @@ +--- +'@rgbpp-sdk/ckb': minor +--- + +Add USDI to compatible xUDT list and remove jsdelivr CDN because of cache + - Fetch and cache compatible xUDT list from Vercel or GitHub server + - Use local static compatible xUDT list when the cache is empty + - Remove jsdelivr CDN because CDN cache time is too long, causing UTXO Airdrop cellDeps to become outdated diff --git a/examples/rgbpp/README.md b/examples/rgbpp/README.md index 58162bcc..1878a7d2 100644 --- a/examples/rgbpp/README.md +++ b/examples/rgbpp/README.md @@ -2,6 +2,8 @@ - xUDT directory: The examples for RGB++ UDT issuance, transfer, transferAll and leap - Spore directory: The examples for RGB++ Spore creation, transfer and leap +- compatible-xudt directory: The examples for RGB++ compatible UDT issuance, transfer, transferAll and leap + - If you want to get the latest compatible xUDT list, `CompatibleXUDTRegistry.refreshCache` should be called first > [!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. diff --git a/examples/rgbpp/xudt/compatible-xudt/1-ckb-leap-btc.ts b/examples/rgbpp/xudt/compatible-xudt/1-ckb-leap-btc.ts index 218813b2..db786446 100644 --- a/examples/rgbpp/xudt/compatible-xudt/1-ckb-leap-btc.ts +++ b/examples/rgbpp/xudt/compatible-xudt/1-ckb-leap-btc.ts @@ -1,6 +1,6 @@ import { serializeScript } from '@nervosnetwork/ckb-sdk-utils'; import { genCkbJumpBtcVirtualTx } from 'rgbpp'; -import { getSecp256k1CellDep, buildRgbppLockArgs } from 'rgbpp/ckb'; +import { getSecp256k1CellDep, buildRgbppLockArgs, CompatibleXUDTRegistry } from 'rgbpp/ckb'; import { CKB_PRIVATE_KEY, isMainnet, collector, ckbAddress, BTC_TESTNET_TYPE } from '../../env'; interface LeapToBtcParams { @@ -18,6 +18,13 @@ const leapRusdFromCkbToBtc = async ({ }: LeapToBtcParams) => { const toRgbppLockArgs = buildRgbppLockArgs(outIndex, btcTxId); + // Refresh the cache by fetching the latest compatible xUDT list from the specified URL. + // The default URL is: + // https://raw.githubusercontent.com/utxostack/typeid-contract-cell-deps/main/compatible-udt.json + // You can set your own trusted URL to fetch the compatible xUDT list. + // await CompatibleXUDTRegistry.refreshCache("https://your-own-trusted-compatible-xudt-url"); + await CompatibleXUDTRegistry.refreshCache(); + const ckbRawTx = await genCkbJumpBtcVirtualTx({ collector, fromCkbAddress: ckbAddress, diff --git a/examples/rgbpp/xudt/compatible-xudt/2-btc-transfer.ts b/examples/rgbpp/xudt/compatible-xudt/2-btc-transfer.ts index 8574abbf..54ab8337 100644 --- a/examples/rgbpp/xudt/compatible-xudt/2-btc-transfer.ts +++ b/examples/rgbpp/xudt/compatible-xudt/2-btc-transfer.ts @@ -1,4 +1,4 @@ -import { buildRgbppLockArgs } from 'rgbpp/ckb'; +import { buildRgbppLockArgs, CompatibleXUDTRegistry } from 'rgbpp/ckb'; import { buildRgbppTransferTx } from 'rgbpp'; import { isMainnet, collector, btcService, btcAccount, btcDataSource, BTC_TESTNET_TYPE } from '../../env'; import { saveCkbVirtualTxResult } from '../../shared/utils'; @@ -18,6 +18,13 @@ const transferRusdOnBtc = async ({ compatibleXudtTypeScript, transferAmount, }: RgbppTransferParams) => { + // Refresh the cache by fetching the latest compatible xUDT list from the specified URL. + // The default URL is: + // https://raw.githubusercontent.com/utxostack/typeid-contract-cell-deps/main/compatible-udt.json + // You can set your own trusted URL to fetch the compatible xUDT list. + // await CompatibleXUDTRegistry.refreshCache("https://your-own-trusted-compatible-xudt-url"); + await CompatibleXUDTRegistry.refreshCache(); + const { ckbVirtualTxResult, btcPsbtHex } = await buildRgbppTransferTx({ ckb: { collector, diff --git a/examples/rgbpp/xudt/compatible-xudt/3-btc-leap-ckb.ts b/examples/rgbpp/xudt/compatible-xudt/3-btc-leap-ckb.ts index fec1724c..6a334456 100644 --- a/examples/rgbpp/xudt/compatible-xudt/3-btc-leap-ckb.ts +++ b/examples/rgbpp/xudt/compatible-xudt/3-btc-leap-ckb.ts @@ -1,4 +1,4 @@ -import { buildRgbppLockArgs } from 'rgbpp/ckb'; +import { buildRgbppLockArgs, CompatibleXUDTRegistry } from 'rgbpp/ckb'; import { serializeScript } from '@nervosnetwork/ckb-sdk-utils'; import { genBtcJumpCkbVirtualTx, sendRgbppUtxos } from 'rgbpp'; import { isMainnet, collector, btcService, btcDataSource, btcAccount, BTC_TESTNET_TYPE } from '../../env'; @@ -18,6 +18,13 @@ const leapRusdFromBtcToCKB = async ({ compatibleXudtTypeScript, transferAmount, }: LeapToCkbParams) => { + // Refresh the cache by fetching the latest compatible xUDT list from the specified URL. + // The default URL is: + // https://raw.githubusercontent.com/utxostack/typeid-contract-cell-deps/main/compatible-udt.json + // You can set your own trusted URL to fetch the compatible xUDT list. + // await CompatibleXUDTRegistry.refreshCache("https://your-own-trusted-compatible-xudt-url"); + await CompatibleXUDTRegistry.refreshCache(); + const ckbVirtualTxResult = await genBtcJumpCkbVirtualTx({ collector, rgbppLockArgsList, diff --git a/examples/rgbpp/xudt/compatible-xudt/assets-api.ts b/examples/rgbpp/xudt/compatible-xudt/assets-api.ts index b47f8328..6f3231ba 100644 --- a/examples/rgbpp/xudt/compatible-xudt/assets-api.ts +++ b/examples/rgbpp/xudt/compatible-xudt/assets-api.ts @@ -2,48 +2,58 @@ import { serializeScript } from '@nervosnetwork/ckb-sdk-utils'; import { btcService } from '../../env'; (async () => { - const assets = await btcService.getRgbppAssetsByBtcAddress('tb1qvt7p9g6mw70sealdewtfp0sekquxuru6j3gwmt', { - type_script: serializeScript({ - codeHash: '0x1142755a044bf2ee358cba9f2da187ce928c91cd4dc8692ded0337efa677d21a', - hashType: 'type', - args: '0x878fcc6f1f08d48e87bb1c3b3d5083f23f8a39c5d5c764f253b55b998526439b', - }), - }); - console.log('RUSD Assets: ', JSON.stringify(assets)); + // const assets = await btcService.getRgbppAssetsByBtcAddress('tb1qvt7p9g6mw70sealdewtfp0sekquxuru6j3gwmt', { + // type_script: serializeScript({ + // codeHash: '0x1142755a044bf2ee358cba9f2da187ce928c91cd4dc8692ded0337efa677d21a', + // hashType: 'type', + // args: '0x878fcc6f1f08d48e87bb1c3b3d5083f23f8a39c5d5c764f253b55b998526439b', + // }), + // }); + // console.log('RUSD Assets: ', JSON.stringify(assets)); - const activities = await btcService.getRgbppActivityByBtcAddress('tb1qvt7p9g6mw70sealdewtfp0sekquxuru6j3gwmt', { - type_script: serializeScript({ - codeHash: '0x1142755a044bf2ee358cba9f2da187ce928c91cd4dc8692ded0337efa677d21a', - hashType: 'type', - args: '0x878fcc6f1f08d48e87bb1c3b3d5083f23f8a39c5d5c764f253b55b998526439b', - }), - }); - console.log('RUSD Activities: ', JSON.stringify(activities)); + // const activities = await btcService.getRgbppActivityByBtcAddress('tb1qvt7p9g6mw70sealdewtfp0sekquxuru6j3gwmt', { + // type_script: serializeScript({ + // codeHash: '0x1142755a044bf2ee358cba9f2da187ce928c91cd4dc8692ded0337efa677d21a', + // hashType: 'type', + // args: '0x878fcc6f1f08d48e87bb1c3b3d5083f23f8a39c5d5c764f253b55b998526439b', + // }), + // }); + // console.log('RUSD Activities: ', JSON.stringify(activities)); - const info = await btcService.getRgbppAssetInfoByTypeScript( - serializeScript({ - codeHash: '0x25c29dc317811a6f6f3985a7a9ebc4838bd388d19d0feeecf0bcd60f6c0975bb', - hashType: 'type', - args: '0x661cfbe2124b3e79e50e505c406be5b2dcf9da15d8654b749ec536fa4c2eaaae', - }), - ); - console.log('Standard xUDT info: ', JSON.stringify(info)); + // const balance = await btcService.getRgbppBalanceByBtcAddress('tb1qvt7p9g6mw70sealdewtfp0sekquxuru6j3gwmt', { + // type_script: serializeScript({ + // codeHash: '0x1142755a044bf2ee358cba9f2da187ce928c91cd4dc8692ded0337efa677d21a', + // hashType: 'type', + // args: '0x878fcc6f1f08d48e87bb1c3b3d5083f23f8a39c5d5c764f253b55b998526439b', + // }), + // no_cache: true, + // }); + // console.log('RUSD balance from btc-assets-api: ', JSON.stringify(balance)); + + // const info = await btcService.getRgbppAssetInfoByTypeScript( + // serializeScript({ + // codeHash: '0x25c29dc317811a6f6f3985a7a9ebc4838bd388d19d0feeecf0bcd60f6c0975bb', + // hashType: 'type', + // args: '0x661cfbe2124b3e79e50e505c406be5b2dcf9da15d8654b749ec536fa4c2eaaae', + // }), + // ); + // console.log('Standard xUDT info: ', JSON.stringify(info)); const rusdInfo = await btcService.getRgbppAssetInfoByTypeScript( serializeScript({ - codeHash: '0x1142755a044bf2ee358cba9f2da187ce928c91cd4dc8692ded0337efa677d21a', + codeHash: '0xcc9dc33ef234e14bc788c43a4848556a5fb16401a04662fc55db9bb201987037', hashType: 'type', - args: '0x878fcc6f1f08d48e87bb1c3b3d5083f23f8a39c5d5c764f253b55b998526439b', + args: '0x71fd1985b2971a9903e4d8ed0d59e6710166985217ca0681437883837b86162f', }), ); console.log('RUSD xUDT info: ', JSON.stringify(rusdInfo)); - const utxoAirdropInfo = await btcService.getRgbppAssetInfoByTypeScript( - serializeScript({ - codeHash: '0xf5da9003e31fa9301a3915fe304de9bdb80524b5f0d8fc325fb699317998ee7a', - hashType: 'type', - args: '0xa63d308c04b4c075eb1d7d5cac891cf20276e3ddb2ec855fc981c88d8134dbe2', - }), - ); - console.log('UTXO Airdrop xUDT info: ', JSON.stringify(utxoAirdropInfo)); + // const utxoAirdropInfo = await btcService.getRgbppAssetInfoByTypeScript( + // serializeScript({ + // codeHash: '0xf5da9003e31fa9301a3915fe304de9bdb80524b5f0d8fc325fb699317998ee7a', + // hashType: 'type', + // args: '0xa63d308c04b4c075eb1d7d5cac891cf20276e3ddb2ec855fc981c88d8134dbe2', + // }), + // ); + // console.log('UTXO Airdrop xUDT info: ', JSON.stringify(utxoAirdropInfo)); })(); diff --git a/packages/ckb/src/constants/index.ts b/packages/ckb/src/constants/index.ts index 72955a7a..86bc6ec7 100644 --- a/packages/ckb/src/constants/index.ts +++ b/packages/ckb/src/constants/index.ts @@ -66,15 +66,6 @@ const TestnetInfo = { depType: 'code', } as CKBComponents.CellDep, - CompatibleXUDTTypeScripts: [ - // RUSD - { - codeHash: '0x1142755a044bf2ee358cba9f2da187ce928c91cd4dc8692ded0337efa677d21a', - hashType: 'type', - args: '', - }, - ] as CKBComponents.Script[], - UniqueTypeScript: { codeHash: '0x8e341bcfec6393dcd41e635733ff2dca00a6af546949f70c57a706c0f344df8b', hashType: 'type', @@ -157,7 +148,7 @@ const TestnetInfo = { } as CKBComponents.Script, UtxoAirdropBadgeTypeDep: { - outPoint: { txHash: '0xfa0a6821293cc1ef4ee67a900862208e27f67b98237c9b13bf93c84607c5cd33', index: '0x2' }, + outPoint: { txHash: '0xbbbb73972ac260a0f7204bea707288c3970688fe8714c3246a5e9a538168a42a', index: '0x0' }, depType: 'code', } as CKBComponents.CellDep, @@ -223,15 +214,6 @@ const MainnetInfo = { depType: 'code', } as CKBComponents.CellDep, - CompatibleXUDTTypeScripts: [ - // RUSD - { - codeHash: '0x26a33e0815888a4a0614a0b7d09fa951e0993ff21e55905510104a0b1312032b', - hashType: 'type', - args: '', - }, - ] as CKBComponents.Script[], - UniqueTypeScript: { codeHash: '0x2c8c11c985da60b0a330c61a85507416d6382c130ba67f0c47ab071e00aec628', hashType: 'data1', @@ -294,6 +276,33 @@ const MainnetInfo = { } as CKBComponents.Script, }; +export const COMPATIBLE_XUDT_TYPE_SCRIPTS: CKBComponents.Script[] = [ + // RUSD Mainnet + { + codeHash: '0x26a33e0815888a4a0614a0b7d09fa951e0993ff21e55905510104a0b1312032b', + hashType: 'type', + args: '', + }, + // RUSD Testnet + { + codeHash: '0x1142755a044bf2ee358cba9f2da187ce928c91cd4dc8692ded0337efa677d21a', + hashType: 'type', + args: '', + }, + // USDI Mainnet + { + codeHash: '0xbfa35a9c38a676682b65ade8f02be164d48632281477e36f8dc2f41f79e56bfc', + hashType: 'type', + args: '', + }, + // USDI Testnet + { + codeHash: '0xcc9dc33ef234e14bc788c43a4848556a5fb16401a04662fc55db9bb201987037', + hashType: 'type', + args: '', + }, +]; + export const UNLOCKABLE_LOCK_SCRIPT = { codeHash: '0x0000000000000000000000000000000000000000000000000000000000000000', hashType: 'data', @@ -363,9 +372,6 @@ export const getSporeTypeScript = (isMainnet: boolean) => export const getSporeTypeDep = (isMainnet: boolean) => isMainnet ? MainnetInfo.SporeTypeDep : TestnetInfo.SporeTypeDep; -export const getCompatibleXudtTypeScripts = (isMainnet: boolean) => - isMainnet ? MainnetInfo.CompatibleXUDTTypeScripts : TestnetInfo.CompatibleXUDTTypeScripts; - export const getUtxoAirdropBadgeTypeScript = (isMainnet: boolean) => isMainnet ? MainnetInfo.UtxoAirdropBadgeTypeScript : TestnetInfo.UtxoAirdropBadgeTypeScript; export const getUtxoAirdropBadgeTypeDep = (isMainnet: boolean) => diff --git a/packages/ckb/src/rgbpp/btc-time.ts b/packages/ckb/src/rgbpp/btc-time.ts index b14d07c7..97d8b882 100644 --- a/packages/ckb/src/rgbpp/btc-time.ts +++ b/packages/ckb/src/rgbpp/btc-time.ts @@ -66,7 +66,7 @@ export const buildBtcTimeCellsSpentTx = async ({ const hasStandardUDT = outputs.some((output) => isStandardUDTTypeSupported(output.type!, isMainnet)); const compatibleXudtCodeHashes = outputs - .filter((output) => isCompatibleUDTTypesSupported(output.type!, isMainnet)) + .filter((output) => isCompatibleUDTTypesSupported(output.type!)) .map((output) => output.type!.codeHash); const cellDeps = await fetchTypeIdCellDeps( isMainnet, diff --git a/packages/ckb/src/utils/cell-dep.spec.ts b/packages/ckb/src/utils/cell-dep.spec.ts index 764f74ba..dd682f9b 100644 --- a/packages/ckb/src/utils/cell-dep.spec.ts +++ b/packages/ckb/src/utils/cell-dep.spec.ts @@ -1,5 +1,5 @@ import { describe, it, expect } from 'vitest'; -import { fetchTypeIdCellDeps } from './cell-dep'; +import { CompatibleXUDTRegistry, fetchTypeIdCellDeps } from './cell-dep'; import { getBtcTimeLockDep, getRgbppLockDep, getUniqueTypeDep, getXudtDep } from '../constants'; describe('dynamic fetch cell dep', () => { @@ -109,8 +109,29 @@ describe('dynamic fetch cell dep', () => { const cellDeps = await fetchTypeIdCellDeps(isMainnet, { utxoAirdropBadge: true, }); - expect(cellDeps[0].outPoint?.txHash).toBe('0xfa0a6821293cc1ef4ee67a900862208e27f67b98237c9b13bf93c84607c5cd33'); - expect(cellDeps[0].outPoint?.index).toBe('0x2'); + expect(cellDeps[0].outPoint?.txHash).toBe('0xbbbb73972ac260a0f7204bea707288c3970688fe8714c3246a5e9a538168a42a'); + expect(cellDeps[0].outPoint?.index).toBe('0x0'); + }, + { timeout: 10000 }, + ); + + it( + 'CompatibleXUDTRegistry.getCompatibleTokens', + async () => { + const scripts = CompatibleXUDTRegistry.getCompatibleTokens(); + expect(scripts.length > 0).toBe(true); + // RUSD Mainnet + expect(scripts[0].codeHash).toBe('0x26a33e0815888a4a0614a0b7d09fa951e0993ff21e55905510104a0b1312032b'); + // USDI Testnet + expect(scripts[3].codeHash).toBe('0xcc9dc33ef234e14bc788c43a4848556a5fb16401a04662fc55db9bb201987037'); + + await CompatibleXUDTRegistry.refreshCache(); + const latestScripts = CompatibleXUDTRegistry.getCompatibleTokens(); + expect(latestScripts.length > 0).toBe(true); + // RUSD Testnet + expect(latestScripts[0].codeHash).toBe('0x1142755a044bf2ee358cba9f2da187ce928c91cd4dc8692ded0337efa677d21a'); + // USDI Mainnet + expect(latestScripts[3].codeHash).toBe('0xbfa35a9c38a676682b65ade8f02be164d48632281477e36f8dc2f41f79e56bfc'); }, { timeout: 10000 }, ); diff --git a/packages/ckb/src/utils/cell-dep.ts b/packages/ckb/src/utils/cell-dep.ts index 5bfd1786..5d71a57b 100644 --- a/packages/ckb/src/utils/cell-dep.ts +++ b/packages/ckb/src/utils/cell-dep.ts @@ -1,5 +1,6 @@ import axios from 'axios'; import { + COMPATIBLE_XUDT_TYPE_SCRIPTS, getBtcTimeLockDep, getRgbppLockDep, getUniqueTypeDep, @@ -36,11 +37,6 @@ export interface CellDepsObject { const GITHUB_CELL_DEPS_JSON_URL = 'https://raw.githubusercontent.com/utxostack/typeid-contract-cell-deps/main/deployment/cell-deps.json'; -// If the CDN has cache issue, please clear the cache by visiting -// https://www.jsdelivr.com/tools/purge?path=/gh/utxostack/typeid-contract-cell-deps@main -const CDN_GITHUB_CELL_DEPS_JSON_URL = - 'https://cdn.jsdelivr.net/gh/utxostack/typeid-contract-cell-deps@main/deployment/cell-deps.json'; - const VERCEL_CELL_DEPS_JSON_STATIC_URL = 'https://typeid-contract-cell-deps.vercel.app/deployment/cell-deps.json'; const VERCEL_SERVER_CELL_DEPS_JSON_URL = 'https://typeid-contract-cell-deps.vercel.app/api/cell-deps'; @@ -49,11 +45,7 @@ const request = (url: string) => axios.get(url, { timeout: 10000 }); const fetchCellDepsJsonFromStaticSource = async () => { try { - const response = await Promise.any([ - request(CDN_GITHUB_CELL_DEPS_JSON_URL), - request(GITHUB_CELL_DEPS_JSON_URL), - request(VERCEL_CELL_DEPS_JSON_STATIC_URL), - ]); + const response = await Promise.any([request(VERCEL_CELL_DEPS_JSON_STATIC_URL), request(GITHUB_CELL_DEPS_JSON_URL)]); return response.data as CellDepsObject; } catch (error) { // for (const e of error.errors) { @@ -210,3 +202,61 @@ export const fetchTypeIdCellDeps = async ( return cellDeps; }; + +const VERCEL_STATIC_COMPATIBLE_XUDT_URL = 'https://typeid-contract-cell-deps.vercel.app/compatible-udt.json'; +const GITHUB_STATIC_COMPATIBLE_XUDT_URL = + 'https://raw.githubusercontent.com/utxostack/typeid-contract-cell-deps/main/compatible-udt.json'; + +/** + * The `CompatibleXUDTRegistry` class is responsible for managing a cache of compatible XUDT (eXtensible User-Defined Token) scripts. + * It fetches and caches the compatible tokens from specified URLs and refreshes the cache periodically. + */ +export class CompatibleXUDTRegistry { + private static cache: CKBComponents.Script[] = []; + private static lastFetchTime: number = 0; + private static CACHE_DURATION = 3 * 60 * 1000; // 3 minutes ([about 24 CKB blocks](https://docs-old.nervos.org/docs/essays/tx-confirmation)) + private static xudtUrl = VERCEL_STATIC_COMPATIBLE_XUDT_URL; + + // If you want to get the latest compatible xUDT list, CompatibleXUDTRegistry.refreshCache should be called first + static getCompatibleTokens(): CKBComponents.Script[] { + const now = Date.now(); + if (this.cache.length === 0 || now - this.lastFetchTime > this.CACHE_DURATION) { + this.refreshCache(this.xudtUrl); + } + return this.cache.length > 0 ? this.cache : COMPATIBLE_XUDT_TYPE_SCRIPTS; + } + + /** + * Refreshes the cache by fetching data from the provided URL or a default URL. + * + * This method attempts to fetch data from the provided URL or a default URL + * using `Promise.any` to handle multiple potential sources. If the fetch is + * successful, it updates the cache with the fetched data and sets the last + * fetch time to the current timestamp. + * + * @param url - An optional URL to fetch data from. If not provided, a default + * URL (`VERCEL_CELL_DEPS_JSON_STATIC_URL`) will be used. + * @returns A promise that resolves when the cache has been refreshed. + */ + static async refreshCache(url?: string): Promise { + this.xudtUrl = url ?? VERCEL_STATIC_COMPATIBLE_XUDT_URL; + const isExternal = url !== VERCEL_STATIC_COMPATIBLE_XUDT_URL && url !== GITHUB_STATIC_COMPATIBLE_XUDT_URL; + try { + const response = await (isExternal + ? request(this.xudtUrl) + : Promise.any([request(this.xudtUrl), request(GITHUB_STATIC_COMPATIBLE_XUDT_URL)])); + if (response && response.data) { + const xudtList = response.data as { codeHash: string }[]; + this.cache = xudtList.map((xudt) => { + return { + codeHash: xudt.codeHash, + hashType: 'type', + } as CKBComponents.Script; + }); + } + this.lastFetchTime = Date.now(); + } catch (error) { + // console.error(error) + } + } +} diff --git a/packages/ckb/src/utils/ckb-tx.ts b/packages/ckb/src/utils/ckb-tx.ts index 69b83080..8aca55d3 100644 --- a/packages/ckb/src/utils/ckb-tx.ts +++ b/packages/ckb/src/utils/ckb-tx.ts @@ -5,7 +5,6 @@ import { CKB_UNIT, UNLOCKABLE_LOCK_SCRIPT, getClusterTypeScript, - getCompatibleXudtTypeScripts, getSporeTypeScript, getTokenMetadataTypeScript, getUtxoAirdropBadgeTypeScript, @@ -15,6 +14,7 @@ import { Hex, IndexerCell, RgbppTokenInfo } from '../types'; import { encodeRgbppTokenInfo, genBtcTimeLockScript } from './rgbpp'; import { Collector } from '../collector'; import { NoLiveCellError } from '../error'; +import { CompatibleXUDTRegistry } from './cell-dep'; export { serializeScript }; @@ -44,8 +44,17 @@ export const isTokenMetadataType = (type: CKBComponents.Script, isMainnet: boole return tokenMetadataType === typeAsset; }; -export const isCompatibleUDTTypesSupported = (type: CKBComponents.Script, isMainnet: boolean): boolean => { - const compatibleXudtTypeBytes = getCompatibleXudtTypeScripts(isMainnet).map((script) => serializeScript(script)); +// +/** + * Checks if the provided UDT (User Defined Token) type script is supported by comparing it against a list of compatible UDT types. + * If you want to get the latest compatible xUDT list, CompatibleXUDTRegistry.refreshCache should be called before the isCompatibleUDTTypesSupported + * + * @param type - The UDT type script to check for compatibility. + * @returns A boolean indicating whether the provided UDT type script is supported. + */ +export const isCompatibleUDTTypesSupported = (type: CKBComponents.Script): boolean => { + const compatibleList = CompatibleXUDTRegistry.getCompatibleTokens(); + const compatibleXudtTypeBytes = compatibleList.map((script) => serializeScript(script)); const typeAsset = serializeScript({ ...type, args: '', @@ -63,7 +72,7 @@ export const isStandardUDTTypeSupported = (type: CKBComponents.Script, isMainnet }; export const isUDTTypeSupported = (type: CKBComponents.Script, isMainnet: boolean): boolean => { - return isStandardUDTTypeSupported(type, isMainnet) || isCompatibleUDTTypesSupported(type, isMainnet); + return isStandardUDTTypeSupported(type, isMainnet) || isCompatibleUDTTypesSupported(type); }; export const isSporeTypeSupported = (type: CKBComponents.Script, isMainnet: boolean): boolean => { diff --git a/tests/rgbpp/xudt/compatible-xudt/1-ckb-leap-btc.ts b/tests/rgbpp/xudt/compatible-xudt/1-ckb-leap-btc.ts index 2dc71e8d..a7af8b88 100644 --- a/tests/rgbpp/xudt/compatible-xudt/1-ckb-leap-btc.ts +++ b/tests/rgbpp/xudt/compatible-xudt/1-ckb-leap-btc.ts @@ -1,6 +1,6 @@ import { serializeScript } from '@nervosnetwork/ckb-sdk-utils'; import { genCkbJumpBtcVirtualTx } from 'rgbpp'; -import { getSecp256k1CellDep, buildRgbppLockArgs } from 'rgbpp/ckb'; +import { getSecp256k1CellDep, buildRgbppLockArgs, CompatibleXUDTRegistry } from 'rgbpp/ckb'; import { CKB_PRIVATE_KEY, isMainnet, collector, ckbAddress, BTC_TESTNET_TYPE } from '../../env'; import { readStepLog } from '../../shared/utils'; @@ -16,6 +16,13 @@ const leapFromCkbToBtc = async ({ outIndex, btcTxId, compatibleXudtTypeScript, t await retry(20, '10s', async () => { const toRgbppLockArgs = buildRgbppLockArgs(outIndex, btcTxId); + // Refresh the cache by fetching the latest compatible xUDT list from the specified URL. + // The default URL is: + // https://raw.githubusercontent.com/utxostack/typeid-contract-cell-deps/main/compatible-udt.json + // You can set your own trusted URL to fetch the compatible xUDT list. + // await CompatibleXUDTRegistry.refreshCache("https://your-own-trusted-compatible-xudt-url"); + await CompatibleXUDTRegistry.refreshCache(); + const ckbRawTx = await genCkbJumpBtcVirtualTx({ collector, fromCkbAddress: ckbAddress, diff --git a/tests/rgbpp/xudt/compatible-xudt/2-btc-transfer.ts b/tests/rgbpp/xudt/compatible-xudt/2-btc-transfer.ts index 9d8a8607..25f60071 100644 --- a/tests/rgbpp/xudt/compatible-xudt/2-btc-transfer.ts +++ b/tests/rgbpp/xudt/compatible-xudt/2-btc-transfer.ts @@ -1,4 +1,4 @@ -import { buildRgbppLockArgs } from 'rgbpp/ckb'; +import { buildRgbppLockArgs, CompatibleXUDTRegistry } from 'rgbpp/ckb'; import { buildRgbppTransferTx } from 'rgbpp'; import { isMainnet, collector, btcService, btcDataSource, BTC_TESTNET_TYPE, btcAccount } from '../../env'; import { getFastestFeeRate, readStepLog, writeStepLog } from '../../shared/utils'; @@ -21,6 +21,13 @@ const transfer = async ({ }: RgbppTransferParams) => { const { retry } = await import('zx'); + // Refresh the cache by fetching the latest compatible xUDT list from the specified URL. + // The default URL is: + // https://raw.githubusercontent.com/utxostack/typeid-contract-cell-deps/main/compatible-udt.json + // You can set your own trusted URL to fetch the compatible xUDT list. + // await CompatibleXUDTRegistry.refreshCache("https://your-own-trusted-compatible-xudt-url"); + await CompatibleXUDTRegistry.refreshCache(); + const feeRate = await getFastestFeeRate(); console.log('feeRate = ', feeRate); diff --git a/tests/rgbpp/xudt/compatible-xudt/3-btc-leap-ckb.ts b/tests/rgbpp/xudt/compatible-xudt/3-btc-leap-ckb.ts index b87f7c78..3bc6a39e 100644 --- a/tests/rgbpp/xudt/compatible-xudt/3-btc-leap-ckb.ts +++ b/tests/rgbpp/xudt/compatible-xudt/3-btc-leap-ckb.ts @@ -1,4 +1,4 @@ -import { buildRgbppLockArgs } from 'rgbpp/ckb'; +import { buildRgbppLockArgs, CompatibleXUDTRegistry } from 'rgbpp/ckb'; import { serializeScript } from '@nervosnetwork/ckb-sdk-utils'; import { genBtcJumpCkbVirtualTx, sendRgbppUtxos } from 'rgbpp'; import { isMainnet, collector, btcService, btcDataSource, btcAccount, BTC_TESTNET_TYPE } from '../../env'; @@ -21,6 +21,13 @@ const leapFromBtcToCKB = async ({ }: LeapToCkbParams) => { const { retry } = await import('zx'); + // Refresh the cache by fetching the latest compatible xUDT list from the specified URL. + // The default URL is: + // https://raw.githubusercontent.com/utxostack/typeid-contract-cell-deps/main/compatible-udt.json + // You can set your own trusted URL to fetch the compatible xUDT list. + // await CompatibleXUDTRegistry.refreshCache("https://your-own-trusted-compatible-xudt-url"); + await CompatibleXUDTRegistry.refreshCache(); + const feeRate = await getFastestFeeRate(); console.log('feeRate = ', feeRate);