@kehtus/proportion-sdk 0.1.0 → 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/src/account.ts CHANGED
@@ -52,8 +52,6 @@ export class AccountModule {
52
52
  { ...contract, functionName: "subscriptionCancelled" },
53
53
  { ...contract, functionName: "pendingSubscriptionFee" },
54
54
  { ...contract, functionName: "apiWallet" },
55
- { ...contract, functionName: "riskEngineWallet" },
56
- { ...contract, functionName: "builderRiskEngineWallet" },
57
55
  { ...contract, functionName: "checkpointIndex" },
58
56
  { ...contract, functionName: "profitableDaysCount" },
59
57
  { ...contract, functionName: "totalCheckpoints" },
@@ -70,10 +68,10 @@ export class AccountModule {
70
68
  ],
71
69
  });
72
70
 
73
- const checkpointIndex = results[16].result!;
74
- const totalCp = results[18].result!;
75
- const [profit, requestedAt] = results[22].result!;
76
- const rawCheckpoints = results[28].result!;
71
+ const checkpointIndex = results[14].result!;
72
+ const totalCp = results[16].result!;
73
+ const profit = results[20].result! as bigint;
74
+ const rawCheckpoints = results[26].result!;
77
75
  const checkpoints = normalizeCheckpoints(rawCheckpoints, totalCp, checkpointIndex);
78
76
 
79
77
  return {
@@ -92,20 +90,18 @@ export class AccountModule {
92
90
  subscriptionCancelled: results[11].result!,
93
91
  pendingSubscriptionFee: results[12].result!,
94
92
  apiWallet: results[13].result!,
95
- riskEngineWallet: results[14].result!,
96
- builderRiskEngineWallet: results[15].result!,
97
93
  checkpointIndex,
98
- profitableDaysCount: results[17].result!,
94
+ profitableDaysCount: results[15].result!,
99
95
  totalCheckpoints: totalCp,
100
- lastCheckpointDay: results[19].result!,
101
- closingInitiatedAt: Number(results[20].result!),
102
- returnInitiatedAt: Number(results[21].result!),
103
- pendingWithdrawal: { profit, requestedAt: Number(requestedAt) },
104
- trailingFloor: results[23].result!,
105
- dailyFloor: results[24].result!,
106
- subscriptionFee: results[25].result!,
107
- isSubscriptionActive: results[26].result!,
108
- canWithdrawProfit: results[27].result!,
96
+ lastCheckpointDay: results[17].result!,
97
+ closingInitiatedAt: Number(results[18].result!),
98
+ returnInitiatedAt: Number(results[19].result!),
99
+ pendingWithdrawal: { profit },
100
+ trailingFloor: results[21].result!,
101
+ dailyFloor: results[22].result!,
102
+ subscriptionFee: results[23].result!,
103
+ isSubscriptionActive: results[24].result!,
104
+ canWithdrawProfit: results[25].result!,
109
105
  checkpoints,
110
106
  };
111
107
  }
@@ -174,13 +170,13 @@ export class AccountModule {
174
170
  return normalizeCheckpoints(all, Number(total), Number(checkpointIndex));
175
171
  }
176
172
 
177
- async getPendingWithdrawal(account: Address): Promise<{ profit: bigint; requestedAt: number }> {
178
- const result = await this.publicClient.readContract({
173
+ async getPendingWithdrawal(account: Address): Promise<{ profit: bigint }> {
174
+ const profit = await this.publicClient.readContract({
179
175
  address: account,
180
176
  abi: fundedAccountAbi,
181
177
  functionName: "pendingWithdrawal",
182
- });
183
- return { profit: result[0], requestedAt: Number(result[1]) };
178
+ }) as bigint;
179
+ return { profit };
184
180
  }
185
181
 
186
182
  async getAccountConfig(account: Address): Promise<{
@@ -243,14 +239,6 @@ export class AccountModule {
243
239
  });
244
240
  }
245
241
 
246
- async cancelStuckWithdrawal(account: Address): Promise<Hash> {
247
- return this.write({
248
- address: account,
249
- abi: fundedAccountAbi,
250
- functionName: "cancelStuckWithdrawal",
251
- });
252
- }
253
-
254
242
  // ── PERMISSIONLESS WRITES ───────────────────────────
255
243
 
