Skip to content

Commit b591ea5

Browse files
committed
refactor: prune unused graph-first warp surface
1 parent 5b0de06 commit b591ea5

6 files changed

Lines changed: 135 additions & 292 deletions

File tree

typescript/sdk/src/index.ts

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -924,11 +924,6 @@ export {
924924
WarpCoreFeeEstimate,
925925
} from './warp/types.js';
926926
export { WarpCore, WarpCoreOptions } from './warp/WarpCore.js';
927-
export {
928-
WarpRouteGraph,
929-
buildWarpRouteTokens,
930-
mapWarpRouteTokens,
931-
} from './warp/WarpRouteGraph.js';
932927
export { EvmTimelockReader } from './timelock/evm/EvmTimelockReader.js';
933928
export { EvmTimelockDeployer } from './timelock/evm/EvmTimelockDeployer.js';
934929
export {

typescript/sdk/src/providers/ConfiguredMultiProtocolProvider.ts

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,15 @@ export interface ConfiguredMultiProtocolProviderOptions {
4747
providerBuilders?: Partial<ProviderBuilderMap>;
4848
}
4949

50+
export function wrapMultiProviderProviders<MetaExt = {}>(
51+
providers: MultiProvider<MetaExt>['providers'],
52+
): ChainMap<TypedProvider> {
53+
return objMap(providers, (_, provider) => ({
54+
type: ProviderType.EthersV5,
55+
provider,
56+
})) as ChainMap<TypedProvider>;
57+
}
58+
5059
export class ConfiguredMultiProtocolProvider<
5160
MetaExt = {},
5261
> extends ChainMetadataManager<MetaExt> {
@@ -77,13 +86,7 @@ export class ConfiguredMultiProtocolProvider<
7786
mp.metadata,
7887
options,
7988
);
80-
81-
const typedProviders = objMap(mp.providers, (_, provider) => ({
82-
type: ProviderType.EthersV5,
83-
provider,
84-
})) as ChainMap<TypedProvider>;
85-
86-
newMp.setProviders(typedProviders);
89+
newMp.setProviders(wrapMultiProviderProviders(mp.providers));
8790
return newMp;
8891
}
8992

typescript/sdk/src/providers/MultiProtocolProvider.ts

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import type { ChainMap, ChainName } from '../types.js';
77
import {
88
ConfiguredMultiProtocolProvider,
99
ConfiguredMultiProtocolProviderOptions,
10+
wrapMultiProviderProviders,
1011
} from './ConfiguredMultiProtocolProvider.js';
1112
import { MultiProvider } from './MultiProvider.js';
1213
import { ProviderType, TypedProvider } from './ProviderType.js';
@@ -27,17 +28,7 @@ export class MultiProtocolProvider<
2728
options: MultiProtocolProviderOptions = {},
2829
): MultiProtocolProvider<MetaExt> {
2930
const newMp = new MultiProtocolProvider<MetaExt>(mp.metadata, options);
30-
newMp.setProviders(
31-
Object.fromEntries(
32-
Object.entries(mp.providers).map(([chain, provider]) => [
33-
chain,
34-
{
35-
type: ProviderType.EthersV5,
36-
provider,
37-
},
38-
]),
39-
) as ChainMap<TypedProvider>,
40-
);
31+
newMp.setProviders(wrapMultiProviderProviders(mp.providers));
4132
return newMp;
4233
}
4334

typescript/sdk/src/warp/WarpCore.test.ts

Lines changed: 0 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,11 @@ import { MultiProtocolProvider } from '../providers/MultiProtocolProvider.js';
1818
import { ProviderType } from '../providers/ProviderType.js';
1919
import { Token } from '../token/Token.js';
2020
import { TokenAmount } from '../token/TokenAmount.js';
21-
import { TokenMetadata } from '../token/TokenMetadata.js';
2221
import { TokenStandard } from '../token/TokenStandard.js';
2322
import { InterchainGasQuote } from '../token/adapters/ITokenAdapter.js';
2423
import { ChainName } from '../types.js';
2524

2625
import { WarpCore } from './WarpCore.js';
27-
import { WarpRouteGraph } from './WarpRouteGraph.js';
2826
import { WarpTxCategory } from './types.js';
2927

