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

Discussion: EIP-1193 #2319

Closed
alcuadrado opened this issue Oct 22, 2019 · 178 comments
Closed

Discussion: EIP-1193 #2319

alcuadrado opened this issue Oct 22, 2019 · 178 comments

Comments

@alcuadrado
Copy link
Member

alcuadrado commented Oct 22, 2019

As agreed at Devcon 5, I'm creating this issue to move the EIP-1193 discussion here. It's been fragmented in multiple places, making it hard for most people to follow it.

Link to the current version of the EIP: https://eips.ethereum.org/EIPS/eip-1193

Previous discussion channels

@alcuadrado
Copy link
Member Author

Summary of Devcon 5 EIP-1193 meeting

Participants

This is an incomplete list of people/projects that participated. Please feel free to add yourself or others: @alcuadrado, @nivida, @davidmurdoch, @joshstevens19, @adrianmcli, @iurimatias, @ricmoo, @spalladino, @javier-tarazaga, @ylv-io, and members from Alchemy, Chainsafe, Metamask, and possibly more projects.

Format of the discussion

Initially, every member raised what they thought were the most important concerns to move the EIP forward. After that, we discussed most of them and proposed possible solutions.

List of concerns

  1. EIP-1193 began as a spec on how to expose a provider in a dapp browser, but mutated into specifying its interface. It still depends on EIPs related to browser-specific stuff.

  2. The way a provider is exposed (i.e. window.ethereum) only supports a single provider. This is in conflict with users installing multiple wallet extensions, and may be problematic with a multi-chain future.

  3. The current provider implementations have different interfaces (i.e. send vs sendAsync).

  4. There's no way to send batch requests in the current spec.

  5. Some providers need open/connect and close/disconnect methods, and others don't.

  6. How can a provider be known to be EIP-1193 compatible?

  7. How can this EIP be extended in the future? How are those extensions going to be detected?

Proposed solutions

  1. EIP-1193 will only focus on the provider's interface. How to expose in browser environments will be part of another document, possibly an RFC. Any dependency on browser-specific EIPs will be removed.

  2. As this EIP won't dictate how to expose the provider, this item is outside of its scope.

  3. Finalizing this EIP and adopting ti will fix it.

  4. There was a short discussion about this. We concluded that we don't know what to do yet. It may be just an issue with the UI controlling the provider. If a sendBatch method is needed in the future, another EIP can extend this one.

  5. We concluded that every provider should provide these methods (/cc @pedrouid ). It's up to the provider implementation to document if they need to be called or not. If a certain provider doesn't need them, it can implement them as no-ops.

6 and 7. Most of the time was spent discussing these items. We considered different approaches like not doing anything at all, imposing a certain class name, and many other techniques.

What we concluded is that providers would have a whitelist of the capabilities they offer. The most basic provider (i.e. HTTP-based provider) will have such a whitelist empty. More featureful providers will declare all of their extra features. For example, a websocket/polling-based provider that supports subscriptions, should declare that in the whitelist.

We analyzed the risk of this whitelist getting huge with time, but still decided to go with this approach. It's not clear that it will actually get huge, nor that this would even care.

We chose this approach over others, as it's more explicit and simpler.

Next steps

  • @pedrouid do you want to adapt EIP-1193: Add close method #2261 so that it includes the open and close methods as described here?

  • I will submit a PR removing any reference to browser-specific stuff.

  • I will prepare a PR with the changes proposed in 6 & 7. We can discuss the details there.

(Disclaimer: I will probably do these things next week, as I have to get back to Argentina and will be super jet-lagged).

@nivida
Copy link
Member

nivida commented Oct 22, 2019

EIP-1193 will only focus on the provider's interface. How to expose in browser environments will be part of another document, possibly an RFC. Any dependency on browser-specific EIPs will be removed.

As a historical addition: We discussed always both and as @frozeman told me is this issue the source of this EIP.

The way a provider is exposed (i.e. window.ethereum) only supports a single provider. This is in conflict with users installing multiple wallet extensions, and may be problematic with a multi-chain future.
As this EIP won't dictate how to expose the provider, this item is outside of its scope.

Yes, same here I also think we should create a separate EIP which defines the injection of providers. This EIP should have a section about security concerns as well and should provide some possible solutions for doing it in a secure way. (probably MetaMask has some good inputs here for creating a RFC @danfinlay)

