@sun-protocol/sun-sdk-psm 0.1.0-beta.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/README.md +26 -0
- package/dist/index.cjs +421 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +95 -0
- package/dist/index.d.ts +95 -0
- package/dist/index.js +385 -0
- package/dist/index.js.map +1 -0
- package/package.json +46 -0
package/README.md
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# @sun-protocol/sun-sdk-psm
|
|
2
|
+
|
|
3
|
+
Runtime-neutral reads, quotes, errors, and transaction action builders for the SUN PSM.
|
|
4
|
+
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @sun-protocol/sun-sdk-psm
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Example
|
|
12
|
+
|
|
13
|
+
```ts
|
|
14
|
+
import { buildPsmInfoRead } from '@sun-protocol/sun-sdk-psm'
|
|
15
|
+
|
|
16
|
+
const read = buildPsmInfoRead({ network: 'mainnet' })
|
|
17
|
+
// Execute `read` with your chain client, then normalize the returned value.
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
Primary exports include PSM read specifications, result normalization, capacity snapshots, pure quote calculations, swap action builders, constants, and error codes.
|
|
21
|
+
|
|
22
|
+
The package currently models the USDT/new-USDD pair on Mainnet and Nile. It does not depend on TronWeb or a wallet and does not sign or broadcast. Use `sun.swap.psm` from `@sun-protocol/sun-sdk-protocols` for complete read, plan, and execute workflows.
|
|
23
|
+
|
|
24
|
+
Requires Node.js 20 or a compatible JavaScript runtime.
|
|
25
|
+
|
|
26
|
+
[Full API documentation](https://github.com/sun-protocol/sun-sdk/blob/main/docs/sdk/api/psm.md)
|
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,421 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/index.ts
|
|
21
|
+
var index_exports = {};
|
|
22
|
+
__export(index_exports, {
|
|
23
|
+
PSM_ERROR_CODES: () => PSM_ERROR_CODES,
|
|
24
|
+
PSM_INFO_ABI: () => PSM_INFO_ABI,
|
|
25
|
+
PSM_USDT_TO_USDD_SCALE: () => PSM_USDT_TO_USDD_SCALE,
|
|
26
|
+
PSM_WAD: () => PSM_WAD,
|
|
27
|
+
buildPsmBuyGemAction: () => buildPsmBuyGemAction,
|
|
28
|
+
buildPsmInfoRead: () => buildPsmInfoRead,
|
|
29
|
+
buildPsmSellGemAction: () => buildPsmSellGemAction,
|
|
30
|
+
createPsmSnapshot: () => createPsmSnapshot,
|
|
31
|
+
normalizePsmInfoResult: () => normalizePsmInfoResult,
|
|
32
|
+
quotePsm: () => quotePsm
|
|
33
|
+
});
|
|
34
|
+
module.exports = __toCommonJS(index_exports);
|
|
35
|
+
|
|
36
|
+
// src/errors.ts
|
|
37
|
+
var PSM_ERROR_CODES = {
|
|
38
|
+
PSM_DISABLED: "PSM_DISABLED",
|
|
39
|
+
PSM_LIMIT_EXCEEDED: "PSM_LIMIT_EXCEEDED"
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
// src/abi.ts
|
|
43
|
+
var PSM_INFO_ABI = {
|
|
44
|
+
type: "function",
|
|
45
|
+
name: "getInfo",
|
|
46
|
+
stateMutability: "view",
|
|
47
|
+
inputs: [{ name: "_psm", type: "address" }],
|
|
48
|
+
outputs: [{ name: "_info", type: "uint256[]" }]
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
// src/reads.ts
|
|
52
|
+
var import_sun_sdk_chains = require("@sun-protocol/sun-sdk-chains");
|
|
53
|
+
var import_sun_sdk_core = require("@sun-protocol/sun-sdk-core");
|
|
54
|
+
var PSM_INFO_FIELDS = [
|
|
55
|
+
"reverseRemainingUsdd",
|
|
56
|
+
"pairSwappedUsdd",
|
|
57
|
+
"totalUsddLimit",
|
|
58
|
+
"pairUsddLimit",
|
|
59
|
+
"psmUsdtBalance",
|
|
60
|
+
"vaultUsddBalance",
|
|
61
|
+
"totalSwappedUsdd",
|
|
62
|
+
"enabled",
|
|
63
|
+
"reverseLimitEnabled",
|
|
64
|
+
"tin",
|
|
65
|
+
"tout"
|
|
66
|
+
];
|
|
67
|
+
var PSM_INFO_RESULT_LENGTH = PSM_INFO_FIELDS.length;
|
|
68
|
+
var ABI_WORD_HEX_LENGTH = 64;
|
|
69
|
+
var DYNAMIC_ARRAY_HEADER_WORDS = 2;
|
|
70
|
+
function contractError(message, context) {
|
|
71
|
+
throw new import_sun_sdk_core.SDKError("SDK_CONTRACT_ERROR", message, context);
|
|
72
|
+
}
|
|
73
|
+
function decodePackedWords(result) {
|
|
74
|
+
const packed = result.startsWith("0x") ? result.slice(2) : result;
|
|
75
|
+
if (!/^[0-9a-fA-F]+$/.test(packed) || packed.length % ABI_WORD_HEX_LENGTH !== 0) {
|
|
76
|
+
return contractError("PSM info result has malformed packed words", { result });
|
|
77
|
+
}
|
|
78
|
+
const words = Array.from({ length: packed.length / ABI_WORD_HEX_LENGTH }, (_, index) => BigInt(`0x${packed.slice(index * ABI_WORD_HEX_LENGTH, (index + 1) * ABI_WORD_HEX_LENGTH)}`).toString());
|
|
79
|
+
if (words.length === PSM_INFO_RESULT_LENGTH) return words;
|
|
80
|
+
if (words.length === PSM_INFO_RESULT_LENGTH + DYNAMIC_ARRAY_HEADER_WORDS && words[0] === "32" && words[1] === String(PSM_INFO_RESULT_LENGTH)) {
|
|
81
|
+
return words.slice(DYNAMIC_ARRAY_HEADER_WORDS);
|
|
82
|
+
}
|
|
83
|
+
return contractError("PSM info result has an unexpected packed word layout", { result });
|
|
84
|
+
}
|
|
85
|
+
function resultValues(result) {
|
|
86
|
+
if (Array.isArray(result)) {
|
|
87
|
+
if (result.length === 1 && Array.isArray(result[0])) return result[0];
|
|
88
|
+
if (result.length === 1 && typeof result[0] === "string") return decodePackedWords(result[0]);
|
|
89
|
+
return result;
|
|
90
|
+
}
|
|
91
|
+
if (typeof result === "string") return decodePackedWords(result);
|
|
92
|
+
if (result && typeof result === "object") {
|
|
93
|
+
const record = result;
|
|
94
|
+
const namedInfo = record._info ?? record.info;
|
|
95
|
+
if (Array.isArray(namedInfo)) return namedInfo;
|
|
96
|
+
if (Array.isArray(record.constant_result) && typeof record.constant_result[0] === "string") {
|
|
97
|
+
return decodePackedWords(record.constant_result[0]);
|
|
98
|
+
}
|
|
99
|
+
if (Array.isArray(record[0])) return record[0];
|
|
100
|
+
return Array.from({ length: PSM_INFO_RESULT_LENGTH }, (_, index) => record[String(index)]);
|
|
101
|
+
}
|
|
102
|
+
return [];
|
|
103
|
+
}
|
|
104
|
+
function toUintString(value) {
|
|
105
|
+
let normalized;
|
|
106
|
+
if (typeof value === "string") {
|
|
107
|
+
normalized = value;
|
|
108
|
+
} else if (typeof value === "number") {
|
|
109
|
+
if (!Number.isSafeInteger(value) || value < 0) {
|
|
110
|
+
return contractError("PSM info value is not a non-negative safe integer", { value });
|
|
111
|
+
}
|
|
112
|
+
normalized = value.toString();
|
|
113
|
+
} else if (typeof value === "bigint") {
|
|
114
|
+
normalized = value.toString();
|
|
115
|
+
} else if (value && typeof value === "object") {
|
|
116
|
+
try {
|
|
117
|
+
const toString = value.toString;
|
|
118
|
+
if (typeof toString !== "function") {
|
|
119
|
+
return contractError("PSM info value is not an unsigned integer", { value });
|
|
120
|
+
}
|
|
121
|
+
const converted = toString.call(value);
|
|
122
|
+
if (typeof converted !== "string") {
|
|
123
|
+
return contractError("PSM info value is not an unsigned integer", { value });
|
|
124
|
+
}
|
|
125
|
+
normalized = converted;
|
|
126
|
+
} catch {
|
|
127
|
+
return contractError("PSM info value is not an unsigned integer", { value });
|
|
128
|
+
}
|
|
129
|
+
} else {
|
|
130
|
+
return contractError("PSM info value is not an unsigned integer", { value });
|
|
131
|
+
}
|
|
132
|
+
if (!/^\d+$/.test(normalized)) {
|
|
133
|
+
return contractError("PSM info value is not an unsigned integer", { value });
|
|
134
|
+
}
|
|
135
|
+
try {
|
|
136
|
+
return BigInt(normalized).toString();
|
|
137
|
+
} catch {
|
|
138
|
+
return contractError("PSM info value is not an unsigned integer", { value });
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
function buildPsmInfoRead(options) {
|
|
142
|
+
const target = (0, import_sun_sdk_core.assertTronAddress)(
|
|
143
|
+
options.infoReader ?? (0, import_sun_sdk_chains.getContractAddress)(options.network, "psmInfoReader"),
|
|
144
|
+
"PSM info reader"
|
|
145
|
+
);
|
|
146
|
+
const psm = (0, import_sun_sdk_core.assertTronAddress)(
|
|
147
|
+
options.psm ?? (0, import_sun_sdk_chains.getContractAddress)(options.network, "psm"),
|
|
148
|
+
"PSM"
|
|
149
|
+
);
|
|
150
|
+
return {
|
|
151
|
+
target,
|
|
152
|
+
functionSelector: "getInfo(address)",
|
|
153
|
+
parameters: [{ type: "address", value: psm }],
|
|
154
|
+
abiFunction: PSM_INFO_ABI,
|
|
155
|
+
outputs: PSM_INFO_ABI.outputs,
|
|
156
|
+
metadata: { protocol: "psm", action: "get-info", network: options.network }
|
|
157
|
+
};
|
|
158
|
+
}
|
|
159
|
+
function normalizePsmInfoResult(result) {
|
|
160
|
+
const values = resultValues(result);
|
|
161
|
+
if (values.length !== PSM_INFO_RESULT_LENGTH) {
|
|
162
|
+
return contractError("PSM info result has an unexpected length", { result });
|
|
163
|
+
}
|
|
164
|
+
const normalized = values.map(toUintString);
|
|
165
|
+
return {
|
|
166
|
+
reverseRemainingUsdd: normalized[0],
|
|
167
|
+
pairSwappedUsdd: normalized[1],
|
|
168
|
+
totalUsddLimit: normalized[2],
|
|
169
|
+
pairUsddLimit: normalized[3],
|
|
170
|
+
psmUsdtBalance: normalized[4],
|
|
171
|
+
vaultUsddBalance: normalized[5],
|
|
172
|
+
totalSwappedUsdd: normalized[6],
|
|
173
|
+
enabled: normalized[7] !== "0",
|
|
174
|
+
reverseLimitEnabled: normalized[8] !== "0",
|
|
175
|
+
tin: normalized[9],
|
|
176
|
+
tout: normalized[10]
|
|
177
|
+
};
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
// src/quote.ts
|
|
181
|
+
var import_sun_sdk_core2 = require("@sun-protocol/sun-sdk-core");
|
|
182
|
+
var PSM_WAD = 10n ** 18n;
|
|
183
|
+
var PSM_USDT_TO_USDD_SCALE = 10n ** 12n;
|
|
184
|
+
var CANONICAL_UINT = /^(0|[1-9]\d*)$/;
|
|
185
|
+
function contractUint(value, field) {
|
|
186
|
+
if (typeof value !== "string" || !CANONICAL_UINT.test(value)) {
|
|
187
|
+
throw new import_sun_sdk_core2.SDKError("SDK_CONTRACT_ERROR", `PSM ${field} is not a canonical unsigned integer`, { field, value });
|
|
188
|
+
}
|
|
189
|
+
try {
|
|
190
|
+
return BigInt(value);
|
|
191
|
+
} catch {
|
|
192
|
+
throw new import_sun_sdk_core2.SDKError("SDK_CONTRACT_ERROR", `PSM ${field} is not an unsigned integer`, { field, value });
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
function inputAmount(value) {
|
|
196
|
+
if (typeof value !== "string" || !CANONICAL_UINT.test(value)) {
|
|
197
|
+
throw new import_sun_sdk_core2.SDKError("SDK_INVALID_ARGUMENT", "specifiedAmount must be a canonical unsigned integer", {
|
|
198
|
+
specifiedAmount: value
|
|
199
|
+
});
|
|
200
|
+
}
|
|
201
|
+
const amount = BigInt(value);
|
|
202
|
+
if (amount === 0n) {
|
|
203
|
+
throw new import_sun_sdk_core2.SDKError("SDK_INVALID_ARGUMENT", "specifiedAmount must be greater than zero", {
|
|
204
|
+
specifiedAmount: value
|
|
205
|
+
});
|
|
206
|
+
}
|
|
207
|
+
return amount;
|
|
208
|
+
}
|
|
209
|
+
function contractBoolean(value, field) {
|
|
210
|
+
if (typeof value !== "boolean") {
|
|
211
|
+
throw new import_sun_sdk_core2.SDKError("SDK_CONTRACT_ERROR", `PSM ${field} is not a boolean`, { field, value });
|
|
212
|
+
}
|
|
213
|
+
return value;
|
|
214
|
+
}
|
|
215
|
+
function validateInfo(info) {
|
|
216
|
+
const numeric = {
|
|
217
|
+
reverseRemainingUsdd: contractUint(info.reverseRemainingUsdd, "reverseRemainingUsdd"),
|
|
218
|
+
pairSwappedUsdd: contractUint(info.pairSwappedUsdd, "pairSwappedUsdd"),
|
|
219
|
+
totalUsddLimit: contractUint(info.totalUsddLimit, "totalUsddLimit"),
|
|
220
|
+
pairUsddLimit: contractUint(info.pairUsddLimit, "pairUsddLimit"),
|
|
221
|
+
psmUsdtBalance: contractUint(info.psmUsdtBalance, "psmUsdtBalance"),
|
|
222
|
+
vaultUsddBalance: contractUint(info.vaultUsddBalance, "vaultUsddBalance"),
|
|
223
|
+
totalSwappedUsdd: contractUint(info.totalSwappedUsdd, "totalSwappedUsdd"),
|
|
224
|
+
tin: contractUint(info.tin, "tin"),
|
|
225
|
+
tout: contractUint(info.tout, "tout")
|
|
226
|
+
};
|
|
227
|
+
if (numeric.tin > PSM_WAD) {
|
|
228
|
+
throw new import_sun_sdk_core2.SDKError("SDK_CONTRACT_ERROR", "PSM tin exceeds WAD", { tin: info.tin });
|
|
229
|
+
}
|
|
230
|
+
return {
|
|
231
|
+
numeric,
|
|
232
|
+
info: {
|
|
233
|
+
reverseRemainingUsdd: numeric.reverseRemainingUsdd.toString(),
|
|
234
|
+
pairSwappedUsdd: numeric.pairSwappedUsdd.toString(),
|
|
235
|
+
totalUsddLimit: numeric.totalUsddLimit.toString(),
|
|
236
|
+
pairUsddLimit: numeric.pairUsddLimit.toString(),
|
|
237
|
+
psmUsdtBalance: numeric.psmUsdtBalance.toString(),
|
|
238
|
+
vaultUsddBalance: numeric.vaultUsddBalance.toString(),
|
|
239
|
+
totalSwappedUsdd: numeric.totalSwappedUsdd.toString(),
|
|
240
|
+
enabled: contractBoolean(info.enabled, "enabled"),
|
|
241
|
+
reverseLimitEnabled: contractBoolean(info.reverseLimitEnabled, "reverseLimitEnabled"),
|
|
242
|
+
tin: numeric.tin.toString(),
|
|
243
|
+
tout: numeric.tout.toString()
|
|
244
|
+
}
|
|
245
|
+
};
|
|
246
|
+
}
|
|
247
|
+
function minimum(...values) {
|
|
248
|
+
return values.reduce((smallest, value) => value < smallest ? value : smallest);
|
|
249
|
+
}
|
|
250
|
+
function nonNegativeDifference(limit, used) {
|
|
251
|
+
return limit > used ? limit - used : 0n;
|
|
252
|
+
}
|
|
253
|
+
function maxSellGem(values) {
|
|
254
|
+
const grossCapacity = minimum(
|
|
255
|
+
nonNegativeDifference(values.totalUsddLimit, values.totalSwappedUsdd),
|
|
256
|
+
nonNegativeDifference(values.pairUsddLimit, values.pairSwappedUsdd),
|
|
257
|
+
values.vaultUsddBalance
|
|
258
|
+
);
|
|
259
|
+
return grossCapacity / PSM_USDT_TO_USDD_SCALE;
|
|
260
|
+
}
|
|
261
|
+
function ceilDiv(numerator, denominator) {
|
|
262
|
+
return (numerator + denominator - 1n) / denominator;
|
|
263
|
+
}
|
|
264
|
+
function sellForGem(gemAmount2, tin) {
|
|
265
|
+
const gem18 = gemAmount2 * PSM_USDT_TO_USDD_SCALE;
|
|
266
|
+
const fee = gem18 * tin / PSM_WAD;
|
|
267
|
+
return { amountIn: gemAmount2, amountOut: gem18 - fee, fee };
|
|
268
|
+
}
|
|
269
|
+
function buyForGem(gemAmount2, tout) {
|
|
270
|
+
const gem18 = gemAmount2 * PSM_USDT_TO_USDD_SCALE;
|
|
271
|
+
const fee = gem18 * tout / PSM_WAD;
|
|
272
|
+
return { amountIn: gem18 + fee, amountOut: gemAmount2, fee };
|
|
273
|
+
}
|
|
274
|
+
function minSellGemForOutput(amountOut, tin) {
|
|
275
|
+
let gemAmount2 = ceilDiv(
|
|
276
|
+
amountOut * PSM_WAD,
|
|
277
|
+
PSM_USDT_TO_USDD_SCALE * (PSM_WAD - tin)
|
|
278
|
+
);
|
|
279
|
+
while (gemAmount2 > 0n && sellForGem(gemAmount2 - 1n, tin).amountOut >= amountOut) {
|
|
280
|
+
gemAmount2 -= 1n;
|
|
281
|
+
}
|
|
282
|
+
while (sellForGem(gemAmount2, tin).amountOut < amountOut) {
|
|
283
|
+
gemAmount2 += 1n;
|
|
284
|
+
}
|
|
285
|
+
return gemAmount2;
|
|
286
|
+
}
|
|
287
|
+
function maxBuyGemForInput(amountIn, tout) {
|
|
288
|
+
let gemAmount2 = amountIn * PSM_WAD / (PSM_USDT_TO_USDD_SCALE * (PSM_WAD + tout));
|
|
289
|
+
while (buyForGem(gemAmount2 + 1n, tout).amountIn <= amountIn) {
|
|
290
|
+
gemAmount2 += 1n;
|
|
291
|
+
}
|
|
292
|
+
while (buyForGem(gemAmount2, tout).amountIn > amountIn) {
|
|
293
|
+
gemAmount2 -= 1n;
|
|
294
|
+
}
|
|
295
|
+
return gemAmount2;
|
|
296
|
+
}
|
|
297
|
+
function createPsmSnapshot(info) {
|
|
298
|
+
const validated = validateInfo(info);
|
|
299
|
+
const values = validated.numeric;
|
|
300
|
+
const sellAvailable = sellForGem(maxSellGem(values), values.tin).amountOut;
|
|
301
|
+
const maxGemByReverseLimit = maxBuyGemForInput(values.reverseRemainingUsdd, values.tout);
|
|
302
|
+
const maxBuyGem = validated.info.reverseLimitEnabled ? minimum(values.psmUsdtBalance, maxGemByReverseLimit) : values.psmUsdtBalance;
|
|
303
|
+
return {
|
|
304
|
+
...validated.info,
|
|
305
|
+
usdtToUsddAvailableAmountOut: sellAvailable.toString(),
|
|
306
|
+
usddToUsdtAvailableAmountOut: maxBuyGem.toString()
|
|
307
|
+
};
|
|
308
|
+
}
|
|
309
|
+
function limitExceeded(direction, requestedAmountOut, availableAmountOut) {
|
|
310
|
+
throw new import_sun_sdk_core2.SDKError(PSM_ERROR_CODES.PSM_LIMIT_EXCEEDED, "PSM output exceeds available capacity", {
|
|
311
|
+
direction,
|
|
312
|
+
requestedAmountOut: requestedAmountOut.toString(),
|
|
313
|
+
availableAmountOut: availableAmountOut.toString()
|
|
314
|
+
});
|
|
315
|
+
}
|
|
316
|
+
function quoteResult(input, specifiedAmount, quote, gemAmount2, feeRate, availableAmountOut) {
|
|
317
|
+
return {
|
|
318
|
+
mode: input.mode,
|
|
319
|
+
direction: input.direction,
|
|
320
|
+
specifiedAmount: specifiedAmount.toString(),
|
|
321
|
+
amountIn: quote.amountIn.toString(),
|
|
322
|
+
amountOut: quote.amountOut.toString(),
|
|
323
|
+
gemAmount: gemAmount2.toString(),
|
|
324
|
+
feeAmount: quote.fee.toString(),
|
|
325
|
+
feeRate: feeRate.toString(),
|
|
326
|
+
availableAmountOut: availableAmountOut.toString()
|
|
327
|
+
};
|
|
328
|
+
}
|
|
329
|
+
function quotePsm(input) {
|
|
330
|
+
if (input.mode !== "exact-in" && input.mode !== "exact-out") {
|
|
331
|
+
throw new import_sun_sdk_core2.SDKError("SDK_INVALID_ARGUMENT", "unsupported PSM quote mode", { mode: input.mode });
|
|
332
|
+
}
|
|
333
|
+
if (input.direction !== "usdt-to-usdd" && input.direction !== "usdd-to-usdt") {
|
|
334
|
+
throw new import_sun_sdk_core2.SDKError("SDK_INVALID_ARGUMENT", "unsupported PSM quote direction", { direction: input.direction });
|
|
335
|
+
}
|
|
336
|
+
const specifiedAmount = inputAmount(input.specifiedAmount);
|
|
337
|
+
const snapshot = validateInfo(input.snapshot);
|
|
338
|
+
const tin = snapshot.numeric.tin;
|
|
339
|
+
const tout = snapshot.numeric.tout;
|
|
340
|
+
const availableAmountOut = contractUint(
|
|
341
|
+
input.direction === "usdt-to-usdd" ? input.snapshot.usdtToUsddAvailableAmountOut : input.snapshot.usddToUsdtAvailableAmountOut,
|
|
342
|
+
input.direction === "usdt-to-usdd" ? "usdtToUsddAvailableAmountOut" : "usddToUsdtAvailableAmountOut"
|
|
343
|
+
);
|
|
344
|
+
if (!snapshot.info.enabled) {
|
|
345
|
+
throw new import_sun_sdk_core2.SDKError(PSM_ERROR_CODES.PSM_DISABLED, "PSM is disabled", {
|
|
346
|
+
direction: input.direction
|
|
347
|
+
});
|
|
348
|
+
}
|
|
349
|
+
if (input.mode === "exact-out" && specifiedAmount > availableAmountOut) {
|
|
350
|
+
return limitExceeded(input.direction, specifiedAmount, availableAmountOut);
|
|
351
|
+
}
|
|
352
|
+
let gemAmount2;
|
|
353
|
+
let quote;
|
|
354
|
+
let feeRate;
|
|
355
|
+
if (input.direction === "usdt-to-usdd") {
|
|
356
|
+
feeRate = tin;
|
|
357
|
+
gemAmount2 = input.mode === "exact-in" ? specifiedAmount : minSellGemForOutput(specifiedAmount, tin);
|
|
358
|
+
quote = sellForGem(gemAmount2, tin);
|
|
359
|
+
} else {
|
|
360
|
+
feeRate = tout;
|
|
361
|
+
gemAmount2 = input.mode === "exact-in" ? maxBuyGemForInput(specifiedAmount, tout) : specifiedAmount;
|
|
362
|
+
quote = buyForGem(gemAmount2, tout);
|
|
363
|
+
}
|
|
364
|
+
if (input.mode === "exact-in" && input.direction === "usdt-to-usdd" && gemAmount2 > maxSellGem(snapshot.numeric)) {
|
|
365
|
+
return limitExceeded(input.direction, quote.amountOut, availableAmountOut);
|
|
366
|
+
}
|
|
367
|
+
if (input.mode === "exact-in" && quote.amountOut > availableAmountOut) {
|
|
368
|
+
return limitExceeded(input.direction, quote.amountOut, availableAmountOut);
|
|
369
|
+
}
|
|
370
|
+
return quoteResult(input, specifiedAmount, quote, gemAmount2, feeRate, availableAmountOut);
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
// src/actions.ts
|
|
374
|
+
var import_sun_sdk_chains2 = require("@sun-protocol/sun-sdk-chains");
|
|
375
|
+
var import_sun_sdk_core3 = require("@sun-protocol/sun-sdk-core");
|
|
376
|
+
var CANONICAL_UINT2 = /^(0|[1-9]\d*)$/;
|
|
377
|
+
function gemAmount(value) {
|
|
378
|
+
if (typeof value !== "string" || !CANONICAL_UINT2.test(value)) {
|
|
379
|
+
throw new import_sun_sdk_core3.SDKError("SDK_INVALID_ARGUMENT", "gemAmount must be a canonical unsigned integer", { gemAmount: value });
|
|
380
|
+
}
|
|
381
|
+
const amount = BigInt(value);
|
|
382
|
+
if (amount === 0n) {
|
|
383
|
+
throw new import_sun_sdk_core3.SDKError("SDK_INVALID_ARGUMENT", "gemAmount must be greater than zero", { gemAmount: value });
|
|
384
|
+
}
|
|
385
|
+
return amount.toString();
|
|
386
|
+
}
|
|
387
|
+
function buildPsmSwapAction(params, method, action) {
|
|
388
|
+
const recipient = (0, import_sun_sdk_core3.assertTronAddress)(params.recipient, "recipient");
|
|
389
|
+
const target = (0, import_sun_sdk_core3.assertTronAddress)(params.psm ?? (0, import_sun_sdk_chains2.getContractAddress)(params.network, "psm"), "psm");
|
|
390
|
+
const amount = gemAmount(params.gemAmount);
|
|
391
|
+
return (0, import_sun_sdk_core3.createContractCallAction)({
|
|
392
|
+
id: params.id ?? `psm-${action}-${params.network}`,
|
|
393
|
+
target,
|
|
394
|
+
functionSelector: `${method}(address,uint256)`,
|
|
395
|
+
parameters: [
|
|
396
|
+
{ type: "address", value: recipient },
|
|
397
|
+
{ type: "uint256", value: amount }
|
|
398
|
+
],
|
|
399
|
+
...params.feeLimit !== void 0 ? { feeLimit: params.feeLimit } : {}
|
|
400
|
+
});
|
|
401
|
+
}
|
|
402
|
+
function buildPsmSellGemAction(params) {
|
|
403
|
+
return buildPsmSwapAction(params, "sellGem", "sell-gem");
|
|
404
|
+
}
|
|
405
|
+
function buildPsmBuyGemAction(params) {
|
|
406
|
+
return buildPsmSwapAction(params, "buyGem", "buy-gem");
|
|
407
|
+
}
|
|
408
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
409
|
+
0 && (module.exports = {
|
|
410
|
+
PSM_ERROR_CODES,
|
|
411
|
+
PSM_INFO_ABI,
|
|
412
|
+
PSM_USDT_TO_USDD_SCALE,
|
|
413
|
+
PSM_WAD,
|
|
414
|
+
buildPsmBuyGemAction,
|
|
415
|
+
buildPsmInfoRead,
|
|
416
|
+
buildPsmSellGemAction,
|
|
417
|
+
createPsmSnapshot,
|
|
418
|
+
normalizePsmInfoResult,
|
|
419
|
+
quotePsm
|
|
420
|
+
});
|
|
421
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/errors.ts","../src/abi.ts","../src/reads.ts","../src/quote.ts","../src/actions.ts"],"sourcesContent":["export * from './types.js'\nexport * from './errors.js'\nexport * from './abi.js'\nexport * from './reads.js'\nexport * from './quote.js'\nexport * from './actions.js'\n","export const PSM_ERROR_CODES = {\n PSM_DISABLED: 'PSM_DISABLED',\n PSM_LIMIT_EXCEEDED: 'PSM_LIMIT_EXCEEDED',\n} as const\n\nexport type PsmErrorCode = typeof PSM_ERROR_CODES[keyof typeof PSM_ERROR_CODES]\n","export const PSM_INFO_ABI = {\n type: 'function',\n name: 'getInfo',\n stateMutability: 'view',\n inputs: [{ name: '_psm', type: 'address' }],\n outputs: [{ name: '_info', type: 'uint256[]' }],\n} as const\n","import { getContractAddress } from '@sun-protocol/sun-sdk-chains'\nimport { SDKError, assertTronAddress } from '@sun-protocol/sun-sdk-core'\nimport { PSM_INFO_ABI } from './abi.js'\nimport type { PsmContractReadSpec, PsmInfo, PsmReadOptions } from './types.js'\n\nconst PSM_INFO_FIELDS = [\n 'reverseRemainingUsdd',\n 'pairSwappedUsdd',\n 'totalUsddLimit',\n 'pairUsddLimit',\n 'psmUsdtBalance',\n 'vaultUsddBalance',\n 'totalSwappedUsdd',\n 'enabled',\n 'reverseLimitEnabled',\n 'tin',\n 'tout',\n] as const\n\nconst PSM_INFO_RESULT_LENGTH = PSM_INFO_FIELDS.length\nconst ABI_WORD_HEX_LENGTH = 64\nconst DYNAMIC_ARRAY_HEADER_WORDS = 2\n\nfunction contractError(message: string, context: Record<string, unknown>): never {\n throw new SDKError('SDK_CONTRACT_ERROR', message, context)\n}\n\nfunction decodePackedWords(result: string): readonly string[] {\n const packed = result.startsWith('0x') ? result.slice(2) : result\n if (!/^[0-9a-fA-F]+$/.test(packed) || packed.length % ABI_WORD_HEX_LENGTH !== 0) {\n return contractError('PSM info result has malformed packed words', { result })\n }\n\n const words = Array.from({ length: packed.length / ABI_WORD_HEX_LENGTH }, (_, index) => (\n BigInt(`0x${packed.slice(index * ABI_WORD_HEX_LENGTH, (index + 1) * ABI_WORD_HEX_LENGTH)}`).toString()\n ))\n if (words.length === PSM_INFO_RESULT_LENGTH) return words\n\n if (\n words.length === PSM_INFO_RESULT_LENGTH + DYNAMIC_ARRAY_HEADER_WORDS\n && words[0] === '32'\n && words[1] === String(PSM_INFO_RESULT_LENGTH)\n ) {\n return words.slice(DYNAMIC_ARRAY_HEADER_WORDS)\n }\n\n return contractError('PSM info result has an unexpected packed word layout', { result })\n}\n\nfunction resultValues(result: unknown): readonly unknown[] {\n if (Array.isArray(result)) {\n if (result.length === 1 && Array.isArray(result[0])) return result[0]\n if (result.length === 1 && typeof result[0] === 'string') return decodePackedWords(result[0])\n return result\n }\n if (typeof result === 'string') return decodePackedWords(result)\n if (result && typeof result === 'object') {\n const record = result as Record<string, unknown>\n const namedInfo = record._info ?? record.info\n if (Array.isArray(namedInfo)) return namedInfo\n if (Array.isArray(record.constant_result) && typeof record.constant_result[0] === 'string') {\n return decodePackedWords(record.constant_result[0])\n }\n if (Array.isArray(record[0])) return record[0]\n return Array.from({ length: PSM_INFO_RESULT_LENGTH }, (_, index) => record[String(index)])\n }\n return []\n}\n\nfunction toUintString(value: unknown): string {\n let normalized: string\n if (typeof value === 'string') {\n normalized = value\n } else if (typeof value === 'number') {\n if (!Number.isSafeInteger(value) || value < 0) {\n return contractError('PSM info value is not a non-negative safe integer', { value })\n }\n normalized = value.toString()\n } else if (typeof value === 'bigint') {\n normalized = value.toString()\n } else if (value && typeof value === 'object') {\n try {\n const toString = (value as { toString?: unknown }).toString\n if (typeof toString !== 'function') {\n return contractError('PSM info value is not an unsigned integer', { value })\n }\n const converted = toString.call(value)\n if (typeof converted !== 'string') {\n return contractError('PSM info value is not an unsigned integer', { value })\n }\n normalized = converted\n } catch {\n return contractError('PSM info value is not an unsigned integer', { value })\n }\n } else {\n return contractError('PSM info value is not an unsigned integer', { value })\n }\n\n if (!/^\\d+$/.test(normalized)) {\n return contractError('PSM info value is not an unsigned integer', { value })\n }\n\n try {\n return BigInt(normalized).toString()\n } catch {\n return contractError('PSM info value is not an unsigned integer', { value })\n }\n}\n\nexport function buildPsmInfoRead(options: PsmReadOptions): PsmContractReadSpec {\n const target = assertTronAddress(\n options.infoReader ?? getContractAddress(options.network, 'psmInfoReader'),\n 'PSM info reader',\n )\n const psm = assertTronAddress(\n options.psm ?? getContractAddress(options.network, 'psm'),\n 'PSM',\n )\n return {\n target,\n functionSelector: 'getInfo(address)',\n parameters: [{ type: 'address', value: psm }],\n abiFunction: PSM_INFO_ABI,\n outputs: PSM_INFO_ABI.outputs,\n metadata: { protocol: 'psm', action: 'get-info', network: options.network },\n }\n}\n\nexport function normalizePsmInfoResult(result: unknown): PsmInfo {\n const values = resultValues(result)\n if (values.length !== PSM_INFO_RESULT_LENGTH) {\n return contractError('PSM info result has an unexpected length', { result })\n }\n\n const normalized = values.map(toUintString)\n return {\n reverseRemainingUsdd: normalized[0]!,\n pairSwappedUsdd: normalized[1]!,\n totalUsddLimit: normalized[2]!,\n pairUsddLimit: normalized[3]!,\n psmUsdtBalance: normalized[4]!,\n vaultUsddBalance: normalized[5]!,\n totalSwappedUsdd: normalized[6]!,\n enabled: normalized[7]! !== '0',\n reverseLimitEnabled: normalized[8]! !== '0',\n tin: normalized[9]!,\n tout: normalized[10]!,\n }\n}\n","import { SDKError } from '@sun-protocol/sun-sdk-core'\nimport { PSM_ERROR_CODES } from './errors.js'\nimport type { PsmErrorCode } from './errors.js'\nimport type { PsmInfo, PsmQuote, PsmQuoteInput, PsmSnapshot } from './types.js'\n\nexport const PSM_WAD = 10n ** 18n\nexport const PSM_USDT_TO_USDD_SCALE = 10n ** 12n\n\ninterface PsmNumericInfo {\n readonly reverseRemainingUsdd: bigint\n readonly pairSwappedUsdd: bigint\n readonly totalUsddLimit: bigint\n readonly pairUsddLimit: bigint\n readonly psmUsdtBalance: bigint\n readonly vaultUsddBalance: bigint\n readonly totalSwappedUsdd: bigint\n readonly tin: bigint\n readonly tout: bigint\n}\n\ninterface IntegerQuote {\n readonly amountIn: bigint\n readonly amountOut: bigint\n readonly fee: bigint\n}\n\ninterface ValidatedPsmInfo {\n readonly info: PsmInfo\n readonly numeric: PsmNumericInfo\n}\n\nconst CANONICAL_UINT = /^(0|[1-9]\\d*)$/\n\nfunction contractUint(value: unknown, field: string): bigint {\n if (typeof value !== 'string' || !CANONICAL_UINT.test(value)) {\n throw new SDKError('SDK_CONTRACT_ERROR', `PSM ${field} is not a canonical unsigned integer`, { field, value })\n }\n\n try {\n return BigInt(value)\n } catch {\n throw new SDKError('SDK_CONTRACT_ERROR', `PSM ${field} is not an unsigned integer`, { field, value })\n }\n}\n\nfunction inputAmount(value: unknown): bigint {\n if (typeof value !== 'string' || !CANONICAL_UINT.test(value)) {\n throw new SDKError('SDK_INVALID_ARGUMENT', 'specifiedAmount must be a canonical unsigned integer', {\n specifiedAmount: value,\n })\n }\n\n const amount = BigInt(value)\n if (amount === 0n) {\n throw new SDKError('SDK_INVALID_ARGUMENT', 'specifiedAmount must be greater than zero', {\n specifiedAmount: value,\n })\n }\n return amount\n}\n\nfunction contractBoolean(value: unknown, field: string): boolean {\n if (typeof value !== 'boolean') {\n throw new SDKError('SDK_CONTRACT_ERROR', `PSM ${field} is not a boolean`, { field, value })\n }\n return value\n}\n\nfunction validateInfo(info: PsmInfo): ValidatedPsmInfo {\n const numeric = {\n reverseRemainingUsdd: contractUint(info.reverseRemainingUsdd, 'reverseRemainingUsdd'),\n pairSwappedUsdd: contractUint(info.pairSwappedUsdd, 'pairSwappedUsdd'),\n totalUsddLimit: contractUint(info.totalUsddLimit, 'totalUsddLimit'),\n pairUsddLimit: contractUint(info.pairUsddLimit, 'pairUsddLimit'),\n psmUsdtBalance: contractUint(info.psmUsdtBalance, 'psmUsdtBalance'),\n vaultUsddBalance: contractUint(info.vaultUsddBalance, 'vaultUsddBalance'),\n totalSwappedUsdd: contractUint(info.totalSwappedUsdd, 'totalSwappedUsdd'),\n tin: contractUint(info.tin, 'tin'),\n tout: contractUint(info.tout, 'tout'),\n }\n\n if (numeric.tin > PSM_WAD) {\n throw new SDKError('SDK_CONTRACT_ERROR', 'PSM tin exceeds WAD', { tin: info.tin })\n }\n\n return {\n numeric,\n info: {\n reverseRemainingUsdd: numeric.reverseRemainingUsdd.toString(),\n pairSwappedUsdd: numeric.pairSwappedUsdd.toString(),\n totalUsddLimit: numeric.totalUsddLimit.toString(),\n pairUsddLimit: numeric.pairUsddLimit.toString(),\n psmUsdtBalance: numeric.psmUsdtBalance.toString(),\n vaultUsddBalance: numeric.vaultUsddBalance.toString(),\n totalSwappedUsdd: numeric.totalSwappedUsdd.toString(),\n enabled: contractBoolean(info.enabled, 'enabled'),\n reverseLimitEnabled: contractBoolean(info.reverseLimitEnabled, 'reverseLimitEnabled'),\n tin: numeric.tin.toString(),\n tout: numeric.tout.toString(),\n },\n }\n}\n\nfunction minimum(...values: readonly bigint[]): bigint {\n return values.reduce((smallest, value) => value < smallest ? value : smallest)\n}\n\nfunction nonNegativeDifference(limit: bigint, used: bigint): bigint {\n return limit > used ? limit - used : 0n\n}\n\nfunction maxSellGem(values: PsmNumericInfo): bigint {\n const grossCapacity = minimum(\n nonNegativeDifference(values.totalUsddLimit, values.totalSwappedUsdd),\n nonNegativeDifference(values.pairUsddLimit, values.pairSwappedUsdd),\n values.vaultUsddBalance,\n )\n return grossCapacity / PSM_USDT_TO_USDD_SCALE\n}\n\nfunction ceilDiv(numerator: bigint, denominator: bigint): bigint {\n return (numerator + denominator - 1n) / denominator\n}\n\nfunction sellForGem(gemAmount: bigint, tin: bigint): IntegerQuote {\n const gem18 = gemAmount * PSM_USDT_TO_USDD_SCALE\n const fee = gem18 * tin / PSM_WAD\n return { amountIn: gemAmount, amountOut: gem18 - fee, fee }\n}\n\nfunction buyForGem(gemAmount: bigint, tout: bigint): IntegerQuote {\n const gem18 = gemAmount * PSM_USDT_TO_USDD_SCALE\n const fee = gem18 * tout / PSM_WAD\n return { amountIn: gem18 + fee, amountOut: gemAmount, fee }\n}\n\nfunction minSellGemForOutput(amountOut: bigint, tin: bigint): bigint {\n let gemAmount = ceilDiv(\n amountOut * PSM_WAD,\n PSM_USDT_TO_USDD_SCALE * (PSM_WAD - tin),\n )\n\n while (gemAmount > 0n && sellForGem(gemAmount - 1n, tin).amountOut >= amountOut) {\n gemAmount -= 1n\n }\n while (sellForGem(gemAmount, tin).amountOut < amountOut) {\n gemAmount += 1n\n }\n return gemAmount\n}\n\nfunction maxBuyGemForInput(amountIn: bigint, tout: bigint): bigint {\n let gemAmount = amountIn * PSM_WAD / (\n PSM_USDT_TO_USDD_SCALE * (PSM_WAD + tout)\n )\n\n while (buyForGem(gemAmount + 1n, tout).amountIn <= amountIn) {\n gemAmount += 1n\n }\n while (buyForGem(gemAmount, tout).amountIn > amountIn) {\n gemAmount -= 1n\n }\n return gemAmount\n}\n\nexport function createPsmSnapshot(info: PsmInfo): PsmSnapshot {\n const validated = validateInfo(info)\n const values = validated.numeric\n const sellAvailable = sellForGem(maxSellGem(values), values.tin).amountOut\n\n const maxGemByReverseLimit = maxBuyGemForInput(values.reverseRemainingUsdd, values.tout)\n const maxBuyGem = validated.info.reverseLimitEnabled\n ? minimum(values.psmUsdtBalance, maxGemByReverseLimit)\n : values.psmUsdtBalance\n\n return {\n ...validated.info,\n usdtToUsddAvailableAmountOut: sellAvailable.toString(),\n usddToUsdtAvailableAmountOut: maxBuyGem.toString(),\n }\n}\n\nfunction limitExceeded(\n direction: PsmQuoteInput['direction'],\n requestedAmountOut: bigint,\n availableAmountOut: bigint,\n): never {\n throw new SDKError<PsmErrorCode>(PSM_ERROR_CODES.PSM_LIMIT_EXCEEDED, 'PSM output exceeds available capacity', {\n direction,\n requestedAmountOut: requestedAmountOut.toString(),\n availableAmountOut: availableAmountOut.toString(),\n })\n}\n\nfunction quoteResult(\n input: PsmQuoteInput,\n specifiedAmount: bigint,\n quote: IntegerQuote,\n gemAmount: bigint,\n feeRate: bigint,\n availableAmountOut: bigint,\n): PsmQuote {\n return {\n mode: input.mode,\n direction: input.direction,\n specifiedAmount: specifiedAmount.toString(),\n amountIn: quote.amountIn.toString(),\n amountOut: quote.amountOut.toString(),\n gemAmount: gemAmount.toString(),\n feeAmount: quote.fee.toString(),\n feeRate: feeRate.toString(),\n availableAmountOut: availableAmountOut.toString(),\n }\n}\n\nexport function quotePsm(input: PsmQuoteInput): PsmQuote {\n if (input.mode !== 'exact-in' && input.mode !== 'exact-out') {\n throw new SDKError('SDK_INVALID_ARGUMENT', 'unsupported PSM quote mode', { mode: input.mode })\n }\n if (input.direction !== 'usdt-to-usdd' && input.direction !== 'usdd-to-usdt') {\n throw new SDKError('SDK_INVALID_ARGUMENT', 'unsupported PSM quote direction', { direction: input.direction })\n }\n\n const specifiedAmount = inputAmount(input.specifiedAmount)\n const snapshot = validateInfo(input.snapshot)\n const tin = snapshot.numeric.tin\n const tout = snapshot.numeric.tout\n const availableAmountOut = contractUint(\n input.direction === 'usdt-to-usdd'\n ? input.snapshot.usdtToUsddAvailableAmountOut\n : input.snapshot.usddToUsdtAvailableAmountOut,\n input.direction === 'usdt-to-usdd'\n ? 'usdtToUsddAvailableAmountOut'\n : 'usddToUsdtAvailableAmountOut',\n )\n\n if (!snapshot.info.enabled) {\n throw new SDKError<PsmErrorCode>(PSM_ERROR_CODES.PSM_DISABLED, 'PSM is disabled', {\n direction: input.direction,\n })\n }\n\n if (input.mode === 'exact-out' && specifiedAmount > availableAmountOut) {\n return limitExceeded(input.direction, specifiedAmount, availableAmountOut)\n }\n\n let gemAmount: bigint\n let quote: IntegerQuote\n let feeRate: bigint\n if (input.direction === 'usdt-to-usdd') {\n feeRate = tin\n gemAmount = input.mode === 'exact-in'\n ? specifiedAmount\n : minSellGemForOutput(specifiedAmount, tin)\n quote = sellForGem(gemAmount, tin)\n } else {\n feeRate = tout\n gemAmount = input.mode === 'exact-in'\n ? maxBuyGemForInput(specifiedAmount, tout)\n : specifiedAmount\n quote = buyForGem(gemAmount, tout)\n }\n\n if (\n input.mode === 'exact-in'\n && input.direction === 'usdt-to-usdd'\n && gemAmount > maxSellGem(snapshot.numeric)\n ) {\n return limitExceeded(input.direction, quote.amountOut, availableAmountOut)\n }\n\n if (input.mode === 'exact-in' && quote.amountOut > availableAmountOut) {\n return limitExceeded(input.direction, quote.amountOut, availableAmountOut)\n }\n\n return quoteResult(input, specifiedAmount, quote, gemAmount, feeRate, availableAmountOut)\n}\n","import { getContractAddress } from '@sun-protocol/sun-sdk-chains'\nimport { SDKError, assertTronAddress, createContractCallAction, type ContractCallAction } from '@sun-protocol/sun-sdk-core'\nimport type { PsmSwapActionOptions } from './types.js'\n\nconst CANONICAL_UINT = /^(0|[1-9]\\d*)$/\n\nfunction gemAmount(value: string): string {\n if (typeof value !== 'string' || !CANONICAL_UINT.test(value)) {\n throw new SDKError('SDK_INVALID_ARGUMENT', 'gemAmount must be a canonical unsigned integer', { gemAmount: value })\n }\n\n const amount = BigInt(value)\n if (amount === 0n) {\n throw new SDKError('SDK_INVALID_ARGUMENT', 'gemAmount must be greater than zero', { gemAmount: value })\n }\n return amount.toString()\n}\n\nfunction buildPsmSwapAction(\n params: PsmSwapActionOptions,\n method: 'sellGem' | 'buyGem',\n action: 'sell-gem' | 'buy-gem',\n): ContractCallAction {\n const recipient = assertTronAddress(params.recipient, 'recipient')\n const target = assertTronAddress(params.psm ?? getContractAddress(params.network, 'psm'), 'psm')\n const amount = gemAmount(params.gemAmount)\n\n return createContractCallAction({\n id: params.id ?? `psm-${action}-${params.network}`,\n target,\n functionSelector: `${method}(address,uint256)`,\n parameters: [\n { type: 'address', value: recipient },\n { type: 'uint256', value: amount },\n ],\n ...(params.feeLimit !== undefined ? { feeLimit: params.feeLimit } : {}),\n })\n}\n\nexport function buildPsmSellGemAction(params: PsmSwapActionOptions): ContractCallAction {\n return buildPsmSwapAction(params, 'sellGem', 'sell-gem')\n}\n\nexport function buildPsmBuyGemAction(params: PsmSwapActionOptions): ContractCallAction {\n return buildPsmSwapAction(params, 'buyGem', 'buy-gem')\n}\n"],"mappings":"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","names":["import_sun_sdk_core","gemAmount","import_sun_sdk_chains","import_sun_sdk_core","CANONICAL_UINT"]}
|
package/dist/index.d.cts
ADDED
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import { TronAddress, ContractParameter, Network, ContractCallAction } from '@sun-protocol/sun-sdk-core';
|
|
2
|
+
|
|
3
|
+
type PsmSwapMode = 'exact-in' | 'exact-out';
|
|
4
|
+
type PsmSwapDirection = 'usdt-to-usdd' | 'usdd-to-usdt';
|
|
5
|
+
interface PsmInfo {
|
|
6
|
+
readonly reverseRemainingUsdd: string;
|
|
7
|
+
readonly pairSwappedUsdd: string;
|
|
8
|
+
readonly totalUsddLimit: string;
|
|
9
|
+
readonly pairUsddLimit: string;
|
|
10
|
+
readonly psmUsdtBalance: string;
|
|
11
|
+
readonly vaultUsddBalance: string;
|
|
12
|
+
readonly totalSwappedUsdd: string;
|
|
13
|
+
readonly enabled: boolean;
|
|
14
|
+
readonly reverseLimitEnabled: boolean;
|
|
15
|
+
readonly tin: string;
|
|
16
|
+
readonly tout: string;
|
|
17
|
+
}
|
|
18
|
+
interface PsmSnapshot extends PsmInfo {
|
|
19
|
+
readonly usdtToUsddAvailableAmountOut: string;
|
|
20
|
+
readonly usddToUsdtAvailableAmountOut: string;
|
|
21
|
+
}
|
|
22
|
+
interface PsmQuoteInput {
|
|
23
|
+
readonly mode: PsmSwapMode;
|
|
24
|
+
readonly direction: PsmSwapDirection;
|
|
25
|
+
readonly specifiedAmount: string;
|
|
26
|
+
readonly snapshot: PsmSnapshot;
|
|
27
|
+
}
|
|
28
|
+
interface PsmQuote {
|
|
29
|
+
readonly mode: PsmSwapMode;
|
|
30
|
+
readonly direction: PsmSwapDirection;
|
|
31
|
+
readonly specifiedAmount: string;
|
|
32
|
+
readonly amountIn: string;
|
|
33
|
+
readonly amountOut: string;
|
|
34
|
+
readonly gemAmount: string;
|
|
35
|
+
readonly feeAmount: string;
|
|
36
|
+
readonly feeRate: string;
|
|
37
|
+
readonly availableAmountOut: string;
|
|
38
|
+
}
|
|
39
|
+
interface PsmContractReadSpec {
|
|
40
|
+
readonly target: TronAddress;
|
|
41
|
+
readonly functionSelector: string;
|
|
42
|
+
readonly parameters: readonly ContractParameter[];
|
|
43
|
+
readonly abiFunction?: unknown;
|
|
44
|
+
readonly outputs: readonly {
|
|
45
|
+
readonly type: string;
|
|
46
|
+
readonly name?: string;
|
|
47
|
+
}[];
|
|
48
|
+
readonly metadata: Record<string, unknown>;
|
|
49
|
+
}
|
|
50
|
+
interface PsmReadOptions {
|
|
51
|
+
readonly network: Network;
|
|
52
|
+
readonly psm?: TronAddress;
|
|
53
|
+
readonly infoReader?: TronAddress;
|
|
54
|
+
}
|
|
55
|
+
interface PsmSwapActionOptions {
|
|
56
|
+
readonly network: Network;
|
|
57
|
+
readonly psm?: TronAddress;
|
|
58
|
+
readonly recipient: TronAddress;
|
|
59
|
+
readonly gemAmount: string;
|
|
60
|
+
readonly feeLimit?: number;
|
|
61
|
+
readonly id?: string;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
declare const PSM_ERROR_CODES: {
|
|
65
|
+
readonly PSM_DISABLED: "PSM_DISABLED";
|
|
66
|
+
readonly PSM_LIMIT_EXCEEDED: "PSM_LIMIT_EXCEEDED";
|
|
67
|
+
};
|
|
68
|
+
type PsmErrorCode = typeof PSM_ERROR_CODES[keyof typeof PSM_ERROR_CODES];
|
|
69
|
+
|
|
70
|
+
declare const PSM_INFO_ABI: {
|
|
71
|
+
readonly type: "function";
|
|
72
|
+
readonly name: "getInfo";
|
|
73
|
+
readonly stateMutability: "view";
|
|
74
|
+
readonly inputs: readonly [{
|
|
75
|
+
readonly name: "_psm";
|
|
76
|
+
readonly type: "address";
|
|
77
|
+
}];
|
|
78
|
+
readonly outputs: readonly [{
|
|
79
|
+
readonly name: "_info";
|
|
80
|
+
readonly type: "uint256[]";
|
|
81
|
+
}];
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
declare function buildPsmInfoRead(options: PsmReadOptions): PsmContractReadSpec;
|
|
85
|
+
declare function normalizePsmInfoResult(result: unknown): PsmInfo;
|
|
86
|
+
|
|
87
|
+
declare const PSM_WAD: bigint;
|
|
88
|
+
declare const PSM_USDT_TO_USDD_SCALE: bigint;
|
|
89
|
+
declare function createPsmSnapshot(info: PsmInfo): PsmSnapshot;
|
|
90
|
+
declare function quotePsm(input: PsmQuoteInput): PsmQuote;
|
|
91
|
+
|
|
92
|
+
declare function buildPsmSellGemAction(params: PsmSwapActionOptions): ContractCallAction;
|
|
93
|
+
declare function buildPsmBuyGemAction(params: PsmSwapActionOptions): ContractCallAction;
|
|
94
|
+
|
|
95
|
+
export { PSM_ERROR_CODES, PSM_INFO_ABI, PSM_USDT_TO_USDD_SCALE, PSM_WAD, type PsmContractReadSpec, type PsmErrorCode, type PsmInfo, type PsmQuote, type PsmQuoteInput, type PsmReadOptions, type PsmSnapshot, type PsmSwapActionOptions, type PsmSwapDirection, type PsmSwapMode, buildPsmBuyGemAction, buildPsmInfoRead, buildPsmSellGemAction, createPsmSnapshot, normalizePsmInfoResult, quotePsm };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import { TronAddress, ContractParameter, Network, ContractCallAction } from '@sun-protocol/sun-sdk-core';
|
|
2
|
+
|
|
3
|
+
type PsmSwapMode = 'exact-in' | 'exact-out';
|
|
4
|
+
type PsmSwapDirection = 'usdt-to-usdd' | 'usdd-to-usdt';
|
|
5
|
+
interface PsmInfo {
|
|
6
|
+
readonly reverseRemainingUsdd: string;
|
|
7
|
+
readonly pairSwappedUsdd: string;
|
|
8
|
+
readonly totalUsddLimit: string;
|
|
9
|
+
readonly pairUsddLimit: string;
|
|
10
|
+
readonly psmUsdtBalance: string;
|
|
11
|
+
readonly vaultUsddBalance: string;
|
|
12
|
+
readonly totalSwappedUsdd: string;
|
|
13
|
+
readonly enabled: boolean;
|
|
14
|
+
readonly reverseLimitEnabled: boolean;
|
|
15
|
+
readonly tin: string;
|
|
16
|
+
readonly tout: string;
|
|
17
|
+
}
|
|
18
|
+
interface PsmSnapshot extends PsmInfo {
|
|
19
|
+
readonly usdtToUsddAvailableAmountOut: string;
|
|
20
|
+
readonly usddToUsdtAvailableAmountOut: string;
|
|
21
|
+
}
|
|
22
|
+
interface PsmQuoteInput {
|
|
23
|
+
readonly mode: PsmSwapMode;
|
|
24
|
+
readonly direction: PsmSwapDirection;
|
|
25
|
+
readonly specifiedAmount: string;
|
|
26
|
+
readonly snapshot: PsmSnapshot;
|
|
27
|
+
}
|
|
28
|
+
interface PsmQuote {
|
|
29
|
+
readonly mode: PsmSwapMode;
|
|
30
|
+
readonly direction: PsmSwapDirection;
|
|
31
|
+
readonly specifiedAmount: string;
|
|
32
|
+
readonly amountIn: string;
|
|
33
|
+
readonly amountOut: string;
|
|
34
|
+
readonly gemAmount: string;
|
|
35
|
+
readonly feeAmount: string;
|
|
36
|
+
readonly feeRate: string;
|
|
37
|
+
readonly availableAmountOut: string;
|
|
38
|
+
}
|
|
39
|
+
interface PsmContractReadSpec {
|
|
40
|
+
readonly target: TronAddress;
|
|
41
|
+
readonly functionSelector: string;
|
|
42
|
+
readonly parameters: readonly ContractParameter[];
|
|
43
|
+
readonly abiFunction?: unknown;
|
|
44
|
+
readonly outputs: readonly {
|
|
45
|
+
readonly type: string;
|
|
46
|
+
readonly name?: string;
|
|
47
|
+
}[];
|
|
48
|
+
readonly metadata: Record<string, unknown>;
|
|
49
|
+
}
|
|
50
|
+
interface PsmReadOptions {
|
|
51
|
+
readonly network: Network;
|
|
52
|
+
readonly psm?: TronAddress;
|
|
53
|
+
readonly infoReader?: TronAddress;
|
|
54
|
+
}
|
|
55
|
+
interface PsmSwapActionOptions {
|
|
56
|
+
readonly network: Network;
|
|
57
|
+
readonly psm?: TronAddress;
|
|
58
|
+
readonly recipient: TronAddress;
|
|
59
|
+
readonly gemAmount: string;
|
|
60
|
+
readonly feeLimit?: number;
|
|
61
|
+
readonly id?: string;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
declare const PSM_ERROR_CODES: {
|
|
65
|
+
readonly PSM_DISABLED: "PSM_DISABLED";
|
|
66
|
+
readonly PSM_LIMIT_EXCEEDED: "PSM_LIMIT_EXCEEDED";
|
|
67
|
+
};
|
|
68
|
+
type PsmErrorCode = typeof PSM_ERROR_CODES[keyof typeof PSM_ERROR_CODES];
|
|
69
|
+
|
|
70
|
+
declare const PSM_INFO_ABI: {
|
|
71
|
+
readonly type: "function";
|
|
72
|
+
readonly name: "getInfo";
|
|
73
|
+
readonly stateMutability: "view";
|
|
74
|
+
readonly inputs: readonly [{
|
|
75
|
+
readonly name: "_psm";
|
|
76
|
+
readonly type: "address";
|
|
77
|
+
}];
|
|
78
|
+
readonly outputs: readonly [{
|
|
79
|
+
readonly name: "_info";
|
|
80
|
+
readonly type: "uint256[]";
|
|
81
|
+
}];
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
declare function buildPsmInfoRead(options: PsmReadOptions): PsmContractReadSpec;
|
|
85
|
+
declare function normalizePsmInfoResult(result: unknown): PsmInfo;
|
|
86
|
+
|
|
87
|
+
declare const PSM_WAD: bigint;
|
|
88
|
+
declare const PSM_USDT_TO_USDD_SCALE: bigint;
|
|
89
|
+
declare function createPsmSnapshot(info: PsmInfo): PsmSnapshot;
|
|
90
|
+
declare function quotePsm(input: PsmQuoteInput): PsmQuote;
|
|
91
|
+
|
|
92
|
+
declare function buildPsmSellGemAction(params: PsmSwapActionOptions): ContractCallAction;
|
|
93
|
+
declare function buildPsmBuyGemAction(params: PsmSwapActionOptions): ContractCallAction;
|
|
94
|
+
|
|
95
|
+
export { PSM_ERROR_CODES, PSM_INFO_ABI, PSM_USDT_TO_USDD_SCALE, PSM_WAD, type PsmContractReadSpec, type PsmErrorCode, type PsmInfo, type PsmQuote, type PsmQuoteInput, type PsmReadOptions, type PsmSnapshot, type PsmSwapActionOptions, type PsmSwapDirection, type PsmSwapMode, buildPsmBuyGemAction, buildPsmInfoRead, buildPsmSellGemAction, createPsmSnapshot, normalizePsmInfoResult, quotePsm };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,385 @@
|
|
|
1
|
+
// src/errors.ts
|
|
2
|
+
var PSM_ERROR_CODES = {
|
|
3
|
+
PSM_DISABLED: "PSM_DISABLED",
|
|
4
|
+
PSM_LIMIT_EXCEEDED: "PSM_LIMIT_EXCEEDED"
|
|
5
|
+
};
|
|
6
|
+
|
|
7
|
+
// src/abi.ts
|
|
8
|
+
var PSM_INFO_ABI = {
|
|
9
|
+
type: "function",
|
|
10
|
+
name: "getInfo",
|
|
11
|
+
stateMutability: "view",
|
|
12
|
+
inputs: [{ name: "_psm", type: "address" }],
|
|
13
|
+
outputs: [{ name: "_info", type: "uint256[]" }]
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
// src/reads.ts
|
|
17
|
+
import { getContractAddress } from "@sun-protocol/sun-sdk-chains";
|
|
18
|
+
import { SDKError, assertTronAddress } from "@sun-protocol/sun-sdk-core";
|
|
19
|
+
var PSM_INFO_FIELDS = [
|
|
20
|
+
"reverseRemainingUsdd",
|
|
21
|
+
"pairSwappedUsdd",
|
|
22
|
+
"totalUsddLimit",
|
|
23
|
+
"pairUsddLimit",
|
|
24
|
+
"psmUsdtBalance",
|
|
25
|
+
"vaultUsddBalance",
|
|
26
|
+
"totalSwappedUsdd",
|
|
27
|
+
"enabled",
|
|
28
|
+
"reverseLimitEnabled",
|
|
29
|
+
"tin",
|
|
30
|
+
"tout"
|
|
31
|
+
];
|
|
32
|
+
var PSM_INFO_RESULT_LENGTH = PSM_INFO_FIELDS.length;
|
|
33
|
+
var ABI_WORD_HEX_LENGTH = 64;
|
|
34
|
+
var DYNAMIC_ARRAY_HEADER_WORDS = 2;
|
|
35
|
+
function contractError(message, context) {
|
|
36
|
+
throw new SDKError("SDK_CONTRACT_ERROR", message, context);
|
|
37
|
+
}
|
|
38
|
+
function decodePackedWords(result) {
|
|
39
|
+
const packed = result.startsWith("0x") ? result.slice(2) : result;
|
|
40
|
+
if (!/^[0-9a-fA-F]+$/.test(packed) || packed.length % ABI_WORD_HEX_LENGTH !== 0) {
|
|
41
|
+
return contractError("PSM info result has malformed packed words", { result });
|
|
42
|
+
}
|
|
43
|
+
const words = Array.from({ length: packed.length / ABI_WORD_HEX_LENGTH }, (_, index) => BigInt(`0x${packed.slice(index * ABI_WORD_HEX_LENGTH, (index + 1) * ABI_WORD_HEX_LENGTH)}`).toString());
|
|
44
|
+
if (words.length === PSM_INFO_RESULT_LENGTH) return words;
|
|
45
|
+
if (words.length === PSM_INFO_RESULT_LENGTH + DYNAMIC_ARRAY_HEADER_WORDS && words[0] === "32" && words[1] === String(PSM_INFO_RESULT_LENGTH)) {
|
|
46
|
+
return words.slice(DYNAMIC_ARRAY_HEADER_WORDS);
|
|
47
|
+
}
|
|
48
|
+
return contractError("PSM info result has an unexpected packed word layout", { result });
|
|
49
|
+
}
|
|
50
|
+
function resultValues(result) {
|
|
51
|
+
if (Array.isArray(result)) {
|
|
52
|
+
if (result.length === 1 && Array.isArray(result[0])) return result[0];
|
|
53
|
+
if (result.length === 1 && typeof result[0] === "string") return decodePackedWords(result[0]);
|
|
54
|
+
return result;
|
|
55
|
+
}
|
|
56
|
+
if (typeof result === "string") return decodePackedWords(result);
|
|
57
|
+
if (result && typeof result === "object") {
|
|
58
|
+
const record = result;
|
|
59
|
+
const namedInfo = record._info ?? record.info;
|
|
60
|
+
if (Array.isArray(namedInfo)) return namedInfo;
|
|
61
|
+
if (Array.isArray(record.constant_result) && typeof record.constant_result[0] === "string") {
|
|
62
|
+
return decodePackedWords(record.constant_result[0]);
|
|
63
|
+
}
|
|
64
|
+
if (Array.isArray(record[0])) return record[0];
|
|
65
|
+
return Array.from({ length: PSM_INFO_RESULT_LENGTH }, (_, index) => record[String(index)]);
|
|
66
|
+
}
|
|
67
|
+
return [];
|
|
68
|
+
}
|
|
69
|
+
function toUintString(value) {
|
|
70
|
+
let normalized;
|
|
71
|
+
if (typeof value === "string") {
|
|
72
|
+
normalized = value;
|
|
73
|
+
} else if (typeof value === "number") {
|
|
74
|
+
if (!Number.isSafeInteger(value) || value < 0) {
|
|
75
|
+
return contractError("PSM info value is not a non-negative safe integer", { value });
|
|
76
|
+
}
|
|
77
|
+
normalized = value.toString();
|
|
78
|
+
} else if (typeof value === "bigint") {
|
|
79
|
+
normalized = value.toString();
|
|
80
|
+
} else if (value && typeof value === "object") {
|
|
81
|
+
try {
|
|
82
|
+
const toString = value.toString;
|
|
83
|
+
if (typeof toString !== "function") {
|
|
84
|
+
return contractError("PSM info value is not an unsigned integer", { value });
|
|
85
|
+
}
|
|
86
|
+
const converted = toString.call(value);
|
|
87
|
+
if (typeof converted !== "string") {
|
|
88
|
+
return contractError("PSM info value is not an unsigned integer", { value });
|
|
89
|
+
}
|
|
90
|
+
normalized = converted;
|
|
91
|
+
} catch {
|
|
92
|
+
return contractError("PSM info value is not an unsigned integer", { value });
|
|
93
|
+
}
|
|
94
|
+
} else {
|
|
95
|
+
return contractError("PSM info value is not an unsigned integer", { value });
|
|
96
|
+
}
|
|
97
|
+
if (!/^\d+$/.test(normalized)) {
|
|
98
|
+
return contractError("PSM info value is not an unsigned integer", { value });
|
|
99
|
+
}
|
|
100
|
+
try {
|
|
101
|
+
return BigInt(normalized).toString();
|
|
102
|
+
} catch {
|
|
103
|
+
return contractError("PSM info value is not an unsigned integer", { value });
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
function buildPsmInfoRead(options) {
|
|
107
|
+
const target = assertTronAddress(
|
|
108
|
+
options.infoReader ?? getContractAddress(options.network, "psmInfoReader"),
|
|
109
|
+
"PSM info reader"
|
|
110
|
+
);
|
|
111
|
+
const psm = assertTronAddress(
|
|
112
|
+
options.psm ?? getContractAddress(options.network, "psm"),
|
|
113
|
+
"PSM"
|
|
114
|
+
);
|
|
115
|
+
return {
|
|
116
|
+
target,
|
|
117
|
+
functionSelector: "getInfo(address)",
|
|
118
|
+
parameters: [{ type: "address", value: psm }],
|
|
119
|
+
abiFunction: PSM_INFO_ABI,
|
|
120
|
+
outputs: PSM_INFO_ABI.outputs,
|
|
121
|
+
metadata: { protocol: "psm", action: "get-info", network: options.network }
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
function normalizePsmInfoResult(result) {
|
|
125
|
+
const values = resultValues(result);
|
|
126
|
+
if (values.length !== PSM_INFO_RESULT_LENGTH) {
|
|
127
|
+
return contractError("PSM info result has an unexpected length", { result });
|
|
128
|
+
}
|
|
129
|
+
const normalized = values.map(toUintString);
|
|
130
|
+
return {
|
|
131
|
+
reverseRemainingUsdd: normalized[0],
|
|
132
|
+
pairSwappedUsdd: normalized[1],
|
|
133
|
+
totalUsddLimit: normalized[2],
|
|
134
|
+
pairUsddLimit: normalized[3],
|
|
135
|
+
psmUsdtBalance: normalized[4],
|
|
136
|
+
vaultUsddBalance: normalized[5],
|
|
137
|
+
totalSwappedUsdd: normalized[6],
|
|
138
|
+
enabled: normalized[7] !== "0",
|
|
139
|
+
reverseLimitEnabled: normalized[8] !== "0",
|
|
140
|
+
tin: normalized[9],
|
|
141
|
+
tout: normalized[10]
|
|
142
|
+
};
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
// src/quote.ts
|
|
146
|
+
import { SDKError as SDKError2 } from "@sun-protocol/sun-sdk-core";
|
|
147
|
+
var PSM_WAD = 10n ** 18n;
|
|
148
|
+
var PSM_USDT_TO_USDD_SCALE = 10n ** 12n;
|
|
149
|
+
var CANONICAL_UINT = /^(0|[1-9]\d*)$/;
|
|
150
|
+
function contractUint(value, field) {
|
|
151
|
+
if (typeof value !== "string" || !CANONICAL_UINT.test(value)) {
|
|
152
|
+
throw new SDKError2("SDK_CONTRACT_ERROR", `PSM ${field} is not a canonical unsigned integer`, { field, value });
|
|
153
|
+
}
|
|
154
|
+
try {
|
|
155
|
+
return BigInt(value);
|
|
156
|
+
} catch {
|
|
157
|
+
throw new SDKError2("SDK_CONTRACT_ERROR", `PSM ${field} is not an unsigned integer`, { field, value });
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
function inputAmount(value) {
|
|
161
|
+
if (typeof value !== "string" || !CANONICAL_UINT.test(value)) {
|
|
162
|
+
throw new SDKError2("SDK_INVALID_ARGUMENT", "specifiedAmount must be a canonical unsigned integer", {
|
|
163
|
+
specifiedAmount: value
|
|
164
|
+
});
|
|
165
|
+
}
|
|
166
|
+
const amount = BigInt(value);
|
|
167
|
+
if (amount === 0n) {
|
|
168
|
+
throw new SDKError2("SDK_INVALID_ARGUMENT", "specifiedAmount must be greater than zero", {
|
|
169
|
+
specifiedAmount: value
|
|
170
|
+
});
|
|
171
|
+
}
|
|
172
|
+
return amount;
|
|
173
|
+
}
|
|
174
|
+
function contractBoolean(value, field) {
|
|
175
|
+
if (typeof value !== "boolean") {
|
|
176
|
+
throw new SDKError2("SDK_CONTRACT_ERROR", `PSM ${field} is not a boolean`, { field, value });
|
|
177
|
+
}
|
|
178
|
+
return value;
|
|
179
|
+
}
|
|
180
|
+
function validateInfo(info) {
|
|
181
|
+
const numeric = {
|
|
182
|
+
reverseRemainingUsdd: contractUint(info.reverseRemainingUsdd, "reverseRemainingUsdd"),
|
|
183
|
+
pairSwappedUsdd: contractUint(info.pairSwappedUsdd, "pairSwappedUsdd"),
|
|
184
|
+
totalUsddLimit: contractUint(info.totalUsddLimit, "totalUsddLimit"),
|
|
185
|
+
pairUsddLimit: contractUint(info.pairUsddLimit, "pairUsddLimit"),
|
|
186
|
+
psmUsdtBalance: contractUint(info.psmUsdtBalance, "psmUsdtBalance"),
|
|
187
|
+
vaultUsddBalance: contractUint(info.vaultUsddBalance, "vaultUsddBalance"),
|
|
188
|
+
totalSwappedUsdd: contractUint(info.totalSwappedUsdd, "totalSwappedUsdd"),
|
|
189
|
+
tin: contractUint(info.tin, "tin"),
|
|
190
|
+
tout: contractUint(info.tout, "tout")
|
|
191
|
+
};
|
|
192
|
+
if (numeric.tin > PSM_WAD) {
|
|
193
|
+
throw new SDKError2("SDK_CONTRACT_ERROR", "PSM tin exceeds WAD", { tin: info.tin });
|
|
194
|
+
}
|
|
195
|
+
return {
|
|
196
|
+
numeric,
|
|
197
|
+
info: {
|
|
198
|
+
reverseRemainingUsdd: numeric.reverseRemainingUsdd.toString(),
|
|
199
|
+
pairSwappedUsdd: numeric.pairSwappedUsdd.toString(),
|
|
200
|
+
totalUsddLimit: numeric.totalUsddLimit.toString(),
|
|
201
|
+
pairUsddLimit: numeric.pairUsddLimit.toString(),
|
|
202
|
+
psmUsdtBalance: numeric.psmUsdtBalance.toString(),
|
|
203
|
+
vaultUsddBalance: numeric.vaultUsddBalance.toString(),
|
|
204
|
+
totalSwappedUsdd: numeric.totalSwappedUsdd.toString(),
|
|
205
|
+
enabled: contractBoolean(info.enabled, "enabled"),
|
|
206
|
+
reverseLimitEnabled: contractBoolean(info.reverseLimitEnabled, "reverseLimitEnabled"),
|
|
207
|
+
tin: numeric.tin.toString(),
|
|
208
|
+
tout: numeric.tout.toString()
|
|
209
|
+
}
|
|
210
|
+
};
|
|
211
|
+
}
|
|
212
|
+
function minimum(...values) {
|
|
213
|
+
return values.reduce((smallest, value) => value < smallest ? value : smallest);
|
|
214
|
+
}
|
|
215
|
+
function nonNegativeDifference(limit, used) {
|
|
216
|
+
return limit > used ? limit - used : 0n;
|
|
217
|
+
}
|
|
218
|
+
function maxSellGem(values) {
|
|
219
|
+
const grossCapacity = minimum(
|
|
220
|
+
nonNegativeDifference(values.totalUsddLimit, values.totalSwappedUsdd),
|
|
221
|
+
nonNegativeDifference(values.pairUsddLimit, values.pairSwappedUsdd),
|
|
222
|
+
values.vaultUsddBalance
|
|
223
|
+
);
|
|
224
|
+
return grossCapacity / PSM_USDT_TO_USDD_SCALE;
|
|
225
|
+
}
|
|
226
|
+
function ceilDiv(numerator, denominator) {
|
|
227
|
+
return (numerator + denominator - 1n) / denominator;
|
|
228
|
+
}
|
|
229
|
+
function sellForGem(gemAmount2, tin) {
|
|
230
|
+
const gem18 = gemAmount2 * PSM_USDT_TO_USDD_SCALE;
|
|
231
|
+
const fee = gem18 * tin / PSM_WAD;
|
|
232
|
+
return { amountIn: gemAmount2, amountOut: gem18 - fee, fee };
|
|
233
|
+
}
|
|
234
|
+
function buyForGem(gemAmount2, tout) {
|
|
235
|
+
const gem18 = gemAmount2 * PSM_USDT_TO_USDD_SCALE;
|
|
236
|
+
const fee = gem18 * tout / PSM_WAD;
|
|
237
|
+
return { amountIn: gem18 + fee, amountOut: gemAmount2, fee };
|
|
238
|
+
}
|
|
239
|
+
function minSellGemForOutput(amountOut, tin) {
|
|
240
|
+
let gemAmount2 = ceilDiv(
|
|
241
|
+
amountOut * PSM_WAD,
|
|
242
|
+
PSM_USDT_TO_USDD_SCALE * (PSM_WAD - tin)
|
|
243
|
+
);
|
|
244
|
+
while (gemAmount2 > 0n && sellForGem(gemAmount2 - 1n, tin).amountOut >= amountOut) {
|
|
245
|
+
gemAmount2 -= 1n;
|
|
246
|
+
}
|
|
247
|
+
while (sellForGem(gemAmount2, tin).amountOut < amountOut) {
|
|
248
|
+
gemAmount2 += 1n;
|
|
249
|
+
}
|
|
250
|
+
return gemAmount2;
|
|
251
|
+
}
|
|
252
|
+
function maxBuyGemForInput(amountIn, tout) {
|
|
253
|
+
let gemAmount2 = amountIn * PSM_WAD / (PSM_USDT_TO_USDD_SCALE * (PSM_WAD + tout));
|
|
254
|
+
while (buyForGem(gemAmount2 + 1n, tout).amountIn <= amountIn) {
|
|
255
|
+
gemAmount2 += 1n;
|
|
256
|
+
}
|
|
257
|
+
while (buyForGem(gemAmount2, tout).amountIn > amountIn) {
|
|
258
|
+
gemAmount2 -= 1n;
|
|
259
|
+
}
|
|
260
|
+
return gemAmount2;
|
|
261
|
+
}
|
|
262
|
+
function createPsmSnapshot(info) {
|
|
263
|
+
const validated = validateInfo(info);
|
|
264
|
+
const values = validated.numeric;
|
|
265
|
+
const sellAvailable = sellForGem(maxSellGem(values), values.tin).amountOut;
|
|
266
|
+
const maxGemByReverseLimit = maxBuyGemForInput(values.reverseRemainingUsdd, values.tout);
|
|
267
|
+
const maxBuyGem = validated.info.reverseLimitEnabled ? minimum(values.psmUsdtBalance, maxGemByReverseLimit) : values.psmUsdtBalance;
|
|
268
|
+
return {
|
|
269
|
+
...validated.info,
|
|
270
|
+
usdtToUsddAvailableAmountOut: sellAvailable.toString(),
|
|
271
|
+
usddToUsdtAvailableAmountOut: maxBuyGem.toString()
|
|
272
|
+
};
|
|
273
|
+
}
|
|
274
|
+
function limitExceeded(direction, requestedAmountOut, availableAmountOut) {
|
|
275
|
+
throw new SDKError2(PSM_ERROR_CODES.PSM_LIMIT_EXCEEDED, "PSM output exceeds available capacity", {
|
|
276
|
+
direction,
|
|
277
|
+
requestedAmountOut: requestedAmountOut.toString(),
|
|
278
|
+
availableAmountOut: availableAmountOut.toString()
|
|
279
|
+
});
|
|
280
|
+
}
|
|
281
|
+
function quoteResult(input, specifiedAmount, quote, gemAmount2, feeRate, availableAmountOut) {
|
|
282
|
+
return {
|
|
283
|
+
mode: input.mode,
|
|
284
|
+
direction: input.direction,
|
|
285
|
+
specifiedAmount: specifiedAmount.toString(),
|
|
286
|
+
amountIn: quote.amountIn.toString(),
|
|
287
|
+
amountOut: quote.amountOut.toString(),
|
|
288
|
+
gemAmount: gemAmount2.toString(),
|
|
289
|
+
feeAmount: quote.fee.toString(),
|
|
290
|
+
feeRate: feeRate.toString(),
|
|
291
|
+
availableAmountOut: availableAmountOut.toString()
|
|
292
|
+
};
|
|
293
|
+
}
|
|
294
|
+
function quotePsm(input) {
|
|
295
|
+
if (input.mode !== "exact-in" && input.mode !== "exact-out") {
|
|
296
|
+
throw new SDKError2("SDK_INVALID_ARGUMENT", "unsupported PSM quote mode", { mode: input.mode });
|
|
297
|
+
}
|
|
298
|
+
if (input.direction !== "usdt-to-usdd" && input.direction !== "usdd-to-usdt") {
|
|
299
|
+
throw new SDKError2("SDK_INVALID_ARGUMENT", "unsupported PSM quote direction", { direction: input.direction });
|
|
300
|
+
}
|
|
301
|
+
const specifiedAmount = inputAmount(input.specifiedAmount);
|
|
302
|
+
const snapshot = validateInfo(input.snapshot);
|
|
303
|
+
const tin = snapshot.numeric.tin;
|
|
304
|
+
const tout = snapshot.numeric.tout;
|
|
305
|
+
const availableAmountOut = contractUint(
|
|
306
|
+
input.direction === "usdt-to-usdd" ? input.snapshot.usdtToUsddAvailableAmountOut : input.snapshot.usddToUsdtAvailableAmountOut,
|
|
307
|
+
input.direction === "usdt-to-usdd" ? "usdtToUsddAvailableAmountOut" : "usddToUsdtAvailableAmountOut"
|
|
308
|
+
);
|
|
309
|
+
if (!snapshot.info.enabled) {
|
|
310
|
+
throw new SDKError2(PSM_ERROR_CODES.PSM_DISABLED, "PSM is disabled", {
|
|
311
|
+
direction: input.direction
|
|
312
|
+
});
|
|
313
|
+
}
|
|
314
|
+
if (input.mode === "exact-out" && specifiedAmount > availableAmountOut) {
|
|
315
|
+
return limitExceeded(input.direction, specifiedAmount, availableAmountOut);
|
|
316
|
+
}
|
|
317
|
+
let gemAmount2;
|
|
318
|
+
let quote;
|
|
319
|
+
let feeRate;
|
|
320
|
+
if (input.direction === "usdt-to-usdd") {
|
|
321
|
+
feeRate = tin;
|
|
322
|
+
gemAmount2 = input.mode === "exact-in" ? specifiedAmount : minSellGemForOutput(specifiedAmount, tin);
|
|
323
|
+
quote = sellForGem(gemAmount2, tin);
|
|
324
|
+
} else {
|
|
325
|
+
feeRate = tout;
|
|
326
|
+
gemAmount2 = input.mode === "exact-in" ? maxBuyGemForInput(specifiedAmount, tout) : specifiedAmount;
|
|
327
|
+
quote = buyForGem(gemAmount2, tout);
|
|
328
|
+
}
|
|
329
|
+
if (input.mode === "exact-in" && input.direction === "usdt-to-usdd" && gemAmount2 > maxSellGem(snapshot.numeric)) {
|
|
330
|
+
return limitExceeded(input.direction, quote.amountOut, availableAmountOut);
|
|
331
|
+
}
|
|
332
|
+
if (input.mode === "exact-in" && quote.amountOut > availableAmountOut) {
|
|
333
|
+
return limitExceeded(input.direction, quote.amountOut, availableAmountOut);
|
|
334
|
+
}
|
|
335
|
+
return quoteResult(input, specifiedAmount, quote, gemAmount2, feeRate, availableAmountOut);
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
// src/actions.ts
|
|
339
|
+
import { getContractAddress as getContractAddress2 } from "@sun-protocol/sun-sdk-chains";
|
|
340
|
+
import { SDKError as SDKError3, assertTronAddress as assertTronAddress2, createContractCallAction } from "@sun-protocol/sun-sdk-core";
|
|
341
|
+
var CANONICAL_UINT2 = /^(0|[1-9]\d*)$/;
|
|
342
|
+
function gemAmount(value) {
|
|
343
|
+
if (typeof value !== "string" || !CANONICAL_UINT2.test(value)) {
|
|
344
|
+
throw new SDKError3("SDK_INVALID_ARGUMENT", "gemAmount must be a canonical unsigned integer", { gemAmount: value });
|
|
345
|
+
}
|
|
346
|
+
const amount = BigInt(value);
|
|
347
|
+
if (amount === 0n) {
|
|
348
|
+
throw new SDKError3("SDK_INVALID_ARGUMENT", "gemAmount must be greater than zero", { gemAmount: value });
|
|
349
|
+
}
|
|
350
|
+
return amount.toString();
|
|
351
|
+
}
|
|
352
|
+
function buildPsmSwapAction(params, method, action) {
|
|
353
|
+
const recipient = assertTronAddress2(params.recipient, "recipient");
|
|
354
|
+
const target = assertTronAddress2(params.psm ?? getContractAddress2(params.network, "psm"), "psm");
|
|
355
|
+
const amount = gemAmount(params.gemAmount);
|
|
356
|
+
return createContractCallAction({
|
|
357
|
+
id: params.id ?? `psm-${action}-${params.network}`,
|
|
358
|
+
target,
|
|
359
|
+
functionSelector: `${method}(address,uint256)`,
|
|
360
|
+
parameters: [
|
|
361
|
+
{ type: "address", value: recipient },
|
|
362
|
+
{ type: "uint256", value: amount }
|
|
363
|
+
],
|
|
364
|
+
...params.feeLimit !== void 0 ? { feeLimit: params.feeLimit } : {}
|
|
365
|
+
});
|
|
366
|
+
}
|
|
367
|
+
function buildPsmSellGemAction(params) {
|
|
368
|
+
return buildPsmSwapAction(params, "sellGem", "sell-gem");
|
|
369
|
+
}
|
|
370
|
+
function buildPsmBuyGemAction(params) {
|
|
371
|
+
return buildPsmSwapAction(params, "buyGem", "buy-gem");
|
|
372
|
+
}
|
|
373
|
+
export {
|
|
374
|
+
PSM_ERROR_CODES,
|
|
375
|
+
PSM_INFO_ABI,
|
|
376
|
+
PSM_USDT_TO_USDD_SCALE,
|
|
377
|
+
PSM_WAD,
|
|
378
|
+
buildPsmBuyGemAction,
|
|
379
|
+
buildPsmInfoRead,
|
|
380
|
+
buildPsmSellGemAction,
|
|
381
|
+
createPsmSnapshot,
|
|
382
|
+
normalizePsmInfoResult,
|
|
383
|
+
quotePsm
|
|
384
|
+
};
|
|
385
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/errors.ts","../src/abi.ts","../src/reads.ts","../src/quote.ts","../src/actions.ts"],"sourcesContent":["export const PSM_ERROR_CODES = {\n PSM_DISABLED: 'PSM_DISABLED',\n PSM_LIMIT_EXCEEDED: 'PSM_LIMIT_EXCEEDED',\n} as const\n\nexport type PsmErrorCode = typeof PSM_ERROR_CODES[keyof typeof PSM_ERROR_CODES]\n","export const PSM_INFO_ABI = {\n type: 'function',\n name: 'getInfo',\n stateMutability: 'view',\n inputs: [{ name: '_psm', type: 'address' }],\n outputs: [{ name: '_info', type: 'uint256[]' }],\n} as const\n","import { getContractAddress } from '@sun-protocol/sun-sdk-chains'\nimport { SDKError, assertTronAddress } from '@sun-protocol/sun-sdk-core'\nimport { PSM_INFO_ABI } from './abi.js'\nimport type { PsmContractReadSpec, PsmInfo, PsmReadOptions } from './types.js'\n\nconst PSM_INFO_FIELDS = [\n 'reverseRemainingUsdd',\n 'pairSwappedUsdd',\n 'totalUsddLimit',\n 'pairUsddLimit',\n 'psmUsdtBalance',\n 'vaultUsddBalance',\n 'totalSwappedUsdd',\n 'enabled',\n 'reverseLimitEnabled',\n 'tin',\n 'tout',\n] as const\n\nconst PSM_INFO_RESULT_LENGTH = PSM_INFO_FIELDS.length\nconst ABI_WORD_HEX_LENGTH = 64\nconst DYNAMIC_ARRAY_HEADER_WORDS = 2\n\nfunction contractError(message: string, context: Record<string, unknown>): never {\n throw new SDKError('SDK_CONTRACT_ERROR', message, context)\n}\n\nfunction decodePackedWords(result: string): readonly string[] {\n const packed = result.startsWith('0x') ? result.slice(2) : result\n if (!/^[0-9a-fA-F]+$/.test(packed) || packed.length % ABI_WORD_HEX_LENGTH !== 0) {\n return contractError('PSM info result has malformed packed words', { result })\n }\n\n const words = Array.from({ length: packed.length / ABI_WORD_HEX_LENGTH }, (_, index) => (\n BigInt(`0x${packed.slice(index * ABI_WORD_HEX_LENGTH, (index + 1) * ABI_WORD_HEX_LENGTH)}`).toString()\n ))\n if (words.length === PSM_INFO_RESULT_LENGTH) return words\n\n if (\n words.length === PSM_INFO_RESULT_LENGTH + DYNAMIC_ARRAY_HEADER_WORDS\n && words[0] === '32'\n && words[1] === String(PSM_INFO_RESULT_LENGTH)\n ) {\n return words.slice(DYNAMIC_ARRAY_HEADER_WORDS)\n }\n\n return contractError('PSM info result has an unexpected packed word layout', { result })\n}\n\nfunction resultValues(result: unknown): readonly unknown[] {\n if (Array.isArray(result)) {\n if (result.length === 1 && Array.isArray(result[0])) return result[0]\n if (result.length === 1 && typeof result[0] === 'string') return decodePackedWords(result[0])\n return result\n }\n if (typeof result === 'string') return decodePackedWords(result)\n if (result && typeof result === 'object') {\n const record = result as Record<string, unknown>\n const namedInfo = record._info ?? record.info\n if (Array.isArray(namedInfo)) return namedInfo\n if (Array.isArray(record.constant_result) && typeof record.constant_result[0] === 'string') {\n return decodePackedWords(record.constant_result[0])\n }\n if (Array.isArray(record[0])) return record[0]\n return Array.from({ length: PSM_INFO_RESULT_LENGTH }, (_, index) => record[String(index)])\n }\n return []\n}\n\nfunction toUintString(value: unknown): string {\n let normalized: string\n if (typeof value === 'string') {\n normalized = value\n } else if (typeof value === 'number') {\n if (!Number.isSafeInteger(value) || value < 0) {\n return contractError('PSM info value is not a non-negative safe integer', { value })\n }\n normalized = value.toString()\n } else if (typeof value === 'bigint') {\n normalized = value.toString()\n } else if (value && typeof value === 'object') {\n try {\n const toString = (value as { toString?: unknown }).toString\n if (typeof toString !== 'function') {\n return contractError('PSM info value is not an unsigned integer', { value })\n }\n const converted = toString.call(value)\n if (typeof converted !== 'string') {\n return contractError('PSM info value is not an unsigned integer', { value })\n }\n normalized = converted\n } catch {\n return contractError('PSM info value is not an unsigned integer', { value })\n }\n } else {\n return contractError('PSM info value is not an unsigned integer', { value })\n }\n\n if (!/^\\d+$/.test(normalized)) {\n return contractError('PSM info value is not an unsigned integer', { value })\n }\n\n try {\n return BigInt(normalized).toString()\n } catch {\n return contractError('PSM info value is not an unsigned integer', { value })\n }\n}\n\nexport function buildPsmInfoRead(options: PsmReadOptions): PsmContractReadSpec {\n const target = assertTronAddress(\n options.infoReader ?? getContractAddress(options.network, 'psmInfoReader'),\n 'PSM info reader',\n )\n const psm = assertTronAddress(\n options.psm ?? getContractAddress(options.network, 'psm'),\n 'PSM',\n )\n return {\n target,\n functionSelector: 'getInfo(address)',\n parameters: [{ type: 'address', value: psm }],\n abiFunction: PSM_INFO_ABI,\n outputs: PSM_INFO_ABI.outputs,\n metadata: { protocol: 'psm', action: 'get-info', network: options.network },\n }\n}\n\nexport function normalizePsmInfoResult(result: unknown): PsmInfo {\n const values = resultValues(result)\n if (values.length !== PSM_INFO_RESULT_LENGTH) {\n return contractError('PSM info result has an unexpected length', { result })\n }\n\n const normalized = values.map(toUintString)\n return {\n reverseRemainingUsdd: normalized[0]!,\n pairSwappedUsdd: normalized[1]!,\n totalUsddLimit: normalized[2]!,\n pairUsddLimit: normalized[3]!,\n psmUsdtBalance: normalized[4]!,\n vaultUsddBalance: normalized[5]!,\n totalSwappedUsdd: normalized[6]!,\n enabled: normalized[7]! !== '0',\n reverseLimitEnabled: normalized[8]! !== '0',\n tin: normalized[9]!,\n tout: normalized[10]!,\n }\n}\n","import { SDKError } from '@sun-protocol/sun-sdk-core'\nimport { PSM_ERROR_CODES } from './errors.js'\nimport type { PsmErrorCode } from './errors.js'\nimport type { PsmInfo, PsmQuote, PsmQuoteInput, PsmSnapshot } from './types.js'\n\nexport const PSM_WAD = 10n ** 18n\nexport const PSM_USDT_TO_USDD_SCALE = 10n ** 12n\n\ninterface PsmNumericInfo {\n readonly reverseRemainingUsdd: bigint\n readonly pairSwappedUsdd: bigint\n readonly totalUsddLimit: bigint\n readonly pairUsddLimit: bigint\n readonly psmUsdtBalance: bigint\n readonly vaultUsddBalance: bigint\n readonly totalSwappedUsdd: bigint\n readonly tin: bigint\n readonly tout: bigint\n}\n\ninterface IntegerQuote {\n readonly amountIn: bigint\n readonly amountOut: bigint\n readonly fee: bigint\n}\n\ninterface ValidatedPsmInfo {\n readonly info: PsmInfo\n readonly numeric: PsmNumericInfo\n}\n\nconst CANONICAL_UINT = /^(0|[1-9]\\d*)$/\n\nfunction contractUint(value: unknown, field: string): bigint {\n if (typeof value !== 'string' || !CANONICAL_UINT.test(value)) {\n throw new SDKError('SDK_CONTRACT_ERROR', `PSM ${field} is not a canonical unsigned integer`, { field, value })\n }\n\n try {\n return BigInt(value)\n } catch {\n throw new SDKError('SDK_CONTRACT_ERROR', `PSM ${field} is not an unsigned integer`, { field, value })\n }\n}\n\nfunction inputAmount(value: unknown): bigint {\n if (typeof value !== 'string' || !CANONICAL_UINT.test(value)) {\n throw new SDKError('SDK_INVALID_ARGUMENT', 'specifiedAmount must be a canonical unsigned integer', {\n specifiedAmount: value,\n })\n }\n\n const amount = BigInt(value)\n if (amount === 0n) {\n throw new SDKError('SDK_INVALID_ARGUMENT', 'specifiedAmount must be greater than zero', {\n specifiedAmount: value,\n })\n }\n return amount\n}\n\nfunction contractBoolean(value: unknown, field: string): boolean {\n if (typeof value !== 'boolean') {\n throw new SDKError('SDK_CONTRACT_ERROR', `PSM ${field} is not a boolean`, { field, value })\n }\n return value\n}\n\nfunction validateInfo(info: PsmInfo): ValidatedPsmInfo {\n const numeric = {\n reverseRemainingUsdd: contractUint(info.reverseRemainingUsdd, 'reverseRemainingUsdd'),\n pairSwappedUsdd: contractUint(info.pairSwappedUsdd, 'pairSwappedUsdd'),\n totalUsddLimit: contractUint(info.totalUsddLimit, 'totalUsddLimit'),\n pairUsddLimit: contractUint(info.pairUsddLimit, 'pairUsddLimit'),\n psmUsdtBalance: contractUint(info.psmUsdtBalance, 'psmUsdtBalance'),\n vaultUsddBalance: contractUint(info.vaultUsddBalance, 'vaultUsddBalance'),\n totalSwappedUsdd: contractUint(info.totalSwappedUsdd, 'totalSwappedUsdd'),\n tin: contractUint(info.tin, 'tin'),\n tout: contractUint(info.tout, 'tout'),\n }\n\n if (numeric.tin > PSM_WAD) {\n throw new SDKError('SDK_CONTRACT_ERROR', 'PSM tin exceeds WAD', { tin: info.tin })\n }\n\n return {\n numeric,\n info: {\n reverseRemainingUsdd: numeric.reverseRemainingUsdd.toString(),\n pairSwappedUsdd: numeric.pairSwappedUsdd.toString(),\n totalUsddLimit: numeric.totalUsddLimit.toString(),\n pairUsddLimit: numeric.pairUsddLimit.toString(),\n psmUsdtBalance: numeric.psmUsdtBalance.toString(),\n vaultUsddBalance: numeric.vaultUsddBalance.toString(),\n totalSwappedUsdd: numeric.totalSwappedUsdd.toString(),\n enabled: contractBoolean(info.enabled, 'enabled'),\n reverseLimitEnabled: contractBoolean(info.reverseLimitEnabled, 'reverseLimitEnabled'),\n tin: numeric.tin.toString(),\n tout: numeric.tout.toString(),\n },\n }\n}\n\nfunction minimum(...values: readonly bigint[]): bigint {\n return values.reduce((smallest, value) => value < smallest ? value : smallest)\n}\n\nfunction nonNegativeDifference(limit: bigint, used: bigint): bigint {\n return limit > used ? limit - used : 0n\n}\n\nfunction maxSellGem(values: PsmNumericInfo): bigint {\n const grossCapacity = minimum(\n nonNegativeDifference(values.totalUsddLimit, values.totalSwappedUsdd),\n nonNegativeDifference(values.pairUsddLimit, values.pairSwappedUsdd),\n values.vaultUsddBalance,\n )\n return grossCapacity / PSM_USDT_TO_USDD_SCALE\n}\n\nfunction ceilDiv(numerator: bigint, denominator: bigint): bigint {\n return (numerator + denominator - 1n) / denominator\n}\n\nfunction sellForGem(gemAmount: bigint, tin: bigint): IntegerQuote {\n const gem18 = gemAmount * PSM_USDT_TO_USDD_SCALE\n const fee = gem18 * tin / PSM_WAD\n return { amountIn: gemAmount, amountOut: gem18 - fee, fee }\n}\n\nfunction buyForGem(gemAmount: bigint, tout: bigint): IntegerQuote {\n const gem18 = gemAmount * PSM_USDT_TO_USDD_SCALE\n const fee = gem18 * tout / PSM_WAD\n return { amountIn: gem18 + fee, amountOut: gemAmount, fee }\n}\n\nfunction minSellGemForOutput(amountOut: bigint, tin: bigint): bigint {\n let gemAmount = ceilDiv(\n amountOut * PSM_WAD,\n PSM_USDT_TO_USDD_SCALE * (PSM_WAD - tin),\n )\n\n while (gemAmount > 0n && sellForGem(gemAmount - 1n, tin).amountOut >= amountOut) {\n gemAmount -= 1n\n }\n while (sellForGem(gemAmount, tin).amountOut < amountOut) {\n gemAmount += 1n\n }\n return gemAmount\n}\n\nfunction maxBuyGemForInput(amountIn: bigint, tout: bigint): bigint {\n let gemAmount = amountIn * PSM_WAD / (\n PSM_USDT_TO_USDD_SCALE * (PSM_WAD + tout)\n )\n\n while (buyForGem(gemAmount + 1n, tout).amountIn <= amountIn) {\n gemAmount += 1n\n }\n while (buyForGem(gemAmount, tout).amountIn > amountIn) {\n gemAmount -= 1n\n }\n return gemAmount\n}\n\nexport function createPsmSnapshot(info: PsmInfo): PsmSnapshot {\n const validated = validateInfo(info)\n const values = validated.numeric\n const sellAvailable = sellForGem(maxSellGem(values), values.tin).amountOut\n\n const maxGemByReverseLimit = maxBuyGemForInput(values.reverseRemainingUsdd, values.tout)\n const maxBuyGem = validated.info.reverseLimitEnabled\n ? minimum(values.psmUsdtBalance, maxGemByReverseLimit)\n : values.psmUsdtBalance\n\n return {\n ...validated.info,\n usdtToUsddAvailableAmountOut: sellAvailable.toString(),\n usddToUsdtAvailableAmountOut: maxBuyGem.toString(),\n }\n}\n\nfunction limitExceeded(\n direction: PsmQuoteInput['direction'],\n requestedAmountOut: bigint,\n availableAmountOut: bigint,\n): never {\n throw new SDKError<PsmErrorCode>(PSM_ERROR_CODES.PSM_LIMIT_EXCEEDED, 'PSM output exceeds available capacity', {\n direction,\n requestedAmountOut: requestedAmountOut.toString(),\n availableAmountOut: availableAmountOut.toString(),\n })\n}\n\nfunction quoteResult(\n input: PsmQuoteInput,\n specifiedAmount: bigint,\n quote: IntegerQuote,\n gemAmount: bigint,\n feeRate: bigint,\n availableAmountOut: bigint,\n): PsmQuote {\n return {\n mode: input.mode,\n direction: input.direction,\n specifiedAmount: specifiedAmount.toString(),\n amountIn: quote.amountIn.toString(),\n amountOut: quote.amountOut.toString(),\n gemAmount: gemAmount.toString(),\n feeAmount: quote.fee.toString(),\n feeRate: feeRate.toString(),\n availableAmountOut: availableAmountOut.toString(),\n }\n}\n\nexport function quotePsm(input: PsmQuoteInput): PsmQuote {\n if (input.mode !== 'exact-in' && input.mode !== 'exact-out') {\n throw new SDKError('SDK_INVALID_ARGUMENT', 'unsupported PSM quote mode', { mode: input.mode })\n }\n if (input.direction !== 'usdt-to-usdd' && input.direction !== 'usdd-to-usdt') {\n throw new SDKError('SDK_INVALID_ARGUMENT', 'unsupported PSM quote direction', { direction: input.direction })\n }\n\n const specifiedAmount = inputAmount(input.specifiedAmount)\n const snapshot = validateInfo(input.snapshot)\n const tin = snapshot.numeric.tin\n const tout = snapshot.numeric.tout\n const availableAmountOut = contractUint(\n input.direction === 'usdt-to-usdd'\n ? input.snapshot.usdtToUsddAvailableAmountOut\n : input.snapshot.usddToUsdtAvailableAmountOut,\n input.direction === 'usdt-to-usdd'\n ? 'usdtToUsddAvailableAmountOut'\n : 'usddToUsdtAvailableAmountOut',\n )\n\n if (!snapshot.info.enabled) {\n throw new SDKError<PsmErrorCode>(PSM_ERROR_CODES.PSM_DISABLED, 'PSM is disabled', {\n direction: input.direction,\n })\n }\n\n if (input.mode === 'exact-out' && specifiedAmount > availableAmountOut) {\n return limitExceeded(input.direction, specifiedAmount, availableAmountOut)\n }\n\n let gemAmount: bigint\n let quote: IntegerQuote\n let feeRate: bigint\n if (input.direction === 'usdt-to-usdd') {\n feeRate = tin\n gemAmount = input.mode === 'exact-in'\n ? specifiedAmount\n : minSellGemForOutput(specifiedAmount, tin)\n quote = sellForGem(gemAmount, tin)\n } else {\n feeRate = tout\n gemAmount = input.mode === 'exact-in'\n ? maxBuyGemForInput(specifiedAmount, tout)\n : specifiedAmount\n quote = buyForGem(gemAmount, tout)\n }\n\n if (\n input.mode === 'exact-in'\n && input.direction === 'usdt-to-usdd'\n && gemAmount > maxSellGem(snapshot.numeric)\n ) {\n return limitExceeded(input.direction, quote.amountOut, availableAmountOut)\n }\n\n if (input.mode === 'exact-in' && quote.amountOut > availableAmountOut) {\n return limitExceeded(input.direction, quote.amountOut, availableAmountOut)\n }\n\n return quoteResult(input, specifiedAmount, quote, gemAmount, feeRate, availableAmountOut)\n}\n","import { getContractAddress } from '@sun-protocol/sun-sdk-chains'\nimport { SDKError, assertTronAddress, createContractCallAction, type ContractCallAction } from '@sun-protocol/sun-sdk-core'\nimport type { PsmSwapActionOptions } from './types.js'\n\nconst CANONICAL_UINT = /^(0|[1-9]\\d*)$/\n\nfunction gemAmount(value: string): string {\n if (typeof value !== 'string' || !CANONICAL_UINT.test(value)) {\n throw new SDKError('SDK_INVALID_ARGUMENT', 'gemAmount must be a canonical unsigned integer', { gemAmount: value })\n }\n\n const amount = BigInt(value)\n if (amount === 0n) {\n throw new SDKError('SDK_INVALID_ARGUMENT', 'gemAmount must be greater than zero', { gemAmount: value })\n }\n return amount.toString()\n}\n\nfunction buildPsmSwapAction(\n params: PsmSwapActionOptions,\n method: 'sellGem' | 'buyGem',\n action: 'sell-gem' | 'buy-gem',\n): ContractCallAction {\n const recipient = assertTronAddress(params.recipient, 'recipient')\n const target = assertTronAddress(params.psm ?? getContractAddress(params.network, 'psm'), 'psm')\n const amount = gemAmount(params.gemAmount)\n\n return createContractCallAction({\n id: params.id ?? `psm-${action}-${params.network}`,\n target,\n functionSelector: `${method}(address,uint256)`,\n parameters: [\n { type: 'address', value: recipient },\n { type: 'uint256', value: amount },\n ],\n ...(params.feeLimit !== undefined ? { feeLimit: params.feeLimit } : {}),\n })\n}\n\nexport function buildPsmSellGemAction(params: PsmSwapActionOptions): ContractCallAction {\n return buildPsmSwapAction(params, 'sellGem', 'sell-gem')\n}\n\nexport function buildPsmBuyGemAction(params: PsmSwapActionOptions): ContractCallAction {\n return buildPsmSwapAction(params, 'buyGem', 'buy-gem')\n}\n"],"mappings":"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","names":["SDKError","SDKError","gemAmount","getContractAddress","SDKError","assertTronAddress","CANONICAL_UINT"]}
|
package/package.json
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@sun-protocol/sun-sdk-psm",
|
|
3
|
+
"version": "0.1.0-beta.0",
|
|
4
|
+
"description": "Runtime-neutral SUN PSM reads, quotes, errors, and transaction action builders.",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"sun",
|
|
7
|
+
"tron",
|
|
8
|
+
"defi",
|
|
9
|
+
"psm",
|
|
10
|
+
"stablecoin"
|
|
11
|
+
],
|
|
12
|
+
"homepage": "https://github.com/sun-protocol/sun-sdk#readme",
|
|
13
|
+
"repository": {
|
|
14
|
+
"type": "git",
|
|
15
|
+
"url": "git+https://github.com/sun-protocol/sun-sdk.git",
|
|
16
|
+
"directory": "packages/psm"
|
|
17
|
+
},
|
|
18
|
+
"private": false,
|
|
19
|
+
"type": "module",
|
|
20
|
+
"engines": {
|
|
21
|
+
"node": ">=20"
|
|
22
|
+
},
|
|
23
|
+
"main": "./dist/index.cjs",
|
|
24
|
+
"module": "./dist/index.js",
|
|
25
|
+
"types": "./dist/index.d.ts",
|
|
26
|
+
"sideEffects": false,
|
|
27
|
+
"files": [
|
|
28
|
+
"dist"
|
|
29
|
+
],
|
|
30
|
+
"exports": {
|
|
31
|
+
".": {
|
|
32
|
+
"types": "./dist/index.d.ts",
|
|
33
|
+
"import": "./dist/index.js",
|
|
34
|
+
"require": "./dist/index.cjs"
|
|
35
|
+
}
|
|
36
|
+
},
|
|
37
|
+
"dependencies": {
|
|
38
|
+
"@sun-protocol/sun-sdk-chains": "0.1.0-beta.0",
|
|
39
|
+
"@sun-protocol/sun-sdk-core": "0.1.0-beta.0"
|
|
40
|
+
},
|
|
41
|
+
"scripts": {
|
|
42
|
+
"build": "tsup src/index.ts --format esm,cjs --dts --sourcemap --clean --tsconfig ../../tsconfig.base.json",
|
|
43
|
+
"typecheck": "tsc -p tsconfig.json --noEmit",
|
|
44
|
+
"test": "vitest run"
|
|
45
|
+
}
|
|
46
|
+
}
|