psf-bch-api 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (53) hide show
  1. package/.env-local +4 -0
  2. package/LICENSE.md +8 -0
  3. package/README.md +8 -0
  4. package/apidoc.json +9 -0
  5. package/bin/server.js +183 -0
  6. package/dev-docs/README.md +4 -0
  7. package/dev-docs/creation-prompt.md +34 -0
  8. package/dev-docs/rest2nostr-poxy-api.plan.md +163 -0
  9. package/dev-docs/test-plan-for-rest2nostr.plan.md +161 -0
  10. package/dev-docs/unit-test-prompt.md +13 -0
  11. package/examples/01-create-account.js +67 -0
  12. package/examples/02-read-posts.js +44 -0
  13. package/examples/03-write-post.js +55 -0
  14. package/examples/04-read-alice-posts.js +49 -0
  15. package/examples/05-get-follow-list.js +53 -0
  16. package/examples/06-update-follow-list.js +63 -0
  17. package/examples/07-liking-event.js +59 -0
  18. package/examples/README.md +90 -0
  19. package/index.js +11 -0
  20. package/package.json +37 -0
  21. package/production/docker/Dockerfile +85 -0
  22. package/production/docker/cleanup-images.sh +5 -0
  23. package/production/docker/docker-compose.yml +19 -0
  24. package/production/docker/start-rest2nostr.sh +3 -0
  25. package/src/adapters/full-node-rpc.js +133 -0
  26. package/src/adapters/index.js +217 -0
  27. package/src/adapters/wlogger.js +79 -0
  28. package/src/config/env/common.js +64 -0
  29. package/src/config/env/development.js +7 -0
  30. package/src/config/env/production.js +7 -0
  31. package/src/config/index.js +14 -0
  32. package/src/controllers/index.js +56 -0
  33. package/src/controllers/rest-api/full-node/blockchain/controller.js +553 -0
  34. package/src/controllers/rest-api/full-node/blockchain/index.js +66 -0
  35. package/src/controllers/rest-api/index.js +55 -0
  36. package/src/controllers/timer-controller.js +72 -0
  37. package/src/entities/event.js +71 -0
  38. package/src/use-cases/full-node-blockchain-use-cases.js +134 -0
  39. package/src/use-cases/index.js +29 -0
  40. package/test/integration/api/event-integration.js +250 -0
  41. package/test/integration/api/req-integration.js +173 -0
  42. package/test/integration/api/subscription-integration.js +198 -0
  43. package/test/integration/use-cases/manage-subscription-integration.js +163 -0
  44. package/test/integration/use-cases/publish-event-integration.js +104 -0
  45. package/test/integration/use-cases/query-events-integration.js +95 -0
  46. package/test/unit/adapters/full-node-rpc-unit.js +122 -0
  47. package/test/unit/bin/server-unit.js +63 -0
  48. package/test/unit/controllers/blockchain-controller-unit.js +215 -0
  49. package/test/unit/controllers/rest-api-index-unit.js +85 -0
  50. package/test/unit/entities/event-unit.js +139 -0
  51. package/test/unit/mocks/controller-mocks.js +98 -0
  52. package/test/unit/mocks/event-mocks.js +194 -0
  53. package/test/unit/use-cases/full-node-blockchain-use-cases-unit.js +137 -0
