@vetro-protocol/gateway 1.0.0-beta

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (113) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +106 -0
  3. package/_esm/abi/gatewayAbi.js +185 -0
  4. package/_esm/abi/gatewayAbi.js.map +1 -0
  5. package/_esm/actions/index.js +18 -0
  6. package/_esm/actions/index.js.map +1 -0
  7. package/_esm/actions/public/getMaxWithdraw.js +28 -0
  8. package/_esm/actions/public/getMaxWithdraw.js.map +1 -0
  9. package/_esm/actions/public/getMintFee.js +28 -0
  10. package/_esm/actions/public/getMintFee.js.map +1 -0
  11. package/_esm/actions/public/getPeggedToken.js +23 -0
  12. package/_esm/actions/public/getPeggedToken.js.map +1 -0
  13. package/_esm/actions/public/getRedeemFee.js +28 -0
  14. package/_esm/actions/public/getRedeemFee.js.map +1 -0
  15. package/_esm/actions/public/getRedeemRequest.js +28 -0
  16. package/_esm/actions/public/getRedeemRequest.js.map +1 -0
  17. package/_esm/actions/public/getTreasury.js +23 -0
  18. package/_esm/actions/public/getTreasury.js.map +1 -0
  19. package/_esm/actions/public/getWithdrawalDelay.js +23 -0
  20. package/_esm/actions/public/getWithdrawalDelay.js.map +1 -0
  21. package/_esm/actions/public/getWithdrawalDelayEnabled.js +23 -0
  22. package/_esm/actions/public/getWithdrawalDelayEnabled.js.map +1 -0
  23. package/_esm/actions/public/index.js +12 -0
  24. package/_esm/actions/public/index.js.map +1 -0
  25. package/_esm/actions/public/isInstantRedeemWhitelisted.js +28 -0
  26. package/_esm/actions/public/isInstantRedeemWhitelisted.js.map +1 -0
  27. package/_esm/actions/public/previewDeposit.js +35 -0
  28. package/_esm/actions/public/previewDeposit.js.map +1 -0
  29. package/_esm/actions/public/previewRedeem.js +35 -0
  30. package/_esm/actions/public/previewRedeem.js.map +1 -0
  31. package/_esm/actions/wallet/cancelRedeemRequest.js +89 -0
  32. package/_esm/actions/wallet/cancelRedeemRequest.js.map +1 -0
  33. package/_esm/actions/wallet/deposit.js +193 -0
  34. package/_esm/actions/wallet/deposit.js.map +1 -0
  35. package/_esm/actions/wallet/redeem.js +226 -0
  36. package/_esm/actions/wallet/redeem.js.map +1 -0
  37. package/_esm/actions/wallet/requestRedeem.js +153 -0
  38. package/_esm/actions/wallet/requestRedeem.js.map +1 -0
  39. package/_esm/gatewayAddresses.js +18 -0
  40. package/_esm/gatewayAddresses.js.map +1 -0
  41. package/_esm/index.js +30 -0
  42. package/_esm/index.js.map +1 -0
  43. package/_esm/types.js +2 -0
  44. package/_esm/types.js.map +1 -0
  45. package/_esm/utils/isAddressValid.js +3 -0
  46. package/_esm/utils/isAddressValid.js.map +1 -0
  47. package/_types/abi/gatewayAbi.d.ts +252 -0
  48. package/_types/abi/gatewayAbi.d.ts.map +1 -0
  49. package/_types/actions/index.d.ts +16 -0
  50. package/_types/actions/index.d.ts.map +1 -0
  51. package/_types/actions/public/getMaxWithdraw.d.ts +6 -0
  52. package/_types/actions/public/getMaxWithdraw.d.ts.map +1 -0
  53. package/_types/actions/public/getMintFee.d.ts +6 -0
  54. package/_types/actions/public/getMintFee.d.ts.map +1 -0
  55. package/_types/actions/public/getPeggedToken.d.ts +5 -0
  56. package/_types/actions/public/getPeggedToken.d.ts.map +1 -0
  57. package/_types/actions/public/getRedeemFee.d.ts +6 -0
  58. package/_types/actions/public/getRedeemFee.d.ts.map +1 -0
  59. package/_types/actions/public/getRedeemRequest.d.ts +6 -0
  60. package/_types/actions/public/getRedeemRequest.d.ts.map +1 -0
  61. package/_types/actions/public/getTreasury.d.ts +5 -0
  62. package/_types/actions/public/getTreasury.d.ts.map +1 -0
  63. package/_types/actions/public/getWithdrawalDelay.d.ts +5 -0
  64. package/_types/actions/public/getWithdrawalDelay.d.ts.map +1 -0
  65. package/_types/actions/public/getWithdrawalDelayEnabled.d.ts +5 -0
  66. package/_types/actions/public/getWithdrawalDelayEnabled.d.ts.map +1 -0
  67. package/_types/actions/public/index.d.ts +12 -0
  68. package/_types/actions/public/index.d.ts.map +1 -0
  69. package/_types/actions/public/isInstantRedeemWhitelisted.d.ts +6 -0
  70. package/_types/actions/public/isInstantRedeemWhitelisted.d.ts.map +1 -0
  71. package/_types/actions/public/previewDeposit.d.ts +7 -0
  72. package/_types/actions/public/previewDeposit.d.ts.map +1 -0
  73. package/_types/actions/public/previewRedeem.d.ts +7 -0
  74. package/_types/actions/public/previewRedeem.d.ts.map +1 -0
  75. package/_types/actions/wallet/cancelRedeemRequest.d.ts +14 -0
  76. package/_types/actions/wallet/cancelRedeemRequest.d.ts.map +1 -0
  77. package/_types/actions/wallet/deposit.d.ts +19 -0
  78. package/_types/actions/wallet/deposit.d.ts.map +1 -0
  79. package/_types/actions/wallet/redeem.d.ts +24 -0
  80. package/_types/actions/wallet/redeem.d.ts.map +1 -0
  81. package/_types/actions/wallet/requestRedeem.d.ts +18 -0
  82. package/_types/actions/wallet/requestRedeem.d.ts.map +1 -0
  83. package/_types/gatewayAddresses.d.ts +8 -0
  84. package/_types/gatewayAddresses.d.ts.map +1 -0
  85. package/_types/index.d.ts +42 -0
  86. package/_types/index.d.ts.map +1 -0
  87. package/_types/types.d.ts +53 -0
  88. package/_types/types.d.ts.map +1 -0
  89. package/_types/utils/isAddressValid.d.ts +3 -0
  90. package/_types/utils/isAddressValid.d.ts.map +1 -0
  91. package/package.json +59 -0
  92. package/src/abi/gatewayAbi.ts +184 -0
  93. package/src/actions/index.ts +18 -0
  94. package/src/actions/public/getMaxWithdraw.ts +40 -0
  95. package/src/actions/public/getMintFee.ts +40 -0
  96. package/src/actions/public/getPeggedToken.ts +33 -0
  97. package/src/actions/public/getRedeemFee.ts +40 -0
  98. package/src/actions/public/getRedeemRequest.ts +40 -0
  99. package/src/actions/public/getTreasury.ts +33 -0
  100. package/src/actions/public/getWithdrawalDelay.ts +33 -0
  101. package/src/actions/public/getWithdrawalDelayEnabled.ts +33 -0
  102. package/src/actions/public/index.ts +11 -0
  103. package/src/actions/public/isInstantRedeemWhitelisted.ts +40 -0
  104. package/src/actions/public/previewDeposit.ts +49 -0
  105. package/src/actions/public/previewRedeem.ts +49 -0
  106. package/src/actions/wallet/cancelRedeemRequest.ts +135 -0
  107. package/src/actions/wallet/deposit.ts +277 -0
  108. package/src/actions/wallet/redeem.ts +321 -0
  109. package/src/actions/wallet/requestRedeem.ts +226 -0
  110. package/src/gatewayAddresses.ts +27 -0
  111. package/src/index.ts +79 -0
  112. package/src/types.ts +60 -0
  113. package/src/utils/isAddressValid.ts +4 -0
