Skip to content

Commit

Permalink
Merge pull request #346 from porters-xyz/tkn-api
Browse files Browse the repository at this point in the history
Tkn api
  • Loading branch information
scermat authored Aug 23, 2024
2 parents 396df36 + dc32ab8 commit 180720c
Show file tree
Hide file tree
Showing 12 changed files with 163 additions and 93 deletions.
4 changes: 2 additions & 2 deletions docs/pages/APIs/TKN/get_contract_address.mdx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# Get Contract Address
`GET /token/:portersAppId/contract-address/:ticker`
`GET https://porters.xyz/api/tkn/v1/token/:portersAppId/contract-address/:ticker`

## Description
Fetches the Ethereum contract address associated with the specified ENS name.
Expand Down Expand Up @@ -41,7 +41,7 @@ Fetches the Ethereum contract address associated with the specified ENS name.

## Request

`GET /token/myAppId/contract-address/usdc`
`GET https://porters.xyz/api/tkn/v1/token/myAppId/contract-address/usdc`

## Response

Expand Down
4 changes: 2 additions & 2 deletions docs/pages/APIs/TKN/get_contract_metadata.mdx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# Get Contract Metadata
`GET /token/:portersAppId/:ticker/metadata`
`GET https://porters.xyz/api/tkn/v1/token/:portersAppId/:ticker/metadata`

## Description
Fetches metadata for a specific token based on the ticker symbol. The metadata includes details like contract address, token name, description, associated URLs, and addresses on various blockchains.
Expand Down Expand Up @@ -71,7 +71,7 @@ Fetches metadata for a specific token based on the ticker symbol. The metadata i

## Request

`GET /token/myAppId/usdt/metadata`
`GET https://porters.xyz/api/tkn/v1/token/myAppId/usdt/metadata`

## Response

Expand Down
4 changes: 2 additions & 2 deletions docs/pages/APIs/TKN/get_token_balance.mdx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# Get Token Balance
`GET /token/:portersAppId/:ticker/balance`
`GET https://porters.xyz/api/tkn/v1/token/:portersAppId/:ticker/balance`

## Description
Fetches the balance of a specific token for a given network and user account.
Expand Down Expand Up @@ -64,7 +64,7 @@ Fetches the balance of a specific token for a given network and user account.

## Request

`GET /token/myAppId/usdc/balance?network=eth&address=0x1234...abcd`
`GET https://porters.xyz/api/tkn/v1/token/myAppId/usdc/balance?network=eth&address=0x1234...abcd`

## Response

Expand Down
4 changes: 2 additions & 2 deletions docs/pages/APIs/TKN/get_token_price_data.mdx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# Get Token Price Data
`GET /token/:portersAppId/:ticker/price`
`GET https://porters.xyz/api/tkn/v1/token/:portersAppId/:ticker/price`

## Description
Fetches the current price of a specific token against Wrapped Ether (WETH) on Uniswap V3, using the 0.3% fee tier.
Expand Down Expand Up @@ -58,7 +58,7 @@ Fetches the current price of a specific token against Wrapped Ether (WETH) on Un

## Request

`GET /token/myAppId/usdc/price`
`GET https://porters.xyz/api/tkn/v1/token/myAppId/usdc/price`

## Response

Expand Down
6 changes: 5 additions & 1 deletion docs/pages/APIs/TKN/intro.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,8 @@ For more information visit [https://tkn.xyz/](https://tkn.xyz/).

Use of this API requires a Porters App to be set up in the Porters backend. The App Id can then be passed as the `portersAppId` parameter.

Since this serice calls multiple chains, it is advisable not to set up any rules that limit chain usage on the App Id that will be used for this API.
Since this serice calls multiple chains, it is advisable not to set up any rules that limit chain usage on the App Id that will be used for this API.

# Base URI

The base url for this api is `https://porters.xyz/api/tkn/v1`
62 changes: 43 additions & 19 deletions gateway/common/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,24 +10,27 @@ import (

// store config as constants for now
const (
SHUTDOWN_DELAY string = "SHUTDOWN_DELAY"
JOB_BUFFER_SIZE = "JOB_BUFFER_SIZE"
NUM_WORKERS = "NUM_WORKERS"
PROXY_TO = "PROXY_TO"
HOST = "HOST" // host to add subdomains to
PORT = "PORT"
DATABASE_URL = "DATABASE_URL"
REDIS_URL = "REDIS_URL"
REDIS_ADDR = "REDIS_ADDR"
REDIS_USER = "REDIS_USER"
REDIS_PASSWORD = "REDIS_PASSWORD"
INSTRUMENT_ENABLED = "ENABLE_INSTRUMENT"
LOG_LEVEL = "LOG_LEVEL"
LOG_HTTP_RESPONSE = "LOG_HTTP_RESPONSE"
FLY_API_KEY = "FLY_API_KEY"
FLY_GATEWAY_URI = "FLY_GATEWAY_URI"
GATEWAY_API_KEY = "GATEWAY_API_KEY"
GATEWAY_REQUEST_API_KEY = "GATEWAY_REQUEST_API_KEY"
SHUTDOWN_DELAY string = "SHUTDOWN_DELAY"
JOB_BUFFER_SIZE = "JOB_BUFFER_SIZE"
NUM_WORKERS = "NUM_WORKERS"
PROXY_TO = "PROXY_TO"
HOST = "HOST" // host to add subdomains to
PORT = "PORT"
DATABASE_URL = "DATABASE_URL"
REDIS_URL = "REDIS_URL"
REDIS_ADDR = "REDIS_ADDR"
REDIS_USER = "REDIS_USER"
REDIS_PASSWORD = "REDIS_PASSWORD"
INSTRUMENT_ENABLED = "ENABLE_INSTRUMENT"
LOG_LEVEL = "LOG_LEVEL" //Used for debugging purposes
LOG_HTTP_REQUEST = "LOG_HTTP_REQUEST" //Used for debugging purposes
LOG_HTTP_REQUEST_FILTER = "LOG_HTTP_REQUEST_FILTER" //Used for debugging purposes
LOG_HTTP_RESPONSE = "LOG_HTTP_RESPONSE" //Used for debugging purposes
LOG_BALANCE_UPDATE = "LOG_BALANCE_UPDATE" //Used for debugging purposes
FLY_API_KEY = "FLY_API_KEY"
FLY_GATEWAY_URI = "FLY_GATEWAY_URI"
GATEWAY_API_KEY = "GATEWAY_API_KEY"
GATEWAY_REQUEST_API_KEY = "GATEWAY_REQUEST_API_KEY"
)

// This may evolve to include config outside env, or use .env file for
Expand All @@ -52,7 +55,10 @@ func setupConfig() *Config {
config.defaults[HOST] = "localhost"
config.defaults[PORT] = "9000"
config.defaults[INSTRUMENT_ENABLED] = "false"
config.defaults[LOG_HTTP_RESPONSE] = "true"
config.defaults[LOG_HTTP_REQUEST] = "false"
config.defaults[LOG_HTTP_RESPONSE] = "false"
config.defaults[LOG_BALANCE_UPDATE] = "false"
config.defaults[LOG_HTTP_REQUEST_FILTER] = ""

level := parseLogLevel(os.Getenv(LOG_LEVEL))
config.SetLogLevel(level)
Expand Down Expand Up @@ -117,3 +123,21 @@ func (c *Config) SetLogLevel(level log.Level) {
logger := log.New(log.NewTextHandler(os.Stdout, &log.HandlerOptions{Level: c.loglevel}))
log.SetDefault(logger)
}

// shouldLogRequest checks if the request URL path matches any of the specified filters in common.LOG_HTTP_FILTER_APP.
// If the filter list is empty, it logs all requests.
func ShouldLogRequest(urlPath string) bool {
filters := GetConfig(LOG_HTTP_REQUEST_FILTER)
if filters == "" {
// If no filters are specified, log everything
return true
}

filterList := strings.Split(filters, ",")
for _, filter := range filterList {
if strings.Contains(urlPath, filter) {
return true
}
}
return false
}
4 changes: 3 additions & 1 deletion gateway/plugins/balance.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,9 @@ func (b *BalanceTracker) HandleRequest(req *http.Request) error {
ctx = common.UpdateContext(ctx, bal)
ctx = common.UpdateContext(ctx, app)

log.Info("Balance for app", "appId", app.Id, "bal", bal.cachedBalance)
if common.Enabled(common.LOG_BALANCE_UPDATE) {
log.Info("Balance for app", "appId", app.Id, "bal", bal.cachedBalance)
}

if bal.cachedBalance > 0 {
lifecycle := proxy.SetStageComplete(ctx, proxy.BalanceCheck|proxy.AccountLookup)
Expand Down
20 changes: 15 additions & 5 deletions gateway/proxy/proxy.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,17 @@ func Start() {

handler := func(proxy *httputil.ReverseProxy) func(http.ResponseWriter, *http.Request) {
return func(resp http.ResponseWriter, req *http.Request) {
//Note this is used for debugging purposes only and is not meant to be on by default. Logs are automatically removed every 30 days.
//Additionally the RemoteAddr logs the internal IP from the load balancer so no external IPs are leaked
//Log request if URL path matches any of the filters
if common.Enabled(common.LOG_HTTP_REQUEST) && common.ShouldLogRequest(req.URL.Path) {
log.Info("Received request",
"method", req.Method,
"url", req.URL.String(),
"remoteAddr", req.RemoteAddr,
"userAgent", req.UserAgent(),
)
}
setupContext(req)
proxy.ServeHTTP(resp, req)
}
Expand Down Expand Up @@ -155,12 +166,11 @@ func setupProxy(remote *url.URL) *httputil.ReverseProxy {
}
}

if resp.StatusCode < 400 && err == nil {

if common.Enabled(common.LOG_HTTP_RESPONSE) {
log.Info("Success response", "resp", resp)
}
if common.Enabled(common.LOG_HTTP_RESPONSE) {
log.Info("Response", "resp", resp)
}

if resp.StatusCode < 400 && err == nil {
updater := db.NewUsageUpdater(ctx, "success")
common.GetTaskQueue().Add(updater)
}
Expand Down
30 changes: 30 additions & 0 deletions web-portal/backend/src/providers/rpc/PortersJsonRpcProvider.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { JsonRpcProvider, FetchRequest } from "ethers";

export class PortersJsonRpcProvider extends JsonRpcProvider {
async fetchData<T = any>(request: FetchRequest): Promise<T> {
const url = new URL(request.url);
console.log('calling endpoint', {
hostname: url.hostname,
port: 443,
path: url.pathname,
method: request.method || 'POST',
headers: {
...request.headers,
Host: url.hostname,
},
});

// Ensure the Host header is set
request.headers['Host'] = url.hostname;

// Perform the HTTP request using fetch
const response = await fetch(request.url, {
method: request.method || 'POST',
headers: request.headers,
body: request.body,
});

const body = await response.json();
return body as T;
}
}
18 changes: 18 additions & 0 deletions web-portal/backend/src/tkn-api/models/AddressInfo.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
export interface AddressInfo {
eth: string;
optimism: string;
arbitrum: string;
avax: string;
bsc: string;
base: string;
cronos: string;
fantom: string;
gnosis: string;
polygon: string;
goerli_testnet: string;
sepolia_testnet: string;
near: string;
solana: string;
tron: string;
ziliqa: string;
}
16 changes: 16 additions & 0 deletions web-portal/backend/src/tkn-api/models/TokenInfo.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { AddressInfo } from "./AddressInfo";

export interface TokenInfo {
contractAddress: string;
name: string;
url: string;
avatar: string;
description: string;
notice: string;
version: string;
decimals: string;
twitter: string;
github: string;
dweb: string; // Assuming this is a string representation of the bytes
addresses: AddressInfo;
}
Loading

0 comments on commit 180720c

Please sign in to comment.