import { defineProperty as _defineProperty } from '../../_virtual/_rollupPluginBabelHelpers.mjs';
import { Buffer } from 'buffer';
import * as ed25519 from '@noble/ed25519';
import { sha512 } from '@noble/hashes/sha512';
import { Keypair } from '@solarti/web3.js';
import { UninitializedDerivedIdentityError } from './errors.mjs';
import { subtractAmounts } from '../../types/Amount.mjs';
import { isSigner } from '../../types/Signer.mjs';

/**
 * @group Modules
 */
class DerivedIdentityClient {
  constructor(metaplex) {
    _defineProperty(this, "originalSigner", null);
    _defineProperty(this, "derivedKeypair", null);
    this.metaplex = metaplex;
  }
  get publicKey() {
    this.assertInitialized();
    return this.derivedKeypair.publicKey;
  }
  get secretKey() {
    this.assertInitialized();
    return this.derivedKeypair.secretKey;
  }
  get originalPublicKey() {
    this.assertInitialized();
    return this.originalSigner.publicKey;
  }
  async deriveFrom(message, originalSigner) {
    this.originalSigner = originalSigner ?? this.metaplex.identity().driver();
    const signature = await this.originalSigner.signMessage(Buffer.from(message));
    const seeds = sha512(signature).slice(0, 32);
    this.derivedKeypair = Keypair.fromSeed(seeds);
  }
  fund(amount) {
    this.assertInitialized();
    return this.metaplex.system().transferSol({
      from: this.originalSigner,
      to: this.derivedKeypair.publicKey,
      amount
    }, {
      payer: this.originalSigner
    });
  }
  withdraw(amount) {
    this.assertInitialized();
    return this.metaplex.system().transferSol({
      from: this.derivedKeypair,
      to: this.originalSigner.publicKey,
      amount
    }, {
      payer: this.derivedKeypair
    });
  }
  async withdrawAll() {
    this.assertInitialized();
    const balance = await this.metaplex.rpc().getBalance(this.derivedKeypair.publicKey);
    const transactionFee = this.metaplex.utils().estimateTransactionFee();
    return this.withdraw(subtractAmounts(balance, transactionFee));
  }
  close() {
    this.originalSigner = null;
    this.derivedKeypair = null;
  }
  async signMessage(message) {
    return ed25519.sync.sign(message, this.secretKey);
  }
  async signTransaction(transaction) {
    transaction.partialSign(this);
    return transaction;
  }
  async signAllTransactions(transactions) {
    return Promise.all(transactions.map(transaction => this.signTransaction(transaction)));
  }
  verifyMessage(message, signature) {
    return ed25519.sync.verify(message, signature, this.publicKey.toBytes());
  }
  equals(that) {
    if (isSigner(that)) {
      that = that.publicKey;
    }
    return this.publicKey.equals(that);
  }
  assertInitialized() {
    if (this.derivedKeypair === null || this.originalSigner === null) {
      throw new UninitializedDerivedIdentityError();
    }
  }
}

export { DerivedIdentityClient };
//# sourceMappingURL=DerivedIdentityClient.mjs.map
