Skip to content

Commit

Permalink
refactor: exit early for errors, rename addKeypairToEnvironment -> ad…
Browse files Browse the repository at this point in the history
…dKeypairToEnvFile

Also use assert.throws() for sync functions that throw errors
  • Loading branch information
mikemaccana committed Nov 16, 2023
1 parent f2cb1dd commit 026252d
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 32 deletions.
41 changes: 22 additions & 19 deletions src/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,18 @@ import { before, describe, test } from "node:test";
import {
getKeypairFromEnvironment,
getKeypairFromFile,
addKeypairToEnvironment,
addKeypairToEnvFile,
} from "./index";

import { Keypair } from "@solana/web3.js";
import assert from "node:assert/strict";
import base58 from "bs58";
import { exec as execForOldPeople } from "child_process";
// See https://m.media-amazon.com/images/I/51TJeGHxyTL._SY445_SX342_.jpg
import { exec as execNoPromises } from "child_process";
import { promisify } from "util";
import { writeFile, unlink } from "node:fs/promises";
import { writeFile, unlink as deleteFile } from "node:fs/promises";
import dotenv from "dotenv";

const exec = promisify(execForOldPeople);
const exec = promisify(execNoPromises);

const log = console.log;

Expand Down Expand Up @@ -75,38 +75,40 @@ describe("getKeypairFromEnvironment", () => {
await getKeypairFromEnvironment(TEST_ENV_VAR_BASE58);
});

test("throws a nice error if the env var doesn't exist", async () => {
assert.rejects(async () => getKeypairFromEnvironment("MISSING_ENV_VAR"), {
test("throws a nice error if the env var doesn't exist", () => {
assert.throws(() => getKeypairFromEnvironment("MISSING_ENV_VAR"), {
message: `Please set 'MISSING_ENV_VAR' in environment.`,
});
});

test("throws a nice error if the value of the env var isn't valid", async () => {
assert.rejects(
async () => getKeypairFromEnvironment("TEST_ENV_VAR_WITH_BAD_VALUE"),
test("throws a nice error if the value of the env var isn't valid", () => {
assert.throws(
() => getKeypairFromEnvironment("TEST_ENV_VAR_WITH_BAD_VALUE"),
{
message: `Invalid secret key in environment variable 'TEST_ENV_VAR_WITH_BAD_VALUE'!`,
},
);
});
});

describe("addKeypairToEnvironment", () => {
describe("addKeypairToEnvFile", () => {
let TEST_ENV_VAR_ARRAY_OF_NUMBERS = "TEST_ENV_VAR_ARRAY_OF_NUMBERS";
let testKeypair: Keypair;

before(async () => {
const randomKeypair = Keypair.generate();
testKeypair = Keypair.generate();

process.env[TEST_ENV_VAR_ARRAY_OF_NUMBERS] = JSON.stringify(
Object.values(randomKeypair.secretKey),
Object.values(testKeypair.secretKey),
);
});

test("generates new keypair and writes to env if variable doesn't exist", async () => {
// Generates new keypair and writes it to the .env file
addKeypairToEnvironment("TEMP_KEYPAIR");
// Load the .env file
addKeypairToEnvFile(testKeypair, "TEMP_KEYPAIR");

// Now reload the environemnt and check it matches our test keypair
dotenv.config();

// Get the secret from the .env file
const secretKeyString = process.env["TEMP_KEYPAIR"];

Expand All @@ -118,14 +120,15 @@ describe("addKeypairToEnvironment", () => {

assert.ok(envKeypair.secretKey);

unlink(".env");
deleteFile(".env");
});

test("throws a nice error if the env var already exists", async () => {
assert.rejects(
async () => addKeypairToEnvironment(TEST_ENV_VAR_ARRAY_OF_NUMBERS),
async () =>
addKeypairToEnvFile(testKeypair, TEST_ENV_VAR_ARRAY_OF_NUMBERS),
{
message: `'TEST_ENV_VAR_ARRAY_OF_NUMBERS' already exists in environment.`,
message: `'TEST_ENV_VAR_ARRAY_OF_NUMBERS' already exists in env file.`,
},
);
});
Expand Down
31 changes: 18 additions & 13 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
import { Keypair } from "@solana/web3.js";
import base58 from "bs58";
import path from "path";
import { readFile } from "fs/promises";
import { appendFileSync } from "node:fs";
import { readFile, appendFile } from "fs/promises";
const log = console.log;

// Default value from Solana CLI
const DEFAULT_FILEPATH = "~/.config/solana/id.json";

export const keypairToSecretKeyJSON = (keypair: Keypair): string => {
return JSON.stringify(Array.from(keypair.secretKey));
};

export const getKeypairFromFile = async (filepath?: string) => {
// Work out correct file name
if (!filepath) {
Expand Down Expand Up @@ -74,16 +77,18 @@ export const getKeypairFromEnvironment = (variableName: string) => {
return Keypair.fromSecretKey(decodedSecretKey);
};

export const addKeypairToEnvironment = (variableName: string) => {
const secretKeyString = process.env[variableName];
if (!secretKeyString) {
// Generate a new keypair if one doesn't exist and add it to a `.env` file
const keypair = Keypair.generate();
appendFileSync(
".env",
`\n${variableName}=${JSON.stringify(Array.from(keypair.secretKey))}`,
);
} else {
throw new Error(`'${variableName}' already exists in environment.`);
export const addKeypairToEnvFile = async (
keypair: Keypair,
variableName: string,
fileName?: string,
) => {
if (!fileName) {
fileName = ".env";
}
const existingSecretKey = process.env[variableName];
if (existingSecretKey) {
throw new Error(`'${variableName}' already exists in env file.`);
}
const secretKeyString = keypairToSecretKeyJSON(keypair);
await appendFile(fileName, `\n${variableName}=${secretKeyString}`);
};

0 comments on commit 026252d

Please sign in to comment.