import { Credential, RewardAccount, StakeAddress } from "./address"; import { ProtocolParamUpdate, RawProtocolParamUpdate, parseProtocolParams } from "./parameterUpdate"; import { ProtocolVersion } from "./protocol-param"; import { Anchor, Buffer32, RawAnchor, RawCredential, RawTxId, UtxoId } from "../types"; export type RawGovActionId = RawTxId; // gov_action = // [ parameter_change_action // // hard_fork_initiation_action // // treasury_withdrawals_action // // no_confidence // // update_committee // // new_constitution // // info_action // ] // policy_hash = scripthash // parameter_change_action = (0, gov_action_id / null, protocol_param_update, policy_hash / null) // hard_fork_initiation_action = (1, gov_action_id / null, protocol_version) // treasury_withdrawals_action = (2, { reward_account => coin }, policy_hash / null) // no_confidence = (3, gov_action_id / null) // update_committee = (4, gov_action_id / null, set, { committee_cold_credential => epoch }, unit_interval) // new_constitution = (5, gov_action_id / null, constitution) // constitution = // [ anchor // , scripthash / null // ] // info_action = 6 export type RawGovAction = | RawParameterChangeAction | RawHardForkInitiationAction | RawTreasuryWithdrawalAction | RawNoConfidenceAction | RawUpdateCommittee | RawNewConstitution | [6]; export type RawParameterChangeAction = [0, RawGovActionId | undefined, RawProtocolParamUpdate, Buffer | undefined]; export type RawHardForkInitiationAction = [1, RawGovActionId | undefined, ProtocolVersion]; export type RawTreasuryWithdrawalAction = [2, Map, Buffer | undefined]; export type RawNoConfidenceAction = [3, RawGovActionId | undefined]; export type RawUpdateCommittee = [ 4, RawGovActionId | null, Set, Map, [number | bigint, number | bigint], ]; export type RawNewConstitution = [5, RawGovActionId | undefined, RawConstitution]; export type RawConstitution = [RawAnchor, Buffer32 | undefined]; export type Constitution = [{anchor: Anchor}, Buffer?] export class GovAction { type!: string; static fromCborObject(obj: RawGovAction): GovAction { throw new Error("Method 'fromCborObject' must be implemented in derived classes"); } } export class ParameterChangeAction extends GovAction { prevGovActionId?: UtxoId; protocolParameterUpdate: ProtocolParamUpdate; policyHash?: Buffer; constructor(protocolParameterUpdate: ProtocolParamUpdate, prevGovActionId?: UtxoId, policyHash?: Buffer) { super(); this.prevGovActionId = prevGovActionId; this.protocolParameterUpdate = protocolParameterUpdate; this.policyHash = policyHash; this.type = "ParameterChangeAction"; } static override fromCborObject(obj: RawGovAction): ParameterChangeAction { if (obj[0] == 0) return new ParameterChangeAction( parseProtocolParams(obj[2]), obj[1] ? UtxoId.fromCborObject(obj[1]) : undefined, obj[3] ); else throw new Error("Invalid CBOR type for ParameterChangeAction"); } } export class HardForkInitiationAction extends GovAction { prevGovActionId?: UtxoId; protocolVersion: ProtocolVersion; constructor(protocolVersion: ProtocolVersion, prevGovActionId?: UtxoId) { super(); this.prevGovActionId = prevGovActionId; this.protocolVersion = protocolVersion; this.type = "HardForkInitiationAction"; } static override fromCborObject(obj: RawGovAction): HardForkInitiationAction { if (obj[0] == 1) return new HardForkInitiationAction(obj[2], obj[1] ? UtxoId.fromCborObject(obj[1]) : undefined); else { throw new Error("Invalid CBOR type for ParameterChangeAction"); } } } export class TreasuryWithdrawalAction extends GovAction { rewards: Map; policyHash?: Buffer; constructor(rewards: Map, policyHash?: Buffer) { super(); this.policyHash = policyHash; this.rewards = rewards; this.type = "TreasuryWithdrawalAction"; } static override fromCborObject(obj: RawGovAction): TreasuryWithdrawalAction { if (obj[0] == 2) { const rewardMap = new Map(); obj[1].forEach((coin, reward) => { const parsedRewardAccount = StakeAddress.fromBytes(reward); rewardMap.set(parsedRewardAccount, coin); }); return new TreasuryWithdrawalAction(rewardMap, obj[2]); } else throw new Error("Invalid CBOR type for TreasuryWithdrawalAction"); } } export class NoConfidenceAction extends GovAction { prevGovActionId?: UtxoId; constructor(prevGovActionId?: UtxoId) { super(); this.prevGovActionId = prevGovActionId; this.type = "NoConfidenceAction"; } static override fromCborObject(obj: RawGovAction): NoConfidenceAction { if (obj[0] == 3) { return new NoConfidenceAction(obj[1] ? UtxoId.fromCborObject(obj[1]) : undefined); } else throw new Error("Invalid CBOR type for NoConfidenceAction"); } } export class UpdateCommitteeAction extends GovAction { prevGovActionId?: UtxoId; coldCredentials: Set; credentialEpochMap: Map; interval: [number | bigint, number | bigint]; constructor( coldCredentials: Set, credentialEpochMap: Map, interval: [number | bigint, number | bigint], prevGovActionId?: UtxoId ) { super(); this.prevGovActionId = prevGovActionId; this.coldCredentials = coldCredentials; this.credentialEpochMap = credentialEpochMap; this.interval = interval; this.type = "UpdateCommitteeAction"; } static override fromCborObject(obj: RawGovAction): UpdateCommitteeAction { if (obj[0] == 4) { const credentialSet = new Set(); const credentialEpochMap = new Map(); obj[2].forEach((rawColdCred) => { credentialSet.add(Credential.fromCborObject(rawColdCred)); }); obj[3].forEach((epoch, rawColdCred) => { credentialEpochMap.set(Credential.fromCborObject(rawColdCred), epoch); }); return new UpdateCommitteeAction( credentialSet, credentialEpochMap, obj[4], obj[1] ? UtxoId.fromCborObject(obj[1]) : undefined ); } else throw new Error("Invalid CBOR type for UpdateCommitteeAction"); } } export class NewConstitutionAction extends GovAction { prevGovActionId?: UtxoId; constitution: Constitution; constructor(constitution: Constitution, prevGovActionId?: UtxoId) { super(); this.constitution = constitution; this.prevGovActionId = prevGovActionId; this.type = "NewConstitutionAction"; } static override fromCborObject(obj: RawGovAction): NewConstitutionAction { if (obj[0] == 5) { const parsedConstitution: Constitution = [{anchor: Anchor.fromCborObject(obj[2][0])}, obj[2][1]]; return new NewConstitutionAction(parsedConstitution, obj[1] ? UtxoId.fromCborObject(obj[1]) : undefined); } else throw new Error("Invalid CBOR type for NewConstitutionAction"); } } export class InfoAction extends GovAction { constructor() { super(); this.type = "InfoAction"; } static override fromCborObject(obj: RawGovAction): InfoAction { if (obj[0] == 6) { return new InfoAction(); } else { throw new Error("Invalid CBOR type for InfoAction"); } } } GovAction.fromCborObject = function (obj: RawGovAction): GovAction { switch (obj[0]) { case 0: return ParameterChangeAction.fromCborObject(obj); case 1: return HardForkInitiationAction.fromCborObject(obj); case 2: return TreasuryWithdrawalAction.fromCborObject(obj); case 3: return NoConfidenceAction.fromCborObject(obj); case 4: return UpdateCommitteeAction.fromCborObject(obj); case 5: return NewConstitutionAction.fromCborObject(obj); case 6: return InfoAction.fromCborObject(obj); default: throw new Error("Unknown GovAction type"); } };