@morpho-org/blue-sdk 1.0.1 → 1.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (151) hide show
  1. package/package.json +10 -6
  2. package/src/addresses.ts +261 -0
  3. package/src/chain/chain.constants.ts +235 -0
  4. package/src/chain/chain.test.ts +51 -0
  5. package/src/chain/chain.types.ts +42 -0
  6. package/src/chain/chain.utils.ts +44 -0
  7. package/src/constants.ts +18 -0
  8. package/src/errors.ts +75 -0
  9. package/src/ethers/ethers.test.ts +17 -0
  10. package/src/ethers/safeGetAddress.ts +4 -0
  11. package/src/ethers/safeParseUnits.ts +29 -0
  12. package/src/evm.ts +172 -0
  13. package/src/helpers/format/format.test.ts +340 -0
  14. package/src/helpers/format/format.ts +416 -0
  15. package/src/helpers/getChecksumedAddress.ts +15 -0
  16. package/{lib/helpers/isZeroAddressOrUnset.d.ts → src/helpers/isZeroAddressOrUnset.ts} +7 -1
  17. package/src/helpers/locale.ts +108 -0
  18. package/src/holding/Holding.ts +109 -0
  19. package/src/market/Market.ts +479 -0
  20. package/src/market/MarketConfig.ts +108 -0
  21. package/src/market/MarketUtils.test.ts +25 -0
  22. package/src/market/MarketUtils.ts +467 -0
  23. package/src/maths/AdaptiveCurveIrmLib.ts +143 -0
  24. package/src/maths/MathLib.ts +208 -0
  25. package/src/maths/MathUtils.ts +31 -0
  26. package/src/maths/SharesMath.ts +40 -0
  27. package/src/notifications.ts +167 -0
  28. package/src/position/Position.ts +251 -0
  29. package/src/signatures/index.ts +18 -0
  30. package/src/signatures/manager.ts +50 -0
  31. package/src/signatures/permit.ts +126 -0
  32. package/src/signatures/permit2.ts +120 -0
  33. package/src/signatures/types.ts +18 -0
  34. package/src/signatures/utils.ts +83 -0
  35. package/src/tests/mocks/markets.ts +110 -0
  36. package/src/token/ERC20Metadata.ts +124 -0
  37. package/src/token/Token.ts +83 -0
  38. package/src/token/TokenNamespace.ts +76 -0
  39. package/src/token/WrappedToken.ts +142 -0
  40. package/src/types.ts +37 -0
  41. package/src/user/User.ts +32 -0
  42. package/src/user/user.types.ts +23 -0
  43. package/src/vault/Vault.ts +370 -0
  44. package/src/vault/VaultAllocation.ts +58 -0
  45. package/src/vault/VaultConfig.ts +55 -0
  46. package/src/vault/VaultUtils.ts +47 -0
  47. package/lib/addresses.d.ts +0 -168
  48. package/lib/addresses.js +0 -169
  49. package/lib/chain/chain.constants.d.ts +0 -3
  50. package/lib/chain/chain.constants.js +0 -232
  51. package/lib/chain/chain.types.d.ts +0 -20
  52. package/lib/chain/chain.types.js +0 -30
  53. package/lib/chain/chain.utils.d.ts +0 -14
  54. package/lib/chain/chain.utils.js +0 -30
  55. package/lib/chain/index.js +0 -18
  56. package/lib/constants.d.ts +0 -8
  57. package/lib/constants.js +0 -13
  58. package/lib/errors.d.ts +0 -37
  59. package/lib/errors.js +0 -71
  60. package/lib/ethers/index.js +0 -18
  61. package/lib/ethers/safeGetAddress.d.ts +0 -1
  62. package/lib/ethers/safeGetAddress.js +0 -6
  63. package/lib/ethers/safeParseUnits.d.ts +0 -2
  64. package/lib/ethers/safeParseUnits.js +0 -25
  65. package/lib/evm.d.ts +0 -36
  66. package/lib/evm.js +0 -113
  67. package/lib/helpers/format/format.d.ts +0 -98
  68. package/lib/helpers/format/format.js +0 -301
  69. package/lib/helpers/format/index.js +0 -17
  70. package/lib/helpers/getChecksumedAddress.d.ts +0 -7
  71. package/lib/helpers/getChecksumedAddress.js +0 -17
  72. package/lib/helpers/index.js +0 -20
  73. package/lib/helpers/isZeroAddressOrUnset.js +0 -14
  74. package/lib/helpers/locale.d.ts +0 -36
  75. package/lib/helpers/locale.js +0 -86
  76. package/lib/holding/Holding.d.ts +0 -60
  77. package/lib/holding/Holding.js +0 -31
  78. package/lib/holding/index.js +0 -17
  79. package/lib/index.d.ts +0 -33
  80. package/lib/index.js +0 -62
  81. package/lib/market/Market.d.ts +0 -159
  82. package/lib/market/Market.js +0 -240
  83. package/lib/market/MarketConfig.d.ts +0 -44
  84. package/lib/market/MarketConfig.js +0 -56
  85. package/lib/market/MarketUtils.d.ts +0 -165
  86. package/lib/market/MarketUtils.js +0 -182
  87. package/lib/market/index.js +0 -19
  88. package/lib/maths/AdaptiveCurveIrmLib.d.ts +0 -37
  89. package/lib/maths/AdaptiveCurveIrmLib.js +0 -116
  90. package/lib/maths/MathLib.d.ts +0 -94
  91. package/lib/maths/MathLib.js +0 -153
  92. package/lib/maths/MathUtils.d.ts +0 -15
  93. package/lib/maths/MathUtils.js +0 -33
  94. package/lib/maths/SharesMath.d.ts +0 -12
  95. package/lib/maths/SharesMath.js +0 -22
  96. package/lib/maths/index.js +0 -20
  97. package/lib/notifications.d.ts +0 -98
  98. package/lib/notifications.js +0 -52
  99. package/lib/position/Position.d.ts +0 -118
  100. package/lib/position/Position.js +0 -145
  101. package/lib/position/index.js +0 -17
  102. package/lib/signatures/index.d.ts +0 -12
  103. package/lib/signatures/index.js +0 -39
  104. package/lib/signatures/manager.d.ts +0 -10
  105. package/lib/signatures/manager.js +0 -37
  106. package/lib/signatures/permit.d.ts +0 -21
  107. package/lib/signatures/permit.js +0 -101
  108. package/lib/signatures/permit2.d.ts +0 -20
  109. package/lib/signatures/permit2.js +0 -91
  110. package/lib/signatures/types.d.ts +0 -13
  111. package/lib/signatures/types.js +0 -2
  112. package/lib/signatures/utils.d.ts +0 -6
  113. package/lib/signatures/utils.js +0 -44
  114. package/lib/tests/mocks/markets.d.ts +0 -17
  115. package/lib/tests/mocks/markets.js +0 -108
  116. package/lib/token/ERC20Metadata.d.ts +0 -249
  117. package/lib/token/ERC20Metadata.js +0 -81
  118. package/lib/token/Token.d.ts +0 -45
  119. package/lib/token/Token.js +0 -39
  120. package/lib/token/TokenNamespace.d.ts +0 -18
  121. package/lib/token/TokenNamespace.js +0 -55
  122. package/lib/token/WrappedToken.d.ts +0 -42
  123. package/lib/token/WrappedToken.js +0 -87
  124. package/lib/token/index.js +0 -18
  125. package/lib/types.d.ts +0 -29
  126. package/lib/types.js +0 -23
  127. package/lib/user/User.d.ts +0 -20
  128. package/lib/user/User.js +0 -11
  129. package/lib/user/index.js +0 -18
  130. package/lib/user/user.types.d.ts +0 -18
  131. package/lib/user/user.types.js +0 -2
  132. package/lib/vault/Vault.d.ts +0 -167
  133. package/lib/vault/Vault.js +0 -156
  134. package/lib/vault/VaultAllocation.d.ts +0 -38
  135. package/lib/vault/VaultAllocation.js +0 -18
  136. package/lib/vault/VaultConfig.d.ts +0 -23
  137. package/lib/vault/VaultConfig.js +0 -26
  138. package/lib/vault/VaultUtils.d.ts +0 -17
  139. package/lib/vault/VaultUtils.js +0 -17
  140. package/lib/vault/index.js +0 -20
  141. /package/{lib/chain/index.d.ts → src/chain/index.ts} +0 -0
  142. /package/{lib/ethers/index.d.ts → src/ethers/index.ts} +0 -0
  143. /package/{lib/helpers/format/index.d.ts → src/helpers/format/index.ts} +0 -0
  144. /package/{lib/helpers/index.d.ts → src/helpers/index.ts} +0 -0
  145. /package/{lib/holding/index.d.ts → src/holding/index.ts} +0 -0
  146. /package/{lib/market/index.d.ts → src/market/index.ts} +0 -0
  147. /package/{lib/maths/index.d.ts → src/maths/index.ts} +0 -0
  148. /package/{lib/position/index.d.ts → src/position/index.ts} +0 -0
  149. /package/{lib/token/index.d.ts → src/token/index.ts} +0 -0
  150. /package/{lib/user/index.d.ts → src/user/index.ts} +0 -0
  151. /package/{lib/vault/index.d.ts → src/vault/index.ts} +0 -0
