Skip to content

Commit 06ca1a0

Browse files
feat: expand bridge transaction history using relay API (#122)
Closes: #120 Added method that returns transactions using relay protocol given an address --------- Co-authored-by: BeroBurny <[email protected]>
1 parent 9345c72 commit 06ca1a0

File tree

5 files changed

+193
-4
lines changed

5 files changed

+193
-4
lines changed

packages/sdk/src/helpers/getBridgeHistory.ts

Lines changed: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,16 @@
11
import { Environment } from "../enums";
2+
import type { RelayRequest } from "../relay";
3+
import { getRequests } from "../relay";
4+
import { RELAY_STATUSES_MAPPING } from "../relay/constants";
25
import { getTransfers } from "../sygma/api";
36
import type { Status, SygmaTransfer } from "../sygma/types";
47
import type { Address } from "../types";
58

69
interface History {
710
originTx: string;
8-
originName: string;
11+
originChainId: number;
912
destinationTx?: string;
10-
destinationName: string;
13+
destinationChainId: number;
1114
amount: string;
1215
tokenSymbol: string;
1316
status: Status;
@@ -16,15 +19,33 @@ interface History {
1619
function handleSygmaResponseEntry(entry: SygmaTransfer): History {
1720
return {
1821
originTx: entry.deposit?.txHash || "0x0",
19-
originName: entry.fromDomain.name,
22+
originChainId: Number(entry.fromDomain.id),
2023
destinationTx: entry.execution?.txHash,
21-
destinationName: entry.toDomain.name,
24+
destinationChainId: Number(entry.toDomain.name),
2225
amount: entry.amount,
2326
tokenSymbol: entry.fee.tokenSymbol,
2427
status: entry.status,
2528
};
2629
}
2730

31+
function handleRelayResponseEntry(entry: RelayRequest): History {
32+
// * mapping statuses from relay to "sprinter" statuses
33+
// * inTxs and outTxs contain information about the
34+
// * transfer. e.g chain ID and amount of tokens
35+
const status = RELAY_STATUSES_MAPPING.get(entry.status);
36+
// ! throw error if data is not available
37+
if (!status || entry.data.inTxs.length <= 0 || entry.data.outTxs.length <= 0)
38+
throw new Error("Missing transaction information");
39+
return {
40+
originTx: entry.data.inTxs[0].hash,
41+
originChainId: entry.data.inTxs[0].chainId,
42+
destinationChainId: entry.data.outTxs[0].chainId,
43+
amount: entry.data.metadata.currencyIn.amountFormatted,
44+
tokenSymbol: entry.data.currencyObject.symbol,
45+
status,
46+
};
47+
}
48+
2849
/**
2950
* Returns bridging history
3051
* for an address
@@ -42,5 +63,11 @@ export async function getBridgeHistory(
4263
sygmaTransfers.map((transfer) => handleSygmaResponseEntry(transfer)),
4364
);
4465

66+
transactions.push(
67+
...(await getRequests(address, environment).then((response) =>
68+
response.requests.map((request) => handleRelayResponseEntry(request)),
69+
)),
70+
);
71+
4572
return transactions;
4673
}

packages/sdk/src/relay/api.ts

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import type { Environment } from "../enums";
2+
3+
import { RELAY_API_ENDPOINTS } from "./constants";
4+
import type { RelayRequestsResponse } from "./types";
5+
6+
/**
7+
* Returns list of transfers from
8+
* Relay protocol
9+
*
10+
* https://docs.relay.link/references/api/get-requests?playground=open
11+
* @param {Environment} environment
12+
*/
13+
export async function getRequests(
14+
address: string,
15+
environment: Environment,
16+
): Promise<RelayRequestsResponse> {
17+
const requestsPath = `/requests/v2`;
18+
const url = new URL(RELAY_API_ENDPOINTS[environment], requestsPath);
19+
url.searchParams.set("user", address);
20+
21+
const response: RelayRequestsResponse = await fetch(url.toString()).then(
22+
(response): Promise<RelayRequestsResponse> => response.json(),
23+
);
24+
25+
return response;
26+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import { Environment } from "../enums";
2+
import { Status } from "../sygma";
3+
4+
import { RelayRequestStatus } from "./types";
5+
6+
export const RELAY_API_ENDPOINTS: Record<Environment, string> = {
7+
[Environment.MAINNET]: "https://api.relay.link",
8+
[Environment.TESTNET]: "https://api.testnets.relay.link",
9+
};
10+
11+
export const RELAY_STATUSES_MAPPING = new Map<RelayRequestStatus, Status>([
12+
[RelayRequestStatus.Refund, Status.failed],
13+
[RelayRequestStatus.Delayed, Status.pending],
14+
[RelayRequestStatus.Waiting, Status.pending],
15+
[RelayRequestStatus.Failure, Status.failed],
16+
[RelayRequestStatus.Pending, Status.pending],
17+
[RelayRequestStatus.Success, Status.executed],
18+
]);

packages/sdk/src/relay/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
export * from "./api";
2+
export * from "./types";

packages/sdk/src/relay/types.ts

Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
/**
2+
* * All types extracted from official relay
3+
* * documentation which can be found here
4+
* * https://docs.relay.link/references/api/get-requests#parameter-user
5+
*/
6+
7+
enum FailureReason {
8+
UNKNOWN = "UNKNOWN",
9+
AMOUNT_TOO_LOW_TO_REFUND = "AMOUNT_TOO_LOW_TO_REFUND",
10+
DEPOSIT_ADDRESS_MISMATCH = "DEPOSIT_ADDRESS_MISMATCH",
11+
DEPOSIT_CHAIN_MISMATCH = "DEPOSIT_CHAIN_MISMATCH",
12+
NA = "N/A",
13+
}
14+
15+
export enum RelayRequestStatus {
16+
Refund = "refund",
17+
Delayed = "delayed",
18+
Waiting = "waiting",
19+
Failure = "failure",
20+
Pending = "pending",
21+
Success = "success",
22+
}
23+
24+
interface Currency {
25+
name: string;
26+
symbol: string;
27+
address: string;
28+
chainId: number;
29+
decimals: number;
30+
metadata: {
31+
isNative: boolean;
32+
logoURI: string;
33+
verified: boolean;
34+
};
35+
}
36+
37+
interface Fees {
38+
fixed: string;
39+
gas: string;
40+
price: string;
41+
}
42+
43+
interface TransactionData {
44+
fee: string;
45+
// * relay documentation marks these as any
46+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
47+
data: any;
48+
// * relay documentation marks these as any
49+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
50+
stateChanges: any;
51+
hash: string;
52+
block: number;
53+
type: string;
54+
chainId: number;
55+
timestamp: number;
56+
}
57+
58+
export interface RelayRequest {
59+
id: string;
60+
status: RelayRequestStatus;
61+
user: string;
62+
recipient: string;
63+
createdAt: string;
64+
updatedAt: string;
65+
66+
data: {
67+
failReason: FailureReason;
68+
fees: Fees;
69+
feesUsd: Fees;
70+
inTxs: Array<TransactionData>;
71+
currency: string;
72+
currencyObject: Currency;
73+
feeCurrency: string;
74+
feeCurrencyObject: Currency;
75+
appFees: Array<{
76+
amount: string;
77+
recipient: string;
78+
}>;
79+
metadata: {
80+
sender: string;
81+
recipient: string;
82+
currencyIn: {
83+
currency: Currency;
84+
amount: string;
85+
amountFormatted: string;
86+
amountUsd: string;
87+
minimumAmount: string;
88+
};
89+
currencyOut: {
90+
currency: Currency;
91+
amount: string;
92+
amountFormatted: string;
93+
amountUsd: string;
94+
minimumAmount: string;
95+
};
96+
rate: string;
97+
};
98+
price: string;
99+
usesExternalLiquidity: boolean;
100+
timeEstimate: number;
101+
outTxs: Array<TransactionData>;
102+
103+
refundCurrencyData: {
104+
amount: string;
105+
amountFormatted: string;
106+
amountUsd: string;
107+
currency: Currency;
108+
minimumAmount: string;
109+
};
110+
};
111+
}
112+
113+
export interface RelayRequestsResponse {
114+
continuation: string;
115+
requests: Array<RelayRequest>;
116+
}

0 commit comments

Comments
 (0)