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

Add web wallet integration into the streamlit web app #591

Open
kongzii opened this issue Dec 9, 2024 · 4 comments
Open

Add web wallet integration into the streamlit web app #591

kongzii opened this issue Dec 9, 2024 · 4 comments

Comments

@kongzii
Copy link
Contributor

kongzii commented Dec 9, 2024

... instead of hard-coded single env private key

This was referenced Dec 9, 2024
@gabrielfior
Copy link
Contributor

I did some research around Streamlit custom components:

-> https://www.kipi.ai/insights/building-a-streamlit-application-with-custom-components-a-step-by-step-guide/#What_is_the_difference_between_Streamlit_and_React_JS
-> https://docs.streamlit.io/develop/concepts/custom-components/create

Basically it involves
-> React app (running e.g. on localhost:3000), which defines a component
-> Python code wrapping the react component (`register_component("MyComponent.tsx", url="localhost:3001")

Although it would be nice to use a Streamlit app (as we normally do) and simply add a wallet, this integration with e.g. Metamask would involve adding a complete React app (with npm deps) inside the PMA repo. Also, it would significantly change our Streamlit deployment scheme, requiring an additional process (npm start or similar) to be started in parallel to the streamlit run script.py.

For that reason, I suggest closing this issue and instead creating 2 tasks, as detailed below.

Frontend task
-> React app which has the same functionality as the streamlit app (+ connect button) - i.e. send messages, select agent, list messages processed, etc

API task
-> Serve /long_term_memories/agent/{agent_identifier}

@kongzii what do you think?

@kongzii
Copy link
Contributor Author

kongzii commented Dec 12, 2024

Also, it would significantly change our Streamlit deployment scheme, requiring an additional process (npm start or similar) to be started in parallel to the streamlit run script.py.

@gabrielfior This doesn't sound right. Streamlit components are normally installable through pip, no need to run a web server for each one.

-> React app (running e.g. on localhost:3000), which defines a component

Where did you found this requirement? I don't see it in either of the links provided.


While I'm not a fan of building a Strealit component, it's still easier than building a whole React app.

However, if someone is going to build that app for us (or if you are fancy for doing plain frontend development), then I'm in.

@gabrielfior
Copy link
Contributor

@gabrielfior This doesn't sound right. Streamlit components are normally installable through pip, no need to run a web server for each one.

You are correct. Here the explanation from Streamlit

A bi-directional Streamlit Component varies slightly from a pure Python library in that it must contain pre-compiled frontend code. This is how base Streamlit works as well; when you pip install streamlit, you are getting a Python library where the HTML and frontend code contained within it have been compiled into static assets.

@kongzii
Copy link
Contributor Author

kongzii commented Dec 12, 2024

Some observations:

Streamlit component are rendered inside of iframe, window.ethereum is not available in the iframe --> so we can't use Metamask directly.

Maybe we can use WalletConnect?

Claude wrote this component for WalletConnect:

import json
import streamlit as st
import streamlit.components.v1 as components
from web3 import Web3


# Initialize WalletConnect component
def wallet_connect_component() -> None:
    # HTML/JS for WalletConnect integration
    wallet_connect_html = """
    <script src="https://cdn.jsdelivr.net/npm/@walletconnect/[email protected]/dist/umd/index.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/web3.min.js"></script>
    <div id="wallet-status"></div>
    <button id="connect-wallet">Connect Wallet</button>
    <script>
        async function initWalletConnect() {
            const provider = new WalletConnectProvider.default({
                infuraId: "YOUR_INFURA_ID", // Replace with your Infura ID
            });
            
            document.getElementById('connect-wallet').onclick = async () => {
                try {
                    await provider.enable();
                    const web3 = new Web3(provider);
                    const accounts = await web3.eth.getAccounts();
                    document.getElementById('wallet-status').innerHTML = 
                        `Connected: ${accounts[0]}`;
                    
                    // Send this back to Streamlit
                    window.parent.postMessage({
                        type: "wallet_connected",
                        address: accounts[0]
                    }, "*");
                    
                } catch (error) {
                    console.error(error);
                    document.getElementById('wallet-status').innerHTML = 
                        `Error: ${error.message}`;
                }
            };
        }
        initWalletConnect();
    </script>
    """

    components.html(wallet_connect_html, height=1000)


wallet_connect_component()

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants