aiia-vault-sdk 1.1.24 → 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.
@@ -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(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()}};
@@ -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, }: {
@@ -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:"[STREAM-INFO]",BLOCK:"[STREAM-BLOCK]",EVENT:"[STREAM-EVENT]",ERROR:"[STREAM-ERROR]",SAVE:"[STREAM-SAVE]",DEBUG:"[STREAM-DEBUG]"};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)=>{const a=[];e.interface.forEachEvent((e=>{a.push(e.name)}));const n=a.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}}))})),i=(await Promise.all(n)).flat();i.sort(((e,t)=>e.blockNumber-t.blockNumber));const c=[...new Set(i.map((e=>e.blockNumber)))].map((e=>t().getBlock(e))),l=await Promise.all(c),m=new Map(l.map((e=>[e.number,e.timestamp])));return i.map((e=>({eventName:e.eventName,blockNumber:e.blockNumber,transactionHash:e.transactionHash,args:Object.fromEntries(Object.entries(e.args||{}).filter((([e])=>isNaN(Number(e))))),timestamp:m.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})=>{const c="1"===process.env.DEBUG_STREAM_EVENTS;let l=a;for(c&&(console.log(`${exports.LOG_PREFIXES.INFO} StreamEvents Debug Mode Enabled`),console.log(`${exports.LOG_PREFIXES.INFO} Initial fromBlock: ${l}`),console.log(`${exports.LOG_PREFIXES.INFO} Batch size: ${n}`),console.log(`${exports.LOG_PREFIXES.INFO} Sleep time: ${i}ms`));;)try{const a=await e().getBlockNumber();c&&console.log(`${exports.LOG_PREFIXES.BLOCK} Latest block: ${a}`);const m=Math.min(l+n,a);if(c&&console.log(`${exports.LOG_PREFIXES.BLOCK} Processing blocks from ${l} to ${m}`),l>=a){c&&console.log(`${exports.LOG_PREFIXES.DEBUG} Caught up to latest block, waiting ${i}ms...`),await(0,exports.sleep)(i);continue}const p=await t(l,m);if(c&&p.length>0){const e=p.reduce(((e,t)=>{const o=t.eventName||"Unknown";return e[o]=(e[o]||0)+1,e}),{});console.log(`${exports.LOG_PREFIXES.EVENT} Found ${p.length} events:`),Object.entries(e).forEach((([e,t])=>{console.log(`${exports.LOG_PREFIXES.EVENT} - ${e}: ${t}`)}))}for(const e of p)c&&console.log(`${exports.LOG_PREFIXES.EVENT} Processing: ${e.eventName||"Event"}`),await r(o(e));await s(m),c&&console.log(`${exports.LOG_PREFIXES.SAVE} Saved latest block: ${m}`),l=m+1}catch(e){c?(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")};
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:"[STREAM-INFO]",BLOCK:"[STREAM-BLOCK]",EVENT:"[STREAM-EVENT]",ERROR:"[STREAM-ERROR]",SAVE:"[STREAM-SAVE]",DEBUG:"[STREAM-DEBUG]"};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")};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "aiia-vault-sdk",
3
- "version": "1.1.24",
3
+ "version": "1.1.26",
4
4
  "description": "SDK for AIIA Vault Contract",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",