mirror of
https://github.com/KoalaSat/nostros.git
synced 2024-09-28 22:30:41 +00:00
LnBits integration (#456)
This commit is contained in:
commit
fd44b9ad17
@ -25,7 +25,7 @@ export const MenuItems: React.FC = () => {
|
|||||||
const [drawerItemIndex, setDrawerItemIndex] = React.useState<number>(-1)
|
const [drawerItemIndex, setDrawerItemIndex] = React.useState<number>(-1)
|
||||||
const { getSatoshiSymbol } = React.useContext(AppContext)
|
const { getSatoshiSymbol } = React.useContext(AppContext)
|
||||||
const { relays } = React.useContext(RelayPoolContext)
|
const { relays } = React.useContext(RelayPoolContext)
|
||||||
const { balance, active } = React.useContext(WalletContext)
|
const { balance, type } = React.useContext(WalletContext)
|
||||||
const {
|
const {
|
||||||
nPub,
|
nPub,
|
||||||
publicKey,
|
publicKey,
|
||||||
@ -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 (!active) return <></>
|
if (!type || !balance) return <></>
|
||||||
return (
|
return (
|
||||||
<Text>
|
<Text>
|
||||||
{`${balance} `}
|
{`${balance} `}
|
||||||
|
@ -1,31 +1,20 @@
|
|||||||
import axios from 'axios'
|
|
||||||
import { getUnixTime } from 'date-fns'
|
import { getUnixTime } from 'date-fns'
|
||||||
import React, { useEffect, useState } from 'react'
|
import React, { useEffect, useState } from 'react'
|
||||||
import SInfo from 'react-native-sensitive-info'
|
import SInfo from 'react-native-sensitive-info'
|
||||||
|
import type WalletAction from '../lib/Lightning'
|
||||||
export interface LndHub {
|
import LnBits, { type LnBitsConfig } from '../lib/Lightning/LnBits'
|
||||||
accessToken: string
|
import LndHub, { type LndHubConfig } from '../lib/Lightning/LndHub'
|
||||||
refreshToken: string
|
|
||||||
url: string
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface WalletAction {
|
|
||||||
id: string
|
|
||||||
monto: number
|
|
||||||
type: 'invoice' | 'transaction'
|
|
||||||
description: string
|
|
||||||
timestamp: number
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface WalletContextProps {
|
export interface WalletContextProps {
|
||||||
active: boolean
|
type?: string
|
||||||
updatedAt?: number
|
setType: (type: string) => void
|
||||||
lndHub?: LndHub
|
updatedAt?: string
|
||||||
setLndHub: (lndHub: LndHub) => void
|
lndHub?: LndHubConfig | LnBitsConfig
|
||||||
balance?: number
|
balance?: number
|
||||||
transactions: WalletAction[]
|
transactions: WalletAction[]
|
||||||
invoices: WalletAction[]
|
invoices: WalletAction[]
|
||||||
refreshLndHub: (login?: string, password?: string, uri?: string) => void
|
updateWallet: () => Promise<void>
|
||||||
|
refreshWallet: (params?: object, type?: string) => void
|
||||||
payInvoice: (invoice: string) => Promise<boolean>
|
payInvoice: (invoice: string) => Promise<boolean>
|
||||||
logoutWallet: () => void
|
logoutWallet: () => void
|
||||||
}
|
}
|
||||||
@ -35,18 +24,18 @@ export interface WalletContextProviderProps {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export const initialWalletContext: WalletContextProps = {
|
export const initialWalletContext: WalletContextProps = {
|
||||||
active: false,
|
|
||||||
setLndHub: () => {},
|
|
||||||
transactions: [],
|
transactions: [],
|
||||||
invoices: [],
|
invoices: [],
|
||||||
refreshLndHub: () => {},
|
setType: () => {},
|
||||||
|
updateWallet: async () => {},
|
||||||
|
refreshWallet: () => {},
|
||||||
payInvoice: async () => false,
|
payInvoice: async () => false,
|
||||||
logoutWallet: () => {},
|
logoutWallet: () => {},
|
||||||
}
|
}
|
||||||
|
|
||||||
export const WalletContextProvider = ({ children }: WalletContextProviderProps): JSX.Element => {
|
export const WalletContextProvider = ({ children }: WalletContextProviderProps): JSX.Element => {
|
||||||
const [active, setActive] = React.useState<boolean>(initialWalletContext.active)
|
const [type, setType] = React.useState<string>()
|
||||||
const [lndHub, setLndHub] = useState<LndHub>()
|
const [config, setConfig] = useState<LndHubConfig | LnBitsConfig>()
|
||||||
const [balance, setBalance] = useState<number>()
|
const [balance, setBalance] = useState<number>()
|
||||||
const [updatedAt, setUpdatedAt] = useState<string>()
|
const [updatedAt, setUpdatedAt] = useState<string>()
|
||||||
const [transactions, setTransactions] = useState<WalletAction[]>(
|
const [transactions, setTransactions] = useState<WalletAction[]>(
|
||||||
@ -57,119 +46,82 @@ export const WalletContextProvider = ({ children }: WalletContextProviderProps):
|
|||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
SInfo.getItem('lndHub', {}).then((value) => {
|
SInfo.getItem('lndHub', {}).then((value) => {
|
||||||
if (value) {
|
if (value) {
|
||||||
setLndHub(JSON.parse(value))
|
setConfig(JSON.parse(value))
|
||||||
|
setType('lndHub')
|
||||||
|
}
|
||||||
|
})
|
||||||
|
SInfo.getItem('lnBits', {}).then((value) => {
|
||||||
|
if (value) {
|
||||||
|
setConfig(JSON.parse(value))
|
||||||
|
setType('lnBits')
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
const refreshLndHub: (login?: string, password?: string, uri?: string) => void = (
|
const getClient: (params?: any, clientType?: string) => LndHub | LnBits | undefined = (
|
||||||
login,
|
params,
|
||||||
password,
|
clientType,
|
||||||
uri,
|
|
||||||
) => {
|
) => {
|
||||||
setLndHub(undefined)
|
const kind = clientType ?? type
|
||||||
let params:
|
let client
|
||||||
| { type: string; refresh_token?: string; login?: string; password?: string }
|
if (kind === 'lndHub') {
|
||||||
| undefined
|
client = new LndHub(params ?? config)
|
||||||
if (lndHub?.refreshToken) {
|
} else if (kind === 'lnBits') {
|
||||||
params = {
|
client = new LnBits(params ?? config)
|
||||||
type: 'refresh_token',
|
}
|
||||||
refresh_token: lndHub?.refreshToken,
|
|
||||||
}
|
return client
|
||||||
uri = lndHub?.url
|
}
|
||||||
} else if (login !== '' && password !== '' && uri !== '') {
|
|
||||||
params = {
|
const refreshWallet: (params?: any, clientType?: string) => void = (params, clientType) => {
|
||||||
type: 'auth',
|
setConfig(undefined)
|
||||||
login,
|
if (clientType) {
|
||||||
password,
|
setType(clientType)
|
||||||
|
const client = getClient(params, clientType)
|
||||||
|
if (client) {
|
||||||
|
client.refresh(params).then((response) => {
|
||||||
|
if (response?.status === 200) setConfig(response.config)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (params && uri) {
|
}
|
||||||
axios.post(`${uri}/auth`, {}, { params }).then((response) => {
|
|
||||||
if (response?.data?.refresh_token && response.data?.access_token && uri) {
|
const updateWallet: () => Promise<void> = async () => {
|
||||||
setLndHub({
|
console.log('config', config)
|
||||||
accessToken: response.data.access_token,
|
console.log('type', type)
|
||||||
refreshToken: response.data.refresh_token,
|
if (!config || !type) return
|
||||||
url: uri,
|
|
||||||
})
|
const client = getClient()
|
||||||
|
console.log('client', client)
|
||||||
|
if (client) {
|
||||||
|
client.getBalance().then((response) => {
|
||||||
|
if (response?.status === 200) {
|
||||||
|
setUpdatedAt(`${getUnixTime(new Date())}-balance`)
|
||||||
|
setBalance(response.balance)
|
||||||
|
SInfo.setItem(type, JSON.stringify(client.config), {})
|
||||||
|
} else if (response?.status === 401) {
|
||||||
|
refreshWallet()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
client.getMovements(setTransactions, setInvoices, setUpdatedAt)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const updateLndHub: () => void = () => {
|
useEffect(() => {
|
||||||
if (!lndHub) return
|
if (config) updateWallet()
|
||||||
|
}, [config])
|
||||||
const headers = {
|
|
||||||
Authorization: `Bearer ${lndHub.accessToken}`,
|
|
||||||
}
|
|
||||||
|
|
||||||
axios.get(`${lndHub.url}/balance`, { headers }).then((response) => {
|
|
||||||
if (response) {
|
|
||||||
if (response.status === 200) {
|
|
||||||
setUpdatedAt(`${getUnixTime(new Date())}-balance`)
|
|
||||||
setBalance(response.data?.BTC?.AvailableBalance ?? 0)
|
|
||||||
SInfo.setItem('lndHub', JSON.stringify(lndHub), {})
|
|
||||||
setActive(true)
|
|
||||||
} else if (response.status === 401) {
|
|
||||||
refreshLndHub()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
axios.get(`${lndHub.url}/gettxs`, { headers }).then((response) => {
|
|
||||||
if (response) {
|
|
||||||
setTransactions(
|
|
||||||
response.data.map((item: any) => {
|
|
||||||
return {
|
|
||||||
id: item.payment_preimage,
|
|
||||||
monto: item.value,
|
|
||||||
type: 'transaction',
|
|
||||||
description: item.memo,
|
|
||||||
timestamp: item.timestamp,
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
)
|
|
||||||
setUpdatedAt(`${getUnixTime(new Date())}-gettxs`)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
axios.get(`${lndHub.url}/getuserinvoices`, { headers }).then((response) => {
|
|
||||||
if (response) {
|
|
||||||
setInvoices(
|
|
||||||
response.data
|
|
||||||
.filter((item: any) => item.ispaid)
|
|
||||||
.map((item: any) => {
|
|
||||||
return {
|
|
||||||
id: item.payment_hash,
|
|
||||||
monto: item.amt,
|
|
||||||
type: 'invoice',
|
|
||||||
description: item.description,
|
|
||||||
timestamp: item.timestamp,
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
)
|
|
||||||
setUpdatedAt(`${getUnixTime(new Date())}-getuserinvoices`)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
useEffect(updateLndHub, [lndHub])
|
|
||||||
|
|
||||||
const payInvoice: (invoice: string) => Promise<boolean> = async (invoice) => {
|
const payInvoice: (invoice: string) => Promise<boolean> = async (invoice) => {
|
||||||
if (active && invoice && invoice !== '') {
|
if (type && config) {
|
||||||
const headers = {
|
const client = new LndHub(config as LndHubConfig)
|
||||||
Authorization: `Bearer ${lndHub?.accessToken}`,
|
const response = await client.payInvoice(invoice)
|
||||||
}
|
if (response?.status === 200) {
|
||||||
const params = {
|
updateWallet()
|
||||||
invoice,
|
return true
|
||||||
}
|
} else if (response?.status === 401) {
|
||||||
const response = await axios.post(`${lndHub?.url}/payinvoice`, params, { headers })
|
refreshWallet()
|
||||||
if (response) {
|
return true
|
||||||
if (response.status === 200) {
|
|
||||||
updateLndHub()
|
|
||||||
return response?.data?.payment_error === ''
|
|
||||||
} else if (response.status === 401) {
|
|
||||||
refreshLndHub()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -178,8 +130,8 @@ export const WalletContextProvider = ({ children }: WalletContextProviderProps):
|
|||||||
|
|
||||||
const logoutWallet: () => void = () => {
|
const logoutWallet: () => void = () => {
|
||||||
SInfo.deleteItem('lndHub', {})
|
SInfo.deleteItem('lndHub', {})
|
||||||
setActive(false)
|
setType(undefined)
|
||||||
setLndHub(undefined)
|
setConfig(undefined)
|
||||||
setBalance(undefined)
|
setBalance(undefined)
|
||||||
setUpdatedAt(undefined)
|
setUpdatedAt(undefined)
|
||||||
setTransactions([])
|
setTransactions([])
|
||||||
@ -189,13 +141,14 @@ export const WalletContextProvider = ({ children }: WalletContextProviderProps):
|
|||||||
return (
|
return (
|
||||||
<WalletContext.Provider
|
<WalletContext.Provider
|
||||||
value={{
|
value={{
|
||||||
active,
|
type,
|
||||||
|
setType,
|
||||||
updatedAt,
|
updatedAt,
|
||||||
setLndHub,
|
|
||||||
balance,
|
balance,
|
||||||
transactions,
|
transactions,
|
||||||
invoices,
|
invoices,
|
||||||
refreshLndHub,
|
refreshWallet,
|
||||||
|
updateWallet,
|
||||||
payInvoice,
|
payInvoice,
|
||||||
logoutWallet,
|
logoutWallet,
|
||||||
}}
|
}}
|
||||||
|
@ -26,6 +26,17 @@
|
|||||||
"loginStep3Description": "You can add the relays used by your contacts to your list and connect to them to strengthen the network.",
|
"loginStep3Description": "You can add the relays used by your contacts to your list and connect to them to strengthen the network.",
|
||||||
"loginskip": "You can skip this process but you may miss out on the opportunity to connect to a diverse range of relays and expand your network's reach"
|
"loginskip": "You can skip this process but you may miss out on the opportunity to connect to a diverse range of relays and expand your network's reach"
|
||||||
},
|
},
|
||||||
|
"walletPage": {
|
||||||
|
"addLnBits": "Add LnBits",
|
||||||
|
"adminKey": "Admin Key",
|
||||||
|
"invoiceReadKey": "Invoice Read Key",
|
||||||
|
"address": "Address",
|
||||||
|
"walletId": "Wallet id",
|
||||||
|
"connectingWallet": "Connecting to wallet",
|
||||||
|
"lnHub": "LNDHub address",
|
||||||
|
"addLnhub": "Add LNDHub",
|
||||||
|
"connect": "Connect"
|
||||||
|
},
|
||||||
"homeNavigator": {
|
"homeNavigator": {
|
||||||
"ProfileCreate": "Profil anlegen",
|
"ProfileCreate": "Profil anlegen",
|
||||||
"Search": "",
|
"Search": "",
|
||||||
|
@ -27,8 +27,14 @@
|
|||||||
"loginskip": "You can skip this process but you may miss out on the opportunity to connect to a diverse range of relays and expand your network's reach"
|
"loginskip": "You can skip this process but you may miss out on the opportunity to connect to a diverse range of relays and expand your network's reach"
|
||||||
},
|
},
|
||||||
"walletPage": {
|
"walletPage": {
|
||||||
"addLnhub": "Add LNHub",
|
"addLnBits": "Add LnBits",
|
||||||
"lnHub": "LNHub address",
|
"adminKey": "Admin Key",
|
||||||
|
"invoiceReadKey": "Invoice Read Key",
|
||||||
|
"address": "Address",
|
||||||
|
"walletId": "Wallet id",
|
||||||
|
"connectingWallet": "Connecting to wallet",
|
||||||
|
"lnHub": "LNDHub address",
|
||||||
|
"addLnhub": "Add LNDHub",
|
||||||
"connect": "Connect"
|
"connect": "Connect"
|
||||||
},
|
},
|
||||||
"homeNavigator": {
|
"homeNavigator": {
|
||||||
|
@ -26,6 +26,17 @@
|
|||||||
"loginStep3Description": "You can add the relays used by your contacts to your list and connect to them to strengthen the network.",
|
"loginStep3Description": "You can add the relays used by your contacts to your list and connect to them to strengthen the network.",
|
||||||
"loginskip": "You can skip this process but you may miss out on the opportunity to connect to a diverse range of relays and expand your network's reach"
|
"loginskip": "You can skip this process but you may miss out on the opportunity to connect to a diverse range of relays and expand your network's reach"
|
||||||
},
|
},
|
||||||
|
"walletPage": {
|
||||||
|
"addLnBits": "Añadir LnBits",
|
||||||
|
"adminKey": "Admin Key",
|
||||||
|
"invoiceReadKey": "Invoice Read Key",
|
||||||
|
"address": "Dirección",
|
||||||
|
"walletId": "Wallet id",
|
||||||
|
"connectingWallet": "Conectando a la wallet",
|
||||||
|
"lnHub": "Dirección LNDHub",
|
||||||
|
"addLnhub": "Añadir LNDHub",
|
||||||
|
"connect": "Connectar"
|
||||||
|
},
|
||||||
"searchPage": {
|
"searchPage": {
|
||||||
"placeholder": "Busca for claves públicas, notas, ...",
|
"placeholder": "Busca for claves públicas, notas, ...",
|
||||||
"emptyTitle": "Consejo",
|
"emptyTitle": "Consejo",
|
||||||
|
@ -26,6 +26,17 @@
|
|||||||
"loginStep3Description": "You can add the relays used by your contacts to your list and connect to them to strengthen the network.",
|
"loginStep3Description": "You can add the relays used by your contacts to your list and connect to them to strengthen the network.",
|
||||||
"loginskip": "You can skip this process but you may miss out on the opportunity to connect to a diverse range of relays and expand your network's reach"
|
"loginskip": "You can skip this process but you may miss out on the opportunity to connect to a diverse range of relays and expand your network's reach"
|
||||||
},
|
},
|
||||||
|
"walletPage": {
|
||||||
|
"addLnBits": "Add LnBits",
|
||||||
|
"adminKey": "Admin Key",
|
||||||
|
"invoiceReadKey": "Invoice Read Key",
|
||||||
|
"address": "Address",
|
||||||
|
"walletId": "Wallet id",
|
||||||
|
"connectingWallet": "Connecting to wallet",
|
||||||
|
"lnHub": "LNDHub address",
|
||||||
|
"addLnhub": "Add LNDHub",
|
||||||
|
"connect": "Connect"
|
||||||
|
},
|
||||||
"searchPage": {
|
"searchPage": {
|
||||||
"placeholder": "Look for public keys, notes, hashtags...",
|
"placeholder": "Look for public keys, notes, hashtags...",
|
||||||
"emptyTitle": "Tip",
|
"emptyTitle": "Tip",
|
||||||
|
@ -26,6 +26,17 @@
|
|||||||
"loginStep3Description": "You can add the relays used by your contacts to your list and connect to them to strengthen the network.",
|
"loginStep3Description": "You can add the relays used by your contacts to your list and connect to them to strengthen the network.",
|
||||||
"loginskip": "You can skip this process but you may miss out on the opportunity to connect to a diverse range of relays and expand your network's reach"
|
"loginskip": "You can skip this process but you may miss out on the opportunity to connect to a diverse range of relays and expand your network's reach"
|
||||||
},
|
},
|
||||||
|
"walletPage": {
|
||||||
|
"addLnBits": "Add LnBits",
|
||||||
|
"adminKey": "Admin Key",
|
||||||
|
"invoiceReadKey": "Invoice Read Key",
|
||||||
|
"address": "Address",
|
||||||
|
"walletId": "Wallet id",
|
||||||
|
"connectingWallet": "Connecting to wallet",
|
||||||
|
"lnHub": "LNDHub address",
|
||||||
|
"addLnhub": "Add LNDHub",
|
||||||
|
"connect": "Connect"
|
||||||
|
},
|
||||||
"searchPage": {
|
"searchPage": {
|
||||||
"placeholder": "Look for public keys, notes, hashtags...",
|
"placeholder": "Look for public keys, notes, hashtags...",
|
||||||
"emptyTitle": "Tip",
|
"emptyTitle": "Tip",
|
||||||
|
@ -26,6 +26,17 @@
|
|||||||
"loginStep3Description": "您可以将您的联系人使用的中继添加到您的列表中并连接到它们以加强网络",
|
"loginStep3Description": "您可以将您的联系人使用的中继添加到您的列表中并连接到它们以加强网络",
|
||||||
"loginskip": "您可以跳过此过程,但您可能会错过连接到各种中继和扩大网络覆盖范围的机会"
|
"loginskip": "您可以跳过此过程,但您可能会错过连接到各种中继和扩大网络覆盖范围的机会"
|
||||||
},
|
},
|
||||||
|
"walletPage": {
|
||||||
|
"addLnBits": "Add LnBits",
|
||||||
|
"adminKey": "Admin Key",
|
||||||
|
"invoiceReadKey": "Invoice Read Key",
|
||||||
|
"address": "Address",
|
||||||
|
"walletId": "Wallet id",
|
||||||
|
"connectingWallet": "Connecting to wallet",
|
||||||
|
"lnHub": "LNDHub address",
|
||||||
|
"addLnhub": "Add LNDHub",
|
||||||
|
"connect": "Connect"
|
||||||
|
},
|
||||||
"searchPage": {
|
"searchPage": {
|
||||||
"placeholder": "查找公钥,Notes,标签...",
|
"placeholder": "查找公钥,Notes,标签...",
|
||||||
"emptyTitle": "提示",
|
"emptyTitle": "提示",
|
||||||
|
@ -32,7 +32,7 @@ export const NotificationsFeed: React.FC = () => {
|
|||||||
const theme = useTheme()
|
const theme = useTheme()
|
||||||
const { t } = useTranslation('common')
|
const { t } = useTranslation('common')
|
||||||
const { database, setNotificationSeenAt, pushedTab, getSatoshiSymbol } = useContext(AppContext)
|
const { database, setNotificationSeenAt, pushedTab, getSatoshiSymbol } = useContext(AppContext)
|
||||||
const { publicKey, reloadLists, mutedEvents } = useContext(UserContext)
|
const { publicKey, reloadLists, mutedEvents, mutedUsers } = useContext(UserContext)
|
||||||
const { lastEventId, relayPool } = useContext(RelayPoolContext)
|
const { lastEventId, relayPool } = useContext(RelayPoolContext)
|
||||||
const [pubKeys, setPubKeys] = React.useState<string[]>([])
|
const [pubKeys, setPubKeys] = React.useState<string[]>([])
|
||||||
const [users, setUsers] = React.useState<User[]>([])
|
const [users, setUsers] = React.useState<User[]>([])
|
||||||
@ -145,7 +145,9 @@ export const NotificationsFeed: React.FC = () => {
|
|||||||
const unmutedThreads = notes.filter((note) => {
|
const unmutedThreads = notes.filter((note) => {
|
||||||
if (!note?.id) return false
|
if (!note?.id) return false
|
||||||
const eTags = getETags(note)
|
const eTags = getETags(note)
|
||||||
return !eTags.some((tag) => mutedEvents.includes(tag[1]))
|
return (
|
||||||
|
!eTags.some((tag) => mutedEvents.includes(tag[1])) && !mutedUsers.includes(note.pubkey)
|
||||||
|
)
|
||||||
})
|
})
|
||||||
setMentionNotes(unmutedThreads)
|
setMentionNotes(unmutedThreads)
|
||||||
setRefreshing(false)
|
setRefreshing(false)
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import Clipboard from '@react-native-clipboard/clipboard'
|
import Clipboard from '@react-native-clipboard/clipboard'
|
||||||
|
import { useFocusEffect } from '@react-navigation/native'
|
||||||
import { differenceInDays, format, fromUnixTime, isSameDay } from 'date-fns'
|
import { differenceInDays, format, fromUnixTime, isSameDay } from 'date-fns'
|
||||||
import { t } from 'i18next'
|
import { t } from 'i18next'
|
||||||
import React, { useEffect, useMemo } from 'react'
|
import React, { useEffect, useMemo } from 'react'
|
||||||
@ -15,24 +16,36 @@ import {
|
|||||||
} from 'react-native-paper'
|
} from 'react-native-paper'
|
||||||
import RBSheet from 'react-native-raw-bottom-sheet'
|
import RBSheet from 'react-native-raw-bottom-sheet'
|
||||||
import MaterialCommunityIcons from 'react-native-vector-icons/MaterialCommunityIcons'
|
import MaterialCommunityIcons from 'react-native-vector-icons/MaterialCommunityIcons'
|
||||||
|
import Logo from '../../Components/Logo'
|
||||||
import NostrosAvatar from '../../Components/NostrosAvatar'
|
import NostrosAvatar from '../../Components/NostrosAvatar'
|
||||||
import { AppContext } from '../../Contexts/AppContext'
|
import { AppContext } from '../../Contexts/AppContext'
|
||||||
import { type WalletAction, WalletContext } from '../../Contexts/WalletContext'
|
import { WalletContext } from '../../Contexts/WalletContext'
|
||||||
import { getZaps, type Zap } from '../../Functions/DatabaseFunctions/Zaps'
|
import { getZaps, type Zap } from '../../Functions/DatabaseFunctions/Zaps'
|
||||||
|
import type WalletAction from '../../lib/Lightning'
|
||||||
import { navigate } from '../../lib/Navigation'
|
import { navigate } from '../../lib/Navigation'
|
||||||
|
|
||||||
export const WalletPage: React.FC = () => {
|
export const WalletPage: React.FC = () => {
|
||||||
const theme = useTheme()
|
const theme = useTheme()
|
||||||
const { getSatoshiSymbol, database, setDisplayUserDrawer } = React.useContext(AppContext)
|
const { getSatoshiSymbol, database, setDisplayUserDrawer } = React.useContext(AppContext)
|
||||||
const { refreshLndHub, active, balance, transactions, invoices, updatedAt } =
|
const { refreshWallet, updateWallet, type, balance, transactions, invoices, updatedAt } =
|
||||||
React.useContext(WalletContext)
|
React.useContext(WalletContext)
|
||||||
const [lnHubAddress, setLndHubAddress] = React.useState<string>()
|
const [lnHubAddress, setLndHubAddress] = React.useState<string>()
|
||||||
|
const [lnBitsAddress, setLnBitsAddress] = React.useState<string>()
|
||||||
|
const [lnBitsInvoiceKey, setLnBitsInvoiceKey] = React.useState<string>()
|
||||||
|
const [lnBitsAdminKey, setLnBitsAdminKey] = React.useState<string>()
|
||||||
const [showNotification, setShowNotification] = React.useState<undefined | string>()
|
const [showNotification, setShowNotification] = React.useState<undefined | string>()
|
||||||
const [actions, setActions] = React.useState<WalletAction[]>([])
|
const [actions, setActions] = React.useState<WalletAction[]>([])
|
||||||
const [zaps, setZaps] = React.useState<Record<string, Zap>>({})
|
const [zaps, setZaps] = React.useState<Record<string, Zap>>({})
|
||||||
const bottomLndHubRef = React.useRef<RBSheet>(null)
|
const bottomLndHubRef = React.useRef<RBSheet>(null)
|
||||||
|
const bottomLndBitsRef = React.useRef<RBSheet>(null)
|
||||||
|
|
||||||
|
useFocusEffect(
|
||||||
|
React.useCallback(() => {
|
||||||
|
updateWallet()
|
||||||
|
return () => {}
|
||||||
|
}, []),
|
||||||
|
)
|
||||||
|
|
||||||
useEffect(refreshLndHub, [])
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const array = [...transactions, ...invoices].sort(
|
const array = [...transactions, ...invoices].sort(
|
||||||
(item1, item2) => item2.timestamp - item1.timestamp,
|
(item1, item2) => item2.timestamp - item1.timestamp,
|
||||||
@ -51,9 +64,9 @@ export const WalletPage: React.FC = () => {
|
|||||||
}
|
}
|
||||||
}, [updatedAt])
|
}, [updatedAt])
|
||||||
|
|
||||||
const pasteLndHub: () => void = () => {
|
const paste: (setFunction: (value: string) => void) => void = (setFunction) => {
|
||||||
Clipboard.getString().then((value) => {
|
Clipboard.getString().then((value) => {
|
||||||
setLndHubAddress(value ?? '')
|
setFunction(value ?? '')
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -67,13 +80,27 @@ export const WalletPage: React.FC = () => {
|
|||||||
if (uri[uri.length - 1] === '/') {
|
if (uri[uri.length - 1] === '/') {
|
||||||
uri = uri.substring(0, uri.length - 1)
|
uri = uri.substring(0, uri.length - 1)
|
||||||
}
|
}
|
||||||
refreshLndHub(login, password, uri)
|
refreshWallet({ login, password, uri }, 'lndHub')
|
||||||
setLndHubAddress(undefined)
|
setLndHubAddress(undefined)
|
||||||
bottomLndHubRef.current?.close()
|
bottomLndHubRef.current?.close()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const connectLnBits: () => void = () => {
|
||||||
|
if (lnBitsAddress && lnBitsAdminKey && lnBitsInvoiceKey) {
|
||||||
|
let uri = lnBitsAddress
|
||||||
|
if (uri[uri.length - 1] === '/') {
|
||||||
|
uri = uri.substring(0, uri.length - 1)
|
||||||
|
}
|
||||||
|
refreshWallet({ lnBitsAddress, lnBitsAdminKey, lnBitsInvoiceKey }, 'lnBits')
|
||||||
|
setLnBitsAddress(undefined)
|
||||||
|
setLnBitsAdminKey(undefined)
|
||||||
|
setLnBitsInvoiceKey(undefined)
|
||||||
|
bottomLndBitsRef.current?.close()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const bottomSheetStyles = React.useMemo(() => {
|
const bottomSheetStyles = React.useMemo(() => {
|
||||||
return {
|
return {
|
||||||
container: {
|
container: {
|
||||||
@ -95,6 +122,13 @@ export const WalletPage: React.FC = () => {
|
|||||||
<Button mode='contained' onPress={() => bottomLndHubRef.current?.open()}>
|
<Button mode='contained' onPress={() => bottomLndHubRef.current?.open()}>
|
||||||
{t('walletPage.addLnhub')}
|
{t('walletPage.addLnhub')}
|
||||||
</Button>
|
</Button>
|
||||||
|
<Button
|
||||||
|
mode='contained'
|
||||||
|
style={styles.button}
|
||||||
|
onPress={() => bottomLndBitsRef.current?.open()}
|
||||||
|
>
|
||||||
|
{t('walletPage.addLnBits')}
|
||||||
|
</Button>
|
||||||
</View>
|
</View>
|
||||||
),
|
),
|
||||||
[],
|
[],
|
||||||
@ -109,7 +143,7 @@ export const WalletPage: React.FC = () => {
|
|||||||
const zap = zaps[item.id]
|
const zap = zaps[item.id]
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<View key={item.id ?? index}>
|
||||||
{(index === 0 || !isSameDay(date, prevDate)) && (
|
{(index === 0 || !isSameDay(date, prevDate)) && (
|
||||||
<Text variant='titleMedium'>{format(date, formatPattern)}</Text>
|
<Text variant='titleMedium'>{format(date, formatPattern)}</Text>
|
||||||
)}
|
)}
|
||||||
@ -172,29 +206,33 @@ export const WalletPage: React.FC = () => {
|
|||||||
</View>
|
</View>
|
||||||
</View>
|
</View>
|
||||||
</TouchableRipple>
|
</TouchableRipple>
|
||||||
</>
|
</View>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<View style={styles.container}>
|
<View style={styles.container}>
|
||||||
{active ? (
|
{type ? (
|
||||||
<View>
|
balance !== undefined ? (
|
||||||
<View style={[styles.balance, { backgroundColor: theme.colors.onSecondary }]}>
|
<View>
|
||||||
<View style={styles.balanceNumber}>
|
<View style={[styles.balance, { backgroundColor: theme.colors.onSecondary }]}>
|
||||||
<Text variant='displayMedium'>{`${balance} `}</Text>
|
<View style={styles.balanceNumber}>
|
||||||
<Text style={styles.balanceSymbol} variant='headlineSmall'>
|
<Text variant='displayMedium'>{`${balance} `}</Text>
|
||||||
{getSatoshiSymbol()}
|
<Text style={styles.balanceSymbol} variant='headlineSmall'>
|
||||||
</Text>
|
{getSatoshiSymbol()}
|
||||||
|
</Text>
|
||||||
|
</View>
|
||||||
</View>
|
</View>
|
||||||
|
<FlatList data={actions} renderItem={renderAction} style={styles.list} />
|
||||||
</View>
|
</View>
|
||||||
<FlatList
|
) : (
|
||||||
data={actions}
|
<View style={styles.center}>
|
||||||
renderItem={renderAction}
|
<View style={styles.centerItem}>
|
||||||
style={styles.list}
|
<Logo onlyIcon size='large' />
|
||||||
keyExtractor={(item) => item.id}
|
</View>
|
||||||
/>
|
<Text style={styles.centerItem}>{t('walletPage.connectingWallet')}</Text>
|
||||||
</View>
|
</View>
|
||||||
|
)
|
||||||
) : (
|
) : (
|
||||||
login
|
login
|
||||||
)}
|
)}
|
||||||
@ -206,7 +244,7 @@ export const WalletPage: React.FC = () => {
|
|||||||
onIconPress={() => setShowNotification(undefined)}
|
onIconPress={() => setShowNotification(undefined)}
|
||||||
onDismiss={() => setShowNotification(undefined)}
|
onDismiss={() => setShowNotification(undefined)}
|
||||||
>
|
>
|
||||||
{t(`profileCard.notifications.${showNotification}`)}
|
{t(`walletPage.notifications.${showNotification}`)}
|
||||||
</Snackbar>
|
</Snackbar>
|
||||||
)}
|
)}
|
||||||
<RBSheet ref={bottomLndHubRef} closeOnDragDown={true} customStyles={bottomSheetStyles}>
|
<RBSheet ref={bottomLndHubRef} closeOnDragDown={true} customStyles={bottomSheetStyles}>
|
||||||
@ -224,7 +262,7 @@ export const WalletPage: React.FC = () => {
|
|||||||
right={
|
right={
|
||||||
<TextInput.Icon
|
<TextInput.Icon
|
||||||
icon='content-paste'
|
icon='content-paste'
|
||||||
onPress={pasteLndHub}
|
onPress={() => paste(setLndHubAddress)}
|
||||||
forceTextInputFocus={false}
|
forceTextInputFocus={false}
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
@ -234,6 +272,69 @@ export const WalletPage: React.FC = () => {
|
|||||||
</Button>
|
</Button>
|
||||||
</View>
|
</View>
|
||||||
</RBSheet>
|
</RBSheet>
|
||||||
|
<RBSheet ref={bottomLndBitsRef} closeOnDragDown={true} customStyles={bottomSheetStyles}>
|
||||||
|
<View>
|
||||||
|
<Text variant='headlineSmall' style={styles.drawerParagraph}>
|
||||||
|
{t('walletPage.addLnBits')}
|
||||||
|
</Text>
|
||||||
|
<TextInput
|
||||||
|
style={styles.drawerParagraph}
|
||||||
|
mode='outlined'
|
||||||
|
multiline
|
||||||
|
label={t('walletPage.address') ?? ''}
|
||||||
|
onChangeText={setLnBitsAddress}
|
||||||
|
value={lnBitsAddress}
|
||||||
|
right={
|
||||||
|
<TextInput.Icon
|
||||||
|
icon='content-paste'
|
||||||
|
onPress={() => paste(setLnBitsAddress)}
|
||||||
|
forceTextInputFocus={false}
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
<TextInput
|
||||||
|
style={styles.drawerParagraph}
|
||||||
|
mode='outlined'
|
||||||
|
multiline
|
||||||
|
label={t('walletPage.adminKey') ?? ''}
|
||||||
|
onChangeText={setLnBitsAdminKey}
|
||||||
|
value={lnBitsAdminKey}
|
||||||
|
right={
|
||||||
|
<TextInput.Icon
|
||||||
|
icon='content-paste'
|
||||||
|
onPress={() => paste(setLnBitsAdminKey)}
|
||||||
|
forceTextInputFocus={false}
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
<TextInput
|
||||||
|
style={styles.drawerParagraph}
|
||||||
|
mode='outlined'
|
||||||
|
multiline
|
||||||
|
label={t('walletPage.invoiceReadKey') ?? ''}
|
||||||
|
onChangeText={setLnBitsInvoiceKey}
|
||||||
|
value={lnBitsInvoiceKey}
|
||||||
|
right={
|
||||||
|
<TextInput.Icon
|
||||||
|
icon='content-paste'
|
||||||
|
onPress={() => paste(setLnBitsInvoiceKey)}
|
||||||
|
forceTextInputFocus={false}
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
<Button
|
||||||
|
mode='contained'
|
||||||
|
onPress={connectLnBits}
|
||||||
|
disabled={
|
||||||
|
lnBitsAddress === undefined ||
|
||||||
|
lnBitsAdminKey === undefined ||
|
||||||
|
lnBitsInvoiceKey === undefined
|
||||||
|
}
|
||||||
|
>
|
||||||
|
{t('walletPage.connect')}
|
||||||
|
</Button>
|
||||||
|
</View>
|
||||||
|
</RBSheet>
|
||||||
</View>
|
</View>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -245,10 +346,18 @@ const styles = StyleSheet.create({
|
|||||||
},
|
},
|
||||||
center: {
|
center: {
|
||||||
justifyContent: 'center',
|
justifyContent: 'center',
|
||||||
alignContent: 'center',
|
|
||||||
height: '100%',
|
height: '100%',
|
||||||
padding: 16,
|
padding: 16,
|
||||||
},
|
},
|
||||||
|
centerItem: {
|
||||||
|
flexDirection: 'row',
|
||||||
|
justifyContent: 'center',
|
||||||
|
width: '100%',
|
||||||
|
textAlign: 'center',
|
||||||
|
},
|
||||||
|
button: {
|
||||||
|
marginTop: 16,
|
||||||
|
},
|
||||||
drawerParagraph: {
|
drawerParagraph: {
|
||||||
marginBottom: 16,
|
marginBottom: 16,
|
||||||
},
|
},
|
||||||
|
108
frontend/lib/Lightning/LnBits/index.ts
Normal file
108
frontend/lib/Lightning/LnBits/index.ts
Normal file
@ -0,0 +1,108 @@
|
|||||||
|
import axios from 'axios'
|
||||||
|
import { getUnixTime } from 'date-fns'
|
||||||
|
import type WalletAction from '..'
|
||||||
|
|
||||||
|
export interface LnBitsConfig {
|
||||||
|
lnBitsAddress: string
|
||||||
|
lnBitsAdminKey: string
|
||||||
|
lnBitsInvoiceKey: string
|
||||||
|
}
|
||||||
|
|
||||||
|
class LndHub {
|
||||||
|
constructor(config?: LnBitsConfig) {
|
||||||
|
this.config = config
|
||||||
|
}
|
||||||
|
|
||||||
|
public config: LnBitsConfig | undefined
|
||||||
|
|
||||||
|
private readonly getHeaders: () => object | undefined = () => {
|
||||||
|
if (!this.config) return
|
||||||
|
return {
|
||||||
|
'X-Api-Key': this.config.lnBitsInvoiceKey,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public payInvoice: (invoice: string) => Promise<{ status: number } | undefined> = async (
|
||||||
|
invoice,
|
||||||
|
) => {
|
||||||
|
if (!this.config) return
|
||||||
|
if (invoice && invoice !== '') {
|
||||||
|
const params = {
|
||||||
|
invoice,
|
||||||
|
}
|
||||||
|
const response = await axios.post(`${this.config?.lnBitsAddress}/payinvoice`, params, {
|
||||||
|
headers: this.getHeaders(),
|
||||||
|
})
|
||||||
|
if (response) {
|
||||||
|
return { status: response.status }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public getBalance: () => Promise<{ balance?: number; status: number } | undefined> = async () => {
|
||||||
|
if (!this.config) return
|
||||||
|
const headers = {
|
||||||
|
'X-Api-Key': this.config.lnBitsInvoiceKey,
|
||||||
|
}
|
||||||
|
const response = await axios.get(`${this.config.lnBitsAddress}/api/v1/wallet`, { headers })
|
||||||
|
if (response) {
|
||||||
|
return {
|
||||||
|
balance: (response.data?.balance ?? 0) / 1000,
|
||||||
|
status: response.status,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public getMovements: (
|
||||||
|
setTransactions: (transactions: WalletAction[]) => void,
|
||||||
|
setInvoices: (invoices: WalletAction[]) => void,
|
||||||
|
setUpdatedAt: (updatedAt: string) => void,
|
||||||
|
) => Promise<void> = async (setTransactions, setInvoices, setUpdatedAt) => {
|
||||||
|
if (!this.config) return
|
||||||
|
const headers = {
|
||||||
|
'X-Api-Key': this.config.lnBitsInvoiceKey,
|
||||||
|
}
|
||||||
|
const response = await axios.get(`${this.config.lnBitsAddress}/api/v1/payments`, { headers })
|
||||||
|
if (response) {
|
||||||
|
setTransactions(
|
||||||
|
response.data
|
||||||
|
.filter((item: any) => item.amount < 0)
|
||||||
|
.map((item: any) => {
|
||||||
|
return {
|
||||||
|
id: item.payment_preimage,
|
||||||
|
monto: Math.abs(item.amount / 1000),
|
||||||
|
type: 'transaction',
|
||||||
|
description: item.memo,
|
||||||
|
timestamp: item.time,
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
setInvoices(
|
||||||
|
response.data
|
||||||
|
.filter((item: any) => item.amount > 0)
|
||||||
|
.map((item: any) => {
|
||||||
|
return {
|
||||||
|
id: item.payment_preimage,
|
||||||
|
monto: item.amount / 1000,
|
||||||
|
type: 'invoice',
|
||||||
|
description: item.memo,
|
||||||
|
timestamp: item.time,
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
setUpdatedAt(`${getUnixTime(new Date())}-movements`)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public refresh: (params: any) => Promise<{ config: LnBitsConfig; status: number } | undefined> =
|
||||||
|
async (params) => {
|
||||||
|
if (params?.lnBitsAddress) {
|
||||||
|
return {
|
||||||
|
config: params,
|
||||||
|
status: 200,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default LndHub
|
134
frontend/lib/Lightning/LndHub/index.ts
Normal file
134
frontend/lib/Lightning/LndHub/index.ts
Normal file
@ -0,0 +1,134 @@
|
|||||||
|
import axios from 'axios'
|
||||||
|
import { getUnixTime } from 'date-fns'
|
||||||
|
import type WalletAction from '..'
|
||||||
|
|
||||||
|
export interface LndHubConfig {
|
||||||
|
accessToken: string
|
||||||
|
refreshToken: string
|
||||||
|
url: string
|
||||||
|
}
|
||||||
|
|
||||||
|
class LndHub {
|
||||||
|
constructor(config?: LndHubConfig) {
|
||||||
|
this.config = config
|
||||||
|
}
|
||||||
|
|
||||||
|
public config: LndHubConfig | undefined
|
||||||
|
|
||||||
|
private readonly getHeaders: () => object | undefined = () => {
|
||||||
|
if (!this.config) return
|
||||||
|
return {
|
||||||
|
Authorization: `Bearer ${this.config.accessToken}`,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public payInvoice: (invoice: string) => Promise<{ status: number } | undefined> = async (
|
||||||
|
invoice,
|
||||||
|
) => {
|
||||||
|
if (!this.config) return
|
||||||
|
if (invoice && invoice !== '') {
|
||||||
|
const params = {
|
||||||
|
invoice,
|
||||||
|
}
|
||||||
|
const response = await axios.post(`${this.config?.url}/payinvoice`, params, {
|
||||||
|
headers: this.getHeaders(),
|
||||||
|
})
|
||||||
|
if (response) {
|
||||||
|
return { status: response.status }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public getBalance: () => Promise<{ balance?: number; status: number } | undefined> = async () => {
|
||||||
|
if (!this.config) return
|
||||||
|
const response = await axios.get(`${this.config.url}/balance`, { headers: this.getHeaders() })
|
||||||
|
if (response) {
|
||||||
|
return {
|
||||||
|
balance: response.data?.BTC?.AvailableBalance ?? 0,
|
||||||
|
status: response.status,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private readonly getTransactions: () => Promise<WalletAction[] | undefined> = async () => {
|
||||||
|
if (!this.config) return
|
||||||
|
const response = await axios.get(`${this.config.url}/gettxs`, { headers: this.getHeaders() })
|
||||||
|
if (response) {
|
||||||
|
return response.data.map((item: any) => {
|
||||||
|
return {
|
||||||
|
id: item.payment_preimage,
|
||||||
|
monto: item.value,
|
||||||
|
type: 'transaction',
|
||||||
|
description: item.memo,
|
||||||
|
timestamp: item.timestamp,
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private readonly getInvoices: () => Promise<WalletAction[] | undefined> = async () => {
|
||||||
|
if (!this.config) return
|
||||||
|
const response = await axios.get(`${this.config.url}/getuserinvoices`, {
|
||||||
|
headers: this.getHeaders(),
|
||||||
|
})
|
||||||
|
if (response) {
|
||||||
|
return response.data
|
||||||
|
.filter((item: any) => item.ispaid)
|
||||||
|
.map((item: any) => {
|
||||||
|
return {
|
||||||
|
id: item.payment_hash,
|
||||||
|
monto: item.amt,
|
||||||
|
type: 'invoice',
|
||||||
|
description: item.description,
|
||||||
|
timestamp: item.timestamp,
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public getMovements: (
|
||||||
|
setTransactions: (transactions: WalletAction[]) => void,
|
||||||
|
setInvoices: (transactions: WalletAction[]) => void,
|
||||||
|
setUpdatedAt: (updatedAt: string) => void,
|
||||||
|
) => Promise<void> = async (setTransactions, setInvoices, setUpdatedAt) => {
|
||||||
|
if (!this.config) return
|
||||||
|
setTransactions((await this.getTransactions()) ?? [])
|
||||||
|
setInvoices((await this.getInvoices()) ?? [])
|
||||||
|
setUpdatedAt(`${getUnixTime(new Date())}-movements`)
|
||||||
|
}
|
||||||
|
|
||||||
|
public refresh: (params: any) => Promise<{ config: LndHubConfig; status: number } | undefined> =
|
||||||
|
async (params) => {
|
||||||
|
let requestParams:
|
||||||
|
| { type: string; refresh_token?: string; login?: string; password?: string }
|
||||||
|
| undefined
|
||||||
|
if (this.config?.refreshToken) {
|
||||||
|
requestParams = {
|
||||||
|
type: 'refresh_token',
|
||||||
|
refresh_token: this.config?.refreshToken,
|
||||||
|
}
|
||||||
|
params.uri = this.config?.url
|
||||||
|
} else if (params.login !== '' && params.password !== '' && params.uri !== '') {
|
||||||
|
requestParams = {
|
||||||
|
type: 'auth',
|
||||||
|
login: params.login,
|
||||||
|
password: params.password,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (params?.uri) {
|
||||||
|
const response = await axios.post(`${params.uri}/auth`, {}, { params: requestParams })
|
||||||
|
if (response) {
|
||||||
|
return {
|
||||||
|
config: {
|
||||||
|
accessToken: response.data.access_token,
|
||||||
|
refreshToken: response.data.refresh_token,
|
||||||
|
url: params.uri,
|
||||||
|
},
|
||||||
|
status: response.status,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default LndHub
|
9
frontend/lib/Lightning/index.ts
Normal file
9
frontend/lib/Lightning/index.ts
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
export interface WalletAction {
|
||||||
|
id: string
|
||||||
|
monto: number
|
||||||
|
type: 'invoice' | 'transaction'
|
||||||
|
description: string
|
||||||
|
timestamp: number
|
||||||
|
}
|
||||||
|
|
||||||
|
export default WalletAction
|
@ -80,7 +80,7 @@
|
|||||||
"@types/react-native-vector-icons": "^6.4.13",
|
"@types/react-native-vector-icons": "^6.4.13",
|
||||||
"@types/react-test-renderer": "^18.0.0",
|
"@types/react-test-renderer": "^18.0.0",
|
||||||
"@types/uuid": "^9.0.0",
|
"@types/uuid": "^9.0.0",
|
||||||
"@typescript-eslint/eslint-plugin": "^5.43.0",
|
"@typescript-eslint/eslint-plugin": "^5.56.0",
|
||||||
"babel-jest": "^29.4.3",
|
"babel-jest": "^29.4.3",
|
||||||
"eslint": "^8.36.0",
|
"eslint": "^8.36.0",
|
||||||
"eslint-config-prettier": "^8.6.0",
|
"eslint-config-prettier": "^8.6.0",
|
||||||
@ -94,10 +94,10 @@
|
|||||||
"eslint-plugin-react": "^7.32.2",
|
"eslint-plugin-react": "^7.32.2",
|
||||||
"eslint-plugin-react-hooks": "^4.6.0",
|
"eslint-plugin-react-hooks": "^4.6.0",
|
||||||
"jest": "^29.4.3",
|
"jest": "^29.4.3",
|
||||||
"metro-react-native-babel-preset": "^0.75.0",
|
"metro-react-native-babel-preset": "^0.76.0",
|
||||||
"prettier": "^2.8.4",
|
"prettier": "^2.8.4",
|
||||||
"react-test-renderer": "18.2.0",
|
"react-test-renderer": "18.2.0",
|
||||||
"typescript": "^4.9.4"
|
"typescript": "^5.0.2"
|
||||||
},
|
},
|
||||||
"resolutions": {
|
"resolutions": {
|
||||||
"@types/react": "^17"
|
"@types/react": "^17"
|
||||||
|
108
yarn.lock
108
yarn.lock
@ -1798,7 +1798,7 @@
|
|||||||
dependencies:
|
dependencies:
|
||||||
"@types/yargs-parser" "*"
|
"@types/yargs-parser" "*"
|
||||||
|
|
||||||
"@typescript-eslint/eslint-plugin@^5.30.5", "@typescript-eslint/eslint-plugin@^5.43.0":
|
"@typescript-eslint/eslint-plugin@^5.30.5":
|
||||||
version "5.55.0"
|
version "5.55.0"
|
||||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.55.0.tgz#bc2400c3a23305e8c9a9c04aa40933868aaaeb47"
|
resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.55.0.tgz#bc2400c3a23305e8c9a9c04aa40933868aaaeb47"
|
||||||
integrity sha512-IZGc50rtbjk+xp5YQoJvmMPmJEYoC53SiKPXyqWfv15XoD2Y5Kju6zN0DwlmaGJp1Iw33JsWJcQ7nw0lGCGjVg==
|
integrity sha512-IZGc50rtbjk+xp5YQoJvmMPmJEYoC53SiKPXyqWfv15XoD2Y5Kju6zN0DwlmaGJp1Iw33JsWJcQ7nw0lGCGjVg==
|
||||||
@ -1814,6 +1814,22 @@
|
|||||||
semver "^7.3.7"
|
semver "^7.3.7"
|
||||||
tsutils "^3.21.0"
|
tsutils "^3.21.0"
|
||||||
|
|
||||||
|
"@typescript-eslint/eslint-plugin@^5.56.0":
|
||||||
|
version "5.56.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.56.0.tgz#e4fbb4d6dd8dab3e733485c1a44a02189ae75364"
|
||||||
|
integrity sha512-ZNW37Ccl3oMZkzxrYDUX4o7cnuPgU+YrcaYXzsRtLB16I1FR5SHMqga3zGsaSliZADCWo2v8qHWqAYIj8nWCCg==
|
||||||
|
dependencies:
|
||||||
|
"@eslint-community/regexpp" "^4.4.0"
|
||||||
|
"@typescript-eslint/scope-manager" "5.56.0"
|
||||||
|
"@typescript-eslint/type-utils" "5.56.0"
|
||||||
|
"@typescript-eslint/utils" "5.56.0"
|
||||||
|
debug "^4.3.4"
|
||||||
|
grapheme-splitter "^1.0.4"
|
||||||
|
ignore "^5.2.0"
|
||||||
|
natural-compare-lite "^1.4.0"
|
||||||
|
semver "^7.3.7"
|
||||||
|
tsutils "^3.21.0"
|
||||||
|
|
||||||
"@typescript-eslint/parser@^5.30.5", "@typescript-eslint/parser@^5.43.0":
|
"@typescript-eslint/parser@^5.30.5", "@typescript-eslint/parser@^5.43.0":
|
||||||
version "5.55.0"
|
version "5.55.0"
|
||||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-5.55.0.tgz#8c96a0b6529708ace1dcfa60f5e6aec0f5ed2262"
|
resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-5.55.0.tgz#8c96a0b6529708ace1dcfa60f5e6aec0f5ed2262"
|
||||||
@ -1832,6 +1848,14 @@
|
|||||||
"@typescript-eslint/types" "5.55.0"
|
"@typescript-eslint/types" "5.55.0"
|
||||||
"@typescript-eslint/visitor-keys" "5.55.0"
|
"@typescript-eslint/visitor-keys" "5.55.0"
|
||||||
|
|
||||||
|
"@typescript-eslint/scope-manager@5.56.0":
|
||||||
|
version "5.56.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-5.56.0.tgz#62b4055088903b5254fa20403010e1c16d6ab725"
|
||||||
|
integrity sha512-jGYKyt+iBakD0SA5Ww8vFqGpoV2asSjwt60Gl6YcO8ksQ8s2HlUEyHBMSa38bdLopYqGf7EYQMUIGdT/Luw+sw==
|
||||||
|
dependencies:
|
||||||
|
"@typescript-eslint/types" "5.56.0"
|
||||||
|
"@typescript-eslint/visitor-keys" "5.56.0"
|
||||||
|
|
||||||
"@typescript-eslint/type-utils@5.55.0":
|
"@typescript-eslint/type-utils@5.55.0":
|
||||||
version "5.55.0"
|
version "5.55.0"
|
||||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-5.55.0.tgz#74bf0233523f874738677bb73cb58094210e01e9"
|
resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-5.55.0.tgz#74bf0233523f874738677bb73cb58094210e01e9"
|
||||||
@ -1842,11 +1866,26 @@
|
|||||||
debug "^4.3.4"
|
debug "^4.3.4"
|
||||||
tsutils "^3.21.0"
|
tsutils "^3.21.0"
|
||||||
|
|
||||||
|
"@typescript-eslint/type-utils@5.56.0":
|
||||||
|
version "5.56.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-5.56.0.tgz#e6f004a072f09c42e263dc50e98c70b41a509685"
|
||||||
|
integrity sha512-8WxgOgJjWRy6m4xg9KoSHPzBNZeQbGlQOH7l2QEhQID/+YseaFxg5J/DLwWSsi9Axj4e/cCiKx7PVzOq38tY4A==
|
||||||
|
dependencies:
|
||||||
|
"@typescript-eslint/typescript-estree" "5.56.0"
|
||||||
|
"@typescript-eslint/utils" "5.56.0"
|
||||||
|
debug "^4.3.4"
|
||||||
|
tsutils "^3.21.0"
|
||||||
|
|
||||||
"@typescript-eslint/types@5.55.0":
|
"@typescript-eslint/types@5.55.0":
|
||||||
version "5.55.0"
|
version "5.55.0"
|
||||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.55.0.tgz#9830f8d3bcbecf59d12f821e5bc6960baaed41fd"
|
resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.55.0.tgz#9830f8d3bcbecf59d12f821e5bc6960baaed41fd"
|
||||||
integrity sha512-M4iRh4AG1ChrOL6Y+mETEKGeDnT7Sparn6fhZ5LtVJF1909D5O4uqK+C5NPbLmpfZ0XIIxCdwzKiijpZUOvOug==
|
integrity sha512-M4iRh4AG1ChrOL6Y+mETEKGeDnT7Sparn6fhZ5LtVJF1909D5O4uqK+C5NPbLmpfZ0XIIxCdwzKiijpZUOvOug==
|
||||||
|
|
||||||
|
"@typescript-eslint/types@5.56.0":
|
||||||
|
version "5.56.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.56.0.tgz#b03f0bfd6fa2afff4e67c5795930aff398cbd834"
|
||||||
|
integrity sha512-JyAzbTJcIyhuUhogmiu+t79AkdnqgPUEsxMTMc/dCZczGMJQh1MK2wgrju++yMN6AWroVAy2jxyPcPr3SWCq5w==
|
||||||
|
|
||||||
"@typescript-eslint/typescript-estree@5.55.0":
|
"@typescript-eslint/typescript-estree@5.55.0":
|
||||||
version "5.55.0"
|
version "5.55.0"
|
||||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.55.0.tgz#8db7c8e47ecc03d49b05362b8db6f1345ee7b575"
|
resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.55.0.tgz#8db7c8e47ecc03d49b05362b8db6f1345ee7b575"
|
||||||
@ -1860,6 +1899,19 @@
|
|||||||
semver "^7.3.7"
|
semver "^7.3.7"
|
||||||
tsutils "^3.21.0"
|
tsutils "^3.21.0"
|
||||||
|
|
||||||
|
"@typescript-eslint/typescript-estree@5.56.0":
|
||||||
|
version "5.56.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.56.0.tgz#48342aa2344649a03321e74cab9ccecb9af086c3"
|
||||||
|
integrity sha512-41CH/GncsLXOJi0jb74SnC7jVPWeVJ0pxQj8bOjH1h2O26jXN3YHKDT1ejkVz5YeTEQPeLCCRY0U2r68tfNOcg==
|
||||||
|
dependencies:
|
||||||
|
"@typescript-eslint/types" "5.56.0"
|
||||||
|
"@typescript-eslint/visitor-keys" "5.56.0"
|
||||||
|
debug "^4.3.4"
|
||||||
|
globby "^11.1.0"
|
||||||
|
is-glob "^4.0.3"
|
||||||
|
semver "^7.3.7"
|
||||||
|
tsutils "^3.21.0"
|
||||||
|
|
||||||
"@typescript-eslint/utils@5.55.0", "@typescript-eslint/utils@^5.10.0":
|
"@typescript-eslint/utils@5.55.0", "@typescript-eslint/utils@^5.10.0":
|
||||||
version "5.55.0"
|
version "5.55.0"
|
||||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-5.55.0.tgz#34e97322e7ae5b901e7a870aabb01dad90023341"
|
resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-5.55.0.tgz#34e97322e7ae5b901e7a870aabb01dad90023341"
|
||||||
@ -1874,6 +1926,20 @@
|
|||||||
eslint-scope "^5.1.1"
|
eslint-scope "^5.1.1"
|
||||||
semver "^7.3.7"
|
semver "^7.3.7"
|
||||||
|
|
||||||
|
"@typescript-eslint/utils@5.56.0":
|
||||||
|
version "5.56.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-5.56.0.tgz#db64705409b9a15546053fb4deb2888b37df1f41"
|
||||||
|
integrity sha512-XhZDVdLnUJNtbzaJeDSCIYaM+Tgr59gZGbFuELgF7m0IY03PlciidS7UQNKLE0+WpUTn1GlycEr6Ivb/afjbhA==
|
||||||
|
dependencies:
|
||||||
|
"@eslint-community/eslint-utils" "^4.2.0"
|
||||||
|
"@types/json-schema" "^7.0.9"
|
||||||
|
"@types/semver" "^7.3.12"
|
||||||
|
"@typescript-eslint/scope-manager" "5.56.0"
|
||||||
|
"@typescript-eslint/types" "5.56.0"
|
||||||
|
"@typescript-eslint/typescript-estree" "5.56.0"
|
||||||
|
eslint-scope "^5.1.1"
|
||||||
|
semver "^7.3.7"
|
||||||
|
|
||||||
"@typescript-eslint/visitor-keys@5.55.0":
|
"@typescript-eslint/visitor-keys@5.55.0":
|
||||||
version "5.55.0"
|
version "5.55.0"
|
||||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.55.0.tgz#01ad414fca8367706d76cdb94adf788dc5b664a2"
|
resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.55.0.tgz#01ad414fca8367706d76cdb94adf788dc5b664a2"
|
||||||
@ -1882,6 +1948,14 @@
|
|||||||
"@typescript-eslint/types" "5.55.0"
|
"@typescript-eslint/types" "5.55.0"
|
||||||
eslint-visitor-keys "^3.3.0"
|
eslint-visitor-keys "^3.3.0"
|
||||||
|
|
||||||
|
"@typescript-eslint/visitor-keys@5.56.0":
|
||||||
|
version "5.56.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.56.0.tgz#f19eb297d972417eb13cb69b35b3213e13cc214f"
|
||||||
|
integrity sha512-1mFdED7u5bZpX6Xxf5N9U2c18sb+8EvU3tyOIj6LQZ5OOvnmj8BVeNNP603OFPm5KkS1a7IvCIcwrdHXaEMG/Q==
|
||||||
|
dependencies:
|
||||||
|
"@typescript-eslint/types" "5.56.0"
|
||||||
|
eslint-visitor-keys "^3.3.0"
|
||||||
|
|
||||||
abort-controller@^3.0.0:
|
abort-controller@^3.0.0:
|
||||||
version "3.0.0"
|
version "3.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/abort-controller/-/abort-controller-3.0.0.tgz#eaf54d53b62bae4138e809ca225c8439a6efb392"
|
resolved "https://registry.yarnpkg.com/abort-controller/-/abort-controller-3.0.0.tgz#eaf54d53b62bae4138e809ca225c8439a6efb392"
|
||||||
@ -2144,6 +2218,13 @@ available-typed-arrays@^1.0.5:
|
|||||||
resolved "https://registry.yarnpkg.com/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz#92f95616501069d07d10edb2fc37d3e1c65123b7"
|
resolved "https://registry.yarnpkg.com/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz#92f95616501069d07d10edb2fc37d3e1c65123b7"
|
||||||
integrity sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==
|
integrity sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==
|
||||||
|
|
||||||
|
axios@^0.21.1:
|
||||||
|
version "0.21.4"
|
||||||
|
resolved "https://registry.yarnpkg.com/axios/-/axios-0.21.4.tgz#c67b90dc0568e5c1cf2b0b858c43ba28e2eda575"
|
||||||
|
integrity sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg==
|
||||||
|
dependencies:
|
||||||
|
follow-redirects "^1.14.0"
|
||||||
|
|
||||||
axios@^1.2.6, axios@^1.3.3:
|
axios@^1.2.6, axios@^1.3.3:
|
||||||
version "1.3.4"
|
version "1.3.4"
|
||||||
resolved "https://registry.yarnpkg.com/axios/-/axios-1.3.4.tgz#f5760cefd9cfb51fd2481acf88c05f67c4523024"
|
resolved "https://registry.yarnpkg.com/axios/-/axios-1.3.4.tgz#f5760cefd9cfb51fd2481acf88c05f67c4523024"
|
||||||
@ -3999,7 +4080,7 @@ flow-parser@^0.121.0:
|
|||||||
resolved "https://registry.yarnpkg.com/flow-parser/-/flow-parser-0.121.0.tgz#9f9898eaec91a9f7c323e9e992d81ab5c58e618f"
|
resolved "https://registry.yarnpkg.com/flow-parser/-/flow-parser-0.121.0.tgz#9f9898eaec91a9f7c323e9e992d81ab5c58e618f"
|
||||||
integrity sha512-1gIBiWJNR0tKUNv8gZuk7l9rVX06OuLzY9AoGio7y/JT4V1IZErEMEq2TJS+PFcw/y0RshZ1J/27VfK1UQzYVg==
|
integrity sha512-1gIBiWJNR0tKUNv8gZuk7l9rVX06OuLzY9AoGio7y/JT4V1IZErEMEq2TJS+PFcw/y0RshZ1J/27VfK1UQzYVg==
|
||||||
|
|
||||||
follow-redirects@^1.15.0:
|
follow-redirects@^1.14.0, follow-redirects@^1.15.0:
|
||||||
version "1.15.2"
|
version "1.15.2"
|
||||||
resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.2.tgz#b460864144ba63f2681096f274c4e57026da2c13"
|
resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.2.tgz#b460864144ba63f2681096f274c4e57026da2c13"
|
||||||
integrity sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==
|
integrity sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==
|
||||||
@ -5452,6 +5533,14 @@ lines-and-columns@^1.1.6:
|
|||||||
resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.2.4.tgz#eca284f75d2965079309dc0ad9255abb2ebc1632"
|
resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.2.4.tgz#eca284f75d2965079309dc0ad9255abb2ebc1632"
|
||||||
integrity sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==
|
integrity sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==
|
||||||
|
|
||||||
|
lnbits@^1.1.5:
|
||||||
|
version "1.1.5"
|
||||||
|
resolved "https://registry.yarnpkg.com/lnbits/-/lnbits-1.1.5.tgz#ffe4bec2c1abddba3ad5c1277fcad0956b2fe712"
|
||||||
|
integrity sha512-RPCBNsKKxlyQTHPKdU66iiXFBz6SuISVVkxJoSZY3Z+CBEzOu6xpgzZtQcZTbc1BCLqQc6HeK4qtfByKWjBTmg==
|
||||||
|
dependencies:
|
||||||
|
axios "^0.21.1"
|
||||||
|
typescript "^4.1.3"
|
||||||
|
|
||||||
lnurl-pay@^2.2.0:
|
lnurl-pay@^2.2.0:
|
||||||
version "2.2.0"
|
version "2.2.0"
|
||||||
resolved "https://registry.yarnpkg.com/lnurl-pay/-/lnurl-pay-2.2.0.tgz#aaf1d3f997d113ea54ca65f5d9de8020005c6e91"
|
resolved "https://registry.yarnpkg.com/lnurl-pay/-/lnurl-pay-2.2.0.tgz#aaf1d3f997d113ea54ca65f5d9de8020005c6e91"
|
||||||
@ -5751,10 +5840,10 @@ metro-react-native-babel-preset@0.72.3:
|
|||||||
"@babel/template" "^7.0.0"
|
"@babel/template" "^7.0.0"
|
||||||
react-refresh "^0.4.0"
|
react-refresh "^0.4.0"
|
||||||
|
|
||||||
metro-react-native-babel-preset@^0.75.0:
|
metro-react-native-babel-preset@^0.76.0:
|
||||||
version "0.75.1"
|
version "0.76.0"
|
||||||
resolved "https://registry.yarnpkg.com/metro-react-native-babel-preset/-/metro-react-native-babel-preset-0.75.1.tgz#370bb3bba3ca83b3be1d8b0ab628271c864491cd"
|
resolved "https://registry.yarnpkg.com/metro-react-native-babel-preset/-/metro-react-native-babel-preset-0.76.0.tgz#440a0e8965b2eb01afa391ef95575faeed67636b"
|
||||||
integrity sha512-a4Se/koIVsH+wmfWsSOiRpFLBSICJcbd6o1wv37QRoFSnH7mYXDOfYxNBZYX46PwN1QwmgR49Iwsef79JOaJMg==
|
integrity sha512-2sM6dy9uAbuQlg7l/VOdiudUUMFRkABJ1YLkZU6Fpqi/rJCXn4fbF0pO+TwCFbBYNIQBY50clv9RPvD2n64hXg==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@babel/core" "^7.20.0"
|
"@babel/core" "^7.20.0"
|
||||||
"@babel/plugin-proposal-async-generator-functions" "^7.0.0"
|
"@babel/plugin-proposal-async-generator-functions" "^7.0.0"
|
||||||
@ -7981,11 +8070,16 @@ typeforce@^1.11.3:
|
|||||||
resolved "https://registry.yarnpkg.com/typeforce/-/typeforce-1.18.0.tgz#d7416a2c5845e085034d70fcc5b6cc4a90edbfdc"
|
resolved "https://registry.yarnpkg.com/typeforce/-/typeforce-1.18.0.tgz#d7416a2c5845e085034d70fcc5b6cc4a90edbfdc"
|
||||||
integrity sha512-7uc1O8h1M1g0rArakJdf0uLRSSgFcYexrVoKo+bzJd32gd4gDy2L/Z+8/FjPnU9ydY3pEnVPtr9FyscYY60K1g==
|
integrity sha512-7uc1O8h1M1g0rArakJdf0uLRSSgFcYexrVoKo+bzJd32gd4gDy2L/Z+8/FjPnU9ydY3pEnVPtr9FyscYY60K1g==
|
||||||
|
|
||||||
typescript@^4.9.4:
|
typescript@^4.1.3:
|
||||||
version "4.9.5"
|
version "4.9.5"
|
||||||
resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.9.5.tgz#095979f9bcc0d09da324d58d03ce8f8374cbe65a"
|
resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.9.5.tgz#095979f9bcc0d09da324d58d03ce8f8374cbe65a"
|
||||||
integrity sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==
|
integrity sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==
|
||||||
|
|
||||||
|
typescript@^5.0.2:
|
||||||
|
version "5.0.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.0.2.tgz#891e1a90c5189d8506af64b9ef929fca99ba1ee5"
|
||||||
|
integrity sha512-wVORMBGO/FAs/++blGNeAVdbNKtIh1rbBL2EyQ1+J9lClJ93KiiKe8PmFIVdXhHcyv44SL9oglmfeSsndo0jRw==
|
||||||
|
|
||||||
uglify-es@^3.1.9:
|
uglify-es@^3.1.9:
|
||||||
version "3.3.9"
|
version "3.3.9"
|
||||||
resolved "https://registry.yarnpkg.com/uglify-es/-/uglify-es-3.3.9.tgz#0c1c4f0700bed8dbc124cdb304d2592ca203e677"
|
resolved "https://registry.yarnpkg.com/uglify-es/-/uglify-es-3.3.9.tgz#0c1c4f0700bed8dbc124cdb304d2592ca203e677"
|
||||||
|
Loading…
Reference in New Issue
Block a user