From 14e025c07b53756af73d2761f60a0afebdbf6c93 Mon Sep 17 00:00:00 2001 From: rohannero Date: Wed, 4 Feb 2026 16:07:53 -0500 Subject: [PATCH 1/5] WIP: refactor --- projects/linx/index.js | 107 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 107 insertions(+) create mode 100644 projects/linx/index.js diff --git a/projects/linx/index.js b/projects/linx/index.js new file mode 100644 index 00000000000..e63c1f4bd14 --- /dev/null +++ b/projects/linx/index.js @@ -0,0 +1,107 @@ +const alephium = require('../helper/chain/alephium'); +const { get } = require('../helper/http'); + +const config = { + linx: "vQcfta4Mm32L7Xsb7tYF2rrR76JWxjNv3oia8GPK6x71", + nodeApiHost: "https://node.mainnet.alephium.org", +} + +const ALPH_TOKEN_ID = '0000000000000000000000000000000000000000000000000000000000000000'; + +const MARKET_CREATED_EVENT_INDEX = 4; +const MARKET_METHOD_INDEX = 4; + +async function getEvents(contractAddress) { + let events = []; + let start = 0; + const limit = 100; + + while (true) { + const response = await get(`${config.nodeApiHost}/events/contract/${contractAddress}?start=${start}&limit=${limit}`); + events = events.concat(response.events); + if (!response.events.length || response.nextStart === undefined) break; + start = response.nextStart; + } + return events; +} + +async function getMarkets() { + const events = await getEvents(config.linx); + let markets = events.filter(e => e.eventIndex === MARKET_CREATED_EVENT_INDEX).map(event => { + const marketId = event.fields[0].value; + const contractId = event.fields[1].value; + const loanTokenId = event.fields[2].value; + const collateralTokenId = event.fields[3].value; + + return { marketId, contractId, loanTokenId, collateralTokenId }; + }); + + markets = Array.from(new Map(markets.map(m => [m.marketId, m])).values()); + return markets; +} + +async function getLockedCollateral(marketContractId, collateralTokenId) { + const contractAddress = alephium.addressFromContractId(marketContractId); + if (collateralTokenId === ALPH_TOKEN_ID) { + return BigInt((await alephium.getAlphBalance(contractAddress)).balance); + } else { + const tokensBalance = await alephium.getTokensBalance(contractAddress); + const tokenBalance = tokensBalance.find(b => b.tokenId === collateralTokenId); + return BigInt(tokenBalance?.balance ?? 0); + } +} + +async function getMarketState(marketId) { + const contractCalls = [{ + group: 0, + address: config.linx, + methodIndex: MARKET_METHOD_INDEX, + args: [{ type: "ByteVec", value: marketId }] + }] + const results = await alephium.contractMultiCall(contractCalls); + return { + totalSupplyAssets: BigInt(results[0].returns[0].value), + totalSupplyShares: BigInt(results[0].returns[1].value), + totalBorrowAssets: BigInt(results[0].returns[2].value), + totalBorrowShares: BigInt(results[0].returns[3].value), + lastUpdate: BigInt(results[0].returns[4].value), + fee: BigInt(results[0].returns[5].value) + }; +} + +async function tvl(api) { + const markets = await getMarkets(); + const tokenAmounts = new Map(); + for (const market of markets) { + const state = await getMarketState(market.marketId); + const idleSupply = state.totalSupplyAssets - state.totalBorrowAssets; + const collateral = await getLockedCollateral(market.contractId, market.collateralTokenId); + tokenAmounts.set(market.collateralTokenId, (tokenAmounts.get(market.collateralTokenId) ?? BigInt(0)) + collateral); + tokenAmounts.set(market.loanTokenId, (tokenAmounts.get(market.loanTokenId) ?? BigInt(0)) + idleSupply); + } + + for (const [tokenId, amount] of tokenAmounts.entries()) { + api.add(tokenId, amount); + } +} + +async function borrowed(api) { + const markets = await getMarkets(); + const tokenAmounts = new Map(); + for (const market of markets) { + const state = await getMarketState(market.marketId); + const borrowAssets = state.totalBorrowAssets; + tokenAmounts.set(market.loanTokenId, (tokenAmounts.get(market.loanTokenId) ?? BigInt(0)) + borrowAssets); + } + + for (const [tokenId, amount] of tokenAmounts.entries()) { + api.add(tokenId, amount); + } +} + +module.exports = { + alephium: { + tvl, + borrowed + } +}; \ No newline at end of file From b7db84f1739d6ca9c343473c7f3b9aa2ea02e4fc Mon Sep 17 00:00:00 2001 From: rohannero Date: Wed, 4 Feb 2026 16:16:07 -0500 Subject: [PATCH 2/5] get tvl from bal --- projects/linx/index.js | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/projects/linx/index.js b/projects/linx/index.js index e63c1f4bd14..727bb66ca0a 100644 --- a/projects/linx/index.js +++ b/projects/linx/index.js @@ -40,13 +40,13 @@ async function getMarkets() { return markets; } -async function getLockedCollateral(marketContractId, collateralTokenId) { +async function getTokenBalance(marketContractId, tokenId) { const contractAddress = alephium.addressFromContractId(marketContractId); - if (collateralTokenId === ALPH_TOKEN_ID) { + if (tokenId === ALPH_TOKEN_ID) { return BigInt((await alephium.getAlphBalance(contractAddress)).balance); } else { const tokensBalance = await alephium.getTokensBalance(contractAddress); - const tokenBalance = tokensBalance.find(b => b.tokenId === collateralTokenId); + const tokenBalance = tokensBalance.find(b => b.tokenId === tokenId); return BigInt(tokenBalance?.balance ?? 0); } } @@ -73,11 +73,10 @@ async function tvl(api) { const markets = await getMarkets(); const tokenAmounts = new Map(); for (const market of markets) { - const state = await getMarketState(market.marketId); - const idleSupply = state.totalSupplyAssets - state.totalBorrowAssets; - const collateral = await getLockedCollateral(market.contractId, market.collateralTokenId); + const collateral = await getTokenBalance(market.contractId, market.collateralTokenId); + const loanBalance = await getTokenBalance(market.contractId, market.loanTokenId); tokenAmounts.set(market.collateralTokenId, (tokenAmounts.get(market.collateralTokenId) ?? BigInt(0)) + collateral); - tokenAmounts.set(market.loanTokenId, (tokenAmounts.get(market.loanTokenId) ?? BigInt(0)) + idleSupply); + tokenAmounts.set(market.loanTokenId, (tokenAmounts.get(market.loanTokenId) ?? BigInt(0)) + loanBalance); } for (const [tokenId, amount] of tokenAmounts.entries()) { From 7c52480ad501f287af717fb5a36ddfdf0f19acc8 Mon Sep 17 00:00:00 2001 From: rohannero Date: Wed, 4 Feb 2026 16:25:40 -0500 Subject: [PATCH 3/5] cg mapping --- projects/helper/tokenMapping.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/projects/helper/tokenMapping.js b/projects/helper/tokenMapping.js index 7e4c7429694..728b4d7582a 100644 --- a/projects/helper/tokenMapping.js +++ b/projects/helper/tokenMapping.js @@ -107,6 +107,11 @@ const fixBalancesTokens = { '0x2a25fbD67b3aE485e461fe55d9DbeF302B7D3989': { coingeckoId: 'usd-coin', decimals: 6 }, '0x83A15000b753AC0EeE06D2Cb41a69e76D0D5c7F7': { coingeckoId: 'ethereum', decimals: 18 }, }, + alephium: { + '383bc735a4de6722af80546ec9eeb3cff508f2f68e97da19489ce69f3e703200': { coingeckoId: 'wrapped-bitcoin', decimals: 8 }, + '722954d9067c5a5ad532746a024f2a9d7a18ed9b90e27d0a3a504962160b5600': { coingeckoId: 'usd-coin', decimals: 6 }, + '556d9582463fe44fbd108aedc9f409f69086dc78d994b88ea6c9e65f8bf98e00': { coingeckoId: 'tether', decimals: 6 }, + } } ibcChains.forEach(chain => fixBalancesTokens[chain] = { ...ibcMappings, ...(fixBalancesTokens[chain] || {}) }) From 42bdb67155ad7ad030d91a7872b51c8f7a9b6929 Mon Sep 17 00:00:00 2001 From: rohannero Date: Wed, 4 Feb 2026 16:35:11 -0500 Subject: [PATCH 4/5] minor refactor --- projects/linx/index.js | 27 +++++++-------------------- 1 file changed, 7 insertions(+), 20 deletions(-) diff --git a/projects/linx/index.js b/projects/linx/index.js index 727bb66ca0a..ceef2d9c926 100644 --- a/projects/linx/index.js +++ b/projects/linx/index.js @@ -51,24 +51,6 @@ async function getTokenBalance(marketContractId, tokenId) { } } -async function getMarketState(marketId) { - const contractCalls = [{ - group: 0, - address: config.linx, - methodIndex: MARKET_METHOD_INDEX, - args: [{ type: "ByteVec", value: marketId }] - }] - const results = await alephium.contractMultiCall(contractCalls); - return { - totalSupplyAssets: BigInt(results[0].returns[0].value), - totalSupplyShares: BigInt(results[0].returns[1].value), - totalBorrowAssets: BigInt(results[0].returns[2].value), - totalBorrowShares: BigInt(results[0].returns[3].value), - lastUpdate: BigInt(results[0].returns[4].value), - fee: BigInt(results[0].returns[5].value) - }; -} - async function tvl(api) { const markets = await getMarkets(); const tokenAmounts = new Map(); @@ -88,8 +70,13 @@ async function borrowed(api) { const markets = await getMarkets(); const tokenAmounts = new Map(); for (const market of markets) { - const state = await getMarketState(market.marketId); - const borrowAssets = state.totalBorrowAssets; + const state = await alephium.contractMultiCall([{ + group: 0, + address: config.linx, + methodIndex: MARKET_METHOD_INDEX, + args: [{ type: "ByteVec", value: market.marketId }] + }]); + const borrowAssets = BigInt(state[0].returns[2].value); tokenAmounts.set(market.loanTokenId, (tokenAmounts.get(market.loanTokenId) ?? BigInt(0)) + borrowAssets); } From 86dd10f97c06d0827e4b52bc8e3dc8c79932b232 Mon Sep 17 00:00:00 2001 From: rohannero Date: Thu, 5 Feb 2026 09:57:51 -0500 Subject: [PATCH 5/5] minor refactor --- projects/linx/index.js | 16 +++------------- 1 file changed, 3 insertions(+), 13 deletions(-) diff --git a/projects/linx/index.js b/projects/linx/index.js index ceef2d9c926..311111b32a2 100644 --- a/projects/linx/index.js +++ b/projects/linx/index.js @@ -53,22 +53,16 @@ async function getTokenBalance(marketContractId, tokenId) { async function tvl(api) { const markets = await getMarkets(); - const tokenAmounts = new Map(); for (const market of markets) { const collateral = await getTokenBalance(market.contractId, market.collateralTokenId); const loanBalance = await getTokenBalance(market.contractId, market.loanTokenId); - tokenAmounts.set(market.collateralTokenId, (tokenAmounts.get(market.collateralTokenId) ?? BigInt(0)) + collateral); - tokenAmounts.set(market.loanTokenId, (tokenAmounts.get(market.loanTokenId) ?? BigInt(0)) + loanBalance); - } - - for (const [tokenId, amount] of tokenAmounts.entries()) { - api.add(tokenId, amount); + api.add(market.collateralTokenId, collateral); + api.add(market.loanTokenId, loanBalance); } } async function borrowed(api) { const markets = await getMarkets(); - const tokenAmounts = new Map(); for (const market of markets) { const state = await alephium.contractMultiCall([{ group: 0, @@ -77,11 +71,7 @@ async function borrowed(api) { args: [{ type: "ByteVec", value: market.marketId }] }]); const borrowAssets = BigInt(state[0].returns[2].value); - tokenAmounts.set(market.loanTokenId, (tokenAmounts.get(market.loanTokenId) ?? BigInt(0)) + borrowAssets); - } - - for (const [tokenId, amount] of tokenAmounts.entries()) { - api.add(tokenId, amount); + api.add(market.loanTokenId, borrowAssets); } }