@across-protocol/sdk 4.1.23 → 4.1.25-beta.1

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 (32) hide show
  1. package/dist/cjs/relayFeeCalculator/chain-queries/factory.d.ts +20 -0
  2. package/dist/cjs/relayFeeCalculator/relayFeeCalculator.d.ts +20 -0
  3. package/dist/cjs/utils/AddressUtils.d.ts +33 -0
  4. package/dist/cjs/utils/AddressUtils.js +132 -4
  5. package/dist/cjs/utils/AddressUtils.js.map +1 -1
  6. package/dist/cjs/utils/NetworkUtils.d.ts +1 -0
  7. package/dist/cjs/utils/NetworkUtils.js +8 -3
  8. package/dist/cjs/utils/NetworkUtils.js.map +1 -1
  9. package/dist/cjs/utils/TokenUtils.d.ts +40 -0
  10. package/dist/esm/relayFeeCalculator/chain-queries/factory.d.ts +20 -0
  11. package/dist/esm/relayFeeCalculator/relayFeeCalculator.d.ts +20 -0
  12. package/dist/esm/utils/AddressUtils.d.ts +40 -0
  13. package/dist/esm/utils/AddressUtils.js +174 -2
  14. package/dist/esm/utils/AddressUtils.js.map +1 -1
  15. package/dist/esm/utils/NetworkUtils.d.ts +6 -0
  16. package/dist/esm/utils/NetworkUtils.js +12 -3
  17. package/dist/esm/utils/NetworkUtils.js.map +1 -1
  18. package/dist/esm/utils/TokenUtils.d.ts +40 -0
  19. package/dist/types/relayFeeCalculator/chain-queries/factory.d.ts +20 -0
  20. package/dist/types/relayFeeCalculator/chain-queries/factory.d.ts.map +1 -1
  21. package/dist/types/relayFeeCalculator/relayFeeCalculator.d.ts +20 -0
  22. package/dist/types/relayFeeCalculator/relayFeeCalculator.d.ts.map +1 -1
  23. package/dist/types/utils/AddressUtils.d.ts +40 -0
  24. package/dist/types/utils/AddressUtils.d.ts.map +1 -1
  25. package/dist/types/utils/NetworkUtils.d.ts +6 -0
  26. package/dist/types/utils/NetworkUtils.d.ts.map +1 -1
  27. package/dist/types/utils/TokenUtils.d.ts +40 -0
  28. package/dist/types/utils/TokenUtils.d.ts.map +1 -1
  29. package/package.json +4 -2
  30. package/scripts/build-bigint-buffer.js +49 -0
  31. package/src/utils/AddressUtils.ts +179 -1
  32. package/src/utils/NetworkUtils.ts +11 -3
@@ -0,0 +1,49 @@
1
+ /**
2
+ * Build Script for bigint-buffer Native Module
3
+ *
4
+ * Purpose:
5
+ * This script handles the native compilation of the bigint-buffer module, which provides
6
+ * high-performance BigInt <-> Buffer conversions using native C++ code.
7
+ *
8
+ * Why JavaScript and not TypeScript or an embedded shell script:
9
+ * 1. This is a build script that runs during package installation (postinstall)
10
+ * 2. Using TypeScript would require the TypeScript compiler or ts-node to be available during installation
11
+ * 3. Plain JavaScript ensures this script can run immediately without compilation
12
+ * 4. This script is operating system agnostic, so it can be run on any platform that supports Node.js
13
+ */
14
+
15
+ const { execSync } = require('child_process');
16
+ const { existsSync } = require('fs');
17
+ const path = require('path');
18
+
19
+ try {
20
+ // Check if the bigint-buffer module exists in node_modules
21
+ // Using path.join for cross-platform compatibility (Windows/Unix)
22
+ const bigintBufferPath = path.join(process.cwd(), 'node_modules/bigint-buffer');
23
+
24
+ // Skip if module isn't installed
25
+ if (!existsSync(bigintBufferPath)) {
26
+ console.log('Skipping bigint-buffer build: folder not found');
27
+ process.exit(0);
28
+ }
29
+
30
+ // Verify node-gyp (native module build tool) is available
31
+ // node-gyp is required to compile the C++ code in bigint-buffer
32
+ try {
33
+ execSync('command -v node-gyp', { stdio: 'ignore' });
34
+ } catch {
35
+ console.log('Skipping bigint-buffer build: node-gyp not found');
36
+ process.exit(0);
37
+ }
38
+
39
+ // Change to the module directory and run the native build
40
+ // node-gyp configure: Creates platform-specific build files
41
+ // node-gyp build: Compiles the native code
42
+ process.chdir(bigintBufferPath);
43
+ execSync('node-gyp configure', { stdio: 'inherit' });
44
+ execSync('node-gyp build', { stdio: 'inherit' });
45
+ } catch (error) {
46
+ // Proper error handling for build failures
47
+ console.error('Error building bigint-buffer:', error);
48
+ process.exit(1);
49
+ }
@@ -1,5 +1,6 @@
1
1
  import { providers, utils } from "ethers";
