@kasufinance/kasu-sdk 1.0.4 → 2.2.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.
- package/CLAUDE.md +410 -0
- package/README.md +179 -12
- package/dist/bundle.cjs.js +658 -90
- package/dist/bundle.esm.js +654 -92
- package/dist/facade/chain-configs.d.ts +11 -0
- package/dist/facade/chain-configs.js +84 -0
- package/dist/facade/chain-configs.js.map +1 -0
- package/dist/facade/deposits.d.ts +56 -0
- package/dist/facade/deposits.js +87 -0
- package/dist/facade/deposits.js.map +1 -0
- package/dist/facade/index.d.ts +6 -0
- package/dist/facade/index.js +9 -0
- package/dist/facade/index.js.map +1 -0
- package/dist/facade/kasu.d.ts +71 -0
- package/dist/facade/kasu.js +101 -0
- package/dist/facade/kasu.js.map +1 -0
- package/dist/facade/strategies.d.ts +37 -0
- package/dist/facade/strategies.js +112 -0
- package/dist/facade/strategies.js.map +1 -0
- package/dist/facade/types.d.ts +127 -0
- package/dist/facade/types.js +2 -0
- package/dist/facade/types.js.map +1 -0
- package/dist/facade/user-portfolio.d.ts +35 -0
- package/dist/facade/user-portfolio.js +53 -0
- package/dist/facade/user-portfolio.js.map +1 -0
- package/dist/index.d.ts +9 -17
- package/dist/index.js +9 -16
- package/dist/index.js.map +1 -1
- package/dist/kasu-sdk.d.ts +17 -0
- package/dist/kasu-sdk.js +17 -0
- package/dist/kasu-sdk.js.map +1 -0
- package/dist/sdk-config.d.ts +34 -4
- package/dist/sdk-config.js +9 -6
- package/dist/sdk-config.js.map +1 -1
- package/dist/services/DataService/data-service.d.ts +9 -2
- package/dist/services/DataService/data-service.js +91 -53
- package/dist/services/DataService/data-service.js.map +1 -1
- package/dist/services/DataService/queries.d.ts +0 -1
- package/dist/services/DataService/queries.js +0 -8
- package/dist/services/DataService/queries.js.map +1 -1
- package/dist/services/DataService/subgraph-types.d.ts +0 -6
- package/dist/services/DataService/types.d.ts +0 -1
- package/dist/services/Locking/locking.d.ts +9 -3
- package/dist/services/Locking/locking.js +114 -20
- package/dist/services/Locking/locking.js.map +1 -1
- package/dist/services/Locking/types.d.ts +1 -1
- package/dist/services/Portfolio/portfolio.d.ts +3 -2
- package/dist/services/Portfolio/portfolio.js +15 -7
- package/dist/services/Portfolio/portfolio.js.map +1 -1
- package/dist/services/Portfolio/types.d.ts +2 -2
- package/dist/services/UserLending/user-lending.d.ts +3 -1
- package/dist/services/UserLending/user-lending.js +9 -3
- package/dist/services/UserLending/user-lending.js.map +1 -1
- package/dist/tests/facade.test.d.ts +1 -0
- package/dist/tests/facade.test.js +196 -0
- package/dist/tests/facade.test.js.map +1 -0
- package/dist/tests/sample.test.js +19 -14
- package/dist/tests/sample.test.js.map +1 -1
- package/dist/utils/deployment-mode.d.ts +6 -0
- package/dist/utils/deployment-mode.js +8 -0
- package/dist/utils/deployment-mode.js.map +1 -0
- package/package.json +2 -2
- package/src/facade/chain-configs.ts +93 -0
- package/src/facade/deposits.ts +102 -0
- package/src/facade/index.ts +26 -0
- package/src/facade/kasu.ts +144 -0
- package/src/facade/strategies.ts +119 -0
- package/src/facade/types.ts +168 -0
- package/src/facade/user-portfolio.ts +73 -0
- package/src/index.ts +59 -25
- package/src/kasu-sdk.ts +27 -0
- package/src/sdk-config.ts +43 -15
- package/src/services/DataService/data-service.ts +106 -66
- package/src/services/DataService/queries.ts +0 -9
- package/src/services/DataService/subgraph-types.ts +0 -7
- package/src/services/DataService/types.ts +0 -1
- package/src/services/Locking/locking.ts +141 -25
- package/src/services/Locking/types.ts +1 -1
- package/src/services/Portfolio/portfolio.ts +21 -11
- package/src/services/Portfolio/types.ts +2 -2
- package/src/services/UserLending/user-lending.ts +13 -4
- package/src/tests/facade.test.ts +245 -0
- package/src/tests/sample.test.ts +7 -9
- package/src/utils/deployment-mode.ts +9 -0
|
@@ -0,0 +1,245 @@
|
|
|
1
|
+
import { CHAIN_CONFIGS } from '../facade/chain-configs';
|
|
2
|
+
import { DepositsFacade } from '../facade/deposits';
|
|
3
|
+
import { Kasu } from '../facade/kasu';
|
|
4
|
+
import { StrategiesFacade } from '../facade/strategies';
|
|
5
|
+
import { PortfolioFacade } from '../facade/user-portfolio';
|
|
6
|
+
|
|
7
|
+
// ---------------------------------------------------------------------------
|
|
8
|
+
// Chain configs
|
|
9
|
+
// ---------------------------------------------------------------------------
|
|
10
|
+
|
|
11
|
+
describe('CHAIN_CONFIGS', () => {
|
|
12
|
+
it('should have base, xdc, and plume entries', () => {
|
|
13
|
+
expect(CHAIN_CONFIGS).toHaveProperty('base');
|
|
14
|
+
expect(CHAIN_CONFIGS).toHaveProperty('xdc');
|
|
15
|
+
expect(CHAIN_CONFIGS).toHaveProperty('plume');
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
it('base should be a full deployment', () => {
|
|
19
|
+
const base = CHAIN_CONFIGS.base;
|
|
20
|
+
expect(base.chainId).toBe(8453);
|
|
21
|
+
expect(base.isLiteDeployment).toBe(false);
|
|
22
|
+
expect(base.contracts.KSUToken).toBeDefined();
|
|
23
|
+
expect(base.contracts.KasuNFTs).toBeDefined();
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
it('xdc should be a lite deployment without KSU token', () => {
|
|
27
|
+
const xdc = CHAIN_CONFIGS.xdc;
|
|
28
|
+
expect(xdc.chainId).toBe(50);
|
|
29
|
+
expect(xdc.isLiteDeployment).toBe(true);
|
|
30
|
+
expect(xdc.contracts.KSUToken).toBeUndefined();
|
|
31
|
+
expect(xdc.contracts.KasuNFTs).toBeUndefined();
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
it('plume should be a lite deployment', () => {
|
|
35
|
+
const plume = CHAIN_CONFIGS.plume;
|
|
36
|
+
expect(plume.chainId).toBe(98866);
|
|
37
|
+
expect(plume.isLiteDeployment).toBe(true);
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
it('all chains should have required contract addresses', () => {
|
|
41
|
+
for (const [, config] of Object.entries(CHAIN_CONFIGS)) {
|
|
42
|
+
expect(config.contracts.LendingPoolManager).toBeDefined();
|
|
43
|
+
expect(config.contracts.UserManager).toBeDefined();
|
|
44
|
+
expect(config.contracts.KasuAllowList).toBeDefined();
|
|
45
|
+
expect(config.contracts.SystemVariables).toBeDefined();
|
|
46
|
+
expect(config.subgraphUrl).toContain('goldsky.com');
|
|
47
|
+
}
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
it('xdc should have poolMetadataMapping', () => {
|
|
51
|
+
const mapping = CHAIN_CONFIGS.xdc.poolMetadataMapping;
|
|
52
|
+
expect(mapping).toBeDefined();
|
|
53
|
+
expect(Object.keys(mapping ?? {}).length).toBeGreaterThan(0);
|
|
54
|
+
});
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
// ---------------------------------------------------------------------------
|
|
58
|
+
// Kasu.create()
|
|
59
|
+
// ---------------------------------------------------------------------------
|
|
60
|
+
|
|
61
|
+
describe('Kasu.create()', () => {
|
|
62
|
+
// Mock provider — enough to construct the SDK without network calls
|
|
63
|
+
const mockProvider = {
|
|
64
|
+
getNetwork: jest.fn().mockResolvedValue({ chainId: 8453, name: 'base' }),
|
|
65
|
+
call: jest.fn(),
|
|
66
|
+
estimateGas: jest.fn(),
|
|
67
|
+
getBlockNumber: jest.fn(),
|
|
68
|
+
getBlock: jest.fn(),
|
|
69
|
+
getTransaction: jest.fn(),
|
|
70
|
+
getTransactionReceipt: jest.fn(),
|
|
71
|
+
getLogs: jest.fn(),
|
|
72
|
+
on: jest.fn(),
|
|
73
|
+
once: jest.fn(),
|
|
74
|
+
off: jest.fn(),
|
|
75
|
+
removeAllListeners: jest.fn(),
|
|
76
|
+
_isProvider: true,
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
it('should create an instance from a chain name', () => {
|
|
80
|
+
const kasu = Kasu.create({
|
|
81
|
+
chain: 'base',
|
|
82
|
+
signerOrProvider: mockProvider as never,
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
expect(kasu).toBeInstanceOf(Kasu);
|
|
86
|
+
expect(kasu.strategies).toBeInstanceOf(StrategiesFacade);
|
|
87
|
+
expect(kasu.deposits).toBeInstanceOf(DepositsFacade);
|
|
88
|
+
expect(kasu.portfolio).toBeInstanceOf(PortfolioFacade);
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
it('should expose chainConfig for the selected chain', () => {
|
|
92
|
+
const kasu = Kasu.create({
|
|
93
|
+
chain: 'xdc',
|
|
94
|
+
signerOrProvider: mockProvider as never,
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
expect(kasu.chainConfig.chainId).toBe(50);
|
|
98
|
+
expect(kasu.isLiteDeployment).toBe(true);
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
it('should accept a custom ChainConfigEntry', () => {
|
|
102
|
+
const custom = {
|
|
103
|
+
...CHAIN_CONFIGS.base,
|
|
104
|
+
chainId: 999,
|
|
105
|
+
name: 'CustomChain',
|
|
106
|
+
};
|
|
107
|
+
|
|
108
|
+
const kasu = Kasu.create({
|
|
109
|
+
chain: custom,
|
|
110
|
+
signerOrProvider: mockProvider as never,
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
expect(kasu.chainConfig.chainId).toBe(999);
|
|
114
|
+
expect(kasu.chainConfig.name).toBe('CustomChain');
|
|
115
|
+
});
|
|
116
|
+
|
|
117
|
+
it('should accept configOverrides', () => {
|
|
118
|
+
const kasu = Kasu.create({
|
|
119
|
+
chain: 'base',
|
|
120
|
+
signerOrProvider: mockProvider as never,
|
|
121
|
+
configOverrides: {
|
|
122
|
+
UNUSED_LENDING_POOL_IDS: ['0xdead'],
|
|
123
|
+
},
|
|
124
|
+
});
|
|
125
|
+
|
|
126
|
+
expect(kasu).toBeInstanceOf(Kasu);
|
|
127
|
+
});
|
|
128
|
+
|
|
129
|
+
it('should expose the underlying KasuSdk via .services', () => {
|
|
130
|
+
const kasu = Kasu.create({
|
|
131
|
+
chain: 'base',
|
|
132
|
+
signerOrProvider: mockProvider as never,
|
|
133
|
+
});
|
|
134
|
+
|
|
135
|
+
expect(kasu.services).toBeDefined();
|
|
136
|
+
expect(kasu.services.DataService).toBeDefined();
|
|
137
|
+
expect(kasu.services.UserLending).toBeDefined();
|
|
138
|
+
expect(kasu.services.Locking).toBeDefined();
|
|
139
|
+
expect(kasu.services.Portfolio).toBeDefined();
|
|
140
|
+
});
|
|
141
|
+
});
|
|
142
|
+
|
|
143
|
+
// ---------------------------------------------------------------------------
|
|
144
|
+
// StrategiesFacade.calculateDepositLimits()
|
|
145
|
+
// ---------------------------------------------------------------------------
|
|
146
|
+
|
|
147
|
+
describe('StrategiesFacade.calculateDepositLimits()', () => {
|
|
148
|
+
// We can test this pure function without network calls by constructing
|
|
149
|
+
// a StrategiesFacade with null services and calling calculateDepositLimits directly.
|
|
150
|
+
const facade = new StrategiesFacade(null as never, null as never);
|
|
151
|
+
|
|
152
|
+
it('should enforce minimum of 1 USDC', () => {
|
|
153
|
+
const tranche = makeTranche({
|
|
154
|
+
minimumDeposit: '0.5',
|
|
155
|
+
maximumDeposit: '10000',
|
|
156
|
+
poolCapacity: '50000',
|
|
157
|
+
});
|
|
158
|
+
|
|
159
|
+
const limits = facade.calculateDepositLimits(tranche);
|
|
160
|
+
expect(limits.min).toBe('1');
|
|
161
|
+
expect(limits.max).toBe('10000');
|
|
162
|
+
expect(limits.availableCapacity).toBe('50000');
|
|
163
|
+
});
|
|
164
|
+
|
|
165
|
+
it('should pass through minimum when >= 1', () => {
|
|
166
|
+
const tranche = makeTranche({
|
|
167
|
+
minimumDeposit: '100',
|
|
168
|
+
maximumDeposit: '10000',
|
|
169
|
+
poolCapacity: '50000',
|
|
170
|
+
});
|
|
171
|
+
|
|
172
|
+
const limits = facade.calculateDepositLimits(tranche);
|
|
173
|
+
expect(limits.min).toBe('100');
|
|
174
|
+
});
|
|
175
|
+
|
|
176
|
+
it('should cap max at pool capacity when capacity is lower', () => {
|
|
177
|
+
const tranche = makeTranche({
|
|
178
|
+
minimumDeposit: '100',
|
|
179
|
+
maximumDeposit: '50000',
|
|
180
|
+
poolCapacity: '10000',
|
|
181
|
+
});
|
|
182
|
+
|
|
183
|
+
const limits = facade.calculateDepositLimits(tranche);
|
|
184
|
+
expect(limits.max).toBe('10000');
|
|
185
|
+
});
|
|
186
|
+
|
|
187
|
+
it('should use maximumDeposit when capacity is higher', () => {
|
|
188
|
+
const tranche = makeTranche({
|
|
189
|
+
minimumDeposit: '100',
|
|
190
|
+
maximumDeposit: '5000',
|
|
191
|
+
poolCapacity: '50000',
|
|
192
|
+
});
|
|
193
|
+
|
|
194
|
+
const limits = facade.calculateDepositLimits(tranche);
|
|
195
|
+
expect(limits.max).toBe('5000');
|
|
196
|
+
});
|
|
197
|
+
});
|
|
198
|
+
|
|
199
|
+
// ---------------------------------------------------------------------------
|
|
200
|
+
// Type exports — verify key facade types are importable
|
|
201
|
+
// ---------------------------------------------------------------------------
|
|
202
|
+
|
|
203
|
+
describe('Type re-exports', () => {
|
|
204
|
+
it('should export facade classes from the main entry', () => {
|
|
205
|
+
// Verify the barrel exports resolve — these would fail at compile time
|
|
206
|
+
// if the re-exports were broken.
|
|
207
|
+
expect(Kasu).toBeDefined();
|
|
208
|
+
expect(CHAIN_CONFIGS).toBeDefined();
|
|
209
|
+
expect(StrategiesFacade).toBeDefined();
|
|
210
|
+
expect(DepositsFacade).toBeDefined();
|
|
211
|
+
expect(PortfolioFacade).toBeDefined();
|
|
212
|
+
});
|
|
213
|
+
});
|
|
214
|
+
|
|
215
|
+
// ---------------------------------------------------------------------------
|
|
216
|
+
// Helpers
|
|
217
|
+
// ---------------------------------------------------------------------------
|
|
218
|
+
|
|
219
|
+
// eslint-disable-next-line @typescript-eslint/explicit-function-return-type
|
|
220
|
+
function makeTranche(raw: {
|
|
221
|
+
minimumDeposit: string;
|
|
222
|
+
maximumDeposit: string;
|
|
223
|
+
poolCapacity: string;
|
|
224
|
+
}) {
|
|
225
|
+
return {
|
|
226
|
+
id: '0xtest',
|
|
227
|
+
name: 'Test Tranche',
|
|
228
|
+
apy: 0.08,
|
|
229
|
+
minApy: 0.06,
|
|
230
|
+
maxApy: 0.10,
|
|
231
|
+
minimumDeposit: raw.minimumDeposit,
|
|
232
|
+
maximumDeposit: raw.maximumDeposit,
|
|
233
|
+
availableCapacity: raw.poolCapacity,
|
|
234
|
+
fixedTermOptions: [],
|
|
235
|
+
_raw: {
|
|
236
|
+
...raw,
|
|
237
|
+
id: '0xtest',
|
|
238
|
+
name: 'Test Tranche',
|
|
239
|
+
apy: '0.08',
|
|
240
|
+
minApy: '0.06',
|
|
241
|
+
maxApy: '0.10',
|
|
242
|
+
fixedTermConfig: [],
|
|
243
|
+
},
|
|
244
|
+
} as never;
|
|
245
|
+
}
|
package/src/tests/sample.test.ts
CHANGED
|
@@ -12,10 +12,10 @@ test('subgraphCall', async () => {
|
|
|
12
12
|
'dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd',
|
|
13
13
|
provider,
|
|
14
14
|
);
|
|
15
|
-
const config = new SdkConfig(
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
{
|
|
15
|
+
const config = new SdkConfig({
|
|
16
|
+
subgraphUrl:
|
|
17
|
+
'https://api.studio.thegraph.com/query/63245/kasu-wip-sepolia/version/latest',
|
|
18
|
+
contracts: {
|
|
19
19
|
IKSULocking: '0x529A81c11ab6176c5E88670d293BB771800066a2',
|
|
20
20
|
IKSULockBonus: '0xBBfFd5F744156FFc526df12F5e09dC7b208Be740',
|
|
21
21
|
KSUToken: '0xa0f698Feb9Bc2BeA6E85eb071D5E3F59dc5bC56b',
|
|
@@ -29,11 +29,9 @@ test('subgraphCall', async () => {
|
|
|
29
29
|
KasuNFTs: '0x0000000000000000000000000000000000000000',
|
|
30
30
|
ExternalTVL: '0x0000000000000000000000000000000000000000',
|
|
31
31
|
},
|
|
32
|
-
|
|
33
|
-
'
|
|
34
|
-
|
|
35
|
-
[''],
|
|
36
|
-
);
|
|
32
|
+
directusUrl: 'https://kasu-finance.directus.app',
|
|
33
|
+
UNUSED_LENDING_POOL_IDS: [''],
|
|
34
|
+
});
|
|
37
35
|
const sdk = new KasuSdk(config, wallet);
|
|
38
36
|
|
|
39
37
|
console.log(
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { SdkConfig } from '../sdk-config';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Check if the SDK is configured for a Lite deployment.
|
|
5
|
+
* Lite deployments don't have KSU token, locking, or loyalty features.
|
|
6
|
+
*/
|
|
7
|
+
export function isLiteDeployment(config: SdkConfig): boolean {
|
|
8
|
+
return config.isLiteDeployment;
|
|
9
|
+
}
|