import { concatBytes, u8, u32le, vec } from '../codecs/binary.js';
import { encodeH256, encodeRemoteRouterConfig, } from '../codecs/shared.js';
import { SYSTEM_PROGRAM_ADDRESS } from '../constants.js';
import { deriveCrossCollateralDispatchAuthorityPda, deriveCrossCollateralStatePda, deriveHyperlaneTokenPda, } from '../pda.js';
import { getTokenInitInstruction, } from './token.js';
import { buildInstruction, readonlyAccount, writableAccount, writableSignerAddress, } from './utils.js';
// Cross-collateral plugin discriminator [2; 8], distinct from the base
// token program discriminator [1; 8] (PROGRAM_INSTRUCTION_DISCRIMINATOR).
const CC_INSTRUCTION_DISCRIMINATOR = new Uint8Array([2, 2, 2, 2, 2, 2, 2, 2]);
export var CrossCollateralInstructionKind;
(function (CrossCollateralInstructionKind) {
    CrossCollateralInstructionKind[CrossCollateralInstructionKind["SetCrossCollateralRouters"] = 0] = "SetCrossCollateralRouters";
    CrossCollateralInstructionKind[CrossCollateralInstructionKind["TransferRemoteTo"] = 1] = "TransferRemoteTo";
    CrossCollateralInstructionKind[CrossCollateralInstructionKind["HandleLocal"] = 2] = "HandleLocal";
    CrossCollateralInstructionKind[CrossCollateralInstructionKind["HandleLocalAccountMetas"] = 3] = "HandleLocalAccountMetas";
})(CrossCollateralInstructionKind || (CrossCollateralInstructionKind = {}));
function encodeCrossCollateralRouterUpdate(update) {
    if (update.kind === 'add') {
        return concatBytes(u8(0), u32le(update.config.domain), encodeH256(update.config.router));
    }
    return concatBytes(u8(1), encodeRemoteRouterConfig(update.config));
}
export async function getCrossCollateralInitInstruction(programAddress, payer, init, pluginAccounts, mailboxOutboxPda) {
    const { address: ccStatePda } = await deriveCrossCollateralStatePda(programAddress);
    const { address: ccDispatchAuthority } = await deriveCrossCollateralDispatchAuthorityPda(programAddress);
    return getTokenInitInstruction(programAddress, payer, init, [
        ...pluginAccounts,
        writableAccount(ccStatePda),
        writableAccount(ccDispatchAuthority),
        readonlyAccount(mailboxOutboxPda),
    ]);
}
export async function getSetCrossCollateralRoutersInstruction(programAddress, owner, updates) {
    const { address: ccStatePda } = await deriveCrossCollateralStatePda(programAddress);
    const { address: tokenPda } = await deriveHyperlaneTokenPda(programAddress);
    return buildInstruction(programAddress, [
        readonlyAccount(SYSTEM_PROGRAM_ADDRESS),
        writableAccount(ccStatePda),
        readonlyAccount(tokenPda),
        writableSignerAddress(owner),
    ], concatBytes(CC_INSTRUCTION_DISCRIMINATOR, u8(CrossCollateralInstructionKind.SetCrossCollateralRouters), vec(updates, encodeCrossCollateralRouterUpdate)));
}
//# sourceMappingURL=cross-collateral-token.js.map