@imtbl/sdk 0.0.1-alpha.3 → 0.1.0-alpha
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/README.md +28 -0
- package/dist/checkout_sdk.d.ts +247 -7
- package/dist/checkout_sdk.js +147 -91
- package/dist/checkout_widgets.d.ts +13 -2
- package/dist/checkout_widgets.js +4 -2
- package/dist/{starkex.d.ts → immutablex_client.d.ts} +670 -10
- package/dist/immutablex_client.js +510 -0
- package/dist/index.cjs +2359 -1820
- package/dist/index.d.ts +644 -41
- package/dist/index.js +2344 -1811
- package/dist/passport.d.ts +5 -2
- package/dist/passport.js +33 -8
- package/dist/provider.d.ts +2 -2
- package/dist/provider.js +43 -43
- package/package.json +22 -32
- package/dist/browser/checkout.js +0 -2
- package/dist/starkex.js +0 -58
- /package/dist/{base.d.ts → config.d.ts} +0 -0
- /package/dist/{base.js → config.js} +0 -0
package/dist/index.js
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
|
-
import { ImmutableX, Config, TransfersApi, OrdersApi,
|
|
1
|
+
import { ImmutableX, Config, Configuration, UsersApi, TransfersApi, OrdersApi, ExchangesApi, TradesApi, generateLegacyStarkPrivateKey, createStarkSigner, Contracts, WithdrawalsApi, MintsApi, DepositsApi, EncodingApi, TokensApi } from '@imtbl/core-sdk';
|
|
2
|
+
export { createStarkSigner as imxClientCreateStarkSigner, generateLegacyStarkPrivateKey as imxClientGenerateLegacyStarkPrivateKey } from '@imtbl/core-sdk';
|
|
3
|
+
import { UserManager } from 'oidc-client-ts';
|
|
4
|
+
import { ethers, utils, Contract } from 'ethers';
|
|
5
|
+
import { Magic } from 'magic-sdk';
|
|
6
|
+
import { OpenIdExtension } from '@magic-ext/oidc';
|
|
2
7
|
import BN from 'bn.js';
|
|
3
8
|
import * as encUtils from 'enc-utils';
|
|
4
9
|
import { parseUnits } from '@ethersproject/units';
|
|
5
10
|
import { BigNumber } from '@ethersproject/bignumber';
|
|
6
|
-
import { ethers, utils, Contract } from 'ethers';
|
|
7
11
|
import detectEthereumProvider from '@metamask/detect-provider';
|
|
8
|
-
import { UserManager } from 'oidc-client-ts';
|
|
9
|
-
import { Magic } from 'magic-sdk';
|
|
10
|
-
import { OpenIdExtension } from '@magic-ext/oidc';
|
|
11
12
|
import { Web3Provider } from '@ethersproject/providers';
|
|
12
13
|
|
|
13
14
|
var Environment;
|
|
@@ -31,7 +32,7 @@ const PRODUCTION = () => {
|
|
|
31
32
|
chainID: 1,
|
|
32
33
|
coreContractAddress: '0x5FDCCA53617f4d2b9134B29090C87D01058e27e9',
|
|
33
34
|
registrationContractAddress: '0x72a06bf2a1CE5e39cBA06c0CAb824960B587d64c',
|
|
34
|
-
sdkVersion: 'ts-immutable-sdk-0.0
|
|
35
|
+
sdkVersion: 'ts-immutable-sdk-0.1.0-alpha',
|
|
35
36
|
});
|
|
36
37
|
};
|
|
37
38
|
// Set `sdkVersion` on config
|
|
@@ -41,10 +42,10 @@ const SANDBOX = () => {
|
|
|
41
42
|
chainID: 5,
|
|
42
43
|
coreContractAddress: '0x7917eDb51ecD6CdB3F9854c3cc593F33de10c623',
|
|
43
44
|
registrationContractAddress: '0x1C97Ada273C9A52253f463042f29117090Cd7D83',
|
|
44
|
-
sdkVersion: 'ts-immutable-sdk-0.0
|
|
45
|
+
sdkVersion: 'ts-immutable-sdk-0.1.0-alpha',
|
|
45
46
|
});
|
|
46
47
|
};
|
|
47
|
-
class
|
|
48
|
+
class ImxConfiguration {
|
|
48
49
|
immutableXConfig;
|
|
49
50
|
baseConfig;
|
|
50
51
|
constructor({ baseConfig, overrides }) {
|
|
@@ -67,11 +68,462 @@ class StarkExConfiguration {
|
|
|
67
68
|
}
|
|
68
69
|
}
|
|
69
70
|
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
71
|
+
class ImmutableXClient {
|
|
72
|
+
immutableX;
|
|
73
|
+
depositsApi;
|
|
74
|
+
mintsApi;
|
|
75
|
+
ordersApi;
|
|
76
|
+
tokensApi;
|
|
77
|
+
tradesApi;
|
|
78
|
+
transfersApi;
|
|
79
|
+
exchangeApi;
|
|
80
|
+
nftCheckoutPrimaryApi;
|
|
81
|
+
usersApi;
|
|
82
|
+
withdrawalsApi;
|
|
83
|
+
balanceApi;
|
|
84
|
+
assetApi;
|
|
85
|
+
collectionApi;
|
|
86
|
+
metadataApi;
|
|
87
|
+
metadataRefreshesApi;
|
|
88
|
+
projectsApi;
|
|
89
|
+
constructor(config) {
|
|
90
|
+
const imxConfig = new ImxConfiguration(config);
|
|
91
|
+
this.immutableX = new ImmutableX(imxConfig.immutableXConfig);
|
|
92
|
+
this.depositsApi = this.immutableX.depositsApi;
|
|
93
|
+
this.mintsApi = this.immutableX.mintsApi;
|
|
94
|
+
this.ordersApi = this.immutableX.ordersApi;
|
|
95
|
+
this.tokensApi = this.immutableX.tokensApi;
|
|
96
|
+
this.tradesApi = this.immutableX.tradesApi;
|
|
97
|
+
this.transfersApi = this.immutableX.transfersApi;
|
|
98
|
+
this.exchangeApi = this.immutableX.exchangeApi;
|
|
99
|
+
this.usersApi = this.immutableX.usersApi;
|
|
100
|
+
this.withdrawalsApi = this.immutableX.withdrawalsApi;
|
|
101
|
+
this.balanceApi = this.immutableX.balanceApi;
|
|
102
|
+
this.assetApi = this.immutableX.assetApi;
|
|
103
|
+
this.collectionApi = this.immutableX.collectionApi;
|
|
104
|
+
this.metadataApi = this.immutableX.metadataApi;
|
|
105
|
+
this.metadataRefreshesApi = this.immutableX.metadataRefreshesApi;
|
|
106
|
+
this.nftCheckoutPrimaryApi = this.immutableX.nftCheckoutPrimaryApi;
|
|
107
|
+
this.projectsApi = this.immutableX.projectsApi;
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Get details of a Deposit with the given ID
|
|
111
|
+
* @param request - the request object containing the parameters to be provided in the API request
|
|
112
|
+
* @returns a promise that resolves with the requested Deposit
|
|
113
|
+
* @throws {@link index.IMXError}
|
|
114
|
+
*/
|
|
115
|
+
getDeposit(request) {
|
|
116
|
+
return this.immutableX.getDeposit(request);
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Get a list of Deposits
|
|
120
|
+
* @param request - optional request object containing the parameters to be provided in the API request
|
|
121
|
+
* @returns a promise that resolves with the requested list of Deposits
|
|
122
|
+
* @throws {@link index.IMXError}
|
|
123
|
+
*/
|
|
124
|
+
listDeposits(request) {
|
|
125
|
+
return this.immutableX.listDeposits(request);
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Get Stark keys for a registered User
|
|
129
|
+
* @param ethAddress - the eth address of the User
|
|
130
|
+
* @returns a promise that resolves with the requested User
|
|
131
|
+
* @throws {@link index.IMXError}
|
|
132
|
+
*/
|
|
133
|
+
getUser(ethAddress) {
|
|
134
|
+
return this.immutableX.getUser(ethAddress);
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* Get details of an Asset
|
|
138
|
+
* @param request - the request object containing the parameters to be provided in the API request
|
|
139
|
+
* @returns a promise that resolves with the requested Asset
|
|
140
|
+
* @throws {@link index.IMXError}
|
|
141
|
+
*/
|
|
142
|
+
getAsset(request) {
|
|
143
|
+
return this.immutableX.getAsset(request);
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* Get a list of Assets
|
|
147
|
+
* @param request - optional request object containing the parameters to be provided in the API request
|
|
148
|
+
* @returns a promise that resolves with the requested list of Assets
|
|
149
|
+
* @throws {@link index.IMXError}
|
|
150
|
+
*/
|
|
151
|
+
listAssets(request) {
|
|
152
|
+
return this.immutableX.listAssets(request);
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* Create a Collection
|
|
156
|
+
* @param ethSigner - the L1 signer
|
|
157
|
+
* @param request - the request object to be provided in the API request
|
|
158
|
+
* @returns a promise that resolves with the created Collection
|
|
159
|
+
* @throws {@link index.IMXError}
|
|
160
|
+
*/
|
|
161
|
+
createCollection(ethSigner, request) {
|
|
162
|
+
return this.immutableX.createCollection(ethSigner, request);
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
* Get details of a Collection at the given address
|
|
166
|
+
* @param request - the request object containing the parameters to be provided in the API request
|
|
167
|
+
* @returns a promise that resolves with the requested Collection
|
|
168
|
+
* @throws {@link index.IMXError}
|
|
169
|
+
*/
|
|
170
|
+
getCollection(request) {
|
|
171
|
+
return this.immutableX.getCollection(request);
|
|
172
|
+
}
|
|
173
|
+
/**
|
|
174
|
+
* Get a list of Collection filters
|
|
175
|
+
* @param request - the request object containing the parameters to be provided in the API request
|
|
176
|
+
* @returns a promise that resolves with the requested list of Collection Filters
|
|
177
|
+
* @throws {@link index.IMXError}
|
|
178
|
+
*/
|
|
179
|
+
listCollectionFilters(request) {
|
|
180
|
+
return this.immutableX.listCollectionFilters(request);
|
|
181
|
+
}
|
|
182
|
+
/**
|
|
183
|
+
* Get a list of Collections
|
|
184
|
+
* @param request - optional request object containing the parameters to be provided in the API request
|
|
185
|
+
* @returns a promise that resolves with the requested list of Collections
|
|
186
|
+
* @throws {@link index.IMXError}
|
|
187
|
+
*/
|
|
188
|
+
listCollections(request) {
|
|
189
|
+
return this.collectionApi.listCollections(request).then((res) => res.data);
|
|
190
|
+
}
|
|
191
|
+
/**
|
|
192
|
+
* Update a Collection
|
|
193
|
+
* @param ethSigner - the L1 signer
|
|
194
|
+
* @param collectionAddress - the Collection contract address
|
|
195
|
+
* @param request - the request object containing the parameters to be provided in the API request
|
|
196
|
+
* @returns a promise that resolves with the updated Collection
|
|
197
|
+
* @throws {@link index.IMXError}
|
|
198
|
+
*/
|
|
199
|
+
updateCollection(ethSigner, collectionAddress, request) {
|
|
200
|
+
return this.immutableX.updateCollection(ethSigner, collectionAddress, request);
|
|
201
|
+
}
|
|
202
|
+
/**
|
|
203
|
+
* Add metadata schema to Collection
|
|
204
|
+
* @param ethSigner - the L1 signer
|
|
205
|
+
* @param collectionAddress - the Collection contract address
|
|
206
|
+
* @param request - the request object containing the parameters to be provided in the API request
|
|
207
|
+
* @returns a promise that resolves with the SuccessResponse if successful
|
|
208
|
+
* @throws {@link index.IMXError}
|
|
209
|
+
*/
|
|
210
|
+
addMetadataSchemaToCollection(ethSigner, collectionAddress, request) {
|
|
211
|
+
return this.immutableX.addMetadataSchemaToCollection(ethSigner, collectionAddress, request);
|
|
212
|
+
}
|
|
213
|
+
/**
|
|
214
|
+
* Get Metadata schema
|
|
215
|
+
* @param request - the request object containing the parameters to be provided in the API request
|
|
216
|
+
* @returns a promise that resolves with the requested Metadata schema
|
|
217
|
+
* @throws {@link index.IMXError}
|
|
218
|
+
*/
|
|
219
|
+
getMetadataSchema(request) {
|
|
220
|
+
return this.immutableX.getMetadataSchema(request);
|
|
221
|
+
}
|
|
222
|
+
/**
|
|
223
|
+
* Update metadata schema by name
|
|
224
|
+
* @param ethSigner - the L1 signer
|
|
225
|
+
* @param collectionAddress - the Collection contract address
|
|
226
|
+
* @param name - the Metadata schema name
|
|
227
|
+
* @param request - the request object containing the parameters to be provided in the API request
|
|
228
|
+
* @returns a promise that resolves with the SuccessResponse if successful
|
|
229
|
+
* @throws {@link index.IMXError}
|
|
230
|
+
*/
|
|
231
|
+
updateMetadataSchemaByName(ethSigner, collectionAddress, name, request) {
|
|
232
|
+
return this.immutableX.updateMetadataSchemaByName(ethSigner, collectionAddress, name, request);
|
|
233
|
+
}
|
|
234
|
+
/**
|
|
235
|
+
* Get a list of metadata refreshes
|
|
236
|
+
* @param ethSigner - the L1 signer
|
|
237
|
+
* @param collectionAddress - the Collection contract address
|
|
238
|
+
* @param pageSize - the page size of the result
|
|
239
|
+
* @param cursor - the cursor
|
|
240
|
+
* @returns a promise that resolves with the requested metadata refreshes
|
|
241
|
+
* @throws {@link index.IMXError}
|
|
242
|
+
*/
|
|
243
|
+
listMetadataRefreshes(ethSigner, collectionAddress, pageSize, cursor) {
|
|
244
|
+
return this.immutableX.listMetadataRefreshes(ethSigner, collectionAddress, pageSize, cursor);
|
|
245
|
+
}
|
|
246
|
+
/**
|
|
247
|
+
* Get a list of metadata refresh errors
|
|
248
|
+
* @param ethSigner - the L1 signer
|
|
249
|
+
* @param refreshId - the metadata refresh ID
|
|
250
|
+
* @param pageSize - the page size of the result
|
|
251
|
+
* @param cursor - the cursor
|
|
252
|
+
* @returns a promise that resolves with the requested metadata refresh errors
|
|
253
|
+
* @throws {@link index.IMXError}
|
|
254
|
+
*/
|
|
255
|
+
getMetadataRefreshErrors(ethSigner, refreshId, pageSize, cursor) {
|
|
256
|
+
return this.immutableX.getMetadataRefreshErrors(ethSigner, refreshId, pageSize, cursor);
|
|
257
|
+
}
|
|
258
|
+
/**
|
|
259
|
+
* Get a list of metadata refresh results
|
|
260
|
+
* @param ethSigner - the L1 signer
|
|
261
|
+
* @param refreshId - the metadata refresh ID
|
|
262
|
+
* @returns a promise that resolves with the requested metadata refresh results
|
|
263
|
+
* @throws {@link index.IMXError}
|
|
264
|
+
*/
|
|
265
|
+
getMetadataRefreshResults(ethSigner, refreshId) {
|
|
266
|
+
return this.immutableX.getMetadataRefreshResults(ethSigner, refreshId);
|
|
267
|
+
}
|
|
268
|
+
/**
|
|
269
|
+
* Request a metadata refresh
|
|
270
|
+
* @param ethSigner - the L1 signer
|
|
271
|
+
* @param request the request object containing the parameters to be provided in the API request
|
|
272
|
+
* @returns a promise that resolves with the requested metadata refresh
|
|
273
|
+
* @throws {@link index.IMXError}
|
|
274
|
+
*/
|
|
275
|
+
createMetadataRefresh(ethSigner, request) {
|
|
276
|
+
return this.immutableX.createMetadataRefresh(ethSigner, request);
|
|
277
|
+
}
|
|
278
|
+
/**
|
|
279
|
+
* Create a Project
|
|
280
|
+
* @param ethSigner - the L1 signer
|
|
281
|
+
* @param request - the request object containing the parameters to be provided in the API request
|
|
282
|
+
* @returns a promise that resolves with the created Project
|
|
283
|
+
* @throws {@link index.IMXError}
|
|
284
|
+
*/
|
|
285
|
+
async createProject(ethSigner, request) {
|
|
286
|
+
return this.immutableX.createProject(ethSigner, request);
|
|
287
|
+
}
|
|
288
|
+
/**
|
|
289
|
+
* Get a Project
|
|
290
|
+
* @param ethSigner - the L1 signer
|
|
291
|
+
* @param id - the Project ID
|
|
292
|
+
* @returns a promise that resolves with the requested Project
|
|
293
|
+
* @throws {@link index.IMXError}
|
|
294
|
+
*/
|
|
295
|
+
async getProject(ethSigner, id) {
|
|
296
|
+
return this.immutableX.getProject(ethSigner, id);
|
|
297
|
+
}
|
|
298
|
+
/**
|
|
299
|
+
* Get Projects owned by the given User
|
|
300
|
+
* @param ethSigner - the L1 signer
|
|
301
|
+
* @param pageSize - the page size of the result
|
|
302
|
+
* @param cursor - the cursor
|
|
303
|
+
* @param orderBy - the property to sort by
|
|
304
|
+
* @param direction - direction to sort (asc/desc)
|
|
305
|
+
* @returns a promise that resolves with the requested Projects
|
|
306
|
+
* @throws {@link index.IMXError}
|
|
307
|
+
*/
|
|
308
|
+
async getProjects(ethSigner, pageSize, cursor, orderBy, direction) {
|
|
309
|
+
return this.immutableX.getProjects(ethSigner, pageSize, cursor, orderBy, direction);
|
|
310
|
+
}
|
|
311
|
+
/**
|
|
312
|
+
* Get the token Balances of the User
|
|
313
|
+
* @param request - the request object containing the parameters to be provided in the API request
|
|
314
|
+
* @returns a promise that resolves with the requested Balance
|
|
315
|
+
* @throws {@link index.IMXError}
|
|
316
|
+
*/
|
|
317
|
+
getBalance(request) {
|
|
318
|
+
return this.immutableX.getBalance(request);
|
|
319
|
+
}
|
|
320
|
+
/**
|
|
321
|
+
* Get a list of Balances for given User
|
|
322
|
+
* @param request the request object containing the parameters to be provided in the API request
|
|
323
|
+
* @returns a promise that resolves with the requested list of Balances
|
|
324
|
+
* @throws {@link index.IMXError}
|
|
325
|
+
*/
|
|
326
|
+
listBalances(request) {
|
|
327
|
+
return this.immutableX.listBalances(request);
|
|
328
|
+
}
|
|
329
|
+
/**
|
|
330
|
+
* Get details of a Mint with the given ID
|
|
331
|
+
* @param request the request object containing the parameters to be provided in the API request
|
|
332
|
+
* @returns a promise that resolves with the requested Mint
|
|
333
|
+
* @throws {@link index.IMXError}
|
|
334
|
+
*/
|
|
335
|
+
getMint(request) {
|
|
336
|
+
return this.immutableX.getMint(request);
|
|
337
|
+
}
|
|
338
|
+
/**
|
|
339
|
+
* Get a list of Mints
|
|
340
|
+
* @param request optional request object containing the parameters to be provided in the API request
|
|
341
|
+
* @returns a promise that resolves with the requested list of Mints
|
|
342
|
+
* @throws {@link index.IMXError}
|
|
343
|
+
*/
|
|
344
|
+
listMints(request) {
|
|
345
|
+
return this.immutableX.listMints(request);
|
|
346
|
+
}
|
|
347
|
+
/**
|
|
348
|
+
* Mint tokens in a batch with fees
|
|
349
|
+
* @param ethSigner - the L1 signer
|
|
350
|
+
* @param request - the request object to be provided in the API request
|
|
351
|
+
* @returns a promise that resolves with the minted tokens
|
|
352
|
+
* @throws {@link index.IMXError}
|
|
353
|
+
*/
|
|
354
|
+
mint(ethSigner, request) {
|
|
355
|
+
return this.immutableX.mint(ethSigner, request);
|
|
356
|
+
}
|
|
357
|
+
/**
|
|
358
|
+
* Get a list of Withdrawals
|
|
359
|
+
* @param request - optional request object containing the parameters to be provided in the API request
|
|
360
|
+
* @returns a promise that resolves with the requested list of Withdrawals
|
|
361
|
+
* @throws {@link index.IMXError}
|
|
362
|
+
*/
|
|
363
|
+
listWithdrawals(request) {
|
|
364
|
+
return this.immutableX.listWithdrawals(request);
|
|
365
|
+
}
|
|
366
|
+
/**
|
|
367
|
+
* Get details of Withdrawal with the given ID
|
|
368
|
+
* @param request - the request object containing the parameters to be provided in the API request
|
|
369
|
+
* @returns a promise that resolves with the requested Withdrawal
|
|
370
|
+
* @throws {@link index.IMXError}
|
|
371
|
+
*/
|
|
372
|
+
getWithdrawal(request) {
|
|
373
|
+
return this.immutableX.getWithdrawal(request);
|
|
374
|
+
}
|
|
375
|
+
/**
|
|
376
|
+
* Get details of an Order with the given ID
|
|
377
|
+
* @param request - the request object containing the parameters to be provided in the API request
|
|
378
|
+
* @returns a promise that resolves with the requested Order
|
|
379
|
+
* @throws {@link index.IMXError}
|
|
380
|
+
*/
|
|
381
|
+
getOrder(request) {
|
|
382
|
+
return this.immutableX.getOrder(request);
|
|
383
|
+
}
|
|
384
|
+
/**
|
|
385
|
+
* Get a list of Orders
|
|
386
|
+
* @param request - optional request object containing the parameters to be provided in the API request
|
|
387
|
+
* @returns a promise that resolves with the requested list of Orders
|
|
388
|
+
* @throws {@link index.IMXError}
|
|
389
|
+
*/
|
|
390
|
+
listOrders(request) {
|
|
391
|
+
return this.immutableX.listOrders(request);
|
|
392
|
+
}
|
|
393
|
+
/**
|
|
394
|
+
* Get details of a Trade with the given ID
|
|
395
|
+
* @param request - the request object containing the parameters to be provided in the API request
|
|
396
|
+
* @returns a promise that resolves with the requested Trade
|
|
397
|
+
* @throws {@link index.IMXError}
|
|
398
|
+
*/
|
|
399
|
+
getTrade(request) {
|
|
400
|
+
return this.immutableX.getTrade(request);
|
|
401
|
+
}
|
|
402
|
+
/**
|
|
403
|
+
* Get a list of Trades
|
|
404
|
+
* @param request - optional request object containing the parameters to be provided in the API request
|
|
405
|
+
* @returns a promise that resolves with the requested list of Trades
|
|
406
|
+
* @throws {@link index.IMXError}
|
|
407
|
+
*/
|
|
408
|
+
listTrades(request) {
|
|
409
|
+
return this.immutableX.listTrades(request);
|
|
410
|
+
}
|
|
411
|
+
/**
|
|
412
|
+
* Get details of a Token
|
|
413
|
+
* @param request - the request object containing the parameters to be provided in the API request
|
|
414
|
+
* @returns a promise that resolves with the requested Token
|
|
415
|
+
* @throws {@link index.IMXError}
|
|
416
|
+
*/
|
|
417
|
+
getToken(request) {
|
|
418
|
+
return this.immutableX.getToken(request);
|
|
419
|
+
}
|
|
420
|
+
/**
|
|
421
|
+
* Get a list of Tokens
|
|
422
|
+
* @param request - optional request object containing the parameters to be provided in the API request
|
|
423
|
+
* @returns a promise that resolves with the requested list of Tokens
|
|
424
|
+
* @throws {@link index.IMXError}
|
|
425
|
+
*/
|
|
426
|
+
listTokens(request) {
|
|
427
|
+
return this.immutableX.listTokens(request);
|
|
428
|
+
}
|
|
429
|
+
/**
|
|
430
|
+
* Get details of a Transfer with the given ID
|
|
431
|
+
* @param request - the request object containing the parameters to be provided in the API request
|
|
432
|
+
* @returns a promise that resolves with the requested Transfer
|
|
433
|
+
* @throws {@link index.IMXError}
|
|
434
|
+
*/
|
|
435
|
+
getTransfer(request) {
|
|
436
|
+
return this.immutableX.getTransfer(request);
|
|
437
|
+
}
|
|
438
|
+
/**
|
|
439
|
+
* Get a list of Transfers
|
|
440
|
+
* @param request - optional request object containing the parameters to be provided in the API request
|
|
441
|
+
* @returns a promise that resolves with the requested list of Transfers
|
|
442
|
+
* @throws {@link index.IMXError}
|
|
443
|
+
*/
|
|
444
|
+
listTransfers(request) {
|
|
445
|
+
return this.immutableX.listTransfers(request);
|
|
446
|
+
}
|
|
447
|
+
/**
|
|
448
|
+
* Create a new Exchange transaction
|
|
449
|
+
* @param request - the request object to be provided in the API request
|
|
450
|
+
* @returns a promise that resolves with the created Exchange Transaction
|
|
451
|
+
* @throws {@link index.IMXError}
|
|
452
|
+
*/
|
|
453
|
+
createExchange(request) {
|
|
454
|
+
return this.immutableX.createExchange(request).then((res) => res.data);
|
|
455
|
+
}
|
|
456
|
+
/**
|
|
457
|
+
* Get an Exchange transaction
|
|
458
|
+
* @param request - the request object to be provided in the API request
|
|
459
|
+
* @returns a promise that resolves with the Exchange Transaction
|
|
460
|
+
* @throws {@link index.IMXError}
|
|
461
|
+
*/
|
|
462
|
+
getExchange(request) {
|
|
463
|
+
return this.immutableX.getExchange(request).then((res) => res.data);
|
|
464
|
+
}
|
|
465
|
+
/**
|
|
466
|
+
* Get Exchange transactions
|
|
467
|
+
* @param request - the request object to be provided in the API request
|
|
468
|
+
* @returns a promise that resolves with Exchange Transactions
|
|
469
|
+
* @throws {@link index.IMXError}
|
|
470
|
+
*/
|
|
471
|
+
getExchanges(request) {
|
|
472
|
+
return this.immutableX.getExchanges(request).then((res) => res.data);
|
|
473
|
+
}
|
|
474
|
+
/**
|
|
475
|
+
* Create a new Transfer request
|
|
476
|
+
* @param walletConnection - the pair of Eth/Stark signers
|
|
477
|
+
* @param request - the request object to be provided in the API request
|
|
478
|
+
* @returns a promise that resolves with the created Exchange Transfer
|
|
479
|
+
* @throws {@link index.IMXError}
|
|
480
|
+
*/
|
|
481
|
+
exchangeTransfer(walletConnection, request) {
|
|
482
|
+
return this.immutableX.exchangeTransfer(walletConnection, request);
|
|
483
|
+
}
|
|
484
|
+
/**
|
|
485
|
+
* Create a new nft primary transaction
|
|
486
|
+
* @param request - the request object to be provided in the API request
|
|
487
|
+
* @returns a promise that resolves with the created nft primary Transaction
|
|
488
|
+
* @throws {@link index.IMXError}
|
|
489
|
+
*/
|
|
490
|
+
createNftPrimary(request) {
|
|
491
|
+
return this.immutableX.createNftPrimary(request).then((res) => res.data);
|
|
492
|
+
}
|
|
493
|
+
/**
|
|
494
|
+
* Get nft primary supported currencies and their limits
|
|
495
|
+
* @param request - the request object to be provided in the API request
|
|
496
|
+
* @returns a promise that resolves with nft primary Currencies
|
|
497
|
+
* @throws {@link index.IMXError}
|
|
498
|
+
*/
|
|
499
|
+
getCurrenciesNFTCheckoutPrimary(request) {
|
|
500
|
+
return this.immutableX
|
|
501
|
+
.getCurrenciesNFTCheckoutPrimary(request)
|
|
502
|
+
.then((res) => res.data);
|
|
503
|
+
}
|
|
504
|
+
/**
|
|
505
|
+
* Get nft primary transaction by transaction id
|
|
506
|
+
* @param request - the request object to be provided in the API request
|
|
507
|
+
* @returns a promise that resolves with nft primary transaction
|
|
508
|
+
* @throws {@link index.IMXError}
|
|
509
|
+
*/
|
|
510
|
+
getNftPrimaryTransaction(request) {
|
|
511
|
+
return this.immutableX
|
|
512
|
+
.getNftPrimaryTransaction(request)
|
|
513
|
+
.then((res) => res.data);
|
|
514
|
+
}
|
|
515
|
+
/**
|
|
516
|
+
* Get list of nft primary transactions
|
|
517
|
+
* @param request - the request object to be provided in the API request
|
|
518
|
+
* @returns a promise that resolves with nft primary transaction
|
|
519
|
+
* @throws {@link index.IMXError}
|
|
520
|
+
*/
|
|
521
|
+
getNftPrimaryTransactions(request) {
|
|
522
|
+
return this.immutableX
|
|
523
|
+
.getNftPrimaryTransactions(request)
|
|
524
|
+
.then((res) => res.data);
|
|
525
|
+
}
|
|
526
|
+
}
|
|
75
527
|
|
|
76
528
|
// used to sign message with L1 keys. Used for registration
|
|
77
529
|
function serializeEthSignature(sig) {
|
|
@@ -143,696 +595,880 @@ function convertToSignableToken(token) {
|
|
|
143
595
|
}
|
|
144
596
|
}
|
|
145
597
|
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
598
|
+
var PassportErrorType;
|
|
599
|
+
(function (PassportErrorType) {
|
|
600
|
+
PassportErrorType["AUTHENTICATION_ERROR"] = "AUTHENTICATION_ERROR";
|
|
601
|
+
PassportErrorType["INVALID_CONFIGURATION"] = "INVALID_CONFIGURATION";
|
|
602
|
+
PassportErrorType["WALLET_CONNECTION_ERROR"] = "WALLET_CONNECTION_ERROR";
|
|
603
|
+
PassportErrorType["NOT_LOGGED_IN_ERROR"] = "NOT_LOGGED_IN_ERROR";
|
|
604
|
+
PassportErrorType["SILENT_LOGIN_ERROR"] = "SILENT_LOGIN_ERROR";
|
|
605
|
+
PassportErrorType["REFRESH_TOKEN_ERROR"] = "REFRESH_TOKEN_ERROR";
|
|
606
|
+
PassportErrorType["USER_REGISTRATION_ERROR"] = "USER_REGISTRATION_ERROR";
|
|
607
|
+
PassportErrorType["LOGOUT_ERROR"] = "LOGOUT_ERROR";
|
|
608
|
+
PassportErrorType["TRANSFER_ERROR"] = "TRANSFER_ERROR";
|
|
609
|
+
PassportErrorType["CREATE_ORDER_ERROR"] = "CREATE_ORDER_ERROR";
|
|
610
|
+
PassportErrorType["CANCEL_ORDER_ERROR"] = "CANCEL_ORDER_ERROR";
|
|
611
|
+
PassportErrorType["EXCHANGE_TRANSFER_ERROR"] = "EXCHANGE_TRANSFER_ERROR";
|
|
612
|
+
PassportErrorType["CREATE_TRADE_ERROR"] = "CREATE_TRADE_ERROR";
|
|
613
|
+
PassportErrorType["OPERATION_NOT_SUPPORTED_ERROR"] = "OPERATION_NOT_SUPPORTED_ERROR";
|
|
614
|
+
})(PassportErrorType || (PassportErrorType = {}));
|
|
615
|
+
class PassportError extends Error {
|
|
616
|
+
type;
|
|
617
|
+
constructor(message, type) {
|
|
618
|
+
super(message);
|
|
619
|
+
this.type = type;
|
|
620
|
+
}
|
|
153
621
|
}
|
|
622
|
+
const withPassportError = async (fn, customErrorType) => {
|
|
623
|
+
try {
|
|
624
|
+
return await fn();
|
|
625
|
+
}
|
|
626
|
+
catch (error) {
|
|
627
|
+
const errorMessage = `${customErrorType}: ${error.message}` || 'UnknownError';
|
|
628
|
+
throw new PassportError(errorMessage, customErrorType);
|
|
629
|
+
}
|
|
630
|
+
};
|
|
154
631
|
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
632
|
+
const POLL_INTERVAL = 1 * 1000; // every 1 second
|
|
633
|
+
const MAX_RETRIES = 3;
|
|
634
|
+
const wait = (ms) => new Promise((resolve) => {
|
|
635
|
+
setTimeout(() => resolve(), ms);
|
|
636
|
+
});
|
|
637
|
+
const retryWithDelay = async (fn, options) => {
|
|
638
|
+
const { retries = MAX_RETRIES, interval = POLL_INTERVAL, finalErr = Error('Retry failed'), } = options || {};
|
|
639
|
+
try {
|
|
640
|
+
return await fn();
|
|
641
|
+
}
|
|
642
|
+
catch (err) {
|
|
643
|
+
if (retries <= 0) {
|
|
644
|
+
return Promise.reject(finalErr);
|
|
645
|
+
}
|
|
646
|
+
await wait(interval);
|
|
647
|
+
return retryWithDelay(fn, { retries: retries - 1, finalErr });
|
|
648
|
+
}
|
|
649
|
+
};
|
|
650
|
+
|
|
651
|
+
const getAuthConfiguration = ({ oidcConfiguration, authenticationDomain, }) => {
|
|
652
|
+
const baseConfiguration = {
|
|
653
|
+
authority: authenticationDomain,
|
|
654
|
+
redirect_uri: oidcConfiguration.redirectUri,
|
|
655
|
+
popup_redirect_uri: oidcConfiguration.redirectUri,
|
|
656
|
+
client_id: oidcConfiguration.clientId,
|
|
657
|
+
metadata: {
|
|
658
|
+
authorization_endpoint: `${authenticationDomain}/authorize`,
|
|
659
|
+
token_endpoint: `${authenticationDomain}/oauth/token`,
|
|
660
|
+
userinfo_endpoint: `${authenticationDomain}/userinfo`,
|
|
661
|
+
end_session_endpoint: `${authenticationDomain}/v2/logout` +
|
|
662
|
+
`?returnTo=${encodeURIComponent(oidcConfiguration.logoutRedirectUri)}` +
|
|
663
|
+
`&client_id=${oidcConfiguration.clientId}`,
|
|
166
664
|
},
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
const starkSignature = await starkExSigner.signMessage(payloadHash);
|
|
171
|
-
const transferSigningParams = {
|
|
172
|
-
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
173
|
-
sender_stark_key: signableResult.data.sender_stark_key,
|
|
174
|
-
sender_vault_id: signableResult.data.sender_vault_id,
|
|
175
|
-
receiver_stark_key: signableResult.data.receiver_stark_key,
|
|
176
|
-
receiver_vault_id: signableResult.data.receiver_vault_id,
|
|
177
|
-
asset_id: signableResult.data.asset_id,
|
|
178
|
-
amount: signableResult.data.amount,
|
|
179
|
-
nonce: signableResult.data.nonce,
|
|
180
|
-
expiration_timestamp: signableResult.data.expiration_timestamp,
|
|
181
|
-
stark_signature: starkSignature,
|
|
182
|
-
};
|
|
183
|
-
const response = await transfersApi.createTransferV1({
|
|
184
|
-
createTransferRequest: transferSigningParams,
|
|
185
|
-
xImxEthAddress: ethAddress,
|
|
186
|
-
xImxEthSignature: ethSignature,
|
|
187
|
-
});
|
|
188
|
-
return {
|
|
189
|
-
sent_signature: response?.data.sent_signature,
|
|
190
|
-
status: response?.data.status?.toString(),
|
|
191
|
-
time: response?.data.time,
|
|
192
|
-
transfer_id: response?.data.transfer_id,
|
|
665
|
+
mergeClaims: true,
|
|
666
|
+
loadUserInfo: true,
|
|
667
|
+
scope: oidcConfiguration.scope,
|
|
193
668
|
};
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
const ethAddress = await ethSigner.getAddress();
|
|
198
|
-
const transfersApi = new TransfersApi(config.immutableXConfig.apiConfiguration);
|
|
199
|
-
const signableRequests = request.map((nftTransfer) => {
|
|
200
|
-
return {
|
|
201
|
-
amount: '1',
|
|
202
|
-
token: convertToSignableToken({
|
|
203
|
-
type: 'ERC721',
|
|
204
|
-
tokenId: nftTransfer.tokenId,
|
|
205
|
-
tokenAddress: nftTransfer.tokenAddress,
|
|
206
|
-
}),
|
|
207
|
-
receiver: nftTransfer.receiver,
|
|
669
|
+
if (oidcConfiguration.audience) {
|
|
670
|
+
baseConfiguration.extraQueryParams = {
|
|
671
|
+
audience: oidcConfiguration.audience,
|
|
208
672
|
};
|
|
209
|
-
});
|
|
210
|
-
const signableResult = await transfersApi.getSignableTransfer({
|
|
211
|
-
getSignableTransferRequestV2: {
|
|
212
|
-
sender_ether_key: ethAddress,
|
|
213
|
-
signable_requests: signableRequests,
|
|
214
|
-
},
|
|
215
|
-
});
|
|
216
|
-
const signableMessage = signableResult.data.signable_message;
|
|
217
|
-
if (signableMessage === undefined) {
|
|
218
|
-
throw new Error('Invalid response from Signable registration offchain');
|
|
219
673
|
}
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
asset_id: resp.asset_id,
|
|
229
|
-
amount: resp.amount,
|
|
230
|
-
nonce: resp.nonce,
|
|
231
|
-
expiration_timestamp: resp.expiration_timestamp,
|
|
232
|
-
stark_signature: starkSignature,
|
|
233
|
-
};
|
|
234
|
-
requests.push(req);
|
|
674
|
+
return baseConfiguration;
|
|
675
|
+
};
|
|
676
|
+
class AuthManager {
|
|
677
|
+
userManager;
|
|
678
|
+
config;
|
|
679
|
+
constructor(config) {
|
|
680
|
+
this.config = config;
|
|
681
|
+
this.userManager = new UserManager(getAuthConfiguration(config));
|
|
235
682
|
}
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
683
|
+
mapOidcUserToDomainModel = (oidcUser) => {
|
|
684
|
+
const passport = oidcUser.profile?.passport;
|
|
685
|
+
return {
|
|
686
|
+
expired: oidcUser.expired,
|
|
687
|
+
idToken: oidcUser.id_token,
|
|
688
|
+
accessToken: oidcUser.access_token,
|
|
689
|
+
refreshToken: oidcUser.refresh_token,
|
|
690
|
+
profile: {
|
|
691
|
+
sub: oidcUser.profile.sub,
|
|
692
|
+
email: oidcUser.profile.email,
|
|
693
|
+
nickname: oidcUser.profile.nickname,
|
|
694
|
+
},
|
|
695
|
+
etherKey: passport?.ether_key || '',
|
|
696
|
+
};
|
|
248
697
|
};
|
|
698
|
+
async login() {
|
|
699
|
+
return withPassportError(async () => {
|
|
700
|
+
const popupWindowFeatures = { width: 410, height: 450 };
|
|
701
|
+
const oidcUser = await this.userManager.signinPopup({
|
|
702
|
+
popupWindowFeatures,
|
|
703
|
+
});
|
|
704
|
+
return this.mapOidcUserToDomainModel(oidcUser);
|
|
705
|
+
}, PassportErrorType.AUTHENTICATION_ERROR);
|
|
706
|
+
}
|
|
707
|
+
async loginCallback() {
|
|
708
|
+
return withPassportError(async () => this.userManager.signinPopupCallback(), PassportErrorType.AUTHENTICATION_ERROR);
|
|
709
|
+
}
|
|
710
|
+
async logout() {
|
|
711
|
+
return withPassportError(async () => this.userManager.signoutRedirect(), PassportErrorType.LOGOUT_ERROR);
|
|
712
|
+
}
|
|
713
|
+
async loginSilent() {
|
|
714
|
+
return withPassportError(async () => {
|
|
715
|
+
const existedUser = await this.getUser();
|
|
716
|
+
if (!existedUser) {
|
|
717
|
+
return null;
|
|
718
|
+
}
|
|
719
|
+
const oidcUser = await this.userManager.signinSilent();
|
|
720
|
+
if (!oidcUser) {
|
|
721
|
+
return null;
|
|
722
|
+
}
|
|
723
|
+
return this.mapOidcUserToDomainModel(oidcUser);
|
|
724
|
+
}, PassportErrorType.SILENT_LOGIN_ERROR);
|
|
725
|
+
}
|
|
726
|
+
async getUser() {
|
|
727
|
+
return withPassportError(async () => {
|
|
728
|
+
const oidcUser = await this.userManager.getUser();
|
|
729
|
+
if (!oidcUser) {
|
|
730
|
+
return null;
|
|
731
|
+
}
|
|
732
|
+
return this.mapOidcUserToDomainModel(oidcUser);
|
|
733
|
+
}, PassportErrorType.NOT_LOGGED_IN_ERROR);
|
|
734
|
+
}
|
|
735
|
+
async requestRefreshTokenAfterRegistration() {
|
|
736
|
+
return withPassportError(async () => {
|
|
737
|
+
const updatedUser = await retryWithDelay(async () => {
|
|
738
|
+
const user = await this.userManager.signinSilent();
|
|
739
|
+
const passportMetadata = user?.profile?.passport;
|
|
740
|
+
const metadataExists = !!passportMetadata?.ether_key &&
|
|
741
|
+
!!passportMetadata?.stark_key &&
|
|
742
|
+
!!passportMetadata?.user_admin_key;
|
|
743
|
+
if (metadataExists) {
|
|
744
|
+
return user;
|
|
745
|
+
}
|
|
746
|
+
return Promise.reject('user wallet addresses not exist');
|
|
747
|
+
});
|
|
748
|
+
if (!updatedUser) {
|
|
749
|
+
return null;
|
|
750
|
+
}
|
|
751
|
+
return this.mapOidcUserToDomainModel(updatedUser);
|
|
752
|
+
}, PassportErrorType.REFRESH_TOKEN_ERROR);
|
|
753
|
+
}
|
|
249
754
|
}
|
|
250
755
|
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
const starkSignature = await signers.starkExSigner.signMessage(payloadHash);
|
|
272
|
-
const resp = getSignableOrderResponse.data;
|
|
273
|
-
const orderParams = {
|
|
274
|
-
createOrderRequest: {
|
|
275
|
-
amount_buy: resp.amount_buy,
|
|
276
|
-
amount_sell: resp.amount_sell,
|
|
277
|
-
asset_id_buy: resp.asset_id_buy,
|
|
278
|
-
asset_id_sell: resp.asset_id_sell,
|
|
279
|
-
expiration_timestamp: resp.expiration_timestamp,
|
|
280
|
-
include_fees: true,
|
|
281
|
-
fees: request.fees,
|
|
282
|
-
nonce: resp.nonce,
|
|
283
|
-
stark_key: resp.stark_key,
|
|
284
|
-
stark_signature: starkSignature,
|
|
285
|
-
vault_id_buy: resp.vault_id_buy,
|
|
286
|
-
vault_id_sell: resp.vault_id_sell,
|
|
287
|
-
},
|
|
288
|
-
xImxEthAddress: ethAddress,
|
|
289
|
-
xImxEthSignature: ethSignature,
|
|
290
|
-
};
|
|
291
|
-
const createOrderResponse = await ordersApi.createOrder(orderParams);
|
|
292
|
-
return {
|
|
293
|
-
...createOrderResponse.data,
|
|
294
|
-
};
|
|
756
|
+
class MagicAdapter {
|
|
757
|
+
magicClient;
|
|
758
|
+
config;
|
|
759
|
+
constructor(config) {
|
|
760
|
+
this.config = config;
|
|
761
|
+
this.magicClient = new Magic(config.magicPublishableApiKey, {
|
|
762
|
+
network: config.network,
|
|
763
|
+
extensions: [new OpenIdExtension()],
|
|
764
|
+
});
|
|
765
|
+
}
|
|
766
|
+
async login(idToken) {
|
|
767
|
+
return withPassportError(async () => {
|
|
768
|
+
await this.magicClient.openid.loginWithOIDC({
|
|
769
|
+
jwt: idToken,
|
|
770
|
+
providerId: this.config.magicProviderId,
|
|
771
|
+
});
|
|
772
|
+
return new ethers.providers.Web3Provider(this.magicClient
|
|
773
|
+
.rpcProvider);
|
|
774
|
+
}, PassportErrorType.WALLET_CONNECTION_ERROR);
|
|
775
|
+
}
|
|
295
776
|
}
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
777
|
+
|
|
778
|
+
var ReceiveMessage;
|
|
779
|
+
(function (ReceiveMessage) {
|
|
780
|
+
ReceiveMessage["CONFIRMATION_WINDOW_READY"] = "confirmation_window_ready";
|
|
781
|
+
ReceiveMessage["TRANSACTION_CONFIRMED"] = "transaction_confirmed";
|
|
782
|
+
ReceiveMessage["TRANSACTION_ERROR"] = "transaction_error";
|
|
783
|
+
})(ReceiveMessage || (ReceiveMessage = {}));
|
|
784
|
+
var SendMessage;
|
|
785
|
+
(function (SendMessage) {
|
|
786
|
+
SendMessage["TRANSACTION_START"] = "transaction_start";
|
|
787
|
+
})(SendMessage || (SendMessage = {}));
|
|
788
|
+
var TransactionTypes;
|
|
789
|
+
(function (TransactionTypes) {
|
|
790
|
+
TransactionTypes["CancelOrder"] = "delete:v1/orders";
|
|
791
|
+
TransactionTypes["CreateOrder"] = "post:v1/orders";
|
|
792
|
+
TransactionTypes["CreateTrade"] = "post:v1/trades";
|
|
793
|
+
TransactionTypes["CreateTransfer"] = "post:v1/transfers";
|
|
794
|
+
TransactionTypes["CreateBatchTransfer"] = "post:v2/transfers";
|
|
795
|
+
})(TransactionTypes || (TransactionTypes = {}));
|
|
796
|
+
const PassportEventType = 'imx_passport_confirmation';
|
|
797
|
+
|
|
798
|
+
const openPopupCenter = ({ url, title, width, height, }) => {
|
|
799
|
+
const left = Math.max(0, Math.round(window.screenX + (window.outerWidth - width) / 2));
|
|
800
|
+
const top = Math.max(0, Math.round(window.screenY + (window.outerHeight - height) / 2));
|
|
801
|
+
const newWindow = window.open(url, title, `
|
|
802
|
+
scrollbars=yes,
|
|
803
|
+
width=${width},
|
|
804
|
+
height=${height},
|
|
805
|
+
top=${top},
|
|
806
|
+
left=${left}
|
|
807
|
+
`);
|
|
808
|
+
if (!newWindow) {
|
|
809
|
+
throw new Error('Failed to open confirmation screen');
|
|
810
|
+
}
|
|
811
|
+
newWindow.focus();
|
|
812
|
+
return newWindow;
|
|
813
|
+
};
|
|
814
|
+
|
|
815
|
+
const ConfirmationWindowTitle = 'Confirm this transaction';
|
|
816
|
+
const ConfirmationWindowHeight = 380;
|
|
817
|
+
const ConfirmationWindowWidth = 480;
|
|
818
|
+
const ConfirmationWindowClosedPollingDuration = 1000;
|
|
819
|
+
class ConfirmationScreen {
|
|
820
|
+
config;
|
|
821
|
+
constructor(config) {
|
|
822
|
+
this.config = config;
|
|
823
|
+
}
|
|
824
|
+
postMessage(destinationWindow, accessToken, message) {
|
|
825
|
+
destinationWindow.postMessage({
|
|
826
|
+
eventType: PassportEventType,
|
|
827
|
+
accessToken,
|
|
828
|
+
...message,
|
|
829
|
+
}, this.config.passportDomain);
|
|
830
|
+
}
|
|
831
|
+
startTransaction(accessToken, transaction, popupOptions) {
|
|
832
|
+
return new Promise((resolve, reject) => {
|
|
833
|
+
const messageHandler = ({ data, origin }) => {
|
|
834
|
+
if (origin != this.config.passportDomain ||
|
|
835
|
+
data.eventType != PassportEventType) {
|
|
836
|
+
return;
|
|
837
|
+
}
|
|
838
|
+
switch (data.messageType) {
|
|
839
|
+
case ReceiveMessage.CONFIRMATION_WINDOW_READY: {
|
|
840
|
+
this.postMessage(confirmationWindow, accessToken, {
|
|
841
|
+
messageType: SendMessage.TRANSACTION_START,
|
|
842
|
+
messageData: transaction,
|
|
843
|
+
});
|
|
844
|
+
break;
|
|
845
|
+
}
|
|
846
|
+
case ReceiveMessage.TRANSACTION_CONFIRMED: {
|
|
847
|
+
resolve({ confirmed: true });
|
|
848
|
+
break;
|
|
849
|
+
}
|
|
850
|
+
case ReceiveMessage.TRANSACTION_ERROR: {
|
|
851
|
+
reject(new Error('Transaction error'));
|
|
852
|
+
break;
|
|
853
|
+
}
|
|
854
|
+
default:
|
|
855
|
+
reject(new Error('Unsupported message type'));
|
|
856
|
+
}
|
|
857
|
+
};
|
|
858
|
+
window.addEventListener('message', messageHandler);
|
|
859
|
+
const confirmationWindow = openPopupCenter({
|
|
860
|
+
url: `${this.config.passportDomain}/transaction-confirmation`,
|
|
861
|
+
title: ConfirmationWindowTitle,
|
|
862
|
+
width: popupOptions?.width || ConfirmationWindowWidth,
|
|
863
|
+
height: popupOptions?.height || ConfirmationWindowHeight,
|
|
864
|
+
});
|
|
865
|
+
// https://stackoverflow.com/questions/9388380/capture-the-close-event-of-popup-window-in-javascript/48240128#48240128
|
|
866
|
+
const timer = setInterval(function () {
|
|
867
|
+
if (confirmationWindow.closed) {
|
|
868
|
+
clearInterval(timer);
|
|
869
|
+
window.removeEventListener('message', messageHandler);
|
|
870
|
+
resolve({ confirmed: false });
|
|
871
|
+
}
|
|
872
|
+
}, ConfirmationWindowClosedPollingDuration);
|
|
873
|
+
});
|
|
874
|
+
}
|
|
320
875
|
}
|
|
321
876
|
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
}
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
877
|
+
const ERC721$1 = 'ERC721';
|
|
878
|
+
const transfer$1 = ({ request, transfersApi, starkSigner, user, passportConfig, }) => {
|
|
879
|
+
return withPassportError(async () => {
|
|
880
|
+
const transferAmount = request.type === ERC721$1 ? '1' : request.amount;
|
|
881
|
+
const getSignableTransferRequest = {
|
|
882
|
+
sender: user.etherKey,
|
|
883
|
+
token: convertToSignableToken(request),
|
|
884
|
+
amount: transferAmount,
|
|
885
|
+
receiver: request.receiver,
|
|
886
|
+
};
|
|
887
|
+
const signableResult = await transfersApi.getSignableTransferV1({
|
|
888
|
+
getSignableTransferRequest,
|
|
889
|
+
});
|
|
890
|
+
const confirmationScreen = new ConfirmationScreen(passportConfig);
|
|
891
|
+
const confirmationResult = await confirmationScreen.startTransaction(user.accessToken, {
|
|
892
|
+
transactionType: TransactionTypes.CreateTransfer,
|
|
893
|
+
transactionData: getSignableTransferRequest,
|
|
894
|
+
});
|
|
895
|
+
if (!confirmationResult.confirmed) {
|
|
896
|
+
throw new Error('Transaction rejected by user');
|
|
897
|
+
}
|
|
898
|
+
const signableResultData = signableResult.data;
|
|
899
|
+
const { payload_hash: payloadHash } = signableResultData;
|
|
900
|
+
const starkSignature = await starkSigner.signMessage(payloadHash);
|
|
901
|
+
const senderStarkKey = await starkSigner.getAddress();
|
|
902
|
+
const transferSigningParams = {
|
|
903
|
+
sender_stark_key: signableResultData.sender_stark_key || senderStarkKey,
|
|
904
|
+
sender_vault_id: signableResultData.sender_vault_id,
|
|
905
|
+
receiver_stark_key: signableResultData.receiver_stark_key,
|
|
906
|
+
receiver_vault_id: signableResultData.receiver_vault_id,
|
|
907
|
+
asset_id: signableResultData.asset_id,
|
|
908
|
+
amount: signableResultData.amount,
|
|
909
|
+
nonce: signableResultData.nonce,
|
|
910
|
+
expiration_timestamp: signableResultData.expiration_timestamp,
|
|
340
911
|
stark_signature: starkSignature,
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
912
|
+
};
|
|
913
|
+
const createTransferRequest = {
|
|
914
|
+
createTransferRequest: transferSigningParams,
|
|
915
|
+
};
|
|
916
|
+
const headers = {
|
|
917
|
+
Authorization: 'Bearer ' + user.accessToken,
|
|
918
|
+
};
|
|
919
|
+
const { data: responseData } = await transfersApi.createTransferV1(createTransferRequest, { headers });
|
|
920
|
+
return {
|
|
921
|
+
sent_signature: responseData.sent_signature,
|
|
922
|
+
status: responseData.status?.toString(),
|
|
923
|
+
time: responseData.time,
|
|
924
|
+
transfer_id: responseData.transfer_id,
|
|
925
|
+
};
|
|
926
|
+
}, PassportErrorType.TRANSFER_ERROR);
|
|
927
|
+
};
|
|
928
|
+
async function batchNftTransfer({ user, starkSigner, request, transfersApi, passportConfig, }) {
|
|
929
|
+
return withPassportError(async () => {
|
|
930
|
+
const ethAddress = user.etherKey;
|
|
931
|
+
const signableRequests = request.map((nftTransfer) => {
|
|
932
|
+
return {
|
|
933
|
+
amount: '1',
|
|
934
|
+
token: convertToSignableToken({
|
|
935
|
+
type: ERC721$1,
|
|
936
|
+
tokenId: nftTransfer.tokenId,
|
|
937
|
+
tokenAddress: nftTransfer.tokenAddress,
|
|
938
|
+
}),
|
|
939
|
+
receiver: nftTransfer.receiver,
|
|
940
|
+
};
|
|
941
|
+
});
|
|
942
|
+
const getSignableTransferRequestV2 = {
|
|
943
|
+
sender_ether_key: ethAddress,
|
|
944
|
+
signable_requests: signableRequests,
|
|
945
|
+
};
|
|
946
|
+
const signableResult = await transfersApi.getSignableTransfer({
|
|
947
|
+
getSignableTransferRequestV2,
|
|
948
|
+
});
|
|
949
|
+
const confirmationScreen = new ConfirmationScreen(passportConfig);
|
|
950
|
+
const popupWindowSize = { width: 480, height: 784 };
|
|
951
|
+
const confirmationResult = await confirmationScreen.startTransaction(user.accessToken, {
|
|
952
|
+
transactionType: TransactionTypes.CreateBatchTransfer,
|
|
953
|
+
transactionData: getSignableTransferRequestV2,
|
|
954
|
+
}, popupWindowSize);
|
|
955
|
+
if (!confirmationResult.confirmed) {
|
|
956
|
+
throw new Error('Transaction rejected by user');
|
|
957
|
+
}
|
|
958
|
+
const requests = await Promise.all(signableResult.data.signable_responses.map(async (resp) => {
|
|
959
|
+
const starkSignature = await starkSigner.signMessage(resp.payload_hash);
|
|
960
|
+
return {
|
|
961
|
+
sender_vault_id: resp.sender_vault_id,
|
|
962
|
+
receiver_stark_key: resp.receiver_stark_key,
|
|
963
|
+
receiver_vault_id: resp.receiver_vault_id,
|
|
964
|
+
asset_id: resp.asset_id,
|
|
965
|
+
amount: resp.amount,
|
|
966
|
+
nonce: resp.nonce,
|
|
967
|
+
expiration_timestamp: resp.expiration_timestamp,
|
|
968
|
+
stark_signature: starkSignature,
|
|
969
|
+
};
|
|
970
|
+
}));
|
|
971
|
+
const transferSigningParams = {
|
|
972
|
+
sender_stark_key: signableResult.data.sender_stark_key,
|
|
973
|
+
requests,
|
|
974
|
+
};
|
|
975
|
+
const headers = {
|
|
976
|
+
Authorization: 'Bearer ' + user.accessToken,
|
|
977
|
+
};
|
|
978
|
+
const response = await transfersApi.createTransfer({
|
|
979
|
+
createTransferRequestV2: transferSigningParams,
|
|
980
|
+
}, { headers });
|
|
981
|
+
return {
|
|
982
|
+
transfer_ids: response?.data.transfer_ids,
|
|
983
|
+
};
|
|
984
|
+
}, PassportErrorType.TRANSFER_ERROR);
|
|
345
985
|
}
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
986
|
+
|
|
987
|
+
const ERC721 = 'ERC721';
|
|
988
|
+
async function createOrder$1({ starkSigner, user, request, ordersApi, passportConfig, }) {
|
|
989
|
+
return withPassportError(async () => {
|
|
990
|
+
const ethAddress = user.etherKey;
|
|
991
|
+
const amountSell = request.sell.type === ERC721 ? '1' : request.sell.amount;
|
|
992
|
+
const amountBuy = request.buy.type === ERC721 ? '1' : request.buy.amount;
|
|
993
|
+
const getSignableOrderRequestV3 = {
|
|
994
|
+
user: ethAddress,
|
|
995
|
+
amount_buy: amountBuy,
|
|
996
|
+
token_buy: convertToSignableToken(request.buy),
|
|
997
|
+
amount_sell: amountSell,
|
|
998
|
+
token_sell: convertToSignableToken(request.sell),
|
|
999
|
+
fees: request.fees,
|
|
1000
|
+
expiration_timestamp: request.expiration_timestamp,
|
|
1001
|
+
};
|
|
1002
|
+
const getSignableOrderResponse = await ordersApi.getSignableOrder({
|
|
1003
|
+
getSignableOrderRequestV3,
|
|
1004
|
+
});
|
|
1005
|
+
const confirmationScreen = new ConfirmationScreen(passportConfig);
|
|
1006
|
+
const confirmationResult = await confirmationScreen.startTransaction(user.accessToken, {
|
|
1007
|
+
transactionType: TransactionTypes.CreateOrder,
|
|
1008
|
+
transactionData: getSignableOrderRequestV3,
|
|
1009
|
+
});
|
|
1010
|
+
if (!confirmationResult.confirmed) {
|
|
1011
|
+
throw new Error('Transaction rejected by user');
|
|
355
1012
|
}
|
|
356
|
-
|
|
357
|
-
|
|
1013
|
+
const { payload_hash: payloadHash } = getSignableOrderResponse.data;
|
|
1014
|
+
const starkSignature = await starkSigner.signMessage(payloadHash);
|
|
1015
|
+
const signableResultData = getSignableOrderResponse.data;
|
|
1016
|
+
const orderParams = {
|
|
1017
|
+
createOrderRequest: {
|
|
1018
|
+
include_fees: true,
|
|
1019
|
+
fees: request.fees,
|
|
1020
|
+
stark_signature: starkSignature,
|
|
1021
|
+
amount_buy: signableResultData.amount_buy,
|
|
1022
|
+
amount_sell: signableResultData.amount_sell,
|
|
1023
|
+
asset_id_buy: signableResultData.asset_id_buy,
|
|
1024
|
+
asset_id_sell: signableResultData.asset_id_sell,
|
|
1025
|
+
expiration_timestamp: signableResultData.expiration_timestamp,
|
|
1026
|
+
nonce: signableResultData.nonce,
|
|
1027
|
+
stark_key: signableResultData.stark_key,
|
|
1028
|
+
vault_id_buy: signableResultData.vault_id_buy,
|
|
1029
|
+
vault_id_sell: signableResultData.vault_id_sell,
|
|
1030
|
+
},
|
|
1031
|
+
};
|
|
1032
|
+
const headers = {
|
|
1033
|
+
Authorization: 'Bearer ' + user.accessToken,
|
|
1034
|
+
};
|
|
1035
|
+
const createOrderResponse = await ordersApi.createOrder(orderParams, {
|
|
1036
|
+
headers,
|
|
1037
|
+
});
|
|
1038
|
+
return {
|
|
1039
|
+
...createOrderResponse.data,
|
|
1040
|
+
};
|
|
1041
|
+
}, PassportErrorType.CREATE_ORDER_ERROR);
|
|
358
1042
|
}
|
|
359
|
-
async function
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
1043
|
+
async function cancelOrder$1({ user, starkSigner, request, ordersApi, passportConfig, }) {
|
|
1044
|
+
return withPassportError(async () => {
|
|
1045
|
+
const getSignableCancelOrderRequest = {
|
|
1046
|
+
order_id: request.order_id,
|
|
1047
|
+
};
|
|
1048
|
+
const getSignableCancelOrderResponse = await ordersApi.getSignableCancelOrder({
|
|
1049
|
+
getSignableCancelOrderRequest,
|
|
1050
|
+
});
|
|
1051
|
+
const confirmationScreen = new ConfirmationScreen(passportConfig);
|
|
1052
|
+
const confirmationResult = await confirmationScreen.startTransaction(user.accessToken, {
|
|
1053
|
+
transactionType: TransactionTypes.CancelOrder,
|
|
1054
|
+
transactionData: getSignableCancelOrderRequest,
|
|
1055
|
+
});
|
|
1056
|
+
if (!confirmationResult.confirmed) {
|
|
1057
|
+
throw new Error('Transaction rejected by user');
|
|
1058
|
+
}
|
|
1059
|
+
const { payload_hash: payloadHash } = getSignableCancelOrderResponse.data;
|
|
1060
|
+
const starkSignature = await starkSigner.signMessage(payloadHash);
|
|
1061
|
+
const headers = {
|
|
1062
|
+
Authorization: 'Bearer ' + user.accessToken,
|
|
1063
|
+
};
|
|
1064
|
+
const cancelOrderResponse = await ordersApi.cancelOrder({
|
|
1065
|
+
id: request.order_id.toString(),
|
|
1066
|
+
cancelOrderRequest: {
|
|
1067
|
+
order_id: request.order_id,
|
|
1068
|
+
stark_signature: starkSignature,
|
|
1069
|
+
},
|
|
1070
|
+
}, { headers });
|
|
1071
|
+
return {
|
|
1072
|
+
order_id: cancelOrderResponse.data.order_id,
|
|
1073
|
+
status: cancelOrderResponse.data.status,
|
|
1074
|
+
};
|
|
1075
|
+
}, PassportErrorType.CANCEL_ORDER_ERROR);
|
|
370
1076
|
}
|
|
371
1077
|
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
vault_id: assertIsDefined(signableWithdrawalResult.data.vault_id),
|
|
398
|
-
nonce: assertIsDefined(signableWithdrawalResult.data.nonce),
|
|
1078
|
+
async function exchangeTransfer$1({ user, starkSigner, request, exchangesApi, }) {
|
|
1079
|
+
return withPassportError(async () => {
|
|
1080
|
+
const ethAddress = user.etherKey;
|
|
1081
|
+
const transferAmount = request.amount;
|
|
1082
|
+
const signableResult = await exchangesApi.getExchangeSignableTransfer({
|
|
1083
|
+
id: request.transactionID,
|
|
1084
|
+
getSignableTransferRequest: {
|
|
1085
|
+
sender: ethAddress,
|
|
1086
|
+
token: convertToSignableToken(request),
|
|
1087
|
+
amount: transferAmount,
|
|
1088
|
+
receiver: request.receiver,
|
|
1089
|
+
},
|
|
1090
|
+
});
|
|
1091
|
+
const starkAddress = await starkSigner.getAddress();
|
|
1092
|
+
const { payload_hash: payloadHash } = signableResult.data;
|
|
1093
|
+
const starkSignature = await starkSigner.signMessage(payloadHash);
|
|
1094
|
+
const transferSigningParams = {
|
|
1095
|
+
sender_stark_key: signableResult.data.sender_stark_key || starkAddress,
|
|
1096
|
+
sender_vault_id: signableResult.data.sender_vault_id,
|
|
1097
|
+
receiver_stark_key: signableResult.data.receiver_stark_key,
|
|
1098
|
+
receiver_vault_id: signableResult.data.receiver_vault_id,
|
|
1099
|
+
asset_id: signableResult.data.asset_id,
|
|
1100
|
+
amount: signableResult.data.amount,
|
|
1101
|
+
nonce: signableResult.data.nonce,
|
|
1102
|
+
expiration_timestamp: signableResult.data.expiration_timestamp,
|
|
399
1103
|
stark_signature: starkSignature,
|
|
400
|
-
}
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
1104
|
+
};
|
|
1105
|
+
const headers = {
|
|
1106
|
+
Authorization: 'Bearer ' + user.accessToken,
|
|
1107
|
+
};
|
|
1108
|
+
const response = await exchangesApi.createExchangeTransfer({
|
|
1109
|
+
id: request.transactionID,
|
|
1110
|
+
createTransferRequest: transferSigningParams,
|
|
1111
|
+
}, { headers });
|
|
1112
|
+
return {
|
|
1113
|
+
sent_signature: response?.data.sent_signature,
|
|
1114
|
+
status: response?.data.status?.toString(),
|
|
1115
|
+
time: response?.data.time,
|
|
1116
|
+
transfer_id: response?.data.transfer_id,
|
|
1117
|
+
};
|
|
1118
|
+
}, PassportErrorType.EXCHANGE_TRANSFER_ERROR);
|
|
405
1119
|
}
|
|
406
1120
|
|
|
407
|
-
async function
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
1121
|
+
async function createTrade$1({ request, tradesApi, user, starkSigner, passportConfig, }) {
|
|
1122
|
+
return withPassportError(async () => {
|
|
1123
|
+
const ethAddress = user.etherKey;
|
|
1124
|
+
const getSignableTradeRequest = {
|
|
1125
|
+
expiration_timestamp: request.expiration_timestamp,
|
|
1126
|
+
fees: request.fees,
|
|
1127
|
+
order_id: request.order_id,
|
|
1128
|
+
user: ethAddress,
|
|
1129
|
+
};
|
|
1130
|
+
const getSignableTradeResponse = await tradesApi.getSignableTrade({
|
|
1131
|
+
getSignableTradeRequest,
|
|
1132
|
+
});
|
|
1133
|
+
const confirmationScreen = new ConfirmationScreen(passportConfig);
|
|
1134
|
+
const confirmationResult = await confirmationScreen.startTransaction(user.accessToken, {
|
|
1135
|
+
transactionType: TransactionTypes.CreateTrade,
|
|
1136
|
+
transactionData: getSignableTradeRequest,
|
|
1137
|
+
});
|
|
1138
|
+
if (!confirmationResult.confirmed) {
|
|
1139
|
+
throw new Error('Transaction rejected by user');
|
|
1140
|
+
}
|
|
1141
|
+
const { payload_hash: payloadHash } = getSignableTradeResponse.data;
|
|
1142
|
+
const starkSignature = await starkSigner.signMessage(payloadHash);
|
|
1143
|
+
const { data: signableResultData } = getSignableTradeResponse;
|
|
1144
|
+
const tradeParams = {
|
|
1145
|
+
createTradeRequest: {
|
|
1146
|
+
include_fees: true,
|
|
1147
|
+
fees: request?.fees,
|
|
1148
|
+
stark_signature: starkSignature,
|
|
1149
|
+
order_id: request?.order_id,
|
|
1150
|
+
fee_info: signableResultData.fee_info,
|
|
1151
|
+
amount_buy: signableResultData.amount_buy,
|
|
1152
|
+
amount_sell: signableResultData.amount_sell,
|
|
1153
|
+
asset_id_buy: signableResultData.asset_id_buy,
|
|
1154
|
+
asset_id_sell: signableResultData.asset_id_sell,
|
|
1155
|
+
expiration_timestamp: signableResultData.expiration_timestamp,
|
|
1156
|
+
nonce: signableResultData.nonce,
|
|
1157
|
+
stark_key: signableResultData.stark_key,
|
|
1158
|
+
vault_id_buy: signableResultData.vault_id_buy,
|
|
1159
|
+
vault_id_sell: signableResultData.vault_id_sell,
|
|
415
1160
|
},
|
|
416
|
-
}
|
|
417
|
-
|
|
418
|
-
|
|
1161
|
+
};
|
|
1162
|
+
const headers = { Authorization: 'Bearer ' + user.accessToken };
|
|
1163
|
+
const { data: createTradeResponse } = await tradesApi.createTradeV3(tradeParams, {
|
|
1164
|
+
headers,
|
|
1165
|
+
});
|
|
1166
|
+
return createTradeResponse;
|
|
1167
|
+
}, PassportErrorType.CREATE_TRADE_ERROR);
|
|
419
1168
|
}
|
|
420
1169
|
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
}
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
async function completeERC20WithdrawalAction({ ethSigner, starkPublicKey, token, config, }) {
|
|
436
|
-
await validateChain(ethSigner, config.immutableXConfig);
|
|
437
|
-
const starkExConfig = config.immutableXConfig;
|
|
438
|
-
const assetType = await getEncodeAssetInfo('asset', 'ERC20', starkExConfig, {
|
|
439
|
-
token_address: token.tokenAddress,
|
|
440
|
-
});
|
|
441
|
-
const isRegistered = await isRegisteredOnChain(starkPublicKey, ethSigner, config);
|
|
442
|
-
if (!isRegistered) {
|
|
443
|
-
return executeRegisterAndWithdrawERC20({
|
|
444
|
-
ethSigner,
|
|
445
|
-
assetType: assetType.asset_type,
|
|
446
|
-
starkPublicKey,
|
|
447
|
-
config,
|
|
1170
|
+
class PassportImxProvider {
|
|
1171
|
+
user;
|
|
1172
|
+
starkSigner;
|
|
1173
|
+
transfersApi;
|
|
1174
|
+
ordersApi;
|
|
1175
|
+
passportConfig;
|
|
1176
|
+
exchangesApi;
|
|
1177
|
+
tradesApi;
|
|
1178
|
+
constructor({ user, starkSigner, passportConfig }) {
|
|
1179
|
+
this.user = user;
|
|
1180
|
+
this.starkSigner = starkSigner;
|
|
1181
|
+
this.passportConfig = passportConfig;
|
|
1182
|
+
const apiConfig = new Configuration({
|
|
1183
|
+
basePath: passportConfig.imxApiBasePath,
|
|
448
1184
|
});
|
|
1185
|
+
this.transfersApi = new TransfersApi(apiConfig);
|
|
1186
|
+
this.ordersApi = new OrdersApi(apiConfig);
|
|
1187
|
+
this.exchangesApi = new ExchangesApi(apiConfig);
|
|
1188
|
+
this.tradesApi = new TradesApi(apiConfig);
|
|
449
1189
|
}
|
|
450
|
-
|
|
451
|
-
return
|
|
1190
|
+
async transfer(request) {
|
|
1191
|
+
return transfer$1({
|
|
1192
|
+
request,
|
|
1193
|
+
user: this.user,
|
|
1194
|
+
starkSigner: this.starkSigner,
|
|
1195
|
+
transfersApi: this.transfersApi,
|
|
1196
|
+
passportConfig: this.passportConfig,
|
|
1197
|
+
});
|
|
452
1198
|
}
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
async function executeWithdrawMintableERC721(ethSigner, assetType, starkPublicKey, mintingBlob, config) {
|
|
456
|
-
const contract = Contracts.Core.connect(config.ethConfiguration.coreContractAddress, ethSigner);
|
|
457
|
-
const populatedTransaction = await contract.populateTransaction.withdrawAndMint(starkPublicKey, assetType, mintingBlob);
|
|
458
|
-
return ethSigner.sendTransaction(populatedTransaction);
|
|
459
|
-
}
|
|
460
|
-
async function executeRegisterAndWithdrawMintableERC721(ethSigner, assetType, starkPublicKey, mintingBlob, config) {
|
|
461
|
-
const etherKey = await ethSigner.getAddress();
|
|
462
|
-
const usersApi = new UsersApi(config.apiConfiguration);
|
|
463
|
-
const signableResult = await getSignableRegistrationOnchain(etherKey, starkPublicKey, usersApi);
|
|
464
|
-
const contract = Contracts.Registration.connect(config.ethConfiguration.registrationContractAddress, ethSigner);
|
|
465
|
-
const populatedTransaction = await contract.populateTransaction.regsiterAndWithdrawAndMint(etherKey, starkPublicKey, signableResult.operator_signature, assetType, mintingBlob);
|
|
466
|
-
return ethSigner.sendTransaction(populatedTransaction);
|
|
467
|
-
}
|
|
468
|
-
function getMintingBlob(token) {
|
|
469
|
-
const id = token.data.id;
|
|
470
|
-
const blueprint = token.data.blueprint || '';
|
|
471
|
-
return encUtils.sanitizeHex(encUtils.utf8ToHex(`{${id}}:{${blueprint}}`));
|
|
472
|
-
}
|
|
473
|
-
async function completeMintableERC721Withdrawal(ethSigner, starkPublicKey, token, config) {
|
|
474
|
-
const starkExConfig = config.immutableXConfig;
|
|
475
|
-
const assetType = await getEncodeAssetInfo('mintable-asset', 'ERC721', starkExConfig, {
|
|
476
|
-
id: token.data.id,
|
|
477
|
-
token_address: token.data.tokenAddress,
|
|
478
|
-
...(token.data.blueprint && { blueprint: token.data.blueprint }),
|
|
479
|
-
});
|
|
480
|
-
const mintingBlob = getMintingBlob(token);
|
|
481
|
-
const isRegistered = await isRegisteredOnChain(starkPublicKey, ethSigner, config);
|
|
482
|
-
if (!isRegistered) {
|
|
483
|
-
return executeRegisterAndWithdrawMintableERC721(ethSigner, assetType.asset_type, starkPublicKey, mintingBlob, starkExConfig);
|
|
1199
|
+
registerOffchain() {
|
|
1200
|
+
throw new PassportError('Operation not supported', PassportErrorType.OPERATION_NOT_SUPPORTED_ERROR);
|
|
484
1201
|
}
|
|
485
|
-
|
|
486
|
-
|
|
1202
|
+
isRegisteredOnchain() {
|
|
1203
|
+
throw new PassportError('Operation not supported', PassportErrorType.OPERATION_NOT_SUPPORTED_ERROR);
|
|
1204
|
+
}
|
|
1205
|
+
createOrder(request) {
|
|
1206
|
+
return createOrder$1({
|
|
1207
|
+
request,
|
|
1208
|
+
user: this.user,
|
|
1209
|
+
starkSigner: this.starkSigner,
|
|
1210
|
+
ordersApi: this.ordersApi,
|
|
1211
|
+
passportConfig: this.passportConfig,
|
|
1212
|
+
});
|
|
1213
|
+
}
|
|
1214
|
+
cancelOrder(request) {
|
|
1215
|
+
return cancelOrder$1({
|
|
1216
|
+
request,
|
|
1217
|
+
user: this.user,
|
|
1218
|
+
starkSigner: this.starkSigner,
|
|
1219
|
+
ordersApi: this.ordersApi,
|
|
1220
|
+
passportConfig: this.passportConfig,
|
|
1221
|
+
});
|
|
1222
|
+
}
|
|
1223
|
+
createTrade(request) {
|
|
1224
|
+
return createTrade$1({
|
|
1225
|
+
request,
|
|
1226
|
+
user: this.user,
|
|
1227
|
+
starkSigner: this.starkSigner,
|
|
1228
|
+
tradesApi: this.tradesApi,
|
|
1229
|
+
passportConfig: this.passportConfig,
|
|
1230
|
+
});
|
|
1231
|
+
}
|
|
1232
|
+
batchNftTransfer(request) {
|
|
1233
|
+
return batchNftTransfer({
|
|
1234
|
+
request,
|
|
1235
|
+
user: this.user,
|
|
1236
|
+
starkSigner: this.starkSigner,
|
|
1237
|
+
transfersApi: this.transfersApi,
|
|
1238
|
+
passportConfig: this.passportConfig,
|
|
1239
|
+
});
|
|
487
1240
|
}
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
return ethSigner.sendTransaction(populatedTransaction);
|
|
496
|
-
}
|
|
497
|
-
async function executeWithdrawERC721(ethSigner, assetType, starkPublicKey, tokenId, config) {
|
|
498
|
-
const contract = Contracts.Core.connect(config.ethConfiguration.coreContractAddress, ethSigner);
|
|
499
|
-
const populatedTransaction = await contract.populateTransaction.withdrawNft(starkPublicKey, assetType, tokenId);
|
|
500
|
-
return ethSigner.sendTransaction(populatedTransaction);
|
|
501
|
-
}
|
|
502
|
-
async function completeERC721Withdrawal(ethSigner, starkPublicKey, token, config) {
|
|
503
|
-
const starkExConfig = config.immutableXConfig;
|
|
504
|
-
const assetType = await getEncodeAssetInfo('asset', 'ERC721', starkExConfig, {
|
|
505
|
-
token_id: token.tokenId,
|
|
506
|
-
token_address: token.tokenAddress,
|
|
507
|
-
});
|
|
508
|
-
const isRegistered = await isRegisteredOnChain(starkPublicKey, ethSigner, config);
|
|
509
|
-
if (!isRegistered) {
|
|
510
|
-
return executeRegisterAndWithdrawERC721(ethSigner, assetType.asset_type, starkPublicKey, token.tokenId, starkExConfig);
|
|
1241
|
+
exchangeTransfer(request) {
|
|
1242
|
+
return exchangeTransfer$1({
|
|
1243
|
+
request,
|
|
1244
|
+
user: this.user,
|
|
1245
|
+
starkSigner: this.starkSigner,
|
|
1246
|
+
exchangesApi: this.exchangesApi,
|
|
1247
|
+
});
|
|
511
1248
|
}
|
|
512
|
-
|
|
513
|
-
|
|
1249
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
1250
|
+
deposit(deposit) {
|
|
1251
|
+
throw new PassportError('Operation not supported', PassportErrorType.OPERATION_NOT_SUPPORTED_ERROR);
|
|
514
1252
|
}
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
const tokenAddress = token.tokenAddress;
|
|
519
|
-
const tokenId = token.tokenId;
|
|
520
|
-
const starkExConfig = config.immutableXConfig;
|
|
521
|
-
const mintsApi = new MintsApi(starkExConfig.apiConfiguration);
|
|
522
|
-
return await mintsApi
|
|
523
|
-
.getMintableTokenDetailsByClientTokenId({
|
|
524
|
-
tokenAddress,
|
|
525
|
-
tokenId,
|
|
526
|
-
})
|
|
527
|
-
.then((mintableToken) => completeMintableERC721Withdrawal(ethSigner, starkPublicKey, {
|
|
528
|
-
type: 'ERC721',
|
|
529
|
-
data: {
|
|
530
|
-
id: tokenId,
|
|
531
|
-
tokenAddress: tokenAddress,
|
|
532
|
-
blueprint: mintableToken.data.blueprint,
|
|
533
|
-
},
|
|
534
|
-
}, config))
|
|
535
|
-
.catch((error) => {
|
|
536
|
-
if (error.response?.status === 404) {
|
|
537
|
-
// token is already minted on L1
|
|
538
|
-
return completeERC721Withdrawal(ethSigner, starkPublicKey, token, config);
|
|
539
|
-
}
|
|
540
|
-
throw error; // unable to recover from any other kind of error
|
|
541
|
-
});
|
|
542
|
-
}
|
|
543
|
-
|
|
544
|
-
async function executeRegisterAndWithdrawEth(ethSigner, assetType, starkPublicKey, config) {
|
|
545
|
-
const etherKey = await ethSigner.getAddress();
|
|
546
|
-
const usersApi = new UsersApi(config.apiConfiguration);
|
|
547
|
-
const signableResult = await getSignableRegistrationOnchain(etherKey, starkPublicKey, usersApi);
|
|
548
|
-
const contract = Contracts.Registration.connect(config.ethConfiguration.registrationContractAddress, ethSigner);
|
|
549
|
-
const populatedTransaction = await contract.populateTransaction.registerAndWithdraw(etherKey, starkPublicKey, signableResult.operator_signature, assetType);
|
|
550
|
-
return ethSigner.sendTransaction(populatedTransaction);
|
|
551
|
-
}
|
|
552
|
-
async function executeWithdrawEth(ethSigner, assetType, starkPublicKey, config) {
|
|
553
|
-
const contract = Contracts.Core.connect(config.ethConfiguration.coreContractAddress, ethSigner);
|
|
554
|
-
const populatedTransaction = await contract.populateTransaction.withdraw(starkPublicKey, assetType);
|
|
555
|
-
return ethSigner.sendTransaction(populatedTransaction);
|
|
556
|
-
}
|
|
557
|
-
async function completeEthWithdrawalAction({ ethSigner, starkPublicKey, config, }) {
|
|
558
|
-
await validateChain(ethSigner, config.immutableXConfig);
|
|
559
|
-
const starkExConfig = config.immutableXConfig;
|
|
560
|
-
const assetType = await getEncodeAssetInfo('asset', 'ETH', starkExConfig);
|
|
561
|
-
const isRegistered = await isRegisteredOnChain(starkPublicKey, ethSigner, config);
|
|
562
|
-
if (!isRegistered) {
|
|
563
|
-
return executeRegisterAndWithdrawEth(ethSigner, assetType.asset_type, starkPublicKey, starkExConfig);
|
|
1253
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
1254
|
+
prepareWithdrawal(request) {
|
|
1255
|
+
throw new PassportError('Operation not supported', PassportErrorType.OPERATION_NOT_SUPPORTED_ERROR);
|
|
564
1256
|
}
|
|
565
|
-
|
|
566
|
-
|
|
1257
|
+
completeWithdrawal(
|
|
1258
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
1259
|
+
starkPublicKey,
|
|
1260
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
1261
|
+
token) {
|
|
1262
|
+
throw new PassportError('Operation not supported', PassportErrorType.OPERATION_NOT_SUPPORTED_ERROR);
|
|
567
1263
|
}
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
async function prepareWithdrawal({ signers, withdrawal, config, }) {
|
|
571
|
-
return prepareWithdrawalAction({
|
|
572
|
-
signers,
|
|
573
|
-
config: config.immutableXConfig,
|
|
574
|
-
...withdrawal,
|
|
575
|
-
});
|
|
576
|
-
}
|
|
577
|
-
async function completeWithdrawal({ signers: { ethSigner }, starkPublicKey, token, config, }) {
|
|
578
|
-
switch (token.type) {
|
|
579
|
-
case 'ETH':
|
|
580
|
-
return completeEthWithdrawalAction({ ethSigner, starkPublicKey, config });
|
|
581
|
-
case 'ERC20':
|
|
582
|
-
return completeERC20WithdrawalAction({
|
|
583
|
-
ethSigner,
|
|
584
|
-
starkPublicKey,
|
|
585
|
-
token,
|
|
586
|
-
config,
|
|
587
|
-
});
|
|
588
|
-
case 'ERC721':
|
|
589
|
-
return completeERC721WithdrawalAction({
|
|
590
|
-
ethSigner,
|
|
591
|
-
starkPublicKey,
|
|
592
|
-
token,
|
|
593
|
-
config,
|
|
594
|
-
});
|
|
1264
|
+
getAddress() {
|
|
1265
|
+
return Promise.resolve(this.starkSigner.getAddress());
|
|
595
1266
|
}
|
|
596
1267
|
}
|
|
597
1268
|
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
getSignableTradeRequest: {
|
|
604
|
-
user: ethAddress,
|
|
605
|
-
order_id: request.order_id,
|
|
606
|
-
fees: request.fees,
|
|
607
|
-
},
|
|
608
|
-
});
|
|
609
|
-
const { signable_message: signableMessage, payload_hash: payloadHash } = signableResult.data;
|
|
610
|
-
const ethSignature = await signRaw(signableMessage, ethSigner);
|
|
611
|
-
const starkSignature = await starkExSigner.signMessage(payloadHash);
|
|
612
|
-
const createTradeResponse = await tradesApi.createTrade({
|
|
613
|
-
createTradeRequest: {
|
|
614
|
-
amount_buy: signableResult.data.amount_buy,
|
|
615
|
-
amount_sell: signableResult.data.amount_sell,
|
|
616
|
-
asset_id_buy: signableResult.data.asset_id_buy,
|
|
617
|
-
asset_id_sell: signableResult.data.asset_id_sell,
|
|
618
|
-
expiration_timestamp: signableResult.data.expiration_timestamp,
|
|
619
|
-
fee_info: signableResult.data.fee_info,
|
|
620
|
-
fees: request.fees,
|
|
621
|
-
include_fees: true,
|
|
622
|
-
nonce: signableResult.data.nonce,
|
|
623
|
-
order_id: request.order_id,
|
|
624
|
-
stark_key: signableResult.data.stark_key,
|
|
625
|
-
vault_id_buy: signableResult.data.vault_id_buy,
|
|
626
|
-
vault_id_sell: signableResult.data.vault_id_sell,
|
|
627
|
-
stark_signature: starkSignature,
|
|
628
|
-
},
|
|
629
|
-
xImxEthAddress: ethAddress,
|
|
630
|
-
xImxEthSignature: ethSignature,
|
|
631
|
-
});
|
|
632
|
-
return createTradeResponse.data;
|
|
633
|
-
}
|
|
1269
|
+
var Networks;
|
|
1270
|
+
(function (Networks) {
|
|
1271
|
+
Networks["PRODUCTION"] = "mainnet";
|
|
1272
|
+
Networks["SANDBOX"] = "goerli";
|
|
1273
|
+
})(Networks || (Networks = {}));
|
|
634
1274
|
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
const usersApi = new UsersApi(starkExConfig.apiConfiguration);
|
|
646
|
-
const getSignableDepositRequest = {
|
|
647
|
-
user,
|
|
648
|
-
token: {
|
|
649
|
-
type: deposit.type,
|
|
650
|
-
data,
|
|
651
|
-
},
|
|
652
|
-
amount: amount.toString(),
|
|
653
|
-
};
|
|
654
|
-
const signableDepositResult = await depositsApi.getSignableDeposit({
|
|
655
|
-
getSignableDepositRequest,
|
|
656
|
-
});
|
|
657
|
-
const encodingResult = await encodingApi.encodeAsset({
|
|
658
|
-
assetType: 'asset',
|
|
659
|
-
encodeAssetRequest: {
|
|
660
|
-
token: {
|
|
661
|
-
type: deposit.type,
|
|
662
|
-
},
|
|
663
|
-
},
|
|
664
|
-
});
|
|
665
|
-
const assetType = encodingResult.data.asset_type;
|
|
666
|
-
const starkPublicKey = signableDepositResult.data.stark_key;
|
|
667
|
-
const vaultId = signableDepositResult.data.vault_id;
|
|
668
|
-
const isRegistered = await isRegisteredOnChain(starkPublicKey, ethSigner, config);
|
|
669
|
-
if (!isRegistered) {
|
|
670
|
-
return executeRegisterAndDepositEth(ethSigner, amount, assetType, starkPublicKey, vaultId, starkExConfig, usersApi);
|
|
1275
|
+
const validateConfiguration = (configuration, requiredKeys, prefix) => {
|
|
1276
|
+
const missingKeys = requiredKeys
|
|
1277
|
+
.map((key) => !configuration[key] && key)
|
|
1278
|
+
.filter((n) => n)
|
|
1279
|
+
.join(', ');
|
|
1280
|
+
if (missingKeys !== '') {
|
|
1281
|
+
const errorMessage = prefix
|
|
1282
|
+
? `${prefix} - ${missingKeys} cannot be null`
|
|
1283
|
+
: `${missingKeys} cannot be null`;
|
|
1284
|
+
throw new PassportError(errorMessage, PassportErrorType.INVALID_CONFIGURATION);
|
|
671
1285
|
}
|
|
672
|
-
|
|
673
|
-
|
|
1286
|
+
};
|
|
1287
|
+
class PassportConfiguration {
|
|
1288
|
+
network;
|
|
1289
|
+
authenticationDomain;
|
|
1290
|
+
passportDomain;
|
|
1291
|
+
magicPublishableApiKey;
|
|
1292
|
+
magicProviderId;
|
|
1293
|
+
imxApiBasePath;
|
|
1294
|
+
oidcConfiguration;
|
|
1295
|
+
baseConfig;
|
|
1296
|
+
constructor({ baseConfig, overrides, ...oidcConfiguration }) {
|
|
1297
|
+
validateConfiguration(oidcConfiguration, [
|
|
1298
|
+
'clientId',
|
|
1299
|
+
'logoutRedirectUri',
|
|
1300
|
+
'redirectUri',
|
|
1301
|
+
]);
|
|
1302
|
+
this.oidcConfiguration = oidcConfiguration;
|
|
1303
|
+
this.baseConfig = baseConfig;
|
|
1304
|
+
if (overrides) {
|
|
1305
|
+
validateConfiguration(overrides, [
|
|
1306
|
+
'network',
|
|
1307
|
+
'authenticationDomain',
|
|
1308
|
+
'magicPublishableApiKey',
|
|
1309
|
+
'magicProviderId',
|
|
1310
|
+
'passportDomain',
|
|
1311
|
+
'imxApiBasePath',
|
|
1312
|
+
], 'overrides');
|
|
1313
|
+
this.network = overrides.network;
|
|
1314
|
+
this.authenticationDomain = overrides.authenticationDomain;
|
|
1315
|
+
this.passportDomain = overrides.passportDomain;
|
|
1316
|
+
this.magicPublishableApiKey = overrides.magicPublishableApiKey;
|
|
1317
|
+
this.magicProviderId = overrides.magicProviderId;
|
|
1318
|
+
this.imxApiBasePath = overrides.imxApiBasePath;
|
|
1319
|
+
}
|
|
1320
|
+
else {
|
|
1321
|
+
switch (baseConfig.environment) {
|
|
1322
|
+
case Environment.SANDBOX: {
|
|
1323
|
+
this.network = Networks.SANDBOX;
|
|
1324
|
+
this.authenticationDomain = 'https://auth.immutable.com';
|
|
1325
|
+
this.magicPublishableApiKey = 'pk_live_10F423798A540ED7';
|
|
1326
|
+
this.magicProviderId = 'fSMzaRQ4O7p4fttl7pCyGVtJS_G70P8SNsLXtPPGHo0=';
|
|
1327
|
+
this.passportDomain = 'https://passport.sandbox.immutable.com';
|
|
1328
|
+
this.imxApiBasePath = 'https://api.sandbox.x.immutable.com';
|
|
1329
|
+
break;
|
|
1330
|
+
}
|
|
1331
|
+
case Environment.PRODUCTION: {
|
|
1332
|
+
this.network = Networks.PRODUCTION;
|
|
1333
|
+
this.authenticationDomain = 'https://auth.immutable.com';
|
|
1334
|
+
this.magicPublishableApiKey = 'pk_live_10F423798A540ED7';
|
|
1335
|
+
this.magicProviderId = 'fSMzaRQ4O7p4fttl7pCyGVtJS_G70P8SNsLXtPPGHo0=';
|
|
1336
|
+
this.passportDomain = 'https://passport.immutable.com';
|
|
1337
|
+
this.imxApiBasePath = 'https://api.x.immutable.com';
|
|
1338
|
+
break;
|
|
1339
|
+
}
|
|
1340
|
+
}
|
|
1341
|
+
}
|
|
674
1342
|
}
|
|
675
1343
|
}
|
|
676
|
-
async function executeRegisterAndDepositEth(ethSigner, amount, assetType, starkPublicKey, vaultId, config, usersApi) {
|
|
677
|
-
const etherKey = await ethSigner.getAddress();
|
|
678
|
-
const coreContract = Contracts.Core.connect(config.ethConfiguration.coreContractAddress, ethSigner);
|
|
679
|
-
const signableResult = await getSignableRegistrationOnchain(etherKey, starkPublicKey, usersApi);
|
|
680
|
-
const populatedTransaction = await coreContract.populateTransaction.registerAndDepositEth(etherKey, starkPublicKey, signableResult.operator_signature, assetType, vaultId);
|
|
681
|
-
return ethSigner.sendTransaction({ ...populatedTransaction, value: amount });
|
|
682
|
-
}
|
|
683
|
-
async function executeDepositEth(ethSigner, amount, assetType, starkPublicKey, vaultId, config) {
|
|
684
|
-
const coreContract = Contracts.Core.connect(config.ethConfiguration.coreContractAddress, ethSigner);
|
|
685
|
-
const populatedTransaction = await coreContract.populateTransaction['deposit(uint256,uint256,uint256)'](starkPublicKey, assetType, vaultId);
|
|
686
|
-
return ethSigner.sendTransaction({ ...populatedTransaction, value: amount });
|
|
687
|
-
}
|
|
688
1344
|
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
const amount = parseUnits(deposit.amount, 0); // 0 to always use undecimalized value
|
|
705
|
-
// Approve whether an amount of token from an account can be spent by a third-party account
|
|
706
|
-
const tokenContract = Contracts.IERC20.connect(deposit.tokenAddress, ethSigner);
|
|
707
|
-
const approveTransaction = await tokenContract.populateTransaction.approve(ethConfiguration.coreContractAddress, amount);
|
|
708
|
-
await ethSigner.sendTransaction(approveTransaction);
|
|
709
|
-
const getSignableDepositRequest = {
|
|
710
|
-
user,
|
|
711
|
-
token: {
|
|
712
|
-
type: deposit.type,
|
|
713
|
-
data,
|
|
714
|
-
},
|
|
715
|
-
amount: amount.toString(),
|
|
716
|
-
};
|
|
717
|
-
const signableDepositResult = await depositsApi.getSignableDeposit({
|
|
718
|
-
getSignableDepositRequest,
|
|
719
|
-
});
|
|
720
|
-
// Perform encoding on asset details to get an assetType (required for stark contract request)
|
|
721
|
-
const encodingResult = await encodingApi.encodeAsset({
|
|
722
|
-
assetType: 'asset',
|
|
723
|
-
encodeAssetRequest: {
|
|
724
|
-
token: {
|
|
725
|
-
type: deposit.type,
|
|
726
|
-
data: {
|
|
727
|
-
token_address: deposit.tokenAddress,
|
|
728
|
-
},
|
|
1345
|
+
const getStarkSigner = async (signer) => {
|
|
1346
|
+
return withPassportError(async () => {
|
|
1347
|
+
const privateKey = await generateLegacyStarkPrivateKey(signer);
|
|
1348
|
+
return createStarkSigner(privateKey);
|
|
1349
|
+
}, PassportErrorType.WALLET_CONNECTION_ERROR);
|
|
1350
|
+
};
|
|
1351
|
+
|
|
1352
|
+
async function registerPassport({ ethSigner, starkSigner, usersApi }, authorization) {
|
|
1353
|
+
return withPassportError(async () => {
|
|
1354
|
+
const userAddress = await ethSigner.getAddress();
|
|
1355
|
+
const starkPublicKey = await starkSigner.getAddress();
|
|
1356
|
+
const signableResult = await usersApi.getSignableRegistrationOffchain({
|
|
1357
|
+
getSignableRegistrationRequest: {
|
|
1358
|
+
ether_key: userAddress,
|
|
1359
|
+
stark_key: starkPublicKey,
|
|
729
1360
|
},
|
|
730
|
-
}
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
const coreContract = Contracts.Core.connect(config.coreContractAddress, ethSigner);
|
|
746
|
-
const populatedTransaction = await coreContract.populateTransaction.depositERC20(starkPublicKey, assetType, vaultId, quantizedAmount);
|
|
747
|
-
return ethSigner.sendTransaction(populatedTransaction);
|
|
748
|
-
}
|
|
749
|
-
async function executeRegisterAndDepositERC20(ethSigner, quantizedAmount, assetType, starkPublicKey, vaultId, config, usersApi) {
|
|
750
|
-
const etherKey = await ethSigner.getAddress();
|
|
751
|
-
const coreContract = Contracts.Core.connect(config.coreContractAddress, ethSigner);
|
|
752
|
-
const signableResult = await getSignableRegistrationOnchain(etherKey, starkPublicKey, usersApi);
|
|
753
|
-
const populatedTransaction = await coreContract.populateTransaction.registerAndDepositERC20(etherKey, starkPublicKey, signableResult.operator_signature, assetType, vaultId, quantizedAmount);
|
|
754
|
-
return ethSigner.sendTransaction(populatedTransaction);
|
|
1361
|
+
});
|
|
1362
|
+
const { signable_message: signableMessage, payload_hash: payloadHash } = signableResult.data;
|
|
1363
|
+
const ethSignature = await signRaw(signableMessage, ethSigner);
|
|
1364
|
+
const starkSignature = await starkSigner.signMessage(payloadHash);
|
|
1365
|
+
const response = await usersApi.registerPassportUser({
|
|
1366
|
+
authorization: `Bearer ` + authorization,
|
|
1367
|
+
registerPassportUserRequest: {
|
|
1368
|
+
eth_signature: ethSignature,
|
|
1369
|
+
ether_key: userAddress,
|
|
1370
|
+
stark_signature: starkSignature,
|
|
1371
|
+
stark_key: starkPublicKey,
|
|
1372
|
+
},
|
|
1373
|
+
});
|
|
1374
|
+
return response.statusText;
|
|
1375
|
+
}, PassportErrorType.USER_REGISTRATION_ERROR);
|
|
755
1376
|
}
|
|
756
1377
|
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
token_id: deposit.tokenId,
|
|
767
|
-
};
|
|
768
|
-
const amount = '1';
|
|
769
|
-
const getSignableDepositRequest = {
|
|
770
|
-
user,
|
|
771
|
-
token: {
|
|
772
|
-
type: deposit.type,
|
|
773
|
-
data,
|
|
774
|
-
},
|
|
775
|
-
amount: amount.toString(),
|
|
776
|
-
};
|
|
777
|
-
const signableDepositResult = await depositsApi.getSignableDeposit({
|
|
778
|
-
getSignableDepositRequest,
|
|
779
|
-
});
|
|
780
|
-
// Perform encoding on asset details to get an assetType (required for stark contract request)
|
|
781
|
-
const encodingResult = await encodingApi.encodeAsset({
|
|
782
|
-
assetType: 'asset',
|
|
783
|
-
encodeAssetRequest: {
|
|
784
|
-
token: {
|
|
785
|
-
type: deposit.type,
|
|
786
|
-
data: {
|
|
787
|
-
token_address: deposit.tokenAddress,
|
|
788
|
-
token_id: deposit.tokenId,
|
|
789
|
-
},
|
|
790
|
-
},
|
|
791
|
-
},
|
|
792
|
-
});
|
|
793
|
-
const assetType = encodingResult.data.asset_type;
|
|
794
|
-
const starkPublicKey = signableDepositResult.data.stark_key;
|
|
795
|
-
const vaultId = signableDepositResult.data.vault_id;
|
|
796
|
-
const isRegistered = await isRegisteredOnChain(starkPublicKey, ethSigner, config);
|
|
797
|
-
// Approve whether an amount of token from an account can be spent by a third-party account
|
|
798
|
-
const tokenContract = Contracts.IERC721.connect(deposit.tokenAddress, ethSigner);
|
|
799
|
-
const operator = immutableXConfig.ethConfiguration.coreContractAddress;
|
|
800
|
-
const isApprovedForAll = await tokenContract.isApprovedForAll(user, operator);
|
|
801
|
-
if (!isApprovedForAll) {
|
|
802
|
-
await tokenContract.setApprovalForAll(operator, true);
|
|
1378
|
+
class Passport {
|
|
1379
|
+
authManager;
|
|
1380
|
+
magicAdapter;
|
|
1381
|
+
config;
|
|
1382
|
+
constructor(passportModuleConfiguration) {
|
|
1383
|
+
const passportConfiguration = new PassportConfiguration(passportModuleConfiguration);
|
|
1384
|
+
this.config = passportConfiguration;
|
|
1385
|
+
this.authManager = new AuthManager(this.config);
|
|
1386
|
+
this.magicAdapter = new MagicAdapter(this.config);
|
|
803
1387
|
}
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
await
|
|
1388
|
+
async getImxProvider(user) {
|
|
1389
|
+
if (!user || !user.idToken) {
|
|
1390
|
+
throw new PassportError('Failed to initialise', PassportErrorType.WALLET_CONNECTION_ERROR);
|
|
1391
|
+
}
|
|
1392
|
+
const provider = await this.magicAdapter.login(user.idToken);
|
|
1393
|
+
const ethSigner = provider.getSigner();
|
|
1394
|
+
const starkSigner = await getStarkSigner(ethSigner);
|
|
1395
|
+
if (!user.etherKey) {
|
|
1396
|
+
const updatedUser = await this.registerUser(ethSigner, starkSigner, user.accessToken);
|
|
1397
|
+
return new PassportImxProvider({
|
|
1398
|
+
user: updatedUser,
|
|
1399
|
+
starkSigner,
|
|
1400
|
+
passportConfig: this.config,
|
|
1401
|
+
});
|
|
1402
|
+
}
|
|
1403
|
+
const userWithEtherKey = user;
|
|
1404
|
+
return new PassportImxProvider({
|
|
1405
|
+
user: userWithEtherKey,
|
|
1406
|
+
starkSigner,
|
|
1407
|
+
passportConfig: this.config,
|
|
1408
|
+
});
|
|
1409
|
+
}
|
|
1410
|
+
async connectImxSilent() {
|
|
1411
|
+
const user = await this.authManager.loginSilent();
|
|
1412
|
+
if (!user) {
|
|
1413
|
+
return null;
|
|
1414
|
+
}
|
|
1415
|
+
return this.getImxProvider(user);
|
|
1416
|
+
}
|
|
1417
|
+
async connectImx() {
|
|
1418
|
+
const user = await this.authManager.login();
|
|
1419
|
+
return this.getImxProvider(user);
|
|
1420
|
+
}
|
|
1421
|
+
async loginCallback() {
|
|
1422
|
+
return this.authManager.loginCallback();
|
|
1423
|
+
}
|
|
1424
|
+
async logout() {
|
|
1425
|
+
return this.authManager.logout();
|
|
1426
|
+
}
|
|
1427
|
+
async getUserInfo() {
|
|
1428
|
+
const user = await this.authManager.getUser();
|
|
1429
|
+
return user?.profile;
|
|
1430
|
+
}
|
|
1431
|
+
async getIdToken() {
|
|
1432
|
+
const user = await this.authManager.getUser();
|
|
1433
|
+
return user?.idToken;
|
|
1434
|
+
}
|
|
1435
|
+
async getAccessToken() {
|
|
1436
|
+
const user = await this.authManager.getUser();
|
|
1437
|
+
return user?.accessToken;
|
|
1438
|
+
}
|
|
1439
|
+
async registerUser(userAdminKeySigner, starkSigner, jwt) {
|
|
1440
|
+
const configuration = new Configuration({
|
|
1441
|
+
basePath: this.config.imxApiBasePath,
|
|
1442
|
+
});
|
|
1443
|
+
const usersApi = new UsersApi(configuration);
|
|
1444
|
+
await registerPassport({
|
|
1445
|
+
ethSigner: userAdminKeySigner,
|
|
1446
|
+
starkSigner,
|
|
1447
|
+
usersApi,
|
|
1448
|
+
}, jwt);
|
|
1449
|
+
const updatedUser = await this.authManager.requestRefreshTokenAfterRegistration();
|
|
1450
|
+
if (!updatedUser) {
|
|
1451
|
+
throw new PassportError('Failed to get refresh token', PassportErrorType.REFRESH_TOKEN_ERROR);
|
|
1452
|
+
}
|
|
1453
|
+
return updatedUser;
|
|
809
1454
|
}
|
|
810
|
-
return executeDepositERC721(ethSigner, deposit.tokenId, assetType, starkPublicKey, vaultId, immutableXConfig);
|
|
811
|
-
}
|
|
812
|
-
async function executeDepositERC721(ethSigner, tokenId, assetType, starkPublicKey, vaultId, config) {
|
|
813
|
-
const coreContract = Contracts.Core.connect(config.ethConfiguration.coreContractAddress, ethSigner);
|
|
814
|
-
const populatedTransaction = await coreContract.populateTransaction.depositNft(starkPublicKey, assetType, vaultId, tokenId);
|
|
815
|
-
return ethSigner.sendTransaction(populatedTransaction);
|
|
816
1455
|
}
|
|
817
1456
|
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
return depositERC721({ signers, deposit, config });
|
|
826
|
-
}
|
|
1457
|
+
function isChainValid(chainID, config) {
|
|
1458
|
+
return chainID === config.ethConfiguration.chainID;
|
|
1459
|
+
}
|
|
1460
|
+
async function validateChain(signer, config) {
|
|
1461
|
+
const chainID = await signer.getChainId();
|
|
1462
|
+
if (!isChainValid(chainID, config))
|
|
1463
|
+
throw new Error('The wallet used for this operation is not connected to the correct network.');
|
|
827
1464
|
}
|
|
828
1465
|
|
|
829
|
-
async function
|
|
830
|
-
await validateChain(
|
|
831
|
-
const
|
|
832
|
-
const
|
|
833
|
-
const transferAmount = request.amount;
|
|
834
|
-
const signableResult = await
|
|
835
|
-
id: request.transactionID,
|
|
1466
|
+
async function transfer({ signers: { ethSigner, starkSigner }, request, config, }) {
|
|
1467
|
+
await validateChain(ethSigner, config.immutableXConfig);
|
|
1468
|
+
const ethAddress = await ethSigner.getAddress();
|
|
1469
|
+
const transfersApi = new TransfersApi(config.immutableXConfig.apiConfiguration);
|
|
1470
|
+
const transferAmount = request.type === 'ERC721' ? '1' : request.amount;
|
|
1471
|
+
const signableResult = await transfersApi.getSignableTransferV1({
|
|
836
1472
|
getSignableTransferRequest: {
|
|
837
1473
|
sender: ethAddress,
|
|
838
1474
|
token: convertToSignableToken(request),
|
|
@@ -841,8 +1477,8 @@ async function exchangeTransfer$1({ signers, request, config, }) {
|
|
|
841
1477
|
},
|
|
842
1478
|
});
|
|
843
1479
|
const { signable_message: signableMessage, payload_hash: payloadHash } = signableResult.data;
|
|
844
|
-
const ethSignature = await signRaw(signableMessage,
|
|
845
|
-
const starkSignature = await
|
|
1480
|
+
const ethSignature = await signRaw(signableMessage, ethSigner);
|
|
1481
|
+
const starkSignature = await starkSigner.signMessage(payloadHash);
|
|
846
1482
|
const transferSigningParams = {
|
|
847
1483
|
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
848
1484
|
sender_stark_key: signableResult.data.sender_stark_key,
|
|
@@ -855,8 +1491,7 @@ async function exchangeTransfer$1({ signers, request, config, }) {
|
|
|
855
1491
|
expiration_timestamp: signableResult.data.expiration_timestamp,
|
|
856
1492
|
stark_signature: starkSignature,
|
|
857
1493
|
};
|
|
858
|
-
const response = await
|
|
859
|
-
id: request.transactionID,
|
|
1494
|
+
const response = await transfersApi.createTransferV1({
|
|
860
1495
|
createTransferRequest: transferSigningParams,
|
|
861
1496
|
xImxEthAddress: ethAddress,
|
|
862
1497
|
xImxEthSignature: ethSignature,
|
|
@@ -868,1060 +1503,1004 @@ async function exchangeTransfer$1({ signers, request, config, }) {
|
|
|
868
1503
|
transfer_id: response?.data.transfer_id,
|
|
869
1504
|
};
|
|
870
1505
|
}
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
}
|
|
891
|
-
}
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
request,
|
|
896
|
-
config: this.config,
|
|
897
|
-
});
|
|
898
|
-
}
|
|
899
|
-
completeWithdrawal(starkPublicKey, token) {
|
|
900
|
-
return completeWithdrawal({
|
|
901
|
-
config: this.config,
|
|
902
|
-
signers: this.signers,
|
|
903
|
-
token,
|
|
904
|
-
starkPublicKey,
|
|
905
|
-
});
|
|
906
|
-
}
|
|
907
|
-
createOrder(request) {
|
|
908
|
-
return createOrder$1({
|
|
909
|
-
signers: this.signers,
|
|
910
|
-
request,
|
|
911
|
-
config: this.config,
|
|
912
|
-
});
|
|
913
|
-
}
|
|
914
|
-
createTrade(request) {
|
|
915
|
-
return createTrade$1({
|
|
916
|
-
signers: this.signers,
|
|
917
|
-
request,
|
|
918
|
-
config: this.config,
|
|
919
|
-
});
|
|
920
|
-
}
|
|
921
|
-
deposit(tokenAmount) {
|
|
922
|
-
return deposit({
|
|
923
|
-
signers: this.signers,
|
|
924
|
-
deposit: tokenAmount,
|
|
925
|
-
config: this.config,
|
|
926
|
-
});
|
|
927
|
-
}
|
|
928
|
-
exchangeTransfer(request) {
|
|
929
|
-
return exchangeTransfer$1({
|
|
930
|
-
signers: this.signers,
|
|
931
|
-
request,
|
|
932
|
-
config: this.config,
|
|
933
|
-
});
|
|
934
|
-
}
|
|
935
|
-
async isRegisteredOnchain() {
|
|
936
|
-
const starkPublicKey = await this.signers.starkExSigner.getAddress();
|
|
937
|
-
return isRegisteredOnChain(starkPublicKey, this.signers.ethSigner, this.config);
|
|
938
|
-
}
|
|
939
|
-
prepareWithdrawal(request) {
|
|
940
|
-
return prepareWithdrawal({
|
|
941
|
-
signers: this.signers,
|
|
942
|
-
withdrawal: request,
|
|
943
|
-
config: this.config,
|
|
944
|
-
});
|
|
945
|
-
}
|
|
946
|
-
transfer(request) {
|
|
947
|
-
return transfer$1({
|
|
948
|
-
signers: this.signers,
|
|
949
|
-
request,
|
|
950
|
-
config: this.config,
|
|
951
|
-
});
|
|
952
|
-
}
|
|
953
|
-
}
|
|
954
|
-
|
|
955
|
-
const WALLET_ACTION = {
|
|
956
|
-
SWITCH_CHAIN: 'wallet_switchEthereumChain',
|
|
957
|
-
CONNECT: 'eth_requestAccounts',
|
|
958
|
-
};
|
|
959
|
-
function isRequestableProvider(provider) {
|
|
960
|
-
return !!provider?.request;
|
|
961
|
-
}
|
|
962
|
-
async function connectProvider(provider, chainID) {
|
|
963
|
-
await provider.request({ method: WALLET_ACTION.CONNECT });
|
|
964
|
-
if (chainID) {
|
|
965
|
-
await provider.request({
|
|
966
|
-
method: WALLET_ACTION.SWITCH_CHAIN,
|
|
967
|
-
params: [{ chainId: `0x${chainID.toString(16)}` }],
|
|
968
|
-
});
|
|
1506
|
+
async function batchTransfer({ signers: { ethSigner, starkSigner }, request, config, }) {
|
|
1507
|
+
await validateChain(ethSigner, config.immutableXConfig);
|
|
1508
|
+
const ethAddress = await ethSigner.getAddress();
|
|
1509
|
+
const transfersApi = new TransfersApi(config.immutableXConfig.apiConfiguration);
|
|
1510
|
+
const signableRequests = request.map((nftTransfer) => {
|
|
1511
|
+
return {
|
|
1512
|
+
amount: '1',
|
|
1513
|
+
token: convertToSignableToken({
|
|
1514
|
+
type: 'ERC721',
|
|
1515
|
+
tokenId: nftTransfer.tokenId,
|
|
1516
|
+
tokenAddress: nftTransfer.tokenAddress,
|
|
1517
|
+
}),
|
|
1518
|
+
receiver: nftTransfer.receiver,
|
|
1519
|
+
};
|
|
1520
|
+
});
|
|
1521
|
+
const signableResult = await transfersApi.getSignableTransfer({
|
|
1522
|
+
getSignableTransferRequestV2: {
|
|
1523
|
+
sender_ether_key: ethAddress,
|
|
1524
|
+
signable_requests: signableRequests,
|
|
1525
|
+
},
|
|
1526
|
+
});
|
|
1527
|
+
const signableMessage = signableResult.data.signable_message;
|
|
1528
|
+
if (signableMessage === undefined) {
|
|
1529
|
+
throw new Error('Invalid response from Signable registration offchain');
|
|
969
1530
|
}
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
const
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
1531
|
+
const ethSignature = await signRaw(signableMessage, ethSigner);
|
|
1532
|
+
const requests = [];
|
|
1533
|
+
for (const resp of signableResult.data.signable_responses) {
|
|
1534
|
+
const starkSignature = await starkSigner.signMessage(resp.payload_hash);
|
|
1535
|
+
const req = {
|
|
1536
|
+
sender_vault_id: resp.sender_vault_id,
|
|
1537
|
+
receiver_stark_key: resp.receiver_stark_key,
|
|
1538
|
+
receiver_vault_id: resp.receiver_vault_id,
|
|
1539
|
+
asset_id: resp.asset_id,
|
|
1540
|
+
amount: resp.amount,
|
|
1541
|
+
nonce: resp.nonce,
|
|
1542
|
+
expiration_timestamp: resp.expiration_timestamp,
|
|
1543
|
+
stark_signature: starkSignature,
|
|
1544
|
+
};
|
|
1545
|
+
requests.push(req);
|
|
979
1546
|
}
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
1547
|
+
// TODO: throw error on missing payload hash?
|
|
1548
|
+
const transferSigningParams = {
|
|
1549
|
+
sender_stark_key: signableResult.data.sender_stark_key,
|
|
1550
|
+
requests,
|
|
1551
|
+
};
|
|
1552
|
+
const response = await transfersApi.createTransfer({
|
|
1553
|
+
createTransferRequestV2: transferSigningParams,
|
|
1554
|
+
xImxEthAddress: ethAddress,
|
|
1555
|
+
xImxEthSignature: ethSignature,
|
|
1556
|
+
});
|
|
1557
|
+
return {
|
|
1558
|
+
transfer_ids: response?.data.transfer_ids,
|
|
1559
|
+
};
|
|
984
1560
|
}
|
|
985
1561
|
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
}
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1562
|
+
async function createOrder({ signers, request, config, }) {
|
|
1563
|
+
await validateChain(signers.ethSigner, config.immutableXConfig);
|
|
1564
|
+
const ethAddress = await signers.ethSigner.getAddress();
|
|
1565
|
+
const ordersApi = new OrdersApi(config.immutableXConfig.apiConfiguration);
|
|
1566
|
+
const amountSell = request.sell.type === 'ERC721' ? '1' : request.sell.amount;
|
|
1567
|
+
const amountBuy = request.buy.type === 'ERC721' ? '1' : request.buy.amount;
|
|
1568
|
+
const getSignableOrderRequest = {
|
|
1569
|
+
user: ethAddress,
|
|
1570
|
+
amount_buy: amountBuy,
|
|
1571
|
+
token_buy: convertToSignableToken(request.buy),
|
|
1572
|
+
amount_sell: amountSell,
|
|
1573
|
+
token_sell: convertToSignableToken(request.sell),
|
|
1574
|
+
fees: request.fees,
|
|
1575
|
+
expiration_timestamp: request.expiration_timestamp,
|
|
1576
|
+
};
|
|
1577
|
+
const getSignableOrderResponse = await ordersApi.getSignableOrder({
|
|
1578
|
+
getSignableOrderRequestV3: getSignableOrderRequest,
|
|
1579
|
+
});
|
|
1580
|
+
const { signable_message: signableMessage, payload_hash: payloadHash } = getSignableOrderResponse.data;
|
|
1581
|
+
const ethSignature = await signRaw(signableMessage, signers.ethSigner);
|
|
1582
|
+
const starkSignature = await signers.starkSigner.signMessage(payloadHash);
|
|
1583
|
+
const resp = getSignableOrderResponse.data;
|
|
1584
|
+
const orderParams = {
|
|
1585
|
+
createOrderRequest: {
|
|
1586
|
+
amount_buy: resp.amount_buy,
|
|
1587
|
+
amount_sell: resp.amount_sell,
|
|
1588
|
+
asset_id_buy: resp.asset_id_buy,
|
|
1589
|
+
asset_id_sell: resp.asset_id_sell,
|
|
1590
|
+
expiration_timestamp: resp.expiration_timestamp,
|
|
1591
|
+
include_fees: true,
|
|
1592
|
+
fees: request.fees,
|
|
1593
|
+
nonce: resp.nonce,
|
|
1594
|
+
stark_key: resp.stark_key,
|
|
1595
|
+
stark_signature: starkSignature,
|
|
1596
|
+
vault_id_buy: resp.vault_id_buy,
|
|
1597
|
+
vault_id_sell: resp.vault_id_sell,
|
|
1598
|
+
},
|
|
1599
|
+
xImxEthAddress: ethAddress,
|
|
1600
|
+
xImxEthSignature: ethSignature,
|
|
1601
|
+
};
|
|
1602
|
+
const createOrderResponse = await ordersApi.createOrder(orderParams);
|
|
1603
|
+
return {
|
|
1604
|
+
...createOrderResponse.data,
|
|
1605
|
+
};
|
|
1006
1606
|
}
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1607
|
+
async function cancelOrder({ signers, request, config, }) {
|
|
1608
|
+
const ordersApi = new OrdersApi(config.immutableXConfig.apiConfiguration);
|
|
1609
|
+
const getSignableCancelOrderResponse = await ordersApi.getSignableCancelOrder({
|
|
1610
|
+
getSignableCancelOrderRequest: {
|
|
1611
|
+
order_id: request.order_id,
|
|
1612
|
+
},
|
|
1613
|
+
});
|
|
1614
|
+
const { signable_message: signableMessage, payload_hash: payloadHash } = getSignableCancelOrderResponse.data;
|
|
1615
|
+
const ethSignature = await signRaw(signableMessage, signers.ethSigner);
|
|
1616
|
+
const starkSignature = await signers.starkSigner.signMessage(payloadHash);
|
|
1617
|
+
const ethAddress = await signers.ethSigner.getAddress();
|
|
1618
|
+
const cancelOrderResponse = await ordersApi.cancelOrder({
|
|
1619
|
+
id: request.order_id.toString(),
|
|
1620
|
+
cancelOrderRequest: {
|
|
1621
|
+
order_id: request.order_id,
|
|
1622
|
+
stark_signature: starkSignature,
|
|
1623
|
+
},
|
|
1624
|
+
xImxEthAddress: ethAddress,
|
|
1625
|
+
xImxEthSignature: ethSignature,
|
|
1626
|
+
});
|
|
1627
|
+
return {
|
|
1628
|
+
order_id: cancelOrderResponse.data.order_id,
|
|
1629
|
+
status: cancelOrderResponse.data.status,
|
|
1630
|
+
};
|
|
1017
1631
|
}
|
|
1018
1632
|
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1633
|
+
async function registerOffchain(signers, config) {
|
|
1634
|
+
await validateChain(signers.ethSigner, config.immutableXConfig);
|
|
1635
|
+
const usersApi = new UsersApi(config.immutableXConfig.apiConfiguration);
|
|
1636
|
+
const userAddress = await signers.ethSigner.getAddress();
|
|
1637
|
+
const starkPublicKey = await signers.starkSigner.getAddress();
|
|
1638
|
+
const signableResult = await usersApi.getSignableRegistrationOffchain({
|
|
1639
|
+
getSignableRegistrationRequest: {
|
|
1640
|
+
ether_key: userAddress,
|
|
1641
|
+
stark_key: starkPublicKey,
|
|
1642
|
+
},
|
|
1643
|
+
});
|
|
1644
|
+
const { signable_message: signableMessage, payload_hash: payloadHash } = signableResult.data;
|
|
1645
|
+
const ethSignature = await signRaw(signableMessage, signers.ethSigner);
|
|
1646
|
+
const starkSignature = await signers.starkSigner.signMessage(payloadHash);
|
|
1647
|
+
const registeredUser = await usersApi.registerUser({
|
|
1648
|
+
registerUserRequest: {
|
|
1649
|
+
eth_signature: ethSignature,
|
|
1650
|
+
ether_key: userAddress,
|
|
1651
|
+
stark_signature: starkSignature,
|
|
1652
|
+
stark_key: starkPublicKey,
|
|
1653
|
+
},
|
|
1654
|
+
});
|
|
1655
|
+
return registeredUser.data;
|
|
1656
|
+
}
|
|
1657
|
+
async function isRegisteredOnChain(starkPublicKey, ethSigner, config) {
|
|
1658
|
+
await validateChain(ethSigner, config.immutableXConfig);
|
|
1659
|
+
const registrationContract = Contracts.Registration.connect(config.immutableXConfig.ethConfiguration.registrationContractAddress, ethSigner);
|
|
1660
|
+
try {
|
|
1661
|
+
return await registrationContract.isRegistered(starkPublicKey);
|
|
1046
1662
|
}
|
|
1047
|
-
|
|
1048
|
-
|
|
1663
|
+
catch (ex) {
|
|
1664
|
+
if (ex.reason === 'USER_UNREGISTERED') {
|
|
1665
|
+
return false;
|
|
1666
|
+
}
|
|
1667
|
+
throw ex;
|
|
1049
1668
|
}
|
|
1050
1669
|
}
|
|
1051
|
-
|
|
1052
|
-
const
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
}
|
|
1057
|
-
const IMX_WALLET_IFRAME_STYLE = 'display: none;';
|
|
1058
|
-
function getIFrame() {
|
|
1059
|
-
return document.querySelector(`iframe#${IMX_WALLET_IFRAME_ID}`);
|
|
1060
|
-
}
|
|
1061
|
-
async function setupIFrame(env) {
|
|
1062
|
-
return new Promise((resolve) => {
|
|
1063
|
-
const iframe = document.createElement('iframe');
|
|
1064
|
-
iframe.setAttribute('id', IMX_WALLET_IFRAME_ID);
|
|
1065
|
-
iframe.setAttribute('src', IMX_WALLET_IFRAME_HOSTS[env]);
|
|
1066
|
-
iframe.setAttribute('style', IMX_WALLET_IFRAME_STYLE);
|
|
1067
|
-
document.body.appendChild(iframe);
|
|
1068
|
-
iframe.onload = () => resolve(iframe);
|
|
1670
|
+
async function getSignableRegistrationOnchain(etherKey, starkPublicKey, usersApi) {
|
|
1671
|
+
const response = await usersApi.getSignableRegistration({
|
|
1672
|
+
getSignableRegistrationRequest: {
|
|
1673
|
+
ether_key: etherKey,
|
|
1674
|
+
stark_key: starkPublicKey,
|
|
1675
|
+
},
|
|
1069
1676
|
});
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
return iframe;
|
|
1075
|
-
return await setupIFrame(env);
|
|
1677
|
+
return {
|
|
1678
|
+
operator_signature: response.data.operator_signature,
|
|
1679
|
+
payload_hash: response.data.payload_hash,
|
|
1680
|
+
};
|
|
1076
1681
|
}
|
|
1077
1682
|
|
|
1078
|
-
const
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
const
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1683
|
+
const assertIsDefined = (value) => {
|
|
1684
|
+
if (value !== undefined)
|
|
1685
|
+
return value;
|
|
1686
|
+
throw new Error('undefined field exception');
|
|
1687
|
+
};
|
|
1688
|
+
async function prepareWithdrawalAction(params) {
|
|
1689
|
+
const { signers: { ethSigner, starkSigner }, type, config, } = params;
|
|
1690
|
+
await validateChain(ethSigner, params.config);
|
|
1691
|
+
const withdrawalsApi = new WithdrawalsApi(config.apiConfiguration);
|
|
1692
|
+
const withdrawalAmount = type === 'ERC721' ? '1' : params.amount;
|
|
1693
|
+
const signableWithdrawalResult = await withdrawalsApi.getSignableWithdrawal({
|
|
1694
|
+
getSignableWithdrawalRequest: {
|
|
1695
|
+
user: await ethSigner.getAddress(),
|
|
1696
|
+
token: convertToSignableToken(params),
|
|
1697
|
+
amount: withdrawalAmount,
|
|
1698
|
+
},
|
|
1699
|
+
});
|
|
1700
|
+
const { signable_message: signableMessage, payload_hash: payloadHash } = signableWithdrawalResult.data;
|
|
1701
|
+
const starkSignature = await starkSigner.signMessage(payloadHash);
|
|
1702
|
+
const { ethAddress, ethSignature } = await signMessage(signableMessage, ethSigner);
|
|
1703
|
+
const prepareWithdrawalResponse = await withdrawalsApi.createWithdrawal({
|
|
1704
|
+
createWithdrawalRequest: {
|
|
1705
|
+
stark_key: assertIsDefined(signableWithdrawalResult.data.stark_key),
|
|
1706
|
+
amount: withdrawalAmount,
|
|
1707
|
+
asset_id: assertIsDefined(signableWithdrawalResult.data.asset_id),
|
|
1708
|
+
vault_id: assertIsDefined(signableWithdrawalResult.data.vault_id),
|
|
1709
|
+
nonce: assertIsDefined(signableWithdrawalResult.data.nonce),
|
|
1710
|
+
stark_signature: starkSignature,
|
|
1711
|
+
},
|
|
1712
|
+
xImxEthAddress: ethAddress,
|
|
1713
|
+
xImxEthSignature: ethSignature,
|
|
1100
1714
|
});
|
|
1715
|
+
return prepareWithdrawalResponse.data;
|
|
1101
1716
|
}
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
}
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
});
|
|
1114
|
-
};
|
|
1115
|
-
window.addEventListener(COMMUNICATION_TYPE, listener);
|
|
1116
|
-
postRequestMessage(iframe, {
|
|
1117
|
-
type: RequestEventType.DISCONNECT_WALLET_REQUEST,
|
|
1118
|
-
details: { starkPublicKey: imxSigner.getAddress() },
|
|
1119
|
-
});
|
|
1717
|
+
|
|
1718
|
+
async function getEncodeAssetInfo(assetType, tokenType, config, tokenData) {
|
|
1719
|
+
const encodingApi = new EncodingApi(config.apiConfiguration);
|
|
1720
|
+
const result = await encodingApi.encodeAsset({
|
|
1721
|
+
assetType,
|
|
1722
|
+
encodeAssetRequest: {
|
|
1723
|
+
token: {
|
|
1724
|
+
type: tokenType,
|
|
1725
|
+
...(tokenData && { data: tokenData }),
|
|
1726
|
+
},
|
|
1727
|
+
},
|
|
1120
1728
|
});
|
|
1729
|
+
return result.data;
|
|
1121
1730
|
}
|
|
1122
1731
|
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
super(message);
|
|
1132
|
-
this.type = type;
|
|
1133
|
-
}
|
|
1732
|
+
async function executeRegisterAndWithdrawERC20({ ethSigner, assetType, starkPublicKey, config, }) {
|
|
1733
|
+
const etherKey = await ethSigner.getAddress();
|
|
1734
|
+
const imxConfig = config.immutableXConfig;
|
|
1735
|
+
const usersApi = new UsersApi(imxConfig.apiConfiguration);
|
|
1736
|
+
const signableResult = await getSignableRegistrationOnchain(etherKey, starkPublicKey, usersApi);
|
|
1737
|
+
const contract = Contracts.Registration.connect(config.immutableXConfig.ethConfiguration.registrationContractAddress, ethSigner);
|
|
1738
|
+
const populatedTransaction = await contract.populateTransaction.registerAndWithdraw(etherKey, starkPublicKey, signableResult.operator_signature, assetType);
|
|
1739
|
+
return ethSigner.sendTransaction(populatedTransaction);
|
|
1134
1740
|
}
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
|
|
1741
|
+
async function executeWithdrawERC20(ethSigner, assetType, starkPublicKey, config) {
|
|
1742
|
+
const contract = Contracts.Core.connect(config.ethConfiguration.coreContractAddress, ethSigner);
|
|
1743
|
+
const populatedTransaction = await contract.populateTransaction.withdraw(starkPublicKey, assetType);
|
|
1744
|
+
return ethSigner.sendTransaction(populatedTransaction);
|
|
1745
|
+
}
|
|
1746
|
+
async function completeERC20WithdrawalAction({ ethSigner, starkPublicKey, token, config, }) {
|
|
1747
|
+
await validateChain(ethSigner, config.immutableXConfig);
|
|
1748
|
+
const imxConfig = config.immutableXConfig;
|
|
1749
|
+
const assetType = await getEncodeAssetInfo('asset', 'ERC20', imxConfig, {
|
|
1750
|
+
token_address: token.tokenAddress,
|
|
1751
|
+
});
|
|
1752
|
+
const isRegistered = await isRegisteredOnChain(starkPublicKey, ethSigner, config);
|
|
1753
|
+
if (!isRegistered) {
|
|
1754
|
+
return executeRegisterAndWithdrawERC20({
|
|
1755
|
+
ethSigner,
|
|
1756
|
+
assetType: assetType.asset_type,
|
|
1757
|
+
starkPublicKey,
|
|
1758
|
+
config,
|
|
1759
|
+
});
|
|
1138
1760
|
}
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
throw new ProviderError(errorMessage, customError.type);
|
|
1761
|
+
else {
|
|
1762
|
+
return executeWithdrawERC20(ethSigner, assetType.asset_type, starkPublicKey, imxConfig);
|
|
1142
1763
|
}
|
|
1143
|
-
}
|
|
1764
|
+
}
|
|
1144
1765
|
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1766
|
+
async function executeWithdrawMintableERC721(ethSigner, assetType, starkPublicKey, mintingBlob, config) {
|
|
1767
|
+
const contract = Contracts.Core.connect(config.ethConfiguration.coreContractAddress, ethSigner);
|
|
1768
|
+
const populatedTransaction = await contract.populateTransaction.withdrawAndMint(starkPublicKey, assetType, mintingBlob);
|
|
1769
|
+
return ethSigner.sendTransaction(populatedTransaction);
|
|
1770
|
+
}
|
|
1771
|
+
async function executeRegisterAndWithdrawMintableERC721(ethSigner, assetType, starkPublicKey, mintingBlob, config) {
|
|
1772
|
+
const etherKey = await ethSigner.getAddress();
|
|
1773
|
+
const usersApi = new UsersApi(config.apiConfiguration);
|
|
1774
|
+
const signableResult = await getSignableRegistrationOnchain(etherKey, starkPublicKey, usersApi);
|
|
1775
|
+
const contract = Contracts.Registration.connect(config.ethConfiguration.registrationContractAddress, ethSigner);
|
|
1776
|
+
const populatedTransaction = await contract.populateTransaction.regsiterAndWithdrawAndMint(etherKey, starkPublicKey, signableResult.operator_signature, assetType, mintingBlob);
|
|
1777
|
+
return ethSigner.sendTransaction(populatedTransaction);
|
|
1778
|
+
}
|
|
1779
|
+
function getMintingBlob(token) {
|
|
1780
|
+
const id = token.data.id;
|
|
1781
|
+
const blueprint = token.data.blueprint || '';
|
|
1782
|
+
return encUtils.sanitizeHex(encUtils.utf8ToHex(`{${id}}:{${blueprint}}`));
|
|
1783
|
+
}
|
|
1784
|
+
async function completeMintableERC721Withdrawal(ethSigner, starkPublicKey, token, config) {
|
|
1785
|
+
const imxConfig = config.immutableXConfig;
|
|
1786
|
+
const assetType = await getEncodeAssetInfo('mintable-asset', 'ERC721', imxConfig, {
|
|
1787
|
+
id: token.data.id,
|
|
1788
|
+
token_address: token.data.tokenAddress,
|
|
1789
|
+
...(token.data.blueprint && { blueprint: token.data.blueprint }),
|
|
1790
|
+
});
|
|
1791
|
+
const mintingBlob = getMintingBlob(token);
|
|
1792
|
+
const isRegistered = await isRegisteredOnChain(starkPublicKey, ethSigner, config);
|
|
1793
|
+
if (!isRegistered) {
|
|
1794
|
+
return executeRegisterAndWithdrawMintableERC721(ethSigner, assetType.asset_type, starkPublicKey, mintingBlob, imxConfig);
|
|
1158
1795
|
}
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
throw new ProviderError('Attempted to disconnect from the MetaMask IMX provider without an established connection', ProviderErrorType.PROVIDER_CONNECTION_ERROR);
|
|
1162
|
-
}
|
|
1163
|
-
return withProviderError(async () => {
|
|
1164
|
-
await disconnect(this.imxSigner);
|
|
1165
|
-
}, { type: ProviderErrorType.PROVIDER_CONNECTION_ERROR });
|
|
1796
|
+
else {
|
|
1797
|
+
return executeWithdrawMintableERC721(ethSigner, assetType.asset_type, starkPublicKey, mintingBlob, imxConfig);
|
|
1166
1798
|
}
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1799
|
+
}
|
|
1800
|
+
async function executeRegisterAndWithdrawERC721(ethSigner, assetType, starkPublicKey, tokenId, config) {
|
|
1801
|
+
const etherKey = await ethSigner.getAddress();
|
|
1802
|
+
const usersApi = new UsersApi(config.apiConfiguration);
|
|
1803
|
+
const signableResult = await getSignableRegistrationOnchain(etherKey, starkPublicKey, usersApi);
|
|
1804
|
+
const contract = Contracts.Registration.connect(config.ethConfiguration.registrationContractAddress, ethSigner);
|
|
1805
|
+
const populatedTransaction = await contract.populateTransaction.registerAndWithdrawNft(etherKey, starkPublicKey, signableResult.operator_signature, assetType, tokenId);
|
|
1806
|
+
return ethSigner.sendTransaction(populatedTransaction);
|
|
1807
|
+
}
|
|
1808
|
+
async function executeWithdrawERC721(ethSigner, assetType, starkPublicKey, tokenId, config) {
|
|
1809
|
+
const contract = Contracts.Core.connect(config.ethConfiguration.coreContractAddress, ethSigner);
|
|
1810
|
+
const populatedTransaction = await contract.populateTransaction.withdrawNft(starkPublicKey, assetType, tokenId);
|
|
1811
|
+
return ethSigner.sendTransaction(populatedTransaction);
|
|
1812
|
+
}
|
|
1813
|
+
async function completeERC721Withdrawal(ethSigner, starkPublicKey, token, config) {
|
|
1814
|
+
const imxConfig = config.immutableXConfig;
|
|
1815
|
+
const assetType = await getEncodeAssetInfo('asset', 'ERC721', imxConfig, {
|
|
1816
|
+
token_id: token.tokenId,
|
|
1817
|
+
token_address: token.tokenAddress,
|
|
1818
|
+
});
|
|
1819
|
+
const isRegistered = await isRegisteredOnChain(starkPublicKey, ethSigner, config);
|
|
1820
|
+
if (!isRegistered) {
|
|
1821
|
+
return executeRegisterAndWithdrawERC721(ethSigner, assetType.asset_type, starkPublicKey, token.tokenId, imxConfig);
|
|
1822
|
+
}
|
|
1823
|
+
else {
|
|
1824
|
+
return executeWithdrawERC721(ethSigner, assetType.asset_type, starkPublicKey, token.tokenId, imxConfig);
|
|
1174
1825
|
}
|
|
1175
1826
|
}
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
|
|
1195
|
-
|
|
1827
|
+
async function completeERC721WithdrawalAction({ ethSigner, starkPublicKey, token, config, }) {
|
|
1828
|
+
await validateChain(ethSigner, config.immutableXConfig);
|
|
1829
|
+
const tokenAddress = token.tokenAddress;
|
|
1830
|
+
const tokenId = token.tokenId;
|
|
1831
|
+
const imxConfig = config.immutableXConfig;
|
|
1832
|
+
const mintsApi = new MintsApi(imxConfig.apiConfiguration);
|
|
1833
|
+
return await mintsApi
|
|
1834
|
+
.getMintableTokenDetailsByClientTokenId({
|
|
1835
|
+
tokenAddress,
|
|
1836
|
+
tokenId,
|
|
1837
|
+
})
|
|
1838
|
+
.then((mintableToken) => completeMintableERC721Withdrawal(ethSigner, starkPublicKey, {
|
|
1839
|
+
type: 'ERC721',
|
|
1840
|
+
data: {
|
|
1841
|
+
id: tokenId,
|
|
1842
|
+
tokenAddress: tokenAddress,
|
|
1843
|
+
blueprint: mintableToken.data.blueprint,
|
|
1844
|
+
},
|
|
1845
|
+
}, config))
|
|
1846
|
+
.catch((error) => {
|
|
1847
|
+
if (error.response?.status === 404) {
|
|
1848
|
+
// token is already minted on L1
|
|
1849
|
+
return completeERC721Withdrawal(ethSigner, starkPublicKey, token, config);
|
|
1196
1850
|
}
|
|
1197
|
-
|
|
1851
|
+
throw error; // unable to recover from any other kind of error
|
|
1852
|
+
});
|
|
1198
1853
|
}
|
|
1199
1854
|
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
PassportErrorType["USER_REGISTRATION_ERROR"] = "USER_REGISTRATION_ERROR";
|
|
1208
|
-
PassportErrorType["LOGOUT_ERROR"] = "LOGOUT_ERROR";
|
|
1209
|
-
PassportErrorType["TRANSFER_ERROR"] = "TRANSFER_ERROR";
|
|
1210
|
-
PassportErrorType["CREATE_ORDER_ERROR"] = "CREATE_ORDER_ERROR";
|
|
1211
|
-
PassportErrorType["CANCEL_ORDER_ERROR"] = "CANCEL_ORDER_ERROR";
|
|
1212
|
-
PassportErrorType["EXCHANGE_TRANSFER_ERROR"] = "EXCHANGE_TRANSFER_ERROR";
|
|
1213
|
-
PassportErrorType["CREATE_TRADE_ERROR"] = "CREATE_TRADE_ERROR";
|
|
1214
|
-
PassportErrorType["OPERATION_NOT_SUPPORTED_ERROR"] = "OPERATION_NOT_SUPPORTED_ERROR";
|
|
1215
|
-
})(PassportErrorType || (PassportErrorType = {}));
|
|
1216
|
-
class PassportError extends Error {
|
|
1217
|
-
type;
|
|
1218
|
-
constructor(message, type) {
|
|
1219
|
-
super(message);
|
|
1220
|
-
this.type = type;
|
|
1221
|
-
}
|
|
1855
|
+
async function executeRegisterAndWithdrawEth(ethSigner, assetType, starkPublicKey, config) {
|
|
1856
|
+
const etherKey = await ethSigner.getAddress();
|
|
1857
|
+
const usersApi = new UsersApi(config.apiConfiguration);
|
|
1858
|
+
const signableResult = await getSignableRegistrationOnchain(etherKey, starkPublicKey, usersApi);
|
|
1859
|
+
const contract = Contracts.Registration.connect(config.ethConfiguration.registrationContractAddress, ethSigner);
|
|
1860
|
+
const populatedTransaction = await contract.populateTransaction.registerAndWithdraw(etherKey, starkPublicKey, signableResult.operator_signature, assetType);
|
|
1861
|
+
return ethSigner.sendTransaction(populatedTransaction);
|
|
1222
1862
|
}
|
|
1223
|
-
|
|
1224
|
-
|
|
1225
|
-
|
|
1863
|
+
async function executeWithdrawEth(ethSigner, assetType, starkPublicKey, config) {
|
|
1864
|
+
const contract = Contracts.Core.connect(config.ethConfiguration.coreContractAddress, ethSigner);
|
|
1865
|
+
const populatedTransaction = await contract.populateTransaction.withdraw(starkPublicKey, assetType);
|
|
1866
|
+
return ethSigner.sendTransaction(populatedTransaction);
|
|
1867
|
+
}
|
|
1868
|
+
async function completeEthWithdrawalAction({ ethSigner, starkPublicKey, config, }) {
|
|
1869
|
+
await validateChain(ethSigner, config.immutableXConfig);
|
|
1870
|
+
const imxConfig = config.immutableXConfig;
|
|
1871
|
+
const assetType = await getEncodeAssetInfo('asset', 'ETH', imxConfig);
|
|
1872
|
+
const isRegistered = await isRegisteredOnChain(starkPublicKey, ethSigner, config);
|
|
1873
|
+
if (!isRegistered) {
|
|
1874
|
+
return executeRegisterAndWithdrawEth(ethSigner, assetType.asset_type, starkPublicKey, imxConfig);
|
|
1226
1875
|
}
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
throw new PassportError(errorMessage, customErrorType);
|
|
1876
|
+
else {
|
|
1877
|
+
return executeWithdrawEth(ethSigner, assetType.asset_type, starkPublicKey, imxConfig);
|
|
1230
1878
|
}
|
|
1231
|
-
}
|
|
1879
|
+
}
|
|
1232
1880
|
|
|
1233
|
-
|
|
1234
|
-
|
|
1235
|
-
|
|
1236
|
-
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
return
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
|
|
1881
|
+
async function prepareWithdrawal({ signers, withdrawal, config, }) {
|
|
1882
|
+
return prepareWithdrawalAction({
|
|
1883
|
+
signers,
|
|
1884
|
+
config: config.immutableXConfig,
|
|
1885
|
+
...withdrawal,
|
|
1886
|
+
});
|
|
1887
|
+
}
|
|
1888
|
+
async function completeWithdrawal({ signers: { ethSigner }, starkPublicKey, token, config, }) {
|
|
1889
|
+
switch (token.type) {
|
|
1890
|
+
case 'ETH':
|
|
1891
|
+
return completeEthWithdrawalAction({ ethSigner, starkPublicKey, config });
|
|
1892
|
+
case 'ERC20':
|
|
1893
|
+
return completeERC20WithdrawalAction({
|
|
1894
|
+
ethSigner,
|
|
1895
|
+
starkPublicKey,
|
|
1896
|
+
token,
|
|
1897
|
+
config,
|
|
1898
|
+
});
|
|
1899
|
+
case 'ERC721':
|
|
1900
|
+
return completeERC721WithdrawalAction({
|
|
1901
|
+
ethSigner,
|
|
1902
|
+
starkPublicKey,
|
|
1903
|
+
token,
|
|
1904
|
+
config,
|
|
1905
|
+
});
|
|
1249
1906
|
}
|
|
1250
|
-
}
|
|
1907
|
+
}
|
|
1251
1908
|
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
userinfo_endpoint: `${authenticationDomain}/userinfo`,
|
|
1262
|
-
end_session_endpoint: `${authenticationDomain}/v2/logout` +
|
|
1263
|
-
`?returnTo=${encodeURIComponent(oidcConfiguration.logoutRedirectUri)}` +
|
|
1264
|
-
`&client_id=${oidcConfiguration.clientId}`,
|
|
1909
|
+
async function createTrade({ signers: { ethSigner, starkSigner }, request, config, }) {
|
|
1910
|
+
await validateChain(ethSigner, config.immutableXConfig);
|
|
1911
|
+
const ethAddress = await ethSigner.getAddress();
|
|
1912
|
+
const tradesApi = new TradesApi(config.immutableXConfig.apiConfiguration);
|
|
1913
|
+
const signableResult = await tradesApi.getSignableTrade({
|
|
1914
|
+
getSignableTradeRequest: {
|
|
1915
|
+
user: ethAddress,
|
|
1916
|
+
order_id: request.order_id,
|
|
1917
|
+
fees: request.fees,
|
|
1265
1918
|
},
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
|
|
1919
|
+
});
|
|
1920
|
+
const { signable_message: signableMessage, payload_hash: payloadHash } = signableResult.data;
|
|
1921
|
+
const ethSignature = await signRaw(signableMessage, ethSigner);
|
|
1922
|
+
const starkSignature = await starkSigner.signMessage(payloadHash);
|
|
1923
|
+
const createTradeResponse = await tradesApi.createTrade({
|
|
1924
|
+
createTradeRequest: {
|
|
1925
|
+
amount_buy: signableResult.data.amount_buy,
|
|
1926
|
+
amount_sell: signableResult.data.amount_sell,
|
|
1927
|
+
asset_id_buy: signableResult.data.asset_id_buy,
|
|
1928
|
+
asset_id_sell: signableResult.data.asset_id_sell,
|
|
1929
|
+
expiration_timestamp: signableResult.data.expiration_timestamp,
|
|
1930
|
+
fee_info: signableResult.data.fee_info,
|
|
1931
|
+
fees: request.fees,
|
|
1932
|
+
include_fees: true,
|
|
1933
|
+
nonce: signableResult.data.nonce,
|
|
1934
|
+
order_id: request.order_id,
|
|
1935
|
+
stark_key: signableResult.data.stark_key,
|
|
1936
|
+
vault_id_buy: signableResult.data.vault_id_buy,
|
|
1937
|
+
vault_id_sell: signableResult.data.vault_id_sell,
|
|
1938
|
+
stark_signature: starkSignature,
|
|
1939
|
+
},
|
|
1940
|
+
xImxEthAddress: ethAddress,
|
|
1941
|
+
xImxEthSignature: ethSignature,
|
|
1942
|
+
});
|
|
1943
|
+
return createTradeResponse.data;
|
|
1944
|
+
}
|
|
1945
|
+
|
|
1946
|
+
async function depositEth({ signers: { ethSigner }, deposit, config, }) {
|
|
1947
|
+
await validateChain(ethSigner, config.immutableXConfig);
|
|
1948
|
+
const user = await ethSigner.getAddress();
|
|
1949
|
+
const data = {
|
|
1950
|
+
decimals: 18,
|
|
1269
1951
|
};
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
|
|
1278
|
-
|
|
1279
|
-
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
this.userManager = new UserManager(getAuthConfiguration(config));
|
|
1283
|
-
}
|
|
1284
|
-
mapOidcUserToDomainModel = (oidcUser) => {
|
|
1285
|
-
const passport = oidcUser.profile?.passport;
|
|
1286
|
-
return {
|
|
1287
|
-
idToken: oidcUser.id_token,
|
|
1288
|
-
accessToken: oidcUser.access_token,
|
|
1289
|
-
refreshToken: oidcUser.refresh_token,
|
|
1290
|
-
profile: {
|
|
1291
|
-
sub: oidcUser.profile.sub,
|
|
1292
|
-
email: oidcUser.profile.email,
|
|
1293
|
-
nickname: oidcUser.profile.nickname,
|
|
1294
|
-
},
|
|
1295
|
-
etherKey: passport?.ether_key || '',
|
|
1296
|
-
};
|
|
1952
|
+
const amount = parseUnits(deposit.amount, 'wei');
|
|
1953
|
+
const imxConfig = config.immutableXConfig;
|
|
1954
|
+
const depositsApi = new DepositsApi(imxConfig.apiConfiguration);
|
|
1955
|
+
const encodingApi = new EncodingApi(imxConfig.apiConfiguration);
|
|
1956
|
+
const usersApi = new UsersApi(imxConfig.apiConfiguration);
|
|
1957
|
+
const getSignableDepositRequest = {
|
|
1958
|
+
user,
|
|
1959
|
+
token: {
|
|
1960
|
+
type: deposit.type,
|
|
1961
|
+
data,
|
|
1962
|
+
},
|
|
1963
|
+
amount: amount.toString(),
|
|
1297
1964
|
};
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
|
|
1301
|
-
|
|
1302
|
-
|
|
1303
|
-
|
|
1304
|
-
|
|
1305
|
-
|
|
1306
|
-
|
|
1307
|
-
|
|
1308
|
-
|
|
1309
|
-
|
|
1310
|
-
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
return
|
|
1315
|
-
const oidcUser = await this.userManager.getUser();
|
|
1316
|
-
if (!oidcUser) {
|
|
1317
|
-
throw new Error('Failed to retrieve user');
|
|
1318
|
-
}
|
|
1319
|
-
return this.mapOidcUserToDomainModel(oidcUser);
|
|
1320
|
-
}, PassportErrorType.NOT_LOGGED_IN_ERROR);
|
|
1965
|
+
const signableDepositResult = await depositsApi.getSignableDeposit({
|
|
1966
|
+
getSignableDepositRequest,
|
|
1967
|
+
});
|
|
1968
|
+
const encodingResult = await encodingApi.encodeAsset({
|
|
1969
|
+
assetType: 'asset',
|
|
1970
|
+
encodeAssetRequest: {
|
|
1971
|
+
token: {
|
|
1972
|
+
type: deposit.type,
|
|
1973
|
+
},
|
|
1974
|
+
},
|
|
1975
|
+
});
|
|
1976
|
+
const assetType = encodingResult.data.asset_type;
|
|
1977
|
+
const starkPublicKey = signableDepositResult.data.stark_key;
|
|
1978
|
+
const vaultId = signableDepositResult.data.vault_id;
|
|
1979
|
+
const isRegistered = await isRegisteredOnChain(starkPublicKey, ethSigner, config);
|
|
1980
|
+
if (!isRegistered) {
|
|
1981
|
+
return executeRegisterAndDepositEth(ethSigner, amount, assetType, starkPublicKey, vaultId, imxConfig, usersApi);
|
|
1321
1982
|
}
|
|
1322
|
-
|
|
1323
|
-
return
|
|
1324
|
-
const updatedUser = await retryWithDelay(async () => {
|
|
1325
|
-
const user = await this.userManager.signinSilent();
|
|
1326
|
-
const passportMetadata = user?.profile?.passport;
|
|
1327
|
-
const metadataExists = !!passportMetadata?.ether_key &&
|
|
1328
|
-
!!passportMetadata?.stark_key &&
|
|
1329
|
-
!!passportMetadata?.user_admin_key;
|
|
1330
|
-
if (metadataExists) {
|
|
1331
|
-
return user;
|
|
1332
|
-
}
|
|
1333
|
-
return Promise.reject('user wallet addresses not exist');
|
|
1334
|
-
});
|
|
1335
|
-
if (!updatedUser) {
|
|
1336
|
-
return null;
|
|
1337
|
-
}
|
|
1338
|
-
return this.mapOidcUserToDomainModel(updatedUser);
|
|
1339
|
-
}, PassportErrorType.REFRESH_TOKEN_ERROR);
|
|
1983
|
+
else {
|
|
1984
|
+
return executeDepositEth(ethSigner, amount, assetType, starkPublicKey, vaultId, imxConfig);
|
|
1340
1985
|
}
|
|
1341
1986
|
}
|
|
1987
|
+
async function executeRegisterAndDepositEth(ethSigner, amount, assetType, starkPublicKey, vaultId, config, usersApi) {
|
|
1988
|
+
const etherKey = await ethSigner.getAddress();
|
|
1989
|
+
const coreContract = Contracts.Core.connect(config.ethConfiguration.coreContractAddress, ethSigner);
|
|
1990
|
+
const signableResult = await getSignableRegistrationOnchain(etherKey, starkPublicKey, usersApi);
|
|
1991
|
+
const populatedTransaction = await coreContract.populateTransaction.registerAndDepositEth(etherKey, starkPublicKey, signableResult.operator_signature, assetType, vaultId);
|
|
1992
|
+
return ethSigner.sendTransaction({ ...populatedTransaction, value: amount });
|
|
1993
|
+
}
|
|
1994
|
+
async function executeDepositEth(ethSigner, amount, assetType, starkPublicKey, vaultId, config) {
|
|
1995
|
+
const coreContract = Contracts.Core.connect(config.ethConfiguration.coreContractAddress, ethSigner);
|
|
1996
|
+
const populatedTransaction = await coreContract.populateTransaction['deposit(uint256,uint256,uint256)'](starkPublicKey, assetType, vaultId);
|
|
1997
|
+
return ethSigner.sendTransaction({ ...populatedTransaction, value: amount });
|
|
1998
|
+
}
|
|
1342
1999
|
|
|
1343
|
-
|
|
1344
|
-
|
|
1345
|
-
config;
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
|
|
1349
|
-
|
|
1350
|
-
|
|
1351
|
-
|
|
2000
|
+
async function depositERC20({ signers: { ethSigner }, deposit, config, }) {
|
|
2001
|
+
await validateChain(ethSigner, config.immutableXConfig);
|
|
2002
|
+
const { apiConfiguration, ethConfiguration } = config.immutableXConfig;
|
|
2003
|
+
const user = await ethSigner.getAddress();
|
|
2004
|
+
const tokensApi = new TokensApi(apiConfiguration);
|
|
2005
|
+
const depositsApi = new DepositsApi(apiConfiguration);
|
|
2006
|
+
const encodingApi = new EncodingApi(apiConfiguration);
|
|
2007
|
+
const usersApi = new UsersApi(apiConfiguration);
|
|
2008
|
+
// Get decimals for this specific ERC20
|
|
2009
|
+
const token = await tokensApi.getToken({ address: deposit.tokenAddress });
|
|
2010
|
+
const decimals = parseInt(token.data.decimals);
|
|
2011
|
+
const data = {
|
|
2012
|
+
decimals,
|
|
2013
|
+
token_address: deposit.tokenAddress,
|
|
2014
|
+
};
|
|
2015
|
+
const amount = parseUnits(deposit.amount, 0); // 0 to always use undecimalized value
|
|
2016
|
+
// Approve whether an amount of token from an account can be spent by a third-party account
|
|
2017
|
+
const tokenContract = Contracts.IERC20.connect(deposit.tokenAddress, ethSigner);
|
|
2018
|
+
const approveTransaction = await tokenContract.populateTransaction.approve(ethConfiguration.coreContractAddress, amount);
|
|
2019
|
+
await ethSigner.sendTransaction(approveTransaction);
|
|
2020
|
+
const getSignableDepositRequest = {
|
|
2021
|
+
user,
|
|
2022
|
+
token: {
|
|
2023
|
+
type: deposit.type,
|
|
2024
|
+
data,
|
|
2025
|
+
},
|
|
2026
|
+
amount: amount.toString(),
|
|
2027
|
+
};
|
|
2028
|
+
const signableDepositResult = await depositsApi.getSignableDeposit({
|
|
2029
|
+
getSignableDepositRequest,
|
|
2030
|
+
});
|
|
2031
|
+
// Perform encoding on asset details to get an assetType (required for stark contract request)
|
|
2032
|
+
const encodingResult = await encodingApi.encodeAsset({
|
|
2033
|
+
assetType: 'asset',
|
|
2034
|
+
encodeAssetRequest: {
|
|
2035
|
+
token: {
|
|
2036
|
+
type: deposit.type,
|
|
2037
|
+
data: {
|
|
2038
|
+
token_address: deposit.tokenAddress,
|
|
2039
|
+
},
|
|
2040
|
+
},
|
|
2041
|
+
},
|
|
2042
|
+
});
|
|
2043
|
+
const assetType = encodingResult.data.asset_type;
|
|
2044
|
+
const starkPublicKey = signableDepositResult.data.stark_key;
|
|
2045
|
+
const vaultId = signableDepositResult.data.vault_id;
|
|
2046
|
+
const quantizedAmount = BigNumber.from(signableDepositResult.data.amount);
|
|
2047
|
+
const isRegistered = await isRegisteredOnChain(starkPublicKey, ethSigner, config);
|
|
2048
|
+
if (!isRegistered) {
|
|
2049
|
+
return executeRegisterAndDepositERC20(ethSigner, quantizedAmount, assetType, starkPublicKey, vaultId, ethConfiguration, usersApi);
|
|
1352
2050
|
}
|
|
1353
|
-
|
|
1354
|
-
return
|
|
1355
|
-
await this.magicClient.openid.loginWithOIDC({
|
|
1356
|
-
jwt: idToken,
|
|
1357
|
-
providerId: this.config.magicProviderId,
|
|
1358
|
-
});
|
|
1359
|
-
return new ethers.providers.Web3Provider(this.magicClient
|
|
1360
|
-
.rpcProvider);
|
|
1361
|
-
}, PassportErrorType.WALLET_CONNECTION_ERROR);
|
|
2051
|
+
else {
|
|
2052
|
+
return executeDepositERC20(ethSigner, quantizedAmount, assetType, starkPublicKey, vaultId, ethConfiguration);
|
|
1362
2053
|
}
|
|
1363
2054
|
}
|
|
2055
|
+
async function executeDepositERC20(ethSigner, quantizedAmount, assetType, starkPublicKey, vaultId, config) {
|
|
2056
|
+
const coreContract = Contracts.Core.connect(config.coreContractAddress, ethSigner);
|
|
2057
|
+
const populatedTransaction = await coreContract.populateTransaction.depositERC20(starkPublicKey, assetType, vaultId, quantizedAmount);
|
|
2058
|
+
return ethSigner.sendTransaction(populatedTransaction);
|
|
2059
|
+
}
|
|
2060
|
+
async function executeRegisterAndDepositERC20(ethSigner, quantizedAmount, assetType, starkPublicKey, vaultId, config, usersApi) {
|
|
2061
|
+
const etherKey = await ethSigner.getAddress();
|
|
2062
|
+
const coreContract = Contracts.Core.connect(config.coreContractAddress, ethSigner);
|
|
2063
|
+
const signableResult = await getSignableRegistrationOnchain(etherKey, starkPublicKey, usersApi);
|
|
2064
|
+
const populatedTransaction = await coreContract.populateTransaction.registerAndDepositERC20(etherKey, starkPublicKey, signableResult.operator_signature, assetType, vaultId, quantizedAmount);
|
|
2065
|
+
return ethSigner.sendTransaction(populatedTransaction);
|
|
2066
|
+
}
|
|
1364
2067
|
|
|
1365
|
-
|
|
1366
|
-
(
|
|
1367
|
-
|
|
1368
|
-
|
|
1369
|
-
|
|
1370
|
-
|
|
1371
|
-
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
|
|
1376
|
-
|
|
1377
|
-
|
|
1378
|
-
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
}
|
|
1383
|
-
|
|
1384
|
-
|
|
1385
|
-
const
|
|
1386
|
-
|
|
1387
|
-
|
|
1388
|
-
|
|
1389
|
-
|
|
1390
|
-
|
|
1391
|
-
|
|
1392
|
-
|
|
1393
|
-
|
|
1394
|
-
|
|
1395
|
-
|
|
1396
|
-
|
|
1397
|
-
|
|
1398
|
-
|
|
1399
|
-
|
|
1400
|
-
};
|
|
1401
|
-
|
|
1402
|
-
const
|
|
1403
|
-
const
|
|
1404
|
-
const
|
|
1405
|
-
|
|
1406
|
-
|
|
1407
|
-
|
|
1408
|
-
|
|
1409
|
-
|
|
2068
|
+
async function depositERC721({ signers: { ethSigner }, deposit, config, }) {
|
|
2069
|
+
await validateChain(ethSigner, config.immutableXConfig);
|
|
2070
|
+
const user = await ethSigner.getAddress();
|
|
2071
|
+
const { immutableXConfig } = config;
|
|
2072
|
+
const depositsApi = new DepositsApi(immutableXConfig.apiConfiguration);
|
|
2073
|
+
const encodingApi = new EncodingApi(immutableXConfig.apiConfiguration);
|
|
2074
|
+
const usersApi = new UsersApi(immutableXConfig.apiConfiguration);
|
|
2075
|
+
const data = {
|
|
2076
|
+
token_address: deposit.tokenAddress,
|
|
2077
|
+
token_id: deposit.tokenId,
|
|
2078
|
+
};
|
|
2079
|
+
const amount = '1';
|
|
2080
|
+
const getSignableDepositRequest = {
|
|
2081
|
+
user,
|
|
2082
|
+
token: {
|
|
2083
|
+
type: deposit.type,
|
|
2084
|
+
data,
|
|
2085
|
+
},
|
|
2086
|
+
amount: amount.toString(),
|
|
2087
|
+
};
|
|
2088
|
+
const signableDepositResult = await depositsApi.getSignableDeposit({
|
|
2089
|
+
getSignableDepositRequest,
|
|
2090
|
+
});
|
|
2091
|
+
// Perform encoding on asset details to get an assetType (required for stark contract request)
|
|
2092
|
+
const encodingResult = await encodingApi.encodeAsset({
|
|
2093
|
+
assetType: 'asset',
|
|
2094
|
+
encodeAssetRequest: {
|
|
2095
|
+
token: {
|
|
2096
|
+
type: deposit.type,
|
|
2097
|
+
data: {
|
|
2098
|
+
token_address: deposit.tokenAddress,
|
|
2099
|
+
token_id: deposit.tokenId,
|
|
2100
|
+
},
|
|
2101
|
+
},
|
|
2102
|
+
},
|
|
2103
|
+
});
|
|
2104
|
+
const assetType = encodingResult.data.asset_type;
|
|
2105
|
+
const starkPublicKey = signableDepositResult.data.stark_key;
|
|
2106
|
+
const vaultId = signableDepositResult.data.vault_id;
|
|
2107
|
+
const isRegistered = await isRegisteredOnChain(starkPublicKey, ethSigner, config);
|
|
2108
|
+
// Approve whether an amount of token from an account can be spent by a third-party account
|
|
2109
|
+
const tokenContract = Contracts.IERC721.connect(deposit.tokenAddress, ethSigner);
|
|
2110
|
+
const operator = immutableXConfig.ethConfiguration.coreContractAddress;
|
|
2111
|
+
const isApprovedForAll = await tokenContract.isApprovedForAll(user, operator);
|
|
2112
|
+
if (!isApprovedForAll) {
|
|
2113
|
+
await tokenContract.setApprovalForAll(operator, true);
|
|
1410
2114
|
}
|
|
1411
|
-
|
|
1412
|
-
|
|
1413
|
-
|
|
1414
|
-
|
|
1415
|
-
|
|
1416
|
-
}, this.config.passportDomain);
|
|
2115
|
+
if (!isRegistered) {
|
|
2116
|
+
const signableResult = await getSignableRegistrationOnchain(user, starkPublicKey, usersApi);
|
|
2117
|
+
const coreContract = Contracts.Core.connect(immutableXConfig.ethConfiguration.coreContractAddress, ethSigner);
|
|
2118
|
+
// Note: proxy registration contract registerAndDepositNft method is not used as it currently fails erc721 transfer ownership check
|
|
2119
|
+
await coreContract.registerUser(user, starkPublicKey, signableResult.operator_signature);
|
|
1417
2120
|
}
|
|
1418
|
-
|
|
1419
|
-
|
|
1420
|
-
|
|
1421
|
-
|
|
1422
|
-
|
|
1423
|
-
|
|
1424
|
-
|
|
1425
|
-
|
|
1426
|
-
|
|
1427
|
-
|
|
1428
|
-
|
|
1429
|
-
|
|
1430
|
-
|
|
1431
|
-
|
|
1432
|
-
|
|
1433
|
-
|
|
1434
|
-
resolve({ confirmed: true });
|
|
1435
|
-
break;
|
|
1436
|
-
}
|
|
1437
|
-
case ReceiveMessage.TRANSACTION_ERROR: {
|
|
1438
|
-
reject(new Error('Transaction error'));
|
|
1439
|
-
break;
|
|
1440
|
-
}
|
|
1441
|
-
default:
|
|
1442
|
-
reject(new Error('Unsupported message type'));
|
|
1443
|
-
}
|
|
1444
|
-
};
|
|
1445
|
-
window.addEventListener('message', messageHandler);
|
|
1446
|
-
const confirmationWindow = openPopupCenter({
|
|
1447
|
-
url: `${this.config.passportDomain}/transaction-confirmation`,
|
|
1448
|
-
title: ConfirmationWindowTitle,
|
|
1449
|
-
width: popupOptions?.width || ConfirmationWindowWidth,
|
|
1450
|
-
height: popupOptions?.height || ConfirmationWindowHeight,
|
|
1451
|
-
});
|
|
1452
|
-
// https://stackoverflow.com/questions/9388380/capture-the-close-event-of-popup-window-in-javascript/48240128#48240128
|
|
1453
|
-
const timer = setInterval(function () {
|
|
1454
|
-
if (confirmationWindow.closed) {
|
|
1455
|
-
clearInterval(timer);
|
|
1456
|
-
window.removeEventListener('message', messageHandler);
|
|
1457
|
-
resolve({ confirmed: false });
|
|
1458
|
-
}
|
|
1459
|
-
}, ConfirmationWindowClosedPollingDuration);
|
|
1460
|
-
});
|
|
2121
|
+
return executeDepositERC721(ethSigner, deposit.tokenId, assetType, starkPublicKey, vaultId, immutableXConfig);
|
|
2122
|
+
}
|
|
2123
|
+
async function executeDepositERC721(ethSigner, tokenId, assetType, starkPublicKey, vaultId, config) {
|
|
2124
|
+
const coreContract = Contracts.Core.connect(config.ethConfiguration.coreContractAddress, ethSigner);
|
|
2125
|
+
const populatedTransaction = await coreContract.populateTransaction.depositNft(starkPublicKey, assetType, vaultId, tokenId);
|
|
2126
|
+
return ethSigner.sendTransaction(populatedTransaction);
|
|
2127
|
+
}
|
|
2128
|
+
|
|
2129
|
+
async function deposit({ signers, deposit, config }) {
|
|
2130
|
+
switch (deposit.type) {
|
|
2131
|
+
case 'ETH':
|
|
2132
|
+
return depositEth({ signers, deposit, config });
|
|
2133
|
+
case 'ERC20':
|
|
2134
|
+
return depositERC20({ signers, deposit, config });
|
|
2135
|
+
case 'ERC721':
|
|
2136
|
+
return depositERC721({ signers, deposit, config });
|
|
1461
2137
|
}
|
|
1462
2138
|
}
|
|
1463
2139
|
|
|
1464
|
-
|
|
1465
|
-
|
|
1466
|
-
|
|
1467
|
-
|
|
1468
|
-
|
|
1469
|
-
|
|
2140
|
+
async function exchangeTransfer({ signers, request, config, }) {
|
|
2141
|
+
await validateChain(signers.ethSigner, config.immutableXConfig);
|
|
2142
|
+
const exchangeApi = new ExchangesApi(config.immutableXConfig.apiConfiguration);
|
|
2143
|
+
const ethAddress = await signers.ethSigner.getAddress();
|
|
2144
|
+
const transferAmount = request.amount;
|
|
2145
|
+
const signableResult = await exchangeApi.getExchangeSignableTransfer({
|
|
2146
|
+
id: request.transactionID,
|
|
2147
|
+
getSignableTransferRequest: {
|
|
2148
|
+
sender: ethAddress,
|
|
1470
2149
|
token: convertToSignableToken(request),
|
|
1471
2150
|
amount: transferAmount,
|
|
1472
2151
|
receiver: request.receiver,
|
|
1473
|
-
}
|
|
1474
|
-
|
|
1475
|
-
|
|
2152
|
+
},
|
|
2153
|
+
});
|
|
2154
|
+
const { signable_message: signableMessage, payload_hash: payloadHash } = signableResult.data;
|
|
2155
|
+
const ethSignature = await signRaw(signableMessage, signers.ethSigner);
|
|
2156
|
+
const starkSignature = await signers.starkSigner.signMessage(payloadHash);
|
|
2157
|
+
const transferSigningParams = {
|
|
2158
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
2159
|
+
sender_stark_key: signableResult.data.sender_stark_key,
|
|
2160
|
+
sender_vault_id: signableResult.data.sender_vault_id,
|
|
2161
|
+
receiver_stark_key: signableResult.data.receiver_stark_key,
|
|
2162
|
+
receiver_vault_id: signableResult.data.receiver_vault_id,
|
|
2163
|
+
asset_id: signableResult.data.asset_id,
|
|
2164
|
+
amount: signableResult.data.amount,
|
|
2165
|
+
nonce: signableResult.data.nonce,
|
|
2166
|
+
expiration_timestamp: signableResult.data.expiration_timestamp,
|
|
2167
|
+
stark_signature: starkSignature,
|
|
2168
|
+
};
|
|
2169
|
+
const response = await exchangeApi.createExchangeTransfer({
|
|
2170
|
+
id: request.transactionID,
|
|
2171
|
+
createTransferRequest: transferSigningParams,
|
|
2172
|
+
xImxEthAddress: ethAddress,
|
|
2173
|
+
xImxEthSignature: ethSignature,
|
|
2174
|
+
});
|
|
2175
|
+
return {
|
|
2176
|
+
sent_signature: response?.data.sent_signature,
|
|
2177
|
+
status: response?.data.status?.toString(),
|
|
2178
|
+
time: response?.data.time,
|
|
2179
|
+
transfer_id: response?.data.transfer_id,
|
|
2180
|
+
};
|
|
2181
|
+
}
|
|
2182
|
+
|
|
2183
|
+
class GenericIMXProvider {
|
|
2184
|
+
config;
|
|
2185
|
+
signers;
|
|
2186
|
+
constructor(config, ethSigner, starkSigner) {
|
|
2187
|
+
this.config = config;
|
|
2188
|
+
this.signers = { ethSigner, starkSigner };
|
|
2189
|
+
}
|
|
2190
|
+
async getAddress() {
|
|
2191
|
+
return await this.signers.ethSigner.getAddress();
|
|
2192
|
+
}
|
|
2193
|
+
registerOffchain() {
|
|
2194
|
+
return registerOffchain(this.signers, this.config);
|
|
2195
|
+
}
|
|
2196
|
+
batchNftTransfer(request) {
|
|
2197
|
+
return batchTransfer({
|
|
2198
|
+
signers: this.signers,
|
|
2199
|
+
request,
|
|
2200
|
+
config: this.config,
|
|
1476
2201
|
});
|
|
1477
|
-
|
|
1478
|
-
|
|
1479
|
-
|
|
1480
|
-
|
|
2202
|
+
}
|
|
2203
|
+
cancelOrder(request) {
|
|
2204
|
+
return cancelOrder({
|
|
2205
|
+
signers: this.signers,
|
|
2206
|
+
request,
|
|
2207
|
+
config: this.config,
|
|
1481
2208
|
});
|
|
1482
|
-
|
|
1483
|
-
|
|
1484
|
-
|
|
1485
|
-
|
|
1486
|
-
|
|
1487
|
-
|
|
1488
|
-
|
|
1489
|
-
const transferSigningParams = {
|
|
1490
|
-
sender_stark_key: signableResultData.sender_stark_key || senderStarkKey,
|
|
1491
|
-
sender_vault_id: signableResultData.sender_vault_id,
|
|
1492
|
-
receiver_stark_key: signableResultData.receiver_stark_key,
|
|
1493
|
-
receiver_vault_id: signableResultData.receiver_vault_id,
|
|
1494
|
-
asset_id: signableResultData.asset_id,
|
|
1495
|
-
amount: signableResultData.amount,
|
|
1496
|
-
nonce: signableResultData.nonce,
|
|
1497
|
-
expiration_timestamp: signableResultData.expiration_timestamp,
|
|
1498
|
-
stark_signature: starkSignature,
|
|
1499
|
-
};
|
|
1500
|
-
const createTransferRequest = {
|
|
1501
|
-
createTransferRequest: transferSigningParams,
|
|
1502
|
-
};
|
|
1503
|
-
const headers = {
|
|
1504
|
-
Authorization: 'Bearer ' + user.accessToken,
|
|
1505
|
-
};
|
|
1506
|
-
const { data: responseData } = await transfersApi.createTransferV1(createTransferRequest, { headers });
|
|
1507
|
-
return {
|
|
1508
|
-
sent_signature: responseData.sent_signature,
|
|
1509
|
-
status: responseData.status?.toString(),
|
|
1510
|
-
time: responseData.time,
|
|
1511
|
-
transfer_id: responseData.transfer_id,
|
|
1512
|
-
};
|
|
1513
|
-
}, PassportErrorType.TRANSFER_ERROR);
|
|
1514
|
-
};
|
|
1515
|
-
async function batchNftTransfer({ user, starkSigner, request, transfersApi, passportConfig, }) {
|
|
1516
|
-
return withPassportError(async () => {
|
|
1517
|
-
const ethAddress = user.etherKey;
|
|
1518
|
-
const signableRequests = request.map((nftTransfer) => {
|
|
1519
|
-
return {
|
|
1520
|
-
amount: '1',
|
|
1521
|
-
token: convertToSignableToken({
|
|
1522
|
-
type: ERC721$1,
|
|
1523
|
-
tokenId: nftTransfer.tokenId,
|
|
1524
|
-
tokenAddress: nftTransfer.tokenAddress,
|
|
1525
|
-
}),
|
|
1526
|
-
receiver: nftTransfer.receiver,
|
|
1527
|
-
};
|
|
2209
|
+
}
|
|
2210
|
+
completeWithdrawal(starkPublicKey, token) {
|
|
2211
|
+
return completeWithdrawal({
|
|
2212
|
+
config: this.config,
|
|
2213
|
+
signers: this.signers,
|
|
2214
|
+
token,
|
|
2215
|
+
starkPublicKey,
|
|
1528
2216
|
});
|
|
1529
|
-
|
|
1530
|
-
|
|
1531
|
-
|
|
1532
|
-
|
|
1533
|
-
|
|
1534
|
-
|
|
2217
|
+
}
|
|
2218
|
+
createOrder(request) {
|
|
2219
|
+
return createOrder({
|
|
2220
|
+
signers: this.signers,
|
|
2221
|
+
request,
|
|
2222
|
+
config: this.config,
|
|
1535
2223
|
});
|
|
1536
|
-
|
|
1537
|
-
|
|
1538
|
-
|
|
1539
|
-
|
|
1540
|
-
|
|
1541
|
-
|
|
1542
|
-
if (!confirmationResult.confirmed) {
|
|
1543
|
-
throw new Error('Transaction rejected by user');
|
|
1544
|
-
}
|
|
1545
|
-
const requests = await Promise.all(signableResult.data.signable_responses.map(async (resp) => {
|
|
1546
|
-
const starkSignature = await starkSigner.signMessage(resp.payload_hash);
|
|
1547
|
-
return {
|
|
1548
|
-
sender_vault_id: resp.sender_vault_id,
|
|
1549
|
-
receiver_stark_key: resp.receiver_stark_key,
|
|
1550
|
-
receiver_vault_id: resp.receiver_vault_id,
|
|
1551
|
-
asset_id: resp.asset_id,
|
|
1552
|
-
amount: resp.amount,
|
|
1553
|
-
nonce: resp.nonce,
|
|
1554
|
-
expiration_timestamp: resp.expiration_timestamp,
|
|
1555
|
-
stark_signature: starkSignature,
|
|
1556
|
-
};
|
|
1557
|
-
}));
|
|
1558
|
-
const transferSigningParams = {
|
|
1559
|
-
sender_stark_key: signableResult.data.sender_stark_key,
|
|
1560
|
-
requests,
|
|
1561
|
-
};
|
|
1562
|
-
const headers = {
|
|
1563
|
-
Authorization: 'Bearer ' + user.accessToken,
|
|
1564
|
-
};
|
|
1565
|
-
const response = await transfersApi.createTransfer({
|
|
1566
|
-
createTransferRequestV2: transferSigningParams,
|
|
1567
|
-
}, { headers });
|
|
1568
|
-
return {
|
|
1569
|
-
transfer_ids: response?.data.transfer_ids,
|
|
1570
|
-
};
|
|
1571
|
-
}, PassportErrorType.TRANSFER_ERROR);
|
|
1572
|
-
}
|
|
1573
|
-
|
|
1574
|
-
const ERC721 = 'ERC721';
|
|
1575
|
-
async function createOrder({ starkSigner, user, request, ordersApi, passportConfig, }) {
|
|
1576
|
-
return withPassportError(async () => {
|
|
1577
|
-
const ethAddress = user.etherKey;
|
|
1578
|
-
const amountSell = request.sell.type === ERC721 ? '1' : request.sell.amount;
|
|
1579
|
-
const amountBuy = request.buy.type === ERC721 ? '1' : request.buy.amount;
|
|
1580
|
-
const getSignableOrderRequestV3 = {
|
|
1581
|
-
user: ethAddress,
|
|
1582
|
-
amount_buy: amountBuy,
|
|
1583
|
-
token_buy: convertToSignableToken(request.buy),
|
|
1584
|
-
amount_sell: amountSell,
|
|
1585
|
-
token_sell: convertToSignableToken(request.sell),
|
|
1586
|
-
fees: request.fees,
|
|
1587
|
-
expiration_timestamp: request.expiration_timestamp,
|
|
1588
|
-
};
|
|
1589
|
-
const getSignableOrderResponse = await ordersApi.getSignableOrder({
|
|
1590
|
-
getSignableOrderRequestV3,
|
|
2224
|
+
}
|
|
2225
|
+
createTrade(request) {
|
|
2226
|
+
return createTrade({
|
|
2227
|
+
signers: this.signers,
|
|
2228
|
+
request,
|
|
2229
|
+
config: this.config,
|
|
1591
2230
|
});
|
|
1592
|
-
|
|
1593
|
-
|
|
1594
|
-
|
|
1595
|
-
|
|
2231
|
+
}
|
|
2232
|
+
deposit(tokenAmount) {
|
|
2233
|
+
return deposit({
|
|
2234
|
+
signers: this.signers,
|
|
2235
|
+
deposit: tokenAmount,
|
|
2236
|
+
config: this.config,
|
|
1596
2237
|
});
|
|
1597
|
-
|
|
1598
|
-
|
|
1599
|
-
|
|
1600
|
-
|
|
1601
|
-
|
|
1602
|
-
|
|
1603
|
-
const orderParams = {
|
|
1604
|
-
createOrderRequest: {
|
|
1605
|
-
include_fees: true,
|
|
1606
|
-
fees: request.fees,
|
|
1607
|
-
stark_signature: starkSignature,
|
|
1608
|
-
amount_buy: signableResultData.amount_buy,
|
|
1609
|
-
amount_sell: signableResultData.amount_sell,
|
|
1610
|
-
asset_id_buy: signableResultData.asset_id_buy,
|
|
1611
|
-
asset_id_sell: signableResultData.asset_id_sell,
|
|
1612
|
-
expiration_timestamp: signableResultData.expiration_timestamp,
|
|
1613
|
-
nonce: signableResultData.nonce,
|
|
1614
|
-
stark_key: signableResultData.stark_key,
|
|
1615
|
-
vault_id_buy: signableResultData.vault_id_buy,
|
|
1616
|
-
vault_id_sell: signableResultData.vault_id_sell,
|
|
1617
|
-
},
|
|
1618
|
-
};
|
|
1619
|
-
const headers = {
|
|
1620
|
-
Authorization: 'Bearer ' + user.accessToken,
|
|
1621
|
-
};
|
|
1622
|
-
const createOrderResponse = await ordersApi.createOrder(orderParams, {
|
|
1623
|
-
headers,
|
|
2238
|
+
}
|
|
2239
|
+
exchangeTransfer(request) {
|
|
2240
|
+
return exchangeTransfer({
|
|
2241
|
+
signers: this.signers,
|
|
2242
|
+
request,
|
|
2243
|
+
config: this.config,
|
|
1624
2244
|
});
|
|
1625
|
-
|
|
1626
|
-
|
|
1627
|
-
|
|
1628
|
-
|
|
1629
|
-
}
|
|
1630
|
-
|
|
1631
|
-
|
|
1632
|
-
|
|
1633
|
-
|
|
1634
|
-
|
|
1635
|
-
const getSignableCancelOrderResponse = await ordersApi.getSignableCancelOrder({
|
|
1636
|
-
getSignableCancelOrderRequest,
|
|
2245
|
+
}
|
|
2246
|
+
async isRegisteredOnchain() {
|
|
2247
|
+
const starkPublicKey = await this.signers.starkSigner.getAddress();
|
|
2248
|
+
return isRegisteredOnChain(starkPublicKey, this.signers.ethSigner, this.config);
|
|
2249
|
+
}
|
|
2250
|
+
prepareWithdrawal(request) {
|
|
2251
|
+
return prepareWithdrawal({
|
|
2252
|
+
signers: this.signers,
|
|
2253
|
+
withdrawal: request,
|
|
2254
|
+
config: this.config,
|
|
1637
2255
|
});
|
|
1638
|
-
|
|
1639
|
-
|
|
1640
|
-
|
|
1641
|
-
|
|
2256
|
+
}
|
|
2257
|
+
transfer(request) {
|
|
2258
|
+
return transfer({
|
|
2259
|
+
signers: this.signers,
|
|
2260
|
+
request,
|
|
2261
|
+
config: this.config,
|
|
1642
2262
|
});
|
|
1643
|
-
|
|
1644
|
-
throw new Error('Transaction rejected by user');
|
|
1645
|
-
}
|
|
1646
|
-
const { payload_hash: payloadHash } = getSignableCancelOrderResponse.data;
|
|
1647
|
-
const starkSignature = await starkSigner.signMessage(payloadHash);
|
|
1648
|
-
const headers = {
|
|
1649
|
-
Authorization: 'Bearer ' + user.accessToken,
|
|
1650
|
-
};
|
|
1651
|
-
const cancelOrderResponse = await ordersApi.cancelOrder({
|
|
1652
|
-
id: request.order_id.toString(),
|
|
1653
|
-
cancelOrderRequest: {
|
|
1654
|
-
order_id: request.order_id,
|
|
1655
|
-
stark_signature: starkSignature,
|
|
1656
|
-
},
|
|
1657
|
-
}, { headers });
|
|
1658
|
-
return {
|
|
1659
|
-
order_id: cancelOrderResponse.data.order_id,
|
|
1660
|
-
status: cancelOrderResponse.data.status,
|
|
1661
|
-
};
|
|
1662
|
-
}, PassportErrorType.CANCEL_ORDER_ERROR);
|
|
2263
|
+
}
|
|
1663
2264
|
}
|
|
1664
2265
|
|
|
1665
|
-
|
|
1666
|
-
|
|
1667
|
-
|
|
1668
|
-
|
|
1669
|
-
|
|
1670
|
-
|
|
1671
|
-
|
|
1672
|
-
|
|
1673
|
-
|
|
1674
|
-
|
|
1675
|
-
|
|
1676
|
-
|
|
2266
|
+
const WALLET_ACTION = {
|
|
2267
|
+
SWITCH_CHAIN: 'wallet_switchEthereumChain',
|
|
2268
|
+
CONNECT: 'eth_requestAccounts',
|
|
2269
|
+
};
|
|
2270
|
+
function isRequestableProvider(provider) {
|
|
2271
|
+
return !!provider?.request;
|
|
2272
|
+
}
|
|
2273
|
+
async function connectProvider(provider, chainID) {
|
|
2274
|
+
await provider.request({ method: WALLET_ACTION.CONNECT });
|
|
2275
|
+
if (chainID) {
|
|
2276
|
+
await provider.request({
|
|
2277
|
+
method: WALLET_ACTION.SWITCH_CHAIN,
|
|
2278
|
+
params: [{ chainId: `0x${chainID.toString(16)}` }],
|
|
1677
2279
|
});
|
|
1678
|
-
|
|
1679
|
-
const { payload_hash: payloadHash } = signableResult.data;
|
|
1680
|
-
const starkSignature = await starkSigner.signMessage(payloadHash);
|
|
1681
|
-
const transferSigningParams = {
|
|
1682
|
-
sender_stark_key: signableResult.data.sender_stark_key || starkAddress,
|
|
1683
|
-
sender_vault_id: signableResult.data.sender_vault_id,
|
|
1684
|
-
receiver_stark_key: signableResult.data.receiver_stark_key,
|
|
1685
|
-
receiver_vault_id: signableResult.data.receiver_vault_id,
|
|
1686
|
-
asset_id: signableResult.data.asset_id,
|
|
1687
|
-
amount: signableResult.data.amount,
|
|
1688
|
-
nonce: signableResult.data.nonce,
|
|
1689
|
-
expiration_timestamp: signableResult.data.expiration_timestamp,
|
|
1690
|
-
stark_signature: starkSignature,
|
|
1691
|
-
};
|
|
1692
|
-
const headers = {
|
|
1693
|
-
Authorization: 'Bearer ' + user.accessToken,
|
|
1694
|
-
};
|
|
1695
|
-
const response = await exchangesApi.createExchangeTransfer({
|
|
1696
|
-
id: request.transactionID,
|
|
1697
|
-
createTransferRequest: transferSigningParams,
|
|
1698
|
-
}, { headers });
|
|
1699
|
-
return {
|
|
1700
|
-
sent_signature: response?.data.sent_signature,
|
|
1701
|
-
status: response?.data.status?.toString(),
|
|
1702
|
-
time: response?.data.time,
|
|
1703
|
-
transfer_id: response?.data.transfer_id,
|
|
1704
|
-
};
|
|
1705
|
-
}, PassportErrorType.EXCHANGE_TRANSFER_ERROR);
|
|
2280
|
+
}
|
|
1706
2281
|
}
|
|
1707
2282
|
|
|
1708
|
-
|
|
1709
|
-
|
|
1710
|
-
|
|
1711
|
-
|
|
1712
|
-
|
|
1713
|
-
|
|
1714
|
-
|
|
1715
|
-
|
|
1716
|
-
|
|
1717
|
-
|
|
1718
|
-
|
|
1719
|
-
|
|
1720
|
-
const confirmationScreen = new ConfirmationScreen(passportConfig);
|
|
1721
|
-
const confirmationResult = await confirmationScreen.startTransaction(user.accessToken, {
|
|
1722
|
-
transactionType: TransactionTypes.CreateTrade,
|
|
1723
|
-
transactionData: getSignableTradeRequest,
|
|
1724
|
-
});
|
|
1725
|
-
if (!confirmationResult.confirmed) {
|
|
1726
|
-
throw new Error('Transaction rejected by user');
|
|
1727
|
-
}
|
|
1728
|
-
const { payload_hash: payloadHash } = getSignableTradeResponse.data;
|
|
1729
|
-
const starkSignature = await starkSigner.signMessage(payloadHash);
|
|
1730
|
-
const { data: signableResultData } = getSignableTradeResponse;
|
|
1731
|
-
const tradeParams = {
|
|
1732
|
-
createTradeRequest: {
|
|
1733
|
-
include_fees: true,
|
|
1734
|
-
fees: request?.fees,
|
|
1735
|
-
stark_signature: starkSignature,
|
|
1736
|
-
order_id: request?.order_id,
|
|
1737
|
-
fee_info: signableResultData.fee_info,
|
|
1738
|
-
amount_buy: signableResultData.amount_buy,
|
|
1739
|
-
amount_sell: signableResultData.amount_sell,
|
|
1740
|
-
asset_id_buy: signableResultData.asset_id_buy,
|
|
1741
|
-
asset_id_sell: signableResultData.asset_id_sell,
|
|
1742
|
-
expiration_timestamp: signableResultData.expiration_timestamp,
|
|
1743
|
-
nonce: signableResultData.nonce,
|
|
1744
|
-
stark_key: signableResultData.stark_key,
|
|
1745
|
-
vault_id_buy: signableResultData.vault_id_buy,
|
|
1746
|
-
vault_id_sell: signableResultData.vault_id_sell,
|
|
1747
|
-
},
|
|
1748
|
-
};
|
|
1749
|
-
const headers = { Authorization: 'Bearer ' + user.accessToken };
|
|
1750
|
-
const { data: createTradeResponse } = await tradesApi.createTradeV3(tradeParams, {
|
|
1751
|
-
headers,
|
|
1752
|
-
});
|
|
1753
|
-
return createTradeResponse;
|
|
1754
|
-
}, PassportErrorType.CREATE_TRADE_ERROR);
|
|
2283
|
+
const ERRORS = {
|
|
2284
|
+
PROVIDER_NOT_FOUND: 'The Metamask provider was not found',
|
|
2285
|
+
};
|
|
2286
|
+
async function connect$1({ chainID, }) {
|
|
2287
|
+
const provider = (await detectEthereumProvider());
|
|
2288
|
+
if (!isRequestableProvider(provider)) {
|
|
2289
|
+
throw new Error(ERRORS.PROVIDER_NOT_FOUND);
|
|
2290
|
+
}
|
|
2291
|
+
await connectProvider(provider, chainID);
|
|
2292
|
+
// NOTE: if we want to listen to Metamask events in the future, we can add a
|
|
2293
|
+
// listener here.
|
|
2294
|
+
return new ethers.providers.Web3Provider(provider);
|
|
1755
2295
|
}
|
|
1756
2296
|
|
|
1757
|
-
|
|
1758
|
-
|
|
1759
|
-
|
|
1760
|
-
|
|
1761
|
-
|
|
1762
|
-
|
|
1763
|
-
|
|
1764
|
-
|
|
1765
|
-
|
|
1766
|
-
|
|
1767
|
-
|
|
1768
|
-
|
|
1769
|
-
|
|
1770
|
-
|
|
1771
|
-
|
|
1772
|
-
|
|
1773
|
-
|
|
1774
|
-
|
|
1775
|
-
|
|
2297
|
+
const COMMUNICATION_TYPE = 'message';
|
|
2298
|
+
var RequestEventType;
|
|
2299
|
+
(function (RequestEventType) {
|
|
2300
|
+
RequestEventType["GET_CONNECTION_REQUEST"] = "GET_CONNECTION_REQUEST";
|
|
2301
|
+
RequestEventType["CONNECT_WALLET_REQUEST"] = "CONNECT_WALLET_REQUEST";
|
|
2302
|
+
RequestEventType["SIGN_MESSAGE_REQUEST"] = "SIGN_MESSAGE_REQUEST";
|
|
2303
|
+
RequestEventType["DISCONNECT_WALLET_REQUEST"] = "DISCONNECT_WALLET_REQUEST";
|
|
2304
|
+
})(RequestEventType || (RequestEventType = {}));
|
|
2305
|
+
var ResponseEventType;
|
|
2306
|
+
(function (ResponseEventType) {
|
|
2307
|
+
ResponseEventType["CONNECT_WALLET_RESPONSE"] = "CONNECT_WALLET_RESPONSE";
|
|
2308
|
+
ResponseEventType["SIGN_MESSAGE_RESPONSE"] = "SIGN_MESSAGE_RESPONSE";
|
|
2309
|
+
ResponseEventType["GET_CONNECTION_RESPONSE"] = "GET_CONNECTION_RESPONSE";
|
|
2310
|
+
ResponseEventType["DISCONNECT_WALLET_RESPONSE"] = "DISCONNECT_WALLET_RESPONSE";
|
|
2311
|
+
})(ResponseEventType || (ResponseEventType = {}));
|
|
2312
|
+
|
|
2313
|
+
function postRequestMessage(iframe, payload) {
|
|
2314
|
+
if (iframe && iframe.contentWindow) {
|
|
2315
|
+
iframe.contentWindow.postMessage(payload, new URL(iframe.src).origin);
|
|
1776
2316
|
}
|
|
1777
|
-
|
|
1778
|
-
|
|
1779
|
-
|
|
1780
|
-
|
|
1781
|
-
|
|
1782
|
-
transfersApi: this.transfersApi,
|
|
1783
|
-
passportConfig: this.passportConfig,
|
|
1784
|
-
});
|
|
2317
|
+
}
|
|
2318
|
+
|
|
2319
|
+
function messageResponseListener(iframe, event, eventType, callback) {
|
|
2320
|
+
if (iframe && event.source !== iframe.contentWindow) {
|
|
2321
|
+
return;
|
|
1785
2322
|
}
|
|
1786
|
-
|
|
1787
|
-
|
|
2323
|
+
const l2WalletMessage = event.data;
|
|
2324
|
+
if (l2WalletMessage.type !== eventType) {
|
|
2325
|
+
return;
|
|
1788
2326
|
}
|
|
1789
|
-
|
|
1790
|
-
|
|
2327
|
+
callback(l2WalletMessage.details);
|
|
2328
|
+
}
|
|
2329
|
+
|
|
2330
|
+
class ImxSigner {
|
|
2331
|
+
publicAddress;
|
|
2332
|
+
iframe;
|
|
2333
|
+
constructor(publicAddress, iframe) {
|
|
2334
|
+
this.publicAddress = publicAddress;
|
|
2335
|
+
this.iframe = iframe;
|
|
1791
2336
|
}
|
|
1792
|
-
|
|
1793
|
-
return
|
|
1794
|
-
request,
|
|
1795
|
-
user: this.user,
|
|
1796
|
-
starkSigner: this.starkSigner,
|
|
1797
|
-
ordersApi: this.ordersApi,
|
|
1798
|
-
passportConfig: this.passportConfig,
|
|
1799
|
-
});
|
|
2337
|
+
getAddress() {
|
|
2338
|
+
return this.publicAddress;
|
|
1800
2339
|
}
|
|
1801
|
-
|
|
1802
|
-
return
|
|
1803
|
-
|
|
1804
|
-
|
|
1805
|
-
|
|
1806
|
-
|
|
1807
|
-
|
|
2340
|
+
signMessage(rawMessage) {
|
|
2341
|
+
return new Promise((resolve, reject) => {
|
|
2342
|
+
const listener = (event) => {
|
|
2343
|
+
messageResponseListener(this.iframe, event, ResponseEventType.SIGN_MESSAGE_RESPONSE, (messageDetails) => {
|
|
2344
|
+
window.removeEventListener(COMMUNICATION_TYPE, listener);
|
|
2345
|
+
if (!messageDetails.success) {
|
|
2346
|
+
reject(new Error(messageDetails.error?.message));
|
|
2347
|
+
}
|
|
2348
|
+
resolve(messageDetails.data.signedMessage);
|
|
2349
|
+
});
|
|
2350
|
+
};
|
|
2351
|
+
window.addEventListener(COMMUNICATION_TYPE, listener);
|
|
2352
|
+
postRequestMessage(this.iframe, {
|
|
2353
|
+
type: RequestEventType.SIGN_MESSAGE_REQUEST,
|
|
2354
|
+
details: { starkPublicKey: this.publicAddress, message: rawMessage },
|
|
2355
|
+
});
|
|
1808
2356
|
});
|
|
1809
2357
|
}
|
|
1810
|
-
|
|
1811
|
-
return
|
|
1812
|
-
request,
|
|
1813
|
-
user: this.user,
|
|
1814
|
-
starkSigner: this.starkSigner,
|
|
1815
|
-
tradesApi: this.tradesApi,
|
|
1816
|
-
passportConfig: this.passportConfig,
|
|
1817
|
-
});
|
|
2358
|
+
getIFrame() {
|
|
2359
|
+
return this.iframe;
|
|
1818
2360
|
}
|
|
1819
|
-
|
|
1820
|
-
|
|
1821
|
-
|
|
1822
|
-
|
|
1823
|
-
|
|
1824
|
-
|
|
1825
|
-
|
|
2361
|
+
}
|
|
2362
|
+
|
|
2363
|
+
const IMX_WALLET_IFRAME_ID = 'imx-wallet-app';
|
|
2364
|
+
const IMX_WALLET_IFRAME_HOSTS = {
|
|
2365
|
+
[Environment.SANDBOX]: 'https://wallets.sandbox.immutable.com',
|
|
2366
|
+
[Environment.PRODUCTION]: 'https://wallets.immutable.com',
|
|
2367
|
+
};
|
|
2368
|
+
const IMX_WALLET_IFRAME_STYLE = 'display: none;';
|
|
2369
|
+
function getIFrame() {
|
|
2370
|
+
return document.querySelector(`iframe#${IMX_WALLET_IFRAME_ID}`);
|
|
2371
|
+
}
|
|
2372
|
+
async function setupIFrame(env) {
|
|
2373
|
+
return new Promise((resolve) => {
|
|
2374
|
+
const iframe = document.createElement('iframe');
|
|
2375
|
+
iframe.setAttribute('id', IMX_WALLET_IFRAME_ID);
|
|
2376
|
+
iframe.setAttribute('src', IMX_WALLET_IFRAME_HOSTS[env]);
|
|
2377
|
+
iframe.setAttribute('style', IMX_WALLET_IFRAME_STYLE);
|
|
2378
|
+
document.body.appendChild(iframe);
|
|
2379
|
+
iframe.onload = () => resolve(iframe);
|
|
2380
|
+
});
|
|
2381
|
+
}
|
|
2382
|
+
async function getOrSetupIFrame(env) {
|
|
2383
|
+
const iframe = getIFrame();
|
|
2384
|
+
if (iframe)
|
|
2385
|
+
return iframe;
|
|
2386
|
+
return await setupIFrame(env);
|
|
2387
|
+
}
|
|
2388
|
+
|
|
2389
|
+
const DEFAULT_CONNECTION_MESSAGE = 'Only sign this request if you’ve initiated an action with Immutable X.';
|
|
2390
|
+
const CONNECTION_FAILED_ERROR = 'The L2 IMX Wallet connection has failed';
|
|
2391
|
+
async function connect(l1Provider, env) {
|
|
2392
|
+
const l1Signer = l1Provider.getSigner();
|
|
2393
|
+
const address = await l1Signer.getAddress();
|
|
2394
|
+
const signature = await l1Signer.signMessage(DEFAULT_CONNECTION_MESSAGE);
|
|
2395
|
+
const iframe = await getOrSetupIFrame(env);
|
|
2396
|
+
return new Promise((resolve, reject) => {
|
|
2397
|
+
const listener = (event) => {
|
|
2398
|
+
messageResponseListener(iframe, event, ResponseEventType.CONNECT_WALLET_RESPONSE, (messageDetails) => {
|
|
2399
|
+
window.removeEventListener(COMMUNICATION_TYPE, listener);
|
|
2400
|
+
if (!messageDetails.success) {
|
|
2401
|
+
reject(new Error(CONNECTION_FAILED_ERROR));
|
|
2402
|
+
}
|
|
2403
|
+
resolve(new ImxSigner(messageDetails.data.starkPublicKey, iframe));
|
|
2404
|
+
});
|
|
2405
|
+
};
|
|
2406
|
+
window.addEventListener(COMMUNICATION_TYPE, listener);
|
|
2407
|
+
postRequestMessage(iframe, {
|
|
2408
|
+
type: RequestEventType.CONNECT_WALLET_REQUEST,
|
|
2409
|
+
details: { ethAddress: address, signature },
|
|
1826
2410
|
});
|
|
1827
|
-
}
|
|
1828
|
-
|
|
1829
|
-
|
|
1830
|
-
|
|
1831
|
-
|
|
1832
|
-
|
|
1833
|
-
|
|
2411
|
+
});
|
|
2412
|
+
}
|
|
2413
|
+
async function disconnect(imxSigner) {
|
|
2414
|
+
const iframe = imxSigner.getIFrame();
|
|
2415
|
+
return new Promise((resolve, reject) => {
|
|
2416
|
+
const listener = (event) => {
|
|
2417
|
+
messageResponseListener(iframe, event, ResponseEventType.DISCONNECT_WALLET_RESPONSE, (messageDetails) => {
|
|
2418
|
+
window.removeEventListener(COMMUNICATION_TYPE, listener);
|
|
2419
|
+
if (!messageDetails.success && messageDetails.error) {
|
|
2420
|
+
reject(messageDetails.error);
|
|
2421
|
+
}
|
|
2422
|
+
iframe.remove();
|
|
2423
|
+
resolve();
|
|
2424
|
+
});
|
|
2425
|
+
};
|
|
2426
|
+
window.addEventListener(COMMUNICATION_TYPE, listener);
|
|
2427
|
+
postRequestMessage(iframe, {
|
|
2428
|
+
type: RequestEventType.DISCONNECT_WALLET_REQUEST,
|
|
2429
|
+
details: { starkPublicKey: imxSigner.getAddress() },
|
|
1834
2430
|
});
|
|
2431
|
+
});
|
|
2432
|
+
}
|
|
2433
|
+
|
|
2434
|
+
var ProviderErrorType;
|
|
2435
|
+
(function (ProviderErrorType) {
|
|
2436
|
+
ProviderErrorType["PROVIDER_CONNECTION_ERROR"] = "PROVIDER_CONNECTION_ERROR";
|
|
2437
|
+
ProviderErrorType["WALLET_CONNECTION_ERROR"] = "WALLET_CONNECTION_ERROR";
|
|
2438
|
+
})(ProviderErrorType || (ProviderErrorType = {}));
|
|
2439
|
+
class ProviderError extends Error {
|
|
2440
|
+
type;
|
|
2441
|
+
constructor(message, type) {
|
|
2442
|
+
super(message);
|
|
2443
|
+
this.type = type;
|
|
1835
2444
|
}
|
|
1836
|
-
|
|
1837
|
-
|
|
1838
|
-
|
|
2445
|
+
}
|
|
2446
|
+
const withProviderError = async (fn, customError) => {
|
|
2447
|
+
try {
|
|
2448
|
+
return await fn();
|
|
1839
2449
|
}
|
|
1840
|
-
|
|
1841
|
-
|
|
1842
|
-
throw new
|
|
2450
|
+
catch (error) {
|
|
2451
|
+
const errorMessage = customError.message || `${error.message}` || 'UnknownError';
|
|
2452
|
+
throw new ProviderError(errorMessage, customError.type);
|
|
1843
2453
|
}
|
|
1844
|
-
|
|
1845
|
-
|
|
1846
|
-
|
|
1847
|
-
|
|
1848
|
-
|
|
1849
|
-
|
|
2454
|
+
};
|
|
2455
|
+
|
|
2456
|
+
class MetaMaskIMXProvider extends GenericIMXProvider {
|
|
2457
|
+
static imxSigner;
|
|
2458
|
+
constructor(config, ethSigner, starkSigner) {
|
|
2459
|
+
super(config, ethSigner, starkSigner);
|
|
1850
2460
|
}
|
|
1851
|
-
|
|
1852
|
-
return
|
|
2461
|
+
static async connect(config) {
|
|
2462
|
+
return await withProviderError(async () => {
|
|
2463
|
+
const metaMaskProvider = await connect$1({
|
|
2464
|
+
chainID: config.immutableXConfig.ethConfiguration.chainID,
|
|
2465
|
+
});
|
|
2466
|
+
this.imxSigner = await connect(metaMaskProvider, config.baseConfig.environment);
|
|
2467
|
+
return new MetaMaskIMXProvider(config, metaMaskProvider.getSigner(), this.imxSigner);
|
|
2468
|
+
}, { type: ProviderErrorType.WALLET_CONNECTION_ERROR });
|
|
1853
2469
|
}
|
|
1854
|
-
|
|
1855
|
-
|
|
1856
|
-
|
|
1857
|
-
|
|
1858
|
-
|
|
1859
|
-
|
|
1860
|
-
}
|
|
1861
|
-
|
|
1862
|
-
const validateConfiguration = (configuration, requiredKeys, prefix) => {
|
|
1863
|
-
const missingKeys = requiredKeys
|
|
1864
|
-
.map((key) => !configuration[key] && key)
|
|
1865
|
-
.filter((n) => n)
|
|
1866
|
-
.join(', ');
|
|
1867
|
-
if (missingKeys !== '') {
|
|
1868
|
-
const errorMessage = prefix
|
|
1869
|
-
? `${prefix} - ${missingKeys} cannot be null`
|
|
1870
|
-
: `${missingKeys} cannot be null`;
|
|
1871
|
-
throw new PassportError(errorMessage, PassportErrorType.INVALID_CONFIGURATION);
|
|
2470
|
+
static async disconnect() {
|
|
2471
|
+
if (!this.imxSigner) {
|
|
2472
|
+
throw new ProviderError('Attempted to disconnect from the MetaMask IMX provider without an established connection', ProviderErrorType.PROVIDER_CONNECTION_ERROR);
|
|
2473
|
+
}
|
|
2474
|
+
return withProviderError(async () => {
|
|
2475
|
+
await disconnect(this.imxSigner);
|
|
2476
|
+
}, { type: ProviderErrorType.PROVIDER_CONNECTION_ERROR });
|
|
1872
2477
|
}
|
|
1873
|
-
|
|
1874
|
-
|
|
1875
|
-
|
|
1876
|
-
|
|
1877
|
-
|
|
1878
|
-
|
|
1879
|
-
|
|
1880
|
-
|
|
1881
|
-
|
|
1882
|
-
|
|
1883
|
-
|
|
1884
|
-
|
|
1885
|
-
|
|
1886
|
-
|
|
1887
|
-
|
|
1888
|
-
|
|
1889
|
-
|
|
1890
|
-
this.baseConfig = baseConfig;
|
|
1891
|
-
if (overrides) {
|
|
1892
|
-
validateConfiguration(overrides, [
|
|
1893
|
-
'network',
|
|
1894
|
-
'authenticationDomain',
|
|
1895
|
-
'magicPublishableApiKey',
|
|
1896
|
-
'magicProviderId',
|
|
1897
|
-
'passportDomain',
|
|
1898
|
-
'imxApiBasePath',
|
|
1899
|
-
], 'overrides');
|
|
1900
|
-
this.network = overrides.network;
|
|
1901
|
-
this.authenticationDomain = overrides.authenticationDomain;
|
|
1902
|
-
this.passportDomain = overrides.passportDomain;
|
|
1903
|
-
this.magicPublishableApiKey = overrides.magicPublishableApiKey;
|
|
1904
|
-
this.magicProviderId = overrides.magicProviderId;
|
|
1905
|
-
this.imxApiBasePath = overrides.imxApiBasePath;
|
|
2478
|
+
static async signMessage(message) {
|
|
2479
|
+
if (!this.imxSigner) {
|
|
2480
|
+
throw new ProviderError('Attempted to sign a message with the MetaMask IMX provider without an established connection', ProviderErrorType.PROVIDER_CONNECTION_ERROR);
|
|
2481
|
+
}
|
|
2482
|
+
return withProviderError(async () => {
|
|
2483
|
+
return await this.imxSigner.signMessage(message);
|
|
2484
|
+
}, { type: ProviderErrorType.PROVIDER_CONNECTION_ERROR });
|
|
2485
|
+
}
|
|
2486
|
+
}
|
|
2487
|
+
|
|
2488
|
+
class ProviderConfiguration {
|
|
2489
|
+
immutableXConfig;
|
|
2490
|
+
baseConfig;
|
|
2491
|
+
constructor({ baseConfig, overrides }) {
|
|
2492
|
+
this.baseConfig = baseConfig;
|
|
2493
|
+
if (overrides) {
|
|
2494
|
+
this.immutableXConfig = overrides.immutableXConfig;
|
|
1906
2495
|
}
|
|
1907
2496
|
else {
|
|
1908
2497
|
switch (baseConfig.environment) {
|
|
1909
2498
|
case Environment.SANDBOX: {
|
|
1910
|
-
this.
|
|
1911
|
-
this.authenticationDomain = 'https://auth.immutable.com';
|
|
1912
|
-
this.magicPublishableApiKey = 'pk_live_10F423798A540ED7';
|
|
1913
|
-
this.magicProviderId = 'fSMzaRQ4O7p4fttl7pCyGVtJS_G70P8SNsLXtPPGHo0=';
|
|
1914
|
-
this.passportDomain = 'https://passport.sandbox.immutable.com';
|
|
1915
|
-
this.imxApiBasePath = 'https://api.sandbox.x.immutable.com';
|
|
2499
|
+
this.immutableXConfig = Config.SANDBOX;
|
|
1916
2500
|
break;
|
|
1917
2501
|
}
|
|
1918
2502
|
case Environment.PRODUCTION: {
|
|
1919
|
-
this.
|
|
1920
|
-
this.authenticationDomain = 'https://auth.immutable.com';
|
|
1921
|
-
this.magicPublishableApiKey = 'pk_live_10F423798A540ED7';
|
|
1922
|
-
this.magicProviderId = 'fSMzaRQ4O7p4fttl7pCyGVtJS_G70P8SNsLXtPPGHo0=';
|
|
1923
|
-
this.passportDomain = 'https://passport.immutable.com';
|
|
1924
|
-
this.imxApiBasePath = 'https://api.x.immutable.com';
|
|
2503
|
+
this.immutableXConfig = Config.PRODUCTION;
|
|
1925
2504
|
break;
|
|
1926
2505
|
}
|
|
1927
2506
|
}
|
|
@@ -1929,108 +2508,6 @@ class PassportConfiguration {
|
|
|
1929
2508
|
}
|
|
1930
2509
|
}
|
|
1931
2510
|
|
|
1932
|
-
const getStarkSigner = async (signer) => {
|
|
1933
|
-
return withPassportError(async () => {
|
|
1934
|
-
const privateKey = await generateLegacyStarkPrivateKey(signer);
|
|
1935
|
-
return createStarkSigner(privateKey);
|
|
1936
|
-
}, PassportErrorType.WALLET_CONNECTION_ERROR);
|
|
1937
|
-
};
|
|
1938
|
-
|
|
1939
|
-
async function registerPassport({ ethSigner, starkSigner, usersApi }, authorization) {
|
|
1940
|
-
return withPassportError(async () => {
|
|
1941
|
-
const userAddress = await ethSigner.getAddress();
|
|
1942
|
-
const starkPublicKey = await starkSigner.getAddress();
|
|
1943
|
-
const signableResult = await usersApi.getSignableRegistrationOffchain({
|
|
1944
|
-
getSignableRegistrationRequest: {
|
|
1945
|
-
ether_key: userAddress,
|
|
1946
|
-
stark_key: starkPublicKey,
|
|
1947
|
-
},
|
|
1948
|
-
});
|
|
1949
|
-
const { signable_message: signableMessage, payload_hash: payloadHash } = signableResult.data;
|
|
1950
|
-
const ethSignature = await signRaw(signableMessage, ethSigner);
|
|
1951
|
-
const starkSignature = await starkSigner.signMessage(payloadHash);
|
|
1952
|
-
const response = await usersApi.registerPassportUser({
|
|
1953
|
-
authorization: `Bearer ` + authorization,
|
|
1954
|
-
registerPassportUserRequest: {
|
|
1955
|
-
eth_signature: ethSignature,
|
|
1956
|
-
ether_key: userAddress,
|
|
1957
|
-
stark_signature: starkSignature,
|
|
1958
|
-
stark_key: starkPublicKey,
|
|
1959
|
-
},
|
|
1960
|
-
});
|
|
1961
|
-
return response.statusText;
|
|
1962
|
-
}, PassportErrorType.USER_REGISTRATION_ERROR);
|
|
1963
|
-
}
|
|
1964
|
-
|
|
1965
|
-
class Passport {
|
|
1966
|
-
authManager;
|
|
1967
|
-
magicAdapter;
|
|
1968
|
-
config;
|
|
1969
|
-
constructor(passportModuleConfiguration) {
|
|
1970
|
-
const passportConfiguration = new PassportConfiguration(passportModuleConfiguration);
|
|
1971
|
-
this.config = passportConfiguration;
|
|
1972
|
-
this.authManager = new AuthManager(this.config);
|
|
1973
|
-
this.magicAdapter = new MagicAdapter(this.config);
|
|
1974
|
-
}
|
|
1975
|
-
async connectImx() {
|
|
1976
|
-
const user = await this.authManager.login();
|
|
1977
|
-
if (!user.idToken) {
|
|
1978
|
-
throw new PassportError('Failed to initialise', PassportErrorType.WALLET_CONNECTION_ERROR);
|
|
1979
|
-
}
|
|
1980
|
-
const provider = await this.magicAdapter.login(user.idToken);
|
|
1981
|
-
const ethSigner = provider.getSigner();
|
|
1982
|
-
const starkSigner = await getStarkSigner(ethSigner);
|
|
1983
|
-
if (!user.etherKey) {
|
|
1984
|
-
const updatedUser = await this.registerUser(ethSigner, starkSigner, user.accessToken);
|
|
1985
|
-
return new PassportImxProvider({
|
|
1986
|
-
user: updatedUser,
|
|
1987
|
-
starkSigner,
|
|
1988
|
-
passportConfig: this.config,
|
|
1989
|
-
});
|
|
1990
|
-
}
|
|
1991
|
-
const userWithEtherKey = user;
|
|
1992
|
-
return new PassportImxProvider({
|
|
1993
|
-
user: userWithEtherKey,
|
|
1994
|
-
starkSigner,
|
|
1995
|
-
passportConfig: this.config,
|
|
1996
|
-
});
|
|
1997
|
-
}
|
|
1998
|
-
async loginCallback() {
|
|
1999
|
-
return this.authManager.loginCallback();
|
|
2000
|
-
}
|
|
2001
|
-
async logout() {
|
|
2002
|
-
return this.authManager.logout();
|
|
2003
|
-
}
|
|
2004
|
-
async getUserInfo() {
|
|
2005
|
-
const user = await this.authManager.getUser();
|
|
2006
|
-
return user.profile;
|
|
2007
|
-
}
|
|
2008
|
-
async getIdToken() {
|
|
2009
|
-
const user = await this.authManager.getUser();
|
|
2010
|
-
return user.idToken;
|
|
2011
|
-
}
|
|
2012
|
-
async getAccessToken() {
|
|
2013
|
-
const user = await this.authManager.getUser();
|
|
2014
|
-
return user.accessToken;
|
|
2015
|
-
}
|
|
2016
|
-
async registerUser(userAdminKeySigner, starkSigner, jwt) {
|
|
2017
|
-
const configuration = new Configuration({
|
|
2018
|
-
basePath: this.config.imxApiBasePath,
|
|
2019
|
-
});
|
|
2020
|
-
const usersApi = new UsersApi(configuration);
|
|
2021
|
-
await registerPassport({
|
|
2022
|
-
ethSigner: userAdminKeySigner,
|
|
2023
|
-
starkSigner,
|
|
2024
|
-
usersApi,
|
|
2025
|
-
}, jwt);
|
|
2026
|
-
const updatedUser = await this.authManager.requestRefreshTokenAfterRegistration();
|
|
2027
|
-
if (!updatedUser) {
|
|
2028
|
-
throw new PassportError('Failed to get refresh token', PassportErrorType.REFRESH_TOKEN_ERROR);
|
|
2029
|
-
}
|
|
2030
|
-
return updatedUser;
|
|
2031
|
-
}
|
|
2032
|
-
}
|
|
2033
|
-
|
|
2034
2511
|
function $parcel$interopDefault(a) {
|
|
2035
2512
|
return a && a.__esModule ? a.default : a;
|
|
2036
2513
|
}
|
|
@@ -2187,7 +2664,9 @@ let $4f91c5f280efe242$export$a75605c67ea83a5a;
|
|
|
2187
2664
|
|
|
2188
2665
|
|
|
2189
2666
|
|
|
2190
|
-
|
|
2667
|
+
/**
|
|
2668
|
+
* The different types of errors that can be returned by the checkout process.
|
|
2669
|
+
*/ let $a8bc256d81a5e2c1$export$e3dc0620abde7f5a;
|
|
2191
2670
|
(function(CheckoutErrorType) {
|
|
2192
2671
|
CheckoutErrorType["PROVIDER_PREFERENCE_ERROR"] = "PROVIDER_PREFERENCE_ERROR";
|
|
2193
2672
|
CheckoutErrorType["CONNECT_PROVIDER_ERROR"] = "CONNECT_PROVIDER_ERROR";
|
|
@@ -2213,12 +2692,6 @@ let $a8bc256d81a5e2c1$export$a22d4e0719ee6def;
|
|
|
2213
2692
|
(function(CheckoutInternalErrorType) {
|
|
2214
2693
|
CheckoutInternalErrorType["REJECTED_SWITCH_AFTER_ADDING_NETWORK"] = "REJECTED_SWITCH_AFTER_ADDING_NETWORK";
|
|
2215
2694
|
})($a8bc256d81a5e2c1$export$a22d4e0719ee6def || ($a8bc256d81a5e2c1$export$a22d4e0719ee6def = {}));
|
|
2216
|
-
class $a8bc256d81a5e2c1$export$620a0d5f1b58ea1d extends Error {
|
|
2217
|
-
constructor(type){
|
|
2218
|
-
super("Checkout internal error");
|
|
2219
|
-
this.type = type;
|
|
2220
|
-
}
|
|
2221
|
-
}
|
|
2222
2695
|
const $a8bc256d81a5e2c1$export$bacc563de539c6c3 = async (fn, customError)=>{
|
|
2223
2696
|
try {
|
|
2224
2697
|
return await fn();
|
|
@@ -2241,6 +2714,70 @@ const $a8bc256d81a5e2c1$export$bacc563de539c6c3 = async (fn, customError)=>{
|
|
|
2241
2714
|
|
|
2242
2715
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
2243
2716
|
|
|
2717
|
+
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
2718
|
+
|
|
2719
|
+
|
|
2720
|
+
|
|
2721
|
+
async function $c99672cf2294e839$export$2d040992269b4717(providerPreference) {
|
|
2722
|
+
const provider = await $c99672cf2294e839$var$getWalletProviderForPreference(providerPreference);
|
|
2723
|
+
if (!provider.provider?.request) throw new ($a8bc256d81a5e2c1$export$b722478a3cbfa3bc)("Incompatible provider", ($a8bc256d81a5e2c1$export$e3dc0620abde7f5a).PROVIDER_REQUEST_MISSING_ERROR, {
|
|
2724
|
+
details: `Unsupported provider for ${providerPreference}`
|
|
2725
|
+
});
|
|
2726
|
+
let accounts = [];
|
|
2727
|
+
try {
|
|
2728
|
+
accounts = await provider.provider.request({
|
|
2729
|
+
method: (0, $4f91c5f280efe242$export$a130407f3423b97d).CHECK_CONNECTION,
|
|
2730
|
+
params: []
|
|
2731
|
+
});
|
|
2732
|
+
} catch (err) {
|
|
2733
|
+
throw new ($a8bc256d81a5e2c1$export$b722478a3cbfa3bc)(`Check wallet connection request failed`, ($a8bc256d81a5e2c1$export$e3dc0620abde7f5a).PROVIDER_REQUEST_FAILED_ERROR, {
|
|
2734
|
+
rpcMethod: ($4f91c5f280efe242$export$a130407f3423b97d).CHECK_CONNECTION
|
|
2735
|
+
});
|
|
2736
|
+
}
|
|
2737
|
+
// accounts[0] will have the active account if connected.
|
|
2738
|
+
return {
|
|
2739
|
+
isConnected: accounts && accounts.length > 0,
|
|
2740
|
+
walletAddress: accounts[0] ?? ""
|
|
2741
|
+
};
|
|
2742
|
+
}
|
|
2743
|
+
async function $c99672cf2294e839$export$fba2f6c3656e07c1(params) {
|
|
2744
|
+
const web3Provider = await $c99672cf2294e839$var$getWalletProviderForPreference(params.providerPreference);
|
|
2745
|
+
await ($a8bc256d81a5e2c1$export$bacc563de539c6c3)(async ()=>{
|
|
2746
|
+
if (!web3Provider || !web3Provider?.provider?.request) throw new ($a8bc256d81a5e2c1$export$b722478a3cbfa3bc)("Incompatible provider", ($a8bc256d81a5e2c1$export$e3dc0620abde7f5a).PROVIDER_REQUEST_MISSING_ERROR, {
|
|
2747
|
+
details: `Unsupported provider for ${params.providerPreference}`
|
|
2748
|
+
});
|
|
2749
|
+
// this makes the request to the wallet to connect i.e request eth accounts ('eth_requestAccounts')
|
|
2750
|
+
await web3Provider.provider.request({
|
|
2751
|
+
method: ($4f91c5f280efe242$export$a130407f3423b97d).CONNECT,
|
|
2752
|
+
params: []
|
|
2753
|
+
});
|
|
2754
|
+
}, {
|
|
2755
|
+
type: ($a8bc256d81a5e2c1$export$e3dc0620abde7f5a).USER_REJECTED_REQUEST_ERROR
|
|
2756
|
+
});
|
|
2757
|
+
return web3Provider;
|
|
2758
|
+
}
|
|
2759
|
+
async function $c99672cf2294e839$var$getWalletProviderForPreference(providerPreference) {
|
|
2760
|
+
let web3Provider = null;
|
|
2761
|
+
switch(providerPreference){
|
|
2762
|
+
case ($d176a05e966364ba$export$3bfad4d03ada24c4).METAMASK:
|
|
2763
|
+
web3Provider = await $c99672cf2294e839$var$getMetaMaskProvider();
|
|
2764
|
+
break;
|
|
2765
|
+
default:
|
|
2766
|
+
throw new ($a8bc256d81a5e2c1$export$b722478a3cbfa3bc)("Provider preference is not supported", ($a8bc256d81a5e2c1$export$e3dc0620abde7f5a).PROVIDER_PREFERENCE_ERROR);
|
|
2767
|
+
}
|
|
2768
|
+
return web3Provider;
|
|
2769
|
+
}
|
|
2770
|
+
async function $c99672cf2294e839$var$getMetaMaskProvider() {
|
|
2771
|
+
const provider = await ($a8bc256d81a5e2c1$export$bacc563de539c6c3)(async ()=>{
|
|
2772
|
+
return await (detectEthereumProvider)();
|
|
2773
|
+
}, {
|
|
2774
|
+
type: ($a8bc256d81a5e2c1$export$e3dc0620abde7f5a).METAMASK_PROVIDER_ERROR
|
|
2775
|
+
});
|
|
2776
|
+
if (!provider || !provider.request) throw new ($a8bc256d81a5e2c1$export$b722478a3cbfa3bc)("No MetaMask provider installed.", ($a8bc256d81a5e2c1$export$e3dc0620abde7f5a).METAMASK_PROVIDER_ERROR);
|
|
2777
|
+
return new (Web3Provider)(provider);
|
|
2778
|
+
}
|
|
2779
|
+
|
|
2780
|
+
|
|
2244
2781
|
var $497c134ecbc8a50f$exports = {};
|
|
2245
2782
|
$497c134ecbc8a50f$exports = JSON.parse('[{"chainId":1},{"chainId":5},{"chainId":137}]');
|
|
2246
2783
|
|
|
@@ -2266,25 +2803,28 @@ async function $de192de6ef100f9f$export$79f13b4cfaaf0d09(provider) {
|
|
|
2266
2803
|
type: ($a8bc256d81a5e2c1$export$e3dc0620abde7f5a).GET_NETWORK_INFO_ERROR
|
|
2267
2804
|
});
|
|
2268
2805
|
}
|
|
2269
|
-
async function $de192de6ef100f9f$export$b827d9418aeb5dbd(provider, chainId) {
|
|
2806
|
+
async function $de192de6ef100f9f$export$b827d9418aeb5dbd(providerPreference, provider, chainId) {
|
|
2807
|
+
let currentProvider = provider;
|
|
2270
2808
|
if (!Object.values(($a47e48dd2c04791b$export$c06e1e7429de6283)).includes(chainId)) throw new ($a8bc256d81a5e2c1$export$b722478a3cbfa3bc)(`Chain:${chainId} is not a supported chain`, ($a8bc256d81a5e2c1$export$e3dc0620abde7f5a).CHAIN_NOT_SUPPORTED_ERROR);
|
|
2271
|
-
if (!
|
|
2809
|
+
if (!currentProvider || !currentProvider.provider?.request) throw new ($a8bc256d81a5e2c1$export$b722478a3cbfa3bc)("Incompatible provider", ($a8bc256d81a5e2c1$export$e3dc0620abde7f5a).PROVIDER_REQUEST_MISSING_ERROR, {
|
|
2272
2810
|
details: `Unsupported provider`
|
|
2273
2811
|
});
|
|
2274
2812
|
// WT-1146 - Refer to the README in this folder for explantion on the switch network flow
|
|
2275
2813
|
try {
|
|
2276
|
-
await $de192de6ef100f9f$var$switchNetworkInWallet(
|
|
2814
|
+
await $de192de6ef100f9f$var$switchNetworkInWallet(currentProvider, chainId);
|
|
2277
2815
|
} catch (err) {
|
|
2278
2816
|
if (err.code === $de192de6ef100f9f$var$UNRECOGNISED_CHAIN_ERROR_CODE) try {
|
|
2279
|
-
await $de192de6ef100f9f$var$addNetworkToWallet(
|
|
2280
|
-
if ((await provider.getNetwork()).chainId !== chainId) // user didn't actually switch
|
|
2281
|
-
throw new (0, $a8bc256d81a5e2c1$export$620a0d5f1b58ea1d)((0, $a8bc256d81a5e2c1$export$a22d4e0719ee6def).REJECTED_SWITCH_AFTER_ADDING_NETWORK);
|
|
2817
|
+
await $de192de6ef100f9f$var$addNetworkToWallet(currentProvider, chainId);
|
|
2282
2818
|
} catch (err) {
|
|
2283
|
-
if (err?.type === ($a8bc256d81a5e2c1$export$a22d4e0719ee6def).REJECTED_SWITCH_AFTER_ADDING_NETWORK) throw new ($a8bc256d81a5e2c1$export$b722478a3cbfa3bc)("User cancelled switch network request", ($a8bc256d81a5e2c1$export$e3dc0620abde7f5a).USER_REJECTED_REQUEST_ERROR);
|
|
2284
2819
|
throw new ($a8bc256d81a5e2c1$export$b722478a3cbfa3bc)("User cancelled add network request", ($a8bc256d81a5e2c1$export$e3dc0620abde7f5a).USER_REJECTED_REQUEST_ERROR);
|
|
2285
2820
|
}
|
|
2286
2821
|
else throw new ($a8bc256d81a5e2c1$export$b722478a3cbfa3bc)("User cancelled switch network request", ($a8bc256d81a5e2c1$export$e3dc0620abde7f5a).USER_REJECTED_REQUEST_ERROR);
|
|
2287
2822
|
}
|
|
2823
|
+
currentProvider = await ($c99672cf2294e839$export$fba2f6c3656e07c1)({
|
|
2824
|
+
providerPreference: providerPreference
|
|
2825
|
+
});
|
|
2826
|
+
if ((await currentProvider.getNetwork()).chainId !== chainId) // user didn't actually switch
|
|
2827
|
+
throw new ($a8bc256d81a5e2c1$export$b722478a3cbfa3bc)("User cancelled switch network request", ($a8bc256d81a5e2c1$export$e3dc0620abde7f5a).USER_REJECTED_REQUEST_ERROR);
|
|
2288
2828
|
// we can assume that if the above succeeds then user has successfully
|
|
2289
2829
|
// switched to the network specified
|
|
2290
2830
|
const newNetwork = ($a47e48dd2c04791b$export$f61f4aaec62f6be9)[chainId];
|
|
@@ -2293,7 +2833,8 @@ async function $de192de6ef100f9f$export$b827d9418aeb5dbd(provider, chainId) {
|
|
|
2293
2833
|
name: newNetwork.chainName,
|
|
2294
2834
|
chainId: parseInt(newNetwork.chainIdHex, 16),
|
|
2295
2835
|
nativeCurrency: newNetwork.nativeCurrency
|
|
2296
|
-
}
|
|
2836
|
+
},
|
|
2837
|
+
provider: currentProvider
|
|
2297
2838
|
};
|
|
2298
2839
|
}
|
|
2299
2840
|
async function $de192de6ef100f9f$export$3043f6442a9ef563({ type: type = ($a47e48dd2c04791b$export$1f05a55fe0680cc7).ALL , exclude: exclude }) {
|
|
@@ -2433,75 +2974,12 @@ const $1564e43dde50bb61$export$fee49741664a4d7e = async (provider, walletAddress
|
|
|
2433
2974
|
|
|
2434
2975
|
|
|
2435
2976
|
|
|
2436
|
-
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
2437
|
-
|
|
2438
|
-
|
|
2439
|
-
|
|
2440
|
-
async function $c99672cf2294e839$export$2d040992269b4717(providerPreference) {
|
|
2441
|
-
const provider = await $c99672cf2294e839$var$getWalletProviderForPreference(providerPreference);
|
|
2442
|
-
if (!provider.provider?.request) throw new ($a8bc256d81a5e2c1$export$b722478a3cbfa3bc)("Incompatible provider", ($a8bc256d81a5e2c1$export$e3dc0620abde7f5a).PROVIDER_REQUEST_MISSING_ERROR, {
|
|
2443
|
-
details: `Unsupported provider for ${providerPreference}`
|
|
2444
|
-
});
|
|
2445
|
-
let accounts = [];
|
|
2446
|
-
try {
|
|
2447
|
-
accounts = await provider.provider.request({
|
|
2448
|
-
method: (0, $4f91c5f280efe242$export$a130407f3423b97d).CHECK_CONNECTION,
|
|
2449
|
-
params: []
|
|
2450
|
-
});
|
|
2451
|
-
} catch (err) {
|
|
2452
|
-
throw new ($a8bc256d81a5e2c1$export$b722478a3cbfa3bc)(`Check wallet connection request failed`, ($a8bc256d81a5e2c1$export$e3dc0620abde7f5a).PROVIDER_REQUEST_FAILED_ERROR, {
|
|
2453
|
-
rpcMethod: ($4f91c5f280efe242$export$a130407f3423b97d).CHECK_CONNECTION
|
|
2454
|
-
});
|
|
2455
|
-
}
|
|
2456
|
-
// accounts[0] will have the active account if connected.
|
|
2457
|
-
return {
|
|
2458
|
-
isConnected: accounts && accounts.length > 0,
|
|
2459
|
-
walletAddress: accounts[0] ?? ""
|
|
2460
|
-
};
|
|
2461
|
-
}
|
|
2462
|
-
async function $c99672cf2294e839$export$fba2f6c3656e07c1(params) {
|
|
2463
|
-
const web3Provider = await $c99672cf2294e839$var$getWalletProviderForPreference(params.providerPreference);
|
|
2464
|
-
await ($a8bc256d81a5e2c1$export$bacc563de539c6c3)(async ()=>{
|
|
2465
|
-
if (!web3Provider || !web3Provider?.provider?.request) throw new ($a8bc256d81a5e2c1$export$b722478a3cbfa3bc)("Incompatible provider", ($a8bc256d81a5e2c1$export$e3dc0620abde7f5a).PROVIDER_REQUEST_MISSING_ERROR, {
|
|
2466
|
-
details: `Unsupported provider for ${params.providerPreference}`
|
|
2467
|
-
});
|
|
2468
|
-
// this makes the request to the wallet to connect i.e request eth accounts ('eth_requestAccounts')
|
|
2469
|
-
await web3Provider.provider.request({
|
|
2470
|
-
method: ($4f91c5f280efe242$export$a130407f3423b97d).CONNECT,
|
|
2471
|
-
params: []
|
|
2472
|
-
});
|
|
2473
|
-
}, {
|
|
2474
|
-
type: ($a8bc256d81a5e2c1$export$e3dc0620abde7f5a).USER_REJECTED_REQUEST_ERROR
|
|
2475
|
-
});
|
|
2476
|
-
return web3Provider;
|
|
2477
|
-
}
|
|
2478
|
-
async function $c99672cf2294e839$var$getWalletProviderForPreference(providerPreference) {
|
|
2479
|
-
let web3Provider = null;
|
|
2480
|
-
switch(providerPreference){
|
|
2481
|
-
case ($d176a05e966364ba$export$3bfad4d03ada24c4).METAMASK:
|
|
2482
|
-
web3Provider = await $c99672cf2294e839$var$getMetaMaskProvider();
|
|
2483
|
-
break;
|
|
2484
|
-
default:
|
|
2485
|
-
throw new ($a8bc256d81a5e2c1$export$b722478a3cbfa3bc)("Provider preference is not supported", ($a8bc256d81a5e2c1$export$e3dc0620abde7f5a).PROVIDER_PREFERENCE_ERROR);
|
|
2486
|
-
}
|
|
2487
|
-
return web3Provider;
|
|
2488
|
-
}
|
|
2489
|
-
async function $c99672cf2294e839$var$getMetaMaskProvider() {
|
|
2490
|
-
const provider = await ($a8bc256d81a5e2c1$export$bacc563de539c6c3)(async ()=>{
|
|
2491
|
-
return await (detectEthereumProvider)();
|
|
2492
|
-
}, {
|
|
2493
|
-
type: ($a8bc256d81a5e2c1$export$e3dc0620abde7f5a).METAMASK_PROVIDER_ERROR
|
|
2494
|
-
});
|
|
2495
|
-
if (!provider || !provider.request) throw new ($a8bc256d81a5e2c1$export$b722478a3cbfa3bc)("No MetaMask provider installed.", ($a8bc256d81a5e2c1$export$e3dc0620abde7f5a).METAMASK_PROVIDER_ERROR);
|
|
2496
|
-
return new (Web3Provider)(provider);
|
|
2497
|
-
}
|
|
2498
|
-
|
|
2499
2977
|
|
|
2500
2978
|
|
|
2501
2979
|
|
|
2502
2980
|
|
|
2503
2981
|
var $6f3c55a615003cbf$exports = {};
|
|
2504
|
-
$6f3c55a615003cbf$exports = JSON.parse('[{"connectionProvider":"metamask","icon":"some-icon-url","name":"MetaMask","description":"complete web3 wallet solution","platform":["
|
|
2982
|
+
$6f3c55a615003cbf$exports = JSON.parse('[{"connectionProvider":"metamask","icon":"some-icon-url","name":"MetaMask","description":"complete web3 wallet solution","platform":["desktop"]},{"connectionProvider":"passport","icon":"pp-icon","name":"Passport","description":"Web3 with your email!","platform":["mobile","desktop"]},{"connectionProvider":"gamestop","icon":"gme-icon","name":"GameStop","description":"Never stopping the game!","platform":["mobile"]}]');
|
|
2505
2983
|
|
|
2506
2984
|
|
|
2507
2985
|
async function $5cdde2ffe6360fec$export$a822caa90d7eef09({ type: type = ($4f91c5f280efe242$export$a75605c67ea83a5a).ALL , exclude: exclude }) {
|
|
@@ -2540,11 +3018,23 @@ const $dbe95599a4661140$export$8e0e7ffc78696d30 = async (params)=>{
|
|
|
2540
3018
|
|
|
2541
3019
|
|
|
2542
3020
|
|
|
3021
|
+
|
|
2543
3022
|
class $a8cb37a3fc8eb863$export$1f60ba4ec72508a0 {
|
|
2544
|
-
|
|
3023
|
+
/**
|
|
3024
|
+
* Check if a wallet is connected to the current application without requesting permission from the wallet and hence triggering a connect popup.
|
|
3025
|
+
* @param {CheckConnectionParams} params - The necessary data required to verify a wallet connection status.
|
|
3026
|
+
* @returns Wallet connection status details.
|
|
3027
|
+
* @throws {@link ErrorType}
|
|
3028
|
+
*/ async checkIsWalletConnected(params) {
|
|
2545
3029
|
return $c99672cf2294e839$export$2d040992269b4717(params.providerPreference);
|
|
2546
3030
|
}
|
|
2547
|
-
|
|
3031
|
+
/**
|
|
3032
|
+
* Establish a connection with a wallet provider such as MetaMask and returns the provider object and the current network details.
|
|
3033
|
+
* @param {ConnectParams} params - The necessary data required to establish a connection with a wallet provider.
|
|
3034
|
+
* @returns Wallet provider and current network information.
|
|
3035
|
+
* @throws {@link ErrorType}
|
|
3036
|
+
*/ async connect(params) {
|
|
3037
|
+
this.providerPreference = params.providerPreference;
|
|
2548
3038
|
const provider = await $c99672cf2294e839$export$fba2f6c3656e07c1(params);
|
|
2549
3039
|
const networkInfo = await $de192de6ef100f9f$export$79f13b4cfaaf0d09(provider);
|
|
2550
3040
|
return {
|
|
@@ -2552,29 +3042,72 @@ class $a8cb37a3fc8eb863$export$1f60ba4ec72508a0 {
|
|
|
2552
3042
|
network: networkInfo
|
|
2553
3043
|
};
|
|
2554
3044
|
}
|
|
2555
|
-
|
|
2556
|
-
|
|
2557
|
-
|
|
2558
|
-
|
|
3045
|
+
/**
|
|
3046
|
+
* Switch the currently connected wallet to a new network.
|
|
3047
|
+
* @param {SwitchNetworkParams} params - The necessary data required to switch network.
|
|
3048
|
+
* @returns The new network information.
|
|
3049
|
+
* @throws {@link ErrorType}
|
|
3050
|
+
*/ async switchNetwork(params) {
|
|
3051
|
+
if (!this.providerPreference) throw new ($a8bc256d81a5e2c1$export$b722478a3cbfa3bc)(`connect should be called before switchNetwork to set the provider preference`, ($a8bc256d81a5e2c1$export$e3dc0620abde7f5a).PROVIDER_PREFERENCE_ERROR);
|
|
3052
|
+
return await $de192de6ef100f9f$export$b827d9418aeb5dbd(this.providerPreference, params.provider, params.chainId);
|
|
3053
|
+
}
|
|
3054
|
+
/**
|
|
3055
|
+
* Fetch the balance of the native token of the current connected network or, if a contract address is provided, it will return the balance of that ERC20 token. For example, if the wallet is connected to the Ethereum Mainnet then the function gets the wallet ETH L1 balance.
|
|
3056
|
+
* @param {GetBalanceParams} params - The necessary data required to fetch the wallet balance.
|
|
3057
|
+
* @returns Native token balance for the given wallet.
|
|
3058
|
+
* @throws {@link ErrorType}
|
|
3059
|
+
*/ async getBalance(params) {
|
|
2559
3060
|
if (!params.contractAddress || params.contractAddress === "") return await $1564e43dde50bb61$export$df96cd8d56be0ab1(params.provider, params.walletAddress);
|
|
2560
3061
|
return await $1564e43dde50bb61$export$60e0fe116a0e6ed0(params.provider, params.walletAddress, params.contractAddress);
|
|
2561
3062
|
}
|
|
2562
|
-
|
|
3063
|
+
/**
|
|
3064
|
+
* Fetch all available balances (ERC20 & Native) of the current connected network of the given wallet. It will loop through the list of allowed tokens and check for balance on each one.
|
|
3065
|
+
* @param {GetAllBalancesParams} params - The necessary data required to fetch all the wallet balances.
|
|
3066
|
+
* @returns List of tokens balance for the given wallet.
|
|
3067
|
+
* @throws {@link ErrorType}
|
|
3068
|
+
*/ async getAllBalances(params) {
|
|
2563
3069
|
return $1564e43dde50bb61$export$fee49741664a4d7e(params.provider, params.walletAddress, params.chainId);
|
|
2564
3070
|
}
|
|
2565
|
-
|
|
3071
|
+
/**
|
|
3072
|
+
* Fetch the list of available networks that a wallet can add or/and switch to.
|
|
3073
|
+
* @param {GetNetworkAllowListParams} params - The necessary data required to fetch the list of available networks.
|
|
3074
|
+
* @returns List of networks.
|
|
3075
|
+
* @throws {@link ErrorType}
|
|
3076
|
+
*/ async getNetworkAllowList(params) {
|
|
2566
3077
|
return await $de192de6ef100f9f$export$3043f6442a9ef563(params);
|
|
2567
3078
|
}
|
|
2568
|
-
|
|
3079
|
+
/**
|
|
3080
|
+
* Get the list of tokens which are allowed to be used with the product.
|
|
3081
|
+
* @param {GetTokenAllowListParams} params - The necessary data required to fetch the list of allowed tokens.
|
|
3082
|
+
* @returns List of allowed tokens.
|
|
3083
|
+
* @throws {@link ErrorType}
|
|
3084
|
+
*/ async getTokenAllowList(params) {
|
|
2569
3085
|
return await $efe60cea83bfc4e8$export$473cec51305fdae8(params);
|
|
2570
3086
|
}
|
|
2571
|
-
|
|
3087
|
+
/**
|
|
3088
|
+
* Fetch the list of wallets which are available to connect with.
|
|
3089
|
+
* @param {GetWalletAllowListParams} params - The necessary data required to fetch the list of allowed wallets.
|
|
3090
|
+
* @returns List of allowed wallets.
|
|
3091
|
+
* @throws {@link ErrorType}
|
|
3092
|
+
*/ async getWalletAllowList(params) {
|
|
2572
3093
|
return await $5cdde2ffe6360fec$export$a822caa90d7eef09(params);
|
|
2573
3094
|
}
|
|
2574
|
-
|
|
3095
|
+
/**
|
|
3096
|
+
* Send a generic transaction to the provider.
|
|
3097
|
+
* @param {SendTransactionParams} params - The necessary data required to send a transaction.
|
|
3098
|
+
* @returns Transaction response.
|
|
3099
|
+
* @throws {@link ErrorType}
|
|
3100
|
+
* @remarks
|
|
3101
|
+
* Further documenation can be found at [MetaMask | Sending Transactions](https://docs.metamask.io/guide/sending-transactions.html).
|
|
3102
|
+
*/ async sendTransaction(params) {
|
|
2575
3103
|
return await $dbe95599a4661140$export$8e0e7ffc78696d30(params);
|
|
2576
3104
|
}
|
|
2577
|
-
|
|
3105
|
+
/**
|
|
3106
|
+
* Get network information about the currently selected network.
|
|
3107
|
+
* @param {GetNetworkParams} params - The necessary data required to get the current network information.
|
|
3108
|
+
* @returns Network details.
|
|
3109
|
+
* @throws {@link ErrorType}
|
|
3110
|
+
*/ async getNetworkInfo(params) {
|
|
2578
3111
|
return await $de192de6ef100f9f$export$79f13b4cfaaf0d09(params.provider);
|
|
2579
3112
|
}
|
|
2580
3113
|
}
|
|
@@ -2669,4 +3202,4 @@ let $9234b4c577442a97$export$c88931fdc51854eb;
|
|
|
2669
3202
|
WidgetTheme["CUSTOM"] = "custom";
|
|
2670
3203
|
})($9234b4c577442a97$export$c88931fdc51854eb || ($9234b4c577442a97$export$c88931fdc51854eb = {}));
|
|
2671
3204
|
|
|
2672
|
-
export { $28a5fdc2f5e6c742$export$d1bfa21f7c76447a as BridgeEventType, $ede253beebe0de4a$export$90db5fe1be5993c1 as BuyEventType, $a47e48dd2c04791b$export$c06e1e7429de6283 as ChainId, $a8cb37a3fc8eb863$export$1f60ba4ec72508a0 as Checkout, $d71a87afc3136184$export$e72e7f9969a47dd3 as ConnectEventType, $d176a05e966364ba$export$3bfad4d03ada24c4 as ConnectionProviders, Environment, GenericIMXProvider, $88e4c575901cd68c$export$5a0ace85cae72d45 as IMTBLWidgetEvents, ImmutableConfiguration, MetaMaskIMXProvider, $9234b4c577442a97$export$95be4ae94445245a as Network, $a47e48dd2c04791b$export$1f05a55fe0680cc7 as NetworkFilterTypes, Passport, PassportConfiguration, PassportError, ProviderConfiguration,
|
|
3205
|
+
export { $28a5fdc2f5e6c742$export$d1bfa21f7c76447a as BridgeEventType, $ede253beebe0de4a$export$90db5fe1be5993c1 as BuyEventType, $a47e48dd2c04791b$export$c06e1e7429de6283 as ChainId, $a8cb37a3fc8eb863$export$1f60ba4ec72508a0 as Checkout, $a8bc256d81a5e2c1$export$e3dc0620abde7f5a as CheckoutErrorType, $d71a87afc3136184$export$e72e7f9969a47dd3 as ConnectEventType, $d176a05e966364ba$export$3bfad4d03ada24c4 as ConnectionProviders, Environment, GenericIMXProvider, $88e4c575901cd68c$export$5a0ace85cae72d45 as IMTBLWidgetEvents, ImmutableConfiguration, ImmutableXClient, MetaMaskIMXProvider, $9234b4c577442a97$export$95be4ae94445245a as Network, $a47e48dd2c04791b$export$1f05a55fe0680cc7 as NetworkFilterTypes, Passport, PassportConfiguration, PassportError, ProviderConfiguration, $5d497088f13bb116$export$140a49745ab55563 as SwapEventType, $08d5ddc39acd6833$export$fd9b17d87f4121d2 as TokenFilterTypes, $9d0f1783d4d36e8a$export$d9be06b70b28c742 as WalletEventType, $4f91c5f280efe242$export$a75605c67ea83a5a as WalletFilterTypes, $9234b4c577442a97$export$c88931fdc51854eb as WidgetTheme };
|