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

Выполнить команду


Для локальной разработки. Не используйте в интернете!