@hyperlane-xyz/sdk
Version:
The official SDK for the Hyperlane Network
72 lines • 3.46 kB
JavaScript
import { DefaultFallbackRoutingIsm__factory, IRoutingIsm__factory, } from '@hyperlane-xyz/core';
import { assert } from '@hyperlane-xyz/utils';
import { EvmIsmReader } from '../EvmIsmReader.js';
import { IsmType, isDynamicallyRoutedIsmType, } from '../types.js';
import { decodeIsmMetadata } from './decode.js';
export class StaticRoutingMetadataBuilder {
baseMetadataBuilder;
constructor(baseMetadataBuilder) {
this.baseMetadataBuilder = baseMetadataBuilder;
}
async build(context, maxDepth = 10) {
const originChain = this.baseMetadataBuilder.multiProvider.getChainName(context.message.parsed.origin);
const originContext = {
...context,
ism: context.ism.domains[originChain],
};
return this.baseMetadataBuilder.build(originContext, maxDepth - 1);
}
static decode(metadata, context) {
// TODO: this is a naive implementation, we should support domain ID keys
assert(context.message.parsed.originChain, 'originChain is required');
const ism = context.ism.domains[context.message.parsed.originChain];
const originMetadata = typeof ism === 'string'
? metadata
: decodeIsmMetadata(metadata, {
...context,
ism: ism,
});
return {
type: IsmType.ROUTING,
origin: context.message.parsed.originChain,
metadata: originMetadata,
};
}
}
export class DynamicRoutingMetadataBuilder extends StaticRoutingMetadataBuilder {
baseMetadataBuilder;
constructor(baseMetadataBuilder) {
super(baseMetadataBuilder);
this.baseMetadataBuilder = baseMetadataBuilder;
}
async build(context, maxDepth = 10) {
const { message, ism } = context;
const originChain = this.baseMetadataBuilder.multiProvider.getChainName(message.parsed.origin);
const destination = message.parsed.destination;
const provider = this.baseMetadataBuilder.multiProvider.getProvider(destination);
// Helper to derive new ISM config and recurse
const deriveAndRecurse = async (moduleAddress) => {
const ismReader = new EvmIsmReader(this.baseMetadataBuilder.multiProvider, destination);
const nextConfig = await ismReader.deriveIsmConfig(moduleAddress);
return this.baseMetadataBuilder.build({ ...context, ism: nextConfig }, maxDepth - 1);
};
// 1) Dynamic routing (AmountRouting or ICA): always route via .route(message)
if (isDynamicallyRoutedIsmType(ism.type)) {
const router = IRoutingIsm__factory.connect(ism.address, provider);
const moduleAddr = await router.route(message.message);
return deriveAndRecurse(moduleAddr);
}
// 2) Static domain routing: if origin is enrolled, delegate to super
if (ism.domains?.[originChain]) {
return super.build(context, maxDepth);
}
// 3) Fallback routing: use .module(origin)
if (ism.type === IsmType.FALLBACK_ROUTING) {
const fallback = DefaultFallbackRoutingIsm__factory.connect(ism.address, provider);
const moduleAddr = await fallback.module(message.parsed.origin);
return deriveAndRecurse(moduleAddr);
}
throw new Error(`DefaultFallbackRoutingMetadataBuilder: unexpected ISM type ${ism.type}`);
}
}
//# sourceMappingURL=routing.js.map