@metamask/snaps-controllers 14.0.2 → 14.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"file":"SnapController.mjs","sourceRoot":"","sources":["../../src/snaps/SnapController.ts"],"names":[],"mappings":"AASA,OAAO,EAAE,cAAc,EAAE,kCAAkC;AAsB3D,OAAO,EAAE,WAAW,EAAE,wCAAwC;AAC9D,OAAO,EAAE,SAAS,EAAE,6BAA6B;AAEjD,OAAO,EACL,0BAA0B,EAC1B,uBAAuB,EACvB,iBAAiB,EACjB,cAAc,EACd,uBAAuB,EACvB,mBAAmB,EACnB,sBAAsB,EACtB,oBAAoB,EACpB,iBAAiB,EAClB,oCAAoC;AAiBrC,OAAO,EACL,qBAAqB,EACrB,eAAe,EACf,4BAA4B,EAC7B,4BAA4B;AAe7B,OAAO,EACL,UAAU,EACV,kBAAkB,EAClB,oBAAoB,EACpB,mBAAmB,EACnB,kBAAkB,EAClB,8BAA8B,EAC9B,mBAAmB,EACnB,WAAW,EACX,eAAe,EACf,QAAQ,EACR,iBAAiB,EACjB,2BAA2B,EAC3B,yBAAyB,EACzB,mBAAmB,EACnB,cAAc,EACd,UAAU,EACV,gBAAgB,EAChB,WAAW,EACX,wBAAwB,EACxB,6BAA6B,EAC7B,WAAW,EACX,gBAAgB,EAChB,0BAA0B,EAC1B,wBAAwB,EACxB,aAAa,EACb,4BAA4B,EAC5B,UAAU,EACV,oCAAoC,EACpC,gCAAgC,EAChC,gCAAgC,EACjC,8BAA8B;AAU/B,OAAO,EACL,WAAW,EACX,MAAM,EACN,sBAAsB,EACtB,YAAY,EACZ,QAAQ,EACR,OAAO,EACP,SAAS,EACT,WAAW,EACX,cAAc,EACd,eAAe,EACf,kBAAkB,EAClB,qBAAqB,EACrB,SAAS,EACT,qBAAqB,EACtB,wBAAwB;AAEzB,OAAO,EAAE,aAAa,EAAE,SAAS,EAAE,oBAAoB;AACvD,OAAO,EAAE,KAAK,EAAE,oBAAoB;AAEpC,OAAO,EAAE,MAAM,EAAE,eAAe;AAChC,OAAO,EAAE,EAAE,EAAE,GAAG,EAAE,eAAe;AAEjC,OAAO,EACL,mBAAmB,EACnB,oBAAoB,EACpB,wCAAwC,EACxC,eAAe,EACf,sBAAsB,EACvB,wBAAoB;AAErB,OAAO,EAAE,kBAAkB,EAAE,6BAAmB;AAShD,OAAO,EAAE,mBAAmB,EAAE,6BAAmB;AACjD,OAAO,EAAE,gBAAgB,EAAE,wBAAoB;AAC/C,OAAO,EAAE,KAAK,EAAE,oBAAgB;AAChC,OAAO,EAAE,WAAW,EAAE,eAAe,EAAE,mBAAe;AAEtD,OAAO,EAAE,GAAG,EAAE,uBAAmB;AAcjC,OAAO,EACL,oBAAoB,EACpB,SAAS,EACT,WAAW,EACX,eAAe,EACf,OAAO,EACP,gBAAgB,EAChB,WAAW,EACX,kBAAkB,EACnB,qBAAiB;AAElB,MAAM,CAAC,MAAM,cAAc,GAAG,gBAAgB,CAAC;AAE/C,qCAAqC;AACrC,MAAM,CAAC,MAAM,qBAAqB,GAAG,oBAAoB,CAAC;AAC1D,MAAM,CAAC,MAAM,oBAAoB,GAAG,mBAAmB,CAAC;AACxD,MAAM,CAAC,MAAM,oBAAoB,GAAG,0BAA0B,CAAC;AAE/D,MAAM,yBAAyB,GAAG,IAAI,GAAG,CAAsB;IAC7D,oBAAoB;IACpB,IAAI;IACJ,SAAS;IACT,SAAS;IACT,SAAS;CACV,CAAC,CAAC;AA+nBH,MAAM,YAAY,GAAwB;IACxC,KAAK,EAAE,EAAE;IACT,UAAU,EAAE,EAAE;IACd,qBAAqB,EAAE,EAAE;CAC1B,CAAC;AAEF;;;;;GAKG;AACH,SAAS,YAAY,CAAC,IAAU;IAC9B,MAAM,aAAa,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,MAAM,CAC5C,CAAC,UAAU,EAAE,GAAG,EAAE,EAAE;QAClB,IAAI,yBAAyB,CAAC,GAAG,CAAC,GAAU,CAAC,EAAE,CAAC;YAC9C,UAAU,CAAC,GAA0B,CAAC,GAAG,IAAI,CAC3C,GAA0B,CACpB,CAAC;QACX,CAAC;QAED,OAAO,UAAU,CAAC;IACpB,CAAC,EACD,EAAE,CACH,CAAC;IAEF,OAAO,aAA8B,CAAC;AACxC,CAAC;AAED;;;;;GAKG;AAEH,MAAM,OAAO,cAAe,SAAQ,cAInC;IACU,oBAAoB,CAA+B;IAEnD,mBAAmB,CAAW;IAE9B,gCAAgC,CAAW;IAE3C,oBAAoB,CAAyB;IAE7C,aAAa,CAAe;IAE5B,cAAc,CAAe;IAE7B,sBAAsB,CAAS;IAE/B,YAAY,CAAS;IAE9B,6DAA6D;IAC7D,gDAAgD;IAC/B,cAAc,CAAS;IAE/B,UAAU,CAAyB;IAEnC,gBAAgB,CAA4B;IAE5C,gBAAgB,CAA4B;IAE5C,mBAAmB,CAAqC;IAExD,mBAAmB,CAA4B;IAE/C,iBAAiB,CAA+B;IAEhD,kBAAkB,CAAgC;IAE3D,4BAA4B,CAAU;IAEtC,cAAc,CAIZ;IAEO,kBAAkB,CAA4B;IAE9C,WAAW,CAAiB;IAE5B,gBAAgB,CAAsC;IAE/D,YAAY,EACV,mBAAmB,EACnB,SAAS,EACT,KAAK,EACL,kBAAkB,GAAG,CAAC,cAAc,CAAC,EACrC,+BAA+B,GAAG,EAAE,EACpC,mBAAmB,GAAG,EAAE,EACxB,qBAAqB,GAAG,cAAc,CAAC,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,EAC1D,WAAW,GAAG,cAAc,CAAC,EAAE,EAAE,QAAQ,CAAC,MAAM,CAAC,EACjD,cAAc,GAAG,cAAc,CAAC,EAAE,EAAE,QAAQ,CAAC,MAAM,CAAC,EACpD,aAAa,GAAG,UAAU,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,EAChD,YAAY,GAAG,EAAE,EACjB,kBAAkB,EAAE,0BAA0B,GAAG,kBAAkB,EACnE,iBAAiB,GAAG,IAAI,EACxB,SAAS,EACT,eAAe,EACf,eAAe,GAAG,GAAG,EAAE,CAAC,CAAC,EAAE,CAAC,EAC5B,kBAAkB,EAClB,UAAU,GACS;QACnB,KAAK,CAAC;YACJ,SAAS;YACT,QAAQ,EAAE;gBACR,UAAU,EAAE;oBACV,OAAO,EAAE,IAAI;oBACb,SAAS,EAAE,KAAK;iBACjB;gBACD,qBAAqB,EAAE;oBACrB,OAAO,EAAE,IAAI;oBACb,SAAS,EAAE,KAAK;iBACjB;gBACD,KAAK,EAAE;oBACL,OAAO,EAAE,CAAC,KAAK,EAAE,EAAE;wBACjB,OAAO,CACL,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC;4BAClB,gEAAgE;4BAChE,kEAAkE;6BACjE,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,KAAK,UAAU,CAAC,UAAU,CAAC;6BACvD,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE;4BACZ,OAAO;gCACL,GAAG,IAAI;gCACP,4DAA4D;gCAC5D,MAAM,EAAE,UAAU,CAAC,OAAO;6BAC3B,CAAC;wBACJ,CAAC,CAAC;6BACD,MAAM,CAAC,CAAC,IAA0B,EAAE,IAAI,EAAE,EAAE;4BAC3C,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC;4BACrB,OAAO,IAAI,CAAC;wBACd,CAAC,EAAE,EAAE,CAAC,CACT,CAAC;oBACJ,CAAC;oBACD,SAAS,EAAE,KAAK;iBACjB;aACF;YACD,IAAI,EAAE,cAAc;YACpB,KAAK,EAAE;gBACL,GAAG,YAAY;gBACf,GAAG,KAAK;aACT;SACF,CAAC,CAAC;QAEH,IAAI,CAAC,oBAAoB,GAAG,mBAAmB,CAAC;QAChD,IAAI,CAAC,mBAAmB,GAAG,kBAAkB,CAAC;QAC9C,IAAI,CAAC,gCAAgC,GAAG,+BAA+B,CAAC;QACxE,IAAI,CAAC,oBAAoB,GAAG,mBAAmB,CAAC;QAChD,IAAI,CAAC,aAAa,GAAG,YAAY,CAAC;QAClC,IAAI,CAAC,cAAc,GAAG,aAAa,CAAC;QACpC,IAAI,CAAC,sBAAsB,GAAG,qBAAqB,CAAC;QACpD,IAAI,CAAC,YAAY,GAAG,WAAW,CAAC;QAChC,IAAI,CAAC,cAAc,GAAG,cAAc,CAAC;QACrC,IAAI,CAAC,mBAAmB,GAAG,0BAA0B,CAAC;QACtD,IAAI,CAAC,UAAU,GAAG,SAAS,CAAC;QAC5B,IAAI,CAAC,gBAAgB,GAAG,eAAe,CAAC;QACxC,IAAI,CAAC,gBAAgB,GAAG,eAAe,CAAC;QACxC,IAAI,CAAC,mBAAmB,GAAG,kBAAkB,CAAC;QAC9C,IAAI,CAAC,kBAAkB,GAAG,iBAAiB,CAAC;QAC5C,IAAI,CAAC,qBAAqB,GAAG,IAAI,CAAC,qBAAqB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACnE,IAAI,CAAC,kBAAkB,GAAG,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC7D,IAAI,CAAC,mBAAmB,GAAG,IAAI,CAAC,mBAAmB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC/D,IAAI,CAAC,kBAAkB,GAAG,IAAI,GAAG,EAAE,CAAC;QACpC,IAAI,CAAC,iBAAiB,GAAG,IAAI,GAAG,EAAE,CAAC;QACnC,IAAI,CAAC,WAAW,GAAG,UAAU,CAAC;QAE9B,IAAI,CAAC,yBAAyB,EAAE,CAAC;QAEjC,sDAAsD;QACtD,IAAI,CAAC,eAAe,CAAC,SAAS,CAC5B,iCAAiC,EACjC,IAAI,CAAC,qBAAqB,CAC3B,CAAC;QAEF,IAAI,CAAC,eAAe,CAAC,SAAS,CAC5B,kCAAkC,EAClC,IAAI,CAAC,kBAAkB,CACxB,CAAC;QAEF,IAAI,CAAC,eAAe,CAAC,SAAS,CAC5B,mCAAmC,EACnC,IAAI,CAAC,mBAAmB,CACzB,CAAC;QACF,qDAAqD;QAErD,IAAI,CAAC,eAAe,CAAC,SAAS,CAC5B,8BAA8B,EAC9B,CAAC,EAAE,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE;YACjB,IAAI,CAAC,kBAAkB,CAAC,MAAM,EAAE,EAAE,EAAE,WAAW,CAAC,SAAS,CAAC,CAAC,KAAK,CAC9D,CAAC,KAAK,EAAE,EAAE;gBACR,QAAQ,CACN,6DAA6D,EAAE,MAAM,eAAe,CAClF,KAAK,CACN,EAAE,CACJ,CAAC;YACJ,CAAC,CACF,CAAC;QACJ,CAAC,CACF,CAAC;QAEF,IAAI,CAAC,eAAe,CAAC,SAAS,CAC5B,4BAA4B,EAC5B,CAAC,EAAE,EAAE,EAAE,EAAE,WAAW,EAAE,MAAM,EAAE,EAAE;YAC9B,IAAI,CAAC,kBAAkB,CAAC,MAAM,EAAE,EAAE,EAAE,WAAW,CAAC,QAAQ,CAAC,CAAC,KAAK,CAC7D,CAAC,KAAK,EAAE,EAAE;gBACR,QAAQ,CACN,4DAA4D,EAAE,MAAM,eAAe,CACjF,KAAK,CACN,EAAE,CACJ,CAAC;YACJ,CAAC,CACF,CAAC;QACJ,CAAC,CACF,CAAC;QAEF,IAAI,CAAC,eAAe,CAAC,SAAS,CAC5B,wBAAwB,EACxB,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,CAC5B,CAAC;QAEF,IAAI,CAAC,uBAAuB,EAAE,CAAC;QAC/B,IAAI,CAAC,wBAAwB,EAAE,CAAC;QAEhC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,EAAE,KAAK,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE,CACtD,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,EAAE,CAAC,CAC5B,CAAC;QAEF,IAAI,IAAI,CAAC,kBAAkB,EAAE,CAAC;YAC5B,IAAI,CAAC,wBAAwB,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC;QACzD,CAAC;QAED,IAAI,CAAC,gBAAgB,GAAG,gBAAgB,CACtC,CAAC,MAAc,EAAE,OAAe,EAAE,OAAgB,EAAE,MAAc,EAAE,EAAE;YACpE,MAAM,YAAY,GAAG,IAAI,CAAC,eAAe,CAAC,IAAI,CAC5C,2BAA2B,EAC3B,MAAM,CACP,CAAC;YACF,IAAI,CAAC,WAAW,CAAC;gBACf,KAAK,EAAE,kBAAkB;gBACzB,QAAQ,EAAE,OAAO;gBACjB,UAAU,EAAE;oBACV,gEAAgE;oBAChE,OAAO,EAAE,MAAM;oBACf,MAAM,EAAE,OAAO;oBACf,gEAAgE;oBAChE,aAAa,EAAE,YAAY,EAAE,QAAQ;oBACrC,OAAO;oBACP,MAAM;iBACP;aACF,CAAC,CAAC;QACL,CAAC,CACF,CAAC;IACJ,CAAC;IAED;;;;;OAKG;IACH,4FAA4F;IAC5F,iGAAiG;IACjG,gFAAgF;IAChF,uBAAuB;QACrB,MAAM,YAAY,GAAG,CAAC,EAAE,MAAM,EAAiB,EAAE,EAAE;YACjD,OAAO,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC;QACxC,CAAC,CAAC;QAEF,MAAM,YAAY,GAId;YACF,OAAO,EAAE,UAAU,CAAC,UAAU;YAC9B,MAAM,EAAE;gBACN,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE;oBACvB,EAAE,EAAE;wBACF,CAAC,gBAAgB,CAAC,KAAK,CAAC,EAAE;4BACxB,MAAM,EAAE,UAAU,CAAC,OAAO;4BAC1B,IAAI,EAAE,YAAY;yBACnB;qBACF;iBACF;gBACD,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE;oBACrB,EAAE,EAAE;wBACF,CAAC,gBAAgB,CAAC,KAAK,CAAC,EAAE;4BACxB,MAAM,EAAE,UAAU,CAAC,OAAO;4BAC1B,IAAI,EAAE,YAAY;yBACnB;wBACD,CAAC,gBAAgB,CAAC,IAAI,CAAC,EAAE,UAAU,CAAC,OAAO;qBAC5C;iBACF;gBACD,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE;oBACpB,EAAE,EAAE;wBACF,CAAC,gBAAgB,CAAC,IAAI,CAAC,EAAE,UAAU,CAAC,OAAO;wBAC3C,CAAC,gBAAgB,CAAC,KAAK,CAAC,EAAE,UAAU,CAAC,OAAO;qBAC7C;iBACF;gBACD,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE;oBACpB,EAAE,EAAE;wBACF,CAAC,gBAAgB,CAAC,KAAK,CAAC,EAAE;4BACxB,MAAM,EAAE,UAAU,CAAC,OAAO;4BAC1B,IAAI,EAAE,YAAY;yBACnB;wBACD,CAAC,gBAAgB,CAAC,MAAM,CAAC,EAAE,UAAU,CAAC,QAAQ;qBAC/C;iBACF;gBACD,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE;oBACpB,EAAE,EAAE;wBACF,CAAC,gBAAgB,CAAC,KAAK,CAAC,EAAE;4BACxB,MAAM,EAAE,UAAU,CAAC,OAAO;4BAC1B,IAAI,EAAE,YAAY;yBACnB;wBACD,CAAC,gBAAgB,CAAC,MAAM,CAAC,EAAE,UAAU,CAAC,QAAQ;qBAC/C;iBACF;aACF;SACF,CAAC;QACF,IAAI,CAAC,cAAc,GAAG,aAAa,CAAC,YAAY,CAAC,CAAC;QAClD,eAAe,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;IACvC,CAAC;IAED;;;OAGG;IACH,wBAAwB;QACtB,IAAI,CAAC,eAAe,CAAC,qBAAqB,CACxC,GAAG,cAAc,OAAO,EACxB,CAAC,GAAG,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,CAChC,CAAC;QAEF,IAAI,CAAC,eAAe,CAAC,qBAAqB,CACxC,GAAG,cAAc,iBAAiB,EAClC,CAAC,GAAG,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,cAAc,CAAC,GAAG,IAAI,CAAC,CAC1C,CAAC;QAEF,IAAI,CAAC,eAAe,CAAC,qBAAqB,CACxC,GAAG,cAAc,MAAM,EACvB,CAAC,GAAG,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,CAC/B,CAAC;QAEF,IAAI,CAAC,eAAe,CAAC,qBAAqB,CACxC,GAAG,cAAc,eAAe,EAChC,KAAK,EAAE,GAAG,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,YAAY,CAAC,GAAG,IAAI,CAAC,CAC9C,CAAC;QAEF,IAAI,CAAC,eAAe,CAAC,qBAAqB,CACxC,GAAG,cAAc,gBAAgB,EACjC,KAAK,EAAE,GAAG,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,aAAa,CAAC,GAAG,IAAI,CAAC,CAC/C,CAAC;QAEF,IAAI,CAAC,eAAe,CAAC,qBAAqB,CACxC,GAAG,cAAc,MAAM,EACvB,CAAC,GAAG,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,CAC/B,CAAC;QAEF,IAAI,CAAC,eAAe,CAAC,qBAAqB,CACxC,GAAG,cAAc,qBAAqB,EACtC,KAAK,IAAI,EAAE,CAAC,IAAI,CAAC,kBAAkB,EAAE,CACtC,CAAC;QAEF,IAAI,CAAC,eAAe,CAAC,qBAAqB,CACxC,GAAG,cAAc,kBAAkB,EACnC,KAAK,EAAE,GAAG,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,eAAe,CAAC,GAAG,IAAI,CAAC,CACjD,CAAC;QAEF,IAAI,CAAC,eAAe,CAAC,qBAAqB,CACxC,GAAG,cAAc,SAAS,EAC1B,CAAC,GAAG,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,IAAI,CAAC,CACtC,CAAC;QAEF,IAAI,CAAC,eAAe,CAAC,qBAAqB,CACxC,GAAG,cAAc,UAAU,EAC3B,KAAK,EAAE,GAAG,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,WAAW,CAAC,GAAG,IAAI,CAAC,CAC7C,CAAC;QAEF,IAAI,CAAC,eAAe,CAAC,qBAAqB,CACxC,GAAG,cAAc,SAAS,EAC1B,KAAK,EAAE,GAAG,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,IAAI,CAAC,CAC5C,CAAC;QAEF,IAAI,CAAC,eAAe,CAAC,qBAAqB,CACxC,GAAG,cAAc,eAAe,EAChC,CAAC,GAAG,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,iBAAiB,CAAC,GAAG,IAAI,CAAC,CAC7C,CAAC;QAEF,IAAI,CAAC,eAAe,CAAC,qBAAqB,CACxC,GAAG,cAAc,UAAU,EAC3B,KAAK,EAAE,GAAG,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,YAAY,CAAC,GAAG,IAAI,CAAC,CAC9C,CAAC;QAEF,IAAI,CAAC,eAAe,CAAC,qBAAqB,CACxC,GAAG,cAAc,SAAS,EAC1B,CAAC,GAAG,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,WAAW,CAAC,GAAG,IAAI,CAAC,CACvC,CAAC;QAEF,IAAI,CAAC,eAAe,CAAC,qBAAqB,CACxC,GAAG,cAAc,mBAAmB,EACpC,CAAC,GAAG,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,gBAAgB,CAAC,GAAG,IAAI,CAAC,CAC5C,CAAC;QAEF,IAAI,CAAC,eAAe,CAAC,qBAAqB,CACxC,GAAG,cAAc,4BAA4B,EAC7C,CAAC,GAAG,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,yBAAyB,CAAC,GAAG,IAAI,CAAC,CACrD,CAAC;QAEF,IAAI,CAAC,eAAe,CAAC,qBAAqB,CACxC,GAAG,cAAc,4BAA4B,EAC7C,CAAC,GAAG,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,yBAAyB,CAAC,GAAG,IAAI,CAAC,CACrD,CAAC;QAEF,IAAI,CAAC,eAAe,CAAC,qBAAqB,CACxC,GAAG,cAAc,mBAAmB,EACpC,CAAC,GAAG,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,qBAAqB,CAAC,GAAG,IAAI,CAAC,CACjD,CAAC;QAEF,IAAI,CAAC,eAAe,CAAC,qBAAqB,CACxC,GAAG,cAAc,2BAA2B,EAC5C,CAAC,GAAG,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,4BAA4B,CAAC,GAAG,IAAI,CAAC,CACxD,CAAC;QAEF,IAAI,CAAC,eAAe,CAAC,qBAAqB,CACxC,GAAG,cAAc,UAAU,EAC3B,KAAK,EAAE,GAAG,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,WAAW,CAAC,GAAG,IAAI,CAAC,CAC7C,CAAC;QAEF,IAAI,CAAC,eAAe,CAAC,qBAAqB,CACxC,GAAG,cAAc,eAAe,EAChC,KAAK,EAAE,GAAG,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,YAAY,CAAC,GAAG,IAAI,CAAC,CAC9C,CAAC;QAEF,IAAI,CAAC,eAAe,CAAC,qBAAqB,CACxC,GAAG,cAAc,2BAA2B,EAC5C,CAAC,GAAG,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,wBAAwB,CAAC,GAAG,IAAI,CAAC,CACpD,CAAC;IACJ,CAAC;IAED;;;;;OAKG;IACH,IAAI;QACF,MAAM,KAAK,GAAG,IAAI,CAAC,gBAAgB,EAAE,CAAC;QACtC,KAAK,MAAM,EAAE,EAAE,EAAE,IAAI,KAAK,EAAE,CAAC;YAC3B,MAAM,0BAA0B,GAAG,IAAI,CAAC,eAAe,CAAC,IAAI,CAC1D,oCAAoC,EACpC,EAAE,EACF,cAAc,CAAC,cAAc,CAC9B,CAAC;YAEF,IAAI,CAAC,0BAA0B,EAAE,CAAC;gBAChC,SAAS;YACX,CAAC;YAED,IAAI,CAAC,kBAAkB,CAAC,eAAe,EAAE,EAAE,EAAE,WAAW,CAAC,OAAO,CAAC,CAAC,KAAK,CACrE,CAAC,KAAK,EAAE,EAAE;gBACR,QAAQ,CACN,2DAA2D,EAAE,MAAM,eAAe,CAChF,KAAK,CACN,EAAE,CACJ,CAAC;YACJ,CAAC,CACF,CAAC;QACJ,CAAC;IACH,CAAC;IAED,wBAAwB,CAAC,iBAAqC;QAC5D,KAAK,MAAM,EACT,MAAM,EACN,QAAQ,EACR,KAAK,EACL,SAAS,EACT,MAAM,EACN,gBAAgB,GACjB,IAAI,iBAAiB,EAAE,CAAC;YACvB,MAAM,YAAY,GAAG,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;YACtC,MAAM,kBAAkB,GAAG,YAAY,KAAK,SAAS,CAAC;YACtD,MAAM,QAAQ,GACZ,kBAAkB,IAAI,SAAS,CAAC,QAAQ,CAAC,OAAO,EAAE,YAAY,CAAC,OAAO,CAAC,CAAC;YAE1E,6DAA6D;YAC7D,IACE,kBAAkB;gBAClB,CAAC,CAAC,QAAQ,IAAI,YAAY,CAAC,YAAY,KAAK,IAAI,CAAC,EACjD,CAAC;gBACD,SAAS;YACX,CAAC;YAED,MAAM,YAAY,GAAG,IAAI,WAAW,CAAe;gBACjD,IAAI,EAAE,gBAAgB,CAAC,QAAQ;gBAC/B,KAAK,EAAE,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC;gBAC/B,MAAM,EAAE,QAAQ;aACjB,CAAC,CAAC;YAEH,MAAM,YAAY,GAAG,KAAK,CAAC,GAAG,CAC5B,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC,IAAI,WAAW,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CACtD,CAAC;YACF,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,GAAG,QAAQ,CAAC,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC;YAC5D,MAAM,UAAU,GAAG,YAAY,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC;YACvE,MAAM,OAAO,GAAG,QAAQ;gBACtB,CAAC,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,KAAK,QAAQ,CAAC;gBACrD,CAAC,CAAC,SAAS,CAAC;YAEd,MAAM,CAAC,UAAU,EAAE,iDAAiD,CAAC,CAAC;YAEtE,MAAM,CACJ,CAAC,QAAQ,IAAI,CAAC,QAAQ,IAAI,OAAO,CAAC,EAClC,0CAA0C,CAC3C,CAAC;YAEF,MAAM,CACJ,QAAQ,CAAC,MAAM,CAAC,KAAK,KAAK,SAAS,EACnC,qEAAqE,CACtE,CAAC;YAEF,MAAM,iBAAiB,GACrB,QAAQ,CAAC,MAAM,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CACpC,YAAY,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,KAAK,IAAI,CAAC,CAChD,IAAI,EAAE,CAAC;YAEV,MAAM,0BAA0B,GAAG,6BAA6B,CAC9D,iBAAiB,CAAC,MAAM,CAAC,OAAO,CAAkB,CACnD,CAAC;YAEF,MAAM,CACJ,iBAAiB,CAAC,MAAM,KAAK,0BAA0B,CAAC,MAAM,EAC9D,mDAAmD,CACpD,CAAC;YAEF,MAAM,WAAW,GAAqB;gBACpC,QAAQ,EAAE,YAAY;gBACtB,UAAU;gBACV,OAAO;gBACP,cAAc,EAAE,EAAE;gBAClB,iBAAiB,EAAE,0BAA0B;aAC9C,CAAC;YAEF,uCAAuC;YACvC,IAAI,CAAC,IAAI,CAAC;gBACR,EAAE,EAAE,MAAM;gBACV,MAAM,EAAE,eAAe;gBACvB,KAAK,EAAE,WAAW;gBAClB,SAAS;gBACT,MAAM;gBACN,gBAAgB;gBAChB,YAAY,EAAE,IAAI;aACnB,CAAC,CAAC;YAEH,oBAAoB;YACpB,MAAM,oBAAoB,GAAG,sBAAsB,CACjD,QAAQ,CAAC,kBAAkB,CAC5B,CAAC;YAEF,IAAI,CAAC,wBAAwB,CAAC,oBAAoB,CAAC,CAAC;YAEpD,MAAM,EAAE,cAAc,EAAE,iBAAiB,EAAE,GACzC,IAAI,CAAC,2BAA2B,CAAC,MAAM,EAAE,oBAAoB,CAAC,CAAC;YAEjE,IAAI,CAAC,kBAAkB,CAAC,EAAE,MAAM,EAAE,cAAc,EAAE,iBAAiB,EAAE,CAAC,CAAC;YAEvE,IAAI,QAAQ,CAAC,kBAAkB,EAAE,CAAC;gBAChC,IAAI,CAAC,yBAAyB,CAC5B,MAAM,EACN,YAAY,EAAE,kBAAkB,IAAI,IAAI,EACxC,QAAQ,CAAC,kBAAkB,CAC5B,CAAC;YACJ,CAAC;YAED,aAAa;YACb,IAAI,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE;gBACpB,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,MAAM,GAAG,UAAU,CAAC,OAAO,CAAC;YAClD,CAAC,CAAC,CAAC;YAEH,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC;YAE3B,cAAc;YACd,IAAI,QAAQ,EAAE,CAAC;gBACb,IAAI,CAAC,eAAe,CAAC,OAAO,CAC1B,4BAA4B,EAC5B,IAAI,CAAC,kBAAkB,CAAC,MAAM,CAAC,EAC/B,YAAY,CAAC,OAAO,EACpB,eAAe,EACf,IAAI,CACL,CAAC;YACJ,CAAC;iBAAM,CAAC;gBACN,IAAI,CAAC,eAAe,CAAC,OAAO,CAC1B,8BAA8B,EAC9B,IAAI,CAAC,kBAAkB,CAAC,MAAM,CAAC,EAC/B,eAAe,EACf,IAAI,CACL,CAAC;YACJ,CAAC;QACH,CAAC;IACH,CAAC;IAED,yBAAyB;QACvB,IAAI,CAAC,4BAA4B,GAAG,UAAU,CAAC,GAAG,EAAE;YAClD,IAAI,CAAC,4BAA4B,EAAE,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;gBAClD,qCAAqC;gBACrC,QAAQ,CAAC,KAAK,CAAC,CAAC;YAClB,CAAC,CAAC,CAAC;YAEH,IAAI,CAAC,yBAAyB,EAAE,CAAC;QACnC,CAAC,EAAE,IAAI,CAAC,sBAAsB,CAAsB,CAAC;IACvD,CAAC;IAED;;;;OAIG;IACH,KAAK,CAAC,kBAAkB;QACtB,IAAI,CAAC,qBAAqB,EAAE,CAAC;QAC7B,MAAM,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,sBAAsB,CAAC,CAAC;QAExD,MAAM,YAAY,GAAG,MAAM,IAAI,CAAC,eAAe,CAAC,IAAI,CAClD,mBAAmB,EACnB,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,MAAM,CACpC,CAAC,YAAY,EAAE,IAAI,EAAE,EAAE;YACrB,YAAY,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG;gBACtB,OAAO,EAAE,IAAI,CAAC,OAAO;gBACrB,QAAQ,EAAE,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,MAAM;aACtC,CAAC;YACF,OAAO,YAAY,CAAC;QACtB,CAAC,EACD,EAAE,CACH,CACF,CAAC;QAEF,MAAM,OAAO,CAAC,GAAG,CACf,MAAM,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC,MAAM,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,EAAE,EAAE;YACtE,IAAI,MAAM,KAAK,mBAAmB,CAAC,OAAO,EAAE,CAAC;gBAC3C,OAAO,IAAI,CAAC,UAAU,CAAC,MAAgB,EAAE,MAAM,CAAC,CAAC;YACnD,CAAC;YAED,OAAO,IAAI,CAAC,YAAY,CAAC,MAAgB,CAAC,CAAC;QAC7C,CAAC,CAAC,CACH,CAAC;IACJ,CAAC;IAED;;;;;;OAMG;IACH,KAAK,CAAC,UAAU,CACd,MAAc,EACd,eAA6B;QAE7B,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC;YACtB,OAAO;QACT,CAAC;QAED,IAAI,CAAC;YACH,IAAI,CAAC,MAAM,CAAC,CAAC,KAAU,EAAE,EAAE;gBACzB,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,OAAO,GAAG,IAAI,CAAC;gBACnC,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,gBAAgB,GAAG,eAAe,CAAC;YACzD,CAAC,CAAC,CAAC;YAEH,MAAM,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;QACjC,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,QAAQ,CACN,iDAAiD,MAAM,IAAI,EAC3D,KAAK,CACN,CAAC;QACJ,CAAC;QAED,IAAI,CAAC,eAAe,CAAC,OAAO,CAC1B,GAAG,cAAc,cAAc,EAC/B,MAAM,EACN,eAAe,CAChB,CAAC;IACJ,CAAC;IAED;;;;;;OAMG;IACH,YAAY,CAAC,MAAc;QACzB,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,OAAO,EAAE,CAAC;YAC3D,OAAO;QACT,CAAC;QAED,IAAI,CAAC,MAAM,CAAC,CAAC,KAAU,EAAE,EAAE;YACzB,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,OAAO,GAAG,KAAK,CAAC;YACpC,OAAO,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,gBAAgB,CAAC;QAC9C,CAAC,CAAC,CAAC;QAEH,IAAI,CAAC,eAAe,CAAC,OAAO,CAAC,GAAG,cAAc,gBAAgB,EAAE,MAAM,CAAC,CAAC;IAC1E,CAAC;IAED,KAAK,CAAC,uBAAuB,CAC3B,MAAc,EACd,EACE,eAAe,EACf,GAAG,QAAQ,EAIZ;QAED,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,mBAAmB,EAAE;YACnE,CAAC,MAAM,CAAC,EAAE,QAAQ;SACnB,CAAC,CAAC;QAEH,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;QAC/B,IAAI,MAAM,CAAC,MAAM,KAAK,mBAAmB,CAAC,OAAO,EAAE,CAAC;YAClD,MAAM,IAAI,KAAK,CACb,2BACE,QAAQ,CAAC,OACX,cAAc,MAAM,8BAClB,MAAM,CAAC,MAAM,EAAE,WAAW,IAAI,EAChC,EAAE,CACH,CAAC;QACJ,CAAC;QAED,MAAM,sBAAsB,GAAG,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC,IAAI,CACnE,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC,mBAAmB,CAAC,QAAQ,CAAC,UAAU,CAAC,CAC1D,CAAC;QAEF,IACE,IAAI,CAAC,aAAa,CAAC,gBAAgB;YACnC,sBAAsB;YACtB,MAAM,CAAC,MAAM,KAAK,mBAAmB,CAAC,QAAQ,EAC9C,CAAC;YACD,MAAM,IAAI,KAAK,CACb,2BAA2B,QAAQ,CAAC,OAAO,cAAc,MAAM,MAC7D,MAAM,CAAC,MAAM,KAAK,mBAAmB,CAAC,WAAW;gBAC/C,CAAC,CAAC,0CAA0C;gBAC5C,CAAC,CAAC,mCACN,EAAE,CACH,CAAC;QACJ,CAAC;QAED,IAAI,CAAC,wBAAwB,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;IACzD,CAAC;IAED;;OAEG;IACH,sBAAsB;QACpB,MAAM,CACJ,IAAI,CAAC,aAAa,CAAC,uBAAuB,KAAK,IAAI,EACnD,qEAAqE,CACtE,CAAC;IACJ,CAAC;IAED;;OAEG;IACH,qBAAqB;QACnB,MAAM,KAAK,GAAG,IAAI,CAAC,gBAAgB,EAAE,CAAC;QACtC,MAAM,CACJ,KAAK,CAAC,YAAY,KAAK,IAAI,EAC3B,mIAAmI,CACpI,CAAC;IACJ,CAAC;IAED,KAAK,CAAC,4BAA4B;QAChC,MAAM,OAAO,GAAG,CAAC,GAAG,IAAI,CAAC,iBAAiB,CAAC,OAAO,EAAE,CAAC,CAAC;QACtD,OAAO,OAAO,CAAC,GAAG,CAChB,OAAO;aACJ,MAAM,CACL,CAAC,CAAC,OAAO,EAAE,OAAO,CAAC,EAAE,EAAE,CACrB,OAAO,CAAC,gBAAgB,KAAK,CAAC;YAC9B,OAAO,CAAC,sBAAsB,CAAC,MAAM,KAAK,CAAC;YAC3C,OAAO,CAAC,WAAW;YACnB,IAAI,CAAC,YAAY;YACjB,SAAS,CAAC,OAAO,CAAC,WAAW,CAAC,GAAG,IAAI,CAAC,YAAY,CACrD;aACA,GAAG,CAAC,KAAK,EAAE,CAAC,MAAM,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,gBAAgB,CAAC,IAAI,CAAC,CAAC,CACzE,CAAC;IACJ,CAAC;IAED,qBAAqB,CAAC,MAAc,EAAE,KAAoB;QACxD,sCAAsC;QACtC,6DAA6D;QAC7D,QAAQ,CAAC,yBAAyB,MAAM,IAAI,EAAE,KAAK,CAAC,CAAC;QACrD,IAAI,CAAC,QAAQ,CAAC,MAAgB,EAAE,gBAAgB,CAAC,KAAK,CAAC,CAAC,KAAK,CAC3D,CAAC,aAAa,EAAE,EAAE;YAChB,qCAAqC;YACrC,QAAQ,CAAC,aAAa,CAAC,CAAC;QAC1B,CAAC,CACF,CAAC;IACJ,CAAC;IAED,kBAAkB,CAAC,MAAc;QAC/B,MAAM,OAAO,GAAG,IAAI,CAAC,iBAAiB,CAAC,MAAgB,CAAC,CAAC;QACzD,sFAAsF;QACtF,yFAAyF;QACzF,OAAO,CAAC,sBAAsB;aAC3B,MAAM,CAAC,CAAC,cAAc,EAAE,EAAE,CAAC,cAAc,CAAC,KAAK,CAAC,MAAM,KAAK,SAAS,CAAC;aACrE,OAAO,CAAC,CAAC,cAAc,EAAE,EAAE,CAAC,cAAc,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC,CAAC;QAC7D,OAAO,CAAC,uBAAuB,IAAI,CAAC,CAAC;IACvC,CAAC;IAED,mBAAmB,CAAC,MAAc;QAChC,MAAM,OAAO,GAAG,IAAI,CAAC,iBAAiB,CAAC,MAAgB,CAAC,CAAC;QACzD,OAAO,CAAC,uBAAuB,IAAI,CAAC,CAAC;QACrC,IAAI,OAAO,CAAC,uBAAuB,KAAK,CAAC,EAAE,CAAC;YAC1C,OAAO,CAAC,sBAAsB;iBAC3B,MAAM,CAAC,CAAC,cAAc,EAAE,EAAE,CAAC,cAAc,CAAC,KAAK,CAAC,MAAM,KAAK,QAAQ,CAAC;iBACpE,OAAO,CAAC,CAAC,cAAc,EAAE,EAAE,CAAC,cAAc,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC;QAChE,CAAC;IACH,CAAC;IAED;;;;;;;;;;;OAWG;IACH,WAAW,CAAC,MAAc,EAAE,KAA0C;QACpE,MAAM,EAAE,WAAW,EAAE,GAAG,IAAI,CAAC,iBAAiB,CAAC,MAAM,CAAC,CAAC;QACvD,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACxB,IAAI,CAAC,MAAM,CAAC,CAAC,KAAU,EAAE,EAAE;YACzB,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,MAAM,GAAG,WAAW,CAAC,KAAK,CAAC,KAAK,CAAC;QACvD,CAAC,CAAC,CAAC;IACL,CAAC;IAED;;;;;OAKG;IACH,KAAK,CAAC,SAAS,CAAC,MAAc;QAC5B,IAAI,CAAC,qBAAqB,EAAE,CAAC;QAC7B,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;QAEtC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;YAClB,MAAM,IAAI,KAAK,CAAC,SAAS,MAAM,gBAAgB,CAAC,CAAC;QACnD,CAAC;QAED,MAAM,IAAI,CAAC,UAAU,CAAC;YACpB,MAAM;YACN,UAAU,EAAE,IAAI,CAAC,UAAU;SAC5B,CAAC,CAAC;IACL,CAAC;IAED;;;;;OAKG;IACH,UAAU,CAAC,MAAc;QACvB,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;QAEvB,IAAI,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,OAAO,EAAE,CAAC;YACrC,MAAM,IAAI,KAAK,CAAC,SAAS,MAAM,qCAAqC,CAAC,CAAC;QACxE,CAAC;QAED,IAAI,CAAC,MAAM,CAAC,CAAC,KAAU,EAAE,EAAE;YACzB,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,OAAO,GAAG,IAAI,CAAC;QACrC,CAAC,CAAC,CAAC;QAEH,IAAI,CAAC,eAAe,CAAC,OAAO,CAC1B,4BAA4B,EAC5B,IAAI,CAAC,kBAAkB,CAAC,MAAM,CAAC,CAChC,CAAC;IACJ,CAAC;IAED;;;;;OAKG;IACH,KAAK,CAAC,WAAW,CAAC,MAAc;QAC9B,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC;YACtB,MAAM,IAAI,KAAK,CAAC,SAAS,MAAM,cAAc,CAAC,CAAC;QACjD,CAAC;QAED,IAAI,CAAC,MAAM,CAAC,CAAC,KAAU,EAAE,EAAE;YACzB,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,OAAO,GAAG,KAAK,CAAC;QACtC,CAAC,CAAC,CAAC;QAEH,IAAI,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE,CAAC;YAC3B,MAAM,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,gBAAgB,CAAC,IAAI,CAAC,CAAC;QACrD,CAAC;QAED,IAAI,CAAC,eAAe,CAAC,OAAO,CAC1B,6BAA6B,EAC7B,IAAI,CAAC,kBAAkB,CAAC,MAAM,CAAC,CAChC,CAAC;IACJ,CAAC;IAED;;;;;;;OAOG;IACI,KAAK,CAAC,QAAQ,CACnB,MAAc,EACd,cAE6B,gBAAgB,CAAC,IAAI;QAElD,MAAM,OAAO,GAAG,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;QACzC,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,MAAM,IAAI,KAAK,CAAC,aAAa,MAAM,mBAAmB,CAAC,CAAC;QAC1D,CAAC;QAED,uDAAuD;QACvD,IAAI,OAAO,CAAC,WAAW,EAAE,CAAC;YACxB,MAAM,OAAO,CAAC,WAAW,CAAC;YAC1B,OAAO;QACT,CAAC;QAED,iFAAiF;QACjF,gDAAgD;QAChD,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,GAAG,qBAAqB,EAAE,CAAC;QACrD,OAAO,CAAC,WAAW,GAAG,OAAO,CAAC;QAE9B,IAAI,CAAC;YACH,IAAI,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE,CAAC;gBAC3B,IAAI,CAAC,oBAAoB,EAAE,CAAC,MAAM,CAAC,CAAC;gBACpC,MAAM,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC;YACpC,CAAC;QACH,CAAC;gBAAS,CAAC;YACT,yBAAyB;YACzB,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC;YAC3B,OAAO,CAAC,sBAAsB,GAAG,EAAE,CAAC;YACpC,OAAO,CAAC,uBAAuB,GAAG,CAAC,CAAC;YACpC,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC;YAC3B,IAAI,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE,CAAC;gBAC3B,IAAI,CAAC,WAAW,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;YACxC,CAAC;YACD,OAAO,EAAE,CAAC;QACZ,CAAC;IACH,CAAC;IAED;;;;;;OAMG;IACI,KAAK,CAAC,YAAY,CACvB,cAE6B,gBAAgB,CAAC,IAAI;QAElD,MAAM,KAAK,GAAG,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAC5D,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC,CACxB,CAAC;QACF,MAAM,QAAQ,GAAG,KAAK,CAAC,GAAG,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE,CACxC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,EAAE,WAAW,CAAC,CACpC,CAAC;QACF,MAAM,OAAO,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC;IACrC,CAAC;IAED;;;;OAIG;IACH,KAAK,CAAC,cAAc,CAAC,MAAc;QACjC,MAAM,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,gCAAgC,EAAE,MAAM,CAAC,CAAC;QAE1E,kFAAkF;QAClF,MAAM,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC;QAEvD,MAAM,OAAO,GAAG,IAAI,CAAC,iBAAiB,CAAC,MAAM,CAAC,CAAC;QAC/C,2DAA2D;QAC3D,OAAO,CAAC,sBAAsB;aAC3B,MAAM,CAAC,CAAC,cAAc,EAAE,EAAE,CAAC,cAAc,CAAC,KAAK,CAAC,MAAM,KAAK,UAAU,CAAC;aACtE,OAAO,CAAC,CAAC,cAAc,EAAE,EAAE,CAAC,cAAc,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC;QAE9D,wEAAwE;QACxE,MAAM,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC;QAEvD,IAAI,CAAC,eAAe,CAAC,OAAO,CAC1B,+BAA+B,EAC/B,IAAI,CAAC,kBAAkB,CAAC,MAAM,CAAC,CAChC,CAAC;IACJ,CAAC;IAED;;;;;;OAMG;IACH,SAAS,CAAC,MAAc;QACtB,OAAO,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,MAAM,KAAK,SAAS,CAAC;IACrD,CAAC;IAED;;;;;OAKG;IACH,GAAG,CAAC,MAAc;QAChB,OAAO,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC;IACnC,CAAC;IAED;;;;;;;OAOG;IACH,GAAG,CAAC,MAAc;QAChB,OAAO,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,MAAgB,CAAC,CAAC;IAC5C,CAAC;IAED;;;;;;;;;OASG;IACH,SAAS,CAAC,MAAc;QACtB,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QAC9B,MAAM,CAAC,IAAI,KAAK,SAAS,EAAE,IAAI,KAAK,CAAC,SAAS,MAAM,cAAc,CAAC,CAAC,CAAC;QACrE,OAAO,IAAI,CAAC;IACd,CAAC;IAED;;;;;;OAMG;IACH,2EAA2E;IAC3E,YAAY,CAAC,MAAc;QACzB,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QAE9B,OAAO,IAAI,CAAC,CAAC,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IAC1C,CAAC;IAED;;;;;;OAMG;IACH,kBAAkB,CAAC,MAAc;QAC/B,OAAO,YAAY,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC;IAC9C,CAAC;IAED;;;;;;OAMG;IACH,uBAAuB,CACrB,MAAc,EACd,OAAO,GAAG,IAAI,CAAC,iBAAiB,CAAC,MAAM,CAAC;QAKxC,OAAO,OAAO,CAAC,aAAa,KAAK,IAAI,IAAI,OAAO,CAAC,cAAc,KAAK,IAAI,CAAC;IAC3E,CAAC;IAED;;;;;;;;;OASG;IACH,KAAK,CAAC,qBAAqB,CAAC,EAC1B,MAAM,EACN,IAAI,EAAE,UAAU,EAChB,QAAQ,EACR,WAAW,GAMZ;QACC,MAAM,OAAO,GAAG,IAAI,CAAC,iBAAiB,CAAC,MAAM,CAAC,CAAC;QAE/C,IAAI,IAAI,CAAC,uBAAuB,CAAC,MAAM,EAAE,OAAO,CAAC,IAAI,QAAQ,EAAE,CAAC;YAC9D,OAAO;gBACL,GAAG,EAAE,MAAM,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,OAAO,CAAC,aAAa,CAAC;gBAC3D,IAAI,EAAE,OAAO,CAAC,cAAc;aAC7B,CAAC;QACJ,CAAC;QAED,MAAM,IAAI,GAAG,UAAU,IAAI,IAAI,CAAC,UAAU,CAAC,YAAY,EAAE,CAAC;QAC1D,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,gBAAgB,EAAE,CAAC;QAE3C,MAAM,OAAO,GAAG,MAAM,oBAAoB,CAAC;YACzC,MAAM;YACN,IAAI;YACJ,sBAAsB,EAAE,IAAI,CAAC,mBAAmB;SACjD,CAAC,CAAC;QAEH,MAAM,aAAa,GAAG,MAAM,IAAI,CAAC,UAAU,CAAC,eAAe,CACzD,OAAO,EACP,IAAI,EACJ,IAAI,EACJ,WAAW,CACZ,CAAC;QACF,MAAM,WAAW,GAAG,MAAM,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,aAAa,CAAC,CAAC;QAEnE,2CAA2C;QAC3C,IAAI,QAAQ,EAAE,CAAC;YACb,OAAO,CAAC,aAAa,GAAG,WAAW,CAAC;YACpC,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC;QAChC,CAAC;QACD,OAAO,EAAE,GAAG,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC;IACtC,CAAC;IAED;;;;;;;OAOG;IACH,KAAK,CAAC,iBAAiB,CAAC,MAAc,EAAE,KAAa;QACnD,IAAI,CAAC;YACH,qFAAqF;YACrF,qCAAqC;YACrC,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAqB,CAAC;YACrD,MAAM,EAAE,IAAI,EAAE,WAAW,EAAE,GAAG,MAAM,CAAC;YAErC,+HAA+H;YAC/H,MAAM,QAAQ,GACZ,IAAI,CAAC,uBAAuB,CAAC,MAAM,CAAC;gBACpC,IAAI,CAAC,UAAU,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC;YAExC,MAAM,EAAE,GAAG,EAAE,GAAG,MAAM,IAAI,CAAC,qBAAqB,CAAC;gBAC/C,MAAM;gBACN,IAAI;gBACJ,QAAQ;gBACR,8DAA8D;gBAC9D,0HAA0H;gBAC1H,WAAW,EAAE,WAAW,IAAI,wCAAwC;aACrE,CAAC,CAAC;YACH,MAAM,cAAc,GAAG,MAAM,IAAI,CAAC,UAAU,CAAC,cAAc,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;YAEzE,mGAAmG;YACnG,OAAO,cAAsC,CAAC;QAChD,CAAC;QAAC,MAAM,CAAC;YACP,MAAM,SAAS,CAAC,QAAQ,CAAC;gBACvB,OAAO,EAAE,4DAA4D;aACtE,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED;;;;;;;;;OASG;IACH,KAAK,CAAC,iBAAiB,CAAC,MAAc,EAAE,KAA2B;QACjE,MAAM,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,MAAM,IAAI,CAAC,qBAAqB,CAAC;YACrD,MAAM;YACN,QAAQ,EAAE,IAAI;SACf,CAAC,CAAC;QACH,MAAM,cAAc,GAAG,MAAM,IAAI,CAAC,UAAU,CAAC,cAAc,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;QAExE,cAAc,CAAC,IAAI,GAAG,IAAI,CAAC;QAC3B,OAAO,IAAI,CAAC,SAAS,CAAC,cAAc,CAAC,CAAC;IACxC,CAAC;IAED;;;;;;;;;;;;;;OAcG;IACH,KAAK,CAAC,kBAAkB,CACtB,MAAc,EACd,KAAkC,EAClC,SAAkB;QAElB,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;YACnB,OAAO,IAAI,CAAC;QACd,CAAC;QAED,IAAI,SAAS,EAAE,CAAC;YACd,OAAO,MAAM,IAAI,CAAC,iBAAiB,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;QACrD,CAAC;QAED,OAAO,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;IAC/B,CAAC;IAED;;;;;;;;;;;;OAYG;IACM,iBAAiB,GAAG,oBAAoB,CAC/C,CACE,MAAc,EACd,YAAyC,EACzC,SAAkB,EAClB,EAAE;QACF,MAAM,OAAO,GAAG,IAAI,CAAC,iBAAiB,CAAC,MAAM,CAAC,CAAC;QAC/C,OAAO,CAAC,UAAU;aACf,YAAY,CAAC,KAAK,IAAI,EAAE;YACvB,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,kBAAkB,CAC5C,MAAM,EACN,YAAY,EACZ,SAAS,CACV,CAAC;YAEF,IAAI,SAAS,EAAE,CAAC;gBACd,OAAO,IAAI,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE;oBAC3B,KAAK,CAAC,UAAU,CAAC,MAAM,CAAC,GAAG,QAAQ,CAAC;gBACtC,CAAC,CAAC,CAAC;YACL,CAAC;YAED,OAAO,IAAI,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE;gBAC3B,KAAK,CAAC,qBAAqB,CAAC,MAAM,CAAC,GAAG,QAAQ,CAAC;YACjD,CAAC,CAAC,CAAC;QACL,CAAC,CAAC;aACD,KAAK,CAAC,QAAQ,CAAC,CAAC;IACrB,CAAC,EACD,sBAAsB,CACvB,CAAC;IAEF;;;;;;;OAOG;IACH,KAAK,CAAC,eAAe,CACnB,MAAc,EACd,YAAkC,EAClC,SAAkB;QAElB,MAAM,OAAO,GAAG,IAAI,CAAC,iBAAiB,CAAC,MAAM,CAAC,CAAC;QAE/C,IAAI,SAAS,EAAE,CAAC;YACd,OAAO,CAAC,KAAK,GAAG,YAAY,CAAC;QAC/B,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,gBAAgB,GAAG,YAAY,CAAC;QAC1C,CAAC;QAED,IAAI,CAAC,iBAAiB,CAAC,MAAM,EAAE,YAAY,EAAE,SAAS,CAAC,CAAC;IAC1D,CAAC;IAED;;;;;;OAMG;IACH,cAAc,CAAC,MAAc,EAAE,SAAkB;QAC/C,MAAM,OAAO,GAAG,IAAI,CAAC,iBAAiB,CAAC,MAAM,CAAC,CAAC;QAC/C,IAAI,SAAS,EAAE,CAAC;YACd,OAAO,CAAC,KAAK,GAAG,IAAI,CAAC;QACvB,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC;QAClC,CAAC;QAED,IAAI,CAAC,iBAAiB,CAAC,MAAM,EAAE,IAAI,EAAE,SAAS,CAAC,CAAC;IAClD,CAAC;IAED;;;;;;;OAOG;IACH,KAAK,CAAC,YAAY,CAAC,MAAc,EAAE,SAAkB;QACnD,MAAM,OAAO,GAAG,IAAI,CAAC,iBAAiB,CAAC,MAAM,CAAC,CAAC;QAC/C,OAAO,MAAM,OAAO,CAAC,aAAa,CAAC,YAAY,CAAC,KAAK,IAAI,EAAE;YACzD,MAAM,WAAW,GAAG,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,gBAAgB,CAAC;YAEzE,IAAI,WAAW,KAAK,SAAS,EAAE,CAAC;gBAC9B,OAAO,WAAW,CAAC;YACrB,CAAC;YAED,MAAM,KAAK,GAAG,SAAS;gBACrB,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,MAAM,CAAC;gBAC/B,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,qBAAqB,CAAC,MAAM,CAAC,CAAC;YAE7C,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;gBAC1C,OAAO,IAAI,CAAC;YACd,CAAC;YAED,IAAI,CAAC,SAAS,EAAE,CAAC;gBACf,sEAAsE;gBACtE,kCAAkC;gBAClC,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;gBAC/B,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC;gBAEhC,OAAO,IAAI,CAAC;YACd,CAAC;YAED,MAAM,SAAS,GAAG,MAAM,IAAI,CAAC,iBAAiB,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;YAC9D,kDAAkD;YAClD,OAAO,CAAC,KAAK,GAAG,SAAS,CAAC;YAE1B,OAAO,SAAS,CAAC;QACnB,CAAC,CAAC,CAAC;IACL,CAAC;IAED;;;;;;;OAOG;IACH,KAAK,CAAC,WAAW,CACf,MAAc,EACd,IAAY,EACZ,WAAkC,qBAAqB,CAAC,MAAM;QAE9D,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;QACpC,MAAM,cAAc,GAAG,iBAAiB,CAAC,IAAI,CAAC,CAAC;QAC/C,MAAM,KAAK,GAAG,IAAI,CAAC,cAAc,EAAE,IAAI,CACrC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,KAAK,cAAc,CACvC,EAAE,KAAK,CAAC;QAET,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,OAAO,IAAI,CAAC;QACd,CAAC;QAED,MAAM,OAAO,GAAG,MAAM,mBAAmB,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;QAE3D,MAAM,CACJ,OAAO,CAAC,MAAM,GAAG,aAAa,EAC9B,oCAAoC,QAAQ,uDAAuD,CACpG,CAAC;QAEF,OAAO,OAAO,CAAC;IACjB,CAAC;IAED;;;;;;;OAOG;IACH,wBAAwB,CAAC,MAAc,EAAE,OAAsB;QAC7D,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;QAEpC,MAAM,EAAE,eAAe,EAAE,GAAG,IAAI,CAAC,QAAQ,CAAC;QAE1C,IAAI,CAAC,eAAe,EAAE,CAAC;YACrB,OAAO,KAAK,CAAC;QACf,CAAC;QAED,OAAO,GAAG,CAAC,eAAe,EAAE,OAAO,CAAC,CAAC;IACvC,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,UAAU;QACd,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QAC9C,IAAI,IAAI,CAAC,oBAAoB,EAAE,CAAC;YAC9B,OAAO,CAAC,OAAO,CAAC,CAAC,MAAM,EAAE,EAAE;gBACzB,IAAI,CAAC,oBAAoB,EAAE,CAAC,MAAM,CAAC,CAAC;YACtC,CAAC,CAAC,CAAC;QACL,CAAC;QAED,MAAM,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,oCAAoC,CAAC,CAAC;QACtE,OAAO,CAAC,OAAO,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,IAAI,CAAC,yBAAyB,CAAC,MAAM,CAAC,CAAC,CAAC;QAEpE,IAAI,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE;YACpB,KAAK,CAAC,KAAK,GAAG,EAAE,CAAC;YACjB,KAAK,CAAC,UAAU,GAAG,EAAE,CAAC;YACtB,KAAK,CAAC,qBAAqB,GAAG,EAAE,CAAC;QACnC,CAAC,CAAC,CAAC;QAEH,IAAI,CAAC,iBAAiB,CAAC,KAAK,EAAE,CAAC;QAC/B,IAAI,CAAC,kBAAkB,CAAC,KAAK,EAAE,CAAC;QAEhC,2EAA2E;QAC3E,IAAI,IAAI,CAAC,kBAAkB,EAAE,CAAC;YAC5B,IAAI,CAAC,wBAAwB,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC;QACzD,CAAC;IACH,CAAC;IAED;;;;;;OAMG;IACH,KAAK,CAAC,UAAU,CAAC,MAAc;QAC7B,OAAO,IAAI,CAAC,WAAW,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;IACpC,CAAC;IAED;;;;;OAKG;IACH,KAAK,CAAC,WAAW,CAAC,OAAiB;QACjC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;YAC5B,MAAM,IAAI,KAAK,CAAC,6BAA6B,CAAC,CAAC;QACjD,CAAC;QAED,OAAO,CAAC,OAAO,CAAC,CAAC,MAAM,EAAE,EAAE;YACzB,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;YACpC,MAAM,CAAC,IAAI,CAAC,SAAS,KAAK,KAAK,EAAE,GAAG,MAAM,oBAAoB,CAAC,CAAC;QAClE,CAAC,CAAC,CAAC;QAEH,MAAM,OAAO,CAAC,GAAG,CACf,OAAO,CAAC,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE;YAC3B,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;YACpC,MAAM,SAAS,GAAG,IAAI,CAAC,kBAAkB,CAAC,MAAM,CAAC,CAAC;YAClD,qEAAqE;YACrE,oEAAoE;YACpE,wDAAwD;YACxD,MAAM,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;YAC/B,IAAI,CAAC,yBAAyB,CAAC,MAAM,CAAC,CAAC;YAEvC,IAAI,CAAC,uBAAuB,CAAC,MAAM,CAAC,CAAC;YAErC,IAAI,CAAC,iBAAiB,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;YAEtC,IAAI,CAAC,MAAM,CAAC,CAAC,KAAU,EAAE,EAAE;gBACzB,OAAO,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;gBAC3B,OAAO,KAAK,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC;gBAChC,OAAO,KAAK,CAAC,qBAAqB,CAAC,MAAM,CAAC,CAAC;YAC7C,CAAC,CAAC,CAAC;YAEH,0EAA0E;YAC1E,IAAI,IAAI,CAAC,MAAM,KAAK,UAAU,CAAC,UAAU,EAAE,CAAC;gBAC1C,IAAI,CAAC,eAAe,CAAC,OAAO,CAC1B,gCAAgC,EAChC,SAAS,CACV,CAAC;YACJ,CAAC;QACH,CAAC,CAAC,CACH,CAAC;IACJ,CAAC;IAED,yBAAyB,CACvB,MAAc,EACd,0BAAqD,EACrD,kBAAsC;QAEtC,IAAI,0BAA0B,EAAE,CAAC;YAC/B,MAAM,yBAAyB,GAAG,OAAO,CACvC,0BAA0B,EAC1B,kBAAkB,CACnB,CAAC;YAEF,KAAK,MAAM,MAAM,IAAI,MAAM,CAAC,IAAI,CAAC,yBAAyB,CAAC,EAAE,CAAC;gBAC5D,IAAI,CAAC,qBAAqB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;YAC7C,CAAC;QACH,CAAC;QAED,KAAK,MAAM,MAAM,IAAI,MAAM,CAAC,IAAI,CAAC,kBAAkB,CAAC,EAAE,CAAC;YACrD,IAAI,CAAC,iBAAiB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QACzC,CAAC;IACH,CAAC;IAED,iBAAiB,CAAC,MAAc,EAAE,MAAc;QAC9C,MAAM,kBAAkB,GAAG,IAAI,CAAC,eAAe,CAAC,IAAI,CAClD,qCAAqC,EACrC,MAAM,CACqC,CAAC;QAE9C,MAAM,cAAc,GAAG,kBAAkB,EAAE,CACzC,0BAA0B,CAC3B,EAAE,OAAO,EAAE,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,KAAK,cAAc,CAAC,OAAO,CAAC,CAAC;QAErE,MAAM,cAAc,GAAG,OAAO,CAC3B,cAAc,EAAE,KAA8B,EAAE,CAAC,MAAM,CAAC,CAC1D,CAAC;QAEF,oEAAoE;QACpE,IAAI,cAAc,EAAE,CAAC;YACnB,OAAO;QACT,CAAC;QAED,yDAAyD;QACzD,IAAI,cAAc,EAAE,CAAC;YACnB,IAAI,CAAC,eAAe,CAAC,IAAI,CACvB,mCAAmC,EACnC,MAAM,EACN,0BAA0B,EAC1B,cAAc,CAAC,OAAO,EACtB,EAAE,GAAI,cAAc,CAAC,KAA8B,EAAE,CAAC,MAAM,CAAC,EAAE,EAAE,EAAE,CACpE,CAAC;YACF,OAAO;QACT,CAAC;QAED,MAAM,mBAAmB,GAAG;YAC1B,CAAC,0BAA0B,CAAC,EAAE;gBAC5B,OAAO,EAAE;oBACP;wBACE,IAAI,EAAE,cAAc,CAAC,OAAO;wBAC5B,KAAK,EAAE;4BACL,CAAC,MAAM,CAAC,EAAE,EAAE;yBACb;qBACF;iBACF;aACF;SACsB,CAAC;QAE1B,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,uCAAuC,EAAE;YACjE,mBAAmB;YACnB,OAAO,EAAE,EAAE,MAAM,EAAE;SACpB,CAAC,CAAC;IACL,CAAC;IAED;;;;;OAKG;IACH,qBAAqB,CAAC,MAAc,EAAE,MAAc;QAClD,MAAM,kBAAkB,GAAG,IAAI,CAAC,eAAe,CAAC,IAAI,CAClD,qCAAqC,EACrC,MAAM,CACqC,CAAC;QAE9C,MAAM,aAAa,GAAG,kBAAkB,EAAE,CACxC,0BAA0B,CAC3B,EAAE,OAAO,EAAE,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,KAAK,cAAc,CAAC,OAAO,CAEtD,CAAC;QAEd,IAAI,CAAC,aAAa,EAAE,CAAC;YACnB,OAAO;QACT,CAAC;QAED,MAAM,aAAa,GAAG,OAAO,CAC1B,aAAa,CAAC,KAA8B,EAAE,CAAC,MAAM,CAAC,CACxD,CAAC;QACF,IAAI,aAAa,EAAE,CAAC;YAClB,MAAM,cAAc,GAAG;gBACrB,GAAI,aAAa,CAAC,KAA8B;aACjD,CAAC;YACF,OAAO,cAAc,CAAC,MAAM,CAAC,CAAC;YAC9B,IAAI,MAAM,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBAC3C,IAAI,CAAC,eAAe,CAAC,IAAI,CACvB,mCAAmC,EACnC,MAAM,EACN,0BAA0B,EAC1B,cAAc,CAAC,OAAO,EACtB,cAAc,CACf,CAAC;YACJ,CAAC;iBAAM,CAAC;gBACN,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,wCAAwC,EAAE;oBAClE,CAAC,MAAM,CAAC,EAAE,CAAC,0BAA0B,CAAC;iBACvC,CAAC,CAAC;YACL,CAAC;QACH,CAAC;IACH,CAAC;IAED;;;;;;OAMG;IACH,4BAA4B,CAC1B,MAAc,EACd,eAAsC;QAEtC,MAAM,CACJ,eAAe,CAAC,KAAK,CAAC,CAAC,cAAc,EAAE,EAAE,CACvC,IAAI,CAAC,mBAAmB,CAAC,QAAQ,CAAC,cAAc,CAAC,CAClD,EACD,2CAA2C,CAC5C,CAAC;QACF,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,wCAAwC,EAAE;YAClE,CAAC,MAAM,CAAC,EAAE,eAAe;SAC1B,CAAC,CAAC;IACL,CAAC;IAED;;;;OAIG;IACH,uBAAuB,CAAC,MAAc;QACpC,MAAM,QAAQ,GAAG,IAAI,CAAC,eAAe,CAAC,IAAI,CACxC,sCAAsC,CACvC,CAAC;QACF,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;YAC/B,IAAI,CAAC,qBAAqB,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;QAC9C,CAAC;IACH,CAAC;IAED;;;;OAIG;IACH,yBAAyB,CAAC,MAAc;QACtC,IACE,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,qCAAqC,EAAE,MAAM,CAAC,EACxE,CAAC;YACD,IAAI,CAAC,eAAe,CAAC,IAAI,CACvB,2CAA2C,EAC3C,MAAM,CACP,CAAC;QACJ,CAAC;IACH,CAAC;IAED;;;;OAIG;IACH,yBAAyB,CAAC,MAAc;QACtC,MAAM,OAAO,GAAG,IAAI,CAAC,iBAAiB,CAAC,MAAM,CAAC,CAAC;QAC/C,OAAO,CAAC,gBAAgB,IAAI,CAAC,CAAC;IAChC,CAAC;IAED;;;;OAIG;IACH,yBAAyB,CAAC,MAAc;QACtC,MAAM,OAAO,GAAG,IAAI,CAAC,iBAAiB,CAAC,MAAM,CAAC,CAAC;QAC/C,MAAM,CACJ,OAAO,CAAC,gBAAgB,GAAG,CAAC,EAC5B,6DAA6D,CAC9D,CAAC;QACF,OAAO,CAAC,gBAAgB,IAAI,CAAC,CAAC;IAChC,CAAC;IAED;;;;OAIG;IACH,WAAW;QACT,OAAO,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;IAC3D,CAAC;IAED;;;;OAIG;IACH,gBAAgB;QACd,OAAO,gBAAgB,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,CAAC;IAC9C,CAAC;IAED;;;;;OAKG;IACH,iBAAiB,CAAC,MAAc;QAC9B,MAAM,WAAW,GACf,IAAI,CAAC,eAAe,CAAC,IAAI,CACvB,qCAAqC,EACrC,MAAM,CACP,IAAI,EAAE,CAAC;QACV,MAAM,KAAK,GACT,WAAW,CAAC,0BAA0B,CAAC,EAAE,OAAO,EAAE,IAAI,CACpD,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,KAAK,cAAc,CAAC,OAAO,CACnD,EAAE,KAAK,IAAI,EAAE,CAAC;QACjB,OAAO,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,MAAM,CAC9B,CAAC,cAAc,EAAE,MAAM,EAAE,EAAE;YACzB,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;YAC9B,MAAM,aAAa,GAAG,IAAI,CAAC,YAAY,CAAC,MAAgB,CAAC,CAAC;YAE1D,IAAI,aAAa,IAAI,IAAI,EAAE,MAAM,KAAK,UAAU,CAAC,UAAU,EAAE,CAAC;gBAC5D,cAAc,CAAC,MAAM,CAAC,GAAG,aAAa,CAAC;YACzC,CAAC;YACD,OAAO,cAAc,CAAC;QACxB,CAAC,EACD,EAAE,CACH,CAAC;IACJ,CAAC;IAED;;;;;;;;;OASG;IACH,KAAK,CAAC,YAAY,CAChB,MAAc,EACd,cAAkC;QAElC,IAAI,CAAC,qBAAqB,EAAE,CAAC;QAE7B,MAAM,MAAM,GAAuB,EAAE,CAAC;QAEtC,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;QAE5C,MAAM,cAAc,GAAG,EAAE,CAAC;QAC1B,MAAM,eAAe,GAAG,EAAE,CAAC;QAE3B,IAAI,CAAC;YACH,KAAK,MAAM,CAAC,MAAM,EAAE,EAAE,OAAO,EAAE,UAAU,EAAE,CAAC,IAAI,MAAM,CAAC,OAAO,CAC5D,cAAc,CACf,EAAE,CAAC;gBACF,mBAAmB,CAAC,MAAM,CAAC,CAAC;gBAE5B,MAAM,CAAC,KAAK,EAAE,OAAO,CAAC,GAAG,mBAAmB,CAAC,UAAU,CAAC,CAAC;gBAEzD,IAAI,KAAK,EAAE,CAAC;oBACV,MAAM,SAAS,CAAC,aAAa,CAC3B,qFACE,UACF,IAAI,CACL,CAAC;gBACJ,CAAC;gBAED,MAAM,QAAQ,GAAG,IAAI,CAAC,mBAAmB,CAAC,MAAM,EAAE;oBAChD,YAAY,EAAE,OAAO;oBACrB,KAAK,EAAE,IAAI,CAAC,cAAc;oBAC1B,UAAU,EAAE,IAAI,CAAC,aAAa,CAAC,eAAe;oBAC9C,cAAc,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE,CAC9B,IAAI,CAAC,aAAa,CAAC,gBAAgB;wBACjC,CAAC,CAAC,MAAM,IAAI,CAAC,wBAAwB,CAAC,MAAM,EAAE,KAAK,CAAC;wBACpD,CAAC,CAAC,KAAK;iBACZ,CAAC,CAAC;gBAEH,+FAA+F;gBAC/F,2CAA2C;gBAC3C,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,kBAAkB,CAAC;gBAElE,IAAI,QAAQ,IAAI,IAAI,CAAC,cAAc,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAC;oBACrD,MAAM,YAAY,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;oBAC5C,cAAc,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,UAAU,EAAE,YAAY,CAAC,OAAO,EAAE,CAAC,CAAC;oBAClE,IAAI,gBAAgB,GAAG,IAAI,CAAC,oBAAoB,CAAC,MAAM,CAAC,CAAC;oBACzD,IAAI,gBAAgB,KAAK,SAAS,EAAE,CAAC;wBACnC,gBAAgB,GAAG,IAAI,CAAC,uBAAuB,CAAC,MAAM,CAAC,CAAC;wBACxD,gBAAgB,CAAC,UAAU,GAAG,OAAO,CAAC;oBACxC,CAAC;yBAAM,CAAC;wBACN,MAAM,IAAI,KAAK,CAAC,qCAAqC,CAAC,CAAC;oBACzD,CAAC;gBACH,CAAC;qBAAM,IAAI,CAAC,QAAQ,EAAE,CAAC;oBACrB,eAAe,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;gBAC/B,CAAC;gBAED,MAAM,CAAC,MAAM,CAAC,GAAG,MAAM,IAAI,CAAC,oBAAoB,CAC9C,MAAM,EACN,MAAM,EACN,QAAQ,EACR,OAAO,CACR,CAAC;YACJ,CAAC;YAED,sDAAsD;YACtD,eAAe,CAAC,OAAO,CAAC,CAAC,MAAM,EAAE,EAAE,CACjC,IAAI,CAAC,eAAe,CAAC,OAAO,CAC1B,8BAA8B,EAC9B,IAAI,CAAC,kBAAkB,CAAC,MAAM,CAAC,EAC/B,MAAM,EACN,KAAK,CACN,CACF,CAAC;YAEF,cAAc,CAAC,OAAO,CAAC,CAAC,EAAE,MAAM,EAAE,UAAU,EAAE,EAAE,EAAE,CAChD,IAAI,CAAC,eAAe,CAAC,OAAO,CAC1B,4BAA4B,EAC5B,IAAI,CAAC,kBAAkB,CAAC,MAAM,CAAC,EAC/B,UAAU,EACV,MAAM,EACN,KAAK,CACN,CACF,CAAC;YAEF,OAAO,CAAC,OAAO,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,IAAI,CAAC,kBAAkB,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC;QACtE,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,SAAS,GAAG,eAAe,CAAC,MAAM,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC;YACvE,MAAM,IAAI,CAAC,WAAW,CAAC,SAAS,CAAC,CAAC;YAClC,MAAM,gBAAgB,GAAG,CAAC,GAAG,IAAI,CAAC,kBAAkB,CAAC,IAAI,EAAE,CAAC,CAAC;YAC7D,MAAM,eAAe,GAAG,cAAc;iBACnC,GAAG,CAAC,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,MAAM,CAAC;iBAC3B,MAAM,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,gBAAgB,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC;YACzD,MAAM,IAAI,CAAC,cAAc,CAAC,eAAe,CAAC,CAAC;YAE3C,MAAM,KAAK,CAAC;QACd,CAAC;QAED,OAAO,MAAM,CAAC;IAChB,CAAC;IAED;;;;;;;;;OASG;IACH,wEAAwE;IACxE,WAAW;IACX,gDAAgD;IACxC,KAAK,CAAC,oBAAoB,CAChC,MAAc,EACd,MAAc,EACd,QAAsB,EACtB,YAAyB;QAEzB,MAAM,YAAY,GAAG,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC;QAE/C,6CAA6C;QAC7C,IAAI,YAAY,IAAI,CAAC,QAAQ,CAAC,kBAAkB,EAAE,CAAC;YACjD,IAAI,qBAAqB,CAAC,YAAY,CAAC,OAAO,EAAE,YAAY,CAAC,EAAE,CAAC;gBAC9D,OAAO,YAAY,CAAC;YACtB,CAAC;YAED,OAAO,MAAM,IAAI,CAAC,UAAU,CAC1B,MAAM,EACN,MAAM,EACN,QAAQ,EACR,YAAY;YACZ,sEAAsE;YACtE,0EAA0E;YAC1E,sDAAsD;YACtD,qEAAqE;YACrE,gDAAgD;YAChD,KAAK,CACN,CAAC;QACJ,CAAC;QAED,IAAI,CAAC,sBAAsB,EAAE,CAAC;QAE9B,IAAI,eAAe,GAAG,IAAI,CAAC,eAAe,CAAC;YACzC,MAAM;YACN,MAAM;YACN,IAAI,EAAE,qBAAqB;SAC5B,CAAC,CAAC;QAEH,IAAI,CAAC,eAAe,CAAC,OAAO,CAC1B,mCAAmC,EACnC,MAAM,EACN,MAAM,EACN,KAAK,CACN,CAAC;QAEF,oDAAoD;QACpD,IAAI,YAAY,IAAI,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE,CAAC;YAC3C,MAAM,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,gBAAgB,CAAC,IAAI,CAAC,CAAC;QACrD,CAAC;QAED,4FAA4F;QAC5F,IAAI,YAAY,IAAI,QAAQ,CAAC,kBAAkB,EAAE,CAAC;YAChD,IAAI,CAAC,yBAAyB,CAAC,MAAM,CAAC,CAAC;QACzC,CAAC;QAED,IAAI,CAAC;YACH,MAAM,EAAE,UAAU,EAAE,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC;gBACrC,MAAM;gBACN,EAAE,EAAE,MAAM;gBACV,QAAQ;gBACR,YAAY;aACb,CAAC,CAAC;YAEH,MAAM,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;YAE9C,eAAe,GAAG,IAAI,CAAC,eAAe,CAAC;gBACrC,MAAM;gBACN,MAAM;gBACN,IAAI,EAAE,oBAAoB;aAC3B,CAAC,CAAC;YAEH,MAAM,IAAI,CAAC,UAAU,CAAC;gBACpB,MAAM;gBACN,UAAU;aACX,CAAC,CAAC;YAEH,MAAM,SAAS,GAAG,IAAI,CAAC,kBAAkB,CAAC,MAAM,CAAC,CAAC;YAElD,IAAI,CAAC,eAAe,CAAC,eAAe,CAAC,EAAE,EAAE;gBACvC,OAAO,EAAE,KAAK;gBACd,IAAI,EAAE,qBAAqB;aAC5B,CAAC,CAAC;YAEH,OAAO,SAAS,CAAC;QACnB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,QAAQ,CAAC,qBAAqB,MAAM,GAAG,EAAE,KAAK,CAAC,CAAC;YAEhD,MAAM,WAAW,GACf,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC;YAE5D,IAAI,CAAC,eAAe,CAAC,eAAe,CAAC,EAAE,EAAE;gBACvC,OAAO,EAAE,KAAK;gBACd,IAAI,EAAE,qBAAqB;gBAC3B,KAAK,EAAE,WAAW;aACnB,CAAC,CAAC;YAEH,IAAI,CAAC,eAAe,CAAC,OAAO,CAC1B,kCAAkC,EAClC,MAAM,EACN,MAAM,EACN,KAAK,EACL,WAAW,CACZ,CAAC;YAEF,MAAM,KAAK,CAAC;QACd,CAAC;IACH,CAAC;IAED,eAAe,CAAC,EACd,MAAM,EACN,MAAM,EACN,IAAI,GAKL;QACC,MAAM,EAAE,GAAG,MAAM,EAAE,CAAC;QACpB,MAAM,OAAO,GAAG,IAAI,CAAC,eAAe,CAAC,IAAI,CACvC,+BAA+B,EAC/B;YACE,MAAM;YACN,EAAE;YACF,IAAI;YACJ,WAAW,EAAE;gBACX,wCAAwC;gBACxC,QAAQ,EAAE,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE;gBACpD,MAAM;aACP;YACD,YAAY,EAAE;gBACZ,OAAO,EAAE,IAAI;aACd;SACF,EACD,IAAI,CACL,CAAC;QAEF,OAAO,EAAE,EAAE,EAAE,OAAO,EAAE,CAAC;IACzB,CAAC;IAED,eAAe,CAAC,EAAU,EAAE,YAAkC;QAC5D,IAAI,CAAC;YACH,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,uCAAuC,EAAE;gBACjE,EAAE;gBACF,YAAY;aACb,CAAC,CAAC;QACL,CAAC;QAAC,MAAM,CAAC;YACP,aAAa;QACf,CAAC;IACH,CAAC;IAED;;;;;;;;;;;;;;;;;;OAkBG;IACH,KAAK,CAAC,UAAU,CACd,MAAc,EACd,MAAc,EACd,QAAsB,EACtB,kBAA0B,8BAA8B,EACxD,SAAS,GAAG,IAAI;QAEhB,IAAI,CAAC,sBAAsB,EAAE,CAAC;QAC9B,IAAI,CAAC,qBAAqB,EAAE,CAAC;QAE7B,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;QAEpC,IAAI,IAAI,CAAC,YAAY,EAAE,CAAC;YACtB,MAAM,IAAI,KAAK,CAAC,gDAAgD,CAAC,CAAC;QACpE,CAAC;QAED,IAAI,CAAC,kBAAkB,CAAC,eAAe,CAAC,EAAE,CAAC;YACzC,MAAM,IAAI,KAAK,CACb,yCAAyC,eAAe,IAAI,CAC7D,CAAC;QACJ,CAAC;QAED,IAAI,eAAe,GAAG,IAAI,CAAC,eAAe,CAAC;YACzC,MAAM;YACN,MAAM;YACN,IAAI,EAAE,oBAAoB;SAC3B,CAAC,CAAC;QAEH,IAAI,CAAC;YACH,IAAI,CAAC,eAAe,CAAC,OAAO,CAC1B,mCAAmC,EACnC,MAAM,EACN,MAAM,EACN,IAAI,CACL,CAAC;YAEF,MAAM,WAAW,GAAG,IAAI,CAAC,QAAQ,CAAC;YAElC,MAAM,OAAO,GAAG,MAAM,SAAS,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;YAClD,MAAM,EAAE,UAAU,EAAE,cAAc,EAAE,QAAQ,EAAE,YAAY,EAAE,GAAG,OAAO,CAAC;YAEvE,MAAM,QAAQ,GAAG,YAAY,CAAC,MAAM,CAAC;YAErC,MAAM,UAAU,GAAG,QAAQ,CAAC,OAAO,CAAC;YACpC,IAAI,CAAC,SAAS,CAAC,UAAU,EAAE,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;gBACzC,MAAM,SAAS,CAAC,aAAa,CAC3B,SAAS,MAAM,IAAI,IAAI,CAAC,OAAO,0EAA0E,eAAe,UAAU,CACnI,CAAC;YACJ,CAAC;YAED,IAAI,CAAC,qBAAqB,CAAC,UAAU,EAAE,eAAe,CAAC,EAAE,CAAC;gBACxD,MAAM,IAAI,KAAK,CACb,mCAAmC,MAAM,wBAAwB,UAAU,oDAAoD,eAAe,IAAI,CACnJ,CAAC;YACJ,CAAC;YAED,MAAM,IAAI,CAAC,uBAAuB,CAAC,MAAM,EAAE;gBACzC,OAAO,EAAE,UAAU;gBACnB,QAAQ,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM;gBAChC,WAAW,EAAE,QAAQ,CAAC,kBAAkB;gBACxC,eAAe,EAAE,QAAQ,CAAC,eAAe;aAC1C,CAAC,CAAC;YAEH,MAAM,oBAAoB,GAAG,sBAAsB,CACjD,QAAQ,CAAC,kBAAkB,CAC5B,CAAC;YAEF,IAAI,CAAC,wBAAwB,CAAC,oBAAoB,CAAC,CAAC;YAEpD,MAAM,EAAE,cAAc,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,GAC9D,IAAI,CAAC,2BAA2B,CAAC,MAAM,EAAE,oBAAoB,CAAC,CAAC;YAEjE,MAAM,EAAE,cAAc,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,GAC9D,IAAI,CAAC,2BAA2B,CAC9B,MAAM,EACN,WAAW,CAAC,kBAAkB,IAAI,EAAE,EACpC,QAAQ,CAAC,kBAAkB,IAAI,EAAE,CAClC,CAAC;YAEJ,IAAI,CAAC,eAAe,CAAC,eAAe,CAAC,EAAE,EAAE;gBACvC,WAAW,EAAE,cAAc;gBAC3B,UAAU,EAAE,QAAQ,CAAC,OAAO;gBAC5B,cAAc;gBACd,mBAAmB;gBACnB,iBAAiB;gBACjB,cAAc;gBACd,iBAAiB;gBACjB,mBAAmB;gBACnB,OAAO,EAAE,KAAK;aACf,CAAC,CAAC;YAEH,MAAM,EAAE,WAAW,EAAE,sBAAsB,EAAE,GAAG,WAAW,EAAE,GAC3D,CAAC,MAAM,eAAe,CAAC,OAAO,CAAuB,CAAC;YAExD,eAAe,GAAG,IAAI,CAAC,eAAe,CAAC;gBACrC,MAAM;gBACN,MAAM;gBACN,IAAI,EAAE,oBAAoB;aAC3B,CAAC,CAAC;YAEH,IAAI,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE,CAAC;gBAC3B,MAAM,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,gBAAgB,CAAC,IAAI,CAAC,CAAC;YACrD,CAAC;YAED,IAAI,CAAC,WAAW,CAAC,MAAM,EAAE,gBAAgB,CAAC,MAAM,CAAC,CAAC;YAElD,IAAI,CAAC,IAAI,CAAC;gBACR,MAAM;gBACN,EAAE,EAAE,MAAM;gBACV,KAAK,EAAE,OAAO;gBACd,QAAQ,EAAE,IAAI;aACf,CAAC,CAAC;YAEH,IAAI,CAAC,kBAAkB,CAAC;gBACtB,MAAM;gBACN,iBAAiB;gBACjB,cAAc,EAAE,sBAAsB;gBACtC,WAAW;aACZ,CAAC,CAAC;YAEH,IAAI,QAAQ,CAAC,kBAAkB,EAAE,CAAC;gBAChC,IAAI,CAAC,yBAAyB,CAC5B,MAAM,EACN,WAAW,CAAC,kBAAkB,IAAI,IAAI,EACtC,QAAQ,CAAC,kBAAkB,CAC5B,CAAC;YACJ,CAAC;YAED,MAAM,gBAAgB,GAAG,IAAI,CAAC,oBAAoB,CAAC,MAAM,CAAC,CAAC;YAC3D,IAAI,gBAAgB,KAAK,SAAS,EAAE,CAAC;gBACnC,gBAAgB,CAAC,WAAW,CAAC,OAAO,GAAG,iBAAiB,CAAC;gBACzD,gBAAgB,CAAC,WAAW,CAAC,OAAO,GAAG,sBAAsB,CAAC;gBAC9D,gBAAgB,CAAC,WAAW,CAAC,WAAW,GAAG,WAAW,CAAC;YACzD,CAAC;YAED,MAAM,UAAU,GAAG,cAAc,CAAC,QAAQ,EAAE,CAAC;YAE7C,MAAM,CACJ,OAAO,UAAU,KAAK,QAAQ,IAAI,UAAU,CAAC,MAAM,GAAG,CAAC,EACvD,iCAAiC,MAAM,IAAI,CAC5C,CAAC;YAEF,IAAI,CAAC;gBACH,MAAM,IAAI,CAAC,UAAU,CAAC,EAAE,MAAM,EAAE,UAAU,EAAE,CAAC,CAAC;YAChD,CAAC;YAAC,MAAM,CAAC;gBACP,MAAM,IAAI,KAAK,CAAC,QAAQ,MAAM,oCAAoC,CAAC,CAAC;YACtE,CAAC;YAED,MAAM,aAAa,GAAG,IAAI,CAAC,kBAAkB,CAAC,MAAM,CAAC,CAAC;YAEtD,IAAI,SAAS,EAAE,CAAC;gBACd,IAAI,CAAC,eAAe,CAAC,OAAO,CAC1B,4BAA4B,EAC5B,aAAa,EACb,IAAI,CAAC,OAAO,EACZ,MAAM,EACN,KAAK,CACN,CAAC;YACJ,CAAC;YAED,IAAI,CAAC,eAAe,CAAC,eAAe,CAAC,EAAE,EAAE;gBACvC,OAAO,EAAE,KAAK;gBACd,IAAI,EAAE,oBAAoB;aAC3B,CAAC,CAAC;YAEH,OAAO,aAAa,CAAC;QACvB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,QAAQ,CAAC,uBAAuB,MAAM,GAAG,EAAE,KAAK,CAAC,CAAC;YAElD,MAAM,WAAW,GACf,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC;YAE5D,IAAI,CAAC,eAAe,CAAC,eAAe,CAAC,EAAE,EAAE;gBACvC,OAAO,EAAE,KAAK;gBACd,KAAK,EAAE,WAAW;gBAClB,IAAI,EAAE,oBAAoB;aAC3B,CAAC,CAAC;YAEH,IAAI,CAAC,eAAe,CAAC,OAAO,CAC1B,kCAAkC,EAClC,MAAM,EACN,MAAM,EACN,IAAI,EACJ,WAAW,CACZ,CAAC;YAEF,MAAM,KAAK,CAAC;QACd,CAAC;IACH,CAAC;IAED,KAAK,CAAC,wBAAwB,CAC5B,MAAc,EACd,YAAyB;QAEzB,OAAO,MAAM,IAAI,CAAC,eAAe,CAAC,IAAI,CACpC,8BAA8B,EAC9B,MAAM,EACN,YAAY,CACb,CAAC;IACJ,CAAC;IAED;;;;;;;;OAQG;IACH,KAAK,CAAC,IAAI,CAAC,IAAiB;QAC1B,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,YAAY,EAAE,GAAG,IAAI,CAAC;QAEpD,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC;QAC3B,MAAM,OAAO,GAAG,IAAI,CAAC,iBAAiB,CAAC,MAAM,CAAC,CAAC;QAC/C,IAAI,CAAC,OAAO,CAAC,cAAc,EAAE,CAAC;YAC5B,GAAG,CAAC,gBAAgB,MAAM,EAAE,CAAC,CAAC;YAE9B,uEAAuE;YACvE,qCAAqC;YACrC,OAAO,CAAC,cAAc,GAAG,CAAC,KAAK,IAAI,EAAE;gBACnC,MAAM,WAAW,GAAG,MAAM,SAAS,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;gBACtD,MAAM,QAAQ,GAAG,WAAW,CAAC,QAAQ,CAAC,MAAM,CAAC;gBAC7C,IAAI,CAAC,qBAAqB,CAAC,QAAQ,CAAC,OAAO,EAAE,YAAY,CAAC,EAAE,CAAC;oBAC3D,MAAM,IAAI,KAAK,CACb,mCAAmC,MAAM,wBAAwB,QAAQ,CAAC,OAAO,oDAAoD,YAAY,IAAI,CACtJ,CAAC;gBACJ,CAAC;gBAED,MAAM,IAAI,CAAC,uBAAuB,CAAC,MAAM,EAAE;oBACzC,OAAO,EAAE,QAAQ,CAAC,OAAO;oBACzB,QAAQ,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM;oBAChC,WAAW,EAAE,QAAQ,CAAC,kBAAkB;oBACxC,eAAe,EAAE,QAAQ,CAAC,eAAe;iBAC1C,CAAC,CAAC;gBAEH,OAAO,IAAI,CAAC,IAAI,CAAC;oBACf,GAAG,IAAI;oBACP,KAAK,EAAE,WAAW;oBAClB,EAAE,EAAE,MAAM;iBACX,CAAC,CAAC;YACL,CAAC,CAAC,EAAE,CAAC;QACP,CAAC;QAED,IAAI,CAAC;YACH,OAAO,MAAM,OAAO,CAAC,cAAc,CAAC;QACtC,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,uEAAuE;YACvE,aAAa;YACb,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC;YAC9B,MAAM,KAAK,CAAC;QACd,CAAC;IACH,CAAC;IAED,KAAK,CAAC,UAAU,CAAC,QAAgD;QAC/D,MAAM,EAAE,MAAM,EAAE,GAAG,QAAQ,CAAC;QAC5B,IAAI,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE,CAAC;YAC3B,MAAM,IAAI,KAAK,CAAC,SAAS,MAAM,uBAAuB,CAAC,CAAC;QAC1D,CAAC;QAED,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,IAAI,CAAC,iBAAiB,CAAC,MAAM,CAAC,CAAC;YAC/C,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,eAAe,CAAC,IAAI,CAC5C,8BAA8B,EAC9B;gBACE,GAAG,QAAQ;gBACX,UAAU,EAAE,MAAM,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC;aAC9C,CACF,CAAC;YAEF,IAAI,CAAC,WAAW,CAAC,MAAM,EAAE,gBAAgB,CAAC,KAAK,CAAC,CAAC;YACjD,0FAA0F;YAC1F,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;YACjC,OAAO,MAAM,CAAC;QAChB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC;YAClC,MAAM,KAAK,CAAC;QACd,CAAC;IACH,CAAC;IAED;;;;;;;;;;OAUG;IACH,KAAK,CAAC,cAAc,CAAC,MAAc;QACjC,IAAI,aAAa,GAAa,EAAE,CAAC;QAEjC,KAAK,MAAM,cAAc,IAAI,IAAI,CAAC,gCAAgC,EAAE,CAAC;YACnE,IACE,IAAI,CAAC,eAAe,CAAC,IAAI,CACvB,oCAAoC,EACpC,MAAM,EACN,cAAc,CACf,EACD,CAAC;gBACD,MAAM,UAAU,GAAG,MAAM,IAAI,CAAC,eAAe,CAAC,IAAI,CAChD,oCAAoC,EACpC,MAAM,EACN,cAAc,CACf,CAAC;gBAEF,IAAI,UAAU,EAAE,CAAC;oBACf,gEAAgE;oBAChE,yCAAyC;oBACzC,IACE,CAAC,KAAK,CAAC,OAAO,CAAC,UAAU,CAAC;wBAC1B,UAAU,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,OAAO,KAAK,KAAK,QAAQ,CAAC,EACrD,CAAC;wBACD,MAAM,IAAI,KAAK,CAAC,8CAA8C,CAAC,CAAC;oBAClE,CAAC;oBAED,aAAa,GAAG,aAAa,CAAC,MAAM,CAAC,UAAsB,CAAC,CAAC;gBAC/D,CAAC;YACH,CAAC;QACH,CAAC;QAED,MAAM,iBAAiB,GAAG;YACxB,GAAG,IAAI,GAAG,CAAC,CAAC,GAAG,kBAAkB,EAAE,GAAG,aAAa,CAAC,CAAC;SACtD,CAAC;QAEF,IACE,iBAAiB,CAAC,MAAM;YACxB,kBAAkB,CAAC,MAAM,GAAG,aAAa,CAAC,MAAM,EAChD,CAAC;YACD,QAAQ,CACN,kCAAkC,MAAM,+CAA+C,EACvF,aAAa,CACd,CAAC;QACJ,CAAC;QACD,OAAO,iBAAiB,CAAC;IAC3B,CAAC;IAED;;;;;;;;;;;;;OAaG;IACH,IAAI,CAAC,IAAiB;QACpB,MAAM,EACJ,EAAE,EAAE,MAAM,EACV,MAAM,EACN,KAAK,EACL,QAAQ,GAAG,KAAK,EAChB,SAAS,EACT,YAAY,EACZ,MAAM,EACN,gBAAgB,GACjB,GAAG,IAAI,CAAC;QAET,MAAM,EACJ,QAAQ,EACR,UAAU,EAAE,cAAc,EAC1B,OAAO,EACP,cAAc,EAAE,iBAAiB,EACjC,iBAAiB,GAClB,GAAG,KAAK,CAAC;QAEV,oBAAoB,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;QACtC,MAAM,EAAE,OAAO,EAAE,GAAG,QAAQ,CAAC,MAAM,CAAC;QAEpC,MAAM,UAAU,GAAG,cAAc,CAAC,QAAQ,EAAE,CAAC;QAE7C,MAAM,CACJ,OAAO,UAAU,KAAK,QAAQ,IAAI,UAAU,CAAC,MAAM,GAAG,CAAC,EACvD,iCAAiC,MAAM,IAAI,CAC5C,CAAC;QAEF,MAAM,cAAc,GAAG,iBAAiB,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE;YACpD,MAAM,CAAC,OAAO,IAAI,CAAC,IAAI,CAAC,MAAM,KAAK,QAAQ,CAAC,CAAC;YAC7C,OAAO;gBACL,IAAI,EAAE,IAAI,CAAC,IAAI;gBACf,KAAK,EAAE,IAAI,CAAC,IAAI,CAAC,MAAM;aACxB,CAAC;QACJ,CAAC,CAAC,CAAC;QAEH,MAAM,UAAU,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC;QAEpC,MAAM,YAAY,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC;QAExC,MAAM,sBAAsB,GAAG,YAAY,EAAE,cAAc,IAAI,EAAE,CAAC;QAClE,MAAM,cAAc,GAAG;YACrB,GAAG,sBAAsB;YACzB;gBACE,OAAO;gBACP,IAAI,EAAE,IAAI,CAAC,GAAG,EAAE;gBAChB,MAAM;aACP;SACF,CAAC;QAEF,MAAM,cAAc,GAAG,iBAAiB,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAEpE,MAAM,IAAI,GAAS;YACjB,2CAA2C;YAC3C,GAAG,YAAY;YAEf,sEAAsE;YACtE,kBAAkB;YAClB,OAAO,EAAE,KAAK;YACd,OAAO,EAAE,IAAI;YAEb,SAAS;YACT,YAAY;YACZ,MAAM;YACN,gBAAgB;YAEhB,EAAE,EAAE,MAAM;YACV,kBAAkB,EAAE,QAAQ,CAAC,MAAM,CAAC,kBAAkB;YACtD,kBAAkB,EAAE,QAAQ,CAAC,MAAM,CAAC,kBAAkB;YACtD,QAAQ,EAAE,QAAQ,CAAC,MAAM;YACzB,MAAM,EAAE,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC,OAAgC;YACnE,UAAU;YACV,OAAO;YACP,cAAc;YACd,cAAc;YACd,iBAAiB,EAAE,cAAc;SAClC,CAAC;QAEF,+CAA+C;QAC/C,OAAO,IAAI,CAAC,gBAAgB,CAAC;QAE7B,+BAA+B;QAC/B,MAAM,EAAE,cAAc,EAAE,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,KAAU,EAAE,EAAE;YACpD,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,IAAI,CAAC;QAC7B,CAAC,CAAC,CAAC;QAEH,8DAA8D;QAC9D,oEAAoE;QACpE,IAAI,QAAQ,EAAE,CAAC;YACb,MAAM,gBAAgB,GAAG,IAAI,CAAC,oBAAoB,CAAC,MAAM,CAAC,CAAC;YAC3D,IAAI,gBAAgB,KAAK,SAAS,EAAE,CAAC;gBACnC,gBAAgB,CAAC,YAAY,GAAG,cAAc,CAAC;YACjD,CAAC;QACH,CAAC;QAED,iEAAiE;QACjE,6CAA6C;QAC7C,MAAM,EAAE,YAAY,EAAE,GAAG,wBAAwB,CAC/C,QAAQ,CAAC,MAAM,EACf,IAAI,EACJ,cAAc,CACf,CAAC;QAEF,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,8CAA8C,EAAE;YACxE,WAAW,EAAE,WAAW,CAAC,IAAI;YAC7B,IAAI,EAAE,YAAY;YAClB,MAAM,EAAE,IAAI,CAAC,EAAE;YACf,OAAO;YACP,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,IAAI,IAAI;SACrC,CAAC,CAAC;QAEH,OAAO,EAAE,GAAG,IAAI,EAAE,UAAU,EAAE,CAAC;IACjC,CAAC;IAED,wBAAwB,CACtB,oBAA2E;QAE3E,MAAM,cAAc,GAAG,MAAM,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC;QACzD,MAAM,kBAAkB,GAAG,KAAK,CAAC,IAAI,CACnC,IAAI,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,iBAAiB,CAAC,CAAC,CAC1C,CAAC;QAEF,MAAM,CACJ,cAAc,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,kBAAkB,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,EAC9D,kEAAkE,kBAAkB;aACjF,MAAM,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,KAAK,IAAI,CAAC;aACrC,IAAI,CAAC,IAAI,CAAC,GAAG,CACjB,CAAC;QAEF,MAAM,wBAAwB,GAAG,cAAc,CAAC,MAAM,CACpD,CAAC,MAAM,EAAE,UAAU,EAAE,EAAE;YACrB,IAAI,WAAW,CAAC,IAAI,CAAC,oBAAoB,EAAE,UAAU,CAAC,EAAE,CAAC;gBACvD,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,oBAAoB,CAAC,UAAU,CAAC,CAAC,CAAC;YACrD,CAAC;YAED,OAAO,MAAM,CAAC;QAChB,CAAC,EACD,EAAE,CACH,CAAC;QAEF,MAAM,CACJ,wBAAwB,CAAC,MAAM,KAAK,CAAC,EACrC,6CAA6C,wBAAwB,CAAC,IAAI,CACxE,IAAI,CACL,EAAE,CACJ,CAAC;IACJ,CAAC;IAED;;;;;;;;OAQG;IACH,wBAAwB,CACtB,MAAc,EACd,eAAmC;QAEnC,IAAI,eAAe,KAAK,SAAS,EAAE,CAAC;YAClC,OAAO;QACT,CAAC;QAED,IAAI,EAAE,CAAC,eAAe,EAAE,kBAAkB,EAAE,CAAC,EAAE,CAAC;YAC9C,MAAM,OAAO,GAAG,aAAa,MAAM,gCAAgC,eAAe,yDAAyD,kBAAkB,EAAE,IAAI,CAAC;YAEpK,IAAI,IAAI,CAAC,aAAa,CAAC,4BAA4B,EAAE,CAAC;gBACpD,MAAM,IAAI,KAAK,CAAC,OAAO,CAAC,CAAC;YAC3B,CAAC;YAED,UAAU,CAAC,OAAO,CAAC,CAAC;QACtB,CAAC;IACH,CAAC;IAED;;;;;;;;;OASG;IACH,gDAAgD;IACxC,KAAK,CAAC,SAAS,CACrB,MAAc,EACd,eAAgC;QAEhC,GAAG,CAAC,qBAAqB,MAAM,EAAE,CAAC,CAAC;QACnC,MAAM,UAAU,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC;QACpC,MAAM,IAAI,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC;QAChC,MAAM,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,GAAG,IAAI,CAAC;QAExD,IAAI,CAAC;YACH,MAAM,oBAAoB,GAAG,sBAAsB,CAAC,kBAAkB,CAAC,CAAC;YAExE,IAAI,CAAC,wBAAwB,CAAC,oBAAoB,CAAC,CAAC;YAEpD,IAAI,CAAC,eAAe,CAAC,eAAe,CAAC,EAAE,EAAE;gBACvC,OAAO,EAAE,KAAK;gBACd,WAAW,EAAE,kBAAkB,IAAI,EAAE;gBACrC,WAAW,EAAE,oBAAoB;aAClC,CAAC,CAAC;YAEH,MAAM,EAAE,WAAW,EAAE,mBAAmB,EAAE,GAAG,WAAW,EAAE,GACxD,CAAC,MAAM,eAAe,CAAC,OAAO,CAAuB,CAAC;YAExD,IAAI,CAAC,kBAAkB,CAAC;gBACtB,MAAM;gBACN,cAAc,EAAE,mBAAmB;gBACnC,WAAW;aACZ,CAAC,CAAC;YAEH,IAAI,IAAI,CAAC,QAAQ,CAAC,kBAAkB,EAAE,CAAC;gBACrC,IAAI,CAAC,yBAAyB,CAC5B,MAAM,EACN,IAAI,EACJ,IAAI,CAAC,QAAQ,CAAC,kBAAkB,CACjC,CAAC;YACJ,CAAC;QACH,CAAC;gBAAS,CAAC;YACT,MAAM,OAAO,GAAG,IAAI,CAAC,iBAAiB,CAAC,MAAM,CAAC,CAAC;YAC/C,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC;QAChC,CAAC;IACH,CAAC;IAED,OAAO;QACL,KAAK,CAAC,OAAO,EAAE,CAAC;QAEhB,IAAI,IAAI,CAAC,4BAA4B,EAAE,CAAC;YACtC,YAAY,CAAC,IAAI,CAAC,4BAA4B,CAAC,CAAC;QAClD,CAAC;QAED,sDAAsD;QACtD,IAAI,CAAC,eAAe,CAAC,WAAW,CAC9B,iCAAiC,EACjC,IAAI,CAAC,qBAAqB,CAC3B,CAAC;QAEF,IAAI,CAAC,eAAe,CAAC,WAAW,CAC9B,kCAAkC,EAClC,IAAI,CAAC,kBAAkB,CACxB,CAAC;QAEF,IAAI,CAAC,eAAe,CAAC,WAAW,CAC9B,mCAAmC,EACnC,IAAI,CAAC,mBAAmB,CACzB,CAAC;QAEF,IAAI,CAAC,eAAe,CAAC,uBAAuB,CAC1C,8BAA8B,CAC/B,CAAC;QAEF,IAAI,CAAC,eAAe,CAAC,uBAAuB,CAAC,4BAA4B,CAAC,CAAC;QAC3E,qDAAqD;IACvD,CAAC;IAED;;;;;;;;;OASG;IACH,KAAK,CAAC,aAAa,CAAC,EAClB,MAAM,EACN,MAAM,EACN,OAAO,EAAE,WAAW,EACpB,OAAO,EAAE,UAAU,GACkB;QACrC,IAAI,CAAC,qBAAqB,EAAE,CAAC;QAE7B,MAAM,CACJ,MAAM,KAAK,eAAe,IAAI,UAAU,CAAC,MAAM,CAAC,EAChD,6CAA6C,CAC9C,CAAC;QAEF,MAAM,OAAO,GAAG;YACd,OAAO,EAAE,KAAK;YACd,EAAE,EAAE,MAAM,EAAE;YACZ,GAAG,UAAU;SACd,CAAC;QAEF,sBAAsB,CAAC,OAAO,CAAC,CAAC;QAEhC,MAAM,cAAc,GAAG,iBAAiB,CAAC,WAAW,CAAC,CAAC;QAEtD,MAAM,CACJ,OAAO,cAAc,KAAK,QAAQ,IAAI,cAAc,KAAK,IAAI,EAC7D,mDAAmD,CACpD,CAAC;QAEF,MAAM,WAAW,GAAG,IAAI,CAAC,eAAe,CAAC,IAAI,CAC3C,qCAAqC,EACrC,MAAM,CACP,CAAC;QAEF,wEAAwE;QACxE,IACE,cAAc,KAAK,IAAI;YACvB,CAAC,CAAC,WAAW,IAAI,CAAC,WAAW,CAAC,WAAW,EAAE,cAAc,CAAC,CAAC,EAC3D,CAAC;YACD,MAAM,IAAI,KAAK,CACb,SAAS,MAAM,8BAA8B,cAAc,IAAI,CAChE,CAAC;QACJ,CAAC;QAED,MAAM,kBAAkB,GAAG,cAAc;YACvC,CAAC,CAAE,WAAwD,CACvD,cAAc,CACf;YACH,CAAC,CAAC,SAAS,CAAC;QAEd,IACE,cAAc,KAAK,cAAc,CAAC,GAAG;YACrC,cAAc,KAAK,cAAc,CAAC,OAAO,EACzC,CAAC;YACD,MAAM,CAAC,kBAAkB,CAAC,CAAC;YAE3B,MAAM,OAAO,GAAG,IAAI,CAAC,eAAe,CAAC,IAAI,CACvC,8CAA8C,EAC9C,MAAM,CACP,CAAC;YAEF,MAAM,OAAO,GACX,cAAc,KAAK,cAAc,CAAC,GAAG;gBACnC,CAAC,CAAC,mBAAmB,CAAC,kBAAkB,CAAC;gBACzC,CAAC,CAAC,uBAAuB,CAAC,kBAAkB,CAAC,CAAC;YAClD,MAAM,CAAC,OAAO,CAAC,CAAC;YAEhB,IACE,CAAC,eAAe,CACd,OAAO,EACP,OAAO,EAAE,WAAW,IAAI,WAAW,CAAC,OAAO,EAC3C,MAAM,CACP,EACD,CAAC;gBACD,MAAM,IAAI,KAAK,CACb,SAAS,MAAM,+CAA+C,MAAM,IAAI,CACzE,CAAC;YACJ,CAAC;QACH,CAAC;QAED,IACE,MAAM,KAAK,eAAe;YAC1B,oBAAoB,CAAC,QAAQ,CAAC,WAAW,CAAC,EAC1C,CAAC;YACD,MAAM,IAAI,KAAK,CAAC,IAAI,WAAW,oCAAoC,CAAC,CAAC;QACvE,CAAC;QAED,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,OAAO,EAAE,CAAC;YACtC,MAAM,IAAI,KAAK,CAAC,SAAS,MAAM,gBAAgB,CAAC,CAAC;QACnD,CAAC;QAED,IAAI,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,MAAM,KAAK,UAAU,CAAC,UAAU,EAAE,CAAC;YAC9D,MAAM,IAAI,KAAK,CACb,SAAS,MAAM,yDAAyD,CACzE,CAAC;QACJ,CAAC;QAED,MAAM,OAAO,GAAG,IAAI,CAAC,oBAAoB,CAAC,kBAAkB,CAAC,CAAC;QAE9D,MAAM,OAAO,GAAG,IAAI,CAAC,iBAAiB,CAAC,MAAM,CAAC,CAAC;QAE/C,IAAI,OAAO,CAAC,WAAW,EAAE,CAAC;YACxB,MAAM,OAAO,CAAC,WAAW,CAAC;QAC5B,CAAC;QAED,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE,CAAC;YAC5B,IAAI,CAAC,OAAO,CAAC,YAAY,EAAE,CAAC;gBAC1B,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;YAChD,CAAC;YAED,IAAI,CAAC;gBACH,MAAM,OAAO,CAAC,YAAY,CAAC;YAC7B,CAAC;oBAAS,CAAC;gBACT,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC;YAC9B,CAAC;QACH,CAAC;QAED,MAAM,kBAAkB,GAAG,IAAI,CAAC,wBAAwB,CACtD,MAAM,EACN,WAAW,EACX,OAAO,CACR,CAAC;QAEF,MAAM,KAAK,GAAG,IAAI,KAAK,CAAC,OAAO,CAAC,CAAC;QACjC,IAAI,CAAC,0BAA0B,CAAC,MAAM,EAAE,kBAAkB,CAAC,EAAE,EAAE,KAAK,CAAC,CAAC;QAEtE,MAAM,uBAAuB,GAAG,IAAI,CAAC,eAAe,CAAC,IAAI,CACvD,mCAAmC,EACnC,MAAM,EACN,EAAE,MAAM,EAAE,OAAO,EAAE,WAAW,EAAE,OAAO,EAAE,kBAAkB,EAAE,CAC9D,CAAC;QAEF,gEAAgE;QAChE,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,WAAW,CAAC,uBAAuB,EAAE,KAAK,CAAC,CAAC;YAEjE,IAAI,MAAM,KAAK,WAAW,EAAE,CAAC;gBAC3B,MAAM,QAAQ,GACZ,OAAO,CAAC,WAAW,KAAK,IAAI,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;gBAC1D,MAAM,IAAI,KAAK,CACb,QAAQ;oBACN,CAAC,CAAC,GAAG,MAAM,sFAAsF;oBACjG,CAAC,CAAC,GAAG,MAAM,4CAA4C,CAC1D,CAAC;YACJ,CAAC;YAED,MAAM,IAAI,CAAC,sBAAsB,CAAC,MAAM,EAAE,WAAW,EAAE,MAAM,CAAC,CAAC;YAE/D,MAAM,iBAAiB,GAAG,MAAM,IAAI,CAAC,yBAAyB,CAC5D,MAAM,EACN,WAAW,EACX,kBAAkB,EAClB,MAAM,CACP,CAAC;YAEF,IAAI,CAAC,2BAA2B,CAC9B,MAAM,EACN,kBAAkB,CAAC,EAAE,EACrB,WAAW,EACX,MAAM,EACN,IAAI,CACL,CAAC;YAEF,OAAO,iBAAiB,CAAC;QAC3B,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,0FAA0F;YAC1F,IAAI,CAAC,2BAA2B,CAC9B,MAAM,EACN,kBAAkB,CAAC,EAAE,EACrB,WAAW,EACX,MAAM,EACN,KAAK,CACN,CAAC;YAEF,MAAM,CAAC,YAAY,EAAE,OAAO,CAAC,GAAG,WAAW,CAAC,KAAK,CAAC,CAAC;YAEnD,IAAI,CAAC,OAAO,EAAE,CAAC;gBACb,QAAQ,CACN,IAAI,MAAM,sCAAsC,EAChD,YAAY,CACb,CAAC;gBACF,MAAM,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,gBAAgB,CAAC,KAAK,CAAC,CAAC;YACtD,CAAC;YAED,MAAM,YAAY,CAAC;QACrB,CAAC;IACH,CAAC;IAED;;;;;;;;OAQG;IACH,oBAAoB,CAAC,UAAiC;QACpD,OAAO,uBAAuB,CAAC,UAAU,CAAC,IAAI,IAAI,CAAC,cAAc,CAAC;IACpE,CAAC;IAED;;;;;;;OAOG;IACH,KAAK,CAAC,gBAAgB,CACpB,MAAc,EACd,OAA2B,EAC3B,WAAyB;QAEzB,OAAO,IAAI,CAAC,eAAe,CAAC,IAAI,CAC9B,yCAAyC,EACzC,MAAM,EACN,OAAO,EACP,SAAS,EACT,WAAW,CACZ,CAAC;IACJ,CAAC;IAED,sBAAsB,CAAC,MAAc,EAAE,EAAU;QAC/C,iFAAiF;QACjF,MAAM,CACJ,IAAI,CAAC,eAAe,CAAC,IAAI,CACvB,sCAAsC,EACtC,MAAM,EACN,EAAE,CACH,CACF,CAAC;IACJ,CAAC;IAED;;;;;;;;OAQG;IACH,KAAK,CAAC,yBAAyB,CAC7B,MAAc,EACd,WAAwB,EACxB,OAAgC,EAChC,MAAe;QAEf,QAAQ,WAAW,EAAE,CAAC;YACpB,KAAK,WAAW,CAAC,aAAa,CAAC;YAC/B,KAAK,WAAW,CAAC,WAAW,CAAC;YAC7B,KAAK,WAAW,CAAC,UAAU,CAAC;YAC5B,KAAK,WAAW,CAAC,cAAc,CAAC,CAAC,CAAC;gBAChC,wDAAwD;gBACxD,MAAM,UAAU,GAAG,MAAqC,CAAC;gBAEzD,oEAAoE;gBACpE,IAAI,UAAU,IAAI,WAAW,CAAC,UAAU,EAAE,SAAS,CAAC,EAAE,CAAC;oBACrD,MAAM,EAAE,OAAO,EAAE,GAAG,IAAI,EAAE,GAAG,UAAU,CAAC;oBACxC,MAAM,EAAE,GAAG,MAAM,IAAI,CAAC,gBAAgB,CACpC,MAAM,EACN,OAA6B,CAC9B,CAAC;oBAEF,OAAO,EAAE,GAAG,IAAI,EAAE,EAAE,EAAE,CAAC;gBACzB,CAAC;gBACD,OAAO,MAAM,CAAC;YAChB,CAAC;YACD,KAAK,WAAW,CAAC,cAAc;gBAC7B,wEAAwE;gBACxE,OAAO,IAAI,CAAC,8BAA8B,CACxC,MAAM,EACN,OAA8C,EAC9C,MAAgC,CACjC,CAAC;YAEJ,KAAK,WAAW,CAAC,kBAAkB;gBACjC,wEAAwE;gBACxE,OAAO,IAAI,CAAC,kCAAkC,CAC5C,OAEC,EACD,MAAoC,CACrC,CAAC;YAEJ,KAAK,WAAW,CAAC,kBAAkB;gBACjC,wEAAwE;gBACxE,OAAO,IAAI,CAAC,kCAAkC,CAC5C,OAAkD,EAClD,MAAoC,CACrC,CAAC;YAEJ;gBACE,OAAO,MAAM,CAAC;QAClB,CAAC;IACH,CAAC;IAED;;;;;;;;;;;;OAYG;IACH,8BAA8B,CAC5B,MAAc,EACd,EAAE,MAAM,EAAE,eAAe,EAAuC,EAChE,EAAE,MAAM,EAA0B;QAElC,MAAM,WAAW,GAAG,IAAI,CAAC,eAAe,CAAC,IAAI,CAC3C,qCAAqC,EACrC,MAAM,CACP,CAAC;QACF,yDAAyD;QACzD,MAAM,CAAC,WAAW,CAAC,CAAC;QAEpB,MAAM,UAAU,GAAG,WAAW,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC;QACtD,MAAM,MAAM,GAAG,iBAAiB,CAAC,UAAU,CAAC,CAAC;QAC7C,MAAM,CAAC,MAAM,CAAC,CAAC;QAEf,MAAM,EAAE,MAAM,EAAE,eAAe,EAAE,GAAG,eAAe,CAAC;QAEpD,MAAM,cAAc,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,MAAM,CAE/C,CAAC,WAAW,EAAE,SAAS,EAAE,EAAE;YAC3B,MAAM,aAAa,GAAG,SAA0B,CAAC;YACjD,MAAM,OAAO,GACX,MAAM,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,aAAa,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;gBACvD,eAAe,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAC;YAC1C,sFAAsF;YACtF,IAAI,OAAO,EAAE,CAAC;gBACZ,WAAW,CAAC,aAAa,CAAC,GAAG,MAAM,CAAC,aAAa,CAAC,CAAC;YACrD,CAAC;YACD,OAAO,WAAW,CAAC;QACrB,CAAC,EAAE,EAAE,CAAC,CAAC;QACP,OAAO,EAAE,MAAM,EAAE,cAAc,EAAE,CAAC;IACpC,CAAC;IAED;;;;;;;;;;;OAWG;IACH,kCAAkC,CAChC,EAAE,MAAM,EAAE,eAAe,EAA2C,EACpE,EAAE,eAAe,EAA8B;QAE/C,MAAM,EAAE,WAAW,EAAE,oBAAoB,EAAE,GAAG,eAAe,CAAC;QAE9D,MAAM,uBAAuB,GAAG,oBAAoB,CAAC,MAAM,CAEzD,CAAC,WAAW,EAAE,UAAU,EAAE,EAAE;YAC5B,MAAM,IAAI,GAAG,eAAe,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC;YAC/D,mDAAmD;YACnD,IAAI,IAAI,EAAE,CAAC;gBACT,WAAW,CAAC,UAAU,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC;gBACpC,WAAW,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,UAAU,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC;YACrD,CAAC;YACD,OAAO,WAAW,CAAC;QACrB,CAAC,EAAE,EAAE,CAAC,CAAC;QACP,OAAO,EAAE,eAAe,EAAE,uBAAuB,EAAE,CAAC;IACtD,CAAC;IAED;;;;;;;;;;;OAWG;IACH,kCAAkC,CAChC,EAAE,MAAM,EAAE,eAAe,EAA2C,EACpE,EAAE,UAAU,EAA8B;QAE1C,MAAM,EAAE,MAAM,EAAE,eAAe,EAAE,GAAG,eAAe,CAAC;QAEpD,MAAM,kBAAkB,GAAG,eAAe,CAAC,MAAM,CAE/C,CAAC,WAAW,EAAE,MAAM,EAAE,EAAE;YACxB,MAAM,MAAM,GAAG,UAAU,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;YACvD,mDAAmD;YACnD,IAAI,MAAM,EAAE,CAAC;gBACX,WAAW,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;gBACjC,WAAW,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC;YAClD,CAAC;YACD,OAAO,WAAW,CAAC;QACrB,CAAC,EAAE,EAAE,CAAC,CAAC;QACP,OAAO,EAAE,UAAU,EAAE,kBAAkB,EAAE,CAAC;IAC5C,CAAC;IAED;;;;;;;OAOG;IACH,wBAAwB,CACtB,MAAc,EACd,WAAwB,EACxB,OAAuB;QAEvB,QAAQ,WAAW,EAAE,CAAC;YACpB,mGAAmG;YACnG,KAAK,WAAW,CAAC,WAAW,CAAC,CAAC,CAAC;gBAC7B,MAAM,CAAC,OAAO,CAAC,MAAM,IAAI,WAAW,CAAC,OAAO,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC,CAAC;gBAE5D,MAAM,WAAW,GAAG,OAAO,CAAC,MAAM,CAAC,EAAY,CAAC;gBAChD,MAAM,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC,eAAe,CAAC,IAAI,CAC3C,sCAAsC,EACtC,MAAM,EACN,WAAW,CACZ,CAAC;gBAEF,OAAO;oBACL,GAAG,OAAO;oBACV,MAAM,EAAE,EAAE,GAAG,OAAO,CAAC,MAAM,EAAE,OAAO,EAAE;iBACvC,CAAC;YACJ,CAAC;YAED;gBACE,OAAO,OAAO,CAAC;QACnB,CAAC;IACH,CAAC;IAED;;;;;;OAMG;IACH,KAAK,CAAC,sBAAsB,CAC1B,MAAc,EACd,WAAwB,EACxB,MAAe;QAEf,QAAQ,WAAW,EAAE,CAAC;YACpB,KAAK,WAAW,CAAC,aAAa,CAAC,CAAC,CAAC;gBAC/B,YAAY,CAAC,MAAM,EAAE,2BAA2B,CAAC,CAAC;gBAElD,IAAI,MAAM,IAAI,WAAW,CAAC,MAAM,EAAE,IAAI,CAAC,EAAE,CAAC;oBACxC,IAAI,CAAC,sBAAsB,CAAC,MAAM,EAAE,MAAM,CAAC,EAAY,CAAC,CAAC;gBAC3D,CAAC;gBAED,MAAM;YACR,CAAC;YACD,KAAK,WAAW,CAAC,WAAW,CAAC,CAAC,CAAC;gBAC7B,YAAY,CAAC,MAAM,EAAE,yBAAyB,CAAC,CAAC;gBAEhD,IAAI,MAAM,IAAI,WAAW,CAAC,MAAM,EAAE,IAAI,CAAC,EAAE,CAAC;oBACxC,IAAI,CAAC,sBAAsB,CAAC,MAAM,EAAE,MAAM,CAAC,EAAY,CAAC,CAAC;gBAC3D,CAAC;gBAED,MAAM;YACR,CAAC;YACD,KAAK,WAAW,CAAC,UAAU,CAAC,CAAC,CAAC;gBAC5B,YAAY,CAAC,MAAM,EAAE,wBAAwB,CAAC,CAAC;gBAE/C,IAAI,MAAM,IAAI,WAAW,CAAC,MAAM,EAAE,IAAI,CAAC,EAAE,CAAC;oBACxC,IAAI,CAAC,sBAAsB,CAAC,MAAM,EAAE,MAAM,CAAC,EAAY,CAAC,CAAC;gBAC3D,CAAC;gBAED,MAAM;YACR,CAAC;YACD,KAAK,WAAW,CAAC,cAAc,CAAC,CAAC,CAAC;gBAChC,YAAY,CAAC,MAAM,EAAE,4BAA4B,CAAC,CAAC;gBAEnD,IAAI,MAAM,IAAI,WAAW,CAAC,MAAM,EAAE,IAAI,CAAC,EAAE,CAAC;oBACxC,IAAI,CAAC,sBAAsB,CAAC,MAAM,EAAE,MAAM,CAAC,EAAY,CAAC,CAAC;gBAC3D,CAAC;gBAED,MAAM;YACR,CAAC;YACD,KAAK,WAAW,CAAC,YAAY;gBAC3B,YAAY,CAAC,MAAM,EAAE,0BAA0B,CAAC,CAAC;gBACjD,MAAM;YACR,KAAK,WAAW,CAAC,cAAc;gBAC7B,YAAY,CAAC,MAAM,EAAE,4BAA4B,CAAC,CAAC;gBACnD,MAAM;YACR,KAAK,WAAW,CAAC,kBAAkB;gBACjC,YAAY,CAAC,MAAM,EAAE,gCAAgC,CAAC,CAAC;gBACvD,MAAM;YACR,KAAK,WAAW,CAAC,sBAAsB;gBACrC,YAAY,CAAC,MAAM,EAAE,oCAAoC,CAAC,CAAC;gBAC3D,MAAM;YACR,KAAK,WAAW,CAAC,kBAAkB;gBACjC,YAAY,CAAC,MAAM,EAAE,gCAAgC,CAAC,CAAC;gBACvD,MAAM;YACR;gBACE,MAAM;QACV,CAAC;IACH,CAAC;IAED,0BAA0B,CAAC,MAAc,EAAE,SAAkB,EAAE,KAAY;QACzE,MAAM,OAAO,GAAG,IAAI,CAAC,iBAAiB,CAAC,MAAM,CAAC,CAAC;QAC/C,OAAO,CAAC,sBAAsB,CAAC,IAAI,CAAC,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC,CAAC;QAC1D,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC;IAC7B,CAAC;IAED,2BAA2B,CACzB,MAAc,EACd,SAAkB,EAClB,WAAwB,EACxB,MAAc,EACd,OAAgB;QAEhB,MAAM,OAAO,GAAG,IAAI,CAAC,iBAAiB,CAAC,MAAM,CAAC,CAAC;QAC/C,OAAO,CAAC,sBAAsB,GAAG,OAAO,CAAC,sBAAsB,CAAC,MAAM,CACpE,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,SAAS,KAAK,SAAS,CAC7C,CAAC;QAEF,IAAI,OAAO,CAAC,sBAAsB,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAChD,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QACnC,CAAC;QAED,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QAE9B,IAAI,kBAAkB,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,EAAE,YAAY,EAAE,CAAC;YAC3D,IAAI,CAAC;gBACH,IAAI,CAAC,gBAAgB,CAAC,MAAM,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC;YAC9D,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,QAAQ,CACN,iDAAiD,IAAI,EAAE,EAAE,MAAM,eAAe,CAC5E,KAAK,CACN,EAAE,CACJ,CAAC;YACJ,CAAC;QACH,CAAC;IACH,CAAC;IAED;;;;;OAKG;IACH,oBAAoB,CAAC,MAAc;QACjC,OAAO,IAAI,CAAC,kBAAkB,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;IAC7C,CAAC;IAED;;;;;;;OAOG;IACH,uBAAuB,CAAC,MAAc;QACpC,MAAM,CACJ,IAAI,CAAC,kBAAkB,CAAC,GAAG,CAAC,MAAM,CAAC,KAAK,SAAS,EACjD,IAAI,KAAK,CAAC,SAAS,MAAM,qCAAqC,CAAC,CAChE,CAAC;QAEF,IAAI,CAAC,kBAAkB,CAAC,GAAG,CAAC,MAAM,EAAE;YAClC,YAAY,EAAE,EAAE;YAChB,WAAW,EAAE,EAAE;YACf,UAAU,EAAE,EAAE;SACf,CAAC,CAAC;QAEH,MAAM,mBAAmB,GAAG,IAAI,CAAC,kBAAkB,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QAEhE,MAAM,CACJ,mBAAmB,KAAK,SAAS,EACjC,IAAI,KAAK,CAAC,gCAAgC,MAAM,GAAG,CAAC,CACrD,CAAC;QACF,OAAO,mBAAmB,CAAC;IAC7B,CAAC;IAED;;;;;;;;;;OAUG;IACH,KAAK,CAAC,aAAa,CAAC,MAAc;QAChC,MAAM,gBAAgB,GAAG,IAAI,CAAC,oBAAoB,CAAC,MAAM,CAAC,CAAC;QAC3D,IAAI,CAAC,gBAAgB,EAAE,CAAC;YACtB,MAAM,IAAI,KAAK,CAAC,0CAA0C,CAAC,CAAC;QAC9D,CAAC;QAED,MAAM,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,gBAAgB,CAAC,IAAI,CAAC,CAAC;QACnD,4DAA4D;QAC5D,IAAI,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,MAAM,KAAK,UAAU,CAAC,OAAO,EAAE,CAAC;YACpD,IAAI,CAAC,WAAW,CAAC,MAAM,EAAE,gBAAgB,CAAC,IAAI,CAAC,CAAC;QAClD,CAAC;QAED,MAAM,EAAE,YAAY,EAAE,WAAW,EAAE,GAAG,gBAAgB,CAAC;QAEvD,IAAI,YAAY,EAAE,MAAM,EAAE,CAAC;YACzB,IAAI,CAAC,YAAY,CAAC,YAAY,CAAC,CAAC;QAClC,CAAC;QAED,uFAAuF;QACvF,yCAAyC;QACzC,IAAI,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,MAAM,KAAK,UAAU,CAAC,OAAO,EAAE,CAAC;YACpD,IAAI,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE;gBACpB,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,MAAM,GAAG,UAAU,CAAC,OAAO,CAAC;YAClD,CAAC,CAAC,CAAC;QACL,CAAC;QAED,IAAI,CAAC,kBAAkB,CAAC;YACtB,MAAM;YACN,iBAAiB,EAAE,WAAW,CAAC,OAAO;YACtC,cAAc,EAAE,WAAW,CAAC,OAAO;YACnC,WAAW,EAAE,WAAW,CAAC,WAAW;SACrC,CAAC,CAAC;QAEH,MAAM,aAAa,GAAG,IAAI,CAAC,kBAAkB,CAAC,MAAM,CAAC,CAAC;QAEtD,IAAI,CAAC,eAAe,CAAC,OAAO,CAC1B,+BAA+B,EAC/B,aAAa,EACb,gBAAgB,CAAC,UAAU,CAC5B,CAAC;QAEF,IAAI,CAAC,kBAAkB,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IACzC,CAAC;IAED;;;;;OAKG;IACH,KAAK,CAAC,cAAc,CAAC,OAAiB;QACpC,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;YAC7B,MAAM,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC;QACnC,CAAC;IACH,CAAC;IAED,WAAW,CAAC,MAAc;QACxB,OAAO,IAAI,CAAC,iBAAiB,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;IAC5C,CAAC;IAED,iBAAiB,CAAC,MAAc;QAC9B,MAAM,OAAO,GAAG,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;QACzC,MAAM,CACJ,OAAO,KAAK,SAAS,EACrB,IAAI,KAAK,CAAC,SAAS,MAAM,0BAA0B,CAAC,CACrD,CAAC;QACF,OAAO,OAAO,CAAC;IACjB,CAAC;IAED,aAAa,CAAC,MAAc;QAC1B,IAAI,IAAI,CAAC,iBAAiB,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC;YACvC,OAAO;QACT,CAAC;QAED,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QAC9B,MAAM,WAAW,GAAG,SAAS,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;QACnD,WAAW,CAAC,KAAK,CAAC;YAChB,OAAO,EAAE,EAAE,MAAM,EAAE;YACnB,KAAK,EACH,IAAI,EAAE,MAAM;gBACX,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC,OAAiC;SAChE,CAAC,CAAC;QAEH,WAAW,CAAC,WAAW,CAAC,CAAC;QAEzB,IAAI,CAAC,iBAAiB,CAAC,GAAG,CAAC,MAAM,EAAE;YACjC,WAAW,EAAE,IAAI;YACjB,YAAY,EAAE,IAAI;YAClB,WAAW,EAAE,IAAI;YACjB,cAAc,EAAE,IAAI;YACpB,aAAa,EAAE,IAAI;YACnB,cAAc,EAAE,IAAI;YACpB,gBAAgB,EAAE,CAAC;YACnB,sBAAsB,EAAE,EAAE;YAC1B,uBAAuB,EAAE,CAAC;YAC1B,WAAW;YACX,UAAU,EAAE,IAAI,KAAK,EAAE;YACvB,aAAa,EAAE,IAAI,KAAK,EAAE;SAC3B,CAAC,CAAC;IACL,CAAC;IAED,2BAA2B,CACzB,MAAc,EACd,qBAGC;QAUD,MAAM,cAAc,GAClB,IAAI,CAAC,eAAe,CAAC,IAAI,CACvB,qCAAqC,EACrC,MAAM,CACP,IAAI,EAAE,CAAC;QAEV,MAAM,cAAc,GAAG,eAAe,CACpC,qBAAqB,EACrB,cAAc,CACf,CAAC;QACF,qFAAqF;QACrF,oDAAoD;QACpD,MAAM,iBAAiB,GAAG,eAAe,CACvC,cAAc,EACd,qBAAqB,CACtB,CAAC;QAEF,sEAAsE;QACtE,qGAAqG;QACrG,MAAM,mBAAmB,GAAG,eAAe,CACzC,cAAc,EACd,iBAAiB,CAClB,CAAC;QAEF,OAAO,EAAE,cAAc,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,CAAC;IACpE,CAAC;IAED,yBAAyB,CAAC,MAAc,EAAE,MAAc;QACtD,MAAM,kBAAkB,GAAG,IAAI,CAAC,eAAe,CAAC,IAAI,CAClD,qCAAqC,EACrC,MAAM,CACqC,CAAC;QAE9C,MAAM,cAAc,GAAG,kBAAkB,EAAE,CACzC,0BAA0B,CAC3B,EAAE,OAAO,EAAE,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,KAAK,cAAc,CAAC,OAAO,CAAC,CAAC;QAErE,OAAO,OAAO,CAAE,cAAc,EAAE,KAA8B,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC;IAC5E,CAAC;IAED,2BAA2B,CACzB,MAAc,EACd,iBAAuC,EACvC,qBAA2C;QAM3C,2EAA2E;QAC3E,4CAA4C;QAC5C,MAAM,sBAAsB,GAAG,MAAM,CAAC,IAAI,CAAC,iBAAiB,CAAC;aAC1D,MAAM,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,IAAI,CAAC,yBAAyB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;aAClE,MAAM,CAAuB,CAAC,WAAW,EAAE,MAAM,EAAE,EAAE;YACpD,WAAW,CAAC,MAAM,CAAC,GAAG,iBAAiB,CAAC,MAAM,CAAC,CAAC;YAChD,OAAO,WAAW,CAAC;QACrB,CAAC,EAAE,EAAE,CAAC,CAAC;QAET,MAAM,cAAc,GAAG,OAAO,CAC5B,qBAAqB,EACrB,sBAAsB,CACvB,CAAC;QAEF,MAAM,iBAAiB,GAAG,OAAO,CAC/B,sBAAsB,EACtB,qBAAqB,CACtB,CAAC;QAEF,sEAAsE;QACtE,qGAAqG;QACrG,MAAM,mBAAmB,GAAG,OAAO,CACjC,sBAAsB,EACtB,iBAAiB,CAClB,CAAC;QAEF,OAAO,EAAE,cAAc,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,CAAC;IACpE,CAAC;IAED;;;;;;;OAOG;IACH,sBAAsB,CAAC,MAAc,EAAE,cAAoC;QACzE,IACE,IAAI,CAAC,aAAa,CAAC,mBAAmB;YACtC,MAAM,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC,QAAQ,CAAC,cAAc,CAAC,gBAAgB,CAAC,EACrE,CAAC;YACD,0EAA0E;YAC1E,WAAW;YACX,MAAM,eAAe,GAAG,IAAI,CAAC,eAAe,CAAC,IAAI,CAC/C,uDAAuD,EACvD,MAAM,CACP,CAAC;YAEF,MAAM,EAAE,aAAa,EAAE,GAAG,IAAI,CAAC,eAAe,CAAC,IAAI,CACjD,wCAAwC,EACxC,eAAe,CAChB,CAAC;YAEF,MAAM,OAAO,GAAG,WAAW,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC;YAEnD,2DAA2D;YAC3D,MAAM,mBAAmB,GAAyB;gBAChD,GAAG,cAAc;gBACjB,kBAAkB,EAAE;oBAClB,OAAO,EAAE;wBACP;4BACE,IAAI,EAAE,kBAAkB;4BACxB,KAAK,EAAE;gCACL,cAAc,EAAE,EAAE;gCAClB,cAAc,EAAE;oCACd,CAAC,UAAU,OAAO,EAAE,CAAC,EAAE;wCACrB,QAAQ,EAAE,EAAE;qCACb;iCACF;gCACD,iBAAiB,EAAE,EAAE;gCACrB,kBAAkB,EAAE,KAAK;6BAC1B;yBACF;qBACF;iBACF;aACF,CAAC;YAEF,OAAO,mBAAmB,CAAC;QAC7B,CAAC;QAED,OAAO,cAAc,CAAC;IACxB,CAAC;IAED;;;;;;;;;;OAUG;IACH,kBAAkB,CAAC,EACjB,MAAM,EACN,iBAAiB,GAAG,EAAE,EACtB,cAAc,GAAG,EAAE,EACnB,WAAW,GAUZ;QACC,MAAM,qBAAqB,GAAG,MAAM,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;QAC7D,IAAI,eAAe,CAAC,qBAAqB,CAAC,EAAE,CAAC;YAC3C,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,wCAAwC,EAAE;gBAClE,CAAC,MAAM,CAAC,EAAE,qBAAqB;aAChC,CAAC,CAAC;QACL,CAAC;QAED,IAAI,eAAe,CAAC,MAAM,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC,EAAE,CAAC;YACjD,MAAM,mBAAmB,GAAG,IAAI,CAAC,sBAAsB,CACrD,MAAM,EACN,cAAc,CACf,CAAC;YAEF,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,uCAAuC,EAAE;gBACjE,mBAAmB;gBACnB,OAAO,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE;gBAC3B,WAAW;aACZ,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED;;;;;;;;;;;;;;OAcG;IACH,cAAc,CAAC,MAAc,EAAE,eAA4B;QACzD,MAAM,YAAY,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;QAE5C,IAAI,qBAAqB,CAAC,YAAY,CAAC,OAAO,EAAE,eAAe,CAAC,EAAE,CAAC;YACjE,OAAO,KAAK,CAAC;QACf,CAAC;QAED,IAAI,OAAO,CAAC,YAAY,CAAC,OAAO,EAAE,eAAe,CAAC,EAAE,CAAC;YACnD,OAAO,KAAK,CAAC;QACf,CAAC;QAED,OAAO,IAAI,CAAC;IACd,CAAC;IAED;;;;;;;;;;OAUG;IACH,KAAK,CAAC,kBAAkB,CACtB,MAAc,EACd,MAAc,EACd,OAAoB;QAEpB,MAAM,cAAc,GAAG,iBAAiB,CAAC,OAAO,CAAC,CAAC;QAElD,MAAM,CAAC,cAAc,EAAE,wCAAwC,CAAC,CAAC;QAEjE,MAAM,aAAa,GAAG,IAAI,CAAC,eAAe,CAAC,IAAI,CAC7C,oCAAoC,EACpC,MAAM,EACN,cAAc,CACf,CAAC;QAEF,IAAI,CAAC,aAAa,EAAE,CAAC;YACnB,OAAO;QACT,CAAC;QAED,MAAM,IAAI,CAAC,aAAa,CAAC;YACvB,MAAM;YACN,OAAO;YACP,MAAM;YACN,OAAO,EAAE;gBACP,OAAO,EAAE,KAAK;gBACd,MAAM,EAAE,OAAO;aAChB;SACF,CAAC,CAAC;IACL,CAAC;IAED;;;;OAIG;IACH,WAAW;QACT,KAAK,MAAM,OAAO,IAAI,IAAI,CAAC,iBAAiB,CAAC,MAAM,EAAE,EAAE,CAAC;YACtD,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC;YAC7B,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC;YAC9B,OAAO,CAAC,KAAK,GAAG,SAAS,CAAC;QAC5B,CAAC;IACH,CAAC;CACF","sourcesContent":["import type {\n AddApprovalRequest,\n UpdateRequestState,\n} from '@metamask/approval-controller';\nimport type {\n RestrictedMessenger,\n ControllerGetStateAction,\n ControllerStateChangeEvent,\n} from '@metamask/base-controller';\nimport { BaseController } from '@metamask/base-controller';\nimport type { CryptographicFunctions } from '@metamask/key-tree';\nimport type {\n Caveat,\n GetEndowments,\n GetPermissions,\n GetSubjectMetadata,\n AddSubjectMetadata,\n GetSubjects,\n GrantPermissions,\n HasPermission,\n HasPermissions,\n PermissionConstraint,\n PermissionsRequest,\n RequestedPermissions,\n RevokeAllPermissions,\n RevokePermissionForAllSubjects,\n RevokePermissions,\n SubjectPermissions,\n UpdateCaveat,\n ValidPermission,\n} from '@metamask/permission-controller';\nimport { SubjectType } from '@metamask/permission-controller';\nimport { rpcErrors } from '@metamask/rpc-errors';\nimport type { BlockReason } from '@metamask/snaps-registry';\nimport {\n WALLET_SNAP_PERMISSION_KEY,\n getMaxRequestTimeCaveat,\n handlerEndowments,\n SnapEndowments,\n getKeyringCaveatOrigins,\n getRpcCaveatOrigins,\n processSnapPermissions,\n getEncryptionEntropy,\n getChainIdsCaveat,\n} from '@metamask/snaps-rpc-methods';\nimport type {\n RequestSnapsParams,\n RequestSnapsResult,\n SnapId,\n ComponentOrElement,\n ContentType,\n OnAssetsLookupResponse,\n FungibleAssetMetadata,\n OnAssetsConversionResponse,\n OnAssetsConversionArguments,\n AssetConversion,\n OnAssetsLookupArguments,\n OnAssetsMarketDataArguments,\n FungibleAssetMarketData,\n OnAssetsMarketDataResponse,\n} from '@metamask/snaps-sdk';\nimport {\n AuxiliaryFileEncoding,\n getErrorMessage,\n OnAssetsLookupResponseStruct,\n} from '@metamask/snaps-sdk';\nimport type {\n FetchedSnapFiles,\n InitialConnections,\n PersistedSnap,\n Snap,\n SnapManifest,\n SnapPermissions,\n SnapRpcHookArgs,\n StatusContext,\n StatusEvents,\n StatusStates,\n TruncatedSnap,\n TruncatedSnapFields,\n} from '@metamask/snaps-utils';\nimport {\n logWarning,\n getPlatformVersion,\n assertIsSnapManifest,\n assertIsValidSnapId,\n DEFAULT_ENDOWMENTS,\n DEFAULT_REQUESTED_SNAP_VERSION,\n encodeAuxiliaryFile,\n HandlerType,\n isOriginAllowed,\n logError,\n normalizeRelative,\n OnTransactionResponseStruct,\n OnSignatureResponseStruct,\n resolveVersionRange,\n SnapCaveatType,\n SnapStatus,\n SnapStatusEvents,\n unwrapError,\n OnHomePageResponseStruct,\n getValidatedLocalizationFiles,\n VirtualFile,\n NpmSnapFileNames,\n OnNameLookupResponseStruct,\n getLocalizedSnapManifest,\n MAX_FILE_SIZE,\n OnSettingsPageResponseStruct,\n isValidUrl,\n OnAssetHistoricalPriceResponseStruct,\n OnAssetsConversionResponseStruct,\n OnAssetsMarketDataResponseStruct,\n} from '@metamask/snaps-utils';\nimport type {\n Json,\n NonEmptyArray,\n SemVerRange,\n CaipAssetType,\n JsonRpcRequest,\n Hex,\n SemVerVersion,\n} from '@metamask/utils';\nimport {\n hexToNumber,\n assert,\n assertIsJsonRpcRequest,\n assertStruct,\n Duration,\n gtRange,\n gtVersion,\n hasProperty,\n inMilliseconds,\n isNonEmptyArray,\n isValidSemVerRange,\n satisfiesVersionRange,\n timeSince,\n createDeferredPromise,\n} from '@metamask/utils';\nimport type { StateMachine } from '@xstate/fsm';\nimport { createMachine, interpret } from '@xstate/fsm';\nimport { Mutex } from 'async-mutex';\nimport type { Patch } from 'immer';\nimport { nanoid } from 'nanoid';\nimport { gt, gte } from 'semver';\n\nimport {\n ALLOWED_PERMISSIONS,\n CLIENT_ONLY_HANDLERS,\n LEGACY_ENCRYPTION_KEY_DERIVATION_OPTIONS,\n METAMASK_ORIGIN,\n STATE_DEBOUNCE_TIMEOUT,\n} from './constants';\nimport type { SnapLocation } from './location';\nimport { detectSnapLocation } from './location';\nimport type {\n GetMetadata,\n GetResult,\n ResolveVersion,\n SnapsRegistryInfo,\n SnapsRegistryRequest,\n Update,\n} from './registry';\nimport { SnapsRegistryStatus } from './registry';\nimport { getRunnableSnaps } from './selectors';\nimport { Timer } from './Timer';\nimport { forceStrict, validateMachine } from '../fsm';\nimport type { CreateInterface, GetInterface } from '../interface';\nimport { log } from '../logging';\nimport type {\n ExecuteSnapAction,\n ExecutionServiceEvents,\n HandleRpcRequestAction,\n SnapErrorJson,\n TerminateAllSnapsAction,\n TerminateSnapAction,\n} from '../services';\nimport type {\n EncryptionResult,\n ExportableKeyEncryptor,\n KeyDerivationOptions,\n} from '../types';\nimport {\n debouncePersistState,\n fetchSnap,\n hasTimedOut,\n permissionsDiff,\n setDiff,\n throttleTracking,\n withTimeout,\n isTrackableHandler,\n} from '../utils';\n\nexport const controllerName = 'SnapController';\n\n// TODO: Figure out how to name these\nexport const SNAP_APPROVAL_INSTALL = 'wallet_installSnap';\nexport const SNAP_APPROVAL_UPDATE = 'wallet_updateSnap';\nexport const SNAP_APPROVAL_RESULT = 'wallet_installSnapResult';\n\nconst TRUNCATED_SNAP_PROPERTIES = new Set<TruncatedSnapFields>([\n 'initialPermissions',\n 'id',\n 'version',\n 'enabled',\n 'blocked',\n]);\n\nexport type PendingRequest = {\n requestId: unknown;\n timer: Timer;\n};\n\nexport type PreinstalledSnapFile = {\n path: string;\n value: string | Uint8Array;\n};\n\nexport type PreinstalledSnap = {\n snapId: SnapId;\n manifest: SnapManifest;\n files: PreinstalledSnapFile[];\n removable?: boolean;\n hidden?: boolean;\n hideSnapBranding?: boolean;\n};\n\n/**\n * A wrapper type for any data stored during runtime of Snaps.\n * It is not persisted in state as it contains non-serializable data and is only relevant for the\n * current session.\n */\nexport type SnapRuntimeData = {\n /**\n * A promise that resolves when the Snap has finished installing\n */\n installPromise: null | Promise<PersistedSnap>;\n\n /**\n * A promise that resolves when the Snap has finished booting\n */\n startPromise: null | Promise<void>;\n\n /**\n * A promise that resolves when the Snap has finished stopping\n */\n stopPromise: null | Promise<void>;\n\n /**\n * A Unix timestamp for the last time the Snap received an RPC request\n */\n lastRequest: null | number;\n\n /**\n * The current number of active references where this Snap is being used\n */\n activeReferences: number;\n\n /**\n * The current pending inbound requests, meaning requests that are processed by snaps.\n */\n pendingInboundRequests: PendingRequest[];\n\n /**\n * The current pending outbound requests, meaning requests made from snaps towards the MetaMask\n * extension.\n */\n pendingOutboundRequests: number;\n\n /**\n * The finite state machine interpreter for possible states that the Snap can be in such as\n * stopped, running, blocked\n *\n * @see {@link SnapController:constructor}\n */\n interpreter: StateMachine.Service<StatusContext, StatusEvents, StatusStates>;\n\n /**\n * Cached encryption key used for state encryption.\n */\n encryptionKey: string | null;\n\n /**\n * Cached encryption salt used for state encryption.\n */\n encryptionSalt: string | null;\n\n /**\n * Cached encrypted state of the Snap.\n */\n state?: Record<string, Json> | null;\n\n /**\n * Cached unencrypted state of the Snap.\n */\n unencryptedState?: Record<string, Json> | null;\n\n /**\n * A mutex to prevent concurrent state updates.\n */\n stateMutex: Mutex;\n\n /**\n * A mutex to prevent concurrent state decryption.\n */\n getStateMutex: Mutex;\n};\n\nexport type SnapError = {\n message: string;\n code: number;\n data?: Json;\n};\n\n// Types that probably should be defined elsewhere in prod\ntype CloseAllConnectionsFunction = (origin: string) => void;\ntype StoredSnaps = Record<SnapId, Snap>;\n\nexport type SnapControllerState = {\n snaps: StoredSnaps;\n snapStates: Record<SnapId, string | null>;\n unencryptedSnapStates: Record<SnapId, string | null>;\n};\n\nexport type PersistedSnapControllerState = SnapControllerState & {\n snaps: Record<SnapId, PersistedSnap>;\n snapStates: Record<SnapId, string>;\n};\n\ntype RollbackSnapshot = {\n statePatches: Patch[];\n permissions: {\n revoked?: SubjectPermissions<ValidPermission<string, Caveat<string, any>>>;\n granted?: RequestedPermissions;\n requestData?: Record<string, unknown>;\n };\n newVersion: string;\n};\n\ntype PendingApproval = {\n id: string;\n promise: Promise<unknown>;\n};\n\n// Controller Messenger Actions\n\n/**\n * Initialise the SnapController. This should be called after all controllers\n * are created.\n */\nexport type SnapControllerInitAction = {\n type: `${typeof controllerName}:init`;\n handler: SnapController['init'];\n};\n\n/**\n * Gets the specified Snap from state.\n */\nexport type GetSnap = {\n type: `${typeof controllerName}:get`;\n handler: SnapController['get'];\n};\n\n/**\n * Handles sending an inbound request to a snap and returns its result.\n */\nexport type HandleSnapRequest = {\n type: `${typeof controllerName}:handleRequest`;\n handler: SnapController['handleRequest'];\n};\n\n/**\n * Gets the specified Snap's persisted state.\n */\nexport type GetSnapState = {\n type: `${typeof controllerName}:getSnapState`;\n handler: SnapController['getSnapState'];\n};\n\n/**\n * Checks if the specified snap exists in state.\n */\nexport type HasSnap = {\n type: `${typeof controllerName}:has`;\n handler: SnapController['has'];\n};\n\n/**\n * Updates the specified Snap's persisted state.\n */\nexport type UpdateSnapState = {\n type: `${typeof controllerName}:updateSnapState`;\n handler: SnapController['updateSnapState'];\n};\n\n/**\n * Clears the specified Snap's persisted state.\n */\nexport type ClearSnapState = {\n type: `${typeof controllerName}:clearSnapState`;\n handler: SnapController['clearSnapState'];\n};\n\n/**\n * Checks all installed snaps against the blocklist.\n */\nexport type UpdateBlockedSnaps = {\n type: `${typeof controllerName}:updateBlockedSnaps`;\n handler: SnapController['updateBlockedSnaps'];\n};\n\nexport type EnableSnap = {\n type: `${typeof controllerName}:enable`;\n handler: SnapController['enableSnap'];\n};\n\nexport type DisableSnap = {\n type: `${typeof controllerName}:disable`;\n handler: SnapController['disableSnap'];\n};\n\nexport type RemoveSnap = {\n type: `${typeof controllerName}:remove`;\n handler: SnapController['removeSnap'];\n};\n\nexport type GetPermittedSnaps = {\n type: `${typeof controllerName}:getPermitted`;\n handler: SnapController['getPermittedSnaps'];\n};\n\nexport type GetAllSnaps = {\n type: `${typeof controllerName}:getAll`;\n handler: SnapController['getAllSnaps'];\n};\n\nexport type GetRunnableSnaps = {\n type: `${typeof controllerName}:getRunnableSnaps`;\n handler: SnapController['getRunnableSnaps'];\n};\n\nexport type StopAllSnaps = {\n type: `${typeof controllerName}:stopAllSnaps`;\n handler: SnapController['stopAllSnaps'];\n};\n\nexport type IncrementActiveReferences = {\n type: `${typeof controllerName}:incrementActiveReferences`;\n handler: SnapController['incrementActiveReferences'];\n};\n\nexport type DecrementActiveReferences = {\n type: `${typeof controllerName}:decrementActiveReferences`;\n handler: SnapController['decrementActiveReferences'];\n};\n\nexport type InstallSnaps = {\n type: `${typeof controllerName}:install`;\n handler: SnapController['installSnaps'];\n};\n\nexport type DisconnectOrigin = {\n type: `${typeof controllerName}:disconnectOrigin`;\n handler: SnapController['removeSnapFromSubject'];\n};\n\nexport type RevokeDynamicPermissions = {\n type: `${typeof controllerName}:revokeDynamicPermissions`;\n handler: SnapController['revokeDynamicSnapPermissions'];\n};\n\nexport type GetSnapFile = {\n type: `${typeof controllerName}:getFile`;\n handler: SnapController['getSnapFile'];\n};\n\nexport type IsMinimumPlatformVersion = {\n type: `${typeof controllerName}:isMinimumPlatformVersion`;\n handler: SnapController['isMinimumPlatformVersion'];\n};\n\nexport type SnapControllerGetStateAction = ControllerGetStateAction<\n typeof controllerName,\n SnapControllerState\n>;\n\nexport type SnapControllerActions =\n | SnapControllerInitAction\n | ClearSnapState\n | GetSnap\n | GetSnapState\n | HandleSnapRequest\n | HasSnap\n | UpdateBlockedSnaps\n | UpdateSnapState\n | EnableSnap\n | DisableSnap\n | RemoveSnap\n | GetPermittedSnaps\n | InstallSnaps\n | GetAllSnaps\n | GetRunnableSnaps\n | IncrementActiveReferences\n | DecrementActiveReferences\n | DisconnectOrigin\n | RevokeDynamicPermissions\n | GetSnapFile\n | SnapControllerGetStateAction\n | StopAllSnaps\n | IsMinimumPlatformVersion;\n\n// Controller Messenger Events\n\nexport type SnapStateChange = {\n type: `${typeof controllerName}:stateChange`;\n payload: [SnapControllerState, Patch[]];\n};\n\n/**\n * Emitted when an installed snap has been blocked.\n */\nexport type SnapBlocked = {\n type: `${typeof controllerName}:snapBlocked`;\n payload: [snapId: string, blockedSnapInfo?: BlockReason];\n};\n\n/**\n * Emitted when a snap installation or update is started.\n */\nexport type SnapInstallStarted = {\n type: `${typeof controllerName}:snapInstallStarted`;\n payload: [snapId: SnapId, origin: string, isUpdate: boolean];\n};\n\n/**\n * Emitted when a snap installation or update failed.\n */\nexport type SnapInstallFailed = {\n type: `${typeof controllerName}:snapInstallFailed`;\n payload: [snapId: SnapId, origin: string, isUpdate: boolean, error: string];\n};\n\n/**\n * Emitted when a snap has been started after being added and authorized during\n * installation.\n */\nexport type SnapInstalled = {\n type: `${typeof controllerName}:snapInstalled`;\n payload: [snap: TruncatedSnap, origin: string, preinstalled: boolean];\n};\n\n/**\n * Emitted when a snap that has previously been fully installed, is uninstalled.\n */\nexport type SnapUninstalled = {\n type: `${typeof controllerName}:snapUninstalled`;\n payload: [snap: TruncatedSnap];\n};\n\n/**\n * Emitted when an installed snap has been unblocked.\n */\nexport type SnapUnblocked = {\n type: `${typeof controllerName}:snapUnblocked`;\n payload: [snapId: string];\n};\n\n/**\n * Emitted when a snap is updated.\n */\nexport type SnapUpdated = {\n type: `${typeof controllerName}:snapUpdated`;\n payload: [\n snap: TruncatedSnap,\n oldVersion: string,\n origin: string,\n preinstalled: boolean,\n ];\n};\n\n/**\n * Emitted when a snap is rolled back.\n */\nexport type SnapRolledback = {\n type: `${typeof controllerName}:snapRolledback`;\n payload: [snap: TruncatedSnap, failedVersion: string];\n};\n\n/**\n * Emitted when a Snap is terminated. This is different from the snap being\n * stopped as it can also be triggered when a snap fails initialization.\n */\nexport type SnapTerminated = {\n type: `${typeof controllerName}:snapTerminated`;\n payload: [snap: TruncatedSnap];\n};\n\n/**\n * Emitted when a Snap is enabled by a user.\n * This is not emitted by default when installing a snap.\n */\nexport type SnapEnabled = {\n type: `${typeof controllerName}:snapEnabled`;\n payload: [snap: TruncatedSnap];\n};\n\n/**\n * Emitted when a Snap is disabled by a user.\n */\nexport type SnapDisabled = {\n type: `${typeof controllerName}:snapDisabled`;\n payload: [snap: TruncatedSnap];\n};\n\n/**\n * Emitted when there is a state change.\n */\nexport type SnapControllerStateChangeEvent = ControllerStateChangeEvent<\n typeof controllerName,\n SnapControllerState\n>;\n\ntype KeyringControllerLock = {\n type: 'KeyringController:lock';\n payload: [];\n};\n\nexport type SnapControllerEvents =\n | SnapBlocked\n | SnapInstalled\n | SnapUninstalled\n | SnapInstallStarted\n | SnapInstallFailed\n | SnapStateChange\n | SnapUnblocked\n | SnapUpdated\n | SnapRolledback\n | SnapTerminated\n | SnapEnabled\n | SnapDisabled\n | SnapControllerStateChangeEvent;\n\ntype NetworkControllerGetNetworkClientById = {\n type: `NetworkController:getNetworkClientById`;\n handler: (customNetworkClientId: string) => {\n configuration: {\n chainId: Hex;\n };\n };\n};\n\ntype SelectedNetworkControllerGetNetworkClientIdForDomain = {\n type: `SelectedNetworkController:getNetworkClientIdForDomain`;\n handler: (domain: string) => string;\n};\n\nexport type AllowedActions =\n | GetEndowments\n | GetPermissions\n | GetSubjects\n | GetSubjectMetadata\n | AddSubjectMetadata\n | HasPermission\n | HasPermissions\n | RevokePermissions\n | RevokeAllPermissions\n | RevokePermissionForAllSubjects\n | GrantPermissions\n | AddApprovalRequest\n | HandleRpcRequestAction\n | ExecuteSnapAction\n | TerminateAllSnapsAction\n | TerminateSnapAction\n | UpdateCaveat\n | UpdateRequestState\n | GetResult\n | GetMetadata\n | Update\n | ResolveVersion\n | CreateInterface\n | GetInterface\n | NetworkControllerGetNetworkClientById\n | SelectedNetworkControllerGetNetworkClientIdForDomain;\n\nexport type AllowedEvents =\n | ExecutionServiceEvents\n | SnapInstalled\n | SnapUpdated\n | KeyringControllerLock;\n\ntype SnapControllerMessenger = RestrictedMessenger<\n typeof controllerName,\n SnapControllerActions | AllowedActions,\n SnapControllerEvents | AllowedEvents,\n AllowedActions['type'],\n AllowedEvents['type']\n>;\n\ntype FeatureFlags = {\n requireAllowlist?: boolean;\n allowLocalSnaps?: boolean;\n disableSnapInstallation?: boolean;\n rejectInvalidPlatformVersion?: boolean;\n useCaip25Permission?: boolean;\n};\n\ntype DynamicFeatureFlags = {\n disableSnaps?: boolean;\n};\n\ntype SnapControllerArgs = {\n /**\n * A teardown function that allows the host to clean up its instrumentation\n * for a running snap.\n */\n closeAllConnections?: CloseAllConnectionsFunction;\n\n /**\n * A list of permissions that are allowed to be dynamic, meaning they can be revoked from the snap whenever.\n */\n dynamicPermissions?: string[];\n\n /**\n * The names of endowment permissions whose values are the names of JavaScript\n * APIs that will be added to the snap execution environment at runtime.\n */\n environmentEndowmentPermissions?: string[];\n\n /**\n * Excluded permissions with its associated error message used to forbid certain permissions.\n */\n excludedPermissions?: Record<string, string>;\n\n /**\n * The function that will be used by the controller fo make network requests.\n * Should be compatible with {@link fetch}.\n */\n fetchFunction?: typeof fetch;\n\n /**\n * Flags that enable or disable features in the controller.\n * See {@link FeatureFlags}.\n */\n featureFlags: FeatureFlags;\n\n /**\n * How frequently to check whether a snap is idle.\n */\n idleTimeCheckInterval?: number;\n\n /**\n * The maximum amount of time that a snap may be idle.\n */\n maxIdleTime?: number;\n\n /**\n * The controller messenger.\n */\n messenger: SnapControllerMessenger;\n\n /**\n * The maximum amount of time a snap may take to process an RPC request,\n * unless it is permitted to take longer.\n */\n maxRequestTime?: number;\n\n /**\n * The npm registry URL that will be used to fetch published snaps.\n */\n npmRegistryUrl?: string;\n\n /**\n * Persisted state that will be used for rehydration.\n */\n state?: PersistedSnapControllerState;\n\n /**\n * A function that takes Snap Id and converts it into a class that fetches files.\n *\n * Used for test overrides.\n */\n detectSnapLocation?: typeof detectSnapLocation;\n\n /**\n * A list of snaps to be preinstalled into the SnapController state on initialization.\n */\n preinstalledSnaps?: PreinstalledSnap[] | null;\n\n /**\n * A utility object containing functions required for state encryption.\n */\n encryptor: ExportableKeyEncryptor;\n\n /**\n * A hook to access the mnemonic seed of the user's primary keyring.\n *\n * @returns The mnemonic seed as bytes.\n */\n getMnemonicSeed: () => Promise<Uint8Array>;\n\n /**\n * A hook to get dynamic feature flags at runtime.\n *\n * @returns The feature flags.\n */\n getFeatureFlags: () => DynamicFeatureFlags;\n\n /**\n * The cryptographic functions to use for the client. This may be an empty\n * object to fall back to the default cryptographic functions.\n */\n clientCryptography?: CryptographicFunctions;\n\n /**\n * MetaMetrics event tracking hook.\n */\n trackEvent: TrackEventHook;\n};\n\ntype AddSnapArgs = {\n id: SnapId;\n origin: string;\n location: SnapLocation;\n versionRange: SemVerRange;\n};\n\n// When we set a snap, we need all required properties to be present and\n// validated.\ntype SetSnapArgs = Omit<AddSnapArgs, 'location' | 'versionRange'> & {\n files: FetchedSnapFiles;\n isUpdate?: boolean;\n removable?: boolean;\n preinstalled?: boolean;\n hidden?: boolean;\n hideSnapBranding?: boolean;\n};\n\ntype TrackingEventPayload = {\n event: string;\n category: string;\n properties: Record<string, Json | undefined>;\n};\n\ntype TrackEventHook = (event: TrackingEventPayload) => void;\n\nconst defaultState: SnapControllerState = {\n snaps: {},\n snapStates: {},\n unencryptedSnapStates: {},\n};\n\n/**\n * Truncates the properties of a snap to only ones that are easily serializable.\n *\n * @param snap - The snap to truncate.\n * @returns Object with serializable snap properties.\n */\nfunction truncateSnap(snap: Snap): TruncatedSnap {\n const truncatedSnap = Object.keys(snap).reduce<Partial<TruncatedSnap>>(\n (serialized, key) => {\n if (TRUNCATED_SNAP_PROPERTIES.has(key as any)) {\n serialized[key as keyof TruncatedSnap] = snap[\n key as keyof TruncatedSnap\n ] as any;\n }\n\n return serialized;\n },\n {},\n );\n\n return truncatedSnap as TruncatedSnap;\n}\n\n/*\n * A snap is initialized in three phases:\n * - Add: Loads the snap from a remote source and parses it.\n * - Authorize: Requests the snap's required permissions from the user.\n * - Start: Initializes the snap in its SES realm with the authorized permissions.\n */\n\nexport class SnapController extends BaseController<\n typeof controllerName,\n SnapControllerState,\n SnapControllerMessenger\n> {\n readonly #closeAllConnections?: CloseAllConnectionsFunction;\n\n readonly #dynamicPermissions: string[];\n\n readonly #environmentEndowmentPermissions: string[];\n\n readonly #excludedPermissions: Record<string, string>;\n\n readonly #featureFlags: FeatureFlags;\n\n readonly #fetchFunction: typeof fetch;\n\n readonly #idleTimeCheckInterval: number;\n\n readonly #maxIdleTime: number;\n\n // This property cannot be hash private yet because of tests.\n // eslint-disable-next-line no-restricted-syntax\n private readonly maxRequestTime: number;\n\n readonly #encryptor: ExportableKeyEncryptor;\n\n readonly #getMnemonicSeed: () => Promise<Uint8Array>;\n\n readonly #getFeatureFlags: () => DynamicFeatureFlags;\n\n readonly #clientCryptography: CryptographicFunctions | undefined;\n\n readonly #detectSnapLocation: typeof detectSnapLocation;\n\n readonly #snapsRuntimeData: Map<SnapId, SnapRuntimeData>;\n\n readonly #rollbackSnapshots: Map<string, RollbackSnapshot>;\n\n #timeoutForLastRequestStatus?: number;\n\n #statusMachine!: StateMachine.Machine<\n StatusContext,\n StatusEvents,\n StatusStates\n >;\n\n readonly #preinstalledSnaps: PreinstalledSnap[] | null;\n\n readonly #trackEvent: TrackEventHook;\n\n readonly #trackSnapExport: ReturnType<typeof throttleTracking>;\n\n constructor({\n closeAllConnections,\n messenger,\n state,\n dynamicPermissions = ['eth_accounts'],\n environmentEndowmentPermissions = [],\n excludedPermissions = {},\n idleTimeCheckInterval = inMilliseconds(5, Duration.Second),\n maxIdleTime = inMilliseconds(30, Duration.Second),\n maxRequestTime = inMilliseconds(60, Duration.Second),\n fetchFunction = globalThis.fetch.bind(undefined),\n featureFlags = {},\n detectSnapLocation: detectSnapLocationFunction = detectSnapLocation,\n preinstalledSnaps = null,\n encryptor,\n getMnemonicSeed,\n getFeatureFlags = () => ({}),\n clientCryptography,\n trackEvent,\n }: SnapControllerArgs) {\n super({\n messenger,\n metadata: {\n snapStates: {\n persist: true,\n anonymous: false,\n },\n unencryptedSnapStates: {\n persist: true,\n anonymous: false,\n },\n snaps: {\n persist: (snaps) => {\n return (\n Object.values(snaps)\n // We should not persist snaps that are in the installing state,\n // since they haven't completed installation and would be unusable\n .filter((snap) => snap.status !== SnapStatus.Installing)\n .map((snap) => {\n return {\n ...snap,\n // At the time state is rehydrated, no snap will be running.\n status: SnapStatus.Stopped,\n };\n })\n .reduce((memo: Record<SnapId, Snap>, snap) => {\n memo[snap.id] = snap;\n return memo;\n }, {})\n );\n },\n anonymous: false,\n },\n },\n name: controllerName,\n state: {\n ...defaultState,\n ...state,\n },\n });\n\n this.#closeAllConnections = closeAllConnections;\n this.#dynamicPermissions = dynamicPermissions;\n this.#environmentEndowmentPermissions = environmentEndowmentPermissions;\n this.#excludedPermissions = excludedPermissions;\n this.#featureFlags = featureFlags;\n this.#fetchFunction = fetchFunction;\n this.#idleTimeCheckInterval = idleTimeCheckInterval;\n this.#maxIdleTime = maxIdleTime;\n this.maxRequestTime = maxRequestTime;\n this.#detectSnapLocation = detectSnapLocationFunction;\n this.#encryptor = encryptor;\n this.#getMnemonicSeed = getMnemonicSeed;\n this.#getFeatureFlags = getFeatureFlags;\n this.#clientCryptography = clientCryptography;\n this.#preinstalledSnaps = preinstalledSnaps;\n this._onUnhandledSnapError = this._onUnhandledSnapError.bind(this);\n this._onOutboundRequest = this._onOutboundRequest.bind(this);\n this._onOutboundResponse = this._onOutboundResponse.bind(this);\n this.#rollbackSnapshots = new Map();\n this.#snapsRuntimeData = new Map();\n this.#trackEvent = trackEvent;\n\n this.#pollForLastRequestStatus();\n\n /* eslint-disable @typescript-eslint/unbound-method */\n this.messagingSystem.subscribe(\n 'ExecutionService:unhandledError',\n this._onUnhandledSnapError,\n );\n\n this.messagingSystem.subscribe(\n 'ExecutionService:outboundRequest',\n this._onOutboundRequest,\n );\n\n this.messagingSystem.subscribe(\n 'ExecutionService:outboundResponse',\n this._onOutboundResponse,\n );\n /* eslint-enable @typescript-eslint/unbound-method */\n\n this.messagingSystem.subscribe(\n 'SnapController:snapInstalled',\n ({ id }, origin) => {\n this.#callLifecycleHook(origin, id, HandlerType.OnInstall).catch(\n (error) => {\n logError(\n `Error when calling \\`onInstall\\` lifecycle hook for snap \"${id}\": ${getErrorMessage(\n error,\n )}`,\n );\n },\n );\n },\n );\n\n this.messagingSystem.subscribe(\n 'SnapController:snapUpdated',\n ({ id }, _oldVersion, origin) => {\n this.#callLifecycleHook(origin, id, HandlerType.OnUpdate).catch(\n (error) => {\n logError(\n `Error when calling \\`onUpdate\\` lifecycle hook for snap \"${id}\": ${getErrorMessage(\n error,\n )}`,\n );\n },\n );\n },\n );\n\n this.messagingSystem.subscribe(\n 'KeyringController:lock',\n this.#handleLock.bind(this),\n );\n\n this.#initializeStateMachine();\n this.#registerMessageHandlers();\n\n Object.values(this.state?.snaps ?? {}).forEach((snap) =>\n this.#setupRuntime(snap.id),\n );\n\n if (this.#preinstalledSnaps) {\n this.#handlePreinstalledSnaps(this.#preinstalledSnaps);\n }\n\n this.#trackSnapExport = throttleTracking(\n (snapId: SnapId, handler: string, success: boolean, origin: string) => {\n const snapMetadata = this.messagingSystem.call(\n 'SnapsRegistry:getMetadata',\n snapId,\n );\n this.#trackEvent({\n event: 'Snap Export Used',\n category: 'Snaps',\n properties: {\n // eslint-disable-next-line @typescript-eslint/naming-convention\n snap_id: snapId,\n export: handler,\n // eslint-disable-next-line @typescript-eslint/naming-convention\n snap_category: snapMetadata?.category,\n success,\n origin,\n },\n });\n },\n );\n }\n\n /**\n * We track status of a Snap using a finite-state-machine.\n * It keeps track of whether the snap is started / stopped / etc.\n *\n * @see {@link SnapController.transition} for interacting with the machine.\n */\n // We initialize the machine in the instance because the status is currently tightly coupled\n // with the SnapController - the guard checks for enabled status inside the SnapController state.\n // In the future, side-effects could be added to the machine during transitions.\n #initializeStateMachine() {\n const disableGuard = ({ snapId }: StatusContext) => {\n return this.getExpect(snapId).enabled;\n };\n\n const statusConfig: StateMachine.Config<\n StatusContext,\n StatusEvents,\n StatusStates\n > = {\n initial: SnapStatus.Installing,\n states: {\n [SnapStatus.Installing]: {\n on: {\n [SnapStatusEvents.Start]: {\n target: SnapStatus.Running,\n cond: disableGuard,\n },\n },\n },\n [SnapStatus.Updating]: {\n on: {\n [SnapStatusEvents.Start]: {\n target: SnapStatus.Running,\n cond: disableGuard,\n },\n [SnapStatusEvents.Stop]: SnapStatus.Stopped,\n },\n },\n [SnapStatus.Running]: {\n on: {\n [SnapStatusEvents.Stop]: SnapStatus.Stopped,\n [SnapStatusEvents.Crash]: SnapStatus.Crashed,\n },\n },\n [SnapStatus.Stopped]: {\n on: {\n [SnapStatusEvents.Start]: {\n target: SnapStatus.Running,\n cond: disableGuard,\n },\n [SnapStatusEvents.Update]: SnapStatus.Updating,\n },\n },\n [SnapStatus.Crashed]: {\n on: {\n [SnapStatusEvents.Start]: {\n target: SnapStatus.Running,\n cond: disableGuard,\n },\n [SnapStatusEvents.Update]: SnapStatus.Updating,\n },\n },\n },\n };\n this.#statusMachine = createMachine(statusConfig);\n validateMachine(this.#statusMachine);\n }\n\n /**\n * Constructor helper for registering the controller's messaging system\n * actions.\n */\n #registerMessageHandlers(): void {\n this.messagingSystem.registerActionHandler(\n `${controllerName}:init`,\n (...args) => this.init(...args),\n );\n\n this.messagingSystem.registerActionHandler(\n `${controllerName}:clearSnapState`,\n (...args) => this.clearSnapState(...args),\n );\n\n this.messagingSystem.registerActionHandler(\n `${controllerName}:get`,\n (...args) => this.get(...args),\n );\n\n this.messagingSystem.registerActionHandler(\n `${controllerName}:getSnapState`,\n async (...args) => this.getSnapState(...args),\n );\n\n this.messagingSystem.registerActionHandler(\n `${controllerName}:handleRequest`,\n async (...args) => this.handleRequest(...args),\n );\n\n this.messagingSystem.registerActionHandler(\n `${controllerName}:has`,\n (...args) => this.has(...args),\n );\n\n this.messagingSystem.registerActionHandler(\n `${controllerName}:updateBlockedSnaps`,\n async () => this.updateBlockedSnaps(),\n );\n\n this.messagingSystem.registerActionHandler(\n `${controllerName}:updateSnapState`,\n async (...args) => this.updateSnapState(...args),\n );\n\n this.messagingSystem.registerActionHandler(\n `${controllerName}:enable`,\n (...args) => this.enableSnap(...args),\n );\n\n this.messagingSystem.registerActionHandler(\n `${controllerName}:disable`,\n async (...args) => this.disableSnap(...args),\n );\n\n this.messagingSystem.registerActionHandler(\n `${controllerName}:remove`,\n async (...args) => this.removeSnap(...args),\n );\n\n this.messagingSystem.registerActionHandler(\n `${controllerName}:getPermitted`,\n (...args) => this.getPermittedSnaps(...args),\n );\n\n this.messagingSystem.registerActionHandler(\n `${controllerName}:install`,\n async (...args) => this.installSnaps(...args),\n );\n\n this.messagingSystem.registerActionHandler(\n `${controllerName}:getAll`,\n (...args) => this.getAllSnaps(...args),\n );\n\n this.messagingSystem.registerActionHandler(\n `${controllerName}:getRunnableSnaps`,\n (...args) => this.getRunnableSnaps(...args),\n );\n\n this.messagingSystem.registerActionHandler(\n `${controllerName}:incrementActiveReferences`,\n (...args) => this.incrementActiveReferences(...args),\n );\n\n this.messagingSystem.registerActionHandler(\n `${controllerName}:decrementActiveReferences`,\n (...args) => this.decrementActiveReferences(...args),\n );\n\n this.messagingSystem.registerActionHandler(\n `${controllerName}:disconnectOrigin`,\n (...args) => this.removeSnapFromSubject(...args),\n );\n\n this.messagingSystem.registerActionHandler(\n `${controllerName}:revokeDynamicPermissions`,\n (...args) => this.revokeDynamicSnapPermissions(...args),\n );\n\n this.messagingSystem.registerActionHandler(\n `${controllerName}:getFile`,\n async (...args) => this.getSnapFile(...args),\n );\n\n this.messagingSystem.registerActionHandler(\n `${controllerName}:stopAllSnaps`,\n async (...args) => this.stopAllSnaps(...args),\n );\n\n this.messagingSystem.registerActionHandler(\n `${controllerName}:isMinimumPlatformVersion`,\n (...args) => this.isMinimumPlatformVersion(...args),\n );\n }\n\n /**\n * Initialise the SnapController.\n *\n * Currently this method calls the `onStart` lifecycle hook for all\n * installed Snaps.\n */\n init() {\n const snaps = this.getRunnableSnaps();\n for (const { id } of snaps) {\n const hasLifecycleHooksEndowment = this.messagingSystem.call(\n 'PermissionController:hasPermission',\n id,\n SnapEndowments.LifecycleHooks,\n );\n\n if (!hasLifecycleHooksEndowment) {\n continue;\n }\n\n this.#callLifecycleHook(METAMASK_ORIGIN, id, HandlerType.OnStart).catch(\n (error) => {\n logError(\n `Error when calling \\`onStart\\` lifecycle hook for Snap \"${id}\": ${getErrorMessage(\n error,\n )}`,\n );\n },\n );\n }\n }\n\n #handlePreinstalledSnaps(preinstalledSnaps: PreinstalledSnap[]) {\n for (const {\n snapId,\n manifest,\n files,\n removable,\n hidden,\n hideSnapBranding,\n } of preinstalledSnaps) {\n const existingSnap = this.get(snapId);\n const isAlreadyInstalled = existingSnap !== undefined;\n const isUpdate =\n isAlreadyInstalled && gtVersion(manifest.version, existingSnap.version);\n\n // Disallow downgrades and overwriting non preinstalled snaps\n if (\n isAlreadyInstalled &&\n (!isUpdate || existingSnap.preinstalled !== true)\n ) {\n continue;\n }\n\n const manifestFile = new VirtualFile<SnapManifest>({\n path: NpmSnapFileNames.Manifest,\n value: JSON.stringify(manifest),\n result: manifest,\n });\n\n const virtualFiles = files.map(\n ({ path, value }) => new VirtualFile({ value, path }),\n );\n const { filePath, iconPath } = manifest.source.location.npm;\n const sourceCode = virtualFiles.find((file) => file.path === filePath);\n const svgIcon = iconPath\n ? virtualFiles.find((file) => file.path === iconPath)\n : undefined;\n\n assert(sourceCode, 'Source code not provided for preinstalled snap.');\n\n assert(\n !iconPath || (iconPath && svgIcon),\n 'Icon not provided for preinstalled snap.',\n );\n\n assert(\n manifest.source.files === undefined,\n 'Auxiliary files are not currently supported for preinstalled snaps.',\n );\n\n const localizationFiles =\n manifest.source.locales?.map((path) =>\n virtualFiles.find((file) => file.path === path),\n ) ?? [];\n\n const validatedLocalizationFiles = getValidatedLocalizationFiles(\n localizationFiles.filter(Boolean) as VirtualFile[],\n );\n\n assert(\n localizationFiles.length === validatedLocalizationFiles.length,\n 'Missing localization files for preinstalled snap.',\n );\n\n const filesObject: FetchedSnapFiles = {\n manifest: manifestFile,\n sourceCode,\n svgIcon,\n auxiliaryFiles: [],\n localizationFiles: validatedLocalizationFiles,\n };\n\n // Add snap to the SnapController state\n this.#set({\n id: snapId,\n origin: METAMASK_ORIGIN,\n files: filesObject,\n removable,\n hidden,\n hideSnapBranding,\n preinstalled: true,\n });\n\n // Setup permissions\n const processedPermissions = processSnapPermissions(\n manifest.initialPermissions,\n );\n\n this.#validateSnapPermissions(processedPermissions);\n\n const { newPermissions, unusedPermissions } =\n this.#calculatePermissionsChange(snapId, processedPermissions);\n\n this.#updatePermissions({ snapId, newPermissions, unusedPermissions });\n\n if (manifest.initialConnections) {\n this.#handleInitialConnections(\n snapId,\n existingSnap?.initialConnections ?? null,\n manifest.initialConnections,\n );\n }\n\n // Set status\n this.update((state) => {\n state.snaps[snapId].status = SnapStatus.Stopped;\n });\n\n this.#setupRuntime(snapId);\n\n // Emit events\n if (isUpdate) {\n this.messagingSystem.publish(\n 'SnapController:snapUpdated',\n this.getTruncatedExpect(snapId),\n existingSnap.version,\n METAMASK_ORIGIN,\n true,\n );\n } else {\n this.messagingSystem.publish(\n 'SnapController:snapInstalled',\n this.getTruncatedExpect(snapId),\n METAMASK_ORIGIN,\n true,\n );\n }\n }\n }\n\n #pollForLastRequestStatus() {\n this.#timeoutForLastRequestStatus = setTimeout(() => {\n this.#stopSnapsLastRequestPastMax().catch((error) => {\n // TODO: Decide how to handle errors.\n logError(error);\n });\n\n this.#pollForLastRequestStatus();\n }, this.#idleTimeCheckInterval) as unknown as number;\n }\n\n /**\n * Checks all installed snaps against the block list and\n * blocks/unblocks snaps as appropriate. See {@link SnapController.blockSnap}\n * for more information.\n */\n async updateBlockedSnaps(): Promise<void> {\n this.#assertCanUsePlatform();\n await this.messagingSystem.call('SnapsRegistry:update');\n\n const blockedSnaps = await this.messagingSystem.call(\n 'SnapsRegistry:get',\n Object.values(this.state.snaps).reduce<SnapsRegistryRequest>(\n (blockListArg, snap) => {\n blockListArg[snap.id] = {\n version: snap.version,\n checksum: snap.manifest.source.shasum,\n };\n return blockListArg;\n },\n {},\n ),\n );\n\n await Promise.all(\n Object.entries(blockedSnaps).map(async ([snapId, { status, reason }]) => {\n if (status === SnapsRegistryStatus.Blocked) {\n return this.#blockSnap(snapId as SnapId, reason);\n }\n\n return this.#unblockSnap(snapId as SnapId);\n }),\n );\n }\n\n /**\n * Blocks an installed snap and prevents it from being started again. Emits\n * {@link SnapBlocked}. Does nothing if the snap is not installed.\n *\n * @param snapId - The snap to block.\n * @param blockedSnapInfo - Information detailing why the snap is blocked.\n */\n async #blockSnap(\n snapId: SnapId,\n blockedSnapInfo?: BlockReason,\n ): Promise<void> {\n if (!this.has(snapId)) {\n return;\n }\n\n try {\n this.update((state: any) => {\n state.snaps[snapId].blocked = true;\n state.snaps[snapId].blockInformation = blockedSnapInfo;\n });\n\n await this.disableSnap(snapId);\n } catch (error) {\n logError(\n `Encountered error when stopping blocked snap \"${snapId}\".`,\n error,\n );\n }\n\n this.messagingSystem.publish(\n `${controllerName}:snapBlocked`,\n snapId,\n blockedSnapInfo,\n );\n }\n\n /**\n * Unblocks a snap so that it can be enabled and started again. Emits\n * {@link SnapUnblocked}. Does nothing if the snap is not installed or already\n * unblocked.\n *\n * @param snapId - The id of the snap to unblock.\n */\n #unblockSnap(snapId: SnapId) {\n if (!this.has(snapId) || !this.state.snaps[snapId].blocked) {\n return;\n }\n\n this.update((state: any) => {\n state.snaps[snapId].blocked = false;\n delete state.snaps[snapId].blockInformation;\n });\n\n this.messagingSystem.publish(`${controllerName}:snapUnblocked`, snapId);\n }\n\n async #assertIsInstallAllowed(\n snapId: SnapId,\n {\n platformVersion,\n ...snapInfo\n }: SnapsRegistryInfo & {\n permissions: SnapPermissions;\n platformVersion: string | undefined;\n },\n ) {\n const results = await this.messagingSystem.call('SnapsRegistry:get', {\n [snapId]: snapInfo,\n });\n\n const result = results[snapId];\n if (result.status === SnapsRegistryStatus.Blocked) {\n throw new Error(\n `Cannot install version \"${\n snapInfo.version\n }\" of snap \"${snapId}\": The version is blocked. ${\n result.reason?.explanation ?? ''\n }`,\n );\n }\n\n const isAllowlistingRequired = Object.keys(snapInfo.permissions).some(\n (permission) => !ALLOWED_PERMISSIONS.includes(permission),\n );\n\n if (\n this.#featureFlags.requireAllowlist &&\n isAllowlistingRequired &&\n result.status !== SnapsRegistryStatus.Verified\n ) {\n throw new Error(\n `Cannot install version \"${snapInfo.version}\" of snap \"${snapId}\": ${\n result.status === SnapsRegistryStatus.Unavailable\n ? 'The registry is temporarily unavailable.'\n : 'The snap is not on the allowlist.'\n }`,\n );\n }\n\n this.#validatePlatformVersion(snapId, platformVersion);\n }\n\n /**\n * Asserts whether new Snaps are allowed to be installed.\n */\n #assertCanInstallSnaps() {\n assert(\n this.#featureFlags.disableSnapInstallation !== true,\n 'Installing Snaps is currently disabled in this version of MetaMask.',\n );\n }\n\n /**\n * Asserts whether the Snaps platform is allowed to run.\n */\n #assertCanUsePlatform() {\n const flags = this.#getFeatureFlags();\n assert(\n flags.disableSnaps !== true,\n 'The Snaps platform requires basic functionality to be used. Enable basic functionality in the settings to use the Snaps platform.',\n );\n }\n\n async #stopSnapsLastRequestPastMax() {\n const entries = [...this.#snapsRuntimeData.entries()];\n return Promise.all(\n entries\n .filter(\n ([_snapId, runtime]) =>\n runtime.activeReferences === 0 &&\n runtime.pendingInboundRequests.length === 0 &&\n runtime.lastRequest &&\n this.#maxIdleTime &&\n timeSince(runtime.lastRequest) > this.#maxIdleTime,\n )\n .map(async ([snapId]) => this.stopSnap(snapId, SnapStatusEvents.Stop)),\n );\n }\n\n _onUnhandledSnapError(snapId: string, error: SnapErrorJson) {\n // Log the error that caused the crash\n // so it gets raised to the developer for debugging purposes.\n logError(`Unhandled error from \"${snapId}\":`, error);\n this.stopSnap(snapId as SnapId, SnapStatusEvents.Crash).catch(\n (stopSnapError) => {\n // TODO: Decide how to handle errors.\n logError(stopSnapError);\n },\n );\n }\n\n _onOutboundRequest(snapId: string) {\n const runtime = this.#getRuntimeExpect(snapId as SnapId);\n // Ideally we would only pause the pending request that is making the outbound request\n // but right now we don't have a way to know which request initiated the outbound request\n runtime.pendingInboundRequests\n .filter((pendingRequest) => pendingRequest.timer.status === 'running')\n .forEach((pendingRequest) => pendingRequest.timer.pause());\n runtime.pendingOutboundRequests += 1;\n }\n\n _onOutboundResponse(snapId: string) {\n const runtime = this.#getRuntimeExpect(snapId as SnapId);\n runtime.pendingOutboundRequests -= 1;\n if (runtime.pendingOutboundRequests === 0) {\n runtime.pendingInboundRequests\n .filter((pendingRequest) => pendingRequest.timer.status === 'paused')\n .forEach((pendingRequest) => pendingRequest.timer.resume());\n }\n }\n\n /**\n * Transitions between states using `snapStatusStateMachineConfig` as the template to figure out\n * the next state. This transition function uses a very minimal subset of XState conventions:\n * - supports initial state\n * - .on supports raw event target string\n * - .on supports {target, cond} object\n * - the arguments for `cond` is the `SerializedSnap` instead of Xstate convention of `(event,\n * context) => boolean`\n *\n * @param snapId - The id of the snap to transition.\n * @param event - The event enum to use to transition.\n */\n #transition(snapId: SnapId, event: StatusEvents | StatusEvents['type']) {\n const { interpreter } = this.#getRuntimeExpect(snapId);\n interpreter.send(event);\n this.update((state: any) => {\n state.snaps[snapId].status = interpreter.state.value;\n });\n }\n\n /**\n * Starts the given snap. Throws an error if no such snap exists\n * or if it is already running.\n *\n * @param snapId - The id of the Snap to start.\n */\n async startSnap(snapId: SnapId): Promise<void> {\n this.#assertCanUsePlatform();\n const snap = this.state.snaps[snapId];\n\n if (!snap.enabled) {\n throw new Error(`Snap \"${snapId}\" is disabled.`);\n }\n\n await this.#startSnap({\n snapId,\n sourceCode: snap.sourceCode,\n });\n }\n\n /**\n * Enables the given snap. A snap can only be started if it is enabled. A snap\n * can only be enabled if it isn't blocked.\n *\n * @param snapId - The id of the Snap to enable.\n */\n enableSnap(snapId: SnapId): void {\n this.getExpect(snapId);\n\n if (this.state.snaps[snapId].blocked) {\n throw new Error(`Snap \"${snapId}\" is blocked and cannot be enabled.`);\n }\n\n this.update((state: any) => {\n state.snaps[snapId].enabled = true;\n });\n\n this.messagingSystem.publish(\n 'SnapController:snapEnabled',\n this.getTruncatedExpect(snapId),\n );\n }\n\n /**\n * Disables the given snap. A snap can only be started if it is enabled.\n *\n * @param snapId - The id of the Snap to disable.\n * @returns A promise that resolves once the snap has been disabled.\n */\n async disableSnap(snapId: SnapId): Promise<void> {\n if (!this.has(snapId)) {\n throw new Error(`Snap \"${snapId}\" not found.`);\n }\n\n this.update((state: any) => {\n state.snaps[snapId].enabled = false;\n });\n\n if (this.isRunning(snapId)) {\n await this.stopSnap(snapId, SnapStatusEvents.Stop);\n }\n\n this.messagingSystem.publish(\n 'SnapController:snapDisabled',\n this.getTruncatedExpect(snapId),\n );\n }\n\n /**\n * Stops the given snap, removes all hooks, closes all connections, and\n * terminates its worker.\n *\n * @param snapId - The id of the Snap to stop.\n * @param statusEvent - The Snap status event that caused the snap to be\n * stopped.\n */\n public async stopSnap(\n snapId: SnapId,\n statusEvent:\n | SnapStatusEvents.Stop\n | SnapStatusEvents.Crash = SnapStatusEvents.Stop,\n ): Promise<void> {\n const runtime = this.#getRuntime(snapId);\n if (!runtime) {\n throw new Error(`The snap \"${snapId}\" is not running.`);\n }\n\n // If we are already stopping, wait for that to finish.\n if (runtime.stopPromise) {\n await runtime.stopPromise;\n return;\n }\n\n // Flag that the Snap is actively stopping, this prevents other calls to stopSnap\n // while we are handling termination of the Snap\n const { promise, resolve } = createDeferredPromise();\n runtime.stopPromise = promise;\n\n try {\n if (this.isRunning(snapId)) {\n this.#closeAllConnections?.(snapId);\n await this.#terminateSnap(snapId);\n }\n } finally {\n // Reset request tracking\n runtime.lastRequest = null;\n runtime.pendingInboundRequests = [];\n runtime.pendingOutboundRequests = 0;\n runtime.stopPromise = null;\n if (this.isRunning(snapId)) {\n this.#transition(snapId, statusEvent);\n }\n resolve();\n }\n }\n\n /**\n * Stops all running snaps, removes all hooks, closes all connections, and\n * terminates their workers.\n *\n * @param statusEvent - The Snap status event that caused the snap to be\n * stopped.\n */\n public async stopAllSnaps(\n statusEvent:\n | SnapStatusEvents.Stop\n | SnapStatusEvents.Crash = SnapStatusEvents.Stop,\n ): Promise<void> {\n const snaps = Object.values(this.state.snaps).filter((snap) =>\n this.isRunning(snap.id),\n );\n const promises = snaps.map(async (snap) =>\n this.stopSnap(snap.id, statusEvent),\n );\n await Promise.allSettled(promises);\n }\n\n /**\n * Terminates the specified snap and emits the `snapTerminated` event.\n *\n * @param snapId - The snap to terminate.\n */\n async #terminateSnap(snapId: SnapId) {\n await this.messagingSystem.call('ExecutionService:terminateSnap', snapId);\n\n // Hack to give up execution for a bit to let gracefully terminating Snaps return.\n await new Promise((resolve) => setTimeout(resolve, 1));\n\n const runtime = this.#getRuntimeExpect(snapId);\n // Unresponsive requests may still be timed, time them out.\n runtime.pendingInboundRequests\n .filter((pendingRequest) => pendingRequest.timer.status !== 'finished')\n .forEach((pendingRequest) => pendingRequest.timer.finish());\n\n // Hack to give up execution for a bit to let timed out requests return.\n await new Promise((resolve) => setTimeout(resolve, 1));\n\n this.messagingSystem.publish(\n 'SnapController:snapTerminated',\n this.getTruncatedExpect(snapId),\n );\n }\n\n /**\n * Returns whether the given snap is running.\n * Throws an error if the snap doesn't exist.\n *\n * @param snapId - The id of the Snap to check.\n * @returns `true` if the snap is running, otherwise `false`.\n */\n isRunning(snapId: SnapId): boolean {\n return this.getExpect(snapId).status === 'running';\n }\n\n /**\n * Returns whether the given snap has been added to state.\n *\n * @param snapId - The id of the Snap to check for.\n * @returns `true` if the snap exists in the controller state, otherwise `false`.\n */\n has(snapId: SnapId): boolean {\n return Boolean(this.get(snapId));\n }\n\n /**\n * Gets the snap with the given id if it exists, including all data.\n * This should not be used if the snap is to be serializable, as e.g.\n * the snap sourceCode may be quite large.\n *\n * @param snapId - The id of the Snap to get.\n * @returns The entire snap object from the controller state.\n */\n get(snapId: string): Snap | undefined {\n return this.state.snaps[snapId as SnapId];\n }\n\n /**\n * Gets the snap with the given id, throws if doesn't.\n * This should not be used if the snap is to be serializable, as e.g.\n * the snap sourceCode may be quite large.\n *\n * @see {@link SnapController.get}\n * @throws {@link Error}. If the snap doesn't exist\n * @param snapId - The id of the snap to get.\n * @returns The entire snap object.\n */\n getExpect(snapId: SnapId): Snap {\n const snap = this.get(snapId);\n assert(snap !== undefined, new Error(`Snap \"${snapId}\" not found.`));\n return snap;\n }\n\n /**\n * Gets the snap with the given id if it exists, excluding any\n * non-serializable or expensive-to-serialize data.\n *\n * @param snapId - The id of the Snap to get.\n * @returns A truncated version of the snap state, that is less expensive to serialize.\n */\n // TODO(ritave): this.get returns undefined, this.getTruncated returns null\n getTruncated(snapId: SnapId): TruncatedSnap | null {\n const snap = this.get(snapId);\n\n return snap ? truncateSnap(snap) : null;\n }\n\n /**\n * Gets the snap with the given id, throw if it doesn't exist.\n *\n * @throws {@link Error}. If snap doesn't exist\n * @param snapId - The id of the snap to get.\n * @returns A truncated version of the snap state, that is less expensive to serialize.\n */\n getTruncatedExpect(snapId: SnapId): TruncatedSnap {\n return truncateSnap(this.getExpect(snapId));\n }\n\n /**\n * Check if a given Snap has a cached encryption key stored in the runtime.\n *\n * @param snapId - The Snap ID.\n * @param runtime - The Snap runtime data.\n * @returns True if the Snap has a cached encryption key, otherwise false.\n */\n #hasCachedEncryptionKey(\n snapId: SnapId,\n runtime = this.#getRuntimeExpect(snapId),\n ): runtime is SnapRuntimeData & {\n encryptionKey: string;\n encryptionSalt: string;\n } {\n return runtime.encryptionKey !== null && runtime.encryptionSalt !== null;\n }\n\n /**\n * Generate an encryption key to be used for state encryption for a given Snap.\n *\n * @param options - An options bag.\n * @param options.snapId - The Snap ID.\n * @param options.salt - A salt to be used for the encryption key.\n * @param options.useCache - Whether to use caching or not.\n * @param options.keyMetadata - Optional metadata about how to derive the encryption key.\n * @returns An encryption key.\n */\n async #getSnapEncryptionKey({\n snapId,\n salt: passedSalt,\n useCache,\n keyMetadata,\n }: {\n snapId: SnapId;\n salt?: string;\n useCache: boolean;\n keyMetadata?: KeyDerivationOptions;\n }): Promise<{ key: unknown; salt: string }> {\n const runtime = this.#getRuntimeExpect(snapId);\n\n if (this.#hasCachedEncryptionKey(snapId, runtime) && useCache) {\n return {\n key: await this.#encryptor.importKey(runtime.encryptionKey),\n salt: runtime.encryptionSalt,\n };\n }\n\n const salt = passedSalt ?? this.#encryptor.generateSalt();\n const seed = await this.#getMnemonicSeed();\n\n const entropy = await getEncryptionEntropy({\n snapId,\n seed,\n cryptographicFunctions: this.#clientCryptography,\n });\n\n const encryptionKey = await this.#encryptor.keyFromPassword(\n entropy,\n salt,\n true,\n keyMetadata,\n );\n const exportedKey = await this.#encryptor.exportKey(encryptionKey);\n\n // Cache exported encryption key in runtime\n if (useCache) {\n runtime.encryptionKey = exportedKey;\n runtime.encryptionSalt = salt;\n }\n return { key: encryptionKey, salt };\n }\n\n /**\n * Decrypt the encrypted state for a given Snap.\n *\n * @param snapId - The Snap ID.\n * @param state - The encrypted state as a string.\n * @returns A valid JSON object derived from the encrypted state.\n * @throws If the decryption fails or the decrypted state is not valid JSON.\n */\n async #decryptSnapState(snapId: SnapId, state: string) {\n try {\n // We assume that the state string here is valid JSON since we control serialization.\n // This lets us skip JSON validation.\n const parsed = JSON.parse(state) as EncryptionResult;\n const { salt, keyMetadata } = parsed;\n\n // We only cache encryption keys if they are already cached or if the encryption key is using the latest key derivation params.\n const useCache =\n this.#hasCachedEncryptionKey(snapId) ||\n this.#encryptor.isVaultUpdated(state);\n\n const { key } = await this.#getSnapEncryptionKey({\n snapId,\n salt,\n useCache,\n // When decrypting state we expect key metadata to be present.\n // If it isn't present, we assume that the Snap state we are decrypting is old enough to use the legacy encryption params.\n keyMetadata: keyMetadata ?? LEGACY_ENCRYPTION_KEY_DERIVATION_OPTIONS,\n });\n const decryptedState = await this.#encryptor.decryptWithKey(key, parsed);\n\n // We assume this to be valid JSON, since all RPC requests from a Snap are validated and sanitized.\n return decryptedState as Record<string, Json>;\n } catch {\n throw rpcErrors.internal({\n message: 'Failed to decrypt snap state, the state must be corrupted.',\n });\n }\n }\n\n /**\n * Encrypt a JSON state object for a given Snap.\n *\n * Note: This function does not assert the validity of the object,\n * please ensure only valid JSON is passed to it.\n *\n * @param snapId - The Snap ID.\n * @param state - The state object.\n * @returns A string containing the encrypted JSON object.\n */\n async #encryptSnapState(snapId: SnapId, state: Record<string, Json>) {\n const { key, salt } = await this.#getSnapEncryptionKey({\n snapId,\n useCache: true,\n });\n const encryptedState = await this.#encryptor.encryptWithKey(key, state);\n\n encryptedState.salt = salt;\n return JSON.stringify(encryptedState);\n }\n\n /**\n * Get the new Snap state to persist based on the given state and encryption\n * flag.\n *\n * - If the state is null, return null.\n * - If the state should be encrypted, return the encrypted state.\n * - Otherwise, if the state should not be encrypted, return the JSON-\n * stringified state.\n *\n * @param snapId - The Snap ID.\n * @param state - The state to persist.\n * @param encrypted - A flag to indicate whether to use encrypted storage or\n * not.\n * @returns The state to persist.\n */\n async #getStateToPersist(\n snapId: SnapId,\n state: Record<string, Json> | null,\n encrypted: boolean,\n ) {\n if (state === null) {\n return null;\n }\n\n if (encrypted) {\n return await this.#encryptSnapState(snapId, state);\n }\n\n return JSON.stringify(state);\n }\n\n /**\n * Persist the state of a Snap.\n *\n * This function is debounced per Snap, meaning that multiple calls to this\n * function for the same Snap will only result in one state update. It also\n * uses a mutex to ensure that only one state update per Snap is processed at\n * a time, avoiding possible race conditions.\n *\n * @param snapId - The Snap ID.\n * @param newSnapState - The new state of the Snap.\n * @param encrypted - A flag to indicate whether to use encrypted storage or\n * not.\n */\n readonly #persistSnapState = debouncePersistState(\n (\n snapId: SnapId,\n newSnapState: Record<string, Json> | null,\n encrypted: boolean,\n ) => {\n const runtime = this.#getRuntimeExpect(snapId);\n runtime.stateMutex\n .runExclusive(async () => {\n const newState = await this.#getStateToPersist(\n snapId,\n newSnapState,\n encrypted,\n );\n\n if (encrypted) {\n return this.update((state) => {\n state.snapStates[snapId] = newState;\n });\n }\n\n return this.update((state) => {\n state.unencryptedSnapStates[snapId] = newState;\n });\n })\n .catch(logError);\n },\n STATE_DEBOUNCE_TIMEOUT,\n );\n\n /**\n * Updates the own state of the snap with the given id.\n * This is distinct from the state MetaMask uses to manage snaps.\n *\n * @param snapId - The id of the Snap whose state should be updated.\n * @param newSnapState - The new state of the snap.\n * @param encrypted - A flag to indicate whether to use encrypted storage or not.\n */\n async updateSnapState(\n snapId: SnapId,\n newSnapState: Record<string, Json>,\n encrypted: boolean,\n ) {\n const runtime = this.#getRuntimeExpect(snapId);\n\n if (encrypted) {\n runtime.state = newSnapState;\n } else {\n runtime.unencryptedState = newSnapState;\n }\n\n this.#persistSnapState(snapId, newSnapState, encrypted);\n }\n\n /**\n * Clears the state of the snap with the given id.\n * This is distinct from the state MetaMask uses to manage snaps.\n *\n * @param snapId - The id of the Snap whose state should be cleared.\n * @param encrypted - A flag to indicate whether to use encrypted storage or not.\n */\n clearSnapState(snapId: SnapId, encrypted: boolean) {\n const runtime = this.#getRuntimeExpect(snapId);\n if (encrypted) {\n runtime.state = null;\n } else {\n runtime.unencryptedState = null;\n }\n\n this.#persistSnapState(snapId, null, encrypted);\n }\n\n /**\n * Gets the own state of the snap with the given id.\n * This is distinct from the state MetaMask uses to manage snaps.\n *\n * @param snapId - The id of the Snap whose state to get.\n * @param encrypted - A flag to indicate whether to use encrypted storage or not.\n * @returns The requested snap state or null if no state exists.\n */\n async getSnapState(snapId: SnapId, encrypted: boolean): Promise<Json> {\n const runtime = this.#getRuntimeExpect(snapId);\n return await runtime.getStateMutex.runExclusive(async () => {\n const cachedState = encrypted ? runtime.state : runtime.unencryptedState;\n\n if (cachedState !== undefined) {\n return cachedState;\n }\n\n const state = encrypted\n ? this.state.snapStates[snapId]\n : this.state.unencryptedSnapStates[snapId];\n\n if (state === null || state === undefined) {\n return null;\n }\n\n if (!encrypted) {\n // For performance reasons, we do not validate that the state is JSON,\n // since we control serialization.\n const json = JSON.parse(state);\n runtime.unencryptedState = json;\n\n return json;\n }\n\n const decrypted = await this.#decryptSnapState(snapId, state);\n // eslint-disable-next-line require-atomic-updates\n runtime.state = decrypted;\n\n return decrypted;\n });\n }\n\n /**\n * Gets a static auxiliary snap file in a chosen file encoding.\n *\n * @param snapId - The id of the Snap whose state to get.\n * @param path - The path to the requested file.\n * @param encoding - An optional requested file encoding.\n * @returns The file requested in the chosen file encoding or null if the file is not found.\n */\n async getSnapFile(\n snapId: SnapId,\n path: string,\n encoding: AuxiliaryFileEncoding = AuxiliaryFileEncoding.Base64,\n ): Promise<string | null> {\n const snap = this.getExpect(snapId);\n const normalizedPath = normalizeRelative(path);\n const value = snap.auxiliaryFiles?.find(\n (file) => file.path === normalizedPath,\n )?.value;\n\n if (!value) {\n return null;\n }\n\n const encoded = await encodeAuxiliaryFile(value, encoding);\n\n assert(\n encoded.length < MAX_FILE_SIZE,\n `Failed to encode static file to \"${encoding}\": Static files must be less than 64 MB when encoded.`,\n );\n\n return encoded;\n }\n\n /**\n * Determine if a given Snap ID supports a given minimum version of the Snaps platform\n * by inspecting the platformVersion in the Snap manifest.\n *\n * @param snapId - The Snap ID.\n * @param version - The version.\n * @returns True if the platform version is equal or greater to the passed version, false otherwise.\n */\n isMinimumPlatformVersion(snapId: SnapId, version: SemVerVersion): boolean {\n const snap = this.getExpect(snapId);\n\n const { platformVersion } = snap.manifest;\n\n if (!platformVersion) {\n return false;\n }\n\n return gte(platformVersion, version);\n }\n\n /**\n * Completely clear the controller's state: delete all associated data,\n * handlers, event listeners, and permissions; tear down all snap providers.\n */\n async clearState() {\n const snapIds = Object.keys(this.state.snaps);\n if (this.#closeAllConnections) {\n snapIds.forEach((snapId) => {\n this.#closeAllConnections?.(snapId);\n });\n }\n\n await this.messagingSystem.call('ExecutionService:terminateAllSnaps');\n snapIds.forEach((snapId) => this.#revokeAllSnapPermissions(snapId));\n\n this.update((state) => {\n state.snaps = {};\n state.snapStates = {};\n state.unencryptedSnapStates = {};\n });\n\n this.#snapsRuntimeData.clear();\n this.#rollbackSnapshots.clear();\n\n // We want to remove all snaps & permissions, except for preinstalled snaps\n if (this.#preinstalledSnaps) {\n this.#handlePreinstalledSnaps(this.#preinstalledSnaps);\n }\n }\n\n /**\n * Removes the given snap from state, and clears all associated handlers\n * and listeners.\n *\n * @param snapId - The id of the Snap.\n * @returns A promise that resolves once the snap has been removed.\n */\n async removeSnap(snapId: SnapId): Promise<void> {\n return this.removeSnaps([snapId]);\n }\n\n /**\n * Stops the given snaps, removes them from state, and clears all associated\n * permissions, handlers, and listeners.\n *\n * @param snapIds - The ids of the Snaps.\n */\n async removeSnaps(snapIds: SnapId[]): Promise<void> {\n if (!Array.isArray(snapIds)) {\n throw new Error('Expected array of snap ids.');\n }\n\n snapIds.forEach((snapId) => {\n const snap = this.getExpect(snapId);\n assert(snap.removable !== false, `${snapId} is not removable.`);\n });\n\n await Promise.all(\n snapIds.map(async (snapId) => {\n const snap = this.getExpect(snapId);\n const truncated = this.getTruncatedExpect(snapId);\n // Disable the snap and revoke all of its permissions before deleting\n // it. This ensures that the snap will not be restarted or otherwise\n // affect the host environment while we are deleting it.\n await this.disableSnap(snapId);\n this.#revokeAllSnapPermissions(snapId);\n\n this.#removeSnapFromSubjects(snapId);\n\n this.#snapsRuntimeData.delete(snapId);\n\n this.update((state: any) => {\n delete state.snaps[snapId];\n delete state.snapStates[snapId];\n delete state.unencryptedSnapStates[snapId];\n });\n\n // If the snap has been fully installed before, also emit snapUninstalled.\n if (snap.status !== SnapStatus.Installing) {\n this.messagingSystem.publish(\n `SnapController:snapUninstalled`,\n truncated,\n );\n }\n }),\n );\n }\n\n #handleInitialConnections(\n snapId: SnapId,\n previousInitialConnections: InitialConnections | null,\n initialConnections: InitialConnections,\n ) {\n if (previousInitialConnections) {\n const revokedInitialConnections = setDiff(\n previousInitialConnections,\n initialConnections,\n );\n\n for (const origin of Object.keys(revokedInitialConnections)) {\n this.removeSnapFromSubject(origin, snapId);\n }\n }\n\n for (const origin of Object.keys(initialConnections)) {\n this.#addSnapToSubject(origin, snapId);\n }\n }\n\n #addSnapToSubject(origin: string, snapId: SnapId) {\n const subjectPermissions = this.messagingSystem.call(\n 'PermissionController:getPermissions',\n origin,\n ) as SubjectPermissions<PermissionConstraint>;\n\n const existingCaveat = subjectPermissions?.[\n WALLET_SNAP_PERMISSION_KEY\n ]?.caveats?.find((caveat) => caveat.type === SnapCaveatType.SnapIds);\n\n const subjectHasSnap = Boolean(\n (existingCaveat?.value as Record<string, Json>)?.[snapId],\n );\n\n // If the subject is already connected to the snap, this is a no-op.\n if (subjectHasSnap) {\n return;\n }\n\n // If an existing caveat exists, we add the snap to that.\n if (existingCaveat) {\n this.messagingSystem.call(\n 'PermissionController:updateCaveat',\n origin,\n WALLET_SNAP_PERMISSION_KEY,\n SnapCaveatType.SnapIds,\n { ...(existingCaveat.value as Record<string, Json>), [snapId]: {} },\n );\n return;\n }\n\n const approvedPermissions = {\n [WALLET_SNAP_PERMISSION_KEY]: {\n caveats: [\n {\n type: SnapCaveatType.SnapIds,\n value: {\n [snapId]: {},\n },\n },\n ],\n },\n } as RequestedPermissions;\n\n this.messagingSystem.call('PermissionController:grantPermissions', {\n approvedPermissions,\n subject: { origin },\n });\n }\n\n /**\n * Removes a snap's permission (caveat) from the specified subject.\n *\n * @param origin - The origin from which to remove the snap.\n * @param snapId - The id of the snap to remove.\n */\n removeSnapFromSubject(origin: string, snapId: SnapId) {\n const subjectPermissions = this.messagingSystem.call(\n 'PermissionController:getPermissions',\n origin,\n ) as SubjectPermissions<PermissionConstraint>;\n\n const snapIdsCaveat = subjectPermissions?.[\n WALLET_SNAP_PERMISSION_KEY\n ]?.caveats?.find((caveat) => caveat.type === SnapCaveatType.SnapIds) as\n | Caveat<string, Json>\n | undefined;\n\n if (!snapIdsCaveat) {\n return;\n }\n\n const caveatHasSnap = Boolean(\n (snapIdsCaveat.value as Record<string, Json>)?.[snapId],\n );\n if (caveatHasSnap) {\n const newCaveatValue = {\n ...(snapIdsCaveat.value as Record<string, Json>),\n };\n delete newCaveatValue[snapId];\n if (Object.keys(newCaveatValue).length > 0) {\n this.messagingSystem.call(\n 'PermissionController:updateCaveat',\n origin,\n WALLET_SNAP_PERMISSION_KEY,\n SnapCaveatType.SnapIds,\n newCaveatValue,\n );\n } else {\n this.messagingSystem.call('PermissionController:revokePermissions', {\n [origin]: [WALLET_SNAP_PERMISSION_KEY],\n });\n }\n }\n }\n\n /**\n * Checks if a list of permissions are dynamic and allowed to be revoked, if they are they will all be revoked.\n *\n * @param snapId - The snap ID.\n * @param permissionNames - The names of the permissions.\n * @throws If non-dynamic permissions are passed.\n */\n revokeDynamicSnapPermissions(\n snapId: string,\n permissionNames: NonEmptyArray<string>,\n ) {\n assert(\n permissionNames.every((permissionName) =>\n this.#dynamicPermissions.includes(permissionName),\n ),\n 'Non-dynamic permissions cannot be revoked',\n );\n this.messagingSystem.call('PermissionController:revokePermissions', {\n [snapId]: permissionNames,\n });\n }\n\n /**\n * Removes a snap's permission (caveat) from all subjects.\n *\n * @param snapId - The id of the Snap.\n */\n #removeSnapFromSubjects(snapId: SnapId) {\n const subjects = this.messagingSystem.call(\n 'PermissionController:getSubjectNames',\n );\n for (const subject of subjects) {\n this.removeSnapFromSubject(subject, snapId);\n }\n }\n\n /**\n * Safely revokes all permissions granted to a Snap.\n *\n * @param snapId - The snap ID.\n */\n #revokeAllSnapPermissions(snapId: string) {\n if (\n this.messagingSystem.call('PermissionController:hasPermissions', snapId)\n ) {\n this.messagingSystem.call(\n 'PermissionController:revokeAllPermissions',\n snapId,\n );\n }\n }\n\n /**\n * Handles incrementing the activeReferences counter.\n *\n * @param snapId - The snap id of the snap that was referenced.\n */\n incrementActiveReferences(snapId: SnapId) {\n const runtime = this.#getRuntimeExpect(snapId);\n runtime.activeReferences += 1;\n }\n\n /**\n * Handles decrement the activeReferences counter.\n *\n * @param snapId - The snap id of the snap that was referenced..\n */\n decrementActiveReferences(snapId: SnapId) {\n const runtime = this.#getRuntimeExpect(snapId);\n assert(\n runtime.activeReferences > 0,\n 'SnapController reference management is in an invalid state.',\n );\n runtime.activeReferences -= 1;\n }\n\n /**\n * Gets all snaps in their truncated format.\n *\n * @returns All installed snaps in their truncated format.\n */\n getAllSnaps(): TruncatedSnap[] {\n return Object.values(this.state.snaps).map(truncateSnap);\n }\n\n /**\n * Gets all runnable snaps.\n *\n * @returns All runnable snaps.\n */\n getRunnableSnaps(): TruncatedSnap[] {\n return getRunnableSnaps(this.getAllSnaps());\n }\n\n /**\n * Gets the serialized permitted snaps of the given origin, if any.\n *\n * @param origin - The origin whose permitted snaps to retrieve.\n * @returns The serialized permitted snaps for the origin.\n */\n getPermittedSnaps(origin: string): RequestSnapsResult {\n const permissions =\n this.messagingSystem.call(\n 'PermissionController:getPermissions',\n origin,\n ) ?? {};\n const snaps =\n permissions[WALLET_SNAP_PERMISSION_KEY]?.caveats?.find(\n (caveat) => caveat.type === SnapCaveatType.SnapIds,\n )?.value ?? {};\n return Object.keys(snaps).reduce<RequestSnapsResult>(\n (permittedSnaps, snapId) => {\n const snap = this.get(snapId);\n const truncatedSnap = this.getTruncated(snapId as SnapId);\n\n if (truncatedSnap && snap?.status !== SnapStatus.Installing) {\n permittedSnaps[snapId] = truncatedSnap;\n }\n return permittedSnaps;\n },\n {},\n );\n }\n\n /**\n * Installs the snaps requested by the given origin, returning the snap\n * object if the origin is permitted to install it, and an authorization error\n * otherwise.\n *\n * @param origin - The origin that requested to install the snaps.\n * @param requestedSnaps - The snaps to install.\n * @returns An object of snap ids and snap objects, or errors if a\n * snap couldn't be installed.\n */\n async installSnaps(\n origin: string,\n requestedSnaps: RequestSnapsParams,\n ): Promise<RequestSnapsResult> {\n this.#assertCanUsePlatform();\n\n const result: RequestSnapsResult = {};\n\n const snapIds = Object.keys(requestedSnaps);\n\n const pendingUpdates = [];\n const pendingInstalls = [];\n\n try {\n for (const [snapId, { version: rawVersion }] of Object.entries(\n requestedSnaps,\n )) {\n assertIsValidSnapId(snapId);\n\n const [error, version] = resolveVersionRange(rawVersion);\n\n if (error) {\n throw rpcErrors.invalidParams(\n `The \"version\" field must be a valid SemVer version range if specified. Received: \"${\n rawVersion as string\n }\".`,\n );\n }\n\n const location = this.#detectSnapLocation(snapId, {\n versionRange: version,\n fetch: this.#fetchFunction,\n allowLocal: this.#featureFlags.allowLocalSnaps,\n resolveVersion: async (range) =>\n this.#featureFlags.requireAllowlist\n ? await this.#resolveAllowlistVersion(snapId, range)\n : range,\n });\n\n // Existing snaps may need to be updated, unless they should be re-installed (e.g. local snaps)\n // Everything else is treated as an install\n const isUpdate = this.has(snapId) && !location.shouldAlwaysReload;\n\n if (isUpdate && this.#isValidUpdate(snapId, version)) {\n const existingSnap = this.getExpect(snapId);\n pendingUpdates.push({ snapId, oldVersion: existingSnap.version });\n let rollbackSnapshot = this.#getRollbackSnapshot(snapId);\n if (rollbackSnapshot === undefined) {\n rollbackSnapshot = this.#createRollbackSnapshot(snapId);\n rollbackSnapshot.newVersion = version;\n } else {\n throw new Error('This snap is already being updated.');\n }\n } else if (!isUpdate) {\n pendingInstalls.push(snapId);\n }\n\n result[snapId] = await this.processRequestedSnap(\n origin,\n snapId,\n location,\n version,\n );\n }\n\n // Once we finish all installs / updates, emit events.\n pendingInstalls.forEach((snapId) =>\n this.messagingSystem.publish(\n `SnapController:snapInstalled`,\n this.getTruncatedExpect(snapId),\n origin,\n false,\n ),\n );\n\n pendingUpdates.forEach(({ snapId, oldVersion }) =>\n this.messagingSystem.publish(\n `SnapController:snapUpdated`,\n this.getTruncatedExpect(snapId),\n oldVersion,\n origin,\n false,\n ),\n );\n\n snapIds.forEach((snapId) => this.#rollbackSnapshots.delete(snapId));\n } catch (error) {\n const installed = pendingInstalls.filter((snapId) => this.has(snapId));\n await this.removeSnaps(installed);\n const snapshottedSnaps = [...this.#rollbackSnapshots.keys()];\n const snapsToRollback = pendingUpdates\n .map(({ snapId }) => snapId)\n .filter((snapId) => snapshottedSnaps.includes(snapId));\n await this.#rollbackSnaps(snapsToRollback);\n\n throw error;\n }\n\n return result;\n }\n\n /**\n * Adds, authorizes, and runs the given snap with a snap provider.\n * Results from this method should be efficiently serializable.\n *\n * @param origin - The origin requesting the snap.\n * @param snapId - The id of the snap.\n * @param location - The location implementation of the snap.\n * @param versionRange - The semver range of the snap to install.\n * @returns The resulting snap object, or an error if something went wrong.\n */\n // TODO: Either fix this lint violation or explain why it's necessary to\n // ignore.\n // eslint-disable-next-line no-restricted-syntax\n private async processRequestedSnap(\n origin: string,\n snapId: SnapId,\n location: SnapLocation,\n versionRange: SemVerRange,\n ): Promise<TruncatedSnap> {\n const existingSnap = this.getTruncated(snapId);\n\n // For devX we always re-install local snaps.\n if (existingSnap && !location.shouldAlwaysReload) {\n if (satisfiesVersionRange(existingSnap.version, versionRange)) {\n return existingSnap;\n }\n\n return await this.updateSnap(\n origin,\n snapId,\n location,\n versionRange,\n // Since we are requesting an update from within processRequestedSnap,\n // we disable the emitting of the snapUpdated event and rely on the caller\n // to publish this event after the update is complete.\n // This is necessary as installSnaps may be installing multiple snaps\n // and we don't want to emit events prematurely.\n false,\n );\n }\n\n this.#assertCanInstallSnaps();\n\n let pendingApproval = this.#createApproval({\n origin,\n snapId,\n type: SNAP_APPROVAL_INSTALL,\n });\n\n this.messagingSystem.publish(\n 'SnapController:snapInstallStarted',\n snapId,\n origin,\n false,\n );\n\n // Existing snaps must be stopped before overwriting\n if (existingSnap && this.isRunning(snapId)) {\n await this.stopSnap(snapId, SnapStatusEvents.Stop);\n }\n\n // Existing snaps that should be re-installed should not maintain their existing permissions\n if (existingSnap && location.shouldAlwaysReload) {\n this.#revokeAllSnapPermissions(snapId);\n }\n\n try {\n const { sourceCode } = await this.#add({\n origin,\n id: snapId,\n location,\n versionRange,\n });\n\n await this.authorize(snapId, pendingApproval);\n\n pendingApproval = this.#createApproval({\n origin,\n snapId,\n type: SNAP_APPROVAL_RESULT,\n });\n\n await this.#startSnap({\n snapId,\n sourceCode,\n });\n\n const truncated = this.getTruncatedExpect(snapId);\n\n this.#updateApproval(pendingApproval.id, {\n loading: false,\n type: SNAP_APPROVAL_INSTALL,\n });\n\n return truncated;\n } catch (error) {\n logError(`Error when adding ${snapId}.`, error);\n\n const errorString =\n error instanceof Error ? error.message : error.toString();\n\n this.#updateApproval(pendingApproval.id, {\n loading: false,\n type: SNAP_APPROVAL_INSTALL,\n error: errorString,\n });\n\n this.messagingSystem.publish(\n 'SnapController:snapInstallFailed',\n snapId,\n origin,\n false,\n errorString,\n );\n\n throw error;\n }\n }\n\n #createApproval({\n origin,\n snapId,\n type,\n }: {\n origin: string;\n snapId: SnapId;\n type: string;\n }): PendingApproval {\n const id = nanoid();\n const promise = this.messagingSystem.call(\n 'ApprovalController:addRequest',\n {\n origin,\n id,\n type,\n requestData: {\n // Mirror previous installation metadata\n metadata: { id, origin: snapId, dappOrigin: origin },\n snapId,\n },\n requestState: {\n loading: true,\n },\n },\n true,\n );\n\n return { id, promise };\n }\n\n #updateApproval(id: string, requestState: Record<string, Json>) {\n try {\n this.messagingSystem.call('ApprovalController:updateRequestState', {\n id,\n requestState,\n });\n } catch {\n // Do nothing\n }\n }\n\n /**\n * Updates an installed snap. The flow is similar to\n * {@link SnapController.installSnaps}. The user will be asked if they want\n * to update, then approve any permission changes, and finally the snap will\n * be restarted.\n *\n * The update will fail if the user rejects any prompt or if the new version\n * of the snap is blocked.\n *\n * If the original version of the snap was blocked and the update succeeded,\n * the snap will be unblocked and enabled before it is restarted.\n *\n * @param origin - The origin requesting the snap update.\n * @param snapId - The id of the Snap to be updated.\n * @param location - The location implementation of the snap.\n * @param newVersionRange - A semver version range in which the maximum version will be chosen.\n * @param emitEvent - An optional boolean flag to indicate whether this update should emit an event.\n * @returns The snap metadata if updated, `null` otherwise.\n */\n async updateSnap(\n origin: string,\n snapId: SnapId,\n location: SnapLocation,\n newVersionRange: string = DEFAULT_REQUESTED_SNAP_VERSION,\n emitEvent = true,\n ): Promise<TruncatedSnap> {\n this.#assertCanInstallSnaps();\n this.#assertCanUsePlatform();\n\n const snap = this.getExpect(snapId);\n\n if (snap.preinstalled) {\n throw new Error('Preinstalled Snaps cannot be manually updated.');\n }\n\n if (!isValidSemVerRange(newVersionRange)) {\n throw new Error(\n `Received invalid snap version range: \"${newVersionRange}\".`,\n );\n }\n\n let pendingApproval = this.#createApproval({\n origin,\n snapId,\n type: SNAP_APPROVAL_UPDATE,\n });\n\n try {\n this.messagingSystem.publish(\n 'SnapController:snapInstallStarted',\n snapId,\n origin,\n true,\n );\n\n const oldManifest = snap.manifest;\n\n const newSnap = await fetchSnap(snapId, location);\n const { sourceCode: sourceCodeFile, manifest: manifestFile } = newSnap;\n\n const manifest = manifestFile.result;\n\n const newVersion = manifest.version;\n if (!gtVersion(newVersion, snap.version)) {\n throw rpcErrors.invalidParams(\n `Snap \"${snapId}@${snap.version}\" is already installed. Couldn't update to a version inside requested \"${newVersionRange}\" range.`,\n );\n }\n\n if (!satisfiesVersionRange(newVersion, newVersionRange)) {\n throw new Error(\n `Version mismatch. Manifest for \"${snapId}\" specifies version \"${newVersion}\" which doesn't satisfy requested version range \"${newVersionRange}\".`,\n );\n }\n\n await this.#assertIsInstallAllowed(snapId, {\n version: newVersion,\n checksum: manifest.source.shasum,\n permissions: manifest.initialPermissions,\n platformVersion: manifest.platformVersion,\n });\n\n const processedPermissions = processSnapPermissions(\n manifest.initialPermissions,\n );\n\n this.#validateSnapPermissions(processedPermissions);\n\n const { newPermissions, unusedPermissions, approvedPermissions } =\n this.#calculatePermissionsChange(snapId, processedPermissions);\n\n const { newConnections, unusedConnections, approvedConnections } =\n this.#calculateConnectionsChange(\n snapId,\n oldManifest.initialConnections ?? {},\n manifest.initialConnections ?? {},\n );\n\n this.#updateApproval(pendingApproval.id, {\n permissions: newPermissions,\n newVersion: manifest.version,\n newPermissions,\n approvedPermissions,\n unusedPermissions,\n newConnections,\n unusedConnections,\n approvedConnections,\n loading: false,\n });\n\n const { permissions: approvedNewPermissions, ...requestData } =\n (await pendingApproval.promise) as PermissionsRequest;\n\n pendingApproval = this.#createApproval({\n origin,\n snapId,\n type: SNAP_APPROVAL_RESULT,\n });\n\n if (this.isRunning(snapId)) {\n await this.stopSnap(snapId, SnapStatusEvents.Stop);\n }\n\n this.#transition(snapId, SnapStatusEvents.Update);\n\n this.#set({\n origin,\n id: snapId,\n files: newSnap,\n isUpdate: true,\n });\n\n this.#updatePermissions({\n snapId,\n unusedPermissions,\n newPermissions: approvedNewPermissions,\n requestData,\n });\n\n if (manifest.initialConnections) {\n this.#handleInitialConnections(\n snapId,\n oldManifest.initialConnections ?? null,\n manifest.initialConnections,\n );\n }\n\n const rollbackSnapshot = this.#getRollbackSnapshot(snapId);\n if (rollbackSnapshot !== undefined) {\n rollbackSnapshot.permissions.revoked = unusedPermissions;\n rollbackSnapshot.permissions.granted = approvedNewPermissions;\n rollbackSnapshot.permissions.requestData = requestData;\n }\n\n const sourceCode = sourceCodeFile.toString();\n\n assert(\n typeof sourceCode === 'string' && sourceCode.length > 0,\n `Invalid source code for snap \"${snapId}\".`,\n );\n\n try {\n await this.#startSnap({ snapId, sourceCode });\n } catch {\n throw new Error(`Snap ${snapId} crashed with updated source code.`);\n }\n\n const truncatedSnap = this.getTruncatedExpect(snapId);\n\n if (emitEvent) {\n this.messagingSystem.publish(\n 'SnapController:snapUpdated',\n truncatedSnap,\n snap.version,\n origin,\n false,\n );\n }\n\n this.#updateApproval(pendingApproval.id, {\n loading: false,\n type: SNAP_APPROVAL_UPDATE,\n });\n\n return truncatedSnap;\n } catch (error) {\n logError(`Error when updating ${snapId},`, error);\n\n const errorString =\n error instanceof Error ? error.message : error.toString();\n\n this.#updateApproval(pendingApproval.id, {\n loading: false,\n error: errorString,\n type: SNAP_APPROVAL_UPDATE,\n });\n\n this.messagingSystem.publish(\n 'SnapController:snapInstallFailed',\n snapId,\n origin,\n true,\n errorString,\n );\n\n throw error;\n }\n }\n\n async #resolveAllowlistVersion(\n snapId: SnapId,\n versionRange: SemVerRange,\n ): Promise<SemVerRange> {\n return await this.messagingSystem.call(\n 'SnapsRegistry:resolveVersion',\n snapId,\n versionRange,\n );\n }\n\n /**\n * Returns a promise representing the complete installation of the requested snap.\n * If the snap is already being installed, the previously pending promise will be returned.\n *\n * @param args - Object containing the snap id and either the URL of the snap's manifest,\n * or the snap's manifest and source code. The object may also optionally contain a target\n * version.\n * @returns The resulting snap object.\n */\n async #add(args: AddSnapArgs): Promise<PersistedSnap> {\n const { id: snapId, location, versionRange } = args;\n\n this.#setupRuntime(snapId);\n const runtime = this.#getRuntimeExpect(snapId);\n if (!runtime.installPromise) {\n log(`Adding snap: ${snapId}`);\n\n // If fetching and setting the snap succeeds, this property will be set\n // to null in the authorize() method.\n runtime.installPromise = (async () => {\n const fetchedSnap = await fetchSnap(snapId, location);\n const manifest = fetchedSnap.manifest.result;\n if (!satisfiesVersionRange(manifest.version, versionRange)) {\n throw new Error(\n `Version mismatch. Manifest for \"${snapId}\" specifies version \"${manifest.version}\" which doesn't satisfy requested version range \"${versionRange}\".`,\n );\n }\n\n await this.#assertIsInstallAllowed(snapId, {\n version: manifest.version,\n checksum: manifest.source.shasum,\n permissions: manifest.initialPermissions,\n platformVersion: manifest.platformVersion,\n });\n\n return this.#set({\n ...args,\n files: fetchedSnap,\n id: snapId,\n });\n })();\n }\n\n try {\n return await runtime.installPromise;\n } catch (error) {\n // Reset promise so users can retry installation in case the problem is\n // temporary.\n runtime.installPromise = null;\n throw error;\n }\n }\n\n async #startSnap(snapData: { snapId: SnapId; sourceCode: string }) {\n const { snapId } = snapData;\n if (this.isRunning(snapId)) {\n throw new Error(`Snap \"${snapId}\" is already started.`);\n }\n\n try {\n const runtime = this.#getRuntimeExpect(snapId);\n const result = await this.messagingSystem.call(\n 'ExecutionService:executeSnap',\n {\n ...snapData,\n endowments: await this.#getEndowments(snapId),\n },\n );\n\n this.#transition(snapId, SnapStatusEvents.Start);\n // We treat the initialization of the snap as the first request, for idle timing purposes.\n runtime.lastRequest = Date.now();\n return result;\n } catch (error) {\n await this.#terminateSnap(snapId);\n throw error;\n }\n }\n\n /**\n * Gets the names of all endowments that will be added to the Snap's\n * Compartment when it executes. These should be the names of global\n * JavaScript APIs accessible in the root realm of the execution environment.\n *\n * Throws an error if the endowment getter for a permission returns a truthy\n * value that is not an array of strings.\n *\n * @param snapId - The id of the snap whose SES endowments to get.\n * @returns An array of the names of the endowments.\n */\n async #getEndowments(snapId: string): Promise<string[]> {\n let allEndowments: string[] = [];\n\n for (const permissionName of this.#environmentEndowmentPermissions) {\n if (\n this.messagingSystem.call(\n 'PermissionController:hasPermission',\n snapId,\n permissionName,\n )\n ) {\n const endowments = await this.messagingSystem.call(\n 'PermissionController:getEndowments',\n snapId,\n permissionName,\n );\n\n if (endowments) {\n // We don't have any guarantees about the type of the endowments\n // value, so we have to guard at runtime.\n if (\n !Array.isArray(endowments) ||\n endowments.some((value) => typeof value !== 'string')\n ) {\n throw new Error('Expected an array of string endowment names.');\n }\n\n allEndowments = allEndowments.concat(endowments as string[]);\n }\n }\n }\n\n const dedupedEndowments = [\n ...new Set([...DEFAULT_ENDOWMENTS, ...allEndowments]),\n ];\n\n if (\n dedupedEndowments.length <\n DEFAULT_ENDOWMENTS.length + allEndowments.length\n ) {\n logError(\n `Duplicate endowments found for ${snapId}. Default endowments should not be requested.`,\n allEndowments,\n );\n }\n return dedupedEndowments;\n }\n\n /**\n * Sets a snap in state. Called when a snap is installed or updated. Performs\n * various validation checks on the received arguments, and will throw if\n * validation fails.\n *\n * The snap will be enabled and unblocked by the time this method returns,\n * regardless of its previous state.\n *\n * See {@link SnapController.add} and {@link SnapController.updateSnap} for\n * usage.\n *\n * @param args - The add snap args.\n * @returns The resulting snap object.\n */\n #set(args: SetSnapArgs): PersistedSnap {\n const {\n id: snapId,\n origin,\n files,\n isUpdate = false,\n removable,\n preinstalled,\n hidden,\n hideSnapBranding,\n } = args;\n\n const {\n manifest,\n sourceCode: sourceCodeFile,\n svgIcon,\n auxiliaryFiles: rawAuxiliaryFiles,\n localizationFiles,\n } = files;\n\n assertIsSnapManifest(manifest.result);\n const { version } = manifest.result;\n\n const sourceCode = sourceCodeFile.toString();\n\n assert(\n typeof sourceCode === 'string' && sourceCode.length > 0,\n `Invalid source code for snap \"${snapId}\".`,\n );\n\n const auxiliaryFiles = rawAuxiliaryFiles.map((file) => {\n assert(typeof file.data.base64 === 'string');\n return {\n path: file.path,\n value: file.data.base64,\n };\n });\n\n const snapsState = this.state.snaps;\n\n const existingSnap = snapsState[snapId];\n\n const previousVersionHistory = existingSnap?.versionHistory ?? [];\n const versionHistory = [\n ...previousVersionHistory,\n {\n version,\n date: Date.now(),\n origin,\n },\n ];\n\n const localizedFiles = localizationFiles.map((file) => file.result);\n\n const snap: Snap = {\n // Restore relevant snap state if it exists\n ...existingSnap,\n\n // Note that the snap will be unblocked and enabled, regardless of its\n // previous state.\n blocked: false,\n enabled: true,\n\n removable,\n preinstalled,\n hidden,\n hideSnapBranding,\n\n id: snapId,\n initialConnections: manifest.result.initialConnections,\n initialPermissions: manifest.result.initialPermissions,\n manifest: manifest.result,\n status: this.#statusMachine.config.initial as StatusStates['value'],\n sourceCode,\n version,\n versionHistory,\n auxiliaryFiles,\n localizationFiles: localizedFiles,\n };\n\n // If the snap was blocked, it isn't any longer\n delete snap.blockInformation;\n\n // store the snap back in state\n const { inversePatches } = this.update((state: any) => {\n state.snaps[snapId] = snap;\n });\n\n // checking for isUpdate here as this function is also used in\n // the install flow, we do not care to create snapshots for installs\n if (isUpdate) {\n const rollbackSnapshot = this.#getRollbackSnapshot(snapId);\n if (rollbackSnapshot !== undefined) {\n rollbackSnapshot.statePatches = inversePatches;\n }\n }\n\n // In case the Snap uses a localized manifest, we need to get the\n // proposed name from the localized manifest.\n const { proposedName } = getLocalizedSnapManifest(\n manifest.result,\n 'en',\n localizedFiles,\n );\n\n this.messagingSystem.call('SubjectMetadataController:addSubjectMetadata', {\n subjectType: SubjectType.Snap,\n name: proposedName,\n origin: snap.id,\n version,\n svgIcon: svgIcon?.toString() ?? null,\n });\n\n return { ...snap, sourceCode };\n }\n\n #validateSnapPermissions(\n processedPermissions: Record<string, Pick<PermissionConstraint, 'caveats'>>,\n ) {\n const permissionKeys = Object.keys(processedPermissions);\n const handlerPermissions = Array.from(\n new Set(Object.values(handlerEndowments)),\n );\n\n assert(\n permissionKeys.some((key) => handlerPermissions.includes(key)),\n `A snap must request at least one of the following permissions: ${handlerPermissions\n .filter((handler) => handler !== null)\n .join(', ')}.`,\n );\n\n const excludedPermissionErrors = permissionKeys.reduce<string[]>(\n (errors, permission) => {\n if (hasProperty(this.#excludedPermissions, permission)) {\n errors.push(this.#excludedPermissions[permission]);\n }\n\n return errors;\n },\n [],\n );\n\n assert(\n excludedPermissionErrors.length === 0,\n `One or more permissions are not allowed:\\n${excludedPermissionErrors.join(\n '\\n',\n )}`,\n );\n }\n\n /**\n * Validate that the platform version specified in the manifest (if any) is\n * compatible with the current platform version.\n *\n * @param snapId - The ID of the Snap.\n * @param platformVersion - The platform version to validate against.\n * @throws If the platform version is greater than the current platform\n * version.\n */\n #validatePlatformVersion(\n snapId: SnapId,\n platformVersion: string | undefined,\n ) {\n if (platformVersion === undefined) {\n return;\n }\n\n if (gt(platformVersion, getPlatformVersion())) {\n const message = `The Snap \"${snapId}\" requires platform version \"${platformVersion}\" which is greater than the current platform version \"${getPlatformVersion()}\".`;\n\n if (this.#featureFlags.rejectInvalidPlatformVersion) {\n throw new Error(message);\n }\n\n logWarning(message);\n }\n }\n\n /**\n * Initiates a request for the given snap's initial permissions.\n * Must be called in order. See processRequestedSnap.\n *\n * This function is not hash private yet because of tests.\n *\n * @param snapId - The id of the Snap.\n * @param pendingApproval - Pending approval to update.\n * @returns The snap's approvedPermissions.\n */\n // eslint-disable-next-line no-restricted-syntax\n private async authorize(\n snapId: SnapId,\n pendingApproval: PendingApproval,\n ): Promise<void> {\n log(`Authorizing snap: ${snapId}`);\n const snapsState = this.state.snaps;\n const snap = snapsState[snapId];\n const { initialPermissions, initialConnections } = snap;\n\n try {\n const processedPermissions = processSnapPermissions(initialPermissions);\n\n this.#validateSnapPermissions(processedPermissions);\n\n this.#updateApproval(pendingApproval.id, {\n loading: false,\n connections: initialConnections ?? {},\n permissions: processedPermissions,\n });\n\n const { permissions: approvedPermissions, ...requestData } =\n (await pendingApproval.promise) as PermissionsRequest;\n\n this.#updatePermissions({\n snapId,\n newPermissions: approvedPermissions,\n requestData,\n });\n\n if (snap.manifest.initialConnections) {\n this.#handleInitialConnections(\n snapId,\n null,\n snap.manifest.initialConnections,\n );\n }\n } finally {\n const runtime = this.#getRuntimeExpect(snapId);\n runtime.installPromise = null;\n }\n }\n\n destroy() {\n super.destroy();\n\n if (this.#timeoutForLastRequestStatus) {\n clearTimeout(this.#timeoutForLastRequestStatus);\n }\n\n /* eslint-disable @typescript-eslint/unbound-method */\n this.messagingSystem.unsubscribe(\n 'ExecutionService:unhandledError',\n this._onUnhandledSnapError,\n );\n\n this.messagingSystem.unsubscribe(\n 'ExecutionService:outboundRequest',\n this._onOutboundRequest,\n );\n\n this.messagingSystem.unsubscribe(\n 'ExecutionService:outboundResponse',\n this._onOutboundResponse,\n );\n\n this.messagingSystem.clearEventSubscriptions(\n 'SnapController:snapInstalled',\n );\n\n this.messagingSystem.clearEventSubscriptions('SnapController:snapUpdated');\n /* eslint-enable @typescript-eslint/unbound-method */\n }\n\n /**\n * Passes a JSON-RPC request object to the RPC handler function of a snap.\n *\n * @param options - A bag of options.\n * @param options.snapId - The ID of the recipient snap.\n * @param options.origin - The origin of the RPC request.\n * @param options.handler - The handler to trigger on the snap for the request.\n * @param options.request - The JSON-RPC request object.\n * @returns The result of the JSON-RPC request.\n */\n async handleRequest({\n snapId,\n origin,\n handler: handlerType,\n request: rawRequest,\n }: SnapRpcHookArgs & { snapId: SnapId }): Promise<unknown> {\n this.#assertCanUsePlatform();\n\n assert(\n origin === METAMASK_ORIGIN || isValidUrl(origin),\n \"'origin' must be a valid URL or 'metamask'.\",\n );\n\n const request = {\n jsonrpc: '2.0',\n id: nanoid(),\n ...rawRequest,\n };\n\n assertIsJsonRpcRequest(request);\n\n const permissionName = handlerEndowments[handlerType];\n\n assert(\n typeof permissionName === 'string' || permissionName === null,\n \"'permissionName' must be either a string or null.\",\n );\n\n const permissions = this.messagingSystem.call(\n 'PermissionController:getPermissions',\n snapId,\n );\n\n // If permissionName is null, the handler does not require a permission.\n if (\n permissionName !== null &&\n (!permissions || !hasProperty(permissions, permissionName))\n ) {\n throw new Error(\n `Snap \"${snapId}\" is not permitted to use \"${permissionName}\".`,\n );\n }\n\n const handlerPermissions = permissionName\n ? (permissions as SubjectPermissions<PermissionConstraint>)[\n permissionName\n ]\n : undefined;\n\n if (\n permissionName === SnapEndowments.Rpc ||\n permissionName === SnapEndowments.Keyring\n ) {\n assert(handlerPermissions);\n\n const subject = this.messagingSystem.call(\n 'SubjectMetadataController:getSubjectMetadata',\n origin,\n );\n\n const origins =\n permissionName === SnapEndowments.Rpc\n ? getRpcCaveatOrigins(handlerPermissions)\n : getKeyringCaveatOrigins(handlerPermissions);\n assert(origins);\n\n if (\n !isOriginAllowed(\n origins,\n subject?.subjectType ?? SubjectType.Website,\n origin,\n )\n ) {\n throw new Error(\n `Snap \"${snapId}\" is not permitted to handle requests from \"${origin}\".`,\n );\n }\n }\n\n if (\n origin !== METAMASK_ORIGIN &&\n CLIENT_ONLY_HANDLERS.includes(handlerType)\n ) {\n throw new Error(`\"${handlerType}\" can only be invoked by MetaMask.`);\n }\n\n if (!this.state.snaps[snapId].enabled) {\n throw new Error(`Snap \"${snapId}\" is disabled.`);\n }\n\n if (this.state.snaps[snapId].status === SnapStatus.Installing) {\n throw new Error(\n `Snap \"${snapId}\" is currently being installed. Please try again later.`,\n );\n }\n\n const timeout = this.#getExecutionTimeout(handlerPermissions);\n\n const runtime = this.#getRuntimeExpect(snapId);\n\n if (runtime.stopPromise) {\n await runtime.stopPromise;\n }\n\n if (!this.isRunning(snapId)) {\n if (!runtime.startPromise) {\n runtime.startPromise = this.startSnap(snapId);\n }\n\n try {\n await runtime.startPromise;\n } finally {\n runtime.startPromise = null;\n }\n }\n\n const transformedRequest = this.#transformSnapRpcRequest(\n snapId,\n handlerType,\n request,\n );\n\n const timer = new Timer(timeout);\n this.#recordSnapRpcRequestStart(snapId, transformedRequest.id, timer);\n\n const handleRpcRequestPromise = this.messagingSystem.call(\n 'ExecutionService:handleRpcRequest',\n snapId,\n { origin, handler: handlerType, request: transformedRequest },\n );\n\n // This will either get the result or reject due to the timeout.\n try {\n const result = await withTimeout(handleRpcRequestPromise, timer);\n\n if (result === hasTimedOut) {\n const stopping =\n runtime.stopPromise !== null || !this.isRunning(snapId);\n throw new Error(\n stopping\n ? `${snapId} was stopped and the request was cancelled. This is likely because the Snap crashed.`\n : `${snapId} failed to respond to the request in time.`,\n );\n }\n\n await this.#assertSnapRpcResponse(snapId, handlerType, result);\n\n const transformedResult = await this.#transformSnapRpcResponse(\n snapId,\n handlerType,\n transformedRequest,\n result,\n );\n\n this.#recordSnapRpcRequestFinish(\n snapId,\n transformedRequest.id,\n handlerType,\n origin,\n true,\n );\n\n return transformedResult;\n } catch (error) {\n // We flag the RPC request as finished early since termination may affect pending requests\n this.#recordSnapRpcRequestFinish(\n snapId,\n transformedRequest.id,\n handlerType,\n origin,\n false,\n );\n\n const [jsonRpcError, handled] = unwrapError(error);\n\n if (!handled) {\n logError(\n `\"${snapId}\" crashed due to an unhandled error:`,\n jsonRpcError,\n );\n await this.stopSnap(snapId, SnapStatusEvents.Crash);\n }\n\n throw jsonRpcError;\n }\n }\n\n /**\n * Determine the execution timeout for a given handler permission.\n *\n * If no permission is specified or the permission itself has no execution timeout defined\n * the constructor argument `maxRequestTime` will be used.\n *\n * @param permission - An optional permission constraint for the handler being called.\n * @returns The execution timeout for the given handler.\n */\n #getExecutionTimeout(permission?: PermissionConstraint): number {\n return getMaxRequestTimeCaveat(permission) ?? this.maxRequestTime;\n }\n\n /**\n * Create a dynamic interface in the SnapInterfaceController.\n *\n * @param snapId - The snap ID.\n * @param content - The initial interface content.\n * @param contentType - The type of content.\n * @returns An identifier that can be used to identify the interface.\n */\n async #createInterface(\n snapId: SnapId,\n content: ComponentOrElement,\n contentType?: ContentType,\n ): Promise<string> {\n return this.messagingSystem.call(\n 'SnapInterfaceController:createInterface',\n snapId,\n content,\n undefined,\n contentType,\n );\n }\n\n #assertInterfaceExists(snapId: SnapId, id: string) {\n // This will throw if the interface isn't accessible, but we assert nevertheless.\n assert(\n this.messagingSystem.call(\n 'SnapInterfaceController:getInterface',\n snapId,\n id,\n ),\n );\n }\n\n /**\n * Transform a RPC response if necessary.\n *\n * @param snapId - The snap ID of the snap that produced the result.\n * @param handlerType - The handler type that produced the result.\n * @param request - The request that returned the result.\n * @param result - The response.\n * @returns The transformed result if applicable, otherwise the original result.\n */\n async #transformSnapRpcResponse(\n snapId: SnapId,\n handlerType: HandlerType,\n request: Record<string, unknown>,\n result: unknown,\n ) {\n switch (handlerType) {\n case HandlerType.OnTransaction:\n case HandlerType.OnSignature:\n case HandlerType.OnHomePage:\n case HandlerType.OnSettingsPage: {\n // Since this type has been asserted earlier we can cast\n const castResult = result as Record<string, Json> | null;\n\n // If a handler returns static content, we turn it into a dynamic UI\n if (castResult && hasProperty(castResult, 'content')) {\n const { content, ...rest } = castResult;\n const id = await this.#createInterface(\n snapId,\n content as ComponentOrElement,\n );\n\n return { ...rest, id };\n }\n return result;\n }\n case HandlerType.OnAssetsLookup:\n // We can cast since the request and result have already been validated.\n return this.#transformOnAssetsLookupResult(\n snapId,\n request as { params: OnAssetsLookupArguments },\n result as OnAssetsLookupResponse,\n );\n\n case HandlerType.OnAssetsConversion:\n // We can cast since the request and result have already been validated.\n return this.#transformOnAssetsConversionResult(\n request as {\n params: OnAssetsConversionArguments;\n },\n result as OnAssetsConversionResponse,\n );\n\n case HandlerType.OnAssetsMarketData:\n // We can cast since the request and result have already been validated.\n return this.#transformOnAssetsMarketDataResult(\n request as { params: OnAssetsMarketDataArguments },\n result as OnAssetsMarketDataResponse,\n );\n\n default:\n return result;\n }\n }\n\n /**\n * Transform an RPC response coming from the `onAssetsLookup` handler.\n *\n * This filters out responses that are out of scope for the Snap based on\n * its permissions and the incoming request.\n *\n * @param snapId - The snap ID of the snap that produced the result.\n * @param request - The request that returned the result.\n * @param request.params - The parameters for the request.\n * @param result - The result.\n * @param result.assets - The assets returned by the Snap.\n * @returns The transformed result.\n */\n #transformOnAssetsLookupResult(\n snapId: SnapId,\n { params: requestedParams }: { params: OnAssetsLookupArguments },\n { assets }: OnAssetsLookupResponse,\n ) {\n const permissions = this.messagingSystem.call(\n 'PermissionController:getPermissions',\n snapId,\n );\n // We know the permissions are guaranteed to be set here.\n assert(permissions);\n\n const permission = permissions[SnapEndowments.Assets];\n const scopes = getChainIdsCaveat(permission);\n assert(scopes);\n\n const { assets: requestedAssets } = requestedParams;\n\n const filteredAssets = Object.keys(assets).reduce<\n Record<CaipAssetType, FungibleAssetMetadata | null>\n >((accumulator, assetType) => {\n const castAssetType = assetType as CaipAssetType;\n const isValid =\n scopes.some((scope) => castAssetType.startsWith(scope)) &&\n requestedAssets.includes(castAssetType);\n // Filter out unrequested assets and assets for scopes the Snap hasn't registered for.\n if (isValid) {\n accumulator[castAssetType] = assets[castAssetType];\n }\n return accumulator;\n }, {});\n return { assets: filteredAssets };\n }\n\n /**\n * Transform an RPC response coming from the `onAssetsConversion` handler.\n *\n * This filters out responses that are out of scope for the Snap based on\n * the incoming request.\n *\n * @param request - The request that returned the result.\n * @param request.params - The parameters for the request.\n * @param result - The result.\n * @param result.conversionRates - The conversion rates returned by the Snap.\n * @returns The transformed result.\n */\n #transformOnAssetsConversionResult(\n { params: requestedParams }: { params: OnAssetsConversionArguments },\n { conversionRates }: OnAssetsConversionResponse,\n ) {\n const { conversions: requestedConversions } = requestedParams;\n\n const filteredConversionRates = requestedConversions.reduce<\n Record<CaipAssetType, Record<CaipAssetType, AssetConversion>>\n >((accumulator, conversion) => {\n const rate = conversionRates[conversion.from]?.[conversion.to];\n // Only include rates that were actually requested.\n if (rate) {\n accumulator[conversion.from] ??= {};\n accumulator[conversion.from][conversion.to] = rate;\n }\n return accumulator;\n }, {});\n return { conversionRates: filteredConversionRates };\n }\n\n /**\n * Transforms an RPC response coming from the `onAssetsMarketData` handler.\n *\n * This filters out responses that are out of scope for the Snap based on\n * the incoming request.\n *\n * @param request - The request that returned the result.\n * @param request.params - The parameters for the request.\n * @param result - The result.\n * @param result.marketData - The market data returned by the Snap.\n * @returns The transformed result.\n */\n #transformOnAssetsMarketDataResult(\n { params: requestedParams }: { params: OnAssetsMarketDataArguments },\n { marketData }: OnAssetsMarketDataResponse,\n ) {\n const { assets: requestedAssets } = requestedParams;\n\n const filteredMarketData = requestedAssets.reduce<\n Record<CaipAssetType, Record<CaipAssetType, FungibleAssetMarketData>>\n >((accumulator, assets) => {\n const result = marketData[assets.asset]?.[assets.unit];\n // Only include rates that were actually requested.\n if (result) {\n accumulator[assets.asset] ??= {};\n accumulator[assets.asset][assets.unit] = result;\n }\n return accumulator;\n }, {});\n return { marketData: filteredMarketData };\n }\n\n /**\n * Transforms a JSON-RPC request before sending it to the Snap, if required for a given handler.\n *\n * @param snapId - The Snap ID.\n * @param handlerType - The handler being called.\n * @param request - The JSON-RPC request.\n * @returns The potentially transformed JSON-RPC request.\n */\n #transformSnapRpcRequest(\n snapId: SnapId,\n handlerType: HandlerType,\n request: JsonRpcRequest,\n ) {\n switch (handlerType) {\n // For onUserInput we inject context, so the client doesn't have to worry about keeping it in sync.\n case HandlerType.OnUserInput: {\n assert(request.params && hasProperty(request.params, 'id'));\n\n const interfaceId = request.params.id as string;\n const { context } = this.messagingSystem.call(\n 'SnapInterfaceController:getInterface',\n snapId,\n interfaceId,\n );\n\n return {\n ...request,\n params: { ...request.params, context },\n };\n }\n\n default:\n return request;\n }\n }\n\n /**\n * Assert that the returned result of a Snap RPC call is the expected shape.\n *\n * @param snapId - The snap ID.\n * @param handlerType - The handler type of the RPC Request.\n * @param result - The result of the RPC request.\n */\n async #assertSnapRpcResponse(\n snapId: SnapId,\n handlerType: HandlerType,\n result: unknown,\n ) {\n switch (handlerType) {\n case HandlerType.OnTransaction: {\n assertStruct(result, OnTransactionResponseStruct);\n\n if (result && hasProperty(result, 'id')) {\n this.#assertInterfaceExists(snapId, result.id as string);\n }\n\n break;\n }\n case HandlerType.OnSignature: {\n assertStruct(result, OnSignatureResponseStruct);\n\n if (result && hasProperty(result, 'id')) {\n this.#assertInterfaceExists(snapId, result.id as string);\n }\n\n break;\n }\n case HandlerType.OnHomePage: {\n assertStruct(result, OnHomePageResponseStruct);\n\n if (result && hasProperty(result, 'id')) {\n this.#assertInterfaceExists(snapId, result.id as string);\n }\n\n break;\n }\n case HandlerType.OnSettingsPage: {\n assertStruct(result, OnSettingsPageResponseStruct);\n\n if (result && hasProperty(result, 'id')) {\n this.#assertInterfaceExists(snapId, result.id as string);\n }\n\n break;\n }\n case HandlerType.OnNameLookup:\n assertStruct(result, OnNameLookupResponseStruct);\n break;\n case HandlerType.OnAssetsLookup:\n assertStruct(result, OnAssetsLookupResponseStruct);\n break;\n case HandlerType.OnAssetsConversion:\n assertStruct(result, OnAssetsConversionResponseStruct);\n break;\n case HandlerType.OnAssetHistoricalPrice:\n assertStruct(result, OnAssetHistoricalPriceResponseStruct);\n break;\n case HandlerType.OnAssetsMarketData:\n assertStruct(result, OnAssetsMarketDataResponseStruct);\n break;\n default:\n break;\n }\n }\n\n #recordSnapRpcRequestStart(snapId: SnapId, requestId: unknown, timer: Timer) {\n const runtime = this.#getRuntimeExpect(snapId);\n runtime.pendingInboundRequests.push({ requestId, timer });\n runtime.lastRequest = null;\n }\n\n #recordSnapRpcRequestFinish(\n snapId: SnapId,\n requestId: unknown,\n handlerType: HandlerType,\n origin: string,\n success: boolean,\n ) {\n const runtime = this.#getRuntimeExpect(snapId);\n runtime.pendingInboundRequests = runtime.pendingInboundRequests.filter(\n (request) => request.requestId !== requestId,\n );\n\n if (runtime.pendingInboundRequests.length === 0) {\n runtime.lastRequest = Date.now();\n }\n\n const snap = this.get(snapId);\n\n if (isTrackableHandler(handlerType) && !snap?.preinstalled) {\n try {\n this.#trackSnapExport(snapId, handlerType, success, origin);\n } catch (error) {\n logError(\n `Error when calling MetaMetrics hook for snap \"${snap?.id}\": ${getErrorMessage(\n error,\n )}`,\n );\n }\n }\n }\n\n /**\n * Retrieves the rollback snapshot of a snap.\n *\n * @param snapId - The snap id.\n * @returns A `RollbackSnapshot` or `undefined` if one doesn't exist.\n */\n #getRollbackSnapshot(snapId: SnapId): RollbackSnapshot | undefined {\n return this.#rollbackSnapshots.get(snapId);\n }\n\n /**\n * Creates a `RollbackSnapshot` that is used to help ensure\n * atomicity in multiple snap updates.\n *\n * @param snapId - The snap id.\n * @throws {@link Error}. If the snap exists before creation or if creation fails.\n * @returns A `RollbackSnapshot`.\n */\n #createRollbackSnapshot(snapId: SnapId): RollbackSnapshot {\n assert(\n this.#rollbackSnapshots.get(snapId) === undefined,\n new Error(`Snap \"${snapId}\" rollback snapshot already exists.`),\n );\n\n this.#rollbackSnapshots.set(snapId, {\n statePatches: [],\n permissions: {},\n newVersion: '',\n });\n\n const newRollbackSnapshot = this.#rollbackSnapshots.get(snapId);\n\n assert(\n newRollbackSnapshot !== undefined,\n new Error(`Snapshot creation failed for ${snapId}.`),\n );\n return newRollbackSnapshot;\n }\n\n /**\n * Rolls back a snap to its previous state, permissions\n * and source code based on the `RollbackSnapshot` that\n * is captured during the update process. After rolling back,\n * the function also emits an event indicating that the\n * snap has been rolled back and it clears the snapshot\n * for that snap.\n *\n * @param snapId - The snap id.\n * @throws {@link Error}. If a snapshot does not exist.\n */\n async #rollbackSnap(snapId: SnapId) {\n const rollbackSnapshot = this.#getRollbackSnapshot(snapId);\n if (!rollbackSnapshot) {\n throw new Error('A snapshot does not exist for this snap.');\n }\n\n await this.stopSnap(snapId, SnapStatusEvents.Stop);\n // Always set to stopped even if it wasn't running initially\n if (this.get(snapId)?.status !== SnapStatus.Stopped) {\n this.#transition(snapId, SnapStatusEvents.Stop);\n }\n\n const { statePatches, permissions } = rollbackSnapshot;\n\n if (statePatches?.length) {\n this.applyPatches(statePatches);\n }\n\n // Reset snap status, as we may have been in another state when we stored state patches\n // But now we are 100% in a stopped state\n if (this.get(snapId)?.status !== SnapStatus.Stopped) {\n this.update((state) => {\n state.snaps[snapId].status = SnapStatus.Stopped;\n });\n }\n\n this.#updatePermissions({\n snapId,\n unusedPermissions: permissions.granted,\n newPermissions: permissions.revoked,\n requestData: permissions.requestData,\n });\n\n const truncatedSnap = this.getTruncatedExpect(snapId);\n\n this.messagingSystem.publish(\n 'SnapController:snapRolledback',\n truncatedSnap,\n rollbackSnapshot.newVersion,\n );\n\n this.#rollbackSnapshots.delete(snapId);\n }\n\n /**\n * Iterates through an array of snap ids\n * and calls `rollbackSnap` on them.\n *\n * @param snapIds - An array of snap ids.\n */\n async #rollbackSnaps(snapIds: SnapId[]) {\n for (const snapId of snapIds) {\n await this.#rollbackSnap(snapId);\n }\n }\n\n #getRuntime(snapId: SnapId): SnapRuntimeData | undefined {\n return this.#snapsRuntimeData.get(snapId);\n }\n\n #getRuntimeExpect(snapId: SnapId): SnapRuntimeData {\n const runtime = this.#getRuntime(snapId);\n assert(\n runtime !== undefined,\n new Error(`Snap \"${snapId}\" runtime data not found`),\n );\n return runtime;\n }\n\n #setupRuntime(snapId: SnapId) {\n if (this.#snapsRuntimeData.has(snapId)) {\n return;\n }\n\n const snap = this.get(snapId);\n const interpreter = interpret(this.#statusMachine);\n interpreter.start({\n context: { snapId },\n value:\n snap?.status ??\n (this.#statusMachine.config.initial as StatusStates['value']),\n });\n\n forceStrict(interpreter);\n\n this.#snapsRuntimeData.set(snapId, {\n lastRequest: null,\n startPromise: null,\n stopPromise: null,\n installPromise: null,\n encryptionKey: null,\n encryptionSalt: null,\n activeReferences: 0,\n pendingInboundRequests: [],\n pendingOutboundRequests: 0,\n interpreter,\n stateMutex: new Mutex(),\n getStateMutex: new Mutex(),\n });\n }\n\n #calculatePermissionsChange(\n snapId: SnapId,\n desiredPermissionsSet: Record<\n string,\n Pick<PermissionConstraint, 'caveats'>\n >,\n ): {\n newPermissions: Record<string, Pick<PermissionConstraint, 'caveats'>>;\n unusedPermissions: SubjectPermissions<\n ValidPermission<string, Caveat<string, any>>\n >;\n approvedPermissions: SubjectPermissions<\n ValidPermission<string, Caveat<string, any>>\n >;\n } {\n const oldPermissions =\n this.messagingSystem.call(\n 'PermissionController:getPermissions',\n snapId,\n ) ?? {};\n\n const newPermissions = permissionsDiff(\n desiredPermissionsSet,\n oldPermissions,\n );\n // TODO(ritave): The assumption that these are unused only holds so long as we do not\n // permit dynamic permission requests.\n const unusedPermissions = permissionsDiff(\n oldPermissions,\n desiredPermissionsSet,\n );\n\n // It's a Set Intersection of oldPermissions and desiredPermissionsSet\n // oldPermissions ∖ (oldPermissions ∖ desiredPermissionsSet) ⟺ oldPermissions ∩ desiredPermissionsSet\n const approvedPermissions = permissionsDiff(\n oldPermissions,\n unusedPermissions,\n );\n\n return { newPermissions, unusedPermissions, approvedPermissions };\n }\n\n #isSubjectConnectedToSnap(snapId: SnapId, origin: string) {\n const subjectPermissions = this.messagingSystem.call(\n 'PermissionController:getPermissions',\n origin,\n ) as SubjectPermissions<PermissionConstraint>;\n\n const existingCaveat = subjectPermissions?.[\n WALLET_SNAP_PERMISSION_KEY\n ]?.caveats?.find((caveat) => caveat.type === SnapCaveatType.SnapIds);\n\n return Boolean((existingCaveat?.value as Record<string, Json>)?.[snapId]);\n }\n\n #calculateConnectionsChange(\n snapId: SnapId,\n oldConnectionsSet: Record<string, Json>,\n desiredConnectionsSet: Record<string, Json>,\n ): {\n newConnections: Record<string, Json>;\n unusedConnections: Record<string, Json>;\n approvedConnections: Record<string, Json>;\n } {\n // Filter out any origins that have been revoked since last install/update.\n // That way they will be represented as new.\n const filteredOldConnections = Object.keys(oldConnectionsSet)\n .filter((origin) => this.#isSubjectConnectedToSnap(snapId, origin))\n .reduce<Record<string, Json>>((accumulator, origin) => {\n accumulator[origin] = oldConnectionsSet[origin];\n return accumulator;\n }, {});\n\n const newConnections = setDiff(\n desiredConnectionsSet,\n filteredOldConnections,\n );\n\n const unusedConnections = setDiff(\n filteredOldConnections,\n desiredConnectionsSet,\n );\n\n // It's a Set Intersection of oldConnections and desiredConnectionsSet\n // oldConnections ∖ (oldConnections ∖ desiredConnectionsSet) ⟺ oldConnections ∩ desiredConnectionsSet\n const approvedConnections = setDiff(\n filteredOldConnections,\n unusedConnections,\n );\n\n return { newConnections, unusedConnections, approvedConnections };\n }\n\n /**\n * Get the permissions to grant to a Snap following an install, update or\n * rollback.\n *\n * @param snapId - The snap ID.\n * @param newPermissions - The new permissions to be granted.\n * @returns The permissions to grant to the Snap.\n */\n #getPermissionsToGrant(snapId: SnapId, newPermissions: RequestedPermissions) {\n if (\n this.#featureFlags.useCaip25Permission &&\n Object.keys(newPermissions).includes(SnapEndowments.EthereumProvider)\n ) {\n // This will return the globally selected network if the Snap doesn't have\n // one set.\n const networkClientId = this.messagingSystem.call(\n 'SelectedNetworkController:getNetworkClientIdForDomain',\n snapId,\n );\n\n const { configuration } = this.messagingSystem.call(\n 'NetworkController:getNetworkClientById',\n networkClientId,\n );\n\n const chainId = hexToNumber(configuration.chainId);\n\n // This needs to be assigned to have proper type inference.\n const modifiedPermissions: RequestedPermissions = {\n ...newPermissions,\n 'endowment:caip25': {\n caveats: [\n {\n type: 'authorizedScopes',\n value: {\n requiredScopes: {},\n optionalScopes: {\n [`eip155:${chainId}`]: {\n accounts: [],\n },\n },\n sessionProperties: {},\n isMultichainOrigin: false,\n },\n },\n ],\n },\n };\n\n return modifiedPermissions;\n }\n\n return newPermissions;\n }\n\n /**\n * Update the permissions for a snap following an install, update or rollback.\n *\n * Grants newly requested permissions and revokes unused/revoked permissions.\n *\n * @param args - An options bag.\n * @param args.snapId - The snap ID.\n * @param args.newPermissions - New permissions to be granted.\n * @param args.unusedPermissions - Unused permissions to be revoked.\n * @param args.requestData - Optional request data from an approval.\n */\n #updatePermissions({\n snapId,\n unusedPermissions = {},\n newPermissions = {},\n requestData,\n }: {\n snapId: SnapId;\n newPermissions?:\n | RequestedPermissions\n | Record<string, Pick<PermissionConstraint, 'caveats'>>;\n unusedPermissions?:\n | RequestedPermissions\n | SubjectPermissions<ValidPermission<string, Caveat<string, any>>>;\n requestData?: Record<string, unknown>;\n }) {\n const unusedPermissionsKeys = Object.keys(unusedPermissions);\n if (isNonEmptyArray(unusedPermissionsKeys)) {\n this.messagingSystem.call('PermissionController:revokePermissions', {\n [snapId]: unusedPermissionsKeys,\n });\n }\n\n if (isNonEmptyArray(Object.keys(newPermissions))) {\n const approvedPermissions = this.#getPermissionsToGrant(\n snapId,\n newPermissions,\n );\n\n this.messagingSystem.call('PermissionController:grantPermissions', {\n approvedPermissions,\n subject: { origin: snapId },\n requestData,\n });\n }\n }\n\n /**\n * Checks if a snap will pass version validation checks\n * with the new version range that is requested. The first\n * check that is done is to check if the existing snap version\n * falls inside the requested range. If it does, we want to return\n * false because we do not care to create a rollback snapshot in\n * that scenario. The second check is to ensure that the current\n * snap version is not greater than all possible versions in\n * the requested version range. If it is, then we also want\n * to return false in that scenario.\n *\n * @param snapId - The snap id.\n * @param newVersionRange - The new version range being requested.\n * @returns `true` if validation checks pass and `false` if they do not.\n */\n #isValidUpdate(snapId: SnapId, newVersionRange: SemVerRange): boolean {\n const existingSnap = this.getExpect(snapId);\n\n if (satisfiesVersionRange(existingSnap.version, newVersionRange)) {\n return false;\n }\n\n if (gtRange(existingSnap.version, newVersionRange)) {\n return false;\n }\n\n return true;\n }\n\n /**\n * Call a lifecycle hook on a snap, if the snap has the\n * `endowment:lifecycle-hooks` permission. If the snap does not have the\n * permission, nothing happens.\n *\n * @param origin - The origin.\n * @param snapId - The snap ID.\n * @param handler - The lifecycle hook to call. This should be one of the\n * supported lifecycle hooks.\n * @private\n */\n async #callLifecycleHook(\n origin: string,\n snapId: SnapId,\n handler: HandlerType,\n ) {\n const permissionName = handlerEndowments[handler];\n\n assert(permissionName, 'Lifecycle hook must have an endowment.');\n\n const hasPermission = this.messagingSystem.call(\n 'PermissionController:hasPermission',\n snapId,\n permissionName,\n );\n\n if (!hasPermission) {\n return;\n }\n\n await this.handleRequest({\n snapId,\n handler,\n origin,\n request: {\n jsonrpc: '2.0',\n method: handler,\n },\n });\n }\n\n /**\n * Handle the `KeyringController:lock` event.\n *\n * Currently this clears the cached encrypted state (if any) for all Snaps.\n */\n #handleLock() {\n for (const runtime of this.#snapsRuntimeData.values()) {\n runtime.encryptionKey = null;\n runtime.encryptionSalt = null;\n runtime.state = undefined;\n }\n }\n}\n"]}
1
+ {"version":3,"file":"SnapController.mjs","sourceRoot":"","sources":["../../src/snaps/SnapController.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n AddApprovalRequest,\n UpdateRequestState,\n} from '@metamask/approval-controller';\nimport type {\n RestrictedMessenger,\n ControllerGetStateAction,\n ControllerStateChangeEvent,\n} from '@metamask/base-controller';\nimport { BaseController } from '@metamask/base-controller';\nimport type { CryptographicFunctions } from '@metamask/key-tree';\nimport type {\n Caveat,\n GetEndowments,\n GetPermissions,\n GetSubjectMetadata,\n AddSubjectMetadata,\n GetSubjects,\n GrantPermissions,\n HasPermission,\n HasPermissions,\n PermissionConstraint,\n PermissionsRequest,\n RequestedPermissions,\n RevokeAllPermissions,\n RevokePermissionForAllSubjects,\n RevokePermissions,\n SubjectPermissions,\n UpdateCaveat,\n ValidPermission,\n} from '@metamask/permission-controller';\nimport { SubjectType } from '@metamask/permission-controller';\nimport { rpcErrors } from '@metamask/rpc-errors';\nimport type { BlockReason } from '@metamask/snaps-registry';\nimport {\n WALLET_SNAP_PERMISSION_KEY,\n getMaxRequestTimeCaveat,\n handlerEndowments,\n SnapEndowments,\n getKeyringCaveatOrigins,\n getRpcCaveatOrigins,\n processSnapPermissions,\n getEncryptionEntropy,\n getChainIdsCaveat,\n} from '@metamask/snaps-rpc-methods';\nimport type {\n RequestSnapsParams,\n RequestSnapsResult,\n SnapId,\n ComponentOrElement,\n ContentType,\n OnAssetsLookupResponse,\n OnAssetsConversionResponse,\n OnAssetsConversionArguments,\n AssetConversion,\n OnAssetsLookupArguments,\n OnAssetsMarketDataArguments,\n OnAssetsMarketDataResponse,\n AssetMarketData,\n AssetMetadata,\n} from '@metamask/snaps-sdk';\nimport {\n AuxiliaryFileEncoding,\n getErrorMessage,\n OnAssetsLookupResponseStruct,\n} from '@metamask/snaps-sdk';\nimport type {\n FetchedSnapFiles,\n InitialConnections,\n PersistedSnap,\n Snap,\n SnapManifest,\n SnapPermissions,\n SnapRpcHookArgs,\n StatusContext,\n StatusEvents,\n StatusStates,\n TruncatedSnap,\n TruncatedSnapFields,\n} from '@metamask/snaps-utils';\nimport {\n logWarning,\n getPlatformVersion,\n assertIsSnapManifest,\n assertIsValidSnapId,\n DEFAULT_ENDOWMENTS,\n DEFAULT_REQUESTED_SNAP_VERSION,\n encodeAuxiliaryFile,\n HandlerType,\n isOriginAllowed,\n logError,\n normalizeRelative,\n OnTransactionResponseStruct,\n OnSignatureResponseStruct,\n resolveVersionRange,\n SnapCaveatType,\n SnapStatus,\n SnapStatusEvents,\n unwrapError,\n OnHomePageResponseStruct,\n getValidatedLocalizationFiles,\n VirtualFile,\n NpmSnapFileNames,\n OnNameLookupResponseStruct,\n getLocalizedSnapManifest,\n MAX_FILE_SIZE,\n OnSettingsPageResponseStruct,\n isValidUrl,\n OnAssetHistoricalPriceResponseStruct,\n OnAssetsConversionResponseStruct,\n OnAssetsMarketDataResponseStruct,\n} from '@metamask/snaps-utils';\nimport type {\n Json,\n NonEmptyArray,\n SemVerRange,\n CaipAssetType,\n JsonRpcRequest,\n Hex,\n SemVerVersion,\n CaipAssetTypeOrId,\n} from '@metamask/utils';\nimport {\n hexToNumber,\n assert,\n assertIsJsonRpcRequest,\n assertStruct,\n Duration,\n gtRange,\n gtVersion,\n hasProperty,\n inMilliseconds,\n isNonEmptyArray,\n isValidSemVerRange,\n satisfiesVersionRange,\n timeSince,\n createDeferredPromise,\n} from '@metamask/utils';\nimport type { StateMachine } from '@xstate/fsm';\nimport { createMachine, interpret } from '@xstate/fsm';\nimport { Mutex } from 'async-mutex';\nimport type { Patch } from 'immer';\nimport { nanoid } from 'nanoid';\nimport { gt, gte } from 'semver';\n\nimport {\n ALLOWED_PERMISSIONS,\n CLIENT_ONLY_HANDLERS,\n LEGACY_ENCRYPTION_KEY_DERIVATION_OPTIONS,\n METAMASK_ORIGIN,\n STATE_DEBOUNCE_TIMEOUT,\n} from './constants';\nimport type { SnapLocation } from './location';\nimport { detectSnapLocation } from './location';\nimport type {\n GetMetadata,\n GetResult,\n ResolveVersion,\n SnapsRegistryInfo,\n SnapsRegistryRequest,\n Update,\n} from './registry';\nimport { SnapsRegistryStatus } from './registry';\nimport { getRunnableSnaps } from './selectors';\nimport { Timer } from './Timer';\nimport { forceStrict, validateMachine } from '../fsm';\nimport type { CreateInterface, GetInterface } from '../interface';\nimport { log } from '../logging';\nimport type {\n ExecuteSnapAction,\n ExecutionServiceEvents,\n HandleRpcRequestAction,\n SnapErrorJson,\n TerminateAllSnapsAction,\n TerminateSnapAction,\n} from '../services';\nimport type {\n EncryptionResult,\n ExportableKeyEncryptor,\n KeyDerivationOptions,\n} from '../types';\nimport {\n debouncePersistState,\n fetchSnap,\n hasTimedOut,\n permissionsDiff,\n setDiff,\n throttleTracking,\n withTimeout,\n isTrackableHandler,\n isLocalSnapId,\n} from '../utils';\n\nexport const controllerName = 'SnapController';\n\n// TODO: Figure out how to name these\nexport const SNAP_APPROVAL_INSTALL = 'wallet_installSnap';\nexport const SNAP_APPROVAL_UPDATE = 'wallet_updateSnap';\nexport const SNAP_APPROVAL_RESULT = 'wallet_installSnapResult';\n\nconst TRUNCATED_SNAP_PROPERTIES = new Set<TruncatedSnapFields>([\n 'initialPermissions',\n 'id',\n 'version',\n 'enabled',\n 'blocked',\n]);\n\nexport type PendingRequest = {\n requestId: unknown;\n timer: Timer;\n};\n\nexport type PreinstalledSnapFile = {\n path: string;\n value: string | Uint8Array;\n};\n\nexport type PreinstalledSnap = {\n snapId: SnapId;\n manifest: SnapManifest;\n files: PreinstalledSnapFile[];\n removable?: boolean;\n hidden?: boolean;\n hideSnapBranding?: boolean;\n};\n\n/**\n * A wrapper type for any data stored during runtime of Snaps.\n * It is not persisted in state as it contains non-serializable data and is only relevant for the\n * current session.\n */\nexport type SnapRuntimeData = {\n /**\n * A promise that resolves when the Snap has finished installing\n */\n installPromise: null | Promise<PersistedSnap>;\n\n /**\n * A promise that resolves when the Snap has finished booting\n */\n startPromise: null | Promise<void>;\n\n /**\n * A promise that resolves when the Snap has finished stopping\n */\n stopPromise: null | Promise<void>;\n\n /**\n * A Unix timestamp for the last time the Snap received an RPC request\n */\n lastRequest: null | number;\n\n /**\n * The current number of active references where this Snap is being used\n */\n activeReferences: number;\n\n /**\n * The current pending inbound requests, meaning requests that are processed by snaps.\n */\n pendingInboundRequests: PendingRequest[];\n\n /**\n * The current pending outbound requests, meaning requests made from snaps towards the MetaMask\n * extension.\n */\n pendingOutboundRequests: number;\n\n /**\n * The finite state machine interpreter for possible states that the Snap can be in such as\n * stopped, running, blocked\n *\n * @see {@link SnapController:constructor}\n */\n interpreter: StateMachine.Service<StatusContext, StatusEvents, StatusStates>;\n\n /**\n * Cached encryption key used for state encryption.\n */\n encryptionKey: string | null;\n\n /**\n * Cached encryption salt used for state encryption.\n */\n encryptionSalt: string | null;\n\n /**\n * Cached encrypted state of the Snap.\n */\n state?: Record<string, Json> | null;\n\n /**\n * Cached unencrypted state of the Snap.\n */\n unencryptedState?: Record<string, Json> | null;\n\n /**\n * A mutex to prevent concurrent state updates.\n */\n stateMutex: Mutex;\n\n /**\n * A mutex to prevent concurrent state decryption.\n */\n getStateMutex: Mutex;\n};\n\nexport type SnapError = {\n message: string;\n code: number;\n data?: Json;\n};\n\n// Types that probably should be defined elsewhere in prod\ntype CloseAllConnectionsFunction = (origin: string) => void;\ntype StoredSnaps = Record<SnapId, Snap>;\n\nexport type SnapControllerState = {\n snaps: StoredSnaps;\n snapStates: Record<SnapId, string | null>;\n unencryptedSnapStates: Record<SnapId, string | null>;\n};\n\nexport type PersistedSnapControllerState = SnapControllerState & {\n snaps: Record<SnapId, PersistedSnap>;\n snapStates: Record<SnapId, string>;\n};\n\ntype RollbackSnapshot = {\n statePatches: Patch[];\n permissions: {\n revoked?: SubjectPermissions<ValidPermission<string, Caveat<string, any>>>;\n granted?: RequestedPermissions;\n requestData?: Record<string, unknown>;\n };\n newVersion: string;\n};\n\ntype PendingApproval = {\n id: string;\n promise: Promise<unknown>;\n};\n\n// Controller Messenger Actions\n\n/**\n * Initialise the SnapController. This should be called after all controllers\n * are created.\n */\nexport type SnapControllerInitAction = {\n type: `${typeof controllerName}:init`;\n handler: SnapController['init'];\n};\n\n/**\n * Gets the specified Snap from state.\n */\nexport type GetSnap = {\n type: `${typeof controllerName}:get`;\n handler: SnapController['get'];\n};\n\n/**\n * Handles sending an inbound request to a snap and returns its result.\n */\nexport type HandleSnapRequest = {\n type: `${typeof controllerName}:handleRequest`;\n handler: SnapController['handleRequest'];\n};\n\n/**\n * Gets the specified Snap's persisted state.\n */\nexport type GetSnapState = {\n type: `${typeof controllerName}:getSnapState`;\n handler: SnapController['getSnapState'];\n};\n\n/**\n * Checks if the specified snap exists in state.\n */\nexport type HasSnap = {\n type: `${typeof controllerName}:has`;\n handler: SnapController['has'];\n};\n\n/**\n * Updates the specified Snap's persisted state.\n */\nexport type UpdateSnapState = {\n type: `${typeof controllerName}:updateSnapState`;\n handler: SnapController['updateSnapState'];\n};\n\n/**\n * Clears the specified Snap's persisted state.\n */\nexport type ClearSnapState = {\n type: `${typeof controllerName}:clearSnapState`;\n handler: SnapController['clearSnapState'];\n};\n\n/**\n * Checks all installed snaps against the blocklist.\n */\nexport type UpdateBlockedSnaps = {\n type: `${typeof controllerName}:updateBlockedSnaps`;\n handler: SnapController['updateBlockedSnaps'];\n};\n\nexport type EnableSnap = {\n type: `${typeof controllerName}:enable`;\n handler: SnapController['enableSnap'];\n};\n\nexport type DisableSnap = {\n type: `${typeof controllerName}:disable`;\n handler: SnapController['disableSnap'];\n};\n\nexport type RemoveSnap = {\n type: `${typeof controllerName}:remove`;\n handler: SnapController['removeSnap'];\n};\n\nexport type GetPermittedSnaps = {\n type: `${typeof controllerName}:getPermitted`;\n handler: SnapController['getPermittedSnaps'];\n};\n\nexport type GetAllSnaps = {\n type: `${typeof controllerName}:getAll`;\n handler: SnapController['getAllSnaps'];\n};\n\nexport type GetRunnableSnaps = {\n type: `${typeof controllerName}:getRunnableSnaps`;\n handler: SnapController['getRunnableSnaps'];\n};\n\nexport type StopAllSnaps = {\n type: `${typeof controllerName}:stopAllSnaps`;\n handler: SnapController['stopAllSnaps'];\n};\n\nexport type IncrementActiveReferences = {\n type: `${typeof controllerName}:incrementActiveReferences`;\n handler: SnapController['incrementActiveReferences'];\n};\n\nexport type DecrementActiveReferences = {\n type: `${typeof controllerName}:decrementActiveReferences`;\n handler: SnapController['decrementActiveReferences'];\n};\n\nexport type InstallSnaps = {\n type: `${typeof controllerName}:install`;\n handler: SnapController['installSnaps'];\n};\n\nexport type DisconnectOrigin = {\n type: `${typeof controllerName}:disconnectOrigin`;\n handler: SnapController['removeSnapFromSubject'];\n};\n\nexport type RevokeDynamicPermissions = {\n type: `${typeof controllerName}:revokeDynamicPermissions`;\n handler: SnapController['revokeDynamicSnapPermissions'];\n};\n\nexport type GetSnapFile = {\n type: `${typeof controllerName}:getFile`;\n handler: SnapController['getSnapFile'];\n};\n\nexport type IsMinimumPlatformVersion = {\n type: `${typeof controllerName}:isMinimumPlatformVersion`;\n handler: SnapController['isMinimumPlatformVersion'];\n};\n\nexport type SetClientActive = {\n type: `${typeof controllerName}:setClientActive`;\n handler: SnapController['setClientActive'];\n};\n\nexport type SnapControllerGetStateAction = ControllerGetStateAction<\n typeof controllerName,\n SnapControllerState\n>;\n\nexport type SnapControllerActions =\n | SnapControllerInitAction\n | ClearSnapState\n | GetSnap\n | GetSnapState\n | HandleSnapRequest\n | HasSnap\n | UpdateBlockedSnaps\n | UpdateSnapState\n | EnableSnap\n | DisableSnap\n | RemoveSnap\n | GetPermittedSnaps\n | InstallSnaps\n | GetAllSnaps\n | GetRunnableSnaps\n | IncrementActiveReferences\n | DecrementActiveReferences\n | DisconnectOrigin\n | RevokeDynamicPermissions\n | GetSnapFile\n | SnapControllerGetStateAction\n | StopAllSnaps\n | IsMinimumPlatformVersion\n | SetClientActive;\n\n// Controller Messenger Events\n\nexport type SnapStateChange = {\n type: `${typeof controllerName}:stateChange`;\n payload: [SnapControllerState, Patch[]];\n};\n\n/**\n * Emitted when an installed snap has been blocked.\n */\nexport type SnapBlocked = {\n type: `${typeof controllerName}:snapBlocked`;\n payload: [snapId: string, blockedSnapInfo?: BlockReason];\n};\n\n/**\n * Emitted when a snap installation or update is started.\n */\nexport type SnapInstallStarted = {\n type: `${typeof controllerName}:snapInstallStarted`;\n payload: [snapId: SnapId, origin: string, isUpdate: boolean];\n};\n\n/**\n * Emitted when a snap installation or update failed.\n */\nexport type SnapInstallFailed = {\n type: `${typeof controllerName}:snapInstallFailed`;\n payload: [snapId: SnapId, origin: string, isUpdate: boolean, error: string];\n};\n\n/**\n * Emitted when a snap has been started after being added and authorized during\n * installation.\n */\nexport type SnapInstalled = {\n type: `${typeof controllerName}:snapInstalled`;\n payload: [snap: TruncatedSnap, origin: string, preinstalled: boolean];\n};\n\n/**\n * Emitted when a snap that has previously been fully installed, is uninstalled.\n */\nexport type SnapUninstalled = {\n type: `${typeof controllerName}:snapUninstalled`;\n payload: [snap: TruncatedSnap];\n};\n\n/**\n * Emitted when an installed snap has been unblocked.\n */\nexport type SnapUnblocked = {\n type: `${typeof controllerName}:snapUnblocked`;\n payload: [snapId: string];\n};\n\n/**\n * Emitted when a snap is updated.\n */\nexport type SnapUpdated = {\n type: `${typeof controllerName}:snapUpdated`;\n payload: [\n snap: TruncatedSnap,\n oldVersion: string,\n origin: string,\n preinstalled: boolean,\n ];\n};\n\n/**\n * Emitted when a snap is rolled back.\n */\nexport type SnapRolledback = {\n type: `${typeof controllerName}:snapRolledback`;\n payload: [snap: TruncatedSnap, failedVersion: string];\n};\n\n/**\n * Emitted when a Snap is terminated. This is different from the snap being\n * stopped as it can also be triggered when a snap fails initialization.\n */\nexport type SnapTerminated = {\n type: `${typeof controllerName}:snapTerminated`;\n payload: [snap: TruncatedSnap];\n};\n\n/**\n * Emitted when a Snap is enabled by a user.\n * This is not emitted by default when installing a snap.\n */\nexport type SnapEnabled = {\n type: `${typeof controllerName}:snapEnabled`;\n payload: [snap: TruncatedSnap];\n};\n\n/**\n * Emitted when a Snap is disabled by a user.\n */\nexport type SnapDisabled = {\n type: `${typeof controllerName}:snapDisabled`;\n payload: [snap: TruncatedSnap];\n};\n\n/**\n * Emitted when there is a state change.\n */\nexport type SnapControllerStateChangeEvent = ControllerStateChangeEvent<\n typeof controllerName,\n SnapControllerState\n>;\n\ntype KeyringControllerLock = {\n type: 'KeyringController:lock';\n payload: [];\n};\n\nexport type SnapControllerEvents =\n | SnapBlocked\n | SnapInstalled\n | SnapUninstalled\n | SnapInstallStarted\n | SnapInstallFailed\n | SnapStateChange\n | SnapUnblocked\n | SnapUpdated\n | SnapRolledback\n | SnapTerminated\n | SnapEnabled\n | SnapDisabled\n | SnapControllerStateChangeEvent;\n\ntype NetworkControllerGetNetworkClientById = {\n type: `NetworkController:getNetworkClientById`;\n handler: (customNetworkClientId: string) => {\n configuration: {\n chainId: Hex;\n };\n };\n};\n\ntype SelectedNetworkControllerGetNetworkClientIdForDomain = {\n type: `SelectedNetworkController:getNetworkClientIdForDomain`;\n handler: (domain: string) => string;\n};\n\nexport type AllowedActions =\n | GetEndowments\n | GetPermissions\n | GetSubjects\n | GetSubjectMetadata\n | AddSubjectMetadata\n | HasPermission\n | HasPermissions\n | RevokePermissions\n | RevokeAllPermissions\n | RevokePermissionForAllSubjects\n | GrantPermissions\n | AddApprovalRequest\n | HandleRpcRequestAction\n | ExecuteSnapAction\n | TerminateAllSnapsAction\n | TerminateSnapAction\n | UpdateCaveat\n | UpdateRequestState\n | GetResult\n | GetMetadata\n | Update\n | ResolveVersion\n | CreateInterface\n | GetInterface\n | NetworkControllerGetNetworkClientById\n | SelectedNetworkControllerGetNetworkClientIdForDomain;\n\nexport type AllowedEvents =\n | ExecutionServiceEvents\n | SnapInstalled\n | SnapUpdated\n | KeyringControllerLock;\n\ntype SnapControllerMessenger = RestrictedMessenger<\n typeof controllerName,\n SnapControllerActions | AllowedActions,\n SnapControllerEvents | AllowedEvents,\n AllowedActions['type'],\n AllowedEvents['type']\n>;\n\ntype FeatureFlags = {\n requireAllowlist?: boolean;\n allowLocalSnaps?: boolean;\n disableSnapInstallation?: boolean;\n rejectInvalidPlatformVersion?: boolean;\n useCaip25Permission?: boolean;\n\n /**\n * Force any local Snap to be treated as a preinstalled Snap.\n *\n * This should only be used for local testing, and should not be enabled in\n * any production builds (including beta and Flask).\n */\n forcePreinstalledSnaps?: boolean;\n};\n\ntype DynamicFeatureFlags = {\n disableSnaps?: boolean;\n};\n\ntype SnapControllerArgs = {\n /**\n * A teardown function that allows the host to clean up its instrumentation\n * for a running snap.\n */\n closeAllConnections?: CloseAllConnectionsFunction;\n\n /**\n * A list of permissions that are allowed to be dynamic, meaning they can be revoked from the snap whenever.\n */\n dynamicPermissions?: string[];\n\n /**\n * The names of endowment permissions whose values are the names of JavaScript\n * APIs that will be added to the snap execution environment at runtime.\n */\n environmentEndowmentPermissions?: string[];\n\n /**\n * Excluded permissions with its associated error message used to forbid certain permissions.\n */\n excludedPermissions?: Record<string, string>;\n\n /**\n * The function that will be used by the controller fo make network requests.\n * Should be compatible with {@link fetch}.\n */\n fetchFunction?: typeof fetch;\n\n /**\n * Flags that enable or disable features in the controller.\n * See {@link FeatureFlags}.\n */\n featureFlags: FeatureFlags;\n\n /**\n * How frequently to check whether a snap is idle.\n */\n idleTimeCheckInterval?: number;\n\n /**\n * The maximum amount of time that a snap may be idle.\n */\n maxIdleTime?: number;\n\n /**\n * The controller messenger.\n */\n messenger: SnapControllerMessenger;\n\n /**\n * The maximum amount of time a snap may take to process an RPC request,\n * unless it is permitted to take longer.\n */\n maxRequestTime?: number;\n\n /**\n * The npm registry URL that will be used to fetch published snaps.\n */\n npmRegistryUrl?: string;\n\n /**\n * Persisted state that will be used for rehydration.\n */\n state?: PersistedSnapControllerState;\n\n /**\n * A function that takes Snap Id and converts it into a class that fetches files.\n *\n * Used for test overrides.\n */\n detectSnapLocation?: typeof detectSnapLocation;\n\n /**\n * A list of snaps to be preinstalled into the SnapController state on initialization.\n */\n preinstalledSnaps?: PreinstalledSnap[] | null;\n\n /**\n * A utility object containing functions required for state encryption.\n */\n encryptor: ExportableKeyEncryptor;\n\n /**\n * A hook to access the mnemonic seed of the user's primary keyring.\n *\n * @returns The mnemonic seed as bytes.\n */\n getMnemonicSeed: () => Promise<Uint8Array>;\n\n /**\n * A hook to get dynamic feature flags at runtime.\n *\n * @returns The feature flags.\n */\n getFeatureFlags: () => DynamicFeatureFlags;\n\n /**\n * The cryptographic functions to use for the client. This may be an empty\n * object to fall back to the default cryptographic functions.\n */\n clientCryptography?: CryptographicFunctions;\n\n /**\n * MetaMetrics event tracking hook.\n */\n trackEvent: TrackEventHook;\n};\n\ntype AddSnapArgs = {\n id: SnapId;\n origin: string;\n location: SnapLocation;\n versionRange: SemVerRange;\n};\n\n// When we set a snap, we need all required properties to be present and\n// validated.\ntype SetSnapArgs = Omit<AddSnapArgs, 'location' | 'versionRange'> & {\n files: FetchedSnapFiles;\n isUpdate?: boolean;\n removable?: boolean;\n preinstalled?: boolean;\n hidden?: boolean;\n hideSnapBranding?: boolean;\n};\n\ntype TrackingEventPayload = {\n event: string;\n category: string;\n properties: Record<string, Json | undefined>;\n};\n\ntype TrackEventHook = (event: TrackingEventPayload) => void;\n\nconst defaultState: SnapControllerState = {\n snaps: {},\n snapStates: {},\n unencryptedSnapStates: {},\n};\n\n/**\n * Truncates the properties of a snap to only ones that are easily serializable.\n *\n * @param snap - The snap to truncate.\n * @returns Object with serializable snap properties.\n */\nfunction truncateSnap(snap: Snap): TruncatedSnap {\n const truncatedSnap = Object.keys(snap).reduce<Partial<TruncatedSnap>>(\n (serialized, key) => {\n if (TRUNCATED_SNAP_PROPERTIES.has(key as any)) {\n serialized[key as keyof TruncatedSnap] = snap[\n key as keyof TruncatedSnap\n ] as any;\n }\n\n return serialized;\n },\n {},\n );\n\n return truncatedSnap as TruncatedSnap;\n}\n\n/*\n * A snap is initialized in three phases:\n * - Add: Loads the snap from a remote source and parses it.\n * - Authorize: Requests the snap's required permissions from the user.\n * - Start: Initializes the snap in its SES realm with the authorized permissions.\n */\n\nexport class SnapController extends BaseController<\n typeof controllerName,\n SnapControllerState,\n SnapControllerMessenger\n> {\n readonly #closeAllConnections?: CloseAllConnectionsFunction;\n\n readonly #dynamicPermissions: string[];\n\n readonly #environmentEndowmentPermissions: string[];\n\n readonly #excludedPermissions: Record<string, string>;\n\n readonly #featureFlags: FeatureFlags;\n\n readonly #fetchFunction: typeof fetch;\n\n readonly #idleTimeCheckInterval: number;\n\n readonly #maxIdleTime: number;\n\n // This property cannot be hash private yet because of tests.\n // eslint-disable-next-line no-restricted-syntax\n private readonly maxRequestTime: number;\n\n readonly #encryptor: ExportableKeyEncryptor;\n\n readonly #getMnemonicSeed: () => Promise<Uint8Array>;\n\n readonly #getFeatureFlags: () => DynamicFeatureFlags;\n\n readonly #clientCryptography: CryptographicFunctions | undefined;\n\n readonly #detectSnapLocation: typeof detectSnapLocation;\n\n readonly #snapsRuntimeData: Map<SnapId, SnapRuntimeData>;\n\n readonly #rollbackSnapshots: Map<string, RollbackSnapshot>;\n\n #timeoutForLastRequestStatus?: number;\n\n #statusMachine!: StateMachine.Machine<\n StatusContext,\n StatusEvents,\n StatusStates\n >;\n\n readonly #preinstalledSnaps: PreinstalledSnap[] | null;\n\n readonly #trackEvent: TrackEventHook;\n\n readonly #trackSnapExport: ReturnType<typeof throttleTracking>;\n\n constructor({\n closeAllConnections,\n messenger,\n state,\n dynamicPermissions = ['eth_accounts'],\n environmentEndowmentPermissions = [],\n excludedPermissions = {},\n idleTimeCheckInterval = inMilliseconds(5, Duration.Second),\n maxIdleTime = inMilliseconds(30, Duration.Second),\n maxRequestTime = inMilliseconds(60, Duration.Second),\n fetchFunction = globalThis.fetch.bind(undefined),\n featureFlags = {},\n detectSnapLocation: detectSnapLocationFunction = detectSnapLocation,\n preinstalledSnaps = null,\n encryptor,\n getMnemonicSeed,\n getFeatureFlags = () => ({}),\n clientCryptography,\n trackEvent,\n }: SnapControllerArgs) {\n super({\n messenger,\n metadata: {\n snapStates: {\n persist: true,\n anonymous: false,\n },\n unencryptedSnapStates: {\n persist: true,\n anonymous: false,\n },\n snaps: {\n persist: (snaps) => {\n return (\n Object.values(snaps)\n // We should not persist snaps that are in the installing state,\n // since they haven't completed installation and would be unusable\n .filter((snap) => snap.status !== SnapStatus.Installing)\n .map((snap) => {\n return {\n ...snap,\n // At the time state is rehydrated, no snap will be running.\n status: SnapStatus.Stopped,\n };\n })\n .reduce((memo: Record<SnapId, Snap>, snap) => {\n memo[snap.id] = snap;\n return memo;\n }, {})\n );\n },\n anonymous: false,\n },\n },\n name: controllerName,\n state: {\n ...defaultState,\n ...state,\n },\n });\n\n this.#closeAllConnections = closeAllConnections;\n this.#dynamicPermissions = dynamicPermissions;\n this.#environmentEndowmentPermissions = environmentEndowmentPermissions;\n this.#excludedPermissions = excludedPermissions;\n this.#featureFlags = featureFlags;\n this.#fetchFunction = fetchFunction;\n this.#idleTimeCheckInterval = idleTimeCheckInterval;\n this.#maxIdleTime = maxIdleTime;\n this.maxRequestTime = maxRequestTime;\n this.#detectSnapLocation = detectSnapLocationFunction;\n this.#encryptor = encryptor;\n this.#getMnemonicSeed = getMnemonicSeed;\n this.#getFeatureFlags = getFeatureFlags;\n this.#clientCryptography = clientCryptography;\n this.#preinstalledSnaps = preinstalledSnaps;\n this._onUnhandledSnapError = this._onUnhandledSnapError.bind(this);\n this._onOutboundRequest = this._onOutboundRequest.bind(this);\n this._onOutboundResponse = this._onOutboundResponse.bind(this);\n this.#rollbackSnapshots = new Map();\n this.#snapsRuntimeData = new Map();\n this.#trackEvent = trackEvent;\n\n this.#pollForLastRequestStatus();\n\n /* eslint-disable @typescript-eslint/unbound-method */\n this.messagingSystem.subscribe(\n 'ExecutionService:unhandledError',\n this._onUnhandledSnapError,\n );\n\n this.messagingSystem.subscribe(\n 'ExecutionService:outboundRequest',\n this._onOutboundRequest,\n );\n\n this.messagingSystem.subscribe(\n 'ExecutionService:outboundResponse',\n this._onOutboundResponse,\n );\n /* eslint-enable @typescript-eslint/unbound-method */\n\n this.messagingSystem.subscribe(\n 'SnapController:snapInstalled',\n ({ id }, origin) => {\n this.#callLifecycleHook(origin, id, HandlerType.OnInstall).catch(\n (error) => {\n logError(\n `Error when calling \\`onInstall\\` lifecycle hook for snap \"${id}\": ${getErrorMessage(\n error,\n )}`,\n );\n },\n );\n },\n );\n\n this.messagingSystem.subscribe(\n 'SnapController:snapUpdated',\n ({ id }, _oldVersion, origin) => {\n this.#callLifecycleHook(origin, id, HandlerType.OnUpdate).catch(\n (error) => {\n logError(\n `Error when calling \\`onUpdate\\` lifecycle hook for snap \"${id}\": ${getErrorMessage(\n error,\n )}`,\n );\n },\n );\n },\n );\n\n this.messagingSystem.subscribe(\n 'KeyringController:lock',\n this.#handleLock.bind(this),\n );\n\n this.#initializeStateMachine();\n this.#registerMessageHandlers();\n\n Object.values(this.state?.snaps ?? {}).forEach((snap) =>\n this.#setupRuntime(snap.id),\n );\n\n if (this.#preinstalledSnaps) {\n this.#handlePreinstalledSnaps(this.#preinstalledSnaps);\n }\n\n this.#trackSnapExport = throttleTracking(\n (snapId: SnapId, handler: string, success: boolean, origin: string) => {\n const snapMetadata = this.messagingSystem.call(\n 'SnapsRegistry:getMetadata',\n snapId,\n );\n this.#trackEvent({\n event: 'Snap Export Used',\n category: 'Snaps',\n properties: {\n // eslint-disable-next-line @typescript-eslint/naming-convention\n snap_id: snapId,\n export: handler,\n // eslint-disable-next-line @typescript-eslint/naming-convention\n snap_category: snapMetadata?.category,\n success,\n origin,\n },\n });\n },\n );\n }\n\n /**\n * We track status of a Snap using a finite-state-machine.\n * It keeps track of whether the snap is started / stopped / etc.\n *\n * @see {@link SnapController.transition} for interacting with the machine.\n */\n // We initialize the machine in the instance because the status is currently tightly coupled\n // with the SnapController - the guard checks for enabled status inside the SnapController state.\n // In the future, side-effects could be added to the machine during transitions.\n #initializeStateMachine() {\n const disableGuard = ({ snapId }: StatusContext) => {\n return this.getExpect(snapId).enabled;\n };\n\n const statusConfig: StateMachine.Config<\n StatusContext,\n StatusEvents,\n StatusStates\n > = {\n initial: SnapStatus.Installing,\n states: {\n [SnapStatus.Installing]: {\n on: {\n [SnapStatusEvents.Start]: {\n target: SnapStatus.Running,\n cond: disableGuard,\n },\n },\n },\n [SnapStatus.Updating]: {\n on: {\n [SnapStatusEvents.Start]: {\n target: SnapStatus.Running,\n cond: disableGuard,\n },\n [SnapStatusEvents.Stop]: SnapStatus.Stopped,\n },\n },\n [SnapStatus.Running]: {\n on: {\n [SnapStatusEvents.Stop]: SnapStatus.Stopped,\n [SnapStatusEvents.Crash]: SnapStatus.Crashed,\n },\n },\n [SnapStatus.Stopped]: {\n on: {\n [SnapStatusEvents.Start]: {\n target: SnapStatus.Running,\n cond: disableGuard,\n },\n [SnapStatusEvents.Update]: SnapStatus.Updating,\n },\n },\n [SnapStatus.Crashed]: {\n on: {\n [SnapStatusEvents.Start]: {\n target: SnapStatus.Running,\n cond: disableGuard,\n },\n [SnapStatusEvents.Update]: SnapStatus.Updating,\n },\n },\n },\n };\n this.#statusMachine = createMachine(statusConfig);\n validateMachine(this.#statusMachine);\n }\n\n /**\n * Constructor helper for registering the controller's messaging system\n * actions.\n */\n #registerMessageHandlers(): void {\n this.messagingSystem.registerActionHandler(\n `${controllerName}:init`,\n (...args) => this.init(...args),\n );\n\n this.messagingSystem.registerActionHandler(\n `${controllerName}:clearSnapState`,\n (...args) => this.clearSnapState(...args),\n );\n\n this.messagingSystem.registerActionHandler(\n `${controllerName}:get`,\n (...args) => this.get(...args),\n );\n\n this.messagingSystem.registerActionHandler(\n `${controllerName}:getSnapState`,\n async (...args) => this.getSnapState(...args),\n );\n\n this.messagingSystem.registerActionHandler(\n `${controllerName}:handleRequest`,\n async (...args) => this.handleRequest(...args),\n );\n\n this.messagingSystem.registerActionHandler(\n `${controllerName}:has`,\n (...args) => this.has(...args),\n );\n\n this.messagingSystem.registerActionHandler(\n `${controllerName}:updateBlockedSnaps`,\n async () => this.updateBlockedSnaps(),\n );\n\n this.messagingSystem.registerActionHandler(\n `${controllerName}:updateSnapState`,\n async (...args) => this.updateSnapState(...args),\n );\n\n this.messagingSystem.registerActionHandler(\n `${controllerName}:enable`,\n (...args) => this.enableSnap(...args),\n );\n\n this.messagingSystem.registerActionHandler(\n `${controllerName}:disable`,\n async (...args) => this.disableSnap(...args),\n );\n\n this.messagingSystem.registerActionHandler(\n `${controllerName}:remove`,\n async (...args) => this.removeSnap(...args),\n );\n\n this.messagingSystem.registerActionHandler(\n `${controllerName}:getPermitted`,\n (...args) => this.getPermittedSnaps(...args),\n );\n\n this.messagingSystem.registerActionHandler(\n `${controllerName}:install`,\n async (...args) => this.installSnaps(...args),\n );\n\n this.messagingSystem.registerActionHandler(\n `${controllerName}:getAll`,\n (...args) => this.getAllSnaps(...args),\n );\n\n this.messagingSystem.registerActionHandler(\n `${controllerName}:getRunnableSnaps`,\n (...args) => this.getRunnableSnaps(...args),\n );\n\n this.messagingSystem.registerActionHandler(\n `${controllerName}:incrementActiveReferences`,\n (...args) => this.incrementActiveReferences(...args),\n );\n\n this.messagingSystem.registerActionHandler(\n `${controllerName}:decrementActiveReferences`,\n (...args) => this.decrementActiveReferences(...args),\n );\n\n this.messagingSystem.registerActionHandler(\n `${controllerName}:disconnectOrigin`,\n (...args) => this.removeSnapFromSubject(...args),\n );\n\n this.messagingSystem.registerActionHandler(\n `${controllerName}:revokeDynamicPermissions`,\n (...args) => this.revokeDynamicSnapPermissions(...args),\n );\n\n this.messagingSystem.registerActionHandler(\n `${controllerName}:getFile`,\n async (...args) => this.getSnapFile(...args),\n );\n\n this.messagingSystem.registerActionHandler(\n `${controllerName}:stopAllSnaps`,\n async (...args) => this.stopAllSnaps(...args),\n );\n\n this.messagingSystem.registerActionHandler(\n `${controllerName}:isMinimumPlatformVersion`,\n (...args) => this.isMinimumPlatformVersion(...args),\n );\n\n this.messagingSystem.registerActionHandler(\n `${controllerName}:setClientActive`,\n (...args) => this.setClientActive(...args),\n );\n }\n\n /**\n * Initialise the SnapController.\n *\n * Currently this method calls the `onStart` lifecycle hook for all\n * runnable Snaps.\n */\n init() {\n this.#callLifecycleHooks(METAMASK_ORIGIN, HandlerType.OnStart);\n }\n\n #handlePreinstalledSnaps(preinstalledSnaps: PreinstalledSnap[]) {\n for (const {\n snapId,\n manifest,\n files,\n removable,\n hidden,\n hideSnapBranding,\n } of preinstalledSnaps) {\n const existingSnap = this.get(snapId);\n const isAlreadyInstalled = existingSnap !== undefined;\n const isUpdate =\n isAlreadyInstalled && gtVersion(manifest.version, existingSnap.version);\n\n // Disallow downgrades and overwriting non preinstalled snaps\n if (\n isAlreadyInstalled &&\n (!isUpdate || existingSnap.preinstalled !== true)\n ) {\n continue;\n }\n\n const manifestFile = new VirtualFile<SnapManifest>({\n path: NpmSnapFileNames.Manifest,\n value: JSON.stringify(manifest),\n result: manifest,\n });\n\n const virtualFiles = files.map(\n ({ path, value }) => new VirtualFile({ value, path }),\n );\n const { filePath, iconPath } = manifest.source.location.npm;\n const sourceCode = virtualFiles.find((file) => file.path === filePath);\n const svgIcon = iconPath\n ? virtualFiles.find((file) => file.path === iconPath)\n : undefined;\n\n assert(sourceCode, 'Source code not provided for preinstalled snap.');\n\n assert(\n !iconPath || (iconPath && svgIcon),\n 'Icon not provided for preinstalled snap.',\n );\n\n assert(\n manifest.source.files === undefined,\n 'Auxiliary files are not currently supported for preinstalled snaps.',\n );\n\n const localizationFiles =\n manifest.source.locales?.map((path) =>\n virtualFiles.find((file) => file.path === path),\n ) ?? [];\n\n const validatedLocalizationFiles = getValidatedLocalizationFiles(\n localizationFiles.filter(Boolean) as VirtualFile[],\n );\n\n assert(\n localizationFiles.length === validatedLocalizationFiles.length,\n 'Missing localization files for preinstalled snap.',\n );\n\n const filesObject: FetchedSnapFiles = {\n manifest: manifestFile,\n sourceCode,\n svgIcon,\n auxiliaryFiles: [],\n localizationFiles: validatedLocalizationFiles,\n };\n\n // Add snap to the SnapController state\n this.#set({\n id: snapId,\n origin: METAMASK_ORIGIN,\n files: filesObject,\n removable,\n hidden,\n hideSnapBranding,\n preinstalled: true,\n });\n\n // Setup permissions\n const processedPermissions = processSnapPermissions(\n manifest.initialPermissions,\n );\n\n this.#validateSnapPermissions(processedPermissions);\n\n const { newPermissions, unusedPermissions } =\n this.#calculatePermissionsChange(snapId, processedPermissions);\n\n this.#updatePermissions({ snapId, newPermissions, unusedPermissions });\n\n if (manifest.initialConnections) {\n this.#handleInitialConnections(\n snapId,\n existingSnap?.initialConnections ?? null,\n manifest.initialConnections,\n );\n }\n\n // Set status\n this.update((state) => {\n state.snaps[snapId].status = SnapStatus.Stopped;\n });\n\n this.#setupRuntime(snapId);\n\n // Emit events\n if (isUpdate) {\n this.messagingSystem.publish(\n 'SnapController:snapUpdated',\n this.getTruncatedExpect(snapId),\n existingSnap.version,\n METAMASK_ORIGIN,\n true,\n );\n } else {\n this.messagingSystem.publish(\n 'SnapController:snapInstalled',\n this.getTruncatedExpect(snapId),\n METAMASK_ORIGIN,\n true,\n );\n }\n }\n }\n\n #pollForLastRequestStatus() {\n this.#timeoutForLastRequestStatus = setTimeout(() => {\n this.#stopSnapsLastRequestPastMax().catch((error) => {\n // TODO: Decide how to handle errors.\n logError(error);\n });\n\n this.#pollForLastRequestStatus();\n }, this.#idleTimeCheckInterval) as unknown as number;\n }\n\n /**\n * Checks all installed snaps against the block list and\n * blocks/unblocks snaps as appropriate. See {@link SnapController.blockSnap}\n * for more information.\n */\n async updateBlockedSnaps(): Promise<void> {\n this.#assertCanUsePlatform();\n await this.messagingSystem.call('SnapsRegistry:update');\n\n const blockedSnaps = await this.messagingSystem.call(\n 'SnapsRegistry:get',\n Object.values(this.state.snaps).reduce<SnapsRegistryRequest>(\n (blockListArg, snap) => {\n blockListArg[snap.id] = {\n version: snap.version,\n checksum: snap.manifest.source.shasum,\n };\n return blockListArg;\n },\n {},\n ),\n );\n\n await Promise.all(\n Object.entries(blockedSnaps).map(async ([snapId, { status, reason }]) => {\n if (status === SnapsRegistryStatus.Blocked) {\n return this.#blockSnap(snapId as SnapId, reason);\n }\n\n return this.#unblockSnap(snapId as SnapId);\n }),\n );\n }\n\n /**\n * Blocks an installed snap and prevents it from being started again. Emits\n * {@link SnapBlocked}. Does nothing if the snap is not installed.\n *\n * @param snapId - The snap to block.\n * @param blockedSnapInfo - Information detailing why the snap is blocked.\n */\n async #blockSnap(\n snapId: SnapId,\n blockedSnapInfo?: BlockReason,\n ): Promise<void> {\n if (!this.has(snapId)) {\n return;\n }\n\n try {\n this.update((state: any) => {\n state.snaps[snapId].blocked = true;\n state.snaps[snapId].blockInformation = blockedSnapInfo;\n });\n\n await this.disableSnap(snapId);\n } catch (error) {\n logError(\n `Encountered error when stopping blocked snap \"${snapId}\".`,\n error,\n );\n }\n\n this.messagingSystem.publish(\n `${controllerName}:snapBlocked`,\n snapId,\n blockedSnapInfo,\n );\n }\n\n /**\n * Unblocks a snap so that it can be enabled and started again. Emits\n * {@link SnapUnblocked}. Does nothing if the snap is not installed or already\n * unblocked.\n *\n * @param snapId - The id of the snap to unblock.\n */\n #unblockSnap(snapId: SnapId) {\n if (!this.has(snapId) || !this.state.snaps[snapId].blocked) {\n return;\n }\n\n this.update((state: any) => {\n state.snaps[snapId].blocked = false;\n delete state.snaps[snapId].blockInformation;\n });\n\n this.messagingSystem.publish(`${controllerName}:snapUnblocked`, snapId);\n }\n\n async #assertIsInstallAllowed(\n snapId: SnapId,\n {\n platformVersion,\n ...snapInfo\n }: SnapsRegistryInfo & {\n permissions: SnapPermissions;\n platformVersion: string | undefined;\n },\n ) {\n const results = await this.messagingSystem.call('SnapsRegistry:get', {\n [snapId]: snapInfo,\n });\n\n const result = results[snapId];\n if (result.status === SnapsRegistryStatus.Blocked) {\n throw new Error(\n `Cannot install version \"${\n snapInfo.version\n }\" of snap \"${snapId}\": The version is blocked. ${\n result.reason?.explanation ?? ''\n }`,\n );\n }\n\n const isAllowlistingRequired = Object.keys(snapInfo.permissions).some(\n (permission) => !ALLOWED_PERMISSIONS.includes(permission),\n );\n\n if (\n this.#featureFlags.requireAllowlist &&\n isAllowlistingRequired &&\n result.status !== SnapsRegistryStatus.Verified\n ) {\n throw new Error(\n `Cannot install version \"${snapInfo.version}\" of snap \"${snapId}\": ${\n result.status === SnapsRegistryStatus.Unavailable\n ? 'The registry is temporarily unavailable.'\n : 'The snap is not on the allowlist.'\n }`,\n );\n }\n\n this.#validatePlatformVersion(snapId, platformVersion);\n }\n\n /**\n * Asserts whether new Snaps are allowed to be installed.\n */\n #assertCanInstallSnaps() {\n assert(\n this.#featureFlags.disableSnapInstallation !== true,\n 'Installing Snaps is currently disabled in this version of MetaMask.',\n );\n }\n\n /**\n * Asserts whether the Snaps platform is allowed to run.\n */\n #assertCanUsePlatform() {\n const flags = this.#getFeatureFlags();\n assert(\n flags.disableSnaps !== true,\n 'The Snaps platform requires basic functionality to be used. Enable basic functionality in the settings to use the Snaps platform.',\n );\n }\n\n async #stopSnapsLastRequestPastMax() {\n const entries = [...this.#snapsRuntimeData.entries()];\n return Promise.all(\n entries\n .filter(\n ([_snapId, runtime]) =>\n runtime.activeReferences === 0 &&\n runtime.pendingInboundRequests.length === 0 &&\n runtime.lastRequest &&\n this.#maxIdleTime &&\n timeSince(runtime.lastRequest) > this.#maxIdleTime,\n )\n .map(async ([snapId]) => this.stopSnap(snapId, SnapStatusEvents.Stop)),\n );\n }\n\n _onUnhandledSnapError(snapId: string, error: SnapErrorJson) {\n // Log the error that caused the crash\n // so it gets raised to the developer for debugging purposes.\n logError(`Unhandled error from \"${snapId}\":`, error);\n this.stopSnap(snapId as SnapId, SnapStatusEvents.Crash).catch(\n (stopSnapError) => {\n // TODO: Decide how to handle errors.\n logError(stopSnapError);\n },\n );\n }\n\n _onOutboundRequest(snapId: string) {\n const runtime = this.#getRuntimeExpect(snapId as SnapId);\n // Ideally we would only pause the pending request that is making the outbound request\n // but right now we don't have a way to know which request initiated the outbound request\n runtime.pendingInboundRequests\n .filter((pendingRequest) => pendingRequest.timer.status === 'running')\n .forEach((pendingRequest) => pendingRequest.timer.pause());\n runtime.pendingOutboundRequests += 1;\n }\n\n _onOutboundResponse(snapId: string) {\n const runtime = this.#getRuntimeExpect(snapId as SnapId);\n runtime.pendingOutboundRequests -= 1;\n if (runtime.pendingOutboundRequests === 0) {\n runtime.pendingInboundRequests\n .filter((pendingRequest) => pendingRequest.timer.status === 'paused')\n .forEach((pendingRequest) => pendingRequest.timer.resume());\n }\n }\n\n /**\n * Transitions between states using `snapStatusStateMachineConfig` as the template to figure out\n * the next state. This transition function uses a very minimal subset of XState conventions:\n * - supports initial state\n * - .on supports raw event target string\n * - .on supports {target, cond} object\n * - the arguments for `cond` is the `SerializedSnap` instead of Xstate convention of `(event,\n * context) => boolean`\n *\n * @param snapId - The id of the snap to transition.\n * @param event - The event enum to use to transition.\n */\n #transition(snapId: SnapId, event: StatusEvents | StatusEvents['type']) {\n const { interpreter } = this.#getRuntimeExpect(snapId);\n interpreter.send(event);\n this.update((state: any) => {\n state.snaps[snapId].status = interpreter.state.value;\n });\n }\n\n /**\n * Starts the given snap. Throws an error if no such snap exists\n * or if it is already running.\n *\n * @param snapId - The id of the Snap to start.\n */\n async startSnap(snapId: SnapId): Promise<void> {\n this.#assertCanUsePlatform();\n const snap = this.state.snaps[snapId];\n\n if (!snap.enabled) {\n throw new Error(`Snap \"${snapId}\" is disabled.`);\n }\n\n await this.#startSnap({\n snapId,\n sourceCode: snap.sourceCode,\n });\n }\n\n /**\n * Enables the given snap. A snap can only be started if it is enabled. A snap\n * can only be enabled if it isn't blocked.\n *\n * @param snapId - The id of the Snap to enable.\n */\n enableSnap(snapId: SnapId): void {\n this.getExpect(snapId);\n\n if (this.state.snaps[snapId].blocked) {\n throw new Error(`Snap \"${snapId}\" is blocked and cannot be enabled.`);\n }\n\n this.update((state: any) => {\n state.snaps[snapId].enabled = true;\n });\n\n this.messagingSystem.publish(\n 'SnapController:snapEnabled',\n this.getTruncatedExpect(snapId),\n );\n }\n\n /**\n * Disables the given snap. A snap can only be started if it is enabled.\n *\n * @param snapId - The id of the Snap to disable.\n * @returns A promise that resolves once the snap has been disabled.\n */\n async disableSnap(snapId: SnapId): Promise<void> {\n if (!this.has(snapId)) {\n throw new Error(`Snap \"${snapId}\" not found.`);\n }\n\n this.update((state: any) => {\n state.snaps[snapId].enabled = false;\n });\n\n if (this.isRunning(snapId)) {\n await this.stopSnap(snapId, SnapStatusEvents.Stop);\n }\n\n this.messagingSystem.publish(\n 'SnapController:snapDisabled',\n this.getTruncatedExpect(snapId),\n );\n }\n\n /**\n * Stops the given snap, removes all hooks, closes all connections, and\n * terminates its worker.\n *\n * @param snapId - The id of the Snap to stop.\n * @param statusEvent - The Snap status event that caused the snap to be\n * stopped.\n */\n public async stopSnap(\n snapId: SnapId,\n statusEvent:\n | SnapStatusEvents.Stop\n | SnapStatusEvents.Crash = SnapStatusEvents.Stop,\n ): Promise<void> {\n const runtime = this.#getRuntime(snapId);\n if (!runtime) {\n throw new Error(`The snap \"${snapId}\" is not running.`);\n }\n\n // If we are already stopping, wait for that to finish.\n if (runtime.stopPromise) {\n await runtime.stopPromise;\n return;\n }\n\n // Flag that the Snap is actively stopping, this prevents other calls to stopSnap\n // while we are handling termination of the Snap\n const { promise, resolve } = createDeferredPromise();\n runtime.stopPromise = promise;\n\n try {\n if (this.isRunning(snapId)) {\n this.#closeAllConnections?.(snapId);\n await this.#terminateSnap(snapId);\n }\n } finally {\n // Reset request tracking\n runtime.lastRequest = null;\n runtime.pendingInboundRequests = [];\n runtime.pendingOutboundRequests = 0;\n runtime.stopPromise = null;\n if (this.isRunning(snapId)) {\n this.#transition(snapId, statusEvent);\n }\n resolve();\n }\n }\n\n /**\n * Stops all running snaps, removes all hooks, closes all connections, and\n * terminates their workers.\n *\n * @param statusEvent - The Snap status event that caused the snap to be\n * stopped.\n */\n public async stopAllSnaps(\n statusEvent:\n | SnapStatusEvents.Stop\n | SnapStatusEvents.Crash = SnapStatusEvents.Stop,\n ): Promise<void> {\n const snaps = Object.values(this.state.snaps).filter((snap) =>\n this.isRunning(snap.id),\n );\n const promises = snaps.map(async (snap) =>\n this.stopSnap(snap.id, statusEvent),\n );\n await Promise.allSettled(promises);\n }\n\n /**\n * Terminates the specified snap and emits the `snapTerminated` event.\n *\n * @param snapId - The snap to terminate.\n */\n async #terminateSnap(snapId: SnapId) {\n await this.messagingSystem.call('ExecutionService:terminateSnap', snapId);\n\n // Hack to give up execution for a bit to let gracefully terminating Snaps return.\n await new Promise((resolve) => setTimeout(resolve, 1));\n\n const runtime = this.#getRuntimeExpect(snapId);\n // Unresponsive requests may still be timed, time them out.\n runtime.pendingInboundRequests\n .filter((pendingRequest) => pendingRequest.timer.status !== 'finished')\n .forEach((pendingRequest) => pendingRequest.timer.finish());\n\n // Hack to give up execution for a bit to let timed out requests return.\n await new Promise((resolve) => setTimeout(resolve, 1));\n\n this.messagingSystem.publish(\n 'SnapController:snapTerminated',\n this.getTruncatedExpect(snapId),\n );\n }\n\n /**\n * Returns whether the given snap is running.\n * Throws an error if the snap doesn't exist.\n *\n * @param snapId - The id of the Snap to check.\n * @returns `true` if the snap is running, otherwise `false`.\n */\n isRunning(snapId: SnapId): boolean {\n return this.getExpect(snapId).status === 'running';\n }\n\n /**\n * Returns whether the given snap has been added to state.\n *\n * @param snapId - The id of the Snap to check for.\n * @returns `true` if the snap exists in the controller state, otherwise `false`.\n */\n has(snapId: SnapId): boolean {\n return Boolean(this.get(snapId));\n }\n\n /**\n * Gets the snap with the given id if it exists, including all data.\n * This should not be used if the snap is to be serializable, as e.g.\n * the snap sourceCode may be quite large.\n *\n * @param snapId - The id of the Snap to get.\n * @returns The entire snap object from the controller state.\n */\n get(snapId: string): Snap | undefined {\n return this.state.snaps[snapId as SnapId];\n }\n\n /**\n * Gets the snap with the given id, throws if doesn't.\n * This should not be used if the snap is to be serializable, as e.g.\n * the snap sourceCode may be quite large.\n *\n * @see {@link SnapController.get}\n * @throws {@link Error}. If the snap doesn't exist\n * @param snapId - The id of the snap to get.\n * @returns The entire snap object.\n */\n getExpect(snapId: SnapId): Snap {\n const snap = this.get(snapId);\n assert(snap !== undefined, new Error(`Snap \"${snapId}\" not found.`));\n return snap;\n }\n\n /**\n * Gets the snap with the given id if it exists, excluding any\n * non-serializable or expensive-to-serialize data.\n *\n * @param snapId - The id of the Snap to get.\n * @returns A truncated version of the snap state, that is less expensive to serialize.\n */\n // TODO(ritave): this.get returns undefined, this.getTruncated returns null\n getTruncated(snapId: SnapId): TruncatedSnap | null {\n const snap = this.get(snapId);\n\n return snap ? truncateSnap(snap) : null;\n }\n\n /**\n * Gets the snap with the given id, throw if it doesn't exist.\n *\n * @throws {@link Error}. If snap doesn't exist\n * @param snapId - The id of the snap to get.\n * @returns A truncated version of the snap state, that is less expensive to serialize.\n */\n getTruncatedExpect(snapId: SnapId): TruncatedSnap {\n return truncateSnap(this.getExpect(snapId));\n }\n\n /**\n * Check if a given Snap has a cached encryption key stored in the runtime.\n *\n * @param snapId - The Snap ID.\n * @param runtime - The Snap runtime data.\n * @returns True if the Snap has a cached encryption key, otherwise false.\n */\n #hasCachedEncryptionKey(\n snapId: SnapId,\n runtime = this.#getRuntimeExpect(snapId),\n ): runtime is SnapRuntimeData & {\n encryptionKey: string;\n encryptionSalt: string;\n } {\n return runtime.encryptionKey !== null && runtime.encryptionSalt !== null;\n }\n\n /**\n * Generate an encryption key to be used for state encryption for a given Snap.\n *\n * @param options - An options bag.\n * @param options.snapId - The Snap ID.\n * @param options.salt - A salt to be used for the encryption key.\n * @param options.useCache - Whether to use caching or not.\n * @param options.keyMetadata - Optional metadata about how to derive the encryption key.\n * @returns An encryption key.\n */\n async #getSnapEncryptionKey({\n snapId,\n salt: passedSalt,\n useCache,\n keyMetadata,\n }: {\n snapId: SnapId;\n salt?: string;\n useCache: boolean;\n keyMetadata?: KeyDerivationOptions;\n }): Promise<{ key: unknown; salt: string }> {\n const runtime = this.#getRuntimeExpect(snapId);\n\n if (this.#hasCachedEncryptionKey(snapId, runtime) && useCache) {\n return {\n key: await this.#encryptor.importKey(runtime.encryptionKey),\n salt: runtime.encryptionSalt,\n };\n }\n\n const salt = passedSalt ?? this.#encryptor.generateSalt();\n const seed = await this.#getMnemonicSeed();\n\n const entropy = await getEncryptionEntropy({\n snapId,\n seed,\n cryptographicFunctions: this.#clientCryptography,\n });\n\n const encryptionKey = await this.#encryptor.keyFromPassword(\n entropy,\n salt,\n true,\n keyMetadata,\n );\n const exportedKey = await this.#encryptor.exportKey(encryptionKey);\n\n // Cache exported encryption key in runtime\n if (useCache) {\n runtime.encryptionKey = exportedKey;\n runtime.encryptionSalt = salt;\n }\n return { key: encryptionKey, salt };\n }\n\n /**\n * Decrypt the encrypted state for a given Snap.\n *\n * @param snapId - The Snap ID.\n * @param state - The encrypted state as a string.\n * @returns A valid JSON object derived from the encrypted state.\n * @throws If the decryption fails or the decrypted state is not valid JSON.\n */\n async #decryptSnapState(snapId: SnapId, state: string) {\n try {\n // We assume that the state string here is valid JSON since we control serialization.\n // This lets us skip JSON validation.\n const parsed = JSON.parse(state) as EncryptionResult;\n const { salt, keyMetadata } = parsed;\n\n // We only cache encryption keys if they are already cached or if the encryption key is using the latest key derivation params.\n const useCache =\n this.#hasCachedEncryptionKey(snapId) ||\n this.#encryptor.isVaultUpdated(state);\n\n const { key } = await this.#getSnapEncryptionKey({\n snapId,\n salt,\n useCache,\n // When decrypting state we expect key metadata to be present.\n // If it isn't present, we assume that the Snap state we are decrypting is old enough to use the legacy encryption params.\n keyMetadata: keyMetadata ?? LEGACY_ENCRYPTION_KEY_DERIVATION_OPTIONS,\n });\n const decryptedState = await this.#encryptor.decryptWithKey(key, parsed);\n\n // We assume this to be valid JSON, since all RPC requests from a Snap are validated and sanitized.\n return decryptedState as Record<string, Json>;\n } catch {\n throw rpcErrors.internal({\n message: 'Failed to decrypt snap state, the state must be corrupted.',\n });\n }\n }\n\n /**\n * Encrypt a JSON state object for a given Snap.\n *\n * Note: This function does not assert the validity of the object,\n * please ensure only valid JSON is passed to it.\n *\n * @param snapId - The Snap ID.\n * @param state - The state object.\n * @returns A string containing the encrypted JSON object.\n */\n async #encryptSnapState(snapId: SnapId, state: Record<string, Json>) {\n const { key, salt } = await this.#getSnapEncryptionKey({\n snapId,\n useCache: true,\n });\n const encryptedState = await this.#encryptor.encryptWithKey(key, state);\n\n encryptedState.salt = salt;\n return JSON.stringify(encryptedState);\n }\n\n /**\n * Get the new Snap state to persist based on the given state and encryption\n * flag.\n *\n * - If the state is null, return null.\n * - If the state should be encrypted, return the encrypted state.\n * - Otherwise, if the state should not be encrypted, return the JSON-\n * stringified state.\n *\n * @param snapId - The Snap ID.\n * @param state - The state to persist.\n * @param encrypted - A flag to indicate whether to use encrypted storage or\n * not.\n * @returns The state to persist.\n */\n async #getStateToPersist(\n snapId: SnapId,\n state: Record<string, Json> | null,\n encrypted: boolean,\n ) {\n if (state === null) {\n return null;\n }\n\n if (encrypted) {\n return await this.#encryptSnapState(snapId, state);\n }\n\n return JSON.stringify(state);\n }\n\n /**\n * Persist the state of a Snap.\n *\n * This function is debounced per Snap, meaning that multiple calls to this\n * function for the same Snap will only result in one state update. It also\n * uses a mutex to ensure that only one state update per Snap is processed at\n * a time, avoiding possible race conditions.\n *\n * @param snapId - The Snap ID.\n * @param newSnapState - The new state of the Snap.\n * @param encrypted - A flag to indicate whether to use encrypted storage or\n * not.\n */\n readonly #persistSnapState = debouncePersistState(\n (\n snapId: SnapId,\n newSnapState: Record<string, Json> | null,\n encrypted: boolean,\n ) => {\n const runtime = this.#getRuntimeExpect(snapId);\n runtime.stateMutex\n .runExclusive(async () => {\n const newState = await this.#getStateToPersist(\n snapId,\n newSnapState,\n encrypted,\n );\n\n if (encrypted) {\n return this.update((state) => {\n state.snapStates[snapId] = newState;\n });\n }\n\n return this.update((state) => {\n state.unencryptedSnapStates[snapId] = newState;\n });\n })\n .catch(logError);\n },\n STATE_DEBOUNCE_TIMEOUT,\n );\n\n /**\n * Updates the own state of the snap with the given id.\n * This is distinct from the state MetaMask uses to manage snaps.\n *\n * @param snapId - The id of the Snap whose state should be updated.\n * @param newSnapState - The new state of the snap.\n * @param encrypted - A flag to indicate whether to use encrypted storage or not.\n */\n async updateSnapState(\n snapId: SnapId,\n newSnapState: Record<string, Json>,\n encrypted: boolean,\n ) {\n const runtime = this.#getRuntimeExpect(snapId);\n\n if (encrypted) {\n runtime.state = newSnapState;\n } else {\n runtime.unencryptedState = newSnapState;\n }\n\n this.#persistSnapState(snapId, newSnapState, encrypted);\n }\n\n /**\n * Clears the state of the snap with the given id.\n * This is distinct from the state MetaMask uses to manage snaps.\n *\n * @param snapId - The id of the Snap whose state should be cleared.\n * @param encrypted - A flag to indicate whether to use encrypted storage or not.\n */\n clearSnapState(snapId: SnapId, encrypted: boolean) {\n const runtime = this.#getRuntimeExpect(snapId);\n if (encrypted) {\n runtime.state = null;\n } else {\n runtime.unencryptedState = null;\n }\n\n this.#persistSnapState(snapId, null, encrypted);\n }\n\n /**\n * Gets the own state of the snap with the given id.\n * This is distinct from the state MetaMask uses to manage snaps.\n *\n * @param snapId - The id of the Snap whose state to get.\n * @param encrypted - A flag to indicate whether to use encrypted storage or not.\n * @returns The requested snap state or null if no state exists.\n */\n async getSnapState(snapId: SnapId, encrypted: boolean): Promise<Json> {\n const runtime = this.#getRuntimeExpect(snapId);\n return await runtime.getStateMutex.runExclusive(async () => {\n const cachedState = encrypted ? runtime.state : runtime.unencryptedState;\n\n if (cachedState !== undefined) {\n return cachedState;\n }\n\n const state = encrypted\n ? this.state.snapStates[snapId]\n : this.state.unencryptedSnapStates[snapId];\n\n if (state === null || state === undefined) {\n return null;\n }\n\n if (!encrypted) {\n // For performance reasons, we do not validate that the state is JSON,\n // since we control serialization.\n const json = JSON.parse(state);\n runtime.unencryptedState = json;\n\n return json;\n }\n\n const decrypted = await this.#decryptSnapState(snapId, state);\n // eslint-disable-next-line require-atomic-updates\n runtime.state = decrypted;\n\n return decrypted;\n });\n }\n\n /**\n * Gets a static auxiliary snap file in a chosen file encoding.\n *\n * @param snapId - The id of the Snap whose state to get.\n * @param path - The path to the requested file.\n * @param encoding - An optional requested file encoding.\n * @returns The file requested in the chosen file encoding or null if the file is not found.\n */\n async getSnapFile(\n snapId: SnapId,\n path: string,\n encoding: AuxiliaryFileEncoding = AuxiliaryFileEncoding.Base64,\n ): Promise<string | null> {\n const snap = this.getExpect(snapId);\n const normalizedPath = normalizeRelative(path);\n const value = snap.auxiliaryFiles?.find(\n (file) => file.path === normalizedPath,\n )?.value;\n\n if (!value) {\n return null;\n }\n\n const encoded = await encodeAuxiliaryFile(value, encoding);\n\n assert(\n encoded.length < MAX_FILE_SIZE,\n `Failed to encode static file to \"${encoding}\": Static files must be less than 64 MB when encoded.`,\n );\n\n return encoded;\n }\n\n /**\n * Determine if a given Snap ID supports a given minimum version of the Snaps platform\n * by inspecting the platformVersion in the Snap manifest.\n *\n * @param snapId - The Snap ID.\n * @param version - The version.\n * @returns True if the platform version is equal or greater to the passed version, false otherwise.\n */\n isMinimumPlatformVersion(snapId: SnapId, version: SemVerVersion): boolean {\n const snap = this.getExpect(snapId);\n\n const { platformVersion } = snap.manifest;\n\n if (!platformVersion) {\n return false;\n }\n\n return gte(platformVersion, version);\n }\n\n /**\n * Completely clear the controller's state: delete all associated data,\n * handlers, event listeners, and permissions; tear down all snap providers.\n */\n async clearState() {\n const snapIds = Object.keys(this.state.snaps);\n if (this.#closeAllConnections) {\n snapIds.forEach((snapId) => {\n this.#closeAllConnections?.(snapId);\n });\n }\n\n await this.messagingSystem.call('ExecutionService:terminateAllSnaps');\n snapIds.forEach((snapId) => this.#revokeAllSnapPermissions(snapId));\n\n this.update((state) => {\n state.snaps = {};\n state.snapStates = {};\n state.unencryptedSnapStates = {};\n });\n\n this.#snapsRuntimeData.clear();\n this.#rollbackSnapshots.clear();\n\n // We want to remove all snaps & permissions, except for preinstalled snaps\n if (this.#preinstalledSnaps) {\n this.#handlePreinstalledSnaps(this.#preinstalledSnaps);\n }\n }\n\n /**\n * Removes the given snap from state, and clears all associated handlers\n * and listeners.\n *\n * @param snapId - The id of the Snap.\n * @returns A promise that resolves once the snap has been removed.\n */\n async removeSnap(snapId: SnapId): Promise<void> {\n return this.removeSnaps([snapId]);\n }\n\n /**\n * Stops the given snaps, removes them from state, and clears all associated\n * permissions, handlers, and listeners.\n *\n * @param snapIds - The ids of the Snaps.\n */\n async removeSnaps(snapIds: SnapId[]): Promise<void> {\n if (!Array.isArray(snapIds)) {\n throw new Error('Expected array of snap ids.');\n }\n\n snapIds.forEach((snapId) => {\n const snap = this.getExpect(snapId);\n assert(snap.removable !== false, `${snapId} is not removable.`);\n });\n\n await Promise.all(\n snapIds.map(async (snapId) => {\n const snap = this.getExpect(snapId);\n const truncated = this.getTruncatedExpect(snapId);\n // Disable the snap and revoke all of its permissions before deleting\n // it. This ensures that the snap will not be restarted or otherwise\n // affect the host environment while we are deleting it.\n await this.disableSnap(snapId);\n this.#revokeAllSnapPermissions(snapId);\n\n this.#removeSnapFromSubjects(snapId);\n\n this.#snapsRuntimeData.delete(snapId);\n\n this.update((state: any) => {\n delete state.snaps[snapId];\n delete state.snapStates[snapId];\n delete state.unencryptedSnapStates[snapId];\n });\n\n // If the snap has been fully installed before, also emit snapUninstalled.\n if (snap.status !== SnapStatus.Installing) {\n this.messagingSystem.publish(\n `SnapController:snapUninstalled`,\n truncated,\n );\n }\n }),\n );\n }\n\n #handleInitialConnections(\n snapId: SnapId,\n previousInitialConnections: InitialConnections | null,\n initialConnections: InitialConnections,\n ) {\n if (previousInitialConnections) {\n const revokedInitialConnections = setDiff(\n previousInitialConnections,\n initialConnections,\n );\n\n for (const origin of Object.keys(revokedInitialConnections)) {\n this.removeSnapFromSubject(origin, snapId);\n }\n }\n\n for (const origin of Object.keys(initialConnections)) {\n this.#addSnapToSubject(origin, snapId);\n }\n }\n\n #addSnapToSubject(origin: string, snapId: SnapId) {\n const subjectPermissions = this.messagingSystem.call(\n 'PermissionController:getPermissions',\n origin,\n ) as SubjectPermissions<PermissionConstraint>;\n\n const existingCaveat = subjectPermissions?.[\n WALLET_SNAP_PERMISSION_KEY\n ]?.caveats?.find((caveat) => caveat.type === SnapCaveatType.SnapIds);\n\n const subjectHasSnap = Boolean(\n (existingCaveat?.value as Record<string, Json>)?.[snapId],\n );\n\n // If the subject is already connected to the snap, this is a no-op.\n if (subjectHasSnap) {\n return;\n }\n\n // If an existing caveat exists, we add the snap to that.\n if (existingCaveat) {\n this.messagingSystem.call(\n 'PermissionController:updateCaveat',\n origin,\n WALLET_SNAP_PERMISSION_KEY,\n SnapCaveatType.SnapIds,\n { ...(existingCaveat.value as Record<string, Json>), [snapId]: {} },\n );\n return;\n }\n\n const approvedPermissions = {\n [WALLET_SNAP_PERMISSION_KEY]: {\n caveats: [\n {\n type: SnapCaveatType.SnapIds,\n value: {\n [snapId]: {},\n },\n },\n ],\n },\n } as RequestedPermissions;\n\n this.messagingSystem.call('PermissionController:grantPermissions', {\n approvedPermissions,\n subject: { origin },\n });\n }\n\n /**\n * Removes a snap's permission (caveat) from the specified subject.\n *\n * @param origin - The origin from which to remove the snap.\n * @param snapId - The id of the snap to remove.\n */\n removeSnapFromSubject(origin: string, snapId: SnapId) {\n const subjectPermissions = this.messagingSystem.call(\n 'PermissionController:getPermissions',\n origin,\n ) as SubjectPermissions<PermissionConstraint>;\n\n const snapIdsCaveat = subjectPermissions?.[\n WALLET_SNAP_PERMISSION_KEY\n ]?.caveats?.find((caveat) => caveat.type === SnapCaveatType.SnapIds) as\n | Caveat<string, Json>\n | undefined;\n\n if (!snapIdsCaveat) {\n return;\n }\n\n const caveatHasSnap = Boolean(\n (snapIdsCaveat.value as Record<string, Json>)?.[snapId],\n );\n if (caveatHasSnap) {\n const newCaveatValue = {\n ...(snapIdsCaveat.value as Record<string, Json>),\n };\n delete newCaveatValue[snapId];\n if (Object.keys(newCaveatValue).length > 0) {\n this.messagingSystem.call(\n 'PermissionController:updateCaveat',\n origin,\n WALLET_SNAP_PERMISSION_KEY,\n SnapCaveatType.SnapIds,\n newCaveatValue,\n );\n } else {\n this.messagingSystem.call('PermissionController:revokePermissions', {\n [origin]: [WALLET_SNAP_PERMISSION_KEY],\n });\n }\n }\n }\n\n /**\n * Checks if a list of permissions are dynamic and allowed to be revoked, if they are they will all be revoked.\n *\n * @param snapId - The snap ID.\n * @param permissionNames - The names of the permissions.\n * @throws If non-dynamic permissions are passed.\n */\n revokeDynamicSnapPermissions(\n snapId: string,\n permissionNames: NonEmptyArray<string>,\n ) {\n assert(\n permissionNames.every((permissionName) =>\n this.#dynamicPermissions.includes(permissionName),\n ),\n 'Non-dynamic permissions cannot be revoked',\n );\n this.messagingSystem.call('PermissionController:revokePermissions', {\n [snapId]: permissionNames,\n });\n }\n\n /**\n * Removes a snap's permission (caveat) from all subjects.\n *\n * @param snapId - The id of the Snap.\n */\n #removeSnapFromSubjects(snapId: SnapId) {\n const subjects = this.messagingSystem.call(\n 'PermissionController:getSubjectNames',\n );\n for (const subject of subjects) {\n this.removeSnapFromSubject(subject, snapId);\n }\n }\n\n /**\n * Safely revokes all permissions granted to a Snap.\n *\n * @param snapId - The snap ID.\n */\n #revokeAllSnapPermissions(snapId: string) {\n if (\n this.messagingSystem.call('PermissionController:hasPermissions', snapId)\n ) {\n this.messagingSystem.call(\n 'PermissionController:revokeAllPermissions',\n snapId,\n );\n }\n }\n\n /**\n * Handles incrementing the activeReferences counter.\n *\n * @param snapId - The snap id of the snap that was referenced.\n */\n incrementActiveReferences(snapId: SnapId) {\n const runtime = this.#getRuntimeExpect(snapId);\n runtime.activeReferences += 1;\n }\n\n /**\n * Handles decrement the activeReferences counter.\n *\n * @param snapId - The snap id of the snap that was referenced..\n */\n decrementActiveReferences(snapId: SnapId) {\n const runtime = this.#getRuntimeExpect(snapId);\n assert(\n runtime.activeReferences > 0,\n 'SnapController reference management is in an invalid state.',\n );\n runtime.activeReferences -= 1;\n }\n\n /**\n * Gets all snaps in their truncated format.\n *\n * @returns All installed snaps in their truncated format.\n */\n getAllSnaps(): TruncatedSnap[] {\n return Object.values(this.state.snaps).map(truncateSnap);\n }\n\n /**\n * Gets all runnable snaps.\n *\n * @returns All runnable snaps.\n */\n getRunnableSnaps(): TruncatedSnap[] {\n return getRunnableSnaps(this.getAllSnaps());\n }\n\n /**\n * Gets the serialized permitted snaps of the given origin, if any.\n *\n * @param origin - The origin whose permitted snaps to retrieve.\n * @returns The serialized permitted snaps for the origin.\n */\n getPermittedSnaps(origin: string): RequestSnapsResult {\n const permissions =\n this.messagingSystem.call(\n 'PermissionController:getPermissions',\n origin,\n ) ?? {};\n const snaps =\n permissions[WALLET_SNAP_PERMISSION_KEY]?.caveats?.find(\n (caveat) => caveat.type === SnapCaveatType.SnapIds,\n )?.value ?? {};\n return Object.keys(snaps).reduce<RequestSnapsResult>(\n (permittedSnaps, snapId) => {\n const snap = this.get(snapId);\n const truncatedSnap = this.getTruncated(snapId as SnapId);\n\n if (truncatedSnap && snap?.status !== SnapStatus.Installing) {\n permittedSnaps[snapId] = truncatedSnap;\n }\n return permittedSnaps;\n },\n {},\n );\n }\n\n /**\n * Installs the snaps requested by the given origin, returning the snap\n * object if the origin is permitted to install it, and an authorization error\n * otherwise.\n *\n * @param origin - The origin that requested to install the snaps.\n * @param requestedSnaps - The snaps to install.\n * @returns An object of snap ids and snap objects, or errors if a\n * snap couldn't be installed.\n */\n async installSnaps(\n origin: string,\n requestedSnaps: RequestSnapsParams,\n ): Promise<RequestSnapsResult> {\n this.#assertCanUsePlatform();\n\n const result: RequestSnapsResult = {};\n\n const snapIds = Object.keys(requestedSnaps);\n\n const pendingUpdates = [];\n const pendingInstalls = [];\n\n try {\n for (const [snapId, { version: rawVersion }] of Object.entries(\n requestedSnaps,\n )) {\n assertIsValidSnapId(snapId);\n\n const [error, version] = resolveVersionRange(rawVersion);\n\n if (error) {\n throw rpcErrors.invalidParams(\n `The \"version\" field must be a valid SemVer version range if specified. Received: \"${\n rawVersion as string\n }\".`,\n );\n }\n\n const location = this.#detectSnapLocation(snapId, {\n versionRange: version,\n fetch: this.#fetchFunction,\n allowLocal: this.#featureFlags.allowLocalSnaps,\n resolveVersion: async (range) =>\n this.#featureFlags.requireAllowlist\n ? await this.#resolveAllowlistVersion(snapId, range)\n : range,\n });\n\n // Existing snaps may need to be updated, unless they should be re-installed (e.g. local snaps)\n // Everything else is treated as an install\n const isUpdate = this.has(snapId) && !location.shouldAlwaysReload;\n\n if (isUpdate && this.#isValidUpdate(snapId, version)) {\n const existingSnap = this.getExpect(snapId);\n pendingUpdates.push({ snapId, oldVersion: existingSnap.version });\n let rollbackSnapshot = this.#getRollbackSnapshot(snapId);\n if (rollbackSnapshot === undefined) {\n rollbackSnapshot = this.#createRollbackSnapshot(snapId);\n rollbackSnapshot.newVersion = version;\n } else {\n throw new Error('This snap is already being updated.');\n }\n } else if (!isUpdate) {\n pendingInstalls.push(snapId);\n }\n\n result[snapId] = await this.processRequestedSnap(\n origin,\n snapId,\n location,\n version,\n );\n }\n\n // Once we finish all installs / updates, emit events.\n pendingInstalls.forEach((snapId) =>\n this.messagingSystem.publish(\n `SnapController:snapInstalled`,\n this.getTruncatedExpect(snapId),\n origin,\n false,\n ),\n );\n\n pendingUpdates.forEach(({ snapId, oldVersion }) =>\n this.messagingSystem.publish(\n `SnapController:snapUpdated`,\n this.getTruncatedExpect(snapId),\n oldVersion,\n origin,\n false,\n ),\n );\n\n snapIds.forEach((snapId) => this.#rollbackSnapshots.delete(snapId));\n } catch (error) {\n const installed = pendingInstalls.filter((snapId) => this.has(snapId));\n await this.removeSnaps(installed);\n const snapshottedSnaps = [...this.#rollbackSnapshots.keys()];\n const snapsToRollback = pendingUpdates\n .map(({ snapId }) => snapId)\n .filter((snapId) => snapshottedSnaps.includes(snapId));\n await this.#rollbackSnaps(snapsToRollback);\n\n throw error;\n }\n\n return result;\n }\n\n /**\n * Adds, authorizes, and runs the given snap with a snap provider.\n * Results from this method should be efficiently serializable.\n *\n * @param origin - The origin requesting the snap.\n * @param snapId - The id of the snap.\n * @param location - The location implementation of the snap.\n * @param versionRange - The semver range of the snap to install.\n * @returns The resulting snap object, or an error if something went wrong.\n */\n // TODO: Either fix this lint violation or explain why it's necessary to\n // ignore.\n // eslint-disable-next-line no-restricted-syntax\n private async processRequestedSnap(\n origin: string,\n snapId: SnapId,\n location: SnapLocation,\n versionRange: SemVerRange,\n ): Promise<TruncatedSnap> {\n const existingSnap = this.getTruncated(snapId);\n\n // For devX we always re-install local snaps.\n if (existingSnap && !location.shouldAlwaysReload) {\n if (satisfiesVersionRange(existingSnap.version, versionRange)) {\n return existingSnap;\n }\n\n return await this.updateSnap(\n origin,\n snapId,\n location,\n versionRange,\n // Since we are requesting an update from within processRequestedSnap,\n // we disable the emitting of the snapUpdated event and rely on the caller\n // to publish this event after the update is complete.\n // This is necessary as installSnaps may be installing multiple snaps\n // and we don't want to emit events prematurely.\n false,\n );\n }\n\n this.#assertCanInstallSnaps();\n\n let pendingApproval = this.#createApproval({\n origin,\n snapId,\n type: SNAP_APPROVAL_INSTALL,\n });\n\n this.messagingSystem.publish(\n 'SnapController:snapInstallStarted',\n snapId,\n origin,\n false,\n );\n\n // Existing snaps must be stopped before overwriting\n if (existingSnap && this.isRunning(snapId)) {\n await this.stopSnap(snapId, SnapStatusEvents.Stop);\n }\n\n // Existing snaps that should be re-installed should not maintain their existing permissions\n if (existingSnap && location.shouldAlwaysReload) {\n this.#revokeAllSnapPermissions(snapId);\n }\n\n try {\n const { sourceCode } = await this.#add({\n origin,\n id: snapId,\n location,\n versionRange,\n });\n\n await this.authorize(snapId, pendingApproval);\n\n pendingApproval = this.#createApproval({\n origin,\n snapId,\n type: SNAP_APPROVAL_RESULT,\n });\n\n await this.#startSnap({\n snapId,\n sourceCode,\n });\n\n const truncated = this.getTruncatedExpect(snapId);\n\n this.#updateApproval(pendingApproval.id, {\n loading: false,\n type: SNAP_APPROVAL_INSTALL,\n });\n\n return truncated;\n } catch (error) {\n logError(`Error when adding ${snapId}.`, error);\n\n const errorString =\n error instanceof Error ? error.message : error.toString();\n\n this.#updateApproval(pendingApproval.id, {\n loading: false,\n type: SNAP_APPROVAL_INSTALL,\n error: errorString,\n });\n\n this.messagingSystem.publish(\n 'SnapController:snapInstallFailed',\n snapId,\n origin,\n false,\n errorString,\n );\n\n throw error;\n }\n }\n\n #createApproval({\n origin,\n snapId,\n type,\n }: {\n origin: string;\n snapId: SnapId;\n type: string;\n }): PendingApproval {\n const id = nanoid();\n const promise = this.messagingSystem.call(\n 'ApprovalController:addRequest',\n {\n origin,\n id,\n type,\n requestData: {\n // Mirror previous installation metadata\n metadata: { id, origin: snapId, dappOrigin: origin },\n snapId,\n },\n requestState: {\n loading: true,\n },\n },\n true,\n );\n\n return { id, promise };\n }\n\n #updateApproval(id: string, requestState: Record<string, Json>) {\n try {\n this.messagingSystem.call('ApprovalController:updateRequestState', {\n id,\n requestState,\n });\n } catch {\n // Do nothing\n }\n }\n\n /**\n * Updates an installed snap. The flow is similar to\n * {@link SnapController.installSnaps}. The user will be asked if they want\n * to update, then approve any permission changes, and finally the snap will\n * be restarted.\n *\n * The update will fail if the user rejects any prompt or if the new version\n * of the snap is blocked.\n *\n * If the original version of the snap was blocked and the update succeeded,\n * the snap will be unblocked and enabled before it is restarted.\n *\n * @param origin - The origin requesting the snap update.\n * @param snapId - The id of the Snap to be updated.\n * @param location - The location implementation of the snap.\n * @param newVersionRange - A semver version range in which the maximum version will be chosen.\n * @param emitEvent - An optional boolean flag to indicate whether this update should emit an event.\n * @returns The snap metadata if updated, `null` otherwise.\n */\n async updateSnap(\n origin: string,\n snapId: SnapId,\n location: SnapLocation,\n newVersionRange: string = DEFAULT_REQUESTED_SNAP_VERSION,\n emitEvent = true,\n ): Promise<TruncatedSnap> {\n this.#assertCanInstallSnaps();\n this.#assertCanUsePlatform();\n\n const snap = this.getExpect(snapId);\n\n if (snap.preinstalled) {\n throw new Error('Preinstalled Snaps cannot be manually updated.');\n }\n\n if (!isValidSemVerRange(newVersionRange)) {\n throw new Error(\n `Received invalid snap version range: \"${newVersionRange}\".`,\n );\n }\n\n let pendingApproval = this.#createApproval({\n origin,\n snapId,\n type: SNAP_APPROVAL_UPDATE,\n });\n\n try {\n this.messagingSystem.publish(\n 'SnapController:snapInstallStarted',\n snapId,\n origin,\n true,\n );\n\n const oldManifest = snap.manifest;\n\n const newSnap = await fetchSnap(snapId, location);\n const { sourceCode: sourceCodeFile, manifest: manifestFile } = newSnap;\n\n const manifest = manifestFile.result;\n\n const newVersion = manifest.version;\n if (!gtVersion(newVersion, snap.version)) {\n throw rpcErrors.invalidParams(\n `Snap \"${snapId}@${snap.version}\" is already installed. Couldn't update to a version inside requested \"${newVersionRange}\" range.`,\n );\n }\n\n if (!satisfiesVersionRange(newVersion, newVersionRange)) {\n throw new Error(\n `Version mismatch. Manifest for \"${snapId}\" specifies version \"${newVersion}\" which doesn't satisfy requested version range \"${newVersionRange}\".`,\n );\n }\n\n await this.#assertIsInstallAllowed(snapId, {\n version: newVersion,\n checksum: manifest.source.shasum,\n permissions: manifest.initialPermissions,\n platformVersion: manifest.platformVersion,\n });\n\n const processedPermissions = processSnapPermissions(\n manifest.initialPermissions,\n );\n\n this.#validateSnapPermissions(processedPermissions);\n\n const { newPermissions, unusedPermissions, approvedPermissions } =\n this.#calculatePermissionsChange(snapId, processedPermissions);\n\n const { newConnections, unusedConnections, approvedConnections } =\n this.#calculateConnectionsChange(\n snapId,\n oldManifest.initialConnections ?? {},\n manifest.initialConnections ?? {},\n );\n\n this.#updateApproval(pendingApproval.id, {\n permissions: newPermissions,\n newVersion: manifest.version,\n newPermissions,\n approvedPermissions,\n unusedPermissions,\n newConnections,\n unusedConnections,\n approvedConnections,\n loading: false,\n });\n\n const { permissions: approvedNewPermissions, ...requestData } =\n (await pendingApproval.promise) as PermissionsRequest;\n\n pendingApproval = this.#createApproval({\n origin,\n snapId,\n type: SNAP_APPROVAL_RESULT,\n });\n\n if (this.isRunning(snapId)) {\n await this.stopSnap(snapId, SnapStatusEvents.Stop);\n }\n\n this.#transition(snapId, SnapStatusEvents.Update);\n\n this.#set({\n origin,\n id: snapId,\n files: newSnap,\n isUpdate: true,\n });\n\n this.#updatePermissions({\n snapId,\n unusedPermissions,\n newPermissions: approvedNewPermissions,\n requestData,\n });\n\n if (manifest.initialConnections) {\n this.#handleInitialConnections(\n snapId,\n oldManifest.initialConnections ?? null,\n manifest.initialConnections,\n );\n }\n\n const rollbackSnapshot = this.#getRollbackSnapshot(snapId);\n if (rollbackSnapshot !== undefined) {\n rollbackSnapshot.permissions.revoked = unusedPermissions;\n rollbackSnapshot.permissions.granted = approvedNewPermissions;\n rollbackSnapshot.permissions.requestData = requestData;\n }\n\n const sourceCode = sourceCodeFile.toString();\n\n assert(\n typeof sourceCode === 'string' && sourceCode.length > 0,\n `Invalid source code for snap \"${snapId}\".`,\n );\n\n try {\n await this.#startSnap({ snapId, sourceCode });\n } catch {\n throw new Error(`Snap ${snapId} crashed with updated source code.`);\n }\n\n const truncatedSnap = this.getTruncatedExpect(snapId);\n\n if (emitEvent) {\n this.messagingSystem.publish(\n 'SnapController:snapUpdated',\n truncatedSnap,\n snap.version,\n origin,\n false,\n );\n }\n\n this.#updateApproval(pendingApproval.id, {\n loading: false,\n type: SNAP_APPROVAL_UPDATE,\n });\n\n return truncatedSnap;\n } catch (error) {\n logError(`Error when updating ${snapId},`, error);\n\n const errorString =\n error instanceof Error ? error.message : error.toString();\n\n this.#updateApproval(pendingApproval.id, {\n loading: false,\n error: errorString,\n type: SNAP_APPROVAL_UPDATE,\n });\n\n this.messagingSystem.publish(\n 'SnapController:snapInstallFailed',\n snapId,\n origin,\n true,\n errorString,\n );\n\n throw error;\n }\n }\n\n async #resolveAllowlistVersion(\n snapId: SnapId,\n versionRange: SemVerRange,\n ): Promise<SemVerRange> {\n return await this.messagingSystem.call(\n 'SnapsRegistry:resolveVersion',\n snapId,\n versionRange,\n );\n }\n\n /**\n * Returns a promise representing the complete installation of the requested snap.\n * If the snap is already being installed, the previously pending promise will be returned.\n *\n * @param args - Object containing the snap id and either the URL of the snap's manifest,\n * or the snap's manifest and source code. The object may also optionally contain a target\n * version.\n * @returns The resulting snap object.\n */\n async #add(args: AddSnapArgs): Promise<PersistedSnap> {\n const { id: snapId, location, versionRange } = args;\n\n this.#setupRuntime(snapId);\n const runtime = this.#getRuntimeExpect(snapId);\n if (!runtime.installPromise) {\n log(`Adding snap: ${snapId}`);\n\n // If fetching and setting the snap succeeds, this property will be set\n // to null in the authorize() method.\n runtime.installPromise = (async () => {\n const fetchedSnap = await fetchSnap(snapId, location);\n const manifest = fetchedSnap.manifest.result;\n if (!satisfiesVersionRange(manifest.version, versionRange)) {\n throw new Error(\n `Version mismatch. Manifest for \"${snapId}\" specifies version \"${manifest.version}\" which doesn't satisfy requested version range \"${versionRange}\".`,\n );\n }\n\n await this.#assertIsInstallAllowed(snapId, {\n version: manifest.version,\n checksum: manifest.source.shasum,\n permissions: manifest.initialPermissions,\n platformVersion: manifest.platformVersion,\n });\n\n const preinstalledArgs =\n this.#featureFlags.forcePreinstalledSnaps && isLocalSnapId(snapId)\n ? {\n preinstalled: true,\n hideSnapBranding: true,\n hidden: false,\n }\n : {};\n\n return this.#set({\n ...args,\n files: fetchedSnap,\n id: snapId,\n ...preinstalledArgs,\n });\n })();\n }\n\n try {\n return await runtime.installPromise;\n } catch (error) {\n // Reset promise so users can retry installation in case the problem is\n // temporary.\n runtime.installPromise = null;\n throw error;\n }\n }\n\n async #startSnap(snapData: { snapId: SnapId; sourceCode: string }) {\n const { snapId } = snapData;\n if (this.isRunning(snapId)) {\n throw new Error(`Snap \"${snapId}\" is already started.`);\n }\n\n try {\n const runtime = this.#getRuntimeExpect(snapId);\n const result = await this.messagingSystem.call(\n 'ExecutionService:executeSnap',\n {\n ...snapData,\n endowments: await this.#getEndowments(snapId),\n },\n );\n\n this.#transition(snapId, SnapStatusEvents.Start);\n // We treat the initialization of the snap as the first request, for idle timing purposes.\n runtime.lastRequest = Date.now();\n return result;\n } catch (error) {\n await this.#terminateSnap(snapId);\n throw error;\n }\n }\n\n /**\n * Gets the names of all endowments that will be added to the Snap's\n * Compartment when it executes. These should be the names of global\n * JavaScript APIs accessible in the root realm of the execution environment.\n *\n * Throws an error if the endowment getter for a permission returns a truthy\n * value that is not an array of strings.\n *\n * @param snapId - The id of the snap whose SES endowments to get.\n * @returns An array of the names of the endowments.\n */\n async #getEndowments(snapId: string): Promise<string[]> {\n let allEndowments: string[] = [];\n\n for (const permissionName of this.#environmentEndowmentPermissions) {\n if (\n this.messagingSystem.call(\n 'PermissionController:hasPermission',\n snapId,\n permissionName,\n )\n ) {\n const endowments = await this.messagingSystem.call(\n 'PermissionController:getEndowments',\n snapId,\n permissionName,\n );\n\n if (endowments) {\n // We don't have any guarantees about the type of the endowments\n // value, so we have to guard at runtime.\n if (\n !Array.isArray(endowments) ||\n endowments.some((value) => typeof value !== 'string')\n ) {\n throw new Error('Expected an array of string endowment names.');\n }\n\n allEndowments = allEndowments.concat(endowments as string[]);\n }\n }\n }\n\n const dedupedEndowments = [\n ...new Set([...DEFAULT_ENDOWMENTS, ...allEndowments]),\n ];\n\n if (\n dedupedEndowments.length <\n DEFAULT_ENDOWMENTS.length + allEndowments.length\n ) {\n logError(\n `Duplicate endowments found for ${snapId}. Default endowments should not be requested.`,\n allEndowments,\n );\n }\n return dedupedEndowments;\n }\n\n /**\n * Sets a snap in state. Called when a snap is installed or updated. Performs\n * various validation checks on the received arguments, and will throw if\n * validation fails.\n *\n * The snap will be enabled and unblocked by the time this method returns,\n * regardless of its previous state.\n *\n * See {@link SnapController.add} and {@link SnapController.updateSnap} for\n * usage.\n *\n * @param args - The add snap args.\n * @returns The resulting snap object.\n */\n #set(args: SetSnapArgs): PersistedSnap {\n const {\n id: snapId,\n origin,\n files,\n isUpdate = false,\n removable,\n preinstalled,\n hidden,\n hideSnapBranding,\n } = args;\n\n const {\n manifest,\n sourceCode: sourceCodeFile,\n svgIcon,\n auxiliaryFiles: rawAuxiliaryFiles,\n localizationFiles,\n } = files;\n\n assertIsSnapManifest(manifest.result);\n const { version } = manifest.result;\n\n const sourceCode = sourceCodeFile.toString();\n\n assert(\n typeof sourceCode === 'string' && sourceCode.length > 0,\n `Invalid source code for snap \"${snapId}\".`,\n );\n\n const auxiliaryFiles = rawAuxiliaryFiles.map((file) => {\n assert(typeof file.data.base64 === 'string');\n return {\n path: file.path,\n value: file.data.base64,\n };\n });\n\n const snapsState = this.state.snaps;\n\n const existingSnap = snapsState[snapId];\n\n const previousVersionHistory = existingSnap?.versionHistory ?? [];\n const versionHistory = [\n ...previousVersionHistory,\n {\n version,\n date: Date.now(),\n origin,\n },\n ];\n\n const localizedFiles = localizationFiles.map((file) => file.result);\n\n const snap: Snap = {\n // Restore relevant snap state if it exists\n ...existingSnap,\n\n // Note that the snap will be unblocked and enabled, regardless of its\n // previous state.\n blocked: false,\n enabled: true,\n\n removable,\n preinstalled,\n hidden,\n hideSnapBranding,\n\n id: snapId,\n initialConnections: manifest.result.initialConnections,\n initialPermissions: manifest.result.initialPermissions,\n manifest: manifest.result,\n status: this.#statusMachine.config.initial as StatusStates['value'],\n sourceCode,\n version,\n versionHistory,\n auxiliaryFiles,\n localizationFiles: localizedFiles,\n };\n\n // If the snap was blocked, it isn't any longer\n delete snap.blockInformation;\n\n // store the snap back in state\n const { inversePatches } = this.update((state: any) => {\n state.snaps[snapId] = snap;\n });\n\n // checking for isUpdate here as this function is also used in\n // the install flow, we do not care to create snapshots for installs\n if (isUpdate) {\n const rollbackSnapshot = this.#getRollbackSnapshot(snapId);\n if (rollbackSnapshot !== undefined) {\n rollbackSnapshot.statePatches = inversePatches;\n }\n }\n\n // In case the Snap uses a localized manifest, we need to get the\n // proposed name from the localized manifest.\n const { proposedName } = getLocalizedSnapManifest(\n manifest.result,\n 'en',\n localizedFiles,\n );\n\n this.messagingSystem.call('SubjectMetadataController:addSubjectMetadata', {\n subjectType: SubjectType.Snap,\n name: proposedName,\n origin: snap.id,\n version,\n svgIcon: svgIcon?.toString() ?? null,\n });\n\n return { ...snap, sourceCode };\n }\n\n #validateSnapPermissions(\n processedPermissions: Record<string, Pick<PermissionConstraint, 'caveats'>>,\n ) {\n const permissionKeys = Object.keys(processedPermissions);\n const handlerPermissions = Array.from(\n new Set(Object.values(handlerEndowments)),\n );\n\n assert(\n permissionKeys.some((key) => handlerPermissions.includes(key)),\n `A snap must request at least one of the following permissions: ${handlerPermissions\n .filter((handler) => handler !== null)\n .join(', ')}.`,\n );\n\n const excludedPermissionErrors = permissionKeys.reduce<string[]>(\n (errors, permission) => {\n if (hasProperty(this.#excludedPermissions, permission)) {\n errors.push(this.#excludedPermissions[permission]);\n }\n\n return errors;\n },\n [],\n );\n\n assert(\n excludedPermissionErrors.length === 0,\n `One or more permissions are not allowed:\\n${excludedPermissionErrors.join(\n '\\n',\n )}`,\n );\n }\n\n /**\n * Validate that the platform version specified in the manifest (if any) is\n * compatible with the current platform version.\n *\n * @param snapId - The ID of the Snap.\n * @param platformVersion - The platform version to validate against.\n * @throws If the platform version is greater than the current platform\n * version.\n */\n #validatePlatformVersion(\n snapId: SnapId,\n platformVersion: string | undefined,\n ) {\n if (platformVersion === undefined) {\n return;\n }\n\n if (gt(platformVersion, getPlatformVersion())) {\n const message = `The Snap \"${snapId}\" requires platform version \"${platformVersion}\" which is greater than the current platform version \"${getPlatformVersion()}\".`;\n\n if (this.#featureFlags.rejectInvalidPlatformVersion) {\n throw new Error(message);\n }\n\n logWarning(message);\n }\n }\n\n /**\n * Initiates a request for the given snap's initial permissions.\n * Must be called in order. See processRequestedSnap.\n *\n * This function is not hash private yet because of tests.\n *\n * @param snapId - The id of the Snap.\n * @param pendingApproval - Pending approval to update.\n * @returns The snap's approvedPermissions.\n */\n // eslint-disable-next-line no-restricted-syntax\n private async authorize(\n snapId: SnapId,\n pendingApproval: PendingApproval,\n ): Promise<void> {\n log(`Authorizing snap: ${snapId}`);\n const snapsState = this.state.snaps;\n const snap = snapsState[snapId];\n const { initialPermissions, initialConnections } = snap;\n\n try {\n const processedPermissions = processSnapPermissions(initialPermissions);\n\n this.#validateSnapPermissions(processedPermissions);\n\n this.#updateApproval(pendingApproval.id, {\n loading: false,\n connections: initialConnections ?? {},\n permissions: processedPermissions,\n });\n\n const { permissions: approvedPermissions, ...requestData } =\n (await pendingApproval.promise) as PermissionsRequest;\n\n this.#updatePermissions({\n snapId,\n newPermissions: approvedPermissions,\n requestData,\n });\n\n if (snap.manifest.initialConnections) {\n this.#handleInitialConnections(\n snapId,\n null,\n snap.manifest.initialConnections,\n );\n }\n } finally {\n const runtime = this.#getRuntimeExpect(snapId);\n runtime.installPromise = null;\n }\n }\n\n destroy() {\n super.destroy();\n\n if (this.#timeoutForLastRequestStatus) {\n clearTimeout(this.#timeoutForLastRequestStatus);\n }\n\n /* eslint-disable @typescript-eslint/unbound-method */\n this.messagingSystem.unsubscribe(\n 'ExecutionService:unhandledError',\n this._onUnhandledSnapError,\n );\n\n this.messagingSystem.unsubscribe(\n 'ExecutionService:outboundRequest',\n this._onOutboundRequest,\n );\n\n this.messagingSystem.unsubscribe(\n 'ExecutionService:outboundResponse',\n this._onOutboundResponse,\n );\n\n this.messagingSystem.clearEventSubscriptions(\n 'SnapController:snapInstalled',\n );\n\n this.messagingSystem.clearEventSubscriptions('SnapController:snapUpdated');\n /* eslint-enable @typescript-eslint/unbound-method */\n }\n\n /**\n * Passes a JSON-RPC request object to the RPC handler function of a snap.\n *\n * @param options - A bag of options.\n * @param options.snapId - The ID of the recipient snap.\n * @param options.origin - The origin of the RPC request.\n * @param options.handler - The handler to trigger on the snap for the request.\n * @param options.request - The JSON-RPC request object.\n * @returns The result of the JSON-RPC request.\n */\n async handleRequest({\n snapId,\n origin,\n handler: handlerType,\n request: rawRequest,\n }: SnapRpcHookArgs & { snapId: SnapId }): Promise<unknown> {\n this.#assertCanUsePlatform();\n\n assert(\n origin === METAMASK_ORIGIN || isValidUrl(origin),\n \"'origin' must be a valid URL or 'metamask'.\",\n );\n\n const request = {\n jsonrpc: '2.0',\n id: nanoid(),\n ...rawRequest,\n };\n\n assertIsJsonRpcRequest(request);\n\n const permissionName = handlerEndowments[handlerType];\n\n assert(\n typeof permissionName === 'string' || permissionName === null,\n \"'permissionName' must be either a string or null.\",\n );\n\n const permissions = this.messagingSystem.call(\n 'PermissionController:getPermissions',\n snapId,\n );\n\n // If permissionName is null, the handler does not require a permission.\n if (\n permissionName !== null &&\n (!permissions || !hasProperty(permissions, permissionName))\n ) {\n throw new Error(\n `Snap \"${snapId}\" is not permitted to use \"${permissionName}\".`,\n );\n }\n\n const handlerPermissions = permissionName\n ? (permissions as SubjectPermissions<PermissionConstraint>)[\n permissionName\n ]\n : undefined;\n\n if (\n permissionName === SnapEndowments.Rpc ||\n permissionName === SnapEndowments.Keyring\n ) {\n assert(handlerPermissions);\n\n const subject = this.messagingSystem.call(\n 'SubjectMetadataController:getSubjectMetadata',\n origin,\n );\n\n const origins =\n permissionName === SnapEndowments.Rpc\n ? getRpcCaveatOrigins(handlerPermissions)\n : getKeyringCaveatOrigins(handlerPermissions);\n assert(origins);\n\n if (\n !isOriginAllowed(\n origins,\n subject?.subjectType ?? SubjectType.Website,\n origin,\n )\n ) {\n throw new Error(\n `Snap \"${snapId}\" is not permitted to handle requests from \"${origin}\".`,\n );\n }\n }\n\n if (\n origin !== METAMASK_ORIGIN &&\n CLIENT_ONLY_HANDLERS.includes(handlerType)\n ) {\n throw new Error(`\"${handlerType}\" can only be invoked by MetaMask.`);\n }\n\n if (!this.state.snaps[snapId].enabled) {\n throw new Error(`Snap \"${snapId}\" is disabled.`);\n }\n\n if (this.state.snaps[snapId].status === SnapStatus.Installing) {\n throw new Error(\n `Snap \"${snapId}\" is currently being installed. Please try again later.`,\n );\n }\n\n const timeout = this.#getExecutionTimeout(handlerPermissions);\n\n const runtime = this.#getRuntimeExpect(snapId);\n\n if (runtime.stopPromise) {\n await runtime.stopPromise;\n }\n\n if (!this.isRunning(snapId)) {\n if (!runtime.startPromise) {\n runtime.startPromise = this.startSnap(snapId);\n }\n\n try {\n await runtime.startPromise;\n } finally {\n runtime.startPromise = null;\n }\n }\n\n const transformedRequest = this.#transformSnapRpcRequest(\n snapId,\n handlerType,\n request,\n );\n\n const timer = new Timer(timeout);\n this.#recordSnapRpcRequestStart(snapId, transformedRequest.id, timer);\n\n const handleRpcRequestPromise = this.messagingSystem.call(\n 'ExecutionService:handleRpcRequest',\n snapId,\n { origin, handler: handlerType, request: transformedRequest },\n );\n\n // This will either get the result or reject due to the timeout.\n try {\n const result = await withTimeout(handleRpcRequestPromise, timer);\n\n if (result === hasTimedOut) {\n const stopping =\n runtime.stopPromise !== null || !this.isRunning(snapId);\n throw new Error(\n stopping\n ? `${snapId} was stopped and the request was cancelled. This is likely because the Snap crashed.`\n : `${snapId} failed to respond to the request in time.`,\n );\n }\n\n await this.#assertSnapRpcResponse(snapId, handlerType, result);\n\n const transformedResult = await this.#transformSnapRpcResponse(\n snapId,\n handlerType,\n transformedRequest,\n result,\n );\n\n this.#recordSnapRpcRequestFinish(\n snapId,\n transformedRequest.id,\n handlerType,\n origin,\n true,\n );\n\n return transformedResult;\n } catch (error) {\n // We flag the RPC request as finished early since termination may affect pending requests\n this.#recordSnapRpcRequestFinish(\n snapId,\n transformedRequest.id,\n handlerType,\n origin,\n false,\n );\n\n const [jsonRpcError, handled] = unwrapError(error);\n\n if (!handled) {\n logError(\n `\"${snapId}\" crashed due to an unhandled error:`,\n jsonRpcError,\n );\n await this.stopSnap(snapId, SnapStatusEvents.Crash);\n }\n\n throw jsonRpcError;\n }\n }\n\n /**\n * Set the active state of the client. This will trigger the `onActive` or\n * `onInactive` lifecycle hooks for all Snaps.\n *\n * @param active - A boolean indicating whether the client is active or not.\n */\n setClientActive(active: boolean) {\n if (active) {\n this.#callLifecycleHooks(METAMASK_ORIGIN, HandlerType.OnActive);\n } else {\n this.#callLifecycleHooks(METAMASK_ORIGIN, HandlerType.OnInactive);\n }\n }\n\n /**\n * Determine the execution timeout for a given handler permission.\n *\n * If no permission is specified or the permission itself has no execution timeout defined\n * the constructor argument `maxRequestTime` will be used.\n *\n * @param permission - An optional permission constraint for the handler being called.\n * @returns The execution timeout for the given handler.\n */\n #getExecutionTimeout(permission?: PermissionConstraint): number {\n return getMaxRequestTimeCaveat(permission) ?? this.maxRequestTime;\n }\n\n /**\n * Create a dynamic interface in the SnapInterfaceController.\n *\n * @param snapId - The snap ID.\n * @param content - The initial interface content.\n * @param contentType - The type of content.\n * @returns An identifier that can be used to identify the interface.\n */\n async #createInterface(\n snapId: SnapId,\n content: ComponentOrElement,\n contentType?: ContentType,\n ): Promise<string> {\n return this.messagingSystem.call(\n 'SnapInterfaceController:createInterface',\n snapId,\n content,\n undefined,\n contentType,\n );\n }\n\n #assertInterfaceExists(snapId: SnapId, id: string) {\n // This will throw if the interface isn't accessible, but we assert nevertheless.\n assert(\n this.messagingSystem.call(\n 'SnapInterfaceController:getInterface',\n snapId,\n id,\n ),\n );\n }\n\n /**\n * Transform a RPC response if necessary.\n *\n * @param snapId - The snap ID of the snap that produced the result.\n * @param handlerType - The handler type that produced the result.\n * @param request - The request that returned the result.\n * @param result - The response.\n * @returns The transformed result if applicable, otherwise the original result.\n */\n async #transformSnapRpcResponse(\n snapId: SnapId,\n handlerType: HandlerType,\n request: Record<string, unknown>,\n result: unknown,\n ) {\n switch (handlerType) {\n case HandlerType.OnTransaction:\n case HandlerType.OnSignature:\n case HandlerType.OnHomePage:\n case HandlerType.OnSettingsPage: {\n // Since this type has been asserted earlier we can cast\n const castResult = result as Record<string, Json> | null;\n\n // If a handler returns static content, we turn it into a dynamic UI\n if (castResult && hasProperty(castResult, 'content')) {\n const { content, ...rest } = castResult;\n const id = await this.#createInterface(\n snapId,\n content as ComponentOrElement,\n );\n\n return { ...rest, id };\n }\n return result;\n }\n case HandlerType.OnAssetsLookup:\n // We can cast since the request and result have already been validated.\n return this.#transformOnAssetsLookupResult(\n snapId,\n request as { params: OnAssetsLookupArguments },\n result as OnAssetsLookupResponse,\n );\n\n case HandlerType.OnAssetsConversion:\n // We can cast since the request and result have already been validated.\n return this.#transformOnAssetsConversionResult(\n request as {\n params: OnAssetsConversionArguments;\n },\n result as OnAssetsConversionResponse,\n );\n\n case HandlerType.OnAssetsMarketData:\n // We can cast since the request and result have already been validated.\n return this.#transformOnAssetsMarketDataResult(\n request as { params: OnAssetsMarketDataArguments },\n result as OnAssetsMarketDataResponse,\n );\n\n default:\n return result;\n }\n }\n\n /**\n * Transform an RPC response coming from the `onAssetsLookup` handler.\n *\n * This filters out responses that are out of scope for the Snap based on\n * its permissions and the incoming request.\n *\n * @param snapId - The snap ID of the snap that produced the result.\n * @param request - The request that returned the result.\n * @param request.params - The parameters for the request.\n * @param result - The result.\n * @param result.assets - The assets returned by the Snap.\n * @returns The transformed result.\n */\n #transformOnAssetsLookupResult(\n snapId: SnapId,\n { params: requestedParams }: { params: OnAssetsLookupArguments },\n { assets }: OnAssetsLookupResponse,\n ) {\n const permissions = this.messagingSystem.call(\n 'PermissionController:getPermissions',\n snapId,\n );\n // We know the permissions are guaranteed to be set here.\n assert(permissions);\n\n const permission = permissions[SnapEndowments.Assets];\n const scopes = getChainIdsCaveat(permission);\n assert(scopes);\n\n const { assets: requestedAssets } = requestedParams;\n\n const filteredAssets = Object.keys(assets).reduce<\n Record<CaipAssetType, AssetMetadata | null>\n >((accumulator, assetType) => {\n const castAssetType = assetType as CaipAssetTypeOrId;\n const isValid =\n scopes.some((scope) => castAssetType.startsWith(scope)) &&\n requestedAssets.includes(castAssetType);\n // Filter out unrequested assets and assets for scopes the Snap hasn't registered for.\n if (isValid) {\n accumulator[castAssetType] = assets[castAssetType];\n }\n return accumulator;\n }, {});\n return { assets: filteredAssets };\n }\n\n /**\n * Transform an RPC response coming from the `onAssetsConversion` handler.\n *\n * This filters out responses that are out of scope for the Snap based on\n * the incoming request.\n *\n * @param request - The request that returned the result.\n * @param request.params - The parameters for the request.\n * @param result - The result.\n * @param result.conversionRates - The conversion rates returned by the Snap.\n * @returns The transformed result.\n */\n #transformOnAssetsConversionResult(\n { params: requestedParams }: { params: OnAssetsConversionArguments },\n { conversionRates }: OnAssetsConversionResponse,\n ) {\n const { conversions: requestedConversions } = requestedParams;\n\n const filteredConversionRates = requestedConversions.reduce<\n Record<CaipAssetType, Record<CaipAssetType, AssetConversion>>\n >((accumulator, conversion) => {\n const rate = conversionRates[conversion.from]?.[conversion.to];\n // Only include rates that were actually requested.\n if (rate) {\n accumulator[conversion.from] ??= {};\n accumulator[conversion.from][conversion.to] = rate;\n }\n return accumulator;\n }, {});\n return { conversionRates: filteredConversionRates };\n }\n\n /**\n * Transforms an RPC response coming from the `onAssetsMarketData` handler.\n *\n * This filters out responses that are out of scope for the Snap based on\n * the incoming request.\n *\n * @param request - The request that returned the result.\n * @param request.params - The parameters for the request.\n * @param result - The result.\n * @param result.marketData - The market data returned by the Snap.\n * @returns The transformed result.\n */\n #transformOnAssetsMarketDataResult(\n { params: requestedParams }: { params: OnAssetsMarketDataArguments },\n { marketData }: OnAssetsMarketDataResponse,\n ) {\n const { assets: requestedAssets } = requestedParams;\n\n const filteredMarketData = requestedAssets.reduce<\n Record<CaipAssetTypeOrId, Record<CaipAssetType, AssetMarketData | null>>\n >((accumulator, assets) => {\n const result = marketData[assets.asset]?.[assets.unit];\n // Only include rates that were actually requested.\n if (result) {\n accumulator[assets.asset] ??= {};\n accumulator[assets.asset][assets.unit] = result;\n }\n return accumulator;\n }, {});\n return { marketData: filteredMarketData };\n }\n\n /**\n * Transforms a JSON-RPC request before sending it to the Snap, if required for a given handler.\n *\n * @param snapId - The Snap ID.\n * @param handlerType - The handler being called.\n * @param request - The JSON-RPC request.\n * @returns The potentially transformed JSON-RPC request.\n */\n #transformSnapRpcRequest(\n snapId: SnapId,\n handlerType: HandlerType,\n request: JsonRpcRequest,\n ) {\n switch (handlerType) {\n // For onUserInput we inject context, so the client doesn't have to worry about keeping it in sync.\n case HandlerType.OnUserInput: {\n assert(request.params && hasProperty(request.params, 'id'));\n\n const interfaceId = request.params.id as string;\n const { context } = this.messagingSystem.call(\n 'SnapInterfaceController:getInterface',\n snapId,\n interfaceId,\n );\n\n return {\n ...request,\n params: { ...request.params, context },\n };\n }\n\n default:\n return request;\n }\n }\n\n /**\n * Assert that the returned result of a Snap RPC call is the expected shape.\n *\n * @param snapId - The snap ID.\n * @param handlerType - The handler type of the RPC Request.\n * @param result - The result of the RPC request.\n */\n async #assertSnapRpcResponse(\n snapId: SnapId,\n handlerType: HandlerType,\n result: unknown,\n ) {\n switch (handlerType) {\n case HandlerType.OnTransaction: {\n assertStruct(result, OnTransactionResponseStruct);\n\n if (result && hasProperty(result, 'id')) {\n this.#assertInterfaceExists(snapId, result.id as string);\n }\n\n break;\n }\n case HandlerType.OnSignature: {\n assertStruct(result, OnSignatureResponseStruct);\n\n if (result && hasProperty(result, 'id')) {\n this.#assertInterfaceExists(snapId, result.id as string);\n }\n\n break;\n }\n case HandlerType.OnHomePage: {\n assertStruct(result, OnHomePageResponseStruct);\n\n if (result && hasProperty(result, 'id')) {\n this.#assertInterfaceExists(snapId, result.id as string);\n }\n\n break;\n }\n case HandlerType.OnSettingsPage: {\n assertStruct(result, OnSettingsPageResponseStruct);\n\n if (result && hasProperty(result, 'id')) {\n this.#assertInterfaceExists(snapId, result.id as string);\n }\n\n break;\n }\n case HandlerType.OnNameLookup:\n assertStruct(result, OnNameLookupResponseStruct);\n break;\n case HandlerType.OnAssetsLookup:\n assertStruct(result, OnAssetsLookupResponseStruct);\n break;\n case HandlerType.OnAssetsConversion:\n assertStruct(result, OnAssetsConversionResponseStruct);\n break;\n case HandlerType.OnAssetHistoricalPrice:\n assertStruct(result, OnAssetHistoricalPriceResponseStruct);\n break;\n case HandlerType.OnAssetsMarketData:\n assertStruct(result, OnAssetsMarketDataResponseStruct);\n break;\n default:\n break;\n }\n }\n\n #recordSnapRpcRequestStart(snapId: SnapId, requestId: unknown, timer: Timer) {\n const runtime = this.#getRuntimeExpect(snapId);\n runtime.pendingInboundRequests.push({ requestId, timer });\n runtime.lastRequest = null;\n }\n\n #recordSnapRpcRequestFinish(\n snapId: SnapId,\n requestId: unknown,\n handlerType: HandlerType,\n origin: string,\n success: boolean,\n ) {\n const runtime = this.#getRuntimeExpect(snapId);\n runtime.pendingInboundRequests = runtime.pendingInboundRequests.filter(\n (request) => request.requestId !== requestId,\n );\n\n if (runtime.pendingInboundRequests.length === 0) {\n runtime.lastRequest = Date.now();\n }\n\n const snap = this.get(snapId);\n\n if (isTrackableHandler(handlerType) && !snap?.preinstalled) {\n try {\n this.#trackSnapExport(snapId, handlerType, success, origin);\n } catch (error) {\n logError(\n `Error when calling MetaMetrics hook for snap \"${snap?.id}\": ${getErrorMessage(\n error,\n )}`,\n );\n }\n }\n }\n\n /**\n * Retrieves the rollback snapshot of a snap.\n *\n * @param snapId - The snap id.\n * @returns A `RollbackSnapshot` or `undefined` if one doesn't exist.\n */\n #getRollbackSnapshot(snapId: SnapId): RollbackSnapshot | undefined {\n return this.#rollbackSnapshots.get(snapId);\n }\n\n /**\n * Creates a `RollbackSnapshot` that is used to help ensure\n * atomicity in multiple snap updates.\n *\n * @param snapId - The snap id.\n * @throws {@link Error}. If the snap exists before creation or if creation fails.\n * @returns A `RollbackSnapshot`.\n */\n #createRollbackSnapshot(snapId: SnapId): RollbackSnapshot {\n assert(\n this.#rollbackSnapshots.get(snapId) === undefined,\n new Error(`Snap \"${snapId}\" rollback snapshot already exists.`),\n );\n\n this.#rollbackSnapshots.set(snapId, {\n statePatches: [],\n permissions: {},\n newVersion: '',\n });\n\n const newRollbackSnapshot = this.#rollbackSnapshots.get(snapId);\n\n assert(\n newRollbackSnapshot !== undefined,\n new Error(`Snapshot creation failed for ${snapId}.`),\n );\n return newRollbackSnapshot;\n }\n\n /**\n * Rolls back a snap to its previous state, permissions\n * and source code based on the `RollbackSnapshot` that\n * is captured during the update process. After rolling back,\n * the function also emits an event indicating that the\n * snap has been rolled back and it clears the snapshot\n * for that snap.\n *\n * @param snapId - The snap id.\n * @throws {@link Error}. If a snapshot does not exist.\n */\n async #rollbackSnap(snapId: SnapId) {\n const rollbackSnapshot = this.#getRollbackSnapshot(snapId);\n if (!rollbackSnapshot) {\n throw new Error('A snapshot does not exist for this snap.');\n }\n\n await this.stopSnap(snapId, SnapStatusEvents.Stop);\n // Always set to stopped even if it wasn't running initially\n if (this.get(snapId)?.status !== SnapStatus.Stopped) {\n this.#transition(snapId, SnapStatusEvents.Stop);\n }\n\n const { statePatches, permissions } = rollbackSnapshot;\n\n if (statePatches?.length) {\n this.applyPatches(statePatches);\n }\n\n // Reset snap status, as we may have been in another state when we stored state patches\n // But now we are 100% in a stopped state\n if (this.get(snapId)?.status !== SnapStatus.Stopped) {\n this.update((state) => {\n state.snaps[snapId].status = SnapStatus.Stopped;\n });\n }\n\n this.#updatePermissions({\n snapId,\n unusedPermissions: permissions.granted,\n newPermissions: permissions.revoked,\n requestData: permissions.requestData,\n });\n\n const truncatedSnap = this.getTruncatedExpect(snapId);\n\n this.messagingSystem.publish(\n 'SnapController:snapRolledback',\n truncatedSnap,\n rollbackSnapshot.newVersion,\n );\n\n this.#rollbackSnapshots.delete(snapId);\n }\n\n /**\n * Iterates through an array of snap ids\n * and calls `rollbackSnap` on them.\n *\n * @param snapIds - An array of snap ids.\n */\n async #rollbackSnaps(snapIds: SnapId[]) {\n for (const snapId of snapIds) {\n await this.#rollbackSnap(snapId);\n }\n }\n\n #getRuntime(snapId: SnapId): SnapRuntimeData | undefined {\n return this.#snapsRuntimeData.get(snapId);\n }\n\n #getRuntimeExpect(snapId: SnapId): SnapRuntimeData {\n const runtime = this.#getRuntime(snapId);\n assert(\n runtime !== undefined,\n new Error(`Snap \"${snapId}\" runtime data not found`),\n );\n return runtime;\n }\n\n #setupRuntime(snapId: SnapId) {\n if (this.#snapsRuntimeData.has(snapId)) {\n return;\n }\n\n const snap = this.get(snapId);\n const interpreter = interpret(this.#statusMachine);\n interpreter.start({\n context: { snapId },\n value:\n snap?.status ??\n (this.#statusMachine.config.initial as StatusStates['value']),\n });\n\n forceStrict(interpreter);\n\n this.#snapsRuntimeData.set(snapId, {\n lastRequest: null,\n startPromise: null,\n stopPromise: null,\n installPromise: null,\n encryptionKey: null,\n encryptionSalt: null,\n activeReferences: 0,\n pendingInboundRequests: [],\n pendingOutboundRequests: 0,\n interpreter,\n stateMutex: new Mutex(),\n getStateMutex: new Mutex(),\n });\n }\n\n #calculatePermissionsChange(\n snapId: SnapId,\n desiredPermissionsSet: Record<\n string,\n Pick<PermissionConstraint, 'caveats'>\n >,\n ): {\n newPermissions: Record<string, Pick<PermissionConstraint, 'caveats'>>;\n unusedPermissions: SubjectPermissions<\n ValidPermission<string, Caveat<string, any>>\n >;\n approvedPermissions: SubjectPermissions<\n ValidPermission<string, Caveat<string, any>>\n >;\n } {\n const oldPermissions =\n this.messagingSystem.call(\n 'PermissionController:getPermissions',\n snapId,\n ) ?? {};\n\n const newPermissions = permissionsDiff(\n desiredPermissionsSet,\n oldPermissions,\n );\n // TODO(ritave): The assumption that these are unused only holds so long as we do not\n // permit dynamic permission requests.\n const unusedPermissions = permissionsDiff(\n oldPermissions,\n desiredPermissionsSet,\n );\n\n // It's a Set Intersection of oldPermissions and desiredPermissionsSet\n // oldPermissions ∖ (oldPermissions ∖ desiredPermissionsSet) ⟺ oldPermissions ∩ desiredPermissionsSet\n const approvedPermissions = permissionsDiff(\n oldPermissions,\n unusedPermissions,\n );\n\n return { newPermissions, unusedPermissions, approvedPermissions };\n }\n\n #isSubjectConnectedToSnap(snapId: SnapId, origin: string) {\n const subjectPermissions = this.messagingSystem.call(\n 'PermissionController:getPermissions',\n origin,\n ) as SubjectPermissions<PermissionConstraint>;\n\n const existingCaveat = subjectPermissions?.[\n WALLET_SNAP_PERMISSION_KEY\n ]?.caveats?.find((caveat) => caveat.type === SnapCaveatType.SnapIds);\n\n return Boolean((existingCaveat?.value as Record<string, Json>)?.[snapId]);\n }\n\n #calculateConnectionsChange(\n snapId: SnapId,\n oldConnectionsSet: Record<string, Json>,\n desiredConnectionsSet: Record<string, Json>,\n ): {\n newConnections: Record<string, Json>;\n unusedConnections: Record<string, Json>;\n approvedConnections: Record<string, Json>;\n } {\n // Filter out any origins that have been revoked since last install/update.\n // That way they will be represented as new.\n const filteredOldConnections = Object.keys(oldConnectionsSet)\n .filter((origin) => this.#isSubjectConnectedToSnap(snapId, origin))\n .reduce<Record<string, Json>>((accumulator, origin) => {\n accumulator[origin] = oldConnectionsSet[origin];\n return accumulator;\n }, {});\n\n const newConnections = setDiff(\n desiredConnectionsSet,\n filteredOldConnections,\n );\n\n const unusedConnections = setDiff(\n filteredOldConnections,\n desiredConnectionsSet,\n );\n\n // It's a Set Intersection of oldConnections and desiredConnectionsSet\n // oldConnections ∖ (oldConnections ∖ desiredConnectionsSet) ⟺ oldConnections ∩ desiredConnectionsSet\n const approvedConnections = setDiff(\n filteredOldConnections,\n unusedConnections,\n );\n\n return { newConnections, unusedConnections, approvedConnections };\n }\n\n /**\n * Get the permissions to grant to a Snap following an install, update or\n * rollback.\n *\n * @param snapId - The snap ID.\n * @param newPermissions - The new permissions to be granted.\n * @returns The permissions to grant to the Snap.\n */\n #getPermissionsToGrant(snapId: SnapId, newPermissions: RequestedPermissions) {\n if (\n this.#featureFlags.useCaip25Permission &&\n Object.keys(newPermissions).includes(SnapEndowments.EthereumProvider)\n ) {\n // This will return the globally selected network if the Snap doesn't have\n // one set.\n const networkClientId = this.messagingSystem.call(\n 'SelectedNetworkController:getNetworkClientIdForDomain',\n snapId,\n );\n\n const { configuration } = this.messagingSystem.call(\n 'NetworkController:getNetworkClientById',\n networkClientId,\n );\n\n const chainId = hexToNumber(configuration.chainId);\n\n // This needs to be assigned to have proper type inference.\n const modifiedPermissions: RequestedPermissions = {\n ...newPermissions,\n 'endowment:caip25': {\n caveats: [\n {\n type: 'authorizedScopes',\n value: {\n requiredScopes: {},\n optionalScopes: {\n [`eip155:${chainId}`]: {\n accounts: [],\n },\n },\n sessionProperties: {},\n isMultichainOrigin: false,\n },\n },\n ],\n },\n };\n\n return modifiedPermissions;\n }\n\n return newPermissions;\n }\n\n /**\n * Update the permissions for a snap following an install, update or rollback.\n *\n * Grants newly requested permissions and revokes unused/revoked permissions.\n *\n * @param args - An options bag.\n * @param args.snapId - The snap ID.\n * @param args.newPermissions - New permissions to be granted.\n * @param args.unusedPermissions - Unused permissions to be revoked.\n * @param args.requestData - Optional request data from an approval.\n */\n #updatePermissions({\n snapId,\n unusedPermissions = {},\n newPermissions = {},\n requestData,\n }: {\n snapId: SnapId;\n newPermissions?:\n | RequestedPermissions\n | Record<string, Pick<PermissionConstraint, 'caveats'>>;\n unusedPermissions?:\n | RequestedPermissions\n | SubjectPermissions<ValidPermission<string, Caveat<string, any>>>;\n requestData?: Record<string, unknown>;\n }) {\n const unusedPermissionsKeys = Object.keys(unusedPermissions);\n if (isNonEmptyArray(unusedPermissionsKeys)) {\n this.messagingSystem.call('PermissionController:revokePermissions', {\n [snapId]: unusedPermissionsKeys,\n });\n }\n\n if (isNonEmptyArray(Object.keys(newPermissions))) {\n const approvedPermissions = this.#getPermissionsToGrant(\n snapId,\n newPermissions,\n );\n\n this.messagingSystem.call('PermissionController:grantPermissions', {\n approvedPermissions,\n subject: { origin: snapId },\n requestData,\n });\n }\n }\n\n /**\n * Checks if a snap will pass version validation checks\n * with the new version range that is requested. The first\n * check that is done is to check if the existing snap version\n * falls inside the requested range. If it does, we want to return\n * false because we do not care to create a rollback snapshot in\n * that scenario. The second check is to ensure that the current\n * snap version is not greater than all possible versions in\n * the requested version range. If it is, then we also want\n * to return false in that scenario.\n *\n * @param snapId - The snap id.\n * @param newVersionRange - The new version range being requested.\n * @returns `true` if validation checks pass and `false` if they do not.\n */\n #isValidUpdate(snapId: SnapId, newVersionRange: SemVerRange): boolean {\n const existingSnap = this.getExpect(snapId);\n\n if (satisfiesVersionRange(existingSnap.version, newVersionRange)) {\n return false;\n }\n\n if (gtRange(existingSnap.version, newVersionRange)) {\n return false;\n }\n\n return true;\n }\n\n /**\n * Call a lifecycle hook for all runnable Snaps.\n *\n * @param origin - The origin of the request.\n * @param handler - The lifecycle hook to call. This should be one of the\n * supported lifecycle hooks.\n */\n #callLifecycleHooks(origin: string, handler: HandlerType) {\n const snaps = this.getRunnableSnaps();\n for (const { id } of snaps) {\n const hasLifecycleHooksEndowment = this.messagingSystem.call(\n 'PermissionController:hasPermission',\n id,\n SnapEndowments.LifecycleHooks,\n );\n\n if (!hasLifecycleHooksEndowment) {\n continue;\n }\n\n this.#callLifecycleHook(origin, id, handler).catch((error) => {\n logError(\n `Error calling lifecycle hook \"${handler}\" for Snap \"${id}\": ${getErrorMessage(\n error,\n )}`,\n );\n });\n }\n }\n\n /**\n * Call a lifecycle hook on a snap, if the snap has the\n * `endowment:lifecycle-hooks` permission. If the snap does not have the\n * permission, nothing happens.\n *\n * @param origin - The origin.\n * @param snapId - The snap ID.\n * @param handler - The lifecycle hook to call. This should be one of the\n * supported lifecycle hooks.\n * @private\n */\n async #callLifecycleHook(\n origin: string,\n snapId: SnapId,\n handler: HandlerType,\n ) {\n const permissionName = handlerEndowments[handler];\n\n assert(permissionName, 'Lifecycle hook must have an endowment.');\n\n const hasPermission = this.messagingSystem.call(\n 'PermissionController:hasPermission',\n snapId,\n permissionName,\n );\n\n if (!hasPermission) {\n return;\n }\n\n await this.handleRequest({\n snapId,\n handler,\n origin,\n request: {\n jsonrpc: '2.0',\n method: handler,\n },\n });\n }\n\n /**\n * Handle the `KeyringController:lock` event.\n *\n * Currently this clears the cached encrypted state (if any) for all Snaps.\n */\n #handleLock() {\n for (const runtime of this.#snapsRuntimeData.values()) {\n runtime.encryptionKey = null;\n runtime.encryptionSalt = null;\n runtime.state = undefined;\n }\n }\n}\n"]}