Skip to content

Commit f197d02

Browse files
committed
fix(contract-manager): preserve nativeToken during chain serialization
1 parent b7b2968 commit f197d02

2 files changed

Lines changed: 183 additions & 0 deletions

File tree

contract_manager/src/core/chains.ts

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -263,6 +263,9 @@ export class CosmWasmChain extends Chain {
263263
gasPrice: this.gasPrice,
264264
id: this.id,
265265
mainnet: this.mainnet,
266+
...(this.nativeToken !== undefined && {
267+
nativeToken: this.nativeToken,
268+
}),
266269
prefix: this.prefix,
267270
type: CosmWasmChain.type,
268271
wormholeChainName: this.wormholeChainName,
@@ -441,6 +444,9 @@ export class SuiChain extends Chain {
441444
endpointType: this.endpointType,
442445
id: this.id,
443446
mainnet: this.mainnet,
447+
...(this.nativeToken !== undefined && {
448+
nativeToken: this.nativeToken,
449+
}),
444450
rpcUrl: this.rpcUrl,
445451
type: SuiChain.type,
446452
wormholeChainName: this.wormholeChainName,
@@ -936,6 +942,9 @@ export class IotaChain extends Chain {
936942
endpointType: this.endpointType,
937943
id: this.id,
938944
mainnet: this.mainnet,
945+
...(this.nativeToken !== undefined && {
946+
nativeToken: this.nativeToken,
947+
}),
939948
rpcUrl: this.rpcUrl,
940949
type: IotaChain.type,
941950
wormholeChainName: this.wormholeChainName,
@@ -1013,6 +1022,9 @@ export class SvmChain extends Chain {
10131022
return {
10141023
id: this.id,
10151024
mainnet: this.mainnet,
1025+
...(this.nativeToken !== undefined && {
1026+
nativeToken: this.nativeToken,
1027+
}),
10161028
rpcUrl: this.rpcUrl,
10171029
type: SvmChain.type,
10181030
wormholeChainName: this.wormholeChainName,
@@ -1131,6 +1143,9 @@ export class EvmChain extends Chain {
11311143
return {
11321144
id: this.id,
11331145
mainnet: this.mainnet,
1146+
...(this.nativeToken !== undefined && {
1147+
nativeToken: this.nativeToken,
1148+
}),
11341149
networkId: this.networkId,
11351150
rpcUrl: this.rpcUrl,
11361151
type: EvmChain.type,
@@ -1311,6 +1326,9 @@ export class AptosChain extends Chain {
13111326
return {
13121327
id: this.id,
13131328
mainnet: this.mainnet,
1329+
...(this.nativeToken !== undefined && {
1330+
nativeToken: this.nativeToken,
1331+
}),
13141332
rpcUrl: this.rpcUrl,
13151333
type: AptosChain.type,
13161334
wormholeChainName: this.wormholeChainName,
@@ -1402,6 +1420,9 @@ export class FuelChain extends Chain {
14021420
gqlUrl: this.gqlUrl,
14031421
id: this.id,
14041422
mainnet: this.mainnet,
1423+
...(this.nativeToken !== undefined && {
1424+
nativeToken: this.nativeToken,
1425+
}),
14051426
type: FuelChain.type,
14061427
wormholeChainName: this.wormholeChainName,
14071428
};
@@ -1519,6 +1540,7 @@ export class TonChain extends Chain {
15191540
wormholeChainName: string,
15201541
nativeToken: TokenId | undefined,
15211542
private rpcUrl: string,
1543+
private networkId: string,
15221544
) {
15231545
super(id, mainnet, wormholeChainName, nativeToken);
15241546
}
@@ -1583,6 +1605,10 @@ export class TonChain extends Chain {
15831605
return {
15841606
id: this.id,
15851607
mainnet: this.mainnet,
1608+
...(this.nativeToken !== undefined && {
1609+
nativeToken: this.nativeToken,
1610+
}),
1611+
networkId: this.networkId,
15861612
rpcUrl: this.rpcUrl,
15871613
type: TonChain.type,
15881614
wormholeChainName: this.wormholeChainName,
@@ -1597,6 +1623,7 @@ export class TonChain extends Chain {
15971623
parsed.wormholeChainName ?? "",
15981624
parsed.nativeToken,
15991625
parsed.rpcUrl ?? "",
1626+
parsed.networkId ?? "",
16001627
);
16011628
}
16021629

@@ -1647,6 +1674,9 @@ export class NearChain extends Chain {
16471674
return {
16481675
id: this.id,
16491676
mainnet: this.mainnet,
1677+
...(this.nativeToken !== undefined && {
1678+
nativeToken: this.nativeToken,
1679+
}),
16501680
networkId: this.networkId,
16511681
rpcUrl: this.rpcUrl,
16521682
type: NearChain.type,
Lines changed: 153 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,153 @@
1+
import { describe, expect, it } from "vitest";
2+
import {
3+
AptosChain,
4+
CosmWasmChain,
5+
EvmChain,
6+
FuelChain,
7+
IotaChain,
8+
NearChain,
9+
SuiChain,
10+
SvmChain,
11+
TonChain,
12+
} from "../src/core/chains";
13+
14+
type ChainFactory = {
15+
fromJson: (parsed: Record<string, unknown>) => {
16+
getNativeToken: () => string | undefined;
17+
toJson: () => Record<string, unknown>;
18+
};
19+
};
20+
21+
describe("Chain Serialization Contract Symmetry", () => {
22+
const chainTestCases = [
23+
{
24+
cls: CosmWasmChain,
25+
name: "CosmWasmChain",
26+
sample: {
27+
endpoint: "http://localhost",
28+
feeDenom: "uosmo",
29+
gasPrice: "0.025",
30+
id: "osmosis",
31+
mainnet: true,
32+
nativeToken: "OSMO",
33+
prefix: "osmo",
34+
type: CosmWasmChain.type,
35+
wormholeChainName: "osmosis",
36+
},
37+
},
38+
{
39+
cls: SuiChain,
40+
name: "SuiChain",
41+
sample: {
42+
endpointType: "json-rpc",
43+
id: "sui",
44+
mainnet: true,
45+
nativeToken: "SUI",
46+
rpcUrl: "http://localhost",
47+
type: SuiChain.type,
48+
wormholeChainName: "sui",
49+
},
50+
},
51+
{
52+
cls: IotaChain,
53+
name: "IotaChain",
54+
sample: {
55+
endpointType: "json-rpc",
56+
id: "iota",
57+
mainnet: true,
58+
nativeToken: "IOTA",
59+
rpcUrl: "http://localhost",
60+
type: IotaChain.type,
61+
wormholeChainName: "iota",
62+
},
63+
},
64+
{
65+
cls: SvmChain,
66+
name: "SvmChain",
67+
sample: {
68+
id: "solana",
69+
mainnet: true,
70+
nativeToken: "SOL",
71+
rpcUrl: "http://localhost",
72+
type: SvmChain.type,
73+
wormholeChainName: "solana",
74+
},
75+
},
76+
{
77+
cls: EvmChain,
78+
name: "EvmChain",
79+
sample: {
80+
id: "ethereum",
81+
mainnet: true,
82+
nativeToken: "ETH",
83+
networkId: 1,
84+
rpcUrl: "http://localhost",
85+
type: EvmChain.type,
86+
},
87+
},
88+
{
89+
cls: AptosChain,
90+
name: "AptosChain",
91+
sample: {
92+
id: "aptos",
93+
mainnet: true,
94+
nativeToken: "APT",
95+
rpcUrl: "http://localhost",
96+
type: AptosChain.type,
97+
wormholeChainName: "aptos",
98+
},
99+
},
100+
{
101+
cls: FuelChain,
102+
name: "FuelChain",
103+
sample: {
104+
gqlUrl: "http://localhost",
105+
id: "fuel",
106+
mainnet: true,
107+
nativeToken: "ETH",
108+
type: FuelChain.type,
109+
wormholeChainName: "fuel_mainnet",
110+
},
111+
},
112+
{
113+
cls: TonChain,
114+
name: "TonChain",
115+
sample: {
116+
id: "ton",
117+
mainnet: true,
118+
nativeToken: "TON",
119+
networkId: "0x1",
120+
rpcUrl: "http://localhost",
121+
type: TonChain.type,
122+
wormholeChainName: "ton_mainnet",
123+
},
124+
},
125+
{
126+
cls: NearChain,
127+
name: "NearChain",
128+
sample: {
129+
id: "near",
130+
mainnet: true,
131+
nativeToken: "NEAR",
132+
networkId: "mainnet",
133+
rpcUrl: "http://localhost",
134+
type: NearChain.type,
135+
wormholeChainName: "near",
136+
},
137+
},
138+
];
139+
140+
for (const { name, cls, sample } of chainTestCases) {
141+
it(`should preserve nativeToken in ${name} through fromJson -> toJson -> fromJson`, () => {
142+
const factory = cls as unknown as ChainFactory;
143+
const chain = factory.fromJson(sample);
144+
expect(chain.getNativeToken()).toEqual(sample.nativeToken);
145+
146+
const json = chain.toJson();
147+
expect(json.nativeToken).toEqual(sample.nativeToken);
148+
149+
const roundTripChain = factory.fromJson(json);
150+
expect(roundTripChain.getNativeToken()).toEqual(sample.nativeToken);
151+
});
152+
}
153+
});

0 commit comments

Comments
 (0)