// src/modules/wrappers/Base.ts
var BaseWrapper = class {
  config;
  value;
  constructor(value, config = {}) {
    this.config = config;
    this.value = value;
  }
  /** Returns the provider result exposed by this provider. */
  get provider() {
    return this.config.provider;
  }
  /** Returns the create result exposed by this provider. */
  static async create(value, config = {}) {
    const valueErrors = await this.validateValue(value);
    if (valueErrors.length > 0) {
      throw new Error(`Invalid value for ${this.constructor.name}: ${String(value)}`);
    }
    const configErrors = await this.validateConfig(config);
    if (configErrors.length > 0) {
      throw new Error(`Invalid config for ${this.constructor.name}: ${JSON.stringify(config)}`);
    }
    return Reflect.construct(this, [value, config]);
  }
  /** Validates config and returns the validation result. */
  static validateConfig(_config) {
    return [];
  }
  /** Validates value and returns the validation result. */
  static validateValue(_value) {
    return [];
  }
  /** Validates  and returns the validation result. */
  validate() {
    return [];
  }
};

// src/modules/wrappers/chain/chain.ts
var ChainWrapper = class extends BaseWrapper {
  /** Returns the id result exposed by this provider. */
  get id() {
    return this.value;
  }
};

// src/modules/wrappers/Fees.ts
import { hexToBigInt } from "@ariestools/sdk";
import { AttoXL1 } from "@xyo-network/xl1-protocol/protocol-lib";
function parseHexOrBigInt(value) {
  return AttoXL1(typeof value === "bigint" ? value : hexToBigInt(value));
}
var FeesWrapper = class _FeesWrapper {
  /** base configuration or state exposed by this contract. */
  base;
  /** gas Limit configuration or state exposed by this contract. */
  gasLimit;
  /** gas Price configuration or state exposed by this contract. */
  gasPrice;
  /** priority configuration or state exposed by this contract. */
  priority;
  /** Creates an instance with the supplied configuration. */
  constructor({
    base,
    gasLimit,
    gasPrice,
    priority
  }) {
    this.base = parseHexOrBigInt(base);
    this.gasLimit = parseHexOrBigInt(gasLimit);
    this.gasPrice = parseHexOrBigInt(gasPrice);
    this.priority = parseHexOrBigInt(priority);
  }
  /** Validates  and returns the validation result. */
  static validate({
    base,
    gasLimit,
    gasPrice,
    priority
  }) {
    const errors = [];
    const baseValue = parseHexOrBigInt(base);
    const gasLimitValue = parseHexOrBigInt(gasLimit);
    const gasPriceValue = parseHexOrBigInt(gasPrice);
    const priorityValue = parseHexOrBigInt(priority);
    if (baseValue <= 0n) {
      errors.push(new Error("Base fee cannot be negative or zero"));
    }
    if (gasLimitValue < 0n) {
      errors.push(new Error("Gas limit cannot be negative"));
    }
    if (gasPriceValue < 0n) {
      errors.push(new Error("Gas price cannot be negative"));
    }
    if (priorityValue < 0n) {
      errors.push(new Error("Priority cannot be negative"));
    }
    return errors;
  }
  /** Validates  and returns the validation result. */
  async validate() {
    return await _FeesWrapper.validate({
      base: this.base,
      gasLimit: this.gasLimit,
      gasPrice: this.gasPrice,
      priority: this.priority
    });
  }
};

// src/modules/wrappers/lib/createSignatureWrappers.ts
import { asHex } from "@ariestools/sdk";
import { PayloadBuilder } from "@xyo-network/sdk";

// src/modules/wrappers/Signature.ts
import { toArrayBuffer } from "@ariestools/sdk";
import { BoundWitnessValidator } from "@xyo-network/sdk";
var SignatureWrapper = class _SignatureWrapper {
  /** XYO address associated with this contract. */
  address;
  /** Protocol hash identifying this value. */
  hash;
  /** signature configuration or state exposed by this contract. */
  signature;
  /** Creates an instance with the supplied configuration. */
  constructor(signature, address, hash) {
    this.signature = signature;
    this.address = address;
    this.hash = hash;
  }
  /** Validates  and returns the validation result. */
  static async validate(hash, address, signature) {
    return await BoundWitnessValidator.validateSignature(toArrayBuffer(hash), address, toArrayBuffer(signature));
  }
  /** Validates  and returns the validation result. */
  async validate() {
    return await _SignatureWrapper.validate(this.hash, this.address, this.signature);
  }
};

// src/modules/wrappers/lib/createSignatureWrappers.ts
var createSignatureWrappers = async (bw) => {
  const signatures = [];
  const hash = await PayloadBuilder.dataHash(bw);
  for (let i = 0; i < bw.$signatures.length; i++) {
    signatures.push(
      new SignatureWrapper(asHex(bw.$signatures[i], true), bw.addresses[i], hash)
    );
  }
  return signatures;
};

