@imtbl/sdk 0.44.4 → 0.45.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.
- package/dist/blockchain_data.js +1 -1
- package/dist/browser/checkout/sdk.js +5 -5
- package/dist/browser/checkout/widgets.js +53 -53
- package/dist/checkout.d.ts +2 -2
- package/dist/checkout.js +25 -16
- package/dist/index.browser.js +11 -11
- package/dist/index.browser.js.map +1 -1
- package/dist/index.cjs +2128 -2124
- package/dist/index.d.ts +209 -214
- package/dist/index.js +2130 -2125
- package/dist/passport.d.ts +2 -2
- package/dist/passport.js +4 -4
- package/dist/{immutablex_client.d.ts → x.d.ts} +155 -2
- package/dist/{provider.js → x.js} +522 -9
- package/package.json +10 -14
- package/dist/immutablex_client.js +0 -523
- package/dist/provider.d.ts +0 -979
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import globalAxios$1, { isAxiosError as isAxiosError$2,
|
|
2
|
-
import { ImmutableX, Config,
|
|
1
|
+
import globalAxios$1, { isAxiosError as isAxiosError$2, HttpStatusCode as HttpStatusCode$3, AxiosError as AxiosError$2 } from 'axios';
|
|
2
|
+
import { ImmutableX, Config, generateLegacyStarkPrivateKey, createStarkSigner, TransfersApi as TransfersApi$1, OrdersApi as OrdersApi$2, UsersApi as UsersApi$1, Contracts, TradesApi as TradesApi$1, ExchangesApi as ExchangesApi$1, WithdrawalsApi as WithdrawalsApi$1, MintsApi as MintsApi$1, DepositsApi as DepositsApi$1, EncodingApi as EncodingApi$1, TokensApi as TokensApi$2, IMXError } from '@imtbl/core-sdk';
|
|
3
3
|
import { UserManager, User, InMemoryWebStorage, WebStorageStateStore } from 'oidc-client-ts';
|
|
4
4
|
import jwt_decode from 'jwt-decode';
|
|
5
5
|
import * as crypto from 'crypto';
|
|
@@ -14,8 +14,6 @@ import { walletContracts } from '@0xsequence/abi';
|
|
|
14
14
|
import { v1 } from '@0xsequence/core';
|
|
15
15
|
import FormData$2 from 'form-data';
|
|
16
16
|
import { Seaport as Seaport$1 } from '@opensea/seaport-js';
|
|
17
|
-
import { parseUnits } from '@ethersproject/units';
|
|
18
|
-
import { BigNumber as BigNumber$2 } from '@ethersproject/bignumber';
|
|
19
17
|
import detectEthereumProvider from '@metamask/detect-provider';
|
|
20
18
|
import * as Uniswap from '@uniswap/sdk-core';
|
|
21
19
|
import { TradeType, Percent } from '@uniswap/sdk-core';
|
|
@@ -23,6 +21,8 @@ import assert from 'assert';
|
|
|
23
21
|
import { FeeAmount, Route, SwapQuoter, Pool, Trade, toHex as toHex$1, encodeRouteToPath } from '@uniswap/v3-sdk';
|
|
24
22
|
import { keccak256 as keccak256$1 } from '@ethersproject/solidity';
|
|
25
23
|
import { SwapRouter, PaymentsExtended } from '@uniswap/router-sdk';
|
|
24
|
+
import { parseUnits } from '@ethersproject/units';
|
|
25
|
+
import { BigNumber as BigNumber$2 } from '@ethersproject/bignumber';
|
|
26
26
|
|
|
27
27
|
var Environment$1;
|
|
28
28
|
(function (Environment) {
|
|
@@ -10619,7 +10619,7 @@ class MultiRollupApiClients {
|
|
|
10619
10619
|
}
|
|
10620
10620
|
|
|
10621
10621
|
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
10622
|
-
const defaultHeaders$1 = { 'x-sdk-version': 'ts-immutable-sdk-0.
|
|
10622
|
+
const defaultHeaders$1 = { 'x-sdk-version': 'ts-immutable-sdk-0.45.1' };
|
|
10623
10623
|
const createConfig = ({ basePath, headers, }) => {
|
|
10624
10624
|
if (!basePath.trim()) {
|
|
10625
10625
|
throw Error('basePath can not be empty');
|
|
@@ -10691,7 +10691,7 @@ class APIError extends Error {
|
|
|
10691
10691
|
|
|
10692
10692
|
/* eslint-disable implicit-arrow-linebreak */
|
|
10693
10693
|
const defaultHeaders = {
|
|
10694
|
-
sdkVersion: 'ts-immutable-sdk-multi-rollup-api-client-0.
|
|
10694
|
+
sdkVersion: 'ts-immutable-sdk-multi-rollup-api-client-0.45.1',
|
|
10695
10695
|
};
|
|
10696
10696
|
/**
|
|
10697
10697
|
* createAPIConfiguration to create a custom Configuration
|
|
@@ -11130,7 +11130,7 @@ const createImmutableXConfiguration = ({ basePath, chainID, coreContractAddress,
|
|
|
11130
11130
|
chainID,
|
|
11131
11131
|
coreContractAddress,
|
|
11132
11132
|
registrationContractAddress,
|
|
11133
|
-
sdkVersion: 'ts-immutable-sdk-0.
|
|
11133
|
+
sdkVersion: 'ts-immutable-sdk-0.45.1',
|
|
11134
11134
|
});
|
|
11135
11135
|
/**
|
|
11136
11136
|
* Sets `sdkVersion` at the time of build
|
|
@@ -11176,7 +11176,7 @@ class ImxConfiguration {
|
|
|
11176
11176
|
}
|
|
11177
11177
|
}
|
|
11178
11178
|
|
|
11179
|
-
class
|
|
11179
|
+
class IMXClient {
|
|
11180
11180
|
immutableX;
|
|
11181
11181
|
depositsApi;
|
|
11182
11182
|
mintsApi;
|
|
@@ -11633,14 +11633,6 @@ class ImmutableXClient {
|
|
|
11633
11633
|
}
|
|
11634
11634
|
}
|
|
11635
11635
|
|
|
11636
|
-
var immutablex_client = /*#__PURE__*/Object.freeze({
|
|
11637
|
-
__proto__: null,
|
|
11638
|
-
IMXError: IMXError,
|
|
11639
|
-
ImmutableXClient: ImmutableXClient,
|
|
11640
|
-
imxClientCreateStarkSigner: createStarkSigner,
|
|
11641
|
-
imxClientGenerateLegacyStarkPrivateKey: generateLegacyStarkPrivateKey
|
|
11642
|
-
});
|
|
11643
|
-
|
|
11644
11636
|
function bind$1(fn, thisArg) {
|
|
11645
11637
|
return function wrap() {
|
|
11646
11638
|
return fn.apply(thisArg, arguments);
|
|
@@ -17873,7 +17865,7 @@ class Passport {
|
|
|
17873
17865
|
this.magicAdapter = new MagicAdapter(this.config);
|
|
17874
17866
|
this.confirmationScreen = new ConfirmationScreen(this.config);
|
|
17875
17867
|
this.immutableXClient = passportModuleConfiguration.overrides?.immutableXClient
|
|
17876
|
-
|| new
|
|
17868
|
+
|| new IMXClient({
|
|
17877
17869
|
baseConfig: passportModuleConfiguration.baseConfig,
|
|
17878
17870
|
});
|
|
17879
17871
|
this.multiRollupApiClients = new MultiRollupApiClients(this.config.multiRollupConfig);
|
|
@@ -19623,1151 +19615,67 @@ var orderbook = /*#__PURE__*/Object.freeze({
|
|
|
19623
19615
|
constants: constants
|
|
19624
19616
|
});
|
|
19625
19617
|
|
|
19626
|
-
function
|
|
19627
|
-
|
|
19628
|
-
|
|
19629
|
-
|
|
19630
|
-
const chainID = await signer.getChainId();
|
|
19631
|
-
if (!isChainValid(chainID, config)) {
|
|
19632
|
-
throw new Error('The wallet used for this operation is not connected to the correct network.');
|
|
19633
|
-
}
|
|
19618
|
+
function bind(fn, thisArg) {
|
|
19619
|
+
return function wrap() {
|
|
19620
|
+
return fn.apply(thisArg, arguments);
|
|
19621
|
+
};
|
|
19634
19622
|
}
|
|
19635
19623
|
|
|
19636
|
-
|
|
19637
|
-
await validateChain(ethSigner, config.immutableXConfig);
|
|
19638
|
-
const ethAddress = await ethSigner.getAddress();
|
|
19639
|
-
const transfersApi = new TransfersApi$1(config.immutableXConfig.apiConfiguration);
|
|
19640
|
-
const transferAmount = request.type === 'ERC721' ? '1' : request.amount;
|
|
19641
|
-
const signableResult = await transfersApi.getSignableTransferV1({
|
|
19642
|
-
getSignableTransferRequest: {
|
|
19643
|
-
sender: ethAddress,
|
|
19644
|
-
token: convertToSignableToken(request),
|
|
19645
|
-
amount: transferAmount,
|
|
19646
|
-
receiver: request.receiver,
|
|
19647
|
-
},
|
|
19648
|
-
});
|
|
19649
|
-
const { signable_message: signableMessage, payload_hash: payloadHash } = signableResult.data;
|
|
19650
|
-
const ethSignature = await signRaw(signableMessage, ethSigner);
|
|
19651
|
-
const starkSignature = await starkSigner.signMessage(payloadHash);
|
|
19652
|
-
const transferSigningParams = {
|
|
19653
|
-
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
19654
|
-
sender_stark_key: signableResult.data.sender_stark_key,
|
|
19655
|
-
sender_vault_id: signableResult.data.sender_vault_id,
|
|
19656
|
-
receiver_stark_key: signableResult.data.receiver_stark_key,
|
|
19657
|
-
receiver_vault_id: signableResult.data.receiver_vault_id,
|
|
19658
|
-
asset_id: signableResult.data.asset_id,
|
|
19659
|
-
amount: signableResult.data.amount,
|
|
19660
|
-
nonce: signableResult.data.nonce,
|
|
19661
|
-
expiration_timestamp: signableResult.data.expiration_timestamp,
|
|
19662
|
-
stark_signature: starkSignature,
|
|
19663
|
-
};
|
|
19664
|
-
const response = await transfersApi.createTransferV1({
|
|
19665
|
-
createTransferRequest: transferSigningParams,
|
|
19666
|
-
xImxEthAddress: ethAddress,
|
|
19667
|
-
xImxEthSignature: ethSignature,
|
|
19668
|
-
});
|
|
19669
|
-
return {
|
|
19670
|
-
sent_signature: response?.data.sent_signature,
|
|
19671
|
-
status: response?.data.status?.toString(),
|
|
19672
|
-
time: response?.data.time,
|
|
19673
|
-
transfer_id: response?.data.transfer_id,
|
|
19674
|
-
};
|
|
19675
|
-
}
|
|
19676
|
-
async function batchTransfer({ signers: { ethSigner, starkSigner }, request, config, }) {
|
|
19677
|
-
await validateChain(ethSigner, config.immutableXConfig);
|
|
19678
|
-
const ethAddress = await ethSigner.getAddress();
|
|
19679
|
-
const transfersApi = new TransfersApi$1(config.immutableXConfig.apiConfiguration);
|
|
19680
|
-
const signableRequests = request.map((nftTransfer) => ({
|
|
19681
|
-
amount: '1',
|
|
19682
|
-
token: convertToSignableToken({
|
|
19683
|
-
type: 'ERC721',
|
|
19684
|
-
tokenId: nftTransfer.tokenId,
|
|
19685
|
-
tokenAddress: nftTransfer.tokenAddress,
|
|
19686
|
-
}),
|
|
19687
|
-
receiver: nftTransfer.receiver,
|
|
19688
|
-
}));
|
|
19689
|
-
const signableResult = await transfersApi.getSignableTransfer({
|
|
19690
|
-
getSignableTransferRequestV2: {
|
|
19691
|
-
sender_ether_key: ethAddress,
|
|
19692
|
-
signable_requests: signableRequests,
|
|
19693
|
-
},
|
|
19694
|
-
});
|
|
19695
|
-
const signableMessage = signableResult.data.signable_message;
|
|
19696
|
-
if (signableMessage === undefined) {
|
|
19697
|
-
throw new Error('Invalid response from Signable registration offchain');
|
|
19698
|
-
}
|
|
19699
|
-
const ethSignature = await signRaw(signableMessage, ethSigner);
|
|
19700
|
-
const requests = [];
|
|
19701
|
-
for (const resp of signableResult.data.signable_responses) {
|
|
19702
|
-
// TODO: remove once fixed
|
|
19703
|
-
// eslint-disable-next-line no-await-in-loop
|
|
19704
|
-
const starkSignature = await starkSigner.signMessage(resp.payload_hash);
|
|
19705
|
-
const req = {
|
|
19706
|
-
sender_vault_id: resp.sender_vault_id,
|
|
19707
|
-
receiver_stark_key: resp.receiver_stark_key,
|
|
19708
|
-
receiver_vault_id: resp.receiver_vault_id,
|
|
19709
|
-
asset_id: resp.asset_id,
|
|
19710
|
-
amount: resp.amount,
|
|
19711
|
-
nonce: resp.nonce,
|
|
19712
|
-
expiration_timestamp: resp.expiration_timestamp,
|
|
19713
|
-
stark_signature: starkSignature,
|
|
19714
|
-
};
|
|
19715
|
-
requests.push(req);
|
|
19716
|
-
}
|
|
19717
|
-
// TODO: throw error on missing payload hash?
|
|
19718
|
-
const transferSigningParams = {
|
|
19719
|
-
sender_stark_key: signableResult.data.sender_stark_key,
|
|
19720
|
-
requests,
|
|
19721
|
-
};
|
|
19722
|
-
const response = await transfersApi.createTransfer({
|
|
19723
|
-
createTransferRequestV2: transferSigningParams,
|
|
19724
|
-
xImxEthAddress: ethAddress,
|
|
19725
|
-
xImxEthSignature: ethSignature,
|
|
19726
|
-
});
|
|
19727
|
-
return {
|
|
19728
|
-
transfer_ids: response?.data.transfer_ids,
|
|
19729
|
-
};
|
|
19730
|
-
}
|
|
19624
|
+
// utils is a library of generic helper functions non-specific to axios
|
|
19731
19625
|
|
|
19732
|
-
|
|
19733
|
-
|
|
19734
|
-
const ethAddress = await signers.ethSigner.getAddress();
|
|
19735
|
-
const ordersApi = new OrdersApi$2(config.immutableXConfig.apiConfiguration);
|
|
19736
|
-
const amountSell = request.sell.type === 'ERC721' ? '1' : request.sell.amount;
|
|
19737
|
-
const amountBuy = request.buy.type === 'ERC721' ? '1' : request.buy.amount;
|
|
19738
|
-
const getSignableOrderRequest = {
|
|
19739
|
-
user: ethAddress,
|
|
19740
|
-
amount_buy: amountBuy,
|
|
19741
|
-
token_buy: convertToSignableToken(request.buy),
|
|
19742
|
-
amount_sell: amountSell,
|
|
19743
|
-
token_sell: convertToSignableToken(request.sell),
|
|
19744
|
-
fees: request.fees,
|
|
19745
|
-
expiration_timestamp: request.expiration_timestamp,
|
|
19746
|
-
};
|
|
19747
|
-
const getSignableOrderResponse = await ordersApi.getSignableOrder({
|
|
19748
|
-
getSignableOrderRequestV3: getSignableOrderRequest,
|
|
19749
|
-
});
|
|
19750
|
-
const { signable_message: signableMessage, payload_hash: payloadHash } = getSignableOrderResponse.data;
|
|
19751
|
-
const ethSignature = await signRaw(signableMessage, signers.ethSigner);
|
|
19752
|
-
const starkSignature = await signers.starkSigner.signMessage(payloadHash);
|
|
19753
|
-
const resp = getSignableOrderResponse.data;
|
|
19754
|
-
const orderParams = {
|
|
19755
|
-
createOrderRequest: {
|
|
19756
|
-
amount_buy: resp.amount_buy,
|
|
19757
|
-
amount_sell: resp.amount_sell,
|
|
19758
|
-
asset_id_buy: resp.asset_id_buy,
|
|
19759
|
-
asset_id_sell: resp.asset_id_sell,
|
|
19760
|
-
expiration_timestamp: resp.expiration_timestamp,
|
|
19761
|
-
fees: request.fees,
|
|
19762
|
-
nonce: resp.nonce,
|
|
19763
|
-
stark_key: resp.stark_key,
|
|
19764
|
-
stark_signature: starkSignature,
|
|
19765
|
-
vault_id_buy: resp.vault_id_buy,
|
|
19766
|
-
vault_id_sell: resp.vault_id_sell,
|
|
19767
|
-
},
|
|
19768
|
-
xImxEthAddress: ethAddress,
|
|
19769
|
-
xImxEthSignature: ethSignature,
|
|
19770
|
-
};
|
|
19771
|
-
const createOrderResponse = await ordersApi.createOrderV3(orderParams);
|
|
19772
|
-
return {
|
|
19773
|
-
...createOrderResponse.data,
|
|
19774
|
-
};
|
|
19775
|
-
}
|
|
19776
|
-
async function cancelOrder({ signers, request, config, }) {
|
|
19777
|
-
const ordersApi = new OrdersApi$2(config.immutableXConfig.apiConfiguration);
|
|
19778
|
-
const getSignableCancelOrderResponse = await ordersApi.getSignableCancelOrderV3({
|
|
19779
|
-
getSignableCancelOrderRequest: {
|
|
19780
|
-
order_id: request.order_id,
|
|
19781
|
-
},
|
|
19782
|
-
});
|
|
19783
|
-
const { signable_message: signableMessage, payload_hash: payloadHash } = getSignableCancelOrderResponse.data;
|
|
19784
|
-
const ethSignature = await signRaw(signableMessage, signers.ethSigner);
|
|
19785
|
-
const starkSignature = await signers.starkSigner.signMessage(payloadHash);
|
|
19786
|
-
const ethAddress = await signers.ethSigner.getAddress();
|
|
19787
|
-
const cancelOrderResponse = await ordersApi.cancelOrderV3({
|
|
19788
|
-
id: request.order_id.toString(),
|
|
19789
|
-
cancelOrderRequest: {
|
|
19790
|
-
order_id: request.order_id,
|
|
19791
|
-
stark_signature: starkSignature,
|
|
19792
|
-
},
|
|
19793
|
-
xImxEthAddress: ethAddress,
|
|
19794
|
-
xImxEthSignature: ethSignature,
|
|
19795
|
-
});
|
|
19796
|
-
return {
|
|
19797
|
-
order_id: cancelOrderResponse.data.order_id,
|
|
19798
|
-
status: cancelOrderResponse.data.status,
|
|
19799
|
-
};
|
|
19800
|
-
}
|
|
19626
|
+
const {toString} = Object.prototype;
|
|
19627
|
+
const {getPrototypeOf} = Object;
|
|
19801
19628
|
|
|
19802
|
-
|
|
19803
|
-
|
|
19804
|
-
|
|
19805
|
-
|
|
19806
|
-
const starkPublicKey = await signers.starkSigner.getAddress();
|
|
19807
|
-
const signableResult = await usersApi.getSignableRegistrationOffchain({
|
|
19808
|
-
getSignableRegistrationRequest: {
|
|
19809
|
-
ether_key: userAddress,
|
|
19810
|
-
stark_key: starkPublicKey,
|
|
19811
|
-
},
|
|
19812
|
-
});
|
|
19813
|
-
const { signable_message: signableMessage, payload_hash: payloadHash } = signableResult.data;
|
|
19814
|
-
const ethSignature = await signRaw(signableMessage, signers.ethSigner);
|
|
19815
|
-
const starkSignature = await signers.starkSigner.signMessage(payloadHash);
|
|
19816
|
-
const registeredUser = await usersApi.registerUser({
|
|
19817
|
-
registerUserRequest: {
|
|
19818
|
-
eth_signature: ethSignature,
|
|
19819
|
-
ether_key: userAddress,
|
|
19820
|
-
stark_signature: starkSignature,
|
|
19821
|
-
stark_key: starkPublicKey,
|
|
19822
|
-
},
|
|
19823
|
-
});
|
|
19824
|
-
return registeredUser.data;
|
|
19825
|
-
}
|
|
19826
|
-
async function isRegisteredOffchain(ethAddress, config) {
|
|
19827
|
-
try {
|
|
19828
|
-
const usersApi = new UsersApi$1(config.immutableXConfig.apiConfiguration);
|
|
19829
|
-
const getUsersResult = await usersApi.getUsers({
|
|
19830
|
-
user: ethAddress,
|
|
19831
|
-
});
|
|
19832
|
-
const { accounts } = getUsersResult.data;
|
|
19833
|
-
return accounts?.length > 0;
|
|
19834
|
-
}
|
|
19835
|
-
catch (ex) {
|
|
19836
|
-
if (ex instanceof AxiosError$2 && ex.response?.status === 404) {
|
|
19837
|
-
return false;
|
|
19838
|
-
}
|
|
19839
|
-
throw ex;
|
|
19840
|
-
}
|
|
19841
|
-
}
|
|
19842
|
-
async function isRegisteredOnChain(starkPublicKey, ethSigner, config) {
|
|
19843
|
-
await validateChain(ethSigner, config.immutableXConfig);
|
|
19844
|
-
const registrationContract = Contracts.Registration.connect(config.immutableXConfig.ethConfiguration.registrationContractAddress, ethSigner);
|
|
19845
|
-
try {
|
|
19846
|
-
return await registrationContract.isRegistered(starkPublicKey);
|
|
19847
|
-
}
|
|
19848
|
-
catch (ex) {
|
|
19849
|
-
if (ex.reason === 'USER_UNREGISTERED') {
|
|
19850
|
-
return false;
|
|
19851
|
-
}
|
|
19852
|
-
throw ex;
|
|
19853
|
-
}
|
|
19854
|
-
}
|
|
19855
|
-
async function getSignableRegistrationOnchain(etherKey, starkPublicKey, usersApi) {
|
|
19856
|
-
const response = await usersApi.getSignableRegistration({
|
|
19857
|
-
getSignableRegistrationRequest: {
|
|
19858
|
-
ether_key: etherKey,
|
|
19859
|
-
stark_key: starkPublicKey,
|
|
19860
|
-
},
|
|
19861
|
-
});
|
|
19862
|
-
return {
|
|
19863
|
-
operator_signature: response.data.operator_signature,
|
|
19864
|
-
payload_hash: response.data.payload_hash,
|
|
19865
|
-
readable_transaction: response.data.readable_transaction,
|
|
19866
|
-
verification_signature: response.data.verification_signature,
|
|
19867
|
-
};
|
|
19868
|
-
}
|
|
19629
|
+
const kindOf = (cache => thing => {
|
|
19630
|
+
const str = toString.call(thing);
|
|
19631
|
+
return cache[str] || (cache[str] = str.slice(8, -1).toLowerCase());
|
|
19632
|
+
})(Object.create(null));
|
|
19869
19633
|
|
|
19870
|
-
const
|
|
19871
|
-
|
|
19872
|
-
|
|
19873
|
-
throw new Error('undefined field exception');
|
|
19634
|
+
const kindOfTest = (type) => {
|
|
19635
|
+
type = type.toLowerCase();
|
|
19636
|
+
return (thing) => kindOf(thing) === type
|
|
19874
19637
|
};
|
|
19875
|
-
async function prepareWithdrawalAction(params) {
|
|
19876
|
-
const { signers: { ethSigner, starkSigner }, type, config, } = params;
|
|
19877
|
-
await validateChain(ethSigner, params.config);
|
|
19878
|
-
const withdrawalsApi = new WithdrawalsApi$1(config.apiConfiguration);
|
|
19879
|
-
const withdrawalAmount = type === 'ERC721' ? '1' : params.amount;
|
|
19880
|
-
const signableWithdrawalResult = await withdrawalsApi.getSignableWithdrawal({
|
|
19881
|
-
getSignableWithdrawalRequest: {
|
|
19882
|
-
user: await ethSigner.getAddress(),
|
|
19883
|
-
token: convertToSignableToken(params),
|
|
19884
|
-
amount: withdrawalAmount,
|
|
19885
|
-
},
|
|
19886
|
-
});
|
|
19887
|
-
const { signable_message: signableMessage, payload_hash: payloadHash } = signableWithdrawalResult.data;
|
|
19888
|
-
const starkSignature = await starkSigner.signMessage(payloadHash);
|
|
19889
|
-
const { ethAddress, ethSignature } = await signMessage$1(signableMessage, ethSigner);
|
|
19890
|
-
const prepareWithdrawalResponse = await withdrawalsApi.createWithdrawal({
|
|
19891
|
-
createWithdrawalRequest: {
|
|
19892
|
-
stark_key: assertIsDefined(signableWithdrawalResult.data.stark_key),
|
|
19893
|
-
amount: withdrawalAmount,
|
|
19894
|
-
asset_id: assertIsDefined(signableWithdrawalResult.data.asset_id),
|
|
19895
|
-
vault_id: assertIsDefined(signableWithdrawalResult.data.vault_id),
|
|
19896
|
-
nonce: assertIsDefined(signableWithdrawalResult.data.nonce),
|
|
19897
|
-
stark_signature: starkSignature,
|
|
19898
|
-
},
|
|
19899
|
-
xImxEthAddress: ethAddress,
|
|
19900
|
-
xImxEthSignature: ethSignature,
|
|
19901
|
-
});
|
|
19902
|
-
return prepareWithdrawalResponse.data;
|
|
19903
|
-
}
|
|
19904
19638
|
|
|
19905
|
-
|
|
19906
|
-
const encodingApi = new EncodingApi$1(config.apiConfiguration);
|
|
19907
|
-
const result = await encodingApi.encodeAsset({
|
|
19908
|
-
assetType,
|
|
19909
|
-
encodeAssetRequest: {
|
|
19910
|
-
token: {
|
|
19911
|
-
type: tokenType,
|
|
19912
|
-
...(tokenData && { data: tokenData }),
|
|
19913
|
-
},
|
|
19914
|
-
},
|
|
19915
|
-
});
|
|
19916
|
-
return result.data;
|
|
19917
|
-
}
|
|
19639
|
+
const typeOfTest = type => thing => typeof thing === type;
|
|
19918
19640
|
|
|
19919
|
-
|
|
19920
|
-
|
|
19921
|
-
|
|
19922
|
-
|
|
19923
|
-
|
|
19924
|
-
|
|
19925
|
-
|
|
19926
|
-
|
|
19927
|
-
}
|
|
19928
|
-
async function executeWithdrawERC20(ethSigner, assetType, starkPublicKey, config) {
|
|
19929
|
-
const contract = Contracts.Core.connect(config.ethConfiguration.coreContractAddress, ethSigner);
|
|
19930
|
-
const populatedTransaction = await contract.populateTransaction.withdraw(starkPublicKey, assetType);
|
|
19931
|
-
return ethSigner.sendTransaction(populatedTransaction);
|
|
19932
|
-
}
|
|
19933
|
-
async function completeERC20WithdrawalAction({ ethSigner, starkPublicKey, token, config, }) {
|
|
19934
|
-
await validateChain(ethSigner, config.immutableXConfig);
|
|
19935
|
-
const imxConfig = config.immutableXConfig;
|
|
19936
|
-
const assetType = await getEncodeAssetInfo('asset', 'ERC20', imxConfig, {
|
|
19937
|
-
token_address: token.tokenAddress,
|
|
19938
|
-
});
|
|
19939
|
-
const isRegistered = await isRegisteredOnChain(starkPublicKey, ethSigner, config);
|
|
19940
|
-
if (!isRegistered) {
|
|
19941
|
-
return executeRegisterAndWithdrawERC20({
|
|
19942
|
-
ethSigner,
|
|
19943
|
-
assetType: assetType.asset_type,
|
|
19944
|
-
starkPublicKey,
|
|
19945
|
-
config,
|
|
19946
|
-
});
|
|
19947
|
-
}
|
|
19948
|
-
return executeWithdrawERC20(ethSigner, assetType.asset_type, starkPublicKey, imxConfig);
|
|
19949
|
-
}
|
|
19641
|
+
/**
|
|
19642
|
+
* Determine if a value is an Array
|
|
19643
|
+
*
|
|
19644
|
+
* @param {Object} val The value to test
|
|
19645
|
+
*
|
|
19646
|
+
* @returns {boolean} True if value is an Array, otherwise false
|
|
19647
|
+
*/
|
|
19648
|
+
const {isArray} = Array;
|
|
19950
19649
|
|
|
19951
|
-
|
|
19952
|
-
|
|
19953
|
-
|
|
19954
|
-
|
|
19955
|
-
|
|
19956
|
-
|
|
19957
|
-
|
|
19958
|
-
|
|
19959
|
-
const signableResult = await getSignableRegistrationOnchain(etherKey, starkPublicKey, usersApi);
|
|
19960
|
-
const contract = Contracts.Registration.connect(config.ethConfiguration.registrationContractAddress, ethSigner);
|
|
19961
|
-
const populatedTransaction = await contract.populateTransaction.regsiterAndWithdrawAndMint(etherKey, starkPublicKey, signableResult.operator_signature, assetType, mintingBlob);
|
|
19962
|
-
return ethSigner.sendTransaction(populatedTransaction);
|
|
19963
|
-
}
|
|
19964
|
-
function getMintingBlob(token) {
|
|
19965
|
-
const { id } = token.data;
|
|
19966
|
-
const blueprint = token.data.blueprint || '';
|
|
19967
|
-
return encUtils.sanitizeHex(encUtils.utf8ToHex(`{${id}}:{${blueprint}}`));
|
|
19968
|
-
}
|
|
19969
|
-
async function completeMintableERC721Withdrawal(ethSigner, starkPublicKey, token, config) {
|
|
19970
|
-
const imxConfig = config.immutableXConfig;
|
|
19971
|
-
const assetType = await getEncodeAssetInfo('mintable-asset', 'ERC721', imxConfig, {
|
|
19972
|
-
id: token.data.id,
|
|
19973
|
-
token_address: token.data.tokenAddress,
|
|
19974
|
-
...(token.data.blueprint && { blueprint: token.data.blueprint }),
|
|
19975
|
-
});
|
|
19976
|
-
const mintingBlob = getMintingBlob(token);
|
|
19977
|
-
const isRegistered = await isRegisteredOnChain(starkPublicKey, ethSigner, config);
|
|
19978
|
-
if (!isRegistered) {
|
|
19979
|
-
return executeRegisterAndWithdrawMintableERC721(ethSigner, assetType.asset_type, starkPublicKey, mintingBlob, imxConfig);
|
|
19980
|
-
}
|
|
19981
|
-
return executeWithdrawMintableERC721(ethSigner, assetType.asset_type, starkPublicKey, mintingBlob, imxConfig);
|
|
19982
|
-
}
|
|
19983
|
-
async function executeRegisterAndWithdrawERC721(ethSigner, assetType, starkPublicKey, tokenId, config) {
|
|
19984
|
-
const etherKey = await ethSigner.getAddress();
|
|
19985
|
-
const usersApi = new UsersApi$1(config.apiConfiguration);
|
|
19986
|
-
const signableResult = await getSignableRegistrationOnchain(etherKey, starkPublicKey, usersApi);
|
|
19987
|
-
const contract = Contracts.Registration.connect(config.ethConfiguration.registrationContractAddress, ethSigner);
|
|
19988
|
-
const populatedTransaction = await contract.populateTransaction.registerAndWithdrawNft(etherKey, starkPublicKey, signableResult.operator_signature, assetType, tokenId);
|
|
19989
|
-
return ethSigner.sendTransaction(populatedTransaction);
|
|
19990
|
-
}
|
|
19991
|
-
async function executeWithdrawERC721(ethSigner, assetType, starkPublicKey, tokenId, config) {
|
|
19992
|
-
const contract = Contracts.Core.connect(config.ethConfiguration.coreContractAddress, ethSigner);
|
|
19993
|
-
const populatedTransaction = await contract.populateTransaction.withdrawNft(starkPublicKey, assetType, tokenId);
|
|
19994
|
-
return ethSigner.sendTransaction(populatedTransaction);
|
|
19995
|
-
}
|
|
19996
|
-
async function completeERC721Withdrawal(ethSigner, starkPublicKey, token, config) {
|
|
19997
|
-
const imxConfig = config.immutableXConfig;
|
|
19998
|
-
const assetType = await getEncodeAssetInfo('asset', 'ERC721', imxConfig, {
|
|
19999
|
-
token_id: token.tokenId,
|
|
20000
|
-
token_address: token.tokenAddress,
|
|
20001
|
-
});
|
|
20002
|
-
const isRegistered = await isRegisteredOnChain(starkPublicKey, ethSigner, config);
|
|
20003
|
-
if (!isRegistered) {
|
|
20004
|
-
return executeRegisterAndWithdrawERC721(ethSigner, assetType.asset_type, starkPublicKey, token.tokenId, imxConfig);
|
|
20005
|
-
}
|
|
20006
|
-
return executeWithdrawERC721(ethSigner, assetType.asset_type, starkPublicKey, token.tokenId, imxConfig);
|
|
20007
|
-
}
|
|
20008
|
-
async function completeERC721WithdrawalAction({ ethSigner, starkPublicKey, token, config, }) {
|
|
20009
|
-
await validateChain(ethSigner, config.immutableXConfig);
|
|
20010
|
-
const { tokenAddress } = token;
|
|
20011
|
-
const { tokenId } = token;
|
|
20012
|
-
const imxConfig = config.immutableXConfig;
|
|
20013
|
-
const mintsApi = new MintsApi$1(imxConfig.apiConfiguration);
|
|
20014
|
-
return await mintsApi
|
|
20015
|
-
.getMintableTokenDetailsByClientTokenId({
|
|
20016
|
-
tokenAddress,
|
|
20017
|
-
tokenId,
|
|
20018
|
-
})
|
|
20019
|
-
.then((mintableToken) => completeMintableERC721Withdrawal(ethSigner, starkPublicKey, {
|
|
20020
|
-
type: 'ERC721',
|
|
20021
|
-
data: {
|
|
20022
|
-
id: tokenId,
|
|
20023
|
-
tokenAddress,
|
|
20024
|
-
blueprint: mintableToken.data.blueprint,
|
|
20025
|
-
},
|
|
20026
|
-
}, config))
|
|
20027
|
-
.catch((error) => {
|
|
20028
|
-
if (error.response?.status === 404) {
|
|
20029
|
-
// token is already minted on L1
|
|
20030
|
-
return completeERC721Withdrawal(ethSigner, starkPublicKey, token, config);
|
|
20031
|
-
}
|
|
20032
|
-
throw error; // unable to recover from any other kind of error
|
|
20033
|
-
});
|
|
20034
|
-
}
|
|
19650
|
+
/**
|
|
19651
|
+
* Determine if a value is undefined
|
|
19652
|
+
*
|
|
19653
|
+
* @param {*} val The value to test
|
|
19654
|
+
*
|
|
19655
|
+
* @returns {boolean} True if the value is undefined, otherwise false
|
|
19656
|
+
*/
|
|
19657
|
+
const isUndefined = typeOfTest('undefined');
|
|
20035
19658
|
|
|
20036
|
-
|
|
20037
|
-
|
|
20038
|
-
|
|
20039
|
-
|
|
20040
|
-
|
|
20041
|
-
|
|
20042
|
-
|
|
20043
|
-
|
|
20044
|
-
|
|
20045
|
-
|
|
20046
|
-
const populatedTransaction = await contract.populateTransaction.withdraw(starkPublicKey, assetType);
|
|
20047
|
-
return ethSigner.sendTransaction(populatedTransaction);
|
|
20048
|
-
}
|
|
20049
|
-
async function completeEthWithdrawalAction({ ethSigner, starkPublicKey, config, }) {
|
|
20050
|
-
await validateChain(ethSigner, config.immutableXConfig);
|
|
20051
|
-
const imxConfig = config.immutableXConfig;
|
|
20052
|
-
const assetType = await getEncodeAssetInfo('asset', 'ETH', imxConfig);
|
|
20053
|
-
const isRegistered = await isRegisteredOnChain(starkPublicKey, ethSigner, config);
|
|
20054
|
-
if (!isRegistered) {
|
|
20055
|
-
return executeRegisterAndWithdrawEth(ethSigner, assetType.asset_type, starkPublicKey, imxConfig);
|
|
20056
|
-
}
|
|
20057
|
-
return executeWithdrawEth(ethSigner, assetType.asset_type, starkPublicKey, imxConfig);
|
|
19659
|
+
/**
|
|
19660
|
+
* Determine if a value is a Buffer
|
|
19661
|
+
*
|
|
19662
|
+
* @param {*} val The value to test
|
|
19663
|
+
*
|
|
19664
|
+
* @returns {boolean} True if value is a Buffer, otherwise false
|
|
19665
|
+
*/
|
|
19666
|
+
function isBuffer(val) {
|
|
19667
|
+
return val !== null && !isUndefined(val) && val.constructor !== null && !isUndefined(val.constructor)
|
|
19668
|
+
&& isFunction(val.constructor.isBuffer) && val.constructor.isBuffer(val);
|
|
20058
19669
|
}
|
|
20059
19670
|
|
|
20060
|
-
|
|
20061
|
-
|
|
20062
|
-
|
|
20063
|
-
|
|
20064
|
-
|
|
20065
|
-
|
|
20066
|
-
|
|
20067
|
-
|
|
20068
|
-
// eslint-disable-next-line consistent-return
|
|
20069
|
-
async function completeWithdrawal({ signers: { ethSigner }, starkPublicKey, token, config, }) {
|
|
20070
|
-
// TODO: please add a reasonable default here
|
|
20071
|
-
// eslint-disable-next-line default-case
|
|
20072
|
-
switch (token.type) {
|
|
20073
|
-
case 'ETH':
|
|
20074
|
-
return completeEthWithdrawalAction({ ethSigner, starkPublicKey, config });
|
|
20075
|
-
case 'ERC20':
|
|
20076
|
-
return completeERC20WithdrawalAction({
|
|
20077
|
-
ethSigner,
|
|
20078
|
-
starkPublicKey,
|
|
20079
|
-
token,
|
|
20080
|
-
config,
|
|
20081
|
-
});
|
|
20082
|
-
case 'ERC721':
|
|
20083
|
-
return completeERC721WithdrawalAction({
|
|
20084
|
-
ethSigner,
|
|
20085
|
-
starkPublicKey,
|
|
20086
|
-
token,
|
|
20087
|
-
config,
|
|
20088
|
-
});
|
|
20089
|
-
}
|
|
20090
|
-
}
|
|
20091
|
-
|
|
20092
|
-
async function createTrade({ signers: { ethSigner, starkSigner }, request, config, }) {
|
|
20093
|
-
await validateChain(ethSigner, config.immutableXConfig);
|
|
20094
|
-
const ethAddress = await ethSigner.getAddress();
|
|
20095
|
-
const tradesApi = new TradesApi$1(config.immutableXConfig.apiConfiguration);
|
|
20096
|
-
const signableResult = await tradesApi.getSignableTrade({
|
|
20097
|
-
getSignableTradeRequest: {
|
|
20098
|
-
user: ethAddress,
|
|
20099
|
-
order_id: request.order_id,
|
|
20100
|
-
fees: request.fees,
|
|
20101
|
-
},
|
|
20102
|
-
});
|
|
20103
|
-
const { signable_message: signableMessage, payload_hash: payloadHash } = signableResult.data;
|
|
20104
|
-
const ethSignature = await signRaw(signableMessage, ethSigner);
|
|
20105
|
-
const starkSignature = await starkSigner.signMessage(payloadHash);
|
|
20106
|
-
const createTradeResponse = await tradesApi.createTradeV3({
|
|
20107
|
-
createTradeRequest: {
|
|
20108
|
-
amount_buy: signableResult.data.amount_buy,
|
|
20109
|
-
amount_sell: signableResult.data.amount_sell,
|
|
20110
|
-
asset_id_buy: signableResult.data.asset_id_buy,
|
|
20111
|
-
asset_id_sell: signableResult.data.asset_id_sell,
|
|
20112
|
-
expiration_timestamp: signableResult.data.expiration_timestamp,
|
|
20113
|
-
fee_info: signableResult.data.fee_info,
|
|
20114
|
-
fees: request.fees,
|
|
20115
|
-
include_fees: true,
|
|
20116
|
-
nonce: signableResult.data.nonce,
|
|
20117
|
-
order_id: request.order_id,
|
|
20118
|
-
stark_key: signableResult.data.stark_key,
|
|
20119
|
-
vault_id_buy: signableResult.data.vault_id_buy,
|
|
20120
|
-
vault_id_sell: signableResult.data.vault_id_sell,
|
|
20121
|
-
stark_signature: starkSignature,
|
|
20122
|
-
},
|
|
20123
|
-
xImxEthAddress: ethAddress,
|
|
20124
|
-
xImxEthSignature: ethSignature,
|
|
20125
|
-
});
|
|
20126
|
-
return createTradeResponse.data;
|
|
20127
|
-
}
|
|
20128
|
-
|
|
20129
|
-
async function executeRegisterAndDepositEth(ethSigner, amount, assetType, starkPublicKey, vaultId, config, usersApi) {
|
|
20130
|
-
const etherKey = await ethSigner.getAddress();
|
|
20131
|
-
const coreContract = Contracts.Core.connect(config.ethConfiguration.coreContractAddress, ethSigner);
|
|
20132
|
-
const signableResult = await getSignableRegistrationOnchain(etherKey, starkPublicKey, usersApi);
|
|
20133
|
-
const populatedTransaction = await coreContract.populateTransaction.registerAndDepositEth(etherKey, starkPublicKey, signableResult.operator_signature, assetType, vaultId);
|
|
20134
|
-
return ethSigner.sendTransaction({ ...populatedTransaction, value: amount });
|
|
20135
|
-
}
|
|
20136
|
-
async function executeDepositEth(ethSigner, amount, assetType, starkPublicKey, vaultId, config) {
|
|
20137
|
-
const coreContract = Contracts.Core.connect(config.ethConfiguration.coreContractAddress, ethSigner);
|
|
20138
|
-
const populatedTransaction = await coreContract.populateTransaction['deposit(uint256,uint256,uint256)'](starkPublicKey, assetType, vaultId);
|
|
20139
|
-
return ethSigner.sendTransaction({ ...populatedTransaction, value: amount });
|
|
20140
|
-
}
|
|
20141
|
-
async function depositEth({ signers: { ethSigner }, deposit, config, }) {
|
|
20142
|
-
await validateChain(ethSigner, config.immutableXConfig);
|
|
20143
|
-
const user = await ethSigner.getAddress();
|
|
20144
|
-
const data = {
|
|
20145
|
-
decimals: 18,
|
|
20146
|
-
};
|
|
20147
|
-
const amount = parseUnits(deposit.amount, 'wei');
|
|
20148
|
-
const imxConfig = config.immutableXConfig;
|
|
20149
|
-
const depositsApi = new DepositsApi$1(imxConfig.apiConfiguration);
|
|
20150
|
-
const encodingApi = new EncodingApi$1(imxConfig.apiConfiguration);
|
|
20151
|
-
const usersApi = new UsersApi$1(imxConfig.apiConfiguration);
|
|
20152
|
-
const getSignableDepositRequest = {
|
|
20153
|
-
user,
|
|
20154
|
-
token: {
|
|
20155
|
-
type: deposit.type,
|
|
20156
|
-
data,
|
|
20157
|
-
},
|
|
20158
|
-
amount: amount.toString(),
|
|
20159
|
-
};
|
|
20160
|
-
const signableDepositResult = await depositsApi.getSignableDeposit({
|
|
20161
|
-
getSignableDepositRequest,
|
|
20162
|
-
});
|
|
20163
|
-
const encodingResult = await encodingApi.encodeAsset({
|
|
20164
|
-
assetType: 'asset',
|
|
20165
|
-
encodeAssetRequest: {
|
|
20166
|
-
token: {
|
|
20167
|
-
type: deposit.type,
|
|
20168
|
-
},
|
|
20169
|
-
},
|
|
20170
|
-
});
|
|
20171
|
-
const assetType = encodingResult.data.asset_type;
|
|
20172
|
-
const starkPublicKey = signableDepositResult.data.stark_key;
|
|
20173
|
-
const vaultId = signableDepositResult.data.vault_id;
|
|
20174
|
-
const isRegistered = await isRegisteredOnChain(starkPublicKey, ethSigner, config);
|
|
20175
|
-
if (!isRegistered) {
|
|
20176
|
-
return executeRegisterAndDepositEth(ethSigner, amount, assetType, starkPublicKey, vaultId, imxConfig, usersApi);
|
|
20177
|
-
}
|
|
20178
|
-
return executeDepositEth(ethSigner, amount, assetType, starkPublicKey, vaultId, imxConfig);
|
|
20179
|
-
}
|
|
20180
|
-
|
|
20181
|
-
async function executeRegisterAndDepositERC20(ethSigner, quantizedAmount, assetType, starkPublicKey, vaultId, config, usersApi) {
|
|
20182
|
-
const etherKey = await ethSigner.getAddress();
|
|
20183
|
-
const coreContract = Contracts.Core.connect(config.coreContractAddress, ethSigner);
|
|
20184
|
-
const signableResult = await getSignableRegistrationOnchain(etherKey, starkPublicKey, usersApi);
|
|
20185
|
-
const populatedTransaction = await coreContract.populateTransaction.registerAndDepositERC20(etherKey, starkPublicKey, signableResult.operator_signature, assetType, vaultId, quantizedAmount);
|
|
20186
|
-
return ethSigner.sendTransaction(populatedTransaction);
|
|
20187
|
-
}
|
|
20188
|
-
async function executeDepositERC20(ethSigner, quantizedAmount, assetType, starkPublicKey, vaultId, config) {
|
|
20189
|
-
const coreContract = Contracts.Core.connect(config.coreContractAddress, ethSigner);
|
|
20190
|
-
const populatedTransaction = await coreContract.populateTransaction.depositERC20(starkPublicKey, assetType, vaultId, quantizedAmount);
|
|
20191
|
-
return ethSigner.sendTransaction(populatedTransaction);
|
|
20192
|
-
}
|
|
20193
|
-
async function depositERC20({ signers: { ethSigner }, deposit, config, }) {
|
|
20194
|
-
await validateChain(ethSigner, config.immutableXConfig);
|
|
20195
|
-
const { apiConfiguration, ethConfiguration } = config.immutableXConfig;
|
|
20196
|
-
const user = await ethSigner.getAddress();
|
|
20197
|
-
const tokensApi = new TokensApi$2(apiConfiguration);
|
|
20198
|
-
const depositsApi = new DepositsApi$1(apiConfiguration);
|
|
20199
|
-
const encodingApi = new EncodingApi$1(apiConfiguration);
|
|
20200
|
-
const usersApi = new UsersApi$1(apiConfiguration);
|
|
20201
|
-
// Get decimals for this specific ERC20
|
|
20202
|
-
const token = await tokensApi.getToken({ address: deposit.tokenAddress });
|
|
20203
|
-
// TODO: remove once fixed
|
|
20204
|
-
// eslint-disable-next-line radix
|
|
20205
|
-
const decimals = parseInt(token.data.decimals);
|
|
20206
|
-
const data = {
|
|
20207
|
-
decimals,
|
|
20208
|
-
token_address: deposit.tokenAddress,
|
|
20209
|
-
};
|
|
20210
|
-
const amount = parseUnits(deposit.amount, 0); // 0 to always use undecimalized value
|
|
20211
|
-
// Approve whether an amount of token from an account can be spent by a third-party account
|
|
20212
|
-
const tokenContract = Contracts.IERC20.connect(deposit.tokenAddress, ethSigner);
|
|
20213
|
-
const approveTransaction = await tokenContract.populateTransaction.approve(ethConfiguration.coreContractAddress, amount);
|
|
20214
|
-
await ethSigner.sendTransaction(approveTransaction);
|
|
20215
|
-
const getSignableDepositRequest = {
|
|
20216
|
-
user,
|
|
20217
|
-
token: {
|
|
20218
|
-
type: deposit.type,
|
|
20219
|
-
data,
|
|
20220
|
-
},
|
|
20221
|
-
amount: amount.toString(),
|
|
20222
|
-
};
|
|
20223
|
-
const signableDepositResult = await depositsApi.getSignableDeposit({
|
|
20224
|
-
getSignableDepositRequest,
|
|
20225
|
-
});
|
|
20226
|
-
// Perform encoding on asset details to get an assetType (required for stark contract request)
|
|
20227
|
-
const encodingResult = await encodingApi.encodeAsset({
|
|
20228
|
-
assetType: 'asset',
|
|
20229
|
-
encodeAssetRequest: {
|
|
20230
|
-
token: {
|
|
20231
|
-
type: deposit.type,
|
|
20232
|
-
data: {
|
|
20233
|
-
token_address: deposit.tokenAddress,
|
|
20234
|
-
},
|
|
20235
|
-
},
|
|
20236
|
-
},
|
|
20237
|
-
});
|
|
20238
|
-
const assetType = encodingResult.data.asset_type;
|
|
20239
|
-
const starkPublicKey = signableDepositResult.data.stark_key;
|
|
20240
|
-
const vaultId = signableDepositResult.data.vault_id;
|
|
20241
|
-
const quantizedAmount = BigNumber$2.from(signableDepositResult.data.amount);
|
|
20242
|
-
const isRegistered = await isRegisteredOnChain(starkPublicKey, ethSigner, config);
|
|
20243
|
-
if (!isRegistered) {
|
|
20244
|
-
return executeRegisterAndDepositERC20(ethSigner, quantizedAmount, assetType, starkPublicKey, vaultId, ethConfiguration, usersApi);
|
|
20245
|
-
}
|
|
20246
|
-
return executeDepositERC20(ethSigner, quantizedAmount, assetType, starkPublicKey, vaultId, ethConfiguration);
|
|
20247
|
-
}
|
|
20248
|
-
|
|
20249
|
-
async function executeDepositERC721(ethSigner, tokenId, assetType, starkPublicKey, vaultId, config) {
|
|
20250
|
-
const coreContract = Contracts.Core.connect(config.ethConfiguration.coreContractAddress, ethSigner);
|
|
20251
|
-
const populatedTransaction = await coreContract.populateTransaction.depositNft(starkPublicKey, assetType, vaultId, tokenId);
|
|
20252
|
-
return ethSigner.sendTransaction(populatedTransaction);
|
|
20253
|
-
}
|
|
20254
|
-
async function depositERC721({ signers: { ethSigner }, deposit, config, }) {
|
|
20255
|
-
await validateChain(ethSigner, config.immutableXConfig);
|
|
20256
|
-
const user = await ethSigner.getAddress();
|
|
20257
|
-
const { immutableXConfig } = config;
|
|
20258
|
-
const depositsApi = new DepositsApi$1(immutableXConfig.apiConfiguration);
|
|
20259
|
-
const encodingApi = new EncodingApi$1(immutableXConfig.apiConfiguration);
|
|
20260
|
-
const usersApi = new UsersApi$1(immutableXConfig.apiConfiguration);
|
|
20261
|
-
const data = {
|
|
20262
|
-
token_address: deposit.tokenAddress,
|
|
20263
|
-
token_id: deposit.tokenId,
|
|
20264
|
-
};
|
|
20265
|
-
const amount = '1';
|
|
20266
|
-
const getSignableDepositRequest = {
|
|
20267
|
-
user,
|
|
20268
|
-
token: {
|
|
20269
|
-
type: deposit.type,
|
|
20270
|
-
data,
|
|
20271
|
-
},
|
|
20272
|
-
amount: amount.toString(),
|
|
20273
|
-
};
|
|
20274
|
-
const signableDepositResult = await depositsApi.getSignableDeposit({
|
|
20275
|
-
getSignableDepositRequest,
|
|
20276
|
-
});
|
|
20277
|
-
// Perform encoding on asset details to get an assetType (required for stark contract request)
|
|
20278
|
-
const encodingResult = await encodingApi.encodeAsset({
|
|
20279
|
-
assetType: 'asset',
|
|
20280
|
-
encodeAssetRequest: {
|
|
20281
|
-
token: {
|
|
20282
|
-
type: deposit.type,
|
|
20283
|
-
data: {
|
|
20284
|
-
token_address: deposit.tokenAddress,
|
|
20285
|
-
token_id: deposit.tokenId,
|
|
20286
|
-
},
|
|
20287
|
-
},
|
|
20288
|
-
},
|
|
20289
|
-
});
|
|
20290
|
-
const assetType = encodingResult.data.asset_type;
|
|
20291
|
-
const starkPublicKey = signableDepositResult.data.stark_key;
|
|
20292
|
-
const vaultId = signableDepositResult.data.vault_id;
|
|
20293
|
-
const isRegistered = await isRegisteredOnChain(starkPublicKey, ethSigner, config);
|
|
20294
|
-
// Approve whether an amount of token from an account can be spent by a third-party account
|
|
20295
|
-
const tokenContract = Contracts.IERC721.connect(deposit.tokenAddress, ethSigner);
|
|
20296
|
-
const operator = immutableXConfig.ethConfiguration.coreContractAddress;
|
|
20297
|
-
const isApprovedForAll = await tokenContract.isApprovedForAll(user, operator);
|
|
20298
|
-
if (!isApprovedForAll) {
|
|
20299
|
-
await tokenContract.setApprovalForAll(operator, true);
|
|
20300
|
-
}
|
|
20301
|
-
if (!isRegistered) {
|
|
20302
|
-
const signableResult = await getSignableRegistrationOnchain(user, starkPublicKey, usersApi);
|
|
20303
|
-
const coreContract = Contracts.Core.connect(immutableXConfig.ethConfiguration.coreContractAddress, ethSigner);
|
|
20304
|
-
// Note: proxy registration contract registerAndDepositNft method is not used as
|
|
20305
|
-
// it currently fails erc721 transfer ownership check
|
|
20306
|
-
await coreContract.registerUser(user, starkPublicKey, signableResult.operator_signature);
|
|
20307
|
-
}
|
|
20308
|
-
return executeDepositERC721(ethSigner, deposit.tokenId, assetType, starkPublicKey, vaultId, immutableXConfig);
|
|
20309
|
-
}
|
|
20310
|
-
|
|
20311
|
-
// TODO: remove once fixed deposit variable shadowing
|
|
20312
|
-
// eslint-disable-next-line consistent-return, @typescript-eslint/no-shadow
|
|
20313
|
-
async function deposit({ signers, deposit, config }) {
|
|
20314
|
-
// TODO: please add a reasonable default here
|
|
20315
|
-
// eslint-disable-next-line default-case
|
|
20316
|
-
switch (deposit.type) {
|
|
20317
|
-
case 'ETH':
|
|
20318
|
-
return depositEth({ signers, deposit, config });
|
|
20319
|
-
case 'ERC20':
|
|
20320
|
-
return depositERC20({ signers, deposit, config });
|
|
20321
|
-
case 'ERC721':
|
|
20322
|
-
return depositERC721({ signers, deposit, config });
|
|
20323
|
-
}
|
|
20324
|
-
}
|
|
20325
|
-
|
|
20326
|
-
async function exchangeTransfer({ signers, request, config, }) {
|
|
20327
|
-
await validateChain(signers.ethSigner, config.immutableXConfig);
|
|
20328
|
-
const exchangeApi = new ExchangesApi$1(config.immutableXConfig.apiConfiguration);
|
|
20329
|
-
const ethAddress = await signers.ethSigner.getAddress();
|
|
20330
|
-
const transferAmount = request.amount;
|
|
20331
|
-
const signableResult = await exchangeApi.getExchangeSignableTransfer({
|
|
20332
|
-
id: request.transactionID,
|
|
20333
|
-
getSignableTransferRequest: {
|
|
20334
|
-
sender: ethAddress,
|
|
20335
|
-
token: convertToSignableToken(request),
|
|
20336
|
-
amount: transferAmount,
|
|
20337
|
-
receiver: request.receiver,
|
|
20338
|
-
},
|
|
20339
|
-
});
|
|
20340
|
-
const { signable_message: signableMessage, payload_hash: payloadHash } = signableResult.data;
|
|
20341
|
-
const ethSignature = await signRaw(signableMessage, signers.ethSigner);
|
|
20342
|
-
const starkSignature = await signers.starkSigner.signMessage(payloadHash);
|
|
20343
|
-
const transferSigningParams = {
|
|
20344
|
-
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
20345
|
-
sender_stark_key: signableResult.data.sender_stark_key,
|
|
20346
|
-
sender_vault_id: signableResult.data.sender_vault_id,
|
|
20347
|
-
receiver_stark_key: signableResult.data.receiver_stark_key,
|
|
20348
|
-
receiver_vault_id: signableResult.data.receiver_vault_id,
|
|
20349
|
-
asset_id: signableResult.data.asset_id,
|
|
20350
|
-
amount: signableResult.data.amount,
|
|
20351
|
-
nonce: signableResult.data.nonce,
|
|
20352
|
-
expiration_timestamp: signableResult.data.expiration_timestamp,
|
|
20353
|
-
stark_signature: starkSignature,
|
|
20354
|
-
};
|
|
20355
|
-
const response = await exchangeApi.createExchangeTransfer({
|
|
20356
|
-
id: request.transactionID,
|
|
20357
|
-
createTransferRequest: transferSigningParams,
|
|
20358
|
-
xImxEthAddress: ethAddress,
|
|
20359
|
-
xImxEthSignature: ethSignature,
|
|
20360
|
-
});
|
|
20361
|
-
return {
|
|
20362
|
-
sent_signature: response?.data.sent_signature,
|
|
20363
|
-
status: response?.data.status?.toString(),
|
|
20364
|
-
time: response?.data.time,
|
|
20365
|
-
transfer_id: response?.data.transfer_id,
|
|
20366
|
-
};
|
|
20367
|
-
}
|
|
20368
|
-
|
|
20369
|
-
class GenericIMXProvider {
|
|
20370
|
-
config;
|
|
20371
|
-
signers;
|
|
20372
|
-
constructor(config, ethSigner, starkSigner) {
|
|
20373
|
-
this.config = config;
|
|
20374
|
-
this.signers = { ethSigner, starkSigner };
|
|
20375
|
-
}
|
|
20376
|
-
async getAddress() {
|
|
20377
|
-
return this.signers.ethSigner.getAddress();
|
|
20378
|
-
}
|
|
20379
|
-
async isRegisteredOffchain() {
|
|
20380
|
-
const ethAddress = await this.getAddress();
|
|
20381
|
-
return isRegisteredOffchain(ethAddress, this.config);
|
|
20382
|
-
}
|
|
20383
|
-
registerOffchain() {
|
|
20384
|
-
return registerOffchain(this.signers, this.config);
|
|
20385
|
-
}
|
|
20386
|
-
batchNftTransfer(request) {
|
|
20387
|
-
return batchTransfer({
|
|
20388
|
-
signers: this.signers,
|
|
20389
|
-
request,
|
|
20390
|
-
config: this.config,
|
|
20391
|
-
});
|
|
20392
|
-
}
|
|
20393
|
-
cancelOrder(request) {
|
|
20394
|
-
return cancelOrder({
|
|
20395
|
-
signers: this.signers,
|
|
20396
|
-
request,
|
|
20397
|
-
config: this.config,
|
|
20398
|
-
});
|
|
20399
|
-
}
|
|
20400
|
-
completeWithdrawal(starkPublicKey, token) {
|
|
20401
|
-
return completeWithdrawal({
|
|
20402
|
-
config: this.config,
|
|
20403
|
-
signers: this.signers,
|
|
20404
|
-
token,
|
|
20405
|
-
starkPublicKey,
|
|
20406
|
-
});
|
|
20407
|
-
}
|
|
20408
|
-
createOrder(request) {
|
|
20409
|
-
return createOrder({
|
|
20410
|
-
signers: this.signers,
|
|
20411
|
-
request,
|
|
20412
|
-
config: this.config,
|
|
20413
|
-
});
|
|
20414
|
-
}
|
|
20415
|
-
createTrade(request) {
|
|
20416
|
-
return createTrade({
|
|
20417
|
-
signers: this.signers,
|
|
20418
|
-
request,
|
|
20419
|
-
config: this.config,
|
|
20420
|
-
});
|
|
20421
|
-
}
|
|
20422
|
-
deposit(tokenAmount) {
|
|
20423
|
-
return deposit({
|
|
20424
|
-
signers: this.signers,
|
|
20425
|
-
deposit: tokenAmount,
|
|
20426
|
-
config: this.config,
|
|
20427
|
-
});
|
|
20428
|
-
}
|
|
20429
|
-
exchangeTransfer(request) {
|
|
20430
|
-
return exchangeTransfer({
|
|
20431
|
-
signers: this.signers,
|
|
20432
|
-
request,
|
|
20433
|
-
config: this.config,
|
|
20434
|
-
});
|
|
20435
|
-
}
|
|
20436
|
-
async isRegisteredOnchain() {
|
|
20437
|
-
const starkPublicKey = await this.signers.starkSigner.getAddress();
|
|
20438
|
-
return isRegisteredOnChain(starkPublicKey, this.signers.ethSigner, this.config);
|
|
20439
|
-
}
|
|
20440
|
-
prepareWithdrawal(request) {
|
|
20441
|
-
return prepareWithdrawal({
|
|
20442
|
-
signers: this.signers,
|
|
20443
|
-
withdrawal: request,
|
|
20444
|
-
config: this.config,
|
|
20445
|
-
});
|
|
20446
|
-
}
|
|
20447
|
-
transfer(request) {
|
|
20448
|
-
return transfer({
|
|
20449
|
-
signers: this.signers,
|
|
20450
|
-
request,
|
|
20451
|
-
config: this.config,
|
|
20452
|
-
});
|
|
20453
|
-
}
|
|
20454
|
-
}
|
|
20455
|
-
|
|
20456
|
-
const WALLET_ACTION = {
|
|
20457
|
-
// TODO: remove once fixed - consider using an enum
|
|
20458
|
-
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
20459
|
-
SWITCH_CHAIN: 'wallet_switchEthereumChain',
|
|
20460
|
-
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
20461
|
-
CONNECT: 'eth_requestAccounts',
|
|
20462
|
-
};
|
|
20463
|
-
function isRequestableProvider(provider) {
|
|
20464
|
-
return !!provider?.request;
|
|
20465
|
-
}
|
|
20466
|
-
async function connectProvider(provider, chainID) {
|
|
20467
|
-
await provider.request({ method: WALLET_ACTION.CONNECT });
|
|
20468
|
-
if (chainID) {
|
|
20469
|
-
await provider.request({
|
|
20470
|
-
method: WALLET_ACTION.SWITCH_CHAIN,
|
|
20471
|
-
params: [{ chainId: `0x${chainID.toString(16)}` }],
|
|
20472
|
-
});
|
|
20473
|
-
}
|
|
20474
|
-
}
|
|
20475
|
-
|
|
20476
|
-
const ERRORS = {
|
|
20477
|
-
// TODO: remove once fixed - consider using something in line with the naming convention
|
|
20478
|
-
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
20479
|
-
PROVIDER_NOT_FOUND: 'The Metamask provider was not found',
|
|
20480
|
-
};
|
|
20481
|
-
async function connect$1({ chainID, }) {
|
|
20482
|
-
const provider = (await detectEthereumProvider());
|
|
20483
|
-
if (!isRequestableProvider(provider)) {
|
|
20484
|
-
throw new Error(ERRORS.PROVIDER_NOT_FOUND);
|
|
20485
|
-
}
|
|
20486
|
-
await connectProvider(provider, chainID);
|
|
20487
|
-
// NOTE: if we want to listen to Metamask events in the future, we can add a
|
|
20488
|
-
// listener here.
|
|
20489
|
-
return new ethers.providers.Web3Provider(provider);
|
|
20490
|
-
}
|
|
20491
|
-
|
|
20492
|
-
const COMMUNICATION_TYPE = 'message';
|
|
20493
|
-
var RequestEventType;
|
|
20494
|
-
(function (RequestEventType) {
|
|
20495
|
-
RequestEventType["GET_CONNECTION_REQUEST"] = "GET_CONNECTION_REQUEST";
|
|
20496
|
-
RequestEventType["CONNECT_WALLET_REQUEST"] = "CONNECT_WALLET_REQUEST";
|
|
20497
|
-
RequestEventType["SIGN_MESSAGE_REQUEST"] = "SIGN_MESSAGE_REQUEST";
|
|
20498
|
-
RequestEventType["DISCONNECT_WALLET_REQUEST"] = "DISCONNECT_WALLET_REQUEST";
|
|
20499
|
-
})(RequestEventType || (RequestEventType = {}));
|
|
20500
|
-
var ResponseEventType;
|
|
20501
|
-
(function (ResponseEventType) {
|
|
20502
|
-
ResponseEventType["CONNECT_WALLET_RESPONSE"] = "CONNECT_WALLET_RESPONSE";
|
|
20503
|
-
ResponseEventType["SIGN_MESSAGE_RESPONSE"] = "SIGN_MESSAGE_RESPONSE";
|
|
20504
|
-
ResponseEventType["GET_CONNECTION_RESPONSE"] = "GET_CONNECTION_RESPONSE";
|
|
20505
|
-
ResponseEventType["DISCONNECT_WALLET_RESPONSE"] = "DISCONNECT_WALLET_RESPONSE";
|
|
20506
|
-
})(ResponseEventType || (ResponseEventType = {}));
|
|
20507
|
-
|
|
20508
|
-
function postRequestMessage(iframe, payload) {
|
|
20509
|
-
if (iframe && iframe.contentWindow) {
|
|
20510
|
-
iframe.contentWindow.postMessage(payload, new URL(iframe.src).origin);
|
|
20511
|
-
}
|
|
20512
|
-
}
|
|
20513
|
-
|
|
20514
|
-
function messageResponseListener(iframe, event, eventType, callback) {
|
|
20515
|
-
if (iframe && event.source !== iframe.contentWindow) {
|
|
20516
|
-
return;
|
|
20517
|
-
}
|
|
20518
|
-
const l2WalletMessage = event.data;
|
|
20519
|
-
if (l2WalletMessage.type !== eventType) {
|
|
20520
|
-
return;
|
|
20521
|
-
}
|
|
20522
|
-
callback(l2WalletMessage.details);
|
|
20523
|
-
}
|
|
20524
|
-
|
|
20525
|
-
class ImxSigner {
|
|
20526
|
-
publicAddress;
|
|
20527
|
-
iframe;
|
|
20528
|
-
constructor(publicAddress, iframe) {
|
|
20529
|
-
this.publicAddress = publicAddress;
|
|
20530
|
-
this.iframe = iframe;
|
|
20531
|
-
}
|
|
20532
|
-
getAddress() {
|
|
20533
|
-
return this.publicAddress;
|
|
20534
|
-
}
|
|
20535
|
-
signMessage(rawMessage) {
|
|
20536
|
-
return new Promise((resolve, reject) => {
|
|
20537
|
-
const listener = (event) => {
|
|
20538
|
-
messageResponseListener(this.iframe, event, ResponseEventType.SIGN_MESSAGE_RESPONSE, (messageDetails) => {
|
|
20539
|
-
window.removeEventListener(COMMUNICATION_TYPE, listener);
|
|
20540
|
-
if (!messageDetails.success) {
|
|
20541
|
-
reject(new Error(messageDetails.error?.message));
|
|
20542
|
-
}
|
|
20543
|
-
resolve(messageDetails.data.signedMessage);
|
|
20544
|
-
});
|
|
20545
|
-
};
|
|
20546
|
-
window.addEventListener(COMMUNICATION_TYPE, listener);
|
|
20547
|
-
postRequestMessage(this.iframe, {
|
|
20548
|
-
type: RequestEventType.SIGN_MESSAGE_REQUEST,
|
|
20549
|
-
details: { starkPublicKey: this.publicAddress, message: rawMessage },
|
|
20550
|
-
});
|
|
20551
|
-
});
|
|
20552
|
-
}
|
|
20553
|
-
getIFrame() {
|
|
20554
|
-
return this.iframe;
|
|
20555
|
-
}
|
|
20556
|
-
}
|
|
20557
|
-
|
|
20558
|
-
const IMX_WALLET_IFRAME_ID = 'imx-wallet-app';
|
|
20559
|
-
const IMX_WALLET_IFRAME_HOSTS = {
|
|
20560
|
-
[Environment$1.SANDBOX]: 'https://wallets.sandbox.immutable.com',
|
|
20561
|
-
[Environment$1.PRODUCTION]: 'https://wallets.immutable.com',
|
|
20562
|
-
};
|
|
20563
|
-
const IMX_WALLET_IFRAME_STYLE = 'display: none;';
|
|
20564
|
-
function getIFrame() {
|
|
20565
|
-
return document.querySelector(`iframe#${IMX_WALLET_IFRAME_ID}`);
|
|
20566
|
-
}
|
|
20567
|
-
async function setupIFrame(env) {
|
|
20568
|
-
return new Promise((resolve) => {
|
|
20569
|
-
const iframe = document.createElement('iframe');
|
|
20570
|
-
iframe.setAttribute('id', IMX_WALLET_IFRAME_ID);
|
|
20571
|
-
iframe.setAttribute('src', IMX_WALLET_IFRAME_HOSTS[env]);
|
|
20572
|
-
iframe.setAttribute('style', IMX_WALLET_IFRAME_STYLE);
|
|
20573
|
-
document.body.appendChild(iframe);
|
|
20574
|
-
iframe.onload = () => resolve(iframe);
|
|
20575
|
-
});
|
|
20576
|
-
}
|
|
20577
|
-
async function getOrSetupIFrame(env) {
|
|
20578
|
-
const iframe = getIFrame();
|
|
20579
|
-
if (iframe)
|
|
20580
|
-
return iframe;
|
|
20581
|
-
return await setupIFrame(env);
|
|
20582
|
-
}
|
|
20583
|
-
|
|
20584
|
-
const DEFAULT_CONNECTION_MESSAGE = 'Only sign this request if you’ve initiated an action with Immutable X.';
|
|
20585
|
-
const CONNECTION_FAILED_ERROR = 'The L2 IMX Wallet connection has failed';
|
|
20586
|
-
async function connect(l1Provider, env) {
|
|
20587
|
-
const l1Signer = l1Provider.getSigner();
|
|
20588
|
-
const address = await l1Signer.getAddress();
|
|
20589
|
-
const signature = await l1Signer.signMessage(DEFAULT_CONNECTION_MESSAGE);
|
|
20590
|
-
const iframe = await getOrSetupIFrame(env);
|
|
20591
|
-
return new Promise((resolve, reject) => {
|
|
20592
|
-
const listener = (event) => {
|
|
20593
|
-
messageResponseListener(iframe, event, ResponseEventType.CONNECT_WALLET_RESPONSE, (messageDetails) => {
|
|
20594
|
-
window.removeEventListener(COMMUNICATION_TYPE, listener);
|
|
20595
|
-
if (!messageDetails.success) {
|
|
20596
|
-
reject(new Error(CONNECTION_FAILED_ERROR));
|
|
20597
|
-
}
|
|
20598
|
-
resolve(new ImxSigner(messageDetails.data.starkPublicKey, iframe));
|
|
20599
|
-
});
|
|
20600
|
-
};
|
|
20601
|
-
window.addEventListener(COMMUNICATION_TYPE, listener);
|
|
20602
|
-
postRequestMessage(iframe, {
|
|
20603
|
-
type: RequestEventType.CONNECT_WALLET_REQUEST,
|
|
20604
|
-
details: { ethAddress: address, signature },
|
|
20605
|
-
});
|
|
20606
|
-
});
|
|
20607
|
-
}
|
|
20608
|
-
async function disconnect(imxSigner) {
|
|
20609
|
-
const iframe = imxSigner.getIFrame();
|
|
20610
|
-
return new Promise((resolve, reject) => {
|
|
20611
|
-
const listener = (event) => {
|
|
20612
|
-
messageResponseListener(iframe, event, ResponseEventType.DISCONNECT_WALLET_RESPONSE, (messageDetails) => {
|
|
20613
|
-
window.removeEventListener(COMMUNICATION_TYPE, listener);
|
|
20614
|
-
if (!messageDetails.success && messageDetails.error) {
|
|
20615
|
-
reject(messageDetails.error);
|
|
20616
|
-
}
|
|
20617
|
-
iframe.remove();
|
|
20618
|
-
resolve();
|
|
20619
|
-
});
|
|
20620
|
-
};
|
|
20621
|
-
window.addEventListener(COMMUNICATION_TYPE, listener);
|
|
20622
|
-
postRequestMessage(iframe, {
|
|
20623
|
-
type: RequestEventType.DISCONNECT_WALLET_REQUEST,
|
|
20624
|
-
details: { starkPublicKey: imxSigner.getAddress() },
|
|
20625
|
-
});
|
|
20626
|
-
});
|
|
20627
|
-
}
|
|
20628
|
-
|
|
20629
|
-
var ProviderErrorType;
|
|
20630
|
-
(function (ProviderErrorType) {
|
|
20631
|
-
ProviderErrorType["PROVIDER_CONNECTION_ERROR"] = "PROVIDER_CONNECTION_ERROR";
|
|
20632
|
-
ProviderErrorType["WALLET_CONNECTION_ERROR"] = "WALLET_CONNECTION_ERROR";
|
|
20633
|
-
})(ProviderErrorType || (ProviderErrorType = {}));
|
|
20634
|
-
class ProviderError extends Error {
|
|
20635
|
-
type;
|
|
20636
|
-
constructor(message, type) {
|
|
20637
|
-
super(message);
|
|
20638
|
-
this.type = type;
|
|
20639
|
-
}
|
|
20640
|
-
}
|
|
20641
|
-
const withProviderError = async (fn, customError) => {
|
|
20642
|
-
try {
|
|
20643
|
-
return await fn();
|
|
20644
|
-
}
|
|
20645
|
-
catch (error) {
|
|
20646
|
-
const errorMessage = customError.message || `${error.message}` || 'UnknownError';
|
|
20647
|
-
throw new ProviderError(errorMessage, customError.type);
|
|
20648
|
-
}
|
|
20649
|
-
};
|
|
20650
|
-
|
|
20651
|
-
class MetaMaskIMXProvider extends GenericIMXProvider {
|
|
20652
|
-
static imxSigner;
|
|
20653
|
-
static async connect(config) {
|
|
20654
|
-
return await withProviderError(async () => {
|
|
20655
|
-
const metaMaskProvider = await connect$1({
|
|
20656
|
-
chainID: config.immutableXConfig.ethConfiguration.chainID,
|
|
20657
|
-
});
|
|
20658
|
-
this.imxSigner = await connect(metaMaskProvider, config.baseConfig.environment);
|
|
20659
|
-
return new MetaMaskIMXProvider(config, metaMaskProvider.getSigner(), this.imxSigner);
|
|
20660
|
-
}, { type: ProviderErrorType.WALLET_CONNECTION_ERROR });
|
|
20661
|
-
}
|
|
20662
|
-
static async disconnect() {
|
|
20663
|
-
if (!this.imxSigner) {
|
|
20664
|
-
throw new ProviderError('Attempted to disconnect from the MetaMask IMX provider without an established connection', ProviderErrorType.PROVIDER_CONNECTION_ERROR);
|
|
20665
|
-
}
|
|
20666
|
-
return withProviderError(async () => {
|
|
20667
|
-
await disconnect(this.imxSigner);
|
|
20668
|
-
}, { type: ProviderErrorType.PROVIDER_CONNECTION_ERROR });
|
|
20669
|
-
}
|
|
20670
|
-
static async signMessage(message) {
|
|
20671
|
-
if (!this.imxSigner) {
|
|
20672
|
-
throw new ProviderError('Attempted to sign a message with the MetaMask IMX provider without an established connection', ProviderErrorType.PROVIDER_CONNECTION_ERROR);
|
|
20673
|
-
}
|
|
20674
|
-
return withProviderError(async () => await this.imxSigner.signMessage(message), { type: ProviderErrorType.PROVIDER_CONNECTION_ERROR });
|
|
20675
|
-
}
|
|
20676
|
-
}
|
|
20677
|
-
|
|
20678
|
-
class ProviderConfiguration {
|
|
20679
|
-
immutableXConfig;
|
|
20680
|
-
baseConfig;
|
|
20681
|
-
constructor({ baseConfig, overrides }) {
|
|
20682
|
-
this.baseConfig = baseConfig;
|
|
20683
|
-
if (overrides) {
|
|
20684
|
-
this.immutableXConfig = overrides.immutableXConfig;
|
|
20685
|
-
}
|
|
20686
|
-
else {
|
|
20687
|
-
// TODO: remove once a sensible default is chosen
|
|
20688
|
-
// eslint-disable-next-line default-case
|
|
20689
|
-
switch (baseConfig.environment) {
|
|
20690
|
-
case Environment$1.SANDBOX: {
|
|
20691
|
-
this.immutableXConfig = Config.SANDBOX;
|
|
20692
|
-
break;
|
|
20693
|
-
}
|
|
20694
|
-
case Environment$1.PRODUCTION: {
|
|
20695
|
-
this.immutableXConfig = Config.PRODUCTION;
|
|
20696
|
-
break;
|
|
20697
|
-
}
|
|
20698
|
-
}
|
|
20699
|
-
}
|
|
20700
|
-
}
|
|
20701
|
-
}
|
|
20702
|
-
|
|
20703
|
-
var provider = /*#__PURE__*/Object.freeze({
|
|
20704
|
-
__proto__: null,
|
|
20705
|
-
GenericIMXProvider: GenericIMXProvider,
|
|
20706
|
-
MetaMaskIMXProvider: MetaMaskIMXProvider,
|
|
20707
|
-
ProviderConfiguration: ProviderConfiguration
|
|
20708
|
-
});
|
|
20709
|
-
|
|
20710
|
-
function bind(fn, thisArg) {
|
|
20711
|
-
return function wrap() {
|
|
20712
|
-
return fn.apply(thisArg, arguments);
|
|
20713
|
-
};
|
|
20714
|
-
}
|
|
20715
|
-
|
|
20716
|
-
// utils is a library of generic helper functions non-specific to axios
|
|
20717
|
-
|
|
20718
|
-
const {toString} = Object.prototype;
|
|
20719
|
-
const {getPrototypeOf} = Object;
|
|
20720
|
-
|
|
20721
|
-
const kindOf = (cache => thing => {
|
|
20722
|
-
const str = toString.call(thing);
|
|
20723
|
-
return cache[str] || (cache[str] = str.slice(8, -1).toLowerCase());
|
|
20724
|
-
})(Object.create(null));
|
|
20725
|
-
|
|
20726
|
-
const kindOfTest = (type) => {
|
|
20727
|
-
type = type.toLowerCase();
|
|
20728
|
-
return (thing) => kindOf(thing) === type
|
|
20729
|
-
};
|
|
20730
|
-
|
|
20731
|
-
const typeOfTest = type => thing => typeof thing === type;
|
|
20732
|
-
|
|
20733
|
-
/**
|
|
20734
|
-
* Determine if a value is an Array
|
|
20735
|
-
*
|
|
20736
|
-
* @param {Object} val The value to test
|
|
20737
|
-
*
|
|
20738
|
-
* @returns {boolean} True if value is an Array, otherwise false
|
|
20739
|
-
*/
|
|
20740
|
-
const {isArray} = Array;
|
|
20741
|
-
|
|
20742
|
-
/**
|
|
20743
|
-
* Determine if a value is undefined
|
|
20744
|
-
*
|
|
20745
|
-
* @param {*} val The value to test
|
|
20746
|
-
*
|
|
20747
|
-
* @returns {boolean} True if the value is undefined, otherwise false
|
|
20748
|
-
*/
|
|
20749
|
-
const isUndefined = typeOfTest('undefined');
|
|
20750
|
-
|
|
20751
|
-
/**
|
|
20752
|
-
* Determine if a value is a Buffer
|
|
20753
|
-
*
|
|
20754
|
-
* @param {*} val The value to test
|
|
20755
|
-
*
|
|
20756
|
-
* @returns {boolean} True if value is a Buffer, otherwise false
|
|
20757
|
-
*/
|
|
20758
|
-
function isBuffer(val) {
|
|
20759
|
-
return val !== null && !isUndefined(val) && val.constructor !== null && !isUndefined(val.constructor)
|
|
20760
|
-
&& isFunction(val.constructor.isBuffer) && val.constructor.isBuffer(val);
|
|
20761
|
-
}
|
|
20762
|
-
|
|
20763
|
-
/**
|
|
20764
|
-
* Determine if a value is an ArrayBuffer
|
|
20765
|
-
*
|
|
20766
|
-
* @param {*} val The value to test
|
|
20767
|
-
*
|
|
20768
|
-
* @returns {boolean} True if value is an ArrayBuffer, otherwise false
|
|
20769
|
-
*/
|
|
20770
|
-
const isArrayBuffer = kindOfTest('ArrayBuffer');
|
|
19671
|
+
/**
|
|
19672
|
+
* Determine if a value is an ArrayBuffer
|
|
19673
|
+
*
|
|
19674
|
+
* @param {*} val The value to test
|
|
19675
|
+
*
|
|
19676
|
+
* @returns {boolean} True if value is an ArrayBuffer, otherwise false
|
|
19677
|
+
*/
|
|
19678
|
+
const isArrayBuffer = kindOfTest('ArrayBuffer');
|
|
20771
19679
|
|
|
20772
19680
|
|
|
20773
19681
|
/**
|
|
@@ -41973,13 +40881,13 @@ const ERC721ABI = [
|
|
|
41973
40881
|
},
|
|
41974
40882
|
];
|
|
41975
40883
|
// Gas overrides -- Anti-spam mechanism for when the baseFee drops low
|
|
41976
|
-
// https://
|
|
41977
|
-
const
|
|
41978
|
-
maxFeePerGas: BigNumber$1.from(
|
|
41979
|
-
maxPriorityFeePerGas: BigNumber$1.from(
|
|
40884
|
+
// https://docs.immutable.com/docs/zkEVM/architecture/gas-config
|
|
40885
|
+
const IMMUTABLE_ZKVEM_GAS_OVERRIDES = {
|
|
40886
|
+
maxFeePerGas: BigNumber$1.from(15e9),
|
|
40887
|
+
maxPriorityFeePerGas: BigNumber$1.from(10e9),
|
|
41980
40888
|
};
|
|
41981
40889
|
|
|
41982
|
-
const SDK_VERSION_MARKER = '0.
|
|
40890
|
+
const SDK_VERSION_MARKER = '0.45.1';
|
|
41983
40891
|
// This SDK version is replaced by the `yarn build` command ran on the root level
|
|
41984
40892
|
const globalPackageVersion = () => SDK_VERSION_MARKER;
|
|
41985
40893
|
|
|
@@ -42127,6 +41035,9 @@ class CheckoutConfiguration {
|
|
|
42127
41035
|
}
|
|
42128
41036
|
|
|
42129
41037
|
const isMatchingAddress = (addressA = '', addressB = '') => (addressA.toLowerCase() === addressB.toLowerCase());
|
|
41038
|
+
const isZkEvmChainId = (chainId) => chainId === ChainId.IMTBL_ZKEVM_DEVNET
|
|
41039
|
+
|| chainId === ChainId.IMTBL_ZKEVM_TESTNET
|
|
41040
|
+
|| chainId === ChainId.IMTBL_ZKEVM_MAINNET;
|
|
42130
41041
|
|
|
42131
41042
|
const getTokenAllowList = async (config, { type = TokenFilterTypes.ALL, chainId, exclude, }) => {
|
|
42132
41043
|
let tokens = [];
|
|
@@ -42473,7 +41384,7 @@ const getBalances = async (config, web3Provider, walletAddress, tokens) => {
|
|
|
42473
41384
|
});
|
|
42474
41385
|
return { balances };
|
|
42475
41386
|
};
|
|
42476
|
-
const getAllBalances = async (config, web3Provider, walletAddress, chainId) => {
|
|
41387
|
+
const getAllBalances = async (config, web3Provider, walletAddress, chainId, forceFetch = false) => {
|
|
42477
41388
|
if (!walletAddress && !web3Provider) {
|
|
42478
41389
|
throw new CheckoutError('both walletAddress and provider are missing. At least one must be provided.', CheckoutErrorType.MISSING_PARAMS);
|
|
42479
41390
|
}
|
|
@@ -42495,6 +41406,9 @@ const getAllBalances = async (config, web3Provider, walletAddress, chainId) => {
|
|
|
42495
41406
|
// eslint-disable-next-line no-console
|
|
42496
41407
|
console.error(err);
|
|
42497
41408
|
}
|
|
41409
|
+
if (forceFetch) {
|
|
41410
|
+
resetBlockscoutClientMap();
|
|
41411
|
+
}
|
|
42498
41412
|
let address = walletAddress;
|
|
42499
41413
|
if (flag && Blockscout.isChainSupported(chainId)) {
|
|
42500
41414
|
// This is a hack because the widgets are still using the tokens symbol
|
|
@@ -42660,16 +41574,19 @@ async function getWalletAllowList(params) {
|
|
|
42660
41574
|
};
|
|
42661
41575
|
}
|
|
42662
41576
|
|
|
42663
|
-
const setTransactionGasLimits = (transaction) => {
|
|
41577
|
+
const setTransactionGasLimits = async (web3Provider, transaction) => {
|
|
42664
41578
|
const rawTx = transaction;
|
|
42665
|
-
|
|
42666
|
-
|
|
41579
|
+
const { chainId } = await web3Provider.getNetwork();
|
|
41580
|
+
if (!isZkEvmChainId(chainId))
|
|
41581
|
+
return rawTx;
|
|
41582
|
+
rawTx.maxFeePerGas = IMMUTABLE_ZKVEM_GAS_OVERRIDES.maxFeePerGas;
|
|
41583
|
+
rawTx.maxPriorityFeePerGas = IMMUTABLE_ZKVEM_GAS_OVERRIDES.maxPriorityFeePerGas;
|
|
42667
41584
|
return rawTx;
|
|
42668
41585
|
};
|
|
42669
41586
|
const sendTransaction = async (web3Provider, transaction) => {
|
|
42670
41587
|
try {
|
|
42671
41588
|
const signer = web3Provider.getSigner();
|
|
42672
|
-
const rawTx = setTransactionGasLimits(transaction);
|
|
41589
|
+
const rawTx = await setTransactionGasLimits(web3Provider, transaction);
|
|
42673
41590
|
const transactionResponse = await signer.sendTransaction(rawTx);
|
|
42674
41591
|
return {
|
|
42675
41592
|
transactionResponse,
|
|
@@ -43371,7 +42288,7 @@ const getTokenBalanceRequirement = (itemRequirement, balances) => {
|
|
|
43371
42288
|
/**
|
|
43372
42289
|
* Gets the balances for all NATIVE and ERC20 balance requirements.
|
|
43373
42290
|
*/
|
|
43374
|
-
const getTokenBalances = async (config, provider, ownerAddress, itemRequirements) => {
|
|
42291
|
+
const getTokenBalances = async (config, provider, ownerAddress, itemRequirements, forceFetch = false) => {
|
|
43375
42292
|
try {
|
|
43376
42293
|
const tokenMap = new Map();
|
|
43377
42294
|
getTokensFromRequirements(itemRequirements).forEach((item) => {
|
|
@@ -43379,7 +42296,7 @@ const getTokenBalances = async (config, provider, ownerAddress, itemRequirements
|
|
|
43379
42296
|
return;
|
|
43380
42297
|
tokenMap.set(item.address.toLocaleLowerCase(), item);
|
|
43381
42298
|
});
|
|
43382
|
-
const { balances } = await getAllBalances(config, provider, ownerAddress, getL2ChainId(config));
|
|
42299
|
+
const { balances } = await getAllBalances(config, provider, ownerAddress, getL2ChainId(config), forceFetch);
|
|
43383
42300
|
return balances.filter((balance) => tokenMap.get((balance.token.address || NATIVE).toLocaleLowerCase()));
|
|
43384
42301
|
}
|
|
43385
42302
|
catch (err) {
|
|
@@ -43429,7 +42346,7 @@ const getERC721Balances = async (provider, ownerAddress, itemRequirements) => {
|
|
|
43429
42346
|
/**
|
|
43430
42347
|
* Checks the item requirements against the owner balances.
|
|
43431
42348
|
*/
|
|
43432
|
-
const balanceCheck = async (config, provider, ownerAddress, itemRequirements) => {
|
|
42349
|
+
const balanceCheck = async (config, provider, ownerAddress, itemRequirements, forceFetch = false) => {
|
|
43433
42350
|
const aggregatedItems = balanceAggregator(itemRequirements);
|
|
43434
42351
|
const requiredToken = [];
|
|
43435
42352
|
const requiredERC721 = [];
|
|
@@ -43450,7 +42367,7 @@ const balanceCheck = async (config, provider, ownerAddress, itemRequirements) =>
|
|
|
43450
42367
|
// Get all ERC20 and NATIVE balances
|
|
43451
42368
|
const balancePromises = [];
|
|
43452
42369
|
if (requiredToken.length > 0) {
|
|
43453
|
-
balancePromises.push(getTokenBalances(config, provider, ownerAddress, aggregatedItems));
|
|
42370
|
+
balancePromises.push(getTokenBalances(config, provider, ownerAddress, aggregatedItems, forceFetch));
|
|
43454
42371
|
}
|
|
43455
42372
|
// Get all ERC721 balances
|
|
43456
42373
|
if (requiredERC721.length > 0) {
|
|
@@ -44813,7 +43730,7 @@ const smartCheckout = async (config, provider, itemRequirements, transactionOrGa
|
|
|
44813
43730
|
aggregatedItems.push(gasItem);
|
|
44814
43731
|
aggregatedItems = itemAggregator(aggregatedItems);
|
|
44815
43732
|
}
|
|
44816
|
-
const balanceCheckResult = await measureAsyncExecution(config, 'Time to run balance checks', balanceCheck(config, provider, ownerAddress, aggregatedItems));
|
|
43733
|
+
const balanceCheckResult = await measureAsyncExecution(config, 'Time to run balance checks', balanceCheck(config, provider, ownerAddress, aggregatedItems, true));
|
|
44817
43734
|
const { sufficient } = balanceCheckResult;
|
|
44818
43735
|
const transactionRequirements = balanceCheckResult.balanceRequirements;
|
|
44819
43736
|
if (sufficient) {
|
|
@@ -44869,1093 +43786,2181 @@ const signFulfillmentTransactions = async (provider, fulfillmentTransactions) =>
|
|
|
44869
43786
|
receipts = await Promise.all(response.map((transaction) => transaction.transactionResponse.wait()));
|
|
44870
43787
|
}
|
|
44871
43788
|
catch (err) {
|
|
44872
|
-
throw new CheckoutError('An error occurred while executing the fulfillment transaction', CheckoutErrorType.EXECUTE_FULFILLMENT_TRANSACTION_ERROR, { error: err });
|
|
43789
|
+
throw new CheckoutError('An error occurred while executing the fulfillment transaction', CheckoutErrorType.EXECUTE_FULFILLMENT_TRANSACTION_ERROR, { error: err });
|
|
43790
|
+
}
|
|
43791
|
+
for (const receipt of receipts) {
|
|
43792
|
+
if (receipt.status === 0) {
|
|
43793
|
+
return {
|
|
43794
|
+
type: SignTransactionStatusType.FAILED,
|
|
43795
|
+
transactionHash: receipt.transactionHash,
|
|
43796
|
+
reason: 'Fulfillment transaction failed and was reverted',
|
|
43797
|
+
};
|
|
43798
|
+
}
|
|
43799
|
+
}
|
|
43800
|
+
return {
|
|
43801
|
+
type: SignTransactionStatusType.SUCCESS,
|
|
43802
|
+
};
|
|
43803
|
+
};
|
|
43804
|
+
const signMessage = async (provider, unsignedMessage) => {
|
|
43805
|
+
try {
|
|
43806
|
+
// eslint-disable-next-line no-underscore-dangle
|
|
43807
|
+
const signedMessage = await provider.getSigner()._signTypedData(unsignedMessage.unsignedMessage.domain, unsignedMessage.unsignedMessage.types, unsignedMessage.unsignedMessage.value);
|
|
43808
|
+
return {
|
|
43809
|
+
orderComponents: unsignedMessage.orderComponents,
|
|
43810
|
+
orderHash: unsignedMessage.orderHash,
|
|
43811
|
+
signedMessage,
|
|
43812
|
+
};
|
|
43813
|
+
}
|
|
43814
|
+
catch (err) {
|
|
43815
|
+
throw new CheckoutError('An error occurred while signing the message', CheckoutErrorType.SIGN_MESSAGE_ERROR, { error: err });
|
|
43816
|
+
}
|
|
43817
|
+
};
|
|
43818
|
+
|
|
43819
|
+
const getUnsignedERC721Transactions = async (actions) => {
|
|
43820
|
+
let approvalTransactions = [];
|
|
43821
|
+
let fulfillmentTransactions = [];
|
|
43822
|
+
const approvalPromises = [];
|
|
43823
|
+
const fulfillmentPromises = [];
|
|
43824
|
+
for (const action of actions) {
|
|
43825
|
+
if (action.type !== ActionType.TRANSACTION)
|
|
43826
|
+
continue;
|
|
43827
|
+
if (action.purpose === TransactionPurpose.APPROVAL) {
|
|
43828
|
+
approvalPromises.push(action.buildTransaction());
|
|
43829
|
+
}
|
|
43830
|
+
if (action.purpose === TransactionPurpose.FULFILL_ORDER) {
|
|
43831
|
+
fulfillmentPromises.push(action.buildTransaction());
|
|
43832
|
+
}
|
|
43833
|
+
}
|
|
43834
|
+
approvalTransactions = await Promise.all(approvalPromises);
|
|
43835
|
+
fulfillmentTransactions = await Promise.all(fulfillmentPromises);
|
|
43836
|
+
return {
|
|
43837
|
+
approvalTransactions,
|
|
43838
|
+
fulfillmentTransactions,
|
|
43839
|
+
};
|
|
43840
|
+
};
|
|
43841
|
+
const getUnsignedERC20ApprovalTransactions = async (actions) => {
|
|
43842
|
+
let approvalTransactions = [];
|
|
43843
|
+
const approvalPromises = [];
|
|
43844
|
+
for (const action of actions) {
|
|
43845
|
+
if (action.type !== ActionType.TRANSACTION)
|
|
43846
|
+
continue;
|
|
43847
|
+
if (action.purpose === TransactionPurpose.APPROVAL) {
|
|
43848
|
+
approvalPromises.push(action.buildTransaction());
|
|
43849
|
+
}
|
|
43850
|
+
}
|
|
43851
|
+
approvalTransactions = await Promise.all(approvalPromises);
|
|
43852
|
+
return approvalTransactions;
|
|
43853
|
+
};
|
|
43854
|
+
const getUnsignedFulfillmentTransactions = async (actions) => {
|
|
43855
|
+
let fulfillmentTransactions = [];
|
|
43856
|
+
const fulfillmentPromises = [];
|
|
43857
|
+
for (const action of actions) {
|
|
43858
|
+
if (action.type !== ActionType.TRANSACTION)
|
|
43859
|
+
continue;
|
|
43860
|
+
if (action.purpose === TransactionPurpose.FULFILL_ORDER) {
|
|
43861
|
+
fulfillmentPromises.push(action.buildTransaction());
|
|
43862
|
+
}
|
|
43863
|
+
}
|
|
43864
|
+
fulfillmentTransactions = await Promise.all(fulfillmentPromises);
|
|
43865
|
+
return fulfillmentTransactions;
|
|
43866
|
+
};
|
|
43867
|
+
const getUnsignedMessage = (orderHash, orderComponents, actions) => {
|
|
43868
|
+
let unsignedMessage;
|
|
43869
|
+
for (const action of actions) {
|
|
43870
|
+
if (action.type !== ActionType.SIGNABLE)
|
|
43871
|
+
continue;
|
|
43872
|
+
if (action.purpose === SignablePurpose.CREATE_LISTING) {
|
|
43873
|
+
unsignedMessage = {
|
|
43874
|
+
domain: action.message.domain,
|
|
43875
|
+
types: action.message.types,
|
|
43876
|
+
value: action.message.value,
|
|
43877
|
+
};
|
|
43878
|
+
}
|
|
43879
|
+
}
|
|
43880
|
+
if (!unsignedMessage)
|
|
43881
|
+
return undefined;
|
|
43882
|
+
return {
|
|
43883
|
+
orderHash,
|
|
43884
|
+
orderComponents,
|
|
43885
|
+
unsignedMessage,
|
|
43886
|
+
};
|
|
43887
|
+
};
|
|
43888
|
+
|
|
43889
|
+
const MAX_FEE_PERCENTAGE_DECIMAL = 1; // 100%
|
|
43890
|
+
const MAX_FEE_DECIMAL_PLACES = 6; // will allow 0.000001 (0.0001%) as the minimum value
|
|
43891
|
+
const calculateFeesPercent = (orderFee, amountBn) => {
|
|
43892
|
+
const feePercentage = orderFee.amount;
|
|
43893
|
+
// note: multiply in and out of the maximum decimal places to the power of ten to do the math in big number integers
|
|
43894
|
+
const feePercentageMultiplier = Math.round(feePercentage.percentageDecimal * (10 ** MAX_FEE_DECIMAL_PLACES));
|
|
43895
|
+
const bnFeeAmount = amountBn
|
|
43896
|
+
.mul(BigNumber$1.from(feePercentageMultiplier))
|
|
43897
|
+
.div(10 ** MAX_FEE_DECIMAL_PLACES);
|
|
43898
|
+
return bnFeeAmount;
|
|
43899
|
+
};
|
|
43900
|
+
const calculateFeesToken = (orderFee, decimals) => {
|
|
43901
|
+
const feeToken = orderFee.amount;
|
|
43902
|
+
const bnFeeAmount = utils$3.parseUnits(feeToken.token, decimals);
|
|
43903
|
+
return bnFeeAmount;
|
|
43904
|
+
};
|
|
43905
|
+
const calculateFees = (orderFees, weiAmount, decimals = 18) => {
|
|
43906
|
+
let totalTokenFees = BigNumber$1.from(0);
|
|
43907
|
+
const amountBn = BigNumber$1.from(weiAmount);
|
|
43908
|
+
// note: multiply in and out of the maximum decimal places to the power of ten to do the math in big number integers
|
|
43909
|
+
const totalAllowableFees = amountBn
|
|
43910
|
+
.mul(MAX_FEE_PERCENTAGE_DECIMAL * (10 ** MAX_FEE_DECIMAL_PLACES))
|
|
43911
|
+
.div(10 ** MAX_FEE_DECIMAL_PLACES);
|
|
43912
|
+
const calculateFeesResult = [];
|
|
43913
|
+
for (const orderFee of orderFees) {
|
|
43914
|
+
let currentFeeBn = BigNumber$1.from(0);
|
|
43915
|
+
if (Object.hasOwn(orderFee.amount, 'percentageDecimal')) {
|
|
43916
|
+
currentFeeBn = calculateFeesPercent(orderFee, amountBn);
|
|
43917
|
+
totalTokenFees = totalTokenFees.add(currentFeeBn);
|
|
43918
|
+
}
|
|
43919
|
+
else if (Object.hasOwn(orderFee.amount, 'token')) {
|
|
43920
|
+
currentFeeBn = calculateFeesToken(orderFee, decimals);
|
|
43921
|
+
totalTokenFees = totalTokenFees.add(currentFeeBn);
|
|
43922
|
+
}
|
|
43923
|
+
else {
|
|
43924
|
+
throw new CheckoutError('Unknown fee type parsed, must be percentageDecimal or token', CheckoutErrorType.ORDER_FEE_ERROR);
|
|
43925
|
+
}
|
|
43926
|
+
if (totalTokenFees.gt(totalAllowableFees)) {
|
|
43927
|
+
throw new CheckoutError(`The combined fees are above the allowed maximum of ${MAX_FEE_PERCENTAGE_DECIMAL * 100}%`, CheckoutErrorType.ORDER_FEE_ERROR);
|
|
43928
|
+
}
|
|
43929
|
+
if (currentFeeBn.gt(0)) {
|
|
43930
|
+
calculateFeesResult.push({
|
|
43931
|
+
amount: currentFeeBn.toString(),
|
|
43932
|
+
recipientAddress: orderFee.recipient,
|
|
43933
|
+
});
|
|
43934
|
+
}
|
|
43935
|
+
} // for
|
|
43936
|
+
return calculateFeesResult;
|
|
43937
|
+
};
|
|
43938
|
+
|
|
43939
|
+
const getItemRequirement = (type, tokenAddress, amount, spenderAddress) => {
|
|
43940
|
+
switch (type) {
|
|
43941
|
+
case ItemType.ERC20:
|
|
43942
|
+
return {
|
|
43943
|
+
type,
|
|
43944
|
+
amount,
|
|
43945
|
+
tokenAddress,
|
|
43946
|
+
spenderAddress,
|
|
43947
|
+
};
|
|
43948
|
+
case ItemType.NATIVE:
|
|
43949
|
+
default:
|
|
43950
|
+
return {
|
|
43951
|
+
type: ItemType.NATIVE,
|
|
43952
|
+
amount,
|
|
43953
|
+
};
|
|
43954
|
+
}
|
|
43955
|
+
};
|
|
43956
|
+
const getTransactionOrGas = (gasLimit, fulfillmentTransactions) => {
|
|
43957
|
+
if (fulfillmentTransactions.length > 0) {
|
|
43958
|
+
return {
|
|
43959
|
+
type: TransactionOrGasType.TRANSACTION,
|
|
43960
|
+
transaction: fulfillmentTransactions[0],
|
|
43961
|
+
};
|
|
43962
|
+
}
|
|
43963
|
+
return {
|
|
43964
|
+
type: TransactionOrGasType.GAS,
|
|
43965
|
+
gasToken: {
|
|
43966
|
+
type: GasTokenType.NATIVE,
|
|
43967
|
+
limit: BigNumber$1.from(gasLimit),
|
|
43968
|
+
},
|
|
43969
|
+
};
|
|
43970
|
+
};
|
|
43971
|
+
const buy = async (config, provider, orders, overrides = {
|
|
43972
|
+
waitFulfillmentSettlements: true,
|
|
43973
|
+
}) => {
|
|
43974
|
+
if (orders.length === 0) {
|
|
43975
|
+
throw new CheckoutError('No orders were provided to the orders array. Please provide at least one order.', CheckoutErrorType.FULFILL_ORDER_LISTING_ERROR);
|
|
43976
|
+
}
|
|
43977
|
+
let order;
|
|
43978
|
+
let spenderAddress = '';
|
|
43979
|
+
let decimals = 18;
|
|
43980
|
+
const gasLimit = constants.estimatedFulfillmentGasGwei;
|
|
43981
|
+
const orderbook = createOrderbookInstance(config);
|
|
43982
|
+
const blockchainClient = createBlockchainDataInstance(config);
|
|
43983
|
+
const fulfillerAddress = await measureAsyncExecution(config, 'Time to get the address from the provider', provider.getSigner().getAddress());
|
|
43984
|
+
// Prefetch balances and store them in memory
|
|
43985
|
+
resetBlockscoutClientMap();
|
|
43986
|
+
getAllBalances(config, provider, fulfillerAddress, getL1ChainId(config));
|
|
43987
|
+
getAllBalances(config, provider, fulfillerAddress, getL2ChainId(config));
|
|
43988
|
+
const { id, takerFees } = orders[0];
|
|
43989
|
+
let orderChainName;
|
|
43990
|
+
try {
|
|
43991
|
+
order = await measureAsyncExecution(config, 'Time to fetch the listing from the orderbook', orderbook.getListing(id));
|
|
43992
|
+
const { seaportContractAddress, chainName } = orderbook.config();
|
|
43993
|
+
orderChainName = chainName;
|
|
43994
|
+
spenderAddress = seaportContractAddress;
|
|
43995
|
+
}
|
|
43996
|
+
catch (err) {
|
|
43997
|
+
throw new CheckoutError('An error occurred while getting the order listing', CheckoutErrorType.GET_ORDER_LISTING_ERROR, {
|
|
43998
|
+
error: err,
|
|
43999
|
+
orderId: id,
|
|
44000
|
+
});
|
|
44001
|
+
}
|
|
44002
|
+
if (order.result.buy.length === 0) {
|
|
44003
|
+
throw new CheckoutError('An error occurred with the get order listing', CheckoutErrorType.GET_ORDER_LISTING_ERROR, {
|
|
44004
|
+
orderId: id,
|
|
44005
|
+
message: 'No buy side tokens found on order',
|
|
44006
|
+
});
|
|
44007
|
+
}
|
|
44008
|
+
const buyToken = order.result.buy[0];
|
|
44009
|
+
if (buyToken.type === 'ERC20') {
|
|
44010
|
+
const token = await measureAsyncExecution(config, 'Time to get decimals of token contract for the buy token', blockchainClient.getToken({ contractAddress: buyToken.contractAddress, chainName: orderChainName }));
|
|
44011
|
+
if (token.result.decimals)
|
|
44012
|
+
decimals = token.result.decimals;
|
|
44013
|
+
}
|
|
44014
|
+
let fees = [];
|
|
44015
|
+
if (takerFees && takerFees.length > 0) {
|
|
44016
|
+
fees = calculateFees(takerFees, buyToken.amount, decimals);
|
|
44017
|
+
}
|
|
44018
|
+
let unsignedApprovalTransactions = [];
|
|
44019
|
+
let unsignedFulfillmentTransactions = [];
|
|
44020
|
+
let orderActions = [];
|
|
44021
|
+
const fulfillOrderStartTime = performance.now();
|
|
44022
|
+
try {
|
|
44023
|
+
const { actions } = await measureAsyncExecution(config, 'Time to call fulfillOrder from the orderbook', orderbook.fulfillOrder(id, fulfillerAddress, fees));
|
|
44024
|
+
orderActions = actions;
|
|
44025
|
+
unsignedApprovalTransactions = await measureAsyncExecution(config, 'Time to construct the unsigned approval transactions', getUnsignedERC20ApprovalTransactions(actions));
|
|
44026
|
+
}
|
|
44027
|
+
catch (err) {
|
|
44028
|
+
const elapsedTimeInSeconds = (performance.now() - fulfillOrderStartTime) / 1000;
|
|
44029
|
+
debugLogger(config, 'Time to call fulfillOrder from the orderbook', elapsedTimeInSeconds);
|
|
44030
|
+
if (err.message.includes(OrderStatusName.EXPIRED)) {
|
|
44031
|
+
throw new CheckoutError('Order is expired', CheckoutErrorType.ORDER_EXPIRED_ERROR, { orderId: id });
|
|
44032
|
+
}
|
|
44033
|
+
// The balances error will be handled by bulk order fulfillment but for now we
|
|
44034
|
+
// need to assert on this string to check that the error is not a balances error
|
|
44035
|
+
if (!err.message.includes('The fulfiller does not have the balances needed to fulfill')) {
|
|
44036
|
+
throw new CheckoutError('Error occurred while trying to fulfill the order', CheckoutErrorType.FULFILL_ORDER_LISTING_ERROR, {
|
|
44037
|
+
orderId: id,
|
|
44038
|
+
error: err,
|
|
44039
|
+
});
|
|
44040
|
+
}
|
|
44041
|
+
}
|
|
44042
|
+
try {
|
|
44043
|
+
unsignedFulfillmentTransactions = await measureAsyncExecution(config, 'Time to construct the unsigned fulfillment transactions', getUnsignedFulfillmentTransactions(orderActions));
|
|
44044
|
+
}
|
|
44045
|
+
catch {
|
|
44046
|
+
// if cannot estimate gas then silently continue and use gas limit in smartCheckout
|
|
44047
|
+
// but get the fulfillment transactions after they have approved the spending
|
|
44048
|
+
}
|
|
44049
|
+
let amount = BigNumber$1.from('0');
|
|
44050
|
+
let type = ItemType.NATIVE;
|
|
44051
|
+
let contractAddress = '';
|
|
44052
|
+
const buyArray = order.result.buy;
|
|
44053
|
+
if (buyArray.length > 0) {
|
|
44054
|
+
switch (buyArray[0].type) {
|
|
44055
|
+
case 'NATIVE':
|
|
44056
|
+
type = ItemType.NATIVE;
|
|
44057
|
+
break;
|
|
44058
|
+
case 'ERC20':
|
|
44059
|
+
type = ItemType.ERC20;
|
|
44060
|
+
contractAddress = buyArray[0].contractAddress;
|
|
44061
|
+
break;
|
|
44062
|
+
default:
|
|
44063
|
+
throw new CheckoutError('Purchasing token type is unsupported', CheckoutErrorType.UNSUPPORTED_TOKEN_TYPE_ERROR, {
|
|
44064
|
+
orderId: id,
|
|
44065
|
+
});
|
|
44066
|
+
}
|
|
44067
|
+
}
|
|
44068
|
+
buyArray.forEach((item) => {
|
|
44069
|
+
if (item.type !== ItemType.ERC721) {
|
|
44070
|
+
amount = amount.add(BigNumber$1.from(item.amount));
|
|
44071
|
+
}
|
|
44072
|
+
});
|
|
44073
|
+
const feeArray = order.result.fees;
|
|
44074
|
+
feeArray.forEach((item) => {
|
|
44075
|
+
amount = amount.add(BigNumber$1.from(item.amount));
|
|
44076
|
+
});
|
|
44077
|
+
const itemRequirements = [
|
|
44078
|
+
getItemRequirement(type, contractAddress, amount, spenderAddress),
|
|
44079
|
+
];
|
|
44080
|
+
const smartCheckoutResult = await measureAsyncExecution(config, 'Total time running smart checkout', smartCheckout(config, provider, itemRequirements, getTransactionOrGas(gasLimit, unsignedFulfillmentTransactions)));
|
|
44081
|
+
if (smartCheckoutResult.sufficient) {
|
|
44082
|
+
const approvalResult = await signApprovalTransactions(provider, unsignedApprovalTransactions);
|
|
44083
|
+
if (approvalResult.type === SignTransactionStatusType.FAILED) {
|
|
44084
|
+
return {
|
|
44085
|
+
status: CheckoutStatus.FAILED,
|
|
44086
|
+
transactionHash: approvalResult.transactionHash,
|
|
44087
|
+
reason: approvalResult.reason,
|
|
44088
|
+
smartCheckoutResult,
|
|
44089
|
+
};
|
|
44090
|
+
}
|
|
44091
|
+
try {
|
|
44092
|
+
if (unsignedFulfillmentTransactions.length === 0) {
|
|
44093
|
+
unsignedFulfillmentTransactions = await getUnsignedFulfillmentTransactions(orderActions);
|
|
44094
|
+
}
|
|
44095
|
+
}
|
|
44096
|
+
catch (err) {
|
|
44097
|
+
throw new CheckoutError('Error fetching fulfillment transaction', CheckoutErrorType.FULFILL_ORDER_LISTING_ERROR, { error: err });
|
|
44098
|
+
}
|
|
44099
|
+
if (overrides.waitFulfillmentSettlements) {
|
|
44100
|
+
const fulfillmentResult = await signFulfillmentTransactions(provider, unsignedFulfillmentTransactions);
|
|
44101
|
+
if (fulfillmentResult.type === SignTransactionStatusType.FAILED) {
|
|
44102
|
+
return {
|
|
44103
|
+
status: CheckoutStatus.FAILED,
|
|
44104
|
+
transactionHash: fulfillmentResult.transactionHash,
|
|
44105
|
+
reason: fulfillmentResult.reason,
|
|
44106
|
+
smartCheckoutResult,
|
|
44107
|
+
};
|
|
44108
|
+
}
|
|
44109
|
+
return {
|
|
44110
|
+
status: CheckoutStatus.SUCCESS,
|
|
44111
|
+
smartCheckoutResult,
|
|
44112
|
+
};
|
|
44113
|
+
}
|
|
44114
|
+
let transactions;
|
|
44115
|
+
try {
|
|
44116
|
+
const response = await Promise.all(unsignedFulfillmentTransactions.map((transaction) => sendTransaction(provider, transaction)));
|
|
44117
|
+
transactions = response.map((result) => result.transactionResponse);
|
|
44118
|
+
}
|
|
44119
|
+
catch (err) {
|
|
44120
|
+
throw new CheckoutError('An error occurred while executing the fulfillment transaction', CheckoutErrorType.EXECUTE_FULFILLMENT_TRANSACTION_ERROR, {
|
|
44121
|
+
message: err.message,
|
|
44122
|
+
});
|
|
44123
|
+
}
|
|
44124
|
+
return {
|
|
44125
|
+
status: CheckoutStatus.FULFILLMENTS_UNSETTLED,
|
|
44126
|
+
smartCheckoutResult,
|
|
44127
|
+
transactions,
|
|
44128
|
+
};
|
|
44129
|
+
}
|
|
44130
|
+
return {
|
|
44131
|
+
status: CheckoutStatus.INSUFFICIENT_FUNDS,
|
|
44132
|
+
smartCheckoutResult,
|
|
44133
|
+
};
|
|
44134
|
+
};
|
|
44135
|
+
|
|
44136
|
+
const cancel = async (config, provider, orderIds, overrides = {
|
|
44137
|
+
waitFulfillmentSettlements: true,
|
|
44138
|
+
}) => {
|
|
44139
|
+
let unsignedCancelOrderTransaction;
|
|
44140
|
+
if (orderIds.length === 0) {
|
|
44141
|
+
throw new CheckoutError('No orderIds were provided to the orderIds array. Please provide at least one orderId.', CheckoutErrorType.CANCEL_ORDER_LISTING_ERROR);
|
|
44142
|
+
}
|
|
44143
|
+
// Update this when bulk cancel is supported
|
|
44144
|
+
const orderId = orderIds[0];
|
|
44145
|
+
try {
|
|
44146
|
+
const offererAddress = await measureAsyncExecution(config, 'Time to get the address from the provider', provider.getSigner().getAddress());
|
|
44147
|
+
const orderbook = createOrderbookInstance(config);
|
|
44148
|
+
const cancelOrderResponse = await measureAsyncExecution(config, 'Time to get the cancel order from the orderbook', orderbook.cancelOrdersOnChain([orderId], offererAddress));
|
|
44149
|
+
unsignedCancelOrderTransaction = await cancelOrderResponse.cancellationAction.buildTransaction();
|
|
44150
|
+
}
|
|
44151
|
+
catch (err) {
|
|
44152
|
+
throw new CheckoutError('An error occurred while cancelling the order listing', CheckoutErrorType.CANCEL_ORDER_LISTING_ERROR, {
|
|
44153
|
+
orderId,
|
|
44154
|
+
error: err,
|
|
44155
|
+
});
|
|
44156
|
+
}
|
|
44157
|
+
if (overrides.waitFulfillmentSettlements) {
|
|
44158
|
+
const result = await signFulfillmentTransactions(provider, [unsignedCancelOrderTransaction]);
|
|
44159
|
+
if (result.type === SignTransactionStatusType.FAILED) {
|
|
44160
|
+
return {
|
|
44161
|
+
status: CheckoutStatus.FAILED,
|
|
44162
|
+
transactionHash: result.transactionHash,
|
|
44163
|
+
reason: result.reason,
|
|
44164
|
+
};
|
|
44165
|
+
}
|
|
44166
|
+
return {
|
|
44167
|
+
status: CheckoutStatus.SUCCESS,
|
|
44168
|
+
};
|
|
44169
|
+
}
|
|
44170
|
+
let transactions;
|
|
44171
|
+
try {
|
|
44172
|
+
const response = await Promise.all([unsignedCancelOrderTransaction].map((transaction) => sendTransaction(provider, transaction)));
|
|
44173
|
+
transactions = response.map((result) => result.transactionResponse);
|
|
44174
|
+
}
|
|
44175
|
+
catch (err) {
|
|
44176
|
+
throw new CheckoutError('An error occurred while executing the fulfillment transaction', CheckoutErrorType.EXECUTE_FULFILLMENT_TRANSACTION_ERROR, {
|
|
44177
|
+
message: err.message,
|
|
44178
|
+
});
|
|
44179
|
+
}
|
|
44180
|
+
return {
|
|
44181
|
+
status: CheckoutStatus.FULFILLMENTS_UNSETTLED,
|
|
44182
|
+
transactions,
|
|
44183
|
+
};
|
|
44184
|
+
};
|
|
44185
|
+
|
|
44186
|
+
const getERC721Requirement = (id, contractAddress, spenderAddress) => ({
|
|
44187
|
+
type: ItemType.ERC721,
|
|
44188
|
+
id,
|
|
44189
|
+
contractAddress,
|
|
44190
|
+
spenderAddress,
|
|
44191
|
+
});
|
|
44192
|
+
const getBuyToken = (buyToken, decimals = 18) => {
|
|
44193
|
+
const bnAmount = utils$3.parseUnits(buyToken.amount, decimals);
|
|
44194
|
+
if (buyToken.type === ItemType.NATIVE) {
|
|
44195
|
+
return {
|
|
44196
|
+
type: ItemType.NATIVE,
|
|
44197
|
+
amount: bnAmount.toString(),
|
|
44198
|
+
};
|
|
44199
|
+
}
|
|
44200
|
+
return {
|
|
44201
|
+
type: ItemType.ERC20,
|
|
44202
|
+
amount: bnAmount.toString(),
|
|
44203
|
+
contractAddress: buyToken.tokenAddress,
|
|
44204
|
+
};
|
|
44205
|
+
};
|
|
44206
|
+
const sell = async (config, provider, orders) => {
|
|
44207
|
+
let orderbook;
|
|
44208
|
+
let listing;
|
|
44209
|
+
let spenderAddress = '';
|
|
44210
|
+
if (orders.length === 0) {
|
|
44211
|
+
throw new CheckoutError('No orders were provided to the orders array. Please provide at least one order.', CheckoutErrorType.PREPARE_ORDER_LISTING_ERROR);
|
|
44212
|
+
}
|
|
44213
|
+
const { buyToken, sellToken, makerFees, orderExpiry, } = orders[0];
|
|
44214
|
+
let decimals = 18;
|
|
44215
|
+
if (buyToken.type === ItemType.ERC20) {
|
|
44216
|
+
// get this from the allowed list
|
|
44217
|
+
const buyTokenContract = new Contract$1(buyToken.tokenAddress, JSON.stringify(ERC20ABI), provider);
|
|
44218
|
+
decimals = await measureAsyncExecution(config, 'Time to get decimals of token contract for the buy token', buyTokenContract.decimals());
|
|
44219
|
+
}
|
|
44220
|
+
const buyTokenOrNative = getBuyToken(buyToken, decimals);
|
|
44221
|
+
try {
|
|
44222
|
+
const walletAddress = await measureAsyncExecution(config, 'Time to get the address from the provider', provider.getSigner().getAddress());
|
|
44223
|
+
orderbook = createOrderbookInstance(config);
|
|
44224
|
+
const { seaportContractAddress } = orderbook.config();
|
|
44225
|
+
spenderAddress = seaportContractAddress;
|
|
44226
|
+
listing = await measureAsyncExecution(config, 'Time to prepare the listing from the orderbook', orderbook.prepareListing({
|
|
44227
|
+
makerAddress: walletAddress,
|
|
44228
|
+
buy: buyTokenOrNative,
|
|
44229
|
+
sell: {
|
|
44230
|
+
type: ItemType.ERC721,
|
|
44231
|
+
contractAddress: sellToken.collectionAddress,
|
|
44232
|
+
tokenId: sellToken.id,
|
|
44233
|
+
},
|
|
44234
|
+
orderExpiry,
|
|
44235
|
+
}));
|
|
44236
|
+
}
|
|
44237
|
+
catch (err) {
|
|
44238
|
+
throw new CheckoutError('An error occurred while preparing the listing', CheckoutErrorType.PREPARE_ORDER_LISTING_ERROR, {
|
|
44239
|
+
error: err,
|
|
44240
|
+
id: sellToken.id,
|
|
44241
|
+
collectionAddress: sellToken.collectionAddress,
|
|
44242
|
+
});
|
|
44873
44243
|
}
|
|
44874
|
-
|
|
44875
|
-
|
|
44244
|
+
const itemRequirements = [
|
|
44245
|
+
getERC721Requirement(sellToken.id, sellToken.collectionAddress, spenderAddress),
|
|
44246
|
+
];
|
|
44247
|
+
const smartCheckoutResult = await measureAsyncExecution(config, 'Total time running smart checkout', smartCheckout(config, provider, itemRequirements, {
|
|
44248
|
+
type: TransactionOrGasType.GAS,
|
|
44249
|
+
gasToken: {
|
|
44250
|
+
type: GasTokenType.NATIVE,
|
|
44251
|
+
limit: BigNumber$1.from(constants.estimatedFulfillmentGasGwei),
|
|
44252
|
+
},
|
|
44253
|
+
}));
|
|
44254
|
+
if (smartCheckoutResult.sufficient) {
|
|
44255
|
+
const unsignedTransactions = await getUnsignedERC721Transactions(listing.actions);
|
|
44256
|
+
const approvalResult = await signApprovalTransactions(provider, unsignedTransactions.approvalTransactions);
|
|
44257
|
+
if (approvalResult.type === SignTransactionStatusType.FAILED) {
|
|
44876
44258
|
return {
|
|
44877
|
-
|
|
44878
|
-
transactionHash:
|
|
44879
|
-
reason:
|
|
44259
|
+
status: CheckoutStatus.FAILED,
|
|
44260
|
+
transactionHash: approvalResult.transactionHash,
|
|
44261
|
+
reason: approvalResult.reason,
|
|
44262
|
+
smartCheckoutResult,
|
|
44880
44263
|
};
|
|
44881
44264
|
}
|
|
44882
|
-
|
|
44883
|
-
|
|
44884
|
-
|
|
44885
|
-
|
|
44886
|
-
|
|
44887
|
-
|
|
44888
|
-
|
|
44889
|
-
|
|
44890
|
-
|
|
44891
|
-
|
|
44892
|
-
|
|
44893
|
-
|
|
44894
|
-
signedMessage,
|
|
44265
|
+
const unsignedMessage = getUnsignedMessage(listing.orderHash, listing.orderComponents, listing.actions);
|
|
44266
|
+
if (!unsignedMessage) {
|
|
44267
|
+
// For sell it is expected the orderbook will always return an unsigned message
|
|
44268
|
+
// If for some reason it is missing then we cannot proceed with the create listing
|
|
44269
|
+
throw new CheckoutError('The unsigned message is missing after preparing the listing', CheckoutErrorType.SIGN_MESSAGE_ERROR, {
|
|
44270
|
+
id: sellToken.id,
|
|
44271
|
+
collectionAddress: sellToken.collectionAddress,
|
|
44272
|
+
});
|
|
44273
|
+
}
|
|
44274
|
+
const signedMessage = await signMessage(provider, unsignedMessage);
|
|
44275
|
+
let orderId = '';
|
|
44276
|
+
const createListingParams = {
|
|
44277
|
+
orderComponents: signedMessage.orderComponents,
|
|
44278
|
+
orderHash: signedMessage.orderHash,
|
|
44279
|
+
orderSignature: signedMessage.signedMessage,
|
|
44280
|
+
makerFees: [],
|
|
44895
44281
|
};
|
|
44896
|
-
|
|
44897
|
-
|
|
44898
|
-
|
|
44899
|
-
|
|
44900
|
-
}
|
|
44901
|
-
|
|
44902
|
-
const getUnsignedERC721Transactions = async (actions) => {
|
|
44903
|
-
let approvalTransactions = [];
|
|
44904
|
-
let fulfillmentTransactions = [];
|
|
44905
|
-
const approvalPromises = [];
|
|
44906
|
-
const fulfillmentPromises = [];
|
|
44907
|
-
for (const action of actions) {
|
|
44908
|
-
if (action.type !== ActionType.TRANSACTION)
|
|
44909
|
-
continue;
|
|
44910
|
-
if (action.purpose === TransactionPurpose.APPROVAL) {
|
|
44911
|
-
approvalPromises.push(action.buildTransaction());
|
|
44282
|
+
if (makerFees !== undefined) {
|
|
44283
|
+
const orderBookFees = calculateFees(makerFees, buyTokenOrNative.amount, decimals);
|
|
44284
|
+
if (orderBookFees.length !== makerFees.length) {
|
|
44285
|
+
throw new CheckoutError('One of the fees is too small, must be greater than 0.000001', CheckoutErrorType.CREATE_ORDER_LISTING_ERROR);
|
|
44286
|
+
}
|
|
44287
|
+
createListingParams.makerFees = orderBookFees;
|
|
44912
44288
|
}
|
|
44913
|
-
|
|
44914
|
-
|
|
44289
|
+
try {
|
|
44290
|
+
const order = await orderbook.createListing(createListingParams);
|
|
44291
|
+
orderId = order.result.id;
|
|
44292
|
+
}
|
|
44293
|
+
catch (err) {
|
|
44294
|
+
throw new CheckoutError('An error occurred while creating the listing', CheckoutErrorType.CREATE_ORDER_LISTING_ERROR, {
|
|
44295
|
+
error: err,
|
|
44296
|
+
collectionId: sellToken.id,
|
|
44297
|
+
collectionAddress: sellToken.collectionAddress,
|
|
44298
|
+
});
|
|
44915
44299
|
}
|
|
44300
|
+
return {
|
|
44301
|
+
status: CheckoutStatus.SUCCESS,
|
|
44302
|
+
orderIds: [orderId],
|
|
44303
|
+
smartCheckoutResult,
|
|
44304
|
+
};
|
|
44916
44305
|
}
|
|
44917
|
-
approvalTransactions = await Promise.all(approvalPromises);
|
|
44918
|
-
fulfillmentTransactions = await Promise.all(fulfillmentPromises);
|
|
44919
44306
|
return {
|
|
44920
|
-
|
|
44921
|
-
|
|
44307
|
+
status: CheckoutStatus.INSUFFICIENT_FUNDS,
|
|
44308
|
+
smartCheckoutResult,
|
|
44922
44309
|
};
|
|
44923
44310
|
};
|
|
44924
|
-
|
|
44925
|
-
|
|
44926
|
-
|
|
44927
|
-
|
|
44928
|
-
|
|
44929
|
-
|
|
44930
|
-
|
|
44931
|
-
|
|
44932
|
-
|
|
44311
|
+
|
|
44312
|
+
class FiatRampService {
|
|
44313
|
+
config;
|
|
44314
|
+
/**
|
|
44315
|
+
* Constructs a new instance of the FiatRampService class.
|
|
44316
|
+
* @param {CheckoutConfiguration} config - The config required for the FiatRampService.
|
|
44317
|
+
*/
|
|
44318
|
+
constructor(config) {
|
|
44319
|
+
this.config = config;
|
|
44933
44320
|
}
|
|
44934
|
-
|
|
44935
|
-
|
|
44936
|
-
|
|
44937
|
-
const getUnsignedFulfillmentTransactions = async (actions) => {
|
|
44938
|
-
let fulfillmentTransactions = [];
|
|
44939
|
-
const fulfillmentPromises = [];
|
|
44940
|
-
for (const action of actions) {
|
|
44941
|
-
if (action.type !== ActionType.TRANSACTION)
|
|
44942
|
-
continue;
|
|
44943
|
-
if (action.purpose === TransactionPurpose.FULFILL_ORDER) {
|
|
44944
|
-
fulfillmentPromises.push(action.buildTransaction());
|
|
44945
|
-
}
|
|
44321
|
+
async feeEstimate() {
|
|
44322
|
+
const config = (await this.config.remote.getConfig('onramp'));
|
|
44323
|
+
return config[OnRampProvider.TRANSAK]?.fees;
|
|
44946
44324
|
}
|
|
44947
|
-
|
|
44948
|
-
|
|
44949
|
-
};
|
|
44950
|
-
const getUnsignedMessage = (orderHash, orderComponents, actions) => {
|
|
44951
|
-
let unsignedMessage;
|
|
44952
|
-
for (const action of actions) {
|
|
44953
|
-
if (action.type !== ActionType.SIGNABLE)
|
|
44954
|
-
continue;
|
|
44955
|
-
if (action.purpose === SignablePurpose.CREATE_LISTING) {
|
|
44956
|
-
unsignedMessage = {
|
|
44957
|
-
domain: action.message.domain,
|
|
44958
|
-
types: action.message.types,
|
|
44959
|
-
value: action.message.value,
|
|
44960
|
-
};
|
|
44961
|
-
}
|
|
44325
|
+
async createWidgetUrl(params) {
|
|
44326
|
+
return (await this.getTransakWidgetUrl(params));
|
|
44962
44327
|
}
|
|
44963
|
-
|
|
44964
|
-
|
|
44965
|
-
|
|
44966
|
-
|
|
44967
|
-
|
|
44968
|
-
|
|
44969
|
-
|
|
44970
|
-
|
|
44971
|
-
|
|
44972
|
-
|
|
44973
|
-
const
|
|
44974
|
-
const
|
|
44975
|
-
|
|
44976
|
-
|
|
44977
|
-
|
|
44978
|
-
|
|
44979
|
-
|
|
44980
|
-
|
|
44981
|
-
|
|
44982
|
-
}
|
|
44983
|
-
|
|
44984
|
-
|
|
44985
|
-
|
|
44986
|
-
return bnFeeAmount;
|
|
44987
|
-
};
|
|
44988
|
-
const calculateFees = (orderFees, weiAmount, decimals = 18) => {
|
|
44989
|
-
let totalTokenFees = BigNumber$1.from(0);
|
|
44990
|
-
const amountBn = BigNumber$1.from(weiAmount);
|
|
44991
|
-
// note: multiply in and out of the maximum decimal places to the power of ten to do the math in big number integers
|
|
44992
|
-
const totalAllowableFees = amountBn
|
|
44993
|
-
.mul(MAX_FEE_PERCENTAGE_DECIMAL * (10 ** MAX_FEE_DECIMAL_PLACES))
|
|
44994
|
-
.div(10 ** MAX_FEE_DECIMAL_PLACES);
|
|
44995
|
-
const calculateFeesResult = [];
|
|
44996
|
-
for (const orderFee of orderFees) {
|
|
44997
|
-
let currentFeeBn = BigNumber$1.from(0);
|
|
44998
|
-
if (Object.hasOwn(orderFee.amount, 'percentageDecimal')) {
|
|
44999
|
-
currentFeeBn = calculateFeesPercent(orderFee, amountBn);
|
|
45000
|
-
totalTokenFees = totalTokenFees.add(currentFeeBn);
|
|
44328
|
+
async getTransakWidgetUrl(params) {
|
|
44329
|
+
let widgetUrl = `${TRANSAK_API_BASE_URL[this.config.environment]}?`;
|
|
44330
|
+
const onRampConfig = (await this.config.remote.getConfig('onramp'));
|
|
44331
|
+
const apiKey = onRampConfig[OnRampProvider.TRANSAK].publishableApiKey;
|
|
44332
|
+
const transakPublishableKey = `apiKey=${apiKey}`;
|
|
44333
|
+
const zkevmNetwork = 'network=immutablezkevm';
|
|
44334
|
+
const defaultPaymentMethod = 'defaultPaymentMethod=credit_debit_card';
|
|
44335
|
+
const disableBankTransfer = 'disablePaymentMethods=sepa_bank_transfer,gbp_bank_transfer,'
|
|
44336
|
+
+ 'pm_cash_app,pm_jwire,pm_paymaya,pm_bpi,pm_ubp,pm_grabpay,pm_shopeepay,pm_gcash,pm_pix,'
|
|
44337
|
+
+ 'pm_astropay,pm_pse,inr_bank_transfer';
|
|
44338
|
+
const productsAvailed = 'productsAvailed=buy';
|
|
44339
|
+
const exchangeScreenTitle = 'exchangeScreenTitle=Buy';
|
|
44340
|
+
const themeColor = 'themeColor=0D0D0D';
|
|
44341
|
+
widgetUrl += `${transakPublishableKey}&`
|
|
44342
|
+
+ `${zkevmNetwork}&`
|
|
44343
|
+
+ `${defaultPaymentMethod}&`
|
|
44344
|
+
+ `${disableBankTransfer}&`
|
|
44345
|
+
+ `${productsAvailed}&`
|
|
44346
|
+
+ `${exchangeScreenTitle}&`
|
|
44347
|
+
+ `${themeColor}`;
|
|
44348
|
+
if (params.isPassport && params.email) {
|
|
44349
|
+
const encodedEmail = encodeURIComponent(params.email);
|
|
44350
|
+
widgetUrl += `&email=${encodedEmail}&isAutoFillUserData=true&disableWalletAddressForm=true`;
|
|
45001
44351
|
}
|
|
45002
|
-
|
|
45003
|
-
|
|
45004
|
-
totalTokenFees = totalTokenFees.add(currentFeeBn);
|
|
44352
|
+
if (params.tokenAmount && params.tokenSymbol) {
|
|
44353
|
+
widgetUrl += `&defaultCryptoAmount=${params.tokenAmount}&cryptoCurrencyCode=${params.tokenSymbol}`;
|
|
45005
44354
|
}
|
|
45006
44355
|
else {
|
|
45007
|
-
|
|
45008
|
-
}
|
|
45009
|
-
if (totalTokenFees.gt(totalAllowableFees)) {
|
|
45010
|
-
throw new CheckoutError(`The combined fees are above the allowed maximum of ${MAX_FEE_PERCENTAGE_DECIMAL * 100}%`, CheckoutErrorType.ORDER_FEE_ERROR);
|
|
44356
|
+
widgetUrl += '&defaultCryptoCurrency=IMX';
|
|
45011
44357
|
}
|
|
45012
|
-
if (
|
|
45013
|
-
|
|
45014
|
-
amount: currentFeeBn.toString(),
|
|
45015
|
-
recipientAddress: orderFee.recipient,
|
|
45016
|
-
});
|
|
44358
|
+
if (params.walletAddress) {
|
|
44359
|
+
widgetUrl += `&walletAddress=${params.walletAddress}`;
|
|
45017
44360
|
}
|
|
45018
|
-
|
|
45019
|
-
|
|
45020
|
-
}
|
|
44361
|
+
return widgetUrl;
|
|
44362
|
+
}
|
|
44363
|
+
}
|
|
45021
44364
|
|
|
45022
|
-
|
|
45023
|
-
|
|
45024
|
-
|
|
44365
|
+
async function getItemRequirementsFromRequirements(provider, requirements) {
|
|
44366
|
+
// Get all decimal values by calling contracts for each ERC20
|
|
44367
|
+
const decimalPromises = [];
|
|
44368
|
+
requirements.forEach((itemRequirementParam) => {
|
|
44369
|
+
if (itemRequirementParam.type === ItemType.ERC20) {
|
|
44370
|
+
const { tokenAddress } = itemRequirementParam;
|
|
44371
|
+
decimalPromises.push(getTokenContract(tokenAddress, ERC20ABI, provider).decimals());
|
|
44372
|
+
}
|
|
44373
|
+
});
|
|
44374
|
+
const decimals = await Promise.all(decimalPromises);
|
|
44375
|
+
// Map ItemRequirementsParam objects to ItemRequirement by parsing amounts from formatted string to BigNumebrs
|
|
44376
|
+
const itemRequirements = requirements.map((itemRequirementParam, index) => {
|
|
44377
|
+
if (itemRequirementParam.type === ItemType.NATIVE) {
|
|
45025
44378
|
return {
|
|
45026
|
-
|
|
45027
|
-
amount,
|
|
45028
|
-
tokenAddress,
|
|
45029
|
-
spenderAddress,
|
|
44379
|
+
...itemRequirementParam,
|
|
44380
|
+
amount: utils$3.parseUnits(itemRequirementParam.amount, 18),
|
|
45030
44381
|
};
|
|
45031
|
-
|
|
45032
|
-
|
|
44382
|
+
}
|
|
44383
|
+
if (itemRequirementParam.type === ItemType.ERC20) {
|
|
45033
44384
|
return {
|
|
45034
|
-
|
|
45035
|
-
amount,
|
|
44385
|
+
...itemRequirementParam,
|
|
44386
|
+
amount: utils$3.parseUnits(itemRequirementParam.amount, decimals[index]),
|
|
45036
44387
|
};
|
|
44388
|
+
}
|
|
44389
|
+
return itemRequirementParam;
|
|
44390
|
+
});
|
|
44391
|
+
return itemRequirements;
|
|
44392
|
+
}
|
|
44393
|
+
|
|
44394
|
+
/**
|
|
44395
|
+
* Validates and builds a version string based on the given SemanticVersion object.
|
|
44396
|
+
* If the version is undefined or has an invalid major version, it returns the default checkout version.
|
|
44397
|
+
* If the version is all zeros, it also returns the default checkout version.
|
|
44398
|
+
* Otherwise, it constructs a validated version string based on the major, minor, patch, and build numbers.
|
|
44399
|
+
*/
|
|
44400
|
+
function validateAndBuildVersion(version) {
|
|
44401
|
+
const defaultPackageVersion = globalPackageVersion();
|
|
44402
|
+
if (version === undefined || version.major === undefined)
|
|
44403
|
+
return defaultPackageVersion;
|
|
44404
|
+
if (!Number.isInteger(version.major) || version.major < 0)
|
|
44405
|
+
return defaultPackageVersion;
|
|
44406
|
+
if (version.minor !== undefined && version.minor < 0)
|
|
44407
|
+
return defaultPackageVersion;
|
|
44408
|
+
if (version.patch !== undefined && version.patch < 0)
|
|
44409
|
+
return defaultPackageVersion;
|
|
44410
|
+
if (version.major === 0 && version.minor === undefined)
|
|
44411
|
+
return defaultPackageVersion;
|
|
44412
|
+
if (version.major === 0 && version.minor === 0 && version.patch === undefined)
|
|
44413
|
+
return defaultPackageVersion;
|
|
44414
|
+
if (version.major === 0 && version.minor === undefined && version.patch === undefined)
|
|
44415
|
+
return defaultPackageVersion;
|
|
44416
|
+
if (version.major === 0 && version.minor === 0 && version.patch === 0)
|
|
44417
|
+
return defaultPackageVersion;
|
|
44418
|
+
let validatedVersion = version.major.toString();
|
|
44419
|
+
if (version.minor === undefined)
|
|
44420
|
+
return validatedVersion;
|
|
44421
|
+
if (Number.isInteger(version.minor)) {
|
|
44422
|
+
validatedVersion += `.${version.minor.toString()}`;
|
|
45037
44423
|
}
|
|
45038
|
-
|
|
45039
|
-
|
|
45040
|
-
if (
|
|
45041
|
-
|
|
45042
|
-
|
|
45043
|
-
|
|
44424
|
+
if (version.patch === undefined)
|
|
44425
|
+
return validatedVersion;
|
|
44426
|
+
if (Number.isInteger(version.patch)) {
|
|
44427
|
+
validatedVersion += `.${version.patch.toString()}`;
|
|
44428
|
+
}
|
|
44429
|
+
if (version.prerelease === undefined || version.prerelease !== 'alpha')
|
|
44430
|
+
return validatedVersion;
|
|
44431
|
+
if (version.prerelease === 'alpha') {
|
|
44432
|
+
validatedVersion += `-${version.prerelease}`;
|
|
44433
|
+
}
|
|
44434
|
+
if (version.build === undefined)
|
|
44435
|
+
return validatedVersion;
|
|
44436
|
+
if (Number.isInteger(version.build) && version.build >= 0) {
|
|
44437
|
+
validatedVersion += `.${version.build.toString()}`;
|
|
44438
|
+
}
|
|
44439
|
+
return validatedVersion;
|
|
44440
|
+
}
|
|
44441
|
+
|
|
44442
|
+
function loadUnresolved(version) {
|
|
44443
|
+
if (window === undefined) {
|
|
44444
|
+
throw new Error('missing window object: please run Checkout client side');
|
|
44445
|
+
}
|
|
44446
|
+
if (document === undefined) {
|
|
44447
|
+
throw new Error('missing document object: please run Checkout client side');
|
|
44448
|
+
}
|
|
44449
|
+
const scriptId = 'immutable-checkout-widgets-bundle';
|
|
44450
|
+
const validVersion = validateAndBuildVersion(version);
|
|
44451
|
+
// Prevent the script to be loaded more than once
|
|
44452
|
+
// by checking the presence of the script and its version.
|
|
44453
|
+
const initScript = document.getElementById(scriptId);
|
|
44454
|
+
if (initScript)
|
|
44455
|
+
return { loaded: true, element: initScript };
|
|
44456
|
+
const tag = document.createElement('script');
|
|
44457
|
+
let cdnUrl = `https://cdn.jsdelivr.net/npm/@imtbl/sdk@${validVersion}/dist/browser/checkout/widgets.js`;
|
|
44458
|
+
tag.setAttribute('id', scriptId);
|
|
44459
|
+
tag.setAttribute('data-version', validVersion);
|
|
44460
|
+
tag.setAttribute('src', cdnUrl);
|
|
44461
|
+
document.head.appendChild(tag);
|
|
44462
|
+
return { loaded: false, element: tag };
|
|
44463
|
+
}
|
|
44464
|
+
|
|
44465
|
+
const PUBLISHABLE_KEY_PREFIX = 'pk_imapik-';
|
|
44466
|
+
const publishableKeyDomainAllowlist = [
|
|
44467
|
+
'https://checkout-api.dev.immutable.com',
|
|
44468
|
+
'https://checkout-api.sandbox.immutable.com',
|
|
44469
|
+
'https://checkout-api.immutable.com',
|
|
44470
|
+
];
|
|
44471
|
+
class HttpClient {
|
|
44472
|
+
config;
|
|
44473
|
+
axiosInstance;
|
|
44474
|
+
constructor(config) {
|
|
44475
|
+
this.config = config;
|
|
44476
|
+
this.axiosInstance = globalAxios$1.create();
|
|
44477
|
+
this.setupInterceptors();
|
|
44478
|
+
}
|
|
44479
|
+
// eslint-disable-next-line class-methods-use-this
|
|
44480
|
+
shouldAddPublishableKey(url) {
|
|
44481
|
+
// Check if the request is going to a whitelisted domain
|
|
44482
|
+
return publishableKeyDomainAllowlist.some((domain) => url.startsWith(domain));
|
|
44483
|
+
}
|
|
44484
|
+
setupInterceptors() {
|
|
44485
|
+
this.axiosInstance.interceptors.request.use((config) => {
|
|
44486
|
+
const publishableKey = this.config?.baseConfig?.publishableKey;
|
|
44487
|
+
if (publishableKey && this.shouldAddPublishableKey(config.url || '')) {
|
|
44488
|
+
if (!publishableKey.startsWith(PUBLISHABLE_KEY_PREFIX)) {
|
|
44489
|
+
throw new Error('Invalid Publishable key. Create your Publishable key in Immutable developer hub.'
|
|
44490
|
+
+ ' https://hub.immutable.com');
|
|
44491
|
+
}
|
|
44492
|
+
// Add publishable key header for whitelisted domains
|
|
44493
|
+
// eslint-disable-next-line no-param-reassign
|
|
44494
|
+
config.headers['x-immutable-publishable-key'] = publishableKey;
|
|
44495
|
+
}
|
|
44496
|
+
return config;
|
|
44497
|
+
}, (error) => Promise.reject(error));
|
|
44498
|
+
}
|
|
44499
|
+
async request(config) {
|
|
44500
|
+
return await this.axiosInstance.request(config);
|
|
44501
|
+
}
|
|
44502
|
+
async get(url, config) {
|
|
44503
|
+
const requestConfig = {
|
|
44504
|
+
...config,
|
|
44505
|
+
url,
|
|
45044
44506
|
};
|
|
44507
|
+
return await this.request(requestConfig);
|
|
45045
44508
|
}
|
|
45046
|
-
|
|
45047
|
-
|
|
45048
|
-
|
|
45049
|
-
|
|
45050
|
-
|
|
45051
|
-
}
|
|
45052
|
-
|
|
44509
|
+
async post(url, data, config) {
|
|
44510
|
+
const requestConfig = {
|
|
44511
|
+
...config,
|
|
44512
|
+
data,
|
|
44513
|
+
url,
|
|
44514
|
+
};
|
|
44515
|
+
return await this.request(requestConfig);
|
|
44516
|
+
}
|
|
44517
|
+
async put(url, data, config) {
|
|
44518
|
+
const requestConfig = {
|
|
44519
|
+
...config,
|
|
44520
|
+
data,
|
|
44521
|
+
url,
|
|
44522
|
+
};
|
|
44523
|
+
return await this.request(requestConfig);
|
|
44524
|
+
}
|
|
44525
|
+
async delete(url, data, config) {
|
|
44526
|
+
const requestConfig = {
|
|
44527
|
+
...config,
|
|
44528
|
+
data,
|
|
44529
|
+
url,
|
|
44530
|
+
};
|
|
44531
|
+
return await this.request(requestConfig);
|
|
44532
|
+
}
|
|
44533
|
+
}
|
|
44534
|
+
|
|
44535
|
+
const SANDBOX_CONFIGURATION = {
|
|
44536
|
+
baseConfig: {
|
|
44537
|
+
environment: Environment$1.SANDBOX,
|
|
44538
|
+
},
|
|
44539
|
+
passport: undefined,
|
|
45053
44540
|
};
|
|
45054
|
-
const
|
|
45055
|
-
|
|
45056
|
-
|
|
45057
|
-
|
|
45058
|
-
|
|
44541
|
+
const WIDGETS_SCRIPT_TIMEOUT = 100;
|
|
44542
|
+
// Checkout SDK
|
|
44543
|
+
class Checkout {
|
|
44544
|
+
readOnlyProviders;
|
|
44545
|
+
httpClient;
|
|
44546
|
+
config;
|
|
44547
|
+
fiatRampService;
|
|
44548
|
+
availability;
|
|
44549
|
+
passport;
|
|
44550
|
+
/**
|
|
44551
|
+
* Constructs a new instance of the CheckoutModule class.
|
|
44552
|
+
* @param {CheckoutModuleConfiguration} [config=SANDBOX_CONFIGURATION] - The configuration object for the CheckoutModule.
|
|
44553
|
+
*/
|
|
44554
|
+
constructor(config = SANDBOX_CONFIGURATION) {
|
|
44555
|
+
this.httpClient = new HttpClient(config);
|
|
44556
|
+
this.config = new CheckoutConfiguration(config, this.httpClient);
|
|
44557
|
+
this.fiatRampService = new FiatRampService(this.config);
|
|
44558
|
+
this.readOnlyProviders = new Map();
|
|
44559
|
+
this.availability = availabilityService(this.config.isDevelopment, this.config.isProduction);
|
|
44560
|
+
this.passport = config.passport;
|
|
44561
|
+
}
|
|
44562
|
+
/**
|
|
44563
|
+
* Loads the widgets bundle and initiate the widgets factory.
|
|
44564
|
+
* @param {WidgetsInit} init - The initialisation parameters for loading the widgets bundle and applying configuration
|
|
44565
|
+
*/
|
|
44566
|
+
async widgets(init) {
|
|
44567
|
+
const checkout = this;
|
|
44568
|
+
// Preload the configurations
|
|
44569
|
+
await checkout.config.remote.getConfig();
|
|
44570
|
+
const factory = new Promise((resolve, reject) => {
|
|
44571
|
+
function checkForWidgetsBundleLoaded() {
|
|
44572
|
+
if (typeof ImmutableCheckoutWidgets !== 'undefined') {
|
|
44573
|
+
resolve(new ImmutableCheckoutWidgets.WidgetsFactory(checkout, init.config));
|
|
44574
|
+
}
|
|
44575
|
+
else {
|
|
44576
|
+
// If ImmutableCheckoutWidgets is not defined, wait for set amount of time.
|
|
44577
|
+
// When time has elapsed, check again if ImmutableCheckoutWidgets is defined.
|
|
44578
|
+
// Once it's defined, the promise will resolve and setTimeout won't be called again.
|
|
44579
|
+
setTimeout(checkForWidgetsBundleLoaded, WIDGETS_SCRIPT_TIMEOUT);
|
|
44580
|
+
}
|
|
44581
|
+
}
|
|
44582
|
+
try {
|
|
44583
|
+
const script = loadUnresolved(init.version);
|
|
44584
|
+
if (script.loaded && typeof ImmutableCheckoutWidgets !== 'undefined') {
|
|
44585
|
+
resolve(new ImmutableCheckoutWidgets.WidgetsFactory(checkout, init.config));
|
|
44586
|
+
}
|
|
44587
|
+
else {
|
|
44588
|
+
checkForWidgetsBundleLoaded();
|
|
44589
|
+
}
|
|
44590
|
+
}
|
|
44591
|
+
catch (err) {
|
|
44592
|
+
reject(new CheckoutError('Failed to load widgets script', CheckoutErrorType.WIDGETS_SCRIPT_LOAD_ERROR, { error: err }));
|
|
44593
|
+
}
|
|
44594
|
+
});
|
|
44595
|
+
return factory;
|
|
44596
|
+
}
|
|
44597
|
+
/**
|
|
44598
|
+
* Creates a provider using the given parameters.
|
|
44599
|
+
* @param {CreateProviderParams} params - The parameters for creating the provider.
|
|
44600
|
+
* @returns {Promise<CreateProviderResult>} A promise that resolves to the created provider.
|
|
44601
|
+
*/
|
|
44602
|
+
async createProvider(params) {
|
|
44603
|
+
return await createProvider(params.walletProviderName, this.passport);
|
|
44604
|
+
}
|
|
44605
|
+
/**
|
|
44606
|
+
* Checks if a wallet is connected to the specified provider.
|
|
44607
|
+
* @param {CheckConnectionParams} params - The parameters for checking the wallet connection.
|
|
44608
|
+
* @returns {Promise<CheckConnectionResult>} - A promise that resolves to the result of the check.
|
|
44609
|
+
*/
|
|
44610
|
+
async checkIsWalletConnected(params) {
|
|
44611
|
+
const web3Provider = await validateProvider(this.config, params.provider, { allowUnsupportedProvider: true });
|
|
44612
|
+
return checkIsWalletConnected(web3Provider);
|
|
45059
44613
|
}
|
|
45060
|
-
|
|
45061
|
-
|
|
45062
|
-
|
|
45063
|
-
|
|
45064
|
-
|
|
45065
|
-
|
|
45066
|
-
|
|
45067
|
-
|
|
45068
|
-
|
|
45069
|
-
|
|
45070
|
-
getAllBalances(config, provider, fulfillerAddress, getL2ChainId(config));
|
|
45071
|
-
const { id, takerFees } = orders[0];
|
|
45072
|
-
let orderChainName;
|
|
45073
|
-
try {
|
|
45074
|
-
order = await measureAsyncExecution(config, 'Time to fetch the listing from the orderbook', orderbook.getListing(id));
|
|
45075
|
-
const { seaportContractAddress, chainName } = orderbook.config();
|
|
45076
|
-
orderChainName = chainName;
|
|
45077
|
-
spenderAddress = seaportContractAddress;
|
|
44614
|
+
/**
|
|
44615
|
+
* Connects to a blockchain network using the specified provider.
|
|
44616
|
+
* @param {ConnectParams} params - The parameters for connecting to the network.
|
|
44617
|
+
* @returns {Promise<ConnectResult>} A promise that resolves to an object containing the provider and network information.
|
|
44618
|
+
* @throws {Error} If the provider is not valid or if there is an error connecting to the network.
|
|
44619
|
+
*/
|
|
44620
|
+
async connect(params) {
|
|
44621
|
+
const web3Provider = await validateProvider(this.config, params.provider, { allowUnsupportedProvider: true });
|
|
44622
|
+
await connectSite(web3Provider);
|
|
44623
|
+
return { provider: web3Provider };
|
|
45078
44624
|
}
|
|
45079
|
-
|
|
45080
|
-
|
|
45081
|
-
|
|
45082
|
-
|
|
44625
|
+
/**
|
|
44626
|
+
* Switches the network for the current wallet provider.
|
|
44627
|
+
* @param {SwitchNetworkParams} params - The parameters for switching the network.
|
|
44628
|
+
* @returns {Promise<SwitchNetworkResult>} - A promise that resolves to the result of switching the network.
|
|
44629
|
+
*/
|
|
44630
|
+
async switchNetwork(params) {
|
|
44631
|
+
const web3Provider = await validateProvider(this.config, params.provider, {
|
|
44632
|
+
allowUnsupportedProvider: true,
|
|
44633
|
+
allowMistmatchedChainId: true,
|
|
45083
44634
|
});
|
|
44635
|
+
const switchNetworkRes = await switchWalletNetwork(this.config, web3Provider, params.chainId);
|
|
44636
|
+
return switchNetworkRes;
|
|
45084
44637
|
}
|
|
45085
|
-
|
|
45086
|
-
|
|
45087
|
-
|
|
45088
|
-
|
|
45089
|
-
|
|
44638
|
+
/**
|
|
44639
|
+
* Retrieves the token information given the token address. This function makes RPC calls to
|
|
44640
|
+
* ERC20 contracts to fetch the main contract information (e.g. symbol).
|
|
44641
|
+
* @param {GetTokenInfoParams} params - The parameters for retrieving the token information.
|
|
44642
|
+
* @returns {Promise<TokenInfo>} - A promise that resolves to the token info request.
|
|
44643
|
+
*/
|
|
44644
|
+
async getTokenInfo(params) {
|
|
44645
|
+
return await getERC20TokenInfo(params.provider, params.tokenAddress);
|
|
45090
44646
|
}
|
|
45091
|
-
|
|
45092
|
-
|
|
45093
|
-
|
|
45094
|
-
|
|
45095
|
-
|
|
44647
|
+
/**
|
|
44648
|
+
* Retrieves the balance of a wallet address.
|
|
44649
|
+
* @param {GetBalanceParams} params - The parameters for retrieving the balance.
|
|
44650
|
+
* @returns {Promise<GetBalanceResult>} - A promise that resolves to the balance result.
|
|
44651
|
+
*/
|
|
44652
|
+
async getBalance(params) {
|
|
44653
|
+
const web3Provider = await validateProvider(this.config, params.provider);
|
|
44654
|
+
if (!params.tokenAddress || params.tokenAddress === '') {
|
|
44655
|
+
return await getBalance(this.config, web3Provider, params.walletAddress);
|
|
44656
|
+
}
|
|
44657
|
+
return await getERC20Balance(web3Provider, params.walletAddress, params.tokenAddress);
|
|
45096
44658
|
}
|
|
45097
|
-
|
|
45098
|
-
|
|
45099
|
-
|
|
44659
|
+
/**
|
|
44660
|
+
* Retrieves the balances of all tokens for a given wallet address on a specific chain.
|
|
44661
|
+
* @param {GetAllBalancesParams} params - The parameters for retrieving the balances.
|
|
44662
|
+
* @returns {Promise<GetAllBalancesResult>} - A promise that resolves to the result of retrieving the balances.
|
|
44663
|
+
*/
|
|
44664
|
+
async getAllBalances(params) {
|
|
44665
|
+
return getAllBalances(this.config, params.provider, params.walletAddress, params.chainId);
|
|
45100
44666
|
}
|
|
45101
|
-
|
|
45102
|
-
|
|
45103
|
-
|
|
45104
|
-
|
|
45105
|
-
|
|
45106
|
-
|
|
45107
|
-
|
|
45108
|
-
unsignedApprovalTransactions = await measureAsyncExecution(config, 'Time to construct the unsigned approval transactions', getUnsignedERC20ApprovalTransactions(actions));
|
|
44667
|
+
/**
|
|
44668
|
+
* Retrieves the supported networks based on the provided parameters.
|
|
44669
|
+
* @param {GetNetworkAllowListParams} params - The parameters for retrieving the network allow list.
|
|
44670
|
+
* @returns {Promise<GetNetworkAllowListResult>} - A promise that resolves to the network allow list result.
|
|
44671
|
+
*/
|
|
44672
|
+
async getNetworkAllowList(params) {
|
|
44673
|
+
return await getNetworkAllowList(this.config, params);
|
|
45109
44674
|
}
|
|
45110
|
-
|
|
45111
|
-
|
|
45112
|
-
|
|
45113
|
-
|
|
45114
|
-
|
|
45115
|
-
|
|
45116
|
-
|
|
45117
|
-
// need to assert on this string to check that the error is not a balances error
|
|
45118
|
-
if (!err.message.includes('The fulfiller does not have the balances needed to fulfill')) {
|
|
45119
|
-
throw new CheckoutError('Error occurred while trying to fulfill the order', CheckoutErrorType.FULFILL_ORDER_LISTING_ERROR, {
|
|
45120
|
-
orderId: id,
|
|
45121
|
-
error: err,
|
|
45122
|
-
});
|
|
45123
|
-
}
|
|
44675
|
+
/**
|
|
44676
|
+
* Retrieves the supported tokens based on the provided parameters.
|
|
44677
|
+
* @param {GetTokenAllowListParams} params - The parameters for retrieving the token allow list.
|
|
44678
|
+
* @returns {Promise<GetTokenAllowListResult>} - A promise that resolves to the token allow list result.
|
|
44679
|
+
*/
|
|
44680
|
+
async getTokenAllowList(params) {
|
|
44681
|
+
return await getTokenAllowList(this.config, params);
|
|
45124
44682
|
}
|
|
45125
|
-
|
|
45126
|
-
|
|
44683
|
+
/**
|
|
44684
|
+
* Retrieves the default supported wallets based on the provided parameters.
|
|
44685
|
+
* @param {GetWalletAllowListParams} params - The parameters for retrieving the wallet allow list.
|
|
44686
|
+
* @returns {Promise<GetWalletAllowListResult>} - A promise that resolves to the wallet allow list result.
|
|
44687
|
+
*/
|
|
44688
|
+
async getWalletAllowList(params) {
|
|
44689
|
+
return await getWalletAllowList(params);
|
|
45127
44690
|
}
|
|
45128
|
-
|
|
45129
|
-
|
|
45130
|
-
|
|
44691
|
+
/**
|
|
44692
|
+
* Sends a transaction using the specified provider and transaction parameters.
|
|
44693
|
+
* @param {SendTransactionParams} params - The parameters for sending the transaction.
|
|
44694
|
+
* @returns {Promise<SendTransactionResult>} A promise that resolves to the result of the transaction.
|
|
44695
|
+
*/
|
|
44696
|
+
async sendTransaction(params) {
|
|
44697
|
+
const web3Provider = await validateProvider(this.config, params.provider);
|
|
44698
|
+
return await sendTransaction(web3Provider, params.transaction);
|
|
45131
44699
|
}
|
|
45132
|
-
|
|
45133
|
-
|
|
45134
|
-
|
|
45135
|
-
|
|
45136
|
-
|
|
45137
|
-
|
|
45138
|
-
|
|
45139
|
-
|
|
45140
|
-
|
|
45141
|
-
|
|
45142
|
-
|
|
45143
|
-
contractAddress = buyArray[0].contractAddress;
|
|
45144
|
-
break;
|
|
45145
|
-
default:
|
|
45146
|
-
throw new CheckoutError('Purchasing token type is unsupported', CheckoutErrorType.UNSUPPORTED_TOKEN_TYPE_ERROR, {
|
|
45147
|
-
orderId: id,
|
|
45148
|
-
});
|
|
45149
|
-
}
|
|
44700
|
+
/**
|
|
44701
|
+
* Retrieves network information using the specified provider.
|
|
44702
|
+
* @param {GetNetworkParams} params - The parameters for retrieving network information.
|
|
44703
|
+
* @returns {Promise<NetworkInfo>} A promise that resolves to the network information.
|
|
44704
|
+
*/
|
|
44705
|
+
async getNetworkInfo(params) {
|
|
44706
|
+
const web3Provider = await validateProvider(this.config, params.provider, {
|
|
44707
|
+
allowUnsupportedProvider: true,
|
|
44708
|
+
allowMistmatchedChainId: true,
|
|
44709
|
+
});
|
|
44710
|
+
return await getNetworkInfo(this.config, web3Provider);
|
|
45150
44711
|
}
|
|
45151
|
-
|
|
45152
|
-
|
|
45153
|
-
|
|
44712
|
+
/**
|
|
44713
|
+
* Determines the requirements for performing a buy.
|
|
44714
|
+
* @param {BuyParams} params - The parameters for the buy.
|
|
44715
|
+
*/
|
|
44716
|
+
async buy(params) {
|
|
44717
|
+
if (params.orders.length > 1) {
|
|
44718
|
+
// eslint-disable-next-line no-console
|
|
44719
|
+
console.warn('This endpoint currently only processes the first order in the array.');
|
|
45154
44720
|
}
|
|
45155
|
-
|
|
45156
|
-
|
|
45157
|
-
|
|
45158
|
-
|
|
45159
|
-
|
|
45160
|
-
|
|
45161
|
-
|
|
45162
|
-
|
|
45163
|
-
|
|
45164
|
-
|
|
45165
|
-
|
|
45166
|
-
|
|
45167
|
-
|
|
45168
|
-
status: CheckoutStatus.FAILED,
|
|
45169
|
-
transactionHash: approvalResult.transactionHash,
|
|
45170
|
-
reason: approvalResult.reason,
|
|
45171
|
-
smartCheckoutResult,
|
|
45172
|
-
};
|
|
44721
|
+
const web3Provider = await validateProvider(this.config, params.provider);
|
|
44722
|
+
return await buy(this.config, web3Provider, params.orders, params.overrides);
|
|
44723
|
+
}
|
|
44724
|
+
/**
|
|
44725
|
+
* Determines the requirements for performing a sell.
|
|
44726
|
+
* @param {SellParams} params - The parameters for the sell.
|
|
44727
|
+
* Only currently actions the first order in the array until we support batch processing.
|
|
44728
|
+
* Only currently actions the first fee in the fees array of each order until we support multiple fees.
|
|
44729
|
+
*/
|
|
44730
|
+
async sell(params) {
|
|
44731
|
+
if (params.orders.length > 1) {
|
|
44732
|
+
// eslint-disable-next-line no-console
|
|
44733
|
+
console.warn('This endpoint currently only processes the first order in the array.');
|
|
45173
44734
|
}
|
|
44735
|
+
const web3Provider = await validateProvider(this.config, params.provider);
|
|
44736
|
+
return await sell(this.config, web3Provider, params.orders);
|
|
44737
|
+
}
|
|
44738
|
+
/**
|
|
44739
|
+
* Cancels a sell.
|
|
44740
|
+
* @param {CancelParams} params - The parameters for the cancel.
|
|
44741
|
+
*/
|
|
44742
|
+
async cancel(params) {
|
|
44743
|
+
// eslint-disable-next-line no-console
|
|
44744
|
+
console.warn('This endpoint currently only processes the first order in the array.');
|
|
44745
|
+
const web3Provider = await validateProvider(this.config, params.provider);
|
|
44746
|
+
return await cancel(this.config, web3Provider, params.orderIds, params.overrides);
|
|
44747
|
+
}
|
|
44748
|
+
/**
|
|
44749
|
+
* Determines the transaction requirements to complete a purchase.
|
|
44750
|
+
* @params {SmartCheckoutParams} params - The parameters for smart checkout.
|
|
44751
|
+
*/
|
|
44752
|
+
async smartCheckout(params) {
|
|
44753
|
+
const web3Provider = await validateProvider(this.config, params.provider);
|
|
44754
|
+
let itemRequirements = [];
|
|
45174
44755
|
try {
|
|
45175
|
-
|
|
45176
|
-
unsignedFulfillmentTransactions = await getUnsignedFulfillmentTransactions(orderActions);
|
|
45177
|
-
}
|
|
44756
|
+
itemRequirements = await getItemRequirementsFromRequirements(web3Provider, params.itemRequirements);
|
|
45178
44757
|
}
|
|
45179
44758
|
catch (err) {
|
|
45180
|
-
throw new CheckoutError('
|
|
45181
|
-
}
|
|
45182
|
-
if (overrides.waitFulfillmentSettlements) {
|
|
45183
|
-
const fulfillmentResult = await signFulfillmentTransactions(provider, unsignedFulfillmentTransactions);
|
|
45184
|
-
if (fulfillmentResult.type === SignTransactionStatusType.FAILED) {
|
|
45185
|
-
return {
|
|
45186
|
-
status: CheckoutStatus.FAILED,
|
|
45187
|
-
transactionHash: fulfillmentResult.transactionHash,
|
|
45188
|
-
reason: fulfillmentResult.reason,
|
|
45189
|
-
smartCheckoutResult,
|
|
45190
|
-
};
|
|
45191
|
-
}
|
|
45192
|
-
return {
|
|
45193
|
-
status: CheckoutStatus.SUCCESS,
|
|
45194
|
-
smartCheckoutResult,
|
|
45195
|
-
};
|
|
44759
|
+
throw new CheckoutError('Failed to map item requirements', CheckoutErrorType.ITEM_REQUIREMENTS_ERROR, { error: err });
|
|
45196
44760
|
}
|
|
45197
|
-
|
|
45198
|
-
|
|
45199
|
-
|
|
45200
|
-
|
|
44761
|
+
return await smartCheckout(this.config, web3Provider, itemRequirements, params.transactionOrGasAmount);
|
|
44762
|
+
}
|
|
44763
|
+
/**
|
|
44764
|
+
* Checks if the given object is a Web3 provider.
|
|
44765
|
+
* @param {Web3Provider} web3Provider - The object to check.
|
|
44766
|
+
* @returns {boolean} - True if the object is a Web3 provider, false otherwise.
|
|
44767
|
+
*/
|
|
44768
|
+
static isWeb3Provider(web3Provider) {
|
|
44769
|
+
return isWeb3Provider(web3Provider);
|
|
44770
|
+
}
|
|
44771
|
+
/**
|
|
44772
|
+
* Estimates the gas required for a swap or bridge transaction.
|
|
44773
|
+
* @param {GasEstimateParams} params - The parameters for the gas estimation.
|
|
44774
|
+
* @returns {Promise<GasEstimateSwapResult | GasEstimateBridgeToL2Result>} - A promise that resolves to the gas estimation result.
|
|
44775
|
+
*/
|
|
44776
|
+
async gasEstimate(params) {
|
|
44777
|
+
this.readOnlyProviders = await createReadOnlyProviders(this.config, this.readOnlyProviders);
|
|
44778
|
+
return await gasEstimator(params, this.readOnlyProviders, this.config);
|
|
44779
|
+
}
|
|
44780
|
+
/**
|
|
44781
|
+
* Creates and returns a URL for the fiat ramp widget.
|
|
44782
|
+
* @param {FiatRampParams} params - The parameters for creating the url.
|
|
44783
|
+
* @returns {Promise<string>} - A promise that resolves to a string url.
|
|
44784
|
+
*/
|
|
44785
|
+
async createFiatRampUrl(params) {
|
|
44786
|
+
let tokenAmount;
|
|
44787
|
+
let tokenSymbol = 'IMX';
|
|
44788
|
+
let email;
|
|
44789
|
+
const walletAddress = await params.web3Provider.getSigner().getAddress();
|
|
44790
|
+
const isPassport = params.web3Provider.provider?.isPassport || false;
|
|
44791
|
+
if (isPassport && params.passport) {
|
|
44792
|
+
const userInfo = await params.passport.getUserInfo();
|
|
44793
|
+
email = userInfo?.email;
|
|
45201
44794
|
}
|
|
45202
|
-
|
|
45203
|
-
|
|
45204
|
-
|
|
45205
|
-
|
|
44795
|
+
const tokenList = await getTokenAllowList(this.config, { type: TokenFilterTypes.ONRAMP });
|
|
44796
|
+
const token = tokenList.tokens?.find((t) => isMatchingAddress(t.address, params.tokenAddress));
|
|
44797
|
+
if (token) {
|
|
44798
|
+
tokenAmount = params.tokenAmount;
|
|
44799
|
+
tokenSymbol = token.symbol;
|
|
45206
44800
|
}
|
|
45207
|
-
return {
|
|
45208
|
-
|
|
45209
|
-
|
|
45210
|
-
|
|
44801
|
+
return await this.fiatRampService.createWidgetUrl({
|
|
44802
|
+
exchangeType: params.exchangeType,
|
|
44803
|
+
isPassport,
|
|
44804
|
+
walletAddress,
|
|
44805
|
+
tokenAmount,
|
|
44806
|
+
tokenSymbol,
|
|
44807
|
+
email,
|
|
44808
|
+
});
|
|
44809
|
+
}
|
|
44810
|
+
/**
|
|
44811
|
+
* Fetches fiat ramp fee estimations.
|
|
44812
|
+
* @returns {Promise<OnRampProviderFees>} - A promise that resolves to OnRampProviderFees.
|
|
44813
|
+
*/
|
|
44814
|
+
async getExchangeFeeEstimate() {
|
|
44815
|
+
return await this.fiatRampService.feeEstimate();
|
|
44816
|
+
}
|
|
44817
|
+
/**
|
|
44818
|
+
* Fetches Swap widget availability.
|
|
44819
|
+
* @returns {Promise<boolean>} - A promise that resolves to a boolean.
|
|
44820
|
+
*/
|
|
44821
|
+
async isSwapAvailable() {
|
|
44822
|
+
return this.availability.checkDexAvailability();
|
|
44823
|
+
}
|
|
44824
|
+
}
|
|
44825
|
+
|
|
44826
|
+
class BlockExplorerService {
|
|
44827
|
+
/**
|
|
44828
|
+
* getTransationLink returns the link to the transaction on blockscout
|
|
44829
|
+
* @param hash transaction hash
|
|
44830
|
+
* @returns link to the transaction on blockscout
|
|
44831
|
+
*/
|
|
44832
|
+
static getTransactionLink(chainId, hash) {
|
|
44833
|
+
const url = BLOCKSCOUT_CHAIN_URL_MAP?.[chainId]?.url;
|
|
44834
|
+
if (!url || !hash)
|
|
44835
|
+
return undefined;
|
|
44836
|
+
return `${url}/tx/${hash}`;
|
|
44837
|
+
}
|
|
44838
|
+
}
|
|
44839
|
+
|
|
44840
|
+
var checkout = /*#__PURE__*/Object.freeze({
|
|
44841
|
+
__proto__: null,
|
|
44842
|
+
BlockExplorerService: BlockExplorerService,
|
|
44843
|
+
get BridgeEventType () { return BridgeEventType; },
|
|
44844
|
+
get ChainId () { return ChainId; },
|
|
44845
|
+
get ChainName () { return ChainName; },
|
|
44846
|
+
get ChainSlug () { return ChainSlug; },
|
|
44847
|
+
Checkout: Checkout,
|
|
44848
|
+
CheckoutConfiguration: CheckoutConfiguration,
|
|
44849
|
+
get CheckoutErrorType () { return CheckoutErrorType; },
|
|
44850
|
+
get CheckoutStatus () { return CheckoutStatus; },
|
|
44851
|
+
get ConnectEventType () { return ConnectEventType; },
|
|
44852
|
+
get ConnectTargetLayer () { return ConnectTargetLayer; },
|
|
44853
|
+
get ExchangeType () { return ExchangeType; },
|
|
44854
|
+
get FeeType () { return FeeType; },
|
|
44855
|
+
get FundingStepType () { return FundingStepType; },
|
|
44856
|
+
get GasEstimateType () { return GasEstimateType; },
|
|
44857
|
+
get GasTokenType () { return GasTokenType; },
|
|
44858
|
+
IMMUTABLE_API_BASE_URL: IMMUTABLE_API_BASE_URL,
|
|
44859
|
+
get IMTBLWidgetEvents () { return IMTBLWidgetEvents; },
|
|
44860
|
+
get ItemType () { return ItemType; },
|
|
44861
|
+
get NetworkFilterTypes () { return NetworkFilterTypes; },
|
|
44862
|
+
get OnRampEventType () { return OnRampEventType; },
|
|
44863
|
+
get OrchestrationEventType () { return OrchestrationEventType; },
|
|
44864
|
+
get ProviderEventType () { return ProviderEventType; },
|
|
44865
|
+
get RoutingOutcomeType () { return RoutingOutcomeType; },
|
|
44866
|
+
get SaleEventType () { return SaleEventType; },
|
|
44867
|
+
get SalePaymentTypes () { return SalePaymentTypes; },
|
|
44868
|
+
get SwapEventType () { return SwapEventType; },
|
|
44869
|
+
get TokenFilterTypes () { return TokenFilterTypes; },
|
|
44870
|
+
get TransactionOrGasType () { return TransactionOrGasType; },
|
|
44871
|
+
get WalletEventType () { return WalletEventType; },
|
|
44872
|
+
get WalletFilterTypes () { return WalletFilterTypes; },
|
|
44873
|
+
get WalletProviderName () { return WalletProviderName; },
|
|
44874
|
+
get WidgetTheme () { return WidgetTheme; },
|
|
44875
|
+
get WidgetType () { return WidgetType; }
|
|
44876
|
+
});
|
|
44877
|
+
|
|
44878
|
+
function isChainValid(chainID, config) {
|
|
44879
|
+
return chainID === config.ethConfiguration.chainID;
|
|
44880
|
+
}
|
|
44881
|
+
async function validateChain(signer, config) {
|
|
44882
|
+
const chainID = await signer.getChainId();
|
|
44883
|
+
if (!isChainValid(chainID, config)) {
|
|
44884
|
+
throw new Error('The wallet used for this operation is not connected to the correct network.');
|
|
44885
|
+
}
|
|
44886
|
+
}
|
|
44887
|
+
|
|
44888
|
+
async function transfer({ signers: { ethSigner, starkSigner }, request, config, }) {
|
|
44889
|
+
await validateChain(ethSigner, config.immutableXConfig);
|
|
44890
|
+
const ethAddress = await ethSigner.getAddress();
|
|
44891
|
+
const transfersApi = new TransfersApi$1(config.immutableXConfig.apiConfiguration);
|
|
44892
|
+
const transferAmount = request.type === 'ERC721' ? '1' : request.amount;
|
|
44893
|
+
const signableResult = await transfersApi.getSignableTransferV1({
|
|
44894
|
+
getSignableTransferRequest: {
|
|
44895
|
+
sender: ethAddress,
|
|
44896
|
+
token: convertToSignableToken(request),
|
|
44897
|
+
amount: transferAmount,
|
|
44898
|
+
receiver: request.receiver,
|
|
44899
|
+
},
|
|
44900
|
+
});
|
|
44901
|
+
const { signable_message: signableMessage, payload_hash: payloadHash } = signableResult.data;
|
|
44902
|
+
const ethSignature = await signRaw(signableMessage, ethSigner);
|
|
44903
|
+
const starkSignature = await starkSigner.signMessage(payloadHash);
|
|
44904
|
+
const transferSigningParams = {
|
|
44905
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
44906
|
+
sender_stark_key: signableResult.data.sender_stark_key,
|
|
44907
|
+
sender_vault_id: signableResult.data.sender_vault_id,
|
|
44908
|
+
receiver_stark_key: signableResult.data.receiver_stark_key,
|
|
44909
|
+
receiver_vault_id: signableResult.data.receiver_vault_id,
|
|
44910
|
+
asset_id: signableResult.data.asset_id,
|
|
44911
|
+
amount: signableResult.data.amount,
|
|
44912
|
+
nonce: signableResult.data.nonce,
|
|
44913
|
+
expiration_timestamp: signableResult.data.expiration_timestamp,
|
|
44914
|
+
stark_signature: starkSignature,
|
|
44915
|
+
};
|
|
44916
|
+
const response = await transfersApi.createTransferV1({
|
|
44917
|
+
createTransferRequest: transferSigningParams,
|
|
44918
|
+
xImxEthAddress: ethAddress,
|
|
44919
|
+
xImxEthSignature: ethSignature,
|
|
44920
|
+
});
|
|
44921
|
+
return {
|
|
44922
|
+
sent_signature: response?.data.sent_signature,
|
|
44923
|
+
status: response?.data.status?.toString(),
|
|
44924
|
+
time: response?.data.time,
|
|
44925
|
+
transfer_id: response?.data.transfer_id,
|
|
44926
|
+
};
|
|
44927
|
+
}
|
|
44928
|
+
async function batchTransfer({ signers: { ethSigner, starkSigner }, request, config, }) {
|
|
44929
|
+
await validateChain(ethSigner, config.immutableXConfig);
|
|
44930
|
+
const ethAddress = await ethSigner.getAddress();
|
|
44931
|
+
const transfersApi = new TransfersApi$1(config.immutableXConfig.apiConfiguration);
|
|
44932
|
+
const signableRequests = request.map((nftTransfer) => ({
|
|
44933
|
+
amount: '1',
|
|
44934
|
+
token: convertToSignableToken({
|
|
44935
|
+
type: 'ERC721',
|
|
44936
|
+
tokenId: nftTransfer.tokenId,
|
|
44937
|
+
tokenAddress: nftTransfer.tokenAddress,
|
|
44938
|
+
}),
|
|
44939
|
+
receiver: nftTransfer.receiver,
|
|
44940
|
+
}));
|
|
44941
|
+
const signableResult = await transfersApi.getSignableTransfer({
|
|
44942
|
+
getSignableTransferRequestV2: {
|
|
44943
|
+
sender_ether_key: ethAddress,
|
|
44944
|
+
signable_requests: signableRequests,
|
|
44945
|
+
},
|
|
44946
|
+
});
|
|
44947
|
+
const signableMessage = signableResult.data.signable_message;
|
|
44948
|
+
if (signableMessage === undefined) {
|
|
44949
|
+
throw new Error('Invalid response from Signable registration offchain');
|
|
44950
|
+
}
|
|
44951
|
+
const ethSignature = await signRaw(signableMessage, ethSigner);
|
|
44952
|
+
const requests = [];
|
|
44953
|
+
for (const resp of signableResult.data.signable_responses) {
|
|
44954
|
+
// TODO: remove once fixed
|
|
44955
|
+
// eslint-disable-next-line no-await-in-loop
|
|
44956
|
+
const starkSignature = await starkSigner.signMessage(resp.payload_hash);
|
|
44957
|
+
const req = {
|
|
44958
|
+
sender_vault_id: resp.sender_vault_id,
|
|
44959
|
+
receiver_stark_key: resp.receiver_stark_key,
|
|
44960
|
+
receiver_vault_id: resp.receiver_vault_id,
|
|
44961
|
+
asset_id: resp.asset_id,
|
|
44962
|
+
amount: resp.amount,
|
|
44963
|
+
nonce: resp.nonce,
|
|
44964
|
+
expiration_timestamp: resp.expiration_timestamp,
|
|
44965
|
+
stark_signature: starkSignature,
|
|
45211
44966
|
};
|
|
44967
|
+
requests.push(req);
|
|
45212
44968
|
}
|
|
44969
|
+
// TODO: throw error on missing payload hash?
|
|
44970
|
+
const transferSigningParams = {
|
|
44971
|
+
sender_stark_key: signableResult.data.sender_stark_key,
|
|
44972
|
+
requests,
|
|
44973
|
+
};
|
|
44974
|
+
const response = await transfersApi.createTransfer({
|
|
44975
|
+
createTransferRequestV2: transferSigningParams,
|
|
44976
|
+
xImxEthAddress: ethAddress,
|
|
44977
|
+
xImxEthSignature: ethSignature,
|
|
44978
|
+
});
|
|
44979
|
+
return {
|
|
44980
|
+
transfer_ids: response?.data.transfer_ids,
|
|
44981
|
+
};
|
|
44982
|
+
}
|
|
44983
|
+
|
|
44984
|
+
async function createOrder({ signers, request, config, }) {
|
|
44985
|
+
await validateChain(signers.ethSigner, config.immutableXConfig);
|
|
44986
|
+
const ethAddress = await signers.ethSigner.getAddress();
|
|
44987
|
+
const ordersApi = new OrdersApi$2(config.immutableXConfig.apiConfiguration);
|
|
44988
|
+
const amountSell = request.sell.type === 'ERC721' ? '1' : request.sell.amount;
|
|
44989
|
+
const amountBuy = request.buy.type === 'ERC721' ? '1' : request.buy.amount;
|
|
44990
|
+
const getSignableOrderRequest = {
|
|
44991
|
+
user: ethAddress,
|
|
44992
|
+
amount_buy: amountBuy,
|
|
44993
|
+
token_buy: convertToSignableToken(request.buy),
|
|
44994
|
+
amount_sell: amountSell,
|
|
44995
|
+
token_sell: convertToSignableToken(request.sell),
|
|
44996
|
+
fees: request.fees,
|
|
44997
|
+
expiration_timestamp: request.expiration_timestamp,
|
|
44998
|
+
};
|
|
44999
|
+
const getSignableOrderResponse = await ordersApi.getSignableOrder({
|
|
45000
|
+
getSignableOrderRequestV3: getSignableOrderRequest,
|
|
45001
|
+
});
|
|
45002
|
+
const { signable_message: signableMessage, payload_hash: payloadHash } = getSignableOrderResponse.data;
|
|
45003
|
+
const ethSignature = await signRaw(signableMessage, signers.ethSigner);
|
|
45004
|
+
const starkSignature = await signers.starkSigner.signMessage(payloadHash);
|
|
45005
|
+
const resp = getSignableOrderResponse.data;
|
|
45006
|
+
const orderParams = {
|
|
45007
|
+
createOrderRequest: {
|
|
45008
|
+
amount_buy: resp.amount_buy,
|
|
45009
|
+
amount_sell: resp.amount_sell,
|
|
45010
|
+
asset_id_buy: resp.asset_id_buy,
|
|
45011
|
+
asset_id_sell: resp.asset_id_sell,
|
|
45012
|
+
expiration_timestamp: resp.expiration_timestamp,
|
|
45013
|
+
fees: request.fees,
|
|
45014
|
+
nonce: resp.nonce,
|
|
45015
|
+
stark_key: resp.stark_key,
|
|
45016
|
+
stark_signature: starkSignature,
|
|
45017
|
+
vault_id_buy: resp.vault_id_buy,
|
|
45018
|
+
vault_id_sell: resp.vault_id_sell,
|
|
45019
|
+
},
|
|
45020
|
+
xImxEthAddress: ethAddress,
|
|
45021
|
+
xImxEthSignature: ethSignature,
|
|
45022
|
+
};
|
|
45023
|
+
const createOrderResponse = await ordersApi.createOrderV3(orderParams);
|
|
45213
45024
|
return {
|
|
45214
|
-
|
|
45215
|
-
smartCheckoutResult,
|
|
45025
|
+
...createOrderResponse.data,
|
|
45216
45026
|
};
|
|
45217
|
-
}
|
|
45027
|
+
}
|
|
45028
|
+
async function cancelOrder({ signers, request, config, }) {
|
|
45029
|
+
const ordersApi = new OrdersApi$2(config.immutableXConfig.apiConfiguration);
|
|
45030
|
+
const getSignableCancelOrderResponse = await ordersApi.getSignableCancelOrderV3({
|
|
45031
|
+
getSignableCancelOrderRequest: {
|
|
45032
|
+
order_id: request.order_id,
|
|
45033
|
+
},
|
|
45034
|
+
});
|
|
45035
|
+
const { signable_message: signableMessage, payload_hash: payloadHash } = getSignableCancelOrderResponse.data;
|
|
45036
|
+
const ethSignature = await signRaw(signableMessage, signers.ethSigner);
|
|
45037
|
+
const starkSignature = await signers.starkSigner.signMessage(payloadHash);
|
|
45038
|
+
const ethAddress = await signers.ethSigner.getAddress();
|
|
45039
|
+
const cancelOrderResponse = await ordersApi.cancelOrderV3({
|
|
45040
|
+
id: request.order_id.toString(),
|
|
45041
|
+
cancelOrderRequest: {
|
|
45042
|
+
order_id: request.order_id,
|
|
45043
|
+
stark_signature: starkSignature,
|
|
45044
|
+
},
|
|
45045
|
+
xImxEthAddress: ethAddress,
|
|
45046
|
+
xImxEthSignature: ethSignature,
|
|
45047
|
+
});
|
|
45048
|
+
return {
|
|
45049
|
+
order_id: cancelOrderResponse.data.order_id,
|
|
45050
|
+
status: cancelOrderResponse.data.status,
|
|
45051
|
+
};
|
|
45052
|
+
}
|
|
45218
45053
|
|
|
45219
|
-
|
|
45220
|
-
|
|
45221
|
-
|
|
45222
|
-
|
|
45223
|
-
|
|
45224
|
-
|
|
45225
|
-
|
|
45226
|
-
|
|
45227
|
-
|
|
45054
|
+
async function registerOffchain(signers, config) {
|
|
45055
|
+
await validateChain(signers.ethSigner, config.immutableXConfig);
|
|
45056
|
+
const usersApi = new UsersApi$1(config.immutableXConfig.apiConfiguration);
|
|
45057
|
+
const userAddress = await signers.ethSigner.getAddress();
|
|
45058
|
+
const starkPublicKey = await signers.starkSigner.getAddress();
|
|
45059
|
+
const signableResult = await usersApi.getSignableRegistrationOffchain({
|
|
45060
|
+
getSignableRegistrationRequest: {
|
|
45061
|
+
ether_key: userAddress,
|
|
45062
|
+
stark_key: starkPublicKey,
|
|
45063
|
+
},
|
|
45064
|
+
});
|
|
45065
|
+
const { signable_message: signableMessage, payload_hash: payloadHash } = signableResult.data;
|
|
45066
|
+
const ethSignature = await signRaw(signableMessage, signers.ethSigner);
|
|
45067
|
+
const starkSignature = await signers.starkSigner.signMessage(payloadHash);
|
|
45068
|
+
const registeredUser = await usersApi.registerUser({
|
|
45069
|
+
registerUserRequest: {
|
|
45070
|
+
eth_signature: ethSignature,
|
|
45071
|
+
ether_key: userAddress,
|
|
45072
|
+
stark_signature: starkSignature,
|
|
45073
|
+
stark_key: starkPublicKey,
|
|
45074
|
+
},
|
|
45075
|
+
});
|
|
45076
|
+
return registeredUser.data;
|
|
45077
|
+
}
|
|
45078
|
+
async function isRegisteredOffchain(ethAddress, config) {
|
|
45228
45079
|
try {
|
|
45229
|
-
const
|
|
45230
|
-
const
|
|
45231
|
-
|
|
45232
|
-
unsignedCancelOrderTransaction = await cancelOrderResponse.cancellationAction.buildTransaction();
|
|
45233
|
-
}
|
|
45234
|
-
catch (err) {
|
|
45235
|
-
throw new CheckoutError('An error occurred while cancelling the order listing', CheckoutErrorType.CANCEL_ORDER_LISTING_ERROR, {
|
|
45236
|
-
orderId,
|
|
45237
|
-
error: err,
|
|
45080
|
+
const usersApi = new UsersApi$1(config.immutableXConfig.apiConfiguration);
|
|
45081
|
+
const getUsersResult = await usersApi.getUsers({
|
|
45082
|
+
user: ethAddress,
|
|
45238
45083
|
});
|
|
45084
|
+
const { accounts } = getUsersResult.data;
|
|
45085
|
+
return accounts?.length > 0;
|
|
45239
45086
|
}
|
|
45240
|
-
|
|
45241
|
-
|
|
45242
|
-
|
|
45243
|
-
return {
|
|
45244
|
-
status: CheckoutStatus.FAILED,
|
|
45245
|
-
transactionHash: result.transactionHash,
|
|
45246
|
-
reason: result.reason,
|
|
45247
|
-
};
|
|
45087
|
+
catch (ex) {
|
|
45088
|
+
if (ex instanceof AxiosError$2 && ex.response?.status === 404) {
|
|
45089
|
+
return false;
|
|
45248
45090
|
}
|
|
45249
|
-
|
|
45250
|
-
status: CheckoutStatus.SUCCESS,
|
|
45251
|
-
};
|
|
45091
|
+
throw ex;
|
|
45252
45092
|
}
|
|
45253
|
-
|
|
45093
|
+
}
|
|
45094
|
+
async function isRegisteredOnChain(starkPublicKey, ethSigner, config) {
|
|
45095
|
+
await validateChain(ethSigner, config.immutableXConfig);
|
|
45096
|
+
const registrationContract = Contracts.Registration.connect(config.immutableXConfig.ethConfiguration.registrationContractAddress, ethSigner);
|
|
45254
45097
|
try {
|
|
45255
|
-
|
|
45256
|
-
transactions = response.map((result) => result.transactionResponse);
|
|
45098
|
+
return await registrationContract.isRegistered(starkPublicKey);
|
|
45257
45099
|
}
|
|
45258
|
-
catch (
|
|
45259
|
-
|
|
45260
|
-
|
|
45261
|
-
}
|
|
45100
|
+
catch (ex) {
|
|
45101
|
+
if (ex.reason === 'USER_UNREGISTERED') {
|
|
45102
|
+
return false;
|
|
45103
|
+
}
|
|
45104
|
+
throw ex;
|
|
45262
45105
|
}
|
|
45106
|
+
}
|
|
45107
|
+
async function getSignableRegistrationOnchain(etherKey, starkPublicKey, usersApi) {
|
|
45108
|
+
const response = await usersApi.getSignableRegistration({
|
|
45109
|
+
getSignableRegistrationRequest: {
|
|
45110
|
+
ether_key: etherKey,
|
|
45111
|
+
stark_key: starkPublicKey,
|
|
45112
|
+
},
|
|
45113
|
+
});
|
|
45263
45114
|
return {
|
|
45264
|
-
|
|
45265
|
-
|
|
45115
|
+
operator_signature: response.data.operator_signature,
|
|
45116
|
+
payload_hash: response.data.payload_hash,
|
|
45117
|
+
readable_transaction: response.data.readable_transaction,
|
|
45118
|
+
verification_signature: response.data.verification_signature,
|
|
45266
45119
|
};
|
|
45267
|
-
}
|
|
45120
|
+
}
|
|
45268
45121
|
|
|
45269
|
-
const
|
|
45270
|
-
|
|
45271
|
-
|
|
45272
|
-
|
|
45273
|
-
spenderAddress,
|
|
45274
|
-
});
|
|
45275
|
-
const getBuyToken = (buyToken, decimals = 18) => {
|
|
45276
|
-
const bnAmount = utils$3.parseUnits(buyToken.amount, decimals);
|
|
45277
|
-
if (buyToken.type === ItemType.NATIVE) {
|
|
45278
|
-
return {
|
|
45279
|
-
type: ItemType.NATIVE,
|
|
45280
|
-
amount: bnAmount.toString(),
|
|
45281
|
-
};
|
|
45282
|
-
}
|
|
45283
|
-
return {
|
|
45284
|
-
type: ItemType.ERC20,
|
|
45285
|
-
amount: bnAmount.toString(),
|
|
45286
|
-
contractAddress: buyToken.tokenAddress,
|
|
45287
|
-
};
|
|
45122
|
+
const assertIsDefined = (value) => {
|
|
45123
|
+
if (value !== undefined)
|
|
45124
|
+
return value;
|
|
45125
|
+
throw new Error('undefined field exception');
|
|
45288
45126
|
};
|
|
45289
|
-
|
|
45290
|
-
|
|
45291
|
-
|
|
45292
|
-
|
|
45293
|
-
|
|
45294
|
-
|
|
45295
|
-
|
|
45296
|
-
|
|
45297
|
-
|
|
45298
|
-
|
|
45299
|
-
|
|
45300
|
-
|
|
45301
|
-
|
|
45302
|
-
|
|
45303
|
-
const
|
|
45304
|
-
|
|
45305
|
-
|
|
45306
|
-
|
|
45307
|
-
|
|
45308
|
-
|
|
45309
|
-
|
|
45310
|
-
|
|
45311
|
-
|
|
45312
|
-
|
|
45313
|
-
|
|
45314
|
-
|
|
45315
|
-
|
|
45127
|
+
async function prepareWithdrawalAction(params) {
|
|
45128
|
+
const { signers: { ethSigner, starkSigner }, type, config, } = params;
|
|
45129
|
+
await validateChain(ethSigner, params.config);
|
|
45130
|
+
const withdrawalsApi = new WithdrawalsApi$1(config.apiConfiguration);
|
|
45131
|
+
const withdrawalAmount = type === 'ERC721' ? '1' : params.amount;
|
|
45132
|
+
const signableWithdrawalResult = await withdrawalsApi.getSignableWithdrawal({
|
|
45133
|
+
getSignableWithdrawalRequest: {
|
|
45134
|
+
user: await ethSigner.getAddress(),
|
|
45135
|
+
token: convertToSignableToken(params),
|
|
45136
|
+
amount: withdrawalAmount,
|
|
45137
|
+
},
|
|
45138
|
+
});
|
|
45139
|
+
const { signable_message: signableMessage, payload_hash: payloadHash } = signableWithdrawalResult.data;
|
|
45140
|
+
const starkSignature = await starkSigner.signMessage(payloadHash);
|
|
45141
|
+
const { ethAddress, ethSignature } = await signMessage$1(signableMessage, ethSigner);
|
|
45142
|
+
const prepareWithdrawalResponse = await withdrawalsApi.createWithdrawal({
|
|
45143
|
+
createWithdrawalRequest: {
|
|
45144
|
+
stark_key: assertIsDefined(signableWithdrawalResult.data.stark_key),
|
|
45145
|
+
amount: withdrawalAmount,
|
|
45146
|
+
asset_id: assertIsDefined(signableWithdrawalResult.data.asset_id),
|
|
45147
|
+
vault_id: assertIsDefined(signableWithdrawalResult.data.vault_id),
|
|
45148
|
+
nonce: assertIsDefined(signableWithdrawalResult.data.nonce),
|
|
45149
|
+
stark_signature: starkSignature,
|
|
45150
|
+
},
|
|
45151
|
+
xImxEthAddress: ethAddress,
|
|
45152
|
+
xImxEthSignature: ethSignature,
|
|
45153
|
+
});
|
|
45154
|
+
return prepareWithdrawalResponse.data;
|
|
45155
|
+
}
|
|
45156
|
+
|
|
45157
|
+
async function getEncodeAssetInfo(assetType, tokenType, config, tokenData) {
|
|
45158
|
+
const encodingApi = new EncodingApi$1(config.apiConfiguration);
|
|
45159
|
+
const result = await encodingApi.encodeAsset({
|
|
45160
|
+
assetType,
|
|
45161
|
+
encodeAssetRequest: {
|
|
45162
|
+
token: {
|
|
45163
|
+
type: tokenType,
|
|
45164
|
+
...(tokenData && { data: tokenData }),
|
|
45316
45165
|
},
|
|
45317
|
-
orderExpiry,
|
|
45318
|
-
}));
|
|
45319
|
-
}
|
|
45320
|
-
catch (err) {
|
|
45321
|
-
throw new CheckoutError('An error occurred while preparing the listing', CheckoutErrorType.PREPARE_ORDER_LISTING_ERROR, {
|
|
45322
|
-
error: err,
|
|
45323
|
-
id: sellToken.id,
|
|
45324
|
-
collectionAddress: sellToken.collectionAddress,
|
|
45325
|
-
});
|
|
45326
|
-
}
|
|
45327
|
-
const itemRequirements = [
|
|
45328
|
-
getERC721Requirement(sellToken.id, sellToken.collectionAddress, spenderAddress),
|
|
45329
|
-
];
|
|
45330
|
-
const smartCheckoutResult = await measureAsyncExecution(config, 'Total time running smart checkout', smartCheckout(config, provider, itemRequirements, {
|
|
45331
|
-
type: TransactionOrGasType.GAS,
|
|
45332
|
-
gasToken: {
|
|
45333
|
-
type: GasTokenType.NATIVE,
|
|
45334
|
-
limit: BigNumber$1.from(constants.estimatedFulfillmentGasGwei),
|
|
45335
45166
|
},
|
|
45336
|
-
})
|
|
45337
|
-
|
|
45338
|
-
|
|
45339
|
-
const approvalResult = await signApprovalTransactions(provider, unsignedTransactions.approvalTransactions);
|
|
45340
|
-
if (approvalResult.type === SignTransactionStatusType.FAILED) {
|
|
45341
|
-
return {
|
|
45342
|
-
status: CheckoutStatus.FAILED,
|
|
45343
|
-
transactionHash: approvalResult.transactionHash,
|
|
45344
|
-
reason: approvalResult.reason,
|
|
45345
|
-
smartCheckoutResult,
|
|
45346
|
-
};
|
|
45347
|
-
}
|
|
45348
|
-
const unsignedMessage = getUnsignedMessage(listing.orderHash, listing.orderComponents, listing.actions);
|
|
45349
|
-
if (!unsignedMessage) {
|
|
45350
|
-
// For sell it is expected the orderbook will always return an unsigned message
|
|
45351
|
-
// If for some reason it is missing then we cannot proceed with the create listing
|
|
45352
|
-
throw new CheckoutError('The unsigned message is missing after preparing the listing', CheckoutErrorType.SIGN_MESSAGE_ERROR, {
|
|
45353
|
-
id: sellToken.id,
|
|
45354
|
-
collectionAddress: sellToken.collectionAddress,
|
|
45355
|
-
});
|
|
45356
|
-
}
|
|
45357
|
-
const signedMessage = await signMessage(provider, unsignedMessage);
|
|
45358
|
-
let orderId = '';
|
|
45359
|
-
const createListingParams = {
|
|
45360
|
-
orderComponents: signedMessage.orderComponents,
|
|
45361
|
-
orderHash: signedMessage.orderHash,
|
|
45362
|
-
orderSignature: signedMessage.signedMessage,
|
|
45363
|
-
makerFees: [],
|
|
45364
|
-
};
|
|
45365
|
-
if (makerFees !== undefined) {
|
|
45366
|
-
const orderBookFees = calculateFees(makerFees, buyTokenOrNative.amount, decimals);
|
|
45367
|
-
if (orderBookFees.length !== makerFees.length) {
|
|
45368
|
-
throw new CheckoutError('One of the fees is too small, must be greater than 0.000001', CheckoutErrorType.CREATE_ORDER_LISTING_ERROR);
|
|
45369
|
-
}
|
|
45370
|
-
createListingParams.makerFees = orderBookFees;
|
|
45371
|
-
}
|
|
45372
|
-
try {
|
|
45373
|
-
const order = await orderbook.createListing(createListingParams);
|
|
45374
|
-
orderId = order.result.id;
|
|
45375
|
-
}
|
|
45376
|
-
catch (err) {
|
|
45377
|
-
throw new CheckoutError('An error occurred while creating the listing', CheckoutErrorType.CREATE_ORDER_LISTING_ERROR, {
|
|
45378
|
-
error: err,
|
|
45379
|
-
collectionId: sellToken.id,
|
|
45380
|
-
collectionAddress: sellToken.collectionAddress,
|
|
45381
|
-
});
|
|
45382
|
-
}
|
|
45383
|
-
return {
|
|
45384
|
-
status: CheckoutStatus.SUCCESS,
|
|
45385
|
-
orderIds: [orderId],
|
|
45386
|
-
smartCheckoutResult,
|
|
45387
|
-
};
|
|
45388
|
-
}
|
|
45389
|
-
return {
|
|
45390
|
-
status: CheckoutStatus.INSUFFICIENT_FUNDS,
|
|
45391
|
-
smartCheckoutResult,
|
|
45392
|
-
};
|
|
45393
|
-
};
|
|
45167
|
+
});
|
|
45168
|
+
return result.data;
|
|
45169
|
+
}
|
|
45394
45170
|
|
|
45395
|
-
|
|
45396
|
-
|
|
45397
|
-
|
|
45398
|
-
|
|
45399
|
-
|
|
45400
|
-
|
|
45401
|
-
|
|
45402
|
-
|
|
45171
|
+
async function executeRegisterAndWithdrawERC20({ ethSigner, assetType, starkPublicKey, config, }) {
|
|
45172
|
+
const etherKey = await ethSigner.getAddress();
|
|
45173
|
+
const imxConfig = config.immutableXConfig;
|
|
45174
|
+
const usersApi = new UsersApi$1(imxConfig.apiConfiguration);
|
|
45175
|
+
const signableResult = await getSignableRegistrationOnchain(etherKey, starkPublicKey, usersApi);
|
|
45176
|
+
const contract = Contracts.Registration.connect(config.immutableXConfig.ethConfiguration.registrationContractAddress, ethSigner);
|
|
45177
|
+
const populatedTransaction = await contract.populateTransaction.registerAndWithdraw(etherKey, starkPublicKey, signableResult.operator_signature, assetType);
|
|
45178
|
+
return ethSigner.sendTransaction(populatedTransaction);
|
|
45179
|
+
}
|
|
45180
|
+
async function executeWithdrawERC20(ethSigner, assetType, starkPublicKey, config) {
|
|
45181
|
+
const contract = Contracts.Core.connect(config.ethConfiguration.coreContractAddress, ethSigner);
|
|
45182
|
+
const populatedTransaction = await contract.populateTransaction.withdraw(starkPublicKey, assetType);
|
|
45183
|
+
return ethSigner.sendTransaction(populatedTransaction);
|
|
45184
|
+
}
|
|
45185
|
+
async function completeERC20WithdrawalAction({ ethSigner, starkPublicKey, token, config, }) {
|
|
45186
|
+
await validateChain(ethSigner, config.immutableXConfig);
|
|
45187
|
+
const imxConfig = config.immutableXConfig;
|
|
45188
|
+
const assetType = await getEncodeAssetInfo('asset', 'ERC20', imxConfig, {
|
|
45189
|
+
token_address: token.tokenAddress,
|
|
45190
|
+
});
|
|
45191
|
+
const isRegistered = await isRegisteredOnChain(starkPublicKey, ethSigner, config);
|
|
45192
|
+
if (!isRegistered) {
|
|
45193
|
+
return executeRegisterAndWithdrawERC20({
|
|
45194
|
+
ethSigner,
|
|
45195
|
+
assetType: assetType.asset_type,
|
|
45196
|
+
starkPublicKey,
|
|
45197
|
+
config,
|
|
45198
|
+
});
|
|
45403
45199
|
}
|
|
45404
|
-
|
|
45405
|
-
|
|
45406
|
-
|
|
45200
|
+
return executeWithdrawERC20(ethSigner, assetType.asset_type, starkPublicKey, imxConfig);
|
|
45201
|
+
}
|
|
45202
|
+
|
|
45203
|
+
async function executeWithdrawMintableERC721(ethSigner, assetType, starkPublicKey, mintingBlob, config) {
|
|
45204
|
+
const contract = Contracts.Core.connect(config.ethConfiguration.coreContractAddress, ethSigner);
|
|
45205
|
+
const populatedTransaction = await contract.populateTransaction.withdrawAndMint(starkPublicKey, assetType, mintingBlob);
|
|
45206
|
+
return ethSigner.sendTransaction(populatedTransaction);
|
|
45207
|
+
}
|
|
45208
|
+
async function executeRegisterAndWithdrawMintableERC721(ethSigner, assetType, starkPublicKey, mintingBlob, config) {
|
|
45209
|
+
const etherKey = await ethSigner.getAddress();
|
|
45210
|
+
const usersApi = new UsersApi$1(config.apiConfiguration);
|
|
45211
|
+
const signableResult = await getSignableRegistrationOnchain(etherKey, starkPublicKey, usersApi);
|
|
45212
|
+
const contract = Contracts.Registration.connect(config.ethConfiguration.registrationContractAddress, ethSigner);
|
|
45213
|
+
const populatedTransaction = await contract.populateTransaction.regsiterAndWithdrawAndMint(etherKey, starkPublicKey, signableResult.operator_signature, assetType, mintingBlob);
|
|
45214
|
+
return ethSigner.sendTransaction(populatedTransaction);
|
|
45215
|
+
}
|
|
45216
|
+
function getMintingBlob(token) {
|
|
45217
|
+
const { id } = token.data;
|
|
45218
|
+
const blueprint = token.data.blueprint || '';
|
|
45219
|
+
return encUtils.sanitizeHex(encUtils.utf8ToHex(`{${id}}:{${blueprint}}`));
|
|
45220
|
+
}
|
|
45221
|
+
async function completeMintableERC721Withdrawal(ethSigner, starkPublicKey, token, config) {
|
|
45222
|
+
const imxConfig = config.immutableXConfig;
|
|
45223
|
+
const assetType = await getEncodeAssetInfo('mintable-asset', 'ERC721', imxConfig, {
|
|
45224
|
+
id: token.data.id,
|
|
45225
|
+
token_address: token.data.tokenAddress,
|
|
45226
|
+
...(token.data.blueprint && { blueprint: token.data.blueprint }),
|
|
45227
|
+
});
|
|
45228
|
+
const mintingBlob = getMintingBlob(token);
|
|
45229
|
+
const isRegistered = await isRegisteredOnChain(starkPublicKey, ethSigner, config);
|
|
45230
|
+
if (!isRegistered) {
|
|
45231
|
+
return executeRegisterAndWithdrawMintableERC721(ethSigner, assetType.asset_type, starkPublicKey, mintingBlob, imxConfig);
|
|
45407
45232
|
}
|
|
45408
|
-
|
|
45409
|
-
|
|
45233
|
+
return executeWithdrawMintableERC721(ethSigner, assetType.asset_type, starkPublicKey, mintingBlob, imxConfig);
|
|
45234
|
+
}
|
|
45235
|
+
async function executeRegisterAndWithdrawERC721(ethSigner, assetType, starkPublicKey, tokenId, config) {
|
|
45236
|
+
const etherKey = await ethSigner.getAddress();
|
|
45237
|
+
const usersApi = new UsersApi$1(config.apiConfiguration);
|
|
45238
|
+
const signableResult = await getSignableRegistrationOnchain(etherKey, starkPublicKey, usersApi);
|
|
45239
|
+
const contract = Contracts.Registration.connect(config.ethConfiguration.registrationContractAddress, ethSigner);
|
|
45240
|
+
const populatedTransaction = await contract.populateTransaction.registerAndWithdrawNft(etherKey, starkPublicKey, signableResult.operator_signature, assetType, tokenId);
|
|
45241
|
+
return ethSigner.sendTransaction(populatedTransaction);
|
|
45242
|
+
}
|
|
45243
|
+
async function executeWithdrawERC721(ethSigner, assetType, starkPublicKey, tokenId, config) {
|
|
45244
|
+
const contract = Contracts.Core.connect(config.ethConfiguration.coreContractAddress, ethSigner);
|
|
45245
|
+
const populatedTransaction = await contract.populateTransaction.withdrawNft(starkPublicKey, assetType, tokenId);
|
|
45246
|
+
return ethSigner.sendTransaction(populatedTransaction);
|
|
45247
|
+
}
|
|
45248
|
+
async function completeERC721Withdrawal(ethSigner, starkPublicKey, token, config) {
|
|
45249
|
+
const imxConfig = config.immutableXConfig;
|
|
45250
|
+
const assetType = await getEncodeAssetInfo('asset', 'ERC721', imxConfig, {
|
|
45251
|
+
token_id: token.tokenId,
|
|
45252
|
+
token_address: token.tokenAddress,
|
|
45253
|
+
});
|
|
45254
|
+
const isRegistered = await isRegisteredOnChain(starkPublicKey, ethSigner, config);
|
|
45255
|
+
if (!isRegistered) {
|
|
45256
|
+
return executeRegisterAndWithdrawERC721(ethSigner, assetType.asset_type, starkPublicKey, token.tokenId, imxConfig);
|
|
45410
45257
|
}
|
|
45411
|
-
|
|
45412
|
-
|
|
45413
|
-
|
|
45414
|
-
|
|
45415
|
-
|
|
45416
|
-
|
|
45417
|
-
|
|
45418
|
-
|
|
45419
|
-
|
|
45420
|
-
|
|
45421
|
-
|
|
45422
|
-
|
|
45423
|
-
|
|
45424
|
-
|
|
45425
|
-
|
|
45426
|
-
|
|
45427
|
-
|
|
45428
|
-
|
|
45429
|
-
|
|
45430
|
-
|
|
45431
|
-
|
|
45432
|
-
|
|
45433
|
-
|
|
45434
|
-
|
|
45435
|
-
|
|
45436
|
-
widgetUrl += `&defaultCryptoAmount=${params.tokenAmount}&cryptoCurrencyCode=${params.tokenSymbol}`;
|
|
45437
|
-
}
|
|
45438
|
-
else {
|
|
45439
|
-
widgetUrl += '&defaultCryptoCurrency=IMX';
|
|
45440
|
-
}
|
|
45441
|
-
if (params.walletAddress) {
|
|
45442
|
-
widgetUrl += `&walletAddress=${params.walletAddress}`;
|
|
45258
|
+
return executeWithdrawERC721(ethSigner, assetType.asset_type, starkPublicKey, token.tokenId, imxConfig);
|
|
45259
|
+
}
|
|
45260
|
+
async function completeERC721WithdrawalAction({ ethSigner, starkPublicKey, token, config, }) {
|
|
45261
|
+
await validateChain(ethSigner, config.immutableXConfig);
|
|
45262
|
+
const { tokenAddress } = token;
|
|
45263
|
+
const { tokenId } = token;
|
|
45264
|
+
const imxConfig = config.immutableXConfig;
|
|
45265
|
+
const mintsApi = new MintsApi$1(imxConfig.apiConfiguration);
|
|
45266
|
+
return await mintsApi
|
|
45267
|
+
.getMintableTokenDetailsByClientTokenId({
|
|
45268
|
+
tokenAddress,
|
|
45269
|
+
tokenId,
|
|
45270
|
+
})
|
|
45271
|
+
.then((mintableToken) => completeMintableERC721Withdrawal(ethSigner, starkPublicKey, {
|
|
45272
|
+
type: 'ERC721',
|
|
45273
|
+
data: {
|
|
45274
|
+
id: tokenId,
|
|
45275
|
+
tokenAddress,
|
|
45276
|
+
blueprint: mintableToken.data.blueprint,
|
|
45277
|
+
},
|
|
45278
|
+
}, config))
|
|
45279
|
+
.catch((error) => {
|
|
45280
|
+
if (error.response?.status === 404) {
|
|
45281
|
+
// token is already minted on L1
|
|
45282
|
+
return completeERC721Withdrawal(ethSigner, starkPublicKey, token, config);
|
|
45443
45283
|
}
|
|
45444
|
-
|
|
45284
|
+
throw error; // unable to recover from any other kind of error
|
|
45285
|
+
});
|
|
45286
|
+
}
|
|
45287
|
+
|
|
45288
|
+
async function executeRegisterAndWithdrawEth(ethSigner, assetType, starkPublicKey, config) {
|
|
45289
|
+
const etherKey = await ethSigner.getAddress();
|
|
45290
|
+
const usersApi = new UsersApi$1(config.apiConfiguration);
|
|
45291
|
+
const signableResult = await getSignableRegistrationOnchain(etherKey, starkPublicKey, usersApi);
|
|
45292
|
+
const contract = Contracts.Registration.connect(config.ethConfiguration.registrationContractAddress, ethSigner);
|
|
45293
|
+
const populatedTransaction = await contract.populateTransaction.registerAndWithdraw(etherKey, starkPublicKey, signableResult.operator_signature, assetType);
|
|
45294
|
+
return ethSigner.sendTransaction(populatedTransaction);
|
|
45295
|
+
}
|
|
45296
|
+
async function executeWithdrawEth(ethSigner, assetType, starkPublicKey, config) {
|
|
45297
|
+
const contract = Contracts.Core.connect(config.ethConfiguration.coreContractAddress, ethSigner);
|
|
45298
|
+
const populatedTransaction = await contract.populateTransaction.withdraw(starkPublicKey, assetType);
|
|
45299
|
+
return ethSigner.sendTransaction(populatedTransaction);
|
|
45300
|
+
}
|
|
45301
|
+
async function completeEthWithdrawalAction({ ethSigner, starkPublicKey, config, }) {
|
|
45302
|
+
await validateChain(ethSigner, config.immutableXConfig);
|
|
45303
|
+
const imxConfig = config.immutableXConfig;
|
|
45304
|
+
const assetType = await getEncodeAssetInfo('asset', 'ETH', imxConfig);
|
|
45305
|
+
const isRegistered = await isRegisteredOnChain(starkPublicKey, ethSigner, config);
|
|
45306
|
+
if (!isRegistered) {
|
|
45307
|
+
return executeRegisterAndWithdrawEth(ethSigner, assetType.asset_type, starkPublicKey, imxConfig);
|
|
45308
|
+
}
|
|
45309
|
+
return executeWithdrawEth(ethSigner, assetType.asset_type, starkPublicKey, imxConfig);
|
|
45310
|
+
}
|
|
45311
|
+
|
|
45312
|
+
async function prepareWithdrawal({ signers, withdrawal, config, }) {
|
|
45313
|
+
return prepareWithdrawalAction({
|
|
45314
|
+
signers,
|
|
45315
|
+
config: config.immutableXConfig,
|
|
45316
|
+
...withdrawal,
|
|
45317
|
+
});
|
|
45318
|
+
}
|
|
45319
|
+
// TODO: remove once fixed
|
|
45320
|
+
// eslint-disable-next-line consistent-return
|
|
45321
|
+
async function completeWithdrawal({ signers: { ethSigner }, starkPublicKey, token, config, }) {
|
|
45322
|
+
// TODO: please add a reasonable default here
|
|
45323
|
+
// eslint-disable-next-line default-case
|
|
45324
|
+
switch (token.type) {
|
|
45325
|
+
case 'ETH':
|
|
45326
|
+
return completeEthWithdrawalAction({ ethSigner, starkPublicKey, config });
|
|
45327
|
+
case 'ERC20':
|
|
45328
|
+
return completeERC20WithdrawalAction({
|
|
45329
|
+
ethSigner,
|
|
45330
|
+
starkPublicKey,
|
|
45331
|
+
token,
|
|
45332
|
+
config,
|
|
45333
|
+
});
|
|
45334
|
+
case 'ERC721':
|
|
45335
|
+
return completeERC721WithdrawalAction({
|
|
45336
|
+
ethSigner,
|
|
45337
|
+
starkPublicKey,
|
|
45338
|
+
token,
|
|
45339
|
+
config,
|
|
45340
|
+
});
|
|
45445
45341
|
}
|
|
45446
45342
|
}
|
|
45447
45343
|
|
|
45448
|
-
async function
|
|
45449
|
-
|
|
45450
|
-
const
|
|
45451
|
-
|
|
45452
|
-
|
|
45453
|
-
|
|
45454
|
-
|
|
45455
|
-
|
|
45344
|
+
async function createTrade({ signers: { ethSigner, starkSigner }, request, config, }) {
|
|
45345
|
+
await validateChain(ethSigner, config.immutableXConfig);
|
|
45346
|
+
const ethAddress = await ethSigner.getAddress();
|
|
45347
|
+
const tradesApi = new TradesApi$1(config.immutableXConfig.apiConfiguration);
|
|
45348
|
+
const signableResult = await tradesApi.getSignableTrade({
|
|
45349
|
+
getSignableTradeRequest: {
|
|
45350
|
+
user: ethAddress,
|
|
45351
|
+
order_id: request.order_id,
|
|
45352
|
+
fees: request.fees,
|
|
45353
|
+
},
|
|
45456
45354
|
});
|
|
45457
|
-
const
|
|
45458
|
-
|
|
45459
|
-
const
|
|
45460
|
-
|
|
45461
|
-
|
|
45462
|
-
|
|
45463
|
-
|
|
45464
|
-
|
|
45465
|
-
|
|
45466
|
-
|
|
45467
|
-
|
|
45468
|
-
|
|
45469
|
-
|
|
45470
|
-
|
|
45471
|
-
|
|
45472
|
-
|
|
45355
|
+
const { signable_message: signableMessage, payload_hash: payloadHash } = signableResult.data;
|
|
45356
|
+
const ethSignature = await signRaw(signableMessage, ethSigner);
|
|
45357
|
+
const starkSignature = await starkSigner.signMessage(payloadHash);
|
|
45358
|
+
const createTradeResponse = await tradesApi.createTradeV3({
|
|
45359
|
+
createTradeRequest: {
|
|
45360
|
+
amount_buy: signableResult.data.amount_buy,
|
|
45361
|
+
amount_sell: signableResult.data.amount_sell,
|
|
45362
|
+
asset_id_buy: signableResult.data.asset_id_buy,
|
|
45363
|
+
asset_id_sell: signableResult.data.asset_id_sell,
|
|
45364
|
+
expiration_timestamp: signableResult.data.expiration_timestamp,
|
|
45365
|
+
fee_info: signableResult.data.fee_info,
|
|
45366
|
+
fees: request.fees,
|
|
45367
|
+
include_fees: true,
|
|
45368
|
+
nonce: signableResult.data.nonce,
|
|
45369
|
+
order_id: request.order_id,
|
|
45370
|
+
stark_key: signableResult.data.stark_key,
|
|
45371
|
+
vault_id_buy: signableResult.data.vault_id_buy,
|
|
45372
|
+
vault_id_sell: signableResult.data.vault_id_sell,
|
|
45373
|
+
stark_signature: starkSignature,
|
|
45374
|
+
},
|
|
45375
|
+
xImxEthAddress: ethAddress,
|
|
45376
|
+
xImxEthSignature: ethSignature,
|
|
45473
45377
|
});
|
|
45474
|
-
return
|
|
45378
|
+
return createTradeResponse.data;
|
|
45475
45379
|
}
|
|
45476
45380
|
|
|
45477
|
-
|
|
45478
|
-
|
|
45479
|
-
|
|
45480
|
-
|
|
45481
|
-
|
|
45482
|
-
|
|
45483
|
-
|
|
45484
|
-
|
|
45485
|
-
|
|
45486
|
-
|
|
45487
|
-
|
|
45488
|
-
|
|
45489
|
-
|
|
45490
|
-
|
|
45491
|
-
|
|
45492
|
-
|
|
45493
|
-
|
|
45494
|
-
|
|
45495
|
-
|
|
45496
|
-
|
|
45497
|
-
|
|
45498
|
-
|
|
45499
|
-
|
|
45500
|
-
|
|
45501
|
-
|
|
45502
|
-
|
|
45503
|
-
|
|
45504
|
-
|
|
45505
|
-
|
|
45381
|
+
async function executeRegisterAndDepositEth(ethSigner, amount, assetType, starkPublicKey, vaultId, config, usersApi) {
|
|
45382
|
+
const etherKey = await ethSigner.getAddress();
|
|
45383
|
+
const coreContract = Contracts.Core.connect(config.ethConfiguration.coreContractAddress, ethSigner);
|
|
45384
|
+
const signableResult = await getSignableRegistrationOnchain(etherKey, starkPublicKey, usersApi);
|
|
45385
|
+
const populatedTransaction = await coreContract.populateTransaction.registerAndDepositEth(etherKey, starkPublicKey, signableResult.operator_signature, assetType, vaultId);
|
|
45386
|
+
return ethSigner.sendTransaction({ ...populatedTransaction, value: amount });
|
|
45387
|
+
}
|
|
45388
|
+
async function executeDepositEth(ethSigner, amount, assetType, starkPublicKey, vaultId, config) {
|
|
45389
|
+
const coreContract = Contracts.Core.connect(config.ethConfiguration.coreContractAddress, ethSigner);
|
|
45390
|
+
const populatedTransaction = await coreContract.populateTransaction['deposit(uint256,uint256,uint256)'](starkPublicKey, assetType, vaultId);
|
|
45391
|
+
return ethSigner.sendTransaction({ ...populatedTransaction, value: amount });
|
|
45392
|
+
}
|
|
45393
|
+
async function depositEth({ signers: { ethSigner }, deposit, config, }) {
|
|
45394
|
+
await validateChain(ethSigner, config.immutableXConfig);
|
|
45395
|
+
const user = await ethSigner.getAddress();
|
|
45396
|
+
const data = {
|
|
45397
|
+
decimals: 18,
|
|
45398
|
+
};
|
|
45399
|
+
const amount = parseUnits(deposit.amount, 'wei');
|
|
45400
|
+
const imxConfig = config.immutableXConfig;
|
|
45401
|
+
const depositsApi = new DepositsApi$1(imxConfig.apiConfiguration);
|
|
45402
|
+
const encodingApi = new EncodingApi$1(imxConfig.apiConfiguration);
|
|
45403
|
+
const usersApi = new UsersApi$1(imxConfig.apiConfiguration);
|
|
45404
|
+
const getSignableDepositRequest = {
|
|
45405
|
+
user,
|
|
45406
|
+
token: {
|
|
45407
|
+
type: deposit.type,
|
|
45408
|
+
data,
|
|
45409
|
+
},
|
|
45410
|
+
amount: amount.toString(),
|
|
45411
|
+
};
|
|
45412
|
+
const signableDepositResult = await depositsApi.getSignableDeposit({
|
|
45413
|
+
getSignableDepositRequest,
|
|
45414
|
+
});
|
|
45415
|
+
const encodingResult = await encodingApi.encodeAsset({
|
|
45416
|
+
assetType: 'asset',
|
|
45417
|
+
encodeAssetRequest: {
|
|
45418
|
+
token: {
|
|
45419
|
+
type: deposit.type,
|
|
45420
|
+
},
|
|
45421
|
+
},
|
|
45422
|
+
});
|
|
45423
|
+
const assetType = encodingResult.data.asset_type;
|
|
45424
|
+
const starkPublicKey = signableDepositResult.data.stark_key;
|
|
45425
|
+
const vaultId = signableDepositResult.data.vault_id;
|
|
45426
|
+
const isRegistered = await isRegisteredOnChain(starkPublicKey, ethSigner, config);
|
|
45427
|
+
if (!isRegistered) {
|
|
45428
|
+
return executeRegisterAndDepositEth(ethSigner, amount, assetType, starkPublicKey, vaultId, imxConfig, usersApi);
|
|
45506
45429
|
}
|
|
45507
|
-
|
|
45508
|
-
|
|
45509
|
-
|
|
45510
|
-
|
|
45430
|
+
return executeDepositEth(ethSigner, amount, assetType, starkPublicKey, vaultId, imxConfig);
|
|
45431
|
+
}
|
|
45432
|
+
|
|
45433
|
+
async function executeRegisterAndDepositERC20(ethSigner, quantizedAmount, assetType, starkPublicKey, vaultId, config, usersApi) {
|
|
45434
|
+
const etherKey = await ethSigner.getAddress();
|
|
45435
|
+
const coreContract = Contracts.Core.connect(config.coreContractAddress, ethSigner);
|
|
45436
|
+
const signableResult = await getSignableRegistrationOnchain(etherKey, starkPublicKey, usersApi);
|
|
45437
|
+
const populatedTransaction = await coreContract.populateTransaction.registerAndDepositERC20(etherKey, starkPublicKey, signableResult.operator_signature, assetType, vaultId, quantizedAmount);
|
|
45438
|
+
return ethSigner.sendTransaction(populatedTransaction);
|
|
45439
|
+
}
|
|
45440
|
+
async function executeDepositERC20(ethSigner, quantizedAmount, assetType, starkPublicKey, vaultId, config) {
|
|
45441
|
+
const coreContract = Contracts.Core.connect(config.coreContractAddress, ethSigner);
|
|
45442
|
+
const populatedTransaction = await coreContract.populateTransaction.depositERC20(starkPublicKey, assetType, vaultId, quantizedAmount);
|
|
45443
|
+
return ethSigner.sendTransaction(populatedTransaction);
|
|
45444
|
+
}
|
|
45445
|
+
async function depositERC20({ signers: { ethSigner }, deposit, config, }) {
|
|
45446
|
+
await validateChain(ethSigner, config.immutableXConfig);
|
|
45447
|
+
const { apiConfiguration, ethConfiguration } = config.immutableXConfig;
|
|
45448
|
+
const user = await ethSigner.getAddress();
|
|
45449
|
+
const tokensApi = new TokensApi$2(apiConfiguration);
|
|
45450
|
+
const depositsApi = new DepositsApi$1(apiConfiguration);
|
|
45451
|
+
const encodingApi = new EncodingApi$1(apiConfiguration);
|
|
45452
|
+
const usersApi = new UsersApi$1(apiConfiguration);
|
|
45453
|
+
// Get decimals for this specific ERC20
|
|
45454
|
+
const token = await tokensApi.getToken({ address: deposit.tokenAddress });
|
|
45455
|
+
// TODO: remove once fixed
|
|
45456
|
+
// eslint-disable-next-line radix
|
|
45457
|
+
const decimals = parseInt(token.data.decimals);
|
|
45458
|
+
const data = {
|
|
45459
|
+
decimals,
|
|
45460
|
+
token_address: deposit.tokenAddress,
|
|
45461
|
+
};
|
|
45462
|
+
const amount = parseUnits(deposit.amount, 0); // 0 to always use undecimalized value
|
|
45463
|
+
// Approve whether an amount of token from an account can be spent by a third-party account
|
|
45464
|
+
const tokenContract = Contracts.IERC20.connect(deposit.tokenAddress, ethSigner);
|
|
45465
|
+
const approveTransaction = await tokenContract.populateTransaction.approve(ethConfiguration.coreContractAddress, amount);
|
|
45466
|
+
await ethSigner.sendTransaction(approveTransaction);
|
|
45467
|
+
const getSignableDepositRequest = {
|
|
45468
|
+
user,
|
|
45469
|
+
token: {
|
|
45470
|
+
type: deposit.type,
|
|
45471
|
+
data,
|
|
45472
|
+
},
|
|
45473
|
+
amount: amount.toString(),
|
|
45474
|
+
};
|
|
45475
|
+
const signableDepositResult = await depositsApi.getSignableDeposit({
|
|
45476
|
+
getSignableDepositRequest,
|
|
45477
|
+
});
|
|
45478
|
+
// Perform encoding on asset details to get an assetType (required for stark contract request)
|
|
45479
|
+
const encodingResult = await encodingApi.encodeAsset({
|
|
45480
|
+
assetType: 'asset',
|
|
45481
|
+
encodeAssetRequest: {
|
|
45482
|
+
token: {
|
|
45483
|
+
type: deposit.type,
|
|
45484
|
+
data: {
|
|
45485
|
+
token_address: deposit.tokenAddress,
|
|
45486
|
+
},
|
|
45487
|
+
},
|
|
45488
|
+
},
|
|
45489
|
+
});
|
|
45490
|
+
const assetType = encodingResult.data.asset_type;
|
|
45491
|
+
const starkPublicKey = signableDepositResult.data.stark_key;
|
|
45492
|
+
const vaultId = signableDepositResult.data.vault_id;
|
|
45493
|
+
const quantizedAmount = BigNumber$2.from(signableDepositResult.data.amount);
|
|
45494
|
+
const isRegistered = await isRegisteredOnChain(starkPublicKey, ethSigner, config);
|
|
45495
|
+
if (!isRegistered) {
|
|
45496
|
+
return executeRegisterAndDepositERC20(ethSigner, quantizedAmount, assetType, starkPublicKey, vaultId, ethConfiguration, usersApi);
|
|
45511
45497
|
}
|
|
45512
|
-
|
|
45513
|
-
|
|
45514
|
-
|
|
45515
|
-
|
|
45498
|
+
return executeDepositERC20(ethSigner, quantizedAmount, assetType, starkPublicKey, vaultId, ethConfiguration);
|
|
45499
|
+
}
|
|
45500
|
+
|
|
45501
|
+
async function executeDepositERC721(ethSigner, tokenId, assetType, starkPublicKey, vaultId, config) {
|
|
45502
|
+
const coreContract = Contracts.Core.connect(config.ethConfiguration.coreContractAddress, ethSigner);
|
|
45503
|
+
const populatedTransaction = await coreContract.populateTransaction.depositNft(starkPublicKey, assetType, vaultId, tokenId);
|
|
45504
|
+
return ethSigner.sendTransaction(populatedTransaction);
|
|
45505
|
+
}
|
|
45506
|
+
async function depositERC721({ signers: { ethSigner }, deposit, config, }) {
|
|
45507
|
+
await validateChain(ethSigner, config.immutableXConfig);
|
|
45508
|
+
const user = await ethSigner.getAddress();
|
|
45509
|
+
const { immutableXConfig } = config;
|
|
45510
|
+
const depositsApi = new DepositsApi$1(immutableXConfig.apiConfiguration);
|
|
45511
|
+
const encodingApi = new EncodingApi$1(immutableXConfig.apiConfiguration);
|
|
45512
|
+
const usersApi = new UsersApi$1(immutableXConfig.apiConfiguration);
|
|
45513
|
+
const data = {
|
|
45514
|
+
token_address: deposit.tokenAddress,
|
|
45515
|
+
token_id: deposit.tokenId,
|
|
45516
|
+
};
|
|
45517
|
+
const amount = '1';
|
|
45518
|
+
const getSignableDepositRequest = {
|
|
45519
|
+
user,
|
|
45520
|
+
token: {
|
|
45521
|
+
type: deposit.type,
|
|
45522
|
+
data,
|
|
45523
|
+
},
|
|
45524
|
+
amount: amount.toString(),
|
|
45525
|
+
};
|
|
45526
|
+
const signableDepositResult = await depositsApi.getSignableDeposit({
|
|
45527
|
+
getSignableDepositRequest,
|
|
45528
|
+
});
|
|
45529
|
+
// Perform encoding on asset details to get an assetType (required for stark contract request)
|
|
45530
|
+
const encodingResult = await encodingApi.encodeAsset({
|
|
45531
|
+
assetType: 'asset',
|
|
45532
|
+
encodeAssetRequest: {
|
|
45533
|
+
token: {
|
|
45534
|
+
type: deposit.type,
|
|
45535
|
+
data: {
|
|
45536
|
+
token_address: deposit.tokenAddress,
|
|
45537
|
+
token_id: deposit.tokenId,
|
|
45538
|
+
},
|
|
45539
|
+
},
|
|
45540
|
+
},
|
|
45541
|
+
});
|
|
45542
|
+
const assetType = encodingResult.data.asset_type;
|
|
45543
|
+
const starkPublicKey = signableDepositResult.data.stark_key;
|
|
45544
|
+
const vaultId = signableDepositResult.data.vault_id;
|
|
45545
|
+
const isRegistered = await isRegisteredOnChain(starkPublicKey, ethSigner, config);
|
|
45546
|
+
// Approve whether an amount of token from an account can be spent by a third-party account
|
|
45547
|
+
const tokenContract = Contracts.IERC721.connect(deposit.tokenAddress, ethSigner);
|
|
45548
|
+
const operator = immutableXConfig.ethConfiguration.coreContractAddress;
|
|
45549
|
+
const isApprovedForAll = await tokenContract.isApprovedForAll(user, operator);
|
|
45550
|
+
if (!isApprovedForAll) {
|
|
45551
|
+
await tokenContract.setApprovalForAll(operator, true);
|
|
45516
45552
|
}
|
|
45517
|
-
if (
|
|
45518
|
-
|
|
45519
|
-
|
|
45520
|
-
|
|
45553
|
+
if (!isRegistered) {
|
|
45554
|
+
const signableResult = await getSignableRegistrationOnchain(user, starkPublicKey, usersApi);
|
|
45555
|
+
const coreContract = Contracts.Core.connect(immutableXConfig.ethConfiguration.coreContractAddress, ethSigner);
|
|
45556
|
+
// Note: proxy registration contract registerAndDepositNft method is not used as
|
|
45557
|
+
// it currently fails erc721 transfer ownership check
|
|
45558
|
+
await coreContract.registerUser(user, starkPublicKey, signableResult.operator_signature);
|
|
45521
45559
|
}
|
|
45522
|
-
return
|
|
45560
|
+
return executeDepositERC721(ethSigner, deposit.tokenId, assetType, starkPublicKey, vaultId, immutableXConfig);
|
|
45523
45561
|
}
|
|
45524
45562
|
|
|
45525
|
-
|
|
45526
|
-
|
|
45527
|
-
|
|
45528
|
-
|
|
45529
|
-
|
|
45530
|
-
|
|
45563
|
+
// TODO: remove once fixed deposit variable shadowing
|
|
45564
|
+
// eslint-disable-next-line consistent-return, @typescript-eslint/no-shadow
|
|
45565
|
+
async function deposit({ signers, deposit, config }) {
|
|
45566
|
+
// TODO: please add a reasonable default here
|
|
45567
|
+
// eslint-disable-next-line default-case
|
|
45568
|
+
switch (deposit.type) {
|
|
45569
|
+
case 'ETH':
|
|
45570
|
+
return depositEth({ signers, deposit, config });
|
|
45571
|
+
case 'ERC20':
|
|
45572
|
+
return depositERC20({ signers, deposit, config });
|
|
45573
|
+
case 'ERC721':
|
|
45574
|
+
return depositERC721({ signers, deposit, config });
|
|
45531
45575
|
}
|
|
45532
|
-
const scriptId = 'immutable-checkout-widgets-bundle';
|
|
45533
|
-
const validVersion = validateAndBuildVersion(version);
|
|
45534
|
-
// Prevent the script to be loaded more than once
|
|
45535
|
-
// by checking the presence of the script and its version.
|
|
45536
|
-
const initScript = document.getElementById(scriptId);
|
|
45537
|
-
if (initScript)
|
|
45538
|
-
return { loaded: true, element: initScript };
|
|
45539
|
-
const tag = document.createElement('script');
|
|
45540
|
-
let cdnUrl = `https://cdn.jsdelivr.net/npm/@imtbl/sdk@${validVersion}/dist/browser/checkout/widgets.js`;
|
|
45541
|
-
tag.setAttribute('id', scriptId);
|
|
45542
|
-
tag.setAttribute('data-version', validVersion);
|
|
45543
|
-
tag.setAttribute('src', cdnUrl);
|
|
45544
|
-
document.head.appendChild(tag);
|
|
45545
|
-
return { loaded: false, element: tag };
|
|
45546
45576
|
}
|
|
45547
45577
|
|
|
45548
|
-
|
|
45549
|
-
|
|
45550
|
-
|
|
45551
|
-
|
|
45552
|
-
|
|
45553
|
-
|
|
45554
|
-
|
|
45578
|
+
async function exchangeTransfer({ signers, request, config, }) {
|
|
45579
|
+
await validateChain(signers.ethSigner, config.immutableXConfig);
|
|
45580
|
+
const exchangeApi = new ExchangesApi$1(config.immutableXConfig.apiConfiguration);
|
|
45581
|
+
const ethAddress = await signers.ethSigner.getAddress();
|
|
45582
|
+
const transferAmount = request.amount;
|
|
45583
|
+
const signableResult = await exchangeApi.getExchangeSignableTransfer({
|
|
45584
|
+
id: request.transactionID,
|
|
45585
|
+
getSignableTransferRequest: {
|
|
45586
|
+
sender: ethAddress,
|
|
45587
|
+
token: convertToSignableToken(request),
|
|
45588
|
+
amount: transferAmount,
|
|
45589
|
+
receiver: request.receiver,
|
|
45590
|
+
},
|
|
45591
|
+
});
|
|
45592
|
+
const { signable_message: signableMessage, payload_hash: payloadHash } = signableResult.data;
|
|
45593
|
+
const ethSignature = await signRaw(signableMessage, signers.ethSigner);
|
|
45594
|
+
const starkSignature = await signers.starkSigner.signMessage(payloadHash);
|
|
45595
|
+
const transferSigningParams = {
|
|
45596
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
45597
|
+
sender_stark_key: signableResult.data.sender_stark_key,
|
|
45598
|
+
sender_vault_id: signableResult.data.sender_vault_id,
|
|
45599
|
+
receiver_stark_key: signableResult.data.receiver_stark_key,
|
|
45600
|
+
receiver_vault_id: signableResult.data.receiver_vault_id,
|
|
45601
|
+
asset_id: signableResult.data.asset_id,
|
|
45602
|
+
amount: signableResult.data.amount,
|
|
45603
|
+
nonce: signableResult.data.nonce,
|
|
45604
|
+
expiration_timestamp: signableResult.data.expiration_timestamp,
|
|
45605
|
+
stark_signature: starkSignature,
|
|
45606
|
+
};
|
|
45607
|
+
const response = await exchangeApi.createExchangeTransfer({
|
|
45608
|
+
id: request.transactionID,
|
|
45609
|
+
createTransferRequest: transferSigningParams,
|
|
45610
|
+
xImxEthAddress: ethAddress,
|
|
45611
|
+
xImxEthSignature: ethSignature,
|
|
45612
|
+
});
|
|
45613
|
+
return {
|
|
45614
|
+
sent_signature: response?.data.sent_signature,
|
|
45615
|
+
status: response?.data.status?.toString(),
|
|
45616
|
+
time: response?.data.time,
|
|
45617
|
+
transfer_id: response?.data.transfer_id,
|
|
45618
|
+
};
|
|
45619
|
+
}
|
|
45620
|
+
|
|
45621
|
+
class GenericIMXProvider {
|
|
45555
45622
|
config;
|
|
45556
|
-
|
|
45557
|
-
constructor(config) {
|
|
45623
|
+
signers;
|
|
45624
|
+
constructor(config, ethSigner, starkSigner) {
|
|
45558
45625
|
this.config = config;
|
|
45559
|
-
this.
|
|
45560
|
-
this.setupInterceptors();
|
|
45561
|
-
}
|
|
45562
|
-
// eslint-disable-next-line class-methods-use-this
|
|
45563
|
-
shouldAddPublishableKey(url) {
|
|
45564
|
-
// Check if the request is going to a whitelisted domain
|
|
45565
|
-
return publishableKeyDomainAllowlist.some((domain) => url.startsWith(domain));
|
|
45626
|
+
this.signers = { ethSigner, starkSigner };
|
|
45566
45627
|
}
|
|
45567
|
-
|
|
45568
|
-
this.
|
|
45569
|
-
const publishableKey = this.config?.baseConfig?.publishableKey;
|
|
45570
|
-
if (publishableKey && this.shouldAddPublishableKey(config.url || '')) {
|
|
45571
|
-
if (!publishableKey.startsWith(PUBLISHABLE_KEY_PREFIX)) {
|
|
45572
|
-
throw new Error('Invalid Publishable key. Create your Publishable key in Immutable developer hub.'
|
|
45573
|
-
+ ' https://hub.immutable.com');
|
|
45574
|
-
}
|
|
45575
|
-
// Add publishable key header for whitelisted domains
|
|
45576
|
-
// eslint-disable-next-line no-param-reassign
|
|
45577
|
-
config.headers['x-immutable-publishable-key'] = publishableKey;
|
|
45578
|
-
}
|
|
45579
|
-
return config;
|
|
45580
|
-
}, (error) => Promise.reject(error));
|
|
45628
|
+
async getAddress() {
|
|
45629
|
+
return this.signers.ethSigner.getAddress();
|
|
45581
45630
|
}
|
|
45582
|
-
async
|
|
45583
|
-
|
|
45631
|
+
async isRegisteredOffchain() {
|
|
45632
|
+
const ethAddress = await this.getAddress();
|
|
45633
|
+
return isRegisteredOffchain(ethAddress, this.config);
|
|
45584
45634
|
}
|
|
45585
|
-
|
|
45586
|
-
|
|
45587
|
-
...config,
|
|
45588
|
-
url,
|
|
45589
|
-
};
|
|
45590
|
-
return await this.request(requestConfig);
|
|
45635
|
+
registerOffchain() {
|
|
45636
|
+
return registerOffchain(this.signers, this.config);
|
|
45591
45637
|
}
|
|
45592
|
-
|
|
45593
|
-
|
|
45594
|
-
|
|
45595
|
-
|
|
45596
|
-
|
|
45597
|
-
};
|
|
45598
|
-
return await this.request(requestConfig);
|
|
45638
|
+
batchNftTransfer(request) {
|
|
45639
|
+
return batchTransfer({
|
|
45640
|
+
signers: this.signers,
|
|
45641
|
+
request,
|
|
45642
|
+
config: this.config,
|
|
45643
|
+
});
|
|
45599
45644
|
}
|
|
45600
|
-
|
|
45601
|
-
|
|
45602
|
-
|
|
45603
|
-
|
|
45604
|
-
|
|
45605
|
-
};
|
|
45606
|
-
return await this.request(requestConfig);
|
|
45645
|
+
cancelOrder(request) {
|
|
45646
|
+
return cancelOrder({
|
|
45647
|
+
signers: this.signers,
|
|
45648
|
+
request,
|
|
45649
|
+
config: this.config,
|
|
45650
|
+
});
|
|
45607
45651
|
}
|
|
45608
|
-
|
|
45609
|
-
|
|
45610
|
-
|
|
45611
|
-
|
|
45612
|
-
|
|
45613
|
-
|
|
45614
|
-
|
|
45652
|
+
completeWithdrawal(starkPublicKey, token) {
|
|
45653
|
+
return completeWithdrawal({
|
|
45654
|
+
config: this.config,
|
|
45655
|
+
signers: this.signers,
|
|
45656
|
+
token,
|
|
45657
|
+
starkPublicKey,
|
|
45658
|
+
});
|
|
45615
45659
|
}
|
|
45616
|
-
|
|
45617
|
-
|
|
45618
|
-
|
|
45619
|
-
|
|
45620
|
-
|
|
45621
|
-
|
|
45622
|
-
passport: undefined,
|
|
45623
|
-
};
|
|
45624
|
-
const WIDGETS_SCRIPT_TIMEOUT = 100;
|
|
45625
|
-
// Checkout SDK
|
|
45626
|
-
class Checkout {
|
|
45627
|
-
readOnlyProviders;
|
|
45628
|
-
httpClient;
|
|
45629
|
-
config;
|
|
45630
|
-
fiatRampService;
|
|
45631
|
-
availability;
|
|
45632
|
-
passport;
|
|
45633
|
-
/**
|
|
45634
|
-
* Constructs a new instance of the CheckoutModule class.
|
|
45635
|
-
* @param {CheckoutModuleConfiguration} [config=SANDBOX_CONFIGURATION] - The configuration object for the CheckoutModule.
|
|
45636
|
-
*/
|
|
45637
|
-
constructor(config = SANDBOX_CONFIGURATION) {
|
|
45638
|
-
this.httpClient = new HttpClient(config);
|
|
45639
|
-
this.config = new CheckoutConfiguration(config, this.httpClient);
|
|
45640
|
-
this.fiatRampService = new FiatRampService(this.config);
|
|
45641
|
-
this.readOnlyProviders = new Map();
|
|
45642
|
-
this.availability = availabilityService(this.config.isDevelopment, this.config.isProduction);
|
|
45643
|
-
this.passport = config.passport;
|
|
45660
|
+
createOrder(request) {
|
|
45661
|
+
return createOrder({
|
|
45662
|
+
signers: this.signers,
|
|
45663
|
+
request,
|
|
45664
|
+
config: this.config,
|
|
45665
|
+
});
|
|
45644
45666
|
}
|
|
45645
|
-
|
|
45646
|
-
|
|
45647
|
-
|
|
45648
|
-
|
|
45649
|
-
|
|
45650
|
-
const checkout = this;
|
|
45651
|
-
// Preload the configurations
|
|
45652
|
-
await checkout.config.remote.getConfig();
|
|
45653
|
-
const factory = new Promise((resolve, reject) => {
|
|
45654
|
-
function checkForWidgetsBundleLoaded() {
|
|
45655
|
-
if (typeof ImmutableCheckoutWidgets !== 'undefined') {
|
|
45656
|
-
resolve(new ImmutableCheckoutWidgets.WidgetsFactory(checkout, init.config));
|
|
45657
|
-
}
|
|
45658
|
-
else {
|
|
45659
|
-
// If ImmutableCheckoutWidgets is not defined, wait for set amount of time.
|
|
45660
|
-
// When time has elapsed, check again if ImmutableCheckoutWidgets is defined.
|
|
45661
|
-
// Once it's defined, the promise will resolve and setTimeout won't be called again.
|
|
45662
|
-
setTimeout(checkForWidgetsBundleLoaded, WIDGETS_SCRIPT_TIMEOUT);
|
|
45663
|
-
}
|
|
45664
|
-
}
|
|
45665
|
-
try {
|
|
45666
|
-
const script = loadUnresolved(init.version);
|
|
45667
|
-
if (script.loaded && typeof ImmutableCheckoutWidgets !== 'undefined') {
|
|
45668
|
-
resolve(new ImmutableCheckoutWidgets.WidgetsFactory(checkout, init.config));
|
|
45669
|
-
}
|
|
45670
|
-
else {
|
|
45671
|
-
checkForWidgetsBundleLoaded();
|
|
45672
|
-
}
|
|
45673
|
-
}
|
|
45674
|
-
catch (err) {
|
|
45675
|
-
reject(new CheckoutError('Failed to load widgets script', CheckoutErrorType.WIDGETS_SCRIPT_LOAD_ERROR, { error: err }));
|
|
45676
|
-
}
|
|
45667
|
+
createTrade(request) {
|
|
45668
|
+
return createTrade({
|
|
45669
|
+
signers: this.signers,
|
|
45670
|
+
request,
|
|
45671
|
+
config: this.config,
|
|
45677
45672
|
});
|
|
45678
|
-
return factory;
|
|
45679
45673
|
}
|
|
45680
|
-
|
|
45681
|
-
|
|
45682
|
-
|
|
45683
|
-
|
|
45684
|
-
|
|
45685
|
-
|
|
45686
|
-
return await createProvider(params.walletProviderName, this.passport);
|
|
45674
|
+
deposit(tokenAmount) {
|
|
45675
|
+
return deposit({
|
|
45676
|
+
signers: this.signers,
|
|
45677
|
+
deposit: tokenAmount,
|
|
45678
|
+
config: this.config,
|
|
45679
|
+
});
|
|
45687
45680
|
}
|
|
45688
|
-
|
|
45689
|
-
|
|
45690
|
-
|
|
45691
|
-
|
|
45692
|
-
|
|
45693
|
-
|
|
45694
|
-
const web3Provider = await validateProvider(this.config, params.provider, { allowUnsupportedProvider: true });
|
|
45695
|
-
return checkIsWalletConnected(web3Provider);
|
|
45681
|
+
exchangeTransfer(request) {
|
|
45682
|
+
return exchangeTransfer({
|
|
45683
|
+
signers: this.signers,
|
|
45684
|
+
request,
|
|
45685
|
+
config: this.config,
|
|
45686
|
+
});
|
|
45696
45687
|
}
|
|
45697
|
-
|
|
45698
|
-
|
|
45699
|
-
|
|
45700
|
-
* @returns {Promise<ConnectResult>} A promise that resolves to an object containing the provider and network information.
|
|
45701
|
-
* @throws {Error} If the provider is not valid or if there is an error connecting to the network.
|
|
45702
|
-
*/
|
|
45703
|
-
async connect(params) {
|
|
45704
|
-
const web3Provider = await validateProvider(this.config, params.provider, { allowUnsupportedProvider: true });
|
|
45705
|
-
await connectSite(web3Provider);
|
|
45706
|
-
return { provider: web3Provider };
|
|
45688
|
+
async isRegisteredOnchain() {
|
|
45689
|
+
const starkPublicKey = await this.signers.starkSigner.getAddress();
|
|
45690
|
+
return isRegisteredOnChain(starkPublicKey, this.signers.ethSigner, this.config);
|
|
45707
45691
|
}
|
|
45708
|
-
|
|
45709
|
-
|
|
45710
|
-
|
|
45711
|
-
|
|
45712
|
-
|
|
45713
|
-
async switchNetwork(params) {
|
|
45714
|
-
const web3Provider = await validateProvider(this.config, params.provider, {
|
|
45715
|
-
allowUnsupportedProvider: true,
|
|
45716
|
-
allowMistmatchedChainId: true,
|
|
45692
|
+
prepareWithdrawal(request) {
|
|
45693
|
+
return prepareWithdrawal({
|
|
45694
|
+
signers: this.signers,
|
|
45695
|
+
withdrawal: request,
|
|
45696
|
+
config: this.config,
|
|
45717
45697
|
});
|
|
45718
|
-
const switchNetworkRes = await switchWalletNetwork(this.config, web3Provider, params.chainId);
|
|
45719
|
-
return switchNetworkRes;
|
|
45720
45698
|
}
|
|
45721
|
-
|
|
45722
|
-
|
|
45723
|
-
|
|
45724
|
-
|
|
45725
|
-
|
|
45726
|
-
|
|
45727
|
-
async getTokenInfo(params) {
|
|
45728
|
-
return await getERC20TokenInfo(params.provider, params.tokenAddress);
|
|
45699
|
+
transfer(request) {
|
|
45700
|
+
return transfer({
|
|
45701
|
+
signers: this.signers,
|
|
45702
|
+
request,
|
|
45703
|
+
config: this.config,
|
|
45704
|
+
});
|
|
45729
45705
|
}
|
|
45730
|
-
|
|
45731
|
-
|
|
45732
|
-
|
|
45733
|
-
|
|
45734
|
-
|
|
45735
|
-
|
|
45736
|
-
|
|
45737
|
-
|
|
45738
|
-
|
|
45739
|
-
|
|
45740
|
-
|
|
45706
|
+
}
|
|
45707
|
+
|
|
45708
|
+
const WALLET_ACTION = {
|
|
45709
|
+
// TODO: remove once fixed - consider using an enum
|
|
45710
|
+
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
45711
|
+
SWITCH_CHAIN: 'wallet_switchEthereumChain',
|
|
45712
|
+
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
45713
|
+
CONNECT: 'eth_requestAccounts',
|
|
45714
|
+
};
|
|
45715
|
+
function isRequestableProvider(provider) {
|
|
45716
|
+
return !!provider?.request;
|
|
45717
|
+
}
|
|
45718
|
+
async function connectProvider(provider, chainID) {
|
|
45719
|
+
await provider.request({ method: WALLET_ACTION.CONNECT });
|
|
45720
|
+
if (chainID) {
|
|
45721
|
+
await provider.request({
|
|
45722
|
+
method: WALLET_ACTION.SWITCH_CHAIN,
|
|
45723
|
+
params: [{ chainId: `0x${chainID.toString(16)}` }],
|
|
45724
|
+
});
|
|
45741
45725
|
}
|
|
45742
|
-
|
|
45743
|
-
|
|
45744
|
-
|
|
45745
|
-
|
|
45746
|
-
|
|
45747
|
-
|
|
45748
|
-
|
|
45726
|
+
}
|
|
45727
|
+
|
|
45728
|
+
const ERRORS = {
|
|
45729
|
+
// TODO: remove once fixed - consider using something in line with the naming convention
|
|
45730
|
+
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
45731
|
+
PROVIDER_NOT_FOUND: 'The Metamask provider was not found',
|
|
45732
|
+
};
|
|
45733
|
+
async function connect$1({ chainID, }) {
|
|
45734
|
+
const provider = (await detectEthereumProvider());
|
|
45735
|
+
if (!isRequestableProvider(provider)) {
|
|
45736
|
+
throw new Error(ERRORS.PROVIDER_NOT_FOUND);
|
|
45749
45737
|
}
|
|
45750
|
-
|
|
45751
|
-
|
|
45752
|
-
|
|
45753
|
-
|
|
45754
|
-
|
|
45755
|
-
|
|
45756
|
-
|
|
45738
|
+
await connectProvider(provider, chainID);
|
|
45739
|
+
// NOTE: if we want to listen to Metamask events in the future, we can add a
|
|
45740
|
+
// listener here.
|
|
45741
|
+
return new ethers.providers.Web3Provider(provider);
|
|
45742
|
+
}
|
|
45743
|
+
|
|
45744
|
+
const COMMUNICATION_TYPE = 'message';
|
|
45745
|
+
var RequestEventType;
|
|
45746
|
+
(function (RequestEventType) {
|
|
45747
|
+
RequestEventType["GET_CONNECTION_REQUEST"] = "GET_CONNECTION_REQUEST";
|
|
45748
|
+
RequestEventType["CONNECT_WALLET_REQUEST"] = "CONNECT_WALLET_REQUEST";
|
|
45749
|
+
RequestEventType["SIGN_MESSAGE_REQUEST"] = "SIGN_MESSAGE_REQUEST";
|
|
45750
|
+
RequestEventType["DISCONNECT_WALLET_REQUEST"] = "DISCONNECT_WALLET_REQUEST";
|
|
45751
|
+
})(RequestEventType || (RequestEventType = {}));
|
|
45752
|
+
var ResponseEventType;
|
|
45753
|
+
(function (ResponseEventType) {
|
|
45754
|
+
ResponseEventType["CONNECT_WALLET_RESPONSE"] = "CONNECT_WALLET_RESPONSE";
|
|
45755
|
+
ResponseEventType["SIGN_MESSAGE_RESPONSE"] = "SIGN_MESSAGE_RESPONSE";
|
|
45756
|
+
ResponseEventType["GET_CONNECTION_RESPONSE"] = "GET_CONNECTION_RESPONSE";
|
|
45757
|
+
ResponseEventType["DISCONNECT_WALLET_RESPONSE"] = "DISCONNECT_WALLET_RESPONSE";
|
|
45758
|
+
})(ResponseEventType || (ResponseEventType = {}));
|
|
45759
|
+
|
|
45760
|
+
function postRequestMessage(iframe, payload) {
|
|
45761
|
+
if (iframe && iframe.contentWindow) {
|
|
45762
|
+
iframe.contentWindow.postMessage(payload, new URL(iframe.src).origin);
|
|
45757
45763
|
}
|
|
45758
|
-
|
|
45759
|
-
|
|
45760
|
-
|
|
45761
|
-
|
|
45762
|
-
|
|
45763
|
-
async getTokenAllowList(params) {
|
|
45764
|
-
return await getTokenAllowList(this.config, params);
|
|
45764
|
+
}
|
|
45765
|
+
|
|
45766
|
+
function messageResponseListener(iframe, event, eventType, callback) {
|
|
45767
|
+
if (iframe && event.source !== iframe.contentWindow) {
|
|
45768
|
+
return;
|
|
45765
45769
|
}
|
|
45766
|
-
|
|
45767
|
-
|
|
45768
|
-
|
|
45769
|
-
* @returns {Promise<GetWalletAllowListResult>} - A promise that resolves to the wallet allow list result.
|
|
45770
|
-
*/
|
|
45771
|
-
async getWalletAllowList(params) {
|
|
45772
|
-
return await getWalletAllowList(params);
|
|
45770
|
+
const l2WalletMessage = event.data;
|
|
45771
|
+
if (l2WalletMessage.type !== eventType) {
|
|
45772
|
+
return;
|
|
45773
45773
|
}
|
|
45774
|
-
|
|
45775
|
-
|
|
45776
|
-
|
|
45777
|
-
|
|
45778
|
-
|
|
45779
|
-
|
|
45780
|
-
|
|
45781
|
-
|
|
45774
|
+
callback(l2WalletMessage.details);
|
|
45775
|
+
}
|
|
45776
|
+
|
|
45777
|
+
class ImxSigner {
|
|
45778
|
+
publicAddress;
|
|
45779
|
+
iframe;
|
|
45780
|
+
constructor(publicAddress, iframe) {
|
|
45781
|
+
this.publicAddress = publicAddress;
|
|
45782
|
+
this.iframe = iframe;
|
|
45782
45783
|
}
|
|
45783
|
-
|
|
45784
|
-
|
|
45785
|
-
* @param {GetNetworkParams} params - The parameters for retrieving network information.
|
|
45786
|
-
* @returns {Promise<NetworkInfo>} A promise that resolves to the network information.
|
|
45787
|
-
*/
|
|
45788
|
-
async getNetworkInfo(params) {
|
|
45789
|
-
const web3Provider = await validateProvider(this.config, params.provider, {
|
|
45790
|
-
allowUnsupportedProvider: true,
|
|
45791
|
-
allowMistmatchedChainId: true,
|
|
45792
|
-
});
|
|
45793
|
-
return await getNetworkInfo(this.config, web3Provider);
|
|
45784
|
+
getAddress() {
|
|
45785
|
+
return this.publicAddress;
|
|
45794
45786
|
}
|
|
45795
|
-
|
|
45796
|
-
|
|
45797
|
-
|
|
45798
|
-
|
|
45799
|
-
|
|
45800
|
-
|
|
45801
|
-
|
|
45802
|
-
|
|
45803
|
-
|
|
45804
|
-
|
|
45805
|
-
|
|
45787
|
+
signMessage(rawMessage) {
|
|
45788
|
+
return new Promise((resolve, reject) => {
|
|
45789
|
+
const listener = (event) => {
|
|
45790
|
+
messageResponseListener(this.iframe, event, ResponseEventType.SIGN_MESSAGE_RESPONSE, (messageDetails) => {
|
|
45791
|
+
window.removeEventListener(COMMUNICATION_TYPE, listener);
|
|
45792
|
+
if (!messageDetails.success) {
|
|
45793
|
+
reject(new Error(messageDetails.error?.message));
|
|
45794
|
+
}
|
|
45795
|
+
resolve(messageDetails.data.signedMessage);
|
|
45796
|
+
});
|
|
45797
|
+
};
|
|
45798
|
+
window.addEventListener(COMMUNICATION_TYPE, listener);
|
|
45799
|
+
postRequestMessage(this.iframe, {
|
|
45800
|
+
type: RequestEventType.SIGN_MESSAGE_REQUEST,
|
|
45801
|
+
details: { starkPublicKey: this.publicAddress, message: rawMessage },
|
|
45802
|
+
});
|
|
45803
|
+
});
|
|
45806
45804
|
}
|
|
45807
|
-
|
|
45808
|
-
|
|
45809
|
-
* @param {SellParams} params - The parameters for the sell.
|
|
45810
|
-
* Only currently actions the first order in the array until we support batch processing.
|
|
45811
|
-
* Only currently actions the first fee in the fees array of each order until we support multiple fees.
|
|
45812
|
-
*/
|
|
45813
|
-
async sell(params) {
|
|
45814
|
-
if (params.orders.length > 1) {
|
|
45815
|
-
// eslint-disable-next-line no-console
|
|
45816
|
-
console.warn('This endpoint currently only processes the first order in the array.');
|
|
45817
|
-
}
|
|
45818
|
-
const web3Provider = await validateProvider(this.config, params.provider);
|
|
45819
|
-
return await sell(this.config, web3Provider, params.orders);
|
|
45805
|
+
getIFrame() {
|
|
45806
|
+
return this.iframe;
|
|
45820
45807
|
}
|
|
45821
|
-
|
|
45822
|
-
|
|
45823
|
-
|
|
45824
|
-
|
|
45825
|
-
|
|
45826
|
-
|
|
45827
|
-
|
|
45828
|
-
|
|
45829
|
-
|
|
45808
|
+
}
|
|
45809
|
+
|
|
45810
|
+
const IMX_WALLET_IFRAME_ID = 'imx-wallet-app';
|
|
45811
|
+
const IMX_WALLET_IFRAME_HOSTS = {
|
|
45812
|
+
[Environment$1.SANDBOX]: 'https://wallets.sandbox.immutable.com',
|
|
45813
|
+
[Environment$1.PRODUCTION]: 'https://wallets.immutable.com',
|
|
45814
|
+
};
|
|
45815
|
+
const IMX_WALLET_IFRAME_STYLE = 'display: none;';
|
|
45816
|
+
function getIFrame() {
|
|
45817
|
+
return document.querySelector(`iframe#${IMX_WALLET_IFRAME_ID}`);
|
|
45818
|
+
}
|
|
45819
|
+
async function setupIFrame(env) {
|
|
45820
|
+
return new Promise((resolve) => {
|
|
45821
|
+
const iframe = document.createElement('iframe');
|
|
45822
|
+
iframe.setAttribute('id', IMX_WALLET_IFRAME_ID);
|
|
45823
|
+
iframe.setAttribute('src', IMX_WALLET_IFRAME_HOSTS[env]);
|
|
45824
|
+
iframe.setAttribute('style', IMX_WALLET_IFRAME_STYLE);
|
|
45825
|
+
document.body.appendChild(iframe);
|
|
45826
|
+
iframe.onload = () => resolve(iframe);
|
|
45827
|
+
});
|
|
45828
|
+
}
|
|
45829
|
+
async function getOrSetupIFrame(env) {
|
|
45830
|
+
const iframe = getIFrame();
|
|
45831
|
+
if (iframe)
|
|
45832
|
+
return iframe;
|
|
45833
|
+
return await setupIFrame(env);
|
|
45834
|
+
}
|
|
45835
|
+
|
|
45836
|
+
const DEFAULT_CONNECTION_MESSAGE = 'Only sign this request if you’ve initiated an action with Immutable X.';
|
|
45837
|
+
const CONNECTION_FAILED_ERROR = 'The L2 IMX Wallet connection has failed';
|
|
45838
|
+
async function connect(l1Provider, env) {
|
|
45839
|
+
const l1Signer = l1Provider.getSigner();
|
|
45840
|
+
const address = await l1Signer.getAddress();
|
|
45841
|
+
const signature = await l1Signer.signMessage(DEFAULT_CONNECTION_MESSAGE);
|
|
45842
|
+
const iframe = await getOrSetupIFrame(env);
|
|
45843
|
+
return new Promise((resolve, reject) => {
|
|
45844
|
+
const listener = (event) => {
|
|
45845
|
+
messageResponseListener(iframe, event, ResponseEventType.CONNECT_WALLET_RESPONSE, (messageDetails) => {
|
|
45846
|
+
window.removeEventListener(COMMUNICATION_TYPE, listener);
|
|
45847
|
+
if (!messageDetails.success) {
|
|
45848
|
+
reject(new Error(CONNECTION_FAILED_ERROR));
|
|
45849
|
+
}
|
|
45850
|
+
resolve(new ImxSigner(messageDetails.data.starkPublicKey, iframe));
|
|
45851
|
+
});
|
|
45852
|
+
};
|
|
45853
|
+
window.addEventListener(COMMUNICATION_TYPE, listener);
|
|
45854
|
+
postRequestMessage(iframe, {
|
|
45855
|
+
type: RequestEventType.CONNECT_WALLET_REQUEST,
|
|
45856
|
+
details: { ethAddress: address, signature },
|
|
45857
|
+
});
|
|
45858
|
+
});
|
|
45859
|
+
}
|
|
45860
|
+
async function disconnect(imxSigner) {
|
|
45861
|
+
const iframe = imxSigner.getIFrame();
|
|
45862
|
+
return new Promise((resolve, reject) => {
|
|
45863
|
+
const listener = (event) => {
|
|
45864
|
+
messageResponseListener(iframe, event, ResponseEventType.DISCONNECT_WALLET_RESPONSE, (messageDetails) => {
|
|
45865
|
+
window.removeEventListener(COMMUNICATION_TYPE, listener);
|
|
45866
|
+
if (!messageDetails.success && messageDetails.error) {
|
|
45867
|
+
reject(messageDetails.error);
|
|
45868
|
+
}
|
|
45869
|
+
iframe.remove();
|
|
45870
|
+
resolve();
|
|
45871
|
+
});
|
|
45872
|
+
};
|
|
45873
|
+
window.addEventListener(COMMUNICATION_TYPE, listener);
|
|
45874
|
+
postRequestMessage(iframe, {
|
|
45875
|
+
type: RequestEventType.DISCONNECT_WALLET_REQUEST,
|
|
45876
|
+
details: { starkPublicKey: imxSigner.getAddress() },
|
|
45877
|
+
});
|
|
45878
|
+
});
|
|
45879
|
+
}
|
|
45880
|
+
|
|
45881
|
+
var ProviderErrorType;
|
|
45882
|
+
(function (ProviderErrorType) {
|
|
45883
|
+
ProviderErrorType["PROVIDER_CONNECTION_ERROR"] = "PROVIDER_CONNECTION_ERROR";
|
|
45884
|
+
ProviderErrorType["WALLET_CONNECTION_ERROR"] = "WALLET_CONNECTION_ERROR";
|
|
45885
|
+
})(ProviderErrorType || (ProviderErrorType = {}));
|
|
45886
|
+
class ProviderError extends Error {
|
|
45887
|
+
type;
|
|
45888
|
+
constructor(message, type) {
|
|
45889
|
+
super(message);
|
|
45890
|
+
this.type = type;
|
|
45830
45891
|
}
|
|
45831
|
-
|
|
45832
|
-
|
|
45833
|
-
|
|
45834
|
-
|
|
45835
|
-
async smartCheckout(params) {
|
|
45836
|
-
const web3Provider = await validateProvider(this.config, params.provider);
|
|
45837
|
-
let itemRequirements = [];
|
|
45838
|
-
try {
|
|
45839
|
-
itemRequirements = await getItemRequirementsFromRequirements(web3Provider, params.itemRequirements);
|
|
45840
|
-
}
|
|
45841
|
-
catch (err) {
|
|
45842
|
-
throw new CheckoutError('Failed to map item requirements', CheckoutErrorType.ITEM_REQUIREMENTS_ERROR, { error: err });
|
|
45843
|
-
}
|
|
45844
|
-
return await smartCheckout(this.config, web3Provider, itemRequirements, params.transactionOrGasAmount);
|
|
45892
|
+
}
|
|
45893
|
+
const withProviderError = async (fn, customError) => {
|
|
45894
|
+
try {
|
|
45895
|
+
return await fn();
|
|
45845
45896
|
}
|
|
45846
|
-
|
|
45847
|
-
|
|
45848
|
-
|
|
45849
|
-
* @returns {boolean} - True if the object is a Web3 provider, false otherwise.
|
|
45850
|
-
*/
|
|
45851
|
-
static isWeb3Provider(web3Provider) {
|
|
45852
|
-
return isWeb3Provider(web3Provider);
|
|
45897
|
+
catch (error) {
|
|
45898
|
+
const errorMessage = customError.message || `${error.message}` || 'UnknownError';
|
|
45899
|
+
throw new ProviderError(errorMessage, customError.type);
|
|
45853
45900
|
}
|
|
45854
|
-
|
|
45855
|
-
|
|
45856
|
-
|
|
45857
|
-
|
|
45858
|
-
|
|
45859
|
-
|
|
45860
|
-
|
|
45861
|
-
|
|
45901
|
+
};
|
|
45902
|
+
|
|
45903
|
+
class MetaMaskIMXProvider extends GenericIMXProvider {
|
|
45904
|
+
static imxSigner;
|
|
45905
|
+
static async connect(config) {
|
|
45906
|
+
return await withProviderError(async () => {
|
|
45907
|
+
const metaMaskProvider = await connect$1({
|
|
45908
|
+
chainID: config.immutableXConfig.ethConfiguration.chainID,
|
|
45909
|
+
});
|
|
45910
|
+
this.imxSigner = await connect(metaMaskProvider, config.baseConfig.environment);
|
|
45911
|
+
return new MetaMaskIMXProvider(config, metaMaskProvider.getSigner(), this.imxSigner);
|
|
45912
|
+
}, { type: ProviderErrorType.WALLET_CONNECTION_ERROR });
|
|
45862
45913
|
}
|
|
45863
|
-
|
|
45864
|
-
|
|
45865
|
-
|
|
45866
|
-
* @returns {Promise<string>} - A promise that resolves to a string url.
|
|
45867
|
-
*/
|
|
45868
|
-
async createFiatRampUrl(params) {
|
|
45869
|
-
let tokenAmount;
|
|
45870
|
-
let tokenSymbol = 'IMX';
|
|
45871
|
-
let email;
|
|
45872
|
-
const walletAddress = await params.web3Provider.getSigner().getAddress();
|
|
45873
|
-
const isPassport = params.web3Provider.provider?.isPassport || false;
|
|
45874
|
-
if (isPassport && params.passport) {
|
|
45875
|
-
const userInfo = await params.passport.getUserInfo();
|
|
45876
|
-
email = userInfo?.email;
|
|
45877
|
-
}
|
|
45878
|
-
const tokenList = await getTokenAllowList(this.config, { type: TokenFilterTypes.ONRAMP });
|
|
45879
|
-
const token = tokenList.tokens?.find((t) => isMatchingAddress(t.address, params.tokenAddress));
|
|
45880
|
-
if (token) {
|
|
45881
|
-
tokenAmount = params.tokenAmount;
|
|
45882
|
-
tokenSymbol = token.symbol;
|
|
45914
|
+
static async disconnect() {
|
|
45915
|
+
if (!this.imxSigner) {
|
|
45916
|
+
throw new ProviderError('Attempted to disconnect from the MetaMask IMX provider without an established connection', ProviderErrorType.PROVIDER_CONNECTION_ERROR);
|
|
45883
45917
|
}
|
|
45884
|
-
return
|
|
45885
|
-
|
|
45886
|
-
|
|
45887
|
-
walletAddress,
|
|
45888
|
-
tokenAmount,
|
|
45889
|
-
tokenSymbol,
|
|
45890
|
-
email,
|
|
45891
|
-
});
|
|
45892
|
-
}
|
|
45893
|
-
/**
|
|
45894
|
-
* Fetches fiat ramp fee estimations.
|
|
45895
|
-
* @returns {Promise<OnRampProviderFees>} - A promise that resolves to OnRampProviderFees.
|
|
45896
|
-
*/
|
|
45897
|
-
async getExchangeFeeEstimate() {
|
|
45898
|
-
return await this.fiatRampService.feeEstimate();
|
|
45918
|
+
return withProviderError(async () => {
|
|
45919
|
+
await disconnect(this.imxSigner);
|
|
45920
|
+
}, { type: ProviderErrorType.PROVIDER_CONNECTION_ERROR });
|
|
45899
45921
|
}
|
|
45900
|
-
|
|
45901
|
-
|
|
45902
|
-
|
|
45903
|
-
|
|
45904
|
-
|
|
45905
|
-
return this.availability.checkDexAvailability();
|
|
45922
|
+
static async signMessage(message) {
|
|
45923
|
+
if (!this.imxSigner) {
|
|
45924
|
+
throw new ProviderError('Attempted to sign a message with the MetaMask IMX provider without an established connection', ProviderErrorType.PROVIDER_CONNECTION_ERROR);
|
|
45925
|
+
}
|
|
45926
|
+
return withProviderError(async () => await this.imxSigner.signMessage(message), { type: ProviderErrorType.PROVIDER_CONNECTION_ERROR });
|
|
45906
45927
|
}
|
|
45907
45928
|
}
|
|
45908
45929
|
|
|
45909
|
-
class
|
|
45910
|
-
|
|
45911
|
-
|
|
45912
|
-
|
|
45913
|
-
|
|
45914
|
-
|
|
45915
|
-
|
|
45916
|
-
|
|
45917
|
-
|
|
45918
|
-
|
|
45919
|
-
|
|
45930
|
+
class ProviderConfiguration {
|
|
45931
|
+
immutableXConfig;
|
|
45932
|
+
baseConfig;
|
|
45933
|
+
constructor({ baseConfig, overrides }) {
|
|
45934
|
+
this.baseConfig = baseConfig;
|
|
45935
|
+
if (overrides) {
|
|
45936
|
+
this.immutableXConfig = overrides.immutableXConfig;
|
|
45937
|
+
}
|
|
45938
|
+
else {
|
|
45939
|
+
// TODO: remove once a sensible default is chosen
|
|
45940
|
+
// eslint-disable-next-line default-case
|
|
45941
|
+
switch (baseConfig.environment) {
|
|
45942
|
+
case Environment$1.SANDBOX: {
|
|
45943
|
+
this.immutableXConfig = Config.SANDBOX;
|
|
45944
|
+
break;
|
|
45945
|
+
}
|
|
45946
|
+
case Environment$1.PRODUCTION: {
|
|
45947
|
+
this.immutableXConfig = Config.PRODUCTION;
|
|
45948
|
+
break;
|
|
45949
|
+
}
|
|
45950
|
+
}
|
|
45951
|
+
}
|
|
45920
45952
|
}
|
|
45921
45953
|
}
|
|
45922
45954
|
|
|
45923
|
-
var
|
|
45955
|
+
var x = /*#__PURE__*/Object.freeze({
|
|
45924
45956
|
__proto__: null,
|
|
45925
|
-
|
|
45926
|
-
|
|
45927
|
-
|
|
45928
|
-
|
|
45929
|
-
|
|
45930
|
-
|
|
45931
|
-
|
|
45932
|
-
get CheckoutErrorType () { return CheckoutErrorType; },
|
|
45933
|
-
get CheckoutStatus () { return CheckoutStatus; },
|
|
45934
|
-
get ConnectEventType () { return ConnectEventType; },
|
|
45935
|
-
get ConnectTargetLayer () { return ConnectTargetLayer; },
|
|
45936
|
-
get ExchangeType () { return ExchangeType; },
|
|
45937
|
-
get FeeType () { return FeeType; },
|
|
45938
|
-
get FundingStepType () { return FundingStepType; },
|
|
45939
|
-
get GasEstimateType () { return GasEstimateType; },
|
|
45940
|
-
get GasTokenType () { return GasTokenType; },
|
|
45941
|
-
IMMUTABLE_API_BASE_URL: IMMUTABLE_API_BASE_URL,
|
|
45942
|
-
get IMTBLWidgetEvents () { return IMTBLWidgetEvents; },
|
|
45943
|
-
get ItemType () { return ItemType; },
|
|
45944
|
-
get NetworkFilterTypes () { return NetworkFilterTypes; },
|
|
45945
|
-
get OnRampEventType () { return OnRampEventType; },
|
|
45946
|
-
get OrchestrationEventType () { return OrchestrationEventType; },
|
|
45947
|
-
get ProviderEventType () { return ProviderEventType; },
|
|
45948
|
-
get RoutingOutcomeType () { return RoutingOutcomeType; },
|
|
45949
|
-
get SaleEventType () { return SaleEventType; },
|
|
45950
|
-
get SalePaymentTypes () { return SalePaymentTypes; },
|
|
45951
|
-
get SwapEventType () { return SwapEventType; },
|
|
45952
|
-
get TokenFilterTypes () { return TokenFilterTypes; },
|
|
45953
|
-
get TransactionOrGasType () { return TransactionOrGasType; },
|
|
45954
|
-
get WalletEventType () { return WalletEventType; },
|
|
45955
|
-
get WalletFilterTypes () { return WalletFilterTypes; },
|
|
45956
|
-
get WalletProviderName () { return WalletProviderName; },
|
|
45957
|
-
get WidgetTheme () { return WidgetTheme; },
|
|
45958
|
-
get WidgetType () { return WidgetType; }
|
|
45957
|
+
GenericIMXProvider: GenericIMXProvider,
|
|
45958
|
+
IMXClient: IMXClient,
|
|
45959
|
+
IMXError: IMXError,
|
|
45960
|
+
MetaMaskIMXProvider: MetaMaskIMXProvider,
|
|
45961
|
+
ProviderConfiguration: ProviderConfiguration,
|
|
45962
|
+
imxClientCreateStarkSigner: createStarkSigner,
|
|
45963
|
+
imxClientGenerateLegacyStarkPrivateKey: generateLegacyStarkPrivateKey
|
|
45959
45964
|
});
|
|
45960
45965
|
|
|
45961
|
-
export { blockchain_data as blockchainData, checkout, config,
|
|
45966
|
+
export { blockchain_data as blockchainData, checkout, config, orderbook, passport, x };
|