1 Commits

Author SHA1 Message Date
Michilis
947799e8c8 test 2025-02-19 23:14:48 +01:00
6 changed files with 50 additions and 113 deletions

64
.gitignore vendored
View File

@@ -1,64 +0,0 @@
# 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

@@ -1,14 +1,12 @@
# Noderunners Relay # Noderunners Relay
A high-performance Nostr relay built by Bitcoiners, for Bitcoiners. This project provides a web interface for managing access to the Noderunners relay service. A high-performance Nostr relay built by Bitcoiners, for Bitcoiners. This project provides a web interface for managing access to the Noderunners relay service.
```
wss://relay.noderunners.network
```
![Noderunners Relay](https://cdn.azzamo.net/5cc03420a18166ef7a20b1e6b7dad240ad7d634824649643c80d74a924062258.png) ![Noderunners Relay](https://cdn.azzamo.net/5cc03420a18166ef7a20b1e6b7dad240ad7d634824649643c80d74a924062258.png)
## Features ## Features
- 🚀 Lightning-fast relay performance with strfry v1.0.3
- ⚡ Lightning Network integration for payments - ⚡ Lightning Network integration for payments
- 🔒 Secure authentication with Nostr - 🔒 Secure authentication with Nostr
- 💻 Modern, responsive web interface - 💻 Modern, responsive web interface
@@ -118,6 +116,20 @@ You can combine iframe mode with URL-based authentication:
<iframe src="https://your-relay-domain.com?iframe=1&npub=npub1..." width="100%" height="600px"></iframe> <iframe src="https://your-relay-domain.com?iframe=1&npub=npub1..." width="100%" height="600px"></iframe>
``` ```
## Supported NIPs
The relay supports the following Nostr Implementation Possibilities (NIPs):
- NIP-01: Basic protocol flow description
- NIP-02: Contact List and Petnames
- NIP-04: Encrypted Direct Messages
- NIP-09: Event Deletion
- NIP-11: Relay Information Document
- NIP-22: Event `created_at` Limits
- NIP-28: Public Chat
- NIP-40: Expiration Timestamp
- NIP-70: Relay Payment Info
- NIP-77: Lightning Network Relay Payment
## API Services ## API Services
### LNbits Integration ### LNbits Integration
@@ -144,6 +156,10 @@ You can combine iframe mode with URL-based authentication:
This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details. This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
## Support
For support, join our [Telegram group](https://t.me/noderunners) or visit [our website](https://noderunners.network).
## Acknowledgments ## Acknowledgments
- Built by the Noderunners community - Built by the Noderunners community

View File

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

View File

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

View File

@@ -46,4 +46,3 @@ We reserve the right to terminate or suspend access to our service immediately,
## 8. Changes to Terms ## 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.

7
test.txt Normal file
View File

@@ -0,0 +1,7 @@
Dit is een test update met git
Update 2