@ritbit/v4-client-js 2.2.4 → 2.2.5

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.
Files changed (36) hide show
  1. package/build/cjs/src/clients/composite-client.js +2 -2
  2. package/build/cjs/src/clients/modules/get.js +35 -36
  3. package/build/cjs/src/clients/modules/post.js +8 -4
  4. package/build/cjs/src/clients/validator-client.js +3 -2
  5. package/build/cjs/src/index.js +2 -5
  6. package/build/cjs/tsconfig.cjs.tsbuildinfo +1 -1
  7. package/build/esm/src/clients/composite-client.d.ts +3 -1
  8. package/build/esm/src/clients/composite-client.d.ts.map +1 -1
  9. package/build/esm/src/clients/composite-client.js +2 -2
  10. package/build/esm/src/clients/modules/get.d.ts +18 -18
  11. package/build/esm/src/clients/modules/get.d.ts.map +1 -1
  12. package/build/esm/src/clients/modules/get.js +35 -36
  13. package/build/esm/src/clients/modules/post.d.ts +4 -1
  14. package/build/esm/src/clients/modules/post.d.ts.map +1 -1
  15. package/build/esm/src/clients/modules/post.js +8 -4
  16. package/build/esm/src/clients/validator-client.d.ts +4 -1
  17. package/build/esm/src/clients/validator-client.d.ts.map +1 -1
  18. package/build/esm/src/clients/validator-client.js +3 -2
  19. package/build/esm/src/index.d.ts +0 -1
  20. package/build/esm/src/index.d.ts.map +1 -1
  21. package/build/esm/src/index.js +1 -2
  22. package/build/esm/tsconfig.esm.tsbuildinfo +1 -1
  23. package/package.json +1 -1
  24. package/ritbit-v4-client-js-2.2.5.tgz +0 -0
  25. package/scripts/publish-if-not-exists.sh +4 -4
  26. package/src/clients/composite-client.ts +4 -2
  27. package/src/clients/modules/get.ts +49 -43
  28. package/src/clients/modules/post.ts +10 -4
  29. package/src/clients/validator-client.ts +5 -2
  30. package/src/index.ts +0 -6
  31. package/tsconfig.json +6 -0
  32. package/build/cjs/src/lib/vesting.js +0 -170
  33. package/build/esm/src/lib/vesting.d.ts +0 -42
  34. package/build/esm/src/lib/vesting.d.ts.map +0 -1
  35. package/build/esm/src/lib/vesting.js +0 -133
  36. package/src/lib/vesting.ts +0 -153
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ritbit/v4-client-js",
3
- "version": "2.2.4",
3
+ "version": "2.2.5",
4
4
  "description": "General client library for the new RITBIT Chain",
5
5
  "main": "build/cjs/src/index.js",
6
6
  "module": "build/esm/src/index.js",
Binary file
@@ -10,12 +10,12 @@ if [ $? -eq 0 ]; then
10
10
 
11
11
  # git config --global user.email "ci@ritbit.trade"
12
12
  # git config --global user.name "gitlab_actions"
13
+
14
+ npm publish
13
15
 
14
16
  # Get version and tag
15
- # git tag ritbit-client-js@${VERSION}
16
- # git push --tags
17
-
18
- npm publish
17
+ git tag ritbit-client-js@${VERSION}
18
+ git push --tags
19
19
  else
20
20
  echo "skipping publish, package $NAME@$VERSION already published"
21
21
  fi
@@ -148,9 +148,11 @@ export class CompositeClient {
148
148
  this._validatorClient.setSelectedGasDenom(gasDenom);
149
149
  }
150
150
 
