@aurigami/sdk 1.24.0 → 1.24.1

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 (41) hide show
  1. package/dist/helpers/priceFetcher.js +9 -13
  2. package/package.json +2 -14
  3. package/src/SDK.ts +0 -223
  4. package/src/abis/index.ts +0 -38
  5. package/src/consts/constants.ts +0 -210
  6. package/src/consts/decimals.ts +0 -31
  7. package/src/consts/deployments.ts +0 -4
  8. package/src/consts/dummy.ts +0 -51
  9. package/src/consts/index.ts +0 -5
  10. package/src/consts/symbols.ts +0 -9
  11. package/src/entities/BlockchainEntity.ts +0 -29
  12. package/src/entities/auriEnv.ts +0 -180
  13. package/src/entities/index.ts +0 -4
  14. package/src/entities/token.ts +0 -21
  15. package/src/entities/tokenAmount.ts +0 -48
  16. package/src/helpers/aurigami-api.ts +0 -42
  17. package/src/helpers/aurora-api-helpers.ts +0 -17
  18. package/src/helpers/graphql-helpers.ts +0 -8
  19. package/src/helpers/helpers.ts +0 -212
  20. package/src/helpers/historicalPriceFetcher.ts +0 -200
  21. package/src/helpers/index.ts +0 -7
  22. package/src/helpers/kyber-aggregator-api.ts +0 -37
  23. package/src/helpers/multicall.ts +0 -251
  24. package/src/helpers/notification-api.ts +0 -22
  25. package/src/helpers/one-inch-aggregator-api.ts +0 -45
  26. package/src/helpers/priceFetcher.ts +0 -388
  27. package/src/helpers/subgraphQuery.ts +0 -17
  28. package/src/helpers/transfer-event-query.ts +0 -68
  29. package/src/index.ts +0 -14
  30. package/src/interactors/Airdrop.ts +0 -72
  31. package/src/interactors/MoneyMarket.ts +0 -486
  32. package/src/interactors/Multicall.ts +0 -50
  33. package/src/interactors/Papermill.ts +0 -185
  34. package/src/interactors/PlyGame.ts +0 -172
  35. package/src/interactors/PlyTokenLock.ts +0 -46
  36. package/src/interactors/Pulp.ts +0 -41
  37. package/src/interactors/Referral.ts +0 -214
  38. package/src/interactors/Staking.ts +0 -156
  39. package/src/interactors/index.ts +0 -9
  40. package/src/interactors/misc.ts +0 -433
  41. package/src/types/index.ts +0 -252
