psf-bch-api 7.2.1 → 7.2.3

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.
@@ -25,6 +25,7 @@ PORT=5942
25
25
  X402_ENABLED=true
26
26
  SERVER_BCH_ADDRESS=bitcoincash:qqlrzp23w08434twmvr4fxw672whkjy0py26r63g3d
27
27
  FACILITATOR_URL=http://localhost:4345/facilitator
28
+ X402_PRICE_SAT=200
28
29
 
29
30
  # Basic Authentication required to access this API?
30
31
  USE_BASIC_AUTH=true
package/README.md CHANGED
@@ -8,7 +8,7 @@ This is a REST API for communicating with Bitcoin Cash infrastructure. It replac
8
8
 
9
9
  ## x402-bch Payments
10
10
 
11
- All REST endpoints exposed under the `/v6` prefix are protected by the [`x402-bch-express`](https://www.npmjs.com/package/x402-bch-express) middleware. Each API call requires a BCH payment authorization for **2000 satoshis**. The middleware advertises payment requirements via HTTP 402 responses and validates incoming `X-PAYMENT` headers with a configured Facilitator.
11
+ All REST endpoints exposed under the `/v6` prefix are protected by the [`x402-bch-express`](https://www.npmjs.com/package/x402-bch-express) middleware. Each API call requires a BCH payment authorization for **200 satoshis**. The middleware advertises payment requirements via HTTP 402 responses and validates incoming `X-PAYMENT` headers with a configured Facilitator.
12
12
 
13
13
  ### Configuration
14
14
 
@@ -17,7 +17,7 @@ Environment variables control the payment flow:
17
17
  - `X402_ENABLED` — set to `false` (case-insensitive) to disable the middleware. Defaults to enabled.
18
18
  - `SERVER_BCH_ADDRESS` — BCH cash address that receives funding transactions. Defaults to `bitcoincash:qqlrzp23w08434twmvr4fxw672whkjy0py26r63g3d`.
19
19
  - `FACILITATOR_URL` — Root URL of the facilitator service (e.g., `http://localhost:4345/facilitator`).
20
- - `X402_PRICE_SAT` — Optional; override the satoshi price per call (defaults to `2000`).
20
+ - `X402_PRICE_SAT` — Optional; override the satoshi price per call (defaults to `200`).
21
21
 
22
22
  When `X402_ENABLED=false`, the server continues to operate without payment headers for local development or trusted deployments.
23
23
 
package/bin/server.js CHANGED
@@ -83,8 +83,10 @@ class Server {
83
83
 
84
84
  // Apply x402 middleware based on configuration
85
85
  // Logic:
86
- // - If X402_ENABLED=false OR USE_BASIC_AUTH=false: Don't apply x402 (no rate limits)
87
86
  // - If X402_ENABLED=true AND USE_BASIC_AUTH=true: Apply x402 conditionally (bypass if basic auth valid)
87
+ // - If X402_ENABLED=true AND USE_BASIC_AUTH=false: Apply x402 unconditionally (no basic auth bypass)
88
+ // - If X402_ENABLED=false AND USE_BASIC_AUTH=true: Require basic auth only
89
+ // - If X402_ENABLED=false AND USE_BASIC_AUTH=false: No access control
88
90
 
89
91
  // Apply access control middleware based on configuration
90
92
  if (x402Settings.enabled && basicAuthSettings.enabled) {
@@ -112,6 +114,21 @@ class Server {
112
114
  }
113
115
 
114
116
  app.use(conditionalX402Middleware)
117
+ } else if (x402Settings.enabled && !basicAuthSettings.enabled) {
118
+ // X402_ENABLED=true AND USE_BASIC_AUTH=false: Apply x402 unconditionally (no basic auth bypass)
119
+ const routes = buildX402Routes(this.config.apiPrefix)
120
+ const facilitatorOptions = x402Settings.facilitatorUrl
121
+ ? { url: x402Settings.facilitatorUrl }
122
+ : undefined
123
+
124
+ wlogger.info(`x402 middleware enabled (basic auth disabled); enforcing ${x402Settings.priceSat} satoshis per request`)
125
+
126
+ // Apply x402 middleware unconditionally - no basic auth bypass
127
+ app.use(x402PaymentMiddleware(
128
+ x402Settings.serverAddress,
129
+ routes,
130
+ facilitatorOptions
131
+ ))
115
132
  } else if (basicAuthSettings.enabled && !x402Settings.enabled) {
116
133
  // USE_BASIC_AUTH=true AND X402_ENABLED=false: Require basic auth, reject unauthenticated requests
117
134
  wlogger.info('Basic auth enforcement enabled (x402 disabled)')
@@ -144,7 +161,7 @@ class Server {
144
161
 
145
162
  // Endpoint logging middleware
146
163
  app.use((req, res, next) => {
147
- console.log(`Endpoint called: ${req.method} ${req.path}`)
164
+ console.log(`Endpoint called: ${req.method} ${req.path} by ${req.ip}`)
148
165
  res.on('finish', () => {
149
166
  console.log(`Endpoint responded: ${req.method} ${req.path} - ${res.statusCode}`)
150
167
  })
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "psf-bch-api",
3
- "version": "7.2.1",
3
+ "version": "7.2.3",
4
4
  "main": "psf-bch-api.js",
5
5
  "type": "module",
6
6
  "scripts": {
@@ -15,17 +15,17 @@
15
15
  "license": "MIT",
16
16
  "description": "REST API proxy to Bitcoin Cash infrastructure",
17
17
  "dependencies": {
18
- "@psf/bch-js": "7.1.0",
18
+ "@psf/bch-js": "7.1.2",
19
19
  "axios": "1.7.7",
20
20
  "cors": "2.8.5",
21
21
  "dotenv": "16.3.1",
22
22
  "express": "5.1.0",
23
- "minimal-slp-wallet": "7.0.1",
23
+ "minimal-slp-wallet": "7.0.2",
24
24
  "psffpp": "1.2.1",
25
25
  "slp-token-media": "1.2.10",
26
26
  "winston": "3.11.0",
27
27
  "winston-daily-rotate-file": "4.7.1",
28
- "x402-bch-express": "1.1.1"
28
+ "x402-bch-express": "1.1.3"
29
29
  },
30
30
  "devDependencies": {
31
31
  "apidoc": "1.2.0",
@@ -9,10 +9,10 @@ RPC_PASSWORD=password
9
9
  FULCRUM_API=http://172.17.0.1:3001/v1
10
10
 
11
11
  # SLP Indexer
12
- SLP_INDEXER_API=http://localhost:5010
12
+ SLP_INDEXER_API=http://172.17.0.1:5010
13
13
 
14
14
  # REST API URL for wallet operations
15
- LOCAL_RESTURL=http://localhost:5942/v6
15
+ LOCAL_RESTURL=http://172.17.0.1:5942/v6
16
16
 
17
17
  # END INFRASTRUCTURE SETUP
18
18
 
@@ -22,13 +22,16 @@ LOCAL_RESTURL=http://localhost:5942/v6
22
22
  PORT=5942
23
23
 
24
24
  # x402 payments required to access this API?
25
- X402_ENABLED=true
26
- SERVER_BCH_ADDRESS=bitcoincash:qqlrzp23w08434twmvr4fxw672whkjy0py26r63g3d
27
- FACILITATOR_URL=http://localhost:4345/facilitator
25
+ X402_ENABLED=false
26
+ #X402_ENABLED=true
27
+ #SERVER_BCH_ADDRESS=bitcoincash:qqlrzp23w08434twmvr4fxw672whkjy0py26r63g3d
28
+ #FACILITATOR_URL=http://localhost:4345/facilitator
29
+ #X402_PRICE_SAT=200
28
30
 
29
31
  # Basic Authentication required to access this API?
30
- USE_BASIC_AUTH=true
31
- BASIC_AUTH_TOKEN=some-random-token
32
+ USE_BASIC_AUTH=false
33
+ #USE_BASIC_AUTH=true
34
+ #BASIC_AUTH_TOKEN=some-random-token
32
35
 
33
36
  # END ACCESS CONTROL
34
37
 
@@ -51,6 +51,8 @@ RUN git clone https://github.com/Permissionless-Software-Foundation/psf-bch-api
51
51
  # and `stage` has the most up-to-date changes.
52
52
  WORKDIR /home/safeuser/psf-bch-api
53
53
 
54
+ RUN git checkout ct-unstable
55
+
54
56
  # Install dependencies
55
57
  RUN npm install
56
58
  RUN npm install minimal-slp-wallet
@@ -58,7 +60,7 @@ RUN npm install minimal-slp-wallet
58
60
  # Generate the API docs
59
61
  RUN npm run docs
60
62
 
61
- COPY .env-local .env
63
+ COPY .env .env
62
64
 
63
65
 
64
66
  CMD ["npm", "start"]
@@ -26,10 +26,10 @@ const normalizeBoolean = (value, defaultValue) => {
26
26
  return defaultValue
27
27
  }
28
28
 
29
- // By default, the price per API call is 2000 satoshis.
29
+ // By default, the price per API call is 200 satoshis.
30
30
  // But the user can override this value by setting the X402_PRICE_SAT environment variable.
31
31
  const parsedPriceSat = Number(process.env.X402_PRICE_SAT)
32
- const priceSat = Number.isFinite(parsedPriceSat) && parsedPriceSat > 0 ? parsedPriceSat : 2000
32
+ const priceSat = Number.isFinite(parsedPriceSat) && parsedPriceSat > 0 ? parsedPriceSat : 200
33
33
 
34
34
  const x402Defaults = {
35
35
  enabled: normalizeBoolean(process.env.X402_ENABLED, true),
@@ -26,7 +26,7 @@ export function buildX402Routes (apiPrefix = '/v6') {
26
26
  price: config.x402.priceSat,
27
27
  network: NETWORK,
28
28
  config: {
29
- description: `${DEFAULT_DESCRIPTION} (2000 satoshis)`,
29
+ description: `${DEFAULT_DESCRIPTION} (${config.x402.priceSat} satoshis)`,
30
30
  maxTimeoutSeconds: DEFAULT_TIMEOUT_SECONDS
31
31
  }
32
32
  }
@@ -6,7 +6,10 @@ import wlogger from '../adapters/wlogger.js'
6
6
  import BCHJS from '@psf/bch-js'
7
7
  import config from '../config/index.js'
8
8
 
9
- const bchjs = new BCHJS({ restURL: config.restURL })
9
+ const bchjs = new BCHJS({
10
+ restURL: config.restURL,
11
+ bearerToken: config.basicAuth.token
12
+ })
10
13
 
11
14
  class FulcrumUseCases {
12
15
  constructor (localConfig = {}) {
@@ -56,7 +59,7 @@ class FulcrumUseCases {
56
59
  async getTransactionDetails ({ txid }) {
57
60
  try {
58
61
  const response = await this.fulcrum.get(`electrumx/tx/data/${txid}`)
59
- console.log(`getTransactionDetails() TXID ${txid}: ${JSON.stringify(response, null, 2)}`)
62
+ // console.log(`getTransactionDetails() TXID ${txid}: ${JSON.stringify(response, null, 2)}`)
60
63
  return response
61
64
  } catch (err) {
62
65
  wlogger.error('Error in FulcrumUseCases.getTransactionDetails()', err)
@@ -274,7 +274,7 @@ class SlpUseCases {
274
274
  // Get transaction data
275
275
  console.log('Decoding OP_RETURN for TXID: ', txid)
276
276
  const txData = await this.bchjs.Electrumx.txData(txid)
277
- console.log(`TXID ${txid}: ${JSON.stringify(txData, null, 2)}`)
277
+ // console.log(`TXID ${txid}: ${JSON.stringify(txData, null, 2)}`)
278
278
  let data = false
279
279
 
280
280
  // Map the vout of the transaction in search of an OP_RETURN
@@ -1,3 +0,0 @@
1
- #!/bin/bash
2
-
3
- npm start
@@ -1,7 +0,0 @@
1
- // Simple Node.js app that prints 'hello world' every 10 seconds
2
-
3
- setInterval(() => {
4
- console.log('hello world')
5
- }, 10000)
6
-
7
- console.log('Timer started. Printing "hello world" every 10 seconds...')