Beta 7 with some repo names changed.

This commit is contained in:
Luis Fernando Molina committed 2020-11-15 13:05:19 +01:00
1 parent 0f7b40cca7
commit 963c19493a
3408 files changed
+462217 -15516

No files matched your search

+2
View File
@@ -0,0 +1,2 @@
export const version = "hash/5.0.6";
//# sourceMappingURL=_version.js.map
+6
View File
@@ -0,0 +1,6 @@
import { keccak256 } from "@ethersproject/keccak256";
import { toUtf8Bytes } from "@ethersproject/strings";
export function id(text) {
return keccak256(toUtf8Bytes(text));
}
//# sourceMappingURL=id.js.map
+7
View File
@@ -0,0 +1,7 @@
"use strict";
import { id } from "./id";
import { isValidName, namehash } from "./namehash";
import { hashMessage, messagePrefix } from "./message";
import { TypedDataEncoder as _TypedDataEncoder } from "./typed-data";
export { id, namehash, isValidName, messagePrefix, hashMessage, _TypedDataEncoder, };
//# sourceMappingURL=index.js.map
+15
View File
@@ -0,0 +1,15 @@
import { concat } from "@ethersproject/bytes";
import { keccak256 } from "@ethersproject/keccak256";
import { toUtf8Bytes } from "@ethersproject/strings";
export const messagePrefix = "\x19Ethereum Signed Message:\n";
export function hashMessage(message) {
if (typeof (message) === "string") {
message = toUtf8Bytes(message);
}
return keccak256(concat([
toUtf8Bytes(messagePrefix),
toUtf8Bytes(String(message.length)),
message
]));
}
//# sourceMappingURL=message.js.map
+37
View File
@@ -0,0 +1,37 @@
import { concat, hexlify } from "@ethersproject/bytes";
import { nameprep, toUtf8Bytes } from "@ethersproject/strings";
import { keccak256 } from "@ethersproject/keccak256";
import { Logger } from "@ethersproject/logger";
import { version } from "./_version";
const logger = new Logger(version);
const Zeros = new Uint8Array(32);
Zeros.fill(0);
const Partition = new RegExp("^((.*)\\.)?([^.]+)$");
export function isValidName(name) {
try {
const comps = name.split(".");
for (let i = 0; i < comps.length; i++) {
if (nameprep(comps[i]).length === 0) {
throw new Error("empty");
}
}
return true;
}
catch (error) { }
return false;
}
export function namehash(name) {
/* istanbul ignore if */
if (typeof (name) !== "string") {
logger.throwArgumentError("invalid address - " + String(name), "name", name);
}
let result = Zeros;
while (name.length) {
const partition = name.match(Partition);
const label = toUtf8Bytes(nameprep(partition[3]));
result = keccak256(concat([result, keccak256(label)]));
name = partition[2] || "";
}
return hexlify(result);
}
//# sourceMappingURL=namehash.js.map
+444
View File
@@ -0,0 +1,444 @@
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
import { getAddress } from "@ethersproject/address";
import { BigNumber } from "@ethersproject/bignumber";
import { arrayify, hexConcat, hexlify, hexValue, hexZeroPad, isHexString } from "@ethersproject/bytes";
import { keccak256 } from "@ethersproject/keccak256";
import { deepCopy, defineReadOnly, shallowCopy } from "@ethersproject/properties";
import { Logger } from "@ethersproject/logger";
import { version } from "./_version";
const logger = new Logger(version);
import { id } from "./id";
const padding = new Uint8Array(32);
padding.fill(0);
const NegativeOne = BigNumber.from(-1);
const Zero = BigNumber.from(0);
const One = BigNumber.from(1);
const MaxUint256 = BigNumber.from("0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff");
function hexPadRight(value) {
const bytes = arrayify(value);
const padOffset = bytes.length % 32;
if (padOffset) {
return hexConcat([bytes, padding.slice(padOffset)]);
}
return hexlify(bytes);
}
const hexTrue = hexZeroPad(One.toHexString(), 32);
const hexFalse = hexZeroPad(Zero.toHexString(), 32);
const domainFieldTypes = {
name: "string",
version: "string",
chainId: "uint256",
verifyingContract: "address",
salt: "bytes32"
};
const domainFieldNames = [
"name", "version", "chainId", "verifyingContract", "salt"
];
function checkString(key) {
return function (value) {
if (typeof (value) !== "string") {
logger.throwArgumentError(`invalid domain value for ${JSON.stringify(key)}`, `domain.${key}`, value);
}
return value;
};
}
const domainChecks = {
name: checkString("name"),
version: checkString("version"),
chainId: function (value) {
try {
return BigNumber.from(value).toString();
}
catch (error) { }
return logger.throwArgumentError(`invalid domain value for "chainId"`, "domain.chainId", value);
},
verifyingContract: function (value) {
try {
return getAddress(value).toLowerCase();
}
catch (error) { }
return logger.throwArgumentError(`invalid domain value "verifyingContract"`, "domain.verifyingContract", value);
},
salt: function (value) {
try {
const bytes = arrayify(value);
if (bytes.length !== 32) {
throw new Error("bad length");
}
return hexlify(bytes);
}
catch (error) { }
return logger.throwArgumentError(`invalid domain value "salt"`, "domain.salt", value);
}
};
function getBaseEncoder(type) {
// intXX and uintXX
{
const match = type.match(/^(u?)int(\d*)$/);
if (match) {
const signed = (match[1] === "");
const width = parseInt(match[2] || "256");
if (width % 8 !== 0 || width > 256 || (match[2] && match[2] !== String(width))) {
logger.throwArgumentError("invalid numeric width", "type", type);
}
const boundsUpper = MaxUint256.mask(signed ? (width - 1) : width);
const boundsLower = signed ? boundsUpper.add(One).mul(NegativeOne) : Zero;
return function (value) {
const v = BigNumber.from(value);
if (v.lt(boundsLower) || v.gt(boundsUpper)) {
logger.throwArgumentError(`value out-of-bounds for ${type}`, "value", value);
}
return hexZeroPad(v.toTwos(256).toHexString(), 32);
};
}
}
// bytesXX
{
const match = type.match(/^bytes(\d+)$/);
if (match) {
const width = parseInt(match[1]);
if (width === 0 || width > 32 || match[1] !== String(width)) {
logger.throwArgumentError("invalid bytes width", "type", type);
}
return function (value) {
const bytes = arrayify(value);
if (bytes.length !== width) {
logger.throwArgumentError(`invalid length for ${type}`, "value", value);
}
return hexPadRight(value);
};
}
}
switch (type) {
case "address": return function (value) {
return hexZeroPad(getAddress(value), 32);
};
case "bool": return function (value) {
return ((!value) ? hexFalse : hexTrue);
};
case "bytes": return function (value) {
return keccak256(value);
};
case "string": return function (value) {
return id(value);
};
}
return null;
}
function encodeType(name, fields) {
return `${name}(${fields.map(({ name, type }) => (type + " " + name)).join(",")})`;
}
export class TypedDataEncoder {
constructor(types) {
defineReadOnly(this, "types", Object.freeze(deepCopy(types)));
defineReadOnly(this, "_encoderCache", {});
defineReadOnly(this, "_types", {});
// Link struct types to their direct child structs
const links = {};
// Link structs to structs which contain them as a child
const parents = {};
// Link all subtypes within a given struct
const subtypes = {};
Object.keys(types).forEach((type) => {
links[type] = {};
parents[type] = [];
subtypes[type] = {};
});
for (const name in types) {
const uniqueNames = {};
types[name].forEach((field) => {
// Check each field has a unique name
if (uniqueNames[field.name]) {
logger.throwArgumentError(`duplicate variable name ${JSON.stringify(field.name)} in ${JSON.stringify(name)}`, "types", types);
}
uniqueNames[field.name] = true;
// Get the base type (drop any array specifiers)
const baseType = field.type.match(/^([^\x5b]*)(\x5b|$)/)[1];
if (baseType === name) {
logger.throwArgumentError(`circular type reference to ${JSON.stringify(baseType)}`, "types", types);
}
// Is this a base encoding type?
const encoder = getBaseEncoder(baseType);
if (encoder) {
return;
}
if (!parents[baseType]) {
logger.throwArgumentError(`unknown type ${JSON.stringify(baseType)}`, "types", types);
}
// Add linkage
parents[baseType].push(name);
links[name][baseType] = true;
});
}
// Deduce the primary type
const primaryTypes = Object.keys(parents).filter((n) => (parents[n].length === 0));
if (primaryTypes.length === 0) {
logger.throwArgumentError("missing primary type", "types", types);
}
else if (primaryTypes.length > 1) {
logger.throwArgumentError(`ambiguous primary types or unused types: ${primaryTypes.map((t) => (JSON.stringify(t))).join(", ")}`, "types", types);
}
defineReadOnly(this, "primaryType", primaryTypes[0]);
// Check for circular type references
function checkCircular(type, found) {
if (found[type]) {
logger.throwArgumentError(`circular type reference to ${JSON.stringify(type)}`, "types", types);
}
found[type] = true;
Object.keys(links[type]).forEach((child) => {
if (!parents[child]) {
return;
}
// Recursively check children
checkCircular(child, found);
// Mark all ancestors as having this decendant
Object.keys(found).forEach((subtype) => {
subtypes[subtype][child] = true;
});
});
delete found[type];
}
checkCircular(this.primaryType, {});
// Compute each fully describe type
for (const name in subtypes) {
const st = Object.keys(subtypes[name]);
st.sort();
this._types[name] = encodeType(name, types[name]) + st.map((t) => encodeType(t, types[t])).join("");
}
}
getEncoder(type) {
let encoder = this._encoderCache[type];
if (!encoder) {
encoder = this._encoderCache[type] = this._getEncoder(type);
}
return encoder;
}
_getEncoder(type) {
// Basic encoder type (address, bool, uint256, etc)
{
const encoder = getBaseEncoder(type);
if (encoder) {
return encoder;
}
}
// Array
const match = type.match(/^(.*)(\x5b(\d*)\x5d)$/);
if (match) {
const subtype = match[1];
const subEncoder = this.getEncoder(subtype);
const length = parseInt(match[3]);
return (value) => {
if (length >= 0 && value.length !== length) {
logger.throwArgumentError("array length mismatch; expected length ${ arrayLength }", "value", value);
}
let result = value.map(subEncoder);
if (this._types[subtype]) {
result = result.map(keccak256);
}
return keccak256(hexConcat(result));
};
}
// Struct
const fields = this.types[type];
if (fields) {
const encodedType = id(this._types[type]);
return (value) => {
const values = fields.map(({ name, type }) => {
const result = this.getEncoder(type)(value[name]);
if (this._types[type]) {
return keccak256(result);
}
return result;
});
values.unshift(encodedType);
return hexConcat(values);
};
}
return logger.throwArgumentError(`unknown type: ${type}`, "type", type);
}
encodeType(name) {
const result = this._types[name];
if (!result) {
logger.throwArgumentError(`unknown type: ${JSON.stringify(name)}`, "name", name);
}
return result;
}
encodeData(type, value) {
return this.getEncoder(type)(value);
}
hashStruct(name, value) {
return keccak256(this.encodeData(name, value));
}
encode(value) {
return this.encodeData(this.primaryType, value);
}
hash(value) {
return this.hashStruct(this.primaryType, value);
}
_visit(type, value, callback) {
// Basic encoder type (address, bool, uint256, etc)
{
const encoder = getBaseEncoder(type);
if (encoder) {
return callback(type, value);
}
}
// Array
const match = type.match(/^(.*)(\x5b(\d*)\x5d)$/);
if (match) {
const subtype = match[1];
const length = parseInt(match[3]);
if (length >= 0 && value.length !== length) {
logger.throwArgumentError("array length mismatch; expected length ${ arrayLength }", "value", value);
}
return value.map((v) => this._visit(subtype, v, callback));
}
// Struct
const fields = this.types[type];
if (fields) {
return fields.reduce((accum, { name, type }) => {
accum[name] = this._visit(type, value[name], callback);
return accum;
}, {});
}
return logger.throwArgumentError(`unknown type: ${type}`, "type", type);
}
visit(value, callback) {
return this._visit(this.primaryType, value, callback);
}
static from(types) {
return new TypedDataEncoder(types);
}
static getPrimaryType(types) {
return TypedDataEncoder.from(types).primaryType;
}
static hashStruct(name, types, value) {
return TypedDataEncoder.from(types).hashStruct(name, value);
}
static hashDomain(domain) {
const domainFields = [];
for (const name in domain) {
const type = domainFieldTypes[name];
if (!type) {
logger.throwArgumentError(`invalid typed-data domain key: ${JSON.stringify(name)}`, "domain", domain);
}
domainFields.push({ name, type });
}
domainFields.sort((a, b) => {
return domainFieldNames.indexOf(a.name) - domainFieldNames.indexOf(b.name);
});
return TypedDataEncoder.hashStruct("EIP712Domain", { EIP712Domain: domainFields }, domain);
}
static encode(domain, types, value) {
return hexConcat([
"0x1901",
TypedDataEncoder.hashDomain(domain),
TypedDataEncoder.from(types).hash(value)
]);
}
static hash(domain, types, value) {
return keccak256(TypedDataEncoder.encode(domain, types, value));
}
// Replaces all address types with ENS names with their looked up address
static resolveNames(domain, types, value, resolveName) {
return __awaiter(this, void 0, void 0, function* () {
// Make a copy to isolate it from the object passed in
domain = shallowCopy(domain);
// Look up all ENS names
const ensCache = {};
// Do we need to look up the domain's verifyingContract?
if (domain.verifyingContract && !isHexString(domain.verifyingContract, 20)) {
ensCache[domain.verifyingContract] = "0x";
}
// We are going to use the encoder to visit all the base values
const encoder = TypedDataEncoder.from(types);
// Get a list of all the addresses
encoder.visit(value, (type, value) => {
if (type === "address" && !isHexString(value, 20)) {
ensCache[value] = "0x";
}
return value;
});
// Lookup each name
for (const name in ensCache) {
ensCache[name] = yield resolveName(name);
}
// Replace the domain verifyingContract if needed
if (domain.verifyingContract && ensCache[domain.verifyingContract]) {
domain.verifyingContract = ensCache[domain.verifyingContract];
}
// Replace all ENS names with their address
value = encoder.visit(value, (type, value) => {
if (type === "address" && ensCache[value]) {
return ensCache[value];
}
return value;
});
return { domain, value };
});
}
static getPayload(domain, types, value) {
// Validate the domain fields
TypedDataEncoder.hashDomain(domain);
// Derive the EIP712Domain Struct reference type
const domainValues = {};
const domainTypes = [];
domainFieldNames.forEach((name) => {
const value = domain[name];
if (value == null) {
return;
}
domainValues[name] = domainChecks[name](value);
domainTypes.push({ name, type: domainFieldTypes[name] });
});
const encoder = TypedDataEncoder.from(types);
const typesWithDomain = shallowCopy(types);
if (typesWithDomain.EIP712Domain) {
typesWithDomain.EIP712Domain = domainTypes;
}
// Validate the data structures and types
encoder.encode(value);
return {
types: typesWithDomain,
domain: domainValues,
primaryType: encoder.primaryType,
message: encoder.visit(value, (type, value) => {
// bytes
if (type.match(/^bytes(\d*)/)) {
return hexlify(arrayify(value));
}
// uint or int
if (type.match(/^u?int/)) {
let prefix = "";
let v = BigNumber.from(value);
if (v.isNegative()) {
prefix = "-";
v = v.mul(-1);
}
return prefix + hexValue(v.toHexString());
}
switch (type) {
case "address":
return value.toLowerCase();
case "bool":
return !!value;
case "string":
if (typeof (value) !== "string") {
logger.throwArgumentError(`invalid string`, "value", value);
}
return value;
}
return logger.throwArgumentError("unsupported type", "type", type);
})
};
}
}
//# sourceMappingURL=typed-data.js.map
+4
View File
@@ -0,0 +1,4 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.version = "hash/5.0.6";
//# sourceMappingURL=_version.js.map
+9
View File
@@ -0,0 +1,9 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var keccak256_1 = require("@ethersproject/keccak256");
var strings_1 = require("@ethersproject/strings");
function id(text) {
return keccak256_1.keccak256(strings_1.toUtf8Bytes(text));
}
exports.id = id;
//# sourceMappingURL=id.js.map
+13
View File
@@ -0,0 +1,13 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var id_1 = require("./id");
exports.id = id_1.id;
var namehash_1 = require("./namehash");
exports.isValidName = namehash_1.isValidName;
exports.namehash = namehash_1.namehash;
var message_1 = require("./message");
exports.hashMessage = message_1.hashMessage;
exports.messagePrefix = message_1.messagePrefix;
var typed_data_1 = require("./typed-data");
exports._TypedDataEncoder = typed_data_1.TypedDataEncoder;
//# sourceMappingURL=index.js.map
+18
View File
@@ -0,0 +1,18 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var bytes_1 = require("@ethersproject/bytes");
var keccak256_1 = require("@ethersproject/keccak256");
var strings_1 = require("@ethersproject/strings");
exports.messagePrefix = "\x19Ethereum Signed Message:\n";
function hashMessage(message) {
if (typeof (message) === "string") {
message = strings_1.toUtf8Bytes(message);
}
return keccak256_1.keccak256(bytes_1.concat([
strings_1.toUtf8Bytes(exports.messagePrefix),
strings_1.toUtf8Bytes(String(message.length)),
message
]));
}
exports.hashMessage = hashMessage;
//# sourceMappingURL=message.js.map
+41
View File
@@ -0,0 +1,41 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var bytes_1 = require("@ethersproject/bytes");
var strings_1 = require("@ethersproject/strings");
var keccak256_1 = require("@ethersproject/keccak256");
var logger_1 = require("@ethersproject/logger");
var _version_1 = require("./_version");
var logger = new logger_1.Logger(_version_1.version);
var Zeros = new Uint8Array(32);
Zeros.fill(0);
var Partition = new RegExp("^((.*)\\.)?([^.]+)$");
function isValidName(name) {
try {
var comps = name.split(".");
for (var i = 0; i < comps.length; i++) {
if (strings_1.nameprep(comps[i]).length === 0) {
throw new Error("empty");
}
}
return true;
}
catch (error) { }
return false;
}
exports.isValidName = isValidName;
function namehash(name) {
/* istanbul ignore if */
if (typeof (name) !== "string") {
logger.throwArgumentError("invalid address - " + String(name), "name", name);
}
var result = Zeros;
while (name.length) {
var partition = name.match(Partition);
var label = strings_1.toUtf8Bytes(strings_1.nameprep(partition[3]));
result = keccak256_1.keccak256(bytes_1.concat([result, keccak256_1.keccak256(label)]));
name = partition[2] || "";
}
return bytes_1.hexlify(result);
}
exports.namehash = namehash;
//# sourceMappingURL=namehash.js.map
+503
View File
@@ -0,0 +1,503 @@
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __generator = (this && this.__generator) || function (thisArg, body) {
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
function verb(n) { return function (v) { return step([n, v]); }; }
function step(op) {
if (f) throw new TypeError("Generator is already executing.");
while (_) try {
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
if (y = 0, t) op = [op[0] & 2, t.value];
switch (op[0]) {
case 0: case 1: t = op; break;
case 4: _.label++; return { value: op[1], done: false };
case 5: _.label++; y = op[1]; op = [0]; continue;
case 7: op = _.ops.pop(); _.trys.pop(); continue;
default:
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
if (t[2]) _.ops.pop();
_.trys.pop(); continue;
}
op = body.call(thisArg, _);
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
}
};
Object.defineProperty(exports, "__esModule", { value: true });
var address_1 = require("@ethersproject/address");
var bignumber_1 = require("@ethersproject/bignumber");
var bytes_1 = require("@ethersproject/bytes");
var keccak256_1 = require("@ethersproject/keccak256");
var properties_1 = require("@ethersproject/properties");
var logger_1 = require("@ethersproject/logger");
var _version_1 = require("./_version");
var logger = new logger_1.Logger(_version_1.version);
var id_1 = require("./id");
var padding = new Uint8Array(32);
padding.fill(0);
var NegativeOne = bignumber_1.BigNumber.from(-1);
var Zero = bignumber_1.BigNumber.from(0);
var One = bignumber_1.BigNumber.from(1);
var MaxUint256 = bignumber_1.BigNumber.from("0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff");
function hexPadRight(value) {
var bytes = bytes_1.arrayify(value);
var padOffset = bytes.length % 32;
if (padOffset) {
return bytes_1.hexConcat([bytes, padding.slice(padOffset)]);
}
return bytes_1.hexlify(bytes);
}
var hexTrue = bytes_1.hexZeroPad(One.toHexString(), 32);
var hexFalse = bytes_1.hexZeroPad(Zero.toHexString(), 32);
var domainFieldTypes = {
name: "string",
version: "string",
chainId: "uint256",
verifyingContract: "address",
salt: "bytes32"
};
var domainFieldNames = [
"name", "version", "chainId", "verifyingContract", "salt"
];
function checkString(key) {
return function (value) {
if (typeof (value) !== "string") {
logger.throwArgumentError("invalid domain value for " + JSON.stringify(key), "domain." + key, value);
}
return value;
};
}
var domainChecks = {
name: checkString("name"),
version: checkString("version"),
chainId: function (value) {
try {
return bignumber_1.BigNumber.from(value).toString();
}
catch (error) { }
return logger.throwArgumentError("invalid domain value for \"chainId\"", "domain.chainId", value);
},
verifyingContract: function (value) {
try {
return address_1.getAddress(value).toLowerCase();
}
catch (error) { }
return logger.throwArgumentError("invalid domain value \"verifyingContract\"", "domain.verifyingContract", value);
},
salt: function (value) {
try {
var bytes = bytes_1.arrayify(value);
if (bytes.length !== 32) {
throw new Error("bad length");
}
return bytes_1.hexlify(bytes);
}
catch (error) { }
return logger.throwArgumentError("invalid domain value \"salt\"", "domain.salt", value);
}
};
function getBaseEncoder(type) {
// intXX and uintXX
{
var match = type.match(/^(u?)int(\d*)$/);
if (match) {
var signed = (match[1] === "");
var width = parseInt(match[2] || "256");
if (width % 8 !== 0 || width > 256 || (match[2] && match[2] !== String(width))) {
logger.throwArgumentError("invalid numeric width", "type", type);
}
var boundsUpper_1 = MaxUint256.mask(signed ? (width - 1) : width);
var boundsLower_1 = signed ? boundsUpper_1.add(One).mul(NegativeOne) : Zero;
return function (value) {
var v = bignumber_1.BigNumber.from(value);
if (v.lt(boundsLower_1) || v.gt(boundsUpper_1)) {
logger.throwArgumentError("value out-of-bounds for " + type, "value", value);
}
return bytes_1.hexZeroPad(v.toTwos(256).toHexString(), 32);
};
}
}
// bytesXX
{
var match = type.match(/^bytes(\d+)$/);
if (match) {
var width_1 = parseInt(match[1]);
if (width_1 === 0 || width_1 > 32 || match[1] !== String(width_1)) {
logger.throwArgumentError("invalid bytes width", "type", type);
}
return function (value) {
var bytes = bytes_1.arrayify(value);
if (bytes.length !== width_1) {
logger.throwArgumentError("invalid length for " + type, "value", value);
}
return hexPadRight(value);
};
}
}
switch (type) {
case "address": return function (value) {
return bytes_1.hexZeroPad(address_1.getAddress(value), 32);
};
case "bool": return function (value) {
return ((!value) ? hexFalse : hexTrue);
};
case "bytes": return function (value) {
return keccak256_1.keccak256(value);
};
case "string": return function (value) {
return id_1.id(value);
};
}
return null;
}
function encodeType(name, fields) {
return name + "(" + fields.map(function (_a) {
var name = _a.name, type = _a.type;
return (type + " " + name);
}).join(",") + ")";
}
var TypedDataEncoder = /** @class */ (function () {
function TypedDataEncoder(types) {
properties_1.defineReadOnly(this, "types", Object.freeze(properties_1.deepCopy(types)));
properties_1.defineReadOnly(this, "_encoderCache", {});
properties_1.defineReadOnly(this, "_types", {});
// Link struct types to their direct child structs
var links = {};
// Link structs to structs which contain them as a child
var parents = {};
// Link all subtypes within a given struct
var subtypes = {};
Object.keys(types).forEach(function (type) {
links[type] = {};
parents[type] = [];
subtypes[type] = {};
});
var _loop_1 = function (name_1) {
var uniqueNames = {};
types[name_1].forEach(function (field) {
// Check each field has a unique name
if (uniqueNames[field.name]) {
logger.throwArgumentError("duplicate variable name " + JSON.stringify(field.name) + " in " + JSON.stringify(name_1), "types", types);
}
uniqueNames[field.name] = true;
// Get the base type (drop any array specifiers)
var baseType = field.type.match(/^([^\x5b]*)(\x5b|$)/)[1];
if (baseType === name_1) {
logger.throwArgumentError("circular type reference to " + JSON.stringify(baseType), "types", types);
}
// Is this a base encoding type?
var encoder = getBaseEncoder(baseType);
if (encoder) {
return;
}
if (!parents[baseType]) {
logger.throwArgumentError("unknown type " + JSON.stringify(baseType), "types", types);
}
// Add linkage
parents[baseType].push(name_1);
links[name_1][baseType] = true;
});
};
for (var name_1 in types) {
_loop_1(name_1);
}
// Deduce the primary type
var primaryTypes = Object.keys(parents).filter(function (n) { return (parents[n].length === 0); });
if (primaryTypes.length === 0) {
logger.throwArgumentError("missing primary type", "types", types);
}
else if (primaryTypes.length > 1) {
logger.throwArgumentError("ambiguous primary types or unused types: " + primaryTypes.map(function (t) { return (JSON.stringify(t)); }).join(", "), "types", types);
}
properties_1.defineReadOnly(this, "primaryType", primaryTypes[0]);
// Check for circular type references
function checkCircular(type, found) {
if (found[type]) {
logger.throwArgumentError("circular type reference to " + JSON.stringify(type), "types", types);
}
found[type] = true;
Object.keys(links[type]).forEach(function (child) {
if (!parents[child]) {
return;
}
// Recursively check children
checkCircular(child, found);
// Mark all ancestors as having this decendant
Object.keys(found).forEach(function (subtype) {
subtypes[subtype][child] = true;
});
});
delete found[type];
}
checkCircular(this.primaryType, {});
// Compute each fully describe type
for (var name_2 in subtypes) {
var st = Object.keys(subtypes[name_2]);
st.sort();
this._types[name_2] = encodeType(name_2, types[name_2]) + st.map(function (t) { return encodeType(t, types[t]); }).join("");
}
}
TypedDataEncoder.prototype.getEncoder = function (type) {
var encoder = this._encoderCache[type];
if (!encoder) {
encoder = this._encoderCache[type] = this._getEncoder(type);
}
return encoder;
};
TypedDataEncoder.prototype._getEncoder = function (type) {
var _this = this;
// Basic encoder type (address, bool, uint256, etc)
{
var encoder = getBaseEncoder(type);
if (encoder) {
return encoder;
}
}
// Array
var match = type.match(/^(.*)(\x5b(\d*)\x5d)$/);
if (match) {
var subtype_1 = match[1];
var subEncoder_1 = this.getEncoder(subtype_1);
var length_1 = parseInt(match[3]);
return function (value) {
if (length_1 >= 0 && value.length !== length_1) {
logger.throwArgumentError("array length mismatch; expected length ${ arrayLength }", "value", value);
}
var result = value.map(subEncoder_1);
if (_this._types[subtype_1]) {
result = result.map(keccak256_1.keccak256);
}
return keccak256_1.keccak256(bytes_1.hexConcat(result));
};
}
// Struct
var fields = this.types[type];
if (fields) {
var encodedType_1 = id_1.id(this._types[type]);
return function (value) {
var values = fields.map(function (_a) {
var name = _a.name, type = _a.type;
var result = _this.getEncoder(type)(value[name]);
if (_this._types[type]) {
return keccak256_1.keccak256(result);
}
return result;
});
values.unshift(encodedType_1);
return bytes_1.hexConcat(values);
};
}
return logger.throwArgumentError("unknown type: " + type, "type", type);
};
TypedDataEncoder.prototype.encodeType = function (name) {
var result = this._types[name];
if (!result) {
logger.throwArgumentError("unknown type: " + JSON.stringify(name), "name", name);
}
return result;
};
TypedDataEncoder.prototype.encodeData = function (type, value) {
return this.getEncoder(type)(value);
};
TypedDataEncoder.prototype.hashStruct = function (name, value) {
return keccak256_1.keccak256(this.encodeData(name, value));
};
TypedDataEncoder.prototype.encode = function (value) {
return this.encodeData(this.primaryType, value);
};
TypedDataEncoder.prototype.hash = function (value) {
return this.hashStruct(this.primaryType, value);
};
TypedDataEncoder.prototype._visit = function (type, value, callback) {
var _this = this;
// Basic encoder type (address, bool, uint256, etc)
{
var encoder = getBaseEncoder(type);
if (encoder) {
return callback(type, value);
}
}
// Array
var match = type.match(/^(.*)(\x5b(\d*)\x5d)$/);
if (match) {
var subtype_2 = match[1];
var length_2 = parseInt(match[3]);
if (length_2 >= 0 && value.length !== length_2) {
logger.throwArgumentError("array length mismatch; expected length ${ arrayLength }", "value", value);
}
return value.map(function (v) { return _this._visit(subtype_2, v, callback); });
}
// Struct
var fields = this.types[type];
if (fields) {
return fields.reduce(function (accum, _a) {
var name = _a.name, type = _a.type;
accum[name] = _this._visit(type, value[name], callback);
return accum;
}, {});
}
return logger.throwArgumentError("unknown type: " + type, "type", type);
};
TypedDataEncoder.prototype.visit = function (value, callback) {
return this._visit(this.primaryType, value, callback);
};
TypedDataEncoder.from = function (types) {
return new TypedDataEncoder(types);
};
TypedDataEncoder.getPrimaryType = function (types) {
return TypedDataEncoder.from(types).primaryType;
};
TypedDataEncoder.hashStruct = function (name, types, value) {
return TypedDataEncoder.from(types).hashStruct(name, value);
};
TypedDataEncoder.hashDomain = function (domain) {
var domainFields = [];
for (var name_3 in domain) {
var type = domainFieldTypes[name_3];
if (!type) {
logger.throwArgumentError("invalid typed-data domain key: " + JSON.stringify(name_3), "domain", domain);
}
domainFields.push({ name: name_3, type: type });
}
domainFields.sort(function (a, b) {
return domainFieldNames.indexOf(a.name) - domainFieldNames.indexOf(b.name);
});
return TypedDataEncoder.hashStruct("EIP712Domain", { EIP712Domain: domainFields }, domain);
};
TypedDataEncoder.encode = function (domain, types, value) {
return bytes_1.hexConcat([
"0x1901",
TypedDataEncoder.hashDomain(domain),
TypedDataEncoder.from(types).hash(value)
]);
};
TypedDataEncoder.hash = function (domain, types, value) {
return keccak256_1.keccak256(TypedDataEncoder.encode(domain, types, value));
};
// Replaces all address types with ENS names with their looked up address
TypedDataEncoder.resolveNames = function (domain, types, value, resolveName) {
return __awaiter(this, void 0, void 0, function () {
var ensCache, encoder, _a, _b, _i, name_4, _c, _d;
return __generator(this, function (_e) {
switch (_e.label) {
case 0:
// Make a copy to isolate it from the object passed in
domain = properties_1.shallowCopy(domain);
ensCache = {};
// Do we need to look up the domain's verifyingContract?
if (domain.verifyingContract && !bytes_1.isHexString(domain.verifyingContract, 20)) {
ensCache[domain.verifyingContract] = "0x";
}
encoder = TypedDataEncoder.from(types);
// Get a list of all the addresses
encoder.visit(value, function (type, value) {
if (type === "address" && !bytes_1.isHexString(value, 20)) {
ensCache[value] = "0x";
}
return value;
});
_a = [];
for (_b in ensCache)
_a.push(_b);
_i = 0;
_e.label = 1;
case 1:
if (!(_i < _a.length)) return [3 /*break*/, 4];
name_4 = _a[_i];
_c = ensCache;
_d = name_4;
return [4 /*yield*/, resolveName(name_4)];
case 2:
_c[_d] = _e.sent();
_e.label = 3;
case 3:
_i++;
return [3 /*break*/, 1];
case 4:
// Replace the domain verifyingContract if needed
if (domain.verifyingContract && ensCache[domain.verifyingContract]) {
domain.verifyingContract = ensCache[domain.verifyingContract];
}
// Replace all ENS names with their address
value = encoder.visit(value, function (type, value) {
if (type === "address" && ensCache[value]) {
return ensCache[value];
}
return value;
});
return [2 /*return*/, { domain: domain, value: value }];
}
});
});
};
TypedDataEncoder.getPayload = function (domain, types, value) {
// Validate the domain fields
TypedDataEncoder.hashDomain(domain);
// Derive the EIP712Domain Struct reference type
var domainValues = {};
var domainTypes = [];
domainFieldNames.forEach(function (name) {
var value = domain[name];
if (value == null) {
return;
}
domainValues[name] = domainChecks[name](value);
domainTypes.push({ name: name, type: domainFieldTypes[name] });
});
var encoder = TypedDataEncoder.from(types);
var typesWithDomain = properties_1.shallowCopy(types);
if (typesWithDomain.EIP712Domain) {
typesWithDomain.EIP712Domain = domainTypes;
}
// Validate the data structures and types
encoder.encode(value);
return {
types: typesWithDomain,
domain: domainValues,
primaryType: encoder.primaryType,
message: encoder.visit(value, function (type, value) {
// bytes
if (type.match(/^bytes(\d*)/)) {
return bytes_1.hexlify(bytes_1.arrayify(value));
}
// uint or int
if (type.match(/^u?int/)) {
var prefix = "";
var v = bignumber_1.BigNumber.from(value);
if (v.isNegative()) {
prefix = "-";
v = v.mul(-1);
}
return prefix + bytes_1.hexValue(v.toHexString());
}
switch (type) {
case "address":
return value.toLowerCase();
case "bool":
return !!value;
case "string":
if (typeof (value) !== "string") {
logger.throwArgumentError("invalid string", "value", value);
}
return value;
}
return logger.throwArgumentError("unsupported type", "type", type);
})
};
};
return TypedDataEncoder;
}());
exports.TypedDataEncoder = TypedDataEncoder;
//# sourceMappingURL=typed-data.js.map
+41
View File
@@ -0,0 +1,41 @@
{
"author": "Richard Moore <me@ricmoo.com>",
"dependencies": {
"@ethersproject/abstract-signer": "^5.0.6",
"@ethersproject/address": "^5.0.5",
"@ethersproject/bignumber": "^5.0.8",
"@ethersproject/bytes": "^5.0.4",
"@ethersproject/keccak256": "^5.0.3",
"@ethersproject/logger": "^5.0.5",
"@ethersproject/properties": "^5.0.4",
"@ethersproject/strings": "^5.0.4"
},
"description": "Hash utility functions for Ethereum.",
"ethereum": "donations.ethers.eth",
"gitHead": "86146650d83865d83b10867e9592923eada5d7cc",
"keywords": [
"Ethereum",
"ethers"
],
"license": "MIT",
"main": "./lib/index.js",
"module": "./lib.esm/index.js",
"name": "@ethersproject/hash",
"publishConfig": {
"access": "public"
},
"repository": {
"type": "git",
"url": "git://github.com/ethers-io/ethers.js.git"
},
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"tarballHash": "0xd3ced44284f7527cca27da2835c7eaeb117480dc6d459415ece6a672679cd538",
"types": "./lib/index.d.ts",
"version": "5.0.6"
,"_resolved": "https://registry.npmjs.org/@ethersproject/hash/-/hash-5.0.6.tgz"
,"_integrity": "sha512-Gvh57v6BWhwnud6l7tMfQm32PRQ2DYx2WaAAQmAxAfYvmzUkpQCBstnGeNMXIL8/2wdkvcB2u+WZRWaZtsFuUQ=="
,"_from": "@ethersproject/hash@>=5.0.0-beta.128"
}