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

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,21 +134,19 @@ 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);
145
+ return (0, ICPGovernance_1.getDetailsFromSignedDisburse)(publicKey.value, this.options.network);
119
146
  case transaction_1.ICPActionType.INCREASE_DISSOLVING_DELAY:
120
147
  return (0, ICPGovernance_1.getDetailsFromSignedTransactionIncreaseDelay)(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
151
  return (0, ICPGovernance_1.getDetailsFromSignedTransactionStopDissolving)(publicKey.value, this.options.network);
125
152
  case transaction_1.ICPActionType.RESTAKE_MATURITY:
@@ -137,19 +164,17 @@ 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);
173
+ return (0, ICPGovernance_1.getDetailsFromUnsignedDisburse)(publicKey.value, this.options.network);
149
174
  case transaction_1.ICPActionType.INCREASE_DISSOLVING_DELAY:
150
175
  return (0, ICPGovernance_1.getDetailsFromUnsignedTransactionIncreaseDelay)(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
179
  return (0, ICPGovernance_1.getDetailsFromUnsignedTransactionStopDissolving)(publicKey.value, this.options.network);
155
180
  case transaction_1.ICPActionType.FOLLOW_NEURON:
@@ -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
238
  case transaction_1.ICPActionType.INCREASE_DISSOLVING_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.signTransactionIncreaseDelay)(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.signTransactionStopDissolving)(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
258
  case transaction_1.ICPActionType.RESTAKE_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.signTransactionRestakeMaturity)(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.total).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;
@@ -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,26 @@ class ICPProtocolImpl {
444
553
  });
445
554
  }
446
555
  getDelegatorDetailsFromPublicKey(publicKey, data) {
556
+ var _a, _b, _c, _d;
447
557
  return __awaiter(this, void 0, void 0, function* () {
448
558
  const address = yield this.getAddressFromPublicKey(publicKey);
449
559
  const availableBalance = yield this.getBalanceOfAddress(address);
450
560
  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);
561
+ const availableActions = yield this.getAvailableDelegatorActions(publicKey, data === null || data === void 0 ? void 0 : data.neuron);
562
+ const neuronBalance = yield this.getNeuronBalance(publicKey);
563
+ const partialNeuron = yield this.getNeuron(publicKey);
452
564
  const totalBalance = (0, module_kit_1.newAmount)(availableBalance.total).blockchain(this.units);
565
+ const subaccountBalance = (0, module_kit_1.newAmount)(neuronBalance.total).blockchain(this.units);
453
566
  return {
454
567
  address,
455
568
  balance: totalBalance.value,
456
569
  delegatees: followees,
457
- availableActions: availableActions
570
+ availableActions: availableActions,
571
+ subaccountBalance: subaccountBalance.value,
572
+ stake: (_a = partialNeuron === null || partialNeuron === void 0 ? void 0 : partialNeuron.stake_e8s) === null || _a === void 0 ? void 0 : _a.toString(),
573
+ votingPower: (_b = partialNeuron === null || partialNeuron === void 0 ? void 0 : partialNeuron.voting_power) === null || _b === void 0 ? void 0 : _b.toString(),
574
+ age: (_c = partialNeuron === null || partialNeuron === void 0 ? void 0 : partialNeuron.age_seconds) === null || _c === void 0 ? void 0 : _c.toString(),
575
+ dissolveDelay: (_d = partialNeuron === null || partialNeuron === void 0 ? void 0 : partialNeuron.dissolve_delay_seconds) === null || _d === void 0 ? void 0 : _d.toString()
458
576
  };
459
577
  });
460
578
  }
@@ -469,7 +587,7 @@ class ICPProtocolImpl {
469
587
  return Promise.reject('Multiple validators for a single delegation are not supported.');
470
588
  }
471
589
  const validator = delegatees[0];
472
- const results = yield Promise.all([this.getDelegatorDetailsFromPublicKey(publicKey), this.getDelegateeDetails(validator)]);
590
+ const results = yield Promise.all([this.getDelegatorDetailsFromPublicKey(publicKey, data), this.getDelegateeDetails(validator, data)]);
473
591
  const delegatorDetails = results[0];
474
592
  const validatorDetails = results[1];
