Skip to content

Commit

Permalink
fix #122
Browse files Browse the repository at this point in the history
  • Loading branch information
BilligsterUser committed Sep 10, 2023
1 parent 7bac55c commit dcfb2ed
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 59 deletions.
12 changes: 7 additions & 5 deletions src/screens/Payment/Processing.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -134,12 +134,12 @@ export default function ProcessingScreen({ navigation, route }: TProcessingPageP
await addLnPaymentToHistory(
res,
[mint.mintUrl],
-amount - res.realFee,
-amount - (res?.realFee??0),
target
)
// update latest 3 history entries
await updateLatestHistory({
amount: -amount - res.realFee,
amount: -amount - (res?.realFee??0),
fee: res.realFee,
type: 2,
value: target,
Expand All @@ -157,20 +157,22 @@ export default function ProcessingScreen({ navigation, route }: TProcessingPageP
}

const handleSwapProcess = async () => {
if (!targetMint?.mintUrl?.trim()) { return handleError({ e: `targetMint: ${targetMint?.mintUrl} is invalid` }) }
// simple way
try {
const res = await autoMintSwap(mint.mintUrl, targetMint?.mintUrl || '', amount, estFee || 0)
const res = await autoMintSwap(mint.mintUrl, targetMint.mintUrl, amount, estFee ?? 0)
l({ swapResult: res })
// add as history entry (multimint swap)
await addToHistory({
amount: -amount,
amount: -amount - (res?.payResult?.realFee??0),
fee: res.payResult.realFee,
type: 3,
value: res.requestTokenResult.invoice?.pr || '',
mints: [mint.mintUrl],
recipient: targetMint?.mintUrl || ''
})
navigation.navigate('success', {
amount: amount - (estFee || 0),
amount,
fee: res.payResult.realFee,
isMelt: true
})
Expand Down
89 changes: 35 additions & 54 deletions src/wallet/index.ts
Original file line number Diff line number Diff line change
@@ -1,23 +1,27 @@
import {
CashuMint, CashuWallet, deriveKeysetId,
getDecodedLnInvoice, getDecodedToken,
getEncodedToken, type MintKeys, type Proof
getEncodedToken,
type GetInfoResponse, type MintKeys,
type PayLnInvoiceResponse, type Proof,
type RequestMintResponse
} from '@cashu/cashu-ts'
import {
addInvoice, addMint, addToken, deleteProofs,
delInvoice, getAllInvoices, getInvoice,
getMintBalance, getMintsUrls
} from '@db'
import { l } from '@log'
import { isCashuToken } from '@util'
import type { IInvoice } from '@src/model'
import { isCashuToken, isNum } from '@util'

import { sumProofsValue } from './proofs'
import { getProofsToUse } from './util'

const _mintKeysMap: { [mintUrl: string]: { [keySetId: string]: MintKeys } } = {}
const wallets: { [mintUrl: string]: CashuWallet } = {}

function _setKeys(mintUrl: string, keys: MintKeys, keySetId?: string) {
function _setKeys(mintUrl: string, keys: MintKeys, keySetId?: string): void {
if (!keySetId) { keySetId = deriveKeysetId(keys) }
if (!_mintKeysMap[mintUrl]) { _mintKeysMap[mintUrl] = {} }
if (!_mintKeysMap[mintUrl][keySetId]) {
Expand All @@ -27,7 +31,7 @@ function _setKeys(mintUrl: string, keys: MintKeys, keySetId?: string) {
}
}

async function getWallet(mintUrl: string) {
async function getWallet(mintUrl: string): Promise<CashuWallet> {
if (wallets[mintUrl]) { return wallets[mintUrl] }
const mint = new CashuMint(mintUrl)
l({ mint })
Expand All @@ -39,7 +43,7 @@ async function getWallet(mintUrl: string) {
return wallet
}

async function getCurrentKeySetId(mintUrl: string) {
async function getCurrentKeySetId(mintUrl: string): Promise<string> {
const wallet = await getWallet(mintUrl)
l({ wallet })
const keys = await (await getWallet(mintUrl)).mint.getKeys()
Expand All @@ -48,19 +52,17 @@ async function getCurrentKeySetId(mintUrl: string) {
return keySetId
}

export function getMintCurrentKeySetId(mintUrl: string) {
export function getMintCurrentKeySetId(mintUrl: string): Promise<string> {
return getCurrentKeySetId(mintUrl)
}

export function getMintKeySetIds(mintUrl: string) {
export function getMintKeySetIds(mintUrl: string): Promise<{ keysets: string[] }> {
return CashuMint.getKeySets(mintUrl)
}

export function getMintInfo(mintUrl: string) {
return CashuMint.getInfo(mintUrl)
}
export function getMintInfo(mintUrl: string): Promise<GetInfoResponse> { return CashuMint.getInfo(mintUrl) }

export async function isTokenSpendable(token: string) {
export async function isTokenSpendable(token: string): Promise<boolean> {
try {
const decoded = getDecodedToken(token)
if (!decoded?.token?.length) { return false }
Expand All @@ -81,11 +83,11 @@ export async function isTokenSpendable(token: string) {
} catch (_) { return false }
}

export async function checkProofsSpent(mintUrl: string, toCheck: { secret: string }[]) {
export async function checkProofsSpent(mintUrl: string, toCheck: { secret: string }[]): Promise<{ secret: string }[]> {
return (await getWallet(mintUrl)).checkProofsSpent(toCheck)
}

export async function checkFees(mintUrl: string, invoice: string) {
export async function checkFees(mintUrl: string, invoice: string): Promise<number> {
const { fee } = await CashuMint.checkFees(mintUrl, { pr: invoice })
return fee
}
Expand Down Expand Up @@ -119,7 +121,7 @@ export async function claimToken(encodedToken: string): Promise<boolean> {
return true
}

export async function requestMint(mintUrl: string, amount: number) {
export async function requestMint(mintUrl: string, amount: number): Promise<RequestMintResponse> {
const wallet = await getWallet(mintUrl)
const result = await wallet.requestMint(amount)
await addInvoice({ amount, mintUrl, ...result })
Expand All @@ -128,7 +130,7 @@ export async function requestMint(mintUrl: string, amount: number) {
return result
}

export async function requestToken(mintUrl: string, amount: number, hash: string) {
export async function requestToken(mintUrl: string, amount: number, hash: string): Promise<{ success: boolean; invoice: IInvoice | null | undefined }> {
const invoice = await getInvoice(hash)
const wallet = await getWallet(mintUrl)
const { proofs, newKeys } = await wallet.requestTokens(amount, hash)
Expand All @@ -139,51 +141,36 @@ export async function requestToken(mintUrl: string, amount: number, hash: string
return { success: true, invoice }
}

export async function payLnInvoice(mintUrl: string, invoice: string, fee: number, proofs: Proof[] = []) {
export async function payLnInvoice(mintUrl: string, invoice: string, fee: number, proofs: Proof[] = []): Promise<{ result?: PayLnInvoiceResponse, fee?: number, realFee?: number, error?: unknown }> {
const wallet = await getWallet(mintUrl)
// const fee = await wallet.getFee(invoice)
// l({ fee })
const decoded = getDecodedLnInvoice(invoice)
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
const amount = decoded.sections[2]!.value as number / 1000
if (!decoded.sections[2] || !isNum(decoded.sections[2].value)) { throw new Error('bad invoice amount') }
const amount = decoded.sections[2].value / 1000
const amountToPay = amount + fee
if (!proofs?.length) {
const { proofsToUse } = await getProofsToUse(mintUrl, amountToPay)
proofs = proofsToUse
}
// l({ amountToPay })
const { send, returnChange, newKeys } = await wallet.send(amountToPay, proofs)
// l({ send })
if (newKeys) { _setKeys(mintUrl, newKeys) }
// add change back to db
if (returnChange.length) { await addToken({ token: [{ mint: mintUrl, proofs: returnChange }] }) }
if (returnChange?.length) { await addToken({ token: [{ mint: mintUrl, proofs: returnChange }] }) }
if (send?.length) { await deleteProofs(proofs) }
try {
const result = await wallet.payLnInvoice(invoice, send, fee)
// l('[payLnInvoice]', { result, mintUrl, amount })
if (result?.newKeys) { _setKeys(mintUrl, result.newKeys) }
if (result?.change?.length) { await addToken({ token: [{ mint: mintUrl, proofs: result.change }] }) }
if (result.isPaid) {
await deleteProofs(send)
}
l({ fee })
if (result.isPaid) { await deleteProofs(send) }
/* l({ fee, change: result.change, sum: sumProofsValue(result.change) })
l({ sumProofsValue: sumProofsValue(result.change) })
l({ resultChange: result.change })
return {
result,
error: undefined,
fee,
realFee: fee - result?.change?.length
? sumProofsValue(result.change)
: 0
}
l({ resultChange: result.change }) */
return { result, fee, realFee: fee - sumProofsValue(returnChange.concat(result.change)) }
} catch (error) {
await addToken({ token: [{ mint: mintUrl, proofs: send }] })
return { result: undefined, error }
}
}

export async function sendToken(mintUrl: string, amount: number, memo: string, proofs: Proof[] = []) {
export async function sendToken(mintUrl: string, amount: number, memo: string, proofs: Proof[] = []): Promise<string> {
const wallet = await getWallet(mintUrl)
if (!proofs?.length) {
const { proofsToUse } = await getProofsToUse(mintUrl, amount)
Expand All @@ -193,7 +180,7 @@ export async function sendToken(mintUrl: string, amount: number, memo: string, p
const { send, returnChange, newKeys } = await wallet.send(amount, proofs)
if (newKeys) { _setKeys(mintUrl, newKeys) }
// add change back to db
if (returnChange.length) { await addToken({ token: [{ mint: mintUrl, proofs: returnChange }] }) }
if (returnChange?.length) { await addToken({ token: [{ mint: mintUrl, proofs: returnChange }] }) }
await deleteProofs(proofs)
return getEncodedToken({ token: [{ mint: mintUrl, proofs: send }], memo: memo.length > 0 ? memo : 'Sent via eNuts.' })
}
Expand All @@ -204,19 +191,13 @@ export async function autoMintSwap(
amount: number,
fee: number,
proofs: Proof[] = []
) {
let { pr, hash } = await requestMint(destMintUrl, amount)
// const fee = await checkFees(destMintUrl, pr)
if (fee > 0) {
// amount = amount + fee
l('[autoMintSwap]', { fee, amount, srcMintUrl, destMintUrl })
if (amount <= 0) {
throw new Error('Swap Error: not enough funds')
}
const resp = await requestMint(destMintUrl, amount)
pr = resp.pr
hash = resp.hash
): Promise<{ payResult: { result?: PayLnInvoiceResponse, fee?: number, realFee?: number, error?: unknown }; requestTokenResult: { success: boolean; invoice?: IInvoice | null } }> {
if (!isNum(fee) || fee < 0) { fee = await checkFees(destMintUrl, (await requestMint(destMintUrl, amount)).pr) }
l('[autoMintSwap]', { fee, amount, srcMintUrl, destMintUrl })
if (!amount || !isNum(amount) || isNaN(amount) || !isFinite(amount) || amount <= 0) {
throw new Error('Swap Error: not enough funds')
}
const { pr, hash } = await requestMint(destMintUrl, amount)
if (!proofs?.length) {
const { proofsToUse } = await getProofsToUse(srcMintUrl, amount + fee)
proofs = proofsToUse
Expand Down Expand Up @@ -248,12 +229,12 @@ export async function fullAutoMintSwap(srcMintUrl: string, destMintUrl: string,

let isRequestTokenLoopRunning = false
let loopHandel: NodeJS.Timeout
export function runRequestTokenLoop() {
export function runRequestTokenLoop(): void {
// eslint-disable-next-line @typescript-eslint/no-misused-promises
loopHandel = setTimeout(requestTokenLoop, 60000)
}

async function requestTokenLoop() {
async function requestTokenLoop(): Promise<void> {
if (isRequestTokenLoopRunning) { return }
isRequestTokenLoopRunning = true
const invoices = await getAllInvoices()
Expand Down

0 comments on commit dcfb2ed

Please sign in to comment.