var v = Object.defineProperty;
var S = (i, e, t) => e in i ? v(i, e, { enumerable: !0, configurable: !0, writable: !0, value: t }) : i[e] = t;
var a = (i, e, t) => S(i, typeof e != "symbol" ? e + "" : e, t);
import { cM as f, cN as I, a5 as x, r as p, cO as b, a8 as w, c7 as U, c8 as E, c9 as m, u as o, cP as k, s as c, p as h, cQ as F, ce as _, Z as $, cb as C, m as T, bM as l, cR as R, bR as N } from "./index-CjwA7HmM.mjs";
import { A as O } from "./aptos-DoqExVYR.mjs";
class Q {
  constructor(e, t, s, r, n = !1) {
    a(this, "transaction");
    a(this, "network");
    a(this, "chain");
    a(this, "description");
    a(this, "parallelizable");
    this.transaction = e, this.network = t, this.chain = s, this.description = r, this.parallelizable = n;
  }
}
const W = [
  { name: "tokenBridgeAddress", ...f },
  { name: "chain", ...I() },
  {
    name: "domainSeparator",
    binary: "bytes",
    custom: x.encode(p),
    omit: !0
  },
  { name: "tokenId", ...f },
  // from https://github.com/aptos-labs/aptos-core/blob/25696fd266498d81d346fe86e01c330705a71465/aptos-move/framework/aptos-framework/sources/account.move#L90-L95
  { name: "domainSeparator", binary: "bytes", custom: new Uint8Array([255]), omit: !0 }
], P = (i) => b(W, i);
class d {
  constructor(e, t, s, r) {
    a(this, "network");
    a(this, "chain");
    a(this, "connection");
    a(this, "contracts");
    a(this, "chainId");
    a(this, "tokenBridgeAddress");
    this.network = e, this.chain = t, this.connection = s, this.contracts = r, this.chainId = w(t);
    const n = r.tokenBridge;
    if (!n)
      throw new Error(`TokenBridge contract Address for chain ${t} not found`);
    this.tokenBridgeAddress = n;
  }
  static async fromRpc(e, t) {
    const [s, r] = await O.chainFromRpc(e), n = t[r];
    if (n.network !== s)
      throw new Error("Network mismatch " + n.network + " !== " + s);
    return new d(s, r, e, n.contracts);
  }
  async isWrappedAsset(e) {
    try {
      return await this.getOriginalAsset(e), !0;
    } catch {
      return !1;
    }
  }
  async getOriginalAsset(e) {
    const t = e.toString().split(p);
    let s;
    if (s = (await this.connection.getAccountResource(t[0], `${this.tokenBridgeAddress}::state::OriginInfo`)).data, !s)
      throw U;
    const r = E(parseInt(s.token_chain.number)), n = new m(s.token_address.external_address);
    return { chain: r, address: n };
  }
  async getTokenUniversalAddress(e) {
    return new m(o.encode(k(e.toString()), !0));
  }
  async getTokenNativeAddress(e, t) {
    const s = e === this.chain ? await this.getTypeFromExternalAddress(t.toString()) : await this.getAssetFullyQualifiedType({ chain: e, address: t });
    if (!s)
      throw new Error("Invalid asset address.");
    return new c(s);
  }
  async hasWrappedAsset(e) {
    try {
      return await this.getWrappedAsset(e), !0;
    } catch {
    }
    return !1;
  }
  async getWrappedAsset(e) {
    if (h(e.address))
      throw new Error("native asset cannot be a wrapped asset");
    const t = await this.getAssetFullyQualifiedType(e);
    if (!t)
      throw new Error("Invalid asset address.");
    return await this.connection.getAccountResource(F(t), `${this.tokenBridgeAddress}::state::OriginInfo`), _(this.chain, t);
  }
  async isTransferCompleted(e) {
    const s = (await this.connection.getAccountResource(this.tokenBridgeAddress, `${this.tokenBridgeAddress}::state::State`)).data.consumed_vaas.elems.handle;
    try {
      return await this.connection.getTableItem(s, {
        key_type: "vector<u8>",
        value_type: "u8",
        key: `0x${$.Buffer.from(C(e.hash)).toString("hex")}`
      }), !0;
    } catch {
      return !1;
    }
  }
  async getWrappedNative() {
    return _(this.chain, T);
  }
  async *createAttestation(e, t) {
    const s = { chain: this.chain, address: new c(e) }, r = await this.getAssetFullyQualifiedType(s);
    if (!r)
      throw new Error("Invalid asset address.");
    yield this.createUnsignedTx({
      function: `${this.tokenBridgeAddress}::attest_token::attest_token_entry`,
      type_arguments: [r],
      arguments: []
    }, "Aptos.AttestToken");
  }
  async *submitAttestation(e, t) {
    yield this.createUnsignedTx({
      function: `${this.tokenBridgeAddress}::wrapped::create_wrapped_coin_type`,
      type_arguments: [],
      arguments: [l(e)]
    }, "Aptos.CreateWrappedCoinType");
    const s = await this.getAssetFullyQualifiedType(e.payload.token);
    if (!s)
      throw new Error("Invalid asset address.");
    yield this.createUnsignedTx({
      function: `${this.tokenBridgeAddress}::wrapped::create_wrapped_coin`,
      type_arguments: [s],
      arguments: [l(e)]
    }, "Aptos.CreateWrappedCoin");
  }
  async *transfer(e, t, s, r, n) {
    const B = 0n, u = 0n, y = h(s) ? T : s.toString(), g = t.address.toUniversalAddress().toUint8Array(), A = w(t.chain);
    n ? yield this.createUnsignedTx({
      function: `${this.tokenBridgeAddress}::transfer_tokens::transfer_tokens_with_payload_entry`,
      type_arguments: [y],
      arguments: [r, A, g, u, n]
    }, "Aptos.TransferTokensWithPayload") : yield this.createUnsignedTx({
      function: `${this.tokenBridgeAddress}::transfer_tokens::transfer_tokens_entry`,
      type_arguments: [y],
      arguments: [r, A, g, B, u]
    }, "Aptos.TransferTokens");
  }
  async *redeem(e, t, s = !0) {
    const r = t.payload.token.chain === this.chain ? await this.getTypeFromExternalAddress(t.payload.token.address.toString()) : await this.getAssetFullyQualifiedType(t.payload.token);
    if (!r)
      throw new Error("Invalid asset address.");
    yield this.createUnsignedTx({
      function: `${this.tokenBridgeAddress}::complete_transfer::submit_vaa_and_register_entry`,
      type_arguments: [r],
      arguments: [l(t)]
    }, "Aptos.CompleteTransfer");
  }
  async getAssetFullyQualifiedType(e) {
    return e.chain === this.chain ? R(e.address.toString()) ? e.address.toString() : null : `${d.getForeignAssetAddress(this.chain, this.tokenBridgeAddress, e)}::coin::T`;
  }
  /**
   * Given a hash, returns the fully qualified type by querying the corresponding TypeInfo.
   * @param address Hash of fully qualified type
   * @returns The fully qualified type associated with the given hash
   */
  async getTypeFromExternalAddress(e) {
    try {
      const t = (await this.connection.getAccountResource(this.tokenBridgeAddress, `${this.tokenBridgeAddress}::state::State`)).data, { handle: s } = t.native_infos, r = await this.connection.getTableItem(s, {
        key_type: `${this.tokenBridgeAddress}::token_hash::TokenHash`,
        value_type: "0x1::type_info::TypeInfo",
        key: { hash: e }
      });
      return r ? [
        r.account_address,
        String.fromCharCode(...o.decode(r.module_name)),
        String.fromCharCode(...o.decode(r.struct_name))
      ].join(p) : null;
    } catch {
      return null;
    }
  }
  /**
   * Derive the module address for an asset defined by the given origin chain and address.
   * @param tokenBridgeAddress Address of token bridge (32 bytes)
   * @param originChain Chain ID of chain that original asset is from
   * @param originAddress Native address of asset
   * @returns The module address for the given asset
   */
  static getForeignAssetAddress(e, t, s) {
    if (h(s.address))
      throw new Error("Invalid token address");
    const r = P({
      chain: s.chain,
      tokenBridgeAddress: new c(t).toUniversalAddress(),
      tokenId: s.address.toUniversalAddress()
    });
    return o.encode(k(r), !0);
  }
  createUnsignedTx(e, t, s = !1) {
    return new Q(e, this.network, this.chain, t, s);
  }
}
N("Aptos", "TokenBridge", d);
export {
  d as AptosTokenBridge
};
