mirror of
https://github.com/minibits-cash/minibits_wallet.git
synced 2026-10-05 19:28:26 +00:00
Faster processing of Nostr Walle Connect commands, stability improvements.
This commit is contained in:
@@ -8,7 +8,14 @@ import notifee from '@notifee/react-native'
|
||||
import messaging from '@react-native-firebase/messaging'
|
||||
import {AppRegistry} from 'react-native'
|
||||
import { rootStoreInstance, setupRootStore } from './src/models'
|
||||
import {WalletTask, NotificationService, NWC_CHANNEL_ID, TASK_QUEUE_CHANNEL_ID} from './src/services'
|
||||
import {
|
||||
WalletTask,
|
||||
NotificationService,
|
||||
SWAP_ALL_TASK,
|
||||
TEST_TASK,
|
||||
SYNC_STATE_WITH_ALL_MINTS_TASK,
|
||||
HANDLE_NWC_REQUEST_TASK
|
||||
} from './src/services'
|
||||
import { log } from './src/services/logService'
|
||||
import App from './src/App'
|
||||
import {name as appName} from './app.json'
|
||||
@@ -17,38 +24,44 @@ function BootstrapApp() {
|
||||
return <App appName={appName} />
|
||||
}
|
||||
|
||||
// Process nwc commands as long running headless tasks
|
||||
// long running tasks
|
||||
notifee.registerForegroundService(async (notification) => {
|
||||
return new Promise(async (resolve) => {
|
||||
log.trace('[registerForegroundService] Foreground service running for task:', notification)
|
||||
|
||||
try {
|
||||
|
||||
if(notification.data.task === 'handleNwcRequestFromNotification') {
|
||||
if(notification.data.task === HANDLE_NWC_REQUEST_TASK) {
|
||||
log.debug(`[registerForegroundService] Submitting task ${HANDLE_NWC_REQUEST_TASK} to the queue.`)
|
||||
|
||||
const {nwcStore} = rootStoreInstance
|
||||
|
||||
// if an app is in killed state, state is not loaded
|
||||
if(nwcStore.all.length === 0) {
|
||||
await setupRootStore(rootStoreInstance)
|
||||
}
|
||||
}
|
||||
|
||||
nwcStore.handleNwcRequestFromNotification(notification.data.data).catch((e) => {
|
||||
log.error('[registerForegroundService]', e.message)
|
||||
})
|
||||
WalletTask.handleNwcRequestQueue({requestEvent: notification.data.data})
|
||||
}
|
||||
|
||||
if(notification.data.task === 'syncSpendableStateWithMints') {
|
||||
WalletTask.syncSpendableStateWithMints()
|
||||
if(notification.data.task === SYNC_STATE_WITH_ALL_MINTS_TASK) {
|
||||
log.debug(`[registerForegroundService] Submitting task ${SYNC_STATE_WITH_ALL_MINTS_TASK} to the queue.`)
|
||||
|
||||
WalletTask.syncStateWithAllMintsQueue({isPending: false})
|
||||
}
|
||||
|
||||
if(notification.data.task === 'sendAll') {
|
||||
WalletTask.sendAll()
|
||||
|
||||
if(notification.data.task === SWAP_ALL_TASK) {
|
||||
log.debug(`[registerForegroundService] Submitting task ${SWAP_ALL_TASK} to the queue.`)
|
||||
|
||||
WalletTask.swapAllQueue()
|
||||
}
|
||||
|
||||
/*if(notification.android.channelId === TASK_QUEUE_CHANNEL_ID) {
|
||||
|
||||
const tasksArray = notification.data.tasksToRun.split('|')
|
||||
|
||||
}*/
|
||||
if(notification.data.task === TEST_TASK) {
|
||||
log.debug(`[registerForegroundService] Submitting task ${TEST_TASK} to the queue.`)
|
||||
|
||||
WalletTask.testQueue()
|
||||
}
|
||||
|
||||
} catch(e) {
|
||||
log.error('[registerForegroundService]', e.message)
|
||||
|
||||
BIN
Binary file not shown.
+4
-4
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "minibits_wallet",
|
||||
"version": "0.1.10-beta.20",
|
||||
"version": "0.1.10-beta.21",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"android:clean": "cd android && ./gradlew clean",
|
||||
@@ -18,7 +18,7 @@
|
||||
"adb:inspect": "adb shell input keyevent 82",
|
||||
"postinstall": "patch-package --exclude 'nothing'"
|
||||
},
|
||||
"dependencies": {
|
||||
"dependencies": {
|
||||
"@cashu/cashu-ts": "minibits-cash/cashu-ts#2b51a7ba7a8461a0040359eecda37b98b603692c",
|
||||
"@fortawesome/fontawesome-svg-core": "^6.6.0",
|
||||
"@fortawesome/free-brands-svg-icons": "^6.6.0",
|
||||
@@ -76,11 +76,11 @@
|
||||
"react-native-svg": "^15.6.0",
|
||||
"react-native-tab-view": "^3.5.2",
|
||||
"react-native-url-polyfill": "^2.0.0",
|
||||
"simple-js-task-queue": "^0.2.2",
|
||||
"taskon": "^0.3.0",
|
||||
"text-encoding-polyfill": "^0.6.7",
|
||||
"util": "^0.12.5"
|
||||
},
|
||||
"devDependencies": {
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.20.0",
|
||||
"@babel/plugin-proposal-export-namespace-from": "^7.18.9",
|
||||
"@babel/preset-env": "^7.20.0",
|
||||
|
||||
@@ -18,8 +18,6 @@ export function Loading(props: ViewProps & { statusMessage?: string, textStyle?:
|
||||
|
||||
const $loading = (shiftedUp = false) => ({
|
||||
flex: 1,
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
backgroundColor: colors.dark.background,
|
||||
|
||||
+141
-175
@@ -18,6 +18,7 @@ import {
|
||||
NostrClient,
|
||||
NostrEvent,
|
||||
NostrUnsignedEvent,
|
||||
SyncQueue,
|
||||
TransactionTaskResult,
|
||||
WalletTask
|
||||
} from '../services'
|
||||
@@ -35,6 +36,8 @@ import { PaymentRequest } from './PaymentRequest'
|
||||
import { PaymentRequests } from './PaymentRequestsStore'
|
||||
import { MINIBITS_MINT_URL } from '@env'
|
||||
import { MintBalance } from './Mint'
|
||||
import { transferTask } from '../services/wallet/transferTask'
|
||||
import { topupTask } from '../services/wallet/topupTask'
|
||||
|
||||
type NwcError = {
|
||||
result_type: string,
|
||||
@@ -169,6 +172,7 @@ export const NwcConnectionModel = types.model('NwcConnection', {
|
||||
}
|
||||
|
||||
// notify errors
|
||||
|
||||
if((nwcResponse as NwcError).error) {
|
||||
let body = ''
|
||||
if(nwcResponse.result_type === 'pay_invoice') {
|
||||
@@ -189,147 +193,27 @@ export const NwcConnectionModel = types.model('NwcConnection', {
|
||||
|
||||
if(nwcResponse.result_type === 'lookup_invoice') {
|
||||
body = 'Lookup invoice error: '
|
||||
}
|
||||
}
|
||||
|
||||
yield NotificationService.createLocalNotification(
|
||||
`<b>${self.name}</b> - Nostr Wallet Connect`,
|
||||
body + (nwcResponse as NwcError).error.message,
|
||||
nwcPngUrl
|
||||
)
|
||||
|
||||
}
|
||||
|
||||
const enabled = yield NotificationService.areNotificationsEnabled()
|
||||
if(enabled) {
|
||||
yield NotificationService.createLocalNotification(
|
||||
`<b>${self.name}</b> - Nostr Wallet Connect`,
|
||||
body + (nwcResponse as NwcError).error.message,
|
||||
nwcPngUrl
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
NostrClient.publish(
|
||||
yield NostrClient.publish(
|
||||
responseEvent,
|
||||
self.connectionRelays
|
||||
)
|
||||
|
||||
NotificationService.stopForegroundService()
|
||||
|
||||
yield NotificationService.stopForegroundService()
|
||||
}),
|
||||
}))
|
||||
.actions(self => ({
|
||||
handleTransferTaskResult: flow(function* handleTransferTaskResult(result: TransactionTaskResult) {
|
||||
log.debug('[handleTransferTaskResult] Got transfer task result', {
|
||||
connection: self.name,
|
||||
meltQuote: result.meltQuote?.quote,
|
||||
txId: result.transaction?.id,
|
||||
})
|
||||
|
||||
if(result.meltQuote?.quote === self.lastMeltQuoteId) {
|
||||
log.error('Meltquote has been already handled, skipping...', {
|
||||
meltQuoteId: self.lastMeltQuoteId,
|
||||
caller: 'handleTransferTaskResult'
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
self.setLastMeltQuoteId(result.meltQuote?.quote)
|
||||
|
||||
let nwcResponse: NwcResponse | NwcError
|
||||
|
||||
if(result.transaction?.status === TransactionStatus.COMPLETED) {
|
||||
const updatedLimit = self.remainingDailyLimit -
|
||||
(result.transaction.amount + result.transaction.fee)
|
||||
|
||||
nwcResponse = {
|
||||
result_type: 'pay_invoice',
|
||||
result: {
|
||||
preimage: result.preimage,
|
||||
}
|
||||
} as NwcResponse
|
||||
|
||||
log.trace('[handleTransferTaskResult] Updating remainingLimit', {
|
||||
connection: self.name,
|
||||
beforeUpdate: self.remainingDailyLimit,
|
||||
afterUpdate: updatedLimit
|
||||
})
|
||||
|
||||
self.setRemainingDailyLimit(updatedLimit)
|
||||
|
||||
// notify completed payment
|
||||
const enabled = yield NotificationService.areNotificationsEnabled()
|
||||
if(enabled) {
|
||||
yield NotificationService.createLocalNotification(
|
||||
`<b>${self.name}</b> - Nostr Wallet Connect`,
|
||||
`Paid ${result.transaction.amount} SAT${result.transaction.fee > 0 ? ', fee ' + result.transaction.fee + ' SAT' : ''}. Remaining today's limit is ${self.remainingDailyLimit} SAT`,
|
||||
nwcPngUrl
|
||||
)
|
||||
}
|
||||
} else {
|
||||
nwcResponse = {
|
||||
result_type: 'pay_invoice',
|
||||
error: { code: 'INTERNAL', message: result.message}
|
||||
} as NwcError
|
||||
}
|
||||
|
||||
if(!result.nwcEvent) {
|
||||
log.error('Missing nwcEvent.', {caller: 'handleTransferTaskResult'})
|
||||
NotificationService.stopForegroundService()
|
||||
return
|
||||
}
|
||||
|
||||
yield self.sendResponse(nwcResponse, result.nwcEvent)
|
||||
}),
|
||||
handleTopupTaskResult: flow(function* handleTopupTaskResult(result: TransactionTaskResult) {
|
||||
log.debug('Got topup task result', {
|
||||
connection: self.name,
|
||||
encodedInvoice: result.encodedInvoice,
|
||||
caller: 'handleTopupTaskResult'
|
||||
})
|
||||
|
||||
if(!result.nwcEvent) {
|
||||
log.error('Missing nwcEvent.', {caller: 'handleTopupTaskResult'})
|
||||
return
|
||||
}
|
||||
|
||||
let nwcResponse: NwcResponse | NwcError
|
||||
|
||||
if(result.paymentRequest) {
|
||||
const pr: PaymentRequest = result.paymentRequest
|
||||
|
||||
nwcResponse = {
|
||||
result_type: 'make_invoice',
|
||||
result: {
|
||||
type: 'incoming',
|
||||
invoice: pr.encodedInvoice,
|
||||
description: pr.description,
|
||||
payment_hash: pr.paymentHash,
|
||||
amount: pr.invoicedAmount * 1000,
|
||||
fees_paid: 0,
|
||||
created_at: Math.floor(pr.createdAt!.getTime() / 1000),
|
||||
expires_at: Math.floor(pr.expiresAt!.getTime() / 1000),
|
||||
preimage: null,
|
||||
settled_at: null
|
||||
} as NwcTransaction
|
||||
} as NwcResponse
|
||||
|
||||
// notify created topup
|
||||
const enabled = yield NotificationService.areNotificationsEnabled()
|
||||
if(enabled) {
|
||||
yield NotificationService.stopForegroundService()
|
||||
|
||||
yield NotificationService.createLocalNotification(
|
||||
`<b>${self.name}</b> - Nostr Wallet Connect`,
|
||||
`Invoice for ${result.paymentRequest.invoicedAmount} SATS has been created.`,
|
||||
nwcPngUrl
|
||||
)
|
||||
}
|
||||
} else {
|
||||
nwcResponse = {
|
||||
result_type: 'make_invoice',
|
||||
error: { code: 'INTERNAL', message: result.message}
|
||||
} as NwcError
|
||||
}
|
||||
|
||||
yield self.sendResponse(nwcResponse, result.nwcEvent)
|
||||
})
|
||||
}))
|
||||
.actions(self => ({
|
||||
handleGetInfo (nwcRequest: NwcRequest): NwcResponse {
|
||||
const nwcResponse = {
|
||||
const nwcResponse: NwcResponse = {
|
||||
result_type: nwcRequest.method,
|
||||
result: {
|
||||
alias: 'Minibits',
|
||||
@@ -369,7 +253,7 @@ export const NwcConnectionModel = types.model('NwcConnection', {
|
||||
} as NwcTransaction
|
||||
})
|
||||
|
||||
const nwcResponse = {
|
||||
const nwcResponse: NwcResponse = {
|
||||
result_type: nwcRequest.method,
|
||||
result: {
|
||||
transactions
|
||||
@@ -389,7 +273,7 @@ export const NwcConnectionModel = types.model('NwcConnection', {
|
||||
resultBalanceMsat = 0
|
||||
}
|
||||
|
||||
const nwcResponse = {
|
||||
const nwcResponse: NwcResponse = {
|
||||
result_type: nwcRequest.method,
|
||||
result: {
|
||||
balance: resultBalanceMsat
|
||||
@@ -417,14 +301,56 @@ export const NwcConnectionModel = types.model('NwcConnection', {
|
||||
} as NwcError
|
||||
}
|
||||
|
||||
yield WalletTask.topup(
|
||||
const result = yield topupTask(
|
||||
mintBalance,
|
||||
roundUp(amontMsat / 1000, 0),
|
||||
'sat',
|
||||
description,
|
||||
undefined,
|
||||
requestEvent
|
||||
)
|
||||
)
|
||||
|
||||
log.debug('Got topup task result', {
|
||||
connection: self.name,
|
||||
encodedInvoice: result.encodedInvoice,
|
||||
caller: 'handleTopupTaskResult'
|
||||
})
|
||||
|
||||
let nwcResponse: NwcResponse | NwcError
|
||||
|
||||
if(result.paymentRequest) {
|
||||
const pr: PaymentRequest = result.paymentRequest
|
||||
|
||||
nwcResponse = {
|
||||
result_type: 'make_invoice',
|
||||
result: {
|
||||
type: 'incoming',
|
||||
invoice: pr.encodedInvoice,
|
||||
description: pr.description,
|
||||
payment_hash: pr.paymentHash,
|
||||
amount: pr.invoicedAmount * 1000,
|
||||
fees_paid: 0,
|
||||
created_at: Math.floor(pr.createdAt!.getTime() / 1000),
|
||||
expires_at: Math.floor(pr.expiresAt!.getTime() / 1000),
|
||||
preimage: null,
|
||||
settled_at: null
|
||||
} as NwcTransaction
|
||||
} as NwcResponse
|
||||
|
||||
yield NotificationService.createLocalNotification(
|
||||
`<b>${self.name}</b> - Nostr Wallet Connect`,
|
||||
`Invoice for ${result.paymentRequest.invoicedAmount} SATS has been created.`,
|
||||
nwcPngUrl
|
||||
)
|
||||
|
||||
} else {
|
||||
nwcResponse = {
|
||||
result_type: 'make_invoice',
|
||||
error: { code: 'INTERNAL', message: result.message}
|
||||
} as NwcError
|
||||
}
|
||||
|
||||
return nwcResponse
|
||||
}),
|
||||
handleLookupInvoice(nwcRequest: NwcRequest) {
|
||||
const paymentRequestsStore = self.getPaymentRequestsStore()
|
||||
@@ -490,13 +416,11 @@ export const NwcConnectionModel = types.model('NwcConnection', {
|
||||
const feeReserve = Math.max(MIN_LIGHTNING_FEE, amountToPay * LIGHTNING_FEE_PERCENT / 100)
|
||||
const totalAmountToPay = amountToPay + feeReserve
|
||||
|
||||
let mintBalance: MintBalance | undefined = undefined
|
||||
let isMinibitsMintSelected: boolean = false
|
||||
let mintBalance: MintBalance | undefined = undefined
|
||||
const minibitsBalance = proofsStore.getMintBalance(MINIBITS_MINT_URL)
|
||||
|
||||
if(minibitsBalance && minibitsBalance.balances.sat! >= totalAmountToPay) {
|
||||
mintBalance = minibitsBalance
|
||||
isMinibitsMintSelected = true
|
||||
mintBalance = minibitsBalance
|
||||
} else {
|
||||
mintBalance = proofsStore.getMintBalanceWithMaxBalance('sat')
|
||||
}
|
||||
@@ -525,7 +449,7 @@ export const NwcConnectionModel = types.model('NwcConnection', {
|
||||
encoded,
|
||||
)
|
||||
|
||||
WalletTask.transfer(
|
||||
const result = yield transferTask(
|
||||
mintBalance,
|
||||
amountToPay,
|
||||
'sat',
|
||||
@@ -536,11 +460,51 @@ export const NwcConnectionModel = types.model('NwcConnection', {
|
||||
requestEvent
|
||||
)
|
||||
|
||||
if(result.meltQuote?.quote === self.lastMeltQuoteId) {
|
||||
throw new AppError(Err.ALREADY_EXISTS_ERROR, 'Already processed', {quote: result.meltQuote?.quote})
|
||||
}
|
||||
|
||||
self.setLastMeltQuoteId(result.meltQuote?.quote)
|
||||
|
||||
let nwcResponse: NwcResponse | NwcError
|
||||
|
||||
if(result.transaction?.status === TransactionStatus.COMPLETED) {
|
||||
const updatedLimit = self.remainingDailyLimit -
|
||||
(result.transaction.amount + result.transaction.fee)
|
||||
|
||||
nwcResponse = {
|
||||
result_type: 'pay_invoice',
|
||||
result: {
|
||||
preimage: result.preimage,
|
||||
}
|
||||
} as NwcResponse
|
||||
|
||||
log.trace('[handleTransferTaskResult] Updating remainingLimit', {
|
||||
connection: self.name,
|
||||
beforeUpdate: self.remainingDailyLimit,
|
||||
afterUpdate: updatedLimit
|
||||
})
|
||||
|
||||
self.setRemainingDailyLimit(updatedLimit)
|
||||
|
||||
yield NotificationService.createLocalNotification(
|
||||
`<b>${self.name}</b> - Nostr Wallet Connect`,
|
||||
`Paid ${result.transaction.amount} SAT${result.transaction.fee > 0 ? ', fee ' + result.transaction.fee + ' SAT' : ''}. Remaining today's limit is ${self.remainingDailyLimit} SAT`,
|
||||
nwcPngUrl
|
||||
)
|
||||
|
||||
} else {
|
||||
nwcResponse = {
|
||||
result_type: 'pay_invoice',
|
||||
error: { code: 'INTERNAL', message: result.message}
|
||||
} as NwcError
|
||||
}
|
||||
|
||||
return nwcResponse
|
||||
|
||||
} catch (e: any) {
|
||||
log.error(`[NwcConnection.handlePayInvoice] ${e.message}`)
|
||||
|
||||
yield NotificationService.stopForegroundService()
|
||||
|
||||
|
||||
return {
|
||||
result_type: nwcRequest.method,
|
||||
error: { code: 'INTERNAL', message: e.message}
|
||||
@@ -549,7 +513,7 @@ export const NwcConnectionModel = types.model('NwcConnection', {
|
||||
})
|
||||
}))
|
||||
.actions(self => ({
|
||||
handleRequest: flow(function* handleRequest(requestEvent: NostrEvent, decryptedNwcRequest?: NwcRequest) {
|
||||
handleNwcRequestTask: flow(function* handleNwcRequestTask(requestEvent: NostrEvent, decryptedNwcRequest?: NwcRequest) {
|
||||
let nwcRequest: NwcRequest
|
||||
if(!decryptedNwcRequest) {
|
||||
const decryptedContent = yield NostrClient.decryptNip04(requestEvent.pubkey, requestEvent.content)
|
||||
@@ -575,25 +539,12 @@ export const NwcConnectionModel = types.model('NwcConnection', {
|
||||
break
|
||||
case 'make_invoice':
|
||||
nwcResponse = yield self.handleMakeInvoice(nwcRequest, requestEvent) as Promise<NwcError | undefined>
|
||||
|
||||
// no early error, topup initiated, register topup result event handler and exit
|
||||
if(!nwcResponse) {
|
||||
EventEmitter.on('ev_topupTask_result', self.handleTopupTaskResult)
|
||||
return
|
||||
}
|
||||
break
|
||||
case 'lookup_invoice':
|
||||
nwcResponse = self.handleLookupInvoice(nwcRequest)
|
||||
break
|
||||
case 'pay_invoice':
|
||||
// only early errors are immediately returned
|
||||
case 'pay_invoice':
|
||||
nwcResponse = yield self.handlePayInvoice(nwcRequest, requestEvent) as Promise<NwcError | undefined>
|
||||
|
||||
// no early error, transfer initiated, register transfer result event handler and exit
|
||||
if(!nwcResponse) {
|
||||
EventEmitter.on('ev_transferTask_result', self.handleTransferTaskResult)
|
||||
return
|
||||
}
|
||||
break
|
||||
default:
|
||||
const message = `NWC method ${nwcRequest.method} is unknown or not yet supported.`
|
||||
@@ -711,7 +662,7 @@ export const NwcStoreModel = types
|
||||
log.debug('[remove]', 'Connection removed from NwcStore')
|
||||
}
|
||||
},
|
||||
receiveNwcEvents () {
|
||||
receiveNwcEventsQueue () {
|
||||
log.trace('[receiveNwcEvents] start listening for NWC events', {
|
||||
walletPubkey: self.walletPubkey
|
||||
})
|
||||
@@ -754,8 +705,13 @@ export const NwcStoreModel = types
|
||||
if(!targetConnection) {
|
||||
throw new AppError(Err.VALIDATION_ERROR, 'Missing connection matching event pubkey', {pubkey: event.pubkey})
|
||||
}
|
||||
// dispatch to correct connection
|
||||
targetConnection.handleRequest(event)
|
||||
|
||||
// dispatch to correct connection, process over sync queue
|
||||
const now = new Date().getTime()
|
||||
SyncQueue.addTask(
|
||||
`handleNwcRequestTask-${now}`,
|
||||
async () => await targetConnection.handleNwcRequestTask(event)
|
||||
)
|
||||
},
|
||||
oneose() {
|
||||
log.trace('[receiveNwcEvents]', `Eose: Got ${eventsBatch.length} NWC events`)
|
||||
@@ -768,7 +724,7 @@ export const NwcStoreModel = types
|
||||
return
|
||||
}
|
||||
},
|
||||
handleNwcRequestFromNotification: flow(function* handleNwcRequestFromNotification(event: NostrEvent, decryptedNwcRequest: NwcRequest) {
|
||||
handleNwcRequestTask: flow(function* handleNwcRequestTask(event: NostrEvent, decryptedNwcRequest?: NwcRequest) {
|
||||
// find connection the nwc request is sent to
|
||||
const targetConnection = self.nwcConnections.find(c =>
|
||||
c.connectionPubkey === event.pubkey
|
||||
@@ -776,21 +732,31 @@ export const NwcStoreModel = types
|
||||
|
||||
if(!targetConnection) {
|
||||
log.error('[handleNwcRequestFromNotification] Missing connection matching event pubkey.', {pubkey: event.pubkey})
|
||||
// notify created topup
|
||||
const enabled = yield NotificationService.areNotificationsEnabled()
|
||||
if(enabled) {
|
||||
yield NotificationService.stopForegroundService()
|
||||
|
||||
yield NotificationService.createLocalNotification(
|
||||
`<b>Nostr Wallet Connect</b> error`,
|
||||
`Your wallet has received a NWC command, but could not find related NWC connection to handle it.`,
|
||||
nwcPngUrl
|
||||
)
|
||||
}
|
||||
|
||||
yield NotificationService.stopForegroundService()
|
||||
yield NotificationService.createLocalNotification(
|
||||
`<b>Nostr Wallet Connect</b> error`,
|
||||
`Your wallet has received a NWC command, but could not find related NWC connection to handle it.`,
|
||||
nwcPngUrl
|
||||
)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
yield targetConnection.handleRequest(event, decryptedNwcRequest)
|
||||
if(!event) {
|
||||
log.error('[handleNwcRequestFromNotification] Missing connection matching event pubkey.')
|
||||
|
||||
yield NotificationService.stopForegroundService()
|
||||
yield NotificationService.createLocalNotification(
|
||||
`<b>Nostr Wallet Connect</b> error`,
|
||||
`Your wallet has received a NWC command, but could not retrieve the required data.`,
|
||||
nwcPngUrl
|
||||
)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
yield targetConnection.handleNwcRequestTask(event, decryptedNwcRequest)
|
||||
})
|
||||
}))
|
||||
.views(self => ({
|
||||
|
||||
+476
-532
File diff suppressed because it is too large
Load Diff
@@ -36,6 +36,7 @@ import numbro from 'numbro'
|
||||
import { TranItem } from './TranDetailScreen'
|
||||
import { translate } from '../i18n'
|
||||
import { Token, getDecodedToken } from '@cashu/cashu-ts'
|
||||
import { RECEIVE_OFFLINE_PREPARE_TASK, RECEIVE_TASK } from '../services/wallet/receiveTask'
|
||||
|
||||
export enum ReceiveOption {
|
||||
// CREATE_AND_SEND_PAYMENT_REQUEST = 'CREATE_AND_SEND_PAYMENT_REQUEST',
|
||||
@@ -125,14 +126,14 @@ export const ReceiveScreen: FC<WalletStackScreenProps<'Receive'>> = observer(
|
||||
|
||||
|
||||
if(isReceiveTaskSentToQueue) {
|
||||
EventEmitter.on('ev_receiveTask_result', handleReceiveTaskResult)
|
||||
EventEmitter.on('ev_receiveOfflinePrepareTask_result', handleReceiveTaskResult)
|
||||
EventEmitter.on(`ev_${RECEIVE_TASK}_result`, handleReceiveTaskResult)
|
||||
EventEmitter.on(`ev_${RECEIVE_OFFLINE_PREPARE_TASK}_result`, handleReceiveTaskResult)
|
||||
}
|
||||
|
||||
// Unsubscribe from the 'sendCompleted' event on component unmount
|
||||
return () => {
|
||||
EventEmitter.off('ev_receiveTask_result', handleReceiveTaskResult)
|
||||
EventEmitter.off('ev_receiveOfflinePrepareTask_result', handleReceiveTaskResult)
|
||||
EventEmitter.off(`ev_${RECEIVE_TASK}_result`, handleReceiveTaskResult)
|
||||
EventEmitter.off(`ev_${RECEIVE_OFFLINE_PREPARE_TASK}_result`, handleReceiveTaskResult)
|
||||
}
|
||||
}, [isReceiveTaskSentToQueue])
|
||||
|
||||
@@ -208,24 +209,12 @@ export const ReceiveScreen: FC<WalletStackScreenProps<'Receive'>> = observer(
|
||||
const amountToReceiveInt = round(toNumber(amountToReceive) * getCurrency(unit).precision, 0)
|
||||
const proofsCount = token!.proofs.length
|
||||
|
||||
if(proofsCount > MAX_SWAP_INPUT_SIZE) {
|
||||
|
||||
WalletTask.receiveBatch(
|
||||
token as Token,
|
||||
amountToReceiveInt,
|
||||
memo,
|
||||
encodedToken as string,
|
||||
)
|
||||
|
||||
} else {
|
||||
|
||||
WalletTask.receive(
|
||||
token as Token,
|
||||
amountToReceiveInt,
|
||||
memo,
|
||||
encodedToken as string,
|
||||
)
|
||||
}
|
||||
WalletTask.receiveQueue(
|
||||
token as Token,
|
||||
amountToReceiveInt,
|
||||
memo,
|
||||
encodedToken as string,
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -262,7 +251,7 @@ export const ReceiveScreen: FC<WalletStackScreenProps<'Receive'>> = observer(
|
||||
|
||||
const amountToReceiveInt = round(toNumber(amountToReceive) * getCurrency(unit).precision, 0)
|
||||
|
||||
WalletTask.receiveOfflinePrepare(
|
||||
WalletTask.receiveOfflinePrepareQueue(
|
||||
token as Token,
|
||||
amountToReceiveInt,
|
||||
memo,
|
||||
|
||||
@@ -19,7 +19,7 @@ import {useHeader} from '../utils/useHeader'
|
||||
import {log} from '../services/logService'
|
||||
import AppError from '../utils/AppError'
|
||||
import { useStores } from '../models'
|
||||
import { SyncStateTaskResult, WalletTask } from '../services/walletService'
|
||||
import { SYNC_STATE_WITH_ALL_MINTS_TASK, SyncStateTaskResult } from '../services/walletService'
|
||||
import EventEmitter from '../utils/eventEmitter'
|
||||
import { translate } from '../i18n'
|
||||
import { NotificationService, TASK_QUEUE_CHANNEL_ID, TASK_QUEUE_CHANNEL_NAME } from '../services/notificationService'
|
||||
@@ -38,8 +38,6 @@ export const RecoveryOptionsScreen: FC<AppStackScreenProps<'RecoveryOptions'>> =
|
||||
const [error, setError] = useState<AppError | undefined>()
|
||||
const [info, setInfo] = useState('')
|
||||
const [isSyncStateSentToQueue, setIsSyncStateSentToQueue] = useState<boolean>(false)
|
||||
const [totalSpentAmount, setTotalSpentAmount] = useState<number>(0)
|
||||
const [syncErrors, setSyncErrors] = useState<AppError[]>([])
|
||||
|
||||
|
||||
useEffect(() => {
|
||||
@@ -49,70 +47,20 @@ export const RecoveryOptionsScreen: FC<AppStackScreenProps<'RecoveryOptions'>> =
|
||||
if (!isSyncStateSentToQueue) { return false }
|
||||
|
||||
setIsLoading(false)
|
||||
|
||||
// runs per each mint
|
||||
if (result.error && result.error) {
|
||||
setSyncErrors(prev => [...prev, result.error!])
|
||||
}
|
||||
|
||||
if (result && result.transactionStateUpdates.length > 0) {
|
||||
|
||||
log.trace('[removeSpentByMintTaskResult]', {transactionStateUpdates: result.transactionStateUpdates})
|
||||
|
||||
let totalSpentPerMint = 0
|
||||
|
||||
for (const update of result.transactionStateUpdates) {
|
||||
if(update.spentByMintAmount) {
|
||||
totalSpentPerMint += update.spentByMintAmount
|
||||
}
|
||||
}
|
||||
setTotalSpentAmount(prev => prev + totalSpentPerMint)
|
||||
}
|
||||
|
||||
if(totalSpentAmount === 0 && result.transactionStateUpdates.length === 0) {
|
||||
setInfo(`No spent ecash from ${new URL(result.mintUrl).hostname}.`)
|
||||
}
|
||||
setInfo(result.message)
|
||||
}
|
||||
|
||||
if(isSyncStateSentToQueue) {
|
||||
EventEmitter.on('ev__syncStateWithMintTask_result', removeSpentByMintTaskResult)
|
||||
EventEmitter.on(`ev_${SYNC_STATE_WITH_ALL_MINTS_TASK}_result`, removeSpentByMintTaskResult)
|
||||
}
|
||||
|
||||
return () => {
|
||||
EventEmitter.off('ev__syncStateWithMintTask_result', removeSpentByMintTaskResult)
|
||||
NotificationService.stopForegroundService()
|
||||
EventEmitter.off(`ev_${SYNC_STATE_WITH_ALL_MINTS_TASK}_result`, removeSpentByMintTaskResult)
|
||||
}
|
||||
}, [isSyncStateSentToQueue])
|
||||
|
||||
|
||||
|
||||
useEffect(() => {
|
||||
const showSpentEcashResult = () => {
|
||||
log.trace('[showSpentEcashResult] got update', {totalSpentAmount})
|
||||
|
||||
if (totalSpentAmount === 0) { return false }
|
||||
|
||||
setInfo(`Removed spent ecash with amount ${totalSpentAmount}.`)
|
||||
}
|
||||
|
||||
showSpentEcashResult()
|
||||
|
||||
}, [totalSpentAmount])
|
||||
|
||||
|
||||
useEffect(() => {
|
||||
const showSyncErrors = () => {
|
||||
log.trace('[showSyncErrors] got update', {syncErrors})
|
||||
|
||||
if (syncErrors.length === 0) { return false }
|
||||
|
||||
setError(syncErrors[syncErrors.length - 1])
|
||||
}
|
||||
|
||||
showSyncErrors()
|
||||
|
||||
}, [syncErrors])
|
||||
|
||||
const gotoSeedRecovery = function () {
|
||||
navigation.navigate('SeedRecovery')
|
||||
}
|
||||
@@ -131,11 +79,10 @@ export const RecoveryOptionsScreen: FC<AppStackScreenProps<'RecoveryOptions'>> =
|
||||
const checkSpent = async function () {
|
||||
setIsLoading(true)
|
||||
setIsSyncStateSentToQueue(true)
|
||||
|
||||
// long task background processing
|
||||
notifee.displayNotification({
|
||||
|
||||
await notifee.displayNotification({
|
||||
title: TASK_QUEUE_CHANNEL_NAME,
|
||||
body: 'Processing pending transactions...',
|
||||
body: 'Cleaning spent ecash from spendable balance...',
|
||||
android: {
|
||||
channelId: TASK_QUEUE_CHANNEL_ID,
|
||||
asForegroundService: true,
|
||||
@@ -145,9 +92,8 @@ export const RecoveryOptionsScreen: FC<AppStackScreenProps<'RecoveryOptions'>> =
|
||||
indeterminate: true,
|
||||
},
|
||||
},
|
||||
data: {task: 'syncSpendableStateWithMints'},
|
||||
})
|
||||
// WalletTask.syncSpendableStateWithMints()
|
||||
data: {task: SYNC_STATE_WITH_ALL_MINTS_TASK},
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -37,7 +37,7 @@ import {
|
||||
} from '../components'
|
||||
import {TransactionStatus, Transaction} from '../models/Transaction'
|
||||
import {useStores} from '../models'
|
||||
import {NostrClient, SyncStateTaskResult, TransactionTaskResult, WalletTask} from '../services'
|
||||
import {NostrClient, SYNC_STATE_WITH_MINT_TASK, SyncStateTaskResult, TransactionTaskResult, WalletTask} from '../services'
|
||||
import {log} from '../services/logService'
|
||||
import AppError, {Err} from '../utils/AppError'
|
||||
import {translate} from '../i18n'
|
||||
@@ -60,6 +60,7 @@ import { MemoInputCard } from '../components/MemoInputCard'
|
||||
import { PaymentRequest as CashuPaymentRequest, PaymentRequestTransport, PaymentRequestTransportType, decodePaymentRequest, getDecodedToken } from '@cashu/cashu-ts'
|
||||
import { ProfilePointer } from 'nostr-tools/nip19'
|
||||
import { MINIBITS_NIP05_DOMAIN } from '@env'
|
||||
import { SEND_TASK } from '../services/wallet/sendTask'
|
||||
|
||||
export enum SendOption {
|
||||
SEND_TOKEN = 'SEND_TOKEN',
|
||||
@@ -447,12 +448,12 @@ export const SendScreen: FC<WalletStackScreenProps<'Send'>> = observer(
|
||||
|
||||
// Subscribe to the 'sendCompleted' event
|
||||
if(isSendTaskSentToQueue) {
|
||||
EventEmitter.on('ev_sendTask_result', handleSendTaskResult)
|
||||
EventEmitter.on(`ev_${SEND_TASK}_result`, handleSendTaskResult)
|
||||
}
|
||||
|
||||
// Unsubscribe from the 'sendCompleted' event on component unmount
|
||||
return () => {
|
||||
EventEmitter.off('ev_sendTask_result', handleSendTaskResult)
|
||||
EventEmitter.off(`ev_${SEND_TASK}_result`, handleSendTaskResult)
|
||||
}
|
||||
}, [isSendTaskSentToQueue])
|
||||
|
||||
@@ -508,12 +509,12 @@ export const SendScreen: FC<WalletStackScreenProps<'Send'>> = observer(
|
||||
|
||||
// Subscribe to the '_syncStateWithMintTask' event
|
||||
if(transactionId) {
|
||||
EventEmitter.on('ev__syncStateWithMintTask_result', handleSendCompleted)
|
||||
EventEmitter.on(`ev_${SYNC_STATE_WITH_MINT_TASK}_result`, handleSendCompleted)
|
||||
}
|
||||
|
||||
// Unsubscribe from the '_syncStateWithMintTask' event on component unmount
|
||||
return () => {
|
||||
EventEmitter.off('ev__syncStateWithMintTask_result', handleSendCompleted)
|
||||
EventEmitter.off(`ev_${SYNC_STATE_WITH_MINT_TASK}_result`, handleSendCompleted)
|
||||
}
|
||||
}, [transactionId])
|
||||
|
||||
@@ -603,7 +604,7 @@ export const SendScreen: FC<WalletStackScreenProps<'Send'>> = observer(
|
||||
|
||||
const amountToSendInt = round(toNumber(amountToSend) * getCurrency(unitRef.current).precision, 0)
|
||||
|
||||
WalletTask.send(
|
||||
WalletTask.sendQueue(
|
||||
mintBalanceToSendFrom as MintBalance,
|
||||
amountToSendInt,
|
||||
unitRef.current,
|
||||
|
||||
@@ -29,6 +29,7 @@ import {
|
||||
import {TransactionStatus, Transaction} from '../models/Transaction'
|
||||
import {useStores} from '../models'
|
||||
import {
|
||||
HANDLE_PENDING_TOPUP_TASK,
|
||||
NostrClient,
|
||||
NostrProfile,
|
||||
TransactionTaskResult,
|
||||
@@ -64,6 +65,7 @@ import numbro from 'numbro'
|
||||
import {MintListItem} from './Mints/MintListItem'
|
||||
import {TranItem} from './TranDetailScreen'
|
||||
import {translate} from '../i18n'
|
||||
import { TOPUP_TASK } from '../services/wallet/topupTask'
|
||||
|
||||
if (
|
||||
Platform.OS === 'android' &&
|
||||
@@ -303,11 +305,11 @@ export const TopupScreen: FC<WalletStackScreenProps<'Topup'>> = observer(
|
||||
}
|
||||
|
||||
// Subscribe to the 'sendCompleted' event
|
||||
EventEmitter.on('ev_topupTask_result', handleTopupTaskResult)
|
||||
EventEmitter.on(`ev_${TOPUP_TASK}_result`, handleTopupTaskResult)
|
||||
|
||||
// Unsubscribe from the 'sendCompleted' event on component unmount
|
||||
return () => {
|
||||
EventEmitter.off('ev_topupTask_result', handleTopupTaskResult)
|
||||
EventEmitter.off(`ev_${TOPUP_TASK}_result`, handleTopupTaskResult)
|
||||
}
|
||||
}, [isTopupTaskSentToQueue])
|
||||
|
||||
@@ -346,13 +348,13 @@ export const TopupScreen: FC<WalletStackScreenProps<'Topup'>> = observer(
|
||||
}
|
||||
|
||||
EventEmitter.on(
|
||||
'ev__handlePendingTopupTask_result',
|
||||
`ev_${HANDLE_PENDING_TOPUP_TASK}_result`,
|
||||
handlePendingTopupTaskResult,
|
||||
)
|
||||
|
||||
return () => {
|
||||
EventEmitter.off(
|
||||
'ev__handlePendingTopupTask_result',
|
||||
`ev_${HANDLE_PENDING_TOPUP_TASK}_result`,
|
||||
handlePendingTopupTaskResult,
|
||||
)
|
||||
}
|
||||
@@ -470,7 +472,7 @@ export const TopupScreen: FC<WalletStackScreenProps<'Topup'>> = observer(
|
||||
0,
|
||||
)
|
||||
|
||||
WalletTask.topup(
|
||||
WalletTask.topupQueue(
|
||||
mintBalanceToTopup as MintBalance,
|
||||
amountToTopupInt,
|
||||
unit,
|
||||
|
||||
@@ -41,7 +41,7 @@ import {
|
||||
import AppError, {Err} from '../utils/AppError'
|
||||
import {log} from '../services/logService'
|
||||
import {isArray} from 'lodash'
|
||||
import {NostrClient, NostrEvent, NostrProfile, TransactionTaskResult, WalletTask} from '../services'
|
||||
import {HANDLE_PENDING_TOPUP_TASK, NostrClient, NostrEvent, NostrProfile, TransactionTaskResult, WalletTask} from '../services'
|
||||
import {Proof} from '../models/Proof'
|
||||
import useColorScheme from '../theme/useThemeColor'
|
||||
import useIsInternetReachable from '../utils/useIsInternetReachable'
|
||||
@@ -58,6 +58,8 @@ import { QRCodeBlock } from './Wallet/QRCode'
|
||||
import { MintListItem } from './Mints/MintListItem'
|
||||
import { Token, getDecodedToken } from '@cashu/cashu-ts'
|
||||
import { faTruckMedical } from '@fortawesome/free-solid-svg-icons'
|
||||
import { RECEIVE_OFFLINE_COMPLETE_TASK, RECEIVE_TASK } from '../services/wallet/receiveTask'
|
||||
import { REVERT_TASK } from '../services/wallet/revertTask'
|
||||
|
||||
if (Platform.OS === 'android' && UIManager.setLayoutAnimationEnabledExperimental) {
|
||||
UIManager.setLayoutAnimationEnabledExperimental(true)
|
||||
@@ -603,12 +605,12 @@ const ReceiveInfoBlock = function (props: {
|
||||
|
||||
// Subscribe to the 'receiveTask' event
|
||||
if(isReceiveTaskSentToQueue === true) {
|
||||
EventEmitter.on('ev_receiveTask_result', handleReceiveTaskResult)
|
||||
EventEmitter.on(`ev_${RECEIVE_TASK}_result`, handleReceiveTaskResult)
|
||||
}
|
||||
|
||||
// Unsubscribe from the 'receiveTask' event on component unmount
|
||||
return () => {
|
||||
EventEmitter.off('ev_receiveTask_result', handleReceiveTaskResult)
|
||||
EventEmitter.off(`ev_${RECEIVE_TASK}_result`, handleReceiveTaskResult)
|
||||
}
|
||||
}, [isReceiveTaskSentToQueue])
|
||||
|
||||
@@ -647,7 +649,7 @@ const ReceiveInfoBlock = function (props: {
|
||||
}
|
||||
|
||||
setIsReceiveTaskSentToQueue(true)
|
||||
WalletTask.receive(
|
||||
WalletTask.receiveQueue(
|
||||
tokenToRetry,
|
||||
amountToReceive,
|
||||
memo,
|
||||
@@ -886,12 +888,12 @@ const ReceiveOfflineInfoBlock = function (props: {
|
||||
|
||||
// Subscribe to the 'sendCompleted' event
|
||||
if(isReceiveOfflineCompleteTaskSentToQueue) {
|
||||
EventEmitter.on('ev_receiveOfflineCompleteTask_result', handleReceiveOfflineCompleteTaskResult)
|
||||
EventEmitter.on(`ev_${RECEIVE_OFFLINE_COMPLETE_TASK}_result`, handleReceiveOfflineCompleteTaskResult)
|
||||
}
|
||||
|
||||
// Unsubscribe from the 'sendCompleted' event on component unmount
|
||||
return () => {
|
||||
EventEmitter.off('ev_receiveOfflineCompleteTask_result', handleReceiveOfflineCompleteTaskResult)
|
||||
EventEmitter.off(`ev_${RECEIVE_OFFLINE_COMPLETE_TASK}_result`, handleReceiveOfflineCompleteTaskResult)
|
||||
}
|
||||
}, [isReceiveOfflineCompleteTaskSentToQueue])
|
||||
|
||||
@@ -902,7 +904,7 @@ const ReceiveOfflineInfoBlock = function (props: {
|
||||
const receiveOfflineComplete = async function () {
|
||||
setIsLoading(true)
|
||||
setIsReceiveOfflineCompleteTaskSentToQueue(true)
|
||||
WalletTask.receiveOfflineComplete(transaction.id!)
|
||||
WalletTask.receiveOfflineCompleteQueue(transaction.id!)
|
||||
}
|
||||
|
||||
const onGoBack = () => {
|
||||
@@ -1095,12 +1097,12 @@ const SendInfoBlock = function (props: {
|
||||
|
||||
// Subscribe to the 'sendCompleted' event
|
||||
if(isRevertTaskSentToQueue) {
|
||||
EventEmitter.on('ev_revertTask_result', handleRevertTaskResult)
|
||||
EventEmitter.on(`ev_${REVERT_TASK}_result`, handleRevertTaskResult)
|
||||
}
|
||||
|
||||
// Unsubscribe from the 'sendCompleted' event on component unmount
|
||||
return () => {
|
||||
EventEmitter.off('ev_revertTask_result', handleRevertTaskResult)
|
||||
EventEmitter.off(`ev_${REVERT_TASK}_result`, handleRevertTaskResult)
|
||||
}
|
||||
}, [isRevertTaskSentToQueue])
|
||||
|
||||
@@ -1135,7 +1137,7 @@ const SendInfoBlock = function (props: {
|
||||
})
|
||||
}
|
||||
|
||||
WalletTask.revert(transaction)
|
||||
WalletTask.revertQueue(transaction)
|
||||
setIsLoading(true)
|
||||
setIsRevertTaskSentToQueue(true)
|
||||
|
||||
@@ -1308,7 +1310,7 @@ const TopupInfoBlock = function (props: {
|
||||
setIsLoading(false)
|
||||
|
||||
// do not react to an active poller :)
|
||||
if(pollerExists(`handlePendingTopupTaskPoller-${result.paymentHash}`)) {
|
||||
if(pollerExists(`handlePendingTopupPoller-${result.paymentHash}`)) {
|
||||
return false
|
||||
}
|
||||
|
||||
@@ -1328,11 +1330,11 @@ const TopupInfoBlock = function (props: {
|
||||
}
|
||||
|
||||
// Subscribe to the 'sendCompleted' event
|
||||
EventEmitter.on('ev__handlePendingTopupTask_result', handlePendingTopupTaskResult)
|
||||
EventEmitter.on(`ev_${HANDLE_PENDING_TOPUP_TASK}_result`, handlePendingTopupTaskResult)
|
||||
|
||||
// Unsubscribe from the 'sendCompleted' event on component unmount
|
||||
return () => {
|
||||
EventEmitter.off('ev__handlePendingTopupTask_result', handlePendingTopupTaskResult)
|
||||
EventEmitter.off(`ev_${HANDLE_PENDING_TOPUP_TASK}_result`, handlePendingTopupTaskResult)
|
||||
}
|
||||
}, [isPendingTopupTaskSentToQueue]))
|
||||
|
||||
@@ -1348,7 +1350,7 @@ const TopupInfoBlock = function (props: {
|
||||
setIsLoading(true)
|
||||
|
||||
setIsPendingTopupTaskSentToQueue(true)
|
||||
WalletTask.handlePendingTopup(
|
||||
WalletTask.handlePendingTopupQueue(
|
||||
{paymentRequest}
|
||||
)
|
||||
|
||||
@@ -1895,7 +1897,7 @@ const getPaymentRequestToRetry = (
|
||||
const paymentRequest: PaymentRequest = pendingRecord.paymentRequest
|
||||
|
||||
if(!paymentRequest) {return undefined}
|
||||
if(pollerExists(`handlePendingTopupTaskPoller-${paymentRequest.paymentHash}`)) {return undefined}
|
||||
if(pollerExists(`handlePendingTopupPoller-${paymentRequest.paymentHash}`)) {return undefined}
|
||||
|
||||
// return paymentRequest to retry if wallet somehow failed to retreive proofs for paid invoice
|
||||
return paymentRequest
|
||||
|
||||
@@ -50,6 +50,7 @@ import { TranItem } from './TranDetailScreen'
|
||||
import useIsInternetReachable from '../utils/useIsInternetReachable'
|
||||
import { translate } from '../i18n'
|
||||
import { MemoInputCard } from '../components/MemoInputCard'
|
||||
import { TRANSFER_TASK } from '../services/wallet/transferTask'
|
||||
|
||||
|
||||
if (
|
||||
@@ -428,12 +429,12 @@ useEffect(() => {
|
||||
|
||||
// Subscribe to the task result event
|
||||
if(isTransferTaskSentToQueue) {
|
||||
EventEmitter.on('ev_transferTask_result', handleTransferTaskResult)
|
||||
EventEmitter.on(`ev_${TRANSFER_TASK}_result`, handleTransferTaskResult)
|
||||
}
|
||||
|
||||
// Unsubscribe from the task result event on component unmount
|
||||
return () => {
|
||||
EventEmitter.off('ev_transferTask_result', handleTransferTaskResult)
|
||||
EventEmitter.off(`ev_${TRANSFER_TASK}_result`, handleTransferTaskResult)
|
||||
}
|
||||
}, [isTransferTaskSentToQueue])
|
||||
|
||||
@@ -636,7 +637,7 @@ const transfer = async function () {
|
||||
|
||||
const amountToTransferInt = round(toNumber(amountToTransfer) * getCurrency(unit).precision, 0)
|
||||
|
||||
WalletTask.transfer(
|
||||
WalletTask.transferQueue(
|
||||
mintBalanceToTransferFrom,
|
||||
amountToTransferInt,
|
||||
unit,
|
||||
|
||||
@@ -42,7 +42,7 @@ import {useStores} from '../models'
|
||||
import {WalletStackScreenProps} from '../navigation'
|
||||
import {Mint, UnitBalance} from '../models/Mint'
|
||||
import {MintsByUnit} from '../models/MintsStore'
|
||||
import {log, NostrClient, WalletTaskResult} from '../services'
|
||||
import {HANDLE_CLAIM_TASK, HANDLE_RECEIVED_EVENT_TASK, log, NostrClient, WalletTaskResult} from '../services'
|
||||
import {Env} from '../utils/envtypes'
|
||||
import {Transaction} from '../models/Transaction'
|
||||
import {TransactionListItem} from './Transactions/TransactionListItem'
|
||||
@@ -64,7 +64,6 @@ import { CurrencyCode, MintUnit, MintUnitCurrencyPairs, convertToFromSats, getCu
|
||||
import { CurrencyAmount } from './Wallet/CurrencyAmount'
|
||||
import { LeftProfileHeader } from './ContactsScreen'
|
||||
import { getUnixTime } from 'date-fns/getUnixTime'
|
||||
import { minibitsPngIcon } from '../components/MinibitsIcon'
|
||||
|
||||
const deploymentKey = APP_ENV === Env.PROD ? CODEPUSH_PRODUCTION_DEPLOYMENT_KEY : CODEPUSH_STAGING_DEPLOYMENT_KEY
|
||||
const MINT_CHECK_INTERVAL = 60
|
||||
@@ -172,7 +171,7 @@ export const WalletScreen: FC<WalletScreenProps> = observer(
|
||||
}
|
||||
|
||||
// Only once on startup - Create websocket subscriptions to receive tokens or payment requests by NOSTR DMs
|
||||
WalletTask.receiveEventsFromRelays().catch(e => false)
|
||||
WalletTask.receiveEventsFromRelaysQueue()
|
||||
|
||||
// Set wallet tab to preferred unit
|
||||
const preferredUnit: MintUnit = userSettingsStore.preferredUnit
|
||||
@@ -185,7 +184,7 @@ export const WalletScreen: FC<WalletScreenProps> = observer(
|
||||
// go through websockets only if remote notifications not working as push data messages are
|
||||
// delivered even if notifications are disabled on device
|
||||
const isRemoteDataPushEnabled = walletProfileStore.device ? true : false
|
||||
if(!isRemoteDataPushEnabled) {nwcStore.receiveNwcEvents()}
|
||||
if(!isRemoteDataPushEnabled) {nwcStore.receiveNwcEventsQueue()}
|
||||
}
|
||||
|
||||
const handleReceivedEventTaskResult = async (result: WalletTaskResult) => {
|
||||
@@ -203,16 +202,16 @@ export const WalletScreen: FC<WalletScreenProps> = observer(
|
||||
}
|
||||
|
||||
Linking.addEventListener('url', handleDeeplink)
|
||||
EventEmitter.on('ev__handleReceivedEventTask_result', handleReceivedEventTaskResult)
|
||||
EventEmitter.on('ev__handleClaimTask_result', handleClaimTaskResult)
|
||||
EventEmitter.on(`ev_${HANDLE_RECEIVED_EVENT_TASK}_result`, handleReceivedEventTaskResult)
|
||||
EventEmitter.on(`ev_${HANDLE_CLAIM_TASK}_result`, handleClaimTaskResult)
|
||||
|
||||
|
||||
getInitialData()
|
||||
|
||||
// Unsubscribe from the task result event on component unmount
|
||||
return () => {
|
||||
EventEmitter.off('ev__handleReceivedEventTask_result', handleReceivedEventTaskResult)
|
||||
EventEmitter.off('ev__handleClaimTask_result', handleClaimTaskResult)
|
||||
EventEmitter.off(`ev_${HANDLE_RECEIVED_EVENT_TASK}_result`, handleReceivedEventTaskResult)
|
||||
EventEmitter.off(`ev_${HANDLE_CLAIM_TASK}_result`, handleClaimTaskResult)
|
||||
}
|
||||
|
||||
}, [])
|
||||
@@ -279,10 +278,10 @@ export const WalletScreen: FC<WalletScreenProps> = observer(
|
||||
if (nowInSec - lastMintCheckRef.current > MINT_CHECK_INTERVAL) {
|
||||
lastMintCheckRef.current = nowInSec
|
||||
|
||||
WalletTask.handleInFlight()
|
||||
WalletTask.handleClaim()
|
||||
WalletTask.syncPendingStateWithMints()
|
||||
WalletTask.handlePendingTopups()
|
||||
WalletTask.handleInFlightQueue()
|
||||
WalletTask.handleClaimQueue()
|
||||
WalletTask.syncStateWithAllMintsQueue({isPending: true})
|
||||
WalletTask.handlePendingTopupsQueue()
|
||||
|
||||
if(userSettingsStore.exchangeCurrency) {
|
||||
walletStore.refreshExchangeRate(userSettingsStore.exchangeCurrency)
|
||||
|
||||
@@ -97,10 +97,10 @@ const reconnectToRelays = async function () {
|
||||
// recreate subscriptions if all relays down
|
||||
if(isRefreshSubNeeded) {
|
||||
log.trace('[reconnectToRelays] Refreshing Nostr subscriptions')
|
||||
WalletTask.receiveEventsFromRelays().catch(e => false)
|
||||
WalletTask.receiveEventsFromRelaysQueue().catch(e => false)
|
||||
|
||||
if(!walletProfileStore.device) {
|
||||
nwcStore.receiveNwcEvents()
|
||||
nwcStore.receiveNwcEventsQueue()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@ import AppError, { Err } from '../utils/AppError'
|
||||
import { Platform } from 'react-native'
|
||||
import { rootStoreInstance, setupRootStore } from '../models'
|
||||
import { NwcRequest, nwcPngUrl } from '../models/NwcStore';
|
||||
import { HANDLE_NWC_REQUEST_TASK } from './walletService'
|
||||
|
||||
export type NotifyReceiveToLnurlData = {
|
||||
type: 'NotifyReceiveToLnurlData',
|
||||
@@ -36,7 +37,10 @@ const NWC_CHANNEL_ID = 'nwcDefault';
|
||||
const NWC_CHANNEL_NAME = 'Minibits NWC payment'
|
||||
|
||||
export const TASK_QUEUE_CHANNEL_ID = 'internalDefault'
|
||||
export const TASK_QUEUE_CHANNEL_NAME = 'Minibits internal tasks'
|
||||
export const TASK_QUEUE_CHANNEL_NAME = 'Minibits tasks'
|
||||
|
||||
export const TEST_CHANNEL_ID = 'testDefault'
|
||||
export const TEST_CHANNEL_NAME = 'Minibits test tasks'
|
||||
|
||||
export const initNotifications = async () => {
|
||||
let enabled = await areNotificationsEnabled()
|
||||
@@ -93,6 +97,16 @@ export const initNotifications = async () => {
|
||||
}
|
||||
})
|
||||
|
||||
notifee.isChannelCreated(TEST_CHANNEL_ID).then(isCreated => {
|
||||
if (!isCreated) {
|
||||
notifee.createChannel({
|
||||
id: TEST_CHANNEL_ID,
|
||||
name: TASK_QUEUE_CHANNEL_NAME,
|
||||
sound: 'default',
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -176,7 +190,7 @@ const _nwcRequestHandler = async function(remoteData: NotifyNwcRequestData) {
|
||||
|
||||
await notifee.displayNotification({
|
||||
title: NWC_CHANNEL_NAME,
|
||||
body: 'Nostr wallet command is being processed.',
|
||||
body: 'Processing remote NWC command...',
|
||||
android: {
|
||||
channelId: NWC_CHANNEL_ID,
|
||||
asForegroundService: true,
|
||||
@@ -186,10 +200,10 @@ const _nwcRequestHandler = async function(remoteData: NotifyNwcRequestData) {
|
||||
indeterminate: true,
|
||||
},
|
||||
},
|
||||
data: {task: 'handleNwcRequestFromNotification', data: cleanedRequestEvent}, // Pass the task data to the foreground service
|
||||
data: {task: HANDLE_NWC_REQUEST_TASK, data: cleanedRequestEvent}, // Pass the task data to the foreground service
|
||||
})
|
||||
} else {
|
||||
await nwcStore.handleNwcRequestFromNotification(requestEvent, nwcRequest)
|
||||
await nwcStore.handleNwcRequestTask(requestEvent, nwcRequest)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
import { Task, TaskId, TaskQueue, TaskStatus } from "simple-js-task-queue"
|
||||
import { Task, TaskId, TaskQueue, TaskStatus } from "taskon"
|
||||
import {log} from './logService'
|
||||
import EventEmitter from '../utils/eventEmitter'
|
||||
import { TransactionTaskResult, WalletTaskResult } from "./walletService"
|
||||
import { NotificationService } from "./notificationService"
|
||||
|
||||
let _queue: any = undefined
|
||||
// const start = new Date().getTime()
|
||||
|
||||
|
||||
const getSyncQueue = function () {
|
||||
if(!_queue) {
|
||||
@@ -15,12 +15,12 @@ const getSyncQueue = function () {
|
||||
stopOnError: false,
|
||||
// verbose: true,
|
||||
taskPrioritizationMode: "head",
|
||||
// memorizeTasks: true
|
||||
memorizeTasks: true
|
||||
})
|
||||
return _queue
|
||||
return _queue as TaskQueue
|
||||
}
|
||||
|
||||
return _queue
|
||||
return _queue as TaskQueue
|
||||
}
|
||||
|
||||
const addTask = function (taskId: TaskId, task: Promise<any> | any) {
|
||||
@@ -54,18 +54,19 @@ const addPrioritizedTask = function (taskId: TaskId, task: Promise<any> | any) {
|
||||
const _handleTaskResult = async (taskId: TaskId, result: WalletTaskResult | TransactionTaskResult) => {
|
||||
log.info(
|
||||
`[_handleTaskResult] The result of task ${taskId}`, result
|
||||
)
|
||||
|
||||
const queue: TaskQueue = getSyncQueue()
|
||||
)
|
||||
|
||||
EventEmitter.emit(`ev_${result.taskFunction}_result`, result)
|
||||
|
||||
/* if(queue.getAllTasksDetails(['idle', 'running']).length === 0) {
|
||||
if(await NotificationService.isNotificationDispayed()) {
|
||||
const queue: TaskQueue = getSyncQueue()
|
||||
|
||||
if(queue.getAllTasksDetails(['idle', 'running']).length === 0) {
|
||||
|
||||
if(await NotificationService.isNotificationDispayed()) {
|
||||
log.trace('[_handleTaskResult] stopForegroundService')
|
||||
NotificationService.stopForegroundService()
|
||||
}
|
||||
} */
|
||||
}
|
||||
}
|
||||
|
||||
// Helper function to handle the task status changes
|
||||
@@ -76,7 +77,8 @@ const _handleTaskStatusChange = (status: TaskStatus, task: Task) => {
|
||||
}
|
||||
|
||||
|
||||
export const SyncQueue = {
|
||||
export const SyncQueue = {
|
||||
getSyncQueue,
|
||||
addTask,
|
||||
addPrioritizedTask,
|
||||
}
|
||||
|
||||
@@ -24,9 +24,9 @@ const {
|
||||
} = rootStoreInstance
|
||||
|
||||
// function names to pass to task results
|
||||
const RECEIVE = 'receiveTask'
|
||||
const RECEIVE_OFFLINE_PREPARE = 'receiveOfflinePrepareTask'
|
||||
const RECEIVE_OFFLINE_COMPLETE = 'receiveOfflineCompleteTask'
|
||||
export const RECEIVE_TASK = 'receiveTask'
|
||||
export const RECEIVE_OFFLINE_PREPARE_TASK = 'receiveOfflinePrepareTask'
|
||||
export const RECEIVE_OFFLINE_COMPLETE_TASK = 'receiveOfflineCompleteTask'
|
||||
|
||||
export const receiveTask = async function (
|
||||
token: Token,
|
||||
@@ -86,14 +86,15 @@ export const receiveTask = async function (
|
||||
)
|
||||
|
||||
return {
|
||||
taskFunction: RECEIVE,
|
||||
taskFunction: RECEIVE_TASK,
|
||||
transaction,
|
||||
message: `The mint ${mintToReceive} is blocked. You can unblock it in Settings.`,
|
||||
} as TransactionTaskResult
|
||||
}
|
||||
|
||||
const {
|
||||
receivedAmount,
|
||||
receivedAmount,
|
||||
receivedProofs,
|
||||
outputToken,
|
||||
swapFeePaid,
|
||||
} = await receiveSync(
|
||||
@@ -133,11 +134,12 @@ export const receiveTask = async function (
|
||||
}
|
||||
|
||||
return {
|
||||
taskFunction: RECEIVE,
|
||||
taskFunction: RECEIVE_TASK,
|
||||
mintUrl: mintToReceive,
|
||||
transaction,
|
||||
message: `You've received ${formatCurrency(receivedAmount, getCurrency(unit).code)} ${getCurrency(unit).code} to your Minibits wallet.`,
|
||||
receivedAmount,
|
||||
receivedProofsCount: receivedProofs.length
|
||||
} as TransactionTaskResult
|
||||
|
||||
} catch (e: any) {
|
||||
@@ -158,7 +160,7 @@ export const receiveTask = async function (
|
||||
log.error(e.name, e.message)
|
||||
|
||||
return {
|
||||
taskFunction: RECEIVE,
|
||||
taskFunction: RECEIVE_TASK,
|
||||
mintUrl: mintToReceive,
|
||||
transaction,
|
||||
message: e.message,
|
||||
@@ -221,7 +223,7 @@ export const receiveOfflinePrepareTask = async function (
|
||||
)
|
||||
|
||||
return {
|
||||
taskFunction: RECEIVE_OFFLINE_PREPARE,
|
||||
taskFunction: RECEIVE_OFFLINE_PREPARE_TASK,
|
||||
mintUrl: mintToReceive,
|
||||
transaction: blockedTransaction,
|
||||
message: `The mint ${mintToReceive} is blocked. You can unblock it in Settings.`,
|
||||
@@ -240,7 +242,7 @@ export const receiveOfflinePrepareTask = async function (
|
||||
)
|
||||
|
||||
return {
|
||||
taskFunction: RECEIVE_OFFLINE_PREPARE,
|
||||
taskFunction: RECEIVE_OFFLINE_PREPARE_TASK,
|
||||
mintUrl: mintToReceive,
|
||||
transaction,
|
||||
message: `You received ${formatCurrency(amountToReceive, getCurrency(unit).code)} ${getCurrency(unit).code} while offline. You need to redeem them to your wallet when you will be online again.`,
|
||||
@@ -262,7 +264,7 @@ export const receiveOfflinePrepareTask = async function (
|
||||
log.error(e.name, e.message)
|
||||
|
||||
return {
|
||||
taskFunction: RECEIVE_OFFLINE_PREPARE,
|
||||
taskFunction: RECEIVE_OFFLINE_PREPARE_TASK,
|
||||
mintUrl: mintToReceive,
|
||||
transaction,
|
||||
message: '',
|
||||
@@ -307,7 +309,7 @@ export const receiveOfflineCompleteTask = async function (
|
||||
)
|
||||
|
||||
return {
|
||||
taskFunction: RECEIVE_OFFLINE_COMPLETE,
|
||||
taskFunction: RECEIVE_OFFLINE_COMPLETE_TASK,
|
||||
mintUrl: mintToReceive,
|
||||
transaction,
|
||||
message: `The mint ${mintToReceive} is blocked. You can unblock it in Settings.`,
|
||||
@@ -354,7 +356,7 @@ export const receiveOfflineCompleteTask = async function (
|
||||
}
|
||||
|
||||
return {
|
||||
taskFunction: RECEIVE_OFFLINE_COMPLETE,
|
||||
taskFunction: RECEIVE_OFFLINE_COMPLETE_TASK,
|
||||
mintUrl: mintToReceive,
|
||||
transaction,
|
||||
message: `You've received ${formatCurrency(receivedAmount, getCurrency(unit).code)} ${getCurrency(unit).code} to your Minibits wallet.`,
|
||||
@@ -378,7 +380,7 @@ export const receiveOfflineCompleteTask = async function (
|
||||
}
|
||||
|
||||
return {
|
||||
taskFunction: RECEIVE_OFFLINE_COMPLETE,
|
||||
taskFunction: RECEIVE_OFFLINE_COMPLETE_TASK,
|
||||
mintUrl: mintToReceive,
|
||||
transaction,
|
||||
message: '',
|
||||
|
||||
@@ -17,7 +17,7 @@ const {
|
||||
walletStore
|
||||
} = rootStoreInstance
|
||||
|
||||
const REVERT = 'revertTask'
|
||||
export const REVERT_TASK = 'revertTask'
|
||||
|
||||
export const revertTask = async function (
|
||||
transaction: Transaction
|
||||
@@ -101,7 +101,7 @@ try {
|
||||
}
|
||||
|
||||
return {
|
||||
taskFunction: REVERT,
|
||||
taskFunction: REVERT_TASK,
|
||||
mintUrl: mintInstance.mintUrl,
|
||||
transaction,
|
||||
message: `Transaction has been reverted and funds were returned to spendable balance.`,
|
||||
@@ -125,7 +125,7 @@ try {
|
||||
log.error(e.name, e.message)
|
||||
|
||||
return {
|
||||
taskFunction: REVERT,
|
||||
taskFunction: REVERT_TASK,
|
||||
mintUrl: transaction.mint,
|
||||
transaction,
|
||||
message: e.message,
|
||||
|
||||
@@ -28,6 +28,8 @@ const {
|
||||
walletStore
|
||||
} = rootStoreInstance
|
||||
|
||||
export const SEND_TASK = 'sendTask'
|
||||
|
||||
export const sendTask = async function (
|
||||
mintBalanceToSendFrom: MintBalance,
|
||||
amountToSend: number,
|
||||
@@ -38,8 +40,8 @@ export const sendTask = async function (
|
||||
|
||||
const mintUrl = mintBalanceToSendFrom.mintUrl
|
||||
|
||||
log.trace('[send]', 'mintBalanceToSendFrom', mintBalanceToSendFrom)
|
||||
log.trace('[send]', 'amountToSend', {amountToSend, unit})
|
||||
log.trace('[sendTask]', 'mintBalanceToSendFrom', mintBalanceToSendFrom)
|
||||
log.trace('[sendTask]', 'amountToSend', {amountToSend, unit})
|
||||
|
||||
// create draft transaction
|
||||
const transactionData: TransactionData[] = [
|
||||
@@ -135,7 +137,7 @@ export const sendTask = async function (
|
||||
|
||||
poller(
|
||||
`syncStateWithMintPoller-${mintUrl}`,
|
||||
WalletTask.syncStateWithMint,
|
||||
WalletTask.syncStateWithMintQueue,
|
||||
{
|
||||
interval: 6 * 1000,
|
||||
maxPolls: 5,
|
||||
@@ -147,7 +149,7 @@ export const sendTask = async function (
|
||||
}
|
||||
|
||||
return {
|
||||
taskFunction: 'sendTask',
|
||||
taskFunction: SEND_TASK,
|
||||
mintUrl,
|
||||
transaction,
|
||||
message: '',
|
||||
@@ -170,7 +172,7 @@ export const sendTask = async function (
|
||||
}
|
||||
|
||||
return {
|
||||
taskFunction: 'sendTask',
|
||||
taskFunction: SEND_TASK,
|
||||
mintUrl,
|
||||
transaction,
|
||||
message: e.message,
|
||||
@@ -421,7 +423,7 @@ export const sendFromMintSync = async function (
|
||||
|
||||
log.error('[sendFromMintSync] Going to clean spent proofs from pending', {transactionId})
|
||||
|
||||
await WalletTask.syncStateWithMintSync({
|
||||
await WalletTask.syncStateWithMintTask({
|
||||
proofsToSync: proofsStore.getByMint(mintUrl, {isPending: true, unit}),
|
||||
mintUrl,
|
||||
isPending: true
|
||||
|
||||
@@ -21,7 +21,7 @@ const {
|
||||
|
||||
// const {walletStore} = nonPersistedStores
|
||||
|
||||
const TOPUP = 'topupTask'
|
||||
export const TOPUP_TASK = 'topupTask'
|
||||
|
||||
export const topupTask = async function (
|
||||
mintBalanceToTopup: MintBalance,
|
||||
@@ -138,19 +138,19 @@ export const topupTask = async function (
|
||||
|
||||
if(!nwcEvent) {
|
||||
poller(
|
||||
`handlePendingTopupTaskPoller-${paymentRequest.paymentHash}`,
|
||||
WalletTask.handlePendingTopup,
|
||||
`handlePendingTopupPoller-${paymentRequest.paymentHash}`,
|
||||
WalletTask.handlePendingTopupQueue,
|
||||
{
|
||||
interval: 6 * 1000,
|
||||
maxPolls: 10,
|
||||
maxErrors: 2
|
||||
},
|
||||
{paymentRequest})
|
||||
.then(() => log.trace('Polling completed', [], `handlePendingTopupTaskPoller`))
|
||||
.then(() => log.trace('Polling completed', [], `handlePendingTopupPoller`))
|
||||
}
|
||||
|
||||
return {
|
||||
taskFunction: TOPUP,
|
||||
taskFunction: TOPUP_TASK,
|
||||
mintUrl,
|
||||
transaction,
|
||||
message: '',
|
||||
@@ -177,7 +177,7 @@ export const topupTask = async function (
|
||||
log.error(e.name, e.message)
|
||||
|
||||
return {
|
||||
taskFunction: TOPUP,
|
||||
taskFunction: TOPUP_TASK,
|
||||
transaction,
|
||||
message: e.message,
|
||||
error: WalletUtils.formatError(e),
|
||||
|
||||
@@ -21,7 +21,7 @@ const {
|
||||
|
||||
// const {walletStore} = nonPersistedStores
|
||||
|
||||
const TRANSFER = 'transferTask'
|
||||
export const TRANSFER_TASK = 'transferTask'
|
||||
|
||||
export const transferTask = async function (
|
||||
mintBalanceToTransferFrom: MintBalance,
|
||||
@@ -248,7 +248,7 @@ export const transferTask = async function (
|
||||
transaction.setBalanceAfter(balanceAfter)
|
||||
|
||||
return {
|
||||
taskFunction: TRANSFER,
|
||||
taskFunction: TRANSFER_TASK,
|
||||
mintUrl,
|
||||
transaction,
|
||||
message: `Lightning invoice has been successfully paid and settled with your Minibits ecash. Fee has been ${formatCurrency(transaction.fee, getCurrency(unit).code)} ${getCurrency(unit).code}.`,
|
||||
@@ -268,7 +268,7 @@ export const transferTask = async function (
|
||||
})
|
||||
|
||||
return {
|
||||
taskFunction: TRANSFER,
|
||||
taskFunction: TRANSFER_TASK,
|
||||
mintUrl,
|
||||
transaction,
|
||||
message: `Lightning payment did not complete in time. Your ecash will remain pending until the payment completes or fails.`,
|
||||
@@ -287,7 +287,7 @@ export const transferTask = async function (
|
||||
} catch (e: any) {
|
||||
let message = e.message
|
||||
let taskResult: TransactionTaskResult = {
|
||||
taskFunction: TRANSFER,
|
||||
taskFunction: TRANSFER_TASK,
|
||||
mintUrl,
|
||||
transaction,
|
||||
message,
|
||||
@@ -350,7 +350,7 @@ export const transferTask = async function (
|
||||
}
|
||||
}
|
||||
|
||||
await WalletTask.syncStateWithMintSync({
|
||||
await WalletTask.syncStateWithMintTask({
|
||||
proofsToSync: proofsStore.getByMint(mintUrl, {isPending: true, unit}),
|
||||
mintUrl,
|
||||
isPending: true
|
||||
|
||||
+384
-244
File diff suppressed because it is too large
Load Diff
@@ -1712,6 +1712,174 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@esbuild/aix-ppc64@npm:0.23.1":
|
||||
version: 0.23.1
|
||||
resolution: "@esbuild/aix-ppc64@npm:0.23.1"
|
||||
conditions: os=aix & cpu=ppc64
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@esbuild/android-arm64@npm:0.23.1":
|
||||
version: 0.23.1
|
||||
resolution: "@esbuild/android-arm64@npm:0.23.1"
|
||||
conditions: os=android & cpu=arm64
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@esbuild/android-arm@npm:0.23.1":
|
||||
version: 0.23.1
|
||||
resolution: "@esbuild/android-arm@npm:0.23.1"
|
||||
conditions: os=android & cpu=arm
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@esbuild/android-x64@npm:0.23.1":
|
||||
version: 0.23.1
|
||||
resolution: "@esbuild/android-x64@npm:0.23.1"
|
||||
conditions: os=android & cpu=x64
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@esbuild/darwin-arm64@npm:0.23.1":
|
||||
version: 0.23.1
|
||||
resolution: "@esbuild/darwin-arm64@npm:0.23.1"
|
||||
conditions: os=darwin & cpu=arm64
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@esbuild/darwin-x64@npm:0.23.1":
|
||||
version: 0.23.1
|
||||
resolution: "@esbuild/darwin-x64@npm:0.23.1"
|
||||
conditions: os=darwin & cpu=x64
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@esbuild/freebsd-arm64@npm:0.23.1":
|
||||
version: 0.23.1
|
||||
resolution: "@esbuild/freebsd-arm64@npm:0.23.1"
|
||||
conditions: os=freebsd & cpu=arm64
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@esbuild/freebsd-x64@npm:0.23.1":
|
||||
version: 0.23.1
|
||||
resolution: "@esbuild/freebsd-x64@npm:0.23.1"
|
||||
conditions: os=freebsd & cpu=x64
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@esbuild/linux-arm64@npm:0.23.1":
|
||||
version: 0.23.1
|
||||
resolution: "@esbuild/linux-arm64@npm:0.23.1"
|
||||
conditions: os=linux & cpu=arm64
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@esbuild/linux-arm@npm:0.23.1":
|
||||
version: 0.23.1
|
||||
resolution: "@esbuild/linux-arm@npm:0.23.1"
|
||||
conditions: os=linux & cpu=arm
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@esbuild/linux-ia32@npm:0.23.1":
|
||||
version: 0.23.1
|
||||
resolution: "@esbuild/linux-ia32@npm:0.23.1"
|
||||
conditions: os=linux & cpu=ia32
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@esbuild/linux-loong64@npm:0.23.1":
|
||||
version: 0.23.1
|
||||
resolution: "@esbuild/linux-loong64@npm:0.23.1"
|
||||
conditions: os=linux & cpu=loong64
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@esbuild/linux-mips64el@npm:0.23.1":
|
||||
version: 0.23.1
|
||||
resolution: "@esbuild/linux-mips64el@npm:0.23.1"
|
||||
conditions: os=linux & cpu=mips64el
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@esbuild/linux-ppc64@npm:0.23.1":
|
||||
version: 0.23.1
|
||||
resolution: "@esbuild/linux-ppc64@npm:0.23.1"
|
||||
conditions: os=linux & cpu=ppc64
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@esbuild/linux-riscv64@npm:0.23.1":
|
||||
version: 0.23.1
|
||||
resolution: "@esbuild/linux-riscv64@npm:0.23.1"
|
||||
conditions: os=linux & cpu=riscv64
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@esbuild/linux-s390x@npm:0.23.1":
|
||||
version: 0.23.1
|
||||
resolution: "@esbuild/linux-s390x@npm:0.23.1"
|
||||
conditions: os=linux & cpu=s390x
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@esbuild/linux-x64@npm:0.23.1":
|
||||
version: 0.23.1
|
||||
resolution: "@esbuild/linux-x64@npm:0.23.1"
|
||||
conditions: os=linux & cpu=x64
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@esbuild/netbsd-x64@npm:0.23.1":
|
||||
version: 0.23.1
|
||||
resolution: "@esbuild/netbsd-x64@npm:0.23.1"
|
||||
conditions: os=netbsd & cpu=x64
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@esbuild/openbsd-arm64@npm:0.23.1":
|
||||
version: 0.23.1
|
||||
resolution: "@esbuild/openbsd-arm64@npm:0.23.1"
|
||||
conditions: os=openbsd & cpu=arm64
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@esbuild/openbsd-x64@npm:0.23.1":
|
||||
version: 0.23.1
|
||||
resolution: "@esbuild/openbsd-x64@npm:0.23.1"
|
||||
conditions: os=openbsd & cpu=x64
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@esbuild/sunos-x64@npm:0.23.1":
|
||||
version: 0.23.1
|
||||
resolution: "@esbuild/sunos-x64@npm:0.23.1"
|
||||
conditions: os=sunos & cpu=x64
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@esbuild/win32-arm64@npm:0.23.1":
|
||||
version: 0.23.1
|
||||
resolution: "@esbuild/win32-arm64@npm:0.23.1"
|
||||
conditions: os=win32 & cpu=arm64
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@esbuild/win32-ia32@npm:0.23.1":
|
||||
version: 0.23.1
|
||||
resolution: "@esbuild/win32-ia32@npm:0.23.1"
|
||||
conditions: os=win32 & cpu=ia32
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@esbuild/win32-x64@npm:0.23.1":
|
||||
version: 0.23.1
|
||||
resolution: "@esbuild/win32-x64@npm:0.23.1"
|
||||
conditions: os=win32 & cpu=x64
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@eslint-community/eslint-utils@npm:^4.2.0, @eslint-community/eslint-utils@npm:^4.4.0":
|
||||
version: 4.4.0
|
||||
resolution: "@eslint-community/eslint-utils@npm:4.4.0"
|
||||
@@ -6225,6 +6393,89 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"esbuild@npm:~0.23.0":
|
||||
version: 0.23.1
|
||||
resolution: "esbuild@npm:0.23.1"
|
||||
dependencies:
|
||||
"@esbuild/aix-ppc64": 0.23.1
|
||||
"@esbuild/android-arm": 0.23.1
|
||||
"@esbuild/android-arm64": 0.23.1
|
||||
"@esbuild/android-x64": 0.23.1
|
||||
"@esbuild/darwin-arm64": 0.23.1
|
||||
"@esbuild/darwin-x64": 0.23.1
|
||||
"@esbuild/freebsd-arm64": 0.23.1
|
||||
"@esbuild/freebsd-x64": 0.23.1
|
||||
"@esbuild/linux-arm": 0.23.1
|
||||
"@esbuild/linux-arm64": 0.23.1
|
||||
"@esbuild/linux-ia32": 0.23.1
|
||||
"@esbuild/linux-loong64": 0.23.1
|
||||
"@esbuild/linux-mips64el": 0.23.1
|
||||
"@esbuild/linux-ppc64": 0.23.1
|
||||
"@esbuild/linux-riscv64": 0.23.1
|
||||
"@esbuild/linux-s390x": 0.23.1
|
||||
"@esbuild/linux-x64": 0.23.1
|
||||
"@esbuild/netbsd-x64": 0.23.1
|
||||
"@esbuild/openbsd-arm64": 0.23.1
|
||||
"@esbuild/openbsd-x64": 0.23.1
|
||||
"@esbuild/sunos-x64": 0.23.1
|
||||
"@esbuild/win32-arm64": 0.23.1
|
||||
"@esbuild/win32-ia32": 0.23.1
|
||||
"@esbuild/win32-x64": 0.23.1
|
||||
dependenciesMeta:
|
||||
"@esbuild/aix-ppc64":
|
||||
optional: true
|
||||
"@esbuild/android-arm":
|
||||
optional: true
|
||||
"@esbuild/android-arm64":
|
||||
optional: true
|
||||
"@esbuild/android-x64":
|
||||
optional: true
|
||||
"@esbuild/darwin-arm64":
|
||||
optional: true
|
||||
"@esbuild/darwin-x64":
|
||||
optional: true
|
||||
"@esbuild/freebsd-arm64":
|
||||
optional: true
|
||||
"@esbuild/freebsd-x64":
|
||||
optional: true
|
||||
"@esbuild/linux-arm":
|
||||
optional: true
|
||||
"@esbuild/linux-arm64":
|
||||
optional: true
|
||||
"@esbuild/linux-ia32":
|
||||
optional: true
|
||||
"@esbuild/linux-loong64":
|
||||
optional: true
|
||||
"@esbuild/linux-mips64el":
|
||||
optional: true
|
||||
"@esbuild/linux-ppc64":
|
||||
optional: true
|
||||
"@esbuild/linux-riscv64":
|
||||
optional: true
|
||||
"@esbuild/linux-s390x":
|
||||
optional: true
|
||||
"@esbuild/linux-x64":
|
||||
optional: true
|
||||
"@esbuild/netbsd-x64":
|
||||
optional: true
|
||||
"@esbuild/openbsd-arm64":
|
||||
optional: true
|
||||
"@esbuild/openbsd-x64":
|
||||
optional: true
|
||||
"@esbuild/sunos-x64":
|
||||
optional: true
|
||||
"@esbuild/win32-arm64":
|
||||
optional: true
|
||||
"@esbuild/win32-ia32":
|
||||
optional: true
|
||||
"@esbuild/win32-x64":
|
||||
optional: true
|
||||
bin:
|
||||
esbuild: bin/esbuild
|
||||
checksum: 0413c3b9257327fb598427688b7186ea335bf1693746fe5713cc93c95854d6388b8ed4ad643fddf5b5ace093f7dcd9038dd58e087bf2da1f04dfb4c5571660af
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"escalade@npm:^3.1.1, escalade@npm:^3.1.2":
|
||||
version: 3.2.0
|
||||
resolution: "escalade@npm:3.2.0"
|
||||
@@ -7029,7 +7280,7 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"fsevents@npm:^2.3.2":
|
||||
"fsevents@npm:^2.3.2, fsevents@npm:~2.3.3":
|
||||
version: 2.3.3
|
||||
resolution: "fsevents@npm:2.3.3"
|
||||
dependencies:
|
||||
@@ -7039,7 +7290,7 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"fsevents@patch:fsevents@^2.3.2#~builtin<compat/fsevents>":
|
||||
"fsevents@patch:fsevents@^2.3.2#~builtin<compat/fsevents>, fsevents@patch:fsevents@~2.3.3#~builtin<compat/fsevents>":
|
||||
version: 2.3.3
|
||||
resolution: "fsevents@patch:fsevents@npm%3A2.3.3#~builtin<compat/fsevents>::version=2.3.3&hash=df0bf1"
|
||||
dependencies:
|
||||
@@ -7126,6 +7377,15 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"get-tsconfig@npm:^4.7.5":
|
||||
version: 4.8.1
|
||||
resolution: "get-tsconfig@npm:4.8.1"
|
||||
dependencies:
|
||||
resolve-pkg-maps: ^1.0.0
|
||||
checksum: 12df01672e691d2ff6db8cf7fed1ddfef90ed94a5f3d822c63c147a26742026d582acd86afcd6f65db67d809625d17dd7f9d34f4d3f38f69bc2f48e19b2bdd5b
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"get-uri@npm:^6.0.1":
|
||||
version: 6.0.3
|
||||
resolution: "get-uri@npm:6.0.3"
|
||||
@@ -9534,7 +9794,7 @@ __metadata:
|
||||
react-native-tab-view: ^3.5.2
|
||||
react-native-url-polyfill: ^2.0.0
|
||||
react-test-renderer: 18.3.1
|
||||
simple-js-task-queue: ^0.2.2
|
||||
taskon: ^0.3.0
|
||||
text-encoding-polyfill: ^0.6.7
|
||||
typescript: 5.0.4
|
||||
util: ^0.12.5
|
||||
@@ -11338,6 +11598,13 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"resolve-pkg-maps@npm:^1.0.0":
|
||||
version: 1.0.0
|
||||
resolution: "resolve-pkg-maps@npm:1.0.0"
|
||||
checksum: 1012afc566b3fdb190a6309cc37ef3b2dcc35dff5fa6683a9d00cd25c3247edfbc4691b91078c97adc82a29b77a2660c30d791d65dab4fc78bfc473f60289977
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"resolve.exports@npm:^2.0.0":
|
||||
version: 2.0.2
|
||||
resolution: "resolve.exports@npm:2.0.2"
|
||||
@@ -11727,13 +11994,6 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"simple-js-task-queue@npm:^0.2.2":
|
||||
version: 0.2.2
|
||||
resolution: "simple-js-task-queue@npm:0.2.2"
|
||||
checksum: bd56fcbea3ecbc081238f02c8892ebbbb692468ecdac9f0d229e96dea85db308889adf1ef128346a3acc8585913813f2415eed0aa4336be6467a4995cf42f39e
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"simple-plist@npm:^1.1.0":
|
||||
version: 1.4.0
|
||||
resolution: "simple-plist@npm:1.4.0"
|
||||
@@ -12209,6 +12469,18 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"taskon@npm:^0.3.0":
|
||||
version: 0.3.0
|
||||
resolution: "taskon@npm:0.3.0"
|
||||
dependencies:
|
||||
tsx: ^4.19.2
|
||||
dependenciesMeta:
|
||||
tsx:
|
||||
optional: true
|
||||
checksum: 7632189a17a8f51a2528e9ed580f9b6892d36ae266ca8e1d81c4779db83252a177f561d37f324d4806027e7eca98a8ad43dde2c5e5e6355a73e9013d4ddf3fc3
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"temp@npm:^0.8.4":
|
||||
version: 0.8.4
|
||||
resolution: "temp@npm:0.8.4"
|
||||
@@ -12368,6 +12640,22 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"tsx@npm:^4.19.2":
|
||||
version: 4.19.2
|
||||
resolution: "tsx@npm:4.19.2"
|
||||
dependencies:
|
||||
esbuild: ~0.23.0
|
||||
fsevents: ~2.3.3
|
||||
get-tsconfig: ^4.7.5
|
||||
dependenciesMeta:
|
||||
fsevents:
|
||||
optional: true
|
||||
bin:
|
||||
tsx: dist/cli.mjs
|
||||
checksum: 7f9f1b338a73297725a9217cedaaad862f7c81d5264093c74b98a71491ad5413b11248d604c0e650f4f7da6f365249f1426fdb58a1325ab9e15448156b1edff6
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"type-check@npm:^0.4.0, type-check@npm:~0.4.0":
|
||||
version: 0.4.0
|
||||
resolution: "type-check@npm:0.4.0"
|
||||
|
||||
Reference in New Issue
Block a user