-
Notifications
You must be signed in to change notification settings - Fork 21
/
utils.ts
159 lines (148 loc) · 5.55 KB
/
utils.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
import { ExplorerUrl, IndexerUrl } from './constants.js';
import type {
EnvironmentMetadata,
Route,
RouteIndexerType,
TransferStatus,
TransferStatusResponse,
} from './types/index.js';
import { Environment } from './types/index.js';
import { Config } from './index.js';
/**
* @@description Get the status of a transfer using transaction hash and optionally domain id
*/
export async function getTransferStatusData(
environment: Environment,
txHash: string,
): Promise<TransferStatusResponse[]>;
export async function getTransferStatusData(
environment: Environment,
txHash: string,
domainId: string,
): Promise<TransferStatusResponse>;
export async function getTransferStatusData(
environment: Environment,
txHash: string,
domainId?: string,
): Promise<TransferStatusResponse | TransferStatusResponse[]> {
let url: string;
let explorerUrl: string;
if (environment === Environment.TESTNET) {
url = `${IndexerUrl.TESTNET}/api/transfers/txHash/${txHash}`;
explorerUrl = `${ExplorerUrl.TESTNET}/transfer/${txHash}`;
} else if (environment === Environment.MAINNET) {
url = `${IndexerUrl.MAINNET}/api/transfers/txHash/${txHash}`;
explorerUrl = `${ExplorerUrl.MAINNET}/transfer/${txHash}`;
} else {
throw new Error('Invalid environment');
}
try {
const response = await fetch(url);
const data = (await response.json()) as (Record<string, unknown> & {
status: TransferStatus;
toDomainId: number;
fromDomainId: number;
})[];
if (domainId) {
const record = data.find(data => data.toDomainId === Number(domainId));
if (!record)
throw new Error(`Transfer with txHash: ${txHash} for domain id: ${domainId} not found.`);
return {
status: record.status,
fromDomainId: record.fromDomainId,
toDomainId: record.toDomainId,
explorerUrl,
};
}
return data.map(record => ({
status: record.status,
fromDomainId: record.fromDomainId,
toDomainId: record.toDomainId,
explorerUrl,
}));
} catch (err) {
if (err instanceof Error) {
throw new Error(`Failed to fetch transfer status because of: ${err.message}`);
} else {
throw new Error('Something went wrong while fetching transfer status');
}
}
}
/**
* Retrieves the environment metadata
*
* This function accepts an environment from the `Environment` enum as its parameter and returns the corresponding environment metadata.
* If the specified environment does not have associated metadata in `EnvironmentMetadataConfig`, the function throws an error.
*
* @param environment - The environment key from the `Environment` enum.
*
* @returns {EnvironmentMetadata} An object mapping domain IDs to {DomainMetadata}.
*
* @throws {Error} Throws an error if the environment does not have defined metadata.
*
*/
export async function getEnvironmentMetadata(
environment: Environment,
): Promise<EnvironmentMetadata> {
try {
const url = `${getIndexerURL(environment)}/api/domains/metadata`;
const response = await fetch(url);
return (await response.json()) as EnvironmentMetadata;
} catch (err) {
if (err instanceof Error) {
throw new Error(`Failed to fetch env metadata because of: ${err.message}`);
} else {
throw new Error('Something went wrong while fetching env metadata');
}
}
}
/**
* Fetches route information based on the source chain ID and resource type.
*
* This function queries the configured indexer URL based on the specified environment (TESTNET or MAINNET)
* to retrieve route data.
*
* @param {Environment} environment - The Sygma environment to use (TESTNET or MAINNET).
* @param {number} sourceChainId - The ID of the source chain from which routes are being fetched.
* @param {'fungible' | 'gmp' | 'all'} type - The type of the resource for which routes are being fetched. Can be 'fungible', 'gmp', or 'all'.
* @returns {Promise<Route[]>} A promise that resolves to an array of Route objects, each representing a route from the source domain to a target domain for a specific resource.
* @throws {Error} Throws an error if an invalid environment is specified, if there's a network or server issue during the fetch operation, or if the fetched data cannot be processed correctly.
*/
export async function getRoutes(
environment: Environment,
sourceChainId: number,
type?: 'fungible' | 'gmp',
): Promise<Route[]> {
try {
const config = new Config();
await config.init(sourceChainId, environment);
const indexerUrl = getIndexerURL(environment);
const typeQuery = type ? `?resourceType=${type}` : '';
const url = `${indexerUrl}/api/routes/from/${config.getSourceDomainConfig().id}${typeQuery}`;
const response = await fetch(url);
const data = (await response.json()) as { routes: RouteIndexerType[] };
return data.routes.map(route => {
const resource = config.getDomainResources().find(r => r.resourceId === route.resourceId)!;
return {
fromDomain: config.getSourceDomainConfig(),
toDomain: config.getDomainConfig(Number(route.toDomainId)),
resource: resource,
};
});
} catch (err) {
if (err instanceof Error) {
throw new Error(`Failed to fetch routes because of: ${err.message}`);
} else {
throw new Error('Something went wrong while fetching routes');
}
}
}
function getIndexerURL(environment: Environment): string {
if (environment === Environment.TESTNET) {
return IndexerUrl.TESTNET;
} else if (environment === Environment.MAINNET) {
return IndexerUrl.MAINNET;
} else {
throw new Error('Invalid environment');
}
}