Sub-Adapters 4
Preview and test each sub adapter.
Gravity Bridge (gravitybridge-ethereum)
Gravity Bridge/osmosis IBC (gravitybridge-osmosis)
Gravity Bridge/cosmoshub IBC (gravitybridge-cosmoshub)
Gravity Bridge/evmos IBC (gravitybridge-evmos)
Adapter Code
Check the entire code written for the Adapter.
Source code
Showing TS source.
1export const name = 'Gravity Bridge - Bridged Assets';
2export const version = '0.1.2';
3export const license = 'MIT';
4
5const GRAVITY_LCD = 'https://api-gravitybridge-ia.cosmosia.notional.ventures';
6
7const ibcAssets = {
8 ugraviton: {
9 coinGecko: 'graviton',
10 },
11 uatom: {
12 coinGecko: 'cosmos',
13 },
14 uosmo: {
15 coinGecko: 'osmosis',
16 },
17 aevmos: {
18 coinGecko: 'evmos',
19 decimals: 18,
20 },
21};
22
23const chains = [
24 {
25 id: 'osmosis',
26 escrow: 'osmo1p9a0t4w5dpv94phumjfks5su2jwdlg59t6tnc0',
27 gravityEscrow: 'gravity1fp9wuhq58pz53wxvv3tnrxkw8m8s6swpf9jvn2',
28 lcd: 'https://lcd.osmosis.zone',
29 },
30 {
31 id: 'cosmoshub',
32 escrow: 'cosmos1zu668p3g4d97gwycvejkutqllug4vpcvqdjtc0',
33 gravityEscrow: 'gravity17nsujlwvwf4xrgawwgxqphdak2anflw54u4h95',
34 lcd: 'https://cosmos-mainnet-rpc.allthatnode.com:1317/',
35 },
36 {
37 id: 'evmos',
38 escrow: 'evmos187dz9zlxc3zrltzx5756tu7zew6yu3v0rsnhe7',
39 gravityEscrow: 'gravity1zl0hq5vcysct05nytm7ptfsd6uyewf0wtg3r2g',
40 lcd: 'https://api-evmos-ia.cosmosia.notional.ventures',
41 },
42];
43
44const ethAssets = [
45 {
46 name: 'USDC',
47 symbol: 'USDC',
48 address: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',
49 stablecoin: true,
50 decimals: 6,
51 },
52 {
53 name: 'USDT',
54 symbol: 'USDT',
55 address: '0xdAC17F958D2ee523a2206206994597C13D831ec7',
56 stablecoin: true,
57 decimals: 6,
58 },
59 {
60 name: 'Wrapped ETH',
61 symbol: 'WETH',
62 address: '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2',
63 coinGecko: 'ethereum',
64 },
65 {
66 name: 'PStake',
67 symbol: 'PSTAKE',
68 address: '0xfB5c6815cA3AC72Ce9F5006869AE67f18bF77006',
69 coinGecko: 'pstake-finance',
70 },
71 {
72 name: 'ATOM',
73 symbol: 'ATOM',
74 address: '0xdaf0b40b961ca51fc914fbabda8e779619576cad',
75 coinGecko: 'cosmos',
76 exported: true,
77 },
78 {
79 name: 'Nym',
80 symbol: 'NYM',
81 address: '0x525a8f6f3ba4752868cde25164382bfbae3990e1',
82 coinGecko: 'nym',
83 exported: true,
84 },
85]
86
87export function setup(sdk: Context) {
88 let cachedSupplies: Promise<any> | null = null;
89
90 const getSupplies = async () => {
91 const supplies: any = {};
92
93 let pagiationKey = null
94 for (let i = 0; i < 20; i += 1) {
95 let url = `${GRAVITY_LCD}/cosmos/bank/v1beta1/supply`
96 if (pagiationKey) {
97 url += `?pagination.key=${pagiationKey}`
98 }
99 const response = await sdk.http.get(url)
100
101 for (const denom of response.supply) {
102 supplies[denom.denom] = denom.amount;
103 }
104
105 pagiationKey = response.pagination.next_key
106 if (!pagiationKey) {
107 break
108 }
109 }
110
111 return supplies;
112 }
113
114 const getBalances = async (lcd: string, address: string) => {
115 let balances: any[] = [];
116
117 let pagiationKey = null
118 for (let i = 0; i < 20; i += 1) {
119 let url = `${lcd}/cosmos/bank/v1beta1/balances/${address}`
120 if (pagiationKey) {
121 url += `?pagination.key=${pagiationKey}`
122 }
123 const response = await sdk.http.get(url)
124
125 balances = [...balances, ...response.balances];
126
127 pagiationKey = response.pagination.next_key
128 if (!pagiationKey) {
129 break
130 }
131 }
132
133 return balances;
134 }
135
136 const getBridgedSupply = (denom: string, decimals = 6) => async (): Promise<number> => {
137 if (!cachedSupplies) {
138 cachedSupplies = getSupplies();
139 }
140 const supplies = await cachedSupplies;
141
142 const decimalMagnitude = decimals ? 10 ** decimals : 1e6;
143 return supplies[denom] / decimalMagnitude;
144 }
145
146 const getBridgedSupplyUSD = async (denom: string, coinGeckoId?: string, decimals?: number) => {
147 const [supply, price] = await Promise.all([
148 getBridgedSupply(denom, decimals)(),
149 coinGeckoId ? sdk.coinGecko.getCurrentPrice(coinGeckoId) : Promise.resolve(1),
150 ]);
151 return supply * price;
152 }
153
154 const getImported = async () => {
155 let imported = 0;
156 for (const token of ethAssets) {
157 if (!token.exported) {
158 const denom = `gravity${token.address}`;
159 const valueBridged = await getBridgedSupplyUSD(denom, token.coinGecko, token.decimals || 18);
160 imported += valueBridged;
161 }
162 }
163 return imported;
164 }
165
166 const getExported = async () => {
167 let exported = 0;
168 for (const token of ethAssets) {
169 if (token.exported) {
170 const [supply, price] = await Promise.all([
171 sdk.ethers.getERC20Contract(token.address).totalSupply(),
172 sdk.coinGecko.getCurrentPrice(token.coinGecko),
173 ]);
174 const supplyDecimal = supply / 1e6;
175 const valueBridged = supplyDecimal * price;
176 exported += valueBridged;
177 }
178 }
179 return exported;
180 }
181
182 const getIBCBridged = async (lcd: string, escrow: string) => {
183 const balances = await getBalances(lcd, escrow);
184
185 let total = 0;
186 for (const balance of balances) {
187 if (balance.denom.indexOf('gravity0x') === 0) {
188 const address = balance.denom.substr(7);
189 for (const token of ethAssets) {
190 if (token.address === address) {
191 const price = token.stablecoin ? 1 : await sdk.coinGecko.getCurrentPrice(token.coinGecko);
192 const amount = balance.amount / (10 ** (token.decimals || 18));
193 const valBridged = amount * price;
194 total += valBridged;
195 break;
196 }
197 }
198 }
199 if (ibcAssets[balance.denom]) {
200 const price = await sdk.coinGecko.getCurrentPrice(ibcAssets[balance.denom].coinGecko);
201 const amount = balance.amount / (10 ** (ibcAssets[balance.denom].decimals || 6));
202 const value = price * amount;
203 total += value;
204 }
205 }
206
207 return total;
208 }
209
210 sdk.registerBundle('gravitybridge', {
211 name: 'Gravity Bridge',
212 icon: sdk.ipfs.getDataURILoader('QmezADpEoBvneUXB9iopsUC4i1JSgW7kuhVF5jDebCsHBw', 'image/svg+xml'),
213 category: 'multisig',
214 });
215
216 sdk.register({
217 id: 'gravitybridge-ethereum',
218 bundle: 'gravitybridge',
219 queries: {
220 currentValueBridgedAToB: getExported,
221 currentValueBridgedBToA: getImported,
222 },
223 metadata: {
224 name: 'Gravity Bridge',
225 icon: sdk.ipfs.getDataURILoader('QmezADpEoBvneUXB9iopsUC4i1JSgW7kuhVF5jDebCsHBw', 'image/svg+xml'),
226
227 chainA: 'gravitybridge',
228 chainB: 'ethereum',
229 category: 'multisig',
230 },
231 });
232
233 for (const chain of chains) {
234 sdk.register({
235 id: `gravitybridge-${chain.id}`,
236 bundle: 'ibc', // Assumes that the IBC bundle will be registered externally
237 queries: {
238 currentValueBridgedAToB: () => getIBCBridged(GRAVITY_LCD, chain.gravityEscrow),
239 currentValueBridgedBToA: () => getIBCBridged(chain.lcd, chain.escrow),
240 },
241 metadata: {
242 name: `Gravity Bridge/${chain.id} IBC`, // TODO change to name
243 icon: sdk.ipfs.getDataURILoader('QmXuNeBVkrfc3zNesdvv9BrWHBsE475uCGcEo3hBgHXLXM', 'image/svg+xml'),
244
245 chainA: 'gravitybridge',
246 chainB: chain.id,
247 category: 'light-client',
248 },
249 });
250 }
251}
252
It's something off?
Report it to the discussion board on Discord, we will take care of it.