{"version":3,"file":"wallet-requestPermissions.cjs","sourceRoot":"","sources":["../src/wallet-requestPermissions.ts"],"names":[],"mappings":";;;AACA,mFAI6C;AAC7C,iEAA2D;AAK3D,2EASyC;AAMzC,mCAA8B;AAE9B,uCAAyE;AAE5D,QAAA,yBAAyB,GAAG;IACvC,WAAW,EAAE,CAAC,mCAAW,CAAC,kBAAkB,CAAC;IAC7C,cAAc,EAAE,gCAAgC;IAChD,SAAS,EAAE;QACT,WAAW,EAAE,IAAI;QACjB,2BAA2B,EAAE,IAAI;QACjC,iDAAiD,EAAE,IAAI;KACxD;CACF,CAAC;AAWF;;;;;;;;;;;;;GAaG;AACH,KAAK,UAAU,gCAAgC,CAC7C,GAAgE,EAChE,GAAiC,EACjC,KAAqC,EACrC,GAA6B,EAC7B,EACE,WAAW,EACX,2BAA2B,EAC3B,iDAAiD,GASlD;IAED,MAAM,EAAE,MAAM,EAAE,GAAG,GAAG,CAAC;IAEvB,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,IAAA,gCAAa,EAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE;QACvD,OAAO,GAAG,CAAC,IAAA,qCAAa,EAAC,EAAE,IAAI,EAAE,EAAE,OAAO,EAAE,GAAG,EAAE,EAAE,CAAC,CAAC,CAAC;KACvD;IAED,IAAI,CAAC,oBAAoB,CAAC,GAAG,MAAM,CAAC;IACpC,OAAO,oBAAoB,CAAC,yDAA6B,CAAC,CAAC;IAE3D,MAAM,2BAA2B,GAE7B,IAAA,aAAI,EAAC,oBAAoB,EAAE;QAC7B,yBAAiB,CAAC,WAAW;QAC7B,sBAAc,CAAC,eAAe;KAC/B,CAAC,CAAC;IACH,OAAO,oBAAoB,CAAC,yBAAiB,CAAC,WAAW,CAAC,CAAC;IAC3D,OAAO,oBAAoB,CAAC,sBAAc,CAAC,eAAe,CAAC,CAAC;IAE5D,MAAM,8BAA8B,GAClC,MAAM,CAAC,IAAI,CAAC,2BAA2B,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC;IAEtD,IAAI,8BAA8B,EAAE;QAClC,MAAM,gBAAgB,GAAG,iDAAiD,CACxE,2BAA2B,CAC5B,CAAC;QACF,oBAAoB,GAAG,EAAE,GAAG,oBAAoB,EAAE,GAAG,gBAAgB,EAAE,CAAC;KACzE;IAED,IAAI,kBAAkB,GAAuB,EAAE,CAAC;IAEhD,MAAM,CAAC,wBAAwB,CAAC,GAC9B,MAAM,2BAA2B,CAAC,oBAAoB,CAAC,CAAC;IAE1D,kBAAkB,GAAG,EAAE,GAAG,wBAAwB,EAAE,CAAC;IAErD,IAAI,8BAA8B,EAAE;QAClC,MAAM,eAAe,GAAG,kBAAkB,CAAC,yDAA6B,CAAC,CAAC;QAE1E,IAAI,CAAC,eAAe,EAAE;YACpB,MAAM,IAAI,KAAK,CACb,kBAAkB,yDAA6B,cAAc,CAC9D,CAAC;SACH;QAED,MAAM,iBAAiB,GAAG,eAAe,CAAC,OAAO,EAAE,IAAI,CACrD,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC,IAAI,KAAK,4CAAgB,CACxC,EAAE,KAAsC,CAAC;QAC1C,IAAI,CAAC,iBAAiB,EAAE;YACtB,MAAM,IAAI,KAAK,CACb,kBAAkB,4CAAgB,eAAe,yDAA6B,cAAc,CAC7F,CAAC;SACH;QAED,OAAO,kBAAkB,CAAC,yDAA6B,CAAC,CAAC;QACzD,mFAAmF;QACnF,4DAA4D;QAC5D,MAAM,WAAW,GAAG,WAAW,EAAE,CAAC;QAElC,kBAAkB,CAAC,yBAAiB,CAAC,WAAW,CAAC,GAAG;YAClD,GAAG,eAAe;YAClB,gBAAgB,EAAE,yBAAiB,CAAC,WAAW;YAC/C,OAAO,EAAE;gBACP;oBACE,IAAI,EAAE,mBAAW,CAAC,wBAAwB;oBAC1C,KAAK,EAAE,WAAW;iBACnB;aACF;SACF,CAAC;QAEF,MAAM,WAAW,GAAG,IAAA,mDAAuB,EAAC,iBAAiB,CAAC,CAAC;QAE/D,IAAI,WAAW,CAAC,MAAM,GAAG,CAAC,EAAE;YAC1B,kBAAkB,CAAC,sBAAc,CAAC,eAAe,CAAC,GAAG;gBACnD,GAAG,eAAe;gBAClB,gBAAgB,EAAE,sBAAc,CAAC,eAAe;gBAChD,OAAO,EAAE;oBACP;wBACE,IAAI,EAAE,mBAAW,CAAC,wBAAwB;wBAC1C,KAAK,EAAE,WAAW;qBACnB;iBACF;aACF,CAAC;SACH;KACF;IAED,GAAG,CAAC,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,kBAAkB,CAAC,CAAC,MAAM,CACnD,CACE,UAAqE,EACR,EAAE,CAC/D,UAAU,KAAK,SAAS,CAC3B,CAAC;IACF,OAAO,GAAG,EAAE,CAAC;AACf,CAAC","sourcesContent":["import type { Caip25CaveatValue } from '@metamask/chain-agnostic-permission';\nimport {\n  Caip25CaveatType,\n  Caip25EndowmentPermissionName,\n  getPermittedEthChainIds,\n} from '@metamask/chain-agnostic-permission';\nimport { isPlainObject } from '@metamask/controller-utils';\nimport type {\n  AsyncJsonRpcEngineNextCallback,\n  JsonRpcEngineEndCallback,\n} from '@metamask/json-rpc-engine';\nimport {\n  type Caveat,\n  type CaveatSpecificationConstraint,\n  invalidParams,\n  MethodNames,\n  type PermissionController,\n  type PermissionSpecificationConstraint,\n  type RequestedPermissions,\n  type ValidPermission,\n} from '@metamask/permission-controller';\nimport type {\n  Json,\n  JsonRpcRequest,\n  PendingJsonRpcResponse,\n} from '@metamask/utils';\nimport { pick } from 'lodash';\n\nimport { CaveatTypes, EndowmentTypes, RestrictedMethods } from './types';\n\nexport const requestPermissionsHandler = {\n  methodNames: [MethodNames.RequestPermissions],\n  implementation: requestPermissionsImplementation,\n  hookNames: {\n    getAccounts: true,\n    requestPermissionsForOrigin: true,\n    getCaip25PermissionFromLegacyPermissionsForOrigin: true,\n  },\n};\n\ntype AbstractPermissionController = PermissionController<\n  PermissionSpecificationConstraint,\n  CaveatSpecificationConstraint\n>;\n\ntype GrantedPermissions = Awaited<\n  ReturnType<AbstractPermissionController['requestPermissions']>\n>[0];\n\n/**\n * Request Permissions implementation to be used in JsonRpcEngine middleware, specifically for `wallet_requestPermissions` RPC method.\n * The request object is expected to contain a CAIP-25 endowment permission.\n *\n * @param req - The JsonRpcEngine request\n * @param res - The JsonRpcEngine result object\n * @param _next - JsonRpcEngine next() callback - unused\n * @param end - JsonRpcEngine end() callback\n * @param options - Method hooks passed to the method implementation\n * @param options.getAccounts - A hook that returns the permitted eth accounts for the origin sorted by lastSelected.\n * @param options.getCaip25PermissionFromLegacyPermissionsForOrigin - A hook that returns a CAIP-25 permission from a legacy `eth_accounts` and `endowment:permitted-chains` permission.\n * @param options.requestPermissionsForOrigin - A hook that requests CAIP-25 permissions for the origin.\n * @returns Nothing.\n */\nasync function requestPermissionsImplementation(\n  req: JsonRpcRequest<[RequestedPermissions]> & { origin: string },\n  res: PendingJsonRpcResponse<Json>,\n  _next: AsyncJsonRpcEngineNextCallback,\n  end: JsonRpcEngineEndCallback,\n  {\n    getAccounts,\n    requestPermissionsForOrigin,\n    getCaip25PermissionFromLegacyPermissionsForOrigin,\n  }: {\n    getAccounts: () => string[];\n    requestPermissionsForOrigin: (\n      requestedPermissions: RequestedPermissions,\n    ) => Promise<[GrantedPermissions]>;\n    getCaip25PermissionFromLegacyPermissionsForOrigin: (\n      requestedPermissions?: RequestedPermissions,\n    ) => RequestedPermissions;\n  },\n) {\n  const { params } = req;\n\n  if (!Array.isArray(params) || !isPlainObject(params[0])) {\n    return end(invalidParams({ data: { request: req } }));\n  }\n\n  let [requestedPermissions] = params;\n  delete requestedPermissions[Caip25EndowmentPermissionName];\n\n  const caip25EquivalentPermissions: Partial<\n    Pick<RequestedPermissions, 'eth_accounts' | 'endowment:permitted-chains'>\n  > = pick(requestedPermissions, [\n    RestrictedMethods.EthAccounts,\n    EndowmentTypes.PermittedChains,\n  ]);\n  delete requestedPermissions[RestrictedMethods.EthAccounts];\n  delete requestedPermissions[EndowmentTypes.PermittedChains];\n\n  const hasCaip25EquivalentPermissions =\n    Object.keys(caip25EquivalentPermissions).length > 0;\n\n  if (hasCaip25EquivalentPermissions) {\n    const caip25Permission = getCaip25PermissionFromLegacyPermissionsForOrigin(\n      caip25EquivalentPermissions,\n    );\n    requestedPermissions = { ...requestedPermissions, ...caip25Permission };\n  }\n\n  let grantedPermissions: GrantedPermissions = {};\n\n  const [frozenGrantedPermissions] =\n    await requestPermissionsForOrigin(requestedPermissions);\n\n  grantedPermissions = { ...frozenGrantedPermissions };\n\n  if (hasCaip25EquivalentPermissions) {\n    const caip25Endowment = grantedPermissions[Caip25EndowmentPermissionName];\n\n    if (!caip25Endowment) {\n      throw new Error(\n        `could not find ${Caip25EndowmentPermissionName} permission.`,\n      );\n    }\n\n    const caip25CaveatValue = caip25Endowment.caveats?.find(\n      ({ type }) => type === Caip25CaveatType,\n    )?.value as Caip25CaveatValue | undefined;\n    if (!caip25CaveatValue) {\n      throw new Error(\n        `could not find ${Caip25CaveatType} in granted ${Caip25EndowmentPermissionName} permission.`,\n      );\n    }\n\n    delete grantedPermissions[Caip25EndowmentPermissionName];\n    // We cannot derive correct eth_accounts value directly from the CAIP-25 permission\n    // because the accounts will not be in order of lastSelected\n    const ethAccounts = getAccounts();\n\n    grantedPermissions[RestrictedMethods.EthAccounts] = {\n      ...caip25Endowment,\n      parentCapability: RestrictedMethods.EthAccounts,\n      caveats: [\n        {\n          type: CaveatTypes.RestrictReturnedAccounts,\n          value: ethAccounts,\n        },\n      ],\n    };\n\n    const ethChainIds = getPermittedEthChainIds(caip25CaveatValue);\n\n    if (ethChainIds.length > 0) {\n      grantedPermissions[EndowmentTypes.PermittedChains] = {\n        ...caip25Endowment,\n        parentCapability: EndowmentTypes.PermittedChains,\n        caveats: [\n          {\n            type: CaveatTypes.RestrictNetworkSwitching,\n            value: ethChainIds,\n          },\n        ],\n      };\n    }\n  }\n\n  res.result = Object.values(grantedPermissions).filter(\n    (\n      permission: ValidPermission<string, Caveat<string, Json>> | undefined,\n    ): permission is ValidPermission<string, Caveat<string, Json>> =>\n      permission !== undefined,\n  );\n  return end();\n}\n"]}