Skip to content

Instantly share code, notes, and snippets.

@abourget
Last active November 28, 2023 22:13
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save abourget/c520dcfb94fe4b87476a4ef4500079ad to your computer and use it in GitHub Desktop.
Save abourget/c520dcfb94fe4b87476a4ef4500079ad to your computer and use it in GitHub Desktop.

The Web3 Gateway (W3G)

Problem

dapps today still rely on centrally hosted endpoints to do the bulk of their work, so dapp users are not fully independent: they cannot take the front end, run with it and still use the app living on the blockchain.

See: https://moxie.org/2022/01/07/web3-first-impressions.html

See the notion of "right to exit": https://medium.com/@danfinlay/what-moxie-missed-on-web3-wallets-8dc572e7f39b

Solution

Standardize the ways backend services are declared, and provide end-users with a Single-URL entrypoint passed to decentralized apps. Include a discovery mechanisms ultimately providing all necessary backend services for the app to function. Provide what is necessary for someone to quickly spin up a business (get paid and cover his costs) by participating in such an economy.

This would be an actual implementation of the "right to exit": provide the ability to hop providers, but keeping the backend services specs unaltered.

This provides censorship-resistance, anti-fragility and independance to users of the decentralized web, along with a business for anyone with the competencies to run such services.

How it works

Let's say a social app needs 5 backend services to function properly:

  • Ethereum blockchain RPC endpoint, with means to read and write
  • a GraphQL endpoint to a Subgraph, indexing the dapp's data on chain
  • an image resizer, for profile pictures and uploads
  • an IPFS pinning service (for writing)
  • an IPFS gateway (for reading)

Two optional services are supported by the dapp, which gracefully degrades the experience if they are not available (as they are most probably much pricier):

  • a full-text search on your social feed
  • a algorithmic feed organizer (like what Facebook and Twitter do today)

Application specify their requirements in such a form:

name: my_social_app
version: 0.0.1
services:
- name: eth_node
  optional: false
  spec:
    kind: blockchains.w3g/v1/Ethereum
    archive: true
    client: geth
    version: v1.10.15+
    rpc: true
    endpoints:
    - getBlock
    - getLogs
    - sendRawTransaction
- name: resizer         # https://imgproxy.net/
  routing:
    kind: FromRoot     # request that the provided endpoint handles requests at root, and forward to the right service, never a subpath
  spec:
    kind: graphics.w3g/v1/imgproxy
    version: v3.1.0
    minimum_patch_version: true
    minimum_minor_version: false  # Implicit, as with `minimum_major_version` ?
- name: ipfs
  spec:
    kind: storage.w3g/v1/IPFS
    features:
    - read
    - write
    - pin
- name: uniswapv2subgraph
  routing:
    kind: MapPath
    from_path: /subgraph/id/Qm1230918230192830129380192
    to_path: /subgraph/id/Qm1230918230192830129380192
  spec:
    kind: subgraphs.w3g/v1/Subgraph
    id: Qm1230918230192830129380192
    #or name: uniswap/exchange-v2
    only_read_entities:
    - Entity1
    - Entity2
- name: full_text
  optional: true
  spec:
    kind: socialdapp.com/v1beta/FullTextIndex
    short_queries_only: true
- name: sorter
  optional: true
  spec:
    kind: socialdapp.com/v1beta/FeedSorter
    ad_revenue_optimized_algo: false
    happiness_optimized_algo: true

All the kind are predefined service types, HTTPS/2.0 based, and imply their respective method of communications (JSON-RPC, or REST, or gRPC, or whatever).

The specs for each kind element specify what is being negotiated between the client (which could be a flat HTML page on a USB key) and the gateway service.

For example, if the gateway service doesn't have a geth v1.9.10+ Ethereum node, it can't provide the service named eth_node. On the flip side, when a W3G endpoint is called for the eth_node service, the provider promises to fulfill all the declared specs.

An application can be designed with degraded backends in mind (feature depth), meaning that an end-user might not want to pay for optional features, or would get to choose one of many options, potentially priced differently. In the example above, it seems that the application could use a FeedSorter that is either ads-revenue-optimized (think Facebook), or happiness-optimized (a brave new world) algorithms. Users could expect the prices to be different here, and could choose, and the app would adjust accordingly.

Costs & Pricing

Along with some sampled usage of users of that bundle of services, the specification itself provides rich information to allow a W3G Service Provider to make informed cost and pricing decisions.

A W3G Provider can offer metered or fixed price access. It can offer bundle of dapps (when the same services are proxied for different dapps). It can use a wide variety of marketing techniques to reach and promote its service. It can use a wide variety of methods to collect payments from end users, and pay backend services (like The Graph subgraphs). It can use various login processes to authenticate its users, or no login at all (say payment was done on-chain), and there's really no reason to collect any other info in order to provide the service.

Some dapps like to subsidize the costs for their users. By dealing with Providers, and offering coupons, dapps can pay providers yet let end users choose which Provider they prefer.

The W3G software stack is there to help those service providers manage costs and pricing, handling payments from clients, and payments to third-party backend providers (if they themselves do not or cannot run certain services, but still want to act as a unique gateway), management of payment channels, credit card payments, metering and quotas, coupon codes, etc..

The discovery

Once a W3G has accepted a spec and agreed with an end-user on pricing, billing and depth of features, it provides the end user with a single URL, that:

  • allows for the discovery of the endpoints providing each service, along with their authentication methods
  • can keep track of consumption, usage, depletion of one's metered account, etc..

A URL could look like:

https://my_social_app_0_0_1_qmdd7a812f3d29192.myw3g.io/discover?token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c

or

https://myw3g.io/discover/my_social_app_0_0_1_qmdd7a1828f8129382/APIKEY123098120398102938019283019283098123

That endpoint could respond with a JSON file similar to:

services:
- name: eth_node
  spec:
    url: https://my_social_app_0_0_1_qmdd7a812f3d29192.myw3g.io/eth_node    # Here, queries sent to `/eth_node` would strip `/eth_node`  before forwarding to the backend service. Might not be cool for some services.
    auth_query_param: token=ABCDEF1234567886431
- name: resizer
  spec:
    url: https://my_social_app_0_0_1_qmdd7a812f3d29192.myw3g.io   # Notice how the gateway will forward requests at the ROOT of the server, directly to the `resizer` backend.
    auth_bearer: ABCDEF1234567886431
    headers:
      X-Routing: "resizer"
- name: uniswapv2subgraph
  spec:
    url: https://my_social_app_0_0_1_qmdd7a812f3d29192.myw3g.io/subgraph/id/Qm1230918230192830129380192
    auth_query_param: token=ABCDEF1234567886431
...

or

services:
- name: eth_node
  spec:
    url: https://gateway1.myw3g.io
    auth_query_param: token=ABCDEF1234567886431
    headers:
      X-Spec: "my_social_app_0_0_1_qmdd7a812f3d29192"    # Some info is needed by the W3G to understand where to route the requests
      X-Routing: "eth_node"                              # for both authentication, and knowing which service of which spec is requested here.
- name: resizer
  spec:
    url: https://gateway3.myw3g.io
    auth_bearer: ABCDEF1234567886431
    headers:
      X-Routing: "resizer"
...

Once this is received, the application can initialize the different libraries that are going to make use of those backend services, along with the authentication mechanisms.

Summary

From a W3G Provider's perspective, this design allows them to have a business and be quickly on the market. It provides great optimizations opportunities (in terms of optimizations of scale, unit economics, etc.).

From a dapp's perspective, it provides a clean way to declare what your app needs, and quickly reach out to providers for them to run those services, offering a basket of users. It allows them to subsidize providers to invert who pays (end-users or dapps).

From an end-user's perspective, you get freedom by choosing who your provider will be, anti-fragility in the apps you use and someone to talk to when backends have issues.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment