@airgap/icp 0.13.15-beta.5 → 0.13.15-beta.7

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.
@@ -1,4 +1,27 @@
1
1
  "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
2
25
  var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
26
  function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
27
  return new (P || (P = Promise))(function (resolve, reject) {
@@ -21,9 +44,11 @@ const assert_1 = require("@airgap/coinlib-core/utils/assert");
21
44
  const array_1 = require("@airgap/coinlib-core/utils/array");
22
45
  const crypto_1 = require("@airgap/crypto");
23
46
  const module_kit_1 = require("@airgap/module-kit");
24
- const module_1 = require("../module");
47
+ const governance_1 = require("../types/governance");
25
48
  const transaction_1 = require("../types/transaction");
26
49
  const account_1 = require("../utils/account");
50
+ const Cbor = __importStar(require("../utils/cbor"));
51
+ const IDL = __importStar(require("../utils/idl"));
27
52
  const principal_1 = require("../utils/principal");
28
53
  const ICPGovernance_1 = require("./ICPGovernance");
29
54
  const ICPImplementation_1 = require("./ICPImplementation");
@@ -75,6 +100,10 @@ class ICPProtocolImpl {
75
100
  algorithm: 'secp256k1'
76
101
  };
77
102
  this.options = createICPProtocolOptions(options.network);
103
+ this.canisterId = {
104
+ ledger: this.options.network.ledgerCanisterId,
105
+ governance: this.options.network.governanceCanisterId
106
+ };
78
107
  }
79
108
  getMetadata() {
80
109
  return __awaiter(this, void 0, void 0, function* () {
@@ -105,25 +134,23 @@ class ICPProtocolImpl {
105
134
  case transaction_1.ICPActionType.TRANSFER:
106
135
  return (0, ICPImplementation_1.getDetailsFromSignedTransactionTransfer)(encoded, publicKey.value, this.options.network);
107
136
  case transaction_1.ICPActionType.GET_NEURON_INFO:
108
- return (0, ICPGovernance_1.getDetailsFromSignedTransactionGetNeuronInfo)(publicKey.value, this.options.network);
137
+ return (0, ICPGovernance_1.getDetailsFromSignedGetNeuronInfo)(publicKey.value, this.options.network);
109
138
  case transaction_1.ICPActionType.TRANSFER_TO_SUBACCOUNT:
110
139
  return (0, ICPGovernance_1.getDetailsFromSignedTransferToSubaccount)(encoded, publicKey.value, this.options.network);
111
140
  case transaction_1.ICPActionType.CLAIM_GOVERNANCE:
112
141
  return (0, ICPGovernance_1.getDetailsFromTransactionClaimGovernance)(publicKey.value, this.options.network);
113
142
  case transaction_1.ICPActionType.FOLLOW_NEURON:
114
143
  return (0, ICPGovernance_1.getDetailsFromSignedFollowNeuron)(publicKey.value, this.options.network);
115
- case transaction_1.ICPActionType.INCREASE_STAKE:
116
- throw new Error('TODO: implement');
117
144
  case transaction_1.ICPActionType.DISBURSE:
118
- return (0, ICPGovernance_1.getDetailsFromSignedTransactionRemoveStake)(publicKey.value, this.options.network);
119
- case transaction_1.ICPActionType.INCREASE_DISSOLVING_DELAY:
120
- return (0, ICPGovernance_1.getDetailsFromSignedTransactionIncreaseDelay)(publicKey.value, this.options.network);
145
+ return (0, ICPGovernance_1.getDetailsFromSignedDisburse)(publicKey.value, this.options.network);
146
+ case transaction_1.ICPActionType.INCREASE_DISSOLVE_DELAY:
147
+ return (0, ICPGovernance_1.getDetailsFromSignedIncreaseDissolveDelay)(publicKey.value, this.options.network);
121
148
  case transaction_1.ICPActionType.START_DISSOLVING:
122
- return (0, ICPGovernance_1.getDetailsFromSignedTransactionStartDissolving)(publicKey.value, this.options.network);
149
+ return (0, ICPGovernance_1.getDetailsFromSignedStartDissolving)(publicKey.value, this.options.network);
123
150
  case transaction_1.ICPActionType.STOP_DISSOLVING:
124
- return (0, ICPGovernance_1.getDetailsFromSignedTransactionStopDissolving)(publicKey.value, this.options.network);
125
- case transaction_1.ICPActionType.RESTAKE_MATURITY:
126
- return (0, ICPGovernance_1.getDetailsFromSignedTransactionRestakeMaturity)(publicKey.value, this.options.network);
151
+ return (0, ICPGovernance_1.getDetailsFromSignedStopDissolving)(publicKey.value, this.options.network);
152
+ case transaction_1.ICPActionType.AUTO_STAKE_MATURITY:
153
+ return (0, ICPGovernance_1.getDetailsFromSignedAutoStakeMaturity)(publicKey.value, this.options.network);
127
154
  default:
128
155
  (0, coinlib_core_1.assertNever)(actionType);
129
156
  throw new errors_1.UnsupportedError(coinlib_core_1.Domain.ICP, 'Unsupported ICP action type');
@@ -137,25 +164,23 @@ class ICPProtocolImpl {
137
164
  case transaction_1.ICPActionType.TRANSFER:
138
165
  return (0, ICPImplementation_1.getDetailsFromUnsignedTransactionTransfer)(encoded, publicKey.value, this.options.network);
139
166
  case transaction_1.ICPActionType.GET_NEURON_INFO:
140
- return (0, ICPGovernance_1.getDetailsFromUnsignedTransactionGetNeuronInfo)(publicKey.value, this.options.network);
167
+ return (0, ICPGovernance_1.getDetailsFromUnsignedGetNeuronInfo)(publicKey.value, this.options.network);
141
168
  case transaction_1.ICPActionType.TRANSFER_TO_SUBACCOUNT:
142
169
  return (0, ICPGovernance_1.getDetailsFromUnsignedTransferToSubaccount)(encoded, publicKey.value, this.options.network);
143
170
  case transaction_1.ICPActionType.CLAIM_GOVERNANCE:
144
171
  return (0, ICPGovernance_1.getDetailsFromUnsignedClaimGovernance)(publicKey.value, this.options.network);
145
- case transaction_1.ICPActionType.INCREASE_STAKE:
146
- throw new Error('TODO: implement');
147
172
  case transaction_1.ICPActionType.DISBURSE:
148
- return (0, ICPGovernance_1.getDetailsFromUnsignedTransactionRemoveStake)(publicKey.value, this.options.network);
149
- case transaction_1.ICPActionType.INCREASE_DISSOLVING_DELAY:
150
- return (0, ICPGovernance_1.getDetailsFromUnsignedTransactionIncreaseDelay)(publicKey.value, this.options.network);
173
+ return (0, ICPGovernance_1.getDetailsFromUnsignedDisburse)(publicKey.value, this.options.network);
174
+ case transaction_1.ICPActionType.INCREASE_DISSOLVE_DELAY:
175
+ return (0, ICPGovernance_1.getDetailsFromUnsignedIncreaseDissolveDelay)(publicKey.value, this.options.network);
151
176
  case transaction_1.ICPActionType.START_DISSOLVING:
152
- return (0, ICPGovernance_1.getDetailsFromUnsignedTransactionStartDissolving)(publicKey.value, this.options.network);
177
+ return (0, ICPGovernance_1.getDetailsFromUnsignedStartDissolving)(publicKey.value, this.options.network);
153
178
  case transaction_1.ICPActionType.STOP_DISSOLVING:
154
- return (0, ICPGovernance_1.getDetailsFromUnsignedTransactionStopDissolving)(publicKey.value, this.options.network);
179
+ return (0, ICPGovernance_1.getDetailsFromUnsignedStopDissolving)(publicKey.value, this.options.network);
155
180
  case transaction_1.ICPActionType.FOLLOW_NEURON:
156
181
  return (0, ICPGovernance_1.getDetailsFromUnsignedFollowNeuron)(publicKey.value, this.options.network);
157
- case transaction_1.ICPActionType.RESTAKE_MATURITY:
158
- return (0, ICPGovernance_1.getDetailsFromUnsignedTransactionRestakeMaturity)(publicKey.value, this.options.network);
182
+ case transaction_1.ICPActionType.AUTO_STAKE_MATURITY:
183
+ return (0, ICPGovernance_1.getDetailsFromUnsignedAutoStakeMaturity)(publicKey.value, this.options.network);
159
184
  default:
160
185
  (0, coinlib_core_1.assertNever)(actionType);
161
186
  throw new errors_1.UnsupportedError(coinlib_core_1.Domain.ICP, 'Unsupported ICP action type');
@@ -193,7 +218,7 @@ class ICPProtocolImpl {
193
218
  case transaction_1.ICPActionType.GET_NEURON_INFO:
194
219
  return {
195
220
  actionType,
196
- encoded: yield (0, ICPGovernance_1.signTransactionGetNeuronInfo)(encoded, secretKey.value, this.options.network.governanceCanisterId)
221
+ encoded: yield (0, ICPGovernance_1.signGetNeuronInfo)(encoded, secretKey.value, this.options.network.governanceCanisterId)
197
222
  };
198
223
  case transaction_1.ICPActionType.TRANSFER_TO_SUBACCOUNT:
199
224
  return {
@@ -203,39 +228,37 @@ class ICPProtocolImpl {
203
228
  case transaction_1.ICPActionType.CLAIM_GOVERNANCE:
204
229
  return {
205
230
  actionType,
206
- encoded: yield (0, ICPGovernance_1.signClaimGovernance)(encoded, secretKey.value, this.options.network.ledgerCanisterId)
231
+ encoded: yield (0, ICPGovernance_1.signClaimGovernance)(encoded, secretKey.value, this.options.network.governanceCanisterId)
207
232
  };
208
- case transaction_1.ICPActionType.INCREASE_STAKE:
209
- throw new Error('TODO: implement');
210
233
  case transaction_1.ICPActionType.DISBURSE:
211
234
  return {
212
235
  actionType,
213
- encoded: yield (0, ICPGovernance_1.signTransactionRemoveStake)(encoded, secretKey.value, this.options.network.ledgerCanisterId)
236
+ encoded: yield (0, ICPGovernance_1.signDisburse)(encoded, secretKey.value, this.options.network.governanceCanisterId)
214
237
  };
215
- case transaction_1.ICPActionType.INCREASE_DISSOLVING_DELAY:
238
+ case transaction_1.ICPActionType.INCREASE_DISSOLVE_DELAY:
216
239
  return {
217
240
  actionType,
218
- encoded: yield (0, ICPGovernance_1.signTransactionIncreaseDelay)(encoded, secretKey.value, this.options.network.ledgerCanisterId)
241
+ encoded: yield (0, ICPGovernance_1.signIncreaseDissolveDelay)(encoded, secretKey.value, this.options.network.governanceCanisterId)
219
242
  };
220
243
  case transaction_1.ICPActionType.START_DISSOLVING:
221
244
  return {
222
245
  actionType,
223
- encoded: yield (0, ICPGovernance_1.signTransactionStartDissolving)(encoded, secretKey.value, this.options.network.ledgerCanisterId)
246
+ encoded: yield (0, ICPGovernance_1.signStartDissolving)(encoded, secretKey.value, this.options.network.governanceCanisterId)
224
247
  };
225
248
  case transaction_1.ICPActionType.STOP_DISSOLVING:
226
249
  return {
227
250
  actionType,
228
- encoded: yield (0, ICPGovernance_1.signTransactionStopDissolving)(encoded, secretKey.value, this.options.network.ledgerCanisterId)
251
+ encoded: yield (0, ICPGovernance_1.signStopDissolving)(encoded, secretKey.value, this.options.network.governanceCanisterId)
229
252
  };
230
253
  case transaction_1.ICPActionType.FOLLOW_NEURON:
231
254
  return {
232
255
  actionType,
233
- encoded: yield (0, ICPGovernance_1.signFollowNeuron)(encoded, secretKey.value, this.options.network.ledgerCanisterId)
256
+ encoded: yield (0, ICPGovernance_1.signFollowNeuron)(encoded, secretKey.value, this.options.network.governanceCanisterId)
234
257
  };
235
- case transaction_1.ICPActionType.RESTAKE_MATURITY:
258
+ case transaction_1.ICPActionType.AUTO_STAKE_MATURITY:
236
259
  return {
237
260
  actionType,
238
- encoded: yield (0, ICPGovernance_1.signTransactionRestakeMaturity)(encoded, secretKey.value, this.options.network.ledgerCanisterId)
261
+ encoded: yield (0, ICPGovernance_1.signAutoStakeMaturity)(encoded, secretKey.value, this.options.network.governanceCanisterId)
239
262
  };
240
263
  default:
241
264
  (0, coinlib_core_1.assertNever)(actionType);
@@ -296,7 +319,16 @@ class ICPProtocolImpl {
296
319
  getBalanceOfPublicKey(publicKey) {
297
320
  return __awaiter(this, void 0, void 0, function* () {
298
321
  const address = (0, ICPImplementation_1.getAddressFromPublicKey)(publicKey.value);
299
- return this.getBalanceOfAddress(address);
322
+ const mainBalance = yield this.getBalanceOfAddress(address);
323
+ const neuronBalance = yield this.getNeuronBalance(publicKey);
324
+ const totalBalance = (0, module_kit_1.newAmount)(mainBalance.total)
325
+ .blockchain(this.units)
326
+ .toBigNumber()
327
+ .plus((0, module_kit_1.newAmount)(neuronBalance).blockchain(this.units).toBigNumber());
328
+ return {
329
+ total: (0, module_kit_1.newAmount)(totalBalance, 'blockchain'),
330
+ transferable: mainBalance.total
331
+ };
300
332
  });
301
333
  }
302
334
  getBalanceOfAddress(address) {
@@ -317,7 +349,7 @@ class ICPProtocolImpl {
317
349
  }
318
350
  else {
319
351
  const feeEstimation = yield this.getTransactionFeeWithPublicKey(publicKey, []);
320
- fee = new bignumber_1.default((0, module_kit_1.newAmount)(feeEstimation.medium).value);
352
+ fee = new bignumber_1.default((0, module_kit_1.newAmount)(feeEstimation).value);
321
353
  if (fee.gte(balanceBn)) {
322
354
  fee = new bignumber_1.default(0);
323
355
  }
@@ -339,7 +371,7 @@ class ICPProtocolImpl {
339
371
  // medium: newAmount(feeDefault.toString(10), 'ICP'),
340
372
  // high: newAmount(feeDefault.toString(10), 'ICP')
341
373
  // }
342
- return this.feeDefaults;
374
+ return this.feeDefaults.medium;
343
375
  });
344
376
  }
345
377
  prepareTransactionWithPublicKey(publicKey, details, configuration) {
@@ -355,15 +387,12 @@ class ICPProtocolImpl {
355
387
  throw new errors_1.BalanceError(coinlib_core_1.Domain.ICP, 'not enough balance');
356
388
  }
357
389
  const amountBn = BigInt((0, module_kit_1.newAmount)(details[0].amount).blockchain(this.units).value);
358
- // Transaction object
359
- const transaction = {
360
- from: (0, ICPImplementation_1.getAddressFromPublicKey)(publicKey.value),
390
+ // Create unsigned
391
+ const unsignedTransaction = (0, ICPImplementation_1.createUnsignedTransaction)({
361
392
  to: details[0].to,
362
393
  amount: amountBn,
363
394
  fee: feeBn
364
- };
365
- // Create unsigned
366
- const unsignedTransaction = (0, ICPImplementation_1.createUnsignedTransaction)(transaction);
395
+ });
367
396
  return (0, module_kit_1.newUnsignedTransaction)({
368
397
  transactions: [
369
398
  {
@@ -379,10 +408,87 @@ class ICPProtocolImpl {
379
408
  // Search for : Transfer ICP from the caller to the destination accountIdentifier. Returns the index of the block containing the tx if it was successful.
380
409
  broadcastTransaction(transaction) {
381
410
  return __awaiter(this, void 0, void 0, function* () {
382
- const txHashes = yield Promise.all(transaction.transactions.map(({ actionType, encoded }) => (0, ICPImplementation_1.broadcastTransaction)(encoded, this.options.network.rpcUrl, this.options.network.governanceCanisterId, transaction_1.ICP_REQUEST_TYPE_PER_ACTION[actionType])));
383
- return txHashes[0];
411
+ for (const { actionType, encoded } of transaction.transactions) {
412
+ const requestType = transaction_1.ICP_REQUEST_TYPE_PER_ACTION[actionType];
413
+ if (requestType !== 'call')
414
+ continue;
415
+ yield (0, ICPImplementation_1.broadcastTransaction)(encoded, this.options.network.rpcUrl, this.canisterId[transaction_1.ICP_CANISTER_TYPE_PER_ACTION[actionType]], transaction_1.ICP_REQUEST_TYPE_PER_ACTION[actionType]);
416
+ }
417
+ return '';
384
418
  });
385
419
  }
420
+ sendQuery(transaction) {
421
+ return __awaiter(this, void 0, void 0, function* () {
422
+ return Promise.all(transaction.transactions
423
+ .filter(({ actionType }) => transaction_1.ICP_REQUEST_TYPE_PER_ACTION[actionType] === 'query')
424
+ .map(({ actionType, encoded }) => __awaiter(this, void 0, void 0, function* () {
425
+ const response = yield (0, ICPImplementation_1.broadcastTransaction)(encoded, this.options.network.rpcUrl, this.canisterId[transaction_1.ICP_CANISTER_TYPE_PER_ACTION[actionType]], transaction_1.ICP_REQUEST_TYPE_PER_ACTION[actionType]);
426
+ const queryResponse = Cbor.decode(response);
427
+ if (queryResponse.status == "rejected" /* QueryResponseStatus.Rejected */) {
428
+ throw new errors_1.NetworkError(coinlib_core_1.Domain.ICP, {}, `Error (${queryResponse.reject_code}) ${queryResponse.reject_message}`);
429
+ }
430
+ return this.decodeQueryResponse(actionType, queryResponse.reply.arg);
431
+ })));
432
+ });
433
+ }
434
+ decodeQueryResponse(actionType, response) {
435
+ switch (actionType) {
436
+ case transaction_1.ICPActionType.GET_NEURON_INFO:
437
+ const NeuronId = IDL.Record({ id: IDL.Nat64 });
438
+ const BallotInfo = IDL.Record({
439
+ vote: IDL.Int32,
440
+ proposal_id: IDL.Opt(NeuronId)
441
+ });
442
+ const DissolveState = IDL.Variant({
443
+ DissolveDelaySeconds: IDL.Nat64,
444
+ WhenDissolvedTimestampSeconds: IDL.Nat64
445
+ });
446
+ const Followees = IDL.Record({ followees: IDL.Vec(NeuronId) });
447
+ const NeuronStakeTransfer = IDL.Record({
448
+ to_subaccount: IDL.Vec(IDL.Nat8),
449
+ neuron_stake_e8s: IDL.Nat64,
450
+ from: IDL.Opt(IDL.Principal),
451
+ memo: IDL.Nat64,
452
+ from_subaccount: IDL.Vec(IDL.Nat8),
453
+ transfer_timestamp: IDL.Nat64,
454
+ block_height: IDL.Nat64
455
+ });
456
+ const KnownNeuronData = IDL.Record({
457
+ name: IDL.Text,
458
+ description: IDL.Opt(IDL.Text)
459
+ });
460
+ const Neuron = IDL.Record({
461
+ id: IDL.Opt(NeuronId),
462
+ staked_maturity_e8s_equivalent: IDL.Opt(IDL.Nat64),
463
+ controller: IDL.Opt(IDL.Principal),
464
+ recent_ballots: IDL.Vec(BallotInfo),
465
+ kyc_verified: IDL.Bool,
466
+ not_for_profit: IDL.Bool,
467
+ maturity_e8s_equivalent: IDL.Nat64,
468
+ cached_neuron_stake_e8s: IDL.Nat64,
469
+ created_timestamp_seconds: IDL.Nat64,
470
+ auto_stake_maturity: IDL.Opt(IDL.Bool),
471
+ aging_since_timestamp_seconds: IDL.Nat64,
472
+ hot_keys: IDL.Vec(IDL.Principal),
473
+ account: IDL.Vec(IDL.Nat8),
474
+ joined_community_fund_timestamp_seconds: IDL.Opt(IDL.Nat64),
475
+ dissolve_state: IDL.Opt(DissolveState),
476
+ followees: IDL.Vec(IDL.Tuple(IDL.Int32, Followees)),
477
+ neuron_fees_e8s: IDL.Nat64,
478
+ transfer: IDL.Opt(NeuronStakeTransfer),
479
+ known_neuron_data: IDL.Opt(KnownNeuronData),
480
+ spawn_at_timestamp_seconds: IDL.Opt(IDL.Nat64)
481
+ });
482
+ const GovernanceError = IDL.Record({
483
+ error_message: IDL.Text,
484
+ error_type: IDL.Int32
485
+ });
486
+ const Result = IDL.Variant({ Ok: Neuron, Err: GovernanceError });
487
+ return IDL.decode([Result], response)[0];
488
+ default:
489
+ throw new errors_1.UnsupportedError(coinlib_core_1.Domain.ICP, `Decode response for action type ${actionType} is not supported`);
490
+ }
491
+ }
386
492
  // DELEGATION
387
493
  getDefaultDelegatee() {
388
494
  var _a, _b, _c;
@@ -392,12 +498,12 @@ class ICPProtocolImpl {
392
498
  return (id === null || id === void 0 ? void 0 : id.toString()) || '';
393
499
  });
394
500
  }
395
- getCurrentDelegateesForPublicKey(publicKey, data) {
501
+ getCurrentDelegateesForPublicKey(_publicKey, data) {
396
502
  return __awaiter(this, void 0, void 0, function* () {
397
503
  // Fetch neurons of address from governance canister (listNeurons)
398
504
  // Fetch followees from each neuron (get_full_neuron_by_id_or_subaccount)
399
505
  // Each of the functions needs a identity (signed user)
400
- return [];
506
+ return (data === null || data === void 0 ? void 0 : data.neuron) ? this.getNeuronFollowees(data.neuron) : [];
401
507
  });
402
508
  }
403
509
  getCurrentDelegateesForAddress(_address, _data) {
@@ -406,19 +512,22 @@ class ICPProtocolImpl {
406
512
  });
407
513
  }
408
514
  getDelegateeDetails(address, data) {
409
- var _a, _b;
515
+ var _a, _b, _c, _d;
410
516
  return __awaiter(this, void 0, void 0, function* () {
411
517
  const partialNeuron = yield (0, ICPImplementation_1.getNeuronInfo)(address, this.options.network.rpcUrl, this.options.network.governanceCanisterId);
518
+ const neuronFolowees = (data === null || data === void 0 ? void 0 : data.neuron) ? this.getNeuronFollowees(data.neuron) : undefined;
412
519
  return {
413
520
  name: ((_b = (_a = partialNeuron === null || partialNeuron === void 0 ? void 0 : partialNeuron.known_neuron_data) === null || _a === void 0 ? void 0 : _a[0]) === null || _b === void 0 ? void 0 : _b.name) || '',
414
- address: address
521
+ address: address,
522
+ status: neuronFolowees ? (neuronFolowees.includes(address) ? 'followed' : 'not-followed') : 'unknown',
523
+ votingPower: (_d = (_c = partialNeuron === null || partialNeuron === void 0 ? void 0 : partialNeuron.voting_power) === null || _c === void 0 ? void 0 : _c.toString()) !== null && _d !== void 0 ? _d : '0'
415
524
  };
416
525
  });
417
526
  }
418
527
  isPublicKeyDelegating(publicKey, data) {
419
528
  var _a, _b;
420
529
  return __awaiter(this, void 0, void 0, function* () {
421
- const partialNeuron = yield this.getNeuron(publicKey.value);
530
+ const partialNeuron = yield this.getNeuron(publicKey);
422
531
  if (partialNeuron === undefined) {
423
532
  return false;
424
533
  }
@@ -444,17 +553,28 @@ class ICPProtocolImpl {
444
553
  });
445
554
  }
446
555
  getDelegatorDetailsFromPublicKey(publicKey, data) {
556
+ var _a, _b, _c, _d, _e;
447
557
  return __awaiter(this, void 0, void 0, function* () {
558
+ const fullNeuron = data === null || data === void 0 ? void 0 : data.neuron;
448
559
  const address = yield this.getAddressFromPublicKey(publicKey);
449
- const availableBalance = yield this.getBalanceOfAddress(address);
450
- const followees = (data === null || data === void 0 ? void 0 : data.neuron) ? this.getNeuronFollowees(data.neuron) : [];
451
- const availableActions = yield this.getAvailableDelegatorActions(publicKey.value, data === null || data === void 0 ? void 0 : data.neuron);
452
- const totalBalance = (0, module_kit_1.newAmount)(availableBalance.total).blockchain(this.units);
560
+ const totalBalance = yield this.getBalanceOfPublicKey(publicKey);
561
+ const followees = fullNeuron ? this.getNeuronFollowees(fullNeuron) : [];
562
+ const availableActions = yield this.getAvailableDelegatorActions(publicKey, data === null || data === void 0 ? void 0 : data.followee, fullNeuron);
563
+ const neuronBalance = yield this.getNeuronBalance(publicKey);
564
+ const partialNeuron = yield this.getNeuron(publicKey);
565
+ const balance = (0, module_kit_1.newAmount)(totalBalance.total).blockchain(this.units);
566
+ const subaccountBalance = (0, module_kit_1.newAmount)(neuronBalance).blockchain(this.units);
453
567
  return {
454
568
  address,
455
- balance: totalBalance.value,
569
+ balance: balance.value,
456
570
  delegatees: followees,
457
- availableActions: availableActions
571
+ availableActions: availableActions,
572
+ subaccountBalance: subaccountBalance.value,
573
+ stake: (_a = partialNeuron === null || partialNeuron === void 0 ? void 0 : partialNeuron.stake_e8s) === null || _a === void 0 ? void 0 : _a.toString(),
574
+ votingPower: (_b = partialNeuron === null || partialNeuron === void 0 ? void 0 : partialNeuron.voting_power) === null || _b === void 0 ? void 0 : _b.toString(),
575
+ age: (_c = partialNeuron === null || partialNeuron === void 0 ? void 0 : partialNeuron.age_seconds) === null || _c === void 0 ? void 0 : _c.toString(),
576
+ dissolveDelay: (_d = partialNeuron === null || partialNeuron === void 0 ? void 0 : partialNeuron.dissolve_delay_seconds) === null || _d === void 0 ? void 0 : _d.toString(),
577
+ maturity: (_e = fullNeuron === null || fullNeuron === void 0 ? void 0 : fullNeuron.maturity_e8s_equivalent) === null || _e === void 0 ? void 0 : _e.toString()
458
578
  };
459
579
  });
460
580
  }
@@ -466,10 +586,13 @@ class ICPProtocolImpl {
466
586
  getDelegationDetailsFromPublicKey(publicKey, delegatees, data) {
467
587
  return __awaiter(this, void 0, void 0, function* () {
468
588
  if (delegatees.length > 1) {
469
- return Promise.reject('Multiple validators for a single delegation are not supported.');
589
+ return Promise.reject('Multiple followees for a single delegation are not supported.');
470
590
  }
471
- const validator = delegatees[0];
472
- const results = yield Promise.all([this.getDelegatorDetailsFromPublicKey(publicKey), this.getDelegateeDetails(validator)]);
591
+ const followee = delegatees[0];
592
+ const results = yield Promise.all([
593
+ this.getDelegatorDetailsFromPublicKey(publicKey, Object.assign(Object.assign({}, data), { followee })),
594
+ this.getDelegateeDetails(followee, data)
595
+ ]);
473
596
  const delegatorDetails = results[0];
474
597
  const validatorDetails = results[1];
475
598
  return {
@@ -483,58 +606,62 @@ class ICPProtocolImpl {
483
606
  throw new errors_1.UnsupportedError(coinlib_core_1.Domain.ICP, '`getDelegationDetailsFromAddress` is not supported');
484
607
  });
485
608
  }
486
- getAvailableDelegatorActions(publicKey, neuron) {
609
+ getAvailableDelegatorActions(publicKey, followee, fullNeuron) {
610
+ var _a;
487
611
  return __awaiter(this, void 0, void 0, function* () {
488
612
  const actions = [];
489
- const hasNeuron = yield this.getNeuronBalance(publicKey).then((balance) => new bignumber_1.default(balance.total.value).gt(0));
490
- const claimedGovernance = yield this.getNeuron(publicKey).then((neuron) => neuron !== undefined);
491
- const isFollowing = neuron ? this.getNeuronFollowees(neuron).length > 0 : false;
492
- const isDissolving = neuron ? this.isNeuronDissolving(neuron) : false;
493
- const canDisburse = neuron ? this.canNeuronDisburse(neuron) : false;
494
- if (!hasNeuron) {
613
+ const results = yield Promise.all([this.getBalanceOfPublicKey(publicKey), this.getNeuronBalance(publicKey), this.getNeuron(publicKey)]);
614
+ const transferableBalance = (_a = results[0].transferable) !== null && _a !== void 0 ? _a : results[0].total;
615
+ const neuronBalance = results[1];
616
+ const partialNeuron = results[2];
617
+ const canStake = new bignumber_1.default(transferableBalance.value).gt(0);
618
+ const isStaking = new bignumber_1.default(neuronBalance.value).gt(0);
619
+ const hasNeuron = partialNeuron !== undefined;
620
+ const isNeuronUpToDate = !isStaking || (hasNeuron && partialNeuron.stake_e8s.toString() === (0, module_kit_1.newAmount)(neuronBalance).blockchain(this.units).value);
621
+ const canFollow = fullNeuron && followee ? !this.getNeuronFollowees(fullNeuron).includes(followee) : false;
622
+ const isDissolving = fullNeuron ? this.isNeuronDissolving(fullNeuron) : false;
623
+ const canDisburse = partialNeuron ? this.canNeuronDisburse(partialNeuron) : false;
624
+ if (canStake && isNeuronUpToDate) {
495
625
  actions.push({
496
- type: module_1.ICPStakingActionType.CREATE_NEURON,
626
+ type: governance_1.ICPStakingActionType.STAKE_AND_FOLLOW,
497
627
  args: ['followee', 'amount', 'delay']
498
628
  });
499
629
  }
500
- if (hasNeuron && !claimedGovernance) {
630
+ if (!canStake && isStaking && canFollow && isNeuronUpToDate) {
501
631
  actions.push({
502
- type: module_1.ICPStakingActionType.CLAIM_GOVERNANCE,
503
- args: ['followee', 'amount', 'delay']
632
+ type: governance_1.ICPStakingActionType.FOLLOW,
633
+ args: ['followee']
504
634
  });
505
635
  }
506
- if (claimedGovernance && !isFollowing && neuron !== undefined) {
636
+ if (isStaking && isNeuronUpToDate) {
507
637
  actions.push({
508
- type: module_1.ICPStakingActionType.FOLLOW_NEURON,
509
- args: ['followee', 'amount', 'delay']
638
+ type: governance_1.ICPStakingActionType.INCREASE_DISSOLVE_DELAY,
639
+ args: ['delay']
510
640
  });
511
641
  }
512
- if (isFollowing) {
642
+ if (!isNeuronUpToDate) {
513
643
  actions.push({
514
- type: module_1.ICPStakingActionType.CHANGE_FOLLOWEE,
515
- args: ['followee', 'amount', 'delay']
644
+ type: governance_1.ICPStakingActionType.REFRESH_NEURON
516
645
  });
517
646
  }
518
- if (claimedGovernance) {
647
+ if (hasNeuron) {
519
648
  actions.push({
520
- type: module_1.ICPStakingActionType.GET_STAKING_DETAILS
649
+ type: governance_1.ICPStakingActionType.GET_STAKING_DETAILS
521
650
  });
522
651
  }
523
- if (claimedGovernance && !isDissolving) {
652
+ if (isStaking && hasNeuron && !isDissolving && fullNeuron !== undefined) {
524
653
  actions.push({
525
- type: module_1.ICPStakingActionType.INCREASE_DISSOLVING_DELAY
526
- }, {
527
- type: module_1.ICPStakingActionType.START_DISSOLVING
654
+ type: governance_1.ICPStakingActionType.START_DISSOLVING
528
655
  });
529
656
  }
530
657
  if (isDissolving) {
531
658
  actions.push({
532
- type: module_1.ICPStakingActionType.STOP_DISSOLVING
659
+ type: governance_1.ICPStakingActionType.STOP_DISSOLVING
533
660
  });
534
661
  }
535
662
  if (canDisburse) {
536
663
  actions.push({
537
- type: module_1.ICPStakingActionType.DISBURSE
664
+ type: governance_1.ICPStakingActionType.DISBURSE_AND_UNFOLLOW
538
665
  });
539
666
  }
540
667
  return actions;
@@ -543,54 +670,171 @@ class ICPProtocolImpl {
543
670
  prepareDelegatorActionFromPublicKey(publicKey, type, data) {
544
671
  return __awaiter(this, void 0, void 0, function* () {
545
672
  switch (type) {
546
- case module_1.ICPStakingActionType.CREATE_NEURON:
547
- (0, assert_1.assertFields)(`${type} action`, data, 'followee', 'amount', 'delay');
548
- return [
549
- (0, module_kit_1.newUnsignedTransaction)({
550
- transactions: yield Promise.all([
551
- (0, ICPGovernance_1.prepareTransferToSubaccount)(publicKey.value, this.options.network.ledgerCanisterId, BigInt(data.amount), BigInt((0, module_kit_1.newAmount)(this.feeDefaults.medium).blockchain(this.units).value)),
552
- (0, ICPGovernance_1.prepareClaimGovernance)(publicKey.value)
553
- ])
554
- })
555
- ];
673
+ case governance_1.ICPStakingActionType.GET_STAKING_DETAILS:
674
+ return this.prepareGetStakingDetails();
675
+ case governance_1.ICPStakingActionType.STAKE_AND_FOLLOW:
676
+ (0, assert_1.assertFields)(`${type} action`, data, 'followee', 'amount', 'dissolveDelay');
677
+ return this.prepareTransferToNeuronAndManage(publicKey, data.followee, data.amount, data.dissolveDelay);
678
+ case governance_1.ICPStakingActionType.FOLLOW:
679
+ (0, assert_1.assertFields)(`${type} action`, data, 'followee');
680
+ return this.prepareFollowNeuron(publicKey, data.followee);
681
+ case governance_1.ICPStakingActionType.REFRESH_NEURON:
682
+ return this.prepareClaimOrRefreshNeuron(publicKey);
683
+ case governance_1.ICPStakingActionType.INCREASE_DISSOLVE_DELAY:
684
+ (0, assert_1.assertFields)(`${type} action`, data, 'dissolveDelay');
685
+ return this.prepareIncreaseDissolveDelay(publicKey, data.dissolveDelay);
686
+ case governance_1.ICPStakingActionType.START_DISSOLVING:
687
+ return this.prepareStartDissolving(publicKey);
688
+ case governance_1.ICPStakingActionType.STOP_DISSOLVING:
689
+ return this.prepareStopDissolving(publicKey);
690
+ case governance_1.ICPStakingActionType.DISBURSE_AND_UNFOLLOW:
691
+ return this.prepareDisburseAndUnfollow(publicKey);
556
692
  default:
557
693
  return Promise.reject(`Delegator action type ${type} is not supported.`);
558
694
  }
559
695
  });
560
696
  }
561
- getKnownNeurons() {
697
+ prepareGetStakingDetails() {
562
698
  return __awaiter(this, void 0, void 0, function* () {
563
- return (0, ICPImplementation_1.listKnownNeurons)(this.options.network.rpcUrl, this.options.network.governanceCanisterId);
699
+ return [
700
+ (0, module_kit_1.newUnsignedTransaction)({
701
+ transactions: yield (0, ICPGovernance_1.prepareGetNeuronInfo)()
702
+ })
703
+ ];
564
704
  });
565
705
  }
566
- getNeuronVotingPower(neuronId) {
706
+ prepareTransferToNeuronAndManage(publicKey, followee, amount, dissolveDelay) {
707
+ var _a, _b;
567
708
  return __awaiter(this, void 0, void 0, function* () {
568
- const neuron = yield (0, ICPImplementation_1.getNeuronInfo)(neuronId, this.options.network.rpcUrl, this.options.network.governanceCanisterId);
569
- if (neuron === undefined) {
570
- return '0';
571
- }
572
- return new bignumber_1.default(neuron.voting_power.toString()).shiftedBy(-this.units.ICP.decimals).toString();
709
+ const amountBigInt = BigInt(amount);
710
+ const feeBigInt = BigInt((0, module_kit_1.newAmount)(this.feeDefaults.medium).blockchain(this.units).value);
711
+ const partialNeuron = yield this.getNeuron(publicKey);
712
+ const currentDissolveDelay = (_b = (_a = partialNeuron === null || partialNeuron === void 0 ? void 0 : partialNeuron.dissolve_delay_seconds) === null || _a === void 0 ? void 0 : _a.toString()) !== null && _b !== void 0 ? _b : '0';
713
+ const differenceInDissolveDelay = new bignumber_1.default(dissolveDelay).minus(currentDissolveDelay);
714
+ return [
715
+ (0, module_kit_1.newUnsignedTransaction)({
716
+ transactions: (0, array_1.flattenArray)(yield Promise.all([
717
+ ...(amountBigInt > BigInt(0)
718
+ ? [
719
+ (0, ICPGovernance_1.prepareTransferToSubaccount)(publicKey.value, this.options.network.governanceCanisterId, amountBigInt, feeBigInt),
720
+ (0, ICPGovernance_1.prepareClaimOrRefreshNeuron)(publicKey.value)
721
+ ]
722
+ : []),
723
+ (0, ICPGovernance_1.prepareFollowNeuron)(publicKey.value, BigInt(followee)),
724
+ differenceInDissolveDelay.gt(0)
725
+ ? (0, ICPGovernance_1.prepareIncreaseDissolveDelay)(publicKey.value, BigInt(differenceInDissolveDelay.toFixed()))
726
+ : Promise.resolve([]),
727
+ (0, ICPGovernance_1.prepareAutoStakeMaturity)(publicKey.value)
728
+ ]))
729
+ })
730
+ ];
731
+ });
732
+ }
733
+ prepareFollowNeuron(publicKey, followee) {
734
+ return __awaiter(this, void 0, void 0, function* () {
735
+ return [
736
+ (0, module_kit_1.newUnsignedTransaction)({
737
+ transactions: yield (0, ICPGovernance_1.prepareFollowNeuron)(publicKey.value, BigInt(followee))
738
+ })
739
+ ];
740
+ });
741
+ }
742
+ prepareClaimOrRefreshNeuron(publicKey) {
743
+ return __awaiter(this, void 0, void 0, function* () {
744
+ return [
745
+ (0, module_kit_1.newUnsignedTransaction)({
746
+ transactions: yield (0, ICPGovernance_1.prepareClaimOrRefreshNeuron)(publicKey.value)
747
+ })
748
+ ];
749
+ });
750
+ }
751
+ prepareIncreaseDissolveDelay(publicKey, dissolveDelay) {
752
+ var _a, _b;
753
+ return __awaiter(this, void 0, void 0, function* () {
754
+ const partialNeuron = yield this.getNeuron(publicKey);
755
+ const currentDissolveDelay = (_b = (_a = partialNeuron === null || partialNeuron === void 0 ? void 0 : partialNeuron.dissolve_delay_seconds) === null || _a === void 0 ? void 0 : _a.toString()) !== null && _b !== void 0 ? _b : '0';
756
+ const differenceInDissolveDelay = new bignumber_1.default(dissolveDelay).minus(currentDissolveDelay);
757
+ return [
758
+ (0, module_kit_1.newUnsignedTransaction)({
759
+ transactions: yield (0, ICPGovernance_1.prepareIncreaseDissolveDelay)(publicKey.value, BigInt(differenceInDissolveDelay.toFixed()))
760
+ })
761
+ ];
762
+ });
763
+ }
764
+ prepareStartDissolving(publicKey) {
765
+ return __awaiter(this, void 0, void 0, function* () {
766
+ return [
767
+ (0, module_kit_1.newUnsignedTransaction)({
768
+ transactions: yield (0, ICPGovernance_1.prepareStartDissolving)(publicKey.value)
769
+ })
770
+ ];
771
+ });
772
+ }
773
+ prepareStopDissolving(publicKey) {
774
+ return __awaiter(this, void 0, void 0, function* () {
775
+ return [
776
+ (0, module_kit_1.newUnsignedTransaction)({
777
+ transactions: yield (0, ICPGovernance_1.prepareStopDissolving)(publicKey.value)
778
+ })
779
+ ];
780
+ });
781
+ }
782
+ prepareDisburseAndUnfollow(publicKey) {
783
+ return __awaiter(this, void 0, void 0, function* () {
784
+ return [
785
+ (0, module_kit_1.newUnsignedTransaction)({
786
+ transactions: (0, array_1.flattenArray)(yield Promise.all([(0, ICPGovernance_1.prepareDisburse)(publicKey.value), (0, ICPGovernance_1.prepareFollowNeuron)(publicKey.value, undefined)]))
787
+ })
788
+ ];
789
+ });
790
+ }
791
+ getMaxStakingAmount(publicKey) {
792
+ var _a, _b;
793
+ return __awaiter(this, void 0, void 0, function* () {
794
+ const balance = yield this.getBalanceOfPublicKey(publicKey);
795
+ const { subAccount } = (0, ICPImplementation_1.getFixedSubaccountFromPublicKey)(publicKey.value);
796
+ const accountIdentifier = account_1.AccountIdentifier.fromPrincipal({
797
+ principal: principal_1.Principal.from(this.options.network.ledgerCanisterId),
798
+ subAccount: subAccount
799
+ });
800
+ const fee = yield this.getTransactionFeeWithPublicKey(publicKey, [
801
+ {
802
+ to: accountIdentifier.toHex(),
803
+ amount: (_a = balance.transferable) !== null && _a !== void 0 ? _a : balance.total
804
+ }
805
+ ]);
806
+ const maxAmount = (0, module_kit_1.newAmount)((_b = balance.transferable) !== null && _b !== void 0 ? _b : balance.total)
807
+ .blockchain(this.units)
808
+ .toBigNumber()
809
+ .minus((0, module_kit_1.newAmount)(fee).blockchain(this.units).value);
810
+ return (0, module_kit_1.newAmount)(maxAmount, 'blockchain');
811
+ });
812
+ }
813
+ getKnownNeurons() {
814
+ return __awaiter(this, void 0, void 0, function* () {
815
+ return (0, ICPImplementation_1.listKnownNeurons)(this.options.network.rpcUrl, this.options.network.governanceCanisterId);
573
816
  });
574
817
  }
575
818
  getNeuron(publicKey) {
576
819
  return __awaiter(this, void 0, void 0, function* () {
577
- const neuron = yield (0, ICPImplementation_1.getNeuronInfoBySubAccount)(publicKey, this.options.network.rpcUrl, this.options.network.governanceCanisterId);
820
+ const neuron = yield (0, ICPImplementation_1.getNeuronInfoBySubAccount)(publicKey.value, this.options.network.rpcUrl, this.options.network.governanceCanisterId);
578
821
  return neuron;
579
822
  });
580
823
  }
581
824
  getNeuronBalance(publicKey) {
582
825
  return __awaiter(this, void 0, void 0, function* () {
583
826
  // Create subaccount from publicKey
584
- const { subAccount, nonce: _ } = (0, ICPImplementation_1.getFixedSubaccountFromPublicKey)(publicKey);
827
+ const { subAccount, nonce: _ } = (0, ICPImplementation_1.getFixedSubaccountFromPublicKey)(publicKey.value);
585
828
  const accountIdentifier = account_1.AccountIdentifier.fromPrincipal({
586
- principal: principal_1.Principal.from(this.options.network.ledgerCanisterId),
829
+ principal: principal_1.Principal.from(this.options.network.governanceCanisterId),
587
830
  subAccount: subAccount
588
831
  });
589
- return this.getBalanceOfAddress(accountIdentifier.toHex());
832
+ return this.getBalanceOfAddress(accountIdentifier.toHex()).then((balance) => balance.total);
590
833
  });
591
834
  }
592
835
  getNeuronFollowees(neuron) {
593
- return (0, array_1.flattenArray)(neuron.followees.map(([_, { followees }]) => followees.map(({ id }) => id.toString())));
836
+ const followees = (0, array_1.flattenArray)(neuron.followees.map(([_, { followees }]) => followees.map(({ id }) => id.toString())));
837
+ return Array.from(new Set(followees));
594
838
  }
595
839
  isNeuronDissolving(neuron) {
596
840
  const dissolveState = neuron.dissolve_state[0];
@@ -599,10 +843,7 @@ class ICPProtocolImpl {
599
843
  dissolveState.WhenDissolvedTimestampSeconds > BigInt(0));
600
844
  }
601
845
  canNeuronDisburse(neuron) {
602
- const dissolveState = neuron.dissolve_state[0];
603
- return (dissolveState !== undefined &&
604
- 'WhenDissolvedTimestampSeconds' in dissolveState &&
605
- dissolveState.WhenDissolvedTimestampSeconds === BigInt(0));
846
+ return neuron.dissolve_delay_seconds === BigInt(0) && neuron.stake_e8s > BigInt(0);
606
847
  }
607
848
  }
608
849
  exports.ICPProtocolImpl = ICPProtocolImpl;