PHP WebShell
Текущая директория: /usr/lib/node_modules/bitgo/node_modules/@celo/contractkit/lib/wrappers
Просмотр файла: Attestations.js
"use strict";
var __extends = (this && this.__extends) || (function () {
var extendStatics = function (d, b) {
extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
return extendStatics(d, b);
};
return function (d, b) {
if (typeof b !== "function" && b !== null)
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
var __assign = (this && this.__assign) || function () {
__assign = Object.assign || function(t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
t[p] = s[p];
}
return t;
};
return __assign.apply(this, arguments);
};
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 };
}
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.AttestationServiceStatusState = exports.AttestationsWrapper = exports.AttestationState = exports.getSecurityCodePrefix = void 0;
var base_1 = require("@celo/base");
var address_1 = require("@celo/base/lib/address");
var async_1 = require("@celo/base/lib/async");
var collections_1 = require("@celo/base/lib/collections");
var parsing_1 = require("@celo/base/lib/parsing");
var string_1 = require("@celo/base/lib/string");
var connect_1 = require("@celo/connect");
var lib_1 = require("@celo/utils/lib");
var typed_data_constructors_1 = require("@celo/utils/lib/typed-data-constructors");
var bignumber_js_1 = __importDefault(require("bignumber.js"));
var cross_fetch_1 = __importDefault(require("cross-fetch"));
var identity_1 = require("../identity");
var BaseWrapper_1 = require("./BaseWrapper");
function hashAddressToSingleDigit(address) {
return new bignumber_js_1.default(address.toLowerCase()).modulo(10).toNumber();
}
function getSecurityCodePrefix(issuerAddress) {
return "".concat(hashAddressToSingleDigit(issuerAddress));
}
exports.getSecurityCodePrefix = getSecurityCodePrefix;
/**
* Contract for managing identities
*/
var AttestationState;
(function (AttestationState) {
AttestationState[AttestationState["None"] = 0] = "None";
AttestationState[AttestationState["Incomplete"] = 1] = "Incomplete";
AttestationState[AttestationState["Complete"] = 2] = "Complete";
})(AttestationState = exports.AttestationState || (exports.AttestationState = {}));
function parseGetCompletableAttestations(response) {
var metadataURLs = (0, parsing_1.parseSolidityStringArray)(response[2].map(BaseWrapper_1.valueToInt), response[3]);
return (0, collections_1.zip3)(response[0].map(BaseWrapper_1.valueToInt), response[1], metadataURLs).map(function (_a) {
var blockNumber = _a[0], issuer = _a[1], metadataURL = _a[2];
return ({ blockNumber: blockNumber, issuer: issuer, metadataURL: metadataURL });
});
}
var AttestationsWrapper = /** @class */ (function (_super) {
__extends(AttestationsWrapper, _super);
function AttestationsWrapper(connection, contract, contracts) {
var _this = _super.call(this, connection, contract) || this;
_this.connection = connection;
_this.contract = contract;
_this.contracts = contracts;
/**
* Returns the time an attestation can be completable before it is considered expired
*/
_this.attestationExpiryBlocks = (0, BaseWrapper_1.proxyCall)(_this.contract.methods.attestationExpiryBlocks, undefined, BaseWrapper_1.valueToInt);
/**
* Returns the attestation request fee in a given currency.
* @param address Token address.
* @returns The fee as big number.
*/
_this.attestationRequestFees = (0, BaseWrapper_1.proxyCall)(_this.contract.methods.attestationRequestFees, undefined, BaseWrapper_1.valueToBigNumber);
_this.selectIssuersWaitBlocks = (0, BaseWrapper_1.proxyCall)(_this.contract.methods.selectIssuersWaitBlocks, undefined, BaseWrapper_1.valueToInt);
/**
* @notice Returns the unselected attestation request for an identifier/account pair, if any.
* @param identifier Attestation identifier (e.g. phone hash)
* @param account Address of the account
*/
_this.getUnselectedRequest = (0, BaseWrapper_1.proxyCall)(_this.contract.methods.getUnselectedRequest, undefined, function (res) { return ({
blockNumber: (0, BaseWrapper_1.valueToInt)(res[0]),
attestationsRequested: (0, BaseWrapper_1.valueToInt)(res[1]),
attestationRequestFeeToken: res[2],
}); });
/**
* @notice Checks if attestation request is expired.
* @param attestationRequestBlockNumber Attestation Request Block Number to be checked
*/
_this.isAttestationExpired = function (attestationRequestBlockNumber) { return __awaiter(_this, void 0, void 0, function () {
var attestationExpiryBlocks, blockNumber;
return __generator(this, function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/, this.attestationExpiryBlocks()];
case 1:
attestationExpiryBlocks = _a.sent();
return [4 /*yield*/, this.connection.getBlockNumber()];
case 2:
blockNumber = _a.sent();
return [2 /*return*/, blockNumber >= attestationRequestBlockNumber + attestationExpiryBlocks];
}
});
}); };
/**
* @notice Waits for appropriate block numbers for before issuer can be selected
* @param identifier Attestation identifier (e.g. phone hash)
* @param account Address of the account
*/
_this.waitForSelectingIssuers = function (identifier, account, timeoutSeconds, pollDurationSeconds) {
if (timeoutSeconds === void 0) { timeoutSeconds = 120; }
if (pollDurationSeconds === void 0) { pollDurationSeconds = 1; }
return __awaiter(_this, void 0, void 0, function () {
var startTime, unselectedRequest, waitBlocks, blockNumber;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
startTime = Date.now();
return [4 /*yield*/, this.getUnselectedRequest(identifier, account)];
case 1:
unselectedRequest = _a.sent();
return [4 /*yield*/, this.selectIssuersWaitBlocks()];
case 2:
waitBlocks = _a.sent();
if (unselectedRequest.blockNumber === 0) {
throw new Error('No unselectedRequest to wait for');
}
_a.label = 3;
case 3:
if (!(Date.now() - startTime < timeoutSeconds * 1000)) return [3 /*break*/, 6];
return [4 /*yield*/, this.connection.getBlockNumber()];
case 4:
blockNumber = _a.sent();
if (blockNumber >= unselectedRequest.blockNumber + waitBlocks) {
return [2 /*return*/];
}
return [4 /*yield*/, (0, async_1.sleep)(pollDurationSeconds * 1000)];
case 5:
_a.sent();
return [3 /*break*/, 3];
case 6: throw new Error('Timeout while waiting for selecting issuers');
}
});
});
};
/**
* Returns the issuers of attestations for a phoneNumber/account combo
* @param identifier Attestation identifier (e.g. phone hash)
* @param account Address of the account
*/
_this.getAttestationIssuers = (0, BaseWrapper_1.proxyCall)(_this.contract.methods.getAttestationIssuers);
/**
* Returns the attestation state of a phone number/account/issuer tuple
* @param identifier Attestation identifier (e.g. phone hash)
* @param account Address of the account
*/
_this.getAttestationState = (0, BaseWrapper_1.proxyCall)(_this.contract.methods.getAttestationState, undefined, function (state) { return ({ attestationState: (0, BaseWrapper_1.valueToInt)(state[0]) }); });
/**
* Returns the attestation stats of a identifer/account pair
* @param identifier Attestation identifier (e.g. phone hash)
* @param account Address of the account
*/
_this.getAttestationStat = (0, BaseWrapper_1.proxyCall)(_this.contract.methods.getAttestationStats, undefined, function (stat) { return ({ completed: (0, BaseWrapper_1.valueToInt)(stat[0]), total: (0, BaseWrapper_1.valueToInt)(stat[1]) }); });
_this.makeIsIssuerRunningAttestationService = function (tries) {
if (tries === void 0) { tries = 3; }
return function (arg) { return __awaiter(_this, void 0, void 0, function () {
var metadata, _a, _b, attestationServiceURLClaim, nameClaim, resp, _c, status_1, version, error_1;
return __generator(this, function (_d) {
switch (_d.label) {
case 0:
_d.trys.push([0, 5, , 6]);
_b = (_a = identity_1.IdentityMetadataWrapper).fetchFromURL;
return [4 /*yield*/, this.contracts.getAccounts()];
case 1: return [4 /*yield*/, _b.apply(_a, [_d.sent(), arg.metadataURL,
tries])];
case 2:
metadata = _d.sent();
attestationServiceURLClaim = metadata.findClaim(identity_1.ClaimTypes.ATTESTATION_SERVICE_URL);
if (attestationServiceURLClaim === undefined) {
throw new Error("No attestation service URL registered for ".concat(arg.issuer));
}
nameClaim = metadata.findClaim(identity_1.ClaimTypes.NAME);
return [4 /*yield*/, (0, cross_fetch_1.default)("".concat(attestationServiceURLClaim.url).concat(attestationServiceURLClaim.url.substr(-1) === '/' ? '' : '/', "status"))];
case 3:
resp = _d.sent();
if (!resp.ok) {
throw new Error("Request failed with status ".concat(resp.status));
}
return [4 /*yield*/, resp.json()];
case 4:
_c = _d.sent(), status_1 = _c.status, version = _c.version;
if (status_1 !== 'ok') {
return [2 /*return*/, { isValid: false, issuer: arg.issuer }];
}
return [2 /*return*/, {
isValid: true,
result: {
blockNumber: arg.blockNumber,
issuer: arg.issuer,
attestationServiceURL: attestationServiceURLClaim.url,
name: nameClaim ? nameClaim.name : undefined,
version: version,
},
}];
case 5:
error_1 = _d.sent();
return [2 /*return*/, { isValid: false, issuer: arg.issuer }];
case 6: return [2 /*return*/];
}
});
}); };
};
/**
* Returns the attestation signer for the specified account.
* @param account The address of token rewards are accumulated in.
* @param account The address of the account.
* @return The reward amount.
*/
_this.getPendingWithdrawals = (0, BaseWrapper_1.proxyCall)(_this.contract.methods.pendingWithdrawals, undefined, BaseWrapper_1.valueToBigNumber);
/**
* Allows issuers to withdraw accumulated attestation rewards
* @param address The address of the token that will be withdrawn
*/
_this.withdraw = (0, BaseWrapper_1.proxySend)(_this.connection, _this.contract.methods.withdraw);
/**
* Returns the list of accounts associated with an identifier.
* @param identifier Attestation identifier (e.g. phone hash)
*/
_this.lookupAccountsForIdentifier = (0, BaseWrapper_1.proxyCall)(_this.contract.methods.lookupAccountsForIdentifier);
/**
* Updates sender's approval status on whether to allow an attestation identifier
* mapping to be transfered from one address to another.
* @param identifier The identifier for this attestation.
* @param index The index of the account in the accounts array.
* @param from The current attestation address to which the identifier is mapped.
* @param to The new address to map to identifier.
* @param status The approval status
*/
_this.approveTransfer = (0, BaseWrapper_1.proxySend)(_this.connection, _this.contract.methods.approveTransfer);
return _this;
}
/**
* Returns the verified status of an identifier/account pair indicating whether the attestation
* stats for a given pair are completed beyond a certain threshold of confidence (aka "verified")
* @param identifier Attestation identifier (e.g. phone hash)
* @param account Address of the account
* @param numAttestationsRequired Optional number of attestations required. Will default to
* hardcoded value if absent.
* @param attestationThreshold Optional threshold for fraction attestations completed. Will
* default to hardcoded value if absent.
*/
AttestationsWrapper.prototype.getVerifiedStatus = function (identifier, account, numAttestationsRequired, attestationThreshold) {
return __awaiter(this, void 0, void 0, function () {
var attestationStats;
return __generator(this, function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/, this.getAttestationStat(identifier, account)];
case 1:
attestationStats = _a.sent();
return [2 /*return*/, lib_1.AttestationUtils.isAccountConsideredVerified(attestationStats, numAttestationsRequired, attestationThreshold)];
}
});
});
};
/**
* Calculates the amount of StableToken required to request Attestations
* @param attestationsRequested The number of attestations to request
*/
AttestationsWrapper.prototype.getAttestationFeeRequired = function (attestationsRequested) {
return __awaiter(this, void 0, void 0, function () {
var contract, attestationFee;
return __generator(this, function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/, this.contracts.getStableToken(base_1.StableToken.cUSD)];
case 1:
contract = _a.sent();
return [4 /*yield*/, this.contract.methods
.getAttestationRequestFee(contract.address)
.call()];
case 2:
attestationFee = _a.sent();
return [2 /*return*/, new bignumber_js_1.default(attestationFee).times(attestationsRequested)];
}
});
});
};
/**
* Approves the necessary amount of StableToken to request Attestations
* @param attestationsRequested The number of attestations to request
*/
AttestationsWrapper.prototype.approveAttestationFee = function (attestationsRequested) {
return __awaiter(this, void 0, void 0, function () {
var tokenContract, fee;
return __generator(this, function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/, this.contracts.getStableToken(base_1.StableToken.cUSD)];
case 1:
tokenContract = _a.sent();
return [4 /*yield*/, this.getAttestationFeeRequired(attestationsRequested)];
case 2:
fee = _a.sent();
return [2 /*return*/, tokenContract.approve(this.address, fee.toFixed())];
}
});
});
};
/**
* Returns an array of attestations that can be completed, along with the issuers' attestation
* service urls
* @param identifier Attestation identifier (e.g. phone hash)
* @param account Address of the account
*/
AttestationsWrapper.prototype.getActionableAttestations = function (identifier, account, tries) {
if (tries === void 0) { tries = 3; }
return __awaiter(this, void 0, void 0, function () {
var result, results;
return __generator(this, function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/, this.contract.methods
.getCompletableAttestations(identifier, account)
.call()];
case 1:
result = _a.sent();
return [4 /*yield*/, (0, async_1.concurrentMap)(5, parseGetCompletableAttestations(result), this.makeIsIssuerRunningAttestationService(tries))];
case 2:
results = _a.sent();
return [2 /*return*/, results.map(function (_) { return (_.isValid ? _.result : null); }).filter(collections_1.notEmpty)];
}
});
});
};
/**
* Returns an array of issuer addresses that were found to not run the attestation service
* @param identifier Attestation identifier (e.g. phone hash)
* @param account Address of the account
*/
AttestationsWrapper.prototype.getNonCompliantIssuers = function (identifier, account, tries) {
if (tries === void 0) { tries = 3; }
return __awaiter(this, void 0, void 0, function () {
var result, withAttestationServiceURLs;
return __generator(this, function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/, this.contract.methods
.getCompletableAttestations(identifier, account)
.call()];
case 1:
result = _a.sent();
return [4 /*yield*/, (0, async_1.concurrentMap)(5, parseGetCompletableAttestations(result), this.makeIsIssuerRunningAttestationService(tries))];
case 2:
withAttestationServiceURLs = _a.sent();
return [2 /*return*/, withAttestationServiceURLs.map(function (_) { return (_.isValid ? null : _.issuer); }).filter(collections_1.notEmpty)];
}
});
});
};
/**
* Completes an attestation with the corresponding code
* @param identifier Attestation identifier (e.g. phone hash)
* @param account Address of the account
* @param issuer The issuer of the attestation
* @param code The code received by the validator
*/
AttestationsWrapper.prototype.complete = function (identifier, account, issuer, code) {
return __awaiter(this, void 0, void 0, function () {
var accounts, attestationSigner, expectedSourceMessage, _a, r, s, v;
return __generator(this, function (_b) {
switch (_b.label) {
case 0: return [4 /*yield*/, this.contracts.getAccounts()];
case 1:
accounts = _b.sent();
return [4 /*yield*/, accounts.getAttestationSigner(issuer)];
case 2:
attestationSigner = _b.sent();
expectedSourceMessage = lib_1.AttestationUtils.getAttestationMessageToSignFromIdentifier(identifier, account);
_a = lib_1.SignatureUtils.parseSignature(expectedSourceMessage, code, attestationSigner), r = _a.r, s = _a.s, v = _a.v;
return [2 /*return*/, (0, connect_1.toTransactionObject)(this.connection, this.contract.methods.complete(identifier, v, r, s))];
}
});
});
};
/**
* Given a list of issuers, finds the matching issuer for a given code
* @param identifier Attestation identifier (e.g. phone hash)
* @param account Address of the account
* @param code The code received by the validator
* @param issuers The list of potential issuers
*/
AttestationsWrapper.prototype.findMatchingIssuer = function (identifier, account, code, issuers) {
return __awaiter(this, void 0, void 0, function () {
var accounts, expectedSourceMessage, _i, issuers_1, issuer, attestationSigner;
return __generator(this, function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/, this.contracts.getAccounts()];
case 1:
accounts = _a.sent();
expectedSourceMessage = lib_1.AttestationUtils.getAttestationMessageToSignFromIdentifier(identifier, account);
_i = 0, issuers_1 = issuers;
_a.label = 2;
case 2:
if (!(_i < issuers_1.length)) return [3 /*break*/, 5];
issuer = issuers_1[_i];
return [4 /*yield*/, accounts.getAttestationSigner(issuer)];
case 3:
attestationSigner = _a.sent();
try {
lib_1.SignatureUtils.parseSignature(expectedSourceMessage, code, attestationSigner);
return [2 /*return*/, issuer];
}
catch (error) {
return [3 /*break*/, 4];
}
_a.label = 4;
case 4:
_i++;
return [3 /*break*/, 2];
case 5: return [2 /*return*/, null];
}
});
});
};
/**
* Returns the current configuration parameters for the contract.
* @param tokens List of tokens used for attestation fees. use CeloTokens.getAddresses() to get
* @return AttestationsConfig object
*/
AttestationsWrapper.prototype.getConfig = function (tokens) {
return __awaiter(this, void 0, void 0, function () {
var feeTokens, fees;
var _a;
var _this = this;
return __generator(this, function (_b) {
switch (_b.label) {
case 0:
feeTokens = tokens;
return [4 /*yield*/, Promise.all(feeTokens.map(function (token) { return __awaiter(_this, void 0, void 0, function () {
var fee;
return __generator(this, function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/, this.attestationRequestFees(token)];
case 1:
fee = _a.sent();
return [2 /*return*/, { fee: fee, address: token }];
}
});
}); }))];
case 1:
fees = _b.sent();
_a = {};
return [4 /*yield*/, this.attestationExpiryBlocks()];
case 2: return [2 /*return*/, (_a.attestationExpiryBlocks = _b.sent(),
_a.attestationRequestFees = fees,
_a)];
}
});
});
};
/**
* @dev Returns human readable configuration of the attestations contract
* @param tokens List of tokens used for attestation fees. use CeloTokens.getAddresses() to get
* @return AttestationsConfig object
*/
AttestationsWrapper.prototype.getHumanReadableConfig = function (tokens) {
return __awaiter(this, void 0, void 0, function () {
var config;
return __generator(this, function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/, this.getConfig(tokens)];
case 1:
config = _a.sent();
return [2 /*return*/, {
attestationRequestFees: config.attestationRequestFees,
attestationExpiry: (0, BaseWrapper_1.blocksToDurationString)(config.attestationExpiryBlocks),
}];
}
});
});
};
/**
* Lookup mapped wallet addresses for a given list of identifiers
* @param identifiers Attestation identifiers (e.g. phone hashes)
*/
AttestationsWrapper.prototype.lookupIdentifiers = function (identifiers) {
return __awaiter(this, void 0, void 0, function () {
var stats, matches, addresses, completed, total, result, rIndex, pIndex, pHash, numberOfMatches, matchingAddresses, mIndex, matchingAddress;
return __generator(this, function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/, this.contract.methods.batchGetAttestationStats(identifiers).call()];
case 1:
stats = _a.sent();
matches = stats[0].map(BaseWrapper_1.valueToInt);
addresses = stats[1];
completed = stats[2].map(BaseWrapper_1.valueToInt);
total = stats[3].map(BaseWrapper_1.valueToInt);
result = {};
rIndex = 0;
for (pIndex = 0; pIndex < identifiers.length; pIndex++) {
pHash = identifiers[pIndex];
numberOfMatches = matches[pIndex];
if (numberOfMatches === 0) {
continue;
}
matchingAddresses = {};
for (mIndex = 0; mIndex < numberOfMatches; mIndex++) {
matchingAddress = addresses[rIndex];
matchingAddresses[matchingAddress] = {
completed: completed[rIndex],
total: total[rIndex],
};
rIndex++;
}
result[pHash] = matchingAddresses;
}
return [2 /*return*/, result];
}
});
});
};
/**
* Requests a new attestation
* @param identifier Attestation identifier (e.g. phone hash)
* @param attestationsRequested The number of attestations to request
*/
AttestationsWrapper.prototype.request = function (identifier, attestationsRequested) {
return __awaiter(this, void 0, void 0, function () {
var contract;
return __generator(this, function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/, this.contracts.getStableToken(base_1.StableToken.cUSD)];
case 1:
contract = _a.sent();
return [2 /*return*/, (0, connect_1.toTransactionObject)(this.connection, this.contract.methods.request(identifier, attestationsRequested, contract.address))];
}
});
});
};
/**
* Selects the issuers for previously requested attestations for a phone number
* @param identifier Attestation identifier (e.g. phone hash)
*/
AttestationsWrapper.prototype.selectIssuers = function (identifier) {
return (0, connect_1.toTransactionObject)(this.connection, this.contract.methods.selectIssuers(identifier));
};
/**
* Waits appropriate number of blocks, then selects issuers for previously requested phone number attestations
* @param identifier Attestation identifier (e.g. phone hash)
* @param account Address of the account
*/
AttestationsWrapper.prototype.selectIssuersAfterWait = function (identifier, account, timeoutSeconds, pollDurationSeconds) {
return __awaiter(this, void 0, void 0, function () {
return __generator(this, function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/, this.waitForSelectingIssuers(identifier, account, timeoutSeconds, pollDurationSeconds)];
case 1:
_a.sent();
return [2 /*return*/, this.selectIssuers(identifier)];
}
});
});
};
/**
* Reveal phone number to issuer
* @param serviceURL: validator's attestation service URL
* @param body
*/
AttestationsWrapper.prototype.revealPhoneNumberToIssuer = function (serviceURL, requestBody) {
return (0, cross_fetch_1.default)((0, string_1.appendPath)(serviceURL, 'attestations'), {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(requestBody),
});
};
/**
* Returns reveal status from validator's attestation service
* @param phoneNumber: attestation's phone number
* @param account: attestation's account
* @param issuer: validator's address
* @param serviceURL: validator's attestation service URL
* @param pepper: phone number privacy pepper
*/
AttestationsWrapper.prototype.getRevealStatus = function (phoneNumber, account, issuer, serviceURL, pepper) {
var urlParams = new URLSearchParams({
phoneNumber: phoneNumber,
salt: pepper !== null && pepper !== void 0 ? pepper : '',
issuer: issuer,
account: account,
});
return (0, cross_fetch_1.default)((0, string_1.appendPath)(serviceURL, 'get_attestations') + '?' + urlParams, {
method: 'GET',
headers: { 'Content-Type': 'application/json' },
});
};
/**
* Returns attestation code for provided security code from validator's attestation service
* @param serviceURL: validator's attestation service URL
* @param body
*/
AttestationsWrapper.prototype.getAttestationForSecurityCode = function (serviceURL, requestBody, signer) {
return __awaiter(this, void 0, void 0, function () {
var urlParams, additionalHeaders, signature, response, ok, status, body, _a, _b, _c;
return __generator(this, function (_d) {
switch (_d.label) {
case 0:
urlParams = new URLSearchParams({
phoneNumber: requestBody.phoneNumber,
account: requestBody.account,
issuer: requestBody.issuer,
});
additionalHeaders = {};
if (requestBody.salt) {
urlParams.set('salt', requestBody.salt);
}
if (!requestBody.securityCode) return [3 /*break*/, 2];
urlParams.set('securityCode', requestBody.securityCode);
return [4 /*yield*/, this.connection.signTypedData(signer, (0, typed_data_constructors_1.attestationSecurityCode)(requestBody.securityCode))];
case 1:
signature = _d.sent();
additionalHeaders = {
Authentication: lib_1.SignatureUtils.serializeSignature(signature),
};
_d.label = 2;
case 2: return [4 /*yield*/, (0, cross_fetch_1.default)((0, string_1.appendPath)(serviceURL, 'get_attestations') + '?' + urlParams, {
method: 'GET',
headers: __assign({ 'Content-Type': 'application/json' }, additionalHeaders),
})];
case 3:
response = _d.sent();
ok = response.ok, status = response.status;
if (!ok) return [3 /*break*/, 5];
return [4 /*yield*/, response.json()];
case 4:
body = _d.sent();
if (body.attestationCode) {
return [2 /*return*/, body.attestationCode];
}
_d.label = 5;
case 5:
_a = Error.bind;
_c = (_b = "Error getting security code for ".concat(requestBody.issuer, ". ").concat(status, ": ")).concat;
return [4 /*yield*/, response.text()];
case 6: throw new (_a.apply(Error, [void 0, _c.apply(_b, [_d.sent()])]))();
}
});
});
};
/**
* Validates a given code by the issuer on-chain
* @param identifier Attestation identifier (e.g. phone hash)
* @param account The address of the account which requested attestation
* @param issuer The address of the issuer of the attestation
* @param code The code send by the issuer
*/
AttestationsWrapper.prototype.validateAttestationCode = function (identifier, account, issuer, code) {
return __awaiter(this, void 0, void 0, function () {
var accounts, attestationSigner, expectedSourceMessage, _a, r, s, v, result;
return __generator(this, function (_b) {
switch (_b.label) {
case 0: return [4 /*yield*/, this.contracts.getAccounts()];
case 1:
accounts = _b.sent();
return [4 /*yield*/, accounts.getAttestationSigner(issuer)];
case 2:
attestationSigner = _b.sent();
expectedSourceMessage = lib_1.AttestationUtils.getAttestationMessageToSignFromIdentifier(identifier, account);
_a = lib_1.SignatureUtils.parseSignature(expectedSourceMessage, code, attestationSigner), r = _a.r, s = _a.s, v = _a.v;
return [4 /*yield*/, this.contract.methods
.validateAttestationCode(identifier, account, v, r, s)
.call()];
case 3:
result = _b.sent();
return [2 /*return*/, result.toLowerCase() !== address_1.NULL_ADDRESS];
}
});
});
};
/**
* Gets the relevant attestation service status for a validator
* @param validator Validator to get the attestation service status for
*/
AttestationsWrapper.prototype.getAttestationServiceStatus = function (validator) {
return __awaiter(this, void 0, void 0, function () {
var accounts, hasAttestationSigner, attestationSigner, attestationServiceURL, ret, metadataURL, metadata, _a, _b, attestationServiceURLClaim, error_2, statusResponse, statusResponseBody, healthzResponse, healthzResponseBody, error_3, error_4;
return __generator(this, function (_c) {
switch (_c.label) {
case 0: return [4 /*yield*/, this.contracts.getAccounts()];
case 1:
accounts = _c.sent();
return [4 /*yield*/, accounts.hasAuthorizedAttestationSigner(validator.address)];
case 2:
hasAttestationSigner = _c.sent();
return [4 /*yield*/, accounts.getAttestationSigner(validator.address)];
case 3:
attestationSigner = _c.sent();
ret = __assign(__assign({}, validator), { hasAttestationSigner: hasAttestationSigner, attestationSigner: attestationSigner, attestationServiceURL: null, okStatus: false, error: null, smsProviders: [], blacklistedRegionCodes: [], rightAccount: false, metadataURL: null, state: AttestationServiceStatusState.NoAttestationSigner, version: null, ageOfLatestBlock: null, smsProvidersRandomized: null, maxDeliveryAttempts: null, maxRerequestMins: null, twilioVerifySidProvided: null });
if (!hasAttestationSigner) {
return [2 /*return*/, ret];
}
return [4 /*yield*/, accounts.getMetadataURL(validator.address)];
case 4:
metadataURL = _c.sent();
ret.metadataURL = metadataURL;
if (!metadataURL) {
ret.state = AttestationServiceStatusState.NoMetadataURL;
return [2 /*return*/, ret];
}
if (metadataURL.startsWith('http://')) {
ret.state = AttestationServiceStatusState.InvalidAttestationServiceURL;
return [2 /*return*/, ret];
}
_c.label = 5;
case 5:
_c.trys.push([5, 8, , 9]);
_b = (_a = identity_1.IdentityMetadataWrapper).fetchFromURL;
return [4 /*yield*/, this.contracts.getAccounts()];
case 6: return [4 /*yield*/, _b.apply(_a, [_c.sent(), metadataURL])];
case 7:
metadata = _c.sent();
attestationServiceURLClaim = metadata.findClaim(identity_1.ClaimTypes.ATTESTATION_SERVICE_URL);
if (!attestationServiceURLClaim) {
ret.state = AttestationServiceStatusState.NoAttestationServiceURL;
return [2 /*return*/, ret];
}
attestationServiceURL = attestationServiceURLClaim.url;
return [3 /*break*/, 9];
case 8:
error_2 = _c.sent();
ret.state =
error_2.type === 'system'
? AttestationServiceStatusState.MetadataTimeout
: AttestationServiceStatusState.InvalidMetadata;
ret.error = error_2;
return [2 /*return*/, ret];
case 9:
ret.attestationServiceURL = attestationServiceURL;
_c.label = 10;
case 10:
_c.trys.push([10, 20, , 21]);
return [4 /*yield*/, (0, cross_fetch_1.default)((0, string_1.appendPath)(attestationServiceURL, 'status'))];
case 11:
statusResponse = _c.sent();
if (!statusResponse.ok) {
ret.state = AttestationServiceStatusState.UnreachableAttestationService;
return [2 /*return*/, ret];
}
ret.okStatus = true;
return [4 /*yield*/, statusResponse.json()];
case 12:
statusResponseBody = _c.sent();
ret.smsProviders = statusResponseBody.smsProviders;
ret.rightAccount = (0, address_1.eqAddress)(validator.address, statusResponseBody.accountAddress);
ret.state = ret.rightAccount
? AttestationServiceStatusState.Valid
: AttestationServiceStatusState.WrongAccount;
ret.ageOfLatestBlock = statusResponseBody.ageOfLatestBlock;
ret.smsProvidersRandomized = statusResponseBody.smsProvidersRandomized;
ret.maxDeliveryAttempts = statusResponseBody.maxDeliveryAttempts;
ret.maxRerequestMins = statusResponseBody.maxRerequestMins;
ret.twilioVerifySidProvided = statusResponseBody.twilioVerifySidProvided;
if (!statusResponseBody.version) return [3 /*break*/, 18];
ret.version = statusResponseBody.version;
_c.label = 13;
case 13:
_c.trys.push([13, 16, , 17]);
return [4 /*yield*/, (0, cross_fetch_1.default)((0, string_1.appendPath)(attestationServiceURL, 'healthz'))];
case 14:
healthzResponse = _c.sent();
return [4 /*yield*/, healthzResponse.json()];
case 15:
healthzResponseBody = _c.sent();
if (!healthzResponse.ok) {
ret.state = AttestationServiceStatusState.Unhealthy;
if (healthzResponseBody.error) {
ret.error = healthzResponseBody.error;
}
}
return [3 /*break*/, 17];
case 16:
error_3 = _c.sent();
ret.state = AttestationServiceStatusState.UnreachableHealthz;
return [3 /*break*/, 17];
case 17:
// Whether or not health check is reachable, also check full node status
// (overrides UnreachableHealthz status)
if ((statusResponseBody.ageOfLatestBlock !== null &&
statusResponseBody.ageOfLatestBlock > 10) ||
statusResponseBody.isNodeSyncing === true) {
ret.state = AttestationServiceStatusState.Unhealthy;
}
return [3 /*break*/, 19];
case 18:
// No version implies 1.0.0
ret.version = '1.0.0';
_c.label = 19;
case 19: return [3 /*break*/, 21];
case 20:
error_4 = _c.sent();
ret.state = AttestationServiceStatusState.UnreachableAttestationService;
ret.error = error_4;
return [3 /*break*/, 21];
case 21: return [2 /*return*/, ret];
}
});
});
};
AttestationsWrapper.prototype.revoke = function (identifer, account) {
return __awaiter(this, void 0, void 0, function () {
var accounts, idx;
return __generator(this, function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/, this.lookupAccountsForIdentifier(identifer)];
case 1:
accounts = _a.sent();
idx = accounts.findIndex(function (acc) { return (0, address_1.eqAddress)(acc, account); });
if (idx < 0) {
throw new Error("Account not found in identifier's accounts");
}
return [2 /*return*/, (0, connect_1.toTransactionObject)(this.connection, this.contract.methods.revoke(identifer, idx))];
}
});
});
};
return AttestationsWrapper;
}(BaseWrapper_1.BaseWrapper));
exports.AttestationsWrapper = AttestationsWrapper;
var AttestationServiceStatusState;
(function (AttestationServiceStatusState) {
AttestationServiceStatusState["NoAttestationSigner"] = "NoAttestationSigner";
AttestationServiceStatusState["NoMetadataURL"] = "NoMetadataURL";
AttestationServiceStatusState["InvalidMetadata"] = "InvalidMetadata";
AttestationServiceStatusState["NoAttestationServiceURL"] = "NoAttestationServiceURL";
AttestationServiceStatusState["InvalidAttestationServiceURL"] = "InvalidAttestationServiceURL";
AttestationServiceStatusState["UnreachableAttestationService"] = "UnreachableAttestationService";
AttestationServiceStatusState["Valid"] = "Valid";
AttestationServiceStatusState["UnreachableHealthz"] = "UnreachableHealthz";
AttestationServiceStatusState["Unhealthy"] = "Unhealthy";
AttestationServiceStatusState["WrongAccount"] = "WrongAccount";
AttestationServiceStatusState["MetadataTimeout"] = "MetadataTimeout";
})(AttestationServiceStatusState = exports.AttestationServiceStatusState || (exports.AttestationServiceStatusState = {}));
//# sourceMappingURL=Attestations.js.mapВыполнить команду
Для локальной разработки. Не используйте в интернете!