Skip to content

Commit

Permalink
feat: add yield payer function
Browse files Browse the repository at this point in the history
  • Loading branch information
Polybius93 committed Nov 13, 2024
1 parent d9b631f commit 835a358
Show file tree
Hide file tree
Showing 4 changed files with 60 additions and 3 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@
"@scure/btc-signer": "1.3.2",
"@types/ramda": "0.30.1",
"bip32": "4.0.0",
"bip39": "^3.1.0",
"bitcoinjs-lib": "6.1.6",
"chalk": "5.3.0",
"decimal.js": "10.4.3",
Expand Down
49 changes: 48 additions & 1 deletion src/functions/bitcoin/bitcoin-functions.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { hexToBytes } from '@noble/hashes/utils';
import { bytesToHex, hexToBytes } from '@noble/hashes/utils';
import {
Address,
OutScript,
Expand All @@ -8,10 +8,12 @@ import {
p2tr,
p2tr_ns,
p2wpkh,
selectUTXO,
} from '@scure/btc-signer';
import { P2Ret, P2TROut } from '@scure/btc-signer/payment';
import { TransactionInput } from '@scure/btc-signer/psbt';
import { BIP32Factory, BIP32Interface } from 'bip32';
import bip39 from 'bip39';
import { Network } from 'bitcoinjs-lib';
import { bitcoin, regtest, testnet } from 'bitcoinjs-lib/src/networks.js';
import { Decimal } from 'decimal.js';
Expand All @@ -31,6 +33,7 @@ import {
isDefined,
isUndefined,
} from '../../utilities/index.js';
import { broadcastTransaction } from './bitcoin-request-functions.js';

const TAPROOT_UNSPENDABLE_KEY_HEX =
'0250929b74c1a04954b78b4b6035e97a5e078a5a0f28ec96d547bfee9ace803ac0';
Expand All @@ -43,6 +46,50 @@ export function getFeeAmount(bitcoinAmount: number, feeBasisPoints: number): num
return new Decimal(bitcoinAmount).times(feePercentage.dividedBy(100)).toNumber();
}

export async function sendYield(
bitcoinWalletMnemonicPhrase: string,
bitcoinNetwork: Network,
bitcoinAmount: bigint,
bitcoinBlockchainAPIURL: string,
bitcoinRecipientAddress: string
): Promise<void> {
const seed = await bip39.mnemonicToSeed(bitcoinWalletMnemonicPhrase);
const derivedKeyPair = bip32.fromSeed(seed, bitcoinNetwork).derivePath(`m/84'/0'/0'/0/0`);

const payment = p2wpkh(derivedKeyPair.publicKey, bitcoinNetwork);
console.log('yieldpayer address:', payment.address);

const utxos = await getUTXOs(payment, bitcoinBlockchainAPIURL);

const psbtOutputs = [{ address: bitcoinRecipientAddress, amount: bitcoinAmount }];

const selected = selectUTXO(utxos, psbtOutputs, 'default', {
changeAddress: payment.address!,
feePerByte: 2n,
bip69: false,
createTx: true,
network: bitcoinNetwork,
dust: 546n as unknown as number,
});

if (!selected) {
throw new Error(
'Failed to select Inputs for the Funding Transaction. Ensure sufficient funds are available.'
);
}

const fundingTX = selected.tx;

if (!fundingTX) {
throw new Error('Failed to create the Funding Transaction');
}

fundingTX.sign(derivedKeyPair.privateKey!);
fundingTX.finalize();

await broadcastTransaction(bytesToHex(fundingTX.extract()), bitcoinBlockchainAPIURL);
}

/**
* Derives the Public Key at the Unhardened Path (0/0) from a given Extended Public Key.
* @param extendedPublicKey - The base58-encoded Extended Public Key.
Expand Down
2 changes: 2 additions & 0 deletions src/functions/bitcoin/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import {
getFeeAmount,
getFeeRecipientAddressFromPublicKey,
getInputIndicesByScript,
sendYield,
} from '../bitcoin/bitcoin-functions.js';
import {
broadcastTransaction,
Expand All @@ -18,6 +19,7 @@ import {
} from '../bitcoin/psbt-functions.js';

export {
sendYield,
createFundingTransaction,
createDepositTransaction,
createWithdrawTransaction,
Expand Down
11 changes: 9 additions & 2 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -764,7 +764,7 @@
"@ethersproject/properties" "^5.7.0"
"@ethersproject/strings" "^5.7.0"

"@gemwallet/api@^3.8.0":
"@gemwallet/[email protected]":
version "3.8.0"
resolved "https://registry.yarnpkg.com/@gemwallet/api/-/api-3.8.0.tgz#46bc47789848c7ac9cc620613e0a1757dc8668a1"
integrity sha512-hZ6XC0mVm3Q54cgonrzk6tHS/wUMjtPHyqsqbtlnNGPouCR7OIfEDo5Y802qLZ5ah6PskhsK0DouVnwUykEM8Q==
Expand Down Expand Up @@ -1833,6 +1833,13 @@ bip32@^2.0.4:
typeforce "^1.11.5"
wif "^2.0.6"

bip39@^3.1.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/bip39/-/bip39-3.1.0.tgz#c55a418deaf48826a6ceb34ac55b3ee1577e18a3"
integrity sha512-c9kiwdk45Do5GL0vJMe7tS95VjCii65mYAH7DfWl3uW8AVzXKQVUm64i3hzVybBDMp9r7j9iNxR85+ul8MdN/A==
dependencies:
"@noble/hashes" "^1.2.0"

bip66@^1.1.0:
version "1.1.5"
resolved "https://registry.yarnpkg.com/bip66/-/bip66-1.1.5.tgz#01fa8748785ca70955d5011217d1b3139969ca22"
Expand Down Expand Up @@ -4478,7 +4485,7 @@ ripple-address-codec@^5.0.0:
"@scure/base" "^1.1.3"
"@xrplf/isomorphic" "^1.0.0"

ripple-binary-codec@^2.1.0:
ripple-binary-codec@2.1.0, ripple-binary-codec@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/ripple-binary-codec/-/ripple-binary-codec-2.1.0.tgz#f1ef81f8d1f05a6cecc06fc6d9b13456569cafda"
integrity sha512-q0GAx+hj3UVcDbhXVjk7qeNfgUMehlElYJwiCuIBwqs/51GVTOwLr39Ht3eNsX5ow2xPRaC5mqHwcFDvLRm6cA==
Expand Down

0 comments on commit 835a358

Please sign in to comment.