Added initial renew support to ENS CLI.

This commit is contained in:
Richard Moore 2020-05-01 16:21:33 -04:00
parent 28800d7681
commit 54dfb757c4
No known key found for this signature in database
GPG Key ID: 665176BE8E9DC651

View File

@ -42,7 +42,8 @@ const ethControllerAbi = [
const ethRegistrarAbi = [
"function ownerOf(uint256 tokenId) view returns (address)",
"function reclaim(uint256 id, address owner) @500000",
"function safeTransferFrom(address from, address to, uint256 tokenId) @500000"
"function safeTransferFrom(address from, address to, uint256 tokenId) @500000",
"function nameExpires(uint256 id) external view returns(uint)"
];
const resolverAbi = [
@ -867,6 +868,140 @@ class ReclaimPlugin extends AddressAccountPlugin {
}
cli.addPlugin("reclaim", ReclaimPlugin);
function zpad(value: number, length: number): string {
let v = String(value);
while (v.length < length) { v = "0" + v; }
return v;
}
function formatDate(date: Date): string {
const count = Math.round((date.getTime() - (new Date()).getTime()) / (24 * 60 * 60 * 1000))
return [
date.getFullYear(),
zpad(date.getMonth() + 1, 2),
zpad(date.getDate(), 2)
].join("-") + ` (${ count } days from now)`;
}
class RenewPlugin extends EnsPlugin {
labels: ReadonlyArray<string>;
// Only one of these two will be set
duration: number;
until: string;
static getHelp(): Help {
return {
name: "renew NAME [ NAME ... ]",
help: "Reset the controller by the registrant"
}
}
static getOptionHelp(): Array<Help> {
return [
{
name: "[ --duration DAYS ]",
help: "Register duration (default: 365 days)"
},
{
name: "[ --until YYYY-MM-DD ]",
help: "Register until date"
},
];
}
getDuration(startDate: number, until: string): number {
const match = until.match(/^(\d\d\d\d)-(\d\d)-(\d\d)$/);
if (!match) {
this.throwError("invalid date format; use YYYY-MM-DD");
}
const year = parseInt(match[1]);
const month = parseInt(match[2]);
const day = parseInt(match[3]);
// Not perfect; allow February 30 or April 31 @TODO?
if (month < 1 || month > 12 || day < 1 || day > 31) {
this.throwError("date out of range");
}
const endDate = (new Date(year, month - 1, day)).getTime() / 1000;
return Math.ceil(endDate - startDate);
}
async prepareOptions(argParser: ArgParser): Promise<void> {
await super.prepareOptions(argParser);
if (this.accounts.length !== 1) {
this.throwError("new requires ONE account");
}
const timespans = argParser.consumeMultiOptions([ "duration", "until" ]);
if (timespans.length === 1) {
const timespan = timespans.pop();
if (timespan.name === "duration") {
this.duration = parseInt(timespan.value) * 60 * 60 * 24;
} else if (timespan.name === "until") {
this.until = timespan.value;
}
} else if (timespans.length > 1) {
this.throwError("renew requires at most ONE of --duration or --until");
} else {
this.duration = 365 * 60 * 60 * 24;
}
}
async prepareArgs(args: Array<string>): Promise<void> {
await super.prepareArgs(args);
const labels: Array<string> = [ ];
args.forEach((arg) => {
const comps = arg.split(".");
if (comps.length !== 2 || comps[1] !== "eth") {
this.throwError(`name not supported ${ JSON.stringify(arg) }`);
}
labels.push(comps[0]);
});
this.labels = Object.freeze(labels);
}
async run(): Promise<void> {
await super.run();
const ethController = await this.getEthController();
const ethRegistrar = await this.getEthRegistrar();
for (let i = 0; i < this.labels.length; i++) {
const label = this.labels[i];
console.log(label);
const expiration = (await ethRegistrar.nameExpires(ethers.utils.id(label))).toNumber();
if (expiration === 0) {
this.throwError(`not registered: ${ label }`);
}
const duration = this.duration ? this.duration: this.getDuration(expiration, this.until);
if (duration < 0) {
this.throwError(`bad duration: ${ duration }`);
}
const fee = (await ethController.rentPrice(label, duration)).mul(11).div(10);
this.dump(`Renew: ${ label }.eth`, {
"Current Expiry": formatDate(new Date(expiration * 1000)),
"Duration": `${ (duration / (24 * 60 * 60)) } days`,
"Until": formatDate(new Date((expiration + duration) * 1000)),
"Fee": `${ ethers.utils.formatEther(fee) } (+10% buffer)`,
});
await ethController.renew(label, duration, {
value: fee
});
}
}
}
cli.addPlugin("renew", RenewPlugin);
/**
* To Do:
* register NAME --registrar