@imtbl/sdk 0.17.5 → 0.18.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 +1 -1
- package/dist/browser/checkout.js +2 -2
- package/dist/checkout_sdk.d.ts +8 -0
- package/dist/checkout_sdk.js +28 -8
- package/dist/checkout_widgets.d.ts +3 -3
- package/dist/checkout_widgets.js +17 -18
- package/dist/immutablex_client.js +1 -1
- package/dist/index.browser.js +9 -9
- package/dist/index.browser.js.map +1 -1
- package/dist/index.cjs +446 -55
- package/dist/index.d.ts +34 -3
- package/dist/index.js +447 -56
- package/dist/passport.d.ts +22 -1
- package/dist/passport.js +402 -30
- package/package.json +1 -1
package/dist/passport.d.ts
CHANGED
|
@@ -10546,6 +10546,27 @@ declare class JsonRpcError extends Error {
|
|
|
10546
10546
|
constructor(code: ProviderErrorCode | RpcErrorCode, message: string);
|
|
10547
10547
|
}
|
|
10548
10548
|
|
|
10549
|
+
interface TypedDataPayload {
|
|
10550
|
+
types: {
|
|
10551
|
+
EIP712Domain: Array<{
|
|
10552
|
+
name: string;
|
|
10553
|
+
type: string;
|
|
10554
|
+
}>;
|
|
10555
|
+
[key: string]: Array<{
|
|
10556
|
+
name: string;
|
|
10557
|
+
type: string;
|
|
10558
|
+
}>;
|
|
10559
|
+
};
|
|
10560
|
+
domain: {
|
|
10561
|
+
name?: string;
|
|
10562
|
+
version?: string;
|
|
10563
|
+
chainId?: number;
|
|
10564
|
+
verifyingContract?: string;
|
|
10565
|
+
salt?: string;
|
|
10566
|
+
};
|
|
10567
|
+
primaryType: string;
|
|
10568
|
+
message: Record<string, any>;
|
|
10569
|
+
}
|
|
10549
10570
|
interface RequestArguments {
|
|
10550
10571
|
method: string;
|
|
10551
10572
|
params?: Array<any>;
|
|
@@ -10613,4 +10634,4 @@ declare class Passport {
|
|
|
10613
10634
|
getLinkedAddresses(): Promise<string[]>;
|
|
10614
10635
|
}
|
|
10615
10636
|
|
|
10616
|
-
export { AccountsChangedEvent, DeviceConnectResponse, DeviceTokenResponse, JsonRpcError, JsonRpcRequestCallback, JsonRpcRequestPayload, JsonRpcResponsePayload, Networks, Passport, PassportError, PassportModuleConfiguration, PassportOverrides, Provider, ProviderErrorCode, ProviderEvent, RequestArguments, RpcErrorCode, UserProfile };
|
|
10637
|
+
export { AccountsChangedEvent, DeviceConnectResponse, DeviceTokenResponse, JsonRpcError, JsonRpcRequestCallback, JsonRpcRequestPayload, JsonRpcResponsePayload, Networks, Passport, PassportError, PassportModuleConfiguration, PassportOverrides, Provider, ProviderErrorCode, ProviderEvent, RequestArguments, RpcErrorCode, TypedDataPayload, UserProfile };
|
package/dist/passport.js
CHANGED
|
@@ -11,7 +11,7 @@ import * as encUtils from 'enc-utils';
|
|
|
11
11
|
import { Web3Provider, JsonRpcProvider } from '@ethersproject/providers';
|
|
12
12
|
import { EventEmitter } from 'events';
|
|
13
13
|
import { walletContracts } from '@0xsequence/abi';
|
|
14
|
-
import { encodeSignature } from '@0xsequence/config';
|
|
14
|
+
import { encodeSignature, decodeSignature } from '@0xsequence/config';
|
|
15
15
|
|
|
16
16
|
/* tslint:disable */
|
|
17
17
|
/* eslint-disable */
|
|
@@ -1709,7 +1709,7 @@ class MultiRollupApiClients {
|
|
|
1709
1709
|
}
|
|
1710
1710
|
|
|
1711
1711
|
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
1712
|
-
const defaultHeaders = { 'x-sdk-version': 'ts-immutable-sdk-0.
|
|
1712
|
+
const defaultHeaders = { 'x-sdk-version': 'ts-immutable-sdk-0.18.0' };
|
|
1713
1713
|
const createConfig = ({ basePath, headers, }) => {
|
|
1714
1714
|
if (!basePath.trim()) {
|
|
1715
1715
|
throw Error('basePath can not be empty');
|
|
@@ -1765,7 +1765,7 @@ const createImmutableXConfiguration = ({ basePath, chainID, coreContractAddress,
|
|
|
1765
1765
|
chainID,
|
|
1766
1766
|
coreContractAddress,
|
|
1767
1767
|
registrationContractAddress,
|
|
1768
|
-
sdkVersion: 'ts-immutable-sdk-0.
|
|
1768
|
+
sdkVersion: 'ts-immutable-sdk-0.18.0',
|
|
1769
1769
|
});
|
|
1770
1770
|
/**
|
|
1771
1771
|
* Sets `sdkVersion` at the time of build
|
|
@@ -5489,6 +5489,8 @@ var globalAxios = axios;
|
|
|
5489
5489
|
* https://openapi-generator.tech
|
|
5490
5490
|
* Do not edit the class manually.
|
|
5491
5491
|
*/
|
|
5492
|
+
// Some imports not used depending on template conditions
|
|
5493
|
+
// @ts-ignore
|
|
5492
5494
|
const BASE_PATH = "https://guardian.sandbox.imtbl.com".replace(/\/+$/, "");
|
|
5493
5495
|
/**
|
|
5494
5496
|
*
|
|
@@ -5516,10 +5518,10 @@ class BaseAPI {
|
|
|
5516
5518
|
*/
|
|
5517
5519
|
class RequiredError extends Error {
|
|
5518
5520
|
field;
|
|
5521
|
+
name = "RequiredError";
|
|
5519
5522
|
constructor(field, msg) {
|
|
5520
5523
|
super(msg);
|
|
5521
5524
|
this.field = field;
|
|
5522
|
-
this.name = "RequiredError";
|
|
5523
5525
|
}
|
|
5524
5526
|
}
|
|
5525
5527
|
|
|
@@ -5564,8 +5566,6 @@ const setBearerAuthToObject = async function (object, configuration) {
|
|
|
5564
5566
|
}
|
|
5565
5567
|
};
|
|
5566
5568
|
function setFlattenedQueryParams(urlSearchParams, parameter, key = "") {
|
|
5567
|
-
if (parameter == null)
|
|
5568
|
-
return;
|
|
5569
5569
|
if (typeof parameter === "object") {
|
|
5570
5570
|
if (Array.isArray(parameter)) {
|
|
5571
5571
|
parameter.forEach(item => setFlattenedQueryParams(urlSearchParams, item, key));
|
|
@@ -5623,6 +5623,208 @@ const createRequestFunction = function (axiosArgs, globalAxios, BASE_PATH, confi
|
|
|
5623
5623
|
};
|
|
5624
5624
|
};
|
|
5625
5625
|
|
|
5626
|
+
/* tslint:disable */
|
|
5627
|
+
/* eslint-disable */
|
|
5628
|
+
/**
|
|
5629
|
+
* Guardian
|
|
5630
|
+
* Guardian API
|
|
5631
|
+
*
|
|
5632
|
+
* The version of the OpenAPI document: 1.0.0
|
|
5633
|
+
* Contact: support@immutable.com
|
|
5634
|
+
*
|
|
5635
|
+
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
|
|
5636
|
+
* https://openapi-generator.tech
|
|
5637
|
+
* Do not edit the class manually.
|
|
5638
|
+
*/
|
|
5639
|
+
/**
|
|
5640
|
+
* MessagesApi - axios parameter creator
|
|
5641
|
+
* @export
|
|
5642
|
+
*/
|
|
5643
|
+
const MessagesApiAxiosParamCreator = function (configuration) {
|
|
5644
|
+
return {
|
|
5645
|
+
/**
|
|
5646
|
+
* Approve a pending evm message
|
|
5647
|
+
* @summary Approve a pending evm message
|
|
5648
|
+
* @param {string} messageID id for the message
|
|
5649
|
+
* @param {*} [options] Override http request option.
|
|
5650
|
+
* @throws {RequiredError}
|
|
5651
|
+
*/
|
|
5652
|
+
approvePendingMessage: async (messageID, options = {}) => {
|
|
5653
|
+
// verify required parameter 'messageID' is not null or undefined
|
|
5654
|
+
assertParamExists('approvePendingMessage', 'messageID', messageID);
|
|
5655
|
+
const localVarPath = `/guardian/v1/messages/{messageID}/approve`
|
|
5656
|
+
.replace(`{${"messageID"}}`, encodeURIComponent(String(messageID)));
|
|
5657
|
+
// use dummy base URL string because the URL constructor only accepts absolute URLs.
|
|
5658
|
+
const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);
|
|
5659
|
+
let baseOptions;
|
|
5660
|
+
if (configuration) {
|
|
5661
|
+
baseOptions = configuration.baseOptions;
|
|
5662
|
+
}
|
|
5663
|
+
const localVarRequestOptions = { method: 'POST', ...baseOptions, ...options };
|
|
5664
|
+
const localVarHeaderParameter = {};
|
|
5665
|
+
const localVarQueryParameter = {};
|
|
5666
|
+
// authentication BearerAuth required
|
|
5667
|
+
// http bearer authentication required
|
|
5668
|
+
await setBearerAuthToObject(localVarHeaderParameter, configuration);
|
|
5669
|
+
setSearchParams(localVarUrlObj, localVarQueryParameter);
|
|
5670
|
+
let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};
|
|
5671
|
+
localVarRequestOptions.headers = { ...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers };
|
|
5672
|
+
return {
|
|
5673
|
+
url: toPathString(localVarUrlObj),
|
|
5674
|
+
options: localVarRequestOptions,
|
|
5675
|
+
};
|
|
5676
|
+
},
|
|
5677
|
+
/**
|
|
5678
|
+
* Check if a given message is valid for EVM
|
|
5679
|
+
* @summary Evaluate an evm message to sign
|
|
5680
|
+
* @param {MessageEvaluationRequest} messageEvaluationRequest Specifies the kind of transaction
|
|
5681
|
+
* @param {*} [options] Override http request option.
|
|
5682
|
+
* @throws {RequiredError}
|
|
5683
|
+
*/
|
|
5684
|
+
evaluateMessage: async (messageEvaluationRequest, options = {}) => {
|
|
5685
|
+
// verify required parameter 'messageEvaluationRequest' is not null or undefined
|
|
5686
|
+
assertParamExists('evaluateMessage', 'messageEvaluationRequest', messageEvaluationRequest);
|
|
5687
|
+
const localVarPath = `/guardian/v1/messages/evaluate`;
|
|
5688
|
+
// use dummy base URL string because the URL constructor only accepts absolute URLs.
|
|
5689
|
+
const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);
|
|
5690
|
+
let baseOptions;
|
|
5691
|
+
if (configuration) {
|
|
5692
|
+
baseOptions = configuration.baseOptions;
|
|
5693
|
+
}
|
|
5694
|
+
const localVarRequestOptions = { method: 'POST', ...baseOptions, ...options };
|
|
5695
|
+
const localVarHeaderParameter = {};
|
|
5696
|
+
const localVarQueryParameter = {};
|
|
5697
|
+
// authentication BearerAuth required
|
|
5698
|
+
// http bearer authentication required
|
|
5699
|
+
await setBearerAuthToObject(localVarHeaderParameter, configuration);
|
|
5700
|
+
localVarHeaderParameter['Content-Type'] = 'application/json';
|
|
5701
|
+
setSearchParams(localVarUrlObj, localVarQueryParameter);
|
|
5702
|
+
let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};
|
|
5703
|
+
localVarRequestOptions.headers = { ...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers };
|
|
5704
|
+
localVarRequestOptions.data = serializeDataIfNeeded(messageEvaluationRequest, localVarRequestOptions, configuration);
|
|
5705
|
+
return {
|
|
5706
|
+
url: toPathString(localVarUrlObj),
|
|
5707
|
+
options: localVarRequestOptions,
|
|
5708
|
+
};
|
|
5709
|
+
},
|
|
5710
|
+
/**
|
|
5711
|
+
* Get an evm message by id
|
|
5712
|
+
* @summary Info for a specific evm message
|
|
5713
|
+
* @param {string} messageID The id of the evm message
|
|
5714
|
+
* @param {*} [options] Override http request option.
|
|
5715
|
+
* @throws {RequiredError}
|
|
5716
|
+
*/
|
|
5717
|
+
getMessageByID: async (messageID, options = {}) => {
|
|
5718
|
+
// verify required parameter 'messageID' is not null or undefined
|
|
5719
|
+
assertParamExists('getMessageByID', 'messageID', messageID);
|
|
5720
|
+
const localVarPath = `/guardian/v1/messages/{messageID}`
|
|
5721
|
+
.replace(`{${"messageID"}}`, encodeURIComponent(String(messageID)));
|
|
5722
|
+
// use dummy base URL string because the URL constructor only accepts absolute URLs.
|
|
5723
|
+
const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);
|
|
5724
|
+
let baseOptions;
|
|
5725
|
+
if (configuration) {
|
|
5726
|
+
baseOptions = configuration.baseOptions;
|
|
5727
|
+
}
|
|
5728
|
+
const localVarRequestOptions = { method: 'GET', ...baseOptions, ...options };
|
|
5729
|
+
const localVarHeaderParameter = {};
|
|
5730
|
+
const localVarQueryParameter = {};
|
|
5731
|
+
// authentication BearerAuth required
|
|
5732
|
+
// http bearer authentication required
|
|
5733
|
+
await setBearerAuthToObject(localVarHeaderParameter, configuration);
|
|
5734
|
+
setSearchParams(localVarUrlObj, localVarQueryParameter);
|
|
5735
|
+
let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};
|
|
5736
|
+
localVarRequestOptions.headers = { ...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers };
|
|
5737
|
+
return {
|
|
5738
|
+
url: toPathString(localVarUrlObj),
|
|
5739
|
+
options: localVarRequestOptions,
|
|
5740
|
+
};
|
|
5741
|
+
},
|
|
5742
|
+
};
|
|
5743
|
+
};
|
|
5744
|
+
/**
|
|
5745
|
+
* MessagesApi - functional programming interface
|
|
5746
|
+
* @export
|
|
5747
|
+
*/
|
|
5748
|
+
const MessagesApiFp = function (configuration) {
|
|
5749
|
+
const localVarAxiosParamCreator = MessagesApiAxiosParamCreator(configuration);
|
|
5750
|
+
return {
|
|
5751
|
+
/**
|
|
5752
|
+
* Approve a pending evm message
|
|
5753
|
+
* @summary Approve a pending evm message
|
|
5754
|
+
* @param {string} messageID id for the message
|
|
5755
|
+
* @param {*} [options] Override http request option.
|
|
5756
|
+
* @throws {RequiredError}
|
|
5757
|
+
*/
|
|
5758
|
+
async approvePendingMessage(messageID, options) {
|
|
5759
|
+
const localVarAxiosArgs = await localVarAxiosParamCreator.approvePendingMessage(messageID, options);
|
|
5760
|
+
return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration);
|
|
5761
|
+
},
|
|
5762
|
+
/**
|
|
5763
|
+
* Check if a given message is valid for EVM
|
|
5764
|
+
* @summary Evaluate an evm message to sign
|
|
5765
|
+
* @param {MessageEvaluationRequest} messageEvaluationRequest Specifies the kind of transaction
|
|
5766
|
+
* @param {*} [options] Override http request option.
|
|
5767
|
+
* @throws {RequiredError}
|
|
5768
|
+
*/
|
|
5769
|
+
async evaluateMessage(messageEvaluationRequest, options) {
|
|
5770
|
+
const localVarAxiosArgs = await localVarAxiosParamCreator.evaluateMessage(messageEvaluationRequest, options);
|
|
5771
|
+
return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration);
|
|
5772
|
+
},
|
|
5773
|
+
/**
|
|
5774
|
+
* Get an evm message by id
|
|
5775
|
+
* @summary Info for a specific evm message
|
|
5776
|
+
* @param {string} messageID The id of the evm message
|
|
5777
|
+
* @param {*} [options] Override http request option.
|
|
5778
|
+
* @throws {RequiredError}
|
|
5779
|
+
*/
|
|
5780
|
+
async getMessageByID(messageID, options) {
|
|
5781
|
+
const localVarAxiosArgs = await localVarAxiosParamCreator.getMessageByID(messageID, options);
|
|
5782
|
+
return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration);
|
|
5783
|
+
},
|
|
5784
|
+
};
|
|
5785
|
+
};
|
|
5786
|
+
/**
|
|
5787
|
+
* MessagesApi - object-oriented interface
|
|
5788
|
+
* @export
|
|
5789
|
+
* @class MessagesApi
|
|
5790
|
+
* @extends {BaseAPI}
|
|
5791
|
+
*/
|
|
5792
|
+
class MessagesApi extends BaseAPI {
|
|
5793
|
+
/**
|
|
5794
|
+
* Approve a pending evm message
|
|
5795
|
+
* @summary Approve a pending evm message
|
|
5796
|
+
* @param {MessagesApiApprovePendingMessageRequest} requestParameters Request parameters.
|
|
5797
|
+
* @param {*} [options] Override http request option.
|
|
5798
|
+
* @throws {RequiredError}
|
|
5799
|
+
* @memberof MessagesApi
|
|
5800
|
+
*/
|
|
5801
|
+
approvePendingMessage(requestParameters, options) {
|
|
5802
|
+
return MessagesApiFp(this.configuration).approvePendingMessage(requestParameters.messageID, options).then((request) => request(this.axios, this.basePath));
|
|
5803
|
+
}
|
|
5804
|
+
/**
|
|
5805
|
+
* Check if a given message is valid for EVM
|
|
5806
|
+
* @summary Evaluate an evm message to sign
|
|
5807
|
+
* @param {MessagesApiEvaluateMessageRequest} requestParameters Request parameters.
|
|
5808
|
+
* @param {*} [options] Override http request option.
|
|
5809
|
+
* @throws {RequiredError}
|
|
5810
|
+
* @memberof MessagesApi
|
|
5811
|
+
*/
|
|
5812
|
+
evaluateMessage(requestParameters, options) {
|
|
5813
|
+
return MessagesApiFp(this.configuration).evaluateMessage(requestParameters.messageEvaluationRequest, options).then((request) => request(this.axios, this.basePath));
|
|
5814
|
+
}
|
|
5815
|
+
/**
|
|
5816
|
+
* Get an evm message by id
|
|
5817
|
+
* @summary Info for a specific evm message
|
|
5818
|
+
* @param {MessagesApiGetMessageByIDRequest} requestParameters Request parameters.
|
|
5819
|
+
* @param {*} [options] Override http request option.
|
|
5820
|
+
* @throws {RequiredError}
|
|
5821
|
+
* @memberof MessagesApi
|
|
5822
|
+
*/
|
|
5823
|
+
getMessageByID(requestParameters, options) {
|
|
5824
|
+
return MessagesApiFp(this.configuration).getMessageByID(requestParameters.messageID, options).then((request) => request(this.axios, this.basePath));
|
|
5825
|
+
}
|
|
5826
|
+
}
|
|
5827
|
+
|
|
5626
5828
|
/* tslint:disable */
|
|
5627
5829
|
/* eslint-disable */
|
|
5628
5830
|
/**
|
|
@@ -5646,7 +5848,7 @@ const TransactionsApiAxiosParamCreator = function (configuration) {
|
|
|
5646
5848
|
* Approve a pending transaction
|
|
5647
5849
|
* @summary Approve a pending transaction given chain
|
|
5648
5850
|
* @param {string} payloadHash Hash for the payload
|
|
5649
|
-
* @param {TransactionApprovalRequest} transactionApprovalRequest request body for approving a pending
|
|
5851
|
+
* @param {TransactionApprovalRequest} transactionApprovalRequest request body for approving a pending transaction
|
|
5650
5852
|
* @param {*} [options] Override http request option.
|
|
5651
5853
|
* @throws {RequiredError}
|
|
5652
5854
|
*/
|
|
@@ -5771,7 +5973,7 @@ const TransactionsApiFp = function (configuration) {
|
|
|
5771
5973
|
* Approve a pending transaction
|
|
5772
5974
|
* @summary Approve a pending transaction given chain
|
|
5773
5975
|
* @param {string} payloadHash Hash for the payload
|
|
5774
|
-
* @param {TransactionApprovalRequest} transactionApprovalRequest request body for approving a pending
|
|
5976
|
+
* @param {TransactionApprovalRequest} transactionApprovalRequest request body for approving a pending transaction
|
|
5775
5977
|
* @param {*} [options] Override http request option.
|
|
5776
5978
|
* @throws {RequiredError}
|
|
5777
5979
|
*/
|
|
@@ -6528,18 +6730,18 @@ const transformGuardianTransactions = (txs) => {
|
|
|
6528
6730
|
};
|
|
6529
6731
|
class GuardianClient {
|
|
6530
6732
|
transactionAPI;
|
|
6733
|
+
messageAPI;
|
|
6531
6734
|
confirmationScreen;
|
|
6532
6735
|
// TODO: ID-977, make this rollup agnostic
|
|
6533
6736
|
imxEtherAddress;
|
|
6534
6737
|
crossSdkBridgeEnabled;
|
|
6535
6738
|
constructor({ accessToken, confirmationScreen, imxEtherAddress, config, }) {
|
|
6739
|
+
const guardianConfiguration = new Configuration({ accessToken, basePath: config.imxPublicApiDomain });
|
|
6536
6740
|
this.confirmationScreen = confirmationScreen;
|
|
6537
|
-
this.transactionAPI = new TransactionsApi(new Configuration(
|
|
6538
|
-
accessToken,
|
|
6539
|
-
basePath: config.imxPublicApiDomain,
|
|
6540
|
-
}));
|
|
6741
|
+
this.transactionAPI = new TransactionsApi(new Configuration(guardianConfiguration));
|
|
6541
6742
|
this.imxEtherAddress = imxEtherAddress;
|
|
6542
6743
|
this.crossSdkBridgeEnabled = config.crossSdkBridgeEnabled;
|
|
6744
|
+
this.messageAPI = new MessagesApi(guardianConfiguration);
|
|
6543
6745
|
}
|
|
6544
6746
|
/**
|
|
6545
6747
|
* Open confirmation screen and close it automatically if the
|
|
@@ -6638,6 +6840,31 @@ class GuardianClient {
|
|
|
6638
6840
|
this.confirmationScreen.closeWindow();
|
|
6639
6841
|
}
|
|
6640
6842
|
}
|
|
6843
|
+
async evaluateMessage({ chainID, payload, user }) {
|
|
6844
|
+
try {
|
|
6845
|
+
const messageEvalResponse = await this.messageAPI.evaluateMessage({ messageEvaluationRequest: { chainID, payload } }, { headers: { Authorization: `Bearer ${user.accessToken}` } });
|
|
6846
|
+
return messageEvalResponse.data;
|
|
6847
|
+
}
|
|
6848
|
+
catch (error) {
|
|
6849
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
6850
|
+
throw new JsonRpcError(RpcErrorCode.INTERNAL_ERROR, `Message failed to validate with error: ${errorMessage}`);
|
|
6851
|
+
}
|
|
6852
|
+
}
|
|
6853
|
+
async validateMessage({ chainID, payload, user }) {
|
|
6854
|
+
const { messageId, confirmationRequired } = await this.evaluateMessage({ chainID, payload, user });
|
|
6855
|
+
if (confirmationRequired && this.crossSdkBridgeEnabled) {
|
|
6856
|
+
throw new JsonRpcError(RpcErrorCode.TRANSACTION_REJECTED, transactionRejectedCrossSdkBridgeError);
|
|
6857
|
+
}
|
|
6858
|
+
if (confirmationRequired && !!messageId) {
|
|
6859
|
+
const confirmationResult = await this.confirmationScreen.requestMessageConfirmation(messageId);
|
|
6860
|
+
if (!confirmationResult.confirmed) {
|
|
6861
|
+
throw new JsonRpcError(RpcErrorCode.TRANSACTION_REJECTED, 'Signature rejected by user');
|
|
6862
|
+
}
|
|
6863
|
+
}
|
|
6864
|
+
else {
|
|
6865
|
+
this.confirmationScreen.closeWindow();
|
|
6866
|
+
}
|
|
6867
|
+
}
|
|
6641
6868
|
}
|
|
6642
6869
|
|
|
6643
6870
|
var PassportEvents;
|
|
@@ -7265,6 +7492,8 @@ var ReceiveMessage;
|
|
|
7265
7492
|
ReceiveMessage["CONFIRMATION_WINDOW_READY"] = "confirmation_window_ready";
|
|
7266
7493
|
ReceiveMessage["TRANSACTION_CONFIRMED"] = "transaction_confirmed";
|
|
7267
7494
|
ReceiveMessage["TRANSACTION_ERROR"] = "transaction_error";
|
|
7495
|
+
ReceiveMessage["MESSAGE_CONFIRMED"] = "message_confirmed";
|
|
7496
|
+
ReceiveMessage["MESSAGE_REJECTED"] = "message_rejected";
|
|
7268
7497
|
})(ReceiveMessage || (ReceiveMessage = {}));
|
|
7269
7498
|
const PASSPORT_EVENT_TYPE = 'imx_passport_confirmation';
|
|
7270
7499
|
|
|
@@ -7318,11 +7547,11 @@ class ConfirmationScreen {
|
|
|
7318
7547
|
reject(new Error('Unsupported message type'));
|
|
7319
7548
|
}
|
|
7320
7549
|
};
|
|
7321
|
-
window.addEventListener('message', messageHandler);
|
|
7322
7550
|
if (!this.confirmationWindow) {
|
|
7323
7551
|
resolve({ confirmed: false });
|
|
7324
7552
|
return;
|
|
7325
7553
|
}
|
|
7554
|
+
window.addEventListener('message', messageHandler);
|
|
7326
7555
|
let href = '';
|
|
7327
7556
|
if (chainType === TransactionApprovalRequestChainTypeEnum.Starkex) {
|
|
7328
7557
|
// eslint-disable-next-line max-len
|
|
@@ -7332,15 +7561,39 @@ class ConfirmationScreen {
|
|
|
7332
7561
|
// eslint-disable-next-line max-len
|
|
7333
7562
|
href = `${this.config.passportDomain}/transaction-confirmation/zkevm?transactionId=${transactionId}&imxEtherAddress=${imxEtherAddress}&chainType=evm&chainId=${chainId}`;
|
|
7334
7563
|
}
|
|
7335
|
-
this.
|
|
7336
|
-
|
|
7337
|
-
|
|
7338
|
-
|
|
7339
|
-
|
|
7340
|
-
|
|
7341
|
-
|
|
7564
|
+
this.showConfirmationScreen(href, messageHandler, resolve);
|
|
7565
|
+
});
|
|
7566
|
+
}
|
|
7567
|
+
requestMessageConfirmation(messageId) {
|
|
7568
|
+
return new Promise((resolve, reject) => {
|
|
7569
|
+
const messageHandler = ({ data, origin }) => {
|
|
7570
|
+
if (origin !== this.config.passportDomain
|
|
7571
|
+
|| data.eventType !== PASSPORT_EVENT_TYPE) {
|
|
7572
|
+
return;
|
|
7573
|
+
}
|
|
7574
|
+
switch (data.messageType) {
|
|
7575
|
+
case ReceiveMessage.CONFIRMATION_WINDOW_READY: {
|
|
7576
|
+
break;
|
|
7577
|
+
}
|
|
7578
|
+
case ReceiveMessage.MESSAGE_CONFIRMED: {
|
|
7579
|
+
resolve({ confirmed: true });
|
|
7580
|
+
break;
|
|
7581
|
+
}
|
|
7582
|
+
case ReceiveMessage.MESSAGE_REJECTED: {
|
|
7583
|
+
reject(new Error('Message rejected'));
|
|
7584
|
+
break;
|
|
7585
|
+
}
|
|
7586
|
+
default:
|
|
7587
|
+
reject(new Error('Unsupported message type'));
|
|
7342
7588
|
}
|
|
7343
|
-
}
|
|
7589
|
+
};
|
|
7590
|
+
if (!this.confirmationWindow) {
|
|
7591
|
+
resolve({ confirmed: false });
|
|
7592
|
+
return;
|
|
7593
|
+
}
|
|
7594
|
+
window.addEventListener('message', messageHandler);
|
|
7595
|
+
const href = `${this.config.passportDomain}/transaction-confirmation/zkevm/message?messageID=${messageId}`;
|
|
7596
|
+
this.showConfirmationScreen(href, messageHandler, resolve);
|
|
7344
7597
|
});
|
|
7345
7598
|
}
|
|
7346
7599
|
loading(popupOptions) {
|
|
@@ -7358,6 +7611,17 @@ class ConfirmationScreen {
|
|
|
7358
7611
|
closeWindow() {
|
|
7359
7612
|
this.confirmationWindow?.close();
|
|
7360
7613
|
}
|
|
7614
|
+
showConfirmationScreen(href, messageHandler, resolve) {
|
|
7615
|
+
this.confirmationWindow.location.href = href;
|
|
7616
|
+
// https://stackoverflow.com/questions/9388380/capture-the-close-event-of-popup-window-in-javascript/48240128#48240128
|
|
7617
|
+
const timer = setInterval(() => {
|
|
7618
|
+
if (this.confirmationWindow?.closed) {
|
|
7619
|
+
clearInterval(timer);
|
|
7620
|
+
window.removeEventListener('message', messageHandler);
|
|
7621
|
+
resolve({ confirmed: false });
|
|
7622
|
+
}
|
|
7623
|
+
}, CONFIRMATION_WINDOW_CLOSED_POLLING_DURATION);
|
|
7624
|
+
}
|
|
7361
7625
|
}
|
|
7362
7626
|
|
|
7363
7627
|
var RelayerTransactionStatus;
|
|
@@ -7386,13 +7650,9 @@ class TypedEventEmitter {
|
|
|
7386
7650
|
}
|
|
7387
7651
|
}
|
|
7388
7652
|
|
|
7389
|
-
|
|
7390
|
-
//
|
|
7391
|
-
//
|
|
7392
|
-
// Weight of a single signature in the multisig
|
|
7393
|
-
const SIGNATURE_WEIGHT = 1;
|
|
7394
|
-
// Total required weight in the multisig
|
|
7395
|
-
const SIGNATURE_THRESHOLD = 1;
|
|
7653
|
+
const SIGNATURE_WEIGHT = 1; // Weight of a single signature in the multi-sig
|
|
7654
|
+
const TRANSACTION_SIGNATURE_THRESHOLD = 1; // Total required weight in the multi-sig for a transaction
|
|
7655
|
+
const EIP712_SIGNATURE_THRESHOLD = 2; // Total required weight in the multi-sig for data signing
|
|
7396
7656
|
const ETH_SIGN_FLAG = '02';
|
|
7397
7657
|
const ETH_SIGN_PREFIX = '\x19\x01';
|
|
7398
7658
|
const META_TRANSACTIONS_TYPE = `tuple(
|
|
@@ -7425,11 +7685,12 @@ const getNonce = async (jsonRpcProvider, smartContractWalletAddress) => {
|
|
|
7425
7685
|
}
|
|
7426
7686
|
return 0;
|
|
7427
7687
|
};
|
|
7688
|
+
const encodeMessageSubDigest = (chainId, walletAddress, digest) => (ethers.utils.solidityPack(['string', 'uint256', 'address', 'bytes32'], [ETH_SIGN_PREFIX, chainId, walletAddress, digest]));
|
|
7428
7689
|
const getSignedMetaTransactions = async (metaTransactions, nonce, chainId, walletAddress, signer) => {
|
|
7429
7690
|
const normalisedMetaTransactions = getNormalisedTransactions(metaTransactions);
|
|
7430
7691
|
// Get the hash
|
|
7431
7692
|
const digest = digestOfTransactionsAndNonce(nonce, normalisedMetaTransactions);
|
|
7432
|
-
const completePayload =
|
|
7693
|
+
const completePayload = encodeMessageSubDigest(chainId, walletAddress, digest);
|
|
7433
7694
|
const hash = ethers.utils.keccak256(completePayload);
|
|
7434
7695
|
// Sign the digest
|
|
7435
7696
|
const hashArray = ethers.utils.arrayify(hash);
|
|
@@ -7437,7 +7698,7 @@ const getSignedMetaTransactions = async (metaTransactions, nonce, chainId, walle
|
|
|
7437
7698
|
const signedDigest = `${ethsigNoType}${ETH_SIGN_FLAG}`;
|
|
7438
7699
|
// Add metadata
|
|
7439
7700
|
const encodedSignature = encodeSignature({
|
|
7440
|
-
threshold:
|
|
7701
|
+
threshold: TRANSACTION_SIGNATURE_THRESHOLD,
|
|
7441
7702
|
signers: [
|
|
7442
7703
|
{
|
|
7443
7704
|
weight: SIGNATURE_WEIGHT,
|
|
@@ -7453,6 +7714,35 @@ const getSignedMetaTransactions = async (metaTransactions, nonce, chainId, walle
|
|
|
7453
7714
|
encodedSignature,
|
|
7454
7715
|
]);
|
|
7455
7716
|
};
|
|
7717
|
+
const decodeRelayerTypedDataSignature = (relayerSignature) => {
|
|
7718
|
+
const signatureWithThreshold = `0000${relayerSignature}`;
|
|
7719
|
+
return decodeSignature(signatureWithThreshold);
|
|
7720
|
+
};
|
|
7721
|
+
const getSignedTypedData = async (typedData, relayerSignature, chainId, walletAddress, signer) => {
|
|
7722
|
+
// Ethers auto-generates the EIP712Domain type in the TypedDataEncoder, and so it needs to be removed
|
|
7723
|
+
const types = { ...typedData.types };
|
|
7724
|
+
// @ts-ignore
|
|
7725
|
+
delete types.EIP712Domain;
|
|
7726
|
+
// eslint-disable-next-line no-underscore-dangle
|
|
7727
|
+
const digest = ethers.utils._TypedDataEncoder.hash(typedData.domain, types, typedData.message);
|
|
7728
|
+
const completePayload = encodeMessageSubDigest(chainId, walletAddress, digest);
|
|
7729
|
+
const hash = ethers.utils.keccak256(completePayload);
|
|
7730
|
+
// Sign the digest
|
|
7731
|
+
const hashArray = ethers.utils.arrayify(hash);
|
|
7732
|
+
const ethsigNoType = await signer.signMessage(hashArray);
|
|
7733
|
+
const signedDigest = `${ethsigNoType}${ETH_SIGN_FLAG}`;
|
|
7734
|
+
const { signers } = decodeRelayerTypedDataSignature(relayerSignature);
|
|
7735
|
+
return encodeSignature({
|
|
7736
|
+
threshold: EIP712_SIGNATURE_THRESHOLD,
|
|
7737
|
+
signers: [
|
|
7738
|
+
...signers,
|
|
7739
|
+
{
|
|
7740
|
+
weight: SIGNATURE_WEIGHT,
|
|
7741
|
+
signature: signedDigest,
|
|
7742
|
+
},
|
|
7743
|
+
],
|
|
7744
|
+
});
|
|
7745
|
+
};
|
|
7456
7746
|
const getEip155ChainId = (chainId) => `eip155:${chainId}`;
|
|
7457
7747
|
|
|
7458
7748
|
class RelayerClient {
|
|
@@ -7518,6 +7808,19 @@ class RelayerClient {
|
|
|
7518
7808
|
const { result } = await this.postToRelayer(payload);
|
|
7519
7809
|
return result;
|
|
7520
7810
|
}
|
|
7811
|
+
async imSignTypedData(address, eip712Payload) {
|
|
7812
|
+
const { chainId } = await this.jsonRpcProvider.ready;
|
|
7813
|
+
const payload = {
|
|
7814
|
+
method: 'im_signTypedData',
|
|
7815
|
+
params: [{
|
|
7816
|
+
address,
|
|
7817
|
+
eip712Payload,
|
|
7818
|
+
chainId: getEip155ChainId(chainId),
|
|
7819
|
+
}],
|
|
7820
|
+
};
|
|
7821
|
+
const { result } = await this.postToRelayer(payload);
|
|
7822
|
+
return result;
|
|
7823
|
+
}
|
|
7521
7824
|
}
|
|
7522
7825
|
|
|
7523
7826
|
const MESSAGE_TO_SIGN = 'Only sign this message from Immutable Passport';
|
|
@@ -7658,6 +7961,60 @@ const sendTransaction = ({ params, magicProvider, jsonRpcProvider, relayerClient
|
|
|
7658
7961
|
return relayerTransaction.hash;
|
|
7659
7962
|
});
|
|
7660
7963
|
|
|
7964
|
+
const REQUIRED_TYPED_DATA_PROPERTIES = ['types', 'domain', 'primaryType', 'message'];
|
|
7965
|
+
const isValidTypedDataPayload = (typedData) => (REQUIRED_TYPED_DATA_PROPERTIES.every((key) => key in typedData));
|
|
7966
|
+
const transformTypedData = (typedData, chainId) => {
|
|
7967
|
+
let transformedTypedData;
|
|
7968
|
+
if (typeof typedData === 'string') {
|
|
7969
|
+
try {
|
|
7970
|
+
transformedTypedData = JSON.parse(typedData);
|
|
7971
|
+
}
|
|
7972
|
+
catch (err) {
|
|
7973
|
+
throw new JsonRpcError(RpcErrorCode.INVALID_PARAMS, `Failed to parse typed data JSON: ${err}`);
|
|
7974
|
+
}
|
|
7975
|
+
}
|
|
7976
|
+
else if (typeof typedData === 'object') {
|
|
7977
|
+
transformedTypedData = typedData;
|
|
7978
|
+
}
|
|
7979
|
+
else {
|
|
7980
|
+
throw new JsonRpcError(RpcErrorCode.INVALID_PARAMS, `Invalid typed data argument: ${typedData}`);
|
|
7981
|
+
}
|
|
7982
|
+
if (!isValidTypedDataPayload(transformedTypedData)) {
|
|
7983
|
+
throw new JsonRpcError(RpcErrorCode.INVALID_PARAMS, `Invalid typed data argument. The following properties are required: ${REQUIRED_TYPED_DATA_PROPERTIES.join(', ')}`);
|
|
7984
|
+
}
|
|
7985
|
+
const providedChainId = transformedTypedData.domain?.chainId;
|
|
7986
|
+
if (providedChainId) {
|
|
7987
|
+
// domain.chainId (if defined) can be a number, string, or hex value, but the relayer & guardian only accept a number.
|
|
7988
|
+
if (typeof providedChainId === 'string') {
|
|
7989
|
+
if (providedChainId.startsWith('0x')) {
|
|
7990
|
+
transformedTypedData.domain.chainId = parseInt(providedChainId, 16);
|
|
7991
|
+
}
|
|
7992
|
+
else {
|
|
7993
|
+
transformedTypedData.domain.chainId = parseInt(providedChainId, 10);
|
|
7994
|
+
}
|
|
7995
|
+
}
|
|
7996
|
+
if (transformedTypedData.domain.chainId !== chainId) {
|
|
7997
|
+
throw new JsonRpcError(RpcErrorCode.INVALID_PARAMS, `Invalid chainId, expected ${chainId}`);
|
|
7998
|
+
}
|
|
7999
|
+
}
|
|
8000
|
+
return transformedTypedData;
|
|
8001
|
+
};
|
|
8002
|
+
const signTypedDataV4 = async ({ params, method, magicProvider, jsonRpcProvider, relayerClient, guardianClient, user, }) => guardianClient
|
|
8003
|
+
.withConfirmationScreen({ width: 480, height: 730 })(async () => {
|
|
8004
|
+
const fromAddress = params[0];
|
|
8005
|
+
const typedDataParam = params[1];
|
|
8006
|
+
if (!fromAddress || !typedDataParam) {
|
|
8007
|
+
throw new JsonRpcError(RpcErrorCode.INVALID_PARAMS, `${method} requires an address and a typed data JSON`);
|
|
8008
|
+
}
|
|
8009
|
+
const { chainId } = await jsonRpcProvider.ready;
|
|
8010
|
+
const typedData = transformTypedData(typedDataParam, chainId);
|
|
8011
|
+
await guardianClient.validateMessage({ chainID: String(chainId), payload: typedData, user });
|
|
8012
|
+
const relayerSignature = await relayerClient.imSignTypedData(fromAddress, typedData);
|
|
8013
|
+
const magicWeb3Provider = new Web3Provider(magicProvider);
|
|
8014
|
+
const signer = magicWeb3Provider.getSigner();
|
|
8015
|
+
return getSignedTypedData(typedData, relayerSignature, BigNumber.from(chainId), fromAddress, signer);
|
|
8016
|
+
});
|
|
8017
|
+
|
|
7661
8018
|
class ZkEvmProvider {
|
|
7662
8019
|
authManager;
|
|
7663
8020
|
config;
|
|
@@ -7741,6 +8098,21 @@ class ZkEvmProvider {
|
|
|
7741
8098
|
case 'eth_accounts': {
|
|
7742
8099
|
return this.isLoggedIn() ? [this.user.zkEvm.ethAddress] : [];
|
|
7743
8100
|
}
|
|
8101
|
+
case 'eth_signTypedData':
|
|
8102
|
+
case 'eth_signTypedData_v4': {
|
|
8103
|
+
if (!this.isLoggedIn()) {
|
|
8104
|
+
throw new JsonRpcError(ProviderErrorCode.UNAUTHORIZED, 'Unauthorised - call eth_requestAccounts first');
|
|
8105
|
+
}
|
|
8106
|
+
return signTypedDataV4({
|
|
8107
|
+
method: request.method,
|
|
8108
|
+
params: request.params || [],
|
|
8109
|
+
magicProvider: this.magicProvider,
|
|
8110
|
+
jsonRpcProvider: this.jsonRpcProvider,
|
|
8111
|
+
relayerClient: this.relayerClient,
|
|
8112
|
+
user: this.user,
|
|
8113
|
+
guardianClient: this.guardianClient,
|
|
8114
|
+
});
|
|
8115
|
+
}
|
|
7744
8116
|
// Pass through methods
|
|
7745
8117
|
case 'eth_gasPrice':
|
|
7746
8118
|
case 'eth_getBalance':
|
package/package.json
CHANGED