Skip to content

Commit 9a18589

Browse files
committed
feat: implement bitcoin onchain allocator
1 parent ba823c1 commit 9a18589

File tree

2 files changed

+84
-3
lines changed

2 files changed

+84
-3
lines changed

src/services/request-handler/index.ts

Lines changed: 79 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1027,7 +1027,13 @@ export class RequestHandlerService {
10271027
);
10281028
}
10291029

1030-
const encodedData = await contract.read.payloads([payloadId as Hex]);
1030+
const rawEncodedData = await contract.read.payloads([payloadId as Hex]);
1031+
const encodedData =
1032+
chain.vmType === "bitcoin-vm"
1033+
? this._convertBitcoinTransactionDataToPsbtWithdrawal(
1034+
rawEncodedData as Hex,
1035+
)
1036+
: rawEncodedData;
10311037

10321038
const id = getDecodedWithdrawalId(
10331039
decodeWithdrawal(encodedData, chain.vmType),
@@ -1041,6 +1047,78 @@ export class RequestHandlerService {
10411047
};
10421048
}
10431049

1050+
private _convertBitcoinTransactionDataToPsbtWithdrawal(
1051+
encodedData: Hex,
1052+
): string {
1053+
const transactionData = decodeAbiParameters(
1054+
[
1055+
{
1056+
type: "tuple",
1057+
components: [
1058+
{
1059+
type: "tuple[]",
1060+
name: "inputs",
1061+
components: [
1062+
{ type: "bytes", name: "txid" },
1063+
{ type: "bytes", name: "index" },
1064+
{ type: "bytes", name: "script" },
1065+
{ type: "bytes", name: "value" },
1066+
],
1067+
},
1068+
{
1069+
type: "tuple[]",
1070+
name: "outputs",
1071+
components: [
1072+
{ type: "bytes", name: "value" },
1073+
{ type: "bytes", name: "script" },
1074+
],
1075+
},
1076+
],
1077+
},
1078+
],
1079+
encodedData,
1080+
)[0] as {
1081+
inputs: { txid: Hex; index: Hex; script: Hex; value: Hex }[];
1082+
outputs: { value: Hex; script: Hex }[];
1083+
};
1084+
1085+
const fromLittleEndian = (value: Hex): bigint => {
1086+
const bytes = Buffer.from(value.slice(2), "hex");
1087+
const reversed = Buffer.from(bytes).reverse();
1088+
const normalized = reversed.toString("hex").replace(/^0+/, "") || "0";
1089+
return BigInt(`0x${normalized}`);
1090+
};
1091+
1092+
const psbt = new bitcoin.Psbt({ network: bitcoin.networks.bitcoin });
1093+
1094+
for (const input of transactionData.inputs) {
1095+
const txid = Buffer.from(input.txid.slice(2), "hex")
1096+
.reverse()
1097+
.toString("hex");
1098+
1099+
psbt.addInput({
1100+
hash: txid,
1101+
index: Number(fromLittleEndian(input.index)),
1102+
witnessUtxo: {
1103+
script: Buffer.from(input.script.slice(2), "hex"),
1104+
value: Number(fromLittleEndian(input.value)),
1105+
},
1106+
});
1107+
}
1108+
1109+
for (const output of transactionData.outputs) {
1110+
psbt.addOutput({
1111+
script: Buffer.from(output.script.slice(2), "hex"),
1112+
value: Number(fromLittleEndian(output.value)),
1113+
});
1114+
}
1115+
1116+
return encodeWithdrawal({
1117+
vmType: "bitcoin-vm",
1118+
withdrawal: { psbt: psbt.toHex() },
1119+
});
1120+
}
1121+
10441122
private async _withdrawalIsReady(payloadId: string) {
10451123
const { contract, publicClient } = await getOnchainAllocator();
10461124

src/utils/onchain-allocator.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -352,6 +352,9 @@ export const getSignatureFromContract = async (
352352
}
353353

354354
case "bitcoin-vm": {
355+
const unsignedPayload = await onchainAllocator.contract.read.payloads([
356+
payloadId as Hex,
357+
]);
355358
const transactionData = decodeAbiParameters(
356359
[
357360
{
@@ -378,7 +381,7 @@ export const getSignatureFromContract = async (
378381
],
379382
},
380383
],
381-
encodedData as Hex,
384+
unsignedPayload as Hex,
382385
)[0] as {
383386
inputs: { txid: Hex; index: Hex; script: Hex; value: Hex }[];
384387
outputs: { value: Hex; script: Hex }[];
@@ -389,7 +392,7 @@ export const getSignatureFromContract = async (
389392
const hashToSign = await payloadBuilder.contract.read.hashToSign([
390393
BigInt(allocatorChainId),
391394
depository,
392-
encodedData as Hex,
395+
unsignedPayload as Hex,
393396
index,
394397
]);
395398

0 commit comments

Comments
 (0)