import { BN } from "@project-serum/anchor";
import { tryNativeToHexString } from "../utils";
import { MockEmitter } from "./wormhole";
const ETHEREUM_KEY_LENGTH = 20;
export class GovernanceEmitter extends MockEmitter {
    constructor(emitterAddress, startSequence) {
        super(emitterAddress, 1, startSequence);
    }
    publishGovernanceMessage(timestamp, module, payload, action, chain, uptickSequence = true) {
        const serialized = Buffer.alloc(35 + payload.length);
        const moduleBytes = Buffer.alloc(32);
        moduleBytes.write(module, 32 - module.length);
        serialized.write(moduleBytes.toString("hex"), 0, "hex");
        serialized.writeUInt8(action, 32); // action
        serialized.writeUInt16BE(chain, 33);
        serialized.write(payload.toString("hex"), 35, "hex");
        return this.publishMessage(0, serialized, 1, timestamp, uptickSequence);
    }
    publishWormholeSetMessageFee(timestamp, chain, amount, uptickSequence = true) {
        const payload = Buffer.alloc(32);
        const amountBytes = new BN(amount.toString()).toBuffer();
        payload.write(amountBytes.toString("hex"), 32 - amountBytes.length, "hex");
        return this.publishGovernanceMessage(timestamp, "Core", payload, 3, chain, uptickSequence);
    }
    publishWormholeTransferFees(timestamp, chain, amount, recipient, uptickSequence = true) {
        const payload = Buffer.alloc(64);
        const amountBytes = new BN(amount.toString()).toBuffer();
        payload.write(amountBytes.toString("hex"), 32 - amountBytes.length, "hex");
        payload.write(recipient.toString("hex"), 32, "hex");
        return this.publishGovernanceMessage(timestamp, "Core", payload, 4, chain, uptickSequence);
    }
    publishWormholeGuardianSetUpgrade(timestamp, newGuardianSetIndex, publicKeys, uptickSequence = true) {
        const numKeys = publicKeys.length;
        const payload = Buffer.alloc(5 + ETHEREUM_KEY_LENGTH * numKeys);
        payload.writeUInt32BE(newGuardianSetIndex, 0);
        payload.writeUInt8(numKeys, 4);
        for (let i = 0; i < numKeys; ++i) {
            const publicKey = publicKeys.at(i);
            if (publicKey == undefined) {
                throw Error("publicKey == undefined");
            }
            payload.write(publicKey.toString("hex"), 5 + ETHEREUM_KEY_LENGTH * i, "hex");
        }
        return this.publishGovernanceMessage(timestamp, "Core", payload, 2, 0, uptickSequence);
    }
    publishWormholeUpgradeContract(timestamp, chain, newContract, uptickSequence = true) {
        const payload = Buffer.alloc(32);
        payload.write(tryNativeToHexString(newContract, chain), 0, "hex");
        return this.publishGovernanceMessage(timestamp, "Core", payload, 1, chain, uptickSequence);
    }
    publishTokenBridgeRegisterChain(timestamp, chain, address, uptickSequence = true) {
        const payload = Buffer.alloc(34);
        payload.writeUInt16BE(chain, 0);
        payload.write(tryNativeToHexString(address, chain), 2, "hex");
        return this.publishGovernanceMessage(timestamp, "TokenBridge", payload, 1, 0, uptickSequence);
    }
    publishTokenBridgeUpgradeContract(timestamp, chain, newContract, uptickSequence = true) {
        const payload = Buffer.alloc(32);
        payload.write(tryNativeToHexString(newContract, this.chain), 0, "hex");
        return this.publishGovernanceMessage(timestamp, "TokenBridge", payload, 2, chain, uptickSequence);
    }
    publishNftBridgeRegisterChain(timestamp, chain, address, uptickSequence = true) {
        const payload = Buffer.alloc(34);
        payload.writeUInt16BE(chain, 0);
        payload.write(tryNativeToHexString(address, chain), 2, "hex");
        return this.publishGovernanceMessage(timestamp, "NFTBridge", payload, 1, 0, uptickSequence);
    }
    publishNftBridgeUpgradeContract(timestamp, chain, newContract, uptickSequence = true) {
        const payload = Buffer.alloc(32);
        payload.write(tryNativeToHexString(newContract, this.chain), 0, "hex");
        return this.publishGovernanceMessage(timestamp, "NFTBridge", payload, 2, chain, uptickSequence);
    }
}
