diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b91f7d2373..a050488c54 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -52,6 +52,8 @@ jobs: - uses: codecov/codecov-action@eaaf4bedf32dbdc6b720b63067d99c4d77d6047d # v3.1.4 with: fail_ci_if_error: true + env: + CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} docker-sanity: needs: [ build, lint ] diff --git a/.gitignore b/.gitignore index a28feb453f..b0fdf16783 100644 --- a/.gitignore +++ b/.gitignore @@ -33,6 +33,9 @@ dist # debug log lerna-debug.log +# debug dump +dump + coverage # vscode diff --git a/apps/package.json b/apps/package.json index 5b6b43534e..b9b30010e5 100644 --- a/apps/package.json +++ b/apps/package.json @@ -43,16 +43,17 @@ "class-transformer": "0.5.1", "class-validator": "0.14.0", "cross-fetch": "3.1.5", + "fast-csv": "^4.3.6", "graphology": "0.25.1", "graphology-components": "1.5.4", "graphology-simple-path": "0.1.2", "joi": "17.8.4", - "lodash": "4.17.21", "level": "7.0.0", "level-js": "6.0.0", "level-packager": "6.0.0", "leveldown": "6.0.0", "lexicographic-integer-encoding": "1.0.1", + "lodash": "4.17.21", "memdown": "6.1.1", "pg": "8.9.0", "reflect-metadata": "0.1.13", @@ -67,9 +68,9 @@ "@types/cache-manager": "4.0.2", "@types/cron": "2.0.1", "@types/express": "4.17.17", - "@types/lodash": "4.14.194", "@types/level": "^6.0.0", "@types/levelup": "4.3.1", + "@types/lodash": "4.14.194", "@types/lossless-json": "1.0.1", "@types/memdown": "3.0.1", "@types/node": "16.11.58", diff --git a/apps/playground-api/__tests__/modules/PlaygroundModule.test.ts b/apps/playground-api/__tests__/modules/PlaygroundModule.test.ts index 1330fe2c70..3a940a6f4d 100644 --- a/apps/playground-api/__tests__/modules/PlaygroundModule.test.ts +++ b/apps/playground-api/__tests__/modules/PlaygroundModule.test.ts @@ -1,5 +1,5 @@ -import { RegTestFoundationKeys } from '@defichain/jellyfish-network' -import { ConsortiumKey } from '../../src/ConsortiumKey' +// import { RegTestFoundationKeys } from '@defichain/jellyfish-network' +// import { ConsortiumKey } from '../../src/ConsortiumKey' import { PlaygroundApiTesting } from '../../testing/PlaygroundApiTesting' const pg = PlaygroundApiTesting.create() @@ -63,46 +63,46 @@ it('should have gov set', async () => { const gov = await testing.container.call('getgov', ['ATTRIBUTES']) expect(gov).toStrictEqual({ ATTRIBUTES: { - 'v0/consortium/1/members': { - '01': { - backingId: 'backing_address_btc_1_c', - mintLimit: 50, - mintLimitDaily: 5, - name: 'Waves HQ', - ownerAddress: ConsortiumKey.address, - status: 0 - }, - '02': { - backingId: 'backing_address_btc_1_br, backing_address_btc_2_br', - mintLimit: 50, - mintLimitDaily: 5, - name: 'Alexandria', - ownerAddress: RegTestFoundationKeys[RegTestFoundationKeys.length - 1].owner.address, - status: 0 - } - }, - 'v0/consortium/2/members': { - '01': { - backingId: 'backing_address_eth_1_c', - mintLimit: 10, - mintLimitDaily: 5, - name: 'Waves HQ', - ownerAddress: ConsortiumKey.address, - status: 0 - }, - '02': { - backingId: 'backing_address_eth_1_br, backing_address_eth_2_br', - mintLimit: 10, - mintLimitDaily: 5, - name: 'Alexandria', - ownerAddress: RegTestFoundationKeys[RegTestFoundationKeys.length - 1].owner.address, - status: 0 - } - }, - 'v0/consortium/1/mint_limit': '50', - 'v0/consortium/1/mint_limit_daily': '5', - 'v0/consortium/2/mint_limit': '20', - 'v0/consortium/2/mint_limit_daily': '10', + // 'v0/consortium/1/members': { + // '01': { + // backingId: 'backing_address_btc_1_c', + // mintLimit: 50, + // mintLimitDaily: 5, + // name: 'Waves HQ', + // ownerAddress: ConsortiumKey.address, + // status: 0 + // }, + // '02': { + // backingId: 'backing_address_btc_1_br, backing_address_btc_2_br', + // mintLimit: 50, + // mintLimitDaily: 5, + // name: 'Alexandria', + // ownerAddress: RegTestFoundationKeys[RegTestFoundationKeys.length - 1].owner.address, + // status: 0 + // } + // }, + // 'v0/consortium/2/members': { + // '01': { + // backingId: 'backing_address_eth_1_c', + // mintLimit: 10, + // mintLimitDaily: 5, + // name: 'Waves HQ', + // ownerAddress: ConsortiumKey.address, + // status: 0 + // }, + // '02': { + // backingId: 'backing_address_eth_1_br, backing_address_eth_2_br', + // mintLimit: 10, + // mintLimitDaily: 5, + // name: 'Alexandria', + // ownerAddress: RegTestFoundationKeys[RegTestFoundationKeys.length - 1].owner.address, + // status: 0 + // } + // }, + // 'v0/consortium/1/mint_limit': '50', + // 'v0/consortium/1/mint_limit_daily': '5', + // 'v0/consortium/2/mint_limit': '20', + // 'v0/consortium/2/mint_limit_daily': '10', 'v0/live/economy/evm/block/fee_burnt': 0, 'v0/live/economy/evm/block/fee_burnt_max': 0, 'v0/live/economy/evm/block/fee_burnt_max_hash': expect.any(String), @@ -118,7 +118,7 @@ it('should have gov set', async () => { 'v0/params/dfip2203/block_period': '20', 'v0/params/dfip2203/fee_pct': '0.05', 'v0/params/dfip2203/reward_pct': '0.05', - 'v0/params/feature/consortium': 'true', + // 'v0/params/feature/consortium': 'true', 'v0/params/feature/gov': 'true', 'v0/token/0/fixed_interval_price_id': 'DFI/USD', 'v0/token/0/loan_collateral_enabled': 'true', @@ -200,6 +200,7 @@ it('should have gov set', async () => { 'v0/token/18/loan_minting_enabled': 'true', 'v0/token/18/loan_minting_interest': '3', 'v0/params/feature/icx': 'true', + 'v0/vaults/dusd-vault/enabled': 'true', 'v0/params/feature/evm': 'true', 'v0/transferdomain/dvm-evm/dat-enabled': 'true', 'v0/transferdomain/evm-dvm/dat-enabled': 'true', diff --git a/apps/playground-api/src/setups/setup.gov.ts b/apps/playground-api/src/setups/setup.gov.ts index b345ee7614..61af001bc1 100644 --- a/apps/playground-api/src/setups/setup.gov.ts +++ b/apps/playground-api/src/setups/setup.gov.ts @@ -63,55 +63,58 @@ export class SetupGov extends PlaygroundSetup> { // Unloop mechanism for DUSD 'v0/token/14/loan_payback_collateral': 'true', + // Enable DUSD loop for loan + 'v0/vaults/dusd-vault/enabled': 'true', + // On-chain governance - 'v0/params/feature/gov': 'true', - - // Enable consortium - 'v0/params/feature/consortium': 'true', - - // Set a consortium global limit for dBTC - 'v0/consortium/1/mint_limit': '50', - 'v0/consortium/1/mint_limit_daily': '5', - - // Set a consortium member for dBTC - 'v0/consortium/1/members': { - '01': { - name: 'Waves HQ', - ownerAddress: this.consortiumOwnerAddress1, - backingId: 'backing_address_btc_1_c', - mintLimitDaily: '5.00000000', - mintLimit: '50.00000000' - }, - '02': { - name: 'Alexandria', - ownerAddress: this.consortiumOwnerAddress2, - backingId: 'backing_address_btc_1_br, backing_address_btc_2_br', - mintLimitDaily: '5.00000000', - mintLimit: '50.00000000' - } - }, - - // Consortium global limit for dETH - 'v0/consortium/2/mint_limit': '20', - 'v0/consortium/2/mint_limit_daily': '10', - - // Set a consortium member for dETH - 'v0/consortium/2/members': { - '01': { - name: 'Waves HQ', - ownerAddress: this.consortiumOwnerAddress1, - backingId: 'backing_address_eth_1_c', - mintLimitDaily: '5.00000000', - mintLimit: '10.00000000' - }, - '02': { - name: 'Alexandria', - ownerAddress: this.consortiumOwnerAddress2, - backingId: 'backing_address_eth_1_br, backing_address_eth_2_br', - mintLimitDaily: '5.00000000', - mintLimit: '10.00000000' - } - } + 'v0/params/feature/gov': 'true' + + // // Enable consortium + // 'v0/params/feature/consortium': 'true' + + // // Set a consortium global limit for dBTC + // 'v0/consortium/1/mint_limit': '50', + // 'v0/consortium/1/mint_limit_daily': '5', + + // // Set a consortium member for dBTC + // 'v0/consortium/1/members': { + // '01': { + // name: 'Waves HQ', + // ownerAddress: this.consortiumOwnerAddress1, + // backingId: 'backing_address_btc_1_c', + // mintLimitDaily: '5.00000000', + // mintLimit: '50.00000000' + // }, + // '02': { + // name: 'Alexandria', + // ownerAddress: this.consortiumOwnerAddress2, + // backingId: 'backing_address_btc_1_br, backing_address_btc_2_br', + // mintLimitDaily: '5.00000000', + // mintLimit: '50.00000000' + // } + // }, + + // // Consortium global limit for dETH + // 'v0/consortium/2/mint_limit': '20', + // 'v0/consortium/2/mint_limit_daily': '10', + + // // Set a consortium member for dETH + // 'v0/consortium/2/members': { + // '01': { + // name: 'Waves HQ', + // ownerAddress: this.consortiumOwnerAddress1, + // backingId: 'backing_address_eth_1_c', + // mintLimitDaily: '5.00000000', + // mintLimit: '10.00000000' + // }, + // '02': { + // name: 'Alexandria', + // ownerAddress: this.consortiumOwnerAddress2, + // backingId: 'backing_address_eth_1_br, backing_address_eth_2_br', + // mintLimitDaily: '5.00000000', + // mintLimit: '10.00000000' + // } + // } } } ] diff --git a/apps/whale-api/docker-compose.yml b/apps/whale-api/docker-compose.yml index 23c007a559..a7eff8d34e 100644 --- a/apps/whale-api/docker-compose.yml +++ b/apps/whale-api/docker-compose.yml @@ -2,7 +2,7 @@ version: "3.7" services: defi-blockchain: - image: defi/defichain:4.0.0-beta13 + image: defi/defichain:4.0.9 ports: - "19554:19554" @@ -42,7 +42,7 @@ services: -fortcanningepilogueheight=15 -grandcentralheight=16 -grandcentralepilogueheight=17 - -nextnetworkupgradeheight=18 + -metachainheight=18 -regtest-skip-loan-collateral-validation -regtest-minttoken-simulate-mainnet=0 diff --git a/apps/whale-api/src/app.configuration.ts b/apps/whale-api/src/app.configuration.ts index 92ef71d0f6..2832430650 100644 --- a/apps/whale-api/src/app.configuration.ts +++ b/apps/whale-api/src/app.configuration.ts @@ -23,7 +23,8 @@ export function AppConfiguration (): any { level: { location: process.env.WHALE_DATABASE_LEVEL_LOCATION } - } + }, + debug: process.env.WHALE_DEBUG } } @@ -34,6 +35,7 @@ export function ENV_VALIDATION_SCHEMA (): any { WHALE_NETWORK: Joi.string().valid('mainnet', 'testnet', 'regtest', 'devnet', 'changi').default('regtest'), WHALE_DEFID_URL: Joi.string().optional(), WHALE_DATABASE_PROVIDER: Joi.string().optional(), - WHALE_DATABASE_LEVEL_LOCATION: Joi.string().optional() + WHALE_DATABASE_LEVEL_LOCATION: Joi.string().optional(), + WHALE_DEBUG: Joi.bool().optional() }) } diff --git a/apps/whale-api/src/module.api/_module.ts b/apps/whale-api/src/module.api/_module.ts index 3c3589292b..ce68eb4a49 100644 --- a/apps/whale-api/src/module.api/_module.ts +++ b/apps/whale-api/src/module.api/_module.ts @@ -3,6 +3,7 @@ import { CacheModule, Global, Module } from '@nestjs/common' import { RpcController } from './rpc.controller' import { ActuatorController } from './actuator.controller' import { TransactionController } from './transaction.controller' +import { DebugController } from './debug.controller' import { ApiValidationPipe } from './pipes/api.validation.pipe' import { AddressController } from './address.controller' import { PoolPairController } from './poolpair.controller' @@ -62,6 +63,7 @@ import { GovernanceService } from './governance.service' LoanController, LegacyController, ConsortiumController, + DebugController, GovernanceController ], providers: [ diff --git a/apps/whale-api/src/module.api/address.controller.e2e.ts b/apps/whale-api/src/module.api/address.controller.e2e.ts index d9c80b7727..6323271cff 100644 --- a/apps/whale-api/src/module.api/address.controller.e2e.ts +++ b/apps/whale-api/src/module.api/address.controller.e2e.ts @@ -8,6 +8,7 @@ import { Testing } from '@defichain/jellyfish-testing' import { ForbiddenException } from '@nestjs/common' import BigNumber from 'bignumber.js' import { RegTestFoundationKeys } from '@defichain/jellyfish-network' +import { RpcApiError } from '@defichain/jellyfish-api-core/dist/index' const container = new MasterNodeRegTestContainer() let app: NestFastifyApplication @@ -1077,7 +1078,15 @@ describe('listTokens', () => { }) it('should return empty and page undefined while listTokens with invalid address', async () => { - const tokens = await controller.listTokens('invalid', { size: 30 }) - expect(tokens).toStrictEqual(expect.objectContaining({ data: [], page: undefined })) + try { + await controller.listTokens('invalid', { size: 30 }) + } catch (err: any) { + expect(err).toBeInstanceOf(RpcApiError) + expect(err.payload).toStrictEqual({ + code: -5, + message: 'Invalid owner address', + method: 'getaccount' + }) + } }) }) diff --git a/apps/whale-api/src/module.api/address.controller.spec.ts b/apps/whale-api/src/module.api/address.controller.spec.ts index c9e0bdaa39..34bd9cb724 100644 --- a/apps/whale-api/src/module.api/address.controller.spec.ts +++ b/apps/whale-api/src/module.api/address.controller.spec.ts @@ -5,6 +5,7 @@ import { Testing } from '@defichain/jellyfish-testing' import BigNumber from 'bignumber.js' import { createTestingApp, stopTestingApp } from '../e2e.module' import { NestFastifyApplication } from '@nestjs/platform-fastify' +import { RpcApiError } from '@defichain/jellyfish-api-core/dist/index' const container = new MasterNodeRegTestContainer() const testing = Testing.create(container) @@ -175,7 +176,15 @@ describe('listTokens', () => { }) it('should return empty and page undefined while listTokens with invalid address', async () => { - const tokens = await controller.listTokens('invalid', { size: 30 }) - expect(tokens).toStrictEqual(expect.objectContaining({ data: [], page: undefined })) + try { + await controller.listTokens('invalid', { size: 30 }) + } catch (err: any) { + expect(err).toBeInstanceOf(RpcApiError) + expect(err.payload).toStrictEqual({ + code: -5, + message: 'Invalid owner address', + method: 'getaccount' + }) + } }) }) diff --git a/apps/whale-api/src/module.api/consortium.controller.spec.ts b/apps/whale-api/src/module.api/consortium.controller.spec.ts index fdc53abe13..e226dd92ef 100644 --- a/apps/whale-api/src/module.api/consortium.controller.spec.ts +++ b/apps/whale-api/src/module.api/consortium.controller.spec.ts @@ -122,7 +122,7 @@ async function setup (): Promise { }]) } -describe('getAssetBreakdown', () => { +describe.skip('getAssetBreakdown', () => { it('should return an empty list if theres no consortium members or tokens initialized', async () => { const info = await controller.getAssetBreakdown() expect(info).toStrictEqual([]) @@ -188,7 +188,7 @@ describe('getAssetBreakdown', () => { }) }) -describe('getMemberStats', () => { +describe.skip('getMemberStats', () => { it('should throw an error if given consortium member id does not exists', async () => { await setup() diff --git a/apps/whale-api/src/module.api/debug.controller.ts b/apps/whale-api/src/module.api/debug.controller.ts new file mode 100644 index 0000000000..924624ce04 --- /dev/null +++ b/apps/whale-api/src/module.api/debug.controller.ts @@ -0,0 +1,18 @@ +import { Controller, ForbiddenException, Get } from '@nestjs/common' +import { Database } from '../module.database/database' + +@Controller('/debug') +export class DebugController { + constructor ( + protected readonly database: Database + ) { + } + + @Get('/dumpdb') + async dumpDb (): Promise { + if (process.env.WHALE_DEBUG === undefined) { + throw new ForbiddenException('Debug mode is not enabled') + } + await this.database.dump() + } +} diff --git a/apps/whale-api/src/module.api/rpc.controller.ts b/apps/whale-api/src/module.api/rpc.controller.ts index 09a2a8550f..6cc23d559e 100644 --- a/apps/whale-api/src/module.api/rpc.controller.ts +++ b/apps/whale-api/src/module.api/rpc.controller.ts @@ -43,7 +43,8 @@ export class MethodWhitelist implements PipeTransform { 'getgovproposal', 'listgovproposals', 'listgovproposalvotes', - 'vmmap' + 'vmmap', + 'gettxout' ] transform (value: string, metadata: ArgumentMetadata): string { diff --git a/apps/whale-api/src/module.api/stats.controller.ts b/apps/whale-api/src/module.api/stats.controller.ts index 9c4bec4126..56452cfaf3 100644 --- a/apps/whale-api/src/module.api/stats.controller.ts +++ b/apps/whale-api/src/module.api/stats.controller.ts @@ -1,4 +1,4 @@ -import { Controller, Get } from '@nestjs/common' +import { Controller, Get, Inject, NotFoundException } from '@nestjs/common' import { BurnData, RewardDistributionData, StatsData, SupplyData } from '@defichain/whale-api-client/dist/api/stats' import { SemaphoreCache } from '@defichain-apps/libs/caches' import { JsonRpcClient } from '@defichain/jellyfish-api-jsonrpc' @@ -11,6 +11,7 @@ import { BlockchainInfo } from '@defichain/jellyfish-api-core/dist/category/bloc import { getBlockSubsidy } from './subsidy' import { BlockSubsidy, + NetworkName, getBlockRewardDistribution } from '@defichain/jellyfish-network' import { BurnInfo } from '@defichain/jellyfish-api-core/dist/category/account' @@ -27,7 +28,8 @@ export class StatsController { protected readonly poolPairService: PoolPairService, protected readonly rpcClient: JsonRpcClient, protected readonly cache: SemaphoreCache, - protected readonly blockSubsidy: BlockSubsidy + protected readonly blockSubsidy: BlockSubsidy, + @Inject('NETWORK') protected readonly network: NetworkName ) { } @@ -210,13 +212,30 @@ export class StatsController { } } + private getBurnAddress (): string { + switch (this.network) { + case 'mainnet': + return '8defichainBurnAddressXXXXXXXdRQkSm' + case 'testnet': + case 'changi': + case 'devnet': + return '7DefichainBurnAddressXXXXXXXdMUE5n' + case 'regtest': + return 'mfburnZSAM7Gs1hpDeNaMotJXSGA7edosG' + default: + throw new NotFoundException('Unable to get burn address due to unknown network') + } + } + /** - * '76a914f7874e8821097615ec345f74c7e5bcf61b12e2ee88ac' is '8defichainBurnAddressXXXXXXXdRQkSm' - * using the hex representation as it's applicable in all network + * ~~'76a914f7874e8821097615ec345f74c7e5bcf61b12e2ee88ac' is '8defichainBurnAddressXXXXXXXdRQkSm'~~ + * ~~using the hex representation as it's applicable in all network~~ + * update: https://github.com/DeFiCh/ain/pull/2798 + * rpc `getaccount` only expects regular address, no more scriptpubkey */ private async getBurnedTotal (): Promise { - const address = '76a914f7874e8821097615ec345f74c7e5bcf61b12e2ee88ac' - const tokens = await this.rpcClient.account.getAccount(address) + const burnAddress = this.getBurnAddress() + const tokens = await this.rpcClient.account.getAccount(burnAddress) const burnInfo = await this.getBurnInfo() const utxo = burnInfo.amount diff --git a/apps/whale-api/src/module.database/database.spec/specifications.ts b/apps/whale-api/src/module.database/database.spec/specifications.ts index d646380fcb..776d484516 100644 --- a/apps/whale-api/src/module.database/database.spec/specifications.ts +++ b/apps/whale-api/src/module.database/database.spec/specifications.ts @@ -33,6 +33,11 @@ export async function shouldGetById (database: Database): Promise { } } +export async function shouldDump (database: Database): Promise { + const dump = await database.dump() + expect(dump).toBeTruthy() +} + export async function shouldGetByPartitionKey (database: Database): Promise { const index = PartitionMapping.index for (const data of PARTITIONS) { diff --git a/apps/whale-api/src/module.database/database.ts b/apps/whale-api/src/module.database/database.ts index 57ef00384c..345a595b0c 100644 --- a/apps/whale-api/src/module.database/database.ts +++ b/apps/whale-api/src/module.database/database.ts @@ -38,6 +38,8 @@ export abstract class Database { mapping: ModelMapping, id: string ): Promise + + abstract dump (): Promise } export enum SortOrder { diff --git a/apps/whale-api/src/module.database/provider.level/level.database.ts b/apps/whale-api/src/module.database/provider.level/level.database.ts index 6e1da834d0..5885c0f2bd 100644 --- a/apps/whale-api/src/module.database/provider.level/level.database.ts +++ b/apps/whale-api/src/module.database/provider.level/level.database.ts @@ -1,3 +1,6 @@ +import fs from 'fs' +import path from 'path' +import { format } from '@fast-csv/format' import sub from 'subleveldown' import level from 'level' import { LevelUp } from 'levelup' @@ -24,6 +27,40 @@ export abstract class LevelUpDatabase extends Database { await this.root.close() } + async dump (): Promise { + let id = 0 + const maxSize = 500_000 + const dir = path.join(process.cwd(), 'dump') + if (!fs.existsSync(dir)) { + fs.mkdirSync(dir) + } + let items: string[] = [] + return await new Promise((resolve, reject) => { + console.time('dump done in: ') + this.root.createReadStream() // query stream + .on('data', function (data) { + items.push(data) + if (items.length >= maxSize) { + const writer = fs.createWriteStream(`${dir}/dump-${id}.csv`) + const csv = format() + csv.pipe(writer) + items.forEach(i => csv.write(i)) + csv.end() + + items = [] + id += 1 + } + }).on('error', function (err) { + reject(err) + }).on('close', function () { + reject(new Error('stream closed')) + }).on('end', function () { + resolve(true) + console.timeEnd('dump done in: ') + }) + }) + } + /** * Sub index space for model indexes. */ diff --git a/apps/whale-api/src/module.database/provider.memory/memory.database.spec.ts b/apps/whale-api/src/module.database/provider.memory/memory.database.spec.ts index 975e3f83bc..ac9cf473a6 100644 --- a/apps/whale-api/src/module.database/provider.memory/memory.database.spec.ts +++ b/apps/whale-api/src/module.database/provider.memory/memory.database.spec.ts @@ -39,6 +39,10 @@ it('should delete and be deleted', async () => { await spec.shouldDelete(database) }) +it('should dump', async () => { + await spec.shouldDump(database) +}) + it('should query by partition pagination', async () => { await spec.shouldQueryPartitionPagination(database) }) diff --git a/apps/whale-api/src/module.indexer/model/dftx/composite.swap.ts b/apps/whale-api/src/module.indexer/model/dftx/composite.swap.ts index e8358b973a..29306bc03d 100644 --- a/apps/whale-api/src/module.indexer/model/dftx/composite.swap.ts +++ b/apps/whale-api/src/module.indexer/model/dftx/composite.swap.ts @@ -4,7 +4,6 @@ import { RawBlock } from '../_abstract' import { Inject, Injectable } from '@nestjs/common' import { NetworkName } from '@defichain/jellyfish-network' import BigNumber from 'bignumber.js' -import { IndexerError } from '../../error' import { PoolPairPathMapping } from './pool.pair.path.mapping' import { PoolSwapIndexer } from './pool.swap' @@ -51,10 +50,6 @@ export class CompositeSwapIndexer extends DfTxIndexer { const poolSwap = compositeSwap.poolSwap const pair = await this.poolPairPathMapping.findPair(poolSwap.fromTokenId, poolSwap.toTokenId) - if (pair !== undefined) { - return [{ id: Number(pair.id) }] - } - - throw new IndexerError(`Pool for pair ${poolSwap.fromTokenId}, ${poolSwap.toTokenId} not found in PoolPairPathMapping`) + return [{ id: Number(pair.id) }] } } diff --git a/apps/whale-api/src/module.indexer/model/dftx/pool.pair.path.mapping.ts b/apps/whale-api/src/module.indexer/model/dftx/pool.pair.path.mapping.ts index 050c52b94f..e32506b4b1 100644 --- a/apps/whale-api/src/module.indexer/model/dftx/pool.pair.path.mapping.ts +++ b/apps/whale-api/src/module.indexer/model/dftx/pool.pair.path.mapping.ts @@ -1,8 +1,9 @@ -import { Injectable } from '@nestjs/common' +import { Injectable, Logger } from '@nestjs/common' import { DeFiDCache, PoolPairInfoWithId } from '../../../module.api/cache/defid.cache' @Injectable() export class PoolPairPathMapping { + private readonly logger = new Logger(PoolPairPathMapping.name) private readonly paths: Record = {} constructor ( @@ -10,13 +11,17 @@ export class PoolPairPathMapping { ) { } - async findPair (tokenA: number, tokenB: number): Promise { + async findPair (tokenA: number, tokenB: number): Promise { const pair = this.paths[`${tokenA}-${tokenB}`] if (pair !== undefined) { return pair } await this.updateMapping() + if (this.paths[`${tokenA}-${tokenB}`] === undefined) { + this.logger.error(`Pool for pair ${tokenA}, ${tokenB} not found in PoolPairPathMapping`) + await this.findPair(tokenA, tokenB) + } return this.paths[`${tokenA}-${tokenB}`] } diff --git a/apps/whale-api/src/module.indexer/model/dftx/pool.swap.ts b/apps/whale-api/src/module.indexer/model/dftx/pool.swap.ts index 881ff707b4..c7b91afcb9 100644 --- a/apps/whale-api/src/module.indexer/model/dftx/pool.swap.ts +++ b/apps/whale-api/src/module.indexer/model/dftx/pool.swap.ts @@ -9,7 +9,6 @@ import { HexEncoder } from '../../../module.model/_hex.encoder' import { PoolSwapAggregatedMapper } from '../../../module.model/pool.swap.aggregated' import { AggregatedIntervals } from './pool.swap.aggregated' import { PoolPairInfoWithId } from '../../../module.api/cache/defid.cache' -import { IndexerError } from '../../error' import { PoolPairPathMapping } from './pool.pair.path.mapping' @Injectable() @@ -89,11 +88,6 @@ export class PoolSwapIndexer extends DfTxIndexer { } async getPair (tokenA: number, tokenB: number): Promise { - const pair = await this.poolPairPathMapping.findPair(tokenA, tokenB) - if (pair !== undefined) { - return pair - } - - throw new IndexerError(`Pool for pair ${tokenA}, ${tokenB} not found in PoolPairPathMapping`) + return await this.poolPairPathMapping.findPair(tokenA, tokenB) } } diff --git a/apps/whale-api/src/module.indexer/rpc.block.provider.ts b/apps/whale-api/src/module.indexer/rpc.block.provider.ts index 369ba308d6..bb66b2d231 100644 --- a/apps/whale-api/src/module.indexer/rpc.block.provider.ts +++ b/apps/whale-api/src/module.indexer/rpc.block.provider.ts @@ -6,6 +6,7 @@ import { Block, BlockMapper } from '../module.model/block' import { IndexStatusMapper, Status } from './status' import { waitForCondition } from '@defichain/testcontainers/dist/utils' import { blockchain as defid, RpcApiError } from '@defichain/jellyfish-api-core' +import { NotFoundIndexerError } from './error' @Injectable() export class RPCBlockProvider { @@ -90,6 +91,7 @@ export class RPCBlockProvider { if (await RPCBlockProvider.isBestChain(indexed, nextBlock)) { await this.index(nextBlock) } else { + this.logger.error(`indexedBlock{height: ${indexed.height}, hash: ${indexed.hash}}, nextBlock{height: ${nextBlock.height}, prevHash: ${nextBlock.previousblockhash}}`) await this.invalidate(indexed.hash, indexed.height) } return true @@ -100,7 +102,7 @@ export class RPCBlockProvider { * @param {defid.Block} nextBlock to check previous block hash */ private static async isBestChain (indexed: Block, nextBlock: defid.Block): Promise { - return nextBlock.previousblockhash === indexed.hash + return indexed.hash === nextBlock.previousblockhash } public async indexGenesis (): Promise { @@ -121,6 +123,7 @@ export class RPCBlockProvider { switch (status.status) { case Status.INVALIDATED: case Status.INDEXED: + case Status.REINDEX: return } @@ -149,7 +152,11 @@ export class RPCBlockProvider { await this.indexer.invalidate(hash) await this.statusMapper.put(hash, height, Status.INVALIDATED) } catch (err) { - await this.statusMapper.put(hash, height, Status.ERROR) + if (err instanceof NotFoundIndexerError) { + await this.statusMapper.put(hash, height, Status.REINDEX) + } else { + await this.statusMapper.put(hash, height, Status.ERROR) + } throw err } } diff --git a/apps/whale-api/src/module.indexer/status.ts b/apps/whale-api/src/module.indexer/status.ts index d170a9ad9a..f3d5751a27 100644 --- a/apps/whale-api/src/module.indexer/status.ts +++ b/apps/whale-api/src/module.indexer/status.ts @@ -36,7 +36,8 @@ export enum Status { INDEXED = 'INDEXED', INVALIDATING = 'INVALIDATING', INVALIDATED = 'INVALIDATED', - ERROR = 'ERROR' + ERROR = 'ERROR', + REINDEX = 'REINDEX' } export interface IndexStatus extends Model { diff --git a/docs/node/CATEGORIES/08-account.md b/docs/node/CATEGORIES/08-account.md index 29104d1a5e..16390bfa9f 100644 --- a/docs/node/CATEGORIES/08-account.md +++ b/docs/node/CATEGORIES/08-account.md @@ -159,7 +159,12 @@ Create a transfer domain transaction submitted to a connected node. ```ts title="client.account.transferDomain()" interface account { - transferDomain (payload: Array>): Promise + transferDomain (payload: Array | Record>): Promise +} + +enum TransferDomainKey { + SRC = 'src', + DST = 'dst' } interface TransferDomainInfo { @@ -176,7 +181,15 @@ enum TransferDomainType { DVM = 2, /** type for EVM To DVM Token transfer */ EVM = 3, -}; +} + +enum TransferDomainOptionalKey { + SINGLE_KEY_CHECK = 'singlekeycheck', +} + +interface TransferDomainOptionalInfo { + singleKeyCheck: boolean +} ``` ## accountToUtxos diff --git a/package-lock.json b/package-lock.json index 7a6b21360a..8d1b966e86 100644 --- a/package-lock.json +++ b/package-lock.json @@ -68,6 +68,7 @@ "class-transformer": "0.5.1", "class-validator": "0.14.0", "cross-fetch": "3.1.5", + "fast-csv": "^4.3.6", "graphology": "0.25.1", "graphology-components": "1.5.4", "graphology-simple-path": "0.1.2", @@ -4052,6 +4053,43 @@ "@ethersproject/strings": "^5.7.0" } }, + "node_modules/@fast-csv/format": { + "version": "4.3.5", + "resolved": "https://registry.npmjs.org/@fast-csv/format/-/format-4.3.5.tgz", + "integrity": "sha512-8iRn6QF3I8Ak78lNAa+Gdl5MJJBM5vRHivFtMRUWINdevNo00K7OXxS2PshawLKTejVwieIlPmK5YlLu6w4u8A==", + "dependencies": { + "@types/node": "^14.0.1", + "lodash.escaperegexp": "^4.1.2", + "lodash.isboolean": "^3.0.3", + "lodash.isequal": "^4.5.0", + "lodash.isfunction": "^3.0.9", + "lodash.isnil": "^4.0.0" + } + }, + "node_modules/@fast-csv/format/node_modules/@types/node": { + "version": "14.18.63", + "resolved": "https://registry.npmjs.org/@types/node/-/node-14.18.63.tgz", + "integrity": "sha512-fAtCfv4jJg+ExtXhvCkCqUKZ+4ok/JQk01qDKhL5BDDoS3AxKXhV5/MAVUZyQnSEd2GT92fkgZl0pz0Q0AzcIQ==" + }, + "node_modules/@fast-csv/parse": { + "version": "4.3.6", + "resolved": "https://registry.npmjs.org/@fast-csv/parse/-/parse-4.3.6.tgz", + "integrity": "sha512-uRsLYksqpbDmWaSmzvJcuApSEe38+6NQZBUsuAyMZKqHxH0g1wcJgsKUvN3WC8tewaqFjBMMGrkHmC+T7k8LvA==", + "dependencies": { + "@types/node": "^14.0.1", + "lodash.escaperegexp": "^4.1.2", + "lodash.groupby": "^4.6.0", + "lodash.isfunction": "^3.0.9", + "lodash.isnil": "^4.0.0", + "lodash.isundefined": "^3.0.1", + "lodash.uniq": "^4.5.0" + } + }, + "node_modules/@fast-csv/parse/node_modules/@types/node": { + "version": "14.18.63", + "resolved": "https://registry.npmjs.org/@types/node/-/node-14.18.63.tgz", + "integrity": "sha512-fAtCfv4jJg+ExtXhvCkCqUKZ+4ok/JQk01qDKhL5BDDoS3AxKXhV5/MAVUZyQnSEd2GT92fkgZl0pz0Q0AzcIQ==" + }, "node_modules/@fastify/ajv-compiler": { "version": "3.4.0", "resolved": "https://registry.npmjs.org/@fastify/ajv-compiler/-/ajv-compiler-3.4.0.tgz", @@ -14707,6 +14745,18 @@ "resolved": "https://registry.npmjs.org/fast-content-type-parse/-/fast-content-type-parse-1.0.0.tgz", "integrity": "sha512-Xbc4XcysUXcsP5aHUU7Nq3OwvHq97C+WnbkeIefpeYLX+ryzFJlU6OStFJhs6Ol0LkUGpcK+wL0JwfM+FCU5IA==" }, + "node_modules/fast-csv": { + "version": "4.3.6", + "resolved": "https://registry.npmjs.org/fast-csv/-/fast-csv-4.3.6.tgz", + "integrity": "sha512-2RNSpuwwsJGP0frGsOmTb9oUF+VkFSM4SyLTDgwf2ciHWTarN0lQTC+F2f/t5J9QjW+c65VFIAAu85GsvMIusw==", + "dependencies": { + "@fast-csv/format": "4.3.5", + "@fast-csv/parse": "4.3.6" + }, + "engines": { + "node": ">=10.0.0" + } + }, "node_modules/fast-decode-uri-component": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/fast-decode-uri-component/-/fast-decode-uri-component-1.0.1.tgz", @@ -19436,6 +19486,11 @@ "resolved": "https://registry.npmjs.org/lodash.difference/-/lodash.difference-4.5.0.tgz", "integrity": "sha1-nMtOUF1Ia5FlE0V3KIWi3yf9AXw=" }, + "node_modules/lodash.escaperegexp": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/lodash.escaperegexp/-/lodash.escaperegexp-4.1.2.tgz", + "integrity": "sha512-TM9YBvyC84ZxE3rgfefxUWiQKLilstD6k7PTGt6wfbtXF8ixIJLOL3VYyV/z+ZiPLsVxAsKAFVwWlWeb2Y8Yyw==" + }, "node_modules/lodash.flatten": { "version": "4.4.0", "license": "MIT" @@ -19445,17 +19500,47 @@ "resolved": "https://registry.npmjs.org/lodash.flow/-/lodash.flow-3.5.0.tgz", "integrity": "sha512-ff3BX/tSioo+XojX4MOsOMhJw0nZoUEF011LX8g8d3gvjVbxd89cCio4BCXronjxcTUIJUoqKEUA+n4CqvvRPw==" }, + "node_modules/lodash.groupby": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/lodash.groupby/-/lodash.groupby-4.6.0.tgz", + "integrity": "sha512-5dcWxm23+VAoz+awKmBaiBvzox8+RqMgFhi7UvX9DHZr2HdxHXM/Wrf8cfKpsW37RNrvtPn6hSwNqurSILbmJw==" + }, + "node_modules/lodash.isboolean": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz", + "integrity": "sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg==" + }, + "node_modules/lodash.isequal": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz", + "integrity": "sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ==" + }, + "node_modules/lodash.isfunction": { + "version": "3.0.9", + "resolved": "https://registry.npmjs.org/lodash.isfunction/-/lodash.isfunction-3.0.9.tgz", + "integrity": "sha512-AirXNj15uRIMMPihnkInB4i3NHeb4iBtNg9WRWuK2o31S+ePwwNmDPaTL3o7dTJ+VXNZim7rFs4rxN4YU1oUJw==" + }, "node_modules/lodash.ismatch": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/lodash.ismatch/-/lodash.ismatch-4.4.0.tgz", "integrity": "sha512-fPMfXjGQEV9Xsq/8MTSgUf255gawYRbjwMyDbcvDhXgV7enSZA0hynz6vMPnpAb5iONEzBHBPsT+0zes5Z301g==", "dev": true }, + "node_modules/lodash.isnil": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/lodash.isnil/-/lodash.isnil-4.0.0.tgz", + "integrity": "sha512-up2Mzq3545mwVnMhTDMdfoG1OurpA/s5t88JmQX809eH3C8491iu2sfKhTfhQtKY78oPNhiaHJUpT/dUDAAtng==" + }, "node_modules/lodash.isplainobject": { "version": "4.0.6", "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", "integrity": "sha1-fFJqUtibRcRcxpC4gWO+BJf1UMs=" }, + "node_modules/lodash.isundefined": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/lodash.isundefined/-/lodash.isundefined-3.0.1.tgz", + "integrity": "sha512-MXB1is3s899/cD8jheYYE2V9qTHwKvt+npCwpD+1Sxm3Q3cECXCiYHjeHWXNwr6Q0SOBPrYUDxendrO6goVTEA==" + }, "node_modules/lodash.memoize": { "version": "4.1.2", "license": "MIT" @@ -20736,9 +20821,15 @@ "license": "MIT" }, "node_modules/nanoid": { - "version": "3.3.4", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.4.tgz", - "integrity": "sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==", + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.6.tgz", + "integrity": "sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], "bin": { "nanoid": "bin/nanoid.cjs" }, @@ -22539,9 +22630,9 @@ } }, "node_modules/postcss": { - "version": "8.4.19", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.19.tgz", - "integrity": "sha512-h+pbPsyhlYj6N2ozBmHhHrs9DzGmbaarbLvWipMRO7RLS+v4onj26MPFXA5OBYFxyqYhUJK456SwDcY9H2/zsA==", + "version": "8.4.31", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.31.tgz", + "integrity": "sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==", "funding": [ { "type": "opencollective", @@ -22550,10 +22641,14 @@ { "type": "tidelift", "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" } ], "dependencies": { - "nanoid": "^3.3.4", + "nanoid": "^3.3.6", "picocolors": "^1.0.0", "source-map-js": "^1.0.2" }, @@ -30824,6 +30919,7 @@ "class-transformer": "0.5.1", "class-validator": "0.14.0", "cross-fetch": "3.1.5", + "fast-csv": "^4.3.6", "graphology": "0.25.1", "graphology-components": "1.5.4", "graphology-simple-path": "0.1.2", @@ -32197,6 +32293,47 @@ "@ethersproject/strings": "^5.7.0" } }, + "@fast-csv/format": { + "version": "4.3.5", + "resolved": "https://registry.npmjs.org/@fast-csv/format/-/format-4.3.5.tgz", + "integrity": "sha512-8iRn6QF3I8Ak78lNAa+Gdl5MJJBM5vRHivFtMRUWINdevNo00K7OXxS2PshawLKTejVwieIlPmK5YlLu6w4u8A==", + "requires": { + "@types/node": "^14.0.1", + "lodash.escaperegexp": "^4.1.2", + "lodash.isboolean": "^3.0.3", + "lodash.isequal": "^4.5.0", + "lodash.isfunction": "^3.0.9", + "lodash.isnil": "^4.0.0" + }, + "dependencies": { + "@types/node": { + "version": "14.18.63", + "resolved": "https://registry.npmjs.org/@types/node/-/node-14.18.63.tgz", + "integrity": "sha512-fAtCfv4jJg+ExtXhvCkCqUKZ+4ok/JQk01qDKhL5BDDoS3AxKXhV5/MAVUZyQnSEd2GT92fkgZl0pz0Q0AzcIQ==" + } + } + }, + "@fast-csv/parse": { + "version": "4.3.6", + "resolved": "https://registry.npmjs.org/@fast-csv/parse/-/parse-4.3.6.tgz", + "integrity": "sha512-uRsLYksqpbDmWaSmzvJcuApSEe38+6NQZBUsuAyMZKqHxH0g1wcJgsKUvN3WC8tewaqFjBMMGrkHmC+T7k8LvA==", + "requires": { + "@types/node": "^14.0.1", + "lodash.escaperegexp": "^4.1.2", + "lodash.groupby": "^4.6.0", + "lodash.isfunction": "^3.0.9", + "lodash.isnil": "^4.0.0", + "lodash.isundefined": "^3.0.1", + "lodash.uniq": "^4.5.0" + }, + "dependencies": { + "@types/node": { + "version": "14.18.63", + "resolved": "https://registry.npmjs.org/@types/node/-/node-14.18.63.tgz", + "integrity": "sha512-fAtCfv4jJg+ExtXhvCkCqUKZ+4ok/JQk01qDKhL5BDDoS3AxKXhV5/MAVUZyQnSEd2GT92fkgZl0pz0Q0AzcIQ==" + } + } + }, "@fastify/ajv-compiler": { "version": "3.4.0", "resolved": "https://registry.npmjs.org/@fastify/ajv-compiler/-/ajv-compiler-3.4.0.tgz", @@ -40486,6 +40623,7 @@ "class-transformer": "0.5.1", "class-validator": "0.14.0", "cross-fetch": "3.1.5", + "fast-csv": "^4.3.6", "graphology": "0.25.1", "graphology-components": "1.5.4", "graphology-simple-path": "0.1.2", @@ -41859,6 +41997,47 @@ "@ethersproject/strings": "^5.7.0" } }, + "@fast-csv/format": { + "version": "4.3.5", + "resolved": "https://registry.npmjs.org/@fast-csv/format/-/format-4.3.5.tgz", + "integrity": "sha512-8iRn6QF3I8Ak78lNAa+Gdl5MJJBM5vRHivFtMRUWINdevNo00K7OXxS2PshawLKTejVwieIlPmK5YlLu6w4u8A==", + "requires": { + "@types/node": "^14.0.1", + "lodash.escaperegexp": "^4.1.2", + "lodash.isboolean": "^3.0.3", + "lodash.isequal": "^4.5.0", + "lodash.isfunction": "^3.0.9", + "lodash.isnil": "^4.0.0" + }, + "dependencies": { + "@types/node": { + "version": "14.18.63", + "resolved": "https://registry.npmjs.org/@types/node/-/node-14.18.63.tgz", + "integrity": "sha512-fAtCfv4jJg+ExtXhvCkCqUKZ+4ok/JQk01qDKhL5BDDoS3AxKXhV5/MAVUZyQnSEd2GT92fkgZl0pz0Q0AzcIQ==" + } + } + }, + "@fast-csv/parse": { + "version": "4.3.6", + "resolved": "https://registry.npmjs.org/@fast-csv/parse/-/parse-4.3.6.tgz", + "integrity": "sha512-uRsLYksqpbDmWaSmzvJcuApSEe38+6NQZBUsuAyMZKqHxH0g1wcJgsKUvN3WC8tewaqFjBMMGrkHmC+T7k8LvA==", + "requires": { + "@types/node": "^14.0.1", + "lodash.escaperegexp": "^4.1.2", + "lodash.groupby": "^4.6.0", + "lodash.isfunction": "^3.0.9", + "lodash.isnil": "^4.0.0", + "lodash.isundefined": "^3.0.1", + "lodash.uniq": "^4.5.0" + }, + "dependencies": { + "@types/node": { + "version": "14.18.63", + "resolved": "https://registry.npmjs.org/@types/node/-/node-14.18.63.tgz", + "integrity": "sha512-fAtCfv4jJg+ExtXhvCkCqUKZ+4ok/JQk01qDKhL5BDDoS3AxKXhV5/MAVUZyQnSEd2GT92fkgZl0pz0Q0AzcIQ==" + } + } + }, "@fastify/ajv-compiler": { "version": "3.4.0", "resolved": "https://registry.npmjs.org/@fastify/ajv-compiler/-/ajv-compiler-3.4.0.tgz", @@ -49643,6 +49822,15 @@ "resolved": "https://registry.npmjs.org/fast-content-type-parse/-/fast-content-type-parse-1.0.0.tgz", "integrity": "sha512-Xbc4XcysUXcsP5aHUU7Nq3OwvHq97C+WnbkeIefpeYLX+ryzFJlU6OStFJhs6Ol0LkUGpcK+wL0JwfM+FCU5IA==" }, + "fast-csv": { + "version": "4.3.6", + "resolved": "https://registry.npmjs.org/fast-csv/-/fast-csv-4.3.6.tgz", + "integrity": "sha512-2RNSpuwwsJGP0frGsOmTb9oUF+VkFSM4SyLTDgwf2ciHWTarN0lQTC+F2f/t5J9QjW+c65VFIAAu85GsvMIusw==", + "requires": { + "@fast-csv/format": "4.3.5", + "@fast-csv/parse": "4.3.6" + } + }, "fast-decode-uri-component": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/fast-decode-uri-component/-/fast-decode-uri-component-1.0.1.tgz", @@ -52919,6 +53107,11 @@ "resolved": "https://registry.npmjs.org/lodash.difference/-/lodash.difference-4.5.0.tgz", "integrity": "sha1-nMtOUF1Ia5FlE0V3KIWi3yf9AXw=" }, + "lodash.escaperegexp": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/lodash.escaperegexp/-/lodash.escaperegexp-4.1.2.tgz", + "integrity": "sha512-TM9YBvyC84ZxE3rgfefxUWiQKLilstD6k7PTGt6wfbtXF8ixIJLOL3VYyV/z+ZiPLsVxAsKAFVwWlWeb2Y8Yyw==" + }, "lodash.flatten": { "version": "4.4.0" }, @@ -52927,17 +53120,47 @@ "resolved": "https://registry.npmjs.org/lodash.flow/-/lodash.flow-3.5.0.tgz", "integrity": "sha512-ff3BX/tSioo+XojX4MOsOMhJw0nZoUEF011LX8g8d3gvjVbxd89cCio4BCXronjxcTUIJUoqKEUA+n4CqvvRPw==" }, + "lodash.groupby": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/lodash.groupby/-/lodash.groupby-4.6.0.tgz", + "integrity": "sha512-5dcWxm23+VAoz+awKmBaiBvzox8+RqMgFhi7UvX9DHZr2HdxHXM/Wrf8cfKpsW37RNrvtPn6hSwNqurSILbmJw==" + }, + "lodash.isboolean": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz", + "integrity": "sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg==" + }, + "lodash.isequal": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz", + "integrity": "sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ==" + }, + "lodash.isfunction": { + "version": "3.0.9", + "resolved": "https://registry.npmjs.org/lodash.isfunction/-/lodash.isfunction-3.0.9.tgz", + "integrity": "sha512-AirXNj15uRIMMPihnkInB4i3NHeb4iBtNg9WRWuK2o31S+ePwwNmDPaTL3o7dTJ+VXNZim7rFs4rxN4YU1oUJw==" + }, "lodash.ismatch": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/lodash.ismatch/-/lodash.ismatch-4.4.0.tgz", "integrity": "sha512-fPMfXjGQEV9Xsq/8MTSgUf255gawYRbjwMyDbcvDhXgV7enSZA0hynz6vMPnpAb5iONEzBHBPsT+0zes5Z301g==", "dev": true }, + "lodash.isnil": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/lodash.isnil/-/lodash.isnil-4.0.0.tgz", + "integrity": "sha512-up2Mzq3545mwVnMhTDMdfoG1OurpA/s5t88JmQX809eH3C8491iu2sfKhTfhQtKY78oPNhiaHJUpT/dUDAAtng==" + }, "lodash.isplainobject": { "version": "4.0.6", "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", "integrity": "sha1-fFJqUtibRcRcxpC4gWO+BJf1UMs=" }, + "lodash.isundefined": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/lodash.isundefined/-/lodash.isundefined-3.0.1.tgz", + "integrity": "sha512-MXB1is3s899/cD8jheYYE2V9qTHwKvt+npCwpD+1Sxm3Q3cECXCiYHjeHWXNwr6Q0SOBPrYUDxendrO6goVTEA==" + }, "lodash.memoize": { "version": "4.1.2" }, @@ -53853,9 +54076,9 @@ "version": "2.15.0" }, "nanoid": { - "version": "3.3.4", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.4.tgz", - "integrity": "sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==" + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.6.tgz", + "integrity": "sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==" }, "napi-macros": { "version": "2.0.0" @@ -55127,11 +55350,11 @@ "dev": true }, "postcss": { - "version": "8.4.19", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.19.tgz", - "integrity": "sha512-h+pbPsyhlYj6N2ozBmHhHrs9DzGmbaarbLvWipMRO7RLS+v4onj26MPFXA5OBYFxyqYhUJK456SwDcY9H2/zsA==", + "version": "8.4.31", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.31.tgz", + "integrity": "sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==", "requires": { - "nanoid": "^3.3.4", + "nanoid": "^3.3.6", "picocolors": "^1.0.0", "source-map-js": "^1.0.2" } @@ -60473,6 +60696,15 @@ "resolved": "https://registry.npmjs.org/fast-content-type-parse/-/fast-content-type-parse-1.0.0.tgz", "integrity": "sha512-Xbc4XcysUXcsP5aHUU7Nq3OwvHq97C+WnbkeIefpeYLX+ryzFJlU6OStFJhs6Ol0LkUGpcK+wL0JwfM+FCU5IA==" }, + "fast-csv": { + "version": "4.3.6", + "resolved": "https://registry.npmjs.org/fast-csv/-/fast-csv-4.3.6.tgz", + "integrity": "sha512-2RNSpuwwsJGP0frGsOmTb9oUF+VkFSM4SyLTDgwf2ciHWTarN0lQTC+F2f/t5J9QjW+c65VFIAAu85GsvMIusw==", + "requires": { + "@fast-csv/format": "4.3.5", + "@fast-csv/parse": "4.3.6" + } + }, "fast-decode-uri-component": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/fast-decode-uri-component/-/fast-decode-uri-component-1.0.1.tgz", @@ -63749,6 +63981,11 @@ "resolved": "https://registry.npmjs.org/lodash.difference/-/lodash.difference-4.5.0.tgz", "integrity": "sha1-nMtOUF1Ia5FlE0V3KIWi3yf9AXw=" }, + "lodash.escaperegexp": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/lodash.escaperegexp/-/lodash.escaperegexp-4.1.2.tgz", + "integrity": "sha512-TM9YBvyC84ZxE3rgfefxUWiQKLilstD6k7PTGt6wfbtXF8ixIJLOL3VYyV/z+ZiPLsVxAsKAFVwWlWeb2Y8Yyw==" + }, "lodash.flatten": { "version": "4.4.0" }, @@ -63757,17 +63994,47 @@ "resolved": "https://registry.npmjs.org/lodash.flow/-/lodash.flow-3.5.0.tgz", "integrity": "sha512-ff3BX/tSioo+XojX4MOsOMhJw0nZoUEF011LX8g8d3gvjVbxd89cCio4BCXronjxcTUIJUoqKEUA+n4CqvvRPw==" }, + "lodash.groupby": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/lodash.groupby/-/lodash.groupby-4.6.0.tgz", + "integrity": "sha512-5dcWxm23+VAoz+awKmBaiBvzox8+RqMgFhi7UvX9DHZr2HdxHXM/Wrf8cfKpsW37RNrvtPn6hSwNqurSILbmJw==" + }, + "lodash.isboolean": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz", + "integrity": "sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg==" + }, + "lodash.isequal": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz", + "integrity": "sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ==" + }, + "lodash.isfunction": { + "version": "3.0.9", + "resolved": "https://registry.npmjs.org/lodash.isfunction/-/lodash.isfunction-3.0.9.tgz", + "integrity": "sha512-AirXNj15uRIMMPihnkInB4i3NHeb4iBtNg9WRWuK2o31S+ePwwNmDPaTL3o7dTJ+VXNZim7rFs4rxN4YU1oUJw==" + }, "lodash.ismatch": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/lodash.ismatch/-/lodash.ismatch-4.4.0.tgz", "integrity": "sha512-fPMfXjGQEV9Xsq/8MTSgUf255gawYRbjwMyDbcvDhXgV7enSZA0hynz6vMPnpAb5iONEzBHBPsT+0zes5Z301g==", "dev": true }, + "lodash.isnil": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/lodash.isnil/-/lodash.isnil-4.0.0.tgz", + "integrity": "sha512-up2Mzq3545mwVnMhTDMdfoG1OurpA/s5t88JmQX809eH3C8491iu2sfKhTfhQtKY78oPNhiaHJUpT/dUDAAtng==" + }, "lodash.isplainobject": { "version": "4.0.6", "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", "integrity": "sha1-fFJqUtibRcRcxpC4gWO+BJf1UMs=" }, + "lodash.isundefined": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/lodash.isundefined/-/lodash.isundefined-3.0.1.tgz", + "integrity": "sha512-MXB1is3s899/cD8jheYYE2V9qTHwKvt+npCwpD+1Sxm3Q3cECXCiYHjeHWXNwr6Q0SOBPrYUDxendrO6goVTEA==" + }, "lodash.memoize": { "version": "4.1.2" }, @@ -64683,9 +64950,9 @@ "version": "2.15.0" }, "nanoid": { - "version": "3.3.4", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.4.tgz", - "integrity": "sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==" + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.6.tgz", + "integrity": "sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==" }, "napi-macros": { "version": "2.0.0" @@ -65957,11 +66224,11 @@ "dev": true }, "postcss": { - "version": "8.4.19", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.19.tgz", - "integrity": "sha512-h+pbPsyhlYj6N2ozBmHhHrs9DzGmbaarbLvWipMRO7RLS+v4onj26MPFXA5OBYFxyqYhUJK456SwDcY9H2/zsA==", + "version": "8.4.31", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.31.tgz", + "integrity": "sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==", "requires": { - "nanoid": "^3.3.4", + "nanoid": "^3.3.6", "picocolors": "^1.0.0", "source-map-js": "^1.0.2" } diff --git a/packages/jellyfish-api-core/__tests__/category/account/getBurnInfo.test.ts b/packages/jellyfish-api-core/__tests__/category/account/getBurnInfo.test.ts index fd2aa51ea0..57b7d89cf5 100644 --- a/packages/jellyfish-api-core/__tests__/category/account/getBurnInfo.test.ts +++ b/packages/jellyfish-api-core/__tests__/category/account/getBurnInfo.test.ts @@ -50,7 +50,7 @@ it('should getBurnInfo', async () => { tokens: ['50.00000000@GOLD'], feeburn: new BigNumber('2'), auctionburn: new BigNumber(0), - consortiumtokens: [], + // consortiumtokens: [], emissionburn: new BigNumber('6274'), paybackburn: [], paybackfees: [], diff --git a/packages/jellyfish-api-core/__tests__/category/account/getTokenBalances.test.ts b/packages/jellyfish-api-core/__tests__/category/account/getTokenBalances.test.ts index bca3785e0b..81094c79c2 100644 --- a/packages/jellyfish-api-core/__tests__/category/account/getTokenBalances.test.ts +++ b/packages/jellyfish-api-core/__tests__/category/account/getTokenBalances.test.ts @@ -1,6 +1,6 @@ import { MasterNodeRegTestContainer } from '@defichain/testcontainers' import { ContainerAdapterClient } from '../../container_adapter_client' -import { TransferDomainType } from '../../../src/category/account' +import { TransferDomainType, TransferDomainOptionalInfo } from '../../../src/category/account' import waitForExpect from 'wait-for-expect' import BigNumber from 'bignumber.js' @@ -137,7 +137,8 @@ describe('Account', () => { address: evmAddr, amount: '3@DFI', domain: TransferDomainType.EVM - } + }, + singlekeycheck: false as unknown as TransferDomainOptionalInfo } ]) await container.generate(1) diff --git a/packages/jellyfish-api-core/__tests__/category/account/transferDomain.singlekeycheck.test.ts b/packages/jellyfish-api-core/__tests__/category/account/transferDomain.singlekeycheck.test.ts new file mode 100644 index 0000000000..9bf3741747 --- /dev/null +++ b/packages/jellyfish-api-core/__tests__/category/account/transferDomain.singlekeycheck.test.ts @@ -0,0 +1,136 @@ +import { MasterNodeRegTestContainer } from '@defichain/testcontainers' +import { ContainerAdapterClient } from '../../container_adapter_client' +import { TransferDomainOptionalInfo, TransferDomainType } from '../../../src/category/account' +import { RpcApiError } from '@defichain/jellyfish-api-core' +import BigNumber from 'bignumber.js' + +describe('TransferDomain', () => { + let legacyAddr: string + let legacyEvmAddr: string + let bech32Addr: string + let bech32EvmAddr: string + const container = new MasterNodeRegTestContainer() + const client = new ContainerAdapterClient(container) + + beforeAll(async () => { + await container.start() + await container.waitForWalletCoinbaseMaturity() + + await client.masternode.setGov({ + ATTRIBUTES: { + 'v0/params/feature/evm': 'true', + 'v0/params/feature/transferdomain': 'true' + } + }) + await container.generate(2) + + legacyAddr = await container.getNewAddress('legacy', 'legacy') + legacyEvmAddr = (await container.call('addressmap', [legacyAddr, 1])).format.erc55 + + bech32Addr = await container.getNewAddress('bech32', 'bech32') + bech32EvmAddr = (await container.call('addressmap', [bech32Addr, 1])).format.erc55 + + await container.call('utxostoaccount', [{ [legacyAddr]: '100000@0' }]) + await container.generate(1) + }) + + afterAll(async () => { + await container.stop() + }) + + describe('single key check restricted', () => { + it('should fail as src key and dst key is different', async () => { + const promise = client.account.transferDomain([ + { + src: { + address: legacyAddr, + amount: '3@DFI', + domain: TransferDomainType.DVM + }, + dst: { + address: bech32EvmAddr, + amount: '3@DFI', + domain: TransferDomainType.EVM + } + } + ]) + await expect(promise).rejects.toThrow(RpcApiError) + await expect(promise).rejects.toThrow('Dst address does not match source key') + }) + + it('should transfer domain with same key', async () => { + const legacyAccBefore = await client.account.getAccount(legacyAddr) + const [value] = legacyAccBefore[0].split('@') + const legacyBalanceBefore = new BigNumber(value) + const evmBalanceBefore = await getEVMBalances(client) + + await client.account.transferDomain([ + { + src: { + address: legacyAddr, + amount: '1@DFI', + domain: TransferDomainType.DVM + }, + dst: { + address: legacyEvmAddr, + amount: '1@DFI', + domain: TransferDomainType.EVM + } + } + ]) + await container.generate(1) + + { + const legacyAccAfter = await client.account.getAccount(legacyAddr) + const [value] = legacyAccAfter[0].split('@') + const legacyBalanceAfter = new BigNumber(value) + expect(legacyBalanceAfter).toStrictEqual(legacyBalanceBefore.minus(1)) + + const evmBalanceAfter = await getEVMBalances(client) + expect(evmBalanceAfter).toStrictEqual(evmBalanceBefore.plus(1)) + } + }) + + it('should transfer domain with different key', async () => { + const legacyAccBefore = await client.account.getAccount(legacyAddr) + const [value] = legacyAccBefore[0].split('@') + const legacyBalanceBefore = new BigNumber(value) + const evmBalanceBefore = await getEVMBalances(client) + + await client.account.transferDomain([ + { + src: { + address: legacyAddr, + amount: '2@DFI', + domain: TransferDomainType.DVM + }, + dst: { + address: bech32EvmAddr, + amount: '2@DFI', + domain: TransferDomainType.EVM + }, + singlekeycheck: false as unknown as TransferDomainOptionalInfo + } + ]) + await container.generate(1) + + { + const legacyAccAfter = await client.account.getAccount(legacyAddr) + const [value] = legacyAccAfter[0].split('@') + const legacyBalanceAfter = new BigNumber(value) + expect(legacyBalanceAfter).toStrictEqual(legacyBalanceBefore.minus(2)) + + const evmBalanceAfter = await getEVMBalances(client) + expect(evmBalanceAfter).toStrictEqual(evmBalanceBefore.plus(2)) + } + }) + }) +}) + +async function getEVMBalances (client: ContainerAdapterClient): Promise { + const ethRes = await client.account.getTokenBalances({}, false) + const [eth] = ethRes[0].split('@') + const withEthRes = await client.account.getTokenBalances({}, false, { symbolLookup: false, includeEth: true }) + const [withEth] = withEthRes[0].split('@') + return new BigNumber(withEth).minus(eth) +} diff --git a/packages/jellyfish-api-core/__tests__/category/account/transferDomain.test.ts b/packages/jellyfish-api-core/__tests__/category/account/transferDomain.test.ts index 963ad0135d..20553b993d 100644 --- a/packages/jellyfish-api-core/__tests__/category/account/transferDomain.test.ts +++ b/packages/jellyfish-api-core/__tests__/category/account/transferDomain.test.ts @@ -1,4 +1,4 @@ -import { MasterNodeRegTestContainer } from '@defichain/testcontainers' +import { MasterNodeRegTestContainer, StartFlags } from '@defichain/testcontainers' import { ContainerAdapterClient } from '../../container_adapter_client' import { TransferDomainType } from '../../../src/category/account' import { RpcApiError } from '@defichain/jellyfish-api-core' @@ -8,9 +8,11 @@ describe('TransferDomain', () => { let dvmAddr: string, evmAddr: string, p2shAddr: string const container = new MasterNodeRegTestContainer() const client = new ContainerAdapterClient(container) + // add `-tdsinglekeycheck` for backward compatibility + const startFlags: StartFlags[] = [{ name: 'tdsinglekeycheck', value: 0 }] beforeAll(async () => { - await container.start() + await container.start({ startFlags }) await container.waitForWalletCoinbaseMaturity() await client.masternode.setGov({ @@ -218,7 +220,7 @@ describe('TransferDomain', () => { } ]) await expect(promise).rejects.toThrow(RpcApiError) - await expect(promise).rejects.toThrow('Failed to create and sign TX: Invalid address') + await expect(promise).rejects.toThrow('Dst address must be an ERC55 address in case of "EVM" domain') }) it('(evm -> dvm) should fail if src address is not ERC55 address in case of "EVM" domain', async () => { @@ -486,7 +488,7 @@ describe('TransferDomain', () => { } ]) await expect(promise).rejects.toThrow(RpcApiError) - await expect(promise).rejects.toThrow('Failed to create and sign TX: Invalid address') + await expect(promise).rejects.toThrow('Cannot transfer inside same domain') }) it('(evm -> evm) should fail if transfer within same domain', async () => { diff --git a/packages/jellyfish-api-core/__tests__/category/evm/evmTx.test.ts b/packages/jellyfish-api-core/__tests__/category/evm/evmTx.test.ts index 0a76dbf6a8..21cf11edb5 100644 --- a/packages/jellyfish-api-core/__tests__/category/evm/evmTx.test.ts +++ b/packages/jellyfish-api-core/__tests__/category/evm/evmTx.test.ts @@ -3,7 +3,7 @@ import { MasterNodeRegTestContainer } from '@defichain/testcontainers' import { Testing } from '@defichain/jellyfish-testing' import { RpcApiError } from '@defichain/jellyfish-api-core/dist/index' import { ContainerAdapterClient } from '../../container_adapter_client' -import { TransferDomainType } from '../../../src/category/account' +import { TransferDomainType, TransferDomainOptionalInfo } from '../../../src/category/account' import BigNumber from 'bignumber.js' describe('EVMTX', () => { @@ -69,7 +69,8 @@ describe('EVMTX', () => { address: ethAddress, amount: `${amount.HUNDRED}@DFI`, domain: TransferDomainType.EVM - } + }, + singlekeycheck: false as unknown as TransferDomainOptionalInfo } ] await container.call('transferdomain', [dvmToEvmTransfer]) diff --git a/packages/jellyfish-api-core/__tests__/category/loan/withdrawFromVault.test.ts b/packages/jellyfish-api-core/__tests__/category/loan/withdrawFromVault.test.ts index 5934409efa..9e4e0bd70a 100644 --- a/packages/jellyfish-api-core/__tests__/category/loan/withdrawFromVault.test.ts +++ b/packages/jellyfish-api-core/__tests__/category/loan/withdrawFromVault.test.ts @@ -294,7 +294,7 @@ describe('Loan', () => { }) await expect(promise).rejects.toThrow(RpcApiError) - await expect(promise).rejects.toThrow(`Collateral for vault <${vaultId1}> not found`) + await expect(promise).rejects.toThrow('amount 9987.77833000 is less than 10000.00000001') }) it('should not withdrawFromVault cause DFI collateral value less than 50% of the minimum required collateral', async () => { @@ -350,7 +350,7 @@ describe('Loan', () => { }) await expect(promise).rejects.toThrow(RpcApiError) - await expect(promise).rejects.toThrow(`Collateral for vault <${vaultId2}> not found`) + await expect(promise).rejects.toThrow('amount 10000.00000000 is less than 99701.00000000') }) it('should not withdrawFromVault liquidated vault', async () => { diff --git a/packages/jellyfish-api-core/__tests__/category/masternode/setGov.locks.token.test.ts b/packages/jellyfish-api-core/__tests__/category/masternode/setGov.locks.token.test.ts index fe9875892d..cc2530801e 100644 --- a/packages/jellyfish-api-core/__tests__/category/masternode/setGov.locks.token.test.ts +++ b/packages/jellyfish-api-core/__tests__/category/masternode/setGov.locks.token.test.ts @@ -250,24 +250,6 @@ describe('SetGov v0/locks/token', () => { const attributes = await testing.rpc.masternode.getGov('ATTRIBUTES') expect(attributes.ATTRIBUTES[`v0/locks/token/${tslaId}`]).toStrictEqual('false') } - - // Lock invalid loan token string - await testing.rpc.masternode.setGov({ ATTRIBUTES: { 'v0/locks/token/abc': 'true' } }) - await testing.generate(1) - - { - const attributes = await testing.rpc.masternode.getGov('ATTRIBUTES') - expect(attributes.ATTRIBUTES['v0/locks/token/abc']).toBeUndefined() - } - - // Unlock invalid loan token string - await testing.rpc.masternode.setGov({ ATTRIBUTES: { 'v0/locks/token/abc': 'false' } }) - await testing.generate(1) - - { - const attributes = await testing.rpc.masternode.getGov('ATTRIBUTES') - expect(attributes.ATTRIBUTES['v0/locks/token/abc']).toBeUndefined() - } }) it('should update loan token if loan token is unlocked', async () => { @@ -440,6 +422,11 @@ describe('SetGov v0/locks/token', () => { expect(txId.length).toStrictEqual(64) }) + it('should fail if lock invalid token', async () => { + const promise = testing.rpc.masternode.setGov({ ATTRIBUTES: { 'v0/locks/token/abc': 'true' } }) + await expect(promise).rejects.toThrow('Token should be defined as numeric ID') + }) + it('should not lock collateral token', async () => { // Try to lock collateral token const promise = testing.rpc.masternode.setGov({ ATTRIBUTES: { [`v0/locks/token/${dfiId}`]: 'true' } }) diff --git a/packages/jellyfish-api-core/__tests__/category/masternode/setGov.test.ts b/packages/jellyfish-api-core/__tests__/category/masternode/setGov.test.ts index 9063f19477..6236bbbcf6 100644 --- a/packages/jellyfish-api-core/__tests__/category/masternode/setGov.test.ts +++ b/packages/jellyfish-api-core/__tests__/category/masternode/setGov.test.ts @@ -517,7 +517,7 @@ describe('setGov ATTRIBUTES loan dusd burn keys', () => { }) }) -describe('setGov consortium ATTRIBUTES', () => { +describe.skip('setGov consortium ATTRIBUTES', () => { const tGroup = TestingGroup.create(2) let account0: string, account1: string let idBTC: string diff --git a/packages/jellyfish-api-core/__tests__/category/masternode/updatemasternode.test.ts b/packages/jellyfish-api-core/__tests__/category/masternode/updatemasternode.test.ts index 03cdfb7ac9..3e57381a45 100644 --- a/packages/jellyfish-api-core/__tests__/category/masternode/updatemasternode.test.ts +++ b/packages/jellyfish-api-core/__tests__/category/masternode/updatemasternode.test.ts @@ -529,7 +529,7 @@ describe('Update Masternode', () => { const promise = container.call('sendrawtransaction', [signedTx.hex]) await expect(promise).rejects.toThrow(DeFiDRpcError) - await expect(promise).rejects.toThrow(`DeFiDRpcError: 'bad-txns-collateral-locked, tried to spend locked collateral for ${masternodeId} (code 16)', code: -26`) + await expect(promise).rejects.toThrow(`DeFiDRpcError: 'bad-txns-collateral-locked, tried to spend locked collateral for ${masternodeId}', code: -26`) }) }) diff --git a/packages/jellyfish-api-core/__tests__/category/rawtx/testMempoolAccept.test.ts b/packages/jellyfish-api-core/__tests__/category/rawtx/testMempoolAccept.test.ts index 44afbe3ed1..1689e86ee1 100644 --- a/packages/jellyfish-api-core/__tests__/category/rawtx/testMempoolAccept.test.ts +++ b/packages/jellyfish-api-core/__tests__/category/rawtx/testMempoolAccept.test.ts @@ -76,12 +76,12 @@ describe('Raw transaction', () => { it('testMempoolAccept() should fail with low fee rate', async () => { const result = await testMempoolAcceptFees(new BigNumber('4.5')) expect(result.allowed).toStrictEqual(false) - expect(result['reject-reason']).toStrictEqual('256: absurdly-high-fee') + expect(result['reject-reason']).toStrictEqual('absurdly-high-fee') }) it('testMempoolAccept() should fail with extreme low fee rate', async () => { const result = await testMempoolAcceptFees(new BigNumber('0.01')) expect(result.allowed).toStrictEqual(false) - expect(result['reject-reason']).toStrictEqual('256: absurdly-high-fee') + expect(result['reject-reason']).toStrictEqual('absurdly-high-fee') }) }) diff --git a/packages/jellyfish-api-core/__tests__/category/token/burnTokens.test.ts b/packages/jellyfish-api-core/__tests__/category/token/burnTokens.test.ts index af03c55710..a4976f82b5 100644 --- a/packages/jellyfish-api-core/__tests__/category/token/burnTokens.test.ts +++ b/packages/jellyfish-api-core/__tests__/category/token/burnTokens.test.ts @@ -1,18 +1,18 @@ import { TestingGroup } from '@defichain/jellyfish-testing' -import { BigNumber } from '../../../src' describe('burnTokens', () => { const tGroup = TestingGroup.create(3) const symbolDBTC = 'DBTC' - let account0: string, account1: string, account2: string - let idBTC: string + let account0: string, account1: string + // let account2: string + // let idBTC: string beforeEach(async () => { await tGroup.start() account0 = await tGroup.get(0).generateAddress() account1 = await tGroup.get(1).generateAddress() - account2 = await tGroup.get(2).generateAddress() + // account2 = await tGroup.get(2).generateAddress() await tGroup.get(0).token.create({ symbol: symbolDBTC, @@ -29,30 +29,30 @@ describe('burnTokens', () => { await tGroup.get(0).generate(1) - idBTC = await tGroup.get(0).token.getTokenId(symbolDBTC) - - await setGovAttr({ 'v0/params/feature/consortium': 'true' }) - - await setGovAttr({ - [`v0/consortium/${idBTC}/mint_limit`]: '10', - [`v0/consortium/${idBTC}/mint_limit_daily`]: '5', - [`v0/consortium/${idBTC}/members`]: { - '02': { - name: 'account2BTC', - ownerAddress: account0, - mintLimitDaily: 5, - mintLimit: 10, - backingId: 'backing2' - }, - '03': { - name: 'account3BTC', - ownerAddress: account2, - mintLimitDaily: 5, - mintLimit: 10, - backingId: 'backing2' - } - } - }) + // idBTC = await tGroup.get(0).token.getTokenId(symbolDBTC) + + // await setGovAttr({ 'v0/params/feature/consortium': 'true' }) + + // await setGovAttr({ + // [`v0/consortium/${idBTC}/mint_limit`]: '10', + // [`v0/consortium/${idBTC}/mint_limit_daily`]: '5', + // [`v0/consortium/${idBTC}/members`]: { + // '02': { + // name: 'account2BTC', + // ownerAddress: account0, + // mintLimitDaily: 5, + // mintLimit: 10, + // backingId: 'backing2' + // }, + // '03': { + // name: 'account3BTC', + // ownerAddress: account2, + // mintLimitDaily: 5, + // mintLimit: 10, + // backingId: 'backing2' + // } + // } + // }) await tGroup.get(0).rpc.token.mintTokens({ amounts: [`10@${symbolDBTC}`] }) await tGroup.get(0).generate(1) @@ -62,11 +62,11 @@ describe('burnTokens', () => { await tGroup.stop() }) - async function setGovAttr (attributes: object): Promise { - const hash = await tGroup.get(0).rpc.masternode.setGov({ ATTRIBUTES: attributes }) - expect(hash).toBeTruthy() - await tGroup.get(0).generate(1) - } + // async function setGovAttr (attributes: object): Promise { + // const hash = await tGroup.get(0).rpc.masternode.setGov({ ATTRIBUTES: attributes }) + // expect(hash).toBeTruthy() + // await tGroup.get(0).generate(1) + // } it('should throw an error if invalid value is provided for amount', async () => { // @ts-expect-error @@ -112,8 +112,8 @@ describe('burnTokens', () => { const tokensAfterBurn = await tGroup.get(0).rpc.account.getAccount(account0) expect(tokensAfterBurn[0]).toStrictEqual(`9.00000000@${symbolDBTC}`) - const attr = (await tGroup.get(2).rpc.masternode.getGov('ATTRIBUTES')).ATTRIBUTES - expect(attr['v0/live/economy/consortium/1/burnt']).toStrictEqual(new BigNumber(1)) + // const attr = (await tGroup.get(2).rpc.masternode.getGov('ATTRIBUTES')).ATTRIBUTES + // expect(attr['v0/live/economy/consortium/1/burnt']).toStrictEqual(new BigNumber(1)) }) it('should burn tokens with utxos', async () => { diff --git a/packages/jellyfish-api-core/__tests__/category/token/mintTokens.test.ts b/packages/jellyfish-api-core/__tests__/category/token/mintTokens.test.ts index 4c64ed6c3e..8309fa1877 100644 --- a/packages/jellyfish-api-core/__tests__/category/token/mintTokens.test.ts +++ b/packages/jellyfish-api-core/__tests__/category/token/mintTokens.test.ts @@ -134,10 +134,12 @@ describe('Token', () => { }) }) -describe('Consortium', () => { +// NOTE(canonbrother): skip as consortium is removed, ref: https://github.com/DeFiCh/ain/pull/2730 +describe.skip('Consortium', () => { const tGroup = TestingGroup.create(4) let account0: string, account1: string, account2: string, account3: string - let idBTC: string, idDOGE: string + let idBTC: string + // let idDOGE: string const symbolBTC = 'BTC' const symbolDOGE = 'DOGE' const startFlags: StartFlags[] = [{ name: 'regtest-minttoken-simulate-mainnet', value: 1 }] @@ -178,22 +180,22 @@ describe('Consortium', () => { await tGroup.get(0).generate(1) idBTC = await tGroup.get(0).token.getTokenId(symbolBTC) - idDOGE = await tGroup.get(0).token.getTokenId(symbolDOGE) + // idDOGE = await tGroup.get(0).token.getTokenId(symbolDOGE) - // Enable consortium - await setGovAttr({ 'v0/params/feature/consortium': 'true' }) + // // Enable consortium + // await setGovAttr({ 'v0/params/feature/consortium': 'true' }) }) afterEach(async () => { await tGroup.stop() }) - async function setGovAttr (attributes: object): Promise { - const hash = await tGroup.get(0).rpc.masternode.setGov({ ATTRIBUTES: attributes }) - expect(hash).toBeTruthy() - await tGroup.get(0).generate(1) - await tGroup.waitForSync() - } + // async function setGovAttr (attributes: object): Promise { + // const hash = await tGroup.get(0).rpc.masternode.setGov({ ATTRIBUTES: attributes }) + // expect(hash).toBeTruthy() + // await tGroup.get(0).generate(1) + // await tGroup.waitForSync() + // } it('should throw an error if foundation or consortium member authorization is not present', async () => { const errorMsg = 'RpcApiError: \'Test MintTokenTx execution failed:\nYou are not a foundation member or token owner and cannot mint this token!\', code: -32600, method: minttokens' @@ -205,82 +207,82 @@ describe('Consortium', () => { it('should throw an error if the token is not specified in governance vars', async () => { // Set consortium members 02 for BTC - await setGovAttr({ - [`v0/consortium/${idBTC}/mint_limit`]: '10', - [`v0/consortium/${idBTC}/mint_limit_daily`]: '5', - [`v0/consortium/${idBTC}/members`]: { - '02': { - name: 'account2BTC', - ownerAddress: account2, - mintLimitDaily: 5, - mintLimit: 10, - backingId: 'backing2' - } - } - }) + // await setGovAttr({ + // [`v0/consortium/${idBTC}/mint_limit`]: '10', + // [`v0/consortium/${idBTC}/mint_limit_daily`]: '5', + // [`v0/consortium/${idBTC}/members`]: { + // '02': { + // name: 'account2BTC', + // ownerAddress: account2, + // mintLimitDaily: 5, + // mintLimit: 10, + // backingId: 'backing2' + // } + // } + // }) // Member 02 trying to mint DOGE await expect(tGroup.get(2).rpc.token.mintTokens({ amounts: [`1@${symbolDOGE}`] })).rejects.toThrow('RpcApiError: \'Test MintTokenTx execution failed:\nYou are not a foundation member or token owner and cannot mint this token!\', code: -32600, method: minttokens') }) it('should throw an error if member daily mint limit exceeds', async () => { - await setGovAttr({ - [`v0/consortium/${idBTC}/mint_limit`]: '10', - [`v0/consortium/${idBTC}/mint_limit_daily`]: '5', - [`v0/consortium/${idBTC}/members`]: { - '02': { - name: 'account2BTC', - ownerAddress: account2, - mintLimitDaily: 5, - mintLimit: 10, - backingId: 'backing2' - } - } - }) + // await setGovAttr({ + // [`v0/consortium/${idBTC}/mint_limit`]: '10', + // [`v0/consortium/${idBTC}/mint_limit_daily`]: '5', + // [`v0/consortium/${idBTC}/members`]: { + // '02': { + // name: 'account2BTC', + // ownerAddress: account2, + // mintLimitDaily: 5, + // mintLimit: 10, + // backingId: 'backing2' + // } + // } + // }) await expect(tGroup.get(2).rpc.token.mintTokens({ amounts: [`6@${symbolBTC}`] })).rejects.toThrow(`RpcApiError: 'Test MintTokenTx execution failed:\nYou will exceed your daily mint limit for ${symbolBTC} token by minting this amount', code: -32600, method: minttokens`) }) it('should throw an error if member maximum mint limit exceeds', async () => { - await setGovAttr({ - [`v0/consortium/${idBTC}/mint_limit`]: '10', - [`v0/consortium/${idBTC}/mint_limit_daily`]: '5', - [`v0/consortium/${idBTC}/members`]: { - '02': { - name: 'account2BTC', - ownerAddress: account2, - mintLimitDaily: 5, - mintLimit: 10, - backingId: 'backing2' - } - } - }) + // await setGovAttr({ + // [`v0/consortium/${idBTC}/mint_limit`]: '10', + // [`v0/consortium/${idBTC}/mint_limit_daily`]: '5', + // [`v0/consortium/${idBTC}/members`]: { + // '02': { + // name: 'account2BTC', + // ownerAddress: account2, + // mintLimitDaily: 5, + // mintLimit: 10, + // backingId: 'backing2' + // } + // } + // }) await expect(tGroup.get(2).rpc.token.mintTokens({ amounts: [`11@${symbolBTC}`] })).rejects.toThrow(`RpcApiError: 'Test MintTokenTx execution failed:\nYou will exceed your maximum mint limit for ${symbolBTC} token by minting this amount!', code: -32600, method: minttokens`) }) it('should throw an error if global daily mint limit exceeds', async () => { - await setGovAttr({ - [`v0/consortium/${idBTC}/mint_limit`]: '10', - [`v0/consortium/${idBTC}/mint_limit_daily`]: '5', - [`v0/consortium/${idBTC}/members`]: { - '01': { - id: '01', - name: 'account1BTC', - ownerAddress: account1, - mintLimitDaily: 5, - mintLimit: 10, - backingId: 'backing1' - }, - '03': { - name: 'account3BTC', - ownerAddress: account3, - mintLimitDaily: 5, - mintLimit: 10, - backingId: 'backing3' - } - } - }) + // await setGovAttr({ + // [`v0/consortium/${idBTC}/mint_limit`]: '10', + // [`v0/consortium/${idBTC}/mint_limit_daily`]: '5', + // [`v0/consortium/${idBTC}/members`]: { + // '01': { + // id: '01', + // name: 'account1BTC', + // ownerAddress: account1, + // mintLimitDaily: 5, + // mintLimit: 10, + // backingId: 'backing1' + // }, + // '03': { + // name: 'account3BTC', + // ownerAddress: account3, + // mintLimitDaily: 5, + // mintLimit: 10, + // backingId: 'backing3' + // } + // } + // }) // Hit global daily mint limit await tGroup.get(1).rpc.token.mintTokens({ amounts: [`5.0000000@${symbolBTC}`] }) @@ -291,27 +293,27 @@ describe('Consortium', () => { }) it('should throw an error if global mint limit exceeds', async () => { - await setGovAttr({ - [`v0/consortium/${idBTC}/mint_limit_daily`]: '5', - [`v0/consortium/${idBTC}/mint_limit`]: '8', - [`v0/consortium/${idBTC}/members`]: { - '01': { - id: '01', - name: 'account1BTC', - ownerAddress: account1, - mintLimitDaily: 5, - mintLimit: 8, - backingId: 'backing1' - }, - '03': { - name: 'account3BTC', - ownerAddress: account3, - mintLimitDaily: 5, - mintLimit: 8, - backingId: 'backing3' - } - } - }) + // await setGovAttr({ + // [`v0/consortium/${idBTC}/mint_limit_daily`]: '5', + // [`v0/consortium/${idBTC}/mint_limit`]: '8', + // [`v0/consortium/${idBTC}/members`]: { + // '01': { + // id: '01', + // name: 'account1BTC', + // ownerAddress: account1, + // mintLimitDaily: 5, + // mintLimit: 8, + // backingId: 'backing1' + // }, + // '03': { + // name: 'account3BTC', + // ownerAddress: account3, + // mintLimitDaily: 5, + // mintLimit: 8, + // backingId: 'backing3' + // } + // } + // }) // Hit global mint limit await tGroup.get(1).rpc.token.mintTokens({ amounts: [`5.0000000@${symbolBTC}`] }) @@ -322,38 +324,38 @@ describe('Consortium', () => { }) it('should throw an error if tried to mint a token while not being an active member of the consortium', async () => { - await setGovAttr({ - [`v0/consortium/${idDOGE}/mint_limit`]: '10', - [`v0/consortium/${idDOGE}/mint_limit_daily`]: '5', - [`v0/consortium/${idDOGE}/members`]: { - '01': { - name: 'account1DOGE', - ownerAddress: account1, - backingId: 'backing1', - mintLimitDaily: 2.00000000, - mintLimit: 5.00000000, - status: 1 - } - } - }) + // await setGovAttr({ + // [`v0/consortium/${idDOGE}/mint_limit`]: '10', + // [`v0/consortium/${idDOGE}/mint_limit_daily`]: '5', + // [`v0/consortium/${idDOGE}/members`]: { + // '01': { + // name: 'account1DOGE', + // ownerAddress: account1, + // backingId: 'backing1', + // mintLimitDaily: 2.00000000, + // mintLimit: 5.00000000, + // status: 1 + // } + // } + // }) await expect(tGroup.get(1).rpc.token.mintTokens({ amounts: [`1@${symbolDOGE}`] })).rejects.toThrow(`Cannot mint token, not an active member of consortium for ${symbolDOGE}!`) }) it('should be able to mint tokens', async () => { - await setGovAttr({ - [`v0/consortium/${idBTC}/mint_limit`]: '10', - [`v0/consortium/${idBTC}/mint_limit_daily`]: '5', - [`v0/consortium/${idBTC}/members`]: { - '02': { - name: 'account2BTC', - ownerAddress: account2, - mintLimit: 10, - mintLimitDaily: 5, - backingId: 'backing2' - } - } - }) + // await setGovAttr({ + // [`v0/consortium/${idBTC}/mint_limit`]: '10', + // [`v0/consortium/${idBTC}/mint_limit_daily`]: '5', + // [`v0/consortium/${idBTC}/members`]: { + // '02': { + // name: 'account2BTC', + // ownerAddress: account2, + // mintLimit: 10, + // mintLimitDaily: 5, + // backingId: 'backing2' + // } + // } + // }) const hash = await tGroup.get(2).rpc.token.mintTokens({ amounts: [`1@${symbolBTC}`] }) expect(hash).toBeTruthy() @@ -368,20 +370,20 @@ describe('Consortium', () => { }) it('should be able to mint tokens to address', async () => { - await setGovAttr({ - 'v0/params/feature/mint-tokens-to-address': 'true', - [`v0/consortium/${idBTC}/mint_limit`]: '10', - [`v0/consortium/${idBTC}/mint_limit_daily`]: '5', - [`v0/consortium/${idBTC}/members`]: { - '02': { - name: 'account2BTC', - ownerAddress: account2, - mintLimit: 10, - mintLimitDaily: 5, - backingId: 'backing2' - } - } - }) + // await setGovAttr({ + // 'v0/params/feature/mint-tokens-to-address': 'true', + // [`v0/consortium/${idBTC}/mint_limit`]: '10', + // [`v0/consortium/${idBTC}/mint_limit_daily`]: '5', + // [`v0/consortium/${idBTC}/members`]: { + // '02': { + // name: 'account2BTC', + // ownerAddress: account2, + // mintLimit: 10, + // mintLimitDaily: 5, + // backingId: 'backing2' + // } + // } + // }) const toAddress = await tGroup.get(2).generateAddress() @@ -397,163 +399,163 @@ describe('Consortium', () => { expect(attr[`v0/live/economy/consortium/${idBTC}/supply`]).toStrictEqual(new BigNumber('1')) }) - it('should be able to set unlimited mint limits per member when global mint_limit or mint_limit_daily is set to -1', async () => { - await setGovAttr({ - [`v0/consortium/${idBTC}/mint_limit_daily`]: '-1', - [`v0/consortium/${idBTC}/mint_limit`]: '-1', - [`v0/consortium/${idBTC}/members`]: { - '01': { - id: '01', - name: 'account1BTC', - ownerAddress: account1, - mintLimitDaily: 10000000, - mintLimit: 10000000, - backingId: 'backing1' - }, - '02': { - name: 'account2BTC', - ownerAddress: account2, - mintLimitDaily: 50000000, - mintLimit: 50000000, - backingId: 'backing2' - }, - '03': { - name: 'account3BTC', - ownerAddress: account3, - mintLimitDaily: 50000000, - mintLimit: 50000000, - backingId: 'backing3' - } - } - }) - }) - - it('should return correct governance attribute values', async () => { - await setGovAttr({ - [`v0/consortium/${idDOGE}/mint_limit`]: '100', - [`v0/consortium/${idDOGE}/mint_limit_daily`]: '50', - [`v0/consortium/${idBTC}/mint_limit`]: '20', - [`v0/consortium/${idBTC}/mint_limit_daily`]: '10', - [`v0/consortium/${idBTC}/members`]: { - '01': { - name: 'account1BTC', - ownerAddress: account1, - backingId: 'backing1', - mintLimitDaily: 5.00000000, - mintLimit: 10.00000000 - }, - '02': { - name: 'account2BTC', - ownerAddress: account2, - backingId: 'backing2', - mintLimitDaily: 5.00000000, - mintLimit: 10.00000000 - } - }, - [`v0/consortium/${idDOGE}/members`]: { - '01': { - name: 'account1DOGE', - ownerAddress: account1, - backingId: 'backing1', - mintLimitDaily: 5.00000000, - mintLimit: 10.00000000 - }, - '02': { - name: 'account2DOGE', - ownerAddress: account2, - backingId: 'backing2', - mintLimitDaily: 5.00000000, - mintLimit: 10.00000000 - } - } - }) - - const attr0 = (await tGroup.get(0).rpc.masternode.getGov('ATTRIBUTES')).ATTRIBUTES - expect(attr0[`v0/consortium/${idBTC}/members`]).toStrictEqual({ - '01': { - name: 'account1BTC', - ownerAddress: account1, - backingId: 'backing1', - mintLimit: new BigNumber(10), - mintLimitDaily: new BigNumber(5), - status: new BigNumber(0) - }, - '02': { - name: 'account2BTC', - ownerAddress: account2, - backingId: 'backing2', - mintLimit: new BigNumber(10), - mintLimitDaily: new BigNumber(5), - status: new BigNumber(0) - } - }) - expect(attr0[`v0/consortium/${idBTC}/mint_limit`]).toStrictEqual('20') - expect(attr0[`v0/consortium/${idBTC}/mint_limit_daily`]).toStrictEqual('10') - - expect(attr0[`v0/consortium/${idDOGE}/members`]).toStrictEqual({ - '01': { - name: 'account1DOGE', - ownerAddress: account1, - backingId: 'backing1', - mintLimit: new BigNumber(10), - mintLimitDaily: new BigNumber(5), - status: new BigNumber(0) - }, - '02': { - name: 'account2DOGE', - ownerAddress: account2, - backingId: 'backing2', - mintLimit: new BigNumber(10), - mintLimitDaily: new BigNumber(5), - status: new BigNumber(0) - } - }) - expect(attr0[`v0/consortium/${idDOGE}/mint_limit`]).toStrictEqual('100') - expect(attr0[`v0/consortium/${idDOGE}/mint_limit_daily`]).toStrictEqual('50') - - await tGroup.get(1).rpc.token.mintTokens({ amounts: [`3@${symbolBTC}`] }) - await tGroup.get(1).rpc.token.mintTokens({ amounts: [`4@${symbolDOGE}`] }) - await tGroup.get(1).generate(1) - await tGroup.waitForSync() - - await tGroup.get(2).rpc.token.mintTokens({ amounts: [`1@${symbolBTC}`] }) - await tGroup.get(2).rpc.token.mintTokens({ amounts: [`2@${symbolDOGE}`] }) - await tGroup.get(2).generate(1) - await tGroup.waitForSync() - - expect((await tGroup.get(1).rpc.account.getAccount(account1))).toStrictEqual([ - `3.00000000@${symbolBTC}`, - `4.00000000@${symbolDOGE}` - ]) - - expect((await tGroup.get(2).rpc.account.getAccount(account2))).toStrictEqual([ - `1.00000000@${symbolBTC}`, - `2.00000000@${symbolDOGE}` - ]) - - const attr2 = (await tGroup.get(2).rpc.masternode.getGov('ATTRIBUTES')).ATTRIBUTES - expect(attr2[`v0/live/economy/consortium/${idBTC}/minted`]).toStrictEqual(new BigNumber(4)) - expect(attr2[`v0/live/economy/consortium/${idBTC}/burnt`]).toStrictEqual(new BigNumber(0)) - expect(attr2[`v0/live/economy/consortium/${idBTC}/supply`]).toStrictEqual(new BigNumber(4)) - expect(attr2[`v0/live/economy/consortium_members/${idBTC}/01/minted`]).toStrictEqual(new BigNumber(3)) - expect(attr2[`v0/live/economy/consortium_members/${idBTC}/01/daily_minted`]).toStrictEqual('0/3.00000000') - expect(attr2[`v0/live/economy/consortium_members/${idBTC}/01/burnt`]).toStrictEqual(new BigNumber(0)) - expect(attr2[`v0/live/economy/consortium_members/${idBTC}/01/supply`]).toStrictEqual(new BigNumber(3)) - expect(attr2[`v0/live/economy/consortium_members/${idBTC}/02/minted`]).toStrictEqual(new BigNumber(1)) - expect(attr2[`v0/live/economy/consortium_members/${idBTC}/02/daily_minted`]).toStrictEqual('0/1.00000000') - expect(attr2[`v0/live/economy/consortium_members/${idBTC}/02/burnt`]).toStrictEqual(new BigNumber(0)) - expect(attr2[`v0/live/economy/consortium_members/${idBTC}/02/supply`]).toStrictEqual(new BigNumber(1)) - - expect(attr2[`v0/live/economy/consortium/${idDOGE}/minted`]).toStrictEqual(new BigNumber(6)) - expect(attr2[`v0/live/economy/consortium/${idDOGE}/burnt`]).toStrictEqual(new BigNumber(0)) - expect(attr2[`v0/live/economy/consortium/${idDOGE}/supply`]).toStrictEqual(new BigNumber(6)) - expect(attr2[`v0/live/economy/consortium_members/${idDOGE}/01/minted`]).toStrictEqual(new BigNumber(4)) - expect(attr2[`v0/live/economy/consortium_members/${idDOGE}/01/daily_minted`]).toStrictEqual('0/4.00000000') - expect(attr2[`v0/live/economy/consortium_members/${idDOGE}/01/burnt`]).toStrictEqual(new BigNumber(0)) - expect(attr2[`v0/live/economy/consortium_members/${idDOGE}/01/supply`]).toStrictEqual(new BigNumber(4)) - expect(attr2[`v0/live/economy/consortium_members/${idDOGE}/02/minted`]).toStrictEqual(new BigNumber(2)) - expect(attr2[`v0/live/economy/consortium_members/${idDOGE}/02/daily_minted`]).toStrictEqual('0/2.00000000') - expect(attr2[`v0/live/economy/consortium_members/${idDOGE}/02/burnt`]).toStrictEqual(new BigNumber(0)) - expect(attr2[`v0/live/economy/consortium_members/${idDOGE}/02/supply`]).toStrictEqual(new BigNumber(2)) - }) + // it('should be able to set unlimited mint limits per member when global mint_limit or mint_limit_daily is set to -1', async () => { + // await setGovAttr({ + // [`v0/consortium/${idBTC}/mint_limit_daily`]: '-1', + // [`v0/consortium/${idBTC}/mint_limit`]: '-1', + // [`v0/consortium/${idBTC}/members`]: { + // '01': { + // id: '01', + // name: 'account1BTC', + // ownerAddress: account1, + // mintLimitDaily: 10000000, + // mintLimit: 10000000, + // backingId: 'backing1' + // }, + // '02': { + // name: 'account2BTC', + // ownerAddress: account2, + // mintLimitDaily: 50000000, + // mintLimit: 50000000, + // backingId: 'backing2' + // }, + // '03': { + // name: 'account3BTC', + // ownerAddress: account3, + // mintLimitDaily: 50000000, + // mintLimit: 50000000, + // backingId: 'backing3' + // } + // } + // }) + // }) + + // it('should return correct governance attribute values', async () => { + // await setGovAttr({ + // [`v0/consortium/${idDOGE}/mint_limit`]: '100', + // [`v0/consortium/${idDOGE}/mint_limit_daily`]: '50', + // [`v0/consortium/${idBTC}/mint_limit`]: '20', + // [`v0/consortium/${idBTC}/mint_limit_daily`]: '10', + // [`v0/consortium/${idBTC}/members`]: { + // '01': { + // name: 'account1BTC', + // ownerAddress: account1, + // backingId: 'backing1', + // mintLimitDaily: 5.00000000, + // mintLimit: 10.00000000 + // }, + // '02': { + // name: 'account2BTC', + // ownerAddress: account2, + // backingId: 'backing2', + // mintLimitDaily: 5.00000000, + // mintLimit: 10.00000000 + // } + // }, + // [`v0/consortium/${idDOGE}/members`]: { + // '01': { + // name: 'account1DOGE', + // ownerAddress: account1, + // backingId: 'backing1', + // mintLimitDaily: 5.00000000, + // mintLimit: 10.00000000 + // }, + // '02': { + // name: 'account2DOGE', + // ownerAddress: account2, + // backingId: 'backing2', + // mintLimitDaily: 5.00000000, + // mintLimit: 10.00000000 + // } + // } + // }) + + // const attr0 = (await tGroup.get(0).rpc.masternode.getGov('ATTRIBUTES')).ATTRIBUTES + // expect(attr0[`v0/consortium/${idBTC}/members`]).toStrictEqual({ + // '01': { + // name: 'account1BTC', + // ownerAddress: account1, + // backingId: 'backing1', + // mintLimit: new BigNumber(10), + // mintLimitDaily: new BigNumber(5), + // status: new BigNumber(0) + // }, + // '02': { + // name: 'account2BTC', + // ownerAddress: account2, + // backingId: 'backing2', + // mintLimit: new BigNumber(10), + // mintLimitDaily: new BigNumber(5), + // status: new BigNumber(0) + // } + // }) + // expect(attr0[`v0/consortium/${idBTC}/mint_limit`]).toStrictEqual('20') + // expect(attr0[`v0/consortium/${idBTC}/mint_limit_daily`]).toStrictEqual('10') + + // expect(attr0[`v0/consortium/${idDOGE}/members`]).toStrictEqual({ + // '01': { + // name: 'account1DOGE', + // ownerAddress: account1, + // backingId: 'backing1', + // mintLimit: new BigNumber(10), + // mintLimitDaily: new BigNumber(5), + // status: new BigNumber(0) + // }, + // '02': { + // name: 'account2DOGE', + // ownerAddress: account2, + // backingId: 'backing2', + // mintLimit: new BigNumber(10), + // mintLimitDaily: new BigNumber(5), + // status: new BigNumber(0) + // } + // }) + // expect(attr0[`v0/consortium/${idDOGE}/mint_limit`]).toStrictEqual('100') + // expect(attr0[`v0/consortium/${idDOGE}/mint_limit_daily`]).toStrictEqual('50') + + // await tGroup.get(1).rpc.token.mintTokens({ amounts: [`3@${symbolBTC}`] }) + // await tGroup.get(1).rpc.token.mintTokens({ amounts: [`4@${symbolDOGE}`] }) + // await tGroup.get(1).generate(1) + // await tGroup.waitForSync() + + // await tGroup.get(2).rpc.token.mintTokens({ amounts: [`1@${symbolBTC}`] }) + // await tGroup.get(2).rpc.token.mintTokens({ amounts: [`2@${symbolDOGE}`] }) + // await tGroup.get(2).generate(1) + // await tGroup.waitForSync() + + // expect((await tGroup.get(1).rpc.account.getAccount(account1))).toStrictEqual([ + // `3.00000000@${symbolBTC}`, + // `4.00000000@${symbolDOGE}` + // ]) + + // expect((await tGroup.get(2).rpc.account.getAccount(account2))).toStrictEqual([ + // `1.00000000@${symbolBTC}`, + // `2.00000000@${symbolDOGE}` + // ]) + + // const attr2 = (await tGroup.get(2).rpc.masternode.getGov('ATTRIBUTES')).ATTRIBUTES + // expect(attr2[`v0/live/economy/consortium/${idBTC}/minted`]).toStrictEqual(new BigNumber(4)) + // expect(attr2[`v0/live/economy/consortium/${idBTC}/burnt`]).toStrictEqual(new BigNumber(0)) + // expect(attr2[`v0/live/economy/consortium/${idBTC}/supply`]).toStrictEqual(new BigNumber(4)) + // expect(attr2[`v0/live/economy/consortium_members/${idBTC}/01/minted`]).toStrictEqual(new BigNumber(3)) + // expect(attr2[`v0/live/economy/consortium_members/${idBTC}/01/daily_minted`]).toStrictEqual('0/3.00000000') + // expect(attr2[`v0/live/economy/consortium_members/${idBTC}/01/burnt`]).toStrictEqual(new BigNumber(0)) + // expect(attr2[`v0/live/economy/consortium_members/${idBTC}/01/supply`]).toStrictEqual(new BigNumber(3)) + // expect(attr2[`v0/live/economy/consortium_members/${idBTC}/02/minted`]).toStrictEqual(new BigNumber(1)) + // expect(attr2[`v0/live/economy/consortium_members/${idBTC}/02/daily_minted`]).toStrictEqual('0/1.00000000') + // expect(attr2[`v0/live/economy/consortium_members/${idBTC}/02/burnt`]).toStrictEqual(new BigNumber(0)) + // expect(attr2[`v0/live/economy/consortium_members/${idBTC}/02/supply`]).toStrictEqual(new BigNumber(1)) + + // expect(attr2[`v0/live/economy/consortium/${idDOGE}/minted`]).toStrictEqual(new BigNumber(6)) + // expect(attr2[`v0/live/economy/consortium/${idDOGE}/burnt`]).toStrictEqual(new BigNumber(0)) + // expect(attr2[`v0/live/economy/consortium/${idDOGE}/supply`]).toStrictEqual(new BigNumber(6)) + // expect(attr2[`v0/live/economy/consortium_members/${idDOGE}/01/minted`]).toStrictEqual(new BigNumber(4)) + // expect(attr2[`v0/live/economy/consortium_members/${idDOGE}/01/daily_minted`]).toStrictEqual('0/4.00000000') + // expect(attr2[`v0/live/economy/consortium_members/${idDOGE}/01/burnt`]).toStrictEqual(new BigNumber(0)) + // expect(attr2[`v0/live/economy/consortium_members/${idDOGE}/01/supply`]).toStrictEqual(new BigNumber(4)) + // expect(attr2[`v0/live/economy/consortium_members/${idDOGE}/02/minted`]).toStrictEqual(new BigNumber(2)) + // expect(attr2[`v0/live/economy/consortium_members/${idDOGE}/02/daily_minted`]).toStrictEqual('0/2.00000000') + // expect(attr2[`v0/live/economy/consortium_members/${idDOGE}/02/burnt`]).toStrictEqual(new BigNumber(0)) + // expect(attr2[`v0/live/economy/consortium_members/${idDOGE}/02/supply`]).toStrictEqual(new BigNumber(2)) + // }) }) diff --git a/packages/jellyfish-api-core/__tests__/category/vault/withdrawFromVault.test.ts b/packages/jellyfish-api-core/__tests__/category/vault/withdrawFromVault.test.ts index d7dead440b..b155e4eadf 100644 --- a/packages/jellyfish-api-core/__tests__/category/vault/withdrawFromVault.test.ts +++ b/packages/jellyfish-api-core/__tests__/category/vault/withdrawFromVault.test.ts @@ -293,7 +293,7 @@ describe('Vault', () => { }) await expect(promise).rejects.toThrow(RpcApiError) - await expect(promise).rejects.toThrow(`Collateral for vault <${vaultId1}> not found`) + await expect(promise).rejects.toThrow('amount 9987.77833000 is less than 10000.00000001') }) it('should not withdrawFromVault cause DFI collateral value less than 50% of the minimum required collateral', async () => { @@ -349,7 +349,7 @@ describe('Vault', () => { }) await expect(promise).rejects.toThrow(RpcApiError) - await expect(promise).rejects.toThrow(`Collateral for vault <${vaultId2}> not found`) + await expect(promise).rejects.toThrow('amount 10000.00000000 is less than 99701.00000000') }) it('should not withdrawFromVault liquidated vault', async () => { diff --git a/packages/jellyfish-api-core/src/category/account.ts b/packages/jellyfish-api-core/src/category/account.ts index 8576f845df..1bb7ed0480 100644 --- a/packages/jellyfish-api-core/src/category/account.ts +++ b/packages/jellyfish-api-core/src/category/account.ts @@ -66,6 +66,10 @@ export enum TransferDomainKey { DST = 'dst' } +export enum TransferDomainOptionalKey { + SINGLE_KEY_CHECK = 'singlekeycheck', +} + /** * Account RPCs for DeFi Blockchain */ @@ -296,16 +300,18 @@ export class Account { /** * Create an transfer domain transaction submitted to a connected node. * - * @param {Array>} payload[] - * @param {Record} payload + * @param {Array | Record>} payload[] + * @param {Record | Record} payload * @param {TransferDomainInfo} info * @param {string} info.address * @param {string} info.amount * @param {TransferDomainType} info.domain * @param {string} [info.data] optional data, note: currently its not used + * @param {TransferDomainOptionalInfo} optionalInfo + * @param {boolean} [optionalInfo.singleKeyCheck=true] * @return {Promise} */ - async transferDomain (payload: Array>): Promise { + async transferDomain (payload: Array | Record>): Promise { return await this.client.call('transferdomain', [payload], 'number') } @@ -725,3 +731,7 @@ export interface TransferDomainInfo { amount: string domain: TransferDomainType } + +export interface TransferDomainOptionalInfo { + singleKeyCheck: boolean +} diff --git a/packages/jellyfish-transaction-builder/__tests__/txn/txn_builder_account_future_swap.test.ts b/packages/jellyfish-transaction-builder/__tests__/txn/txn_builder_account_future_swap.test.ts index 9364070b4a..55584e782e 100644 --- a/packages/jellyfish-transaction-builder/__tests__/txn/txn_builder_account_future_swap.test.ts +++ b/packages/jellyfish-transaction-builder/__tests__/txn/txn_builder_account_future_swap.test.ts @@ -915,7 +915,7 @@ describe('create futureswap', () => { const promise = sendTransaction(testing.container, txn) await expect(promise).rejects.toThrow(DeFiDRpcError) - await expect(promise).rejects.toThrow('DeFiDRpcError: \'DFIP2203Tx: DFIP2203 not currently active (code 16)\', code: -26') + await expect(promise).rejects.toThrow('DeFiDRpcError: \'DFIP2203Tx: DFIP2203 not currently active\', code: -26') }) it('should refund the futureswap if DFIP2203 is disabled before execution', async () => { @@ -1009,7 +1009,7 @@ describe('create futureswap', () => { const promise = sendTransaction(testing.container, txn) await expect(promise).rejects.toThrow(DeFiDRpcError) - await expect(promise).rejects.toThrow('DeFiDRpcError: \'DFIP2203Tx: Source amount must be more than zero (code 16)\', code: -26') + await expect(promise).rejects.toThrow('DeFiDRpcError: \'DFIP2203Tx: Source amount must be more than zero\', code: -26') } { // negative source amount is given @@ -1035,7 +1035,7 @@ describe('create futureswap', () => { const promise = sendTransaction(testing.container, txn) await expect(promise).rejects.toThrow(DeFiDRpcError) - await expect(promise).rejects.toThrow('DeFiDRpcError: \'DFIP2203Tx: Source amount must be more than zero (code 16)\', code: -26') + await expect(promise).rejects.toThrow('DeFiDRpcError: \'DFIP2203Tx: Source amount must be more than zero\', code: -26') } { // invalid source dtoken 100 @@ -1049,7 +1049,7 @@ describe('create futureswap', () => { const promise = sendTransaction(testing.container, txn) await expect(promise).rejects.toThrow(DeFiDRpcError) - await expect(promise).rejects.toThrow('DeFiDRpcError: \'DFIP2203Tx: Could not get source loan token 100 (code 16)\', code: -26') + await expect(promise).rejects.toThrow('DeFiDRpcError: \'DFIP2203Tx: Could not get source loan token 100\', code: -26') } { // non loan source token 1(BTC) @@ -1063,7 +1063,7 @@ describe('create futureswap', () => { const promise = sendTransaction(testing.container, txn) await expect(promise).rejects.toThrow(DeFiDRpcError) - await expect(promise).rejects.toThrow('DeFiDRpcError: \'DFIP2203Tx: Could not get source loan token 1 (code 16)\', code: -26') + await expect(promise).rejects.toThrow('DeFiDRpcError: \'DFIP2203Tx: Could not get source loan token 1\', code: -26') } { // destination is given when futureswap dtoken to dusd @@ -1077,7 +1077,7 @@ describe('create futureswap', () => { const promise = sendTransaction(testing.container, txn) await expect(promise).rejects.toThrow(DeFiDRpcError) - await expect(promise).rejects.toThrow('DeFiDRpcError: \'DFIP2203Tx: Destination should not be set when source amount is dToken or DFI (code 16)\', code: -26') + await expect(promise).rejects.toThrow('DeFiDRpcError: \'DFIP2203Tx: Destination should not be set when source amount is dToken or DFI\', code: -26') } { // INVALID destination 100 is given when futureswap dusd to dtoken @@ -1091,7 +1091,7 @@ describe('create futureswap', () => { const promise = sendTransaction(testing.container, txn) await expect(promise).rejects.toThrow(DeFiDRpcError) - await expect(promise).rejects.toThrow('DeFiDRpcError: \'DFIP2203Tx: Could not get destination loan token 100. Set valid destination. (code 16)\', code: -26') + await expect(promise).rejects.toThrow('DeFiDRpcError: \'DFIP2203Tx: Could not get destination loan token 100. Set valid destination.\', code: -26') } { // arbitrary address without enough balance @@ -1106,7 +1106,7 @@ describe('create futureswap', () => { const promise = sendTransaction(testing.container, txn) await expect(promise).rejects.toThrow(DeFiDRpcError) - await expect(promise).rejects.toThrow('DeFiDRpcError: \'DFIP2203Tx: Transaction must have at least one input from owner (code 16)\', code: -26') + await expect(promise).rejects.toThrow('DeFiDRpcError: \'DFIP2203Tx: Transaction must have at least one input from owner\', code: -26') } }) @@ -1135,7 +1135,7 @@ describe('create futureswap', () => { // Ensure the created txn is correct const promise = sendTransaction(testing.container, txn) await expect(promise).rejects.toThrow(DeFiDRpcError) - await expect(promise).rejects.toThrow('DeFiDRpcError: \'DFIP2203Tx: DFIP2203 currently disabled for token 2 (code 16)\', code: -26') + await expect(promise).rejects.toThrow('DeFiDRpcError: \'DFIP2203Tx: DFIP2203 currently disabled for token 2\', code: -26') }) it('should not create DFI-to-DUSD futureswap while dfip2206f is not active', async () => { @@ -1154,7 +1154,7 @@ describe('create futureswap', () => { const promise = sendTransaction(testing.container, txn) await expect(promise).rejects.toThrow(DeFiDRpcError) - await expect(promise).rejects.toThrow('DeFiDRpcError: \'DFIP2203Tx: DFIP2206F not currently active (code 16)\', code: -26') + await expect(promise).rejects.toThrow('DeFiDRpcError: \'DFIP2203Tx: DFIP2206F not currently active\', code: -26') }) }) @@ -1883,7 +1883,7 @@ describe('withdraw futureswap', () => { const promise = sendTransaction(testing.container, txn) await expect(promise).rejects.toThrow(DeFiDRpcError) - await expect(promise).rejects.toThrow('DeFiDRpcError: \'DFIP2203Tx: amount 1.00000000 is less than 1.00000001 (code 16)\', code: -26') + await expect(promise).rejects.toThrow('DeFiDRpcError: \'DFIP2203Tx: amount 1.00000000 is less than 1.00000001\', code: -26') } // Withdraw fail - Destination should not be set when source amount is dToken or DFI @@ -1898,7 +1898,7 @@ describe('withdraw futureswap', () => { const promise = sendTransaction(testing.container, txn) await expect(promise).rejects.toThrow(DeFiDRpcError) - await expect(promise).rejects.toThrow('DeFiDRpcError: \'DFIP2203Tx: Destination should not be set when source amount is dToken or DFI (code 16)\', code: -26') + await expect(promise).rejects.toThrow('DeFiDRpcError: \'DFIP2203Tx: Destination should not be set when source amount is dToken or DFI\', code: -26') } // Withdraw fail - try to withdraw from unavailable futureswap @@ -1913,7 +1913,7 @@ describe('withdraw futureswap', () => { const promise = sendTransaction(testing.container, txn) await expect(promise).rejects.toThrow(DeFiDRpcError) - await expect(promise).rejects.toThrow('DeFiDRpcError: \'DFIP2203Tx: amount 0.00000000 is less than 0.50000000 (code 16)\', code: -26') + await expect(promise).rejects.toThrow('DeFiDRpcError: \'DFIP2203Tx: amount 0.00000000 is less than 0.50000000\', code: -26') } // Withdraw fail - Invalid source token: 10 @@ -1928,7 +1928,7 @@ describe('withdraw futureswap', () => { const promise = sendTransaction(testing.container, txn) await expect(promise).rejects.toThrow(DeFiDRpcError) - await expect(promise).rejects.toThrow('DeFiDRpcError: \'DFIP2203Tx: Could not get source loan token 10 (code 16)\', code: -26') + await expect(promise).rejects.toThrow('DeFiDRpcError: \'DFIP2203Tx: Could not get source loan token 10\', code: -26') } // withdraw with BTC(1) which is not a loan token @@ -1943,7 +1943,7 @@ describe('withdraw futureswap', () => { const promise = sendTransaction(testing.container, txn) await expect(promise).rejects.toThrow(DeFiDRpcError) - await expect(promise).rejects.toThrow('DeFiDRpcError: \'DFIP2203Tx: Could not get source loan token 1 (code 16)\', code: -26') + await expect(promise).rejects.toThrow('DeFiDRpcError: \'DFIP2203Tx: Could not get source loan token 1\', code: -26') } // withdraw from arbitrary address @@ -1958,7 +1958,7 @@ describe('withdraw futureswap', () => { const promise = sendTransaction(testing.container, txn) await expect(promise).rejects.toThrow(DeFiDRpcError) - await expect(promise).rejects.toThrow('DeFiDRpcError: \'DFIP2203Tx: Transaction must have at least one input from owner (code 16)\', code: -26') + await expect(promise).rejects.toThrow('DeFiDRpcError: \'DFIP2203Tx: Transaction must have at least one input from owner\', code: -26') } // withdraw from arbitrary valid address @@ -1973,7 +1973,7 @@ describe('withdraw futureswap', () => { const promise = sendTransaction(testing.container, txn) await expect(promise).rejects.toThrow(DeFiDRpcError) - await expect(promise).rejects.toThrow('DeFiDRpcError: \'DFIP2203Tx: Transaction must have at least one input from owner (code 16)\', code: -26') + await expect(promise).rejects.toThrow('DeFiDRpcError: \'DFIP2203Tx: Transaction must have at least one input from owner\', code: -26') } // withdraw 0 amount @@ -1988,7 +1988,7 @@ describe('withdraw futureswap', () => { const promise = sendTransaction(testing.container, txn) await expect(promise).rejects.toThrow(DeFiDRpcError) - await expect(promise).rejects.toThrow('DeFiDRpcError: \'DFIP2203Tx: Source amount must be more than zero (code 16)\', code: -26') + await expect(promise).rejects.toThrow('DeFiDRpcError: \'DFIP2203Tx: Source amount must be more than zero\', code: -26') } // withdraw -1 amount @@ -2016,7 +2016,7 @@ describe('withdraw futureswap', () => { const promise = sendTransaction(testing.container, txn) await expect(promise).rejects.toThrow(DeFiDRpcError) - await expect(promise).rejects.toThrow('DeFiDRpcError: \'DFIP2203Tx: Source amount must be more than zero (code 16)\', code: -26') + await expect(promise).rejects.toThrow('DeFiDRpcError: \'DFIP2203Tx: Source amount must be more than zero\', code: -26') } // withdraw after setting ${idTSLA}/dfip2203 to false @@ -2034,7 +2034,7 @@ describe('withdraw futureswap', () => { const promise = sendTransaction(testing.container, txn) await expect(promise).rejects.toThrow(DeFiDRpcError) - await expect(promise).rejects.toThrow('DeFiDRpcError: \'DFIP2203Tx: DFIP2203 currently disabled for token 2 (code 16)\', code: -26') + await expect(promise).rejects.toThrow('DeFiDRpcError: \'DFIP2203Tx: DFIP2203 currently disabled for token 2\', code: -26') await testing.rpc.masternode.setGov({ [attributeKey]: { [`v0/token/${idTSLA}/dfip2203`]: 'true' } }) } @@ -2053,7 +2053,7 @@ describe('withdraw futureswap', () => { const promise = sendTransaction(testing.container, txn) await expect(promise).rejects.toThrow(DeFiDRpcError) - await expect(promise).rejects.toThrow('DeFiDRpcError: \'DFIP2203Tx: DFIP2203 not currently active (code 16)\', code: -26') + await expect(promise).rejects.toThrow('DeFiDRpcError: \'DFIP2203Tx: DFIP2203 not currently active\', code: -26') await testing.rpc.masternode.setGov({ [attributeKey]: { 'v0/params/dfip2203/active': 'true' } }) } @@ -2098,7 +2098,7 @@ describe('withdraw futureswap', () => { const promise = sendTransaction(testing.container, txn) await expect(promise).rejects.toThrow(DeFiDRpcError) - await expect(promise).rejects.toThrow('DeFiDRpcError: \'DFIP2203Tx: amount 0.00000000 is less than 1.00000000 (code 16)\', code: -26') + await expect(promise).rejects.toThrow('DeFiDRpcError: \'DFIP2203Tx: amount 0.00000000 is less than 1.00000000\', code: -26') } }) }) diff --git a/packages/jellyfish-transaction-builder/__tests__/txn/txn_builder_account_transfer_domain.test.ts b/packages/jellyfish-transaction-builder/__tests__/txn/txn_builder_account_transfer_domain.test.ts index f326ddabb0..4615ac8efd 100644 --- a/packages/jellyfish-transaction-builder/__tests__/txn/txn_builder_account_transfer_domain.test.ts +++ b/packages/jellyfish-transaction-builder/__tests__/txn/txn_builder_account_transfer_domain.test.ts @@ -1,6 +1,6 @@ import { DeFiDRpcError, MasterNodeRegTestContainer } from '@defichain/testcontainers' import { getProviders, MockProviders } from '../provider.mock' -import { P2WPKHTransactionBuilder } from '../../src' +import { P2WPKHTransactionBuilder, Prevout } from '../../src' import { fundEllipticPair, sendTransaction } from '../test.utils' import BigNumber from 'bignumber.js' import { Interface, ethers } from 'ethers' @@ -166,11 +166,21 @@ describe('transferDomain', () => { }] } - const txn = await builder.account.transferDomain(transferDomain, dvmScript, { maximumAmount: 50 }) + const utxos: any[] = await container.call('listunspent', [ + 1, 9999999, [dvmAddr], true + ]) + const utxo: Prevout = { + txid: utxos[0].txid, + vout: utxos[0].vout, + value: new BigNumber(utxos[0].amount), + script: dvmScript, + tokenId: utxos[0].tokenId + } + const txn = await builder.account.transferDomain(transferDomain, dvmScript, [utxo]) const promise = sendTransaction(testing.container, txn) await expect(promise).rejects.toThrow(DeFiDRpcError) - await expect(promise).rejects.toThrow('DeFiDRpcError: \'TransferDomainTx: Cannot transfer inside same domain (code 16)') + await expect(promise).rejects.toThrow('DeFiDRpcError: \'TransferDomainTx: Cannot transfer inside same domain') }) it('should fail if amount is different', async () => { @@ -223,11 +233,21 @@ describe('transferDomain', () => { }] } - const txn = await builder.account.transferDomain(transferDomain, dvmScript, { maximumAmount: 50 }) + const utxos: any[] = await container.call('listunspent', [ + 1, 9999999, [dvmAddr], true + ]) + const utxo: Prevout = { + txid: utxos[0].txid, + vout: utxos[0].vout, + value: new BigNumber(utxos[0].amount), + script: dvmScript, + tokenId: utxos[0].tokenId + } + const txn = await builder.account.transferDomain(transferDomain, dvmScript, [utxo]) const promise = sendTransaction(testing.container, txn) await expect(promise).rejects.toThrow(DeFiDRpcError) - await expect(promise).rejects.toThrow('DeFiDRpcError: \'TransferDomainTx: Source amount must be equal to destination amount (code 16)') + await expect(promise).rejects.toThrow('DeFiDRpcError: \'TransferDomainTx: Source amount must be equal to destination amount') }) it('(dvm -> evm) should fail if source address and source domain are not match', async () => { @@ -280,11 +300,21 @@ describe('transferDomain', () => { }] } - const txn = await builder.account.transferDomain(transferDomain, dvmScript, { maximumAmount: 50 }) + const utxos: any[] = await container.call('listunspent', [ + 1, 9999999, [dvmAddr], true + ]) + const utxo: Prevout = { + txid: utxos[0].txid, + vout: utxos[0].vout, + value: new BigNumber(utxos[0].amount), + script: dvmScript, + tokenId: utxos[0].tokenId + } + const txn = await builder.account.transferDomain(transferDomain, dvmScript, [utxo]) const promise = sendTransaction(testing.container, txn) await expect(promise).rejects.toThrow(DeFiDRpcError) - await expect(promise).rejects.toThrow('DeFiDRpcError: \'TransferDomainTx: Src address must be a legacy or Bech32 address in case of "DVM" domain (code 16)\', code: -26') + await expect(promise).rejects.toThrow('DeFiDRpcError: \'TransferDomainTx: Src address must be a legacy or Bech32 address in case of "DVM" domain\', code: -26') }) it('(evm -> dvm) should fail if source address and source domain are not match', async () => { @@ -337,11 +367,21 @@ describe('transferDomain', () => { }] } - const txn = await builder.account.transferDomain(transferDomain, dvmScript, { maximumAmount: 50 }) + const utxos: any[] = await container.call('listunspent', [ + 1, 9999999, [dvmAddr], true + ]) + const utxo: Prevout = { + txid: utxos[0].txid, + vout: utxos[0].vout, + value: new BigNumber(utxos[0].amount), + script: dvmScript, + tokenId: utxos[0].tokenId + } + const txn = await builder.account.transferDomain(transferDomain, dvmScript, [utxo]) const promise = sendTransaction(testing.container, txn) await expect(promise).rejects.toThrow(DeFiDRpcError) - await expect(promise).rejects.toThrow('DeFiDRpcError: \'TransferDomainTx: Src address must be an ERC55 address in case of "EVM" domain (code 16)\', code: -26') + await expect(promise).rejects.toThrow('DeFiDRpcError: \'TransferDomainTx: Src address must be an ERC55 address in case of "EVM" domain\', code: -26') }) it('(dvm -> evm) should fail if destination address and destination domain are not match', async () => { @@ -394,11 +434,21 @@ describe('transferDomain', () => { }] } - const txn = await builder.account.transferDomain(transferDomain, dvmScript, { maximumAmount: 50 }) + const utxos: any[] = await container.call('listunspent', [ + 1, 9999999, [dvmAddr], true + ]) + const utxo: Prevout = { + txid: utxos[0].txid, + vout: utxos[0].vout, + value: new BigNumber(utxos[0].amount), + script: dvmScript, + tokenId: utxos[0].tokenId + } + const txn = await builder.account.transferDomain(transferDomain, dvmScript, [utxo]) const promise = sendTransaction(testing.container, txn) await expect(promise).rejects.toThrow(DeFiDRpcError) - await expect(promise).rejects.toThrow('DeFiDRpcError: \'TransferDomainTx: Dst address must be an ERC55 address in case of "EVM" domain (code 16)') + await expect(promise).rejects.toThrow('DeFiDRpcError: \'TransferDomainTx: Dst address must be an ERC55 address in case of "EVM" domain') }) it('(evm -> dvm) should fail if destination address and destination domain are not match', async () => { @@ -451,11 +501,21 @@ describe('transferDomain', () => { }] } - const txn = await builder.account.transferDomain(transferDomain, dvmScript, { maximumAmount: 50 }) + const utxos: any[] = await container.call('listunspent', [ + 1, 9999999, [dvmAddr], true + ]) + const utxo: Prevout = { + txid: utxos[0].txid, + vout: utxos[0].vout, + value: new BigNumber(utxos[0].amount), + script: dvmScript, + tokenId: utxos[0].tokenId + } + const txn = await builder.account.transferDomain(transferDomain, dvmScript, [utxo]) const promise = sendTransaction(testing.container, txn) await expect(promise).rejects.toThrow(DeFiDRpcError) - await expect(promise).rejects.toThrow('DeFiDRpcError: \'TransferDomainTx: Dst address must be a legacy or Bech32 address in case of "DVM" domain (code 16)\', code: -26') + await expect(promise).rejects.toThrow('DeFiDRpcError: \'TransferDomainTx: Dst address must be a legacy or Bech32 address in case of "DVM" domain\', code: -26') }) it('(dvm -> evm) should fail if address is not owned', async () => { @@ -510,11 +570,21 @@ describe('transferDomain', () => { }] } - const txn = await builder.account.transferDomain(transferDomain, invalidDvmScript, { maximumAmount: 50 }) + const utxos: any[] = await container.call('listunspent', [ + 1, 9999999, [dvmAddr], true + ]) + const utxo: Prevout = { + txid: utxos[0].txid, + vout: utxos[0].vout, + value: new BigNumber(utxos[0].amount), + script: dvmScript, + tokenId: utxos[0].tokenId + } + const txn = await builder.account.transferDomain(transferDomain, invalidDvmScript, [utxo]) const promise = sendTransaction(testing.container, txn) await expect(promise).rejects.toThrow(DeFiDRpcError) - await expect(promise).rejects.toThrow('DeFiDRpcError: \'TransferDomainTx: tx must have at least one input from account owner (code 16)') + await expect(promise).rejects.toThrow('DeFiDRpcError: \'TransferDomainTx: tx must have at least one input from account owner') }) it('should not transfer if custom (isDAT = false) token is transferred', async () => { @@ -568,7 +638,17 @@ describe('transferDomain', () => { }] } - const txn = await builder.account.transferDomain(transferDomain, invalidDvmScript, { maximumAmount: 50 }) + const utxos: any[] = await container.call('listunspent', [ + 1, 9999999, [dvmAddr], true + ]) + const utxo: Prevout = { + txid: utxos[0].txid, + vout: utxos[0].vout, + value: new BigNumber(utxos[0].amount), + script: dvmScript, + tokenId: utxos[0].tokenId + } + const txn = await builder.account.transferDomain(transferDomain, invalidDvmScript, [utxo]) const promise = sendTransaction(testing.container, txn) await expect(promise).rejects.toThrow(DeFiDRpcError) @@ -669,7 +749,17 @@ describe('transferDomain', () => { }] } - const txn = await builder.account.transferDomain(transferDomain, dvmScript, { maximumAmount: 50 }) + const utxos: any[] = await container.call('listunspent', [ + 1, 9999999, [dvmAddr], true + ]) + const utxo: Prevout = { + txid: utxos[0].txid, + vout: utxos[0].vout, + value: new BigNumber(utxos[0].amount), + script: dvmScript, + tokenId: utxos[0].tokenId + } + const txn = await builder.account.transferDomain(transferDomain, dvmScript, [utxo]) const promise = sendTransaction(testing.container, txn) await expect(promise).rejects.toThrow(DeFiDRpcError) @@ -875,7 +965,17 @@ describe('transferDomain', () => { ] } - const txn = await builder.account.transferDomain(transferDomain, dvmScript, { maximumAmount: 50 }) + const utxos: any[] = await container.call('listunspent', [ + 1, 9999999, [dvmAddr], true + ]) + const utxo: Prevout = { + txid: utxos[0].txid, + vout: utxos[0].vout, + value: new BigNumber(utxos[0].amount), + script: dvmScript, + tokenId: utxos[0].tokenId + } + const txn = await builder.account.transferDomain(transferDomain, dvmScript, [utxo]) const promise = sendTransaction(testing.container, txn) await expect(promise).rejects.toThrow(DeFiDRpcError) await expect(promise).rejects.toThrow('TransferDomain currently only supports a single transfer per transaction') @@ -935,10 +1035,18 @@ describe('transferDomain', () => { } }] } - // NOTE(canonbrother): `maximumAmount` is a workaround to grab only single vin - // since maximumCount behaviour does not return by provided value - // but catch up total utxos of the tokenId - const txn = await builder.account.transferDomain(transferDomain, dvmScript, { maximumAmount: 50 }) + + const utxos: any[] = await container.call('listunspent', [ + 1, 9999999, [dvmAddr], true + ]) + const utxo: Prevout = { + txid: utxos[0].txid, + vout: utxos[0].vout, + value: new BigNumber(utxos[0].amount), + script: dvmScript, + tokenId: utxos[0].tokenId + } + const txn = await builder.account.transferDomain(transferDomain, dvmScript, [utxo]) const outs = await sendTransaction(container, txn) const encoded: string = OP_CODES.OP_DEFI_TX_TRANSFER_DOMAIN(transferDomain).asBuffer().toString('hex') const expectedTransferDomainScript = `6a${encoded}` @@ -1026,7 +1134,17 @@ describe('transferDomain', () => { }] } - const txn = await builder.account.transferDomain(transferDomain, dvmScript, { maximumAmount: 50 }) + const utxos: any[] = await container.call('listunspent', [ + 1, 9999999, [dvmAddr], true + ]) + const utxo: Prevout = { + txid: utxos[0].txid, + vout: utxos[0].vout, + value: new BigNumber(utxos[0].amount), + script: dvmScript, + tokenId: utxos[0].tokenId + } + const txn = await builder.account.transferDomain(transferDomain, dvmScript, [utxo]) const outs = await sendTransaction(container, txn) const encoded: string = OP_CODES.OP_DEFI_TX_TRANSFER_DOMAIN(transferDomain).asBuffer().toString('hex') const expectedTransferDomainScript = `6a${encoded}` @@ -1118,7 +1236,17 @@ describe('transferDomain', () => { }] } - const txn = await builder.account.transferDomain(transferDomain, dvmScript, { maximumAmount: 50 }) + const utxos: any[] = await container.call('listunspent', [ + 1, 9999999, [dvmAddr], true + ]) + const utxo: Prevout = { + txid: utxos[0].txid, + vout: utxos[0].vout, + value: new BigNumber(utxos[0].amount), + script: dvmScript, + tokenId: utxos[0].tokenId + } + const txn = await builder.account.transferDomain(transferDomain, dvmScript, [utxo]) const outs = await sendTransaction(container, txn) const encoded: string = OP_CODES.OP_DEFI_TX_TRANSFER_DOMAIN(transferDomain).asBuffer().toString('hex') const expectedTransferDomainScript = `6a${encoded}` @@ -1205,7 +1333,17 @@ describe('transferDomain', () => { }] } - const txn = await builder.account.transferDomain(transferDomain, dvmScript, { maximumAmount: 50 }) + const utxos: any[] = await container.call('listunspent', [ + 1, 9999999, [dvmAddr], true + ]) + const utxo: Prevout = { + txid: utxos[0].txid, + vout: utxos[0].vout, + value: new BigNumber(utxos[0].amount), + script: dvmScript, + tokenId: utxos[0].tokenId + } + const txn = await builder.account.transferDomain(transferDomain, dvmScript, [utxo]) const outs = await sendTransaction(container, txn) const encoded: string = OP_CODES.OP_DEFI_TX_TRANSFER_DOMAIN(transferDomain).asBuffer().toString('hex') const expectedTransferDomainScript = `6a${encoded}` diff --git a/packages/jellyfish-transaction-builder/__tests__/txn/txn_builder_claim_dfc_htlc.test.ts b/packages/jellyfish-transaction-builder/__tests__/txn/txn_builder_claim_dfc_htlc.test.ts index 34a799b80e..96a76d3e41 100644 --- a/packages/jellyfish-transaction-builder/__tests__/txn/txn_builder_claim_dfc_htlc.test.ts +++ b/packages/jellyfish-transaction-builder/__tests__/txn/txn_builder_claim_dfc_htlc.test.ts @@ -219,6 +219,6 @@ describe('claim DFC HTLC', () => { seed: 'INVALID_SEED' } const txn = await builder.icxorderbook.claimDFCHTLC(claimDFCHTLC, script) - await expect(sendTransaction(testing.container, txn)).rejects.toThrow('DeFiDRpcError: \'ICXClaimDFCHTLCTx: hash generated from given seed is different than in dfc htlc: e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 - 957fc0fd643f605b2938e0631a61529fd70bd35b2162a21d978c41e5241a5220! (code 16)\', code: -26') + await expect(sendTransaction(testing.container, txn)).rejects.toThrow('DeFiDRpcError: \'ICXClaimDFCHTLCTx: hash generated from given seed is different than in dfc htlc: e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 - 957fc0fd643f605b2938e0631a61529fd70bd35b2162a21d978c41e5241a5220!\', code: -26') }) }) diff --git a/packages/jellyfish-transaction-builder/__tests__/txn/txn_builder_governance_createcfp.test.ts b/packages/jellyfish-transaction-builder/__tests__/txn/txn_builder_governance_createcfp.test.ts index 3ff1f19dce..344d26b3d8 100644 --- a/packages/jellyfish-transaction-builder/__tests__/txn/txn_builder_governance_createcfp.test.ts +++ b/packages/jellyfish-transaction-builder/__tests__/txn/txn_builder_governance_createcfp.test.ts @@ -150,7 +150,7 @@ describe('createCfp', () => { const promise = sendTransaction(testing.container, txn) await expect(promise).rejects.toThrow(DeFiDRpcError) - await expect(promise).rejects.toThrow("DeFiDRpcError: 'CreateCfpTx: proposal title must not be empty (code 16)', code: -26") + await expect(promise).rejects.toThrow("DeFiDRpcError: 'CreateCfpTx: proposal title must not be empty', code: -26") }) it('should reject with invalid title length', async () => { @@ -169,7 +169,7 @@ describe('createCfp', () => { const promise = sendTransaction(testing.container, txn) await expect(promise).rejects.toThrow(DeFiDRpcError) - await expect(promise).rejects.toThrow("DeFiDRpcError: 'CreateCfpTx: proposal title cannot be more than 128 bytes (code 16)', code: -26") + await expect(promise).rejects.toThrow("DeFiDRpcError: 'CreateCfpTx: proposal title cannot be more than 128 bytes', code: -26") }) it('should reject with empty context', async () => { @@ -188,7 +188,7 @@ describe('createCfp', () => { const promise = sendTransaction(testing.container, txn) await expect(promise).rejects.toThrow(DeFiDRpcError) - await expect(promise).rejects.toThrow("DeFiDRpcError: 'CreateCfpTx: proposal context must not be empty (code 16)', code: -26") + await expect(promise).rejects.toThrow("DeFiDRpcError: 'CreateCfpTx: proposal context must not be empty', code: -26") }) it('should reject with invalid context length', async () => { @@ -207,7 +207,7 @@ describe('createCfp', () => { const promise = sendTransaction(testing.container, txn) await expect(promise).rejects.toThrow(DeFiDRpcError) - await expect(promise).rejects.toThrow("DeFiDRpcError: 'CreateCfpTx: proposal context cannot be more than 512 bytes (code 16)', code: -26") + await expect(promise).rejects.toThrow("DeFiDRpcError: 'CreateCfpTx: proposal context cannot be more than 512 bytes', code: -26") }) it('should reject with invalid context hash length', async () => { @@ -226,7 +226,7 @@ describe('createCfp', () => { const promise = sendTransaction(testing.container, txn) await expect(promise).rejects.toThrow(DeFiDRpcError) - await expect(promise).rejects.toThrow("DeFiDRpcError: 'CreateCfpTx: proposal context hash cannot be more than 512 bytes (code 16)', code: -26") + await expect(promise).rejects.toThrow("DeFiDRpcError: 'CreateCfpTx: proposal context hash cannot be more than 512 bytes', code: -26") }) it('should reject if proposal wants to gain all money (amount exceeds 1.2B DFI)', async () => { @@ -246,6 +246,6 @@ describe('createCfp', () => { const promise = sendTransaction(testing.container, txn) await expect(promise).rejects.toThrow(DeFiDRpcError) - await expect(promise).rejects.toThrow("DeFiDRpcError: 'CreateCfpTx: proposal wants to gain all money (code 16)', code: -26") + await expect(promise).rejects.toThrow("DeFiDRpcError: 'CreateCfpTx: proposal wants to gain all money', code: -26") }) }) diff --git a/packages/jellyfish-transaction-builder/__tests__/txn/txn_builder_governance_createvoc.test.ts b/packages/jellyfish-transaction-builder/__tests__/txn/txn_builder_governance_createvoc.test.ts index d9346edf98..2769493023 100644 --- a/packages/jellyfish-transaction-builder/__tests__/txn/txn_builder_governance_createvoc.test.ts +++ b/packages/jellyfish-transaction-builder/__tests__/txn/txn_builder_governance_createvoc.test.ts @@ -183,7 +183,7 @@ describe('createVoc', () => { const promise = sendTransaction(testing.container, txn) await expect(promise).rejects.toThrow(DeFiDRpcError) - await expect(promise).rejects.toThrow("DeFiDRpcError: 'CreateVocTx: proposal title must not be empty (code 16)', code: -26") + await expect(promise).rejects.toThrow("DeFiDRpcError: 'CreateVocTx: proposal title must not be empty', code: -26") }) it('should reject with invalid title length', async () => { @@ -203,7 +203,7 @@ describe('createVoc', () => { const promise = sendTransaction(testing.container, txn) await expect(promise).rejects.toThrow(DeFiDRpcError) - await expect(promise).rejects.toThrow("DeFiDRpcError: 'CreateVocTx: proposal title cannot be more than 128 bytes (code 16)', code: -26") + await expect(promise).rejects.toThrow("DeFiDRpcError: 'CreateVocTx: proposal title cannot be more than 128 bytes', code: -26") }) it('should reject with empty context', async () => { @@ -223,7 +223,7 @@ describe('createVoc', () => { const promise = sendTransaction(testing.container, txn) await expect(promise).rejects.toThrow(DeFiDRpcError) - await expect(promise).rejects.toThrow("DeFiDRpcError: 'CreateVocTx: proposal context must not be empty (code 16)', code: -26") + await expect(promise).rejects.toThrow("DeFiDRpcError: 'CreateVocTx: proposal context must not be empty', code: -26") }) it('should reject with invalid context length', async () => { @@ -243,7 +243,7 @@ describe('createVoc', () => { const promise = sendTransaction(testing.container, txn) await expect(promise).rejects.toThrow(DeFiDRpcError) - await expect(promise).rejects.toThrow("DeFiDRpcError: 'CreateVocTx: proposal context cannot be more than 512 bytes (code 16)', code: -26") + await expect(promise).rejects.toThrow("DeFiDRpcError: 'CreateVocTx: proposal context cannot be more than 512 bytes', code: -26") }) it('should reject with invalid context hash length', async () => { @@ -263,6 +263,6 @@ describe('createVoc', () => { const promise = sendTransaction(testing.container, txn) await expect(promise).rejects.toThrow(DeFiDRpcError) - await expect(promise).rejects.toThrow("DeFiDRpcError: 'CreateVocTx: proposal context hash cannot be more than 512 bytes (code 16)', code: -26") + await expect(promise).rejects.toThrow("DeFiDRpcError: 'CreateVocTx: proposal context hash cannot be more than 512 bytes', code: -26") }) }) diff --git a/packages/jellyfish-transaction-builder/__tests__/txn/txn_builder_governance_vote.test.ts b/packages/jellyfish-transaction-builder/__tests__/txn/txn_builder_governance_vote.test.ts index 3bd434d97c..1874d456b3 100644 --- a/packages/jellyfish-transaction-builder/__tests__/txn/txn_builder_governance_vote.test.ts +++ b/packages/jellyfish-transaction-builder/__tests__/txn/txn_builder_governance_vote.test.ts @@ -116,7 +116,7 @@ describe('vote', () => { const promise = sendTransaction(testing.container, txn) await expect(promise).rejects.toThrow(DeFiDRpcError) - await expect(promise).rejects.toThrow(`DeFiDRpcError: 'VoteTx: masternode <${invalidMasternodeId}> does not exist (code 16)', code: -26`) + await expect(promise).rejects.toThrow(`DeFiDRpcError: 'VoteTx: masternode <${invalidMasternodeId}> does not exist', code: -26`) }) it('should not vote on a proposal that does not exist', async () => { @@ -146,7 +146,7 @@ describe('vote', () => { const promise = sendTransaction(testing.container, txn) await expect(promise).rejects.toThrow(DeFiDRpcError) - await expect(promise).rejects.toThrow(`DeFiDRpcError: 'VoteTx: proposal <${proposalId}> does not exist (code 16)', code: -26`) + await expect(promise).rejects.toThrow(`DeFiDRpcError: 'VoteTx: proposal <${proposalId}> does not exist', code: -26`) }) it('should not vote on a proposal with a masternode that did not mint at least one block', async () => { @@ -175,7 +175,7 @@ describe('vote', () => { const promise = sendTransaction(testing.container, txn) await expect(promise).rejects.toThrow(DeFiDRpcError) - await expect(promise).rejects.toThrow(`DeFiDRpcError: 'VoteTx: masternode <${masternodeId}> does not mine at least one block (code 16)', code: -26`) + await expect(promise).rejects.toThrow(`DeFiDRpcError: 'VoteTx: masternode <${masternodeId}> does not mine at least one block', code: -26`) }) it('should not vote on a proposal not in voting period', async () => { @@ -207,7 +207,7 @@ describe('vote', () => { const promise = sendTransaction(testing.container, txn) await expect(promise).rejects.toThrow(DeFiDRpcError) - await expect(promise).rejects.toThrow(`DeFiDRpcError: 'VoteTx: proposal <${proposalId}> is not in voting period (code 16)', code: -26`) + await expect(promise).rejects.toThrow(`DeFiDRpcError: 'VoteTx: proposal <${proposalId}> is not in voting period', code: -26`) }) }) @@ -273,6 +273,6 @@ describe('vote with masternode operator with legacy address', () => { const promise = sendTransaction(testing.container, txn) await expect(promise).rejects.toThrow(DeFiDRpcError) - await expect(promise).rejects.toThrow("DeFiDRpcError: 'VoteTx: tx must have at least one input from the owner (code 16)', code: -26") + await expect(promise).rejects.toThrow("DeFiDRpcError: 'VoteTx: tx must have at least one input from the owner', code: -26") }) }) diff --git a/packages/jellyfish-transaction-builder/__tests__/txn/txn_builder_icx_close_offer.test.ts b/packages/jellyfish-transaction-builder/__tests__/txn/txn_builder_icx_close_offer.test.ts index 4a3e479726..ab6ae7b99e 100644 --- a/packages/jellyfish-transaction-builder/__tests__/txn/txn_builder_icx_close_offer.test.ts +++ b/packages/jellyfish-transaction-builder/__tests__/txn/txn_builder_icx_close_offer.test.ts @@ -101,7 +101,7 @@ describe('close ICX offer', () => { } const txn = await builder.icxorderbook.closeOffer(closeOffer, script) - await expect(sendTransaction(testing.container, txn)).rejects.toThrow("DeFiDRpcError: 'ICXCloseOfferTx: offer with creation tx 0000000000000000000000000000000000000000000000000000000000000000 does not exists! (code 16)', code: -26") + await expect(sendTransaction(testing.container, txn)).rejects.toThrow("DeFiDRpcError: 'ICXCloseOfferTx: offer with creation tx 0000000000000000000000000000000000000000000000000000000000000000 does not exists!', code: -26") }) it('should not close ICX order with input not from offer owner', async () => { @@ -120,6 +120,6 @@ describe('close ICX offer', () => { const txn = await newBuilder.icxorderbook.closeOffer({ offerTx }, newAddressScript) - await expect(sendTransaction(testing.container, txn)).rejects.toThrow("DeFiDRpcError: 'ICXCloseOfferTx: tx must have at least one input from offer owner (code 16)', code: -26") + await expect(sendTransaction(testing.container, txn)).rejects.toThrow("DeFiDRpcError: 'ICXCloseOfferTx: tx must have at least one input from offer owner', code: -26") }) }) diff --git a/packages/jellyfish-transaction-builder/__tests__/txn/txn_builder_icx_close_order.test.ts b/packages/jellyfish-transaction-builder/__tests__/txn/txn_builder_icx_close_order.test.ts index 938d343550..21321dde6e 100644 --- a/packages/jellyfish-transaction-builder/__tests__/txn/txn_builder_icx_close_order.test.ts +++ b/packages/jellyfish-transaction-builder/__tests__/txn/txn_builder_icx_close_order.test.ts @@ -100,7 +100,7 @@ describe('close ICX order', () => { } const txn = await builder.icxorderbook.closeOrder(closeOrder, script) - await expect(sendTransaction(testing.container, txn)).rejects.toThrow("DeFiDRpcError: 'ICXCloseOrderTx: order with creation tx 0000000000000000000000000000000000000000000000000000000000000000 does not exists! (code 16)', code: -26") + await expect(sendTransaction(testing.container, txn)).rejects.toThrow("DeFiDRpcError: 'ICXCloseOrderTx: order with creation tx 0000000000000000000000000000000000000000000000000000000000000000 does not exists!', code: -26") }) it('should not close ICX order with input not from order owner', async () => { @@ -118,6 +118,6 @@ describe('close ICX order', () => { const txn = await newBuilder.icxorderbook.closeOrder({ orderTx }, newAddressScript) - await expect(sendTransaction(testing.container, txn)).rejects.toThrow("DeFiDRpcError: 'ICXCloseOrderTx: tx must have at least one input from order owner (code 16)', code: -26") + await expect(sendTransaction(testing.container, txn)).rejects.toThrow("DeFiDRpcError: 'ICXCloseOrderTx: tx must have at least one input from order owner', code: -26") }) }) diff --git a/packages/jellyfish-transaction-builder/__tests__/txn/txn_builder_loan_close_vault.test.ts b/packages/jellyfish-transaction-builder/__tests__/txn/txn_builder_loan_close_vault.test.ts index 1fb65cd27c..9a156a2c87 100644 --- a/packages/jellyfish-transaction-builder/__tests__/txn/txn_builder_loan_close_vault.test.ts +++ b/packages/jellyfish-transaction-builder/__tests__/txn/txn_builder_loan_close_vault.test.ts @@ -303,7 +303,7 @@ describe('loans.closeVault', () => { }, script) const promise = sendTransaction(tGroup.get(0).container, txn) - await expect(promise).rejects.toThrow(`DeFiDRpcError: 'CloseVaultTx: Vault <${'0'.repeat(64)}> not found (code 16)', code: -26`) + await expect(promise).rejects.toThrow(`DeFiDRpcError: 'CloseVaultTx: Vault <${'0'.repeat(64)}> not found', code: -26`) }) it('should not closeVault for vault with loan taken', async () => { @@ -314,7 +314,7 @@ describe('loans.closeVault', () => { }, script) const promise = sendTransaction(tGroup.get(0).container, txn) - await expect(promise).rejects.toThrow(`DeFiDRpcError: 'CloseVaultTx: Vault <${vaultWithLoanTakenId}> has loans (code 16)', code: -26`) + await expect(promise).rejects.toThrow(`DeFiDRpcError: 'CloseVaultTx: Vault <${vaultWithLoanTakenId}> has loans', code: -26`) }) it('should not closeVault for mayliquidate vault', async () => { @@ -333,7 +333,7 @@ describe('loans.closeVault', () => { }, script) const promise = sendTransaction(tGroup.get(0).container, txn) - await expect(promise).rejects.toThrow(`DeFiDRpcError: 'CloseVaultTx: Vault <${vaultWithLiquidationId}> has loans (code 16)', code: -26`) + await expect(promise).rejects.toThrow(`DeFiDRpcError: 'CloseVaultTx: Vault <${vaultWithLiquidationId}> has loans', code: -26`) await tGroup.get(0).rpc.oracle.setOracleData(oracleId, Math.floor(new Date().getTime() / 1000), { prices: [{ tokenAmount: '2@TSLA', currency: 'USD' }] }) await tGroup.get(0).generate(1) @@ -357,7 +357,7 @@ describe('loans.closeVault', () => { }, script) const promise = sendTransaction(tGroup.get(0).container, txn) - await expect(promise).rejects.toThrow(`DeFiDRpcError: 'CloseVaultTx: Vault <${vaultWithLiquidationId}> has loans (code 16)', code: -26`) + await expect(promise).rejects.toThrow(`DeFiDRpcError: 'CloseVaultTx: Vault <${vaultWithLiquidationId}> has loans', code: -26`) await tGroup.get(0).container.waitForPriceValid('TSLA/USD') @@ -385,7 +385,7 @@ describe('loans.closeVault', () => { }, script) const promise = sendTransaction(tGroup.get(0).container, txn) - await expect(promise).rejects.toThrow('DeFiDRpcError: \'CloseVaultTx: Cannot close vault under liquidation (code 16)\', code: -26') + await expect(promise).rejects.toThrow('DeFiDRpcError: \'CloseVaultTx: Cannot close vault under liquidation\', code: -26') await tGroup.get(0).rpc.oracle.setOracleData(oracleId, Math.floor(new Date().getTime() / 1000), { prices: [{ tokenAmount: '2@TSLA', currency: 'USD' }] }) await tGroup.get(0).generate(1) @@ -405,6 +405,6 @@ describe('loans.closeVault', () => { const promise = sendTransaction(tGroup.get(0).container, txn) await expect(promise).rejects.toThrow(DeFiDRpcError) - await expect(promise).rejects.toThrow('DeFiDRpcError: \'CloseVaultTx: tx must have at least one input from token owner (code 16)\', code: -26') + await expect(promise).rejects.toThrow('DeFiDRpcError: \'CloseVaultTx: tx must have at least one input from token owner\', code: -26') }) }) diff --git a/packages/jellyfish-transaction-builder/__tests__/txn/txn_builder_loan_create_vault.test.ts b/packages/jellyfish-transaction-builder/__tests__/txn/txn_builder_loan_create_vault.test.ts index 121df77c69..b24e1e5f0e 100644 --- a/packages/jellyfish-transaction-builder/__tests__/txn/txn_builder_loan_create_vault.test.ts +++ b/packages/jellyfish-transaction-builder/__tests__/txn/txn_builder_loan_create_vault.test.ts @@ -251,7 +251,7 @@ describe('loans.createVault', () => { const promise = sendTransaction(testing.container, txn) await expect(promise).rejects.toThrow(DeFiDRpcError) - await expect(promise).rejects.toThrow('VaultTx: Cannot find existing loan scheme with id scheme3 (code 16)\', code: -26') + await expect(promise).rejects.toThrow('VaultTx: Cannot find existing loan scheme with id scheme3\', code: -26') }) it('should not createVault with scheme set to be destroyed', async () => { @@ -275,7 +275,7 @@ describe('loans.createVault', () => { const promise = sendTransaction(testing.container, txn) await expect(promise).rejects.toThrow(DeFiDRpcError) - await expect(promise).rejects.toThrow('VaultTx: Cannot set scheme4 as loan scheme, set to be destroyed on block 150 (code 16)\', code: -26') + await expect(promise).rejects.toThrow('VaultTx: Cannot set scheme4 as loan scheme, set to be destroyed on block 150\', code: -26') }) }) @@ -314,6 +314,6 @@ describe('loans.createVault when no default scheme and the given schemeId is emp const promise = sendTransaction(testing.container, txn) await expect(promise).rejects.toThrow(DeFiDRpcError) - await expect(promise).rejects.toThrow('DeFiDRpcError: \'VaultTx: There is no default loan scheme (code 16)\', code: -26') + await expect(promise).rejects.toThrow('DeFiDRpcError: \'VaultTx: There is no default loan scheme\', code: -26') }) }) diff --git a/packages/jellyfish-transaction-builder/__tests__/txn/txn_builder_loan_deposit_to_vault.test.ts b/packages/jellyfish-transaction-builder/__tests__/txn/txn_builder_loan_deposit_to_vault.test.ts index 0527e25457..6f39e72f1c 100644 --- a/packages/jellyfish-transaction-builder/__tests__/txn/txn_builder_loan_deposit_to_vault.test.ts +++ b/packages/jellyfish-transaction-builder/__tests__/txn/txn_builder_loan_deposit_to_vault.test.ts @@ -316,7 +316,7 @@ describe('loans.depositToVault', () => { const promise = sendTransaction(tGroup.get(0).container, txn) await expect(promise).rejects.toThrow(DeFiDRpcError) - await expect(promise).rejects.toThrow('DepositToVaultTx: tx must have at least one input from token owner (code 16)\', code: -26') + await expect(promise).rejects.toThrow('DepositToVaultTx: tx must have at least one input from token owner\', code: -26') }) it('should be failed as vault is not exists', async () => { diff --git a/packages/jellyfish-transaction-builder/__tests__/txn/txn_builder_loan_destroy_loan_scheme.test.ts b/packages/jellyfish-transaction-builder/__tests__/txn/txn_builder_loan_destroy_loan_scheme.test.ts index b9d0a94b9f..51df686bf4 100644 --- a/packages/jellyfish-transaction-builder/__tests__/txn/txn_builder_loan_destroy_loan_scheme.test.ts +++ b/packages/jellyfish-transaction-builder/__tests__/txn/txn_builder_loan_destroy_loan_scheme.test.ts @@ -96,7 +96,7 @@ describe('loan.destroyLoanScheme()', () => { const promise = sendTransaction(testing.container, txn) await expect(promise).rejects.toThrow(DeFiDRpcError) - await expect(promise).rejects.toThrow('DestroyLoanSchemeTx: id cannot be empty or more than 8 chars long (code 16)\', code: -26') + await expect(promise).rejects.toThrow('DestroyLoanSchemeTx: id cannot be empty or more than 8 chars long\', code: -26') }) it('should not destroyLoanScheme if identifier is an empty string', async () => { @@ -108,7 +108,7 @@ describe('loan.destroyLoanScheme()', () => { const promise = sendTransaction(testing.container, txn) await expect(promise).rejects.toThrow(DeFiDRpcError) - await expect(promise).rejects.toThrow('DestroyLoanSchemeTx: id cannot be empty or more than 8 chars long (code 16)\', code: -26') + await expect(promise).rejects.toThrow('DestroyLoanSchemeTx: id cannot be empty or more than 8 chars long\', code: -26') }) it('should not destroyLoanScheme if identifier does not exists', async () => { @@ -120,7 +120,7 @@ describe('loan.destroyLoanScheme()', () => { const promise = sendTransaction(testing.container, txn) await expect(promise).rejects.toThrow(DeFiDRpcError) - await expect(promise).rejects.toThrow('DestroyLoanSchemeTx: Cannot find existing loan scheme with id scheme2 (code 16)\', code: -26') + await expect(promise).rejects.toThrow('DestroyLoanSchemeTx: Cannot find existing loan scheme with id scheme2\', code: -26') }) it('should not destroyLoanScheme if identifier is a default scheme', async () => { @@ -132,7 +132,7 @@ describe('loan.destroyLoanScheme()', () => { const promise = sendTransaction(testing.container, txn) await expect(promise).rejects.toThrow(DeFiDRpcError) - await expect(promise).rejects.toThrow('DeFiDRpcError: \'DestroyLoanSchemeTx: Cannot destroy default loan scheme, set new default first (code 16)\', code: -26') + await expect(promise).rejects.toThrow('DeFiDRpcError: \'DestroyLoanSchemeTx: Cannot destroy default loan scheme, set new default first\', code: -26') }) }) @@ -239,6 +239,6 @@ describe('loan.destroyLoanScheme() with height less than current height', () => const promise = sendTransaction(testing.container, txn) await expect(promise).rejects.toThrow(DeFiDRpcError) - await expect(promise).rejects.toThrow('DeFiDRpcError: \'DestroyLoanSchemeTx: Destruction height below current block height, set future height (code 16)\', code: -26') + await expect(promise).rejects.toThrow('DeFiDRpcError: \'DestroyLoanSchemeTx: Destruction height below current block height, set future height\', code: -26') }) }) diff --git a/packages/jellyfish-transaction-builder/__tests__/txn/txn_builder_loan_payback_loan.test.ts b/packages/jellyfish-transaction-builder/__tests__/txn/txn_builder_loan_payback_loan.test.ts index 65c419c1da..7f36094362 100644 --- a/packages/jellyfish-transaction-builder/__tests__/txn/txn_builder_loan_payback_loan.test.ts +++ b/packages/jellyfish-transaction-builder/__tests__/txn/txn_builder_loan_payback_loan.test.ts @@ -864,7 +864,7 @@ describe('paybackLoan failed #2', () => { const promise = sendTransaction(bob.container, txn) await expect(promise).rejects.toThrow(DeFiDRpcError) - await expect(promise).rejects.toThrow('DeFiDRpcError: \'PaybackLoanTx: amount 0.00000000 is less than 0.00006850 (code 16)\', code: -26') + await expect(promise).rejects.toThrow('DeFiDRpcError: \'PaybackLoanTx: amount 0.00000000 is less than 0.00006850\', code: -26') }) }) @@ -2110,7 +2110,7 @@ describe('paybackLoan for any token', () => { }, script) let promise = sendTransaction(testing.container, txn) - await expect(promise).rejects.toThrow('DeFiDRpcError: \'PaybackLoanTx: Payback of loan via DFI token is not currently active (code 16)\', code: -26') + await expect(promise).rejects.toThrow('DeFiDRpcError: \'PaybackLoanTx: Payback of loan via DFI token is not currently active\', code: -26') await testing.rpc.masternode.setGov({ [attributeKey]: { [key]: 'false' } }) await testing.container.generate(1) @@ -2129,7 +2129,7 @@ describe('paybackLoan for any token', () => { }, script) promise = sendTransaction(testing.container, txn) - await expect(promise).rejects.toThrow('DeFiDRpcError: \'PaybackLoanTx: Payback of loan via DFI token is not currently active (code 16)\', code: -26') + await expect(promise).rejects.toThrow('DeFiDRpcError: \'PaybackLoanTx: Payback of loan via DFI token is not currently active\', code: -26') }) it('should not be able to payback TSLA loan using DFI when the governance is set to payback DUSD using DFI', async () => { @@ -2155,7 +2155,7 @@ describe('paybackLoan for any token', () => { }, script) const promise = sendTransaction(testing.container, txn) - await expect(promise).rejects.toThrow('DeFiDRpcError: \'PaybackLoanTx: There is no loan on token (DUSD) in this vault! (code 16)\', code: -26') + await expect(promise).rejects.toThrow('DeFiDRpcError: \'PaybackLoanTx: There is no loan on token (DUSD) in this vault!\', code: -26') }) it('should not be able to payback DUSD loan using other tokens', async () => { @@ -2173,7 +2173,7 @@ describe('paybackLoan for any token', () => { }, script) const promise = sendTransaction(testing.container, txn) - await expect(promise).rejects.toThrow('DeFiDRpcError: \'PaybackLoanTx: There is no loan on token (TSLA) in this vault! (code 16)\', code: -26') + await expect(promise).rejects.toThrow('DeFiDRpcError: \'PaybackLoanTx: There is no loan on token (TSLA) in this vault!\', code: -26') }) it('should not be able to payback TSLA loan using DFI - without PaybackLoanMetadataV2', async () => { @@ -2207,7 +2207,7 @@ describe('paybackLoan for any token', () => { }, script) const payBackPromise = sendTransaction(testing.container, txn) - await expect(payBackPromise).rejects.toThrow('DeFiDRpcError: \'PaybackLoanTx: Payback of loan via DFI token is not currently active (code 16)\', code: -26') + await expect(payBackPromise).rejects.toThrow('DeFiDRpcError: \'PaybackLoanTx: Payback of loan via DFI token is not currently active\', code: -26') }) it('should not be able to payback TSLA loan using BTC - without PaybackLoanMetadataV2', async () => { @@ -2265,7 +2265,7 @@ describe('paybackLoan for any token', () => { }, script) const payBackPromise = sendTransaction(testing.container, txn) - await expect(payBackPromise).rejects.toThrow('DeFiDRpcError: \'PaybackLoanTx: Loan token with id (3) does not exist! (code 16)\', code: -26') + await expect(payBackPromise).rejects.toThrow('DeFiDRpcError: \'PaybackLoanTx: Loan token with id (3) does not exist!\', code: -26') }) it('should not be able to payback DUSD loan using TSLA - without PaybackLoanMetadataV2', async () => { @@ -2296,6 +2296,6 @@ describe('paybackLoan for any token', () => { }, script) const payBackPromise = sendTransaction(testing.container, txn) - await expect(payBackPromise).rejects.toThrow('DeFiDRpcError: \'PaybackLoanTx: There is no loan on token (TSLA) in this vault! (code 16)\', code: -26') + await expect(payBackPromise).rejects.toThrow('DeFiDRpcError: \'PaybackLoanTx: There is no loan on token (TSLA) in this vault!\', code: -26') }) }) diff --git a/packages/jellyfish-transaction-builder/__tests__/txn/txn_builder_loan_set_collateral_token.test.ts b/packages/jellyfish-transaction-builder/__tests__/txn/txn_builder_loan_set_collateral_token.test.ts index 1230b8a4d8..084a140862 100644 --- a/packages/jellyfish-transaction-builder/__tests__/txn/txn_builder_loan_set_collateral_token.test.ts +++ b/packages/jellyfish-transaction-builder/__tests__/txn/txn_builder_loan_set_collateral_token.test.ts @@ -88,7 +88,7 @@ describe('loan.setCollateralToken()', () => { activateAfterBlock: 0 }, script) const promise = sendTransaction(testing.container, txn) - await expect(promise).rejects.toThrow('DeFiDRpcError: \'SetLoanCollateralTokenTx: No such token (2) (code 16)\', code: -26') + await expect(promise).rejects.toThrow('DeFiDRpcError: \'SetLoanCollateralTokenTx: No such token (2)\', code: -26') }) it('should setCollateralToken if factor is greater than 1', async () => { @@ -115,6 +115,6 @@ describe('loan.setCollateralToken()', () => { activateAfterBlock: 0 }, script) const promise = sendTransaction(testing.container, txn) - await expect(promise).rejects.toThrow('DeFiDRpcError: \'SetLoanCollateralTokenTx: Price feed MFST/USD does not belong to any oracle (code 16)\', code: -26') + await expect(promise).rejects.toThrow('DeFiDRpcError: \'SetLoanCollateralTokenTx: Price feed MFST/USD does not belong to any oracle\', code: -26') }) }) diff --git a/packages/jellyfish-transaction-builder/__tests__/txn/txn_builder_loan_set_default_loan_scheme.test.ts b/packages/jellyfish-transaction-builder/__tests__/txn/txn_builder_loan_set_default_loan_scheme.test.ts index 45bf01b609..7d0bc7f374 100644 --- a/packages/jellyfish-transaction-builder/__tests__/txn/txn_builder_loan_set_default_loan_scheme.test.ts +++ b/packages/jellyfish-transaction-builder/__tests__/txn/txn_builder_loan_set_default_loan_scheme.test.ts @@ -87,7 +87,7 @@ describe('loan.setDefaultLoanScheme()', () => { const promise = sendTransaction(testing.container, txn) await expect(promise).rejects.toThrow(DeFiDRpcError) - await expect(promise).rejects.toThrow('DefaultLoanSchemeTx: id cannot be empty or more than 8 chars long (code 16)\', code: -26') + await expect(promise).rejects.toThrow('DefaultLoanSchemeTx: id cannot be empty or more than 8 chars long\', code: -26') }) it('should not setDefaultLoanScheme if identifier is more than 8 chars long', async () => { @@ -98,7 +98,7 @@ describe('loan.setDefaultLoanScheme()', () => { const promise = sendTransaction(testing.container, txn) await expect(promise).rejects.toThrow(DeFiDRpcError) - await expect(promise).rejects.toThrow('DefaultLoanSchemeTx: id cannot be empty or more than 8 chars long (code 16)\', code: -26') + await expect(promise).rejects.toThrow('DefaultLoanSchemeTx: id cannot be empty or more than 8 chars long\', code: -26') }) it('should not setDefaultLoanScheme if identifier does not exists', async () => { @@ -109,7 +109,7 @@ describe('loan.setDefaultLoanScheme()', () => { const promise = sendTransaction(testing.container, txn) await expect(promise).rejects.toThrow(DeFiDRpcError) - await expect(promise).rejects.toThrow('DefaultLoanSchemeTx: Cannot find existing loan scheme with id scheme3 (code 16)\', code: -26') + await expect(promise).rejects.toThrow('DefaultLoanSchemeTx: Cannot find existing loan scheme with id scheme3\', code: -26') }) it('should not setDefaultLoanScheme if the identifier is a default scheme', async () => { @@ -120,7 +120,7 @@ describe('loan.setDefaultLoanScheme()', () => { const promise = sendTransaction(testing.container, txn) await expect(promise).rejects.toThrow(DeFiDRpcError) - await expect(promise).rejects.toThrow('DefaultLoanSchemeTx: Loan scheme with id scheme1 is already set as default (code 16)\', code: -26') + await expect(promise).rejects.toThrow('DefaultLoanSchemeTx: Loan scheme with id scheme1 is already set as default\', code: -26') }) it('should not setDefaultLoanScheme if the scheme is going to be deleted at future block', async () => { @@ -143,7 +143,7 @@ describe('loan.setDefaultLoanScheme()', () => { const promise = sendTransaction(container, txn) await expect(promise).rejects.toThrow(DeFiDRpcError) - await expect(promise).rejects.toThrow('DefaultLoanSchemeTx: Cannot set scheme3 as default, set to destroyed on block 120 (code 16)\', code: -26') + await expect(promise).rejects.toThrow('DefaultLoanSchemeTx: Cannot set scheme3 as default, set to destroyed on block 120\', code: -26') // Delete at block 120 await testing.container.waitForBlockHeight(120) diff --git a/packages/jellyfish-transaction-builder/__tests__/txn/txn_builder_loan_set_loan_scheme.test.ts b/packages/jellyfish-transaction-builder/__tests__/txn/txn_builder_loan_set_loan_scheme.test.ts index a12e1b81e8..a2b870cd74 100644 --- a/packages/jellyfish-transaction-builder/__tests__/txn/txn_builder_loan_set_loan_scheme.test.ts +++ b/packages/jellyfish-transaction-builder/__tests__/txn/txn_builder_loan_set_loan_scheme.test.ts @@ -90,7 +90,7 @@ describe('loan.createLoanScheme()', () => { const promise = sendTransaction(testing.container, txn) await expect(promise).rejects.toThrow(DeFiDRpcError) - await expect(promise).rejects.toThrow('LoanSchemeTx: minimum collateral ratio cannot be less than 100 (code 16)\', code: -26') + await expect(promise).rejects.toThrow('LoanSchemeTx: minimum collateral ratio cannot be less than 100\', code: -26') }) it('should not createLoanScheme if rate is less than 0.01', async () => { @@ -104,7 +104,7 @@ describe('loan.createLoanScheme()', () => { const promise = sendTransaction(testing.container, txn) await expect(promise).rejects.toThrow(DeFiDRpcError) - await expect(promise).rejects.toThrow('LoanSchemeTx: interest rate cannot be less than 0.01 (code 16)\', code: -26') + await expect(promise).rejects.toThrow('LoanSchemeTx: interest rate cannot be less than 0.01\', code: -26') }) it('should not createLoanScheme if same ratio and rate were created before', async () => { @@ -118,7 +118,7 @@ describe('loan.createLoanScheme()', () => { const promise = sendTransaction(testing.container, txn) await expect(promise).rejects.toThrow(DeFiDRpcError) - await expect(promise).rejects.toThrow('LoanSchemeTx: Loan scheme default with same interestrate and mincolratio already exists (code 16)\', code: -26') + await expect(promise).rejects.toThrow('LoanSchemeTx: Loan scheme default with same interestrate and mincolratio already exists\', code: -26') }) it('should not createLoanScheme if same identifier was created before', async () => { @@ -132,7 +132,7 @@ describe('loan.createLoanScheme()', () => { const promise = sendTransaction(testing.container, txn) await expect(promise).rejects.toThrow(DeFiDRpcError) - await expect(promise).rejects.toThrow('LoanSchemeTx: Loan scheme already exist with id default (code 16)\', code: -26') + await expect(promise).rejects.toThrow('LoanSchemeTx: Loan scheme already exist with id default\', code: -26') }) it('should not createLoanScheme if identifier is an empty string', async () => { @@ -146,7 +146,7 @@ describe('loan.createLoanScheme()', () => { const promise = sendTransaction(testing.container, txn) await expect(promise).rejects.toThrow(DeFiDRpcError) - await expect(promise).rejects.toThrow('LoanSchemeTx: id cannot be empty or more than 8 chars long (code 16)\', code: -26') + await expect(promise).rejects.toThrow('LoanSchemeTx: id cannot be empty or more than 8 chars long\', code: -26') }) it('should not createLoanScheme if identifier is more than 8 chars long', async () => { @@ -160,7 +160,7 @@ describe('loan.createLoanScheme()', () => { const promise = sendTransaction(testing.container, txn) await expect(promise).rejects.toThrow(DeFiDRpcError) - await expect(promise).rejects.toThrow('LoanSchemeTx: id cannot be empty or more than 8 chars long (code 16)\', code: -26') + await expect(promise).rejects.toThrow('LoanSchemeTx: id cannot be empty or more than 8 chars long\', code: -26') }) }) @@ -254,7 +254,7 @@ describe('loan.updateLoanScheme()', () => { const promise = sendTransaction(testing.container, txn) await expect(promise).rejects.toThrow(DeFiDRpcError) - await expect(promise).rejects.toThrow('LoanSchemeTx: minimum collateral ratio cannot be less than 100 (code 16)\', code: -26') + await expect(promise).rejects.toThrow('LoanSchemeTx: minimum collateral ratio cannot be less than 100\', code: -26') }) it('should not updateLoanScheme if rate is less than 0.01', async () => { @@ -268,7 +268,7 @@ describe('loan.updateLoanScheme()', () => { const promise = sendTransaction(testing.container, txn) await expect(promise).rejects.toThrow(DeFiDRpcError) - await expect(promise).rejects.toThrow('LoanSchemeTx: interest rate cannot be less than 0.01 (code 16)\', code: -26') + await expect(promise).rejects.toThrow('LoanSchemeTx: interest rate cannot be less than 0.01\', code: -26') }) it('should not updateLoanScheme if same ratio and rate were created before', async () => { @@ -282,7 +282,7 @@ describe('loan.updateLoanScheme()', () => { const promise = sendTransaction(testing.container, txn) // Failed because its ratio and rate are same as default await expect(promise).rejects.toThrow(DeFiDRpcError) - await expect(promise).rejects.toThrow('LoanSchemeTx: Loan scheme default with same interestrate and mincolratio already exists (code 16)\', code: -26') + await expect(promise).rejects.toThrow('LoanSchemeTx: Loan scheme default with same interestrate and mincolratio already exists\', code: -26') }) it('should not updateLoanScheme if identifier does not exist', async () => { @@ -296,7 +296,7 @@ describe('loan.updateLoanScheme()', () => { const promise = sendTransaction(testing.container, txn) await expect(promise).rejects.toThrow(DeFiDRpcError) - await expect(promise).rejects.toThrow('LoanSchemeTx: Cannot find existing loan scheme with id scheme2 (code 16)\', code: -26') + await expect(promise).rejects.toThrow('LoanSchemeTx: Cannot find existing loan scheme with id scheme2\', code: -26') }) it('should not updateLoanScheme if identifier is an empty string', async () => { @@ -310,7 +310,7 @@ describe('loan.updateLoanScheme()', () => { const promise = sendTransaction(testing.container, txn) await expect(promise).rejects.toThrow(DeFiDRpcError) - await expect(promise).rejects.toThrow('LoanSchemeTx: id cannot be empty or more than 8 chars long (code 16)\', code: -26') + await expect(promise).rejects.toThrow('LoanSchemeTx: id cannot be empty or more than 8 chars long\', code: -26') }) it('should not updateLoanScheme if identifier is more than 8 chars long', async () => { @@ -324,7 +324,7 @@ describe('loan.updateLoanScheme()', () => { const promise = sendTransaction(testing.container, txn) await expect(promise).rejects.toThrow(DeFiDRpcError) - await expect(promise).rejects.toThrow('LoanSchemeTx: id cannot be empty or more than 8 chars long (code 16)\', code: -26') + await expect(promise).rejects.toThrow('LoanSchemeTx: id cannot be empty or more than 8 chars long\', code: -26') }) }) @@ -447,7 +447,7 @@ describe('loan.updateLoanScheme() with update less than current height', () => { const promise = sendTransaction(testing.container, txn) await expect(promise).rejects.toThrow(DeFiDRpcError) - await expect(promise).rejects.toThrow('LoanSchemeTx: Update height below current block height, set future height (code 16)\', code: -26') + await expect(promise).rejects.toThrow('LoanSchemeTx: Update height below current block height, set future height\', code: -26') }) }) @@ -496,6 +496,6 @@ describe('loan.updateLoanScheme() if a pending loan scheme exists with same rate // Attempt to update same ratio and rate as the pending scheme const promise = sendTransaction(testing.container, txn) await expect(promise).rejects.toThrow(DeFiDRpcError) - await expect(promise).rejects.toThrow('LoanSchemeTx: Loan scheme scheme1 with same interestrate and mincolratio already exists (code 16)\', code: -26') + await expect(promise).rejects.toThrow('LoanSchemeTx: Loan scheme scheme1 with same interestrate and mincolratio already exists\', code: -26') }) }) diff --git a/packages/jellyfish-transaction-builder/__tests__/txn/txn_builder_loan_set_loan_token.test.ts b/packages/jellyfish-transaction-builder/__tests__/txn/txn_builder_loan_set_loan_token.test.ts index 70fc9ab7ee..f521ba950a 100644 --- a/packages/jellyfish-transaction-builder/__tests__/txn/txn_builder_loan_set_loan_token.test.ts +++ b/packages/jellyfish-transaction-builder/__tests__/txn/txn_builder_loan_set_loan_token.test.ts @@ -146,7 +146,7 @@ describe('loan.setLoanToken()', () => { }, script) const promise = sendTransaction(testing.container, txn) - await expect(promise).rejects.toThrow('SetLoanTokenTx: Invalid token symbol. Valid: Start with an alphabet, non-empty, not contain # or / (code 16)\', code: -26') + await expect(promise).rejects.toThrow('SetLoanTokenTx: Invalid token symbol. Valid: Start with an alphabet, non-empty, not contain # or /\', code: -26') }) it('should not setLoanToken if the symbol is used in other token', async () => { @@ -180,7 +180,7 @@ describe('loan.setLoanToken()', () => { }, script) const promise = sendTransaction(testing.container, txn) - await expect(promise).rejects.toThrow('DeFiDRpcError: \'SetLoanTokenTx: token \'Token3\' already exists! (code 16)\', code: -26') + await expect(promise).rejects.toThrow('DeFiDRpcError: \'SetLoanTokenTx: token \'Token3\' already exists!\', code: -26') }) it('should not setLoanToken if currencyPair does not belong to any oracle', async () => { @@ -194,7 +194,7 @@ describe('loan.setLoanToken()', () => { }, script) const promise = sendTransaction(testing.container, txn) - await expect(promise).rejects.toThrow('DeFiDRpcError: \'SetLoanTokenTx: Price feed MFST/USD does not belong to any oracle (code 16)\', code: -26') + await expect(promise).rejects.toThrow('DeFiDRpcError: \'SetLoanTokenTx: Price feed MFST/USD does not belong to any oracle\', code: -26') }) it('should setLoanToken with the given name', async () => { diff --git a/packages/jellyfish-transaction-builder/__tests__/txn/txn_builder_loan_take_loan.test.ts b/packages/jellyfish-transaction-builder/__tests__/txn/txn_builder_loan_take_loan.test.ts index 486c5eff65..a9639861ee 100644 --- a/packages/jellyfish-transaction-builder/__tests__/txn/txn_builder_loan_take_loan.test.ts +++ b/packages/jellyfish-transaction-builder/__tests__/txn/txn_builder_loan_take_loan.test.ts @@ -620,7 +620,7 @@ describe('loans.takeLoan failed', () => { const promise = sendTransaction(bob.container, txn) await expect(promise).rejects.toThrow(DeFiDRpcError) - await expect(promise).rejects.toThrow('DeFiDRpcError: \'TakeLoanTx: At least 50% of the minimum required collateral must be in DFI or DUSD (code 16)\', code: -26') + await expect(promise).rejects.toThrow('DeFiDRpcError: \'TakeLoanTx: At least 50% of the minimum required collateral must be in DFI or DUSD\', code: -26') { // revert DFI value changes @@ -1151,7 +1151,7 @@ describe('takeLoan with 50% DUSD or DFI collaterals', () => { // Ensure the created txn is correct const outs = sendTransaction(bob.container, txn) await expect(outs).rejects.toThrow(DeFiDRpcError) - await expect(outs).rejects.toThrow('DeFiDRpcError: \'TakeLoanTx: At least 50% of the minimum required collateral must be in DFI or DUSD (code 16)\', code: -26') + await expect(outs).rejects.toThrow('DeFiDRpcError: \'TakeLoanTx: At least 50% of the minimum required collateral must be in DFI or DUSD\', code: -26') }) it('should not takeLoan with DUSD sole collateral before reaching fort canning road height', async () => { @@ -1190,7 +1190,7 @@ describe('takeLoan with 50% DUSD or DFI collaterals', () => { // Ensure the created txn is correct const outs = sendTransaction(bob.container, txn) await expect(outs).rejects.toThrow(DeFiDRpcError) - await expect(outs).rejects.toThrow('DeFiDRpcError: \'TakeLoanTx: At least 50% of the minimum required collateral must be in DFI or DUSD (code 16)\', code: -26') + await expect(outs).rejects.toThrow('DeFiDRpcError: \'TakeLoanTx: At least 50% of the minimum required collateral must be in DFI or DUSD\', code: -26') }) it('should not takeLoan with 25% DFI + 25% DUSD collateral before reaching fort canning road height', async () => { @@ -1226,7 +1226,7 @@ describe('takeLoan with 50% DUSD or DFI collaterals', () => { // Ensure the created txn is correct const outs = sendTransaction(bob.container, txn) await expect(outs).rejects.toThrow(DeFiDRpcError) - await expect(outs).rejects.toThrow('DeFiDRpcError: \'TakeLoanTx: At least 50% of the minimum required collateral must be in DFI or DUSD (code 16)\', code: -26') + await expect(outs).rejects.toThrow('DeFiDRpcError: \'TakeLoanTx: At least 50% of the minimum required collateral must be in DFI or DUSD\', code: -26') }) it('should not takeLoan with 33.33% DUSD collateral', async () => { @@ -1266,7 +1266,7 @@ describe('takeLoan with 50% DUSD or DFI collaterals', () => { // Ensure the created txn is correct const outs = sendTransaction(bob.container, txn) await expect(outs).rejects.toThrow(DeFiDRpcError) - await expect(outs).rejects.toThrow('DeFiDRpcError: \'TakeLoanTx: At least 50% of the minimum required collateral must be in DFI or DUSD (code 16)\', code: -26') + await expect(outs).rejects.toThrow('DeFiDRpcError: \'TakeLoanTx: At least 50% of the minimum required collateral must be in DFI or DUSD\', code: -26') }) it('should not takeLoan with 24.9975% DFI + 24.9975% DUSD of minimum required collateral', async () => { @@ -1301,6 +1301,6 @@ describe('takeLoan with 50% DUSD or DFI collaterals', () => { // Ensure the created txn is correct const outs = sendTransaction(bob.container, txn) await expect(outs).rejects.toThrow(DeFiDRpcError) - await expect(outs).rejects.toThrow('DeFiDRpcError: \'TakeLoanTx: At least 50% of the minimum required collateral must be in DFI or DUSD (code 16)\', code: -26') + await expect(outs).rejects.toThrow('DeFiDRpcError: \'TakeLoanTx: At least 50% of the minimum required collateral must be in DFI or DUSD\', code: -26') }) }) diff --git a/packages/jellyfish-transaction-builder/__tests__/txn/txn_builder_loan_update_loan_token.test.ts b/packages/jellyfish-transaction-builder/__tests__/txn/txn_builder_loan_update_loan_token.test.ts index 92022217ad..9d20c28e5a 100644 --- a/packages/jellyfish-transaction-builder/__tests__/txn/txn_builder_loan_update_loan_token.test.ts +++ b/packages/jellyfish-transaction-builder/__tests__/txn/txn_builder_loan_update_loan_token.test.ts @@ -188,7 +188,7 @@ describe('loan.updateLoanToken()', () => { tokenTx: loanTokenId }, script) const promise = sendTransaction(testing.container, txn) - await expect(promise).rejects.toThrow('DeFiDRpcError: \'UpdateLoanTokenTx: Invalid token symbol. Valid: Start with an alphabet, non-empty, not contain # or / (code 16)\', code: -26') + await expect(promise).rejects.toThrow('DeFiDRpcError: \'UpdateLoanTokenTx: Invalid token symbol. Valid: Start with an alphabet, non-empty, not contain # or /\', code: -26') }) it('should not updateLoanToken if the symbol is used in other token', async () => { @@ -224,7 +224,7 @@ describe('loan.updateLoanToken()', () => { tokenTx: loanTokenId }, script) const promise = sendTransaction(testing.container, txn) - await expect(promise).rejects.toThrow('DeFiDRpcError: \'UpdateLoanTokenTx: token with key \'Token1\' already exists! (code 16)\', code: -26') + await expect(promise).rejects.toThrow('DeFiDRpcError: \'UpdateLoanTokenTx: token with key \'Token1\' already exists!\', code: -26') }) it('should updateLoanToken if name is more than 128 letters', async () => { @@ -294,7 +294,7 @@ describe('loan.updateLoanToken()', () => { tokenTx: loanTokenId }, script) const promise = sendTransaction(testing.container, txn) - await expect(promise).rejects.toThrow('DeFiDRpcError: \'UpdateLoanTokenTx: Price feed MFST/USD does not belong to any oracle (code 16)\', code: -26') + await expect(promise).rejects.toThrow('DeFiDRpcError: \'UpdateLoanTokenTx: Price feed MFST/USD does not belong to any oracle\', code: -26') }) it('should not updateLoanToken if tokenTx does not exist', async () => { @@ -308,6 +308,6 @@ describe('loan.updateLoanToken()', () => { tokenTx: 'd6e157b66957dda2297947e31ac2a1d0c92eae515f35bc1ebad9478d06efa3c0' }, script) const promise = sendTransaction(testing.container, txn) - await expect(promise).rejects.toThrow('DeFiDRpcError: \'UpdateLoanTokenTx: Loan token (d6e157b66957dda2297947e31ac2a1d0c92eae515f35bc1ebad9478d06efa3c0) does not exist! (code 16)\', code: -26') + await expect(promise).rejects.toThrow('DeFiDRpcError: \'UpdateLoanTokenTx: Loan token (d6e157b66957dda2297947e31ac2a1d0c92eae515f35bc1ebad9478d06efa3c0) does not exist!\', code: -26') }) }) diff --git a/packages/jellyfish-transaction-builder/__tests__/txn/txn_builder_loan_update_vault.test.ts b/packages/jellyfish-transaction-builder/__tests__/txn/txn_builder_loan_update_vault.test.ts index 5893c91e20..391c3693ea 100644 --- a/packages/jellyfish-transaction-builder/__tests__/txn/txn_builder_loan_update_vault.test.ts +++ b/packages/jellyfish-transaction-builder/__tests__/txn/txn_builder_loan_update_vault.test.ts @@ -225,7 +225,7 @@ describe('loans updateVault', () => { const promise = sendTransaction(alice.container, txn) await expect(promise).rejects.toThrow(DeFiDRpcError) - await expect(promise).rejects.toThrow('DeFiDRpcError: \'UpdateVaultTx: Cannot update vault while any of the asset\'s price is invalid (code 16)\', code: -26') + await expect(promise).rejects.toThrow('DeFiDRpcError: \'UpdateVaultTx: Cannot update vault while any of the asset\'s price is invalid\', code: -26') await alice.container.waitForPriceValid('DFI/USD') @@ -273,7 +273,7 @@ describe('loans updateVault', () => { const promise = sendTransaction(alice.container, txn) await expect(promise).rejects.toThrow(DeFiDRpcError) - await expect(promise).rejects.toThrow('DeFiDRpcError: \'UpdateVaultTx: Vault does not have enough collateralization ratio defined by loan scheme - 147 < 150 (code 16)\', code: -26') + await expect(promise).rejects.toThrow('DeFiDRpcError: \'UpdateVaultTx: Vault does not have enough collateralization ratio defined by loan scheme - 147 < 150\', code: -26') }) it('should not updateVault as different auth address', async () => { @@ -297,6 +297,6 @@ describe('loans updateVault', () => { const promise = sendTransaction(alice.container, txn) await expect(promise).rejects.toThrow(DeFiDRpcError) - await expect(promise).rejects.toThrow('DeFiDRpcError: \'UpdateVaultTx: tx must have at least one input from token owner (code 16)\', code: -26') + await expect(promise).rejects.toThrow('DeFiDRpcError: \'UpdateVaultTx: tx must have at least one input from token owner\', code: -26') }) }) diff --git a/packages/jellyfish-transaction-builder/__tests__/txn/txn_builder_loan_withdraw_from_vault.test.ts b/packages/jellyfish-transaction-builder/__tests__/txn/txn_builder_loan_withdraw_from_vault.test.ts index a0476eaf71..d45d02b476 100644 --- a/packages/jellyfish-transaction-builder/__tests__/txn/txn_builder_loan_withdraw_from_vault.test.ts +++ b/packages/jellyfish-transaction-builder/__tests__/txn/txn_builder_loan_withdraw_from_vault.test.ts @@ -332,7 +332,7 @@ describe('loans.withdrawFromVault', () => { const promise = sendTransaction(tGroup.get(0).container, txn) await expect(promise).rejects.toThrow(DeFiDRpcError) - await expect(promise).rejects.toThrow('DeFiDRpcError: \'WithdrawFromVaultTx: At least 50% of the minimum required collateral must be in DFI or DUSD (code 16)\', code: -26') + await expect(promise).rejects.toThrow('DeFiDRpcError: \'WithdrawFromVaultTx: At least 50% of the minimum required collateral must be in DFI or DUSD\', code: -26') }) it('should not withdraw from liquidated vault', async () => { diff --git a/packages/jellyfish-transaction-builder/__tests__/txn/txn_builder_masternode_create.test.ts b/packages/jellyfish-transaction-builder/__tests__/txn/txn_builder_masternode_create.test.ts index f8261b3713..5e762afc13 100644 --- a/packages/jellyfish-transaction-builder/__tests__/txn/txn_builder_masternode_create.test.ts +++ b/packages/jellyfish-transaction-builder/__tests__/txn/txn_builder_masternode_create.test.ts @@ -175,7 +175,7 @@ describe('CreateMasternode', () => { try { await sendTransaction(container, txn) } catch (err) { - expect(err.message).toStrictEqual('DeFiDRpcError: \'CreateMasternodeTx: malformed tx vouts (wrong creation fee or collateral amount) (code 16)\', code: -26') + expect(err.message).toStrictEqual('DeFiDRpcError: \'CreateMasternodeTx: malformed tx vouts (wrong creation fee or collateral amount)\', code: -26') } }) }) diff --git a/packages/jellyfish-transaction-builder/__tests__/txn/txn_builder_masternode_update.test.ts b/packages/jellyfish-transaction-builder/__tests__/txn/txn_builder_masternode_update.test.ts index da1fc16141..529d874484 100644 --- a/packages/jellyfish-transaction-builder/__tests__/txn/txn_builder_masternode_update.test.ts +++ b/packages/jellyfish-transaction-builder/__tests__/txn/txn_builder_masternode_update.test.ts @@ -558,7 +558,7 @@ describe('UpdateMasternode', () => { }) const promise = sendTransaction(container, txn) await expect(promise).rejects.toThrow(DeFiDRpcError) - await expect(promise).rejects.toThrow("DeFiDRpcError: 'bad-txns-customtx, UpdateMasternodeTx: Owner address must be P2PKH or P2WPKH type (code 16)', code: -26") + await expect(promise).rejects.toThrow("DeFiDRpcError: 'UpdateMasternodeTx: Owner address must be P2PKH or P2WPKH type', code: -26") } { const address = await container.getNewAddress('', 'p2sh-segwit') @@ -572,7 +572,7 @@ describe('UpdateMasternode', () => { const txn: TransactionSegWit = await builder.masternode.update(updateMasternode, script) const promise = sendTransaction(container, txn) await expect(promise).rejects.toThrow(DeFiDRpcError) - await expect(promise).rejects.toThrow("DeFiDRpcError: 'bad-txns-customtx, UpdateMasternodeTx: Operator address must be P2PKH or P2WPKH type (code 16)', code: -26") + await expect(promise).rejects.toThrow("DeFiDRpcError: 'UpdateMasternodeTx: Operator address must be P2PKH or P2WPKH type', code: -26") } // Updated: P2SH is allowed - https://github.com/DeFiCh/ain/pull/1664 // { @@ -587,7 +587,7 @@ describe('UpdateMasternode', () => { // const txn: TransactionSegWit = await builder.masternode.update(updateMasternode, script) // const promise = sendTransaction(container, txn) // await expect(promise).rejects.toThrow(DeFiDRpcError) - // await expect(promise).rejects.toThrow("DeFiDRpcError: 'bad-txns-customtx, UpdateMasternodeTx: Reward address must be P2PKH or P2WPKH type (code 16)', code: -26") + // await expect(promise).rejects.toThrow("DeFiDRpcError: 'UpdateMasternodeTx: Reward address must be P2PKH or P2WPKH type', code: -26") // } }) @@ -609,7 +609,7 @@ describe('UpdateMasternode', () => { const txn: TransactionSegWit = await builder.masternode.update(updateMasternode, script) const promise = sendTransaction(container, txn) await expect(promise).rejects.toThrow(DeFiDRpcError) - await expect(promise).rejects.toThrow('DeFiDRpcError: \'bad-txns-customtx, UpdateMasternodeTx: Operator address must be P2PKH or P2WPKH type (code 16)\', code: -26') + await expect(promise).rejects.toThrow('DeFiDRpcError: \'UpdateMasternodeTx: Operator address must be P2PKH or P2WPKH type\', code: -26') } // NOTE(canonbrother): panic as raw address is not verified on ain @@ -622,7 +622,7 @@ describe('UpdateMasternode', () => { // const txn: TransactionSegWit = await builder.masternode.update(updateMasternode, script) // const promise = sendTransaction(container, txn) // await expect(promise).rejects.toThrow(DeFiDRpcError) - // await expect(promise).rejects.toThrow('DeFiDRpcError: \'bad-txns-customtx, UpdateMasternodeTx: Reward address must be P2SH, P2PKH or P2WPKH type (code 16)\', code: -26') + // await expect(promise).rejects.toThrow('DeFiDRpcError: \'UpdateMasternodeTx: Reward address must be P2SH, P2PKH or P2WPKH type\', code: -26') // } }) @@ -652,7 +652,7 @@ describe('UpdateMasternode', () => { const promise = sendTransaction(container, txn) await expect(promise).rejects.toThrow(DeFiDRpcError) - await expect(promise).rejects.toThrow("DeFiDRpcError: 'bad-txns-customtx, UpdateMasternodeTx: Missing previous collateral from transaction inputs (code 16)', code: -26") + await expect(promise).rejects.toThrow("DeFiDRpcError: 'UpdateMasternodeTx: Missing previous collateral from transaction inputs', code: -26") }) it('should fail to update owner address with same address', async () => { @@ -686,7 +686,7 @@ describe('UpdateMasternode', () => { const promise = sendTransaction(container, txn) await expect(promise).rejects.toThrow(DeFiDRpcError) - await expect(promise).rejects.toThrow("DeFiDRpcError: 'bad-txns-customtx, UpdateMasternodeTx: Masternode with collateral address as operator or owner already exists (code 16)', code: -26") + await expect(promise).rejects.toThrow("DeFiDRpcError: 'UpdateMasternodeTx: Masternode with collateral address as operator or owner already exists', code: -26") }) it('should fail to update another node with operator address that is already used', async () => { @@ -720,7 +720,7 @@ describe('UpdateMasternode', () => { const txn: TransactionSegWit = await builder.masternode.update(updateMasternode, script) const promise = sendTransaction(container, txn) await expect(promise).rejects.toThrow(DeFiDRpcError) - await expect(promise).rejects.toThrow("DeFiDRpcError: 'bad-txns-customtx, UpdateMasternodeTx: Masternode with that operator address already exists (code 16)', code: -26") + await expect(promise).rejects.toThrow("DeFiDRpcError: 'UpdateMasternodeTx: Masternode with that operator address already exists', code: -26") }) it('should not update masternode while in PRE_ENABLED or TRANSFERRING state', async () => { @@ -756,7 +756,7 @@ describe('UpdateMasternode', () => { const txn: TransactionSegWit = await builder.masternode.update(updateMasternode, script) const promise = sendTransaction(container, txn) await expect(promise).rejects.toThrow(DeFiDRpcError) - await expect(promise).rejects.toThrow(`DeFiDRpcError: 'bad-txns-customtx, UpdateMasternodeTx: Masternode ${masternodeId} is not in 'ENABLED' state (code 16)', code: -26`) + await expect(promise).rejects.toThrow(`DeFiDRpcError: 'UpdateMasternodeTx: Masternode ${masternodeId} is not in 'ENABLED' state', code: -26`) } await container.generate(20) @@ -997,6 +997,6 @@ describe('Update Masternode (Multi-containers)', () => { const promise = sendTransaction(node[1].container, txn) await expect(promise).rejects.toThrow(DeFiDRpcError) - await expect(promise).rejects.toThrow('DeFiDRpcError: \'bad-txns-customtx, UpdateMasternodeTx: tx must have at least one input from the owner (code 16)\', code: -26') + await expect(promise).rejects.toThrow('DeFiDRpcError: \'UpdateMasternodeTx: tx must have at least one input from the owner\', code: -26') }) }) diff --git a/packages/jellyfish-transaction-builder/__tests__/txn/txn_builder_token_burn_token.test.ts b/packages/jellyfish-transaction-builder/__tests__/txn/txn_builder_token_burn_token.test.ts index 3c6e3ac572..7ba09d9047 100644 --- a/packages/jellyfish-transaction-builder/__tests__/txn/txn_builder_token_burn_token.test.ts +++ b/packages/jellyfish-transaction-builder/__tests__/txn/txn_builder_token_burn_token.test.ts @@ -22,28 +22,28 @@ let wavesConsortiumAddress: string let idBTC: string async function setupGovs (): Promise { - await testing.rpc.masternode.setGov({ - [attributeKey]: - { - // Enable consortium - 'v0/params/feature/consortium': 'true', - - // Set a consortium global limit for dBTC - [`v0/consortium/${idBTC}/mint_limit`]: '50', - [`v0/consortium/${idBTC}/mint_limit_daily`]: '5', - - // Set a consortium member for dBTC - [`v0/consortium/${idBTC}/members`]: { - '01': { - name: 'Waves HQ', - ownerAddress: wavesConsortiumAddress, - backingId: 'backing_address_btc_1_c', - mintLimitDaily: '5.00000000', - mintLimit: '50.00000000' - } - } - } - }) + // await testing.rpc.masternode.setGov({ + // [attributeKey]: + // { + // // Enable consortium + // 'v0/params/feature/consortium': 'true', + + // // Set a consortium global limit for dBTC + // [`v0/consortium/${idBTC}/mint_limit`]: '50', + // [`v0/consortium/${idBTC}/mint_limit_daily`]: '5', + + // // Set a consortium member for dBTC + // [`v0/consortium/${idBTC}/members`]: { + // '01': { + // name: 'Waves HQ', + // ownerAddress: wavesConsortiumAddress, + // backingId: 'backing_address_btc_1_c', + // mintLimitDaily: '5.00000000', + // mintLimit: '50.00000000' + // } + // } + // } + // }) } describe('burnToken', () => { @@ -111,7 +111,7 @@ describe('burnToken', () => { const promise = sendTransaction(testing.container, txn) await expect(promise).rejects.toThrow(DeFiDRpcError) - await expect(promise).rejects.toThrow("DeFiDRpcError: 'BurnTokenTx: amount 0.00000000 is less than 15.00000000 (code 16)', code: -26") + await expect(promise).rejects.toThrow("DeFiDRpcError: 'BurnTokenTx: amount 0.00000000 is less than 15.00000000', code: -26") }) it('should burnToken without context', async () => { @@ -236,7 +236,7 @@ describe('burnToken', () => { // Verify that the burn action is tied to the existing consortium member expect(keys.some(key => burntKeyRegex.exec(key) === null)).toStrictEqual(true) - expect(attributes.ATTRIBUTES[`v0/live/economy/consortium_members/${idBTC}/01/burnt`]).toStrictEqual(new BigNumber(30)) + // expect(attributes.ATTRIBUTES[`v0/live/economy/consortium_members/${idBTC}/01/burnt`]).toStrictEqual(new BigNumber(30)) // Verify the token balance is deducted correctly (100 - 30 = 70 BTC) const accAfter = await testing.rpc.account.getAccount(await providers.getAddress()) diff --git a/packages/jellyfish-transaction-builder/__tests__/txn/txn_builder_token_mint_token.test.ts b/packages/jellyfish-transaction-builder/__tests__/txn/txn_builder_token_mint_token.test.ts index 2c19c83ac2..21243dab04 100644 --- a/packages/jellyfish-transaction-builder/__tests__/txn/txn_builder_token_mint_token.test.ts +++ b/packages/jellyfish-transaction-builder/__tests__/txn/txn_builder_token_mint_token.test.ts @@ -12,7 +12,7 @@ import { Bech32, WIF } from '@defichain/jellyfish-crypto' const attributeKey = 'ATTRIBUTES' const symbolDBTC = 'BTC' -describe('Consortium', () => { +describe.skip('Consortium', () => { const tGroup = TestingGroup.create(3) const alice = tGroup.get(0) const bob = tGroup.get(1) @@ -154,7 +154,7 @@ describe('Consortium', () => { const txn = await cBuilder.tokens.mint(tokenMint, script) const promise = sendTransaction(charlie.container, txn) - await expect(promise).rejects.toThrow("DeFiDRpcError: 'MintTokenTx: You are not a foundation or consortium member and cannot mint this token! (code 16)', code: -26") + await expect(promise).rejects.toThrow("DeFiDRpcError: 'MintTokenTx: You are not a foundation or consortium member and cannot mint this token!', code: -26") }) it('should throw an error if the token is not specified in governance vars', async () => { @@ -172,7 +172,7 @@ describe('Consortium', () => { const txn = await aBuilder.tokens.mint(tokenMint, script) const promise = sendTransaction(alice.container, txn) - await expect(promise).rejects.toThrow("DeFiDRpcError: 'MintTokenTx: You are not a foundation member or token owner and cannot mint this token! (code 16)', code: -26") + await expect(promise).rejects.toThrow("DeFiDRpcError: 'MintTokenTx: You are not a foundation member or token owner and cannot mint this token!', code: -26") }) it('should not mintTokens for non-existent token', async () => { @@ -190,7 +190,7 @@ describe('Consortium', () => { const txn = await aBuilder.tokens.mint(tokenMint, script) const promise = sendTransaction(alice.container, txn) - await expect(promise).rejects.toThrow("DeFiDRpcError: 'MintTokenTx: token 22 does not exist! (code 16)', code: -26") + await expect(promise).rejects.toThrow("DeFiDRpcError: 'MintTokenTx: token 22 does not exist!', code: -26") }) it('should throw an error if member daily mint limit exceeds', async () => { @@ -208,7 +208,7 @@ describe('Consortium', () => { const txn = await aBuilder.tokens.mint(tokenMint, script) const promise = sendTransaction(alice.container, txn) - await expect(promise).rejects.toThrow("DeFiDRpcError: 'MintTokenTx: You will exceed your daily mint limit for BTC token by minting this amount (code 16)', code: -26") + await expect(promise).rejects.toThrow("DeFiDRpcError: 'MintTokenTx: You will exceed your daily mint limit for BTC token by minting this amount', code: -26") }) it('should throw an error if member maximum mint limit exceeds', async () => { @@ -226,7 +226,7 @@ describe('Consortium', () => { const txn = await aBuilder.tokens.mint(tokenMint, script) const promise = sendTransaction(alice.container, txn) - await expect(promise).rejects.toThrow("DeFiDRpcError: 'MintTokenTx: You will exceed your maximum mint limit for BTC token by minting this amount! (code 16)', code: -26") + await expect(promise).rejects.toThrow("DeFiDRpcError: 'MintTokenTx: You will exceed your maximum mint limit for BTC token by minting this amount!', code: -26") }) it('should throw an error if global daily mint limit exceeds', async () => { @@ -249,7 +249,7 @@ describe('Consortium', () => { const txn = await bBuilder.tokens.mint(tokenMint, script) const promise = sendTransaction(bob.container, txn) - await expect(promise).rejects.toThrow("DeFiDRpcError: 'MintTokenTx: You will exceed global daily maximum consortium mint limit for BTC token by minting this amount. (code 16)', code: -26") + await expect(promise).rejects.toThrow("DeFiDRpcError: 'MintTokenTx: You will exceed global daily maximum consortium mint limit for BTC token by minting this amount.', code: -26") }) it('should throw an error if global mint limit exceeds', async () => { @@ -272,7 +272,7 @@ describe('Consortium', () => { const txn = await bBuilder.tokens.mint(tokenMint, script) const promise = sendTransaction(bob.container, txn) - await expect(promise).rejects.toThrow("MintTokenTx: You will exceed global daily maximum consortium mint limit for BTC token by minting this amount. (code 16)', code: -26") + await expect(promise).rejects.toThrow("MintTokenTx: You will exceed global daily maximum consortium mint limit for BTC token by minting this amount.', code: -26") }) it('should mintTokens', async () => { diff --git a/packages/jellyfish-transaction-builder/__tests__/txn/txn_builder_vault_close_vault.test.ts b/packages/jellyfish-transaction-builder/__tests__/txn/txn_builder_vault_close_vault.test.ts index f51ab21310..669a7a9b46 100644 --- a/packages/jellyfish-transaction-builder/__tests__/txn/txn_builder_vault_close_vault.test.ts +++ b/packages/jellyfish-transaction-builder/__tests__/txn/txn_builder_vault_close_vault.test.ts @@ -303,7 +303,7 @@ describe('vault.closeVault', () => { }, script) const promise = sendTransaction(tGroup.get(0).container, txn) - await expect(promise).rejects.toThrow(`DeFiDRpcError: 'CloseVaultTx: Vault <${'0'.repeat(64)}> not found (code 16)', code: -26`) + await expect(promise).rejects.toThrow(`DeFiDRpcError: 'CloseVaultTx: Vault <${'0'.repeat(64)}> not found', code: -26`) }) it('should not closeVault for vault with loan taken', async () => { @@ -314,7 +314,7 @@ describe('vault.closeVault', () => { }, script) const promise = sendTransaction(tGroup.get(0).container, txn) - await expect(promise).rejects.toThrow(`DeFiDRpcError: 'CloseVaultTx: Vault <${vaultWithLoanTakenId}> has loans (code 16)', code: -26`) + await expect(promise).rejects.toThrow(`DeFiDRpcError: 'CloseVaultTx: Vault <${vaultWithLoanTakenId}> has loans', code: -26`) }) it('should not closeVault for mayliquidate vault', async () => { @@ -333,7 +333,7 @@ describe('vault.closeVault', () => { }, script) const promise = sendTransaction(tGroup.get(0).container, txn) - await expect(promise).rejects.toThrow(`DeFiDRpcError: 'CloseVaultTx: Vault <${vaultWithLiquidationId}> has loans (code 16)', code: -26`) + await expect(promise).rejects.toThrow(`DeFiDRpcError: 'CloseVaultTx: Vault <${vaultWithLiquidationId}> has loans', code: -26`) await tGroup.get(0).rpc.oracle.setOracleData(oracleId, Math.floor(new Date().getTime() / 1000), { prices: [{ tokenAmount: '2@TSLA', currency: 'USD' }] }) await tGroup.get(0).generate(1) @@ -357,7 +357,7 @@ describe('vault.closeVault', () => { }, script) const promise = sendTransaction(tGroup.get(0).container, txn) - await expect(promise).rejects.toThrow(`DeFiDRpcError: 'CloseVaultTx: Vault <${vaultWithLiquidationId}> has loans (code 16)', code: -26`) + await expect(promise).rejects.toThrow(`DeFiDRpcError: 'CloseVaultTx: Vault <${vaultWithLiquidationId}> has loans', code: -26`) await tGroup.get(0).container.waitForPriceValid('TSLA/USD') @@ -385,7 +385,7 @@ describe('vault.closeVault', () => { }, script) const promise = sendTransaction(tGroup.get(0).container, txn) - await expect(promise).rejects.toThrow('DeFiDRpcError: \'CloseVaultTx: Cannot close vault under liquidation (code 16)\', code: -26') + await expect(promise).rejects.toThrow('DeFiDRpcError: \'CloseVaultTx: Cannot close vault under liquidation\', code: -26') await tGroup.get(0).rpc.oracle.setOracleData(oracleId, Math.floor(new Date().getTime() / 1000), { prices: [{ tokenAmount: '2@TSLA', currency: 'USD' }] }) await tGroup.get(0).generate(1) @@ -405,6 +405,6 @@ describe('vault.closeVault', () => { const promise = sendTransaction(tGroup.get(0).container, txn) await expect(promise).rejects.toThrow(DeFiDRpcError) - await expect(promise).rejects.toThrow('DeFiDRpcError: \'CloseVaultTx: tx must have at least one input from token owner (code 16)\', code: -26') + await expect(promise).rejects.toThrow('DeFiDRpcError: \'CloseVaultTx: tx must have at least one input from token owner\', code: -26') }) }) diff --git a/packages/jellyfish-transaction-builder/__tests__/txn/txn_builder_vault_create_vault.test.ts b/packages/jellyfish-transaction-builder/__tests__/txn/txn_builder_vault_create_vault.test.ts index 739aadf3c3..d7d4dfcd44 100644 --- a/packages/jellyfish-transaction-builder/__tests__/txn/txn_builder_vault_create_vault.test.ts +++ b/packages/jellyfish-transaction-builder/__tests__/txn/txn_builder_vault_create_vault.test.ts @@ -251,7 +251,7 @@ describe('vault.createVault', () => { const promise = sendTransaction(testing.container, txn) await expect(promise).rejects.toThrow(DeFiDRpcError) - await expect(promise).rejects.toThrow('VaultTx: Cannot find existing loan scheme with id scheme3 (code 16)\', code: -26') + await expect(promise).rejects.toThrow('VaultTx: Cannot find existing loan scheme with id scheme3\', code: -26') }) it('should not createVault with scheme set to be destroyed', async () => { @@ -275,7 +275,7 @@ describe('vault.createVault', () => { const promise = sendTransaction(testing.container, txn) await expect(promise).rejects.toThrow(DeFiDRpcError) - await expect(promise).rejects.toThrow('VaultTx: Cannot set scheme4 as loan scheme, set to be destroyed on block 150 (code 16)\', code: -26') + await expect(promise).rejects.toThrow('VaultTx: Cannot set scheme4 as loan scheme, set to be destroyed on block 150\', code: -26') }) }) @@ -314,6 +314,6 @@ describe('vault.createVault when no default scheme and the given schemeId is emp const promise = sendTransaction(testing.container, txn) await expect(promise).rejects.toThrow(DeFiDRpcError) - await expect(promise).rejects.toThrow('DeFiDRpcError: \'VaultTx: There is no default loan scheme (code 16)\', code: -26') + await expect(promise).rejects.toThrow('DeFiDRpcError: \'VaultTx: There is no default loan scheme\', code: -26') }) }) diff --git a/packages/jellyfish-transaction-builder/__tests__/txn/txn_builder_vault_deposit_to_vault.test.ts b/packages/jellyfish-transaction-builder/__tests__/txn/txn_builder_vault_deposit_to_vault.test.ts index bb3f7675cd..d0e7bbadbb 100644 --- a/packages/jellyfish-transaction-builder/__tests__/txn/txn_builder_vault_deposit_to_vault.test.ts +++ b/packages/jellyfish-transaction-builder/__tests__/txn/txn_builder_vault_deposit_to_vault.test.ts @@ -316,7 +316,7 @@ describe('vault.depositToVault', () => { const promise = sendTransaction(tGroup.get(0).container, txn) await expect(promise).rejects.toThrow(DeFiDRpcError) - await expect(promise).rejects.toThrow('DepositToVaultTx: tx must have at least one input from token owner (code 16)\', code: -26') + await expect(promise).rejects.toThrow('DepositToVaultTx: tx must have at least one input from token owner\', code: -26') }) it('should be failed as vault is not exists', async () => { diff --git a/packages/jellyfish-transaction-builder/__tests__/txn/txn_builder_vault_update_vault.test.ts b/packages/jellyfish-transaction-builder/__tests__/txn/txn_builder_vault_update_vault.test.ts index b5842c9436..eb6a2bee60 100644 --- a/packages/jellyfish-transaction-builder/__tests__/txn/txn_builder_vault_update_vault.test.ts +++ b/packages/jellyfish-transaction-builder/__tests__/txn/txn_builder_vault_update_vault.test.ts @@ -225,7 +225,7 @@ describe('vault.updateVault', () => { const promise = sendTransaction(alice.container, txn) await expect(promise).rejects.toThrow(DeFiDRpcError) - await expect(promise).rejects.toThrow('DeFiDRpcError: \'UpdateVaultTx: Cannot update vault while any of the asset\'s price is invalid (code 16)\', code: -26') + await expect(promise).rejects.toThrow('DeFiDRpcError: \'UpdateVaultTx: Cannot update vault while any of the asset\'s price is invalid\', code: -26') await alice.container.waitForPriceValid('DFI/USD') @@ -273,7 +273,7 @@ describe('vault.updateVault', () => { const promise = sendTransaction(alice.container, txn) await expect(promise).rejects.toThrow(DeFiDRpcError) - await expect(promise).rejects.toThrow('DeFiDRpcError: \'UpdateVaultTx: Vault does not have enough collateralization ratio defined by loan scheme - 147 < 150 (code 16)\', code: -26') + await expect(promise).rejects.toThrow('DeFiDRpcError: \'UpdateVaultTx: Vault does not have enough collateralization ratio defined by loan scheme - 147 < 150\', code: -26') }) it('should not updateVault as different auth address', async () => { @@ -297,6 +297,6 @@ describe('vault.updateVault', () => { const promise = sendTransaction(alice.container, txn) await expect(promise).rejects.toThrow(DeFiDRpcError) - await expect(promise).rejects.toThrow('DeFiDRpcError: \'UpdateVaultTx: tx must have at least one input from token owner (code 16)\', code: -26') + await expect(promise).rejects.toThrow('DeFiDRpcError: \'UpdateVaultTx: tx must have at least one input from token owner\', code: -26') }) }) diff --git a/packages/jellyfish-transaction-builder/__tests__/txn/txn_builder_vault_withdraw_from_vault.test.ts b/packages/jellyfish-transaction-builder/__tests__/txn/txn_builder_vault_withdraw_from_vault.test.ts index 388b51b0bb..ee6ca2ec60 100644 --- a/packages/jellyfish-transaction-builder/__tests__/txn/txn_builder_vault_withdraw_from_vault.test.ts +++ b/packages/jellyfish-transaction-builder/__tests__/txn/txn_builder_vault_withdraw_from_vault.test.ts @@ -332,7 +332,7 @@ describe('vault.withdrawFromVault', () => { const promise = sendTransaction(tGroup.get(0).container, txn) await expect(promise).rejects.toThrow(DeFiDRpcError) - await expect(promise).rejects.toThrow('DeFiDRpcError: \'WithdrawFromVaultTx: At least 50% of the minimum required collateral must be in DFI or DUSD (code 16)') + await expect(promise).rejects.toThrow('DeFiDRpcError: \'WithdrawFromVaultTx: At least 50% of the minimum required collateral must be in DFI or DUSD') }) it('should not withdraw from liquidated vault', async () => { diff --git a/packages/jellyfish-transaction-builder/src/provider.ts b/packages/jellyfish-transaction-builder/src/provider.ts index 71459d0a33..f728b12bd0 100644 --- a/packages/jellyfish-transaction-builder/src/provider.ts +++ b/packages/jellyfish-transaction-builder/src/provider.ts @@ -30,15 +30,9 @@ export interface PrevoutProvider { * * @param {BigNumber} minBalance of balance combined in a Prevout required for a single transaction. * required to create transaction. - * @param {ListUnspentOptions} [options] - * @param {number} [options.minimumAmount] default = 0, minimum value of each UTXO - * @param {number} [options.maximumAmount] default is 'unlimited', maximum value of each UTXO - * @param {number} [options.maximumCount] default is 'unlimited', maximum number of UTXOs - * @param {number} [options.minimumSumAmount] default is 'unlimited', minimum sum value of all UTXOs - * @param {string} [options.tokenId] default is 'all', filter by token * @return {Prevout[]} selected all required for creating the transaction */ - collect: (minBalance: BigNumber, options?: ListUnspentQueryOptions) => Promise + collect: (minBalance: BigNumber) => Promise } /** diff --git a/packages/jellyfish-transaction-builder/src/txn/txn_builder.ts b/packages/jellyfish-transaction-builder/src/txn/txn_builder.ts index 5a89915446..3847b770f9 100644 --- a/packages/jellyfish-transaction-builder/src/txn/txn_builder.ts +++ b/packages/jellyfish-transaction-builder/src/txn/txn_builder.ts @@ -10,7 +10,7 @@ import { } from '@defichain/jellyfish-transaction' import { SignInputOption, TransactionSigner } from '@defichain/jellyfish-transaction-signature' import BigNumber from 'bignumber.js' -import { EllipticPairProvider, FeeRateProvider, ListUnspentQueryOptions, Prevout, PrevoutProvider } from '../provider' +import { EllipticPairProvider, FeeRateProvider, Prevout, PrevoutProvider } from '../provider' import { calculateFeeP2WPKH } from './txn_fee' import { TxnBuilderError, TxnBuilderErrorType } from './txn_builder_error' import { EllipticPair } from '@defichain/jellyfish-crypto' @@ -45,16 +45,10 @@ export abstract class P2WPKHTxnBuilder { /** * @param {BigNumber} minBalance to collect, required to form a transaction - * @param {ListUnspentOptions} [options] - * @param {number} [options.minimumAmount] default = 0, minimum value of each UTXO - * @param {number} [options.maximumAmount] default is 'unlimited', maximum value of each UTXO - * @param {number} [options.maximumCount] default is 'unlimited', maximum number of UTXOs - * @param {number} [options.minimumSumAmount] default is 'unlimited', minimum sum value of all UTXOs - * @param {string} [options.tokenId] default is 'all', filter by token * @return {Promise} */ - protected async collectPrevouts (minBalance: BigNumber, options?: ListUnspentQueryOptions): Promise { - const prevouts = await this.prevoutProvider.collect(minBalance, options) + protected async collectPrevouts (minBalance: BigNumber): Promise { + const prevouts = await this.prevoutProvider.collect(minBalance) if (prevouts.length === 0) { throw new TxnBuilderError(TxnBuilderErrorType.NO_PREVOUTS, 'no prevouts available to create a transaction' @@ -104,21 +98,30 @@ export abstract class P2WPKHTxnBuilder { * @param {OP_DEFI_TX} opDeFiTx to create * @param {Script} changeScript to send unspent to after deducting the fees * @param {BigNumber} [outValue=0] for the opDeFiTx, usually always be 0. - * @param {ListUnspentOptions} [options] - * @param {number} [options.minimumAmount] default = 0, minimum value of each UTXO - * @param {number} [options.maximumAmount] default is 'unlimited', maximum value of each UTXO - * @param {number} [options.maximumCount] default is 'unlimited', maximum number of UTXOs - * @param {number} [options.minimumSumAmount] default is 'unlimited', minimum sum value of all UTXOs - * @param {string} [options.tokenId] default is 'all', filter by token + * @param {Prevout[]} [utxos=[]] provide it if you want to spent specific UTXOs */ async createDeFiTx ( opDeFiTx: OP_DEFI_TX, changeScript: Script, outValue: BigNumber = new BigNumber('0'), - options: ListUnspentQueryOptions = {} + utxos: Prevout[] = [] ): Promise { const minFee = outValue.plus(0.001) // see JSDoc above - const { prevouts, vin, total } = await this.collectPrevouts(minFee, options) + + let prevouts: Prevout[] = [] + let vin: Vin[] = [] + let total: BigNumber = new BigNumber('0') + + if (utxos.length > 0) { + ({ prevouts, vin, total } = joinPrevouts(utxos)) + if (minFee.gt(total)) { + throw new TxnBuilderError(TxnBuilderErrorType.MIN_BALANCE_NOT_ENOUGH, + 'not enough balance after combing all prevouts' + ) + } + } else { + ({ prevouts, vin, total } = await this.collectPrevouts(minFee)) + } const deFiOut: Vout = { value: outValue, diff --git a/packages/jellyfish-transaction-builder/src/txn/txn_builder_account.ts b/packages/jellyfish-transaction-builder/src/txn/txn_builder_account.ts index 99f93e7441..5e38c54ce5 100644 --- a/packages/jellyfish-transaction-builder/src/txn/txn_builder_account.ts +++ b/packages/jellyfish-transaction-builder/src/txn/txn_builder_account.ts @@ -5,7 +5,7 @@ import { } from '@defichain/jellyfish-transaction' import { P2WPKHTxnBuilder } from './txn_builder' import { TxnBuilderError, TxnBuilderErrorType } from './txn_builder_error' -import { ListUnspentQueryOptions } from '../provider' +import { Prevout } from '../provider' export class TxnBuilderAccount extends P2WPKHTxnBuilder { /** @@ -145,21 +145,16 @@ export class TxnBuilderAccount extends P2WPKHTxnBuilder { * * @param {TransferDomain} transferDomain txn to create * @param {Script} changeScript to send unspent to after deducting the (converted + fees) - * @param {ListUnspentOptions} [options] - * @param {number} [options.minimumAmount] default = 0, minimum value of each UTXO - * @param {number} [options.maximumAmount] default is 'unlimited', maximum value of each UTXO - * @param {number} [options.maximumCount] default is 'unlimited', maximum number of UTXOs - * @param {number} [options.minimumSumAmount] default is 'unlimited', minimum sum value of all UTXOs - * @param {string} [options.tokenId] default is 'all', filter by token + * @param {Prevout[]} utxos to be speficically provided if needed * @returns {Promise} */ - async transferDomain (transferDomain: TransferDomain, changeScript: Script, options: ListUnspentQueryOptions = {}): Promise { + async transferDomain (transferDomain: TransferDomain, changeScript: Script, utxos: Prevout[] = []): Promise { return await super.createDeFiTx( OP_CODES.OP_DEFI_TX_TRANSFER_DOMAIN(transferDomain), changeScript, new BigNumber(0), - options + utxos ) } } diff --git a/packages/ocean-api-client/src/OceanApiClient.ts b/packages/ocean-api-client/src/OceanApiClient.ts index ebe18b7b50..84788bcb08 100644 --- a/packages/ocean-api-client/src/OceanApiClient.ts +++ b/packages/ocean-api-client/src/OceanApiClient.ts @@ -2,6 +2,7 @@ import 'url-search-params-polyfill' import AbortController from 'abort-controller' import fetch from 'cross-fetch' import { ApiException, ApiMethod, ApiPagedResponse, ApiResponse, ClientException, TimeoutException } from './' +import { NetworkName } from '@defichain/jellyfish-network' /** * OceanApiClient configurable options @@ -24,7 +25,19 @@ export interface OceanApiClientOptions { /** * Network that ocean client is configured to */ - network?: 'mainnet' | 'testnet' | 'devnet' | 'regtest' | 'changi' | string + network?: NetworkName | 'playground' +} + +/** + * OceanApiClient default options + */ +function getDefaultOptions (network: NetworkName | 'playground'): OceanApiClientOptions { + return { + url: `https://${network}.ocean.jellyfishsdk.com`, + timeout: 60000, + version: 'v0', + network + } } /** @@ -35,10 +48,7 @@ export class OceanApiClient { protected readonly options: OceanApiClientOptions ) { this.options = { - url: 'https://ocean.defichain.com', - timeout: 60000, - version: 'v1', - network: 'mainnet', + ...getDefaultOptions(options?.network ?? 'mainnet'), ...options } this.options.url = this.options.url?.replace(/\/$/, '') diff --git a/packages/testcontainers/src/containers/DeFiDContainer.ts b/packages/testcontainers/src/containers/DeFiDContainer.ts index 64ad77997d..1f0c4db61a 100644 --- a/packages/testcontainers/src/containers/DeFiDContainer.ts +++ b/packages/testcontainers/src/containers/DeFiDContainer.ts @@ -36,7 +36,7 @@ export abstract class DeFiDContainer extends DockerContainer { if (process?.env?.DEFICHAIN_DOCKER_IMAGE !== undefined) { return process.env.DEFICHAIN_DOCKER_IMAGE } - return 'defi/defichain:4.0.0-beta13' // renovate.json regexManagers + return 'defi/defichain:4.0.9' // renovate.json regexManagers } public static readonly DefaultStartOptions = { diff --git a/packages/testcontainers/src/containers/NativeChainContainer.ts b/packages/testcontainers/src/containers/NativeChainContainer.ts index 9824b97d09..ef812e5468 100644 --- a/packages/testcontainers/src/containers/NativeChainContainer.ts +++ b/packages/testcontainers/src/containers/NativeChainContainer.ts @@ -29,7 +29,7 @@ export class NativeChainContainer extends GenericContainer { if (process?.env?.DEFICHAIN_DOCKER_IMAGE !== undefined) { return process.env.DEFICHAIN_DOCKER_IMAGE } - return 'defi/defichain:4.0.0-beta13' // renovate.json regexManagers + return 'defi/defichain:4.0.9' // renovate.json regexManagers } public static readonly PREFIX = 'defichain-testcontainers-' @@ -121,7 +121,7 @@ export class NativeChainContainer extends GenericContainer { '-fortcanningepilogueheight=15', '-grandcentralheight=16', '-grandcentralepilogueheight=17', - '-nextnetworkupgradeheight=18', + '-metachainheight=18', '-regtest-skip-loan-collateral-validation', '-regtest-minttoken-simulate-mainnet=0' ], diff --git a/packages/testcontainers/src/containers/RegTestContainer/index.ts b/packages/testcontainers/src/containers/RegTestContainer/index.ts index 5d423b93e8..2c6d9ea45a 100644 --- a/packages/testcontainers/src/containers/RegTestContainer/index.ts +++ b/packages/testcontainers/src/containers/RegTestContainer/index.ts @@ -42,7 +42,7 @@ export class RegTestContainer extends DeFiDContainer { '-fortcanningepilogueheight=15', '-grandcentralheight=16', '-grandcentralepilogueheight=17', - '-nextnetworkupgradeheight=18', + '-metachainheight=18', '-regtest-skip-loan-collateral-validation', '-regtest-minttoken-simulate-mainnet=0', '-rpc-governance-accept-neutral=1' diff --git a/packages/whale-api-client/__tests__/WhaleApiClient.test.ts b/packages/whale-api-client/__tests__/WhaleApiClient.test.ts index 31ad55b0cf..7b40a952dc 100644 --- a/packages/whale-api-client/__tests__/WhaleApiClient.test.ts +++ b/packages/whale-api-client/__tests__/WhaleApiClient.test.ts @@ -1,42 +1,58 @@ import nock from 'nock' import { WhaleApiClient } from '@defichain/whale-api-client/dist/whale.api.client' +import { NetworkName } from '@defichain/jellyfish-network' -const client = new WhaleApiClient({ - url: 'http://whale-api-test.internal', - network: 'regtest', - version: 'v0.0' +describe('WhaleApiClient default url', () => { + it.each([ + 'mainnet', + 'testnet' + ])('should query default url successfully: %s', async (network: NetworkName) => { + const client = new WhaleApiClient({ network }) + const response = await client.stats.get() + expect(response).toMatchObject({ + blockchain: expect.any(Object) + }) + }) }) -it('should requestData via GET', async () => { - nock('http://whale-api-test.internal') - .get('/v0.0/regtest/foo') - .reply(200, function () { - return { - data: { - bar: ['1', '2'] +describe('WhaleApiClient HTTP', () => { + const client = new WhaleApiClient({ + url: 'http://whale-api-test.internal', + network: 'regtest', + version: 'v0.0' + }) + + it('should requestData via GET', async () => { + nock('http://whale-api-test.internal') + .get('/v0.0/regtest/foo') + .reply(200, function () { + return { + data: { + bar: ['1', '2'] + } } - } - }) + }) - const result = await client.requestData('GET', 'foo') - await expect(result).toStrictEqual({ - bar: ['1', '2'] + const result = await client.requestData('GET', 'foo') + await expect(result).toStrictEqual({ + bar: ['1', '2'] + }) }) -}) -it('should requestData via POST', async () => { - nock('http://whale-api-test.internal') - .post('/v0.0/regtest/bar') - .reply(200, function (_, body: object) { - return { - data: body - } - }) + it('should requestData via POST', async () => { + nock('http://whale-api-test.internal') + .post('/v0.0/regtest/bar') + .reply(200, function (_, body: object) { + return { + data: body + } + }) - const result = await client.requestData('POST', 'bar', { - abc: ['a', 'b', 'c'] - }) - await expect(result).toStrictEqual({ - abc: ['a', 'b', 'c'] + const result = await client.requestData('POST', 'bar', { + abc: ['a', 'b', 'c'] + }) + await expect(result).toStrictEqual({ + abc: ['a', 'b', 'c'] + }) }) }) diff --git a/packages/whale-api-client/__tests__/api/consortium.test.ts b/packages/whale-api-client/__tests__/api/consortium.test.ts index 2175a335ed..0c81b95b84 100644 --- a/packages/whale-api-client/__tests__/api/consortium.test.ts +++ b/packages/whale-api-client/__tests__/api/consortium.test.ts @@ -1,3 +1,5 @@ +// NOTE(canonbrother): skip as consortium is removed, ref: https://github.com/DeFiCh/ain/pull/2730 + import { TestingGroup } from '@defichain/jellyfish-testing' import { StartFlags } from '@defichain/testcontainers' import { WhaleApiException } from '../../src' @@ -124,7 +126,7 @@ async function setup (): Promise { }]) } -describe('getAssetBreakdown', () => { +describe.skip('getAssetBreakdown', () => { it('should respond an empty list if theres no consortium members or tokens initialized', async () => { const info = await client.consortium.getAssetBreakdown() expect(info).toStrictEqual([]) @@ -190,7 +192,7 @@ describe('getAssetBreakdown', () => { }) }) -describe('getMemberStats', () => { +describe.skip('getMemberStats', () => { it('should throw an error if provided consortium member id is invalid', async () => { try { await setup() diff --git a/packages/whale-api-client/src/whale.api.client.ts b/packages/whale-api-client/src/whale.api.client.ts index 6a06f4fa13..41eb68a418 100644 --- a/packages/whale-api-client/src/whale.api.client.ts +++ b/packages/whale-api-client/src/whale.api.client.ts @@ -47,11 +47,13 @@ export interface WhaleApiClientOptions { /** * WhaleApiClient default options */ -const DEFAULT_OPTIONS: WhaleApiClientOptions = { - url: 'https://ocean.defichain.com', - timeout: 60000, - version: 'v0', - network: 'mainnet' +function getDefaultOptions (network: NetworkName): WhaleApiClientOptions { + return { + url: `https://${network}.ocean.jellyfishsdk.com`, + timeout: 60000, + version: 'v0', + network + } } /** @@ -88,7 +90,10 @@ export class WhaleApiClient { constructor ( protected readonly options: WhaleApiClientOptions ) { - this.options = { ...DEFAULT_OPTIONS, ...options } + this.options = { + ...getDefaultOptions(options?.network ?? 'mainnet'), + ...options + } this.options.url = this.options.url?.replace(/\/$/, '') }