"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.ArweaveClient = void 0;
var tslib_1 = require("tslib");
var arweave_1 = tslib_1.__importDefault(require("arweave"));
var axios_1 = tslib_1.__importDefault(require("axios"));
var superstruct_1 = require("superstruct");
var constants_1 = require("../../constants");
var utils_1 = require("../../utils");
var ArweaveClient = (function () {
    function ArweaveClient(arweaveJWT, logger, gatewayURL, protocol, port) {
        if (gatewayURL === void 0) { gatewayURL = "arweave.net"; }
        if (protocol === void 0) { protocol = "https"; }
        if (port === void 0) { port = 443; }
        this.arweaveJWT = arweaveJWT;
        this.logger = logger;
        this.gatewayUrl = "".concat(protocol, "://").concat(gatewayURL, ":").concat(port);
        this.client = new arweave_1.default({
            host: gatewayURL,
            port: port,
            protocol: protocol,
            timeout: 20000,
            logging: false,
        });
        this.logger.debug({
            at: "ArweaveClient:constructor",
            message: "Arweave client initialized",
            gateway: this.gatewayUrl,
        });
    }
    ArweaveClient.prototype.set = function (value, topicTag) {
        var _a, _b, _c;
        return tslib_1.__awaiter(this, void 0, void 0, function () {
            var transaction, result, message, _d, _e;
            var _f;
            return tslib_1.__generator(this, function (_g) {
                switch (_g.label) {
                    case 0: return [4, this.client.createTransaction({ data: JSON.stringify(value, utils_1.jsonReplacerWithBigNumbers) }, this.arweaveJWT)];
                    case 1:
                        transaction = _g.sent();
                        transaction.addTag("Content-Type", "application/json");
                        transaction.addTag("App-Name", constants_1.ARWEAVE_TAG_APP_NAME);
                        transaction.addTag("App-Version", constants_1.ARWEAVE_TAG_APP_VERSION.toString());
                        if ((0, utils_1.isDefined)(topicTag)) {
                            transaction.addTag("Topic", topicTag);
                        }
                        return [4, this.client.transactions.sign(transaction, this.arweaveJWT)];
                    case 2:
                        _g.sent();
                        return [4, this.client.transactions.post(transaction)];
                    case 3:
                        result = _g.sent();
                        if (!(result.status !== 200)) return [3, 6];
                        message = (_c = (_b = (_a = result === null || result === void 0 ? void 0 : result.data) === null || _a === void 0 ? void 0 : _a.error) === null || _b === void 0 ? void 0 : _b.msg) !== null && _c !== void 0 ? _c : "Unknown error";
                        _e = (_d = this.logger).error;
                        _f = {
                            at: "ArweaveClient:set",
                            message: message,
                            result: result,
                            txn: transaction.id
                        };
                        return [4, this.getAddress()];
                    case 4:
                        _f.address = _g.sent();
                        return [4, this.getBalance()];
                    case 5:
                        _e.apply(_d, [(_f.balance = (_g.sent()).toString(),
                                _f)]);
                        throw new Error(message);
                    case 6:
                        this.logger.debug({
                            at: "ArweaveClient:set",
                            message: "Arweave transaction posted with ".concat(transaction.id),
                        });
                        _g.label = 7;
                    case 7: return [2, transaction.id];
                }
            });
        });
    };
    ArweaveClient.prototype.get = function (transactionID, validator) {
        return tslib_1.__awaiter(this, void 0, void 0, function () {
            var transactionUrl, _a, data, responseStatus;
            return tslib_1.__generator(this, function (_b) {
                switch (_b.label) {
                    case 0:
                        transactionUrl = "".concat(this.gatewayUrl, "/").concat(transactionID);
                        return [4, axios_1.default.get(transactionUrl)];
                    case 1:
                        _a = _b.sent(), data = _a.data, responseStatus = _a.status;
                        if (responseStatus !== 200 || ("status" in data && data["status"] !== 200)) {
                            this.logger.debug({
                                at: "ArweaveClient:get",
                                message: "Failed to retrieve value from Arweave - network error or invalid response status",
                                transactionID: transactionID,
                                responseStatus: responseStatus,
                                data: data,
                            });
                            return [2, null];
                        }
                        try {
                            return [2, (0, superstruct_1.create)(data, validator)];
                        }
                        catch (e) {
                            this.logger.warn({
                                at: "ArweaveClient:get",
                                message: "Retrieved value from Arweave does not match the expected type: ".concat(e),
                            });
                            return [2, null];
                        }
                        return [2];
                }
            });
        });
    };
    ArweaveClient.prototype.getByTopic = function (tag, validator, originQueryAddress) {
        var _a, _b, _c, _d;
        if (originQueryAddress === void 0) { originQueryAddress = constants_1.DEFAULT_ARWEAVE_STORAGE_ADDRESS; }
        return tslib_1.__awaiter(this, void 0, void 0, function () {
            var transactions, entries, results;
            var _this = this;
            return tslib_1.__generator(this, function (_e) {
                switch (_e.label) {
                    case 0: return [4, this.client.api.post("/graphql", {
                            query: "\n        { \n          transactions (\n            owners: [\"".concat(originQueryAddress, "\"]\n            tags: [\n              { name: \"App-Name\", values: [\"").concat(constants_1.ARWEAVE_TAG_APP_NAME, "\"] },\n              { name: \"Content-Type\", values: [\"application/json\"] },\n              { name: \"App-Version\", values: [\"").concat(constants_1.ARWEAVE_TAG_APP_VERSION, "\"] },\n              ").concat(tag ? "{ name: \"Topic\", values: [\"".concat(tag, "\"] } ") : "", "\n            ]\n          ) { edges { node { id } } } \n        }"),
                        })];
                    case 1:
                        transactions = _e.sent();
                        entries = (_d = (_c = (_b = (_a = transactions === null || transactions === void 0 ? void 0 : transactions.data) === null || _a === void 0 ? void 0 : _a.data) === null || _b === void 0 ? void 0 : _b.transactions) === null || _c === void 0 ? void 0 : _c.edges) !== null && _d !== void 0 ? _d : [];
                        this.logger.debug({
                            at: "ArweaveClient:getByTopic",
                            message: "Retrieved ".concat(entries.length, " matching transactions from Arweave"),
                            transactions: entries.map(function (edge) { return edge.node.id; }),
                            metaInformation: {
                                tag: tag,
                                originQueryAddress: originQueryAddress,
                                appVersion: constants_1.ARWEAVE_TAG_APP_VERSION,
                            },
                        });
                        return [4, Promise.all(entries.map(function (edge) { return tslib_1.__awaiter(_this, void 0, void 0, function () {
                                var data, e_1;
                                return tslib_1.__generator(this, function (_a) {
                                    switch (_a.label) {
                                        case 0:
                                            _a.trys.push([0, 2, , 3]);
                                            return [4, this.get(edge.node.id, validator)];
                                        case 1:
                                            data = _a.sent();
                                            return [2, (0, utils_1.isDefined)(data)
                                                    ? {
                                                        data: data,
                                                        hash: edge.node.id,
                                                    }
                                                    : null];
                                        case 2:
                                            e_1 = _a.sent();
                                            this.logger.warn({
                                                at: "ArweaveClient:getByTopic",
                                                message: "Bad request for Arweave topic ".concat(edge.node.id, ": ").concat(e_1),
                                            });
                                            return [2, null];
                                        case 3: return [2];
                                    }
                                });
                            }); }))];
                    case 2:
                        results = _e.sent();
                        return [2, results.filter(utils_1.isDefined)];
                }
            });
        });
    };
    ArweaveClient.prototype.getMetadata = function (transactionID) {
        return tslib_1.__awaiter(this, void 0, void 0, function () {
            var transaction, tags;
            return tslib_1.__generator(this, function (_a) {
                switch (_a.label) {
                    case 0: return [4, this.client.transactions.get(transactionID)];
                    case 1:
                        transaction = _a.sent();
                        if (!(0, utils_1.isDefined)(transaction)) {
                            return [2, null];
                        }
                        tags = Object.fromEntries(transaction.tags.map(function (tag) { return [
                            tag.get("name", { decode: true, string: true }),
                            tag.get("value", { decode: true, string: true }),
                        ]; }));
                        return [2, {
                                contentType: tags["Content-Type"],
                                appName: tags["App-Name"],
                                topic: tags.Topic,
                            }];
                }
            });
        });
    };
    ArweaveClient.prototype.getAddress = function () {
        return this.client.wallets.jwkToAddress(this.arweaveJWT);
    };
    ArweaveClient.prototype.getBalance = function () {
        return tslib_1.__awaiter(this, void 0, void 0, function () {
            var address, balanceInFloat, _a, balance, exponent, resultingBN;
            return tslib_1.__generator(this, function (_b) {
                switch (_b.label) {
                    case 0: return [4, this.getAddress()];
                    case 1:
                        address = _b.sent();
                        return [4, this.client.wallets.getBalance(address)];
                    case 2:
                        balanceInFloat = _b.sent();
                        if (balanceInFloat.includes("e")) {
                            _a = balanceInFloat.split("e"), balance = _a[0], exponent = _a[1];
                            resultingBN = utils_1.BigNumber.from(balance).mul((0, utils_1.toBN)(10).pow(exponent.replace("+", "")));
                            return [2, utils_1.BigNumber.from(resultingBN.toString())];
                        }
                        else {
                            return [2, utils_1.BigNumber.from(balanceInFloat)];
                        }
                        return [2];
                }
            });
        });
    };
    return ArweaveClient;
}());
exports.ArweaveClient = ArweaveClient;
//# sourceMappingURL=ArweaveClient.js.map