475
593
  return {
@@ -483,58 +601,73 @@ class ICPProtocolImpl {
483
601
  throw new errors_1.UnsupportedError(coinlib_core_1.Domain.ICP, '`getDelegationDetailsFromAddress` is not supported');
484
602
  });
485
603
  }
486
- getAvailableDelegatorActions(publicKey, neuron) {
604
+ getAvailableDelegatorActions(publicKey, fullNeuron) {
487
605
  return __awaiter(this, void 0, void 0, function* () {
488
606
  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) {
607
+ const neuronBalance = yield this.getNeuronBalance(publicKey);
608
+ const partialNeuron = yield this.getNeuron(publicKey);
609
+ const isStaking = new bignumber_1.default(neuronBalance.total.value).gt(0);
610
+ const hasNeuron = partialNeuron !== undefined;
611
+ const isNeuronUpToDate = hasNeuron && partialNeuron.stake_e8s.toString() === (0, module_kit_1.newAmount)(neuronBalance.total).blockchain(this.units).value;
612
+ const isFollowing = fullNeuron ? this.getNeuronFollowees(fullNeuron).length > 0 : false;
613
+ const isDissolving = fullNeuron ? this.isNeuronDissolving(fullNeuron) : false;
614
+ const canDisburse = partialNeuron ? this.canNeuronDisburse(partialNeuron) : false;
615
+ if (!isStaking && !hasNeuron) {
495
616
  actions.push({
496
- type: module_1.ICPStakingActionType.CREATE_NEURON,
617
+ type: governance_1.ICPStakingActionType.CREATE_NEURON,
497
618
  args: ['followee', 'amount', 'delay']
498
619
  });
499
620
  }
500
- if (hasNeuron && !claimedGovernance) {
621
+ if (isStaking && !hasNeuron) {
501
622
  actions.push({
502
- type: module_1.ICPStakingActionType.CLAIM_GOVERNANCE,
623
+ type: governance_1.ICPStakingActionType.CLAIM_GOVERNANCE,
503
624
  args: ['followee', 'amount', 'delay']
504
625
  });
505
626
  }
506
- if (claimedGovernance && !isFollowing && neuron !== undefined) {
627
+ if (!isNeuronUpToDate) {
628
+ actions.push({
629
+ type: governance_1.ICPStakingActionType.REFRESH_NEURON,
630
+ args: ['amount']
631
+ });
632
+ }
633
+ if (isNeuronUpToDate && fullNeuron === undefined) {
634
+ actions.push({
635
+ type: governance_1.ICPStakingActionType.INCREASE_STAKE,
636
+ args: ['amount']
637
+ });
638
+ }
639
+ if (isNeuronUpToDate && !isFollowing && fullNeuron !== undefined) {
507
640
  actions.push({
508
- type: module_1.ICPStakingActionType.FOLLOW_NEURON,
641
+ type: governance_1.ICPStakingActionType.FOLLOW_NEURON,
509
642
  args: ['followee', 'amount', 'delay']
510
643
  });
511
644
  }
512
- if (isFollowing) {
645
+ if (isFollowing && fullNeuron !== undefined) {
513
646
  actions.push({
514
- type: module_1.ICPStakingActionType.CHANGE_FOLLOWEE,
647
+ type: governance_1.ICPStakingActionType.CHANGE_FOLLOWEE,
515
648
  args: ['followee', 'amount', 'delay']
516
649
  });
517
650
  }
518
- if (claimedGovernance) {
651
+ if (hasNeuron) {
519
652
  actions.push({
520
- type: module_1.ICPStakingActionType.GET_STAKING_DETAILS
653
+ type: governance_1.ICPStakingActionType.GET_STAKING_DETAILS
521
654
  });
522
655
  }
523
- if (claimedGovernance && !isDissolving) {
656
+ if (isStaking && hasNeuron && !isDissolving && fullNeuron !== undefined) {
524
657
  actions.push({
525
- type: module_1.ICPStakingActionType.INCREASE_DISSOLVING_DELAY
658
+ type: governance_1.ICPStakingActionType.INCREASE_DISSOLVING_DELAY
526
659
  }, {
527
- type: module_1.ICPStakingActionType.START_DISSOLVING
660
+ type: governance_1.ICPStakingActionType.START_DISSOLVING
528
661
  });
529
662
  }
530
663
  if (isDissolving) {
531
664
  actions.push({
532
- type: module_1.ICPStakingActionType.STOP_DISSOLVING
665
+ type: governance_1.ICPStakingActionType.STOP_DISSOLVING
533
666
  });
534
667
  }
535
668
  if (canDisburse) {
536
669
  actions.push({
537
- type: module_1.ICPStakingActionType.DISBURSE
670
+ type: governance_1.ICPStakingActionType.DISBURSE
538
671
  });
539
672
  }
540
673
  return actions;
@@ -543,47 +676,121 @@ class ICPProtocolImpl {
543
676
  prepareDelegatorActionFromPublicKey(publicKey, type, data) {
544
677
  return __awaiter(this, void 0, void 0, function* () {
545
678
  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
- ];
679
+ case governance_1.ICPStakingActionType.CREATE_NEURON:
680
+ case governance_1.ICPStakingActionType.INCREASE_STAKE:
681
+ (0, assert_1.assertFields)(`${type} action`, data, 'amount');
682
+ return this.prepareTransferToNeuron(publicKey, data.amount);
683
+ case governance_1.ICPStakingActionType.CLAIM_GOVERNANCE:
684
+ case governance_1.ICPStakingActionType.REFRESH_NEURON:
685
+ (0, assert_1.assertFields)(`${type} action`, data, 'amount');
686
+ return this.prepareClaimOrRefreshNeuron(publicKey, data.amount);
687
+ case governance_1.ICPStakingActionType.GET_STAKING_DETAILS:
688
+ return this.prepareGetStakingDetails();
689
+ case governance_1.ICPStakingActionType.START_DISSOLVING:
690
+ return this.prepareStartDissolving(publicKey);
691
+ case governance_1.ICPStakingActionType.DISBURSE:
692
+ return this.prepareDisburse(publicKey);
556
693
  default:
557
694
  return Promise.reject(`Delegator action type ${type} is not supported.`);
558
695
  }
559
696
  });
560
697
  }
561
- getKnownNeurons() {
698
+ prepareTransferToNeuron(publicKey, amount) {
562
699
  return __awaiter(this, void 0, void 0, function* () {
563
- return (0, ICPImplementation_1.listKnownNeurons)(this.options.network.rpcUrl, this.options.network.governanceCanisterId);
700
+ const amountBigInt = BigInt(amount);
701
+ const feeBigInt = BigInt((0, module_kit_1.newAmount)(this.feeDefaults.medium).blockchain(this.units).value);
702
+ return [
703
+ (0, module_kit_1.newUnsignedTransaction)({
704
+ transactions: yield Promise.all([
705
+ (0, ICPGovernance_1.prepareTransferToSubaccount)(publicKey.value, this.options.network.governanceCanisterId, amountBigInt, feeBigInt),
706
+ (0, ICPGovernance_1.prepareClaimOrRefreshNeuron)(publicKey.value)
707
+ ])
708
+ })
709
+ ];
710
+ });
711
+ }
712
+ prepareClaimOrRefreshNeuron(publicKey, amount) {
713
+ return __awaiter(this, void 0, void 0, function* () {
714
+ const amountBigInt = BigInt(amount);
715
+ const feeBigInt = BigInt((0, module_kit_1.newAmount)(this.feeDefaults.medium).blockchain(this.units).value);
716
+ return [
717
+ (0, module_kit_1.newUnsignedTransaction)({
718
+ transactions: (yield Promise.all([
719
+ amountBigInt > 0
720
+ ? (0, ICPGovernance_1.prepareTransferToSubaccount)(publicKey.value, this.options.network.governanceCanisterId, amountBigInt, feeBigInt)
721
+ : Promise.resolve(undefined),
722
+ (0, ICPGovernance_1.prepareClaimOrRefreshNeuron)(publicKey.value)
723
+ ])).filter((tx) => tx !== undefined)
724
+ })
725
+ ];
726
+ });
727
+ }
728
+ prepareGetStakingDetails() {
729
+ return __awaiter(this, void 0, void 0, function* () {
730
+ return [
731
+ (0, module_kit_1.newUnsignedTransaction)({
732
+ transactions: [yield (0, ICPGovernance_1.prepareGetNeuronInfo)()]
733
+ })
734
+ ];
564
735
  });
565
736
  }
566
- getNeuronVotingPower(neuronId) {
737
+ prepareStartDissolving(publicKey) {
567
738
  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();
739
+ return [
740
+ (0, module_kit_1.newUnsignedTransaction)({
741
+ transactions: [yield (0, ICPGovernance_1.prepareStartDissolving)(publicKey.value)]
742
+ })
743
+ ];
744
+ });
745
+ }
746
+ prepareDisburse(publicKey) {
747
+ return __awaiter(this, void 0, void 0, function* () {
748
+ return [
749
+ (0, module_kit_1.newUnsignedTransaction)({
750
+ transactions: [yield (0, ICPGovernance_1.prepareDisburse)(publicKey.value)]
751
+ })
752
+ ];
753
+ });
754
+ }
755
+ getMaxStakingAmount(publicKey) {
756
+ var _a, _b;
757
+ return __awaiter(this, void 0, void 0, function* () {
758
+ const balance = yield this.getBalanceOfPublicKey(publicKey);
759
+ const { subAccount } = (0, ICPImplementation_1.getFixedSubaccountFromPublicKey)(publicKey.value);
760
+ const accountIdentifier = account_1.AccountIdentifier.fromPrincipal({
761
+ principal: principal_1.Principal.from(this.options.network.ledgerCanisterId),
762
+ subAccount: subAccount
763
+ });
764
+ const fee = yield this.getTransactionFeeWithPublicKey(publicKey, [
765
+ {
766
+ to: accountIdentifier.toHex(),
767
+ amount: (_a = balance.transferable) !== null && _a !== void 0 ? _a : balance.total
768
+ }
769
+ ]);
770
+ const maxAmount = (0, module_kit_1.newAmount)((_b = balance.transferable) !== null && _b !== void 0 ? _b : balance.total)
771
+ .blockchain(this.units)
772
+ .toBigNumber()
773
+ .minus((0, module_kit_1.newAmount)(fee).blockchain(this.units).value);
774
+ return (0, module_kit_1.newAmount)(maxAmount, 'blockchain');
775
+ });
776
+ }
777
+ getKnownNeurons() {
778
+ return __awaiter(this, void 0, void 0, function* () {
779
+ return (0, ICPImplementation_1.listKnownNeurons)(this.options.network.rpcUrl, this.options.network.governanceCanisterId);
573
780
  });
574
781
  }
575
782
  getNeuron(publicKey) {
576
783
  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);
784
+ const neuron = yield (0, ICPImplementation_1.getNeuronInfoBySubAccount)(publicKey.value, this.options.network.rpcUrl, this.options.network.governanceCanisterId);
578
785
  return neuron;
579
786
  });
580
787
  }
581
788
  getNeuronBalance(publicKey) {
582
789
  return __awaiter(this, void 0, void 0, function* () {
583
790
  // Create subaccount from publicKey
584
- const { subAccount, nonce: _ } = (0, ICPImplementation_1.getFixedSubaccountFromPublicKey)(publicKey);
791
+ const { subAccount, nonce: _ } = (0, ICPImplementation_1.getFixedSubaccountFromPublicKey)(publicKey.value);
585
792
  const accountIdentifier = account_1.AccountIdentifier.fromPrincipal({
586
- principal: principal_1.Principal.from(this.options.network.ledgerCanisterId),
793
+ principal: principal_1.Principal.from(this.options.network.governanceCanisterId),
587
794
  subAccount: subAccount
588
795
  });
589
796
  return this.getBalanceOfAddress(accountIdentifier.toHex());
@@ -599,10 +806,7 @@ class ICPProtocolImpl {
599
806
  dissolveState.WhenDissolvedTimestampSeconds > BigInt(0));
600
807
  }
601
808
  canNeuronDisburse(neuron) {
602
- const dissolveState = neuron.dissolve_state[0];
603
- return (dissolveState !== undefined &&
604
- 'WhenDissolvedTimestampSeconds' in dissolveState &&
605
- dissolveState.WhenDissolvedTimestampSeconds === BigInt(0));
809
+ return neuron.dissolve_delay_seconds === BigInt(0) && neuron.stake_e8s > BigInt(0);
606
810
  }
607
811
  }
608
812
  exports.ICPProtocolImpl = ICPProtocolImpl;