diff --git a/.github/scripts/release-ecr-tags.js b/.github/scripts/release-ecr-tags.js index cf10de6fde..5af7fe6804 100644 --- a/.github/scripts/release-ecr-tags.js +++ b/.github/scripts/release-ecr-tags.js @@ -13,9 +13,10 @@ module.exports = ({ context }) => { } function getReleaseTag(context) { - const semver = context.payload.release.tag_name - if (semver.match(/^v[0-9]+\.[0-9]+\.[0-9]+$/) === null) { + const semver = require("semver"); + const version = context.payload.release.tag_name; + if (!semver.valid(version)) { throw new Error(`Release Violation: Provided version '${semver}' is not valid semver.`) } - return semver.replace('v','') + return version.replace('v','') } diff --git a/.github/scripts/release-tags.js b/.github/scripts/release-tags.js index 72a05b58fc..ee6ef003ad 100644 --- a/.github/scripts/release-tags.js +++ b/.github/scripts/release-tags.js @@ -55,11 +55,12 @@ function getDomain(context) { } function getReleaseTag(domain, app, context) { - const semver = context.payload.release.tag_name - if (semver.match(/^v[0-9]+\.[0-9]+\.[0-9]+$/) === null) { - throw new Error(`Release Violation: Provided version '${semver}' is not valid semver.`) + const semver = require("semver"); + const version = context.payload.release.tag_name; + if (!semver.valid(version)) { + throw new Error(`Release Violation: Provided version '${version}' is not valid semver.`) } - return `ghcr.io/${domain}/${app}:latest,ghcr.io/${domain}/${app}:${semver.replace('v','')}` + return `ghcr.io/${domain}/${app}:latest,ghcr.io/${domain}/${app}:${version.replace('v','')}` } function getMainTag(domain, app, { sha }) { diff --git a/.github/workflows/release-apps.yml b/.github/workflows/release-apps.yml index 15b5097901..fe1ee64b1f 100644 --- a/.github/workflows/release-apps.yml +++ b/.github/workflows/release-apps.yml @@ -39,6 +39,12 @@ jobs: username: ${{ github.repository_owner }} password: ${{ secrets.GITHUB_TOKEN }} + - uses: actions/setup-node@64ed1c7eab4cce3362f8c340dee64e5eaeef8f7c # v3.6.0 + with: + node-version-file: '.nvmrc' + + - run: npm ci + - name: Resolve Tags uses: actions/github-script@d7906e4ad0b1822421a7e6a35d5ca353c962f410 # v6.4.1 id: tags diff --git a/.github/workflows/release-ecr.yml b/.github/workflows/release-ecr.yml index 37b228677f..f6993453be 100644 --- a/.github/workflows/release-ecr.yml +++ b/.github/workflows/release-ecr.yml @@ -22,6 +22,12 @@ jobs: steps: - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + - uses: actions/setup-node@64ed1c7eab4cce3362f8c340dee64e5eaeef8f7c # v3.6.0 + with: + node-version-file: '.nvmrc' + + - run: npm ci + - name: Set up QEMU uses: docker/setup-qemu-action@e81a89b1732b9c48d79cd809d8d81d79c4647a18 # v2.1.0 diff --git a/.github/workflows/release-publish.yml b/.github/workflows/release-publish.yml index 000a905784..d799eeab50 100644 --- a/.github/workflows/release-publish.yml +++ b/.github/workflows/release-publish.yml @@ -16,18 +16,15 @@ jobs: with: node-version-file: '.nvmrc' - - uses: actions/github-script@d7906e4ad0b1822421a7e6a35d5ca353c962f410 # v6.4.1 + - run: npm ci + + - name: Resolve Version + uses: actions/github-script@d7906e4ad0b1822421a7e6a35d5ca353c962f410 # v6.4.1 id: version with: - script: | - const semver = context.ref.replace('refs/tags/v', '') - if (semver.match(/^[0-9]+\.[0-9]+\.[0-9]+$/)) { - return semver - } - throw new Error('not semver') + script: return require('./.github/scripts/release-ecr-tags.js')({ context }) result-encoding: string - - run: npm ci - run: npm run all:build - run: npm run all:version ${{ steps.version.outputs.result }} diff --git a/apps/legacy-api/src/pipes/NetworkValidationPipe.ts b/apps/legacy-api/src/pipes/NetworkValidationPipe.ts index f6c727f721..7ae5ba953c 100644 --- a/apps/legacy-api/src/pipes/NetworkValidationPipe.ts +++ b/apps/legacy-api/src/pipes/NetworkValidationPipe.ts @@ -5,7 +5,7 @@ import { PipeTransform } from '@nestjs/common' -export type SupportedNetwork = 'mainnet' | 'testnet' | 'devnet' | 'regtest' +export type SupportedNetwork = 'mainnet' | 'testnet' | 'devnet' | 'regtest' | 'changi' @Injectable() export class NetworkValidationPipe implements PipeTransform { @@ -14,7 +14,8 @@ export class NetworkValidationPipe implements PipeTransform { 'mainnet', 'testnet', 'devnet', - 'regtest' + 'regtest', + 'changi' ]) transform (value: any, metadata: ArgumentMetadata): any { diff --git a/apps/playground-api/__tests__/bots/OracleBot.test.ts b/apps/playground-api/__tests__/bots/OracleBot.test.ts index 49bb7c5585..4032ee4e39 100644 --- a/apps/playground-api/__tests__/bots/OracleBot.test.ts +++ b/apps/playground-api/__tests__/bots/OracleBot.test.ts @@ -62,6 +62,9 @@ describe('oracle bot', () => { const USDT = oracleData.tokenPrices.find(x => x.token === 'USDT') expect(USDT?.amount).toBeDefined() + + const MATIC = oracleData.tokenPrices.find(x => x.token === 'MATIC') + expect(MATIC?.amount).toBeDefined() }, 200000) }) }) diff --git a/apps/playground-api/__tests__/modules/PlaygroundModule.test.ts b/apps/playground-api/__tests__/modules/PlaygroundModule.test.ts index 0cc8045067..44cd39779f 100644 --- a/apps/playground-api/__tests__/modules/PlaygroundModule.test.ts +++ b/apps/playground-api/__tests__/modules/PlaygroundModule.test.ts @@ -15,12 +15,12 @@ afterAll(async () => { it('should have pool pairs setup', async () => { const pairs = await testing.container.call('listpoolpairs') - expect(Object.values(pairs).length).toBe(16) + expect(Object.values(pairs).length).toBe(17) }) it('should have tokens setup', async () => { const tokens = await testing.container.call('listtokens') - expect(Object.values(tokens).length).toBe(34) + expect(Object.values(tokens).length).toBe(36) }) it('should have oracles setup', async () => { @@ -56,13 +56,13 @@ it('should have loan tokens', async () => { it('should have loan collateral tokens', async () => { const results = await testing.container.call('listcollateraltokens') - expect(results.length).toBe(13) + expect(results.length).toBe(14) }) it('should have gov set', async () => { const gov = await testing.container.call('getgov', ['ATTRIBUTES']) expect(gov).toStrictEqual({ - ATTRIBUTES: expect.objectContaining({ + ATTRIBUTES: { 'v0/consortium/1/members': { '01': { backingId: 'backing_address_btc_1_c', @@ -103,9 +103,22 @@ it('should have gov set', async () => { '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), + 'v0/live/economy/evm/block/fee_burnt_min': 92233720368.54776, + 'v0/live/economy/evm/block/fee_burnt_min_hash': '0000000000000000000000000000000000000000000000000000000000000000', + 'v0/live/economy/evm/block/fee_priority': 0, + 'v0/live/economy/evm/block/fee_priority_max': 0, + 'v0/live/economy/evm/block/fee_priority_max_hash': expect.any(String), + 'v0/live/economy/evm/block/fee_priority_min': 92233720368.54776, + 'v0/live/economy/evm/block/fee_priority_min_hash': '0000000000000000000000000000000000000000000000000000000000000000', + 'v0/live/economy/loans': expect.any(Array), 'v0/params/dfip2203/active': 'true', - 'v0/params/dfip2203/reward_pct': '0.05', '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/gov': 'true', 'v0/token/0/fixed_interval_price_id': 'DFI/USD', 'v0/token/0/loan_collateral_enabled': 'true', @@ -143,49 +156,65 @@ it('should have gov set', async () => { 'v0/token/12/fixed_interval_price_id': 'EUROC/USD', 'v0/token/12/loan_collateral_enabled': 'true', 'v0/token/12/loan_collateral_factor': '1', - 'v0/token/13/payback_dfi': 'true', - 'v0/token/13/payback_dfi_fee_pct': '0.01', - 'v0/token/13/loan_payback/1': 'true', - 'v0/token/13/loan_payback/15': 'true', - 'v0/token/13/loan_payback_fee_pct/1': '0.01', - 'v0/token/13/loan_payback_fee_pct/15': '0.01', - 'v0/token/13/fixed_interval_price_id': 'DUSD/USD', + 'v0/token/13/fixed_interval_price_id': 'MATIC/USD', 'v0/token/13/loan_collateral_enabled': 'true', - 'v0/token/13/loan_collateral_factor': '1.2', - 'v0/token/13/loan_minting_enabled': 'true', - 'v0/token/13/loan_minting_interest': '0', - 'v0/token/13/loan_payback_collateral': 'true', - 'v0/token/14/loan_payback/6': 'true', - 'v0/token/14/loan_payback/13': 'true', - 'v0/token/14/loan_payback_fee_pct/6': '0.01', - 'v0/token/14/loan_payback_fee_pct/13': '0.01', - 'v0/token/14/fixed_interval_price_id': 'TU10/USD', + 'v0/token/13/loan_collateral_factor': '1', + 'v0/token/14/payback_dfi': 'true', + 'v0/token/14/payback_dfi_fee_pct': '0.01', + 'v0/token/14/loan_payback/1': 'true', + 'v0/token/14/loan_payback/16': 'true', + 'v0/token/14/loan_payback_fee_pct/1': '0.01', + 'v0/token/14/loan_payback_fee_pct/16': '0.01', + 'v0/token/14/fixed_interval_price_id': 'DUSD/USD', + 'v0/token/14/loan_collateral_enabled': 'true', + 'v0/token/14/loan_collateral_factor': '1.2', 'v0/token/14/loan_minting_enabled': 'true', - 'v0/token/14/loan_minting_interest': '1', - 'v0/token/15/loan_payback/1': 'true', - 'v0/token/15/loan_payback/13': 'true', - 'v0/token/15/loan_payback_fee_pct/1': '0.01', - 'v0/token/15/loan_payback_fee_pct/13': '0.01', - 'v0/token/15/fixed_interval_price_id': 'TD10/USD', + 'v0/token/14/loan_minting_interest': '0', + 'v0/token/14/loan_payback_collateral': 'true', + 'v0/token/15/loan_payback/6': 'true', + 'v0/token/15/loan_payback/14': 'true', + 'v0/token/15/loan_payback_fee_pct/6': '0.01', + 'v0/token/15/loan_payback_fee_pct/14': '0.01', + 'v0/token/15/fixed_interval_price_id': 'TU10/USD', 'v0/token/15/loan_minting_enabled': 'true', - 'v0/token/15/loan_minting_interest': '1.5', + 'v0/token/15/loan_minting_interest': '1', + 'v0/token/16/loan_payback/1': 'true', 'v0/token/16/loan_payback/14': 'true', + 'v0/token/16/loan_payback_fee_pct/1': '0.01', 'v0/token/16/loan_payback_fee_pct/14': '0.01', - 'v0/token/16/fixed_interval_price_id': 'TS25/USD', + 'v0/token/16/fixed_interval_price_id': 'TD10/USD', 'v0/token/16/loan_minting_enabled': 'true', - 'v0/token/16/loan_minting_interest': '2', - 'v0/token/17/payback_dfi': 'true', - 'v0/token/17/payback_dfi_fee_pct': '0.01', - 'v0/token/17/loan_payback/13': 'true', + 'v0/token/16/loan_minting_interest': '1.5', 'v0/token/17/loan_payback/15': 'true', - 'v0/token/17/loan_payback_fee_pct/13': '0.01', 'v0/token/17/loan_payback_fee_pct/15': '0.01', - 'v0/token/17/fixed_interval_price_id': 'TR50/USD', + 'v0/token/17/fixed_interval_price_id': 'TS25/USD', 'v0/token/17/loan_minting_enabled': 'true', - 'v0/token/17/loan_minting_interest': '3', + 'v0/token/17/loan_minting_interest': '2', + 'v0/token/18/payback_dfi': 'true', + 'v0/token/18/payback_dfi_fee_pct': '0.01', + 'v0/token/18/loan_payback/14': 'true', + 'v0/token/18/loan_payback/16': 'true', + 'v0/token/18/loan_payback_fee_pct/14': '0.01', + 'v0/token/18/loan_payback_fee_pct/16': '0.01', + 'v0/token/18/fixed_interval_price_id': 'TR50/USD', + 'v0/token/18/loan_minting_enabled': 'true', + 'v0/token/18/loan_minting_interest': '3', + 'v0/params/feature/icx': 'true', 'v0/params/feature/evm': 'true', - 'v0/params/feature/icx': 'true' - }) + 'v0/params/feature/transferdomain': 'true', + 'v0/params/foundation/members': [ + 'bcrt1qyrfrpadwgw7p5eh3e9h3jmu4kwlz4prx73cqny', + 'bcrt1qyeuu9rvq8a67j86pzvh5897afdmdjpyankp4mu', + 'msER9bmJjyEemRpQoS8YYVL21VyZZrSgQ7', + 'mwsZw8nF7pKxWH8eoKL9tPxTpaFkz7QeLU' + ], + 'v0/transferdomain/dvm-evm/enabled': 'true', + 'v0/transferdomain/dvm-evm/src-formats': ['bech32', 'p2pkh'], + 'v0/transferdomain/dvm-evm/dest-formats': ['erc55'], + 'v0/transferdomain/evm-dvm/src-formats': ['erc55'], + 'v0/transferdomain/evm-dvm/auth-formats': ['bech32-erc55'], + 'v0/transferdomain/evm-dvm/dest-formats': ['bech32', 'p2pkh'] + } }) async function waitForPriceValid (): Promise { diff --git a/apps/playground-api/src/bots/OracleBot.ts b/apps/playground-api/src/bots/OracleBot.ts index dc381cc712..4328f13071 100644 --- a/apps/playground-api/src/bots/OracleBot.ts +++ b/apps/playground-api/src/bots/OracleBot.ts @@ -144,6 +144,12 @@ export class OracleBot { amount: new BigNumber(1), change: new BigNumber(0), direction: PriceDirection.STABLE + }, + { + token: 'MATIC', + amount: new BigNumber(1), + change: new BigNumber(0), + direction: PriceDirection.STABLE } ] diff --git a/apps/playground-api/src/setups/setup.dex.ts b/apps/playground-api/src/setups/setup.dex.ts index e238a707a6..99cb01b534 100644 --- a/apps/playground-api/src/setups/setup.dex.ts +++ b/apps/playground-api/src/setups/setup.dex.ts @@ -235,6 +235,22 @@ export class SetupDex extends PlaygroundSetup { utxoToAccount: { [PlaygroundSetup.address]: '2000@0' } + }, + { + symbol: 'MATIC-DFI', + create: { + tokenA: 'MATIC', + tokenB: 'DFI', + commission: 0, + status: true, + ownerAddress: PlaygroundSetup.address + }, + add: { + '*': ['3000@DFI', '30000000@MATIC'] + }, + utxoToAccount: { + [PlaygroundSetup.address]: '3000@0' + } } ] } @@ -269,13 +285,17 @@ export class SetupDex extends PlaygroundSetup { const poolPairs = await this.client.poolpair.listPoolPairs() const poolPairIds = Object.keys(poolPairs) - // apply `toFixed(8)` due to 1 / 16 = 0.0625 which is valid amount on setgov + // apply `toFixed(8)` due to 1 / 17 = 0.05882353 which is valid amount on setgov const splits = Number(new BigNumber(1 / poolPairIds.length).toFixed(8)) const lpSplits: any = {} for (const k in poolPairs) { lpSplits[parseInt(k)] = splits } + // to fix: LP_SPLITS: total = 0.9996 vs expected 100000000', code: -32600, method: setgov + // 0.05882353 * 17 !== 100000000 + const lstKey = Object.keys(lpSplits)[0] + lpSplits[lstKey] = Number(new BigNumber(lpSplits[lstKey]).minus(0.00000001).toFixed(8)) await this.client.masternode.setGov({ LP_SPLITS: lpSplits }) await this.generate(1) } diff --git a/apps/playground-api/src/setups/setup.gov.ts b/apps/playground-api/src/setups/setup.gov.ts index 7f1fe98f90..a440fea955 100644 --- a/apps/playground-api/src/setups/setup.gov.ts +++ b/apps/playground-api/src/setups/setup.gov.ts @@ -14,54 +14,54 @@ export class SetupGov extends PlaygroundSetup> { ATTRIBUTES: { // dfi pay dtoken // DFI pay DUSD - 'v0/token/13/payback_dfi': 'true', - 'v0/token/13/payback_dfi_fee_pct': '0.01', + 'v0/token/14/payback_dfi': 'true', + 'v0/token/14/payback_dfi_fee_pct': '0.01', // DFI pay TR50 - 'v0/token/17/payback_dfi': 'true', - 'v0/token/17/payback_dfi_fee_pct': '0.01', + 'v0/token/18/payback_dfi': 'true', + 'v0/token/18/payback_dfi_fee_pct': '0.01', // dtoken (DUSD) pay dtoken #1 // DUSD pay TD10 - 'v0/token/15/loan_payback/13': 'true', - 'v0/token/15/loan_payback_fee_pct/13': '0.01', + 'v0/token/16/loan_payback/14': 'true', + 'v0/token/16/loan_payback_fee_pct/14': '0.01', // DUSD pay TU10 - 'v0/token/14/loan_payback/13': 'true', - 'v0/token/14/loan_payback_fee_pct/13': '0.01', + 'v0/token/15/loan_payback/14': 'true', + 'v0/token/15/loan_payback_fee_pct/14': '0.01', // DUSD pay TR50 - 'v0/token/17/loan_payback/13': 'true', - 'v0/token/17/loan_payback_fee_pct/13': '0.01', + 'v0/token/18/loan_payback/14': 'true', + 'v0/token/18/loan_payback_fee_pct/14': '0.01', // dtoken pay dtoken #2 // TD10 pay DUSD - 'v0/token/13/loan_payback/15': 'true', - 'v0/token/13/loan_payback_fee_pct/15': '0.01', + 'v0/token/14/loan_payback/16': 'true', + 'v0/token/14/loan_payback_fee_pct/16': '0.01', // TD10 pay TR50 - 'v0/token/17/loan_payback/15': 'true', - 'v0/token/17/loan_payback_fee_pct/15': '0.01', + 'v0/token/18/loan_payback/16': 'true', + 'v0/token/18/loan_payback_fee_pct/16': '0.01', // TU10 pay TS25 - 'v0/token/16/loan_payback/14': 'true', - 'v0/token/16/loan_payback_fee_pct/14': '0.01', + 'v0/token/17/loan_payback/15': 'true', + 'v0/token/17/loan_payback_fee_pct/15': '0.01', // cToken pay dToken // BTC pay TD10 - 'v0/token/15/loan_payback/1': 'true', - 'v0/token/15/loan_payback_fee_pct/1': '0.01', + 'v0/token/16/loan_payback/1': 'true', + 'v0/token/16/loan_payback_fee_pct/1': '0.01', // BTC pay DUSD - 'v0/token/13/loan_payback/1': 'true', - 'v0/token/13/loan_payback_fee_pct/1': '0.01', + 'v0/token/14/loan_payback/1': 'true', + 'v0/token/14/loan_payback_fee_pct/1': '0.01', // CU10 pay TU10 - 'v0/token/14/loan_payback/6': 'true', - 'v0/token/14/loan_payback_fee_pct/6': '0.01', + 'v0/token/15/loan_payback/6': 'true', + 'v0/token/15/loan_payback_fee_pct/6': '0.01', // Unloop mechanism for DUSD - 'v0/token/13/loan_payback_collateral': 'true', + 'v0/token/14/loan_payback_collateral': 'true', // On-chain governance 'v0/params/feature/gov': 'true', @@ -155,7 +155,14 @@ export class SetupGov extends PlaygroundSetup> { await this.client.masternode.setGov({ ATTRIBUTES: { - 'v0/params/feature/evm': 'true' + 'v0/params/feature/evm': 'true', + 'v0/params/feature/transferdomain': 'true', + 'v0/transferdomain/dvm-evm/enabled': 'true', + 'v0/transferdomain/dvm-evm/src-formats': ['p2pkh', 'bech32'], + 'v0/transferdomain/dvm-evm/dest-formats': ['erc55'], + 'v0/transferdomain/evm-dvm/src-formats': ['erc55'], + 'v0/transferdomain/evm-dvm/auth-formats': ['bech32-erc55'], + 'v0/transferdomain/evm-dvm/dest-formats': ['p2pkh', 'bech32'] } }) await this.generate(1) diff --git a/apps/playground-api/src/setups/setup.loan.collateral.ts b/apps/playground-api/src/setups/setup.loan.collateral.ts index 7509ed5666..b48b8141b1 100644 --- a/apps/playground-api/src/setups/setup.loan.collateral.ts +++ b/apps/playground-api/src/setups/setup.loan.collateral.ts @@ -71,6 +71,11 @@ export class SetupLoanCollateral extends PlaygroundSetup { token: 'EUROC', fixedIntervalPriceId: 'EUROC/USD', factor: new BigNumber('1') + }, + { + token: 'MATIC', + fixedIntervalPriceId: 'MATIC/USD', + factor: new BigNumber('1') } ] } diff --git a/apps/playground-api/src/setups/setup.oracle.ts b/apps/playground-api/src/setups/setup.oracle.ts index 6d767d694f..b1783aaafe 100644 --- a/apps/playground-api/src/setups/setup.oracle.ts +++ b/apps/playground-api/src/setups/setup.oracle.ts @@ -87,6 +87,10 @@ const FEEDS: OraclePriceFeed[] = [ { token: 'EUROC', currency: 'USD' + }, + { + token: 'MATIC', + currency: 'USD' } ] diff --git a/apps/playground-api/src/setups/setup.token.ts b/apps/playground-api/src/setups/setup.token.ts index 288a82d8af..0e7f9b2d3b 100644 --- a/apps/playground-api/src/setups/setup.token.ts +++ b/apps/playground-api/src/setups/setup.token.ts @@ -142,6 +142,17 @@ export class SetupToken extends PlaygroundSetup { collateralAddress: PlaygroundSetup.address }, amount: 200000000 + }, + { + create: { + symbol: 'MATIC', + name: 'Playground MATIC', + isDAT: true, + mintable: true, + tradeable: true, + collateralAddress: PlaygroundSetup.address + }, + amount: 100000000 } ] } diff --git a/apps/whale-api/__sanity__/WhaleSanityContainer.sanity.ts b/apps/whale-api/__sanity__/WhaleSanityContainer.sanity.ts index f808c92c61..db14363fd5 100644 --- a/apps/whale-api/__sanity__/WhaleSanityContainer.sanity.ts +++ b/apps/whale-api/__sanity__/WhaleSanityContainer.sanity.ts @@ -164,6 +164,7 @@ describe('/rpc/getblock', () => { difficulty: 4.656542373906925e-10, hash: 'd744db74fb70ed42767ae028a129365fb4d7de54ba1b6575fb047490554f8a7b', height: 0, + masternode: '0000000000000000000000000000000000000000000000000000000000000000', mediantime: 1579045065, merkleroot: '5615dbbb379da893dd694e02d25a7955e1b7471db55f42bbd82b5d3f5bdb8d38', mintedBlocks: 0, @@ -172,7 +173,8 @@ describe('/rpc/getblock', () => { nonutxo: [ { AnchorReward: 0.2, - IncentiveFunding: 20 + Burnt: 0, + CommunityDevelopmentFunds: 0 } ], size: 1424, diff --git a/apps/whale-api/docker-compose.yml b/apps/whale-api/docker-compose.yml index 00d94820cc..0f5e0b0ecc 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:master-91a01aea0 + image: defi/defichain:4.0.0-beta10-ocean ports: - "19554:19554" command: > @@ -42,7 +42,6 @@ services: -grandcentralheight=16 -grandcentralepilogueheight=17 -nextnetworkupgradeheight=18 - -changiintermediateheight=19 -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 b3811c2a6c..92ef71d0f6 100644 --- a/apps/whale-api/src/app.configuration.ts +++ b/apps/whale-api/src/app.configuration.ts @@ -31,7 +31,7 @@ export function ENV_VALIDATION_SCHEMA (): any { return Joi.object({ NODE_ENV: Joi.string().optional(), WHALE_VERSION: Joi.string().optional(), - WHALE_NETWORK: Joi.string().valid('mainnet', 'testnet', 'regtest', 'devnet').default('regtest'), + 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() diff --git a/apps/whale-api/src/module.api/masternode.service.ts b/apps/whale-api/src/module.api/masternode.service.ts index 8a6db932f6..6d118996b2 100644 --- a/apps/whale-api/src/module.api/masternode.service.ts +++ b/apps/whale-api/src/module.api/masternode.service.ts @@ -29,6 +29,12 @@ const MasternodeConsensusParams = { newActivationDelay: 1008, resignDelay: 60, newResignDelay: 2 * 1008 + }, + changi: { + activationDelay: 10, + newActivationDelay: 1008, + resignDelay: 60, + newResignDelay: 2 * 1008 } } diff --git a/package-lock.json b/package-lock.json index af857c4183..6a3955cb6f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -24,6 +24,7 @@ "lerna": "5.1.8", "lint-staged": "13.2.3", "nock": "13.3.0", + "semver": "^7.5.4", "shuffle-seed": "1.1.6", "ts-jest": "27.1.5", "typescript": "4.2.4", @@ -22396,9 +22397,9 @@ } }, "node_modules/semver": { - "version": "7.3.8", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", - "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", "dependencies": { "lru-cache": "^6.0.0" }, @@ -34666,6 +34667,7 @@ "lerna": "5.1.8", "lint-staged": "13.2.3", "nock": "13.3.0", + "semver": "^7.5.4", "shuffle-seed": "1.1.6", "ts-jest": "27.1.5", "typescript": "4.2.4", @@ -50615,9 +50617,9 @@ } }, "semver": { - "version": "7.3.8", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", - "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", "requires": { "lru-cache": "^6.0.0" } @@ -60721,9 +60723,9 @@ } }, "semver": { - "version": "7.3.8", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", - "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", "requires": { "lru-cache": "^6.0.0" } diff --git a/package.json b/package.json index 6eb9de3111..508d20e450 100644 --- a/package.json +++ b/package.json @@ -36,6 +36,7 @@ "lerna": "5.1.8", "lint-staged": "13.2.3", "nock": "13.3.0", + "semver": "^7.5.4", "shuffle-seed": "1.1.6", "ts-jest": "27.1.5", "typescript": "4.2.4", 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 eb1d3f4a38..9d2d52fe9e 100644 --- a/packages/jellyfish-api-core/__tests__/category/account/getTokenBalances.test.ts +++ b/packages/jellyfish-api-core/__tests__/category/account/getTokenBalances.test.ts @@ -104,13 +104,21 @@ describe('Account', () => { it('should getTokenBalances with including eth', async () => { await client.masternode.setGov({ ATTRIBUTES: { - 'v0/params/feature/evm': 'true' + // Enable evm + 'v0/params/feature/evm': 'true', + 'v0/params/feature/transferdomain': 'true', + 'v0/transferdomain/dvm-evm/enabled': 'true', + 'v0/transferdomain/dvm-evm/src-formats': ['p2pkh', 'bech32'], + 'v0/transferdomain/dvm-evm/dest-formats': ['erc55'], + 'v0/transferdomain/evm-dvm/src-formats': ['erc55'], + 'v0/transferdomain/evm-dvm/auth-formats': ['bech32-erc55'], + 'v0/transferdomain/evm-dvm/dest-formats': ['p2pkh', 'bech32'] } }) - await container.generate(1) + await container.generate(2) - const dvmAddr = await container.call('getnewaddress') - const evmAddr = await container.getNewAddress('eth', 'eth') + const dvmAddr = await container.call('getnewaddress', ['', 'bech32']) + const evmAddr = await container.getNewAddress('erc55', 'erc55') await container.call('utxostoaccount', [{ [dvmAddr]: '100@0' }]) await container.generate(1) 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 af784c8a88..02a74d6c62 100644 --- a/packages/jellyfish-api-core/__tests__/category/account/transferDomain.test.ts +++ b/packages/jellyfish-api-core/__tests__/category/account/transferDomain.test.ts @@ -15,13 +15,20 @@ describe('TransferDomain', () => { await client.masternode.setGov({ ATTRIBUTES: { - 'v0/params/feature/evm': 'true' + 'v0/params/feature/evm': 'true', + 'v0/params/feature/transferdomain': 'true', + 'v0/transferdomain/dvm-evm/enabled': 'true', + 'v0/transferdomain/dvm-evm/src-formats': ['p2pkh', 'bech32'], + 'v0/transferdomain/dvm-evm/dest-formats': ['erc55'], + 'v0/transferdomain/evm-dvm/src-formats': ['erc55'], + 'v0/transferdomain/evm-dvm/auth-formats': ['bech32-erc55'], + 'v0/transferdomain/evm-dvm/dest-formats': ['p2pkh', 'bech32'] } }) - await container.generate(1) + await container.generate(2) - dvmAddr = await container.call('getnewaddress') - evmAddr = await container.getNewAddress('eth', 'eth') + dvmAddr = await container.call('getnewaddress', ['', 'bech32']) + evmAddr = await container.getNewAddress('erc55', 'erc55') await container.call('utxostoaccount', [{ [dvmAddr]: '100@0' }]) await container.generate(1) @@ -83,7 +90,7 @@ describe('TransferDomain', () => { await expect(promise).rejects.toThrow('Source amount must be equal to destination amount') }) - it('should fail if transfer other than DFI token', async () => { + it('should fail if transfer diff token', async () => { const promise = client.account.transferDomain([ { src: { @@ -99,7 +106,7 @@ describe('TransferDomain', () => { } ]) await expect(promise).rejects.toThrow(RpcApiError) - await expect(promise).rejects.toThrow('For transferdomain, only DFI token is currently supported') + await expect(promise).rejects.toThrow('Source token and destination token must be the same') }) it('(dvm -> evm) should fail if source address and source domain are not match', async () => { @@ -137,7 +144,7 @@ describe('TransferDomain', () => { } ]) await expect(promise).rejects.toThrow(RpcApiError) - await expect(promise).rejects.toThrow('Src address must be an ETH address in case of "EVM" domain') + await expect(promise).rejects.toThrow('Src address must be an ERC55 address in case of "EVM" domain') }) it('(dvm -> evm) should fail if destination address and destination domain are not match', async () => { @@ -156,7 +163,7 @@ describe('TransferDomain', () => { } ]) await expect(promise).rejects.toThrow(RpcApiError) - await expect(promise).rejects.toThrow('Dst address must be an ETH address in case of "EVM" domain') + await expect(promise).rejects.toThrow('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 () => { @@ -370,7 +377,7 @@ describe('TransferDomain', () => { expect(new BigNumber(withoutEth)).toStrictEqual(new BigNumber(withEth)) }) - it('should (duo) Transfer Domain from DVM to EVM', async () => { + it.skip('should (duo) Transfer Domain from DVM to EVM', async () => { const dvmAcc = await client.account.getAccount(dvmAddr) const [dvmBalance0, tokenId0] = dvmAcc[0].split('@') @@ -422,7 +429,7 @@ describe('TransferDomain', () => { .toStrictEqual(new BigNumber(withEth).minus(3 + 4)) }) - it('should (duo) Transfer Domain from EVM to DVM', async () => { + it.skip('should (duo) Transfer Domain from EVM to DVM', async () => { const dvmAcc = await client.account.getAccount(dvmAddr) const [dvmBalance0, tokenId0] = dvmAcc[0].split('@') @@ -471,7 +478,7 @@ describe('TransferDomain', () => { expect(new BigNumber(withoutEth)).toStrictEqual(new BigNumber(withEth)) }) - it('should (duo-diff) Transfer Domain from EVM to DVM and DVM to EVM', async () => { + it.skip('should (duo-diff) Transfer Domain from EVM to DVM and DVM to EVM', async () => { // transfer some to evm first await client.account.transferDomain([ { 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 8993fb2f2f..dbd5fe4d16 100644 --- a/packages/jellyfish-api-core/__tests__/category/evm/evmTx.test.ts +++ b/packages/jellyfish-api-core/__tests__/category/evm/evmTx.test.ts @@ -23,15 +23,25 @@ describe('EVMTX', () => { beforeAll(async () => { await container.start() await container.waitForWalletCoinbaseMaturity() - await testing.rpc.masternode.setGov({ - ATTRIBUTES: { 'v0/params/feature/evm': 'true' } + await client.masternode.setGov({ + ATTRIBUTES: { + // Enable evm + 'v0/params/feature/evm': 'true', + 'v0/params/feature/transferdomain': 'true', + 'v0/transferdomain/dvm-evm/enabled': 'true', + 'v0/transferdomain/dvm-evm/src-formats': ['p2pkh', 'bech32'], + 'v0/transferdomain/dvm-evm/dest-formats': ['erc55'], + 'v0/transferdomain/evm-dvm/src-formats': ['erc55'], + 'v0/transferdomain/evm-dvm/auth-formats': ['bech32-erc55'], + 'v0/transferdomain/evm-dvm/dest-formats': ['p2pkh', 'bech32'] + } }) - await container.generate(1) - dfiAddress = await container.call('getnewaddress') + await container.generate(2) + dfiAddress = await container.call('getnewaddress', ['', 'bech32']) await container.call('utxostoaccount', [{ [dfiAddress]: '105@DFI' }]) await container.generate(1) - ethAddress = await container.call('getnewaddress', ['', 'eth']) - toEthAddress = await container.call('getnewaddress', ['', 'eth']) + ethAddress = await container.call('getnewaddress', ['', 'erc55']) + toEthAddress = await container.call('getnewaddress', ['', 'erc55']) }) afterAll(async () => { diff --git a/packages/jellyfish-api-core/__tests__/category/loan/setLoanToken.test.ts b/packages/jellyfish-api-core/__tests__/category/loan/setLoanToken.test.ts index b978c56af9..a1e07262b8 100644 --- a/packages/jellyfish-api-core/__tests__/category/loan/setLoanToken.test.ts +++ b/packages/jellyfish-api-core/__tests__/category/loan/setLoanToken.test.ts @@ -104,7 +104,7 @@ describe('Loan setLoanToken', () => { symbol: '', fixedIntervalPriceId: 'Token2/USD' }) - await expect(promise).rejects.toThrow('RpcApiError: \'Test SetLoanTokenTx execution failed:\ntoken symbol should be non-empty and starts with a letter\', code: -32600, method: setloantoken') + await expect(promise).rejects.toThrow('RpcApiError: \'Test SetLoanTokenTx execution failed:\nInvalid token symbol. Valid: Start with an alphabet, non-empty, not contain # or /\', code: -32600, method: setloantoken') }) it('should not setLoanToken if the symbol is used in other token', async () => { diff --git a/packages/jellyfish-api-core/__tests__/category/loan/updateLoanToken.test.ts b/packages/jellyfish-api-core/__tests__/category/loan/updateLoanToken.test.ts index 138a3f9c37..552ba4e404 100644 --- a/packages/jellyfish-api-core/__tests__/category/loan/updateLoanToken.test.ts +++ b/packages/jellyfish-api-core/__tests__/category/loan/updateLoanToken.test.ts @@ -143,7 +143,7 @@ describe('Loan updateLoanToken', () => { it('should not updateLoanToken if symbol is an empty string', async () => { const promise = testing.rpc.loan.updateLoanToken('Token1', { symbol: '' }) - await expect(promise).rejects.toThrow('RpcApiError: \'Test UpdateLoanTokenTx execution failed:\ntoken symbol should be non-empty and starts with a letter\', code: -32600, method: updateloantoken') + await expect(promise).rejects.toThrow('RpcApiError: \'Test UpdateLoanTokenTx execution failed:\nInvalid token symbol. Valid: Start with an alphabet, non-empty, not contain # or /\', code: -32600, method: updateloantoken') }) it('should not updateLoanToken if the symbol is used in other token', async () => { diff --git a/packages/jellyfish-network/__tests__/BitcoinJsLib.test.ts b/packages/jellyfish-network/__tests__/BitcoinJsLib.test.ts index b1496cc200..0f8093ebd4 100644 --- a/packages/jellyfish-network/__tests__/BitcoinJsLib.test.ts +++ b/packages/jellyfish-network/__tests__/BitcoinJsLib.test.ts @@ -35,3 +35,15 @@ it('should match RegTest network', () => { expect(network.scriptHash).toStrictEqual(0xc4) expect(network.messagePrefix).toStrictEqual('\x15Defi Signed Message:\n') }) + +it('should match Changi network', () => { + const network = getNetworkBitcoinJsLib('changi') + + expect(network.bech32).toStrictEqual('tf') + expect(network.bip32.public).toStrictEqual(0x043587cf) + expect(network.bip32.private).toStrictEqual(0x04358394) + expect(network.wif).toStrictEqual(0xef) + expect(network.pubKeyHash).toStrictEqual(0xf) + expect(network.scriptHash).toStrictEqual(0x80) + expect(network.messagePrefix).toStrictEqual('\x15Defi Signed Message:\n') +}) diff --git a/packages/jellyfish-network/__tests__/Network.test.ts b/packages/jellyfish-network/__tests__/Network.test.ts index 4241bdfdcc..e2da47ff28 100644 --- a/packages/jellyfish-network/__tests__/Network.test.ts +++ b/packages/jellyfish-network/__tests__/Network.test.ts @@ -1,4 +1,4 @@ -import { Network, MainNet, RegTest, TestNet, DevNet, getNetwork } from '../src' +import { Network, MainNet, RegTest, TestNet, DevNet, Changi, getNetwork } from '../src' it('should be exported', () => { const network: Network = MainNet @@ -26,6 +26,11 @@ describe('getNetwork', () => { expect(getNetwork('regtest').name).toStrictEqual('regtest') expect(getNetwork('regtest').bech32.hrp).toStrictEqual('bcrt') }) + + it('should get changi', () => { + expect(getNetwork('changi').name).toStrictEqual('changi') + expect(getNetwork('changi').bech32.hrp).toStrictEqual('tf') + }) }) it('should match MainNet network', () => { @@ -71,3 +76,14 @@ it('should match RegTest network', () => { expect(RegTest.scriptHashPrefix).toStrictEqual(0xc4) expect(RegTest.messagePrefix).toStrictEqual('\x15Defi Signed Message:\n') }) + +it('should match Changi network', () => { + expect(Changi.name).toStrictEqual('changi') + expect(Changi.bech32.hrp).toStrictEqual('tf') + expect(Changi.bip32.publicPrefix).toStrictEqual(0x043587cf) + expect(Changi.bip32.privatePrefix).toStrictEqual(0x04358394) + expect(Changi.wifPrefix).toStrictEqual(0xef) + expect(Changi.pubKeyHashPrefix).toStrictEqual(0xf) + expect(Changi.scriptHashPrefix).toStrictEqual(0x80) + expect(Changi.messagePrefix).toStrictEqual('\x15Defi Signed Message:\n') +}) diff --git a/packages/jellyfish-network/src/Network.ts b/packages/jellyfish-network/src/Network.ts index 5c9db12d39..59e0f2a426 100644 --- a/packages/jellyfish-network/src/Network.ts +++ b/packages/jellyfish-network/src/Network.ts @@ -8,7 +8,7 @@ export type NetworkName = Network['name'] * They can be found in DeFiCh/ain project in file chainparams.cpp, under base58Prefixes */ export interface Network { - name: 'mainnet' | 'testnet' | 'regtest' | 'devnet' + name: 'mainnet' | 'testnet' | 'regtest' | 'devnet' | 'changi' bech32: { /** bech32 human readable part */ hrp: 'df' | 'tf' | 'bcrt' @@ -48,6 +48,8 @@ export function getNetwork (network: NetworkName): Network { return DevNet case 'regtest': return RegTest + case 'changi': + return Changi default: throw new Error(`${network as string} network not found`) } @@ -104,8 +106,8 @@ export const DevNet: Network = { ...TestNet, name: 'devnet', ports: { - rpc: 20554, - p2p: 20555 + rpc: 21554, + p2p: 21555 } } @@ -130,3 +132,15 @@ export const RegTest: Network = { p2p: 19555 } } + +/** + * Changi specific DeFi configuration. + */ +export const Changi: Network = { + ...TestNet, + name: 'changi', + ports: { + rpc: 20554, + p2p: 20555 + } +} 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 cdf4ca5c6a..c3c0f067bc 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 @@ -35,10 +35,17 @@ describe('transferDomain', () => { await testing.rpc.masternode.setGov({ ATTRIBUTES: { - 'v0/params/feature/evm': 'true' + 'v0/params/feature/evm': 'true', + 'v0/params/feature/transferdomain': 'true', + 'v0/transferdomain/dvm-evm/enabled': 'true', + 'v0/transferdomain/dvm-evm/src-formats': ['p2pkh', 'bech32'], + 'v0/transferdomain/dvm-evm/dest-formats': ['erc55'], + 'v0/transferdomain/evm-dvm/src-formats': ['erc55'], + 'v0/transferdomain/evm-dvm/auth-formats': ['bech32-erc55'], + 'v0/transferdomain/evm-dvm/dest-formats': ['p2pkh', 'bech32'] } }) - await testing.generate(1) + await testing.generate(2) providers = await getProviders(testing.container) providers.setEllipticPair(WIF.asEllipticPair(RegTestFoundationKeys[0].owner.privKey)) @@ -154,7 +161,7 @@ describe('transferDomain', () => { const promise = sendTransaction(testing.container, txn) await expect(promise).rejects.toThrow(DeFiDRpcError) - await expect(promise).rejects.toThrow('DeFiDRpcError: \'TransferDomainTx: For transferdomain, only DFI token is currently supported (code 16)') + await expect(promise).rejects.toThrow('DeFiDRpcError: \'TransferDomainTx: Non-DAT or LP tokens are not supported for transferdomain (code 16)') }) it('(dvm -> evm) should fail if source address and source domain are not match', async () => { @@ -214,7 +221,7 @@ describe('transferDomain', () => { const promise = sendTransaction(testing.container, txn) await expect(promise).rejects.toThrow(DeFiDRpcError) - await expect(promise).rejects.toThrow('DeFiDRpcError: \'TransferDomainTx: Src address must be an ETH 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 16)\', code: -26') }) it('(dvm -> evm) should fail if destination address and destination domain are not match', async () => { @@ -244,7 +251,7 @@ describe('transferDomain', () => { const promise = sendTransaction(testing.container, txn) await expect(promise).rejects.toThrow(DeFiDRpcError) - await expect(promise).rejects.toThrow('DeFiDRpcError: \'TransferDomainTx: Dst address must be an ETH 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 (code 16)') }) it('(evm -> dvm) should fail if destination address and destination domain are not match', async () => { @@ -438,7 +445,7 @@ describe('transferDomain', () => { expect(new BigNumber(withoutEth)).toStrictEqual(new BigNumber(withEth)) }) - it('should (duo) transfer domain from DVM to EVM', async () => { + it.skip('should (duo) transfer domain from DVM to EVM', async () => { const dvmAccBefore = await testing.rpc.account.getAccount(dvmAddr) const [dvmBalanceBefore0, tokenIdBefore0] = dvmAccBefore[0].split('@') @@ -525,7 +532,7 @@ describe('transferDomain', () => { .toStrictEqual(new BigNumber(withEth).minus(2 + 1.5)) }) - it('should (duo) transfer domain from EVM to DVM', async () => { + it.skip('should (duo) transfer domain from EVM to DVM', async () => { const dvmAccBefore = await testing.rpc.account.getAccount(dvmAddr) const [dvmBalanceBefore0, tokenIdBefore0] = dvmAccBefore[0].split('@') @@ -609,7 +616,7 @@ describe('transferDomain', () => { expect(new BigNumber(withoutEth)).toStrictEqual(new BigNumber(withEth)) }) - it('should (duo-diff) Transfer Domain from EVM to DVM and DVM to EVM', async () => { + it.skip('should (duo-diff) Transfer Domain from EVM to DVM and DVM to EVM', async () => { // transfer some to evm first { const transferDomain: TransferDomain = { 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 a764762841..70fc9ab7ee 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: token symbol should be non-empty and starts with a letter (code 16)\', code: -26') + await expect(promise).rejects.toThrow('SetLoanTokenTx: Invalid token symbol. Valid: Start with an alphabet, non-empty, not contain # or / (code 16)\', code: -26') }) it('should not setLoanToken if the symbol is used in other token', async () => { 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 fa94c98687..92022217ad 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: token symbol should be non-empty and starts with a letter (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 16)\', code: -26') }) it('should not updateLoanToken if the symbol is used in other token', async () => { diff --git a/packages/jellyfish-transaction-builder/__tests__/txn/varint_gt_128.test.ts b/packages/jellyfish-transaction-builder/__tests__/txn/varint_gt_128.test.ts index 405776ac0d..512432f997 100644 --- a/packages/jellyfish-transaction-builder/__tests__/txn/varint_gt_128.test.ts +++ b/packages/jellyfish-transaction-builder/__tests__/txn/varint_gt_128.test.ts @@ -599,56 +599,58 @@ it('should setCollateralToken, takeLoan and paybackLoan', async () => { await providers.setupMocks() const script = await providers.elliptic.script() + // not allowed for non-DAT token // test DCT token on `setCollateralToken` - { - await fundEllipticPair(container, providers.ellipticPair, 10) - - const txn = await builder.loans.setCollateralToken({ - token: 128, - factor: new BigNumber(1), - currencyPair: { token: 'FISH#128', currency: 'USD' }, - activateAfterBlock: 0 - }, script) - - // Ensure the created txn is correct. - const outs = await sendTransaction(container, txn) - expect(outs[0].value).toStrictEqual(0) - - const col = await testing.rpc.loan.getCollateralToken('FISH#128') - expect(col).toStrictEqual({ - token: 'FISH#128', - tokenId: expect.stringMatching(/[0-f]{64}/), - factor: new BigNumber(1), - fixedIntervalPriceId: 'FISH#128/USD' - }) - } - + // { + // await fundEllipticPair(container, providers.ellipticPair, 10) + + // const txn = await builder.loans.setCollateralToken({ + // token: 128, + // factor: new BigNumber(1), + // currencyPair: { token: 'FISH#128', currency: 'USD' }, + // activateAfterBlock: 0 + // }, script) + + // // Ensure the created txn is correct. + // const outs = await sendTransaction(container, txn) + // expect(outs[0].value).toStrictEqual(0) + + // const col = await testing.rpc.loan.getCollateralToken('FISH#128') + // expect(col).toStrictEqual({ + // token: 'FISH#128', + // tokenId: expect.stringMatching(/[0-f]{64}/), + // factor: new BigNumber(1), + // fixedIntervalPriceId: 'FISH#128/USD' + // }) + // } + + // not allowed for non-DAT token // test >128 DAT token on `setCollateralToken` - { - await fundEllipticPair(container, providers.ellipticPair, 10) - - const catId = Number(await testing.token.getTokenId('CAT')) - expect(catId).toBeGreaterThan(128) - - const txn = await builder.loans.setCollateralToken({ - token: catId, - factor: new BigNumber(1), - currencyPair: { token: 'CAT', currency: 'USD' }, - activateAfterBlock: 0 - }, script) - - // Ensure the created txn is correct. - const outs = await sendTransaction(container, txn) - expect(outs[0].value).toStrictEqual(0) - - const col = await testing.rpc.loan.getCollateralToken('CAT') - expect(col).toStrictEqual({ - token: 'CAT', - tokenId: expect.stringMatching(/[0-f]{64}/), - factor: new BigNumber(1), - fixedIntervalPriceId: 'CAT/USD' - }) - } + // { + // await fundEllipticPair(container, providers.ellipticPair, 10) + + // const catId = Number(await testing.token.getTokenId('CAT')) + // expect(catId).toBeGreaterThan(128) + + // const txn = await builder.loans.setCollateralToken({ + // token: catId, + // factor: new BigNumber(1), + // currencyPair: { token: 'CAT', currency: 'USD' }, + // activateAfterBlock: 0 + // }, script) + + // // Ensure the created txn is correct. + // const outs = await sendTransaction(container, txn) + // expect(outs[0].value).toStrictEqual(0) + + // const col = await testing.rpc.loan.getCollateralToken('CAT') + // expect(col).toStrictEqual({ + // token: 'CAT', + // tokenId: expect.stringMatching(/[0-f]{64}/), + // factor: new BigNumber(1), + // fixedIntervalPriceId: 'CAT/USD' + // }) + // } await testing.rpc.loan.createLoanScheme({ minColRatio: 150, diff --git a/packages/jellyfish-transaction-builder/src/txn/txn_builder_governance.ts b/packages/jellyfish-transaction-builder/src/txn/txn_builder_governance.ts index 8eaa3d86fc..39e0698018 100644 --- a/packages/jellyfish-transaction-builder/src/txn/txn_builder_governance.ts +++ b/packages/jellyfish-transaction-builder/src/txn/txn_builder_governance.ts @@ -45,12 +45,18 @@ export class TxnBuilderGovernance extends P2WPKHTxnBuilder { } let creationFee = new BigNumber('5') if (this.network.name === 'mainnet') { - creationFee = new BigNumber('100') - } - if (this.network.name === 'testnet') { - creationFee = new BigNumber('50') - } - if (createVoc.options === 1) { + if (createVoc.options === 1) { + creationFee = new BigNumber('5000') + } else { + creationFee = new BigNumber('50') + } + } else if (this.network.name === 'testnet') { + if (createVoc.options === 1) { + creationFee = new BigNumber('50') + } else { + creationFee = new BigNumber('50') + } + } else if (createVoc.options === 1) { creationFee = new BigNumber('10000') } return await this.createDeFiTx( diff --git a/packages/ocean-api-client/src/OceanApiClient.ts b/packages/ocean-api-client/src/OceanApiClient.ts index 1542a350f9..ebe18b7b50 100644 --- a/packages/ocean-api-client/src/OceanApiClient.ts +++ b/packages/ocean-api-client/src/OceanApiClient.ts @@ -24,7 +24,7 @@ export interface OceanApiClientOptions { /** * Network that ocean client is configured to */ - network?: 'mainnet' | 'testnet' | 'devnet' | 'regtest' | string + network?: 'mainnet' | 'testnet' | 'devnet' | 'regtest' | 'changi' | string } /** diff --git a/packages/testcontainers/src/containers/DeFiDContainer.ts b/packages/testcontainers/src/containers/DeFiDContainer.ts index 50c54f29af..b04feb86dd 100644 --- a/packages/testcontainers/src/containers/DeFiDContainer.ts +++ b/packages/testcontainers/src/containers/DeFiDContainer.ts @@ -6,7 +6,7 @@ import { NativeChainRpc } from '../index' /** * Types of network as per https://github.com/DeFiCh/ain/blob/bc231241/src/chainparams.cpp#L825-L836 */ -type Network = 'mainnet' | 'testnet' | 'devnet' | 'regtest' +type Network = 'mainnet' | 'testnet' | 'devnet' | 'regtest' | 'changi' /** * Mandatory options to start defid with @@ -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-beta8' // renovate.json regexManagers + return 'defi/defichain:4.0.0-beta10-ocean' // renovate.json regexManagers } public static readonly DefaultStartOptions = { diff --git a/packages/testcontainers/src/containers/NativeChainContainer.ts b/packages/testcontainers/src/containers/NativeChainContainer.ts index df7f1cf204..51eaa6e548 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:master-91a01aea0' // renovate.json regexManagers + return 'defi/defichain:4.0.0-beta10-ocean' // renovate.json regexManagers } public static readonly PREFIX = 'defichain-testcontainers-' @@ -90,6 +90,9 @@ export class NativeChainContainer extends GenericContainer { '-rpcbind=0.0.0.0', '-rpcworkqueue=512' ], + changi: [ + '-changi=1' + ], testnet: [ '-testnet=1' ], diff --git a/packages/whale-api-client/src/api/stats.ts b/packages/whale-api-client/src/api/stats.ts index 4b2e24bdc2..2656a1c01b 100644 --- a/packages/whale-api-client/src/api/stats.ts +++ b/packages/whale-api-client/src/api/stats.ts @@ -143,7 +143,7 @@ export interface SupplyData { export interface BurnData { address: string /** - * Amount send to burn address + * Amount of DFI send to burn address */ amount: number /** @@ -151,19 +151,19 @@ export interface BurnData { */ tokens: string[] /** - * Amount collected via fee burn + * Amount of DFI collected via fee burn */ feeburn: number /** - * Amount collected via emission burn + * Amount of DFI collected via emission burn */ emissionburn: number /** - * Amount collected via auction burn + * Amount of DFI collected via auction burn */ auctionburn: number /** - * Value of burn after payback + * Value of burn after payback (in DFI) */ paybackburn: number /** @@ -183,19 +183,19 @@ export interface BurnData { */ dfipaybacktokens: string[] /** - * Amount of paybacks + * Amount of paybacks; formatted as AMOUNT@SYMBOL */ paybackfees: string[] /** - * Amount of tokens that are paid back + * Amount of tokens that are paid back; formatted as AMOUNT@SYMBOL */ paybacktokens: string[] /** - * Amount of tokens burned due to futureswap + * Amount of tokens burned due to futureswap; formatted as AMOUNT@SYMBOL */ dfip2203: string[] /** - * Amount of tokens burned due to DFI-to-DUSD swap + * Amount of tokens burned due to DFI-to-DUSD swap; formatted as AMOUNT@SYMBOL */ dfip2206f: string[] }