diff --git a/package.json b/package.json index c3f33eb..2ce9c44 100644 --- a/package.json +++ b/package.json @@ -12,7 +12,7 @@ "size-limit": "^7.0.8", "ts-jest": "^29.1.1", "tslib": "^2.3.1", - "typescript": "^4.5.5", + "typescript": "^5.1.6", "yarn-deduplicate": "^6.0.2" }, "engines": { @@ -72,4 +72,4 @@ "prettier": "^3.0.1", "web3": "^1.7.3" } -} \ No newline at end of file +} diff --git a/src/constants/tokens.ts b/src/constants/tokens.ts index 169928f..8ae9787 100644 --- a/src/constants/tokens.ts +++ b/src/constants/tokens.ts @@ -11,7 +11,7 @@ export const COINBASE_WRAPPED_STAKED_ETH = new Token( export const COINBASE_WRAPPED_STAKED_ETH_BASE_GOERLI = new Token( ChainId.BASE_GOERLI, - '0x7c6b91D9Be155A6Db01f749217d76fF02A7227F2', + '0x4fC531f8Ae7A7808E0dccCA08F1e3c7694582950', 18, 'cbETH', 'Coinbase Wrapped Staked ETH' @@ -25,6 +25,14 @@ export const COINBASE_WRAPPED_STAKED_ETH_ARBITRUM_ONE = new Token( 'Coinbase Wrapped Staked ETH' ) +export const COINBASE_WRAPPED_STAKED_ETH_OPTIMISM = new Token( + ChainId.OPTIMISM, + '0xadDb6A0412DE1BA0F936DCaeb8Aaa24578dcF3B2', + 18, + 'cbETH', + 'Coinbase Wrapped Staked ETH' +) + export const DAI = new Token( ChainId.MAINNET, '0x6B175474E89094C44Da98b954EedeAC495271d0F', @@ -70,6 +78,14 @@ export const DAI_AVALANCHE = new Token( 'DAI.e' ) +export const DAI_BASE_GOERLI = new Token( + ChainId.BASE_GOERLI, + '0x174956bDfbCEb6e53089297cce4fE2825E58d92C', + 18, + 'DAI', + 'Dai Stablecoin' +) + export const USDT = new Token( ChainId.MAINNET, '0xdAC17F958D2ee523a2206206994597C13D831ec7', diff --git a/src/fixtures/index.ts b/src/fixtures/index.ts index b7a68ff..bfbe7fd 100644 --- a/src/fixtures/index.ts +++ b/src/fixtures/index.ts @@ -13,6 +13,8 @@ import { COINBASE_WRAPPED_STAKED_ETH, COINBASE_WRAPPED_STAKED_ETH_BASE_GOERLI, COINBASE_WRAPPED_STAKED_ETH_ARBITRUM_ONE, + DAI_BASE_GOERLI, + COINBASE_WRAPPED_STAKED_ETH_OPTIMISM, } from '../constants/tokens' import { compareTokenInfos } from '../utils' @@ -33,6 +35,9 @@ export const Tokens: Partial>> = { }, [ChainId.OPTIMISM]: { DAI: tokenToTokenInfo(DAI_OPTIMISM), + COINBASE_WRAPPED_STAKED_ETH: tokenToTokenInfo( + COINBASE_WRAPPED_STAKED_ETH_OPTIMISM + ), }, [ChainId.BNB]: { DAI: tokenToTokenInfo(DAI_BNB), @@ -42,6 +47,7 @@ export const Tokens: Partial>> = { DAI: tokenToTokenInfo(DAI_AVALANCHE), }, [ChainId.BASE_GOERLI]: { + DAI: tokenToTokenInfo(DAI_BASE_GOERLI), COINBASE_WRAPPED_STAKED_ETH: tokenToTokenInfo( COINBASE_WRAPPED_STAKED_ETH_BASE_GOERLI ), diff --git a/src/index.test.ts b/src/index.test.ts index 8abb337..ec6a399 100644 --- a/src/index.test.ts +++ b/src/index.test.ts @@ -5,9 +5,11 @@ import { COINBASE_WRAPPED_STAKED_ETH, COINBASE_WRAPPED_STAKED_ETH_ARBITRUM_ONE, COINBASE_WRAPPED_STAKED_ETH_BASE_GOERLI, + COINBASE_WRAPPED_STAKED_ETH_OPTIMISM, DAI, DAI_ARBITRUM_ONE, DAI_AVALANCHE, + DAI_BASE_GOERLI, DAI_BNB, DAI_OPTIMISM, DAI_POLYGON, @@ -255,93 +257,6 @@ describe(mergeTokenLists, () => { }) }) describe(chainify, () => { - it('creates tokenMap correctly in chainify', async () => { - const chainified = await chainify(sampleL1TokenList) - - expect(chainified.tokenMap).toEqual({ - '10_0xDA10009cBd5D07dd0CeCc66161FC93D7c9000da1': { - ...Tokens[ChainId.OPTIMISM]!.DAI, - name: 'Dai Stablecoin', - extensions: { - bridgeInfo: { - [ChainId.MAINNET]: { - tokenAddress: DAI.address, - }, - }, - }, - }, - '137_0x8f3Cf7ad23Cd3CaDbD9735AFf958023239c6A063': { - ...Tokens[ChainId.POLYGON]!.DAI, - extensions: { - bridgeInfo: { - [ChainId.MAINNET]: { - tokenAddress: DAI.address, - }, - }, - }, - }, - '1_0x6B175474E89094C44Da98b954EedeAC495271d0F': { - ...Tokens[ChainId.MAINNET]!.DAI, - extensions: { - bridgeInfo: { - [ChainId.BNB]: { - tokenAddress: DAI_BNB.address, - }, - [ChainId.AVALANCHE]: { - tokenAddress: DAI_AVALANCHE.address, - }, - [ChainId.OPTIMISM]: { - tokenAddress: DAI_OPTIMISM.address, - }, - [ChainId.POLYGON]: { - tokenAddress: DAI_POLYGON.address, - }, - [ChainId.ARBITRUM_ONE]: { - tokenAddress: DAI_ARBITRUM_ONE.address, - // destBridgeAddress: arbBridgeL2Address, - // originBridgeAddress: arbBridgeL1Address, - }, - }, - }, - }, - '42161_0xDA10009cBd5D07dd0CeCc66161FC93D7c9000da1': { - ...Tokens[ChainId.ARBITRUM_ONE]!.DAI, - extensions: { - bridgeInfo: { - [ChainId.MAINNET]: { - tokenAddress: DAI.address, - // originBridgeAddress: arbBridgeL2Address, - // destBridgeAddress: arbBridgeL1Address, - }, - }, - }, - name: 'Dai Stablecoin', - }, - '43114_0xd586E7F844cEa2F87f50152665BCbc2C279D8d70': { - ...Tokens[ChainId.AVALANCHE]!.DAI, - name: 'Dai Stablecoin', - symbol: 'DAI', - extensions: { - bridgeInfo: { - [ChainId.MAINNET]: { - tokenAddress: DAI.address, - }, - }, - }, - }, - '56_0x1AF3F329e8BE154074D8769D1FFa4eE058B1DBc3': { - ...Tokens[ChainId.BNB]!.DAI, - extensions: { - bridgeInfo: { - [ChainId.MAINNET]: { - tokenAddress: DAI.address, - }, - }, - }, - }, - }) - }) - it('provides bridge extensions', async () => { const chainified = await chainify(sampleL1TokenList) @@ -367,6 +282,9 @@ describe(chainify, () => { // destBridgeAddress: arbBridgeL2Address, // originBridgeAddress: arbBridgeL1Address, }, + [ChainId.BASE_GOERLI]: { + tokenAddress: DAI_BASE_GOERLI.address, + }, }, }, }, @@ -426,10 +344,20 @@ describe(chainify, () => { }, }, }, + { + ...Tokens[ChainId.BASE_GOERLI]!.DAI, + extensions: { + bridgeInfo: { + [ChainId.MAINNET]: { + tokenAddress: DAI.address, + }, + }, + }, + }, ]) }) - it('provides bridge extensions for base goerli list', async () => { + it('provides bridge extensions for base list', async () => { const chainified = await chainify(sampleL1TokenList_3) expect(chainified.tokens).toEqual([ @@ -437,12 +365,26 @@ describe(chainify, () => { ...Tokens[ChainId.MAINNET]!.COINBASE_WRAPPED_STAKED_ETH, extensions: { bridgeInfo: { - [ChainId.ARBITRUM_ONE]: { - tokenAddress: COINBASE_WRAPPED_STAKED_ETH_ARBITRUM_ONE.address, + [ChainId.OPTIMISM]: { + tokenAddress: COINBASE_WRAPPED_STAKED_ETH_OPTIMISM.address, }, [ChainId.BASE_GOERLI]: { tokenAddress: COINBASE_WRAPPED_STAKED_ETH_BASE_GOERLI.address, }, + [ChainId.ARBITRUM_ONE]: { + tokenAddress: COINBASE_WRAPPED_STAKED_ETH_ARBITRUM_ONE.address, + }, + }, + }, + }, + { + ...Tokens[ChainId.OPTIMISM]!.COINBASE_WRAPPED_STAKED_ETH, + name: 'Coinbase Wrapped Staked ETH', + extensions: { + bridgeInfo: { + [ChainId.MAINNET]: { + tokenAddress: COINBASE_WRAPPED_STAKED_ETH.address, + }, }, }, }, diff --git a/src/providers/OptimismMappingProvider.ts b/src/providers/OptimismMappingProvider.ts index 8fa7c36..d381700 100644 --- a/src/providers/OptimismMappingProvider.ts +++ b/src/providers/OptimismMappingProvider.ts @@ -5,7 +5,7 @@ import { GenericMappedTokenData } from '../constants/types' const optimismTokenListURL = 'https://raw.githubusercontent.com/' + - 'ethereum-optimism/ethereum-optimism.github.io/2138386277e4156d159615d1840882cecc398437/optimism.tokenlist.json' + 'ethereum-optimism/ethereum-optimism.github.io/master/optimism.tokenlist.json' /** * The Optimism L2 mapping (linked above) is manually maintained by the Optimism team. @@ -16,25 +16,27 @@ export class OptimismMappingProvider implements MappingProvider { async provide(): Promise { const tokens: { [key: string]: string | undefined } = {} - let optimismTokens = await getTokenList(optimismTokenListURL) + let allTokens = await getTokenList(optimismTokenListURL) - for (const token of optimismTokens.tokens) { - const bridgeInfo = token?.extensions?.bridgeInfo + let opTokenId_baseAddressMap: Record = {} + allTokens.tokens.forEach((token) => { + if (token.chainId === ChainId.OPTIMISM) { + if (typeof token.extensions?.opTokenId === 'string') { + opTokenId_baseAddressMap[token.extensions.opTokenId] = token.address + } + } + }) + + allTokens.tokens.forEach((token) => { if ( token.chainId === ChainId.MAINNET && - bridgeInfo && - typeof bridgeInfo === 'object' + typeof token.extensions?.opTokenId === 'string' && + token.extensions!.opTokenId in opTokenId_baseAddressMap ) { - const opBridgeInfo = bridgeInfo[ChainId.OPTIMISM] - if ( - opBridgeInfo && - typeof opBridgeInfo === 'object' && - typeof opBridgeInfo.tokenAddress === 'string' - ) { - tokens[token.address.toLowerCase()] = opBridgeInfo.tokenAddress - } + tokens[token.address.toLowerCase()] = + opTokenId_baseAddressMap[token.extensions!.opTokenId] } - } + }) return tokens } diff --git a/yarn.lock b/yarn.lock index 72a254a..360d015 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5177,7 +5177,7 @@ is-module@^1.0.0: resolved "https://registry.npmjs.org/is-module/-/is-module-1.0.0.tgz" integrity sha1-Mlj7afeMFNW4FdZkM2tM/7ZEFZE= -is-negative-zero@^2.0.1, is-negative-zero@^2.0.2: +is-negative-zero@^2.0.2: version "2.0.2" resolved "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz" integrity sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA== @@ -5244,7 +5244,7 @@ is-retry-allowed@^1.0.0: resolved "https://registry.yarnpkg.com/is-retry-allowed/-/is-retry-allowed-1.2.0.tgz#d778488bd0a4666a3be8a1482b9f2baafedea8b4" integrity sha512-RUbUeKwvm3XG2VYamhJL1xFktgjvPzL0Hq8C+6yrWIswDy3BIXGqCxhxkc30N9jqK311gVU137K8Ei55/zVJRg== -is-shared-array-buffer@^1.0.1, is-shared-array-buffer@^1.0.2: +is-shared-array-buffer@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz#8f259c573b60b6a32d4058a1a07430c0a7344c79" integrity sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA== @@ -5301,7 +5301,7 @@ is-unicode-supported@^0.1.0: resolved "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz" integrity sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw== -is-weakref@^1.0.1, is-weakref@^1.0.2: +is-weakref@^1.0.2: version "1.0.2" resolved "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz" integrity sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ== @@ -6208,11 +6208,6 @@ miller-rabin@^4.0.0: bn.js "^4.0.0" brorand "^1.0.1" -mime-db@1.51.0: - version "1.51.0" - resolved "https://registry.npmjs.org/mime-db/-/mime-db-1.51.0.tgz" - integrity sha512-5y8A56jg7XVQx2mbv1lu49NR4dokRnhZYTtL+KGfaa27uq4pSTXkwQkFJl4pkRMyNFz/EtYDSkiiEHx3F7UN6g== - mime-db@1.52.0: version "1.52.0" resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70" @@ -6274,7 +6269,7 @@ minimatch@^3.0.4, minimatch@^3.1.2: dependencies: brace-expansion "^1.1.7" -minimist@^1.2.0, minimist@^1.2.5, minimist@^1.2.6: +minimist@^1.2.0, minimist@^1.2.6: version "1.2.6" resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.6.tgz#8637a5b759ea0d6e98702cfb3a9283323c93af44" integrity sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q== @@ -6485,12 +6480,12 @@ object-assign@^4, object-assign@^4.1.0, object-assign@^4.1.1: resolved "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz" integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM= -object-inspect@^1.11.0, object-inspect@^1.12.0, object-inspect@^1.9.0: +object-inspect@^1.12.0, object-inspect@^1.9.0: version "1.12.2" resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.12.2.tgz#c0641f26394532f28ab8d796ab954e43c009a8ea" integrity sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ== -object-keys@^1.0.12, object-keys@^1.1.1: +object-keys@^1.1.1: version "1.1.1" resolved "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz" integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA== @@ -7674,7 +7669,7 @@ string.prototype.matchall@^4.0.6: regexp.prototype.flags "^1.3.1" side-channel "^1.0.4" -string.prototype.trimend@^1.0.4, string.prototype.trimend@^1.0.5: +string.prototype.trimend@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/string.prototype.trimend/-/string.prototype.trimend-1.0.5.tgz#914a65baaab25fbdd4ee291ca7dde57e869cb8d0" integrity sha512-I7RGvmjV4pJ7O3kdf+LXFpVfdNOxtCW/2C8f6jNiW4+PQchwxkCDzlk1/7p+Wl4bqFIZeF47qAHXLuHHWKAxog== @@ -7683,7 +7678,7 @@ string.prototype.trimend@^1.0.4, string.prototype.trimend@^1.0.5: define-properties "^1.1.4" es-abstract "^1.19.5" -string.prototype.trimstart@^1.0.4, string.prototype.trimstart@^1.0.5: +string.prototype.trimstart@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/string.prototype.trimstart/-/string.prototype.trimstart-1.0.5.tgz#5466d93ba58cfa2134839f81d7f42437e8c01fef" integrity sha512-THx16TJCGlsN0o6dl2o6ncWUsdgnLRSA23rRE5pyGBw/mLr3Ej/R2LaqCtgP8VNMGZsvMWnf9ooZPyY2bHvUFg== @@ -8088,12 +8083,17 @@ typescript@^4.5.5: resolved "https://registry.npmjs.org/typescript/-/typescript-4.5.5.tgz" integrity sha512-TCTIul70LyWe6IJWT8QSYeA54WQe8EjQFU4wY52Fasj5UKx88LNYKCgBEHcOMOrFF1rKGbD8v/xcNWVUq9SymA== +typescript@^5.1.6: + version "5.1.6" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.1.6.tgz#02f8ac202b6dad2c0dd5e0913745b47a37998274" + integrity sha512-zaWCozRZ6DLEWAWFrVDz1H6FVXzUSfTy5FUMWsQlU8Ym5JP9eO4xkTIROFCQvhQf61z6O/G6ugw3SgAnvvm+HA== + ultron@~1.1.0: version "1.1.1" resolved "https://registry.yarnpkg.com/ultron/-/ultron-1.1.1.tgz#9fe1536a10a664a65266a1e3ccf85fd36302bc9c" integrity sha512-UIEXBNeYmKptWH6z8ZnqTeS8fV74zG0/eRU9VGkpzz+LIJNs8W/zM/L+7ctCkRrgbNnnR0xxw4bKOr0cW0N0Og== -unbox-primitive@^1.0.1, unbox-primitive@^1.0.2: +unbox-primitive@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/unbox-primitive/-/unbox-primitive-1.0.2.tgz#29032021057d5e6cdbd08c5129c226dff8ed6f9e" integrity sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==