git.delta.rocks / unique-network / refs/commits / 430b0201ea83

difftreelog

Merge pull request #1046 from UniqueNetwork/ci/hydra-xcm-integration

Yaroslav Bolyukin2023-12-14parents: #27ba026 #ef7fe00.patch.diff
in: master
hydra xcm integration

16 files changed

modified.baedeker/rewrites.example.jsonnetdiffbeforeafterboth
--- a/.baedeker/rewrites.example.jsonnet
+++ b/.baedeker/rewrites.example.jsonnet
@@ -1,17 +1,18 @@
 local dotenv = {
-    [std.splitLimit(line, "=", 2)[0]]: std.splitLimit(line, "=", 2)[1]
-    for line in std.split(importstr "../.env", "\n")
-    if line != ""
-    if std.member(line, "=")
+  [std.splitLimit(line, '=', 2)[0]]: std.splitLimit(line, '=', 2)[1]
+  for line in std.split(importstr '../.env', '\n')
+  if line != ''
+  if std.member(line, '=')
 };
 
 function(prev, repoDir)
-(import 'baedeker-library/ops/rewrites.libsonnet').rewriteNodePaths({
-	'bin/unique':'%s/target/release/unique-collator' % repoDir,
-	'bin/polkadot':{dockerImage:'uniquenetwork/builder-polkadot:%s' % dotenv.POLKADOT_MAINNET_BRANCH},
-	'bin/acala':{dockerImage:'uniquenetwork/builder-acala:%s' % dotenv.ACALA_BUILD_BRANCH},
-	'bin/moonbeam':{dockerImage:'uniquenetwork/builder-moonbeam:%s' % dotenv.MOONBEAM_BUILD_BRANCH},
-	'bin/cumulus':{dockerImage:'uniquenetwork/builder-cumulus:%s' % dotenv.STATEMINE_BUILD_BRANCH},
-	'bin/astar':{dockerImage:'uniquenetwork/builder-astar:%s' % dotenv.ASTAR_BUILD_BRANCH},
-	'bin/polkadex':{dockerImage:'uniquenetwork/builder-polkadex:%s' % dotenv.POLKADEX_BUILD_BRANCH},
-})(prev)
+  (import 'baedeker-library/ops/rewrites.libsonnet').rewriteNodePaths({
+    'bin/unique': '%s/target/release/unique-collator' % repoDir,
+    'bin/polkadot': { dockerImage: 'uniquenetwork/builder-polkadot:%s' % dotenv.POLKADOT_MAINNET_BRANCH },
+    'bin/acala': { dockerImage: 'uniquenetwork/builder-acala:%s' % dotenv.ACALA_BUILD_BRANCH },
+    'bin/moonbeam': { dockerImage: 'uniquenetwork/builder-moonbeam:%s' % dotenv.MOONBEAM_BUILD_BRANCH },
+    'bin/cumulus': { dockerImage: 'uniquenetwork/builder-cumulus:%s' % dotenv.STATEMINE_BUILD_BRANCH },
+    'bin/astar': { dockerImage: 'uniquenetwork/builder-astar:%s' % dotenv.ASTAR_BUILD_BRANCH },
+    'bin/polkadex': { dockerImage: 'uniquenetwork/builder-polkadex:%s' % dotenv.POLKADEX_BUILD_BRANCH },
+    'bin/hydradx': { dockerImage: 'uniquenetwork/builder-hydraDx:%s' % dotenv.HYDRADX_BUILD_BRANCH },
+  })(prev)
modified.baedeker/xcm-opal.jsonnetdiffbeforeafterboth
--- a/.baedeker/xcm-opal.jsonnet
+++ b/.baedeker/xcm-opal.jsonnet
@@ -19,6 +19,9 @@
 		[name]: {
 			bin: $.bin,
 			wantedKeys: 'relay',
+			extraArgs: [
+				"-lxcm=trace"
+			],
 		},
 		for name in ['alice', 'bob', 'charlie', 'dave', 'eve']
 	},
@@ -35,6 +38,9 @@
 		[name]: {
 			bin: $.bin,
 			wantedKeys: 'para',
+			extraArgs: [
+				"-lxcm=trace"
+			],
 		},
 		for name in ['alice', 'bob']
 	},
@@ -52,6 +58,9 @@
 		[name]: {
 			bin: $.bin,
 			wantedKeys: 'para',
+			extraArgs: [
+				"-lxcm=trace"
+			],
 		},
 		for name in ['alice', 'bob']
 	},
modified.baedeker/xcm-quartz.jsonnetdiffbeforeafterboth
--- a/.baedeker/xcm-quartz.jsonnet
+++ b/.baedeker/xcm-quartz.jsonnet
@@ -24,6 +24,9 @@
 		[name]: {
 			bin: $.bin,
 			wantedKeys: 'relay',
+			extraArgs: [
+				"-lxcm=trace"
+			],
 		},
 		for name in ['alice', 'bob', 'charlie', 'dave', 'eve', 'ferdie']
 	},
@@ -40,6 +43,9 @@
 		[name]: {
 			bin: $.bin,
 			wantedKeys: 'para',
+			extraArgs: [
+				"-lxcm=trace"
+			],
 		},
 		for name in ['alice', 'bob']
 	},
@@ -60,6 +66,9 @@
 		[name]: {
 			bin: $.bin,
 			wantedKeys: 'para',
+			extraArgs: [
+				"-lxcm=trace"
+			],
 		},
 		for name in ['alice', 'bob']
 	},
@@ -79,6 +88,9 @@
 		[name]: {
 			bin: $.bin,
 			wantedKeys: 'para-nimbus',
+			extraArgs: [
+				"-lxcm=trace"
+			],
 		},
 		for name in ['alith', 'baltathar']
 	},
@@ -96,6 +108,9 @@
 		[name]: {
 			bin: $.bin,
 			wantedKeys: 'para',
+			extraArgs: [
+				"-lxcm=trace"
+			],
 		},
 		for name in ['alice', 'bob']
 	},
@@ -113,6 +128,9 @@
 		[name]: {
 			bin: $.bin,
 			wantedKeys: 'para',
+			extraArgs: [
+				"-lxcm=trace"
+			],
 		},
 		for name in ['alice', 'bob']
 	},
modified.baedeker/xcm-unique.jsonnetdiffbeforeafterboth
--- a/.baedeker/xcm-unique.jsonnet
+++ b/.baedeker/xcm-unique.jsonnet
@@ -11,22 +11,25 @@
 	spec: {Genesis:{
 		chain: relay_spec,
 		modify:: m.genericRelay($, hrmp = std.join([], [
-			[[$.parachains[a].paraId, $.parachains[b].paraId, 8, 512], [$.parachains[b].paraId, $.parachains[a].paraId, 8, 512]],
-			for [a, b] in [
+			// [[$.parachains[a].paraId, $.parachains[b].paraId, 8, 512], [$.parachains[b].paraId, $.parachains[a].paraId, 8, 512]],
+			// for [a, b] in [
 				// ['unique', 'acala'],
 				// ['unique', 'moonbeam'],
 				// ['unique', 'statemint'],
 				// ['unique', 'astar'],
 				// ['unique', 'polkadex'],
-			]
+			// ]
 		])),
 	}},
 	nodes: {
 		[name]: {
 			bin: $.bin,
 			wantedKeys: 'relay',
+			extraArgs: [
+				"-lxcm=trace"
+			],
 		},
-		for name in ['alice', 'bob', 'charlie', 'dave', 'eve', 'ferdie', 'gregory']
+		for name in ['alice', 'bob', 'charlie', 'dave', 'eve', 'ferdie', 'gregory', 'holly']
 	},
 };
 
@@ -41,6 +44,9 @@
 		[name]: {
 			bin: $.bin,
 			wantedKeys: 'para',
+			extraArgs: [
+				"-lxcm=trace"
+			],
 		},
 		for name in ['alice', 'bob']
 	},
@@ -61,6 +67,9 @@
 		[name]: {
 			bin: $.bin,
 			wantedKeys: 'para',
+			extraArgs: [
+				"-lxcm=trace"
+			],
 		},
 		for name in ['alice', 'bob']
 	},
@@ -80,6 +89,9 @@
 		[name]: {
 			bin: $.bin,
 			wantedKeys: 'para-nimbus',
+			extraArgs: [
+				"-lxcm=trace"
+			],
 		},
 		for name in ['alith', 'baltathar']
 	},
@@ -97,6 +109,9 @@
 		[name]: {
 			bin: $.bin,
 			wantedKeys: 'para-ed',
+			extraArgs: [
+				"-lxcm=trace"
+			],
 		},
 		for name in ['alice', 'bob']
 	},
@@ -114,6 +129,9 @@
 		[name]: {
 			bin: $.bin,
 			wantedKeys: 'para',
+			extraArgs: [
+				"-lxcm=trace"
+			],
 		},
 		for name in ['alice', 'bob']
 	},
@@ -131,14 +149,39 @@
 		[name]: {
 			bin: $.bin,
 			wantedKeys: 'para',
+			extraArgs: [
+				"-lxcm=trace"
+			],
+		},
+		for name in ['alice', 'bob']
+	},
+};
+
+local hydraDx = {
+	name: 'hydraDx',
+	bin: 'bin/hydradx',
+	paraId: 1007,
+	spec: {Genesis:{
+		chain: 'local',
+		modify:: m.genericPara($),
+	}},
+	nodes: {
+		[name]: {
+			bin: $.bin,
+			wantedKeys: 'para',
+			legacyRpc: true,
+			extraArgs: [
+				"-lxcm=trace"
+			],
 		},
 		for name in ['alice', 'bob']
 	},
 };
 
+
 relay + {
 	parachains: {
 		[para.name]: para,
-		for para in [unique, acala, moonbeam, statemint, astar, polkadex]
+		for para in [unique, acala, moonbeam, statemint, astar, polkadex, hydraDx]
 	},
 }
