diff --git a/docs/swagger/algorand-routes.yml b/docs/swagger/algorand-routes.yml new file mode 100644 index 0000000000..3bd24e87f7 --- /dev/null +++ b/docs/swagger/algorand-routes.yml @@ -0,0 +1,73 @@ +paths: + /algorand/poll: + post: + tags: + - 'algorand' + summary: 'Poll the status of a transaction' + consumes: + - 'application/json' + produces: + - 'application/json' + parameters: + - in: 'body' + name: 'body' + required: true + schema: + $ref: '#/definitions/AlgorandPollRequest' + responses: + '200': + schema: + $ref: '#/definitions/AlgorandPollResponse' + /algorand/balances: + post: + tags: + - 'algorand' + summary: 'Get the balances of an account' + consumes: + - 'application/json' + produces: + - 'application/json' + parameters: + - in: 'body' + name: 'body' + required: true + schema: + $ref: '#/definitions/BalancesRequest' + responses: + '200': + schema: + $ref: '#/definitions/BalancesResponse' + /algorand/assets: + get: + tags: + - 'algorand' + summary: 'Get assets info' + consumes: + - 'application/json' + produces: + - 'application/json' + parameters: + - in: 'query' + name: 'query' + required: true + schema: + $ref: '#/definitions/AlgorandAssetsRequest' + /algorand/opt-in: + post: + tags: + - 'algorand' + summary: 'Opt into an asset' + consumes: + - 'application/json' + produces: + - 'application/json' + parameters: + - in: 'body' + name: 'body' + required: true + schema: + $ref: '#/definitions/AlgorandOptInRequest' + responses: + '200': + schema: + $ref: '#/definitions/AlgorandOptInResponse' \ No newline at end of file diff --git a/docs/swagger/definitions.yml b/docs/swagger/definitions.yml index bd569dde33..0763752f16 100644 --- a/docs/swagger/definitions.yml +++ b/docs/swagger/definitions.yml @@ -64,7 +64,7 @@ definitions: tokenSymbols: type: 'array' items: 'string' - example: ['WETH', 'DAI'] + example: [ 'WETH', 'DAI' ] chain: type: 'string' example: 'ethereum' @@ -117,7 +117,7 @@ definitions: tokenSymbols: type: 'array' items: 'string' - example: ['WETH', 'DAI'] + example: [ 'WETH', 'DAI' ] chain: type: 'string' example: 'ethereum' @@ -293,34 +293,34 @@ definitions: example: '{"type": 2,"chainId": 42,"nonce": 129,"maxPriorityFeePerGas": "94000000000","maxFeePerGas": "94000000000","gasPrice": null,"gasLimit": "100000","to": "0xd0A1E359811322d97991E03f863a0C30C2cF029C","value": "0","data": "0x095ea7b30000000000000000000000007a250d5630b4cf539739df2c5dacb4c659f2488dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","accessList": [],"hash": "0xa321bbe8888c3bc88ecb1ad4f03f22a71e6f5715dfcb19e0a2dca9036c981b6d","v": 1,"r": "0x47c517271885b7041d81bcd65cd050a5d6be3fbd67a8f1660ac8d7e68fc8221f","s": "0x7c62e114b2cb0eae6236b597fb4aacb01c51e56afd7f734e6039d83aa400ba82","from": "0xFaA12FD102FE8623C9299c72B03E45107F2772B5","confirmations": 0}' # noqa: documentation InjectivePollResponse: - type: 'object' - required: - - 'blockNumber' - - 'hash' - - 'gasWanted' - - 'gasLimit' - - 'gasUsed' - - 'sequences' - properties: - blockNumber: - type: 'number' - example: 123456 - hash: - type: 'string' - example: '0xaaaaaaaaaabbbb' - gasWanted: - type: 'number' - example: 1000000 - gasLimit: - type: 'number' - example: 2000000 - gasUsed: - type: 'number' - example: 1000000 - sequences: - type: 'array' - items: 'number' - example: [1,2] + type: 'object' + required: + - 'blockNumber' + - 'hash' + - 'gasWanted' + - 'gasLimit' + - 'gasUsed' + - 'sequences' + properties: + blockNumber: + type: 'number' + example: 123456 + hash: + type: 'string' + example: '0xaaaaaaaaaabbbb' + gasWanted: + type: 'number' + example: 1000000 + gasLimit: + type: 'number' + example: 2000000 + gasUsed: + type: 'number' + example: 1000000 + sequences: + type: 'array' + items: 'number' + example: [ 1,2 ] InjectivePollRequest: type: 'object' @@ -666,7 +666,7 @@ definitions: walletAddresses: type: 'array' items: 'string' - example: ['0xd0A1E359811322d97991E03f863a0C30C2cF029C', '0xd0A1E359811322d97991E03f863a0C30C2XXXXXX'] + example: [ '0xd0A1E359811322d97991E03f863a0C30C2cF029C', '0xd0A1E359811322d97991E03f863a0C30C2XXXXXX' ] GetWalletSignRequest: type: 'object' @@ -744,7 +744,7 @@ definitions: tokenSymbols: type: 'array' items: 'string' - example: ['ATOM', 'NETA'] + example: [ 'ATOM', 'NETA' ] CosmosPollRequest: type: 'object' @@ -1214,7 +1214,7 @@ definitions: example: 5 prices: type: 'object' - example: ['1', '2', '3'] + example: [ '1', '2', '3' ] PerpPairsRequest: @@ -1254,7 +1254,7 @@ definitions: pairs: type: 'array' items: 'string' - example: ['AAVEUSD', 'PERPUSD', 'BTCUSD'] + example: [ 'AAVEUSD', 'PERPUSD', 'BTCUSD' ] PerpPriceRequest: type: 'object' @@ -1625,24 +1625,24 @@ definitions: type: 'string' ClobMarketsRequest: - type: 'object' - required: - - 'chain' - - 'network' - - 'connector' - properties: - market: - type: 'string' - example: 'AAVE-USDT' - chain: - type: 'string' - example: 'injective' - network: - type: 'string' - example: 'mainnet' - connector: - type: 'string' - example: 'injective' + type: 'object' + required: + - 'chain' + - 'network' + - 'connector' + properties: + market: + type: 'string' + example: 'AAVE-USDT' + chain: + type: 'string' + example: 'injective' + network: + type: 'string' + example: 'mainnet' + connector: + type: 'string' + example: 'injective' ClobMarketResponse: type: 'object' @@ -2070,7 +2070,7 @@ definitions: example: 'injective' network: type: 'string' - example: 'mainnet' + example: 'mainnet' address: type: 'string' example: '0x...' @@ -2095,7 +2095,7 @@ definitions: tokenSymbols: type: 'array' items: 'string' - example: ["NEAR", "ETH", "AURORA"] + example: [ "NEAR", "ETH", "AURORA" ] chain: type: 'string' example: 'near' @@ -2322,3 +2322,165 @@ definitions: lastTradePrice: type: 'string' example: '1.234' + + AlgorandPollRequest: + type: 'object' + required: + - 'network' + - 'txHash' + properties: + network: + type: 'string' + example: 'testnet' + txHash: + type: 'string' + example: 'T3ZUYEJ5Y7KEDKITIXO4B5OWU4SBVGOFCPOYGZQHF2XZGENZUBQA' + + AlgorandPollResponse: + type: 'object' + required: + - 'currentBlock' + - 'txBlock' + - 'txHash' + - 'fee' + properties: + currentBlock: + type: 'integer' + example: 28243911 + txBlock: + type: 'integer' + example: 28243910 + txHash: + type: 'string' + example: 'T3ZUYEJ5Y7KEDKITIXO4B5OWU4SBVGOFCPOYGZQHF2XZGENZUBQA' + fee: + type: 'integer' + example: 1000 + + AlgorandAssetsRequest: + type: 'object' + properties: + network: + type: 'string' + example: 'testnet' + assetSymbols: + type: 'array' + items: 'string' + example: [ 'ALGO', 'USDC' ] + + AlgorandAssetsResponse: + type: 'object' + required: + - 'assets' + properties: + assets: + type: 'array' + items: 'object' + example: [ { symbol: 'ALGO', assetId: 0, decimal: 6 } ] + + AlgorandOptInRequest: + type: 'object' + required: + - 'network' + - 'address' + - 'assetSymbol' + properties: + network: + type: 'string' + example: 'testnet' + address: + type: 'string' + example: 'T3ZUYEJ5Y7KEDKITIXO4B5OWU4SBVGOFCPOYGZQHF2XZGENZUBQA' + assetSymbol: + type: 'string' + example: 'USDC' + + AlgorandOptInResponse: + type: 'object' + required: + - 'network' + - 'timestamp' + - 'latency' + - 'assetId' + - 'transactionResponse' + properties: + network: + type: 'string' + example: 'testnet' + timestamp: + type: 'integer' + example: 163636808574 + latency: + type: 'number' + example: 0.5 + assetId: + type: 'string' + example: 'USDC' + transactionResponse: + type: 'object' + + ClobBatchOrdersRequest: + type: 'object' + required: + - 'chain' + - 'network' + - 'connector' + - 'address' + - 'createOrderParams' + - 'cancelOrderIds' + properties: + chain: + type: 'string' + example: 'injective' + network: + type: 'string' + example: 'mainnet' + connector: + type: 'string' + example: 'injective' + address: + type: 'string' + example: '0x...' + createOrderParams: + type: 'array' + items: 'object' + example: [ { + market: 'AAVE-USDT', + price: '2', + amount: '0.10', + side: 'SELL', + orderType: 'LIMIT', + }, + { + price: '3', + amount: '0.10', + side: 'SELL', + } ] + cancelOrderParams: + type: 'array' + items: 'object' + example: [ + { market: 'AAVE-USDT', orderId: '0x...' }, + { market: 'AAVE-USDT', orderId: '0x...' }, + ] + + ClobBatchOrdersResponse: + type: 'object' + required: + - 'network' + - 'timestamp' + - 'latency' + - 'txHash' + properties: + network: + type: 'string' + example: 'mainnet' + timestamp: + type: 'integer' + example: 1636368085740 + latency: + type: 'number' + example: 0.5 + txHash: + type: 'string' + example: '0x...' diff --git a/docs/swagger/swagger.yml b/docs/swagger/swagger.yml index 883ade5516..5fc6f46c12 100644 --- a/docs/swagger/swagger.yml +++ b/docs/swagger/swagger.yml @@ -14,7 +14,7 @@ host: 'localhost:15888' tags: - name: 'system' - description: 'Get information about the currently running Gateway program' + description: 'Get information about the currently running Gateway program' - name: 'network' description: 'Get information about specific networks' - name: 'wallet' @@ -29,6 +29,8 @@ tags: description: 'Interact with AMM LP contracts' - name: 'evm' description: 'Interact with EVM based blockchains' + - name: 'algorand' + description: 'Interact with the Algorand blockchain' - name: 'cosmos' description: 'Interact with the Cosmos blockchain' - name: 'near' diff --git a/package.json b/package.json index 224b7c79d7..06558f3aeb 100644 --- a/package.json +++ b/package.json @@ -44,6 +44,7 @@ "@perp/sdk-curie": "^1.16.0", "@sushiswap/sdk": "^5.0.0-canary.116", "@switchboard-xyz/defikingdoms-sdk": "^1.0.7", + "@tinymanorg/tinyman-js-sdk": "^3.0.0", "@traderjoe-xyz/sdk": "^1.6.1", "@types/fs-extra": "^9.0.13", "@types/lodash": "^4.14.178", @@ -59,6 +60,7 @@ "@zuzu-cat/defira-sdk": "^1.0.0", "abi-decoder": "^2.4.0", "ajv": "^8.6.3", + "algosdk": "^2.2.0", "app-root-path": "^3.0.0", "axios": "^0.21.1", "big.js": "6.1.1", @@ -130,10 +132,10 @@ "eslint-plugin-promise": "^5.1.0", "eslint-plugin-standard": "^4.0.1", "google-protobuf": "^3.2.0", - "jsbi": "^3.2.0", "hardhat": "^2.13.0", "jest": "^27.3.1", "jest-extended": "^0.11.5", + "jsbi": "^3.2.0", "mock-ethers-provider": "^1.0.2", "node-cache": "5.1.2", "nodemon": "^2.0.16", diff --git a/src/amm/amm.controllers.ts b/src/amm/amm.controllers.ts index ded18c1fc5..76c1a8e3d4 100644 --- a/src/amm/amm.controllers.ts +++ b/src/amm/amm.controllers.ts @@ -39,6 +39,11 @@ import { trade as refTrade, estimateGas as refEstimateGas, } from '../connectors/ref/ref.controllers'; +import { + price as tinymanPrice, + trade as tinymanTrade, + estimateGas as tinymanEstimateGas, +} from '../connectors/tinyman/tinyman.controllers'; import { getPriceData as perpPriceData, createTakerOrder, @@ -48,7 +53,10 @@ import { checkMarketStatus, getAccountValue, } from '../connectors/perp/perp.controllers'; -import { getChain, getConnector } from '../services/connection-manager'; +import { + getInitializedChain, + getConnector, +} from '../services/connection-manager'; import { Ethereumish, Nearish, @@ -63,11 +71,16 @@ import { price as zigzagPrice, trade as zigzagTrade, } from '../connectors/zigzag/zigzag.controllers'; +import { Algorand } from '../chains/algorand/algorand'; +import { Tinyman } from '../connectors/tinyman/tinyman'; export async function price(req: PriceRequest): Promise { - const chain = await getChain(req.chain, req.network); - const connector: Uniswapish | RefAMMish | ZigZagish = await getConnector< - Uniswapish | RefAMMish | ZigZagish + const chain = await getInitializedChain( + req.chain, + req.network + ); + const connector: Uniswapish | RefAMMish | Tinyman | ZigZagish= await getConnector< + Uniswapish | RefAMMish | Tinyman | ZigZagish >(req.chain, req.network, req.connector); // we currently use the presence of routerAbi to distinguish Uniswapish from RefAMMish @@ -75,15 +88,20 @@ export async function price(req: PriceRequest): Promise { return uniswapPrice(chain, connector, req); } else if ('estimate' in connector) { return zigzagPrice(chain, connector as any, req); + } else if (connector instanceof Tinyman) { + return tinymanPrice(chain as unknown as Algorand, connector, req); } else { return refPrice(chain, connector, req); } } export async function trade(req: TradeRequest): Promise { - const chain = await getChain(req.chain, req.network); - const connector: Uniswapish | RefAMMish | ZigZagish = await getConnector< - Uniswapish | RefAMMish | ZigZagish + const chain = await getInitializedChain( + req.chain, + req.network + ); + const connector: Uniswapish | RefAMMish | Tinyman | ZigZagish = await getConnector< + Uniswapish | RefAMMish | Tinyman | ZigZagish >(req.chain, req.network, req.connector); // we currently use the presence of routerAbi to distinguish Uniswapish from RefAMMish @@ -91,6 +109,8 @@ export async function trade(req: TradeRequest): Promise { return uniswapTrade(chain, connector, req); } else if ('estimate' in connector) { return zigzagTrade(chain, connector as any, req); + } else if (connector instanceof Tinyman) { + return tinymanTrade(chain as unknown as Algorand, connector, req); } else { return refTrade(chain, connector, req); } @@ -99,7 +119,7 @@ export async function trade(req: TradeRequest): Promise { export async function addLiquidity( req: AddLiquidityRequest ): Promise { - const chain = await getChain(req.chain, req.network); + const chain = await getInitializedChain(req.chain, req.network); const connector: UniswapLPish = await getConnector( req.chain, req.network, @@ -112,7 +132,7 @@ export async function addLiquidity( export async function reduceLiquidity( req: RemoveLiquidityRequest ): Promise { - const chain = await getChain(req.chain, req.network); + const chain = await getInitializedChain(req.chain, req.network); const connector: UniswapLPish = await getConnector( req.chain, req.network, @@ -125,7 +145,7 @@ export async function reduceLiquidity( export async function collectFees( req: CollectEarnedFeesRequest ): Promise { - const chain = await getChain(req.chain, req.network); + const chain = await getInitializedChain(req.chain, req.network); const connector: UniswapLPish = await getConnector( req.chain, req.network, @@ -137,7 +157,7 @@ export async function collectFees( export async function positionInfo( req: PositionRequest ): Promise { - const chain = await getChain(req.chain, req.network); + const chain = await getInitializedChain(req.chain, req.network); const connector: UniswapLPish = await getConnector( req.chain, req.network, @@ -149,7 +169,7 @@ export async function positionInfo( export async function poolPrice( req: PoolPriceRequest ): Promise { - const chain = await getChain(req.chain, req.network); + const chain = await getInitializedChain(req.chain, req.network); const connector: UniswapLPish = await getConnector( req.chain, req.network, @@ -161,14 +181,19 @@ export async function poolPrice( export async function estimateGas( req: NetworkSelectionRequest ): Promise { - const chain = await getChain(req.chain, req.network); - const connector: Uniswapish | RefAMMish = await getConnector< + const chain = await getInitializedChain( + req.chain, + req.network + ); + const connector: Uniswapish | RefAMMish | Tinyman = await getConnector< Uniswapish | RefAMMish >(req.chain, req.network, req.connector); // we currently use the presence of routerAbi to distinguish Uniswapish from RefAMMish if ('routerAbi' in connector) { return uniswapEstimateGas(chain, connector); + } else if (connector instanceof Tinyman) { + return tinymanEstimateGas(chain as unknown as Algorand, connector); } else { return refEstimateGas(chain, connector); } @@ -178,7 +203,7 @@ export async function estimateGas( export async function perpMarketPrices( req: PriceRequest ): Promise { - const chain = await getChain(req.chain, req.network); + const chain = await getInitializedChain(req.chain, req.network); const connector: Perpish = await getConnector( req.chain, req.network, @@ -191,7 +216,7 @@ export async function perpOrder( req: PerpCreateTakerRequest, isOpen: boolean ): Promise { - const chain = await getChain(req.chain, req.network); + const chain = await getInitializedChain(req.chain, req.network); const connector: Perpish = await getConnector( req.chain, req.network, @@ -204,7 +229,7 @@ export async function perpOrder( export async function perpPosition( req: PerpPositionRequest ): Promise { - const chain = await getChain(req.chain, req.network); + const chain = await getInitializedChain(req.chain, req.network); const connector: Perpish = await getConnector( req.chain, req.network, @@ -217,7 +242,7 @@ export async function perpPosition( export async function perpBalance( req: PerpBalanceRequest ): Promise { - const chain = await getChain(req.chain, req.network); + const chain = await getInitializedChain(req.chain, req.network); const connector: Perpish = ( await getConnector(req.chain, req.network, req.connector, req.address) ); @@ -227,7 +252,7 @@ export async function perpBalance( export async function perpPairs( req: NetworkSelectionRequest ): Promise { - const chain = await getChain(req.chain, req.network); + const chain = await getInitializedChain(req.chain, req.network); const connector: Perpish = await getConnector( req.chain, req.network, @@ -239,7 +264,7 @@ export async function perpPairs( export async function getMarketStatus( req: PerpMarketRequest ): Promise { - const chain = await getChain(req.chain, req.network); + const chain = await getInitializedChain(req.chain, req.network); const connector: Perpish = await getConnector( req.chain, req.network, @@ -251,7 +276,7 @@ export async function getMarketStatus( export async function estimatePerpGas( req: NetworkSelectionRequest ): Promise { - const chain = await getChain(req.chain, req.network); + const chain = await getInitializedChain(req.chain, req.network); const connector: Perpish = await getConnector( req.chain, req.network, diff --git a/src/app.ts b/src/app.ts index 7ee3a61ef8..286244c103 100644 --- a/src/app.ts +++ b/src/app.ts @@ -18,6 +18,7 @@ import { NetworkRoutes } from './network/network.routes'; import { ConnectorsRoutes } from './connectors/connectors.routes'; import { EVMRoutes } from './evm/evm.routes'; import { AmmRoutes, AmmLiquidityRoutes, PerpAmmRoutes } from './amm/amm.routes'; +import { AlgorandRoutes } from './chains/algorand/algorand.routes'; import { InjectiveRoutes } from './chains/injective/injective.routes'; import { NearRoutes } from './chains/near/near.routes'; import { CLOBRoutes, PerpClobRoutes } from './clob/clob.routes'; @@ -49,6 +50,7 @@ gatewayApp.use( gatewayApp.use('/config', ConfigRoutes.router); gatewayApp.use('/network', NetworkRoutes.router); gatewayApp.use('/evm', EVMRoutes.router); +gatewayApp.use('/algorand', AlgorandRoutes.router); gatewayApp.use('/injective', InjectiveRoutes.router); gatewayApp.use('/connectors', ConnectorsRoutes.router); @@ -103,6 +105,7 @@ export const swaggerDocument = SwaggerManager.generateSwaggerJson( './docs/swagger/amm-liquidity-routes.yml', './docs/swagger/evm-routes.yml', './docs/swagger/network-routes.yml', + './docs/swagger/algorand-routes.yml', './docs/swagger/near-routes.yml', './docs/swagger/cosmos-routes.yml', './docs/swagger/injective-routes.yml', diff --git a/src/chains/algorand/algorand.config.ts b/src/chains/algorand/algorand.config.ts new file mode 100644 index 0000000000..e79ab83cd8 --- /dev/null +++ b/src/chains/algorand/algorand.config.ts @@ -0,0 +1,39 @@ +import { ConfigManagerV2 } from '../../services/config-manager-v2'; + +export interface NetworkConfig { + name: string; + nodeURL: string; + indexerURL: string; + assetListType: string; + assetListSource: string; + maxLRUCacheInstances: number; +} + +export interface Config { + network: NetworkConfig; + nativeCurrencySymbol: string; +} + +export function getAlgorandConfig(network: string): Config { + return { + network: { + name: network, + nodeURL: ConfigManagerV2.getInstance().get( + 'algorand.networks.' + network + '.nodeURL' + ), + indexerURL: ConfigManagerV2.getInstance().get( + 'algorand.networks.' + network + '.indexerURL' + ), + assetListType: ConfigManagerV2.getInstance().get( + 'algorand.networks.' + network + '.assetListType' + ), + assetListSource: ConfigManagerV2.getInstance().get( + 'algorand.networks.' + network + '.assetListSource' + ), + maxLRUCacheInstances: 10, + }, + nativeCurrencySymbol: ConfigManagerV2.getInstance().get( + 'algorand.nativeCurrencySymbol' + ), + }; +} diff --git a/src/chains/algorand/algorand.controller.ts b/src/chains/algorand/algorand.controller.ts new file mode 100644 index 0000000000..8e60686c7f --- /dev/null +++ b/src/chains/algorand/algorand.controller.ts @@ -0,0 +1,125 @@ +import { + AlgorandAsset, + AssetsRequest, + AssetsResponse, + OptInRequest, + OptInResponse, + PollRequest, + PollResponse, +} from '../algorand/algorand.requests'; +import { Algorand } from './algorand'; +import { + BalanceRequest, + BalanceResponse, +} from '../../network/network.requests'; +import { latency } from '../../services/base'; +import { + HttpException, + NETWORK_ERROR_CODE, + TOKEN_NOT_SUPPORTED_ERROR_CODE, + TOKEN_NOT_SUPPORTED_ERROR_MESSAGE, +} from '../../services/error-handler'; + +async function getInitializedAlgorand(network: string): Promise { + const algorand = Algorand.getInstance(network); + + if (!algorand.ready()) { + await algorand.init(); + } + + return algorand; +} + +export async function poll( + algorand: Algorand, + req: PollRequest +): Promise { + return await algorand.getTransaction(req.txHash); +} + +export async function balances( + chain: Algorand, + request: BalanceRequest +): Promise { + const initTime = Date.now(); + const balances: Record = {}; + + const account = await chain.getAccountFromAddress(request.address); + + if (request.tokenSymbols.includes(chain.nativeTokenSymbol)) { + balances[chain.nativeTokenSymbol] = await chain.getNativeBalance(account); + } + + for (const token of request.tokenSymbols) { + if (token === chain.nativeTokenSymbol) continue; + balances[token] = await chain.getAssetBalance(account, token); + } + + return { + network: request.network, + timestamp: initTime, + latency: latency(initTime, Date.now()), + balances: balances, + }; +} + +export async function getAssets( + request: AssetsRequest +): Promise { + if (request.network === undefined) { + throw new HttpException( + 500, + 'Missing network parameter', + NETWORK_ERROR_CODE + ); + } + + let assets: AlgorandAsset[] = []; + const algorand = await getInitializedAlgorand(request.network); + + if (!request.assetSymbols) { + assets = algorand.storedAssetList; + } else { + let assetSymbols; + if (typeof request.assetSymbols === 'string') { + assetSymbols = [request.assetSymbols]; + } else { + assetSymbols = request.assetSymbols; + } + for (const a of assetSymbols as []) { + assets.push(algorand.getAssetForSymbol(a) as AlgorandAsset); + } + } + + return { + assets: assets, + }; +} + +export async function optIn(request: OptInRequest): Promise { + const initTime = Date.now(); + + const algorand = await getInitializedAlgorand(request.network); + const asset = algorand.getAssetForSymbol(request.assetSymbol); + + if (asset === undefined) { + throw new HttpException( + 500, + TOKEN_NOT_SUPPORTED_ERROR_MESSAGE + request.assetSymbol, + TOKEN_NOT_SUPPORTED_ERROR_CODE + ); + } + + const transactionResponse = await algorand.optIn( + request.address, + request.assetSymbol + ); + + return { + network: request.network, + timestamp: initTime, + latency: latency(initTime, Date.now()), + assetId: (asset as AlgorandAsset).assetId, + transactionResponse: transactionResponse, + }; +} diff --git a/src/chains/algorand/algorand.requests.ts b/src/chains/algorand/algorand.requests.ts new file mode 100644 index 0000000000..3142f6089c --- /dev/null +++ b/src/chains/algorand/algorand.requests.ts @@ -0,0 +1,40 @@ +export interface PollRequest { + network: string; + txHash: string; +} + +export type PollResponse = { + currentBlock: number; + txBlock: number | null; + txHash: string; + fee: number; +}; + +export type AssetsRequest = { + network?: string; + assetSymbols?: string[]; +}; + +export interface AlgorandAsset { + symbol: string; + assetId: number; + decimals: number; +} + +export type AssetsResponse = { + assets: AlgorandAsset[]; +}; + +export interface OptInRequest { + network: string; + address: string; + assetSymbol: string; +} + +export interface OptInResponse { + network: string; + timestamp: number; + latency: number; + assetId: number; + transactionResponse: any; +} diff --git a/src/chains/algorand/algorand.routes.ts b/src/chains/algorand/algorand.routes.ts new file mode 100644 index 0000000000..365d3c831d --- /dev/null +++ b/src/chains/algorand/algorand.routes.ts @@ -0,0 +1,91 @@ +/* eslint-disable no-inner-declarations */ +/* eslint-disable @typescript-eslint/ban-types */ +import { Response, Router, Request, NextFunction } from 'express'; +import { asyncHandler } from '../../services/error-handler'; +import { + AssetsRequest, + AssetsResponse, + PollRequest, + PollResponse, + OptInRequest, + OptInResponse, +} from './algorand.requests'; +import { + validateAlgorandBalanceRequest, + validateAlgorandPollRequest, + validateAssetsRequest, + validateOptInRequest, +} from './algorand.validators'; +import { getInitializedChain } from '../../services/connection-manager'; +import { Algorand } from './algorand'; +import { balances, getAssets, optIn, poll } from './algorand.controller'; +import { + BalanceRequest, + BalanceResponse, +} from '../../network/network.requests'; + +export namespace AlgorandRoutes { + export const router = Router(); + + router.post( + '/poll', + asyncHandler( + async ( + req: Request<{}, {}, PollRequest>, + res: Response + ) => { + validateAlgorandPollRequest(req.body); + const algorand = await getInitializedChain( + 'algorand', + req.body.network + ); + res.status(200).json(await poll(algorand, req.body)); + } + ) + ); + + router.post( + '/balances', + asyncHandler( + async ( + req: Request<{}, {}, BalanceRequest>, + res: Response, + _next: NextFunction + ) => { + validateAlgorandBalanceRequest(req.body); + const chain = await getInitializedChain( + req.body.chain, + req.body.network + ); + + res.status(200).json(await balances(chain, req.body)); + } + ) + ); + + router.get( + '/assets', + asyncHandler( + async ( + req: Request<{}, {}, {}, AssetsRequest>, + res: Response + ) => { + validateAssetsRequest(req.query); + res.status(200).json(await getAssets(req.query)); + } + ) + ); + + router.post( + '/opt-in', + asyncHandler( + async ( + req: Request<{}, {}, OptInRequest>, + res: Response + ) => { + validateOptInRequest(req.body); + res.status(200).json(await optIn(req.body)); + } + ) + ); +} diff --git a/src/chains/algorand/algorand.ts b/src/chains/algorand/algorand.ts new file mode 100644 index 0000000000..b1ce86ffce --- /dev/null +++ b/src/chains/algorand/algorand.ts @@ -0,0 +1,293 @@ +import LRUCache from 'lru-cache'; +import { getAlgorandConfig } from './algorand.config'; +import { + Algodv2, + Indexer, + mnemonicToSecretKey, + makeAssetTransferTxnWithSuggestedParamsFromObject, + Account, +} from 'algosdk'; +import { AlgorandAsset, PollResponse } from './algorand.requests'; +import { createCipheriv, createDecipheriv, randomBytes } from 'crypto'; +import { TokenListType, walletPath } from '../../services/base'; +import fse from 'fs-extra'; +import { ConfigManagerCertPassphrase } from '../../services/config-manager-cert-passphrase'; +import axios from 'axios'; +import { promises as fs } from 'fs'; + +type AssetListType = TokenListType; + +export class Algorand { + public nativeTokenSymbol; + private _assetMap: Record = {}; + private static _instances: LRUCache; + private _chain: string = 'algorand'; + private _network: string; + private _algod: Algodv2; + private _indexer: Indexer; + private _ready: boolean = false; + private _assetListType: AssetListType; + private _assetListSource: string; + public gasPrice: number; + public gasLimit: number; + public gasCost: number; + + constructor( + network: string, + nodeUrl: string, + indexerUrl: string, + assetListType: AssetListType, + assetListSource: string + ) { + this._network = network; + const config = getAlgorandConfig(network); + this.nativeTokenSymbol = config.nativeCurrencySymbol; + this._algod = new Algodv2('', nodeUrl); + this._indexer = new Indexer('', indexerUrl, 'undefined'); + this._assetListType = assetListType; + this._assetListSource = assetListSource; + this.gasPrice = 0; + this.gasLimit = 0; + this.gasCost = 0.001; + } + + public get algod(): Algodv2 { + return this._algod; + } + + public get indexer(): Indexer { + return this._indexer; + } + + public get network(): string { + return this._network; + } + + public get storedAssetList(): AlgorandAsset[] { + return Object.values(this._assetMap); + } + + public ready(): boolean { + return this._ready; + } + + public async init(): Promise { + await this.loadAssets(); + this._ready = true; + return; + } + + async close() { + return; + } + + public static getInstance(network: string): Algorand { + const config = getAlgorandConfig(network); + if (Algorand._instances === undefined) { + Algorand._instances = new LRUCache({ + max: config.network.maxLRUCacheInstances, + }); + } + + if (!Algorand._instances.has(config.network.name)) { + if (network !== null) { + const nodeUrl = config.network.nodeURL; + const indexerUrl = config.network.indexerURL; + const assetListType = config.network.assetListType as TokenListType; + const assetListSource = config.network.assetListSource; + Algorand._instances.set( + config.network.name, + new Algorand( + network, + nodeUrl, + indexerUrl, + assetListType, + assetListSource + ) + ); + } else { + throw new Error( + `Algorand.getInstance received an unexpected network: ${network}.` + ); + } + } + + return Algorand._instances.get(config.network.name) as Algorand; + } + + public static getConnectedInstances(): { [name: string]: Algorand } { + const connectedInstances: { [name: string]: Algorand } = {}; + if (this._instances !== undefined) { + const keys = Array.from(this._instances.keys()); + for (const instance of keys) { + if (instance !== undefined) { + connectedInstances[instance] = this._instances.get( + instance + ) as Algorand; + } + } + } + return connectedInstances; + } + + async getCurrentBlockNumber(): Promise { + const status = await this._algod.status().do(); + return status['next-version-round']; + } + + public async getTransaction(txHash: string): Promise { + const transactionId = txHash.startsWith('0x') ? txHash.slice(2) : txHash; + let currentBlock; + let transactionData; + let transactionBlock; + let fee; + try { + transactionData = await this._algod + .pendingTransactionInformation(transactionId) + .do(); + transactionBlock = transactionData['confirmed-round']; // will be undefined if not confirmed + transactionBlock = transactionBlock ? transactionBlock : null; + fee = transactionData.txn.fee; + currentBlock = await this.getCurrentBlockNumber(); + } catch (error: any) { + if (error.status != 404) { + throw error; + } + transactionData = await this._indexer + .lookupTransactionByID(transactionId) + .do(); + currentBlock = transactionData['current-round']; + transactionBlock = transactionData.transaction['confirmed-round']; + fee = transactionData.transaction.fee; + } + return { + currentBlock, + txBlock: transactionBlock, + txHash: '0x' + transactionId, + fee, + }; + } + + public getAccountFromPrivateKey(mnemonic: string): Account { + return mnemonicToSecretKey(mnemonic); + } + async getAccountFromAddress(address: string): Promise { + const path = `${walletPath}/${this._chain}`; + const encryptedMnemonic: string = await fse.readFile( + `${path}/${address}.json`, + 'utf8' + ); + const passphrase = ConfigManagerCertPassphrase.readPassphrase(); + if (!passphrase) { + throw new Error('missing passphrase'); + } + const mnemonic = this.decrypt(encryptedMnemonic, passphrase); + + return mnemonicToSecretKey(mnemonic); + } + + public encrypt(mnemonic: string, password: string): string { + const iv = randomBytes(16); + const key = Buffer.alloc(32); + key.write(password); + + const cipher = createCipheriv('aes-256-cbc', key, iv); + + const encrypted = Buffer.concat([cipher.update(mnemonic), cipher.final()]); + + return `${iv.toString('hex')}:${encrypted.toString('hex')}`; + } + + public decrypt(encryptedMnemonic: string, password: string): string { + const [iv, encryptedKey] = encryptedMnemonic.split(':'); + const key = Buffer.alloc(32); + key.write(password); + + const decipher = createDecipheriv( + 'aes-256-cbc', + key, + Buffer.from(iv, 'hex') + ); + + const decrpyted = Buffer.concat([ + decipher.update(Buffer.from(encryptedKey, 'hex')), + decipher.final(), + ]); + + return decrpyted.toString(); + } + + public async getAssetBalance( + account: Account, + assetName: string + ): Promise { + const algorandAsset = this._assetMap[assetName]; + let balance; + + try { + const response = await this._algod + .accountAssetInformation(account.addr, algorandAsset.assetId) + .do(); + balance = response['asset-holding'].amount; + } catch (error: any) { + if (!error.message.includes('account asset info not found')) { + throw error; + } + balance = 0; + } + + const amount = balance * parseFloat(`1e-${algorandAsset.decimals}`); + return amount.toString(); + } + + public async getNativeBalance(account: Account): Promise { + const accountInfo = await this._algod.accountInformation(account.addr).do(); + const algoAsset = this._assetMap[this.nativeTokenSymbol]; + return ( + accountInfo.amount * parseFloat(`1e-${algoAsset.decimals}`) + ).toString(); + } + + public getAssetForSymbol(symbol: string): AlgorandAsset | null { + return this._assetMap[symbol] ? this._assetMap[symbol] : null; + } + + public async optIn(address: string, symbol: string) { + const account = await this.getAccountFromAddress(address); + const assetIndex = this._assetMap[symbol].assetId; + const suggestedParams = await this._algod.getTransactionParams().do(); + const optInTxn = makeAssetTransferTxnWithSuggestedParamsFromObject({ + from: account.addr, + to: address, + suggestedParams, + assetIndex, + amount: 0, + }); + const signedOptInTxn = optInTxn.signTxn(account.sk); + const resp = await this._algod.sendRawTransaction(signedOptInTxn).do(); + return resp; + } + + private async loadAssets(): Promise { + const assetData = await this.getAssetData(); + for (const result of assetData) { + this._assetMap[result.unit_name.toUpperCase()] = { + symbol: result.unit_name.toUpperCase(), + assetId: +result.id, + decimals: result.decimals, + }; + } + } + + private async getAssetData(): Promise { + let assetData; + if (this._assetListType === 'URL') { + const response = await axios.get(this._assetListSource); + assetData = response.data.results; + } else { + const data = JSON.parse(await fs.readFile(this._assetListSource, 'utf8')); + assetData = data.results; + } + return assetData; + } +} diff --git a/src/chains/algorand/algorand.validators.ts b/src/chains/algorand/algorand.validators.ts new file mode 100644 index 0000000000..cdd353314b --- /dev/null +++ b/src/chains/algorand/algorand.validators.ts @@ -0,0 +1,71 @@ +import { + invalidTokenSymbolsError, + mkRequestValidator, + mkValidator, + RequestValidator, + validateTokenSymbols, + Validator, +} from '../../services/validators'; +import { + invalidAddressError, + validateNetwork, +} from '../ethereum/ethereum.validators'; +import { validateTxHash } from '../injective/injective.validators'; +import { invalidChainError } from '../near/near.validators'; + +const validateAlgorandChain: Validator = mkValidator( + 'chain', + invalidChainError, + (val) => typeof val === 'string' && val === 'algorand' +); + +const validateAlgorandAddress: Validator = mkValidator( + 'address', + invalidAddressError, + (val) => typeof val === 'string' && /[A-Z0-9]{58}/.test(val) +); + +export const validateAlgorandPollRequest: RequestValidator = mkRequestValidator( + [validateNetwork, validateTxHash] +); + +export const validateAlgorandBalanceRequest: RequestValidator = + mkRequestValidator([ + validateAlgorandChain, + validateNetwork, + validateAlgorandAddress, + validateTokenSymbols, + ]); + +export const validateAssetSymbols: Validator = (req: any) => { + const errors: Array = []; + if (req.assetSymbols) { + if (Array.isArray(req.assetSymbols)) { + req.tokenSymbols.forEach((symbol: any) => { + if (typeof symbol !== 'string') { + errors.push(invalidTokenSymbolsError); + } + }); + } else if (typeof req.assetSymbols !== 'string') { + errors.push(invalidTokenSymbolsError); + } + } + return errors; +}; + +export const validateAssetSymbol: Validator = mkValidator( + 'assetSymbol', + invalidTokenSymbolsError, + (val) => typeof val === 'string' +); + +export const validateAssetsRequest: RequestValidator = mkRequestValidator([ + validateNetwork, + validateAssetSymbols, +]); + +export const validateOptInRequest: RequestValidator = mkRequestValidator([ + validateNetwork, + validateAlgorandAddress, + validateAssetSymbol, +]); diff --git a/src/chains/injective/injective.routes.ts b/src/chains/injective/injective.routes.ts index fe0f8be742..0894b03957 100644 --- a/src/chains/injective/injective.routes.ts +++ b/src/chains/injective/injective.routes.ts @@ -26,7 +26,7 @@ import { validateTransferToBankAccountRequest, validateTransferToSubAccountRequest, } from './injective.validators'; -import { getChain } from '../../services/connection-manager'; +import { getInitializedChain } from '../../services/connection-manager'; import { NetworkSelectionRequest } from '../../services/common-interfaces'; export namespace InjectiveRoutes { @@ -39,7 +39,7 @@ export namespace InjectiveRoutes { req: Request<{}, {}, NetworkSelectionRequest>, res: Response ) => { - const injective = await getChain( + const injective = await getInitializedChain( req.query.chain, req.query.network ); @@ -56,7 +56,7 @@ export namespace InjectiveRoutes { res: Response ) => { validateTransferToBankAccountRequest(req.body); - const injective = await getChain( + const injective = await getInitializedChain( req.body.chain, req.body.network ); @@ -75,7 +75,7 @@ export namespace InjectiveRoutes { res: Response ) => { validateTransferToSubAccountRequest(req.body); - const injective = await getChain( + const injective = await getInitializedChain( req.body.chain, req.body.network ); @@ -94,7 +94,7 @@ export namespace InjectiveRoutes { res: Response ) => { validateBalanceRequest(req.body); - const injective = await getChain( + const injective = await getInitializedChain( req.body.chain, req.body.network ); @@ -111,7 +111,7 @@ export namespace InjectiveRoutes { res: Response ) => { validatePollRequest(req.body); - const injective = await getChain( + const injective = await getInitializedChain( req.body.chain, req.body.network ); diff --git a/src/chains/injective/injective.ts b/src/chains/injective/injective.ts index 2236c2a176..4ad21ac06e 100644 --- a/src/chains/injective/injective.ts +++ b/src/chains/injective/injective.ts @@ -234,10 +234,13 @@ export class Injective { public static getConnectedInstances(): { [name: string]: Injective } { const connectedInstances: { [name: string]: Injective } = {}; if (this._instances !== undefined) { - for (const instance of this._instances.keys()) { - connectedInstances[instance] = this._instances.get( - instance - ) as Injective; + const keys = Array.from(this._instances.keys()); + for (const instance of keys) { + if (instance !== undefined) { + connectedInstances[instance] = this._instances.get( + instance + ) as Injective; + } } } return connectedInstances; diff --git a/src/chains/near/near.routes.ts b/src/chains/near/near.routes.ts index 6480defa88..28e345cef5 100644 --- a/src/chains/near/near.routes.ts +++ b/src/chains/near/near.routes.ts @@ -3,7 +3,7 @@ import { Router, Request, Response, NextFunction } from 'express'; import { Nearish } from '../../services/common-interfaces'; import { asyncHandler } from '../../services/error-handler'; -import { getChain } from '../../services/connection-manager'; +import { getInitializedChain } from '../../services/connection-manager'; import { BalanceResponse, PollRequest, PollResponse } from './near.requests'; import { validateBalanceRequest } from './near.validators'; import * as nearControllers from './near.controllers'; @@ -31,7 +31,10 @@ export namespace NearRoutes { ) => { validateBalanceRequest(req.body); - const chain = await getChain('near', req.body.network); + const chain = await getInitializedChain( + 'near', + req.body.network + ); res .status(200) @@ -51,7 +54,10 @@ export namespace NearRoutes { ) => { validatePollRequest(req.body); - const chain = await getChain('near', req.body.network); + const chain = await getInitializedChain( + 'near', + req.body.network + ); res .status(200) diff --git a/src/clob/clob.controllers.ts b/src/clob/clob.controllers.ts index 6dc07db96e..42ce7624d3 100644 --- a/src/clob/clob.controllers.ts +++ b/src/clob/clob.controllers.ts @@ -2,7 +2,10 @@ import { EstimateGasResponse } from '../amm/amm.requests'; import { latency } from '../services/base'; import { NetworkSelectionRequest } from '../services/common-interfaces'; -import { getChain, getConnector } from '../services/connection-manager'; +import { + getInitializedChain, + getConnector, +} from '../services/connection-manager'; import { ClobBatchUpdateRequest, ClobDeleteOrderRequest, @@ -57,7 +60,7 @@ export async function getMarkets( request: ClobMarketsRequest ): Promise { const startTimestamp: number = Date.now(); - await getChain(request.chain, request.network); + await getInitializedChain(request.chain, request.network); const connector: any = await getConnector( request.chain, request.network, @@ -81,7 +84,7 @@ export async function getOrderBooks( request: ClobOrderbookRequest ): Promise { const startTimestamp: number = Date.now(); - await getChain(request.chain, request.network); + await getInitializedChain(request.chain, request.network); const connector: any = await getConnector( request.chain, request.network, @@ -105,7 +108,7 @@ export async function getTickers( request: ClobTickerRequest ): Promise { const startTimestamp: number = Date.now(); - await getChain(request.chain, request.network); + await getInitializedChain(request.chain, request.network); const connector: any = await getConnector( request.chain, request.network, @@ -129,7 +132,7 @@ export async function getOrders( request: ClobGetOrderRequest ): Promise { const startTimestamp: number = Date.now(); - await getChain(request.chain, request.network); + await getInitializedChain(request.chain, request.network); const connector: any = await getConnector( request.chain, request.network, @@ -153,7 +156,7 @@ export async function postOrder( request: ClobPostOrderRequest ): Promise { const startTimestamp: number = Date.now(); - await getChain(request.chain, request.network); + await getInitializedChain(request.chain, request.network); const connector: any = await getConnector( request.chain, request.network, @@ -177,7 +180,7 @@ export async function deleteOrder( request: ClobDeleteOrderRequest ): Promise { const startTimestamp: number = Date.now(); - await getChain(request.chain, request.network); + await getInitializedChain(request.chain, request.network); const connector: any = await getConnector( request.chain, request.network, @@ -202,7 +205,7 @@ export async function batchOrders( request: ClobBatchUpdateRequest ): Promise { const startTimestamp: number = Date.now(); - await getChain(request.chain, request.network); + await getInitializedChain(request.chain, request.network); const connector: any = await getConnector( request.chain, request.network, @@ -228,7 +231,7 @@ export async function estimateGas( request: NetworkSelectionRequest ): Promise { const startTimestamp: number = Date.now(); - await getChain(request.chain, request.network); + await getInitializedChain(request.chain, request.network); const connector: any = await getConnector( request.chain, request.network, @@ -249,7 +252,7 @@ export async function perpGetMarkets( request: PerpClobMarketRequest ): Promise { const startTimestamp: number = Date.now(); - await getChain(request.chain, request.network); + await getInitializedChain(request.chain, request.network); const connector: any = await getConnector( request.chain, request.network, @@ -268,7 +271,7 @@ export async function perpGetOrderBooks( request: PerpClobOrderbookRequest ): Promise { const startTimestamp: number = Date.now(); - await getChain(request.chain, request.network); + await getInitializedChain(request.chain, request.network); const connector: any = await getConnector( request.chain, request.network, @@ -287,7 +290,7 @@ export async function perpGetTickers( request: PerpClobTickerRequest ): Promise { const startTimestamp: number = Date.now(); - await getChain(request.chain, request.network); + await getInitializedChain(request.chain, request.network); const connector: any = await getConnector( request.chain, request.network, @@ -306,7 +309,7 @@ export async function perpGetOrders( request: PerpClobGetOrderRequest ): Promise { const startTimestamp: number = Date.now(); - await getChain(request.chain, request.network); + await getInitializedChain(request.chain, request.network); const connector: any = await getConnector( request.chain, request.network, @@ -325,7 +328,7 @@ export async function perpPostOrder( request: PerpClobPostOrderRequest ): Promise { const startTimestamp: number = Date.now(); - await getChain(request.chain, request.network); + await getInitializedChain(request.chain, request.network); const connector: any = await getConnector( request.chain, request.network, @@ -344,7 +347,7 @@ export async function perpDeleteOrder( request: PerpClobDeleteOrderRequest ): Promise { const startTimestamp: number = Date.now(); - await getChain(request.chain, request.network); + await getInitializedChain(request.chain, request.network); const connector: any = await getConnector( request.chain, request.network, @@ -363,7 +366,7 @@ export async function perpEstimateGas( request: NetworkSelectionRequest ): Promise { const startTimestamp: number = Date.now(); - await getChain(request.chain, request.network); + await getInitializedChain(request.chain, request.network); const connector: any = await getConnector( request.chain, request.network, @@ -382,7 +385,7 @@ export async function perpFundingInfo( request: PerpClobFundingInfoRequest ): Promise { const startTimestamp: number = Date.now(); - await getChain(request.chain, request.network); + await getInitializedChain(request.chain, request.network); const connector: any = await getConnector( request.chain, request.network, @@ -401,7 +404,7 @@ export async function perpFundingPayments( request: PerpClobFundingPaymentsRequest ): Promise { const startTimestamp: number = Date.now(); - await getChain(request.chain, request.network); + await getInitializedChain(request.chain, request.network); const connector: any = await getConnector( request.chain, request.network, @@ -420,7 +423,7 @@ export async function perpPositions( request: PerpClobPositionRequest ): Promise { const startTimestamp: number = Date.now(); - await getChain(request.chain, request.network); + await getInitializedChain(request.chain, request.network); const connector: any = await getConnector( request.chain, request.network, @@ -439,7 +442,7 @@ export async function perpTrades( request: PerpClobGetTradesRequest ): Promise { const startTimestamp: number = Date.now(); - await getChain(request.chain, request.network); + await getInitializedChain(request.chain, request.network); const connector: any = await getConnector( request.chain, request.network, @@ -458,7 +461,7 @@ export async function perpLastTradePrice( request: PerpClobGetLastTradePriceRequest ): Promise { const startTimestamp: number = Date.now(); - await getChain(request.chain, request.network); + await getInitializedChain(request.chain, request.network); const connector: any = await getConnector( request.chain, request.network, @@ -486,7 +489,7 @@ export async function perpBatchOrders( request: PerpClobBatchUpdateRequest ): Promise { const startTimestamp: number = Date.now(); - await getChain(request.chain, request.network); + await getInitializedChain(request.chain, request.network); const connector: any = await getConnector( request.chain, request.network, diff --git a/src/connectors/connectors.routes.ts b/src/connectors/connectors.routes.ts index b039d748c2..7cf67624c0 100644 --- a/src/connectors/connectors.routes.ts +++ b/src/connectors/connectors.routes.ts @@ -20,6 +20,7 @@ import { XsswapConfig } from './xsswap/xsswap.config'; import { ConnectorsResponse } from './connectors.request'; import { DexalotCLOBConfig } from './dexalot/dexalot.clob.config'; import { ZigZagConfig } from './zigzag/zigzag.config'; +import { TinymanConfig } from './tinyman/tinyman.config'; export namespace ConnectorsRoutes { export const router = Router(); @@ -158,6 +159,12 @@ export namespace ConnectorsRoutes { chain_type: ZigZagConfig.config.chainType, available_networks: ZigZagConfig.config.availableNetworks, }, + { + name: 'tinyman', + trading_type: TinymanConfig.config.tradingTypes, + chain_type: TinymanConfig.config.chainType, + available_networks: TinymanConfig.config.availableNetworks, + }, ], }); }) diff --git a/src/connectors/tinyman/tinyman.config.ts b/src/connectors/tinyman/tinyman.config.ts new file mode 100644 index 0000000000..e9e974b991 --- /dev/null +++ b/src/connectors/tinyman/tinyman.config.ts @@ -0,0 +1,22 @@ +import { ConfigManagerV2 } from '../../services/config-manager-v2'; +import { AvailableNetworks } from '../../services/config-manager-types'; + +export namespace TinymanConfig { + export interface NetworkConfig { + allowedSlippage: string; + tradingTypes: Array; + chainType: string; + availableNetworks: Array; + } + + export const config: NetworkConfig = { + allowedSlippage: ConfigManagerV2.getInstance().get( + 'tinyman.allowedSlippage' + ), + tradingTypes: ['AMM'], + chainType: 'ALGORAND', + availableNetworks: [ + { chain: 'algorand', networks: ['mainnet', 'testnet'] }, + ], + }; +} diff --git a/src/connectors/tinyman/tinyman.controllers.ts b/src/connectors/tinyman/tinyman.controllers.ts new file mode 100644 index 0000000000..979e680f04 --- /dev/null +++ b/src/connectors/tinyman/tinyman.controllers.ts @@ -0,0 +1,160 @@ +import Decimal from 'decimal.js-light'; +import { + HttpException, + PRICE_FAILED_ERROR_CODE, + PRICE_FAILED_ERROR_MESSAGE, + TRADE_FAILED_ERROR_CODE, + TRADE_FAILED_ERROR_MESSAGE, + SWAP_PRICE_EXCEEDS_LIMIT_PRICE_ERROR_CODE, + SWAP_PRICE_EXCEEDS_LIMIT_PRICE_ERROR_MESSAGE, + SWAP_PRICE_LOWER_THAN_LIMIT_PRICE_ERROR_CODE, + SWAP_PRICE_LOWER_THAN_LIMIT_PRICE_ERROR_MESSAGE, + UNKNOWN_ERROR_ERROR_CODE, + UNKNOWN_ERROR_MESSAGE, +} from '../../services/error-handler'; +import { latency } from '../../services/base'; +import { logger } from '../../services/logger'; +import { + EstimateGasResponse, + PriceRequest, + PriceResponse, + TradeRequest, + TradeResponse, +} from '../../amm/amm.requests'; +import { Tinyman } from './tinyman'; +import { Account } from 'algosdk'; +import { Algorand } from '../../chains/algorand/algorand'; + +export async function price( + algorand: Algorand, + tinyman: Tinyman, + req: PriceRequest +): Promise { + const startTimestamp: number = Date.now(); + let trade; + try { + trade = await tinyman.estimateTrade(req); + } catch (e) { + if (e instanceof Error) { + throw new HttpException( + 500, + PRICE_FAILED_ERROR_MESSAGE + e.message, + PRICE_FAILED_ERROR_CODE + ); + } else { + throw new HttpException( + 500, + UNKNOWN_ERROR_MESSAGE, + UNKNOWN_ERROR_ERROR_CODE + ); + } + } + + return { + network: algorand.network, + timestamp: startTimestamp, + latency: latency(startTimestamp, Date.now()), + base: req.base, + quote: req.quote, + amount: req.amount, + rawAmount: req.amount, + expectedAmount: String(trade.expectedAmount), + price: String(trade.expectedPrice), + gasPrice: algorand.gasPrice, + gasPriceToken: algorand.nativeTokenSymbol, + gasLimit: algorand.gasLimit, + gasCost: String(algorand.gasCost), + }; +} + +export async function trade( + algorand: Algorand, + tinyman: Tinyman, + req: TradeRequest +): Promise { + const startTimestamp: number = Date.now(); + + const limitPrice = req.limitPrice; + const account: Account = await algorand.getAccountFromAddress(req.address); + + let trade; + try { + trade = await tinyman.estimateTrade(req); + } catch (e) { + throw new HttpException( + 500, + TRADE_FAILED_ERROR_MESSAGE, + TRADE_FAILED_ERROR_CODE + ); + } + + const estimatedPrice = trade.expectedPrice; + logger.info( + `Expected execution price is ${estimatedPrice}, ` + + `limit price is ${limitPrice}.` + ); + + if (req.side === 'BUY') { + if (limitPrice && new Decimal(estimatedPrice).gt(new Decimal(limitPrice))) { + logger.error('Swap price exceeded limit price.'); + throw new HttpException( + 500, + SWAP_PRICE_EXCEEDS_LIMIT_PRICE_ERROR_MESSAGE( + estimatedPrice, + limitPrice + ), + SWAP_PRICE_EXCEEDS_LIMIT_PRICE_ERROR_CODE + ); + } + } else { + if (limitPrice && new Decimal(estimatedPrice).lt(new Decimal(limitPrice))) { + logger.error('Swap price lower than limit price.'); + throw new HttpException( + 500, + SWAP_PRICE_LOWER_THAN_LIMIT_PRICE_ERROR_MESSAGE( + estimatedPrice, + limitPrice + ), + SWAP_PRICE_LOWER_THAN_LIMIT_PRICE_ERROR_CODE + ); + } + } + const tx = await tinyman.executeTrade( + account, + trade.trade, + req.side === 'BUY' + ); + + logger.info(`${req.side} swap has been executed.`); + + return { + network: algorand.network, + timestamp: startTimestamp, + latency: latency(startTimestamp, Date.now()), + base: req.base, + quote: req.quote, + amount: req.amount, + rawAmount: req.amount, + expectedIn: String(trade.expectedAmount), + price: String(estimatedPrice), + gasPrice: algorand.gasPrice, + gasPriceToken: algorand.nativeTokenSymbol, + gasLimit: algorand.gasLimit, + gasCost: String(algorand.gasCost), + txHash: tx.txnID, + }; +} + +export async function estimateGas( + algorand: Algorand, + _tinyman: Tinyman +): Promise { + return { + network: algorand.network, + timestamp: Date.now(), + gasPrice: algorand.gasPrice, + gasPriceToken: algorand.nativeTokenSymbol, + gasLimit: algorand.gasLimit, + gasCost: String(algorand.gasCost), + }; +} diff --git a/src/connectors/tinyman/tinyman.ts b/src/connectors/tinyman/tinyman.ts new file mode 100644 index 0000000000..a2cd31371e --- /dev/null +++ b/src/connectors/tinyman/tinyman.ts @@ -0,0 +1,222 @@ +import { + poolUtils, + SignerTransaction, + SupportedNetwork, + Swap, + SwapQuote, + SwapQuoteType, + SwapType, + V2PoolInfo, +} from '@tinymanorg/tinyman-js-sdk'; +import { V2SwapExecution } from '@tinymanorg/tinyman-js-sdk/dist/swap/types'; +import { Account } from 'algosdk'; +import LRUCache from 'lru-cache'; +import { pow } from 'mathjs'; +import { PriceRequest } from '../../amm/amm.requests'; +import { Algorand } from '../../chains/algorand/algorand'; +import { getAlgorandConfig } from '../../chains/algorand/algorand.config'; +import { AlgorandAsset } from '../../chains/algorand/algorand.requests'; +import { percentRegexp } from '../../services/config-manager-v2'; +import { + HttpException, + TOKEN_NOT_SUPPORTED_ERROR_CODE, + TOKEN_NOT_SUPPORTED_ERROR_MESSAGE, +} from '../../services/error-handler'; +import { logger } from '../../services/logger'; +import { TinymanConfig } from './tinyman.config'; + +export class Tinyman { + private static _instances: LRUCache; + private chain: Algorand; + private _ready: boolean = false; + private _config: TinymanConfig.NetworkConfig; + private _swap; + + public get swap() { + return this._swap; + } + + private constructor(network: string) { + this._config = TinymanConfig.config; + this.chain = Algorand.getInstance(network); + this._swap = Swap; + } + + public static getInstance(network: string): Tinyman { + const config = getAlgorandConfig(network); + if (Tinyman._instances === undefined) { + Tinyman._instances = new LRUCache({ + max: config.network.maxLRUCacheInstances, + }); + } + + if (!Tinyman._instances.has(network)) { + if (network !== null) { + Tinyman._instances.set(network, new Tinyman(network)); + } else { + throw new Error( + `Tinyman.getInstance received an unexpected network: ${network}.` + ); + } + } + + return Tinyman._instances.get(network) as Tinyman; + } + + public async init() { + if (!this.chain.ready()) { + await this.chain.init(); + } + this._ready = true; + } + + public ready(): boolean { + return this._ready; + } + + /** + * Gets the allowed slippage percent from configuration. + */ + getSlippage(): number { + const allowedSlippage = this._config.allowedSlippage; + const nd = allowedSlippage.match(percentRegexp); + let slippage = 0.0; + if (nd) slippage = Number(nd[1]) / Number(nd[2]); + return slippage; + } + + /** + * Fetches information about a pair and constructs a pair from the given two tokens. + * This is to replace the Fetcher Class + * @param baseToken first token + * @param quoteToken second token + */ + + async fetchData( + baseToken: AlgorandAsset, + quoteToken: AlgorandAsset + ): Promise { + logger.info( + `Fetching pair data for ${baseToken.symbol}-${quoteToken.symbol}.` + ); + return await poolUtils.v2.getPoolInfo({ + network: this.chain.network as SupportedNetwork, + client: this.chain.algod, + asset1ID: baseToken.assetId, + asset2ID: quoteToken.assetId, + }); + } + + /** + * This is typically used for calculating token prices. + * + * @param req Price request object + */ + + async estimateTrade(req: PriceRequest) { + const baseToken: AlgorandAsset | null = this.chain.getAssetForSymbol( + req.base + ); + const quoteToken: AlgorandAsset | null = this.chain.getAssetForSymbol( + req.quote + ); + + if (baseToken === null || quoteToken === null) + throw new HttpException( + 500, + TOKEN_NOT_SUPPORTED_ERROR_MESSAGE, + TOKEN_NOT_SUPPORTED_ERROR_CODE + ); + const baseAsset = { id: baseToken.assetId, decimals: baseToken.decimals }; + const quoteAsset = { + id: quoteToken.assetId, + decimals: quoteToken.decimals, + }; + const amount = Number(req.amount) * pow(10, baseToken.decimals); + const isBuy: boolean = req.side === 'BUY'; + const pool: V2PoolInfo = await this.fetchData(baseToken, quoteToken); + + const quote = await this.swap.v2.getQuote({ + type: isBuy === true ? SwapType.FixedOutput : SwapType.FixedInput, + amount: Number(amount.toString()), + assetIn: isBuy === true ? quoteAsset : baseAsset, + assetOut: isBuy === true ? baseAsset : quoteAsset, + pool, + network: this.chain.network as SupportedNetwork, + isSwapRouterEnabled: false, + }); + const price = + quote.type === SwapQuoteType.Direct ? quote.data.quote.rate : 0; + logger.info( + `Best quote for ${baseToken.symbol}-${quoteToken.symbol}: ` + + `${price}` + + `${baseToken.symbol}.` + ); + const expectedPrice = isBuy === true ? 1 / price : price; + const expectedAmount = + req.side === 'BUY' + ? Number(req.amount) + : expectedPrice * Number(req.amount); + + return { trade: quote, expectedAmount, expectedPrice }; + } + + /** + * Given an account and a tinyman trade, try to execute it on blockchain. + * + * @param account Algorand account + * @param quote Expected trade + * @param isBuy Used to indicate buy or sell swap + */ + + async executeTrade( + account: Account, + quote: SwapQuote, + isBuy: boolean + ): Promise { + const network = this.chain.network as SupportedNetwork; + const fixedSwapTxns = await this.swap.v2.generateTxns({ + client: this.chain.algod, + network, + swapType: isBuy === true ? SwapType.FixedOutput : SwapType.FixedInput, + quote, + slippage: this.getSlippage(), + initiatorAddr: account.addr, + }); + const signedTxns = await this.swap.v2.signTxns({ + txGroup: fixedSwapTxns, + initiatorSigner: this.signerWithSecretKey(account), + }); + const tx = await this.swap.v2.execute({ + client: this.chain.algod, + quote, + txGroup: fixedSwapTxns, + signedTxns, + }); + + logger.info(`Swap transaction Id: ${tx.txnID}`); + return tx; + } + + /** + * @param account account data that will sign the transactions + * @returns a function that will sign the transactions, can be used as `initiatorSigner` + */ + signerWithSecretKey(account: Account) { + return function (txGroups: SignerTransaction[][]): Promise { + // Filter out transactions that don't need to be signed by the account + const txnsToBeSigned = txGroups.flatMap((txGroup) => + txGroup.filter((item) => item.signers?.includes(account.addr)) + ); + // Sign all transactions that need to be signed by the account + const signedTxns: Uint8Array[] = txnsToBeSigned.map(({ txn }) => + txn.signTxn(account.sk) + ); + + // We wrap this with a Promise since SDK's initiatorSigner expects a Promise + return new Promise((resolve) => { + resolve(signedTxns); + }); + }; + } +} diff --git a/src/evm/evm.routes.ts b/src/evm/evm.routes.ts index 55fec975fd..d064a0c0ac 100644 --- a/src/evm/evm.routes.ts +++ b/src/evm/evm.routes.ts @@ -22,7 +22,7 @@ import { validateXdcAllowancesRequest, } from '../chains/xdc/xdc.validators'; -import { getChain } from '../services/connection-manager'; +import { getInitializedChain } from '../services/connection-manager'; import { AllowancesRequest, AllowancesResponse, @@ -45,7 +45,7 @@ export namespace EVMRoutes { res: Response ) => { validateNonceRequest(req.body); - const chain = await getChain( + const chain = await getInitializedChain( req.body.chain, req.body.network ); @@ -62,7 +62,7 @@ export namespace EVMRoutes { res: Response ) => { validateNonceRequest(req.body); - const chain = await getChain( + const chain = await getInitializedChain( req.body.chain, req.body.network ); @@ -83,7 +83,7 @@ export namespace EVMRoutes { } else { validateAllowancesRequest(req.body); } - const chain = await getChain( + const chain = await getInitializedChain( req.body.chain, req.body.network ); @@ -105,7 +105,7 @@ export namespace EVMRoutes { validateApproveRequest(req.body); } - const chain = await getChain( + const chain = await getInitializedChain( req.body.chain, req.body.network ); @@ -122,7 +122,7 @@ export namespace EVMRoutes { res: Response ) => { validateCancelRequest(req.body); - const chain = await getChain( + const chain = await getInitializedChain( req.body.chain, req.body.network ); diff --git a/src/network/network.controllers.ts b/src/network/network.controllers.ts index 5a89028ff6..9a5a7af320 100644 --- a/src/network/network.controllers.ts +++ b/src/network/network.controllers.ts @@ -20,6 +20,11 @@ import { EthereumBase, TokenInfo } from '../chains/ethereum/ethereum-base'; import { Cronos } from '../chains/cronos/cronos'; import { Near } from '../chains/near/near'; import { Nearish, Xdcish } from '../services/common-interfaces'; +import { Algorand } from '../chains/algorand/algorand'; +import { + getInitializedChain, + UnsupportedChainException, +} from '../services/connection-manager'; export async function getStatus( req: StatusRequest @@ -28,37 +33,32 @@ export async function getStatus( let connections: any[] = []; let chain: string; let chainId: number; + let network: string; let rpcUrl: string; let currentBlockNumber: number | undefined; let nativeCurrency: string; if (req.chain) { - if (req.chain === 'avalanche') { - connections.push(Avalanche.getInstance(req.network as string)); - } else if (req.chain === 'binance-smart-chain') { - connections.push(BinanceSmartChain.getInstance(req.network as string)); - } else if (req.chain === 'harmony') { - connections.push(Harmony.getInstance(req.network as string)); - } else if (req.chain === 'ethereum') { - connections.push(Ethereum.getInstance(req.network as string)); - } else if (req.chain === 'polygon') { - connections.push(Polygon.getInstance(req.network as string)); - } else if (req.chain === 'xdc') { - connections.push(Xdc.getInstance(req.network as string)); - } else if (req.chain === 'near') { - connections.push(Near.getInstance(req.network as string)); - } else if (req.chain === 'cronos') { - connections.push(await Cronos.getInstance(req.network as string)); - } else if (req.chain === 'injective') { - connections.push(Injective.getInstance(req.network as string)); - } else { - throw new HttpException( - 500, - UNKNOWN_KNOWN_CHAIN_ERROR_MESSAGE(req.chain), - UNKNOWN_CHAIN_ERROR_CODE + try { + connections.push( + await getInitializedChain(req.chain, req.network as string) ); + } catch (e) { + if (e instanceof UnsupportedChainException) { + throw new HttpException( + 500, + UNKNOWN_KNOWN_CHAIN_ERROR_MESSAGE(req.chain), + UNKNOWN_CHAIN_ERROR_CODE + ); + } + throw e; } } else { + const algorandConnections = Algorand.getConnectedInstances(); + connections = connections.concat( + algorandConnections ? Object.values(algorandConnections) : [] + ); + const avalancheConnections = Avalanche.getConnectedInstances(); connections = connections.concat( avalancheConnections ? Object.values(avalancheConnections) : [] @@ -104,11 +104,9 @@ export async function getStatus( } for (const connection of connections) { - if (!connection.ready()) { - await connection.init(); - } chain = connection.chain; chainId = connection.chainId; + network = connection.network; rpcUrl = connection.rpcUrl; nativeCurrency = connection.nativeTokenSymbol; @@ -120,6 +118,7 @@ export async function getStatus( statuses.push({ chain, chainId, + network, rpcUrl, currentBlockNumber, nativeCurrency, @@ -130,34 +129,25 @@ export async function getStatus( } export async function getTokens(req: TokensRequest): Promise { - let connection: EthereumBase | Nearish | Injective | Xdcish; + type connectionType = EthereumBase | Nearish | Injective | Xdcish; + let connection: connectionType; let tokens: TokenInfo[] = []; if (req.chain && req.network) { - if (req.chain === 'avalanche') { - connection = Avalanche.getInstance(req.network); - } else if (req.chain === 'binance-smart-chain') { - connection = BinanceSmartChain.getInstance(req.network); - } else if (req.chain === 'harmony') { - connection = Harmony.getInstance(req.network); - } else if (req.chain === 'ethereum') { - connection = Ethereum.getInstance(req.network); - } else if (req.chain === 'polygon') { - connection = Polygon.getInstance(req.network); - } else if (req.chain === 'xdc') { - connection = Xdc.getInstance(req.network); - } else if (req.chain === 'near') { - connection = Near.getInstance(req.network); - } else if (req.chain === 'cronos') { - connection = await Cronos.getInstance(req.network); - } else if (req.chain === 'injective') { - connection = Injective.getInstance(req.network); - } else { - throw new HttpException( - 500, - UNKNOWN_KNOWN_CHAIN_ERROR_MESSAGE(req.chain), - UNKNOWN_CHAIN_ERROR_CODE - ); + try { + connection = (await getInitializedChain( + req.chain as string, + req.network as string + )) as connectionType; + } catch (e) { + if (e instanceof UnsupportedChainException) { + throw new HttpException( + 500, + UNKNOWN_KNOWN_CHAIN_ERROR_MESSAGE(req.chain), + UNKNOWN_CHAIN_ERROR_CODE + ); + } + throw e; } } else { throw new HttpException( @@ -167,10 +157,6 @@ export async function getTokens(req: TokensRequest): Promise { ); } - if (!connection.ready()) { - await connection.init(); - } - if (!req.tokenSymbols) { tokens = connection.storedTokenList; } else { diff --git a/src/network/network.requests.ts b/src/network/network.requests.ts index 43a0628a04..e8ce46a299 100644 --- a/src/network/network.requests.ts +++ b/src/network/network.requests.ts @@ -41,6 +41,7 @@ export interface StatusRequest { export interface StatusResponse { chain: string; chainId: number; + network: string; rpcUrl: string; nativeCurrency: string; currentBlockNumber?: number; // only reachable if connected diff --git a/src/network/network.routes.ts b/src/network/network.routes.ts index 67dd9a79ac..8abefae8d7 100644 --- a/src/network/network.routes.ts +++ b/src/network/network.routes.ts @@ -3,7 +3,7 @@ import { NextFunction, Request, Response, Router } from 'express'; import * as ethereumControllers from '../chains/ethereum/ethereum.controllers'; import { Ethereumish } from '../services/common-interfaces'; import { ConfigManagerV2 } from '../services/config-manager-v2'; -import { getChain } from '../services/connection-manager'; +import { getInitializedChain } from '../services/connection-manager'; import { asyncHandler } from '../services/error-handler'; import { mkRequestValidator, @@ -64,7 +64,7 @@ export namespace NetworkRoutes { _next: NextFunction ) => { validateEthereumBalanceRequest(req.body); - const chain = await getChain( + const chain = await getInitializedChain( req.body.chain, req.body.network ); @@ -85,7 +85,7 @@ export namespace NetworkRoutes { ) => { validatePollRequest(req.body); - const chain = await getChain( + const chain = await getInitializedChain( req.body.chain, req.body.network ); diff --git a/src/services/connection-manager.ts b/src/services/connection-manager.ts index df0f5953a3..37af1d8411 100644 --- a/src/services/connection-manager.ts +++ b/src/services/connection-manager.ts @@ -36,10 +36,23 @@ import { Near } from '../chains/near/near'; import { Ref } from '../connectors/ref/ref'; import { Xsswap } from '../connectors/xsswap/xsswap'; import { DexalotCLOB } from '../connectors/dexalot/dexalot'; +import { Algorand } from '../chains/algorand/algorand'; +import { Cosmos } from '../chains/cosmos/cosmos'; +import { Tinyman } from '../connectors/tinyman/tinyman'; -export type ChainUnion = Ethereumish | Nearish | Injective | Xdcish; +export type ChainUnion = + | Algorand + | Cosmos + | Ethereumish + | Nearish + | Injective + | Xdcish; -export type Chain = T extends Ethereumish +export type Chain = T extends Algorand + ? Algorand + : T extends Cosmos + ? Cosmos + : T extends Ethereumish ? Ethereumish : T extends Nearish ? Nearish @@ -49,25 +62,27 @@ export type Chain = T extends Ethereumish ? Injective : never; -export async function getChain( +export class UnsupportedChainException extends Error { + constructor(message?: string) { + message = + message !== undefined + ? message + : 'Please provide a supported chain name.'; + super(message); + this.name = 'UnsupportedChainError'; + this.stack = (new Error()).stack; + } +} + +export async function getInitializedChain( chain: string, network: string ): Promise> { - let chainInstance: ChainUnion; - - if (chain === 'ethereum') chainInstance = Ethereum.getInstance(network); - else if (chain === 'avalanche') - chainInstance = Avalanche.getInstance(network); - else if (chain === 'polygon') chainInstance = Polygon.getInstance(network); - else if (chain === 'xdc') chainInstance = Xdc.getInstance(network); - else if (chain === 'harmony') chainInstance = Harmony.getInstance(network); - else if (chain === 'near') chainInstance = Near.getInstance(network); - else if (chain === 'binance-smart-chain') - chainInstance = BinanceSmartChain.getInstance(network); - else if (chain === 'cronos') chainInstance = Cronos.getInstance(network); - else if (chain === 'injective') - chainInstance = Injective.getInstance(network); - else throw new Error('unsupported chain'); + const chainInstance = getChainInstance(chain, network); + + if (chainInstance === undefined) { + throw new UnsupportedChainException(`unsupported chain ${chain}`); + } if (!chainInstance.ready()) { await chainInstance.init(); @@ -76,6 +91,41 @@ export async function getChain( return chainInstance as Chain; } +export function getChainInstance( + chain: string, + network: string +): ChainUnion | undefined { + let connection: ChainUnion | undefined; + + if (chain === 'algorand') { + connection = Algorand.getInstance(network); + } else if (chain === 'ethereum') { + connection = Ethereum.getInstance(network); + } else if (chain === 'avalanche') { + connection = Avalanche.getInstance(network); + } else if (chain === 'harmony') { + connection = Harmony.getInstance(network); + } else if (chain === 'polygon') { + connection = Polygon.getInstance(network); + } else if (chain === 'cronos') { + connection = Cronos.getInstance(network); + } else if (chain === 'cosmos') { + connection = Cosmos.getInstance(network); + } else if (chain === 'near') { + connection = Near.getInstance(network); + } else if (chain === 'binance-smart-chain') { + connection = BinanceSmartChain.getInstance(network); + } else if (chain === 'xdc') { + connection = Xdc.getInstance(network); + } else if (chain === 'injective') { + connection = Injective.getInstance(network); + } else { + connection = undefined; + } + + return connection; +} + export type ConnectorUnion = | Uniswapish | UniswapLPish @@ -83,7 +133,8 @@ export type ConnectorUnion = | RefAMMish | CLOBish | ZigZag - | InjectiveClobPerp; + | InjectiveClobPerp + | Tinyman; export type Connector = T extends Uniswapish ? Uniswapish @@ -99,6 +150,8 @@ export type Connector = T extends Uniswapish ? ZigZag : T extends InjectiveClobPerp ? InjectiveClobPerp + : T extends Tinyman + ? Tinyman : never; export async function getConnector( @@ -153,6 +206,8 @@ export async function getConnector( connectorInstance = DexalotCLOB.getInstance(network); } else if (chain === 'ethereum' && connector === 'zigzag') { connectorInstance = ZigZag.getInstance(network); + } else if (chain == 'algorand' && connector == 'tinyman') { + connectorInstance = Tinyman.getInstance(network); } else { throw new Error('unsupported chain or connector'); } diff --git a/src/services/schema/algorand-schema.json b/src/services/schema/algorand-schema.json new file mode 100644 index 0000000000..c45ea9f9ab --- /dev/null +++ b/src/services/schema/algorand-schema.json @@ -0,0 +1,50 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "type": "object", + "properties": { + "networks": { + "type": "object", + "patternProperties": { + "^\\w+$": { + "type": "object", + "properties": { + "chainId": { + "type": "string" + }, + "nodeURL": { + "type": "string" + }, + "indexerURL": { + "type": "string" + }, + "assetListType": { + "type": "string" + }, + "assetListSource": { + "type": "string" + } + }, + "required": [ + "chainId", + "nodeURL", + "indexerURL", + "assetListType", + "assetListSource" + ], + "additionalProperties": false + } + }, + "additionalProperties": false + }, + "nativeCurrencySymbol": { + "type": "string" + }, + "gasLimitEstimate": { + "type": "integer" + } + }, + "additionalProperties": false, + "required": [ + "nativeCurrencySymbol" + ] +} diff --git a/src/services/schema/tinyman-schema.json b/src/services/schema/tinyman-schema.json new file mode 100644 index 0000000000..16bee50e7f --- /dev/null +++ b/src/services/schema/tinyman-schema.json @@ -0,0 +1,11 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "type": "object", + "properties": { + "allowedSlippage": { "type": "string" } + }, + "additionalProperties": false, + "required": [ + "allowedSlippage" + ] +} diff --git a/src/services/wallet/wallet.controllers.ts b/src/services/wallet/wallet.controllers.ts index 35d4047019..c547aeea34 100644 --- a/src/services/wallet/wallet.controllers.ts +++ b/src/services/wallet/wallet.controllers.ts @@ -1,12 +1,6 @@ import fse from 'fs-extra'; -import { Avalanche } from '../../chains/avalanche/avalanche'; -import { BinanceSmartChain } from '../../chains/binance-smart-chain/binance-smart-chain'; -import { Cronos } from '../../chains/cronos/cronos'; -import { Ethereum } from '../../chains/ethereum/ethereum'; -import { Polygon } from '../../chains/polygon/polygon'; import { Xdc } from '../../chains/xdc/xdc'; import { Cosmos } from '../../chains/cosmos/cosmos'; -import { Harmony } from '../../chains/harmony/harmony'; import { Injective } from '../../chains/injective/injective'; import { @@ -31,8 +25,13 @@ import { } from '../error-handler'; import { EthereumBase } from '../../chains/ethereum/ethereum-base'; import { Near } from '../../chains/near/near'; -import { getChain } from '../connection-manager'; +import { + ChainUnion, + getInitializedChain, + UnsupportedChainException, +} from '../connection-manager'; import { Ethereumish } from '../common-interfaces'; +import { Algorand } from '../../chains/algorand/algorand'; export function convertXdcAddressToEthAddress(publicKey: string): string { return publicKey.length === 43 && publicKey.slice(0, 3) === 'xdc' @@ -41,6 +40,7 @@ export function convertXdcAddressToEthAddress(publicKey: string): string { } const walletPath = './conf/wallets'; + export async function mkdirIfDoesNotExist(path: string): Promise { const exists = await fse.pathExists(path); if (!exists) { @@ -55,50 +55,38 @@ export async function addWallet( if (!passphrase) { throw new Error('There is no passphrase'); } - let connection: EthereumBase | Near | Cosmos | Injective | Xdc; + let connection: ChainUnion; let address: string | undefined; let encryptedPrivateKey: string | undefined; - if (req.chain === 'ethereum') { - connection = Ethereum.getInstance(req.network); - } else if (req.chain === 'avalanche') { - connection = Avalanche.getInstance(req.network); - } else if (req.chain === 'harmony') { - connection = Harmony.getInstance(req.network); - } else if (req.chain === 'polygon') { - connection = Polygon.getInstance(req.network); - } else if (req.chain === 'cronos') { - connection = Cronos.getInstance(req.network); - } else if (req.chain === 'cosmos') { - connection = Cosmos.getInstance(req.network); - } else if (req.chain === 'near') { - if (!('address' in req)) + if (req.chain === 'near') { + if (!('address' in req)) { throw new HttpException( 500, ACCOUNT_NOT_SPECIFIED_ERROR_MESSAGE(), ACCOUNT_NOT_SPECIFIED_CODE ); - connection = Near.getInstance(req.network); - } else if (req.chain === 'binance-smart-chain') { - connection = BinanceSmartChain.getInstance(req.network); - } else if (req.chain === 'xdc') { - connection = Xdc.getInstance(req.network); - } else if (req.chain === 'injective') { - connection = Injective.getInstance(req.network); - } else { - throw new HttpException( - 500, - UNKNOWN_KNOWN_CHAIN_ERROR_MESSAGE(req.chain), - UNKNOWN_CHAIN_ERROR_CODE - ); + } } - if (!connection.ready()) { - await connection.init(); + try { + connection = await getInitializedChain(req.chain, req.network); + } catch (e) { + if (e instanceof UnsupportedChainException) { + throw new HttpException( + 500, + UNKNOWN_KNOWN_CHAIN_ERROR_MESSAGE(req.chain), + UNKNOWN_CHAIN_ERROR_CODE + ); + } + throw e; } try { - if (connection instanceof EthereumBase) { + if (connection instanceof Algorand) { + address = connection.getAccountFromPrivateKey(req.privateKey).addr; + encryptedPrivateKey = connection.encrypt(req.privateKey, passphrase); + } else if (connection instanceof EthereumBase) { address = connection.getWalletFromPrivateKey(req.privateKey).address; encryptedPrivateKey = await connection.encrypt( req.privateKey, @@ -113,12 +101,12 @@ export async function addWallet( passphrase ); } else if (connection instanceof Cosmos) { - const wallet = await connection.getAccountsfromPrivateKey( + const wallet = await (connection as Cosmos).getAccountsfromPrivateKey( req.privateKey, 'cosmos' ); address = wallet.address; - encryptedPrivateKey = await connection.encrypt( + encryptedPrivateKey = await (connection as Cosmos).encrypt( req.privateKey, passphrase ); @@ -171,7 +159,7 @@ export async function removeWallet(req: RemoveWalletRequest): Promise { export async function signMessage( req: WalletSignRequest ): Promise { - const chain: Ethereumish = await getChain(req.chain, req.network); + const chain: Ethereumish = await getInitializedChain(req.chain, req.network); const wallet = await chain.getWallet(req.address); return { signature: await wallet.signMessage(req.message) }; } diff --git a/src/services/wallet/wallet.validators.ts b/src/services/wallet/wallet.validators.ts index e262982fc2..65da5f34fe 100644 --- a/src/services/wallet/wallet.validators.ts +++ b/src/services/wallet/wallet.validators.ts @@ -5,8 +5,12 @@ import { Validator, mkSelectingValidator, } from '../validators'; + const { fromBase64 } = require('@cosmjs/encoding'); +export const invalidAlgorandPrivateKeyOrMnemonicError: string = + 'The privateKey param is not a valid Algorand private key or mnemonic.'; + export const invalidEthPrivateKeyError: string = 'The privateKey param is not a valid Ethereum private key (64 hexadecimal characters).'; @@ -16,6 +20,11 @@ export const invalidNearPrivateKeyError: string = export const invalidCosmosPrivateKeyError: string = 'The privateKey param is not a valid Cosmos private key.'; +export const isAlgorandPrivateKeyOrMnemonic = (str: string): boolean => { + const parts = str.split(' '); + return parts.length === 25; +}; + // test if a string matches the shape of an Ethereum private key export const isEthPrivateKey = (str: string): boolean => { return /^(0x|xdc)?[a-fA-F0-9]{64}$/.test(str); @@ -42,6 +51,11 @@ export const validatePrivateKey: Validator = mkSelectingValidator( 'chain', (req, key) => req[key], { + algorand: mkValidator( + 'privateKey', + invalidAlgorandPrivateKeyOrMnemonicError, + (val) => typeof val === 'string' && isAlgorandPrivateKeyOrMnemonic(val) + ), ethereum: mkValidator( 'privateKey', invalidEthPrivateKeyError, @@ -114,7 +128,8 @@ export const validateChain: Validator = mkValidator( invalidChainError, (val) => typeof val === 'string' && - (val === 'ethereum' || + (val === 'algorand' || + val === 'ethereum' || val === 'avalanche' || val === 'polygon' || val === 'xdc' || diff --git a/src/templates/algorand.yml b/src/templates/algorand.yml new file mode 100644 index 0000000000..f675a41ae1 --- /dev/null +++ b/src/templates/algorand.yml @@ -0,0 +1,16 @@ +networks: + mainnet: + chainId: mainnet + nodeURL: https://xna-mainnet-api.algonode.cloud + indexerURL: https://mainnet-idx.algonode.cloud + assetListType: URL + assetListSource: 'https://mainnet.analytics.tinyman.org/api/v1/assets/?limit=1000&is_pool_member=true&with_statistics=false&verified_only=true' + testnet: + chainId: testnet + nodeURL: https://testnet-api.algonode.network + indexerURL: https://testnet-idx.algonode.cloud + assetListType: URL + assetListSource: 'https://testnet.analytics.tinyman.org/api/v1/assets/?limit=1000&is_pool_member=true&with_statistics=false&verified_only=true' + +nativeCurrencySymbol: ALGO +gasLimitEstimate: 500000 diff --git a/src/templates/root.yml b/src/templates/root.yml index cb22e62331..ea919906ec 100644 --- a/src/templates/root.yml +++ b/src/templates/root.yml @@ -4,6 +4,10 @@ configurations: configurationPath: server.yml schemaPath: server-schema.json + $namespace algorand: + configurationPath: algorand.yml + schemaPath: algorand-schema.json + $namespace ethereum: configurationPath: ethereum.yml schemaPath: ethereum-schema.json @@ -18,12 +22,12 @@ configurations: $namespace dexalot: configurationPath: dexalot.yml - schemaPath: dexalot-schema.json + schemaPath: dexalot-schema.json $namespace polygon: configurationPath: polygon.yml schemaPath: ethereum-schema.json - + $namespace defira: configurationPath: defira.yml schemaPath: defira-schema.json @@ -39,7 +43,7 @@ configurations: $namespace quickswap: configurationPath: quickswap.yml schemaPath: quickswap-schema.json - + $namespace perp: configurationPath: perp.yml schemaPath: perp-schema.json @@ -48,10 +52,14 @@ configurations: configurationPath: sushiswap.yml schemaPath: sushiswap-schema.json + $namespace tinyman: + configurationPath: tinyman.yml + schemaPath: tinyman-schema.json + $namespace traderjoe: configurationPath: traderjoe.yml schemaPath: traderjoe-schema.json - + $namespace uniswap: configurationPath: uniswap.yml schemaPath: uniswap-schema.json @@ -77,12 +85,12 @@ configurations: schemaPath: ethereum-schema.json $namespace mad_meerkat: - configurationPath: mad_meerkat.yml - schemaPath: cronos-connector-schema.json + configurationPath: mad_meerkat.yml + schemaPath: cronos-connector-schema.json $namespace vvs: - configurationPath: vvs.yml - schemaPath: cronos-connector-schema.json + configurationPath: vvs.yml + schemaPath: cronos-connector-schema.json $namespace binance-smart-chain: configurationPath: binance-smart-chain.yml diff --git a/src/templates/tinyman.yml b/src/templates/tinyman.yml new file mode 100644 index 0000000000..4d02117f25 --- /dev/null +++ b/src/templates/tinyman.yml @@ -0,0 +1,3 @@ +# allowedSlippage: how much the execution price is allowed to move unfavorably +# from the trade execution price. It uses a rational number for precision. +allowedSlippage: '2/100' diff --git a/test-helpers/curl/curl.sh b/test-helpers/curl/curl.sh index 24be3d5391..bbaffbf6ec 100644 --- a/test-helpers/curl/curl.sh +++ b/test-helpers/curl/curl.sh @@ -32,6 +32,8 @@ curl -s -X GET -k --key $GATEWAY_KEY --cert $GATEWAY_CERT "https://localhost:158 curl -s -X GET -k --key $GATEWAY_KEY --cert $GATEWAY_CERT "https://localhost:15888/network/status?chain=cronos&network=mainnet" | jq +curl -s -X GET -k --key $GATEWAY_KEY --cert $GATEWAY_CERT "https://localhost:15888/network/status?chain=algorand&network=mainnet" | jq + curl -s -X GET -k --key $GATEWAY_KEY --cert $GATEWAY_CERT https://localhost:15888/network/config | jq curl -s -X POST -k --key $GATEWAY_KEY --cert $GATEWAY_CERT -H "Content-Type: application/json" -d "$(envsubst < ./requests/network_poll.json)" https://localhost:15888/network/poll | jq @@ -55,6 +57,8 @@ curl -s -X POST -k --key $GATEWAY_KEY --cert $GATEWAY_CERT -H "Content-Type: app # Wallet ## add private keys +curl -s -X POST -k --key $GATEWAY_KEY --cert $GATEWAY_CERT -H "Content-Type: application/json" -d "$(envsubst < ./requests/add_algorand_key.json)" https://localhost:15888/wallet/add | jq + curl -s -X POST -k --key $GATEWAY_KEY --cert $GATEWAY_CERT -H "Content-Type: application/json" -d "$(envsubst < ./requests/add_ethereum_key.json)" https://localhost:15888/wallet/add | jq curl -s -X POST -k --key $GATEWAY_KEY --cert $GATEWAY_CERT -H "Content-Type: application/json" -d "$(envsubst < ./requests/add_avalanche_key.json)" https://localhost:15888/wallet/add | jq @@ -80,6 +84,8 @@ curl -s -X GET -k --key $GATEWAY_KEY --cert $GATEWAY_CERT https://localhost:1588 curl -s -X GET -k --key $GATEWAY_KEY --cert $GATEWAY_CERT "https://localhost:15888/wallet/sign?chain=ethereum&network=mainnet&address=$ETH_ADDRESS&message=messageToBeSigned" | jq ## remove keys +curl -s -X DELETE -k --key $GATEWAY_KEY --cert $GATEWAY_CERT -H "Content-Type: application/json" -d "$(envsubst < ./requests/remove_algorand_key.json)" https://localhost:15888/wallet/remove | jq + curl -s -X DELETE -k --key $GATEWAY_KEY --cert $GATEWAY_CERT -H "Content-Type: application/json" -d "$(envsubst < ./requests/remove_ethereum_key.json)" https://localhost:15888/wallet/remove | jq curl -s -X DELETE -k --key $GATEWAY_KEY --cert $GATEWAY_CERT -H "Content-Type: application/json" -d "$(envsubst < ./requests/remove_avalanche_key.json)" https://localhost:15888/wallet/remove | jq @@ -124,6 +130,8 @@ curl -s -X POST -k --key $GATEWAY_KEY --cert $GATEWAY_CERT -H "Content-Type: app curl -s -X POST -k --key $GATEWAY_KEY --cert $GATEWAY_CERT -H "Content-Type: application/json" -d "$(envsubst < ./requests/price_zigzag.json)" https://localhost:15888/amm/price | jq +curl -s -X POST -k --key $GATEWAY_KEY --cert $GATEWAY_CERT -H "Content-Type: application/json" -d "$(envsubst < ./requests/price_tinyman.json)" https://localhost:15888/amm/price | jq + ## trade curl -s -X POST -k --key $GATEWAY_KEY --cert $GATEWAY_CERT -H "Content-Type: application/json" -d "$(envsubst < ./requests/eth_uniswap_trade.json)" https://localhost:15888/amm/trade | jq @@ -150,6 +158,8 @@ curl -s -X POST -k --key $GATEWAY_KEY --cert $GATEWAY_CERT -H "Content-Type: app curl -s -X POST -k --key $GATEWAY_KEY --cert $GATEWAY_CERT -H "Content-Type: application/json" -d "$(envsubst < ./requests/eth_zigzag_trade.json)" https://localhost:15888/amm/trade | jq +curl -s -X POST -k --key $GATEWAY_KEY --cert $GATEWAY_CERT -H "Content-Type: application/json" -d "$(envsubst < ./requests/algorand_tinyman_trade.json)" https://localhost:15888/amm/trade | jq + ## Perp - curie ### Market prices @@ -229,6 +239,20 @@ curl -s -X POST -k --key $GATEWAY_KEY --cert $GATEWAY_CERT -H "Content-Type: app curl -s -X POST -k --key $GATEWAY_KEY --cert $GATEWAY_CERT -H "Content-Type: application/json" -d "$(envsubst < ./requests/xdc_approve.json)" https://localhost:15888/evm/approve | jq +# Algorand + +## post poll +curl -s -X POST -k --key $GATEWAY_KEY --cert $GATEWAY_CERT -H "Content-Type: application/json" -d "$(envsubst < ./requests/algorand_poll.json)" https://localhost:15888/algorand/poll | jq + +## get balances +curl -s -X POST -k --key $GATEWAY_KEY --cert $GATEWAY_CERT -H "Content-Type: application/json" -d "$(envsubst < ./requests/algorand_balances.json)" https://localhost:15888/algorand/balances | jq + +## get assets +curl -s -X GET -k --key $GATEWAY_KEY --cert $GATEWAY_CERT "https://localhost:15888/algorand/assets?network=mainnet" | jq + +## post opt-in +curl -s -X POST -k --key $GATEWAY_KEY --cert $GATEWAY_CERT -H "Content-Type: application/json" -d "$(envsubst < ./requests/algorand_opt_in.json)" https://localhost:15888/algorand/opt-in | jq + # NEAR ## get balances diff --git a/test-helpers/curl/requests/add_algorand_key.json b/test-helpers/curl/requests/add_algorand_key.json new file mode 100644 index 0000000000..ffa8aec259 --- /dev/null +++ b/test-helpers/curl/requests/add_algorand_key.json @@ -0,0 +1,5 @@ +{ + "privateKey": "$ALGORAND_MNEMONIC", + "chain": "algorand", + "network": "mainnet" +} diff --git a/test-helpers/curl/requests/algorand_balances.json b/test-helpers/curl/requests/algorand_balances.json new file mode 100644 index 0000000000..e26df9a027 --- /dev/null +++ b/test-helpers/curl/requests/algorand_balances.json @@ -0,0 +1,8 @@ +{ + "chain": "algorand", + "network": "mainnet", + "address": "$ALGORAND_ADDRESS", + "tokenSymbols": [ + "ALGO" + ] +} \ No newline at end of file diff --git a/test-helpers/curl/requests/algorand_opt_in.json b/test-helpers/curl/requests/algorand_opt_in.json new file mode 100644 index 0000000000..4f2a223feb --- /dev/null +++ b/test-helpers/curl/requests/algorand_opt_in.json @@ -0,0 +1,5 @@ +{ + "network": "testnet", + "address": "$ALGORAND_ADDRESS", + "assetSymbol": "USDC" +} \ No newline at end of file diff --git a/test-helpers/curl/requests/algorand_poll.json b/test-helpers/curl/requests/algorand_poll.json new file mode 100644 index 0000000000..2470220241 --- /dev/null +++ b/test-helpers/curl/requests/algorand_poll.json @@ -0,0 +1,4 @@ +{ + "network": "mainnet", + "txHash": "0xT3ZUYEJ5Y7KEDKITIXO4B5OWU4SBVGOFCPOYGZQHF2XZGENZUBQA" +} \ No newline at end of file diff --git a/test-helpers/curl/requests/algorand_tinyman_trade.json b/test-helpers/curl/requests/algorand_tinyman_trade.json new file mode 100644 index 0000000000..a01879a582 --- /dev/null +++ b/test-helpers/curl/requests/algorand_tinyman_trade.json @@ -0,0 +1,10 @@ +{ + "address": "$ALGORAND_ADDRESS", + "quote": "USDC", + "base": "ALGO", + "amount": "1", + "side": "BUY", + "chain": "algorand", + "network": "mainnet", + "connector": "tinyman" +} diff --git a/test-helpers/curl/requests/network_balances.json b/test-helpers/curl/requests/network_balances.json index 7298b9fb75..8c6c198643 100644 --- a/test-helpers/curl/requests/network_balances.json +++ b/test-helpers/curl/requests/network_balances.json @@ -2,5 +2,7 @@ "chain": "avalanche", "network": "avalanche", "address": "$AVALANCHE_ADDRESS", - "tokenSymbols": ["WAVAX"] + "tokenSymbols": [ + "USDC" + ] } diff --git a/test-helpers/curl/requests/price_tinyman.json b/test-helpers/curl/requests/price_tinyman.json new file mode 100644 index 0000000000..ae61f9ad5c --- /dev/null +++ b/test-helpers/curl/requests/price_tinyman.json @@ -0,0 +1,9 @@ +{ + "connector": "tinyman", + "chain": "algorand", + "network": "mainnet", + "quote": "USDC", + "base": "ALGO", + "amount": "1", + "side": "BUY" +} diff --git a/test-helpers/curl/requests/remove_algorand_key.json b/test-helpers/curl/requests/remove_algorand_key.json new file mode 100644 index 0000000000..8018bfd001 --- /dev/null +++ b/test-helpers/curl/requests/remove_algorand_key.json @@ -0,0 +1,4 @@ +{ + "address": "$ALGORAND_ADDRESS", + "chain": "algorand" +} diff --git a/test/chains/algorand/algorand.routes.test.ts b/test/chains/algorand/algorand.routes.test.ts new file mode 100644 index 0000000000..0b8aef5152 --- /dev/null +++ b/test/chains/algorand/algorand.routes.test.ts @@ -0,0 +1,625 @@ +import request from 'supertest'; +import { gatewayApp } from '../../../src/app'; +import { Algorand } from '../../../src/chains/algorand/algorand'; +import { + patch, + setUpTempDir, + tearDownTempDir, + unpatch, +} from '../../services/patch'; +import { getAlgorandConfig } from '../../../src/chains/algorand/algorand.config'; +import { + NETWORK_ERROR_CODE, + NETWORK_ERROR_MESSAGE, + UNKNOWN_ERROR_ERROR_CODE, +} from '../../../src/services/error-handler'; +import { ConfigManagerCertPassphrase } from '../../../src/services/config-manager-cert-passphrase'; + +let algorand: Algorand; +const EXPECTED_CURRENT_BLOCK_NUMBER = 100; +const CHAIN_NAME = 'algorand'; +const NETWORK = 'testnet'; +const CONFIG = getAlgorandConfig(NETWORK); +const NATIVE_TOKEN = CONFIG.nativeCurrencySymbol; +const NATIVE_TOKEN_ID = 0; +const USDC_TOKEN = 'USDC'; +const USDC_TOKEN_ID = 10458941; +const ACCOUNT_ADDRESS = + 'FJZ4AJ3EWSNV4PXULFTTT4R5PLMNASEIMWEK5H4EY6E67RGJNSEY7OZEMA'; // noqa: mock +const MNEUMONIC = + 'share' + + ' general' + + ' gasp' + + ' trial' + + ' until' + + ' jelly' + + ' mobile' + + ' category' + + ' viable' + + ' meadow' + + ' civil' + + ' pigeon' + + ' dream' + + ' vehicle' + + ' process' + + ' crack' + + ' devote' + + ' outside' + + ' ankle' + + ' mobile' + + ' analyst' + + ' stomach' + + ' dignity' + + ' above' + + ' vast'; // mock +const ALGO_DECIMALS = 6; +const USDC_DECIMALS = 6; + +beforeAll(async () => { + algorand = Algorand.getInstance(NETWORK); + patchGetAssetData(); + patchCurrentBlockNumber(); + await algorand.init(); +}); + +beforeEach(() => { + setUpTempDir('algorand-tests'); + patchCurrentBlockNumber(); + patchCertPassphrase(); +}); + +afterEach(() => { + tearDownTempDir(); + unpatch(); +}); + +const patchCertPassphrase = () => { + patch(ConfigManagerCertPassphrase, 'readPassphrase', () => 'a'); +}; + +const patchCurrentBlockNumber = ( + withError: boolean = false, + instance: Algorand | undefined = undefined, + expectedCurrentBlockNumber: number = EXPECTED_CURRENT_BLOCK_NUMBER +) => { + instance = instance !== undefined ? instance : algorand; + patch(instance.algod, 'status', () => { + return withError + ? {} + : { + do: async () => { + return { 'next-version-round': expectedCurrentBlockNumber }; + }, + }; + }); +}; + +const patchGetAssetData = () => { + patch(algorand, 'getAssetData', async () => { + return [ + { + id: NATIVE_TOKEN_ID.toString(), + is_liquidity_token: false, + name: 'Algorand', + unit_name: NATIVE_TOKEN, + decimals: ALGO_DECIMALS, + total_amount: null, + url: 'https://algorand.org', + is_verified: true, + clawback_address: '', + liquidity_in_usd: '744662.849801994861', + last_day_volume_in_usd: '58.407348762305', + last_week_volume_in_usd: '2261.387003578427', + last_day_price_change: '-0.156310', + is_stable: false, + is_wrapped: false, + }, + { + id: USDC_TOKEN_ID.toString(), + is_liquidity_token: false, + name: 'USDC', + unit_name: USDC_TOKEN, + decimals: USDC_DECIMALS, + total_amount: '18446744073709551615', + url: 'https://centre.io', + is_verified: true, + clawback_address: + 'XM2W7VZODABS6RAL3FENBRKCOF6XLOQZZWIVVZTBYCVH2ADRYKN53CQLXM', + liquidity_in_usd: '210464.272543000000', + last_day_volume_in_usd: '8.000000000000', + last_week_volume_in_usd: '6198.073873000000', + last_day_price_change: '0.000000', + is_stable: false, + is_wrapped: false, + }, + ]; + }); +}; + +describe('GET /network/config', () => { + it('should return 200 and the result dictionary should include the algorand config', async () => { + await request(gatewayApp) + .get(`/network/config`) + .set('Accept', 'application/json') + .expect('Content-Type', /json/) + .expect(200) + .expect((resp) => { + resp.body.alogrand === CONFIG; + }); + }); +}); + +describe('GET /network/status', () => { + it('should return 200 with network info when chain provided', async () => { + await request(gatewayApp) + .get(`/network/status`) + .query({ chain: CHAIN_NAME, network: NETWORK }) + .set('Accept', 'application/json') + .expect('Content-Type', /json/) + .expect(200) + .expect({ + network: NETWORK, + currentBlockNumber: EXPECTED_CURRENT_BLOCK_NUMBER, + nativeCurrency: NATIVE_TOKEN, + }); + }); + + it('should return 200 with a status list, if an instance is already instantiated', async () => { + await request(gatewayApp) + .get(`/network/status`) + .set('Accept', 'application/json') + .expect('Content-Type', /json/) + .expect(200) + .expect([ + { + network: NETWORK, + currentBlockNumber: EXPECTED_CURRENT_BLOCK_NUMBER, + nativeCurrency: NATIVE_TOKEN, + }, + ]); + + const mainnetAlgorandChain = Algorand.getInstance('mainnet'); + const mainnetBlockNumber = EXPECTED_CURRENT_BLOCK_NUMBER + 1; + patchCurrentBlockNumber(false, mainnetAlgorandChain, mainnetBlockNumber); + + await request(gatewayApp) + .get(`/network/status`) + .set('Accept', 'application/json') + .expect('Content-Type', /json/) + .expect(200) + .expect([ + { + network: 'mainnet', + currentBlockNumber: mainnetBlockNumber, + nativeCurrency: NATIVE_TOKEN, + }, + { + network: NETWORK, + currentBlockNumber: EXPECTED_CURRENT_BLOCK_NUMBER, + nativeCurrency: NATIVE_TOKEN, + }, + ]); + }); +}); + +describe('POST /algorand/poll', () => { + const expectedTransactionHash = + '0x2faeb1aa55f96c1db55f643a8cf19b0f76bf091d0b7d1b068d2e829414576362'; // noqa: mock + const expectedTransactionFee = 1000; + const expectedTransactionBlock = 99; + + it('should get a NETWORK_ERROR_CODE when the network is unavailable', async () => { + patch(algorand.algod, 'pendingTransactionInformation', () => { + const error: any = new Error('something went wrong'); + error.code = 'NETWORK_ERROR'; + throw error; + }); + + await request(gatewayApp) + .post('/algorand/poll') + .send({ + network: NETWORK, + txHash: expectedTransactionHash, + }) + .expect(503) + .expect((res) => { + expect(res.body.errorCode).toEqual(NETWORK_ERROR_CODE); + expect(res.body.message).toEqual(NETWORK_ERROR_MESSAGE); + }); + }); + + it('should get a UNKNOWN_ERROR_ERROR_CODE when an unknown error is thrown', async () => { + patch(algorand.algod, 'pendingTransactionInformation', () => { + throw new Error(); + }); + + await request(gatewayApp) + .post('/algorand/poll') + .send({ + network: NETWORK, + txHash: expectedTransactionHash, + }) + .expect(503) + .expect((res) => { + expect(res.body.errorCode).toEqual(UNKNOWN_ERROR_ERROR_CODE); + }); + }); + + it('should return a null txBlock if transaction is still in mempool', async () => { + patch(algorand.algod, 'pendingTransactionInformation', (_: any) => { + return { + do: async () => { + return { + // partial response + txn: { + fee: expectedTransactionFee, + }, + }; + }, + }; + }); + + await request(gatewayApp) + .post('/algorand/poll') + .send({ + network: NETWORK, + txHash: expectedTransactionHash, + }) + .expect(200) + .expect({ + currentBlock: EXPECTED_CURRENT_BLOCK_NUMBER, + txBlock: null, + txHash: expectedTransactionHash, + fee: expectedTransactionFee, + }); + }); + + it('should return a txBlock if transaction is in a block and still on the algod node', async () => { + patch(algorand.algod, 'pendingTransactionInformation', (_: any) => { + return { + do: async () => { + return { + // partial response + 'confirmed-round': expectedTransactionBlock, + txn: { + fee: expectedTransactionFee, + }, + }; + }, + }; + }); + + await request(gatewayApp) + .post('/algorand/poll') + .send({ + network: NETWORK, + txHash: expectedTransactionHash, + }) + .expect(200) + .expect({ + currentBlock: EXPECTED_CURRENT_BLOCK_NUMBER, + txBlock: expectedTransactionBlock, + txHash: expectedTransactionHash, + fee: expectedTransactionFee, + }); + }); + + it('should return a txBlock if transaction is in a block and no longer on the algod node', async () => { + patch(algorand.algod, 'pendingTransactionInformation', (_: any) => { + const error: any = new Error('something went wrong'); + error.message = + 'could not find the transaction in the transaction pool or in the last 1000 confirmed rounds'; + error.status = 404; + throw error; + }); + + patch(algorand.indexer, 'lookupTransactionByID', (_: any) => { + return { + do: async () => { + return { + // partial response + 'current-round': EXPECTED_CURRENT_BLOCK_NUMBER, + transaction: { + 'confirmed-round': expectedTransactionBlock, + fee: expectedTransactionFee, + }, + }; + }, + }; + }); + + await request(gatewayApp) + .post('/algorand/poll') + .send({ + network: NETWORK, + txHash: expectedTransactionHash, + }) + .expect(200) + .expect({ + currentBlock: EXPECTED_CURRENT_BLOCK_NUMBER, + txBlock: expectedTransactionBlock, + txHash: expectedTransactionHash, + fee: expectedTransactionFee, + }); + }); +}); + +describe('test managing Algorand wallets', () => { + test('adding and removing a wallet', async () => { + await request(gatewayApp) + .get('/wallet') + .expect('Content-Type', /json/) + .expect(200) + .expect([]); + + await request(gatewayApp) + .post('/wallet/add') + .send({ + chain: CHAIN_NAME, + network: NETWORK, + privateKey: MNEUMONIC, + }) + .expect(200) + .expect({ + address: ACCOUNT_ADDRESS, + }); + + await request(gatewayApp) + .get('/wallet') + .expect('Content-Type', /json/) + .expect(200) + .expect([ + { + chain: CHAIN_NAME, + walletAddresses: [ACCOUNT_ADDRESS], + }, + ]); + + await request(gatewayApp) + .delete('/wallet/remove') + .send({ + chain: CHAIN_NAME, + address: ACCOUNT_ADDRESS, + }) + .expect(200); + + await request(gatewayApp) + .get('/wallet') + .expect('Content-Type', /json/) + .expect(200) + .expect([ + { + chain: CHAIN_NAME, + walletAddresses: [], + }, + ]); + }); +}); + +describe('POST /algorand/balances', () => { + const expectedBalance = '9'; + + it('should return 200 with correct balance for native token', async () => { + patch(algorand.algod, 'accountInformation', (_: any) => { + return { + do: async () => { + return { + amount: + parseFloat(expectedBalance) * parseFloat(`1e${ALGO_DECIMALS}`), + }; + }, + }; + }); + + await request(gatewayApp).post('/wallet/add').send({ + chain: CHAIN_NAME, + network: NETWORK, + privateKey: MNEUMONIC, + }); + + await request(gatewayApp) + .post(`/algorand/balances`) + .send({ + chain: CHAIN_NAME, + network: NETWORK, + address: ACCOUNT_ADDRESS, + tokenSymbols: [NATIVE_TOKEN], + }) + .set('Accept', 'application/json') + .expect('Content-Type', /json/) + .expect(200) + .expect((resp) => { + expect(resp.body).toHaveProperty('timestamp'); + expect(resp.body).toHaveProperty('latency'); + expect(resp.body.network).toEqual(NETWORK); + expect(resp.body.balances[NATIVE_TOKEN]).toEqual(expectedBalance); + }); + }); + + it('should return 200 with correct balance for non-native token', async () => { + patch(algorand.algod, 'accountAssetInformation', (_: any, __: any) => { + return { + do: async () => { + return { + 'asset-holding': { + amount: Math.round( + parseFloat(expectedBalance) * parseFloat(`1e${USDC_DECIMALS}`) + ), + }, + }; + }, + }; + }); + + await request(gatewayApp).post('/wallet/add').send({ + chain: CHAIN_NAME, + network: NETWORK, + privateKey: MNEUMONIC, + }); + + await request(gatewayApp) + .post(`/algorand/balances`) + .send({ + chain: CHAIN_NAME, + network: NETWORK, + address: ACCOUNT_ADDRESS, + tokenSymbols: [USDC_TOKEN], + }) + .set('Accept', 'application/json') + .expect('Content-Type', /json/) + .expect(200) + .expect((resp) => { + expect(resp.body).toHaveProperty('timestamp'); + expect(resp.body).toHaveProperty('latency'); + expect(resp.body.network).toEqual(NETWORK); + expect(resp.body.balances).toEqual({ USDC: expectedBalance }); + }); + }); + + it('should return 200 with zero balance', async () => { + patch(algorand.algod, 'accountAssetInformation', (_: any, __: any) => { + const error: any = new Error('account asset info not found'); + error.code = 404; + throw error; + }); + + await request(gatewayApp).post('/wallet/add').send({ + chain: CHAIN_NAME, + network: NETWORK, + privateKey: MNEUMONIC, + }); + + await request(gatewayApp) + .post(`/algorand/balances`) + .send({ + chain: CHAIN_NAME, + network: NETWORK, + address: ACCOUNT_ADDRESS, + tokenSymbols: [USDC_TOKEN], + }) + .set('Accept', 'application/json') + .expect('Content-Type', /json/) + .expect(200) + .expect((resp) => { + expect(resp.body).toHaveProperty('timestamp'); + expect(resp.body).toHaveProperty('latency'); + expect(resp.body.network).toEqual(NETWORK); + expect(resp.body.balances).toEqual({ USDC: '0' }); + }); + }); + + it('should return 404 when parameters are invalid/incomplete', async () => { + await request(gatewayApp) + .post(`/algorand/balances`) + .send({ + chain: CHAIN_NAME, + network: NETWORK, + }) + .expect(404); + }); +}); + +describe('GET /algorand/assets', () => { + it('should return 200 with all assets if assetSymbols not provided', async () => { + await request(gatewayApp) + .get(`/algorand/assets`) + .query({ + network: NETWORK, + }) + .expect('Content-Type', /json/) + .expect(200) + .expect((resp) => { + expect(resp.body).toEqual({ + assets: [ + { + symbol: NATIVE_TOKEN, + assetId: NATIVE_TOKEN_ID, + decimals: ALGO_DECIMALS, + }, + { + symbol: USDC_TOKEN, + assetId: USDC_TOKEN_ID, + decimals: USDC_DECIMALS, + }, + ], + }); + }); + }); + + it('should return 200 with the requested asset', async () => { + await request(gatewayApp) + .get(`/algorand/assets`) + .query({ + network: NETWORK, + assetSymbols: [USDC_TOKEN], + }) + .expect('Content-Type', /json/) + .expect(200) + .expect((resp) => { + expect(resp.body).toEqual({ + assets: [ + { + symbol: USDC_TOKEN, + assetId: USDC_TOKEN_ID, + decimals: USDC_DECIMALS, + }, + ], + }); + }); + }); +}); + +describe('POST /algorand/opt-in', () => { + it('should return 200 with the opt-in response', async () => { + const expectedTransactionId = + 'RVZ24ML6UE3OFXFN5ID3L65EHSRAYYX3FCCTKQP3P3P5K73Y65CQ'; + + patch(algorand.algod, 'getTransactionParams', () => { + return { + do: async () => { + return { + fee: 0, + firstRound: 29228608, + flatFee: false, + genesisHash: 'SGO1GKSzyE7IEPItTxCByw9x8FmnrCDexi9/cOUJOiI=', + genesisID: 'testnet-v1.0', + lastRound: 29229608, + }; + }, + }; + }); + + patch(algorand.algod, 'sendRawTransaction', (_: Uint8Array) => { + return { + do: async () => { + return { + txId: expectedTransactionId, + }; + }, + }; + }); + + await request(gatewayApp).post('/wallet/add').send({ + chain: CHAIN_NAME, + network: NETWORK, + privateKey: MNEUMONIC, + }); + + await request(gatewayApp) + .post('/algorand/opt-in') + .send({ + network: NETWORK, + address: ACCOUNT_ADDRESS, + assetSymbol: USDC_TOKEN, + }) + .expect('Content-Type', /json/) + .expect(200) + .expect((resp) => { + expect(resp.body.network).toEqual(NETWORK); + expect(resp.body.assetId).toEqual(USDC_TOKEN_ID); + expect(resp.body.transactionResponse).toEqual({ + txId: expectedTransactionId, + }); + }); + }); +}); diff --git a/test/connectors/tinyman/tinyman.test.ts b/test/connectors/tinyman/tinyman.test.ts new file mode 100644 index 0000000000..0c85d06c5b --- /dev/null +++ b/test/connectors/tinyman/tinyman.test.ts @@ -0,0 +1,279 @@ +jest.useFakeTimers(); +import { Tinyman } from '../../../src/connectors/tinyman/tinyman'; +import { patch, unpatch } from '../../services/patch'; +import { Algorand } from '../../../src/chains/algorand/algorand'; +import { poolUtils, SwapQuoteType, } from '@tinymanorg/tinyman-js-sdk'; +import { getAlgorandConfig } from '../../../src/chains/algorand/algorand.config'; + +let algorand: Algorand; +let tm: Tinyman; +const EXPECTED_CURRENT_BLOCK_NUMBER = 100; +const CHAIN_NAME = 'algorand'; +const NETWORK = 'testnet'; +const CONFIG = getAlgorandConfig(NETWORK); +const NATIVE_TOKEN = CONFIG.nativeCurrencySymbol; +const NATIVE_TOKEN_ID = 0; +const USDC_TOKEN = 'USDC'; +const USDC_TOKEN_ID = 10458941; +const TX = { + txnID: 1234, + round: 1, + quote: {}, + assetOut: undefined, +}; +const MNEUMONIC = + 'share' + + ' general' + + ' gasp' + + ' trial' + + ' until' + + ' jelly' + + ' mobile' + + ' category' + + ' viable' + + ' meadow' + + ' civil' + + ' pigeon' + + ' dream' + + ' vehicle' + + ' process' + + ' crack' + + ' devote' + + ' outside' + + ' ankle' + + ' mobile' + + ' analyst' + + ' stomach' + + ' dignity' + + ' above' + + ' vast'; // mock +const ALGO_DECIMALS = 6; +const USDC_DECIMALS = 6; + +export const patchCurrentBlockNumber = ( + withError: boolean = false, + instance: Algorand | undefined = undefined, + expectedCurrentBlockNumber: number = EXPECTED_CURRENT_BLOCK_NUMBER +) => { + instance = instance !== undefined ? instance : algorand; + patch(instance.algod, 'status', () => { + return withError + ? {} + : { + do: async () => { + return { 'next-version-round': expectedCurrentBlockNumber }; + }, + }; + }); +}; + +export const patchGetAssetData = () => { + patch(algorand, 'getAssetData', async () => { + return [ + { + id: NATIVE_TOKEN_ID.toString(), + is_liquidity_token: false, + name: 'Algorand', + unit_name: NATIVE_TOKEN, + decimals: ALGO_DECIMALS, + total_amount: null, + url: 'https://algorand.org', + is_verified: true, + clawback_address: '', + liquidity_in_usd: '744662.849801994861', + last_day_volume_in_usd: '58.407348762305', + last_week_volume_in_usd: '2261.387003578427', + last_day_price_change: '-0.156310', + is_stable: false, + is_wrapped: false, + }, + { + id: USDC_TOKEN_ID.toString(), + is_liquidity_token: false, + name: 'USDC', + unit_name: USDC_TOKEN, + decimals: USDC_DECIMALS, + total_amount: '18446744073709551615', + url: 'https://centre.io', + is_verified: true, + clawback_address: + 'XM2W7VZODABS6RAL3FENBRKCOF6XLOQZZWIVVZTBYCVH2ADRYKN53CQLXM', + liquidity_in_usd: '210464.272543000000', + last_day_volume_in_usd: '8.000000000000', + last_week_volume_in_usd: '6198.073873000000', + last_day_price_change: '0.000000', + is_stable: false, + is_wrapped: false, + }, + ]; + }); +}; + +beforeAll(async () => { + algorand = Algorand.getInstance(NETWORK); + patchCurrentBlockNumber(); + patchGetAssetData(); + await algorand.init(); + + tm = Tinyman.getInstance(NETWORK); + await tm.init(); +}); + +afterEach(() => { + unpatch(); +}); + +afterAll(async () => { + await algorand.close(); +}); + +const patchSwap = () => { + patch(tm.swap, 'v2', { + getQuote() { + return { type: SwapQuoteType.Direct, data: { quote: { rate: 1 } } }; + }, + generateTxns() { + return []; + }, + signTxns() { + return; + }, + async execute() { + return TX; + }, + }); +}; + +const patchFetcher = () => { + patch(poolUtils.v2, 'getPoolInfo', () => { + return { + account: { + lsig: { + tag: new Uint8Array([80, 114, 111, 103, 114, 97, 109]), + logic: new Uint8Array([ + 6, 128, 24, 0, 0, 0, 0, 59, 193, 147, 29, 0, 0, 0, 0, 1, 225, 171, + 112, 0, 0, 0, 0, 0, 0, 0, 0, 129, 0, 91, 53, 0, 52, 0, 49, 24, 18, + 68, 49, 25, 129, 1, 18, 68, 129, 1, 67, + ]), + args: undefined, + sig: undefined, + msig: undefined, + }, + sigkey: undefined, + }, + validatorAppID: 1002541853, + asset1ID: 31566704, + asset2ID: 0, + status: 'ready', + contractVersion: 'v2', + asset1ProtocolFees: BigInt('10961420982'), + asset2ProtocolFees: BigInt('48196942141'), + asset1Reserves: BigInt('1200097723737'), + asset2Reserves: BigInt('6633822022882'), + issuedPoolTokens: BigInt('2690871970933'), + cumulativePriceUpdateTimeStamp: 1682547803, + protocolFeeRatio: 6, + totalFeeShare: BigInt('30'), + poolTokenID: 1002590888, + }; + }); +}; + +describe('verify Tinyman estimate Sell Trade', () => { + it('Should return an ExpectedTrade when available', async () => { + patchFetcher(); + + const expectedTrade = await tm.estimateTrade({ + chain: CHAIN_NAME, + network: NETWORK, + base: 'ALGO', + quote: 'USDC', + amount: '1', + side: 'SELL', + }); + expect(expectedTrade).toHaveProperty('trade'); + expect(expectedTrade).toHaveProperty('expectedAmount'); + expect(expectedTrade.expectedAmount).toEqual(0.180363); + expect(expectedTrade.expectedPrice).toEqual(0.180363); + }); + + it('Should throw an error if no pair is available', async () => { + patchFetcher(); + + await expect(async () => { + await tm.estimateTrade({ + chain: CHAIN_NAME, + network: NETWORK, + base: 'ETH', + quote: 'DAI', + amount: '1', + side: 'SELL', + }); + }).rejects.toThrow(''); + }); +}); + +describe('verify Tinyman estimate Buy Trade', () => { + it('Should return an ExpectedTrade when available', async () => { + patchFetcher(); + + const expectedTrade = await tm.estimateTrade({ + chain: CHAIN_NAME, + network: NETWORK, + base: 'ALGO', + quote: 'USDC', + amount: '1', + side: 'BUY', + }); + expect(expectedTrade).toHaveProperty('trade'); + expect(expectedTrade).toHaveProperty('expectedAmount'); + expect(expectedTrade.expectedAmount).toEqual(1); + expect(expectedTrade.expectedPrice).toEqual(0.18145); + }); + + it('Should return an error if no pair is available', async () => { + patchFetcher(); + + await expect(async () => { + await tm.estimateTrade({ + chain: CHAIN_NAME, + network: NETWORK, + base: 'ETH', + quote: 'DAI', + amount: '1', + side: 'BUY', + }); + }).rejects.toThrow(''); + }); +}); + +describe('getAllowedSlippage', () => { + it('return value from config when string is null', () => { + const allowedSlippage = tm.getSlippage(); + expect(allowedSlippage).toEqual(0.02); + }); +}); + +describe('verify Tinyman executeTrade', () => { + it('Should pass when pair is available', async () => { + patchFetcher(); + patchSwap(); + + const trade = await tm.estimateTrade({ + chain: CHAIN_NAME, + network: NETWORK, + base: 'ALGO', + quote: 'USDC', + amount: '1', + side: 'BUY', + }); + + const tradeResult = await tm.executeTrade( + algorand.getAccountFromPrivateKey(MNEUMONIC), + trade.trade, + true + ); + expect(tradeResult.txnID).toEqual(TX.txnID); + expect(tradeResult.round).toEqual(TX.round); + }); +}); diff --git a/test/services/patch.ts b/test/services/patch.ts index c338779f2f..0d96a6aaa7 100644 --- a/test/services/patch.ts +++ b/test/services/patch.ts @@ -1,3 +1,7 @@ +import path from 'path'; +import fs from 'fs'; +import os from 'os'; + let patchedObjects: Set = new Set(); export const classHasGetter = (obj: any, prop: string): boolean => { @@ -78,3 +82,25 @@ export const unpatch = (): void => { }); patchedObjects = new Set(); }; + +let currDir: string | null = null; +let tempDir: string; + +export function setUpTempDir(dirPrefix: string = ''): string { + if (currDir !== null) { + throw new Error('Temp dir already set up'); + } + currDir = process.cwd(); + tempDir = fs.mkdtempSync(path.join(os.tmpdir(), dirPrefix)); + process.chdir(tempDir); + return tempDir; +} + +export function tearDownTempDir(): void { + if (currDir === null) { + throw new Error('Temp dir not set up'); + } + process.chdir(currDir as string); + fs.rmSync(tempDir, { recursive: true }); + currDir = null; +} diff --git a/yarn.lock b/yarn.lock index 225c583871..f66a7c8aca 100644 --- a/yarn.lock +++ b/yarn.lock @@ -982,137 +982,137 @@ "@ethersproject-xdc/abi@file:vendor/@ethersproject-xdc/abi": version "5.7.0" dependencies: - "@ethersproject-xdc/address" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-abi-5.7.0-a3be5780-b0a1-49ed-99fd-192d5cbd2bd7-1682382909340/node_modules/@ethersproject-xdc/address" - "@ethersproject-xdc/bignumber" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-abi-5.7.0-a3be5780-b0a1-49ed-99fd-192d5cbd2bd7-1682382909340/node_modules/@ethersproject-xdc/bignumber" - "@ethersproject-xdc/bytes" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-abi-5.7.0-a3be5780-b0a1-49ed-99fd-192d5cbd2bd7-1682382909340/node_modules/@ethersproject-xdc/bytes" - "@ethersproject-xdc/constants" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-abi-5.7.0-a3be5780-b0a1-49ed-99fd-192d5cbd2bd7-1682382909340/node_modules/@ethersproject-xdc/constants" - "@ethersproject-xdc/hash" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-abi-5.7.0-a3be5780-b0a1-49ed-99fd-192d5cbd2bd7-1682382909340/node_modules/@ethersproject-xdc/hash" - "@ethersproject-xdc/keccak256" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-abi-5.7.0-a3be5780-b0a1-49ed-99fd-192d5cbd2bd7-1682382909340/node_modules/@ethersproject-xdc/keccak256" - "@ethersproject-xdc/logger" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-abi-5.7.0-a3be5780-b0a1-49ed-99fd-192d5cbd2bd7-1682382909340/node_modules/@ethersproject-xdc/logger" - "@ethersproject-xdc/properties" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-abi-5.7.0-a3be5780-b0a1-49ed-99fd-192d5cbd2bd7-1682382909340/node_modules/@ethersproject-xdc/properties" - "@ethersproject-xdc/strings" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-abi-5.7.0-a3be5780-b0a1-49ed-99fd-192d5cbd2bd7-1682382909340/node_modules/@ethersproject-xdc/strings" + "@ethersproject-xdc/address" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-abi-5.7.0-3e29bda7-47b6-4217-b452-147669088157-1683016746640/node_modules/@ethersproject-xdc/address" + "@ethersproject-xdc/bignumber" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-abi-5.7.0-3e29bda7-47b6-4217-b452-147669088157-1683016746640/node_modules/@ethersproject-xdc/bignumber" + "@ethersproject-xdc/bytes" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-abi-5.7.0-3e29bda7-47b6-4217-b452-147669088157-1683016746640/node_modules/@ethersproject-xdc/bytes" + "@ethersproject-xdc/constants" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-abi-5.7.0-3e29bda7-47b6-4217-b452-147669088157-1683016746640/node_modules/@ethersproject-xdc/constants" + "@ethersproject-xdc/hash" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-abi-5.7.0-3e29bda7-47b6-4217-b452-147669088157-1683016746640/node_modules/@ethersproject-xdc/hash" + "@ethersproject-xdc/keccak256" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-abi-5.7.0-3e29bda7-47b6-4217-b452-147669088157-1683016746640/node_modules/@ethersproject-xdc/keccak256" + "@ethersproject-xdc/logger" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-abi-5.7.0-3e29bda7-47b6-4217-b452-147669088157-1683016746640/node_modules/@ethersproject-xdc/logger" + "@ethersproject-xdc/properties" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-abi-5.7.0-3e29bda7-47b6-4217-b452-147669088157-1683016746640/node_modules/@ethersproject-xdc/properties" + "@ethersproject-xdc/strings" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-abi-5.7.0-3e29bda7-47b6-4217-b452-147669088157-1683016746640/node_modules/@ethersproject-xdc/strings" "@ethersproject-xdc/abstract-provider@file:vendor/@ethersproject-xdc/abstract-provider": version "5.7.0" dependencies: - "@ethersproject-xdc/bignumber" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-abstract-provider-5.7.0-d125aa93-cf3f-42d5-aaf1-16fb2072c002-1682382909339/node_modules/@ethersproject-xdc/bignumber" - "@ethersproject-xdc/bytes" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-abstract-provider-5.7.0-d125aa93-cf3f-42d5-aaf1-16fb2072c002-1682382909339/node_modules/@ethersproject-xdc/bytes" - "@ethersproject-xdc/logger" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-abstract-provider-5.7.0-d125aa93-cf3f-42d5-aaf1-16fb2072c002-1682382909339/node_modules/@ethersproject-xdc/logger" - "@ethersproject-xdc/networks" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-abstract-provider-5.7.0-d125aa93-cf3f-42d5-aaf1-16fb2072c002-1682382909339/node_modules/@ethersproject-xdc/networks" - "@ethersproject-xdc/properties" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-abstract-provider-5.7.0-d125aa93-cf3f-42d5-aaf1-16fb2072c002-1682382909339/node_modules/@ethersproject-xdc/properties" - "@ethersproject-xdc/transactions" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-abstract-provider-5.7.0-d125aa93-cf3f-42d5-aaf1-16fb2072c002-1682382909339/node_modules/@ethersproject-xdc/transactions" - "@ethersproject-xdc/web" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-abstract-provider-5.7.0-d125aa93-cf3f-42d5-aaf1-16fb2072c002-1682382909339/node_modules/@ethersproject-xdc/web" + "@ethersproject-xdc/bignumber" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-abstract-provider-5.7.0-f0c569d0-9df8-46e7-823e-ed1f83869d57-1683016746639/node_modules/@ethersproject-xdc/bignumber" + "@ethersproject-xdc/bytes" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-abstract-provider-5.7.0-f0c569d0-9df8-46e7-823e-ed1f83869d57-1683016746639/node_modules/@ethersproject-xdc/bytes" + "@ethersproject-xdc/logger" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-abstract-provider-5.7.0-f0c569d0-9df8-46e7-823e-ed1f83869d57-1683016746639/node_modules/@ethersproject-xdc/logger" + "@ethersproject-xdc/networks" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-abstract-provider-5.7.0-f0c569d0-9df8-46e7-823e-ed1f83869d57-1683016746639/node_modules/@ethersproject-xdc/networks" + "@ethersproject-xdc/properties" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-abstract-provider-5.7.0-f0c569d0-9df8-46e7-823e-ed1f83869d57-1683016746639/node_modules/@ethersproject-xdc/properties" + "@ethersproject-xdc/transactions" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-abstract-provider-5.7.0-f0c569d0-9df8-46e7-823e-ed1f83869d57-1683016746639/node_modules/@ethersproject-xdc/transactions" + "@ethersproject-xdc/web" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-abstract-provider-5.7.0-f0c569d0-9df8-46e7-823e-ed1f83869d57-1683016746639/node_modules/@ethersproject-xdc/web" "@ethersproject-xdc/abstract-signer@file:vendor/@ethersproject-xdc/abstract-signer": version "5.7.0" dependencies: - "@ethersproject-xdc/abstract-provider" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-abstract-signer-5.7.0-86225265-c299-4a69-b5fd-fd2cbabe45af-1682382909341/node_modules/@ethersproject-xdc/abstract-provider" - "@ethersproject-xdc/bignumber" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-abstract-signer-5.7.0-86225265-c299-4a69-b5fd-fd2cbabe45af-1682382909341/node_modules/@ethersproject-xdc/bignumber" - "@ethersproject-xdc/bytes" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-abstract-signer-5.7.0-86225265-c299-4a69-b5fd-fd2cbabe45af-1682382909341/node_modules/@ethersproject-xdc/bytes" - "@ethersproject-xdc/logger" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-abstract-signer-5.7.0-86225265-c299-4a69-b5fd-fd2cbabe45af-1682382909341/node_modules/@ethersproject-xdc/logger" - "@ethersproject-xdc/properties" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-abstract-signer-5.7.0-86225265-c299-4a69-b5fd-fd2cbabe45af-1682382909341/node_modules/@ethersproject-xdc/properties" + "@ethersproject-xdc/abstract-provider" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-abstract-signer-5.7.0-614824b0-8374-44c7-8cdd-0874f626c97a-1683016746638/node_modules/@ethersproject-xdc/abstract-provider" + "@ethersproject-xdc/bignumber" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-abstract-signer-5.7.0-614824b0-8374-44c7-8cdd-0874f626c97a-1683016746638/node_modules/@ethersproject-xdc/bignumber" + "@ethersproject-xdc/bytes" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-abstract-signer-5.7.0-614824b0-8374-44c7-8cdd-0874f626c97a-1683016746638/node_modules/@ethersproject-xdc/bytes" + "@ethersproject-xdc/logger" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-abstract-signer-5.7.0-614824b0-8374-44c7-8cdd-0874f626c97a-1683016746638/node_modules/@ethersproject-xdc/logger" + "@ethersproject-xdc/properties" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-abstract-signer-5.7.0-614824b0-8374-44c7-8cdd-0874f626c97a-1683016746638/node_modules/@ethersproject-xdc/properties" "@ethersproject-xdc/address@file:vendor/@ethersproject-xdc/address": version "5.7.0" dependencies: - "@ethersproject-xdc/bignumber" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-address-5.7.0-3a609e4d-98a2-4c96-94ed-9a9b93943e81-1682382909338/node_modules/@ethersproject-xdc/bignumber" - "@ethersproject-xdc/bytes" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-address-5.7.0-3a609e4d-98a2-4c96-94ed-9a9b93943e81-1682382909338/node_modules/@ethersproject-xdc/bytes" - "@ethersproject-xdc/keccak256" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-address-5.7.0-3a609e4d-98a2-4c96-94ed-9a9b93943e81-1682382909338/node_modules/@ethersproject-xdc/keccak256" - "@ethersproject-xdc/logger" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-address-5.7.0-3a609e4d-98a2-4c96-94ed-9a9b93943e81-1682382909338/node_modules/@ethersproject-xdc/logger" - "@ethersproject-xdc/rlp" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-address-5.7.0-3a609e4d-98a2-4c96-94ed-9a9b93943e81-1682382909338/node_modules/@ethersproject-xdc/rlp" + "@ethersproject-xdc/bignumber" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-address-5.7.0-6d9e6e4c-7b37-4000-b386-e56150d4f442-1683016746638/node_modules/@ethersproject-xdc/bignumber" + "@ethersproject-xdc/bytes" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-address-5.7.0-6d9e6e4c-7b37-4000-b386-e56150d4f442-1683016746638/node_modules/@ethersproject-xdc/bytes" + "@ethersproject-xdc/keccak256" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-address-5.7.0-6d9e6e4c-7b37-4000-b386-e56150d4f442-1683016746638/node_modules/@ethersproject-xdc/keccak256" + "@ethersproject-xdc/logger" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-address-5.7.0-6d9e6e4c-7b37-4000-b386-e56150d4f442-1683016746638/node_modules/@ethersproject-xdc/logger" + "@ethersproject-xdc/rlp" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-address-5.7.0-6d9e6e4c-7b37-4000-b386-e56150d4f442-1683016746638/node_modules/@ethersproject-xdc/rlp" "@ethersproject-xdc/base64@file:vendor/@ethersproject-xdc/base64": version "5.7.0" dependencies: - "@ethersproject-xdc/bytes" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-base64-5.7.0-6dab380d-3dfe-4955-a438-4ea14634d9e6-1682382909338/node_modules/@ethersproject-xdc/bytes" + "@ethersproject-xdc/bytes" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-base64-5.7.0-f2055c04-1b90-48f4-9be7-13d79393f846-1683016746638/node_modules/@ethersproject-xdc/bytes" "@ethersproject-xdc/basex@file:vendor/@ethersproject-xdc/basex": version "5.7.0" dependencies: - "@ethersproject-xdc/bytes" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-basex-5.7.0-5288ba86-0fbc-4760-85d0-2b47725b4b7e-1682382909339/node_modules/@ethersproject-xdc/bytes" - "@ethersproject-xdc/properties" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-basex-5.7.0-5288ba86-0fbc-4760-85d0-2b47725b4b7e-1682382909339/node_modules/@ethersproject-xdc/properties" + "@ethersproject-xdc/bytes" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-basex-5.7.0-e6606340-411f-4cc3-a9c1-a6752ed5ca66-1683016746639/node_modules/@ethersproject-xdc/bytes" + "@ethersproject-xdc/properties" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-basex-5.7.0-e6606340-411f-4cc3-a9c1-a6752ed5ca66-1683016746639/node_modules/@ethersproject-xdc/properties" "@ethersproject-xdc/bignumber@file:vendor/@ethersproject-xdc/bignumber": version "5.7.0" dependencies: - "@ethersproject-xdc/bytes" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-bignumber-5.7.0-41cc9d74-27fd-4d64-aee5-4080c2c51e79-1682382909345/node_modules/@ethersproject-xdc/bytes" - "@ethersproject-xdc/logger" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-bignumber-5.7.0-41cc9d74-27fd-4d64-aee5-4080c2c51e79-1682382909345/node_modules/@ethersproject-xdc/logger" + "@ethersproject-xdc/bytes" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-bignumber-5.7.0-dcdfb6a9-ec6f-4b39-9f68-6c9bbc8b429b-1683016746642/node_modules/@ethersproject-xdc/bytes" + "@ethersproject-xdc/logger" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-bignumber-5.7.0-dcdfb6a9-ec6f-4b39-9f68-6c9bbc8b429b-1683016746642/node_modules/@ethersproject-xdc/logger" bn.js "^5.2.1" "@ethersproject-xdc/bytes@file:vendor/@ethersproject-xdc/bytes": version "5.7.0" dependencies: - "@ethersproject-xdc/logger" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-bytes-5.7.0-6b385371-4029-4e5b-bdc0-87a8f6612520-1682382909340/node_modules/@ethersproject-xdc/logger" + "@ethersproject-xdc/logger" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-bytes-5.7.0-46e8ffa4-dc47-4d8c-9b2c-2516452c620f-1683016746639/node_modules/@ethersproject-xdc/logger" "@ethersproject-xdc/constants@file:vendor/@ethersproject-xdc/constants": version "5.7.0" dependencies: - "@ethersproject-xdc/bignumber" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-constants-5.7.0-0ca962bc-c2c2-42b6-a085-cd7402c249a8-1682382909339/node_modules/@ethersproject-xdc/bignumber" + "@ethersproject-xdc/bignumber" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-constants-5.7.0-4b00a952-8ee5-4651-870f-0f13a46bb24f-1683016746644/node_modules/@ethersproject-xdc/bignumber" "@ethersproject-xdc/contracts@file:vendor/@ethersproject-xdc/contracts": version "5.6.0" dependencies: - "@ethersproject-xdc/abi" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-contracts-5.6.0-04b9daca-b5f0-4127-a97d-f07a37869b3f-1682382909339/node_modules/@ethersproject-xdc/abi" - "@ethersproject-xdc/abstract-provider" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-contracts-5.6.0-04b9daca-b5f0-4127-a97d-f07a37869b3f-1682382909339/node_modules/@ethersproject-xdc/abstract-provider" - "@ethersproject-xdc/abstract-signer" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-contracts-5.6.0-04b9daca-b5f0-4127-a97d-f07a37869b3f-1682382909339/node_modules/@ethersproject-xdc/abstract-signer" - "@ethersproject-xdc/address" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-contracts-5.6.0-04b9daca-b5f0-4127-a97d-f07a37869b3f-1682382909339/node_modules/@ethersproject-xdc/address" - "@ethersproject-xdc/bignumber" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-contracts-5.6.0-04b9daca-b5f0-4127-a97d-f07a37869b3f-1682382909339/node_modules/@ethersproject-xdc/bignumber" - "@ethersproject-xdc/bytes" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-contracts-5.6.0-04b9daca-b5f0-4127-a97d-f07a37869b3f-1682382909339/node_modules/@ethersproject-xdc/bytes" - "@ethersproject-xdc/constants" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-contracts-5.6.0-04b9daca-b5f0-4127-a97d-f07a37869b3f-1682382909339/node_modules/@ethersproject-xdc/constants" - "@ethersproject-xdc/logger" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-contracts-5.6.0-04b9daca-b5f0-4127-a97d-f07a37869b3f-1682382909339/node_modules/@ethersproject-xdc/logger" - "@ethersproject-xdc/properties" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-contracts-5.6.0-04b9daca-b5f0-4127-a97d-f07a37869b3f-1682382909339/node_modules/@ethersproject-xdc/properties" - "@ethersproject-xdc/transactions" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-contracts-5.6.0-04b9daca-b5f0-4127-a97d-f07a37869b3f-1682382909339/node_modules/@ethersproject-xdc/transactions" + "@ethersproject-xdc/abi" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-contracts-5.6.0-207d5f8d-7ddc-442e-97b3-b659c5de792f-1683016746640/node_modules/@ethersproject-xdc/abi" + "@ethersproject-xdc/abstract-provider" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-contracts-5.6.0-207d5f8d-7ddc-442e-97b3-b659c5de792f-1683016746640/node_modules/@ethersproject-xdc/abstract-provider" + "@ethersproject-xdc/abstract-signer" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-contracts-5.6.0-207d5f8d-7ddc-442e-97b3-b659c5de792f-1683016746640/node_modules/@ethersproject-xdc/abstract-signer" + "@ethersproject-xdc/address" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-contracts-5.6.0-207d5f8d-7ddc-442e-97b3-b659c5de792f-1683016746640/node_modules/@ethersproject-xdc/address" + "@ethersproject-xdc/bignumber" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-contracts-5.6.0-207d5f8d-7ddc-442e-97b3-b659c5de792f-1683016746640/node_modules/@ethersproject-xdc/bignumber" + "@ethersproject-xdc/bytes" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-contracts-5.6.0-207d5f8d-7ddc-442e-97b3-b659c5de792f-1683016746640/node_modules/@ethersproject-xdc/bytes" + "@ethersproject-xdc/constants" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-contracts-5.6.0-207d5f8d-7ddc-442e-97b3-b659c5de792f-1683016746640/node_modules/@ethersproject-xdc/constants" + "@ethersproject-xdc/logger" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-contracts-5.6.0-207d5f8d-7ddc-442e-97b3-b659c5de792f-1683016746640/node_modules/@ethersproject-xdc/logger" + "@ethersproject-xdc/properties" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-contracts-5.6.0-207d5f8d-7ddc-442e-97b3-b659c5de792f-1683016746640/node_modules/@ethersproject-xdc/properties" + "@ethersproject-xdc/transactions" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-contracts-5.6.0-207d5f8d-7ddc-442e-97b3-b659c5de792f-1683016746640/node_modules/@ethersproject-xdc/transactions" "@ethersproject-xdc/hash@file:vendor/@ethersproject-xdc/hash": version "5.7.0" dependencies: - "@ethersproject-xdc/abstract-signer" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-hash-5.7.0-9b16a632-0d7e-4eaa-9ec6-44acc4468bd1-1682382909344/node_modules/@ethersproject-xdc/abstract-signer" - "@ethersproject-xdc/address" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-hash-5.7.0-9b16a632-0d7e-4eaa-9ec6-44acc4468bd1-1682382909344/node_modules/@ethersproject-xdc/address" - "@ethersproject-xdc/base64" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-hash-5.7.0-9b16a632-0d7e-4eaa-9ec6-44acc4468bd1-1682382909344/node_modules/@ethersproject-xdc/base64" - "@ethersproject-xdc/bignumber" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-hash-5.7.0-9b16a632-0d7e-4eaa-9ec6-44acc4468bd1-1682382909344/node_modules/@ethersproject-xdc/bignumber" - "@ethersproject-xdc/bytes" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-hash-5.7.0-9b16a632-0d7e-4eaa-9ec6-44acc4468bd1-1682382909344/node_modules/@ethersproject-xdc/bytes" - "@ethersproject-xdc/keccak256" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-hash-5.7.0-9b16a632-0d7e-4eaa-9ec6-44acc4468bd1-1682382909344/node_modules/@ethersproject-xdc/keccak256" - "@ethersproject-xdc/logger" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-hash-5.7.0-9b16a632-0d7e-4eaa-9ec6-44acc4468bd1-1682382909344/node_modules/@ethersproject-xdc/logger" - "@ethersproject-xdc/properties" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-hash-5.7.0-9b16a632-0d7e-4eaa-9ec6-44acc4468bd1-1682382909344/node_modules/@ethersproject-xdc/properties" - "@ethersproject-xdc/strings" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-hash-5.7.0-9b16a632-0d7e-4eaa-9ec6-44acc4468bd1-1682382909344/node_modules/@ethersproject-xdc/strings" + "@ethersproject-xdc/abstract-signer" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-hash-5.7.0-42701ac9-cfa2-4bd6-a684-ddbe7f96f49b-1683016746649/node_modules/@ethersproject-xdc/abstract-signer" + "@ethersproject-xdc/address" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-hash-5.7.0-42701ac9-cfa2-4bd6-a684-ddbe7f96f49b-1683016746649/node_modules/@ethersproject-xdc/address" + "@ethersproject-xdc/base64" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-hash-5.7.0-42701ac9-cfa2-4bd6-a684-ddbe7f96f49b-1683016746649/node_modules/@ethersproject-xdc/base64" + "@ethersproject-xdc/bignumber" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-hash-5.7.0-42701ac9-cfa2-4bd6-a684-ddbe7f96f49b-1683016746649/node_modules/@ethersproject-xdc/bignumber" + "@ethersproject-xdc/bytes" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-hash-5.7.0-42701ac9-cfa2-4bd6-a684-ddbe7f96f49b-1683016746649/node_modules/@ethersproject-xdc/bytes" + "@ethersproject-xdc/keccak256" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-hash-5.7.0-42701ac9-cfa2-4bd6-a684-ddbe7f96f49b-1683016746649/node_modules/@ethersproject-xdc/keccak256" + "@ethersproject-xdc/logger" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-hash-5.7.0-42701ac9-cfa2-4bd6-a684-ddbe7f96f49b-1683016746649/node_modules/@ethersproject-xdc/logger" + "@ethersproject-xdc/properties" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-hash-5.7.0-42701ac9-cfa2-4bd6-a684-ddbe7f96f49b-1683016746649/node_modules/@ethersproject-xdc/properties" + "@ethersproject-xdc/strings" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-hash-5.7.0-42701ac9-cfa2-4bd6-a684-ddbe7f96f49b-1683016746649/node_modules/@ethersproject-xdc/strings" "@ethersproject-xdc/hdnode@file:vendor/@ethersproject-xdc/hdnode": version "5.7.0" dependencies: - "@ethersproject-xdc/abstract-signer" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-hdnode-5.7.0-67e0114e-3348-4a00-a1fd-013c3204cc73-1682382909346/node_modules/@ethersproject-xdc/abstract-signer" - "@ethersproject-xdc/basex" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-hdnode-5.7.0-67e0114e-3348-4a00-a1fd-013c3204cc73-1682382909346/node_modules/@ethersproject-xdc/basex" - "@ethersproject-xdc/bignumber" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-hdnode-5.7.0-67e0114e-3348-4a00-a1fd-013c3204cc73-1682382909346/node_modules/@ethersproject-xdc/bignumber" - "@ethersproject-xdc/bytes" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-hdnode-5.7.0-67e0114e-3348-4a00-a1fd-013c3204cc73-1682382909346/node_modules/@ethersproject-xdc/bytes" - "@ethersproject-xdc/logger" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-hdnode-5.7.0-67e0114e-3348-4a00-a1fd-013c3204cc73-1682382909346/node_modules/@ethersproject-xdc/logger" - "@ethersproject-xdc/pbkdf2" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-hdnode-5.7.0-67e0114e-3348-4a00-a1fd-013c3204cc73-1682382909346/node_modules/@ethersproject-xdc/pbkdf2" - "@ethersproject-xdc/properties" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-hdnode-5.7.0-67e0114e-3348-4a00-a1fd-013c3204cc73-1682382909346/node_modules/@ethersproject-xdc/properties" - "@ethersproject-xdc/sha2" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-hdnode-5.7.0-67e0114e-3348-4a00-a1fd-013c3204cc73-1682382909346/node_modules/@ethersproject-xdc/sha2" - "@ethersproject-xdc/signing-key" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-hdnode-5.7.0-67e0114e-3348-4a00-a1fd-013c3204cc73-1682382909346/node_modules/@ethersproject-xdc/signing-key" - "@ethersproject-xdc/strings" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-hdnode-5.7.0-67e0114e-3348-4a00-a1fd-013c3204cc73-1682382909346/node_modules/@ethersproject-xdc/strings" - "@ethersproject-xdc/transactions" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-hdnode-5.7.0-67e0114e-3348-4a00-a1fd-013c3204cc73-1682382909346/node_modules/@ethersproject-xdc/transactions" - "@ethersproject-xdc/wordlists" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-hdnode-5.7.0-67e0114e-3348-4a00-a1fd-013c3204cc73-1682382909346/node_modules/@ethersproject-xdc/wordlists" + "@ethersproject-xdc/abstract-signer" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-hdnode-5.7.0-ce8d5b97-301d-41ca-a8ea-df58cdb5fd6d-1683016746642/node_modules/@ethersproject-xdc/abstract-signer" + "@ethersproject-xdc/basex" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-hdnode-5.7.0-ce8d5b97-301d-41ca-a8ea-df58cdb5fd6d-1683016746642/node_modules/@ethersproject-xdc/basex" + "@ethersproject-xdc/bignumber" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-hdnode-5.7.0-ce8d5b97-301d-41ca-a8ea-df58cdb5fd6d-1683016746642/node_modules/@ethersproject-xdc/bignumber" + "@ethersproject-xdc/bytes" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-hdnode-5.7.0-ce8d5b97-301d-41ca-a8ea-df58cdb5fd6d-1683016746642/node_modules/@ethersproject-xdc/bytes" + "@ethersproject-xdc/logger" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-hdnode-5.7.0-ce8d5b97-301d-41ca-a8ea-df58cdb5fd6d-1683016746642/node_modules/@ethersproject-xdc/logger" + "@ethersproject-xdc/pbkdf2" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-hdnode-5.7.0-ce8d5b97-301d-41ca-a8ea-df58cdb5fd6d-1683016746642/node_modules/@ethersproject-xdc/pbkdf2" + "@ethersproject-xdc/properties" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-hdnode-5.7.0-ce8d5b97-301d-41ca-a8ea-df58cdb5fd6d-1683016746642/node_modules/@ethersproject-xdc/properties" + "@ethersproject-xdc/sha2" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-hdnode-5.7.0-ce8d5b97-301d-41ca-a8ea-df58cdb5fd6d-1683016746642/node_modules/@ethersproject-xdc/sha2" + "@ethersproject-xdc/signing-key" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-hdnode-5.7.0-ce8d5b97-301d-41ca-a8ea-df58cdb5fd6d-1683016746642/node_modules/@ethersproject-xdc/signing-key" + "@ethersproject-xdc/strings" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-hdnode-5.7.0-ce8d5b97-301d-41ca-a8ea-df58cdb5fd6d-1683016746642/node_modules/@ethersproject-xdc/strings" + "@ethersproject-xdc/transactions" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-hdnode-5.7.0-ce8d5b97-301d-41ca-a8ea-df58cdb5fd6d-1683016746642/node_modules/@ethersproject-xdc/transactions" + "@ethersproject-xdc/wordlists" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-hdnode-5.7.0-ce8d5b97-301d-41ca-a8ea-df58cdb5fd6d-1683016746642/node_modules/@ethersproject-xdc/wordlists" "@ethersproject-xdc/json-wallets@file:vendor/@ethersproject-xdc/json-wallets": version "5.6.0" dependencies: - "@ethersproject-xdc/abstract-signer" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-json-wallets-5.6.0-dd858808-b7c9-41ea-ac9b-72f8ce5ca524-1682382909345/node_modules/@ethersproject-xdc/abstract-signer" - "@ethersproject-xdc/address" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-json-wallets-5.6.0-dd858808-b7c9-41ea-ac9b-72f8ce5ca524-1682382909345/node_modules/@ethersproject-xdc/address" - "@ethersproject-xdc/bytes" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-json-wallets-5.6.0-dd858808-b7c9-41ea-ac9b-72f8ce5ca524-1682382909345/node_modules/@ethersproject-xdc/bytes" - "@ethersproject-xdc/hdnode" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-json-wallets-5.6.0-dd858808-b7c9-41ea-ac9b-72f8ce5ca524-1682382909345/node_modules/@ethersproject-xdc/hdnode" - "@ethersproject-xdc/keccak256" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-json-wallets-5.6.0-dd858808-b7c9-41ea-ac9b-72f8ce5ca524-1682382909345/node_modules/@ethersproject-xdc/keccak256" - "@ethersproject-xdc/logger" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-json-wallets-5.6.0-dd858808-b7c9-41ea-ac9b-72f8ce5ca524-1682382909345/node_modules/@ethersproject-xdc/logger" - "@ethersproject-xdc/pbkdf2" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-json-wallets-5.6.0-dd858808-b7c9-41ea-ac9b-72f8ce5ca524-1682382909345/node_modules/@ethersproject-xdc/pbkdf2" - "@ethersproject-xdc/properties" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-json-wallets-5.6.0-dd858808-b7c9-41ea-ac9b-72f8ce5ca524-1682382909345/node_modules/@ethersproject-xdc/properties" - "@ethersproject-xdc/random" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-json-wallets-5.6.0-dd858808-b7c9-41ea-ac9b-72f8ce5ca524-1682382909345/node_modules/@ethersproject-xdc/random" - "@ethersproject-xdc/strings" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-json-wallets-5.6.0-dd858808-b7c9-41ea-ac9b-72f8ce5ca524-1682382909345/node_modules/@ethersproject-xdc/strings" - "@ethersproject-xdc/transactions" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-json-wallets-5.6.0-dd858808-b7c9-41ea-ac9b-72f8ce5ca524-1682382909345/node_modules/@ethersproject-xdc/transactions" + "@ethersproject-xdc/abstract-signer" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-json-wallets-5.6.0-89cc9170-62a6-4cd9-b0b6-c4793f745169-1683016746641/node_modules/@ethersproject-xdc/abstract-signer" + "@ethersproject-xdc/address" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-json-wallets-5.6.0-89cc9170-62a6-4cd9-b0b6-c4793f745169-1683016746641/node_modules/@ethersproject-xdc/address" + "@ethersproject-xdc/bytes" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-json-wallets-5.6.0-89cc9170-62a6-4cd9-b0b6-c4793f745169-1683016746641/node_modules/@ethersproject-xdc/bytes" + "@ethersproject-xdc/hdnode" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-json-wallets-5.6.0-89cc9170-62a6-4cd9-b0b6-c4793f745169-1683016746641/node_modules/@ethersproject-xdc/hdnode" + "@ethersproject-xdc/keccak256" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-json-wallets-5.6.0-89cc9170-62a6-4cd9-b0b6-c4793f745169-1683016746641/node_modules/@ethersproject-xdc/keccak256" + "@ethersproject-xdc/logger" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-json-wallets-5.6.0-89cc9170-62a6-4cd9-b0b6-c4793f745169-1683016746641/node_modules/@ethersproject-xdc/logger" + "@ethersproject-xdc/pbkdf2" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-json-wallets-5.6.0-89cc9170-62a6-4cd9-b0b6-c4793f745169-1683016746641/node_modules/@ethersproject-xdc/pbkdf2" + "@ethersproject-xdc/properties" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-json-wallets-5.6.0-89cc9170-62a6-4cd9-b0b6-c4793f745169-1683016746641/node_modules/@ethersproject-xdc/properties" + "@ethersproject-xdc/random" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-json-wallets-5.6.0-89cc9170-62a6-4cd9-b0b6-c4793f745169-1683016746641/node_modules/@ethersproject-xdc/random" + "@ethersproject-xdc/strings" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-json-wallets-5.6.0-89cc9170-62a6-4cd9-b0b6-c4793f745169-1683016746641/node_modules/@ethersproject-xdc/strings" + "@ethersproject-xdc/transactions" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-json-wallets-5.6.0-89cc9170-62a6-4cd9-b0b6-c4793f745169-1683016746641/node_modules/@ethersproject-xdc/transactions" aes-js "3.0.0" scrypt-js "3.0.1" "@ethersproject-xdc/keccak256@file:vendor/@ethersproject-xdc/keccak256": version "5.7.0" dependencies: - "@ethersproject-xdc/bytes" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-keccak256-5.7.0-d62cd71b-bd59-48c1-a0a4-6b3bdb92533d-1682382909340/node_modules/@ethersproject-xdc/bytes" + "@ethersproject-xdc/bytes" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-keccak256-5.7.0-c74c3f66-b45f-4ff8-87d5-a2e5a610edcf-1683016746641/node_modules/@ethersproject-xdc/bytes" js-sha3 "0.8.0" "@ethersproject-xdc/logger@file:vendor/@ethersproject-xdc/logger": @@ -1121,67 +1121,67 @@ "@ethersproject-xdc/networks@file:vendor/@ethersproject-xdc/networks": version "5.7.1" dependencies: - "@ethersproject-xdc/logger" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-networks-5.7.1-7d47a9e1-9ab5-4401-b297-70f265e0a07a-1682382909342/node_modules/@ethersproject-xdc/logger" + "@ethersproject-xdc/logger" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-networks-5.7.1-2c38e0bd-8ac0-40c6-b530-a09ccfd584d7-1683016746643/node_modules/@ethersproject-xdc/logger" "@ethersproject-xdc/pbkdf2@file:vendor/@ethersproject-xdc/pbkdf2": version "5.7.0" dependencies: - "@ethersproject-xdc/bytes" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-pbkdf2-5.7.0-f8323b4a-a10e-41e9-86a3-52ebd83b4439-1682382909340/node_modules/@ethersproject-xdc/bytes" - "@ethersproject-xdc/sha2" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-pbkdf2-5.7.0-f8323b4a-a10e-41e9-86a3-52ebd83b4439-1682382909340/node_modules/@ethersproject-xdc/sha2" + "@ethersproject-xdc/bytes" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-pbkdf2-5.7.0-2e07335f-3d68-4348-8319-c906b373c018-1683016746650/node_modules/@ethersproject-xdc/bytes" + "@ethersproject-xdc/sha2" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-pbkdf2-5.7.0-2e07335f-3d68-4348-8319-c906b373c018-1683016746650/node_modules/@ethersproject-xdc/sha2" "@ethersproject-xdc/properties@file:vendor/@ethersproject-xdc/properties": version "5.7.0" dependencies: - "@ethersproject-xdc/logger" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-properties-5.7.0-4d860278-4928-415c-a068-05c90656651a-1682382909342/node_modules/@ethersproject-xdc/logger" + "@ethersproject-xdc/logger" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-properties-5.7.0-1ab13968-e0e1-4034-9018-f41efb5f46bd-1683016746643/node_modules/@ethersproject-xdc/logger" "@ethersproject-xdc/providers@file:vendor/@ethersproject-xdc/providers": version "5.6.2" dependencies: - "@ethersproject-xdc/abstract-provider" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-providers-5.6.2-12670854-d71d-424b-a739-a02fea51d58d-1682382909341/node_modules/@ethersproject-xdc/abstract-provider" - "@ethersproject-xdc/abstract-signer" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-providers-5.6.2-12670854-d71d-424b-a739-a02fea51d58d-1682382909341/node_modules/@ethersproject-xdc/abstract-signer" - "@ethersproject-xdc/address" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-providers-5.6.2-12670854-d71d-424b-a739-a02fea51d58d-1682382909341/node_modules/@ethersproject-xdc/address" - "@ethersproject-xdc/basex" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-providers-5.6.2-12670854-d71d-424b-a739-a02fea51d58d-1682382909341/node_modules/@ethersproject-xdc/basex" - "@ethersproject-xdc/bignumber" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-providers-5.6.2-12670854-d71d-424b-a739-a02fea51d58d-1682382909341/node_modules/@ethersproject-xdc/bignumber" - "@ethersproject-xdc/bytes" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-providers-5.6.2-12670854-d71d-424b-a739-a02fea51d58d-1682382909341/node_modules/@ethersproject-xdc/bytes" - "@ethersproject-xdc/constants" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-providers-5.6.2-12670854-d71d-424b-a739-a02fea51d58d-1682382909341/node_modules/@ethersproject-xdc/constants" - "@ethersproject-xdc/hash" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-providers-5.6.2-12670854-d71d-424b-a739-a02fea51d58d-1682382909341/node_modules/@ethersproject-xdc/hash" - "@ethersproject-xdc/logger" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-providers-5.6.2-12670854-d71d-424b-a739-a02fea51d58d-1682382909341/node_modules/@ethersproject-xdc/logger" - "@ethersproject-xdc/networks" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-providers-5.6.2-12670854-d71d-424b-a739-a02fea51d58d-1682382909341/node_modules/@ethersproject-xdc/networks" - "@ethersproject-xdc/properties" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-providers-5.6.2-12670854-d71d-424b-a739-a02fea51d58d-1682382909341/node_modules/@ethersproject-xdc/properties" - "@ethersproject-xdc/random" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-providers-5.6.2-12670854-d71d-424b-a739-a02fea51d58d-1682382909341/node_modules/@ethersproject-xdc/random" - "@ethersproject-xdc/rlp" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-providers-5.6.2-12670854-d71d-424b-a739-a02fea51d58d-1682382909341/node_modules/@ethersproject-xdc/rlp" - "@ethersproject-xdc/sha2" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-providers-5.6.2-12670854-d71d-424b-a739-a02fea51d58d-1682382909341/node_modules/@ethersproject-xdc/sha2" - "@ethersproject-xdc/strings" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-providers-5.6.2-12670854-d71d-424b-a739-a02fea51d58d-1682382909341/node_modules/@ethersproject-xdc/strings" - "@ethersproject-xdc/transactions" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-providers-5.6.2-12670854-d71d-424b-a739-a02fea51d58d-1682382909341/node_modules/@ethersproject-xdc/transactions" - "@ethersproject-xdc/web" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-providers-5.6.2-12670854-d71d-424b-a739-a02fea51d58d-1682382909341/node_modules/@ethersproject-xdc/web" + "@ethersproject-xdc/abstract-provider" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-providers-5.6.2-5537dfc6-ae43-4ab4-9443-1d8e52fc13fe-1683016746647/node_modules/@ethersproject-xdc/abstract-provider" + "@ethersproject-xdc/abstract-signer" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-providers-5.6.2-5537dfc6-ae43-4ab4-9443-1d8e52fc13fe-1683016746647/node_modules/@ethersproject-xdc/abstract-signer" + "@ethersproject-xdc/address" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-providers-5.6.2-5537dfc6-ae43-4ab4-9443-1d8e52fc13fe-1683016746647/node_modules/@ethersproject-xdc/address" + "@ethersproject-xdc/basex" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-providers-5.6.2-5537dfc6-ae43-4ab4-9443-1d8e52fc13fe-1683016746647/node_modules/@ethersproject-xdc/basex" + "@ethersproject-xdc/bignumber" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-providers-5.6.2-5537dfc6-ae43-4ab4-9443-1d8e52fc13fe-1683016746647/node_modules/@ethersproject-xdc/bignumber" + "@ethersproject-xdc/bytes" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-providers-5.6.2-5537dfc6-ae43-4ab4-9443-1d8e52fc13fe-1683016746647/node_modules/@ethersproject-xdc/bytes" + "@ethersproject-xdc/constants" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-providers-5.6.2-5537dfc6-ae43-4ab4-9443-1d8e52fc13fe-1683016746647/node_modules/@ethersproject-xdc/constants" + "@ethersproject-xdc/hash" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-providers-5.6.2-5537dfc6-ae43-4ab4-9443-1d8e52fc13fe-1683016746647/node_modules/@ethersproject-xdc/hash" + "@ethersproject-xdc/logger" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-providers-5.6.2-5537dfc6-ae43-4ab4-9443-1d8e52fc13fe-1683016746647/node_modules/@ethersproject-xdc/logger" + "@ethersproject-xdc/networks" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-providers-5.6.2-5537dfc6-ae43-4ab4-9443-1d8e52fc13fe-1683016746647/node_modules/@ethersproject-xdc/networks" + "@ethersproject-xdc/properties" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-providers-5.6.2-5537dfc6-ae43-4ab4-9443-1d8e52fc13fe-1683016746647/node_modules/@ethersproject-xdc/properties" + "@ethersproject-xdc/random" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-providers-5.6.2-5537dfc6-ae43-4ab4-9443-1d8e52fc13fe-1683016746647/node_modules/@ethersproject-xdc/random" + "@ethersproject-xdc/rlp" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-providers-5.6.2-5537dfc6-ae43-4ab4-9443-1d8e52fc13fe-1683016746647/node_modules/@ethersproject-xdc/rlp" + "@ethersproject-xdc/sha2" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-providers-5.6.2-5537dfc6-ae43-4ab4-9443-1d8e52fc13fe-1683016746647/node_modules/@ethersproject-xdc/sha2" + "@ethersproject-xdc/strings" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-providers-5.6.2-5537dfc6-ae43-4ab4-9443-1d8e52fc13fe-1683016746647/node_modules/@ethersproject-xdc/strings" + "@ethersproject-xdc/transactions" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-providers-5.6.2-5537dfc6-ae43-4ab4-9443-1d8e52fc13fe-1683016746647/node_modules/@ethersproject-xdc/transactions" + "@ethersproject-xdc/web" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-providers-5.6.2-5537dfc6-ae43-4ab4-9443-1d8e52fc13fe-1683016746647/node_modules/@ethersproject-xdc/web" bech32 "1.1.4" ws "7.4.6" "@ethersproject-xdc/random@file:vendor/@ethersproject-xdc/random": version "5.7.0" dependencies: - "@ethersproject-xdc/bytes" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-random-5.7.0-dd1f632f-f772-4842-9565-b12f7f7b5410-1682382909346/node_modules/@ethersproject-xdc/bytes" - "@ethersproject-xdc/logger" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-random-5.7.0-dd1f632f-f772-4842-9565-b12f7f7b5410-1682382909346/node_modules/@ethersproject-xdc/logger" + "@ethersproject-xdc/bytes" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-random-5.7.0-a212651f-0acc-4bb2-9d1f-839e6d1c38cd-1683016746643/node_modules/@ethersproject-xdc/bytes" + "@ethersproject-xdc/logger" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-random-5.7.0-a212651f-0acc-4bb2-9d1f-839e6d1c38cd-1683016746643/node_modules/@ethersproject-xdc/logger" "@ethersproject-xdc/rlp@file:vendor/@ethersproject-xdc/rlp": version "5.7.0" dependencies: - "@ethersproject-xdc/bytes" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-rlp-5.7.0-9c49a513-09cc-48f5-b999-e81f34cac75e-1682382909342/node_modules/@ethersproject-xdc/bytes" - "@ethersproject-xdc/logger" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-rlp-5.7.0-9c49a513-09cc-48f5-b999-e81f34cac75e-1682382909342/node_modules/@ethersproject-xdc/logger" + "@ethersproject-xdc/bytes" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-rlp-5.7.0-994f3fa4-5b81-48e8-bb87-ff0565fdbba0-1683016746649/node_modules/@ethersproject-xdc/bytes" + "@ethersproject-xdc/logger" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-rlp-5.7.0-994f3fa4-5b81-48e8-bb87-ff0565fdbba0-1683016746649/node_modules/@ethersproject-xdc/logger" "@ethersproject-xdc/sha2@file:vendor/@ethersproject-xdc/sha2": version "5.7.0" dependencies: - "@ethersproject-xdc/bytes" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-sha2-5.7.0-12a71856-645c-40f5-8201-f9149262332c-1682382909348/node_modules/@ethersproject-xdc/bytes" - "@ethersproject-xdc/logger" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-sha2-5.7.0-12a71856-645c-40f5-8201-f9149262332c-1682382909348/node_modules/@ethersproject-xdc/logger" + "@ethersproject-xdc/bytes" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-sha2-5.7.0-2dab76b7-4f79-4184-a0fa-bb5a60a6eb87-1683016746644/node_modules/@ethersproject-xdc/bytes" + "@ethersproject-xdc/logger" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-sha2-5.7.0-2dab76b7-4f79-4184-a0fa-bb5a60a6eb87-1683016746644/node_modules/@ethersproject-xdc/logger" hash.js "1.1.7" "@ethersproject-xdc/signing-key@file:vendor/@ethersproject-xdc/signing-key": version "5.7.0" dependencies: - "@ethersproject-xdc/bytes" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-signing-key-5.7.0-925d18b3-2a15-4a70-8d51-cbf9a4b126f1-1682382909342/node_modules/@ethersproject-xdc/bytes" - "@ethersproject-xdc/logger" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-signing-key-5.7.0-925d18b3-2a15-4a70-8d51-cbf9a4b126f1-1682382909342/node_modules/@ethersproject-xdc/logger" - "@ethersproject-xdc/properties" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-signing-key-5.7.0-925d18b3-2a15-4a70-8d51-cbf9a4b126f1-1682382909342/node_modules/@ethersproject-xdc/properties" + "@ethersproject-xdc/bytes" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-signing-key-5.7.0-d8963b13-2ae2-42a7-b4b5-fa0da5103535-1683016746644/node_modules/@ethersproject-xdc/bytes" + "@ethersproject-xdc/logger" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-signing-key-5.7.0-d8963b13-2ae2-42a7-b4b5-fa0da5103535-1683016746644/node_modules/@ethersproject-xdc/logger" + "@ethersproject-xdc/properties" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-signing-key-5.7.0-d8963b13-2ae2-42a7-b4b5-fa0da5103535-1683016746644/node_modules/@ethersproject-xdc/properties" bn.js "^5.2.1" elliptic "6.5.4" hash.js "1.1.7" @@ -1189,76 +1189,76 @@ "@ethersproject-xdc/solidity@file:vendor/@ethersproject-xdc/solidity": version "5.6.0" dependencies: - "@ethersproject-xdc/bignumber" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-solidity-5.6.0-ada79c8c-b253-4d2e-b9a2-5186f55c82b8-1682382909344/node_modules/@ethersproject-xdc/bignumber" - "@ethersproject-xdc/bytes" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-solidity-5.6.0-ada79c8c-b253-4d2e-b9a2-5186f55c82b8-1682382909344/node_modules/@ethersproject-xdc/bytes" - "@ethersproject-xdc/keccak256" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-solidity-5.6.0-ada79c8c-b253-4d2e-b9a2-5186f55c82b8-1682382909344/node_modules/@ethersproject-xdc/keccak256" - "@ethersproject-xdc/logger" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-solidity-5.6.0-ada79c8c-b253-4d2e-b9a2-5186f55c82b8-1682382909344/node_modules/@ethersproject-xdc/logger" - "@ethersproject-xdc/sha2" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-solidity-5.6.0-ada79c8c-b253-4d2e-b9a2-5186f55c82b8-1682382909344/node_modules/@ethersproject-xdc/sha2" - "@ethersproject-xdc/strings" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-solidity-5.6.0-ada79c8c-b253-4d2e-b9a2-5186f55c82b8-1682382909344/node_modules/@ethersproject-xdc/strings" + "@ethersproject-xdc/bignumber" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-solidity-5.6.0-3545b369-9bbe-4dd1-afcf-4e751476f4df-1683016746643/node_modules/@ethersproject-xdc/bignumber" + "@ethersproject-xdc/bytes" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-solidity-5.6.0-3545b369-9bbe-4dd1-afcf-4e751476f4df-1683016746643/node_modules/@ethersproject-xdc/bytes" + "@ethersproject-xdc/keccak256" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-solidity-5.6.0-3545b369-9bbe-4dd1-afcf-4e751476f4df-1683016746643/node_modules/@ethersproject-xdc/keccak256" + "@ethersproject-xdc/logger" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-solidity-5.6.0-3545b369-9bbe-4dd1-afcf-4e751476f4df-1683016746643/node_modules/@ethersproject-xdc/logger" + "@ethersproject-xdc/sha2" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-solidity-5.6.0-3545b369-9bbe-4dd1-afcf-4e751476f4df-1683016746643/node_modules/@ethersproject-xdc/sha2" + "@ethersproject-xdc/strings" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-solidity-5.6.0-3545b369-9bbe-4dd1-afcf-4e751476f4df-1683016746643/node_modules/@ethersproject-xdc/strings" "@ethersproject-xdc/strings@file:vendor/@ethersproject-xdc/strings": version "5.7.0" dependencies: - "@ethersproject-xdc/bytes" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-strings-5.7.0-d05ae7ed-8c53-4e7d-a722-8ae58e79d319-1682382909347/node_modules/@ethersproject-xdc/bytes" - "@ethersproject-xdc/constants" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-strings-5.7.0-d05ae7ed-8c53-4e7d-a722-8ae58e79d319-1682382909347/node_modules/@ethersproject-xdc/constants" - "@ethersproject-xdc/logger" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-strings-5.7.0-d05ae7ed-8c53-4e7d-a722-8ae58e79d319-1682382909347/node_modules/@ethersproject-xdc/logger" + "@ethersproject-xdc/bytes" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-strings-5.7.0-3b221bd2-b43d-4eb5-9ece-d289ce50968a-1683016746645/node_modules/@ethersproject-xdc/bytes" + "@ethersproject-xdc/constants" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-strings-5.7.0-3b221bd2-b43d-4eb5-9ece-d289ce50968a-1683016746645/node_modules/@ethersproject-xdc/constants" + "@ethersproject-xdc/logger" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-strings-5.7.0-3b221bd2-b43d-4eb5-9ece-d289ce50968a-1683016746645/node_modules/@ethersproject-xdc/logger" "@ethersproject-xdc/transactions@file:vendor/@ethersproject-xdc/transactions": version "5.7.0" dependencies: - "@ethersproject-xdc/address" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-transactions-5.7.0-d74cb0c4-3b68-4d96-9d0b-56ee160493eb-1682382909347/node_modules/@ethersproject-xdc/address" - "@ethersproject-xdc/bignumber" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-transactions-5.7.0-d74cb0c4-3b68-4d96-9d0b-56ee160493eb-1682382909347/node_modules/@ethersproject-xdc/bignumber" - "@ethersproject-xdc/bytes" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-transactions-5.7.0-d74cb0c4-3b68-4d96-9d0b-56ee160493eb-1682382909347/node_modules/@ethersproject-xdc/bytes" - "@ethersproject-xdc/constants" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-transactions-5.7.0-d74cb0c4-3b68-4d96-9d0b-56ee160493eb-1682382909347/node_modules/@ethersproject-xdc/constants" - "@ethersproject-xdc/keccak256" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-transactions-5.7.0-d74cb0c4-3b68-4d96-9d0b-56ee160493eb-1682382909347/node_modules/@ethersproject-xdc/keccak256" - "@ethersproject-xdc/logger" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-transactions-5.7.0-d74cb0c4-3b68-4d96-9d0b-56ee160493eb-1682382909347/node_modules/@ethersproject-xdc/logger" - "@ethersproject-xdc/properties" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-transactions-5.7.0-d74cb0c4-3b68-4d96-9d0b-56ee160493eb-1682382909347/node_modules/@ethersproject-xdc/properties" - "@ethersproject-xdc/rlp" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-transactions-5.7.0-d74cb0c4-3b68-4d96-9d0b-56ee160493eb-1682382909347/node_modules/@ethersproject-xdc/rlp" - "@ethersproject-xdc/signing-key" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-transactions-5.7.0-d74cb0c4-3b68-4d96-9d0b-56ee160493eb-1682382909347/node_modules/@ethersproject-xdc/signing-key" + "@ethersproject-xdc/address" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-transactions-5.7.0-00913364-142f-4cbb-85f5-ac371d126794-1683016746648/node_modules/@ethersproject-xdc/address" + "@ethersproject-xdc/bignumber" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-transactions-5.7.0-00913364-142f-4cbb-85f5-ac371d126794-1683016746648/node_modules/@ethersproject-xdc/bignumber" + "@ethersproject-xdc/bytes" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-transactions-5.7.0-00913364-142f-4cbb-85f5-ac371d126794-1683016746648/node_modules/@ethersproject-xdc/bytes" + "@ethersproject-xdc/constants" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-transactions-5.7.0-00913364-142f-4cbb-85f5-ac371d126794-1683016746648/node_modules/@ethersproject-xdc/constants" + "@ethersproject-xdc/keccak256" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-transactions-5.7.0-00913364-142f-4cbb-85f5-ac371d126794-1683016746648/node_modules/@ethersproject-xdc/keccak256" + "@ethersproject-xdc/logger" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-transactions-5.7.0-00913364-142f-4cbb-85f5-ac371d126794-1683016746648/node_modules/@ethersproject-xdc/logger" + "@ethersproject-xdc/properties" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-transactions-5.7.0-00913364-142f-4cbb-85f5-ac371d126794-1683016746648/node_modules/@ethersproject-xdc/properties" + "@ethersproject-xdc/rlp" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-transactions-5.7.0-00913364-142f-4cbb-85f5-ac371d126794-1683016746648/node_modules/@ethersproject-xdc/rlp" + "@ethersproject-xdc/signing-key" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-transactions-5.7.0-00913364-142f-4cbb-85f5-ac371d126794-1683016746648/node_modules/@ethersproject-xdc/signing-key" "@ethersproject-xdc/units@file:vendor/@ethersproject-xdc/units": version "5.6.0" dependencies: - "@ethersproject-xdc/bignumber" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-units-5.6.0-4c4b4961-6652-4d25-b75c-0bbf21e31886-1682382909345/node_modules/@ethersproject-xdc/bignumber" - "@ethersproject-xdc/constants" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-units-5.6.0-4c4b4961-6652-4d25-b75c-0bbf21e31886-1682382909345/node_modules/@ethersproject-xdc/constants" - "@ethersproject-xdc/logger" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-units-5.6.0-4c4b4961-6652-4d25-b75c-0bbf21e31886-1682382909345/node_modules/@ethersproject-xdc/logger" + "@ethersproject-xdc/bignumber" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-units-5.6.0-a1c86f00-c37c-4b42-8c2d-432e2621ad93-1683016746646/node_modules/@ethersproject-xdc/bignumber" + "@ethersproject-xdc/constants" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-units-5.6.0-a1c86f00-c37c-4b42-8c2d-432e2621ad93-1683016746646/node_modules/@ethersproject-xdc/constants" + "@ethersproject-xdc/logger" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-units-5.6.0-a1c86f00-c37c-4b42-8c2d-432e2621ad93-1683016746646/node_modules/@ethersproject-xdc/logger" "@ethersproject-xdc/wallet@file:vendor/@ethersproject-xdc/wallet": version "5.6.0" dependencies: - "@ethersproject-xdc/abstract-provider" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-wallet-5.6.0-bd399d30-c8cc-482b-b1cb-6adb152d563d-1682382909347/node_modules/@ethersproject-xdc/abstract-provider" - "@ethersproject-xdc/abstract-signer" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-wallet-5.6.0-bd399d30-c8cc-482b-b1cb-6adb152d563d-1682382909347/node_modules/@ethersproject-xdc/abstract-signer" - "@ethersproject-xdc/address" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-wallet-5.6.0-bd399d30-c8cc-482b-b1cb-6adb152d563d-1682382909347/node_modules/@ethersproject-xdc/address" - "@ethersproject-xdc/bignumber" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-wallet-5.6.0-bd399d30-c8cc-482b-b1cb-6adb152d563d-1682382909347/node_modules/@ethersproject-xdc/bignumber" - "@ethersproject-xdc/bytes" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-wallet-5.6.0-bd399d30-c8cc-482b-b1cb-6adb152d563d-1682382909347/node_modules/@ethersproject-xdc/bytes" - "@ethersproject-xdc/hash" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-wallet-5.6.0-bd399d30-c8cc-482b-b1cb-6adb152d563d-1682382909347/node_modules/@ethersproject-xdc/hash" - "@ethersproject-xdc/hdnode" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-wallet-5.6.0-bd399d30-c8cc-482b-b1cb-6adb152d563d-1682382909347/node_modules/@ethersproject-xdc/hdnode" - "@ethersproject-xdc/json-wallets" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-wallet-5.6.0-bd399d30-c8cc-482b-b1cb-6adb152d563d-1682382909347/node_modules/@ethersproject-xdc/json-wallets" - "@ethersproject-xdc/keccak256" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-wallet-5.6.0-bd399d30-c8cc-482b-b1cb-6adb152d563d-1682382909347/node_modules/@ethersproject-xdc/keccak256" - "@ethersproject-xdc/logger" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-wallet-5.6.0-bd399d30-c8cc-482b-b1cb-6adb152d563d-1682382909347/node_modules/@ethersproject-xdc/logger" - "@ethersproject-xdc/properties" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-wallet-5.6.0-bd399d30-c8cc-482b-b1cb-6adb152d563d-1682382909347/node_modules/@ethersproject-xdc/properties" - "@ethersproject-xdc/random" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-wallet-5.6.0-bd399d30-c8cc-482b-b1cb-6adb152d563d-1682382909347/node_modules/@ethersproject-xdc/random" - "@ethersproject-xdc/signing-key" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-wallet-5.6.0-bd399d30-c8cc-482b-b1cb-6adb152d563d-1682382909347/node_modules/@ethersproject-xdc/signing-key" - "@ethersproject-xdc/transactions" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-wallet-5.6.0-bd399d30-c8cc-482b-b1cb-6adb152d563d-1682382909347/node_modules/@ethersproject-xdc/transactions" - "@ethersproject-xdc/wordlists" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-wallet-5.6.0-bd399d30-c8cc-482b-b1cb-6adb152d563d-1682382909347/node_modules/@ethersproject-xdc/wordlists" + "@ethersproject-xdc/abstract-provider" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-wallet-5.6.0-c6faf6f9-70b6-4e3b-b6a6-6c2d1865982b-1683016746649/node_modules/@ethersproject-xdc/abstract-provider" + "@ethersproject-xdc/abstract-signer" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-wallet-5.6.0-c6faf6f9-70b6-4e3b-b6a6-6c2d1865982b-1683016746649/node_modules/@ethersproject-xdc/abstract-signer" + "@ethersproject-xdc/address" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-wallet-5.6.0-c6faf6f9-70b6-4e3b-b6a6-6c2d1865982b-1683016746649/node_modules/@ethersproject-xdc/address" + "@ethersproject-xdc/bignumber" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-wallet-5.6.0-c6faf6f9-70b6-4e3b-b6a6-6c2d1865982b-1683016746649/node_modules/@ethersproject-xdc/bignumber" + "@ethersproject-xdc/bytes" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-wallet-5.6.0-c6faf6f9-70b6-4e3b-b6a6-6c2d1865982b-1683016746649/node_modules/@ethersproject-xdc/bytes" + "@ethersproject-xdc/hash" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-wallet-5.6.0-c6faf6f9-70b6-4e3b-b6a6-6c2d1865982b-1683016746649/node_modules/@ethersproject-xdc/hash" + "@ethersproject-xdc/hdnode" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-wallet-5.6.0-c6faf6f9-70b6-4e3b-b6a6-6c2d1865982b-1683016746649/node_modules/@ethersproject-xdc/hdnode" + "@ethersproject-xdc/json-wallets" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-wallet-5.6.0-c6faf6f9-70b6-4e3b-b6a6-6c2d1865982b-1683016746649/node_modules/@ethersproject-xdc/json-wallets" + "@ethersproject-xdc/keccak256" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-wallet-5.6.0-c6faf6f9-70b6-4e3b-b6a6-6c2d1865982b-1683016746649/node_modules/@ethersproject-xdc/keccak256" + "@ethersproject-xdc/logger" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-wallet-5.6.0-c6faf6f9-70b6-4e3b-b6a6-6c2d1865982b-1683016746649/node_modules/@ethersproject-xdc/logger" + "@ethersproject-xdc/properties" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-wallet-5.6.0-c6faf6f9-70b6-4e3b-b6a6-6c2d1865982b-1683016746649/node_modules/@ethersproject-xdc/properties" + "@ethersproject-xdc/random" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-wallet-5.6.0-c6faf6f9-70b6-4e3b-b6a6-6c2d1865982b-1683016746649/node_modules/@ethersproject-xdc/random" + "@ethersproject-xdc/signing-key" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-wallet-5.6.0-c6faf6f9-70b6-4e3b-b6a6-6c2d1865982b-1683016746649/node_modules/@ethersproject-xdc/signing-key" + "@ethersproject-xdc/transactions" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-wallet-5.6.0-c6faf6f9-70b6-4e3b-b6a6-6c2d1865982b-1683016746649/node_modules/@ethersproject-xdc/transactions" + "@ethersproject-xdc/wordlists" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-wallet-5.6.0-c6faf6f9-70b6-4e3b-b6a6-6c2d1865982b-1683016746649/node_modules/@ethersproject-xdc/wordlists" "@ethersproject-xdc/web@file:vendor/@ethersproject-xdc/web": version "5.7.1" dependencies: - "@ethersproject-xdc/base64" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-web-5.7.1-4353037b-bc0d-4fed-b514-31a64d4c9607-1682382909346/node_modules/@ethersproject-xdc/base64" - "@ethersproject-xdc/bytes" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-web-5.7.1-4353037b-bc0d-4fed-b514-31a64d4c9607-1682382909346/node_modules/@ethersproject-xdc/bytes" - "@ethersproject-xdc/logger" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-web-5.7.1-4353037b-bc0d-4fed-b514-31a64d4c9607-1682382909346/node_modules/@ethersproject-xdc/logger" - "@ethersproject-xdc/properties" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-web-5.7.1-4353037b-bc0d-4fed-b514-31a64d4c9607-1682382909346/node_modules/@ethersproject-xdc/properties" - "@ethersproject-xdc/strings" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-web-5.7.1-4353037b-bc0d-4fed-b514-31a64d4c9607-1682382909346/node_modules/@ethersproject-xdc/strings" + "@ethersproject-xdc/base64" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-web-5.7.1-177911e6-2b63-41dc-8b07-e56eaff3ba24-1683016746650/node_modules/@ethersproject-xdc/base64" + "@ethersproject-xdc/bytes" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-web-5.7.1-177911e6-2b63-41dc-8b07-e56eaff3ba24-1683016746650/node_modules/@ethersproject-xdc/bytes" + "@ethersproject-xdc/logger" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-web-5.7.1-177911e6-2b63-41dc-8b07-e56eaff3ba24-1683016746650/node_modules/@ethersproject-xdc/logger" + "@ethersproject-xdc/properties" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-web-5.7.1-177911e6-2b63-41dc-8b07-e56eaff3ba24-1683016746650/node_modules/@ethersproject-xdc/properties" + "@ethersproject-xdc/strings" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-web-5.7.1-177911e6-2b63-41dc-8b07-e56eaff3ba24-1683016746650/node_modules/@ethersproject-xdc/strings" "@ethersproject-xdc/wordlists@file:vendor/@ethersproject-xdc/wordlists": version "5.7.0" dependencies: - "@ethersproject-xdc/bytes" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-wordlists-5.7.0-2494c801-bd8a-4957-85b5-475e925c7d5e-1682382909346/node_modules/@ethersproject-xdc/bytes" - "@ethersproject-xdc/hash" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-wordlists-5.7.0-2494c801-bd8a-4957-85b5-475e925c7d5e-1682382909346/node_modules/@ethersproject-xdc/hash" - "@ethersproject-xdc/logger" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-wordlists-5.7.0-2494c801-bd8a-4957-85b5-475e925c7d5e-1682382909346/node_modules/@ethersproject-xdc/logger" - "@ethersproject-xdc/properties" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-wordlists-5.7.0-2494c801-bd8a-4957-85b5-475e925c7d5e-1682382909346/node_modules/@ethersproject-xdc/properties" - "@ethersproject-xdc/strings" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-wordlists-5.7.0-2494c801-bd8a-4957-85b5-475e925c7d5e-1682382909346/node_modules/@ethersproject-xdc/strings" + "@ethersproject-xdc/bytes" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-wordlists-5.7.0-4275385e-be8e-4a9f-bbf3-e531bf3d76fe-1683016746650/node_modules/@ethersproject-xdc/bytes" + "@ethersproject-xdc/hash" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-wordlists-5.7.0-4275385e-be8e-4a9f-bbf3-e531bf3d76fe-1683016746650/node_modules/@ethersproject-xdc/hash" + "@ethersproject-xdc/logger" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-wordlists-5.7.0-4275385e-be8e-4a9f-bbf3-e531bf3d76fe-1683016746650/node_modules/@ethersproject-xdc/logger" + "@ethersproject-xdc/properties" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-wordlists-5.7.0-4275385e-be8e-4a9f-bbf3-e531bf3d76fe-1683016746650/node_modules/@ethersproject-xdc/properties" + "@ethersproject-xdc/strings" "file:../../../../Library/Caches/Yarn/v6/npm-@ethersproject-xdc-wordlists-5.7.0-4275385e-be8e-4a9f-bbf3-e531bf3d76fe-1683016746650/node_modules/@ethersproject-xdc/strings" "@ethersproject/abi@5.7.0", "@ethersproject/abi@^5.0.12", "@ethersproject/abi@^5.1.2", "@ethersproject/abi@^5.4.0", "@ethersproject/abi@^5.5.0", "@ethersproject/abi@^5.6.3", "@ethersproject/abi@^5.7.0": version "5.7.0" @@ -3342,17 +3342,17 @@ resolved "https://registry.yarnpkg.com/@pedrouid/environment/-/environment-1.0.1.tgz#858f0f8a057340e0b250398b75ead77d6f4342ec" integrity sha512-HaW78NszGzRZd9SeoI3JD11JqY+lubnaOx7Pewj5pfjqWXOEATpeKIFb9Z4t2WBUK2iryiXX3lzWwmYWgUL0Ug== -"@perp/curie-deployments@2022.12.20-1671509278203": - version "2022.12.20-1671509278203" - resolved "https://registry.yarnpkg.com/@perp/curie-deployments/-/curie-deployments-2022.12.20-1671509278203.tgz#16c716936741df41cd91171d3d75575eb49971d8" - integrity sha512-zEHFTzg7S/4V2uRmFQZVrQDghWE8uyMYedp/tMdgKdNCiUaGbsm7c0dBAdO1HxFA49JrshhefJ9rjoaCMLvGTQ== +"@perp/curie-deployments@2023.4.12-1681295833590": + version "2023.4.12-1681295833590" + resolved "https://registry.yarnpkg.com/@perp/curie-deployments/-/curie-deployments-2023.4.12-1681295833590.tgz#d4f0afe189ec37799dc32b53242db56fc18f2f14" + integrity sha512-NJbTy3frix5AQS5Bk/littykkmQ/m1rFD5HUQG8b0SDVGsqvIsSr5NSlhwb+UGJS7EHtgxevh4P4dTPc4dN6lQ== "@perp/sdk-curie@^1.16.0": - version "1.18.0" - resolved "https://registry.yarnpkg.com/@perp/sdk-curie/-/sdk-curie-1.18.0.tgz#8b1400390b066ed6109140d7c2ae7f42462e932e" - integrity sha512-im2uk0xq42PzLw2OHcDmp/I9Nie1eSBD0D+xFd4N6MlJ1ilVSzex88jdZfxJJG9aKts9DLxNNzz6hFh0poDxGA== + version "1.20.0" + resolved "https://registry.yarnpkg.com/@perp/sdk-curie/-/sdk-curie-1.20.0.tgz#3d070a3626b35d605003523705d9781c8a6e711e" + integrity sha512-J1cVhqfbI04glsDZjbZT82OG31U9yLRzc4pPVBhEhzMk74PY8EhiO6BDbo8X/5AreMQk+8HKzbSXr/FhBR6yag== dependencies: - "@perp/curie-deployments" "2022.12.20-1671509278203" + "@perp/curie-deployments" "2023.4.12-1681295833590" cross-fetch "3.1.5" exponential-backoff "3.1.0" @@ -4304,6 +4304,14 @@ dependencies: defer-to-connect "^2.0.1" +"@tinymanorg/tinyman-js-sdk@^3.0.0": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@tinymanorg/tinyman-js-sdk/-/tinyman-js-sdk-3.0.0.tgz#878f6e07641dfe1fda086cfefc292bc74507e529" + integrity sha512-i/rly864c1rTD1kqyFhJa87VXW6b2xkDJeBPhR1pSsXn0+IzZr0PKktc5rCfpHnS5zR23NNwtHY3yNOPGBNy2g== + dependencies: + algosdk "^2.1.0" + base64-js "^1.5.1" + "@tootallnate/once@1": version "1.1.2" resolved "https://registry.yarnpkg.com/@tootallnate/once/-/once-1.1.2.tgz#ccb91445360179a04e7fe6aff78c00ffc1eeaf82" @@ -6062,6 +6070,27 @@ alchemy-sdk@^2.6.3: sturdy-websocket "^0.2.1" websocket "^1.0.34" +algo-msgpack-with-bigint@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/algo-msgpack-with-bigint/-/algo-msgpack-with-bigint-2.1.1.tgz#38bb717220525b3ff42232eefdcd9efb9ad405d6" + integrity sha512-F1tGh056XczEaEAqu7s+hlZUDWwOBT70Eq0lfMpBP2YguSQVyxRbprLq5rELXKQOyOaixTWYhMeMQMzP0U5FoQ== + +algosdk@^2.1.0, algosdk@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/algosdk/-/algosdk-2.2.0.tgz#12f80b5f68c955b338aa5b9d5fc6cbd64ce6ea7a" + integrity sha512-FG3u/60DzjMK9Cffy9itst7WcfsTgZKfsD1r8pT33PfsA7r8NoXiUSL7cf0fNWFus6S3E14BpE2CY64VJ8KV1A== + dependencies: + algo-msgpack-with-bigint "^2.1.1" + buffer "^6.0.3" + cross-fetch "^3.1.5" + hi-base32 "^0.5.1" + js-sha256 "^0.9.0" + js-sha3 "^0.8.0" + js-sha512 "^0.8.0" + json-bigint "^1.0.0" + tweetnacl "^1.0.3" + vlq "^2.0.4" + ansi-colors@4.1.1: version "4.1.1" resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-4.1.1.tgz#cbb9ae256bf750af1eab344f229aa27fe94ba348" @@ -6608,7 +6637,7 @@ base-x@^4.0.0: resolved "https://registry.yarnpkg.com/base-x/-/base-x-4.0.0.tgz#d0e3b7753450c73f8ad2389b5c018a4af7b2224a" integrity sha512-FuwxlW4H5kh37X/oW59pwTzzTKRzfrrQwhmyspRM7swOEZcHtDZSCt45U6oKgtuFE+WYPblePMVIPR4RZrh/hw== -base64-js@^1.0.2, base64-js@^1.3.0, base64-js@^1.3.1: +base64-js@^1.0.2, base64-js@^1.3.0, base64-js@^1.3.1, base64-js@^1.5.1: version "1.5.1" resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a" integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA== @@ -9218,36 +9247,36 @@ ethereumjs-util@^6.0.0, ethereumjs-util@^6.1.0, ethereumjs-util@^6.2.1: "ethers-xdc@file:./vendor/ethers-xdc": version "5.7.2" dependencies: - "@ethersproject-xdc/abi" "file:../../../../Library/Caches/Yarn/v6/npm-ethers-xdc-5.7.2-2666e0ab-58fa-4b44-8fc3-a84f63fe4598-1682382909330/node_modules/@ethersproject-xdc/abi" - "@ethersproject-xdc/abstract-provider" "file:../../../../Library/Caches/Yarn/v6/npm-ethers-xdc-5.7.2-2666e0ab-58fa-4b44-8fc3-a84f63fe4598-1682382909330/node_modules/@ethersproject-xdc/abstract-provider" - "@ethersproject-xdc/abstract-signer" "file:../../../../Library/Caches/Yarn/v6/npm-ethers-xdc-5.7.2-2666e0ab-58fa-4b44-8fc3-a84f63fe4598-1682382909330/node_modules/@ethersproject-xdc/abstract-signer" - "@ethersproject-xdc/address" "file:../../../../Library/Caches/Yarn/v6/npm-ethers-xdc-5.7.2-2666e0ab-58fa-4b44-8fc3-a84f63fe4598-1682382909330/node_modules/@ethersproject-xdc/address" - "@ethersproject-xdc/base64" "file:../../../../Library/Caches/Yarn/v6/npm-ethers-xdc-5.7.2-2666e0ab-58fa-4b44-8fc3-a84f63fe4598-1682382909330/node_modules/@ethersproject-xdc/base64" - "@ethersproject-xdc/basex" "file:../../../../Library/Caches/Yarn/v6/npm-ethers-xdc-5.7.2-2666e0ab-58fa-4b44-8fc3-a84f63fe4598-1682382909330/node_modules/@ethersproject-xdc/basex" - "@ethersproject-xdc/bignumber" "file:../../../../Library/Caches/Yarn/v6/npm-ethers-xdc-5.7.2-2666e0ab-58fa-4b44-8fc3-a84f63fe4598-1682382909330/node_modules/@ethersproject-xdc/bignumber" - "@ethersproject-xdc/bytes" "file:../../../../Library/Caches/Yarn/v6/npm-ethers-xdc-5.7.2-2666e0ab-58fa-4b44-8fc3-a84f63fe4598-1682382909330/node_modules/@ethersproject-xdc/bytes" - "@ethersproject-xdc/constants" "file:../../../../Library/Caches/Yarn/v6/npm-ethers-xdc-5.7.2-2666e0ab-58fa-4b44-8fc3-a84f63fe4598-1682382909330/node_modules/@ethersproject-xdc/constants" - "@ethersproject-xdc/contracts" "file:../../../../Library/Caches/Yarn/v6/npm-ethers-xdc-5.7.2-2666e0ab-58fa-4b44-8fc3-a84f63fe4598-1682382909330/node_modules/@ethersproject-xdc/contracts" - "@ethersproject-xdc/hash" "file:../../../../Library/Caches/Yarn/v6/npm-ethers-xdc-5.7.2-2666e0ab-58fa-4b44-8fc3-a84f63fe4598-1682382909330/node_modules/@ethersproject-xdc/hash" - "@ethersproject-xdc/hdnode" "file:../../../../Library/Caches/Yarn/v6/npm-ethers-xdc-5.7.2-2666e0ab-58fa-4b44-8fc3-a84f63fe4598-1682382909330/node_modules/@ethersproject-xdc/hdnode" - "@ethersproject-xdc/json-wallets" "file:../../../../Library/Caches/Yarn/v6/npm-ethers-xdc-5.7.2-2666e0ab-58fa-4b44-8fc3-a84f63fe4598-1682382909330/node_modules/@ethersproject-xdc/json-wallets" - "@ethersproject-xdc/keccak256" "file:../../../../Library/Caches/Yarn/v6/npm-ethers-xdc-5.7.2-2666e0ab-58fa-4b44-8fc3-a84f63fe4598-1682382909330/node_modules/@ethersproject-xdc/keccak256" - "@ethersproject-xdc/logger" "file:../../../../Library/Caches/Yarn/v6/npm-ethers-xdc-5.7.2-2666e0ab-58fa-4b44-8fc3-a84f63fe4598-1682382909330/node_modules/@ethersproject-xdc/logger" - "@ethersproject-xdc/networks" "file:../../../../Library/Caches/Yarn/v6/npm-ethers-xdc-5.7.2-2666e0ab-58fa-4b44-8fc3-a84f63fe4598-1682382909330/node_modules/@ethersproject-xdc/networks" - "@ethersproject-xdc/pbkdf2" "file:../../../../Library/Caches/Yarn/v6/npm-ethers-xdc-5.7.2-2666e0ab-58fa-4b44-8fc3-a84f63fe4598-1682382909330/node_modules/@ethersproject-xdc/pbkdf2" - "@ethersproject-xdc/properties" "file:../../../../Library/Caches/Yarn/v6/npm-ethers-xdc-5.7.2-2666e0ab-58fa-4b44-8fc3-a84f63fe4598-1682382909330/node_modules/@ethersproject-xdc/properties" - "@ethersproject-xdc/providers" "file:../../../../Library/Caches/Yarn/v6/npm-ethers-xdc-5.7.2-2666e0ab-58fa-4b44-8fc3-a84f63fe4598-1682382909330/node_modules/@ethersproject-xdc/providers" - "@ethersproject-xdc/random" "file:../../../../Library/Caches/Yarn/v6/npm-ethers-xdc-5.7.2-2666e0ab-58fa-4b44-8fc3-a84f63fe4598-1682382909330/node_modules/@ethersproject-xdc/random" - "@ethersproject-xdc/rlp" "file:../../../../Library/Caches/Yarn/v6/npm-ethers-xdc-5.7.2-2666e0ab-58fa-4b44-8fc3-a84f63fe4598-1682382909330/node_modules/@ethersproject-xdc/rlp" - "@ethersproject-xdc/sha2" "file:../../../../Library/Caches/Yarn/v6/npm-ethers-xdc-5.7.2-2666e0ab-58fa-4b44-8fc3-a84f63fe4598-1682382909330/node_modules/@ethersproject-xdc/sha2" - "@ethersproject-xdc/signing-key" "file:../../../../Library/Caches/Yarn/v6/npm-ethers-xdc-5.7.2-2666e0ab-58fa-4b44-8fc3-a84f63fe4598-1682382909330/node_modules/@ethersproject-xdc/signing-key" - "@ethersproject-xdc/solidity" "file:../../../../Library/Caches/Yarn/v6/npm-ethers-xdc-5.7.2-2666e0ab-58fa-4b44-8fc3-a84f63fe4598-1682382909330/node_modules/@ethersproject-xdc/solidity" - "@ethersproject-xdc/strings" "file:../../../../Library/Caches/Yarn/v6/npm-ethers-xdc-5.7.2-2666e0ab-58fa-4b44-8fc3-a84f63fe4598-1682382909330/node_modules/@ethersproject-xdc/strings" - "@ethersproject-xdc/transactions" "file:../../../../Library/Caches/Yarn/v6/npm-ethers-xdc-5.7.2-2666e0ab-58fa-4b44-8fc3-a84f63fe4598-1682382909330/node_modules/@ethersproject-xdc/transactions" - "@ethersproject-xdc/units" "file:../../../../Library/Caches/Yarn/v6/npm-ethers-xdc-5.7.2-2666e0ab-58fa-4b44-8fc3-a84f63fe4598-1682382909330/node_modules/@ethersproject-xdc/units" - "@ethersproject-xdc/wallet" "file:../../../../Library/Caches/Yarn/v6/npm-ethers-xdc-5.7.2-2666e0ab-58fa-4b44-8fc3-a84f63fe4598-1682382909330/node_modules/@ethersproject-xdc/wallet" - "@ethersproject-xdc/web" "file:../../../../Library/Caches/Yarn/v6/npm-ethers-xdc-5.7.2-2666e0ab-58fa-4b44-8fc3-a84f63fe4598-1682382909330/node_modules/@ethersproject-xdc/web" - "@ethersproject-xdc/wordlists" "file:../../../../Library/Caches/Yarn/v6/npm-ethers-xdc-5.7.2-2666e0ab-58fa-4b44-8fc3-a84f63fe4598-1682382909330/node_modules/@ethersproject-xdc/wordlists" + "@ethersproject-xdc/abi" "file:../../../../Library/Caches/Yarn/v6/npm-ethers-xdc-5.7.2-3437d327-444f-450b-8c5b-20880cd20b26-1683016746628/node_modules/@ethersproject-xdc/abi" + "@ethersproject-xdc/abstract-provider" "file:../../../../Library/Caches/Yarn/v6/npm-ethers-xdc-5.7.2-3437d327-444f-450b-8c5b-20880cd20b26-1683016746628/node_modules/@ethersproject-xdc/abstract-provider" + "@ethersproject-xdc/abstract-signer" "file:../../../../Library/Caches/Yarn/v6/npm-ethers-xdc-5.7.2-3437d327-444f-450b-8c5b-20880cd20b26-1683016746628/node_modules/@ethersproject-xdc/abstract-signer" + "@ethersproject-xdc/address" "file:../../../../Library/Caches/Yarn/v6/npm-ethers-xdc-5.7.2-3437d327-444f-450b-8c5b-20880cd20b26-1683016746628/node_modules/@ethersproject-xdc/address" + "@ethersproject-xdc/base64" "file:../../../../Library/Caches/Yarn/v6/npm-ethers-xdc-5.7.2-3437d327-444f-450b-8c5b-20880cd20b26-1683016746628/node_modules/@ethersproject-xdc/base64" + "@ethersproject-xdc/basex" "file:../../../../Library/Caches/Yarn/v6/npm-ethers-xdc-5.7.2-3437d327-444f-450b-8c5b-20880cd20b26-1683016746628/node_modules/@ethersproject-xdc/basex" + "@ethersproject-xdc/bignumber" "file:../../../../Library/Caches/Yarn/v6/npm-ethers-xdc-5.7.2-3437d327-444f-450b-8c5b-20880cd20b26-1683016746628/node_modules/@ethersproject-xdc/bignumber" + "@ethersproject-xdc/bytes" "file:../../../../Library/Caches/Yarn/v6/npm-ethers-xdc-5.7.2-3437d327-444f-450b-8c5b-20880cd20b26-1683016746628/node_modules/@ethersproject-xdc/bytes" + "@ethersproject-xdc/constants" "file:../../../../Library/Caches/Yarn/v6/npm-ethers-xdc-5.7.2-3437d327-444f-450b-8c5b-20880cd20b26-1683016746628/node_modules/@ethersproject-xdc/constants" + "@ethersproject-xdc/contracts" "file:../../../../Library/Caches/Yarn/v6/npm-ethers-xdc-5.7.2-3437d327-444f-450b-8c5b-20880cd20b26-1683016746628/node_modules/@ethersproject-xdc/contracts" + "@ethersproject-xdc/hash" "file:../../../../Library/Caches/Yarn/v6/npm-ethers-xdc-5.7.2-3437d327-444f-450b-8c5b-20880cd20b26-1683016746628/node_modules/@ethersproject-xdc/hash" + "@ethersproject-xdc/hdnode" "file:../../../../Library/Caches/Yarn/v6/npm-ethers-xdc-5.7.2-3437d327-444f-450b-8c5b-20880cd20b26-1683016746628/node_modules/@ethersproject-xdc/hdnode" + "@ethersproject-xdc/json-wallets" "file:../../../../Library/Caches/Yarn/v6/npm-ethers-xdc-5.7.2-3437d327-444f-450b-8c5b-20880cd20b26-1683016746628/node_modules/@ethersproject-xdc/json-wallets" + "@ethersproject-xdc/keccak256" "file:../../../../Library/Caches/Yarn/v6/npm-ethers-xdc-5.7.2-3437d327-444f-450b-8c5b-20880cd20b26-1683016746628/node_modules/@ethersproject-xdc/keccak256" + "@ethersproject-xdc/logger" "file:../../../../Library/Caches/Yarn/v6/npm-ethers-xdc-5.7.2-3437d327-444f-450b-8c5b-20880cd20b26-1683016746628/node_modules/@ethersproject-xdc/logger" + "@ethersproject-xdc/networks" "file:../../../../Library/Caches/Yarn/v6/npm-ethers-xdc-5.7.2-3437d327-444f-450b-8c5b-20880cd20b26-1683016746628/node_modules/@ethersproject-xdc/networks" + "@ethersproject-xdc/pbkdf2" "file:../../../../Library/Caches/Yarn/v6/npm-ethers-xdc-5.7.2-3437d327-444f-450b-8c5b-20880cd20b26-1683016746628/node_modules/@ethersproject-xdc/pbkdf2" + "@ethersproject-xdc/properties" "file:../../../../Library/Caches/Yarn/v6/npm-ethers-xdc-5.7.2-3437d327-444f-450b-8c5b-20880cd20b26-1683016746628/node_modules/@ethersproject-xdc/properties" + "@ethersproject-xdc/providers" "file:../../../../Library/Caches/Yarn/v6/npm-ethers-xdc-5.7.2-3437d327-444f-450b-8c5b-20880cd20b26-1683016746628/node_modules/@ethersproject-xdc/providers" + "@ethersproject-xdc/random" "file:../../../../Library/Caches/Yarn/v6/npm-ethers-xdc-5.7.2-3437d327-444f-450b-8c5b-20880cd20b26-1683016746628/node_modules/@ethersproject-xdc/random" + "@ethersproject-xdc/rlp" "file:../../../../Library/Caches/Yarn/v6/npm-ethers-xdc-5.7.2-3437d327-444f-450b-8c5b-20880cd20b26-1683016746628/node_modules/@ethersproject-xdc/rlp" + "@ethersproject-xdc/sha2" "file:../../../../Library/Caches/Yarn/v6/npm-ethers-xdc-5.7.2-3437d327-444f-450b-8c5b-20880cd20b26-1683016746628/node_modules/@ethersproject-xdc/sha2" + "@ethersproject-xdc/signing-key" "file:../../../../Library/Caches/Yarn/v6/npm-ethers-xdc-5.7.2-3437d327-444f-450b-8c5b-20880cd20b26-1683016746628/node_modules/@ethersproject-xdc/signing-key" + "@ethersproject-xdc/solidity" "file:../../../../Library/Caches/Yarn/v6/npm-ethers-xdc-5.7.2-3437d327-444f-450b-8c5b-20880cd20b26-1683016746628/node_modules/@ethersproject-xdc/solidity" + "@ethersproject-xdc/strings" "file:../../../../Library/Caches/Yarn/v6/npm-ethers-xdc-5.7.2-3437d327-444f-450b-8c5b-20880cd20b26-1683016746628/node_modules/@ethersproject-xdc/strings" + "@ethersproject-xdc/transactions" "file:../../../../Library/Caches/Yarn/v6/npm-ethers-xdc-5.7.2-3437d327-444f-450b-8c5b-20880cd20b26-1683016746628/node_modules/@ethersproject-xdc/transactions" + "@ethersproject-xdc/units" "file:../../../../Library/Caches/Yarn/v6/npm-ethers-xdc-5.7.2-3437d327-444f-450b-8c5b-20880cd20b26-1683016746628/node_modules/@ethersproject-xdc/units" + "@ethersproject-xdc/wallet" "file:../../../../Library/Caches/Yarn/v6/npm-ethers-xdc-5.7.2-3437d327-444f-450b-8c5b-20880cd20b26-1683016746628/node_modules/@ethersproject-xdc/wallet" + "@ethersproject-xdc/web" "file:../../../../Library/Caches/Yarn/v6/npm-ethers-xdc-5.7.2-3437d327-444f-450b-8c5b-20880cd20b26-1683016746628/node_modules/@ethersproject-xdc/web" + "@ethersproject-xdc/wordlists" "file:../../../../Library/Caches/Yarn/v6/npm-ethers-xdc-5.7.2-3437d327-444f-450b-8c5b-20880cd20b26-1683016746628/node_modules/@ethersproject-xdc/wordlists" ethers@4.0.0-beta.3: version "4.0.0-beta.3" @@ -10617,6 +10646,11 @@ hexoid@^1.0.0: resolved "https://registry.yarnpkg.com/hexoid/-/hexoid-1.0.0.tgz#ad10c6573fb907de23d9ec63a711267d9dc9bc18" integrity sha512-QFLV0taWQOZtvIRIAdBChesmogZrtuXvVWsFHZTk2SU+anspqZ2vMnoLg7IE1+Uk16N19APic1BuF8bC8c2m5g== +hi-base32@^0.5.1: + version "0.5.1" + resolved "https://registry.yarnpkg.com/hi-base32/-/hi-base32-0.5.1.tgz#1279f2ddae2673219ea5870c2121d2a33132857e" + integrity sha512-EmBBpvdYh/4XxsnUybsPag6VikPYnN30td+vQk+GI3qpahVEG9+gTkG0aXVxTjBqQ5T6ijbWIu77O+C5WFWsnA== + hmac-drbg@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/hmac-drbg/-/hmac-drbg-1.0.1.tgz#d2745701025a6c775a6c545793ed502fc0c649a1" @@ -11899,6 +11933,11 @@ js-sha3@0.8.0, js-sha3@^0.8.0: resolved "https://registry.yarnpkg.com/js-sha3/-/js-sha3-0.8.0.tgz#b9b7a5da73afad7dedd0f8c463954cbde6818840" integrity sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q== +js-sha512@^0.8.0: + version "0.8.0" + resolved "https://registry.yarnpkg.com/js-sha512/-/js-sha512-0.8.0.tgz#dd22db8d02756faccf19f218e3ed61ec8249f7d4" + integrity sha512-PWsmefG6Jkodqt+ePTvBZCSMFgN7Clckjd0O7su3I0+BW2QWUTJNzjktHsztGLhncP2h8mcF9V9Y2Ha59pAViQ== + "js-tokens@^3.0.0 || ^4.0.0", js-tokens@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" @@ -11977,6 +12016,13 @@ jsesc@^2.5.1: resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-2.5.2.tgz#80564d2e483dacf6e8ef209650a67df3f0c283a4" integrity sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA== +json-bigint@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/json-bigint/-/json-bigint-1.0.0.tgz#ae547823ac0cad8398667f8cd9ef4730f5b01ff1" + integrity sha512-SiPv/8VpZuWbvLSMtTDU8hEfrZWg/mH/nV/b4o0CYbSxu1UIQPLdwKOCIyLQX+VIPO5vrLX3i8qtqFyhdPSUSQ== + dependencies: + bignumber.js "^9.0.0" + json-buffer@3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/json-buffer/-/json-buffer-3.0.0.tgz#5b1f397afc75d677bde8bcfc0e47e1f9a3d9a898" @@ -17113,6 +17159,11 @@ verror@1.10.0: core-util-is "1.0.2" extsprintf "^1.2.0" +vlq@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/vlq/-/vlq-2.0.4.tgz#6057b85729245b9829e3cc7755f95b228d4fe041" + integrity sha512-aodjPa2wPQFkra1G8CzJBTHXhgk3EVSwxSWXNPr1fgdFLUb8kvLV1iEb6rFgasIsjP82HWI6dsb5Io26DDnasA== + vuvuzela@1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/vuvuzela/-/vuvuzela-1.0.3.tgz#3be145e58271c73ca55279dd851f12a682114b0b"