480 lines
16 KiB
JavaScript
480 lines
16 KiB
JavaScript
/*
|
|
This file is part of web3.js.
|
|
web3.js is free software: you can redistribute it and/or modify
|
|
it under the terms of the GNU Lesser General Public License as published by
|
|
the Free Software Foundation, either version 3 of the License, or
|
|
(at your option) any later version.
|
|
web3.js is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU Lesser General Public License for more details.
|
|
You should have received a copy of the GNU Lesser General Public License
|
|
along with web3.js. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
/**
|
|
* @file Registry.js
|
|
*
|
|
* @author Samuel Furter <samuel@ethereum.org>
|
|
* @date 2018
|
|
*/
|
|
"use strict";
|
|
var _ = require('underscore');
|
|
var Contract = require('web3-eth-contract');
|
|
var namehash = require('eth-ens-namehash');
|
|
var PromiEvent = require('web3-core-promievent');
|
|
var formatters = require('web3-core-helpers').formatters;
|
|
var utils = require('web3-utils');
|
|
var REGISTRY_ABI = require('../resources/ABI/Registry');
|
|
var RESOLVER_ABI = require('../resources/ABI/Resolver');
|
|
/**
|
|
* A wrapper around the ENS registry contract.
|
|
*
|
|
* @method Registry
|
|
* @param {Ens} ens
|
|
* @constructor
|
|
*/
|
|
function Registry(ens) {
|
|
var self = this;
|
|
this.ens = ens;
|
|
this.contract = ens.checkNetwork().then(function (address) {
|
|
var contract = new Contract(REGISTRY_ABI, address);
|
|
contract.setProvider(self.ens.eth.currentProvider);
|
|
return contract;
|
|
});
|
|
}
|
|
/**
|
|
* Returns the address of the owner of an ENS name.
|
|
*
|
|
* @deprecated Please use the "getOwner" method instead of "owner"
|
|
*
|
|
* @method owner
|
|
*
|
|
* @param {string} name
|
|
* @param {function} callback
|
|
*
|
|
* @callback callback callback(error, result)
|
|
* @returns {Promise<string>}
|
|
*/
|
|
Registry.prototype.owner = function (name, callback) {
|
|
console.warn('Deprecated: Please use the "getOwner" method instead of "owner".');
|
|
return this.getOwner(name, callback);
|
|
};
|
|
/**
|
|
* Returns the address of the owner of an ENS name.
|
|
*
|
|
* @method getOwner
|
|
*
|
|
* @param {string} name
|
|
* @param {function} callback
|
|
*
|
|
* @callback callback callback(error, result)
|
|
* @returns {Promise<string>}
|
|
*/
|
|
Registry.prototype.getOwner = function (name, callback) {
|
|
var promiEvent = new PromiEvent(true);
|
|
this.contract.then(function (contract) {
|
|
return contract.methods.owner(namehash.hash(name)).call();
|
|
}).then(function (receipt) {
|
|
if (_.isFunction(callback)) {
|
|
// It's required to pass the receipt to the first argument to be backward compatible and to have the required consistency
|
|
callback(receipt, receipt);
|
|
return;
|
|
}
|
|
promiEvent.resolve(receipt);
|
|
}).catch(function (error) {
|
|
if (_.isFunction(callback)) {
|
|
callback(error, null);
|
|
return;
|
|
}
|
|
promiEvent.reject(error);
|
|
});
|
|
return promiEvent.eventEmitter;
|
|
};
|
|
/**
|
|
* Returns the address of the owner of an ENS name.
|
|
*
|
|
* @method setOwner
|
|
*
|
|
* @param {string} name
|
|
* @param {string} address
|
|
* @param {TransactionConfig} txConfig
|
|
* @param {function} callback
|
|
*
|
|
* @callback callback callback(error, result)
|
|
* @returns {PromiEvent<TransactionReceipt | TransactionRevertInstructionError>}
|
|
*/
|
|
Registry.prototype.setOwner = function (name, address, txConfig, callback) {
|
|
var promiEvent = new PromiEvent(true);
|
|
this.contract.then(function (contract) {
|
|
return contract.methods.setOwner(namehash.hash(name), formatters.inputAddressFormatter(address)).send(txConfig);
|
|
}).then(function (receipt) {
|
|
if (_.isFunction(callback)) {
|
|
// It's required to pass the receipt to the first argument to be backward compatible and to have the required consistency
|
|
callback(receipt, receipt);
|
|
return;
|
|
}
|
|
promiEvent.resolve(receipt);
|
|
}).catch(function (error) {
|
|
if (_.isFunction(callback)) {
|
|
callback(error, null);
|
|
return;
|
|
}
|
|
promiEvent.reject(error);
|
|
});
|
|
return promiEvent.eventEmitter;
|
|
};
|
|
/**
|
|
* Returns the TTL of the given node by his name
|
|
*
|
|
* @method getTTL
|
|
*
|
|
* @param {string} name
|
|
* @param {function} callback
|
|
*
|
|
* @callback callback callback(error, result)
|
|
* @returnss {Promise<string>}
|
|
*/
|
|
Registry.prototype.getTTL = function (name, callback) {
|
|
var promiEvent = new PromiEvent(true);
|
|
this.contract.then(function (contract) {
|
|
return contract.methods.ttl(namehash.hash(name)).call();
|
|
}).then(function (receipt) {
|
|
if (_.isFunction(callback)) {
|
|
// It's required to pass the receipt to the first argument to be backward compatible and to have the required consistency
|
|
callback(receipt, receipt);
|
|
return;
|
|
}
|
|
promiEvent.resolve(receipt);
|
|
}).catch(function (error) {
|
|
if (_.isFunction(callback)) {
|
|
callback(error, null);
|
|
return;
|
|
}
|
|
promiEvent.reject(error);
|
|
});
|
|
return promiEvent.eventEmitter;
|
|
};
|
|
/**
|
|
* Returns the address of the owner of an ENS name.
|
|
*
|
|
* @method setTTL
|
|
*
|
|
* @param {string} name
|
|
* @param {number} ttl
|
|
* @param {TransactionConfig} txConfig
|
|
* @param {function} callback
|
|
*
|
|
* @callback callback callback(error, result)
|
|
* @returns {PromiEvent<TransactionReceipt | TransactionRevertInstructionError>}
|
|
*/
|
|
Registry.prototype.setTTL = function (name, ttl, txConfig, callback) {
|
|
var promiEvent = new PromiEvent(true);
|
|
this.contract.then(function (contract) {
|
|
return contract.methods.setTTL(namehash.hash(name), ttl).send(txConfig);
|
|
}).then(function (receipt) {
|
|
if (_.isFunction(callback)) {
|
|
// It's required to pass the receipt to the first argument to be backward compatible and to have the required consistency
|
|
callback(receipt, receipt);
|
|
return;
|
|
}
|
|
promiEvent.resolve(receipt);
|
|
}).catch(function (error) {
|
|
if (_.isFunction(callback)) {
|
|
callback(error, null);
|
|
return;
|
|
}
|
|
promiEvent.reject(error);
|
|
});
|
|
return promiEvent.eventEmitter;
|
|
};
|
|
/**
|
|
* Returns the address of the owner of an ENS name.
|
|
*
|
|
* @method setSubnodeOwner
|
|
*
|
|
* @param {string} name
|
|
* @param {string} label
|
|
* @param {string} address
|
|
* @param {TransactionConfig} txConfig
|
|
* @param {function} callback
|
|
*
|
|
* @callback callback callback(error, result)
|
|
* @returns {PromiEvent<TransactionReceipt | TransactionRevertInstructionError>}
|
|
*/
|
|
Registry.prototype.setSubnodeOwner = function (name, label, address, txConfig, callback) {
|
|
var promiEvent = new PromiEvent(true);
|
|
if (!utils.isHexStrict(label)) {
|
|
label = utils.sha3(label);
|
|
}
|
|
this.contract.then(function (contract) {
|
|
return contract.methods.setSubnodeOwner(namehash.hash(name), label, formatters.inputAddressFormatter(address)).send(txConfig);
|
|
}).then(function (receipt) {
|
|
if (_.isFunction(callback)) {
|
|
// It's required to pass the receipt to the first argument to be backward compatible and to have the required consistency
|
|
callback(receipt, receipt);
|
|
return;
|
|
}
|
|
promiEvent.resolve(receipt);
|
|
}).catch(function (error) {
|
|
if (_.isFunction(callback)) {
|
|
callback(error, null);
|
|
return;
|
|
}
|
|
promiEvent.reject(error);
|
|
});
|
|
return promiEvent.eventEmitter;
|
|
};
|
|
/**
|
|
* Sets the owner, resolver, and TTL for an ENS record in a single operation.
|
|
*
|
|
* @method setRecord
|
|
*
|
|
* @param {string} name
|
|
* @param {string} owner
|
|
* @param {string} resolver
|
|
* @param {string | number} ttl
|
|
* @param {TransactionConfig} txConfig
|
|
* @param {function} callback
|
|
*
|
|
* @callback callback callback(error, result)
|
|
* @returns {PromiEvent<TransactionReceipt | TransactionRevertInstructionError>}
|
|
*/
|
|
Registry.prototype.setRecord = function (name, owner, resolver, ttl, txConfig, callback) {
|
|
var promiEvent = new PromiEvent(true);
|
|
this.contract.then(function (contract) {
|
|
return contract.methods.setRecord(namehash.hash(name), formatters.inputAddressFormatter(owner), formatters.inputAddressFormatter(resolver), ttl).send(txConfig);
|
|
}).then(function (receipt) {
|
|
if (_.isFunction(callback)) {
|
|
// It's required to pass the receipt to the first argument to be backward compatible and to have the required consistency
|
|
callback(receipt, receipt);
|
|
return;
|
|
}
|
|
promiEvent.resolve(receipt);
|
|
}).catch(function (error) {
|
|
if (_.isFunction(callback)) {
|
|
callback(error, null);
|
|
return;
|
|
}
|
|
promiEvent.reject(error);
|
|
});
|
|
return promiEvent.eventEmitter;
|
|
};
|
|
/**
|
|
* Sets the owner, resolver and TTL for a subdomain, creating it if necessary.
|
|
*
|
|
* @method setSubnodeRecord
|
|
*
|
|
* @param {string} name
|
|
* @param {string} label
|
|
* @param {string} owner
|
|
* @param {string} resolver
|
|
* @param {string | number} ttl
|
|
* @param {TransactionConfig} txConfig
|
|
* @param {function} callback
|
|
*
|
|
* @callback callback callback(error, result)
|
|
* @returns {PromiEvent<TransactionReceipt | TransactionRevertInstructionError>}
|
|
*/
|
|
Registry.prototype.setSubnodeRecord = function (name, label, owner, resolver, ttl, txConfig, callback) {
|
|
var promiEvent = new PromiEvent(true);
|
|
if (!utils.isHexStrict(label)) {
|
|
label = utils.sha3(label);
|
|
}
|
|
this.contract.then(function (contract) {
|
|
return contract.methods.setSubnodeRecord(namehash.hash(name), label, formatters.inputAddressFormatter(owner), formatters.inputAddressFormatter(resolver), ttl).send(txConfig);
|
|
}).then(function (receipt) {
|
|
if (_.isFunction(callback)) {
|
|
// It's required to pass the receipt to the first argument to be backward compatible and to have the required consistency
|
|
callback(receipt, receipt);
|
|
return;
|
|
}
|
|
promiEvent.resolve(receipt);
|
|
}).catch(function (error) {
|
|
if (_.isFunction(callback)) {
|
|
callback(error, null);
|
|
return;
|
|
}
|
|
promiEvent.reject(error);
|
|
});
|
|
return promiEvent.eventEmitter;
|
|
};
|
|
/**
|
|
* Sets or clears an approval by the given operator.
|
|
*
|
|
* @method setApprovalForAll
|
|
*
|
|
* @param {string} operator
|
|
* @param {boolean} approved
|
|
* @param {TransactionConfig} txConfig
|
|
* @param {function} callback
|
|
*
|
|
* @callback callback callback(error, result)
|
|
* @returns {PromiEvent<TransactionReceipt | TransactionRevertInstructionError>}
|
|
*/
|
|
Registry.prototype.setApprovalForAll = function (operator, approved, txConfig, callback) {
|
|
var promiEvent = new PromiEvent(true);
|
|
this.contract.then(function (contract) {
|
|
return contract.methods.setApprovalForAll(formatters.inputAddressFormatter(operator), approved).send(txConfig);
|
|
}).then(function (receipt) {
|
|
if (_.isFunction(callback)) {
|
|
// It's required to pass the receipt to the first argument to be backward compatible and to have the required consistency
|
|
callback(receipt, receipt);
|
|
return;
|
|
}
|
|
promiEvent.resolve(receipt);
|
|
}).catch(function (error) {
|
|
if (_.isFunction(callback)) {
|
|
callback(error, null);
|
|
return;
|
|
}
|
|
promiEvent.reject(error);
|
|
});
|
|
return promiEvent.eventEmitter;
|
|
};
|
|
/**
|
|
* Returns true if the operator is approved
|
|
*
|
|
* @method isApprovedForAll
|
|
*
|
|
* @param {string} owner
|
|
* @param {string} operator
|
|
* @param {function} callback
|
|
*
|
|
* @callback callback callback(error, result)
|
|
* @returns {Promise<boolean>}
|
|
*/
|
|
Registry.prototype.isApprovedForAll = function (owner, operator, callback) {
|
|
var promiEvent = new PromiEvent(true);
|
|
this.contract.then(function (contract) {
|
|
return contract.methods.isApprovedForAll(formatters.inputAddressFormatter(owner), formatters.inputAddressFormatter(operator)).call();
|
|
}).then(function (receipt) {
|
|
if (_.isFunction(callback)) {
|
|
// It's required to pass the receipt to the first argument to be backward compatible and to have the required consistency
|
|
callback(receipt, receipt);
|
|
return;
|
|
}
|
|
promiEvent.resolve(receipt);
|
|
}).catch(function (error) {
|
|
if (_.isFunction(callback)) {
|
|
callback(error, null);
|
|
return;
|
|
}
|
|
promiEvent.reject(error);
|
|
});
|
|
return promiEvent.eventEmitter;
|
|
};
|
|
/**
|
|
* Returns true if the record exists
|
|
*
|
|
* @method recordExists
|
|
*
|
|
* @param {string} name
|
|
* @param {function} callback
|
|
*
|
|
* @callback callback callback(error, result)
|
|
* @returns {Promise<boolean>}
|
|
*/
|
|
Registry.prototype.recordExists = function (name, callback) {
|
|
var promiEvent = new PromiEvent(true);
|
|
this.contract.then(function (contract) {
|
|
return contract.methods.recordExists(namehash.hash(name)).call();
|
|
}).then(function (receipt) {
|
|
if (_.isFunction(callback)) {
|
|
// It's required to pass the receipt to the first argument to be backward compatible and to have the required consistency
|
|
callback(receipt, receipt);
|
|
return;
|
|
}
|
|
promiEvent.resolve(receipt);
|
|
}).catch(function (error) {
|
|
if (_.isFunction(callback)) {
|
|
callback(error, null);
|
|
return;
|
|
}
|
|
promiEvent.reject(error);
|
|
});
|
|
return promiEvent.eventEmitter;
|
|
};
|
|
/**
|
|
* Returns the resolver contract associated with a name.
|
|
*
|
|
* @deprecated Please use the "getResolver" method instead of "resolver"
|
|
*
|
|
* @method resolver
|
|
*
|
|
* @param {string} name
|
|
* @param {function} callback
|
|
*
|
|
* @callback callback callback(error, result)
|
|
* @returns {Promise<Contract>}
|
|
*/
|
|
Registry.prototype.resolver = function (name, callback) {
|
|
console.warn('Deprecated: Please use the "getResolver" method instead of "resolver".');
|
|
return this.getResolver(name, callback);
|
|
};
|
|
/**
|
|
* Returns the resolver contract associated with a name.
|
|
*
|
|
* @method getResolver
|
|
*
|
|
* @param {string} name
|
|
* @param {function} callback
|
|
*
|
|
* @callback callback callback(error, result)
|
|
* @returns {Promise<Contract>}
|
|
*/
|
|
Registry.prototype.getResolver = function (name, callback) {
|
|
var self = this;
|
|
return this.contract.then(function (contract) {
|
|
return contract.methods.resolver(namehash.hash(name)).call();
|
|
}).then(function (address) {
|
|
var contract = new Contract(RESOLVER_ABI, address);
|
|
contract.setProvider(self.ens.eth.currentProvider);
|
|
if (_.isFunction(callback)) {
|
|
// It's required to pass the contract to the first argument to be backward compatible and to have the required consistency
|
|
callback(contract, contract);
|
|
return;
|
|
}
|
|
return contract;
|
|
}).catch(function (error) {
|
|
if (_.isFunction(callback)) {
|
|
callback(error, null);
|
|
return;
|
|
}
|
|
throw error;
|
|
});
|
|
};
|
|
/**
|
|
* Returns the address of the owner of an ENS name.
|
|
*
|
|
* @method setResolver
|
|
*
|
|
* @param {string} name
|
|
* @param {string} address
|
|
* @param {TransactionConfig} txConfig
|
|
* @param {function} callback
|
|
*
|
|
* @callback callback callback(error, result)
|
|
* @returns {PromiEvent<TransactionReceipt | TransactionRevertInstructionError>}
|
|
*/
|
|
Registry.prototype.setResolver = function (name, address, txConfig, callback) {
|
|
var promiEvent = new PromiEvent(true);
|
|
this.contract.then(function (contract) {
|
|
return contract.methods.setResolver(namehash.hash(name), formatters.inputAddressFormatter(address)).send(txConfig);
|
|
}).then(function (receipt) {
|
|
if (_.isFunction(callback)) {
|
|
// It's required to pass the receipt to the first argument to be backward compatible and to have the required consistency
|
|
callback(receipt, receipt);
|
|
return;
|
|
}
|
|
promiEvent.resolve(receipt);
|
|
}).catch(function (error) {
|
|
if (_.isFunction(callback)) {
|
|
callback(error, null);
|
|
return;
|
|
}
|
|
promiEvent.reject(error);
|
|
});
|
|
return promiEvent.eventEmitter;
|
|
};
|
|
module.exports = Registry;
|