@agoric/fast-usdc 0.2.0-u19.1 → 0.2.0-u20.0
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/README.md +17 -91
- package/package.json +22 -29
- package/src/cli/config.js +1 -1
- package/src/cli/lp-commands.js +2 -2
- package/src/cli/operator-commands.js +1 -4
- package/src/cli/transfer.js +2 -2
- package/src/constants.js +2 -2
- package/src/operator-kit-interface.js +29 -0
- package/src/pool-share-math.js +18 -26
- package/src/type-guards.js +49 -13
- package/src/types.ts +58 -12
- package/src/utils/fees.js +104 -18
- package/tools/mock-evidence.ts +208 -0
- package/src/add-operators.core.js +0 -63
- package/src/distribute-fees.core.js +0 -93
- package/src/exos/advancer.js +0 -369
- package/src/exos/liquidity-pool.js +0 -414
- package/src/exos/operator-kit.js +0 -124
- package/src/exos/settler.js +0 -393
- package/src/exos/status-manager.js +0 -427
- package/src/exos/transaction-feed.js +0 -259
- package/src/fast-usdc-policy.core.js +0 -65
- package/src/fast-usdc.contract.js +0 -316
- package/src/fast-usdc.flows.js +0 -23
- package/src/start-fast-usdc.core.js +0 -246
- package/src/utils/chain-policies.js +0 -140
- package/src/utils/config-marshal.js +0 -130
- package/src/utils/core-eval.js +0 -73
- package/src/utils/deploy-config.js +0 -127
- package/src/utils/zoe.js +0 -28
|
@@ -1,414 +0,0 @@
|
|
|
1
|
-
import { AmountMath, AmountShape, RatioShape } from '@agoric/ertp';
|
|
2
|
-
import {
|
|
3
|
-
makeRecorderTopic,
|
|
4
|
-
RecorderKitShape,
|
|
5
|
-
TopicsRecordShape,
|
|
6
|
-
} from '@agoric/zoe/src/contractSupport/index.js';
|
|
7
|
-
import { SeatShape } from '@agoric/zoe/src/typeGuards.js';
|
|
8
|
-
import { M } from '@endo/patterns';
|
|
9
|
-
import { Fail, q } from '@endo/errors';
|
|
10
|
-
import {
|
|
11
|
-
borrowCalc,
|
|
12
|
-
checkPoolBalance,
|
|
13
|
-
depositCalc,
|
|
14
|
-
makeParity,
|
|
15
|
-
repayCalc,
|
|
16
|
-
withdrawCalc,
|
|
17
|
-
} from '../pool-share-math.js';
|
|
18
|
-
import {
|
|
19
|
-
makeNatAmountShape,
|
|
20
|
-
makeProposalShapes,
|
|
21
|
-
PoolMetricsShape,
|
|
22
|
-
} from '../type-guards.js';
|
|
23
|
-
|
|
24
|
-
/**
|
|
25
|
-
* @import {Amount, Brand, Payment} from '@agoric/ertp';
|
|
26
|
-
* @import {Zone} from '@agoric/zone';
|
|
27
|
-
* @import {Remote} from '@agoric/internal'
|
|
28
|
-
* @import {StorageNode} from '@agoric/internal/src/lib-chainStorage.js'
|
|
29
|
-
* @import {MakeRecorderKit} from '@agoric/zoe/src/contractSupport/recorder.js'
|
|
30
|
-
* @import {USDCProposalShapes, ShareWorth} from '../pool-share-math.js'
|
|
31
|
-
* @import {PoolStats} from '../types.js';
|
|
32
|
-
*/
|
|
33
|
-
|
|
34
|
-
const { add, isGTE, makeEmpty } = AmountMath;
|
|
35
|
-
|
|
36
|
-
/**
|
|
37
|
-
* @typedef {{
|
|
38
|
-
* Principal: Amount<'nat'>;
|
|
39
|
-
* PoolFee: Amount<'nat'>;
|
|
40
|
-
* ContractFee: Amount<'nat'>;
|
|
41
|
-
* }} RepayAmountKWR
|
|
42
|
-
*/
|
|
43
|
-
|
|
44
|
-
/**
|
|
45
|
-
* @typedef {{
|
|
46
|
-
* Principal: Payment<'nat'>;
|
|
47
|
-
* PoolFee: Payment<'nat'>;
|
|
48
|
-
* ContractFee: Payment<'nat'>;
|
|
49
|
-
* }} RepayPaymentKWR
|
|
50
|
-
*/
|
|
51
|
-
|
|
52
|
-
export const stateShape = harden({
|
|
53
|
-
encumberedBalance: AmountShape,
|
|
54
|
-
feeSeat: M.remotable(),
|
|
55
|
-
poolStats: M.record(),
|
|
56
|
-
poolMetricsRecorderKit: RecorderKitShape,
|
|
57
|
-
poolSeat: M.remotable(),
|
|
58
|
-
PoolShares: M.remotable(),
|
|
59
|
-
proposalShapes: {
|
|
60
|
-
deposit: M.pattern(),
|
|
61
|
-
withdraw: M.pattern(),
|
|
62
|
-
withdrawFees: M.pattern(),
|
|
63
|
-
},
|
|
64
|
-
shareMint: M.remotable(),
|
|
65
|
-
shareWorth: RatioShape,
|
|
66
|
-
});
|
|
67
|
-
|
|
68
|
-
/**
|
|
69
|
-
* @param {Zone} zone
|
|
70
|
-
* @param {ZCF} zcf
|
|
71
|
-
* @param {Brand<'nat'>} USDC
|
|
72
|
-
* @param {{
|
|
73
|
-
* makeRecorderKit: MakeRecorderKit;
|
|
74
|
-
* }} tools
|
|
75
|
-
*/
|
|
76
|
-
export const prepareLiquidityPoolKit = (zone, zcf, USDC, tools) => {
|
|
77
|
-
return zone.exoClassKit(
|
|
78
|
-
'Liquidity Pool',
|
|
79
|
-
{
|
|
80
|
-
borrower: M.interface('borrower', {
|
|
81
|
-
borrow: M.call(SeatShape, makeNatAmountShape(USDC, 1n)).returns(),
|
|
82
|
-
returnToPool: M.call(SeatShape, makeNatAmountShape(USDC, 1n)).returns(),
|
|
83
|
-
}),
|
|
84
|
-
repayer: M.interface('repayer', {
|
|
85
|
-
repay: M.call(
|
|
86
|
-
SeatShape,
|
|
87
|
-
harden({
|
|
88
|
-
Principal: makeNatAmountShape(USDC, 1n),
|
|
89
|
-
PoolFee: makeNatAmountShape(USDC, 0n),
|
|
90
|
-
ContractFee: makeNatAmountShape(USDC, 0n),
|
|
91
|
-
}),
|
|
92
|
-
).returns(),
|
|
93
|
-
}),
|
|
94
|
-
external: M.interface('external', {
|
|
95
|
-
publishPoolMetrics: M.call().returns(),
|
|
96
|
-
}),
|
|
97
|
-
depositHandler: M.interface('depositHandler', {
|
|
98
|
-
handle: M.call(SeatShape, M.any()).returns(M.promise()),
|
|
99
|
-
}),
|
|
100
|
-
withdrawHandler: M.interface('withdrawHandler', {
|
|
101
|
-
handle: M.call(SeatShape, M.any()).returns(M.promise()),
|
|
102
|
-
}),
|
|
103
|
-
withdrawFeesHandler: M.interface('withdrawFeesHandler', {
|
|
104
|
-
handle: M.call(SeatShape, M.any()).returns(M.promise()),
|
|
105
|
-
}),
|
|
106
|
-
public: M.interface('public', {
|
|
107
|
-
makeDepositInvitation: M.call().returns(M.promise()),
|
|
108
|
-
makeWithdrawInvitation: M.call().returns(M.promise()),
|
|
109
|
-
getPublicTopics: M.call().returns(TopicsRecordShape),
|
|
110
|
-
}),
|
|
111
|
-
feeRecipient: M.interface('feeRecipient', {
|
|
112
|
-
getContractFeeBalance: M.call().returns(AmountShape),
|
|
113
|
-
makeWithdrawFeesInvitation: M.call().returns(M.promise()),
|
|
114
|
-
}),
|
|
115
|
-
},
|
|
116
|
-
/**
|
|
117
|
-
* @param {ZCFMint<'nat'>} shareMint
|
|
118
|
-
* @param {Remote<StorageNode>} node
|
|
119
|
-
*/
|
|
120
|
-
(shareMint, node) => {
|
|
121
|
-
const { brand: PoolShares } = shareMint.getIssuerRecord();
|
|
122
|
-
const proposalShapes = makeProposalShapes({ USDC, PoolShares });
|
|
123
|
-
const shareWorth = makeParity(USDC, PoolShares);
|
|
124
|
-
const { zcfSeat: poolSeat } = zcf.makeEmptySeatKit();
|
|
125
|
-
const { zcfSeat: feeSeat } = zcf.makeEmptySeatKit();
|
|
126
|
-
const poolMetricsRecorderKit = tools.makeRecorderKit(
|
|
127
|
-
node,
|
|
128
|
-
PoolMetricsShape,
|
|
129
|
-
);
|
|
130
|
-
const encumberedBalance = makeEmpty(USDC);
|
|
131
|
-
/** @type {PoolStats} */
|
|
132
|
-
const poolStats = harden({
|
|
133
|
-
totalBorrows: makeEmpty(USDC),
|
|
134
|
-
totalContractFees: makeEmpty(USDC),
|
|
135
|
-
totalPoolFees: makeEmpty(USDC),
|
|
136
|
-
totalRepays: makeEmpty(USDC),
|
|
137
|
-
});
|
|
138
|
-
return {
|
|
139
|
-
/** used for `checkPoolBalance` invariant. aka 'outstanding borrows' */
|
|
140
|
-
encumberedBalance,
|
|
141
|
-
feeSeat,
|
|
142
|
-
poolStats,
|
|
143
|
-
poolMetricsRecorderKit,
|
|
144
|
-
poolSeat,
|
|
145
|
-
PoolShares,
|
|
146
|
-
proposalShapes,
|
|
147
|
-
shareMint,
|
|
148
|
-
shareWorth,
|
|
149
|
-
};
|
|
150
|
-
},
|
|
151
|
-
{
|
|
152
|
-
borrower: {
|
|
153
|
-
/**
|
|
154
|
-
* @param {ZCFSeat} toSeat
|
|
155
|
-
* @param {Amount<'nat'>} amount
|
|
156
|
-
*/
|
|
157
|
-
borrow(toSeat, amount) {
|
|
158
|
-
const { encumberedBalance, poolSeat, poolStats } = this.state;
|
|
159
|
-
|
|
160
|
-
// Validate amount is available in pool
|
|
161
|
-
const post = borrowCalc(
|
|
162
|
-
amount,
|
|
163
|
-
poolSeat.getAmountAllocated('USDC', USDC),
|
|
164
|
-
encumberedBalance,
|
|
165
|
-
poolStats,
|
|
166
|
-
);
|
|
167
|
-
|
|
168
|
-
// COMMIT POINT
|
|
169
|
-
// UNTIL #10684: ability to terminate an incarnation w/o terminating the contract
|
|
170
|
-
zcf.atomicRearrange(harden([[poolSeat, toSeat, { USDC: amount }]]));
|
|
171
|
-
|
|
172
|
-
Object.assign(this.state, post);
|
|
173
|
-
this.facets.external.publishPoolMetrics();
|
|
174
|
-
},
|
|
175
|
-
/**
|
|
176
|
-
* If something fails during advance, return funds to the pool.
|
|
177
|
-
*
|
|
178
|
-
* @param {ZCFSeat} borrowSeat
|
|
179
|
-
* @param {Amount<'nat'>} amount
|
|
180
|
-
*/
|
|
181
|
-
returnToPool(borrowSeat, amount) {
|
|
182
|
-
const { zcfSeat: repaySeat } = zcf.makeEmptySeatKit();
|
|
183
|
-
const returnAmounts = harden({
|
|
184
|
-
Principal: amount,
|
|
185
|
-
PoolFee: makeEmpty(USDC),
|
|
186
|
-
ContractFee: makeEmpty(USDC),
|
|
187
|
-
});
|
|
188
|
-
const borrowSeatAllocation = borrowSeat.getCurrentAllocation();
|
|
189
|
-
isGTE(borrowSeatAllocation.USDC, amount) ||
|
|
190
|
-
Fail`⚠️ borrowSeatAllocation ${q(borrowSeatAllocation)} less than amountKWR ${q(amount)}`;
|
|
191
|
-
// arrange payments in a format repay is expecting
|
|
192
|
-
zcf.atomicRearrange(
|
|
193
|
-
harden([[borrowSeat, repaySeat, { USDC: amount }, returnAmounts]]),
|
|
194
|
-
);
|
|
195
|
-
this.facets.repayer.repay(repaySeat, returnAmounts);
|
|
196
|
-
borrowSeat.exit();
|
|
197
|
-
repaySeat.exit();
|
|
198
|
-
},
|
|
199
|
-
},
|
|
200
|
-
repayer: {
|
|
201
|
-
/**
|
|
202
|
-
* @param {ZCFSeat} fromSeat
|
|
203
|
-
* @param {RepayAmountKWR} amounts
|
|
204
|
-
*/
|
|
205
|
-
repay(fromSeat, amounts) {
|
|
206
|
-
const {
|
|
207
|
-
encumberedBalance,
|
|
208
|
-
feeSeat,
|
|
209
|
-
poolSeat,
|
|
210
|
-
poolStats,
|
|
211
|
-
shareWorth,
|
|
212
|
-
} = this.state;
|
|
213
|
-
checkPoolBalance(
|
|
214
|
-
poolSeat.getCurrentAllocation(),
|
|
215
|
-
shareWorth,
|
|
216
|
-
encumberedBalance,
|
|
217
|
-
);
|
|
218
|
-
|
|
219
|
-
const fromSeatAllocation = fromSeat.getCurrentAllocation();
|
|
220
|
-
// Validate allocation equals amounts and Principal <= encumberedBalance
|
|
221
|
-
const post = repayCalc(
|
|
222
|
-
shareWorth,
|
|
223
|
-
fromSeatAllocation,
|
|
224
|
-
amounts,
|
|
225
|
-
encumberedBalance,
|
|
226
|
-
poolStats,
|
|
227
|
-
);
|
|
228
|
-
|
|
229
|
-
const { ContractFee, ...rest } = amounts;
|
|
230
|
-
|
|
231
|
-
// COMMIT POINT
|
|
232
|
-
// UNTIL #10684: ability to terminate an incarnation w/o terminating the contract
|
|
233
|
-
zcf.atomicRearrange(
|
|
234
|
-
harden([
|
|
235
|
-
[
|
|
236
|
-
fromSeat,
|
|
237
|
-
poolSeat,
|
|
238
|
-
rest,
|
|
239
|
-
{ USDC: add(amounts.PoolFee, amounts.Principal) },
|
|
240
|
-
],
|
|
241
|
-
[fromSeat, feeSeat, { ContractFee }, { USDC: ContractFee }],
|
|
242
|
-
]),
|
|
243
|
-
);
|
|
244
|
-
|
|
245
|
-
Object.assign(this.state, post);
|
|
246
|
-
this.facets.external.publishPoolMetrics();
|
|
247
|
-
},
|
|
248
|
-
},
|
|
249
|
-
external: {
|
|
250
|
-
publishPoolMetrics() {
|
|
251
|
-
const { poolStats, shareWorth, encumberedBalance } = this.state;
|
|
252
|
-
const { recorder } = this.state.poolMetricsRecorderKit;
|
|
253
|
-
// Consumers of this .write() are off-chain / outside the VM.
|
|
254
|
-
// And there's no way to recover from a failed write.
|
|
255
|
-
// So don't await.
|
|
256
|
-
void recorder.write({
|
|
257
|
-
encumberedBalance,
|
|
258
|
-
shareWorth,
|
|
259
|
-
...poolStats,
|
|
260
|
-
});
|
|
261
|
-
},
|
|
262
|
-
},
|
|
263
|
-
|
|
264
|
-
depositHandler: {
|
|
265
|
-
/** @param {ZCFSeat} lp */
|
|
266
|
-
async handle(lp) {
|
|
267
|
-
const { shareWorth, shareMint, poolSeat, encumberedBalance } =
|
|
268
|
-
this.state;
|
|
269
|
-
const { external } = this.facets;
|
|
270
|
-
|
|
271
|
-
/** @type {USDCProposalShapes['deposit']} */
|
|
272
|
-
// @ts-expect-error ensured by proposalShape
|
|
273
|
-
const proposal = lp.getProposal();
|
|
274
|
-
checkPoolBalance(
|
|
275
|
-
poolSeat.getCurrentAllocation(),
|
|
276
|
-
shareWorth,
|
|
277
|
-
encumberedBalance,
|
|
278
|
-
);
|
|
279
|
-
const post = depositCalc(shareWorth, proposal);
|
|
280
|
-
|
|
281
|
-
// COMMIT POINT
|
|
282
|
-
const mint = shareMint.mintGains(post.payouts);
|
|
283
|
-
try {
|
|
284
|
-
this.state.shareWorth = post.shareWorth;
|
|
285
|
-
zcf.atomicRearrange(
|
|
286
|
-
harden([
|
|
287
|
-
// zoe guarantees lp has proposal.give allocated
|
|
288
|
-
[lp, poolSeat, proposal.give],
|
|
289
|
-
// mintGains() above establishes that mint has post.payouts
|
|
290
|
-
[mint, lp, post.payouts],
|
|
291
|
-
]),
|
|
292
|
-
);
|
|
293
|
-
} catch (cause) {
|
|
294
|
-
// UNTIL #10684: ability to terminate an incarnation w/o terminating the contract
|
|
295
|
-
throw new Error('🚨 cannot commit deposit', { cause });
|
|
296
|
-
} finally {
|
|
297
|
-
lp.exit();
|
|
298
|
-
mint.exit();
|
|
299
|
-
}
|
|
300
|
-
external.publishPoolMetrics();
|
|
301
|
-
},
|
|
302
|
-
},
|
|
303
|
-
withdrawHandler: {
|
|
304
|
-
/** @param {ZCFSeat} lp */
|
|
305
|
-
async handle(lp) {
|
|
306
|
-
const { shareWorth, shareMint, poolSeat, encumberedBalance } =
|
|
307
|
-
this.state;
|
|
308
|
-
const { external } = this.facets;
|
|
309
|
-
|
|
310
|
-
/** @type {USDCProposalShapes['withdraw']} */
|
|
311
|
-
// @ts-expect-error ensured by proposalShape
|
|
312
|
-
const proposal = lp.getProposal();
|
|
313
|
-
const { zcfSeat: burn } = zcf.makeEmptySeatKit();
|
|
314
|
-
const post = withdrawCalc(
|
|
315
|
-
shareWorth,
|
|
316
|
-
proposal,
|
|
317
|
-
poolSeat.getCurrentAllocation(),
|
|
318
|
-
encumberedBalance,
|
|
319
|
-
);
|
|
320
|
-
|
|
321
|
-
// COMMIT POINT
|
|
322
|
-
try {
|
|
323
|
-
this.state.shareWorth = post.shareWorth;
|
|
324
|
-
zcf.atomicRearrange(
|
|
325
|
-
harden([
|
|
326
|
-
// zoe guarantees lp has proposal.give allocated
|
|
327
|
-
[lp, burn, proposal.give],
|
|
328
|
-
// checkPoolBalance() + withdrawCalc() guarantee poolSeat has enough
|
|
329
|
-
[poolSeat, lp, post.payouts],
|
|
330
|
-
]),
|
|
331
|
-
);
|
|
332
|
-
shareMint.burnLosses(proposal.give, burn);
|
|
333
|
-
} catch (cause) {
|
|
334
|
-
// UNTIL #10684: ability to terminate an incarnation w/o terminating the contract
|
|
335
|
-
throw new Error('🚨 cannot commit withdraw', { cause });
|
|
336
|
-
} finally {
|
|
337
|
-
lp.exit();
|
|
338
|
-
burn.exit();
|
|
339
|
-
}
|
|
340
|
-
external.publishPoolMetrics();
|
|
341
|
-
},
|
|
342
|
-
},
|
|
343
|
-
withdrawFeesHandler: {
|
|
344
|
-
/** @param {ZCFSeat} seat */
|
|
345
|
-
async handle(seat) {
|
|
346
|
-
const { feeSeat } = this.state;
|
|
347
|
-
|
|
348
|
-
const { want } = seat.getProposal();
|
|
349
|
-
const available = feeSeat.getAmountAllocated('USDC', want.USDC.brand);
|
|
350
|
-
isGTE(available, want.USDC) ||
|
|
351
|
-
Fail`cannot withdraw ${want.USDC}; only ${available} available`;
|
|
352
|
-
|
|
353
|
-
// COMMIT POINT
|
|
354
|
-
zcf.atomicRearrange(harden([[feeSeat, seat, want]]));
|
|
355
|
-
seat.exit();
|
|
356
|
-
},
|
|
357
|
-
},
|
|
358
|
-
public: {
|
|
359
|
-
makeDepositInvitation() {
|
|
360
|
-
return zcf.makeInvitation(
|
|
361
|
-
this.facets.depositHandler,
|
|
362
|
-
'Deposit',
|
|
363
|
-
undefined,
|
|
364
|
-
this.state.proposalShapes.deposit,
|
|
365
|
-
);
|
|
366
|
-
},
|
|
367
|
-
makeWithdrawInvitation() {
|
|
368
|
-
return zcf.makeInvitation(
|
|
369
|
-
this.facets.withdrawHandler,
|
|
370
|
-
'Withdraw',
|
|
371
|
-
undefined,
|
|
372
|
-
this.state.proposalShapes.withdraw,
|
|
373
|
-
);
|
|
374
|
-
},
|
|
375
|
-
getPublicTopics() {
|
|
376
|
-
const { poolMetricsRecorderKit } = this.state;
|
|
377
|
-
return {
|
|
378
|
-
poolMetrics: makeRecorderTopic(
|
|
379
|
-
'poolMetrics',
|
|
380
|
-
poolMetricsRecorderKit,
|
|
381
|
-
),
|
|
382
|
-
};
|
|
383
|
-
},
|
|
384
|
-
},
|
|
385
|
-
feeRecipient: {
|
|
386
|
-
getContractFeeBalance() {
|
|
387
|
-
const { feeSeat } = this.state;
|
|
388
|
-
/** @type {Amount<'nat'>} */
|
|
389
|
-
const balance = feeSeat.getCurrentAllocation().USDC;
|
|
390
|
-
return balance;
|
|
391
|
-
},
|
|
392
|
-
makeWithdrawFeesInvitation() {
|
|
393
|
-
return zcf.makeInvitation(
|
|
394
|
-
this.facets.withdrawFeesHandler,
|
|
395
|
-
'Withdraw Fees',
|
|
396
|
-
undefined,
|
|
397
|
-
this.state.proposalShapes.withdrawFees,
|
|
398
|
-
);
|
|
399
|
-
},
|
|
400
|
-
},
|
|
401
|
-
},
|
|
402
|
-
{
|
|
403
|
-
finish: ({ facets: { external } }) => {
|
|
404
|
-
void external.publishPoolMetrics();
|
|
405
|
-
},
|
|
406
|
-
stateShape,
|
|
407
|
-
},
|
|
408
|
-
);
|
|
409
|
-
};
|
|
410
|
-
harden(prepareLiquidityPoolKit);
|
|
411
|
-
|
|
412
|
-
/**
|
|
413
|
-
* @typedef {ReturnType<ReturnType<typeof prepareLiquidityPoolKit>>} LiquidityPoolKit
|
|
414
|
-
*/
|
package/src/exos/operator-kit.js
DELETED
|
@@ -1,124 +0,0 @@
|
|
|
1
|
-
import { makeTracer } from '@agoric/internal';
|
|
2
|
-
import { Fail } from '@endo/errors';
|
|
3
|
-
import { M } from '@endo/patterns';
|
|
4
|
-
import { CctpTxEvidenceShape, RiskAssessmentShape } from '../type-guards.js';
|
|
5
|
-
|
|
6
|
-
const trace = makeTracer('TxOperator');
|
|
7
|
-
|
|
8
|
-
/**
|
|
9
|
-
* @import {Zone} from '@agoric/zone';
|
|
10
|
-
* @import {CctpTxEvidence, RiskAssessment} from '../types.js';
|
|
11
|
-
*/
|
|
12
|
-
|
|
13
|
-
/**
|
|
14
|
-
* @typedef {object} OperatorPowers
|
|
15
|
-
* @property {(evidence: CctpTxEvidence, riskAssessment: RiskAssessment, operatorId: string) => void} attest
|
|
16
|
-
*/
|
|
17
|
-
|
|
18
|
-
/**
|
|
19
|
-
* @typedef {object} OperatorStatus
|
|
20
|
-
* @property {boolean} [disabled]
|
|
21
|
-
* @property {string} operatorId
|
|
22
|
-
*/
|
|
23
|
-
|
|
24
|
-
/**
|
|
25
|
-
* @typedef {Readonly<{ operatorId: string, powers: OperatorPowers }> & {disabled: boolean}} State
|
|
26
|
-
*/
|
|
27
|
-
|
|
28
|
-
const OperatorKitI = {
|
|
29
|
-
admin: M.interface('Admin', {
|
|
30
|
-
disable: M.call().returns(),
|
|
31
|
-
}),
|
|
32
|
-
|
|
33
|
-
invitationMakers: M.interface('InvitationMakers', {
|
|
34
|
-
SubmitEvidence: M.call(CctpTxEvidenceShape)
|
|
35
|
-
.optional(RiskAssessmentShape)
|
|
36
|
-
.returns(M.promise()),
|
|
37
|
-
}),
|
|
38
|
-
|
|
39
|
-
operator: M.interface('Operator', {
|
|
40
|
-
submitEvidence: M.call(CctpTxEvidenceShape)
|
|
41
|
-
.optional(RiskAssessmentShape)
|
|
42
|
-
.returns(),
|
|
43
|
-
getStatus: M.call().returns(M.record()),
|
|
44
|
-
}),
|
|
45
|
-
};
|
|
46
|
-
|
|
47
|
-
/**
|
|
48
|
-
* @param {Zone} zone
|
|
49
|
-
* @param {{ makeInertInvitation: Function }} staticPowers
|
|
50
|
-
*/
|
|
51
|
-
export const prepareOperatorKit = (zone, staticPowers) =>
|
|
52
|
-
zone.exoClassKit(
|
|
53
|
-
'Operator Kit',
|
|
54
|
-
OperatorKitI,
|
|
55
|
-
/**
|
|
56
|
-
* @param {string} operatorId
|
|
57
|
-
* @param {OperatorPowers} powers facet of the durable transaction feed
|
|
58
|
-
* @returns {State}
|
|
59
|
-
*/
|
|
60
|
-
(operatorId, powers) => {
|
|
61
|
-
return {
|
|
62
|
-
operatorId,
|
|
63
|
-
powers,
|
|
64
|
-
disabled: false,
|
|
65
|
-
};
|
|
66
|
-
},
|
|
67
|
-
{
|
|
68
|
-
admin: {
|
|
69
|
-
disable() {
|
|
70
|
-
trace(`operator ${this.state.operatorId} disabled`);
|
|
71
|
-
this.state.disabled = true;
|
|
72
|
-
},
|
|
73
|
-
},
|
|
74
|
-
/**
|
|
75
|
-
* NB: when this kit is an offer result, the smart-wallet will detect the `invitationMakers`
|
|
76
|
-
* key and save it for future offers.
|
|
77
|
-
*/
|
|
78
|
-
invitationMakers: {
|
|
79
|
-
/**
|
|
80
|
-
* Provide an API call in the form of an invitation maker, so that the
|
|
81
|
-
* capability is available in the smart-wallet bridge.
|
|
82
|
-
*
|
|
83
|
-
* NB: The `Invitation` object is evidence that the operation took
|
|
84
|
-
* place, rather than as a means of performing it as in the
|
|
85
|
-
* fluxAggregator contract used for price oracles.
|
|
86
|
-
*
|
|
87
|
-
* @param {CctpTxEvidence} evidence
|
|
88
|
-
* @param {RiskAssessment} [riskAssessment]
|
|
89
|
-
* @returns {Promise<Invitation>}
|
|
90
|
-
*/
|
|
91
|
-
async SubmitEvidence(evidence, riskAssessment) {
|
|
92
|
-
const { operator } = this.facets;
|
|
93
|
-
operator.submitEvidence(evidence, riskAssessment);
|
|
94
|
-
return staticPowers.makeInertInvitation(
|
|
95
|
-
'evidence was pushed in the invitation maker call',
|
|
96
|
-
);
|
|
97
|
-
},
|
|
98
|
-
},
|
|
99
|
-
operator: {
|
|
100
|
-
/**
|
|
101
|
-
* submit evidence from this operator
|
|
102
|
-
*
|
|
103
|
-
* @param {CctpTxEvidence} evidence
|
|
104
|
-
* @param {RiskAssessment} [riskAssessment]
|
|
105
|
-
* @returns {void}
|
|
106
|
-
*/
|
|
107
|
-
submitEvidence(evidence, riskAssessment = {}) {
|
|
108
|
-
const { state } = this;
|
|
109
|
-
!state.disabled || Fail`submitEvidence for disabled operator`;
|
|
110
|
-
state.powers.attest(evidence, riskAssessment, state.operatorId);
|
|
111
|
-
},
|
|
112
|
-
/** @returns {OperatorStatus} */
|
|
113
|
-
getStatus() {
|
|
114
|
-
const { state } = this;
|
|
115
|
-
return {
|
|
116
|
-
operatorId: state.operatorId,
|
|
117
|
-
disabled: state.disabled,
|
|
118
|
-
};
|
|
119
|
-
},
|
|
120
|
-
},
|
|
121
|
-
},
|
|
122
|
-
);
|
|
123
|
-
|
|
124
|
-
/** @typedef {ReturnType<ReturnType<typeof prepareOperatorKit>>} OperatorKit */
|