import { Binary, createClient } from 'polkadot-api';
import { createWsClient } from 'polkadot-api/ws';
import { consumeDmp, attachSibling, attachRelay } from '../xcm.js';
import { getParams, respond, errorResponse } from './rpc_utils.js';
import { logger } from '../logger.js';

const log = logger.child({ module: "forklift_xcm" });
const forklift_xcm_attach_relay = async (con, req, { chain, xcm, provider }) => {
  try {
    const { url } = getParams(req, ["url"]);
    const relayClient = createWsClient(url);
    const parachainClient = createClient(provider);
    await Promise.race([
      await attachRelay(relayClient, parachainClient, chain, xcm),
      new Promise(
        (_, rej) => setTimeout(() => rej(new Error("Timed out")), 1e4)
      )
    ]);
    con.send(respond(req, null));
  } catch (ex) {
    log.error(ex, "attach_relay failed");
    con.send(
      errorResponse(req, {
        code: -1,
        message: ex.message
      })
    );
  }
};
const forklift_xcm_attach_sibling = async (con, req, { chain, xcm, provider }) => {
  try {
    const { url } = getParams(req, ["url"]);
    const siblingClient = createWsClient(url);
    const selfClient = createClient(provider);
    await Promise.race([
      attachSibling(siblingClient, selfClient, chain, xcm),
      new Promise(
        (_, rej) => setTimeout(() => rej(new Error("Timed out")), 1e4)
      )
    ]);
    con.send(respond(req, null));
  } catch (ex) {
    log.error(ex, "attach_sibling failed");
    con.send(
      errorResponse(req, {
        code: -1,
        message: ex.message
      })
    );
  }
};
const forklift_xcm_consume_dmp = async (con, req, { chain }) => {
  const { hash, paraId } = getParams(req, ["hash", "paraId"]);
  try {
    await consumeDmp(chain, hash, paraId);
    con.send(respond(req, null));
  } catch (ex) {
    log.error(ex, "consume_dmp failed");
    con.send(
      errorResponse(req, {
        code: -1,
        message: ex.message
      })
    );
  }
};
const forklift_xcm_push_hrmp = async (con, req, { xcm }) => {
  const { senderId, messages } = getParams(req, ["senderId", "messages"]);
  try {
    xcm.pushHrmp(senderId, messages.map(Binary.fromHex));
    con.send(respond(req, null));
  } catch (ex) {
    log.error(ex, "push_hrmp failed");
    con.send(errorResponse(req, { code: -1, message: ex.message }));
  }
};
const forklift_xcm_open_hrmp_channel = async (con, req, { chain }) => {
  const { recipientId } = getParams(req, ["recipientId"]);
  chain.openHrmpChannel(recipientId);
  con.send(respond(req, null));
};
const forklift_xcm_push_ump = async (con, req, { xcm }) => {
  const { paraId, messages } = getParams(req, ["paraId", "messages"]);
  try {
    xcm.pushUmp(paraId, messages.map(Binary.fromHex));
    con.send(respond(req, null));
  } catch (ex) {
    log.error(ex, "push_ump failed");
    con.send(
      errorResponse(req, {
        code: -1,
        message: ex.message
      })
    );
  }
};

export { forklift_xcm_attach_relay, forklift_xcm_attach_sibling, forklift_xcm_consume_dmp, forklift_xcm_open_hrmp_channel, forklift_xcm_push_hrmp, forklift_xcm_push_ump };
//# sourceMappingURL=forklift_xcm.js.map
