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