@agoric/fast-usdc 0.1.1-dev-b1e63c2.0 → 0.1.1-dev-92714b3.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/package.json +15 -15
- package/src/exos/advancer.js +0 -1
- package/src/exos/settler.js +18 -6
- package/src/fast-usdc.contract.js +6 -1
- package/src/utils/store.js +119 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agoric/fast-usdc",
|
|
3
|
-
"version": "0.1.1-dev-
|
|
3
|
+
"version": "0.1.1-dev-92714b3.0+92714b3",
|
|
4
4
|
"description": "CLI and library for Fast USDC product",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"files": [
|
|
@@ -23,9 +23,9 @@
|
|
|
23
23
|
"lint:eslint": "eslint ."
|
|
24
24
|
},
|
|
25
25
|
"devDependencies": {
|
|
26
|
-
"@agoric/swingset-liveslots": "0.10.3-dev-
|
|
27
|
-
"@agoric/vats": "0.15.2-dev-
|
|
28
|
-
"@agoric/zone": "0.2.3-dev-
|
|
26
|
+
"@agoric/swingset-liveslots": "0.10.3-dev-92714b3.0+92714b3",
|
|
27
|
+
"@agoric/vats": "0.15.2-dev-92714b3.0+92714b3",
|
|
28
|
+
"@agoric/zone": "0.2.3-dev-92714b3.0+92714b3",
|
|
29
29
|
"@fast-check/ava": "^2.0.1",
|
|
30
30
|
"ava": "^5.3.0",
|
|
31
31
|
"c8": "^10.1.2",
|
|
@@ -33,16 +33,16 @@
|
|
|
33
33
|
"ts-blank-space": "^0.4.4"
|
|
34
34
|
},
|
|
35
35
|
"dependencies": {
|
|
36
|
-
"@agoric/client-utils": "0.1.1-dev-
|
|
37
|
-
"@agoric/cosmic-proto": "0.4.1-dev-
|
|
38
|
-
"@agoric/ertp": "0.16.3-dev-
|
|
39
|
-
"@agoric/internal": "0.3.3-dev-
|
|
40
|
-
"@agoric/notifier": "0.6.3-dev-
|
|
41
|
-
"@agoric/orchestration": "0.1.1-dev-
|
|
42
|
-
"@agoric/store": "0.9.3-dev-
|
|
43
|
-
"@agoric/vat-data": "0.5.3-dev-
|
|
44
|
-
"@agoric/vow": "0.1.1-dev-
|
|
45
|
-
"@agoric/zoe": "0.26.3-dev-
|
|
36
|
+
"@agoric/client-utils": "0.1.1-dev-92714b3.0+92714b3",
|
|
37
|
+
"@agoric/cosmic-proto": "0.4.1-dev-92714b3.0+92714b3",
|
|
38
|
+
"@agoric/ertp": "0.16.3-dev-92714b3.0+92714b3",
|
|
39
|
+
"@agoric/internal": "0.3.3-dev-92714b3.0+92714b3",
|
|
40
|
+
"@agoric/notifier": "0.6.3-dev-92714b3.0+92714b3",
|
|
41
|
+
"@agoric/orchestration": "0.1.1-dev-92714b3.0+92714b3",
|
|
42
|
+
"@agoric/store": "0.9.3-dev-92714b3.0+92714b3",
|
|
43
|
+
"@agoric/vat-data": "0.5.3-dev-92714b3.0+92714b3",
|
|
44
|
+
"@agoric/vow": "0.1.1-dev-92714b3.0+92714b3",
|
|
45
|
+
"@agoric/zoe": "0.26.3-dev-92714b3.0+92714b3",
|
|
46
46
|
"@cosmjs/proto-signing": "^0.32.4",
|
|
47
47
|
"@cosmjs/stargate": "^0.32.4",
|
|
48
48
|
"@endo/base64": "^1.0.9",
|
|
@@ -82,5 +82,5 @@
|
|
|
82
82
|
"publishConfig": {
|
|
83
83
|
"access": "public"
|
|
84
84
|
},
|
|
85
|
-
"gitHead": "
|
|
85
|
+
"gitHead": "92714b306af99c26bd765f94dce5efea889b66ed"
|
|
86
86
|
}
|
package/src/exos/advancer.js
CHANGED
package/src/exos/settler.js
CHANGED
|
@@ -13,6 +13,7 @@ import {
|
|
|
13
13
|
EvmHashShape,
|
|
14
14
|
makeNatAmountShape,
|
|
15
15
|
} from '../type-guards.js';
|
|
16
|
+
import { asMultiset } from '../utils/store.js';
|
|
16
17
|
|
|
17
18
|
/**
|
|
18
19
|
* @import {FungibleTokenPacketData} from '@agoric/cosmic-proto/ibc/applications/transfer/v2/packet.js';
|
|
@@ -149,6 +150,7 @@ export const prepareSettler = (
|
|
|
149
150
|
).returns(M.boolean()),
|
|
150
151
|
}),
|
|
151
152
|
self: M.interface('SettlerSelfI', {
|
|
153
|
+
addMintedEarly: M.call(M.string(), M.nat()).returns(),
|
|
152
154
|
disburse: M.call(EvmHashShape, M.nat()).returns(M.promise()),
|
|
153
155
|
forward: M.call(EvmHashShape, M.nat(), M.string()).returns(),
|
|
154
156
|
}),
|
|
@@ -174,8 +176,8 @@ export const prepareSettler = (
|
|
|
174
176
|
intermediateRecipient: config.intermediateRecipient,
|
|
175
177
|
/** @type {HostInterface<TargetRegistration>|undefined} */
|
|
176
178
|
registration: undefined,
|
|
177
|
-
/** @type {
|
|
178
|
-
mintedEarly: zone.detached().
|
|
179
|
+
/** @type {MapStore<ReturnType<typeof makeMintedEarlyKey>, number>} */
|
|
180
|
+
mintedEarly: zone.detached().mapStore('mintedEarly'),
|
|
179
181
|
};
|
|
180
182
|
},
|
|
181
183
|
{
|
|
@@ -221,7 +223,7 @@ export const prepareSettler = (
|
|
|
221
223
|
|
|
222
224
|
case PendingTxStatus.Advancing:
|
|
223
225
|
log('⚠️ tap: minted while advancing', nfa, amount);
|
|
224
|
-
|
|
226
|
+
self.addMintedEarly(nfa, amount);
|
|
225
227
|
return;
|
|
226
228
|
|
|
227
229
|
case PendingTxStatus.Observed:
|
|
@@ -234,7 +236,7 @@ export const prepareSettler = (
|
|
|
234
236
|
log('⚠️ tap: minted before observed', nfa, amount);
|
|
235
237
|
// XXX consider capturing in vstorage
|
|
236
238
|
// we would need a new key, as this does not have a txHash
|
|
237
|
-
|
|
239
|
+
self.addMintedEarly(nfa, amount);
|
|
238
240
|
}
|
|
239
241
|
},
|
|
240
242
|
},
|
|
@@ -256,7 +258,7 @@ export const prepareSettler = (
|
|
|
256
258
|
const { value: fullValue } = fullAmount;
|
|
257
259
|
const key = makeMintedEarlyKey(forwardingAddress, fullValue);
|
|
258
260
|
if (mintedEarly.has(key)) {
|
|
259
|
-
mintedEarly.
|
|
261
|
+
asMultiset(mintedEarly).remove(key);
|
|
260
262
|
statusManager.advanceOutcomeForMintedEarly(txHash, success);
|
|
261
263
|
if (success) {
|
|
262
264
|
void this.facets.self.disburse(txHash, fullValue);
|
|
@@ -290,7 +292,7 @@ export const prepareSettler = (
|
|
|
290
292
|
forwardingAddress,
|
|
291
293
|
amount,
|
|
292
294
|
);
|
|
293
|
-
mintedEarly.
|
|
295
|
+
asMultiset(mintedEarly).remove(key);
|
|
294
296
|
statusManager.advanceOutcomeForUnknownMint(evidence);
|
|
295
297
|
void this.facets.self.forward(txHash, amount, destination.value);
|
|
296
298
|
return true;
|
|
@@ -299,6 +301,16 @@ export const prepareSettler = (
|
|
|
299
301
|
},
|
|
300
302
|
},
|
|
301
303
|
self: {
|
|
304
|
+
/**
|
|
305
|
+
* Helper function to track a minted-early transaction by incrementing or initializing its counter
|
|
306
|
+
* @param {NobleAddress} address
|
|
307
|
+
* @param {NatValue} amount
|
|
308
|
+
*/
|
|
309
|
+
addMintedEarly(address, amount) {
|
|
310
|
+
const key = makeMintedEarlyKey(address, amount);
|
|
311
|
+
const { mintedEarly } = this.state;
|
|
312
|
+
asMultiset(mintedEarly).add(key);
|
|
313
|
+
},
|
|
302
314
|
/**
|
|
303
315
|
* @param {EvmHash} txHash
|
|
304
316
|
* @param {NatValue} fullValue
|
|
@@ -175,7 +175,12 @@ export const contract = async (zcf, privateArgs, zone, tools) => {
|
|
|
175
175
|
trace('connectToNoble', agoricChainId, nobleChainId, agoricToNoble);
|
|
176
176
|
chainHub.updateConnection(agoricChainId, nobleChainId, agoricToNoble);
|
|
177
177
|
// v1 has `NobleAccount` which we don't expect to ever settle.
|
|
178
|
-
|
|
178
|
+
// Including the connection_id in the zone key lets us use
|
|
179
|
+
// this before and after null-upgrade in multichain-testing.
|
|
180
|
+
const nobleAccountV = zone.makeOnce(
|
|
181
|
+
`NobleICA-${agoricToNoble.counterparty.connection_id}`,
|
|
182
|
+
() => makeNobleAccount(),
|
|
183
|
+
);
|
|
179
184
|
|
|
180
185
|
return vowTools.when(nobleAccountV, nobleAccount => {
|
|
181
186
|
trace('nobleAccount', nobleAccount);
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import { Fail } from '@endo/errors';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @import {Key} from '@endo/patterns';
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
// TODO provide something like this in a more common place, perhaps as a BagStore
|
|
8
|
+
/**
|
|
9
|
+
* Creates a bag (multi-set) API that wraps a MapStore where values are counts.
|
|
10
|
+
*
|
|
11
|
+
* @template {Key} K
|
|
12
|
+
* @param {MapStore<K, number>} mapStore
|
|
13
|
+
*/
|
|
14
|
+
export const asMultiset = mapStore =>
|
|
15
|
+
harden({
|
|
16
|
+
/**
|
|
17
|
+
* Add an item to the bag, incrementing its count.
|
|
18
|
+
*
|
|
19
|
+
* @param {K} item The item to add
|
|
20
|
+
* @param {number} [count] How many to add (defaults to 1)
|
|
21
|
+
*/
|
|
22
|
+
add: (item, count = 1) => {
|
|
23
|
+
if (count <= 0) {
|
|
24
|
+
throw Fail`Cannot add a non-positive count ${count} to bag`;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
if (mapStore.has(item)) {
|
|
28
|
+
const currentCount = mapStore.get(item);
|
|
29
|
+
mapStore.set(item, currentCount + count);
|
|
30
|
+
} else {
|
|
31
|
+
mapStore.init(item, count);
|
|
32
|
+
}
|
|
33
|
+
},
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Remove an item from the bag, decrementing its count. If count reaches
|
|
37
|
+
* zero, the item is removed completely.
|
|
38
|
+
*
|
|
39
|
+
* @param {K} item The item to remove
|
|
40
|
+
* @param {number} [count] How many to remove (defaults to 1)
|
|
41
|
+
* @returns {boolean} Whether the removal was successful
|
|
42
|
+
* @throws {Error} If trying to remove more items than exist
|
|
43
|
+
*/
|
|
44
|
+
remove: (item, count = 1) => {
|
|
45
|
+
if (count <= 0) {
|
|
46
|
+
throw Fail`Cannot remove a non-positive count ${count} from bag`;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
if (!mapStore.has(item)) {
|
|
50
|
+
return false;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
const currentCount = mapStore.get(item);
|
|
54
|
+
if (currentCount < count) {
|
|
55
|
+
throw Fail`Cannot remove ${count} of ${item} from bag; only ${currentCount} exist`;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
if (currentCount === count) {
|
|
59
|
+
mapStore.delete(item);
|
|
60
|
+
} else {
|
|
61
|
+
mapStore.set(item, currentCount - count);
|
|
62
|
+
}
|
|
63
|
+
return true;
|
|
64
|
+
},
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Get the count of an item in the bag.
|
|
68
|
+
*
|
|
69
|
+
* @param {K} item The item to check
|
|
70
|
+
* @returns {number} The count (0 if not present)
|
|
71
|
+
*/
|
|
72
|
+
count: item => {
|
|
73
|
+
return mapStore.has(item) ? mapStore.get(item) : 0;
|
|
74
|
+
},
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Check if the bag contains at least one of the item.
|
|
78
|
+
*
|
|
79
|
+
* @param {K} item The item to check
|
|
80
|
+
* @returns {boolean} Whether the item is in the bag
|
|
81
|
+
*/
|
|
82
|
+
has: item => {
|
|
83
|
+
return mapStore.has(item);
|
|
84
|
+
},
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Get all unique items in the bag.
|
|
88
|
+
*
|
|
89
|
+
* @returns {Iterable<K>} Iterable of unique items
|
|
90
|
+
*/
|
|
91
|
+
keys: () => {
|
|
92
|
+
return mapStore.keys();
|
|
93
|
+
},
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* Get all entries (item, count) in the bag.
|
|
97
|
+
*
|
|
98
|
+
* @returns {Iterable<[K, number]>} Iterable of [item, count] pairs
|
|
99
|
+
*/
|
|
100
|
+
entries: () => {
|
|
101
|
+
return mapStore.entries();
|
|
102
|
+
},
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* Get the total number of unique items in the bag.
|
|
106
|
+
*
|
|
107
|
+
* @returns {number} Number of unique items
|
|
108
|
+
*/
|
|
109
|
+
size: () => {
|
|
110
|
+
return mapStore.getSize();
|
|
111
|
+
},
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* Remove all items from the bag.
|
|
115
|
+
*/
|
|
116
|
+
clear: () => {
|
|
117
|
+
mapStore.clear();
|
|
118
|
+
},
|
|
119
|
+
});
|