@agoric/orchestration 0.1.1-dev-2e2466e.0 → 0.1.1-dev-dcca603.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 +14 -14
- package/src/exos/stakingAccountKit.js +106 -74
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agoric/orchestration",
|
|
3
|
-
"version": "0.1.1-dev-
|
|
3
|
+
"version": "0.1.1-dev-dcca603.0+dcca603",
|
|
4
4
|
"description": "Chain abstraction for Agoric's orchestration clients",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "index.js",
|
|
@@ -29,18 +29,18 @@
|
|
|
29
29
|
},
|
|
30
30
|
"homepage": "https://github.com/Agoric/agoric-sdk#readme",
|
|
31
31
|
"dependencies": {
|
|
32
|
-
"@agoric/assert": "0.6.1-dev-
|
|
33
|
-
"@agoric/cosmic-proto": "0.4.1-dev-
|
|
34
|
-
"@agoric/ertp": "0.16.3-dev-
|
|
35
|
-
"@agoric/internal": "0.3.3-dev-
|
|
36
|
-
"@agoric/network": "0.1.1-dev-
|
|
37
|
-
"@agoric/notifier": "0.6.3-dev-
|
|
38
|
-
"@agoric/store": "0.9.3-dev-
|
|
39
|
-
"@agoric/time": "0.3.3-dev-
|
|
40
|
-
"@agoric/vat-data": "0.5.3-dev-
|
|
41
|
-
"@agoric/vats": "0.15.2-dev-
|
|
42
|
-
"@agoric/zoe": "0.26.3-dev-
|
|
43
|
-
"@agoric/zone": "0.2.3-dev-
|
|
32
|
+
"@agoric/assert": "0.6.1-dev-dcca603.0+dcca603",
|
|
33
|
+
"@agoric/cosmic-proto": "0.4.1-dev-dcca603.0+dcca603",
|
|
34
|
+
"@agoric/ertp": "0.16.3-dev-dcca603.0+dcca603",
|
|
35
|
+
"@agoric/internal": "0.3.3-dev-dcca603.0+dcca603",
|
|
36
|
+
"@agoric/network": "0.1.1-dev-dcca603.0+dcca603",
|
|
37
|
+
"@agoric/notifier": "0.6.3-dev-dcca603.0+dcca603",
|
|
38
|
+
"@agoric/store": "0.9.3-dev-dcca603.0+dcca603",
|
|
39
|
+
"@agoric/time": "0.3.3-dev-dcca603.0+dcca603",
|
|
40
|
+
"@agoric/vat-data": "0.5.3-dev-dcca603.0+dcca603",
|
|
41
|
+
"@agoric/vats": "0.15.2-dev-dcca603.0+dcca603",
|
|
42
|
+
"@agoric/zoe": "0.26.3-dev-dcca603.0+dcca603",
|
|
43
|
+
"@agoric/zone": "0.2.3-dev-dcca603.0+dcca603",
|
|
44
44
|
"@endo/base64": "^1.0.4",
|
|
45
45
|
"@endo/far": "^1.1.1",
|
|
46
46
|
"@endo/marshal": "^1.4.1",
|
|
@@ -82,5 +82,5 @@
|
|
|
82
82
|
"typeCoverage": {
|
|
83
83
|
"atLeast": 96.39
|
|
84
84
|
},
|
|
85
|
-
"gitHead": "
|
|
85
|
+
"gitHead": "dcca603cec5ba954773f176058c6e5a0360a3b2f"
|
|
86
86
|
}
|
|
@@ -1,9 +1,14 @@
|
|
|
1
1
|
// @ts-check
|
|
2
2
|
/** @file Use-object for the owner of a staking account */
|
|
3
|
+
import {
|
|
4
|
+
MsgWithdrawDelegatorReward,
|
|
5
|
+
MsgWithdrawDelegatorRewardResponse,
|
|
6
|
+
} from '@agoric/cosmic-proto/cosmos/distribution/v1beta1/tx.js';
|
|
3
7
|
import {
|
|
4
8
|
MsgDelegate,
|
|
5
9
|
MsgDelegateResponse,
|
|
6
10
|
} from '@agoric/cosmic-proto/cosmos/staking/v1beta1/tx.js';
|
|
11
|
+
import { Any } from '@agoric/cosmic-proto/google/protobuf/any.js';
|
|
7
12
|
import { AmountShape } from '@agoric/ertp';
|
|
8
13
|
import { makeTracer } from '@agoric/internal';
|
|
9
14
|
import { UnguardedHelperI } from '@agoric/internal/src/typeGuards.js';
|
|
@@ -11,10 +16,9 @@ import { M, prepareExoClassKit } from '@agoric/vat-data';
|
|
|
11
16
|
import { TopicsRecordShape } from '@agoric/zoe/src/contractSupport/index.js';
|
|
12
17
|
import { decodeBase64 } from '@endo/base64';
|
|
13
18
|
import { E } from '@endo/far';
|
|
14
|
-
import { Any } from '@agoric/cosmic-proto/google/protobuf/any.js';
|
|
15
19
|
|
|
16
20
|
/**
|
|
17
|
-
* @import { ChainAccount, ChainAddress } from '../types.js';
|
|
21
|
+
* @import { ChainAccount, ChainAddress, ChainAmount, CosmosValidatorAddress } from '../types.js';
|
|
18
22
|
* @import { RecorderKit, MakeRecorderKit } from '@agoric/zoe/src/contractSupport/recorder.js';
|
|
19
23
|
* @import { Baggage } from '@agoric/swingset-liveslots';
|
|
20
24
|
* @import {AnyJson} from '@agoric/cosmic-proto';
|
|
@@ -38,10 +42,8 @@ const { Fail } = assert;
|
|
|
38
42
|
|
|
39
43
|
const HolderI = M.interface('holder', {
|
|
40
44
|
getPublicTopics: M.call().returns(TopicsRecordShape),
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
makeTransferAccountInvitation: M.call().returns(M.promise()),
|
|
44
|
-
delegate: M.callWhen(M.string(), AmountShape).returns(M.string()),
|
|
45
|
+
delegate: M.callWhen(M.string(), AmountShape).returns(M.record()),
|
|
46
|
+
withdrawReward: M.callWhen(M.string()).returns(M.array()),
|
|
45
47
|
});
|
|
46
48
|
|
|
47
49
|
/** @type {{ [name: string]: [description: string, valueShape: Pattern] }} */
|
|
@@ -49,6 +51,33 @@ const PUBLIC_TOPICS = {
|
|
|
49
51
|
account: ['Staking Account holder status', M.any()],
|
|
50
52
|
};
|
|
51
53
|
|
|
54
|
+
// UNTIL https://github.com/cosmology-tech/telescope/issues/605
|
|
55
|
+
/**
|
|
56
|
+
* @param {Any} x
|
|
57
|
+
* @returns {AnyJson}
|
|
58
|
+
*/
|
|
59
|
+
const toAnyJSON = x => /** @type {AnyJson} */ (Any.toJSON(x));
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* @template T
|
|
63
|
+
* @param {string} ackStr
|
|
64
|
+
* @param {(p: {typeUrl: string, value: Uint8Array}) => T} fromProtoMsg
|
|
65
|
+
*/
|
|
66
|
+
export const tryDecodeResponse = (ackStr, fromProtoMsg) => {
|
|
67
|
+
try {
|
|
68
|
+
const any = Any.decode(decodeBase64(ackStr));
|
|
69
|
+
const protoMsg = Any.decode(any.value);
|
|
70
|
+
|
|
71
|
+
const msg = fromProtoMsg(protoMsg);
|
|
72
|
+
return msg;
|
|
73
|
+
} catch (cause) {
|
|
74
|
+
throw assert.error(`bad response: ${ackStr}`, undefined, { cause });
|
|
75
|
+
}
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
/** @type {(c: { denom: string, amount: string }) => ChainAmount} */
|
|
79
|
+
const toChainAmount = c => ({ denom: c.denom, value: BigInt(c.amount) });
|
|
80
|
+
|
|
52
81
|
/**
|
|
53
82
|
* @param {Baggage} baggage
|
|
54
83
|
* @param {MakeRecorderKit} makeRecorderKit
|
|
@@ -62,10 +91,10 @@ export const prepareStakingAccountKit = (baggage, makeRecorderKit, zcf) => {
|
|
|
62
91
|
helper: UnguardedHelperI,
|
|
63
92
|
holder: HolderI,
|
|
64
93
|
invitationMakers: M.interface('invitationMakers', {
|
|
65
|
-
Delegate:
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
94
|
+
Delegate: M.call(M.string(), AmountShape).returns(M.promise()),
|
|
95
|
+
WithdrawReward: M.call(M.string()).returns(M.promise()),
|
|
96
|
+
CloseAccount: M.call().returns(M.promise()),
|
|
97
|
+
TransferAccount: M.call().returns(M.promise()),
|
|
69
98
|
}),
|
|
70
99
|
},
|
|
71
100
|
/**
|
|
@@ -93,58 +122,39 @@ export const prepareStakingAccountKit = (baggage, makeRecorderKit, zcf) => {
|
|
|
93
122
|
getUpdater() {
|
|
94
123
|
return this.state.topicKit.recorder;
|
|
95
124
|
},
|
|
96
|
-
|
|
97
|
-
|
|
125
|
+
},
|
|
126
|
+
invitationMakers: {
|
|
98
127
|
/**
|
|
99
|
-
*
|
|
128
|
+
*
|
|
100
129
|
* @param {string} validatorAddress
|
|
101
|
-
* @param {Amount<'nat'>}
|
|
130
|
+
* @param {Amount<'nat'>} amount
|
|
102
131
|
*/
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
// FIXME brand handling and amount scaling
|
|
106
|
-
const amount = {
|
|
107
|
-
amount: String(ertpAmount.value),
|
|
108
|
-
denom: 'uatom',
|
|
109
|
-
};
|
|
110
|
-
|
|
111
|
-
const account = this.facets.helper.owned();
|
|
112
|
-
const delegatorAddress = this.state.chainAddress.address;
|
|
113
|
-
|
|
114
|
-
const result = await E(account).executeEncodedTx([
|
|
115
|
-
/** @type {AnyJson} */ (
|
|
116
|
-
Any.toJSON(
|
|
117
|
-
MsgDelegate.toProtoMsg({
|
|
118
|
-
delegatorAddress,
|
|
119
|
-
validatorAddress,
|
|
120
|
-
amount,
|
|
121
|
-
}),
|
|
122
|
-
)
|
|
123
|
-
),
|
|
124
|
-
]);
|
|
132
|
+
Delegate(validatorAddress, amount) {
|
|
133
|
+
trace('Delegate', validatorAddress, amount);
|
|
125
134
|
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
throw Fail`Unexpected response: ${result}`;
|
|
131
|
-
} catch (e) {
|
|
132
|
-
throw Fail`Unable to decode result: ${result}`;
|
|
133
|
-
}
|
|
135
|
+
return zcf.makeInvitation(async seat => {
|
|
136
|
+
seat.exit();
|
|
137
|
+
return this.facets.holder.delegate(validatorAddress, amount);
|
|
138
|
+
}, 'Delegate');
|
|
134
139
|
},
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
140
|
+
/** @param {string} validatorAddress */
|
|
141
|
+
WithdrawReward(validatorAddress) {
|
|
142
|
+
trace('WithdrawReward', validatorAddress);
|
|
143
|
+
|
|
144
|
+
return zcf.makeInvitation(async seat => {
|
|
145
|
+
seat.exit();
|
|
146
|
+
return this.facets.holder.withdrawReward(validatorAddress);
|
|
147
|
+
}, 'WithdrawReward');
|
|
142
148
|
},
|
|
143
149
|
CloseAccount() {
|
|
144
|
-
|
|
150
|
+
throw Error('not yet implemented');
|
|
145
151
|
},
|
|
152
|
+
/**
|
|
153
|
+
* Starting a transfer revokes the account holder. The associated updater
|
|
154
|
+
* will get a special notification that the account is being transferred.
|
|
155
|
+
*/
|
|
146
156
|
TransferAccount() {
|
|
147
|
-
|
|
157
|
+
throw Error('not yet implemented');
|
|
148
158
|
},
|
|
149
159
|
},
|
|
150
160
|
holder: {
|
|
@@ -158,37 +168,59 @@ export const prepareStakingAccountKit = (baggage, makeRecorderKit, zcf) => {
|
|
|
158
168
|
},
|
|
159
169
|
});
|
|
160
170
|
},
|
|
171
|
+
// TODO move this beneath the Orchestration abstraction,
|
|
172
|
+
// to the OrchestrationAccount provided by makeAccount()
|
|
161
173
|
/**
|
|
162
|
-
*
|
|
174
|
+
* _Assumes users has already sent funds to their ICA, until #9193
|
|
163
175
|
* @param {string} validatorAddress
|
|
164
176
|
* @param {Amount<'nat'>} ertpAmount
|
|
165
177
|
*/
|
|
166
178
|
async delegate(validatorAddress, ertpAmount) {
|
|
167
179
|
trace('delegate', validatorAddress, ertpAmount);
|
|
168
|
-
return this.facets.helper.delegate(validatorAddress, ertpAmount);
|
|
169
|
-
},
|
|
170
|
-
/**
|
|
171
|
-
*
|
|
172
|
-
* @param {string} validatorAddress
|
|
173
|
-
* @param {Amount<'nat'>} ertpAmount
|
|
174
|
-
*/
|
|
175
|
-
makeDelegateInvitation(validatorAddress, ertpAmount) {
|
|
176
|
-
trace('makeDelegateInvitation', validatorAddress, ertpAmount);
|
|
177
180
|
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
181
|
+
// FIXME get values from proposal or args
|
|
182
|
+
// FIXME brand handling and amount scaling
|
|
183
|
+
trace('TODO: handle brand', ertpAmount);
|
|
184
|
+
const amount = {
|
|
185
|
+
amount: String(ertpAmount.value),
|
|
186
|
+
denom: 'uatom',
|
|
187
|
+
};
|
|
188
|
+
|
|
189
|
+
const account = this.facets.helper.owned();
|
|
190
|
+
const delegatorAddress = this.state.chainAddress.address;
|
|
191
|
+
|
|
192
|
+
const result = await E(account).executeEncodedTx([
|
|
193
|
+
toAnyJSON(
|
|
194
|
+
MsgDelegate.toProtoMsg({
|
|
195
|
+
delegatorAddress,
|
|
196
|
+
validatorAddress,
|
|
197
|
+
amount,
|
|
198
|
+
}),
|
|
199
|
+
),
|
|
200
|
+
]);
|
|
201
|
+
|
|
202
|
+
if (!result) throw Fail`Failed to delegate.`;
|
|
203
|
+
return tryDecodeResponse(result, MsgDelegateResponse.fromProtoMsg);
|
|
185
204
|
},
|
|
205
|
+
|
|
186
206
|
/**
|
|
187
|
-
*
|
|
188
|
-
*
|
|
207
|
+
* @param {string} validatorAddress
|
|
208
|
+
* @returns {Promise<ChainAmount[]>}
|
|
189
209
|
*/
|
|
190
|
-
|
|
191
|
-
|
|
210
|
+
async withdrawReward(validatorAddress) {
|
|
211
|
+
const { chainAddress } = this.state;
|
|
212
|
+
assert.typeof(validatorAddress, 'string');
|
|
213
|
+
const msg = MsgWithdrawDelegatorReward.toProtoMsg({
|
|
214
|
+
delegatorAddress: chainAddress.address,
|
|
215
|
+
validatorAddress,
|
|
216
|
+
});
|
|
217
|
+
const account = this.facets.helper.owned();
|
|
218
|
+
const result = await E(account).executeEncodedTx([toAnyJSON(msg)]);
|
|
219
|
+
const { amount: coins } = tryDecodeResponse(
|
|
220
|
+
result,
|
|
221
|
+
MsgWithdrawDelegatorRewardResponse.fromProtoMsg,
|
|
222
|
+
);
|
|
223
|
+
return harden(coins.map(toChainAmount));
|
|
192
224
|
},
|
|
193
225
|
},
|
|
194
226
|
},
|