UNPKG

@unspent/phi

Version:

a collection of anyone can spend contracts

166 lines 5.52 kB
import { DefaultOptions } from "../../common/constant.js"; import { BaseUtxPhiContract } from "../../common/contract.js"; import { sum, toHex, binToBigInt } from "../../common/util.js"; import { artifact as v3 } from "./cash/v3.js"; export class Drip extends BaseUtxPhiContract { constructor(options = DefaultOptions) { let script; if (options.version === 3) { script = v3; } else { throw Error("Unrecognized Drip Version"); } super(options.network, script, []); this.options = options; this.options = options; } refresh() { this._refresh([]); } static fromString(str, network = "mainnet") { const p = this.parseSerializedString(str, network); // if the contract shortcode doesn't match, error if (!(Drip.c == p.code)) throw "non-faucet serialized string passed to faucet constructor"; if (![3].includes(p.options.version)) throw Error("faucet contract version not recognized"); if (p.args.length != 0) throw `invalid number of arguments ${p.args.length}`; const faucet = new Drip(p.options); faucet.checkLockingBytecode(p.lockingBytecode); return faucet; } // Create a Drip contract from an OpReturn by building a serialized string. static fromOpReturn(opReturn, network = "mainnet") { const p = this.parseOpReturn(opReturn, network); // check code if (p.code !== this.c) throw Error(`Wrong short code passed to ${this.name} class: ${p.code}`); // version if (![3].includes(p.options.version)) throw Error(`Wrong version code passed to ${this.name} class: ${p.options.version}`); // parse arguments if (p.args.length != 0) throw `invalid number of arguments ${p.args.length}`; const faucet = new Drip(p.options); faucet.checkLockingBytecode(p.lockingBytecode); return faucet; } static async getSpendableBalance(opReturn, network = "mainnet", networkProvider, blockHeight) { const p = this.parseOpReturn(opReturn, network); const utxos = await networkProvider.getUtxos(p.address); const spendableUtxos = utxos.map((u) => { // @ts-ignore if (u.height !== 0) { // @ts-ignore if (blockHeight - u.height > period) { return u.satoshis; } else { return 0n; } } else { return 0n; } }); const spendable = spendableUtxos.length > 0 ? spendableUtxos.reduce(sum) : 0n; if (spendable > Drip.minPayout) { return spendable; } else { return 0n; } } static getExecutorAllowance(opReturn, network = "mainnet") { const p = this.parseOpReturn(opReturn, network); // pop the index to get to the payout p.args.pop(); return binToBigInt(p.args.pop()); } toString() { return [ `${Drip.c}`, `${this.options.version}`, `${this.getLockingBytecode()}`, ].join(Drip.delimiter); } asText() { return `The dripping miner MEV faucet`; } asCommand() { let chipnetFlag = this.options.network == 'mainnet' ? '' : "--chipnet "; return `unspent drip ${chipnetFlag} --version ${this.options.version}`; } toOpReturn(hex = false) { const chunks = [ Drip._PROTOCOL_ID, Drip.c, toHex(this.options.version), "0x" + this.getLockingBytecode(true), ]; return this.asOpReturn(chunks, hex); } getOutputLockingBytecodes(hex = true) { hex; return []; } isSpecial() { return false; } async execute( //@ts-ignore exAddress, //@ts-ignore fee, utxos, debug) { // Filter to inputs of sufficient age if (!utxos) utxos = await this.getUtxos(1); debug; const fn = this.getFunction(Drip.fn); let txids = await Promise.all(utxos.map(async (utxo) => await this.doDrip(utxo, fn))); return txids.join(","); } async doDrip(utxo, fn) { let balance = BigInt(utxo.satoshis); let tx = fn(); let newPrincipal = balance - BigInt(balance * 4392n / 1333036486n) + 1n; const to = []; tx = tx.from([utxo]); // if enough remains for an additional payout if ((balance - newPrincipal) > Drip.minPayout) { to.push({ to: this.getAddress(), amount: newPrincipal, }); tx.to(to); } else if (balance > Drip.minPayout) { newPrincipal = balance - Drip.minPayout; if (newPrincipal > 576) { to.push({ to: this.getAddress(), amount: newPrincipal, }); tx.to(to); } else { tx.withOpReturn([]); } } else { tx.withOpReturn([]); } tx .withAge(1) .withoutChange(); let txn = ""; txn = (await tx.send()).txid; return txn; } } Drip.c = "$"; Drip.fn = "drip"; Drip.minPayout = 164n; //# sourceMappingURL=Drip.js.map