Commit Graph

52 Commits

Author SHA1 Message Date
ekzyis 8a19fc0905
Use <Alert> for auth banner in /settings (#1238) 2024-06-12 18:16:54 -05:00
ekzyis 286f53f2b3
Update zap undos info (#1237) 2024-06-12 18:16:41 -05:00
ekzyis 2597eb56f3
Item mention notifications (#1208)
* Parse internal refs to links

* Item mention notifications

* Also parse item mentions as URLs

* Fix subType determined by referrer item instead of referee item

* Ignore subType

Considering if the item that was referred to was a post or comment made the code more complex than initially necessary.

For example, notifications for /notifications are deduplicated based on item id and the same item could refer to posts and comments, so to include "one of your posts" or "one of your comments" in the title would require splitting notifications based on the type of referred item.

I didn't want to do this but also wanted to have consistent notification titles between push and /notifications, so I use "items" in both places now, even though I think using "items" isn't ideal from a user perspective. I think it might be confusing.

* Fix rootText

* Replace full links to #<id> syntax in push notifications

* Refactor mention code into separate functions
2024-06-03 12:12:42 -05:00
ekzyis a7bc757514
Use same button to generate and delete API keys (#1210) 2024-05-30 16:24:18 -05:00
ekzyis 94cce9155d
Frontend payment UX cleanup (#1194)
* Replace useInvoiceable with usePayment hook

* Show WebLnError in QR code fallback

* Fix missing removal of old zap undo code

* Fix payment timeout message

* Fix unused arg in super()

* Also bail if invoice expired

* Fix revert on reply error

* Use JIT_INVOICE_TIMEOUT_MS constant

* Remove unnecessary PaymentContext

* Fix me as a dependency in FeeButtonContext

* Fix anon sats added before act success

* Optimistic updates for zaps

* Fix modal not closed after custom zap

* Optimistic update for custom zaps

* Optimistic update for bounty payments

* Consistent error handling for zaps and bounty payments

* Optimistic update for poll votes

* Use var balance in payment.request

* Rename invoiceable to prepaid

* Log cancelled invoices

* Client notifications

We now show notifications that are stored on the client to inform the user about following errors in the prepaid payment flow:

- if a payment fails
- if an invoice expires before it is paid
- if a payment was interrupted (for example via page refresh)
- if the action fails after payment

* Remove unnecessary passing of act

* Use AbortController for zap undos

* Fix anon zap update not updating bolt color

* Fix zap counted towards anon sats even if logged in

* Fix duplicate onComplete call

* Fix downzap type error

* Fix "missing field 'path' while writing result" error

* Pass full item in downzap props

The previous commit fixed cache updates for downzaps but then the cache update for custom zaps failed because 'path' wasn't included in the server response.

This commit is the proper fix.

* Parse lnc rpc error messages

* Add hash to InvoiceExpiredError
2024-05-28 12:18:54 -05:00
Tom Smith 2b2f2d589c
Show Alert Message on Settings Page (#1179)
* Show alert message

* Add extra line

* Use css var

* Restore lightning in filter

* Show alert at top of page
2024-05-17 10:47:06 -05:00
ekzyis 3f86981339
Fix wallet detach unavailable (#1150) 2024-05-06 15:04:05 -05:00
SatsAllDay 15f9950477
Store hashed and salted email addresses (#1111)
* first pass of hashing user emails

* use salt

* add a salt to .env.development (prod salt needs to be kept a secret)
* move `hashEmail` util to a new util module

* trigger a one-time job to migrate existing emails via the worker

so we can use the salt from an env var

* move newsletter signup

move newsletter signup to prisma adapter create user with email code path
so we can still auto-enroll email accounts without having to persist the email address
in plaintext

* remove `email` from api key session lookup query

* drop user email index before dropping column

* restore email column, just null values instead

* fix function name

* fix salt and hash raw sql statement

* update auth methods email type in typedefs from str to bool

* remove todo comment

* lowercase email before hashing during migration

* check for emailHash and email to accommodate migration window

update our lookups to check for a matching emailHash, and then a matching
email, in that order, to accommodate the case that a user tries to login
via email while the migration is running, and their account has not yet been migrated

also update sndev to have a command `./sndev email` to launch the mailhog inbox in your browser

also update `./sndev login` to hash the generated email address and insert it into the db record

* update sndev help

* update awards.csv

* update the hack in next-auth to re-use the email supplied on input to `getUserByEmail`

* consolidate console.error logs

* create generic open command

---------

Co-authored-by: Keyan <34140557+huumn@users.noreply.github.com>
Co-authored-by: keyan <keyan.kousha+huumn@gmail.com>
2024-05-04 18:06:15 -05:00
ekzyis 4961cc045b
Allow deletion of wallet logs (#1101)
* Allow deletion of wallet logs

* Refactor wallet logs client<>server glue code

* Use variant='link' and className='text-muted fw-bold nav-link' for clear & cancel

There is a bug though: 'clear' stays highlighted after modal is closed

* Include wallet in toast

* Delete logs on logout

* Fix ugly wallet name in confirm dialog

* Fix clear still highlighted after modal closed

* Only delete client wallet logs

* Fix ugly wallet name in toast

* Fix bad search and replace

* Use Wallet object as constant

* Also delete LNC logs on logout

---------

Co-authored-by: Keyan <34140557+huumn@users.noreply.github.com>
2024-05-03 14:14:33 -05:00
keyan 6aa5991520 litcli passthrough 2024-05-02 19:46:27 -05:00
ekzyis 4be54b74df
Use !configured to disable LNC default checkbox (#1117) 2024-04-28 13:03:37 -05:00
keyan 4a14e0342b don't allow lnc edits because they won't work 2024-04-27 19:02:16 -05:00
keyan 2da3762d40 unattach -> detach 2024-04-27 18:37:57 -05:00
Keyan c3d709b025
add lnc attached wallet (#1104)
* add litd to docker env

* lnc payments

* handle locked wallet configuration

* create new lnc connection for every action

* ensure creds are decrypted before reconnecting

* perform permissions check
2024-04-26 21:22:30 -05:00
Ben Allen ecedbd1527
Add PasswordInput component (#1090)
* feat: add PasswordHider

* feat: add PasswordInput

* fix typo and require requirement

* merge state

* use ...props and lnbits password required

---------

Co-authored-by: Keyan <34140557+huumn@users.noreply.github.com>
2024-04-21 17:28:57 -05:00
keyan 1a25179a98 modal spacing fixes 2024-04-16 15:33:00 -05:00
Michael Bumann dec4452d62
Use password field to NWC connection (#1076)
This should prevent the browser from saving and auto-completing the NWC connection string
2024-04-16 10:53:33 -05:00
ekzyis 9f4d5e13aa
CLN autowithdrawal (#1042)
* Add CLN node to docker-compose.yml

* Attach CLN wallet via CLNRest

* Remove leading space

* Implement autowithdrawal to CLN in worker

* Fix UnhandledSchemeError during build

See https://github.com/vercel/next.js/discussions/33982

* Refactor CLN invoice code into @/lib/cln

* Fix missing env vars

* Fix validation error if rune invalid

* Update header

* Add rune placeholder

* Fix missing expiry for test invoice

* Remove nonsensical comment

* Remove unnecessary async

* Show level SUCCESS as OK in logs

* Add stacker_cln commands to sndev

* fix sndev posix compliance, add cln_withdraw

* give stacker_cln larger channels

---------

Co-authored-by: Keyan <34140557+huumn@users.noreply.github.com>
Co-authored-by: keyan <keyan.kousha+huumn@gmail.com>
2024-04-14 17:34:21 -05:00
SatsAllDay e6b825dafe
Mute Management Settings Page (#1034)
* first pass of a mute mgmt page, ported from subscription mgmt page pr

* adjust error message for mutes

* muted users -> muted stackers

* fix typo in component name
2024-04-08 09:13:56 -05:00
SatsAllDay 992fc54160
Subscription management page (#1000)
* first pass of a subscription management page under settings

* add tabs to settings ui

* NymActionDropdown

* update Apollo InMemoryCache to merge paginated list of my subscribed users

* various updates

* switch from UsersNullable to Users

* bake the nym action dropdwon into the user component

* add back fields to the user query

* `meSubscriptionPosts`, `meSubscriptionComments`, `meMute`

* Refetch my subscribed users when a user subscription is changed

* update user list to hide stats in the subscribed list users

* update my sub'd users fragment to remove unnecessary user fields

* memoize subscribe user context provider value to avoid re-renders

* use inner join instead of left join

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

* throw error when unauthenticated

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

---------

Co-authored-by: Keyan <34140557+huumn@users.noreply.github.com>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
2024-04-03 19:38:47 -05:00
ekzyis 15fb7f446b
Wallet Logs (#994)
* nwc wallet logs

* persist logs in IndexedDB

* Potential fix for empty error message

* load logs limited to 5m ago from IDB

* load logs from past via query param

* Add 5m, 1h, 6h links for earlier logs

* Show end of log

* Clamp to logStart

* Add log.module.css

* Remove TODO about persistence

* Use table for logs

* <table> fixes bad format with fixed width and message overflow into start of next row
* also using ---start of log--- instead of ---end of log--- now
* removed time string in header nav

* Rename .header to .logNav

* Simply load all logs and remove navigation

I realized the code for navigation was most likely premature optimization which even resulted in worse UX:
Using the buttons to load logs from 5m, 1h, 6h ago sometimes meant that nothing happened at all since there were no logs from 5m, 1h, 6h ago.
That's why I added a time string as "start of logs" so it's at least visible that it changed but that looked bad so I removed it.

But all of this was not necessary: I can simply load all logs at once and then the user can scroll around however they like.

I was worried that it would be bad for performance to load all logs at once since we might store a lot of logs but as mentioned, that's probably premature optimization.

WHEN a lot of logs are stored AND this becomes a problem (What problem even? Slow page load?), THEN we can think about this.

If page load ever becomes slow because of loading logs, we could probably simply not load the logs at page load but only when /wallet/logs is visited.

But for now, this works fine.

* Add follow checkbox

* Create WalletLogs component

* Embed wallet logs

* Remove test error

* Fix level padding

* Add LNbits logs

* Add logs for attaching LND and lnAddr

* Use err.message || err.toString?.() consistently

* Autowithdrawal logs

* Use details from LND error

* Don't log test invoice individually

* Also refetch logs on error

* Remove obsolete and annoying toasts

* Replace scrollIntoView with scroll

* Use constant embedded max-height

* Fix missing width: 100% for embedded logs

* Show full payment hash and preimage in logs

* Also parse details from LND errors on autowithdrawal failures

* Remove TODO

* Fix accidental removal of wss:// check

* Fix alignment of start marker and show empty if empty

* Fix sendPayment loop

* Split context in two
2024-04-03 17:27:21 -05:00
keyan 43ebb44866 consitent top padding settings, profiles, satistics 2024-03-28 17:09:57 -05:00
Keyan df7e944bf8
Merge pull request #980 from stackernews/hashed-api-keys
Hash API keys with SHA-256 before storing them
2024-03-27 13:02:57 -05:00
ekzyis 8f39a229c3 Fix overlay trigger hitbox 2024-03-26 22:33:18 +01:00
ekzyis 121205fa4b Add delete obstacle 2024-03-26 22:33:18 +01:00
ekzyis e68cbd8469 Remove unnecessary export of ApiKey component 2024-03-26 22:33:18 +01:00
ekzyis 17a0106fcc Hash API keys with SHA-256 and never show them again 2024-03-26 22:33:18 +01:00
ekzyis 52b2b788f8 Fix zap undo wrong default value shown 2024-03-26 17:57:20 +01:00
ekzyis 3388f818cf Add withdrawal notifications 2024-03-26 00:50:48 +01:00
ekzyis 81502f8645 Better zapUndos default 2024-03-25 20:34:28 +01:00
ekzyis fe3724aa7d Rename to ZapUndosField
This makes the component name more consistent with the setting.
2024-03-25 20:34:28 +01:00
ekzyis 46f044552a Remove unnecessary false 2024-03-25 20:34:28 +01:00
ekzyis c2aef34ba2 Add threshold for zap undos 2024-03-25 20:34:28 +01:00
ekzyis d237861ff5
Use module path aliases (#938)
* Use module path aliases

* fix broken refactor

* path mapping for svgs, style, and remaining places (bonus: lose babel dep)

---------

Co-authored-by: keyan <keyan.kousha+huumn@gmail.com>
2024-03-19 19:37:31 -05:00
ekzyis 2ba4063645 Add setting for no referral links on copy 2024-03-17 16:23:03 +01:00
ekzyis 687012d1a0
API Keys (#915)
* Generate API key in settings

* Check x-api-key for GraphQL API requests

* Don't fallback to cookie if x-api-key header was provided

* Select all session fields

* Fix error if API key not found

* Fix style in settings via form-label className

---------

Co-authored-by: Keyan <34140557+huumn@users.noreply.github.com>
2024-03-14 15:32:34 -05:00
ekzyis 817234a7fa
More zap undo fixes (#872)
* Don't throw error if invoice attached

* Only show progress bar for undo toasts

* Update zap undo info in settings

* Skip zap undo toast flow for external payments
2024-02-24 11:38:40 -06:00
ekzyis fa4f09ddca
Territory notifications for everyone (#870)
* Territory notifications

* Migrate old setting to new table

* Auto subscribe founders to their territories on creation

* Fix (un)subscribe not shown to founder

* Rename to toggleSubSubscription

* Fix inconsistency between toggleSubSubscription and toggleMuteSub

* Add dedicated button in header for following territories

* Don't drop noteTerritoryPosts column

* Fix db dip in Sub.meSubscription resolver

* Move territory subscribe to new territory context menu

* Decrease space between share icon and mute button

* Fix eslint
2024-02-23 09:12:49 -06:00
Austin Kelsay 565e939245
Nostr crossposting all item types (#779)
* crosspost-item

* crosspost old items, update with nEventId

* Updating noteId encoding, cleaning up a little

* Fixing item-info condition, cleaning up

* Linting

* Add createdAt variable back

* Change instances of eventId to noteId

* Adding upsertNoteId mutation

* Cleaning up updateItem, using toasts to communivate success/failure in crosspost-item

* Linting

* Move crosspost to share button, make sure only OP can crosspost

* Lint

* Simplify conditions

* user might have no nostr extension installed

Co-authored-by: ekzyis <27162016+ekzyis@users.noreply.github.com>

* change upsertNoteId to updateNoteID for resolver and mutations, change isOp to mine, remove unused noteId params

* Basic setup for crossposting poll / link items

* post rebase fixes and Bounty and job crossposts

* Job crossposting working

* adding back accidentally removed import

* Lint / rebase

* Outsource as much crossposting logic from discussion-form into use-crossposter as possible

* Fix incorrect property for user relays, fix itemId param in updateNoteId

* Fix toast messages / error cases in use-crossposter

* Update item forms to for updated use-crossposter hook

* CrosspostDropdownItem in share updated to accomodate use-crossposter update

* Encode paramaterized replacable event id's in naddress format with nostr-tools, bounty to follw nip-99 spec

* Increase timeout on relay connection / cleaning up

* No longer crossposting job

* Add blastr, fix crosspost button in item-info for polls/discussions, finish removing job crosspostr code

* Fix toaster error, create reusable crossposterror function to surface toaster

* Cleaning up / comments / linting

* Update copy

* Simplify CrosspostdropdownItem, keep replies from being crossposted

* Moved query for missing item fields when crossposting to use-crossposter hook

* Remove unneeded param in CrosspostDropdownItem, lint

* Small fixes post rebase

* Remove unused import

* fix nostr-tools version, fix package-lock.json

* Update components/item-info.js

Co-authored-by: ekzyis <ek@stacker.news>

* Remove unused param, determine poll item type from pollCost field, add mutiny strfry relay to defaults

* Update toaster implementations, use no-cache for item query, restructure crosspostItem to use await with try catch

* crosspost info modal that lives under adv-post-form now has dynamic crossposting info

* Move determineItemType into handleEventCreation, mover item/event handing outside of do ... while loop

* Lint

* Reconcile skip method with onCancel function in toaster

* Handle failedRelays being undefined

* determine item type from router.query.type if available otherwise use item fields

* Initiliaze failerRelays as undefined but handle error explicitly

* Lint

* Fix crosspost default value for link, poll, bounty forms

---------

Co-authored-by: ekzyis <27162016+ekzyis@users.noreply.github.com>
Co-authored-by: ekzyis <ek@stacker.news>
Co-authored-by: Keyan <34140557+huumn@users.noreply.github.com>
2024-02-21 19:18:36 -06:00
ekzyis c57fcd6518
Allow zap undo's for short period of time (#857)
* Cancel zaps

* Hide zap error toast

* Immediately throw error about insufficient funds

* Optimistic UX

* Also hide success zap toast

* Show undo instead of cancel

* Include sat amount in toast

* Fix undo toasts removed on navigation

* Add setting for zap undos

* Add undo to custom zaps

* Use WithUndos suffix

* Fix toast flow transition

* Fix setting not respected

* Skip undo flow if funds insufficient

* Remove brackets around undo

* Fix insufficient funds detection

* Fix downzap undo

* Add progress bar to toasts

* Use 'button' instead of 'notification' in zap undo info

* Remove console.log

* Fix toast progress bar restarts

---------

Co-authored-by: Keyan <34140557+huumn@users.noreply.github.com>
2024-02-21 18:48:42 -06:00
Alex Lewin b3498fe277
Add Opt-in to Display Linked Accounts in Profile (#826)
* Add display linked accounts to settings

* Apply suggestions from code review

Co-authored-by: ekzyis <ek@stacker.news>

* small styling enhancements

---------

Co-authored-by: ekzyis <ek@stacker.news>
Co-authored-by: Keyan <34140557+huumn@users.noreply.github.com>
Co-authored-by: keyan <keyan.kousha+huumn@gmail.com>
2024-02-14 13:33:31 -06:00
keyan 5c3c7fb185 allow more restricted macroons fix #827 2024-02-14 12:58:25 -06:00
Keyan ec4e1b5da7
LND autowithdraw (#806)
* wip

* wip

* improved validatation, test connection before save, code reuse

* worker send to lnd

* autowithdraw priority
2024-02-13 13:17:56 -06:00
mzivil 6355d7eabc
Add nsfw setting to territories (#788)
* add nsfw column to sub

* add nsfw boolean to territorySchema

* save nsfw value in upsertSub mutation

* return nsfw value from Sub query for correct value in edit territory form

* add nsfw checkbox to territory form

* add nsfw badge to territory header

* add nsfwMode to user

* show nsfw badge next to item territory

* exclude nsfw sub from items query

* show nsfw mode checkbox on settings page

* fix nsfw badge formatting

* separate user from current, signed in user

* update relationClause to join with sub table

* refactor to simplify hide nsfw sql

* filter nsfw items when viewing user items

* hide nsfw posts for logged out users

* filter nsfw subs based on user preference

* show nsfw sub name if logged out user is viewing the page

* show current sub at the top of the list instead of bottom

* always join item with sub to check nsfw

* check for sub presence before showing nsfw badge on item

* skip manually adding sub to select if sub is null

* fix relationClause to join with root item

* move moderation and nsfw into accordion

---------

Co-authored-by: Keyan <34140557+huumn@users.noreply.github.com>
2024-02-09 20:35:32 -06:00
ekzyis b3d485e8c4
Refactor default payment method setting (#803)
* Refactor setting of default providers

* fixed warning about component update while rendering another component
* individual providers no longer need to know if they are the default or not
* default setting is now handled by WebLNContext -- the same context that returns the provider. this makes a lot more sense and is a lot easier to read
* default payment checkbox is now also disabled if there is only one enabled provider or if it is the default provider

* Fix order lost on page reload

On page reload, the providers were synced in the order they were loaded.

This means that the default payment provider setting was lost.

Fixed this by syncing order to local storage and on page reload, only syncing providers when they were initialized (else the order would have been lost again).
2024-02-09 09:42:26 -06:00
ekzyis 310011f05d
Expose WebLN interface via React Context (#749)
* Add LNbits card

* Save LNbits Provider in WebLN context

* Check LNbits connection on save

* refactor: put LNbitsProvider into own file

* Pay invoices using WebLN provider from context

* Remove deprecated FIXME

* Try WebLN provider first

* Fix unhandled promise rejection

* Fix this in sendPayment

* Be optimistic regarding WebLN zaps

This wraps the WebLN payment promise with Apollo cache updates.

We will be optimistics and assume that the payment will succeed and update the cache accordingly.

When we notice that the payment failed, we undo this update.

* Bold strike on WebLN zap

If lightning strike animation is disabled, toaster will be used.

* Rename undo variable to amount

* Fix zap undo

* Add NWC card

* Attempt to check NWC connection using info event

* Fix NaN on zap

Third argument of update is reserved for context

* Fix TypeError in catch of QR code

* Add basic NWC payments

* Wrap LNbits getInfo with try/catch

* EOSE is enough to check NWC connection

* refactor: Wrap WebLN providers into own context

I should have done this earlier

* Show red indicator on error

* Fix useEffect return value

* Fix wrong usage of pubkey

The event pubkey is derived from the secret. Doesn't make sense to manually set it. It's also the wrong pubkey: we're not the wallet service.

* Use p tag in NWC request

* Add comment about required filter field

* Aesthetic changes to NWC sendPayment

* Add TODO about receipt verification

* Fix WebLN attempted again after error

* Fix undefined name

* Add code to mock NWC relay

* Revert "Bold strike on WebLN zap"

This reverts commit a9eb27daec0cd2ef30b56294b05e0056fb5b4184.

* Fix update undo

* Fix lightning strike before payment

* WIP: Wrap WebLN payments with toasts

* add toasts for pending, error, success
* while pending, invoice can be canceled
* there are still some race conditions between payiny the invoice / error on payment and invoice cancellation

* Fix invoice poll using stale value from cache

* Remove unnecessary if

* Make sure that pay_invoice is declared as supported

* Check if WebLN provider is enabled before calling sendPayment

* Fix bad retry

If WebLN payments failed due to insufficient balances, the promise resolved and thus the action was retried but failed immediately since the invoice (still) wasn't paid.

* Fix cache undo update

* Fix no cache update after QR payment

* refactor: Use fragments to undo cache updates

* Remove console.log

* Small changes to NWC relay mocking

* Return SendPaymentResponse

See https://www.webln.guide/building-lightning-apps/webln-reference/webln.sendpayment

* Also undo cache update on retry failure

* Disable NWC mocking

* Fix initialValue not set

But following warning is now shown in console:

"""
Warning: A component is changing a controlled input to be uncontrolled.
This is likely caused by the value changing from a defined to undefined, which should not happen.
Decide between using a controlled or uncontrolled input element for the lifetime of the component. More info: https://reactjs.org/link/controlled-components
"""

* Remove comment since only relevant for blastr (mutiny relay)

* Remove TODO

* Fix duplicate cache update

* Fix QR modal not closed after payment

* Ignore lnbits variable unused

* Use single relay connection for all NWC events

* Fix missing timer and subscription cleanup

* Remove TODO

Confirmed that nostr-tools verifies events and filters for us.

See https://github.com/nbd-wtf/nostr-tools/blob/master/abstract-relay.ts#L161

* Fix switch from controlled to uncontrolled input

* Show 'configure' on error

* Use budgetable instead of async

* Remove EOSE listener

Only nostr.mutinywallet.com didn't respond with info events due to implementation-specific reasons. This is no longer the case.

* Use invoice expiry for NWC timeout

I don't think there was a specific reason why I used 60 seconds initially.

* Validate LNbits config on save

* Validate NWC config on save

* Also show unattach if configuration is invalid

If unattach is only shown if configuration is valid, resetting the configuration is not possible while it's invalid. So we're stuck with a red wallet indicator.

* Fix detection of WebLN payment

It depended on a Apollo cache update function being available. But that is not the case for every WebLN payment.

* Fix formik bag lost

* Use payment instead of zap in toast

* autoscale capture svc by response time

* docs and changes for testing lnbits locally

* Rename configJSON to config

Naming of config object was inconsistent with saveConfig function which was annoying.

Also fixed other inconsistencies between LNbits and NWC provider.

* Allow setting of default payment provider

* Update TODO comment about provider priority

The list 'paymentMethods' is not used yet but is already implemented for future iterations.

* Add wallet security disclaimer

* Update labels

---------

Co-authored-by: Keyan <34140557+huumn@users.noreply.github.com>
Co-authored-by: keyan <keyan.kousha+huumn@gmail.com>
2024-02-08 12:33:13 -06:00
keyan d45a46e7a4 improve copy on autowithdraw 2024-01-13 11:28:14 -06:00
ekzyis 12f9c4761d Fix isNaN checks 2024-01-13 17:32:53 +01:00
keyan 59ff146cc9 fix fee percent typo 2024-01-12 23:50:17 -06:00
keyan 6288db1b83 fix autowithdraw wording 2024-01-12 23:45:38 -06:00