Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add UTXOAirdropBadge Testnet deployment information #294

Merged
merged 11 commits into from
Jan 16, 2025
10 changes: 10 additions & 0 deletions .changeset/breezy-pumpkins-swim.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
---
'@rgbpp-sdk/service': minor
'@rgbpp-sdk/ckb': minor
ShookLyngs marked this conversation as resolved.
Show resolved Hide resolved
---

Add UTXOAirdropBadge testnet deployment information

- Add UTXOAirdropBadge and metadata Testnet deployment information
- Fetch UTXOAirdropBadge and metadata Testnet deployment information from GitHub and Vercel server
- Add `isUtxoAirdropBadgeType` and `isTokenMetadataType` for `btc-assets-api` to encode the token information and metadata of the UTXOAirdropBadge
12 changes: 12 additions & 0 deletions .changeset/mighty-pumas-grab.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
---
'@rgbpp-sdk/service': minor
'@rgbpp-sdk/btc': minor
'@rgbpp-sdk/ckb': minor
---

Add `OfflineBtcAssetsDataSource` and `OfflineCollector` to offline build RGB++ transactions

- Add `OfflineBtcAssetsDataSource` to collect BTC UTXOs to build RGB++ BTC transactions offline
- Add `OfflineCollector` to collect CKB cells to build RGB++ CKB transactions offline
- Improved error handling for `OfflineBtcAssetsDataSource`
- Add examples for RGB++ assets offline launch, transfer, and leap
2 changes: 1 addition & 1 deletion examples/rgbpp/shared/btc-account.ts
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ export async function signAndSendPsbt(
signPsbt(psbt, account);
psbt.finalizeAllInputs();

const tx = psbt.extractTransaction();
const tx = psbt.extractTransaction(true);
const txHex = tx.toHex();

const { txid } = await service.sendBtcTransaction(txHex);
Expand Down
18 changes: 18 additions & 0 deletions examples/rgbpp/xudt/compatible-xudt/assets-api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,4 +28,22 @@ import { btcService } from '../../env';
}),
);
console.log('Standard xUDT info: ', JSON.stringify(info));

const rusdInfo = await btcService.getRgbppAssetInfoByTypeScript(
serializeScript({
codeHash: '0x1142755a044bf2ee358cba9f2da187ce928c91cd4dc8692ded0337efa677d21a',
hashType: 'type',
args: '0x878fcc6f1f08d48e87bb1c3b3d5083f23f8a39c5d5c764f253b55b998526439b',
}),
);
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));
})();
44 changes: 44 additions & 0 deletions packages/ckb/src/constants/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,23 @@ const TestnetInfo = {
outPoint: { txHash: '0x5364b3535965e9eac9a35dd7af8e9e45a61d30a16e115923c032f80b28783e21', index: '0x1' },
depType: 'code',
} as CKBComponents.CellDep,

UtxoAirdropBadgeTypeScript: {
codeHash: '0xf5da9003e31fa9301a3915fe304de9bdb80524b5f0d8fc325fb699317998ee7a',
hashType: 'type',
args: '',
} as CKBComponents.Script,

UtxoAirdropBadgeTypeDep: {
outPoint: { txHash: '0xfa0a6821293cc1ef4ee67a900862208e27f67b98237c9b13bf93c84607c5cd33', index: '0x2' },
depType: 'code',
} as CKBComponents.CellDep,

TokenMetadataTypeScript: {
codeHash: '0x0c7dc8caec145b51b142e13f47fe4262c80628213d1b6c3d9c1aa6a62088804e',
hashType: 'type',
args: '',
} as CKBComponents.Script,
};

const MainnetInfo = {
Expand Down Expand Up @@ -256,6 +273,25 @@ const MainnetInfo = {
},
depType: 'code',
} as CKBComponents.CellDep,

// TODO: Update the UtxoAirdropBadgeTypeScript and UtxoAirdropBadgeTypeDep after the mainnet deployment
UtxoAirdropBadgeTypeScript: {
codeHash: '0xf5da9003e31fa9301a3915fe304de9bdb80524b5f0d8fc325fb699317998ee7a',
hashType: 'type',
args: '',
} as CKBComponents.Script,

UtxoAirdropBadgeTypeDep: {
outPoint: { txHash: '0xfa0a6821293cc1ef4ee67a900862208e27f67b98237c9b13bf93c84607c5cd33', index: '0x2' },
depType: 'code',
} as CKBComponents.CellDep,

// TODO: Update the TokenMetadataTypeScript after the mainnet deployment
TokenMetadataTypeScript: {
codeHash: '0x0c7dc8caec145b51b142e13f47fe4262c80628213d1b6c3d9c1aa6a62088804e',
hashType: 'type',
args: '',
} as CKBComponents.Script,
};

export const UNLOCKABLE_LOCK_SCRIPT = {
Expand Down Expand Up @@ -329,3 +365,11 @@ export const getSporeTypeDep = (isMainnet: boolean) =>

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) =>
isMainnet ? MainnetInfo.UtxoAirdropBadgeTypeDep : TestnetInfo.UtxoAirdropBadgeTypeDep;

