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