Draft API Proposal: Treat all accounts like an interface for better strict typing.
Is your feature request related to a problem? Please describe.
There are a lot of ways to represent an account on the Stellar network. You could use a Keypair, an Account, a MuxedAccount, or even just a string. When we move to the higher-level SDK, there's even an AccountResponse object that's also Account-like.
This is confusing and bug-prone (e.g. stellar/js-stellar-sdk#653): these objects are sometimes interchangeable and other times not, and violating compatibility expectations is too easy.
Describe the solution you'd like
I'd like to introduce an Account interface rather than an object, in order to facilitate Typescript-side enforcement of compatibility.
On Muxed Accounts This underlying issue reared its head when we introduced support for muxed accounts. I believe we should treat them as first-class citizens in the SDK, and this would help facilitate that.
Compatibility
We may be able to avoid breaking backwards compatibility with naming clashes if we name it AccountInterface instead of Account.
Additional context An API proposal follows:
interface AccountInterface {
accountId(): string;
sequenceNumber(): string;
incrementSequenceNumber(): void;
equals(otherAccount: AccountInterface): boolean;
}
These are the three fundamental things any proper account should be able to provide.
class Account implements AccountInterface {
constructor(accountId: string, sequence: string);
/* implementing AccountInterface */
accountId(): string;
sequenceNumber(): string;
incrementSequenceNumber(): void;
createMuxedAccount(id: string): MuxedAccount;
toXDRObject(): xdr.AccountId;
equals(otherAccount: AccountInterface): boolean;
};
This would be the interface-compatible version of the current Account object.
class MuxedAccount implements AccountInterface {
constructor(account: Account, sequence: string);
static fromAddress(address: string, sequenceNum: string): MuxedAccount;
static extractUnderlyingAddress(address: string): string;
/* implementing AccountInterface */
accountId(): string;
sequenceNumber(): string;
incrementSequenceNumber(): void;
getId(): string;
setId(id: string): MuxedAccount;
baseAccount(): Account;
toXDRObject(): xdr.MuxedAccount;
equals(otherAccount: MuxedAccount): boolean;
};
This would be the interface-compatible upgrade to the current MuxedAccount object.