Last active
April 23, 2025 21:11
-
-
Save xstelea/e63777eae63531bc2452925a4d42d98d to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import { BlueprintInterface } from "@radixdlt/babylon-core-api-sdk"; | |
| import { GatewayApiClient } from "@radixdlt/babylon-gateway-api-sdk"; | |
| export const gatewayClientImplementation = (gateway: GatewayApiClient) => { | |
| const getComponentInformation = async ( | |
| address: string | |
| ): Promise<{ packageAddress: string; blueprintName: string } | null> => { | |
| const { items } = await gateway.state.innerClient.stateEntityDetails({ | |
| stateEntityDetailsRequest: { | |
| addresses: [address], | |
| }, | |
| }); | |
| if (!items?.[0]?.details) { | |
| return null; | |
| } | |
| const packageDetails = items[0].details as { | |
| package_address?: string; | |
| blueprint_name?: string; | |
| }; | |
| if (packageDetails?.package_address && packageDetails?.blueprint_name) { | |
| return { | |
| packageAddress: packageDetails.package_address, | |
| blueprintName: packageDetails.blueprint_name, | |
| }; | |
| } | |
| return null; | |
| }; | |
| const getAllEventsForComponent = async ( | |
| address: string | |
| ): Promise<{ | |
| interface: BlueprintInterface; | |
| } | null> => { | |
| const information = await getComponentInformation(address); | |
| if (!information) { | |
| return null; | |
| } | |
| // Todo: Use `exhaustPaginationWithLedgerState` to get all data | |
| const events = await gateway.state.innerClient.packageBlueprintPage({ | |
| statePackageBlueprintPageRequest: { | |
| package_address: information.packageAddress, | |
| }, | |
| }); | |
| return events.items.find((item) => item.name === information.blueprintName) | |
| ?.definition as { | |
| interface: BlueprintInterface; | |
| }; | |
| }; | |
| const stateEntityDetails = async (address: string) => { | |
| const entityData = await gateway.state.innerClient.stateEntityDetails({ | |
| stateEntityDetailsRequest: { | |
| addresses: [address], | |
| }, | |
| }); | |
| return entityData.items[0]; | |
| }; | |
| return { | |
| getComponentInformation, | |
| getAllEventsForComponent, | |
| stateEntityDetails, | |
| }; | |
| }; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import { | |
| GatewayApiClient, | |
| RadixNetwork, | |
| } from '@radixdlt/babylon-gateway-api-sdk'; | |
| import { gatewayClientImplementation } from './gatewayClientImplementation'; | |
| // TODO: Use `exhaustPaginationWithLedgerState` to get all events for a component | |
| export type GatewayModule = ReturnType<typeof GatewayModule>; | |
| export const GatewayModule = ({ | |
| gatewayClient, | |
| stokenetGatewayClient, | |
| }: { | |
| gatewayClient?: GatewayApiClient; | |
| stokenetGatewayClient?: GatewayApiClient; | |
| }) => { | |
| const gateway = | |
| gatewayClient ?? | |
| GatewayApiClient.initialize({ | |
| networkId: RadixNetwork.Mainnet, | |
| applicationName: 'hookah.ing', | |
| applicationVersion: '0.0.1', | |
| }); | |
| const stokenetGateway = | |
| stokenetGatewayClient ?? | |
| GatewayApiClient.initialize({ | |
| networkId: RadixNetwork.Stokenet, | |
| applicationName: 'hookah.ing', | |
| applicationVersion: '0.0.1', | |
| }); | |
| const stokenet = gatewayClientImplementation(stokenetGateway); | |
| const mainnet = gatewayClientImplementation(gateway); | |
| const networkAwareGatewayClient = (address: string) => | |
| address.includes('_tdx_2_') ? stokenet : mainnet; | |
| return { | |
| stateEntityDetails: (address: string) => | |
| networkAwareGatewayClient(address).stateEntityDetails(address), | |
| getAllEventsForComponent: (address: string) => | |
| networkAwareGatewayClient(address).getAllEventsForComponent(address), | |
| }; | |
| }; | |
| export const gatewayModule = GatewayModule({}); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import { | |
| BlueprintDefinition, | |
| BlueprintInterface, | |
| } from "@radixdlt/babylon-core-api-sdk"; | |
| import { gatewayModule, GatewayModule } from "./../gateway/gatewayModule"; | |
| export const TriggerValidator = ({ | |
| gatewayModule, | |
| }: { | |
| gatewayModule: GatewayModule; | |
| }) => { | |
| const BLOCKED_EVENTS = ["RemoveMetadataEvent", "SetMetadataEvent"]; | |
| const SHARED_EVENTS = [ | |
| "RemoveMetadataEvent", | |
| "SetMetadataEvent", | |
| "LockOwnerRoleEvent", | |
| "SetOwnerRoleEvent", | |
| "SetRoleEvent", | |
| ]; | |
| const isValid = async (emitterAddress: string, eventName: string) => { | |
| try { | |
| const validEvents = await getValidEvents(emitterAddress); | |
| if (!validEvents.includes(eventName)) { | |
| return false; | |
| } | |
| return true; | |
| } catch (error) { | |
| return false; | |
| } | |
| }; | |
| const getValidEvents = async (emitterAddress: string) => { | |
| const POOL_EVENTS = [ | |
| "ContributionEvent", | |
| "RedemptionEvent", | |
| "WithdrawEvent", | |
| "DepositEvent", | |
| ...SHARED_EVENTS, | |
| ]; | |
| const LOCKER_EVENTS = [ | |
| "ClaimEvent", | |
| "RecoverEvent", | |
| "StoreEvent", | |
| ...SHARED_EVENTS, | |
| ]; | |
| const ACCOUNT_EVENTS = [ | |
| "AddAuthorizedDepositorEvent", | |
| "DepositEvent", | |
| "PayFeeEvent", | |
| "LockFeeEvent", | |
| "RejectedDepositEvent", | |
| "RemoveAuthorizedDepositorEvent", | |
| "RemoveResourcePreferenceEvent", | |
| "SetDefaultDepositRuleEvent", | |
| "SetResourcePreferenceEvent", | |
| "WithdrawEvent", | |
| ...SHARED_EVENTS, | |
| ]; | |
| const RESOURCE_EVENTS = [ | |
| "BurnFungibleResourceEvent", | |
| "BurnNonFungibleResourceEvent", | |
| "MintFungibleResourceEvent", | |
| "MintNonFungibleResourceEvent", | |
| "VaultCreationEvent", | |
| ...SHARED_EVENTS, | |
| ]; | |
| const VALIDATOR_EVENTS = [ | |
| "RegisterValidatorEvent", | |
| "UnregisterValidatorEvent", | |
| "StakeEvent", | |
| "UnstakeEvent", | |
| "ClaimXrdEvent", | |
| "UpdateAcceptingStakeDelegationStateEvent", | |
| "ProtocolUpdateReadinessSignalEvent", | |
| "ValidatorEmissionAppliedEvent", | |
| "ValidatorRewardAppliedEvent", | |
| ...SHARED_EVENTS, | |
| ]; | |
| const INTERNAL_VAULT_EVENTS = [ | |
| "DepositEvent", | |
| "LockFeeEvent", | |
| "PayFeeEvent", | |
| "RecallEvent", | |
| "WithdrawEvent", | |
| ]; | |
| const CONSENSUS_MANAGER_EVENTS = [ | |
| "EpochChangeEvent", | |
| "RoundChangeEvent", | |
| "DepositEvent", | |
| ].filter((event) => !BLOCKED_EVENTS.includes(event)); | |
| if (emitterAddress.startsWith("component_")) { | |
| // Check component events from the gateway | |
| const componentEvents = (await gatewayModule.getAllEventsForComponent( | |
| emitterAddress | |
| )) as { | |
| interface: BlueprintInterface; | |
| }; | |
| // Return component events if available | |
| if (componentEvents?.interface?.events) { | |
| return [ | |
| ...Object.keys(componentEvents.interface.events), | |
| ...SHARED_EVENTS, | |
| ]; | |
| } | |
| } | |
| const entityDetails = | |
| await gatewayModule.stateEntityDetails(emitterAddress); | |
| if (!entityDetails || entityDetails.address !== emitterAddress) { | |
| return []; | |
| } | |
| if (emitterAddress.startsWith("pool_")) { | |
| return POOL_EVENTS; | |
| } | |
| if (emitterAddress.startsWith("locker_")) { | |
| return LOCKER_EVENTS; | |
| } | |
| if (emitterAddress.startsWith("account_")) { | |
| return ACCOUNT_EVENTS; | |
| } | |
| if (emitterAddress.startsWith("resource_")) { | |
| return RESOURCE_EVENTS; | |
| } | |
| if (emitterAddress.startsWith("validator_")) { | |
| return VALIDATOR_EVENTS; | |
| } | |
| if (emitterAddress.startsWith("internal_vault_")) { | |
| return INTERNAL_VAULT_EVENTS; | |
| } | |
| if (emitterAddress.startsWith("consensusmanager_")) { | |
| return CONSENSUS_MANAGER_EVENTS; | |
| } | |
| if (emitterAddress.startsWith("package_")) { | |
| const possibleEvents = | |
| entityDetails.details?.type === "Package" && | |
| entityDetails.details?.blueprints?.items | |
| .map((blueprint) => | |
| Object.keys( | |
| ( | |
| blueprint.definition as { | |
| interface: BlueprintDefinition["_interface"]; | |
| } | |
| ).interface.events | |
| ) | |
| ) | |
| .flat() | |
| .filter((value): value is string => typeof value === "string"); | |
| if (possibleEvents) { | |
| return possibleEvents; | |
| } | |
| } | |
| return []; | |
| }; | |
| return { | |
| getValidEvents, | |
| isValid, | |
| }; | |
| }; | |
| export const triggerValidator = TriggerValidator({ | |
| gatewayModule, | |
| }); | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment