@unspent/phi
Version:
a collection of anyone can spend contracts
166 lines • 5.52 kB
JavaScript
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