Skip to content

Conversation

@nesitor
Copy link
Member

@nesitor nesitor commented Sep 10, 2025

Problem: Ledger wallet users cannot use Aleph to send transactions.

Solution: Implement Ledger use on SDK to allow using them.

@nesitor nesitor self-assigned this Sep 10, 2025
@nesitor nesitor force-pushed the andres-feature-implement_ledger_wallet branch from 422e9b0 to ef69187 Compare October 1, 2025 11:03
@1yam 1yam force-pushed the andres-feature-implement_ledger_wallet branch from ef69187 to 9b8d8b6 Compare October 31, 2025 09:46
@1yam 1yam assigned 1yam and unassigned nesitor Oct 31, 2025
@1yam 1yam marked this pull request as ready for review October 31, 2025 09:46
@1yam 1yam requested a review from odesenfans October 31, 2025 09:46
@github-actions
Copy link

Failed to retrieve llama text: POST 503:

503 Service Unavailable


No server is available to handle this request.

address: Optional[str] = None

model_config = SettingsConfigDict(use_enum_values=True)
# model_config = SettingsConfigDict(use_enum_values=True)
Copy link
Contributor

Choose a reason for hiding this comment

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

Why comment this?

Copy link
Member

Choose a reason for hiding this comment

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

Not sure, that change was from @nesitor

def __init__(self, account: LedgerAccount, device: Dongle):
def __init__(
self, account: LedgerAccount, device: Dongle, chain: Optional[Chain] = None
):
Copy link
Contributor

Choose a reason for hiding this comment

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

For some reason you're not calling the __init__ method of ETHAccount (the base class), why? You also re-specify a bunch of constants like CHAIN or CURVE for no clear reason.

Copy link
Member

@1yam 1yam Nov 3, 2025

Choose a reason for hiding this comment

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

The init method of EthAccount expects a private_key to initialize the account.
In our case, since we are interacting with a hardware wallet (Ledger), we don’t have or need access to the private key — the Ledger device handles signing internally.

The goal here is to preserve the interface and behavior of EthAccount so that this Ledger-based account can be used seamlessly like any other account within the SDK, without requiring code changes elsewhere.

As a result, the base class init isn’t called, since it would require a private_key we cannot provide.

And for CHAIN and CURVE aren’t needed, I’ll remove them.

Copy link
Contributor

Choose a reason for hiding this comment

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

Okay but is it even reusing any method of ETHAccount? If it does, just create a base class for the methods used in both Ledger / non-Ledger accounts and inherit that from both then.

@1yam 1yam requested a review from odesenfans November 4, 2025 12:53
Copy link
Contributor

@odesenfans odesenfans left a comment

Choose a reason for hiding this comment

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

Looks like this needs a refactoring of base classes the class hierarchy make sense.

def __init__(self, account: LedgerAccount, device: Dongle):
def __init__(
self, account: LedgerAccount, device: Dongle, chain: Optional[Chain] = None
):
Copy link
Contributor

Choose a reason for hiding this comment

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

Okay but is it even reusing any method of ETHAccount? If it does, just create a base class for the methods used in both Ledger / non-Ledger accounts and inherit that from both then.

def get_accounts(
device: Optional[Dongle] = None, count: int = 5
) -> List[LedgerAccount]:
"""Initialize an aleph.im account from a LedgerHQ device from
Copy link
Contributor

Choose a reason for hiding this comment

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

aleph.im -> Aleph Cloud

account_type: Optional[Type[AccountFromPrivateKey]] = None,
chain: Optional[Chain] = None,
) -> AccountFromPrivateKey:
) -> Union[AccountFromPrivateKey, LedgerETHAccount]:
Copy link
Contributor

Choose a reason for hiding this comment

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

Should be a base class instead


path: Path
path: Optional[Path] = None
type: Optional[AccountType] = AccountType.INTERNAL
Copy link
Contributor

Choose a reason for hiding this comment

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

Why is it optional?


class AccountType(str, Enum):
INTERNAL: str = "internal"
EXTERNAL: str = "external"
Copy link
Contributor

Choose a reason for hiding this comment

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

Internal/External is not really representative. Use Hot/Cold, Imported / Hardware or something like that.

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

Successfully merging this pull request may close these issues.

4 participants