Skip to content
Merged
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
19 changes: 19 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# Editor configuration, see http://editorconfig.org
root = true

[*]
charset = utf-8
indent_style = space
indent_size = 2
insert_final_newline = true
trim_trailing_whitespace = true
end_of_line = lf

[*.md]
max_line_length = off
trim_trailing_whitespace = false

[{*.ts,*.tsx}]
ij_typescript_force_quote_style = true
ij_typescript_use_double_quotes = false
ij_typescript_use_semicolon_after_statement = false
14 changes: 8 additions & 6 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,24 +5,27 @@
"type": "module",
"main": "src/scripts/coingecko.js",
"scripts": {
"build": "npm run public && npm run coingecko",
"coingecko": "node src/scripts/coingecko.js",
"downloadImages": "node --experimental-json-modules src/scripts/downloadImages",
"cowFi:tokens": "node ./src/scripts/cowFi-tokens.js",
"build": "npm run generateGnosisChainList && npm run public && npm run coingecko",
"coingecko": "yarn run-script src/scripts/coingecko.js",
"downloadImages": "yarn run-script src/scripts/downloadImages",
"cowFi:tokens": "yarn run-script ./src/scripts/cowFi-tokens.js",
"generateGnosisChainList": "yarn run-script src/scripts/generateGnosisChainList.ts",
"public": "copyfiles src/public/*.json build/lists -f",
"workflowHelper": "python3 src/scripts/workflow_helper.py",
"validate": "ajv -s node_modules/@uniswap/token-lists/dist/tokenlist.schema.json -d src/public/CowSwap.json -c ajv-formats --errors text",
"fetchPermitInfo": "ts-node src/permitInfo/fetchPermitInfo.ts",
"fetchPermitInfo": "yarn run-script src/permitInfo/fetchPermitInfo.ts",
"fetchPermitInfo:mainnet": "yarn run fetchPermitInfo -- 1",
"fetchPermitInfo:gnosis": "yarn run fetchPermitInfo -- 100",
"fetchPermitInfo:sepolia": "yarn run fetchPermitInfo -- 11155111",
"recheckPermitInfo:mainnet": "yarn run fetchPermitInfo -- 1 '' '' true",
"recheckPermitInfo:gnosis": "yarn run fetchPermitInfo -- 100 '' '' true",
"recheckPermitInfo:sepolia": "yarn run fetchPermitInfo -- 11155111 '' '' true",
"run-script": "node --loader ts-node/esm --experimental-json-modules --experimental-specifier-resolution=node",
"test": "node --test"
},
"license": "(MIT OR Apache-2.0)",
"dependencies": {
"@cowprotocol/cow-sdk": "^5.1.0",
"@cowprotocol/permit-utils": "^0.1.2",
"@uniswap/token-lists": "^1.0.0-beta.33",
"ajv": "^8.12.0",
Expand All @@ -31,7 +34,6 @@
"axios": "^1.0.0",
"exponential-backoff": "^3.1.1",
"lodash": "^4.17.21",
"node-fetch": "^3.3.0",
"p-retry": "^6.1.0",
"p-throttle": "^5.1.0",
"ts-node": "^10.9.1"
Expand Down
50 changes: 50 additions & 0 deletions src/abi/multicallAbi.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
export const MULTICALL_ABI = [
{
'inputs': [
{
'internalType': 'bool',
'name': 'requireSuccess',
'type': 'bool'
},
{
'components': [
{
'internalType': 'address',
'name': 'target',
'type': 'address'
},
{
'internalType': 'bytes',
'name': 'callData',
'type': 'bytes'
}
],
'internalType': 'struct Multicall3.Call[]',
'name': 'calls',
'type': 'tuple[]'
}
],
'name': 'tryAggregate',
'outputs': [
{
'components': [
{
'internalType': 'bool',
'name': 'success',
'type': 'bool'
},
{
'internalType': 'bytes',
'name': 'returnData',
'type': 'bytes'
}
],
'internalType': 'struct Multicall3.Result[]',
'name': 'returnData',
'type': 'tuple[]'
}
],
'stateMutability': 'payable',
'type': 'function'
}
]
7 changes: 7 additions & 0 deletions src/abi/omnibridgeAbi.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
export const OMNIBRIDGE_CONTRACT_ABI = [{
'inputs': [{'internalType': 'address', 'name': '_nativeToken', 'type': 'address'}],
'name': 'bridgedTokenAddress',
'outputs': [{'internalType': 'address', 'name': '', 'type': 'address'}],
'stateMutability': 'view',
'type': 'function'
}]
9 changes: 5 additions & 4 deletions src/permitInfo/const.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
import { env } from 'node:process'
import { join } from 'node:path'
import {SupportedChainId} from '@cowprotocol/cow-sdk'

// CoW protocol contract address. Could be any address in theory for checking the token is permittable
export const SPENDER_ADDRESS = '0xC92E8bdf79f0507f65a392b0ab4667716BFE0110'

export const DEFAULT_RPC_URLS: Record<number, string> = {
1: 'https://mainnet.infura.io/v3/' + env.INFURA_API_KEY,
100: 'https://rpc.gnosischain.com',
11155111: 'https://ethereum-sepolia.publicnode.com',
export const DEFAULT_RPC_URLS: Record<SupportedChainId, string> = {
[SupportedChainId.MAINNET]: 'https://mainnet.infura.io/v3/' + env.INFURA_API_KEY,
[SupportedChainId.GNOSIS_CHAIN]: 'https://rpc.gnosischain.com',
[SupportedChainId.SEPOLIA]: 'https://ethereum-sepolia.publicnode.com',
}

export const BASE_PATH = join('..', 'public')
26 changes: 15 additions & 11 deletions src/permitInfo/fetchPermitInfo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,13 +38,14 @@ import {
import * as path from 'node:path'
import { readFileSync, writeFileSync } from 'node:fs'
import { JsonRpcProvider } from '@ethersproject/providers'
import { argv, chdir, exit } from 'node:process'
import { BASE_PATH, SPENDER_ADDRESS } from './const.ts'
import { sortPermitInfo } from './utils/sortPermitInfo.ts'
import { getProvider } from './utils/getProvider.ts'
import { Token } from './types.ts'
import { getTokensFromTokenList } from './utils/getTokensFromTokenList.ts'
import { getUnsupportedTokensFromPermitInfo } from './utils/getUnsupportedTokensFromPermitInfo.ts'
import { argv, chdir, env, exit } from 'node:process'
import { BASE_PATH, SPENDER_ADDRESS } from './const'
import { sortPermitInfo } from './utils/sortPermitInfo'
import { getProvider } from './utils/getProvider'
import { Token } from './types'
import { getTokensFromTokenList } from './utils/getTokensFromTokenList'
import { getUnsupportedTokensFromPermitInfo } from './utils/getUnsupportedTokensFromPermitInfo'
import { SupportedChainId } from '@cowprotocol/cow-sdk'

// TODO: maybe make the args nicer?
// Get args from cli: chainId, optional token lists path, optional rpcUrl, optional recheckUnsupported flag
Expand All @@ -59,7 +60,7 @@ if (!chainId) {
chdir(path.dirname(scriptPath))

async function fetchPermitInfo(
chainId: number,
chainId: SupportedChainId,
tokenListPath: string | undefined,
rpcUrl: string | undefined,
recheckUnsupported: boolean = false,
Expand All @@ -81,6 +82,10 @@ async function fetchPermitInfo(
}
}

if (!rpcUrl && chainId === 1 && !env.INFURA_API_KEY) {
throw new Error(`INFURA_API_KEY is required`)
}

// Build provider instance
const provider = getProvider(chainId, rpcUrl)

Expand Down Expand Up @@ -132,7 +137,7 @@ const throttle = pThrottle({
const throttledGetTokenPermitInfo = throttle(getTokenPermitInfo)

async function _fetchPermitInfo(
chainId: number,
chainId: SupportedChainId,
provider: JsonRpcProvider,
token: Token,
existing: PermitInfo | undefined,
Expand All @@ -151,7 +156,6 @@ async function _fetchPermitInfo(
provider,
spender: SPENDER_ADDRESS,
tokenAddress: token.address,
tokenName: token.name,
})

if ('error' in response) {
Expand All @@ -169,6 +173,6 @@ async function _fetchPermitInfo(
}

// Execute the script
fetchPermitInfo(+chainId, tokenListPath, rpcUrl, !!recheckUnsupported, !!forceRecheck).then(() =>
fetchPermitInfo(+chainId as SupportedChainId, tokenListPath, rpcUrl, !!recheckUnsupported, !!forceRecheck).then(() =>
console.info(`Done 🏁`),
)
10 changes: 3 additions & 7 deletions src/permitInfo/utils/getProvider.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,14 @@
import { JsonRpcProvider } from '@ethersproject/providers'
import { DEFAULT_RPC_URLS } from '../const.ts'
import { env } from 'node:process'
import { DEFAULT_RPC_URLS } from '../const'
import { ethers } from 'ethers'
import {SupportedChainId} from '@cowprotocol/cow-sdk'

export function getProvider(chainId: number, rpcUrl: string | undefined): JsonRpcProvider {
const rpcEndpoint = rpcUrl ? rpcUrl : DEFAULT_RPC_URLS[chainId]
const rpcEndpoint = rpcUrl ? rpcUrl : DEFAULT_RPC_URLS[chainId as SupportedChainId]

if (!rpcEndpoint) {
throw new Error(`No RPC found for network ${chainId}`)
}

if (!rpcUrl && chainId === 1 && !env.INFURA_API_KEY) {
throw new Error(`INFURA_API_KEY is required`)
}

return new ethers.providers.JsonRpcProvider(rpcEndpoint)
}
15 changes: 8 additions & 7 deletions src/permitInfo/utils/getTokensFromTokenList.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
import { readFileSync } from 'node:fs'
import { BASE_PATH } from '../const.ts'
import { Token } from '../types.ts'
import { BASE_PATH } from '../const'
import { Token } from '../types'
import { join } from 'node:path'
import { SupportedChainId } from '@cowprotocol/cow-sdk'

const tokenListsByNetwork: Record<number, string> = {
1: 'CowSwap.json',
100: 'CowSwap.json',
11155111: 'CowSwapSepolia.json',
const tokenListsByNetwork: Record<SupportedChainId, string> = {
[SupportedChainId.MAINNET]: 'CowSwap.json',
[SupportedChainId.GNOSIS_CHAIN]: 'CowSwap.json',
[SupportedChainId.SEPOLIA]: 'CowSwapSepolia.json',
}

export function getTokensFromTokenList(chainId: number, tokenListPath: string | undefined): Array<Token> {
export function getTokensFromTokenList(chainId: SupportedChainId, tokenListPath: string | undefined): Array<Token> {
const filePath = tokenListPath
? tokenListPath
: join(BASE_PATH, tokenListsByNetwork[chainId])
Expand Down
4 changes: 2 additions & 2 deletions src/permitInfo/utils/getUnsupportedTokensFromPermitInfo.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { isSupportedPermitInfo, PermitInfo } from '@cowprotocol/permit-utils'
import { Token } from '../types.js'
import { Token } from '../types'

export function getUnsupportedTokensFromPermitInfo(
chainId: number,
Expand All @@ -9,7 +9,7 @@ export function getUnsupportedTokensFromPermitInfo(

for (const [k, v] of Object.entries(allPermitInfo)) {
if (!isSupportedPermitInfo(v)) {
tokens.push({ address: k, name: v?.name, chainId })
tokens.push({ address: k, name: (v as PermitInfo)?.name, chainId })
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/permitInfo/utils/sortPermitInfo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ export function sortPermitInfo(allPermitInfo: Record<string, PermitInfo>): Recor
// Otherwise, supported tokens go on top
return isSupportedPermitInfo(pb) ? 1 : -1
})
.reduce((acc, address) => {
.reduce<{[address: string]: PermitInfo}>((acc, address) => {
// Create a new object with the keys in the sorted order
acc[address] = allPermitInfo[address]

Expand Down
Loading