aiia-vault-sdk 1.1.25 → 1.1.26
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/SeedRoundFundraiser.d.ts +2 -2
- package/dist/SeedRoundFundraiser.js +1 -1
- package/dist/TradingVault.d.ts +106 -1
- package/dist/TradingVault.js +1 -1
- package/dist/utils.d.ts +7 -3
- package/dist/utils.js +1 -1
- package/package.json +1 -1
@@ -467,8 +467,8 @@ export declare class SeedRoundFundraiserSDK {
|
|
467
467
|
attempts: number;
|
468
468
|
}>;
|
469
469
|
getContractAddress(): string;
|
470
|
-
getAllEvents(fromBlock: number, toBlock: number): Promise<ParsedSeedRoundFundraiserEventRaw[]>;
|
471
|
-
streamEvents(fromBlock: number, onEvent: (event: ParsedSeedRoundFundraiserEvent) => Promise<void>, saveLatestBlock: (blockNumber: number) => Promise<void>, batchSize?: number, sleepTime?: number): Promise<void>;
|
470
|
+
getAllEvents(fromBlock: number, toBlock: number, whitelistEvents?: string[]): Promise<ParsedSeedRoundFundraiserEventRaw[]>;
|
471
|
+
streamEvents(fromBlock: number, onEvent: (event: ParsedSeedRoundFundraiserEvent) => Promise<void>, saveLatestBlock: (blockNumber: number) => Promise<void>, batchSize?: number, sleepTime?: number, whitelistEvents?: string[]): Promise<void>;
|
472
472
|
formatEventArgs: (event: ParsedSeedRoundFundraiserEventRaw) => ParsedSeedRoundFundraiserEvent;
|
473
473
|
/**
|
474
474
|
* Gets detailed information about a user's contribution in a specific round
|
@@ -1 +1 @@
|
|
1
|
-
"use strict";var t=this&&this.__importDefault||function(t){return t&&t.__esModule?t:{default:t}};Object.defineProperty(exports,"__esModule",{value:!0}),exports.SeedRoundFundraiserSDK=void 0;const e=require("ethers"),n=t(require("./abis/SeedRoundFundraiser.json")),o=t(require("./contracts.json")),r=require("./utils"),i=t(require("./whitelist-tokens.json"));exports.SeedRoundFundraiserSDK=class{constructor(t,i){this.name="SeedRoundFundraiser",this.isBootstrapped=!1,this.PRICE_PRECISION=1e18,this.whitelistedTokensArray=[],this.projectToken="",this.projectTokenDecimals=0,this.formatEventArgs=t=>{const{eventName:e,args:n}=t;switch(e){case"TokenWhitelisted":return{...t,args:{...n,token:n.token.toLowerCase(),price:Number(n.price)/this.PRICE_PRECISION}};case"TokenPriceUpdated":return{...t,args:{...n,token:n.token.toLowerCase(),oldPrice:Number(n.oldPrice)/this.PRICE_PRECISION,newPrice:Number(n.newPrice)/this.PRICE_PRECISION}};case"TokenRemovedFromWhitelist":return{...t,args:{...n,token:n.token.toLowerCase()}};case"RoundCreated":case"RoundUpdated":return{...t,args:{...n,roundId:Number(n.roundId),startTime:Number(n.startTime),endTime:Number(n.endTime),targetFund:Number(n.targetFund)/this.PRICE_PRECISION,totalAllocation:Number(n.totalAllocation),maxFundPerAccount:Number(n.maxFundPerAccount)/this.PRICE_PRECISION}};case"RoundEnded":return{...t,args:{...n,roundId:Number(n.roundId),raisedFunds:Number(n.raisedFunds)/this.PRICE_PRECISION,participants:Number(n.participants)}};case"Contribution":return{...t,args:{...n,roundId:Number(n.roundId),contributor:n.contributor.toLowerCase(),token:n.token.toLowerCase(),amount:Number(n.amount),fundAmount:Number(n.fundAmount)/this.PRICE_PRECISION,tokenAllocation:Number(n.tokenAllocation)}};case"TokensClaimed":return{...t,args:{...n,roundId:Number(n.roundId),user:n.user.toLowerCase(),amount:Number(n.amount)}};case"ProjectTokenUpdated":return{...t,args:{...n,oldToken:n.oldToken.toLowerCase(),newToken:n.newToken.toLowerCase()}};case"ClaimingEnabledUpdated":case"RefundEnabledUpdated":return{...t,args:{...n,roundId:Number(n.roundId),enabled:n.enabled}};case"Refunded":return{...t,args:{...n,roundId:Number(n.roundId),user:n.user.toLowerCase(),token:n.token.toLowerCase(),amount:Number(n.amount)}};default:return t}};const a=Array.isArray(t)?t:[t];this.providers=a.map((t=>new e.ethers.JsonRpcProvider(t)));const s=(0,r.getRandomProvider)(this.providers);this.contractAddress=(0,r.resolveContractAddress)(a[0],this.name,o.default,i),this.contract=new e.ethers.Contract(this.contractAddress,n.default.abi,s),this.networkName=(0,r.getNetworkFromRpc)(a[0]),this.importWhitelistedTokens()}importWhitelistedTokens(){try{i.default[this.networkName]?(this.whitelistedTokensArray=i.default[this.networkName].map((t=>({name:t.name,address:t.address.toLowerCase(),decimals:t.decimals,symbol:t.symbol,icon:t.icon}))),console.log(`Imported ${this.whitelistedTokensArray.length} whitelisted tokens for ${this.networkName} network`)):console.log(`No whitelisted tokens found for ${this.networkName} network`)}catch(t){console.error("Error importing whitelisted tokens:",t)}}async getWhitelistedTokenInfo(t,e,n,o,r){const i=t.toLowerCase();if(!this.whitelistedTokensArray.some((t=>t.address===i)))return null;const a=await this.getWhitelistedToken(i);if(!a.isWhitelisted)return null;let s=0,d=0n;return r&&r.roundId>=0&&(d=r.maxFundPerAccountRaw*BigInt(10**n)/a.priceRaw,s=r.maxFundPerAccount/a.price),{address:i,isWhitelisted:a.isWhitelisted,price:a.price,symbol:e,maxContribution:s,maxContributionRaw:d,decimals:n,icon:o}}async getAllWhitelistedTokensInfo(){const t=await this.getLatestRoundId();let e;if(t>=0){const n=await this.getRound(t);n.exists&&!n.ended&&(e={roundId:t,maxFundPerAccount:n.maxFundPerAccount,maxFundPerAccountRaw:n.maxFundPerAccountRaw})}const n=this.whitelistedTokensArray.map((t=>this.getWhitelistedTokenInfo(t.address,t.symbol,t.decimals,t.icon,e)));return(await Promise.all(n)).filter((t=>null!==t))}getRandomProvider(){return(0,r.getRandomProvider)(this.providers)}getContractWithRandomProvider(){return new e.ethers.Contract(this.contractAddress,n.default.abi,this.getRandomProvider())}async bootstrap(){if(this.isBootstrapped)return;const t=await Promise.all(this.providers.map(((t,e)=>(0,r.checkRpcHealth)(t,e))));if(this.providers=this.providers.filter(((e,n)=>t[n])),0===this.providers.length)throw new Error("No active RPC providers available");this.projectToken=await this.getProjectToken(),this.projectTokenDecimals=await(0,r.getTokenDecimals)(this.projectToken,this.getRandomProvider()),this.isBootstrapped=!0}async signAndSendTransaction(t,e,n={}){return(0,r.signAndSendTransaction)(t,e,(()=>this.getRandomProvider()),n,this.contract)}async buildAddWhitelistedTokenTx(t,e){const n=BigInt(Math.floor(e*this.PRICE_PRECISION));return await this.contract.addWhitelistedToken.populateTransaction(t,n)}async buildUpdateTokenPriceTx(t,e){const n=BigInt(Math.floor(e*this.PRICE_PRECISION));return await this.contract.updateTokenPrice.populateTransaction(t,n)}async buildRemoveWhitelistedTokenTx(t){return await this.contract.removeWhitelistedToken.populateTransaction(t)}async buildCreateRoundTx(t,e,n,o,i){const a=BigInt(Math.floor(n*this.PRICE_PRECISION)),s=BigInt(Math.floor(i*this.PRICE_PRECISION)),d=await(0,r.getTokenDecimals)(await this.getProjectToken(),this.getRandomProvider()),c=BigInt(Math.floor(o*Math.pow(10,d)));return await this.contract.createRound.populateTransaction(t,e,a,c,s)}async buildUpdateRoundTx(t,e,n,o,i,a){const s=BigInt(Math.floor(o*this.PRICE_PRECISION)),d=BigInt(Math.floor(a*this.PRICE_PRECISION)),c=await(0,r.getTokenDecimals)(await this.getProjectToken(),this.getRandomProvider()),u=BigInt(Math.floor(i*Math.pow(10,c)));return await this.contract.updateRound.populateTransaction(t,e,n,s,u,d)}async buildEndRoundTx(t){return await this.contract.endRound.populateTransaction(t)}async buildSetClaimingEnabledTx(t,e){return await this.contract.setClaimingEnabled.populateTransaction(t,e)}async buildSetRefundEnabledTx(t,e){return await this.contract.setRefundEnabled.populateTransaction(t,e)}async buildContributeTx(t,n,o){let i=18;n!==e.ethers.ZeroAddress&&(i=await(0,r.getTokenDecimals)(n,this.getRandomProvider()));const a=e.ethers.parseUnits(o.toString(),i),s=await this.contract.contribute.populateTransaction(t,n,n===e.ethers.ZeroAddress?0:a);return n===e.ethers.ZeroAddress&&(s.value=a),s}async buildContributeTxRaw(t,n,o){const r=await this.contract.contribute.populateTransaction(t,n,n===e.ethers.ZeroAddress?0:o);return n===e.ethers.ZeroAddress&&(r.value=o),r}async buildWithdrawFundsTx(t,e){const n=await(0,r.getTokenDecimals)(t,this.getRandomProvider()),o=BigInt(Math.floor(e*Math.pow(10,n)));return await this.contract.withdrawFunds.populateTransaction(t,o)}async buildClaimTokensByRoundIdTx(t){return await this.contract.claimTokensByRoundId.populateTransaction(t)}async getWhitelistedToken(t){const e=await this.contract.whitelistedTokens(t);return{isWhitelisted:e.isWhitelisted,price:Number(e.price)/this.PRICE_PRECISION,priceRaw:e.price}}async getRound(t){const e=await this.contract.rounds(t);return this.projectToken||(this.projectToken=await this.getProjectToken()),this.projectTokenDecimals||(this.projectTokenDecimals=await(0,r.getTokenDecimals)(this.projectToken,this.getRandomProvider())),{startTime:Number(e.startTime),endTime:Number(e.endTime),targetFund:Number(e.targetFund)/this.PRICE_PRECISION,totalAllocation:Number(e.totalAllocation)/10**this.projectTokenDecimals,maxFundPerAccount:Number(e.maxFundPerAccount)/this.PRICE_PRECISION,maxFundPerAccountRaw:e.maxFundPerAccount,exists:e.exists,ended:e.ended,claimingEnabled:e.claimingEnabled,refundEnabled:e.refundEnabled}}async getUserContribution(t,n){this.projectToken||(this.projectToken=await this.getProjectToken()),this.projectTokenDecimals||(this.projectTokenDecimals=await(0,r.getTokenDecimals)(this.projectToken,this.getRandomProvider()));const o=await this.contract.userContributions(t,n);let i=18;return o.contributedToken!==e.ethers.ZeroAddress&&"0x0000000000000000000000000000000000000000"!==o.contributedToken&&(i=await(0,r.getTokenDecimals)(o.contributedToken,this.getRandomProvider())),{fundAmount:Number(o.fundAmount)/this.PRICE_PRECISION,tokenAllocation:Number(o.tokenAllocation)/10**this.projectTokenDecimals,claimed:o.claimed,refunded:o.refunded,contributedToken:o.contributedToken,contributedAmount:Number(o.contributedAmount)/10**i,contributedAmountRaw:o.contributedAmount}}async getRoundRaisedFunds(t){const e=await this.contract.roundRaisedFunds(t);return Number(e)/this.PRICE_PRECISION}async getRoundParticipants(t){const e=await this.contract.roundParticipants(t);return Number(e)}async getUserParticipatedRound(t){const e=await this.contract.userParticipatedRound(t);return Number(e)}async getProjectToken(){return await this.contract.projectToken()}async getTotalRounds(){const t=await this.contract.totalRounds();return Number(t)}async getTotalRaisedFunds(){const t=await this.contract.totalRaisedFunds();return Number(t)/this.PRICE_PRECISION}async isRoundActive(t){return await this.contract.isRoundActive(t)}async getLatestRoundId(){const t=await this.getTotalRounds();return 0===t?-1:t-1}async getRoundInfo(t){const e=await this.getTotalRounds();if(t<0||t>=e)throw new Error(`Invalid round ID: ${t}`);return{roundId:t,config:await this.getRound(t),raisedFunds:await this.getRoundRaisedFunds(t),participants:await this.getRoundParticipants(t),isActive:await this.isRoundActive(t)}}async getUserTotalContribution(t){const e=await this.contract.getUserTotalContribution(t);return{totalFundAmount:Number(e.totalFundAmount)/this.PRICE_PRECISION,totalTokenAllocation:Number(e.totalTokenAllocation)}}async getTransactionStatus(t,e=10){return await(0,r.getTransactionStatus)(this.getRandomProvider(),t,e)}getContractAddress(){return this.contractAddress}async getAllEvents(t,e){return await this.bootstrap(),(0,r.getAllEvents)(this.contract,(()=>this.getRandomProvider()),(()=>this.getContractWithRandomProvider()),t,e)}async streamEvents(t,e,n,o=1e3,i=5e3){return await this.bootstrap(),(0,r.streamEvents)({getProvider:()=>this.getRandomProvider(),getAllEvents:(t,e)=>this.getAllEvents(t,e),formatEvent:t=>this.formatEventArgs(t),onEvent:e,saveLatestBlock:n,fromBlock:t,batchSize:o,sleepTime:i})}async getUserRoundContribution(t,n){const[o,i]=await Promise.all([this.contract.getUserRoundContribution(t,n),this.contract.rounds(t)]),a=o.contributedToken!==e.ethers.ZeroAddress?await(0,r.getTokenDecimals)(o.contributedToken,this.getRandomProvider()):18,s={fundAmount:Number(o.fundAmount)/this.PRICE_PRECISION,tokenAllocation:Number(o.tokenAllocation),claimed:o.claimed,refunded:o.refunded,contributedToken:o.contributedToken,contributedAmount:Number(o.contributedAmount)/a,contributedAmountRaw:o.contributedAmount},d=Math.floor(Date.now()/1e3),c=i.exists&&!i.ended&&d>=Number(i.startTime)&&d<=Number(i.endTime),u={contribution:s,roundInfo:{exists:i.exists,isActive:c,claimingEnabled:i.claimingEnabled,refundEnabled:i.refundEnabled}};if(s.fundAmount>0){const t=s.contributedToken;let n="ETH",o=18;return t!==e.ethers.ZeroAddress&&([n,o]=await Promise.all([(0,r.getTokenSymbol)(t,this.getRandomProvider()),(0,r.getTokenDecimals)(t,this.getRandomProvider())])),{...u,tokenInfo:{symbol:n,decimals:o}}}return u}async buildTransferProjectTokenToContract(t){this.projectToken||(this.projectToken=await this.getProjectToken()),this.projectTokenDecimals||(this.projectTokenDecimals=await(0,r.getTokenDecimals)(this.projectToken,this.getRandomProvider()));const n=new e.ethers.Interface(["function transfer(address to, uint256 amount) returns (bool)"]),o=e.ethers.parseUnits(t.toString(),this.projectTokenDecimals);return{to:this.projectToken,data:n.encodeFunctionData("transfer",[this.contractAddress,o])}}async hasAdminRole(t){const e=await this.contract.DEFAULT_ADMIN_ROLE();return await this.contract.hasRole(e,t)}async buildGrantAdminRoleTx(t){const e=await this.contract.DEFAULT_ADMIN_ROLE();return await this.contract.grantRole.populateTransaction(e,t)}async getAdminRoleHash(){return await this.contract.DEFAULT_ADMIN_ROLE()}};
|
1
|
+
"use strict";var t=this&&this.__importDefault||function(t){return t&&t.__esModule?t:{default:t}};Object.defineProperty(exports,"__esModule",{value:!0}),exports.SeedRoundFundraiserSDK=void 0;const e=require("ethers"),n=t(require("./abis/SeedRoundFundraiser.json")),o=t(require("./contracts.json")),r=require("./utils"),i=t(require("./whitelist-tokens.json"));exports.SeedRoundFundraiserSDK=class{constructor(t,i){this.name="SeedRoundFundraiser",this.isBootstrapped=!1,this.PRICE_PRECISION=1e18,this.whitelistedTokensArray=[],this.projectToken="",this.projectTokenDecimals=0,this.formatEventArgs=t=>{const{eventName:e,args:n}=t;switch(e){case"TokenWhitelisted":return{...t,args:{...n,token:n.token.toLowerCase(),price:Number(n.price)/this.PRICE_PRECISION}};case"TokenPriceUpdated":return{...t,args:{...n,token:n.token.toLowerCase(),oldPrice:Number(n.oldPrice)/this.PRICE_PRECISION,newPrice:Number(n.newPrice)/this.PRICE_PRECISION}};case"TokenRemovedFromWhitelist":return{...t,args:{...n,token:n.token.toLowerCase()}};case"RoundCreated":case"RoundUpdated":return{...t,args:{...n,roundId:Number(n.roundId),startTime:Number(n.startTime),endTime:Number(n.endTime),targetFund:Number(n.targetFund)/this.PRICE_PRECISION,totalAllocation:Number(n.totalAllocation),maxFundPerAccount:Number(n.maxFundPerAccount)/this.PRICE_PRECISION}};case"RoundEnded":return{...t,args:{...n,roundId:Number(n.roundId),raisedFunds:Number(n.raisedFunds)/this.PRICE_PRECISION,participants:Number(n.participants)}};case"Contribution":return{...t,args:{...n,roundId:Number(n.roundId),contributor:n.contributor.toLowerCase(),token:n.token.toLowerCase(),amount:Number(n.amount),fundAmount:Number(n.fundAmount)/this.PRICE_PRECISION,tokenAllocation:Number(n.tokenAllocation)}};case"TokensClaimed":return{...t,args:{...n,roundId:Number(n.roundId),user:n.user.toLowerCase(),amount:Number(n.amount)}};case"ProjectTokenUpdated":return{...t,args:{...n,oldToken:n.oldToken.toLowerCase(),newToken:n.newToken.toLowerCase()}};case"ClaimingEnabledUpdated":case"RefundEnabledUpdated":return{...t,args:{...n,roundId:Number(n.roundId),enabled:n.enabled}};case"Refunded":return{...t,args:{...n,roundId:Number(n.roundId),user:n.user.toLowerCase(),token:n.token.toLowerCase(),amount:Number(n.amount)}};default:return t}};const a=Array.isArray(t)?t:[t];this.providers=a.map((t=>new e.ethers.JsonRpcProvider(t)));const s=(0,r.getRandomProvider)(this.providers);this.contractAddress=(0,r.resolveContractAddress)(a[0],this.name,o.default,i),this.contract=new e.ethers.Contract(this.contractAddress,n.default.abi,s),this.networkName=(0,r.getNetworkFromRpc)(a[0]),this.importWhitelistedTokens()}importWhitelistedTokens(){try{i.default[this.networkName]?(this.whitelistedTokensArray=i.default[this.networkName].map((t=>({name:t.name,address:t.address.toLowerCase(),decimals:t.decimals,symbol:t.symbol,icon:t.icon}))),console.log(`Imported ${this.whitelistedTokensArray.length} whitelisted tokens for ${this.networkName} network`)):console.log(`No whitelisted tokens found for ${this.networkName} network`)}catch(t){console.error("Error importing whitelisted tokens:",t)}}async getWhitelistedTokenInfo(t,e,n,o,r){const i=t.toLowerCase();if(!this.whitelistedTokensArray.some((t=>t.address===i)))return null;const a=await this.getWhitelistedToken(i);if(!a.isWhitelisted)return null;let s=0,d=0n;return r&&r.roundId>=0&&(d=r.maxFundPerAccountRaw*BigInt(this.PRICE_PRECISION)/a.priceRaw,s=r.maxFundPerAccount/a.price),{address:i,isWhitelisted:a.isWhitelisted,price:a.price,symbol:e,maxContribution:s,maxContributionRaw:d,decimals:n,icon:o}}async getAllWhitelistedTokensInfo(){const t=await this.getLatestRoundId();let e;if(t>=0){const n=await this.getRound(t);n.exists&&!n.ended&&(e={roundId:t,maxFundPerAccount:n.maxFundPerAccount,maxFundPerAccountRaw:n.maxFundPerAccountRaw})}const n=this.whitelistedTokensArray.map((t=>this.getWhitelistedTokenInfo(t.address,t.symbol,t.decimals,t.icon,e)));return(await Promise.all(n)).filter((t=>null!==t))}getRandomProvider(){return(0,r.getRandomProvider)(this.providers)}getContractWithRandomProvider(){return new e.ethers.Contract(this.contractAddress,n.default.abi,this.getRandomProvider())}async bootstrap(){if(this.isBootstrapped)return;const t=await Promise.all(this.providers.map(((t,e)=>(0,r.checkRpcHealth)(t,e))));if(this.providers=this.providers.filter(((e,n)=>t[n])),0===this.providers.length)throw new Error("No active RPC providers available");this.projectToken=await this.getProjectToken(),this.projectTokenDecimals=await(0,r.getTokenDecimals)(this.projectToken,this.getRandomProvider()),this.isBootstrapped=!0}async signAndSendTransaction(t,e,n={}){return(0,r.signAndSendTransaction)(t,e,(()=>this.getRandomProvider()),n,this.contract)}async buildAddWhitelistedTokenTx(t,e){const n=BigInt(Math.floor(e*this.PRICE_PRECISION));return await this.contract.addWhitelistedToken.populateTransaction(t,n)}async buildUpdateTokenPriceTx(t,e){const n=BigInt(Math.floor(e*this.PRICE_PRECISION));return await this.contract.updateTokenPrice.populateTransaction(t,n)}async buildRemoveWhitelistedTokenTx(t){return await this.contract.removeWhitelistedToken.populateTransaction(t)}async buildCreateRoundTx(t,e,n,o,i){const a=BigInt(Math.floor(n*this.PRICE_PRECISION)),s=BigInt(Math.floor(i*this.PRICE_PRECISION)),d=await(0,r.getTokenDecimals)(await this.getProjectToken(),this.getRandomProvider()),c=BigInt(Math.floor(o*Math.pow(10,d)));return await this.contract.createRound.populateTransaction(t,e,a,c,s)}async buildUpdateRoundTx(t,e,n,o,i,a){const s=BigInt(Math.floor(o*this.PRICE_PRECISION)),d=BigInt(Math.floor(a*this.PRICE_PRECISION)),c=await(0,r.getTokenDecimals)(await this.getProjectToken(),this.getRandomProvider()),u=BigInt(Math.floor(i*Math.pow(10,c)));return await this.contract.updateRound.populateTransaction(t,e,n,s,u,d)}async buildEndRoundTx(t){return await this.contract.endRound.populateTransaction(t)}async buildSetClaimingEnabledTx(t,e){return await this.contract.setClaimingEnabled.populateTransaction(t,e)}async buildSetRefundEnabledTx(t,e){return await this.contract.setRefundEnabled.populateTransaction(t,e)}async buildContributeTx(t,n,o){let i=18;n!==e.ethers.ZeroAddress&&(i=await(0,r.getTokenDecimals)(n,this.getRandomProvider()));const a=e.ethers.parseUnits(o.toString(),i),s=await this.contract.contribute.populateTransaction(t,n,n===e.ethers.ZeroAddress?0:a);return n===e.ethers.ZeroAddress&&(s.value=a),s}async buildContributeTxRaw(t,n,o){const r=await this.contract.contribute.populateTransaction(t,n,n===e.ethers.ZeroAddress?0:o);return n===e.ethers.ZeroAddress&&(r.value=o),r}async buildWithdrawFundsTx(t,e){const n=await(0,r.getTokenDecimals)(t,this.getRandomProvider()),o=BigInt(Math.floor(e*Math.pow(10,n)));return await this.contract.withdrawFunds.populateTransaction(t,o)}async buildClaimTokensByRoundIdTx(t){return await this.contract.claimTokensByRoundId.populateTransaction(t)}async getWhitelistedToken(t){const e=await this.contract.whitelistedTokens(t);return{isWhitelisted:e.isWhitelisted,price:Number(e.price)/this.PRICE_PRECISION,priceRaw:e.price}}async getRound(t){const e=await this.contract.rounds(t);return this.projectToken||(this.projectToken=await this.getProjectToken()),this.projectTokenDecimals||(this.projectTokenDecimals=await(0,r.getTokenDecimals)(this.projectToken,this.getRandomProvider())),{startTime:Number(e.startTime),endTime:Number(e.endTime),targetFund:Number(e.targetFund)/this.PRICE_PRECISION,totalAllocation:Number(e.totalAllocation)/10**this.projectTokenDecimals,maxFundPerAccount:Number(e.maxFundPerAccount)/this.PRICE_PRECISION,maxFundPerAccountRaw:e.maxFundPerAccount,exists:e.exists,ended:e.ended,claimingEnabled:e.claimingEnabled,refundEnabled:e.refundEnabled}}async getUserContribution(t,n){this.projectToken||(this.projectToken=await this.getProjectToken()),this.projectTokenDecimals||(this.projectTokenDecimals=await(0,r.getTokenDecimals)(this.projectToken,this.getRandomProvider()));const o=await this.contract.userContributions(t,n);let i=18;return o.contributedToken!==e.ethers.ZeroAddress&&"0x0000000000000000000000000000000000000000"!==o.contributedToken&&(i=await(0,r.getTokenDecimals)(o.contributedToken,this.getRandomProvider())),{fundAmount:Number(o.fundAmount)/this.PRICE_PRECISION,tokenAllocation:Number(o.tokenAllocation)/10**this.projectTokenDecimals,claimed:o.claimed,refunded:o.refunded,contributedToken:o.contributedToken,contributedAmount:Number(o.contributedAmount)/10**i,contributedAmountRaw:o.contributedAmount}}async getRoundRaisedFunds(t){const e=await this.contract.roundRaisedFunds(t);return Number(e)/this.PRICE_PRECISION}async getRoundParticipants(t){const e=await this.contract.roundParticipants(t);return Number(e)}async getUserParticipatedRound(t){const e=await this.contract.userParticipatedRound(t);return Number(e)}async getProjectToken(){return await this.contract.projectToken()}async getTotalRounds(){const t=await this.contract.totalRounds();return Number(t)}async getTotalRaisedFunds(){const t=await this.contract.totalRaisedFunds();return Number(t)/this.PRICE_PRECISION}async isRoundActive(t){return await this.contract.isRoundActive(t)}async getLatestRoundId(){const t=await this.getTotalRounds();return 0===t?-1:t-1}async getRoundInfo(t){const e=await this.getTotalRounds();if(t<0||t>=e)throw new Error(`Invalid round ID: ${t}`);return{roundId:t,config:await this.getRound(t),raisedFunds:await this.getRoundRaisedFunds(t),participants:await this.getRoundParticipants(t),isActive:await this.isRoundActive(t)}}async getUserTotalContribution(t){const e=await this.contract.getUserTotalContribution(t);return{totalFundAmount:Number(e.totalFundAmount)/this.PRICE_PRECISION,totalTokenAllocation:Number(e.totalTokenAllocation)}}async getTransactionStatus(t,e=10){return await(0,r.getTransactionStatus)(this.getRandomProvider(),t,e)}getContractAddress(){return this.contractAddress}async getAllEvents(t,e,n){return await this.bootstrap(),(0,r.getAllEvents)(this.contract,(()=>this.getRandomProvider()),(()=>this.getContractWithRandomProvider()),t,e,n)}async streamEvents(t,e,n,o=1e3,i=5e3,a){return await this.bootstrap(),(0,r.streamEvents)({getProvider:()=>this.getRandomProvider(),getAllEvents:(t,e)=>this.getAllEvents(t,e,a),formatEvent:t=>this.formatEventArgs(t),onEvent:e,saveLatestBlock:n,fromBlock:t,batchSize:o,sleepTime:i})}async getUserRoundContribution(t,n){const[o,i]=await Promise.all([this.contract.getUserRoundContribution(t,n),this.contract.rounds(t)]),a=o.contributedToken!==e.ethers.ZeroAddress?await(0,r.getTokenDecimals)(o.contributedToken,this.getRandomProvider()):18,s={fundAmount:Number(o.fundAmount)/this.PRICE_PRECISION,tokenAllocation:Number(o.tokenAllocation),claimed:o.claimed,refunded:o.refunded,contributedToken:o.contributedToken,contributedAmount:Number(o.contributedAmount)/a,contributedAmountRaw:o.contributedAmount},d=Math.floor(Date.now()/1e3),c=i.exists&&!i.ended&&d>=Number(i.startTime)&&d<=Number(i.endTime),u={contribution:s,roundInfo:{exists:i.exists,isActive:c,claimingEnabled:i.claimingEnabled,refundEnabled:i.refundEnabled}};if(s.fundAmount>0){const t=s.contributedToken;let n="ETH",o=18;return t!==e.ethers.ZeroAddress&&([n,o]=await Promise.all([(0,r.getTokenSymbol)(t,this.getRandomProvider()),(0,r.getTokenDecimals)(t,this.getRandomProvider())])),{...u,tokenInfo:{symbol:n,decimals:o}}}return u}async buildTransferProjectTokenToContract(t){this.projectToken||(this.projectToken=await this.getProjectToken()),this.projectTokenDecimals||(this.projectTokenDecimals=await(0,r.getTokenDecimals)(this.projectToken,this.getRandomProvider()));const n=new e.ethers.Interface(["function transfer(address to, uint256 amount) returns (bool)"]),o=e.ethers.parseUnits(t.toString(),this.projectTokenDecimals);return{to:this.projectToken,data:n.encodeFunctionData("transfer",[this.contractAddress,o])}}async hasAdminRole(t){const e=await this.contract.DEFAULT_ADMIN_ROLE();return await this.contract.hasRole(e,t)}async buildGrantAdminRoleTx(t){const e=await this.contract.DEFAULT_ADMIN_ROLE();return await this.contract.grantRole.populateTransaction(e,t)}async getAdminRoleHash(){return await this.contract.DEFAULT_ADMIN_ROLE()}};
|
package/dist/TradingVault.d.ts
CHANGED
@@ -66,6 +66,111 @@ export declare class TradingVaultSDK {
|
|
66
66
|
getAllowanceRaw(tokenAddress: string, owner: string, spender: string): Promise<bigint>;
|
67
67
|
getAllowance(tokenAddress: string, owner: string, spender: string): Promise<number>;
|
68
68
|
buildGrantOperatorRoleTxRaw(operator: string): Promise<ethers.ContractTransaction>;
|
69
|
+
/**
|
70
|
+
* Gets the OPERATOR_ROLE hash
|
71
|
+
*
|
72
|
+
* @returns The OPERATOR_ROLE hash
|
73
|
+
*
|
74
|
+
* @example
|
75
|
+
* ```typescript
|
76
|
+
* const operatorRoleHash = await sdk.getOperatorRoleHash();
|
77
|
+
* ```
|
78
|
+
*/
|
79
|
+
getOperatorRoleHash(): Promise<string>;
|
80
|
+
/**
|
81
|
+
* Checks if an address has the operator role
|
82
|
+
*
|
83
|
+
* @param address - The address to check
|
84
|
+
* @returns Boolean indicating if the address has operator role
|
85
|
+
*
|
86
|
+
* @example
|
87
|
+
* ```typescript
|
88
|
+
* const hasOperatorRole = await sdk.hasOperatorRole("0x...");
|
89
|
+
* ```
|
90
|
+
*/
|
91
|
+
hasOperatorRole(address: string): Promise<boolean>;
|
92
|
+
/**
|
93
|
+
* Builds a transaction to grant operator role to an address
|
94
|
+
*
|
95
|
+
* @param address - The address to grant operator role to
|
96
|
+
* @returns Populated transaction
|
97
|
+
*
|
98
|
+
* @example
|
99
|
+
* ```typescript
|
100
|
+
* const tx = await sdk.buildGrantOperatorRoleTx("0x...");
|
101
|
+
* ```
|
102
|
+
*/
|
103
|
+
buildGrantOperatorRoleTx(address: string): Promise<ethers.ContractTransaction>;
|
104
|
+
/**
|
105
|
+
* Gets the PRICE_SETTER_ROLE hash
|
106
|
+
*
|
107
|
+
* @returns The PRICE_SETTER_ROLE hash
|
108
|
+
*
|
109
|
+
* @example
|
110
|
+
* ```typescript
|
111
|
+
* const priceSetterRoleHash = await sdk.getPriceSetterRoleHash();
|
112
|
+
* ```
|
113
|
+
*/
|
114
|
+
getPriceSetterRoleHash(): Promise<string>;
|
115
|
+
/**
|
116
|
+
* Checks if an address has the price setter role
|
117
|
+
*
|
118
|
+
* @param address - The address to check
|
119
|
+
* @returns Boolean indicating if the address has price setter role
|
120
|
+
*
|
121
|
+
* @example
|
122
|
+
* ```typescript
|
123
|
+
* const hasPriceSetterRole = await sdk.hasPriceSetterRole("0x...");
|
124
|
+
* ```
|
125
|
+
*/
|
126
|
+
hasPriceSetterRole(address: string): Promise<boolean>;
|
127
|
+
/**
|
128
|
+
* Builds a transaction to grant price setter role to an address
|
129
|
+
*
|
130
|
+
* @param address - The address to grant price setter role to
|
131
|
+
* @returns Populated transaction
|
132
|
+
*
|
133
|
+
* @example
|
134
|
+
* ```typescript
|
135
|
+
* const tx = await sdk.buildGrantPriceSetterRoleTx("0x...");
|
136
|
+
* ```
|
137
|
+
*/
|
138
|
+
buildGrantPriceSetterRoleTx(address: string): Promise<ethers.ContractTransaction>;
|
139
|
+
/**
|
140
|
+
* Gets the DEFAULT_ADMIN_ROLE hash
|
141
|
+
*
|
142
|
+
* @returns The DEFAULT_ADMIN_ROLE hash
|
143
|
+
*
|
144
|
+
* @example
|
145
|
+
* ```typescript
|
146
|
+
* const adminRoleHash = await sdk.getAdminRoleHash();
|
147
|
+
* ```
|
148
|
+
*/
|
149
|
+
getAdminRoleHash(): Promise<string>;
|
150
|
+
/**
|
151
|
+
* Checks if an address has the admin role
|
152
|
+
*
|
153
|
+
* @param address - The address to check
|
154
|
+
* @returns Boolean indicating if the address has admin role
|
155
|
+
*
|
156
|
+
* @example
|
157
|
+
* ```typescript
|
158
|
+
* const hasAdminRole = await sdk.hasAdminRole("0x...");
|
159
|
+
* ```
|
160
|
+
*/
|
161
|
+
hasAdminRole(address: string): Promise<boolean>;
|
162
|
+
/**
|
163
|
+
* Builds a transaction to grant admin role to an address
|
164
|
+
*
|
165
|
+
* @param address - The address to grant admin role to
|
166
|
+
* @returns Populated transaction
|
167
|
+
*
|
168
|
+
* @example
|
169
|
+
* ```typescript
|
170
|
+
* const tx = await sdk.buildGrantAdminRoleTx("0x...");
|
171
|
+
* ```
|
172
|
+
*/
|
173
|
+
buildGrantAdminRoleTx(address: string): Promise<ethers.ContractTransaction>;
|
69
174
|
getPrice(): Promise<number>;
|
70
175
|
getPriceRaw(): Promise<bigint>;
|
71
176
|
getCurrency(): Promise<string>;
|
@@ -109,7 +214,7 @@ export declare class TradingVaultSDK {
|
|
109
214
|
weight: number;
|
110
215
|
duration: number;
|
111
216
|
}>;
|
112
|
-
getAllEvents(fromBlock: number, toBlock: number): Promise<AnyEventRaw[]>;
|
217
|
+
getAllEvents(fromBlock: number, toBlock: number, whitelistEvents?: string[]): Promise<AnyEventRaw[]>;
|
113
218
|
streamEvents(fromBlock: number, onEvent: (event: AnyEvent) => Promise<void>, saveLatestBlock: (blockNumber: number) => Promise<void>, batchSize?: number, sleepTime?: number): Promise<void>;
|
114
219
|
formatEventArgs: (event: AnyEventRaw) => AnyEvent;
|
115
220
|
estimateUnrealizedPnl({ price, entryPrice, initAmount, remainingAmount, }: {
|
package/dist/TradingVault.js
CHANGED
@@ -1 +1 @@
|
|
1
|
-
"use strict";var t=this&&this.__importDefault||function(t){return t&&t.__esModule?t:{default:t}};Object.defineProperty(exports,"__esModule",{value:!0}),exports.TradingVaultSDK=void 0;const e=require("ethers"),r=t(require("./abis/TradingVault.json")),a=t(require("./contracts.json")),n=require("./utils");exports.TradingVaultSDK=class{constructor(t,i){this.name="TradingVault",this._currency=null,this._rewardToken=null,this._currencyDecimals=null,this._rewardTokenDecimals=null,this.priceDecimals=6,this.isBootstrapped=!1,this.configs=[],this.BASE_WEIGHT=1e4,this.BASE_PRICE=100,this.formatEventArgs=t=>{const e=this._currencyDecimals,r=this._rewardTokenDecimals,{eventName:a,args:n}=t;switch(a){case"PositionCreated":return{...t,args:{...n,user:n.user.toLowerCase(),amount:Number(n.amount)/Math.pow(10,e),entryPrice:Number(n.entryPrice)/Math.pow(10,this.priceDecimals),tokenId:Number(n.tokenId),openedAt:Number(n.openedAt)}};case"PositionReduced":return{...t,args:{...n,user:n.user.toLowerCase(),reducedAmount:Number(n.reducedAmount)/Math.pow(10,e),remainingAmount:Number(n.remainingAmount)/Math.pow(10,e),totalReward:Number(n.totalReward)/Math.pow(10,r),userReward:Number(n.userReward)/Math.pow(10,r),treasuryReward:Number(n.treasuryReward)/Math.pow(10,r),rewardedAmount:Number(n.rewardedAmount)/Math.pow(10,r),weight:Number(n.weight),tokenId:Number(n.tokenId),lossAmount:Number(n.lossAmount)/Math.pow(10,e),price:Number(n.price)/Math.pow(10,this.priceDecimals),loss:Number(n.loss)/Math.pow(10,e)}};case"CurrencyBorrowed":case"CurrencyRepaid":return{...t,args:{...n,amount:Number(n.amount)/Math.pow(10,e),borrower:n.borrower.toLowerCase()}};case"PriceUpdated":return{...t,args:{...n,oldPrice:Number(n.oldPrice)/Math.pow(10,this.priceDecimals),newPrice:Number(n.newPrice)/Math.pow(10,this.priceDecimals),requiredReward:Number(n.requiredReward)/Math.pow(10,r)}};case"TotalAmountUpdated":return{...t,args:{...n,newTotalAmount:Number(n.newTotalAmount)/Math.pow(10,e)}};case"CurrencyUpdated":return{...t,args:{...n,oldCurrency:n.oldCurrency.toLowerCase(),newCurrency:n.newCurrency.toLowerCase()}};case"RewardTokenUpdated":return{...t,args:{...n,oldRewardToken:n.oldRewardToken.toLowerCase(),newRewardToken:n.newRewardToken.toLowerCase()}};case"ReduceEnabledUpdated":return{...t,args:{...n,enabled:n.enabled}};case"TreasuryUpdated":return{...t,args:{...n,oldTreasury:n.oldTreasury.toLowerCase(),newTreasury:n.newTreasury.toLowerCase()}};case"RewardConfigsUpdated":return{...t,args:{...n}};case"TotalRewardsUpdated":case"TotalRewardsHarvestedUpdated":return{...t,args:{...n,oldAmount:Number(n.oldAmount)/Math.pow(10,r),newAmount:Number(n.newAmount)/Math.pow(10,r)}};default:return t}};const o=Array.isArray(t)?t:[t];this.providers=o.map((t=>new e.ethers.JsonRpcProvider(t)));const s=(0,n.getRandomProvider)(this.providers);this.contractAddress=(0,n.resolveContractAddress)(o[0],this.name,a.default,i),this.contract=new e.ethers.Contract(this.contractAddress,r.default.abi,s)}getRandomProvider(){return(0,n.getRandomProvider)(this.providers)}getContractWithRandomProvider(){return new e.ethers.Contract(this.contractAddress,r.default.abi,this.getRandomProvider())}async bootstrap(){if(this.isBootstrapped)return;const t=await Promise.all(this.providers.map(((t,e)=>(0,n.checkRpcHealth)(t,e))));if(this.providers=this.providers.filter(((e,r)=>t[r])),0===this.providers.length)throw new Error("No active RPC providers available");await Promise.all([this.getCurrencyDecimals(),this.getRewardTokenDecimals(),(async()=>{const t=await this.getRewardConfigsLength(),e=[];for(let r=0;r<t;r++)e.push(this.getRewardConfig(r));const r=await Promise.all(e);this.configs=r.map((t=>({weight:Number(t.weight)/this.BASE_WEIGHT,duration:Number(t.duration)})))})()]),this.isBootstrapped=!0}async signAndSendTransaction(t,e,r={}){return(0,n.signAndSendTransaction)(t,e,(()=>this.getRandomProvider()),r)}async buildCreatePositionTx(t,e){const r=await this.getCurrencyDecimals(),a=BigInt(Math.floor(t*Math.pow(10,r)));return this.buildCreatePositionTxRaw(a,e)}async buildReducePositionTx(t,e){const r=await this.getCurrencyDecimals(),a=BigInt(Math.floor(e*Math.pow(10,r)));return this.buildReducePositionTxRaw(t,a)}async buildReducePositionsTx(t,e){const r=await this.getCurrencyDecimals(),a=e.map((t=>BigInt(Math.floor(t*Math.pow(10,r)))));return this.buildReducePositionsTxRaw(t,a)}async buildBorrowCurrencyTx(t){const e=await this.getCurrencyDecimals(),r=BigInt(Math.floor(t*Math.pow(10,e)));return this.buildBorrowCurrencyTxRaw(r)}async buildRepayCurrencyTx(t){const e=await this.getCurrencyDecimals(),r=BigInt(Math.floor(t*Math.pow(10,e)));return this.buildRepayCurrencyTxRaw(r)}async buildSetPriceTx(t){const e=this.priceDecimals,r=BigInt(Math.floor(t*Math.pow(10,e)));return this.buildSetPriceTxRaw(r)}async buildClaimERC20Tx(t,r){const a=new e.ethers.Contract(t,["function decimals() view returns (uint8)"],this.getRandomProvider()),n=await a.decimals(),i=BigInt(Math.floor(r*Math.pow(10,n)));return this.buildClaimERC20TxRaw(t,i)}async buildCreatePositionTxRaw(t,e){return await this.contract.createPosition.populateTransaction(t,e)}async buildReducePositionTxRaw(t,e){return await this.contract.reducePosition.populateTransaction(t,e)}async buildReducePositionsTxRaw(t,e){return await this.contract.reducePositions.populateTransaction(t,e)}async buildBorrowCurrencyTxRaw(t){return await this.contract.borrowCurrency.populateTransaction(t)}async buildRepayCurrencyTxRaw(t){return await this.contract.repayCurrency.populateTransaction(t)}async buildSetPriceTxRaw(t){return await this.contract.setPrice.populateTransaction(t)}async buildSetCurrencyTxRaw(t){this._currency=null;return await this.contract.setCurrency.populateTransaction(t)}async buildSetRewardTokenTxRaw(t){this._rewardToken=null;return await this.contract.setRewardToken.populateTransaction(t)}async buildSetTreasuryTxRaw(t){return await this.contract.setTreasury.populateTransaction(t)}async buildUpdateRewardConfigsTxRaw(t){return await this.contract.updateRewardConfigs.populateTransaction(t)}async buildSetReduceEnabledTxRaw(t){return await this.contract.setReduceEnabled.populateTransaction(t)}async buildClaimERC20TxRaw(t,e){return await this.contract.claimERC20.populateTransaction(t,e)}async buildApproveERC20Tx(t,r,a){const n=new e.ethers.Contract(t,["function decimals() view returns (uint8)"],this.getRandomProvider()),i=await n.decimals(),o=BigInt(Math.floor(a*Math.pow(10,Number(i))));return this.buildApproveERC20TxRaw(t,r,o)}async buildApproveERC20TxRaw(t,e,r){return await(0,n.buildApproveERC20Tx)(t,e,r,this.getRandomProvider())}async getAllowanceRaw(t,e,r){return await(0,n.getTokenAllowance)(t,e,r,this.getRandomProvider())}async getAllowance(t,e,r){const[a,i]=await Promise.all([this.getAllowanceRaw(t,e,r),(0,n.getTokenDecimals)(t,this.getRandomProvider())]);return Number(a)/Math.pow(10,i)}async buildGrantOperatorRoleTxRaw(t){return await this.contract.grantOperatorRole.populateTransaction(t)}async getPrice(){const t=await this.getPriceRaw(),e=this.priceDecimals;return Number(t)/Math.pow(10,e)}async getPriceRaw(){return await this.contract.price()}async getCurrency(){return this._currency||(this._currency=await this.contract.currency()),this._currency}async getRewardToken(){return this._rewardToken||(this._rewardToken=await this.contract.rewardToken()),this._rewardToken}async getTreasury(){return await this.contract.treasury()}async getTotalAmount(){const t=await this.getTotalAmountRaw(),e=await this.getCurrencyDecimals();return Number(t)/Math.pow(10,e)}async getTotalAmountRaw(){return await this.contract.totalAmount()}async getTotalBorrowed(){const t=await this.getTotalBorrowedRaw(),e=await this.getCurrencyDecimals();return Number(t)/Math.pow(10,e)}async getTotalBorrowedRaw(){return await this.contract.totalBorrowed()}async isReduceEnabled(){return await this.contract.isReduceEnabled()}async getPosition(t){const e=await this.getPositionRaw(t),r=await this.getCurrencyDecimals(),a=await this.getRewardTokenDecimals(),n=this.priceDecimals;return{remainingAmount:Number(e.remainingAmount)/Math.pow(10,r),entryPrice:Number(e.entryPrice)/Math.pow(10,n),outPrice:Number(e.outPrice)/Math.pow(10,n),openedAt:Number(e.openedAt),closedAt:Number(e.closedAt),rewardedAmount:Number(e.rewardedAmount)/Math.pow(10,a),lossAmount:Number(e.lossAmount)/Math.pow(10,r),initAmount:Number(e.initAmount)/Math.pow(10,r)}}async getPositionRaw(t){return await this.contract.positions(t)}async getRewardConfig(t){return await this.contract.rewardConfigs(t)}async getRewardConfigsLength(){return await this.contract.getRewardConfigsLength()}async getCurrencyDecimals(){if(null===this._currencyDecimals){const t=await this.getCurrency(),r=new e.ethers.Contract(t,["function decimals() view returns (uint8)"],this.getRandomProvider());this._currencyDecimals=Number(await r.decimals())}return this._currencyDecimals}async getRewardTokenDecimals(){if(null===this._rewardTokenDecimals){const t=await this.getRewardToken(),r=new e.ethers.Contract(t,["function decimals() view returns (uint8)"],this.getRandomProvider());this._rewardTokenDecimals=Number(await r.decimals())}return this._rewardTokenDecimals}getContractAddress(){return this.contractAddress}getConfigs(){return[...this.configs]}async getAllEvents(t,e){return await this.bootstrap(),(0,n.getAllEvents)(this.contract,(()=>this.getRandomProvider()),(()=>this.getContractWithRandomProvider()),t,e)}async streamEvents(t,e,r,a=1e3,i=5e3){return await this.bootstrap(),(0,n.streamEvents)({getProvider:()=>this.getRandomProvider(),getAllEvents:(t,e)=>this.getAllEvents(t,e),formatEvent:t=>this.formatEventArgs(t),onEvent:e,saveLatestBlock:r,fromBlock:t,batchSize:a,sleepTime:i})}estimateUnrealizedPnl({price:t,entryPrice:e,initAmount:r,remainingAmount:a}){const n=a*(t-e)/this.BASE_PRICE;return{pnl:n,pnlPercentage:n/r*100}}estReducePosition({amount:t,price:e,entryPrice:r,openedAt:a,configs:n=[]}){const i=this.BASE_PRICE;this.BASE_WEIGHT;let o=t,s=0,c=0,u=0,d=0;if(e<r){return o=t-t*(r-e)/100,{amount:o,totalReward:0,userReward:0,treasuryReward:0,weight:0}}if(e>=r){s=t*(e-r)/i;const o=Math.floor(Date.now()/1e3)-a;d=this.getRewardWeight(o,n),c=s*d,u=s-c}return{amount:o,totalReward:s,userReward:c,treasuryReward:u,weight:d}}estReducePositions({positions:t,price:e,configs:r=[]}){return t.map((t=>this.estReducePosition({amount:t.amount,price:e,entryPrice:t.entryPrice,openedAt:t.openedAt,configs:r}))).reduce(((t,e)=>({amount:t.amount+e.amount,totalReward:t.totalReward+e.totalReward,userReward:t.userReward+e.userReward,treasuryReward:t.treasuryReward+e.treasuryReward})),{amount:0,totalReward:0,userReward:0,treasuryReward:0})}getRewardWeight(t,e){return(0,n.getRewardWeight)(t,e)}estimateUnrealizedPnls({price:t,positions:e}){return e.reduce(((e,r)=>{const{pnl:a}=this.estimateUnrealizedPnl({price:t,...r});return{totalInitAmount:e.totalInitAmount+r.initAmount,totalRemainingAmount:e.totalRemainingAmount+r.remainingAmount,totalRewardedAmount:e.totalRewardedAmount+r.rewardedAmount,totalLossAmount:e.totalLossAmount+r.lossAmount,totalPnl:e.totalPnl+a}}),{totalInitAmount:0,totalRemainingAmount:0,totalRewardedAmount:0,totalLossAmount:0,totalPnl:0})}async buildAddReward(t){const e=await this.getRewardTokenDecimals(),r=BigInt(Math.floor(t*Math.pow(10,e)));return this.buildAddRewardTxRaw(r)}async buildAddRewardTxRaw(t){return await this.contract.addReward.populateTransaction(t)}};
|
1
|
+
"use strict";var t=this&&this.__importDefault||function(t){return t&&t.__esModule?t:{default:t}};Object.defineProperty(exports,"__esModule",{value:!0}),exports.TradingVaultSDK=void 0;const e=require("ethers"),r=t(require("./abis/TradingVault.json")),a=t(require("./contracts.json")),n=require("./utils");exports.TradingVaultSDK=class{constructor(t,o){this.name="TradingVault",this._currency=null,this._rewardToken=null,this._currencyDecimals=null,this._rewardTokenDecimals=null,this.priceDecimals=6,this.isBootstrapped=!1,this.configs=[],this.BASE_WEIGHT=1e4,this.BASE_PRICE=100,this.formatEventArgs=t=>{const e=this._currencyDecimals,r=this._rewardTokenDecimals,{eventName:a,args:n}=t;switch(a){case"PositionCreated":return{...t,args:{...n,user:n.user.toLowerCase(),amount:Number(n.amount)/Math.pow(10,e),entryPrice:Number(n.entryPrice)/Math.pow(10,this.priceDecimals),tokenId:Number(n.tokenId),openedAt:Number(n.openedAt)}};case"PositionReduced":return{...t,args:{...n,user:n.user.toLowerCase(),reducedAmount:Number(n.reducedAmount)/Math.pow(10,e),remainingAmount:Number(n.remainingAmount)/Math.pow(10,e),totalReward:Number(n.totalReward)/Math.pow(10,r),userReward:Number(n.userReward)/Math.pow(10,r),treasuryReward:Number(n.treasuryReward)/Math.pow(10,r),rewardedAmount:Number(n.rewardedAmount)/Math.pow(10,r),weight:Number(n.weight),tokenId:Number(n.tokenId),lossAmount:Number(n.lossAmount)/Math.pow(10,e),price:Number(n.price)/Math.pow(10,this.priceDecimals),loss:Number(n.loss)/Math.pow(10,e)}};case"CurrencyBorrowed":case"CurrencyRepaid":return{...t,args:{...n,amount:Number(n.amount)/Math.pow(10,e),borrower:n.borrower.toLowerCase()}};case"PriceUpdated":return{...t,args:{...n,oldPrice:Number(n.oldPrice)/Math.pow(10,this.priceDecimals),newPrice:Number(n.newPrice)/Math.pow(10,this.priceDecimals),requiredReward:Number(n.requiredReward)/Math.pow(10,r)}};case"TotalAmountUpdated":return{...t,args:{...n,newTotalAmount:Number(n.newTotalAmount)/Math.pow(10,e)}};case"CurrencyUpdated":return{...t,args:{...n,oldCurrency:n.oldCurrency.toLowerCase(),newCurrency:n.newCurrency.toLowerCase()}};case"RewardTokenUpdated":return{...t,args:{...n,oldRewardToken:n.oldRewardToken.toLowerCase(),newRewardToken:n.newRewardToken.toLowerCase()}};case"ReduceEnabledUpdated":return{...t,args:{...n,enabled:n.enabled}};case"TreasuryUpdated":return{...t,args:{...n,oldTreasury:n.oldTreasury.toLowerCase(),newTreasury:n.newTreasury.toLowerCase()}};case"RewardConfigsUpdated":return{...t,args:{...n}};case"TotalRewardsUpdated":case"TotalRewardsHarvestedUpdated":return{...t,args:{...n,oldAmount:Number(n.oldAmount)/Math.pow(10,r),newAmount:Number(n.newAmount)/Math.pow(10,r)}};default:return t}};const i=Array.isArray(t)?t:[t];this.providers=i.map((t=>new e.ethers.JsonRpcProvider(t)));const s=(0,n.getRandomProvider)(this.providers);this.contractAddress=(0,n.resolveContractAddress)(i[0],this.name,a.default,o),this.contract=new e.ethers.Contract(this.contractAddress,r.default.abi,s)}getRandomProvider(){return(0,n.getRandomProvider)(this.providers)}getContractWithRandomProvider(){return new e.ethers.Contract(this.contractAddress,r.default.abi,this.getRandomProvider())}async bootstrap(){if(this.isBootstrapped)return;const t=await Promise.all(this.providers.map(((t,e)=>(0,n.checkRpcHealth)(t,e))));if(this.providers=this.providers.filter(((e,r)=>t[r])),0===this.providers.length)throw new Error("No active RPC providers available");await Promise.all([this.getCurrencyDecimals(),this.getRewardTokenDecimals(),(async()=>{const t=await this.getRewardConfigsLength(),e=[];for(let r=0;r<t;r++)e.push(this.getRewardConfig(r));const r=await Promise.all(e);this.configs=r.map((t=>({weight:Number(t.weight)/this.BASE_WEIGHT,duration:Number(t.duration)})))})()]),this.isBootstrapped=!0}async signAndSendTransaction(t,e,r={}){return(0,n.signAndSendTransaction)(t,e,(()=>this.getRandomProvider()),r)}async buildCreatePositionTx(t,e){const r=await this.getCurrencyDecimals(),a=BigInt(Math.floor(t*Math.pow(10,r)));return this.buildCreatePositionTxRaw(a,e)}async buildReducePositionTx(t,e){const r=await this.getCurrencyDecimals(),a=BigInt(Math.floor(e*Math.pow(10,r)));return this.buildReducePositionTxRaw(t,a)}async buildReducePositionsTx(t,e){const r=await this.getCurrencyDecimals(),a=e.map((t=>BigInt(Math.floor(t*Math.pow(10,r)))));return this.buildReducePositionsTxRaw(t,a)}async buildBorrowCurrencyTx(t){const e=await this.getCurrencyDecimals(),r=BigInt(Math.floor(t*Math.pow(10,e)));return this.buildBorrowCurrencyTxRaw(r)}async buildRepayCurrencyTx(t){const e=await this.getCurrencyDecimals(),r=BigInt(Math.floor(t*Math.pow(10,e)));return this.buildRepayCurrencyTxRaw(r)}async buildSetPriceTx(t){const e=this.priceDecimals,r=BigInt(Math.floor(t*Math.pow(10,e)));return this.buildSetPriceTxRaw(r)}async buildClaimERC20Tx(t,r){const a=new e.ethers.Contract(t,["function decimals() view returns (uint8)"],this.getRandomProvider()),n=await a.decimals(),o=BigInt(Math.floor(r*Math.pow(10,n)));return this.buildClaimERC20TxRaw(t,o)}async buildCreatePositionTxRaw(t,e){return await this.contract.createPosition.populateTransaction(t,e)}async buildReducePositionTxRaw(t,e){return await this.contract.reducePosition.populateTransaction(t,e)}async buildReducePositionsTxRaw(t,e){return await this.contract.reducePositions.populateTransaction(t,e)}async buildBorrowCurrencyTxRaw(t){return await this.contract.borrowCurrency.populateTransaction(t)}async buildRepayCurrencyTxRaw(t){return await this.contract.repayCurrency.populateTransaction(t)}async buildSetPriceTxRaw(t){return await this.contract.setPrice.populateTransaction(t)}async buildSetCurrencyTxRaw(t){this._currency=null;return await this.contract.setCurrency.populateTransaction(t)}async buildSetRewardTokenTxRaw(t){this._rewardToken=null;return await this.contract.setRewardToken.populateTransaction(t)}async buildSetTreasuryTxRaw(t){return await this.contract.setTreasury.populateTransaction(t)}async buildUpdateRewardConfigsTxRaw(t){return await this.contract.updateRewardConfigs.populateTransaction(t)}async buildSetReduceEnabledTxRaw(t){return await this.contract.setReduceEnabled.populateTransaction(t)}async buildClaimERC20TxRaw(t,e){return await this.contract.claimERC20.populateTransaction(t,e)}async buildApproveERC20Tx(t,r,a){const n=new e.ethers.Contract(t,["function decimals() view returns (uint8)"],this.getRandomProvider()),o=await n.decimals(),i=BigInt(Math.floor(a*Math.pow(10,Number(o))));return this.buildApproveERC20TxRaw(t,r,i)}async buildApproveERC20TxRaw(t,e,r){return await(0,n.buildApproveERC20Tx)(t,e,r,this.getRandomProvider())}async getAllowanceRaw(t,e,r){return await(0,n.getTokenAllowance)(t,e,r,this.getRandomProvider())}async getAllowance(t,e,r){const[a,o]=await Promise.all([this.getAllowanceRaw(t,e,r),(0,n.getTokenDecimals)(t,this.getRandomProvider())]);return Number(a)/Math.pow(10,o)}async buildGrantOperatorRoleTxRaw(t){return await this.contract.grantOperatorRole.populateTransaction(t)}async getOperatorRoleHash(){return await this.contract.OPERATOR_ROLE()}async hasOperatorRole(t){const e=await this.contract.OPERATOR_ROLE();return await this.contract.hasRole(e,t)}async buildGrantOperatorRoleTx(t){return await this.contract.grantOperatorRole.populateTransaction(t)}async getPriceSetterRoleHash(){return await this.contract.PRICE_SETTER_ROLE()}async hasPriceSetterRole(t){const e=await this.contract.PRICE_SETTER_ROLE();return await this.contract.hasRole(e,t)}async buildGrantPriceSetterRoleTx(t){return await this.contract.grantPriceSetterRole.populateTransaction(t)}async getAdminRoleHash(){return await this.contract.DEFAULT_ADMIN_ROLE()}async hasAdminRole(t){const e=await this.contract.DEFAULT_ADMIN_ROLE();return await this.contract.hasRole(e,t)}async buildGrantAdminRoleTx(t){const e=await this.contract.DEFAULT_ADMIN_ROLE();return await this.contract.grantRole.populateTransaction(e,t)}async getPrice(){const t=await this.getPriceRaw(),e=this.priceDecimals;return Number(t)/Math.pow(10,e)}async getPriceRaw(){return await this.contract.price()}async getCurrency(){return this._currency||(this._currency=await this.contract.currency()),this._currency}async getRewardToken(){return this._rewardToken||(this._rewardToken=await this.contract.rewardToken()),this._rewardToken}async getTreasury(){return await this.contract.treasury()}async getTotalAmount(){const t=await this.getTotalAmountRaw(),e=await this.getCurrencyDecimals();return Number(t)/Math.pow(10,e)}async getTotalAmountRaw(){return await this.contract.totalAmount()}async getTotalBorrowed(){const t=await this.getTotalBorrowedRaw(),e=await this.getCurrencyDecimals();return Number(t)/Math.pow(10,e)}async getTotalBorrowedRaw(){return await this.contract.totalBorrowed()}async isReduceEnabled(){return await this.contract.isReduceEnabled()}async getPosition(t){const e=await this.getPositionRaw(t),r=await this.getCurrencyDecimals(),a=await this.getRewardTokenDecimals(),n=this.priceDecimals;return{remainingAmount:Number(e.remainingAmount)/Math.pow(10,r),entryPrice:Number(e.entryPrice)/Math.pow(10,n),outPrice:Number(e.outPrice)/Math.pow(10,n),openedAt:Number(e.openedAt),closedAt:Number(e.closedAt),rewardedAmount:Number(e.rewardedAmount)/Math.pow(10,a),lossAmount:Number(e.lossAmount)/Math.pow(10,r),initAmount:Number(e.initAmount)/Math.pow(10,r)}}async getPositionRaw(t){return await this.contract.positions(t)}async getRewardConfig(t){return await this.contract.rewardConfigs(t)}async getRewardConfigsLength(){return await this.contract.getRewardConfigsLength()}async getCurrencyDecimals(){if(null===this._currencyDecimals){const t=await this.getCurrency(),r=new e.ethers.Contract(t,["function decimals() view returns (uint8)"],this.getRandomProvider());this._currencyDecimals=Number(await r.decimals())}return this._currencyDecimals}async getRewardTokenDecimals(){if(null===this._rewardTokenDecimals){const t=await this.getRewardToken(),r=new e.ethers.Contract(t,["function decimals() view returns (uint8)"],this.getRandomProvider());this._rewardTokenDecimals=Number(await r.decimals())}return this._rewardTokenDecimals}getContractAddress(){return this.contractAddress}getConfigs(){return[...this.configs]}async getAllEvents(t,e,r){return await this.bootstrap(),(0,n.getAllEvents)(this.contract,(()=>this.getRandomProvider()),(()=>this.getContractWithRandomProvider()),t,e,r)}async streamEvents(t,e,r,a=1e3,o=5e3){const i=["CurrencyBorrowed","CurrencyRepaid","CurrencyUpdated","PositionCreated","PositionReduced","PriceUpdated","ReduceEnabledUpdated","RewardConfigsUpdated","RewardTokenUpdated","TotalAmountUpdated","TotalRewardsHarvestedUpdated","TotalRewardsUpdated","Transfer","TreasuryUpdated"];return await this.bootstrap(),(0,n.streamEvents)({getProvider:()=>this.getRandomProvider(),getAllEvents:(t,e)=>this.getAllEvents(t,e,i),formatEvent:t=>this.formatEventArgs(t),onEvent:e,saveLatestBlock:r,fromBlock:t,batchSize:a,sleepTime:o})}estimateUnrealizedPnl({price:t,entryPrice:e,initAmount:r,remainingAmount:a}){const n=a*(t-e)/this.BASE_PRICE;return{pnl:n,pnlPercentage:n/r*100}}estReducePosition({amount:t,price:e,entryPrice:r,openedAt:a,configs:n=[]}){const o=this.BASE_PRICE;this.BASE_WEIGHT;let i=t,s=0,c=0,u=0,d=0;if(e<r){return i=t-t*(r-e)/100,{amount:i,totalReward:0,userReward:0,treasuryReward:0,weight:0}}if(e>=r){s=t*(e-r)/o;const i=Math.floor(Date.now()/1e3)-a;d=this.getRewardWeight(i,n),c=s*d,u=s-c}return{amount:i,totalReward:s,userReward:c,treasuryReward:u,weight:d}}estReducePositions({positions:t,price:e,configs:r=[]}){return t.map((t=>this.estReducePosition({amount:t.amount,price:e,entryPrice:t.entryPrice,openedAt:t.openedAt,configs:r}))).reduce(((t,e)=>({amount:t.amount+e.amount,totalReward:t.totalReward+e.totalReward,userReward:t.userReward+e.userReward,treasuryReward:t.treasuryReward+e.treasuryReward})),{amount:0,totalReward:0,userReward:0,treasuryReward:0})}getRewardWeight(t,e){return(0,n.getRewardWeight)(t,e)}estimateUnrealizedPnls({price:t,positions:e}){return e.reduce(((e,r)=>{const{pnl:a}=this.estimateUnrealizedPnl({price:t,...r});return{totalInitAmount:e.totalInitAmount+r.initAmount,totalRemainingAmount:e.totalRemainingAmount+r.remainingAmount,totalRewardedAmount:e.totalRewardedAmount+r.rewardedAmount,totalLossAmount:e.totalLossAmount+r.lossAmount,totalPnl:e.totalPnl+a}}),{totalInitAmount:0,totalRemainingAmount:0,totalRewardedAmount:0,totalLossAmount:0,totalPnl:0})}async buildAddReward(t){const e=await this.getRewardTokenDecimals(),r=BigInt(Math.floor(t*Math.pow(10,e)));return this.buildAddRewardTxRaw(r)}async buildAddRewardTxRaw(t){return await this.contract.addReward.populateTransaction(t)}};
|
package/dist/utils.d.ts
CHANGED
@@ -37,11 +37,13 @@ export interface BaseEventRaw {
|
|
37
37
|
* Generic function to get all events from a contract within a block range
|
38
38
|
* @param contract The ethers contract instance
|
39
39
|
* @param getRandomProvider Function to get a random provider
|
40
|
+
* @param getContractWithRandomProvider Function to get a contract with a random provider
|
40
41
|
* @param fromBlock Starting block number
|
41
42
|
* @param toBlock Ending block number
|
43
|
+
* @param whitelistEvents Optional array of event names to filter (only these events will be retrieved)
|
42
44
|
* @returns Array of parsed events with timestamps
|
43
45
|
*/
|
44
|
-
export declare const getAllEvents: <TEventRaw extends BaseEventRaw, TContract extends ethers.BaseContract>(contract: TContract, getRandomProvider: () => ethers.Provider, getContractWithRandomProvider: () => TContract, fromBlock: number, toBlock: number) => Promise<TEventRaw[]>;
|
46
|
+
export declare const getAllEvents: <TEventRaw extends BaseEventRaw, TContract extends ethers.BaseContract>(contract: TContract, getRandomProvider: () => ethers.Provider, getContractWithRandomProvider: () => TContract, fromBlock: number, toBlock: number, whitelistEvents?: string[]) => Promise<TEventRaw[]>;
|
45
47
|
/**
|
46
48
|
* Generic function to stream blockchain events
|
47
49
|
* @param getProvider Function to get a provider
|
@@ -52,16 +54,18 @@ export declare const getAllEvents: <TEventRaw extends BaseEventRaw, TContract ex
|
|
52
54
|
* @param fromBlock Starting block number
|
53
55
|
* @param batchSize Number of blocks to process in each batch
|
54
56
|
* @param sleepTime Time to wait between iterations when caught up
|
57
|
+
* @param whitelistEvents Optional array of event names to filter (only these events will be retrieved)
|
55
58
|
*/
|
56
|
-
export declare const streamEvents: <TRawEvent, TFormattedEvent>({ getProvider, getAllEvents, formatEvent, onEvent, saveLatestBlock, fromBlock, batchSize, sleepTime, }: {
|
59
|
+
export declare const streamEvents: <TRawEvent, TFormattedEvent>({ getProvider, getAllEvents, formatEvent, onEvent, saveLatestBlock, fromBlock, batchSize, sleepTime, whitelistEvents, }: {
|
57
60
|
getProvider: () => ethers.Provider;
|
58
|
-
getAllEvents: (fromBlock: number, toBlock: number) => Promise<TRawEvent[]>;
|
61
|
+
getAllEvents: (fromBlock: number, toBlock: number, whitelistEvents?: string[]) => Promise<TRawEvent[]>;
|
59
62
|
formatEvent: (event: TRawEvent) => TFormattedEvent;
|
60
63
|
onEvent: (event: TFormattedEvent) => Promise<void>;
|
61
64
|
saveLatestBlock: (blockNumber: number) => Promise<void>;
|
62
65
|
fromBlock: number;
|
63
66
|
batchSize?: number;
|
64
67
|
sleepTime?: number;
|
68
|
+
whitelistEvents?: string[];
|
65
69
|
}) => Promise<void>;
|
66
70
|
/**
|
67
71
|
* Generic function to sign and send a transaction
|
package/dist/utils.js
CHANGED
@@ -1 +1 @@
|
|
1
|
-
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.getNetworkFromRpc=exports.signAndSendTransaction=exports.streamEvents=exports.getAllEvents=exports.resolveContractAddress=exports.getRewardWeight=exports.buildApproveERC20Tx=exports.getTokenAllowance=exports.getTokenSymbol=exports.getTokenDecimals=exports.getTransactionStatus=exports.checkRpcHealth=exports.getRandomProvider=exports.sleep=exports.LOG_PREFIXES=void 0;const e=require("ethers");exports.LOG_PREFIXES={INFO:"[36m[STREAM-INFO][0m",BLOCK:"[33m[STREAM-BLOCK][0m",EVENT:"[32m[STREAM-EVENT][0m",ERROR:"[31m[STREAM-ERROR][0m",SAVE:"[35m[STREAM-SAVE][0m",DEBUG:"[34m[STREAM-DEBUG][0m"};exports.sleep=async e=>new Promise((t=>setTimeout(t,e)));exports.getRandomProvider=e=>e[Math.floor(Math.random()*e.length)];exports.checkRpcHealth=async(e,t=0)=>{try{const t=new Promise(((e,t)=>{setTimeout((()=>t(new Error("RPC request timeout"))),5e3)}));return await Promise.race([e.getBlockNumber(),t]),!0}catch(e){return console.error(`${exports.LOG_PREFIXES.ERROR} RPC health check failed:`,e,t),!1}};exports.getTransactionStatus=async(e,t,o=10)=>{let r=0,s=1e3;for(;r<o;)try{const a=await e.getTransactionReceipt(t);if(!a){if(r++,r===o)return{hash:t,status:null,confirmations:0,isCompleted:!1,attempts:r};await(0,exports.sleep)(s),s*=2;continue}const n=Number(await a.confirmations()||0);return{hash:a.hash,status:1===a.status,confirmations:n,isCompleted:!0,attempts:r+1}}catch(e){throw new Error(`Failed to get transaction status: ${e.message}`)}throw new Error("Failed to get transaction status after maximum retries")};exports.getTokenDecimals=async(t,o)=>{const r=new e.ethers.Contract(t,["function decimals() view returns (uint8)"],o);return Number(await r.decimals())};exports.getTokenSymbol=async(t,o)=>{const r=new e.ethers.Contract(t,["function symbol() view returns (string)"],o);return await r.symbol()};exports.getTokenAllowance=async(t,o,r,s)=>{if(t===e.ethers.ZeroAddress||t.toLowerCase()===e.ethers.ZeroAddress)return BigInt("0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff");const a=new e.ethers.Contract(t,["function allowance(address owner, address spender) view returns (uint256)"],s);return await a.allowance(o,r)};exports.buildApproveERC20Tx=async(t,o,r,s)=>{const a=new e.ethers.Contract(t,["function approve(address spender, uint256 amount) returns (bool)"],s);return await a.approve.populateTransaction(o,r)};exports.getRewardWeight=(e,t)=>{let o=0;const r=[...t].sort(((e,t)=>e.duration-t.duration));for(const t of r)e>=t.duration&&(o=t.weight);return o};exports.resolveContractAddress=(e,t,o,r)=>{if(r)return r;const s=(0,exports.getNetworkFromRpc)(e);return o?.[s]?.[t]};exports.getAllEvents=async(e,t,o,r,s)=>{
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.getNetworkFromRpc=exports.signAndSendTransaction=exports.streamEvents=exports.getAllEvents=exports.resolveContractAddress=exports.getRewardWeight=exports.buildApproveERC20Tx=exports.getTokenAllowance=exports.getTokenSymbol=exports.getTokenDecimals=exports.getTransactionStatus=exports.checkRpcHealth=exports.getRandomProvider=exports.sleep=exports.LOG_PREFIXES=void 0;const e=require("ethers");exports.LOG_PREFIXES={INFO:"[36m[STREAM-INFO][0m",BLOCK:"[33m[STREAM-BLOCK][0m",EVENT:"[32m[STREAM-EVENT][0m",ERROR:"[31m[STREAM-ERROR][0m",SAVE:"[35m[STREAM-SAVE][0m",DEBUG:"[34m[STREAM-DEBUG][0m"};exports.sleep=async e=>new Promise((t=>setTimeout(t,e)));exports.getRandomProvider=e=>e[Math.floor(Math.random()*e.length)];exports.checkRpcHealth=async(e,t=0)=>{try{const t=new Promise(((e,t)=>{setTimeout((()=>t(new Error("RPC request timeout"))),5e3)}));return await Promise.race([e.getBlockNumber(),t]),!0}catch(e){return console.error(`${exports.LOG_PREFIXES.ERROR} RPC health check failed:`,e,t),!1}};exports.getTransactionStatus=async(e,t,o=10)=>{let r=0,s=1e3;for(;r<o;)try{const a=await e.getTransactionReceipt(t);if(!a){if(r++,r===o)return{hash:t,status:null,confirmations:0,isCompleted:!1,attempts:r};await(0,exports.sleep)(s),s*=2;continue}const n=Number(await a.confirmations()||0);return{hash:a.hash,status:1===a.status,confirmations:n,isCompleted:!0,attempts:r+1}}catch(e){throw new Error(`Failed to get transaction status: ${e.message}`)}throw new Error("Failed to get transaction status after maximum retries")};exports.getTokenDecimals=async(t,o)=>{const r=new e.ethers.Contract(t,["function decimals() view returns (uint8)"],o);return Number(await r.decimals())};exports.getTokenSymbol=async(t,o)=>{const r=new e.ethers.Contract(t,["function symbol() view returns (string)"],o);return await r.symbol()};exports.getTokenAllowance=async(t,o,r,s)=>{if(t===e.ethers.ZeroAddress||t.toLowerCase()===e.ethers.ZeroAddress)return BigInt("0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff");const a=new e.ethers.Contract(t,["function allowance(address owner, address spender) view returns (uint256)"],s);return await a.allowance(o,r)};exports.buildApproveERC20Tx=async(t,o,r,s)=>{const a=new e.ethers.Contract(t,["function approve(address spender, uint256 amount) returns (bool)"],s);return await a.approve.populateTransaction(o,r)};exports.getRewardWeight=(e,t)=>{let o=0;const r=[...t].sort(((e,t)=>e.duration-t.duration));for(const t of r)e>=t.duration&&(o=t.weight);return o};exports.resolveContractAddress=(e,t,o,r)=>{if(r)return r;const s=(0,exports.getNetworkFromRpc)(e);return o?.[s]?.[t]};exports.getAllEvents=async(e,t,o,r,s,a)=>{let n=[];e.interface.forEachEvent((e=>{n.push(e.name)})),a&&a.length>0&&(n=n.filter((e=>a.includes(e))));const i=n.map((async t=>{const a=o(),n=a.filters[t]();return(await a.queryFilter(n,r,s)).map((o=>{const r=e.interface.parseLog({topics:o.topics,data:o.data});return{eventName:t,blockNumber:o.blockNumber,transactionHash:o.transactionHash,args:r?.args.toObject(),timestamp:null}}))})),c=(await Promise.all(i)).flat();c.sort(((e,t)=>e.blockNumber-t.blockNumber));const l=[...new Set(c.map((e=>e.blockNumber)))].map((e=>t().getBlock(e))),m=await Promise.all(l),p=new Map(m.map((e=>[e.number,e.timestamp])));return c.map((e=>({eventName:e.eventName,blockNumber:e.blockNumber,transactionHash:e.transactionHash,args:Object.fromEntries(Object.entries(e.args||{}).filter((([e])=>isNaN(Number(e))))),timestamp:p.get(e.blockNumber)??null})))};exports.streamEvents=async({getProvider:e,getAllEvents:t,formatEvent:o,onEvent:r,saveLatestBlock:s,fromBlock:a,batchSize:n=1e3,sleepTime:i=5e3,whitelistEvents:c})=>{const l="1"===process.env.DEBUG_STREAM_EVENTS;let m=a;for(l&&(console.log(`${exports.LOG_PREFIXES.INFO} StreamEvents Debug Mode Enabled`),console.log(`${exports.LOG_PREFIXES.INFO} Initial fromBlock: ${m}`),console.log(`${exports.LOG_PREFIXES.INFO} Batch size: ${n}`),console.log(`${exports.LOG_PREFIXES.INFO} Sleep time: ${i}ms`),c&&c.length>0&&console.log(`${exports.LOG_PREFIXES.INFO} Whitelist events: ${c.join(", ")}`));;)try{const a=await e().getBlockNumber();l&&console.log(`${exports.LOG_PREFIXES.BLOCK} Latest block: ${a}`);const p=Math.min(m+n,a);if(l&&console.log(`${exports.LOG_PREFIXES.BLOCK} Processing blocks from ${m} to ${p}`),m>=a){l&&console.log(`${exports.LOG_PREFIXES.DEBUG} Caught up to latest block, waiting ${i}ms...`),await(0,exports.sleep)(i);continue}const f=await t(m,p,c);if(l&&f.length>0){const e=f.reduce(((e,t)=>{const o=t.eventName||"Unknown";return e[o]=(e[o]||0)+1,e}),{});console.log(`${exports.LOG_PREFIXES.EVENT} Found ${f.length} events:`),Object.entries(e).forEach((([e,t])=>{console.log(`${exports.LOG_PREFIXES.EVENT} - ${e}: ${t}`)}))}for(const e of f)l&&console.log(`${exports.LOG_PREFIXES.EVENT} Processing: ${e.eventName||"Event"}`),await r(o(e));await s(p),l&&console.log(`${exports.LOG_PREFIXES.SAVE} Saved latest block: ${p}`),m=p+1}catch(e){l?(console.error(`${exports.LOG_PREFIXES.ERROR} Error in streamEvents:`,e),console.error(`${exports.LOG_PREFIXES.ERROR} Stack trace:`,e instanceof Error?e.stack:"")):console.error(`${exports.LOG_PREFIXES.ERROR} Error in streamEvents:`,e),await(0,exports.sleep)(1e3)}};exports.signAndSendTransaction=async(e,t,o,{onSubmit:r,onFinally:s,onError:a}={},n)=>{try{const a={...e};let n;if("object"==typeof t&&null!==t&&"sendTransaction"in t){const e=t.connect(o());n=(await e.sendTransaction(a)).hash}else n=await t(a);r&&await r(n);const i=await(0,exports.getTransactionStatus)(o(),n);if(null===i.status)throw new Error("Transaction may not be minted on-chain yet or has failed. Please check the blockchain explorer.");if(!1===i.status)throw new Error("Transaction failed. Please check the blockchain explorer for details.");return s&&await s({...i,txHash:n}),{transaction:{hash:n},status:i}}catch(e){if(n&&e)try{if("CALL_EXCEPTION"===e.code&&e.data){const t=e.data;for(const o of Object.values(n.interface.fragments).filter((e=>"error"===e.type)))if("name"in o){const r=n.interface.getError(o.name);if(r&&r.selector){if(r.selector===t){const t=o.name,r=e.errorArgs||[],s=new Error(`Transaction failed with custom error: ${t}(${r.join(", ")})`);throw Object.assign(s,e),a&&await a(s),s}}}console.log(`${exports.LOG_PREFIXES.DEBUG} Unknown custom error with selector: ${t}`)}}catch(e){console.error(`${exports.LOG_PREFIXES.ERROR} Error decoding transaction error:`,e)}throw a&&await a(e instanceof Error?e:new Error(String(e))),e}};exports.getNetworkFromRpc=e=>{const t=e.toLowerCase();let o=t;try{if(t.includes("://")){o=new URL(t).hostname}else t.includes("@")&&(o=t.split("@")[1].split("/")[0])}catch(e){console.warn(`${exports.LOG_PREFIXES.ERROR} Failed to parse RPC URL: ${t}`)}const r=[[/sepolia\.base|base-sepolia/,"base-sepolia"],[/goerli\.base|base-goerli/,"base-goerli"],[/base-mainnet/,"base"],[/polygon-mumbai|mumbai\.polygon/,"polygon-mumbai"],[/polygon-amoy|amoy\.polygon/,"polygon-amoy"],[/polygon-zkevm|zkevm|zkevm[-.]polygon/,"polygon-zkevm"],[/arbitrum.*sepolia|sepolia.*arbitrum/,"arbitrum-sepolia"],[/arbitrum.*goerli|goerli.*arbitrum/,"arbitrum-goerli"],[/arbitrum-nova|nova[-.]arbitrum/,"arbitrum-nova"],[/optimism-sepolia|sepolia[-.]optimism/,"optimism-sepolia"],[/optimism-goerli|goerli[-.]optimism/,"optimism-goerli"],[/avalanche-fuji|fuji[-.]avalanche|avax-test/,"avalanche-fuji"],[/bsc-testnet|testnet[-.]bsc|data-seed-prebsc/,"bsc-testnet"],[/base(?![-.]sepolia|[-.]goerli)/,"base"],[/polygon(?![-.]mumbai|[-.]amoy)/,"polygon"],[/arbitrum(?![-.]nova)/,"arbitrum"],[/optimism(?![-.]sepolia|[-.]goerli)/,"optimism"],[/avalanche|avax(?![-.]test|[-.]fuji)/,"avalanche"],[/bsc|binance(?![-.]testnet)/,"bsc"],[/eth-sepolia|sepolia(?![-.]base|[-.]arbitrum|[-.]optimism)/,"sepolia"],[/eth-goerli|goerli(?![-.]base|[-.]arbitrum|[-.]optimism)/,"goerli"],[/eth-mainnet|ethereum|eth\.rpc/,"ethereum"],[/mainnet/,"ethereum"]];for(const[e,o]of r)if(e.test(t))return o;for(const[e,t]of r)if(e.test(o))return t;throw new Error("Failed to get network from RPC URL")};
|