3028
const MOCK_LOCAL_QUOTE = { gasUnits: 2_000n, gasPrice: 100, fee: 200_000n };
@@ -64,29 +62,10 @@ describe('WarpCore', () => {
6462
const exampleConfig = yamlParse(
6563
fs.readFileSync('./src/warp/test-warp-core-config.yaml', 'utf-8'),
6664
);
67-
const routeGraph = WarpRouteGraph.FromConfig(multiProvider, exampleConfig);
6865
const fromConfig = WarpCore.FromConfig(multiProvider, exampleConfig);
69-
const fromRouteGraph = WarpCore.FromRouteGraph(
70-
routeGraph,
71-
exampleConfig.options,
72-
);
7366
expect(fromArgs).to.be.instanceOf(WarpCore);
74-
expect(routeGraph).to.be.instanceOf(WarpRouteGraph);
7567
expect(fromConfig).to.be.instanceOf(WarpCore);
76-
expect(fromRouteGraph).to.be.instanceOf(WarpCore);
77-
expect(routeGraph.tokens[0]).to.be.instanceOf(TokenMetadata);
7868
expect(fromConfig.tokens.length).to.equal(exampleConfig.tokens.length);
79-
expect(fromRouteGraph.tokens.length).to.equal(exampleConfig.tokens.length);
80-
expect(fromRouteGraph.tokens[0]).to.be.instanceOf(Token);
81-
expect(
82-
fromRouteGraph.tokens[0]?.getConnections(),
83-
).to.have.length.greaterThan(0);
84-
expect(fromRouteGraph.localFeeConstants).to.deep.equal(
85-
fromConfig.localFeeConstants,
86-
);
87-
expect(fromRouteGraph.interchainFeeConstants).to.deep.equal(
88-
fromConfig.interchainFeeConstants,
89-
);
9069

9170
warpCore = fromConfig;
9271
[

typescript/sdk/src/warp/WarpCore.ts

Lines changed: 123 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ import {
1616
} from '@hyperlane-xyz/utils';
1717
import { Keypair } from '@solana/web3.js';
1818

19-
import type { ChainMetadata } from '../metadata/chainMetadataTypes.js';
2019
import type { ConfiguredMultiProtocolProvider as MultiProtocolProvider } from '../providers/ConfiguredMultiProtocolProvider.js';
2120
import { ProviderType } from '../providers/ProviderType.js';
2221
import {
@@ -26,7 +25,7 @@ import {
2625
import { IToken } from '../token/IToken.js';
2726
import { Token } from '../token/Token.js';
2827
import { TokenAmount } from '../token/TokenAmount.js';
29-
import { TokenMetadata } from '../token/TokenMetadata.js';
28+
import { parseTokenConnectionId } from '../token/TokenConnection.js';
3029
import {
3130
LOCKBOX_STANDARDS,
3231
MINT_LIMITED_STANDARDS,
@@ -44,7 +43,7 @@ import {
4443
IHypXERC20Adapter,
4544
InterchainGasQuote,
4645
} from '../token/adapters/ITokenAdapter.js';
47-
import { ChainNameOrId } from '../types.js';
46+
import { ChainName, ChainNameOrId } from '../types.js';
4847

4948
import {
5049
FeeConstantConfig,
@@ -54,7 +53,6 @@ import {
5453
WarpTxCategory,
5554
WarpTypedTransaction,
5655
} from './types.js';
57-
import { WarpRouteGraph, buildWarpRouteTokens } from './WarpRouteGraph.js';
5856

5957
export interface WarpCoreOptions {
6058
logger?: Logger;
@@ -63,7 +61,9 @@ export interface WarpCoreOptions {
6361
routeBlacklist?: RouteBlacklist;
6462
}
6563

66-
export class WarpCore extends WarpRouteGraph<Token> {
64+
export class WarpCore {
65+
public readonly multiProvider: MultiProtocolProvider<{ mailbox?: Address }>;
66+
public readonly tokens: Token[];
6767
public readonly localFeeConstants: FeeConstantConfig;
6868
public readonly interchainFeeConstants: FeeConstantConfig;
6969
public readonly routeBlacklist: RouteBlacklist;
@@ -74,7 +74,8 @@ export class WarpCore extends WarpRouteGraph<Token> {
7474
tokens: Token[],
7575
options?: WarpCoreOptions,
7676
) {
77-
super(multiProvider, tokens);
77+
this.multiProvider = multiProvider;
78+
this.tokens = tokens;
7879
this.localFeeConstants = options?.localFeeConstants || [];
7980
this.interchainFeeConstants = options?.interchainFeeConstants || [];
8081
this.routeBlacklist = options?.routeBlacklist || [];
@@ -95,23 +96,40 @@ export class WarpCore extends WarpRouteGraph<Token> {
9596
config: unknown,
9697
): WarpCore {
9798
const parsedConfig = WarpCoreConfigSchema.parse(config);
98-
const routeGraph = new WarpRouteGraph(
99-
multiProvider,
100-
buildWarpRouteTokens(parsedConfig, (token) => new TokenMetadata(token)),
99+
const tokens = parsedConfig.tokens.map(
100+
(token) =>
101+
new Token({
102+
...token,
103+
addressOrDenom: token.addressOrDenom || '',
104+
connections: undefined,
105+
}),
101106
);
102-
return WarpCore.FromRouteGraph(routeGraph, parsedConfig.options);
103-
}
104107

105-
static FromRouteGraph(
106-
routeGraph: WarpRouteGraph,
107-
options?: WarpCoreOptions,
108-
): WarpCore {
109-
const tokens = routeGraph.mapTokens((token) => new Token(token)).tokens;
110-
return new WarpCore(routeGraph.multiProvider, tokens, options);
111-
}
108+
parsedConfig.tokens.forEach((config, i) => {
109+
for (const connection of config.connections || []) {
110+
const token1 = tokens[i];
111+
assert(token1, `Token config missing at index ${i}`);
112+
const { chainName, addressOrDenom } = parseTokenConnectionId(
113+
connection.token,
114+
);
115+
const token2 = tokens.find(
116+
(token) =>
117+
token.chainName === chainName &&
118+
token.addressOrDenom === addressOrDenom &&
119+
(!token1.warpRouteId || token.warpRouteId === token1.warpRouteId),
120+
);
121+
assert(
122+
token2,
123+
`Connected token not found: ${chainName} ${addressOrDenom}`,
124+
);
125+
token1.addConnection({
126+
...connection,
127+
token: token2,
128+
});
129+
}
130+
});
112131

113-
protected override createNativeToken(chainMetadata: ChainMetadata): Token {
114-
return Token.FromChainMetadataNativeToken(chainMetadata);
132+
return new WarpCore(multiProvider, tokens, parsedConfig.options);
115133
}
116134

117135
/**
@@ -1253,6 +1271,91 @@ export class WarpCore extends WarpRouteGraph<Token> {
12531271
return null;
12541272
}
12551273

1274+
protected resolveDestinationToken({
1275+
originToken,
1276+
destination,
1277+
destinationToken,
1278+
}: {
1279+
originToken: IToken;
1280+
destination: ChainNameOrId;
1281+
destinationToken?: IToken;
1282+
}): IToken {
1283+
const destinationName = this.multiProvider.getChainName(destination);
1284+
const destinationCandidates = originToken
1285+
.getConnections()
1286+
.filter((connection) => connection.token.chainName === destinationName)
1287+
.map((connection) => connection.token);
1288+
1289+
assert(
1290+
destinationCandidates.length > 0,
1291+
`No connection found for ${destinationName}`,
1292+
);
1293+
1294+
if (destinationToken) {
1295+
assert(
1296+
destinationToken.chainName === destinationName,
1297+
`Destination token chain mismatch for ${destinationName}`,
1298+
);
1299+
const matchedToken = destinationCandidates.find(
1300+
(candidate) =>
1301+
candidate.equals(destinationToken) ||
1302+
candidate.addressOrDenom.toLowerCase() ===
1303+
destinationToken.addressOrDenom.toLowerCase(),
1304+
);
1305+
assert(
1306+
matchedToken,
1307+
`Destination token ${destinationToken.addressOrDenom} is not connected from ${originToken.chainName} to ${destinationName}`,
1308+
);
1309+
return matchedToken;
1310+
}
1311+
1312+
assert(
1313+
destinationCandidates.length === 1,
1314+
`Ambiguous route to ${destinationName}; specify destination token`,
1315+
);
1316+
return destinationCandidates[0];
1317+
}
1318+
1319+
findToken(
1320+
chainName: ChainName,
1321+
addressOrDenom?: Address | string,
1322+
): Token | null {
1323+
if (!addressOrDenom) return null;
1324+
1325+
const results = this.tokens.filter(
1326+
(token) =>
1327+
token.chainName === chainName &&
1328+
token.addressOrDenom.toLowerCase() === addressOrDenom.toLowerCase(),
1329+
);
1330+
1331+
if (results.length === 1) return results[0];
1332+
1333+
if (results.length > 1)
1334+
throw new Error(`Ambiguous token search results for ${addressOrDenom}`);
1335+
1336+
const chainMetadata = this.multiProvider.getChainMetadata(chainName);
1337+
if (chainMetadata.nativeToken?.denom === addressOrDenom) {
1338+
return Token.FromChainMetadataNativeToken(chainMetadata);
1339+
}
1340+
1341+
return null;
1342+
}
1343+
1344+
getTokenChains(): ChainName[] {
1345+
return [...new Set(this.tokens.map((token) => token.chainName)).values()];
1346+
}
1347+
1348+
getTokensForChain(chainName: ChainName): Token[] {
1349+
return this.tokens.filter((token) => token.chainName === chainName);
1350+
}
1351+
1352+
getTokensForRoute(origin: ChainName, destination: ChainName): Token[] {
1353+
return this.tokens.filter(
1354+
(token) =>
1355+
token.chainName === origin && token.getConnectionForChain(destination),
1356+
);
1357+
}
1358+
12561359
/**
12571360
* Ensure the sender has sufficient balances for transfer and interchain gas
12581361
*/

0 commit comments

Comments
 (0)