<|start_filename|>public/preload.js<|end_filename|>
const { ipcRenderer, contextBridge } = require("electron");

const allowedInvokeChannels = [
  "ledger-get-name-version",
  "ledger-get-address",
  "ledger-sign-transaction",
];

const allowedSendChannels = [
  "CHECK_FOR_UPDATE_PENDING",
  "UPDATE_ERROR",
  "CHECK_FOR_UPDATE_SUCCESS",
  "DOWNLOAD_UPDATE_SUCCESS",
];

const allowedOnChannels = [
  "CHECK_FOR_UPDATE_SUCCESS",
  "UPDATE_ERROR",
  "DOWNLOAD_UPDATE_SUCCESS",
  "DOWNLOAD_UPDATE_FAILURE",
];

function init() {
  window.isElectron = true;
  contextBridge.exposeInMainWorld("ipcBridge", {
    invoke: (text, data) => {
      if (allowedInvokeChannels.includes(text)) {
        return ipcRenderer.invoke(text, data);
      }
    },
    send: (text, data) => {
      if (allowedSendChannels.includes(text)) {
        return ipcRenderer.send(text, data);
      }
    },
    on: (text, callback) => {
      if (allowedOnChannels.includes(text)) {
        return ipcRenderer.on(text, callback);
      }
    },
  });
}

init();


<|start_filename|>public/electron.js<|end_filename|>
const { app, BrowserWindow, ipcMain } = require("electron");
const { MinaLedgerJS } = require("mina-ledger-js");
const TransportNodeHid = require("@ledgerhq/hw-transport-node-hid-singleton");
const { autoUpdater } = require("electron-updater");
const path = require("path");
const url = require("url");

let mainWindow;

function createWindow() {
  mainWindow = new BrowserWindow({
    width: 1200,
    height: 800,
    titleBarStyle: "hidden",
    backgroundColor: "#ffffff",
    icon: path.join(__dirname, "icon.png"),
    title: "Clorio Wallet",
    webPreferences: {
      preload: path.join(__dirname, "preload.js"),
      nodeIntegration: false,
      enableRemoteModule: false,
      devTools: false,
      sandbox: true,
      contextIsolation: true,
      disableBlinkFeatures: "Auxclick",
    },
    minWidth: 800,
    minHeight: 800,
  });
  mainWindow.loadURL(
    process.env.ELECTRON_START_URL ||
      url.format({
        pathname: path.join(__dirname, "index.html"),
        protocol: "file:",
        slashes: true,
      })
  );

  const ses = mainWindow.webContents.session;
  ses.setPermissionRequestHandler((webContents, permission, callback) => {
    return callback(false);
  });

  mainWindow.on("closed", () => {
    mainWindow = null;
  });

  ipcMain.on("CHECK_FOR_UPDATE_PENDING", () => {
    autoUpdater.checkForUpdates();
  });

  autoUpdater.on("error", (error) => {
    mainWindow.webContents.send("UPDATE_ERROR");
  });

  autoUpdater.on("update-available", (info) => {
    mainWindow.webContents.send("CHECK_FOR_UPDATE_SUCCESS", info.version);
    autoUpdater.downloadUpdate();
  });

  autoUpdater.on("update-downloaded", () => {
    mainWindow.webContents.send("DOWNLOAD_UPDATE_SUCCESS");
    autoUpdater.quitAndInstall();
  });
  autoUpdater.checkForUpdatesAndNotify();
}

app.on("ready", createWindow);

app.on("window-all-closed", () => {
  if (process.platform !== "darwin") {
    app.quit();
  }
});

app.on("activate", () => {
  if (mainWindow === null) {
    createWindow();
  }
});

app.on("web-contents-created", (e, contents) => {
  contents.on("new-window", (e, url) => {
    e.preventDefault();
    require("open")(url);
  });
  contents.on("will-navigate", (e, url) => {
    e.preventDefault();
    return {
      cancel: true,
    };
  });
});

ipcMain.handle("ledger-get-name-version", async () => {
  const transport = await TransportNodeHid.default.open();
  const instance = new MinaLedgerJS(transport);
  return await instance.getAppName();
});
ipcMain.handle("ledger-get-address", async (event, accountNumber) => {
  const transport = await TransportNodeHid.default.open();
  const instance = new MinaLedgerJS(transport);
  return await instance.getAddress(accountNumber);
});
ipcMain.handle("ledger-sign-transaction", async (event, transaction) => {
  const transport = await TransportNodeHid.default.open();
  const instance = new MinaLedgerJS(transport);
  return await instance.signTransaction(transaction);
});


<|start_filename|>config-overrides.js<|end_filename|>
const { override } = require("customize-cra");
const cspHtmlWebpackPlugin = require("csp-html-webpack-plugin");

const cspConfigPolicy = {
  "default-src":
    "'self' https://*.clor.io https://fonts.googleapis.com https://api.mina.tools",
  "connect-src":
    "'self' https://*.clor.io/v1/graphql https://api.mina.tools/v1/epoch",
  "img-src": "https://*.staketab.com 'self'",
  "script-src": "'self'",
  "style-src": "'self' https://fonts.googleapis.com",
  "object-src": "'self'",
  "font-src": "https://fonts.googleapis.com https://fonts.gstatic.com",
};

function addCspHtmlWebpackPlugin(config) {
  if (process.env.NODE_ENV === "production") {
    config.plugins.push(new cspHtmlWebpackPlugin(cspConfigPolicy));
  }

  return config;
}

module.exports = {
  webpack: override(addCspHtmlWebpackPlugin),
};


<|start_filename|>public/index.css<|end_filename|>
body{
  background-color: #fff;
}

#full-page-container {
  display: table;
  display: table;
  width: 100vw;
  height: 100vh;
}

#full-page-content {
  display: table-cell;
  vertical-align: middle
}

#central-text {
  margin-left: auto;
  margin-right: auto
}

#initial-loader,
.loader {
  display: flex;
  justify-content: center;
  align-items: center;
  width: 100%;
  height: 100vh
}

.fade-in-out {
  -webkit-animation: flickerAnimation 2s infinite;
  -moz-animation: flickerAnimation 2s infinite;
  -o-animation: flickerAnimation 2s infinite;
  animation: flickerAnimation 2s infinite;
}

@keyframes flickerAnimation {
  0% {
    opacity: 1;
  }

  50% {
    opacity: 0;
  }

  100% {
    opacity: 1;
  }
}

@-o-keyframes flickerAnimation {
  0% {
    opacity: 1;
  }

  50% {
    opacity: 0;
  }

  100% {
    opacity: 1;
  }
}

@-moz-keyframes flickerAnimation {
  0% {
    opacity: 1;
  }

  50% {
    opacity: 0;
  }

  100% {
    opacity: 1;
  }
}

@-webkit-keyframes flickerAnimation {
  0% {
    opacity: 1;
  }

  50% {
    opacity: 0;
  }

  100% {
    opacity: 1;
  }
}
