Skip to content

feat: add btc/runes receiver #76

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

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
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
2 changes: 1 addition & 1 deletion .husky/pre-commit
Original file line number Diff line number Diff line change
@@ -1 +1 @@
# pnpm test
lint-staged
4 changes: 4 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
"esm2cjs": "^1.0.2",
"husky": "^9.1.7",
"jsdom": "^24.1.1",
"lint-staged": "^15.5.1",
"pkgroll": "^2.6.1",
"ts-node": "^10.9.2",
"ts-patch": "^3.3.0",
Expand All @@ -44,5 +45,8 @@
"@noble/secp256k1": "1.7.1",
"@tanstack/react-query": "5.69.0"
}
},
"lint-staged": {
"*": ["biome check --no-errors-on-unmatched --files-ignore-unknown=true"]
}
}
36 changes: 36 additions & 0 deletions packages/executor/src/actions/finalizeBTCTransaction.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import { AddressPurpose, connect, disconnect } from "@midl-xyz/midl-js-core";
import type { MidlContextState } from "@midl-xyz/midl-js-react";
import { http, type Chain, createWalletClient } from "viem";
import { afterEach, beforeEach, describe, expect, it } from "vitest";
import { createStore } from "zustand";
import { midlConfig } from "~/__tests__/midlConfig";
import { finalizeBTCTransaction } from "~/actions/finalizeBTCTransaction";
import { getEVMFromBitcoinNetwork } from "~/utils";

describe("finalizeBTCTransaction", () => {
const store = createStore<MidlContextState>()(() => ({}));
const chain = getEVMFromBitcoinNetwork(midlConfig.getState().network);

const walletClient = createWalletClient({
chain: chain as Chain,
transport: http(chain.rpcUrls.default.http[0]),
});

beforeEach(async () => {
await connect(midlConfig, {
purposes: [AddressPurpose.Payment],
});
});

afterEach(async () => {
await disconnect(midlConfig);
});

it("throws no intentions", async () => {
await expect(
finalizeBTCTransaction(midlConfig, store, walletClient),
).rejects.toThrowError(
"Cannot finalize BTC transaction without intentions",
);
});
});
41 changes: 36 additions & 5 deletions packages/executor/src/actions/finalizeBTCTransaction.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import {
AddressPurpose,
type Config,
type EdictRuneParams,
type EdictRuneResponse,
Expand All @@ -15,10 +16,12 @@
type StateOverride,
encodeFunctionData,
padHex,
zeroAddress,
} from "viem";
import { estimateGasMulti } from "viem/actions";
import type { StoreApi } from "zustand";
import { addTxIntention } from "~/actions/addTxIntention";
import { getPublicKey } from "~/actions/getPublicKey";
import { getPublicKeyForAccount } from "~/actions/getPublicKeyForAccount";
import { executorAddress, multisigAddress } from "~/config";
import { executorAbi } from "~/contracts/abi";
Expand Down Expand Up @@ -79,9 +82,9 @@
config: Config,
store: StoreApi<MidlContextState>,
client: Client,
options: FinalizeBTCTransactionOptions,
options: FinalizeBTCTransactionOptions = {},
) => {
const { network } = config.getState();
const { network, accounts } = config.getState();

if (!network) {
throw new Error("No network set");
Expand All @@ -90,7 +93,7 @@
const { intentions = [] } = store.getState();

if (intentions.length === 0) {
throw new Error("No intentions found");
throw new Error("Cannot finalize BTC transaction without intentions");
}

const pk = await getPublicKeyForAccount(config, options.publicKey);
Expand Down Expand Up @@ -216,6 +219,34 @@
}

if (options.shouldComplete) {
const runesReceiver = accounts?.find(
(it) => it.purpose === AddressPurpose.Ordinals,
);
const btcReceiver =
accounts?.find((it) => it.purpose === AddressPurpose.Payment) ??
runesReceiver;

Check warning on line 227 in packages/executor/src/actions/finalizeBTCTransaction.ts

View check run for this annotation

Codecov / codecov/patch

packages/executor/src/actions/finalizeBTCTransaction.ts#L222-L227

Added lines #L222 - L227 were not covered by tests

if (
!runesReceiver &&
options.assetsToWithdraw?.find((it) => it !== zeroAddress)
) {
throw new Error("No ordinals account found to withdraw runes");
}

Check warning on line 234 in packages/executor/src/actions/finalizeBTCTransaction.ts

View check run for this annotation

Codecov / codecov/patch

packages/executor/src/actions/finalizeBTCTransaction.ts#L229-L234

Added lines #L229 - L234 were not covered by tests

if (!btcReceiver) {
throw new Error("No account found to withdraw BTC");
}

Check warning on line 238 in packages/executor/src/actions/finalizeBTCTransaction.ts

View check run for this annotation

Codecov / codecov/patch

packages/executor/src/actions/finalizeBTCTransaction.ts#L236-L238

Added lines #L236 - L238 were not covered by tests

const btcPublicKey = getPublicKey(
config,
btcReceiver.publicKey,
) as `0x${string}`;

Check warning on line 243 in packages/executor/src/actions/finalizeBTCTransaction.ts

View check run for this annotation

Codecov / codecov/patch

packages/executor/src/actions/finalizeBTCTransaction.ts#L240-L243

Added lines #L240 - L243 were not covered by tests

const runesPublicKey = getPublicKey(
config,
runesReceiver?.publicKey ?? btcReceiver.publicKey,
) as `0x${string}`;

Check warning on line 248 in packages/executor/src/actions/finalizeBTCTransaction.ts

View check run for this annotation

Codecov / codecov/patch

packages/executor/src/actions/finalizeBTCTransaction.ts#L245-L248

Added lines #L245 - L248 were not covered by tests

addTxIntention(config, store, {
hasWithdraw,
hasRunesWithdraw,
Expand All @@ -228,8 +259,8 @@
functionName: "completeTx",
args: [
`0x${btcTx.tx.id}`,
pk as `0x${string}`,
padHex("0x0", { size: 32 }), // BTC receiver
runesPublicKey,
btcPublicKey,

Check warning on line 263 in packages/executor/src/actions/finalizeBTCTransaction.ts

View check run for this annotation

Codecov / codecov/patch

packages/executor/src/actions/finalizeBTCTransaction.ts#L262-L263

Added lines #L262 - L263 were not covered by tests
options.assetsToWithdraw ?? [],
new Array(options.assetsToWithdraw?.length ?? 0).fill(0n),
],
Expand Down
Loading