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.