@centrifuge/sdk 0.0.0-alpha.28 → 0.0.0-alpha.30
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/dist/Centrifuge.d.ts +183 -169
- package/dist/Centrifuge.d.ts.map +1 -1
- package/dist/Centrifuge.js +169 -79
- package/dist/Centrifuge.js.map +1 -1
- package/dist/Centrifuge.test.js +33 -15
- package/dist/Centrifuge.test.js.map +1 -1
- package/dist/abi/index.d.ts +11 -0
- package/dist/abi/index.d.ts.map +1 -1
- package/dist/abi/index.js +3 -1
- package/dist/abi/index.js.map +1 -1
- package/dist/config/chains.d.ts +156 -938
- package/dist/config/chains.d.ts.map +1 -1
- package/dist/config/chains.js +2 -11
- package/dist/config/chains.js.map +1 -1
- package/dist/entities/BalanceSheet.d.ts +24 -10
- package/dist/entities/BalanceSheet.d.ts.map +1 -1
- package/dist/entities/BalanceSheet.js +4 -59
- package/dist/entities/BalanceSheet.js.map +1 -1
- package/dist/entities/Investor.d.ts +1 -5
- package/dist/entities/Investor.d.ts.map +1 -1
- package/dist/entities/Investor.js +40 -10
- package/dist/entities/Investor.js.map +1 -1
- package/dist/entities/Pool.d.ts +5 -5
- package/dist/entities/Pool.d.ts.map +1 -1
- package/dist/entities/Pool.js +18 -5
- package/dist/entities/Pool.js.map +1 -1
- package/dist/entities/Pool.test.js +5 -5
- package/dist/entities/Pool.test.js.map +1 -1
- package/dist/entities/PoolNetwork.d.ts +5 -6
- package/dist/entities/PoolNetwork.d.ts.map +1 -1
- package/dist/entities/PoolNetwork.js +22 -59
- package/dist/entities/PoolNetwork.js.map +1 -1
- package/dist/entities/ShareClass.d.ts +36 -30
- package/dist/entities/ShareClass.d.ts.map +1 -1
- package/dist/entities/ShareClass.js +329 -265
- package/dist/entities/ShareClass.js.map +1 -1
- package/dist/entities/ShareClass.test.js +16 -17
- package/dist/entities/ShareClass.test.js.map +1 -1
- package/dist/entities/Vault.d.ts +5 -5
- package/dist/entities/Vault.d.ts.map +1 -1
- package/dist/entities/Vault.js +5 -4
- package/dist/entities/Vault.js.map +1 -1
- package/dist/entities/Vault.test.js +10 -19
- package/dist/entities/Vault.test.js.map +1 -1
- package/dist/types/transaction.d.ts +39 -0
- package/dist/types/transaction.d.ts.map +1 -1
- package/dist/types/transaction.js +40 -1
- package/dist/types/transaction.js.map +1 -1
- package/dist/utils/transaction.d.ts +10 -3
- package/dist/utils/transaction.d.ts.map +1 -1
- package/dist/utils/transaction.js +8 -2
- package/dist/utils/transaction.js.map +1 -1
- package/package.json +3 -3
|
@@ -2,14 +2,16 @@ import { catchError, combineLatest, defer, EMPTY, expand, filter, map, of, switc
|
|
|
2
2
|
import { encodeFunctionData, encodePacked, getContract, parseAbi } from 'viem';
|
|
3
3
|
import { ABI } from '../abi/index.js';
|
|
4
4
|
import { AccountType } from '../types/holdings.js';
|
|
5
|
+
import { MessageType } from '../types/transaction.js';
|
|
5
6
|
import { Balance, Price } from '../utils/BigInt.js';
|
|
6
7
|
import { addressToBytes32, randomUint } from '../utils/index.js';
|
|
7
8
|
import { repeatOnEvents } from '../utils/rx.js';
|
|
8
|
-
import {
|
|
9
|
+
import { wrapTransaction } from '../utils/transaction.js';
|
|
9
10
|
import { AssetId, ShareClassId } from '../utils/types.js';
|
|
10
11
|
import { BalanceSheet } from './BalanceSheet.js';
|
|
11
12
|
import { Entity } from './Entity.js';
|
|
12
13
|
import { PoolNetwork } from './PoolNetwork.js';
|
|
14
|
+
import { Vault } from './Vault.js';
|
|
13
15
|
/**
|
|
14
16
|
* Query and interact with a share class, which allows querying total issuance, NAV per share,
|
|
15
17
|
* and allows interactions related to asynchronous deposits and redemptions.
|
|
@@ -29,9 +31,8 @@ export class ShareClass extends Entity {
|
|
|
29
31
|
* @returns The details of the share class, including name, symbol, total issuance, and NAV per share.
|
|
30
32
|
*/
|
|
31
33
|
details() {
|
|
32
|
-
return this._query(null, () => combineLatest([this._metrics(), this._metadata(), this.navPerNetwork()]).pipe(map(([metrics, metadata, navPerNetwork]) => {
|
|
33
|
-
const totalIssuance = navPerNetwork.reduce((acc, item) => acc.add(item.totalIssuance), new Balance(0n,
|
|
34
|
-
);
|
|
34
|
+
return this._query(null, () => combineLatest([this._metrics(), this._metadata(), this.navPerNetwork(), this.pool.currency()]).pipe(map(([metrics, metadata, navPerNetwork, poolCurrency]) => {
|
|
35
|
+
const totalIssuance = navPerNetwork.reduce((acc, item) => acc.add(item.totalIssuance), new Balance(0n, poolCurrency.decimals));
|
|
35
36
|
return {
|
|
36
37
|
id: this.id,
|
|
37
38
|
name: metadata.name,
|
|
@@ -53,113 +54,88 @@ export class ShareClass extends Entity {
|
|
|
53
54
|
})));
|
|
54
55
|
}
|
|
55
56
|
navPerNetwork() {
|
|
56
|
-
return this._root._queryIndexer(`query ($scId: String!) {
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
57
|
+
return this._query(null, () => this.pool.currency().pipe(switchMap((poolCurrency) => this._root._queryIndexer(`query ($scId: String!) {
|
|
58
|
+
tokenInstances(where: { tokenId: $scId }) {
|
|
59
|
+
items {
|
|
60
|
+
totalIssuance
|
|
61
|
+
tokenPrice
|
|
62
|
+
blockchain {
|
|
63
|
+
id
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}`, { scId: this.id.raw }, (data) => data.tokenInstances.items.map((item) => ({
|
|
67
68
|
chainId: Number(item.blockchain.id),
|
|
68
|
-
totalIssuance: new Balance(item.totalIssuance,
|
|
69
|
+
totalIssuance: new Balance(item.totalIssuance, poolCurrency.decimals),
|
|
69
70
|
pricePerShare: new Price(item.tokenPrice),
|
|
70
|
-
nav: new Balance(item.totalIssuance,
|
|
71
|
-
})));
|
|
71
|
+
nav: new Balance(item.totalIssuance, poolCurrency.decimals).mul(new Price(item.tokenPrice)),
|
|
72
|
+
}))))));
|
|
72
73
|
}
|
|
73
74
|
/**
|
|
74
75
|
* Query the vaults of the share class.
|
|
75
|
-
* @param chainId The chain ID to query the vaults on.
|
|
76
|
-
* @returns
|
|
76
|
+
* @param chainId The optional chain ID to query the vaults on.
|
|
77
|
+
* @returns All vaults of the share class, or filtered by the given chain.
|
|
77
78
|
*/
|
|
78
79
|
vaults(chainId) {
|
|
79
|
-
return this._query(null, () =>
|
|
80
|
+
return this._query(null, () => this._allVaults().pipe(map((allVaults) => {
|
|
81
|
+
const vaults = allVaults.filter((vault) => vault.chainId === chainId || !chainId);
|
|
82
|
+
return vaults.map((vault) => new Vault(this._root, new PoolNetwork(this._root, this.pool, vault.chainId), this, vault.assetAddress, vault.address));
|
|
83
|
+
})));
|
|
80
84
|
}
|
|
81
85
|
/**
|
|
82
|
-
* Query all the
|
|
86
|
+
* Query all the balances of the share class (from BalanceSheet and Holdings).
|
|
83
87
|
*/
|
|
84
|
-
|
|
85
|
-
return this._query(null, () => this.
|
|
86
|
-
if (res.
|
|
88
|
+
balances(chainId) {
|
|
89
|
+
return this._query(null, () => combineLatest([this._balances(), this.pool.currency()]).pipe(switchMap(([res, poolCurrency]) => {
|
|
90
|
+
if (res.length === 0) {
|
|
87
91
|
return of([]);
|
|
88
92
|
}
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
93
|
+
const items = res.filter((item) => Number(item.asset.blockchain.id) === chainId || !chainId);
|
|
94
|
+
return combineLatest([
|
|
95
|
+
combineLatest(items.map((holding) => {
|
|
96
|
+
if (!holding.holding)
|
|
97
|
+
return of(null);
|
|
98
|
+
const assetId = new AssetId(holding.assetId);
|
|
99
|
+
return this._holding(assetId);
|
|
100
|
+
})),
|
|
101
|
+
combineLatest(items.map((holding) => {
|
|
102
|
+
const assetId = new AssetId(holding.assetId);
|
|
103
|
+
return this._balance(Number(holding.asset.blockchain.id), {
|
|
104
|
+
address: holding.asset.address,
|
|
105
|
+
assetTokenId: BigInt(holding.asset.assetTokenId),
|
|
106
|
+
id: assetId,
|
|
107
|
+
decimals: holding.asset.decimals,
|
|
108
|
+
});
|
|
109
|
+
})),
|
|
110
|
+
]).pipe(map(([holdings, balances]) => items.map((data, i) => {
|
|
111
|
+
const holding = holdings[i];
|
|
112
|
+
const balance = balances[i];
|
|
113
|
+
// If the holding hasn't been initialized yet, the price is 1
|
|
114
|
+
const price = holding ? balance.price : Price.fromFloat(1);
|
|
115
|
+
const value = Balance.fromFloat(balance.amount.toDecimal().mul(price.toDecimal()), poolCurrency.decimals);
|
|
94
116
|
return {
|
|
95
|
-
|
|
117
|
+
assetId: new AssetId(data.assetId),
|
|
118
|
+
amount: balance.amount,
|
|
119
|
+
value,
|
|
120
|
+
price,
|
|
96
121
|
asset: {
|
|
97
|
-
decimals: data.
|
|
98
|
-
address: data.
|
|
99
|
-
name: data.
|
|
100
|
-
symbol: data.
|
|
101
|
-
chainId: Number(data.
|
|
122
|
+
decimals: data.asset.decimals,
|
|
123
|
+
address: data.asset.address,
|
|
124
|
+
name: data.asset.name,
|
|
125
|
+
symbol: data.asset.symbol,
|
|
126
|
+
chainId: Number(data.asset.blockchain.id),
|
|
127
|
+
},
|
|
128
|
+
holding: holding && {
|
|
129
|
+
valuation: holding.valuation,
|
|
130
|
+
amount: holding.amount,
|
|
131
|
+
value: holding.value,
|
|
132
|
+
isLiability: holding.isLiability,
|
|
133
|
+
accounts: holding.accounts,
|
|
102
134
|
},
|
|
103
135
|
};
|
|
104
136
|
})));
|
|
105
137
|
})));
|
|
106
138
|
}
|
|
107
|
-
/** @internal */
|
|
108
|
-
_holding(assetId) {
|
|
109
|
-
return this._query(['holding', assetId.toString()], () => this._root._protocolAddresses(this.pool.chainId).pipe(switchMap(({ holdings: holdingsAddr, hubRegistry }) => defer(async () => {
|
|
110
|
-
const holdings = getContract({
|
|
111
|
-
address: holdingsAddr,
|
|
112
|
-
abi: ABI.Holdings,
|
|
113
|
-
client: this._root.getClient(this.pool.chainId),
|
|
114
|
-
});
|
|
115
|
-
const [valuation, amount, value, assetDecimals, isLiability, ...accounts] = await Promise.all([
|
|
116
|
-
holdings.read.valuation([this.pool.id.raw, this.id.raw, assetId.raw]),
|
|
117
|
-
holdings.read.amount([this.pool.id.raw, this.id.raw, assetId.raw]),
|
|
118
|
-
holdings.read.value([this.pool.id.raw, this.id.raw, assetId.raw]),
|
|
119
|
-
this._root.getClient(this.pool.chainId).readContract({
|
|
120
|
-
address: hubRegistry,
|
|
121
|
-
// Use inline ABI because of function overload
|
|
122
|
-
abi: parseAbi(['function decimals(uint256) view returns (uint8)']),
|
|
123
|
-
functionName: 'decimals',
|
|
124
|
-
args: [assetId.raw],
|
|
125
|
-
}),
|
|
126
|
-
holdings.read.isLiability([this.pool.id.raw, this.id.raw, assetId.raw]),
|
|
127
|
-
...[
|
|
128
|
-
AccountType.Asset,
|
|
129
|
-
AccountType.Equity,
|
|
130
|
-
AccountType.Loss,
|
|
131
|
-
AccountType.Gain,
|
|
132
|
-
AccountType.Expense,
|
|
133
|
-
AccountType.Liability,
|
|
134
|
-
].map((kind) => holdings.read.accountId([this.pool.id.raw, this.id.raw, assetId.raw, kind])),
|
|
135
|
-
]);
|
|
136
|
-
return {
|
|
137
|
-
assetId,
|
|
138
|
-
assetDecimals,
|
|
139
|
-
valuation,
|
|
140
|
-
amount: new Balance(amount, assetDecimals),
|
|
141
|
-
value: new Balance(value, 18), // TODO: Replace with pool currency decimals
|
|
142
|
-
isLiability,
|
|
143
|
-
accounts: {
|
|
144
|
-
[AccountType.Asset]: accounts[0] || null,
|
|
145
|
-
[AccountType.Equity]: accounts[1] || null,
|
|
146
|
-
[AccountType.Loss]: accounts[2] || null,
|
|
147
|
-
[AccountType.Gain]: accounts[3] || null,
|
|
148
|
-
[AccountType.Expense]: accounts[4] || null,
|
|
149
|
-
[AccountType.Liability]: accounts[5] || null,
|
|
150
|
-
},
|
|
151
|
-
};
|
|
152
|
-
}).pipe(repeatOnEvents(this._root, {
|
|
153
|
-
address: holdingsAddr,
|
|
154
|
-
abi: ABI.Holdings,
|
|
155
|
-
eventName: ['Increase', 'Decrease', 'Update', 'UpdateValuation'],
|
|
156
|
-
filter: (events) => {
|
|
157
|
-
return events.some((event) => {
|
|
158
|
-
return event.args.scId === this.id && event.args.assetId === assetId.raw;
|
|
159
|
-
});
|
|
160
|
-
},
|
|
161
|
-
}, this.pool.chainId)))));
|
|
162
|
-
}
|
|
163
139
|
/**
|
|
164
140
|
* Get the pending and approved amounts for deposits and redemptions for each asset.
|
|
165
141
|
*/
|
|
@@ -253,12 +229,12 @@ export class ShareClass extends Entity {
|
|
|
253
229
|
*/
|
|
254
230
|
createHolding(assetId, valuation, isLiability, accounts) {
|
|
255
231
|
const self = this;
|
|
256
|
-
return this._transact(async function* (
|
|
232
|
+
return this._transact(async function* (ctx) {
|
|
257
233
|
const [{ hub }, metadata] = await Promise.all([
|
|
258
234
|
self._root._protocolAddresses(self.pool.chainId),
|
|
259
235
|
self.pool.metadata(),
|
|
260
236
|
]);
|
|
261
|
-
let
|
|
237
|
+
let data;
|
|
262
238
|
if (isLiability) {
|
|
263
239
|
const expenseAccount = accounts[AccountType.Expense] || metadata?.shareClasses?.[self.id.raw]?.defaultAccounts?.expense;
|
|
264
240
|
const liabilityAccount = accounts[AccountType.Liability] || metadata?.shareClasses?.[self.id.raw]?.defaultAccounts?.liability;
|
|
@@ -266,8 +242,7 @@ export class ShareClass extends Entity {
|
|
|
266
242
|
throw new Error('Missing required accounts for liability creation');
|
|
267
243
|
}
|
|
268
244
|
if (expenseAccount) {
|
|
269
|
-
|
|
270
|
-
address: hub,
|
|
245
|
+
data = encodeFunctionData({
|
|
271
246
|
abi: ABI.Hub,
|
|
272
247
|
functionName: 'initializeLiability',
|
|
273
248
|
args: [self.pool.id.raw, self.id.raw, assetId.raw, valuation, expenseAccount, liabilityAccount],
|
|
@@ -285,12 +260,7 @@ export class ShareClass extends Entity {
|
|
|
285
260
|
functionName: 'initializeLiability',
|
|
286
261
|
args: [self.pool.id.raw, self.id.raw, assetId.raw, valuation, newExpenseAccount, liabilityAccount],
|
|
287
262
|
});
|
|
288
|
-
|
|
289
|
-
address: hub,
|
|
290
|
-
abi: ABI.Hub,
|
|
291
|
-
functionName: 'multicall',
|
|
292
|
-
args: [[createAccountData, initHoldingData]],
|
|
293
|
-
});
|
|
263
|
+
data = [createAccountData, initHoldingData];
|
|
294
264
|
}
|
|
295
265
|
}
|
|
296
266
|
else {
|
|
@@ -302,8 +272,7 @@ export class ShareClass extends Entity {
|
|
|
302
272
|
throw new Error('Missing required accounts for holding creation');
|
|
303
273
|
}
|
|
304
274
|
if (assetAccount) {
|
|
305
|
-
|
|
306
|
-
address: hub,
|
|
275
|
+
data = encodeFunctionData({
|
|
307
276
|
abi: ABI.Hub,
|
|
308
277
|
functionName: 'initializeHolding',
|
|
309
278
|
args: [
|
|
@@ -339,81 +308,101 @@ export class ShareClass extends Entity {
|
|
|
339
308
|
lossAccount,
|
|
340
309
|
],
|
|
341
310
|
});
|
|
342
|
-
|
|
343
|
-
address: hub,
|
|
344
|
-
abi: ABI.Hub,
|
|
345
|
-
functionName: 'multicall',
|
|
346
|
-
args: [[createAccountData, initHoldingData]],
|
|
347
|
-
});
|
|
311
|
+
data = [createAccountData, initHoldingData];
|
|
348
312
|
}
|
|
349
313
|
}
|
|
350
|
-
yield*
|
|
314
|
+
yield* wrapTransaction('Create holding', ctx, {
|
|
315
|
+
contract: hub,
|
|
316
|
+
data,
|
|
317
|
+
});
|
|
351
318
|
}, this.pool.chainId);
|
|
352
319
|
}
|
|
353
320
|
updateSharePrice(pricePerShare) {
|
|
354
321
|
const self = this;
|
|
355
|
-
return this._transact(async function* (
|
|
322
|
+
return this._transact(async function* (ctx) {
|
|
356
323
|
const { hub } = await self._root._protocolAddresses(self.pool.chainId);
|
|
357
|
-
yield*
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
324
|
+
yield* wrapTransaction('Update share price', ctx, {
|
|
325
|
+
contract: hub,
|
|
326
|
+
data: encodeFunctionData({
|
|
327
|
+
abi: ABI.Hub,
|
|
328
|
+
functionName: 'updateSharePrice',
|
|
329
|
+
args: [self.pool.id.raw, self.id.raw, pricePerShare.toBigInt()],
|
|
330
|
+
}),
|
|
331
|
+
});
|
|
363
332
|
}, this.pool.chainId);
|
|
364
333
|
}
|
|
365
334
|
setMaxAssetPriceAge(assetId, maxPriceAge) {
|
|
366
335
|
const self = this;
|
|
367
|
-
return this._transact(async function* (
|
|
336
|
+
return this._transact(async function* (ctx) {
|
|
368
337
|
const { hub } = await self._root._protocolAddresses(self.pool.chainId);
|
|
369
|
-
yield*
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
338
|
+
yield* wrapTransaction('Set max asset price age', ctx, {
|
|
339
|
+
contract: hub,
|
|
340
|
+
data: encodeFunctionData({
|
|
341
|
+
abi: ABI.Hub,
|
|
342
|
+
functionName: 'setMaxAssetPriceAge',
|
|
343
|
+
args: [self.pool.id.raw, self.id.raw, assetId.raw, BigInt(maxPriceAge)],
|
|
344
|
+
}),
|
|
345
|
+
messages: {
|
|
346
|
+
[assetId.centrifugeId]: [MessageType.MaxAssetPriceAge],
|
|
347
|
+
},
|
|
348
|
+
});
|
|
375
349
|
}, this.pool.chainId);
|
|
376
350
|
}
|
|
377
351
|
setMaxSharePriceAge(chainId, maxPriceAge) {
|
|
378
352
|
const self = this;
|
|
379
|
-
return this._transact(async function* (
|
|
353
|
+
return this._transact(async function* (ctx) {
|
|
380
354
|
const [{ hub }, id] = await Promise.all([
|
|
381
355
|
self._root._protocolAddresses(self.pool.chainId),
|
|
382
356
|
self._root.id(chainId),
|
|
383
357
|
]);
|
|
384
|
-
yield*
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
358
|
+
yield* wrapTransaction('Set max share price age', ctx, {
|
|
359
|
+
contract: hub,
|
|
360
|
+
data: encodeFunctionData({
|
|
361
|
+
abi: ABI.Hub,
|
|
362
|
+
functionName: 'setMaxSharePriceAge',
|
|
363
|
+
args: [id, self.pool.id.raw, self.id.raw, BigInt(maxPriceAge)],
|
|
364
|
+
}),
|
|
365
|
+
messages: {
|
|
366
|
+
[id]: [MessageType.MaxSharePriceAge],
|
|
367
|
+
},
|
|
368
|
+
});
|
|
390
369
|
}, this.pool.chainId);
|
|
391
370
|
}
|
|
392
371
|
notifyAssetPrice(assetId) {
|
|
393
372
|
const self = this;
|
|
394
|
-
return this._transact(async function* (
|
|
373
|
+
return this._transact(async function* (ctx) {
|
|
395
374
|
const { hub } = await self._root._protocolAddresses(self.pool.chainId);
|
|
396
|
-
yield*
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
375
|
+
yield* wrapTransaction('Notify asset price', ctx, {
|
|
376
|
+
contract: hub,
|
|
377
|
+
data: encodeFunctionData({
|
|
378
|
+
abi: ABI.Hub,
|
|
379
|
+
functionName: 'notifyAssetPrice',
|
|
380
|
+
args: [self.pool.id.raw, self.id.raw, assetId.raw],
|
|
381
|
+
}),
|
|
382
|
+
messages: {
|
|
383
|
+
[assetId.centrifugeId]: [MessageType.NotifyPricePoolPerAsset],
|
|
384
|
+
},
|
|
385
|
+
});
|
|
402
386
|
}, this.pool.chainId);
|
|
403
387
|
}
|
|
404
388
|
notifySharePrice(chainId) {
|
|
405
389
|
const self = this;
|
|
406
|
-
return this._transact(async function* (
|
|
390
|
+
return this._transact(async function* (ctx) {
|
|
407
391
|
const [{ hub }, id] = await Promise.all([
|
|
408
392
|
self._root._protocolAddresses(self.pool.chainId),
|
|
409
393
|
self._root.id(chainId),
|
|
410
394
|
]);
|
|
411
|
-
yield*
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
395
|
+
yield* wrapTransaction('Notify share price', ctx, {
|
|
396
|
+
contract: hub,
|
|
397
|
+
data: encodeFunctionData({
|
|
398
|
+
abi: ABI.Hub,
|
|
399
|
+
functionName: 'notifySharePrice',
|
|
400
|
+
args: [self.pool.id.raw, self.id.raw, id],
|
|
401
|
+
}),
|
|
402
|
+
messages: {
|
|
403
|
+
[id]: [MessageType.NotifyPricePoolPerShare],
|
|
404
|
+
},
|
|
405
|
+
});
|
|
417
406
|
}, this.pool.chainId);
|
|
418
407
|
}
|
|
419
408
|
/**
|
|
@@ -423,18 +412,17 @@ export class ShareClass extends Entity {
|
|
|
423
412
|
approveDepositsAndIssueShares(assets) {
|
|
424
413
|
// TODO: Also claim orders
|
|
425
414
|
const self = this;
|
|
426
|
-
return this._transact(async function* (
|
|
427
|
-
const
|
|
428
|
-
const [{ hub }, pendingAmounts,
|
|
429
|
-
// ...estimates
|
|
430
|
-
] = await Promise.all([
|
|
415
|
+
return this._transact(async function* (ctx) {
|
|
416
|
+
const [{ hub }, pendingAmounts] = await Promise.all([
|
|
431
417
|
self._root._protocolAddresses(self.pool.chainId),
|
|
432
418
|
self.pendingAmounts(),
|
|
433
|
-
...centIds.map((centId) => self._root._estimate(self.pool.chainId, { centId })),
|
|
434
419
|
]);
|
|
435
|
-
// const estimateByCentId: Map<number, bigint> = new Map(centIds.map((centId, i) => [centId, estimates[i]!]))
|
|
436
420
|
const batch = [];
|
|
437
|
-
const
|
|
421
|
+
const messages = {};
|
|
422
|
+
// function addMessage(centId: number, message: MessageType) {
|
|
423
|
+
// if (!messages[centId]) messages[centId] = []
|
|
424
|
+
// messages[centId].push(message)
|
|
425
|
+
// }
|
|
438
426
|
for (const asset of assets) {
|
|
439
427
|
const pending = pendingAmounts.find((e) => e.assetId.equals(asset.assetId));
|
|
440
428
|
if (!pending) {
|
|
@@ -481,21 +469,10 @@ export class ShareClass extends Entity {
|
|
|
481
469
|
if (batch.length === 0) {
|
|
482
470
|
throw new Error('No approve or issue actions provided');
|
|
483
471
|
}
|
|
484
|
-
yield*
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
to: hub,
|
|
489
|
-
value: estimate,
|
|
490
|
-
});
|
|
491
|
-
}
|
|
492
|
-
return walletClient.writeContract({
|
|
493
|
-
address: hub,
|
|
494
|
-
abi: ABI.Hub,
|
|
495
|
-
functionName: 'multicall',
|
|
496
|
-
args: [batch],
|
|
497
|
-
value: estimate,
|
|
498
|
-
});
|
|
472
|
+
yield* wrapTransaction('Approve and issue', ctx, {
|
|
473
|
+
contract: hub,
|
|
474
|
+
data: batch,
|
|
475
|
+
messages,
|
|
499
476
|
});
|
|
500
477
|
}, this.pool.chainId);
|
|
501
478
|
}
|
|
@@ -506,18 +483,17 @@ export class ShareClass extends Entity {
|
|
|
506
483
|
approveRedeemsAndRevokeShares(assets) {
|
|
507
484
|
// TODO: Also claim orders
|
|
508
485
|
const self = this;
|
|
509
|
-
return this._transact(async function* (
|
|
510
|
-
const
|
|
511
|
-
const [{ hub }, pendingAmounts,
|
|
512
|
-
// ...estimates
|
|
513
|
-
] = await Promise.all([
|
|
486
|
+
return this._transact(async function* (ctx) {
|
|
487
|
+
const [{ hub }, pendingAmounts] = await Promise.all([
|
|
514
488
|
self._root._protocolAddresses(self.pool.chainId),
|
|
515
489
|
self.pendingAmounts(),
|
|
516
|
-
...centIds.map((centId) => self._root._estimate(self.pool.chainId, { centId })),
|
|
517
490
|
]);
|
|
518
|
-
// const estimateByCentId: Map<number, bigint> = new Map(centIds.map((centId, i) => [centId, estimates[i]!]))
|
|
519
491
|
const batch = [];
|
|
520
|
-
const
|
|
492
|
+
const messages = {};
|
|
493
|
+
// function addMessage(centId: number, message: MessageType) {
|
|
494
|
+
// if (!messages[centId]) messages[centId] = []
|
|
495
|
+
// messages[centId].push(message)
|
|
496
|
+
// }
|
|
521
497
|
for (const asset of assets) {
|
|
522
498
|
const pending = pendingAmounts.find((e) => e.assetId.equals(asset.assetId));
|
|
523
499
|
if (!pending) {
|
|
@@ -569,21 +545,10 @@ export class ShareClass extends Entity {
|
|
|
569
545
|
if (batch.length === 0) {
|
|
570
546
|
throw new Error('No approve or revoke actions provided');
|
|
571
547
|
}
|
|
572
|
-
yield*
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
to: hub,
|
|
577
|
-
value: estimate,
|
|
578
|
-
});
|
|
579
|
-
}
|
|
580
|
-
return walletClient.writeContract({
|
|
581
|
-
address: hub,
|
|
582
|
-
abi: ABI.Hub,
|
|
583
|
-
functionName: 'multicall',
|
|
584
|
-
args: [batch],
|
|
585
|
-
value: estimate,
|
|
586
|
-
});
|
|
548
|
+
yield* wrapTransaction('Approve and revoke', ctx, {
|
|
549
|
+
contract: hub,
|
|
550
|
+
data: batch,
|
|
551
|
+
messages,
|
|
587
552
|
});
|
|
588
553
|
}, this.pool.chainId);
|
|
589
554
|
}
|
|
@@ -593,25 +558,26 @@ export class ShareClass extends Entity {
|
|
|
593
558
|
*/
|
|
594
559
|
claimDeposit(assetId, investor) {
|
|
595
560
|
const self = this;
|
|
596
|
-
return this._transact(async function* (
|
|
597
|
-
const [{ hub }, investorOrder
|
|
561
|
+
return this._transact(async function* (ctx) {
|
|
562
|
+
const [{ hub }, investorOrder] = await Promise.all([
|
|
598
563
|
self._root._protocolAddresses(self.pool.chainId),
|
|
599
564
|
self.investorOrder(assetId, investor),
|
|
600
|
-
self._root._estimate(self.pool.chainId, { centId: assetId.centrifugeId }),
|
|
601
565
|
]);
|
|
602
|
-
yield*
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
566
|
+
yield* wrapTransaction('Claim deposit', ctx, {
|
|
567
|
+
contract: hub,
|
|
568
|
+
data: encodeFunctionData({
|
|
569
|
+
abi: ABI.Hub,
|
|
570
|
+
functionName: 'notifyDeposit',
|
|
571
|
+
args: [
|
|
572
|
+
self.pool.id.raw,
|
|
573
|
+
self.id.raw,
|
|
574
|
+
assetId.raw,
|
|
575
|
+
addressToBytes32(investor),
|
|
576
|
+
investorOrder.maxDepositClaims,
|
|
577
|
+
],
|
|
578
|
+
}),
|
|
579
|
+
messages: { [assetId.centrifugeId]: [MessageType.RequestCallback] },
|
|
580
|
+
});
|
|
615
581
|
}, this.pool.chainId);
|
|
616
582
|
}
|
|
617
583
|
/**
|
|
@@ -620,19 +586,20 @@ export class ShareClass extends Entity {
|
|
|
620
586
|
*/
|
|
621
587
|
claimRedeem(assetId, investor) {
|
|
622
588
|
const self = this;
|
|
623
|
-
return this._transact(async function* (
|
|
624
|
-
const [{ hub }, investorOrder
|
|
589
|
+
return this._transact(async function* (ctx) {
|
|
590
|
+
const [{ hub }, investorOrder] = await Promise.all([
|
|
625
591
|
self._root._protocolAddresses(self.pool.chainId),
|
|
626
592
|
self.investorOrder(assetId, investor),
|
|
627
|
-
self._root._estimate(self.pool.chainId, { centId: assetId.centrifugeId }),
|
|
628
593
|
]);
|
|
629
|
-
yield*
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
594
|
+
yield* wrapTransaction('Claim redeem', ctx, {
|
|
595
|
+
contract: hub,
|
|
596
|
+
data: encodeFunctionData({
|
|
597
|
+
abi: ABI.Hub,
|
|
598
|
+
functionName: 'notifyRedeem',
|
|
599
|
+
args: [self.pool.id.raw, self.id.raw, assetId.raw, addressToBytes32(investor), investorOrder.maxRedeemClaims],
|
|
600
|
+
}),
|
|
601
|
+
messages: { [assetId.centrifugeId]: [MessageType.RequestCallback] },
|
|
602
|
+
});
|
|
636
603
|
}, this.pool.chainId);
|
|
637
604
|
}
|
|
638
605
|
/**
|
|
@@ -643,45 +610,146 @@ export class ShareClass extends Entity {
|
|
|
643
610
|
*/
|
|
644
611
|
updateMember(address, validUntil, chainId) {
|
|
645
612
|
const self = this;
|
|
646
|
-
return this._transact(async function* (
|
|
647
|
-
const [{ hub }, id
|
|
613
|
+
return this._transact(async function* (ctx) {
|
|
614
|
+
const [{ hub }, id] = await Promise.all([
|
|
648
615
|
self._root._protocolAddresses(self.pool.chainId),
|
|
649
616
|
self._root.id(chainId),
|
|
650
|
-
self._root._estimate(self.pool.chainId, { chainId }),
|
|
651
617
|
]);
|
|
652
618
|
const payload = encodePacked(['uint8', 'bytes32', 'uint64'], [/* UpdateRestrictionType.Member */ 1, addressToBytes32(address), BigInt(validUntil)]);
|
|
653
|
-
yield*
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
619
|
+
yield* wrapTransaction('Update member', ctx, {
|
|
620
|
+
contract: hub,
|
|
621
|
+
data: encodeFunctionData({
|
|
622
|
+
abi: ABI.Hub,
|
|
623
|
+
functionName: 'updateRestriction',
|
|
624
|
+
args: [self.pool.id.raw, self.id.raw, id, payload, 0n],
|
|
625
|
+
}),
|
|
626
|
+
messages: { [id]: [MessageType.UpdateRestriction] },
|
|
627
|
+
});
|
|
660
628
|
}, this.pool.chainId);
|
|
661
629
|
}
|
|
662
630
|
/** @internal */
|
|
663
|
-
|
|
631
|
+
_balances() {
|
|
664
632
|
return this._root._queryIndexer(`query ($scId: String!) {
|
|
665
|
-
|
|
633
|
+
holdingEscrows(where: { tokenId: $scId }) {
|
|
666
634
|
items {
|
|
635
|
+
holding {
|
|
636
|
+
updatedAt
|
|
637
|
+
}
|
|
638
|
+
assetAmount
|
|
639
|
+
assetPrice
|
|
667
640
|
assetId
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
id
|
|
677
|
-
}
|
|
641
|
+
asset {
|
|
642
|
+
decimals
|
|
643
|
+
assetTokenId
|
|
644
|
+
address
|
|
645
|
+
name
|
|
646
|
+
symbol
|
|
647
|
+
blockchain {
|
|
648
|
+
id
|
|
678
649
|
}
|
|
679
650
|
}
|
|
680
651
|
}
|
|
681
652
|
}
|
|
682
653
|
}`, {
|
|
683
654
|
scId: this.id.raw,
|
|
684
|
-
});
|
|
655
|
+
}, (data) => data.holdingEscrows.items);
|
|
656
|
+
}
|
|
657
|
+
/** @internal */
|
|
658
|
+
_holding(assetId) {
|
|
659
|
+
return this._query(['holding', assetId.toString()], () => combineLatest([this._root._protocolAddresses(this.pool.chainId), this.pool.currency()]).pipe(switchMap(([{ holdings: holdingsAddr, hubRegistry }, poolCurrency]) => defer(async () => {
|
|
660
|
+
const holdings = getContract({
|
|
661
|
+
address: holdingsAddr,
|
|
662
|
+
abi: ABI.Holdings,
|
|
663
|
+
client: this._root.getClient(this.pool.chainId),
|
|
664
|
+
});
|
|
665
|
+
const [valuation, amount, value, assetDecimals, isLiability, ...accounts] = await Promise.all([
|
|
666
|
+
holdings.read.valuation([this.pool.id.raw, this.id.raw, assetId.raw]),
|
|
667
|
+
holdings.read.amount([this.pool.id.raw, this.id.raw, assetId.raw]),
|
|
668
|
+
holdings.read.value([this.pool.id.raw, this.id.raw, assetId.raw]),
|
|
669
|
+
this._root.getClient(this.pool.chainId).readContract({
|
|
670
|
+
address: hubRegistry,
|
|
671
|
+
// Use inline ABI because of function overload
|
|
672
|
+
abi: parseAbi(['function decimals(uint256) view returns (uint8)']),
|
|
673
|
+
functionName: 'decimals',
|
|
674
|
+
args: [assetId.raw],
|
|
675
|
+
}),
|
|
676
|
+
holdings.read.isLiability([this.pool.id.raw, this.id.raw, assetId.raw]),
|
|
677
|
+
...[
|
|
678
|
+
AccountType.Asset,
|
|
679
|
+
AccountType.Equity,
|
|
680
|
+
AccountType.Loss,
|
|
681
|
+
AccountType.Gain,
|
|
682
|
+
AccountType.Expense,
|
|
683
|
+
AccountType.Liability,
|
|
684
|
+
].map((kind) => holdings.read.accountId([this.pool.id.raw, this.id.raw, assetId.raw, kind])),
|
|
685
|
+
]);
|
|
686
|
+
return {
|
|
687
|
+
assetId,
|
|
688
|
+
assetDecimals,
|
|
689
|
+
valuation,
|
|
690
|
+
amount: new Balance(amount, assetDecimals),
|
|
691
|
+
value: new Balance(value, poolCurrency.decimals),
|
|
692
|
+
isLiability,
|
|
693
|
+
accounts: {
|
|
694
|
+
[AccountType.Asset]: accounts[0] || null,
|
|
695
|
+
[AccountType.Equity]: accounts[1] || null,
|
|
696
|
+
[AccountType.Loss]: accounts[2] || null,
|
|
697
|
+
[AccountType.Gain]: accounts[3] || null,
|
|
698
|
+
[AccountType.Expense]: accounts[4] || null,
|
|
699
|
+
[AccountType.Liability]: accounts[5] || null,
|
|
700
|
+
},
|
|
701
|
+
};
|
|
702
|
+
}).pipe(repeatOnEvents(this._root, {
|
|
703
|
+
address: holdingsAddr,
|
|
704
|
+
abi: ABI.Holdings,
|
|
705
|
+
eventName: ['Increase', 'Decrease', 'Update', 'UpdateValuation'],
|
|
706
|
+
filter: (events) => {
|
|
707
|
+
return events.some((event) => {
|
|
708
|
+
return event.args.scId === this.id && event.args.assetId === assetId.raw;
|
|
709
|
+
});
|
|
710
|
+
},
|
|
711
|
+
}, this.pool.chainId)))));
|
|
712
|
+
}
|
|
713
|
+
/** @internal */
|
|
714
|
+
_balance(chainId, asset) {
|
|
715
|
+
return this._query(['balance', asset.id.toString()], () => combineLatest([this._root._protocolAddresses(chainId), this.pool.currency()]).pipe(switchMap(([addresses, poolCurrency]) => defer(async () => {
|
|
716
|
+
const client = this._root.getClient(chainId);
|
|
717
|
+
const [amountBn, priceBn] = await Promise.all([
|
|
718
|
+
client.readContract({
|
|
719
|
+
address: addresses.balanceSheet,
|
|
720
|
+
abi: ABI.BalanceSheet,
|
|
721
|
+
functionName: 'availableBalanceOf',
|
|
722
|
+
args: [this.pool.id.raw, this.id.raw, asset.address, BigInt(asset.assetTokenId ?? 0n)],
|
|
723
|
+
}),
|
|
724
|
+
client.readContract({
|
|
725
|
+
address: addresses.spoke,
|
|
726
|
+
abi: ABI.Spoke,
|
|
727
|
+
functionName: 'pricePoolPerAsset',
|
|
728
|
+
args: [this.pool.id.raw, this.id.raw, asset.id.raw, false],
|
|
729
|
+
}),
|
|
730
|
+
]);
|
|
731
|
+
console.log('addresses.spoke', addresses.spoke);
|
|
732
|
+
console.log('priceBn', priceBn, this.pool.id.raw, this.id.raw, asset.id.raw);
|
|
733
|
+
const amount = new Balance(amountBn, asset.decimals);
|
|
734
|
+
const price = new Price(priceBn);
|
|
735
|
+
const value = Balance.fromFloat(amount.toDecimal().mul(price.toDecimal()), poolCurrency.decimals);
|
|
736
|
+
return {
|
|
737
|
+
amount,
|
|
738
|
+
value,
|
|
739
|
+
price,
|
|
740
|
+
};
|
|
741
|
+
}).pipe(repeatOnEvents(this._root, {
|
|
742
|
+
address: [addresses.balanceSheet, addresses.spoke],
|
|
743
|
+
abi: [ABI.ShareClassManager, ABI.Spoke],
|
|
744
|
+
eventName: ['NoteDeposit', 'Deposit', 'Withdraw', 'UpdateAssetPrice'],
|
|
745
|
+
filter: (events) => {
|
|
746
|
+
return events.some((event) => event.args.scId === this.id.raw &&
|
|
747
|
+
// UpdateAssetPrice event
|
|
748
|
+
(event.args.assetId === asset.id.raw ||
|
|
749
|
+
// NoteDeposit, Deposit, Withdraw events
|
|
750
|
+
event.args.asset?.toLowerCase() === asset.address?.toLowerCase()));
|
|
751
|
+
},
|
|
752
|
+
}, chainId)))));
|
|
685
753
|
}
|
|
686
754
|
/** @internal */
|
|
687
755
|
_allVaults() {
|
|
@@ -761,23 +829,20 @@ export class ShareClass extends Entity {
|
|
|
761
829
|
}
|
|
762
830
|
/** @internal */
|
|
763
831
|
_epoch(assetId) {
|
|
764
|
-
return this._query(['epoch', assetId.toString()], () =>
|
|
832
|
+
return this._query(['epoch', assetId.toString()], () => combineLatest([
|
|
833
|
+
this._root._protocolAddresses(this.pool.chainId),
|
|
834
|
+
this.pool.currency(),
|
|
835
|
+
this._root.assetDecimals(assetId, this.pool.chainId),
|
|
836
|
+
]).pipe(switchMap(([{ shareClassManager }, poolCurrency, assetDecimals]) => defer(async () => {
|
|
765
837
|
const scm = getContract({
|
|
766
838
|
address: shareClassManager,
|
|
767
839
|
abi: ABI.ShareClassManager,
|
|
768
840
|
client: this._root.getClient(this.pool.chainId),
|
|
769
841
|
});
|
|
770
|
-
const [epoch, pendingDeposit, pendingRedeem
|
|
842
|
+
const [epoch, pendingDeposit, pendingRedeem] = await Promise.all([
|
|
771
843
|
scm.read.epochId([this.id.raw, assetId.raw]),
|
|
772
844
|
scm.read.pendingDeposit([this.id.raw, assetId.raw]),
|
|
773
845
|
scm.read.pendingRedeem([this.id.raw, assetId.raw]),
|
|
774
|
-
this._root.getClient(this.pool.chainId).readContract({
|
|
775
|
-
address: hubRegistry,
|
|
776
|
-
// Use inline ABI because of function overload
|
|
777
|
-
abi: parseAbi(['function decimals(uint256) view returns (uint8)']),
|
|
778
|
-
functionName: 'decimals',
|
|
779
|
-
args: [assetId.raw],
|
|
780
|
-
}),
|
|
781
846
|
]);
|
|
782
847
|
const depositEpoch = epoch[0];
|
|
783
848
|
const redeemEpoch = epoch[1];
|
|
@@ -794,12 +859,10 @@ export class ShareClass extends Entity {
|
|
|
794
859
|
redeemEpoch,
|
|
795
860
|
issueEpoch,
|
|
796
861
|
revokeEpoch,
|
|
797
|
-
// TODO: Replace with assetDecimals()
|
|
798
862
|
pendingDeposit: new Balance(pendingDeposit, assetDecimals),
|
|
799
|
-
|
|
800
|
-
pendingRedeem: new Balance(pendingRedeem, 18),
|
|
863
|
+
pendingRedeem: new Balance(pendingRedeem, poolCurrency.decimals),
|
|
801
864
|
approvedDeposit: new Balance(approvedDeposit, assetDecimals),
|
|
802
|
-
approvedRedeem: new Balance(approvedRedeem,
|
|
865
|
+
approvedRedeem: new Balance(approvedRedeem, poolCurrency.decimals),
|
|
803
866
|
};
|
|
804
867
|
}).pipe(repeatOnEvents(this._root, {
|
|
805
868
|
address: shareClassManager,
|
|
@@ -824,19 +887,20 @@ export class ShareClass extends Entity {
|
|
|
824
887
|
/** @internal */
|
|
825
888
|
_updateContract(chainId, target, payload) {
|
|
826
889
|
const self = this;
|
|
827
|
-
return this._transact(async function* (
|
|
828
|
-
const id = await
|
|
829
|
-
|
|
890
|
+
return this._transact(async function* (ctx) {
|
|
891
|
+
const [id, { hub }] = await Promise.all([
|
|
892
|
+
self._root.id(chainId),
|
|
830
893
|
self._root._protocolAddresses(self.pool.chainId),
|
|
831
|
-
self._root._estimate(self.pool.chainId, { centId: id }),
|
|
832
894
|
]);
|
|
833
|
-
yield*
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
895
|
+
yield* wrapTransaction('Update contract', ctx, {
|
|
896
|
+
contract: hub,
|
|
897
|
+
data: encodeFunctionData({
|
|
898
|
+
abi: ABI.Hub,
|
|
899
|
+
functionName: 'updateContract',
|
|
900
|
+
args: [self.pool.id.raw, self.id.raw, id, addressToBytes32(target), payload, 0n],
|
|
901
|
+
}),
|
|
902
|
+
messages: { [id]: [MessageType.UpdateContract] },
|
|
903
|
+
});
|
|
840
904
|
}, this.pool.chainId);
|
|
841
905
|
}
|
|
842
906
|
/** @internal */
|