Skip to content

Commit

Permalink
split ln address settings into global and pubkey specific
Browse files Browse the repository at this point in the history
  • Loading branch information
myxmaster committed Jan 18, 2025
1 parent 1dc7012 commit d33cad6
Show file tree
Hide file tree
Showing 16 changed files with 816 additions and 295 deletions.
2 changes: 1 addition & 1 deletion PushNotificationManager.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ export default class PushNotificationManager extends React.Component<any, any> {
console.log('Notification Received - Foreground', notification);
// Don't display redeem notification if auto-redeem is on
if (
stores.settingsStore.settings?.lightningAddress
stores.settingsStore.settings?.lightningAddressGlobal
?.automaticallyAccept &&
JSON.stringify(notification.payload).includes(
'Redeem within the next 24 hours'
Expand Down
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
"<rootDir>/node_modules"
],
"transformIgnorePatterns": [
"node_modules/(?!(react-native|@react-native|react-native-blob-util|react-native-randombytes|dateformat)/)"
"node_modules/(?!(react-native|@react-native|react-native-blob-util|react-native-randombytes|dateformat|uuid)/)"
],
"testPathIgnorePatterns": [
"check-styles.test.ts"
Expand Down Expand Up @@ -140,6 +140,7 @@
"tty-browserify": "0.0.0",
"url": "0.10.3",
"util": "0.10.4",
"uuid": "9.0.1",
"vm-browserify": "0.0.4"
},
"devDependencies": {
Expand Down
177 changes: 124 additions & 53 deletions stores/LightningAddressStore.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Platform } from 'react-native';
import { action, observable } from 'mobx';
import ReactNativeBlobUtil from 'react-native-blob-util';
import ReactNativeBlobUtil, { FetchBlobResponse } from 'react-native-blob-util';
import { Notifications } from 'react-native-notifications';

import BigNumber from 'bignumber.js';
Expand Down Expand Up @@ -30,12 +30,12 @@ const LNURL_HOST = 'https://zeuspay.com/api';
const LNURL_SOCKET_HOST = 'https://zeuspay.com';
const LNURL_SOCKET_PATH = '/stream';

export const LEGACY_ADDRESS_ACTIVATED_STRING = 'olympus-lightning-address';
export const LEGACY_HASHES_STORAGE_STRING = 'olympus-lightning-address-hashes';

export const ADDRESS_ACTIVATED_STRING = 'zeuspay-lightning-address';
export const HASHES_STORAGE_STRING = 'zeuspay-lightning-address-hashes';

export type LightningAddressServiceStatus = true | false | 'unknown';

export default class LightningAddressStore {
@observable public lightningAddress: string;
@observable public lightningAddressHandle: string;
Expand Down Expand Up @@ -95,24 +95,7 @@ export default class LightningAddressStore {
return this.preimageMap;
};

@action
public getLightningAddressActivated = async () => {
this.loading = true;
const lightningAddressActivated = await Storage.getItem(
ADDRESS_ACTIVATED_STRING
);

if (lightningAddressActivated) {
this.lightningAddressActivated = Boolean(lightningAddressActivated);
this.loading = false;
return this.lightningAddressActivated;
} else {
this.loading = false;
}
};

setLightningAddress = async (handle: string, domain: string) => {
await Storage.setItem(ADDRESS_ACTIVATED_STRING, true);
this.lightningAddressActivated = true;
this.lightningAddressHandle = handle;
this.lightningAddressDomain = domain;
Expand Down Expand Up @@ -149,7 +132,9 @@ export default class LightningAddressStore {
const nostrSignatures: any = [];
if (preimages) {
const nostrPrivateKey =
this.settingsStore?.settings?.lightningAddress?.nostrPrivateKey;
this.settingsStore.settings.lightningAddressByPubkey?.[
this.nodeInfoStore.nodeInfo.identity_pubkey
]?.nostrPrivateKey;
for (let i = 0; i < preimages.length; i++) {
const preimage = preimages[i];
const hash = sha256
Expand Down Expand Up @@ -340,37 +325,39 @@ export default class LightningAddressStore {
.then(async (response: any) => {
const data = response.json();
const status = response.info().status;
const {
handle,
domain,
created_at,
success
} = data;
const { handle, created_at, success } =
data;

if (status === 200 && success) {
if (handle) {
this.setLightningAddress(
handle,
domain
await this.settingsStore.updateSettings(
{
lightningAddressGlobal:
{
automaticallyAccept:
true,
allowComments:
true,
nostrRelays:
relays,
notifications: 1
},
lightningAddressByPubkey:
{
[this
.nodeInfoStore
.nodeInfo
.identity_pubkey]:
{
enabled:
true,
nostrPrivateKey
}
}
}
);
}

await this.settingsStore.updateSettings(
{
lightningAddress: {
enabled: true,
automaticallyAccept:
true,
automaticallyRequestOlympusChannels:
false, // deprecated
allowComments: true,
nostrPrivateKey,
nostrRelays: relays,
notifications: 1
}
}
);

// ensure push credentials are in place
// right after creation
this.updatePushCredentials();
Expand Down Expand Up @@ -595,6 +582,38 @@ export default class LightningAddressStore {
domain;
if (handle && domain) {
this.lightningAddress = `${handle}@${domain}`;

// If backend could not be reached earlier, we set "enabled: true" now
if (
this.settingsStore.settings
.lightningAddressByPubkey?.[
this.nodeInfoStore
.nodeInfo
.identity_pubkey
].enabled === false
) {
await this.settingsStore.updateSettings(
{
lightningAddressByPubkey:
{
...this
.settingsStore
.settings
.lightningAddressByPubkey,
[this
.nodeInfoStore
.nodeInfo
.identity_pubkey]:
{
enabled:
true,
nostrPrivateKey:
''
}
}
}
);
}
}

if (
Expand Down Expand Up @@ -761,7 +780,7 @@ export default class LightningAddressStore {
const hashpk = getPublicKey(hash);

await Promise.all(
this.settingsStore.settings.lightningAddress.nostrRelays.map(
this.settingsStore.settings.lightningAddressGlobal.nostrRelays.map(
async (relayItem) => {
const relay = relayInit(relayItem);
relay.on('connect', () => {
Expand Down Expand Up @@ -978,7 +997,7 @@ export default class LightningAddressStore {
memo: comment ? `ZEUS Pay: ${comment}` : 'ZEUS Pay',
preimage,
private:
this.settingsStore?.settings?.lightningAddress
this.settingsStore?.settings?.lightningAddressGlobal
?.routeHints || false
})
.then((result: any) => {
Expand Down Expand Up @@ -1032,9 +1051,9 @@ export default class LightningAddressStore {
@action
public redeemAllOpenPayments = async () => {
this.redeemingAll = true;
const attestationLevel = this.settingsStore?.settings?.lightningAddress
?.automaticallyAcceptAttestationLevel
? this.settingsStore.settings.lightningAddress
const attestationLevel = this.settingsStore?.settings
?.lightningAddressGlobal?.automaticallyAcceptAttestationLevel
? this.settingsStore.settings.lightningAddressGlobal
.automaticallyAcceptAttestationLevel
: 2;

Expand Down Expand Up @@ -1107,9 +1126,9 @@ export default class LightningAddressStore {
const { hash, amount_msat, comment } = data;

const attestationLevel = this.settingsStore?.settings
?.lightningAddress
?.lightningAddressGlobal
?.automaticallyAcceptAttestationLevel
? this.settingsStore.settings.lightningAddress
? this.settingsStore.settings.lightningAddressGlobal
.automaticallyAcceptAttestationLevel
: 2;

Expand Down Expand Up @@ -1164,6 +1183,58 @@ export default class LightningAddressStore {
}
};

public checkLightningAddressExists =
async (): Promise<LightningAddressServiceStatus> => {
const timeout = (ms: number) =>
new Promise((_, reject) =>
setTimeout(() => reject(new Error('Request timed out')), ms)
);

try {
const authResponse = (await Promise.race([
ReactNativeBlobUtil.fetch(
'POST',
`${LNURL_HOST}/lnurl/auth`,
{ 'Content-Type': 'application/json' },
JSON.stringify({
pubkey: this.nodeInfoStore.nodeInfo.identity_pubkey
})
),
timeout(10000) // 10 seconds should be enough
])) as FetchBlobResponse;

const authData = authResponse.json();
if (authResponse.info().status !== 200) return 'unknown';

const { verification } = authData;
const data = await BackendUtils.signMessage(verification);
const signature = data.zbase || data.signature;

const statusResponse = (await Promise.race([
ReactNativeBlobUtil.fetch(
'POST',
`${LNURL_HOST}/lnurl/status`,
{ 'Content-Type': 'application/json' },
JSON.stringify({
pubkey: this.nodeInfoStore.nodeInfo.identity_pubkey,
message: verification,
signature
})
),
timeout(10000) // 10 seconds should be enough
])) as FetchBlobResponse;

const statusData = statusResponse.json();
if (statusResponse.info().status !== 200) return 'unknown';

const { handle, domain } = statusData;
return Boolean(handle && domain);
} catch (error) {
console.error('Lightning Address check failed:', error);
return 'unknown';
}
};

@action
public reset = () => {
this.loading = false;
Expand Down
Loading

0 comments on commit d33cad6

Please sign in to comment.