@@ -1,388 +0,0 @@
1
- import AuriLensABI from '@aurigami/contracts/artifacts/contracts/AuriLens.sol/AuriLens.json';
2
- import { AuriPythOracle, ERC20, IUniswapV2Pair } from '@aurigami/contracts/typechain';
3
- import axios from 'axios';
4
- import BigNumber from 'bignumber.js';
5
- import { BigNumber as BN, ethers, providers } from 'ethers';
6
- import { AuriOracleABI, EIP20InterfaceABI, IUniswapV2PairABI } from '../abis';
7
- import {
8
- DECIMAL_PRECISION,
9
- HARDCODE_PRICE_TOKENS,
10
- PRICE_WHITELISTED,
11
- STADER_ETH,
12
- USDT_ETH,
13
- networkAddresses,
14
- } from '../consts/constants';
15
- import { TokenAmount } from '../entities/tokenAmount';
16
- import { Address, TokenValuation } from '../types';
17
- import { assert, decimalFactor, devLog, getDecimal, isSameAddress } from './helpers';
18
- import { getSwapInfo } from './kyber-aggregator-api';
19
- import { createContract } from './multicall';
20
- import { getQuoteOneInch } from './one-inch-aggregator-api';
21
-
22
- export async function prepareParamsAggregator(address: string, provider: providers.Provider) {
23
- const tokenInErc20 = createContract<ERC20>(address, EIP20InterfaceABI.abi, provider);
24
- const tokenInDecimal = await tokenInErc20.callStatic.decimals();
25
- const tokenInQuantity = BN.from(10).pow(tokenInDecimal).toString();
26
- const usdtAddress =
27
- networkAddresses.auTokens.find((autoken) => autoken.name == 'auUSDT')?.underlying ?? '';
28
- const usdtDecimal = getDecimal(usdtAddress);
29
- return {
30
- tokenInQuantity,
31
- usdtAddress,
32
- usdtDecimal,
33
- };
34
- }
35
-
36
- export async function fetchPriceFromOneInch(address: string, provider: providers.Provider) {
37
- const { tokenInQuantity, usdtAddress, usdtDecimal } = await prepareParamsAggregator(
38
- address,
39
- provider
40
- );
41
- const info = await getQuoteOneInch(address, usdtAddress, tokenInQuantity);
42
- const outputAmount = info.toTokenAmount;
43
- return new BigNumber(outputAmount).dividedBy(10 ** usdtDecimal);
44
- }
45
-
46
- export async function fetchPriceFromKyberSwap(
47
- address: string,
48
- provider: providers.Provider,
49
- onAurora = true
50
- ): Promise<BigNumber> {
51
- if (address == networkAddresses.tokens.STADER) {
52
- const ETH_PROVIDER = new ethers.providers.JsonRpcProvider('https://rpc.ankr.com/eth');
53
-
54
- return fetchPriceFromKyberSwap(STADER_ETH, ETH_PROVIDER, false);
55
- }
56
- let { tokenInQuantity, usdtAddress, usdtDecimal } = await prepareParamsAggregator(
57
- address,
58
- provider
59
- );
60
- if (!onAurora) {
61
- usdtAddress = USDT_ETH;
62
- }
63
- const info = await getSwapInfo(address, usdtAddress, tokenInQuantity, onAurora);
64
- const outputAmount = info.outputAmount;
65
- return new BigNumber(outputAmount).dividedBy(10 ** usdtDecimal);
66
- }
67
-
68
- export async function fetchPriceFromDefiLlamaAPI(id: string): Promise<BigNumber> {
69
- const price = await axios
70
- .get(`https://coins.llama.fi/prices/current/${id}`)
71
- .then((res: any) => {
72
- return res.data.coins[id].price;
73
- })
74
- .catch((err: any) => {
75
- console.log(`unable to fetch price from DefiLlama API: ${err}`);
76
- console.error(err);
77
- return 0;
78
- });
79
- return new BigNumber(price);
80
- }
81
-
82
- export async function fetchPriceFromCoingeckoAPI(id: string): Promise<BigNumber> {
83
- const price = await axios
84
- .get(`https://api.coingecko.com/api/v3/simple/price?ids=${id}&vs_currencies=usd`)
85
- .then((res: any) => {
86
- return res.data[id];
87
- })
88
- .catch((err: any) => {
89
- console.log(`Unable to fetch price from Coingecko API for ${id}`);
90
- console.error(err);
91
- return { usd: 0 };
92
- });
93
-
94
- return new BigNumber(price.usd);
95
- }
96
-
97
- export async function fetchPriceFromDefiLlamaAndCoingecko(id: Address): Promise<BigNumber> {
98
- if (
99
- id.toLowerCase() == networkAddresses.tokens.AURORA ||
100
- id.toLowerCase() == networkAddresses.tokens.TRI ||
101
- id.toLowerCase() == networkAddresses.tokens.META
102
- ) {
103
- return fetchPriceFromDefiLlamaAPI(`aurora:${id.toLowerCase()}`).catch((e) =>
104
- fetchPriceFromCoingecko(id)
105
- );
106
- } else if (id.toLowerCase() == networkAddresses.tokens.STADER) {
107
- return fetchPriceFromCoingecko(id);
108
- }
109
- throw Error(`Unknown token ${id} in fetchPriceFromDefiLlama`);
110
- }
111
-
112
- export async function fetchPriceFromCoingecko(id: Address): Promise<BigNumber> {
113
- switch (id.toLowerCase()) {
114
- case networkAddresses.tokens.AURORA:
115
- return fetchPriceFromCoingeckoAPI('aurora-near');
116
-
117
- case networkAddresses.tokens.TRI:
118
- return fetchPriceFromCoingeckoAPI('trisolaris');
119
-
120
- case networkAddresses.tokens.META:
121
- return fetchPriceFromCoingeckoAPI('meta-pool');
122
-
123
- case networkAddresses.tokens.STADER:
124
- return fetchPriceFromCoingeckoAPI('stader');
125
-
126
- default:
127
- throw Error(`Unknown token ${id} in fetchPriceFromCoingecko`);
128
- }
129
- }
130
-
131
- export async function fetchLPPositions(
132
- LPAddress: Address,
133
- provider: providers.Provider
134
- ): Promise<{
135
- token0: Address;
136
- token1: Address;
137
- reserve0: BN;
138
- reserve1: BN;
139
- totalSupply: BN;
140
- }> {
141
- const LPContract = createContract<IUniswapV2Pair>(LPAddress, IUniswapV2PairABI.abi, provider);
142
- const [token0, token1, reserves, totalSupply] = await Promise.all([
143
- LPContract.callStatic.token0(),
144
- LPContract.callStatic.token1(),
145
- LPContract.callStatic.getReserves(),
146
- LPContract.callStatic.totalSupply(),
147
- ]);
148
-
149
- return {
150
- token0: token0,
151
- token1: token1,
152
- reserve0: reserves.reserve0,
153
- reserve1: reserves.reserve1,
154
- totalSupply: totalSupply,
155
- };
156
- }
157
-
158
- export async function fetchLPPrice(
159
- address: Address,
160
- provider: providers.Provider
161
- ): Promise<BigNumber> {
162
- var LPInfo = await fetchLPPositions(address, provider);
163
- const LPDecimal = getDecimal(address);
164
-
165
- async function fetchLPPriceBy(tokenReverse: {
166
- address: string;
167
- reserve: BN;
168
- }): Promise<BigNumber> {
169
- if (tokenReverse.reserve.isZero()) return new BigNumber(0);
170
-
171
- // Should NOT call `fetchPrice`, it will cause an infinite loop
172
- // because the token can be PLY. To calculate PLY price, we need to
173
- // call `fetchPrice` again...
174
- const tokenPrice: BigNumber = await _fetchPrice(tokenReverse.address, provider);
175
- const tokenDecimal = getDecimal(tokenReverse.address);
176
-
177
- // reserveUSD will be divided by 10^tokenDecimal later for more precision
178
- const reserveUSD: BigNumber = tokenPrice
179
- .multipliedBy(tokenReverse.reserve.toString())
180
- .multipliedBy(2);
181
- return reserveUSD
182
- .multipliedBy(decimalFactor(LPDecimal))
183
- .dividedBy(new BigNumber(LPInfo.totalSupply.toString()))
184
- .dividedBy(decimalFactor(tokenDecimal));
185
- }
186
-
187
- try {
188
- // MUST await here
189
- const lpPrice = await fetchLPPriceBy({
190
- address: LPInfo.token0,
191
- reserve: LPInfo.reserve0,
192
- });
193
- if (lpPrice.isZero()) {
194
- throw Error(`Price is zero`);
195
- }
196
- return lpPrice;
197
- } catch (e) {
198
- devLog(`fetchLPPriceBy ${LPInfo.token0} failed`, e);
199
- try {
200
- // MUST await here
201
- return await fetchLPPriceBy({
202
- address: LPInfo.token1,
203
- reserve: LPInfo.reserve1,
204
- });
205
- } catch (e) {
206
- devLog(`fetchLPPriceBy ${LPInfo.token1} failed`, e);
207
- throw Error(`Unable to fetch price for both tokens of LP ${address}`);
208
- }
209
- }
210
- }
211
-
212
- export async function fetchStNEARPrice(): Promise<BigNumber> {
213
- const ratioPromise = axios
214
- .get('https://validators.narwallets.com/metrics_json')
215
- .then((res) => res.data);
216
- const nearPricePromise = fetchPriceFromCoingeckoAPI('near');
217
- const [ratioRes, nearPrice]: [any, BigNumber] = await Promise.all([
218
- ratioPromise,
219
- nearPricePromise,
220
- ]);
221
- const ratio = new BigNumber(ratioRes.st_near_price);
222
- return ratio.multipliedBy(nearPrice);
223
- }
224
-
225
- function processPriceFromOracle(rawPrice: BN, underlyingDecimal: number) {
226
- return new BigNumber(rawPrice.toString()).div(decimalFactor(36 - underlyingDecimal));
227
- }
228
- export async function fetchPriceFromOracle(
229
- auTokenAddress: Address,
230
- underlyingDecimal: number,
231
- provider: providers.Provider
232
- ): Promise<BigNumber> {
233
- const oracleContract = createContract<AuriPythOracle>(
234
- networkAddresses.misc.PYTH_ORACLE,
235
- AuriOracleABI.abi,
236
- provider
237
- );
238
- const rawPrice = await oracleContract.callStatic
239
- .getUnderlyingPrice(auTokenAddress)
240
- .catch((e: any) => {
241
- console.log(`Unable to fetch price from oracle for ${auTokenAddress}`);
242
- return BN.from(0);
243
- });
244
-
245
- // In case of error, probally it is because the underlying token is not supported
246
- // by the backup oracle. In that case, we will fetch from third-party.
247
- if (rawPrice.isZero()) {
248
- const matchingAuToken = networkAddresses.auTokens.find((auToken) => {
249
- return isSameAddress(auToken.address, auTokenAddress);
250
- });
251
- if (matchingAuToken?.name == 'auSTNEAR') {
252
- return fetchStNEARPrice();
253
- }
254
- }
255
-
256
- return processPriceFromOracle(rawPrice, underlyingDecimal);
257
- }
258
-
259
- export async function fetchUnderlyingTokensPrices(provider: providers.Provider): Promise<
260
- {
261
- auToken: string;
262
- underlyingPrice: BigNumber;
263
- }[]
264
- > {
265
- const auriLens = createContract(networkAddresses.misc.AURILENS, AuriLensABI.abi, provider);
266
- const auTokenAddresses = networkAddresses.auTokens.map((auToken) => auToken.address);
267
- const underlyingDecimals = networkAddresses.auTokens.map((auToken) =>
268
- getDecimal(auToken.underlying)
269
- );
270
- const rawPrices = await auriLens.callStatic.auTokenUnderlyingPriceAll(auTokenAddresses);
271
- return rawPrices.map((res: any, ind: number) => {
272
- return {
273
- auToken: res.auToken,
274
- underlyingPrice: processPriceFromOracle(res.underlyingPrice, underlyingDecimals[ind]),
275
- };
276
- });
277
- }
278
-
279
- function shouldFetchFromKyberSwap(address: string) {
280
- address = address.toLowerCase();
281
- return (
282
- address == networkAddresses.tokens.TRI ||
283
- address == networkAddresses.tokens.META ||
284
- address == networkAddresses.tokens.STADER
285
- );
286
- }
287
-
288
- /**
289
- * Fetch price from Oracle or Coingecko
290
- */
291
- async function _fetchPrice(address: Address, provider: providers.Provider): Promise<BigNumber> {
292
- assert(
293
- PRICE_WHITELISTED.has(address.toLocaleLowerCase()),
294
- `Address ${address} is not whitelisted for price fetching`
295
- );
296
- if (address.toLowerCase() == networkAddresses.tokens.META) {
297
- return fetchPriceFromDefiLlamaAndCoingecko(address);
298
- }
299
- if (shouldFetchFromKyberSwap(address)) {
300
- return fetchPriceFromKyberSwap(address, provider).catch((e) => {
301
- return fetchPriceFromDefiLlamaAndCoingecko(address);
302
- });
303
- }
304
- const matchingAuToken = networkAddresses.auTokens.find((auToken) => {
305
- return isSameAddress(auToken.underlying, address);
306
- });
307
-
308
- if (matchingAuToken !== undefined) {
309
- return fetchPriceFromOracle(matchingAuToken.address, getDecimal(address), provider);
310
- } else {
311
- throw Error(`Unable to fetch price for ${address}`);
312
- }
313
- }
314
-
315
- export async function fetchPrice(
316
- address: Address,
317
- provider: providers.Provider
318
- ): Promise<BigNumber> {
319
- if (address.toLowerCase() in HARDCODE_PRICE_TOKENS) {
320
- return new BigNumber(HARDCODE_PRICE_TOKENS[address.toLowerCase()]);
321
- } else if (isSameAddress(address, networkAddresses.tokens.PLYWNEAR)) {
322
- return fetchLPPrice(address, provider);
323
- } else if (isSameAddress(address, networkAddresses.tokens.PLY)) {
324
- return fetchPLYPrice(provider);
325
- } else if (isSameAddress(address, networkAddresses.tokens.PULP)) {
326
- return fetchPULPPrice(provider);
327
- }
328
- return _fetchPrice(address, provider);
329
- }
330
-
331
- export async function fetchPLYPrice(provider: providers.Provider): Promise<BigNumber> {
332
- //TODO: Fetch PLY price from CEX?
333
- return fetchToken0PriceByLP(networkAddresses.tokens.PLYWNEAR, provider);
334
- }
335
-
336
- export async function fetchPULPPrice(provider: providers.Provider): Promise<BigNumber> {
337
- //TODO: Calculate PULP price
338
- return new BigNumber(0);
339
- }
340
-
341
- export async function fetchToken0PriceByLP(
342
- LP: Address,
343
- provider: providers.Provider
344
- ): Promise<BigNumber> {
345
- const LPInfo = await fetchLPPositions(LP, provider);
346
-
347
- if (LPInfo.reserve1.isZero()) {
348
- return new BigNumber(0);
349
- }
350
-
351
- const token0Decimal = getDecimal(LPInfo.token0);
352
- const token1Decimal = getDecimal(LPInfo.token1);
353
-
354
- // (token0Price * reserve0) / 10^decimal0 = (token1Price * reserve1) / 10^decimal1
355
- // token0Price = (token1Price * reserve1) * 10^decimal0 / 10^decimal1 / reserve0
356
- return (await fetchPrice(LPInfo.token1, provider))
357
- .multipliedBy(LPInfo.reserve1.toString())
358
- .multipliedBy(decimalFactor(token0Decimal))
359
- .dividedBy(decimalFactor(token1Decimal))
360
- .dividedBy(LPInfo.reserve0.toString());
361
- }
362
-
363
- export async function fetchValuation(
364
- tokenAmount: TokenAmount,
365
- provider: providers.Provider
366
- ): Promise<BigNumber> {
367
- if (tokenAmount.rawAmount() == '0') return new BigNumber(0);
368
- var price = await fetchPrice(tokenAmount.token.address, provider);
369
- return calcValuation(tokenAmount, price);
370
- }
371
-
372
- export function calcValuation(tokenAmount: TokenAmount, price: BigNumber) {
373
- return new BigNumber(tokenAmount.formattedAmount()).multipliedBy(price);
374
- }
375
-
376
- export async function valuateToken(
377
- tokenAmount: TokenAmount,
378
- provider: providers.Provider
379
- ): Promise<TokenValuation> {
380
- let tokenValuation = await fetchValuation(tokenAmount, provider);
381
- return {
382
- tokenAmount: tokenAmount,
383
- currencyAmount: {
384
- currency: 'USD',
385
- amount: tokenValuation.toFixed(DECIMAL_PRECISION),
386
- },
387
- };
388
- }
@@ -1,17 +0,0 @@
1
- export function getLiquidationEventsQuery(address: string, limit: number) {
2
- return `{
3
- liquidationEvents(
4
- first: ${limit},
5
- where: {from: "${address.toLowerCase()}"}
6
- ) {
7
- amount
8
- auTokenSymbol
9
- blockTime
10
- from
11
- id
12
- underlyingRepayAmountUSD
13
- underlyingSymbol
14
- underlyingRepayAmount
15
- }
16
- }`;
17
- }
@@ -1,68 +0,0 @@
1
- import AuTokenABI from '@aurigami/contracts/artifacts/contracts/AuToken.sol/AuToken.json';
2
- import { AuToken } from '@aurigami/contracts/typechain';
3
- import { BigNumber as BN, Contract } from 'ethers';
4
- import { BlockchainEntityRead } from '../entities/BlockchainEntity';
5
- import { NetworkConnection } from '../types';
6
-
7
- type SimpleTransfer = {
8
- from: string;
9
- to: string;
10
- amount: BN;
11
- blockNumber: number;
12
- };
13
-
14
- export class TransferEventQuery extends BlockchainEntityRead {
15
- auToken: AuToken;
16
-
17
- constructor(tokenAddr: string, networkConnection: NetworkConnection) {
18
- super(networkConnection);
19
- this.auToken = new Contract(
20
- tokenAddr,
21
- AuTokenABI.abi,
22
- this._networkConnection.provider
23
- ) as AuToken;
24
- }
25
-
26
- /**
27
- * query ERC20 transfers from/to an address & auto convert them into SimpleTransfer.
28
- * The result will be sorted by blocknumber.
29
- */
30
- async queryERC20TransfersOf(
31
- address: string,
32
- fromBlock: number,
33
- toBlock: number
34
- ): Promise<SimpleTransfer[]> {
35
- const filters = [
36
- this.auToken.filters.Transfer(address, null),
37
- this.auToken.filters.Transfer(null, address),
38
- ];
39
-
40
- const events = (
41
- await Promise.all(
42
- filters.map((filter) => this.auToken.queryFilter(filter, fromBlock, toBlock))
43
- )
44
- ).flat();
45
-
46
- let results: SimpleTransfer[] = events.map((event) => {
47
- return {
48
- from: event.args![0],
49
- to: event.args![1],
50
- amount: event.args![2],
51
- blockNumber: event.blockNumber,
52
- };
53
- });
54
-
55
- results.sort((a, b) => a.blockNumber - b.blockNumber);
56
-
57
- return results;
58
- }
59
-
60
- /**
61
- * Get the balance of an address at a given block number.
62
- *
63
- * Note that this will return the balance after the block get mined.
64
- */
65
- async queryERC20BalanceAt(address: string, endBlock: number): Promise<BN> {
66
- return this.auToken.balanceOf(address, { blockTag: endBlock + 1 });
67
- }
68
- }
package/src/index.ts DELETED
@@ -1,14 +0,0 @@
1
- import BigNumber from 'bignumber.js';
2
- import { ethers } from 'ethers';
3
- import { Logger } from 'ethers/lib/utils';
4
-
5
- ethers.utils.Logger.setLogLevel(Logger.levels.ERROR);
6
- BigNumber.config({ DECIMAL_PLACES: 50 });
7
-
8
- export * as abis from './abis';
9
- export * from './consts';
10
- export * from './entities';
11
- export * from './helpers';
12
- export * from './interactors';
13
- export * from './SDK';
14
- export * from './types';
@@ -1,72 +0,0 @@
1
- import { TransactionResponse } from '@ethersproject/abstract-provider';
2
- import { BigNumber as BN, utils } from 'ethers';
3
- import { AuriEnv, BlockchainEntity, BlockchainEntityRead, Token, TokenAmount } from '../entities';
4
- import * as helpers from '../helpers';
5
- import { Address, NetworkConnection } from '../types';
6
-
7
- export class AirdropRead extends BlockchainEntityRead {
8
- public readonly env: AuriEnv;
9
-
10
- public constructor(networkConnection: NetworkConnection) {
11
- super(networkConnection);
12
- this.env = new AuriEnv(networkConnection);
13
- }
14
-
15
- /**
16
- * Get redeemable rewards amount of user
17
- */
18
- public async getRedeemableReward(
19
- campaign: string,
20
- token: Address,
21
- user: Address
22
- ): Promise<TokenAmount> {
23
- let tokenInstance: Token = new Token(token, helpers.getDecimal(token));
24
-
25
- let rewards: BN = await this.env.auriAirdrop.raw.getRedeemableReward(
26
- utils.formatBytes32String(campaign),
27
- token,
28
- user
29
- );
30
-
31
- return new TokenAmount(tokenInstance, rewards.toString());
32
- }
33
- }
34
-
35
- export class AirdropReadWrite extends AirdropRead {
36
- /**
37
- * Transfer rewards from multiple campaigns to msg.sender
38
- */
39
- public async redeemMultiple(
40
- campaigns: string[],
41
- tokens: Address[]
42
- ): Promise<TransactionResponse> {
43
- helpers.assert(
44
- campaigns.length == tokens.length,
45
- 'campaigns and tokens must have the same length'
46
- );
47
- return this.env.auriAirdrop.raw.connect(this._networkConnection.signer!).redeem(
48
- campaigns.map((e) => utils.formatBytes32String(e)),
49
- tokens,
50
- await this._networkConnection.signer!.getAddress()
51
- );
52
- }
53
-
54
- /**
55
- * Redeem reward from a single campaign
56
- */
57
- public async redeemSingle(campaign: string, token: Address): Promise<TransactionResponse> {
58
- return this.redeemMultiple([campaign], [token]);
59
- }
60
- }
61
-
62
- export class Airdrop extends BlockchainEntity {
63
- constructor() {
64
- super();
65
- }
66
- public read(networkConnection: NetworkConnection): AirdropRead {
67
- return new AirdropRead(networkConnection);
68
- }
69
- public readWrite(networkConnection: NetworkConnection): AirdropReadWrite {
70
- return new AirdropReadWrite(networkConnection);
71
- }
72
- }