Migrate From ckb-sdk-core to Lumos
Summary
To avoid splitting the development ecosystem, ckb-sdk-js
will be migrated to lumos
, please check out the migration list.
If you are using any function that is not on this list, please refer to the lumos
documentation.
reference:
Transaction migration example list
Simple transaction migration example
before: ckb-sdk-js simple example
after:
simple transaction with lumos example
import { Script, Address, config, Indexer, RPC, hd, commons } from "@ckb-lumos/lumos"
import { TransactionSkeleton, encodeToAddress, sealTransaction } from "@ckb-lumos/helpers"
// ckt
const CKB_RPC_URL = "https://testnet.ckb.dev/rpc"
const CKB_INDEXER_URL = "https://testnet.ckb.dev/indexer"
const rpc = new RPC(CKB_RPC_URL)
const indexer = new Indexer(CKB_INDEXER_URL, CKB_RPC_URL)
const CONFIG = config.createConfig({
PREFIX: "ckt",
SCRIPTS: {
...config.predefined.AGGRON4.SCRIPTS,
},
})
config.initializeConfig(CONFIG)
export const generateSECP256K1Account = (privKey: string) => {
const pubKey = hd.key.privateToPublic(privKey)
const args = hd.key.publicKeyToBlake160(pubKey)
const template = CONFIG.SCRIPTS["SECP256K1_BLAKE160"]!
const lockScript = {
codeHash: template.CODE_HASH,
hashType: template.HASH_TYPE,
args: args,
}
const address = encodeToAddress(lockScript, { config: CONFIG })
return {
lockScript,
address,
pubKey,
privKey,
}
}
const bootstrap = async () => {
const alice = generateSECP256K1Account("0xd00c06bfd800d27397002dca6fb0993d5ba6399b4238b2f29ee9deb97593d2bc")
const bob = generateSECP256K1Account("0x63d86723e08f0f813a36ce6aa123bb2289d90680ae1e99d4de8cdb334553f24d")
let txSkeleton = TransactionSkeleton({ cellProvider: indexer })
txSkeleton = await commons.secp256k1Blake160.transfer(txSkeleton, alice.address, bob.address, BigInt(1000 * 10 ** 8))
txSkeleton = await commons.secp256k1Blake160.payFee(txSkeleton, alice.address, BigInt(1 * 10 ** 8), {
config: CONFIG,
})
txSkeleton = commons.common.prepareSigningEntries(txSkeleton)
const message = txSkeleton.get("signingEntries").get(0)?.message
const Sig = hd.key.signRecoverable(message!, alice.privKey)
const tx = sealTransaction(txSkeleton, [Sig])
const hash = await rpc.sendTransaction(tx, "passthrough")
console.log("The transaction hash is", hash)
}
bootstrap()
sudt transaction migration example
before: ckb-sdk-js sudt example
after:
sudt transaction with lumos example
import { config, Indexer, RPC, hd, commons } from "@ckb-lumos/lumos"
import { TransactionSkeleton, encodeToAddress, sealTransaction } from "@ckb-lumos/helpers"
const CKB_RPC_URL = "https://testnet.ckb.dev/rpc"
const CKB_INDEXER_URL = "https://testnet.ckb.dev/indexer"
const rpc = new RPC(CKB_RPC_URL)
const indexer = new Indexer(CKB_INDEXER_URL, CKB_RPC_URL)
const CONFIG = config.createConfig({
PREFIX: "ckt",
SCRIPTS: {
...config.predefined.AGGRON4.SCRIPTS,
ANYONE_CAN_PAY: {
CODE_HASH: "0x3419a1c09eb2567f6552ee7a8ecffd64155cffe0f1796e6e61ec088d740c1356",
HASH_TYPE: "type",
TX_HASH: "0xec26b0f85ed839ece5f11c4c4e837ec359f5adc4420410f6453b1f6b60fb96a6",
INDEX: "0x0",
DEP_TYPE: "code",
},
},
})
config.initializeConfig(CONFIG)
export const generateSECP256K1Account = (privKey: string) => {
const pubKey = hd.key.privateToPublic(privKey)
const args = hd.key.publicKeyToBlake160(pubKey)
const template = CONFIG.SCRIPTS["SECP256K1_BLAKE160"]!
const lockScript = {
codeHash: template.CODE_HASH,
hashType: template.HASH_TYPE,
args: args,
}
const address = encodeToAddress(lockScript, { config: CONFIG })
return {
lockScript,
address,
pubKey,
privKey,
}
}
export const issueToken = async (fromAddress: string, privKey: string) => {
let txSkeleton = TransactionSkeleton({ cellProvider: indexer })
txSkeleton = await commons.sudt.issueToken(txSkeleton, fromAddress, BigInt(10000))
txSkeleton = await commons.secp256k1Blake160.payFee(txSkeleton, fromAddress, BigInt(1 * 10 ** 8))
txSkeleton = commons.common.prepareSigningEntries(txSkeleton)
const message = txSkeleton.get("signingEntries").get(0)?.message
const Sig = hd.key.signRecoverable(message!, privKey)
const tx = sealTransaction(txSkeleton, [Sig])
const hash = await rpc.sendTransaction(tx, "passthrough")
return hash
}
export const transferToken = async (fromAddress: string, toAddress: string, privKey: string) => {
const token = commons.sudt.ownerForSudt(fromAddress)
let txSkeleton = TransactionSkeleton({ cellProvider: indexer })
txSkeleton = await commons.sudt.transfer(txSkeleton, [fromAddress], token, toAddress, BigInt(1000))
txSkeleton = await commons.secp256k1Blake160.payFee(txSkeleton, fromAddress, BigInt(1 * 10 ** 8))
txSkeleton = commons.common.prepareSigningEntries(txSkeleton)
const message = txSkeleton.get("signingEntries").get(0)?.message
const Sig = hd.key.signRecoverable(message!, privKey)
const tx = sealTransaction(txSkeleton, [Sig])
const hash = await rpc.sendTransaction(tx, "passthrough")
return hash
}
const bootstrap = async () => {
const alice = generateSECP256K1Account("0xd00c06bfd800d27397002dca6fb0993d5ba6399b4238b2f29ee9deb97593d2bc")
const bob = generateSECP256K1Account("0x63d86723e08f0f813a36ce6aa123bb2289d90680ae1e99d4de8cdb334553f24d")
const issueTxHash = await issueToken(bob.address, bob.privKey)
console.log("issueTxHash is", issueTxHash)
// Wait a minute.
const transferTxHash = await transferToken(alice.address, bob.address, alice.privKey)
console.log("transferTxHash is", transferTxHash)
}
bootstrap()
dao transaction migration example
before: ckb-sdk-js dao example
after:
dao transaction with lumos example
import { BI, OutPoint, Cell, config, Indexer, RPC, hd, commons } from "@ckb-lumos/lumos"
import { TransactionSkeleton, encodeToAddress, sealTransaction } from "@ckb-lumos/helpers"
// ckt
const CKB_RPC_URL = "https://testnet.ckb.dev/rpc"
const CKB_INDEXER_URL = "https://testnet.ckb.dev/indexer"
const rpc = new RPC(CKB_RPC_URL)
const indexer = new Indexer(CKB_INDEXER_URL, CKB_RPC_URL)
const CONFIG = config.createConfig({
PREFIX: "ckt",
SCRIPTS: {
...config.predefined.AGGRON4.SCRIPTS,
},
})
config.initializeConfig(CONFIG)
export const generateSECP256K1Account = (privKey: string) => {
const pubKey = hd.key.privateToPublic(privKey)
const args = hd.key.publicKeyToBlake160(pubKey)
const template = CONFIG.SCRIPTS["SECP256K1_BLAKE160"]!
const lockScript = {
codeHash: template.CODE_HASH,
hashType: template.HASH_TYPE,
args: args,
}
const address = encodeToAddress(lockScript, { config: CONFIG })
return {
lockScript,
address,
pubKey,
privKey,
}
}
export const getCellByOutPoint = async (outpoint: OutPoint): Promise<Cell> => {
const tx = await rpc.get_transaction(outpoint.txHash)
if (!tx) {
throw new Error(`not found tx: ${outpoint.txHash}`)
}
const block = await rpc.getBlock(tx.txStatus.blockHash!)
return {
cellOutput: tx.transaction.outputs[0],
data: tx.transaction.outputsData[0],
outPoint: outpoint,
blockHash: tx.txStatus.blockHash,
blockNumber: block!.header.number,
}
}
export const deposit = async (fromAddress: string, privKey: string) => {
let txSkeleton = TransactionSkeleton({ cellProvider: indexer })
txSkeleton = await commons.dao.deposit(txSkeleton, fromAddress, fromAddress, BigInt(1000 * 10 ** 8))
txSkeleton = await commons.secp256k1Blake160.payFee(txSkeleton, fromAddress, BigInt(1 * 10 ** 8))
txSkeleton = commons.common.prepareSigningEntries(txSkeleton)
const message = txSkeleton.get("signingEntries").get(0)?.message
const Sig = hd.key.signRecoverable(message!, privKey)
const tx = sealTransaction(txSkeleton, [Sig])
const hash = await rpc.sendTransaction(tx, "passthrough")
return hash
}
export const withdraw = async (depositOutpoint: OutPoint, fromAddress: string, privKey: string) => {
let txSkeleton = TransactionSkeleton({ cellProvider: indexer })
const depositCell = await getCellByOutPoint(depositOutpoint)
txSkeleton = await commons.dao.withdraw(txSkeleton, depositCell, fromAddress)
txSkeleton = await commons.secp256k1Blake160.payFee(txSkeleton, fromAddress, BigInt(1 * 10 ** 8))
txSkeleton = commons.common.prepareSigningEntries(txSkeleton)
const message = txSkeleton.get("signingEntries").get(0)?.message
const Sig = hd.key.signRecoverable(message!, privKey)
const tx = sealTransaction(txSkeleton, [Sig])
const hash = await rpc.sendTransaction(tx, "passthrough")
return hash
}
export const unlock = async (
depositOutpoint: OutPoint,
withdrawOutpoint: OutPoint,
fromAddress: string,
privKey: string
) => {
let txSkeleton = TransactionSkeleton({ cellProvider: indexer })
const depositCell = await getCellByOutPoint(depositOutpoint)
const withdrawCell = await getCellByOutPoint(withdrawOutpoint)
txSkeleton = await commons.dao.unlock(txSkeleton, depositCell, withdrawCell, fromAddress, fromAddress)
txSkeleton = await commons.secp256k1Blake160.payFee(txSkeleton, fromAddress, BI.from(1 * 10 ** 8))
txSkeleton = commons.common.prepareSigningEntries(txSkeleton)
const message = txSkeleton.get("signingEntries").get(0)?.message
const Sig = hd.key.signRecoverable(message!, privKey)
const tx = sealTransaction(txSkeleton, [Sig])
const hash = await rpc.sendTransaction(tx, "passthrough")
return hash
}
const bootstrap = async () => {
const alice = generateSECP256K1Account("0xd00c06bfd800d27397002dca6fb0993d5ba6399b4238b2f29ee9deb97593d2bc")
const depositTx = await deposit(alice.address, alice.privKey)
const depositOutpoint = { txHash: depositTx, index: "0x0" }
const withdrawTx = await withdraw(depositOutpoint, alice.address, alice.privKey)
const withdrawOutpoint = { txHash: withdrawTx, index: "0x0" }
// wait 180 epoch
const unlockTx = await unlock(depositOutpoint, withdrawOutpoint, alice.address, alice.privKey)
console.log("unlockTx is", unlockTx)
}
bootstrap()