@@ -0,0 +1,40 @@
1
+ import { type Address, type Client } from "viem";
2
+ import { readContract } from "viem/actions";
3
+
4
+ import { gatewayAbi } from "../../abi/gatewayAbi.js";
5
+ import { isAddressValid } from "../../utils/isAddressValid.js";
6
+
7
+ export async function getRedeemRequest(
8
+ client: Client,
9
+ parameters: {
10
+ address: Address;
11
+ user: Address;
12
+ },
13
+ ) {
14
+ // Validate client
15
+ if (!client) {
16
+ throw new Error("Client is not defined");
17
+ }
18
+
19
+ // Validate parameters exist
20
+ if (!parameters) {
21
+ throw new Error("Parameters are required");
22
+ }
23
+
24
+ // Validate gateway address
25
+ if (!isAddressValid(parameters.address)) {
26
+ throw new Error("Gateway is invalid");
27
+ }
28
+
29
+ // Validate user address
30
+ if (!isAddressValid(parameters.user)) {
31
+ throw new Error("User is invalid");
32
+ }
33
+
34
+ return readContract(client, {
35
+ abi: gatewayAbi,
36
+ address: parameters.address,
37
+ args: [parameters.user],
38
+ functionName: "getRedeemRequest",
39
+ });
40
+ }
@@ -0,0 +1,33 @@
1
+ import { type Address, type Client } from "viem";
2
+ import { readContract } from "viem/actions";
3
+
4
+ import { gatewayAbi } from "../../abi/gatewayAbi.js";
5
+ import { isAddressValid } from "../../utils/isAddressValid.js";
6
+
7
+ export async function getTreasury(
8
+ client: Client,
9
+ parameters: {
10
+ address: Address;
11
+ },
12
+ ) {
13
+ // Validate client
14
+ if (!client) {
15
+ throw new Error("Client is not defined");
16
+ }
17
+
18
+ // Validate parameters exist
19
+ if (!parameters) {
20
+ throw new Error("Parameters are required");
21
+ }
22
+
23
+ // Validate gateway address
24
+ if (!isAddressValid(parameters.address)) {
25
+ throw new Error("Gateway is invalid");
26
+ }
27
+
28
+ return readContract(client, {
29
+ abi: gatewayAbi,
30
+ address: parameters.address,
31
+ functionName: "treasury",
32
+ });
33
+ }
@@ -0,0 +1,33 @@
1
+ import { type Address, type Client } from "viem";
2
+ import { readContract } from "viem/actions";
3
+
4
+ import { gatewayAbi } from "../../abi/gatewayAbi.js";
5
+ import { isAddressValid } from "../../utils/isAddressValid.js";
6
+
7
+ export async function getWithdrawalDelay(
8
+ client: Client,
9
+ parameters: {
10
+ address: Address;
11
+ },
12
+ ) {
13
+ // Validate client
14
+ if (!client) {
15
+ throw new Error("Client is not defined");
16
+ }
17
+
18
+ // Validate parameters exist
19
+ if (!parameters) {
20
+ throw new Error("Parameters are required");
21
+ }
22
+
23
+ // Validate gateway address
24
+ if (!isAddressValid(parameters.address)) {
25
+ throw new Error("Gateway is invalid");
26
+ }
27
+
28
+ return readContract(client, {
29
+ abi: gatewayAbi,
30
+ address: parameters.address,
31
+ functionName: "withdrawalDelay",
32
+ });
33
+ }
@@ -0,0 +1,33 @@
1
+ import { type Address, type Client } from "viem";
2
+ import { readContract } from "viem/actions";
3
+
4
+ import { gatewayAbi } from "../../abi/gatewayAbi.js";
5
+ import { isAddressValid } from "../../utils/isAddressValid.js";
6
+
7
+ export async function getWithdrawalDelayEnabled(
8
+ client: Client,
9
+ parameters: {
10
+ address: Address;
11
+ },
12
+ ) {
13
+ // Validate client
14
+ if (!client) {
15
+ throw new Error("Client is not defined");
16
+ }
17
+
18
+ // Validate parameters exist
19
+ if (!parameters) {
20
+ throw new Error("Parameters are required");
21
+ }
22
+
23
+ // Validate gateway address
24
+ if (!isAddressValid(parameters.address)) {
25
+ throw new Error("Gateway is invalid");
26
+ }
27
+
28
+ return readContract(client, {
29
+ abi: gatewayAbi,
30
+ address: parameters.address,
31
+ functionName: "withdrawalDelayEnabled",
32
+ });
33
+ }
@@ -0,0 +1,11 @@
1
+ export * from "./getMaxWithdraw.js";
2
+ export * from "./getMintFee.js";
3
+ export * from "./getPeggedToken.js";
4
+ export * from "./getRedeemFee.js";
5
+ export * from "./getRedeemRequest.js";
6
+ export * from "./getTreasury.js";
7
+ export * from "./getWithdrawalDelay.js";
8
+ export * from "./getWithdrawalDelayEnabled.js";
9
+ export * from "./isInstantRedeemWhitelisted.js";
10
+ export * from "./previewDeposit.js";
11
+ export * from "./previewRedeem.js";
@@ -0,0 +1,40 @@
1
+ import { type Address, type Client } from "viem";
2
+ import { readContract } from "viem/actions";
3
+
4
+ import { gatewayAbi } from "../../abi/gatewayAbi.js";
5
+ import { isAddressValid } from "../../utils/isAddressValid.js";
6
+
7
+ export async function isInstantRedeemWhitelisted(
8
+ client: Client,
9
+ parameters: {
10
+ address: Address;
11
+ account: Address;
12
+ },
13
+ ) {
14
+ // Validate client
15
+ if (!client) {
16
+ throw new Error("Client is not defined");
17
+ }
18
+
19
+ // Validate parameters exist
20
+ if (!parameters) {
21
+ throw new Error("Parameters are required");
22
+ }
23
+
24
+ // Validate gateway address
25
+ if (!isAddressValid(parameters.address)) {
26
+ throw new Error("Gateway is invalid");
27
+ }
28
+
29
+ // Validate account address
30
+ if (!isAddressValid(parameters.account)) {
31
+ throw new Error("Account is invalid");
32
+ }
33
+
34
+ return readContract(client, {
35
+ abi: gatewayAbi,
36
+ address: parameters.address,
37
+ args: [parameters.account],
38
+ functionName: "isInstantRedeemWhitelisted",
39
+ });
40
+ }
@@ -0,0 +1,49 @@
1
+ import { type Address, type Client } from "viem";
2
+ import { readContract } from "viem/actions";
3
+
4
+ import { gatewayAbi } from "../../abi/gatewayAbi.js";
5
+ import { isAddressValid } from "../../utils/isAddressValid.js";
6
+
7
+ export async function previewDeposit(
8
+ client: Client,
9
+ parameters: {
10
+ address: Address;
11
+ tokenIn: Address;
12
+ amountIn: bigint;
13
+ },
14
+ ) {
15
+ // Validate client
16
+ if (!client) {
17
+ throw new Error("Client is not defined");
18
+ }
19
+
20
+ // Validate parameters exist
21
+ if (!parameters) {
22
+ throw new Error("Parameters are required");
23
+ }
24
+
25
+ // Validate gateway address
26
+ if (!isAddressValid(parameters.address)) {
27
+ throw new Error("Gateway is invalid");
28
+ }
29
+
30
+ // Validate tokenIn address
31
+ if (!isAddressValid(parameters.tokenIn)) {
32
+ throw new Error("Token is invalid");
33
+ }
34
+
35
+ // Validate amountIn
36
+ if (typeof parameters.amountIn !== "bigint") {
37
+ throw new Error("Amount must be a bigint");
38
+ }
39
+ if (parameters.amountIn <= 0n) {
40
+ throw new Error("Amount must be greater than 0");
41
+ }
42
+
43
+ return readContract(client, {
44
+ abi: gatewayAbi,
45
+ address: parameters.address,
46
+ args: [parameters.tokenIn, parameters.amountIn],
47
+ functionName: "previewDeposit",
48
+ });
49
+ }
@@ -0,0 +1,49 @@
1
+ import { type Address, type Client } from "viem";
2
+ import { readContract } from "viem/actions";
3
+
4
+ import { gatewayAbi } from "../../abi/gatewayAbi.js";
5
+ import { isAddressValid } from "../../utils/isAddressValid.js";
6
+
7
+ export async function previewRedeem(
8
+ client: Client,
9
+ parameters: {
10
+ address: Address;
11
+ tokenOut: Address;
12
+ peggedTokenIn: bigint;
13
+ },
14
+ ) {
15
+ // Validate client
16
+ if (!client) {
17
+ throw new Error("Client is not defined");
18
+ }
19
+
20
+ // Validate parameters exist
21
+ if (!parameters) {
22
+ throw new Error("Parameters are required");
23
+ }
24
+
25
+ // Validate gateway address
26
+ if (!isAddressValid(parameters.address)) {
27
+ throw new Error("Gateway is invalid");
28
+ }
29
+
30
+ // Validate tokenOut address
31
+ if (!isAddressValid(parameters.tokenOut)) {
32
+ throw new Error("Token is invalid");
33
+ }
34
+
35
+ // Validate peggedTokenIn
36
+ if (typeof parameters.peggedTokenIn !== "bigint") {
37
+ throw new Error("Amount must be a bigint");
38
+ }
39
+ if (parameters.peggedTokenIn <= 0n) {
40
+ throw new Error("Amount must be greater than 0");
41
+ }
42
+
43
+ return readContract(client, {
44
+ abi: gatewayAbi,
45
+ address: parameters.address,
46
+ args: [parameters.tokenOut, parameters.peggedTokenIn],
47
+ functionName: "previewRedeem",
48
+ });
49
+ }
@@ -0,0 +1,135 @@
1
+ import { EventEmitter } from "events";
2
+ import { toPromiseEvent } from "to-promise-event";
3
+ import {
4
+ type Address,
5
+ type TransactionReceipt,
6
+ type WalletClient,
7
+ encodeFunctionData,
8
+ isAddress,
9
+ isAddressEqual,
10
+ zeroAddress,
11
+ } from "viem";
12
+ import { waitForTransactionReceipt, writeContract } from "viem/actions";
13
+
14
+ import { gatewayAbi } from "../../abi/gatewayAbi.js";
15
+ import type { CancelRedeemRequestEvents } from "../../types.js";
16
+
17
+ export type CancelRedeemRequestParams = {
18
+ gatewayAddress: Address;
19
+ };
20
+
21
+ const canCancelRedeemRequest = function ({
22
+ client,
23
+ gatewayAddress,
24
+ }: {
25
+ client: WalletClient;
26
+ gatewayAddress: Address;
27
+ }): {
28
+ canCancelRedeemRequest: boolean;
29
+ reason?: string;
30
+ } {
31
+ if (!client) {
32
+ return {
33
+ canCancelRedeemRequest: false,
34
+ reason: "Client is not defined",
35
+ };
36
+ }
37
+ if (!client.chain) {
38
+ return {
39
+ canCancelRedeemRequest: false,
40
+ reason: "Chain is not defined on wallet client",
41
+ };
42
+ }
43
+ if (!client.account) {
44
+ return {
45
+ canCancelRedeemRequest: false,
46
+ reason: "Client must have an account",
47
+ };
48
+ }
49
+ // Validate gateway address
50
+ if (!gatewayAddress || !isAddress(gatewayAddress)) {
51
+ return {
52
+ canCancelRedeemRequest: false,
53
+ reason: "Invalid gateway address",
54
+ };
55
+ }
56
+ if (isAddressEqual(gatewayAddress, zeroAddress)) {
57
+ return {
58
+ canCancelRedeemRequest: false,
59
+ reason: "Gateway address cannot be zero address",
60
+ };
61
+ }
62
+
63
+ return { canCancelRedeemRequest: true };
64
+ };
65
+
66
+ const runCancelRedeemRequest = (
67
+ walletClient: WalletClient,
68
+ { gatewayAddress }: CancelRedeemRequestParams,
69
+ ) =>
70
+ async function (emitter: EventEmitter<CancelRedeemRequestEvents>) {
71
+ try {
72
+ const { canCancelRedeemRequest: canCancelRedeemRequestFlag, reason } =
73
+ canCancelRedeemRequest({
74
+ client: walletClient,
75
+ gatewayAddress,
76
+ });
77
+
78
+ if (!canCancelRedeemRequestFlag) {
79
+ emitter.emit("cancel-redeem-request-failed-validation", reason!);
80
+ return;
81
+ }
82
+
83
+ emitter.emit("pre-cancel-redeem-request");
84
+
85
+ const cancelHash = await writeContract(walletClient, {
86
+ abi: gatewayAbi,
87
+ account: walletClient.account!,
88
+ address: gatewayAddress,
89
+ chain: walletClient.chain,
90
+ functionName: "cancelRedeemRequest",
91
+ }).catch(function (error: Error) {
92
+ emitter.emit("user-signing-cancel-redeem-request-error", error);
93
+ });
94
+
95
+ if (!cancelHash) {
96
+ return;
97
+ }
98
+
99
+ emitter.emit("user-signed-cancel-redeem-request", cancelHash);
100
+
101
+ const cancelReceipt = await waitForTransactionReceipt(walletClient, {
102
+ hash: cancelHash,
103
+ }).catch(function (error: Error) {
104
+ emitter.emit("cancel-redeem-request-failed", error);
105
+ });
106
+
107
+ if (!cancelReceipt) {
108
+ return;
109
+ }
110
+
111
+ const cancelEventMap: Record<
112
+ TransactionReceipt["status"],
113
+ keyof CancelRedeemRequestEvents
114
+ > = {
115
+ reverted: "cancel-redeem-request-transaction-reverted",
116
+ success: "cancel-redeem-request-transaction-succeeded",
117
+ };
118
+
119
+ emitter.emit(cancelEventMap[cancelReceipt.status], cancelReceipt);
120
+ } catch (error) {
121
+ emitter.emit("unexpected-error", error as Error);
122
+ } finally {
123
+ emitter.emit("cancel-redeem-request-settled");
124
+ }
125
+ };
126
+
127
+ export const cancelRedeemRequest = (
128
+ ...args: Parameters<typeof runCancelRedeemRequest>
129
+ ) => toPromiseEvent<CancelRedeemRequestEvents>(runCancelRedeemRequest(...args));
130
+
131
+ export const encodeCancelRedeemRequest = () =>
132
+ encodeFunctionData({
133
+ abi: gatewayAbi,
134
+ functionName: "cancelRedeemRequest",
135
+ });
@@ -0,0 +1,277 @@
1
+ import { EventEmitter } from "events";
2
+ import { toPromiseEvent } from "to-promise-event";
3
+ import {
4
+ type Address,
5
+ type TransactionReceipt,
6
+ type WalletClient,
7
+ encodeFunctionData,
8
+ isAddress,
9
+ isAddressEqual,
10
+ zeroAddress,
11
+ } from "viem";
12
+ import { waitForTransactionReceipt, writeContract } from "viem/actions";
13
+ import { allowance, approve } from "viem-erc20/actions";
14
+
15
+ import { gatewayAbi } from "../../abi/gatewayAbi.js";
16
+ import type { DepositEvents } from "../../types.js";
17
+
18
+ export type DepositParams = {
19
+ amountIn: bigint;
20
+ approveAmount?: bigint;
21
+ gatewayAddress: Address;
22
+ minPeggedTokenOut: bigint;
23
+ receiver: Address;
24
+ tokenIn: Address;
25
+ };
26
+
27
+ const canDeposit = function ({
28
+ amountIn,
29
+ approveAmount,
30
+ client,
31
+ gatewayAddress,
32
+ minPeggedTokenOut,
33
+ receiver,
34
+ tokenIn,
35
+ }: {
36
+ amountIn: bigint;
37
+ approveAmount: bigint;
38
+ client: WalletClient;
39
+ gatewayAddress: Address;
40
+ minPeggedTokenOut: bigint;
41
+ receiver: Address;
42
+ tokenIn: Address;
43
+ }): {
44
+ canDeposit: boolean;
45
+ reason?: string;
46
+ } {
47
+ // Validate client
48
+ if (!client) {
49
+ return {
50
+ canDeposit: false,
51
+ reason: "Client is not defined",
52
+ };
53
+ }
54
+ if (!client.chain) {
55
+ return {
56
+ canDeposit: false,
57
+ reason: "Chain is not defined on wallet client",
58
+ };
59
+ }
60
+ // Validate client has required properties
61
+ if (!client.account) {
62
+ return {
63
+ canDeposit: false,
64
+ reason: "Client must have an account",
65
+ };
66
+ }
67
+ // Validate gateway address
68
+ if (!gatewayAddress || !isAddress(gatewayAddress)) {
69
+ return {
70
+ canDeposit: false,
71
+ reason: "Invalid gateway address",
72
+ };
73
+ }
74
+ if (isAddressEqual(gatewayAddress, zeroAddress)) {
75
+ return {
76
+ canDeposit: false,
77
+ reason: "Gateway address cannot be zero address",
78
+ };
79
+ }
80
+ // Validate tokenIn address
81
+ if (!tokenIn || !isAddress(tokenIn)) {
82
+ return {
83
+ canDeposit: false,
84
+ reason: "Invalid token address",
85
+ };
86
+ }
87
+ if (isAddressEqual(tokenIn, zeroAddress)) {
88
+ return {
89
+ canDeposit: false,
90
+ reason: "Token address cannot be zero address",
91
+ };
92
+ }
93
+
94
+ // Validate receiver address
95
+ if (!receiver || !isAddress(receiver)) {
96
+ return {
97
+ canDeposit: false,
98
+ reason: "Invalid receiver address",
99
+ };
100
+ }
101
+ if (isAddressEqual(receiver, zeroAddress)) {
102
+ return {
103
+ canDeposit: false,
104
+ reason: "Receiver address cannot be zero address",
105
+ };
106
+ }
107
+
108
+ // Validate amountIn
109
+ if (typeof amountIn !== "bigint") {
110
+ return {
111
+ canDeposit: false,
112
+ reason: "Amount must be a bigint",
113
+ };
114
+ }
115
+ if (amountIn <= 0n) {
116
+ return {
117
+ canDeposit: false,
118
+ reason: "Amount must be greater than 0",
119
+ };
120
+ }
121
+
122
+ // Validate minPeggedTokenOut
123
+ if (typeof minPeggedTokenOut !== "bigint") {
124
+ return {
125
+ canDeposit: false,
126
+ reason: "Minimum output must be a bigint",
127
+ };
128
+ }
129
+ if (minPeggedTokenOut < 0n) {
130
+ return {
131
+ canDeposit: false,
132
+ reason: "Minimum output cannot be negative",
133
+ };
134
+ }
135
+
136
+ // Validate approveAmount
137
+ if (approveAmount < amountIn) {
138
+ return {
139
+ canDeposit: false,
140
+ reason: "Approve amount must be greater than or equal to amount",
141
+ };
142
+ }
143
+
144
+ return { canDeposit: true };
145
+ };
146
+
147
+ const runDeposit = (
148
+ walletClient: WalletClient,
149
+ {
150
+ amountIn,
151
+ approveAmount = amountIn,
152
+ gatewayAddress,
153
+ minPeggedTokenOut,
154
+ receiver,
155
+ tokenIn,
156
+ }: DepositParams,
157
+ ) =>
158
+ async function (emitter: EventEmitter<DepositEvents>) {
159
+ try {
160
+ const { canDeposit: canDepositFlag, reason } = canDeposit({
161
+ amountIn,
162
+ approveAmount,
163
+ client: walletClient,
164
+ gatewayAddress,
165
+ minPeggedTokenOut,
166
+ receiver,
167
+ tokenIn,
168
+ });
169
+
170
+ if (!canDepositFlag) {
171
+ emitter.emit("deposit-failed-validation", reason!);
172
+ return;
173
+ }
174
+
175
+ // Check current allowance
176
+ const currentAllowance = await allowance(walletClient, {
177
+ address: tokenIn,
178
+ // account is already validated
179
+ owner: walletClient.account!.address,
180
+ spender: gatewayAddress,
181
+ });
182
+
183
+ // If allowance is insufficient, approve first
184
+ if (currentAllowance < amountIn) {
185
+ emitter.emit("pre-approve");
186
+
187
+ const approvalHash = await approve(walletClient, {
188
+ address: tokenIn,
189
+ amount: approveAmount,
190
+ spender: gatewayAddress,
191
+ }).catch(function (error: Error) {
192
+ emitter.emit("user-signing-approval-error", error);
193
+ });
194
+
195
+ if (!approvalHash) {
196
+ return;
197
+ }
198
+
199
+ emitter.emit("user-signed-approval", approvalHash);
200
+
201
+ const approvalReceipt = await waitForTransactionReceipt(walletClient, {
202
+ hash: approvalHash,
203
+ }).catch(function (error: Error) {
204
+ emitter.emit("deposit-failed", error);
205
+ });
206
+
207
+ if (!approvalReceipt) {
208
+ return;
209
+ }
210
+
211
+ if (approvalReceipt.status === "reverted") {
212
+ emitter.emit("approve-transaction-reverted", approvalReceipt);
213
+ return;
214
+ }
215
+
216
+ emitter.emit("approve-transaction-succeeded", approvalReceipt);
217
+ }
218
+
219
+ emitter.emit("pre-deposit");
220
+
221
+ const depositHash = await writeContract(walletClient, {
222
+ abi: gatewayAbi,
223
+ account: walletClient.account!,
224
+ address: gatewayAddress,
225
+ args: [tokenIn, amountIn, minPeggedTokenOut, receiver],
226
+ chain: walletClient.chain,
227
+ functionName: "deposit",
228
+ }).catch(function (error: Error) {
229
+ emitter.emit("user-signing-deposit-error", error);
230
+ });
231
+
232
+ if (!depositHash) {
233
+ return;
234
+ }
235
+
236
+ emitter.emit("user-signed-deposit", depositHash);
237
+
238
+ const depositReceipt = await waitForTransactionReceipt(walletClient, {
239
+ hash: depositHash,
240
+ }).catch(function (error: Error) {
241
+ emitter.emit("deposit-failed", error);
242
+ });
243
+
244
+ if (!depositReceipt) {
245
+ return;
246
+ }
247
+
248
+ const depositEventMap: Record<
249
+ TransactionReceipt["status"],
250
+ keyof DepositEvents
251
+ > = {
252
+ reverted: "deposit-transaction-reverted",
253
+ success: "deposit-transaction-succeeded",
254
+ };
255
+
256
+ emitter.emit(depositEventMap[depositReceipt.status], depositReceipt);
257
+ } catch (error) {
258
+ emitter.emit("unexpected-error", error as Error);
259
+ } finally {
260
+ emitter.emit("deposit-settled");
261
+ }
262
+ };
263
+
264
+ export const deposit = (...args: Parameters<typeof runDeposit>) =>
265
+ toPromiseEvent<DepositEvents>(runDeposit(...args));
266
+
267
+ export const encodeDeposit = ({
268
+ amountIn,
269
+ minPeggedTokenOut,
270
+ receiver,
271
+ tokenIn,
272
+ }: Omit<DepositParams, "gatewayAddress">) =>
273
+ encodeFunctionData({
274
+ abi: gatewayAbi,
275
+ args: [tokenIn, amountIn, minPeggedTokenOut, receiver],
276
+ functionName: "deposit",
277
+ });