Skip to content
This repository was archived by the owner on Mar 8, 2024. It is now read-only.

Commit 487fb91

Browse files
committed
update README and Dockerfile
add command to print key(s) allow verify and inspect commands to be provided an explicit PayID
1 parent d5c6bb5 commit 487fb91

File tree

10 files changed

+200
-70
lines changed

10 files changed

+200
-70
lines changed

Dockerfile

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,21 @@
11
FROM node:12-alpine
22

3-
ADD . / payid-utils/
3+
ADD . / payid-cli/
44

5-
RUN cd payid-utils/ &&\
5+
RUN cd payid-cli/ &&\
6+
npm set unsafe-perm true &&\
67
npm cache clean --force &&\
78
npm install &&\
89
npm run build && \
910
npm link
1011

1112
FROM node:12-alpine
1213

13-
RUN mkdir /opt/payid-utils
14+
RUN mkdir /opt/payid-cli
1415

15-
WORKDIR /opt/payid-utils
16+
WORKDIR /opt/payid-cli
1617

17-
COPY --from=0 /payid-utils/dist /opt/payid-utils/dist
18-
COPY --from=0 /payid-utils/node_modules /opt/payid-utils/node_modules
18+
COPY --from=0 /payid-cli/dist /opt/payid-cli/dist
19+
COPY --from=0 /payid-cli/node_modules /opt/payid-cli/node_modules
1920

20-
CMD ["node", "/opt/payid-utils/dist/cli.js"]
21+
ENTRYPOINT ["node", "/opt/payid-cli/dist/cli.js"]

README.md

Lines changed: 70 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2,49 +2,87 @@
22

