Adapter

Gravity Bridge - Bridged Assets

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.

Adapter Info

Version

0.1.2

License

MIT

IPFS CID

QmT4AuT9Ks5cQohAQKhBu2BMKz6gaqxNf4Hs6oC6Zc5bRc

CID (source)

QmVzeX6pcY2RuRvgvgUx5yQ5gnoGP2e9B4kBfYBDYH22Pz

Collections

Author

mihal.eth