@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.
- package/lib/stake.browser.js +1802 -582
- package/lib/stake.browser.js.map +1 -1
- package/lib/stake.d.ts +66 -24
- package/lib/stake.js +1885 -633
- package/lib/stake.js.map +1 -1
- package/lib/stake.m.js +1802 -582
- package/lib/stake.m.js.map +1 -1
- package/package.json +1 -1
- package/src/networks/ethereum/clients/{deposit.client.ts → convert.client.ts} +36 -4
- package/src/networks/ethereum/clients/opp.client.ts +390 -0
- package/src/networks/ethereum/clients/pretoken.client.ts +88 -49
- package/src/networks/ethereum/clients/receipt.client.ts +129 -0
- package/src/networks/ethereum/clients/stake.client.ts +1 -148
- package/src/networks/ethereum/contract.ts +7 -4
- package/src/networks/ethereum/ethereum.ts +133 -133
- package/src/networks/ethereum/types.ts +1 -0
- package/src/networks/solana/solana.ts +35 -18
- package/src/types.ts +60 -1
- package/src/networks/ethereum/clients/liq.client.ts +0 -47
|
@@ -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 {
|
|
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
|
|