mirror of
https://github.com/alexgo-io/DefiLlama-Adapters.git
synced 2026-01-12 16:53:02 +08:00
Adding Juris Protocol Lending Protocol (#16832)
This commit is contained in:
@@ -42,7 +42,7 @@ const ibcMappings = {
|
||||
const fixBalancesTokens = {
|
||||
ozone: {
|
||||
// '0x83048f0bf34feed8ced419455a4320a735a92e9d': { coingeckoId: "ozonechain", decimals: 18 }, // was mapped to wrong chain
|
||||
},
|
||||
},
|
||||
camp: {
|
||||
[ADDRESSES.camp.WCAMP]: { coingeckoId: "camp-network", decimals: 18 }, // Wrapped CAMP (ERC-20 wrapper of native CAMP)
|
||||
[ADDRESSES.camp.ETH]: { coingeckoId: "ethereum", decimals: 18 }, // Wrapped ETH
|
||||
@@ -301,4 +301,4 @@ module.exports = {
|
||||
stripTokenHeader,
|
||||
getUniqueAddresses,
|
||||
eulerTokens,
|
||||
}
|
||||
}
|
||||
|
||||
63
projects/jurisprotocol/abi.json
Normal file
63
projects/jurisprotocol/abi.json
Normal file
@@ -0,0 +1,63 @@
|
||||
{
|
||||
"protocol": {
|
||||
"name": "Juris Protocol",
|
||||
"description": "Decentralized staking and lending protocol on Terra Classic ecosystem",
|
||||
"category": "Lending"
|
||||
},
|
||||
"source_repo": "https://github.com/JurisProtocol/documents",
|
||||
"tokens": {
|
||||
"JURIS": {
|
||||
"name": "Juris Protocol",
|
||||
"symbol": "JURIS",
|
||||
"decimals": 6,
|
||||
"address": "terra1vhgq25vwuhdhn9xjll0rhl2s67jzw78a4g2t78y5kz89q9lsdskq2pxcj2",
|
||||
"coingeckoId": "juris-protocol",
|
||||
"type": "cw20",
|
||||
"owner": "true"
|
||||
},
|
||||
"LUNC": {
|
||||
"name": "Terra Luna Classic",
|
||||
"symbol": "LUNC",
|
||||
"decimals": 6,
|
||||
"address": "uluna",
|
||||
"coingeckoId": "terra-luna-classic",
|
||||
"type": "native"
|
||||
},
|
||||
"USTC": {
|
||||
"name": "TerraClassicUSD",
|
||||
"symbol": "USTC",
|
||||
"decimals": 6,
|
||||
"address": "uusd",
|
||||
"coingeckoId": "terraclassicusd",
|
||||
"type": "native"
|
||||
}
|
||||
},
|
||||
"contracts": {
|
||||
"staking": [
|
||||
"terra1rta0rnaxz9ww6hnrj9347vdn66gkgxcmcwgpm2jj6qulv8adc52s95qa5y"
|
||||
],
|
||||
"lending": [],
|
||||
"vesting": [
|
||||
"terra1w89kclh6qd4ftyll4k0x4cyd23lzd9krsntds4y0z2x67kymtf3qj9fgrl",
|
||||
"terra14783nqrx4mjqfnymyqp88dsjf5c6axlt2m75wwt2supwkc0jxr0qyrhqtl",
|
||||
"terra1lejvcrgmhcuedemdetv6qrru7yu8qgwn6e070fq6q4kpda838kpsghwl2u",
|
||||
"terra1hdm8l39h4vmmy8yl48hev8r7qa8pl7uygcraawfljslpepcn7mjqtp83fg",
|
||||
"terra1cjjy4yzzp6sdv6uq27u6l82gslpdkw4l3zk785674mh8gk9dn5qqvr4nr0",
|
||||
"terra1pfefmmls2w67njucd2qgvv4qefcutyl95g986pd69caxdyzp7acsfp0fv8",
|
||||
"terra1ux3em04y0ruwfhljlhl2p8743yyj84xh6s0nyqutyte9397yrq3qe77fm9",
|
||||
"terra15fyg7elhndd7990eshsjz07p3rsssqsm4jjg48zgxpadhahmxd7stpfur5",
|
||||
"terra18wdt4vcejy06mrpp6naju4vv2j7s7hlksew5dq247fxhxvrtxj7qx3x97u",
|
||||
"terra1xgxxjzw9ej5ha2tgsd498w3w4nnu58m59xzwyysmvgnj0y2yrq6q4lm0ru",
|
||||
"terra1w8ysh7fg5f8mfu5cjeumfhjwja6crf20k447a9gftv4lcn2jgpqsf3ztv2",
|
||||
"terra1pljarz83hu9rfdvg88ft8dr76rwmkr5r0avv30ra3p6pgdepfutqrw90dr",
|
||||
"terra1jw5e3hk3k2qz9985r2c3fd0ac5uuz6j98xp9ealnu9qt3dx2wtuqc202fn",
|
||||
"terra1jt70skckl3a3zl98l7na4zqhuyyaerx97rdt9gy2u6eadxc2ke8s2lffsl",
|
||||
"terra13jhdcxd3v7n6fnc4gjj692jsa4jfnh83aly87vj4kyn5c8gp02esgelln5",
|
||||
"terra12xq35pp48mwp7qep2tdlnt2jg8pxmsll0vtnygay7tgh0djdk34sw6qhdl"
|
||||
],
|
||||
"reserve": [],
|
||||
"pool2": [],
|
||||
"ownTokens": [],
|
||||
"treasury": []
|
||||
}
|
||||
}
|
||||
106
projects/jurisprotocol/index.js
Normal file
106
projects/jurisprotocol/index.js
Normal file
@@ -0,0 +1,106 @@
|
||||
const abi = require('./abi.json');
|
||||
const { queryContract, queryV1Beta1 } = require('../helper/chain/cosmos');
|
||||
|
||||
const { contracts, tokens } = abi;
|
||||
|
||||
// Build helpers from abi.json
|
||||
const TOKENS = Object.values(tokens || {});
|
||||
const TOKEN_BY_ADDR = Object.fromEntries(TOKENS.map(t => [t.address, t]));
|
||||
const OWNED_CW20_SET = new Set(
|
||||
TOKENS
|
||||
.filter(t => t.type === 'cw20' && (t.owner === true || t.owner === 'true'))
|
||||
.map(t => t.address)
|
||||
);
|
||||
const NATIVE_DENOMS = new Set(
|
||||
TOKENS.filter(t => t.type === 'native').map(t => t.address)
|
||||
);
|
||||
|
||||
async function smartQuery(contract, msgObj) {
|
||||
const res = await queryContract({ contract, chain: 'terra', data: msgObj });
|
||||
return res?.data ?? res ?? {};
|
||||
}
|
||||
|
||||
async function bankBalances(address) {
|
||||
const res = await queryV1Beta1({
|
||||
chain: 'terra',
|
||||
// Standard Cosmos SDK REST path
|
||||
url: `/bank/v1beta1/balances/${address}`,
|
||||
});
|
||||
return res?.balances ?? [];
|
||||
}
|
||||
|
||||
async function cw20Balance(token, owner) {
|
||||
const r = await smartQuery(token, { balance: { address: owner } });
|
||||
const raw = String(r.balance ?? r.amount ?? '0').replace(/[^0-9]/g, '') || '0';
|
||||
return raw;
|
||||
}
|
||||
|
||||
function nativeBalance(balances, denom) {
|
||||
const row = balances.find(r => r.denom === denom);
|
||||
return String(row?.amount ?? '0').replace(/[^0-9]/g, '') || '0';
|
||||
}
|
||||
|
||||
// Core worker: optional exclusion for protocol-owned CW20s, with verbose logging
|
||||
async function fetchBalances(moduleName, api, { excludeOwnedCw20 = false, logTag = '' } = {}) {
|
||||
const owners = (contracts[moduleName] || []).filter(Boolean);
|
||||
if (!owners.length) {
|
||||
console.log(`[${logTag || moduleName}] no owners configured`);
|
||||
return;
|
||||
}
|
||||
|
||||
await Promise.all(owners.map(async owner => {
|
||||
console.log(`[${logTag || moduleName}] owner=${owner} — scanning balances`);
|
||||
|
||||
const bank = await bankBalances(owner);
|
||||
|
||||
// Natives
|
||||
for (const denom of NATIVE_DENOMS) {
|
||||
const bal = nativeBalance(bank, denom);
|
||||
if (+bal > 0) {
|
||||
console.log(`[${logTag || moduleName}] owner=${owner} native ${denom}=${bal}`);
|
||||
api.add(denom, bal);
|
||||
}
|
||||
}
|
||||
|
||||
// CW20s
|
||||
for (const t of TOKENS) {
|
||||
if (t.type !== 'cw20') continue;
|
||||
const bal = await cw20Balance(t.address, owner);
|
||||
if (+bal <= 0) continue;
|
||||
|
||||
const info = TOKEN_BY_ADDR[t.address] || {};
|
||||
const sym = info.symbol || '';
|
||||
const isOwned = OWNED_CW20_SET.has(t.address);
|
||||
const excluded = excludeOwnedCw20 && isOwned;
|
||||
|
||||
console.log(
|
||||
`[${logTag || moduleName}] owner=${owner} cw20 ${sym}(${t.address})=${bal}${excluded ? ' [EXCLUDED]' : ''}`
|
||||
);
|
||||
|
||||
if (!excluded) api.add(t.address, bal);
|
||||
}
|
||||
|
||||
console.log(`[${logTag || moduleName}] owner=${owner} — done`);
|
||||
}));
|
||||
}
|
||||
|
||||
// Build category fns from abi.json (default: no exclusions)
|
||||
const terraExport = {};
|
||||
Object.keys(contracts).forEach(key => {
|
||||
if (contracts[key]?.length) {
|
||||
terraExport[key] = (api) => fetchBalances(key, api, { excludeOwnedCw20: false, logTag: key });
|
||||
}
|
||||
});
|
||||
|
||||
// TVL: include all desired categories but exclude owner CW20s (e.g., JURIS) everywhere
|
||||
terraExport.tvl = async (api) => {
|
||||
const cats = Object.keys(contracts).filter(k => k !== 'tvl');
|
||||
await Promise.all(cats.map((k) => fetchBalances(k, api, { excludeOwnedCw20: true, logTag: `TVL:${k}` })));
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
methodology:
|
||||
'TVL sums native denoms and non-owned CW20s across configured contract owners; any CW20 with owner=true in abi.json (e.g., JURIS) is excluded from TVL but still logged for visibility.',
|
||||
timetravel: false,
|
||||
terra: terraExport,
|
||||
};
|
||||
Reference in New Issue
Block a user