From b5ad8583930add13bb038b2f1b34c3a437074e98 Mon Sep 17 00:00:00 2001 From: ian Date: Tue, 5 Mar 2024 14:24:58 +0800 Subject: [PATCH] :sparkles: Export tx file for ckb-cli --- src/TransactionPage.js | 1 - src/lib/ckb-address.js | 6 ++++++ src/lib/transaction.js | 40 +++++++++++++++++++++++++++++++++++++++- 3 files changed, 45 insertions(+), 2 deletions(-) diff --git a/src/TransactionPage.js b/src/TransactionPage.js index 1257041..df02305 100644 --- a/src/TransactionPage.js +++ b/src/TransactionPage.js @@ -68,7 +68,6 @@ function ResolveInputs({ endpoint, transaction, resolveInputs }) { ); setState({ isProcessing: false, error: null }); } catch (error) { - console.error(error.stack); setState({ isProcessing: false, error: `Failed to resolve inputs: ${error}`, diff --git a/src/lib/ckb-address.js b/src/lib/ckb-address.js index ffaae2b..9b39622 100644 --- a/src/lib/ckb-address.js +++ b/src/lib/ckb-address.js @@ -97,3 +97,9 @@ export function decodeDeprecatedSecp256k1Address(address) { // ignore } } + +export function encodeDeprecatedSecp256k1Address(args) { + const data = [1, 0, ...Array.from(decodeHex(args.slice(2)))]; + const words = bech32.toWords(data); + return bech32.encode("ckt", words, 1023); +} diff --git a/src/lib/transaction.js b/src/lib/transaction.js index 8e29041..773ee7e 100644 --- a/src/lib/transaction.js +++ b/src/lib/transaction.js @@ -14,6 +14,7 @@ import { SECP256K1_CODE_HASH, SECP256K1_MULTISIG_CODE_HASH, decodeCkbAddress, + encodeDeprecatedSecp256k1Address, } from "./ckb-address.js"; import { importMultisigAddresses } from "./multisig-address.js"; import { @@ -603,7 +604,7 @@ export function exportBuildingPacket(bp, format) { for (const output of bp.value.payload.outputs) { fee = fee - BigInt(output.capacity); } - for (const output of bp.value.payload.outputs) { + for (const output of bp.value.resolved_inputs.outputs) { const lockHash = "0x" + ckbHasher() @@ -716,6 +717,43 @@ export function exportBuildingPacket(bp, format) { status: "PartiallySigned", context: [bp.value.payload], }; + } else if (format === "ckb-cli") { + // eslint-disable-next-line no-unused-vars + const { hash, ...transaction } = bp.value.payload; + const signatures = {}; + const multisig_configs = {}; + for (const output of bp.value.resolved_inputs.outputs) { + if ( + output.lock.code_hash === SECP256K1_MULTISIG_CODE_HASH_HEX && + !(output.lock.args in multisig_configs) + ) { + const lockHash = + "0x" + + ckbHasher() + .update(Script.pack(Script.parse(output.lock))) + .digest("hex"); + const action = bp.value.lock_actions.find( + (item) => item.script_hash === lockHash, + ); + const da = toJson( + MultisigAction.unpack(decodeHex(action.data.slice(2))), + ); + multisig_configs[output.lock.args] = { + sighash_addresses: da.config.signer_pubkey_hashes.map((args) => + encodeDeprecatedSecp256k1Address(args), + ), + require_first_n: parseInt(da.config.require_first_n, 16), + threshold: parseInt(da.config.threshold, 16), + }; + signatures[output.lock.args] = da.signed.map((item) => item.signature); + } + } + + return { + transaction, + signatures, + multisig_configs, + }; } return bp;