"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.MockSolanaTokenBridge = exports.MockEthereumTokenBridge = exports.MockTokenBridge = void 0;
const anchor_1 = require("@project-serum/anchor");
const web3_js_1 = require("@solana/web3.js");
const utils_1 = require("../utils");
const wormhole_1 = require("./wormhole");
class MockTokenBridge extends wormhole_1.MockEmitter {
    constructor(emitterAddress, chain, consistencyLevel, startSequence) {
        super(emitterAddress, chain, startSequence);
        this.consistencyLevel = consistencyLevel;
    }
    publishTokenBridgeMessage(serialized, nonce, timestamp, uptickSequence = true) {
        return this.publishMessage(nonce == undefined ? 0 : nonce, serialized, this.consistencyLevel, timestamp, uptickSequence);
    }
    publishAttestMeta(tokenAddress, decimals, symbol, name, nonce, timestamp, uptickSequence = true) {
        const serialized = Buffer.alloc(100);
        serialized.writeUInt8(2, 0);
        const hexlified = Buffer.from(tokenAddress, "hex");
        if (hexlified.length != 32) {
            throw new Error("tokenAddress must be 32 bytes");
        }
        serialized.write(hexlified.toString("hex"), 1, "hex");
        serialized.writeUInt16BE(this.chain, 33);
        serialized.writeUInt8(decimals, 35);
        // truncate to 32 characters
        symbol = symbol.substring(0, 32);
        serialized.write(symbol, 68 - symbol.length);
        // truncate to 32 characters
        name = name.substring(0, 32);
        serialized.write(name, 100 - name.length);
        return this.publishTokenBridgeMessage(serialized, nonce, timestamp, uptickSequence);
    }
    serializeTransferOnly(withPayload, tokenAddress, tokenChain, amount, recipientChain, recipient, fee, fromAddress) {
        const serialized = Buffer.alloc(133);
        serialized.writeUInt8(withPayload ? 3 : 1, 0);
        const amountBytes = new anchor_1.BN(amount.toString()).toBuffer();
        serialized.write(amountBytes.toString("hex"), 33 - amountBytes.length, "hex");
        serialized.write(tokenAddress, 33, "hex");
        serialized.writeUInt16BE(tokenChain, 65);
        serialized.write(recipient, 67, "hex");
        serialized.writeUInt16BE(recipientChain, 99);
        if (withPayload) {
            if (fromAddress === undefined) {
                throw new Error("fromAddress === undefined");
            }
            serialized.write(fromAddress.toString("hex"), 101, "hex");
        }
        else {
            if (fee === undefined) {
                throw new Error("fee === undefined");
            }
            const feeBytes = new anchor_1.BN(fee.toString()).toBuffer();
            serialized.write(feeBytes.toString("hex"), 133 - feeBytes.length, "hex");
        }
        return serialized;
    }
    publishTransferTokens(tokenAddress, tokenChain, amount, recipientChain, recipient, fee, nonce, timestamp, uptickSequence = true) {
        return this.publishTokenBridgeMessage(this.serializeTransferOnly(false, // withPayload
        tokenAddress, tokenChain, amount, recipientChain, recipient, fee), nonce, timestamp, uptickSequence);
    }
    publishTransferTokensWithPayload(tokenAddress, tokenChain, amount, recipientChain, recipient, fromAddress, payload, nonce, timestamp, uptickSequence = true) {
        return this.publishTokenBridgeMessage(Buffer.concat([
            this.serializeTransferOnly(true, // withPayload
            tokenAddress, tokenChain, amount, recipientChain, recipient, undefined, // fee
            fromAddress),
            payload,
        ]), nonce, timestamp, uptickSequence);
    }
}
exports.MockTokenBridge = MockTokenBridge;
class MockEthereumTokenBridge extends MockTokenBridge {
    constructor(emitterAddress, startSequence) {
        const chain = 2;
        super(utils_1.tryNativeToHexString(emitterAddress, chain), chain, 15, startSequence);
    }
    publishAttestMeta(tokenAddress, decimals, symbol, name, nonce, timestamp, uptickSequence = true) {
        return super.publishAttestMeta(utils_1.tryNativeToHexString(tokenAddress, this.chain), decimals, symbol == undefined ? "" : symbol, name == undefined ? "" : name, nonce, timestamp, uptickSequence);
    }
}
exports.MockEthereumTokenBridge = MockEthereumTokenBridge;
class MockSolanaTokenBridge extends MockTokenBridge {
    constructor(emitterAddress) {
        super(new web3_js_1.PublicKey(emitterAddress).toBuffer().toString("hex"), 1, 32);
    }
    publishAttestMeta(mint, decimals, symbol, name, nonce, timestamp, uptickSequence = true) {
        return super.publishAttestMeta(new web3_js_1.PublicKey(mint).toBuffer().toString("hex"), decimals, symbol == undefined ? "" : symbol, name == undefined ? "" : name, nonce, timestamp, uptickSequence);
    }
}
exports.MockSolanaTokenBridge = MockSolanaTokenBridge;
