@fepvenancio/stela-sdk 0.8.1 → 0.10.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/dist/index.cjs +177 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +173 -2
- package/dist/index.d.ts +173 -2
- package/dist/index.js +168 -2
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -258,11 +258,35 @@ var TOKENS = [
|
|
|
258
258
|
addresses: {
|
|
259
259
|
sepolia: "0x04f2345306bf8ef1c8c1445661354ef08421aa092459445a5d6b46641237e943"
|
|
260
260
|
}
|
|
261
|
+
},
|
|
262
|
+
// NFT Collections (ERC721)
|
|
263
|
+
{
|
|
264
|
+
symbol: "GENESIS",
|
|
265
|
+
name: "Stela Genesis",
|
|
266
|
+
decimals: 0,
|
|
267
|
+
assetType: "ERC721",
|
|
268
|
+
addresses: {
|
|
269
|
+
sepolia: "0x0265ea52ffbf1b7e1a029b94fe1a2023899dd0bc02eb1f11c9b04ea90e957d28"
|
|
270
|
+
}
|
|
271
|
+
},
|
|
272
|
+
{
|
|
273
|
+
symbol: "MockNFT",
|
|
274
|
+
name: "Mock ERC721",
|
|
275
|
+
decimals: 0,
|
|
276
|
+
assetType: "ERC721",
|
|
277
|
+
addresses: {
|
|
278
|
+
sepolia: "0x032bfd52134ad92beae1bc5018a3748e1d1240efd627220e314c07e4c63433d5"
|
|
279
|
+
}
|
|
261
280
|
}
|
|
262
281
|
];
|
|
263
282
|
function normalizeHex(addr) {
|
|
264
283
|
return "0x" + addr.replace(/^0x0*/i, "").toLowerCase();
|
|
265
284
|
}
|
|
285
|
+
function getNFTCollections(network) {
|
|
286
|
+
return TOKENS.filter(
|
|
287
|
+
(t) => t.assetType === "ERC721" && t.addresses[network] !== void 0
|
|
288
|
+
);
|
|
289
|
+
}
|
|
266
290
|
function getTokensForNetwork(network) {
|
|
267
291
|
return TOKENS.filter((t) => t.addresses[network] !== void 0);
|
|
268
292
|
}
|
|
@@ -288,6 +312,74 @@ function sharesToPercentage(shares, totalSupply, currentIssuedPercentage) {
|
|
|
288
312
|
function calculateFeeShares(shares, feeBps) {
|
|
289
313
|
return shares * feeBps / MAX_BPS;
|
|
290
314
|
}
|
|
315
|
+
function divCeil(a, b) {
|
|
316
|
+
if (a === 0n) return 0n;
|
|
317
|
+
return (a + b - 1n) / b;
|
|
318
|
+
}
|
|
319
|
+
function proRataInterest(amount, elapsed, duration) {
|
|
320
|
+
if (amount === 0n || elapsed === 0n) return 0n;
|
|
321
|
+
if (elapsed >= duration) return amount;
|
|
322
|
+
return divCeil(amount * elapsed, duration);
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
// src/math/position.ts
|
|
326
|
+
var DEFAULT_DUST_BUFFER_SECONDS = 60n;
|
|
327
|
+
function shareProportionBps(shares, totalSupply) {
|
|
328
|
+
if (totalSupply === 0n) return 0n;
|
|
329
|
+
return shares * MAX_BPS / totalSupply;
|
|
330
|
+
}
|
|
331
|
+
function proportionalAssetValue(assetValue, shares, totalSupply) {
|
|
332
|
+
if (totalSupply === 0n || shares === 0n) return 0n;
|
|
333
|
+
return assetValue * shares / totalSupply;
|
|
334
|
+
}
|
|
335
|
+
function computePositionValue(params) {
|
|
336
|
+
const { shares, totalSupply, elapsed, duration } = params;
|
|
337
|
+
const shareBps = shareProportionBps(shares, totalSupply);
|
|
338
|
+
const debt = params.debtAssets.map((asset) => ({
|
|
339
|
+
asset,
|
|
340
|
+
proportionalValue: proportionalAssetValue(asset.value, shares, totalSupply)
|
|
341
|
+
}));
|
|
342
|
+
const interest = params.interestAssets.map((asset) => {
|
|
343
|
+
const fullInterest = proportionalAssetValue(asset.value, shares, totalSupply);
|
|
344
|
+
const accruedInterest = duration === 0n ? fullInterest : proRataInterest(fullInterest, elapsed, duration);
|
|
345
|
+
return { asset, fullInterest, accruedInterest };
|
|
346
|
+
});
|
|
347
|
+
const collateral = params.collateralAssets.map((asset) => ({
|
|
348
|
+
asset,
|
|
349
|
+
proportionalValue: proportionalAssetValue(asset.value, shares, totalSupply)
|
|
350
|
+
}));
|
|
351
|
+
return {
|
|
352
|
+
inscriptionId: params.inscriptionId,
|
|
353
|
+
shares,
|
|
354
|
+
totalSupply,
|
|
355
|
+
shareBps,
|
|
356
|
+
debt,
|
|
357
|
+
interest,
|
|
358
|
+
collateral,
|
|
359
|
+
accrued: interest,
|
|
360
|
+
elapsed,
|
|
361
|
+
duration
|
|
362
|
+
};
|
|
363
|
+
}
|
|
364
|
+
function accruedInterestWithBuffer(amount, elapsed, duration, bufferSeconds = DEFAULT_DUST_BUFFER_SECONDS) {
|
|
365
|
+
if (duration === 0n) return amount;
|
|
366
|
+
const bufferedElapsed = elapsed + bufferSeconds;
|
|
367
|
+
return proRataInterest(amount, bufferedElapsed, duration);
|
|
368
|
+
}
|
|
369
|
+
function computeSafePositionFloor(params) {
|
|
370
|
+
const { shares, totalSupply, elapsed, duration } = params;
|
|
371
|
+
const buffer = params.bufferSeconds ?? DEFAULT_DUST_BUFFER_SECONDS;
|
|
372
|
+
const debtFloor = params.debtAssets.map((asset) => ({
|
|
373
|
+
asset,
|
|
374
|
+
proportionalValue: proportionalAssetValue(asset.value, shares, totalSupply)
|
|
375
|
+
}));
|
|
376
|
+
const interestFloor = params.interestAssets.map((asset) => {
|
|
377
|
+
const fullInterest = proportionalAssetValue(asset.value, shares, totalSupply);
|
|
378
|
+
const safeAccrued = accruedInterestWithBuffer(fullInterest, elapsed, duration, buffer);
|
|
379
|
+
return { asset, proportionalValue: safeAccrued };
|
|
380
|
+
});
|
|
381
|
+
return { debtFloor, interestFloor };
|
|
382
|
+
}
|
|
291
383
|
var SELECTORS = {
|
|
292
384
|
InscriptionCreated: starknet.hash.getSelectorFromName("InscriptionCreated"),
|
|
293
385
|
InscriptionSigned: starknet.hash.getSelectorFromName("InscriptionSigned"),
|
|
@@ -751,6 +843,27 @@ function getRefinanceApprovalTypedData(params) {
|
|
|
751
843
|
}
|
|
752
844
|
};
|
|
753
845
|
}
|
|
846
|
+
function getTermsAcknowledgmentTypedData(params) {
|
|
847
|
+
return {
|
|
848
|
+
types: {
|
|
849
|
+
StarknetDomain: STARKNET_DOMAIN_TYPE,
|
|
850
|
+
TermsAcknowledgment: [
|
|
851
|
+
{ name: "user", type: "ContractAddress" },
|
|
852
|
+
{ name: "terms_version", type: "shortstring" },
|
|
853
|
+
{ name: "terms_hash", type: "felt" },
|
|
854
|
+
{ name: "agreed_at", type: "u128" }
|
|
855
|
+
]
|
|
856
|
+
},
|
|
857
|
+
primaryType: "TermsAcknowledgment",
|
|
858
|
+
domain: { ...STELA_DOMAIN, chainId: params.chainId },
|
|
859
|
+
message: {
|
|
860
|
+
user: params.user,
|
|
861
|
+
terms_version: params.termsVersion,
|
|
862
|
+
terms_hash: params.termsHash,
|
|
863
|
+
agreed_at: params.agreedAt.toString()
|
|
864
|
+
}
|
|
865
|
+
};
|
|
866
|
+
}
|
|
754
867
|
|
|
755
868
|
// src/offchain/signature.ts
|
|
756
869
|
function serializeSignature(sig) {
|
|
@@ -3470,9 +3583,14 @@ function extractFieldU256(val) {
|
|
|
3470
3583
|
}
|
|
3471
3584
|
var ShareClient = class {
|
|
3472
3585
|
contract;
|
|
3586
|
+
address;
|
|
3587
|
+
account;
|
|
3473
3588
|
constructor(opts) {
|
|
3589
|
+
this.address = opts.stelaAddress;
|
|
3474
3590
|
this.contract = new starknet.Contract(stela_default, opts.stelaAddress, opts.provider);
|
|
3591
|
+
this.account = opts.account;
|
|
3475
3592
|
}
|
|
3593
|
+
// ── Read Methods ───────────────────────────────────────────────────
|
|
3476
3594
|
/** Get share balance for an account on a specific inscription */
|
|
3477
3595
|
async balanceOf(account, inscriptionId) {
|
|
3478
3596
|
const result = await this.contract.call("balance_of", [account, ...toU256(inscriptionId)]);
|
|
@@ -3496,6 +3614,53 @@ var ShareClient = class {
|
|
|
3496
3614
|
const result = await this.contract.call("is_approved_for_all", [owner, operator]);
|
|
3497
3615
|
return Boolean(result[0]);
|
|
3498
3616
|
}
|
|
3617
|
+
// ── Call Builders ──────────────────────────────────────────────────
|
|
3618
|
+
/**
|
|
3619
|
+
* Build a call to transfer shares (ERC1155 safeTransferFrom).
|
|
3620
|
+
* This enables secondary market trading of lending positions.
|
|
3621
|
+
*
|
|
3622
|
+
* @param from - Current share holder
|
|
3623
|
+
* @param to - Recipient address
|
|
3624
|
+
* @param inscriptionId - The inscription (token ID)
|
|
3625
|
+
* @param amount - Number of shares to transfer
|
|
3626
|
+
* @param data - Optional calldata (empty array by default)
|
|
3627
|
+
*/
|
|
3628
|
+
buildTransferShares(from, to, inscriptionId, amount, data = []) {
|
|
3629
|
+
return {
|
|
3630
|
+
contractAddress: this.address,
|
|
3631
|
+
entrypoint: "safe_transfer_from",
|
|
3632
|
+
calldata: [from, to, ...toU256(inscriptionId), ...toU256(amount), String(data.length), ...data]
|
|
3633
|
+
};
|
|
3634
|
+
}
|
|
3635
|
+
/**
|
|
3636
|
+
* Build a call to approve an operator for all ERC1155 tokens.
|
|
3637
|
+
* Required before a marketplace contract can transfer shares on your behalf.
|
|
3638
|
+
*
|
|
3639
|
+
* @param operator - The address to approve (e.g., marketplace contract)
|
|
3640
|
+
* @param approved - Whether to approve or revoke
|
|
3641
|
+
*/
|
|
3642
|
+
buildSetApprovalForAll(operator, approved) {
|
|
3643
|
+
return {
|
|
3644
|
+
contractAddress: this.address,
|
|
3645
|
+
entrypoint: "set_approval_for_all",
|
|
3646
|
+
calldata: [operator, approved ? "1" : "0"]
|
|
3647
|
+
};
|
|
3648
|
+
}
|
|
3649
|
+
// ── Execute Methods ────────────────────────────────────────────────
|
|
3650
|
+
/** Transfer shares to another address */
|
|
3651
|
+
async transferShares(from, to, inscriptionId, amount, data = []) {
|
|
3652
|
+
if (!this.account) throw new Error("Account required for write operations");
|
|
3653
|
+
const result = await this.account.execute([
|
|
3654
|
+
this.buildTransferShares(from, to, inscriptionId, amount, data)
|
|
3655
|
+
]);
|
|
3656
|
+
return { transaction_hash: result.transaction_hash };
|
|
3657
|
+
}
|
|
3658
|
+
/** Approve or revoke an operator for all ERC1155 tokens */
|
|
3659
|
+
async setApprovalForAll(operator, approved) {
|
|
3660
|
+
if (!this.account) throw new Error("Account required for write operations");
|
|
3661
|
+
const result = await this.account.execute([this.buildSetApprovalForAll(operator, approved)]);
|
|
3662
|
+
return { transaction_hash: result.transaction_hash };
|
|
3663
|
+
}
|
|
3499
3664
|
};
|
|
3500
3665
|
function extractBigInt(result) {
|
|
3501
3666
|
const arr = result;
|
|
@@ -3780,7 +3945,8 @@ var StelaSdk = class {
|
|
|
3780
3945
|
});
|
|
3781
3946
|
this.shares = new ShareClient({
|
|
3782
3947
|
stelaAddress: this.stelaAddress,
|
|
3783
|
-
provider: opts.provider
|
|
3948
|
+
provider: opts.provider,
|
|
3949
|
+
account: opts.account
|
|
3784
3950
|
});
|
|
3785
3951
|
const stelaContract = new starknet.Contract(stela_default, this.stelaAddress, opts.provider);
|
|
3786
3952
|
this.locker = new LockerClient(stelaContract, opts.provider, opts.account);
|
|
@@ -3796,6 +3962,7 @@ exports.AUCTION_RESERVE_BPS = AUCTION_RESERVE_BPS;
|
|
|
3796
3962
|
exports.ApiClient = ApiClient;
|
|
3797
3963
|
exports.ApiError = ApiError;
|
|
3798
3964
|
exports.CHAIN_ID = CHAIN_ID;
|
|
3965
|
+
exports.DEFAULT_DUST_BUFFER_SECONDS = DEFAULT_DUST_BUFFER_SECONDS;
|
|
3799
3966
|
exports.EXPLORER_TX_URL = EXPLORER_TX_URL;
|
|
3800
3967
|
exports.GRACE_PERIOD = GRACE_PERIOD;
|
|
3801
3968
|
exports.InscriptionClient = InscriptionClient;
|
|
@@ -3809,11 +3976,15 @@ exports.StelaSdk = StelaSdk;
|
|
|
3809
3976
|
exports.TOKENS = TOKENS;
|
|
3810
3977
|
exports.VALID_STATUSES = VALID_STATUSES;
|
|
3811
3978
|
exports.VIRTUAL_SHARE_OFFSET = VIRTUAL_SHARE_OFFSET;
|
|
3979
|
+
exports.accruedInterestWithBuffer = accruedInterestWithBuffer;
|
|
3812
3980
|
exports.addressesEqual = addressesEqual;
|
|
3813
3981
|
exports.calculateFeeShares = calculateFeeShares;
|
|
3982
|
+
exports.computePositionValue = computePositionValue;
|
|
3983
|
+
exports.computeSafePositionFloor = computeSafePositionFloor;
|
|
3814
3984
|
exports.computeStatus = computeStatus;
|
|
3815
3985
|
exports.convertToShares = convertToShares;
|
|
3816
3986
|
exports.deserializeSignature = deserializeSignature;
|
|
3987
|
+
exports.divCeil = divCeil;
|
|
3817
3988
|
exports.findTokenByAddress = findTokenByAddress;
|
|
3818
3989
|
exports.formatAddress = formatAddress;
|
|
3819
3990
|
exports.formatDuration = formatDuration;
|
|
@@ -3826,9 +3997,11 @@ exports.getCollectionBorrowAcceptanceTypedData = getCollectionBorrowAcceptanceTy
|
|
|
3826
3997
|
exports.getCollectionLendOfferTypedData = getCollectionLendOfferTypedData;
|
|
3827
3998
|
exports.getInscriptionOrderTypedData = getInscriptionOrderTypedData;
|
|
3828
3999
|
exports.getLendOfferTypedData = getLendOfferTypedData;
|
|
4000
|
+
exports.getNFTCollections = getNFTCollections;
|
|
3829
4001
|
exports.getRefinanceApprovalTypedData = getRefinanceApprovalTypedData;
|
|
3830
4002
|
exports.getRefinanceOfferTypedData = getRefinanceOfferTypedData;
|
|
3831
4003
|
exports.getRenegotiationProposalTypedData = getRenegotiationProposalTypedData;
|
|
4004
|
+
exports.getTermsAcknowledgmentTypedData = getTermsAcknowledgmentTypedData;
|
|
3832
4005
|
exports.getTokensForNetwork = getTokensForNetwork;
|
|
3833
4006
|
exports.hashAssets = hashAssets;
|
|
3834
4007
|
exports.hashBatchEntries = hashBatchEntries;
|
|
@@ -3837,9 +4010,12 @@ exports.normalizeAddress = normalizeAddress;
|
|
|
3837
4010
|
exports.parseAmount = parseAmount;
|
|
3838
4011
|
exports.parseEvent = parseEvent;
|
|
3839
4012
|
exports.parseEvents = parseEvents;
|
|
4013
|
+
exports.proRataInterest = proRataInterest;
|
|
4014
|
+
exports.proportionalAssetValue = proportionalAssetValue;
|
|
3840
4015
|
exports.resolveNetwork = resolveNetwork;
|
|
3841
4016
|
exports.scaleByPercentage = scaleByPercentage;
|
|
3842
4017
|
exports.serializeSignature = serializeSignature;
|
|
4018
|
+
exports.shareProportionBps = shareProportionBps;
|
|
3843
4019
|
exports.sharesToPercentage = sharesToPercentage;
|
|
3844
4020
|
exports.toHex = toHex;
|
|
3845
4021
|
exports.toU256 = toU256;
|