Skip to content

Commit

Permalink
feat: Babylon staking transaction
Browse files Browse the repository at this point in the history
  • Loading branch information
originalix committed Apr 29, 2024
1 parent 0872380 commit fdee6eb
Show file tree
Hide file tree
Showing 7 changed files with 76 additions and 20 deletions.
45 changes: 33 additions & 12 deletions packages/engine/src/vaults/impl/btc/provider.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import * as BitcoinJS from 'bitcoinjs-lib';
import { toXOnly } from 'bitcoinjs-lib/src/psbt/bip371';
import { isTaprootInput, toXOnly } from 'bitcoinjs-lib/src/psbt/bip371';

import { memoizee } from '@onekeyhq/shared/src/utils/cacheUtils';

Expand All @@ -25,7 +25,9 @@ function tapTweakHash(pubKey: Buffer, h: Buffer | undefined): Buffer {
export function tweakSigner(
privKey: Buffer,
publicKey: Buffer,
opts: { tweakHash?: Buffer; network?: Network } = {},
opts: { tweakHash?: Buffer; network?: Network; needTweak: boolean } = {
needTweak: true,
},
): BitcoinJS.Signer {
let privateKey: Uint8Array | null = new Uint8Array(privKey.buffer);
if (!privateKey) {
Expand All @@ -43,13 +45,17 @@ export function tweakSigner(
privateKey,
tapTweakHash(toXOnly(publicKey), opts.tweakHash),
);

if (!tweakedPrivateKey) {
throw new Error('Invalid tweaked private key!');
}

return getBitcoinECPair().fromPrivateKey(Buffer.from(tweakedPrivateKey), {
network: opts.network,
});
return getBitcoinECPair().fromPrivateKey(
Buffer.from(opts.needTweak ? tweakedPrivateKey : privateKey),
{
network: opts.network,
},
);
}

export default class Provider extends BaseProvider {
Expand Down Expand Up @@ -78,13 +84,28 @@ export default class Provider extends BaseProvider {
const publicKey = await signer.getPubkey(true);

// P2TR
if (input.tapInternalKey) {
const privateKey = await signer.getPrvkey();
const tweakedSigner = tweakSigner(privateKey, publicKey, {
network: this.network,
});

return tweakedSigner;
if (isTaprootInput(input)) {
let needTweak = true;
// script path spend
if (
input.tapLeafScript &&
input.tapLeafScript?.length > 0 &&
!input.tapMerkleRoot
) {
input.tapLeafScript.forEach((e) => {
if (e.controlBlock && e.script) {
needTweak = false;
}
});
}
if (input.tapInternalKey) {
const privateKey = await signer.getPrvkey();
const tweakedSigner = tweakSigner(privateKey, publicKey, {
network: this.network,
needTweak,
});
return tweakedSigner;
}
}

// For other encoding
Expand Down
6 changes: 5 additions & 1 deletion packages/engine/src/vaults/utils/btcForkChain/KeyringHd.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,10 +45,14 @@ export class KeyringHd extends KeyringHdBase {
throw new OneKeyInternalError('Software signing requires a password.');
}

const dbAccount = (await this.getDbAccount()) as DBUTXOAccount;
const { transferInfo } = unsignedTx.encodedTx as IEncodedTxBtc;
const signers = await this.getSigners(
password,
(inputsToSign || unsignedTx.inputs).map((input) => input.address),
[
...(inputsToSign || unsignedTx.inputs).map((input) => input.address),
...Object.values(dbAccount.addresses),
],
transferInfo.useCustomAddressesBalance,
);
debugLogger.engine.info('signTransaction', this.networkId, unsignedTx);
Expand Down
3 changes: 3 additions & 0 deletions packages/engine/src/vaults/utils/btcForkChain/VaultBtcFork.ts
Original file line number Diff line number Diff line change
Expand Up @@ -444,6 +444,9 @@ export default class VaultBtcFork extends VaultBase {
}

decodedTxToLegacy(decodedTx: IDecodedTx): Promise<IDecodedTxLegacy> {
if (!decodedTx.actions || decodedTx.actions.length === 0) {
return Promise.resolve({} as IDecodedTxLegacy);
}
const { type, nativeTransfer, inscriptionInfo } = decodedTx.actions[0];
if (type === IDecodedTxActionType.NATIVE_TRANSFER && nativeTransfer) {
return Promise.resolve({
Expand Down
18 changes: 15 additions & 3 deletions packages/kit-bg/src/providers/ProviderApiBtc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -437,7 +437,15 @@ class ProviderApiBtc extends ProviderApiBase {
) {
const { psbtHexs, options } = params;

const { network } = getActiveWalletAccount();
const { network, wallet } = getActiveWalletAccount();
if (wallet?.type === 'hw') {
throw web3Errors.provider.custom({
code: 4003,
message:
'Partially signed bitcoin transactions is not supported on hardware.',
});
}

if (!network) return null;

const psbtNetwork = toPsbtNetwork(network);
Expand Down Expand Up @@ -537,13 +545,14 @@ class ProviderApiBtc extends ProviderApiBase {
psbt,
psbtNetwork,
account,
isBtcWalletProvider: options.isBtcWalletProvider,
});

const resp = (await this.backgroundApi.serviceDapp.openSignAndSendModal(
request,
{
encodedTx: {
inputs: decodedPsbt.inputInfos.map((v) => ({
inputs: (decodedPsbt.inputInfos ?? []).map((v) => ({
...v,
path: '',
value: v.value.toString(),
Expand All @@ -553,7 +562,7 @@ class ProviderApiBtc extends ProviderApiBase {
),
),
})),
outputs: decodedPsbt.outputInfos.map((v) => ({
outputs: (decodedPsbt.outputInfos ?? []).map((v) => ({
...v,
value: v.value.toString(),
inscriptions: v.inscriptions.map((i) =>
Expand Down Expand Up @@ -589,6 +598,9 @@ class ProviderApiBtc extends ProviderApiBase {
});
}

if (options.isBtcWalletProvider) {
return respPsbt.extractTransaction().toHex();
}
return respPsbt.toHex();
}

Expand Down
4 changes: 3 additions & 1 deletion packages/shared/src/engine/engineConsts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -285,4 +285,6 @@ export const isLightningNetworkByNetworkId = (networkId?: string) =>
networkId === OnekeyNetwork.lightning ||
networkId === OnekeyNetwork.tlightning;
export const isBTCNetwork = (networkId?: string) =>
networkId === OnekeyNetwork.btc || networkId === OnekeyNetwork.tbtc;
networkId === OnekeyNetwork.btc ||
networkId === OnekeyNetwork.tbtc ||
networkId === OnekeyNetwork.sbtc;
Original file line number Diff line number Diff line change
Expand Up @@ -43,12 +43,12 @@ export type PushTxParams = {
};
export type SignPsbtParams = {
psbtHex: string;
options: { autoFinalized: boolean };
options: { autoFinalized: boolean; isBtcWalletProvider: boolean };
};

export type SignPsbtsParams = {
psbtHexs: string[];
options: { autoFinalized: boolean };
options: { autoFinalized: boolean; isBtcWalletProvider: boolean };
};

export type PushPsbtParams = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,11 @@ import { isBTCNetwork } from '../../engine/engineConsts';

import { NETWORK_TYPES, NetworkTypeEnum } from './ProviderApiBtc.types';

import type { InputToSign, Inscription } from './ProviderApiBtc.types';
import type {
InputToSign,
Inscription,
SignPsbtParams,
} from './ProviderApiBtc.types';

export const OPENAPI_URL_MAINNET = 'https://wallet-api.unisat.io/v5';
export const OPENAPI_URL_TESTNET = 'https://wallet-api-testnet.unisat.io/v5';
Expand Down Expand Up @@ -130,10 +134,12 @@ export function getInputsToSignFromPsbt({
psbt,
psbtNetwork,
account,
isBtcWalletProvider,
}: {
account: Account;
psbt: BitcoinJS.Psbt;
psbtNetwork: BitcoinJS.networks.Network;
isBtcWalletProvider: SignPsbtParams['options']['isBtcWalletProvider'];
}) {
const inputsToSign: InputToSign[] = [];
psbt.data.inputs.forEach((v, index) => {
Expand Down Expand Up @@ -164,6 +170,14 @@ export function getInputsToSignFromPsbt({
Buffer.from(account.pubKey as string, 'hex'),
);
}
} else if (isBtcWalletProvider) {
// handle babylon
inputsToSign.push({
index,
publicKey: account.pubKey as string,
address: account.address,
sighashTypes: v.sighashType ? [v.sighashType] : undefined,
});
}
}
});
Expand Down

0 comments on commit fdee6eb

Please sign in to comment.