/* Import modules. */ import { broadcast } from '@nexajs/provider' import { buildCoins } from '@nexajs/purse' import { encodeDataPush, encodeNullData, OP, } from '@nexajs/script' import { hexToBin, utf8ToBin, } from '@nexajs/utils' /* Import (local) modules. */ import { useWalletStore } from '@/stores/wallet' /* Initialize constants. */ const TIMETOCASHOUT_HEX = '6c6c6c6c5479009c63557a7cad6d6d67547a519d537ab275030051147b7e00cd8800cc55ea537a94a2697568' export default async function () { /* Initialize locals. */ let coins let lockingScript let nullData let receivers let response let scriptPubkey let unlockingScript let userData /* Initialize wallet store. */ const Wallet = useWalletStore() /* Validate play address. */ if (!this.address) { throw new Error('Missing play address.') } /* Validate authorization hash. */ if (!this.authHash) { throw new Error('Missing authorization hash.') } /* Set script public key. */ scriptPubkey = encodeDataPush(Wallet.publicKey) /* Set locking script. */ lockingScript = hexToBin(TIMETOCASHOUT_HEX) // console.info('\nCONTRACT TEMPLATE', binToHex(lockingScript)) /* Set unlocking script. */ // NOTE: Index of (executed) contract method. unlockingScript = new Uint8Array([ ...encodeDataPush(scriptPubkey), ...utf8ToBin('{{SIGNATURE}}'), // placeholder for signature OP.ZERO, // contract function index ]) /* Handle coin locks. */ coins = Wallet.coins.map(_coin => { return { ..._coin, locking: lockingScript, unlocking: unlockingScript, } }) // console.log('COINS-2', coins) /* Initialize receivers. */ receivers = [] /* Initialize user data. */ userData = [ 'NEXA.games', this.authHash, ] // console.log('AUTH HASH', this.authHash) /* Initialize hex data. */ nullData = encodeNullData(userData) // console.log('HEX DATA', nullData) /* Validate user data. */ if (userData) { console.log('USER DATA', userData) // TODO Validate data length is less than OP_RETURN max (220). /* Add OP_RETURN data. */ receivers.push({ data: nullData, }) } /* Add value output. */ receivers.push({ address: this.address, satoshis: BigInt(this.satoshis), }) receivers.push({ address: Wallet.address, // satoshis: changeVal, }) console.log('RECEIVERS', receivers) /* Build transaction. */ response = await buildCoins(coins, receivers) .catch(err => console.error(err)) console.log('BUILD TRANSACTION', response.raw) /* Broadcast transaction. */ response = await broadcast(response.raw) .catch(err => console.error(err)) console.log('SEND TRANSACTION', response) try { const txResult = JSON.parse(response) console.log('TX RESULT', txResult) if (txResult?.result) { // TEMP FOR DEV PURPOSES ONLY window.open('https://nexa.games/fairplay/' + this.playid) } if (txResult?.error) { if (txResult?.error.message.includes('txn-mempool-conflict')) { return alert(`Oops! Please wait for pending transactions to confirm before sending.`) } if (txResult?.error.message.includes('bad-txns-in-belowout')) { return alert(`Oops! You don't have enough NEXA to send that amount.`) } alert(txResult?.error.message) } /* Reset gameplay. */ this.resetGameplay() } catch (err) { console.error(err) } }