@imtbl/sdk 1.6.0 → 1.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/blockchain_data.js +5 -4
- package/dist/browser/checkout/sdk.js +7 -7
- package/dist/browser/checkout/widgets.js +62 -62
- package/dist/checkout.d.ts +2 -0
- package/dist/checkout.js +18 -9
- package/dist/config.js +4 -3
- package/dist/index.browser.js +13 -13
- package/dist/index.browser.js.map +1 -1
- package/dist/index.cjs +363 -358
- package/dist/index.d.ts +2 -0
- package/dist/index.js +363 -358
- package/dist/orderbook.js +4 -3
- package/dist/passport.d.ts +1 -0
- package/dist/passport.js +386 -389
- package/dist/x.js +5 -4
- package/package.json +1 -1
package/dist/passport.js
CHANGED
|
@@ -8,10 +8,10 @@ import * as crypto from 'crypto';
|
|
|
8
8
|
import { Magic } from 'magic-sdk';
|
|
9
9
|
import { OpenIdExtension } from '@magic-ext/oidc';
|
|
10
10
|
import { JsonRpcProvider, Web3Provider } from '@ethersproject/providers';
|
|
11
|
-
import { BigNumber, ethers } from 'ethers';
|
|
12
11
|
import BN from 'bn.js';
|
|
13
12
|
import * as encUtils from 'enc-utils';
|
|
14
13
|
import { EventEmitter } from 'events';
|
|
14
|
+
import { BigNumber, ethers } from 'ethers';
|
|
15
15
|
import { walletContracts } from '@0xsequence/abi';
|
|
16
16
|
import { v1 } from '@0xsequence/core';
|
|
17
17
|
|
|
@@ -9146,7 +9146,7 @@ class MultiRollupApiClients {
|
|
|
9146
9146
|
}
|
|
9147
9147
|
|
|
9148
9148
|
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
9149
|
-
const defaultHeaders = { 'x-sdk-version': 'ts-immutable-sdk-1.
|
|
9149
|
+
const defaultHeaders = { 'x-sdk-version': 'ts-immutable-sdk-1.7.0' };
|
|
9150
9150
|
const createConfig = ({ basePath, headers, }) => {
|
|
9151
9151
|
if (!basePath.trim()) {
|
|
9152
9152
|
throw Error('basePath can not be empty');
|
|
@@ -9293,7 +9293,7 @@ const storeDetail = (key, value) => {
|
|
|
9293
9293
|
};
|
|
9294
9294
|
setItem(Store.RUNTIME, RUNTIME_DETAILS);
|
|
9295
9295
|
};
|
|
9296
|
-
const getDetail = (key) => {
|
|
9296
|
+
const getDetail$1 = (key) => {
|
|
9297
9297
|
// Handle the scenario where detail is a falsy value
|
|
9298
9298
|
if (RUNTIME_DETAILS[key] === undefined) {
|
|
9299
9299
|
return undefined;
|
|
@@ -9325,7 +9325,7 @@ const flattenProperties = (properties) => {
|
|
|
9325
9325
|
};
|
|
9326
9326
|
|
|
9327
9327
|
// WARNING: DO NOT CHANGE THE STRING BELOW. IT GETS REPLACED AT BUILD TIME.
|
|
9328
|
-
const SDK_VERSION = '1.
|
|
9328
|
+
const SDK_VERSION = '1.7.0';
|
|
9329
9329
|
const getReferrer = () => {
|
|
9330
9330
|
if (isNode()) {
|
|
9331
9331
|
return '';
|
|
@@ -9368,7 +9368,7 @@ const initialise = async () => {
|
|
|
9368
9368
|
initialised = true;
|
|
9369
9369
|
try {
|
|
9370
9370
|
const runtimeDetails = flattenProperties(getRuntimeDetails());
|
|
9371
|
-
const existingRuntimeId = getDetail(Detail.RUNTIME_ID);
|
|
9371
|
+
const existingRuntimeId = getDetail$1(Detail.RUNTIME_ID);
|
|
9372
9372
|
const body = {
|
|
9373
9373
|
version: 1,
|
|
9374
9374
|
data: {
|
|
@@ -9521,6 +9521,7 @@ const setPublishableApiKeyFn = (publishableApiKey) => {
|
|
|
9521
9521
|
storeDetail(Detail.PUBLISHABLE_API_KEY, publishableApiKey);
|
|
9522
9522
|
};
|
|
9523
9523
|
errorBoundary(getGlobalisedValue('setPublishableApiKey', setPublishableApiKeyFn));
|
|
9524
|
+
const getDetail = errorBoundary(getGlobalisedValue('getDetail', getDetail$1));
|
|
9524
9525
|
|
|
9525
9526
|
var Environment;
|
|
9526
9527
|
(function (Environment) {
|
|
@@ -9537,7 +9538,7 @@ const createImmutableXConfiguration = ({ basePath, chainID, coreContractAddress,
|
|
|
9537
9538
|
chainID,
|
|
9538
9539
|
coreContractAddress,
|
|
9539
9540
|
registrationContractAddress,
|
|
9540
|
-
sdkVersion: 'ts-immutable-sdk-1.
|
|
9541
|
+
sdkVersion: 'ts-immutable-sdk-1.7.0',
|
|
9541
9542
|
});
|
|
9542
9543
|
/**
|
|
9543
9544
|
* Sets `sdkVersion` at the time of build
|
|
@@ -10040,6 +10041,69 @@ class IMXClient {
|
|
|
10040
10041
|
}
|
|
10041
10042
|
}
|
|
10042
10043
|
|
|
10044
|
+
// used to sign message with L1 keys. Used for registration
|
|
10045
|
+
function serializeEthSignature(sig) {
|
|
10046
|
+
// This is because golang appends a recovery param
|
|
10047
|
+
// https://github.com/ethers-io/ethers.js/issues/823
|
|
10048
|
+
return encUtils.addHexPrefix(encUtils.padLeft(sig.r.toString(16), 64)
|
|
10049
|
+
+ encUtils.padLeft(sig.s.toString(16), 64)
|
|
10050
|
+
+ encUtils.padLeft(sig.recoveryParam?.toString(16) || '', 2));
|
|
10051
|
+
}
|
|
10052
|
+
function importRecoveryParam(v) {
|
|
10053
|
+
const isValidBigNumber = new BN(v, 16).cmp(new BN(27)) !== -1
|
|
10054
|
+
? new BN(v, 16).sub(new BN(27)).toNumber()
|
|
10055
|
+
: new BN(v, 16).toNumber();
|
|
10056
|
+
return v.trim()
|
|
10057
|
+
? isValidBigNumber
|
|
10058
|
+
: undefined;
|
|
10059
|
+
}
|
|
10060
|
+
// used chained with serializeEthSignature. serializeEthSignature(deserializeSignature(...))
|
|
10061
|
+
function deserializeSignature(sig, size = 64) {
|
|
10062
|
+
const removedHexPrefixSig = encUtils.removeHexPrefix(sig);
|
|
10063
|
+
return {
|
|
10064
|
+
r: new BN(removedHexPrefixSig.substring(0, size), 'hex'),
|
|
10065
|
+
s: new BN(removedHexPrefixSig.substring(size, size * 2), 'hex'),
|
|
10066
|
+
recoveryParam: importRecoveryParam(removedHexPrefixSig.substring(size * 2, size * 2 + 2)),
|
|
10067
|
+
};
|
|
10068
|
+
}
|
|
10069
|
+
async function signRaw(payload, signer) {
|
|
10070
|
+
const signature = deserializeSignature(await signer.signMessage(payload));
|
|
10071
|
+
return serializeEthSignature(signature);
|
|
10072
|
+
}
|
|
10073
|
+
|
|
10074
|
+
/**
|
|
10075
|
+
* Helper method to convert token type to a SignableToken type
|
|
10076
|
+
* @param token - the token type to convert to a SignableToken type
|
|
10077
|
+
* @returns the converted SignableToken
|
|
10078
|
+
*/
|
|
10079
|
+
function convertToSignableToken(token) {
|
|
10080
|
+
switch (token.type) {
|
|
10081
|
+
case 'ERC721':
|
|
10082
|
+
return {
|
|
10083
|
+
type: 'ERC721',
|
|
10084
|
+
data: {
|
|
10085
|
+
token_id: token.tokenId,
|
|
10086
|
+
token_address: token.tokenAddress,
|
|
10087
|
+
},
|
|
10088
|
+
};
|
|
10089
|
+
case 'ERC20':
|
|
10090
|
+
return {
|
|
10091
|
+
type: 'ERC20',
|
|
10092
|
+
data: {
|
|
10093
|
+
token_address: token.tokenAddress,
|
|
10094
|
+
},
|
|
10095
|
+
};
|
|
10096
|
+
case 'ETH':
|
|
10097
|
+
default:
|
|
10098
|
+
return {
|
|
10099
|
+
type: 'ETH',
|
|
10100
|
+
data: {
|
|
10101
|
+
decimals: 18,
|
|
10102
|
+
},
|
|
10103
|
+
};
|
|
10104
|
+
}
|
|
10105
|
+
}
|
|
10106
|
+
|
|
10043
10107
|
function bind(fn, thisArg) {
|
|
10044
10108
|
return function wrap() {
|
|
10045
10109
|
return fn.apply(thisArg, arguments);
|
|
@@ -13955,69 +14019,6 @@ const TransactionApprovalRequestChainTypeEnum = {
|
|
|
13955
14019
|
Evm: 'evm'
|
|
13956
14020
|
};
|
|
13957
14021
|
|
|
13958
|
-
// used to sign message with L1 keys. Used for registration
|
|
13959
|
-
function serializeEthSignature(sig) {
|
|
13960
|
-
// This is because golang appends a recovery param
|
|
13961
|
-
// https://github.com/ethers-io/ethers.js/issues/823
|
|
13962
|
-
return encUtils.addHexPrefix(encUtils.padLeft(sig.r.toString(16), 64)
|
|
13963
|
-
+ encUtils.padLeft(sig.s.toString(16), 64)
|
|
13964
|
-
+ encUtils.padLeft(sig.recoveryParam?.toString(16) || '', 2));
|
|
13965
|
-
}
|
|
13966
|
-
function importRecoveryParam(v) {
|
|
13967
|
-
const isValidBigNumber = new BN(v, 16).cmp(new BN(27)) !== -1
|
|
13968
|
-
? new BN(v, 16).sub(new BN(27)).toNumber()
|
|
13969
|
-
: new BN(v, 16).toNumber();
|
|
13970
|
-
return v.trim()
|
|
13971
|
-
? isValidBigNumber
|
|
13972
|
-
: undefined;
|
|
13973
|
-
}
|
|
13974
|
-
// used chained with serializeEthSignature. serializeEthSignature(deserializeSignature(...))
|
|
13975
|
-
function deserializeSignature(sig, size = 64) {
|
|
13976
|
-
const removedHexPrefixSig = encUtils.removeHexPrefix(sig);
|
|
13977
|
-
return {
|
|
13978
|
-
r: new BN(removedHexPrefixSig.substring(0, size), 'hex'),
|
|
13979
|
-
s: new BN(removedHexPrefixSig.substring(size, size * 2), 'hex'),
|
|
13980
|
-
recoveryParam: importRecoveryParam(removedHexPrefixSig.substring(size * 2, size * 2 + 2)),
|
|
13981
|
-
};
|
|
13982
|
-
}
|
|
13983
|
-
async function signRaw(payload, signer) {
|
|
13984
|
-
const signature = deserializeSignature(await signer.signMessage(payload));
|
|
13985
|
-
return serializeEthSignature(signature);
|
|
13986
|
-
}
|
|
13987
|
-
|
|
13988
|
-
/**
|
|
13989
|
-
* Helper method to convert token type to a SignableToken type
|
|
13990
|
-
* @param token - the token type to convert to a SignableToken type
|
|
13991
|
-
* @returns the converted SignableToken
|
|
13992
|
-
*/
|
|
13993
|
-
function convertToSignableToken(token) {
|
|
13994
|
-
switch (token.type) {
|
|
13995
|
-
case 'ERC721':
|
|
13996
|
-
return {
|
|
13997
|
-
type: 'ERC721',
|
|
13998
|
-
data: {
|
|
13999
|
-
token_id: token.tokenId,
|
|
14000
|
-
token_address: token.tokenAddress,
|
|
14001
|
-
},
|
|
14002
|
-
};
|
|
14003
|
-
case 'ERC20':
|
|
14004
|
-
return {
|
|
14005
|
-
type: 'ERC20',
|
|
14006
|
-
data: {
|
|
14007
|
-
token_address: token.tokenAddress,
|
|
14008
|
-
},
|
|
14009
|
-
};
|
|
14010
|
-
case 'ETH':
|
|
14011
|
-
default:
|
|
14012
|
-
return {
|
|
14013
|
-
type: 'ETH',
|
|
14014
|
-
data: {
|
|
14015
|
-
decimals: 18,
|
|
14016
|
-
},
|
|
14017
|
-
};
|
|
14018
|
-
}
|
|
14019
|
-
}
|
|
14020
|
-
|
|
14021
14022
|
var PassportErrorType;
|
|
14022
14023
|
(function (PassportErrorType) {
|
|
14023
14024
|
PassportErrorType["AUTHENTICATION_ERROR"] = "AUTHENTICATION_ERROR";
|
|
@@ -14262,29 +14263,54 @@ class AuthManager {
|
|
|
14262
14263
|
},
|
|
14263
14264
|
});
|
|
14264
14265
|
};
|
|
14265
|
-
|
|
14266
|
+
/**
|
|
14267
|
+
* login
|
|
14268
|
+
* @param anonymousId Caller can pass an anonymousId if they want to associate their user's identity with immutable's internal instrumentation.
|
|
14269
|
+
*/
|
|
14270
|
+
async login(anonymousId) {
|
|
14266
14271
|
return withPassportError(async () => {
|
|
14272
|
+
const rid = getDetail(Detail.RUNTIME_ID);
|
|
14267
14273
|
const popupWindowFeatures = { width: 410, height: 450 };
|
|
14268
14274
|
const oidcUser = await this.userManager.signinPopup({
|
|
14275
|
+
extraQueryParams: {
|
|
14276
|
+
rid: rid || '',
|
|
14277
|
+
third_party_a_id: anonymousId || '',
|
|
14278
|
+
},
|
|
14269
14279
|
popupWindowFeatures,
|
|
14270
14280
|
});
|
|
14271
14281
|
return AuthManager.mapOidcUserToDomainModel(oidcUser);
|
|
14272
14282
|
}, PassportErrorType.AUTHENTICATION_ERROR);
|
|
14273
14283
|
}
|
|
14284
|
+
async getUserOrLogin() {
|
|
14285
|
+
let user = null;
|
|
14286
|
+
try {
|
|
14287
|
+
user = await this.getUser();
|
|
14288
|
+
}
|
|
14289
|
+
catch (err) {
|
|
14290
|
+
// eslint-disable-next-line no-console
|
|
14291
|
+
console.warn('failed to retrieve a cached user session:', err);
|
|
14292
|
+
}
|
|
14293
|
+
return user || this.login();
|
|
14294
|
+
}
|
|
14274
14295
|
async loginCallback() {
|
|
14275
14296
|
return withPassportError(async () => this.userManager.signinPopupCallback(), PassportErrorType.AUTHENTICATION_ERROR);
|
|
14276
14297
|
}
|
|
14277
|
-
|
|
14298
|
+
/**
|
|
14299
|
+
* loginWithDeviceFlow
|
|
14300
|
+
* @param anonymousId Caller can pass an anonymousId if they want to associate their user's identity with immutable's internal instrumentation.
|
|
14301
|
+
*/
|
|
14302
|
+
async loginWithDeviceFlow(anonymousId) {
|
|
14278
14303
|
return withPassportError(async () => {
|
|
14279
14304
|
const response = await globalAxios$1.post(`${this.config.authenticationDomain}/oauth/device/code`, {
|
|
14280
14305
|
client_id: this.config.oidcConfiguration.clientId,
|
|
14281
14306
|
scope: this.config.oidcConfiguration.scope,
|
|
14282
14307
|
audience: this.config.oidcConfiguration.audience,
|
|
14283
14308
|
}, formUrlEncodedHeader);
|
|
14309
|
+
const rid = getDetail(Detail.RUNTIME_ID);
|
|
14284
14310
|
return {
|
|
14285
14311
|
code: response.data.user_code,
|
|
14286
14312
|
deviceCode: response.data.device_code,
|
|
14287
|
-
url: response.data.verification_uri_complete
|
|
14313
|
+
url: `${response.data.verification_uri_complete}${rid ? `&rid=${rid}` : ''}${anonymousId ? `&third_party_a_id=${anonymousId}` : ''}`,
|
|
14288
14314
|
interval: response.data.interval,
|
|
14289
14315
|
};
|
|
14290
14316
|
}, PassportErrorType.AUTHENTICATION_ERROR);
|
|
@@ -14518,274 +14544,53 @@ const getStarkSigner = async (signer) => withPassportError(async () => {
|
|
|
14518
14544
|
return createStarkSigner(privateKey);
|
|
14519
14545
|
}, PassportErrorType.WALLET_CONNECTION_ERROR);
|
|
14520
14546
|
|
|
14521
|
-
|
|
14522
|
-
|
|
14523
|
-
|
|
14524
|
-
|
|
14525
|
-
});
|
|
14526
|
-
const retryWithDelay = async (fn, options) => {
|
|
14527
|
-
const { retries = MAX_RETRIES, interval = POLL_INTERVAL, finalErr = Error('Retry failed'), finallyFn = () => { }, } = options || {};
|
|
14528
|
-
try {
|
|
14529
|
-
return await fn();
|
|
14530
|
-
}
|
|
14531
|
-
catch (err) {
|
|
14532
|
-
if (retries <= 0) {
|
|
14533
|
-
return Promise.reject(finalErr);
|
|
14534
|
-
}
|
|
14535
|
-
await wait(interval);
|
|
14536
|
-
return retryWithDelay(fn, { retries: retries - 1, finalErr, finallyFn });
|
|
14537
|
-
}
|
|
14538
|
-
finally {
|
|
14539
|
-
if (retries <= 0) {
|
|
14540
|
-
finallyFn();
|
|
14541
|
-
}
|
|
14542
|
-
}
|
|
14543
|
-
};
|
|
14547
|
+
var PassportEvents;
|
|
14548
|
+
(function (PassportEvents) {
|
|
14549
|
+
PassportEvents["LOGGED_OUT"] = "loggedOut";
|
|
14550
|
+
})(PassportEvents || (PassportEvents = {}));
|
|
14544
14551
|
|
|
14545
|
-
|
|
14546
|
-
|
|
14547
|
-
|
|
14548
|
-
|
|
14549
|
-
|
|
14550
|
-
|
|
14551
|
-
|
|
14552
|
-
|
|
14553
|
-
|
|
14554
|
-
|
|
14555
|
-
|
|
14556
|
-
}
|
|
14557
|
-
|
|
14558
|
-
|
|
14559
|
-
|
|
14560
|
-
|
|
14561
|
-
|
|
14562
|
-
|
|
14563
|
-
|
|
14564
|
-
|
|
14565
|
-
|
|
14566
|
-
|
|
14567
|
-
|
|
14568
|
-
|
|
14569
|
-
|
|
14570
|
-
|
|
14571
|
-
|
|
14572
|
-
|
|
14573
|
-
|
|
14574
|
-
|
|
14575
|
-
}
|
|
14576
|
-
|
|
14577
|
-
|
|
14578
|
-
|
|
14579
|
-
|
|
14580
|
-
|
|
14581
|
-
|
|
14582
|
-
|
|
14583
|
-
|
|
14584
|
-
|
|
14585
|
-
|
|
14586
|
-
|
|
14587
|
-
value: t.value ? convertBigNumberishToString(t.value) : '0',
|
|
14588
|
-
data: t.data ? t.data.toString() : '0x',
|
|
14589
|
-
}));
|
|
14590
|
-
}
|
|
14591
|
-
catch (error) {
|
|
14592
|
-
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
14593
|
-
throw new JsonRpcError(RpcErrorCode.INVALID_PARAMS, `Transaction failed to parsing: ${errorMessage}`);
|
|
14594
|
-
}
|
|
14595
|
-
};
|
|
14596
|
-
class GuardianClient {
|
|
14597
|
-
transactionAPI;
|
|
14598
|
-
messageAPI;
|
|
14599
|
-
confirmationScreen;
|
|
14600
|
-
crossSdkBridgeEnabled;
|
|
14601
|
-
authManager;
|
|
14602
|
-
constructor({ confirmationScreen, config, authManager }) {
|
|
14603
|
-
const guardianConfiguration = new Configuration({ basePath: config.imxPublicApiDomain });
|
|
14604
|
-
this.confirmationScreen = confirmationScreen;
|
|
14605
|
-
this.crossSdkBridgeEnabled = config.crossSdkBridgeEnabled;
|
|
14606
|
-
this.messageAPI = new MessagesApi(guardianConfiguration);
|
|
14607
|
-
this.transactionAPI = new TransactionsApi(guardianConfiguration);
|
|
14608
|
-
this.authManager = authManager;
|
|
14609
|
-
}
|
|
14610
|
-
/**
|
|
14611
|
-
* Open confirmation screen and close it automatically if the
|
|
14612
|
-
* underlying task fails.
|
|
14613
|
-
*/
|
|
14614
|
-
withConfirmationScreen(popupWindowSize) {
|
|
14615
|
-
return (task) => this.withConfirmationScreenTask(popupWindowSize)(task)();
|
|
14616
|
-
}
|
|
14617
|
-
withConfirmationScreenTask(popupWindowSize) {
|
|
14618
|
-
return (task) => async () => {
|
|
14619
|
-
this.confirmationScreen.loading(popupWindowSize);
|
|
14620
|
-
try {
|
|
14621
|
-
return await task();
|
|
14622
|
-
}
|
|
14623
|
-
catch (err) {
|
|
14624
|
-
this.confirmationScreen.closeWindow();
|
|
14625
|
-
throw err;
|
|
14626
|
-
}
|
|
14627
|
-
};
|
|
14628
|
-
}
|
|
14629
|
-
withDefaultConfirmationScreenTask(task) {
|
|
14630
|
-
return this.withConfirmationScreenTask()(task);
|
|
14631
|
-
}
|
|
14632
|
-
async evaluateImxTransaction({ payloadHash }) {
|
|
14633
|
-
const finallyFn = () => {
|
|
14634
|
-
this.confirmationScreen.closeWindow();
|
|
14635
|
-
};
|
|
14636
|
-
const user = await this.authManager.getUser();
|
|
14637
|
-
const headers = { Authorization: `Bearer ${user.accessToken}` };
|
|
14638
|
-
const transactionRes = await retryWithDelay(async () => this.transactionAPI.getTransactionByID({
|
|
14639
|
-
transactionID: payloadHash,
|
|
14640
|
-
chainType: 'starkex',
|
|
14641
|
-
}, { headers }), { finallyFn });
|
|
14642
|
-
if (!transactionRes.data.id) {
|
|
14643
|
-
throw new Error("Transaction doesn't exists");
|
|
14644
|
-
}
|
|
14645
|
-
const evaluateImxRes = await this.transactionAPI.evaluateTransaction({
|
|
14646
|
-
id: payloadHash,
|
|
14647
|
-
transactionEvaluationRequest: {
|
|
14648
|
-
chainType: 'starkex',
|
|
14649
|
-
},
|
|
14650
|
-
}, { headers });
|
|
14651
|
-
const { confirmationRequired } = evaluateImxRes.data;
|
|
14652
|
-
if (confirmationRequired) {
|
|
14653
|
-
if (this.crossSdkBridgeEnabled) {
|
|
14654
|
-
throw new Error(transactionRejectedCrossSdkBridgeError);
|
|
14655
|
-
}
|
|
14656
|
-
const confirmationResult = await this.confirmationScreen.requestConfirmation(payloadHash, user.imx.ethAddress, TransactionApprovalRequestChainTypeEnum.Starkex);
|
|
14657
|
-
if (!confirmationResult.confirmed) {
|
|
14658
|
-
throw new Error('Transaction rejected by user');
|
|
14659
|
-
}
|
|
14660
|
-
}
|
|
14661
|
-
else {
|
|
14662
|
-
this.confirmationScreen.closeWindow();
|
|
14663
|
-
}
|
|
14664
|
-
}
|
|
14665
|
-
async evaluateEVMTransaction({ chainId, nonce, metaTransactions, }) {
|
|
14666
|
-
const user = await this.authManager.getUser();
|
|
14667
|
-
const headers = { Authorization: `Bearer ${user.accessToken}` };
|
|
14668
|
-
const guardianTransactions = transformGuardianTransactions(metaTransactions);
|
|
14669
|
-
try {
|
|
14670
|
-
const transactionEvaluationResponseAxiosResponse = await this.transactionAPI.evaluateTransaction({
|
|
14671
|
-
id: 'evm',
|
|
14672
|
-
transactionEvaluationRequest: {
|
|
14673
|
-
chainType: 'evm',
|
|
14674
|
-
chainId,
|
|
14675
|
-
transactionData: {
|
|
14676
|
-
nonce,
|
|
14677
|
-
userAddress: user.zkEvm.ethAddress,
|
|
14678
|
-
metaTransactions: guardianTransactions,
|
|
14679
|
-
},
|
|
14680
|
-
},
|
|
14681
|
-
}, { headers });
|
|
14682
|
-
return transactionEvaluationResponseAxiosResponse.data;
|
|
14683
|
-
}
|
|
14684
|
-
catch (error) {
|
|
14685
|
-
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
14686
|
-
throw new JsonRpcError(RpcErrorCode.INTERNAL_ERROR, `Transaction failed to validate with error: ${errorMessage}`);
|
|
14687
|
-
}
|
|
14688
|
-
}
|
|
14689
|
-
async validateEVMTransaction({ chainId, nonce, metaTransactions, }) {
|
|
14690
|
-
const transactionEvaluationResponse = await this.evaluateEVMTransaction({
|
|
14691
|
-
chainId,
|
|
14692
|
-
nonce,
|
|
14693
|
-
metaTransactions,
|
|
14694
|
-
});
|
|
14695
|
-
const { confirmationRequired, transactionId } = transactionEvaluationResponse;
|
|
14696
|
-
if (confirmationRequired && this.crossSdkBridgeEnabled) {
|
|
14697
|
-
throw new JsonRpcError(RpcErrorCode.TRANSACTION_REJECTED, transactionRejectedCrossSdkBridgeError);
|
|
14698
|
-
}
|
|
14699
|
-
if (confirmationRequired && !!transactionId) {
|
|
14700
|
-
const user = await this.authManager.getUser();
|
|
14701
|
-
const confirmationResult = await this.confirmationScreen.requestConfirmation(transactionId, user.zkEvm.ethAddress, TransactionApprovalRequestChainTypeEnum.Evm, chainId);
|
|
14702
|
-
if (!confirmationResult.confirmed) {
|
|
14703
|
-
throw new JsonRpcError(RpcErrorCode.TRANSACTION_REJECTED, 'Transaction rejected by user');
|
|
14704
|
-
}
|
|
14705
|
-
}
|
|
14706
|
-
else {
|
|
14707
|
-
this.confirmationScreen.closeWindow();
|
|
14708
|
-
}
|
|
14709
|
-
}
|
|
14710
|
-
async evaluateMessage({ chainID, payload }) {
|
|
14711
|
-
try {
|
|
14712
|
-
const user = await this.authManager.getUser();
|
|
14713
|
-
if (user === null) {
|
|
14714
|
-
throw new PassportError('evaluateMessage requires a valid ID token or refresh token. Please log in first', PassportErrorType.NOT_LOGGED_IN_ERROR);
|
|
14715
|
-
}
|
|
14716
|
-
const messageEvalResponse = await this.messageAPI.evaluateMessage({ messageEvaluationRequest: { chainID, payload } }, { headers: { Authorization: `Bearer ${user.accessToken}` } });
|
|
14717
|
-
return messageEvalResponse.data;
|
|
14718
|
-
}
|
|
14719
|
-
catch (error) {
|
|
14720
|
-
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
14721
|
-
throw new JsonRpcError(RpcErrorCode.INTERNAL_ERROR, `Message failed to validate with error: ${errorMessage}`);
|
|
14722
|
-
}
|
|
14723
|
-
}
|
|
14724
|
-
async validateMessage({ chainID, payload }) {
|
|
14725
|
-
const { messageId, confirmationRequired } = await this.evaluateMessage({ chainID, payload });
|
|
14726
|
-
if (confirmationRequired && this.crossSdkBridgeEnabled) {
|
|
14727
|
-
throw new JsonRpcError(RpcErrorCode.TRANSACTION_REJECTED, transactionRejectedCrossSdkBridgeError);
|
|
14728
|
-
}
|
|
14729
|
-
if (confirmationRequired && !!messageId) {
|
|
14730
|
-
const user = await this.authManager.getUser();
|
|
14731
|
-
const confirmationResult = await this.confirmationScreen.requestMessageConfirmation(messageId, user.zkEvm.ethAddress);
|
|
14732
|
-
if (!confirmationResult.confirmed) {
|
|
14733
|
-
throw new JsonRpcError(RpcErrorCode.TRANSACTION_REJECTED, 'Signature rejected by user');
|
|
14734
|
-
}
|
|
14735
|
-
}
|
|
14736
|
-
else {
|
|
14737
|
-
this.confirmationScreen.closeWindow();
|
|
14738
|
-
}
|
|
14739
|
-
}
|
|
14740
|
-
}
|
|
14741
|
-
|
|
14742
|
-
var PassportEvents;
|
|
14743
|
-
(function (PassportEvents) {
|
|
14744
|
-
PassportEvents["LOGGED_OUT"] = "loggedOut";
|
|
14745
|
-
})(PassportEvents || (PassportEvents = {}));
|
|
14746
|
-
|
|
14747
|
-
async function exchangeTransfer({ user, starkSigner, request, exchangesApi, }) {
|
|
14748
|
-
return withPassportError(async () => {
|
|
14749
|
-
const { ethAddress } = user.imx;
|
|
14750
|
-
const transferAmount = request.amount;
|
|
14751
|
-
const signableResult = await exchangesApi.getExchangeSignableTransfer({
|
|
14752
|
-
id: request.transactionID,
|
|
14753
|
-
getSignableTransferRequest: {
|
|
14754
|
-
sender: ethAddress,
|
|
14755
|
-
token: convertToSignableToken(request),
|
|
14756
|
-
amount: transferAmount,
|
|
14757
|
-
receiver: request.receiver,
|
|
14758
|
-
},
|
|
14759
|
-
});
|
|
14760
|
-
const starkAddress = await starkSigner.getAddress();
|
|
14761
|
-
const { payload_hash: payloadHash } = signableResult.data;
|
|
14762
|
-
const starkSignature = await starkSigner.signMessage(payloadHash);
|
|
14763
|
-
const transferSigningParams = {
|
|
14764
|
-
sender_stark_key: signableResult.data.sender_stark_key || starkAddress,
|
|
14765
|
-
sender_vault_id: signableResult.data.sender_vault_id,
|
|
14766
|
-
receiver_stark_key: signableResult.data.receiver_stark_key,
|
|
14767
|
-
receiver_vault_id: signableResult.data.receiver_vault_id,
|
|
14768
|
-
asset_id: signableResult.data.asset_id,
|
|
14769
|
-
amount: signableResult.data.amount,
|
|
14770
|
-
nonce: signableResult.data.nonce,
|
|
14771
|
-
expiration_timestamp: signableResult.data.expiration_timestamp,
|
|
14772
|
-
stark_signature: starkSignature,
|
|
14773
|
-
};
|
|
14774
|
-
const headers = {
|
|
14775
|
-
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
14776
|
-
Authorization: `Bearer ${user.accessToken}`,
|
|
14777
|
-
};
|
|
14778
|
-
const response = await exchangesApi.createExchangeTransfer({
|
|
14779
|
-
id: request.transactionID,
|
|
14780
|
-
createTransferRequest: transferSigningParams,
|
|
14781
|
-
}, { headers });
|
|
14782
|
-
return {
|
|
14783
|
-
sent_signature: response?.data.sent_signature,
|
|
14784
|
-
status: response?.data.status?.toString(),
|
|
14785
|
-
time: response?.data.time,
|
|
14786
|
-
transfer_id: response?.data.transfer_id,
|
|
14787
|
-
};
|
|
14788
|
-
}, PassportErrorType.EXCHANGE_TRANSFER_ERROR);
|
|
14552
|
+
async function exchangeTransfer({ user, starkSigner, request, exchangesApi, }) {
|
|
14553
|
+
return withPassportError(async () => {
|
|
14554
|
+
const { ethAddress } = user.imx;
|
|
14555
|
+
const transferAmount = request.amount;
|
|
14556
|
+
const signableResult = await exchangesApi.getExchangeSignableTransfer({
|
|
14557
|
+
id: request.transactionID,
|
|
14558
|
+
getSignableTransferRequest: {
|
|
14559
|
+
sender: ethAddress,
|
|
14560
|
+
token: convertToSignableToken(request),
|
|
14561
|
+
amount: transferAmount,
|
|
14562
|
+
receiver: request.receiver,
|
|
14563
|
+
},
|
|
14564
|
+
});
|
|
14565
|
+
const starkAddress = await starkSigner.getAddress();
|
|
14566
|
+
const { payload_hash: payloadHash } = signableResult.data;
|
|
14567
|
+
const starkSignature = await starkSigner.signMessage(payloadHash);
|
|
14568
|
+
const transferSigningParams = {
|
|
14569
|
+
sender_stark_key: signableResult.data.sender_stark_key || starkAddress,
|
|
14570
|
+
sender_vault_id: signableResult.data.sender_vault_id,
|
|
14571
|
+
receiver_stark_key: signableResult.data.receiver_stark_key,
|
|
14572
|
+
receiver_vault_id: signableResult.data.receiver_vault_id,
|
|
14573
|
+
asset_id: signableResult.data.asset_id,
|
|
14574
|
+
amount: signableResult.data.amount,
|
|
14575
|
+
nonce: signableResult.data.nonce,
|
|
14576
|
+
expiration_timestamp: signableResult.data.expiration_timestamp,
|
|
14577
|
+
stark_signature: starkSignature,
|
|
14578
|
+
};
|
|
14579
|
+
const headers = {
|
|
14580
|
+
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
14581
|
+
Authorization: `Bearer ${user.accessToken}`,
|
|
14582
|
+
};
|
|
14583
|
+
const response = await exchangesApi.createExchangeTransfer({
|
|
14584
|
+
id: request.transactionID,
|
|
14585
|
+
createTransferRequest: transferSigningParams,
|
|
14586
|
+
}, { headers });
|
|
14587
|
+
return {
|
|
14588
|
+
sent_signature: response?.data.sent_signature,
|
|
14589
|
+
status: response?.data.status?.toString(),
|
|
14590
|
+
time: response?.data.time,
|
|
14591
|
+
transfer_id: response?.data.transfer_id,
|
|
14592
|
+
};
|
|
14593
|
+
}, PassportErrorType.EXCHANGE_TRANSFER_ERROR);
|
|
14789
14594
|
}
|
|
14790
14595
|
|
|
14791
14596
|
const ERC721$1 = 'ERC721';
|
|
@@ -15037,6 +14842,30 @@ async function batchNftTransfer({ user, starkSigner, request, transfersApi, guar
|
|
|
15037
14842
|
}), PassportErrorType.TRANSFER_ERROR);
|
|
15038
14843
|
}
|
|
15039
14844
|
|
|
14845
|
+
const POLL_INTERVAL = 1 * 1000; // every 1 second
|
|
14846
|
+
const MAX_RETRIES = 3;
|
|
14847
|
+
const wait = (ms) => new Promise((resolve) => {
|
|
14848
|
+
setTimeout(() => resolve(), ms);
|
|
14849
|
+
});
|
|
14850
|
+
const retryWithDelay = async (fn, options) => {
|
|
14851
|
+
const { retries = MAX_RETRIES, interval = POLL_INTERVAL, finalErr = Error('Retry failed'), finallyFn = () => { }, } = options || {};
|
|
14852
|
+
try {
|
|
14853
|
+
return await fn();
|
|
14854
|
+
}
|
|
14855
|
+
catch (err) {
|
|
14856
|
+
if (retries <= 0) {
|
|
14857
|
+
return Promise.reject(finalErr);
|
|
14858
|
+
}
|
|
14859
|
+
await wait(interval);
|
|
14860
|
+
return retryWithDelay(fn, { retries: retries - 1, finalErr, finallyFn });
|
|
14861
|
+
}
|
|
14862
|
+
finally {
|
|
14863
|
+
if (retries <= 0) {
|
|
14864
|
+
finallyFn();
|
|
14865
|
+
}
|
|
14866
|
+
}
|
|
14867
|
+
};
|
|
14868
|
+
|
|
15040
14869
|
async function forceUserRefresh(authManager) {
|
|
15041
14870
|
// User metadata is updated asynchronously. Poll userinfo endpoint until it is updated.
|
|
15042
14871
|
await retryWithDelay(async () => {
|
|
@@ -15082,16 +14911,12 @@ class PassportImxProvider {
|
|
|
15082
14911
|
*/
|
|
15083
14912
|
signers;
|
|
15084
14913
|
signerInitialisationError;
|
|
15085
|
-
constructor({ authManager, immutableXClient,
|
|
14914
|
+
constructor({ authManager, immutableXClient, passportEventEmitter, magicAdapter, imxApiClients, guardianClient, }) {
|
|
15086
14915
|
this.authManager = authManager;
|
|
15087
14916
|
this.immutableXClient = immutableXClient;
|
|
15088
|
-
this.guardianClient = new GuardianClient({
|
|
15089
|
-
confirmationScreen,
|
|
15090
|
-
config,
|
|
15091
|
-
authManager,
|
|
15092
|
-
});
|
|
15093
14917
|
this.magicAdapter = magicAdapter;
|
|
15094
14918
|
this.imxApiClients = imxApiClients;
|
|
14919
|
+
this.guardianClient = guardianClient;
|
|
15095
14920
|
this.initialiseSigners();
|
|
15096
14921
|
passportEventEmitter.on(PassportEvents.LOGGED_OUT, this.handleLogout);
|
|
15097
14922
|
}
|
|
@@ -15254,33 +15079,21 @@ class PassportImxProvider {
|
|
|
15254
15079
|
|
|
15255
15080
|
class PassportImxProviderFactory {
|
|
15256
15081
|
authManager;
|
|
15257
|
-
config;
|
|
15258
|
-
confirmationScreen;
|
|
15259
15082
|
immutableXClient;
|
|
15260
15083
|
magicAdapter;
|
|
15261
15084
|
passportEventEmitter;
|
|
15262
15085
|
imxApiClients;
|
|
15263
|
-
|
|
15086
|
+
guardianClient;
|
|
15087
|
+
constructor({ authManager, immutableXClient, magicAdapter, passportEventEmitter, imxApiClients, guardianClient, }) {
|
|
15264
15088
|
this.authManager = authManager;
|
|
15265
|
-
this.config = config;
|
|
15266
|
-
this.confirmationScreen = confirmationScreen;
|
|
15267
15089
|
this.immutableXClient = immutableXClient;
|
|
15268
15090
|
this.magicAdapter = magicAdapter;
|
|
15269
15091
|
this.passportEventEmitter = passportEventEmitter;
|
|
15270
15092
|
this.imxApiClients = imxApiClients;
|
|
15093
|
+
this.guardianClient = guardianClient;
|
|
15271
15094
|
}
|
|
15272
15095
|
async getProvider() {
|
|
15273
|
-
|
|
15274
|
-
try {
|
|
15275
|
-
user = await this.authManager.getUser();
|
|
15276
|
-
}
|
|
15277
|
-
catch (e) {
|
|
15278
|
-
// eslint-disable-next-line no-console
|
|
15279
|
-
console.warn(e);
|
|
15280
|
-
}
|
|
15281
|
-
if (!user) {
|
|
15282
|
-
user = await this.authManager.login();
|
|
15283
|
-
}
|
|
15096
|
+
const user = await this.authManager.getUserOrLogin();
|
|
15284
15097
|
return this.createProviderInstance(user);
|
|
15285
15098
|
}
|
|
15286
15099
|
async getProviderSilent() {
|
|
@@ -15295,13 +15108,12 @@ class PassportImxProviderFactory {
|
|
|
15295
15108
|
throw new PassportError('Failed to initialise', PassportErrorType.WALLET_CONNECTION_ERROR);
|
|
15296
15109
|
}
|
|
15297
15110
|
return new PassportImxProvider({
|
|
15298
|
-
config: this.config,
|
|
15299
15111
|
authManager: this.authManager,
|
|
15300
15112
|
immutableXClient: this.immutableXClient,
|
|
15301
|
-
confirmationScreen: this.confirmationScreen,
|
|
15302
15113
|
passportEventEmitter: this.passportEventEmitter,
|
|
15303
15114
|
magicAdapter: this.magicAdapter,
|
|
15304
15115
|
imxApiClients: this.imxApiClients,
|
|
15116
|
+
guardianClient: this.guardianClient,
|
|
15305
15117
|
});
|
|
15306
15118
|
}
|
|
15307
15119
|
}
|
|
@@ -15796,6 +15608,38 @@ class RelayerClient {
|
|
|
15796
15608
|
}
|
|
15797
15609
|
}
|
|
15798
15610
|
|
|
15611
|
+
/**
|
|
15612
|
+
* ProviderErrors should take priority over RpcErrorCodes
|
|
15613
|
+
* https://eips.ethereum.org/EIPS/eip-1193#provider-errors
|
|
15614
|
+
* https://eips.ethereum.org/EIPS/eip-1474#error-codes
|
|
15615
|
+
*/
|
|
15616
|
+
var ProviderErrorCode;
|
|
15617
|
+
(function (ProviderErrorCode) {
|
|
15618
|
+
ProviderErrorCode[ProviderErrorCode["USER_REJECTED_REQUEST"] = 4001] = "USER_REJECTED_REQUEST";
|
|
15619
|
+
ProviderErrorCode[ProviderErrorCode["UNAUTHORIZED"] = 4100] = "UNAUTHORIZED";
|
|
15620
|
+
ProviderErrorCode[ProviderErrorCode["UNSUPPORTED_METHOD"] = 4200] = "UNSUPPORTED_METHOD";
|
|
15621
|
+
ProviderErrorCode[ProviderErrorCode["DISCONNECTED"] = 4900] = "DISCONNECTED";
|
|
15622
|
+
})(ProviderErrorCode || (ProviderErrorCode = {}));
|
|
15623
|
+
var RpcErrorCode;
|
|
15624
|
+
(function (RpcErrorCode) {
|
|
15625
|
+
RpcErrorCode[RpcErrorCode["RPC_SERVER_ERROR"] = -32000] = "RPC_SERVER_ERROR";
|
|
15626
|
+
RpcErrorCode[RpcErrorCode["INVALID_REQUEST"] = -32600] = "INVALID_REQUEST";
|
|
15627
|
+
RpcErrorCode[RpcErrorCode["METHOD_NOT_FOUND"] = -32601] = "METHOD_NOT_FOUND";
|
|
15628
|
+
RpcErrorCode[RpcErrorCode["INVALID_PARAMS"] = -32602] = "INVALID_PARAMS";
|
|
15629
|
+
RpcErrorCode[RpcErrorCode["INTERNAL_ERROR"] = -32603] = "INTERNAL_ERROR";
|
|
15630
|
+
RpcErrorCode[RpcErrorCode["PARSE_ERROR"] = -32700] = "PARSE_ERROR";
|
|
15631
|
+
RpcErrorCode[RpcErrorCode["TRANSACTION_REJECTED"] = -32003] = "TRANSACTION_REJECTED";
|
|
15632
|
+
})(RpcErrorCode || (RpcErrorCode = {}));
|
|
15633
|
+
class JsonRpcError extends Error {
|
|
15634
|
+
message;
|
|
15635
|
+
code;
|
|
15636
|
+
constructor(code, message) {
|
|
15637
|
+
super(message);
|
|
15638
|
+
this.message = message;
|
|
15639
|
+
this.code = code;
|
|
15640
|
+
}
|
|
15641
|
+
}
|
|
15642
|
+
|
|
15799
15643
|
const MESSAGE_TO_SIGN = 'Only sign this message from Immutable Passport';
|
|
15800
15644
|
async function registerZkEvmUser({ authManager, magicProvider, multiRollupApiClients, accessToken, jsonRpcProvider, }) {
|
|
15801
15645
|
const web3Provider = new Web3Provider(magicProvider);
|
|
@@ -15830,17 +15674,7 @@ async function registerZkEvmUser({ authManager, magicProvider, multiRollupApiCli
|
|
|
15830
15674
|
}
|
|
15831
15675
|
|
|
15832
15676
|
const loginZkEvmUser = async ({ authManager, magicAdapter, multiRollupApiClients, jsonRpcProvider, }) => {
|
|
15833
|
-
|
|
15834
|
-
try {
|
|
15835
|
-
user = await authManager.getUser();
|
|
15836
|
-
}
|
|
15837
|
-
catch (err) {
|
|
15838
|
-
// eslint-disable-next-line no-console
|
|
15839
|
-
console.warn('eth_requestAccounts` failed to retrieve a cached user session:', err);
|
|
15840
|
-
}
|
|
15841
|
-
if (!user) {
|
|
15842
|
-
user = await authManager.login();
|
|
15843
|
-
}
|
|
15677
|
+
const user = await authManager.getUserOrLogin();
|
|
15844
15678
|
if (!user.idToken) {
|
|
15845
15679
|
throw new Error('User is missing idToken');
|
|
15846
15680
|
}
|
|
@@ -15865,6 +15699,171 @@ const loginZkEvmUser = async ({ authManager, magicAdapter, multiRollupApiClients
|
|
|
15865
15699
|
};
|
|
15866
15700
|
};
|
|
15867
15701
|
|
|
15702
|
+
const transactionRejectedCrossSdkBridgeError = 'Transaction requires confirmation but this functionality is not'
|
|
15703
|
+
+ ' supported in this environment. Please contact Immutable support if you need to enable this feature.';
|
|
15704
|
+
const convertBigNumberishToString = (value) => BigNumber.from(value).toString();
|
|
15705
|
+
const transformGuardianTransactions = (txs) => {
|
|
15706
|
+
try {
|
|
15707
|
+
return txs.map((t) => ({
|
|
15708
|
+
delegateCall: t.delegateCall === true,
|
|
15709
|
+
revertOnError: t.revertOnError === true,
|
|
15710
|
+
gasLimit: t.gasLimit ? convertBigNumberishToString(t.gasLimit) : '0',
|
|
15711
|
+
target: t.to ?? ethers.constants.AddressZero,
|
|
15712
|
+
value: t.value ? convertBigNumberishToString(t.value) : '0',
|
|
15713
|
+
data: t.data ? t.data.toString() : '0x',
|
|
15714
|
+
}));
|
|
15715
|
+
}
|
|
15716
|
+
catch (error) {
|
|
15717
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
15718
|
+
throw new JsonRpcError(RpcErrorCode.INVALID_PARAMS, `Transaction failed to parsing: ${errorMessage}`);
|
|
15719
|
+
}
|
|
15720
|
+
};
|
|
15721
|
+
class GuardianClient {
|
|
15722
|
+
transactionAPI;
|
|
15723
|
+
messageAPI;
|
|
15724
|
+
confirmationScreen;
|
|
15725
|
+
crossSdkBridgeEnabled;
|
|
15726
|
+
authManager;
|
|
15727
|
+
constructor({ confirmationScreen, config, authManager }) {
|
|
15728
|
+
const guardianConfiguration = new Configuration({ basePath: config.imxPublicApiDomain });
|
|
15729
|
+
this.confirmationScreen = confirmationScreen;
|
|
15730
|
+
this.crossSdkBridgeEnabled = config.crossSdkBridgeEnabled;
|
|
15731
|
+
this.messageAPI = new MessagesApi(guardianConfiguration);
|
|
15732
|
+
this.transactionAPI = new TransactionsApi(guardianConfiguration);
|
|
15733
|
+
this.authManager = authManager;
|
|
15734
|
+
}
|
|
15735
|
+
/**
|
|
15736
|
+
* Open confirmation screen and close it automatically if the
|
|
15737
|
+
* underlying task fails.
|
|
15738
|
+
*/
|
|
15739
|
+
withConfirmationScreen(popupWindowSize) {
|
|
15740
|
+
return (task) => this.withConfirmationScreenTask(popupWindowSize)(task)();
|
|
15741
|
+
}
|
|
15742
|
+
withConfirmationScreenTask(popupWindowSize) {
|
|
15743
|
+
return (task) => async () => {
|
|
15744
|
+
this.confirmationScreen.loading(popupWindowSize);
|
|
15745
|
+
try {
|
|
15746
|
+
return await task();
|
|
15747
|
+
}
|
|
15748
|
+
catch (err) {
|
|
15749
|
+
this.confirmationScreen.closeWindow();
|
|
15750
|
+
throw err;
|
|
15751
|
+
}
|
|
15752
|
+
};
|
|
15753
|
+
}
|
|
15754
|
+
withDefaultConfirmationScreenTask(task) {
|
|
15755
|
+
return this.withConfirmationScreenTask()(task);
|
|
15756
|
+
}
|
|
15757
|
+
async evaluateImxTransaction({ payloadHash }) {
|
|
15758
|
+
const finallyFn = () => {
|
|
15759
|
+
this.confirmationScreen.closeWindow();
|
|
15760
|
+
};
|
|
15761
|
+
const user = await this.authManager.getUser();
|
|
15762
|
+
const headers = { Authorization: `Bearer ${user.accessToken}` };
|
|
15763
|
+
const transactionRes = await retryWithDelay(async () => this.transactionAPI.getTransactionByID({
|
|
15764
|
+
transactionID: payloadHash,
|
|
15765
|
+
chainType: 'starkex',
|
|
15766
|
+
}, { headers }), { finallyFn });
|
|
15767
|
+
if (!transactionRes.data.id) {
|
|
15768
|
+
throw new Error("Transaction doesn't exists");
|
|
15769
|
+
}
|
|
15770
|
+
const evaluateImxRes = await this.transactionAPI.evaluateTransaction({
|
|
15771
|
+
id: payloadHash,
|
|
15772
|
+
transactionEvaluationRequest: {
|
|
15773
|
+
chainType: 'starkex',
|
|
15774
|
+
},
|
|
15775
|
+
}, { headers });
|
|
15776
|
+
const { confirmationRequired } = evaluateImxRes.data;
|
|
15777
|
+
if (confirmationRequired) {
|
|
15778
|
+
if (this.crossSdkBridgeEnabled) {
|
|
15779
|
+
throw new Error(transactionRejectedCrossSdkBridgeError);
|
|
15780
|
+
}
|
|
15781
|
+
const confirmationResult = await this.confirmationScreen.requestConfirmation(payloadHash, user.imx.ethAddress, TransactionApprovalRequestChainTypeEnum.Starkex);
|
|
15782
|
+
if (!confirmationResult.confirmed) {
|
|
15783
|
+
throw new Error('Transaction rejected by user');
|
|
15784
|
+
}
|
|
15785
|
+
}
|
|
15786
|
+
else {
|
|
15787
|
+
this.confirmationScreen.closeWindow();
|
|
15788
|
+
}
|
|
15789
|
+
}
|
|
15790
|
+
async evaluateEVMTransaction({ chainId, nonce, metaTransactions, }) {
|
|
15791
|
+
const user = await this.authManager.getUser();
|
|
15792
|
+
const headers = { Authorization: `Bearer ${user.accessToken}` };
|
|
15793
|
+
const guardianTransactions = transformGuardianTransactions(metaTransactions);
|
|
15794
|
+
try {
|
|
15795
|
+
const transactionEvaluationResponseAxiosResponse = await this.transactionAPI.evaluateTransaction({
|
|
15796
|
+
id: 'evm',
|
|
15797
|
+
transactionEvaluationRequest: {
|
|
15798
|
+
chainType: 'evm',
|
|
15799
|
+
chainId,
|
|
15800
|
+
transactionData: {
|
|
15801
|
+
nonce,
|
|
15802
|
+
userAddress: user.zkEvm.ethAddress,
|
|
15803
|
+
metaTransactions: guardianTransactions,
|
|
15804
|
+
},
|
|
15805
|
+
},
|
|
15806
|
+
}, { headers });
|
|
15807
|
+
return transactionEvaluationResponseAxiosResponse.data;
|
|
15808
|
+
}
|
|
15809
|
+
catch (error) {
|
|
15810
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
15811
|
+
throw new JsonRpcError(RpcErrorCode.INTERNAL_ERROR, `Transaction failed to validate with error: ${errorMessage}`);
|
|
15812
|
+
}
|
|
15813
|
+
}
|
|
15814
|
+
async validateEVMTransaction({ chainId, nonce, metaTransactions, }) {
|
|
15815
|
+
const transactionEvaluationResponse = await this.evaluateEVMTransaction({
|
|
15816
|
+
chainId,
|
|
15817
|
+
nonce,
|
|
15818
|
+
metaTransactions,
|
|
15819
|
+
});
|
|
15820
|
+
const { confirmationRequired, transactionId } = transactionEvaluationResponse;
|
|
15821
|
+
if (confirmationRequired && this.crossSdkBridgeEnabled) {
|
|
15822
|
+
throw new JsonRpcError(RpcErrorCode.TRANSACTION_REJECTED, transactionRejectedCrossSdkBridgeError);
|
|
15823
|
+
}
|
|
15824
|
+
if (confirmationRequired && !!transactionId) {
|
|
15825
|
+
const user = await this.authManager.getUser();
|
|
15826
|
+
const confirmationResult = await this.confirmationScreen.requestConfirmation(transactionId, user.zkEvm.ethAddress, TransactionApprovalRequestChainTypeEnum.Evm, chainId);
|
|
15827
|
+
if (!confirmationResult.confirmed) {
|
|
15828
|
+
throw new JsonRpcError(RpcErrorCode.TRANSACTION_REJECTED, 'Transaction rejected by user');
|
|
15829
|
+
}
|
|
15830
|
+
}
|
|
15831
|
+
else {
|
|
15832
|
+
this.confirmationScreen.closeWindow();
|
|
15833
|
+
}
|
|
15834
|
+
}
|
|
15835
|
+
async evaluateMessage({ chainID, payload }) {
|
|
15836
|
+
try {
|
|
15837
|
+
const user = await this.authManager.getUser();
|
|
15838
|
+
if (user === null) {
|
|
15839
|
+
throw new PassportError('evaluateMessage requires a valid ID token or refresh token. Please log in first', PassportErrorType.NOT_LOGGED_IN_ERROR);
|
|
15840
|
+
}
|
|
15841
|
+
const messageEvalResponse = await this.messageAPI.evaluateMessage({ messageEvaluationRequest: { chainID, payload } }, { headers: { Authorization: `Bearer ${user.accessToken}` } });
|
|
15842
|
+
return messageEvalResponse.data;
|
|
15843
|
+
}
|
|
15844
|
+
catch (error) {
|
|
15845
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
15846
|
+
throw new JsonRpcError(RpcErrorCode.INTERNAL_ERROR, `Message failed to validate with error: ${errorMessage}`);
|
|
15847
|
+
}
|
|
15848
|
+
}
|
|
15849
|
+
async validateMessage({ chainID, payload }) {
|
|
15850
|
+
const { messageId, confirmationRequired } = await this.evaluateMessage({ chainID, payload });
|
|
15851
|
+
if (confirmationRequired && this.crossSdkBridgeEnabled) {
|
|
15852
|
+
throw new JsonRpcError(RpcErrorCode.TRANSACTION_REJECTED, transactionRejectedCrossSdkBridgeError);
|
|
15853
|
+
}
|
|
15854
|
+
if (confirmationRequired && !!messageId) {
|
|
15855
|
+
const user = await this.authManager.getUser();
|
|
15856
|
+
const confirmationResult = await this.confirmationScreen.requestMessageConfirmation(messageId, user.zkEvm.ethAddress);
|
|
15857
|
+
if (!confirmationResult.confirmed) {
|
|
15858
|
+
throw new JsonRpcError(RpcErrorCode.TRANSACTION_REJECTED, 'Signature rejected by user');
|
|
15859
|
+
}
|
|
15860
|
+
}
|
|
15861
|
+
else {
|
|
15862
|
+
this.confirmationScreen.closeWindow();
|
|
15863
|
+
}
|
|
15864
|
+
}
|
|
15865
|
+
}
|
|
15866
|
+
|
|
15868
15867
|
const MAX_TRANSACTION_HASH_RETRIEVAL_RETRIES = 30;
|
|
15869
15868
|
const TRANSACTION_HASH_RETRIEVAL_WAIT = 1000;
|
|
15870
15869
|
const getMetaTransactions = async (metaTransaction, nonce, chainId, walletAddress, signer, relayerClient) => {
|
|
@@ -16009,7 +16008,6 @@ const signTypedDataV4 = async ({ params, method, magicProvider, jsonRpcProvider,
|
|
|
16009
16008
|
class ZkEvmProvider {
|
|
16010
16009
|
authManager;
|
|
16011
16010
|
config;
|
|
16012
|
-
confirmationScreen;
|
|
16013
16011
|
magicAdapter;
|
|
16014
16012
|
multiRollupApiClients;
|
|
16015
16013
|
jsonRpcProvider; // Used for read
|
|
@@ -16019,11 +16017,11 @@ class ZkEvmProvider {
|
|
|
16019
16017
|
magicProvider; // Used for signing
|
|
16020
16018
|
zkevmAddress;
|
|
16021
16019
|
isPassport = true;
|
|
16022
|
-
constructor({ authManager, magicAdapter, config,
|
|
16020
|
+
constructor({ authManager, magicAdapter, config, multiRollupApiClients, passportEventEmitter, guardianClient, }) {
|
|
16023
16021
|
this.authManager = authManager;
|
|
16024
16022
|
this.magicAdapter = magicAdapter;
|
|
16025
16023
|
this.config = config;
|
|
16026
|
-
this.
|
|
16024
|
+
this.guardianClient = guardianClient;
|
|
16027
16025
|
if (config.crossSdkBridgeEnabled) {
|
|
16028
16026
|
// JsonRpcProvider by default sets the referrer as "client".
|
|
16029
16027
|
// On Unreal 4 this errors as the browser used is expecting a valid URL.
|
|
@@ -16043,7 +16041,6 @@ class ZkEvmProvider {
|
|
|
16043
16041
|
const shouldEmitAccountsChanged = this.isLoggedIn();
|
|
16044
16042
|
this.magicProvider = undefined;
|
|
16045
16043
|
this.relayerClient = undefined;
|
|
16046
|
-
this.guardianClient = undefined;
|
|
16047
16044
|
if (shouldEmitAccountsChanged) {
|
|
16048
16045
|
this.eventEmitter.emit(ProviderEvent.ACCOUNTS_CHANGED, []);
|
|
16049
16046
|
}
|
|
@@ -16051,8 +16048,7 @@ class ZkEvmProvider {
|
|
|
16051
16048
|
isLoggedIn() {
|
|
16052
16049
|
return this.magicProvider !== undefined
|
|
16053
16050
|
&& this.zkevmAddress !== undefined
|
|
16054
|
-
&& this.relayerClient !== undefined
|
|
16055
|
-
&& this.guardianClient !== undefined;
|
|
16051
|
+
&& this.relayerClient !== undefined;
|
|
16056
16052
|
}
|
|
16057
16053
|
async performRequest(request) {
|
|
16058
16054
|
switch (request.method) {
|
|
@@ -16062,7 +16058,6 @@ class ZkEvmProvider {
|
|
|
16062
16058
|
}
|
|
16063
16059
|
const { magicProvider, user } = await loginZkEvmUser({
|
|
16064
16060
|
authManager: this.authManager,
|
|
16065
|
-
config: this.config,
|
|
16066
16061
|
magicAdapter: this.magicAdapter,
|
|
16067
16062
|
multiRollupApiClients: this.multiRollupApiClients,
|
|
16068
16063
|
jsonRpcProvider: this.jsonRpcProvider,
|
|
@@ -16073,11 +16068,6 @@ class ZkEvmProvider {
|
|
|
16073
16068
|
jsonRpcProvider: this.jsonRpcProvider,
|
|
16074
16069
|
authManager: this.authManager,
|
|
16075
16070
|
});
|
|
16076
|
-
this.guardianClient = new GuardianClient({
|
|
16077
|
-
confirmationScreen: this.confirmationScreen,
|
|
16078
|
-
config: this.config,
|
|
16079
|
-
authManager: this.authManager,
|
|
16080
|
-
});
|
|
16081
16071
|
this.zkevmAddress = user.zkEvm.ethAddress;
|
|
16082
16072
|
this.eventEmitter.emit(ProviderEvent.ACCOUNTS_CHANGED, [user.zkEvm.ethAddress]);
|
|
16083
16073
|
return [user.zkEvm.ethAddress];
|
|
@@ -16256,15 +16246,19 @@ const buildPrivateVars = (passportModuleConfiguration) => {
|
|
|
16256
16246
|
const immutableXClient = passportModuleConfiguration.overrides
|
|
16257
16247
|
? passportModuleConfiguration.overrides.immutableXClient
|
|
16258
16248
|
: new IMXClient({ baseConfig: passportModuleConfiguration.baseConfig });
|
|
16249
|
+
const guardianClient = new GuardianClient({
|
|
16250
|
+
confirmationScreen,
|
|
16251
|
+
config,
|
|
16252
|
+
authManager,
|
|
16253
|
+
});
|
|
16259
16254
|
const imxApiClients = buildImxApiClients(passportModuleConfiguration);
|
|
16260
16255
|
const passportImxProviderFactory = new PassportImxProviderFactory({
|
|
16261
16256
|
authManager,
|
|
16262
|
-
config,
|
|
16263
|
-
confirmationScreen,
|
|
16264
16257
|
immutableXClient,
|
|
16265
16258
|
magicAdapter,
|
|
16266
16259
|
passportEventEmitter,
|
|
16267
16260
|
imxApiClients,
|
|
16261
|
+
guardianClient,
|
|
16268
16262
|
});
|
|
16269
16263
|
return {
|
|
16270
16264
|
config,
|
|
@@ -16275,6 +16269,7 @@ const buildPrivateVars = (passportModuleConfiguration) => {
|
|
|
16275
16269
|
multiRollupApiClients,
|
|
16276
16270
|
passportEventEmitter,
|
|
16277
16271
|
passportImxProviderFactory,
|
|
16272
|
+
guardianClient,
|
|
16278
16273
|
};
|
|
16279
16274
|
};
|
|
16280
16275
|
class Passport {
|
|
@@ -16286,6 +16281,7 @@ class Passport {
|
|
|
16286
16281
|
multiRollupApiClients;
|
|
16287
16282
|
passportImxProviderFactory;
|
|
16288
16283
|
passportEventEmitter;
|
|
16284
|
+
guardianClient;
|
|
16289
16285
|
constructor(passportModuleConfiguration) {
|
|
16290
16286
|
const privateVars = buildPrivateVars(passportModuleConfiguration);
|
|
16291
16287
|
this.config = privateVars.config;
|
|
@@ -16296,6 +16292,7 @@ class Passport {
|
|
|
16296
16292
|
this.multiRollupApiClients = privateVars.multiRollupApiClients;
|
|
16297
16293
|
this.passportEventEmitter = privateVars.passportEventEmitter;
|
|
16298
16294
|
this.passportImxProviderFactory = privateVars.passportImxProviderFactory;
|
|
16295
|
+
this.guardianClient = privateVars.guardianClient;
|
|
16299
16296
|
setPassportClientId(passportModuleConfiguration.clientId);
|
|
16300
16297
|
track('passport', 'initialised');
|
|
16301
16298
|
}
|
|
@@ -16315,8 +16312,8 @@ class Passport {
|
|
|
16315
16312
|
authManager: this.authManager,
|
|
16316
16313
|
magicAdapter: this.magicAdapter,
|
|
16317
16314
|
config: this.config,
|
|
16318
|
-
confirmationScreen: this.confirmationScreen,
|
|
16319
16315
|
multiRollupApiClients: this.multiRollupApiClients,
|
|
16316
|
+
guardianClient: this.guardianClient,
|
|
16320
16317
|
});
|
|
16321
16318
|
}
|
|
16322
16319
|
/**
|