"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const satstack_1 = require("./satstack");
const bitcoin_1 = __importDefault(require("@ledgerhq/coin-bitcoin/datasets/bitcoin"));
const descriptor_1 = require("@ledgerhq/coin-bitcoin/descriptor");
const live_env_1 = require("@ledgerhq/live-env");
const account_1 = require("../../account");
const currencies_1 = require("../../currencies");
(0, currencies_1.setSupportedCurrencies)(["bitcoin"]);
jest.setTimeout(10000);
describe("validateRPCNodeConfig", () => {
    test("valid cases", () => {
        expect((0, satstack_1.validateRPCNodeConfig)({
            host: "192.168.0.1:9999",
            username: "user",
            password: "pass",
        })).toEqual([]);
        expect((0, satstack_1.validateRPCNodeConfig)({
            host: "192.168.0.1:9999",
            username: "user",
            password: "pass",
            tls: false,
        })).toEqual([]);
        expect((0, satstack_1.validateRPCNodeConfig)({
            host: "192.168.0.1:9999",
            username: "user",
            password: "pass",
            tls: true,
        })).toEqual([]);
        expect((0, satstack_1.validateRPCNodeConfig)({
            host: "ledger.com",
            username: "user",
            password: "pass",
        })).toEqual([]);
    });
    test("invalid cases", () => {
        const errors = (0, satstack_1.validateRPCNodeConfig)({
            host: "",
            username: "",
            password: "",
        });
        expect(errors.length).toEqual(3);
        expect(errors.map(e => e.field).sort()).toEqual(["host", "password", "username"]);
        expect(errors.every(e => e.error instanceof Error)).toBe(true);
    });
});
describe("isValidHost", () => {
    test("invalid", () => {
        expect((0, satstack_1.isValidHost)("")).toBe(false);
        expect((0, satstack_1.isValidHost)("a b")).toBe(false);
        expect((0, satstack_1.isValidHost)("ledger .com")).toBe(false);
    });
    test("valid", () => {
        expect((0, satstack_1.isValidHost)("52.207.220.222/node/btc/")).toBe(true);
        expect((0, satstack_1.isValidHost)("ledger.com/foo")).toBe(true);
        expect((0, satstack_1.isValidHost)("ledger.com")).toBe(true);
        expect((0, satstack_1.isValidHost)("localhost")).toBe(true);
        expect((0, satstack_1.isValidHost)("0.0.0.0")).toBe(true);
        expect((0, satstack_1.isValidHost)("127.0.0.1")).toBe(true);
        expect((0, satstack_1.isValidHost)("192.168.0.1")).toBe(true);
        expect((0, satstack_1.isValidHost)("192.168.0.1:8888")).toBe(true);
        expect((0, satstack_1.isValidHost)("locahost:8888")).toBe(true);
        expect((0, satstack_1.isValidHost)("ledger:8888")).toBe(true);
        expect((0, satstack_1.isValidHost)("ledger1:8888")).toBe(true);
        expect((0, satstack_1.isValidHost)("ledger-1:8888")).toBe(true);
    });
});
const mockConfig = {
    host: "localhost",
    username: "user",
    password: "pass",
};
describe("checkRPCNodeConfig", () => {
    beforeAll(() => {
        (0, live_env_1.setEnv)("MOCK", "1");
    });
    afterAll(() => {
        (0, live_env_1.setEnv)("MOCK", "");
    });
    test("default is good", async () => {
        await (0, satstack_1.checkRPCNodeConfig)(mockConfig);
    });
    test("disconnected case", async () => {
        (0, satstack_1.setMockStatus)({
            type: "node-disconnected",
        });
        try {
            await expect(async () => {
                await (0, satstack_1.checkRPCNodeConfig)(mockConfig);
            }).rejects.toThrow();
        }
        finally {
            (0, satstack_1.setMockStatus)({
                type: "ready",
            });
        }
    });
});
describe("parseSatStackConfig", () => {
    test("parse a config with descriptors", () => {
        expect((0, satstack_1.parseSatStackConfig)(`{
        "accounts": [
          {
            "external": "pkh([224b6226/44'/0'/0']xpub6BuPWhjLqutPV8SF4RMrrn8c3t7uBZbz4CBbThpbg9GYjqRMncra9mjgSfWSK7uMDz37hhzJ8wvkbDDQQJt6VgwLoszvmPiSBtLA1bPLLSn/0/*)",
            "internal": "pkh([224b6226/44'/0'/0']xpub6BuPWhjLqutPV8SF4RMrrn8c3t7uBZbz4CBbThpbg9GYjqRMncra9mjgSfWSK7uMDz37hhzJ8wvkbDDQQJt6VgwLoszvmPiSBtLA1bPLLSn/1/*)"
          },
          {
            "external": "wpkh([d6a9e45e/84'/0'/1']xpub6DEHKg8fgKcb9at2u9Xhjtx4tXGyWqUPQAx2zNCzr41gQRyCqpCn7onSoJU4VS96GXyCtAhhFxErnG2pGVvVexaqF7DEfqGGnGk7Havn7C2/0/*)",
            "internal": "wpkh([d6a9e45e/84'/0'/1']xpub6DEHKg8fgKcb9at2u9Xhjtx4tXGyWqUPQAx2zNCzr41gQRyCqpCn7onSoJU4VS96GXyCtAhhFxErnG2pGVvVexaqF7DEfqGGnGk7Havn7C2/1/*)",
            "_whatever": 42
          }
        ],
        "rpcurl": "localhost",
        "rpcuser": "user",
        "rpcpass": "pass",
        "notls": true,
        "_whatever": {"a":"b"}
      }`)).toEqual({
            accounts: [
                {
                    descriptor: {
                        external: "pkh([224b6226/44'/0'/0']xpub6BuPWhjLqutPV8SF4RMrrn8c3t7uBZbz4CBbThpbg9GYjqRMncra9mjgSfWSK7uMDz37hhzJ8wvkbDDQQJt6VgwLoszvmPiSBtLA1bPLLSn/0/*)",
                        internal: "pkh([224b6226/44'/0'/0']xpub6BuPWhjLqutPV8SF4RMrrn8c3t7uBZbz4CBbThpbg9GYjqRMncra9mjgSfWSK7uMDz37hhzJ8wvkbDDQQJt6VgwLoszvmPiSBtLA1bPLLSn/1/*)",
                    },
                    extra: {},
                },
                {
                    descriptor: {
                        external: "wpkh([d6a9e45e/84'/0'/1']xpub6DEHKg8fgKcb9at2u9Xhjtx4tXGyWqUPQAx2zNCzr41gQRyCqpCn7onSoJU4VS96GXyCtAhhFxErnG2pGVvVexaqF7DEfqGGnGk7Havn7C2/0/*)",
                        internal: "wpkh([d6a9e45e/84'/0'/1']xpub6DEHKg8fgKcb9at2u9Xhjtx4tXGyWqUPQAx2zNCzr41gQRyCqpCn7onSoJU4VS96GXyCtAhhFxErnG2pGVvVexaqF7DEfqGGnGk7Havn7C2/1/*)",
                    },
                    extra: {
                        _whatever: 42,
                    },
                },
            ],
            extra: {
                _whatever: {
                    a: "b",
                },
            },
            node: {
                host: "localhost",
                password: "pass",
                tls: false,
                username: "user",
            },
        });
    });
    test("invalid values", () => {
        expect(() => (0, satstack_1.parseSatStackConfig)("")).toThrow();
        expect((0, satstack_1.parseSatStackConfig)("{}")).toBeUndefined();
        expect((0, satstack_1.parseSatStackConfig)('{"accounts":[]}')).toBeUndefined();
        expect((0, satstack_1.parseSatStackConfig)('{"accounts":[],"rpcurl":"localhost","rpcuser":"user"}')).toBeUndefined();
        expect((0, satstack_1.parseSatStackConfig)('{"accounts":[],"rpcurl":"localhost","rpcpass":"pass"}')).toBeUndefined();
        expect((0, satstack_1.parseSatStackConfig)('{"accounts":[],"rpcuser":"user","rpcpass": "pass"}')).toBeUndefined();
    });
});
describe("stringifySatStackConfig", () => {
    test("stringify config with accounts", () => {
        expect((0, satstack_1.stringifySatStackConfig)({
            node: mockConfig,
            extra: {
                foo: "bar",
            },
            accounts: (bitcoin_1.default.accounts || [])
                .map(a => (0, descriptor_1.inferDescriptorFromAccount)((0, account_1.fromAccountRaw)(a.raw)))
                .filter(Boolean).map((descriptor, i) => ({
                descriptor,
                extra: {
                    i,
                },
            })),
        })).toEqual(`{
  "accounts": [
    {
      "external": "pkh([224b6226/44'/0'/0']xpub6BuPWhjLqutPV8SF4RMrrn8c3t7uBZbz4CBbThpbg9GYjqRMncra9mjgSfWSK7uMDz37hhzJ8wvkbDDQQJt6VgwLoszvmPiSBtLA1bPLLSn/0/*)",
      "internal": "pkh([224b6226/44'/0'/0']xpub6BuPWhjLqutPV8SF4RMrrn8c3t7uBZbz4CBbThpbg9GYjqRMncra9mjgSfWSK7uMDz37hhzJ8wvkbDDQQJt6VgwLoszvmPiSBtLA1bPLLSn/1/*)",
      "i": 0
    },
    {
      "external": "wpkh([d6a9e45e/84'/0'/1']xpub6DEHKg8fgKcb9at2u9Xhjtx4tXGyWqUPQAx2zNCzr41gQRyCqpCn7onSoJU4VS96GXyCtAhhFxErnG2pGVvVexaqF7DEfqGGnGk7Havn7C2/0/*)",
      "internal": "wpkh([d6a9e45e/84'/0'/1']xpub6DEHKg8fgKcb9at2u9Xhjtx4tXGyWqUPQAx2zNCzr41gQRyCqpCn7onSoJU4VS96GXyCtAhhFxErnG2pGVvVexaqF7DEfqGGnGk7Havn7C2/1/*)",
      "i": 1
    }
  ],
  "rpcurl": "localhost",
  "rpcuser": "user",
  "rpcpass": "pass",
  "notls": true,
  "foo": "bar"
}`);
    });
});
describe("editSatStackConfig", () => {
    const config = {
        node: { ...mockConfig, tls: false },
        extra: {
            foo: "bar",
        },
        accounts: (bitcoin_1.default.accounts || [])
            .map(a => (0, descriptor_1.inferDescriptorFromAccount)((0, account_1.fromAccountRaw)(a.raw)))
            .filter(Boolean)
            .map((descriptor, i) => ({
            descriptor,
            extra: {
                i,
            },
        })),
    };
    test("restore identity", () => {
        expect((0, satstack_1.parseSatStackConfig)((0, satstack_1.stringifySatStackConfig)(config))).toEqual(config);
    });
    test("update node config", () => {
        expect((0, satstack_1.editSatStackConfig)({
            ...config,
            node: {
                ...config.node,
                host: "ledger.com",
                password: "update",
            },
        }, {
            node: config.node,
        })).toEqual(config);
    });
    test("append accounts", () => {
        expect((0, satstack_1.editSatStackConfig)({ ...config, accounts: config.accounts.slice(0, 1) }, {
            accounts: config.accounts.slice(1),
        })).toEqual(config);
    });
    test("dedup accounts", () => {
        expect((0, satstack_1.editSatStackConfig)({ ...config, accounts: config.accounts.slice(0, 1) }, {
            accounts: config.accounts,
        })).toEqual(config);
    });
});
describe("isSatStackEnabled", () => {
    afterEach(() => {
        (0, live_env_1.setEnv)("SATSTACK", false);
    });
    test("enabled", () => {
        (0, live_env_1.setEnv)("SATSTACK", true);
        expect((0, satstack_1.isSatStackEnabled)()).toBe(true);
    });
    test("disabled", () => {
        expect((0, satstack_1.isSatStackEnabled)()).toBe(false);
    });
});
describe("fetchSatStackStatus", () => {
    beforeEach(() => {
        (0, live_env_1.setEnv)("MOCK", "1");
        (0, satstack_1.setMockStatus)({
            type: "ready",
        });
    });
    afterEach(() => {
        (0, live_env_1.setEnv)("SATSTACK", false);
        (0, live_env_1.setEnv)("MOCK", "");
        (0, satstack_1.setMockStatus)({
            type: "ready",
        });
    });
    test("disconnected", async () => {
        await expect((0, satstack_1.fetchSatStackStatus)()).resolves.toEqual({
            type: "satstack-disconnected",
        });
    });
    test("scanning", async () => {
        (0, live_env_1.setEnv)("SATSTACK", true);
        (0, satstack_1.setMockStatus)({
            type: "scanning",
            progress: 0.42,
        });
        await expect((0, satstack_1.fetchSatStackStatus)()).resolves.toEqual({
            type: "scanning",
            progress: 0.42,
        });
    });
    test("ready", async () => {
        (0, live_env_1.setEnv)("SATSTACK", true);
        await expect((0, satstack_1.fetchSatStackStatus)()).resolves.toEqual({
            type: "ready",
        });
    });
});
describe("statusObservable", () => {
    beforeEach(() => {
        (0, live_env_1.setEnv)("MOCK", "1");
        (0, satstack_1.setMockStatus)({
            type: "ready",
        });
    });
    afterEach(() => {
        (0, live_env_1.setEnv)("SATSTACK", false);
        (0, live_env_1.setEnv)("MOCK", "");
        (0, satstack_1.setMockStatus)({
            type: "ready",
        });
    });
    test("events", async () => {
        (0, live_env_1.setEnv)("SATSTACK", true);
        const stack = [
            {
                type: "ready",
            },
            {
                type: "node-disconnected",
            },
            {
                type: "node-disconnected",
            },
            {
                type: "satstack-disconnected",
            },
            {
                type: "ready",
            },
        ];
        let success;
        const p = new Promise(s => {
            success = s;
        });
        let last = {
            type: "ready",
        };
        const u = satstack_1.statusObservable.subscribe(e => {
            if (stack.length === 0) {
                u.unsubscribe();
                success();
            }
            else {
                expect(e).toEqual(last);
                (0, satstack_1.setMockStatus)((last = stack.splice(0, 1)[0]));
            }
        });
        await p;
    });
});
describe("requiresSatStackReady", () => {
    beforeEach(() => {
        (0, live_env_1.setEnv)("MOCK", "1");
    });
    afterEach(() => {
        (0, satstack_1.setMockStatus)({
            type: "ready",
        });
        (0, live_env_1.setEnv)("SATSTACK", false);
        (0, live_env_1.setEnv)("MOCK", "");
    });
    test("without satstack", async () => {
        await expect((0, satstack_1.requiresSatStackReady)()).resolves.toBe(undefined);
    });
    test("with satstack", async () => {
        (0, live_env_1.setEnv)("SATSTACK", true);
        await expect((0, satstack_1.requiresSatStackReady)()).resolves.toBe(undefined);
    });
    test("with satstack not ready", async () => {
        (0, live_env_1.setEnv)("SATSTACK", true);
        (0, satstack_1.setMockStatus)({
            type: "node-disconnected",
        });
        await expect((0, satstack_1.requiresSatStackReady)()).rejects.toThrow();
    });
});
//# sourceMappingURL=satstack.test.js.map