Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions .changeset/joy-id-sign-psbt-return-psbt.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
---
"@ckb-ccc/joy-id": patch
---

`signPsbt` now always returns a PSBT. Previously JoyID returned a raw
transaction when `autoFinalized` was true, and failed on PSBTs with inputs it
couldn't sign.

If you broadcast the result of `signPsbt` directly, extract the transaction
from the PSBT or use `signAndBroadcastPsbt` instead.
7 changes: 7 additions & 0 deletions .changeset/scure-btc-signer.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
"@ckb-ccc/joy-id": patch
"@ckb-ccc/xverse": patch
---

Use `@scure/btc-signer` instead of `bitcoinjs-lib` for PSBTs. JoyID no longer
calls `initEccLib`, which set global state.
3 changes: 2 additions & 1 deletion packages/examples/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,8 @@
"@ckb-ccc/ccc": "workspace:*",
"@ckb-ccc/playground": "file:src/playground",
"@noble/curves": "^2.2.0",
"@noble/hashes": "^2.2.0"
"@noble/hashes": "^2.2.0",
"@scure/btc-signer": "2.4.1"
},
"packageManager": "pnpm@11.8.0"
}
2 changes: 0 additions & 2 deletions packages/examples/src/playground/index.d.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
import { ccc } from "@ckb-ccc/ccc";
import * as bitcoinLib from "bitcoinjs-lib";

export function render(tx: ccc.Transaction): Promise<void>;
export const signer: ccc.Signer;
export const client: ccc.Client;
export const bitcoin: typeof bitcoinLib;
58 changes: 25 additions & 33 deletions packages/examples/src/transferBtc.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { ccc } from "@ckb-ccc/ccc";
import { bitcoin, signer } from "@ckb-ccc/playground";
import { signer } from "@ckb-ccc/playground";
import * as btc from "@scure/btc-signer";

// Supported wallets: Unisat, JoyID, Xverse
// Check if the current signer is also a Bitcoin signer
Expand Down Expand Up @@ -60,46 +61,37 @@ if (!vout || !vout.scriptpubkey) {
}

// Build PSBT with the selected UTXO as input
const psbt = new bitcoin.Psbt({
network: isXverse ? bitcoin.networks.testnet : bitcoin.networks.testnet,
});
const input: {
hash: string;
index: number;
witnessUtxo: {
script: Uint8Array;
value: bigint;
};
tapInternalKey?: Uint8Array;
} = {
hash: selectedUtxo.txid,
const tx = new btc.Transaction();
const isTaproot =
vout.scriptpubkey_type === "v1_p2tr" ||
vout.scriptpubkey_type === "witness_v1_taproot";
tx.addInput({
txid: selectedUtxo.txid,
index: selectedUtxo.vout,
witnessUtxo: {
script: ccc.bytesFrom(vout.scriptpubkey),
value: BigInt(vout.value),
amount: BigInt(vout.value),
},
};

// Handle Taproot (P2TR) specific input fields
if (
vout.scriptpubkey_type === "v1_p2tr" ||
vout.scriptpubkey_type === "witness_v1_taproot"
) {
input.tapInternalKey = ccc
.bytesFrom(await signer.getBtcPublicKey())
.subarray(1);
}

psbt.addInput(input);
// Taproot inputs need the internal key
...(isTaproot
? {
tapInternalKey: ccc
.bytesFrom(await signer.getBtcPublicKey())
.subarray(1),
}
: {}),
});

// Add a single output back to the same address minus a hardcoded 200 sat fee
psbt.addOutput({
address: btcAddress,
value: BigInt(vout.value) - BigInt(FEE_SATS),
});
// Signet uses the testnet address format
tx.addOutputAddress(
btcAddress,
BigInt(vout.value) - BigInt(FEE_SATS),
btc.TEST_NETWORK,
);

// Sign and broadcast the transaction
const txId = await signer.signAndBroadcastPsbt(psbt.toHex());
const txId = await signer.signAndBroadcastPsbt(tx.toPSBT());
console.log(
`View transaction: https://mempool.space/${btcTestnetName}/tx/${txId.slice(2)}`,
);
11 changes: 10 additions & 1 deletion packages/joy-id/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
},
"devDependencies": {
"@eslint/js": "^10.0.1",
"@noble/curves": "^2.2.0",
"eslint": "^10.5.0",
"eslint-config-prettier": "^10.1.8",
"eslint-plugin-prettier": "^5.5.6",
Expand All @@ -56,9 +57,17 @@
},
"dependencies": {
"@ckb-ccc/core": "workspace:*",
"@scure/btc-signer": "2.4.1",
"@joyid/ckb": "^1.1.4",
"@joyid/common": "^0.2.2"
},
"packageManager": "pnpm@11.8.0",
"types": "./dist.commonjs/index.d.ts"
"types": "./dist.commonjs/index.d.ts",
"inlinedDependencies": {
"@noble/curves": "2.4.0",
"@noble/hashes": "2.4.0",
"@scure/base": "2.4.0",
"@scure/btc-signer": "2.4.1",
"micro-packed": "0.11.1"
}
}
Loading
Loading