added.docker/Dockerfile-hydradx.j2diffbeforeafterboth
--- /dev/null
+++ b/.docker/Dockerfile-hydradx.j2
@@ -0,0 +1,46 @@
+# ===== Rust builder =====
+FROM ubuntu:22.04 as rust-builder
+LABEL maintainer="Unique.Network"
+
+ENV CARGO_HOME="/cargo-home"
+ENV PATH="/cargo-home/bin:$PATH"
+ENV TZ=UTC
+RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
+
+RUN apt-get update && \
+    apt-get install -y curl cmake pkg-config libssl-dev git clang llvm libudev-dev protobuf-compiler && \
+    apt-get clean && \
+    rm -r /var/lib/apt/lists/*
+
+RUN curl https://sh.rustup.rs -sSf | sh -s -- -y --default-toolchain none
+
+RUN rustup toolchain install {{ RUST_TOOLCHAIN }} && \
+    rustup target add wasm32-unknown-unknown --toolchain {{ RUST_TOOLCHAIN }} && \
+    rustup default {{ RUST_TOOLCHAIN }} && \
+    rustup target list --installed && \
+    rustup show
+
+RUN mkdir /unique_parachain
+WORKDIR /unique_parachain
+
+# ===== BUILD ACALA =====
+FROM rust-builder as builder-hydradx-bin
+
+WORKDIR /unique_parachain
+
+RUN git clone --depth 1 -b {{ HYDRADX_BUILD_BRANCH }} https://github.com/galacticcouncil/HydraDX-node.git
+
+RUN --mount=type=cache,target=/cargo-home/registry \
+    --mount=type=cache,target=/cargo-home/git \
+    --mount=type=cache,target=/unique_parachain/parachain/target \
+    cd HydraDX-node && \
+    CARGO_INCREMENTAL=0 cargo build --release --locked && \
+    mkdir /unique_parachain/Hydradx && \
+    mv ./target/release/hydradx /unique_parachain/Hydradx/hydradx
+
+# ===== BIN ======
+
+FROM ubuntu:22.04 as builder-hydradx
+
+COPY --from=builder-hydradx-bin /unique_parachain/Hydradx/hydradx /bin/hydradx
+ENTRYPOINT ["/bin/hydradx"]
modified.envdiffbeforeafterboth
--- a/.env
+++ b/.env
@@ -12,7 +12,7 @@
 UNIQUE_MAINNET_BRANCH=release-v10010063
 UNIQUE_REPLICA_FROM=wss://ws.unique.network:443
 POLKADEX_BUILD_BRANCH=v1.1.0
-
+HYDRADX_BUILD_BRANCH=v20.1.1
 
 KUSAMA_MAINNET_BRANCH=release-v1.0.0
 STATEMINE_BUILD_BRANCH=release-parachains-v9430
modified.github/workflows/xcm.ymldiffbeforeafterboth
before · .github/workflows/xcm.yml
1name: xcm-testnet23# Controls when the action will run.4on:5  workflow_call:67  # Allows you to run this workflow manually from the Actions tab8  workflow_dispatch:910#Define Workflow variables11env:12  REPO_URL: ${{ github.server_url }}/${{ github.repository }}1314# A workflow run is made up of one or more jobs that can run sequentially or in parallel15jobs:16  prepare-execution-marix:17    name: Prepare execution matrix1819    runs-on: [self-hosted-ci]20    outputs:21      matrix: ${{ steps.create_matrix.outputs.matrix }}2223    steps:24      - name: Clean Workspace25        uses: AutoModality/action-clean@v1.1.02627      # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it28      - uses: actions/checkout@v3.1.029        with:30          ref: ${{ github.head_ref }} #Checking out head commit3132      - name: Read .env file33        uses: xom9ikk/dotenv@v23435      - name: Create Execution matrix36        uses: CertainLach/create-matrix-action@v437        id: create_matrix38        with:39          matrix: |40            network {opal}, relay_branch {${{ env.UNIQUEWEST_MAINNET_BRANCH }}}, acala_version {${{ env.ACALA_BUILD_BRANCH }}}, moonbeam_version {${{ env.MOONBEAM_BUILD_BRANCH }}}, cumulus_version {${{ env.WESTMINT_BUILD_BRANCH }}}, astar_version {${{ env.ASTAR_BUILD_BRANCH }}}, polkadex_version {${{ env.POLKADEX_BUILD_BRANCH }}}, runtest {testXcmOpal}, runtime_features {opal-runtime}41            network {quartz}, relay_branch {${{ env.KUSAMA_MAINNET_BRANCH }}}, acala_version {${{ env.KARURA_BUILD_BRANCH }}}, moonbeam_version {${{ env.MOONRIVER_BUILD_BRANCH }}}, cumulus_version {${{ env.STATEMINE_BUILD_BRANCH }}}, astar_version {${{ env.SHIDEN_BUILD_BRANCH }}}, polkadex_version {${{ env.POLKADEX_BUILD_BRANCH }}}, runtest {testFullXcmQuartz}, runtime_features {quartz-runtime}42            network {unique}, relay_branch {${{ env.POLKADOT_MAINNET_BRANCH }}}, acala_version {${{ env.ACALA_BUILD_BRANCH }}}, moonbeam_version {${{ env.MOONBEAM_BUILD_BRANCH }}}, cumulus_version {${{ env.STATEMINT_BUILD_BRANCH }}}, astar_version {${{ env.ASTAR_BUILD_BRANCH }}}, polkadex_version {${{ env.POLKADEX_BUILD_BRANCH }}}, runtest {testFullXcmUnique}, runtime_features {unique-runtime}4344  xcm:45    needs: prepare-execution-marix46    # The type of runner that the job will run on47    runs-on: [XL]4849    timeout-minutes: 6005051    name: ${{ matrix.network }}5253    continue-on-error: true #Do not stop testing of matrix runs failed.  As it decided during PR review - it required 50/50& Let's check it with false.5455    strategy:56      matrix:57        include: ${{fromJson(needs.prepare-execution-marix.outputs.matrix)}}5859    steps:60      - name: Skip if pull request is in Draft61        if: github.event.pull_request.draft == true62        run: exit 16364      - name: Clean Workspace65        uses: AutoModality/action-clean@v1.1.06667      # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it68      - uses: actions/checkout@v3.1.069        with:70          ref: ${{ github.head_ref }} #Checking out head commit7172      # Prepare SHA73      - name: Prepare SHA74        uses: ./.github/actions/prepare7576      - name: Read .env file77        uses: xom9ikk/dotenv@v27879      - name: Log in to Docker Hub80        uses: docker/login-action@v2.1.081        with:82          username: ${{ secrets.CORE_DOCKERHUB_USERNAME }}83          password: ${{ secrets.CORE_DOCKERHUB_TOKEN }}8485      # Check POLKADOT version and build it if it doesn't exist in repository86      - name: Generate ENV related extend Dockerfile file for POLKADOT87        uses: cuchi/jinja2-action@v1.2.088        with:89          template: .docker/Dockerfile-polkadot.j290          output_file: .docker/Dockerfile-polkadot.${{ matrix.relay_branch }}.yml91          variables: |92            RUST_TOOLCHAIN=${{ env.RUST_TOOLCHAIN }}93            POLKADOT_BUILD_BRANCH=${{ matrix.relay_branch }}9495      - name: Check if the dockerhub repository contains the needed version POLKADOT96        run: |97          # aquire token98            TOKEN=$(curl -s -H "Content-Type: application/json" -X POST -d '{"username": "'${{ secrets.CORE_DOCKERHUB_USERNAME }}'", "password": "'${{ secrets.CORE_DOCKERHUB_TOKEN }}'"}' https://hub.docker.com/v2/users/login/ | jq -r .token)99            export TOKEN=$TOKEN100101          # Get TAGS from DOCKERHUB POLKADOT repository102            POLKADOT_TAGS=$(curl -s -H "Authorization: JWT ${TOKEN}" https://hub.docker.com/v2/repositories/uniquenetwork/builder-polkadot/tags/?page_size=100 | jq -r '."results"[]["name"]')103          # Show TAGS104            echo "POLKADOT TAGS:"105            echo $POLKADOT_TAGS106          # Check correct version POLKADOT and build it if it doesn't exist in POLKADOT TAGS107            if [[ ${POLKADOT_TAGS[*]} =~ (^|[[:space:]])"${{ matrix.relay_branch }}"($|[[:space:]]) ]]; then108                echo "Repository has needed POLKADOT version";109                docker pull uniquenetwork/builder-polkadot:${{ matrix.relay_branch }}110            else111                echo "Repository has not needed POLKADOT version, so build it";112                cd .docker/ && docker build --file ./Dockerfile-polkadot.${{ matrix.relay_branch }}.yml --tag uniquenetwork/builder-polkadot:${{ matrix.relay_branch }} .113                echo "Push needed POLKADOT version to the repository";114                docker push uniquenetwork/builder-polkadot:${{ matrix.relay_branch }}115            fi116        shell: bash117118      # Check ACALA version and build it if it doesn't exist in repository119      - name: Generate ENV related extend Dockerfile file for ACALA120        uses: cuchi/jinja2-action@v1.2.0121        with:122          template: .docker/Dockerfile-acala.j2123          output_file: .docker/Dockerfile-acala.${{ matrix.acala_version }}.yml124          variables: |125            RUST_TOOLCHAIN=${{ env.RUST_TOOLCHAIN }}126            ACALA_BUILD_BRANCH=${{ matrix.acala_version }}127128      - name: Check if the dockerhub repository contains the needed ACALA version129        run: |130          # aquire token131            TOKEN=$(curl -s -H "Content-Type: application/json" -X POST -d '{"username": "'${{ secrets.CORE_DOCKERHUB_USERNAME }}'", "password": "'${{ secrets.CORE_DOCKERHUB_TOKEN }}'"}' https://hub.docker.com/v2/users/login/ | jq -r .token)132            export TOKEN=$TOKEN133134          # Get TAGS from DOCKERHUB repository135            ACALA_TAGS=$(curl -s -H "Authorization: JWT ${TOKEN}" https://hub.docker.com/v2/repositories/uniquenetwork/builder-acala/tags/?page_size=100 | jq -r '."results"[]["name"]')136          # Show TAGS137            echo "ACALA TAGS:"138            echo $ACALA_TAGS139          # Check correct version ACALA and build it if it doesn't exist in ACALA TAGS140            if [[ ${ACALA_TAGS[*]} =~ (^|[[:space:]])"${{ matrix.acala_version }}"($|[[:space:]]) ]]; then141                echo "Repository has needed ACALA version";142                docker pull uniquenetwork/builder-acala:${{ matrix.acala_version }}143            else144                echo "Repository has not needed ACALA version, so build it";145                cd .docker/ && docker build --file ./Dockerfile-acala.${{ matrix.acala_version }}.yml --tag uniquenetwork/builder-acala:${{ matrix.acala_version }} .146                echo "Push needed ACALA version to the repository";147                docker push uniquenetwork/builder-acala:${{ matrix.acala_version }}148            fi149        shell: bash150151      # Check MOONBEAM version and build it if it doesn't exist in repository152      - name: Generate ENV related extend Dockerfile file for MOONBEAM153        uses: cuchi/jinja2-action@v1.2.0154        with:155          template: .docker/Dockerfile-moonbeam.j2156          output_file: .docker/Dockerfile-moonbeam.${{ matrix.moonbeam_version }}.yml157          variables: |158            RUST_TOOLCHAIN=${{ env.RUST_TOOLCHAIN }}159            MOONBEAM_BUILD_BRANCH=${{ matrix.moonbeam_version }}160161      - name: Check if the dockerhub repository contains the needed MOONBEAM version162        run: |163          # aquire token164            TOKEN=$(curl -s -H "Content-Type: application/json" -X POST -d '{"username": "'${{ secrets.CORE_DOCKERHUB_USERNAME }}'", "password": "'${{ secrets.CORE_DOCKERHUB_TOKEN }}'"}' https://hub.docker.com/v2/users/login/ | jq -r .token)165            export TOKEN=$TOKEN166167          # Get TAGS from DOCKERHUB repository168            MOONBEAM_TAGS=$(curl -s -H "Authorization: JWT ${TOKEN}" https://hub.docker.com/v2/repositories/uniquenetwork/builder-moonbeam/tags/?page_size=100 | jq -r '."results"[]["name"]')169          # Show TAGS170            echo "MOONBEAM TAGS:"171            echo $MOONBEAM_TAGS172          # Check correct version MOONBEAM and build it if it doesn't exist in MOONBEAM TAGS173            if [[ ${MOONBEAM_TAGS[*]} =~ (^|[[:space:]])"${{ matrix.moonbeam_version }}"($|[[:space:]]) ]]; then174                echo "Repository has needed MOONBEAM version";175                docker pull uniquenetwork/builder-moonbeam:${{ matrix.moonbeam_version }}176            else177                echo "Repository has not needed MOONBEAM version, so build it";178                cd .docker/ && docker build --file ./Dockerfile-moonbeam.${{ matrix.moonbeam_version }}.yml --tag uniquenetwork/builder-moonbeam:${{ matrix.moonbeam_version }} .179                echo "Push needed MOONBEAM version to the repository";180                docker push uniquenetwork/builder-moonbeam:${{ matrix.moonbeam_version }}181            fi182        shell: bash183184      # Check CUMULUS version and build it if it doesn't exist in repository185      - name: Generate ENV related extend Dockerfile file for CUMULUS186        uses: cuchi/jinja2-action@v1.2.0187        with:188          template: .docker/Dockerfile-cumulus.j2189          output_file: .docker/Dockerfile-cumulus.${{ matrix.cumulus_version }}.yml190          variables: |191            RUST_TOOLCHAIN=${{ env.RUST_TOOLCHAIN }}192            CUMULUS_BUILD_BRANCH=${{ matrix.cumulus_version }}193194      - name: Check if the dockerhub repository contains the needed CUMULUS version195        run: |196          # aquire token197            TOKEN=$(curl -s -H "Content-Type: application/json" -X POST -d '{"username": "'${{ secrets.CORE_DOCKERHUB_USERNAME }}'", "password": "'${{ secrets.CORE_DOCKERHUB_TOKEN }}'"}' https://hub.docker.com/v2/users/login/ | jq -r .token)198            export TOKEN=$TOKEN199200          # Get TAGS from DOCKERHUB repository201            CUMULUS_TAGS=$(curl -s -H "Authorization: JWT ${TOKEN}" https://hub.docker.com/v2/repositories/uniquenetwork/builder-cumulus/tags/?page_size=100 | jq -r '."results"[]["name"]')202          # Show TAGS203            echo "CUMULUS TAGS:"204            echo $CUMULUS_TAGS205          # Check correct version CUMULUS and build it if it doesn't exist in CUMULUS TAGS206            if [[ ${CUMULUS_TAGS[*]} =~ (^|[[:space:]])"${{ matrix.cumulus_version }}"($|[[:space:]]) ]]; then207                echo "Repository has needed CUMULUS version";208                docker pull uniquenetwork/builder-cumulus:${{ matrix.cumulus_version }}209            else210                echo "Repository has not needed CUMULUS version, so build it";211                cd .docker/ && docker build --file ./Dockerfile-cumulus.${{ matrix.cumulus_version }}.yml --tag uniquenetwork/builder-cumulus:${{ matrix.cumulus_version }} .212                echo "Push needed CUMULUS version to the repository";213                docker push uniquenetwork/builder-cumulus:${{ matrix.cumulus_version }}214            fi215        shell: bash216217      # Check ASTAR version and build it if it doesn't exist in repository218      - name: Generate ENV related extend Dockerfile file for ASTAR219        uses: cuchi/jinja2-action@v1.2.0220        with:221          template: .docker/Dockerfile-astar.j2222          output_file: .docker/Dockerfile-astar.${{ matrix.astar_version }}.yml223          variables: |224            RUST_TOOLCHAIN=${{ env.RUST_TOOLCHAIN }}225            ASTAR_BUILD_BRANCH=${{ matrix.astar_version }}226227      - name: Check if the dockerhub repository contains the needed ASTAR version228        run: |229          # aquire token230            TOKEN=$(curl -s -H "Content-Type: application/json" -X POST -d '{"username": "'${{ secrets.CORE_DOCKERHUB_USERNAME }}'", "password": "'${{ secrets.CORE_DOCKERHUB_TOKEN }}'"}' https://hub.docker.com/v2/users/login/ | jq -r .token)231            export TOKEN=$TOKEN232233          # Get TAGS from DOCKERHUB repository234            ASTAR_TAGS=$(curl -s -H "Authorization: JWT ${TOKEN}" https://hub.docker.com/v2/repositories/uniquenetwork/builder-astar/tags/?page_size=100 | jq -r '."results"[]["name"]')235          # Show TAGS236            echo "ASTAR TAGS:"237            echo $ASTAR_TAGS238          # Check correct version ASTAR and build it if it doesn't exist in ASTAR TAGS239            if [[ ${ASTAR_TAGS[*]} =~ (^|[[:space:]])"${{ matrix.astar_version }}"($|[[:space:]]) ]]; then240                echo "Repository has needed ASTAR version";241                docker pull uniquenetwork/builder-astar:${{ matrix.astar_version }}242            else243                echo "Repository has not needed ASTAR version, so build it";244                cd .docker/ && docker build --file ./Dockerfile-astar.${{ matrix.astar_version }}.yml --tag uniquenetwork/builder-astar:${{ matrix.astar_version }} .245                echo "Push needed ASTAR version to the repository";246                docker push uniquenetwork/builder-astar:${{ matrix.astar_version }}247            fi248        shell: bash249250      # Check POLKADEX version and build it if it doesn't exist in repository251      - name: Generate ENV related extend Dockerfile file for POLKADEX252        uses: cuchi/jinja2-action@v1.2.0253        with:254          template: .docker/Dockerfile-polkadex.j2255          output_file: .docker/Dockerfile-polkadex.${{ matrix.polkadex_version }}.yml256          variables: |257            RUST_TOOLCHAIN=${{ env.RUST_TOOLCHAIN }}258            POLKADEX_BUILD_BRANCH=${{ matrix.polkadex_version }}259260      - name: Check if the dockerhub repository contains the needed POLKADEX version261        run: |262          # aquire token263            TOKEN=$(curl -s -H "Content-Type: application/json" -X POST -d '{"username": "'${{ secrets.CORE_DOCKERHUB_USERNAME }}'", "password": "'${{ secrets.CORE_DOCKERHUB_TOKEN }}'"}' https://hub.docker.com/v2/users/login/ | jq -r .token)264            export TOKEN=$TOKEN265266          # Get TAGS from DOCKERHUB repository267            POLKADEX_TAGS=$(curl -s -H "Authorization: JWT ${TOKEN}" https://hub.docker.com/v2/repositories/uniquenetwork/builder-polkadex/tags/?page_size=100 | jq -r '."results"[]["name"]')268          # Show TAGS269            echo "POLKADEX TAGS:"270            echo $POLKADEX_TAGS271          # Check correct version POLKADEX and build it if it doesn't exist in POLKADEX TAGS272            if [[ ${POLKADEX_TAGS[*]} =~ (^|[[:space:]])"${{ matrix.polkadex_version }}"($|[[:space:]]) ]]; then273                echo "Repository has needed POLKADEX version";274                docker pull uniquenetwork/builder-polkadex:${{ matrix.polkadex_version }}275            else276                echo "Repository has not needed POLKADEX version, so build it";277                cd .docker/ && docker build --file ./Dockerfile-polkadex.${{ matrix.polkadex_version }}.yml --tag uniquenetwork/builder-polkadex:${{ matrix.polkadex_version }} .278                echo "Push needed POLKADEX version to the repository";279                docker push uniquenetwork/builder-polkadex:${{ matrix.polkadex_version }}280            fi281        shell: bash282283      - name: Build unique-chain284        run: |285          docker build --file .docker/Dockerfile-unique \286            --build-arg RUNTIME_FEATURES=${{ matrix.runtime_features }} \287            --build-arg RUST_TOOLCHAIN=${{ env.RUST_TOOLCHAIN }} \288            --tag uniquenetwork/ci-xcm-local:${{ matrix.network }}-${{ env.REF_SLUG }}-${{ env.BUILD_SHA }} \289            .290291      - name: Push docker image version292        run: docker push uniquenetwork/ci-xcm-local:${{ matrix.network }}-${{ env.REF_SLUG }}-${{ env.BUILD_SHA }}293294      - uses: actions/setup-node@v3.5.1295        with:296          node-version: 18297298      - name: Install baedeker299        uses: UniqueNetwork/baedeker-action/setup@built300301      - name: Setup library302        run: mkdir -p .baedeker/vendor/ && git clone https://github.com/UniqueNetwork/baedeker-library .baedeker/vendor/baedeker-library303304      - name: Start network305        uses: UniqueNetwork/baedeker-action@built306        id: bdk307        with:308          jpath: |309            .baedeker/vendor310          tla-str: |311            relay_spec=${{ env.RELAY_CHAIN_TYPE }}-local312          inputs: |313            .baedeker/xcm-${{ matrix.network }}.jsonnet314            snippet:(import 'baedeker-library/ops/rewrites.libsonnet').rewriteNodePaths({'bin/polkadot':{dockerImage:'uniquenetwork/builder-polkadot:${{ matrix.relay_branch }}'}})315            snippet:(import 'baedeker-library/ops/rewrites.libsonnet').rewriteNodePaths({'bin/unique':{dockerImage:'uniquenetwork/ci-xcm-local:${{ matrix.network }}-${{ env.REF_SLUG }}-${{ env.BUILD_SHA }}'}})316            snippet:(import 'baedeker-library/ops/rewrites.libsonnet').rewriteNodePaths({'bin/acala':{dockerImage:'uniquenetwork/builder-acala:${{ matrix.acala_version }}'}})317            snippet:(import 'baedeker-library/ops/rewrites.libsonnet').rewriteNodePaths({'bin/moonbeam':{dockerImage:'uniquenetwork/builder-moonbeam:${{ matrix.moonbeam_version }}'}})318            snippet:(import 'baedeker-library/ops/rewrites.libsonnet').rewriteNodePaths({'bin/cumulus':{dockerImage:'uniquenetwork/builder-cumulus:${{ matrix.cumulus_version }}'}})319            snippet:(import 'baedeker-library/ops/rewrites.libsonnet').rewriteNodePaths({'bin/astar':{dockerImage:'uniquenetwork/builder-astar:${{ matrix.astar_version }}'}})320            snippet:(import 'baedeker-library/ops/rewrites.libsonnet').rewriteNodePaths({'bin/polkadex':{dockerImage:'uniquenetwork/builder-polkadex:${{ matrix.polkadex_version }}'}})321322      - name: Upload network config323        uses: actions/upload-artifact@v3324        with:325          name: ${{ matrix.network }}-network-config326          path: ${{ steps.bdk.outputs.composeProject }}327          retention-days: 2328329      - name: Yarn install330        working-directory: js-packages/tests331        run: |332          yarn install333          yarn add mochawesome334335      - name: Call HRMP initialization336        working-directory: js-packages/tests337        run: |338          yarn ts-node --esm util/createHrmp.ts ${{matrix.network}}339340      - name: Run XCM tests341        working-directory: js-packages/tests342        run: |343          # Wanted by both wait_for_first_block344          export RPC_URL="${RELAY_OPAL_HTTP_URL:-${RELAY_QUARTZ_HTTP_URL:-${RELAY_UNIQUE_HTTP_URL:-}}}"345          ../scripts/wait_for_first_block.sh346          echo "Ready to start tests"347          NOW=$(date +%s) && yarn ${{ matrix.runtest }} --reporter mochawesome --reporter-options reportFilename=test-${NOW}348349      - name: XCM Test Report350        uses: phoenix-actions/test-reporting@v10351        id: test-report352        if: success() || failure()353        with:354          name: XCM Tests ${{ matrix.network }}355          path: js-packages/tests/mochawesome-report/test-*.json356          reporter: mochawesome-json357          fail-on-error: 'false'358359      - name: Clean Workspace360        if: always()361        uses: AutoModality/action-clean@v1.1.0362363      - name: Remove builder cache364        if: always()365        run: |366          docker system prune -a -f
after · .github/workflows/xcm.yml
1name: xcm-testnet23# Controls when the action will run.4on:5  workflow_call:67  # Allows you to run this workflow manually from the Actions tab8  workflow_dispatch:910#Define Workflow variables11env:12  REPO_URL: ${{ github.server_url }}/${{ github.repository }}1314# A workflow run is made up of one or more jobs that can run sequentially or in parallel15jobs:16  prepare-execution-marix:17    name: Prepare execution matrix1819    runs-on: [self-hosted-ci]20    outputs:21      matrix: ${{ steps.create_matrix.outputs.matrix }}2223    steps:24      - name: Clean Workspace25        uses: AutoModality/action-clean@v1.1.02627      # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it28      - uses: actions/checkout@v3.1.029        with:30          ref: ${{ github.head_ref }} #Checking out head commit3132      - name: Read .env file33        uses: xom9ikk/dotenv@v23435      - name: Create Execution matrix36        uses: CertainLach/create-matrix-action@v437        id: create_matrix38        with:39          matrix: |40            network {opal}, relay_branch {${{ env.UNIQUEWEST_MAINNET_BRANCH }}}, acala_version {${{ env.ACALA_BUILD_BRANCH }}}, moonbeam_version {${{ env.MOONBEAM_BUILD_BRANCH }}}, cumulus_version {${{ env.WESTMINT_BUILD_BRANCH }}}, astar_version {${{ env.ASTAR_BUILD_BRANCH }}}, polkadex_version {${{ env.POLKADEX_BUILD_BRANCH }}}, hydradx_version {${{ env.HYDRADX_BUILD_BRANCH }}}, runtest {testXcmOpal}, runtime_features {opal-runtime}41            network {quartz}, relay_branch {${{ env.KUSAMA_MAINNET_BRANCH }}}, acala_version {${{ env.KARURA_BUILD_BRANCH }}}, moonbeam_version {${{ env.MOONRIVER_BUILD_BRANCH }}}, cumulus_version {${{ env.STATEMINE_BUILD_BRANCH }}}, astar_version {${{ env.SHIDEN_BUILD_BRANCH }}}, polkadex_version {${{ env.POLKADEX_BUILD_BRANCH }}}, hydradx_version {${{ env.HYDRADX_BUILD_BRANCH }}}, runtest {testFullXcmQuartz}, runtime_features {quartz-runtime}42            network {unique}, relay_branch {${{ env.POLKADOT_MAINNET_BRANCH }}}, acala_version {${{ env.ACALA_BUILD_BRANCH }}}, moonbeam_version {${{ env.MOONBEAM_BUILD_BRANCH }}}, cumulus_version {${{ env.STATEMINT_BUILD_BRANCH }}}, astar_version {${{ env.ASTAR_BUILD_BRANCH }}}, polkadex_version {${{ env.POLKADEX_BUILD_BRANCH }}}, hydradx_version {${{ env.HYDRADX_BUILD_BRANCH }}}, runtest {testFullXcmUnique}, runtime_features {unique-runtime}4344  xcm:45    needs: prepare-execution-marix46    # The type of runner that the job will run on47    runs-on: [XL]4849    timeout-minutes: 6005051    name: ${{ matrix.network }}5253    continue-on-error: true #Do not stop testing of matrix runs failed.  As it decided during PR review - it required 50/50& Let's check it with false.5455    strategy:56      matrix:57        include: ${{fromJson(needs.prepare-execution-marix.outputs.matrix)}}5859    steps:60      - name: Skip if pull request is in Draft61        if: github.event.pull_request.draft == true62        run: exit 16364      - name: Clean Workspace65        uses: AutoModality/action-clean@v1.1.06667      # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it68      - uses: actions/checkout@v3.1.069        with:70          ref: ${{ github.head_ref }} #Checking out head commit7172      # Prepare SHA73      - name: Prepare SHA74        uses: ./.github/actions/prepare7576      - name: Read .env file77        uses: xom9ikk/dotenv@v27879      - name: Log in to Docker Hub80        uses: docker/login-action@v2.1.081        with:82          username: ${{ secrets.CORE_DOCKERHUB_USERNAME }}83          password: ${{ secrets.CORE_DOCKERHUB_TOKEN }}8485      # Check POLKADOT version and build it if it doesn't exist in repository86      - name: Generate ENV related extend Dockerfile file for POLKADOT87        uses: cuchi/jinja2-action@v1.2.088        with:89          template: .docker/Dockerfile-polkadot.j290          output_file: .docker/Dockerfile-polkadot.${{ matrix.relay_branch }}.yml91          variables: |92            RUST_TOOLCHAIN=${{ env.RUST_TOOLCHAIN }}93            POLKADOT_BUILD_BRANCH=${{ matrix.relay_branch }}9495      - name: Check if the dockerhub repository contains the needed version POLKADOT96        run: |97          # aquire token98            TOKEN=$(curl -s -H "Content-Type: application/json" -X POST -d '{"username": "'${{ secrets.CORE_DOCKERHUB_USERNAME }}'", "password": "'${{ secrets.CORE_DOCKERHUB_TOKEN }}'"}' https://hub.docker.com/v2/users/login/ | jq -r .token)99            export TOKEN=$TOKEN100101          # Get TAGS from DOCKERHUB POLKADOT repository102            POLKADOT_TAGS=$(curl -s -H "Authorization: JWT ${TOKEN}" https://hub.docker.com/v2/repositories/uniquenetwork/builder-polkadot/tags/?page_size=100 | jq -r '."results"[]["name"]')103          # Show TAGS104            echo "POLKADOT TAGS:"105            echo $POLKADOT_TAGS106          # Check correct version POLKADOT and build it if it doesn't exist in POLKADOT TAGS107            if [[ ${POLKADOT_TAGS[*]} =~ (^|[[:space:]])"${{ matrix.relay_branch }}"($|[[:space:]]) ]]; then108                echo "Repository has needed POLKADOT version";109                docker pull uniquenetwork/builder-polkadot:${{ matrix.relay_branch }}110            else111                echo "Repository has not needed POLKADOT version, so build it";112                cd .docker/ && docker build --file ./Dockerfile-polkadot.${{ matrix.relay_branch }}.yml --tag uniquenetwork/builder-polkadot:${{ matrix.relay_branch }} .113                echo "Push needed POLKADOT version to the repository";114                docker push uniquenetwork/builder-polkadot:${{ matrix.relay_branch }}115            fi116        shell: bash117118      # Check ACALA version and build it if it doesn't exist in repository119      - name: Generate ENV related extend Dockerfile file for ACALA120        uses: cuchi/jinja2-action@v1.2.0121        with:122          template: .docker/Dockerfile-acala.j2123          output_file: .docker/Dockerfile-acala.${{ matrix.acala_version }}.yml124          variables: |125            RUST_TOOLCHAIN=${{ env.RUST_TOOLCHAIN }}126            ACALA_BUILD_BRANCH=${{ matrix.acala_version }}127128      - name: Check if the dockerhub repository contains the needed ACALA version129        run: |130          # aquire token131            TOKEN=$(curl -s -H "Content-Type: application/json" -X POST -d '{"username": "'${{ secrets.CORE_DOCKERHUB_USERNAME }}'", "password": "'${{ secrets.CORE_DOCKERHUB_TOKEN }}'"}' https://hub.docker.com/v2/users/login/ | jq -r .token)132            export TOKEN=$TOKEN133134          # Get TAGS from DOCKERHUB repository135            ACALA_TAGS=$(curl -s -H "Authorization: JWT ${TOKEN}" https://hub.docker.com/v2/repositories/uniquenetwork/builder-acala/tags/?page_size=100 | jq -r '."results"[]["name"]')136          # Show TAGS137            echo "ACALA TAGS:"138            echo $ACALA_TAGS139          # Check correct version ACALA and build it if it doesn't exist in ACALA TAGS140            if [[ ${ACALA_TAGS[*]} =~ (^|[[:space:]])"${{ matrix.acala_version }}"($|[[:space:]]) ]]; then141                echo "Repository has needed ACALA version";142                docker pull uniquenetwork/builder-acala:${{ matrix.acala_version }}143            else144                echo "Repository has not needed ACALA version, so build it";145                cd .docker/ && docker build --file ./Dockerfile-acala.${{ matrix.acala_version }}.yml --tag uniquenetwork/builder-acala:${{ matrix.acala_version }} .146                echo "Push needed ACALA version to the repository";147                docker push uniquenetwork/builder-acala:${{ matrix.acala_version }}148            fi149        shell: bash150151      # Check MOONBEAM version and build it if it doesn't exist in repository152      - name: Generate ENV related extend Dockerfile file for MOONBEAM153        uses: cuchi/jinja2-action@v1.2.0154        with:155          template: .docker/Dockerfile-moonbeam.j2156          output_file: .docker/Dockerfile-moonbeam.${{ matrix.moonbeam_version }}.yml157          variables: |158            RUST_TOOLCHAIN=${{ env.RUST_TOOLCHAIN }}159            MOONBEAM_BUILD_BRANCH=${{ matrix.moonbeam_version }}160161      - name: Check if the dockerhub repository contains the needed MOONBEAM version162        run: |163          # aquire token164            TOKEN=$(curl -s -H "Content-Type: application/json" -X POST -d '{"username": "'${{ secrets.CORE_DOCKERHUB_USERNAME }}'", "password": "'${{ secrets.CORE_DOCKERHUB_TOKEN }}'"}' https://hub.docker.com/v2/users/login/ | jq -r .token)165            export TOKEN=$TOKEN166167          # Get TAGS from DOCKERHUB repository168            MOONBEAM_TAGS=$(curl -s -H "Authorization: JWT ${TOKEN}" https://hub.docker.com/v2/repositories/uniquenetwork/builder-moonbeam/tags/?page_size=100 | jq -r '."results"[]["name"]')169          # Show TAGS170            echo "MOONBEAM TAGS:"171            echo $MOONBEAM_TAGS172          # Check correct version MOONBEAM and build it if it doesn't exist in MOONBEAM TAGS173            if [[ ${MOONBEAM_TAGS[*]} =~ (^|[[:space:]])"${{ matrix.moonbeam_version }}"($|[[:space:]]) ]]; then174                echo "Repository has needed MOONBEAM version";175                docker pull uniquenetwork/builder-moonbeam:${{ matrix.moonbeam_version }}176            else177                echo "Repository has not needed MOONBEAM version, so build it";178                cd .docker/ && docker build --file ./Dockerfile-moonbeam.${{ matrix.moonbeam_version }}.yml --tag uniquenetwork/builder-moonbeam:${{ matrix.moonbeam_version }} .179                echo "Push needed MOONBEAM version to the repository";180                docker push uniquenetwork/builder-moonbeam:${{ matrix.moonbeam_version }}181            fi182        shell: bash183184      # Check CUMULUS version and build it if it doesn't exist in repository185      - name: Generate ENV related extend Dockerfile file for CUMULUS186        uses: cuchi/jinja2-action@v1.2.0187        with:188          template: .docker/Dockerfile-cumulus.j2189          output_file: .docker/Dockerfile-cumulus.${{ matrix.cumulus_version }}.yml190          variables: |191            RUST_TOOLCHAIN=${{ env.RUST_TOOLCHAIN }}192            CUMULUS_BUILD_BRANCH=${{ matrix.cumulus_version }}193194      - name: Check if the dockerhub repository contains the needed CUMULUS version195        run: |196          # aquire token197            TOKEN=$(curl -s -H "Content-Type: application/json" -X POST -d '{"username": "'${{ secrets.CORE_DOCKERHUB_USERNAME }}'", "password": "'${{ secrets.CORE_DOCKERHUB_TOKEN }}'"}' https://hub.docker.com/v2/users/login/ | jq -r .token)198            export TOKEN=$TOKEN199200          # Get TAGS from DOCKERHUB repository201            CUMULUS_TAGS=$(curl -s -H "Authorization: JWT ${TOKEN}" https://hub.docker.com/v2/repositories/uniquenetwork/builder-cumulus/tags/?page_size=100 | jq -r '."results"[]["name"]')202          # Show TAGS203            echo "CUMULUS TAGS:"204            echo $CUMULUS_TAGS205          # Check correct version CUMULUS and build it if it doesn't exist in CUMULUS TAGS206            if [[ ${CUMULUS_TAGS[*]} =~ (^|[[:space:]])"${{ matrix.cumulus_version }}"($|[[:space:]]) ]]; then207                echo "Repository has needed CUMULUS version";208                docker pull uniquenetwork/builder-cumulus:${{ matrix.cumulus_version }}209            else210                echo "Repository has not needed CUMULUS version, so build it";211                cd .docker/ && docker build --file ./Dockerfile-cumulus.${{ matrix.cumulus_version }}.yml --tag uniquenetwork/builder-cumulus:${{ matrix.cumulus_version }} .212                echo "Push needed CUMULUS version to the repository";213                docker push uniquenetwork/builder-cumulus:${{ matrix.cumulus_version }}214            fi215        shell: bash216217      # Check ASTAR version and build it if it doesn't exist in repository218      - name: Generate ENV related extend Dockerfile file for ASTAR219        uses: cuchi/jinja2-action@v1.2.0220        with:221          template: .docker/Dockerfile-astar.j2222          output_file: .docker/Dockerfile-astar.${{ matrix.astar_version }}.yml223          variables: |224            RUST_TOOLCHAIN=${{ env.RUST_TOOLCHAIN }}225            ASTAR_BUILD_BRANCH=${{ matrix.astar_version }}226227      - name: Check if the dockerhub repository contains the needed ASTAR version228        run: |229          # aquire token230            TOKEN=$(curl -s -H "Content-Type: application/json" -X POST -d '{"username": "'${{ secrets.CORE_DOCKERHUB_USERNAME }}'", "password": "'${{ secrets.CORE_DOCKERHUB_TOKEN }}'"}' https://hub.docker.com/v2/users/login/ | jq -r .token)231            export TOKEN=$TOKEN232233          # Get TAGS from DOCKERHUB repository234            ASTAR_TAGS=$(curl -s -H "Authorization: JWT ${TOKEN}" https://hub.docker.com/v2/repositories/uniquenetwork/builder-astar/tags/?page_size=100 | jq -r '."results"[]["name"]')235          # Show TAGS236            echo "ASTAR TAGS:"237            echo $ASTAR_TAGS238          # Check correct version ASTAR and build it if it doesn't exist in ASTAR TAGS239            if [[ ${ASTAR_TAGS[*]} =~ (^|[[:space:]])"${{ matrix.astar_version }}"($|[[:space:]]) ]]; then240                echo "Repository has needed ASTAR version";241                docker pull uniquenetwork/builder-astar:${{ matrix.astar_version }}242            else243                echo "Repository has not needed ASTAR version, so build it";244                cd .docker/ && docker build --file ./Dockerfile-astar.${{ matrix.astar_version }}.yml --tag uniquenetwork/builder-astar:${{ matrix.astar_version }} .245                echo "Push needed ASTAR version to the repository";246                docker push uniquenetwork/builder-astar:${{ matrix.astar_version }}247            fi248        shell: bash249250      # Check POLKADEX version and build it if it doesn't exist in repository251      - name: Generate ENV related extend Dockerfile file for POLKADEX252        uses: cuchi/jinja2-action@v1.2.0253        with:254          template: .docker/Dockerfile-polkadex.j2255          output_file: .docker/Dockerfile-polkadex.${{ matrix.polkadex_version }}.yml256          variables: |257            RUST_TOOLCHAIN=${{ env.RUST_TOOLCHAIN }}258            POLKADEX_BUILD_BRANCH=${{ matrix.polkadex_version }}259260      - name: Check if the dockerhub repository contains the needed POLKADEX version261        run: |262          # aquire token263            TOKEN=$(curl -s -H "Content-Type: application/json" -X POST -d '{"username": "'${{ secrets.CORE_DOCKERHUB_USERNAME }}'", "password": "'${{ secrets.CORE_DOCKERHUB_TOKEN }}'"}' https://hub.docker.com/v2/users/login/ | jq -r .token)264            export TOKEN=$TOKEN265266          # Get TAGS from DOCKERHUB repository267            POLKADEX_TAGS=$(curl -s -H "Authorization: JWT ${TOKEN}" https://hub.docker.com/v2/repositories/uniquenetwork/builder-polkadex/tags/?page_size=100 | jq -r '."results"[]["name"]')268          # Show TAGS269            echo "POLKADEX TAGS:"270            echo $POLKADEX_TAGS271          # Check correct version POLKADEX and build it if it doesn't exist in POLKADEX TAGS272            if [[ ${POLKADEX_TAGS[*]} =~ (^|[[:space:]])"${{ matrix.polkadex_version }}"($|[[:space:]]) ]]; then273                echo "Repository has needed POLKADEX version";274                docker pull uniquenetwork/builder-polkadex:${{ matrix.polkadex_version }}275            else276                echo "Repository has not needed POLKADEX version, so build it";277                cd .docker/ && docker build --file ./Dockerfile-polkadex.${{ matrix.polkadex_version }}.yml --tag uniquenetwork/builder-polkadex:${{ matrix.polkadex_version }} .278                echo "Push needed POLKADEX version to the repository";279                docker push uniquenetwork/builder-polkadex:${{ matrix.polkadex_version }}280            fi281        shell: bash282283      # Check Hydradx version and build it if it doesn't exist in repository284      - name: Generate ENV related extend Dockerfile file for Hydradx285        uses: cuchi/jinja2-action@v1.2.0286        with:287          template: .docker/Dockerfile-hydradx.j2288          output_file: .docker/Dockerfile-hydradx.${{ matrix.hydradx_version }}.yml289          variables: |290            RUST_TOOLCHAIN=${{ env.RUST_TOOLCHAIN }}291            HYDRADX_BUILD_BRANCH=${{ matrix.hydradx_version }}292293      - name: Check if the dockerhub repository contains the needed HYDRADX version294        run: |295          # aquire token296            TOKEN=$(curl -s -H "Content-Type: application/json" -X POST -d '{"username": "'${{ secrets.CORE_DOCKERHUB_USERNAME }}'", "password": "'${{ secrets.CORE_DOCKERHUB_TOKEN }}'"}' https://hub.docker.com/v2/users/login/ | jq -r .token)297            export TOKEN=$TOKEN298299          # Get TAGS from DOCKERHUB repository300            HYDRADX_TAGS=$(curl -s -H "Authorization: JWT ${TOKEN}" https://hub.docker.com/v2/repositories/uniquenetwork/builder-hydradx/tags/?page_size=100 | jq -r '."results"[]["name"]')301          # Show TAGS302            echo "HYDRADX TAGS:"303            echo $HYDRADX_TAGS304          # Check correct version HYDRADX and build it if it doesn't exist in HYDRADX TAGS305            if [[ ${HYDRADX_TAGS[*]} =~ (^|[[:space:]])"${{ matrix.hydradx_version }}"($|[[:space:]]) ]]; then306                echo "Repository has needed HYDRADX version";307                docker pull uniquenetwork/builder-hydradx:${{ matrix.hydradx_version }}308            else309                echo "Repository has not needed HYDRADX version, so build it";310                cd .docker/ && docker build --file ./Dockerfile-hydradx.${{ matrix.hydradx_version }}.yml --tag uniquenetwork/builder-hydradx:${{ matrix.hydradx_version }} .311                echo "Push needed HYDRADX version to the repository";312                docker push uniquenetwork/builder-hydradx:${{ matrix.hydradx_version }}313            fi314        shell: bash315316317      - name: Build unique-chain318        run: |319          docker build --file .docker/Dockerfile-unique \320            --build-arg RUNTIME_FEATURES=${{ matrix.runtime_features }} \321            --build-arg RUST_TOOLCHAIN=${{ env.RUST_TOOLCHAIN }} \322            --tag uniquenetwork/ci-xcm-local:${{ matrix.network }}-${{ env.REF_SLUG }}-${{ env.BUILD_SHA }} \323            .324325      - name: Push docker image version326        run: docker push uniquenetwork/ci-xcm-local:${{ matrix.network }}-${{ env.REF_SLUG }}-${{ env.BUILD_SHA }}327328      - uses: actions/setup-node@v3.5.1329        with:330          node-version: 18331332      - name: Install baedeker333        uses: UniqueNetwork/baedeker-action/setup@built334335      - name: Setup library336        run: mkdir -p .baedeker/vendor/ && git clone https://github.com/UniqueNetwork/baedeker-library .baedeker/vendor/baedeker-library337338      - name: Start network339        uses: UniqueNetwork/baedeker-action@built340        id: bdk341        with:342          jpath: |343            .baedeker/vendor344          tla-str: |345            relay_spec=${{ env.RELAY_CHAIN_TYPE }}-local346          inputs: |347            .baedeker/xcm-${{ matrix.network }}.jsonnet348            snippet:(import 'baedeker-library/ops/rewrites.libsonnet').rewriteNodePaths({'bin/polkadot':{dockerImage:'uniquenetwork/builder-polkadot:${{ matrix.relay_branch }}'}})349            snippet:(import 'baedeker-library/ops/rewrites.libsonnet').rewriteNodePaths({'bin/unique':{dockerImage:'uniquenetwork/ci-xcm-local:${{ matrix.network }}-${{ env.REF_SLUG }}-${{ env.BUILD_SHA }}'}})350            snippet:(import 'baedeker-library/ops/rewrites.libsonnet').rewriteNodePaths({'bin/acala':{dockerImage:'uniquenetwork/builder-acala:${{ matrix.acala_version }}'}})351            snippet:(import 'baedeker-library/ops/rewrites.libsonnet').rewriteNodePaths({'bin/moonbeam':{dockerImage:'uniquenetwork/builder-moonbeam:${{ matrix.moonbeam_version }}'}})352            snippet:(import 'baedeker-library/ops/rewrites.libsonnet').rewriteNodePaths({'bin/cumulus':{dockerImage:'uniquenetwork/builder-cumulus:${{ matrix.cumulus_version }}'}})353            snippet:(import 'baedeker-library/ops/rewrites.libsonnet').rewriteNodePaths({'bin/astar':{dockerImage:'uniquenetwork/builder-astar:${{ matrix.astar_version }}'}})354            snippet:(import 'baedeker-library/ops/rewrites.libsonnet').rewriteNodePaths({'bin/polkadex':{dockerImage:'uniquenetwork/builder-polkadex:${{ matrix.polkadex_version }}'}})355            snippet:(import 'baedeker-library/ops/rewrites.libsonnet').rewriteNodePaths({'bin/hydradx':{dockerImage:'uniquenetwork/builder-hydradx:${{ matrix.hydradx_version }}'}})356357      - name: Upload network config358        uses: actions/upload-artifact@v3359        with:360          name: ${{ matrix.network }}-network-config361          path: ${{ steps.bdk.outputs.composeProject }}362          retention-days: 2363364      - name: Yarn install365        working-directory: js-packages/tests366        run: |367          yarn install368          yarn add mochawesome369370      - name: Call HRMP initialization371        working-directory: js-packages/tests372        run: |373          yarn ts-node --esm util/createHrmp.ts ${{matrix.network}}374375      - name: Run XCM tests376        working-directory: js-packages/tests377        run: |378          # Wanted by both wait_for_first_block379          export RPC_URL="${RELAY_OPAL_HTTP_URL:-${RELAY_QUARTZ_HTTP_URL:-${RELAY_UNIQUE_HTTP_URL:-}}}"380          ../scripts/wait_for_first_block.sh381          echo "Ready to start tests"382          NOW=$(date +%s) && yarn ${{ matrix.runtest }} --reporter mochawesome --reporter-options reportFilename=test-${NOW}383384      - name: XCM Test Report385        uses: phoenix-actions/test-reporting@v10386        id: test-report387        if: success() || failure()388        with:389          name: XCM Tests ${{ matrix.network }}390          path: js-packages/tests/mochawesome-report/test-*.json391          reporter: mochawesome-json392          fail-on-error: 'false'393394      - name: Clean Workspace395        if: always()396        uses: AutoModality/action-clean@v1.1.0397398      - name: Remove builder cache399        if: always()400        run: |401          docker system prune -a -f
modified.vscode/settings.jsondiffbeforeafterboth
--- a/.vscode/settings.json
+++ b/.vscode/settings.json
@@ -10,5 +10,5 @@
 		"SKIP_WASM_BUILD": "1"
 	},
 	"rust-analyzer.cargo.features": ["runtime-benchmarks", "try-runtime"],
-	"solidity.packageDefaultDependenciesDirectory": "tests/node_modules"
+	"solidity.packageDefaultDependenciesDirectory": "js-packages/node_modules"
 }
modifiedjs-packages/.vscode/settings.jsondiffbeforeafterboth
--- a/js-packages/.vscode/settings.json
+++ b/js-packages/.vscode/settings.json
@@ -3,7 +3,7 @@
 		"RUN_GOV_TESTS": "1",
 		"RUN_XCM_TESTS": "1"
 	},
-	"mochaExplorer.files": "src/**/*.test.ts",
+	"mochaExplorer.files": "tests/**/*.test.ts",
 	"mochaExplorer.require": "ts-node/register",
 	"eslint.format.enable": true,
 	"[javascript]": {
modifiedjs-packages/playgrounds/unique.dev.tsdiffbeforeafterboth
--- a/js-packages/playgrounds/unique.dev.ts
+++ b/js-packages/playgrounds/unique.dev.ts
@@ -17,7 +17,7 @@
 import type {FrameSystemEventRecord, StagingXcmV2TraitsError, StagingXcmV3TraitsOutcome} from '@polkadot/types/lookup';
 import type {SignerOptions, VoidFn} from '@polkadot/api/types';
 import {spawnSync} from 'child_process';
-import {AcalaHelper, AstarHelper, MoonbeamHelper, PolkadexHelper, RelayHelper, WestmintHelper, ForeignAssetsGroup, XcmGroup, XTokensGroup, TokensGroup} from './unique.xcm.js';
+import {AcalaHelper, AstarHelper, MoonbeamHelper, PolkadexHelper, RelayHelper, WestmintHelper, ForeignAssetsGroup, XcmGroup, XTokensGroup, TokensGroup, HydraDxHelper} from './unique.xcm.js';
 import {CollectiveGroup, CollectiveMembershipGroup, DemocracyGroup, RankedCollectiveGroup, ReferendaGroup} from './unique.governance.js';
 import type {ICollectiveGroup, IFellowshipGroup} from './unique.governance.js';
 
@@ -667,6 +667,20 @@
   }
 }
 
