Added initial renew support to ENS CLI.
This commit is contained in:
parent
28800d7681
commit
54dfb757c4
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user