// src/modules/wrappers/transaction/HydratedTransaction.ts
import { hexToBigInt as hexToBigInt2, isDefined } from "@ariestools/sdk";
import { PayloadBuilder as PayloadBuilder2 } from "@xyo-network/sdk";
import {
  elevatedTransaction,
  isAllowedBlockPayload,
  isTransferPayload,
  tryExtractElevatedHashes,
  tryExtractElevatedHashesFromScript,
  XYO_ZERO_ADDRESS
} from "@xyo-network/xl1-protocol/protocol-lib";
import { validateTransaction } from "@xyo-network/xl1-protocol/validation";
import { transactionRequiredGas } from "#protocol-sdk";
var sumTransfers = (payload) => {
  let total = 0n;
  for (const i of Object.values(payload.transfers)) {
    total += hexToBigInt2(i ?? "00");
  }
  return total;
};
var HydratedTransactionWrapper = class _HydratedTransactionWrapper {
  /** Payload carried by the transport envelope. */
  data;
  /** Fee limits and prices applied to the transaction. */
  fees;
  context;
  payloadsCache = [];
  _signatureCache = [];
  constructor(data, context) {
    this.context = context ?? { singletons: {} };
    this.data = data;
    this.fees = new FeesWrapper(
      this.boundWitness.fees
    );
  }
  /** Returns the bound witness result exposed by this provider. */
  get boundWitness() {
    return this.data[0];
  }
  /**
   * A copy of the transaction that excludes non-elevated payloads — i.e. only what ends up on chain.
   */
  get elevated() {
    return elevatedTransaction(this.data);
  }
  /** Returns the elevated payload count result exposed by this provider. */
  get elevatedPayloadCount() {
    const { script } = this.data[0];
    return script ? tryExtractElevatedHashesFromScript(script).length : 0;
  }
  /** Returns the elevated payloads result exposed by this provider. */
  get elevatedPayloads() {
    return tryExtractElevatedHashes(this.data);
  }
  /** Returns the external payloads result exposed by this provider. */
  get externalPayloads() {
    const allPayloads = this.payloads;
    return Object.fromEntries(
      this.boundWitness.payload_hashes.map((payloadHash, i) => {
        const payload = allPayloads.find((p) => p._hash === payloadHash);
        return [payloadHash, isDefined(payload) ? payload : this.boundWitness.payload_schemas[i]];
      })
    );
  }
  /** Returns the from result exposed by this provider. */
  get from() {
    return this.data[0].from;
  }
  /** Returns the payload count result exposed by this provider. */
  get payloadCount() {
    return this.payloadsCache.length;
  }
  /** Returns the payloads result exposed by this provider. */
  get payloads() {
    return [...this.payloadsCache];
  }
  /** Returns the private external payloads result exposed by this provider. */
  get privateExternalPayloads() {
    const allPayloads = this.payloads;
    return Object.fromEntries(
      this.boundWitness.payload_hashes.flatMap((payloadHash, i) => allPayloads.every((p) => p._hash !== payloadHash) ? [[payloadHash, this.boundWitness.payload_schemas[i]]] : [])
    );
  }
  // list all the payloads that are included in the transaction and are not elevated and found in the hydration
  /** Returns the public external payloads result exposed by this provider. */
  get publicExternalPayloads() {
    const allPayloads = this.payloads;
    const elevatedPayloads = this.elevatedPayloads;
    return allPayloads.filter((p) => elevatedPayloads.every((ep) => ep._hash !== p._hash));
  }
  /** Returns the signature count result exposed by this provider. */
  get signatureCount() {
    return this._signatureCache.length;
  }
  /** Returns the signatures result exposed by this provider. */
  get signatures() {
    return [...this._signatureCache];
  }
  /** Returns the parse result exposed by this provider. */
  static async parse(transaction, validate = false) {
    const wrapper = new _HydratedTransactionWrapper(
      transaction
    );
    if (validate) {
      await wrapper.parse();
      const errors = await wrapper.validate();
      if (errors.length > 0) {
        throw new Error(`Block validation failed: ${errors.join(", ")}`);
      }
      return wrapper;
    }
    return await wrapper.parse();
  }
  /** Returns the elevated payload result exposed by this provider. */
  elevatedPayload(index) {
    return this.elevatedPayloads.at(index);
  }
  /** Returns the gas required result exposed by this provider. */
  gasRequired() {
    return transactionRequiredGas(this.data);
  }
  /** Returns the payload result exposed by this provider. */
  payload(index) {
    return this.payloads.at(index);
  }
  /** Returns the reward result exposed by this provider. */
  reward() {
    return this.payloadsCache.reduce((acc, payload) => acc + (isTransferPayload(payload) && payload.from === XYO_ZERO_ADDRESS ? sumTransfers(payload) : 0n), 0n);
  }
  /** Returns the signature result exposed by this provider. */
  signature(index) {
    return this._signatureCache[index];
  }
  /** Validates  and returns the validation result. */
  async validate() {
    const signatureErrors = await Promise.all(this._signatureCache.map(async (signature) => signature.validate()));
    const transactionErrors = await validateTransaction({ ...this.context, chainId: this.data[0].chain }, this.data);
    return [...signatureErrors.flat(), ...transactionErrors];
  }
  async parse(validate = false) {
    const payloadsWithHashMeta = await PayloadBuilder2.addHashMeta(this.data[1]);
    const transactionPayloads = payloadsWithHashMeta.filter(isAllowedBlockPayload);
    this._signatureCache = await createSignatureWrappers(this.data[0]);
    for (const payload of transactionPayloads) {
      this.payloadsCache.push(payload);
    }
    if (validate) {
      await this.validate();
    }
    return this;
  }
};
export {
  BaseWrapper,
  ChainWrapper,
  FeesWrapper,
  HydratedTransactionWrapper,
  SignatureWrapper,
  createSignatureWrappers
};
//# sourceMappingURL=wrappers.mjs.map