+export class DevHydraDxHelper extends HydraDxHelper {
+  wait: WaitGroup;
+  fastDemocracy: HydraFastDemocracyGroup;
+
+  constructor(logger: { log: (msg: any, level: any) => void, level: any }, options: {[key: string]: any} = {}) {
+    options.helperBase = options.helperBase ?? DevHydraDxHelper;
+
+    super(logger, options);
+
+    this.wait = new WaitGroup(this);
+    this.fastDemocracy = new HydraFastDemocracyGroup(this);
+  }
+}
+
 export class DevKaruraHelper extends DevAcalaHelper {}
 
 export class ArrangeGroup {
@@ -1150,6 +1164,91 @@
   }
 }
 
+class HydraFastDemocracyGroup {
+  helper: DevHydraDxHelper;
+
+  constructor(helper: DevHydraDxHelper) {
+    this.helper = helper;
+  }
+
+  async executeProposal(proposalDesciption: string, encodedProposal: string) {
+    const proposalHash = blake2AsHex(encodedProposal);
+    const aliceAccount = this.helper.util.fromSeed('//Alice');
+    const bobAccount = this.helper.util.fromSeed('//Bob');
+    const eveAccount = this.helper.util.fromSeed('//Eve');
+
+    const councilVotingThreshold = 1;
+    const technicalCommitteeThreshold = 3;
+    const fastTrackVotingPeriod = 3;
+    const fastTrackDelayPeriod = 0;
+
+    console.log(`[democracy] executing '${proposalDesciption}' proposal`);
+
+    // >>> Propose external motion through council >>>
+    console.log('\t* Propose external motion through council.......');
+    const externalMotion = this.helper.democracy.externalProposeMajority({Inline: encodedProposal});
+    const encodedMotion = externalMotion?.method.toHex() || '';
+    const motionHash = blake2AsHex(encodedMotion);
+    console.log('\t* Motion hash is %s', motionHash);
+
+    await this.helper.collective.council.propose(
+      aliceAccount,
+      councilVotingThreshold,
+      externalMotion,
+      externalMotion.encodedLength,
+    );
+
+    console.log('\t* Propose external motion through council.......DONE');
+    // <<< Propose external motion through council <<<
+
+    // >>> Fast track proposal through technical committee >>>
+    console.log('\t* Fast track proposal through technical committee.......');
+    const fastTrack = this.helper.democracy.fastTrack(proposalHash, fastTrackVotingPeriod, fastTrackDelayPeriod);
+    const encodedFastTrack = fastTrack?.method.toHex() || '';
+    const fastTrackHash = blake2AsHex(encodedFastTrack);
+    console.log('\t* FastTrack hash is %s', fastTrackHash);
+
+    await this.helper.collective.techCommittee.propose(aliceAccount, technicalCommitteeThreshold, fastTrack, fastTrack.encodedLength);
+
+    const techProposalIdx = await this.helper.collective.techCommittee.proposalCount() - 1;
+    await this.helper.collective.techCommittee.vote(aliceAccount, fastTrackHash, techProposalIdx, true);
+    await this.helper.collective.techCommittee.vote(bobAccount, fastTrackHash, techProposalIdx, true);
+    await this.helper.collective.techCommittee.vote(eveAccount, fastTrackHash, techProposalIdx, true);
+
+    await this.helper.collective.techCommittee.close(
+      bobAccount,
+      fastTrackHash,
+      techProposalIdx,
+      {
+        refTime: 1_000_000_000,
+        proofSize: 1_000_000,
+      },
+      fastTrack.encodedLength,
+    );
+    console.log('\t* Fast track proposal through technical committee.......DONE');
+    // <<< Fast track proposal through technical committee <<<
+
+    const democracyStarted = await this.helper.wait.expectEvent(3, Event.Democracy.Started);
+    const referendumIndex = democracyStarted.referendumIndex;
+
+    // >>> Referendum voting >>>
+    console.log(`\t* Referendum #${referendumIndex} voting.......`);
+    await this.helper.democracy.referendumVote(eveAccount, referendumIndex, {
+      balance: 10_000_000_000_000_000_000n,
+      vote: {aye: true, conviction: 1},
+    });
+    console.log(`\t* Referendum #${referendumIndex} voting.......DONE`);
+    // <<< Referendum voting <<<
+
+    // Wait the proposal to pass
+    await this.helper.wait.expectEvent(3, Event.Democracy.Passed, event => event.referendumIndex == referendumIndex);
+
+    await this.helper.wait.newBlocks(1);
+
+    console.log(`[democracy] executing '${proposalDesciption}' proposal.......DONE`);
+  }
+}
+
 class WaitGroup {
   helper: ChainHelperBase;
 
modifiedjs-packages/playgrounds/unique.xcm.tsdiffbeforeafterboth
--- a/js-packages/playgrounds/unique.xcm.ts
+++ b/js-packages/playgrounds/unique.xcm.ts
@@ -71,6 +71,31 @@
   }
 }
 
