@openfort/openfort-js 0.8.12 → 0.8.13

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 CHANGED
@@ -4256,6 +4256,7 @@ class DeviceCredentialsManager {
4256
4256
  }
4257
4257
  }
4258
4258
 
4259
+ /* eslint-disable */
4259
4260
  const isBrowser = () => typeof document !== 'undefined';
4260
4261
 
4261
4262
  function base64URLEncode(str) {
@@ -4770,7 +4771,7 @@ class JsonRpcError extends Error {
4770
4771
  }
4771
4772
  }
4772
4773
 
4773
- const buildOpenfortTransactions = async (transactionRequest, backendApiClients, account, authentication, policyId) => {
4774
+ const buildOpenfortTransactions$4 = async (transactionRequest, backendApiClients, account, authentication, policyId) => {
4774
4775
  const interactions = transactionRequest.map((tx) => {
4775
4776
  if (!tx.to) {
4776
4777
  throw new JsonRpcError(RpcErrorCode.INVALID_PARAMS, 'eth_sendTransaction requires a "to" field');
@@ -4801,7 +4802,7 @@ const buildOpenfortTransactions = async (transactionRequest, backendApiClients,
4801
4802
  return transactionResponse.data;
4802
4803
  };
4803
4804
  const sendTransaction = async ({ params, signer, account, authentication, backendClient, policyId, }) => {
4804
- const openfortTransaction = await buildOpenfortTransactions(params, backendClient, account, authentication, policyId);
4805
+ const openfortTransaction = await buildOpenfortTransactions$4(params, backendClient, account, authentication, policyId);
4805
4806
  let response;
4806
4807
  if (openfortTransaction?.nextAction?.payload?.signableHash) {
4807
4808
  const signature = await signer.sign(openfortTransaction.nextAction.payload.signableHash);
@@ -5998,6 +5999,29 @@ const soneiumMinato = {
5998
5999
  slug: 'soneium-minato-testnet',
5999
6000
  };
6000
6001
 
6002
+ const sophonTestnet = {
6003
+ name: 'Sophon Testnet',
6004
+ title: 'Sophon Testnet',
6005
+ chain: 'sophon-testnet',
6006
+ rpc: ['https://rpc.testnet.sophon.xyz'],
6007
+ nativeCurrency: {
6008
+ name: 'Sophon',
6009
+ symbol: 'SOPH',
6010
+ decimals: 18,
6011
+ },
6012
+ shortName: 'sophon-testnet',
6013
+ chainId: 531050104,
6014
+ explorers: [
6015
+ {
6016
+ name: 'Sophon Block Explorer',
6017
+ url: 'https://explorer.testnet.sophon.xyz',
6018
+ standard: 'EIP3091',
6019
+ },
6020
+ ],
6021
+ testnet: true,
6022
+ slug: 'sophon-testnet',
6023
+ };
6024
+
6001
6025
  const chainMap = {
6002
6026
  // eslint-disable-next-line @typescript-eslint/naming-convention
6003
6027
  56: chain$m,
@@ -6055,6 +6079,342 @@ const chainMap = {
6055
6079
  5611: opBNBTestnet,
6056
6080
  // eslint-disable-next-line @typescript-eslint/naming-convention
6057
6081
  1946: soneiumMinato,
6082
+ // eslint-disable-next-line @typescript-eslint/naming-convention
6083
+ 531050104: sophonTestnet,
6084
+ };
6085
+
6086
+ const REQUIRED_CHAIN_PROPERTIES = ['chainId', 'chainName', 'nativeCurrency'];
6087
+ const isValidChainParameter = (chainParam) => (REQUIRED_CHAIN_PROPERTIES.every((key) => key in chainParam));
6088
+ const validateNativeCurrency = (nativeCurrency) => {
6089
+ if (!nativeCurrency || typeof nativeCurrency !== 'object')
6090
+ return false;
6091
+ const hasRequiredProperties = ('name' in nativeCurrency
6092
+ && 'symbol' in nativeCurrency
6093
+ && 'decimals' in nativeCurrency);
6094
+ if (!hasRequiredProperties)
6095
+ return false;
6096
+ return (typeof nativeCurrency.name === 'string'
6097
+ && typeof nativeCurrency.symbol === 'string'
6098
+ && typeof nativeCurrency.decimals === 'number'
6099
+ && Number.isInteger(nativeCurrency.decimals));
6100
+ };
6101
+ const transformChainParameter = (chainParam) => {
6102
+ if (!chainParam || typeof chainParam !== 'object') {
6103
+ throw new JsonRpcError(RpcErrorCode.INVALID_PARAMS, 'Invalid chain parameter: expected an object');
6104
+ }
6105
+ if (!isValidChainParameter(chainParam)) {
6106
+ throw new JsonRpcError(RpcErrorCode.INVALID_PARAMS, `Invalid chain parameter. The following properties are required: ${REQUIRED_CHAIN_PROPERTIES.join(', ')}`);
6107
+ }
6108
+ if (!chainParam.chainName || chainParam.chainName.trim() === '') {
6109
+ throw new JsonRpcError(RpcErrorCode.INVALID_PARAMS, 'chainName cannot be empty');
6110
+ }
6111
+ if (!validateNativeCurrency(chainParam.nativeCurrency)) {
6112
+ throw new JsonRpcError(RpcErrorCode.INVALID_PARAMS, 'Invalid nativeCurrency object');
6113
+ }
6114
+ if (chainParam.rpcUrls?.length === 0) {
6115
+ throw new JsonRpcError(RpcErrorCode.INVALID_PARAMS, 'At least one RPC URL must be provided');
6116
+ }
6117
+ // Ensure chainId is a valid hex string
6118
+ if (!/^0x[0-9a-fA-F]+$/.test(chainParam.chainId)) {
6119
+ throw new JsonRpcError(RpcErrorCode.INVALID_PARAMS, 'chainId must be a valid hex string');
6120
+ }
6121
+ return {
6122
+ chainId: chainParam.chainId,
6123
+ blockExplorerUrls: chainParam.blockExplorerUrls || [],
6124
+ chainName: chainParam.chainName,
6125
+ iconUrls: chainParam.iconUrls || [],
6126
+ rpcUrls: chainParam.rpcUrls || [],
6127
+ nativeCurrency: chainParam.nativeCurrency,
6128
+ };
6129
+ };
6130
+ const addEthereumChain = async ({ params, rpcProvider, }) => {
6131
+ if (!params || !Array.isArray(params) || params.length === 0) {
6132
+ throw new JsonRpcError(RpcErrorCode.INVALID_PARAMS, 'Invalid parameters for wallet_addEthereumChain');
6133
+ }
6134
+ const chainParameter = transformChainParameter(params[0]);
6135
+ const chainIdNumber = parseInt(chainParameter.chainId, 16);
6136
+ // Get current chainId
6137
+ const { chainId: currentChainId } = await rpcProvider.detectNetwork();
6138
+ // If we're already on this chain, return false
6139
+ if (chainIdNumber === currentChainId) {
6140
+ return false;
6141
+ }
6142
+ try {
6143
+ const signer = await SignerManager.embedded();
6144
+ if (!signer) {
6145
+ throw new JsonRpcError(ProviderErrorCode.UNAUTHORIZED, 'Unauthorized - no account available');
6146
+ }
6147
+ // If we successfully configured the chain, return null (success)
6148
+ return null;
6149
+ }
6150
+ catch (error) {
6151
+ if (error instanceof Error) {
6152
+ throw new JsonRpcError(RpcErrorCode.INTERNAL_ERROR, `Failed to add chain: ${error.message}`);
6153
+ }
6154
+ throw new JsonRpcError(RpcErrorCode.INTERNAL_ERROR, 'Failed to add chain');
6155
+ }
6156
+ };
6157
+
6158
+ function formatPolicyData(policy) {
6159
+ const data = (() => {
6160
+ if (policy.type === 'token-allowance') {
6161
+ return {
6162
+ allowance: (policy.data.allowance.toString()),
6163
+ };
6164
+ }
6165
+ if (policy.type === 'gas-limit') {
6166
+ return {
6167
+ limit: policy.data.limit.toString(),
6168
+ };
6169
+ }
6170
+ return policy.data;
6171
+ })();
6172
+ return {
6173
+ data,
6174
+ type: typeof policy.type === 'string' ? policy.type : policy.type.custom,
6175
+ };
6176
+ }
6177
+ function formatPermissionRequest(permission) {
6178
+ return {
6179
+ ...permission,
6180
+ policies: permission.policies.map(formatPolicyData),
6181
+ required: permission.required ?? false,
6182
+ type: typeof permission.type === 'string'
6183
+ ? permission.type
6184
+ : permission.type.custom,
6185
+ };
6186
+ }
6187
+ const formatSessionRequest$1 = (address, chainId, validAfter, validUntil, policyId, optimistic = false, whitelist, player, limit, externalOwnerAddress) => {
6188
+ const request = {
6189
+ address,
6190
+ chainId,
6191
+ validAfter,
6192
+ validUntil,
6193
+ optimistic,
6194
+ whitelist,
6195
+ player,
6196
+ };
6197
+ if (policyId)
6198
+ request.policy = policyId;
6199
+ if (externalOwnerAddress)
6200
+ request.externalOwnerAddress = externalOwnerAddress;
6201
+ if (limit)
6202
+ request.limit = limit;
6203
+ return request;
6204
+ };
6205
+ const buildOpenfortTransactions$3 = async (params, backendApiClients, account, authentication, policyId) => {
6206
+ const param = params[0];
6207
+ const now = Math.floor(new Date().getTime() / 1000);
6208
+ const expiry = Math.floor(new Date(Date.now() + param.expiry * 1000).getTime() / 1000);
6209
+ const formattedPermissions = param.permissions.map(formatPermissionRequest);
6210
+ const whitelist = formattedPermissions.filter((p) => p.type === 'contract-call'
6211
+ || p.type === 'erc20-token-transfer').map((p) => p.data.address);
6212
+ if (param.signer && param.signer.type === 'keys') {
6213
+ throw new JsonRpcError(RpcErrorCode.INVALID_PARAMS, 'Failed to request permissions - missing session address');
6214
+ }
6215
+ const sessionAddress = param.signer?.data?.id;
6216
+ if (!sessionAddress) {
6217
+ throw new JsonRpcError(RpcErrorCode.INVALID_PARAMS, 'Failed to request permissions - missing session address');
6218
+ }
6219
+ const sessionRequest = formatSessionRequest$1(sessionAddress, account.chainId, now, expiry, policyId, false, whitelist, authentication.player);
6220
+ const transactionResponse = await backendApiClients.sessionsApi.createSession({
6221
+ createSessionRequest: sessionRequest,
6222
+ }, {
6223
+ headers: {
6224
+ authorization: `Bearer ${backendApiClients.config.backend.accessToken}`,
6225
+ // eslint-disable-next-line @typescript-eslint/naming-convention
6226
+ 'x-player-token': authentication.token,
6227
+ // eslint-disable-next-line @typescript-eslint/naming-convention
6228
+ 'x-auth-provider': authentication.thirdPartyProvider,
6229
+ // eslint-disable-next-line @typescript-eslint/naming-convention
6230
+ 'x-token-type': authentication.thirdPartyTokenType,
6231
+ },
6232
+ });
6233
+ return transactionResponse.data;
6234
+ };
6235
+ function formatRequest(result) {
6236
+ return {
6237
+ expiry: result.validUntil ? Number(result.validUntil) : 0,
6238
+ grantedPermissions: result.whitelist?.map((address) => ({
6239
+ type: 'contract-call',
6240
+ data: {
6241
+ address,
6242
+ calls: [],
6243
+ },
6244
+ policies: [{
6245
+ data: {
6246
+ limit: result.limit,
6247
+ },
6248
+ type: { custom: 'usage-limit' },
6249
+ }],
6250
+ })),
6251
+ permissionsContext: result.id,
6252
+ };
6253
+ }
6254
+ const registerSession = async ({ params, signer, account, authentication, backendClient, policyId, }) => {
6255
+ const openfortTransaction = await buildOpenfortTransactions$3(params, backendClient, account, authentication, policyId);
6256
+ let response;
6257
+ if (openfortTransaction?.nextAction?.payload?.signableHash) {
6258
+ const signature = await signer.sign(openfortTransaction.nextAction.payload.signableHash);
6259
+ const openfortSignatureResponse = await backendClient.sessionsApi.signatureSession({
6260
+ id: openfortTransaction.id,
6261
+ signatureRequest: { signature },
6262
+ });
6263
+ if (!openfortSignatureResponse) {
6264
+ throw new JsonRpcError(RpcErrorCode.RPC_SERVER_ERROR, 'Transaction failed to submit');
6265
+ }
6266
+ response = openfortSignatureResponse.data;
6267
+ }
6268
+ else {
6269
+ throw new JsonRpcError(RpcErrorCode.RPC_SERVER_ERROR, 'Transaction failed to submit');
6270
+ }
6271
+ if (response.isActive === false) {
6272
+ throw new JsonRpcError(RpcErrorCode.RPC_SERVER_ERROR, 'Failed to request permissions');
6273
+ }
6274
+ return formatRequest(response);
6275
+ };
6276
+
6277
+ const formatSessionRequest = (address, chainId, player, policyId) => {
6278
+ const request = {
6279
+ address,
6280
+ chainId,
6281
+ player,
6282
+ };
6283
+ if (policyId)
6284
+ request.policy = policyId;
6285
+ return request;
6286
+ };
6287
+ const buildOpenfortTransactions$2 = async (params, backendApiClients, account, authentication, policyId) => {
6288
+ const sessionRequest = formatSessionRequest(params.permissionContext, account.chainId, authentication.player, policyId);
6289
+ const transactionResponse = await backendApiClients.sessionsApi.revokeSession({
6290
+ revokeSessionRequest: sessionRequest,
6291
+ }, {
6292
+ headers: {
6293
+ authorization: `Bearer ${backendApiClients.config.backend.accessToken}`,
6294
+ // eslint-disable-next-line @typescript-eslint/naming-convention
6295
+ 'x-player-token': authentication.token,
6296
+ // eslint-disable-next-line @typescript-eslint/naming-convention
6297
+ 'x-auth-provider': authentication.thirdPartyProvider,
6298
+ // eslint-disable-next-line @typescript-eslint/naming-convention
6299
+ 'x-token-type': authentication.thirdPartyTokenType,
6300
+ },
6301
+ });
6302
+ return transactionResponse.data;
6303
+ };
6304
+ const revokeSession = async ({ params, signer, account, authentication, backendClient, policyId, }) => {
6305
+ const openfortTransaction = await buildOpenfortTransactions$2(params, backendClient, account, authentication, policyId);
6306
+ let response;
6307
+ if (openfortTransaction?.nextAction?.payload?.signableHash) {
6308
+ const signature = await signer.sign(openfortTransaction.nextAction.payload.signableHash);
6309
+ const openfortSignatureResponse = await backendClient.sessionsApi.signatureSession({
6310
+ id: openfortTransaction.id,
6311
+ signatureRequest: { signature },
6312
+ });
6313
+ if (!openfortSignatureResponse) {
6314
+ throw new JsonRpcError(RpcErrorCode.RPC_SERVER_ERROR, 'Transaction failed to submit');
6315
+ }
6316
+ response = openfortSignatureResponse.data;
6317
+ }
6318
+ else {
6319
+ throw new JsonRpcError(RpcErrorCode.RPC_SERVER_ERROR, 'Transaction failed to submit');
6320
+ }
6321
+ if (response.isActive === false) {
6322
+ throw new JsonRpcError(RpcErrorCode.RPC_SERVER_ERROR, 'Failed to request permissions');
6323
+ }
6324
+ return {};
6325
+ };
6326
+
6327
+ const buildOpenfortTransactions$1 = async (calls, backendApiClients, account, authentication, policyId) => {
6328
+ const interactions = calls.map((call) => {
6329
+ if (!call.to) {
6330
+ throw new JsonRpcError(RpcErrorCode.INVALID_PARAMS, 'wallet_sendCalls requires a "to" field');
6331
+ }
6332
+ return {
6333
+ to: String(call.to),
6334
+ data: call.data ? String(call.data) : undefined,
6335
+ value: call.value ? String(call.value) : undefined,
6336
+ };
6337
+ });
6338
+ const transactionResponse = await backendApiClients.transactionIntentsApi.createTransactionIntent({
6339
+ createTransactionIntentRequest: {
6340
+ policy: policyId,
6341
+ chainId: account.chainId,
6342
+ interactions,
6343
+ },
6344
+ }, {
6345
+ headers: {
6346
+ authorization: `Bearer ${backendApiClients.config.backend.accessToken}`,
6347
+ // eslint-disable-next-line @typescript-eslint/naming-convention
6348
+ 'x-player-token': authentication.token,
6349
+ // eslint-disable-next-line @typescript-eslint/naming-convention
6350
+ 'x-auth-provider': authentication.thirdPartyProvider,
6351
+ // eslint-disable-next-line @typescript-eslint/naming-convention
6352
+ 'x-token-type': authentication.thirdPartyTokenType,
6353
+ },
6354
+ });
6355
+ return transactionResponse.data;
6356
+ };
6357
+ const sendCalls = async ({ params, signer, account, authentication, backendClient, policyId, }) => {
6358
+ const openfortTransaction = await buildOpenfortTransactions$1(params[0].calls, backendClient, account, authentication, policyId);
6359
+ let response;
6360
+ if (openfortTransaction?.nextAction?.payload?.signableHash) {
6361
+ const signature = await signer.sign(openfortTransaction.nextAction.payload.signableHash);
6362
+ const openfortSignatureResponse = (await backendClient.transactionIntentsApi.signature({
6363
+ id: openfortTransaction.id,
6364
+ signatureRequest: { signature },
6365
+ })).data.response;
6366
+ if (!openfortSignatureResponse) {
6367
+ throw new JsonRpcError(RpcErrorCode.RPC_SERVER_ERROR, 'Transaction failed to submit');
6368
+ }
6369
+ response = openfortSignatureResponse;
6370
+ }
6371
+ else if (openfortTransaction.response) {
6372
+ response = openfortTransaction.response;
6373
+ }
6374
+ else {
6375
+ throw new JsonRpcError(RpcErrorCode.RPC_SERVER_ERROR, 'Transaction failed to submit');
6376
+ }
6377
+ if (response.status === 0 && !response.transactionHash) {
6378
+ throw new JsonRpcError(RpcErrorCode.RPC_SERVER_ERROR, response.error.reason);
6379
+ }
6380
+ return response.transactionHash;
6381
+ };
6382
+
6383
+ const buildOpenfortTransactions = async (transactionIntentId, backendApiClients, authentication) => {
6384
+ const transactionResponse = await backendApiClients.transactionIntentsApi.getTransactionIntent({
6385
+ id: transactionIntentId,
6386
+ }, {
6387
+ headers: {
6388
+ authorization: `Bearer ${backendApiClients.config.backend.accessToken}`,
6389
+ // eslint-disable-next-line @typescript-eslint/naming-convention
6390
+ 'x-player-token': authentication.token,
6391
+ // eslint-disable-next-line @typescript-eslint/naming-convention
6392
+ 'x-auth-provider': authentication.thirdPartyProvider,
6393
+ // eslint-disable-next-line @typescript-eslint/naming-convention
6394
+ 'x-token-type': authentication.thirdPartyTokenType,
6395
+ },
6396
+ });
6397
+ return transactionResponse.data;
6398
+ };
6399
+ const getCallStatus = async ({ params, authentication, backendClient, }) => {
6400
+ const transactionIntent = await buildOpenfortTransactions(params[0], backendClient, authentication);
6401
+ return {
6402
+ status: !transactionIntent.response ? 'PENDING' : 'CONFIRMED',
6403
+ receipts: transactionIntent.response
6404
+ ? [{
6405
+ status: transactionIntent.response.status === 0 ? 'reverted' : 'success',
6406
+ logs: transactionIntent.response.logs?.map((log) => ({
6407
+ address: log.address,
6408
+ data: log.data,
6409
+ topics: log.topics,
6410
+ })) || [],
6411
+ blockHash: transactionIntent.response.transactionHash || '',
6412
+ blockNumber: BigInt(transactionIntent.response.blockNumber || 0),
6413
+ gasUsed: BigInt(transactionIntent.response.gasUsed || 0),
6414
+ transactionHash: transactionIntent.response.transactionHash || '',
6415
+ }]
6416
+ : undefined,
6417
+ };
6058
6418
  };
6059
6419
 
6060
6420
  class EvmProvider {
@@ -6089,7 +6449,10 @@ class EvmProvider {
6089
6449
  };
6090
6450
  async #performRequest(request) {
6091
6451
  switch (request.method) {
6092
- case 'eth_accounts':
6452
+ case 'eth_accounts': {
6453
+ const account = Account.fromStorage(this.#storage);
6454
+ return account ? [account.address] : [];
6455
+ }
6093
6456
  case 'eth_requestAccounts': {
6094
6457
  let account = Account.fromStorage(this.#storage);
6095
6458
  if (account) {
@@ -6148,6 +6511,96 @@ class EvmProvider {
6148
6511
  const { chainId } = await this.#rpcProvider.detectNetwork();
6149
6512
  return bytes.hexlify(chainId);
6150
6513
  }
6514
+ case 'wallet_addEthereumChain': {
6515
+ const signer = SignerManager.fromStorage();
6516
+ if (!signer) {
6517
+ throw new JsonRpcError(ProviderErrorCode.UNAUTHORIZED, 'Unauthorized - must be authenticated and configured with a signer');
6518
+ }
6519
+ return await addEthereumChain({
6520
+ params: request.params || [],
6521
+ rpcProvider: this.#rpcProvider,
6522
+ });
6523
+ }
6524
+ // EIP-5792: Wallet Call API
6525
+ case 'wallet_showCallsStatus': {
6526
+ return null;
6527
+ }
6528
+ case 'wallet_getCallsStatus': {
6529
+ const account = Account.fromStorage(this.#storage);
6530
+ const signer = SignerManager.fromStorage();
6531
+ const authentication = Authentication.fromStorage(this.#storage);
6532
+ if (!account || !signer || !authentication) {
6533
+ throw new JsonRpcError(ProviderErrorCode.UNAUTHORIZED, 'Unauthorized - call eth_requestAccounts first');
6534
+ }
6535
+ return await getCallStatus({
6536
+ params: (request.params || {}),
6537
+ authentication,
6538
+ backendClient: this.#backendApiClients,
6539
+ account,
6540
+ });
6541
+ }
6542
+ case 'wallet_sendCalls': {
6543
+ const account = Account.fromStorage(this.#storage);
6544
+ const signer = SignerManager.fromStorage();
6545
+ const authentication = Authentication.fromStorage(this.#storage);
6546
+ if (!account || !signer || !authentication) {
6547
+ throw new JsonRpcError(ProviderErrorCode.UNAUTHORIZED, 'Unauthorized - call eth_requestAccounts first');
6548
+ }
6549
+ return await sendCalls({
6550
+ params: request.params || [],
6551
+ signer,
6552
+ account,
6553
+ authentication,
6554
+ backendClient: this.#backendApiClients,
6555
+ policyId: this.#policyId,
6556
+ });
6557
+ }
6558
+ case 'wallet_grantPermissions': {
6559
+ const account = Account.fromStorage(this.#storage);
6560
+ const signer = SignerManager.fromStorage();
6561
+ const authentication = Authentication.fromStorage(this.#storage);
6562
+ if (!account || !signer || !authentication) {
6563
+ throw new JsonRpcError(ProviderErrorCode.UNAUTHORIZED, 'Unauthorized - call eth_requestAccounts first');
6564
+ }
6565
+ return await registerSession({
6566
+ params: (request.params || []),
6567
+ signer,
6568
+ account,
6569
+ authentication,
6570
+ backendClient: this.#backendApiClients,
6571
+ policyId: this.#policyId,
6572
+ });
6573
+ }
6574
+ // EIP-7715: Wallet Session Key API
6575
+ case 'wallet_revokePermissions': {
6576
+ const account = Account.fromStorage(this.#storage);
6577
+ const signer = SignerManager.fromStorage();
6578
+ const authentication = Authentication.fromStorage(this.#storage);
6579
+ if (!account || !signer || !authentication) {
6580
+ throw new JsonRpcError(ProviderErrorCode.UNAUTHORIZED, 'Unauthorized - call eth_requestAccounts first');
6581
+ }
6582
+ return await revokeSession({
6583
+ params: (request.params || {}),
6584
+ signer,
6585
+ account,
6586
+ authentication,
6587
+ backendClient: this.#backendApiClients,
6588
+ });
6589
+ }
6590
+ case 'wallet_getCapabilities': {
6591
+ const { chainId } = await this.#rpcProvider.detectNetwork();
6592
+ const capabilities = {
6593
+ [bytes.hexlify(chainId)]: {
6594
+ permissions: {
6595
+ supported: true,
6596
+ signerTypes: ['account', 'key'],
6597
+ keyTypes: ['secp256k1'],
6598
+ permissionTypes: ['contract-calls'],
6599
+ },
6600
+ },
6601
+ };
6602
+ return capabilities;
6603
+ }
6151
6604
  // Pass through methods
6152
6605
  case 'eth_gasPrice':
6153
6606
  case 'eth_getBalance':
@@ -6164,7 +6617,7 @@ class EvmProvider {
6164
6617
  return this.#rpcProvider.send(request.method, request.params || []);
6165
6618
  }
6166
6619
  default: {
6167
- throw new JsonRpcError(ProviderErrorCode.UNSUPPORTED_METHOD, 'Method not supported');
6620
+ throw new JsonRpcError(ProviderErrorCode.UNSUPPORTED_METHOD, `${request.method}: Method not supported`);
6168
6621
  }
6169
6622
  }
6170
6623
  }
@@ -6308,7 +6761,7 @@ class Openfort {
6308
6761
  * @returns A Provider instance.
6309
6762
  * @throws {OpenfortError} If the signer is not an EmbeddedSigner.
6310
6763
  */
6311
- getEthereumProvider(options = { announceProvider: true }) {
6764
+ getEthereumProvider(options = {}) {
6312
6765
  const authentication = Authentication.fromStorage(this.storage);
6313
6766
  const signer = SignerManager.fromStorage();
6314
6767
  const account = Account.fromStorage(this.storage);
@@ -6321,12 +6774,10 @@ class Openfort {
6321
6774
  backendApiClients: this.backendApiClients,
6322
6775
  policyId: options.policy,
6323
6776
  });
6324
- if (options?.announceProvider) {
6325
- announceProvider({
6326
- info: openfortProviderInfo,
6327
- provider,
6328
- });
6329
- }
6777
+ announceProvider({
6778
+ info: { ...openfortProviderInfo, ...options.providerInfo },
6779
+ provider,
6780
+ });
6330
6781
  return provider;
6331
6782
  }
6332
6783
  /**
@@ -6406,7 +6857,9 @@ class Openfort {
6406
6857
  // eslint-disable-next-line no-param-reassign
6407
6858
  delete types.EIP712Domain;
6408
6859
  const account = Account.fromStorage(this.storage);
6409
- if (account && account.type === AccountType.UPGRADEABLE_V5) {
6860
+ if (account && [AccountType.UPGRADEABLE_V5,
6861
+ AccountType.UPGRADEABLE_V6,
6862
+ AccountType.ZKSYNC_UPGRADEABLE_V1].includes(account.type)) {
6410
6863
  const updatedDomain = {
6411
6864
  name: 'Openfort',
6412
6865
  version: '0.5',
package/dist/index.d.ts CHANGED
@@ -589,8 +589,12 @@ declare class Openfort {
589
589
  * @throws {OpenfortError} If the signer is not an EmbeddedSigner.
590
590
  */
591
591
  getEthereumProvider(options?: {
592
- announceProvider: boolean;
593
592
  policy?: string;
593
+ providerInfo?: {
594
+ icon: `data:image/${string}`;
595
+ name: string;
596
+ rdns: string;
597
+ };
594
598
  }): Provider;
595
599
  /**
596
600
  * Configures a session key and returns the session key details.
package/dist/index.js CHANGED
@@ -4233,6 +4233,7 @@ class DeviceCredentialsManager {
4233
4233
  }
4234
4234
  }
4235
4235
 
4236
+ /* eslint-disable */
4236
4237
  const isBrowser = () => typeof document !== 'undefined';
4237
4238
 
4238
4239
  function base64URLEncode(str) {
@@ -4747,7 +4748,7 @@ class JsonRpcError extends Error {
4747
4748
  }
4748
4749
  }
4749
4750
 
4750
- const buildOpenfortTransactions = async (transactionRequest, backendApiClients, account, authentication, policyId) => {
4751
+ const buildOpenfortTransactions$4 = async (transactionRequest, backendApiClients, account, authentication, policyId) => {
4751
4752
  const interactions = transactionRequest.map((tx) => {
4752
4753
  if (!tx.to) {
4753
4754
  throw new JsonRpcError(RpcErrorCode.INVALID_PARAMS, 'eth_sendTransaction requires a "to" field');
@@ -4778,7 +4779,7 @@ const buildOpenfortTransactions = async (transactionRequest, backendApiClients,
4778
4779
  return transactionResponse.data;
4779
4780
  };
4780
4781
  const sendTransaction = async ({ params, signer, account, authentication, backendClient, policyId, }) => {
4781
- const openfortTransaction = await buildOpenfortTransactions(params, backendClient, account, authentication, policyId);
4782
+ const openfortTransaction = await buildOpenfortTransactions$4(params, backendClient, account, authentication, policyId);
4782
4783
  let response;
4783
4784
  if (openfortTransaction?.nextAction?.payload?.signableHash) {
4784
4785
  const signature = await signer.sign(openfortTransaction.nextAction.payload.signableHash);
@@ -5975,6 +5976,29 @@ const soneiumMinato = {
5975
5976
  slug: 'soneium-minato-testnet',
5976
5977
  };
5977
5978
 
5979
+ const sophonTestnet = {
5980
+ name: 'Sophon Testnet',
5981
+ title: 'Sophon Testnet',
5982
+ chain: 'sophon-testnet',
5983
+ rpc: ['https://rpc.testnet.sophon.xyz'],
5984
+ nativeCurrency: {
5985
+ name: 'Sophon',
5986
+ symbol: 'SOPH',
5987
+ decimals: 18,
5988
+ },
5989
+ shortName: 'sophon-testnet',
5990
+ chainId: 531050104,
5991
+ explorers: [
5992
+ {
5993
+ name: 'Sophon Block Explorer',
5994
+ url: 'https://explorer.testnet.sophon.xyz',
5995
+ standard: 'EIP3091',
5996
+ },
5997
+ ],
5998
+ testnet: true,
5999
+ slug: 'sophon-testnet',
6000
+ };
6001
+
5978
6002
  const chainMap = {
5979
6003
  // eslint-disable-next-line @typescript-eslint/naming-convention
5980
6004
  56: chain$m,
@@ -6032,6 +6056,342 @@ const chainMap = {
6032
6056
  5611: opBNBTestnet,
6033
6057
  // eslint-disable-next-line @typescript-eslint/naming-convention
6034
6058
  1946: soneiumMinato,
6059
+ // eslint-disable-next-line @typescript-eslint/naming-convention
6060
+ 531050104: sophonTestnet,
6061
+ };
6062
+
6063
+ const REQUIRED_CHAIN_PROPERTIES = ['chainId', 'chainName', 'nativeCurrency'];
6064
+ const isValidChainParameter = (chainParam) => (REQUIRED_CHAIN_PROPERTIES.every((key) => key in chainParam));
6065
+ const validateNativeCurrency = (nativeCurrency) => {
6066
+ if (!nativeCurrency || typeof nativeCurrency !== 'object')
6067
+ return false;
6068
+ const hasRequiredProperties = ('name' in nativeCurrency
6069
+ && 'symbol' in nativeCurrency
6070
+ && 'decimals' in nativeCurrency);
6071
+ if (!hasRequiredProperties)
6072
+ return false;
6073
+ return (typeof nativeCurrency.name === 'string'
6074
+ && typeof nativeCurrency.symbol === 'string'
6075
+ && typeof nativeCurrency.decimals === 'number'
6076
+ && Number.isInteger(nativeCurrency.decimals));
6077
+ };
6078
+ const transformChainParameter = (chainParam) => {
6079
+ if (!chainParam || typeof chainParam !== 'object') {
6080
+ throw new JsonRpcError(RpcErrorCode.INVALID_PARAMS, 'Invalid chain parameter: expected an object');
6081
+ }
6082
+ if (!isValidChainParameter(chainParam)) {
6083
+ throw new JsonRpcError(RpcErrorCode.INVALID_PARAMS, `Invalid chain parameter. The following properties are required: ${REQUIRED_CHAIN_PROPERTIES.join(', ')}`);
6084
+ }
6085
+ if (!chainParam.chainName || chainParam.chainName.trim() === '') {
6086
+ throw new JsonRpcError(RpcErrorCode.INVALID_PARAMS, 'chainName cannot be empty');
6087
+ }
6088
+ if (!validateNativeCurrency(chainParam.nativeCurrency)) {
6089
+ throw new JsonRpcError(RpcErrorCode.INVALID_PARAMS, 'Invalid nativeCurrency object');
6090
+ }
6091
+ if (chainParam.rpcUrls?.length === 0) {
6092
+ throw new JsonRpcError(RpcErrorCode.INVALID_PARAMS, 'At least one RPC URL must be provided');
6093
+ }
6094
+ // Ensure chainId is a valid hex string
6095
+ if (!/^0x[0-9a-fA-F]+$/.test(chainParam.chainId)) {
6096
+ throw new JsonRpcError(RpcErrorCode.INVALID_PARAMS, 'chainId must be a valid hex string');
6097
+ }
6098
+ return {
6099
+ chainId: chainParam.chainId,
6100
+ blockExplorerUrls: chainParam.blockExplorerUrls || [],
6101
+ chainName: chainParam.chainName,
6102
+ iconUrls: chainParam.iconUrls || [],
6103
+ rpcUrls: chainParam.rpcUrls || [],
6104
+ nativeCurrency: chainParam.nativeCurrency,
6105
+ };
6106
+ };
6107
+ const addEthereumChain = async ({ params, rpcProvider, }) => {
6108
+ if (!params || !Array.isArray(params) || params.length === 0) {
6109
+ throw new JsonRpcError(RpcErrorCode.INVALID_PARAMS, 'Invalid parameters for wallet_addEthereumChain');
6110
+ }
6111
+ const chainParameter = transformChainParameter(params[0]);
6112
+ const chainIdNumber = parseInt(chainParameter.chainId, 16);
6113
+ // Get current chainId
6114
+ const { chainId: currentChainId } = await rpcProvider.detectNetwork();
6115
+ // If we're already on this chain, return false
6116
+ if (chainIdNumber === currentChainId) {
6117
+ return false;
6118
+ }
6119
+ try {
6120
+ const signer = await SignerManager.embedded();
6121
+ if (!signer) {
6122
+ throw new JsonRpcError(ProviderErrorCode.UNAUTHORIZED, 'Unauthorized - no account available');
6123
+ }
6124
+ // If we successfully configured the chain, return null (success)
6125
+ return null;
6126
+ }
6127
+ catch (error) {
6128
+ if (error instanceof Error) {
6129
+ throw new JsonRpcError(RpcErrorCode.INTERNAL_ERROR, `Failed to add chain: ${error.message}`);
6130
+ }
6131
+ throw new JsonRpcError(RpcErrorCode.INTERNAL_ERROR, 'Failed to add chain');
6132
+ }
6133
+ };
6134
+
6135
+ function formatPolicyData(policy) {
6136
+ const data = (() => {
6137
+ if (policy.type === 'token-allowance') {
6138
+ return {
6139
+ allowance: (policy.data.allowance.toString()),
6140
+ };
6141
+ }
6142
+ if (policy.type === 'gas-limit') {
6143
+ return {
6144
+ limit: policy.data.limit.toString(),
6145
+ };
6146
+ }
6147
+ return policy.data;
6148
+ })();
6149
+ return {
6150
+ data,
6151
+ type: typeof policy.type === 'string' ? policy.type : policy.type.custom,
6152
+ };
6153
+ }
6154
+ function formatPermissionRequest(permission) {
6155
+ return {
6156
+ ...permission,
6157
+ policies: permission.policies.map(formatPolicyData),
6158
+ required: permission.required ?? false,
6159
+ type: typeof permission.type === 'string'
6160
+ ? permission.type
6161
+ : permission.type.custom,
6162
+ };
6163
+ }
6164
+ const formatSessionRequest$1 = (address, chainId, validAfter, validUntil, policyId, optimistic = false, whitelist, player, limit, externalOwnerAddress) => {
6165
+ const request = {
6166
+ address,
6167
+ chainId,
6168
+ validAfter,
6169
+ validUntil,
6170
+ optimistic,
6171
+ whitelist,
6172
+ player,
6173
+ };
6174
+ if (policyId)
6175
+ request.policy = policyId;
6176
+ if (externalOwnerAddress)
6177
+ request.externalOwnerAddress = externalOwnerAddress;
6178
+ if (limit)
6179
+ request.limit = limit;
6180
+ return request;
6181
+ };
6182
+ const buildOpenfortTransactions$3 = async (params, backendApiClients, account, authentication, policyId) => {
6183
+ const param = params[0];
6184
+ const now = Math.floor(new Date().getTime() / 1000);
6185
+ const expiry = Math.floor(new Date(Date.now() + param.expiry * 1000).getTime() / 1000);
6186
+ const formattedPermissions = param.permissions.map(formatPermissionRequest);
6187
+ const whitelist = formattedPermissions.filter((p) => p.type === 'contract-call'
6188
+ || p.type === 'erc20-token-transfer').map((p) => p.data.address);
6189
+ if (param.signer && param.signer.type === 'keys') {
6190
+ throw new JsonRpcError(RpcErrorCode.INVALID_PARAMS, 'Failed to request permissions - missing session address');
6191
+ }
6192
+ const sessionAddress = param.signer?.data?.id;
6193
+ if (!sessionAddress) {
6194
+ throw new JsonRpcError(RpcErrorCode.INVALID_PARAMS, 'Failed to request permissions - missing session address');
6195
+ }
6196
+ const sessionRequest = formatSessionRequest$1(sessionAddress, account.chainId, now, expiry, policyId, false, whitelist, authentication.player);
6197
+ const transactionResponse = await backendApiClients.sessionsApi.createSession({
6198
+ createSessionRequest: sessionRequest,
6199
+ }, {
6200
+ headers: {
6201
+ authorization: `Bearer ${backendApiClients.config.backend.accessToken}`,
6202
+ // eslint-disable-next-line @typescript-eslint/naming-convention
6203
+ 'x-player-token': authentication.token,
6204
+ // eslint-disable-next-line @typescript-eslint/naming-convention
6205
+ 'x-auth-provider': authentication.thirdPartyProvider,
6206
+ // eslint-disable-next-line @typescript-eslint/naming-convention
6207
+ 'x-token-type': authentication.thirdPartyTokenType,
6208
+ },
6209
+ });
6210
+ return transactionResponse.data;
6211
+ };
6212
+ function formatRequest(result) {
6213
+ return {
6214
+ expiry: result.validUntil ? Number(result.validUntil) : 0,
6215
+ grantedPermissions: result.whitelist?.map((address) => ({
6216
+ type: 'contract-call',
6217
+ data: {
6218
+ address,
6219
+ calls: [],
6220
+ },
6221
+ policies: [{
6222
+ data: {
6223
+ limit: result.limit,
6224
+ },
6225
+ type: { custom: 'usage-limit' },
6226
+ }],
6227
+ })),
6228
+ permissionsContext: result.id,
6229
+ };
6230
+ }
6231
+ const registerSession = async ({ params, signer, account, authentication, backendClient, policyId, }) => {
6232
+ const openfortTransaction = await buildOpenfortTransactions$3(params, backendClient, account, authentication, policyId);
6233
+ let response;
6234
+ if (openfortTransaction?.nextAction?.payload?.signableHash) {
6235
+ const signature = await signer.sign(openfortTransaction.nextAction.payload.signableHash);
6236
+ const openfortSignatureResponse = await backendClient.sessionsApi.signatureSession({
6237
+ id: openfortTransaction.id,
6238
+ signatureRequest: { signature },
6239
+ });
6240
+ if (!openfortSignatureResponse) {
6241
+ throw new JsonRpcError(RpcErrorCode.RPC_SERVER_ERROR, 'Transaction failed to submit');
6242
+ }
6243
+ response = openfortSignatureResponse.data;
6244
+ }
6245
+ else {
6246
+ throw new JsonRpcError(RpcErrorCode.RPC_SERVER_ERROR, 'Transaction failed to submit');
6247
+ }
6248
+ if (response.isActive === false) {
6249
+ throw new JsonRpcError(RpcErrorCode.RPC_SERVER_ERROR, 'Failed to request permissions');
6250
+ }
6251
+ return formatRequest(response);
6252
+ };
6253
+
6254
+ const formatSessionRequest = (address, chainId, player, policyId) => {
6255
+ const request = {
6256
+ address,
6257
+ chainId,
6258
+ player,
6259
+ };
6260
+ if (policyId)
6261
+ request.policy = policyId;
6262
+ return request;
6263
+ };
6264
+ const buildOpenfortTransactions$2 = async (params, backendApiClients, account, authentication, policyId) => {
6265
+ const sessionRequest = formatSessionRequest(params.permissionContext, account.chainId, authentication.player, policyId);
6266
+ const transactionResponse = await backendApiClients.sessionsApi.revokeSession({
6267
+ revokeSessionRequest: sessionRequest,
6268
+ }, {
6269
+ headers: {
6270
+ authorization: `Bearer ${backendApiClients.config.backend.accessToken}`,
6271
+ // eslint-disable-next-line @typescript-eslint/naming-convention
6272
+ 'x-player-token': authentication.token,
6273
+ // eslint-disable-next-line @typescript-eslint/naming-convention
6274
+ 'x-auth-provider': authentication.thirdPartyProvider,
6275
+ // eslint-disable-next-line @typescript-eslint/naming-convention
6276
+ 'x-token-type': authentication.thirdPartyTokenType,
6277
+ },
6278
+ });
6279
+ return transactionResponse.data;
6280
+ };
6281
+ const revokeSession = async ({ params, signer, account, authentication, backendClient, policyId, }) => {
6282
+ const openfortTransaction = await buildOpenfortTransactions$2(params, backendClient, account, authentication, policyId);
6283
+ let response;
6284
+ if (openfortTransaction?.nextAction?.payload?.signableHash) {
6285
+ const signature = await signer.sign(openfortTransaction.nextAction.payload.signableHash);
6286
+ const openfortSignatureResponse = await backendClient.sessionsApi.signatureSession({
6287
+ id: openfortTransaction.id,
6288
+ signatureRequest: { signature },
6289
+ });
6290
+ if (!openfortSignatureResponse) {
6291
+ throw new JsonRpcError(RpcErrorCode.RPC_SERVER_ERROR, 'Transaction failed to submit');
6292
+ }
6293
+ response = openfortSignatureResponse.data;
6294
+ }
6295
+ else {
6296
+ throw new JsonRpcError(RpcErrorCode.RPC_SERVER_ERROR, 'Transaction failed to submit');
6297
+ }
6298
+ if (response.isActive === false) {
6299
+ throw new JsonRpcError(RpcErrorCode.RPC_SERVER_ERROR, 'Failed to request permissions');
6300
+ }
6301
+ return {};
6302
+ };
6303
+
6304
+ const buildOpenfortTransactions$1 = async (calls, backendApiClients, account, authentication, policyId) => {
6305
+ const interactions = calls.map((call) => {
6306
+ if (!call.to) {
6307
+ throw new JsonRpcError(RpcErrorCode.INVALID_PARAMS, 'wallet_sendCalls requires a "to" field');
6308
+ }
6309
+ return {
6310
+ to: String(call.to),
6311
+ data: call.data ? String(call.data) : undefined,
6312
+ value: call.value ? String(call.value) : undefined,
6313
+ };
6314
+ });
6315
+ const transactionResponse = await backendApiClients.transactionIntentsApi.createTransactionIntent({
6316
+ createTransactionIntentRequest: {
6317
+ policy: policyId,
6318
+ chainId: account.chainId,
6319
+ interactions,
6320
+ },
6321
+ }, {
6322
+ headers: {
6323
+ authorization: `Bearer ${backendApiClients.config.backend.accessToken}`,
6324
+ // eslint-disable-next-line @typescript-eslint/naming-convention
6325
+ 'x-player-token': authentication.token,
6326
+ // eslint-disable-next-line @typescript-eslint/naming-convention
6327
+ 'x-auth-provider': authentication.thirdPartyProvider,
6328
+ // eslint-disable-next-line @typescript-eslint/naming-convention
6329
+ 'x-token-type': authentication.thirdPartyTokenType,
6330
+ },
6331
+ });
6332
+ return transactionResponse.data;
6333
+ };
6334
+ const sendCalls = async ({ params, signer, account, authentication, backendClient, policyId, }) => {
6335
+ const openfortTransaction = await buildOpenfortTransactions$1(params[0].calls, backendClient, account, authentication, policyId);
6336
+ let response;
6337
+ if (openfortTransaction?.nextAction?.payload?.signableHash) {
6338
+ const signature = await signer.sign(openfortTransaction.nextAction.payload.signableHash);
6339
+ const openfortSignatureResponse = (await backendClient.transactionIntentsApi.signature({
6340
+ id: openfortTransaction.id,
6341
+ signatureRequest: { signature },
6342
+ })).data.response;
6343
+ if (!openfortSignatureResponse) {
6344
+ throw new JsonRpcError(RpcErrorCode.RPC_SERVER_ERROR, 'Transaction failed to submit');
6345
+ }
6346
+ response = openfortSignatureResponse;
6347
+ }
6348
+ else if (openfortTransaction.response) {
6349
+ response = openfortTransaction.response;
6350
+ }
6351
+ else {
6352
+ throw new JsonRpcError(RpcErrorCode.RPC_SERVER_ERROR, 'Transaction failed to submit');
6353
+ }
6354
+ if (response.status === 0 && !response.transactionHash) {
6355
+ throw new JsonRpcError(RpcErrorCode.RPC_SERVER_ERROR, response.error.reason);
6356
+ }
6357
+ return response.transactionHash;
6358
+ };
6359
+
6360
+ const buildOpenfortTransactions = async (transactionIntentId, backendApiClients, authentication) => {
6361
+ const transactionResponse = await backendApiClients.transactionIntentsApi.getTransactionIntent({
6362
+ id: transactionIntentId,
6363
+ }, {
6364
+ headers: {
6365
+ authorization: `Bearer ${backendApiClients.config.backend.accessToken}`,
6366
+ // eslint-disable-next-line @typescript-eslint/naming-convention
6367
+ 'x-player-token': authentication.token,
6368
+ // eslint-disable-next-line @typescript-eslint/naming-convention
6369
+ 'x-auth-provider': authentication.thirdPartyProvider,
6370
+ // eslint-disable-next-line @typescript-eslint/naming-convention
6371
+ 'x-token-type': authentication.thirdPartyTokenType,
6372
+ },
6373
+ });
6374
+ return transactionResponse.data;
6375
+ };
6376
+ const getCallStatus = async ({ params, authentication, backendClient, }) => {
6377
+ const transactionIntent = await buildOpenfortTransactions(params[0], backendClient, authentication);
6378
+ return {
6379
+ status: !transactionIntent.response ? 'PENDING' : 'CONFIRMED',
6380
+ receipts: transactionIntent.response
6381
+ ? [{
6382
+ status: transactionIntent.response.status === 0 ? 'reverted' : 'success',
6383
+ logs: transactionIntent.response.logs?.map((log) => ({
6384
+ address: log.address,
6385
+ data: log.data,
6386
+ topics: log.topics,
6387
+ })) || [],
6388
+ blockHash: transactionIntent.response.transactionHash || '',
6389
+ blockNumber: BigInt(transactionIntent.response.blockNumber || 0),
6390
+ gasUsed: BigInt(transactionIntent.response.gasUsed || 0),
6391
+ transactionHash: transactionIntent.response.transactionHash || '',
6392
+ }]
6393
+ : undefined,
6394
+ };
6035
6395
  };
6036
6396
 
6037
6397
  class EvmProvider {
@@ -6066,7 +6426,10 @@ class EvmProvider {
6066
6426
  };
6067
6427
  async #performRequest(request) {
6068
6428
  switch (request.method) {
6069
- case 'eth_accounts':
6429
+ case 'eth_accounts': {
6430
+ const account = Account.fromStorage(this.#storage);
6431
+ return account ? [account.address] : [];
6432
+ }
6070
6433
  case 'eth_requestAccounts': {
6071
6434
  let account = Account.fromStorage(this.#storage);
6072
6435
  if (account) {
@@ -6125,6 +6488,96 @@ class EvmProvider {
6125
6488
  const { chainId } = await this.#rpcProvider.detectNetwork();
6126
6489
  return hexlify(chainId);
6127
6490
  }
6491
+ case 'wallet_addEthereumChain': {
6492
+ const signer = SignerManager.fromStorage();
6493
+ if (!signer) {
6494
+ throw new JsonRpcError(ProviderErrorCode.UNAUTHORIZED, 'Unauthorized - must be authenticated and configured with a signer');
6495
+ }
6496
+ return await addEthereumChain({
6497
+ params: request.params || [],
6498
+ rpcProvider: this.#rpcProvider,
6499
+ });
6500
+ }
6501
+ // EIP-5792: Wallet Call API
6502
+ case 'wallet_showCallsStatus': {
6503
+ return null;
6504
+ }
6505
+ case 'wallet_getCallsStatus': {
6506
+ const account = Account.fromStorage(this.#storage);
6507
+ const signer = SignerManager.fromStorage();
6508
+ const authentication = Authentication.fromStorage(this.#storage);
6509
+ if (!account || !signer || !authentication) {
6510
+ throw new JsonRpcError(ProviderErrorCode.UNAUTHORIZED, 'Unauthorized - call eth_requestAccounts first');
6511
+ }
6512
+ return await getCallStatus({
6513
+ params: (request.params || {}),
6514
+ authentication,
6515
+ backendClient: this.#backendApiClients,
6516
+ account,
6517
+ });
6518
+ }
6519
+ case 'wallet_sendCalls': {
6520
+ const account = Account.fromStorage(this.#storage);
6521
+ const signer = SignerManager.fromStorage();
6522
+ const authentication = Authentication.fromStorage(this.#storage);
6523
+ if (!account || !signer || !authentication) {
6524
+ throw new JsonRpcError(ProviderErrorCode.UNAUTHORIZED, 'Unauthorized - call eth_requestAccounts first');
6525
+ }
6526
+ return await sendCalls({
6527
+ params: request.params || [],
6528
+ signer,
6529
+ account,
6530
+ authentication,
6531
+ backendClient: this.#backendApiClients,
6532
+ policyId: this.#policyId,
6533
+ });
6534
+ }
6535
+ case 'wallet_grantPermissions': {
6536
+ const account = Account.fromStorage(this.#storage);
6537
+ const signer = SignerManager.fromStorage();
6538
+ const authentication = Authentication.fromStorage(this.#storage);
6539
+ if (!account || !signer || !authentication) {
6540
+ throw new JsonRpcError(ProviderErrorCode.UNAUTHORIZED, 'Unauthorized - call eth_requestAccounts first');
6541
+ }
6542
+ return await registerSession({
6543
+ params: (request.params || []),
6544
+ signer,
6545
+ account,
6546
+ authentication,
6547
+ backendClient: this.#backendApiClients,
6548
+ policyId: this.#policyId,
6549
+ });
6550
+ }
6551
+ // EIP-7715: Wallet Session Key API
6552
+ case 'wallet_revokePermissions': {
6553
+ const account = Account.fromStorage(this.#storage);
6554
+ const signer = SignerManager.fromStorage();
6555
+ const authentication = Authentication.fromStorage(this.#storage);
6556
+ if (!account || !signer || !authentication) {
6557
+ throw new JsonRpcError(ProviderErrorCode.UNAUTHORIZED, 'Unauthorized - call eth_requestAccounts first');
6558
+ }
6559
+ return await revokeSession({
6560
+ params: (request.params || {}),
6561
+ signer,
6562
+ account,
6563
+ authentication,
6564
+ backendClient: this.#backendApiClients,
6565
+ });
6566
+ }
6567
+ case 'wallet_getCapabilities': {
6568
+ const { chainId } = await this.#rpcProvider.detectNetwork();
6569
+ const capabilities = {
6570
+ [hexlify(chainId)]: {
6571
+ permissions: {
6572
+ supported: true,
6573
+ signerTypes: ['account', 'key'],
6574
+ keyTypes: ['secp256k1'],
6575
+ permissionTypes: ['contract-calls'],
6576
+ },
6577
+ },
6578
+ };
6579
+ return capabilities;
6580
+ }
6128
6581
  // Pass through methods
6129
6582
  case 'eth_gasPrice':
6130
6583
  case 'eth_getBalance':
@@ -6141,7 +6594,7 @@ class EvmProvider {
6141
6594
  return this.#rpcProvider.send(request.method, request.params || []);
6142
6595
  }
6143
6596
  default: {
6144
- throw new JsonRpcError(ProviderErrorCode.UNSUPPORTED_METHOD, 'Method not supported');
6597
+ throw new JsonRpcError(ProviderErrorCode.UNSUPPORTED_METHOD, `${request.method}: Method not supported`);
6145
6598
  }
6146
6599
  }
6147
6600
  }
@@ -6285,7 +6738,7 @@ class Openfort {
6285
6738
  * @returns A Provider instance.
6286
6739
  * @throws {OpenfortError} If the signer is not an EmbeddedSigner.
6287
6740
  */
6288
- getEthereumProvider(options = { announceProvider: true }) {
6741
+ getEthereumProvider(options = {}) {
6289
6742
  const authentication = Authentication.fromStorage(this.storage);
6290
6743
  const signer = SignerManager.fromStorage();
6291
6744
  const account = Account.fromStorage(this.storage);
@@ -6298,12 +6751,10 @@ class Openfort {
6298
6751
  backendApiClients: this.backendApiClients,
6299
6752
  policyId: options.policy,
6300
6753
  });
6301
- if (options?.announceProvider) {
6302
- announceProvider({
6303
- info: openfortProviderInfo,
6304
- provider,
6305
- });
6306
- }
6754
+ announceProvider({
6755
+ info: { ...openfortProviderInfo, ...options.providerInfo },
6756
+ provider,
6757
+ });
6307
6758
  return provider;
6308
6759
  }
6309
6760
  /**
@@ -6383,7 +6834,9 @@ class Openfort {
6383
6834
  // eslint-disable-next-line no-param-reassign
6384
6835
  delete types.EIP712Domain;
6385
6836
  const account = Account.fromStorage(this.storage);
6386
- if (account && account.type === AccountType.UPGRADEABLE_V5) {
6837
+ if (account && [AccountType.UPGRADEABLE_V5,
6838
+ AccountType.UPGRADEABLE_V6,
6839
+ AccountType.ZKSYNC_UPGRADEABLE_V1].includes(account.type)) {
6387
6840
  const updatedDomain = {
6388
6841
  name: 'Openfort',
6389
6842
  version: '0.5',
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openfort/openfort-js",
3
- "version": "0.8.12",
3
+ "version": "0.8.13",
4
4
  "author": "Openfort (https://www.openfort.xyz)",
5
5
  "bugs": "https://github.com/openfort-xyz/openfort-js/issues",
6
6
  "repository": "openfort-xyz/openfort-js.git",