@hyperlane-xyz/sdk
Version:
The official SDK for the Hyperlane Network
116 lines • 4.91 kB
JavaScript
import { ProtocolType, objFilter, objMap, pick, } from '@hyperlane-xyz/utils';
import { ChainTechnicalStack } from '../metadata/chainMetadataTypes.js';
import { MinimalProviderRegistry, } from './MinimalProviderRegistry.js';
import { MultiProvider } from './MultiProvider.js';
import { PROTOCOL_TO_DEFAULT_PROVIDER_TYPE, ProviderType, } from './ProviderType.js';
import { defaultZKSyncProviderBuilder } from './builders/zksync.js';
import { estimateTransactionFee, } from './transactionFeeEstimators.js';
export function wrapMultiProviderProviders(chainMetadata, providers) {
// CAST: objMap preserves the chain keys, but its generic return type does not
// narrow back to ChainMap<TypedProvider>.
return objMap(providers, (chain, provider) => ({
type: chainMetadata[chain]?.technicalStack === ChainTechnicalStack.ZkSync
? ProviderType.ZkSync
: ProviderType.EthersV5,
provider,
}));
}
function wrapMultiProviderBuilder(providerBuilder) {
return (urls, chainId) => ({
type: ProviderType.EthersV5,
provider: providerBuilder(urls, chainId),
});
}
function unwrapEthersProviderBuilder(providerBuilder) {
if (!providerBuilder)
return undefined;
return (urls, chainId) => {
const provider = providerBuilder(urls, chainId);
if (provider.type !== ProviderType.EthersV5) {
throw new Error(`Cannot convert ${provider.type} builder into a MultiProvider EthersV5 builder`);
}
return provider.provider;
};
}
export function createAdapterFromMultiProvider(AdapterClass, mp, options) {
const adapterOptions =
// CAST: preserve adapter-specific option fields while injecting the bridged builder map.
{
...options,
providerBuilders: {
...options?.providerBuilders,
[ProviderType.EthersV5]: wrapMultiProviderBuilder(mp.providerBuilder),
[ProviderType.ZkSync]: defaultZKSyncProviderBuilder,
},
};
const newMp = new AdapterClass(mp.metadata, adapterOptions);
newMp.setProviders(wrapMultiProviderProviders(mp.metadata, mp.providers));
return newMp;
}
export class MultiProviderAdapter extends MinimalProviderRegistry {
options;
getDefaultProviderType(chainNameOrId) {
const metadata = this.tryGetChainMetadata(chainNameOrId);
if (!metadata)
return undefined;
if (metadata.protocol === ProtocolType.Ethereum &&
metadata.technicalStack === ChainTechnicalStack.ZkSync) {
return ProviderType.ZkSync;
}
if (metadata.protocol === ProtocolType.Unknown)
return undefined;
return PROTOCOL_TO_DEFAULT_PROVIDER_TYPE[metadata.protocol];
}
constructor(chainMetadata, options = {}) {
super(chainMetadata, options);
this.options = options;
}
static fromMultiProvider(mp, options = {}) {
return createAdapterFromMultiProvider(MultiProviderAdapter, mp, options);
}
tryGetProvider(chainNameOrId, type) {
return super.tryGetProvider(chainNameOrId, type ?? this.getDefaultProviderType(chainNameOrId));
}
toMultiProvider(options) {
const newMp = new MultiProvider(this.metadata, {
...options,
providerBuilder: options?.providerBuilder ||
unwrapEthersProviderBuilder(this.providerBuilders[ProviderType.EthersV5]),
});
const providers = objMap(this.providers, (_, typeToProviders) => typeToProviders[ProviderType.EthersV5]?.provider);
const filteredProviders = objFilter(providers, (_, p) => !!p);
newMp.setProviders(filteredProviders);
return newMp;
}
extendChainMetadata(additionalMetadata) {
const newMetadata = super.extendChainMetadata(additionalMetadata).metadata;
return new MultiProviderAdapter(newMetadata, {
...this.options,
providers: this.providers,
providerBuilders: this.providerBuilders,
});
}
intersect(chains, throwIfNotSubset = false) {
const { intersection, result } = super.intersect(chains, throwIfNotSubset);
return {
intersection,
result: new MultiProviderAdapter(result.metadata, {
...this.options,
providers: pick(this.providers, intersection),
providerBuilders: this.providerBuilders,
}),
};
}
estimateTransactionFee({ chainNameOrId, transaction, sender, senderPubKey, }) {
const provider = this.getProvider(chainNameOrId, transaction.type);
const chainMetadata = this.getChainMetadata(chainNameOrId);
return estimateTransactionFee({
transaction,
provider,
chainMetadata,
sender,
senderPubKey,
});
}
}
//# sourceMappingURL=MultiProviderAdapter.js.map