|
@@ -1,23 +1,120 @@
|
|
|
<script setup lang="ts">
|
|
|
+/* Import modules. */
|
|
|
+import BCHJS from '@psf/bch-js'
|
|
|
+import { binToHex } from '@nexajs/utils'
|
|
|
+
|
|
|
/* Define properties. */
|
|
|
// https://vuejs.org/guide/components/props.html#props-declaration
|
|
|
const props = defineProps({
|
|
|
balances: Object,
|
|
|
cashAddress: String,
|
|
|
+ utxos: Object,
|
|
|
+})
|
|
|
+
|
|
|
+/* Initialize stores. */
|
|
|
+import { useWalletStore } from '@/stores/wallet'
|
|
|
+const Wallet = useWalletStore()
|
|
|
+
|
|
|
+// REST API servers.
|
|
|
+const BCHN_MAINNET = 'https://bchn.fullstack.cash/v5/'
|
|
|
+
|
|
|
+const runtimeConfig = useRuntimeConfig()
|
|
|
+const jwtAuthToken = runtimeConfig.public.PSF_JWT_AUTH_TOKEN
|
|
|
+
|
|
|
+const balances = ref(null)
|
|
|
+const cashAddress = ref(null)
|
|
|
+
|
|
|
+// Instantiate bch-js based on the network.
|
|
|
+const bchjs = new BCHJS({
|
|
|
+ restURL: BCHN_MAINNET,
|
|
|
+ apiToken: jwtAuthToken,
|
|
|
})
|
|
|
+// console.log('bchjs', bchjs)
|
|
|
|
|
|
-const clearWallet = () => {
|
|
|
|
|
|
+const calculateFee = () => {
|
|
|
+ // Calculate miner fees.
|
|
|
+ // Get byte count (x inputs, pay + remainder = 2x outputs)
|
|
|
+ return bchjs.BitcoinCash.getByteCount({ P2PKH: 1 }, { P2PKH: 2 })
|
|
|
}
|
|
|
|
|
|
-const start = () => {
|
|
|
+// Combine all accounts inputs and outputs in one unsigned Tx
|
|
|
+const buildUnsignedTx = async () => {
|
|
|
+ try {
|
|
|
+ // console.log(`inputs: ${JSON.stringify(combinedInputs, null, 2)}`)
|
|
|
+
|
|
|
+ const fee = await calculateFee()
|
|
|
+ const paymentAmount = props.balances.confirmed - fee
|
|
|
+ const satsNeeded = fee + paymentAmount
|
|
|
+ const receiver = 'bitcoincash:qq27zfgmy7hckrrxygjdz6rr847pjkzzyc6d0un4e4'
|
|
|
+ console.log(`payment (+fee): ${satsNeeded}`)
|
|
|
+
|
|
|
+ const transactionBuilder = new bchjs.TransactionBuilder()
|
|
|
+
|
|
|
+ props.utxos.forEach(async function (_utxo) {
|
|
|
+ const utxo = _utxo
|
|
|
+ console.log('UTXO', utxo);
|
|
|
+ transactionBuilder.addInput(utxo.tx_hash, utxo.tx_pos)
|
|
|
+ const originalAmount = utxo.value
|
|
|
+ const remainder = originalAmount - satsNeeded
|
|
|
+ console.log('REMAINDER', remainder);
|
|
|
+
|
|
|
+
|
|
|
+ if (remainder < 0) {
|
|
|
+ throw new Error('Selected UTXO does not have enough satoshis')
|
|
|
+ }
|
|
|
+
|
|
|
+ // Send payment
|
|
|
+ transactionBuilder.addOutput(receiver, satsNeeded)
|
|
|
+
|
|
|
+ // Send the BCH change back to the payment part
|
|
|
+ // transactionBuilder.addOutput(account.address, remainder - 300)
|
|
|
+ })
|
|
|
|
|
|
+ const tx = transactionBuilder.transaction.buildIncomplete()
|
|
|
+ const hex = tx.toHex()
|
|
|
+ console.log(`Non-signed Tx hex: ${hex}`)
|
|
|
+ // fs.writeFileSync('unsigned_tx.json', JSON.stringify(hex, null, 2))
|
|
|
+ // console.log('unsigned_tx.json written successfully.')
|
|
|
+ } catch (err) {
|
|
|
+ console.error(`Error in buildUnsignedTx(): ${err}`)
|
|
|
+ throw err
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
-// onMounted(() => {
|
|
|
-// console.log('Mounted!')
|
|
|
-// // Now it's safe to perform setup operations.
|
|
|
-// })
|
|
|
+
|
|
|
+const cashout = () => {
|
|
|
+ alert('WIP?? sorry...')
|
|
|
+}
|
|
|
+
|
|
|
+const start = async () => {
|
|
|
+ console.log('Starting...')
|
|
|
+
|
|
|
+ console.log('FEE', calculateFee())
|
|
|
+
|
|
|
+ buildUnsignedTx()
|
|
|
+
|
|
|
+ const readyToFuse = props.utxos
|
|
|
+ console.log('READY TO FUSE', readyToFuse)
|
|
|
+
|
|
|
+ // TODO Handle any filtering required BEFORE submitting for fusion.
|
|
|
+
|
|
|
+ const response = await $fetch('/v1', {
|
|
|
+ method: 'POST',
|
|
|
+ body: {
|
|
|
+ authid: binToHex(Wallet.wallet.publicKey),
|
|
|
+ coins: readyToFuse,
|
|
|
+ tokens: [],
|
|
|
+ },
|
|
|
+ })
|
|
|
+ .catch(err => console.error(err))
|
|
|
+ console.log('RESPONSE', response)
|
|
|
+}
|
|
|
+
|
|
|
+onMounted(() => {
|
|
|
+ // console.log('Mounted!', props.balances)
|
|
|
+ // Now it's safe to perform setup operations.
|
|
|
+})
|
|
|
|
|
|
// onBeforeUnmount(() => {
|
|
|
// console.log('Before Unmount!')
|
|
@@ -46,19 +143,23 @@ const start = () => {
|
|
|
</h3>
|
|
|
|
|
|
<h3>
|
|
|
- Confirmed: {{balances?.confirmed}}
|
|
|
+ Confirmed: {{props.balances?.confirmed}}
|
|
|
</h3>
|
|
|
<h3>
|
|
|
- Unconfirmed: {{balances?.unconfirmed}}
|
|
|
+ Unconfirmed: {{props.balances?.unconfirmed}}
|
|
|
</h3>
|
|
|
|
|
|
- <button @click="clearWallet">
|
|
|
- Clear wallet
|
|
|
- </button>
|
|
|
+ <div class="my-3 grid grid-cols-2 gap-4">
|
|
|
+ <button @click="cashout" class="px-3 py-2 bg-lime-200 border-2 border-lime-400 text-2xl text-lime-800 font-medium rounded shadow hover:bg-lime-100">
|
|
|
+ Cashout Wallet
|
|
|
+ </button>
|
|
|
+
|
|
|
+ <button @click="start" class="px-3 py-2 bg-lime-200 border-2 border-lime-400 text-2xl text-lime-800 font-medium rounded shadow hover:bg-lime-100">
|
|
|
+ Start Fusions
|
|
|
+ </button>
|
|
|
+ </div>
|
|
|
|
|
|
- <button @click="start">
|
|
|
- Start
|
|
|
- </button>
|
|
|
+ <pre class="text-xs">{{props.utxos}}</pre>
|
|
|
|
|
|
</section>
|
|
|
|