Skip to content

Commit 8a9b9d2

Browse files
committed
add readPassword, add password stdin input for golembase account CI actions
1 parent 2750651 commit 8a9b9d2

File tree

5 files changed

+59
-19
lines changed

5 files changed

+59
-19
lines changed

.github/workflows/ci.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,8 @@ jobs:
4545
4646
- name: Create and fund an account
4747
run: |
48-
go run ./cmd/golembase account create
49-
go run ./cmd/golembase account fund
48+
printf "password" | go run ./cmd/golembase account create
49+
printf "password" | go run ./cmd/golembase account fund
5050
working-directory: ./gb-op-geth
5151

5252
- name: Run tests

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ The repo also contains an example application to showcase how you can use this S
2020

2121
(Note: As an alternative to installing the demo CLI, you can build the [actual CLI](https://github.com/Golem-Base/golembase-op-geth/blob/main/cmd/golembase/README.md) as it's included in the golembase-op-geth repo.)
2222

23-
When you create a user, it will generate a private key file called `private.key` and store it in:
23+
When you create a user, it will generate an encrypted keystore file with a password you provide called `wallet.json` and store it in:
2424

2525
- `~/.config/golembase/` on **Linux**
2626
- `~/Library/Application Support/golembase/` on **macOS**
@@ -126,7 +126,7 @@ This is a basic TypeScript application that:
126126
* `type GolemBaseCreate`: A type representing a create transaction in GolemBase
127127
* `Annotation`: A type representing an annotation with a key and a value, used for efficient lookups
128128

129-
2. Reads the private key, which it locates through the `xdg-portable` module.
129+
2. Reads the private key from a wallet, which it locates through the `xdg-portable` module.
130130

131131
3. Create a logger using the `tslog` TypeScript Logger
132132

example/index.ts

Lines changed: 43 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,13 @@
1-
import * as fs from "fs"
1+
import { readFileSync } from "fs"
2+
import { join } from "path"
3+
import { stdin, stdout } from "process"
4+
import { createInterface } from "readline";
25
import {
36
type ILogObj,
47
Logger
58
} from "tslog"
69
import xdg from "xdg-portable"
10+
import { Wallet, getBytes } from "ethers"
711
import {
812
createClient,
913
formatEther,
@@ -13,7 +17,39 @@ import {
1317
type AccountData,
1418
} from "golem-base-sdk"
1519

16-
const keyBytes = fs.readFileSync(xdg.config() + '/golembase/private.key');
20+
// Path to a golembase wallet
21+
const walletPath = join(xdg.config(), 'golembase', 'wallet.json');
22+
const keystore = readFileSync(walletPath, 'utf8');
23+
24+
/**
25+
* Read password either from piped stdin or interactively from the terminal.
26+
*/
27+
async function readPassword(prompt: string = "Enter wallet password: "): Promise<string> {
28+
if (stdin.isTTY) {
29+
// Interactive prompt
30+
const rl = createInterface({
31+
input: stdin,
32+
output: stdout,
33+
terminal: true,
34+
});
35+
36+
return new Promise((resolve) => {
37+
rl.question(prompt, (password) => {
38+
rl.close();
39+
resolve(password.trim());
40+
});
41+
// Hide input for security
42+
(rl as any)._writeToOutput = () => {};
43+
});
44+
} else {
45+
// Input is piped
46+
const chunks: Buffer[] = [];
47+
for await (const chunk of stdin) {
48+
chunks.push(Buffer.from(chunk));
49+
}
50+
return Buffer.concat(chunks).toString().trim();
51+
}
52+
}
1753

1854
const encoder = new TextEncoder()
1955
const decoder = new TextDecoder()
@@ -35,7 +71,11 @@ async function asyncFilter<T>(arr: T[], callback: (item: T) => Promise<boolean>)
3571
};
3672

3773
async function main() {
38-
const key: AccountData = new Tagged("privatekey", keyBytes)
74+
log.info("Attempting to decrypt wallet", walletPath);
75+
const wallet = Wallet.fromEncryptedJsonSync(keystore, await readPassword());
76+
log.info("Successfully decrypted wallet for account", wallet.address);
77+
78+
const key: AccountData = new Tagged("privatekey", getBytes(wallet.privateKey))
3979
const client = {
4080
local: await createClient(
4181
1337,

test/client.spec.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
import * as fs from 'fs'
1+
import { readFileSync } from "fs"
2+
import { join } from "path"
23
import {
34
expect
45
} from "chai"
@@ -8,7 +9,7 @@ import {
89
Logger
910
} from "tslog"
1011
import xdg from "xdg-portable"
11-
import { Wallet, utils } from "ethers"
12+
import { Wallet, getBytes } from "ethers"
1213
import {
1314
createClient,
1415
type GolemBaseClient,
@@ -30,11 +31,10 @@ const log = new Logger<ILogObj>({
3031
})
3132

3233
// Path to a golembase wallet
33-
const walletPath = path.join(xdg.config(), 'golembase', 'wallet.json');
34+
const walletPath = join(xdg.config(), 'golembase', 'wallet.json');
3435
// The password that the test wallet was encrypted with
3536
const walletTestPassword = "password";
36-
37-
const keystore = fs.readFileSync(walletPath);
37+
const keystore = readFileSync(walletPath, 'utf8');
3838
const wallet = Wallet.fromEncryptedJsonSync(keystore, walletTestPassword);
3939

4040
let entitiesOwnedCount = 0
@@ -44,7 +44,7 @@ let client: GolemBaseClient
4444

4545
describe("the golem-base client", () => {
4646
it("can be created", async () => {
47-
const key: AccountData = new Tagged("privatekey", utils.arrayify(wallet.privateKey))
47+
const key: AccountData = new Tagged("privatekey", getBytes(wallet.privateKey))
4848
client = {
4949
local: await createClient(
5050
1337,

test/internal/client.spec.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
import * as fs from 'fs'
1+
import { readFileSync } from "fs"
2+
import { join } from "path"
23
import {
34
expect
45
} from "chai"
@@ -8,7 +9,7 @@ import {
89
Logger
910
} from "tslog"
1011
import xdg from "xdg-portable"
11-
import { Wallet, utils } from "ethers"
12+
import { Wallet, getBytes } from "ethers"
1213
import {
1314
internal,
1415
type GolemBaseCreate,
@@ -63,11 +64,10 @@ async function ownerAddress(client: internal.GolemBaseClient): Promise<Hex> {
6364
}
6465

6566
// Path to a golembase wallet
66-
const walletPath = path.join(xdg.config(), 'golembase', 'wallet.json');
67+
const walletPath = join(xdg.config(), 'golembase', 'wallet.json');
6768
// The password that the test wallet was encrypted with
6869
const walletTestPassword = "password";
69-
70-
const keystore = fs.readFileSync(walletPath);
70+
const keystore = readFileSync(walletPath);
7171
const wallet = Wallet.fromEncryptedJsonSync(keystore, walletTestPassword);
7272

7373
let client: GolemBaseClient
@@ -81,7 +81,7 @@ let expirationBlock: number
8181

8282
describe("the internal golem-base client", () => {
8383
it("can be created", async () => {
84-
const key: AccountData = new Tagged("privatekey", utils.arrayify(wallet.privateKey))
84+
const key: AccountData = new Tagged("privatekey", getBytes(wallet.privateKey))
8585
client = {
8686
local: await internal.createClient(
8787
1337,

0 commit comments

Comments
 (0)