Intro2Stellar | Creating Wallet Web App | Using Python

arnav_mehta__

Arnav Mehta

Posted on August 17, 2024

Intro2Stellar | Creating Wallet Web App | Using Python

This is a submission for the Build Better on Stellar: Smart Contract Challenge : Create a Tutorial

Your Tutorial

What I Created

I developed a comprehensive, 13-minute step-by-step coding tutorial that covers the following aspects of Stellar:

  • An introduction to Stellar: What it is and its core features
  • The purpose and advantages of using Stellar
  • A practical tutorial on how to utilize Stellar's capabilities
  • A complete walkthrough for developing a full-fledged application with a frontend, utilizing Stellar's Python SDK -- developing a wallet app

Journey

I researched a lot regarding stellar and it's ecosystem:

  • Investigated companies that have successfully implemented Stellar in their operations
  • Explored additional use cases and benefits that Stellar offers beyond its primary functions
  • Thoroughly examined Stellar's documentation to gain a deep understanding of its capabilities
  • Carefully selecting the SDK that I believed could be explained most effectively to users

After this experience and my research I'm looking forward to build more projects on the Stellar's ecosystem

Final Code:


"""
Class StellarWallets:
- create a new account -- add funds if needed
- check balance
- send payment

WebUI using Streamlit

"""

from stellar_sdk import Keypair, Server, TransactionBuilder, Network, Asset
from stellar_sdk.exceptions import NotFoundError
import streamlit as st

TESTNET_URL = "https://horizon-testnet.stellar.org"
MAX_FEE = 100

class StellarWallet:
    def __init__(self) -> None:
        self.server = Server(horizon_url=TESTNET_URL)

    def create_account(self, source_secret=None, starting_balance="10"):
        new_account = Keypair.random()

        if source_secret:
            source_keypair = Keypair.from_secret(source_secret)
            source_acc = self.server.load_account(account_id=source_keypair.public_key)
            transaction = TransactionBuilder(
                source_account=source_acc,
                network_passphrase=Network.TESTNET_NETWORK_PASSPHRASE,
                base_fee=MAX_FEE
            ).append_create_account_op(
                destination=new_account.public_key,
                starting_balance=starting_balance
            ).set_timeout(30).build()

            transaction.sign(source_keypair)
            response = self.server.submit_transaction(transaction)
            print(f">>> response: {response}")
        return {
            "public_key": new_account.public_key,
            "secret_key": new_account.secret, 
            "source_account_key": source_keypair.public_key if source_secret else None
        }

    def check_balance(self, public_key):
        try:
            account = self.server.accounts().account_id(public_key).call()
            balances = account["balances"]
            if not balances:
                return "No balance found!"
            return "\n".join([f"{balance['asset_type']}: {balance['balance']}" for balance in balances])
        except NotFoundError:
            return "Account not found!"

    def send_payment(self, source_secret, destination_public_key, amount, message: str = "Memo"):
        try:
            source_keypair = Keypair.from_secret(source_secret)
            source_account = self.server.load_account(account_id=source_keypair.public_key)
            self.server.accounts().account_id(destination_public_key).call()

            transaction = TransactionBuilder(
                source_account=source_account,
                network_passphrase=Network.TESTNET_NETWORK_PASSPHRASE,
                base_fee=MAX_FEE
            ).add_text_memo(message).append_payment_op(destination=destination_public_key, amount=amount, asset=Asset.native()).set_timeout(30).build()

            transaction.sign(source_keypair)
            response = self.server.submit_transaction(transaction)
            st.success(f">>> Check the transaction at: https://testnet.stellarchain.io/transactions/{response['hash']}")

            return f"Payment sent to {destination_public_key} with amount {amount}"
        except Exception as e:
            return f"Error sending payment! {e}"


def main():
    st.set_page_config(page_title="Stellar Wallet")
    st.title("Stellar Wallet")

    wallet = StellarWallet()
    menu = st.sidebar.selectbox("Menu", ["Create Account", "Check Balance", "Send Payment"])

    if menu == "Create Account":
        st.header("Create a new Account")
        source_secret = st.text_input("Source Secret Key (Optional)")
        starting_balance = st.text_input("Starting Balance", "10")

        if st.button("Create Account"):
            new_account = wallet.create_account(source_secret=source_secret, starting_balance=starting_balance)
            st.success("Account created successfully!")
            st.write(f"Public Key: {new_account['public_key']}")
            st.write(f"Secret Key: {new_account['secret_key']}")
            st.write(f"Source Account Key: {new_account['source_account_key']}")

    elif menu == "Check Balance":
        st.header("Check Balance")
        public_key = st.text_input("Public Key")

        if st.button("Check Balance"):
            balance = wallet.check_balance(public_key)
            st.write(balance)

    elif menu == "Send Payment":
        st.header("Send Payment")
        source_secret = st.text_input("Source Secret Key")
        destination_public_key = st.text_input("Destination Public Key")
        amount = st.text_input("Amount")
        message = st.text_input("Message", "Memo")

        if st.button("Send Payment"):
            response = wallet.send_payment(source_secret, destination_public_key, amount, message)
            st.success(response)

if __name__ == "__main__":
    main()
Enter fullscreen mode Exit fullscreen mode
💖 💪 🙅 🚩
arnav_mehta__
Arnav Mehta

Posted on August 17, 2024

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related