2
- import { BigNumber } from "./BigNumberUtils";
2
+ import bs58 from "bs58";
3
+ import { BigNumber, chainIsEvm } from "./";
3
4
 
4
5
  /**
5
6
  * Checks if a contract is deployed at the given address
@@ -68,3 +69,180 @@ export function isValidEvmAddress(address: string): boolean {
68
69
  return false;
69
70
  }
70
71
  }
72
+
73
+ /**
74
+ * Creates the proper address type given the input chain ID corresponding to the address's origin network.
75
+ * @param address Stringified address type to convert. Can be either hex encoded or base58 encoded.
76
+ * @param chainId Network ID corresponding to the input address, used to determine which address type to output.
77
+ * @returns a child `Address` type most fitting for the chain ID.
78
+ * @todo: Change this to `toAddress` once we remove the other `toAddress` function.
79
+ */
80
+ export function toAddressType(address: string, chainId: number): Address | EvmAddress | SvmAddress {
81
+ try {
82
+ if (chainIsEvm(chainId)) {
83
+ return EvmAddress.from(address);
84
+ }
85
+ return SvmAddress.from(address);
86
+ } catch (e) {
87
+ // If we hit this block, then the validation for one of the child address classes failed. We still may want to keep this address in our state, so
88
+ // return an unchecked address type.
89
+ return new Address(utils.arrayify(address));
90
+ }
91
+ }
92
+
93
+ // The Address class can contain any address type. It is up to the subclasses to determine how to format the address's internal representation,
94
+ // which for this class, is a bytes32 hex string.
95
+ export class Address {
96
+ readonly rawAddress: Uint8Array;
97
+
98
+ // Keep all address types in cache so that we may lazily evaluate them when necessary.
99
+ evmAddress: string | undefined = undefined;
100
+ bytes32Address: string | undefined = undefined;
101
+ svmAddress: string | undefined = undefined;
102
+ bnAddress: BigNumber | undefined = undefined;
103
+
104
+ constructor(_rawAddress: Uint8Array) {
105
+ // The only validation done here is checking that the address is at most a 32-byte address, which will be well-defined on any supported network.
106
+ // Further validation is done on the subclasses so that we can guarantee that, for example, an EvmAddress type will always contain a valid, 20-byte
107
+ // EVM address.
108
+ if (_rawAddress.length > 32) {
109
+ throw new Error(`Address ${utils.hexlify(_rawAddress)} cannot be longer than 32 bytes.`);
110
+ }
111
+ // Ensure all addresses in this class are internally stored as 32 bytes.
112
+ this.rawAddress = utils.zeroPad(_rawAddress, 32);
113
+ }
114
+
115
+ // Converts the address into a bytes32 string. Note that the output bytes will be lowercase so that it matches ethers event data. This function will never
116
+ // throw since address length validation was done at construction time.
117
+ toBytes32(): string {
118
+ return (this.bytes32Address ??= utils.hexZeroPad(utils.hexlify(this.rawAddress), 32).toLowerCase());
119
+ }
120
+
121
+ // Converts the address (can be bytes32 or bytes20) to its base58 counterpart. This conversion will always succeed, even if the input address is not valid on Solana,
122
+ // as this address may be needed to represent an EVM address on Solana.
123
+ toBase58(): string {
124
+ return (this.svmAddress ??= bs58.encode(this.rawAddress));
125
+ }
126
+
127
+ // Converts the address to a BigNumber type.
128
+ toBigNumber(): BigNumber {
129
+ return (this.bnAddress ??= BigNumber.from(this.toBytes32()));
130
+ }
131
+
132
+ // Converts the address to a valid EVM address. If it is unable to convert the address to a valid EVM address for some reason, such as if this address
133
+ // is longer than 20 bytes, then this function will throw an error.
134
+ toEvmAddress(): string {
135
+ const parseRawAddress = () => {
136
+ const hexString = utils.hexlify(this.rawAddress);
137
+ const rawAddress = utils.hexZeroPad(utils.hexStripZeros(hexString), 20);
138
+ return utils.getAddress(rawAddress);
139
+ };
140
+ return (this.evmAddress ??= parseRawAddress());
141
+ }
142
+
143
+ // Converts the address to a hex string. This method should be overriden by subclasses to obtain more meaningful
144
+ // address representations for the target chain ID.
145
+ toAddress(): string {
146
+ return this.toBytes32();
147
+ }
148
+
149
+ // Implements `Hexable` for `Address`. Needed for encoding purposes. This class is treated by default as a bytes32 primitive type, but can change for subclasses.
150
+ toHexString(): string {
151
+ return this.toBytes32();
152
+ }
153
+
154
+ // Checks if this address can be coerced into a bytes20 evm address. Returns true if it is possible and false otherwise.
155
+ isValidEvmAddress(): boolean {
156
+ try {
157
+ this.toAddress();
158
+ return true;
159
+ } catch {
160
+ return false;
161
+ }
162
+ }
163
+
164
+ // Checks if the address is valid on the given chain ID.
165
+ isValidOn(chainId: number): boolean {
166
+ if (chainIsEvm(chainId)) {
167
+ return this.isValidEvmAddress();
168
+ }
169
+ // Assume the address is always valid on Solana.
170
+ return true;
171
+ }
172
+
173
+ // Checks if the object is an address by looking at whether it has an Address constructor.
174
+ static isAddress(obj: unknown): boolean {
175
+ return obj instanceof this;
176
+ }
177
+
178
+ // Converts the input address to a 32-byte hex data string.
179
+ toString(): string {
180
+ return this.toHexString();
181
+ }
182
+
183
+ // Checks if the address is the zero address.
184
+ isZeroAddress(): boolean {
185
+ return utils.stripZeros(this.rawAddress).length === 0;
186
+ }
187
+
188
+ // Checks if the other address is equivalent to this address.
189
+ eq(other: Address): boolean {
190
+ return this.toString() === other.toString();
191
+ }
192
+
193
+ // Compares Addresses by first converting them to BigNumbers.
194
+ compare(otherAddress: Address): 1 | -1 | 0 {
195
+ // Convert address strings to BigNumbers and then sort numerical value of the BigNumber, which sorts the addresses
196
+ // effectively by their hex value.
197
+ const bnAddressA = this.toBigNumber();
198
+ const bnAddressB = otherAddress.toBigNumber();
199
+ if (bnAddressA.gt(bnAddressB)) {
200
+ return 1;
201
+ } else if (bnAddressA.lt(bnAddressB)) {
202
+ return -1;
203
+ } else {
204
+ return 0;
205
+ }
206
+ }
207
+ }
208
+
209
+ // Subclass of address which strictly deals with 20-byte addresses. These addresses are guaranteed to be valid EVM addresses, so `toAddress` will always succeed.
210
+ export class EvmAddress extends Address {
211
+ // On construction, validate that the address can indeed be coerced into an EVM address. Throw immediately if it cannot.
212
+ constructor(rawAddress: Uint8Array) {
213
+ super(rawAddress);
214
+ const hexString = utils.hexlify(rawAddress);
215
+ if (!this.isValidEvmAddress()) {
216
+ throw new Error(`${hexString} is not a valid EVM address`);
217
+ }
218
+ }
219
+
220
+ // Override `toAddress` to return the 20-byte representation address.
221
+ override toAddress(): string {
222
+ return this.toEvmAddress();
223
+ }
224
+
225
+ // Constructs a new EvmAddress type.
226
+ static from(hexString: string): EvmAddress {
227
+ return new this(utils.arrayify(hexString));
228
+ }
229
+ }
230
+
231
+ // Subclass of address which strictly deals SVM addresses. These addresses are guaranteed to be valid SVM addresses, so `toBase58` will always produce a valid Solana address.
232
+ export class SvmAddress extends Address {
233
+ // On construction, validate that the address is a point on Curve25519. Throw immediately if it is not.
234
+ constructor(rawAddress: Uint8Array) {
235
+ super(rawAddress);
236
+ }
237
+
238
+ // Override the toAddress function for SVM addresses only since while they will never have a defined 20-byte representation. The base58 encoded addresses are also the encodings
239
+ // used in TOKEN_SYMBOLS_MAP.
240
+ override toAddress(): string {
241
+ return this.toBase58();
242
+ }
243
+
244
+ // Constructs a new SvmAddress type.
245
+ static from(bs58Address: string): SvmAddress {
246
+ return new this(bs58.decode(bs58Address));
247
+ }
248
+ }
@@ -130,9 +130,17 @@ export function chainIsL1(chainId: number): boolean {
130
130
  * @returns True if chain corresponding to chainId has an EVM-like execution layer.
131
131
  */
132
132
  export function chainIsEvm(chainId: number): boolean {
133
- chainId;
134
- // TODO: Fix when we support non-EVM chains.
135
- return true;
133
+ // TODO: Update when additional execution layers beyond EVM and SVM are supported.
134
+ return PUBLIC_NETWORKS[chainId]?.family !== ChainFamily.SVM;
135
+ }
136
+
137
+ /**
138
+ * Determines whether a chain ID runs on an SVM-like execution layer.
139
+ * @param chainId Chain ID to evaluate.
140
+ * @returns True if chain corresponding to chainId has an SVM-like execution layer.
141
+ */
142
+ export function chainIsSvm(chainId: number): boolean {
143
+ return PUBLIC_NETWORKS[chainId]?.family === ChainFamily.SVM;
136
144
  }
137
145
 
138
146
  /**