+class DemocracyGroup<T extends ChainHelperBase> extends HelperGroup<T> {
+  notePreimagePallet: string;
+
+  constructor(helper: T, options: { [key: string]: any } = {}) {
+    super(helper);
+    this.notePreimagePallet = options.notePreimagePallet;
+  }
+
+  async notePreimage(signer: TSigner, encodedProposal: string) {
+    await this.helper.executeExtrinsic(signer, `api.tx.${this.notePreimagePallet}.notePreimage`, [encodedProposal], true);
+  }
+
+  externalProposeMajority(proposal: any) {
+    return this.helper.constructApiCall('api.tx.democracy.externalProposeMajority', [proposal]);
+  }
+
+  fastTrack(proposalHash: string, votingPeriod: number, delayPeriod: number) {
+    return this.helper.constructApiCall('api.tx.democracy.fastTrack', [proposalHash, votingPeriod, delayPeriod]);
+  }
+
+  async referendumVote(signer: TSigner, referendumIndex: number, accountVote: DemocracyStandardAccountVote) {
+    await this.helper.executeExtrinsic(signer, 'api.tx.democracy.vote', [referendumIndex, {Standard: accountVote}], true);
+  }
+}
+
 class MoonbeamCollectiveGroup extends HelperGroup<MoonbeamHelper> {
   collective: string;
 
@@ -97,6 +122,31 @@
   }
 }
 
