var __extends = (this && this.__extends) || (function () {
    var extendStatics = function (d, b) {
        extendStatics = Object.setPrototypeOf ||
            ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
            function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
        return extendStatics(d, b);
    };
    return function (d, b) {
        if (typeof b !== "function" && b !== null)
            throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
        extendStatics(d, b);
        function __() { this.constructor = d; }
        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
    };
})();
import { BN } from "@project-serum/anchor";
import { PublicKey } from "@solana/web3.js";
import { tryNativeToHexString } from "../utils";
import { MockEmitter } from "./wormhole";
var MockTokenBridge = /** @class */ (function (_super) {
    __extends(MockTokenBridge, _super);
    function MockTokenBridge(emitterAddress, chain, consistencyLevel, startSequence) {
        var _this = _super.call(this, emitterAddress, chain, startSequence) || this;
        _this.consistencyLevel = consistencyLevel;
        return _this;
    }
    MockTokenBridge.prototype.publishTokenBridgeMessage = function (serialized, nonce, timestamp, uptickSequence) {
        if (uptickSequence === void 0) { uptickSequence = true; }
        return this.publishMessage(nonce == undefined ? 0 : nonce, serialized, this.consistencyLevel, timestamp, uptickSequence);
    };
    MockTokenBridge.prototype.publishAttestMeta = function (tokenAddress, decimals, symbol, name, nonce, timestamp, uptickSequence) {
        if (uptickSequence === void 0) { uptickSequence = true; }
        var serialized = Buffer.alloc(100);
        serialized.writeUInt8(2, 0);
        var 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);
    };
    MockTokenBridge.prototype.serializeTransferOnly = function (withPayload, tokenAddress, tokenChain, amount, recipientChain, recipient, fee, fromAddress) {
        var serialized = Buffer.alloc(133);
        serialized.writeUInt8(1, 0);
        var amountBytes = new 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");
            }
            var feeBytes = new BN(fee.toString()).toBuffer();
            serialized.write(feeBytes.toString("hex"), 133 - feeBytes.length, "hex");
        }
        return serialized;
    };
    MockTokenBridge.prototype.publishTransferTokens = function (tokenAddress, tokenChain, amount, recipientChain, recipient, fee, nonce, timestamp, uptickSequence) {
        if (uptickSequence === void 0) { uptickSequence = true; }
        return this.publishTokenBridgeMessage(this.serializeTransferOnly(false, // withPayload
        tokenAddress, tokenChain, amount, recipientChain, recipient, fee), nonce, timestamp, uptickSequence);
    };
    MockTokenBridge.prototype.publishTransferTokensWithPayload = function (tokenAddress, tokenChain, amount, recipientChain, recipient, fromAddress, payload, nonce, timestamp, uptickSequence) {
        if (uptickSequence === void 0) { uptickSequence = true; }
        return this.publishTokenBridgeMessage(Buffer.concat([
            this.serializeTransferOnly(true, // withPayload
            tokenAddress, tokenChain, amount, recipientChain, recipient, undefined, // fee
            fromAddress),
            payload,
        ]), nonce, timestamp, uptickSequence);
    };
    return MockTokenBridge;
}(MockEmitter));
export { MockTokenBridge };
var MockEthereumTokenBridge = /** @class */ (function (_super) {
    __extends(MockEthereumTokenBridge, _super);
    function MockEthereumTokenBridge(emitterAddress, startSequence) {
        var _this = this;
        var chain = 2;
        _this = _super.call(this, tryNativeToHexString(emitterAddress, chain), chain, 15, startSequence) || this;
        return _this;
    }
    MockEthereumTokenBridge.prototype.publishAttestMeta = function (tokenAddress, decimals, symbol, name, nonce, timestamp, uptickSequence) {
        if (uptickSequence === void 0) { uptickSequence = true; }
        return _super.prototype.publishAttestMeta.call(this, tryNativeToHexString(tokenAddress, this.chain), decimals, symbol == undefined ? "" : symbol, name == undefined ? "" : name, nonce, timestamp, uptickSequence);
    };
    return MockEthereumTokenBridge;
}(MockTokenBridge));
export { MockEthereumTokenBridge };
var MockSolanaTokenBridge = /** @class */ (function (_super) {
    __extends(MockSolanaTokenBridge, _super);
    function MockSolanaTokenBridge(emitterAddress) {
        return _super.call(this, new PublicKey(emitterAddress).toBuffer().toString("hex"), 1, 32) || this;
    }
    MockSolanaTokenBridge.prototype.publishAttestMeta = function (mint, decimals, symbol, name, nonce, timestamp, uptickSequence) {
        if (uptickSequence === void 0) { uptickSequence = true; }
        return _super.prototype.publishAttestMeta.call(this, new PublicKey(mint).toBuffer().toString("hex"), decimals, symbol == undefined ? "" : symbol, name == undefined ? "" : name, nonce, timestamp, uptickSequence);
    };
    return MockSolanaTokenBridge;
}(MockTokenBridge));
export { MockSolanaTokenBridge };
