diff --git a/EIPS/eip-5388.md b/EIPS/eip-5388.md new file mode 100644 index 0000000000000..934b3e4c4e871 --- /dev/null +++ b/EIPS/eip-5388.md @@ -0,0 +1,151 @@ +--- +eip: 5388 +title: Token-Gated HTTP Endpoints +description: Composable RESTful and Solidity interface to implement token-gated HTTP endpoints using data tokens. +author: Tim Daubenschütz (@TimDaub) +discussions-to: https://ethereum-magicians.org/t/token-gated-https-endpoints/10205 +status: Draft +type: Standards Track +category: ERC +created: 2022-08-01 +requires: 712 +--- + +## Abstract + +This standard introduces composable RESTful HTTP and Solidity interfaces that enable paying to access HTTP endpoints using [EIP-20](./eip-20.md) tokens. + +## Motivation + +According to RFC 7231, HTTP status code `402 Payment Required` is reserved for future use. But the future is now as Ethereum enables users to verify their identity with a server using public key infrastructure. + +The Ethereum community has expressed the need for a composable method of token-gating HTTP endpoints. In this document, we outline a protocol implementable by HTTP servers to accept [EIP-20](./eip-20.md) payments prior to allowing access to an authorized endpoint. + +## Specification + +The keywords "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY" and "OPTIONAL" in this document are to be interpreted as described in RFC 2119. + +Upon the user's initial request, an HTTP server implementing token-gating via this EIP responds with a `402 Payment Required` status code: + +- Its body must include a valid JSON string that complies with the Solidity Contract ABI Specification for calling contracts. +- It must include a custom header `X-EIP-5388-CONTRACT-ADDRESS` that suggests the contract's address a call must be directed to. +- It must include a custom header `X-EIP-5388-ABI-ENCODED-INPUT` that suggests the call signature the user must invoke at `X-EIP-5388-CONTRACT-ADDRESS` to gain access to the endpoint. + +### Example Response + +``` +HTTP/2.0 402 Payment Required +Date: Mon, 01 Aug 2022 13:37:00 GMT +Content-Type: application/json +X-EIP-5388-CONTRACT-ADDRESS: 0x005241438cAF3eaCb05bB6543151f7AF894C5B58 +X-EIP-5388-ABI-ENCODED-INPUT: 23b872dd00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007b + +"{\"constant\":false,\"inputs\":[{\"name\":\"_from\",\"type\":\"address\"},{\"name\":\"_to\",\"type\":\"address\"},{\"name\":\"_value\",\"type\":\"uint256\"}],\"name\":\"transferFrom\",\"outputs\":[{\"name\":\"success\",\"type\":\"bool\"}],\"type\":\"function\"}" +``` + +### Authorization via [EIP-712](./eip-712) Signature + +After successfully calling the suggested Ethereum contract with the appropriate inputs, for a user request that containing a validly signed message for endpoint authorization, the server must allow access to the bespoke endpoint. + +The signature is complaint with [EIP-712](./eip-712.md): + +```js +keccak256(abi.encodePacked( + hex"1901", + DOMAIN_SEPARATOR, + keccak256(abi.encode( + keccak256("Invocation(address contract,string input"), + contract, + keccak256(bytes(input)), + )) +)) +``` + +where `DOMAIN_SEPARATOR` must be unique to the chain to prevent replay attacks from other domains, and satisfy the requirements of [EIP-712](./eip-712.md): + +```js +DOMAIN_SEPARATOR = keccak256( + abi.encode( + keccak256( + "EIP712Domain(string version,uint256 chainId,string endpoint,string method)" + ), + keccak256(bytes(version)), + chainid, + keccak256(bytes(endpoint)), + keccak256(bytes(method)) + ) +); +``` + +where `endpoint` must represent the full URL, e.g. `https://ethereum.org/api/v1/cutedoge` and `method` an existing HTTP method. + +```js +{ + "types": { + "EIP712Domain": [ + { + "name": "version", + "type": "string" + }, + { + "name": "chainId", + "type": "uint256" + }, + { + "name": "endpoint", + "type": "string" + }, + { + "name": "method", + "type": "string" + } + ], + "Invocation": [ + { + "name": "contract", + "type": "address" + }, + { + "name": "input", + "type": "string" + } + ], + "primaryType": "Invocation", + "domain": { + "version": version, + "chainId": chainid, + "endpoint": endpoint, + "method": method + }, + "message": { + "contract": contract, + "input": input + } + } +} +``` + +The resulting hexadecimal-encoded signature must be included in a user's request to the endpoint as the `Bearer` value of the `Authorization` header. An example: + +```http +GET /index.html +Authorization: Bearer 0xabc... +``` + +Upon validating the signature and cross-checking it with the mandated on-chain interaction, a server must allow access to the appointed endpoint's resource. + +## Rationale + +There is no rationale related this standard. + +## Backwards Compatibility + +No backward compatibility issues were found. + +## Security Considerations + +Needs discussion. + +## Copyright + +Copyright and related rights waived via [CC0](../LICENSE.md).