Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Keycard signing for dapp interactions #21785

Open
wants to merge 11 commits into
base: develop
Choose a base branch
from

Conversation

clauxx
Copy link
Member

@clauxx clauxx commented Dec 10, 2024

fixes #21618

Summary

  1. Added support for signing dapp requests with the keycard
  2. Removed WC methods that are not supported by test dapps anymore: eth_sign, eth_signTransaction (previously could only be tested on test dapps)
  3. Fixed issue where dapp logo is not shown in request sometimes

Steps to test

  • Open Status
  • Log into a keycard profile
  • Connect to dapp
  • Send any request from dapp
  • Slide the authorization slider
  • Sign with the keycard
  • Dapp shows success

status: ready

@status-im-auto
Copy link
Member

status-im-auto commented Dec 10, 2024

Jenkins Builds

Click to see older builds (8)
Commit #️⃣ Finished (UTC) Duration Platform Result
✔️ 0983e41 #2 2024-12-10 14:49:40 ~4 min tests 📄log
✔️ 0983e41 #3 2024-12-10 14:55:24 ~9 min android 🤖apk 📲
✔️ 0983e41 #3 2024-12-10 14:56:14 ~10 min android-e2e 🤖apk 📲
✔️ 0983e41 #2 2024-12-10 15:01:00 ~15 min ios 📱ipa 📲
4eaab72 #4 2025-01-02 14:45:18 ~3 min tests 📄log
✔️ 4eaab72 #5 2025-01-02 14:47:58 ~6 min android-e2e 🤖apk 📲
✔️ 4eaab72 #4 2025-01-02 14:48:34 ~7 min ios 📱ipa 📲
✔️ 4eaab72 #5 2025-01-02 14:49:50 ~8 min android 🤖apk 📲
Commit #️⃣ Finished (UTC) Duration Platform Result
✔️ a2aa35c #6 2025-01-06 11:39:59 ~4 min tests 📄log
✔️ a2aa35c #6 2025-01-06 11:42:41 ~7 min ios 📱ipa 📲
✔️ a2aa35c #7 2025-01-06 11:42:56 ~7 min android-e2e 🤖apk 📲
✔️ a2aa35c #7 2025-01-06 11:44:28 ~9 min android 🤖apk 📲
4cc6aed #7 2025-01-09 13:49:37 ~4 min tests 📄log
✔️ 4cc6aed #8 2025-01-09 13:53:30 ~8 min android-e2e 🤖apk 📲
✔️ 4cc6aed #8 2025-01-09 13:54:00 ~8 min android 🤖apk 📲
✔️ 4cc6aed #7 2025-01-09 13:54:51 ~9 min ios 📱ipa 📲

@flexsurfer
Copy link
Member

this PR should wait for #21753 , because auth on keycard has little bit changed

@@ -8,7 +8,8 @@
[:auth-button-label {:optional true} [:maybe string?]]
[:auth-button-icon-left {:optional true} [:maybe keyword?]]
[:blur? {:optional true} [:maybe boolean?]]
[:theme {:optional true} [:maybe :schema.common/theme]]])
[:theme {:optional true} [:maybe :schema.common/theme]]
[:keycard-supported? {:optional true} [:maybe boolean?]]])
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we don't have this param anymore

@@ -45,6 +45,7 @@
[standard-authentication/slide-button
{:size :size-48
:track-text slide-button-text
:keycard-supported? true
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

:on-complete (when sign-on-keycard? #(on-auth-success ""))

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@flexsurfer what's the difference between the :on-complete and :on-auth-success props here? Looking at the one used in send (status-im.contexts.wallet.send.transaction-confirmation.view) and seems like the changes are recent:

  [standard-auth/slide-button {...
                                          :on-complete (when sign-on-keycard?
                                                         #(rf/dispatch
                                                           [:wallet/prepare-signatures-for-transactions
                                                            :send
                                                            ""]))
                                          :on-auth-success
                                          (fn [psw]
                                            (rf/dispatch
                                             [:wallet/prepare-signatures-for-transactions :send
                                              psw]))}]

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

on-complete is used when you need to sign on keycard, on-auth-success used if you need password (for keycard also, it will work)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it confusing yes, when we want to sign on keycard, we just need a signal from the slide button that it was activated, we don't need auth process

Copy link
Member Author

@clauxx clauxx Jan 2, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks! yes we might need to rethink this, since now if we pass :on-complete, then :on-auth-success will never be called. It might make sense to add the keycard (or signing in general) into standard-auth.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes we might need to rethink this

100%, thank you

(fn [{:keys [db]} [password]]
(let [prepared-hash (get-in db [:wallet-connect/current-request :prepared-hash])
address (get-in db [:wallet-connect/current-request :address])
keycard-sign? (-> (get-in db [:wallet :keypairs])
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you need to move this outside, because there are two options

  1. keypair is keycard we need to sign on keycard
  2. profile is keycard, means we need to get password from keycard and sign regular way with password

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

how can we know whether we need to actually sign on the keycard? I see that there's (get-in transaction-for-signing [:signingDetails :signOnKeycard]), but that comes from the router, which we don't use for dapps.

Copy link
Member

@flexsurfer flexsurfer Dec 11, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

keycard-sign? is correct you can use it, to know that you need to sign on keycard, but you need to move it outside of this event, you need to move this code

(if keycard-sign?
       {:fx [[:dispatch
              [:standard-auth/authorize-with-keycard

to where :on-complete is used

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done 👍

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

im not sure why you need check again, you already passed the empty password?

@VolodLytvynenko VolodLytvynenko self-assigned this Dec 16, 2024
@status-im-auto
Copy link
Member

50% of end-end tests have passed

Total executed tests: 8
Failed tests: 4
Expected to fail tests: 0
Passed tests: 4
IDs of failed tests: 727230,702745,727229,702843 

Failed tests (4)

Click to expand
  • Rerun failed tests

  • Class TestWalletMultipleDevice:

    1. test_wallet_send_asset_from_drawer, id: 727230
    Test setup failed: critical/test_wallet.py:22: in prepare_devices
        self.drivers, self.loop = create_shared_drivers(2)
    base_test_case.py:310: in create_shared_drivers
        drivers = loop.run_until_complete(start_threads(test_suite_data.current_test.name,
    /usr/lib/python3.10/asyncio/base_events.py:649: in run_until_complete
        return future.result()
    __init__.py:26: in start_threads
        returns[k] = await returns[k]
    /usr/lib/python3.10/concurrent/futures/thread.py:58: in run
        result = self.fn(*self.args, **self.kwargs)
    ../../../../status-app-prs@tmp/venv/lib/python3.10/site-packages/appium/webdriver/webdriver.py:257: in __init__
        super().__init__(
    ../../../../status-app-prs@tmp/venv/lib/python3.10/site-packages/selenium/webdriver/remote/webdriver.py:206: in __init__
        self.start_session(capabilities)
    ../../../../status-app-prs@tmp/venv/lib/python3.10/site-packages/appium/webdriver/webdriver.py:360: in start_session
        raise SessionNotCreatedException(
     A valid W3C session creation response must contain a non-empty "sessionId" entry. Got "{'value': {'error': 'unknown error', 'message': 'failed serving request POST /wd/hub/session', 'stacktrace': ''}}" instead
    



    2. test_wallet_send_eth, id: 727229

    Test setup failed: critical/test_wallet.py:22: in prepare_devices
        self.drivers, self.loop = create_shared_drivers(2)
    base_test_case.py:310: in create_shared_drivers
        drivers = loop.run_until_complete(start_threads(test_suite_data.current_test.name,
    /usr/lib/python3.10/asyncio/base_events.py:649: in run_until_complete
        return future.result()
    __init__.py:26: in start_threads
        returns[k] = await returns[k]
    /usr/lib/python3.10/concurrent/futures/thread.py:58: in run
        result = self.fn(*self.args, **self.kwargs)
    ../../../../status-app-prs@tmp/venv/lib/python3.10/site-packages/appium/webdriver/webdriver.py:257: in __init__
        super().__init__(
    ../../../../status-app-prs@tmp/venv/lib/python3.10/site-packages/selenium/webdriver/remote/webdriver.py:206: in __init__
        self.start_session(capabilities)
    ../../../../status-app-prs@tmp/venv/lib/python3.10/site-packages/appium/webdriver/webdriver.py:360: in start_session
        raise SessionNotCreatedException(
     A valid W3C session creation response must contain a non-empty "sessionId" entry. Got "{'value': {'error': 'unknown error', 'message': 'failed serving request POST /wd/hub/session', 'stacktrace': ''}}" instead
    



    Class TestOneToOneChatMultipleSharedDevicesNewUi:

    1. test_1_1_chat_non_latin_messages_stack_update_profile_photo, id: 702745

    Device 1: Find SendMessageButton by accessibility id: send-message-button
    Device 1: Tap on found: SendMessageButton

    critical/chats/test_1_1_public_chats.py:286: in test_1_1_chat_non_latin_messages_stack_update_profile_photo
        self.home_2.navigate_back_to_home_view()
    ../views/base_view.py:426: in navigate_back_to_home_view
        while not self.chat_floating_screen.is_element_disappeared(1) \
    ../views/base_element.py:231: in is_element_disappeared
        return self.wait_for_invisibility_of_element(sec)
    ../views/base_element.py:154: in wait_for_invisibility_of_element
        .until(expected_conditions.invisibility_of_element_located((self.by, self.locator)))
    ../../../../status-app-prs@tmp/venv/lib/python3.10/site-packages/selenium/webdriver/support/wait.py:86: in until
        value = method(self._driver)
    ../../../../status-app-prs@tmp/venv/lib/python3.10/site-packages/selenium/webdriver/support/expected_conditions.py:320: in _predicate
        return _element_if_visible(target, visibility=False)
    ../../../../status-app-prs@tmp/venv/lib/python3.10/site-packages/selenium/webdriver/support/expected_conditions.py:175: in _element_if_visible
        return element if element.is_displayed() == visibility else False
     'dict' object has no attribute 'is_displayed'
    



    Device sessions

    Class TestCommunityMultipleDeviceMerged:

    1. test_community_message_edit, id: 702843

    Test setup failed: critical/chats/test_public_chat_browsing.py:307: in prepare_devices
        self.drivers, self.loop = create_shared_drivers(2)
    base_test_case.py:310: in create_shared_drivers
        drivers = loop.run_until_complete(start_threads(test_suite_data.current_test.name,
    /usr/lib/python3.10/asyncio/base_events.py:649: in run_until_complete
        return future.result()
    __init__.py:26: in start_threads
        returns[k] = await returns[k]
    /usr/lib/python3.10/concurrent/futures/thread.py:58: in run
        result = self.fn(*self.args, **self.kwargs)
    ../../../../status-app-prs@tmp/venv/lib/python3.10/site-packages/appium/webdriver/webdriver.py:257: in __init__
        super().__init__(
    ../../../../status-app-prs@tmp/venv/lib/python3.10/site-packages/selenium/webdriver/remote/webdriver.py:206: in __init__
        self.start_session(capabilities)
    ../../../../status-app-prs@tmp/venv/lib/python3.10/site-packages/appium/webdriver/webdriver.py:360: in start_session
        raise SessionNotCreatedException(
     A valid W3C session creation response must contain a non-empty "sessionId" entry. Got "{'value': {'error': 'unknown error', 'message': 'failed serving request POST /wd/hub/session', 'stacktrace': ''}}" instead
    



    Passed tests (4)

    Click to expand

    Class TestWalletOneDevice:

    1. test_wallet_add_remove_regular_account, id: 727231
    2. test_wallet_balance_mainnet, id: 740490

    Class TestCommunityOneDeviceMerged:

    1. test_community_copy_and_paste_message_in_chat_input, id: 702742
    Device sessions

    2. test_restore_multiaccount_with_waku_backup_remove_profile_switch, id: 703133
    Device sessions

    @VolodLytvynenko VolodLytvynenko removed their assignment Dec 17, 2024
    @clauxx clauxx force-pushed the cl-21618-dapps-keycard-signing branch from 0983e41 to c5e6a89 Compare January 2, 2025 14:40
    @clauxx clauxx requested a review from jakubgs as a code owner January 2, 2025 14:40
    @clauxx clauxx requested a review from flexsurfer January 2, 2025 14:41
    @jakubgs jakubgs removed their request for review January 3, 2025 15:18
    @clauxx clauxx force-pushed the cl-21618-dapps-keycard-signing branch from 4eaab72 to 7b40486 Compare January 6, 2025 11:32
    @clauxx clauxx force-pushed the cl-21618-dapps-keycard-signing branch from 7b40486 to a2aa35c Compare January 6, 2025 11:35
    :hashes [prepared-hash]
    :on-success (fn [signatures]
    (rf/dispatch [:hide-bottom-sheet])
    (-> signatures first :signature on-success))
    Copy link
    Member

    @flexsurfer flexsurfer Jan 6, 2025

    Choose a reason for hiding this comment

    The reason will be displayed to describe this comment to others. Learn more.

    it's really hard to read

    Copy link
    Member Author

    Choose a reason for hiding this comment

    The reason will be displayed to describe this comment to others. Learn more.

    can you explain why?

    Copy link
    Member

    Choose a reason for hiding this comment

    The reason will be displayed to describe this comment to others. Learn more.

    Ambiguity in Intent
    The use of -> in this context suggests that the operations are straightforward transformations of signatures. However, the final step (on-success) is a function call, not a pure transformation. This mix of data access (first and :signature) and side effects (calling on-success) makes the threading less intuitive.

    Threading for Side Effects
    The threading macro is typically used for chaining transformations, not invoking side-effectful functions. Here, on-success is likely a callback or effect, which introduces a conceptual break in the chain.

    Reduced Readability
    It’s not immediately clear that the result of :signature is being passed as an argument to on-success. This could be more explicit without using ->, especially since the threading macro is more suitable for operations where each step returns a value for the next.

    Potential for Misleading Assumptions
    Readers might mistakenly assume that on-success is part of a chain of transformations, rather than a separate effectful operation, which can lead to confusion about the purpose of the code.

    (fn [signatures]
                  (rf/dispatch [:hide-bottom-sheet])
                  (on-success (:signature (first signatures))))

    Copy link
    Member Author

    @clauxx clauxx Jan 9, 2025

    Choose a reason for hiding this comment

    The reason will be displayed to describe this comment to others. Learn more.

    @flexsurfer

    Wasn't aware -> was constrained to data transformations and that it shouldn't be mixed with other types of operations, but if it affects readability here, can remove/simplify it.

    threading macro is more suitable for operations where each step returns a value for the next.

    Well yeah, for threading to work they have to return a value, but the last op. doesn't really have to return.

    Readers might mistakenly assume that on-success is part of a chain of transformations, rather than a separate effectful operation, which can lead to confusion about the purpose of the code.

    I assume we're all familiar with what on-success does and that it's not a pure transformation, given how often it's used

    p.s. this reads a bit like GPT 😄

    (fn [{:keys [db]} [password]]
    (let [prepared-hash (get-in db [:wallet-connect/current-request :prepared-hash])
    address (get-in db [:wallet-connect/current-request :address])
    keycard-sign? (-> (get-in db [:wallet :keypairs])
    Copy link
    Member

    Choose a reason for hiding this comment

    The reason will be displayed to describe this comment to others. Learn more.

    im not sure why you need check again, you already passed the empty password?

    @shivekkhurana shivekkhurana added the wallet-core Issues for mobile wallet team label Jan 7, 2025
    @flexsurfer flexsurfer mentioned this pull request Jan 8, 2025
    7 tasks
    Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
    Labels
    request-manual-qa wallet-core Issues for mobile wallet team
    Projects
    Status: REVIEW
    Development

    Successfully merging this pull request may close these issues.

    🖇️ Integrate Keycard signing flow for dapp transactions
    5 participants