Include Java nostr

This commit is contained in:
KoalaSat 2023-04-03 18:56:22 +02:00
parent 55995232ae
commit 8b28b9dae0
No known key found for this signature in database
GPG Key ID: 2F7F61C6146AB157
15 changed files with 60 additions and 33 deletions

View File

@ -21,7 +21,7 @@ jobs:
- uses: actions/setup-java@v3 - uses: actions/setup-java@v3
with: with:
distribution: temurin distribution: temurin
java-version: 11 java-version: 19
- name: Setup Gradle - name: Setup Gradle
uses: gradle/gradle-build-action@v2 uses: gradle/gradle-build-action@v2

View File

@ -165,6 +165,8 @@ dependencies {
implementation 'com.facebook.fresco:animated-webp:2.6.0' implementation 'com.facebook.fresco:animated-webp:2.6.0'
implementation 'com.facebook.fresco:webpsupport:2.6.0' implementation 'com.facebook.fresco:webpsupport:2.6.0'
implementation 'com.github.KoalaSat.nostr-java:nostr-base:70e62e24ad'
implementation 'com.github.KoalaSat.nostr-java:nostr-event:70e62e24ad'
implementation 'com.facebook.fresco:animated-gif:2.6.0' implementation 'com.facebook.fresco:animated-gif:2.6.0'

View File

@ -21,6 +21,11 @@ import java.util.UUID;
import java.util.regex.Matcher; import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import nostr.crypto.schnorr.Schnorr;
import nostr.crypto.bech32.Bech32;
import nostr.util.NostrException;
import nostr.util.NostrUtil;
public class Event { public class Event {
private final int created_at; private final int created_at;
private final String content; private final String content;
@ -87,7 +92,13 @@ public class Event {
} }
protected boolean isValid() { protected boolean isValid() {
return !id.isEmpty() && !sig.isEmpty() && created_at <= System.currentTimeMillis() / 1000L; boolean verified = false;
try {
verified = Schnorr.verify(NostrUtil.hexToBytes(id), NostrUtil.hexToBytes(pubkey), NostrUtil.hexToBytes(sig));
} catch (Exception e) {
e.printStackTrace();
}
return verified && created_at <= System.currentTimeMillis() / 1000L;
} }
protected String getMainEventId() { protected String getMainEventId() {
@ -143,9 +154,9 @@ public class Event {
protected String getRepostId() { protected String getRepostId() {
String match = null; String match = null;
Matcher m = Pattern.compile("#\\[(\\d+)\\]").matcher(content); Matcher matcherTag = Pattern.compile("#\\[(\\d+)\\]").matcher(content);
while (m.find()) { if (matcherTag.find()) {
int position = Integer.parseInt(m.group(1)); int position = Integer.parseInt(matcherTag.group(1));
try { try {
JSONArray tag = tags.getJSONArray(position); JSONArray tag = tags.getJSONArray(position);
String tagKind = tag.getString(0); String tagKind = tag.getString(0);
@ -156,6 +167,15 @@ public class Event {
e.printStackTrace(); e.printStackTrace();
} }
} }
Matcher matcherBech = Pattern.compile("nostr:((nevent1|note1)\\S+)").matcher(content);
if (matcherBech.find()) {
String bech32 = matcherBech.group(1);
try {
match = Bech32.fromBech32(bech32);
} catch (NostrException e) {
e.printStackTrace();
}
}
return match; return match;
} }

View File

@ -1,5 +1,11 @@
// Top-level build file where you can add configuration options common to all sub-projects/modules. // Top-level build file where you can add configuration options common to all sub-projects/modules.
allprojects {
repositories {
maven { url 'https://jitpack.io' }
}
}
buildscript { buildscript {
ext { ext {
buildToolsVersion = "33.0.0" buildToolsVersion = "33.0.0"

View File

@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.5.1-all.zip distributionUrl=https\://services.gradle.org/distributions/gradle-7.6.1-all.zip
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists zipStorePath=wrapper/dists

View File

@ -45,7 +45,7 @@ export const MenuItems: React.FC = () => {
React.useEffect(() => { React.useEffect(() => {
setActiveRelays(relays.filter((relay) => relay.active).length) setActiveRelays(relays.filter((relay) => relay.active).length)
}, [relays]) }, [relays, balance])
const onPressLogout: () => void = () => { const onPressLogout: () => void = () => {
logout() logout()
@ -154,7 +154,7 @@ export const MenuItems: React.FC = () => {
onPress={() => onPressItem('wallet', 1)} onPress={() => onPressItem('wallet', 1)}
onTouchEnd={() => setDrawerItemIndex(-1)} onTouchEnd={() => setDrawerItemIndex(-1)}
right={() => { right={() => {
if (!type || !balance) return <></> if (!type || balance === undefined) return <></>
return ( return (
<Text> <Text>
{`${balance} `} {`${balance} `}

View File

@ -78,6 +78,7 @@ export const LinksPreview: React.FC<TextContentProps> = ({ urls, lnUrl }) => {
rowPosition: 'top' | 'bottom', rowPosition: 'top' | 'bottom',
) => JSX.Element = (link, index, rowPosition) => ( ) => JSX.Element = (link, index, rowPosition) => (
<TouchableWithoutFeedback <TouchableWithoutFeedback
key={link}
onPress={() => onPress={() =>
navigate('ImageGallery', { navigate('ImageGallery', {
urls: imageLinks, urls: imageLinks,
@ -86,7 +87,6 @@ export const LinksPreview: React.FC<TextContentProps> = ({ urls, lnUrl }) => {
} }
> >
<FastImage <FastImage
key={link}
style={[ style={[
styles.cardCover, styles.cardCover,
{ {

View File

@ -131,6 +131,7 @@ export const WalletContextProvider = ({ children }: WalletContextProviderProps):
const logoutWallet: () => void = () => { const logoutWallet: () => void = () => {
SInfo.deleteItem('lndHub', {}) SInfo.deleteItem('lndHub', {})
SInfo.deleteItem('lnBits', {})
setType(undefined) setType(undefined)
setConfig(undefined) setConfig(undefined)
setBalance(undefined) setBalance(undefined)

View File

@ -75,7 +75,7 @@ export const ConversationPage: React.FC<ConversationPageProps> = ({ route }) =>
return () => return () =>
relayPool?.unsubscribe([ relayPool?.unsubscribe([
`conversation${route.params.pubKey}`, `conversation${route.params.pubKey.substring(0, 8)}`,
`conversation-replies${route.params.pubKey.substring(0, 8)}`, `conversation-replies${route.params.pubKey.substring(0, 8)}`,
]) ])
}, []), }, []),
@ -272,7 +272,7 @@ export const ConversationPage: React.FC<ConversationPageProps> = ({ route }) =>
if (!publicKey || !privateKey || !otherUser) return <></> if (!publicKey || !privateKey || !otherUser) return <></>
const eTags = getETags(item) const eTags = getETags(item)
const showAvatar = directMessages[index - 1]?.pubkey !== item.pubkey const showAvatar = index < 1 || directMessages[index - 1]?.pubkey !== item.pubkey
const isReply = eTags.length > 0 const isReply = eTags.length > 0
const repliedMessageId = eTags.length > 0 ? eTags[eTags.length - 1][1] : undefined const repliedMessageId = eTags.length > 0 ? eTags[eTags.length - 1][1] : undefined
const repliedMessage = directMessages.find((message) => message.id === repliedMessageId) const repliedMessage = directMessages.find((message) => message.id === repliedMessageId)

View File

@ -92,7 +92,7 @@ export const MyFeed: React.FC<MyFeedProps> = ({
const message: RelayFilters = { const message: RelayFilters = {
kinds: [Kind.Text, Kind.RecommendRelay], kinds: [Kind.Text, Kind.RecommendRelay],
authors: contacts authors: contacts,
} }
if (results.length >= pageSize) { if (results.length >= pageSize) {
message.since = results[pageSize - 1].created_at message.since = results[pageSize - 1].created_at

View File

@ -119,16 +119,16 @@ export const NotificationsFeed: React.FC = () => {
{ {
kinds: [Kind.Text], kinds: [Kind.Text],
'#p': [publicKey], '#p': [publicKey],
since: limitDate since: limitDate,
}, },
{ {
kinds: [Kind.Text], kinds: [Kind.Text],
'#e': [publicKey], '#e': [publicKey],
since: limitDate since: limitDate,
}, },
{ {
kinds: [30001], kinds: [30001],
authors: [publicKey] authors: [publicKey],
}, },
]) ])
} }

View File

@ -37,9 +37,9 @@ export const NotePage: React.FC<NotePageProps> = ({ route }) => {
return () => return () =>
relayPool?.unsubscribe([ relayPool?.unsubscribe([
`meta-notepage${route.params.noteId}`, `meta-notepage${route.params.noteId.substring(0, 8)}`,
`notepage${route.params.noteId}`, `notepage${route.params.noteId.substring(0, 8)}`,
`notepage-replies-${route.params.noteId}`, `notepage-replies-${route.params.noteId.substring(0, 8)}`,
]) ])
}, []), }, []),
) )

View File

@ -44,7 +44,7 @@ export const NotesFeed: React.FC<NotesFeedProps> = ({
}, [pageSize, lastEventId, activeTab]) }, [pageSize, lastEventId, activeTab])
const subscribe: () => Promise<void> = async () => { const subscribe: () => Promise<void> = async () => {
relayPool?.subscribe(`profile-user${publicKey}`, [ relayPool?.subscribe(`profile-user${publicKey.substring(0, 8)}`, [
{ {
kinds: [Kind.Text, Kind.RecommendRelay], kinds: [Kind.Text, Kind.RecommendRelay],
authors: [publicKey], authors: [publicKey],

View File

@ -56,8 +56,7 @@ export const WalletPage: React.FC = () => {
if (database && publicKey) { if (database && publicKey) {
const preimages: string[] = actions.filter((item) => item.id !== '').map((item) => item.id) const preimages: string[] = actions.filter((item) => item.id !== '').map((item) => item.id)
getZaps(database, { preimages }).then( getZaps(database, { preimages }).then((results) => {
(results) => {
if (results) { if (results) {
const map: Record<string, Zap> = {} const map: Record<string, Zap> = {}
results.forEach((zap) => { results.forEach((zap) => {
@ -66,8 +65,7 @@ export const WalletPage: React.FC = () => {
}) })
setZaps(map) setZaps(map)
} }
}, })
)
relayPool?.subscribe(`profile-zaps${publicKey.substring(0, 8)}`, [ relayPool?.subscribe(`profile-zaps${publicKey.substring(0, 8)}`, [
{ {
kinds: [9735], kinds: [9735],

View File

@ -53,7 +53,7 @@ class LndHub {
private readonly getTransactions: () => Promise<WalletAction[] | undefined> = async () => { private readonly getTransactions: () => Promise<WalletAction[] | undefined> = async () => {
if (!this.config) return if (!this.config) return
const response = await axios.get(`${this.config.url}/gettxs`, { headers: this.getHeaders() }) const response = await axios.get(`${this.config.url}/gettxs`, { headers: this.getHeaders() })
if (response) { if (response?.data) {
return response.data.map((item: any) => { return response.data.map((item: any) => {
return { return {
id: item.payment_preimage, id: item.payment_preimage,
@ -71,7 +71,7 @@ class LndHub {
const response = await axios.get(`${this.config.url}/getuserinvoices`, { const response = await axios.get(`${this.config.url}/getuserinvoices`, {
headers: this.getHeaders(), headers: this.getHeaders(),
}) })
if (response) { if (response?.data) {
return response.data return response.data
.filter((item: any) => item.ispaid) .filter((item: any) => item.ispaid)
.map((item: any) => { .map((item: any) => {