@wireio/stake 0.4.0 → 0.4.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.
@@ -0,0 +1,129 @@
1
+ import { BigNumber } from "ethers";
2
+ import { preLaunchReceipt } from "../types";
3
+ import { EthereumContractService } from "../contract";
4
+ import { ReceiptNFTKind } from "../../../types";
5
+
6
+ export class ReceiptClient {
7
+
8
+ private readonly contractService: EthereumContractService;
9
+
10
+ get contract() { return this.contractService.contract; }
11
+
12
+ constructor(contract: EthereumContractService) {
13
+ this.contractService = contract;
14
+ }
15
+
16
+
17
+
18
+ async allReceipts(address: string): Promise<preLaunchReceipt[]> {
19
+ return this.fetchPreLaunchReceipts(address);
20
+ }
21
+
22
+ async stakeReceipts(address: string): Promise<preLaunchReceipt[]> {
23
+ return this.fetchPreLaunchReceipts(address, ReceiptNFTKind.STAKE);
24
+ }
25
+
26
+ async pretokenReceipts(address: string): Promise<preLaunchReceipt[]> {
27
+ return this.fetchPreLaunchReceipts(address, ReceiptNFTKind.PRETOKEN_PURCHASE);
28
+ }
29
+
30
+
31
+
32
+ /**
33
+ *
34
+ * @param address (string) to fetch receipts for
35
+ * @returns preLaunchReceipt[]
36
+ */
37
+ async fetchPreLaunchReceipts(address: string, type?: ReceiptNFTKind): Promise<preLaunchReceipt[]> {
38
+ const receiptContract = this.contract.ReceiptNFT;
39
+
40
+ // first figure out which tokenIds this address owns, from events
41
+ const tokenIds = await this.getOwnedTokenIdsFor(address);
42
+
43
+ const results: preLaunchReceipt[] = [];
44
+
45
+ // next fetch on-chain receipt data just for those ids
46
+ for (const idBN of tokenIds) {
47
+ try {
48
+ const receiptData = await receiptContract.getReceipt(idBN);
49
+
50
+ //skip any receipt not of the requested type
51
+ if(type !== undefined && receiptData.kind !== type) continue;
52
+
53
+ results.push({
54
+ tokenId: idBN.toBigInt(),
55
+ receipt: {
56
+ account: receiptData.account,
57
+ currency: receiptData.currency,
58
+ kind: receiptData.kind,
59
+ indexAtMint: receiptData.indexAtMint.toBigInt(),
60
+ principal: {
61
+ amount: receiptData.principal.toBigInt(),
62
+ decimals: 18,
63
+ symbol: "LiqETH"
64
+ },
65
+ shares: {
66
+ amount: receiptData.shares.toBigInt(),
67
+ decimals: 18,
68
+ symbol: "LiqETH"
69
+ },
70
+ timestamp: new Date(Number(receiptData.timestamp.toString()) * 1000).toLocaleString(),
71
+ }
72
+ });
73
+ } catch (err) {
74
+ // in case of any mismatch or race, just skip this id
75
+ console.warn(`Failed to load receipt for tokenId=${idBN.toString()}`, err);
76
+ continue;
77
+ }
78
+ }
79
+
80
+ return results;
81
+ }
82
+
83
+
84
+
85
+
86
+ private async getOwnedTokenIdsFor(
87
+ owner: string,
88
+ fromBlock = 0,
89
+ toBlock: number | string = "latest"
90
+ ): Promise<BigNumber[]> {
91
+ const receiptContract = this.contract.ReceiptNFT;
92
+
93
+ // Logs where address received tokens
94
+ const toLogs = await receiptContract.queryFilter(
95
+ receiptContract.filters.Transfer(null, owner),
96
+ fromBlock,
97
+ toBlock
98
+ );
99
+
100
+ // Logs where address sent tokens (including burns from owner → 0)
101
+ const fromLogs = await receiptContract.queryFilter(
102
+ receiptContract.filters.Transfer(owner, null),
103
+ fromBlock,
104
+ toBlock
105
+ );
106
+
107
+ const owned = new Set<string>();
108
+
109
+ // Add all received tokenIds
110
+ for (const e of toLogs) {
111
+ const tokenId = e.args?.tokenId;
112
+ if (!tokenId) continue;
113
+ owned.add(tokenId.toString());
114
+ }
115
+
116
+ // Remove all sent tokenIds
117
+ for (const e of fromLogs) {
118
+ const tokenId = e.args?.tokenId;
119
+ if (!tokenId) continue;
120
+ owned.delete(tokenId.toString());
121
+ }
122
+
123
+ // Convert to BigNumbers
124
+ return Array.from(owned).map((id) => BigNumber.from(id));
125
+ }
126
+
127
+
128
+
129
+ }
@@ -1,5 +1,5 @@
1
1
  import { BigNumber, ethers } from "ethers";
2
- import { preLaunchReceipt, StakedEvent, WithdrawnStakeEvent, WithdrawnStakeResult } from "../types";
2
+ import { StakedEvent, WithdrawnStakeEvent, WithdrawnStakeResult } from "../types";
3
3
  import { EthereumContractService } from "../contract";
4
4
  import { formatContractErrors } from "../utils";
5
5
 
@@ -28,62 +28,6 @@ export class StakeClient {
28
28
  }
29
29
 
30
30
 
31
- /**
32
- * Read OPP / Outpost state used by the Depositor to decide whether staking is allowed.
33
- * Returns various data
34
- */
35
- async getOppStatus(): Promise<any> {
36
- const depositor = this.contract.Depositor;
37
- const opp = this.contract.OPP;
38
-
39
-
40
- const oppAddress: string = await depositor.oppAddress();
41
- const oppInboundAddress: string = await depositor.oppInboundAddress();
42
- const prevEpochSent = await opp.prevEpochSent();
43
-
44
-
45
- const inbound = this.contractService.getReadOnly('OPPInbound');
46
-
47
- // Query useful getters
48
- const nextEpochBN: any = await inbound.nextEpochNum();
49
- const pendingEpochRaw: any = await inbound.pendingEpoch();
50
- const pendingMessageCount: any = await inbound.pendingMessageCount();
51
- const previousEpochHash: string = await inbound.previousEpochHash();
52
- const nextEpochNum = (nextEpochBN && typeof nextEpochBN.toNumber === 'function') ? nextEpochBN.toNumber() : Number(nextEpochBN || 0);
53
-
54
- const pendingEpoch = (pendingEpochRaw && pendingEpochRaw.epochNumber !== undefined)
55
- ? {
56
- epochNumber: (pendingEpochRaw.epochNumber && typeof pendingEpochRaw.epochNumber.toNumber === 'function') ? pendingEpochRaw.epochNumber.toNumber() : Number(pendingEpochRaw.epochNumber || 0),
57
- timestamp: (pendingEpochRaw.timestamp && typeof pendingEpochRaw.timestamp.toNumber === 'function') ? pendingEpochRaw.timestamp.toNumber() : Number(pendingEpochRaw.timestamp || 0),
58
- prevEpochHash: pendingEpochRaw.prevEpochHash,
59
- merkleRoot: pendingEpochRaw.merkleRoot,
60
- firstMessageID: pendingEpochRaw.firstMessageID,
61
- lastMessageID: pendingEpochRaw.lastMessageID,
62
- }
63
- : null;
64
-
65
- const pendingMessagesBN = pendingMessageCount;
66
- const pendingMessages = (pendingMessagesBN && typeof pendingMessagesBN.toString === 'function') ? pendingMessagesBN.toString() : String(pendingMessagesBN || '0');
67
-
68
- const hasPendingMessages = (pendingMessagesBN && typeof pendingMessagesBN.gt === 'function') ? pendingMessagesBN.gt(0) : (Number(pendingMessages) > 0);
69
-
70
- return {
71
- oppAddress,
72
- prevEpochSent,
73
- oppInboundAddress,
74
- nextEpochNum,
75
- pendingEpoch,
76
- pendingMessageCount: pendingMessages,
77
- previousEpochHash,
78
- hasPendingMessages,
79
- raw: {
80
- nextEpochBN,
81
- pendingEpochRaw,
82
- pendingMessageCount: pendingMessagesBN,
83
- },
84
- };
85
- }
86
-
87
31
 
88
32
  /**
89
33
  *
@@ -153,97 +97,6 @@ export class StakeClient {
153
97
 
154
98
 
155
99
 
156
- async getOwnedTokenIdsFor(
157
- owner: string,
158
- fromBlock = 1850820,
159
- toBlock: number | string = "latest"
160
- ): Promise<BigNumber[]> {
161
- const receiptContract = this.contract.ReceiptNFT;
162
-
163
- // Logs where address received tokens
164
- const toLogs = await receiptContract.queryFilter(
165
- receiptContract.filters.Transfer(null, owner),
166
- fromBlock,
167
- toBlock
168
- );
169
-
170
- // Logs where address sent tokens (including burns from owner → 0)
171
- const fromLogs = await receiptContract.queryFilter(
172
- receiptContract.filters.Transfer(owner, null),
173
- fromBlock,
174
- toBlock
175
- );
176
-
177
- const owned = new Set<string>();
178
-
179
- // Add all received tokenIds
180
- for (const e of toLogs) {
181
- const tokenId = e.args?.tokenId;
182
- if (!tokenId) continue;
183
- owned.add(tokenId.toString());
184
- }
185
-
186
- // Remove all sent tokenIds
187
- for (const e of fromLogs) {
188
- const tokenId = e.args?.tokenId;
189
- if (!tokenId) continue;
190
- owned.delete(tokenId.toString());
191
- }
192
-
193
- // Convert to BigNumbers
194
- return Array.from(owned).map((id) => BigNumber.from(id));
195
- }
196
-
197
-
198
- /**
199
- *
200
- * @param amountWei an amount of liqETH (in WEI) to stake to the Outpost
201
- * @returns txHash (hash of the transaction), receipt, WithdrawnStake event
202
- */
203
- async fetchPreLaunchReceipts(address: string): Promise<preLaunchReceipt[]> {
204
- const receiptContract = this.contract.ReceiptNFT;
205
-
206
- // first figure out which tokenIds this address owns, from events
207
- const tokenIds = await this.getOwnedTokenIdsFor(address);
208
-
209
- const results: preLaunchReceipt[] = [];
210
-
211
- // next fetch on-chain receipt data just for those ids
212
- for (const idBN of tokenIds) {
213
- try {
214
- const receiptData = await receiptContract.getReceipt(idBN);
215
- const formattedReceipt = {
216
- account: receiptData.account,
217
- currency: receiptData.currency,
218
- kind: receiptData.kind,
219
- indexAtMint: receiptData.indexAtMint.toBigInt(),
220
- principal: {
221
- amount: receiptData.principal.toBigInt(),
222
- decimals: 18,
223
- symbol: "LiqETH"
224
- },
225
- shares: {
226
- amount: receiptData.shares.toBigInt(),
227
- decimals: 18,
228
- symbol: "LiqETH"
229
- },
230
- timestamp: new Date(Number(receiptData.timestamp.toString()) * 1000).toLocaleString(),
231
- }
232
-
233
- // Only fetch staking receipts (kind 1 is a wire pretoken receipt)
234
- if(receiptData.kind == 0) results.push({ tokenId: idBN.toBigInt(), receipt: formattedReceipt } as any);
235
- } catch (err) {
236
- // in case of any mismatch or race, just skip this id
237
- console.warn(`Failed to load receipt for tokenId=${idBN.toString()}`, err);
238
- continue;
239
- }
240
- }
241
-
242
- console.log('results of prelaunch receipts', results)
243
- return results;
244
- }
245
-
246
-
247
100
  /**
248
101
  *
249
102
  * @param amountWei an amount of liqETH (in WEI) to stake to the Outpost
@@ -21,6 +21,7 @@ import OPPInboundArtifact from '../../assets/ethereum/ABI/outpost/OPPInbound.sol
21
21
  import PretokenArtifact from '../../assets/ethereum/ABI/outpost/Pretoken.sol/Pretoken.json';
22
22
  import AggregatorArtifact from '../../assets/ethereum/ABI/outpost/Aggregator.sol/Aggregator.json';
23
23
  import EthUsdPriceConsumerArtifact from '../../assets/ethereum/ABI/outpost/EthUsdPriceConsumer.sol/EthUsdPriceConsumer.json';
24
+ import PoolArtifact from '../../assets/ethereum/ABI/outpost/Pool.sol/Pool.json';
24
25
 
25
26
  import ERC20Artifact from '../../assets/ethereum/ABI/token/ERC20Token.sol/ERC20Token.json';
26
27
  import ERC721Artifact from '../../assets/ethereum/ABI/token/ERC721Token.sol/ERC721Token.json';
@@ -41,6 +42,7 @@ export const ERC1155Abi = ERC1155Artifact.abi;
41
42
 
42
43
  // Make sure ContractName in ./types includes all of these keys.
43
44
  export const ADDRESSES: AddressBook = {
45
+ // LiqETH contracts
44
46
  Accounting: "0xd333A03a44D5d602A98c1B7bcd7ED1f042DD0dEd",
45
47
  DepositManager: "0x601eaA31e8d33D8725786f1733f4cE6cCEf740D4",
46
48
  LiqEth: "0x08252e1Dcbaa86A2887927b02536CD3E67a802c8", // AKA LiqEthToken
@@ -48,10 +50,6 @@ export const ADDRESSES: AddressBook = {
48
50
  WithdrawalQueue: "0x951E413FC81a2CE133078ABE8B88677F5296abE7",
49
51
  WithdrawalVault: "0x0D2bf834DD560839e986d42D06DeE268A17c2d13",
50
52
 
51
- // LiqEthAuthority: "0x7A9cf59EC53F32577Cc8200466Cc7693713129D5",
52
- // BeaconState: "0xD3860E5977C94b343341635a2dEEBD20B651c48f",
53
- // YieldOracle: "0x307b35816674913cf122975B3CF912b5709653F3",
54
-
55
53
  //Outpost contracts
56
54
  Depositor: "0x69Aa53Ef02F124dB421AeDda509d6912341299Cc",
57
55
  ReceiptNFT: "0x13588fF41E2f47D047874162B1eD15AaF6818f5a",
@@ -63,6 +61,7 @@ export const ADDRESSES: AddressBook = {
63
61
  Pretoken: "0xcf6A1209A7A391cc576174204386F4e5462323dC",
64
62
  EthUsdPriceConsumer: "0x1Ef180FF49313fCB8B5c0470268295d0d24CDE69",
65
63
  Aggregator: "0xFCfc3ddd4CBd9Ad3b3af3A374B8bdA1b66eE6FFF",
64
+ Pool: "0x29DEf0fA009e02d108d9505018EAe0168F233e03",
66
65
  };
67
66
 
68
67
  export type Contracts<T extends string = ContractName> = Record<T, ContractConfig>;
@@ -142,6 +141,10 @@ export const CONTRACTS: Contracts<ContractName> = {
142
141
  EthUsdPriceConsumer: {
143
142
  address: ADDRESSES.EthUsdPriceConsumer,
144
143
  abi: EthUsdPriceConsumerArtifact.abi as JsonFragment[],
144
+ },
145
+ Pool: {
146
+ address: ADDRESSES.Pool,
147
+ abi: PoolArtifact.abi as JsonFragment[],
145
148
  }
146
149
  };
147
150