33
![NPM version badge](https://img.shields.io/npm/v/@payid-org/payid-cli)
44

5-
PayID CLI for creating, fetching, signing and verifying PayIDs. Based on the Typescript PayID Utils library.
5+
Command-line interface for creating, fetching, signing and verifying PayIDs.
6+
Based on the Typescript PayID [Utils](https://github.com/payid-org/utils) library.
67

78
## Prerequisites
89

9-
In order to use the CLI, both [node](https://nodejs.org/en/download/) and
10-
[npm](https://docs.npmjs.com/downloading-and-installing-packages-locally) must be installed first.
10+
In order to use the CLI, both [node](https://nodejs.org/en/download/) and
11+
[npm](https://docs.npmjs.com/downloading-and-installing-packages-locally) must be installed first.
1112

1213
## Installation
1314

14-
To install the PayID CLI, run the command
15+
To install the PayID CLI, run the command:
16+
1517
```
1618
npm install -g @payid-org/payid-cli
1719
```
1820

1921
## Interactive vs single command mode
2022

21-
CLI can be run in interactive mode or as a single command mode.
22-
In interactive mode, a prompt is shown where multiple commands can be run until the exit command is run.
23+
CLI can be run in interactive mode or non-interactive (single command) mode.
24+
In interactive mode, a prompt is shown where multiple commands can be run until the `exit` command is run.
25+
Interactive mode retains a history of commands run which can be accessed using the up arrow key. Command completion
26+
is available using the tab key.
27+
28+
In non-interactive mode, a single command is run (based on supplied command line arguments) and then the CLI exits.
29+
No prompt is shown in this mode. This mode is useful for running commands from a script as well as chaining the results
30+
of multiple commands together.
2331

24-
In single command mode, a single command is run and then the CLI exits. No prompt is shown in this mode.
25-
This mode is useful for running commands from a script, or from a shell where multiple commands can be
26-
chained together or to pipe output to another application.
32+
To run the CLI in interactive mode, run `payid`.
2733

28-
To run the CLI in interactive mode, run ```payid```.
34+
To run the CLI in non-interactive, run `payid <command> <arguments>`. Examples:
2935

30-
To run the CLI in single command mode, run ```payid <command> <arguments>```. Example:
3136
```
3237
payid load 'nhartner$xpring.money'
3338
```
34-
_note: when passing a PayID as an argument in single command mode, the PayID needs to be quoted
35-
if run in a Linux shell (to avoid the '$' being interpolated as a variable by the Linux shell).
39+
40+
Or to run multiple commands:
41+
42+
```
43+
payid init 'my$pay.id' && payid crypto-address add btc mainnet notARealAddress && payid save
44+
```
45+
46+
_Note_: when passing a PayID as an argument in non-interactive mode, the PayID needs to be escaped or quoted
47+
to avoid the '\$' being interpolated as a variable by the shell.
3648

3749
## Commands
3850

39-
A list of available commands can be found run running the `help` command.
51+
The following commands are available:
52+
53+
```
54+
help [command...] Provides help for a given command.
55+
exit Exits application.
56+
clear clear the terminal
57+
crypto-address add <paymentNetwork> <environment> <address> [tag] start building a new PayID
58+
crypto-address remove <address> remove an address from the current PayID
59+
keys clear clears all loaded keys
60+
keys generate generates and saves a new identity key
61+
keys list lists keys that have been loaded
62+
keys load <filePath> load identity-key from file
63+
keys print print keys that have been loaded in pem format
64+
init <payid> initializes a new PayID
65+
inspect [payId] Inspect signatures on the loaded PayID or from an optionally specified PayID
66+
load <payId> loads a PayID from PayID server
67+
show Shows the currently loaded PayID
68+
sign sign the loaded PayID with the loaded signing keys
69+
verify [payId] Verify the loaded PayID or an optionally specified PayID
70+
save Save the currently loaded PayID
71+
from-url <url> convert a URL to a PayID
72+
to-url <payId> converts PayID to url
73+
74+
```
4075

4176
## Use Cases
4277

4378
### Loading a PayID
79+
4480
The following command can be used to load an existing PayID from a remote server:
81+
4582
```
4683
load nhartner$xpring
4784
```
85+
4886
This will fetch all the PayID address mappings for the given PayID from the remote
4987
server and displays the resulting JSON.
5088

@@ -59,6 +97,7 @@ crypto-address add xrpl mainnet rP3t3JStqWPYd8H88WfBYh3v84qqYzbHQ6 12345
5997
crypto-address add btc mainnet 3M2CH71P6uZTra1PsjiEhNFB7kCENShCgt
6098
save
6199
```
100+
62101
The end result should be a PayID json representation being saved to the local filesystem as
63102
example.json.
64103

@@ -72,9 +111,11 @@ To remove all loaded keys from the CLI's local storage, use the `keys clear` com
72111
The `keys list` command will show you all keys currently loaded into the CLI.
73112

74113
To generate new key run:
114+
75115
```
76116
keys generate
77117
```
118+
78119
This will generate a new key and save it to a file named `identity-key.pem`. To load a previously
79120
created identity key, run `keys load </path/to/pem/file>`.
80121

@@ -93,5 +134,18 @@ command can be used to save your PayID, with signed addresses, to file.
93134

94135
Two commands are available to verify a PayID's verified addresses.
95136

96-
- ```verify``` - checks if all the verified addresses have valid signatures
97-
- ```insepct``` - displays details information about each verified address and signatures.
137+
- `verify` - checks if all the verified addresses have valid signatures.
138+
- `inspect` - displays details information about each verified address and signatures.
139+
140+
## Creating, Signing and Inspecting a PayID
141+
142+
Bringing all the above commands together, we can create a PayID, add an address mapping, generate an identity key,
143+
sign our PayID address mapping and then inspect the final result.
144+
145+
```
146+
init example$mypayid.com
147+
crypto-address add xrpl mainnet rP3t3JStqWPYd8H88WfBYh3v84qqYzbHQ6
148+
keys generate
149+
sign
150+
inspect
151+
```

src/cli.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ new cmd.ClearKeysCommand(vorpal, localStorage).setup()
1717
new cmd.GenerateIdentityKeyCommand(vorpal, localStorage).setup()
1818
new cmd.ListKeysCommand(vorpal, localStorage).setup()
1919
new cmd.LoadIdentityKeyCommand(vorpal, localStorage).setup()
20+
new cmd.PrintKeysCommand(vorpal, localStorage).setup()
2021
new cmd.InitPayIdCommand(vorpal, localStorage).setup()
2122
new cmd.InspectPayIdCommand(vorpal, localStorage).setup()
2223
new cmd.LoadPayIdCommand(vorpal, localStorage).setup()

src/commands/Command.ts

Lines changed: 54 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
import { PaymentInformation } from '@payid-org/utils'
1+
import { convertPayIdToUrl, PaymentInformation } from '@payid-org/utils'
2+
import axios, { AxiosResponse } from 'axios'
23
import * as Vorpal from 'vorpal'
34
import { Args } from 'vorpal'
45

@@ -34,13 +35,11 @@ abstract class Command {
3435
// Execute the concrete action inside a try/catch wrapper
3536
this.vorpal.command(this.command(), this.description()).action(
3637
async (args: Args): Promise<void> => {
37-
try {
38-
await this.action(args)
39-
} catch (error) {
38+
await this.action(args).catch((error) => {
4039
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment -- error has any type
4140
const { message } = error
4241
this.vorpal.log(message)
43-
}
42+
})
4443
},
4544
)
4645
}
@@ -71,6 +70,23 @@ abstract class Command {
7170
jsonBeautify(JSON.stringify(info, null, 2))
7271
}
7372

73+
/**
74+
* Retrieves a PayID using the optional payId argument or else returns the PaymentInformation
75+
* currently loaded in local storage.
76+
*
77+
* @param args - The vorpal args object.
78+
* @returns PaymentInformation from args or local storage. Or error if can't be loaded.
79+
*/
80+
protected async payIdFromArgsOrLocalStorage(
81+
args: Args,
82+
): Promise<PaymentInformation> {
83+
const { payId } = args
84+
if (payId) {
85+
return loadPayId(payId)
86+
}
87+
return this.getPaymentInfo()
88+
}
89+
7490
/**
7591
* The vorpal command.
7692
*
@@ -93,4 +109,37 @@ abstract class Command {
93109
protected abstract async action(args: Args): Promise<void>
94110
}
95111

112+
/**
113+
* Loads a PayID from a remote server.
114+
*
115+
* @param payId - The PayID to lookup.
116+
* @returns A promise that resolves to the PaymentInformation for the PayID.
117+
*/
118+
export async function loadPayId(payId: string): Promise<PaymentInformation> {
119+
const url = convertPayIdToUrl(payId).href
120+
return axios
121+
.get(url, {
122+
headers: {
123+
'payid-version': '1.0',
124+
accept: 'application/payid+json',
125+
},
126+
})
127+
.then((response) => {
128+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment -- axios response.data has an any type
129+
const info: PaymentInformation = response.data
130+
return info
131+
})
132+
.catch((error) => {
133+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment -- axios error has an any type
134+
const {
135+
response,
136+
message,
137+
}: { response?: AxiosResponse; message: string } = error
138+
if (response) {
139+
throw new Error(`Received HTTP status ${response.status} on ${url}`)
140+
}
141+
throw new Error(`Bad request ${url}. Error: ${message}.`)
142+
})
143+
}
144+
96145
export default Command

src/commands/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ export { default as GenerateIdentityKeyCommand } from './key-generate'
88
export { default as LoadIdentityKeyCommand } from './key-load'
99
export { default as ClearKeysCommand } from './keys-clear'
1010
export { default as ListKeysCommand } from './keys-list'
11+
export { default as PrintKeysCommand } from './keys-print'
1112
export { default as LocalStorage } from './localstorage'
1213
export { default as InitPayIdCommand } from './payid-init'
1314
export { default as InspectPayIdCommand } from './payid-inspect'

src/commands/keys-print.ts

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
import { toKey } from '@payid-org/utils'
2+
3+
import Command from './Command'
4+
5+
/**
6+
* Prints, to console, a summary of the identity and server keys that are currently loaded in
7+
* local storage and available to use for signing.
8+
*/
9+
export default class PrintKeysCommand extends Command {
10+
/**
11+
* @override
12+
*/
13+
protected async action(): Promise<void> {
14+
this.printKeys('identity-keys')
15+
}
16+
17+
/**
18+
* @override
19+
*/
20+
protected command(): string {
21+
return 'keys print'
22+
}
23+
24+
/**
25+
* @override
26+
*/
27+
protected description(): string {
28+
return 'print keys that have been loaded in pem format'
29+
}
30+
31+
/**
32+
* Prints the key as pem to the console.
33+
*
34+
* @param name - The name of the key to print.
35+
*/
36+
private printKeys(name: string): void {
37+
const keys = this.localStorage.getSigningKeys(name)
38+
keys.forEach((key) => {
39+
const pem = toKey(key).toPEM(true)
40+
this.vorpal.log(pem)
41+
})
42+
}
43+
}

src/commands/payid-inspect.ts

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,18 +29,21 @@ export default class InspectPayIdCommand extends Command {
2929
* @override
3030
*/
3131
protected command(): string {
32-
return 'inspect'
32+
return 'inspect [payId]'
3333
}
3434

3535
/**
3636
* @override
3737
*/
3838
protected description(): string {
39-
return 'Inspect signatures on the loaded PayID'
39+
return 'Inspect signatures on the loaded PayID or from an optionally specified PayID'
4040
}
4141

42-
protected async action(): Promise<void> {
43-
const info = this.getPaymentInfo()
42+
/**
43+
* @override
44+
*/
45+
protected async action(args: Vorpal.Args): Promise<void> {
46+
const info = await this.payIdFromArgsOrLocalStorage(args)
4447
const result = this.paymentInformationInspector.inspect(info)
4548
this.vorpal.log(`${info.payId} ${validString(result.isVerified)}`)
4649
result.verifiedAddressesResults.forEach((addressResult) => {

src/commands/payid-load.ts

Lines changed: 6 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
1-
import { convertPayIdToUrl, PaymentInformation } from '@payid-org/utils'
2-
import axios, { AxiosResponse } from 'axios'
31
import * as Vorpal from 'vorpal'
42

5-
import Command from './Command'
3+
import Command, { loadPayId } from './Command'
64

75
/**
86
* Loads a PayID from the remote server. For example, "load test$xpring.money" will
@@ -15,40 +13,17 @@ export default class LoadPayIdCommand extends Command {
1513
* @override
1614
*/
1715
protected async action(args: Vorpal.Args): Promise<void> {
18-
const { payid } = args
19-
const url = convertPayIdToUrl(payid).href
20-
await axios
21-
.get(url, {
22-
headers: {
23-
'payid-version': '1.0',
24-
accept: 'application/payid+json',
25-
},
26-
})
27-
.then((response) => {
28-
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment -- axios response.data has an any type
29-
const info: PaymentInformation = response.data
30-
this.localStorage.setPaymentInfo(info)
31-
this.logPaymentInfo(info)
32-
})
33-
.catch((error) => {
34-
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment -- axios error has an any type
35-
const {
36-
response,
37-
message,
38-
}: { response?: AxiosResponse; message: string } = error
39-
if (response) {
40-
this.vorpal.log(`Received HTTP status ${response.status} on ${url}`)
41-
return
42-
}
43-
this.vorpal.log(`Bad request ${url}. Error: ${message}.`)
44-
})
16+
const { payId } = args
17+
const info = await loadPayId(payId)
18+
this.localStorage.setPaymentInfo(info)
19+
this.logPaymentInfo(info)
4520
}
4621

4722
/**
4823
* @override
4924
*/
5025
protected command(): string {
51-
return 'load <payid>'
26+
return 'load <payId>'
5227
}
5328

5429
/**

0 commit comments

Comments
 (0)