import { aj as S, aI as g, ax as v, an as I, ah as f, di as w, L as x, ai as m, m as i, cc as T, i as d, t as k, C as U, ap as $, at as c, au as C } from "./platform-Cil_UtAQ.mjs";
import { e as u, A as h, f as E, d as _, i as F } from "./address-rVHWlcKQ.mjs";
import { T as b } from "./chunk-KJH4KKG6-Brt4fyqz.mjs";
import { A as W } from "./platform-vRQufc6j.mjs";
import { A as N } from "./unsignedTransaction-BJi-f5xi.mjs";
const O = [
  { name: "tokenBridgeAddress", ...g },
  { name: "chain", ...v() },
  {
    name: "domainSeparator",
    binary: "bytes",
    custom: I.encode(u),
    omit: !0
  },
  { name: "tokenId", ...g },
  // 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 }
], Q = (B) => S(O, B);
class o {
  network;
  chain;
  connection;
  contracts;
  chainId;
  tokenBridgeAddress;
  constructor(e, t, s, r) {
    this.network = e, this.chain = t, this.connection = s, this.contracts = r, this.chainId = f(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 W.chainFromRpc(e), n = t[r];
    if (n.network !== s)
      throw new Error("Network mismatch " + n.network + " !== " + s);
    return new o(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(u);
    let s = null;
    try {
      s = await this.connection.getAccountResource({
        accountAddress: t[0],
        resourceType: `${this.tokenBridgeAddress}::state::OriginInfo`
      });
    } catch (a) {
      throw a instanceof b && a.data?.error_code === "resource_not_found" ? w(e.toString()) : a;
    }
    if (!s)
      throw w(e.toString());
    const r = x(parseInt(s.token_chain.number)), n = new m(s.token_address.external_address);
    return { chain: r, address: n };
  }
  async getTokenUniversalAddress(e) {
    return new m(i.encode(T(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 h(s);
  }
  async hasWrappedAsset(e) {
    try {
      return await this.getWrappedAsset(e), !0;
    } catch {
    }
    return !1;
  }
  async getWrappedAsset(e) {
    if (d(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: E(t),
      resourceType: `${this.tokenBridgeAddress}::state::OriginInfo`
    }), k(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${U.from($(e.hash)).toString("hex")}`
        }
      }), !0;
    } catch {
      return !1;
    }
  }
  async getWrappedNative() {
    return k(this.chain, _);
  }
  async *createAttestation(e, t) {
    const s = { chain: this.chain, address: new h(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: [c(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: [c(e)]
    }, "Aptos.CreateWrappedCoin");
  }
  async *transfer(e, t, s, r, n) {
    const a = 0n, p = 0n, A = d(s) ? _ : s.toString(), y = t.address.toUniversalAddress().toUint8Array(), l = f(t.chain);
    n ? yield this.createUnsignedTx({
      function: `${this.tokenBridgeAddress}::transfer_tokens::transfer_tokens_with_payload_entry`,
      typeArguments: [A],
      functionArguments: [r, l, y, p, n]
    }, "Aptos.TransferTokensWithPayload") : yield this.createUnsignedTx({
      function: `${this.tokenBridgeAddress}::transfer_tokens::transfer_tokens_entry`,
      typeArguments: [A],
      functionArguments: [r, l, y, a, 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: [c(t)]
    }, "Aptos.CompleteTransfer");
  }
  async getAssetFullyQualifiedType(e) {
    return e.chain === this.chain ? F(e.address.toString()) ? e.address.toString() : null : `${o.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(...i.decode(r.module_name)),
        String.fromCharCode(...i.decode(r.struct_name))
      ].join(u) : 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 (d(s.address))
      throw new Error("Invalid token address");
    const r = Q({
      chain: s.chain,
      tokenBridgeAddress: new h(t).toUniversalAddress(),
      tokenId: s.address.toUniversalAddress()
    });
    return i.encode(T(r), !0);
  }
  createUnsignedTx(e, t, s = !1) {
    return new N(e, this.network, this.chain, t, s);
  }
}
C("Aptos", "TokenBridge", o);
export {
  o as AptosTokenBridge
};
