Compare commits
No commits in common. "ffc156df2bbc21eb8fcdc77bce4db17de8ee1984" and "ec2383b99889f47f651860f9e41f38fbcd1940a2" have entirely different histories.
ffc156df2b
...
ec2383b998
@ -231,7 +231,7 @@ export async function createLightningInvoice (actionType, args, context) {
|
||||
}, { models })
|
||||
|
||||
const { invoice: wrappedInvoice, maxFee } = await wrapInvoice(
|
||||
bolt11, { msats: cost, description }, { lnd })
|
||||
bolt11, { description }, { lnd })
|
||||
|
||||
return {
|
||||
bolt11,
|
||||
|
@ -1,13 +1,13 @@
|
||||
import { timeSince } from '@/lib/time'
|
||||
import styles from './log-message.module.css'
|
||||
|
||||
export default function LogMessage ({ showWallet, wallet, level, message, ts }) {
|
||||
export default function LogMessage ({ wallet, level, message, ts }) {
|
||||
level = level.toLowerCase()
|
||||
const levelClassName = ['ok', 'success'].includes(level) ? 'text-success' : level === 'error' ? 'text-danger' : level === 'info' ? 'text-info' : ''
|
||||
return (
|
||||
<tr className={styles.line}>
|
||||
<td className={styles.timestamp}>{timeSince(new Date(ts))}</td>
|
||||
{showWallet ? <td className={styles.wallet}>[{wallet}]</td> : <td className='mx-1' />}
|
||||
<td className={styles.wallet}>[{wallet}]</td>
|
||||
<td className={`${styles.level} ${levelClassName}`}>{level === 'success' ? 'ok' : level}</td>
|
||||
<td>{message}</td>
|
||||
</tr>
|
||||
|
@ -30,13 +30,7 @@ export function WalletLogs ({ wallet, embedded }) {
|
||||
{logs.length === 0 && <div className='w-100 text-center'>empty</div>}
|
||||
<table>
|
||||
<tbody>
|
||||
{logs.map((log, i) => (
|
||||
<LogMessage
|
||||
key={i}
|
||||
showWallet={!wallet}
|
||||
{...log}
|
||||
/>
|
||||
))}
|
||||
{logs.map((log, i) => <LogMessage key={i} {...log} />)}
|
||||
</tbody>
|
||||
</table>
|
||||
<div className='w-100 text-center'>------ start of logs ------</div>
|
||||
|
@ -52,7 +52,6 @@ export const msatsToSats = msats => {
|
||||
if (msats === null || msats === undefined) {
|
||||
return null
|
||||
}
|
||||
// implicitly floors the result
|
||||
return Number(BigInt(msats) / 1000n)
|
||||
}
|
||||
|
||||
@ -63,8 +62,6 @@ export const satsToMsats = sats => {
|
||||
return BigInt(sats) * 1000n
|
||||
}
|
||||
|
||||
export const msatsSatsFloor = msats => satsToMsats(msatsToSats(msats))
|
||||
|
||||
export const msatsToSatsDecimal = msats => {
|
||||
if (msats === null || msats === undefined) {
|
||||
return null
|
||||
|
@ -3,7 +3,7 @@ import { createInvoice as clnCreateInvoice } from '@/lib/cln'
|
||||
export * from 'wallets/cln'
|
||||
|
||||
export const testConnectServer = async ({ socket, rune, cert }) => {
|
||||
return await createInvoice({ msats: 1000, expiry: 1, description: '' }, { socket, rune, cert })
|
||||
return await createInvoice({ msats: 1, expiry: 1, description: '' }, { socket, rune, cert })
|
||||
}
|
||||
|
||||
export const createInvoice = async (
|
||||
|
@ -105,7 +105,6 @@ export function useWallet (name) {
|
||||
|
||||
return {
|
||||
...wallet,
|
||||
canSend: !!wallet.sendPayment,
|
||||
sendPayment,
|
||||
config,
|
||||
save,
|
||||
@ -376,7 +375,7 @@ export function useWallets () {
|
||||
|
||||
const resetClient = useCallback(async (wallet) => {
|
||||
for (const w of wallets) {
|
||||
if (w.canSend) {
|
||||
if (w.sendPayment) {
|
||||
await w.delete()
|
||||
}
|
||||
await w.deleteLogs()
|
||||
|
@ -1,4 +1,3 @@
|
||||
import { msatsSatsFloor } from '@/lib/format'
|
||||
import { lnAddrOptions } from '@/lib/lnurl'
|
||||
|
||||
export * from 'wallets/lightning-address'
|
||||
@ -13,10 +12,6 @@ export const createInvoice = async (
|
||||
) => {
|
||||
const { callback, commentAllowed } = await lnAddrOptions(address)
|
||||
const callbackUrl = new URL(callback)
|
||||
|
||||
// most lnurl providers suck nards so we have to floor to nearest sat
|
||||
msats = msatsSatsFloor(msats)
|
||||
|
||||
callbackUrl.searchParams.append('amount', msats)
|
||||
|
||||
if (commentAllowed >= description?.length) {
|
||||
|
@ -1,7 +1,7 @@
|
||||
export * from 'wallets/lnbits'
|
||||
|
||||
export async function testConnectServer ({ url, invoiceKey }) {
|
||||
return await createInvoice({ msats: 1000, expiry: 1 }, { url, invoiceKey })
|
||||
return await createInvoice({ msats: 1, expiry: 1 }, { url, invoiceKey })
|
||||
}
|
||||
|
||||
export async function createInvoice (
|
||||
|
@ -4,7 +4,7 @@ import { authenticatedLndGrpc, createInvoice as lndCreateInvoice } from 'ln-serv
|
||||
export * from 'wallets/lnd'
|
||||
|
||||
export const testConnectServer = async ({ cert, macaroon, socket }) => {
|
||||
return await createInvoice({ msats: 1000, expiry: 1 }, { cert, macaroon, socket })
|
||||
return await createInvoice({ msats: 1, expiry: 1 }, { cert, macaroon, socket })
|
||||
}
|
||||
|
||||
export const createInvoice = async (
|
||||
|
@ -53,21 +53,7 @@ export async function createInvoice (userId, { msats, description, descriptionHa
|
||||
|
||||
const bolt11 = await parsePaymentRequest({ request: invoice })
|
||||
if (BigInt(bolt11.mtokens) !== BigInt(msats)) {
|
||||
if (BigInt(bolt11.mtokens) > BigInt(msats)) {
|
||||
throw new Error(`invoice is for an amount greater than requested ${bolt11.mtokens} > ${msats}`)
|
||||
}
|
||||
if (BigInt(bolt11.mtokens) === 0n) {
|
||||
throw new Error('invoice is for 0 msats')
|
||||
}
|
||||
if (BigInt(msats) - BigInt(bolt11.mtokens) >= 1000n) {
|
||||
throw new Error(`invoice has a different satoshi amount ${bolt11.mtokens} !== ${msats}`)
|
||||
}
|
||||
|
||||
await addWalletLog({
|
||||
wallet,
|
||||
level: 'INFO',
|
||||
message: `wallet does not support msats so we floored ${msats} msats to nearest sat ${BigInt(bolt11.mtokens)} msats`
|
||||
}, { models })
|
||||
throw new Error('invoice has incorrect amount')
|
||||
}
|
||||
|
||||
return { invoice, wallet }
|
||||
|
@ -19,10 +19,10 @@ const ZAP_SYBIL_FEE_MULT = 10 / 9 // the fee for the zap sybil service
|
||||
@param options {object}
|
||||
@returns {
|
||||
invoice: the wrapped incoming invoice,
|
||||
maxFee: number
|
||||
outgoingMaxFeeMsat: number
|
||||
}
|
||||
*/
|
||||
export default async function wrapInvoice (bolt11, { msats, description, descriptionHash }, { lnd }) {
|
||||
export default async function wrapInvoice (bolt11, { description, descriptionHash }, { lnd }) {
|
||||
try {
|
||||
console.group('wrapInvoice', description)
|
||||
|
||||
@ -38,7 +38,7 @@ export default async function wrapInvoice (bolt11, { msats, description, descrip
|
||||
|
||||
console.log('invoice', inv.mtokens, inv.expires_at, inv.cltv_delta)
|
||||
|
||||
// validate outgoing amount
|
||||
// validate amount
|
||||
if (inv.mtokens) {
|
||||
outgoingMsat = toPositiveNumber(inv.mtokens)
|
||||
if (outgoingMsat < MIN_OUTGOING_MSATS) {
|
||||
@ -48,17 +48,7 @@ export default async function wrapInvoice (bolt11, { msats, description, descrip
|
||||
throw new Error(`Invoice amount is too high: ${outgoingMsat}`)
|
||||
}
|
||||
} else {
|
||||
throw new Error('Outgoing invoice is missing amount')
|
||||
}
|
||||
|
||||
// validate incoming amount
|
||||
if (msats) {
|
||||
msats = toPositiveNumber(msats)
|
||||
if (outgoingMsat * ZAP_SYBIL_FEE_MULT > msats) {
|
||||
throw new Error('Sybil fee is too low')
|
||||
}
|
||||
} else {
|
||||
throw new Error('Incoming invoice amount is missing')
|
||||
throw new Error('Invoice amount is missing')
|
||||
}
|
||||
|
||||
// validate features
|
||||
@ -155,13 +145,13 @@ export default async function wrapInvoice (bolt11, { msats, description, descrip
|
||||
|
||||
// validate the fee budget
|
||||
const minEstFees = toPositiveNumber(routingFeeMsat)
|
||||
const outgoingMaxFeeMsat = Math.ceil(msats * MAX_FEE_ESTIMATE_PERCENT)
|
||||
const outgoingMaxFeeMsat = Math.ceil(outgoingMsat * MAX_FEE_ESTIMATE_PERCENT)
|
||||
if (minEstFees > outgoingMaxFeeMsat) {
|
||||
throw new Error('Estimated fees are too high')
|
||||
}
|
||||
|
||||
// calculate the incoming invoice amount, without fees
|
||||
wrapped.mtokens = String(msats)
|
||||
wrapped.mtokens = String(Math.ceil(outgoingMsat * ZAP_SYBIL_FEE_MULT))
|
||||
console.log('outgoingMaxFeeMsat', outgoingMaxFeeMsat, 'wrapped', wrapped)
|
||||
|
||||
return {
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { msatsSatsFloor, msatsToSats, satsToMsats } from '@/lib/format'
|
||||
import { msatsToSats, satsToMsats } from '@/lib/format'
|
||||
import { createWithdrawal } from '@/api/resolvers/wallet'
|
||||
import { createInvoice } from 'wallets/server'
|
||||
|
||||
@ -12,13 +12,14 @@ export async function autoWithdraw ({ data: { id }, models, lnd }) {
|
||||
// excess must be greater than 10% of threshold
|
||||
if (excess < Number(threshold) * 0.1) return
|
||||
|
||||
// floor fee to nearest sat but still denominated in msats
|
||||
const maxFeeMsats = msatsSatsFloor(Math.ceil(excess * (user.autoWithdrawMaxFeePercent / 100.0)))
|
||||
// msats will be floored by createInvoice if it needs to be
|
||||
const msats = BigInt(excess) - maxFeeMsats
|
||||
const maxFeeMsats = Math.ceil(excess * (user.autoWithdrawMaxFeePercent / 100.0))
|
||||
const msats = excess - maxFeeMsats
|
||||
|
||||
// must be >= 1 sat
|
||||
if (msats < 1000n) return
|
||||
if (msats < 1000) return
|
||||
|
||||
// maxFee is expected to be in sats, ie "msatsFeePaying" is always divisible by 1000
|
||||
const maxFee = msatsToSats(maxFeeMsats)
|
||||
|
||||
// check that
|
||||
// 1. the user doesn't have an autowithdraw pending
|
||||
@ -32,7 +33,7 @@ export async function autoWithdraw ({ data: { id }, models, lnd }) {
|
||||
OR (
|
||||
status <> 'CONFIRMED' AND
|
||||
now() < created_at + interval '1 hour' AND
|
||||
"msatsFeePaying" >= ${maxFeeMsats}
|
||||
"msatsFeePaying" >= ${satsToMsats(maxFee)}
|
||||
))
|
||||
)`
|
||||
|
||||
@ -40,6 +41,6 @@ export async function autoWithdraw ({ data: { id }, models, lnd }) {
|
||||
|
||||
const { invoice, wallet } = await createInvoice(id, { msats, description: 'SN: autowithdrawal', expiry: 360 }, { models })
|
||||
return await createWithdrawal(null,
|
||||
{ invoice, maxFee: msatsToSats(maxFeeMsats) },
|
||||
{ invoice, maxFee },
|
||||
{ me: { id }, models, lnd, walletId: wallet.id })
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user