+class CollectiveGroup<T extends ChainHelperBase> extends HelperGroup<T> {
+  collective: string;
+
+  constructor(helper: T, palletName: string) {
+    super(helper);
+
+    this.collective = palletName;
+  }
+
+  async propose(signer: TSigner, threshold: number, proposalHash: string, lengthBound: number) {
+    await this.helper.executeExtrinsic(signer, `api.tx.${this.collective}.propose`, [threshold, proposalHash, lengthBound], true);
+  }
+
+  async vote(signer: TSigner, proposalHash: string, proposalIndex: number, approve: boolean) {
+    await this.helper.executeExtrinsic(signer, `api.tx.${this.collective}.vote`, [proposalHash, proposalIndex, approve], true);
+  }
+
+  async close(signer: TSigner, proposalHash: string, proposalIndex: number, weightBound: any, lengthBound: number) {
+    await this.helper.executeExtrinsic(signer, `api.tx.${this.collective}.close`, [proposalHash, proposalIndex, weightBound, lengthBound], true);
+  }
+
+  async proposalCount() {
+    return Number(await this.helper.callRpc(`api.query.${this.collective}.proposalCount`, []));
+  }
+}
 class PolkadexXcmHelperGroup<T extends ChainHelperBase> extends HelperGroup<T> {
   async whitelistToken(signer: TSigner, assetId: any) {
     await this.helper.executeExtrinsic(signer, 'api.tx.xcmHelper.whitelistToken', [assetId], true);
@@ -372,3 +422,28 @@
   }
 }
 
