From 412bf4716db9a8ed78685e13f8e0cf1362b6d996 Mon Sep 17 00:00:00 2001 From: shocknet-justin Date: Fri, 19 Dec 2025 01:58:18 -0500 Subject: [PATCH 1/7] renames --- src/e2e.ts | 8 ++-- src/index.ts | 8 ++-- src/services/lnd/lnd.ts | 8 ++-- src/services/lnd/settings.ts | 4 +- src/services/main/index.ts | 18 ++++----- src/services/main/init.ts | 15 +++----- src/services/main/liquidityProvider.ts | 52 +++++++++++++------------- src/services/main/paymentManager.ts | 6 +-- src/services/main/rugPullTracker.ts | 4 +- src/tests/setupBootstrapped.ts | 14 +++---- 10 files changed, 64 insertions(+), 73 deletions(-) diff --git a/src/e2e.ts b/src/e2e.ts index bb7973af..1589729e 100644 --- a/src/e2e.ts +++ b/src/e2e.ts @@ -21,7 +21,7 @@ const start = async () => { return } - const { mainHandler, liquidityProviderInfo, wizard, adminManager } = keepOn + const { mainHandler, local, wizard, adminManager } = keepOn const serverMethods = GetServerMethods(mainHandler) const nostrSettings = settingsManager.getSettings().nostrRelaySettings log("initializing nostr middleware") @@ -33,8 +33,8 @@ const start = async () => { privateKey: app.privateKey, publicKey: app.publicKey, name: app.name, - provider: app.publicKey === liquidityProviderInfo.publicKey ? { - clientId: liquidityProviderInfo.clientId, + provider: app.publicKey === local.publicKey ? { + clientId: `client_${local.appId}`, pubkey: settingsManager.getSettings().liquiditySettings.liquidityProviderPub, relayUrl: settingsManager.getSettings().liquiditySettings.providerRelayUrl } : undefined @@ -49,7 +49,7 @@ const start = async () => { log("starting server") mainHandler.attachNostrSend(Send) mainHandler.StartBeacons() - const appNprofile = nprofileEncode({ pubkey: liquidityProviderInfo.publicKey, relays: nostrSettings.relays }) + const appNprofile = nprofileEncode({ pubkey: local.publicKey, relays: nostrSettings.relays }) if (wizard) { wizard.AddConnectInfo(appNprofile, nostrSettings.relays) } diff --git a/src/index.ts b/src/index.ts index 4b70ae85..0eacaf06 100644 --- a/src/index.ts +++ b/src/index.ts @@ -23,7 +23,7 @@ const start = async () => { return } - const { mainHandler, liquidityProviderInfo, wizard, adminManager } = keepOn + const { mainHandler, local, wizard, adminManager } = keepOn const serverMethods = GetServerMethods(mainHandler) log("initializing nostr middleware") const relays = settingsManager.getSettings().nostrRelaySettings.relays @@ -34,8 +34,8 @@ const start = async () => { privateKey: app.privateKey, publicKey: app.publicKey, name: app.name, - provider: app.publicKey === liquidityProviderInfo.publicKey ? { - clientId: liquidityProviderInfo.clientId, + provider: app.publicKey === local.publicKey ? { + clientId: `client_${local.appId}`, pubkey: settingsManager.getSettings().liquiditySettings.liquidityProviderPub, relayUrl: settingsManager.getSettings().liquiditySettings.providerRelayUrl } : undefined @@ -53,7 +53,7 @@ const start = async () => { mainHandler.attachNostrProcessPing(Ping) mainHandler.attachNostrReset(Reset) mainHandler.StartBeacons() - const appNprofile = nprofileEncode({ pubkey: liquidityProviderInfo.publicKey, relays }) + const appNprofile = nprofileEncode({ pubkey: local.publicKey, relays }) if (wizard) { wizard.AddConnectInfo(appNprofile, relays) } diff --git a/src/services/lnd/lnd.ts b/src/services/lnd/lnd.ts index 07cd8750..65855b2e 100644 --- a/src/services/lnd/lnd.ts +++ b/src/services/lnd/lnd.ts @@ -372,8 +372,8 @@ export default class { if (mustUseProvider) { console.log("using provider") const invoice = await this.liquidProvider.AddInvoice(value, memo, from, expiry) - const providerDst = this.liquidProvider.GetProviderDestination() - return { payRequest: invoice, providerDst } + const providerPubkey = this.liquidProvider.GetProviderPubkey() + return { payRequest: invoice, providerPubkey } } try { const res = await this.lightning.addInvoice(AddInvoiceReq(value, expiry, true, memo, blind), DeadLineMetadata()) @@ -435,8 +435,8 @@ export default class { const mustUseProvider = this.liquidProvider.getSettings().useOnlyLiquidityProvider || useProvider if (mustUseProvider) { const res = await this.liquidProvider.PayInvoice(invoice, decodedAmount, from, serviceFee) - const providerDst = this.liquidProvider.GetProviderDestination() - return { feeSat: res.service_fee, valueSat: res.amount_paid, paymentPreimage: res.preimage, providerDst } + const providerPubkey = this.liquidProvider.GetProviderPubkey() + return { feeSat: res.service_fee, valueSat: res.amount_paid, paymentPreimage: res.preimage, providerPubkey } } await this.Health() try { diff --git a/src/services/lnd/settings.ts b/src/services/lnd/settings.ts index 43a125a5..842cd57b 100644 --- a/src/services/lnd/settings.ts +++ b/src/services/lnd/settings.ts @@ -35,7 +35,7 @@ export type NodeInfo = { } export type Invoice = { payRequest: string - providerDst?: string + providerPubkey?: string } export type DecodedInvoice = { numSatoshis: number @@ -45,7 +45,7 @@ export type PaidInvoice = { feeSat: number valueSat: number paymentPreimage: string - providerDst?: string + providerPubkey?: string } diff --git a/src/services/main/index.ts b/src/services/main/index.ts index 6185e2e2..fa9be22e 100644 --- a/src/services/main/index.ts +++ b/src/services/main/index.ts @@ -468,15 +468,11 @@ export default class { } const defaultNames = ['wallet', 'wallet-test', this.settings.getSettings().serviceSettings.defaultAppName] - const liquidityProviderApp = apps.find(app => defaultNames.includes(app.name)) - if (!liquidityProviderApp) { - throw new Error("wallet app not initialized correctly") - } - const liquidityProviderInfo = { - privateKey: liquidityProviderApp.nostr_private_key || "", - publicKey: liquidityProviderApp.nostr_public_key || "", - name: "liquidity_provider", clientId: `client_${liquidityProviderApp.app_id}` + const local = apps.find(app => defaultNames.includes(app.name)) + if (!local) { + throw new Error("local app not initialized correctly") } + this.liquidityProvider.setNostrInfo({ localId: `client_${local.app_id}`, localPubkey: local.nostr_public_key || "" }) const relays = this.settings.getSettings().nostrRelaySettings.relays const appsInfo: AppInfo[] = apps.map(app => { return { @@ -484,8 +480,8 @@ export default class { privateKey: app.nostr_private_key || "", publicKey: app.nostr_public_key || "", name: app.name, - provider: app.nostr_public_key === liquidityProviderInfo.publicKey ? { - clientId: liquidityProviderInfo.clientId, + provider: app.nostr_public_key === local.nostr_public_key ? { + clientId: `client_${local.app_id}`, pubkey: this.settings.getSettings().liquiditySettings.liquidityProviderPub, relayUrl: this.settings.getSettings().liquiditySettings.providerRelayUrl } : undefined @@ -495,7 +491,7 @@ export default class { apps: appsInfo, relays, maxEventContentLength: this.settings.getSettings().nostrRelaySettings.maxEventContentLength, - /* clients: [liquidityProviderInfo], + /* clients: [local], providerDestinationPub: this.settings.getSettings().liquiditySettings.liquidityProviderPub */ } this.nostrReset(s) diff --git a/src/services/main/init.ts b/src/services/main/init.ts index 006b8e5d..d3e4c6b0 100644 --- a/src/services/main/init.ts +++ b/src/services/main/init.ts @@ -63,16 +63,11 @@ export const initMainHandler = async (log: PubLogger, settingsManager: SettingsM return { privateKey: app.nostr_private_key, publicKey: app.nostr_public_key, appId: app.app_id, name: app.name } } })) - const liquidityProviderApp = apps.find(app => defaultNames.includes(app.name)) - if (!liquidityProviderApp) { - throw new Error("wallet app not initialized correctly") + const local = apps.find(app => defaultNames.includes(app.name)) + if (!local) { + throw new Error("local app not initialized correctly") } - const liquidityProviderInfo = { - privateKey: liquidityProviderApp.privateKey, - publicKey: liquidityProviderApp.publicKey, - name: "liquidity_provider", clientId: `client_${liquidityProviderApp.appId}` - } - mainHandler.liquidityProvider.setNostrInfo({ clientId: liquidityProviderInfo.clientId, myPub: liquidityProviderInfo.publicKey }) + mainHandler.liquidityProvider.setNostrInfo({ localId: `client_${local.appId}`, localPubkey: local.publicKey }) const stop = await processArgs(mainHandler) if (stop) { return @@ -82,7 +77,7 @@ export const initMainHandler = async (log: PubLogger, settingsManager: SettingsM await mainHandler.appUserManager.CleanupInactiveUsers() await mainHandler.appUserManager.CleanupNeverActiveUsers() await mainHandler.paymentManager.watchDog.Start() - return { mainHandler, apps, liquidityProviderInfo, liquidityProviderApp, wizard, adminManager } + return { mainHandler, apps, local, wizard, adminManager } } const processArgs = async (mainHandler: Main) => { diff --git a/src/services/main/liquidityProvider.ts b/src/services/main/liquidityProvider.ts index ee8917ef..3bf1f0cc 100644 --- a/src/services/main/liquidityProvider.ts +++ b/src/services/main/liquidityProvider.ts @@ -12,12 +12,12 @@ export class LiquidityProvider { getSettings: () => LiquiditySettings client: ReturnType clientCbs: Record> = {} - clientId: string = "" - myPub: string = "" + localId: string = "" + localPubkey: string = "" log = getLogger({ component: 'liquidityProvider' }) // nostrSend: NostrSend | null = null configured = false - pubDestination: string + providerPubkey: string ready: boolean invoicePaidCb: InvoicePaidCb connecting = false @@ -34,9 +34,9 @@ export class LiquidityProvider { constructor(getSettings: () => LiquiditySettings, utils: Utils, invoicePaidCb: InvoicePaidCb, incrementProviderBalance: (balance: number) => Promise) { this.utils = utils this.getSettings = getSettings - const pubDestination = getSettings().liquidityProviderPub + const providerPubkey = getSettings().liquidityProviderPub const disableLiquidityProvider = getSettings().disableLiquidityProvider - if (!pubDestination) { + if (!providerPubkey) { this.log("No pub provider to liquidity provider, will not be initialized") return } @@ -44,16 +44,16 @@ export class LiquidityProvider { this.log("Liquidity provider is disabled, will not be initialized") return } - this.log("connecting to liquidity provider:", pubDestination) - this.pubDestination = pubDestination + this.log("connecting to liquidity provider:", providerPubkey) + this.providerPubkey = providerPubkey this.invoicePaidCb = invoicePaidCb this.incrementProviderBalance = incrementProviderBalance this.client = newNostrClient({ - pubDestination: this.pubDestination, - retrieveNostrUserAuth: async () => this.myPub, - retrieveNostrAdminAuth: async () => this.myPub, - retrieveNostrMetricsAuth: async () => this.myPub, - retrieveNostrGuestWithPubAuth: async () => this.myPub + pubDestination: this.providerPubkey, + retrieveNostrUserAuth: async () => this.localPubkey, + retrieveNostrAdminAuth: async () => this.localPubkey, + retrieveNostrMetricsAuth: async () => this.localPubkey, + retrieveNostrGuestWithPubAuth: async () => this.localPubkey }, this.clientSend, this.clientSub) this.configuredInterval = setInterval(() => { @@ -64,8 +64,8 @@ export class LiquidityProvider { }, 1000) } - GetProviderDestination() { - return this.pubDestination + GetProviderPubkey() { + return this.providerPubkey } IsReady = () => { @@ -74,7 +74,7 @@ export class LiquidityProvider { } AwaitProviderReady = async (): Promise<'inactive' | 'ready'> => { - if (!this.pubDestination || this.getSettings().disableLiquidityProvider) { + if (!this.providerPubkey || this.getSettings().disableLiquidityProvider) { return 'inactive' } if (this.IsReady()) { @@ -283,24 +283,24 @@ export class LiquidityProvider { return res } - setNostrInfo = ({ clientId, myPub }: { myPub: string, clientId: string }) => { + setNostrInfo = ({ localId, localPubkey }: { localPubkey: string, localId: string }) => { this.log("setting nostr info") - this.clientId = clientId - this.myPub = myPub + this.localId = localId + this.localPubkey = localPubkey this.setSetIfConfigured() } setSetIfConfigured = () => { - if (this.utils.nostrSender.IsReady() && !!this.pubDestination && !!this.clientId && !!this.myPub) { + if (this.utils.nostrSender.IsReady() && !!this.providerPubkey && !!this.localId && !!this.localPubkey) { this.configured = true this.log("configured to send to ") } } onBeaconEvent = async (beaconData: { content: string, pub: string }) => { - this.log("received beacon event from", beaconData.pub, "expected", this.pubDestination) - if (beaconData.pub !== this.pubDestination) { - this.log(ERROR, "got beacon from invalid pub", beaconData.pub, this.pubDestination) + this.log("received beacon event from", beaconData.pub, "expected", this.providerPubkey) + if (beaconData.pub !== this.providerPubkey) { + this.log(ERROR, "got beacon from invalid pub", beaconData.pub, this.providerPubkey) return } const beacon = JSON.parse(beaconData.content) as Types.BeaconData @@ -323,8 +323,8 @@ export class LiquidityProvider { } onEvent = async (res: { requestId: string }, fromPub: string) => { - if (fromPub !== this.pubDestination) { - this.log("got event from invalid pub", fromPub, this.pubDestination) + if (fromPub !== this.providerPubkey) { + this.log("got event from invalid pub", fromPub, this.providerPubkey) return false } if (this.clientCbs[res.requestId]) { @@ -351,7 +351,7 @@ export class LiquidityProvider { if (this.clientCbs[reqId]) { throw new Error("request was already sent") } - this.utils.nostrSender.Send({ type: 'client', clientId: this.clientId }, { + this.utils.nostrSender.Send({ type: 'client', clientId: this.localId }, { type: 'content', pub: to, content: JSON.stringify(message) @@ -389,7 +389,7 @@ export class LiquidityProvider { this.log("sub for", reqId, "was already registered, overriding") return } - this.utils.nostrSender.Send({ type: 'client', clientId: this.clientId }, { + this.utils.nostrSender.Send({ type: 'client', clientId: this.localId }, { type: 'content', pub: to, content: JSON.stringify(message) diff --git a/src/services/main/paymentManager.ts b/src/services/main/paymentManager.ts index d2e9c5b3..b4a86766 100644 --- a/src/services/main/paymentManager.ts +++ b/src/services/main/paymentManager.ts @@ -259,7 +259,7 @@ export default class { } const use = await this.liquidityManager.beforeInvoiceCreation(req.amountSats) const res = await this.lnd.NewInvoice(req.amountSats, req.memo, options.expiry, { useProvider: use === 'provider', from: 'user' }, req.blind) - const userInvoice = await this.storage.paymentStorage.AddUserInvoice(user, res.payRequest, options, res.providerDst) + const userInvoice = await this.storage.paymentStorage.AddUserInvoice(user, res.payRequest, options, res.providerPubkey) const appId = options.linkedApplication ? options.linkedApplication.app_id : "" this.storage.eventsLog.LogEvent({ type: 'new_invoice', userId: user.user_id, appUserId: "", appId, balance: user.balance_sats, data: userInvoice.invoice, amount: req.amountSats }) return { @@ -373,7 +373,7 @@ export default class { const totalAmountToDecrement = payAmount + serviceFee const routingFeeLimit = this.getRoutingFeeLimit(payAmount) const use = await this.liquidityManager.beforeOutInvoicePayment(payAmount, serviceFee) - const provider = use === 'provider' ? this.lnd.liquidProvider.GetProviderDestination() : undefined + const provider = use === 'provider' ? this.lnd.liquidProvider.GetProviderPubkey() : undefined const pendingPayment = await this.storage.StartTransaction(async tx => { await this.storage.userStorage.DecrementUserBalance(userId, totalAmountToDecrement, invoice, tx) return await this.storage.paymentStorage.AddPendingExternalPayment(userId, invoice, { payAmount, serviceFee, networkFee: 0 }, linkedApplication, provider, tx, optionals) @@ -386,7 +386,7 @@ export default class { const payment = await this.lnd.PayInvoice(invoice, amountForLnd, { routingFeeLimit, serviceFee }, payAmount, { useProvider: use === 'provider', from: 'user' }, index => { this.storage.paymentStorage.SetExternalPaymentIndex(pendingPayment.serial_id, index) }) - await this.storage.paymentStorage.UpdateExternalPayment(pendingPayment.serial_id, payment.feeSat, serviceFee, true, payment.providerDst) + await this.storage.paymentStorage.UpdateExternalPayment(pendingPayment.serial_id, payment.feeSat, serviceFee, true, payment.providerPubkey) const feeDiff = serviceFee - payment.feeSat if (feeDiff < 0) { // should not happen to lnd beacuse of the fee limit, culd happen to provider if the fee used to calculate the provider fee are out of date this.log("WARNING: network fee was higher than expected,", feeDiff, "were lost by", use === 'provider' ? "provider" : "lnd") diff --git a/src/services/main/rugPullTracker.ts b/src/services/main/rugPullTracker.ts index 8feecb30..87d4f2df 100644 --- a/src/services/main/rugPullTracker.ts +++ b/src/services/main/rugPullTracker.ts @@ -20,7 +20,7 @@ export class RugPullTracker { } CheckProviderBalance = async (): Promise<{ balance: number, prevBalance?: number }> => { - const pubDst = this.liquidProvider.GetProviderDestination() + const pubDst = this.liquidProvider.GetProviderPubkey() if (!pubDst) { return { balance: 0 } } @@ -31,7 +31,7 @@ export class RugPullTracker { const pendingBalance = await this.liquidProvider.GetPendingBalance() const trackedBalance = balance + pendingBalance if (!providerTracker) { - this.log("starting to track provider", this.liquidProvider.GetProviderDestination()) + this.log("starting to track provider", this.liquidProvider.GetProviderPubkey()) await this.storage.liquidityStorage.CreateTrackedProvider('lnPub', pubDst, trackedBalance) return { balance: trackedBalance } } diff --git a/src/tests/setupBootstrapped.ts b/src/tests/setupBootstrapped.ts index f4e12220..92bdb69c 100644 --- a/src/tests/setupBootstrapped.ts +++ b/src/tests/setupBootstrapped.ts @@ -20,13 +20,13 @@ export const initBootstrappedInstance = async (T: TestBase) => { if (!initialized) { throw new Error("failed to initialize bootstrapped main handler") } - const { mainHandler: bootstrapped, liquidityProviderInfo, liquidityProviderApp } = initialized + const { mainHandler: bootstrapped, local } = initialized T.main.attachNostrSend(async (_, data, r) => { if (data.type === 'event') { throw new Error("unsupported event type") } - if (data.pub !== liquidityProviderInfo.publicKey) { - throw new Error("invalid pub " + data.pub + " expected " + liquidityProviderInfo.publicKey) + if (data.pub !== local.publicKey) { + throw new Error("invalid pub " + data.pub + " expected " + local.publicKey) } const j = JSON.parse(data.content) as { requestId: string } console.log("sending new operation to provider") @@ -42,7 +42,7 @@ export const initBootstrappedInstance = async (T: TestBase) => { } bootstrapped.liquidityProvider.onEvent(res, data.pub) }) - bootstrapped.liquidityProvider.setNostrInfo({ clientId: liquidityProviderInfo.clientId, myPub: liquidityProviderInfo.publicKey }) + bootstrapped.liquidityProvider.setNostrInfo({ localId: `client_${local.appId}`, localPubkey: local.publicKey }) await new Promise(res => { const interval = setInterval(async () => { const canHandle = bootstrapped.liquidityProvider.IsReady() @@ -54,10 +54,10 @@ export const initBootstrappedInstance = async (T: TestBase) => { } }, 500) }) - const bUser = await bootstrapped.applicationManager.AddAppUser(liquidityProviderApp.appId, { identifier: "user1_bootstrapped", balance: 0, fail_if_exists: true }) - const bootstrappedUser: TestUserData = { userId: bUser.info.userId, appUserIdentifier: bUser.identifier, appId: liquidityProviderApp.appId } + const bUser = await bootstrapped.applicationManager.AddAppUser(local.appId, { identifier: "user1_bootstrapped", balance: 0, fail_if_exists: true }) + const bootstrappedUser: TestUserData = { userId: bUser.info.userId, appUserIdentifier: bUser.identifier, appId: local.appId } return { - bootstrapped, liquidityProviderInfo, liquidityProviderApp, bootstrappedUser, stop: () => { + bootstrapped, local, bootstrappedUser, stop: () => { bootstrapped.Stop() } } From 5902e6cc72c08746881463f363ef56475c4d810f Mon Sep 17 00:00:00 2001 From: shocknet-justin Date: Fri, 19 Dec 2025 02:02:58 -0500 Subject: [PATCH 2/7] onready --- src/services/main/liquidityProvider.ts | 10 ++++++++++ src/services/nostr/sender.ts | 10 ++++++++++ 2 files changed, 20 insertions(+) diff --git a/src/services/main/liquidityProvider.ts b/src/services/main/liquidityProvider.ts index 3bf1f0cc..baeb812a 100644 --- a/src/services/main/liquidityProvider.ts +++ b/src/services/main/liquidityProvider.ts @@ -56,7 +56,17 @@ export class LiquidityProvider { retrieveNostrGuestWithPubAuth: async () => this.localPubkey }, this.clientSend, this.clientSub) + this.utils.nostrSender.OnReady(() => { + this.setSetIfConfigured() + if (this.configured) { + clearInterval(this.configuredInterval) + this.Connect() + } + }) this.configuredInterval = setInterval(() => { + if (!this.configured && this.utils.nostrSender.IsReady()) { + this.setSetIfConfigured() + } if (this.configured) { clearInterval(this.configuredInterval) this.Connect() diff --git a/src/services/nostr/sender.ts b/src/services/nostr/sender.ts index c3d0c2f2..c061dc56 100644 --- a/src/services/nostr/sender.ts +++ b/src/services/nostr/sender.ts @@ -2,9 +2,19 @@ import { NostrSend, SendData, SendInitiator } from "./nostrPool.js" export class NostrSender { private _nostrSend: NostrSend = () => { throw new Error('nostr send not initialized yet') } private isReady: boolean = false + private onReadyCallbacks: (() => void)[] = [] AttachNostrSend(nostrSend: NostrSend) { this._nostrSend = nostrSend this.isReady = true + this.onReadyCallbacks.forEach(cb => cb()) + this.onReadyCallbacks = [] + } + OnReady(callback: () => void) { + if (this.isReady) { + callback() + } else { + this.onReadyCallbacks.push(callback) + } } Send(initiator: SendInitiator, data: SendData, relays?: string[] | undefined) { if (!this._nostrSend) { From ddafc2db2ad605a5fa5443e56c5ab06587807da0 Mon Sep 17 00:00:00 2001 From: shocknet-justin Date: Fri, 19 Dec 2025 02:06:31 -0500 Subject: [PATCH 3/7] debug --- src/services/main/liquidityProvider.ts | 41 ++++++++++++++++++++++++-- 1 file changed, 38 insertions(+), 3 deletions(-) diff --git a/src/services/main/liquidityProvider.ts b/src/services/main/liquidityProvider.ts index baeb812a..25d045a7 100644 --- a/src/services/main/liquidityProvider.ts +++ b/src/services/main/liquidityProvider.ts @@ -57,10 +57,14 @@ export class LiquidityProvider { }, this.clientSend, this.clientSub) this.utils.nostrSender.OnReady(() => { + this.log("nostrSender is ready, checking if liquidity provider can be configured") this.setSetIfConfigured() if (this.configured) { + this.log("liquidity provider configured, clearing interval and connecting") clearInterval(this.configuredInterval) this.Connect() + } else { + this.log("liquidity provider not yet configured, waiting for nostr info") } }) this.configuredInterval = setInterval(() => { @@ -68,6 +72,7 @@ export class LiquidityProvider { this.setSetIfConfigured() } if (this.configured) { + this.log("liquidity provider configured via interval, clearing interval and connecting") clearInterval(this.configuredInterval) this.Connect() } @@ -132,6 +137,9 @@ export class LiquidityProvider { } GetUserState = async () => { + if (!this.configured || !this.utils.nostrSender.IsReady()) { + throw new Error("liquidity provider not initialized") + } const res = await Promise.race([this.client.GetUserInfo(), new Promise(res => setTimeout(() => res({ status: 'ERROR', reason: 'timeout' }), 10 * 1000))]) if (res.status === 'ERROR') { if (res.reason !== 'timeout') { @@ -211,6 +219,11 @@ export class LiquidityProvider { if (!this.IsReady()) { throw new Error("liquidity provider is not ready yet, disabled or unreachable") } + if (!this.configured || !this.utils.nostrSender.IsReady()) { + const reason = !this.configured ? `configured=false (nostrReady=${this.utils.nostrSender.IsReady()}, hasProviderPub=${!!this.providerPubkey}, hasLocalId=${!!this.localId}, hasLocalPubkey=${!!this.localPubkey})` : 'nostrSender not ready' + this.log(`liquidity provider not initialized: ${reason}`) + throw new Error(`liquidity provider not initialized: ${reason}`) + } const res = await this.client.NewInvoice({ amountSats: amount, memo, expiry }) if (res.status === 'ERROR') { this.log("error creating invoice", res.reason) @@ -230,6 +243,9 @@ export class LiquidityProvider { if (!this.IsReady()) { throw new Error("liquidity provider is not ready yet, disabled or unreachable") } + if (!this.configured || !this.utils.nostrSender.IsReady()) { + throw new Error("liquidity provider not initialized") + } const fees = this.GetFees() const providerServiceFee = this.GetServiceFee(decodedAmount, fees) if (feeLimit && providerServiceFee > feeLimit) { @@ -269,6 +285,9 @@ export class LiquidityProvider { if (!this.IsReady()) { throw new Error("liquidity provider is not ready yet, disabled or unreachable") } + if (!this.configured || !this.utils.nostrSender.IsReady()) { + throw new Error("liquidity provider not initialized") + } const res = await this.client.GetPaymentState({ invoice }) if (res.status === 'ERROR') { this.log("error getting payment state", res.reason) @@ -281,6 +300,9 @@ export class LiquidityProvider { if (!this.IsReady()) { throw new Error("liquidity provider is not ready yet, disabled or unreachable") } + if (!this.configured || !this.utils.nostrSender.IsReady()) { + throw new Error("liquidity provider not initialized") + } const res = await this.client.GetUserOperations({ latestIncomingInvoice: { ts: 0, id: 0 }, latestOutgoingInvoice: { ts: 0, id: 0 }, latestIncomingTx: { ts: 0, id: 0 }, latestOutgoingTx: { ts: 0, id: 0 }, latestIncomingUserToUserPayment: { ts: 0, id: 0 }, @@ -298,13 +320,26 @@ export class LiquidityProvider { this.localId = localId this.localPubkey = localPubkey this.setSetIfConfigured() + // If nostrSender becomes ready after setNostrInfo, ensure we check again + if (!this.configured && this.utils.nostrSender.IsReady()) { + this.setSetIfConfigured() + } } setSetIfConfigured = () => { - if (this.utils.nostrSender.IsReady() && !!this.providerPubkey && !!this.localId && !!this.localPubkey) { - this.configured = true - this.log("configured to send to ") + const nostrReady = this.utils.nostrSender.IsReady() + const hasProviderPub = !!this.providerPubkey + const hasLocalId = !!this.localId + const hasLocalPubkey = !!this.localPubkey + + if (nostrReady && hasProviderPub && hasLocalId && hasLocalPubkey) { + if (!this.configured) { + this.configured = true + this.log("configured to send to provider") + } + } else if (!this.configured) { + this.log(`not configured yet: nostrReady=${nostrReady}, hasProviderPub=${hasProviderPub}, hasLocalId=${hasLocalId}, hasLocalPubkey=${hasLocalPubkey}`) } } onBeaconEvent = async (beaconData: { content: string, pub: string }) => { From 4a7e4660e78653ad1e9cadd51040a4f5c6448b1a Mon Sep 17 00:00:00 2001 From: shocknet-justin Date: Fri, 19 Dec 2025 02:18:44 -0500 Subject: [PATCH 4/7] rm debug logs --- src/services/main/liquidityProvider.ts | 18 +----------------- 1 file changed, 1 insertion(+), 17 deletions(-) diff --git a/src/services/main/liquidityProvider.ts b/src/services/main/liquidityProvider.ts index 25d045a7..08bf3128 100644 --- a/src/services/main/liquidityProvider.ts +++ b/src/services/main/liquidityProvider.ts @@ -57,14 +57,10 @@ export class LiquidityProvider { }, this.clientSend, this.clientSub) this.utils.nostrSender.OnReady(() => { - this.log("nostrSender is ready, checking if liquidity provider can be configured") this.setSetIfConfigured() if (this.configured) { - this.log("liquidity provider configured, clearing interval and connecting") clearInterval(this.configuredInterval) this.Connect() - } else { - this.log("liquidity provider not yet configured, waiting for nostr info") } }) this.configuredInterval = setInterval(() => { @@ -72,7 +68,6 @@ export class LiquidityProvider { this.setSetIfConfigured() } if (this.configured) { - this.log("liquidity provider configured via interval, clearing interval and connecting") clearInterval(this.configuredInterval) this.Connect() } @@ -316,7 +311,6 @@ export class LiquidityProvider { } setNostrInfo = ({ localId, localPubkey }: { localPubkey: string, localId: string }) => { - this.log("setting nostr info") this.localId = localId this.localPubkey = localPubkey this.setSetIfConfigured() @@ -328,22 +322,13 @@ export class LiquidityProvider { setSetIfConfigured = () => { - const nostrReady = this.utils.nostrSender.IsReady() - const hasProviderPub = !!this.providerPubkey - const hasLocalId = !!this.localId - const hasLocalPubkey = !!this.localPubkey - - if (nostrReady && hasProviderPub && hasLocalId && hasLocalPubkey) { + if (this.utils.nostrSender.IsReady() && !!this.providerPubkey && !!this.localId && !!this.localPubkey) { if (!this.configured) { this.configured = true - this.log("configured to send to provider") } - } else if (!this.configured) { - this.log(`not configured yet: nostrReady=${nostrReady}, hasProviderPub=${hasProviderPub}, hasLocalId=${hasLocalId}, hasLocalPubkey=${hasLocalPubkey}`) } } onBeaconEvent = async (beaconData: { content: string, pub: string }) => { - this.log("received beacon event from", beaconData.pub, "expected", this.providerPubkey) if (beaconData.pub !== this.providerPubkey) { this.log(ERROR, "got beacon from invalid pub", beaconData.pub, this.providerPubkey) return @@ -358,7 +343,6 @@ export class LiquidityProvider { this.log(ERROR, "got beacon from invalid type", beacon.type) return } - this.log("valid beacon received, updating ready state") this.lastSeenBeacon = Date.now() this.ready = true if (beacon.fees) { From 0a5f2eea93b713c85979135b8fdc870caf1f0119 Mon Sep 17 00:00:00 2001 From: shocknet-justin Date: Fri, 19 Dec 2025 02:24:00 -0500 Subject: [PATCH 5/7] clean --- src/services/main/liquidityProvider.ts | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/src/services/main/liquidityProvider.ts b/src/services/main/liquidityProvider.ts index 08bf3128..16c49c09 100644 --- a/src/services/main/liquidityProvider.ts +++ b/src/services/main/liquidityProvider.ts @@ -132,7 +132,7 @@ export class LiquidityProvider { } GetUserState = async () => { - if (!this.configured || !this.utils.nostrSender.IsReady()) { + if (!this.configured) { throw new Error("liquidity provider not initialized") } const res = await Promise.race([this.client.GetUserInfo(), new Promise(res => setTimeout(() => res({ status: 'ERROR', reason: 'timeout' }), 10 * 1000))]) @@ -214,10 +214,8 @@ export class LiquidityProvider { if (!this.IsReady()) { throw new Error("liquidity provider is not ready yet, disabled or unreachable") } - if (!this.configured || !this.utils.nostrSender.IsReady()) { - const reason = !this.configured ? `configured=false (nostrReady=${this.utils.nostrSender.IsReady()}, hasProviderPub=${!!this.providerPubkey}, hasLocalId=${!!this.localId}, hasLocalPubkey=${!!this.localPubkey})` : 'nostrSender not ready' - this.log(`liquidity provider not initialized: ${reason}`) - throw new Error(`liquidity provider not initialized: ${reason}`) + if (!this.configured) { + throw new Error("liquidity provider not initialized") } const res = await this.client.NewInvoice({ amountSats: amount, memo, expiry }) if (res.status === 'ERROR') { @@ -238,7 +236,7 @@ export class LiquidityProvider { if (!this.IsReady()) { throw new Error("liquidity provider is not ready yet, disabled or unreachable") } - if (!this.configured || !this.utils.nostrSender.IsReady()) { + if (!this.configured) { throw new Error("liquidity provider not initialized") } const fees = this.GetFees() @@ -370,9 +368,6 @@ export class LiquidityProvider { } clientSend = (to: string, message: NostrRequest): Promise => { - if (!this.configured || !this.utils.nostrSender.IsReady()) { - throw new Error("liquidity provider not initialized") - } if (!message.requestId) { message.requestId = makeId(16) } @@ -399,9 +394,6 @@ export class LiquidityProvider { } clientSub = (to: string, message: NostrRequest, cb: (res: any) => void): void => { - if (!this.configured || !this.utils.nostrSender.IsReady()) { - throw new Error("liquidity provider not initialized") - } if (!message.requestId) { message.requestId = message.rpcName } From 4b6216612f1c6728ba855dcf779ef79811c02ca4 Mon Sep 17 00:00:00 2001 From: shocknet-justin Date: Fri, 19 Dec 2025 02:28:35 -0500 Subject: [PATCH 6/7] clean --- src/services/main/liquidityProvider.ts | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/src/services/main/liquidityProvider.ts b/src/services/main/liquidityProvider.ts index 16c49c09..c3017ef8 100644 --- a/src/services/main/liquidityProvider.ts +++ b/src/services/main/liquidityProvider.ts @@ -132,9 +132,6 @@ export class LiquidityProvider { } GetUserState = async () => { - if (!this.configured) { - throw new Error("liquidity provider not initialized") - } const res = await Promise.race([this.client.GetUserInfo(), new Promise(res => setTimeout(() => res({ status: 'ERROR', reason: 'timeout' }), 10 * 1000))]) if (res.status === 'ERROR') { if (res.reason !== 'timeout') { @@ -214,9 +211,6 @@ export class LiquidityProvider { if (!this.IsReady()) { throw new Error("liquidity provider is not ready yet, disabled or unreachable") } - if (!this.configured) { - throw new Error("liquidity provider not initialized") - } const res = await this.client.NewInvoice({ amountSats: amount, memo, expiry }) if (res.status === 'ERROR') { this.log("error creating invoice", res.reason) @@ -236,9 +230,6 @@ export class LiquidityProvider { if (!this.IsReady()) { throw new Error("liquidity provider is not ready yet, disabled or unreachable") } - if (!this.configured) { - throw new Error("liquidity provider not initialized") - } const fees = this.GetFees() const providerServiceFee = this.GetServiceFee(decodedAmount, fees) if (feeLimit && providerServiceFee > feeLimit) { @@ -278,9 +269,6 @@ export class LiquidityProvider { if (!this.IsReady()) { throw new Error("liquidity provider is not ready yet, disabled or unreachable") } - if (!this.configured || !this.utils.nostrSender.IsReady()) { - throw new Error("liquidity provider not initialized") - } const res = await this.client.GetPaymentState({ invoice }) if (res.status === 'ERROR') { this.log("error getting payment state", res.reason) @@ -293,9 +281,6 @@ export class LiquidityProvider { if (!this.IsReady()) { throw new Error("liquidity provider is not ready yet, disabled or unreachable") } - if (!this.configured || !this.utils.nostrSender.IsReady()) { - throw new Error("liquidity provider not initialized") - } const res = await this.client.GetUserOperations({ latestIncomingInvoice: { ts: 0, id: 0 }, latestOutgoingInvoice: { ts: 0, id: 0 }, latestIncomingTx: { ts: 0, id: 0 }, latestOutgoingTx: { ts: 0, id: 0 }, latestIncomingUserToUserPayment: { ts: 0, id: 0 }, From eca39a035f3eea76b9b36907d5ee887d98e16dd9 Mon Sep 17 00:00:00 2001 From: boufni95 Date: Fri, 19 Dec 2025 15:28:38 +0000 Subject: [PATCH 7/7] local provider client rename --- src/e2e.ts | 8 ++++---- src/index.ts | 8 ++++---- src/services/main/init.ts | 8 ++++---- src/tests/setupBootstrapped.ts | 14 +++++++------- 4 files changed, 19 insertions(+), 19 deletions(-) diff --git a/src/e2e.ts b/src/e2e.ts index 1589729e..bb2cb17d 100644 --- a/src/e2e.ts +++ b/src/e2e.ts @@ -21,7 +21,7 @@ const start = async () => { return } - const { mainHandler, local, wizard, adminManager } = keepOn + const { mainHandler, localProviderClient, wizard, adminManager } = keepOn const serverMethods = GetServerMethods(mainHandler) const nostrSettings = settingsManager.getSettings().nostrRelaySettings log("initializing nostr middleware") @@ -33,8 +33,8 @@ const start = async () => { privateKey: app.privateKey, publicKey: app.publicKey, name: app.name, - provider: app.publicKey === local.publicKey ? { - clientId: `client_${local.appId}`, + provider: app.publicKey === localProviderClient.publicKey ? { + clientId: `client_${localProviderClient.appId}`, pubkey: settingsManager.getSettings().liquiditySettings.liquidityProviderPub, relayUrl: settingsManager.getSettings().liquiditySettings.providerRelayUrl } : undefined @@ -49,7 +49,7 @@ const start = async () => { log("starting server") mainHandler.attachNostrSend(Send) mainHandler.StartBeacons() - const appNprofile = nprofileEncode({ pubkey: local.publicKey, relays: nostrSettings.relays }) + const appNprofile = nprofileEncode({ pubkey: localProviderClient.publicKey, relays: nostrSettings.relays }) if (wizard) { wizard.AddConnectInfo(appNprofile, nostrSettings.relays) } diff --git a/src/index.ts b/src/index.ts index 0eacaf06..fbe6802c 100644 --- a/src/index.ts +++ b/src/index.ts @@ -23,7 +23,7 @@ const start = async () => { return } - const { mainHandler, local, wizard, adminManager } = keepOn + const { mainHandler, localProviderClient, wizard, adminManager } = keepOn const serverMethods = GetServerMethods(mainHandler) log("initializing nostr middleware") const relays = settingsManager.getSettings().nostrRelaySettings.relays @@ -34,8 +34,8 @@ const start = async () => { privateKey: app.privateKey, publicKey: app.publicKey, name: app.name, - provider: app.publicKey === local.publicKey ? { - clientId: `client_${local.appId}`, + provider: app.publicKey === localProviderClient.publicKey ? { + clientId: `client_${localProviderClient.appId}`, pubkey: settingsManager.getSettings().liquiditySettings.liquidityProviderPub, relayUrl: settingsManager.getSettings().liquiditySettings.providerRelayUrl } : undefined @@ -53,7 +53,7 @@ const start = async () => { mainHandler.attachNostrProcessPing(Ping) mainHandler.attachNostrReset(Reset) mainHandler.StartBeacons() - const appNprofile = nprofileEncode({ pubkey: local.publicKey, relays }) + const appNprofile = nprofileEncode({ pubkey: localProviderClient.publicKey, relays }) if (wizard) { wizard.AddConnectInfo(appNprofile, relays) } diff --git a/src/services/main/init.ts b/src/services/main/init.ts index d3e4c6b0..776e989a 100644 --- a/src/services/main/init.ts +++ b/src/services/main/init.ts @@ -63,11 +63,11 @@ export const initMainHandler = async (log: PubLogger, settingsManager: SettingsM return { privateKey: app.nostr_private_key, publicKey: app.nostr_public_key, appId: app.app_id, name: app.name } } })) - const local = apps.find(app => defaultNames.includes(app.name)) - if (!local) { + const localProviderClient = apps.find(app => defaultNames.includes(app.name)) + if (!localProviderClient) { throw new Error("local app not initialized correctly") } - mainHandler.liquidityProvider.setNostrInfo({ localId: `client_${local.appId}`, localPubkey: local.publicKey }) + mainHandler.liquidityProvider.setNostrInfo({ localId: `client_${localProviderClient.appId}`, localPubkey: localProviderClient.publicKey }) const stop = await processArgs(mainHandler) if (stop) { return @@ -77,7 +77,7 @@ export const initMainHandler = async (log: PubLogger, settingsManager: SettingsM await mainHandler.appUserManager.CleanupInactiveUsers() await mainHandler.appUserManager.CleanupNeverActiveUsers() await mainHandler.paymentManager.watchDog.Start() - return { mainHandler, apps, local, wizard, adminManager } + return { mainHandler, apps, localProviderClient, wizard, adminManager } } const processArgs = async (mainHandler: Main) => { diff --git a/src/tests/setupBootstrapped.ts b/src/tests/setupBootstrapped.ts index 92bdb69c..81e2e8bd 100644 --- a/src/tests/setupBootstrapped.ts +++ b/src/tests/setupBootstrapped.ts @@ -20,13 +20,13 @@ export const initBootstrappedInstance = async (T: TestBase) => { if (!initialized) { throw new Error("failed to initialize bootstrapped main handler") } - const { mainHandler: bootstrapped, local } = initialized + const { mainHandler: bootstrapped, localProviderClient } = initialized T.main.attachNostrSend(async (_, data, r) => { if (data.type === 'event') { throw new Error("unsupported event type") } - if (data.pub !== local.publicKey) { - throw new Error("invalid pub " + data.pub + " expected " + local.publicKey) + if (data.pub !== localProviderClient.publicKey) { + throw new Error("invalid pub " + data.pub + " expected " + localProviderClient.publicKey) } const j = JSON.parse(data.content) as { requestId: string } console.log("sending new operation to provider") @@ -42,7 +42,7 @@ export const initBootstrappedInstance = async (T: TestBase) => { } bootstrapped.liquidityProvider.onEvent(res, data.pub) }) - bootstrapped.liquidityProvider.setNostrInfo({ localId: `client_${local.appId}`, localPubkey: local.publicKey }) + bootstrapped.liquidityProvider.setNostrInfo({ localId: `client_${localProviderClient.appId}`, localPubkey: localProviderClient.publicKey }) await new Promise(res => { const interval = setInterval(async () => { const canHandle = bootstrapped.liquidityProvider.IsReady() @@ -54,10 +54,10 @@ export const initBootstrappedInstance = async (T: TestBase) => { } }, 500) }) - const bUser = await bootstrapped.applicationManager.AddAppUser(local.appId, { identifier: "user1_bootstrapped", balance: 0, fail_if_exists: true }) - const bootstrappedUser: TestUserData = { userId: bUser.info.userId, appUserIdentifier: bUser.identifier, appId: local.appId } + const bUser = await bootstrapped.applicationManager.AddAppUser(localProviderClient.appId, { identifier: "user1_bootstrapped", balance: 0, fail_if_exists: true }) + const bootstrappedUser: TestUserData = { userId: bUser.info.userId, appUserIdentifier: bUser.identifier, appId: localProviderClient.appId } return { - bootstrapped, local, bootstrappedUser, stop: () => { + bootstrapped, localProviderClient, bootstrappedUser, stop: () => { bootstrapped.Stop() } }