UNPKG

@ledgerhq/live-common

Version:
374 lines • 14 kB
"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"); const index_1 = require("@ledgerhq/coin-framework/crypto-assets/index"); (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", () => { // eslint-disable-next-line @typescript-eslint/consistent-type-assertions (0, index_1.setCryptoAssetsStore)({ findTokenById: (_) => undefined, findTokenByAddressInCurrency: (_, __) => undefined, }); 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