+export class HydraDxHelper extends XcmChainHelper {
+  balance: SubstrateBalanceGroup<HydraDxHelper>;
+  xcm: XcmGroup<HydraDxHelper>;
+  xTokens: XTokensGroup<HydraDxHelper>;
+  democracy: DemocracyGroup<HydraDxHelper>;
+  collective: {
+    council: CollectiveGroup<HydraDxHelper>,
+    techCommittee: CollectiveGroup<HydraDxHelper>,
+  };
+
+  constructor(logger?: ILogger, options: { [key: string]: any } = {}) {
+    super(logger, options.helperBase ?? HydraDxHelper);
+    options.notePreimagePallet = options.notePreimagePallet ?? 'preimage';
+
+    this.balance = new SubstrateBalanceGroup(this);
+    this.xcm = new XcmGroup(this, 'polkadotXcm');
+    this.xTokens = new XTokensGroup(this);
+    this.democracy = new DemocracyGroup(this, options);
+    this.collective = {
+      council: new CollectiveGroup(this, 'council'),
+      techCommittee: new CollectiveGroup(this, 'technicalCommittee'),
+    };
+  }
+}
+
modifiedjs-packages/tests/config.tsdiffbeforeafterboth
--- a/js-packages/tests/config.ts
+++ b/js-packages/tests/config.ts
@@ -29,6 +29,7 @@
   statemineUrl: process.env.RELAY_STATEMINE_URL || 'ws://127.0.0.1:9948',
   statemintUrl: process.env.RELAY_STATEMINT_URL || 'ws://127.0.0.1:9948',
   polkadexUrl: process.env.RELAY_POLKADEX_URL || 'ws://127.0.0.1:9950',
