"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const WERR_REVIEW_ACTIONS_js_1 = require("../WERR_REVIEW_ACTIONS.js");
const WERR_INVALID_PARAMETER_js_1 = require("../WERR_INVALID_PARAMETER.js");
const toOriginHeader_js_1 = require("./utils/toOriginHeader.js");
const WERR_INSUFFICIENT_FUNDS_js_1 = __importDefault(require("../WERR_INSUFFICIENT_FUNDS.js"));
class HTTPWalletJSON {
    constructor(originator, baseUrl = 'http://localhost:3321', httpClient = fetch) {
        this.baseUrl = baseUrl;
        this.originator = originator;
        this.httpClient = httpClient;
        // Detect if we're in a browser environment
        const isBrowser = typeof globalThis.window !== 'undefined' && typeof document !== 'undefined' && globalThis.window?.origin !== 'file://';
        this.api = async (call, args) => {
            // In browser environments, let the browser handle Origin header automatically
            // In Node.js environments, we need to set it manually if originator is provided
            const origin = !isBrowser && this.originator
                ? (0, toOriginHeader_js_1.toOriginHeader)(this.originator, 'http')
                : undefined;
            if (!isBrowser && origin === undefined) {
                throw new Error('HTTPWalletJSON: originator is required when using the HTTP substrate in Node.js. ' +
                    'Pass an originator (e.g. "example.com") to the constructor.');
            }
            const res = await httpClient(`${this.baseUrl}/${call}`, {
                method: 'POST',
                headers: {
                    Accept: 'application/json',
                    'Content-Type': 'application/json',
                    ...(origin ? { Origin: origin } : {}),
                    ...(origin ? { Originator: origin } : {}),
                },
                body: JSON.stringify(args)
            });
            const data = await res.json();
            // Check the HTTP status on the original response
            if (!res.ok) {
                if (res.status === 400 && data.isError) {
                    let err;
                    switch (data.code) {
                        case 5:
                            err = new WERR_REVIEW_ACTIONS_js_1.WERR_REVIEW_ACTIONS(data.reviewActionResults, data.sendWithResults, data.txid, data.tx, data.noSendChange);
                            break;
                        case 6:
                            err = new WERR_INVALID_PARAMETER_js_1.WERR_INVALID_PARAMETER(data.parameter);
                            err.message = data.message;
                            break;
                        case 7:
                            err = new WERR_INSUFFICIENT_FUNDS_js_1.default(data.totalSatoshisNeeded, data.moreSatoshisNeeded);
                            break;
                        default: break;
                    }
                    if (err)
                        throw err;
                }
                const err = {
                    call,
                    args,
                    message: data.message ?? `HTTP Client error ${res.status}`
                };
                throw new Error(JSON.stringify(err));
            }
            return data;
        };
    }
    async createAction(args) {
        return await this.api('createAction', args);
    }
    async signAction(args) {
        return await this.api('signAction', args);
    }
    async abortAction(args) {
        return await this.api('abortAction', args);
    }
    async listActions(args) {
        return await this.api('listActions', args);
    }
    async internalizeAction(args) {
        return await this.api('internalizeAction', args);
    }
    async listOutputs(args) {
        return await this.api('listOutputs', args);
    }
    async relinquishOutput(args) {
        return await this.api('relinquishOutput', args);
    }
    async getPublicKey(args) {
        return await this.api('getPublicKey', args);
    }
    async revealCounterpartyKeyLinkage(args) {
        return await this.api('revealCounterpartyKeyLinkage', args);
    }
    async revealSpecificKeyLinkage(args) {
        return await this.api('revealSpecificKeyLinkage', args);
    }
    async encrypt(args) {
        return await this.api('encrypt', args);
    }
    async decrypt(args) {
        return await this.api('decrypt', args);
    }
    async createHmac(args) {
        return await this.api('createHmac', args);
    }
    async verifyHmac(args) {
        return await this.api('verifyHmac', args);
    }
    async createSignature(args) {
        return await this.api('createSignature', args);
    }
    async verifySignature(args) {
        return await this.api('verifySignature', args);
    }
    async acquireCertificate(args) {
        return await this.api('acquireCertificate', args);
    }
    async listCertificates(args) {
        return await this.api('listCertificates', args);
    }
    async proveCertificate(args) {
        return await this.api('proveCertificate', args);
    }
    async relinquishCertificate(args) {
        return await this.api('relinquishCertificate', args);
    }
    async discoverByIdentityKey(args) {
        return await this.api('discoverByIdentityKey', args);
    }
    async discoverByAttributes(args) {
        return await this.api('discoverByAttributes', args);
    }
    async isAuthenticated(args) {
        return await this.api('isAuthenticated', args);
    }
    async waitForAuthentication(args) {
        return await this.api('waitForAuthentication', args);
    }
    async getHeight(args) {
        return await this.api('getHeight', args);
    }
    async getHeaderForHeight(args) {
        return await this.api('getHeaderForHeight', args);
    }
    async getNetwork(args) {
        return await this.api('getNetwork', args);
    }
    async getVersion(args) {
        return await this.api('getVersion', args);
    }
}
exports.default = HTTPWalletJSON;
//# sourceMappingURL=HTTPWalletJSON.js.map