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

Initial Commit for adding support for web3 providers outside of infur… #46

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added AWSCLIV2.pkg
Binary file not shown.
23 changes: 22 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,23 +14,44 @@ The best way to develop and test the API is to deploy your own instance to AWS.

1. Install and configure [AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/install-cliv2.html) and [AWS CDK V1](https://docs.aws.amazon.com/cdk/latest/guide/getting_started.html).
2. Create .env file in the root directory of the project with:

```
PROJECT_ID = '' # Infura Project Id
JSON_RPC_PROVIDER = '<JSON_RPC_PROVIDER>'
THROTTLE_PER_FIVE_MINS = '' # Optional
```

To override the default JSON_RPC_PROVIDER for a specific chain, set up a connection by specifying the environment variable

```
JSON_RPC_PROVIDER_{CHAIN} = '<JSON_RPC_PROVIDER>'
```

For example, specifying a provider for Optimism :

```
JSON_RPC_PROVIDER_OPTIMISM = '<JSON_RPC_PROVIDER>'
```

3. Install and build the package

```
npm install && npm run build
```

4. To deploy the API run:

```
cdk deploy RoutingAPIStack
```

This will deploy to the default account your AWS CLI is configured for. Once complete it will output something like:

```
RoutingAPIStack.Url = https://...
```

You can then try it out:

```
curl --request GET '<INSERT_YOUR_URL_HERE>/quote?tokenInAddress=0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2&tokenInChainId=1&tokenOutAddress=0x1f9840a85d5af5bf1d1762f925bdaddc4201f984&tokenOutChainId=1&amount=100&type=exactIn'
```
Expand Down
23 changes: 15 additions & 8 deletions bin/app.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { ChainId } from '@uniswap/smart-order-router'
import * as cdk from 'aws-cdk-lib'
import { CfnOutput, SecretValue, Stack, StackProps, Stage, StageProps } from 'aws-cdk-lib'
import * as chatbot from 'aws-cdk-lib/aws-chatbot'
Expand All @@ -19,7 +20,8 @@ export class RoutingAPIStage extends Stage {
scope: Construct,
id: string,
props: StageProps & {
infuraProjectId: string
jsonRpcProvider: string
jsonRpcProviderOverride: Map<ChainId, string>
Copy link
Contributor

@willpote willpote Jun 2, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Think we should remove this, but even if we wanted this map there would be no need to create it at this level and pass it all the way through empty. You can just create it inside routing-lambda-stack.ts

provisionedConcurrency: number
ethGasStationInfoUrl: string
chatbotSNSArn?: string
Expand All @@ -32,7 +34,8 @@ export class RoutingAPIStage extends Stage {
) {
super(scope, id, props)
const {
infuraProjectId,
jsonRpcProvider,
jsonRpcProviderOverride,
provisionedConcurrency,
ethGasStationInfoUrl,
chatbotSNSArn,
Expand All @@ -44,7 +47,8 @@ export class RoutingAPIStage extends Stage {
} = props

const { url } = new RoutingAPIStack(this, 'RoutingAPI', {
infuraProjectId,
jsonRpcProvider,
jsonRpcProviderOverride,
provisionedConcurrency,
ethGasStationInfoUrl,
chatbotSNSArn,
Expand Down Expand Up @@ -93,8 +97,8 @@ export class RoutingAPIPipeline extends Stack {
// Secrets are stored in secrets manager in the pipeline account. Accounts we deploy to
// have been granted permissions to access secrets via resource policies.

const infuraProjectId = sm.Secret.fromSecretAttributes(this, 'InfuraProjectId', {
secretCompleteArn: 'arn:aws:secretsmanager:us-east-2:644039819003:secret:infuraProjectId-UlSwK2',
const jsonRpcProvider = sm.Secret.fromSecretAttributes(this, 'jsonRpcProvider', {
secretCompleteArn: 'arn:aws:secretsmanager:us-east-2:644039819003:secret:jsonRpcProvider-UlSwK2',
Comment on lines +100 to +101
Copy link
Contributor

@willpote willpote Jun 2, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did you create the secret in secrets manager? I don't see it there. Also lets sync tomorrow because it should be the production infura id that you use, so i'll need to share that with you

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

https://github.com/Uniswap/routing-api/pull/47/files

Hey reworked and simplified this PR entirely

})

const ethGasStationInfoUrl = sm.Secret.fromSecretAttributes(this, 'ETHGasStationUrl', {
Expand All @@ -119,14 +123,15 @@ export class RoutingAPIPipeline extends Stack {
// Beta us-east-2
const betaUsEast2Stage = new RoutingAPIStage(this, 'beta-us-east-2', {
env: { account: '145079444317', region: 'us-east-2' },
jsonRpcProvider: jsonRpcProvider.secretValue.toString(),
jsonRpcProviderOverride: new Map<ChainId, string>(),
provisionedConcurrency: 20,
ethGasStationInfoUrl: ethGasStationInfoUrl.secretValue.toString(),
stage: STAGE.BETA,
route53Arn: route53Arn.secretValueFromJson('arn').toString(),
pinata_key: pinataApi.secretValueFromJson('pinata-api-key').toString(),
pinata_secret: pinataSecret.secretValueFromJson('secret').toString(),
hosted_zone: hostedZone.secretValueFromJson('zone').toString(),
infuraProjectId: infuraProjectId.secretValue.toString(),
})

const betaUsEast2AppStage = pipeline.addStage(betaUsEast2Stage)
Expand All @@ -136,7 +141,8 @@ export class RoutingAPIPipeline extends Stack {
// Prod us-east-2
const prodUsEast2Stage = new RoutingAPIStage(this, 'prod-us-east-2', {
env: { account: '606857263320', region: 'us-east-2' },
infuraProjectId: infuraProjectId.secretValue.toString(),
jsonRpcProvider: jsonRpcProvider.secretValue.toString(),
jsonRpcProviderOverride: new Map<ChainId, string>(),
provisionedConcurrency: 100,
ethGasStationInfoUrl: ethGasStationInfoUrl.secretValue.toString(),
chatbotSNSArn: 'arn:aws:sns:us-east-2:644039819003:SlackChatbotTopic',
Expand Down Expand Up @@ -204,7 +210,8 @@ const app = new cdk.App()

// Local dev stack
new RoutingAPIStack(app, 'RoutingAPIStack', {
infuraProjectId: process.env.PROJECT_ID!,
jsonRpcProvider: process.env.JSON_RPC_PROVIDER!,
jsonRpcProviderOverride: new Map<ChainId, string>(),
provisionedConcurrency: process.env.PROVISION_CONCURRENCY ? parseInt(process.env.PROVISION_CONCURRENCY) : 0,
throttlingOverride: process.env.THROTTLE_PER_FIVE_MINS,
ethGasStationInfoUrl: process.env.ETH_GAS_STATION_INFO_URL!,
Expand Down
10 changes: 7 additions & 3 deletions bin/stacks/routing-api-stack.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { ChainId } from '@uniswap/smart-order-router'
import * as cdk from 'aws-cdk-lib'
import { CfnOutput, Duration } from 'aws-cdk-lib'
import * as aws_apigateway from 'aws-cdk-lib/aws-apigateway'
Expand All @@ -20,7 +21,8 @@ export class RoutingAPIStack extends cdk.Stack {
parent: Construct,
name: string,
props: cdk.StackProps & {
infuraProjectId: string
jsonRpcProvider: string
jsonRpcProviderOverride: Map<ChainId, string>
provisionedConcurrency: number
throttlingOverride?: string
ethGasStationInfoUrl: string
Expand All @@ -35,7 +37,6 @@ export class RoutingAPIStack extends cdk.Stack {
super(parent, name, props)

const {
infuraProjectId,
provisionedConcurrency,
throttlingOverride,
ethGasStationInfoUrl,
Expand All @@ -45,6 +46,8 @@ export class RoutingAPIStack extends cdk.Stack {
pinata_key,
pinata_secret,
hosted_zone,
jsonRpcProvider,
jsonRpcProviderOverride,
} = props

const {
Expand All @@ -70,11 +73,12 @@ export class RoutingAPIStack extends cdk.Stack {
poolCacheBucket,
poolCacheBucket2,
poolCacheKey,
infuraProjectId,
tokenListCacheBucket,
provisionedConcurrency,
ethGasStationInfoUrl,
chatbotSNSArn,
jsonRpcProvider,
jsonRpcProviderOverride,
}
)

Expand Down
46 changes: 24 additions & 22 deletions bin/stacks/routing-lambda-stack.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { ChainId, ID_TO_NETWORK_NAME } from '@uniswap/smart-order-router'
import * as cdk from 'aws-cdk-lib'
import { Duration } from 'aws-cdk-lib'
import * as asg from 'aws-cdk-lib/aws-applicationautoscaling'
Expand All @@ -15,11 +16,14 @@ export interface RoutingLambdaStackProps extends cdk.NestedStackProps {
poolCacheBucket: aws_s3.Bucket
poolCacheBucket2: aws_s3.Bucket
poolCacheKey: string
infuraProjectId: string
tokenListCacheBucket: aws_s3.Bucket
provisionedConcurrency: number
ethGasStationInfoUrl: string
chatbotSNSArn?: string

// JSON RPC ENDPOINTS
jsonRpcProvider: string
jsonRpcProviderOverride: Map<ChainId, string>
}
export class RoutingLambdaStack extends cdk.NestedStack {
public readonly routingLambda: aws_lambda_nodejs.NodejsFunction
Expand All @@ -32,11 +36,12 @@ export class RoutingLambdaStack extends cdk.NestedStack {
poolCacheBucket,
poolCacheBucket2,
poolCacheKey,
infuraProjectId,
tokenListCacheBucket,
provisionedConcurrency,
ethGasStationInfoUrl,
chatbotSNSArn,
jsonRpcProvider,
jsonRpcProviderOverride,
} = props

const lambdaRole = new aws_iam.Role(this, 'RoutingLambdaRole', {
Expand All @@ -53,6 +58,21 @@ export class RoutingLambdaStack extends cdk.NestedStack {

const region = cdk.Stack.of(this).region

const env = {
VERSION: '2',
JSON_RPC_PROVIDER: jsonRpcProvider,
NODE_OPTIONS: '--enable-source-maps',
POOL_CACHE_BUCKET: poolCacheBucket.bucketName,
POOL_CACHE_BUCKET_2: poolCacheBucket2.bucketName,
POOL_CACHE_KEY: poolCacheKey,
TOKEN_LIST_CACHE_BUCKET: tokenListCacheBucket.bucketName,
ETH_GAS_STATION_INFO_URL: ethGasStationInfoUrl,
}

jsonRpcProviderOverride.forEach((url: string, chainId: ChainId) => {
;(env as any)[`JSON_RPC_PROVIDER_${ID_TO_NETWORK_NAME(chainId).toUpperCase}`] = url
})
Comment on lines +72 to +74
Copy link
Contributor

@willpote willpote Jun 2, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't see this used? And we set the same url for each one anyway. I commented below, but I think its best to just pass in the project id and the name of the provider (i.e. infura or alchemy), then compute the url for each chain in code.


this.routingLambda = new aws_lambda_nodejs.NodejsFunction(this, 'RoutingLambda2', {
role: lambdaRole,
runtime: aws_lambda.Runtime.NODEJS_14_X,
Expand All @@ -65,16 +85,7 @@ export class RoutingLambdaStack extends cdk.NestedStack {
sourceMap: true,
},
description: 'Routing Lambda',
environment: {
VERSION: '2',
NODE_OPTIONS: '--enable-source-maps',
POOL_CACHE_BUCKET: poolCacheBucket.bucketName,
POOL_CACHE_BUCKET_2: poolCacheBucket2.bucketName,
POOL_CACHE_KEY: poolCacheKey,
TOKEN_LIST_CACHE_BUCKET: tokenListCacheBucket.bucketName,
ETH_GAS_STATION_INFO_URL: ethGasStationInfoUrl,
PROJECT_ID: infuraProjectId,
},
environment: env,
layers: [
aws_lambda.LayerVersion.fromLayerVersionArn(
this,
Expand All @@ -97,16 +108,7 @@ export class RoutingLambdaStack extends cdk.NestedStack {
sourceMap: true,
},
description: 'Route to Ratio Lambda',
environment: {
VERSION: '2',
NODE_OPTIONS: '--enable-source-maps',
POOL_CACHE_BUCKET: poolCacheBucket.bucketName,
POOL_CACHE_BUCKET_2: poolCacheBucket2.bucketName,
POOL_CACHE_KEY: poolCacheKey,
PROJECT_ID: infuraProjectId,
TOKEN_LIST_CACHE_BUCKET: tokenListCacheBucket.bucketName,
ETH_GAS_STATION_INFO_URL: ethGasStationInfoUrl,
},
environment: env,
layers: [
aws_lambda.LayerVersion.fromLayerVersionArn(
this,
Expand Down
8 changes: 3 additions & 5 deletions lib/handlers/injector-sor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import {
CachingV3PoolProvider,
ChainId,
EIP1559GasPriceProvider,
ID_TO_NETWORK_NAME,
IGasPriceProvider,
IMetric,
ITokenListProvider,
Expand Down Expand Up @@ -107,10 +106,9 @@ export abstract class InjectorSOR<Router, QueryParams> extends Injector<

const dependenciesByChainArray = await Promise.all(
_.map(SUPPORTED_CHAINS, async (chainId: ChainId) => {
const chainName = ID_TO_NETWORK_NAME(chainId)
// updated chainNames to match infura strings
const projectId = process.env.PROJECT_ID
const url = `https://${chainName}.infura.io/v3/${projectId}`
const url = process.env.JSON_RPC_PROVIDER!

log.info({ url: url, id: process.env.PROJECT_ID }, `generated rpc url`)
Comment on lines +109 to +111
Copy link
Contributor

@willpote willpote Jun 2, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can't use the same URL for all networks. You need to construct the url depending on the chainId passed in.

I think its best to take the other approach we discussed- create the secret so it has two fields, something like
providerName: 'infura'
and
projectId: .... Then pass both those into the lambda and construct the URL using a function like

buildJsonRpcUrl(providerName: string, id: string): string


let timeout: number
switch (chainId) {
Expand Down
14 changes: 7 additions & 7 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@
"@uniswap/v3-periphery": "^1.1.0",
"@uniswap/v3-sdk": "^3.7.1",
"async-retry": "^1.3.1",
"aws-cdk-lib": "^2.24.1",
"aws-cdk-lib": "^2.26.0",
"aws-embedded-metrics": "^2.0.4",
"aws-sdk": "^2.927.0",
"aws-xray-sdk": "^3.3.3",
Expand Down