package/package.json CHANGED
@@ -1,11 +1,11 @@
1
1
  {
2
2
  "name": "@morpho-org/blue-sdk",
3
- "version": "1.0.1",
3
+ "version": "1.0.2",
4
4
  "author": "Morpho Association <contact@morpho.org>",
5
5
  "license": "MIT",
6
6
  "main": "src/index.ts",
7
7
  "files": [
8
- "lib"
8
+ "src"
9
9
  ],
10
10
  "scripts": {
11
11
  "prepublish": "yarn build",
@@ -15,21 +15,25 @@
15
15
  "test:blue-sdk": "yarn test"
16
16
  },
17
17
  "dependencies": {
18
- "@morpho-org/morpho-ts": "1.0.1",
18
+ "@morpho-org/morpho-ts": "1.0.2",
19
19
  "ethers": "^6.12.1",
20
20
  "ethers-multicall-provider": "^6.3.0",
21
21
  "ethers-types": "^3.15.1",
22
22
  "rxjs": "^7.8.1"
23
23
  },
24
24
  "devDependencies": {
25
- "@morpho-org/morpho-test": "1.0.1",
25
+ "@morpho-org/morpho-test": "1.0.2",
26
26
  "@types/jest": "^29.5.12",
27
27
  "jest": "^29.6.2",
28
28
  "ts-jest": "^29.1.1",
29
29
  "typescript": "^5.4.5"
30
30
  },
31
31
  "publishConfig": {
32
- "access": "public"
32
+ "access": "public",
33
+ "main": "lib/index.js",
34
+ "files": [
35
+ "lib"
36
+ ]
33
37
  },
34
38
  "jest": {
35
39
  "verbose": true,
@@ -50,5 +54,5 @@
50
54
  ],
51
55
  "preset": "ts-jest"
52
56
  },
53
- "gitHead": "474aa49a57a91da7d47a0bf666b5fccede4d395e"
57
+ "gitHead": "d8e67d7bf53582572306f0c11761163208129ff1"
54
58
  }