Required Sections:

  • Defining of the window.ethereum object interface
    • window.ethereum.getProvider(..) -> Get provider for specific chain
    • window.ethereum.provider -> Get default provider selected by the user
    • ... what ever other property or method should exists on the window.ethereum object
  • Security (SES, Realms Shim, Realm Proposal)

(we probably should have further discussion about the injection of providers in the related RFC PR)

There's no way to send batch requests in the current spec.

Discussed 2y ago here.

We concluded that every provider should provide these methods (/cc @pedrouid ). It's up to the provider implementation to document if they need to be called or not. If a certain provider doesn't need them, it can implement them as no-ops.

Agreed.

What we concluded is that providers would have a whitelist of the capabilities they offer. The most basic provider (i.e. HTTP-based provider) will have such a whitelist empty. More featureful providers will declare all of their extra features. For example, a websocket/polling-based provider that supports subscriptions, should declare that in the whitelist.

We analyzed the risk of this whitelist getting huge with time, but still decided to go with this approach. It's not clear that it will actually get huge, nor that this would even care.

We chose this approach over others, as it's more explicit and simpler.

Sounds good!

  • But where exactly do we define and extend this whitelist?
  • Is it allowed to have an object stored behind a capability key for getting some further configuration possibilities?

I would propose (as discussed at Devcon in Osaka) a method called getCapabilities:

export interface EIP1193 {
 // .... other methods
 getCapabilities(): Capabilities;
}

export interface Capabilities {
  [capability_key: string]: any;
}

@pedrouid
Copy link
Contributor

Thanks @alcuadrado for sharing the summary of Devcon's meeting 🙏

I agree that open/close methods should be added with the ability to make them no-ops for certain providers which might not require them.

However we technically don't need the open method since EIP-1102 already specified a similar method enable which is now widely used.

I will update the #2261 to add the note for no-ops but other than that I don't see the need to have open if it will serve the same purpose for enable

Regarding all other points, I have no other objections and I'm glad we have reached consensus specially on point number 2. We should merge #2090 which includes related changes.

@axic
Copy link
Member

axic commented Oct 24, 2019

As agreed at Devcon 5, I'm creating this issue to move the EIP-1193 discussion here. It's been fragmented in multiple places, making it hard for most people to follow it.

As a historical addition: We discussed always both and as @frozeman told me is this issue (ethereum/interfaces#16) the source of this EIP.

Interesting – the EIP itself lists https://ethereum-magicians.org/t/eip-1193-ethereum-provider-javascript-api/640 as the official forum.

In case there is an agreement to use this issue, can someone update the EIP as well as perhaps add links to the other two mentioned forums into a References section?

@frozeman
Copy link
Contributor

Great to see this going back to GitHub issues. I find them better readable.

Where can I see the latest agreed version of this eip?

@rekmarks
Copy link
Contributor

@pedrouid EIP-1102 states that ethereum.enable() is deprecated in favor of the eth_requestAccounts RPC method. What are your thoughts on that?

Starting within a release or two, the MetaMask inpage provider will support both. We believe that it would be too disruptive for dapp developers to remove enable anytime soon.

@alcuadrado
Copy link
Member Author

alcuadrado commented Dec 2, 2019

Interesting – the EIP itself lists https://ethereum-magicians.org/t/eip-1193-ethereum-provider-javascript-api/640 as the official forum.

In case there is an agreement to use this issue, can someone update the EIP as well as perhaps add links to the other two mentioned forums into a References section?

I created #2419 to update the EIP

I agree that open/close methods should be added with the ability to make them no-ops for certain providers which might not require them.

However we technically don't need the open method since EIP-1102 already specified a similar method enable which is now widely used.

I will update the #2261 to add the note for no-ops but other than that I don't see the need to have open if it will serve the same purpose for enable

Completely agree with this. Thanks for updating #2261 !

  • But where exactly do we define and extend this whitelist?

  • Is it allowed to have an object stored behind a capability key for getting some further configuration possibilities?

I would propose a method called getCapabilities:

export interface EIP1193 {
 // .... other methods
 getCapabilities(): Capabilities;
}

export interface Capabilities {
  [capability_key: string]: any;
}

I'll explore different alternatives this week and post the results here or in a PR.

Starting within a release or two, the MetaMask inpage provider will support both. We believe that it would be too disruptive for dapp developers to remove enable anytime soon.

I agree with this. I wouldn't add enable to the EIP, but removing it from the actual implementations should be done with care.

@axic
Copy link
Member

axic commented Dec 2, 2019

Since @alcuadrado seems to be very actively pursuing this EIP (perhaps even to Final status?), I'd suggest to consider adding him to the author list so he could automerge updates.

@frozeman @ryanio @marcgarreau @MaiaVictor what do you think?

@nivida
Copy link
Member

nivida commented Dec 3, 2019

@axic Sounds like a good idea. @alcuadrado took the lead for this EIP in the related meeting we had during Devcon.

@ryanio
Copy link
Contributor

ryanio commented Dec 3, 2019

I am open to adding @alcuadrado to lead closing discussions to bring us to final, if I can get a +1 from another author in agreement. Thank you for taking the initiative.

@rekmarks
Copy link
Contributor

rekmarks commented Dec 3, 2019

Regarding open/close

I believe that an open method should be added to #2261.

As discussed, EIP 1102 has deprecated its enable method, and replaced it with send('eth_requestAccounts'). The point of this method is to do exactly what you'd expect: ask the user to expose their Ethereum account(s).

In #2261, close is described as: Provider connection can be closed using this method. I interpret this to mean that the provider will stop communicating with any Ethereum chains and possibly the wallet itself, and no longer accept any RPC requests.

The question then becomes, if you close a Provider connection, how do you reopen it?

I don't think these methods were considered with MetaMask in mind, but I'll use us as a concrete example. In MetaMask, even if you haven't "connected" in the sense of EIP 1102 (i.e. exposed any accounts), you can still request a bunch of RPC methods, such as net_version and eth_chainId. In addition, you can also check if e.g. MetaMask is unlocked. If we ever implemented close in any non-trivial sense, there'd be no way to explicitly re-open the connection. If we re-opened the connection implicitly, e.g. on an RPC request, then I don't see the point of closing the connection in the first place.

In short, I don't believe that close is useful without an open method in EIP 1193. I created a PR against #2261 with suggested changes here: pedrouid#4

I don't think this is the case, but if the desire is to enable the dapp to ask the user to stop exposing accounts, I believe that discussion should move to EIP 1102 or EIP 2255.

To be clear, MetaMask will support this EIP either way, and as things stand, we'll support close as a no-op.

cc: @alcuadrado @pedrouid

@wighawag
Copy link
Contributor

wighawag commented Dec 3, 2019

I don't think this is the case, but if the desire is to enable the dapp to ask the user to stop exposing accounts, I believe that discussion should move to EIP 1102 or EIP 2255.

For me I always interpreted this way. The same way as other wbe3 provider allow you to logout.

This is useful for dapps that for example support both a builtin provider and web based one.
By allowing the user to "close" the builtin provider we can bring them back to the "wallet choice" screen. See my post here : https://ethereum-magicians.org/t/eip-1102-opt-in-provider-access/414/59?u=wighawag

As for a "close" as a way to block rpc request. I don't see the point. If an app do not want to send rpc request, it can simply not call them anymore.

Regarding "open", assuming this would be a call to be made for dapps that want to make rpc request, this would be a breaking change as now dapp would not be able to call eth_chainId to get it know what the wallet is currently pointing at.

@rekmarks
Copy link
Contributor

rekmarks commented Dec 3, 2019

By allowing the user to "close" the builtin provider we can bring them back to the "wallet choice" screen.

@wighawag I think that's a compelling use case, but IMO close is still under-specified and should have a corresponding open method. If close is intended as the complement to send('eth_requestAccounts'), then I don't understand why it's being added to EIP 1193, and I'd argue that its name is misleading.

The changes to the spec I've described are not breaking, because they remain optional.

As for a "close" as a way to block rpc request. I don't see the point. If an app do not want to send rpc request, it can simply not call them anymore.

Similarly, if a dapp doesn't want to use a particular provider, couldn't it also just ignore it?

@pedrouid
Copy link
Contributor

pedrouid commented Dec 4, 2019

I think that's a compelling use case, but IMO close is still under-specified and should have a corresponding open method.

In that case, I would also add that the open method should be specified to make a eth_requestAccounts.

Also given so many dapps are using enable instead of open shouldn't we instead rename close to disable to make it backwards compatible.

@wighawag
Copy link
Contributor

wighawag commented Dec 4, 2019

@rekmarks

then I don't understand why it's being added to EIP 1193, and I'd argue that its name is misleading.

That is why I call it eth_closeAccounts in my post and as it is the complement to eth_requestAccount it should go with it. I am open to a different naming
But yes it would not be part of EIP-1193, my post related to 1102.

if we want open and close as you describe, we will have to consider the backward compatibility issue. I would make that another EIP. And I would argue that these could also be rpc methods. I don't see why these need to be js functions

@pedrouid

In that case, I would also add that the open method should be specified to make a eth_requestAccounts.

that would make it redundant. open is actually doing less, it just allow the dapp to make rpc request.
So if we follow that, we do not need open

@pedrouid
Copy link
Contributor

pedrouid commented Dec 4, 2019

But the EIP-1102 already caused a lot of breaking changes, couldn't we make use of that developer time already spent on the enable method and just apply the changes for the eth_requestAccounts plus with the addition of disable for the EIP-1193?

@wighawag
Copy link
Contributor

wighawag commented Dec 4, 2019

We can keep enable (for backward compatibility) but we should move towards using rpc methods, keeping EIP-1193 as simple as possible

As for adding a eth_closeAccounts this won't break backward compatibility. so we can add it.
This would be part of EIP-1102 though

@MicahZoltu
Copy link
Contributor

Can we move this to Last Call/Final or close it? Is there any reason to leave it in Draft state at this point? Is work being done on it?

@MicahZoltu
Copy link
Contributor

This EIP, as currently worded, is incompatible with current web3.js and ethers.js implementations and there is no clean upgrade path for clients/servers. The problem is that libraries and providers that implement

window.ethereum.send(payload: JsonRpcRequest, callback: (error: JsonRpcErrorResponse | null, response: JsonRpcSuccessResponse | null) => void): void

cannot also implement

window.ethereum.send(method: string, params: unknown[]): Promise<unknown>

A client needs to choose which one of those it expects, and a provider needs to choose which one it implements. Things will only work if the client and the provider both align.

Recommended remediation: Add a method for asking the provider what version of the protocol it is running. This could be as simple as a string, or a string array, where the string(s) represent supported protocols.

version: (): Promise<('eip-1193' | 'eip-1234')[]>

If a given provider supports several different EIPs, then it can return each of them in the array. The client then merely needs to check if that function exists, and if it does do a .includes check on the result for its preferred protocol (potentially working its way down a list). We can start with just 2 protocols, one for eip 1193 and one for legacy web3.

@davidmurdoch
Copy link

davidmurdoch commented Feb 11, 2020

@MicahZoltu, why can't they implement both signatures?

Providers can use method overloading to provide both ways. An example in TypeScript:

  public send(payload: JsonRpc.Request, callback?: Callback): void;
  public send(method: string, params?: any[]): Promise<any>;
  public send(arg1: string | JsonRpc.Request, arg2?: Callback | any[]): Promise<any> {
    if (typeod arg1 === "string") {
      // handle as EIP-1193
    } else {
      // Log deprecation notice and handle as legacy
      console.warn("`provider.send` was invoked via 'legacy' callback signature. This signature, `send(payload: JsonRpc.Request, callback?: Callback): void`, has been deprecated in favor of the signature for `send` defined in EIP-1193 and will be removed in future versions.");
    }
}

Or are you just worried about callers not being able to differentiate between the legacy way the new 1193 way?

I don't think this EIP should be concerned too much with this level of backwards-compatibility; providers, and clients that consume these providers, should be free to decide if they want to continue to support the legacy signature and for how long (and they should log a deprecation notice before complete removal).

@davidmurdoch
Copy link

@rekmarks, @wighawag I know I'm late to the discussion here.. but my assumption is that open and close are socket-related methods that have nothing to do with unlocking accounts. This is why these methods would be no-ops for providers that are communicating over HTTP-only.

@MicahZoltu
Copy link
Contributor

@davidmurdoch Sorry for the delay in getting back to you. A provider can provide multiple overloads and switch on parameters (which is a terrible pattern IMO, but it does work in this case). However, callers cannot do the same thing. All they know is that there is a send function, but they do not know what parameters the send function expects. If the send function expects only Request,Callback and they give it string,unknown[] then it will fail. If the send function expects only string,unknown[] and they give it Request,Callback then it will also fail.

There is currently no graceful migration from old style to new style. This could easily be avoided with the addition of a protocol handshake or by just using different function names. I don't see a particularly compelling argument in making the migration more painful than necessary here.

@davidmurdoch
Copy link

Method overloading is a very common feature and I personally have no issue using it in JS. I don't mind overloading to support the old style in Ganache for another year or so (likely logging a deprecation notice in the meantime, and then an obsolete notice after that).

I get that it's a bit inconvenient for everyone who writes a provider to have to keep the old API around if they want to be useful, but doing so provides a sense of stability around Ethereum's client-side APIs. As a user, especially a new user, It's beyond annoying when a project changes their long established public interface in a backwards-incompatible manner, rendering years of community documentation and examples outdated.

Because this EIP describes an API that is exposed to clients by the browser itself, we should consider treating it with the same level of back-compat longevity that browsers do -- supporting the old signature for the foreseeable future.

All that said, I know Ganache has it easy here, as implementors choose us and don't have to worry about the browser's/wallet's provider's API. Still, I think provider implementors should consider maintaining the old style for while.

As far as changing the method name, have any suggestions?

For the version signaling idea (handshake or version property or other method), I'm not sure that'd be very graceful either.

@MicahZoltu
Copy link
Contributor

With the ability to handshake, as a dapp developer I can ask the provider, "I would like to communicate with 1193 style send, do you support that?" and if it doesn't respond or responds with no I can then either gracefully degrade to legacy style sends, or I can present the user with a useful error message.

On the other hand, if there is no way to probe for versioning all I can do is try to do a modern send and then if it fails tell the user that something went wrong (and the error message is likely useless to the user, since I'm calling an API with the wrong parameters).

@davidmurdoch What is your argument against a version/handshake?

@ryanio
Copy link
Contributor

ryanio commented Nov 26, 2020

Thanks @enolan for pointing these errata out, I have started a PR to fix: #3138

For an EIP-1193 provider that implements websocket support, check out the MetaMask window.ethereum provider. I copied and pasted the newly fixed example 4 in a index.html page with an await ethereum.enable() beforehand, loaded it with npx http-server in Google Chrome with the MetaMask browser extension, and I started getting new block notifications, e.g.:

New block 0xacf9f1: {hash: "0x48004272e8d6394a1f1c453e87341c4ebb67d0b1bb788aa1b305ba7752feb97a", parentHash: "0x88c85215f2353d5f94da76f4ea9e2978ad7200cd222114fc3f6a5b1e4458b017", sha3Uncles: "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347", miner: "0x04668ec2f57cc15c381b461b9fedab5d451c8f7f", stateRoot: "0x07f2f661d2baebf7333d121ba52868f12a4cce70cd8e7e34b777cb5cfab27e7c", …}

@davidmurdoch
Copy link

@enolan you can also try with [email protected] (which is not a production-ready release).

@enolan
Copy link

enolan commented Nov 27, 2020

@ryanio MetaMask doesn't actually support websockets, at least according to MetaMask/metamask-extension#1645. Using it in the browser console I do get events - they seem to be polling and providing the streaming interface. For some reason I wasn't getting the events in my Rust code, so I assumed it was just dropping the eth_subscribe calls silently, but I guess I just had a bug somewhere.

Thanks for fixing the examples!

MicahZoltu pushed a commit that referenced this issue Dec 2, 2020
This PR fixes two errata in the EIP-1193 examples section, special thanks to @enolan for noting in #2319 (comment) and #2319 (comment).
@flexsurfer
Copy link

flexsurfer commented Feb 8, 2021

hey, some dapps have stopped working with our provider, probably because they moved to request and they request accounts first, but according to EIP provider must throw an error if the request is unauthorized, this is causing the issue because dapps expect something else? how other providers handle this case ?

@flexsurfer
Copy link

MM has this example

ethereum
  .request({ method: 'eth_accounts' })
  .then(handleAccountsChanged)
  .catch((err) => {
    // Some unexpected error.
    // For backwards compatibility reasons, if no accounts are available,
    // eth_accounts will return an empty array.
    console.error(err);
  });

but an error is expected here 4100 | Unauthorized | The requested method and/or account has not been authorized by the user. if permissions haven't been granted

@rekmarks
Copy link
Contributor

rekmarks commented Feb 8, 2021

Hi @flexsurfer, that's because MetaMask implements EIP-1102. You have to call ethereum.request({ method: 'eth_requestAccounts' }) first. Since you're asking about MetaMask specifically, I'll also refer you to the relevant section of our documentation.

@flexsurfer
Copy link

hey @rekmarks thanks, some dapps request 'eth_accounts' before 'eth_requestAccounts', in that case we throw an error in our provider, but MM doesn't, and in that case, dapp works in MM but not with our provider, so it seems MM doesn't throw an error and returns empty accounts? but in that case how dapp can distinguish empty accounts and unauthorized request? according to EIP-1193 provider should throw 4100 | Unauthorized error

@rekmarks
Copy link
Contributor

rekmarks commented Feb 8, 2021

There is no specification governing the behavior of eth_accounts in this situation. Historically, it's returned an empty array, and MetaMask continues to do so in order to prevent breaking the existing, widespread uses of that method.

Your reading of 1193 is correct, and it's certainly fine (probably better) to reject with an error if no accounts are available. However, my sense is that most dapps interpret an empty array as an authorization problem. I can't think of other reasons why a wallet wouldn't have any accounts available.

@sambacha
Copy link
Contributor

sambacha commented Feb 8, 2021 via email

@ethereum ethereum deleted a comment from adamlaska Feb 9, 2021
Arachnid pushed a commit to Arachnid/EIPs that referenced this issue Mar 6, 2021
* Moves 2696 to final.

* Removes review end date from 2696.

* Markes RequestArguments as readonly.

This came up in the discussion at ethereum#2319 (comment) (which this is just a break-out of).
Arachnid pushed a commit to Arachnid/EIPs that referenced this issue Mar 6, 2021
This PR fixes two errata in the EIP-1193 examples section, special thanks to @enolan for noting in ethereum#2319 (comment) and ethereum#2319 (comment).
@ethereum ethereum deleted a comment from Narubestz May 6, 2022
@ethereum ethereum deleted a comment from Thebest1mol May 6, 2022
@MicahZoltu
Copy link
Contributor

Closing this for housekeeping purposes since this EIP is final, but feel free to continue discussing here as needed.

@kdenhartog
Copy link
Contributor

I noticed in this EIP there wasn't a mention about privacy considerations in this document. Given this one is final I doubt we want to be modifying this one any more, but I'm curious where others who worked on this originally stand on the general principle of when we should be exposing that the ethereum provider versus when it should not be injected since this can present a fingerprinting privacy risk for users that can give websites the ability to fingerprint users.

@ryanio
Copy link
Contributor

ryanio commented Jun 24, 2022

@kdenhartog check out https://github.com/ethereum/EIPs/blob/master/EIPS/eip-1102.md although it seems the status is stagnant, @rekmarks maybe we should get this one over the finish line to final unless there was some reason or if another EIP took precedence. What is MM's current position on it?

@kdenhartog
Copy link
Contributor

From a quick read of that EIP it looks like it shares common goals, although it looks like it's codifying behavior that has been in production for quite some time. I'll jump into the discussion on ethereum-magicians since that looks like the best way to keep that discussion going.

@kdenhartog
Copy link
Contributor

Here's some other security considerations we think would be useful for this EIP. @MicahZoltu for Finalized EIPs like this one are we allowed to make updates here or should we open a new EIP to move this forward?

brave/brave-browser#23710

@MicahZoltu
Copy link
Contributor

If you want to make a normative change, you will need a new EIP/standard. If you want to, for example, add a security consideration and the author is OK with it then that would be a non-normative change and is allowed. The key is, anything (no matter how silly/dumb) that is compliant with this EIP today must still be compliant after the change. This precludes pretty much any change to the specification itself other than typo fixes and the like.

As an example, there are many problems with ERC-20, yet we cannot change it and instead we have to develop new standards that either extend or replace it.

@kdenhartog
Copy link
Contributor

👍🏻 awesome makes sense to me. I think we'll want to aim for something a bit more normative here so I'll draft up a starter EIP and take that route instead

@GIgako19929
Copy link

@🥰

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