From 094589f61232b9185451dcde93a71cdf286d7edd Mon Sep 17 00:00:00 2001 From: Dylan Duan Date: Mon, 13 Jan 2025 11:05:27 +0800 Subject: [PATCH 1/6] feat: Decode unique cell token info and metadata --- package.json | 7 ++++--- pnpm-lock.yaml | 44 ++++++++++++++++++++++++----------------- src/services/ckb.ts | 8 ++++---- src/utils/xudt.ts | 23 +-------------------- test/utils/xudt.test.ts | 19 +++++++++++++++--- 5 files changed, 51 insertions(+), 50 deletions(-) diff --git a/package.json b/package.json index c1156cc7..e9f6be6c 100644 --- a/package.json +++ b/package.json @@ -42,12 +42,13 @@ "@fastify/swagger-ui": "^3.0.0", "@immobiliarelabs/fastify-sentry": "^8.0.1", "@nervosnetwork/ckb-sdk-utils": "^0.109.1", - "@rgbpp-sdk/btc": "0.0.0-snap-20250106033736", - "@rgbpp-sdk/ckb": "0.0.0-snap-20250106033736", - "@rgbpp-sdk/service": "0.0.0-snap-20250106033736", + "@rgbpp-sdk/btc": "0.0.0-snap-20250110025940", + "@rgbpp-sdk/ckb": "0.0.0-snap-20250110025940", + "@rgbpp-sdk/service": "0.0.0-snap-20250110025940", "@sentry/node": "^7.102.1", "@sentry/profiling-node": "^7.102.1", "@spore-sdk/core": "^0.2.0-beta.9", + "@utxostack/metadata": "^0.0.2", "async-retry": "^1.3.3", "awilix": "^10.0.1", "axios": "^1.7.7", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index f6fa03a3..60befe85 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -60,14 +60,14 @@ importers: specifier: ^0.109.1 version: 0.109.4 '@rgbpp-sdk/btc': - specifier: 0.0.0-snap-20250106033736 - version: 0.0.0-snap-20250106033736(@ckb-lumos/lumos@0.22.2) + specifier: 0.0.0-snap-20250110025940 + version: 0.0.0-snap-20250110025940(@ckb-lumos/lumos@0.22.2) '@rgbpp-sdk/ckb': - specifier: 0.0.0-snap-20250106033736 - version: 0.0.0-snap-20250106033736(@ckb-lumos/lumos@0.22.2)(lodash@4.17.21) + specifier: 0.0.0-snap-20250110025940 + version: 0.0.0-snap-20250110025940(@ckb-lumos/lumos@0.22.2)(lodash@4.17.21) '@rgbpp-sdk/service': - specifier: 0.0.0-snap-20250106033736 - version: 0.0.0-snap-20250106033736 + specifier: 0.0.0-snap-20250110025940 + version: 0.0.0-snap-20250110025940 '@sentry/node': specifier: ^7.102.1 version: 7.120.2 @@ -77,6 +77,9 @@ importers: '@spore-sdk/core': specifier: ^0.2.0-beta.9 version: 0.2.1(@ckb-lumos/lumos@0.22.2)(lodash@4.17.21) + '@utxostack/metadata': + specifier: ^0.0.2 + version: 0.0.2 async-retry: specifier: ^1.3.3 version: 1.3.3 @@ -854,14 +857,14 @@ packages: '@polka/url@1.0.0-next.28': resolution: {integrity: sha512-8LduaNlMZGwdZ6qWrKlfa+2M4gahzFkprZiAt2TF8uS0qQgBizKXpXURqvTJ4WtmupWxaLqjRb2UCTe72mu+Aw==} - '@rgbpp-sdk/btc@0.0.0-snap-20250106033736': - resolution: {integrity: sha512-exqUYZ1Eo0APFJ8kDzTY+ckIks8Makr14FGvhHc6VFOiC8X8IqYA+0kuyluLS2oxsyN1HeBJdUwOuwPBJpQaaQ==} + '@rgbpp-sdk/btc@0.0.0-snap-20250110025940': + resolution: {integrity: sha512-pm9Ry4YwmZvg4D/T/E2m8X9/VJW5zYz8K79yQQ5yaPuF8ALGjz1u0JmGte4i/rTm1strk7gc4fgVkfDyDHiTgw==} - '@rgbpp-sdk/ckb@0.0.0-snap-20250106033736': - resolution: {integrity: sha512-eLoT9V1KgyoBHz+f1S/mLqf2Fjs/GrF1kqymEyExn+25RDKD+2lePA9qZD826HRprNT6VQ3pwW/svYZfKdSqew==} + '@rgbpp-sdk/ckb@0.0.0-snap-20250110025940': + resolution: {integrity: sha512-3EQXudkcPPphnZgc4X/ANie1nXkmnuln8SbqzjATtobn7+hICu/1+LVYRJfmnl9+sTyHq3a1BYa71NkrcigrDQ==} - '@rgbpp-sdk/service@0.0.0-snap-20250106033736': - resolution: {integrity: sha512-nSQp4gVFYN5ShefZsag4pMUdOGMTECIGhTjyK4BKFX8YTVlcYb+kbagvwfLpi58XhFP+/YXe1PGWmAHxwaJf6w==} + '@rgbpp-sdk/service@0.0.0-snap-20250110025940': + resolution: {integrity: sha512-oXRb+QmHnHKUpDH7jrtFJGRq1iekGS7KiXu614BRJ8i1jNTec7diEdYr7Mi/6nFjI986eozxIGjtrWdCcwr3ag==} '@rollup/pluginutils@4.2.1': resolution: {integrity: sha512-iKnFXr7NkdZAIHiIWE+BX5ULi/ucVFYWD6TbAV+rZctiRTY2PL6tsIKhoIOaoskiWAkgu+VsbXgUVDNLHf+InQ==} @@ -1155,6 +1158,9 @@ packages: '@ungap/structured-clone@1.2.1': resolution: {integrity: sha512-fEzPV3hSkSMltkw152tJKNARhOupqbH96MZWyRjNaYZOMIzbrTeQDG+MTc6Mr2pgzFQzFxAfmhGDNP5QK++2ZA==} + '@utxostack/metadata@0.0.2': + resolution: {integrity: sha512-cdijFAo8vfDZ6iA8bofT25IZz3djZ45FlnZ/6QHwDH5I3iwf6I/L8mGSTvnxp4I2SnPm8Vhy7PoCdXOrC8Z5SA==} + '@vercel/build-utils@7.11.0': resolution: {integrity: sha512-UFrx1hNIjNJJkd0NZrYfaOrmcWhQmrVsbKe9o3L9jX9J1iufG685wIZ9tFCKKC0Fa2HWbNDNzNxrE5SCAS2lyA==} @@ -4404,13 +4410,13 @@ snapshots: '@polka/url@1.0.0-next.28': {} - '@rgbpp-sdk/btc@0.0.0-snap-20250106033736(@ckb-lumos/lumos@0.22.2)': + '@rgbpp-sdk/btc@0.0.0-snap-20250110025940(@ckb-lumos/lumos@0.22.2)': dependencies: '@bitcoinerlab/secp256k1': 1.2.0 '@ckb-lumos/codec': 0.22.2 '@nervosnetwork/ckb-types': 0.109.3 - '@rgbpp-sdk/ckb': 0.0.0-snap-20250106033736(@ckb-lumos/lumos@0.22.2)(lodash@4.17.21) - '@rgbpp-sdk/service': 0.0.0-snap-20250106033736 + '@rgbpp-sdk/ckb': 0.0.0-snap-20250110025940(@ckb-lumos/lumos@0.22.2)(lodash@4.17.21) + '@rgbpp-sdk/service': 0.0.0-snap-20250110025940 bip32: 4.0.0 bitcoinjs-lib: 6.1.7 ecpair: 2.1.0 @@ -4420,7 +4426,7 @@ snapshots: - '@ckb-lumos/lumos' - debug - '@rgbpp-sdk/ckb@0.0.0-snap-20250106033736(@ckb-lumos/lumos@0.22.2)(lodash@4.17.21)': + '@rgbpp-sdk/ckb@0.0.0-snap-20250110025940(@ckb-lumos/lumos@0.22.2)(lodash@4.17.21)': dependencies: '@ckb-lumos/base': 0.22.2 '@ckb-lumos/codec': 0.22.2 @@ -4428,7 +4434,7 @@ snapshots: '@nervosnetwork/ckb-sdk-core': 0.109.3 '@nervosnetwork/ckb-sdk-utils': 0.109.3 '@nervosnetwork/ckb-types': 0.109.3 - '@rgbpp-sdk/service': 0.0.0-snap-20250106033736 + '@rgbpp-sdk/service': 0.0.0-snap-20250110025940 '@spore-sdk/core': 0.2.1(@ckb-lumos/lumos@0.22.2)(lodash@4.17.21) axios: 1.7.9 camelcase-keys: 7.0.2 @@ -4438,7 +4444,7 @@ snapshots: - debug - lodash - '@rgbpp-sdk/service@0.0.0-snap-20250106033736': + '@rgbpp-sdk/service@0.0.0-snap-20250110025940': dependencies: '@ckb-lumos/base': 0.22.2 '@ckb-lumos/codec': 0.22.2 @@ -4721,6 +4727,8 @@ snapshots: '@ungap/structured-clone@1.2.1': {} + '@utxostack/metadata@0.0.2': {} + '@vercel/build-utils@7.11.0': {} '@vercel/error-utils@2.0.2': {} diff --git a/src/services/ckb.ts b/src/services/ckb.ts index ee7c51fb..bf683b2a 100644 --- a/src/services/ckb.ts +++ b/src/services/ckb.ts @@ -13,7 +13,6 @@ import { UngroupedIndexerTransaction } from '@ckb-lumos/ckb-indexer/lib/type'; import { z } from 'zod'; import * as Sentry from '@sentry/node'; import { - decodeInfoCellData, decodeUDTHashFromInscriptionData, getInscriptionInfoTypeScript, isInscriptionInfoTypeScript, @@ -25,6 +24,7 @@ import { scriptToHash } from '@nervosnetwork/ckb-sdk-utils'; import { Cell } from '../routes/rgbpp/types'; import { uniq } from 'lodash'; import { IS_MAINNET } from '../constants'; +import { decodeTokenInfo, TokenInfo } from '@utxostack/metadata'; export type TransactionWithStatus = Awaited>; @@ -199,7 +199,7 @@ export default class CKBClient { if (!encodeData) { return null; } - const data = decodeInfoCellData(encodeData); + const data = decodeTokenInfo(encodeData); return data; } @@ -221,7 +221,7 @@ export default class CKBClient { if (decodeUDTHashFromInscriptionData(encodeData) !== xudtTypeHash) { return null; } - const data = decodeInfoCellData(encodeData); + const data = decodeTokenInfo(encodeData); return data; } @@ -294,7 +294,7 @@ export default class CKBClient { const typeHash = computeScriptHash(script); const cachedData = await this.dataCache.get(`type:${typeHash}`); if (cachedData) { - return cachedData as ReturnType; + return cachedData as TokenInfo; } const txs = await this.getAllInfoCellTxs(); diff --git a/src/utils/xudt.ts b/src/utils/xudt.ts index 970a24e3..f1323759 100644 --- a/src/utils/xudt.ts +++ b/src/utils/xudt.ts @@ -1,27 +1,6 @@ import { BI } from '@ckb-lumos/lumos'; import { remove0x } from '@rgbpp-sdk/btc'; -import { getUniqueTypeScript, hexToUtf8 } from '@rgbpp-sdk/ckb'; - -// https://github.com/ckb-cell/unique-cell?tab=readme-ov-file#xudt-information -export function decodeInfoCellData(data: string) { - const hex = remove0x(data); - const info = { - decimal: BI.from(`0x${hex.slice(0, 2)}`).toNumber(), - name: '', - symbol: '', - }; - - const nameSize = BI.from(`0x${hex.slice(2, 4)}`).toNumber() * 2; - if (nameSize > 0) { - info.name = hexToUtf8(`0x${hex.slice(4, 4 + nameSize)}`); - } - - const symbolSize = BI.from(`0x${hex.slice(4 + nameSize, 4 + nameSize + 2)}`).toNumber() * 2; - if (symbolSize > 0) { - info.symbol = hexToUtf8(`0x${hex.slice(4 + nameSize + 2, 4 + nameSize + 2 + symbolSize)}`); - } - return info; -} +import { getUniqueTypeScript } from '@rgbpp-sdk/ckb'; export function decodeUDTHashFromInscriptionData(data: string) { try { diff --git a/test/utils/xudt.test.ts b/test/utils/xudt.test.ts index fe15d284..df24b74b 100644 --- a/test/utils/xudt.test.ts +++ b/test/utils/xudt.test.ts @@ -1,15 +1,28 @@ import { describe, expect, test } from 'vitest'; -import { decodeInfoCellData, decodeUDTHashFromInscriptionData } from '../../src/utils/xudt'; +import { decodeUDTHashFromInscriptionData } from '../../src/utils/xudt'; +import { decodeMetadata, decodeTokenInfo } from '@utxostack/metadata'; describe('XUDT utils', () => { - test('decodeInfoCellData: should decode the inscription info cell', async () => { + test('decodeTokenInfo: should decode the inscription info cell', async () => { const data = '0x08094d656d6573436f696e054d454d45538a139905afdd927a56e3dbf2c3993a8d26a69e7ba35f92894460882e3fa6b6ef0040075af0750700000000000000000000ca9a3b00000000000000000000000000'; - const decoded = decodeInfoCellData(data); + const decoded = decodeTokenInfo(data); expect(decoded).toEqual({ decimal: 8, name: 'MemesCoin', symbol: 'MEMES', + totalSupply: BigInt(0), + }); + }); + + test('decodeMetadata: should decode the token metadata', async () => { + const data = + '0x04000000200000000f251aec82b7d329bfe94ac8456fd96c463248aec5551b18fd215ca5dcb94be70300000020000000a8efe3e8d534fbad88251c1f82cf2428f87637a27cfbf28b6365e9b74d895d1802000000100000000000a40731af05000000000000000000'; + const decoded = decodeMetadata(data); + expect(decoded).toEqual({ + issuer: '0xa8efe3e8d534fbad88251c1f82cf2428f87637a27cfbf28b6365e9b74d895d18', + circulatingSupply: BigInt(1600_0000) * BigInt(10 ** 8), + tokenInfoCellTypeHash: '0x0f251aec82b7d329bfe94ac8456fd96c463248aec5551b18fd215ca5dcb94be7', }); }); From 6f4eb6f545bf3241d754e0fdf2a65e88e8d9a464 Mon Sep 17 00:00:00 2001 From: Dylan Duan Date: Mon, 13 Jan 2025 15:19:34 +0800 Subject: [PATCH 2/6] feat: Update getInfoCellData return value --- package.json | 3 +- pnpm-lock.yaml | 10 +++---- src/services/ckb.ts | 67 +++++++++++++++++++++++++++++++++++++-------- 3 files changed, 62 insertions(+), 18 deletions(-) diff --git a/package.json b/package.json index e9f6be6c..87d65b3b 100644 --- a/package.json +++ b/package.json @@ -9,6 +9,7 @@ "start": "node ./dist/src/index.js", "build": "tsc -p tsconfig.json", "test": "vitest", + "format": "eslint --fix --ext .ts && prettier --write '**/*.ts'", "coverage": "vitest run --coverage", "postinstall": "npx simple-git-hooks" }, @@ -48,7 +49,7 @@ "@sentry/node": "^7.102.1", "@sentry/profiling-node": "^7.102.1", "@spore-sdk/core": "^0.2.0-beta.9", - "@utxostack/metadata": "^0.0.2", + "@utxostack/metadata": "^0.0.3", "async-retry": "^1.3.3", "awilix": "^10.0.1", "axios": "^1.7.7", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 60befe85..89c09161 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -78,8 +78,8 @@ importers: specifier: ^0.2.0-beta.9 version: 0.2.1(@ckb-lumos/lumos@0.22.2)(lodash@4.17.21) '@utxostack/metadata': - specifier: ^0.0.2 - version: 0.0.2 + specifier: ^0.0.3 + version: 0.0.3 async-retry: specifier: ^1.3.3 version: 1.3.3 @@ -1158,8 +1158,8 @@ packages: '@ungap/structured-clone@1.2.1': resolution: {integrity: sha512-fEzPV3hSkSMltkw152tJKNARhOupqbH96MZWyRjNaYZOMIzbrTeQDG+MTc6Mr2pgzFQzFxAfmhGDNP5QK++2ZA==} - '@utxostack/metadata@0.0.2': - resolution: {integrity: sha512-cdijFAo8vfDZ6iA8bofT25IZz3djZ45FlnZ/6QHwDH5I3iwf6I/L8mGSTvnxp4I2SnPm8Vhy7PoCdXOrC8Z5SA==} + '@utxostack/metadata@0.0.3': + resolution: {integrity: sha512-/OPotiMgvvk7nnx9rv/ZMM+43VsEarKwvwex21BVYl4TzfGGu0eCkkgysB0IwTAVLV+AFGZyqzFsndW3tnN54Q==} '@vercel/build-utils@7.11.0': resolution: {integrity: sha512-UFrx1hNIjNJJkd0NZrYfaOrmcWhQmrVsbKe9o3L9jX9J1iufG685wIZ9tFCKKC0Fa2HWbNDNzNxrE5SCAS2lyA==} @@ -4727,7 +4727,7 @@ snapshots: '@ungap/structured-clone@1.2.1': {} - '@utxostack/metadata@0.0.2': {} + '@utxostack/metadata@0.0.3': {} '@vercel/build-utils@7.11.0': {} diff --git a/src/services/ckb.ts b/src/services/ckb.ts index bf683b2a..4a8efdc0 100644 --- a/src/services/ckb.ts +++ b/src/services/ckb.ts @@ -4,6 +4,7 @@ import { getUniqueTypeScript, getXudtTypeScript, isScriptEqual, + isTokenMetadataType, sendCkbTx, } from '@rgbpp-sdk/ckb'; import { Cradle } from '../container'; @@ -24,7 +25,7 @@ import { scriptToHash } from '@nervosnetwork/ckb-sdk-utils'; import { Cell } from '../routes/rgbpp/types'; import { uniq } from 'lodash'; import { IS_MAINNET } from '../constants'; -import { decodeTokenInfo, TokenInfo } from '@utxostack/metadata'; +import { decodeMetadata, decodeTokenInfo, Metadata, TokenInfo } from '@utxostack/metadata'; export type TransactionWithStatus = Awaited>; @@ -147,6 +148,7 @@ export class CKBRpcError extends Error { } } +type TokenInfoMetadata = TokenInfo | (TokenInfo & Metadata); export default class CKBClient { public rpc: RPC; public indexer: Indexer; @@ -183,7 +185,7 @@ export default class CKBClient { * @param index - the index of the unique cell in the transaction * @param xudtTypeScript - the xudt type script * reference: - * - https://github.com/ckb-cell/unique-cell + * - https://github.com/utxostack/unique-cell/metadata */ public getUniqueCellData(tx: TransactionWithStatus, index: number, xudtTypeScript: Script) { // find the xudt cell index in the transaction @@ -203,6 +205,32 @@ export default class CKBClient { return data; } + /** + * Get the token metadata data of the given xudt type script from the transaction + * @param tx - the ckb transaction that contains the token metadata cell + * @param index - the index of the token metadata cell in the transaction + * @param xudtTypeScript - the xudt type script + * reference: + * - https://github.com/utxostack/unique-cell/metadata + */ + public getTokenMetadataData(tx: TransactionWithStatus, index: number, xudtTypeScript: Script) { + // find the xudt cell index in the transaction + // generally, the xudt cell and token metadata cell are in the same transaction + const xudtCellIndex = tx.transaction.outputs.findIndex((cell) => { + return cell.type && isScriptEqual(cell.type, xudtTypeScript); + }); + if (xudtCellIndex === -1) { + return null; + } + + const encodeData = tx.transaction.outputsData[index]; + if (!encodeData) { + return null; + } + const data = decodeMetadata(encodeData); + return data; + } + /** * Get the inscription cell data of the given xudt type script from the transaction * @param tx - the ckb transaction that contains the inscription cell @@ -290,26 +318,41 @@ export default class CKBClient { * Get the unique cell of the given xudt type * @param script - the xudt type script */ - public async getInfoCellData(script: Script) { + public async getInfoCellData(script: Script): Promise { const typeHash = computeScriptHash(script); const cachedData = await this.dataCache.get(`type:${typeHash}`); if (cachedData) { - return cachedData as TokenInfo; + return cachedData as TokenInfoMetadata; } + let infoData: TokenInfoMetadata | null = null; const txs = await this.getAllInfoCellTxs(); for (const tx of txs) { - // check if the unique cell is the info cell of the xudt type - const uniqueCellIndex = tx.transaction.outputs.findIndex((cell) => { - return cell.type && isUniqueCellTypeScript(cell.type, IS_MAINNET); - }); + // check if the unique cell is one of the info cells of the xudt type + const uniqueCellIndex = tx.transaction.outputs.findIndex( + (cell) => cell.type && isUniqueCellTypeScript(cell.type, IS_MAINNET), + ); if (uniqueCellIndex !== -1) { - const infoCellData = this.getUniqueCellData(tx, uniqueCellIndex, script); - if (infoCellData) { - await this.dataCache.set(`type:${typeHash}`, infoCellData); - return infoCellData; + infoData = this.getUniqueCellData(tx, uniqueCellIndex, script); + if (infoData) { + // check if the token metadata cell is one of the info cells of the xudt type + const metadataCellIndex = tx.transaction.outputs.findIndex( + (cell) => cell.type && isTokenMetadataType(cell.type, IS_MAINNET), + ); + if (metadataCellIndex !== -1) { + const metadataData = this.getTokenMetadataData(tx, metadataCellIndex, script); + if (metadataData) { + infoData = { + ...infoData, + ...metadataData, + }; + } + } + await this.dataCache.set(`type:${typeHash}`, infoData); + return infoData; } } + // check if the inscription cell is the info cell of the xudt type const inscriptionCellIndex = tx.transaction.outputs.findIndex((cell) => { return cell.type && isInscriptionInfoTypeScript(cell.type, IS_MAINNET); From 97e153beb0f0c24590bbd540b60cc357b5694b9a Mon Sep 17 00:00:00 2001 From: Dylan Duan Date: Mon, 13 Jan 2025 16:31:29 +0800 Subject: [PATCH 3/6] fix: Update token info and metadata bigint data type --- package.json | 2 +- pnpm-lock.yaml | 10 +++++----- src/services/ckb.ts | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/package.json b/package.json index 87d65b3b..0f8cc09e 100644 --- a/package.json +++ b/package.json @@ -49,7 +49,7 @@ "@sentry/node": "^7.102.1", "@sentry/profiling-node": "^7.102.1", "@spore-sdk/core": "^0.2.0-beta.9", - "@utxostack/metadata": "^0.0.3", + "@utxostack/metadata": "^0.0.5", "async-retry": "^1.3.3", "awilix": "^10.0.1", "axios": "^1.7.7", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 89c09161..dce11399 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -78,8 +78,8 @@ importers: specifier: ^0.2.0-beta.9 version: 0.2.1(@ckb-lumos/lumos@0.22.2)(lodash@4.17.21) '@utxostack/metadata': - specifier: ^0.0.3 - version: 0.0.3 + specifier: ^0.0.5 + version: 0.0.5 async-retry: specifier: ^1.3.3 version: 1.3.3 @@ -1158,8 +1158,8 @@ packages: '@ungap/structured-clone@1.2.1': resolution: {integrity: sha512-fEzPV3hSkSMltkw152tJKNARhOupqbH96MZWyRjNaYZOMIzbrTeQDG+MTc6Mr2pgzFQzFxAfmhGDNP5QK++2ZA==} - '@utxostack/metadata@0.0.3': - resolution: {integrity: sha512-/OPotiMgvvk7nnx9rv/ZMM+43VsEarKwvwex21BVYl4TzfGGu0eCkkgysB0IwTAVLV+AFGZyqzFsndW3tnN54Q==} + '@utxostack/metadata@0.0.5': + resolution: {integrity: sha512-lMU7qdEnNJUsspGDKI896uETpOEinBZchgNmEvWvXY5smU9H85mP8J/oh2Vt3K93MYv/LJNH4Ao49LO0A+UhTw==} '@vercel/build-utils@7.11.0': resolution: {integrity: sha512-UFrx1hNIjNJJkd0NZrYfaOrmcWhQmrVsbKe9o3L9jX9J1iufG685wIZ9tFCKKC0Fa2HWbNDNzNxrE5SCAS2lyA==} @@ -4727,7 +4727,7 @@ snapshots: '@ungap/structured-clone@1.2.1': {} - '@utxostack/metadata@0.0.3': {} + '@utxostack/metadata@0.0.5': {} '@vercel/build-utils@7.11.0': {} diff --git a/src/services/ckb.ts b/src/services/ckb.ts index 4a8efdc0..d9b5d0f8 100644 --- a/src/services/ckb.ts +++ b/src/services/ckb.ts @@ -148,7 +148,7 @@ export class CKBRpcError extends Error { } } -type TokenInfoMetadata = TokenInfo | (TokenInfo & Metadata); +type TokenInfoMetadata = TokenInfo & Partial; export default class CKBClient { public rpc: RPC; public indexer: Indexer; From 4fa78befeb1850022b11c2ad89df913c3fbced2d Mon Sep 17 00:00:00 2001 From: Dylan Duan Date: Mon, 13 Jan 2025 17:29:50 +0800 Subject: [PATCH 4/6] Fix unit tests error --- package.json | 2 +- pnpm-lock.yaml | 10 +++++----- test/utils/xudt.test.ts | 19 +++++++++++++------ 3 files changed, 19 insertions(+), 12 deletions(-) diff --git a/package.json b/package.json index 0f8cc09e..17eaec35 100644 --- a/package.json +++ b/package.json @@ -49,7 +49,7 @@ "@sentry/node": "^7.102.1", "@sentry/profiling-node": "^7.102.1", "@spore-sdk/core": "^0.2.0-beta.9", - "@utxostack/metadata": "^0.0.5", + "@utxostack/metadata": "^0.0.6", "async-retry": "^1.3.3", "awilix": "^10.0.1", "axios": "^1.7.7", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index dce11399..bd179a6f 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -78,8 +78,8 @@ importers: specifier: ^0.2.0-beta.9 version: 0.2.1(@ckb-lumos/lumos@0.22.2)(lodash@4.17.21) '@utxostack/metadata': - specifier: ^0.0.5 - version: 0.0.5 + specifier: ^0.0.6 + version: 0.0.6 async-retry: specifier: ^1.3.3 version: 1.3.3 @@ -1158,8 +1158,8 @@ packages: '@ungap/structured-clone@1.2.1': resolution: {integrity: sha512-fEzPV3hSkSMltkw152tJKNARhOupqbH96MZWyRjNaYZOMIzbrTeQDG+MTc6Mr2pgzFQzFxAfmhGDNP5QK++2ZA==} - '@utxostack/metadata@0.0.5': - resolution: {integrity: sha512-lMU7qdEnNJUsspGDKI896uETpOEinBZchgNmEvWvXY5smU9H85mP8J/oh2Vt3K93MYv/LJNH4Ao49LO0A+UhTw==} + '@utxostack/metadata@0.0.6': + resolution: {integrity: sha512-oech0S5HUFMhbrVNk9jEIXi3L8It23bTGcRiC3m30eyn0AtwWlMJyj49mC//4hgLKUFEmVhVSjTKsrYY2wSmhg==} '@vercel/build-utils@7.11.0': resolution: {integrity: sha512-UFrx1hNIjNJJkd0NZrYfaOrmcWhQmrVsbKe9o3L9jX9J1iufG685wIZ9tFCKKC0Fa2HWbNDNzNxrE5SCAS2lyA==} @@ -4727,7 +4727,7 @@ snapshots: '@ungap/structured-clone@1.2.1': {} - '@utxostack/metadata@0.0.5': {} + '@utxostack/metadata@0.0.6': {} '@vercel/build-utils@7.11.0': {} diff --git a/test/utils/xudt.test.ts b/test/utils/xudt.test.ts index df24b74b..f963d58c 100644 --- a/test/utils/xudt.test.ts +++ b/test/utils/xudt.test.ts @@ -4,14 +4,21 @@ import { decodeMetadata, decodeTokenInfo } from '@utxostack/metadata'; describe('XUDT utils', () => { test('decodeTokenInfo: should decode the inscription info cell', async () => { - const data = - '0x08094d656d6573436f696e054d454d45538a139905afdd927a56e3dbf2c3993a8d26a69e7ba35f92894460882e3fa6b6ef0040075af0750700000000000000000000ca9a3b00000000000000000000000000'; - const decoded = decodeTokenInfo(data); - expect(decoded).toEqual({ + const data1 = '0x08094d656d6573436f696e054d454d4553'; + const decoded1 = decodeTokenInfo(data1); + expect(decoded1).toEqual({ + decimal: 8, + name: 'MemesCoin', + symbol: 'MEMES', + }); + + const data2 = '0x08094d656d6573436f696e054d454d455301000000100000000040075af07507000000000000000000'; + const decoded2 = decodeTokenInfo(data2); + expect(decoded2).toEqual({ decimal: 8, name: 'MemesCoin', symbol: 'MEMES', - totalSupply: BigInt(0), + totalSupply: '0x775f05a074000', }); }); @@ -21,7 +28,7 @@ describe('XUDT utils', () => { const decoded = decodeMetadata(data); expect(decoded).toEqual({ issuer: '0xa8efe3e8d534fbad88251c1f82cf2428f87637a27cfbf28b6365e9b74d895d18', - circulatingSupply: BigInt(1600_0000) * BigInt(10 ** 8), + circulatingSupply: `0x${BigInt(1600_0000_0000_0000).toString(16)}`, tokenInfoCellTypeHash: '0x0f251aec82b7d329bfe94ac8456fd96c463248aec5551b18fd215ca5dcb94be7', }); }); From 2b6cdf00ccc60616b85e749478bab97767c16556 Mon Sep 17 00:00:00 2001 From: Dylan Duan Date: Mon, 13 Jan 2025 19:16:29 +0800 Subject: [PATCH 5/6] test: Add UTXO-AIRDROP token test --- test/__fixtures__/rgbpp-utxo-pairs.mock.json | 37 +++++++++++++++++++ .../rgbpp/__snapshots__/address.test.ts.snap | 23 ++++++++++++ .../services/__snapshots__/rgbpp.test.ts.snap | 16 ++++++++ 3 files changed, 76 insertions(+) diff --git a/test/__fixtures__/rgbpp-utxo-pairs.mock.json b/test/__fixtures__/rgbpp-utxo-pairs.mock.json index f956630e..bac29670 100644 --- a/test/__fixtures__/rgbpp-utxo-pairs.mock.json +++ b/test/__fixtures__/rgbpp-utxo-pairs.mock.json @@ -442,5 +442,42 @@ "txIndex": "0x1" } ] + }, + { + "utxo": { + "txid": "13618e2a8e5b091fd1381cd7d67c3dececb2727fdbeb9887965b577b6c2239ab", + "vout": 0, + "value": 546, + "status": { + "confirmed": true, + "block_height": 2816899, + "block_hash": "000000000000000838d3bf989d702597827cd9830b8bedeaba49a5f2621053fa", + "block_time": 1716348699 + } + }, + "cells": [ + { + "cellOutput": { + "capacity": "0x1b381be34e00", + "lock": { + "codeHash": "0x9bd7e06f3ecf4be0f2fcd2188b23f1b9fcc88e5d4b65a8637b17723bbda3cce8", + "args": "0x9787495f518fec240d7857067f3016daf705286d", + "hashType": "type" + }, + "type": { + "codeHash": "0xf5da9003e31fa9301a3915fe304de9bdb80524b5f0d8fc325fb699317998ee7a", + "args": "0xa63d308c04b4c075eb1d7d5cac891cf20276e3ddb2ec855fc981c88d8134dbe2", + "hashType": "type" + } + }, + "data": "0x00000000000000000000000000000000", + "outPoint": { + "txHash": "0xe4e156943c82ee5500d39343a01dda0c48946a6000f449c58ac91708576cf669", + "index": "0x2" + }, + "blockNumber": "0xf17dd7", + "txIndex": "0x1" + } + ] } ] diff --git a/test/routes/rgbpp/__snapshots__/address.test.ts.snap b/test/routes/rgbpp/__snapshots__/address.test.ts.snap index ba974ccf..ecf4753a 100644 --- a/test/routes/rgbpp/__snapshots__/address.test.ts.snap +++ b/test/routes/rgbpp/__snapshots__/address.test.ts.snap @@ -5940,6 +5940,29 @@ exports[`/:btc_address/assets 1`] = ` "txIndex": "0x1", "typeHash": "0xf0d58aed78476f0aa4fab18f45de1fdcf4f42426fb03570de236dfd36638f3ed", }, + { + "blockNumber": "0xf17dd7", + "cellOutput": { + "capacity": "0x1b381be34e00", + "lock": { + "args": "0x9787495f518fec240d7857067f3016daf705286d", + "codeHash": "0x9bd7e06f3ecf4be0f2fcd2188b23f1b9fcc88e5d4b65a8637b17723bbda3cce8", + "hashType": "type", + }, + "type": { + "args": "0xa63d308c04b4c075eb1d7d5cac891cf20276e3ddb2ec855fc981c88d8134dbe2", + "codeHash": "0xf5da9003e31fa9301a3915fe304de9bdb80524b5f0d8fc325fb699317998ee7a", + "hashType": "type", + }, + }, + "data": "0x00000000000000000000000000000000", + "outPoint": { + "index": "0x2", + "txHash": "0xe4e156943c82ee5500d39343a01dda0c48946a6000f449c58ac91708576cf669", + }, + "txIndex": "0x1", + "typeHash": "0xe5ee2fdd79aaa218bd74a821c305fa40305408fae2dbfedf8243ea2b4d7af8e4", + }, ] `; diff --git a/test/services/__snapshots__/rgbpp.test.ts.snap b/test/services/__snapshots__/rgbpp.test.ts.snap index f0cdc96d..f9eaa375 100644 --- a/test/services/__snapshots__/rgbpp.test.ts.snap +++ b/test/services/__snapshots__/rgbpp.test.ts.snap @@ -38,6 +38,22 @@ exports[`RgbppCollector > getRgbppBalanceByCells: should return the rgbpp balanc "hashType": "type", }, }, + "0xe5ee2fdd79aaa218bd74a821c305fa40305408fae2dbfedf8243ea2b4d7af8e4": { + "amount": "0x0", + "circulatingSupply": "0x0", + "decimal": 0, + "issuer": "0x75f11d14d0d8dfc084ce777961cfd9e75ace8c77282217bcc16f57533ea2ee09", + "name": "Pre-claim -Airdrop Badge", + "symbol": "UTXO-AIRDROP", + "tokenInfoCellTypeHash": "0xb18540dcfde52a96232ec865401284b8b94e1692db54f45803e90d93a4e0d9c7", + "totalSupply": "0x3e8", + "type_hash": "0xe5ee2fdd79aaa218bd74a821c305fa40305408fae2dbfedf8243ea2b4d7af8e4", + "type_script": { + "args": "0xa63d308c04b4c075eb1d7d5cac891cf20276e3ddb2ec855fc981c88d8134dbe2", + "codeHash": "0xf5da9003e31fa9301a3915fe304de9bdb80524b5f0d8fc325fb699317998ee7a", + "hashType": "type", + }, + }, } `; From 0a775ffa0af8aca20359013fa42921f4fbd829b8 Mon Sep 17 00:00:00 2001 From: Dylan Duan Date: Tue, 14 Jan 2025 19:29:21 +0800 Subject: [PATCH 6/6] chore: Bump version to v2.5.2 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 17eaec35..c9102256 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "btc-assets-api", - "version": "2.4.2", + "version": "2.5.2", "title": "Bitcoin/RGB++ Assets API", "description": "", "main": "index.js",