ekzyis d89a4a429a
Wallet v2 (#2169)
* Migrate vault entries to new schema (#2092)

* Migrate existing vault entries to new schema

* Read+write new vault schema

* Drop VaultEntry table

* Refactor vaultPrismaFragments

* Remove wrong comment

* Remove TODO

* Fix possible race condition on update of vault key

* Remove lib/object.js

* Wallet schema v2 (#2146)

* Add wallet-v2 TODOs

* Update checkWallet

* Wallet list

* Delete almost all wallet v1 code

and add some code for wallet protocol forms

* Define protocol display name in JSON

* Show form per protocol

* Increase max-height of image in form

* Add JSdoc for protocols, form validation

* Use wallet cards again

My wallet list was quite ugly and I couldn't look at it anymore.

* Refactor hooks in wallet provider

* Fix PasswordInput not used

* Read encrypted wallets

* Decrypt wallets

* useWalletQuery now returns decrypted wallets
* Refactor useIndexedDB because its only purpose will be to store the key, so no need for pagination code etc.
* There is still a bug: if the wallet is not decrypted on first render, the form will not see the decrypted value. See TODO.

* Rename protocolJson to protocol

it no longer uses a JSON file

* Fix form not updated with decrypted API key

* Fix wallet template forms

* Fix optional shown as hint

* Rename to mapUserWalletResolveTypes

* Save LNbits send and recv

TODO:

* implement resolvers for other protocols
* fix double update required for trigger?
* add missing validation on server
* add missing network tests
* don't import from wallets/client on server

* Move definitions to lib/wallets.json and lib/protocols

* Fix ProtocolWallet.updated_at not updated by trigger

* Move wallet fragments into wallets/client/fragments/

* move invoice fragments to fragments/invoice.js
* remove some unused fragments that I don't think I also will not use
* move fragments that will be generated in own file

* Move wallet resolvers into wallets/server/resolvers

* Fix missing authorization check on wallet update

* Run all shared code in generic wallet update function

* Fix 'encrypt' flag not set for blink send currency

* Add mutations for all protocols

* Fix macaroon validation

* Fix CLN socket value not set

* Add server-side schema validation

* Fix JSDoc typedef for protocols

* Don't put JSDoc into separate file

* Create test invoices on save

* Also move type resolvers into wallets/server/resolvers

* Fix unconfigured protocols of UserWallet not found

* Fix Blink API key in wallet seed

* Test send payment on save (except LNC)

This does not include LNC because LNC cannot be saved yet

* Check if window.webln is defined on save

* Create new wallets from templates

* Separate protocols in wallets/lib into individual files

* Use justify-content-start for protocol tabs

and larger margin at the top

* Add LNC to client protocols

* Only return wallets from useWallets

* Query decrypted wallets

* Payments with new wallets

* More wallet logos

* Fix TypeError in useIndexedDB

* Add protocol attach docs

* Fix undefined useWalletRecvPrompt import

* Remove outdated TODOs

* First successful zap to new wallets

* Fix walletLogger imports

* Fix sequences

* the sequences for InvoiceForward and DirectPayment were still starting at 1
* when using setval() with two arguments, nextval() will return the second argument+1 (see https://www.postgresql.org/docs/current/functions-sequence.html)

* Rename ProtocolWallet columns

* Remove more outdated TODOs

* Update wallet indicator

* Fix page reset on route change

* Refactor __typename checks into functions

* Refactor protocol selection into own hook

* Add button to detach protocol

* Refetch wallet on save and detach

* Refetch wallets on change

* Always show all templates

* Refactor WalletLink component

* Also put wallet into forms context

* Remove outdated TODOs

* Use useMemo in wallets hooks

* Passphrase modals

* prompt for password if decryption failed
* add button to reveal passphrase on wallet page

TODO:
* remove button if passphrase was revealed or imported
* encrypt wallets with new key on passphrase reveal

* Fix protocol missing as callback dependency

* Encrypt wallets with new key on passphrase export

* Update 'unlock wallets' text

* Rename wallet mutation hooks

* Remove 'removeWallet' mutation

Wallets are automatically deleted when all protocols are deleted

* Passphrase reset

* Use 110px as minimum width for bip39 words

longest bip39 words are 8 characters and they fit into 103px so I rounded up to 110px.

* Also disable passphrase export on save

* Wallet settings

* Fix wallet receive prompt

* Remove unused parameters from postgres function

* Rename UserWallet to Wallet, ProtocolWallet to WalletProtocol

* Use danger variant for button to show passphrase

* Fix inconsistent imports and exports

* Remove outdated TODOs

* wallet logs

* Remove outdated comment

* Make sure wallets are used in priority order

* Separate wallets from templates in reducer

* Fix missing useCallback dependencies

* Refactor with useWalletLogger hook

* Move enabled to WalletProtocol

* Add checkbox to enable/disable protocol

* Fix migration with prod db dump

* Parse Coinos relay URLs

* Skip network tests if only enabled changed

* Allow IndexedDB calls without session

* Add code to migrate old CryptoKey

* first try to use existing CryptoKey before generating a new one
* bump IDB version to delete old object stores and create new ones
* return IDB callbacks with useMemo
* don't delete old IDB right away, wait until next release

* Fix ghost import error

*Sometimes*, I get import errors because it tries to resolve @/wallets/server to wallets/server.js instead of wallets/server/index.js.

For the files in wallets/server, it kind of makes sense because it's a circular import.

But I don't know why the files in worker/ have this problem.

Interestingly, it only seems to happen with walletLogger imports, so I guess its related to its import chain.

Anyway, this commit should make sure this never happens again ...

* Skip wallets queries if not logged in

* Split CUSTOM wallet into NWC and LN_ADDR

* Migrate local wallets

* Link to /wallets/:id/receive if send not supported

* Hide separator if there are no configured wallets

* Save LNC

* Add one-liner to attach LNC

* Update wallet priorities via DnD

* Wallet logs are part of protocol resolvers

* Fix logging to deleted protocol

* Fix trying to fetch logs for template

* also change type to Int so GraphQL layer can catch trying to fetch string IDs as is the case for templates

* Fix embedded flag for wallets logs not set

* Remove TODO

* Decrease max-height for embedded wallet logs on big screens

* Fix missing refetch on wallet priority update

* Set priorities of all wallets in one tx

* Fix nested state update

* Add DragIcon

* DnD mobile support and refactor

* Add CancelButton to wallet settings

* Remount form if path changes

This fixes the following warning in the console:

"""
Warning: A component is changing an uncontrolled input to be controlled. This is likely caused by the value changing from undefined to a defined value, which should not happen. Decide between using a controlled or uncontrolled input element for the lifetime of the component.
"""

* Support string and object for wallet.image JSON

* Append domain to lightning address inputs

* Remove outdated TODOs

* Add template IDs to wallet JSON

* Fix missing callback dependency

* Implement lightning address save in receive prompt

* Update TODOs

* Fix missing check for enabled

* Pay QR codes with WebLN as anon

* Add logo for NWC

* Fix trying to save logs for template

* Add template logs

* Fix inconsistent margin

* Always throw on missing key

* Remove misleading comment

Wallets are returned even if decryption fails so we can show the unlock page if a wallet is stored as encrypted in the context.

Maybe I should rethink this.

* Check for existing wallets on local wallet migration

* Fix local wallet migration causing duplicates

* Fix protocol reattached on detach due to migration

* Fix form not centered

* Fix ZEUS lightning address domain

* Add placeholder, help, hints etc. to wallet form inputs

* Fix wallet badges not updated

* Remove unused declared variables

* Rename to ATTACH_PAGE

* Fix 500 error if no amount was given to LNURLp endpoint

* Tag log messages with wallet name

* Only skip network tests if we're disabling the wallet

* Rename var to networkTests

* Continue to store key hash in IndexedDB

* Rethink wallet state management

If decryption failed, the function to decrypt the wallets didn't throw but simply returned wallets that were still encrypted.

This was bad because it meant we could not rely on the wallets in the state being decrypted, even though this was the original idea behind the query hooks: hide the details of encryption and decryption inside them.

Because of this, we had to check if the wallets were still encrypted before we ran the wallet migration since we want to check if a protocol already exists.

This commit fixes this by making encryption and decryption always throw (and catching the errors), as well as returning a ready state from hooks. A hook might not be ready because it still needs to load something (in the case of the crypto hooks, it's loading the key from IndexedDB). Callers check that ready state before they call the function returned by the hook.

So now, the wallet migration hook can itself simply check if the hook to encrypt wallets is ready and if the wallets are no longer loading to let callers know if it itself is ready.

Since we also relied on wallets stored as encrypted in the context to show the unlock page, this was also changed by comparing the local and remote key hash.

* Add empty line

* Save new key hash during wallet reset

* Only receive protocol upserts require networkTests param

* Compare key hashes on server on each save

* Delete old code

* Fix card shows attach instead of configure

* Fix empty wallets created during migration

The old schema can contain '' instead of NULL in the columns of wallets for receiving.

* Update reset passphrase text

* Wrap passphrase reset in try/catch

* Fix migrate called multiple times

* Update key hash on migration if not set

* Fetch local wallets in migrate

* Fix missing await on setKey

* Let first device set key hash

* Fix indicator not shown if wallets locked

* Check if IndexedDB is available

* Fix inconsistent WebLN error message

* Disable WebLN if not available

* Remove outdated TODO

* Cursor-based pagination for wallet logs

* Fix log message x-overflow

* Add context to wallet logs

* Wrap errors are warnings in logs

* Rename wallet v2 migrations

* Update wallet status during logging

* Fix wallet logs loading state

The loading state would go from false -> true -> false because it's false when the lazy query wasn't called yet.

* Add wallet search

* Add Alby Go wallet

* Revert "Add Alby Go wallet"

This reverts commit 926c70638f1673756480c848237e52d5889dc037.

* Fix wallet logs sent by client don't update protocol status

* Fix mutation name

* put drag icon on opposite corner

* Add wallets/README.md

* Fix inconsistent case in wallets/README.md

* Fix autoprefixer warning about mixed support

This warning was in the app logs:

app     | Warning
app     |
app     | (31:3) autoprefixer: end value has mixed support, consider using flex-end instead
app     |
app     | Import trace for requested module:
app     | ./styles/wallet.module.css
app     | ./wallets/client/hooks/prompt.js
app     | ./wallets/client/hooks/index.js
app     | ./wallets/client/context/hooks.js
app     | ./wallets/client/context/provider.js
app     | ./wallets/client/context/index.js

* fix effect of wallet indicators on logo

* Fix deleting wallet template logs

* Use name as primary key of WalletTemplate

* Fix wallet_clear_vault trigger not mentioned in README

* Fix wallet receive prompt

Also remove no longer needed templateId from wallets.json and helper functions

* Use findUnique since name is now primary key

* Merge Alby wallets into one

* Remove unused name parameter from WalletsForm component

* Fix number check to decide if wallet or template

* Update wallet encryption on click, not as effect

* add cashu.me and lightning address logos

* add images

* Use recommended typeof to check if IDB available

* Also check if IDB available on delete

* Use constraint triggers

* Add indices on columns used for joins

* Fix inconsistent CLEAR OR REPLACE TRIGGER

* Attach wallet_check_support trigger to WalletProtocol table

* Update wallets/README.md

* Remove debugging code

* Refactor reducer: replace page with status

* Show 'wallets unavailable' if device does not support IndexedDB

* Remove duplicate ELSIF condition

* Fix hasSendWallet

The useSendWallets hook was not checking if the returned send wallets are enabled.

Since the components that used that hook only need to know if there is a send wallet, I replaced the useSendWallets hook with a useHasSendWallet hook.

* Add Cash App wallet

* fix changes loglevel enum

* Fix key init race condition in strict mode if no key exists yet

* Formatting

* Fix key init race condition via transactions in readwrite mode

* Replace Promise.withResolvers with regular promises

* replace generic spinner with our usual

---------

Co-authored-by: k00b <k00b@stacker.news>
2025-07-15 16:36:43 -05:00

24 lines
4.8 KiB
XML

<svg width="176" height="56" viewBox="0 0 176 56" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_1995_141)">
<path opacity="1.01495" d="M164.279 4.34717L164.917 5.60721C165.116 6.00637 165.436 6.32704 165.854 6.54658L167.11 7.18658L165.854 7.82657C165.456 8.02616 165.136 8.34682 164.917 8.76595L164.279 10.026L163.641 8.76595C163.442 8.36678 163.122 8.04612 162.704 7.82657L161.448 7.18658L162.704 6.54658C163.102 6.34699 163.422 6.02633 163.641 5.60721L164.279 4.34717Z" fill="#0822F5"/>
<path opacity="1.09657" d="M81.6394 1.93066L82.2775 3.1907C82.4764 3.58987 82.7961 3.91053 83.214 4.13007L84.4702 4.77007L83.214 5.41007C82.816 5.60965 82.4963 5.93032 82.2775 6.34944L81.6394 7.60948L81.0013 6.34944C80.8024 5.95028 80.4827 5.62961 80.0648 5.41007L78.8086 4.77007L80.0648 4.13007C80.4628 3.93049 80.7825 3.60983 81.0013 3.1907L81.6394 1.93066Z" fill="#0822F5"/>
<path opacity="1.10383" d="M167.239 39.3579L167.877 40.6179C168.076 41.0171 168.396 41.3378 168.814 41.5573L170.07 42.1973L168.814 42.8373C168.416 43.0369 168.096 43.3576 167.877 43.7767L167.239 45.0367L166.601 43.7767C166.402 43.3775 166.082 43.0569 165.664 42.8373L164.408 42.1973L165.664 41.5573C166.062 41.3577 166.382 41.0371 166.601 40.6179L167.239 39.3579Z" fill="#0822F5"/>
<path opacity="0.905724" d="M2.83081 23.1975L3.46886 24.4575C3.66784 24.8567 3.98753 25.1774 4.40539 25.3969L5.66161 26.0369L4.40539 26.6769C4.00743 26.8765 3.68774 27.1972 3.46886 27.6163L2.83081 28.8763L2.19275 27.6163C1.99377 27.2171 1.67408 26.8965 1.25622 26.6769L0 26.0369L1.25622 25.3969C1.65418 25.1973 1.97387 24.8767 2.19275 24.4575L2.83081 23.1975Z" fill="#0822F5"/>
<path d="M14.5654 35.5643L42.8536 21.3619V20.0859H14.5654V9.99365H60.511V25.1327L32.2799 39.2207V40.4953H60.6277V50.5876H14.5654V35.567V35.5643Z" fill="black"/>
<path d="M96.2128 30.9251V29.5333C103.993 29.5333 109.165 26.2694 109.165 20.564C109.165 13.0557 103.698 10.0007 93.8887 10.0007H63.624V50.5801H93.8887C104.461 50.5801 109.165 46.7653 109.165 40.7885C109.165 34.8116 105.392 30.9251 96.2128 30.9251ZM88.1369 41.3606H79.017V34.5774H88.1369C91.0871 34.5774 92.6099 35.9147 92.6099 37.9411C92.6099 40.5636 90.8337 41.3593 88.1369 41.3593V41.3606ZM88.1369 25.9408H79.017V19.2122H88.1369C90.5034 19.2122 92.6099 19.8003 92.6099 22.6304C92.6099 25.4605 90.1824 25.9395 88.1369 25.9395V25.9408Z" fill="black"/>
<path d="M111.301 9.99854H139.126C156.021 9.99854 163.636 18.3438 163.636 30.2882C163.636 42.834 154.482 50.5779 139.126 50.5779H111.301V9.99854ZM147.199 30.2882C147.199 23.1245 142.218 20.4328 137.382 20.4328H127.392V40.1423H137.382C142.16 40.1423 147.199 37.4506 147.199 30.2869V30.2882Z" fill="black"/>
<path opacity="0.596148" d="M146.402 14.2175C146.402 14.2175 154.529 15.081 155.152 3.33887C155.152 3.33887 155.073 13.036 163.369 14.1842C163.369 14.1842 155.707 14.6393 155.401 24.8353C155.39 24.8473 155.459 15.2061 146.402 14.2175Z" fill="#F0FF27" stroke="black" stroke-linejoin="round"/>
<path opacity="0.324772" d="M1.16504 39.8337C1.16504 39.8337 9.29134 40.6972 9.9148 28.9551C9.9148 28.9551 9.83521 38.6522 18.1313 39.8004C18.1313 39.8004 10.4693 40.2555 10.1642 50.4516C10.1523 50.4635 10.2212 40.8223 1.16504 39.8337Z" fill="#F0FF27" stroke="black" stroke-linejoin="round"/>
<path opacity="0.151851" d="M164.346 17.9782C164.346 17.9782 169.266 18.5011 169.644 11.3906C169.644 11.3906 169.596 17.2624 174.618 17.9569C174.618 17.9569 169.979 18.2324 169.794 24.4061C169.787 24.4128 169.828 18.5756 164.346 17.9769V17.9782Z" fill="#F0FF27" stroke="black" stroke-linejoin="round"/>
<path opacity="0.0628216" d="M67.9766 7.58759C67.9766 7.58759 72.8966 8.1105 73.2747 1C73.2747 1 73.227 6.87175 78.2492 7.5663C78.2492 7.5663 73.6103 7.84173 73.4246 14.0155C73.418 14.0222 73.4591 8.18501 67.9766 7.58626V7.58759Z" fill="#F0FF27" stroke="black" stroke-linejoin="round"/>
<path opacity="0.0235497" d="M15.9355 23.2949C15.9355 23.2949 20.8556 23.8178 21.2337 16.7073C21.2337 16.7073 21.1859 22.579 26.2082 23.2736C26.2082 23.2736 21.5693 23.549 21.3836 29.7228C21.377 29.7294 21.4181 23.8923 15.9355 23.2935V23.2949Z" fill="#F0FF27" stroke="black" stroke-linejoin="round"/>
<path opacity="0.01" d="M102.614 50.321L103.252 51.5811C103.451 51.9802 103.771 52.3009 104.189 52.5205L105.445 53.1605L104.189 53.8005C103.791 54 103.471 54.3207 103.252 54.7398L102.614 55.9999L101.976 54.7398C101.777 54.3407 101.457 54.02 101.039 53.8005L99.7832 53.1605L101.039 52.5205C101.437 52.3209 101.757 52.0002 101.976 51.5811L102.614 50.321Z" fill="#0822F5"/>
<path opacity="0.01" d="M89.5137 48.7829C89.5137 48.7829 94.4338 49.3058 94.8118 42.1953C94.8118 42.1953 94.7641 48.0671 99.7863 48.7616C99.7863 48.7616 95.1474 49.037 94.9617 55.2108C94.9551 55.2175 94.9962 49.3803 89.5137 48.7816V48.7829Z" fill="#F0FF27" stroke="black" stroke-linejoin="round"/>
</g>
<defs>
<clipPath id="clip0_1995_141">
<rect width="176" height="56" fill="white"/>
</clipPath>
</defs>
</svg>