defi-dash-sdk 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (50) hide show
  1. package/README.md +210 -0
  2. package/dist/index.d.ts +12 -0
  3. package/dist/index.d.ts.map +1 -0
  4. package/dist/index.js +29 -0
  5. package/dist/index.js.map +1 -0
  6. package/dist/lib/navi_calculations.d.ts +76 -0
  7. package/dist/lib/navi_calculations.d.ts.map +1 -0
  8. package/dist/lib/navi_calculations.js +185 -0
  9. package/dist/lib/navi_calculations.js.map +1 -0
  10. package/dist/lib/scallop/flash-loan-client.d.ts +88 -0
  11. package/dist/lib/scallop/flash-loan-client.d.ts.map +1 -0
  12. package/dist/lib/scallop/flash-loan-client.js +146 -0
  13. package/dist/lib/scallop/flash-loan-client.js.map +1 -0
  14. package/dist/lib/scallop/flash-loan.d.ts +30 -0
  15. package/dist/lib/scallop/flash-loan.d.ts.map +1 -0
  16. package/dist/lib/scallop/flash-loan.js +61 -0
  17. package/dist/lib/scallop/flash-loan.js.map +1 -0
  18. package/dist/lib/scallop/index.d.ts +6 -0
  19. package/dist/lib/scallop/index.d.ts.map +1 -0
  20. package/dist/lib/scallop/index.js +20 -0
  21. package/dist/lib/scallop/index.js.map +1 -0
  22. package/dist/lib/scallop/scallop-addresses.d.ts +24 -0
  23. package/dist/lib/scallop/scallop-addresses.d.ts.map +1 -0
  24. package/dist/lib/scallop/scallop-addresses.js +67 -0
  25. package/dist/lib/scallop/scallop-addresses.js.map +1 -0
  26. package/dist/lib/scallop/scallop-builder.d.ts +96 -0
  27. package/dist/lib/scallop/scallop-builder.d.ts.map +1 -0
  28. package/dist/lib/scallop/scallop-builder.js +163 -0
  29. package/dist/lib/scallop/scallop-builder.js.map +1 -0
  30. package/dist/lib/suilend/const.d.ts +27 -0
  31. package/dist/lib/suilend/const.d.ts.map +1 -0
  32. package/dist/lib/suilend/const.js +178 -0
  33. package/dist/lib/suilend/const.js.map +1 -0
  34. package/dist/lib/suilend/suilend.d.ts +15 -0
  35. package/dist/lib/suilend/suilend.d.ts.map +1 -0
  36. package/dist/lib/suilend/suilend.js +32 -0
  37. package/dist/lib/suilend/suilend.js.map +1 -0
  38. package/dist/lib/utils/coin.d.ts +21 -0
  39. package/dist/lib/utils/coin.d.ts.map +1 -0
  40. package/dist/lib/utils/coin.js +50 -0
  41. package/dist/lib/utils/coin.js.map +1 -0
  42. package/dist/lib/utils/format.d.ts +24 -0
  43. package/dist/lib/utils/format.d.ts.map +1 -0
  44. package/dist/lib/utils/format.js +39 -0
  45. package/dist/lib/utils/format.js.map +1 -0
  46. package/dist/lib/utils/index.d.ts +8 -0
  47. package/dist/lib/utils/index.d.ts.map +1 -0
  48. package/dist/lib/utils/index.js +24 -0
  49. package/dist/lib/utils/index.js.map +1 -0
  50. package/package.json +56 -0
package/README.md ADDED
@@ -0,0 +1,210 @@
1
+ # DeFi Dash SDK
2
+
3
+ > Multi-protocol DeFi SDK for Sui blockchain - leverage strategies, flash loans, and lending protocols
4
+
5
+ [![npm version](https://img.shields.io/npm/v/defi-dash-sdk.svg)](https://www.npmjs.com/package/defi-dash-sdk)
6
+ [![License: ISC](https://img.shields.io/badge/License-ISC-blue.svg)](https://opensource.org/licenses/ISC)
7
+
8
+ ## Features
9
+
10
+ - 🔧 **Utility Functions** - Token formatting, coin type normalization
11
+ - 🏦 **Protocol Wrappers** - Scallop, Suilend integration
12
+ - 🔄 **Leverage Strategies** - One-click leverage long positions
13
+ - ⚡ **Type-Safe** - Full TypeScript support
14
+
15
+ ---
16
+
17
+ ## Installation
18
+
19
+ ```bash
20
+ npm install defi-dash-sdk
21
+ # or
22
+ yarn add defi-dash-sdk
23
+ ```
24
+
25
+ ---
26
+
27
+ ## Quick Start
28
+
29
+ ### 1. Basic Usage - Utility Functions
30
+
31
+ ```typescript
32
+ import { formatUnits, parseUnits, normalizeCoinType } from 'defi-dash-sdk';
33
+
34
+ // Format token amounts
35
+ const humanReadable = formatUnits(1000000, 6); // "1" (USDC)
36
+ const rawAmount = parseUnits("1.5", 6); // 1500000n
37
+
38
+ // Normalize coin types
39
+ const normalized = normalizeCoinType("0x2::sui::SUI");
40
+ // "0x0000000000000000000000000000000000000000000000000000000000000002::sui::SUI"
41
+ ```
42
+
43
+ ### 2. Using Type Definitions
44
+
45
+ ```typescript
46
+ import type { MarketReserve } from 'defi-dash-sdk';
47
+
48
+ const reserve: MarketReserve = {
49
+ coinType: "0x2::sui::SUI",
50
+ id: "0x...",
51
+ decimals: 9,
52
+ symbol: "SUI"
53
+ };
54
+ ```
55
+
56
+ ---
57
+
58
+ ## API Reference
59
+
60
+ ### Utilities
61
+
62
+ #### `formatUnits(amount, decimals): string`
63
+
64
+ Converts raw token amount to human-readable format.
65
+
66
+ **Parameters:**
67
+
68
+ - `amount` - Raw amount (string | number | bigint)
69
+ - `decimals` - Token decimals (e.g., 6 for USDC, 9 for SUI)
70
+
71
+ **Returns:** Formatted string with proper decimal placement
72
+
73
+ **Example:**
74
+
75
+ ```typescript
76
+ formatUnits(1500000, 6) // "1.5"
77
+ formatUnits(1000000000, 9) // "1"
78
+ ```
79
+
80
+ #### `parseUnits(amount, decimals): bigint`
81
+
82
+ Converts human-readable amount to raw units.
83
+
84
+ **Parameters:**
85
+
86
+ - `amount` - Human-readable amount string
87
+ - `decimals` - Token decimals
88
+
89
+ **Returns:** Raw amount as bigint
90
+
91
+ **Example:**
92
+
93
+ ```typescript
94
+ parseUnits("1.5", 6) // 1500000n
95
+ ```
96
+
97
+ #### `normalizeCoinType(coinType): string`
98
+
99
+ Normalizes Sui coin type addresses (pads to 64 chars, ensures 0x prefix).
100
+
101
+ #### `formatCoinType(type): string`
102
+
103
+ Uses `normalizeStructTag` from `@mysten/sui` with fallback.
104
+
105
+ ---
106
+
107
+ ## Development
108
+
109
+ This package is designed for both Node.js scripts and frontend applications.
110
+
111
+ ### For Testing Strategies
112
+
113
+ Clone the repo to access example scripts:
114
+
115
+ ```bash
116
+ git clone https://github.com/yourusername/defi-dash-sdk.git
117
+ cd defi-dash-sdk
118
+ npm install
119
+
120
+ # Run example leverage strategy
121
+ npm run test:suilend-leverage
122
+ ```
123
+
124
+ ### Building from Source
125
+
126
+ ```bash
127
+ npm run build # Compiles TypeScript to dist/
128
+ ```
129
+
130
+ ---
131
+
132
+ ## Architecture
133
+
134
+ ```
135
+ defi-dash-sdk/
136
+ ├── src/
137
+ │ ├── index.ts # SDK entry point
138
+ │ └── lib/
139
+ │ ├── utils/ # Formatting & normalization
140
+ │ ├── scallop/ # Flash loan wrapper
141
+ │ └── suilend/ # Lending constants
142
+ └── tests/ # Integration examples
143
+ ```
144
+
145
+ ---
146
+
147
+ ## Examples
148
+
149
+ ### Using in a Frontend (React/Next.js)
150
+
151
+ ```typescript
152
+ import { formatUnits, normalizeCoinType } from 'defi-dash-sdk';
153
+
154
+ function TokenBalance({ amount, decimals, symbol }) {
155
+ const formatted = formatUnits(amount, decimals);
156
+
157
+ return <div>{formatted} {symbol}</div>;
158
+ }
159
+ ```
160
+
161
+ ### Using in a Node.js Script
162
+
163
+ ```typescript
164
+ import { parseUnits } from 'defi-dash-sdk';
165
+
166
+ const depositAmount = parseUnits("100", 6); // 100 USDC
167
+ console.log(`Depositing: ${depositAmount} raw units`);
168
+ ```
169
+
170
+ ---
171
+
172
+ ## Protocol Support
173
+
174
+ | Protocol | Type | Status |
175
+ | ----------- | ----------------- | -------------- |
176
+ | Scallop | Flash Loans | ✅ Supported |
177
+ | Suilend | Lending/Borrowing | ✅ Supported |
178
+ | 7k Protocol | Swap Aggregator | ✅ Supported |
179
+ | NAVI | Lending | 🚧 In Progress |
180
+
181
+ ---
182
+
183
+ ## Dependencies
184
+
185
+ Core dependencies (automatically installed):
186
+
187
+ - `@mysten/sui` - Sui blockchain SDK
188
+ - `@suilend/sdk` - Suilend protocol
189
+ - `@scallop-io/sui-scallop-sdk` - Scallop flash loans
190
+ - `@7kprotocol/sdk-ts` - 7k swap aggregator
191
+
192
+ ---
193
+
194
+ ## Contributing
195
+
196
+ Contributions are welcome! Please open an issue or PR.
197
+
198
+ ---
199
+
200
+ ## License
201
+
202
+ ISC
203
+
204
+ ---
205
+
206
+ ## Links
207
+
208
+ - [Documentation](#) (Coming Soon)
209
+ - [GitHub Repository](#)
210
+ - [Example Apps](#)
@@ -0,0 +1,12 @@
1
+ /**
2
+ * DeFi Dash SDK
3
+ *
4
+ * Multi-protocol DeFi SDK for Sui blockchain integrating leverage strategies,
5
+ * flash loans, and lending protocols.
6
+ *
7
+ * @module defi-dash-sdk
8
+ */
9
+ export * from "./lib/utils";
10
+ export * from "./lib/scallop";
11
+ export type { MarketReserve } from "./lib/suilend/const";
12
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,cAAc,aAAa,CAAC;AAG5B,cAAc,eAAe,CAAC;AAG9B,YAAY,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,29 @@
1
+ "use strict";
2
+ /**
3
+ * DeFi Dash SDK
4
+ *
5
+ * Multi-protocol DeFi SDK for Sui blockchain integrating leverage strategies,
6
+ * flash loans, and lending protocols.
7
+ *
8
+ * @module defi-dash-sdk
9
+ */
10
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
11
+ if (k2 === undefined) k2 = k;
12
+ var desc = Object.getOwnPropertyDescriptor(m, k);
13
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
14
+ desc = { enumerable: true, get: function() { return m[k]; } };
15
+ }
16
+ Object.defineProperty(o, k2, desc);
17
+ }) : (function(o, m, k, k2) {
18
+ if (k2 === undefined) k2 = k;
19
+ o[k2] = m[k];
20
+ }));
21
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
22
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
23
+ };
24
+ Object.defineProperty(exports, "__esModule", { value: true });
25
+ // Utility functions
26
+ __exportStar(require("./lib/utils"), exports);
27
+ // Protocol wrappers
28
+ __exportStar(require("./lib/scallop"), exports);
29
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAAA;;;;;;;GAOG;;;;;;;;;;;;;;;;AAEH,oBAAoB;AACpB,8CAA4B;AAE5B,oBAAoB;AACpB,gDAA8B"}
@@ -0,0 +1,76 @@
1
+ /**
2
+ * Navi Protocol Calculation Utilities
3
+ */
4
+ export interface NaviPoolInfo {
5
+ coinType: string;
6
+ symbol: string;
7
+ decimals: number;
8
+ supplyApy: number;
9
+ borrowApy: number;
10
+ liquidationThreshold: number;
11
+ ltv: number;
12
+ totalSupply: number;
13
+ totalBorrow: number;
14
+ availableLiquidity: number;
15
+ utilizationRate: number;
16
+ rawPool: any;
17
+ }
18
+ export interface NaviUserPosition {
19
+ coinType: string;
20
+ symbol: string;
21
+ decimals: number;
22
+ price: number;
23
+ supplyAmount: number;
24
+ supplyValueUsd: number;
25
+ supplyApy: number;
26
+ borrowAmount: number;
27
+ borrowValueUsd: number;
28
+ borrowApy: number;
29
+ liquidationThreshold: number;
30
+ liquidationPrice: number;
31
+ }
32
+ export interface NaviAccountSummary {
33
+ positions: NaviUserPosition[];
34
+ totalSupplyValueUsd: number;
35
+ totalBorrowValueUsd: number;
36
+ totalCollateralValueUsd: number;
37
+ netWorthUsd: number;
38
+ healthFactor: number;
39
+ weightedSupplyApy: number;
40
+ weightedBorrowApy: number;
41
+ netApy: number;
42
+ }
43
+ export interface LeverageInfo {
44
+ maxLeverage: number;
45
+ safeLeverage: number;
46
+ targetLtv: number;
47
+ }
48
+ export declare function fetchNaviPoolData(): Promise<Map<string, NaviPoolInfo>>;
49
+ export declare function fetchNaviUserData(userAddress: string, poolMap?: Map<string, NaviPoolInfo>): Promise<NaviUserPosition[]>;
50
+ export declare function fetchNaviAccountSummary(userAddress: string, poolMap?: Map<string, NaviPoolInfo>): Promise<NaviAccountSummary>;
51
+ export declare function calculateLeverageMultiplier(pool: NaviPoolInfo, safetyBuffer?: number, executionBuffer?: number): LeverageInfo;
52
+ /**
53
+ * ```typescript
54
+ * const summary = await fetchNaviAccountSummary(address);
55
+ *
56
+ * // 전체 요약
57
+ * console.log("Health Factor:", summary.healthFactor);
58
+ * console.log("Net APY:", summary.netApy);
59
+ * console.log("Net Worth:", summary.netWorthUsd);
60
+ *
61
+ * // 각 position 정보
62
+ * for (const pos of summary.positions) {
63
+ * console.log(`${pos.symbol}:`);
64
+ * console.log(` Supply: ${pos.supplyAmount} ($${pos.supplyValueUsd})`);
65
+ * console.log(` Borrow: ${pos.borrowAmount} ($${pos.borrowValueUsd})`);
66
+ * console.log(` Liquidation Price: $${pos.liquidationPrice}`);
67
+ * }
68
+ *
69
+ * // 레버리지 계산
70
+ * const poolMap = await fetchNaviPoolData();
71
+ * const suiPool = poolMap.get("0x2::sui::SUI");
72
+ * const leverage = calculateLeverageMultiplier(suiPool);
73
+ * console.log("Safe Leverage:", leverage.safeLeverage);
74
+ * ```
75
+ */
76
+ //# sourceMappingURL=navi_calculations.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"navi_calculations.d.ts","sourceRoot":"","sources":["../../src/lib/navi_calculations.ts"],"names":[],"mappings":"AAAA;;GAEG;AAaH,MAAM,WAAW,YAAY;IAC3B,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,oBAAoB,EAAE,MAAM,CAAC;IAC7B,GAAG,EAAE,MAAM,CAAC;IACZ,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,eAAe,EAAE,MAAM,CAAC;IACxB,OAAO,EAAE,GAAG,CAAC;CACd;AAED,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IAEd,YAAY,EAAE,MAAM,CAAC;IACrB,cAAc,EAAE,MAAM,CAAC;IACvB,SAAS,EAAE,MAAM,CAAC;IAElB,YAAY,EAAE,MAAM,CAAC;IACrB,cAAc,EAAE,MAAM,CAAC;IACvB,SAAS,EAAE,MAAM,CAAC;IAElB,oBAAoB,EAAE,MAAM,CAAC;IAC7B,gBAAgB,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,kBAAkB;IACjC,SAAS,EAAE,gBAAgB,EAAE,CAAC;IAC9B,mBAAmB,EAAE,MAAM,CAAC;IAC5B,mBAAmB,EAAE,MAAM,CAAC;IAC5B,uBAAuB,EAAE,MAAM,CAAC;IAChC,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,iBAAiB,EAAE,MAAM,CAAC;IAC1B,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,YAAY;IAC3B,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;CACnB;AAMD,wBAAsB,iBAAiB,IAAI,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC,CAiD5E;AAED,wBAAsB,iBAAiB,CACrC,WAAW,EAAE,MAAM,EACnB,OAAO,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,YAAY,CAAC,GAClC,OAAO,CAAC,gBAAgB,EAAE,CAAC,CA0D7B;AAED,wBAAsB,uBAAuB,CAC3C,WAAW,EAAE,MAAM,EACnB,OAAO,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,YAAY,CAAC,GAClC,OAAO,CAAC,kBAAkB,CAAC,CAkD7B;AAMD,wBAAgB,2BAA2B,CACzC,IAAI,EAAE,YAAY,EAClB,YAAY,GAAE,MAAa,EAC3B,eAAe,GAAE,MAAa,GAC7B,YAAY,CAed;AAMD;;;;;;;;;;;;;;;;;;;;;;;GAuBG"}
@@ -0,0 +1,185 @@
1
+ "use strict";
2
+ /**
3
+ * Navi Protocol Calculation Utilities
4
+ */
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.fetchNaviPoolData = fetchNaviPoolData;
7
+ exports.fetchNaviUserData = fetchNaviUserData;
8
+ exports.fetchNaviAccountSummary = fetchNaviAccountSummary;
9
+ exports.calculateLeverageMultiplier = calculateLeverageMultiplier;
10
+ const lending_1 = require("@naviprotocol/lending");
11
+ const sdk_ts_1 = require("@7kprotocol/sdk-ts");
12
+ // ============================================================================
13
+ // Data Fetching Functions
14
+ // ============================================================================
15
+ async function fetchNaviPoolData() {
16
+ const pools = await (0, lending_1.getPools)({ env: "prod" });
17
+ const poolsArray = Array.isArray(pools) ? pools : Object.values(pools);
18
+ const poolMap = new Map();
19
+ for (const pool of poolsArray) {
20
+ const coinType = (0, lending_1.normalizeCoinType)(pool.coinType ?? pool.suiCoinType ?? "");
21
+ if (!coinType)
22
+ continue;
23
+ const decimals = pool.token?.decimals ?? 9;
24
+ const symbol = pool.token?.symbol ?? pool.symbol ?? "UNKNOWN";
25
+ const supplyApy = parseFloat(pool.supplyApy ?? pool.supplyIncentiveApyInfo?.apy ?? "0");
26
+ const borrowApy = parseFloat(pool.borrowApy ?? pool.borrowIncentiveApyInfo?.apy ?? "0");
27
+ const liquidationThreshold = parseFloat(pool.liquidationFactor?.threshold ?? "0.8");
28
+ // LTV is stored as scaled by 1e27 in Navi
29
+ const rawLtv = parseFloat(pool.ltv ?? "0");
30
+ const ltv = rawLtv > 1 ? rawLtv / 1e27 : rawLtv || 0.75;
31
+ const totalSupply = parseFloat(pool.totalSupply ?? "0") / Math.pow(10, decimals);
32
+ const totalBorrow = parseFloat(pool.totalBorrow ?? "0") / Math.pow(10, decimals);
33
+ poolMap.set(coinType, {
34
+ coinType,
35
+ symbol,
36
+ decimals,
37
+ supplyApy,
38
+ borrowApy,
39
+ liquidationThreshold,
40
+ ltv,
41
+ totalSupply,
42
+ totalBorrow,
43
+ availableLiquidity: totalSupply - totalBorrow,
44
+ utilizationRate: totalSupply > 0 ? totalBorrow / totalSupply : 0,
45
+ rawPool: pool,
46
+ });
47
+ }
48
+ return poolMap;
49
+ }
50
+ async function fetchNaviUserData(userAddress, poolMap) {
51
+ const lendingState = await (0, lending_1.getLendingState)(userAddress, { env: "prod" });
52
+ const pools = poolMap ?? (await fetchNaviPoolData());
53
+ // 1차: position 데이터 수집
54
+ const rawPositions = [];
55
+ for (const pos of lendingState) {
56
+ const coinType = (0, lending_1.normalizeCoinType)(pos.pool.coinType);
57
+ const pool = pools.get(coinType);
58
+ if (!pool)
59
+ continue;
60
+ const supplyBalance = BigInt(pos.supplyBalance);
61
+ const borrowBalance = BigInt(pos.borrowBalance);
62
+ if (supplyBalance <= 0n && borrowBalance <= 0n)
63
+ continue;
64
+ const price = await (0, sdk_ts_1.getTokenPrice)(coinType);
65
+ const supplyAmount = Number(supplyBalance) / Math.pow(10, pool.decimals);
66
+ const borrowAmount = Number(borrowBalance) / Math.pow(10, pool.decimals);
67
+ rawPositions.push({
68
+ coinType,
69
+ symbol: pool.symbol,
70
+ decimals: pool.decimals,
71
+ price,
72
+ supplyAmount,
73
+ supplyValueUsd: supplyAmount * price,
74
+ supplyApy: pool.supplyApy,
75
+ borrowAmount,
76
+ borrowValueUsd: borrowAmount * price,
77
+ borrowApy: pool.borrowApy,
78
+ liquidationThreshold: pool.liquidationThreshold,
79
+ });
80
+ }
81
+ // 2차: 전체 borrow 합계 계산
82
+ const totalBorrowValueUsd = rawPositions.reduce((sum, p) => sum + p.borrowValueUsd, 0);
83
+ // 3차: 각 position에 liquidationPrice 계산
84
+ const positions = rawPositions.map((pos) => {
85
+ // liquidationPrice = totalBorrowValueUsd / (supplyAmount * liquidationThreshold)
86
+ let liquidationPrice = 0;
87
+ if (pos.supplyAmount > 0 && pos.liquidationThreshold > 0) {
88
+ liquidationPrice =
89
+ totalBorrowValueUsd / (pos.supplyAmount * pos.liquidationThreshold);
90
+ }
91
+ return {
92
+ ...pos,
93
+ liquidationPrice,
94
+ };
95
+ });
96
+ return positions;
97
+ }
98
+ async function fetchNaviAccountSummary(userAddress, poolMap) {
99
+ const pools = poolMap ?? (await fetchNaviPoolData());
100
+ const positions = await fetchNaviUserData(userAddress, pools);
101
+ let totalSupplyValueUsd = 0;
102
+ let totalBorrowValueUsd = 0;
103
+ let totalCollateralValueUsd = 0;
104
+ let weightedSupplyApy = 0;
105
+ let weightedBorrowApy = 0;
106
+ for (const pos of positions) {
107
+ totalSupplyValueUsd += pos.supplyValueUsd;
108
+ totalBorrowValueUsd += pos.borrowValueUsd;
109
+ totalCollateralValueUsd += pos.supplyValueUsd * pos.liquidationThreshold;
110
+ weightedSupplyApy += pos.supplyApy * pos.supplyValueUsd;
111
+ weightedBorrowApy += pos.borrowApy * pos.borrowValueUsd;
112
+ }
113
+ if (totalSupplyValueUsd > 0) {
114
+ weightedSupplyApy = weightedSupplyApy / totalSupplyValueUsd;
115
+ }
116
+ if (totalBorrowValueUsd > 0) {
117
+ weightedBorrowApy = weightedBorrowApy / totalBorrowValueUsd;
118
+ }
119
+ const netWorthUsd = totalSupplyValueUsd - totalBorrowValueUsd;
120
+ const healthFactor = totalBorrowValueUsd > 0
121
+ ? totalCollateralValueUsd / totalBorrowValueUsd
122
+ : 999;
123
+ // Net APY 계산
124
+ let netApy = 0;
125
+ if (netWorthUsd > 0) {
126
+ const supplyInterest = totalSupplyValueUsd * (weightedSupplyApy / 100);
127
+ const borrowInterest = totalBorrowValueUsd * (weightedBorrowApy / 100);
128
+ netApy = ((supplyInterest - borrowInterest) / netWorthUsd) * 100;
129
+ }
130
+ return {
131
+ positions,
132
+ totalSupplyValueUsd,
133
+ totalBorrowValueUsd,
134
+ totalCollateralValueUsd,
135
+ netWorthUsd,
136
+ healthFactor,
137
+ weightedSupplyApy,
138
+ weightedBorrowApy,
139
+ netApy,
140
+ };
141
+ }
142
+ // ============================================================================
143
+ // Leverage Calculation (Pool 기반)
144
+ // ============================================================================
145
+ function calculateLeverageMultiplier(pool, safetyBuffer = 0.05, executionBuffer = 0.95) {
146
+ const targetLtv = pool.liquidationThreshold - safetyBuffer;
147
+ if (targetLtv >= 1 || targetLtv <= 0) {
148
+ return { maxLeverage: 1, safeLeverage: 1, targetLtv: 0 };
149
+ }
150
+ const theoreticalMax = 1 / (1 - targetLtv);
151
+ const safeLeverage = theoreticalMax * executionBuffer;
152
+ return {
153
+ maxLeverage: Number(theoreticalMax.toFixed(2)),
154
+ safeLeverage: Number(safeLeverage.toFixed(2)),
155
+ targetLtv: Number(targetLtv.toFixed(4)),
156
+ };
157
+ }
158
+ // ============================================================================
159
+ // Example Usage
160
+ // ============================================================================
161
+ /**
162
+ * ```typescript
163
+ * const summary = await fetchNaviAccountSummary(address);
164
+ *
165
+ * // 전체 요약
166
+ * console.log("Health Factor:", summary.healthFactor);
167
+ * console.log("Net APY:", summary.netApy);
168
+ * console.log("Net Worth:", summary.netWorthUsd);
169
+ *
170
+ * // 각 position 정보
171
+ * for (const pos of summary.positions) {
172
+ * console.log(`${pos.symbol}:`);
173
+ * console.log(` Supply: ${pos.supplyAmount} ($${pos.supplyValueUsd})`);
174
+ * console.log(` Borrow: ${pos.borrowAmount} ($${pos.borrowValueUsd})`);
175
+ * console.log(` Liquidation Price: $${pos.liquidationPrice}`);
176
+ * }
177
+ *
178
+ * // 레버리지 계산
179
+ * const poolMap = await fetchNaviPoolData();
180
+ * const suiPool = poolMap.get("0x2::sui::SUI");
181
+ * const leverage = calculateLeverageMultiplier(suiPool);
182
+ * console.log("Safe Leverage:", leverage.safeLeverage);
183
+ * ```
184
+ */
185
+ //# sourceMappingURL=navi_calculations.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"navi_calculations.js","sourceRoot":"","sources":["../../src/lib/navi_calculations.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,88 @@
1
+ import { Transaction } from "@mysten/sui/transactions";
2
+ /**
3
+ * Scallop Protocol Addresses
4
+ * Default: fetched from https://sui.apis.scallop.io/addresses/{addressId}
5
+ * Can be overridden via constructor
6
+ */
7
+ export interface ScallopCoreIds {
8
+ protocolPkg: string;
9
+ version: string;
10
+ market: string;
11
+ coinDecimalsRegistry: string;
12
+ xOracle?: string;
13
+ }
14
+ export interface ScallopCoinTypes {
15
+ [coinName: string]: string;
16
+ }
17
+ export interface ScallopFlashLoanClientOptions {
18
+ /** Override default protocol package ID */
19
+ protocolPkg?: string;
20
+ /** Override default version object ID */
21
+ version?: string;
22
+ /** Override default market object ID */
23
+ market?: string;
24
+ /** Additional coin types to add/override */
25
+ coinTypes?: ScallopCoinTypes;
26
+ /** Full override of core IDs */
27
+ coreIds?: Partial<ScallopCoreIds>;
28
+ }
29
+ type TransactionArg = ReturnType<Transaction["splitCoins"]>;
30
+ /**
31
+ * Custom Scallop Flash Loan Client
32
+ *
33
+ * Allows you to use default addresses from API or override them locally.
34
+ * This is useful when the SDK's addresses are outdated.
35
+ *
36
+ * @example
37
+ * ```ts
38
+ * // Use defaults
39
+ * const client = new ScallopFlashLoanClient();
40
+ *
41
+ * // Override protocol package (when SDK is outdated)
42
+ * const client = new ScallopFlashLoanClient({
43
+ * protocolPkg: "0x...",
44
+ * });
45
+ * ```
46
+ */
47
+ export declare class ScallopFlashLoanClient {
48
+ private coreIds;
49
+ private coinTypes;
50
+ constructor(options?: ScallopFlashLoanClientOptions);
51
+ /**
52
+ * Get coin type from coin name
53
+ */
54
+ getCoinType(coinName: string): string;
55
+ /**
56
+ * Get current core IDs (for debugging)
57
+ */
58
+ getCoreIds(): ScallopCoreIds;
59
+ /**
60
+ * Borrow a flash loan from Scallop
61
+ *
62
+ * @param tx - Sui Transaction object
63
+ * @param amount - Amount to borrow (in smallest unit)
64
+ * @param coinName - Coin name (e.g., 'sui', 'usdc')
65
+ * @returns [loanCoin, receipt] - The borrowed coin and flash loan receipt
66
+ */
67
+ borrowFlashLoan(tx: Transaction, amount: number | bigint, coinName: string): [TransactionArg, TransactionArg];
68
+ /**
69
+ * Repay a flash loan to Scallop
70
+ *
71
+ * @param tx - Sui Transaction object
72
+ * @param coin - The coin to repay (must include fee)
73
+ * @param receipt - The flash loan receipt (Hot Potato)
74
+ * @param coinName - Coin name (e.g., 'sui', 'usdc')
75
+ */
76
+ repayFlashLoan(tx: Transaction, coin: TransactionArg, receipt: TransactionArg, coinName: string): void;
77
+ /**
78
+ * Calculate flash loan fee (0.05% = 5 basis points)
79
+ */
80
+ static calculateFee(amount: bigint): bigint;
81
+ /**
82
+ * Fetch latest addresses from Scallop API
83
+ * Use this to update the client when SDK is outdated
84
+ */
85
+ static fetchFromAPI(addressId?: string): Promise<ScallopCoreIds>;
86
+ }
87
+ export default ScallopFlashLoanClient;
88
+ //# sourceMappingURL=flash-loan-client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"flash-loan-client.d.ts","sourceRoot":"","sources":["../../../src/lib/scallop/flash-loan-client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAGvD;;;;GAIG;AACH,MAAM,WAAW,cAAc;IAC7B,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,oBAAoB,EAAE,MAAM,CAAC;IAC7B,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,gBAAgB;IAC/B,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAAC;CAC5B;AAmCD,MAAM,WAAW,6BAA6B;IAC5C,2CAA2C;IAC3C,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,yCAAyC;IACzC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,wCAAwC;IACxC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,4CAA4C;IAC5C,SAAS,CAAC,EAAE,gBAAgB,CAAC;IAC7B,gCAAgC;IAChC,OAAO,CAAC,EAAE,OAAO,CAAC,cAAc,CAAC,CAAC;CACnC;AAED,KAAK,cAAc,GAAG,UAAU,CAAC,WAAW,CAAC,YAAY,CAAC,CAAC,CAAC;AAE5D;;;;;;;;;;;;;;;;GAgBG;AACH,qBAAa,sBAAsB;IACjC,OAAO,CAAC,OAAO,CAAiB;IAChC,OAAO,CAAC,SAAS,CAAmB;gBAExB,OAAO,GAAE,6BAAkC;IAkBvD;;OAEG;IACH,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM;IAQrC;;OAEG;IACH,UAAU,IAAI,cAAc;IAI5B;;;;;;;OAOG;IACH,eAAe,CACb,EAAE,EAAE,WAAW,EACf,MAAM,EAAE,MAAM,GAAG,MAAM,EACvB,QAAQ,EAAE,MAAM,GACf,CAAC,cAAc,EAAE,cAAc,CAAC;IAanC;;;;;;;OAOG;IACH,cAAc,CACZ,EAAE,EAAE,WAAW,EACf,IAAI,EAAE,cAAc,EACpB,OAAO,EAAE,cAAc,EACvB,QAAQ,EAAE,MAAM,GACf,IAAI;IAgBP;;OAEG;IACH,MAAM,CAAC,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM;IAM3C;;;OAGG;WACU,YAAY,CACvB,SAAS,GAAE,MAAmC,GAC7C,OAAO,CAAC,cAAc,CAAC;CAc3B;AAED,eAAe,sBAAsB,CAAC"}