Compare commits
11 commits
b519c0e447
...
a2366c40f2
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a2366c40f2 | ||
|
|
cf85a2fd7c | ||
|
|
c308d4be78 | ||
|
|
f1aa5d7139 | ||
|
|
9981e2628e | ||
|
|
ece75df22d | ||
|
|
c909cd660a | ||
|
|
5b88982fed | ||
|
|
4d19b55c57 | ||
|
|
071a27ad2d | ||
|
|
fee87e2741 |
7 changed files with 1122 additions and 1865 deletions
|
|
@ -2,3 +2,21 @@
|
||||||
.github
|
.github
|
||||||
build
|
build
|
||||||
node_modules
|
node_modules
|
||||||
|
|
||||||
|
# Runtime state files (should not be baked into image)
|
||||||
|
*.sqlite
|
||||||
|
*.sqlite-journal
|
||||||
|
*.sqlite-wal
|
||||||
|
*.sqlite-shm
|
||||||
|
*.db
|
||||||
|
admin.connect
|
||||||
|
admin.enroll
|
||||||
|
admin.npub
|
||||||
|
app.nprofile
|
||||||
|
.jwt_secret
|
||||||
|
|
||||||
|
# Runtime data directories
|
||||||
|
metric_cache/
|
||||||
|
metric_events/
|
||||||
|
bundler_events/
|
||||||
|
logs/
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
FROM node:18
|
FROM node:20
|
||||||
|
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
|
|
||||||
|
|
|
||||||
2926
package-lock.json
generated
2926
package-lock.json
generated
File diff suppressed because it is too large
Load diff
|
|
@ -77,6 +77,7 @@
|
||||||
"zip-a-folder": "^3.1.9"
|
"zip-a-folder": "^3.1.9"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
"@types/better-sqlite3": "^7.6.13",
|
||||||
"@types/chai": "^4.3.4",
|
"@types/chai": "^4.3.4",
|
||||||
"@types/chai-string": "^1.4.5",
|
"@types/chai-string": "^1.4.5",
|
||||||
"@types/cors": "^2.8.17",
|
"@types/cors": "^2.8.17",
|
||||||
|
|
|
||||||
|
|
@ -241,6 +241,8 @@ export default class {
|
||||||
const paid = await this.paymentManager.PayInvoice(appUser.user.user_id, req, app, {
|
const paid = await this.paymentManager.PayInvoice(appUser.user.user_id, req, app, {
|
||||||
ack: pendingOp => { this.notifyAppUserPayment(appUser, pendingOp) }
|
ack: pendingOp => { this.notifyAppUserPayment(appUser, pendingOp) }
|
||||||
})
|
})
|
||||||
|
// Refresh appUser balance from DB so notification has accurate latest_balance
|
||||||
|
appUser.user.balance_sats = paid.latest_balance
|
||||||
this.notifyAppUserPayment(appUser, paid.operation)
|
this.notifyAppUserPayment(appUser, paid.operation)
|
||||||
getLogger({ appName: app.name })(appUser.identifier, "invoice paid", paid.amount_paid, "sats")
|
getLogger({ appName: app.name })(appUser.identifier, "invoice paid", paid.amount_paid, "sats")
|
||||||
return paid
|
return paid
|
||||||
|
|
|
||||||
|
|
@ -1,14 +1,14 @@
|
||||||
import { base64 } from "@scure/base";
|
import { base64, hex } from "@scure/base";
|
||||||
import { randomBytes } from "@noble/hashes/utils";
|
import { randomBytes } from "@noble/hashes/utils";
|
||||||
import { streamXOR as xchacha20 } from "@stablelib/xchacha20";
|
import { streamXOR as xchacha20 } from "@stablelib/xchacha20";
|
||||||
import { secp256k1 } from "@noble/curves/secp256k1";
|
import { secp256k1 } from "@noble/curves/secp256k1.js";
|
||||||
import { sha256 } from "@noble/hashes/sha256";
|
import { sha256 } from "@noble/hashes/sha256";
|
||||||
export type EncryptedData = {
|
export type EncryptedData = {
|
||||||
ciphertext: Uint8Array;
|
ciphertext: Uint8Array;
|
||||||
nonce: Uint8Array;
|
nonce: Uint8Array;
|
||||||
}
|
}
|
||||||
export const getSharedSecret = (privateKey: string, publicKey: string) => {
|
export const getSharedSecret = (privateKey: string, publicKey: string) => {
|
||||||
const key = secp256k1.getSharedSecret(privateKey, "02" + publicKey);
|
const key = secp256k1.getSharedSecret(hex.decode(privateKey), hex.decode("02" + publicKey));
|
||||||
return sha256(key.slice(1, 33));
|
return sha256(key.slice(1, 33));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -205,20 +205,24 @@ export class NostrPool {
|
||||||
const log = getLogger({ appName: keys.name })
|
const log = getLogger({ appName: keys.name })
|
||||||
this.log(`📤 Publishing Kind ${event.kind} event to ${relays.length} relay(s): ${relays.join(', ')}`)
|
this.log(`📤 Publishing Kind ${event.kind} event to ${relays.length} relay(s): ${relays.join(', ')}`)
|
||||||
const pool = new SimplePool()
|
const pool = new SimplePool()
|
||||||
await Promise.all(pool.publish(relays, signed).map(async p => {
|
try {
|
||||||
try {
|
await Promise.all(pool.publish(relays, signed).map(async p => {
|
||||||
await p
|
try {
|
||||||
sent = true
|
await p
|
||||||
} catch (e: any) {
|
sent = true
|
||||||
this.log(ERROR, `Failed to publish Kind ${event.kind} event:`, e.message || e)
|
} catch (e: any) {
|
||||||
log(e)
|
this.log(ERROR, `Failed to publish Kind ${event.kind} event:`, e.message || e)
|
||||||
|
log(e)
|
||||||
|
}
|
||||||
|
}))
|
||||||
|
if (!sent) {
|
||||||
|
this.log(ERROR, `Failed to send Kind ${event.kind} event to any relay`)
|
||||||
|
log("failed to send event")
|
||||||
|
} else {
|
||||||
|
this.log(`✅ Kind ${event.kind} event published successfully (id: ${signed.id.slice(0, 16)}...)`)
|
||||||
}
|
}
|
||||||
}))
|
} finally {
|
||||||
if (!sent) {
|
pool.close(relays)
|
||||||
this.log(ERROR, `Failed to send Kind ${event.kind} event to any relay`)
|
|
||||||
log("failed to send event")
|
|
||||||
} else {
|
|
||||||
this.log(`✅ Kind ${event.kind} event published successfully (id: ${signed.id.slice(0, 16)}...)`)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue