@openfort/openfort-js 0.8.18 → 0.8.19
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/index.cjs +220 -49
- package/dist/index.d.ts +1 -0
- package/dist/index.js +220 -49
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -3339,7 +3339,7 @@ class KeyPair extends signingKey.SigningKey {
|
|
|
3339
3339
|
}
|
|
3340
3340
|
}
|
|
3341
3341
|
|
|
3342
|
-
const VERSION = '0.8.
|
|
3342
|
+
const VERSION = '0.8.19';
|
|
3343
3343
|
|
|
3344
3344
|
var Event;
|
|
3345
3345
|
(function (Event) {
|
|
@@ -3350,6 +3350,8 @@ var Event;
|
|
|
3350
3350
|
Event["AUTHENTICATION_UPDATED"] = "authentication-updated";
|
|
3351
3351
|
Event["SIGN"] = "sign";
|
|
3352
3352
|
Event["SET_RECOVERY_METHOD"] = "set-recovery-method";
|
|
3353
|
+
Event["SWITCH_CHAIN"] = "switch-chain";
|
|
3354
|
+
Event["CHAIN_SWITCHED"] = "chain-switched";
|
|
3353
3355
|
Event["EXPORT"] = "export";
|
|
3354
3356
|
Event["SIGNED"] = "signed";
|
|
3355
3357
|
Event["LOGOUT"] = "logout";
|
|
@@ -3419,6 +3421,17 @@ class SignRequest {
|
|
|
3419
3421
|
this.requestConfiguration = requestConfiguration;
|
|
3420
3422
|
}
|
|
3421
3423
|
}
|
|
3424
|
+
class SwitchChainRequest {
|
|
3425
|
+
uuid;
|
|
3426
|
+
action = Event.SWITCH_CHAIN;
|
|
3427
|
+
chainId;
|
|
3428
|
+
requestConfiguration;
|
|
3429
|
+
constructor(uuid, chainId, requestConfiguration) {
|
|
3430
|
+
this.uuid = uuid;
|
|
3431
|
+
this.chainId = chainId;
|
|
3432
|
+
this.requestConfiguration = requestConfiguration;
|
|
3433
|
+
}
|
|
3434
|
+
}
|
|
3422
3435
|
class ExportPrivateKeyRequest {
|
|
3423
3436
|
uuid;
|
|
3424
3437
|
action = Event.EXPORT;
|
|
@@ -3489,6 +3502,27 @@ class ConfigureResponse {
|
|
|
3489
3502
|
this.version = null;
|
|
3490
3503
|
}
|
|
3491
3504
|
}
|
|
3505
|
+
class SwitchChainResponse {
|
|
3506
|
+
uuid;
|
|
3507
|
+
success;
|
|
3508
|
+
deviceID;
|
|
3509
|
+
address;
|
|
3510
|
+
chainId;
|
|
3511
|
+
accountType;
|
|
3512
|
+
ownerAddress;
|
|
3513
|
+
version;
|
|
3514
|
+
action = Event.CHAIN_SWITCHED;
|
|
3515
|
+
constructor(uuid, deviceID, accountType, chainId, address, ownerAddress) {
|
|
3516
|
+
this.success = true;
|
|
3517
|
+
this.deviceID = deviceID;
|
|
3518
|
+
this.uuid = uuid;
|
|
3519
|
+
this.accountType = accountType;
|
|
3520
|
+
this.chainId = chainId;
|
|
3521
|
+
this.address = address;
|
|
3522
|
+
this.ownerAddress = ownerAddress;
|
|
3523
|
+
this.version = null;
|
|
3524
|
+
}
|
|
3525
|
+
}
|
|
3492
3526
|
class UpdateAuthenticationResponse {
|
|
3493
3527
|
uuid;
|
|
3494
3528
|
success;
|
|
@@ -3659,6 +3693,7 @@ class IframeManager {
|
|
|
3659
3693
|
[Event.AUTHENTICATION_UPDATED]: UpdateAuthenticationResponse,
|
|
3660
3694
|
[Event.CURRENT_DEVICE]: GetCurrentDeviceResponse,
|
|
3661
3695
|
[Event.SIGNED]: SignResponse,
|
|
3696
|
+
[Event.CHAIN_SWITCHED]: SwitchChainResponse,
|
|
3662
3697
|
[Event.LOGGED_OUT]: LogoutResponse,
|
|
3663
3698
|
[Event.SET_RECOVERY_METHOD]: SetRecoveryMethodResponse,
|
|
3664
3699
|
[Event.EXPORT]: ExportPrivateKeyResponse,
|
|
@@ -3756,6 +3791,33 @@ class IframeManager {
|
|
|
3756
3791
|
sessionStorage.setItem('iframe-version', response.version ?? 'undefined');
|
|
3757
3792
|
return response.signature;
|
|
3758
3793
|
}
|
|
3794
|
+
async switchChain(iframeConfiguration, chainId) {
|
|
3795
|
+
await this.waitForIframeLoad();
|
|
3796
|
+
const uuid = this.generateShortUUID();
|
|
3797
|
+
const requestConfiguration = {
|
|
3798
|
+
thirdPartyProvider: iframeConfiguration.thirdPartyProvider ?? undefined,
|
|
3799
|
+
thirdPartyTokenType: iframeConfiguration.thirdPartyTokenType ?? undefined,
|
|
3800
|
+
token: iframeConfiguration.accessToken ?? undefined,
|
|
3801
|
+
publishableKey: this.sdkConfiguration.baseConfiguration.publishableKey,
|
|
3802
|
+
openfortURL: this.sdkConfiguration.backendUrl,
|
|
3803
|
+
};
|
|
3804
|
+
const request = new SwitchChainRequest(uuid, chainId, requestConfiguration);
|
|
3805
|
+
this.iframe?.contentWindow?.postMessage(request, '*');
|
|
3806
|
+
let response;
|
|
3807
|
+
try {
|
|
3808
|
+
response = await this.waitForResponse(uuid);
|
|
3809
|
+
}
|
|
3810
|
+
catch (e) {
|
|
3811
|
+
console.log('switchChain', e);
|
|
3812
|
+
if (e instanceof NotConfiguredError) {
|
|
3813
|
+
await this.configure(iframeConfiguration);
|
|
3814
|
+
return this.switchChain(iframeConfiguration, chainId);
|
|
3815
|
+
}
|
|
3816
|
+
throw e;
|
|
3817
|
+
}
|
|
3818
|
+
sessionStorage.setItem('iframe-version', response.version ?? 'undefined');
|
|
3819
|
+
return response;
|
|
3820
|
+
}
|
|
3759
3821
|
async export(iframeConfiguration) {
|
|
3760
3822
|
await this.waitForIframeLoad();
|
|
3761
3823
|
const uuid = this.generateShortUUID();
|
|
@@ -4004,6 +4066,30 @@ class Recovery {
|
|
|
4004
4066
|
}
|
|
4005
4067
|
}
|
|
4006
4068
|
|
|
4069
|
+
class Account {
|
|
4070
|
+
type;
|
|
4071
|
+
address;
|
|
4072
|
+
ownerAddress;
|
|
4073
|
+
chainId;
|
|
4074
|
+
constructor(type, address, chainId, ownerAddress) {
|
|
4075
|
+
this.type = type;
|
|
4076
|
+
this.address = address;
|
|
4077
|
+
this.chainId = chainId;
|
|
4078
|
+
this.ownerAddress = ownerAddress;
|
|
4079
|
+
}
|
|
4080
|
+
static fromStorage(storage) {
|
|
4081
|
+
const account = storage.get(StorageKeys.ACCOUNT);
|
|
4082
|
+
if (!account) {
|
|
4083
|
+
return null;
|
|
4084
|
+
}
|
|
4085
|
+
const accountObj = JSON.parse(account);
|
|
4086
|
+
return new Account(accountObj.type, accountObj.address, accountObj.chainId, accountObj.ownerAddress);
|
|
4087
|
+
}
|
|
4088
|
+
save(storage) {
|
|
4089
|
+
storage.save(StorageKeys.ACCOUNT, JSON.stringify(this));
|
|
4090
|
+
}
|
|
4091
|
+
}
|
|
4092
|
+
|
|
4007
4093
|
class EmbeddedSigner {
|
|
4008
4094
|
iframeManager;
|
|
4009
4095
|
iframeConfiguration;
|
|
@@ -4019,6 +4105,12 @@ class EmbeddedSigner {
|
|
|
4019
4105
|
async export() {
|
|
4020
4106
|
return await this.iframeManager.export(this.iframeConfiguration);
|
|
4021
4107
|
}
|
|
4108
|
+
async switchChain({ chainId }) {
|
|
4109
|
+
const deviceAccount = await this.iframeManager
|
|
4110
|
+
.switchChain(this.iframeConfiguration, chainId);
|
|
4111
|
+
new Account(deviceAccount.accountType, deviceAccount.address, deviceAccount.chainId, deviceAccount.ownerAddress).save(this.storage);
|
|
4112
|
+
SignerManager.storage.save(StorageKeys.SIGNER, JSON.stringify(deviceAccount));
|
|
4113
|
+
}
|
|
4022
4114
|
async setEmbeddedRecovery({ recoveryMethod, recoveryPassword, encryptionSession }) {
|
|
4023
4115
|
await this.iframeManager
|
|
4024
4116
|
.setEmbeddedRecovery(this.iframeConfiguration, recoveryMethod, recoveryPassword, encryptionSession);
|
|
@@ -4088,6 +4180,10 @@ class SessionSigner {
|
|
|
4088
4180
|
updateAuthentication() {
|
|
4089
4181
|
return Promise.resolve();
|
|
4090
4182
|
}
|
|
4183
|
+
// eslint-disable-next-line class-methods-use-this
|
|
4184
|
+
switchChain() {
|
|
4185
|
+
return Promise.resolve();
|
|
4186
|
+
}
|
|
4091
4187
|
async export() {
|
|
4092
4188
|
return this.sessionKey.getPrivateKey();
|
|
4093
4189
|
}
|
|
@@ -4097,30 +4193,6 @@ class SessionSigner {
|
|
|
4097
4193
|
}
|
|
4098
4194
|
}
|
|
4099
4195
|
|
|
4100
|
-
class Account {
|
|
4101
|
-
type;
|
|
4102
|
-
address;
|
|
4103
|
-
ownerAddress;
|
|
4104
|
-
chainId;
|
|
4105
|
-
constructor(type, address, chainId, ownerAddress) {
|
|
4106
|
-
this.type = type;
|
|
4107
|
-
this.address = address;
|
|
4108
|
-
this.chainId = chainId;
|
|
4109
|
-
this.ownerAddress = ownerAddress;
|
|
4110
|
-
}
|
|
4111
|
-
static fromStorage(storage) {
|
|
4112
|
-
const account = storage.get(StorageKeys.ACCOUNT);
|
|
4113
|
-
if (!account) {
|
|
4114
|
-
return null;
|
|
4115
|
-
}
|
|
4116
|
-
const accountObj = JSON.parse(account);
|
|
4117
|
-
return new Account(accountObj.type, accountObj.address, accountObj.chainId, accountObj.ownerAddress);
|
|
4118
|
-
}
|
|
4119
|
-
save(storage) {
|
|
4120
|
-
storage.save(StorageKeys.ACCOUNT, JSON.stringify(this));
|
|
4121
|
-
}
|
|
4122
|
-
}
|
|
4123
|
-
|
|
4124
4196
|
let iframeManagerSingleton = null;
|
|
4125
4197
|
class SignerManager {
|
|
4126
4198
|
static storage = new LocalStorage();
|
|
@@ -4880,6 +4952,7 @@ var BackendTransactionStatus;
|
|
|
4880
4952
|
var ProviderEvent;
|
|
4881
4953
|
(function (ProviderEvent) {
|
|
4882
4954
|
ProviderEvent["ACCOUNTS_CHANGED"] = "accountsChanged";
|
|
4955
|
+
ProviderEvent["ACCOUNTS_CONNECT"] = "connect";
|
|
4883
4956
|
})(ProviderEvent || (ProviderEvent = {}));
|
|
4884
4957
|
|
|
4885
4958
|
/**
|
|
@@ -4948,7 +5021,14 @@ const sendTransaction = async ({ params, signer, account, authentication, backen
|
|
|
4948
5021
|
const openfortTransaction = await buildOpenfortTransactions$4(params, backendClient, account, authentication, policyId);
|
|
4949
5022
|
let response;
|
|
4950
5023
|
if (openfortTransaction?.nextAction?.payload?.signableHash) {
|
|
4951
|
-
|
|
5024
|
+
let signature;
|
|
5025
|
+
// zkSyncSepolia and Sophon test need a different signature
|
|
5026
|
+
if ([300, 531050104].includes(account.chainId)) {
|
|
5027
|
+
signature = await signer.sign(openfortTransaction.nextAction.payload.signableHash, false, false);
|
|
5028
|
+
}
|
|
5029
|
+
else {
|
|
5030
|
+
signature = await signer.sign(openfortTransaction.nextAction.payload.signableHash);
|
|
5031
|
+
}
|
|
4952
5032
|
const openfortSignatureResponse = (await backendClient.transactionIntentsApi.signature({
|
|
4953
5033
|
id: openfortTransaction.id,
|
|
4954
5034
|
signatureRequest: { signature },
|
|
@@ -5476,12 +5556,9 @@ const chain$i = {
|
|
|
5476
5556
|
networkId: 11155111,
|
|
5477
5557
|
redFlags: [],
|
|
5478
5558
|
rpc: [
|
|
5479
|
-
'https://rpc.
|
|
5480
|
-
'https://rpc2.sepolia.org',
|
|
5481
|
-
'https://rpc-sepolia.rockx.com',
|
|
5559
|
+
'https://ethereum-sepolia-rpc.publicnode.com',
|
|
5482
5560
|
'https://rpc.sepolia.ethpandaops.io',
|
|
5483
5561
|
'https://sepolia.gateway.tenderly.co',
|
|
5484
|
-
'https://ethereum-sepolia.publicnode.com',
|
|
5485
5562
|
],
|
|
5486
5563
|
shortName: 'sep',
|
|
5487
5564
|
slug: 'sepolia',
|
|
@@ -6451,6 +6528,7 @@ const buildOpenfortTransactions$3 = async (params, backendApiClients, account, a
|
|
|
6451
6528
|
const formattedPermissions = param.permissions.map(formatPermissionRequest);
|
|
6452
6529
|
const whitelist = formattedPermissions.filter((p) => p.type === 'contract-call'
|
|
6453
6530
|
|| p.type === 'erc20-token-transfer').map((p) => p.data.address);
|
|
6531
|
+
const limit = formattedPermissions[0].policies.find((p) => p.type === 'usage-limit')?.data?.limit;
|
|
6454
6532
|
if (param.signer && param.signer.type === 'keys') {
|
|
6455
6533
|
throw new JsonRpcError(RpcErrorCode.INVALID_PARAMS, 'Failed to request permissions - missing session address');
|
|
6456
6534
|
}
|
|
@@ -6458,7 +6536,7 @@ const buildOpenfortTransactions$3 = async (params, backendApiClients, account, a
|
|
|
6458
6536
|
if (!sessionAddress) {
|
|
6459
6537
|
throw new JsonRpcError(RpcErrorCode.INVALID_PARAMS, 'Failed to request permissions - missing session address');
|
|
6460
6538
|
}
|
|
6461
|
-
const sessionRequest = formatSessionRequest$1(sessionAddress, account.chainId, now, expiry, policyId, false, whitelist, authentication.player);
|
|
6539
|
+
const sessionRequest = formatSessionRequest$1(sessionAddress, account.chainId, now, expiry, policyId, false, whitelist, authentication.player, limit);
|
|
6462
6540
|
const transactionResponse = await backendApiClients.sessionsApi.createSession({
|
|
6463
6541
|
createSessionRequest: sessionRequest,
|
|
6464
6542
|
}, {
|
|
@@ -6497,7 +6575,14 @@ const registerSession = async ({ params, signer, account, authentication, backen
|
|
|
6497
6575
|
const openfortTransaction = await buildOpenfortTransactions$3(params, backendClient, account, authentication, policyId);
|
|
6498
6576
|
let response;
|
|
6499
6577
|
if (openfortTransaction?.nextAction?.payload?.signableHash) {
|
|
6500
|
-
|
|
6578
|
+
let signature;
|
|
6579
|
+
// zkSyncSepolia and Sophon test need a different signature
|
|
6580
|
+
if ([300, 531050104].includes(account.chainId)) {
|
|
6581
|
+
signature = await signer.sign(openfortTransaction.nextAction.payload.signableHash, false, false);
|
|
6582
|
+
}
|
|
6583
|
+
else {
|
|
6584
|
+
signature = await signer.sign(openfortTransaction.nextAction.payload.signableHash);
|
|
6585
|
+
}
|
|
6501
6586
|
const openfortSignatureResponse = await backendClient.sessionsApi.signatureSession({
|
|
6502
6587
|
id: openfortTransaction.id,
|
|
6503
6588
|
signatureRequest: { signature },
|
|
@@ -6547,7 +6632,14 @@ const revokeSession = async ({ params, signer, account, authentication, backendC
|
|
|
6547
6632
|
const openfortTransaction = await buildOpenfortTransactions$2(params, backendClient, account, authentication, policyId);
|
|
6548
6633
|
let response;
|
|
6549
6634
|
if (openfortTransaction?.nextAction?.payload?.signableHash) {
|
|
6550
|
-
|
|
6635
|
+
let signature;
|
|
6636
|
+
// zkSyncSepolia and Sophon test need a different signature
|
|
6637
|
+
if ([300, 531050104].includes(account.chainId)) {
|
|
6638
|
+
signature = await signer.sign(openfortTransaction.nextAction.payload.signableHash, false, false);
|
|
6639
|
+
}
|
|
6640
|
+
else {
|
|
6641
|
+
signature = await signer.sign(openfortTransaction.nextAction.payload.signableHash);
|
|
6642
|
+
}
|
|
6551
6643
|
const openfortSignatureResponse = await backendClient.sessionsApi.signatureSession({
|
|
6552
6644
|
id: openfortTransaction.id,
|
|
6553
6645
|
signatureRequest: { signature },
|
|
@@ -6601,7 +6693,14 @@ const sendCalls = async ({ params, signer, account, authentication, backendClien
|
|
|
6601
6693
|
const openfortTransaction = await buildOpenfortTransactions$1(params[0].calls, backendClient, account, authentication, policy);
|
|
6602
6694
|
let response;
|
|
6603
6695
|
if (openfortTransaction?.nextAction?.payload?.signableHash) {
|
|
6604
|
-
|
|
6696
|
+
let signature;
|
|
6697
|
+
// zkSyncSepolia and Sophon test need a different signature
|
|
6698
|
+
if ([300, 531050104].includes(account.chainId)) {
|
|
6699
|
+
signature = await signer.sign(openfortTransaction.nextAction.payload.signableHash, false, false);
|
|
6700
|
+
}
|
|
6701
|
+
else {
|
|
6702
|
+
signature = await signer.sign(openfortTransaction.nextAction.payload.signableHash);
|
|
6703
|
+
}
|
|
6605
6704
|
const openfortSignatureResponse = (await backendClient.transactionIntentsApi.signature({
|
|
6606
6705
|
id: openfortTransaction.id,
|
|
6607
6706
|
signatureRequest: { signature },
|
|
@@ -6660,16 +6759,38 @@ const getCallStatus = async ({ params, authentication, backendClient, }) => {
|
|
|
6660
6759
|
};
|
|
6661
6760
|
};
|
|
6662
6761
|
|
|
6762
|
+
const personalSign = async ({ params, signer, account, }) => {
|
|
6763
|
+
const message = params[0];
|
|
6764
|
+
const fromAddress = params[1];
|
|
6765
|
+
if (!fromAddress || !message) {
|
|
6766
|
+
throw new JsonRpcError(RpcErrorCode.INVALID_PARAMS, 'personal_sign requires an address and a message');
|
|
6767
|
+
}
|
|
6768
|
+
if (fromAddress.toLowerCase() !== account.address.toLowerCase()) {
|
|
6769
|
+
throw new JsonRpcError(RpcErrorCode.INVALID_PARAMS, 'personal_sign requires the signer to be the from address');
|
|
6770
|
+
}
|
|
6771
|
+
const signature = await signer.sign(message, false, true);
|
|
6772
|
+
return signature;
|
|
6773
|
+
};
|
|
6774
|
+
|
|
6663
6775
|
class EvmProvider {
|
|
6664
6776
|
#storage;
|
|
6665
6777
|
#policyId;
|
|
6778
|
+
/**
|
|
6779
|
+
* Updates the policy ID for the provider
|
|
6780
|
+
* @param newPolicyId - The new policy ID to use
|
|
6781
|
+
*/
|
|
6782
|
+
updatePolicy(newPolicy) {
|
|
6783
|
+
this.#policyId = newPolicy;
|
|
6784
|
+
}
|
|
6785
|
+
#validateAndRefreshSession;
|
|
6666
6786
|
#eventEmitter;
|
|
6667
6787
|
#rpcProvider; // Used for read
|
|
6668
6788
|
#backendApiClients;
|
|
6669
6789
|
isOpenfort = true;
|
|
6670
|
-
constructor({ storage, backendApiClients, openfortEventEmitter, policyId, }) {
|
|
6790
|
+
constructor({ storage, backendApiClients, openfortEventEmitter, policyId, validateAndRefreshSession, }) {
|
|
6671
6791
|
this.#storage = storage;
|
|
6672
6792
|
this.#policyId = policyId;
|
|
6793
|
+
this.#validateAndRefreshSession = validateAndRefreshSession;
|
|
6673
6794
|
this.#backendApiClients = backendApiClients;
|
|
6674
6795
|
const account = Account.fromStorage(this.#storage);
|
|
6675
6796
|
const chainId = account?.chainId || 8453;
|
|
@@ -6699,6 +6820,7 @@ class EvmProvider {
|
|
|
6699
6820
|
case 'eth_requestAccounts': {
|
|
6700
6821
|
let account = Account.fromStorage(this.#storage);
|
|
6701
6822
|
if (account) {
|
|
6823
|
+
this.#eventEmitter.emit(ProviderEvent.ACCOUNTS_CONNECT, { chainId: bytes.hexlify(account.chainId) });
|
|
6702
6824
|
return [account.address];
|
|
6703
6825
|
}
|
|
6704
6826
|
const signer = SignerManager.fromStorage();
|
|
@@ -6720,6 +6842,8 @@ class EvmProvider {
|
|
|
6720
6842
|
if (!account || !signer || !authentication) {
|
|
6721
6843
|
throw new JsonRpcError(ProviderErrorCode.UNAUTHORIZED, 'Unauthorized - call eth_requestAccounts first');
|
|
6722
6844
|
}
|
|
6845
|
+
this.#validateAndRefreshSession();
|
|
6846
|
+
console.log(`eth_sendTransaction ${this.#policyId}`);
|
|
6723
6847
|
return await sendTransaction({
|
|
6724
6848
|
params: request.params || [],
|
|
6725
6849
|
signer,
|
|
@@ -6736,6 +6860,7 @@ class EvmProvider {
|
|
|
6736
6860
|
if (!account || !signer) {
|
|
6737
6861
|
throw new JsonRpcError(ProviderErrorCode.UNAUTHORIZED, 'Unauthorized - call eth_requestAccounts first');
|
|
6738
6862
|
}
|
|
6863
|
+
this.#validateAndRefreshSession();
|
|
6739
6864
|
return await signTypedDataV4({
|
|
6740
6865
|
method: request.method,
|
|
6741
6866
|
params: request.params || [],
|
|
@@ -6744,6 +6869,19 @@ class EvmProvider {
|
|
|
6744
6869
|
rpcProvider: this.#rpcProvider,
|
|
6745
6870
|
});
|
|
6746
6871
|
}
|
|
6872
|
+
case 'personal_sign': {
|
|
6873
|
+
const account = Account.fromStorage(this.#storage);
|
|
6874
|
+
const signer = SignerManager.fromStorage();
|
|
6875
|
+
if (!account || !signer) {
|
|
6876
|
+
throw new JsonRpcError(ProviderErrorCode.UNAUTHORIZED, 'Unauthorized - call eth_requestAccounts first');
|
|
6877
|
+
}
|
|
6878
|
+
this.#validateAndRefreshSession();
|
|
6879
|
+
return await personalSign({
|
|
6880
|
+
params: request.params || [],
|
|
6881
|
+
signer,
|
|
6882
|
+
account,
|
|
6883
|
+
});
|
|
6884
|
+
}
|
|
6747
6885
|
case 'eth_chainId': {
|
|
6748
6886
|
// Call detect network to fetch the chainId so to take advantage of
|
|
6749
6887
|
// the caching layer provided by StaticJsonRpcProvider.
|
|
@@ -6754,6 +6892,25 @@ class EvmProvider {
|
|
|
6754
6892
|
const { chainId } = await this.#rpcProvider.detectNetwork();
|
|
6755
6893
|
return bytes.hexlify(chainId);
|
|
6756
6894
|
}
|
|
6895
|
+
case 'wallet_switchEthereumChain': {
|
|
6896
|
+
const signer = SignerManager.fromStorage();
|
|
6897
|
+
if (!signer) {
|
|
6898
|
+
throw new JsonRpcError(ProviderErrorCode.UNAUTHORIZED, 'Unauthorized - must be authenticated and configured with a signer');
|
|
6899
|
+
}
|
|
6900
|
+
if (!request.params || !Array.isArray(request.params) || request.params.length === 0) {
|
|
6901
|
+
throw new JsonRpcError(RpcErrorCode.INVALID_PARAMS, 'Invalid parameters for wallet_switchEthereumChain');
|
|
6902
|
+
}
|
|
6903
|
+
this.#validateAndRefreshSession();
|
|
6904
|
+
try {
|
|
6905
|
+
const chainIdNumber = parseInt(request.params[0].chainId, 16);
|
|
6906
|
+
await signer.switchChain({ chainId: chainIdNumber });
|
|
6907
|
+
this.#rpcProvider = new providers.StaticJsonRpcProvider(chainMap[chainIdNumber].rpc[0]);
|
|
6908
|
+
}
|
|
6909
|
+
catch (error) {
|
|
6910
|
+
throw new JsonRpcError(RpcErrorCode.INTERNAL_ERROR, 'Failed to switch chain');
|
|
6911
|
+
}
|
|
6912
|
+
return null;
|
|
6913
|
+
}
|
|
6757
6914
|
case 'wallet_addEthereumChain': {
|
|
6758
6915
|
const signer = SignerManager.fromStorage();
|
|
6759
6916
|
if (!signer) {
|
|
@@ -6775,6 +6932,7 @@ class EvmProvider {
|
|
|
6775
6932
|
if (!account || !signer || !authentication) {
|
|
6776
6933
|
throw new JsonRpcError(ProviderErrorCode.UNAUTHORIZED, 'Unauthorized - call eth_requestAccounts first');
|
|
6777
6934
|
}
|
|
6935
|
+
this.#validateAndRefreshSession();
|
|
6778
6936
|
return await getCallStatus({
|
|
6779
6937
|
params: (request.params || {}),
|
|
6780
6938
|
authentication,
|
|
@@ -6789,6 +6947,7 @@ class EvmProvider {
|
|
|
6789
6947
|
if (!account || !signer || !authentication) {
|
|
6790
6948
|
throw new JsonRpcError(ProviderErrorCode.UNAUTHORIZED, 'Unauthorized - call eth_requestAccounts first');
|
|
6791
6949
|
}
|
|
6950
|
+
this.#validateAndRefreshSession();
|
|
6792
6951
|
return await sendCalls({
|
|
6793
6952
|
params: request.params || [],
|
|
6794
6953
|
signer,
|
|
@@ -6805,6 +6964,7 @@ class EvmProvider {
|
|
|
6805
6964
|
if (!account || !signer || !authentication) {
|
|
6806
6965
|
throw new JsonRpcError(ProviderErrorCode.UNAUTHORIZED, 'Unauthorized - call eth_requestAccounts first');
|
|
6807
6966
|
}
|
|
6967
|
+
this.#validateAndRefreshSession();
|
|
6808
6968
|
return await registerSession({
|
|
6809
6969
|
params: (request.params || []),
|
|
6810
6970
|
signer,
|
|
@@ -6822,6 +6982,7 @@ class EvmProvider {
|
|
|
6822
6982
|
if (!account || !signer || !authentication) {
|
|
6823
6983
|
throw new JsonRpcError(ProviderErrorCode.UNAUTHORIZED, 'Unauthorized - call eth_requestAccounts first');
|
|
6824
6984
|
}
|
|
6985
|
+
this.#validateAndRefreshSession();
|
|
6825
6986
|
return await revokeSession({
|
|
6826
6987
|
params: (request.params || {}),
|
|
6827
6988
|
signer,
|
|
@@ -6843,6 +7004,9 @@ class EvmProvider {
|
|
|
6843
7004
|
paymasterService: {
|
|
6844
7005
|
supported: true,
|
|
6845
7006
|
},
|
|
7007
|
+
atomicBatch: {
|
|
7008
|
+
supported: true,
|
|
7009
|
+
},
|
|
6846
7010
|
},
|
|
6847
7011
|
};
|
|
6848
7012
|
return capabilities;
|
|
@@ -6983,6 +7147,7 @@ function announceProvider(detail) {
|
|
|
6983
7147
|
|
|
6984
7148
|
class Openfort {
|
|
6985
7149
|
storage;
|
|
7150
|
+
provider = null;
|
|
6986
7151
|
constructor(sdkConfiguration) {
|
|
6987
7152
|
this.storage = new LocalStorage();
|
|
6988
7153
|
const configuration = new Configuration(sdkConfiguration.baseConfiguration.publishableKey, sdkConfiguration.overrides?.backendUrl || 'https://api.openfort.xyz', sdkConfiguration.shieldConfiguration?.shieldPublishableKey || '', sdkConfiguration.shieldConfiguration?.shieldEncryptionKey || '', sdkConfiguration.overrides?.shieldUrl || 'https://shield.openfort.xyz', sdkConfiguration.overrides?.iframeUrl || 'https://embedded.openfort.xyz', sdkConfiguration.shieldConfiguration?.debug || false);
|
|
@@ -7011,20 +7176,26 @@ class Openfort {
|
|
|
7011
7176
|
const authentication = Authentication.fromStorage(this.storage);
|
|
7012
7177
|
const signer = SignerManager.fromStorage();
|
|
7013
7178
|
const account = Account.fromStorage(this.storage);
|
|
7014
|
-
|
|
7015
|
-
|
|
7016
|
-
|
|
7017
|
-
|
|
7018
|
-
|
|
7019
|
-
|
|
7020
|
-
|
|
7021
|
-
|
|
7022
|
-
|
|
7023
|
-
|
|
7024
|
-
|
|
7025
|
-
|
|
7026
|
-
|
|
7027
|
-
|
|
7179
|
+
if (!this.provider) {
|
|
7180
|
+
this.provider = new EvmProvider({
|
|
7181
|
+
storage: this.storage,
|
|
7182
|
+
openfortEventEmitter: new TypedEventEmitter(),
|
|
7183
|
+
signer: signer || undefined,
|
|
7184
|
+
account: account || undefined,
|
|
7185
|
+
authentication: authentication || undefined,
|
|
7186
|
+
backendApiClients: this.backendApiClients,
|
|
7187
|
+
policyId: options.policy,
|
|
7188
|
+
validateAndRefreshSession: this.validateAndRefreshToken.bind(this),
|
|
7189
|
+
});
|
|
7190
|
+
announceProvider({
|
|
7191
|
+
info: { ...openfortProviderInfo, ...options.providerInfo },
|
|
7192
|
+
provider: this.provider,
|
|
7193
|
+
});
|
|
7194
|
+
}
|
|
7195
|
+
else if (this.provider && options.policy) {
|
|
7196
|
+
this.provider.updatePolicy(options.policy);
|
|
7197
|
+
}
|
|
7198
|
+
return this.provider;
|
|
7028
7199
|
}
|
|
7029
7200
|
/**
|
|
7030
7201
|
* Configures a session key and returns the session key details.
|
package/dist/index.d.ts
CHANGED
package/dist/index.js
CHANGED
|
@@ -3316,7 +3316,7 @@ class KeyPair extends SigningKey {
|
|
|
3316
3316
|
}
|
|
3317
3317
|
}
|
|
3318
3318
|
|
|
3319
|
-
const VERSION = '0.8.
|
|
3319
|
+
const VERSION = '0.8.19';
|
|
3320
3320
|
|
|
3321
3321
|
var Event;
|
|
3322
3322
|
(function (Event) {
|
|
@@ -3327,6 +3327,8 @@ var Event;
|
|
|
3327
3327
|
Event["AUTHENTICATION_UPDATED"] = "authentication-updated";
|
|
3328
3328
|
Event["SIGN"] = "sign";
|
|
3329
3329
|
Event["SET_RECOVERY_METHOD"] = "set-recovery-method";
|
|
3330
|
+
Event["SWITCH_CHAIN"] = "switch-chain";
|
|
3331
|
+
Event["CHAIN_SWITCHED"] = "chain-switched";
|
|
3330
3332
|
Event["EXPORT"] = "export";
|
|
3331
3333
|
Event["SIGNED"] = "signed";
|
|
3332
3334
|
Event["LOGOUT"] = "logout";
|
|
@@ -3396,6 +3398,17 @@ class SignRequest {
|
|
|
3396
3398
|
this.requestConfiguration = requestConfiguration;
|
|
3397
3399
|
}
|
|
3398
3400
|
}
|
|
3401
|
+
class SwitchChainRequest {
|
|
3402
|
+
uuid;
|
|
3403
|
+
action = Event.SWITCH_CHAIN;
|
|
3404
|
+
chainId;
|
|
3405
|
+
requestConfiguration;
|
|
3406
|
+
constructor(uuid, chainId, requestConfiguration) {
|
|
3407
|
+
this.uuid = uuid;
|
|
3408
|
+
this.chainId = chainId;
|
|
3409
|
+
this.requestConfiguration = requestConfiguration;
|
|
3410
|
+
}
|
|
3411
|
+
}
|
|
3399
3412
|
class ExportPrivateKeyRequest {
|
|
3400
3413
|
uuid;
|
|
3401
3414
|
action = Event.EXPORT;
|
|
@@ -3466,6 +3479,27 @@ class ConfigureResponse {
|
|
|
3466
3479
|
this.version = null;
|
|
3467
3480
|
}
|
|
3468
3481
|
}
|
|
3482
|
+
class SwitchChainResponse {
|
|
3483
|
+
uuid;
|
|
3484
|
+
success;
|
|
3485
|
+
deviceID;
|
|
3486
|
+
address;
|
|
3487
|
+
chainId;
|
|
3488
|
+
accountType;
|
|
3489
|
+
ownerAddress;
|
|
3490
|
+
version;
|
|
3491
|
+
action = Event.CHAIN_SWITCHED;
|
|
3492
|
+
constructor(uuid, deviceID, accountType, chainId, address, ownerAddress) {
|
|
3493
|
+
this.success = true;
|
|
3494
|
+
this.deviceID = deviceID;
|
|
3495
|
+
this.uuid = uuid;
|
|
3496
|
+
this.accountType = accountType;
|
|
3497
|
+
this.chainId = chainId;
|
|
3498
|
+
this.address = address;
|
|
3499
|
+
this.ownerAddress = ownerAddress;
|
|
3500
|
+
this.version = null;
|
|
3501
|
+
}
|
|
3502
|
+
}
|
|
3469
3503
|
class UpdateAuthenticationResponse {
|
|
3470
3504
|
uuid;
|
|
3471
3505
|
success;
|
|
@@ -3636,6 +3670,7 @@ class IframeManager {
|
|
|
3636
3670
|
[Event.AUTHENTICATION_UPDATED]: UpdateAuthenticationResponse,
|
|
3637
3671
|
[Event.CURRENT_DEVICE]: GetCurrentDeviceResponse,
|
|
3638
3672
|
[Event.SIGNED]: SignResponse,
|
|
3673
|
+
[Event.CHAIN_SWITCHED]: SwitchChainResponse,
|
|
3639
3674
|
[Event.LOGGED_OUT]: LogoutResponse,
|
|
3640
3675
|
[Event.SET_RECOVERY_METHOD]: SetRecoveryMethodResponse,
|
|
3641
3676
|
[Event.EXPORT]: ExportPrivateKeyResponse,
|
|
@@ -3733,6 +3768,33 @@ class IframeManager {
|
|
|
3733
3768
|
sessionStorage.setItem('iframe-version', response.version ?? 'undefined');
|
|
3734
3769
|
return response.signature;
|
|
3735
3770
|
}
|
|
3771
|
+
async switchChain(iframeConfiguration, chainId) {
|
|
3772
|
+
await this.waitForIframeLoad();
|
|
3773
|
+
const uuid = this.generateShortUUID();
|
|
3774
|
+
const requestConfiguration = {
|
|
3775
|
+
thirdPartyProvider: iframeConfiguration.thirdPartyProvider ?? undefined,
|
|
3776
|
+
thirdPartyTokenType: iframeConfiguration.thirdPartyTokenType ?? undefined,
|
|
3777
|
+
token: iframeConfiguration.accessToken ?? undefined,
|
|
3778
|
+
publishableKey: this.sdkConfiguration.baseConfiguration.publishableKey,
|
|
3779
|
+
openfortURL: this.sdkConfiguration.backendUrl,
|
|
3780
|
+
};
|
|
3781
|
+
const request = new SwitchChainRequest(uuid, chainId, requestConfiguration);
|
|
3782
|
+
this.iframe?.contentWindow?.postMessage(request, '*');
|
|
3783
|
+
let response;
|
|
3784
|
+
try {
|
|
3785
|
+
response = await this.waitForResponse(uuid);
|
|
3786
|
+
}
|
|
3787
|
+
catch (e) {
|
|
3788
|
+
console.log('switchChain', e);
|
|
3789
|
+
if (e instanceof NotConfiguredError) {
|
|
3790
|
+
await this.configure(iframeConfiguration);
|
|
3791
|
+
return this.switchChain(iframeConfiguration, chainId);
|
|
3792
|
+
}
|
|
3793
|
+
throw e;
|
|
3794
|
+
}
|
|
3795
|
+
sessionStorage.setItem('iframe-version', response.version ?? 'undefined');
|
|
3796
|
+
return response;
|
|
3797
|
+
}
|
|
3736
3798
|
async export(iframeConfiguration) {
|
|
3737
3799
|
await this.waitForIframeLoad();
|
|
3738
3800
|
const uuid = this.generateShortUUID();
|
|
@@ -3981,6 +4043,30 @@ class Recovery {
|
|
|
3981
4043
|
}
|
|
3982
4044
|
}
|
|
3983
4045
|
|
|
4046
|
+
class Account {
|
|
4047
|
+
type;
|
|
4048
|
+
address;
|
|
4049
|
+
ownerAddress;
|
|
4050
|
+
chainId;
|
|
4051
|
+
constructor(type, address, chainId, ownerAddress) {
|
|
4052
|
+
this.type = type;
|
|
4053
|
+
this.address = address;
|
|
4054
|
+
this.chainId = chainId;
|
|
4055
|
+
this.ownerAddress = ownerAddress;
|
|
4056
|
+
}
|
|
4057
|
+
static fromStorage(storage) {
|
|
4058
|
+
const account = storage.get(StorageKeys.ACCOUNT);
|
|
4059
|
+
if (!account) {
|
|
4060
|
+
return null;
|
|
4061
|
+
}
|
|
4062
|
+
const accountObj = JSON.parse(account);
|
|
4063
|
+
return new Account(accountObj.type, accountObj.address, accountObj.chainId, accountObj.ownerAddress);
|
|
4064
|
+
}
|
|
4065
|
+
save(storage) {
|
|
4066
|
+
storage.save(StorageKeys.ACCOUNT, JSON.stringify(this));
|
|
4067
|
+
}
|
|
4068
|
+
}
|
|
4069
|
+
|
|
3984
4070
|
class EmbeddedSigner {
|
|
3985
4071
|
iframeManager;
|
|
3986
4072
|
iframeConfiguration;
|
|
@@ -3996,6 +4082,12 @@ class EmbeddedSigner {
|
|
|
3996
4082
|
async export() {
|
|
3997
4083
|
return await this.iframeManager.export(this.iframeConfiguration);
|
|
3998
4084
|
}
|
|
4085
|
+
async switchChain({ chainId }) {
|
|
4086
|
+
const deviceAccount = await this.iframeManager
|
|
4087
|
+
.switchChain(this.iframeConfiguration, chainId);
|
|
4088
|
+
new Account(deviceAccount.accountType, deviceAccount.address, deviceAccount.chainId, deviceAccount.ownerAddress).save(this.storage);
|
|
4089
|
+
SignerManager.storage.save(StorageKeys.SIGNER, JSON.stringify(deviceAccount));
|
|
4090
|
+
}
|
|
3999
4091
|
async setEmbeddedRecovery({ recoveryMethod, recoveryPassword, encryptionSession }) {
|
|
4000
4092
|
await this.iframeManager
|
|
4001
4093
|
.setEmbeddedRecovery(this.iframeConfiguration, recoveryMethod, recoveryPassword, encryptionSession);
|
|
@@ -4065,6 +4157,10 @@ class SessionSigner {
|
|
|
4065
4157
|
updateAuthentication() {
|
|
4066
4158
|
return Promise.resolve();
|
|
4067
4159
|
}
|
|
4160
|
+
// eslint-disable-next-line class-methods-use-this
|
|
4161
|
+
switchChain() {
|
|
4162
|
+
return Promise.resolve();
|
|
4163
|
+
}
|
|
4068
4164
|
async export() {
|
|
4069
4165
|
return this.sessionKey.getPrivateKey();
|
|
4070
4166
|
}
|
|
@@ -4074,30 +4170,6 @@ class SessionSigner {
|
|
|
4074
4170
|
}
|
|
4075
4171
|
}
|
|
4076
4172
|
|
|
4077
|
-
class Account {
|
|
4078
|
-
type;
|
|
4079
|
-
address;
|
|
4080
|
-
ownerAddress;
|
|
4081
|
-
chainId;
|
|
4082
|
-
constructor(type, address, chainId, ownerAddress) {
|
|
4083
|
-
this.type = type;
|
|
4084
|
-
this.address = address;
|
|
4085
|
-
this.chainId = chainId;
|
|
4086
|
-
this.ownerAddress = ownerAddress;
|
|
4087
|
-
}
|
|
4088
|
-
static fromStorage(storage) {
|
|
4089
|
-
const account = storage.get(StorageKeys.ACCOUNT);
|
|
4090
|
-
if (!account) {
|
|
4091
|
-
return null;
|
|
4092
|
-
}
|
|
4093
|
-
const accountObj = JSON.parse(account);
|
|
4094
|
-
return new Account(accountObj.type, accountObj.address, accountObj.chainId, accountObj.ownerAddress);
|
|
4095
|
-
}
|
|
4096
|
-
save(storage) {
|
|
4097
|
-
storage.save(StorageKeys.ACCOUNT, JSON.stringify(this));
|
|
4098
|
-
}
|
|
4099
|
-
}
|
|
4100
|
-
|
|
4101
4173
|
let iframeManagerSingleton = null;
|
|
4102
4174
|
class SignerManager {
|
|
4103
4175
|
static storage = new LocalStorage();
|
|
@@ -4857,6 +4929,7 @@ var BackendTransactionStatus;
|
|
|
4857
4929
|
var ProviderEvent;
|
|
4858
4930
|
(function (ProviderEvent) {
|
|
4859
4931
|
ProviderEvent["ACCOUNTS_CHANGED"] = "accountsChanged";
|
|
4932
|
+
ProviderEvent["ACCOUNTS_CONNECT"] = "connect";
|
|
4860
4933
|
})(ProviderEvent || (ProviderEvent = {}));
|
|
4861
4934
|
|
|
4862
4935
|
/**
|
|
@@ -4925,7 +4998,14 @@ const sendTransaction = async ({ params, signer, account, authentication, backen
|
|
|
4925
4998
|
const openfortTransaction = await buildOpenfortTransactions$4(params, backendClient, account, authentication, policyId);
|
|
4926
4999
|
let response;
|
|
4927
5000
|
if (openfortTransaction?.nextAction?.payload?.signableHash) {
|
|
4928
|
-
|
|
5001
|
+
let signature;
|
|
5002
|
+
// zkSyncSepolia and Sophon test need a different signature
|
|
5003
|
+
if ([300, 531050104].includes(account.chainId)) {
|
|
5004
|
+
signature = await signer.sign(openfortTransaction.nextAction.payload.signableHash, false, false);
|
|
5005
|
+
}
|
|
5006
|
+
else {
|
|
5007
|
+
signature = await signer.sign(openfortTransaction.nextAction.payload.signableHash);
|
|
5008
|
+
}
|
|
4929
5009
|
const openfortSignatureResponse = (await backendClient.transactionIntentsApi.signature({
|
|
4930
5010
|
id: openfortTransaction.id,
|
|
4931
5011
|
signatureRequest: { signature },
|
|
@@ -5453,12 +5533,9 @@ const chain$i = {
|
|
|
5453
5533
|
networkId: 11155111,
|
|
5454
5534
|
redFlags: [],
|
|
5455
5535
|
rpc: [
|
|
5456
|
-
'https://rpc.
|
|
5457
|
-
'https://rpc2.sepolia.org',
|
|
5458
|
-
'https://rpc-sepolia.rockx.com',
|
|
5536
|
+
'https://ethereum-sepolia-rpc.publicnode.com',
|
|
5459
5537
|
'https://rpc.sepolia.ethpandaops.io',
|
|
5460
5538
|
'https://sepolia.gateway.tenderly.co',
|
|
5461
|
-
'https://ethereum-sepolia.publicnode.com',
|
|
5462
5539
|
],
|
|
5463
5540
|
shortName: 'sep',
|
|
5464
5541
|
slug: 'sepolia',
|
|
@@ -6428,6 +6505,7 @@ const buildOpenfortTransactions$3 = async (params, backendApiClients, account, a
|
|
|
6428
6505
|
const formattedPermissions = param.permissions.map(formatPermissionRequest);
|
|
6429
6506
|
const whitelist = formattedPermissions.filter((p) => p.type === 'contract-call'
|
|
6430
6507
|
|| p.type === 'erc20-token-transfer').map((p) => p.data.address);
|
|
6508
|
+
const limit = formattedPermissions[0].policies.find((p) => p.type === 'usage-limit')?.data?.limit;
|
|
6431
6509
|
if (param.signer && param.signer.type === 'keys') {
|
|
6432
6510
|
throw new JsonRpcError(RpcErrorCode.INVALID_PARAMS, 'Failed to request permissions - missing session address');
|
|
6433
6511
|
}
|
|
@@ -6435,7 +6513,7 @@ const buildOpenfortTransactions$3 = async (params, backendApiClients, account, a
|
|
|
6435
6513
|
if (!sessionAddress) {
|
|
6436
6514
|
throw new JsonRpcError(RpcErrorCode.INVALID_PARAMS, 'Failed to request permissions - missing session address');
|
|
6437
6515
|
}
|
|
6438
|
-
const sessionRequest = formatSessionRequest$1(sessionAddress, account.chainId, now, expiry, policyId, false, whitelist, authentication.player);
|
|
6516
|
+
const sessionRequest = formatSessionRequest$1(sessionAddress, account.chainId, now, expiry, policyId, false, whitelist, authentication.player, limit);
|
|
6439
6517
|
const transactionResponse = await backendApiClients.sessionsApi.createSession({
|
|
6440
6518
|
createSessionRequest: sessionRequest,
|
|
6441
6519
|
}, {
|
|
@@ -6474,7 +6552,14 @@ const registerSession = async ({ params, signer, account, authentication, backen
|
|
|
6474
6552
|
const openfortTransaction = await buildOpenfortTransactions$3(params, backendClient, account, authentication, policyId);
|
|
6475
6553
|
let response;
|
|
6476
6554
|
if (openfortTransaction?.nextAction?.payload?.signableHash) {
|
|
6477
|
-
|
|
6555
|
+
let signature;
|
|
6556
|
+
// zkSyncSepolia and Sophon test need a different signature
|
|
6557
|
+
if ([300, 531050104].includes(account.chainId)) {
|
|
6558
|
+
signature = await signer.sign(openfortTransaction.nextAction.payload.signableHash, false, false);
|
|
6559
|
+
}
|
|
6560
|
+
else {
|
|
6561
|
+
signature = await signer.sign(openfortTransaction.nextAction.payload.signableHash);
|
|
6562
|
+
}
|
|
6478
6563
|
const openfortSignatureResponse = await backendClient.sessionsApi.signatureSession({
|
|
6479
6564
|
id: openfortTransaction.id,
|
|
6480
6565
|
signatureRequest: { signature },
|
|
@@ -6524,7 +6609,14 @@ const revokeSession = async ({ params, signer, account, authentication, backendC
|
|
|
6524
6609
|
const openfortTransaction = await buildOpenfortTransactions$2(params, backendClient, account, authentication, policyId);
|
|
6525
6610
|
let response;
|
|
6526
6611
|
if (openfortTransaction?.nextAction?.payload?.signableHash) {
|
|
6527
|
-
|
|
6612
|
+
let signature;
|
|
6613
|
+
// zkSyncSepolia and Sophon test need a different signature
|
|
6614
|
+
if ([300, 531050104].includes(account.chainId)) {
|
|
6615
|
+
signature = await signer.sign(openfortTransaction.nextAction.payload.signableHash, false, false);
|
|
6616
|
+
}
|
|
6617
|
+
else {
|
|
6618
|
+
signature = await signer.sign(openfortTransaction.nextAction.payload.signableHash);
|
|
6619
|
+
}
|
|
6528
6620
|
const openfortSignatureResponse = await backendClient.sessionsApi.signatureSession({
|
|
6529
6621
|
id: openfortTransaction.id,
|
|
6530
6622
|
signatureRequest: { signature },
|
|
@@ -6578,7 +6670,14 @@ const sendCalls = async ({ params, signer, account, authentication, backendClien
|
|
|
6578
6670
|
const openfortTransaction = await buildOpenfortTransactions$1(params[0].calls, backendClient, account, authentication, policy);
|
|
6579
6671
|
let response;
|
|
6580
6672
|
if (openfortTransaction?.nextAction?.payload?.signableHash) {
|
|
6581
|
-
|
|
6673
|
+
let signature;
|
|
6674
|
+
// zkSyncSepolia and Sophon test need a different signature
|
|
6675
|
+
if ([300, 531050104].includes(account.chainId)) {
|
|
6676
|
+
signature = await signer.sign(openfortTransaction.nextAction.payload.signableHash, false, false);
|
|
6677
|
+
}
|
|
6678
|
+
else {
|
|
6679
|
+
signature = await signer.sign(openfortTransaction.nextAction.payload.signableHash);
|
|
6680
|
+
}
|
|
6582
6681
|
const openfortSignatureResponse = (await backendClient.transactionIntentsApi.signature({
|
|
6583
6682
|
id: openfortTransaction.id,
|
|
6584
6683
|
signatureRequest: { signature },
|
|
@@ -6637,16 +6736,38 @@ const getCallStatus = async ({ params, authentication, backendClient, }) => {
|
|
|
6637
6736
|
};
|
|
6638
6737
|
};
|
|
6639
6738
|
|
|
6739
|
+
const personalSign = async ({ params, signer, account, }) => {
|
|
6740
|
+
const message = params[0];
|
|
6741
|
+
const fromAddress = params[1];
|
|
6742
|
+
if (!fromAddress || !message) {
|
|
6743
|
+
throw new JsonRpcError(RpcErrorCode.INVALID_PARAMS, 'personal_sign requires an address and a message');
|
|
6744
|
+
}
|
|
6745
|
+
if (fromAddress.toLowerCase() !== account.address.toLowerCase()) {
|
|
6746
|
+
throw new JsonRpcError(RpcErrorCode.INVALID_PARAMS, 'personal_sign requires the signer to be the from address');
|
|
6747
|
+
}
|
|
6748
|
+
const signature = await signer.sign(message, false, true);
|
|
6749
|
+
return signature;
|
|
6750
|
+
};
|
|
6751
|
+
|
|
6640
6752
|
class EvmProvider {
|
|
6641
6753
|
#storage;
|
|
6642
6754
|
#policyId;
|
|
6755
|
+
/**
|
|
6756
|
+
* Updates the policy ID for the provider
|
|
6757
|
+
* @param newPolicyId - The new policy ID to use
|
|
6758
|
+
*/
|
|
6759
|
+
updatePolicy(newPolicy) {
|
|
6760
|
+
this.#policyId = newPolicy;
|
|
6761
|
+
}
|
|
6762
|
+
#validateAndRefreshSession;
|
|
6643
6763
|
#eventEmitter;
|
|
6644
6764
|
#rpcProvider; // Used for read
|
|
6645
6765
|
#backendApiClients;
|
|
6646
6766
|
isOpenfort = true;
|
|
6647
|
-
constructor({ storage, backendApiClients, openfortEventEmitter, policyId, }) {
|
|
6767
|
+
constructor({ storage, backendApiClients, openfortEventEmitter, policyId, validateAndRefreshSession, }) {
|
|
6648
6768
|
this.#storage = storage;
|
|
6649
6769
|
this.#policyId = policyId;
|
|
6770
|
+
this.#validateAndRefreshSession = validateAndRefreshSession;
|
|
6650
6771
|
this.#backendApiClients = backendApiClients;
|
|
6651
6772
|
const account = Account.fromStorage(this.#storage);
|
|
6652
6773
|
const chainId = account?.chainId || 8453;
|
|
@@ -6676,6 +6797,7 @@ class EvmProvider {
|
|
|
6676
6797
|
case 'eth_requestAccounts': {
|
|
6677
6798
|
let account = Account.fromStorage(this.#storage);
|
|
6678
6799
|
if (account) {
|
|
6800
|
+
this.#eventEmitter.emit(ProviderEvent.ACCOUNTS_CONNECT, { chainId: hexlify(account.chainId) });
|
|
6679
6801
|
return [account.address];
|
|
6680
6802
|
}
|
|
6681
6803
|
const signer = SignerManager.fromStorage();
|
|
@@ -6697,6 +6819,8 @@ class EvmProvider {
|
|
|
6697
6819
|
if (!account || !signer || !authentication) {
|
|
6698
6820
|
throw new JsonRpcError(ProviderErrorCode.UNAUTHORIZED, 'Unauthorized - call eth_requestAccounts first');
|
|
6699
6821
|
}
|
|
6822
|
+
this.#validateAndRefreshSession();
|
|
6823
|
+
console.log(`eth_sendTransaction ${this.#policyId}`);
|
|
6700
6824
|
return await sendTransaction({
|
|
6701
6825
|
params: request.params || [],
|
|
6702
6826
|
signer,
|
|
@@ -6713,6 +6837,7 @@ class EvmProvider {
|
|
|
6713
6837
|
if (!account || !signer) {
|
|
6714
6838
|
throw new JsonRpcError(ProviderErrorCode.UNAUTHORIZED, 'Unauthorized - call eth_requestAccounts first');
|
|
6715
6839
|
}
|
|
6840
|
+
this.#validateAndRefreshSession();
|
|
6716
6841
|
return await signTypedDataV4({
|
|
6717
6842
|
method: request.method,
|
|
6718
6843
|
params: request.params || [],
|
|
@@ -6721,6 +6846,19 @@ class EvmProvider {
|
|
|
6721
6846
|
rpcProvider: this.#rpcProvider,
|
|
6722
6847
|
});
|
|
6723
6848
|
}
|
|
6849
|
+
case 'personal_sign': {
|
|
6850
|
+
const account = Account.fromStorage(this.#storage);
|
|
6851
|
+
const signer = SignerManager.fromStorage();
|
|
6852
|
+
if (!account || !signer) {
|
|
6853
|
+
throw new JsonRpcError(ProviderErrorCode.UNAUTHORIZED, 'Unauthorized - call eth_requestAccounts first');
|
|
6854
|
+
}
|
|
6855
|
+
this.#validateAndRefreshSession();
|
|
6856
|
+
return await personalSign({
|
|
6857
|
+
params: request.params || [],
|
|
6858
|
+
signer,
|
|
6859
|
+
account,
|
|
6860
|
+
});
|
|
6861
|
+
}
|
|
6724
6862
|
case 'eth_chainId': {
|
|
6725
6863
|
// Call detect network to fetch the chainId so to take advantage of
|
|
6726
6864
|
// the caching layer provided by StaticJsonRpcProvider.
|
|
@@ -6731,6 +6869,25 @@ class EvmProvider {
|
|
|
6731
6869
|
const { chainId } = await this.#rpcProvider.detectNetwork();
|
|
6732
6870
|
return hexlify(chainId);
|
|
6733
6871
|
}
|
|
6872
|
+
case 'wallet_switchEthereumChain': {
|
|
6873
|
+
const signer = SignerManager.fromStorage();
|
|
6874
|
+
if (!signer) {
|
|
6875
|
+
throw new JsonRpcError(ProviderErrorCode.UNAUTHORIZED, 'Unauthorized - must be authenticated and configured with a signer');
|
|
6876
|
+
}
|
|
6877
|
+
if (!request.params || !Array.isArray(request.params) || request.params.length === 0) {
|
|
6878
|
+
throw new JsonRpcError(RpcErrorCode.INVALID_PARAMS, 'Invalid parameters for wallet_switchEthereumChain');
|
|
6879
|
+
}
|
|
6880
|
+
this.#validateAndRefreshSession();
|
|
6881
|
+
try {
|
|
6882
|
+
const chainIdNumber = parseInt(request.params[0].chainId, 16);
|
|
6883
|
+
await signer.switchChain({ chainId: chainIdNumber });
|
|
6884
|
+
this.#rpcProvider = new StaticJsonRpcProvider(chainMap[chainIdNumber].rpc[0]);
|
|
6885
|
+
}
|
|
6886
|
+
catch (error) {
|
|
6887
|
+
throw new JsonRpcError(RpcErrorCode.INTERNAL_ERROR, 'Failed to switch chain');
|
|
6888
|
+
}
|
|
6889
|
+
return null;
|
|
6890
|
+
}
|
|
6734
6891
|
case 'wallet_addEthereumChain': {
|
|
6735
6892
|
const signer = SignerManager.fromStorage();
|
|
6736
6893
|
if (!signer) {
|
|
@@ -6752,6 +6909,7 @@ class EvmProvider {
|
|
|
6752
6909
|
if (!account || !signer || !authentication) {
|
|
6753
6910
|
throw new JsonRpcError(ProviderErrorCode.UNAUTHORIZED, 'Unauthorized - call eth_requestAccounts first');
|
|
6754
6911
|
}
|
|
6912
|
+
this.#validateAndRefreshSession();
|
|
6755
6913
|
return await getCallStatus({
|
|
6756
6914
|
params: (request.params || {}),
|
|
6757
6915
|
authentication,
|
|
@@ -6766,6 +6924,7 @@ class EvmProvider {
|
|
|
6766
6924
|
if (!account || !signer || !authentication) {
|
|
6767
6925
|
throw new JsonRpcError(ProviderErrorCode.UNAUTHORIZED, 'Unauthorized - call eth_requestAccounts first');
|
|
6768
6926
|
}
|
|
6927
|
+
this.#validateAndRefreshSession();
|
|
6769
6928
|
return await sendCalls({
|
|
6770
6929
|
params: request.params || [],
|
|
6771
6930
|
signer,
|
|
@@ -6782,6 +6941,7 @@ class EvmProvider {
|
|
|
6782
6941
|
if (!account || !signer || !authentication) {
|
|
6783
6942
|
throw new JsonRpcError(ProviderErrorCode.UNAUTHORIZED, 'Unauthorized - call eth_requestAccounts first');
|
|
6784
6943
|
}
|
|
6944
|
+
this.#validateAndRefreshSession();
|
|
6785
6945
|
return await registerSession({
|
|
6786
6946
|
params: (request.params || []),
|
|
6787
6947
|
signer,
|
|
@@ -6799,6 +6959,7 @@ class EvmProvider {
|
|
|
6799
6959
|
if (!account || !signer || !authentication) {
|
|
6800
6960
|
throw new JsonRpcError(ProviderErrorCode.UNAUTHORIZED, 'Unauthorized - call eth_requestAccounts first');
|
|
6801
6961
|
}
|
|
6962
|
+
this.#validateAndRefreshSession();
|
|
6802
6963
|
return await revokeSession({
|
|
6803
6964
|
params: (request.params || {}),
|
|
6804
6965
|
signer,
|
|
@@ -6820,6 +6981,9 @@ class EvmProvider {
|
|
|
6820
6981
|
paymasterService: {
|
|
6821
6982
|
supported: true,
|
|
6822
6983
|
},
|
|
6984
|
+
atomicBatch: {
|
|
6985
|
+
supported: true,
|
|
6986
|
+
},
|
|
6823
6987
|
},
|
|
6824
6988
|
};
|
|
6825
6989
|
return capabilities;
|
|
@@ -6960,6 +7124,7 @@ function announceProvider(detail) {
|
|
|
6960
7124
|
|
|
6961
7125
|
class Openfort {
|
|
6962
7126
|
storage;
|
|
7127
|
+
provider = null;
|
|
6963
7128
|
constructor(sdkConfiguration) {
|
|
6964
7129
|
this.storage = new LocalStorage();
|
|
6965
7130
|
const configuration = new Configuration(sdkConfiguration.baseConfiguration.publishableKey, sdkConfiguration.overrides?.backendUrl || 'https://api.openfort.xyz', sdkConfiguration.shieldConfiguration?.shieldPublishableKey || '', sdkConfiguration.shieldConfiguration?.shieldEncryptionKey || '', sdkConfiguration.overrides?.shieldUrl || 'https://shield.openfort.xyz', sdkConfiguration.overrides?.iframeUrl || 'https://embedded.openfort.xyz', sdkConfiguration.shieldConfiguration?.debug || false);
|
|
@@ -6988,20 +7153,26 @@ class Openfort {
|
|
|
6988
7153
|
const authentication = Authentication.fromStorage(this.storage);
|
|
6989
7154
|
const signer = SignerManager.fromStorage();
|
|
6990
7155
|
const account = Account.fromStorage(this.storage);
|
|
6991
|
-
|
|
6992
|
-
|
|
6993
|
-
|
|
6994
|
-
|
|
6995
|
-
|
|
6996
|
-
|
|
6997
|
-
|
|
6998
|
-
|
|
6999
|
-
|
|
7000
|
-
|
|
7001
|
-
|
|
7002
|
-
|
|
7003
|
-
|
|
7004
|
-
|
|
7156
|
+
if (!this.provider) {
|
|
7157
|
+
this.provider = new EvmProvider({
|
|
7158
|
+
storage: this.storage,
|
|
7159
|
+
openfortEventEmitter: new TypedEventEmitter(),
|
|
7160
|
+
signer: signer || undefined,
|
|
7161
|
+
account: account || undefined,
|
|
7162
|
+
authentication: authentication || undefined,
|
|
7163
|
+
backendApiClients: this.backendApiClients,
|
|
7164
|
+
policyId: options.policy,
|
|
7165
|
+
validateAndRefreshSession: this.validateAndRefreshToken.bind(this),
|
|
7166
|
+
});
|
|
7167
|
+
announceProvider({
|
|
7168
|
+
info: { ...openfortProviderInfo, ...options.providerInfo },
|
|
7169
|
+
provider: this.provider,
|
|
7170
|
+
});
|
|
7171
|
+
}
|
|
7172
|
+
else if (this.provider && options.policy) {
|
|
7173
|
+
this.provider.updatePolicy(options.policy);
|
|
7174
|
+
}
|
|
7175
|
+
return this.provider;
|
|
7005
7176
|
}
|
|
7006
7177
|
/**
|
|
7007
7178
|
* Configures a session key and returns the session key details.
|
package/package.json
CHANGED