-
Notifications
You must be signed in to change notification settings - Fork 45
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
feat: add fee output to psbt #376
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,6 +2,9 @@ | |
import { hex, base64 } from '@scure/base'; | ||
import { AddressType, getAddressInfo, Network } from 'bitcoin-address-validation'; | ||
import { EsploraClient, UTXO } from '../esplora'; | ||
import { stripHexPrefix } from '../utils'; | ||
|
||
const DUST_LIMIT = 546; | ||
|
||
export type BitcoinNetworkName = Exclude<Network, 'regtest'>; | ||
|
||
|
@@ -33,22 +36,37 @@ | |
* May add an additional change output. This returns an **unsigned** PSBT encoded | ||
* as a Base64 string. | ||
* | ||
* @param fromAddress The Bitcoin address which is sending to the `toAddress`. | ||
* @param toAddress The Bitcoin address which is receiving the BTC. | ||
* @param amount The amount of BTC (as satoshis) to send. | ||
* @param publicKey Optional public key needed if using P2SH-P2WPKH. | ||
* @param opReturnData Optional OP_RETURN data to include in an output. | ||
* @param confirmationTarget The number of blocks to include this tx (for fee estimation). | ||
* @param params An object containing the following properties: | ||
* - `fromAddress`: The Bitcoin address which is sending to the `toAddress`. | ||
* - `toAddress`: The Bitcoin address which is receiving the BTC. | ||
* - `amount`: The amount of BTC (as satoshis) to send. | ||
* - `publicKey` (optional): Public key needed if using P2SH-P2WPKH. | ||
* - `opReturnData` (optional): OP_RETURN data to include in an output. | ||
* - `confirmationTarget` (optional): The number of blocks to include this tx (for fee estimation). Defaults to 3. | ||
* | ||
* @returns {Promise<string>} The Base64 encoded PSBT. | ||
*/ | ||
export async function createBitcoinPsbt( | ||
fromAddress: string, | ||
toAddress: string, | ||
amount: number, | ||
publicKey?: string, | ||
opReturnData?: string, | ||
confirmationTarget: number = 3 | ||
): Promise<string> { | ||
export async function createBitcoinPsbt(params: { | ||
fromAddress: string; | ||
toAddress: string; | ||
amount: number; | ||
publicKey?: string; | ||
opReturnData?: string; | ||
confirmationTarget?: number; | ||
feeRecipient?: string; | ||
feeAmount?: number; | ||
}): Promise<string> { | ||
const { | ||
fromAddress, | ||
toAddress, | ||
amount, | ||
publicKey, | ||
opReturnData, | ||
confirmationTarget = 3, | ||
feeRecipient, | ||
feeAmount, | ||
} = params; | ||
|
||
const addressInfo = getAddressInfo(fromAddress); | ||
const network = addressInfo.network; | ||
if (network === 'regtest') { | ||
|
@@ -92,14 +110,17 @@ | |
}, | ||
]; | ||
|
||
if (feeRecipient && feeAmount && feeAmount > DUST_LIMIT) { | ||
outputs.push({ | ||
address: feeRecipient, | ||
amount: BigInt(feeAmount), | ||
}); | ||
} | ||
|
||
if (opReturnData) { | ||
// Strip 0x prefix from opReturn | ||
if (opReturnData.startsWith('0x')) { | ||
opReturnData = opReturnData.slice(2); | ||
} | ||
outputs.push({ | ||
// OP_RETURN https://github.com/paulmillr/scure-btc-signer/issues/26 | ||
script: Script.encode(['RETURN', hex.decode(opReturnData)]), | ||
script: Script.encode(['RETURN', hex.decode(stripHexPrefix(opReturnData))]), | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why is this necessary now and wasn't necessary before? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It does the same thing as the code I removed above |
||
amount: BigInt(0), | ||
}); | ||
} | ||
|
@@ -117,11 +138,11 @@ | |
allowUnknownOutputs: true, // Required for OP_RETURN | ||
allowLegacyWitnessUtxo: true, // Required for P2SH-P2WPKH | ||
// eslint-disable-next-line @typescript-eslint/no-explicit-any | ||
dust: BigInt(546) as any, // TODO: update scure-btc-signer | ||
dust: BigInt(DUST_LIMIT) as any, // TODO: update scure-btc-signer | ||
}); | ||
|
||
if (!transaction || !transaction.tx) { | ||
throw new Error('Failed to create transaction. Do you have enough funds?'); | ||
Check failure on line 145 in sdk/src/wallet/utxo.ts GitHub Actions / SDKtest/utxo.test.ts > UTXO Tests > should spend from address to create a transaction with an OP return output
|
||
} | ||
|
||
return base64.encode(transaction.tx.toPSBT(0)); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd use big.js here. JS arithmetic with decimals is not great.