@@ -0,0 +1,44 @@
1
+ /*
2
+ Example script for reading posts (kind 1 events) from a relay.
3
+ Refactored to use REST API instead of WebSocket.
4
+
5
+ Run the server with `npm start` in the main directory, before running this example.
6
+ */
7
+
8
+ const API_URL = process.env.API_URL || 'http://localhost:5942'
9
+
10
+ // JB55's public key
11
+ const jb55 = '32e1827635450ebb3c5a7d12c1f8e7b2b514439ac10a67eef3d9fd9c5c68e245'
12
+
13
+ // Create subscription ID
14
+ const subId = 'read-posts-' + Date.now()
15
+
16
+ // Create filters - read posts from JB55
17
+ const filters = {
18
+ limit: 2,
19
+ kinds: [1],
20
+ authors: [jb55]
21
+ }
22
+
23
+ try {
24
+ // Query events using GET /req/:subId
25
+ const filtersJson = encodeURIComponent(JSON.stringify([filters]))
26
+ const url = `${API_URL}/req/${subId}?filters=${filtersJson}`
27
+
28
+ console.log(`Querying events from ${API_URL}`)
29
+ console.log('Filters:', JSON.stringify(filters, null, 2))
30
+
31
+ const response = await fetch(url)
32
+ const events = await response.json()
33
+
34
+ console.log(`\nReceived ${events.length} events:`)
35
+ events.forEach((ev, index) => {
36
+ console.log(`\nEvent ${index + 1}:`)
37
+ console.log(' ID:', ev.id)
38
+ console.log(' Author:', ev.pubkey)
39
+ console.log(' Created:', new Date(ev.created_at * 1000).toISOString())
40
+ console.log(' Content:', ev.content)
41
+ })
42
+ } catch (err) {
43
+ console.error('Error reading posts:', err)
44
+ }
@@ -0,0 +1,55 @@
1
+ /*
2
+ Example script for writing a post to a relay.
3
+ Refactored to use REST API instead of WebSocket.
4
+
5
+ Run the server with `npm start` in the main directory, before running this example.
6
+ */
7
+
8
+ import { finalizeEvent, getPublicKey } from 'nostr-tools/pure'
9
+ import { hexToBytes } from '@noble/hashes/utils.js'
10
+
11
+ const API_URL = process.env.API_URL || 'http://localhost:5942'
12
+
13
+ // Alice is our user making the post.
14
+ const alicePrivKeyHex = '3292a48aa331aeccce003d50d70fbd79617ba91860abbd2c78fa4a8301e36bc0'
15
+ const alicePrivKeyBin = hexToBytes(alicePrivKeyHex)
16
+ const alicePubKey = getPublicKey(alicePrivKeyBin)
17
+ console.log(`Alice Public Key: ${alicePubKey}`)
18
+
19
+ const now = new Date()
20
+
21
+ // Generate a post.
22
+ const eventTemplate = {
23
+ kind: 1,
24
+ created_at: Math.floor(Date.now() / 1000),
25
+ tags: [],
26
+ content: `This is a test message posted at ${now.toLocaleString()}`
27
+ }
28
+ console.log(`eventTemplate: ${JSON.stringify(eventTemplate, null, 2)}`)
29
+
30
+ // Sign the post
31
+ const signedEvent = finalizeEvent(eventTemplate, alicePrivKeyBin)
32
+ console.log('signedEvent:', JSON.stringify(signedEvent, null, 2))
33
+
34
+ // Publish to REST API
35
+ try {
36
+ const response = await fetch(`${API_URL}/event`, {
37
+ method: 'POST',
38
+ headers: {
39
+ 'Content-Type': 'application/json'
40
+ },
41
+ body: JSON.stringify(signedEvent)
42
+ })
43
+
44
+ const result = await response.json()
45
+ console.log('result:', result)
46
+
47
+ if (result.accepted) {
48
+ console.log('Post published successfully!')
49
+ console.log('Event ID:', result.eventId)
50
+ } else {
51
+ console.error('Failed to publish:', result.message)
52
+ }
53
+ } catch (err) {
54
+ console.error('Error publishing post:', err)
55
+ }
@@ -0,0 +1,49 @@
1
+ /*
2
+ Example script for reading posts from user Alice.
3
+ Refactored to use REST API instead of WebSocket.
4
+
5
+ Run the server with `npm start` in the main directory, before running this example.
6
+ */
7
+
8
+ import { getPublicKey } from 'nostr-tools/pure'
9
+ import { hexToBytes } from '@noble/hashes/utils.js'
10
+
11
+ const API_URL = process.env.API_URL || 'http://localhost:5942'
12
+
13
+ // Alice is our user.
14
+ const alicePrivKeyHex = '3292a48aa331aeccce003d50d70fbd79617ba91860abbd2c78fa4a8301e36bc0'
15
+ const alicePrivKeyBin = hexToBytes(alicePrivKeyHex)
16
+ const alicePubKey = getPublicKey(alicePrivKeyBin)
17
+ console.log(`Alice Public Key: ${alicePubKey}`)
18
+
19
+ // Create subscription ID
20
+ const subId = 'read-alice-posts-' + Date.now()
21
+
22
+ // Create filters - read posts from Alice
23
+ const filters = {
24
+ limit: 2,
25
+ kinds: [1],
26
+ authors: [alicePubKey]
27
+ }
28
+
29
+ try {
30
+ // Query events using GET /req/:subId
31
+ const filtersJson = encodeURIComponent(JSON.stringify([filters]))
32
+ const url = `${API_URL}/req/${subId}?filters=${filtersJson}`
33
+
34
+ console.log(`Querying events from ${API_URL}`)
35
+ console.log('Filters:', JSON.stringify(filters, null, 2))
36
+
37
+ const response = await fetch(url)
38
+ const events = await response.json()
39
+
40
+ console.log(`\nReceived ${events.length} events from Alice:`)
41
+ events.forEach((ev, index) => {
42
+ console.log(`\nEvent ${index + 1}:`)
43
+ console.log(' ID:', ev.id)
44
+ console.log(' Created:', new Date(ev.created_at * 1000).toISOString())
45
+ console.log(' Content:', ev.content)
46
+ })
47
+ } catch (err) {
48
+ console.error('Error reading Alice posts:', err)
49
+ }
@@ -0,0 +1,53 @@
1
+ /*
2
+ Example script for getting a follow list (kind 3 events).
3
+ Refactored to use REST API instead of WebSocket.
4
+
5
+ Run the server with `npm start` in the main directory, before running this example.
6
+ */
7
+
8
+ import { getPublicKey } from 'nostr-tools/pure'
9
+ import { hexToBytes } from '@noble/hashes/utils.js'
10
+
11
+ const API_URL = process.env.API_URL || 'http://localhost:5942'
12
+
13
+ // Alice is our user to get the follow list.
14
+ const alicePrivKeyHex = '3292a48aa331aeccce003d50d70fbd79617ba91860abbd2c78fa4a8301e36bc0'
15
+ const alicePrivKeyBin = hexToBytes(alicePrivKeyHex)
16
+ const alicePubKey = getPublicKey(alicePrivKeyBin)
17
+ console.log(`Alice Public Key: ${alicePubKey}`)
18
+
19
+ // Create subscription ID
20
+ const subId = 'get-follow-list-' + Date.now()
21
+
22
+ // Create filters - get follow list (kind 3) from Alice
23
+ const filters = {
24
+ limit: 5,
25
+ kinds: [3],
26
+ authors: [alicePubKey]
27
+ }
28
+
29
+ try {
30
+ // Query events using GET /req/:subId
31
+ const filtersJson = encodeURIComponent(JSON.stringify([filters]))
32
+ const url = `${API_URL}/req/${subId}?filters=${filtersJson}`
33
+
34
+ console.log(`Querying follow list from ${API_URL}`)
35
+ console.log('Filters:', JSON.stringify(filters, null, 2))
36
+
37
+ const response = await fetch(url)
38
+ const events = await response.json()
39
+
40
+ if (events.length > 0) {
41
+ // Get the most recent follow list (kind 3 events are replaceable)
42
+ const followListEvent = events[0]
43
+ const aliceFollowList = followListEvent.tags.filter(tag => tag[0] === 'p')
44
+ console.log(`\nAlice Follow list (${aliceFollowList.length} followed users):`)
45
+ aliceFollowList.forEach((tag, index) => {
46
+ console.log(` ${index + 1}. ${tag[1]}${tag[3] ? ` (${tag[3]})` : ''}`)
47
+ })
48
+ } else {
49
+ console.log('\nNo follow list found for Alice')
50
+ }
51
+ } catch (err) {
52
+ console.error('Error getting follow list:', err)
53
+ }
@@ -0,0 +1,63 @@
1
+ /*
2
+ Example to update the follow list with a new list of people to follow.
3
+ Refactored to use REST API instead of WebSocket.
4
+
5
+ Run the server with `npm start` in the main directory, before running this example.
6
+ */
7
+
8
+ import { finalizeEvent, getPublicKey } from 'nostr-tools/pure'
9
+ import { hexToBytes } from '@noble/hashes/utils.js'
10
+
11
+ const API_URL = process.env.API_URL || 'http://localhost:5942'
12
+
13
+ // Alice wants to update her follow list
14
+ const alicePrivKeyHex = '3292a48aa331aeccce003d50d70fbd79617ba91860abbd2c78fa4a8301e36bc0'
15
+ const alicePrivKeyBin = hexToBytes(alicePrivKeyHex)
16
+ const alicePubKey = getPublicKey(alicePrivKeyBin)
17
+ console.log(`Alice Public Key: ${alicePubKey}`)
18
+
19
+ // Bob is the person to be added to the new follow list
20
+ const bobPrivKeyHex = 'd2e71a977bc3900d6b0f787421e3d1a666cd12ca625482b0d9eeffd23489c99f'
21
+ const bobPrivKeyBin = hexToBytes(bobPrivKeyHex)
22
+ const bobPubKey = getPublicKey(bobPrivKeyBin)
23
+ console.log(`Bob Public Key: ${bobPubKey}`)
24
+
25
+ const psf = 'wss://nostr-relay.psfoundation.info'
26
+
27
+ const followList = [
28
+ ['p', bobPubKey, psf, 'bob']
29
+ ]
30
+
31
+ // Generate a follow list event (kind 3)
32
+ const eventTemplate = {
33
+ kind: 3,
34
+ created_at: Math.floor(Date.now() / 1000),
35
+ tags: followList,
36
+ content: ''
37
+ }
38
+ console.log(`eventTemplate: ${JSON.stringify(eventTemplate, null, 2)}`)
39
+
40
+ // Sign the event
41
+ const signedEvent = finalizeEvent(eventTemplate, alicePrivKeyBin)
42
+
43
+ // Publish to REST API
44
+ try {
45
+ const response = await fetch(`${API_URL}/event`, {
46
+ method: 'POST',
47
+ headers: {
48
+ 'Content-Type': 'application/json'
49
+ },
50
+ body: JSON.stringify(signedEvent)
51
+ })
52
+
53
+ const result = await response.json()
54
+ console.log('Publish result:', result)
55
+
56
+ if (result.accepted) {
57
+ console.log('Follow list updated successfully!')
58
+ } else {
59
+ console.error('Failed to update follow list:', result.message)
60
+ }
61
+ } catch (err) {
62
+ console.error('Error updating follow list:', err)
63
+ }
@@ -0,0 +1,59 @@
1
+ /*
2
+ Example script for adding a reaction (like) to an event.
3
+ Refactored to use REST API instead of WebSocket.
4
+ https://github.com/nostr-protocol/nips/blob/master/25.md
5
+
6
+ Run the server with `npm start` in the main directory, before running this example.
7
+ */
8
+
9
+ import { hexToBytes } from '@noble/hashes/utils.js'
10
+ import { finalizeEvent, getPublicKey } from 'nostr-tools/pure'
11
+
12
+ const API_URL = process.env.API_URL || 'http://localhost:5942'
13
+
14
+ const bobPrivKeyHex = 'd2e71a977bc3900d6b0f787421e3d1a666cd12ca625482b0d9eeffd23489c99f'
15
+ const bobPrivKeyBin = hexToBytes(bobPrivKeyHex)
16
+ const bobPubKey = getPublicKey(bobPrivKeyBin)
17
+
18
+ const psf = 'wss://nostr-relay.psfoundation.info'
19
+
20
+ const evIdToLike = 'd09b4c5da59be3cd2768aa53fa78b77bf4859084c94f3bf26d401f004a9c8167'
21
+ const evIdAuthorPubKey = '2c7e76c0f8dc1dca9d0197c7d19be580a8d074ccada6a2f6ebe056ae41092e92'
22
+
23
+ // Generate like event (kind 7)
24
+ const likeEventTemplate = {
25
+ kind: 7,
26
+ created_at: Math.floor(Date.now() / 1000),
27
+ pubkey: bobPubKey,
28
+ tags: [
29
+ ['e', evIdToLike, psf], // "e" tag includes event id, relay reference
30
+ ['p', evIdAuthorPubKey, psf] // "p" tag includes author pubkey, relay reference
31
+ ],
32
+ content: '+'
33
+ }
34
+
35
+ // Sign the event
36
+ const signedEvent = finalizeEvent(likeEventTemplate, bobPrivKeyBin)
37
+ console.log('signedEvent:', JSON.stringify(signedEvent, null, 2))
38
+
39
+ // Publish to REST API
40
+ try {
41
+ const response = await fetch(`${API_URL}/event`, {
42
+ method: 'POST',
43
+ headers: {
44
+ 'Content-Type': 'application/json'
45
+ },
46
+ body: JSON.stringify(signedEvent)
47
+ })
48
+
49
+ const result = await response.json()
50
+ console.log('result:', result)
51
+
52
+ if (result.accepted) {
53
+ console.log('Like published successfully!')
54
+ } else {
55
+ console.error('Failed to publish like:', result.message)
56
+ }
57
+ } catch (err) {
58
+ console.error('Error publishing like:', err)
59
+ }
@@ -0,0 +1,90 @@
1
+ # REST2NOSTR Examples
2
+
3
+ This directory contains examples refactored from the `nostr-sandbox/` directory to use the REST API instead of WebSocket connections.
4
+
5
+ ## Prerequisites
6
+
7
+ 1. Install dependencies:
8
+ ```bash
9
+ npm install nostr-tools @noble/hashes
10
+ ```
11
+
12
+ 2. Start the REST2NOSTR proxy server:
13
+ ```bash
14
+ npm start
15
+ ```
16
+
17
+ 3. Set the API_URL environment variable if the server is not running on localhost:3000:
18
+ ```bash
19
+ export API_URL=http://localhost:3000
20
+ ```
21
+
22
+ ## Examples
23
+
24
+ ### 01-create-account.js
25
+ Creates a new Nostr account keypair and publishes profile metadata (kind 0 event).
26
+
27
+ ```bash
28
+ node examples/01-create-account.js
29
+ ```
30
+
31
+ ### 02-read-posts.js
32
+ Reads posts (kind 1 events) from a specific author using GET /req/:subId.
33
+
34
+ ```bash
35
+ node examples/02-read-posts.js
36
+ ```
37
+
38
+ ### 03-write-post.js
39
+ Publishes a text post (kind 1 event) using POST /event.
40
+
41
+ ```bash
42
+ node examples/03-write-post.js
43
+ ```
44
+
45
+ ### 04-read-alice-posts.js
46
+ Reads posts from Alice's account using GET /req/:subId with author filter.
47
+
48
+ ```bash
49
+ node examples/04-read-alice-posts.js
50
+ ```
51
+
52
+ ### 14-get-follow-list.js
53
+ Retrieves a user's follow list (kind 3 event) using GET /req/:subId.
54
+
55
+ ```bash
56
+ node examples/05-get-follow-list.js
57
+ ```
58
+
59
+ ### 15-update-follow-list.js
60
+ Updates a user's follow list (kind 3 event) using POST /event.
61
+
62
+ ```bash
63
+ node examples/06-update-follow-list.js
64
+ ```
65
+
66
+ ### 17-liking-event.js
67
+ Adds a reaction/like to an event (kind 7 event) using POST /event.
68
+
69
+ ```bash
70
+ node examples/07-liking-event.js
71
+ ```
72
+
73
+ ## API Endpoints Used
74
+
75
+ - **POST /event**: Publish events to the relay
76
+ - **GET /req/:subId**: Stateless query for events (returns immediately)
77
+
78
+ ## Differences from WebSocket Examples
79
+
80
+ 1. **No WebSocket connections**: All communication is via HTTP REST API
81
+ 2. **Stateless queries**: GET /req/:subId returns events immediately rather than streaming
82
+ 3. **Event publishing**: POST /event returns immediately with acceptance status
83
+ 4. **No subscription management**: For stateless queries, subscriptions are automatically closed after EOSE
84
+
85
+ ## Notes
86
+
87
+ - These examples use the same private keys as the original sandbox examples for consistency
88
+ - The REST API handles WebSocket connections to relays internally
89
+ - For real-time streaming, use POST /req/:subId which supports Server-Sent Events (SSE)
90
+
package/index.js ADDED
@@ -0,0 +1,11 @@
1
+ /*
2
+ Main entry point for REST2NOSTR Proxy API
3
+ */
4
+
5
+ import Server from './bin/server.js'
6
+
7
+ const server = new Server()
8
+ server.startServer().catch(err => {
9
+ console.error('Failed to start server:', err)
10
+ process.exit(1)
11
+ })
package/package.json ADDED
@@ -0,0 +1,37 @@
1
+ {
2
+ "name": "psf-bch-api",
3
+ "version": "1.1.0",
4
+ "main": "index.js",
5
+ "type": "module",
6
+ "scripts": {
7
+ "start": "node bin/server.js",
8
+ "docs": "./node_modules/.bin/apidoc -i src/ -o docs",
9
+ "lint": "standard --env mocha --fix",
10
+ "test": "npm run lint && TEST=unit c8 mocha 'test/unit/**/*.js' --exit",
11
+ "test:integration": "mocha --timeout 25000 'test/integration/**/*.js' --exit",
12
+ "coverage": "c8 --reporter=html mocha 'test/unit/**/*.js' --exit"
13
+ },
14
+ "author": "Chris Troutner <chris.troutner@gmail.com>",
15
+ "license": "MIT",
16
+ "description": "REST API proxy to Bitcoin Cash infrastructure",
17
+ "dependencies": {
18
+ "axios": "1.7.7",
19
+ "cors": "2.8.5",
20
+ "dotenv": "16.3.1",
21
+ "express": "5.1.0",
22
+ "winston": "3.11.0",
23
+ "winston-daily-rotate-file": "4.7.1"
24
+ },
25
+ "devDependencies": {
26
+ "apidoc": "1.2.0",
27
+ "c8": "10.1.3",
28
+ "chai": "6.2.0",
29
+ "mocha": "11.7.4",
30
+ "sinon": "21.0.0",
31
+ "standard": "17.1.2"
32
+ },
33
+ "apidoc": {
34
+ "title": "psf-bch-api",
35
+ "url": "http://localhost:3070"
36
+ }
37
+ }
@@ -0,0 +1,85 @@
1
+ # Create a Dockerized API server
2
+ #
3
+
4
+ #IMAGE BUILD COMMANDS
5
+ # ct-base-ubuntu = ubuntu 18.04 + nodejs v10 LTS
6
+ #FROM christroutner/ct-base-ubuntu
7
+ FROM ubuntu:22.04
8
+ MAINTAINER Chris Troutner <chris.troutner@gmail.com>
9
+
10
+ #Update the OS and install any OS packages needed.
11
+ RUN apt-get update
12
+ RUN apt-get install -y sudo git curl nano gnupg wget zip unzip python3
13
+
14
+ #Install Node and NPM
15
+ RUN curl -sL https://deb.nodesource.com/setup_20.x -o nodesource_setup.sh
16
+ RUN bash nodesource_setup.sh
17
+ RUN apt-get install -y nodejs build-essential
18
+
19
+ #Create the user 'safeuser' and add them to the sudo group.
20
+ RUN useradd -ms /bin/bash safeuser
21
+ RUN adduser safeuser sudo
22
+
23
+ #Set password to 'password' change value below if you want a different password
24
+ RUN echo safeuser:password | chpasswd
25
+
26
+ #Set the working directory to be the home directory
27
+ WORKDIR /home/safeuser
28
+
29
+ #Setup NPM for non-root global install
30
+ RUN mkdir /home/safeuser/.npm-global
31
+ RUN chown -R safeuser .npm-global
32
+ RUN echo "export PATH=~/.npm-global/bin:$PATH" >> /home/safeuser/.profile
33
+ RUN runuser -l safeuser -c "npm config set prefix '~/.npm-global'"
34
+
35
+ # Update to the latest version of npm.
36
+ #RUN npm install -g npm@8.3.0
37
+
38
+ # npm mirror to prevent direct dependency on npm.
39
+ #RUN npm set registry http://94.130.170.209:4873/
40
+
41
+ # Switch to user account.
42
+ #USER safeuser
43
+ # Prep 'sudo' commands.
44
+ #RUN echo 'abcd8765' | sudo -S pwd
45
+
46
+ #RUN npm install -g node-gyp
47
+
48
+ # Clone the rest.bitcoin.com repository
49
+ WORKDIR /home/safeuser
50
+ RUN git clone https://github.com/christroutner/REST2NOSTR
51
+
52
+ # Switch to the desired branch. `master` is usually stable,
53
+ # and `stage` has the most up-to-date changes.
54
+ WORKDIR /home/safeuser/REST2NOSTR
55
+
56
+ # For development: switch to unstable branch
57
+ #RUN git checkout pin-ipfs
58
+
59
+ # Install dependencies
60
+ RUN npm install
61
+
62
+ # Generate the API docs
63
+ RUN npm run docs
64
+
65
+ #VOLUME /home/safeuser/keys
66
+
67
+ # Make leveldb folders
68
+ #RUN mkdir leveldb
69
+ #WORKDIR /home/safeuser/psf-slp-indexer/leveldb
70
+ #RUN mkdir current
71
+ #RUN mkdir zips
72
+ #RUN mkdir backup
73
+ #WORKDIR /home/safeuser/psf-slp-indexer/leveldb/zips
74
+ #COPY restore-auto.sh restore-auto.sh
75
+ #WORKDIR /home/safeuser/psf-slp-indexer
76
+
77
+ # Expose the port the API will be served on.
78
+ #EXPOSE 5011
79
+
80
+ # Start the application.
81
+ #COPY start-production.sh start-production.sh
82
+ VOLUME start-rest2nostr.sh
83
+ CMD ["./start-rest2nostr.sh"]
84
+
85
+ #CMD ["npm", "start"]
@@ -0,0 +1,5 @@
1
+ #!/bin/bash
2
+
3
+ # Remove all untagged docker images.
4
+ docker rmi $(docker images | grep "^<none>" | awk '{print $3}')
5
+
@@ -0,0 +1,19 @@
1
+ # Start the service with the command 'docker-compose up -d'
2
+
3
+ services:
4
+ rest2nostr:
5
+ build: .
6
+ container_name: rest2nostr
7
+ logging:
8
+ driver: 'json-file'
9
+ options:
10
+ max-size: '10m'
11
+ max-file: '10'
12
+ #mem_limit: 500mb
13
+ #links:
14
+ # - mongo-slp-indexer
15
+ ports:
16
+ - '5942:5942' # <host port>:<container port>
17
+ volumes:
18
+ - ./start-rest2nostr.sh:/home/safeuser/REST2NOSTR/start-rest2nostr.sh
19
+ restart: always
@@ -0,0 +1,3 @@
1
+ #!/bin/bash
2
+
3
+ npm start