+  hydraDxUrl: process.env.RELAY_HYDRADX_URL || 'ws://127.0.0.1:9951',
 };
 
 export default config;
modifiedjs-packages/tests/util/createHrmp.tsdiffbeforeafterboth
--- a/js-packages/tests/util/createHrmp.ts
+++ b/js-packages/tests/util/createHrmp.ts
@@ -27,6 +27,7 @@
       await bidirOpen(1001, 1004);
       await bidirOpen(1001, 1005);
       await bidirOpen(1001, 1006);
+      await bidirOpen(1001, 1007);
       break;
     default:
       throw new Error(`unknown hrmp config profile: ${profile}`);
modifiedjs-packages/tests/util/index.tsdiffbeforeafterboth
--- a/js-packages/tests/util/index.ts
+++ b/js-packages/tests/util/index.ts
@@ -11,7 +11,7 @@
 import config from '../config.js';
 import {ChainHelperBase} from '@unique/playgrounds/unique.js';
 import type {ILogger} from '@unique/playgrounds/types.js';
-import {DevUniqueHelper, SilentLogger, SilentConsole, DevMoonbeamHelper, DevMoonriverHelper, DevAcalaHelper, DevKaruraHelper, DevRelayHelper, DevWestmintHelper, DevStatemineHelper, DevStatemintHelper, DevAstarHelper, DevShidenHelper, DevPolkadexHelper} from '@unique/playgrounds/unique.dev.js';
+import {DevUniqueHelper, SilentLogger, SilentConsole, DevMoonbeamHelper, DevMoonriverHelper, DevAcalaHelper, DevKaruraHelper, DevRelayHelper, DevWestmintHelper, DevStatemineHelper, DevStatemintHelper, DevAstarHelper, DevShidenHelper, DevPolkadexHelper, DevHydraDxHelper} from '@unique/playgrounds/unique.dev.js';
 import {dirname} from 'path';
 import {fileURLToPath} from 'url';
 
