@spield/sdk 0.4.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/CHANGELOG.md +67 -0
- package/README.md +94 -0
- package/RELEASE.md +8 -0
- package/USAGE.md +215 -0
- package/dist/index.cjs +1520 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +783 -0
- package/dist/index.d.ts +783 -0
- package/dist/index.js +1474 -0
- package/dist/index.js.map +1 -0
- package/package.json +66 -0
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,783 @@
|
|
|
1
|
+
import { rpc, xdr, Horizon } from '@stellar/stellar-sdk';
|
|
2
|
+
|
|
3
|
+
type SpieldNetworkKey = 'testnet' | 'custom';
|
|
4
|
+
type SpieldNetworkConfig = {
|
|
5
|
+
key: SpieldNetworkKey;
|
|
6
|
+
networkName: 'TESTNET' | string;
|
|
7
|
+
networkPassphrase: string;
|
|
8
|
+
rpcUrl: string;
|
|
9
|
+
horizonUrl: string;
|
|
10
|
+
explorerUrl: string;
|
|
11
|
+
contracts: {
|
|
12
|
+
/** Standardized Return share token over the strategy. */
|
|
13
|
+
sr: string;
|
|
14
|
+
/** Blend adapter behind SR. */
|
|
15
|
+
strategy: string;
|
|
16
|
+
/** PT/YT engine. This contract is also the custom SEP-41 YT token. */
|
|
17
|
+
yieldEngine: string;
|
|
18
|
+
/** PT/SR market. */
|
|
19
|
+
market: string;
|
|
20
|
+
/** Fixed-rate vault. */
|
|
21
|
+
vault: string;
|
|
22
|
+
/** One-transaction USDC routes. */
|
|
23
|
+
router: string;
|
|
24
|
+
/** Principal Token Stellar Asset Contract. */
|
|
25
|
+
pt: string;
|
|
26
|
+
usdc: string;
|
|
27
|
+
};
|
|
28
|
+
assets: {
|
|
29
|
+
/** The only trustline the protocol requires. YT is a contract token, not a classic asset. */
|
|
30
|
+
pt: {
|
|
31
|
+
code: string;
|
|
32
|
+
issuer: string;
|
|
33
|
+
};
|
|
34
|
+
};
|
|
35
|
+
decimals: number;
|
|
36
|
+
};
|
|
37
|
+
declare const STELLAR_NETWORK_PASSPHRASES: {
|
|
38
|
+
readonly PUBLIC: "Public Global Stellar Network ; September 2015";
|
|
39
|
+
readonly TESTNET: "Test SDF Network ; September 2015";
|
|
40
|
+
};
|
|
41
|
+
/**
|
|
42
|
+
* The live Spield Testnet deployment, tracking `deploy_sr_testnet.state` as of the
|
|
43
|
+
* **2026-08-30 redeploy**.
|
|
44
|
+
*
|
|
45
|
+
* That deployment carries the whole `FINAL_CHECK.md` round, and two of the fixes change behaviour
|
|
46
|
+
* an SDK consumer can observe:
|
|
47
|
+
*
|
|
48
|
+
* * **V2-01** — the market now prices every value-moving trade on a SYNCHRONIZED index
|
|
49
|
+
* (`yieldEngine.py_index_current`). The `quote*` views still read the stored rate and can
|
|
50
|
+
* therefore slightly OVER-state a sale, so size `minOut` from a simulation of the real entry
|
|
51
|
+
* point rather than from a quote. See `USAGE.md`.
|
|
52
|
+
* * **V2-03** — the router no longer refuses to trade while a stray token balance rests on it, so
|
|
53
|
+
* a stranger's dust can no longer deny every route.
|
|
54
|
+
*
|
|
55
|
+
* New read-only surface: `sr.realizableRate()`, `strategy.claimableEmissions()`.
|
|
56
|
+
*/
|
|
57
|
+
declare const testnet: () => SpieldNetworkConfig;
|
|
58
|
+
declare const customNetwork: (config: SpieldNetworkConfig) => SpieldNetworkConfig;
|
|
59
|
+
|
|
60
|
+
type SpieldSigner = {
|
|
61
|
+
getAddress(): Promise<string>;
|
|
62
|
+
signTransaction(xdr: string, opts: {
|
|
63
|
+
networkPassphrase: string;
|
|
64
|
+
address: string;
|
|
65
|
+
}): Promise<{
|
|
66
|
+
signedTxXdr: string;
|
|
67
|
+
}>;
|
|
68
|
+
};
|
|
69
|
+
type FreighterApi = {
|
|
70
|
+
getAddress?: () => Promise<{
|
|
71
|
+
address?: string;
|
|
72
|
+
} | string>;
|
|
73
|
+
signTransaction?: (xdr: string, opts: {
|
|
74
|
+
networkPassphrase: string;
|
|
75
|
+
address: string;
|
|
76
|
+
}) => Promise<{
|
|
77
|
+
signedTxXdr?: string;
|
|
78
|
+
} | string>;
|
|
79
|
+
};
|
|
80
|
+
declare class FreighterSigner implements SpieldSigner {
|
|
81
|
+
private readonly api?;
|
|
82
|
+
constructor(api?: FreighterApi | undefined);
|
|
83
|
+
private get freighter();
|
|
84
|
+
getAddress(): Promise<string>;
|
|
85
|
+
signTransaction(xdr: string, opts: {
|
|
86
|
+
networkPassphrase: string;
|
|
87
|
+
address: string;
|
|
88
|
+
}): Promise<{
|
|
89
|
+
signedTxXdr: string;
|
|
90
|
+
}>;
|
|
91
|
+
}
|
|
92
|
+
declare class ManualSigner implements SpieldSigner {
|
|
93
|
+
private readonly address;
|
|
94
|
+
private readonly sign;
|
|
95
|
+
constructor(address: string, sign: SpieldSigner['signTransaction']);
|
|
96
|
+
getAddress(): Promise<string>;
|
|
97
|
+
signTransaction(xdr: string, opts: {
|
|
98
|
+
networkPassphrase: string;
|
|
99
|
+
address: string;
|
|
100
|
+
}): Promise<{
|
|
101
|
+
signedTxXdr: string;
|
|
102
|
+
}>;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
type SpieldClientOptions = {
|
|
106
|
+
network?: SpieldNetworkConfig;
|
|
107
|
+
signer?: SpieldSigner;
|
|
108
|
+
simulationSource?: string;
|
|
109
|
+
/** Maximum time to wait for Soroban RPC to index a submitted transaction. Defaults to 120 seconds. */
|
|
110
|
+
confirmationTimeoutMs?: number;
|
|
111
|
+
/** Delay between confirmation polls. Defaults to 1 second. */
|
|
112
|
+
confirmationPollIntervalMs?: number;
|
|
113
|
+
};
|
|
114
|
+
type CallOptions = {
|
|
115
|
+
signer?: SpieldSigner;
|
|
116
|
+
};
|
|
117
|
+
type TransactionResult = {
|
|
118
|
+
hash: string;
|
|
119
|
+
status: 'success';
|
|
120
|
+
explorerUrl: string;
|
|
121
|
+
};
|
|
122
|
+
type TokenSymbol = 'USDC' | 'PT' | 'YT' | string;
|
|
123
|
+
type TokenAmount = {
|
|
124
|
+
raw: bigint;
|
|
125
|
+
formatted: string;
|
|
126
|
+
decimals: number;
|
|
127
|
+
symbol: TokenSymbol;
|
|
128
|
+
};
|
|
129
|
+
|
|
130
|
+
type SorobanContext = {
|
|
131
|
+
network: SpieldNetworkConfig;
|
|
132
|
+
signer?: SpieldSigner;
|
|
133
|
+
simulationSource: string;
|
|
134
|
+
confirmationTimeoutMs?: number;
|
|
135
|
+
confirmationPollIntervalMs?: number;
|
|
136
|
+
};
|
|
137
|
+
declare class SorobanClient {
|
|
138
|
+
private readonly context;
|
|
139
|
+
readonly server: rpc.Server;
|
|
140
|
+
constructor(context: SorobanContext);
|
|
141
|
+
read<T = unknown>(contractId: string, method: string, args?: xdr.ScVal[]): Promise<T>;
|
|
142
|
+
/**
|
|
143
|
+
* **Simulate a value-moving entry point AS `invoker`, and return what it would actually pay.**
|
|
144
|
+
*
|
|
145
|
+
* The `quote_*` views cannot synchronize SR — a view may not write — so they price on SR's stored
|
|
146
|
+
* high-water rate, which lags whenever nothing has synced since the last mutation. The real entry
|
|
147
|
+
* points *do* synchronize (`FINAL_CHECK.md` V2-01), so a quote can OVER-state a sale: derive
|
|
148
|
+
* `minOut` from it and the trade can trip its own slippage bound and revert.
|
|
149
|
+
*
|
|
150
|
+
* Simulating the real function runs the same synchronized code the submission will. Nothing is
|
|
151
|
+
* signed and nothing is sent.
|
|
152
|
+
*
|
|
153
|
+
* Unlike {@link read}, this simulates as the **user** rather than the shared simulation source,
|
|
154
|
+
* because the result depends on their balances.
|
|
155
|
+
*
|
|
156
|
+
* Returns `null` whenever the simulation cannot run — an unaffordable size, a route the pool
|
|
157
|
+
* cannot fill, a deployment predating the entry point — so callers fall back to the quote instead
|
|
158
|
+
* of failing the trade.
|
|
159
|
+
*/
|
|
160
|
+
simulateAs(invoker: string, contractId: string, method: string, args?: xdr.ScVal[]): Promise<bigint | null>;
|
|
161
|
+
write(contractId: string, method: string, args?: xdr.ScVal[], signer?: SpieldSigner | undefined): Promise<TransactionResult>;
|
|
162
|
+
private waitForConfirmation;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
type BlendStrategyRateBound = {
|
|
166
|
+
lastRate: bigint;
|
|
167
|
+
lastTimestamp: number;
|
|
168
|
+
maxAprBps: number;
|
|
169
|
+
};
|
|
170
|
+
type BlendStrategyState = {
|
|
171
|
+
currentRate: bigint;
|
|
172
|
+
totalShares: TokenAmount;
|
|
173
|
+
availableLiquidity: TokenAmount;
|
|
174
|
+
underlying: string;
|
|
175
|
+
pool: string;
|
|
176
|
+
rateBound: BlendStrategyRateBound;
|
|
177
|
+
};
|
|
178
|
+
/** Read client for the Blend adapter behind SR. */
|
|
179
|
+
declare class BlendStrategyClient {
|
|
180
|
+
private readonly network;
|
|
181
|
+
private readonly soroban;
|
|
182
|
+
constructor(network: SpieldNetworkConfig, soroban: SorobanClient);
|
|
183
|
+
private get contract();
|
|
184
|
+
getAvailableLiquidity(): Promise<TokenAmount>;
|
|
185
|
+
/**
|
|
186
|
+
* **BLND accrued to the protocol and not yet claimed.**
|
|
187
|
+
*
|
|
188
|
+
* Measured on mainnet 2026-08-30: Blend allocates emissions to XLM *suppliers* and USDC
|
|
189
|
+
* *borrowers*, not USDC suppliers — which is the side Spield is on — so this reads `0` and has
|
|
190
|
+
* never been anything else. Allocations carry an expiration and rotate each cycle, so it will not
|
|
191
|
+
* necessarily stay zero.
|
|
192
|
+
*
|
|
193
|
+
* Claiming is permissionless and pays a destination fixed in contract storage, so an integrator
|
|
194
|
+
* can trigger it but can never redirect it.
|
|
195
|
+
*/
|
|
196
|
+
getClaimableEmissions(): Promise<TokenAmount>;
|
|
197
|
+
/**
|
|
198
|
+
* **What the whole Blend position is really worth**, live rate, no monotonicity guard, no write.
|
|
199
|
+
* Unlike {@link getPositionValue} this keeps answering while a rate decrease has exits frozen.
|
|
200
|
+
*/
|
|
201
|
+
getPositionValueUnguarded(): Promise<TokenAmount | null>;
|
|
202
|
+
getRateBound(): Promise<BlendStrategyRateBound>;
|
|
203
|
+
getPositionValue(input: {
|
|
204
|
+
shares: string | number | bigint;
|
|
205
|
+
}): Promise<TokenAmount>;
|
|
206
|
+
getState(): Promise<BlendStrategyState>;
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
declare const YT_MAX_IN_PAD_BPS = 300n;
|
|
210
|
+
type SrMarketStats = {
|
|
211
|
+
ptReserve: TokenAmount;
|
|
212
|
+
srReserve: TokenAmount;
|
|
213
|
+
assetReserve: TokenAmount;
|
|
214
|
+
totalShares: TokenAmount;
|
|
215
|
+
ptPrice: bigint;
|
|
216
|
+
ptPriceNumber: number;
|
|
217
|
+
impliedApy: bigint;
|
|
218
|
+
impliedApyPct: number;
|
|
219
|
+
expiry: number;
|
|
220
|
+
expiryDate: Date;
|
|
221
|
+
treasuryEarned: TokenAmount;
|
|
222
|
+
treasuryFeeShareBps: number;
|
|
223
|
+
paused: boolean;
|
|
224
|
+
};
|
|
225
|
+
type SrMarketQuote = {
|
|
226
|
+
input: TokenAmount;
|
|
227
|
+
output: TokenAmount;
|
|
228
|
+
available: boolean;
|
|
229
|
+
};
|
|
230
|
+
type SrLpPosition = {
|
|
231
|
+
shares: TokenAmount;
|
|
232
|
+
ptClaim: TokenAmount;
|
|
233
|
+
srClaim: TokenAmount;
|
|
234
|
+
};
|
|
235
|
+
/** Client for the current PT/SR AMM and its YT routes. */
|
|
236
|
+
declare class SrMarketClient {
|
|
237
|
+
private readonly network;
|
|
238
|
+
private readonly soroban;
|
|
239
|
+
private readonly signer?;
|
|
240
|
+
private latestLiquidityAbi;
|
|
241
|
+
constructor(network: SpieldNetworkConfig, soroban: SorobanClient, signer?: SpieldSigner | undefined);
|
|
242
|
+
private get contract();
|
|
243
|
+
getStats(): Promise<SrMarketStats>;
|
|
244
|
+
private quote;
|
|
245
|
+
quoteBuyPt(input: {
|
|
246
|
+
srIn: string | number | bigint;
|
|
247
|
+
}): Promise<SrMarketQuote>;
|
|
248
|
+
quoteSellPt(input: {
|
|
249
|
+
ptIn: string | number | bigint;
|
|
250
|
+
}): Promise<SrMarketQuote>;
|
|
251
|
+
quoteBuyYt(input: {
|
|
252
|
+
ytOut: string | number | bigint;
|
|
253
|
+
}): Promise<SrMarketQuote>;
|
|
254
|
+
quoteSellYt(input: {
|
|
255
|
+
ytIn: string | number | bigint;
|
|
256
|
+
}): Promise<SrMarketQuote>;
|
|
257
|
+
getLpPosition(input: {
|
|
258
|
+
owner: string;
|
|
259
|
+
}): Promise<SrLpPosition>;
|
|
260
|
+
buyPt(input: {
|
|
261
|
+
srIn: string | number | bigint;
|
|
262
|
+
minPtOut?: string | number | bigint;
|
|
263
|
+
deadlineLedger?: number;
|
|
264
|
+
signer?: SpieldSigner;
|
|
265
|
+
}): Promise<TransactionResult>;
|
|
266
|
+
sellPt(input: {
|
|
267
|
+
ptIn: string | number | bigint;
|
|
268
|
+
minSrOut?: string | number | bigint;
|
|
269
|
+
deadlineLedger?: number;
|
|
270
|
+
signer?: SpieldSigner;
|
|
271
|
+
}): Promise<TransactionResult>;
|
|
272
|
+
buyYt(input: {
|
|
273
|
+
ytOut: string | number | bigint;
|
|
274
|
+
maxSrIn?: string | number | bigint;
|
|
275
|
+
deadlineLedger?: number;
|
|
276
|
+
signer?: SpieldSigner;
|
|
277
|
+
}): Promise<TransactionResult>;
|
|
278
|
+
sellYt(input: {
|
|
279
|
+
ytIn: string | number | bigint;
|
|
280
|
+
minSrOut?: string | number | bigint;
|
|
281
|
+
deadlineLedger?: number;
|
|
282
|
+
signer?: SpieldSigner;
|
|
283
|
+
}): Promise<TransactionResult>;
|
|
284
|
+
addLiquidity(input: {
|
|
285
|
+
ptIn: string | number | bigint;
|
|
286
|
+
srIn: string | number | bigint;
|
|
287
|
+
/** Minimum LP shares accepted. Positive values opt into the new caller-controlled tolerance. */
|
|
288
|
+
minShares?: string | number | bigint;
|
|
289
|
+
signer?: SpieldSigner;
|
|
290
|
+
}): Promise<TransactionResult>;
|
|
291
|
+
removeLiquidity(input: {
|
|
292
|
+
shares: string | number | bigint;
|
|
293
|
+
minPtOut?: string | number | bigint;
|
|
294
|
+
minSrOut?: string | number | bigint;
|
|
295
|
+
signer?: SpieldSigner;
|
|
296
|
+
}): Promise<TransactionResult>;
|
|
297
|
+
/** Permissionless keep-alive for an LP share entry. */
|
|
298
|
+
bumpLp(input?: {
|
|
299
|
+
owner?: string;
|
|
300
|
+
signer?: SpieldSigner;
|
|
301
|
+
}): Promise<TransactionResult>;
|
|
302
|
+
private supportsLatestLiquidityAbi;
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
declare const toBaseUnits: (amount: string | number | bigint, decimals?: number) => bigint;
|
|
306
|
+
/** Parse an amount that may be zero, for slippage floors and optional minimum outputs. */
|
|
307
|
+
declare const assertNonNegativeAmount: (amount: string | number | bigint, decimals?: number) => bigint;
|
|
308
|
+
declare const fromBaseUnits: (units: bigint | number | string, decimals?: number) => string;
|
|
309
|
+
declare const tokenAmount: (raw: bigint | number | string, symbol: TokenSymbol, decimals?: number) => TokenAmount;
|
|
310
|
+
|
|
311
|
+
declare const SCALAR_12: bigint;
|
|
312
|
+
/** Convert a 12-decimal fixed-point contract scalar (price, rate, APY) to a JS number. */
|
|
313
|
+
declare const fromScalar12: (v: bigint) => number;
|
|
314
|
+
type SrState = {
|
|
315
|
+
exchangeRate: bigint;
|
|
316
|
+
exchangeRateNumber: number;
|
|
317
|
+
totalSupply: TokenAmount;
|
|
318
|
+
totalAssets: TokenAmount;
|
|
319
|
+
maxRedeemable: TokenAmount | null;
|
|
320
|
+
depositCap: TokenAmount | null;
|
|
321
|
+
depositHeadroom: TokenAmount | null;
|
|
322
|
+
/** True when the configured TVL cap, rather than a pause, blocks every new deposit. */
|
|
323
|
+
depositCapReached: boolean;
|
|
324
|
+
paused: boolean;
|
|
325
|
+
};
|
|
326
|
+
/** Client for Spield's Standardized Return (SR) share token. */
|
|
327
|
+
declare class StandardizedReturnClient {
|
|
328
|
+
private readonly network;
|
|
329
|
+
private readonly soroban;
|
|
330
|
+
private readonly signer?;
|
|
331
|
+
constructor(network: SpieldNetworkConfig, soroban: SorobanClient, signer?: SpieldSigner | undefined);
|
|
332
|
+
private get contract();
|
|
333
|
+
getExchangeRate(): Promise<bigint>;
|
|
334
|
+
/**
|
|
335
|
+
* **The honest twin of {@link getExchangeRate} — what a share is ACTUALLY worth.**
|
|
336
|
+
*
|
|
337
|
+
* `exchange_rate` is a high-water mark: it ratchets up and never falls. That stops the protocol
|
|
338
|
+
* repricing on a transient dip, but it means every value built on it — `previewRedeem`,
|
|
339
|
+
* `getAssetsOf` — reports MORE underlying than a redemption pays once Blend has taken a real loss.
|
|
340
|
+
*
|
|
341
|
+
* This reads the venue with no monotonicity guard, so unlike the guarded paths it keeps answering
|
|
342
|
+
* while exits are frozen — which is exactly when somebody needs the number.
|
|
343
|
+
*
|
|
344
|
+
* Returns `0n` on a deployment predating it. Sitting slightly ABOVE `exchange_rate` in normal
|
|
345
|
+
* operation is expected (it sees accrual the stored rate has not synced); only the other
|
|
346
|
+
* direction is interesting.
|
|
347
|
+
*/
|
|
348
|
+
getRealizableRate(): Promise<bigint>;
|
|
349
|
+
/** A holder's actual pro-rata claim. See {@link getRealizableRate}. `null` if unavailable. */
|
|
350
|
+
getRealizableValue(input: {
|
|
351
|
+
shares: string | number | bigint;
|
|
352
|
+
}): Promise<TokenAmount | null>;
|
|
353
|
+
srToUnderlying(shares: bigint, rate: bigint): bigint;
|
|
354
|
+
underlyingToSr(amount: bigint, rate: bigint): bigint;
|
|
355
|
+
previewDeposit(input: {
|
|
356
|
+
amount: string | number | bigint;
|
|
357
|
+
}): Promise<TokenAmount>;
|
|
358
|
+
previewRedeem(input: {
|
|
359
|
+
shares: string | number | bigint;
|
|
360
|
+
}): Promise<TokenAmount>;
|
|
361
|
+
getBalance(input: {
|
|
362
|
+
owner: string;
|
|
363
|
+
}): Promise<TokenAmount>;
|
|
364
|
+
getAssetsOf(input: {
|
|
365
|
+
owner: string;
|
|
366
|
+
}): Promise<TokenAmount>;
|
|
367
|
+
getState(): Promise<SrState>;
|
|
368
|
+
deposit(input: {
|
|
369
|
+
amount: string | number | bigint;
|
|
370
|
+
receiver?: string;
|
|
371
|
+
minSharesOut?: string | number | bigint;
|
|
372
|
+
signer?: SpieldSigner;
|
|
373
|
+
}): Promise<TransactionResult>;
|
|
374
|
+
redeem(input: {
|
|
375
|
+
shares: string | number | bigint;
|
|
376
|
+
receiver?: string;
|
|
377
|
+
minUnderlyingOut?: string | number | bigint;
|
|
378
|
+
signer?: SpieldSigner;
|
|
379
|
+
}): Promise<TransactionResult>;
|
|
380
|
+
redeemPartial(input: {
|
|
381
|
+
shares: string | number | bigint;
|
|
382
|
+
receiver?: string;
|
|
383
|
+
minUnderlyingOut?: string | number | bigint;
|
|
384
|
+
signer?: SpieldSigner;
|
|
385
|
+
}): Promise<TransactionResult>;
|
|
386
|
+
/** Permissionless update of SR's stored high-water exchange rate. */
|
|
387
|
+
syncRate(input?: {
|
|
388
|
+
signer?: SpieldSigner;
|
|
389
|
+
}): Promise<TransactionResult>;
|
|
390
|
+
/** Permissionless keep-alive for an SR holder's persistent balance entry. */
|
|
391
|
+
bumpHolder(input?: {
|
|
392
|
+
owner?: string;
|
|
393
|
+
signer?: SpieldSigner;
|
|
394
|
+
}): Promise<TransactionResult>;
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
/**
|
|
398
|
+
* PT is the protocol's only classic asset, so it is the only trustline a wallet needs.
|
|
399
|
+
* YT is a contract token issued by the yield engine and requires none.
|
|
400
|
+
*/
|
|
401
|
+
type PtTrustlineStatus = {
|
|
402
|
+
pt: boolean;
|
|
403
|
+
ready: boolean;
|
|
404
|
+
};
|
|
405
|
+
declare class HorizonClient {
|
|
406
|
+
private readonly network;
|
|
407
|
+
readonly horizon: Horizon.Server;
|
|
408
|
+
constructor(network: SpieldNetworkConfig);
|
|
409
|
+
getPtTrustline(address: string): Promise<PtTrustlineStatus>;
|
|
410
|
+
setupPtTrustline(address: string, signer?: SpieldSigner): Promise<TransactionResult | null>;
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
type SrTokenKey = 'USDC' | 'SR' | 'PT' | 'YT';
|
|
414
|
+
declare class SrTokensClient {
|
|
415
|
+
private readonly network;
|
|
416
|
+
private readonly soroban;
|
|
417
|
+
private readonly horizon;
|
|
418
|
+
private readonly signer?;
|
|
419
|
+
constructor(network: SpieldNetworkConfig, soroban: SorobanClient, horizon: HorizonClient, signer?: SpieldSigner | undefined);
|
|
420
|
+
getBalance(input: {
|
|
421
|
+
token: SrTokenKey;
|
|
422
|
+
owner: string;
|
|
423
|
+
}): Promise<TokenAmount>;
|
|
424
|
+
getBalances(input: {
|
|
425
|
+
owner: string;
|
|
426
|
+
}): Promise<Record<'usdc' | 'sr' | 'pt' | 'yt', TokenAmount>>;
|
|
427
|
+
getPtTrustline(input: {
|
|
428
|
+
owner: string;
|
|
429
|
+
}): Promise<PtTrustlineStatus>;
|
|
430
|
+
/** Set up the sole v2 trustline. YT is a contract token and must not get a trustline. */
|
|
431
|
+
ensurePtTrustline(input?: {
|
|
432
|
+
owner?: string;
|
|
433
|
+
signer?: SpieldSigner;
|
|
434
|
+
}): Promise<TransactionResult | null>;
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
type SrFixedRateQuote = {
|
|
438
|
+
input: TokenAmount;
|
|
439
|
+
payout: TokenAmount;
|
|
440
|
+
coupon: TokenAmount;
|
|
441
|
+
rateBps: number;
|
|
442
|
+
ratePct: number;
|
|
443
|
+
};
|
|
444
|
+
type SrVaultStats = {
|
|
445
|
+
ptInventory: TokenAmount;
|
|
446
|
+
ytInventory: TokenAmount;
|
|
447
|
+
totalLiability: TokenAmount;
|
|
448
|
+
/** USDC banked for open receipts during resumable redemptions. */
|
|
449
|
+
totalCollected: TokenAmount;
|
|
450
|
+
couponCapacity: TokenAmount;
|
|
451
|
+
rateBps: number;
|
|
452
|
+
ratePct: number;
|
|
453
|
+
maturity: number;
|
|
454
|
+
maturityDate: Date;
|
|
455
|
+
openReceipts: number;
|
|
456
|
+
paused: boolean;
|
|
457
|
+
};
|
|
458
|
+
type SrVaultReceipt = {
|
|
459
|
+
receiptId: number;
|
|
460
|
+
owner: string;
|
|
461
|
+
principal: TokenAmount;
|
|
462
|
+
payout: TokenAmount;
|
|
463
|
+
rateBps: number;
|
|
464
|
+
ratePct: number;
|
|
465
|
+
maturity: number;
|
|
466
|
+
maturityDate: Date;
|
|
467
|
+
open: boolean;
|
|
468
|
+
/** USDC already secured for this receipt during an earlier partial redemption. */
|
|
469
|
+
collected: TokenAmount;
|
|
470
|
+
remaining: TokenAmount;
|
|
471
|
+
};
|
|
472
|
+
type SrVaultSurplus = {
|
|
473
|
+
sr: TokenAmount;
|
|
474
|
+
yt: TokenAmount;
|
|
475
|
+
usdc: TokenAmount;
|
|
476
|
+
};
|
|
477
|
+
/** Fixed-rate USDC vault backed by v2 bearer PT inventory. */
|
|
478
|
+
declare class SrVaultClient {
|
|
479
|
+
private readonly network;
|
|
480
|
+
private readonly soroban;
|
|
481
|
+
private readonly signer?;
|
|
482
|
+
constructor(network: SpieldNetworkConfig, soroban: SorobanClient, signer?: SpieldSigner | undefined);
|
|
483
|
+
private get contract();
|
|
484
|
+
quoteFixedRate(input: {
|
|
485
|
+
amount: string | number | bigint;
|
|
486
|
+
}): Promise<SrFixedRateQuote>;
|
|
487
|
+
getStats(): Promise<SrVaultStats>;
|
|
488
|
+
getReceipt(input: {
|
|
489
|
+
receiptId: number;
|
|
490
|
+
}): Promise<SrVaultReceipt | null>;
|
|
491
|
+
getOwnerReceipts(input: {
|
|
492
|
+
owner: string;
|
|
493
|
+
maxScan?: number;
|
|
494
|
+
}): Promise<SrVaultReceipt[]>;
|
|
495
|
+
deposit(input: {
|
|
496
|
+
amount: string | number | bigint;
|
|
497
|
+
signer?: SpieldSigner;
|
|
498
|
+
}): Promise<TransactionResult>;
|
|
499
|
+
redeemReceipt(input: {
|
|
500
|
+
receiptId: number;
|
|
501
|
+
signer?: SpieldSigner;
|
|
502
|
+
}): Promise<TransactionResult>;
|
|
503
|
+
/** Remaining USDC owed before a receipt can close. Falls back to receipt data on the old ABI. */
|
|
504
|
+
getRedeemRemaining(input: {
|
|
505
|
+
receiptId: number;
|
|
506
|
+
}): Promise<TokenAmount>;
|
|
507
|
+
/** Read surplus SR, YT and USDC that the latest vault ABI can release after expiry. */
|
|
508
|
+
getSurplus(): Promise<SrVaultSurplus | null>;
|
|
509
|
+
/** Permissionless keep-alive for a long-dated vault receipt. */
|
|
510
|
+
bumpReceipt(input: {
|
|
511
|
+
receiptId: number;
|
|
512
|
+
signer?: SpieldSigner;
|
|
513
|
+
}): Promise<TransactionResult>;
|
|
514
|
+
/** Permissionless claim and reinvestment of the vault's YT yield. */
|
|
515
|
+
harvest(input?: {
|
|
516
|
+
signer?: SpieldSigner;
|
|
517
|
+
}): Promise<TransactionResult>;
|
|
518
|
+
private assertReceiptId;
|
|
519
|
+
}
|
|
520
|
+
|
|
521
|
+
type UserInterest = {
|
|
522
|
+
index: bigint;
|
|
523
|
+
accrued: TokenAmount;
|
|
524
|
+
withdrawn: TokenAmount;
|
|
525
|
+
};
|
|
526
|
+
type YieldSolvency = {
|
|
527
|
+
held: TokenAmount;
|
|
528
|
+
needed: TokenAmount;
|
|
529
|
+
surplus: TokenAmount;
|
|
530
|
+
solvent: boolean;
|
|
531
|
+
};
|
|
532
|
+
type YieldState = YieldSolvency & {
|
|
533
|
+
totalPy: TokenAmount;
|
|
534
|
+
totalAccrued: TokenAmount;
|
|
535
|
+
pyIndex: bigint;
|
|
536
|
+
yieldFeeBps: number;
|
|
537
|
+
yieldFeePct: number;
|
|
538
|
+
expiry: number;
|
|
539
|
+
expiryDate: Date;
|
|
540
|
+
expired: boolean;
|
|
541
|
+
paused: boolean;
|
|
542
|
+
};
|
|
543
|
+
/** Client for the PT/YT engine. The engine contract itself is the YT token. */
|
|
544
|
+
declare class YieldEngineClient {
|
|
545
|
+
private readonly network;
|
|
546
|
+
private readonly soroban;
|
|
547
|
+
private readonly signer?;
|
|
548
|
+
constructor(network: SpieldNetworkConfig, soroban: SorobanClient, signer?: SpieldSigner | undefined);
|
|
549
|
+
private get contract();
|
|
550
|
+
getYtBalance(input: {
|
|
551
|
+
owner: string;
|
|
552
|
+
}): Promise<TokenAmount>;
|
|
553
|
+
getClaimableInterest(input: {
|
|
554
|
+
owner: string;
|
|
555
|
+
}): Promise<TokenAmount>;
|
|
556
|
+
getInterest(input: {
|
|
557
|
+
owner: string;
|
|
558
|
+
}): Promise<UserInterest>;
|
|
559
|
+
getSolvency(): Promise<YieldSolvency>;
|
|
560
|
+
getState(): Promise<YieldState>;
|
|
561
|
+
mintPy(input: {
|
|
562
|
+
srIn: string | number | bigint;
|
|
563
|
+
receiver?: string;
|
|
564
|
+
signer?: SpieldSigner;
|
|
565
|
+
}): Promise<TransactionResult>;
|
|
566
|
+
redeemPy(input: {
|
|
567
|
+
amount: string | number | bigint;
|
|
568
|
+
receiver?: string;
|
|
569
|
+
signer?: SpieldSigner;
|
|
570
|
+
}): Promise<TransactionResult>;
|
|
571
|
+
claimYield(input?: {
|
|
572
|
+
signer?: SpieldSigner;
|
|
573
|
+
}): Promise<TransactionResult>;
|
|
574
|
+
transferYt(input: {
|
|
575
|
+
to: string;
|
|
576
|
+
amount: string | number | bigint;
|
|
577
|
+
signer?: SpieldSigner;
|
|
578
|
+
}): Promise<TransactionResult>;
|
|
579
|
+
/** Permissionless expiry-index stamp; only succeeds at or after expiry. */
|
|
580
|
+
stampExpiryIndex(input?: {
|
|
581
|
+
signer?: SpieldSigner;
|
|
582
|
+
}): Promise<TransactionResult>;
|
|
583
|
+
/** Keep both a holder's YT balance and interest entries alive. Permissionless on the latest ABI. */
|
|
584
|
+
bumpHolder(input?: {
|
|
585
|
+
owner?: string;
|
|
586
|
+
signer?: SpieldSigner;
|
|
587
|
+
}): Promise<TransactionResult>;
|
|
588
|
+
}
|
|
589
|
+
|
|
590
|
+
type SrPortfolio = {
|
|
591
|
+
owner: string;
|
|
592
|
+
balances: Awaited<ReturnType<SrTokensClient['getBalances']>>;
|
|
593
|
+
srAsUsdc: ReturnType<typeof tokenAmount>;
|
|
594
|
+
claimableYield: ReturnType<typeof tokenAmount>;
|
|
595
|
+
claimableYieldAsUsdc: ReturnType<typeof tokenAmount>;
|
|
596
|
+
interest: UserInterest;
|
|
597
|
+
lpPosition: SrLpPosition;
|
|
598
|
+
fixedReceipts: SrVaultReceipt[];
|
|
599
|
+
hasPtTrustline: boolean;
|
|
600
|
+
};
|
|
601
|
+
declare class SrPortfolioClient {
|
|
602
|
+
private readonly tokens;
|
|
603
|
+
private readonly sr;
|
|
604
|
+
private readonly yieldEngine;
|
|
605
|
+
private readonly market;
|
|
606
|
+
private readonly vault;
|
|
607
|
+
private readonly decimals;
|
|
608
|
+
constructor(tokens: SrTokensClient, sr: StandardizedReturnClient, yieldEngine: YieldEngineClient, market: SrMarketClient, vault: SrVaultClient, decimals: number);
|
|
609
|
+
getPortfolio(input: {
|
|
610
|
+
owner: string;
|
|
611
|
+
maxReceiptScan?: number;
|
|
612
|
+
}): Promise<SrPortfolio>;
|
|
613
|
+
}
|
|
614
|
+
|
|
615
|
+
declare class SrProtocolClient {
|
|
616
|
+
private readonly sr;
|
|
617
|
+
private readonly strategy;
|
|
618
|
+
private readonly yieldEngine;
|
|
619
|
+
private readonly market;
|
|
620
|
+
private readonly vault;
|
|
621
|
+
constructor(sr: StandardizedReturnClient, strategy: BlendStrategyClient, yieldEngine: YieldEngineClient, market: SrMarketClient, vault: SrVaultClient);
|
|
622
|
+
getHealth(): Promise<{
|
|
623
|
+
sr: SrState;
|
|
624
|
+
strategy: BlendStrategyState;
|
|
625
|
+
yieldEngine: YieldSolvency & {
|
|
626
|
+
totalPy: TokenAmount;
|
|
627
|
+
totalAccrued: TokenAmount;
|
|
628
|
+
pyIndex: bigint;
|
|
629
|
+
yieldFeeBps: number;
|
|
630
|
+
yieldFeePct: number;
|
|
631
|
+
expiry: number;
|
|
632
|
+
expiryDate: Date;
|
|
633
|
+
expired: boolean;
|
|
634
|
+
paused: boolean;
|
|
635
|
+
};
|
|
636
|
+
market: SrMarketStats;
|
|
637
|
+
vault: SrVaultStats;
|
|
638
|
+
}>;
|
|
639
|
+
getSolvency(): Promise<YieldSolvency>;
|
|
640
|
+
}
|
|
641
|
+
|
|
642
|
+
declare const DEFAULT_ROUTER_SLIPPAGE_BPS = 100;
|
|
643
|
+
/** One-transaction USDC routes that fit against the deployed Blend-backed stack. */
|
|
644
|
+
declare class SrRouterClient {
|
|
645
|
+
private readonly network;
|
|
646
|
+
private readonly soroban;
|
|
647
|
+
private readonly signer?;
|
|
648
|
+
constructor(network: SpieldNetworkConfig, soroban: SorobanClient, signer?: SpieldSigner | undefined);
|
|
649
|
+
private get contract();
|
|
650
|
+
/**
|
|
651
|
+
* The basis for `minOut`: what the REAL entry point would pay, falling back to the quote.
|
|
652
|
+
*
|
|
653
|
+
* `FINAL_CHECK.md` V2-01 — the market synchronizes SR on every value-moving call, but `quote_*`
|
|
654
|
+
* is a view and cannot. A quote therefore lags, and for a sale it reports MORE than the trade
|
|
655
|
+
* will pay; sizing `minOut` from it can revert the trade on its own slippage bound.
|
|
656
|
+
*
|
|
657
|
+
* Simulation runs the same synchronized code path the submission runs, so its answer is the one
|
|
658
|
+
* that executes. It legitimately returns `null` (unaffordable size, unfillable route, older
|
|
659
|
+
* deployment) — in which case the quote is used exactly as before.
|
|
660
|
+
*/
|
|
661
|
+
private executableBasis;
|
|
662
|
+
private quote;
|
|
663
|
+
quoteBuyPt(input: {
|
|
664
|
+
usdcIn: string | number | bigint;
|
|
665
|
+
}): Promise<TokenAmount>;
|
|
666
|
+
quoteBuyYt(input: {
|
|
667
|
+
ytOut: string | number | bigint;
|
|
668
|
+
}): Promise<TokenAmount>;
|
|
669
|
+
quoteSellPt(input: {
|
|
670
|
+
ptIn: string | number | bigint;
|
|
671
|
+
}): Promise<TokenAmount>;
|
|
672
|
+
quoteSellYt(input: {
|
|
673
|
+
ytIn: string | number | bigint;
|
|
674
|
+
}): Promise<TokenAmount>;
|
|
675
|
+
quoteRedeemPy(input: {
|
|
676
|
+
amount: string | number | bigint;
|
|
677
|
+
}): Promise<TokenAmount>;
|
|
678
|
+
quoteClaimYield(input: {
|
|
679
|
+
owner: string;
|
|
680
|
+
}): Promise<TokenAmount>;
|
|
681
|
+
buyPt(input: {
|
|
682
|
+
usdcIn: string | number | bigint;
|
|
683
|
+
minPtOut?: string | number | bigint;
|
|
684
|
+
slippageBps?: number;
|
|
685
|
+
deadlineLedger?: number;
|
|
686
|
+
signer?: SpieldSigner;
|
|
687
|
+
}): Promise<TransactionResult>;
|
|
688
|
+
sellPt(input: {
|
|
689
|
+
ptIn: string | number | bigint;
|
|
690
|
+
minUsdcOut?: string | number | bigint;
|
|
691
|
+
slippageBps?: number;
|
|
692
|
+
deadlineLedger?: number;
|
|
693
|
+
signer?: SpieldSigner;
|
|
694
|
+
}): Promise<TransactionResult>;
|
|
695
|
+
redeemPy(input: {
|
|
696
|
+
amount: string | number | bigint;
|
|
697
|
+
minUsdcOut?: string | number | bigint;
|
|
698
|
+
slippageBps?: number;
|
|
699
|
+
signer?: SpieldSigner;
|
|
700
|
+
}): Promise<TransactionResult>;
|
|
701
|
+
claimYield(input?: {
|
|
702
|
+
minUsdcOut?: string | number | bigint;
|
|
703
|
+
slippageBps?: number;
|
|
704
|
+
signer?: SpieldSigner;
|
|
705
|
+
}): Promise<TransactionResult>;
|
|
706
|
+
}
|
|
707
|
+
|
|
708
|
+
type TwoStepTransactionResult = {
|
|
709
|
+
first?: TransactionResult;
|
|
710
|
+
second: TransactionResult;
|
|
711
|
+
};
|
|
712
|
+
/**
|
|
713
|
+
* The Spield protocol client. Every namespace targets the SR-based contracts:
|
|
714
|
+
* USDC wraps into SR, SR splits into PT + YT, and PT trades against SR on the market.
|
|
715
|
+
*/
|
|
716
|
+
declare class SpieldClient {
|
|
717
|
+
readonly network: SpieldNetworkConfig;
|
|
718
|
+
/** Wrap USDC into yield-bearing SR shares, and unwrap fully or partially. */
|
|
719
|
+
readonly sr: StandardizedReturnClient;
|
|
720
|
+
/** Blend rate guard, position value, and currently withdrawable liquidity. */
|
|
721
|
+
readonly strategy: BlendStrategyClient;
|
|
722
|
+
/** Mint/redeem PT + YT, read and claim interest, transfer YT. */
|
|
723
|
+
readonly yield: YieldEngineClient;
|
|
724
|
+
/** PT/SR quotes, PT and YT trades, liquidity. */
|
|
725
|
+
readonly market: SrMarketClient;
|
|
726
|
+
/** Fixed-rate quotes, receipts, deposit, redeem, harvest. */
|
|
727
|
+
readonly vault: SrVaultClient;
|
|
728
|
+
/** One-transaction USDC routes for PT, redemption, and yield claims. */
|
|
729
|
+
readonly router: SrRouterClient;
|
|
730
|
+
/** USDC/SR/PT/YT balances and the single required PT trustline. */
|
|
731
|
+
readonly tokens: SrTokensClient;
|
|
732
|
+
/** Wallet-wide balances, interest, LP position, and vault receipts. */
|
|
733
|
+
readonly portfolio: SrPortfolioClient;
|
|
734
|
+
/** Cross-contract health and yield-engine solvency. */
|
|
735
|
+
readonly protocol: SrProtocolClient;
|
|
736
|
+
private readonly signer?;
|
|
737
|
+
constructor(options?: SpieldClientOptions);
|
|
738
|
+
/** All-in USDC cost for an exact YT face amount, using the deployed two-step route. */
|
|
739
|
+
quoteBuyYtFromUsdc(input: {
|
|
740
|
+
ytOut: string | number | bigint;
|
|
741
|
+
}): Promise<TokenAmount>;
|
|
742
|
+
/**
|
|
743
|
+
* Live-safe YT purchase: wrap only the missing SR, then buy YT. The one-call router version exceeds
|
|
744
|
+
* the deployed Blend pool's Soroban budget, so this deliberately uses up to two signatures.
|
|
745
|
+
*/
|
|
746
|
+
buyYtFromUsdc(input: {
|
|
747
|
+
ytOut: string | number | bigint;
|
|
748
|
+
signer?: SpieldSigner;
|
|
749
|
+
onProgress?: (step: 'wrap' | 'buy', index: number, total: number) => void;
|
|
750
|
+
}): Promise<TwoStepTransactionResult>;
|
|
751
|
+
/**
|
|
752
|
+
* Live-safe YT exit: sell to SR, then unwrap the actual proceeds. The combined router route no
|
|
753
|
+
* longer fits the deployed Blend-backed stack after the SR partial-exit/cap upgrade.
|
|
754
|
+
*/
|
|
755
|
+
sellYtToUsdc(input: {
|
|
756
|
+
ytIn: string | number | bigint;
|
|
757
|
+
signer?: SpieldSigner;
|
|
758
|
+
onProgress?: (step: 'sell' | 'unwrap', index: number, total: number) => void;
|
|
759
|
+
}): Promise<TwoStepTransactionResult>;
|
|
760
|
+
}
|
|
761
|
+
|
|
762
|
+
declare class SpieldSdkError extends Error {
|
|
763
|
+
readonly code: string;
|
|
764
|
+
readonly cause?: unknown | undefined;
|
|
765
|
+
constructor(message: string, code: string, cause?: unknown | undefined);
|
|
766
|
+
}
|
|
767
|
+
declare class SpieldValidationError extends SpieldSdkError {
|
|
768
|
+
constructor(message: string, cause?: unknown);
|
|
769
|
+
}
|
|
770
|
+
declare class SpieldSignerError extends SpieldSdkError {
|
|
771
|
+
constructor(message: string, cause?: unknown);
|
|
772
|
+
}
|
|
773
|
+
declare class SpieldRpcError extends SpieldSdkError {
|
|
774
|
+
constructor(message: string, cause?: unknown);
|
|
775
|
+
}
|
|
776
|
+
declare class SpieldContractError extends SpieldSdkError {
|
|
777
|
+
constructor(message: string, cause?: unknown);
|
|
778
|
+
}
|
|
779
|
+
declare class SpieldConfigurationError extends SpieldSdkError {
|
|
780
|
+
constructor(message: string, cause?: unknown);
|
|
781
|
+
}
|
|
782
|
+
|
|
783
|
+
export { BlendStrategyClient, type BlendStrategyRateBound, type BlendStrategyState, type CallOptions, DEFAULT_ROUTER_SLIPPAGE_BPS, FreighterSigner, ManualSigner, type PtTrustlineStatus, SCALAR_12, STELLAR_NETWORK_PASSPHRASES, SpieldClient, type SpieldClientOptions, SpieldConfigurationError, SpieldContractError, type SpieldNetworkConfig, type SpieldNetworkKey, SpieldRpcError, SpieldSdkError, type SpieldSigner, SpieldSignerError, SpieldValidationError, type SrFixedRateQuote, type SrLpPosition, SrMarketClient, type SrMarketQuote, type SrMarketStats, type SrPortfolio, SrPortfolioClient, SrProtocolClient, SrRouterClient, type SrState, type SrTokenKey, SrTokensClient, SrVaultClient, type SrVaultReceipt, type SrVaultStats, type SrVaultSurplus, StandardizedReturnClient, type TokenAmount, type TokenSymbol, type TransactionResult, type TwoStepTransactionResult, type UserInterest, YT_MAX_IN_PAD_BPS, YieldEngineClient, type YieldSolvency, type YieldState, assertNonNegativeAmount, customNetwork, fromBaseUnits, fromScalar12, testnet, toBaseUnits, tokenAmount };
|