@gearbox-protocol/sdk 13.0.0-next.16 → 13.0.0-next.18
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/dist/cjs/abi/310/iSecuritizeKYCFactory.js +7 -0
- package/dist/cjs/sdk/accounts/AbstractCreditAccountsService.js +50 -36
- package/dist/cjs/sdk/base/ChainContractsRegister.js +1 -1
- package/dist/cjs/sdk/base/TokensMeta.js +126 -8
- package/dist/cjs/sdk/market/kyc/SecuritizeKYCFactory.js +13 -0
- package/dist/esm/abi/310/iSecuritizeKYCFactory.js +7 -0
- package/dist/esm/sdk/accounts/AbstractCreditAccountsService.js +50 -36
- package/dist/esm/sdk/base/ChainContractsRegister.js +1 -1
- package/dist/esm/sdk/base/TokensMeta.js +130 -7
- package/dist/esm/sdk/market/kyc/SecuritizeKYCFactory.js +13 -0
- package/dist/types/abi/310/iSecuritizeKYCFactory.d.ts +10 -0
- package/dist/types/sdk/accounts/AbstractCreditAccountsService.d.ts +17 -23
- package/dist/types/sdk/accounts/types.d.ts +21 -0
- package/dist/types/sdk/base/TokensMeta.d.ts +26 -4
- package/dist/types/sdk/base/token-types.d.ts +9 -2
- package/dist/types/sdk/market/kyc/SecuritizeKYCFactory.d.ts +13 -0
- package/package.json +1 -1
|
@@ -50,6 +50,13 @@ const iSecuritizeKYCFactoryAbi = [
|
|
|
50
50
|
outputs: [{ name: "", type: "address[]", internalType: "address[]" }],
|
|
51
51
|
stateMutability: "view"
|
|
52
52
|
},
|
|
53
|
+
{
|
|
54
|
+
type: "function",
|
|
55
|
+
name: "getDSTokens",
|
|
56
|
+
inputs: [],
|
|
57
|
+
outputs: [{ name: "", type: "address[]", internalType: "address[]" }],
|
|
58
|
+
stateMutability: "view"
|
|
59
|
+
},
|
|
53
60
|
{
|
|
54
61
|
type: "function",
|
|
55
62
|
name: "getInvestor",
|
|
@@ -787,43 +787,52 @@ class AbstractCreditAccountService extends import_base.SDKConstruct {
|
|
|
787
787
|
const tx = await this.multicallTx(cm, ca.creditAccount, calls);
|
|
788
788
|
return { tx, calls, creditFacade: cm.creditFacade };
|
|
789
789
|
}
|
|
790
|
+
/**
|
|
791
|
+
* Returns address to which approval should be given on collateral token
|
|
792
|
+
* It's credit manager for classical markets and special wallet for KYC markets
|
|
793
|
+
* @param options - {@link GetApprovalAddressProps}
|
|
794
|
+
* @returns
|
|
795
|
+
**/
|
|
796
|
+
async getApprovalAddress(options) {
|
|
797
|
+
const { creditManager } = options;
|
|
798
|
+
const suite = this.sdk.marketRegister.findCreditManager(creditManager);
|
|
799
|
+
await this.sdk.tokensMeta.loadTokenData(suite.underlying);
|
|
800
|
+
const underlying = this.sdk.tokensMeta.mustGet(suite.underlying);
|
|
801
|
+
if (this.sdk.tokensMeta.isKYCUnderlying(underlying)) {
|
|
802
|
+
const factory = new import_market.SecuritizeKYCFactory(this.sdk, underlying.kycFactory);
|
|
803
|
+
if ("creditAccount" in options) {
|
|
804
|
+
return factory.getWallet(options.creditAccount);
|
|
805
|
+
}
|
|
806
|
+
return factory.precomputeWalletAddress(creditManager, options.borrower);
|
|
807
|
+
}
|
|
808
|
+
return suite.creditManager.address;
|
|
809
|
+
}
|
|
790
810
|
/**
|
|
791
811
|
* Executes swap specified by given calls, update quotas of affected tokens
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
* @param {bigint} ethAmount - native token amount to attach to tx
|
|
800
|
-
* @param {Address} creditManager - address of credit manager to open credit account on
|
|
801
|
-
* @param {Array<Asset>} collateral - array of collateral which can be just directly added or swapped using the path {@link Asset}
|
|
802
|
-
* @param {Record<Address, PermitResult>} permits - permits of collateral tokens (in any permittable token is present) {@link PermitResult}
|
|
803
|
-
* @param {bigint} debt - debt to open credit account with
|
|
804
|
-
* @param {boolean} withdrawDebt - flag to withdraw debt to wallet after opening credit account;
|
|
805
|
-
used for borrowing functionality
|
|
806
|
-
* @param {bigint} referralCode - referral code to open credit account with
|
|
807
|
-
* @param {Address} to - wallet address to transfer credit account to\
|
|
808
|
-
* @param {Array<MultiCall>} calls - array of MultiCall from router methods findOpenStrategyPath {@link MultiCall}.
|
|
809
|
-
Used for trading and strategy functionality
|
|
810
|
-
* @param {Array<Asset>} averageQuota - average quota for tokens after open {@link Asset}
|
|
811
|
-
* @param {Array<Asset>} minQuota - minimum quota for tokens after open {@link Asset}
|
|
812
|
+
* - Open credit account is executed in the following order: price update -> increase debt -> add collateral ->
|
|
813
|
+
* -> update quotas -> (optionally: execute swap path for trading/strategy) ->
|
|
814
|
+
* -> (optionally: withdraw debt for lending)
|
|
815
|
+
*- Basic open credit account: price update -> increase debt -> add collateral -> update quotas
|
|
816
|
+
*- Lending: price update -> increase debt -> add collateral -> update quotas -> withdraw debt
|
|
817
|
+
*- Strategy/trading: price update -> increase debt -> add collateral -> update quotas -> execute swap path
|
|
818
|
+
*- In strategy is possible situation when collateral is added, but not swapped; the only swapped value in this case will be debt
|
|
812
819
|
* @returns All necessary data to execute the transaction (call, credit facade)
|
|
813
|
-
|
|
814
|
-
async openCA({
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
820
|
+
**/
|
|
821
|
+
async openCA(props) {
|
|
822
|
+
const {
|
|
823
|
+
ethAmount,
|
|
824
|
+
creditManager,
|
|
825
|
+
reopenCreditAccount,
|
|
826
|
+
collateral,
|
|
827
|
+
permits,
|
|
828
|
+
debt,
|
|
829
|
+
withdrawToken,
|
|
830
|
+
referralCode,
|
|
831
|
+
to,
|
|
832
|
+
calls: openPathCalls,
|
|
833
|
+
minQuota,
|
|
834
|
+
averageQuota
|
|
835
|
+
} = props;
|
|
827
836
|
const cmSuite = this.sdk.marketRegister.findCreditManager(creditManager);
|
|
828
837
|
const cm = cmSuite.creditManager;
|
|
829
838
|
let tokenToWithdraw;
|
|
@@ -855,7 +864,12 @@ class AbstractCreditAccountService extends import_base.SDKConstruct {
|
|
|
855
864
|
averageQuota
|
|
856
865
|
})
|
|
857
866
|
];
|
|
858
|
-
|
|
867
|
+
let tx;
|
|
868
|
+
if (reopenCreditAccount) {
|
|
869
|
+
tx = await this.multicallTx(cmSuite, reopenCreditAccount, calls);
|
|
870
|
+
} else {
|
|
871
|
+
tx = await this.openCreditAccountTx(cmSuite, to, calls, referralCode);
|
|
872
|
+
}
|
|
859
873
|
tx.value = ethAmount.toString(10);
|
|
860
874
|
return { calls, tx, creditFacade: cmSuite.creditFacade };
|
|
861
875
|
}
|
|
@@ -1208,8 +1222,8 @@ class AbstractCreditAccountService extends import_base.SDKConstruct {
|
|
|
1208
1222
|
await this.sdk.tokensMeta.loadTokenData(suite.underlying);
|
|
1209
1223
|
const underlying = this.sdk.tokensMeta.mustGet(suite.underlying);
|
|
1210
1224
|
if (this.sdk.tokensMeta.isKYCUnderlying(underlying)) {
|
|
1211
|
-
const tokensToRegister = [];
|
|
1212
1225
|
const factory = new import_market.SecuritizeKYCFactory(this.sdk, underlying.kycFactory);
|
|
1226
|
+
const tokensToRegister = await factory.getDSTokens();
|
|
1213
1227
|
return factory.openCreditAccount(
|
|
1214
1228
|
suite.creditManager.address,
|
|
1215
1229
|
calls,
|
|
@@ -48,7 +48,7 @@ class ChainContractsRegister {
|
|
|
48
48
|
logger;
|
|
49
49
|
constructor(client, logger) {
|
|
50
50
|
this.client = client;
|
|
51
|
-
this.tokensMeta = new import_TokensMeta.TokensMeta(client);
|
|
51
|
+
this.tokensMeta = new import_TokensMeta.TokensMeta(client, logger);
|
|
52
52
|
this.logger = logger;
|
|
53
53
|
}
|
|
54
54
|
resetContracts() {
|
|
@@ -22,16 +22,19 @@ __export(TokensMeta_exports, {
|
|
|
22
22
|
});
|
|
23
23
|
module.exports = __toCommonJS(TokensMeta_exports);
|
|
24
24
|
var import_viem = require("viem");
|
|
25
|
+
var import_iSecuritizeKYCFactory = require("../../abi/310/iSecuritizeKYCFactory.js");
|
|
25
26
|
var import_iStateSerializer = require("../../abi/iStateSerializer.js");
|
|
26
27
|
var import_iVersion = require("../../abi/iVersion.js");
|
|
27
|
-
var import__ = require("../index.js");
|
|
28
28
|
var import_utils = require("../utils/index.js");
|
|
29
|
+
var import_token_types = require("./token-types.js");
|
|
29
30
|
class TokensMeta extends import_utils.AddressMap {
|
|
30
31
|
#client;
|
|
31
32
|
#tokenDataLoaded = new import_utils.AddressSet();
|
|
32
|
-
|
|
33
|
+
#logger;
|
|
34
|
+
constructor(client, logger) {
|
|
33
35
|
super(void 0, "tokensMeta");
|
|
34
36
|
this.#client = client;
|
|
37
|
+
this.#logger = logger?.child?.({ name: "TokensMeta" }) ?? logger;
|
|
35
38
|
}
|
|
36
39
|
reset() {
|
|
37
40
|
this.clear();
|
|
@@ -43,6 +46,11 @@ class TokensMeta extends import_utils.AddressMap {
|
|
|
43
46
|
decimals(token) {
|
|
44
47
|
return this.mustGet(token).decimals;
|
|
45
48
|
}
|
|
49
|
+
/**
|
|
50
|
+
* Returns true if the token is a phantom token, throws if the token data is not loaded
|
|
51
|
+
* @param t
|
|
52
|
+
* @returns
|
|
53
|
+
*/
|
|
46
54
|
isPhantomToken(t) {
|
|
47
55
|
if (!this.#tokenDataLoaded.has(t.addr)) {
|
|
48
56
|
throw new Error(
|
|
@@ -51,6 +59,11 @@ class TokensMeta extends import_utils.AddressMap {
|
|
|
51
59
|
}
|
|
52
60
|
return "contractType" in t && t.contractType.startsWith("PHANTOM_TOKEN::");
|
|
53
61
|
}
|
|
62
|
+
/**
|
|
63
|
+
* Returns true if the token is a KYC underlying token, throws if the token data is not loaded
|
|
64
|
+
* @param t
|
|
65
|
+
* @returns
|
|
66
|
+
*/
|
|
54
67
|
isKYCUnderlying(t) {
|
|
55
68
|
if (!this.#tokenDataLoaded.has(t.addr)) {
|
|
56
69
|
throw new Error(
|
|
@@ -59,9 +72,22 @@ class TokensMeta extends import_utils.AddressMap {
|
|
|
59
72
|
}
|
|
60
73
|
return "contractType" in t && t.contractType.startsWith("KYC_UNDERLYING::");
|
|
61
74
|
}
|
|
75
|
+
/**
|
|
76
|
+
* Returns true if the token is a DSToken, throws if the token data is not loaded
|
|
77
|
+
* @param t
|
|
78
|
+
* @returns
|
|
79
|
+
*/
|
|
80
|
+
isDSToken(t) {
|
|
81
|
+
if (!this.#tokenDataLoaded.has(t.addr)) {
|
|
82
|
+
throw new Error(
|
|
83
|
+
`extended token data not loaded for ${t.symbol} (${t.addr})`
|
|
84
|
+
);
|
|
85
|
+
}
|
|
86
|
+
return !!t.isDSToken;
|
|
87
|
+
}
|
|
62
88
|
/**
|
|
63
89
|
* Returns a map of all phantom tokens
|
|
64
|
-
* Throws if
|
|
90
|
+
* Throws if token data is not loaded
|
|
65
91
|
*/
|
|
66
92
|
get phantomTokens() {
|
|
67
93
|
const result = new import_utils.AddressMap();
|
|
@@ -72,6 +98,10 @@ class TokensMeta extends import_utils.AddressMap {
|
|
|
72
98
|
}
|
|
73
99
|
return result;
|
|
74
100
|
}
|
|
101
|
+
/**
|
|
102
|
+
* Returns a map of all KYC underlying tokens
|
|
103
|
+
* Throws if token data is not loaded
|
|
104
|
+
*/
|
|
75
105
|
get kycUnderlyings() {
|
|
76
106
|
const result = new import_utils.AddressMap();
|
|
77
107
|
for (const [token, meta] of this.entries()) {
|
|
@@ -81,6 +111,15 @@ class TokensMeta extends import_utils.AddressMap {
|
|
|
81
111
|
}
|
|
82
112
|
return result;
|
|
83
113
|
}
|
|
114
|
+
get dsTokens() {
|
|
115
|
+
const result = new import_utils.AddressMap();
|
|
116
|
+
for (const [token, meta] of this.entries()) {
|
|
117
|
+
if (this.isDSToken(meta)) {
|
|
118
|
+
result.upsert(token, meta);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
return result;
|
|
122
|
+
}
|
|
84
123
|
formatBN(arg0, arg1, arg2) {
|
|
85
124
|
const token = typeof arg0 === "object" ? arg0.token : arg0;
|
|
86
125
|
const amount = typeof arg0 === "object" ? arg0.balance : arg1;
|
|
@@ -100,7 +139,7 @@ class TokensMeta extends import_utils.AddressMap {
|
|
|
100
139
|
return meta;
|
|
101
140
|
}
|
|
102
141
|
/**
|
|
103
|
-
* Loads token information about phantom
|
|
142
|
+
* Loads token information about phantom tokens, KYC underlying tokens and DSTokens
|
|
104
143
|
*
|
|
105
144
|
* @param tokens - tokens to load data for, defaults to all tokens
|
|
106
145
|
*/
|
|
@@ -128,15 +167,26 @@ class TokensMeta extends import_utils.AddressMap {
|
|
|
128
167
|
allowFailure: true,
|
|
129
168
|
batchSize: 0
|
|
130
169
|
});
|
|
170
|
+
this.#logger?.debug(`loaded ${resp.length} contract types`);
|
|
171
|
+
const kycFactories = new import_utils.AddressSet();
|
|
131
172
|
for (let i = 0; i < tokensToLoad.length; i++) {
|
|
132
|
-
this.#overrideTokenMeta(
|
|
173
|
+
const meta = this.#overrideTokenMeta(
|
|
174
|
+
tokensToLoad[i],
|
|
175
|
+
resp[2 * i],
|
|
176
|
+
resp[2 * i + 1]
|
|
177
|
+
);
|
|
133
178
|
this.#tokenDataLoaded.add(tokensToLoad[i]);
|
|
179
|
+
if (this.isKYCUnderlying(meta)) {
|
|
180
|
+
kycFactories.add(meta.kycFactory);
|
|
181
|
+
}
|
|
134
182
|
}
|
|
183
|
+
this.#logger?.debug(`found ${kycFactories.size} KYC factories`);
|
|
184
|
+
await this.#loadDSTokens(kycFactories);
|
|
135
185
|
}
|
|
136
186
|
#overrideTokenMeta(token, contractTypeResp, serializeResp) {
|
|
137
187
|
const meta = this.mustGet(token);
|
|
138
188
|
if (contractTypeResp.status === "success") {
|
|
139
|
-
const contractType = (0,
|
|
189
|
+
const contractType = (0, import_utils.bytes32ToString)(contractTypeResp.result);
|
|
140
190
|
if (contractType.startsWith("KYC_UNDERLYING::")) {
|
|
141
191
|
if (serializeResp.status === "success") {
|
|
142
192
|
this.#overrideKYCUnderlying(meta, contractType, serializeResp.result);
|
|
@@ -151,10 +201,12 @@ class TokensMeta extends import_utils.AddressMap {
|
|
|
151
201
|
contractType
|
|
152
202
|
});
|
|
153
203
|
}
|
|
204
|
+
this.#logger?.debug(`token ${meta.symbol} is ${contractType}`);
|
|
154
205
|
}
|
|
206
|
+
return this.mustGet(token);
|
|
155
207
|
}
|
|
156
208
|
#overrideKYCUnderlying(meta, contractType, serialized) {
|
|
157
|
-
if (contractType ===
|
|
209
|
+
if (contractType === import_token_types.KYC_UNDERLYING_DEFAULT) {
|
|
158
210
|
const decoded = (0, import_viem.decodeAbiParameters)(
|
|
159
211
|
[
|
|
160
212
|
{ type: "address", name: "kycFactory" },
|
|
@@ -168,7 +220,7 @@ class TokensMeta extends import_utils.AddressMap {
|
|
|
168
220
|
kycFactory: decoded[0],
|
|
169
221
|
asset: decoded[1]
|
|
170
222
|
});
|
|
171
|
-
} else if (contractType ===
|
|
223
|
+
} else if (contractType === import_token_types.KYC_UNDERLYING_ON_DEMAND) {
|
|
172
224
|
const decoded = (0, import_viem.decodeAbiParameters)(
|
|
173
225
|
[
|
|
174
226
|
{ type: "address", name: "kycFactory" },
|
|
@@ -188,6 +240,72 @@ class TokensMeta extends import_utils.AddressMap {
|
|
|
188
240
|
});
|
|
189
241
|
}
|
|
190
242
|
}
|
|
243
|
+
async #loadDSTokens(kycFactories) {
|
|
244
|
+
const resp = await this.#client.multicall({
|
|
245
|
+
contracts: kycFactories.map((address) => ({
|
|
246
|
+
address,
|
|
247
|
+
abi: import_iSecuritizeKYCFactory.iSecuritizeKYCFactoryAbi,
|
|
248
|
+
functionName: "getDSTokens"
|
|
249
|
+
})),
|
|
250
|
+
allowFailure: false,
|
|
251
|
+
batchSize: 0
|
|
252
|
+
});
|
|
253
|
+
const dsToken = new import_utils.AddressSet(resp.flat());
|
|
254
|
+
const tokensToLoad = dsToken.difference(new Set(this.keys()));
|
|
255
|
+
this.#logger?.debug(
|
|
256
|
+
`found ${dsToken.size} DSTokens in KYC factories, need to load ${tokensToLoad.size} basic metadata`
|
|
257
|
+
);
|
|
258
|
+
await this.#loadWithoutCompressor(tokensToLoad);
|
|
259
|
+
for (const token of dsToken) {
|
|
260
|
+
const meta = this.mustGet(token);
|
|
261
|
+
this.upsert(token, {
|
|
262
|
+
...meta,
|
|
263
|
+
isDSToken: true
|
|
264
|
+
});
|
|
265
|
+
this.#tokenDataLoaded.add(token);
|
|
266
|
+
this.#logger?.debug(`token ${meta.symbol} (${token}) is a DSToken`);
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
async #loadWithoutCompressor(tokens_) {
|
|
270
|
+
if (tokens_.size === 0) {
|
|
271
|
+
return;
|
|
272
|
+
}
|
|
273
|
+
const tokens = Array.from(tokens_);
|
|
274
|
+
const resp = await this.#client.multicall({
|
|
275
|
+
contracts: tokens.flatMap(
|
|
276
|
+
(t) => [
|
|
277
|
+
{
|
|
278
|
+
address: t,
|
|
279
|
+
abi: import_viem.erc20Abi,
|
|
280
|
+
functionName: "symbol"
|
|
281
|
+
},
|
|
282
|
+
{
|
|
283
|
+
address: t,
|
|
284
|
+
abi: import_viem.erc20Abi,
|
|
285
|
+
functionName: "name"
|
|
286
|
+
},
|
|
287
|
+
{
|
|
288
|
+
address: t,
|
|
289
|
+
abi: import_viem.erc20Abi,
|
|
290
|
+
functionName: "decimals"
|
|
291
|
+
}
|
|
292
|
+
]
|
|
293
|
+
),
|
|
294
|
+
allowFailure: false,
|
|
295
|
+
batchSize: 0
|
|
296
|
+
});
|
|
297
|
+
this.#logger?.debug(
|
|
298
|
+
`loaded ${resp.length} basic metadata without compressor`
|
|
299
|
+
);
|
|
300
|
+
for (let i = 0; i < tokens.length; i++) {
|
|
301
|
+
this.upsert(tokens[i], {
|
|
302
|
+
addr: tokens[i],
|
|
303
|
+
symbol: resp[3 * i],
|
|
304
|
+
name: resp[3 * i + 1],
|
|
305
|
+
decimals: resp[3 * i + 2]
|
|
306
|
+
});
|
|
307
|
+
}
|
|
308
|
+
}
|
|
191
309
|
}
|
|
192
310
|
// Annotate the CommonJS export names for ESM import in node:
|
|
193
311
|
0 && (module.exports = {
|
|
@@ -32,6 +32,19 @@ class SecuritizeKYCFactory extends import_base.BaseContract {
|
|
|
32
32
|
abi
|
|
33
33
|
});
|
|
34
34
|
}
|
|
35
|
+
async precomputeWalletAddress(creditManager, investor) {
|
|
36
|
+
return this.contract.read.precomputeWalletAddress([
|
|
37
|
+
creditManager,
|
|
38
|
+
investor
|
|
39
|
+
]);
|
|
40
|
+
}
|
|
41
|
+
async getWallet(creditAccount) {
|
|
42
|
+
return this.contract.read.getWallet([creditAccount]);
|
|
43
|
+
}
|
|
44
|
+
async getDSTokens() {
|
|
45
|
+
const tokens = await this.contract.read.getDSTokens();
|
|
46
|
+
return [...tokens];
|
|
47
|
+
}
|
|
35
48
|
multicall(creditAccount, calls, tokensToRegister) {
|
|
36
49
|
return this.createRawTx({
|
|
37
50
|
functionName: "multicall",
|
|
@@ -27,6 +27,13 @@ const iSecuritizeKYCFactoryAbi = [
|
|
|
27
27
|
outputs: [{ name: "", type: "address[]", internalType: "address[]" }],
|
|
28
28
|
stateMutability: "view"
|
|
29
29
|
},
|
|
30
|
+
{
|
|
31
|
+
type: "function",
|
|
32
|
+
name: "getDSTokens",
|
|
33
|
+
inputs: [],
|
|
34
|
+
outputs: [{ name: "", type: "address[]", internalType: "address[]" }],
|
|
35
|
+
stateMutability: "view"
|
|
36
|
+
},
|
|
30
37
|
{
|
|
31
38
|
type: "function",
|
|
32
39
|
name: "getInvestor",
|
|
@@ -779,43 +779,52 @@ class AbstractCreditAccountService extends SDKConstruct {
|
|
|
779
779
|
const tx = await this.multicallTx(cm, ca.creditAccount, calls);
|
|
780
780
|
return { tx, calls, creditFacade: cm.creditFacade };
|
|
781
781
|
}
|
|
782
|
+
/**
|
|
783
|
+
* Returns address to which approval should be given on collateral token
|
|
784
|
+
* It's credit manager for classical markets and special wallet for KYC markets
|
|
785
|
+
* @param options - {@link GetApprovalAddressProps}
|
|
786
|
+
* @returns
|
|
787
|
+
**/
|
|
788
|
+
async getApprovalAddress(options) {
|
|
789
|
+
const { creditManager } = options;
|
|
790
|
+
const suite = this.sdk.marketRegister.findCreditManager(creditManager);
|
|
791
|
+
await this.sdk.tokensMeta.loadTokenData(suite.underlying);
|
|
792
|
+
const underlying = this.sdk.tokensMeta.mustGet(suite.underlying);
|
|
793
|
+
if (this.sdk.tokensMeta.isKYCUnderlying(underlying)) {
|
|
794
|
+
const factory = new SecuritizeKYCFactory(this.sdk, underlying.kycFactory);
|
|
795
|
+
if ("creditAccount" in options) {
|
|
796
|
+
return factory.getWallet(options.creditAccount);
|
|
797
|
+
}
|
|
798
|
+
return factory.precomputeWalletAddress(creditManager, options.borrower);
|
|
799
|
+
}
|
|
800
|
+
return suite.creditManager.address;
|
|
801
|
+
}
|
|
782
802
|
/**
|
|
783
803
|
* Executes swap specified by given calls, update quotas of affected tokens
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
* @param {bigint} ethAmount - native token amount to attach to tx
|
|
792
|
-
* @param {Address} creditManager - address of credit manager to open credit account on
|
|
793
|
-
* @param {Array<Asset>} collateral - array of collateral which can be just directly added or swapped using the path {@link Asset}
|
|
794
|
-
* @param {Record<Address, PermitResult>} permits - permits of collateral tokens (in any permittable token is present) {@link PermitResult}
|
|
795
|
-
* @param {bigint} debt - debt to open credit account with
|
|
796
|
-
* @param {boolean} withdrawDebt - flag to withdraw debt to wallet after opening credit account;
|
|
797
|
-
used for borrowing functionality
|
|
798
|
-
* @param {bigint} referralCode - referral code to open credit account with
|
|
799
|
-
* @param {Address} to - wallet address to transfer credit account to\
|
|
800
|
-
* @param {Array<MultiCall>} calls - array of MultiCall from router methods findOpenStrategyPath {@link MultiCall}.
|
|
801
|
-
Used for trading and strategy functionality
|
|
802
|
-
* @param {Array<Asset>} averageQuota - average quota for tokens after open {@link Asset}
|
|
803
|
-
* @param {Array<Asset>} minQuota - minimum quota for tokens after open {@link Asset}
|
|
804
|
+
* - Open credit account is executed in the following order: price update -> increase debt -> add collateral ->
|
|
805
|
+
* -> update quotas -> (optionally: execute swap path for trading/strategy) ->
|
|
806
|
+
* -> (optionally: withdraw debt for lending)
|
|
807
|
+
*- Basic open credit account: price update -> increase debt -> add collateral -> update quotas
|
|
808
|
+
*- Lending: price update -> increase debt -> add collateral -> update quotas -> withdraw debt
|
|
809
|
+
*- Strategy/trading: price update -> increase debt -> add collateral -> update quotas -> execute swap path
|
|
810
|
+
*- In strategy is possible situation when collateral is added, but not swapped; the only swapped value in this case will be debt
|
|
804
811
|
* @returns All necessary data to execute the transaction (call, credit facade)
|
|
805
|
-
|
|
806
|
-
async openCA({
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
812
|
+
**/
|
|
813
|
+
async openCA(props) {
|
|
814
|
+
const {
|
|
815
|
+
ethAmount,
|
|
816
|
+
creditManager,
|
|
817
|
+
reopenCreditAccount,
|
|
818
|
+
collateral,
|
|
819
|
+
permits,
|
|
820
|
+
debt,
|
|
821
|
+
withdrawToken,
|
|
822
|
+
referralCode,
|
|
823
|
+
to,
|
|
824
|
+
calls: openPathCalls,
|
|
825
|
+
minQuota,
|
|
826
|
+
averageQuota
|
|
827
|
+
} = props;
|
|
819
828
|
const cmSuite = this.sdk.marketRegister.findCreditManager(creditManager);
|
|
820
829
|
const cm = cmSuite.creditManager;
|
|
821
830
|
let tokenToWithdraw;
|
|
@@ -847,7 +856,12 @@ class AbstractCreditAccountService extends SDKConstruct {
|
|
|
847
856
|
averageQuota
|
|
848
857
|
})
|
|
849
858
|
];
|
|
850
|
-
|
|
859
|
+
let tx;
|
|
860
|
+
if (reopenCreditAccount) {
|
|
861
|
+
tx = await this.multicallTx(cmSuite, reopenCreditAccount, calls);
|
|
862
|
+
} else {
|
|
863
|
+
tx = await this.openCreditAccountTx(cmSuite, to, calls, referralCode);
|
|
864
|
+
}
|
|
851
865
|
tx.value = ethAmount.toString(10);
|
|
852
866
|
return { calls, tx, creditFacade: cmSuite.creditFacade };
|
|
853
867
|
}
|
|
@@ -1200,8 +1214,8 @@ class AbstractCreditAccountService extends SDKConstruct {
|
|
|
1200
1214
|
await this.sdk.tokensMeta.loadTokenData(suite.underlying);
|
|
1201
1215
|
const underlying = this.sdk.tokensMeta.mustGet(suite.underlying);
|
|
1202
1216
|
if (this.sdk.tokensMeta.isKYCUnderlying(underlying)) {
|
|
1203
|
-
const tokensToRegister = [];
|
|
1204
1217
|
const factory = new SecuritizeKYCFactory(this.sdk, underlying.kycFactory);
|
|
1218
|
+
const tokensToRegister = await factory.getDSTokens();
|
|
1205
1219
|
return factory.openCreditAccount(
|
|
1206
1220
|
suite.creditManager.address,
|
|
1207
1221
|
calls,
|
|
@@ -1,20 +1,28 @@
|
|
|
1
1
|
import {
|
|
2
|
-
decodeAbiParameters
|
|
2
|
+
decodeAbiParameters,
|
|
3
|
+
erc20Abi
|
|
3
4
|
} from "viem";
|
|
5
|
+
import { iSecuritizeKYCFactoryAbi } from "../../abi/310/iSecuritizeKYCFactory.js";
|
|
4
6
|
import { iStateSerializerAbi } from "../../abi/iStateSerializer.js";
|
|
5
7
|
import { iVersionAbi } from "../../abi/iVersion.js";
|
|
6
8
|
import {
|
|
9
|
+
AddressMap,
|
|
10
|
+
AddressSet,
|
|
7
11
|
bytes32ToString,
|
|
12
|
+
formatBN
|
|
13
|
+
} from "../utils/index.js";
|
|
14
|
+
import {
|
|
8
15
|
KYC_UNDERLYING_DEFAULT,
|
|
9
16
|
KYC_UNDERLYING_ON_DEMAND
|
|
10
|
-
} from "
|
|
11
|
-
import { AddressMap, AddressSet, formatBN } from "../utils/index.js";
|
|
17
|
+
} from "./token-types.js";
|
|
12
18
|
class TokensMeta extends AddressMap {
|
|
13
19
|
#client;
|
|
14
20
|
#tokenDataLoaded = new AddressSet();
|
|
15
|
-
|
|
21
|
+
#logger;
|
|
22
|
+
constructor(client, logger) {
|
|
16
23
|
super(void 0, "tokensMeta");
|
|
17
24
|
this.#client = client;
|
|
25
|
+
this.#logger = logger?.child?.({ name: "TokensMeta" }) ?? logger;
|
|
18
26
|
}
|
|
19
27
|
reset() {
|
|
20
28
|
this.clear();
|
|
@@ -26,6 +34,11 @@ class TokensMeta extends AddressMap {
|
|
|
26
34
|
decimals(token) {
|
|
27
35
|
return this.mustGet(token).decimals;
|
|
28
36
|
}
|
|
37
|
+
/**
|
|
38
|
+
* Returns true if the token is a phantom token, throws if the token data is not loaded
|
|
39
|
+
* @param t
|
|
40
|
+
* @returns
|
|
41
|
+
*/
|
|
29
42
|
isPhantomToken(t) {
|
|
30
43
|
if (!this.#tokenDataLoaded.has(t.addr)) {
|
|
31
44
|
throw new Error(
|
|
@@ -34,6 +47,11 @@ class TokensMeta extends AddressMap {
|
|
|
34
47
|
}
|
|
35
48
|
return "contractType" in t && t.contractType.startsWith("PHANTOM_TOKEN::");
|
|
36
49
|
}
|
|
50
|
+
/**
|
|
51
|
+
* Returns true if the token is a KYC underlying token, throws if the token data is not loaded
|
|
52
|
+
* @param t
|
|
53
|
+
* @returns
|
|
54
|
+
*/
|
|
37
55
|
isKYCUnderlying(t) {
|
|
38
56
|
if (!this.#tokenDataLoaded.has(t.addr)) {
|
|
39
57
|
throw new Error(
|
|
@@ -42,9 +60,22 @@ class TokensMeta extends AddressMap {
|
|
|
42
60
|
}
|
|
43
61
|
return "contractType" in t && t.contractType.startsWith("KYC_UNDERLYING::");
|
|
44
62
|
}
|
|
63
|
+
/**
|
|
64
|
+
* Returns true if the token is a DSToken, throws if the token data is not loaded
|
|
65
|
+
* @param t
|
|
66
|
+
* @returns
|
|
67
|
+
*/
|
|
68
|
+
isDSToken(t) {
|
|
69
|
+
if (!this.#tokenDataLoaded.has(t.addr)) {
|
|
70
|
+
throw new Error(
|
|
71
|
+
`extended token data not loaded for ${t.symbol} (${t.addr})`
|
|
72
|
+
);
|
|
73
|
+
}
|
|
74
|
+
return !!t.isDSToken;
|
|
75
|
+
}
|
|
45
76
|
/**
|
|
46
77
|
* Returns a map of all phantom tokens
|
|
47
|
-
* Throws if
|
|
78
|
+
* Throws if token data is not loaded
|
|
48
79
|
*/
|
|
49
80
|
get phantomTokens() {
|
|
50
81
|
const result = new AddressMap();
|
|
@@ -55,6 +86,10 @@ class TokensMeta extends AddressMap {
|
|
|
55
86
|
}
|
|
56
87
|
return result;
|
|
57
88
|
}
|
|
89
|
+
/**
|
|
90
|
+
* Returns a map of all KYC underlying tokens
|
|
91
|
+
* Throws if token data is not loaded
|
|
92
|
+
*/
|
|
58
93
|
get kycUnderlyings() {
|
|
59
94
|
const result = new AddressMap();
|
|
60
95
|
for (const [token, meta] of this.entries()) {
|
|
@@ -64,6 +99,15 @@ class TokensMeta extends AddressMap {
|
|
|
64
99
|
}
|
|
65
100
|
return result;
|
|
66
101
|
}
|
|
102
|
+
get dsTokens() {
|
|
103
|
+
const result = new AddressMap();
|
|
104
|
+
for (const [token, meta] of this.entries()) {
|
|
105
|
+
if (this.isDSToken(meta)) {
|
|
106
|
+
result.upsert(token, meta);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
return result;
|
|
110
|
+
}
|
|
67
111
|
formatBN(arg0, arg1, arg2) {
|
|
68
112
|
const token = typeof arg0 === "object" ? arg0.token : arg0;
|
|
69
113
|
const amount = typeof arg0 === "object" ? arg0.balance : arg1;
|
|
@@ -83,7 +127,7 @@ class TokensMeta extends AddressMap {
|
|
|
83
127
|
return meta;
|
|
84
128
|
}
|
|
85
129
|
/**
|
|
86
|
-
* Loads token information about phantom
|
|
130
|
+
* Loads token information about phantom tokens, KYC underlying tokens and DSTokens
|
|
87
131
|
*
|
|
88
132
|
* @param tokens - tokens to load data for, defaults to all tokens
|
|
89
133
|
*/
|
|
@@ -111,10 +155,21 @@ class TokensMeta extends AddressMap {
|
|
|
111
155
|
allowFailure: true,
|
|
112
156
|
batchSize: 0
|
|
113
157
|
});
|
|
158
|
+
this.#logger?.debug(`loaded ${resp.length} contract types`);
|
|
159
|
+
const kycFactories = new AddressSet();
|
|
114
160
|
for (let i = 0; i < tokensToLoad.length; i++) {
|
|
115
|
-
this.#overrideTokenMeta(
|
|
161
|
+
const meta = this.#overrideTokenMeta(
|
|
162
|
+
tokensToLoad[i],
|
|
163
|
+
resp[2 * i],
|
|
164
|
+
resp[2 * i + 1]
|
|
165
|
+
);
|
|
116
166
|
this.#tokenDataLoaded.add(tokensToLoad[i]);
|
|
167
|
+
if (this.isKYCUnderlying(meta)) {
|
|
168
|
+
kycFactories.add(meta.kycFactory);
|
|
169
|
+
}
|
|
117
170
|
}
|
|
171
|
+
this.#logger?.debug(`found ${kycFactories.size} KYC factories`);
|
|
172
|
+
await this.#loadDSTokens(kycFactories);
|
|
118
173
|
}
|
|
119
174
|
#overrideTokenMeta(token, contractTypeResp, serializeResp) {
|
|
120
175
|
const meta = this.mustGet(token);
|
|
@@ -134,7 +189,9 @@ class TokensMeta extends AddressMap {
|
|
|
134
189
|
contractType
|
|
135
190
|
});
|
|
136
191
|
}
|
|
192
|
+
this.#logger?.debug(`token ${meta.symbol} is ${contractType}`);
|
|
137
193
|
}
|
|
194
|
+
return this.mustGet(token);
|
|
138
195
|
}
|
|
139
196
|
#overrideKYCUnderlying(meta, contractType, serialized) {
|
|
140
197
|
if (contractType === KYC_UNDERLYING_DEFAULT) {
|
|
@@ -171,6 +228,72 @@ class TokensMeta extends AddressMap {
|
|
|
171
228
|
});
|
|
172
229
|
}
|
|
173
230
|
}
|
|
231
|
+
async #loadDSTokens(kycFactories) {
|
|
232
|
+
const resp = await this.#client.multicall({
|
|
233
|
+
contracts: kycFactories.map((address) => ({
|
|
234
|
+
address,
|
|
235
|
+
abi: iSecuritizeKYCFactoryAbi,
|
|
236
|
+
functionName: "getDSTokens"
|
|
237
|
+
})),
|
|
238
|
+
allowFailure: false,
|
|
239
|
+
batchSize: 0
|
|
240
|
+
});
|
|
241
|
+
const dsToken = new AddressSet(resp.flat());
|
|
242
|
+
const tokensToLoad = dsToken.difference(new Set(this.keys()));
|
|
243
|
+
this.#logger?.debug(
|
|
244
|
+
`found ${dsToken.size} DSTokens in KYC factories, need to load ${tokensToLoad.size} basic metadata`
|
|
245
|
+
);
|
|
246
|
+
await this.#loadWithoutCompressor(tokensToLoad);
|
|
247
|
+
for (const token of dsToken) {
|
|
248
|
+
const meta = this.mustGet(token);
|
|
249
|
+
this.upsert(token, {
|
|
250
|
+
...meta,
|
|
251
|
+
isDSToken: true
|
|
252
|
+
});
|
|
253
|
+
this.#tokenDataLoaded.add(token);
|
|
254
|
+
this.#logger?.debug(`token ${meta.symbol} (${token}) is a DSToken`);
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
async #loadWithoutCompressor(tokens_) {
|
|
258
|
+
if (tokens_.size === 0) {
|
|
259
|
+
return;
|
|
260
|
+
}
|
|
261
|
+
const tokens = Array.from(tokens_);
|
|
262
|
+
const resp = await this.#client.multicall({
|
|
263
|
+
contracts: tokens.flatMap(
|
|
264
|
+
(t) => [
|
|
265
|
+
{
|
|
266
|
+
address: t,
|
|
267
|
+
abi: erc20Abi,
|
|
268
|
+
functionName: "symbol"
|
|
269
|
+
},
|
|
270
|
+
{
|
|
271
|
+
address: t,
|
|
272
|
+
abi: erc20Abi,
|
|
273
|
+
functionName: "name"
|
|
274
|
+
},
|
|
275
|
+
{
|
|
276
|
+
address: t,
|
|
277
|
+
abi: erc20Abi,
|
|
278
|
+
functionName: "decimals"
|
|
279
|
+
}
|
|
280
|
+
]
|
|
281
|
+
),
|
|
282
|
+
allowFailure: false,
|
|
283
|
+
batchSize: 0
|
|
284
|
+
});
|
|
285
|
+
this.#logger?.debug(
|
|
286
|
+
`loaded ${resp.length} basic metadata without compressor`
|
|
287
|
+
);
|
|
288
|
+
for (let i = 0; i < tokens.length; i++) {
|
|
289
|
+
this.upsert(tokens[i], {
|
|
290
|
+
addr: tokens[i],
|
|
291
|
+
symbol: resp[3 * i],
|
|
292
|
+
name: resp[3 * i + 1],
|
|
293
|
+
decimals: resp[3 * i + 2]
|
|
294
|
+
});
|
|
295
|
+
}
|
|
296
|
+
}
|
|
174
297
|
}
|
|
175
298
|
export {
|
|
176
299
|
TokensMeta
|
|
@@ -9,6 +9,19 @@ class SecuritizeKYCFactory extends BaseContract {
|
|
|
9
9
|
abi
|
|
10
10
|
});
|
|
11
11
|
}
|
|
12
|
+
async precomputeWalletAddress(creditManager, investor) {
|
|
13
|
+
return this.contract.read.precomputeWalletAddress([
|
|
14
|
+
creditManager,
|
|
15
|
+
investor
|
|
16
|
+
]);
|
|
17
|
+
}
|
|
18
|
+
async getWallet(creditAccount) {
|
|
19
|
+
return this.contract.read.getWallet([creditAccount]);
|
|
20
|
+
}
|
|
21
|
+
async getDSTokens() {
|
|
22
|
+
const tokens = await this.contract.read.getDSTokens();
|
|
23
|
+
return [...tokens];
|
|
24
|
+
}
|
|
12
25
|
multicall(creditAccount, calls, tokensToRegister) {
|
|
13
26
|
return this.createRawTx({
|
|
14
27
|
functionName: "multicall",
|
|
@@ -42,6 +42,16 @@ export declare const iSecuritizeKYCFactoryAbi: readonly [{
|
|
|
42
42
|
readonly internalType: "address[]";
|
|
43
43
|
}];
|
|
44
44
|
readonly stateMutability: "view";
|
|
45
|
+
}, {
|
|
46
|
+
readonly type: "function";
|
|
47
|
+
readonly name: "getDSTokens";
|
|
48
|
+
readonly inputs: readonly [];
|
|
49
|
+
readonly outputs: readonly [{
|
|
50
|
+
readonly name: "";
|
|
51
|
+
readonly type: "address[]";
|
|
52
|
+
readonly internalType: "address[]";
|
|
53
|
+
}];
|
|
54
|
+
readonly stateMutability: "view";
|
|
45
55
|
}, {
|
|
46
56
|
readonly type: "function";
|
|
47
57
|
readonly name: "getInvestor";
|
|
@@ -5,7 +5,7 @@ import type { GearboxSDK } from "../GearboxSDK.js";
|
|
|
5
5
|
import { type CreditSuite, type OnDemandPriceUpdates, type PriceUpdateV300, type PriceUpdateV310, type UpdatePriceFeedsResult } from "../market/index.js";
|
|
6
6
|
import { type Asset, type RouterCASlice } from "../router/index.js";
|
|
7
7
|
import type { MultiCall, RawTx } from "../types/index.js";
|
|
8
|
-
import type { AccountToCheck, AddCollateralProps, ChangeDeptProps, ClaimDelayedProps, CloseCreditAccountProps, CloseCreditAccountResult, CloseOptions, CreditAccountOperationResult, EnableTokensProps, ExecuteSwapProps, FullyLiquidateProps, FullyLiquidateResult, GetConnectedBotsResult, GetConnectedMigrationBotsResult, GetCreditAccountsOptions, GetPendingWithdrawalsProps, GetPendingWithdrawalsResult, OpenCAProps, PermitResult, PrepareUpdateQuotasProps, PreviewDelayedWithdrawalProps, PreviewDelayedWithdrawalResult, PriceUpdatesOptions, Rewards, StartDelayedWithdrawalProps, UpdateQuotasProps } from "./types.js";
|
|
8
|
+
import type { AccountToCheck, AddCollateralProps, ChangeDeptProps, ClaimDelayedProps, CloseCreditAccountProps, CloseCreditAccountResult, CloseOptions, CreditAccountOperationResult, EnableTokensProps, ExecuteSwapProps, FullyLiquidateProps, FullyLiquidateResult, GetApprovalAddressProps, GetConnectedBotsResult, GetConnectedMigrationBotsResult, GetCreditAccountsOptions, GetPendingWithdrawalsProps, GetPendingWithdrawalsResult, OpenCAProps, PermitResult, PrepareUpdateQuotasProps, PreviewDelayedWithdrawalProps, PreviewDelayedWithdrawalResult, PriceUpdatesOptions, Rewards, StartDelayedWithdrawalProps, UpdateQuotasProps } from "./types.js";
|
|
9
9
|
export interface CreditAccountServiceOptions {
|
|
10
10
|
batchSize?: number;
|
|
11
11
|
}
|
|
@@ -149,31 +149,25 @@ export declare abstract class AbstractCreditAccountService extends SDKConstruct
|
|
|
149
149
|
* @returns All necessary data to execute the transaction (call, credit facade)
|
|
150
150
|
*/
|
|
151
151
|
enableTokens({ enabledTokens, disabledTokens, creditAccount: ca, }: EnableTokensProps): Promise<CreditAccountOperationResult>;
|
|
152
|
+
/**
|
|
153
|
+
* Returns address to which approval should be given on collateral token
|
|
154
|
+
* It's credit manager for classical markets and special wallet for KYC markets
|
|
155
|
+
* @param options - {@link GetApprovalAddressProps}
|
|
156
|
+
* @returns
|
|
157
|
+
**/
|
|
158
|
+
getApprovalAddress(options: GetApprovalAddressProps): Promise<Address>;
|
|
152
159
|
/**
|
|
153
160
|
* Executes swap specified by given calls, update quotas of affected tokens
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
* @param {bigint} ethAmount - native token amount to attach to tx
|
|
162
|
-
* @param {Address} creditManager - address of credit manager to open credit account on
|
|
163
|
-
* @param {Array<Asset>} collateral - array of collateral which can be just directly added or swapped using the path {@link Asset}
|
|
164
|
-
* @param {Record<Address, PermitResult>} permits - permits of collateral tokens (in any permittable token is present) {@link PermitResult}
|
|
165
|
-
* @param {bigint} debt - debt to open credit account with
|
|
166
|
-
* @param {boolean} withdrawDebt - flag to withdraw debt to wallet after opening credit account;
|
|
167
|
-
used for borrowing functionality
|
|
168
|
-
* @param {bigint} referralCode - referral code to open credit account with
|
|
169
|
-
* @param {Address} to - wallet address to transfer credit account to\
|
|
170
|
-
* @param {Array<MultiCall>} calls - array of MultiCall from router methods findOpenStrategyPath {@link MultiCall}.
|
|
171
|
-
Used for trading and strategy functionality
|
|
172
|
-
* @param {Array<Asset>} averageQuota - average quota for tokens after open {@link Asset}
|
|
173
|
-
* @param {Array<Asset>} minQuota - minimum quota for tokens after open {@link Asset}
|
|
161
|
+
* - Open credit account is executed in the following order: price update -> increase debt -> add collateral ->
|
|
162
|
+
* -> update quotas -> (optionally: execute swap path for trading/strategy) ->
|
|
163
|
+
* -> (optionally: withdraw debt for lending)
|
|
164
|
+
*- Basic open credit account: price update -> increase debt -> add collateral -> update quotas
|
|
165
|
+
*- Lending: price update -> increase debt -> add collateral -> update quotas -> withdraw debt
|
|
166
|
+
*- Strategy/trading: price update -> increase debt -> add collateral -> update quotas -> execute swap path
|
|
167
|
+
*- In strategy is possible situation when collateral is added, but not swapped; the only swapped value in this case will be debt
|
|
174
168
|
* @returns All necessary data to execute the transaction (call, credit facade)
|
|
175
|
-
|
|
176
|
-
openCA(
|
|
169
|
+
**/
|
|
170
|
+
openCA(props: OpenCAProps): Promise<CreditAccountOperationResult>;
|
|
177
171
|
/**
|
|
178
172
|
* Returns borrow rate with 4 digits precision (10000 = 100%)
|
|
179
173
|
* @param ca
|
|
@@ -291,6 +291,10 @@ export interface OpenCAProps extends PrepareUpdateQuotasProps {
|
|
|
291
291
|
* Address of credit manager to open credit account on
|
|
292
292
|
*/
|
|
293
293
|
creditManager: Address;
|
|
294
|
+
/**
|
|
295
|
+
* Optional address of credit account to reopen
|
|
296
|
+
*/
|
|
297
|
+
reopenCreditAccount?: Address;
|
|
294
298
|
/**
|
|
295
299
|
* Wallet address to transfer credit account to
|
|
296
300
|
*/
|
|
@@ -435,6 +439,16 @@ export interface LlamathenaProportionalWithdrawProps extends PrepareUpdateQuotas
|
|
|
435
439
|
*/
|
|
436
440
|
creditAccount: RouterCASlice;
|
|
437
441
|
}
|
|
442
|
+
/**
|
|
443
|
+
* Options to get approval address for collateral token
|
|
444
|
+
*/
|
|
445
|
+
export type GetApprovalAddressProps = {
|
|
446
|
+
creditManager: Address;
|
|
447
|
+
borrower: Address;
|
|
448
|
+
} | {
|
|
449
|
+
creditManager: Address;
|
|
450
|
+
creditAccount: Address;
|
|
451
|
+
};
|
|
438
452
|
export interface ICreditAccountsService extends Construct {
|
|
439
453
|
sdk: GearboxSDK;
|
|
440
454
|
/**
|
|
@@ -553,6 +567,13 @@ export interface ICreditAccountsService extends Construct {
|
|
|
553
567
|
* @returns All necessary data to execute the transaction (call, credit facade)
|
|
554
568
|
*/
|
|
555
569
|
enableTokens(props: EnableTokensProps): Promise<CreditAccountOperationResult>;
|
|
570
|
+
/**
|
|
571
|
+
* Returns address to which approval should be given on collateral token
|
|
572
|
+
* It's credit manager for classical markets and special wallet for KYC markets
|
|
573
|
+
* @param props - {@link GetApprovalAddressProps}
|
|
574
|
+
* @returns
|
|
575
|
+
*/
|
|
576
|
+
getApprovalAddress(props: GetApprovalAddressProps): Promise<Address>;
|
|
556
577
|
/**
|
|
557
578
|
* Executes swap specified by given calls, update quotas of affected tokens
|
|
558
579
|
* - Open credit account is executed in the following order: price update -> increase debt -> add collateral ->
|
|
@@ -1,31 +1,53 @@
|
|
|
1
1
|
import { type Address, type Chain, type PublicClient, type Transport } from "viem";
|
|
2
2
|
import type { Asset } from "../router/index.js";
|
|
3
|
+
import type { ILogger } from "../types/logger.js";
|
|
3
4
|
import { AddressMap } from "../utils/index.js";
|
|
4
|
-
import type
|
|
5
|
+
import { type DSTokenMeta, type KYCTokenMeta, type PhantomTokenMeta, type TokenMetaData } from "./token-types.js";
|
|
5
6
|
export interface FormatBNOptions {
|
|
6
7
|
precision?: number;
|
|
7
8
|
symbol?: boolean;
|
|
8
9
|
}
|
|
9
10
|
export declare class TokensMeta extends AddressMap<TokenMetaData> {
|
|
10
11
|
#private;
|
|
11
|
-
constructor(client: PublicClient<Transport, Chain
|
|
12
|
+
constructor(client: PublicClient<Transport, Chain>, logger?: ILogger);
|
|
12
13
|
reset(): void;
|
|
13
14
|
symbol(token: Address): string;
|
|
14
15
|
decimals(token: Address): number;
|
|
16
|
+
/**
|
|
17
|
+
* Returns true if the token is a phantom token, throws if the token data is not loaded
|
|
18
|
+
* @param t
|
|
19
|
+
* @returns
|
|
20
|
+
*/
|
|
15
21
|
isPhantomToken(t: TokenMetaData): t is PhantomTokenMeta;
|
|
22
|
+
/**
|
|
23
|
+
* Returns true if the token is a KYC underlying token, throws if the token data is not loaded
|
|
24
|
+
* @param t
|
|
25
|
+
* @returns
|
|
26
|
+
*/
|
|
16
27
|
isKYCUnderlying(t: TokenMetaData): t is KYCTokenMeta;
|
|
28
|
+
/**
|
|
29
|
+
* Returns true if the token is a DSToken, throws if the token data is not loaded
|
|
30
|
+
* @param t
|
|
31
|
+
* @returns
|
|
32
|
+
*/
|
|
33
|
+
isDSToken(t: TokenMetaData): t is DSTokenMeta;
|
|
17
34
|
/**
|
|
18
35
|
* Returns a map of all phantom tokens
|
|
19
|
-
* Throws if
|
|
36
|
+
* Throws if token data is not loaded
|
|
20
37
|
*/
|
|
21
38
|
get phantomTokens(): AddressMap<PhantomTokenMeta>;
|
|
39
|
+
/**
|
|
40
|
+
* Returns a map of all KYC underlying tokens
|
|
41
|
+
* Throws if token data is not loaded
|
|
42
|
+
*/
|
|
22
43
|
get kycUnderlyings(): AddressMap<KYCTokenMeta>;
|
|
44
|
+
get dsTokens(): AddressMap<DSTokenMeta>;
|
|
23
45
|
formatBN(asset: Asset, options?: FormatBNOptions): string;
|
|
24
46
|
formatBN(token: Address, amount: number | bigint | string | undefined, options?: FormatBNOptions): string;
|
|
25
47
|
findBySymbol(symbol: string): TokenMetaData | undefined;
|
|
26
48
|
mustFindBySymbol(symbol: string): TokenMetaData;
|
|
27
49
|
/**
|
|
28
|
-
* Loads token information about phantom
|
|
50
|
+
* Loads token information about phantom tokens, KYC underlying tokens and DSTokens
|
|
29
51
|
*
|
|
30
52
|
* @param tokens - tokens to load data for, defaults to all tokens
|
|
31
53
|
*/
|
|
@@ -1,11 +1,14 @@
|
|
|
1
1
|
import type { Address } from "viem";
|
|
2
2
|
import type { MarketData, Unarray } from "./types.js";
|
|
3
|
-
|
|
3
|
+
type TokenData = Unarray<MarketData["tokens"]>;
|
|
4
4
|
export declare const PHANTOM_TOKEN_CONTRACT_TYPES: readonly ["PHANTOM_TOKEN::CONVEX", "PHANTOM_TOKEN::INFINIFI_UNWIND", "PHANTOM_TOKEN::INFRARED", "PHANTOM_TOKEN::MELLOW_WITHDRAWAL", "PHANTOM_TOKEN::MIDAS_REDEMPTION", "PHANTOM_TOKEN::STAKING_REWARDS", "PHANTOM_TOKEN::UPSHIFT_WITHDRAW"];
|
|
5
5
|
export declare const KYC_UNDERLYING_DEFAULT = "KYC_UNDERLYING::DEFAULT";
|
|
6
6
|
export declare const KYC_UNDERLYING_ON_DEMAND = "KYC_UNDERLYING::ON_DEMAND";
|
|
7
7
|
export type KYCUnderlyingContractType = typeof KYC_UNDERLYING_DEFAULT | typeof KYC_UNDERLYING_ON_DEMAND;
|
|
8
8
|
export type PhantomTokenContractType = (typeof PHANTOM_TOKEN_CONTRACT_TYPES)[number];
|
|
9
|
+
export type SimpleTokenMeta = TokenData & {
|
|
10
|
+
isDSToken?: boolean;
|
|
11
|
+
};
|
|
9
12
|
export type PhantomTokenMeta = SimpleTokenMeta & {
|
|
10
13
|
contractType: PhantomTokenContractType;
|
|
11
14
|
};
|
|
@@ -21,5 +24,9 @@ export type KYCOnDemandTokenMeta = SimpleTokenMeta & {
|
|
|
21
24
|
pool: Address;
|
|
22
25
|
liquidityProvider: Address;
|
|
23
26
|
};
|
|
27
|
+
export type DSTokenMeta = Omit<SimpleTokenMeta, "isDSToken"> & {
|
|
28
|
+
isDSToken: true;
|
|
29
|
+
};
|
|
24
30
|
export type KYCTokenMeta = KYCDefaultTokenMeta | KYCOnDemandTokenMeta;
|
|
25
|
-
export type TokenMetaData = SimpleTokenMeta | PhantomTokenMeta | KYCTokenMeta;
|
|
31
|
+
export type TokenMetaData = SimpleTokenMeta | PhantomTokenMeta | KYCTokenMeta | DSTokenMeta;
|
|
32
|
+
export {};
|
|
@@ -46,6 +46,16 @@ declare const abi: readonly [{
|
|
|
46
46
|
readonly internalType: "address[]";
|
|
47
47
|
}];
|
|
48
48
|
readonly stateMutability: "view";
|
|
49
|
+
}, {
|
|
50
|
+
readonly type: "function";
|
|
51
|
+
readonly name: "getDSTokens";
|
|
52
|
+
readonly inputs: readonly [];
|
|
53
|
+
readonly outputs: readonly [{
|
|
54
|
+
readonly name: "";
|
|
55
|
+
readonly type: "address[]";
|
|
56
|
+
readonly internalType: "address[]";
|
|
57
|
+
}];
|
|
58
|
+
readonly stateMutability: "view";
|
|
49
59
|
}, {
|
|
50
60
|
readonly type: "function";
|
|
51
61
|
readonly name: "getInvestor";
|
|
@@ -426,6 +436,9 @@ declare const abi: readonly [{
|
|
|
426
436
|
type abi = typeof abi;
|
|
427
437
|
export declare class SecuritizeKYCFactory extends BaseContract<abi> {
|
|
428
438
|
constructor(options: ConstructOptions, address: Address);
|
|
439
|
+
precomputeWalletAddress(creditManager: Address, investor: Address): Promise<Address>;
|
|
440
|
+
getWallet(creditAccount: Address): Promise<Address>;
|
|
441
|
+
getDSTokens(): Promise<Address[]>;
|
|
429
442
|
multicall(creditAccount: Address, calls: MultiCall[], tokensToRegister: Address[]): RawTx;
|
|
430
443
|
openCreditAccount(creditManager: Address, calls: MultiCall[], tokensToRegister: Address[]): RawTx;
|
|
431
444
|
}
|