256
244
  async checkpoint(account: Address): Promise<Hash> {
@@ -294,6 +282,14 @@ export class AccountModule {
294
282
  });
295
283
  }
296
284
 
285
+ async bridgeToEvm(account: Address): Promise<Hash> {
286
+ return this.write({
287
+ address: account,
288
+ abi: fundedAccountAbi,
289
+ functionName: "bridgeToEvm",
290
+ });
291
+ }
292
+
297
293
  async finalizeReturn(account: Address): Promise<Hash> {
298
294
  return this.write({
299
295
  address: account,
@@ -326,14 +322,4 @@ export class AccountModule {
326
322
  });
327
323
  }
328
324
 
329
- // ── RISK ENGINE WRITES ──────────────────────────────
330
-
331
- async setRiskEngineWallet(account: Address, wallet: Address): Promise<Hash> {
332
- return this.write({
333
- address: account,
334
- abi: fundedAccountAbi,
335
- functionName: "setRiskEngineWallet",
336
- args: [wallet],
337
- });
338
- }
339
325
  }
package/src/constants.ts CHANGED
@@ -13,8 +13,9 @@ export const hyperEvm = {
13
13
  } as const satisfies Chain;
14
14
 
15
15
  export const ADDRESSES = {
16
- MAIN_VAULT: "0x4478888dA8d22E275344C1A24BDEbcf2bfE2dc45",
17
- FACTORY: "0xb7cE604a000CCFCe7c7DAfFBaefD26c33C86CE7A",
16
+ MAIN_VAULT: "0x3A8cD3feb02959B2AB622Fcebe40A477c73f9488",
17
+ FACTORY: "0x04B71DC7414Bfa940D1c11f839011B6a11031D2E",
18
+ FORWARDER: "0x5961880B2C461F9733EC71720528461840881f4E",
18
19
  USDC: "0xb88339CB7199b77E23DB6E890353E22632Ba630f",
19
20
  } as const;
20
21
 
@@ -33,12 +34,12 @@ export const HYPE_FOR_GAS = 1_000_000_000_000_000n; // 0.001 ether
33
34
 
34
35
  // Decimals
35
36
  export const USDC_DECIMALS = 6;
36
- export const ACCOUNT_VALUE_DECIMALS = 8;
37
- export const DECIMALS_MULTIPLIER = 100n; // 68 dec
37
+ export const ACCOUNT_VALUE_DECIMALS = 8; // spotBalance, spotSend
38
+ export const DECIMALS_MULTIPLIER = 100n; // 6dec8dec (used for spotSend conversion)
39
+ // Note: accountValue, HWM, dayStartValue, floors are all 6dec (accountMarginSummary returns 6dec)
38
40
 
39
41
  // Time (seconds)
40
42
  export const SUBSCRIPTION_PERIOD = 30 * 86400;
41
- export const WITHDRAWAL_TIMEOUT = 7 * 86400;
42
43
  export const BRIDGE_DELAY = 30;
43
44
  export const CLOSING_TIMEOUT = 3 * 86400;
44
45
  export const CHECKPOINT_INTERVAL = 86400;
package/src/indexer.ts CHANGED
@@ -43,7 +43,7 @@ export class IndexerModule {
43
43
 
44
44
  private static readonly PAGE_SIZE = 1000;
45
45
  private static readonly VAULT_FIELDS = `id address totalDeposits totalWithdrawals totalActivationFees cumulativeActivationFeesToVault totalAllocated totalShares cumulativeProfitShares cumulativeCancelledProfit cumulativeSubscriptionFees cumulativeProtocolFeesRouted cumulativeHypercoreFees cumulativeAccountGains cumulativeAccountLosses cumulativeRescuedFunds totalAccountsActivated totalAccountsActive totalAccountsClosed paused subscriptionFeeMultiplier protocolFeeBps protocolFeeReceiver updatedAt`;
46
- private static readonly ACCOUNT_FIELDS = `id owner builder { id address vaultAddress } vaultAddress factoryAddress state accountSize drawdownBps dailyDrawdownEnabled activationFee highWaterMark profitableDaysCount lastCheckpointDay totalCheckpoints subscriptionPaidUntil subscriptionCancelled pendingSubscriptionFee subscriptionFeeMultiplier dayStartValue apiWallet riskEngineWallet builderRiskEngineWallet createdAt activatedAt closingInitiatedAt returnInitiatedAt closedAt returnedAmount breachType breachValue breachFloor closePendingSubFee closePendingProfit lastWithdrawalId updatedAt`;
46
+ private static readonly ACCOUNT_FIELDS = `id owner builder { id address vaultAddress } vaultAddress factoryAddress state accountSize drawdownBps dailyDrawdownEnabled activationFee highWaterMark profitableDaysCount lastCheckpointDay totalCheckpoints subscriptionPaidUntil subscriptionCancelled pendingSubscriptionFee subscriptionFeeMultiplier dayStartValue apiWallet createdAt activatedAt closingInitiatedAt returnInitiatedAt closedAt returnedAmount breachType breachValue breachFloor closePendingSubFee closePendingProfit lastWithdrawalId updatedAt`;
47
47
  private static readonly MAIN_VAULT_CONFIG_FIELDS = `id vaultAddress factoryAddress owner pendingOwner relayer paused protocolFeeReceiver feeMultiplier subscriptionFeeMultiplier dailyDdDiscountBps minBuilderShares builderLeverage protocolFeeBps minAccountSize maxAccountSize minDrawdownBps maxDrawdownBps maxUtilizationBps maxSingleAccountBps hypeForSpot maxCap createdAt updatedAt`;
48
48
  private static readonly FACTORY_CONFIG_FIELDS = `id factoryAddress vaultAddress owner pendingOwner createdAt updatedAt`;
49
49
  private static readonly CONFIG_CHANGE_FIELDS = `id contractAddress contractType field oldValue newValue blockNumber timestamp txHash`;
package/src/types.ts CHANGED
@@ -58,7 +58,6 @@ export type IndexerAccountStateLabel =
58
58
  export type BreachType =
59
59
  | "TRAILING_DRAWDOWN"
60
60
  | "DAILY_DRAWDOWN"
61
- | "LEVERAGE"
62
61
  | "POSITION_LEVERAGE"
63
62
  | "UNAUTHORIZED_ASSET"
64
63
  | "SUBSCRIPTION_EXPIRED";
@@ -123,15 +122,13 @@ export interface AccountDetails {
123
122
  subscriptionCancelled: boolean;
124
123
  pendingSubscriptionFee: bigint;
125
124
  apiWallet: Address;
126
- riskEngineWallet: Address;
127
- builderRiskEngineWallet: Address;
128
125
  checkpointIndex: number;
129
126
  totalCheckpoints: number;
130
127
  profitableDaysCount: number;
131
128
  lastCheckpointDay: bigint;
132
129
  closingInitiatedAt: number;
133
130
  returnInitiatedAt: number;
134
- pendingWithdrawal: { profit: bigint; requestedAt: number };
131
+ pendingWithdrawal: { profit: bigint };
135
132
  trailingFloor: bigint;
136
133
  dailyFloor: bigint;
137
134
  subscriptionFee: bigint;
@@ -214,8 +211,6 @@ export interface GqlAccount {
214
211
  subscriptionFeeMultiplier: number;
215
212
  dayStartValue: string;
216
213
  apiWallet: string | null;
217
- riskEngineWallet: string | null;
218
- builderRiskEngineWallet: string | null;
219
214
  createdAt: string;
220
215
  activatedAt: string | null;
221
216
  closingInitiatedAt: string | null;
package/src/utils.ts CHANGED
@@ -35,7 +35,7 @@ export function formatUsd(amount: bigint, dec: number = USDC_DECIMALS): string {
35
35
  return "$" + num.toLocaleString("en-US", { minimumFractionDigits: 2, maximumFractionDigits: 2 });
36
36
  }
37
37
 
38
- // ── Drawdown ────────────────────────────────────────
38
+ // ── Drawdown (all values in 6dec — matching on-chain HWM/dayStartValue) ──
39
39
 
40
40
  export function trailingFloor(hwm: bigint, drawdownBps: number): bigint {
41
41
  return hwm - (hwm * BigInt(drawdownBps)) / BPS;
@@ -1,197 +0,0 @@
1
- # План улучшения Proportion SDK
2
-
3
- ## Статус после повторной сверки
4
-
5
- Этот документ обновлён после повторной проверки against:
6
-
7
- - `contracts/MainVault.sol`
8
- - `contracts/FundedAccount.sol`
9
- - `contracts/FundedAccountFactory.sol`
10
- - `prop-sdk/src/*`
11
- - критичные indexer-файлы `envio-funded/schema.graphql` и `envio-funded/src/EventHandlers.ts`
12
-
13
- Если этот план и Solidity расходятся, Solidity остаётся source of truth.
14
-
15
- ## Что уже закрыто
16
-
17
- ### Контрактная синхронизация
18
-
19
- - ABI в SDK синхронизированы с текущими локальными контрактами.
20
- - Формулы `activationFee`, `subscriptionFee`, `splitProfit`, `trailingFloor`, `dailyFloor` приведены к актуальной Solidity-логике.
21
- - `arch.md` обновлён и теперь описывает текущий surface SDK, а не старую версию контрактов.
22
-
23
- ### VaultModule
24
-
25
- - Добавлены admin setters для текущих mutable параметров vault:
26
- - `setFeeMultiplier`
27
- - `setSubscriptionFeeMultiplier`
28
- - `setHypeForSpot`
29
- - `setMaxCap`
30
- - `setMinBuilderShares`
31
- - `setBuilderLeverage`
32
- - `setProtocolFeeBps`
33
- - `setMinAccountSize`
34
- - `setMaxAccountSize`
35
- - `setMinDrawdownBps`
36
- - `setMaxDrawdownBps`
37
- - `setMaxUtilizationBps`
38
- - `setMaxSingleAccountBps`
39
- - `getStats()` расширен и читает текущий конфиг и runtime state vault.
40
- - Добавлены utility getters:
41
- - `isFundedAccount`
42
- - `getDelegateBuilder`
43
- - `getRemainingCap`
44
- - `activateFunded()` больше не полагается на stale native fee default и читает `hypeForSpot()` из vault.
45
-
46
- ### AccountModule
47
-
48
- - Добавлен `initiateCloseAdmin`.
49
- - Добавлен `getAccountConfig()`.
50
- - `getDetails()` теперь возвращает `subscriptionFeeMultiplier`, `checkpointIndex` и нормализованные checkpoints вместо сырого ring-buffer порядка.
51
- - Текущий write surface выровнен с локальным `FundedAccount.sol`.
52
-
53
- ### FactoryModule
54
-
55
- - SDK переведён на реальный on-chain surface новой фабрики:
56
- - `allAccounts(index)`
57
- - `allAccountsIndex(account)`
58
- - `traderBuilderNonce(owner, builder)`
59
- - `predictFundedAccountAddress(owner, builder)`
60
- - Сохранены совместимые helper-методы `getAccountsCount()` и `getAccounts()`, но теперь они реализованы поверх probing `allAccounts(index)`.
61
- - Добавлены safe helpers:
62
- - `hasAccount`
63
- - `findAccountIndex`
64
-
65
- ### Indexer Layer
66
-
67
- - GraphQL-типы приведены к реальной `schema.graphql`.
68
- - Разделены on-chain state labels и indexer state labels.
69
- - Учтён `POSITION_LEVERAGE`.
70
- - Учтены дополнительные индексируемые поля вроде `subscriptionFeeMultiplier`, `lastWithdrawalId`, `totalAllocated`, `totalShares`.
71
- - Vault analytics больше не должны опираться на жёстко зашитый 90/10 split: актуальны `protocolFeeReceiver`, mutable `PROTOCOL_FEE_BPS` и фактический amount, остающийся в vault.
72
- - Для service/backend use cases добавлена инъекция `fetchFn` и `webSocketCtor`, чтобы SDK не зависел жёстко от глобальных runtime объектов.
73
-
74
- ## Что в старом плане устарело
75
-
76
- ### Устаревшие статусы
77
-
78
- Следующие пункты были верны для прошлой версии SDK, но уже закрыты:
79
-
80
- - отсутствие `initiateCloseAdmin`
81
- - отсутствие `getAccountConfig`
82
- - отсутствие большинства admin setters в `VaultModule`
83
- - неполный `VaultStats`
84
- - отсутствие `isFundedAccount` и `getDelegateBuilder`
85
-
86
- ### Устаревшие константы
87
-
88
- В старом плане были значения, которые больше не совпадают с текущими контрактами:
89
-
90
- - `MIN_PROFIT_BPS` указан как `150`, но в текущем `FundedAccount.sol` он равен `50`
91
- - важные экспортируемые значения нужно сверять с локальной Solidity, а не со старым plan draft
92
-
93
- ### Необязательная рекомендация про отдельный `AdminModule`
94
-
95
- Идея отдельного `AdminModule` сама по себе нормальная, но сейчас это не must-have.
96
- Текущий `VaultModule` уже покрывает актуальный owner admin surface без архитектурного долга, который требовал бы срочного выделения нового модуля.
97
-
98
- ## Что остаётся актуальным
99
-
100
- ### Phase 2. Улучшения API и DX
101
-
102
- 1. Выровнять числовую модель SDK для service use cases.
103
- Сейчас часть helper-ов (`fromUsdc`, `from8Dec`, `formatUsd`) переводит `bigint` в `number`, что удобно для UI, но не идеально для финансовой серверной логики.
104
-
105
- 2. Выровнять timestamp-модель.
106
- Сейчас часть временных полей в `AccountDetails` хранится как `bigint`, часть как `number`. Лучше выбрать одну ясную стратегию API.
107
-
108
- 3. Добавить типы для параметризуемого admin-конфига.
109
- Практичный следующий шаг:
110
-
111
- ```ts
112
- export interface VaultParameters {
113
- feeMultiplier: number;
114
- subscriptionFeeMultiplier: number;
115
- minBuilderShares: bigint;
116
- builderLeverage: bigint;
117
- protocolFeeBps: bigint;
118
- minAccountSize: bigint;
119
- maxAccountSize: bigint;
120
- minDrawdownBps: number;
121
- maxDrawdownBps: number;
122
- maxUtilizationBps: bigint;
123
- maxSingleAccountBps: bigint;
124
- hypeForSpot: bigint;
125
- maxCap: bigint;
126
- }
127
- ```
128
-
129
- 4. Добавить validation helpers поверх текущего `VaultStats`.
130
- Это уже полезный SDK-level слой, который не зависит от деплоя:
131
-
132
- ```ts
133
- export function validateAccountSize(size: bigint, vaultStats: VaultStats): {
134
- valid: boolean;
135
- reason?: string;
136
- }
137
-
138
- export function validateDrawdownBps(bps: number, vaultStats: VaultStats): {
139
- valid: boolean;
140
- reason?: string;
141
- }
142
-
143
- export function canBuilderActivate(
144
- builderInfo: BuilderInfo,
145
- accountSize: bigint,
146
- vaultStats: VaultStats
147
- ): {
148
- canActivate: boolean;
149
- reason?: string;
150
- }
151
- ```
152
-
153
- ### Phase 3. Дополнительные helper-обёртки
154
-
155
- 1. Batch reads:
156
-
157
- ```ts
158
- async getMultipleLPPositions(addresses: Address[]): Promise<LPPosition[]>
159
- async getMultipleBuilderInfo(addresses: Address[]): Promise<BuilderInfo[]>
160
- async getMultipleAccountDetails(addresses: Address[]): Promise<AccountDetails[]>
161
- ```
162
-
163
- 2. Дополнительные indexer helpers:
164
-
165
- ```ts
166
- async getEventsByDateRange(
167
- accountAddress: Address,
168
- fromDate: Date,
169
- toDate: Date
170
- ): Promise<GqlAccountEvent[]>
171
-
172
- async getCheckpointHistory(
173
- accountAddress: Address,
174
- limit?: number
175
- ): Promise<GqlCheckpoint[]>
176
- ```
177
-
178
- 3. Higher-level admin ergonomics:
179
-
180
- - `getCurrentParameters()`
181
- - `validateParameters()`
182
- - опциональный bulk-update helper для owner workflows
183
-
184
- ## Рекомендуемый следующий порядок работ
185
-
186
- 1. Сначала привести numeric/timestamp API к более строгой и единообразной модели.
187
- 2. Затем добавить validation helpers поверх уже актуального `VaultStats`.
188
- 3. После этого расширять batch helpers и high-level admin ergonomics.
189
-
190
- ## Проверка
191
-
192
- После последних изменений:
193
-
194
- - `npm run check` проходит
195
- - `npm run test:unit` проходит
196
-
197
- RPC/GraphQL-зависимые тесты не считаются источником истины, пока локальные контракты не задеплоены.