{"version":3,"file":"index.cjs","sourceRoot":"","sources":["../../../src/common/endowments/index.ts"],"names":[],"mappings":";;;;;;AAAA,qDAAiD;AAEjD,2CAA8C;AAO9C,0FAA6D;AAE7D;;GAEG;AACH,MAAM,oBAAoB,GAAG,IAAA,gCAAqB,GAAE,CAAC;AAErD;;;;GAIG;AACH,MAAM,kBAAkB,GAAG,oBAAoB,CAAC,MAAM,CAAC,CAAC,SAAS,EAAE,OAAO,EAAE,EAAE;IAC5E,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE;QAC7B,SAAS,CAAC,GAAG,CAAC,IAAI,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC;IACvC,CAAC,CAAC,CAAC;IACH,OAAO,SAAS,CAAC;AACnB,CAAC,EAAE,IAAI,GAAG,EAAyE,CAAC,CAAC;AAErF;;;;;;;;;;;;;;GAcG;AACH,SAAgB,gBAAgB,CAAC,EAC/B,IAAI,EACJ,QAAQ,EACR,MAAM,EACN,UAAU,EACV,MAAM,GAOP;IACC,MAAM,oBAAoB,GAA4B,EAAE,CAAC;IAEzD,0EAA0E;IAC1E,yEAAyE;IACzE,2CAA2C;IAC3C,MAAM,MAAM,GAAG,UAAU,CAAC,MAAM,CAI9B,CAAC,EAAE,aAAa,EAAE,SAAS,EAAE,EAAE,aAAa,EAAE,EAAE;QAC9C,oEAAoE;QACpE,IAAI,kBAAkB,CAAC,GAAG,CAAC,aAAa,CAAC,EAAE,CAAC;YAC1C,IAAI,CAAC,IAAA,mBAAW,EAAC,oBAAoB,EAAE,aAAa,CAAC,EAAE,CAAC;gBACtD,uEAAuE;gBACvE,gEAAgE;gBAChE,wEAAwE;gBACxE,4CAA4C;gBAC5C,2DAA2D;gBAE3D,mEAAmE;gBACnE,oEAAoE;gBACpE,MAAM,EAAE,gBAAgB,EAAE,GAAG,SAAS,EAAE,GAAG,kBAAkB,CAAC,GAAG,CAC/D,aAAa,CACb,CAAC,EAAE,WAAW,EAAE,SAAS,MAAM,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC;gBAC/C,MAAM,CAAC,MAAM,CAAC,oBAAoB,EAAE,SAAS,CAAC,CAAC;gBAC/C,IAAI,gBAAgB,EAAE,CAAC;oBACrB,SAAS,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC;gBACnC,CAAC;YACH,CAAC;YACD,aAAa,CAAC,aAAa,CAAC,GAAG,oBAAoB,CAAC,aAAa,CAAC,CAAC;QACrE,CAAC;aAAM,IAAI,aAAa,KAAK,UAAU,EAAE,CAAC;YACxC,iDAAiD;YACjD,aAAa,CAAC,aAAa,CAAC,GAAG,QAAQ,CAAC;QAC1C,CAAC;aAAM,CAAC;YACN,uEAAuE;YACvE,oCAAoC;YACpC,MAAM,sBAAS,CAAC,QAAQ,CAAC,uBAAuB,aAAa,IAAI,CAAC,CAAC;QACrE,CAAC;QACD,OAAO,EAAE,aAAa,EAAE,SAAS,EAAE,CAAC;IACtC,CAAC,EACD;QACE,aAAa,EAAE,EAAE,IAAI,EAAE;QACvB,SAAS,EAAE,EAAE;KACd,CACF,CAAC;IAEF,MAAM,QAAQ,GAAG,KAAK,IAAI,EAAE;QAC1B,MAAM,OAAO,CAAC,GAAG,CACf,MAAM,CAAC,SAAS,CAAC,GAAG,CAAC,KAAK,EAAE,gBAAgB,EAAE,EAAE,CAAC,gBAAgB,EAAE,CAAC,CACrE,CAAC;IACJ,CAAC,CAAC;IACF,OAAO,EAAE,UAAU,EAAE,MAAM,CAAC,aAAa,EAAE,QAAQ,EAAE,CAAC;AACxD,CAAC;AAjED,4CAiEC","sourcesContent":["import { rpcErrors } from '@metamask/rpc-errors';\nimport type { SnapsEthereumProvider, SnapsProvider } from '@metamask/snaps-sdk';\nimport { hasProperty } from '@metamask/utils';\n\nimport type {\n  EndowmentFactoryOptions,\n  EndowmentFactoryResult,\n  NotifyFunction,\n} from './commonEndowmentFactory';\nimport buildCommonEndowments from './commonEndowmentFactory';\n\n/**\n * Retrieve consolidated endowment factories for common endowments.\n */\nconst registeredEndowments = buildCommonEndowments();\n\n/**\n * A map of endowment names to their factory functions. Some endowments share\n * the same factory function, but we only call each factory once for each snap.\n * See {@link createEndowments} for details.\n */\nconst endowmentFactories = registeredEndowments.reduce((factories, builder) => {\n  builder.names.forEach((name) => {\n    factories.set(name, builder.factory);\n  });\n  return factories;\n}, new Map<string, (options?: EndowmentFactoryOptions) => EndowmentFactoryResult>());\n\n/**\n * Gets the endowments for a particular Snap. Some endowments, like `setTimeout`\n * and `clearTimeout`, must be attenuated so that they can only affect behavior\n * within the Snap's own realm. Therefore, we use factory functions to create\n * such attenuated / modified endowments. Otherwise, the value that's on the\n * root realm global will be used.\n *\n * @param options - An options bag.\n * @param options.snap - The Snaps global API object.\n * @param options.ethereum - The Snap's EIP-1193 provider object.\n * @param options.snapId - The id of the snap that will use the created endowments.\n * @param options.endowments - The list of endowments to provide to the snap.\n * @param options.notify - A reference to the notify function of the snap executor.\n * @returns An object containing the Snap's endowments.\n */\nexport function createEndowments({\n  snap,\n  ethereum,\n  snapId,\n  endowments,\n  notify,\n}: {\n  snap: SnapsProvider;\n  ethereum: SnapsEthereumProvider;\n  snapId: string;\n  endowments: string[];\n  notify: NotifyFunction;\n}): { endowments: Record<string, unknown>; teardown: () => Promise<void> } {\n  const attenuatedEndowments: Record<string, unknown> = {};\n\n  // TODO: All endowments should be hardened to prevent covert communication\n  // channels. Hardening the returned objects breaks tests elsewhere in the\n  // monorepo, so further research is needed.\n  const result = endowments.reduce<{\n    allEndowments: Record<string, unknown>;\n    teardowns: (() => Promise<void> | void)[];\n  }>(\n    ({ allEndowments, teardowns }, endowmentName) => {\n      // First, check if the endowment has a factory, and default to that.\n      if (endowmentFactories.has(endowmentName)) {\n        if (!hasProperty(attenuatedEndowments, endowmentName)) {\n          // Call the endowment factory for the current endowment. If the factory\n          // creates multiple endowments, they will all be assigned to the\n          // `attenuatedEndowments` object, but will only be passed on to the snap\n          // if explicitly listed among its endowment.\n          // This may not have an actual use case, but, safety first.\n\n          // We just confirmed that endowmentFactories has the specified key.\n          // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n          const { teardownFunction, ...endowment } = endowmentFactories.get(\n            endowmentName,\n          )!({ sourceLabel: `Snap: ${snapId}`, notify });\n          Object.assign(attenuatedEndowments, endowment);\n          if (teardownFunction) {\n            teardowns.push(teardownFunction);\n          }\n        }\n        allEndowments[endowmentName] = attenuatedEndowments[endowmentName];\n      } else if (endowmentName === 'ethereum') {\n        // Special case for adding the EIP-1193 provider.\n        allEndowments[endowmentName] = ethereum;\n      } else {\n        // If we get to this point, we've been passed an endowment that doesn't\n        // exist in our current environment.\n        throw rpcErrors.internal(`Unknown endowment: \"${endowmentName}\".`);\n      }\n      return { allEndowments, teardowns };\n    },\n    {\n      allEndowments: { snap },\n      teardowns: [],\n    },\n  );\n\n  const teardown = async () => {\n    await Promise.all(\n      result.teardowns.map(async (teardownFunction) => teardownFunction()),\n    );\n  };\n  return { endowments: result.allEndowments, teardown };\n}\n"]}