@across-protocol/sdk 4.1.23 → 4.1.24
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.
- package/dist/cjs/relayFeeCalculator/chain-queries/factory.d.ts +20 -0
- package/dist/cjs/relayFeeCalculator/relayFeeCalculator.d.ts +20 -0
- package/dist/cjs/utils/AddressUtils.d.ts +33 -0
- package/dist/cjs/utils/AddressUtils.js +132 -4
- package/dist/cjs/utils/AddressUtils.js.map +1 -1
- package/dist/cjs/utils/NetworkUtils.d.ts +1 -0
- package/dist/cjs/utils/NetworkUtils.js +8 -3
- package/dist/cjs/utils/NetworkUtils.js.map +1 -1
- package/dist/cjs/utils/TokenUtils.d.ts +40 -0
- package/dist/esm/relayFeeCalculator/chain-queries/factory.d.ts +20 -0
- package/dist/esm/relayFeeCalculator/relayFeeCalculator.d.ts +20 -0
- package/dist/esm/utils/AddressUtils.d.ts +40 -0
- package/dist/esm/utils/AddressUtils.js +174 -2
- package/dist/esm/utils/AddressUtils.js.map +1 -1
- package/dist/esm/utils/NetworkUtils.d.ts +6 -0
- package/dist/esm/utils/NetworkUtils.js +12 -3
- package/dist/esm/utils/NetworkUtils.js.map +1 -1
- package/dist/esm/utils/TokenUtils.d.ts +40 -0
- package/dist/types/relayFeeCalculator/chain-queries/factory.d.ts +20 -0
- package/dist/types/relayFeeCalculator/chain-queries/factory.d.ts.map +1 -1
- package/dist/types/relayFeeCalculator/relayFeeCalculator.d.ts +20 -0
- package/dist/types/relayFeeCalculator/relayFeeCalculator.d.ts.map +1 -1
- package/dist/types/utils/AddressUtils.d.ts +40 -0
- package/dist/types/utils/AddressUtils.d.ts.map +1 -1
- package/dist/types/utils/NetworkUtils.d.ts +6 -0
- package/dist/types/utils/NetworkUtils.d.ts.map +1 -1
- package/dist/types/utils/TokenUtils.d.ts +40 -0
- package/dist/types/utils/TokenUtils.d.ts.map +1 -1
- package/package.json +3 -2
- package/src/utils/AddressUtils.ts +179 -1
- package/src/utils/NetworkUtils.ts +11 -3
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { providers, utils } from "ethers";
|
|
2
|
-
import
|
|
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
|
-
|
|
134
|
-
|
|
135
|
-
|
|
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
|
/**
|