var v = Object.defineProperty;
var S = (a, e, t) => e in a ? v(a, e, { enumerable: !0, configurable: !0, writable: !0, value: t }) : a[e] = t;
var i = (a, e, t) => S(a, typeof e != "symbol" ? e + "" : e, t);
import { aN as I, aJ as f, aL as x, $, aP as m, d9 as U, aB as E, _ as w, a3 as o, cv as k, j as c, a7 as T, d as F, aO as C, L as h } from "./address-BkeBsCZD.mjs";
import { b as A, A as u, c as b, a as _, i as N } from "./address-xvE59bSC.mjs";
import { A as O } from "./platform-BVScq6Cn.mjs";
import { A as W } from "./unsignedTransaction-BDOQhqcZ.mjs";
import { r as Q } from "./chain-uXEmLNMk.mjs";
const R = [
  { name: "tokenBridgeAddress", ...f },
  { name: "chain", ...x() },
  {
    name: "domainSeparator",
    binary: "bytes",
    custom: $.encode(A),
    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 = (a) => I(R, a);
class d {
  constructor(e, t, s, r) {
    i(this, "network");
    i(this, "chain");
    i(this, "connection");
    i(this, "contracts");
    i(this, "chainId");
    i(this, "tokenBridgeAddress");
    this.network = e, this.chain = t, this.connection = s, this.contracts = r, this.chainId = m(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(A), s = await this.connection.getAccountResource({
      accountAddress: t[0],
      resourceType: `${this.tokenBridgeAddress}::state::OriginInfo`
    });
    if (!s)
      throw U(e.toString());
    const r = E(parseInt(s.token_chain.number)), n = new w(s.token_address.external_address);
    return { chain: r, address: n };
  }
  async getTokenUniversalAddress(e) {
    return new w(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 u(s);
  }
  async hasWrappedAsset(e) {
    try {
      return await this.getWrappedAsset(e), !0;
    } catch {
    }
    return !1;
  }
  async getWrappedAsset(e) {
    if (c(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({
      accountAddress: b(t),
      resourceType: `${this.tokenBridgeAddress}::state::OriginInfo`
    }), T(this.chain, t);
  }
  async isTransferCompleted(e) {
    const s = (await this.connection.getAccountResource({
      accountAddress: this.tokenBridgeAddress,
      resourceType: `${this.tokenBridgeAddress}::state::State`
    })).consumed_vaas.elems.handle;
    try {
      return await this.connection.getTableItem({
        handle: s,
        data: {
          key_type: "vector<u8>",
          value_type: "u8",
          key: `0x${F.Buffer.from(C(e.hash)).toString("hex")}`
        }
      }), !0;
    } catch {
      return !1;
    }
  }
  async getWrappedNative() {
    return T(this.chain, _);
  }
  async *createAttestation(e, t) {
    const s = { chain: this.chain, address: new u(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`,
      typeArguments: [r],
      functionArguments: []
    }, "Aptos.AttestToken");
  }
  async *submitAttestation(e, t) {
    yield this.createUnsignedTx({
      function: `${this.tokenBridgeAddress}::wrapped::create_wrapped_coin_type`,
      typeArguments: [],
      functionArguments: [h(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`,
      typeArguments: [s],
      functionArguments: [h(e)]
    }, "Aptos.CreateWrappedCoin");
  }
  async *transfer(e, t, s, r, n) {
    const B = 0n, p = 0n, y = c(s) ? _ : s.toString(), g = t.address.toUniversalAddress().toUint8Array(), l = m(t.chain);
    n ? yield this.createUnsignedTx({
      function: `${this.tokenBridgeAddress}::transfer_tokens::transfer_tokens_with_payload_entry`,
      typeArguments: [y],
      functionArguments: [r, l, g, p, n]
    }, "Aptos.TransferTokensWithPayload") : yield this.createUnsignedTx({
      function: `${this.tokenBridgeAddress}::transfer_tokens::transfer_tokens_entry`,
      typeArguments: [y],
      functionArguments: [r, l, g, B, p]
    }, "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`,
      typeArguments: [r],
      functionArguments: [h(t)]
    }, "Aptos.CompleteTransfer");
  }
  async getAssetFullyQualifiedType(e) {
    return e.chain === this.chain ? N(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({
        accountAddress: this.tokenBridgeAddress,
        resourceType: `${this.tokenBridgeAddress}::state::State`
      }), { handle: s } = t.native_infos, r = await this.connection.getTableItem({
        handle: s,
        data: {
          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(A) : 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 (c(s.address))
      throw new Error("Invalid token address");
    const r = P({
      chain: s.chain,
      tokenBridgeAddress: new u(t).toUniversalAddress(),
      tokenId: s.address.toUniversalAddress()
    });
    return o.encode(k(r), !0);
  }
  createUnsignedTx(e, t, s = !1) {
    return new W(e, this.network, this.chain, t, s);
  }
}
Q("Aptos", "TokenBridge", d);
export {
  d as AptosTokenBridge
};