151
- async populateAccountNumberCache(address: string): Promise<void> {
151
+ async populateAccountNumberCache(
152
+ address: string
153
+ ): Promise<{ typeUrl: string } | undefined> {
152
154
  if (!this._validatorClient) throw new Error('Validator client not initialized');
153
- await this._validatorClient.populateAccountNumberCache(address);
155
+ return this._validatorClient.populateAccountNumberCache(address);
154
156
  }
155
157
 
156
158
  /**
@@ -14,15 +14,10 @@ import {
14
14
  import { UserStats } from '@ritbit/v4-proto/src/codegen/ritbit/stats/stats';
15
15
  import * as AuthModule from 'cosmjs-types/cosmos/auth/v1beta1/query';
16
16
  import * as BankModule from 'cosmjs-types/cosmos/bank/v1beta1/query';
17
- import { Any } from 'cosmjs-types/google/protobuf/any';
18
17
  import Long from 'long';
19
18
  import protobuf from 'protobufjs';
20
19
 
21
20
  import { bigIntToBytes } from '../../lib/helpers';
22
- import {
23
- computeUnlockedAmount,
24
- decodeVestingFromAny,
25
- } from '../../lib/vesting';
26
21
  import { PAGE_REQUEST } from '../constants';
27
22
  import { UnexpectedClientError } from '../lib/errors';
28
23
  import {
@@ -173,6 +168,46 @@ export class Get {
173
168
  return coin;
174
169
  }
175
170
 
171
+ /**
172
+ * @description Get spendable (unlocked) balance of one denom for an account.
173
+ * For vesting accounts returns only the unlocked portion; for regular accounts equals full balance.
174
+ *
175
+ * @returns Coin spendable balance for denom.
176
+ */
177
+ async getSpendableBalance(address: string, denom: string): Promise<Coin | undefined> {
178
+ const requestData: Uint8Array = Uint8Array.from(
179
+ BankModule.QuerySpendableBalanceByDenomRequest.encode({
180
+ address,
181
+ denom,
182
+ }).finish(),
183
+ );
184
+
185
+ const data: Uint8Array = await this.sendQuery(
186
+ '/cosmos.bank.v1beta1.Query/SpendableBalanceByDenom',
187
+ requestData,
188
+ );
189
+ const coin = BankModule.QuerySpendableBalanceByDenomResponse.decode(data).balance;
190
+ return coin;
191
+ }
192
+
193
+ /**
194
+ * @description Get all spendable (unlocked) balances for an account.
195
+ * For vesting accounts returns only unlocked portions; for regular accounts equals full balances.
196
+ *
197
+ * @returns Array of Coin spendable balances.
198
+ */
199
+ async getSpendableBalances(address: string): Promise<Coin[]> {
200
+ const requestData: Uint8Array = Uint8Array.from(
201
+ BankModule.QuerySpendableBalancesRequest.encode({ address }).finish(),
202
+ );
203
+
204
+ const data: Uint8Array = await this.sendQuery(
205
+ '/cosmos.bank.v1beta1.Query/SpendableBalances',
206
+ requestData,
207
+ );
208
+ return BankModule.QuerySpendableBalancesResponse.decode(data).balances;
209
+ }
210
+
176
211
  /**
177
212
  * @description Get all subaccounts
178
213
  *
@@ -328,14 +363,13 @@ export class Get {
328
363
  }
329
364
 
330
365
  /**
331
- * @description Get raw account (Any) for an address or the promise is rejected if the account
332
- * does not exist on-chain. Use this when you need vesting/account type details (e.g. decoding
333
- * ContinuousVestingAccount) instead of the normalized Account from getAccount.
366
+ * @description Get Account for an address or the promise is rejected if the account
367
+ * does not exist on-chain.
334
368
  *
335
369
  * @throws UnexpectedClientError if a malformed response is returned with no GRPC error.
336
- * @returns The raw account as protobuf Any (typeUrl + value).
370
+ * @returns An account with typeUrl for a given address.
337
371
  */
338
- async getAccountRaw(address: string): Promise<Any> {
372
+ async getAccount(address: string): Promise<Account & { typeUrl: string }> {
339
373
  const requestData: Uint8Array = Uint8Array.from(
340
374
  AuthModule.QueryAccountRequest.encode({ address }).finish(),
341
375
  );
@@ -344,43 +378,15 @@ export class Get {
344
378
  '/cosmos.auth.v1beta1.Query/Account',
345
379
  requestData,
346
380
  );
347
- const rawAccount: Any | undefined = AuthModule.QueryAccountResponse.decode(data).account;
381
+ const rawAccount = AuthModule.QueryAccountResponse.decode(data).account;
348
382
 
349
383
  if (rawAccount === undefined) {
350
384
  throw new UnexpectedClientError();
351
385
  }
352
- return rawAccount;
353
- }
354
-
355
- /**
356
- * @description Get Account for an address or the promise is rejected if the account
357
- * does not exist on-chain.
358
- *
359
- * @throws UnexpectedClientError if a malformed response is returned with no GRPC error.
360
- * @returns An account for a given address.
361
- */
362
- async getAccount(address: string): Promise<Account> {
363
- const rawAccount = await this.getAccountRaw(address);
364
- return accountFromAny(rawAccount);
365
- }
366
-
367
- /**
368
- * @description Get unlocked native amount for a vesting account (by denom).
369
- * Uses getAccountRaw and decodes vesting types (Continuous/Delayed/Periodic/Base).
370
- * @returns Unlocked amount in base units (string), or undefined if not vesting or denom not found.
371
- */
372
- async getAccountVesting(
373
- address: string,
374
- nativeDenom: string
375
- ): Promise<string | undefined> {
376
- try {
377
- const raw = await this.getAccountRaw(address);
378
- const info = decodeVestingFromAny(raw);
379
- if (!info) return undefined;
380
- return computeUnlockedAmount(info, nativeDenom);
381
- } catch {
382
- return undefined;
383
- }
386
+ return {
387
+ ...accountFromAny(rawAccount),
388
+ typeUrl: rawAccount.typeUrl,
389
+ };
384
390
  }
385
391
 
386
392
  /**
@@ -92,12 +92,17 @@ export class Post {
92
92
  * @description Retrieves the account number for the given wallet address and populates the accountNumberCache.
93
93
  * The account number is required for txOptions when signing a transaction.
94
94
  * Pre-populating the cache avoids a round-trip request during the first transaction creation in the session, preventing it from being a performance blocker.
95
+ * @returns { typeUrl } при первом вызове; undefined при cache hit (данные уже в кеше).
95
96
  */
96
- public async populateAccountNumberCache(address: string): Promise<void> {
97
- if (this.accountNumberCache.has(address)) return;
97
+ public async populateAccountNumberCache(
98
+ address: string
99
+ ): Promise<{ typeUrl: string } | undefined> {
100
+ if (this.accountNumberCache.has(address)) return undefined;
98
101
 
99
- const account = await this.get.getAccount(address);
102
+ const result = await this.get.getAccount(address);
103
+ const { typeUrl, ...account } = result;
100
104
  this.accountNumberCache.set(address, account);
105
+ return typeUrl != null ? { typeUrl } : undefined;
101
106
  }
102
107
 
103
108
  setSelectedGasDenom(selectedGasDenom: SelectedGasDenom): void {
@@ -310,7 +315,8 @@ export class Post {
310
315
  return this.accountNumberCache.get(address)!;
311
316
  }
312
317
  }
313
- const account = await this.get.getAccount(address);
318
+ const result = await this.get.getAccount(address);
319
+ const { typeUrl: _typeUrl, ...account } = result;
314
320
  this.accountNumberCache.set(address, account);
315
321
  return account;
316
322
  }
@@ -71,10 +71,13 @@ export class ValidatorClient {
71
71
 
72
72
  /**
73
73
  * @description populate account number cache in the Post module for performance.
74
+ * @returns { typeUrl } при первом вызове; undefined при cache hit.
74
75
  */
75
- async populateAccountNumberCache(address: string): Promise<void> {
76
+ async populateAccountNumberCache(
77
+ address: string
78
+ ): Promise<{ typeUrl: string } | undefined> {
76
79
  if (!this._post) throw new Error('Post module not initialized');
77
- await this._post.populateAccountNumberCache(address);
80
+ return this._post.populateAccountNumberCache(address);
78
81
  }
79
82
 
80
83
  private async initialize(): Promise<void> {
package/src/index.ts CHANGED
@@ -7,12 +7,6 @@ export * as onboarding from './lib/onboarding';
7
7
  export * as tradingKeyUtils from './lib/trading-key-utils';
8
8
  export * as utils from './lib/utils';
9
9
  export * as validation from './lib/validation';
10
- export {
11
- type VestingInfo,
12
- decodeVestingFromAny,
13
- computeUnlockedAmount,
14
- } from './lib/vesting';
15
-
16
10
  export { CompositeClient } from './clients/composite-client';
17
11
  export { FaucetClient } from './clients/faucet-client';
18
12
  export { IndexerClient } from './clients/indexer-client';
package/tsconfig.json ADDED
@@ -0,0 +1,6 @@
1
+ {
2
+ "extends": "./tsconfig.esm.json",
3
+ "compilerOptions": {
4
+ "noEmit": true
5
+ }
6
+ }
@@ -1,170 +0,0 @@
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 () {
19
- var ownKeys = function(o) {
20
- ownKeys = Object.getOwnPropertyNames || function (o) {
21
- var ar = [];
22
- for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
- return ar;
24
- };
25
- return ownKeys(o);
26
- };
27
- return function (mod) {
28
- if (mod && mod.__esModule) return mod;
29
- var result = {};
30
- if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
- __setModuleDefault(result, mod);
32
- return result;
33
- };
34
- })();
35
- Object.defineProperty(exports, "__esModule", { value: true });
36
- exports.decodeVestingFromAny = decodeVestingFromAny;
37
- exports.computeUnlockedAmount = computeUnlockedAmount;
38
- const Vesting = __importStar(require("cosmjs-types/cosmos/vesting/v1beta1/vesting"));
39
- const VESTING_TYPE_URLS = [
40
- '/cosmos.vesting.v1beta1.ContinuousVestingAccount',
41
- '/cosmos.vesting.v1beta1.DelayedVestingAccount',
42
- '/cosmos.vesting.v1beta1.PeriodicVestingAccount',
43
- '/cosmos.vesting.v1beta1.BaseVestingAccount',
44
- ];
45
- function bigintToNumber(value) {
46
- if (value == null || value === undefined)
47
- return 0;
48
- return Number(value);
49
- }
50
- /**
51
- * Декодирует сырой аккаунт (Any из getAccountRaw) в VestingInfo.
52
- * Возвращает null, если тип аккаунта не vesting или нет original_vesting.
53
- */
54
- function decodeVestingFromAny(raw) {
55
- var _a, _b, _c, _d;
56
- const { typeUrl, value } = raw;
57
- if (!VESTING_TYPE_URLS.some((u) => typeUrl === u)) {
58
- return null;
59
- }
60
- try {
61
- switch (typeUrl) {
62
- case '/cosmos.vesting.v1beta1.ContinuousVestingAccount': {
63
- const acc = Vesting.ContinuousVestingAccount.decode(value);
64
- const base = acc.baseVestingAccount;
65
- if (!((_a = base === null || base === void 0 ? void 0 : base.originalVesting) === null || _a === void 0 ? void 0 : _a.length))
66
- return null;
67
- return {
68
- originalVesting: base.originalVesting.map((c) => ({
69
- denom: c.denom,
70
- amount: c.amount,
71
- })),
72
- startTimeSec: bigintToNumber(acc.startTime),
73
- endTimeSec: bigintToNumber(base.endTime),
74
- };
75
- }
76
- case '/cosmos.vesting.v1beta1.DelayedVestingAccount': {
77
- const acc = Vesting.DelayedVestingAccount.decode(value);
78
- const base = acc.baseVestingAccount;
79
- if (!((_b = base === null || base === void 0 ? void 0 : base.originalVesting) === null || _b === void 0 ? void 0 : _b.length))
80
- return null;
81
- return {
82
- originalVesting: base.originalVesting.map((c) => ({
83
- denom: c.denom,
84
- amount: c.amount,
85
- })),
86
- startTimeSec: 0,
87
- endTimeSec: bigintToNumber(base.endTime),
88
- };
89
- }
90
- case '/cosmos.vesting.v1beta1.PeriodicVestingAccount': {
91
- const acc = Vesting.PeriodicVestingAccount.decode(value);
92
- const base = acc.baseVestingAccount;
93
- if (!((_c = base === null || base === void 0 ? void 0 : base.originalVesting) === null || _c === void 0 ? void 0 : _c.length))
94
- return null;
95
- return {
96
- originalVesting: base.originalVesting.map((c) => ({
97
- denom: c.denom,
98
- amount: c.amount,
99
- })),
100
- startTimeSec: bigintToNumber(acc.startTime),
101
- endTimeSec: bigintToNumber(base.endTime),
102
- vestingPeriods: acc.vestingPeriods.map((p) => ({
103
- lengthSec: bigintToNumber(p.length),
104
- amount: p.amount.map((c) => ({ denom: c.denom, amount: c.amount })),
105
- })),
106
- };
107
- }
108
- case '/cosmos.vesting.v1beta1.BaseVestingAccount': {
109
- const base = Vesting.BaseVestingAccount.decode(value);
110
- if (!((_d = base === null || base === void 0 ? void 0 : base.originalVesting) === null || _d === void 0 ? void 0 : _d.length))
111
- return null;
112
- return {
113
- originalVesting: base.originalVesting.map((c) => ({
114
- denom: c.denom,
115
- amount: c.amount,
116
- })),
117
- startTimeSec: 0,
118
- endTimeSec: bigintToNumber(base.endTime),
119
- };
120
- }
121
- default:
122
- return null;
123
- }
124
- }
125
- catch {
126
- return null;
127
- }
128
- }
129
- /**
130
- * Считает разблокированную сумму в base units для денома по VestingInfo.
131
- *
132
- * - Continuous / Delayed / Base: линейная разблокировка от startTimeSec до endTimeSec.
133
- * - Periodic: каждый период — клифф; сумма периода разблокируется целиком
134
- * по истечении его длительности (start + Σ lengths предыдущих + length текущего).
135
- */
136
- function computeUnlockedAmount(info, denom) {
137
- var _a, _b, _c;
138
- const entry = info.originalVesting.find((c) => c.denom === denom);
139
- if (!entry)
140
- return undefined;
141
- const total = BigInt(entry.amount);
142
- const { startTimeSec, endTimeSec } = info;
143
- if (startTimeSec === 0 && endTimeSec === 0)
144
- return entry.amount;
145
- const nowSec = Math.floor(Date.now() / 1000);
146
- if (nowSec <= startTimeSec)
147
- return '0';
148
- if (nowSec >= endTimeSec)
149
- return entry.amount;
150
- // Periodic: считаем по периодам (клиффы)
151
- if ((_a = info.vestingPeriods) === null || _a === void 0 ? void 0 : _a.length) {
152
- let unlocked = BigInt(0);
153
- let periodStartSec = startTimeSec;
154
- for (const p of info.vestingPeriods) {
155
- const periodEndSec = periodStartSec + p.lengthSec;
156
- if (nowSec >= periodEndSec) {
157
- const periodAmount = (_c = (_b = p.amount.find((c) => c.denom === denom)) === null || _b === void 0 ? void 0 : _b.amount) !== null && _c !== void 0 ? _c : '0';
158
- unlocked += BigInt(periodAmount);
159
- }
160
- periodStartSec = periodEndSec;
161
- }
162
- return String(unlocked);
163
- }
164
- // Linear (Continuous / Delayed / Base)
165
- const period = endTimeSec - startTimeSec;
166
- const elapsed = nowSec - startTimeSec;
167
- const unlocked = (total * BigInt(elapsed)) / BigInt(period);
168
- return String(unlocked);
169
- }
170
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidmVzdGluZy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9saWIvdmVzdGluZy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQTBDQSxvREFvRUM7QUFTRCxzREFpQ0M7QUF2SkQscUZBQXVFO0FBeUJ2RSxNQUFNLGlCQUFpQixHQUFHO0lBQ3hCLGtEQUFrRDtJQUNsRCwrQ0FBK0M7SUFDL0MsZ0RBQWdEO0lBQ2hELDRDQUE0QztDQUNwQyxDQUFDO0FBRVgsU0FBUyxjQUFjLENBQUMsS0FBeUI7SUFDL0MsSUFBSSxLQUFLLElBQUksSUFBSSxJQUFJLEtBQUssS0FBSyxTQUFTO1FBQUUsT0FBTyxDQUFDLENBQUM7SUFDbkQsT0FBTyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUM7QUFDdkIsQ0FBQztBQUVEOzs7R0FHRztBQUNILFNBQWdCLG9CQUFvQixDQUFDLEdBQVE7O0lBQzNDLE1BQU0sRUFBRSxPQUFPLEVBQUUsS0FBSyxFQUFFLEdBQUcsR0FBRyxDQUFDO0lBQy9CLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLE9BQU8sS0FBSyxDQUFDLENBQUMsRUFBRSxDQUFDO1FBQ2xELE9BQU8sSUFBSSxDQUFDO0lBQ2QsQ0FBQztJQUNELElBQUksQ0FBQztRQUNILFFBQVEsT0FBTyxFQUFFLENBQUM7WUFDaEIsS0FBSyxrREFBa0QsQ0FBQyxDQUFDLENBQUM7Z0JBQ3hELE1BQU0sR0FBRyxHQUFHLE9BQU8sQ0FBQyx3QkFBd0IsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUM7Z0JBQzNELE1BQU0sSUFBSSxHQUFHLEdBQUcsQ0FBQyxrQkFBa0IsQ0FBQztnQkFDcEMsSUFBSSxDQUFDLENBQUEsTUFBQSxJQUFJLGFBQUosSUFBSSx1QkFBSixJQUFJLENBQUUsZUFBZSwwQ0FBRSxNQUFNLENBQUE7b0JB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
@@ -1,42 +0,0 @@
1
- import { Any } from 'cosmjs-types/google/protobuf/any';
2
- /** Один период вестинга (для PeriodicVestingAccount). */
3
- export interface VestingPeriod {
4
- /** Длительность периода в секундах. */
5
- lengthSec: number;
6
- /** Монеты, разблокируемые в конце периода. */
7
- amount: Array<{
8
- denom: string;
9
- amount: string;
10
- }>;
11
- }
12
- /**
13
- * Нормализованная информация о вестинг-аккаунте, достаточная для расчёта
14
- * разблокированной суммы. Типы Continuous/Delayed/Periodic/Base сводятся к этому виду.
15
- */
16
- export interface VestingInfo {
17
- /** Монеты original_vesting (деном + количество в base units). */
18
- originalVesting: Array<{
19
- denom: string;
20
- amount: string;
21
- }>;
22
- /** Начало вестинга (Unix секунды). */
23
- startTimeSec: number;
24
- /** Конец вестинга (Unix секунды). */
25
- endTimeSec: number;
26
- /** Периоды (только для PeriodicVestingAccount). */
27
- vestingPeriods?: VestingPeriod[];
28
- }
29
- /**
30
- * Декодирует сырой аккаунт (Any из getAccountRaw) в VestingInfo.
31
- * Возвращает null, если тип аккаунта не vesting или нет original_vesting.
32
- */
33
- export declare function decodeVestingFromAny(raw: Any): VestingInfo | null;
34
- /**
35
- * Считает разблокированную сумму в base units для денома по VestingInfo.
36
- *
37
- * - Continuous / Delayed / Base: линейная разблокировка от startTimeSec до endTimeSec.
38
- * - Periodic: каждый период — клифф; сумма периода разблокируется целиком
39
- * по истечении его длительности (start + Σ lengths предыдущих + length текущего).
40
- */
41
- export declare function computeUnlockedAmount(info: VestingInfo, denom: string): string | undefined;
42
- //# sourceMappingURL=vesting.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"vesting.d.ts","sourceRoot":"","sources":["../../../../src/lib/vesting.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,kCAAkC,CAAC;AAGvD,yDAAyD;AACzD,MAAM,WAAW,aAAa;IAC5B,uCAAuC;IACvC,SAAS,EAAE,MAAM,CAAC;IAClB,8CAA8C;IAC9C,MAAM,EAAE,KAAK,CAAC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CAClD;AAED;;;GAGG;AACH,MAAM,WAAW,WAAW;IAC1B,iEAAiE;IACjE,eAAe,EAAE,KAAK,CAAC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC1D,sCAAsC;IACtC,YAAY,EAAE,MAAM,CAAC;IACrB,qCAAqC;IACrC,UAAU,EAAE,MAAM,CAAC;IACnB,mDAAmD;IACnD,cAAc,CAAC,EAAE,aAAa,EAAE,CAAC;CAClC;AAcD;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,GAAG,GAAG,WAAW,GAAG,IAAI,CAoEjE;AAED;;;;;;GAMG;AACH,wBAAgB,qBAAqB,CACnC,IAAI,EAAE,WAAW,EACjB,KAAK,EAAE,MAAM,GACZ,MAAM,GAAG,SAAS,CA8BpB"}
@@ -1,133 +0,0 @@
1
- import * as Vesting from 'cosmjs-types/cosmos/vesting/v1beta1/vesting';
2
- const VESTING_TYPE_URLS = [
3
- '/cosmos.vesting.v1beta1.ContinuousVestingAccount',
4
- '/cosmos.vesting.v1beta1.DelayedVestingAccount',
5
- '/cosmos.vesting.v1beta1.PeriodicVestingAccount',
6
- '/cosmos.vesting.v1beta1.BaseVestingAccount',
7
- ];
8
- function bigintToNumber(value) {
9
- if (value == null || value === undefined)
10
- return 0;
11
- return Number(value);
12
- }
13
- /**
14
- * Декодирует сырой аккаунт (Any из getAccountRaw) в VestingInfo.
15
- * Возвращает null, если тип аккаунта не vesting или нет original_vesting.
16
- */
17
- export function decodeVestingFromAny(raw) {
18
- var _a, _b, _c, _d;
19
- const { typeUrl, value } = raw;
20
- if (!VESTING_TYPE_URLS.some((u) => typeUrl === u)) {
21
- return null;
22
- }
23
- try {
24
- switch (typeUrl) {
25
- case '/cosmos.vesting.v1beta1.ContinuousVestingAccount': {
26
- const acc = Vesting.ContinuousVestingAccount.decode(value);
27
- const base = acc.baseVestingAccount;
28
- if (!((_a = base === null || base === void 0 ? void 0 : base.originalVesting) === null || _a === void 0 ? void 0 : _a.length))
29
- return null;
30
- return {
31
- originalVesting: base.originalVesting.map((c) => ({
32
- denom: c.denom,
33
- amount: c.amount,
34
- })),
35
- startTimeSec: bigintToNumber(acc.startTime),
36
- endTimeSec: bigintToNumber(base.endTime),
37
- };
38
- }
39
- case '/cosmos.vesting.v1beta1.DelayedVestingAccount': {
40
- const acc = Vesting.DelayedVestingAccount.decode(value);
41
- const base = acc.baseVestingAccount;
42
- if (!((_b = base === null || base === void 0 ? void 0 : base.originalVesting) === null || _b === void 0 ? void 0 : _b.length))
43
- return null;
44
- return {
45
- originalVesting: base.originalVesting.map((c) => ({
46
- denom: c.denom,
47
- amount: c.amount,
48
- })),
49
- startTimeSec: 0,
50
- endTimeSec: bigintToNumber(base.endTime),
51
- };
52
- }
53
- case '/cosmos.vesting.v1beta1.PeriodicVestingAccount': {
54
- const acc = Vesting.PeriodicVestingAccount.decode(value);
55
- const base = acc.baseVestingAccount;
56
- if (!((_c = base === null || base === void 0 ? void 0 : base.originalVesting) === null || _c === void 0 ? void 0 : _c.length))
57
- return null;
58
- return {
59
- originalVesting: base.originalVesting.map((c) => ({
60
- denom: c.denom,
61
- amount: c.amount,
62
- })),
63
- startTimeSec: bigintToNumber(acc.startTime),
64
- endTimeSec: bigintToNumber(base.endTime),
65
- vestingPeriods: acc.vestingPeriods.map((p) => ({
66
- lengthSec: bigintToNumber(p.length),
67
- amount: p.amount.map((c) => ({ denom: c.denom, amount: c.amount })),
68
- })),
69
- };
70
- }
71
- case '/cosmos.vesting.v1beta1.BaseVestingAccount': {
72
- const base = Vesting.BaseVestingAccount.decode(value);
73
- if (!((_d = base === null || base === void 0 ? void 0 : base.originalVesting) === null || _d === void 0 ? void 0 : _d.length))
74
- return null;
75
- return {
76
- originalVesting: base.originalVesting.map((c) => ({
77
- denom: c.denom,
78
- amount: c.amount,
79
- })),
80
- startTimeSec: 0,
81
- endTimeSec: bigintToNumber(base.endTime),
82
- };
83
- }
84
- default:
85
- return null;
86
- }
87
- }
88
- catch {
89
- return null;
90
- }
91
- }
92
- /**
93
- * Считает разблокированную сумму в base units для денома по VestingInfo.
94
- *
95
- * - Continuous / Delayed / Base: линейная разблокировка от startTimeSec до endTimeSec.
96
- * - Periodic: каждый период — клифф; сумма периода разблокируется целиком
97
- * по истечении его длительности (start + Σ lengths предыдущих + length текущего).
98
- */
99
- export function computeUnlockedAmount(info, denom) {
100
- var _a, _b, _c;
101
- const entry = info.originalVesting.find((c) => c.denom === denom);
102
- if (!entry)
103
- return undefined;
104
- const total = BigInt(entry.amount);
105
- const { startTimeSec, endTimeSec } = info;
106
- if (startTimeSec === 0 && endTimeSec === 0)
107
- return entry.amount;
108
- const nowSec = Math.floor(Date.now() / 1000);
109
- if (nowSec <= startTimeSec)
110
- return '0';
111
- if (nowSec >= endTimeSec)
112
- return entry.amount;
113
- // Periodic: считаем по периодам (клиффы)
114
- if ((_a = info.vestingPeriods) === null || _a === void 0 ? void 0 : _a.length) {
115
- let unlocked = BigInt(0);
116
- let periodStartSec = startTimeSec;
117
- for (const p of info.vestingPeriods) {
118
- const periodEndSec = periodStartSec + p.lengthSec;
119
- if (nowSec >= periodEndSec) {
120
- const periodAmount = (_c = (_b = p.amount.find((c) => c.denom === denom)) === null || _b === void 0 ? void 0 : _b.amount) !== null && _c !== void 0 ? _c : '0';
121
- unlocked += BigInt(periodAmount);
122
- }
123
- periodStartSec = periodEndSec;
124
- }
125
- return String(unlocked);
126
- }
127
- // Linear (Continuous / Delayed / Base)
128
- const period = endTimeSec - startTimeSec;
129
- const elapsed = nowSec - startTimeSec;
130
- const unlocked = (total * BigInt(elapsed)) / BigInt(period);
131
- return String(unlocked);
132
- }
133
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidmVzdGluZy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9saWIvdmVzdGluZy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFDQSxPQUFPLEtBQUssT0FBTyxNQUFNLDZDQUE2QyxDQUFDO0FBeUJ2RSxNQUFNLGlCQUFpQixHQUFHO0lBQ3hCLGtEQUFrRDtJQUNsRCwrQ0FBK0M7SUFDL0MsZ0RBQWdEO0lBQ2hELDRDQUE0QztDQUNwQyxDQUFDO0FBRVgsU0FBUyxjQUFjLENBQUMsS0FBeUI7SUFDL0MsSUFBSSxLQUFLLElBQUksSUFBSSxJQUFJLEtBQUssS0FBSyxTQUFTO1FBQUUsT0FBTyxDQUFDLENBQUM7SUFDbkQsT0FBTyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUM7QUFDdkIsQ0FBQztBQUVEOzs7R0FHRztBQUNILE1BQU0sVUFBVSxvQkFBb0IsQ0FBQyxHQUFROztJQUMzQyxNQUFNLEVBQUUsT0FBTyxFQUFFLEtBQUssRUFBRSxHQUFHLEdBQUcsQ0FBQztJQUMvQixJQUFJLENBQUMsaUJBQWlCLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxPQUFPLEtBQUssQ0FBQyxDQUFDLEVBQUUsQ0FBQztRQUNsRCxPQUFPLElBQUksQ0FBQztJQUNkLENBQUM7SUFDRCxJQUFJLENBQUM7UUFDSCxRQUFRLE9BQU8sRUFBRSxDQUFDO1lBQ2hCLEtBQUssa0RBQWtELENBQUMsQ0FBQyxDQUFDO2dCQUN4RCxNQUFNLEdBQUcsR0FBRyxPQUFPLENBQUMsd0JBQXdCLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDO2dCQUMzRCxNQUFNLElBQUksR0FBRyxHQUFHLENBQUMsa0JBQWtCLENBQUM7Z0JBQ3BDLElBQUksQ0FBQyxDQUFBLE1BQUEsSUFBSSxhQUFKLElBQUksdUJBQUosSUFBSSxDQUFFLGVBQWUsMENBQUUsTUFBTSxDQUFBO29CQUFFLE9BQU8sSUFBSSxDQUFDO2dCQUNoRCxPQUFPO29C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