6 Commits

Author SHA1 Message Date
Michilis
da1d1b0d53 Merge pull request #4 from Michilis/dev
Move terms.txt to public/ to fix Terms page loading
2025-11-10 21:22:50 -03:00
Noderunners
0ab66479d9 Move terms.txt to public/ to fix Terms page loading 2025-11-11 01:21:52 +01:00
Michilis
1129fb9341 Merge pull request #3 from Michilis/dev
fix(lnbits): normalize invoice response (fallback to bolt11) and upda…
2025-11-10 16:51:25 -03:00
Noderunners
4afe3f6d3e fix(lnbits): normalize invoice response (fallback to bolt11) and update payment status check; chore: add .gitignore 2025-11-10 20:47:58 +01:00
Michilis
21bbd0fab1 Merge pull request #2 from Michilis/dev
Fix API calls to use npub instead of identifier
2025-11-06 17:17:48 -03:00
Michilis
bb3b5604a1 Fix API calls to use npub instead of identifier
- Updated getUserInfo to send npub field instead of identifier
- Updated whitelistUser to send npub field instead of identifier
- Resolves 422 Unprocessable Content error from backend API
2025-07-01 19:18:29 +00:00
4 changed files with 109 additions and 23 deletions

64
.gitignore vendored Normal file
View File

@@ -0,0 +1,64 @@
# Dependencies
node_modules/
# Production builds
dist/
dist-ssr/
build/
# Vite and tooling caches
.vite/
.esbuild/
.rollup.cache/
.parcel-cache/
.turbo/
# Logs
logs/
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
lerna-debug.log*
# Environment files
.env
.env.local
.env.*.local
.env.production.local
.env.development.local
.env.test.local
!.env.example
# Coverage
coverage/
# TypeScript build info
*.tsbuildinfo
# Editor directories and files
.vscode/
.idea/
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?
*~
# OS metadata
.DS_Store
Thumbs.db
# Misc secrets/keys (if present)
*.pem
*.key
*.crt
*.p12
*.pfx
# Package tarballs
*.tgz

View File

@@ -45,4 +45,5 @@ We reserve the right to terminate or suspend access to our service immediately,
## 8. Changes to Terms
We reserve the right to modify these terms at any time. We will notify users of any changes by updating the date at the top of this page.
We reserve the right to modify these terms at any time. We will notify users of any changes by updating the date at the top of this page.

View File

@@ -11,7 +11,7 @@ export const apiService = {
'Content-Type': 'application/json',
},
body: JSON.stringify({
identifier: pubkey,
npub: pubkey,
}),
});
@@ -48,7 +48,7 @@ export const apiService = {
'X-Api-Key': apiKey,
},
body: JSON.stringify({
identifier: pubkey,
npub: pubkey,
}),
});

View File

@@ -8,6 +8,7 @@ const api = axios.create({
headers: {
'X-Api-Key': API_KEY,
'Content-Type': 'application/json',
Accept: 'application/json',
},
});
@@ -62,16 +63,26 @@ export const lnbitsService = {
extra = {},
}: CreateInvoiceParams): Promise<Invoice> {
try {
const response = await api.post('/api/v1/payments', {
// Build a V1-safe payload: only include known/supported fields when defined
const payload: Record<string, any> = {
out: false,
amount,
memo,
unit,
webhook,
internal,
extra,
});
return response.data;
};
if (unit) payload.unit = unit;
if (webhook) payload.webhook = webhook;
if (typeof internal === 'boolean') payload.internal = internal;
if (extra && Object.keys(extra).length > 0) payload.extra = extra;
const response = await api.post('/api/v1/payments', payload);
const data = response.data ?? {};
// Normalize response to ensure payment_request is always populated for the UI
const normalized: Invoice = {
...data,
payment_request: data.payment_request || data.bolt11,
bolt11: data.bolt11 || data.payment_request,
};
return normalized;
} catch (error) {
console.error('Error creating invoice:', error);
throw error;
@@ -82,10 +93,13 @@ export const lnbitsService = {
async checkPayment(paymentHash: string): Promise<PaymentStatus> {
try {
const response = await api.get(`/api/v1/payments/${paymentHash}`);
const data = response.data || {};
// Normalize potential V1 shapes
const paid: boolean = (data.paid === true) || (data.status === 'paid') || (data.settled === true);
return {
paid: response.data.paid,
preimage: response.data.preimage,
details: response.data.details,
paid,
preimage: data.preimage,
details: data.details,
};
} catch (error) {
console.error('Error checking payment:', error);
@@ -150,17 +164,24 @@ export const lnbitsService = {
// Long poll payment status
async longPollPayment(paymentHash: string, timeout = 60000): Promise<boolean> {
try {
const response = await api.get(`/public/v1/payment/${paymentHash}`, {
timeout,
});
return response.data.paid;
} catch (error) {
if (axios.isAxiosError(error) && error.code === 'ECONNABORTED') {
return false; // Timeout reached
// Fallback to authenticated polling against V1 status endpoint to ensure compatibility
const start = Date.now();
const pollIntervalMs = 2000;
while (Date.now() - start < timeout) {
try {
const status = await this.checkPayment(paymentHash);
if (status.paid) return true;
} catch (error) {
// If transient error, keep polling until timeout
if (axios.isAxiosError(error) && (error.response?.status ?? 0) >= 500) {
// continue
} else {
console.error('Error polling payment:', error);
throw error;
}
}
console.error('Error polling payment:', error);
throw error;
await new Promise((r) => setTimeout(r, pollIntervalMs));
}
return false;
},
};