@kasufinance/kasu-sdk 2.4.1 → 2.5.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/LICENSE +21 -0
- package/README.md +189 -253
- package/dist/bundle.cjs.js +4777 -1794
- package/dist/bundle.esm.js +4766 -1816
- package/dist/domain/deposit-bounds.d.ts +62 -0
- package/dist/domain/deposit-bounds.js +84 -0
- package/dist/domain/deposit-bounds.js.map +1 -0
- package/dist/domain/deposit-bounds.test.js +135 -0
- package/dist/domain/deposit-bounds.test.js.map +1 -0
- package/dist/domain/index.d.ts +26 -0
- package/dist/domain/index.js +23 -0
- package/dist/domain/index.js.map +1 -0
- package/dist/domain/partners.d.ts +34 -0
- package/dist/domain/partners.js +43 -0
- package/dist/domain/partners.js.map +1 -0
- package/dist/domain/partners.test.d.ts +1 -0
- package/dist/domain/partners.test.js +53 -0
- package/dist/domain/partners.test.js.map +1 -0
- package/dist/domain/pools.d.ts +70 -0
- package/dist/domain/pools.js +134 -0
- package/dist/domain/pools.js.map +1 -0
- package/dist/domain/pools.test.d.ts +1 -0
- package/dist/domain/pools.test.js +184 -0
- package/dist/domain/pools.test.js.map +1 -0
- package/dist/domain/rates.d.ts +83 -0
- package/dist/domain/rates.js +120 -0
- package/dist/domain/rates.js.map +1 -0
- package/dist/domain/rates.test.d.ts +1 -0
- package/dist/domain/rates.test.js +181 -0
- package/dist/domain/rates.test.js.map +1 -0
- package/dist/domain/tranche-display-name.d.ts +17 -0
- package/dist/domain/tranche-display-name.js +30 -0
- package/dist/domain/tranche-display-name.js.map +1 -0
- package/dist/domain/tranche-display-name.test.d.ts +1 -0
- package/dist/domain/tranche-display-name.test.js +58 -0
- package/dist/domain/tranche-display-name.test.js.map +1 -0
- package/dist/domain/tranches.d.ts +89 -0
- package/dist/domain/tranches.js +150 -0
- package/dist/domain/tranches.js.map +1 -0
- package/dist/domain/tranches.test.d.ts +1 -0
- package/dist/domain/tranches.test.js +206 -0
- package/dist/domain/tranches.test.js.map +1 -0
- package/dist/facade/chain-configs.js +54 -0
- package/dist/facade/chain-configs.js.map +1 -1
- package/dist/facade/config.test.d.ts +1 -0
- package/dist/facade/config.test.js +216 -0
- package/dist/facade/config.test.js.map +1 -0
- package/dist/facade/deposits.d.ts +22 -1
- package/dist/facade/deposits.js +24 -1
- package/dist/facade/deposits.js.map +1 -1
- package/dist/facade/facade.test.d.ts +1 -0
- package/dist/{tests → facade}/facade.test.js +10 -5
- package/dist/facade/facade.test.js.map +1 -0
- package/dist/facade/index.d.ts +2 -1
- package/dist/facade/index.js +2 -0
- package/dist/facade/index.js.map +1 -1
- package/dist/facade/kasu.d.ts +49 -8
- package/dist/facade/kasu.js +117 -13
- package/dist/facade/kasu.js.map +1 -1
- package/dist/facade/strategies.d.ts +25 -0
- package/dist/facade/strategies.js +36 -0
- package/dist/facade/strategies.js.map +1 -1
- package/dist/facade/types.d.ts +57 -2
- package/dist/facade/unused-pool-ids.d.ts +31 -0
- package/dist/facade/unused-pool-ids.js +57 -0
- package/dist/facade/unused-pool-ids.js.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +5 -0
- package/dist/index.js.map +1 -1
- package/dist/sdk-config.d.ts +11 -0
- package/dist/sdk-config.js +8 -1
- package/dist/sdk-config.js.map +1 -1
- package/dist/services/DataService/data-service.d.ts +5 -0
- package/dist/services/DataService/data-service.js +7 -2
- package/dist/services/DataService/data-service.js.map +1 -1
- package/dist/services/Locking/calculate-apy.test.d.ts +1 -0
- package/dist/services/Locking/calculate-apy.test.js +41 -0
- package/dist/services/Locking/calculate-apy.test.js.map +1 -0
- package/dist/services/Locking/locking.d.ts +14 -0
- package/dist/services/Locking/locking.js +16 -2
- package/dist/services/Locking/locking.js.map +1 -1
- package/dist/tests/sample.test.js +46 -25
- package/dist/tests/sample.test.js.map +1 -1
- package/package.json +44 -13
- package/src/domain/deposit-bounds.test.ts +200 -0
- package/src/domain/deposit-bounds.ts +118 -0
- package/src/domain/index.ts +70 -0
- package/src/domain/partners.test.ts +83 -0
- package/src/domain/partners.ts +66 -0
- package/src/domain/pools.test.ts +260 -0
- package/src/domain/pools.ts +150 -0
- package/src/domain/rates.test.ts +254 -0
- package/src/domain/rates.ts +120 -0
- package/src/domain/tranche-display-name.test.ts +96 -0
- package/src/domain/tranche-display-name.ts +34 -0
- package/src/domain/tranches.test.ts +300 -0
- package/src/domain/tranches.ts +177 -0
- package/src/facade/chain-configs.ts +55 -0
- package/src/facade/config.test.ts +265 -0
- package/src/facade/deposits.ts +25 -0
- package/src/{tests → facade}/facade.test.ts +10 -5
- package/src/facade/index.ts +4 -0
- package/src/facade/kasu.ts +155 -12
- package/src/facade/strategies.ts +36 -0
- package/src/facade/types.ts +60 -2
- package/src/facade/unused-pool-ids.ts +59 -0
- package/src/index.ts +6 -0
- package/src/sdk-config.ts +19 -1
- package/src/services/DataService/data-service.ts +7 -2
- package/src/services/Locking/calculate-apy.test.ts +52 -0
- package/src/services/Locking/locking.ts +16 -2
- package/src/tests/sample.test.ts +54 -33
- package/.eslintignore +0 -3
- package/.eslintrc.json +0 -90
- package/.github/workflows/ci.yml +0 -39
- package/.github/workflows/gitleaks.yml +0 -22
- package/.github/workflows/main.yml +0 -41
- package/.gitleaksignore +0 -19
- package/.prettierignore +0 -3
- package/.prettierrc +0 -28
- package/CLAUDE.md +0 -410
- package/copy-abi.ps1 +0 -15
- package/dist/tests/facade.test.js.map +0 -1
- package/index.ts +0 -2
- package/jest-config.ts +0 -9
- package/jest.config.js +0 -8
- package/rollup.config.js +0 -45
- package/tsconfig.json +0 -27
- /package/dist/{tests/facade.test.d.ts → domain/deposit-bounds.test.d.ts} +0 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Kasu Finance
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,313 +1,249 @@
|
|
|
1
1
|
# Kasu SDK
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
3
|
+
[](https://www.npmjs.com/package/@kasufinance/kasu-sdk)
|
|
4
|
+
[](./LICENSE)
|
|
5
|
+
[](https://github.com/Kasu-Finance/kasu-sdk/actions/workflows/ci.yml)
|
|
6
|
+
|
|
7
|
+
`@kasufinance/kasu-sdk` is the TypeScript SDK for the Kasu Finance protocol —
|
|
8
|
+
real-world credit funded on-chain. It wraps the core contracts, the subgraphs
|
|
9
|
+
and the CMS behind one object, so an application can list lending strategies,
|
|
10
|
+
read a lender's positions and submit KYC-gated deposits and withdrawals without
|
|
11
|
+
re-implementing the plumbing. It also ships a pure domain layer: the rate,
|
|
12
|
+
tranche and pool rules every Kasu frontend agrees on, as numbers rather than
|
|
13
|
+
copy.
|
|
8
14
|
|
|
9
15
|
## Installation
|
|
10
16
|
|
|
11
17
|
```bash
|
|
12
18
|
npm install @kasufinance/kasu-sdk
|
|
13
|
-
# or
|
|
14
|
-
yarn add @kasufinance/kasu-sdk
|
|
15
19
|
```
|
|
16
20
|
|
|
17
|
-
The SDK is built against
|
|
18
|
-
|
|
21
|
+
The SDK is built against **ethers v5** and resolves to the ethers already in
|
|
22
|
+
your project — it is marked external in the published bundle, so there is only
|
|
23
|
+
ever one copy in the tree. ethers v6 is not supported.
|
|
19
24
|
|
|
20
|
-
##
|
|
25
|
+
## Requirements
|
|
21
26
|
|
|
22
|
-
- **Node or
|
|
23
|
-
|
|
24
|
-
|
|
27
|
+
- **Node 18 or later**, or any runtime with a global `fetch` (all modern
|
|
28
|
+
browsers, Deno, Bun, edge runtimes). No XHR polyfill is needed.
|
|
29
|
+
- **A provider or signer** — optional. Without one the SDK builds a read-only
|
|
30
|
+
provider from the chain's default RPC; pass your own to control the endpoint,
|
|
31
|
+
and a signer to send transactions.
|
|
25
32
|
|
|
26
|
-
|
|
27
|
-
// server.ts
|
|
28
|
-
import { XMLHttpRequest } from 'xhr2';
|
|
29
|
-
global.XMLHttpRequest = XMLHttpRequest;
|
|
30
|
-
```
|
|
31
|
-
|
|
32
|
-
- **Provider/Signer** – pass an `ethers` `Signer` for write actions or a
|
|
33
|
-
`Provider` for read-only usage. The SDK does not create its own provider,
|
|
34
|
-
so you are free to reuse whatever the dapp already uses.
|
|
35
|
-
|
|
36
|
-
## Integrator Quick Start
|
|
37
|
-
|
|
38
|
-
The simplest way to use the SDK is via the `Kasu` facade, which bundles built-in
|
|
39
|
-
chain configs and provides three domain-specific interfaces:
|
|
33
|
+
## Quick start
|
|
40
34
|
|
|
41
35
|
```ts
|
|
42
|
-
import {
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
36
|
+
import {
|
|
37
|
+
Kasu,
|
|
38
|
+
fetchUnusedPoolIds,
|
|
39
|
+
netEffectiveApy,
|
|
40
|
+
} from '@kasufinance/kasu-sdk';
|
|
41
|
+
import { parseUnits } from 'ethers/lib/utils';
|
|
42
|
+
|
|
43
|
+
// Read-only. No wallet, no provider — uses the chain's default public RPC.
|
|
44
|
+
const kasu = Kasu.create({ chain: 'base' });
|
|
45
|
+
|
|
46
|
+
// The strategies a lender should see: active, not oversubscribed, capacity first.
|
|
47
|
+
const strategies = await kasu.strategies.getVisible();
|
|
48
|
+
|
|
49
|
+
// Rates are NET of the platform performance fee. `getPerformanceFeePercent()`
|
|
50
|
+
// returns a percentage in 0..100 (10 = ten percent), never a fraction.
|
|
51
|
+
const feePercent = await kasu.strategies.getPerformanceFeePercent();
|
|
50
52
|
for (const s of strategies) {
|
|
51
|
-
|
|
53
|
+
const net = netEffectiveApy(s.tranches[0].apy, feePercent);
|
|
54
|
+
console.log(s.name, `${(net * 100).toFixed(2)}% p.a. net`);
|
|
52
55
|
}
|
|
53
56
|
|
|
54
|
-
//
|
|
55
|
-
const
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
// 3. Deposit (requires a Signer and KYC signature from Nexera)
|
|
60
|
-
const kycParams = kasu.deposits.buildKycParams('0xYourAddress...');
|
|
61
|
-
// ... obtain kycSignature via your backend + Nexera signing service ...
|
|
62
|
-
const tx = await kasu.deposits.deposit({
|
|
63
|
-
poolId: strategy.id,
|
|
64
|
-
trancheId: strategy.tranches[0].id,
|
|
65
|
-
amount: parseUnits('1000', 6), // 1000 USDC
|
|
66
|
-
kycSignature: { blockExpiration, signature },
|
|
57
|
+
// Optional: hide pools that have no published content yet.
|
|
58
|
+
const readOnly = Kasu.create({
|
|
59
|
+
chain: 'base',
|
|
60
|
+
configOverrides: { UNUSED_LENDING_POOL_IDS: await fetchUnusedPoolIds() },
|
|
67
61
|
});
|
|
68
62
|
|
|
69
|
-
//
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
const
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
63
|
+
// Writes need a signer. `connect` returns a NEW instance; the read-only one
|
|
64
|
+
// keeps working.
|
|
65
|
+
// signer: an ethers v5 Signer from your wallet library
|
|
66
|
+
const signed = kasu.connect(signer);
|
|
67
|
+
const strategy = strategies[0];
|
|
68
|
+
const kycParams = signed.deposits.buildKycParams('0xYourAddress');
|
|
69
|
+
// blockExpiration, signature: obtained from your KYC backend using kycParams
|
|
70
|
+
const tx = await signed.deposits.deposit({
|
|
71
|
+
poolId: strategy.id,
|
|
72
|
+
trancheId: strategy.tranches[0].id,
|
|
73
|
+
amount: parseUnits('1000', kasu.chainConfig.stableAsset.decimals),
|
|
74
|
+
kycSignature: { blockExpiration, signature },
|
|
78
75
|
});
|
|
79
|
-
```
|
|
80
|
-
|
|
81
|
-
### Supported chains
|
|
82
|
-
|
|
83
|
-
| Chain | Usage | Deployment Type |
|
|
84
|
-
|-------|-------|-----------------|
|
|
85
|
-
| Base | `Kasu.create({ chain: 'base', ... })` | Full (KSU + lending) |
|
|
86
|
-
| XDC | `Kasu.create({ chain: 'xdc', ... })` | Lite (lending only) |
|
|
87
|
-
| Plume | `Kasu.create({ chain: 'plume', ... })` | Lite (lending only) |
|
|
88
76
|
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
```ts
|
|
92
|
-
const kasu = Kasu.create({
|
|
93
|
-
chain: { chainId: 123, name: 'MyChain', isLiteDeployment: true, contracts: { ... }, ... },
|
|
94
|
-
signerOrProvider: provider,
|
|
95
|
-
});
|
|
77
|
+
// Positions and yield (read-only is enough).
|
|
78
|
+
const positions = await kasu.portfolio.getPositions('0xUserAddress');
|
|
96
79
|
```
|
|
97
80
|
|
|
98
|
-
|
|
81
|
+
Calling a write method on a read-only instance throws before it touches the
|
|
82
|
+
contract: `Kasu: this instance is read-only; call kasu.connect(signer) first`.
|
|
99
83
|
|
|
100
|
-
|
|
101
|
-
|--------|---------|---------|
|
|
102
|
-
| `kasu.strategies` | `getAll()`, `getById()`, `getPlatformStats()`, `calculateDepositLimits()` | Browse pools, APY, capacity |
|
|
103
|
-
| `kasu.deposits` | `deposit()`, `withdraw()`, `withdrawMax()`, `buildKycParams()`, `isClearingPending()` | Submit transactions |
|
|
104
|
-
| `kasu.portfolio` | `getPositions()`, `getTransactionHistory()` | User balances, yield, history |
|
|
84
|
+
## Supported deployments
|
|
105
85
|
|
|
106
|
-
|
|
86
|
+
Each deployment lends in exactly one stable token. A different token means a
|
|
87
|
+
separate deployment, not a second vault.
|
|
107
88
|
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
89
|
+
| Chain key | Network | Chain ID | Type | Stable asset | Subgraph | Status |
|
|
90
|
+
| ---------- | ------------------ | -------- | ---- | ------------ | ---------------------- | ----------------------------- |
|
|
91
|
+
| `base` | Base Mainnet | 8453 | Full | USDC | `kasu-base/v1.0.13` | Production |
|
|
92
|
+
| `xdc` | XDC Mainnet | 50 | Lite | AUDD | `kasu-xdc/v1.0.0` | Production |
|
|
93
|
+
| `xdc-usdc` | XDC Mainnet (USDC) | 50 | Lite | USDC | `kasu-xdc-usdc/v1.0.0` | Production, separate stack |
|
|
94
|
+
| `plume` | Plume Mainnet | 98866 | Lite | pUSD | legacy project | Retired — frozen history only |
|
|
113
95
|
|
|
114
|
-
|
|
96
|
+
Full deployments have the KSU token, locking and loyalty rewards; Lite
|
|
97
|
+
deployments have lending only. `plume` is wound down: it has no default RPC, so
|
|
98
|
+
a read-only `Kasu.create({ chain: 'plume' })` throws — pass your own provider to
|
|
99
|
+
read its history.
|
|
115
100
|
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
### Full Deployment (Base)
|
|
120
|
-
|
|
121
|
-
Full deployments have all features including KSU token, locking, and loyalty rewards:
|
|
101
|
+
Every entry lives in `CHAIN_CONFIGS`, including contract addresses, subgraph
|
|
102
|
+
URLs, the stable asset and public RPC defaults:
|
|
122
103
|
|
|
123
104
|
```ts
|
|
124
|
-
import {
|
|
125
|
-
import { KasuSdk, SdkConfig } from '@kasufinance/kasu-sdk';
|
|
126
|
-
import { XMLHttpRequest } from 'xhr2';
|
|
127
|
-
|
|
128
|
-
global.XMLHttpRequest = XMLHttpRequest; // required on Node runtimes
|
|
105
|
+
import { CHAIN_CONFIGS } from '@kasufinance/kasu-sdk';
|
|
129
106
|
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
const config = new SdkConfig({
|
|
133
|
-
contracts: {
|
|
134
|
-
KSUToken: '0x…', // Required for Full deployment
|
|
135
|
-
IKSULocking: '0x…',
|
|
136
|
-
IKSULockBonus: '0x…',
|
|
137
|
-
UserManager: '0x…',
|
|
138
|
-
LendingPoolManager: '0x…',
|
|
139
|
-
KasuAllowList: '0x…',
|
|
140
|
-
SystemVariables: '0x…',
|
|
141
|
-
UserLoyaltyRewards: '0x…',
|
|
142
|
-
KsuPrice: '0x…',
|
|
143
|
-
ClearingCoordinator: '0x…',
|
|
144
|
-
KasuNFTs: '0x…', // Required for Full deployment
|
|
145
|
-
ExternalTVL: '0x…',
|
|
146
|
-
},
|
|
147
|
-
UNUSED_LENDING_POOL_IDS: [''],
|
|
148
|
-
directusUrl: 'https://kasu-finance.directus.app/',
|
|
149
|
-
subgraphUrl: 'https://api.goldsky.com/.../kasu-base/v1/gn',
|
|
150
|
-
isLiteDeployment: false, // Full deployment (default)
|
|
151
|
-
});
|
|
152
|
-
|
|
153
|
-
export const kasuSdk = new KasuSdk(config, provider);
|
|
107
|
+
CHAIN_CONFIGS.base.stableAsset; // { address, symbol, name, decimals, currencyCode }
|
|
108
|
+
CHAIN_CONFIGS.xdc.rpcUrls; // starting preference only — override with your own
|
|
154
109
|
```
|
|
155
110
|
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
111
|
+
You can also pass a whole `ChainConfigEntry` instead of a chain key.
|
|
112
|
+
|
|
113
|
+
## Facade API overview
|
|
114
|
+
|
|
115
|
+
| Facade | Methods | Purpose |
|
|
116
|
+
| ----------------- | ----------------------------------------------------------------------------------------------------------------------- | ------------------------------- |
|
|
117
|
+
| `kasu.strategies` | `getAll()`, `getVisible()`, `getById()`, `getPlatformStats()`, `getPerformanceFeePercent()`, `calculateDepositLimits()` | Browse pools, APY, capacity |
|
|
118
|
+
| `kasu.deposits` | `deposit()`, `withdraw()`, `withdrawMax()`, `buildKycParams()`, `isClearingPending()` | Submit transactions |
|
|
119
|
+
| `kasu.portfolio` | `getPositions()`, `getTransactionHistory()` | Lender balances, yield, history |
|
|
120
|
+
|
|
121
|
+
On the instance itself: `kasu.connect(signer)`, `kasu.isReadOnly`,
|
|
122
|
+
`kasu.provider`, `kasu.chainConfig`, `kasu.isLiteDeployment`, and
|
|
123
|
+
`kasu.services` for the low-level services below.
|
|
124
|
+
|
|
125
|
+
`fetchUnusedPoolIds(directusUrl?)` reads the pool ids that are configured but
|
|
126
|
+
not yet published, for `configOverrides.UNUSED_LENDING_POOL_IDS`. It may
|
|
127
|
+
return an empty list; pass it straight through. `SdkConfig` normalises an empty
|
|
128
|
+
exclusion list to `['']`, because the subgraph reads `id_not_in: []` as "match
|
|
129
|
+
nothing" and would otherwise hide every pool.
|
|
130
|
+
|
|
131
|
+
## Domain helpers
|
|
132
|
+
|
|
133
|
+
Pure functions shared by every Kasu frontend. They return **numbers and codes,
|
|
134
|
+
never copy** — no locale, no `Intl`, no user-facing strings — so each
|
|
135
|
+
application formats them in its own design system and language.
|
|
136
|
+
|
|
137
|
+
| Module | Exports |
|
|
138
|
+
| -------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
139
|
+
| Rates | `EPOCHS_IN_YEAR`, `epochRateToApy`, `apyToEpochRate`, `netEffectiveApy` |
|
|
140
|
+
| Tranches | `trancheHasCapacity`, `poolAllTranchesFull`, `derivePoolStatus`, `trancheRiskRank`, `compareTrancheSeniority`, `pickDefaultTrancheId`, `trancheApyBounds`, `netTrancheApyBounds`, `MIN_TRANCHE_CAPACITY` |
|
|
141
|
+
| Deposit bounds | `resolveDepositBounds`, `resolveBoundShortcuts`, `isBelowMinimumCapacity`, `parseTrancheBound`, `floorToCents`, `ceilToCents` |
|
|
142
|
+
| Pools | `selectVisiblePools`, `poolMaxApy`, `pickHighestYieldTranche`, `maxNetRateCeiling` |
|
|
143
|
+
| Partners | `getCreditOriginator`, `getInstitutionalLender`, `APXIUM`, `INVOICEMATE`, `RIXON_CAPITAL` |
|
|
144
|
+
| Tranche display name | `getTrancheDisplayName`, `UPPER_MEZZANINE` |
|
|
145
|
+
|
|
146
|
+
Two rules worth knowing:
|
|
147
|
+
|
|
148
|
+
- **Rates fail closed.** `netEffectiveApy`, `netTrancheApyBounds` and
|
|
149
|
+
`maxNetRateCeiling` return `NaN` / `null` rather than a plausible-looking
|
|
150
|
+
wrong number when an input is out of domain. Render that as "no rate", never
|
|
151
|
+
as zero, and never substitute a fee of `0` for one you have not loaded — a
|
|
152
|
+
fee-less rate overstates what a lender earns.
|
|
153
|
+
- **The tranche rename is display-only.** `getTrancheDisplayName` maps the
|
|
154
|
+
`Senior` tranche to "Upper Mezzanine" on Apxium strategies, because the true
|
|
155
|
+
senior position is held by an institutional lender. Call it at the view
|
|
156
|
+
boundary only: ranking, matching and sorting keep the raw on-chain name.
|
|
157
|
+
|
|
158
|
+
## Low-level `KasuSdk`
|
|
159
|
+
|
|
160
|
+
Most integrators should use the `Kasu` facade. For locking, swaps, NFTs and
|
|
161
|
+
anything the facade does not cover, reach the services directly — either
|
|
162
|
+
through `kasu.services` or by constructing `KasuSdk` with your own `SdkConfig`
|
|
163
|
+
(see `CHAIN_CONFIGS` in `src/facade/chain-configs.ts` for a complete example of
|
|
164
|
+
every field).
|
|
160
165
|
|
|
161
166
|
```ts
|
|
162
|
-
|
|
163
|
-
contracts: {
|
|
164
|
-
// KSUToken: undefined, // Not available on Lite
|
|
165
|
-
IKSULocking: '0x…', // Lite version contract
|
|
166
|
-
IKSULockBonus: '0x…', // Lite version contract
|
|
167
|
-
UserManager: '0x…', // Lite version contract
|
|
168
|
-
LendingPoolManager: '0x…',
|
|
169
|
-
KasuAllowList: '0x…',
|
|
170
|
-
SystemVariables: '0x…',
|
|
171
|
-
UserLoyaltyRewards: '0x…', // Lite version contract
|
|
172
|
-
KsuPrice: '0x…', // Lite version contract
|
|
173
|
-
ClearingCoordinator: '0x…',
|
|
174
|
-
// KasuNFTs: undefined, // Not available on Lite
|
|
175
|
-
ExternalTVL: '0x…',
|
|
176
|
-
},
|
|
177
|
-
UNUSED_LENDING_POOL_IDS: [''],
|
|
178
|
-
directusUrl: 'https://kasu-finance.directus.app/',
|
|
179
|
-
subgraphUrl: 'https://api.goldsky.com/.../kasu-xdc/v1.0.0/gn',
|
|
180
|
-
isLiteDeployment: true, // Lite deployment - disables KSU features
|
|
181
|
-
});
|
|
182
|
-
|
|
183
|
-
export const kasuSdk = new KasuSdk(config, provider);
|
|
184
|
-
```
|
|
167
|
+
import { KasuSdk, SdkConfig, CHAIN_CONFIGS } from '@kasufinance/kasu-sdk';
|
|
185
168
|
|
|
186
|
-
### Multi-Chain Configuration
|
|
187
|
-
|
|
188
|
-
For frontends supporting multiple chains, create a config per chain:
|
|
189
|
-
|
|
190
|
-
```ts
|
|
191
|
-
// config/chains.ts
|
|
192
|
-
const chainConfigs = {
|
|
193
|
-
base: {
|
|
194
|
-
chainId: 8453,
|
|
195
|
-
subgraphUrl: 'https://api.goldsky.com/.../kasu-base/v1/gn',
|
|
196
|
-
isLiteDeployment: false,
|
|
197
|
-
contracts: { /* Base contract addresses */ },
|
|
198
|
-
},
|
|
199
|
-
xdc: {
|
|
200
|
-
chainId: 50,
|
|
201
|
-
subgraphUrl: 'https://api.goldsky.com/.../kasu-xdc/v1.0.0/gn',
|
|
202
|
-
isLiteDeployment: true,
|
|
203
|
-
contracts: { /* XDC contract addresses */ },
|
|
204
|
-
},
|
|
205
|
-
};
|
|
206
|
-
|
|
207
|
-
// Create SDK for current chain
|
|
208
|
-
const chainConfig = chainConfigs[currentChain];
|
|
209
169
|
const config = new SdkConfig({
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
170
|
+
subgraphUrl: CHAIN_CONFIGS.base.subgraphUrl,
|
|
171
|
+
contracts: CHAIN_CONFIGS.base.contracts,
|
|
172
|
+
directusUrl: CHAIN_CONFIGS.base.directusUrl,
|
|
173
|
+
UNUSED_LENDING_POOL_IDS: [],
|
|
174
|
+
isLiteDeployment: false,
|
|
175
|
+
stableAssetDecimals: CHAIN_CONFIGS.base.stableAsset.decimals,
|
|
213
176
|
});
|
|
214
|
-
const sdk = new KasuSdk(config, provider);
|
|
215
|
-
```
|
|
216
|
-
|
|
217
|
-
See `kasu-fe-next/src/config/sdk` in the Kasu frontend repository for full
|
|
218
|
-
mainnet and testnet examples, including how Kasu fetches unused pool ids before
|
|
219
|
-
instantiating the SDK.
|
|
220
|
-
|
|
221
|
-
### Low-level Quick start
|
|
222
177
|
|
|
223
|
-
|
|
224
|
-
import { JsonRpcProvider } from '@ethersproject/providers';
|
|
225
|
-
import { KasuSdk } from '@kasufinance/kasu-sdk';
|
|
226
|
-
|
|
227
|
-
const provider = new JsonRpcProvider(RPC_URL);
|
|
178
|
+
// provider: an ethers v5 Provider or Signer
|
|
228
179
|
const sdk = new KasuSdk(config, provider);
|
|
229
|
-
|
|
180
|
+
// currentEpochId: from `await kasu.deposits.getCurrentEpoch()`
|
|
230
181
|
const pools = await sdk.DataService.getPoolOverview(currentEpochId);
|
|
231
|
-
const lockingPeriods = await sdk.Locking.getLockPeriods();
|
|
232
|
-
const userSummary = await sdk.Portfolio.getPortfolioSummary(userAddress);
|
|
233
|
-
await sdk.Locking.lockKSUTokens(amountBn, lockPeriodBn); // signer required
|
|
234
182
|
```
|
|
235
183
|
|
|
236
|
-
|
|
237
|
-
|
|
184
|
+
| Service | Purpose |
|
|
185
|
+
| ------------- | ------------------------------------------------------------------------------------------- |
|
|
186
|
+
| `DataService` | On-chain pool data (subgraph, external TVL) plus CMS content — descriptions, KPIs, imagery. |
|
|
187
|
+
| `Locking` | KSU locking: periods, projected rewards, lock/unlock, claim fees. Full deployments only. |
|
|
188
|
+
| `UserLending` | Deposit and withdrawal requests, transaction history, CSV builders. |
|
|
189
|
+
| `Portfolio` | Balances, rewards, lending totals, APY. |
|
|
190
|
+
| `Swapper` | Calls through the on-chain swapper. |
|
|
238
191
|
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
| `DataService` | Aggregates on-chain data (subgraphs/external TVL) and off-chain content from Directus (pool descriptions, KPIs). |
|
|
242
|
-
| `Locking` | High-level helpers for KSU locking: read locking periods, calculate projected rewards, lock/unlock, claim fees. |
|
|
243
|
-
| `UserLending` | User-centric lending utilities (deposit/withdraw requests, transaction history, CSV builders). |
|
|
244
|
-
| `Portfolio` | Portfolio snapshots: balances, rewards, lending totals, APY calculations. |
|
|
245
|
-
| `Swapper` | Helpers for contract calls through the on-chain swapper. |
|
|
192
|
+
Every method is typed, so an editor discovers the shape of `PoolOverview`,
|
|
193
|
+
`LockPeriod`, `PortfolioRewards` and the rest without reading the source.
|
|
246
194
|
|
|
247
|
-
|
|
248
|
-
(`PoolOverview`, `LockPeriod`, `PortfolioRewards`, etc.) without digging into
|
|
249
|
-
the implementation.
|
|
195
|
+
## Lite deployment behaviour
|
|
250
196
|
|
|
251
|
-
|
|
197
|
+
With `isLiteDeployment: true`, KSU-related functionality degrades predictably
|
|
198
|
+
rather than throwing at random:
|
|
252
199
|
|
|
253
|
-
|
|
254
|
-
|
|
200
|
+
| Method | Full deployment | Lite deployment |
|
|
201
|
+
| ----------------------------------------------- | --------------------- | ------------------------------------ |
|
|
202
|
+
| `Locking.lockKSUTokens()` | Works normally | Throws |
|
|
203
|
+
| `Locking.getUserTotalLockedAmount()` | Returns locked amount | Returns `'0'` |
|
|
204
|
+
| `Locking.getLoyaltyLevelAndApyBonusFromRatio()` | Calculates the level | Returns level 0, 0% bonus |
|
|
205
|
+
| `Locking.getKasuEpochTokenPrice()` | Returns the price | Returns `{ price: 0, decimals: 18 }` |
|
|
206
|
+
| `Portfolio.getUserNfts()` | Returns NFT ids | Returns `[]` |
|
|
207
|
+
| `Portfolio.getPortfolioRewards()` | Returns rewards | Returns zeros |
|
|
255
208
|
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
| `Locking.lockKSUTokens()` | Works normally | Throws error |
|
|
259
|
-
| `Locking.getUserTotalLockedAmount()` | Returns locked amount | Returns `'0'` |
|
|
260
|
-
| `Locking.getLoyaltyLevelAndApyBonusFromRatio()` | Calculates level | Returns level 0, 0% bonus |
|
|
261
|
-
| `Locking.getKasuEpochTokenPrice()` | Returns current price | Returns `{ price: 0, decimals: 18 }` |
|
|
262
|
-
| `Portfolio.getUserNfts()` | Returns NFT ids | Returns `[]` |
|
|
263
|
-
| `Portfolio.getPortfolioRewards()` | Returns rewards | Returns zeros |
|
|
209
|
+
Applications should hide KSU surfaces — the locking panel, loyalty badges, KSU
|
|
210
|
+
rewards — when `kasu.isLiteDeployment` is true.
|
|
264
211
|
|
|
265
|
-
|
|
266
|
-
loyalty badges, KSU rewards) when `config.isLiteDeployment` is true.
|
|
212
|
+
## Development
|
|
267
213
|
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
const sdk = new KasuSdk(
|
|
277
|
-
{ ...config, UNUSED_LENDING_POOL_IDS: unusedPools.length ? unusedPools : [''] },
|
|
278
|
-
provider,
|
|
279
|
-
);
|
|
214
|
+
```bash
|
|
215
|
+
npm ci
|
|
216
|
+
npm run build-tc # regenerate typechain factories from abis/
|
|
217
|
+
npm run build # eslint + tsc
|
|
218
|
+
npm run rollup-build # bundle to dist/
|
|
219
|
+
npm run test:unit # the offline suites — the fast loop, and what CI runs
|
|
220
|
+
npm test # the same suites; the live specs skip unless LIVE_TESTS=1
|
|
221
|
+
npm run test:live # opt-in: the specs that reach real subgraphs and RPCs
|
|
280
222
|
```
|
|
281
223
|
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
## Building & testing locally
|
|
224
|
+
Everything outside `src/tests/` is offline and fast. `src/tests/` holds the
|
|
225
|
+
specs that talk to live networks; they are skipped unless `LIVE_TESTS=1`, so a
|
|
226
|
+
network problem cannot fail a pull request that did not touch the network.
|
|
286
227
|
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
npm run build-tc # regenerate typechain factories
|
|
290
|
-
npm run build # type-check + compile
|
|
291
|
-
npm run rollup-build
|
|
292
|
-
npm test
|
|
293
|
-
```
|
|
228
|
+
CI runs `build-tc`, `build`, `test:unit` and `rollup-build` on every pull
|
|
229
|
+
request.
|
|
294
230
|
|
|
295
|
-
|
|
296
|
-
npm.
|
|
231
|
+
## Versioning & publishing
|
|
297
232
|
|
|
298
|
-
|
|
233
|
+
The package follows semantic versioning. The published runtime entry is the
|
|
234
|
+
rollup bundle (`dist/bundle.cjs.js` / `dist/bundle.esm.js`), which
|
|
235
|
+
`prepublishOnly` rebuilds — so when verifying a release, check the contents of a
|
|
236
|
+
packed tarball rather than the version number alone.
|
|
299
237
|
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
| Base | 8453 | Full | `kasu-base/v1` |
|
|
303
|
-
| XDC | 50 | Lite | `kasu-xdc/v1.0.0` |
|
|
304
|
-
| Plume | 98866 | Lite | `kasu-plume/prod` |
|
|
238
|
+
Publishing is manual and is done by a member of the npm organisation; the
|
|
239
|
+
tag workflow only verifies that a pushed `vX.Y.Z` tag matches `package.json`.
|
|
305
240
|
|
|
306
241
|
## Support
|
|
307
|
-
|
|
308
|
-
-
|
|
309
|
-
-
|
|
310
|
-
-
|
|
242
|
+
|
|
243
|
+
- Issues: <https://github.com/Kasu-Finance/kasu-sdk/issues>
|
|
244
|
+
- Developer documentation: <https://devdocs.kasu.finance>
|
|
245
|
+
- Product documentation: <https://docs.kasu.finance>
|
|
311
246
|
|
|
312
247
|
## License
|
|
313
|
-
|
|
248
|
+
|
|
249
|
+
MIT — see [LICENSE](./LICENSE).
|