@ledgerhq/live-common
Version:
Common ground for the Ledger Live apps
136 lines • 5.46 kB
JavaScript
/* eslint-disable @typescript-eslint/consistent-type-assertions */
import { getChainAPI, logged } from "@ledgerhq/coin-solana/network/index";
import { getEnv } from "@ledgerhq/live-env";
import { makeBridges } from "@ledgerhq/coin-solana/bridge/bridge";
import { PubKeyDisplayMode } from "@ledgerhq/coin-solana/signer";
import { Message, MessageV0 } from "@solana/web3.js";
import { flow, isArray, isEqual, isObject, isUndefined, mapValues, omitBy } from "lodash/fp";
import { getMockedMethods } from "./mock-data";
import { scanAccounts, sync } from "../../../bridge/mockHelpers";
function mockChainAPI(config) {
const mockedMethods = getMockedMethods();
const api = new Proxy({ config }, {
get(_, propKey) {
if (propKey in api) {
return api[propKey];
}
if (propKey === "then") {
return undefined;
}
const method = propKey.toString();
const mocks = mockedMethods.filter(mock => mock.method === method);
if (mocks.length === 0) {
throw new Error(`no mock found for api method: ${method}`);
}
return function (...rawArgs) {
const args = preprocessArgs(method, rawArgs);
const mock = mocks.find(({ params: mockArgs }) => isEqual(args)(mockArgs));
if (mock === undefined) {
const argsJson = JSON.stringify(args);
throw new Error(`no mock found for api method ${method} with args ${argsJson}`);
}
return Promise.resolve(mock.answer);
};
},
});
return api;
}
function removeUndefineds(input) {
return isObject(input)
? isArray(input)
? input.map(removeUndefineds)
: flow(omitBy(isUndefined), mapValues(removeUndefineds))(input)
: input;
}
function preprocessArgs(method, args) {
if (method === "getFeeForMessage") {
// getFeeForMessage needs some args preprocessing
if (args.length === 1 && (args[0] instanceof Message || args[0] instanceof MessageV0)) {
return [Buffer.from(args[0].serialize()).toString("base64")];
}
else {
throw new Error("unexpected getFeeForMessage function signature");
}
}
if (method === "getSimulationComputeUnits") {
// getSimulationComputeUnits needs args preprocessing
// args[0] is instructions array, args[1] is payer PublicKey
if (args.length === 2) {
const instructions = args[0];
const payer = args[1];
// Serialize the payer PublicKey to string
const serializedPayer = payer?.toString?.() ?? payer;
// Serialize PublicKey objects in instruction keys to strings
const serializedInstructions = instructions?.map?.(instruction => {
const inst = instruction;
return {
...inst,
keys: inst.keys?.map?.(key => {
const k = key;
return {
...k,
pubkey: k.pubkey?.toString?.() ?? k.pubkey,
};
}) || inst.keys,
programId: inst.programId?.toString?.() ?? inst.programId,
};
}) || instructions;
return [serializedInstructions, serializedPayer];
}
}
return removeUndefineds(args);
}
const APP_VERSION = "1.7.1";
const signature = "fakeSignatureTlaowosfpqwkpofqkpqwpoesHQv6xHyYwDsrPJvqcSKRJGBLrbE";
const signer = {
getAppConfiguration: () => Promise.resolve({
version: APP_VERSION,
blindSigningEnabled: false,
pubKeyDisplayMode: PubKeyDisplayMode.LONG,
}),
getAddress: (_path, _display) => Promise.resolve({ address: Buffer.from("fakeAddress") }),
signTransaction: (_path, _txBuffer) => Promise.resolve({ signature: Buffer.from(signature) }),
signMessage: (_path, _messageHex) => Promise.resolve({ signature: Buffer.from(signature) }),
};
const signerContext = (_deviceId, fn) => fn(signer);
// Bridge with this api will log all api calls to a file.
// The calls data can be copied to mock-data.ts from the file.
// Uncomment fs module in logged.ts
/* eslint-disable-next-line @typescript-eslint/no-unused-vars */
function createMockDataForAPI() {
const chainAPICache = new Map();
return {
getAPI: (config) => {
const endpoint = config.endpoint;
if (!chainAPICache.has(endpoint)) {
chainAPICache.set(endpoint, logged(getChainAPI(config), "/tmp/log"));
}
return chainAPICache.get(endpoint);
},
signerContext,
};
}
function getMockedAPIs() {
const mockedAPI = mockChainAPI({ cluster: "mock" });
return {
getAPI: (_) => mockedAPI,
signerContext,
};
}
// const bridges = makeBridges(createMockDataForAPI());
const bridges = makeBridges(getMockedAPIs());
export default getEnv("PLAYWRIGHT_RUN") || getEnv("DETOX")
? {
accountBridge: {
...bridges.accountBridge,
sync,
},
currencyBridge: {
...bridges.currencyBridge,
preload: () => Promise.resolve({}),
hydrate: () => { },
scanAccounts,
},
}
: bridges;
//# sourceMappingURL=mock.js.map