export const getTokenMetadataTypeScript = (isMainnet: boolean) =>
isMainnet ? MainnetInfo.TokenMetadataTypeScript : TestnetInfo.TokenMetadataTypeScript;
157 changes: 101 additions & 56 deletions packages/ckb/src/utils/cell-dep.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,70 +3,115 @@ import { fetchTypeIdCellDeps } from './cell-dep';
import { getBtcTimeLockDep, getRgbppLockDep, getUniqueTypeDep, getXudtDep } from '../constants';

describe('dynamic fetch cell dep', () => {
it('fetchTypeIdCellDeps with xudt and unique', async () => {
const isMainnet = false;
const [xudtDep, uniqueDep] = await fetchTypeIdCellDeps(isMainnet, { xudt: true, unique: true });
expect(xudtDep.outPoint?.txHash).toBe(getXudtDep(isMainnet).outPoint?.txHash);
expect(uniqueDep.outPoint?.txHash).toBe(getUniqueTypeDep(isMainnet).outPoint?.txHash);
});
it(
'fetchTypeIdCellDeps with xudt and unique',
async () => {
const isMainnet = false;
const [xudtDep, uniqueDep] = await fetchTypeIdCellDeps(isMainnet, { xudt: true, unique: true });
expect(xudtDep.outPoint?.txHash).toBe(getXudtDep(isMainnet).outPoint?.txHash);
expect(uniqueDep.outPoint?.txHash).toBe(getUniqueTypeDep(isMainnet).outPoint?.txHash);
},
{ timeout: 10000 },
);

it('fetchTypeIdCellDeps with rgbpp and config', async () => {
const isMainnet = false;
const [rgbppDep, configDep] = await fetchTypeIdCellDeps(isMainnet, { rgbpp: true });
expect(rgbppDep.outPoint?.txHash).toBe(getRgbppLockDep(isMainnet).outPoint?.txHash);
expect(configDep.outPoint?.index).toBe('0x1');
});
it(
'fetchTypeIdCellDeps with rgbpp and config',
async () => {
const isMainnet = false;
const [rgbppDep, configDep] = await fetchTypeIdCellDeps(isMainnet, { rgbpp: true });
expect(rgbppDep.outPoint?.txHash).toBe(getRgbppLockDep(isMainnet).outPoint?.txHash);
expect(configDep.outPoint?.index).toBe('0x1');
},
{ timeout: 10000 },
);

it('fetchTypeIdCellDeps with rgbpp, config and xudt', async () => {
const isMainnet = false;
const [rgbppDep, configDep, xudtDep] = await fetchTypeIdCellDeps(isMainnet, { rgbpp: true, xudt: true });
expect(rgbppDep.outPoint?.txHash).toBe(getRgbppLockDep(isMainnet).outPoint?.txHash);
expect(configDep.outPoint?.index).toBe('0x1');
expect(xudtDep.outPoint?.txHash).toBe(getXudtDep(isMainnet).outPoint?.txHash);
});
it(
'fetchTypeIdCellDeps with rgbpp, config and xudt',
async () => {
const isMainnet = false;
const [rgbppDep, configDep, xudtDep] = await fetchTypeIdCellDeps(isMainnet, { rgbpp: true, xudt: true });
expect(rgbppDep.outPoint?.txHash).toBe(getRgbppLockDep(isMainnet).outPoint?.txHash);
expect(configDep.outPoint?.index).toBe('0x1');
expect(xudtDep.outPoint?.txHash).toBe(getXudtDep(isMainnet).outPoint?.txHash);
},
{ timeout: 10000 },
);

it('fetchTypeIdCellDeps with btcTime and config', async () => {
const isMainnet = true;
const [btcTimeDep, configDep] = await fetchTypeIdCellDeps(isMainnet, { btcTime: true });
expect(btcTimeDep.outPoint?.txHash).toBe(getBtcTimeLockDep(isMainnet).outPoint?.txHash);
expect(configDep.outPoint?.index).toBe('0x1');
});
it(
'fetchTypeIdCellDeps with btcTime and config',
async () => {
const isMainnet = true;
const [btcTimeDep, configDep] = await fetchTypeIdCellDeps(isMainnet, { btcTime: true });
expect(btcTimeDep.outPoint?.txHash).toBe(getBtcTimeLockDep(isMainnet).outPoint?.txHash);
expect(configDep.outPoint?.index).toBe('0x1');
},
{ timeout: 10000 },
);

it('fetchTypeIdCellDeps with btcTime, config and xudt', async () => {
const isMainnet = true;
const [btcTimeDep, configDep, xudtDep] = await fetchTypeIdCellDeps(isMainnet, { btcTime: true, xudt: true });
expect(btcTimeDep.outPoint?.txHash).toBe(getBtcTimeLockDep(isMainnet).outPoint?.txHash);
expect(configDep.outPoint?.index).toBe('0x1');
expect(xudtDep.outPoint?.txHash).toBe(getXudtDep(isMainnet).outPoint?.txHash);
});
it(
'fetchTypeIdCellDeps with btcTime, config and xudt',
async () => {
const isMainnet = true;
const [btcTimeDep, configDep, xudtDep] = await fetchTypeIdCellDeps(isMainnet, { btcTime: true, xudt: true });
expect(btcTimeDep.outPoint?.txHash).toBe(getBtcTimeLockDep(isMainnet).outPoint?.txHash);
expect(configDep.outPoint?.index).toBe('0x1');
expect(xudtDep.outPoint?.txHash).toBe(getXudtDep(isMainnet).outPoint?.txHash);
},
{ timeout: 10000 },
);

it('fetchTypeIdCellDeps with rgbpp, btcTime, xudt and unique', async () => {
const isMainnet = false;
const cellDeps = await fetchTypeIdCellDeps(isMainnet, { rgbpp: true, btcTime: true, xudt: true, unique: true });
expect(cellDeps[0].outPoint?.txHash).toBe(getRgbppLockDep(isMainnet).outPoint?.txHash);
expect(cellDeps[1].outPoint?.index).toBe('0x1');
it(
'fetchTypeIdCellDeps with rgbpp, btcTime, xudt and unique',
async () => {
const isMainnet = false;
const cellDeps = await fetchTypeIdCellDeps(isMainnet, { rgbpp: true, btcTime: true, xudt: true, unique: true });
expect(cellDeps[0].outPoint?.txHash).toBe(getRgbppLockDep(isMainnet).outPoint?.txHash);
expect(cellDeps[1].outPoint?.index).toBe('0x1');

expect(cellDeps[2].outPoint?.txHash).toBe(getBtcTimeLockDep(isMainnet).outPoint?.txHash);
expect(cellDeps[3].outPoint?.index).toBe('0x1');
expect(cellDeps[2].outPoint?.txHash).toBe(getBtcTimeLockDep(isMainnet).outPoint?.txHash);
expect(cellDeps[3].outPoint?.index).toBe('0x1');

expect(cellDeps[4].outPoint?.txHash).toBe(getXudtDep(isMainnet).outPoint?.txHash);
expect(cellDeps[4].outPoint?.txHash).toBe(getXudtDep(isMainnet).outPoint?.txHash);

expect(cellDeps[5].outPoint?.txHash).toBe(getUniqueTypeDep(isMainnet).outPoint?.txHash);
});
expect(cellDeps[5].outPoint?.txHash).toBe(getUniqueTypeDep(isMainnet).outPoint?.txHash);
},
{ timeout: 10000 },
);

it('fetchTypeIdCellDeps without cell deps', async () => {
const isMainnet = false;
const cellDeps = await fetchTypeIdCellDeps(isMainnet, {});
expect(cellDeps.length).toBe(0);
});
it(
'fetchTypeIdCellDeps without cell deps',
async () => {
const isMainnet = false;
const cellDeps = await fetchTypeIdCellDeps(isMainnet, {});
expect(cellDeps.length).toBe(0);
},
{ timeout: 10000 },
);

it('fetchTypeIdCellDeps with RUSD', async () => {
const isMainnet = false;
const cellDeps = await fetchTypeIdCellDeps(isMainnet, {
xudt: false,
compatibleXudtCodeHashes: ['0x1142755a044bf2ee358cba9f2da187ce928c91cd4dc8692ded0337efa677d21a'],
});
expect(cellDeps[0].outPoint?.txHash).toBe('0xed7d65b9ad3d99657e37c4285d585fea8a5fcaf58165d54dacf90243f911548b');
expect(cellDeps[0].outPoint?.index).toBe('0x0');
});
it(
'fetchTypeIdCellDeps with RUSD',
async () => {
const isMainnet = false;
const cellDeps = await fetchTypeIdCellDeps(isMainnet, {
xudt: false,
compatibleXudtCodeHashes: ['0x1142755a044bf2ee358cba9f2da187ce928c91cd4dc8692ded0337efa677d21a'],
});
expect(cellDeps[0].outPoint?.txHash).toBe('0xed7d65b9ad3d99657e37c4285d585fea8a5fcaf58165d54dacf90243f911548b');
expect(cellDeps[0].outPoint?.index).toBe('0x0');
},
{ timeout: 10000 },
);

it(
'fetchTypeIdCellDeps with UTXOAirdropBadge',
async () => {
const isMainnet = false;
const cellDeps = await fetchTypeIdCellDeps(isMainnet, {
utxoAirdropBadge: true,
});
expect(cellDeps[0].outPoint?.txHash).toBe('0xfa0a6821293cc1ef4ee67a900862208e27f67b98237c9b13bf93c84607c5cd33');
expect(cellDeps[0].outPoint?.index).toBe('0x2');
},
{ timeout: 10000 },
);
});
Loading
Loading