@@ -91,6 +91,8 @@
 
 export const usingPolkadexPlaygrounds = (url: string, code: (helper: DevPolkadexHelper, privateKey: (seed: string) => Promise<IKeyringPair>) => Promise<void>) => usingPlaygroundsGeneral<DevPolkadexHelper>(DevPolkadexHelper, url, code);
 
+export const usingHydraDxPlaygrounds = (url: string, code: (helper: DevHydraDxHelper, privateKey: (seed: string) => Promise<IKeyringPair>) => Promise<void>) => usingPlaygroundsGeneral<DevHydraDxHelper>(DevHydraDxHelper, url, code);
+
 export const MINIMUM_DONOR_FUND = 4_000_000n;
 export const DONOR_FUNDING = 4_000_000n;
 
modifiedjs-packages/tests/xcm/lowLevelXcmUnique.test.tsdiffbeforeafterboth
--- a/js-packages/tests/xcm/lowLevelXcmUnique.test.ts
+++ b/js-packages/tests/xcm/lowLevelXcmUnique.test.ts
@@ -16,10 +16,10 @@
 
 import type {IKeyringPair} from '@polkadot/types/types';
 import config from '../config.js';
-import {itSub, describeXCM, usingPlaygrounds, usingAcalaPlaygrounds, usingMoonbeamPlaygrounds, usingAstarPlaygrounds, usingPolkadexPlaygrounds, usingRelayPlaygrounds} from '../util/index.js';
+import {itSub, describeXCM, usingPlaygrounds, usingAcalaPlaygrounds, usingMoonbeamPlaygrounds, usingAstarPlaygrounds, usingPolkadexPlaygrounds, usingHydraDxPlaygrounds} from '../util/index.js';
 import {nToBigInt} from '@polkadot/util';
 import {hexToString} from '@polkadot/util';
-import {ASTAR_DECIMALS, SAFE_XCM_VERSION, SENDER_BUDGET, UNIQUE_CHAIN, UNQ_DECIMALS, XcmTestHelper, acalaUrl, astarUrl,  moonbeamUrl, polkadexUrl, relayUrl, uniqueAssetId} from './xcm.types.js';
+import {ASTAR_DECIMALS, SAFE_XCM_VERSION, SENDER_BUDGET, UNIQUE_CHAIN, UNQ_DECIMALS, XcmTestHelper, acalaUrl, astarUrl,  hydraDxUrl,  moonbeamUrl, polkadexUrl, uniqueAssetId} from './xcm.types.js';
 
 const testHelper = new XcmTestHelper('unique');
 
@@ -364,3 +364,40 @@
     await testHelper.rejectReserveTransferUNQfrom('astar', alice);
   });
 });
+
+describeXCM('[XCMLL] Integration test: Exchanging tokens with HydraDx', () => {
+  let alice: IKeyringPair;
+  let randomAccount: IKeyringPair;
+
+  before(async () => {
+    await usingPlaygrounds(async (helper, privateKey) => {
+      alice = await privateKey('//Alice');
+      console.log(config.acalaUrl);
+      randomAccount = helper.arrange.createEmptyAccount();
+
+      // Set the default version to wrap the first message to other chains.
+      await helper.getSudo().xcm.setSafeXcmVersion(alice, SAFE_XCM_VERSION);
+      await helper.balance.transferToSubstrate(alice, randomAccount.address, SENDER_BUDGET);
+    });
+
+    await usingHydraDxPlaygrounds(hydraDxUrl, async (helper) => {
+      await helper.balance.transferToSubstrate(alice, randomAccount.address, 10000000000000n);
+    });
+  });
+
+  itSub('Should connect and send UNQ to HydraDx', async () => {
+    await testHelper.sendUnqTo('hydraDx', randomAccount);
+  });
+
+  itSub('Should connect to HydraDx and send UNQ back', async () => {
+    await testHelper.sendUnqBack('hydraDx', alice, randomAccount);
+  });
+
+  itSub('HydraDx can send only up to its balance', async () => {
+    await testHelper.sendOnlyOwnedBalance('hydraDx', alice);
+  });
+
+  itSub('Should not accept reserve transfer of UNQ from HydraDx', async () => {
+    await testHelper.rejectReserveTransferUNQfrom('hydraDx', alice);
+  });
+});
\ No newline at end of file
modifiedjs-packages/tests/xcm/xcm.types.tsdiffbeforeafterboth
--- a/js-packages/tests/xcm/xcm.types.ts
+++ b/js-packages/tests/xcm/xcm.types.ts
@@ -1,6 +1,6 @@
 import type {IKeyringPair} from '@polkadot/types/types';
 import {hexToString} from '@polkadot/util';
-import {expect, usingAcalaPlaygrounds, usingAstarPlaygrounds, usingKaruraPlaygrounds, usingMoonbeamPlaygrounds, usingMoonriverPlaygrounds, usingPlaygrounds, usingPolkadexPlaygrounds, usingRelayPlaygrounds, usingShidenPlaygrounds} from '../util/index.js';
+import {expect, usingAcalaPlaygrounds, usingAstarPlaygrounds, usingHydraDxPlaygrounds, usingKaruraPlaygrounds, usingMoonbeamPlaygrounds, usingMoonriverPlaygrounds, usingPlaygrounds, usingPolkadexPlaygrounds, usingRelayPlaygrounds, usingShidenPlaygrounds} from '../util/index.js';
 import {DevUniqueHelper, Event} from '@unique/playgrounds/unique.dev.js';
 import config from '../config.js';
 
@@ -10,6 +10,7 @@
 export const MOONBEAM_CHAIN = +(process.env.RELAY_MOONBEAM_ID || 2004);
 export const ASTAR_CHAIN = +(process.env.RELAY_ASTAR_ID || 2006);
 export const POLKADEX_CHAIN = +(process.env.RELAY_POLKADEX_ID || 2040);
+export const HYDRADX_CHAIN = +(process.env.RELAY_HYDRADX_ID || 2034);
 
 export const QUARTZ_CHAIN = +(process.env.RELAY_QUARTZ_ID || 2095);
 export const STATEMINE_CHAIN = +(process.env.RELAY_STATEMINE_ID || 1000);
@@ -25,6 +26,7 @@
 export const moonbeamUrl = config.moonbeamUrl;
 export const astarUrl = config.astarUrl;
 export const polkadexUrl = config.polkadexUrl;
+export const hydraDxUrl = config.hydraDxUrl;
 
 export const karuraUrl = config.karuraUrl;
 export const moonriverUrl = config.moonriverUrl;
@@ -87,6 +89,7 @@
   moonriver: usingMoonriverPlaygrounds,
   karura: usingKaruraPlaygrounds,
   shiden: usingShidenPlaygrounds,
+  hydraDx: usingHydraDxPlaygrounds,
 } as const;
 type NetworkNames = keyof typeof NETWORKS;
 
@@ -108,6 +111,8 @@
       return KARURA_CHAIN;
     case 'shiden':
       return SHIDEN_CHAIN;
+    case 'hydraDx':
+      return HYDRADX_CHAIN;
   }
 }
 
@@ -127,6 +132,8 @@
       return karuraUrl;
     case 'shiden':
       return shidenUrl;
+    case 'hydraDx':
+      return hydraDxUrl;
   }
 }
 
@@ -277,7 +284,7 @@
         since the hash is being checked to ensure
         it matches what was sent.
       */
-        if(networkName == 'polkadex') {
+        if(networkName == 'polkadex' || networkName =='hydraDx') {
           await helper.wait.expectEvent(maxWaitBlocks, Event.XcmpQueue.Fail, event => event.messageHash == messageSent.messageHash);
         } else {
           await helper.wait.expectEvent(maxWaitBlocks, Event.XcmpQueue.Success, event => event.messageHash == messageSent.messageHash);