"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.EthereumProviderIdentity = void 0;
const utils_1 = require("@streamr/utils");
const ethers_1 = require("ethers");
const promises_1 = require("../utils/promises");
const Identity_1 = require("./Identity");
const trackerless_network_1 = require("@streamr/trackerless-network");
/**
 * An identity that uses an Ethereum provider (= external wallet) to sign messages
 */
class EthereumProviderIdentity extends Identity_1.Identity {
    provider;
    expectedChainId;
    signer;
    cachedUserIdString;
    cachedUserIdBytes;
    rateLimitedSigner;
    constructor(provider, expectedChainId) {
        super();
        this.provider = provider;
        this.expectedChainId = expectedChainId;
        this.signer = provider.getSigner();
        this.rateLimitedSigner = (0, promises_1.pLimitFn)(async (payload) => {
            // sign one at a time & wait a moment before asking for next signature
            // otherwise MetaMask extension may not show the prompt window
            const sig = await (await this.signer).signMessage(payload);
            await (0, utils_1.wait)(50);
            return (0, utils_1.hexToBinary)(sig);
        }, 1);
    }
    async getUserIdRaw() {
        this.cachedUserIdBytes ??= (0, utils_1.toUserIdRaw)(await this.getUserId());
        return this.cachedUserIdBytes;
    }
    async getUserId() {
        this.cachedUserIdString ??= (0, utils_1.toUserId)(await (await this.signer).getAddress());
        return this.cachedUserIdString;
    }
    // eslint-disable-next-line class-methods-use-this
    getSignatureType() {
        return trackerless_network_1.SignatureType.ECDSA_SECP256K1_EVM;
    }
    async createMessageSignature(payload) {
        return this.rateLimitedSigner(payload);
    }
    async getTransactionSigner() {
        if (this.expectedChainId === undefined) {
            throw new Error('Streamr chainId not configuredin the StreamrClient options!');
        }
        const actualChainId = (await this.provider.getNetwork()).chainId;
        if (actualChainId !== BigInt(this.expectedChainId)) {
            throw new Error(`Connect your wallet to the chain with chainId ${this.expectedChainId} (chainId of currently selected chain is ${actualChainId})`);
        }
        return this.signer;
    }
    static fromConfig(config) {
        const ethereum = config.auth?.ethereum;
        const provider = new ethers_1.BrowserProvider(ethereum);
        return new EthereumProviderIdentity(provider, config.contracts.ethereumNetwork.chainId);
    }
}
exports.EthereumProviderIdentity = EthereumProviderIdentity;
//# sourceMappingURL=EthereumProviderIdentity.js.map