@@ -0,0 +1,261 @@
1
+ import { ChainId } from "./chain";
2
+ import { UnsupportedChainIdError } from "./errors";
3
+ import { Address } from "./types";
4
+
5
+ /** Address used to replicate an erc20-behaviour for native token.
6
+ *
7
+ * NB: data might differ from expected onchain native token data
8
+ */
9
+ export const NATIVE_ADDRESS = "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE";
10
+
11
+ export const addresses = {
12
+ [ChainId.EthGoerliTestnet]: {
13
+ morpho: "0x64c7044050Ba0431252df24fEd4d9635a275CB41",
14
+ permit2: "0x000000000022D473030F116dDEE9F6B43aC78BA3",
15
+ bundler: "0xCFFbEEAFCD79Fd68FD56Dbc31A419f290A2Fe9e0",
16
+ urd: "0x820755E757a590683dc43115290eb1Cb20a60405",
17
+ wNative: "0xB4FBF271143F4FBf7B91A5ded31805e42b2208d6",
18
+ stEth: "0x1643E812aE58766192Cf7D2Cf9567dF2C37e9B7F",
19
+ wstEth: "0x6320cD32aA674d2898A68ec82e869385Fc5f7E2f",
20
+ rEth: "0x178E141a0E3b34152f73Ff610437A7bf9B83267A",
21
+ sDai: "0xD8134205b0328F5676aaeFb3B2a0DC15f4029d8C",
22
+ dai: "0x11fE4B6AE13d2a6055C8D9cF65c55bac32B5d844",
23
+ usdc: "0x62bD2A599664D421132d7C54AB4DbE3233f4f0Ae",
24
+ usdt: "0x576e379FA7B899b4De1E251e935B31543Df3e954",
25
+ },
26
+ [ChainId.EthMainnet]: {
27
+ morpho: "0xBBBBBbbBBb9cC5e90e3b3Af64bdAF62C37EEFFCb",
28
+ adaptiveCurveIrm: "0x870aC11D48B15DB9a138Cf899d20F13F79Ba00BC",
29
+ publicAllocator: "0xfd32fA2ca22c76dD6E550706Ad913FC6CE91c75D",
30
+ permit2: "0x000000000022D473030F116dDEE9F6B43aC78BA3",
31
+ bundler: "0x4095F064B8d3c3548A3bebfd0Bbfd04750E30077",
32
+ aaveV3OptimizerBundler: "0x16F38d2E764E7BeBF625a8E995b34968226D2F9c",
33
+ aaveV2Bundler: "0xb3dCc75DB379925edFd3007511A8CE0cB4aa8e76",
34
+ aaveV3Bundler: "0x98ccB155E86bb478d514a827d16f58c6912f9BDC",
35
+ morphoToken: "0x9994E35Db50125E0DF82e4c2dde62496CE330999",
36
+ rEth: "0xae78736Cd615f374D3085123A210448E74Fc6393",
37
+ sDai: "0x83F20F44975D03b1b09e64809B757c47f942BEeA",
38
+ dai: "0x6B175474E89094C44Da98b954EedeAC495271d0F",
39
+ mkr: "0x9f8F72aA9304c8B593d555F12eF6589cC3A579A2",
40
+ wstEth: "0x7f39C581F595B53c5cb19bD0b3f8dA6c935E2Ca0",
41
+ wNative: "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2",
42
+ stEth: "0xae7ab96520DE3A18E5e111B5EaAb095312D7fE84",
43
+ USDe: "0x4c9EDD5852cd905f086C759E8383e09bff1E68B3",
44
+ sUSDe: "0x9D39A5DE30e57443BfF2A8307A4256c8797A3497",
45
+ bIB01: "0xCA30c93B02514f86d5C86a6e375E3A330B435Fb5",
46
+ // If we want to change the wbIB01 address, we have to check if the new one has simple permit or not.
47
+ // Currently, wbIB01 is considered to have simple permit.
48
+ wbIB01: "0xcA2A7068e551d5C4482eb34880b194E4b945712F",
49
+ bC3M: "0x2F123cF3F37CE3328CC9B5b8415f9EC5109b45e7",
50
+ // If we want to change the wbC3M address, we have to check if the new one has simple permit or not.
51
+ // Currently, wbC3M is considered to have simple permit.
52
+ wbC3M: "0x95D7337d43340E2721960Dc402D9b9117f0d81a2",
53
+ usdc: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
54
+ usdt: "0xdAC17F958D2ee523a2206206994597C13D831ec7",
55
+ wbtc: "0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599",
56
+ sWise: "0x48C3399719B582dD63eB5AADf12A40B4C3f52FA2",
57
+ osEth: "0xf1C9acDc66974dFB6dEcB12aA385b9cD01190E38",
58
+ weEth: "0xCd5fE23C85820F7B72D0926FC9b05b43E359b7ee",
59
+ ezEth: "0xbf5495Efe5DB9ce00f80364C8B423567e58d2110",
60
+ pyUsd: "0x6c3ea9036406852006290770BEdFcAbA0e23A0e8",
61
+ crvUsd: "0xf939E0A03FB07F59A73314E73794Be0E57ac1b4E",
62
+ morphoOperator: "0x640428D38189B11B844dAEBDBAAbbdfbd8aE0143",
63
+ butterfly: "0xc55126051B22eBb829D00368f4B12Bde432de5Da",
64
+ marketRewardsProgramRegistry: "0x5148bF15bb722E1854F66430Bc9FeD0E9FDaCE7D",
65
+ timeBoundedUrd: "0x330eefa8a787552DC5cAd3C3cA644844B1E61Ddb",
66
+ rsEth: "0xA1290d69c65A6Fe4DF752f95823fae25cB99e5A7",
67
+
68
+ /* Curve tokens */
69
+ "stkcvxcrvUSDTWBTCWETH-morpho":
70
+ "0xb0Ce26C88e4e7DCa51968b6047f44646f5064278",
71
+ crvUSDTWBTCWETH: "0xf5f5B97624542D72A9E06f04804Bf81baA15e2B4",
72
+
73
+ "stkcvxcrvUSDCWBTCWETH-morpho":
74
+ "0x0ea1a65A2c255f24Ee8D81eA6AaC54Decd9d269e",
75
+ crvUSDCWBTCWETH: "0x7F86Bf177Dd4F3494b841a37e810A34dD56c829B",
76
+
77
+ "stkcvxcrvCRVUSDTBTCWSTETH-morpho":
78
+ "0x3ce8Ec9f3d89aD0A2DdbCC3FDB8991BD241Fc82E",
79
+ crvCRVUSDTBTCWSTETH: "0x2889302a794dA87fBF1D6Db415C1492194663D13",
80
+
81
+ "stkcvxTryLSD-morpho": "0x6BA072F0d22806F2C52e9792AF47f2D59103BEBE",
82
+ tryLSD: "0x2570f1bD5D2735314FC102eb12Fc1aFe9e6E7193",
83
+
84
+ "stkcvxcrvUSDETHCRV-morpho": "0xAc904BAfBb5FB04Deb2b6198FdCEedE75a78Ce5a",
85
+ crvUSDETHCRV: "0x4eBdF703948ddCEA3B11f675B4D1Fba9d2414A14",
86
+ },
87
+ [ChainId.BaseMainnet]: {
88
+ morpho: "0xBBBBBbbBBb9cC5e90e3b3Af64bdAF62C37EEFFCb",
89
+ permit2: "0x000000000022D473030F116dDEE9F6B43aC78BA3",
90
+ bundler: "0xb5D342521EB5b983aE6a6324A4D9eac87C9D1987",
91
+ wNative: "0x4200000000000000000000000000000000000006",
92
+ adaptiveCurveIrm: "0x46415998764C29aB2a25CbeA6254146D50D22687",
93
+ publicAllocator: "0xA090dD1a701408Df1d4d0B85b716c87565f90467",
94
+
95
+ /* Tokens */
96
+ usdc: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
97
+ cbEth: "0x2Ae3F1Ec7F1F5012CFEab0185bfc7aa3cf0DEc22",
98
+ },
99
+ } as const;
100
+
101
+ interface ChainAddresses {
102
+ morpho: Address;
103
+ permit2: Address;
104
+ bundler: Address;
105
+ wNative: Address;
106
+ adaptiveCurveIrm?: Address;
107
+ publicAllocator?: Address;
108
+ morphoToken?: Address;
109
+ wstEth?: Address;
110
+ stEth?: Address;
111
+ dai?: Address;
112
+ mkr?: Address;
113
+ rEth?: Address;
114
+ sDai?: Address;
115
+ usdc?: Address;
116
+ usdt?: Address;
117
+ bIB01?: Address;
118
+ wbIB01?: Address;
119
+ bC3M?: Address;
120
+ wbC3M?: Address;
121
+ wbtc?: Address;
122
+ sWise?: Address;
123
+ osEth?: Address;
124
+ weEth?: Address;
125
+ ezEth?: Address;
126
+ pyUsd?: Address;
127
+ sUSDe?: Address;
128
+ USDe?: Address;
129
+ marketRewardsProgramRegistry?: Address;
130
+ timeBoundedUrd?: Address;
131
+ rsEth?: Address;
132
+ crvUsd?: Address;
133
+ morphoOperator?: Address;
134
+ butterfly?: Address;
135
+ aaveV3OptimizerBundler?: Address;
136
+ aaveV2Bundler?: Address;
137
+ aaveV3Bundler?: Address;
138
+
139
+ /* Curve tokens */
140
+ "stkcvxcrvUSDTWBTCWETH-morpho"?: Address;
141
+ crvUSDTWBTCWETH?: Address;
142
+ "stkcvxcrvUSDCWBTCWETH-morpho"?: Address;
143
+ crvUSDCWBTCWETH?: Address;
144
+ "stkcvxcrvCRVUSDTBTCWSTETH-morpho"?: Address;
145
+ crvCRVUSDTBTCWSTETH?: Address;
146
+ "stkcvxTryLSD-morpho"?: Address;
147
+ tryLSD?: Address;
148
+ "stkcvxcrvUSDETHCRV-morpho"?: Address;
149
+ crvUSDETHCRV?: Address;
150
+ }
151
+
152
+ export type AddressLabel = keyof (typeof addresses)[ChainId];
153
+
154
+ export default addresses as {
155
+ [n in ChainId]: ChainAddresses;
156
+ };
157
+
158
+ export const getChainAddresses = (chainId: number): ChainAddresses => {
159
+ const chainAddresses = addresses[chainId as ChainId];
160
+
161
+ if (!chainAddresses) throw new UnsupportedChainIdError(chainId);
162
+
163
+ return chainAddresses;
164
+ };
165
+
166
+ export const wrapping: {
167
+ [n in ChainId]: {
168
+ [unwrapped: string]: string;
169
+ };
170
+ } = {
171
+ [ChainId.EthGoerliTestnet]: {
172
+ [NATIVE_ADDRESS]: addresses[ChainId.EthGoerliTestnet].wNative,
173
+ [addresses[ChainId.EthGoerliTestnet].stEth]:
174
+ addresses[ChainId.EthGoerliTestnet].wstEth,
175
+ },
176
+ [ChainId.EthMainnet]: {
177
+ [addresses[ChainId.EthMainnet].bIB01]: addresses[ChainId.EthMainnet].wbIB01,
178
+ [addresses[ChainId.EthMainnet].bC3M]: addresses[ChainId.EthMainnet].wbC3M,
179
+ [NATIVE_ADDRESS]: addresses[ChainId.EthMainnet].wNative,
180
+ [addresses[ChainId.EthMainnet].stEth]: addresses[ChainId.EthMainnet].wstEth,
181
+ [addresses[ChainId.EthMainnet].crvUSDTWBTCWETH]:
182
+ addresses[ChainId.EthMainnet]["stkcvxcrvUSDTWBTCWETH-morpho"],
183
+ [addresses[ChainId.EthMainnet].crvUSDCWBTCWETH]:
184
+ addresses[ChainId.EthMainnet]["stkcvxcrvUSDCWBTCWETH-morpho"],
185
+ [addresses[ChainId.EthMainnet].crvCRVUSDTBTCWSTETH]:
186
+ addresses[ChainId.EthMainnet]["stkcvxcrvCRVUSDTBTCWSTETH-morpho"],
187
+ [addresses[ChainId.EthMainnet].tryLSD]:
188
+ addresses[ChainId.EthMainnet]["stkcvxTryLSD-morpho"],
189
+ [addresses[ChainId.EthMainnet].crvUSDETHCRV]:
190
+ addresses[ChainId.EthMainnet]["stkcvxcrvUSDETHCRV-morpho"],
191
+ },
192
+ [ChainId.BaseMainnet]: {
193
+ [NATIVE_ADDRESS]: addresses[ChainId.BaseMainnet].wNative,
194
+ },
195
+ };
196
+
197
+ export const reverseWrapping = Object.fromEntries(
198
+ Object.entries(wrapping).map(([n, chainWrapping]) => [
199
+ n,
200
+ Object.fromEntries(
201
+ Object.entries(chainWrapping)
202
+ .map((w) => [...w].reverse())
203
+ .filter(([add, wAdd]) => !!add && !!wAdd)
204
+ ),
205
+ ])
206
+ ) as typeof wrapping;
207
+
208
+ export function getUnwrappedToken(wrappedToken: Address, chainId: ChainId) {
209
+ return reverseWrapping[chainId][wrappedToken];
210
+ }
211
+
212
+ export function getWrappedToken(unWrappedToken: Address, chainId: ChainId) {
213
+ return wrapping[chainId][unWrappedToken];
214
+ }
215
+
216
+ export const erc20WrapperTokens: {
217
+ [id in ChainId]: Set<Address>;
218
+ } = {
219
+ [ChainId.EthMainnet]: new Set([
220
+ addresses[ChainId.EthMainnet].wbIB01,
221
+ addresses[ChainId.EthMainnet].wbC3M,
222
+ ]),
223
+ [ChainId.EthGoerliTestnet]: new Set(),
224
+ [ChainId.BaseMainnet]: new Set(),
225
+ };
226
+
227
+ export const wrappedBackedTokens: {
228
+ [id in ChainId]: Set<Address>;
229
+ } = {
230
+ [ChainId.EthMainnet]: new Set([
231
+ addresses[ChainId.EthMainnet].wbIB01,
232
+ addresses[ChainId.EthMainnet].wbC3M,
233
+ ]),
234
+ [ChainId.EthGoerliTestnet]: new Set(),
235
+ [ChainId.BaseMainnet]: new Set(),
236
+ };
237
+
238
+ export const getWrappedBackedTokens = (chainId: number) => {
239
+ const tokens = wrappedBackedTokens[chainId as ChainId];
240
+
241
+ if (!tokens) throw new UnsupportedChainIdError(chainId);
242
+
243
+ return tokens;
244
+ };
245
+
246
+ /** /!\ These tokens can not be listed in `erc20WrapperTokens` because the following specs are different:
247
+ * - calling `depositFor` supplies on blue instead of minting wrapped token to the user
248
+ */
249
+ export const convexWrapperTokens: {
250
+ [id in ChainId]: Set<Address>;
251
+ } = {
252
+ [ChainId.EthMainnet]: new Set([
253
+ addresses[ChainId.EthMainnet]["stkcvxcrvUSDTWBTCWETH-morpho"],
254
+ addresses[ChainId.EthMainnet]["stkcvxcrvUSDCWBTCWETH-morpho"],
255
+ addresses[ChainId.EthMainnet]["stkcvxcrvCRVUSDTBTCWSTETH-morpho"],
256
+ addresses[ChainId.EthMainnet]["stkcvxTryLSD-morpho"],
257
+ addresses[ChainId.EthMainnet]["stkcvxcrvUSDETHCRV-morpho"],
258
+ ]),
259
+ [ChainId.EthGoerliTestnet]: new Set(),
260
+ [ChainId.BaseMainnet]: new Set(),
261
+ };
@@ -0,0 +1,235 @@
1
+ import { ChainMetadata, ChainId } from "./chain.types";
2
+
3
+ export const BLUE_AVAILABLE_CHAINS = [ChainId.EthMainnet, ChainId.BaseMainnet];
4
+
5
+ export const CHAIN_METADATA: Record<ChainId, ChainMetadata> = {
6
+ [ChainId.EthMainnet]: {
7
+ name: "Ethereum",
8
+ id: ChainId.EthMainnet,
9
+ nativeCurrency: { name: "Ether", symbol: "ETH", decimals: 18 },
10
+ defaultRpcUrl:
11
+ "https://mainnet.infura.io/V3/84842078b09946638c03157f83405213",
12
+ explorerUrl: "https://etherscan.io",
13
+ isTestnet: false,
14
+ shortName: "ETH",
15
+ logoSrc: "https://cdn.morpho.org/assets/chains/eth.svg",
16
+ identifier: "mainnet",
17
+ },
18
+ [ChainId.EthGoerliTestnet]: {
19
+ name: "Ethereum Goerli Testnet",
20
+ id: ChainId.EthGoerliTestnet,
21
+ nativeCurrency: { name: "Goerli Ether", symbol: "ETH", decimals: 18 },
22
+ defaultRpcUrl:
23
+ "https://goerli.infura.io/V3/84842078b09946638c03157f83405213",
24
+ explorerUrl: "https://goerli.etherscan.io",
25
+ isTestnet: true,
26
+ shortName: "Goerli",
27
+ logoSrc: "https://cdn.morpho.org/assets/chains/eth.svg",
28
+ identifier: "goerli",
29
+ },
30
+ [ChainId.BaseMainnet]: {
31
+ name: "Base",
32
+ id: ChainId.BaseMainnet,
33
+ nativeCurrency: { name: "Ether", symbol: "ETH", decimals: 18 },
34
+ defaultRpcUrl: "https://rpc.baseprotocol.org",
35
+ explorerUrl: "https://basescan.org",
36
+ isTestnet: false,
37
+ shortName: "Base",
38
+ logoSrc: "https://cdn.morpho.org/assets/chains/base.png",
39
+ identifier: "base",
40
+ },
41
+ // [ChainId.PolygonMainnet]: {
42
+ // name: "Polygon Mainnet",
43
+ // id: ChainId.PolygonMainnet,
44
+ // nativeCurrency: { name: "MATIC", symbol: "MATIC", decimals: 18n },
45
+ // defaultRpcUrl: "https://rpc-mainnet.maticvigil.com",
46
+ // explorerUrl: "https://polygonscan.com",
47
+ // isTestnet: false,
48
+ // shortName: "Polygon",
49
+ // },
50
+ // [ChainId.MumbaiTestnet]: {
51
+ // name: "Mumbai Testnet",
52
+ // id: ChainId.MumbaiTestnet,
53
+ // nativeCurrency: { name: "MATIC", symbol: "MATIC", decimals: 18n },
54
+ // defaultRpcUrl: "https://rpc-mumbai.maticvigil.com",
55
+ // explorerUrl: "https://mumbai.polygonscan.com",
56
+ // isTestnet: true,
57
+ // shortName: "Mumbai",
58
+ // },
59
+
60
+ /* see https://chainid.network/chains.json */
61
+
62
+ // [ChainId.PolygonMainnet]: {
63
+ // name: "Polygon Mainnet",
64
+ // id: ChainId.PolygonMainnet,
65
+ // nativeCurrency: { name: "MATIC", symbol: "MATIC", decimals: 18n },
66
+ // defaultRpcUrl: "https://rpc-mainnet.maticvigil.com",
67
+ // explorerUrl: "https://polygonscan.com",
68
+ // isTestnet: false,
69
+ // shortName: "Polygon",
70
+ // },
71
+ // [ChainId.MumbaiTestnet]: {
72
+ // name: "Mumbai Testnet",
73
+ // id: ChainId.MumbaiTestnet,
74
+ // nativeCurrency: { name: "MATIC", symbol: "MATIC", decimals: 18n },
75
+ // defaultRpcUrl: "https://rpc-mumbai.maticvigil.com",
76
+ // explorerUrl: "https://mumbai.polygonscan.com",
77
+ // isTestnet: true,
78
+ // shortName: "Mumbai",
79
+ // },
80
+ // [ChainId.OptimismMainnet]: {
81
+ // name: "Optimism Mainnet",
82
+ // id: ChainId.OptimismMainnet,
83
+ // baseCurrency: "ETH",
84
+ // defaultRpcUrl: "https://mainnet.optimism.io",
85
+ // explorerUrl: "https://optimistic.etherscan.io",
86
+ // isTestnet: false,
87
+ // },
88
+ // [ChainId.BscMainnet]: {
89
+ // name: "Binance Smart Chain Mainnet",
90
+ // id: ChainId.BscMainnet,
91
+ // baseCurrency: "BNB",
92
+ // defaultRpcUrl: "https://bsc-dataseed.binance.org",
93
+ // explorerUrl: "https://bscscan.com",
94
+ // isTestnet: false,
95
+ // },
96
+ // [ChainId.ArbitrumMainnet]: {
97
+ // name: "Arbitrum Mainnet",
98
+ // id: ChainId.ArbitrumMainnet,
99
+ // baseCurrency: "ETH",
100
+ // defaultRpcUrl: "https://arb1.arbitrum.io/rpc",
101
+ // explorerUrl: "https://arbiscan.io",
102
+ // isTestnet: false,
103
+ // },
104
+ // [ChainId.ArbitrumTestnet]: {
105
+ // name: "Arbitrum Testnet",
106
+ // id: ChainId.ArbitrumTestnet,
107
+ // baseCurrency: "ETH",
108
+ // defaultRpcUrl: "https://rinkeby.arbitrum.io/rpc",
109
+ // explorerUrl: "https://rinkeby-explorer.arbitrum.io",
110
+ // isTestnet: true,
111
+ // },
112
+ // [ChainId.GnosisChain]: {
113
+ // name: "Gnosis Chain",
114
+ // id: ChainId.GnosisChain,
115
+ // baseCurrency: "XDAI",
116
+ // defaultRpcUrl: "https://rpc.xdaichain.com",
117
+ // explorerUrl: "https://gnosis.blockscout.com",
118
+ // isTestnet: false,
119
+ // },
120
+ // [ChainId.FantomMainnet]: {
121
+ // name: "Fantom Mainnet",
122
+ // id: ChainId.FantomMainnet,
123
+ // baseCurrency: "FTM",
124
+ // defaultRpcUrl: "https://rpcapi.fantom.network",
125
+ // explorerUrl: "https://ftmscan.com",
126
+ // isTestnet: false,
127
+ // },
128
+ // [ChainId.FantomTestnet]: {
129
+ // name: "Fantom Testnet",
130
+ // id: ChainId.FantomTestnet,
131
+ // baseCurrency: "FTM",
132
+ // defaultRpcUrl: "https://rpc.testnet.fantom.network",
133
+ // explorerUrl: "https://explorer.testnet.fantom.network",
134
+ // isTestnet: true,
135
+ // },
136
+ // [ChainId.HarmonyMainnet]: {
137
+ // name: "Harmony Mainnet",
138
+ // id: ChainId.HarmonyMainnet,
139
+ // baseCurrency: "ONE",
140
+ // defaultRpcUrl: "https://api.harmony.one",
141
+ // explorerUrl: "https://explorer.harmony.one",
142
+ // isTestnet: false,
143
+ // },
144
+ // [ChainId.HarmonyTestnet]: {
145
+ // name: "Harmony Testnet",
146
+ // id: ChainId.HarmonyTestnet,
147
+ // baseCurrency: "ONE",
148
+ // defaultRpcUrl: "https://api.s0.b.hmny.io",
149
+ // explorerUrl: "https://explorer.testnet.harmony.one",
150
+ // isTestnet: true,
151
+ // },
152
+ // [ChainId.BscTestnet]: {
153
+ // name: "Binance Smart Chain Testnet",
154
+ // id: ChainId.BscTestnet,
155
+ // baseCurrency: "BNB",
156
+ // defaultRpcUrl: "https://data-seed-prebsc-1-s1.binance.org:8545",
157
+ // explorerUrl: "https://testnet.bscscan.com",
158
+ // isTestnet: true,
159
+ // },
160
+ // [ChainId.OptimismTestnet]: {
161
+ // name: "Optimism Testnet",
162
+ // id: ChainId.OptimismTestnet,
163
+ // baseCurrency: "ETH",
164
+ // defaultRpcUrl: "https://kovan.optimism.io",
165
+ // explorerUrl: "https://kovan-optimistic.etherscan.io",
166
+ // isTestnet: true,
167
+ // },
168
+ // [ChainId.EthRopstenTestnet]: {
169
+ // name: "Ethereum Ropsten Testnet",
170
+ // id: ChainId.EthRopstenTestnet,
171
+ // baseCurrency: "ETH",
172
+ // defaultRpcUrl:
173
+ // "https://ropsten.infura.io/V4/84842078b09946638c03157f83405213",
174
+ // explorerUrl: "https://ropsten.etherscan.io",
175
+ // isTestnet: true,
176
+ // },
177
+ // [ChainId.EthRinkebyTestnet]: {
178
+ // name: "Ethereum Rinkeby Testnet",
179
+ // id: ChainId.EthRinkebyTestnet,
180
+ // baseCurrency: "ETH",
181
+ // defaultRpcUrl:
182
+ // "https://rinkeby.infura.io/V4/84842078b09946638c03157f83405213",
183
+ // explorerUrl: "https://rinkeby.etherscan.io",
184
+ // isTestnet: true,
185
+ // },
186
+ // [ChainId.EthKovanTestnet]: {
187
+ // name: "Ethereum Kovan Testnet",
188
+ // id: ChainId.EthKovanTestnet,
189
+ // baseCurrency: "ETH",
190
+ // defaultRpcUrl:
191
+ // "https://kovan.infura.io/V4/84842078b09946638c03157f83405213",
192
+ // explorerUrl: "https://kovan.etherscan.io",
193
+ // isTestnet: true,
194
+ // },
195
+ // [ChainId.BaseGoerliTestnet]: {
196
+ // name: "Base Goerli Testnet",
197
+ // id: ChainId.BaseGoerliTestnet,
198
+ // baseCurrency: "ETH",
199
+ // defaultRpcUrl: "https://rpc-goerli.baseprotocol.org",
200
+ // explorerUrl: "https://goerli.basescan.org",
201
+ // isTestnet: true,
202
+ // },
203
+ // [ChainId.GnosisChainTestnet]: {
204
+ // name: "Gnosis Chain Testnet",
205
+ // id: ChainId.GnosisChainTestnet,
206
+ // baseCurrency: "XDAI",
207
+ // defaultRpcUrl: "https://rpc.chiado.gnosis.gateway.fm",
208
+ // explorerUrl: "https://gnosis-chiado.blockscout.com/",
209
+ // isTestnet: true,
210
+ // },
211
+ // [ChainId.AvalancheMainnet]: {
212
+ // name: "Avalanche Mainnet",
213
+ // id: ChainId.AvalancheMainnet,
214
+ // baseCurrency: "AVAX",
215
+ // defaultRpcUrl: "https://api.avax.network/ext/bc/C/rpc",
216
+ // explorerUrl: "https://cchain.explorer.avax.network",
217
+ // isTestnet: false,
218
+ // },
219
+ // [ChainId.AvalancheFujiTestnet]: {
220
+ // name: "Avalanche Fuji Testnet",
221
+ // id: ChainId.AvalancheFujiTestnet,
222
+ // baseCurrency: "AVAX",
223
+ // defaultRpcUrl: "https://api.avax-test.network/ext/bc/C/rpc",
224
+ // explorerUrl: "https://cchain.explorer.avax-test.network",
225
+ // isTestnet: true,
226
+ // },
227
+ // [ChainId.MoonbaseAlphaTestnet]: {
228
+ // name: "Moonbase Alpha Testnet",
229
+ // id: ChainId.MoonbaseAlphaTestnet,
230
+ // baseCurrency: "DEV",
231
+ // defaultRpcUrl: "https://rpc.testnet.moonbeam.network",
232
+ // explorerUrl: "https://moonbase-blockscout.testnet.moonbeam.network",
233
+ // isTestnet: true,
234
+ // },
235
+ };
@@ -0,0 +1,51 @@
1
+ import { entries, keys, values } from "@morpho-org/morpho-ts";
2
+
3
+ import { ChainId } from "./chain.types";
4
+ import { ChainUtils } from "./chain.utils";
5
+
6
+ describe("Network", () => {
7
+ it("Should have all data for all networks", () => {
8
+ const chainIdLength = ChainUtils.getAllChainIds().length;
9
+ const chainMetadataLength = keys(ChainUtils.chainMetadata).length;
10
+
11
+ expect(chainIdLength).toEqual(chainMetadataLength);
12
+ });
13
+
14
+ it("Should have consistent chainIds", () => {
15
+ entries(ChainUtils.chainMetadata).forEach(([chainId, { id }]) => {
16
+ expect(+chainId).toEqual(id);
17
+ });
18
+ });
19
+
20
+ it("Should have Testnet in the name for testnet chains", () => {
21
+ Object.values(ChainUtils.chainMetadata)
22
+ .filter(({ isTestnet }) => isTestnet)
23
+ .forEach(({ name }) => {
24
+ expect(name).toMatch(/Testnet/);
25
+ });
26
+ });
27
+ it("Should convert correctly a chainId to hexChainId", () => {
28
+ expect(
29
+ ChainUtils.toHexChainId(ChainUtils.ChainId.EthGoerliTestnet)
30
+ ).toEqual("0x5");
31
+ expect(ChainUtils.toHexChainId(ChainUtils.ChainId.BaseMainnet)).toEqual(
32
+ "0x2105"
33
+ );
34
+ });
35
+
36
+ it("Should return all testnets", () => {
37
+ expect(ChainUtils.getTestnets()).toEqual(
38
+ values(ChainUtils.chainMetadata)
39
+ .filter(({ isTestnet }) => isTestnet)
40
+ .map(({ id }) => id)
41
+ );
42
+ });
43
+ it("Should return all networks", () => {
44
+ expect(ChainUtils.getAllChainIds()).toEqual(
45
+ values(ChainUtils.chainMetadata).map(({ id }) => id)
46
+ );
47
+ expect(
48
+ ChainUtils.getAllChainLabels().map((label) => ChainId[label])
49
+ ).toEqual(ChainUtils.getAllChainIds());
50
+ });
51
+ });
@@ -0,0 +1,42 @@
1
+ export enum ChainId {
2
+ EthMainnet = 1,
3
+ EthGoerliTestnet = 5,
4
+ BaseMainnet = 8453,
5
+ // PolygonMainnet = 137,
6
+ // MumbaiTestnet = 80001,
7
+ // OptimismMainnet = 10,
8
+ // BscMainnet = 56,
9
+ // ArbitrumMainnet = 42161,
10
+ // ArbitrumTestnet = 421611,
11
+ // GnosisChain = 100,
12
+ // FantomMainnet = 250,
13
+ // FantomTestnet = 4002,
14
+ // HarmonyMainnet = 128,
15
+ // HarmonyTestnet = 1666600000,
16
+ // BscTestnet = 97,
17
+ // OptimismTestnet = 69,
18
+ // EthRopstenTestnet = 3,
19
+ // EthRinkebyTestnet = 4,
20
+ // EthKovanTestnet = 42,
21
+ // GnosisChainTestnet = 10200,
22
+ // AvalancheMainnet = 43114,
23
+ // AvalancheFujiTestnet = 43113,
24
+ // MoonbaseAlphaTestnet = 1287,
25
+ // BaseGoerliTestnet = 84531,
26
+ }
27
+
28
+ export interface ChainMetadata {
29
+ readonly name: string;
30
+ readonly id: ChainId;
31
+ readonly defaultRpcUrl: string;
32
+ readonly explorerUrl: string;
33
+ readonly nativeCurrency: {
34
+ readonly name: string;
35
+ readonly symbol: string;
36
+ readonly decimals: number;
37
+ };
38
+ readonly isTestnet: boolean;
39
+ readonly shortName: string;
40
+ readonly identifier: string;
41
+ readonly logoSrc: string;
42
+ }
@@ -0,0 +1,44 @@
1
+ import { values } from "@morpho-org/morpho-ts";
2
+
3
+ import { UnsupportedChainIdError } from "../errors";
4
+
5
+ import { BLUE_AVAILABLE_CHAINS, CHAIN_METADATA } from "./chain.constants";
6
+ import {
7
+ ChainId as _ChainId,
8
+ ChainMetadata as _ChainMetadata,
9
+ } from "./chain.types";
10
+
11
+ export namespace ChainUtils {
12
+ export const blueAvailableChains = BLUE_AVAILABLE_CHAINS;
13
+ export const chainMetadata = CHAIN_METADATA;
14
+
15
+ export interface ChainMetadata extends _ChainMetadata {}
16
+ export import ChainId = _ChainId;
17
+
18
+ export const toHexChainId = (chainId: ChainId) => {
19
+ return `0x${chainId.toString(16)}`;
20
+ };
21
+
22
+ export const getAllChainIds = () =>
23
+ values(ChainId).filter((value) => typeof value === "number");
24
+
25
+ export const getAllChainLabels = () =>
26
+ Object.values(ChainId).filter(
27
+ (value) => typeof value === "string"
28
+ ) as (keyof typeof ChainId)[];
29
+
30
+ export const getTestnets = () =>
31
+ getAllChainIds().filter((chainId) => CHAIN_METADATA[chainId].isTestnet);
32
+
33
+ export function isSupported(chainId: number): chainId is ChainId {
34
+ return blueAvailableChains.includes(chainId as ChainId);
35
+ }
36
+
37
+ export function parseSupportedChainId(candidate: any): ChainId {
38
+ const chainId = parseInt(candidate);
39
+
40
+ if (!isSupported(chainId)) throw new UnsupportedChainIdError(candidate);
41
+
42
+ return chainId;
43
+ }
44
+ }